diff options
author | Thomas Deutschmann <whissi@gentoo.org> | 2021-03-30 10:59:39 +0200 |
---|---|---|
committer | Thomas Deutschmann <whissi@gentoo.org> | 2021-04-01 00:04:14 +0200 |
commit | 5ff1d6955496b3cf9a35042c9ac35db43bc336b1 (patch) | |
tree | 6d470f7eb448f59f53e8df1010aec9dad8ce1f72 /tiff/tools | |
parent | Import Ghostscript 9.53.1 (diff) | |
download | ghostscript-gpl-patches-5ff1d6955496b3cf9a35042c9ac35db43bc336b1.tar.gz ghostscript-gpl-patches-5ff1d6955496b3cf9a35042c9ac35db43bc336b1.tar.bz2 ghostscript-gpl-patches-5ff1d6955496b3cf9a35042c9ac35db43bc336b1.zip |
Import Ghostscript 9.54ghostscript-9.54
Signed-off-by: Thomas Deutschmann <whissi@gentoo.org>
Diffstat (limited to 'tiff/tools')
-rw-r--r-- | tiff/tools/CMakeLists.txt | 27 | ||||
-rw-r--r-- | tiff/tools/Makefile.in | 4 | ||||
-rw-r--r-- | tiff/tools/fax2ps.c | 30 | ||||
-rw-r--r-- | tiff/tools/fax2tiff.c | 23 | ||||
-rw-r--r-- | tiff/tools/pal2rgb.c | 50 | ||||
-rw-r--r-- | tiff/tools/ppm2tiff.c | 230 | ||||
-rw-r--r-- | tiff/tools/raw2tiff.c | 63 | ||||
-rw-r--r-- | tiff/tools/rgb2ycbcr.c | 32 | ||||
-rw-r--r-- | tiff/tools/thumbnail.c | 32 | ||||
-rw-r--r-- | tiff/tools/tiff2bw.c | 40 | ||||
-rw-r--r-- | tiff/tools/tiff2pdf.c | 409 | ||||
-rw-r--r-- | tiff/tools/tiff2ps.c | 122 | ||||
-rw-r--r-- | tiff/tools/tiff2rgba.c | 62 | ||||
-rw-r--r-- | tiff/tools/tiffcmp.c | 42 | ||||
-rw-r--r-- | tiff/tools/tiffcp.c | 149 | ||||
-rw-r--r-- | tiff/tools/tiffcrop.c | 235 | ||||
-rw-r--r-- | tiff/tools/tiffdither.c | 46 | ||||
-rw-r--r-- | tiff/tools/tiffdump.c | 17 | ||||
-rw-r--r-- | tiff/tools/tiffgt.c | 51 | ||||
-rw-r--r-- | tiff/tools/tiffinfo.c | 103 | ||||
-rw-r--r-- | tiff/tools/tiffmedian.c | 49 | ||||
-rw-r--r-- | tiff/tools/tiffset.c | 61 | ||||
-rw-r--r-- | tiff/tools/tiffsplit.c | 17 |
23 files changed, 1269 insertions, 625 deletions
diff --git a/tiff/tools/CMakeLists.txt b/tiff/tools/CMakeLists.txt index 886d4549..ff2a1ddc 100644 --- a/tiff/tools/CMakeLists.txt +++ b/tiff/tools/CMakeLists.txt @@ -123,3 +123,30 @@ if(HAVE_OPENGL) install(TARGETS tiffgt RUNTIME DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}") endif() + +if(WEBP_SUPPORT AND EMSCRIPTEN) + # Emscripten is pretty finnicky about linker flags. + # It needs --shared-memory if and only if atomics or bulk-memory is used. + foreach(target fax2ps + fax2tiff + pal2rgb + ppm2tiff + raw2tiff + rgb2ycbcr + thumbnail + tiff2bw + tiff2pdf + tiff2ps + tiff2rgba + tiffcmp + tiffcp + tiffcrop + tiffdither + tiffdump + tiffinfo + tiffmedian + tiffset + tiffsplit) + target_link_options(${target} PUBLIC "-Wl,--shared-memory") + endforeach() +endif() diff --git a/tiff/tools/Makefile.in b/tiff/tools/Makefile.in index 7ec4ed62..8b1a2460 100644 --- a/tiff/tools/Makefile.in +++ b/tiff/tools/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.2 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/tiff/tools/fax2ps.c b/tiff/tools/fax2ps.c index 274b29e4..f59f4921 100644 --- a/tiff/tools/fax2ps.c +++ b/tiff/tools/fax2ps.c @@ -48,6 +48,13 @@ #include "tiffiop.h" #include "tiffio.h" +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif + float defxres = 204.; /* default x resolution (pixels/inch) */ float defyres = 98.; /* default y resolution (lines/inch) */ const float half = 0.5; @@ -330,7 +337,7 @@ main(int argc, char** argv) int c, dowarnings = 0; /* if 1, enable library warnings */ TIFF* tif; - while ((c = getopt(argc, argv, "l:p:x:y:W:H:wS")) != -1) + while ((c = getopt(argc, argv, "l:p:x:y:W:H:wSh")) != -1) switch (c) { case 'H': /* page height */ pageHeight = (float)atof(optarg); @@ -350,7 +357,7 @@ main(int argc, char** argv) if( pages == NULL ) { fprintf(stderr, "Out of memory\n"); - exit(-1); + exit(EXIT_FAILURE); } pages[npages++] = pageNumber; break; @@ -366,8 +373,10 @@ main(int argc, char** argv) case 'l': maxline = atoi(optarg); break; + case 'h': + usage(EXIT_SUCCESS); case '?': - usage(-1); + usage(EXIT_FAILURE); } if (npages > 0) qsort(pages, npages, sizeof(uint16), pcompar); @@ -391,7 +400,7 @@ main(int argc, char** argv) fd = tmpfile(); if (fd == NULL) { fprintf(stderr, "Could not obtain temporary file.\n"); - exit(-2); + exit(EXIT_FAILURE); } #if defined(HAVE_SETMODE) && defined(O_BINARY) setmode(fileno(stdin), O_BINARY); @@ -401,7 +410,7 @@ main(int argc, char** argv) fclose(fd); fprintf(stderr, "Could not copy stdin to temporary file.\n"); - exit(-2); + exit(EXIT_FAILURE); } } _TIFF_lseek_f(fileno(fd), 0, SEEK_SET); @@ -421,10 +430,10 @@ main(int argc, char** argv) printf("%%%%Pages: %u\n", totalPages); printf("%%%%EOF\n"); - return (0); + return (EXIT_SUCCESS); } -char* stuff[] = { +const char* stuff[] = { "usage: fax2ps [options] [input.tif ...]", "where options are:", " -w suppress warning messages", @@ -441,13 +450,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); } diff --git a/tiff/tools/fax2tiff.c b/tiff/tools/fax2tiff.c index 21223131..eecb41e3 100644 --- a/tiff/tools/fax2tiff.c +++ b/tiff/tools/fax2tiff.c @@ -68,7 +68,7 @@ uint16 badfaxrun; uint32 badfaxlines; int copyFaxFile(TIFF* tifin, TIFF* tifout); -static void usage(void); +static void usage(int code); /* Struct to carry client data. Note that it does not appear that the client @@ -110,7 +110,7 @@ main(int argc, char* argv[]) extern char* optarg; #endif - while ((c = getopt(argc, argv, "R:X:o:r:1234ABLMPUW5678abcflmprsuvwz?")) != -1) + while ((c = getopt(argc, argv, "R:X:o:r:1234ABLMPUW5678abcflmprsuvwzh")) != -1) switch (c) { /* input-related options */ case '3': /* input is g3-encoded */ @@ -216,13 +216,15 @@ main(int argc, char* argv[]) case 'v': /* -v for info */ verbose++; break; + case 'h': + usage(EXIT_SUCCESS); case '?': - usage(); + usage(EXIT_FAILURE); /*NOTREACHED*/ } npages = argc - optind; if (npages < 1) - usage(); + usage(EXIT_FAILURE); rowbuf = _TIFFmalloc(TIFFhowmany8(xsize)); refbuf = _TIFFmalloc(TIFFhowmany8(xsize)); @@ -426,7 +428,7 @@ copyFaxFile(TIFF* tifin, TIFF* tifout) return (row); } -char* stuff[] = { +const char* stuff[] = { "usage: fax2tiff [options] input.raw...", "where options are:", " -3 input data is G3-encoded [default]", @@ -463,16 +465,15 @@ NULL }; static void -usage(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]); - exit(EXIT_FAILURE); + fprintf(out, "%s\n", stuff[i]); + exit(code); } /* vim: set ts=8 sts=8 sw=8 noet: */ diff --git a/tiff/tools/pal2rgb.c b/tiff/tools/pal2rgb.c index 9492f1cf..bf95cb37 100644 --- a/tiff/tools/pal2rgb.c +++ b/tiff/tools/pal2rgb.c @@ -39,10 +39,17 @@ #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 strneq(a,b,n) (strncmp(a,b,n) == 0) -static void usage(void); +static void usage(int code); static void cpTags(TIFF* in, TIFF* out); static int @@ -85,14 +92,14 @@ main(int argc, char* argv[]) extern char* optarg; #endif - while ((c = getopt(argc, argv, "C:c:p:r:")) != -1) + while ((c = getopt(argc, argv, "C:c:p:r:h")) != -1) switch (c) { case 'C': /* force colormap interpretation */ cmap = atoi(optarg); break; case 'c': /* compression scheme */ if (!processCompressOptions(optarg)) - usage(); + usage(EXIT_FAILURE); break; case 'p': /* planar configuration */ if (streq(optarg, "separate")) @@ -100,33 +107,35 @@ main(int argc, char* argv[]) else if (streq(optarg, "contig")) config = PLANARCONFIG_CONTIG; else - usage(); + usage(EXIT_FAILURE); break; case 'r': /* rows/strip */ rowsperstrip = atoi(optarg); break; + case 'h': + usage(EXIT_SUCCESS); case '?': - usage(); + usage(EXIT_FAILURE); /*NOTREACHED*/ } if (argc - optind != 2) - usage(); + usage(EXIT_FAILURE); in = TIFFOpen(argv[optind], "r"); if (in == NULL) - return (-1); + return (EXIT_FAILURE); if (!TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &shortv) || shortv != PHOTOMETRIC_PALETTE) { fprintf(stderr, "%s: Expecting a palette image.\n", argv[optind]); (void) TIFFClose(in); - return (-1); + return (EXIT_FAILURE); } if (!TIFFGetField(in, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) { fprintf(stderr, "%s: No colormap (not a valid palette image).\n", argv[optind]); (void) TIFFClose(in); - return (-1); + return (EXIT_FAILURE); } bitspersample = 0; TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample); @@ -134,12 +143,12 @@ main(int argc, char* argv[]) fprintf(stderr, "%s: Sorry, can only handle 8-bit images.\n", argv[optind]); (void) TIFFClose(in); - return (-1); + return (EXIT_FAILURE); } out = TIFFOpen(argv[optind+1], "w"); if (out == NULL) { (void) TIFFClose(in); - return (-2); + return (EXIT_FAILURE); } cpTags(in, out); TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &imagewidth); @@ -198,7 +207,7 @@ main(int argc, char* argv[]) * buffer overflow. Go ahead and fail now to prevent that. */ fprintf(stderr, "Could not determine correct image size for output. Exiting.\n"); - return -1; + return EXIT_FAILURE; } ibuf = (unsigned char*)_TIFFmalloc(tss_in); obuf = (unsigned char*)_TIFFmalloc(tss_out); @@ -242,7 +251,7 @@ main(int argc, char* argv[]) done: (void) TIFFClose(in); (void) TIFFClose(out); - return (0); + return (EXIT_SUCCESS); } static int @@ -263,7 +272,7 @@ processCompressOptions(char* opt) else if (cp[1] == 'r' ) jpegcolormode = JPEGCOLORMODE_RAW; else - usage(); + usage(EXIT_FAILURE); cp = strchr(cp+1,':'); } @@ -427,7 +436,7 @@ cpTags(TIFF* in, TIFF* out) } #undef NTAGS -char* stuff[] = { +const char* stuff[] = { "usage: pal2rgb [options] input.tif output.tif", "where options are:", " -p contig pack samples contiguously (e.g. RGBRGB...)", @@ -448,16 +457,15 @@ NULL }; static void -usage(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]); - exit(-1); + fprintf(out, "%s\n", stuff[i]); + exit(code); } /* vim: set ts=8 sts=8 sw=8 noet: */ diff --git a/tiff/tools/ppm2tiff.c b/tiff/tools/ppm2tiff.c index 2b275618..c6332439 100644 --- a/tiff/tools/ppm2tiff.c +++ b/tiff/tools/ppm2tiff.c @@ -51,6 +51,13 @@ extern int getopt(int argc, char * const argv[], const char *optstring); #endif +#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 strneq(a,b,n) (strncmp(a,b,n) == 0) @@ -60,14 +67,109 @@ static int quality = 75; /* JPEG quality */ static int jpegcolormode = JPEGCOLORMODE_RGB; static uint32 g3opts; -static void usage(void); +static void usage(int code); static int processCompressOptions(char*); static void +pack_none (unsigned char *buf, unsigned int smpls, uint16 bps) +{ + (void)buf; + (void)smpls; + (void)bps; + return; +} + +static void +pack_swab (unsigned char *buf, unsigned int smpls, uint16 bps) +{ + unsigned int s; + unsigned char h; + unsigned char l; + (void)bps; + + for (s = 0; smpls > s; s++) { + + h = buf [s * 2 + 0]; + l = buf [s * 2 + 1]; + + buf [s * 2 + 0] = l; + buf [s * 2 + 1] = h; + } + return; +} + +static void +pack_bytes (unsigned char *buf, unsigned int smpls, uint16 bps) +{ + unsigned int s; + unsigned int in; + unsigned int out; + int bits; + uint16 t; + + in = 0; + out = 0; + bits = 0; + t = 0; + + for (s = 0; smpls > s; s++) { + + t <<= bps; + t |= (uint16) buf [in++]; + + bits += bps; + + if (8 <= bits) { + bits -= 8; + buf [out++] = (t >> bits) & 0xFF; + } + } + if (0 != bits) + buf [out] = (t << (8 - bits)) & 0xFF; +} + +static void +pack_words (unsigned char *buf, unsigned int smpls, uint16 bps) +{ + unsigned int s; + unsigned int in; + unsigned int out; + int bits; + uint32 t; + + in = 0; + out = 0; + bits = 0; + t = 0; + + for (s = 0; smpls > s; s++) { + + t <<= bps; + t |= (uint32) buf [in++] << 8; + t |= (uint32) buf [in++] << 0; + + bits += bps; + + if (16 <= bits) { + + bits -= 16; + buf [out++] = (t >> (bits + 8)); + buf [out++] = (t >> (bits + 0)); + } + } + if (0 != bits) { + t <<= 16 - bits; + + buf [out++] = (t >> (16 + 8)); + buf [out++] = (t >> (16 + 0)); + } +} + +static void BadPPM(char* file) { fprintf(stderr, "%s: Not a PPM file.\n", file); - exit(-2); + exit(EXIT_FAILURE); } @@ -90,8 +192,10 @@ main(int argc, char* argv[]) double resolution = -1; unsigned char *buf = NULL; tmsize_t linebytes = 0; + int pbm; uint16 spp = 1; uint16 bpp = 8; + void (*pack_func) (unsigned char *buf, unsigned int smpls, uint16 bps); TIFF *out; FILE *in; unsigned int w, h, prec, row; @@ -105,13 +209,13 @@ main(int argc, char* argv[]) if (argc < 2) { fprintf(stderr, "%s: Too few arguments\n", argv[0]); - usage(); + usage(EXIT_FAILURE); } - while ((c = getopt(argc, argv, "c:r:R:")) != -1) + while ((c = getopt(argc, argv, "c:r:R:h")) != -1) switch (c) { case 'c': /* compression scheme */ if (!processCompressOptions(optarg)) - usage(); + usage(EXIT_FAILURE); break; case 'r': /* rows/strip */ rowsperstrip = atoi(optarg); @@ -119,14 +223,16 @@ main(int argc, char* argv[]) case 'R': /* resolution */ resolution = atof(optarg); break; + case 'h': + usage(EXIT_SUCCESS); case '?': - usage(); + usage(EXIT_FAILURE); /*NOTREACHED*/ } if (optind + 2 < argc) { fprintf(stderr, "%s: Too many arguments\n", argv[0]); - usage(); + usage(EXIT_FAILURE); } /* @@ -138,7 +244,7 @@ main(int argc, char* argv[]) in = fopen(infile, "rb"); if (in == NULL) { fprintf(stderr, "%s: Can not open.\n", infile); - return (-1); + return (EXIT_FAILURE); } } else { infile = "<stdin>"; @@ -152,17 +258,17 @@ main(int argc, char* argv[]) BadPPM(infile); switch (fgetc(in)) { case '4': /* it's a PBM file */ - bpp = 1; + pbm = !0; spp = 1; photometric = PHOTOMETRIC_MINISWHITE; break; case '5': /* it's a PGM file */ - bpp = 8; + pbm = 0; spp = 1; photometric = PHOTOMETRIC_MINISBLACK; break; case '6': /* it's a PPM file */ - bpp = 8; + pbm = 0; spp = 3; photometric = PHOTOMETRIC_RGB; if (compression == COMPRESSION_JPEG && @@ -193,23 +299,56 @@ main(int argc, char* argv[]) ungetc(c, in); break; } - switch (bpp) { - case 1: + if (pbm) { if (fscanf(in, " %u %u", &w, &h) != 2) BadPPM(infile); if (fgetc(in) != '\n') BadPPM(infile); - break; - case 8: + bpp = 1; + pack_func = pack_none; + } else { if (fscanf(in, " %u %u %u", &w, &h, &prec) != 3) BadPPM(infile); - if (fgetc(in) != '\n' || prec != 255) + if (fgetc(in) != '\n' || 0 == prec || 65535 < prec) BadPPM(infile); - break; + + if (0 != (prec & (prec + 1))) { + fprintf(stderr, "%s: unsupported maxval %u.\n", + infile, prec); + exit(EXIT_FAILURE); + } + bpp = 0; + if ((prec + 1) & 0xAAAAAAAA) bpp |= 1; + if ((prec + 1) & 0xCCCCCCCC) bpp |= 2; + if ((prec + 1) & 0xF0F0F0F0) bpp |= 4; + if ((prec + 1) & 0xFF00FF00) bpp |= 8; + if ((prec + 1) & 0xFFFF0000) bpp |= 16; + + switch (bpp) { + case 8: + pack_func = pack_none; + break; + case 16: + { + const unsigned short i = 0x0100; + + if (0 == *(unsigned char*) &i) + pack_func = pack_swab; + else + pack_func = pack_none; + } + break; + default: + if (8 >= bpp) + pack_func = pack_bytes; + else + pack_func = pack_words; + break; + } } out = TIFFOpen(argv[optind], "w"); if (out == NULL) - return (-4); + return (EXIT_FAILURE); TIFFSetField(out, TIFFTAG_IMAGEWIDTH, (uint32) w); TIFFSetField(out, TIFFTAG_IMAGELENGTH, (uint32) h); TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); @@ -232,33 +371,30 @@ main(int argc, char* argv[]) TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, g3opts); break; } - switch (bpp) { - case 1: - /* if round-up overflows, result will be zero, OK */ - linebytes = (multiply_ms(spp, w) + (8 - 1)) / 8; - if (rowsperstrip == (uint32) -1) { - TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, h); - } else { - TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, - TIFFDefaultStripSize(out, rowsperstrip)); - } - break; - case 8: - linebytes = multiply_ms(spp, w); - TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, - TIFFDefaultStripSize(out, rowsperstrip)); - break; + if (pbm) { + /* if round-up overflows, result will be zero, OK */ + linebytes = (multiply_ms(spp, w) + (8 - 1)) / 8; + } else if (bpp <= 8) { + linebytes = multiply_ms(spp, w); + } else { + linebytes = multiply_ms(2 * spp, w); + } + if (rowsperstrip == (uint32) -1) { + TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, h); + } else { + TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, + TIFFDefaultStripSize(out, rowsperstrip)); } if (linebytes == 0) { fprintf(stderr, "%s: scanline size overflow\n", infile); (void) TIFFClose(out); - exit(-2); + exit(EXIT_FAILURE); } scanline_size = TIFFScanlineSize(out); if (scanline_size == 0) { /* overflow - TIFFScanlineSize already printed a message */ (void) TIFFClose(out); - exit(-2); + exit(EXIT_FAILURE); } if (scanline_size < linebytes) buf = (unsigned char *)_TIFFmalloc(linebytes); @@ -267,7 +403,7 @@ main(int argc, char* argv[]) if (buf == NULL) { fprintf(stderr, "%s: Not enough memory\n", infile); (void) TIFFClose(out); - exit(-2); + exit(EXIT_FAILURE); } if (resolution > 0) { TIFFSetField(out, TIFFTAG_XRESOLUTION, resolution); @@ -280,6 +416,7 @@ main(int argc, char* argv[]) infile, (unsigned long) row); break; } + pack_func (buf, w * spp, bpp); if (TIFFWriteScanline(out, buf, row, 0) < 0) break; } @@ -288,7 +425,7 @@ main(int argc, char* argv[]) (void) TIFFClose(out); if (buf) _TIFFfree(buf); - return (0); + return (EXIT_SUCCESS); } static void @@ -305,7 +442,7 @@ processG3Options(char* cp) else if (strneq(cp, "fill", 4)) g3opts |= GROUP3OPT_FILLBITS; else - usage(); + usage(EXIT_FAILURE); } while( (cp = strchr(cp, ':')) ); } } @@ -328,7 +465,7 @@ processCompressOptions(char* opt) else if (cp[1] == 'r' ) jpegcolormode = JPEGCOLORMODE_RAW; else - usage(); + usage(EXIT_FAILURE); cp = strchr(cp+1,':'); } @@ -352,7 +489,7 @@ processCompressOptions(char* opt) return (1); } -char* stuff[] = { +const char* stuff[] = { "usage: ppm2tiff [options] input.ppm output.tif", "where options are:", " -r # make each strip have no more than # rows", @@ -376,16 +513,15 @@ NULL }; static void -usage(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]); - exit(-1); + fprintf(out, "%s\n", stuff[i]); + exit(code); } /* vim: set ts=8 sts=8 sw=8 noet: */ diff --git a/tiff/tools/raw2tiff.c b/tiff/tools/raw2tiff.c index ab36ff4e..8bbdc045 100644 --- a/tiff/tools/raw2tiff.c +++ b/tiff/tools/raw2tiff.c @@ -59,6 +59,13 @@ #include "tiffiop.h" #include "tiffio.h" +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif + #ifndef HAVE_GETOPT extern int getopt(int argc, char * const argv[], const char *optstring); #endif @@ -81,7 +88,7 @@ static void swapBytesInScanline(void *, uint32, TIFFDataType); static int guessSize(int, TIFFDataType, _TIFF_off_t, uint32, int, uint32 *, uint32 *); static double correlation(void *, void *, uint32, TIFFDataType); -static void usage(void); +static void usage(int); static int processCompressOptions(char*); int @@ -114,7 +121,7 @@ main(int argc, char* argv[]) switch (c) { case 'c': /* compression scheme */ if (!processCompressOptions(optarg)) - usage(); + usage(EXIT_FAILURE); break; case 'r': /* rows/strip */ rowsperstrip = atoi(optarg); @@ -193,24 +200,24 @@ main(int argc, char* argv[]) outfilename = optarg; break; case 'h': - usage(); + usage(EXIT_SUCCESS); default: break; } } if (argc - optind < 2) - usage(); + usage(EXIT_FAILURE); fd = open(argv[optind], O_RDONLY|O_BINARY, 0); if (fd < 0) { fprintf(stderr, "%s: %s: Cannot open input file.\n", argv[0], argv[optind]); - return (-1); + return (EXIT_FAILURE); } if (guessSize(fd, dtype, hdr_size, nbands, swab, &width, &length) < 0) - return 1; + return EXIT_FAILURE; if (outfilename == NULL) outfilename = argv[optind+1]; @@ -218,7 +225,7 @@ main(int argc, char* argv[]) if (out == NULL) { fprintf(stderr, "%s: %s: Cannot open file for output.\n", argv[0], outfilename); - return (-1); + return (EXIT_FAILURE); } TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width); TIFFSetField(out, TIFFTAG_IMAGELENGTH, length); @@ -336,7 +343,7 @@ main(int argc, char* argv[]) if (buf1) _TIFFfree(buf1); TIFFClose(out); - return (0); + return (EXIT_SUCCESS); } static void @@ -372,7 +379,7 @@ guessSize(int fd, TIFFDataType dtype, _TIFF_off_t hdr_size, uint32 nbands, _TIFF_stat_s filestat; uint32 w, h, scanlinesize, imagesize; uint32 depth = TIFFDataWidth(dtype); - float cor_coef = 0, tmp; + double cor_coef = 0, tmp; if (_TIFF_fstat_f(fd, &filestat) == -1) { fprintf(stderr, "Failed to obtain file size.\n"); @@ -419,22 +426,28 @@ guessSize(int fd, TIFFDataType dtype, _TIFF_off_t hdr_size, uint32 nbands, w++) { if (imagesize % w == 0) { scanlinesize = w * depth; + h = imagesize / w; + if (h < 2) + continue; + /* reads 2 lines at the middle of the image and calculate their correlation. + * it works for h >= 2. (in this case it will compare line 0 and line 1 */ buf1 = _TIFFmalloc(scanlinesize); buf2 = _TIFFmalloc(scanlinesize); - h = imagesize / w; do { - if (_TIFF_lseek_f(fd, hdr_size + (int)(h/2)*scanlinesize, + if (_TIFF_lseek_f(fd, hdr_size + (int)((h - 1)/2)*scanlinesize, SEEK_SET) == (_TIFF_off_t)-1) { fprintf(stderr, "seek error.\n"); fail=1; break; } + /* read line (h-1)/2 */ if (read(fd, buf1, scanlinesize) != (long) scanlinesize) { fprintf(stderr, "read error.\n"); fail=1; break; } + /* read line ((h-1)/2)+1 */ if (read(fd, buf2, scanlinesize) != (long) scanlinesize) { fprintf(stderr, "read error.\n"); @@ -445,11 +458,15 @@ guessSize(int fd, TIFFDataType dtype, _TIFF_off_t hdr_size, uint32 nbands, swapBytesInScanline(buf1, w, dtype); swapBytesInScanline(buf2, w, dtype); } - tmp = (float) fabs(correlation(buf1, buf2, - w, dtype)); - if (tmp > cor_coef) { - cor_coef = tmp; + if (0 == memcmp(buf1, buf2, scanlinesize)) { *width = w, *length = h; + } else { + tmp = fabs(correlation(buf1, buf2, + w, dtype)); + if (tmp > cor_coef) { + cor_coef = tmp; + *width = w, *length = h; + } } } while (0); @@ -564,6 +581,7 @@ correlation(void *buf1, void *buf2, uint32 n_elem, TIFFDataType dtype) M2 /= n_elem; D1 -= M1 * M1 * n_elem; D2 -= M2 * M2 * n_elem; + if (D1 * D2 == 0.0) return 0.0; /* avoid divide by zero */ K = (K - M1 * M2 * n_elem) / sqrt(D1 * D2); return K; @@ -587,7 +605,7 @@ processCompressOptions(char* opt) else if (cp[1] == 'r' ) jpegcolormode = JPEGCOLORMODE_RAW; else - usage(); + usage(EXIT_FAILURE); cp = strchr(cp+1,':'); } @@ -606,7 +624,7 @@ processCompressOptions(char* opt) return (1); } -static char* stuff[] = { +static const char* stuff[] = { "raw2tiff --- tool for converting raw byte sequences in TIFF images", "usage: raw2tiff [options] input.raw output.tif", "where options are:", @@ -667,16 +685,15 @@ NULL }; static void -usage(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]); - exit(-1); + fprintf(out, "%s\n", stuff[i]); + exit(code); } /* vim: set ts=8 sts=8 sw=8 noet: */ diff --git a/tiff/tools/rgb2ycbcr.c b/tiff/tools/rgb2ycbcr.c index cf5f956f..482cc5b4 100644 --- a/tiff/tools/rgb2ycbcr.c +++ b/tiff/tools/rgb2ycbcr.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) @@ -89,17 +96,17 @@ main(int argc, char* argv[]) else if (streq(optarg, "zip")) compression = COMPRESSION_ADOBE_DEFLATE; else - usage(-1); + usage(EXIT_FAILURE); break; case 'h': horizSubSampling = atoi(optarg); if( horizSubSampling != 1 && horizSubSampling != 2 && horizSubSampling != 4 ) - usage(-1); + usage(EXIT_FAILURE); break; case 'v': vertSubSampling = atoi(optarg); if( vertSubSampling != 1 && vertSubSampling != 2 && vertSubSampling != 4 ) - usage(-1); + usage(EXIT_FAILURE); break; case 'r': rowsperstrip = atoi(optarg); @@ -113,14 +120,14 @@ main(int argc, char* argv[]) refBlackWhite[5] = 240.; break; case '?': - usage(0); + usage(EXIT_FAILURE); /*NOTREACHED*/ } if (argc - optind < 2) - usage(-1); + usage(EXIT_FAILURE); out = TIFFOpen(argv[argc-1], "w"); if (out == NULL) - return (-2); + return (EXIT_FAILURE); setupLumaTables(); for (; optind < argc-1; optind++) { in = TIFFOpen(argv[optind], "r"); @@ -129,6 +136,7 @@ main(int argc, char* argv[]) if (!tiffcvt(in, out) || !TIFFWriteDirectory(out)) { (void) TIFFClose(out); + (void) TIFFClose(in); return (1); } } while (TIFFReadDirectory(in)); @@ -136,7 +144,7 @@ main(int argc, char* argv[]) } } (void) TIFFClose(out); - return (0); + return (EXIT_SUCCESS); } float *lumaRed; @@ -356,7 +364,7 @@ tiffcvt(TIFF* in, TIFF* out) return result; } -char* stuff[] = { +const char* stuff[] = { "usage: rgb2ycbcr [-c comp] [-r rows] [-h N] [-v N] input... output\n", "where comp is one of the following compression algorithms:\n", " jpeg\t\tJPEG encoding\n", @@ -374,14 +382,12 @@ char* stuff[] = { 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); } diff --git a/tiff/tools/thumbnail.c b/tiff/tools/thumbnail.c index 169a6369..edb69983 100644 --- a/tiff/tools/thumbnail.c +++ b/tiff/tools/thumbnail.c @@ -39,6 +39,13 @@ #include "tiffio.h" +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif + #ifndef HAVE_GETOPT extern int getopt(int argc, char * const argv[], const char *optstring); #endif @@ -67,7 +74,7 @@ static uint8* thumbnail; static int cpIFD(TIFF*, TIFF*); static int generateThumbnail(TIFF*, TIFF*); static void initScale(); -static void usage(void); +static void usage(int code); #if !HAVE_DECL_OPTARG extern char* optarg; @@ -94,11 +101,11 @@ main(int argc, char* argv[]) streq(optarg, "linear")? LINEAR : EXP; break; - default: usage(); + default: usage(EXIT_FAILURE); } } if (argc-optind != 2) - usage(); + usage(EXIT_FAILURE); out = TIFFOpen(argv[optind+1], "w"); if (out == NULL) @@ -111,7 +118,7 @@ main(int argc, char* argv[]) if (!thumbnail) { TIFFError(TIFFFileName(in), "Can't allocate space for thumbnail buffer."); - return 1; + return EXIT_FAILURE; } if (in != NULL) { @@ -125,10 +132,10 @@ main(int argc, char* argv[]) (void) TIFFClose(in); } (void) TIFFClose(out); - return 0; + return EXIT_SUCCESS; bad: (void) TIFFClose(out); - return 1; + return EXIT_FAILURE; } #define CopyField(tag, v) \ @@ -650,7 +657,7 @@ generateThumbnail(TIFF* in, TIFF* out) TIFFWriteDirectory(out) != -1); } -char* stuff[] = { +const char* stuff[] = { "usage: thumbnail [options] input.tif output.tif", "where options are:", " -h # specify thumbnail image height (default is 274)", @@ -667,16 +674,15 @@ NULL }; static void -usage(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]); - exit(-1); + fprintf(out, "%s\n", stuff[i]); + exit(code); } /* vim: set ts=8 sts=8 sw=8 noet: */ diff --git a/tiff/tools/tiff2bw.c b/tiff/tools/tiff2bw.c index dbc697b0..654bd324 100644 --- a/tiff/tools/tiff2bw.c +++ b/tiff/tools/tiff2bw.c @@ -40,13 +40,20 @@ #include "tiffio.h" #include "tiffiop.h" +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif + /* x% weighting -> fraction of full color */ #define PCT(x) (((x)*256+50)/100) int RED = PCT(30); /* 30% */ int GREEN = PCT(59); /* 59% */ int BLUE = PCT(11); /* 11% */ -static void usage(void); +static void usage(int code); static int processCompressOptions(char*); static void @@ -133,11 +140,11 @@ main(int argc, char* argv[]) inbuf = (unsigned char *) NULL; outbuf = (unsigned char *) NULL; - while ((c = getopt(argc, argv, "c:r:R:G:B:")) != -1) + while ((c = getopt(argc, argv, "c:r:R:G:B:h")) != -1) switch (c) { case 'c': /* compression scheme */ if (!processCompressOptions(optarg)) - usage(); + usage(EXIT_FAILURE); break; case 'r': /* rows/strip */ rowsperstrip = atoi(optarg); @@ -151,15 +158,17 @@ main(int argc, char* argv[]) case 'B': BLUE = PCT(atoi(optarg)); break; + case 'h': + usage(EXIT_SUCCESS); case '?': - usage(); + usage(EXIT_FAILURE); /*NOTREACHED*/ } if (argc - optind < 2) - usage(); + usage(EXIT_FAILURE); in = TIFFOpen(argv[optind], "r"); if (in == NULL) - return (-1); + return (EXIT_FAILURE); photometric = 0; TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &photometric); if (photometric != PHOTOMETRIC_RGB && photometric != PHOTOMETRIC_PALETTE ) { @@ -306,7 +315,7 @@ main(int argc, char* argv[]) _TIFFfree(outbuf); TIFFClose(in); TIFFClose(out); - return (0); + return (EXIT_SUCCESS); tiff2bw_error: if (inbuf) @@ -317,7 +326,7 @@ main(int argc, char* argv[]) TIFFClose(out); if (in) TIFFClose(in); - return (-1); + return (EXIT_FAILURE); } static int @@ -338,7 +347,7 @@ processCompressOptions(char* opt) else if (cp[1] == 'r' ) jpegcolormode = JPEGCOLORMODE_RAW; else - usage(); + usage(EXIT_FAILURE); cp = strchr(cp+1,':'); } @@ -492,7 +501,7 @@ cpTags(TIFF* in, TIFF* out) } #undef NTAGS -char* stuff[] = { +const char* stuff[] = { "usage: tiff2bw [options] input.tif output.tif", "where options are:", " -R % use #% from red channel", @@ -515,16 +524,15 @@ NULL }; static void -usage(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]); - exit(-1); + fprintf(out, "%s\n", stuff[i]); + exit(code); } /* vim: set ts=8 sts=8 sw=8 noet: */ diff --git a/tiff/tools/tiff2pdf.c b/tiff/tools/tiff2pdf.c index 779c1662..acaef0d6 100644 --- a/tiff/tools/tiff2pdf.c +++ b/tiff/tools/tiff2pdf.c @@ -70,6 +70,8 @@ extern int getopt(int argc, char * const argv[], const char *optstring); #define TIFF_DIR_MAX 65534 +#define DEFAULT_MAX_MALLOC (256 * 1024 * 1024) + /* This type is of PDF color spaces. */ typedef enum { T2P_CS_BILEVEL = 0x01, /* Bilevel, black and white */ @@ -176,6 +178,7 @@ typedef struct { uint16 tiff_orientation; toff_t tiff_dataoffset; tsize_t tiff_datasize; + tsize_t tiff_maxdatasize; uint16 tiff_resunit; uint16 pdf_centimeters; uint16 pdf_overrideres; @@ -207,14 +210,19 @@ typedef struct { char pdf_datetime[TIFF2PDF_DATETIME_SIZE]; #define TIFF2PDF_CREATOR_SIZE 512 char pdf_creator[TIFF2PDF_CREATOR_SIZE]; + int pdf_creator_set; #define TIFF2PDF_AUTHOR_SIZE 512 char pdf_author[TIFF2PDF_AUTHOR_SIZE]; + int pdf_author_set; #define TIFF2PDF_TITLE_SIZE 512 char pdf_title[TIFF2PDF_TITLE_SIZE]; + int pdf_title_set; #define TIFF2PDF_SUBJECT_SIZE 512 char pdf_subject[TIFF2PDF_SUBJECT_SIZE]; + int pdf_subject_set; #define TIFF2PDF_KEYWORDS_SIZE 512 char pdf_keywords[TIFF2PDF_KEYWORDS_SIZE]; + int pdf_keywords_set; t2p_cs_t pdf_colorspace; uint16 pdf_colorspace_invert; uint16 pdf_switchdecode; @@ -224,7 +232,7 @@ typedef struct { t2p_compress_t pdf_defaultcompression; uint16 pdf_defaultcompressionquality; t2p_compress_t pdf_compression; - uint16 pdf_compressionquality; + uint16 pdf_compressionquality; /* for deflate : 100 * zipquality + predictor */ uint16 pdf_nopassthrough; t2p_transcode_t pdf_transcode; t2p_sample_t pdf_sample; @@ -255,7 +263,7 @@ typedef struct { /* These functions are called by main. */ -void tiff2pdf_usage(void); +static void tiff2pdf_usage(int); int tiff2pdf_match_paper_size(float*, float*, char*); /* These functions are used to generate a PDF from a TIFF. */ @@ -301,8 +309,8 @@ tsize_t t2p_sample_lab_signed_to_unsigned(tdata_t, uint32); tsize_t t2p_write_pdf_header(T2P*, TIFF*); tsize_t t2p_write_pdf_obj_start(uint32, TIFF*); tsize_t t2p_write_pdf_obj_end(TIFF*); -tsize_t t2p_write_pdf_name(unsigned char*, TIFF*); -tsize_t t2p_write_pdf_string(char*, TIFF*); +tsize_t t2p_write_pdf_name(const unsigned char*, TIFF*); +tsize_t t2p_write_pdf_string(const char*, TIFF*); tsize_t t2p_write_pdf_stream(tdata_t, tsize_t, TIFF*); tsize_t t2p_write_pdf_stream_start(TIFF*); tsize_t t2p_write_pdf_stream_end(TIFF*); @@ -617,8 +625,11 @@ int main(int argc, char** argv){ while (argv && (c = getopt(argc, argv, - "o:q:u:x:y:w:l:r:p:e:c:a:t:s:k:jzndifbhF")) != -1){ + "m:o:q:u:x:y:w:l:r:p:e:c:a:t:s:k:jzndifbhF")) != -1){ switch (c) { + case 'm': + t2p->tiff_maxdatasize = (tsize_t)strtoul(optarg, NULL, 0) << 20; + break; case 'o': outfilename = optarg; break; @@ -718,31 +729,37 @@ int main(int argc, char** argv){ case 'c': strncpy(t2p->pdf_creator, optarg, sizeof(t2p->pdf_creator) - 1); t2p->pdf_creator[sizeof(t2p->pdf_creator) - 1] = '\0'; + t2p->pdf_creator_set = 1; break; case 'a': strncpy(t2p->pdf_author, optarg, sizeof(t2p->pdf_author) - 1); t2p->pdf_author[sizeof(t2p->pdf_author) - 1] = '\0'; + t2p->pdf_author_set = 1; break; case 't': strncpy(t2p->pdf_title, optarg, sizeof(t2p->pdf_title) - 1); t2p->pdf_title[sizeof(t2p->pdf_title) - 1] = '\0'; + t2p->pdf_title_set = 1; break; case 's': strncpy(t2p->pdf_subject, optarg, sizeof(t2p->pdf_subject) - 1); t2p->pdf_subject[sizeof(t2p->pdf_subject) - 1] = '\0'; + t2p->pdf_subject_set = 1; break; case 'k': strncpy(t2p->pdf_keywords, optarg, sizeof(t2p->pdf_keywords) - 1); t2p->pdf_keywords[sizeof(t2p->pdf_keywords) - 1] = '\0'; + t2p->pdf_keywords_set = 1; break; case 'b': t2p->pdf_image_interpolate = 1; break; - case 'h': - case '?': - tiff2pdf_usage(); + case 'h': + tiff2pdf_usage(EXIT_SUCCESS); goto success; - break; + case '?': + tiff2pdf_usage(EXIT_FAILURE); + goto fail; } } @@ -759,14 +776,14 @@ int main(int argc, char** argv){ } } else { TIFFError(TIFF2PDF_MODULE, "No input file specified"); - tiff2pdf_usage(); + tiff2pdf_usage(EXIT_FAILURE); goto fail; } if(argc > optind) { TIFFError(TIFF2PDF_MODULE, "No support for multiple input files"); - tiff2pdf_usage(); + tiff2pdf_usage(EXIT_FAILURE); goto fail; } @@ -828,8 +845,8 @@ success: } -void tiff2pdf_usage(){ - char* lines[]={ +static void tiff2pdf_usage(int code) { + static const char* lines[]={ "usage: tiff2pdf [options] input.tiff", "options:", " -o: output to file name", @@ -850,7 +867,7 @@ void tiff2pdf_usage(){ " -l: length in units", " -r: 'd' for resolution default, 'o' for resolution override", " -p: paper size, eg \"letter\", \"legal\", \"A4\"", - " -F: make the tiff fill the PDF page", + " -F: make the tiff fill the PDF page", " -f: set PDF \"Fit Window\" user preference", " -e: date, overrides image or current date/time default, YYYYMMDDHHMMSS", " -c: sets document creator, overrides image software default", @@ -859,14 +876,16 @@ void tiff2pdf_usage(){ " -s: sets document subject, overrides image image description default", " -k: sets document keywords", " -b: set PDF \"Interpolate\" user preference", + " -m: set memory allocation limit (in MiB). set to 0 to disable limit", " -h: usage", NULL }; int i=0; + FILE * out = (code == EXIT_SUCCESS) ? stdout : stderr; - fprintf(stderr, "%s\n\n", TIFFGetVersion()); + fprintf(out, "%s\n\n", TIFFGetVersion()); for (i=0;lines[i]!=NULL;i++){ - fprintf(stderr, "%s\n", lines[i]); + fprintf(out, "%s\n", lines[i]); } return; @@ -954,6 +973,7 @@ T2P* t2p_init() t2p->pdf_defaultpagewidth=612.0; t2p->pdf_defaultpagelength=792.0; t2p->pdf_xrefcount=3; /* Catalog, Info, Pages */ + t2p->tiff_maxdatasize = DEFAULT_MAX_MALLOC; return(t2p); } @@ -1012,14 +1032,14 @@ void t2p_validate(T2P* t2p){ #endif #ifdef ZIP_SUPPORT if(t2p->pdf_defaultcompression==T2P_COMPRESS_ZIP){ - uint16 m=t2p->pdf_defaultcompressionquality%100; - if(t2p->pdf_defaultcompressionquality/100 > 9 || - (m>1 && m<10) || m>15){ - t2p->pdf_defaultcompressionquality=0; + uint16 m=t2p->pdf_defaultcompressionquality%100; + if(t2p->pdf_defaultcompressionquality/100 > 9 || + (m>1 && m<10) || m>15){ + t2p->pdf_defaultcompressionquality=0; } if(t2p->pdf_defaultcompressionquality%100 !=0){ - t2p->pdf_defaultcompressionquality/=100; - t2p->pdf_defaultcompressionquality*=100; + t2p->pdf_defaultcompressionquality/=100; + t2p->pdf_defaultcompressionquality*=100; TIFFError( TIFF2PDF_MODULE, "PNG Group predictor differencing not implemented, assuming compression quality %u", @@ -1804,8 +1824,12 @@ void t2p_read_tiff_data(T2P* t2p, TIFF* input){ if(t2p->tiff_compression== COMPRESSION_ADOBE_DEFLATE || t2p->tiff_compression==COMPRESSION_DEFLATE){ if(TIFFIsTiled(input) || (TIFFNumberOfStrips(input)==1) ){ + uint16 predictor; t2p->pdf_transcode = T2P_TRANSCODE_RAW; t2p->pdf_compression=T2P_COMPRESS_ZIP; + TIFFGetField(input, TIFFTAG_PREDICTOR, &predictor); + t2p->pdf_compressionquality = predictor; + /* TIFFTAG_ZIPQUALITY is always Z_DEFAULT_COMPRESSION on reading */ } } #endif @@ -2063,9 +2087,17 @@ void t2p_read_tiff_size(T2P* t2p, TIFF* input){ #endif (void) 0; } - k = checkMultiply64(TIFFScanlineSize(input), t2p->tiff_length, t2p); - if(t2p->tiff_planar==PLANARCONFIG_SEPARATE){ - k = checkMultiply64(k, t2p->tiff_samplesperpixel, t2p); +#ifdef JPEG_SUPPORT + if(t2p->pdf_compression == T2P_COMPRESS_JPEG + && t2p->tiff_photometric == PHOTOMETRIC_YCBCR) { + k = checkMultiply64(TIFFNumberOfStrips(input), TIFFStripSize(input), t2p); + } else +#endif + { + k = checkMultiply64(TIFFScanlineSize(input), t2p->tiff_length, t2p); + if(t2p->tiff_planar==PLANARCONFIG_SEPARATE){ + k = checkMultiply64(k, t2p->tiff_samplesperpixel, t2p); + } } if (k == 0) { /* Assume we had overflow inside TIFFScanlineSize */ @@ -2115,7 +2147,7 @@ void t2p_read_tiff_size_tile(T2P* t2p, TIFF* input, ttile_t tile){ k=tbc[tile]; #ifdef OJPEG_SUPPORT if(t2p->tiff_compression==COMPRESSION_OJPEG){ - k = checkAdd64(k, 2048, t2p); + k = checkAdd64(k, 2048, t2p); } #endif #ifdef JPEG_SUPPORT @@ -2205,6 +2237,9 @@ int t2p_tile_is_corner_edge(T2P_TILES tiles, ttile_t tile){ return(t2p_tile_is_right_edge(tiles, tile) & t2p_tile_is_bottom_edge(tiles, tile) ); } +#if defined(JPEG_SUPPORT) || defined(OJPEG_SUPPORT) +static const unsigned char jpeg_eof_marker[] = { 0xff, 0xd9 }; +#endif /* This function reads the raster image data from the input TIFF for an image and writes @@ -2252,16 +2287,22 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if (buffer == NULL) { - TIFFError(TIFF2PDF_MODULE, - "Can't allocate %lu bytes of memory for " - "t2p_readwrite_pdf_image, %s", - (unsigned long) t2p->tiff_datasize, + TIFFError(TIFF2PDF_MODULE, + "Can't allocate %lu bytes of memory for " + "t2p_readwrite_pdf_image, %s", + (unsigned long) t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } - TIFFReadRawStrip(input, 0, (tdata_t) buffer, - t2p->tiff_datasize); + memset(buffer, 0, t2p->tiff_datasize); + if (TIFFReadRawStrip(input, 0, (tdata_t) buffer, + t2p->tiff_datasize) < 0) { + TIFFError(TIFF2PDF_MODULE, + "TIFFReadRawStrip() failed"); + _TIFFfree(buffer); + return(0); + } if (t2p->tiff_fillorder==FILLORDER_LSB2MSB){ /* * make sure is lsb-to-msb @@ -2281,16 +2322,21 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(buffer == NULL){ - TIFFError(TIFF2PDF_MODULE, - "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", - (unsigned long) t2p->tiff_datasize, + TIFFError(TIFF2PDF_MODULE, + "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", + (unsigned long) t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } - memset(buffer, 0, t2p->tiff_datasize); - TIFFReadRawStrip(input, 0, (tdata_t) buffer, - t2p->tiff_datasize); + memset(buffer, 0, t2p->tiff_datasize); + if (TIFFReadRawStrip(input, 0, (tdata_t) buffer, + t2p->tiff_datasize) < 0) { + TIFFError(TIFF2PDF_MODULE, + "TIFFReadRawStrip() failed"); + _TIFFfree(buffer); + return(0); + } if (t2p->tiff_fillorder==FILLORDER_LSB2MSB) { TIFFReverseBits(buffer, t2p->tiff_datasize); @@ -2308,14 +2354,14 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(buffer == NULL) { - TIFFError(TIFF2PDF_MODULE, - "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", - (unsigned long) t2p->tiff_datasize, + TIFFError(TIFF2PDF_MODULE, + "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", + (unsigned long) t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } - memset(buffer, 0, t2p->tiff_datasize); + memset(buffer, 0, t2p->tiff_datasize); if(t2p->pdf_ojpegiflength==0){ inputoffset=t2pSeekFile(input, 0, SEEK_CUR); @@ -2375,8 +2421,8 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ } } else { if(! t2p->pdf_ojpegdata){ - TIFFError(TIFF2PDF_MODULE, - "No support for OJPEG image %s with bad tables", + TIFFError(TIFF2PDF_MODULE, + "No support for OJPEG image %s with bad tables", TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); @@ -2384,32 +2430,39 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(buffer==NULL){ - TIFFError(TIFF2PDF_MODULE, - "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", - (unsigned long) t2p->tiff_datasize, + TIFFError(TIFF2PDF_MODULE, + "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", + (unsigned long) t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } - memset(buffer, 0, t2p->tiff_datasize); + memset(buffer, 0, t2p->tiff_datasize); _TIFFmemcpy(buffer, t2p->pdf_ojpegdata, t2p->pdf_ojpegdatalength); bufferoffset=t2p->pdf_ojpegdatalength; stripcount=TIFFNumberOfStrips(input); for(i=0;i<stripcount;i++){ + tsize_t retTIFFReadRawStrip; if(i != 0){ buffer[bufferoffset++]=0xff; buffer[bufferoffset++]=(0xd0 | ((i-1)%8)); } - bufferoffset+=TIFFReadRawStrip(input, + retTIFFReadRawStrip = TIFFReadRawStrip(input, i, (tdata_t) &(((unsigned char*)buffer)[bufferoffset]), -1); + if (retTIFFReadRawStrip < 0) { + TIFFError(TIFF2PDF_MODULE, "TIFFReadRawStrip()"); + _TIFFfree(buffer); + t2p->t2p_error = T2P_ERR_ERROR; + return(0); + } + bufferoffset += retTIFFReadRawStrip; } + t2pWriteFile(output, (tdata_t) buffer, bufferoffset); if( ! ( (buffer[bufferoffset-1]==0xd9) && (buffer[bufferoffset-2]==0xff) ) ){ - buffer[bufferoffset++]=0xff; - buffer[bufferoffset++]=0xd9; + t2pWriteFile(output, (tdata_t) jpeg_eof_marker, sizeof(jpeg_eof_marker)); } - t2pWriteFile(output, (tdata_t) buffer, bufferoffset); _TIFFfree(buffer); return(bufferoffset); #if 0 @@ -2433,14 +2486,14 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(buffer==NULL){ - TIFFError(TIFF2PDF_MODULE, - "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", - (unsigned long) t2p->tiff_datasize, + TIFFError(TIFF2PDF_MODULE, + "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", + (unsigned long) t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } - memset(buffer, 0, t2p->tiff_datasize); + memset(buffer, 0, t2p->tiff_datasize); if (TIFFGetField(input, TIFFTAG_JPEGTABLES, &count, &jpt) != 0) { if(count > 4) { _TIFFmemcpy(buffer, jpt, count); @@ -2455,16 +2508,24 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ stripbuffer = (unsigned char*) _TIFFmalloc(max_striplength); if(stripbuffer==NULL){ - TIFFError(TIFF2PDF_MODULE, - "Can't allocate %u bytes of memory for t2p_readwrite_pdf_image, %s", - max_striplength, + TIFFError(TIFF2PDF_MODULE, + "Can't allocate %u bytes of memory for t2p_readwrite_pdf_image, %s", + max_striplength, TIFFFileName(input)); _TIFFfree(buffer); t2p->t2p_error = T2P_ERR_ERROR; return(0); } + memset(stripbuffer, 0, max_striplength); for(i=0;i<stripcount;i++){ striplength=TIFFReadRawStrip(input, i, (tdata_t) stripbuffer, -1); + if (striplength < 0) { + TIFFError(TIFF2PDF_MODULE, "TIFFReadRawStrip() failed"); + _TIFFfree(samplebuffer); + _TIFFfree(buffer); + t2p->t2p_error = T2P_ERR_ERROR; + return(0); + } if(!t2p_process_jpeg_strip( stripbuffer, &striplength, @@ -2482,9 +2543,8 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ return(0); } } - buffer[bufferoffset++]=0xff; - buffer[bufferoffset++]=0xd9; t2pWriteFile(output, (tdata_t) buffer, bufferoffset); + t2pWriteFile(output, (tdata_t) jpeg_eof_marker, sizeof(jpeg_eof_marker)); _TIFFfree(stripbuffer); _TIFFfree(buffer); return(bufferoffset); @@ -2496,14 +2556,14 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ if(t2p->pdf_sample==T2P_SAMPLE_NOTHING){ buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(buffer==NULL){ - TIFFError(TIFF2PDF_MODULE, - "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", - (unsigned long) t2p->tiff_datasize, + TIFFError(TIFF2PDF_MODULE, + "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", + (unsigned long) t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } - memset(buffer, 0, t2p->tiff_datasize); + memset(buffer, 0, t2p->tiff_datasize); stripsize=TIFFStripSize(input); stripcount=TIFFNumberOfStrips(input); for(i=0;i<stripcount;i++){ @@ -2534,19 +2594,19 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(buffer==NULL){ - TIFFError(TIFF2PDF_MODULE, - "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", - (unsigned long) t2p->tiff_datasize, + TIFFError(TIFF2PDF_MODULE, + "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", + (unsigned long) t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } - memset(buffer, 0, t2p->tiff_datasize); + memset(buffer, 0, t2p->tiff_datasize); samplebuffer = (unsigned char*) _TIFFmalloc(stripsize); if(samplebuffer==NULL){ - TIFFError(TIFF2PDF_MODULE, - "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", - (unsigned long) t2p->tiff_datasize, + TIFFError(TIFF2PDF_MODULE, + "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", + (unsigned long) t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; _TIFFfree(buffer); @@ -2561,9 +2621,9 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ (tdata_t) &(samplebuffer[samplebufferoffset]), TIFFmin(sepstripsize, stripsize - samplebufferoffset)); if(read==-1){ - TIFFError(TIFF2PDF_MODULE, - "Error on decoding strip %u of %s", - i + j*stripcount, + TIFFError(TIFF2PDF_MODULE, + "Error on decoding strip %u of %s", + i + j*stripcount, TIFFFileName(input)); _TIFFfree(buffer); t2p->t2p_error=T2P_ERR_ERROR; @@ -2584,14 +2644,14 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(buffer==NULL){ - TIFFError(TIFF2PDF_MODULE, - "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", - (unsigned long) t2p->tiff_datasize, + TIFFError(TIFF2PDF_MODULE, + "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", + (unsigned long) t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } - memset(buffer, 0, t2p->tiff_datasize); + memset(buffer, 0, t2p->tiff_datasize); stripsize=TIFFStripSize(input); stripcount=TIFFNumberOfStrips(input); for(i=0;i<stripcount;i++){ @@ -2855,7 +2915,14 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ t2p->t2p_error = T2P_ERR_ERROR; return(0); } - TIFFReadRawTile(input, tile, (tdata_t) buffer, t2p->tiff_datasize); + memset(buffer, 0, t2p->tiff_datasize); + if (TIFFReadRawTile(input, tile, (tdata_t) buffer, t2p->tiff_datasize) < 0) { + TIFFError(TIFF2PDF_MODULE, + "TIFFReadRawTile() failed"); + _TIFFfree(buffer); + t2p->t2p_error = T2P_ERR_ERROR; + return(0); + } if (t2p->tiff_fillorder==FILLORDER_LSB2MSB){ TIFFReverseBits(buffer, t2p->tiff_datasize); } @@ -2876,7 +2943,14 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ t2p->t2p_error = T2P_ERR_ERROR; return(0); } - TIFFReadRawTile(input, tile, (tdata_t) buffer, t2p->tiff_datasize); + memset(buffer, 0, t2p->tiff_datasize); + if (TIFFReadRawTile(input, tile, (tdata_t) buffer, t2p->tiff_datasize) < 0) { + TIFFError(TIFF2PDF_MODULE, + "TIFFReadRawTile() failed"); + _TIFFfree(buffer); + t2p->t2p_error = T2P_ERR_ERROR; + return(0); + } if (t2p->tiff_fillorder==FILLORDER_LSB2MSB){ TIFFReverseBits(buffer, t2p->tiff_datasize); } @@ -2887,6 +2961,7 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ #endif #ifdef OJPEG_SUPPORT if(t2p->tiff_compression == COMPRESSION_OJPEG){ + tsize_t retTIFFReadRawTile; if(! t2p->pdf_ojpegdata){ TIFFError(TIFF2PDF_MODULE, "No support for OJPEG image %s with " @@ -2905,6 +2980,7 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ t2p->t2p_error = T2P_ERR_ERROR; return(0); } + memset(buffer, 0, t2p->tiff_datasize); _TIFFmemcpy(buffer, t2p->pdf_ojpegdata, t2p->pdf_ojpegdatalength); if(edge!=0){ if(t2p_tile_is_bottom_edge(t2p->tiff_tiles[t2p->pdf_page], tile)){ @@ -2920,14 +2996,20 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ (t2p->tiff_tiles[t2p->pdf_page].tiles_edgetilewidth ) & 0xff; } } - bufferoffset=t2p->pdf_ojpegdatalength; - bufferoffset+=TIFFReadRawTile(input, + bufferoffset = t2p->pdf_ojpegdatalength; + retTIFFReadRawTile = TIFFReadRawTile(input, tile, (tdata_t) &(((unsigned char*)buffer)[bufferoffset]), -1); - ((unsigned char*)buffer)[bufferoffset++]=0xff; - ((unsigned char*)buffer)[bufferoffset++]=0xd9; + if (retTIFFReadRawTile < 0) { + TIFFError(TIFF2PDF_MODULE, "TIFFReadRawTile() failed"); + _TIFFfree(buffer); + t2p->t2p_error = T2P_ERR_ERROR; + return(0); + } + bufferoffset += retTIFFReadRawTile; t2pWriteFile(output, (tdata_t) buffer, bufferoffset); + t2pWriteFile(output, (tdata_t) jpeg_eof_marker, sizeof(jpeg_eof_marker)); _TIFFfree(buffer); return(bufferoffset); } @@ -2946,9 +3028,10 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ t2p->t2p_error = T2P_ERR_ERROR; return(0); } + memset(buffer, 0, t2p->tiff_datasize); if(TIFFGetField(input, TIFFTAG_JPEGTABLES, &count, &jpt) != 0) { if (count > 4) { - int retTIFFReadRawTile; + tsize_t retTIFFReadRawTile; /* Ignore EOI marker of JpegTables */ _TIFFmemcpy(buffer, jpt, count - 2); bufferoffset += count - 2; @@ -2957,7 +3040,7 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ table_end[1] = buffer[bufferoffset-1]; xuint32 = bufferoffset; bufferoffset -= 2; - retTIFFReadRawTile= TIFFReadRawTile( + retTIFFReadRawTile = TIFFReadRawTile( input, tile, (tdata_t) &(((unsigned char*)buffer)[bufferoffset]), @@ -2994,6 +3077,7 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ t2p->t2p_error = T2P_ERR_ERROR; return(0); } + memset(buffer, 0, t2p->tiff_datasize); read = TIFFReadEncodedTile( input, @@ -3019,25 +3103,27 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ tilecount=septilecount/t2p->tiff_samplesperpixel; buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(buffer==NULL){ - TIFFError(TIFF2PDF_MODULE, + TIFFError(TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory " - "for t2p_readwrite_pdf_image_tile, %s", - (unsigned long) t2p->tiff_datasize, + "for t2p_readwrite_pdf_image_tile, %s", + (unsigned long) t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } + memset(buffer, 0, t2p->tiff_datasize); samplebuffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(samplebuffer==NULL){ - TIFFError(TIFF2PDF_MODULE, + TIFFError(TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory " - "for t2p_readwrite_pdf_image_tile, %s", - (unsigned long) t2p->tiff_datasize, + "for t2p_readwrite_pdf_image_tile, %s", + (unsigned long) t2p->tiff_datasize, TIFFFileName(input)); _TIFFfree(buffer); t2p->t2p_error = T2P_ERR_ERROR; return(0); } + memset(samplebuffer, 0, t2p->tiff_datasize); samplebufferoffset=0; for(i=0;i<t2p->tiff_samplesperpixel;i++){ read = @@ -3069,23 +3155,24 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ if(buffer==NULL){ buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(buffer==NULL){ - TIFFError(TIFF2PDF_MODULE, + TIFFError(TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory " - "for t2p_readwrite_pdf_image_tile, %s", - (unsigned long) t2p->tiff_datasize, + "for t2p_readwrite_pdf_image_tile, %s", + (unsigned long) t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } + memset(buffer, 0, t2p->tiff_datasize); read = TIFFReadEncodedTile( input, tile, (tdata_t) &buffer[bufferoffset], t2p->tiff_datasize); if(read==-1){ - TIFFError(TIFF2PDF_MODULE, - "Error on decoding tile %u of %s", - tile, + TIFFError(TIFF2PDF_MODULE, + "Error on decoding tile %u of %s", + tile, TIFFFileName(input)); _TIFFfree(buffer); t2p->t2p_error=T2P_ERR_ERROR; @@ -3108,8 +3195,8 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ } if(t2p->pdf_sample & T2P_SAMPLE_YCBCR_TO_RGB){ - TIFFError(TIFF2PDF_MODULE, - "No support for YCbCr to RGB in tile for %s", + TIFFError(TIFF2PDF_MODULE, + "No support for YCbCr to RGB in tile for %s", TIFFFileName(input)); _TIFFfree(buffer); t2p->t2p_error = T2P_ERR_ERROR; @@ -3242,18 +3329,26 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ break; } + if (TIFFStripSize(output) > t2p->tiff_datasize) { + TIFFError(TIFF2PDF_MODULE, + "Size mismatch input %ld, output %ld", + t2p->tiff_datasize, TIFFStripSize(output)); + _TIFFfree(buffer); + t2p->t2p_error = T2P_ERR_ERROR; + return(0); + } t2p_enable(output); t2p->outputwritten = 0; bufferoffset = TIFFWriteEncodedStrip(output, (tstrip_t) 0, buffer, - TIFFStripSize(output)); + TIFFStripSize(output)); if (buffer != NULL) { _TIFFfree(buffer); buffer = NULL; } if (bufferoffset == -1) { - TIFFError(TIFF2PDF_MODULE, - "Error writing encoded tile to output PDF %s", - TIFFFileName(output)); + TIFFError(TIFF2PDF_MODULE, + "Error writing encoded tile to output PDF %s", + TIFFFileName(output)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } @@ -3731,6 +3826,11 @@ tsize_t t2p_sample_realize_palette(T2P* t2p, unsigned char* buffer){ for(i=sample_count;i>0;i--){ palette_offset=buffer[i-1] * component_count; sample_offset= (i-1) * component_count; + if(palette_offset + component_count > t2p->pdf_palettesize){ + TIFFError(TIFF2PDF_MODULE, + "Error: palette_offset + component_count > t2p->pdf_palettesize"); + return 1; + } for(j=0;j<component_count;j++){ buffer[sample_offset+j]=t2p->pdf_palette[palette_offset+j]; } @@ -3886,7 +3986,7 @@ tsize_t t2p_write_pdf_obj_end(TIFF* output){ This function writes a PDF name object to output. */ -tsize_t t2p_write_pdf_name(unsigned char* name, TIFF* output){ +tsize_t t2p_write_pdf_name(const unsigned char* name, TIFF* output){ tsize_t written=0; uint32 i=0; @@ -3984,7 +4084,7 @@ tsize_t t2p_write_pdf_name(unsigned char* name, TIFF* output){ * This function writes a PDF string object to output. */ -tsize_t t2p_write_pdf_string(char* pdfstr, TIFF* output) +tsize_t t2p_write_pdf_string(const char* pdfstr, TIFF* output) { tsize_t written = 0; uint32 i = 0; @@ -4175,7 +4275,7 @@ tsize_t t2p_write_pdf_catalog(T2P* t2p, TIFF* output) tsize_t t2p_write_pdf_info(T2P* t2p, TIFF* input, TIFF* output) { tsize_t written = 0; - char* info; + const char* info; char buffer[512]; if(t2p->pdf_datetime[0] == '\0') @@ -4190,60 +4290,51 @@ tsize_t t2p_write_pdf_info(T2P* t2p, TIFF* input, TIFF* output) snprintf(buffer, sizeof(buffer), "libtiff / tiff2pdf - %d", TIFFLIB_VERSION); written += t2p_write_pdf_string(buffer, output); written += t2pWriteFile(output, (tdata_t) "\n", 1); + if (!t2p->pdf_creator_set) { + if (TIFFGetField(input, TIFFTAG_SOFTWARE, &info) != 0 && info) { + strncpy(t2p->pdf_creator, info, sizeof(t2p->pdf_creator) - 1); + t2p->pdf_creator[sizeof(t2p->pdf_creator) - 1] = '\0'; + } + } if (t2p->pdf_creator[0] != '\0') { written += t2pWriteFile(output, (tdata_t) "/Creator ", 9); written += t2p_write_pdf_string(t2p->pdf_creator, output); written += t2pWriteFile(output, (tdata_t) "\n", 1); - } else { - if (TIFFGetField(input, TIFFTAG_SOFTWARE, &info) != 0 && info) { - if(strlen(info) >= sizeof(t2p->pdf_creator)) - info[sizeof(t2p->pdf_creator) - 1] = '\0'; - written += t2pWriteFile(output, (tdata_t) "/Creator ", 9); - written += t2p_write_pdf_string(info, output); - written += t2pWriteFile(output, (tdata_t) "\n", 1); + } + if (!t2p->pdf_author_set) { + if ((TIFFGetField(input, TIFFTAG_ARTIST, &info) != 0 + || TIFFGetField(input, TIFFTAG_COPYRIGHT, &info) != 0) + && info) { + strncpy(t2p->pdf_author, info, sizeof(t2p->pdf_author) - 1); + t2p->pdf_author[sizeof(t2p->pdf_author) - 1] = '\0'; } } if (t2p->pdf_author[0] != '\0') { written += t2pWriteFile(output, (tdata_t) "/Author ", 8); written += t2p_write_pdf_string(t2p->pdf_author, output); written += t2pWriteFile(output, (tdata_t) "\n", 1); - } else { - if ((TIFFGetField(input, TIFFTAG_ARTIST, &info) != 0 - || TIFFGetField(input, TIFFTAG_COPYRIGHT, &info) != 0) - && info) { - if (strlen(info) >= sizeof(t2p->pdf_author)) - info[sizeof(t2p->pdf_author) - 1] = '\0'; - written += t2pWriteFile(output, (tdata_t) "/Author ", 8); - written += t2p_write_pdf_string(info, output); - written += t2pWriteFile(output, (tdata_t) "\n", 1); + } + if (!t2p->pdf_title_set) { + if (TIFFGetField(input, TIFFTAG_DOCUMENTNAME, &info) != 0 && info) { + strncpy(t2p->pdf_title, info, sizeof(t2p->pdf_title) - 1); + t2p->pdf_title[sizeof(t2p->pdf_title) - 1] = '\0'; } } if (t2p->pdf_title[0] != '\0') { written += t2pWriteFile(output, (tdata_t) "/Title ", 7); written += t2p_write_pdf_string(t2p->pdf_title, output); written += t2pWriteFile(output, (tdata_t) "\n", 1); - } else { - if (TIFFGetField(input, TIFFTAG_DOCUMENTNAME, &info) != 0){ - if(strlen(info) > 511) { - info[512] = '\0'; - } - written += t2pWriteFile(output, (tdata_t) "/Title ", 7); - written += t2p_write_pdf_string(info, output); - written += t2pWriteFile(output, (tdata_t) "\n", 1); + } + if (!t2p->pdf_subject_set) { + if (TIFFGetField(input, TIFFTAG_IMAGEDESCRIPTION, &info) != 0 && info) { + strncpy(t2p->pdf_subject, info, sizeof(t2p->pdf_subject) - 1); + t2p->pdf_subject[sizeof(t2p->pdf_subject) - 1] = '\0'; } } if (t2p->pdf_subject[0] != '\0') { written += t2pWriteFile(output, (tdata_t) "/Subject ", 9); written += t2p_write_pdf_string(t2p->pdf_subject, output); written += t2pWriteFile(output, (tdata_t) "\n", 1); - } else { - if (TIFFGetField(input, TIFFTAG_IMAGEDESCRIPTION, &info) != 0 && info) { - if (strlen(info) >= sizeof(t2p->pdf_subject)) - info[sizeof(t2p->pdf_subject) - 1] = '\0'; - written += t2pWriteFile(output, (tdata_t) "/Subject ", 9); - written += t2p_write_pdf_string(info, output); - written += t2pWriteFile(output, (tdata_t) "\n", 1); - } } if (t2p->pdf_keywords[0] != '\0') { written += t2pWriteFile(output, (tdata_t) "/Keywords ", 10); @@ -4928,8 +5019,18 @@ tsize_t t2p_write_pdf_xobject_stream_dict(ttile_t tile, return(written); } + +/* used to normalize the White Point */ +#define normalizePoint(x,y,z) do { \ + if (y != 0.0F) { \ + x /= y; \ + z /= y; \ + y = 1.0F; \ + } \ +} while(0) + /* - * This function writes a PDF Image XObject Colorspace name to output. + * This function writes a PDF Image XObject Colorspace name to output. */ @@ -4988,9 +5089,7 @@ tsize_t t2p_write_pdf_xobject_cs(T2P* t2p, TIFF* output){ X_W = t2p->tiff_whitechromaticities[0]; Y_W = t2p->tiff_whitechromaticities[1]; Z_W = 1.0F - (X_W + Y_W); - X_W /= Y_W; - Z_W /= Y_W; - Y_W = 1.0F; + normalizePoint(X_W, Y_W, Z_W); buflen=snprintf(buffer, sizeof(buffer), "[%.4f %.4f %.4f] \n", X_W, Y_W, Z_W); check_snprintf_ret(t2p, buflen, buffer); written += t2pWriteFile(output, (tdata_t) buffer, buflen); @@ -5119,9 +5218,7 @@ tsize_t t2p_write_pdf_xobject_calcs(T2P* t2p, TIFF* output){ X_W = t2p->tiff_whitechromaticities[0]; Y_W = t2p->tiff_whitechromaticities[1]; Z_W = 1.0F - (X_W + Y_W); - X_W /= Y_W; - Z_W /= Y_W; - Y_W = 1.0F; + normalizePoint(X_W, Y_W, Z_W); } if(t2p->pdf_colorspace & T2P_CS_CALRGB){ written += t2pWriteFile(output, (tdata_t) "/CalRGB ", 8); @@ -5146,9 +5243,7 @@ tsize_t t2p_write_pdf_xobject_calcs(T2P* t2p, TIFF* output){ X_W = (X_R * R) + (X_G * G) + (X_B * B); Y_W = (Y_R * R) + (Y_G * G) + (Y_B * B); Z_W = (Z_R * R) + (Z_G * G) + (Z_B * B); - X_W /= Y_W; - Z_W /= Y_W; - Y_W = 1.0; + normalizePoint(X_W, Y_W, Z_W); } written += t2pWriteFile(output, (tdata_t) "<< \n", 4); if(t2p->pdf_colorspace & T2P_CS_CALGRAY){ @@ -5597,6 +5692,13 @@ tsize_t t2p_write_pdf(T2P* t2p, TIFF* input, TIFF* output){ written += t2p_write_pdf_stream_start(output); streamlen=written; t2p_read_tiff_size_tile(t2p, input, i2); + if (t2p->tiff_maxdatasize && (t2p->tiff_datasize > t2p->tiff_maxdatasize)) { + TIFFError(TIFF2PDF_MODULE, + "Allocation of " TIFF_UINT64_FORMAT " bytes is forbidden. Limit is " TIFF_UINT64_FORMAT ". Use -m option to change limit", + (uint64)t2p->tiff_datasize, (uint64)t2p->tiff_maxdatasize); + t2p->t2p_error = T2P_ERR_ERROR; + return (0); + } written += t2p_readwrite_pdf_image_tile(t2p, input, output, i2); t2p_write_advance_directory(t2p, output); if(t2p->t2p_error!=T2P_ERR_OK){return(0);} @@ -5620,6 +5722,13 @@ tsize_t t2p_write_pdf(T2P* t2p, TIFF* input, TIFF* output){ written += t2p_write_pdf_stream_start(output); streamlen=written; t2p_read_tiff_size(t2p, input); + if (t2p->tiff_maxdatasize && (t2p->tiff_datasize > t2p->tiff_maxdatasize)) { + TIFFError(TIFF2PDF_MODULE, + "Allocation of " TIFF_UINT64_FORMAT " bytes is forbidden. Limit is " TIFF_UINT64_FORMAT ". Use -m option to change limit", + (uint64)t2p->tiff_datasize, (uint64)t2p->tiff_maxdatasize); + t2p->t2p_error = T2P_ERR_ERROR; + return (0); + } written += t2p_readwrite_pdf_image(t2p, input, output); t2p_write_advance_directory(t2p, output); if(t2p->t2p_error!=T2P_ERR_OK){return(0);} 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); } 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); } diff --git a/tiff/tools/tiffcmp.c b/tiff/tools/tiffcmp.c index 7b764883..041d6a2d 100644 --- a/tiff/tools/tiffcmp.c +++ b/tiff/tools/tiffcmp.c @@ -39,6 +39,13 @@ #include "tiffio.h" +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif + #ifndef HAVE_GETOPT extern int getopt(int argc, char * const argv[], const char *optstring); #endif @@ -51,7 +58,7 @@ static uint16 sampleformat = SAMPLEFORMAT_UINT; static uint32 imagewidth; static uint32 imagelength; -static void usage(void); +static void usage(int code); static int tiffcmp(TIFF*, TIFF*); static int cmptags(TIFF*, TIFF*); static int ContigCompare(int, uint32, unsigned char*, unsigned char*, tsize_t); @@ -61,6 +68,12 @@ static void PrintFloatDiff(uint32, int, uint32, double, double); static void leof(const char*, uint32, int); +/* + * exit with status : + * 0 No differences were found. + * 1 Differences were found. + * >1 An error occurred. + */ int main(int argc, char* argv[]) { @@ -71,7 +84,7 @@ main(int argc, char* argv[]) extern char* optarg; #endif - while ((c = getopt(argc, argv, "ltz:")) != -1) + while ((c = getopt(argc, argv, "ltz:h")) != -1) switch (c) { case 'l': stopondiff = 0; @@ -82,18 +95,20 @@ main(int argc, char* argv[]) case 't': stoponfirsttag = 0; break; + case 'h': + usage(EXIT_SUCCESS); case '?': - usage(); + usage(2); /*NOTREACHED*/ } if (argc - optind < 2) - usage(); + usage(2); tif1 = TIFFOpen(argv[optind], "r"); if (tif1 == NULL) - return (-1); + return (2); tif2 = TIFFOpen(argv[optind+1], "r"); if (tif2 == NULL) - return (-2); + return (2); dirnum = 0; while (tiffcmp(tif1, tif2)) { if (!TIFFReadDirectory(tif1)) { @@ -115,7 +130,7 @@ main(int argc, char* argv[]) return (0); } -char* stuff[] = { +static const char* stuff[] = { "usage: tiffcmp [options] file1 file2", "where options are:", " -l list each byte of image data that differs between the files", @@ -125,16 +140,15 @@ NULL }; static void -usage(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]); - exit(-1); + fprintf(out, "%s\n", stuff[i]); + exit(code); } #define checkEOF(tif, row, sample) { \ @@ -177,7 +191,7 @@ tiffcmp(TIFF* tif1, TIFF* tif2) buf2 = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(tif2)); if (buf1 == NULL || buf2 == NULL) { fprintf(stderr, "No space for scanline buffers\n"); - exit(-1); + exit(2); } if (config1 != config2 && bitspersample != 8 && samplesperpixel > 1) { fprintf(stderr, diff --git a/tiff/tools/tiffcp.c b/tiff/tools/tiffcp.c index 84d81488..e56b1c10 100644 --- a/tiff/tools/tiffcp.c +++ b/tiff/tools/tiffcp.c @@ -51,6 +51,13 @@ #include "tiffio.h" +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif + #ifndef HAVE_GETOPT extern int getopt(int argc, char * const argv[], const char *optstring); #endif @@ -65,6 +72,12 @@ extern int getopt(int argc, char * const argv[], const char *optstring); #define TRUE 1 #define FALSE 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 outtiled = -1; static uint32 tilewidth; static uint32 tilelength; @@ -84,16 +97,31 @@ static int jpegcolormode = JPEGCOLORMODE_RGB; static uint16 defcompression = (uint16) -1; static uint16 defpredictor = (uint16) -1; static int defpreset = -1; +static int subcodec = -1; static int tiffcp(TIFF*, TIFF*); static int processCompressOptions(char*); -static void usage(void); +static void usage(int code); static char comma = ','; /* (default) comma separator character */ static TIFF* bias = NULL; static int pageNum = 0; static int pageInSeq = 0; +/** + * 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); +} + static int nextSrcImage (TIFF *tif, char **imageSpec) /* seek to the next image specified in *imageSpec @@ -114,7 +142,7 @@ static int nextSrcImage (TIFF *tif, char **imageSpec) fprintf (stderr, "Expected a %c separated image # list after %s\n", comma, TIFFFileName (tif)); - exit (-4); /* syntax error */ + exit (EXIT_FAILURE); /* syntax error */ } } if (TIFFSetDirectory (tif, nextImage)) return 1; @@ -132,12 +160,14 @@ static TIFF* openSrcImage (char **imageSpec) no images specified, or a pointer to the next image number text */ { + /* disable strip shopping when using jbig compression */ + const char *mode = (defcompression == COMPRESSION_JBIG) ? "rc" : "r"; TIFF *tif; char *fn = *imageSpec; *imageSpec = strchr (fn, comma); if (*imageSpec) { /* there is at least one image number specifier */ **imageSpec = '\0'; - tif = TIFFOpen (fn, "r"); + tif = TIFFOpen (fn, mode); /* but, ignore any single trailing comma */ if (!(*imageSpec)[1]) {*imageSpec = NULL; return tif;} if (tif) { @@ -148,7 +178,7 @@ static TIFF* openSrcImage (char **imageSpec) } } }else - tif = TIFFOpen (fn, "r"); + tif = TIFFOpen (fn, mode); return tif; } @@ -173,30 +203,33 @@ main(int argc, char* argv[]) *mp++ = 'w'; *mp = '\0'; - while ((c = getopt(argc, argv, ",:b:c:f:l:o:p:r:w:aistBLMC8x")) != -1) + while ((c = getopt(argc, argv, "m:,:b:c:f:l:o:p:r:w:aistBLMC8xh")) != -1) switch (c) { + case 'm': + maxMalloc = (tmsize_t)strtoul(optarg, NULL, 0) << 20; + break; case ',': - if (optarg[0] != '=') usage(); + if (optarg[0] != '=') usage(EXIT_FAILURE); comma = optarg[1]; break; case 'b': /* this file is bias image subtracted from others */ if (bias) { fputs ("Only 1 bias image may be specified\n", stderr); - exit (-2); + exit (EXIT_FAILURE); } { uint16 samples = (uint16) -1; char **biasFn = &optarg; bias = openSrcImage (biasFn); - if (!bias) exit (-5); + if (!bias) exit (EXIT_FAILURE); if (TIFFIsTiled (bias)) { fputs ("Bias image must be organized in strips\n", stderr); - exit (-7); + exit (EXIT_FAILURE); } TIFFGetField(bias, TIFFTAG_SAMPLESPERPIXEL, &samples); if (samples != 1) { fputs ("Bias image must be monochrome\n", stderr); - exit (-7); + exit (EXIT_FAILURE); } } break; @@ -205,7 +238,7 @@ main(int argc, char* argv[]) break; case 'c': /* compression scheme */ if (!processCompressOptions(optarg)) - usage(); + usage(EXIT_FAILURE); break; case 'f': /* fill order */ if (streq(optarg, "lsb2msb")) @@ -213,7 +246,7 @@ main(int argc, char* argv[]) else if (streq(optarg, "msb2lsb")) deffillorder = FILLORDER_MSB2LSB; else - usage(); + usage(EXIT_FAILURE); break; case 'i': /* ignore errors */ ignore = TRUE; @@ -231,7 +264,7 @@ main(int argc, char* argv[]) else if (streq(optarg, "contig")) defconfig = PLANARCONFIG_CONTIG; else - usage(); + usage(EXIT_FAILURE); break; case 'r': /* rows/strip */ defrowsperstrip = atol(optarg); @@ -264,15 +297,18 @@ main(int argc, char* argv[]) case 'x': pageInSeq = 1; break; + case 'h': + usage(EXIT_SUCCESS); + /*NOTREACHED*/ case '?': - usage(); + usage(EXIT_FAILURE); /*NOTREACHED*/ } if (argc - optind < 2) - usage(); + usage(EXIT_FAILURE); out = TIFFOpen(argv[argc-1], mode); if (out == NULL) - return (-2); + return (EXIT_FAILURE); if ((argc - optind) == 2) pageNum = -1; for (; optind < argc-1 ; optind++) { @@ -280,14 +316,14 @@ main(int argc, char* argv[]) in = openSrcImage (&imageCursor); if (in == NULL) { (void) TIFFClose(out); - return (-3); + return (EXIT_FAILURE); } if (diroff != 0 && !TIFFSetSubDirectory(in, diroff)) { TIFFError(TIFFFileName(in), "Error, setting subdirectory at " TIFF_UINT64_FORMAT, diroff); (void) TIFFClose(in); (void) TIFFClose(out); - return (1); + return (EXIT_FAILURE); } for (;;) { config = defconfig; @@ -302,7 +338,7 @@ main(int argc, char* argv[]) if (!tiffcp(in, out) || !TIFFWriteDirectory(out)) { (void) TIFFClose(in); (void) TIFFClose(out); - return (1); + return (EXIT_FAILURE); } if (imageCursor) { /* seek next image directory */ if (!nextSrcImage(in, &imageCursor)) break; @@ -313,7 +349,7 @@ main(int argc, char* argv[]) } (void) TIFFClose(out); - return (0); + return (EXIT_SUCCESS); } static void @@ -326,8 +362,10 @@ processZIPOptions(char* cp) defpredictor = atoi(cp); else if (*cp == 'p') defpreset = atoi(++cp); + else if (*cp == 's') + subcodec = atoi(++cp); else - usage(); + usage(EXIT_FAILURE); } while( (cp = strchr(cp, ':')) ); } } @@ -347,7 +385,7 @@ processG3Options(char* cp) else if (strneq(cp, "fill", 4)) defg3opts |= GROUP3OPT_FILLBITS; else - usage(); + usage(EXIT_FAILURE); } while( (cp = strchr(cp, ':')) ); } } @@ -370,7 +408,7 @@ processCompressOptions(char* opt) else if (cp[1] == 'r' ) jpegcolormode = JPEGCOLORMODE_RAW; else - usage(); + usage(EXIT_FAILURE); cp = strchr(cp+1,':'); } @@ -405,7 +443,7 @@ processCompressOptions(char* opt) return (1); } -char* stuff[] = { +static const char* stuff[] = { "usage: tiffcp [options] input... output", "where options are:", " -a append to output instead of overwriting", @@ -423,6 +461,7 @@ char* stuff[] = { " -i ignore read errors", " -b file[,#] bias (dark) monochrome image to be subtracted from all others", " -,=% use % rather than , to separate image #'s (per Note below)", +" -m size set maximum memory allocation size (MiB). 0 to disable limit.", "", " -r # make each strip have no more than # rows", " -w # set output tile width (pixels)", @@ -458,6 +497,9 @@ char* stuff[] = { "LZW, Deflate (ZIP), LZMA2, ZSTD and WEBP options:", " # set predictor value", " p# set compression level (preset)", +#if LIBDEFLATE_SUPPORT +" s# set subcodec (0=zlib, 1=libdeflate) (only for Deflate/ZIP)", +#endif "For example, -c lzw:2 to get LZW-encoded data with horizontal differencing,", "-c zip:3:p9 for Deflate encoding with maximum compression level and floating", "point predictor.", @@ -470,16 +512,15 @@ NULL }; static void -usage(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]); - exit(-1); + fprintf(out, "%s\n", stuff[i]); + exit(code); } #define CopyField(tag, v) \ @@ -741,11 +782,23 @@ tiffcp(TIFF* in, TIFF* out) case COMPRESSION_DEFLATE: case COMPRESSION_LZMA: case COMPRESSION_ZSTD: - case COMPRESSION_WEBP: if (predictor != (uint16)-1) TIFFSetField(out, TIFFTAG_PREDICTOR, predictor); else CopyField(TIFFTAG_PREDICTOR, predictor); + if( compression == COMPRESSION_ADOBE_DEFLATE || + compression == COMPRESSION_DEFLATE ) + { + if( subcodec != -1 ) + { + if( TIFFSetField(out, TIFFTAG_DEFLATE_SUBCODEC, subcodec) != 1 ) + { + return FALSE; + } + } + } + /*fallthrough*/ + case COMPRESSION_WEBP: if (preset != -1) { if (compression == COMPRESSION_ADOBE_DEFLATE || compression == COMPRESSION_DEFLATE) @@ -858,7 +911,7 @@ DECLAREcpFunc(cpContig2ContigByRow) tdata_t buf; uint32 row; - buf = _TIFFmalloc(scanlinesize); + buf = limitMalloc(scanlinesize); if (!buf) return 0; _TIFFmemset(buf, 0, scanlinesize); @@ -932,8 +985,8 @@ DECLAREcpFunc(cpBiasedContig2Contig) subtractLine = lineSubtractFn (sampleBits); if (subtractLine) { uint32 row; - buf = _TIFFmalloc(bufSize); - biasBuf = _TIFFmalloc(bufSize); + buf = limitMalloc(bufSize); + biasBuf = limitMalloc(bufSize); for (row = 0; row < imagelength; row++) { if (TIFFReadScanline(in, buf, row, 0) < 0 && !ignore) { @@ -995,7 +1048,7 @@ bad: DECLAREcpFunc(cpDecodedStrips) { tsize_t stripsize = TIFFStripSize(in); - tdata_t buf = _TIFFmalloc(stripsize); + tdata_t buf = limitMalloc(stripsize); (void) imagewidth; (void) spp; if (buf) { @@ -1045,7 +1098,7 @@ DECLAREcpFunc(cpSeparate2SeparateByRow) tsample_t s; (void) imagewidth; - buf = _TIFFmalloc(scanlinesize); + buf = limitMalloc(scanlinesize); if (!buf) return 0; _TIFFmemset(buf, 0, scanlinesize); @@ -1096,8 +1149,8 @@ DECLAREcpFunc(cpContig2SeparateByRow) return 0; } - inbuf = _TIFFmalloc(scanlinesizein); - outbuf = _TIFFmalloc(scanlinesizeout); + inbuf = limitMalloc(scanlinesizein); + outbuf = limitMalloc(scanlinesizeout); if (!inbuf || !outbuf) goto bad; _TIFFmemset(inbuf, 0, scanlinesizein); @@ -1159,8 +1212,8 @@ DECLAREcpFunc(cpSeparate2ContigByRow) return 0; } - inbuf = _TIFFmalloc(scanlinesizein); - outbuf = _TIFFmalloc(scanlinesizeout); + inbuf = limitMalloc(scanlinesizein); + outbuf = limitMalloc(scanlinesizeout); if (!inbuf || !outbuf) goto bad; _TIFFmemset(inbuf, 0, scanlinesizein); @@ -1266,7 +1319,7 @@ cpImage(TIFF* in, TIFF* out, readFunc fin, writeFunc fout, if (scanlinesize && imagelength && bytes / (tsize_t)imagelength == scanlinesize) { - buf = _TIFFmalloc(bytes); + buf = limitMalloc(bytes); if (buf) { if ((*fin)(in, (uint8*)buf, imagelength, imagewidth, spp)) { @@ -1314,7 +1367,7 @@ DECLAREreadFunc(readSeparateStripsIntoBuffer) if (!scanlinesize) return 0; - scanline = _TIFFmalloc(scanlinesize); + scanline = limitMalloc(scanlinesize); if (!scanline) return 0; _TIFFmemset(scanline, 0, scanlinesize); @@ -1363,7 +1416,7 @@ DECLAREreadFunc(readContigTilesIntoBuffer) uint32 row; (void) spp; - tilebuf = _TIFFmalloc(tilesize); + tilebuf = limitMalloc(tilesize); if (tilebuf == 0) return 0; _TIFFmemset(tilebuf, 0, tilesize); @@ -1417,13 +1470,13 @@ DECLAREreadFunc(readSeparateTilesIntoBuffer) uint32 row; uint16 bps = 0, bytes_per_sample; - if (spp > (INT_MAX / tilew)) + if (tilew && spp > (INT_MAX / tilew)) { TIFFError(TIFFFileName(in), "Error, cannot handle that much samples per tile row (Tile Width * Samples/Pixel)"); return 0; } iskew = imagew - tilew*spp; - tilebuf = _TIFFmalloc(tilesize); + tilebuf = limitMalloc(tilesize); if (tilebuf == 0) return 0; _TIFFmemset(tilebuf, 0, tilesize); @@ -1524,7 +1577,7 @@ DECLAREwriteFunc(writeBufferToSeparateStrips) tstrip_t strip = 0; tsample_t s; - obuf = _TIFFmalloc(stripsize); + obuf = limitMalloc(stripsize); if (obuf == NULL) return (0); _TIFFmemset(obuf, 0, stripsize); @@ -1566,7 +1619,7 @@ DECLAREwriteFunc(writeBufferToContigTiles) (void) spp; - obuf = _TIFFmalloc(TIFFTileSize(out)); + obuf = limitMalloc(TIFFTileSize(out)); if (obuf == NULL) return 0; _TIFFmemset(obuf, 0, tilesize); @@ -1619,7 +1672,7 @@ DECLAREwriteFunc(writeBufferToSeparateTiles) uint32 row; uint16 bps = 0, bytes_per_sample; - obuf = _TIFFmalloc(TIFFTileSize(out)); + obuf = limitMalloc(TIFFTileSize(out)); if (obuf == NULL) return 0; _TIFFmemset(obuf, 0, tilesize); diff --git a/tiff/tools/tiffcrop.c b/tiff/tools/tiffcrop.c index 7b3c9e78..d20b585a 100644 --- a/tiff/tools/tiffcrop.c +++ b/tiff/tools/tiffcrop.c @@ -128,6 +128,13 @@ static char tiffcrop_rev_date[] = "12-13-2010"; # include <stdint.h> #endif +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif + #ifndef HAVE_GETOPT extern int getopt(int argc, char * const argv[], const char *optstring); #endif @@ -333,7 +340,7 @@ struct paperdef { /* European page sizes corrected from update sent by * thomas . jarosch @ intra2net . com on 5/7/2010 * Paper Size Width Length Aspect Ratio */ -struct paperdef PaperTable[MAX_PAPERNAMES] = { +const struct paperdef PaperTable[MAX_PAPERNAMES] = { {"default", 8.500, 14.000, 0.607}, {"pa4", 8.264, 11.000, 0.751}, {"letter", 8.500, 11.000, 0.773}, @@ -461,7 +468,7 @@ static int writeBufferToSeparateTiles (TIFF*, uint8*, uint32, uint32, tsample static int extractContigSamplesToBuffer (uint8 *, uint8 *, uint32, uint32, tsample_t, uint16, uint16, struct dump_opts *); static int processCompressOptions(char*); -static void usage(void); +static void usage(int code); /* All other functions by Richard Nolde, not found in tiffcp */ static void initImageData (struct image_data *); @@ -617,7 +624,28 @@ static int dump_buffer (FILE *, int, uint32, uint32, uint32, unsigned char *); /* Functions derived in whole or in part from tiffcp */ /* The following functions are taken largely intact from tiffcp */ -static char* usage_info[] = { +#define DEFAULT_MAX_MALLOC (256 * 1024 * 1024) + +/* malloc size limit (in bytes) + * disabled when set to 0 */ +static tmsize_t maxMalloc = DEFAULT_MAX_MALLOC; + +/** + * 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 -k option to change limit.\n"); return NULL; + } + return _TIFFmalloc(s); +} + + + +static const char* usage_info[] = { "usage: tiffcrop [options] source1 ... sourceN destination", "where options are:", " -h Print this syntax listing", @@ -630,6 +658,7 @@ static char* usage_info[] = { " -s Write output in strips", " -t Write output in tiles", " -i Ignore read errors", +" -k size set the memory allocation limit in MiB. 0 to disable limit", " ", " -r # Make each strip have no more than # rows", " -w # Set output tile width (pixels)", @@ -798,7 +827,7 @@ static int readContigTilesIntoBuffer (TIFF* in, uint8* buf, if (tilesize == 0 || tile_rowsize == 0) { TIFFError("readContigTilesIntoBuffer", "Tile size or tile rowsize is zero"); - exit(-1); + exit(EXIT_FAILURE); } if (tilesize < (tsize_t)(tl * tile_rowsize)) @@ -812,7 +841,7 @@ static int readContigTilesIntoBuffer (TIFF* in, uint8* buf, if (tl != (tile_buffsize / tile_rowsize)) { TIFFError("readContigTilesIntoBuffer", "Integer overflow when calculating buffer size."); - exit(-1); + exit(EXIT_FAILURE); } } @@ -820,9 +849,9 @@ static int readContigTilesIntoBuffer (TIFF* in, uint8* buf, if( (size_t) tile_buffsize > 0xFFFFFFFFU - 3U ) { TIFFError("readContigTilesIntoBuffer", "Integer overflow when calculating buffer size."); - exit(-1); + exit(EXIT_FAILURE); } - tilebuf = _TIFFmalloc(tile_buffsize + 3); + tilebuf = limitMalloc(tile_buffsize + 3); if (tilebuf == 0) return 0; tilebuf[tile_buffsize] = 0; @@ -986,7 +1015,7 @@ static int readSeparateTilesIntoBuffer (TIFF* in, uint8 *obuf, for (sample = 0; (sample < spp) && (sample < MAX_SAMPLES); sample++) { srcbuffs[sample] = NULL; - tbuff = (unsigned char *)_TIFFmalloc(tilesize + 8); + tbuff = (unsigned char *)limitMalloc(tilesize + 8); if (!tbuff) { TIFFError ("readSeparateTilesIntoBuffer", @@ -1181,7 +1210,7 @@ writeBufferToSeparateStrips (TIFF* out, uint8* buf, } rowstripsize = rowsperstrip * bytes_per_sample * (width + 1); - obuf = _TIFFmalloc (rowstripsize); + obuf = limitMalloc (rowstripsize); if (obuf == NULL) return 1; @@ -1246,7 +1275,7 @@ static int writeBufferToContigTiles (TIFF* out, uint8* buf, uint32 imagelength, if (tilesize == 0 || tile_rowsize == 0 || tl == 0 || tw == 0) { TIFFError("writeBufferToContigTiles", "Tile size, tile row size, tile width, or tile length is zero"); - exit(-1); + exit(EXIT_FAILURE); } tile_buffsize = tilesize; @@ -1261,7 +1290,7 @@ static int writeBufferToContigTiles (TIFF* out, uint8* buf, uint32 imagelength, if (tl != tile_buffsize / tile_rowsize) { TIFFError("writeBufferToContigTiles", "Integer overflow when calculating buffer size"); - exit(-1); + exit(EXIT_FAILURE); } } @@ -1275,7 +1304,7 @@ static int writeBufferToContigTiles (TIFF* out, uint8* buf, uint32 imagelength, } src_rowsize = ((imagewidth * spp * bps) + 7U) / 8; - tilebuf = _TIFFmalloc(tile_buffsize); + tilebuf = limitMalloc(tile_buffsize); if (tilebuf == 0) return 1; for (row = 0; row < imagelength; row += tl) @@ -1323,7 +1352,7 @@ static int writeBufferToSeparateTiles (TIFF* out, uint8* buf, uint32 imagelength uint32 imagewidth, tsample_t spp, struct dump_opts * dump) { - tdata_t obuf = _TIFFmalloc(TIFFTileSize(out)); + tdata_t obuf = limitMalloc(TIFFTileSize(out)); uint32 tl, tw; uint32 row, col, nrow, ncol; uint32 src_rowsize, col_offset; @@ -1334,9 +1363,10 @@ static int writeBufferToSeparateTiles (TIFF* out, uint8* buf, uint32 imagelength if (obuf == NULL) return 1; - TIFFGetField(out, TIFFTAG_TILELENGTH, &tl); - TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw); - TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps); + if( !TIFFGetField(out, TIFFTAG_TILELENGTH, &tl) || + !TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw) || + !TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps) ) + return 1; if( imagewidth == 0 || (uint32)bps * (uint32)spp > TIFF_UINT32_MAX / imagewidth || @@ -1407,7 +1437,7 @@ processG3Options(char* cp) else if (strneq(cp, "fill", 4)) defg3opts |= GROUP3OPT_FILLBITS; else - usage(); + usage(EXIT_FAILURE); } while( (cp = strchr(cp, ':')) ); } } @@ -1439,7 +1469,7 @@ processCompressOptions(char* opt) else if (strneq(cp + 1, "rgb", 3 )) jpegcolormode = JPEGCOLORMODE_RGB; else - usage(); + usage(EXIT_FAILURE); cp = strchr(cp + 1, ':'); } } @@ -1473,14 +1503,15 @@ processCompressOptions(char* opt) } static void -usage(void) +usage(int code) { int i; + FILE * out = (code == EXIT_SUCCESS) ? stdout : stderr; - fprintf(stderr, "\n%s\n", TIFFGetVersion()); + fprintf(out, "\n%s\n", TIFFGetVersion()); for (i = 0; usage_info[i] != NULL; i++) - fprintf(stderr, "%s\n", usage_info[i]); - exit(-1); + fprintf(out, "%s\n", usage_info[i]); + exit(code); } #define CopyField(tag, v) \ @@ -1611,7 +1642,7 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 *mp++ = 'w'; *mp = '\0'; while ((c = getopt(argc, argv, - "ac:d:e:f:hil:m:p:r:stvw:z:BCD:E:F:H:I:J:K:LMN:O:P:R:S:U:V:X:Y:Z:")) != -1) + "ac:d:e:f:hik:l:m:p:r:stvw:z:BCD:E:F:H:I:J:K:LMN:O:P:R:S:U:V:X:Y:Z:")) != -1) { good_args++; switch (c) { @@ -1621,7 +1652,7 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 { TIFFError ("Unknown compression option", "%s", optarg); TIFFError ("For valid options type", "tiffcrop -h"); - exit (-1); + exit (EXIT_FAILURE); } break; case 'd': start = strtoul(optarg, NULL, 0); /* initial IFD offset */ @@ -1629,7 +1660,7 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 { TIFFError ("","Directory offset must be greater than zero"); TIFFError ("For valid options type", "tiffcrop -h"); - exit (-1); + exit (EXIT_FAILURE); } *dirnum = start - 1; break; @@ -1652,7 +1683,7 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 break; /* Sections */ default: TIFFError ("Unknown export mode","%s", optarg); TIFFError ("For valid options type", "tiffcrop -h"); - exit (-1); + exit (EXIT_FAILURE); } break; case 'f': if (streq(optarg, "lsb2msb")) /* fill order */ @@ -1663,13 +1694,15 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 { TIFFError ("Unknown fill order", "%s", optarg); TIFFError ("For valid options type", "tiffcrop -h"); - exit (-1); + exit (EXIT_FAILURE); } break; - case 'h': usage(); + case 'h': usage(EXIT_SUCCESS); break; case 'i': ignore = TRUE; /* ignore errors */ break; + case 'k': maxMalloc = (tmsize_t)strtoul(optarg, NULL, 0) << 20; + break; case 'l': outtiled = TRUE; /* tile length */ *deftilelength = atoi(optarg); break; @@ -1682,7 +1715,7 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 { TIFFError ("Unknown planar configuration", "%s", optarg); TIFFError ("For valid options type", "tiffcrop -h"); - exit (-1); + exit (EXIT_FAILURE); } break; case 'r': /* rows/strip */ @@ -1694,13 +1727,13 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 case 't': /* generate tiled output */ outtiled = TRUE; break; - case 'v': TIFFError("Library Release", "%s", TIFFGetVersion()); - TIFFError ("Tiffcrop version", "%s, last updated: %s", + case 'v': printf("Library Release: %s\n", TIFFGetVersion()); + printf("Tiffcrop version: %s, last updated: %s\n", tiffcrop_version_id, tiffcrop_rev_date); - TIFFError ("Tiffcp code", "Copyright (c) 1988-1997 Sam Leffler"); - TIFFError (" ", "Copyright (c) 1991-1997 Silicon Graphics, Inc"); - TIFFError ("Tiffcrop additions", "Copyright (c) 2007-2010 Richard Nolde"); - exit (0); + printf("Tiffcp code: Copyright (c) 1988-1997 Sam Leffler\n"); + printf(" : Copyright (c) 1991-1997 Silicon Graphics, Inc\n"); + printf("Tiffcrop additions: Copyright (c) 2007-2010 Richard Nolde\n"); + exit (EXIT_SUCCESS); break; case 'w': /* tile width */ outtiled = TRUE; @@ -1719,7 +1752,7 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 { TIFFError ("Unable to parse coordinates for region", "%d %s", i, optarg); TIFFError ("For valid options type", "tiffcrop -h"); - exit (-1); + exit (EXIT_FAILURE); } } /* check for remaining elements over MAX_REGIONS */ @@ -1727,7 +1760,7 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 { TIFFError ("Region list exceeds limit of", "%d regions %s", MAX_REGIONS, optarg); TIFFError ("For valid options type", "tiffcrop -h"); - exit (-1);; + exit (EXIT_FAILURE);; } break; /* options for file open modes */ @@ -1749,7 +1782,7 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 { TIFFError("Invalid dump option", "%s", optarg); TIFFError ("For valid options type", "tiffcrop -h"); - exit (-1); + exit (EXIT_FAILURE); } *opt_offset = '\0'; @@ -1781,7 +1814,7 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 { TIFFError("parse_command_opts", "Unknown dump format %s", opt_offset + 1); TIFFError ("For valid options type", "tiffcrop -h"); - exit (-1); + exit (EXIT_FAILURE); } } } @@ -1813,7 +1846,7 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 { TIFFError("", "You must specify a dump format for dump files"); TIFFError ("For valid options type", "tiffcrop -h"); - exit (-1); + exit (EXIT_FAILURE); } } break; @@ -1842,7 +1875,7 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 break; default: TIFFError ("Edge reference must be top, bottom, left, or right", "%s", optarg); TIFFError ("For valid options type", "tiffcrop -h"); - exit (-1); + exit (EXIT_FAILURE); } break; case 'F': /* flip eg mirror image or cropped segment, M was already used */ @@ -1857,7 +1890,7 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 break; default: TIFFError ("Flip mode must be horiz, vert, or both", "%s", optarg); TIFFError ("For valid options type", "tiffcrop -h"); - exit (-1); + exit (EXIT_FAILURE); } break; case 'H': /* set horizontal resolution to new value */ @@ -1890,7 +1923,7 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 TIFFError("Missing or unknown option for inverting PHOTOMETRIC_INTERPRETATION", "%s", optarg); TIFFError ("For valid options type", "tiffcrop -h"); - exit (-1); + exit (EXIT_FAILURE); break; case 'J': /* horizontal margin for sectioned ouput pages */ page->hmargin = atof(optarg); @@ -1963,7 +1996,7 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 break; default: TIFFError ("Orientation must be portrait, landscape, or auto.", "%s", optarg); TIFFError ("For valid options type", "tiffcrop -h"); - exit (-1); + exit (EXIT_FAILURE); } break; case 'P': /* page size selection */ @@ -1982,7 +2015,7 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 TIFFError ("", "%-15.15s %5.2f %5.2f", PaperTable[i].name, PaperTable[i].width, PaperTable[i].length); - exit (-1); + exit (EXIT_FAILURE); } TIFFError ("Invalid paper size", "%s", optarg); @@ -1992,7 +2025,7 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 TIFFError ("", "%-15.15s %5.2f %5.2f", PaperTable[i].name, PaperTable[i].width, PaperTable[i].length); - exit (-1); + exit (EXIT_FAILURE); } else { @@ -2011,7 +2044,7 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 break; default: TIFFError ("Rotation must be 90, 180, or 270 degrees clockwise", "%s", optarg); TIFFError ("For valid options type", "tiffcrop -h"); - exit (-1); + exit (EXIT_FAILURE); } break; case 'S': /* subdivide into Cols:Rows sections, eg 3:2 would be 3 across and 2 down */ @@ -2030,7 +2063,7 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 if ((page->cols * page->rows) > MAX_SECTIONS) { TIFFError ("Limit for subdivisions, ie rows x columns, exceeded", "%d", MAX_SECTIONS); - exit (-1); + exit (EXIT_FAILURE); } page->mode |= PAGE_MODE_ROWSCOLS; break; @@ -2054,7 +2087,7 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 { TIFFError ("Illegal unit of measure","%s", optarg); TIFFError ("For valid options type", "tiffcrop -h"); - exit (-1); + exit (EXIT_FAILURE); } break; case 'V': /* set vertical resolution to new value */ @@ -2079,7 +2112,7 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 opt_offset = strchr(opt_ptr, ':'); if (!opt_offset) { TIFFError("Wrong parameter syntax for -Z", "tiffcrop -h"); - exit(-1); + exit(EXIT_FAILURE); } *opt_offset = '\0'; crop_data->zonelist[i].position = atoi(opt_ptr); @@ -2089,11 +2122,11 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 if ((opt_ptr != NULL) && (i >= MAX_REGIONS)) { TIFFError("Zone list exceeds region limit", "%d", MAX_REGIONS); - exit (-1); + exit (EXIT_FAILURE); } break; case '?': TIFFError ("For valid options type", "tiffcrop -h"); - exit (-1); + exit (EXIT_FAILURE); /*NOTREACHED*/ } } @@ -2225,7 +2258,7 @@ main(int argc, char* argv[]) &crop, &page, &dump, imagelist, &image_count); if (argc - optind < 2) - usage(); + usage(EXIT_FAILURE); if ((argc - optind) == 2) pageNum = -1; @@ -2318,7 +2351,7 @@ main(int argc, char* argv[]) if ((dump.infile = fopen(temp_filename, dump.mode)) == NULL) { TIFFError ("Unable to open dump file for writing", "%s", temp_filename); - exit (-1); + exit (EXIT_FAILURE); } dump_info(dump.infile, dump.format, "Reading image","%d from %s", dump_images, TIFFFileName(in)); @@ -2337,7 +2370,7 @@ main(int argc, char* argv[]) if ((dump.outfile = fopen(temp_filename, dump.mode)) == NULL) { TIFFError ("Unable to open dump file for writing", "%s", temp_filename); - exit (-1); + exit (EXIT_FAILURE); } dump_info(dump.outfile, dump.format, "Writing image","%d from %s", dump_images, TIFFFileName(in)); @@ -2350,7 +2383,7 @@ main(int argc, char* argv[]) if (loadImage(in, &image, &dump, &read_buff)) { TIFFError("main", "Unable to load source image"); - exit (-1); + exit (EXIT_FAILURE); } /* Correct the image orientation if it was not ORIENTATION_TOPLEFT. @@ -2364,7 +2397,7 @@ main(int argc, char* argv[]) if (getCropOffsets(&image, &crop, &dump)) { TIFFError("main", "Unable to define crop regions"); - exit (-1); + exit (EXIT_FAILURE); } if (crop.selections > 0) @@ -2372,7 +2405,7 @@ main(int argc, char* argv[]) if (processCropSelections(&image, &crop, &read_buff, seg_buffs)) { TIFFError("main", "Unable to process image selections"); - exit (-1); + exit (EXIT_FAILURE); } } else /* Single image segment without zones or regions */ @@ -2380,7 +2413,7 @@ main(int argc, char* argv[]) if (createCroppedImage(&image, &crop, &read_buff, &crop_buff)) { TIFFError("main", "Unable to create output image"); - exit (-1); + exit (EXIT_FAILURE); } } if (page.mode == PAGE_MODE_NONE) @@ -2394,12 +2427,12 @@ main(int argc, char* argv[]) { if (update_output_file (&out, mp, crop.exp_mode, argv[argc - 1], &next_page)) - exit (1); + exit (EXIT_FAILURE); if (writeCroppedImage(in, out, &image, &dump,crop.combined_width, crop.combined_length, crop_buff, next_page, total_pages)) { TIFFError("main", "Unable to write new image"); - exit (-1); + exit (EXIT_FAILURE); } } } @@ -2416,18 +2449,18 @@ main(int argc, char* argv[]) if (computeOutputPixelOffsets(&crop, &image, &page, sections, &dump)) { TIFFError("main", "Unable to compute output section data"); - exit (-1); + exit (EXIT_FAILURE); } /* If there are multiple files on the command line, the final one is assumed * to be the output filename into which the images are written. */ if (update_output_file (&out, mp, crop.exp_mode, argv[argc - 1], &next_page)) - exit (1); + exit (EXIT_FAILURE); if (writeImageSections(in, out, &image, &page, sections, &dump, sect_src, §_buff)) { TIFFError("main", "Unable to write image sections"); - exit (-1); + exit (EXIT_FAILURE); } } @@ -3002,9 +3035,25 @@ extractContigSamples24bits (uint8 *in, uint8 *out, uint32 cols, src = in + src_byte; matchbits = maskbits << (32 - src_bit - bps); if (little_endian) - buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3]; + { + buff1 = (src[0] << 24); + if (matchbits & 0x00ff0000) + buff1 |= (src[1] << 16); + if (matchbits & 0x0000ff00) + buff1 |= (src[2] << 8); + if (matchbits & 0x000000ff) + buff1 |= src[3]; + } else - buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0]; + { + buff1 = src[0]; + if (matchbits & 0x0000ff00) + buff1 |= (src[1] << 8); + if (matchbits & 0x00ff0000) + buff1 |= (src[2] << 16); + if (matchbits & 0xff000000) + buff1 |= (src[3] << 24); + } buff1 = (buff1 & matchbits) << (src_bit); if (ready_bits < 16) /* add another bps bits to the buffer */ @@ -4023,9 +4072,9 @@ combineSeparateSamples24bits (uint8 *in[], uint8 *out, uint32 cols, { src = in[s] + src_offset + src_byte; if (little_endian) - buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3]; + buff1 = ((uint32)src[0] << 24) | ((uint32)src[1] << 16) | ((uint32)src[2] << 8) | (uint32)src[3]; else - buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0]; + buff1 = ((uint32)src[3] << 24) | ((uint32)src[2] << 16) | ((uint32)src[1] << 8) | (uint32)src[0]; buff1 = (buff1 & matchbits) << (src_bit); /* If we have a full buffer's worth, write it out */ @@ -4824,13 +4873,13 @@ static int readSeparateStripsIntoBuffer (TIFF *in, uint8 *obuf, uint32 length, if( (size_t) stripsize > 0xFFFFFFFFU - 3U ) { TIFFError("readSeparateStripsIntoBuffer", "Integer overflow when calculating buffer size."); - exit(-1); + exit(EXIT_FAILURE); } for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++) { srcbuffs[s] = NULL; - buff = _TIFFmalloc(stripsize + 3); + buff = limitMalloc(stripsize + 3); if (!buff) { TIFFError ("readSeparateStripsIntoBuffer", @@ -6034,13 +6083,13 @@ loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned c if (ntiles == 0 || tlsize == 0 || tile_rowsize == 0) { TIFFError("loadImage", "File appears to be tiled, but the number of tiles, tile size, or tile rowsize is zero."); - exit(-1); + exit(EXIT_FAILURE); } buffsize = tlsize * ntiles; if (tlsize != (buffsize / ntiles)) { TIFFError("loadImage", "Integer overflow when calculating buffer size"); - exit(-1); + exit(EXIT_FAILURE); } if (buffsize < (uint32)(ntiles * tl * tile_rowsize)) @@ -6049,7 +6098,7 @@ loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned c if (ntiles != (buffsize / tl / tile_rowsize)) { TIFFError("loadImage", "Integer overflow when calculating buffer size"); - exit(-1); + exit(EXIT_FAILURE); } #ifdef DEBUG2 @@ -6074,20 +6123,20 @@ loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned c if (nstrips == 0 || stsize == 0) { TIFFError("loadImage", "File appears to be striped, but the number of stipes or stripe size is zero."); - exit(-1); + exit(EXIT_FAILURE); } buffsize = stsize * nstrips; if (stsize != (buffsize / nstrips)) { TIFFError("loadImage", "Integer overflow when calculating buffer size"); - exit(-1); + exit(EXIT_FAILURE); } buffsize_check = ((length * width * spp * bps) + 7); if (length != ((buffsize_check - 7) / width / spp / bps)) { TIFFError("loadImage", "Integer overflow detected."); - exit(-1); + exit(EXIT_FAILURE); } if (buffsize < (uint32) (((length * width * spp * bps) + 7) / 8)) { @@ -6137,7 +6186,7 @@ loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned c TIFFError("loadImage", "Unable to allocate/reallocate read buffer"); return (-1); } - read_buff = (unsigned char *)_TIFFmalloc(buffsize+3); + read_buff = (unsigned char *)limitMalloc(buffsize+3); } else { @@ -6152,7 +6201,7 @@ loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned c if (!new_buff) { free (read_buff); - read_buff = (unsigned char *)_TIFFmalloc(buffsize+3); + read_buff = (unsigned char *)limitMalloc(buffsize+3); } else read_buff = new_buff; @@ -7026,21 +7075,21 @@ writeImageSections(TIFF *in, TIFF *out, struct image_data *image, if (createImageSection(sectsize, sect_buff_ptr)) { TIFFError("writeImageSections", "Unable to allocate section buffer"); - exit (-1); + exit(EXIT_FAILURE); } sect_buff = *sect_buff_ptr; if (extractImageSection (image, §ions[i], src_buff, sect_buff)) { TIFFError("writeImageSections", "Unable to extract image sections"); - exit (-1); + exit(EXIT_FAILURE); } /* call the write routine here instead of outside the loop */ if (writeSingleSection(in, out, image, dump, width, length, hres, vres, sect_buff)) { TIFFError("writeImageSections", "Unable to write image section"); - exit (-1); + exit(EXIT_FAILURE); } } @@ -7335,7 +7384,7 @@ createImageSection(uint32 sectsize, unsigned char **sect_buff_ptr) if (!sect_buff) { - sect_buff = (unsigned char *)_TIFFmalloc(sectsize); + sect_buff = (unsigned char *)limitMalloc(sectsize); *sect_buff_ptr = sect_buff; _TIFFmemset(sect_buff, 0, sectsize); } @@ -7346,8 +7395,8 @@ createImageSection(uint32 sectsize, unsigned char **sect_buff_ptr) new_buff = _TIFFrealloc(sect_buff, sectsize); if (!new_buff) { - free (sect_buff); - sect_buff = (unsigned char *)_TIFFmalloc(sectsize); + _TIFFfree (sect_buff); + sect_buff = (unsigned char *)limitMalloc(sectsize); } else sect_buff = new_buff; @@ -7388,7 +7437,7 @@ processCropSelections(struct image_data *image, struct crop_mask *crop, cropsize = crop->bufftotal; crop_buff = seg_buffs[0].buffer; if (!crop_buff) - crop_buff = (unsigned char *)_TIFFmalloc(cropsize); + crop_buff = (unsigned char *)limitMalloc(cropsize); else { prev_cropsize = seg_buffs[0].size; @@ -7398,7 +7447,7 @@ processCropSelections(struct image_data *image, struct crop_mask *crop, if (! next_buff) { _TIFFfree (crop_buff); - crop_buff = (unsigned char *)_TIFFmalloc(cropsize); + crop_buff = (unsigned char *)limitMalloc(cropsize); } else crop_buff = next_buff; @@ -7490,7 +7539,7 @@ processCropSelections(struct image_data *image, struct crop_mask *crop, cropsize = crop->bufftotal; crop_buff = seg_buffs[i].buffer; if (!crop_buff) - crop_buff = (unsigned char *)_TIFFmalloc(cropsize); + crop_buff = (unsigned char *)limitMalloc(cropsize); else { prev_cropsize = seg_buffs[0].size; @@ -7500,7 +7549,7 @@ processCropSelections(struct image_data *image, struct crop_mask *crop, if (! next_buff) { _TIFFfree (crop_buff); - crop_buff = (unsigned char *)_TIFFmalloc(cropsize); + crop_buff = (unsigned char *)limitMalloc(cropsize); } else crop_buff = next_buff; @@ -7626,7 +7675,7 @@ createCroppedImage(struct image_data *image, struct crop_mask *crop, crop_buff = *crop_buff_ptr; if (!crop_buff) { - crop_buff = (unsigned char *)_TIFFmalloc(cropsize); + crop_buff = (unsigned char *)limitMalloc(cropsize); *crop_buff_ptr = crop_buff; _TIFFmemset(crop_buff, 0, cropsize); prev_cropsize = cropsize; @@ -7639,7 +7688,7 @@ createCroppedImage(struct image_data *image, struct crop_mask *crop, if (!new_buff) { free (crop_buff); - crop_buff = (unsigned char *)_TIFFmalloc(cropsize); + crop_buff = (unsigned char *)limitMalloc(cropsize); } else crop_buff = new_buff; @@ -8412,7 +8461,7 @@ rotateImage(uint16 rotation, struct image_data *image, uint32 *img_width, return (-1); } - if (!(rbuff = (unsigned char *)_TIFFmalloc(buffsize))) + if (!(rbuff = (unsigned char *)limitMalloc(buffsize))) { TIFFError("rotateImage", "Unable to allocate rotation buffer of %1u bytes", buffsize); return (-1); @@ -9042,7 +9091,7 @@ mirrorImage(uint16 spp, uint16 bps, uint16 mirror, uint32 width, uint32 length, { case MIRROR_BOTH: case MIRROR_VERT: - line_buff = (unsigned char *)_TIFFmalloc(rowsize); + line_buff = (unsigned char *)limitMalloc(rowsize); if (line_buff == NULL) { TIFFError ("mirrorImage", "Unable to allocate mirror line buffer of %1u bytes", rowsize); @@ -9079,7 +9128,7 @@ mirrorImage(uint16 spp, uint16 bps, uint16 mirror, uint32 width, uint32 length, } else { /* non 8 bit per sample data */ - if (!(line_buff = (unsigned char *)_TIFFmalloc(rowsize + 1))) + if (!(line_buff = (unsigned char *)limitMalloc(rowsize + 1))) { TIFFError("mirrorImage", "Unable to allocate mirror line buffer"); return (-1); diff --git a/tiff/tools/tiffdither.c b/tiff/tools/tiffdither.c index 3fd7f81a..a9d1b7c5 100644 --- a/tiff/tools/tiffdither.c +++ b/tiff/tools/tiffdither.c @@ -39,6 +39,13 @@ #include "tiffio.h" #include "tiffiop.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 strneq(a,b,n) (strncmp(a,b,n) == 0) @@ -49,7 +56,7 @@ uint32 imagewidth; uint32 imagelength; int threshold = 128; -static void usage(void); +static void usage(int code); /* * Floyd-Steinberg error propragation with threshold. @@ -166,7 +173,7 @@ processG3Options(char* cp) else if (strneq(cp, "fill", 4)) group3options |= GROUP3OPT_FILLBITS; else - usage(); + usage(EXIT_FAILURE); } while ((cp = strchr(cp, ':'))); } } @@ -213,11 +220,11 @@ main(int argc, char* argv[]) extern char *optarg; #endif - while ((c = getopt(argc, argv, "c:f:r:t:")) != -1) + while ((c = getopt(argc, argv, "c:f:r:t:h")) != -1) switch (c) { case 'c': /* compression scheme */ if (!processCompressOptions(optarg)) - usage(); + usage(EXIT_FAILURE); break; case 'f': /* fill order */ if (streq(optarg, "lsb2msb")) @@ -225,7 +232,7 @@ main(int argc, char* argv[]) else if (streq(optarg, "msb2lsb")) fillorder = FILLORDER_MSB2LSB; else - usage(); + usage(EXIT_FAILURE); break; case 'r': /* rows/strip */ rowsperstrip = atoi(optarg); @@ -237,29 +244,31 @@ main(int argc, char* argv[]) else if (threshold > 255) threshold = 255; break; + case 'h': + usage(EXIT_SUCCESS); case '?': - usage(); + usage(EXIT_FAILURE); /*NOTREACHED*/ } if (argc - optind < 2) - usage(); + usage(EXIT_FAILURE); in = TIFFOpen(argv[optind], "r"); if (in == NULL) - return (-1); + return (EXIT_FAILURE); TIFFGetField(in, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel); if (samplesperpixel != 1) { fprintf(stderr, "%s: Not a b&w image.\n", argv[0]); - return (-1); + return (EXIT_FAILURE); } TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample); if (bitspersample != 8) { fprintf(stderr, " %s: Sorry, only handle 8-bit samples.\n", argv[0]); - return (-1); + return (EXIT_FAILURE); } out = TIFFOpen(argv[optind+1], "w"); if (out == NULL) - return (-1); + return (EXIT_FAILURE); CopyField(TIFFTAG_IMAGEWIDTH, imagewidth); TIFFGetField(in, TIFFTAG_IMAGELENGTH, &imagelength); TIFFSetField(out, TIFFTAG_IMAGELENGTH, imagelength-1); @@ -293,10 +302,10 @@ main(int argc, char* argv[]) fsdither(in, out); TIFFClose(in); TIFFClose(out); - return (0); + return (EXIT_SUCCESS); } -char* stuff[] = { +static const char* stuff[] = { "usage: tiffdither [options] input.tif output.tif", "where options are:", " -r # make each strip have no more than # rows", @@ -323,16 +332,15 @@ NULL }; static void -usage(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]); - exit(-1); + fprintf(out, "%s\n", stuff[i]); + exit(code); } /* vim: set ts=8 sts=8 sw=8 noet: */ diff --git a/tiff/tools/tiffdump.c b/tiff/tools/tiffdump.c index 4cdcda0c..00be9dd4 100644 --- a/tiff/tools/tiffdump.c +++ b/tiff/tools/tiffdump.c @@ -56,6 +56,13 @@ extern int getopt(int argc, char * const argv[], const char *optstring); #include "tiffio.h" +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif + #ifndef O_BINARY # define O_BINARY 0 #endif @@ -105,7 +112,7 @@ void usage() { fprintf(stderr, "usage: %s [-h] [-o offset] [-m maxitems] file.tif ...\n", appname); - exit(-1); + exit(EXIT_FAILURE); } int @@ -142,7 +149,7 @@ main(int argc, char* argv[]) fd = open(argv[optind], O_RDONLY|O_BINARY, 0); if (fd < 0) { perror(argv[0]); - return (-1); + return (EXIT_FAILURE); } if (multiplefiles) printf("%s:\n", argv[optind]); @@ -152,7 +159,7 @@ main(int argc, char* argv[]) dump(fd, diroff); close(fd); } - return (0); + return (EXIT_SUCCESS); } #define ord(e) ((int)e) @@ -451,7 +458,7 @@ ReadDirectory(int fd, unsigned int ix, uint64 off) { datafits = 0; datamem = NULL; - dataoffset = *(uint64*)dp; + memcpy(&dataoffset, dp, sizeof(uint64)); if (swabflag) TIFFSwabLong8(&dataoffset); } @@ -874,7 +881,7 @@ Fatal(const char* fmt, ...) va_start(ap, fmt); vError(stderr, fmt, ap); va_end(ap); - exit(-1); + exit(EXIT_FAILURE); } /* vim: set ts=8 sts=8 sw=8 noet: */ diff --git a/tiff/tools/tiffgt.c b/tiff/tools/tiffgt.c index 2f11b0ca..f3cca8c9 100644 --- a/tiff/tools/tiffgt.c +++ b/tiff/tools/tiffgt.c @@ -48,6 +48,13 @@ #include "tiffio.h" #include "tiffiop.h" +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif + #ifndef HAVE_GETOPT extern int getopt(int argc, char * const argv[], const char *optstring); #endif @@ -68,12 +75,12 @@ static int filenum; static TIFFErrorHandler oerror; static TIFFErrorHandler owarning; -static void cleanup_and_exit(void); +static void cleanup_and_exit(int); static int initImage(void); static int prevImage(void); static int nextImage(void); static void setWindowSize(void); -static void usage(void); +static void usage(int); static uint16 photoArg(const char*); static void raster_draw(void); static void raster_reshape(int, int); @@ -102,7 +109,7 @@ main(int argc, char* argv[]) oerror = TIFFSetErrorHandler(NULL); owarning = TIFFSetWarningHandler(NULL); - while ((c = getopt(argc, argv, "d:o:p:eflmsvw?")) != -1) + while ((c = getopt(argc, argv, "d:o:p:eflmsvwh")) != -1) switch (c) { case 'd': dirnum = atoi(optarg); @@ -131,13 +138,16 @@ main(int argc, char* argv[]) case 'v': verbose = 1; break; + case 'h': + usage(EXIT_SUCCESS); + /*NOTREACHED*/ case '?': - usage(); + usage(EXIT_FAILURE); /*NOTREACHED*/ } filenum = argc - optind; if ( filenum < 1) - usage(); + usage(EXIT_FAILURE); glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); @@ -157,13 +167,13 @@ main(int argc, char* argv[]) filelist = (char **) _TIFFmalloc(filenum * sizeof(char*)); if (!filelist) { TIFFError(argv[0], "Can not allocate space for the file list."); - return 1; + return EXIT_FAILURE; } _TIFFmemcpy(filelist, argv + optind, filenum * sizeof(char*)); fileindex = -1; if (nextImage() < 0) { _TIFFfree(filelist); - return 2; + return EXIT_FAILURE; } /* * Set initial directory if user-specified @@ -177,7 +187,7 @@ main(int argc, char* argv[]) photo = photo0; if (initImage() < 0){ _TIFFfree(filelist); - return 3; + return EXIT_FAILURE; } /* * Create a new window or reconfigure an existing @@ -193,12 +203,12 @@ main(int argc, char* argv[]) glutSpecialFunc(raster_special); glutMainLoop(); - cleanup_and_exit(); - return 0; + cleanup_and_exit(EXIT_SUCCESS); + return EXIT_SUCCESS; } static void -cleanup_and_exit(void) +cleanup_and_exit(int code) { TIFFRGBAImageEnd(&img); if (filelist != NULL) @@ -207,7 +217,7 @@ cleanup_and_exit(void) _TIFFfree(raster); if (tif != NULL) TIFFClose(tif); - exit(0); + exit(code); } static int @@ -250,7 +260,7 @@ initImage(void) if (raster == NULL) { width = height = 0; TIFFError(filelist[fileindex], "No space for raster buffer"); - cleanup_and_exit(); + cleanup_and_exit(EXIT_FAILURE); } width = w; height = h; @@ -361,7 +371,7 @@ raster_keys(unsigned char key, int x, int y) break; case 'q': /* exit */ case '\033': - cleanup_and_exit(); + cleanup_and_exit(EXIT_SUCCESS); } glutPostRedisplay(); } @@ -422,7 +432,7 @@ raster_special(int key, int x, int y) # pragma GCC diagnostic pop # endif -char* stuff[] = { +static const char* stuff[] = { "usage: tiffgt [options] file.tif", "where options are:", " -c use colormap visual", @@ -440,16 +450,15 @@ NULL }; static void -usage(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]); - exit(-1); + fprintf(out, "%s\n", stuff[i]); + exit(code); } static uint16 diff --git a/tiff/tools/tiffinfo.c b/tiff/tools/tiffinfo.c index 049e3a34..2271c9d1 100644 --- a/tiff/tools/tiffinfo.c +++ b/tiff/tools/tiffinfo.c @@ -42,15 +42,22 @@ #include "tiffiop.h" +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif + static TIFFErrorHandler old_error_handler = 0; -static int status = 0; /* exit status */ +static int status = EXIT_SUCCESS; /* exit status */ static int showdata = 0; /* show data */ static int rawdata = 0; /* show raw/decoded data */ static int showwords = 0; /* show data as bytes/words */ static int readdata = 0; /* read data in file */ static int stoponerr = 1; /* stop on first read error */ -static void usage(void); +static void usage(int); static void tiffinfo(TIFF*, uint16, long, int); static void @@ -58,7 +65,7 @@ PrivateErrorHandler(const char* module, const char* fmt, va_list ap) { if (old_error_handler) (*old_error_handler)(module,fmt,ap); - status = 1; + status = EXIT_FAILURE; } int @@ -75,7 +82,7 @@ main(int argc, char* argv[]) uint64 diroff = 0; int chopstrips = 0; /* disable strip chopping */ - while ((c = getopt(argc, argv, "f:o:cdDSjilmrsvwz0123456789")) != -1) + while ((c = getopt(argc, argv, "f:o:cdDSjilmrsvwz0123456789h")) != -1) switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': @@ -97,7 +104,7 @@ main(int argc, char* argv[]) else if (streq(optarg, "msb2lsb")) order = FILLORDER_MSB2LSB; else - usage(); + usage(EXIT_FAILURE); break; case 'i': stoponerr = 0; @@ -122,12 +129,15 @@ main(int argc, char* argv[]) case 'z': chopstrips = 1; break; + case 'h': + usage(EXIT_SUCCESS); + /*NOTREACHED*/ case '?': - usage(); + usage(EXIT_FAILURE); /*NOTREACHED*/ } if (optind >= argc) - usage(); + usage(EXIT_FAILURE); old_error_handler = TIFFSetErrorHandler(PrivateErrorHandler); @@ -162,7 +172,7 @@ main(int argc, char* argv[]) return (status); } -char* stuff[] = { +static const char* stuff[] = { "usage: tiffinfo [options] input...", "where options are:", " -D read data", @@ -182,16 +192,15 @@ NULL }; static void -usage(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]); - exit(-1); + fprintf(out, "%s\n", stuff[i]); + exit(code); } static void @@ -407,11 +416,11 @@ ShowRawWords(uint16* pp, uint32 n) putchar('\n'); } -void -TIFFReadRawData(TIFF* tif, int bitrev) +static void +TIFFReadRawDataStriped(TIFF* tif, int bitrev) { tstrip_t nstrips = TIFFNumberOfStrips(tif); - const char* what = TIFFIsTiled(tif) ? "Tile" : "Strip"; + const char* what = "Strip"; uint64* stripbc=NULL; TIFFGetField(tif, TIFFTAG_STRIPBYTECOUNTS, &stripbc); @@ -456,6 +465,66 @@ TIFFReadRawData(TIFF* tif, int bitrev) } static void +TIFFReadRawDataTiled(TIFF* tif, int bitrev) +{ + const char* what = "Tile"; + uint32 ntiles = TIFFNumberOfTiles(tif); + uint64 *tilebc; + + TIFFGetField(tif, TIFFTAG_TILEBYTECOUNTS, &tilebc); + if (tilebc != NULL && ntiles > 0) { + uint64 bufsize = 0; + tdata_t buf = NULL; + uint32 t; + + for (t = 0; t < ntiles; t++) { + if (buf == NULL || tilebc[t] > bufsize) { + buf = _TIFFrealloc(buf, (tmsize_t)tilebc[t]); + bufsize = tilebc[t]; + } + if (buf == NULL) { + fprintf(stderr, + "Cannot allocate buffer to read tile %lu\n", + (unsigned long) t); + break; + } + if (TIFFReadRawTile(tif, t, buf, (tmsize_t)tilebc[t]) < 0) { + fprintf(stderr, "Error reading tile %lu\n", + (unsigned long) t); + if (stoponerr) + break; + } else if (showdata) { + if (bitrev) { + TIFFReverseBits(buf, (tmsize_t)tilebc[t]); + printf("%s %lu: (bit reversed)\n ", + what, (unsigned long) t); + } else { + printf("%s %lu:\n ", what, + (unsigned long) t); + } + if (showwords) { + ShowRawWords((uint16*) buf, (uint32)(tilebc[t]>>1)); + } else { + ShowRawBytes((unsigned char*) buf, (uint32) tilebc[t]); + } + } + } + if (buf != NULL) + _TIFFfree(buf); + } +} + +void +TIFFReadRawData(TIFF* tif, int bitrev) +{ + if (TIFFIsTiled(tif)) { + TIFFReadRawDataTiled(tif, bitrev); + } else { + TIFFReadRawDataStriped(tif, bitrev); + } +} + +static void tiffinfo(TIFF* tif, uint16 order, long flags, int is_image) { TIFFPrintDirectory(tif, stdout, flags); diff --git a/tiff/tools/tiffmedian.c b/tiff/tools/tiffmedian.c index bd0d1561..6654cd6f 100644 --- a/tiff/tools/tiffmedian.c +++ b/tiff/tools/tiffmedian.c @@ -54,6 +54,13 @@ #include "tiffio.h" +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif + #define MAX_CMAP_SIZE 256 #define streq(a,b) (strcmp(a,b) == 0) @@ -106,7 +113,7 @@ static void quant(TIFF*, TIFF*); static void quant_fsdither(TIFF*, TIFF*); static Colorbox* largest_box(void); -static void usage(void); +static void usage(int); static int processCompressOptions(char*); #define CopyField(tag, v) \ @@ -127,11 +134,11 @@ main(int argc, char* argv[]) #endif num_colors = MAX_CMAP_SIZE; - while ((c = getopt(argc, argv, "c:C:r:f")) != -1) + while ((c = getopt(argc, argv, "c:C:r:fh")) != -1) switch (c) { case 'c': /* compression scheme */ if (!processCompressOptions(optarg)) - usage(); + usage(EXIT_FAILURE); break; case 'C': /* set colormap size */ num_colors = atoi(optarg); @@ -139,7 +146,7 @@ main(int argc, char* argv[]) fprintf(stderr, "-c: colormap too big, max %d\n", MAX_CMAP_SIZE); - usage(); + usage(EXIT_FAILURE); } break; case 'f': /* dither */ @@ -148,15 +155,18 @@ main(int argc, char* argv[]) case 'r': /* rows/strip */ rowsperstrip = atoi(optarg); break; + case 'h': + usage(EXIT_SUCCESS); + /*NOTREACHED*/ case '?': - usage(); + usage(EXIT_FAILURE); /*NOTREACHED*/ } if (argc - optind != 2) - usage(); + usage(EXIT_FAILURE); in = TIFFOpen(argv[optind], "r"); if (in == NULL) - return (-1); + return (EXIT_FAILURE); TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &imagewidth); TIFFGetField(in, TIFFTAG_IMAGELENGTH, &imagelength); TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample); @@ -164,18 +174,18 @@ main(int argc, char* argv[]) if (bitspersample != 8 && bitspersample != 16) { fprintf(stderr, "%s: Image must have at least 8-bits/sample\n", argv[optind]); - return (-3); + return (EXIT_FAILURE); } if (!TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &photometric) || photometric != PHOTOMETRIC_RGB || samplesperpixel < 3) { fprintf(stderr, "%s: Image must have RGB data\n", argv[optind]); - return (-4); + return (EXIT_FAILURE); } TIFFGetField(in, TIFFTAG_PLANARCONFIG, &config); if (config != PLANARCONFIG_CONTIG) { fprintf(stderr, "%s: Can only handle contiguous data packing\n", argv[optind]); - return (-5); + return (EXIT_FAILURE); } /* @@ -245,7 +255,7 @@ main(int argc, char* argv[]) */ out = TIFFOpen(argv[optind+1], "w"); if (out == NULL) - return (-2); + return (EXIT_FAILURE); CopyField(TIFFTAG_SUBFILETYPE, longv); CopyField(TIFFTAG_IMAGEWIDTH, longv); @@ -290,7 +300,7 @@ main(int argc, char* argv[]) } TIFFSetField(out, TIFFTAG_COLORMAP, rm, gm, bm); (void) TIFFClose(out); - return (0); + return (EXIT_SUCCESS); } static int @@ -333,16 +343,15 @@ NULL }; static void -usage(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]); - exit(-1); + fprintf(out, "%s\n", stuff[i]); + exit(code); } static void @@ -356,7 +365,7 @@ get_histogram(TIFF* in, Colorbox* box) inputline = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in)); if (inputline == NULL) { fprintf(stderr, "No space for scanline buffer\n"); - exit(-1); + exit(EXIT_FAILURE); } box->rmin = box->gmin = box->bmin = 999; box->rmax = box->gmax = box->bmax = -1; @@ -378,7 +387,7 @@ get_histogram(TIFF* in, Colorbox* box) fprintf(stderr, "Logic error. " "Histogram array overflow!\n"); - exit(-6); + exit(EXIT_FAILURE); } if (red < box->rmin) box->rmin = red; diff --git a/tiff/tools/tiffset.c b/tiff/tools/tiffset.c index 7ecc401b..75cf45c0 100644 --- a/tiff/tools/tiffset.c +++ b/tiff/tools/tiffset.c @@ -35,7 +35,18 @@ #include "tiffio.h" -static char* usageMsg[] = { +#ifdef NEED_LIBPORT +# include "libport.h" +#endif + +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif + +static const char* usageMsg[] = { "usage: tiffset [options] filename", "where options are:", " -s <tagname> [count] <value>... set the tag value", @@ -43,16 +54,20 @@ static char* usageMsg[] = { " -d <dirno> set the directory", " -sd <diroff> set the subdirectory", " -sf <tagname> <filename> read the tag value from file (for ASCII tags only)", +" -h this help screen", NULL }; static void -usage(void) +usage(int code) { int i; + FILE * out = (code == EXIT_SUCCESS) ? stdout : stderr; + + fprintf(out, "%s\n\n", TIFFGetVersion()); for (i = 0; usageMsg[i]; i++) - fprintf(stderr, "%s\n", usageMsg[i]); - exit(-1); + fprintf(out, "%s\n", usageMsg[i]); + exit(code); } static const TIFFField * @@ -80,11 +95,11 @@ main(int argc, char* argv[]) int arg_index; if (argc < 2) - usage(); + usage(EXIT_FAILURE); tiff = TIFFOpen(argv[argc-1], "r+"); if (tiff == NULL) - return 2; + return EXIT_FAILURE; for( arg_index = 1; arg_index < argc-1; arg_index++ ) { if (strcmp(argv[arg_index],"-d") == 0 && arg_index < argc-2) { @@ -92,7 +107,7 @@ main(int argc, char* argv[]) if( TIFFSetDirectory(tiff, atoi(argv[arg_index]) ) != 1 ) { fprintf( stderr, "Failed to set directory=%s\n", argv[arg_index] ); - return 6; + return EXIT_FAILURE; } arg_index++; } @@ -101,7 +116,7 @@ main(int argc, char* argv[]) if( TIFFSetSubDirectory(tiff, atoi(argv[arg_index]) ) != 1 ) { fprintf( stderr, "Failed to set sub directory=%s\n", argv[arg_index] ); - return 7; + return EXIT_FAILURE; } arg_index++; } @@ -113,7 +128,7 @@ main(int argc, char* argv[]) tagname = argv[arg_index]; fip = GetField(tiff, tagname); if (!fip) - return 3; + return EXIT_FAILURE; if (TIFFUnsetField(tiff, TIFFFieldTag(fip)) != 1) { @@ -151,7 +166,7 @@ main(int argc, char* argv[]) "Number of tag values is not enough. " "Expected %d values for %s tag, got %d\n", wc, TIFFFieldName(fip), argc - arg_index); - return 4; + return EXIT_FAILURE; } if (wc > 1 || TIFFFieldWriteCount(fip) == TIFF_VARIABLE) { @@ -200,7 +215,7 @@ main(int argc, char* argv[]) if (!array) { fprintf(stderr, "No space for %s tag\n", tagname); - return 4; + return EXIT_FAILURE; } switch (TIFFFieldDataType(fip)) { @@ -317,18 +332,19 @@ main(int argc, char* argv[]) const TIFFField *fip; char *text; size_t len; + int ret; arg_index++; fip = GetField(tiff, argv[arg_index]); if (!fip) - return 3; + return EXIT_FAILURE; if (TIFFFieldDataType(fip) != TIFF_ASCII) { fprintf( stderr, "Only ASCII tags can be set from file. " "%s is not ASCII tag.\n", TIFFFieldName(fip) ); - return 5; + return EXIT_FAILURE; } arg_index++; @@ -339,28 +355,41 @@ main(int argc, char* argv[]) } text = (char *) malloc(1000000); + if(text == NULL) { + fprintf( stderr, + "Memory allocation error\n"); + fclose( fp ); + continue; + } len = fread( text, 1, 999999, fp ); text[len] = '\0'; fclose( fp ); - if(TIFFSetField( tiff, TIFFFieldTag(fip), text ) != 1) { + if(TIFFFieldPassCount( fip )) { + ret = TIFFSetField( tiff, TIFFFieldTag(fip), (uint16)len, text ); + } else { + ret = TIFFSetField( tiff, TIFFFieldTag(fip), text ); + } + if(!ret) { fprintf(stderr, "Failed to set %s from file %s\n", TIFFFieldName(fip), argv[arg_index]); } _TIFFfree( text ); arg_index++; + } else if (strcmp(argv[arg_index],"-h") == 0 || strcmp(argv[arg_index],"--help") == 0) { + usage(EXIT_SUCCESS); } else { fprintf(stderr, "Unrecognised option: %s\n", argv[arg_index]); - usage(); + usage(EXIT_FAILURE); } } TIFFRewriteDirectory(tiff); TIFFClose(tiff); - return 0; + return EXIT_SUCCESS; } /* vim: set ts=8 sts=8 sw=8 noet: */ diff --git a/tiff/tools/tiffsplit.c b/tiff/tools/tiffsplit.c index c8b7f2dd..43b6fdc1 100644 --- a/tiff/tools/tiffsplit.c +++ b/tiff/tools/tiffsplit.c @@ -30,6 +30,13 @@ #include "tiffio.h" +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif + #ifndef HAVE_GETOPT extern int getopt(int argc, char * const argv[], const char *optstring); #endif @@ -60,7 +67,7 @@ main(int argc, char* argv[]) if (argc < 2) { fprintf(stderr, "%s\n\n", TIFFGetVersion()); fprintf(stderr, "usage: tiffsplit input.tif [prefix]\n"); - return (-3); + return (EXIT_FAILURE); } if (argc > 2) { strncpy(fname, argv[2], sizeof(fname)); @@ -83,14 +90,14 @@ main(int argc, char* argv[]) _TIFFfree(path); if (out == NULL) - return (-2); + return (EXIT_FAILURE); if (!tiffcp(in, out)) - return (-1); + return (EXIT_FAILURE); TIFFClose(out); } while (TIFFReadDirectory(in)); (void) TIFFClose(in); } - return (0); + return (EXIT_SUCCESS); } static void @@ -117,7 +124,7 @@ newfilename(void) if (fnum == MAXFILES) { if (!defname || fname[0] == 'z') { fprintf(stderr, "tiffsplit: too many files.\n"); - exit(1); + exit(EXIT_FAILURE); } fname[0]++; fnum = 0; |