summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Deutschmann <whissi@gentoo.org>2021-03-30 10:59:39 +0200
committerThomas Deutschmann <whissi@gentoo.org>2021-04-01 00:04:14 +0200
commit5ff1d6955496b3cf9a35042c9ac35db43bc336b1 (patch)
tree6d470f7eb448f59f53e8df1010aec9dad8ce1f72 /tiff/tools/tiffcp.c
parentImport Ghostscript 9.53.1 (diff)
downloadghostscript-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.c149
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);