diff options
Diffstat (limited to 'tiff/tools/tiff2ps.c')
-rw-r--r-- | tiff/tools/tiff2ps.c | 122 |
1 files changed, 78 insertions, 44 deletions
diff --git a/tiff/tools/tiff2ps.c b/tiff/tools/tiff2ps.c index 5874aba6..4ed5eba2 100644 --- a/tiff/tools/tiff2ps.c +++ b/tiff/tools/tiff2ps.c @@ -40,6 +40,13 @@ #include "tiffio.h" +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif + /* * Revision history * 2013-Jan-21 @@ -174,6 +181,12 @@ #define FALSE 0 #endif +#define DEFAULT_MAX_MALLOC (256 * 1024 * 1024) + +/* malloc size limit (in bytes) + * disabled when set to 0 */ +static tmsize_t maxMalloc = DEFAULT_MAX_MALLOC; + int ascii85 = FALSE; /* use ASCII85 encoding */ int interpolate = TRUE; /* interpolate level2 image */ int level2 = FALSE; /* generate PostScript level 2 */ @@ -234,6 +247,20 @@ tsize_t Ascii85EncodeBlock( uint8 * ascii85_p, unsigned f_eod, const uint8 * raw static void usage(int); +/** + * This custom malloc function enforce a maximum allocation size + */ +static void* limitMalloc(tmsize_t s) +{ + if (maxMalloc && (s > maxMalloc)) { + fprintf(stderr, "MemoryLimitError: allocation of " TIFF_UINT64_FORMAT " bytes is forbidden. Limit is " TIFF_UINT64_FORMAT ".\n", + (uint64)s, (uint64)maxMalloc); + fprintf(stderr, " use -M option to change limit.\n"); + return NULL; + } + return _TIFFmalloc(s); +} + int main(int argc, char* argv[]) { @@ -252,8 +279,11 @@ main(int argc, char* argv[]) pageOrientation[0] = '\0'; - while ((c = getopt(argc, argv, "b:d:h:H:W:L:i:w:l:o:O:P:C:r:t:acemxyzps1238DT")) != -1) + while ((c = getopt(argc, argv, "b:d:h:H:W:L:M:i:w:l:o:O:P:C:r:t:acemxyzps1238DT")) != -1) switch (c) { + case 'M': + maxMalloc = (tmsize_t)strtoul(optarg, NULL, 0) << 20; + break; case 'b': bottommargin = atof(optarg); break; @@ -309,7 +339,7 @@ main(int argc, char* argv[]) case '9': diroff = (uint32) strtoul(optarg, NULL, 0); break; default: TIFFError ("-o", "Offset must be a numeric value."); - exit (1); + exit (EXIT_FAILURE); } break; case 'O': /* XXX too bad -o is already taken */ @@ -318,21 +348,21 @@ main(int argc, char* argv[]) fprintf(stderr, "%s: %s: Cannot open output file.\n", argv[0], optarg); - exit(-2); + exit (EXIT_FAILURE); } break; case 'P': - switch (optarg[0]) - { - case 'l': - case 'L': strcpy (pageOrientation, "Landscape"); - break; - case 'p': - case 'P': strcpy (pageOrientation, "Portrait"); - break; - default: TIFFError ("-P", "Page orientation must be Landscape or Portrait"); - exit (-1); - } + switch (optarg[0]) + { + case 'l': + case 'L': strcpy (pageOrientation, "Landscape"); + break; + case 'p': + case 'P': strcpy (pageOrientation, "Portrait"); + break; + default: TIFFError ("-P", "Page orientation must be Landscape or Portrait"); + exit (EXIT_FAILURE); + } break; case 'l': leftmargin = atof(optarg); @@ -363,7 +393,7 @@ main(int argc, char* argv[]) break; default: fprintf (stderr, "Rotation angle must be 90, 180, 270 (degrees ccw) or auto\n"); - exit (-1); + exit (EXIT_FAILURE); } break; case 's': @@ -401,7 +431,7 @@ main(int argc, char* argv[]) res_unit = RESUNIT_INCH; break; case '?': - usage(-1); + usage(EXIT_FAILURE); } if (useImagemask == TRUE) @@ -409,14 +439,14 @@ main(int argc, char* argv[]) if ((level2 == FALSE) && (level3 == FALSE)) { TIFFError ("-m "," imagemask operator requres Postscript Level2 or Level3"); - exit (1); + exit (EXIT_FAILURE); } } if (pageWidth && (maxPageWidth > pageWidth)) { TIFFError ("-W", "Max viewport width cannot exceed page width"); - exit (1); + exit (EXIT_FAILURE); } /* auto rotate requires a specified page width and height */ @@ -429,13 +459,13 @@ main(int argc, char* argv[]) if ((maxPageWidth > 0) || (maxPageHeight > 0)) { TIFFError ("-r auto", " is incompatible with maximum page width/height specified by -H or -W"); - exit (1); + exit (EXIT_FAILURE); } } if ((maxPageWidth > 0) && (maxPageHeight > 0)) { TIFFError ("-H and -W", " Use only one of -H or -W to define a viewport"); - exit (1); + exit (EXIT_FAILURE); } if ((generateEPSF == TRUE) && (printAll == TRUE)) @@ -466,13 +496,13 @@ main(int argc, char* argv[]) && !TIFFSetDirectory(tif, (tdir_t)dirnum)) { TIFFClose(tif); - return (-1); + return (EXIT_FAILURE); } else if (diroff != 0 && !TIFFSetSubDirectory(tif, diroff)) { TIFFClose(tif); - return (-1); + return (EXIT_FAILURE); } np = TIFF2PS(output, tif, pageWidth, pageHeight, leftmargin, bottommargin, centered); @@ -486,10 +516,10 @@ main(int argc, char* argv[]) if (np) PSTail(output, np); else - usage(-1); + usage(EXIT_FAILURE); if (output != stdout) fclose(output); - return (0); + return (EXIT_SUCCESS); } static uint16 samplesperpixel; @@ -2187,7 +2217,7 @@ PS_Lvl2page(FILE* fd, TIFF* tif, uint32 w, uint32 h) else chunk_size = TIFFStripSize(tif); } - buf_data = (unsigned char *)_TIFFmalloc(chunk_size); + buf_data = (unsigned char *)limitMalloc(chunk_size); if (!buf_data) { TIFFError(filename, "Can't alloc %lu bytes for %s.", (unsigned long) chunk_size, tiled_image ? "tiles" : "strips"); @@ -2205,7 +2235,7 @@ PS_Lvl2page(FILE* fd, TIFF* tif, uint32 w, uint32 h) * 5*chunk_size/4. */ - ascii85_p = _TIFFmalloc( (chunk_size+(chunk_size/2)) + 8 ); + ascii85_p = limitMalloc( (chunk_size+(chunk_size/2)) + 8 ); if ( !ascii85_p ) { _TIFFfree( buf_data ); @@ -2449,7 +2479,7 @@ PSDataColorContig(FILE* fd, TIFF* tif, uint32 w, uint32 h, int nc) TIFFError(filename, "Inconsistent value of es: %d (samplesperpixel=%u, nc=%d)", es, samplesperpixel, nc); return; } - tf_buf = (unsigned char *) _TIFFmalloc(tf_bytesperrow); + tf_buf = (unsigned char *) limitMalloc(tf_bytesperrow); if (tf_buf == NULL) { TIFFError(filename, "No space for scanline buffer"); return; @@ -2467,8 +2497,10 @@ PSDataColorContig(FILE* fd, TIFF* tif, uint32 w, uint32 h, int nc) } if (alpha) { int adjust; - cc = 0; - for (; (cc + nc) <= tf_bytesperrow; cc += samplesperpixel) { + /* + * the code inside this loop reads nc bytes + 1 extra byte (for adjust) + */ + for (cc = 0; (cc + nc) < tf_bytesperrow; cc += samplesperpixel) { DOBREAK(breaklen, nc, fd); /* * For images with alpha, matte against @@ -2486,8 +2518,10 @@ PSDataColorContig(FILE* fd, TIFF* tif, uint32 w, uint32 h, int nc) cp += es; } } else { - cc = 0; - for (; (cc + nc) <= tf_bytesperrow; cc += samplesperpixel) { + /* + * the code inside this loop reads nc bytes per iteration + */ + for (cc = 0; (cc + nc) <= tf_bytesperrow; cc += samplesperpixel) { DOBREAK(breaklen, nc, fd); switch (nc) { case 4: c = *cp++; PUTHEX(c,fd); @@ -2513,7 +2547,7 @@ PSDataColorSeparate(FILE* fd, TIFF* tif, uint32 w, uint32 h, int nc) unsigned char *cp, c; (void) w; - tf_buf = (unsigned char *) _TIFFmalloc(tf_bytesperrow); + tf_buf = (unsigned char *) limitMalloc(tf_bytesperrow); if (tf_buf == NULL) { TIFFError(filename, "No space for scanline buffer"); return; @@ -2559,7 +2593,7 @@ PSDataPalette(FILE* fd, TIFF* tif, uint32 w, uint32 h) return; } nc = 3 * (8 / bitspersample); - tf_buf = (unsigned char *) _TIFFmalloc(tf_bytesperrow); + tf_buf = (unsigned char *) limitMalloc(tf_bytesperrow); if (tf_buf == NULL) { TIFFError(filename, "No space for scanline buffer"); return; @@ -2624,7 +2658,7 @@ PSDataBW(FILE* fd, TIFF* tif, uint32 w, uint32 h) #endif (void) w; (void) h; - tf_buf = (unsigned char *) _TIFFmalloc(stripsize); + tf_buf = (unsigned char *) limitMalloc(stripsize); if (tf_buf == NULL) { TIFFError(filename, "No space for scanline buffer"); return; @@ -2644,7 +2678,7 @@ PSDataBW(FILE* fd, TIFF* tif, uint32 w, uint32 h) * 5*stripsize/4. */ - ascii85_p = _TIFFmalloc( (stripsize+(stripsize/2)) + 8 ); + ascii85_p = limitMalloc( (stripsize+(stripsize/2)) + 8 ); if ( !ascii85_p ) { _TIFFfree( tf_buf ); @@ -2681,7 +2715,7 @@ PSDataBW(FILE* fd, TIFF* tif, uint32 w, uint32 h) #if defined( EXP_ASCII85ENCODER ) if (alpha) { int adjust, i; - for (i = 0; i < cc; i+=2) { + for (i = 0; i < (cc - 1); i+=2) { adjust = 255 - cp[i + 1]; cp[i / 2] = cp[i] + adjust; } @@ -2771,7 +2805,7 @@ PSRawDataBW(FILE* fd, TIFF* tif, uint32 w, uint32 h) bufsize = (uint32) bc[s]; } - tf_buf = (unsigned char*) _TIFFmalloc(bufsize); + tf_buf = (unsigned char*) limitMalloc(bufsize); if (tf_buf == NULL) { TIFFError(filename, "No space for strip buffer"); return; @@ -2788,7 +2822,7 @@ PSRawDataBW(FILE* fd, TIFF* tif, uint32 w, uint32 h) * 5*bufsize/4. */ - ascii85_p = _TIFFmalloc( (bufsize+(bufsize/2)) + 8 ); + ascii85_p = limitMalloc( (bufsize+(bufsize/2)) + 8 ); if ( !ascii85_p ) { _TIFFfree( tf_buf ); @@ -3014,7 +3048,7 @@ tsize_t Ascii85EncodeBlock( uint8 * ascii85_p, unsigned f_eod, const uint8 * raw tsize_t len; /* Output this many bytes */ len = raw_l + 1; - val32 = *++raw_p << 24; /* Prime the pump */ + val32 = (uint32)*++raw_p << 24; /* Prime the pump */ if ( --raw_l > 0 ) val32 += *(++raw_p) << 16; if ( --raw_l > 0 ) val32 += *(++raw_p) << 8; @@ -3053,7 +3087,7 @@ tsize_t Ascii85EncodeBlock( uint8 * ascii85_p, unsigned f_eod, const uint8 * raw #endif /* EXP_ASCII85ENCODER */ -char* stuff[] = { +const char* stuff[] = { "usage: tiff2ps [options] input.tif ...", "where options are:", " -1 generate PostScript Level 1 (default)", @@ -3075,6 +3109,7 @@ char* stuff[] = { " -i # enable/disable (Nz/0) pixel interpolation (default: enable)", " -l # set the left margin to # inches", " -m use \"imagemask\" operator instead of \"image\"", +" -M size set the memory allocation limit in MiB. 0 to disable limit", " -o # convert directory at file offset # bytes", " -O file write PostScript to file instead of standard output", " -p generate regular (non-encapsulated) PostScript", @@ -3092,13 +3127,12 @@ 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); } |