summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'tiff/tools/tiff2rgba.c')
-rw-r--r--tiff/tools/tiff2rgba.c62
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);
}