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/tiffcp.c | |
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/tiffcp.c')
-rw-r--r-- | tiff/tools/tiffcp.c | 149 |
1 files changed, 101 insertions, 48 deletions
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); |