summaryrefslogtreecommitdiff
path: root/tiff/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tiff/tools')
-rw-r--r--tiff/tools/CMakeLists.txt27
-rw-r--r--tiff/tools/Makefile.in4
-rw-r--r--tiff/tools/fax2ps.c30
-rw-r--r--tiff/tools/fax2tiff.c23
-rw-r--r--tiff/tools/pal2rgb.c50
-rw-r--r--tiff/tools/ppm2tiff.c230
-rw-r--r--tiff/tools/raw2tiff.c63
-rw-r--r--tiff/tools/rgb2ycbcr.c32
-rw-r--r--tiff/tools/thumbnail.c32
-rw-r--r--tiff/tools/tiff2bw.c40
-rw-r--r--tiff/tools/tiff2pdf.c409
-rw-r--r--tiff/tools/tiff2ps.c122
-rw-r--r--tiff/tools/tiff2rgba.c62
-rw-r--r--tiff/tools/tiffcmp.c42
-rw-r--r--tiff/tools/tiffcp.c149
-rw-r--r--tiff/tools/tiffcrop.c235
-rw-r--r--tiff/tools/tiffdither.c46
-rw-r--r--tiff/tools/tiffdump.c17
-rw-r--r--tiff/tools/tiffgt.c51
-rw-r--r--tiff/tools/tiffinfo.c103
-rw-r--r--tiff/tools/tiffmedian.c49
-rw-r--r--tiff/tools/tiffset.c61
-rw-r--r--tiff/tools/tiffsplit.c17
23 files changed, 1269 insertions, 625 deletions
diff --git a/tiff/tools/CMakeLists.txt b/tiff/tools/CMakeLists.txt
index 886d4549c..ff2a1ddc2 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 7ec4ed620..8b1a24600 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 274b29e4f..f59f4921b 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 212231310..eecb41e33 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 9492f1cf1..bf95cb37a 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 2b2756187..c63324397 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 ab36ff4e6..8bbdc045c 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 cf5f956f3..482cc5b47 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 169a63698..edb699837 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 dbc697b06..654bd3248 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 779c1662e..acaef0d63 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 5874aba64..4ed5eba27 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 2eb6f6c40..764395f61 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 7b7648834..041d6a2da 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 84d81488d..e56b1c109 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 7b3c9e789..d20b585a5 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, &sect_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, &sections[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 3fd7f81a4..a9d1b7c58 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 4cdcda0c1..00be9dd4e 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 2f11b0cab..f3cca8c97 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 049e3a349..2271c9d10 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 bd0d15618..6654cd6fa 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 7ecc401bd..75cf45c06 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 c8b7f2ddc..43b6fdc11 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;