diff options
Diffstat (limited to 'tiff/tools/tiff2rgba.c')
-rw-r--r-- | tiff/tools/tiff2rgba.c | 62 |
1 files changed, 46 insertions, 16 deletions
diff --git a/tiff/tools/tiff2rgba.c b/tiff/tools/tiff2rgba.c index 2eb6f6c4..764395f6 100644 --- a/tiff/tools/tiff2rgba.c +++ b/tiff/tools/tiff2rgba.c @@ -39,6 +39,13 @@ #include "tiffiop.h" #include "tiffio.h" +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif + #define streq(a,b) (strcmp(a,b) == 0) #define CopyField(tag, v) \ if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v) @@ -53,6 +60,10 @@ uint32 rowsperstrip = (uint32) -1; int process_by_block = 0; /* default is whole image at once */ int no_alpha = 0; int bigtiff_output = 0; +#define DEFAULT_MAX_MALLOC (256 * 1024 * 1024) +/* malloc size limit (in bytes) + * disabled when set to 0 */ +static tmsize_t maxMalloc = DEFAULT_MAX_MALLOC; static int tiffcvt(TIFF* in, TIFF* out); @@ -68,8 +79,11 @@ main(int argc, char* argv[]) extern char *optarg; #endif - while ((c = getopt(argc, argv, "c:r:t:bn8")) != -1) + while ((c = getopt(argc, argv, "c:r:t:bn8hM:")) != -1) switch (c) { + case 'M': + maxMalloc = (tmsize_t)strtoul(optarg, NULL, 0) << 20; + break; case 'b': process_by_block = 1; break; @@ -86,7 +100,7 @@ main(int argc, char* argv[]) else if (streq(optarg, "zip")) compression = COMPRESSION_DEFLATE; else - usage(-1); + usage(EXIT_FAILURE); break; case 'r': @@ -105,17 +119,20 @@ main(int argc, char* argv[]) bigtiff_output = 1; break; + case 'h': + usage(EXIT_SUCCESS); + /*NOTREACHED*/ case '?': - usage(0); + usage(EXIT_FAILURE); /*NOTREACHED*/ } if (argc - optind < 2) - usage(-1); + usage(EXIT_FAILURE); out = TIFFOpen(argv[argc-1], bigtiff_output?"w8":"w"); if (out == NULL) - return (-2); + return (EXIT_FAILURE); for (; optind < argc-1; optind++) { in = TIFFOpen(argv[optind], "r"); @@ -132,7 +149,7 @@ main(int argc, char* argv[]) } } (void) TIFFClose(out); - return (0); + return (EXIT_SUCCESS); } static int @@ -166,7 +183,7 @@ cvt_by_tile( TIFF *in, TIFF *out ) if (tile_width != (rastersize / tile_height) / sizeof( uint32)) { TIFFError(TIFFFileName(in), "Integer overflow when calculating raster buffer"); - exit(-1); + exit(EXIT_FAILURE); } raster = (uint32*)_TIFFmalloc(rastersize); if (raster == 0) { @@ -182,7 +199,7 @@ cvt_by_tile( TIFF *in, TIFF *out ) if (tile_width != wrk_linesize / sizeof (uint32)) { TIFFError(TIFFFileName(in), "Integer overflow when calculating wrk_line buffer"); - exit(-1); + exit(EXIT_FAILURE); } wrk_line = (uint32*)_TIFFmalloc(wrk_linesize); if (!wrk_line) { @@ -279,7 +296,7 @@ cvt_by_strip( TIFF *in, TIFF *out ) if (width != (rastersize / rowsperstrip) / sizeof( uint32)) { TIFFError(TIFFFileName(in), "Integer overflow when calculating raster buffer"); - exit(-1); + exit(EXIT_FAILURE); } raster = (uint32*)_TIFFmalloc(rastersize); if (raster == 0) { @@ -295,7 +312,7 @@ cvt_by_strip( TIFF *in, TIFF *out ) if (width != wrk_linesize / sizeof (uint32)) { TIFFError(TIFFFileName(in), "Integer overflow when calculating wrk_line buffer"); - exit(-1); + exit(EXIT_FAILURE); } wrk_line = (uint32*)_TIFFmalloc(wrk_linesize); if (!wrk_line) { @@ -395,6 +412,12 @@ cvt_whole_image( TIFF *in, TIFF *out ) (unsigned long)width, (unsigned long)height); return 0; } + if (maxMalloc != 0 && (tmsize_t)pixel_count * (tmsize_t)sizeof(uint32) > maxMalloc) { + TIFFError(TIFFFileName(in), + "Raster size " TIFF_UINT64_FORMAT " over memory limit (" TIFF_UINT64_FORMAT "), try -b option.", + (uint64)pixel_count * sizeof(uint32), (uint64)maxMalloc); + return 0; + } rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip); TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip); @@ -520,6 +543,13 @@ tiffcvt(TIFF* in, TIFF* out) TIFFSetField(out, TIFFTAG_SOFTWARE, TIFFGetVersion()); CopyField(TIFFTAG_DOCUMENTNAME, stringv); + if (maxMalloc != 0 && TIFFStripSize(in) > maxMalloc) + { + TIFFError(TIFFFileName(in), + "Strip Size " TIFF_UINT64_FORMAT " over memory limit (" TIFF_UINT64_FORMAT ")", + (uint64)TIFFStripSize(in), (uint64)maxMalloc); + return 0; + } if( process_by_block && TIFFIsTiled( in ) ) return( cvt_by_tile( in, out ) ); else if( process_by_block ) @@ -528,8 +558,8 @@ tiffcvt(TIFF* in, TIFF* out) return( cvt_whole_image( in, out ) ); } -static char* stuff[] = { - "usage: tiff2rgba [-c comp] [-r rows] [-b] [-n] [-8] input... output", +static const char* stuff[] = { + "usage: tiff2rgba [-c comp] [-r rows] [-b] [-n] [-8] [-M size] input... output", "where comp is one of the following compression algorithms:", " jpeg\t\tJPEG encoding", " zip\t\tZip/Deflate encoding", @@ -541,19 +571,19 @@ static char* stuff[] = { " -b (progress by block rather than as a whole image)", " -n don't emit alpha component.", " -8 write BigTIFF file instead of ClassicTIFF", + " -M set the memory allocation limit in MiB. 0 to disable limit", NULL }; static void usage(int code) { - char buf[BUFSIZ]; int i; + FILE * out = (code == EXIT_SUCCESS) ? stdout : stderr; - setbuf(stderr, buf); - fprintf(stderr, "%s\n\n", TIFFGetVersion()); + fprintf(out, "%s\n\n", TIFFGetVersion()); for (i = 0; stuff[i] != NULL; i++) - fprintf(stderr, "%s\n", stuff[i]); + fprintf(out, "%s\n", stuff[i]); exit(code); } |