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