Updated libtiff from 4.1.0 to 4.2.0.
Overwrite existing files with same files from the new release. Then try
to apply patches one by one in order.
- Part of 0017-safe_skews_in_gtTileContig.patch has been removed because
upstream has code to partially deal with the issues in the function.
- Not upgrading to 4.3.0 to quickly pick up fixes without having to deal
with more patches not applying.
Change-Id: Ief38124673546e1747537da9db988d7786c90475
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/85374
Reviewed-by: Daniel Hosseinian <dhoss@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/third_party/libtiff/0017-safe_skews_in_gtTileContig.patch b/third_party/libtiff/0017-safe_skews_in_gtTileContig.patch
index b27bab5..61c4624 100644
--- a/third_party/libtiff/0017-safe_skews_in_gtTileContig.patch
+++ b/third_party/libtiff/0017-safe_skews_in_gtTileContig.patch
@@ -2,14 +2,6 @@
index fc554ccab..fff3f7fde 100644
--- a/third_party/libtiff/tif_getimage.c
+++ b/third_party/libtiff/tif_getimage.c
-@@ -31,6 +31,7 @@
- */
- #include "tiffiop.h"
- #include <stdio.h>
-+#include <limits.h>
-
- static int gtTileContig(TIFFRGBAImage*, uint32*, uint32, uint32);
- static int gtTileSeparate(TIFFRGBAImage*, uint32*, uint32, uint32);
@@ -628,6 +629,7 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
uint32 tw, th;
unsigned char* buf = NULL;
@@ -18,47 +10,6 @@
uint32 nrow;
int ret = 1, flip;
uint32 this_tw, tocol;
-@@ -648,19 +650,37 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
- flip = setorientation(img);
- if (flip & FLIP_VERTICALLY) {
- y = h - 1;
-- toskew = -(int32)(tw + w);
-+ safeskew = 0;
-+ safeskew -= tw;
-+ safeskew -= w;
- }
- else {
- y = 0;
-- toskew = -(int32)(tw - w);
-+ safeskew = 0;
-+ safeskew -= tw;
-+ safeskew +=w;
- }
-
-+ if(safeskew > INT_MAX || safeskew < INT_MIN){
-+ _TIFFfree(buf);
-+ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "Invalid skew");
-+ return (0);
-+ }
-+ toskew = safeskew;
-+
- /*
- * Leftmost tile is clipped on left side if col_offset > 0.
- */
- leftmost_fromskew = img->col_offset % tw;
- leftmost_tw = tw - leftmost_fromskew;
-- leftmost_toskew = toskew + leftmost_fromskew;
-+ safeskew = toskew;
-+ safeskew += leftmost_fromskew;
-+ if(safeskew > INT_MAX || safeskew < INT_MIN){
-+ _TIFFfree(buf);
-+ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "Invalid skew");
-+ return (0);
-+ }
-+ leftmost_toskew = safeskew;
- for (row = 0; ret != 0 && row < h; row += nrow)
- {
- rowstoread = th - (row + img->row_offset) % th;
@@ -686,9 +706,24 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
/*
* Rightmost tile is clipped on right side.
diff --git a/third_party/libtiff/README.pdfium b/third_party/libtiff/README.pdfium
index c5b6c87..bcde8e9 100644
--- a/third_party/libtiff/README.pdfium
+++ b/third_party/libtiff/README.pdfium
@@ -1,6 +1,6 @@
Name: LibTIFF
URL: http://www.simplesystems.org/libtiff/
-Version: 4.1.0
+Version: 4.2.0
Security Critical: yes
License: BSD
diff --git a/third_party/libtiff/tif_aux.c b/third_party/libtiff/tif_aux.c
index 8188db5..c9f1905 100644
--- a/third_party/libtiff/tif_aux.c
+++ b/third_party/libtiff/tif_aux.c
@@ -270,7 +270,7 @@
return (1);
case TIFFTAG_EXTRASAMPLES:
*va_arg(ap, uint16 *) = td->td_extrasamples;
- *va_arg(ap, uint16 **) = td->td_sampleinfo;
+ *va_arg(ap, const uint16 **) = td->td_sampleinfo;
return (1);
case TIFFTAG_MATTEING:
*va_arg(ap, uint16 *) =
@@ -292,8 +292,8 @@
case TIFFTAG_YCBCRCOEFFICIENTS:
{
/* defaults are from CCIR Recommendation 601-1 */
- static float ycbcrcoeffs[] = { 0.299f, 0.587f, 0.114f };
- *va_arg(ap, float **) = ycbcrcoeffs;
+ static const float ycbcrcoeffs[] = { 0.299f, 0.587f, 0.114f };
+ *va_arg(ap, const float **) = ycbcrcoeffs;
return 1;
}
case TIFFTAG_YCBCRSUBSAMPLING:
@@ -305,14 +305,14 @@
return (1);
case TIFFTAG_WHITEPOINT:
{
- static float whitepoint[2];
-
/* TIFF 6.0 specification tells that it is no default
value for the WhitePoint, but AdobePhotoshop TIFF
Technical Note tells that it should be CIE D50. */
- whitepoint[0] = D50_X0 / (D50_X0 + D50_Y0 + D50_Z0);
- whitepoint[1] = D50_Y0 / (D50_X0 + D50_Y0 + D50_Z0);
- *va_arg(ap, float **) = whitepoint;
+ static const float whitepoint[] = {
+ D50_X0 / (D50_X0 + D50_Y0 + D50_Z0),
+ D50_Y0 / (D50_X0 + D50_Y0 + D50_Z0)
+ };
+ *va_arg(ap, const float **) = whitepoint;
return 1;
}
case TIFFTAG_TRANSFERFUNCTION:
@@ -321,16 +321,16 @@
TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "No space for \"TransferFunction\" tag");
return (0);
}
- *va_arg(ap, uint16 **) = td->td_transferfunction[0];
+ *va_arg(ap, const uint16 **) = td->td_transferfunction[0];
if (td->td_samplesperpixel - td->td_extrasamples > 1) {
- *va_arg(ap, uint16 **) = td->td_transferfunction[1];
- *va_arg(ap, uint16 **) = td->td_transferfunction[2];
+ *va_arg(ap, const uint16 **) = td->td_transferfunction[1];
+ *va_arg(ap, const uint16 **) = td->td_transferfunction[2];
}
return (1);
case TIFFTAG_REFERENCEBLACKWHITE:
if (!td->td_refblackwhite && !TIFFDefaultRefBlackWhite(td))
return (0);
- *va_arg(ap, float **) = td->td_refblackwhite;
+ *va_arg(ap, const float **) = td->td_refblackwhite;
return (1);
}
return 0;
diff --git a/third_party/libtiff/tif_compress.c b/third_party/libtiff/tif_compress.c
index 8130ef0..915478f 100644
--- a/third_party/libtiff/tif_compress.c
+++ b/third_party/libtiff/tif_compress.c
@@ -264,7 +264,7 @@
return NULL;
}
codecs = new_codecs;
- _TIFFmemcpy(codecs + i - 1, cd, sizeof(TIFFCodec));
+ _TIFFmemcpy(codecs + i - 1, cd->info, sizeof(TIFFCodec));
i++;
}
for (c = _TIFFBuiltinCODECS; c->name; c++) {
diff --git a/third_party/libtiff/tif_dir.c b/third_party/libtiff/tif_dir.c
index 1e0a76c..347b711 100644
--- a/third_party/libtiff/tif_dir.c
+++ b/third_party/libtiff/tif_dir.c
@@ -29,6 +29,7 @@
* (and also some miscellaneous stuff)
*/
#include "tiffiop.h"
+#include <float.h> /*--: for Rational2Double */
/*
* These are used in the backwards compatibility code...
@@ -123,7 +124,7 @@
{
TIFFWarningExt(tif->tif_clientdata,module,
"ExtraSamples tag value is changing, "
- "but TransferFunction was read with a different value. Cancelling it");
+ "but TransferFunction was read with a different value. Canceling it");
TIFFClrFieldBit(tif,FIELD_TRANSFERFUNCTION);
_TIFFfree(td->td_transferfunction[0]);
td->td_transferfunction[0] = NULL;
@@ -205,7 +206,7 @@
/*
* If the data require post-decoding processing to byte-swap
* samples, set it up here. Note that since tags are required
- * to be ordered, compression code can override this behaviour
+ * to be ordered, compression code can override this behavior
* in the setup method if it wants to roll the post decoding
* work in with its normal work.
*/
@@ -275,7 +276,7 @@
{
TIFFWarningExt(tif->tif_clientdata,module,
"SamplesPerPixel tag value is changing, "
- "but SMinSampleValue tag was read with a different value. Cancelling it");
+ "but SMinSampleValue tag was read with a different value. Canceling it");
TIFFClrFieldBit(tif,FIELD_SMINSAMPLEVALUE);
_TIFFfree(td->td_sminsamplevalue);
td->td_sminsamplevalue = NULL;
@@ -284,7 +285,7 @@
{
TIFFWarningExt(tif->tif_clientdata,module,
"SamplesPerPixel tag value is changing, "
- "but SMaxSampleValue tag was read with a different value. Cancelling it");
+ "but SMaxSampleValue tag was read with a different value. Canceling it");
TIFFClrFieldBit(tif,FIELD_SMAXSAMPLEVALUE);
_TIFFfree(td->td_smaxsamplevalue);
td->td_smaxsamplevalue = NULL;
@@ -296,7 +297,7 @@
{
TIFFWarningExt(tif->tif_clientdata,module,
"SamplesPerPixel tag value is changing, "
- "but TransferFunction was read with a different value. Cancelling it");
+ "but TransferFunction was read with a different value. Canceling it");
TIFFClrFieldBit(tif,FIELD_TRANSFERFUNCTION);
_TIFFfree(td->td_transferfunction[0]);
td->td_transferfunction[0] = NULL;
@@ -393,7 +394,7 @@
if (tif->tif_mode != O_RDONLY)
goto badvalue32;
TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
- "Nonstandard tile width %d, convert file", v32);
+ "Nonstandard tile width %u, convert file", v32);
}
td->td_tilewidth = v32;
tif->tif_flags |= TIFF_ISTILED;
@@ -404,7 +405,7 @@
if (tif->tif_mode != O_RDONLY)
goto badvalue32;
TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
- "Nonstandard tile length %d, convert file", v32);
+ "Nonstandard tile length %u, convert file", v32);
}
td->td_tilelength = v32;
tif->tif_flags |= TIFF_ISTILED;
@@ -559,6 +560,10 @@
* Set custom value ... save a copy of the custom tag value.
*/
tv_size = _TIFFDataSize(fip->field_type);
+ /*--: Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size. */
+ if (fip->field_type == TIFF_RATIONAL || fip->field_type == TIFF_SRATIONAL) {
+ tv_size = _TIFFSetGetFieldSize(fip->set_field_type);
+ }
if (tv_size == 0) {
status = 0;
TIFFErrorExt(tif->tif_clientdata, module,
@@ -638,6 +643,7 @@
|| fip->field_writecount == TIFF_VARIABLE2
|| fip->field_writecount == TIFF_SPP
|| tv->count > 1) {
+ /*--: Rational2Double: For Rationals tv_size is set above to 4 or 8 according to fip->set_field_type! */
_TIFFmemcpy(tv->value, va_arg(ap, void *),
tv->count * tv_size);
} else {
@@ -698,6 +704,22 @@
break;
case TIFF_RATIONAL:
case TIFF_SRATIONAL:
+ /*-- Rational2Double: For Rationals tv_size is set above to 4 or 8 according to fip->set_field_type! */
+ {
+ if (tv_size == 8) {
+ double v2 = va_arg(ap, double);
+ _TIFFmemcpy(val, &v2, tv_size);
+ } else {
+ /*-- default should be tv_size == 4 */
+ float v3 = (float)va_arg(ap, double);
+ _TIFFmemcpy(val, &v3, tv_size);
+ /*-- ToDo: After Testing, this should be removed and tv_size==4 should be set as default. */
+ if (tv_size != 4) {
+ TIFFErrorExt(0,"TIFFLib: _TIFFVSetField()", "Rational2Double: .set_field_type in not 4 but %d", tv_size);
+ }
+ }
+ }
+ break;
case TIFF_FLOAT:
{
float v2 = _TIFFClampDoubleToFloat(va_arg(ap, double));
@@ -1011,19 +1033,19 @@
*va_arg(ap, uint16*) = td->td_halftonehints[1];
break;
case TIFFTAG_COLORMAP:
- *va_arg(ap, uint16**) = td->td_colormap[0];
- *va_arg(ap, uint16**) = td->td_colormap[1];
- *va_arg(ap, uint16**) = td->td_colormap[2];
+ *va_arg(ap, const uint16**) = td->td_colormap[0];
+ *va_arg(ap, const uint16**) = td->td_colormap[1];
+ *va_arg(ap, const uint16**) = td->td_colormap[2];
break;
case TIFFTAG_STRIPOFFSETS:
case TIFFTAG_TILEOFFSETS:
_TIFFFillStriles( tif );
- *va_arg(ap, uint64**) = td->td_stripoffset_p;
+ *va_arg(ap, const uint64**) = td->td_stripoffset_p;
break;
case TIFFTAG_STRIPBYTECOUNTS:
case TIFFTAG_TILEBYTECOUNTS:
_TIFFFillStriles( tif );
- *va_arg(ap, uint64**) = td->td_stripbytecount_p;
+ *va_arg(ap, const uint64**) = td->td_stripbytecount_p;
break;
case TIFFTAG_MATTEING:
*va_arg(ap, uint16*) =
@@ -1032,7 +1054,7 @@
break;
case TIFFTAG_EXTRASAMPLES:
*va_arg(ap, uint16*) = td->td_extrasamples;
- *va_arg(ap, uint16**) = td->td_sampleinfo;
+ *va_arg(ap, const uint16**) = td->td_sampleinfo;
break;
case TIFFTAG_TILEWIDTH:
*va_arg(ap, uint32*) = td->td_tilewidth;
@@ -1067,7 +1089,7 @@
break;
case TIFFTAG_SUBIFD:
*va_arg(ap, uint16*) = td->td_nsubifd;
- *va_arg(ap, uint64**) = td->td_subifd;
+ *va_arg(ap, const uint64**) = td->td_subifd;
break;
case TIFFTAG_YCBCRPOSITIONING:
*va_arg(ap, uint16*) = td->td_ycbcrpositioning;
@@ -1077,20 +1099,20 @@
*va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1];
break;
case TIFFTAG_TRANSFERFUNCTION:
- *va_arg(ap, uint16**) = td->td_transferfunction[0];
+ *va_arg(ap, const uint16**) = td->td_transferfunction[0];
if (td->td_samplesperpixel - td->td_extrasamples > 1) {
- *va_arg(ap, uint16**) = td->td_transferfunction[1];
- *va_arg(ap, uint16**) = td->td_transferfunction[2];
+ *va_arg(ap, const uint16**) = td->td_transferfunction[1];
+ *va_arg(ap, const uint16**) = td->td_transferfunction[2];
} else {
- *va_arg(ap, uint16**) = NULL;
- *va_arg(ap, uint16**) = NULL;
+ *va_arg(ap, const uint16**) = NULL;
+ *va_arg(ap, const uint16**) = NULL;
}
break;
case TIFFTAG_REFERENCEBLACKWHITE:
- *va_arg(ap, float**) = td->td_refblackwhite;
+ *va_arg(ap, const float**) = td->td_refblackwhite;
break;
case TIFFTAG_INKNAMES:
- *va_arg(ap, char**) = td->td_inknames;
+ *va_arg(ap, const char**) = td->td_inknames;
break;
default:
{
@@ -1132,7 +1154,7 @@
*va_arg(ap, uint32*) = (uint32)tv->count;
else /* Assume TIFF_VARIABLE */
*va_arg(ap, uint16*) = (uint16)tv->count;
- *va_arg(ap, void **) = tv->value;
+ *va_arg(ap, const void **) = tv->value;
ret_val = 1;
} else if (fip->field_tag == TIFFTAG_DOTRANGE
&& strcmp(fip->field_name,"DotRange") == 0) {
@@ -1200,6 +1222,23 @@
break;
case TIFF_RATIONAL:
case TIFF_SRATIONAL:
+ {
+ /*-- Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size and return value size. */
+ int tv_size = _TIFFSetGetFieldSize(fip->set_field_type);
+ if (tv_size == 8) {
+ *va_arg(ap, double*) = *(double *)val;
+ ret_val = 1;
+ } else {
+ /*-- default should be tv_size == 4 */
+ *va_arg(ap, float*) = *(float *)val;
+ ret_val = 1;
+ /*-- ToDo: After Testing, this should be removed and tv_size==4 should be set as default. */
+ if (tv_size != 4) {
+ TIFFErrorExt(0,"TIFFLib: _TIFFVGetField()", "Rational2Double: .set_field_type in not 4 but %d", tv_size);
+ }
+ }
+ }
+ break;
case TIFF_FLOAT:
*va_arg(ap, float*) =
*(float *)val;
@@ -1365,6 +1404,17 @@
}
/*
+ * Creates the EXIF GPS custom directory
+ */
+int
+TIFFCreateGPSDirectory(TIFF* tif)
+{
+ const TIFFFieldArray* gpsFieldArray;
+ gpsFieldArray = _TIFFGetGpsFields();
+ return TIFFCreateCustomDirectory(tif, gpsFieldArray);
+}
+
+/*
* Setup a default directory structure.
*/
int
diff --git a/third_party/libtiff/tif_dir.h b/third_party/libtiff/tif_dir.h
index e7f0667..f608dd7 100644
--- a/third_party/libtiff/tif_dir.h
+++ b/third_party/libtiff/tif_dir.h
@@ -261,6 +261,7 @@
extern const TIFFFieldArray* _TIFFGetFields(void);
extern const TIFFFieldArray* _TIFFGetExifFields(void);
+extern const TIFFFieldArray* _TIFFGetGpsFields(void);
extern void _TIFFSetupFields(TIFF* tif, const TIFFFieldArray* infoarray);
extern void _TIFFPrintFieldInfo(TIFF*, FILE*);
@@ -269,6 +270,7 @@
typedef enum {
tfiatImage,
tfiatExif,
+ tfiatGps, /* EXIF-GPS fields array type */
tfiatOther
} TIFFFieldArrayType;
diff --git a/third_party/libtiff/tif_dirinfo.c b/third_party/libtiff/tif_dirinfo.c
index e1f6b23..7217042 100644
--- a/third_party/libtiff/tif_dirinfo.c
+++ b/third_party/libtiff/tif_dirinfo.c
@@ -47,9 +47,19 @@
#endif
static const TIFFFieldArray tiffFieldArray;
static const TIFFFieldArray exifFieldArray;
+static const TIFFFieldArray gpsFieldArray;
#ifdef _MSC_VER
#pragma warning( pop )
#endif
+/*--: Rational2Double: --
+ * The Rational2Double upgraded libtiff functionality allows the definition and achievement of true double-precision accuracy
+ * for TIFF tags of RATIONAL type and field_bit=FIELD_CUSTOM using the set_field_type = TIFF_SETGET_DOUBLE.
+ * Unfortunately, that changes the old implemented interface for TIFFGetField().
+ * In order to keep the old TIFFGetField() interface behavior those tags have to be redefined with set_field_type = TIFF_SETGET_FLOAT!
+ *
+ * Rational custom arrays are already defined as _Cxx_FLOAT, thus can stay.
+ *
+ */
static const TIFFField
tiffFields[] = {
@@ -75,12 +85,12 @@
{ TIFFTAG_STRIPBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "StripByteCounts", NULL },
{ TIFFTAG_MINSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_MINSAMPLEVALUE, 1, 0, "MinSampleValue", NULL },
{ TIFFTAG_MAXSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_MAXSAMPLEVALUE, 1, 0, "MaxSampleValue", NULL },
- { TIFFTAG_XRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "XResolution", NULL },
- { TIFFTAG_YRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "YResolution", NULL },
+ { TIFFTAG_XRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "XResolution", NULL },
+ { TIFFTAG_YRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "YResolution", NULL },
{ TIFFTAG_PLANARCONFIG, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_PLANARCONFIG, 0, 0, "PlanarConfiguration", NULL },
{ TIFFTAG_PAGENAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PageName", NULL },
- { TIFFTAG_XPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "XPosition", NULL },
- { TIFFTAG_YPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "YPosition", NULL },
+ { TIFFTAG_XPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "XPosition", NULL },
+ { TIFFTAG_YPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "YPosition", NULL },
{ TIFFTAG_FREEOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeOffsets", NULL },
{ TIFFTAG_FREEBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeByteCounts", NULL },
{ TIFFTAG_GRAYRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseUnit", NULL },
@@ -135,14 +145,18 @@
{ TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToScreen", NULL },
{ TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToCamera", NULL },
{ TIFFTAG_CFAREPEATPATTERNDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CFARepeatPatternDim", NULL },
- { TIFFTAG_CFAPATTERN, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CFAPattern" , NULL},
+ { TIFFTAG_CFAPATTERN, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CFAPattern" , NULL},
{ TIFFTAG_COPYRIGHT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Copyright", NULL },
/* end Pixar tags */
- { TIFFTAG_RICHTIFFIPTC, -3, -3, TIFF_LONG, 0, TIFF_SETGET_C32_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "RichTIFFIPTC", NULL },
+ { TIFFTAG_RICHTIFFIPTC, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "RichTIFFIPTC", NULL },
{ TIFFTAG_PHOTOSHOP, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "Photoshop", NULL },
- { TIFFTAG_EXIFIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "EXIFIFDOffset", (TIFFFieldArray*) &exifFieldArray },
+ /*--: EXIFIFD and GPSIFD specified as TIFF_LONG by Aware-Systems and not TIFF_IFD8 as in original LibTiff.
+ * However, for IFD-like tags, libtiff uses the data type TIFF_IFD8 in tiffFields[]-tag definition combined with
+ * a special handling procedure in order to write either a 32-bit value and the TIFF_IFD type-id into ClassicTIFF files
+ * or a 64-bit value and the TIFF_IFD8 type-id into BigTIFF files. */
+ { TIFFTAG_EXIFIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EXIFIFDOffset", (TIFFFieldArray*) &exifFieldArray },
{ TIFFTAG_ICCPROFILE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ICC Profile", NULL },
- { TIFFTAG_GPSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "GPSIFDOffset", NULL },
+ { TIFFTAG_GPSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GPSIFDOffset", (TIFFFieldArray*) &gpsFieldArray },
{ TIFFTAG_FAXRECVPARAMS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvParams", NULL },
{ TIFFTAG_FAXSUBADDRESS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxSubAddress", NULL },
{ TIFFTAG_FAXRECVTIME, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvTime", NULL },
@@ -163,7 +177,7 @@
{ TIFFTAG_BLACKLEVELDELTAV, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "BlackLevelDeltaV", NULL },
{ TIFFTAG_WHITELEVEL, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "WhiteLevel", NULL },
{ TIFFTAG_DEFAULTSCALE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultScale", NULL },
- { TIFFTAG_BESTQUALITYSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BestQualityScale", NULL },
+ { TIFFTAG_BESTQUALITYSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BestQualityScale", NULL },
{ TIFFTAG_DEFAULTCROPORIGIN, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultCropOrigin", NULL },
{ TIFFTAG_DEFAULTCROPSIZE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultCropSize", NULL },
{ TIFFTAG_COLORMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ColorMatrix1", NULL },
@@ -175,16 +189,16 @@
{ TIFFTAG_ANALOGBALANCE, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AnalogBalance", NULL },
{ TIFFTAG_ASSHOTNEUTRAL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotNeutral", NULL },
{ TIFFTAG_ASSHOTWHITEXY, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "AsShotWhiteXY", NULL },
- { TIFFTAG_BASELINEEXPOSURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineExposure", NULL },
- { TIFFTAG_BASELINENOISE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineNoise", NULL },
- { TIFFTAG_BASELINESHARPNESS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineSharpness", NULL },
+ { TIFFTAG_BASELINEEXPOSURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineExposure", NULL },
+ { TIFFTAG_BASELINENOISE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineNoise", NULL },
+ { TIFFTAG_BASELINESHARPNESS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineSharpness", NULL },
{ TIFFTAG_BAYERGREENSPLIT, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BayerGreenSplit", NULL },
- { TIFFTAG_LINEARRESPONSELIMIT, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "LinearResponseLimit", NULL },
+ { TIFFTAG_LINEARRESPONSELIMIT, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "LinearResponseLimit", NULL },
{ TIFFTAG_CAMERASERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraSerialNumber", NULL },
{ TIFFTAG_LENSINFO, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "LensInfo", NULL },
- { TIFFTAG_CHROMABLURRADIUS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ChromaBlurRadius", NULL },
- { TIFFTAG_ANTIALIASSTRENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "AntiAliasStrength", NULL },
- { TIFFTAG_SHADOWSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ShadowScale", NULL },
+ { TIFFTAG_CHROMABLURRADIUS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ChromaBlurRadius", NULL },
+ { TIFFTAG_ANTIALIASSTRENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "AntiAliasStrength", NULL },
+ { TIFFTAG_SHADOWSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ShadowScale", NULL },
{ TIFFTAG_DNGPRIVATEDATA, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "DNGPrivateData", NULL },
{ TIFFTAG_MAKERNOTESAFETY, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "MakerNoteSafety", NULL },
{ TIFFTAG_CALIBRATIONILLUMINANT1, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CalibrationIlluminant1", NULL },
@@ -217,47 +231,68 @@
/* begin pseudo tags */
};
+/*
+ * EXIF tags (Version 2.31, July 2016 plus version 2.32 May 2019)
+ */
static const TIFFField
exifFields[] = {
- { EXIFTAG_EXPOSURETIME, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureTime", NULL },
- { EXIFTAG_FNUMBER, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FNumber", NULL },
+ { EXIFTAG_EXPOSURETIME, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureTime", NULL },
+ { EXIFTAG_FNUMBER, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FNumber", NULL },
{ EXIFTAG_EXPOSUREPROGRAM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureProgram", NULL },
{ EXIFTAG_SPECTRALSENSITIVITY, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SpectralSensitivity", NULL },
{ EXIFTAG_ISOSPEEDRATINGS, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ISOSpeedRatings", NULL },
{ EXIFTAG_OECF, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OptoelectricConversionFactor", NULL },
+ { EXIFTAG_SENSITIVITYTYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SensitivityType", NULL },
+ { EXIFTAG_STANDARDOUTPUTSENSITIVITY, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "StandardOutputSensitivity", NULL },
+ { EXIFTAG_RECOMMENDEDEXPOSUREINDEX, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RecommendedExposureIndex", NULL },
+ { EXIFTAG_ISOSPEED, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeed", NULL },
+ { EXIFTAG_ISOSPEEDLATITUDEYYY, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeedLatitudeyyy", NULL },
+ { EXIFTAG_ISOSPEEDLATITUDEZZZ, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeedLatitudezzz", NULL },
{ EXIFTAG_EXIFVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExifVersion", NULL },
{ EXIFTAG_DATETIMEORIGINAL, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeOriginal", NULL },
{ EXIFTAG_DATETIMEDIGITIZED, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeDigitized", NULL },
+ { EXIFTAG_OFFSETTIME, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTime", NULL },
+ { EXIFTAG_OFFSETTIMEORIGINAL, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTimeOriginal", NULL },
+ { EXIFTAG_OFFSETTIMEDIGITIZED, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTimeDigitized", NULL },
{ EXIFTAG_COMPONENTSCONFIGURATION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ComponentsConfiguration", NULL },
- { EXIFTAG_COMPRESSEDBITSPERPIXEL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CompressedBitsPerPixel", NULL },
- { EXIFTAG_SHUTTERSPEEDVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ShutterSpeedValue", NULL },
- { EXIFTAG_APERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ApertureValue", NULL },
- { EXIFTAG_BRIGHTNESSVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BrightnessValue", NULL },
- { EXIFTAG_EXPOSUREBIASVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureBiasValue", NULL },
- { EXIFTAG_MAXAPERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MaxApertureValue", NULL },
- { EXIFTAG_SUBJECTDISTANCE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistance", NULL },
+ { EXIFTAG_COMPRESSEDBITSPERPIXEL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CompressedBitsPerPixel", NULL },
+ { EXIFTAG_SHUTTERSPEEDVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ShutterSpeedValue", NULL },
+ { EXIFTAG_APERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ApertureValue", NULL },
+ { EXIFTAG_BRIGHTNESSVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BrightnessValue", NULL },
+ { EXIFTAG_EXPOSUREBIASVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureBiasValue", NULL },
+ { EXIFTAG_MAXAPERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MaxApertureValue", NULL },
+ /*--: EXIFTAG_SUBJECTDISTANCE: LibTiff returns value of "-1" if numerator equals 4294967295 (0xFFFFFFFF) to indicate infinite distance!
+ * However, there are two other EXIF tags where numerator indicates a special value and six other cases where the denominator indicates special values,
+ * which are not treated within LibTiff!! */
+ { EXIFTAG_SUBJECTDISTANCE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistance", NULL },
{ EXIFTAG_METERINGMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MeteringMode", NULL },
{ EXIFTAG_LIGHTSOURCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LightSource", NULL },
{ EXIFTAG_FLASH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Flash", NULL },
- { EXIFTAG_FOCALLENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLength", NULL },
+ { EXIFTAG_FOCALLENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLength", NULL },
{ EXIFTAG_SUBJECTAREA, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SubjectArea", NULL },
{ EXIFTAG_MAKERNOTE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "MakerNote", NULL },
{ EXIFTAG_USERCOMMENT, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "UserComment", NULL },
{ EXIFTAG_SUBSECTIME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTime", NULL },
{ EXIFTAG_SUBSECTIMEORIGINAL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeOriginal", NULL },
{ EXIFTAG_SUBSECTIMEDIGITIZED, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeDigitized", NULL },
+ { EXIFTAG_TEMPERATURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Temperature", NULL },
+ { EXIFTAG_HUMIDITY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Humidity", NULL },
+ { EXIFTAG_PRESSURE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Pressure", NULL },
+ { EXIFTAG_WATERDEPTH, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WaterDepth", NULL },
+ { EXIFTAG_ACCELERATION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Acceleration", NULL },
+ { EXIFTAG_CAMERAELEVATIONANGLE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraElevationAngle", NULL },
{ EXIFTAG_FLASHPIXVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashpixVersion", NULL },
{ EXIFTAG_COLORSPACE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ColorSpace", NULL },
{ EXIFTAG_PIXELXDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelXDimension", NULL },
{ EXIFTAG_PIXELYDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelYDimension", NULL },
{ EXIFTAG_RELATEDSOUNDFILE, 13, 13, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RelatedSoundFile", NULL },
- { EXIFTAG_FLASHENERGY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashEnergy", NULL },
+ { EXIFTAG_FLASHENERGY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashEnergy", NULL },
{ EXIFTAG_SPATIALFREQUENCYRESPONSE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SpatialFrequencyResponse", NULL },
- { EXIFTAG_FOCALPLANEXRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneXResolution", NULL },
- { EXIFTAG_FOCALPLANEYRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneYResolution", NULL },
+ { EXIFTAG_FOCALPLANEXRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneXResolution", NULL },
+ { EXIFTAG_FOCALPLANEYRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneYResolution", NULL },
{ EXIFTAG_FOCALPLANERESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneResolutionUnit", NULL },
{ EXIFTAG_SUBJECTLOCATION, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectLocation", NULL },
- { EXIFTAG_EXPOSUREINDEX, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureIndex", NULL },
+ { EXIFTAG_EXPOSUREINDEX, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureIndex", NULL },
{ EXIFTAG_SENSINGMETHOD, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SensingMethod", NULL },
{ EXIFTAG_FILESOURCE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FileSource", NULL },
{ EXIFTAG_SCENETYPE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneType", NULL },
@@ -265,22 +300,79 @@
{ EXIFTAG_CUSTOMRENDERED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CustomRendered", NULL },
{ EXIFTAG_EXPOSUREMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureMode", NULL },
{ EXIFTAG_WHITEBALANCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhiteBalance", NULL },
- { EXIFTAG_DIGITALZOOMRATIO, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DigitalZoomRatio", NULL },
+ { EXIFTAG_DIGITALZOOMRATIO, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DigitalZoomRatio", NULL },
{ EXIFTAG_FOCALLENGTHIN35MMFILM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLengthIn35mmFilm", NULL },
{ EXIFTAG_SCENECAPTURETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneCaptureType", NULL },
- { EXIFTAG_GAINCONTROL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GainControl", NULL },
+ { EXIFTAG_GAINCONTROL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GainControl", NULL },
{ EXIFTAG_CONTRAST, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Contrast", NULL },
{ EXIFTAG_SATURATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Saturation", NULL },
{ EXIFTAG_SHARPNESS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Sharpness", NULL },
{ EXIFTAG_DEVICESETTINGDESCRIPTION, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "DeviceSettingDescription", NULL },
{ EXIFTAG_SUBJECTDISTANCERANGE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistanceRange", NULL },
- { EXIFTAG_IMAGEUNIQUEID, 33, 33, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageUniqueID", NULL }
+ { EXIFTAG_IMAGEUNIQUEID, 33, 33, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageUniqueID", NULL },
+ { EXIFTAG_CAMERAOWNERNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraOwnerName", NULL },
+ { EXIFTAG_BODYSERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BodySerialNumber", NULL },
+ { EXIFTAG_LENSSPECIFICATION, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensSpecification", NULL },
+ { EXIFTAG_LENSMAKE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensMake", NULL },
+ { EXIFTAG_LENSMODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensModel", NULL },
+ { EXIFTAG_LENSSERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensSerialNumber", NULL },
+ { EXIFTAG_GAMMA, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Gamma", NULL },
+ { EXIFTAG_COMPOSITEIMAGE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CompositeImage", NULL },
+ { EXIFTAG_SOURCEIMAGENUMBEROFCOMPOSITEIMAGE, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SourceImageNumberOfCompositeImage", NULL },
+ { EXIFTAG_SOURCEEXPOSURETIMESOFCOMPOSITEIMAGE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SourceExposureTimesOfCompositeImage", NULL }
+};
+/*
+ * EXIF-GPS tags (Version 2.31, July 2016; nothing changed for version 2.32 May 2019)
+ */
+
+static TIFFField
+gpsFields[] = {
+ /* For the GPS tag definitions in gpsFields[] the standard definition for Rationals is TIFF_SETGET_DOUBLE and TIFF_SETGET_C0_FLOAT.
+ *-- ATTENTION: After the upgrade with Rational2Double, the GPSTAG values can now be written and also read in double precision!
+ * In order to achieve double precision for GPS tags:
+ * Standard definitions for GPSTAG is kept to TIFF_SETGET_DOUBLE
+ * and TIFF_SETGET_C0_FLOAT is changed to TIFF_SETGET_C0_DOUBLE.
+ */
+ { GPSTAG_VERSIONID , 4, 4, TIFF_BYTE , 0, TIFF_SETGET_C0_UINT8 , TIFF_SETGET_UINT8 , FIELD_CUSTOM , 1, 0, "VersionID", NULL },
+ { GPSTAG_LATITUDEREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "LatitudeRef", NULL },
+ { GPSTAG_LATITUDE , 3, 3, TIFF_RATIONAL , 0, TIFF_SETGET_C0_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Latitude", NULL },
+ { GPSTAG_LONGITUDEREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "LongitudeRef", NULL },
+ { GPSTAG_LONGITUDE , 3, 3, TIFF_RATIONAL , 0, TIFF_SETGET_C0_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Longitude", NULL },
+ { GPSTAG_ALTITUDEREF , 1, 1, TIFF_BYTE , 0, TIFF_SETGET_UINT8 , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "AltitudeRef", NULL },
+ { GPSTAG_ALTITUDE , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Altitude", NULL },
+ { GPSTAG_TIMESTAMP , 3, 3, TIFF_RATIONAL , 0, TIFF_SETGET_C0_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "TimeStamp", NULL },
+ { GPSTAG_SATELLITES , -1, -1, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Satellites", NULL },
+ { GPSTAG_STATUS , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Status", NULL },
+ { GPSTAG_MEASUREMODE , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "MeasureMode", NULL },
+ { GPSTAG_DOP , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DOP", NULL },
+ { GPSTAG_SPEEDREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "SpeedRef", NULL },
+ { GPSTAG_SPEED , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Speed", NULL },
+ { GPSTAG_TRACKREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "TrackRef", NULL },
+ { GPSTAG_TRACK , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Track", NULL },
+ { GPSTAG_IMGDIRECTIONREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "ImgDirectionRef", NULL },
+ { GPSTAG_IMGDIRECTION , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "ImgDirection", NULL },
+ { GPSTAG_MAPDATUM , -1, -1, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "MapDatum", NULL },
+ { GPSTAG_DESTLATITUDEREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestLatitudeRef", NULL },
+ { GPSTAG_DESTLATITUDE , 3, 3, TIFF_RATIONAL , 0, TIFF_SETGET_C0_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestLatitude", NULL },
+ { GPSTAG_DESTLONGITUDEREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestLongitudeRef", NULL },
+ { GPSTAG_DESTLONGITUDE , 3, 3, TIFF_RATIONAL , 0, TIFF_SETGET_C0_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestLongitude", NULL },
+ { GPSTAG_DESTBEARINGREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestBearingRef", NULL },
+ { GPSTAG_DESTBEARING , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestBearing", NULL },
+ { GPSTAG_DESTDISTANCEREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestDistanceRef", NULL },
+ { GPSTAG_DESTDISTANCE , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestDistance", NULL },
+ { GPSTAG_PROCESSINGMETHOD , -1, -1, TIFF_UNDEFINED , 0, TIFF_SETGET_C16_UINT8 , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 1, "ProcessingMethod", NULL },
+ { GPSTAG_AREAINFORMATION , -1, -1, TIFF_UNDEFINED , 0, TIFF_SETGET_C16_UINT8 , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 1, "AreaInformation", NULL },
+ { GPSTAG_DATESTAMP , 11, 11, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DateStamp", NULL },
+ { GPSTAG_DIFFERENTIAL , 1, 1, TIFF_SHORT , 0, TIFF_SETGET_UINT16 , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Differential", NULL },
+ { GPSTAG_GPSHPOSITIONINGERROR , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "HorizontalPositioningError", NULL }
};
static const TIFFFieldArray
tiffFieldArray = { tfiatImage, 0, TIFFArrayCount(tiffFields), (TIFFField*) tiffFields };
static const TIFFFieldArray
exifFieldArray = { tfiatExif, 0, TIFFArrayCount(exifFields), (TIFFField*) exifFields };
+static const TIFFFieldArray
+gpsFieldArray = { tfiatGps, 0, TIFFArrayCount(gpsFields), (TIFFField*) gpsFields };
/*
* We have our own local lfind() equivalent to avoid subtle differences
@@ -313,6 +405,12 @@
return(&exifFieldArray);
}
+const TIFFFieldArray*
+_TIFFGetGpsFields(void)
+{
+ return(&gpsFieldArray);
+}
+
void
_TIFFSetupFields(TIFF* tif, const TIFFFieldArray* fieldarray)
{
@@ -502,6 +600,82 @@
}
}
+/*
+ * Rational2Double:
+ * Return size of TIFFSetGetFieldType in bytes.
+ *
+ * XXX: TIFF_RATIONAL values for FIELD_CUSTOM are stored internally as 4-byte float.
+ * However, some of them should be stored internally as 8-byte double.
+ * This is now managed by the SetGetField of the tag-definition!
+ */
+int
+_TIFFSetGetFieldSize(TIFFSetGetFieldType setgettype)
+{
+ switch (setgettype)
+ {
+ case TIFF_SETGET_UNDEFINED:
+ case TIFF_SETGET_ASCII:
+ case TIFF_SETGET_C0_ASCII:
+ case TIFF_SETGET_C16_ASCII:
+ case TIFF_SETGET_C32_ASCII:
+ case TIFF_SETGET_OTHER:
+ return 0;
+ case TIFF_SETGET_UINT8:
+ case TIFF_SETGET_SINT8:
+ case TIFF_SETGET_C0_UINT8:
+ case TIFF_SETGET_C0_SINT8:
+ case TIFF_SETGET_C16_UINT8:
+ case TIFF_SETGET_C16_SINT8:
+ case TIFF_SETGET_C32_UINT8:
+ case TIFF_SETGET_C32_SINT8:
+ return 1;
+ case TIFF_SETGET_UINT16:
+ case TIFF_SETGET_SINT16:
+ case TIFF_SETGET_C0_UINT16:
+ case TIFF_SETGET_C0_SINT16:
+ case TIFF_SETGET_C16_UINT16:
+ case TIFF_SETGET_C16_SINT16:
+ case TIFF_SETGET_C32_UINT16:
+ case TIFF_SETGET_C32_SINT16:
+ return 2;
+ case TIFF_SETGET_INT:
+ case TIFF_SETGET_UINT32:
+ case TIFF_SETGET_SINT32:
+ case TIFF_SETGET_FLOAT:
+ case TIFF_SETGET_UINT16_PAIR:
+ case TIFF_SETGET_C0_UINT32:
+ case TIFF_SETGET_C0_SINT32:
+ case TIFF_SETGET_C0_FLOAT:
+ case TIFF_SETGET_C16_UINT32:
+ case TIFF_SETGET_C16_SINT32:
+ case TIFF_SETGET_C16_FLOAT:
+ case TIFF_SETGET_C32_UINT32:
+ case TIFF_SETGET_C32_SINT32:
+ case TIFF_SETGET_C32_FLOAT:
+ return 4;
+ case TIFF_SETGET_UINT64:
+ case TIFF_SETGET_SINT64:
+ case TIFF_SETGET_DOUBLE:
+ case TIFF_SETGET_IFD8:
+ case TIFF_SETGET_C0_UINT64:
+ case TIFF_SETGET_C0_SINT64:
+ case TIFF_SETGET_C0_DOUBLE:
+ case TIFF_SETGET_C0_IFD8:
+ case TIFF_SETGET_C16_UINT64:
+ case TIFF_SETGET_C16_SINT64:
+ case TIFF_SETGET_C16_DOUBLE:
+ case TIFF_SETGET_C16_IFD8:
+ case TIFF_SETGET_C32_UINT64:
+ case TIFF_SETGET_C32_SINT64:
+ case TIFF_SETGET_C32_DOUBLE:
+ case TIFF_SETGET_C32_IFD8:
+ return 8;
+ default:
+ return 0;
+ }
+} /*-- _TIFFSetGetFieldSize --- */
+
+
const TIFFField*
TIFFFindField(TIFF* tif, uint32 tag, TIFFDataType dt)
{
@@ -1062,10 +1236,6 @@
if (tag == TIFFTAG_LERC_PARAMETERS)
return 1;
break;
- case COMPRESSION_WEBP:
- if (tag == TIFFTAG_PREDICTOR)
- return 1;
- break;
}
return 0;
}
diff --git a/third_party/libtiff/tif_dirread.c b/third_party/libtiff/tif_dirread.c
index ceb166c..70611d0 100644
--- a/third_party/libtiff/tif_dirread.c
+++ b/third_party/libtiff/tif_dirread.c
@@ -640,7 +640,7 @@
err=TIFFReadDirEntryCheckedDouble(tif,direntry,&m);
if (err!=TIFFReadDirEntryErrOk)
return(err);
- if ((m > FLT_MAX) || (m < FLT_MIN))
+ if ((m > FLT_MAX) || (m < -FLT_MAX))
return(TIFFReadDirEntryErrRange);
*value=(float)m;
return(TIFFReadDirEntryErrOk);
@@ -839,6 +839,7 @@
uint32 datasize;
void* data;
uint64 target_count64;
+ int original_datasize_clamped;
typesize=TIFFDataWidth(direntry->tdir_type);
target_count64 = (direntry->tdir_count > maxcount) ?
@@ -851,6 +852,12 @@
}
(void) desttypesize;
+ /* We just want to know if the original tag size is more than 4 bytes
+ * (classic TIFF) or 8 bytes (BigTIFF)
+ */
+ original_datasize_clamped =
+ ((direntry->tdir_count > 10) ? 10 : (int)direntry->tdir_count) * typesize;
+
/*
* As a sanity check, make sure we have no more than a 2GB tag array
* in either the current data type or the dest data type. This also
@@ -865,7 +872,7 @@
datasize=(*count)*typesize;
assert((tmsize_t)datasize>0);
- if( isMapped(tif) && datasize > (uint32)tif->tif_size )
+ if( isMapped(tif) && datasize > (uint64)tif->tif_size )
return TIFFReadDirEntryErrIo;
if( !isMapped(tif) &&
@@ -882,7 +889,7 @@
}
if (!(tif->tif_flags&TIFF_BIGTIFF))
{
- if (datasize<=4)
+ if (original_datasize_clamped<=4)
_TIFFmemcpy(data,&direntry->tdir_offset,datasize);
else
{
@@ -903,7 +910,7 @@
}
else
{
- if (datasize<=8)
+ if (original_datasize_clamped<=8)
_TIFFmemcpy(data,&direntry->tdir_offset,datasize);
else
{
@@ -3401,7 +3408,7 @@
return TIFFReadDirEntryErrIo;
}
mb=ma+size;
- if (mb > (size_t)tif->tif_size)
+ if (mb > (uint64)tif->tif_size)
return(TIFFReadDirEntryErrIo);
_TIFFmemcpy(dest,tif->tif_base+ma,size);
}
@@ -3910,11 +3917,51 @@
break;
case TIFFTAG_STRIPOFFSETS:
case TIFFTAG_TILEOFFSETS:
+ switch( dp->tdir_type )
+ {
+ case TIFF_SHORT:
+ case TIFF_LONG:
+ case TIFF_LONG8:
+ break;
+ default:
+ /* Warn except if directory typically created with TIFFDeferStrileArrayWriting() */
+ if( !(tif->tif_mode == O_RDWR &&
+ dp->tdir_count == 0 &&
+ dp->tdir_type == 0 &&
+ dp->tdir_offset.toff_long8 == 0) )
+ {
+ fip = TIFFFieldWithTag(tif,dp->tdir_tag);
+ TIFFWarningExt(tif->tif_clientdata,module,
+ "Invalid data type for tag %s",
+ fip ? fip->field_name : "unknown tagname");
+ }
+ break;
+ }
_TIFFmemcpy( &(tif->tif_dir.td_stripoffset_entry),
dp, sizeof(TIFFDirEntry) );
break;
case TIFFTAG_STRIPBYTECOUNTS:
case TIFFTAG_TILEBYTECOUNTS:
+ switch( dp->tdir_type )
+ {
+ case TIFF_SHORT:
+ case TIFF_LONG:
+ case TIFF_LONG8:
+ break;
+ default:
+ /* Warn except if directory typically created with TIFFDeferStrileArrayWriting() */
+ if( !(tif->tif_mode == O_RDWR &&
+ dp->tdir_count == 0 &&
+ dp->tdir_type == 0 &&
+ dp->tdir_offset.toff_long8 == 0) )
+ {
+ fip = TIFFFieldWithTag(tif,dp->tdir_tag);
+ TIFFWarningExt(tif->tif_clientdata,module,
+ "Invalid data type for tag %s",
+ fip ? fip->field_name : "unknown tagname");
+ }
+ break;
+ }
_TIFFmemcpy( &(tif->tif_dir.td_stripbytecount_entry),
dp, sizeof(TIFFDirEntry) );
break;
@@ -4409,6 +4456,7 @@
uint16 di;
const TIFFField* fip;
uint32 fii;
+ (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */
_TIFFSetupFields(tif, infoarray);
dircount=TIFFFetchDirectory(tif,diroff,&dir,NULL);
if (!dircount)
@@ -4513,6 +4561,17 @@
return TIFFReadCustomDirectory(tif, diroff, exifFieldArray);
}
+/*
+ *--: EXIF-GPS custom directory reading as another special case of custom IFD.
+ */
+int
+TIFFReadGPSDirectory(TIFF* tif, toff_t diroff)
+{
+ const TIFFFieldArray* gpsFieldArray;
+ gpsFieldArray = _TIFFGetGpsFields();
+ return TIFFReadCustomDirectory(tif, diroff, gpsFieldArray);
+}
+
static int
EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
{
@@ -5148,6 +5207,7 @@
if (err==TIFFReadDirEntryErrOk)
{
int m;
+ assert(data); /* avoid CLang static Analyzer false positive */
m=TIFFSetField(tif,dp->tdir_tag,data[0],data[1]);
_TIFFfree(data);
if (!m)
@@ -5231,7 +5291,7 @@
assert(fip->field_readcount>=1);
assert(fip->field_passcount==0);
if (dp->tdir_count!=(uint64)fip->field_readcount)
- /* corrupt file */;
+ /* corrupt file */;
else
{
err=TIFFReadDirEntryFloatArray(tif,dp,&data);
@@ -5247,6 +5307,29 @@
}
}
break;
+ /*--: Rational2Double: Extend for Double Arrays and Rational-Arrays read into Double-Arrays. */
+ case TIFF_SETGET_C0_DOUBLE:
+ {
+ double* data;
+ assert(fip->field_readcount>=1);
+ assert(fip->field_passcount==0);
+ if (dp->tdir_count!=(uint64)fip->field_readcount)
+ /* corrupt file */;
+ else
+ {
+ err=TIFFReadDirEntryDoubleArray(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m=TIFFSetField(tif,dp->tdir_tag,data);
+ if (data!=0)
+ _TIFFfree(data);
+ if (!m)
+ return(0);
+ }
+ }
+ }
+ break;
case TIFF_SETGET_C16_ASCII:
{
uint8* data;
@@ -6042,6 +6125,12 @@
{
sizeofval = sizeof(uint64);
}
+ else if( dirent->tdir_type == TIFF_SLONG8 )
+ {
+ /* Non conformant but used by some images as in */
+ /* https://github.com/OSGeo/gdal/issues/2165 */
+ sizeofval = sizeof(int64);
+ }
else
{
TIFFErrorExt(tif->tif_clientdata, module,
@@ -6114,7 +6203,7 @@
_TIFFUnsanitizedAddUInt64AndInt(nOffset, (i + 1) * sizeofvalint) <= nOffsetEndPage;
++i )
{
- if( sizeofval == sizeof(uint16) )
+ if( dirent->tdir_type == TIFF_SHORT )
{
uint16 val;
memcpy(&val,
@@ -6124,7 +6213,7 @@
TIFFSwabShort(&val);
panVals[strile + i] = val;
}
- else if( sizeofval == sizeof(uint32) )
+ else if( dirent->tdir_type == TIFF_LONG )
{
uint32 val;
memcpy(&val,
@@ -6134,7 +6223,7 @@
TIFFSwabLong(&val);
panVals[strile + i] = val;
}
- else
+ else if( dirent->tdir_type == TIFF_LONG8 )
{
uint64 val;
memcpy(&val,
@@ -6144,6 +6233,17 @@
TIFFSwabLong8(&val);
panVals[strile + i] = val;
}
+ else /* if( dirent->tdir_type == TIFF_SLONG8 ) */
+ {
+ /* Non conformant data type */
+ int64 val;
+ memcpy(&val,
+ buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
+ sizeof(val));
+ if( bSwab )
+ TIFFSwabLong8((uint64*) &val);
+ panVals[strile + i] = (uint64) val;
+ }
}
return 1;
}
@@ -6354,7 +6454,7 @@
if( td->td_stripoffset_p != NULL )
return 1;
- /* If tdir_count was cancelled, then we already got there, but in error */
+ /* If tdir_count was canceled, then we already got there, but in error */
if( td->td_stripoffset_entry.tdir_count == 0 )
return 0;
diff --git a/third_party/libtiff/tif_dirwrite.c b/third_party/libtiff/tif_dirwrite.c
index 9e4d306..f481250 100644
--- a/third_party/libtiff/tif_dirwrite.c
+++ b/third_party/libtiff/tif_dirwrite.c
@@ -28,6 +28,8 @@
* Directory Write Support Routines.
*/
#include "tiffiop.h"
+#include <float.h> /*--: for Rational2Double */
+#include <math.h> /*--: for Rational2Double */
#ifdef HAVE_IEEEFP
#define TIFFCvtNativeToIEEEFloat(tif, n, fp)
@@ -154,6 +156,19 @@
static int TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
+
+/*--: Rational2Double: New functions to support true double-precision for custom rational tag types. */
+static int TIFFWriteDirectoryTagRationalDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value);
+static int TIFFWriteDirectoryTagSrationalDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value);
+static int TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value);
+static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value);
+static void DoubleToRational(double value, uint32 *num, uint32 *denom);
+static void DoubleToSrational(double value, int32 *num, int32 *denom);
+#if 0
+static void DoubleToRational_direct(double value, unsigned long *num, unsigned long *denom);
+static void DoubleToSrational_direct(double value, long *num, long *denom);
+#endif
+
#ifdef notdef
static int TIFFWriteDirectoryTagCheckedFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value);
#endif
@@ -796,12 +811,42 @@
goto bad;
break;
case TIFF_RATIONAL:
- if (!TIFFWriteDirectoryTagRationalArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
- goto bad;
+ {
+ /*-- Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size. */
+ int tv_size;
+ tv_size = _TIFFSetGetFieldSize(tif->tif_dir.td_customValues[m].info->set_field_type);
+ if (tv_size == 8) {
+ if (!TIFFWriteDirectoryTagRationalDoubleArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ } else {
+ /*-- default should be tv_size == 4 */
+ if (!TIFFWriteDirectoryTagRationalArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ /*-- ToDo: After Testing, this should be removed and tv_size==4 should be set as default. */
+ if (tv_size != 4) {
+ TIFFErrorExt(0,"TIFFLib: _TIFFWriteDirectorySec()", "Rational2Double: .set_field_type in not 4 but %d", tv_size);
+ }
+ }
+ }
break;
case TIFF_SRATIONAL:
- if (!TIFFWriteDirectoryTagSrationalArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
- goto bad;
+ {
+ /*-- Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size. */
+ int tv_size;
+ tv_size = _TIFFSetGetFieldSize(tif->tif_dir.td_customValues[m].info->set_field_type);
+ if (tv_size == 8) {
+ if (!TIFFWriteDirectoryTagSrationalDoubleArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ } else {
+ /*-- default should be tv_size == 4 */
+ if (!TIFFWriteDirectoryTagSrationalArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ /*-- ToDo: After Testing, this should be removed and tv_size==4 should be set as default. */
+ if (tv_size != 4) {
+ TIFFErrorExt(0,"TIFFLib: _TIFFWriteDirectorySec()", "Rational2Double: .set_field_type in not 4 but %d", tv_size);
+ }
+ }
+ }
break;
case TIFF_FLOAT:
if (!TIFFWriteDirectoryTagFloatArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
@@ -1560,6 +1605,29 @@
return(TIFFWriteDirectoryTagCheckedSrationalArray(tif,ndir,dir,tag,count,value));
}
+/*-- Rational2Double: additional write functions */
+static int
+TIFFWriteDirectoryTagRationalDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedRationalDoubleArray(tif,ndir,dir,tag,count,value));
+}
+
+static int
+TIFFWriteDirectoryTagSrationalDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedSrationalDoubleArray(tif,ndir,dir,tag,count,value));
+}
+
#ifdef notdef
static int TIFFWriteDirectoryTagFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value)
{
@@ -2318,19 +2386,20 @@
static int
TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
{
- static const char module[] = "TIFFWriteDirectoryTagCheckedRational";
+ static const char module[] = "TIFFWriteDirectoryTagCheckedRational";
uint32 m[2];
assert(sizeof(uint32)==4);
- if( value < 0 )
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Negative value is illegal");
- return 0;
- }
- else if( value != value )
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Not-a-number value is illegal");
- return 0;
- }
+ if (value < 0)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module, "Negative value is illegal");
+ return 0;
+ }
+ else if (value != value)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module, "Not-a-number value is illegal");
+ return 0;
+ }
+#ifdef not_def
else if (value==0.0)
{
m[0]=0;
@@ -2351,6 +2420,15 @@
m[0]=0xFFFFFFFF;
m[1]=(uint32)(0xFFFFFFFF/value);
}
+#else
+ /*--Rational2Double: New function also used for non-custom rational tags.
+ * However, could be omitted here, because TIFFWriteDirectoryTagCheckedRational() is not used by code for custom tags,
+ * only by code for named-tiff-tags like FIELD_RESOLUTION and FIELD_POSITION */
+ else {
+ DoubleToRational(value, &m[0], &m[1]);
+ }
+#endif
+
if (tif->tif_flags&TIFF_SWAB)
{
TIFFSwabLong(&m[0]);
@@ -2377,6 +2455,7 @@
}
for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++)
{
+#ifdef not_def
if (*na<=0.0 || *na != *na)
{
nb[0]=0;
@@ -2398,6 +2477,10 @@
nb[0]=0xFFFFFFFF;
nb[1]=(uint32)((double)0xFFFFFFFF/(*na));
}
+#else
+ /*-- Rational2Double: Also for float precision accuracy is sometimes enhanced --*/
+ DoubleToRational(*na, &nb[0], &nb[1]);
+#endif
}
if (tif->tif_flags&TIFF_SWAB)
TIFFSwabArrayOfLong(m,count*2);
@@ -2424,6 +2507,7 @@
}
for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++)
{
+#ifdef not_def
if (*na<0.0)
{
if (*na==(int32)(*na))
@@ -2460,6 +2544,10 @@
nb[1]=(int32)((double)0x7FFFFFFF/(*na));
}
}
+#else
+ /*-- Rational2Double: Also for float precision accuracy is sometimes enhanced --*/
+ DoubleToSrational(*na, &nb[0], &nb[1]);
+#endif
}
if (tif->tif_flags&TIFF_SWAB)
TIFFSwabArrayOfLong((uint32*)m,count*2);
@@ -2468,6 +2556,400 @@
return(o);
}
+/*-- Rational2Double: additional write functions for double arrays */
+static int
+TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
+{
+ static const char module[] = "TIFFWriteDirectoryTagCheckedRationalDoubleArray";
+ uint32* m;
+ double* na;
+ uint32* nb;
+ uint32 nc;
+ int o;
+ assert(sizeof(uint32)==4);
+ m=_TIFFmalloc(count*2*sizeof(uint32));
+ if (m==NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++)
+ {
+ DoubleToRational(*na, &nb[0], &nb[1]);
+ }
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfLong(m,count*2);
+ o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,count,count*8,&m[0]);
+ _TIFFfree(m);
+ return(o);
+} /*-- TIFFWriteDirectoryTagCheckedRationalDoubleArray() ------- */
+
+static int
+TIFFWriteDirectoryTagCheckedSrationalDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
+{
+ static const char module[] = "TIFFWriteDirectoryTagCheckedSrationalDoubleArray";
+ int32* m;
+ double* na;
+ int32* nb;
+ uint32 nc;
+ int o;
+ assert(sizeof(int32)==4);
+ m=_TIFFmalloc(count*2*sizeof(int32));
+ if (m==NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++)
+ {
+ DoubleToSrational(*na, &nb[0], &nb[1]);
+ }
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfLong((uint32*)m,count*2);
+ o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SRATIONAL,count,count*8,&m[0]);
+ _TIFFfree(m);
+ return(o);
+} /*--- TIFFWriteDirectoryTagCheckedSrationalDoubleArray() -------- */
+
+#if 0
+static
+void DoubleToRational_direct(double value, unsigned long *num, unsigned long *denom)
+{
+ /*--- OLD Code for debugging and comparison ---- */
+ /* code merged from TIFFWriteDirectoryTagCheckedRationalArray() and TIFFWriteDirectoryTagCheckedRational() */
+
+ /* First check for zero and also check for negative numbers (which are illegal for RATIONAL)
+ * and also check for "not-a-number". In each case just set this to zero to support also rational-arrays.
+ */
+ if (value<=0.0 || value != value)
+ {
+ *num=0;
+ *denom=1;
+ }
+ else if (value <= 0xFFFFFFFFU && (value==(double)(uint32)(value))) /* check for integer values */
+ {
+ *num=(uint32)(value);
+ *denom=1;
+ }
+ else if (value<1.0)
+ {
+ *num = (uint32)((value) * (double)0xFFFFFFFFU);
+ *denom=0xFFFFFFFFU;
+ }
+ else
+ {
+ *num=0xFFFFFFFFU;
+ *denom=(uint32)((double)0xFFFFFFFFU/(value));
+ }
+} /*-- DoubleToRational_direct() -------------- */
+#endif
+
+#if 0
+static
+void DoubleToSrational_direct(double value, long *num, long *denom)
+{
+ /*--- OLD Code for debugging and comparison -- SIGNED-version ----*/
+ /* code was amended from original TIFFWriteDirectoryTagCheckedSrationalArray() */
+
+ /* First check for zero and also check for negative numbers (which are illegal for RATIONAL)
+ * and also check for "not-a-number". In each case just set this to zero to support also rational-arrays.
+ */
+ if (value<0.0)
+ {
+ if (value==(int32)(value))
+ {
+ *num=(int32)(value);
+ *denom=1;
+ }
+ else if (value>-1.0)
+ {
+ *num=-(int32)((-value) * (double)0x7FFFFFFF);
+ *denom=0x7FFFFFFF;
+ }
+ else
+ {
+ *num=-0x7FFFFFFF;
+ *denom=(int32)((double)0x7FFFFFFF / (-value));
+ }
+ }
+ else
+ {
+ if (value==(int32)(value))
+ {
+ *num=(int32)(value);
+ *denom=1;
+ }
+ else if (value<1.0)
+ {
+ *num=(int32)((value) *(double)0x7FFFFFFF);
+ *denom=0x7FFFFFFF;
+ }
+ else
+ {
+ *num=0x7FFFFFFF;
+ *denom=(int32)((double)0x7FFFFFFF / (value));
+ }
+ }
+} /*-- DoubleToSrational_direct() --------------*/
+#endif
+
+//#define DOUBLE2RAT_DEBUGOUTPUT
+/** ----- Rational2Double: Double To Rational Conversion ----------------------------------------------------------
+* There is a mathematical theorem to convert real numbers into a rational (integer fraction) number.
+* This is called "continuous fraction" which uses the Euclidean algorithm to find the greatest common divisor (GCD).
+* (ref. e.g. https://de.wikipedia.org/wiki/Kettenbruch or https://en.wikipedia.org/wiki/Continued_fraction
+* https://en.wikipedia.org/wiki/Euclidean_algorithm)
+* The following functions implement the
+* - ToRationalEuclideanGCD() auxiliary function which mainly implements euclidean GCD
+* - DoubleToRational() conversion function for un-signed rationals
+* - DoubleToSrational() conversion function for signed rationals
+------------------------------------------------------------------------------------------------------------------*/
+
+/**---- ToRationalEuclideanGCD() -----------------------------------------
+* Calculates the rational fractional of a double input value
+* using the Euclidean algorithm to find the greatest common divisor (GCD)
+------------------------------------------------------------------------*/
+static
+void ToRationalEuclideanGCD(double value, int blnUseSignedRange, int blnUseSmallRange, unsigned long long *ullNum, unsigned long long *ullDenom)
+{
+ /* Internally, the integer variables can be bigger than the external ones,
+ * as long as the result will fit into the external variable size.
+ */
+ unsigned long long val, numSum[3] = { 0, 1, 0 }, denomSum[3] = { 1, 0, 0 };
+ unsigned long long aux, bigNum, bigDenom;
+ unsigned long long returnLimit;
+ int i;
+ unsigned long long nMax;
+ double fMax;
+ unsigned long maxDenom;
+ /*-- nMax and fMax defines the initial accuracy of the starting fractional,
+ * or better, the highest used integer numbers used within the starting fractional (bigNum/bigDenom).
+ * There are two approaches, which can accidentally lead to different accuracies just depending on the value.
+ * Therefore, blnUseSmallRange steers this behavior.
+ * For long long nMax = ((9223372036854775807-1)/2); for long nMax = ((2147483647-1)/2);
+ */
+ if (blnUseSmallRange) {
+ nMax = (unsigned long long)((2147483647 - 1) / 2); /* for ULONG range */
+ }
+ else {
+ nMax = ((9223372036854775807 - 1) / 2); /* for ULLONG range */
+ }
+ fMax = (double)nMax;
+
+ /*-- For the Euclidean GCD define the denominator range, so that it stays within size of unsigned long variables.
+ * maxDenom should be LONG_MAX for negative values and ULONG_MAX for positive ones.
+ * Also the final returned value of ullNum and ullDenom is limited according to signed- or unsigned-range.
+ */
+ if (blnUseSignedRange) {
+ maxDenom = 2147483647UL; /*LONG_MAX = 0x7FFFFFFFUL*/
+ returnLimit = maxDenom;
+ }
+ else {
+ maxDenom = 0xFFFFFFFFUL; /*ULONG_MAX = 0xFFFFFFFFUL*/
+ returnLimit = maxDenom;
+ }
+
+ /*-- First generate a rational fraction (bigNum/bigDenom) which represents the value
+ * as a rational number with the highest accuracy. Therefore, unsigned long long (uint64) is needed.
+ * This rational fraction is then reduced using the Euclidean algorithm to find the greatest common divisor (GCD).
+ * bigNum = big numinator of value without fraction (or cut residual fraction)
+ * bigDenom = big denominator of value
+ *-- Break-criteria so that uint64 cast to "bigNum" introduces no error and bigDenom has no overflow,
+ * and stop with enlargement of fraction when the double-value of it reaches an integer number without fractional part.
+ */
+ bigDenom = 1;
+ while ((value != floor(value)) && (value < fMax) && (bigDenom < nMax)) {
+ bigDenom <<= 1;
+ value *= 2;
+ }
+ bigNum = (unsigned long long)value;
+
+ /*-- Start Euclidean algorithm to find the greatest common divisor (GCD) -- */
+#define MAX_ITERATIONS 64
+ for (i = 0; i < MAX_ITERATIONS; i++) {
+ /* if bigDenom is not zero, calculate integer part of fraction. */
+ if (bigDenom == 0) {
+ val = 0;
+ break;
+ }
+ else {
+ val = bigNum / bigDenom;
+ }
+
+ /* Set bigDenom to reminder of bigNum/bigDenom and bigNum to previous denominator bigDenom. */
+ aux = bigNum;
+ bigNum = bigDenom;
+ bigDenom = aux % bigDenom;
+
+ /* calculate next denominator and check for its given maximum */
+ aux = val;
+ if (denomSum[1] * val + denomSum[0] >= maxDenom) {
+ aux = (maxDenom - denomSum[0]) / denomSum[1];
+ if (aux * 2 >= val || denomSum[1] >= maxDenom)
+ i = (MAX_ITERATIONS + 1); /* exit but execute rest of for-loop */
+ else
+ break;
+ }
+ /* calculate next numerator to numSum2 and save previous one to numSum0; numSum1 just copy of numSum2. */
+ numSum[2] = aux * numSum[1] + numSum[0];
+ numSum[0] = numSum[1];
+ numSum[1] = numSum[2];
+ /* calculate next denominator to denomSum2 and save previous one to denomSum0; denomSum1 just copy of denomSum2. */
+ denomSum[2] = aux * denomSum[1] + denomSum[0];
+ denomSum[0] = denomSum[1];
+ denomSum[1] = denomSum[2];
+ }
+
+ /*-- Check and adapt for final variable size and return values; reduces internal accuracy; denominator is kept in ULONG-range with maxDenom -- */
+ while (numSum[1] > returnLimit || denomSum[1] > returnLimit) {
+ numSum[1] = numSum[1] / 2;
+ denomSum[1] = denomSum[1] / 2;
+ }
+
+ /* return values */
+ *ullNum = numSum[1];
+ *ullDenom = denomSum[1];
+
+} /*-- ToRationalEuclideanGCD() -------------- */
+
+
+/**---- DoubleToRational() -----------------------------------------------
+* Calculates the rational fractional of a double input value
+* for UN-SIGNED rationals,
+* using the Euclidean algorithm to find the greatest common divisor (GCD)
+------------------------------------------------------------------------*/
+static
+void DoubleToRational(double value, uint32 *num, uint32 *denom)
+{
+ /*---- UN-SIGNED RATIONAL ---- */
+ double dblDiff, dblDiff2;
+ unsigned long long ullNum, ullDenom, ullNum2, ullDenom2;
+
+ /*-- Check for negative values. If so it is an error. */
+ /* Test written that way to catch NaN */
+ if (!(value >= 0)) {
+ *num = *denom = 0;
+ TIFFErrorExt(0, "TIFFLib: DoubleToRational()", " Negative Value for Unsigned Rational given.");
+ return;
+ }
+
+ /*-- Check for too big numbers (> ULONG_MAX) -- */
+ if (value > 0xFFFFFFFFUL) {
+ *num = 0xFFFFFFFFU;
+ *denom = 0;
+ return;
+ }
+ /*-- Check for easy integer numbers -- */
+ if (value == (uint32)(value)) {
+ *num = (uint32)value;
+ *denom = 1;
+ return;
+ }
+ /*-- Check for too small numbers for "unsigned long" type rationals -- */
+ if (value < 1.0 / (double)0xFFFFFFFFUL) {
+ *num = 0;
+ *denom = 0xFFFFFFFFU;
+ return;
+ }
+
+ /*-- There are two approaches using the Euclidean algorithm,
+ * which can accidentally lead to different accuracies just depending on the value.
+ * Try both and define which one was better.
+ */
+ ToRationalEuclideanGCD(value, FALSE, FALSE, &ullNum, &ullDenom);
+ ToRationalEuclideanGCD(value, FALSE, TRUE, &ullNum2, &ullDenom2);
+ /*-- Double-Check, that returned values fit into ULONG :*/
+ if (ullNum > 0xFFFFFFFFUL || ullDenom > 0xFFFFFFFFUL || ullNum2 > 0xFFFFFFFFUL || ullDenom2 > 0xFFFFFFFFUL) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ TIFFErrorExt(0, "TIFFLib: DoubleToRational()", " Num or Denom exceeds ULONG: val=%14.6f, num=%I64u, denom=%I64u | num2=%I64u, denom2=%I64u", value, ullNum, ullDenom, ullNum2, ullDenom2);
+#else
+ TIFFErrorExt(0, "TIFFLib: DoubleToRational()", " Num or Denom exceeds ULONG: val=%14.6f, num=%12llu, denom=%12llu | num2=%12llu, denom2=%12llu", value, ullNum, ullDenom, ullNum2, ullDenom2);
+#endif
+ assert(0);
+ }
+
+ /* Check, which one has higher accuracy and take that. */
+ dblDiff = fabs(value - ((double)ullNum / (double)ullDenom));
+ dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2));
+ if (dblDiff < dblDiff2) {
+ *num = (uint32)ullNum;
+ *denom = (uint32)ullDenom;
+ }
+ else {
+ *num = (uint32)ullNum2;
+ *denom = (uint32)ullDenom2;
+ }
+} /*-- DoubleToRational() -------------- */
+
+/**---- DoubleToSrational() -----------------------------------------------
+* Calculates the rational fractional of a double input value
+* for SIGNED rationals,
+* using the Euclidean algorithm to find the greatest common divisor (GCD)
+------------------------------------------------------------------------*/
+static
+void DoubleToSrational(double value, int32 *num, int32 *denom)
+{
+ /*---- SIGNED RATIONAL ----*/
+ int neg = 1;
+ double dblDiff, dblDiff2;
+ unsigned long long ullNum, ullDenom, ullNum2, ullDenom2;
+
+ /*-- Check for negative values and use then the positive one for internal calculations, but take the sign into account before returning. */
+ if (value < 0) { neg = -1; value = -value; }
+
+ /*-- Check for too big numbers (> LONG_MAX) -- */
+ if (value > 0x7FFFFFFFL) {
+ *num = 0x7FFFFFFFL;
+ *denom = 0;
+ return;
+ }
+ /*-- Check for easy numbers -- */
+ if (value == (int32)(value)) {
+ *num = (int32)(neg * value);
+ *denom = 1;
+ return;
+ }
+ /*-- Check for too small numbers for "long" type rationals -- */
+ if (value < 1.0 / (double)0x7FFFFFFFL) {
+ *num = 0;
+ *denom = 0x7FFFFFFFL;
+ return;
+ }
+
+ /*-- There are two approaches using the Euclidean algorithm,
+ * which can accidentally lead to different accuracies just depending on the value.
+ * Try both and define which one was better.
+ * Furthermore, set behavior of ToRationalEuclideanGCD() to the range of signed-long.
+ */
+ ToRationalEuclideanGCD(value, TRUE, FALSE, &ullNum, &ullDenom);
+ ToRationalEuclideanGCD(value, TRUE, TRUE, &ullNum2, &ullDenom2);
+ /*-- Double-Check, that returned values fit into LONG :*/
+ if (ullNum > 0x7FFFFFFFL || ullDenom > 0x7FFFFFFFL || ullNum2 > 0x7FFFFFFFL || ullDenom2 > 0x7FFFFFFFL) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ TIFFErrorExt(0, "TIFFLib: DoubleToSrational()", " Num or Denom exceeds LONG: val=%14.6f, num=%I64u, denom=%I64u | num2=%I64u, denom2=%I64u", neg*value, ullNum, ullDenom, ullNum2, ullDenom2);
+#else
+ TIFFErrorExt(0, "TIFFLib: DoubleToSrational()", " Num or Denom exceeds LONG: val=%14.6f, num=%12llu, denom=%12llu | num2=%12llu, denom2=%12llu", neg*value, ullNum, ullDenom, ullNum2, ullDenom2);
+#endif
+ assert(0);
+ }
+
+ /* Check, which one has higher accuracy and take that. */
+ dblDiff = fabs(value - ((double)ullNum / (double)ullDenom));
+ dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2));
+ if (dblDiff < dblDiff2) {
+ *num = (int32)(neg * (long)ullNum);
+ *denom = (int32)ullDenom;
+ }
+ else {
+ *num = (int32)(neg * (long)ullNum2);
+ *denom = (int32)ullDenom2;
+ }
+} /*-- DoubleToSrational() --------------*/
+
+
+
+
+
#ifdef notdef
static int
TIFFWriteDirectoryTagCheckedFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value)
diff --git a/third_party/libtiff/tif_fax3.c b/third_party/libtiff/tif_fax3.c
index d11c968..9ab5b26 100644
--- a/third_party/libtiff/tif_fax3.c
+++ b/third_party/libtiff/tif_fax3.c
@@ -73,6 +73,7 @@
int EOLcnt; /* count of EOL codes recognized */
TIFFFaxFillFunc fill; /* fill routine */
uint32* runs; /* b&w runs for current/previous row */
+ uint32 nruns; /* size of the refruns / curruns arrays */
uint32* refruns; /* runs for reference line */
uint32* curruns; /* runs for current line */
@@ -160,7 +161,9 @@
*/
sp->bitmap =
TIFFGetBitRevTable(tif->tif_dir.td_fillorder != FILLORDER_LSB2MSB);
+ sp->curruns = sp->runs;
if (sp->refruns) { /* init reference line to white */
+ sp->refruns = sp->runs + sp->nruns;
sp->refruns[0] = (uint32) sp->b.rowpixels;
sp->refruns[1] = 0;
}
@@ -218,8 +221,12 @@
#define Nop
-/*
+/**
* Decode the requested amount of G3 1D-encoded data.
+ * @param buf destination buffer
+ * @param occ available bytes in destination buffer
+ * @param s number of planes (ignored)
+ * @returns 1 for success, -1 in case of error
*/
static int
Fax3Decode1D(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
@@ -300,7 +307,9 @@
else
EXPAND2D(EOF2Da);
(*sp->fill)(buf, thisrun, pa, lastx);
- SETVALUE(0); /* imaginary change for reference */
+ if (pa < thisrun + sp->nruns) {
+ SETVALUE(0); /* imaginary change for reference */
+ }
SWAP(uint32*, sp->curruns, sp->refruns);
buf += sp->b.rowbytes;
occ -= sp->b.rowbytes;
@@ -506,7 +515,7 @@
int needsRefLine;
Fax3CodecState* dsp = (Fax3CodecState*) Fax3State(tif);
tmsize_t rowbytes;
- uint32 rowpixels, nruns;
+ uint32 rowpixels;
if (td->td_bitspersample != 1) {
TIFFErrorExt(tif->tif_clientdata, module,
@@ -523,6 +532,13 @@
rowbytes = TIFFScanlineSize(tif);
rowpixels = td->td_imagewidth;
}
+ if ((uint64)rowbytes < ((uint64)rowpixels + 7) / 8)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Inconsistent number of bytes per row : rowbytes=%lu rowpixels=%lu",
+ (unsigned long)(rowbytes), (unsigned long)(rowpixels));
+ return (0);
+ }
sp->rowbytes = rowbytes;
sp->rowpixels = rowpixels;
/*
@@ -539,26 +555,26 @@
TIFFroundup and TIFFSafeMultiply return zero on integer overflow
*/
dsp->runs=(uint32*) NULL;
- nruns = TIFFroundup_32(rowpixels,32);
+ dsp->nruns = TIFFroundup_32(rowpixels,32);
if (needsRefLine) {
- nruns = TIFFSafeMultiply(uint32,nruns,2);
+ dsp->nruns = TIFFSafeMultiply(uint32,dsp->nruns,2);
}
- if ((nruns == 0) || (TIFFSafeMultiply(uint32,nruns,2) == 0)) {
+ if ((dsp->nruns == 0) || (TIFFSafeMultiply(uint32,dsp->nruns,2) == 0)) {
TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
"Row pixels integer overflow (rowpixels %u)",
rowpixels);
return (0);
}
dsp->runs = (uint32*) _TIFFCheckMalloc(tif,
- TIFFSafeMultiply(uint32,nruns,2),
+ TIFFSafeMultiply(uint32,dsp->nruns,2),
sizeof (uint32),
"for Group 3/4 run arrays");
if (dsp->runs == NULL)
return (0);
- memset( dsp->runs, 0, TIFFSafeMultiply(uint32,nruns,2)*sizeof(uint32));
+ memset( dsp->runs, 0, TIFFSafeMultiply(uint32,dsp->nruns,2)*sizeof(uint32));
dsp->curruns = dsp->runs;
if (needsRefLine)
- dsp->refruns = dsp->runs + nruns;
+ dsp->refruns = dsp->runs + dsp->nruns;
else
dsp->refruns = NULL;
if (td->td_compression == COMPRESSION_CCITTFAX3
@@ -594,15 +610,19 @@
*/
#define Fax3FlushBits(tif, sp) { \
- if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) \
- (void) TIFFFlushData1(tif); \
+ if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) { \
+ if( !TIFFFlushData1(tif) ) \
+ return 0; \
+ } \
*(tif)->tif_rawcp++ = (uint8) (sp)->data; \
(tif)->tif_rawcc++; \
(sp)->data = 0, (sp)->bit = 8; \
}
#define _FlushBits(tif) { \
- if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) \
- (void) TIFFFlushData1(tif); \
+ if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) { \
+ if( !TIFFFlushData1(tif) ) \
+ return 0; \
+ } \
*(tif)->tif_rawcp++ = (uint8) data; \
(tif)->tif_rawcc++; \
data = 0, bit = 8; \
@@ -627,7 +647,7 @@
* the output stream. Values are
* assumed to be at most 16 bits.
*/
-static void
+static int
Fax3PutBits(TIFF* tif, unsigned int bits, unsigned int length)
{
Fax3CodecState* sp = EncoderState(tif);
@@ -638,6 +658,7 @@
sp->data = data;
sp->bit = bit;
+ return 1;
}
/*
@@ -662,7 +683,7 @@
* appropriate table that holds the make-up and
* terminating codes is supplied.
*/
-static void
+static int
putspan(TIFF* tif, int32 span, const tableentry* tab)
{
Fax3CodecState* sp = EncoderState(tif);
@@ -700,6 +721,8 @@
sp->data = data;
sp->bit = bit;
+
+ return 1;
}
/*
@@ -708,7 +731,7 @@
* here. We also handle writing the tag bit for the next
* scanline when doing 2d encoding.
*/
-static void
+static int
Fax3PutEOL(TIFF* tif)
{
Fax3CodecState* sp = EncoderState(tif);
@@ -742,6 +765,8 @@
sp->data = data;
sp->bit = bit;
+
+ return 1;
}
/*
@@ -991,12 +1016,14 @@
for (;;) {
span = find0span(bp, bs, bits); /* white span */
- putspan(tif, span, TIFFFaxWhiteCodes);
+ if( !putspan(tif, span, TIFFFaxWhiteCodes) )
+ return 0;
bs += span;
if (bs >= bits)
break;
span = find1span(bp, bs, bits); /* black span */
- putspan(tif, span, TIFFFaxBlackCodes);
+ if( !putspan(tif, span, TIFFFaxBlackCodes) )
+ return 0;
bs += span;
if (bs >= bits)
break;
@@ -1048,21 +1075,28 @@
(b1 < a1 && a1 - b1 <= 3U) ? -(int32)(a1 - b1) : 0x7FFFFFFF;
if (!(-3 <= d && d <= 3)) { /* horizontal mode */
a2 = finddiff2(bp, a1, bits, PIXEL(bp,a1));
- putcode(tif, &horizcode);
+ if( !putcode(tif, &horizcode) )
+ return 0;
if (a0+a1 == 0 || PIXEL(bp, a0) == 0) {
- putspan(tif, a1-a0, TIFFFaxWhiteCodes);
- putspan(tif, a2-a1, TIFFFaxBlackCodes);
+ if( !putspan(tif, a1-a0, TIFFFaxWhiteCodes) )
+ return 0;
+ if( !putspan(tif, a2-a1, TIFFFaxBlackCodes) )
+ return 0;
} else {
- putspan(tif, a1-a0, TIFFFaxBlackCodes);
- putspan(tif, a2-a1, TIFFFaxWhiteCodes);
+ if( !putspan(tif, a1-a0, TIFFFaxBlackCodes) )
+ return 0;
+ if( !putspan(tif, a2-a1, TIFFFaxWhiteCodes) )
+ return 0;
}
a0 = a2;
} else { /* vertical mode */
- putcode(tif, &vcodes[d+3]);
+ if( !putcode(tif, &vcodes[d+3]) )
+ return 0;
a0 = a1;
}
} else { /* pass mode */
- putcode(tif, &passcode);
+ if( !putcode(tif, &passcode) )
+ return 0;
a0 = b2;
}
if (a0 >= bits)
@@ -1091,7 +1125,10 @@
}
while (cc > 0) {
if ((sp->b.mode & FAXMODE_NOEOL) == 0)
- Fax3PutEOL(tif);
+ {
+ if( !Fax3PutEOL(tif) )
+ return 0;
+ }
if (is2DEncoding(sp)) {
if (sp->tag == G3_1D) {
if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels))
@@ -1128,8 +1165,8 @@
return (1);
}
-static void
-Fax3Close(TIFF* tif)
+static int
+_Fax3Close(TIFF* tif)
{
if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0 && tif->tif_rawcp) {
Fax3CodecState* sp = EncoderState(tif);
@@ -1145,6 +1182,13 @@
Fax3PutBits(tif, code, length);
Fax3FlushBits(tif, sp);
}
+ return 1;
+}
+
+static void
+Fax3Close(TIFF* tif)
+{
+ _Fax3Close(tif);
}
static void
@@ -1453,6 +1497,13 @@
EXPAND2D(EOFG4);
if (EOLcnt)
goto EOFG4;
+ if (((lastx + 7) >> 3) > (int)occ) /* check for buffer overrun */
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Buffer overrun detected : %d bytes available, %d bits needed",
+ (int)occ, lastx);
+ return -1;
+ }
(*sp->fill)(buf, thisrun, pa, lastx);
SETVALUE(0); /* imaginary change for reference */
SWAP(uint32*, sp->curruns, sp->refruns);
@@ -1468,6 +1519,13 @@
fputs( "Bad EOFB\n", stderr );
#endif
ClrBits( 13 );
+ if (((lastx + 7) >> 3) > (int)occ) /* check for buffer overrun */
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Buffer overrun detected : %d bytes available, %d bits needed",
+ (int)occ, lastx);
+ return -1;
+ }
(*sp->fill)(buf, thisrun, pa, lastx);
UNCACHE_STATE(tif, sp);
return ( sp->line ? 1 : -1); /* don't error on badly-terminated strips */
diff --git a/third_party/libtiff/tif_fax3.h b/third_party/libtiff/tif_fax3.h
index abadcd9..701716c 100644
--- a/third_party/libtiff/tif_fax3.h
+++ b/third_party/libtiff/tif_fax3.h
@@ -240,6 +240,11 @@
* current row and reset decoding state.
*/
#define SETVALUE(x) do { \
+ if (pa >= thisrun + sp->nruns) { \
+ TIFFErrorExt(tif->tif_clientdata, module, "Buffer overflow at line %u of %s %u", \
+ sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
+ return (-1); \
+ } \
*pa++ = RunLength + (x); \
a0 += (x); \
RunLength = 0; \
@@ -377,6 +382,11 @@
*/
#define CHECK_b1 do { \
if (pa != thisrun) while (b1 <= a0 && b1 < lastx) { \
+ if( pb + 1 >= sp->refruns + sp->nruns) { \
+ TIFFErrorExt(tif->tif_clientdata, module, "Buffer overflow at line %u of %s %u", \
+ sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
+ return (-1); \
+ } \
b1 += pb[0] + pb[1]; \
pb += 2; \
} \
@@ -387,10 +397,20 @@
*/
#define EXPAND2D(eoflab) do { \
while (a0 < lastx) { \
+ if (pa >= thisrun + sp->nruns) { \
+ TIFFErrorExt(tif->tif_clientdata, module, "Buffer overflow at line %u of %s %u", \
+ sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
+ return (-1); \
+ } \
LOOKUP8(7, TIFFFaxMainTable, eof2d); \
switch (TabEnt->State) { \
case S_Pass: \
CHECK_b1; \
+ if( pb + 1 >= sp->refruns + sp->nruns) { \
+ TIFFErrorExt(tif->tif_clientdata, module, "Buffer overflow at line %u of %s %u", \
+ sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
+ return (-1); \
+ } \
b1 += *pb++; \
RunLength += b1 - a0; \
a0 = b1; \
@@ -469,20 +489,28 @@
case S_V0: \
CHECK_b1; \
SETVALUE(b1 - a0); \
+ if( pb >= sp->refruns + sp->nruns) { \
+ TIFFErrorExt(tif->tif_clientdata, module, "Buffer overflow at line %u of %s %u", \
+ sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
+ return (-1); \
+ } \
b1 += *pb++; \
break; \
case S_VR: \
CHECK_b1; \
SETVALUE(b1 - a0 + TabEnt->Param); \
+ if( pb >= sp->refruns + sp->nruns) { \
+ TIFFErrorExt(tif->tif_clientdata, module, "Buffer overflow at line %u of %s %u", \
+ sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
+ return (-1); \
+ } \
b1 += *pb++; \
break; \
case S_VL: \
CHECK_b1; \
- if (b1 <= (int) (a0 + TabEnt->Param)) { \
- if (b1 < (int) (a0 + TabEnt->Param) || pa != thisrun) { \
- unexpected("VL", a0); \
- goto eol2d; \
- } \
+ if (b1 < (int) (a0 + TabEnt->Param)) { \
+ unexpected("VL", a0); \
+ goto eol2d; \
} \
SETVALUE(b1 - a0 - TabEnt->Param); \
b1 -= *--pb; \
@@ -529,6 +557,7 @@
CLEANUP_RUNS(); \
} while (0)
#endif /* _FAX3_ */
+/* vim: set ts=8 sts=4 sw=4 noet: */
/*
* Local Variables:
* mode: c
diff --git a/third_party/libtiff/tif_fax3sm.c b/third_party/libtiff/tif_fax3sm.c
index 822191e..ba2fc53 100644
--- a/third_party/libtiff/tif_fax3sm.c
+++ b/third_party/libtiff/tif_fax3sm.c
@@ -1,5 +1,6 @@
/* WARNING, this file was automatically generated by the
mkg3states program */
+#include <stdint.h>
#include "tiff.h"
#include "tif_fax3.h"
const TIFFFaxTabEnt TIFFFaxMainTable[128] = {
diff --git a/third_party/libtiff/tif_getimage.c b/third_party/libtiff/tif_getimage.c
index 3a86bcf..2e88c9b 100644
--- a/third_party/libtiff/tif_getimage.c
+++ b/third_party/libtiff/tif_getimage.c
@@ -647,38 +647,28 @@
flip = setorientation(img);
if (flip & FLIP_VERTICALLY) {
- y = h - 1;
- safeskew = 0;
- safeskew -= tw;
- safeskew -= w;
+ if ((tw + w) > INT_MAX) {
+ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "unsupported tile size (too wide)");
+ return (0);
+ }
+ y = h - 1;
+ toskew = -(int32)(tw + w);
}
else {
- y = 0;
- safeskew = 0;
- safeskew -= tw;
- safeskew +=w;
+ if (tw > (INT_MAX + w)) {
+ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "unsupported tile size (too wide)");
+ return (0);
+ }
+ y = 0;
+ toskew = -(int32)(tw - w);
}
- if(safeskew > INT_MAX || safeskew < INT_MIN){
- _TIFFfree(buf);
- TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "Invalid skew");
- return (0);
- }
- toskew = safeskew;
-
/*
* Leftmost tile is clipped on left side if col_offset > 0.
*/
leftmost_fromskew = img->col_offset % tw;
leftmost_tw = tw - leftmost_fromskew;
- safeskew = toskew;
- safeskew += leftmost_fromskew;
- if(safeskew > INT_MAX || safeskew < INT_MIN){
- _TIFFfree(buf);
- TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "Invalid skew");
- return (0);
- }
- leftmost_toskew = safeskew;
+ leftmost_toskew = toskew + leftmost_fromskew;
for (row = 0; ret != 0 && row < h; row += nrow)
{
rowstoread = th - (row + img->row_offset) % th;
@@ -800,10 +790,18 @@
flip = setorientation(img);
if (flip & FLIP_VERTICALLY) {
+ if ((tw + w) > INT_MAX) {
+ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "unsupported tile size (too wide)");
+ return (0);
+ }
y = h - 1;
toskew = -(int32)(tw + w);
}
else {
+ if (tw > (INT_MAX + w)) {
+ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "unsupported tile size (too wide)");
+ return (0);
+ }
y = 0;
toskew = -(int32)(tw - w);
}
@@ -974,6 +972,10 @@
flip = setorientation(img);
if (flip & FLIP_VERTICALLY) {
+ if ( w > INT_MAX ) {
+ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Width overflow");
+ return (0);
+ }
y = h - 1;
toskew = -(int32)(w + w);
} else {
@@ -1070,6 +1072,10 @@
flip = setorientation(img);
if (flip & FLIP_VERTICALLY) {
+ if ( w > INT_MAX ) {
+ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Width overflow");
+ return (0);
+ }
y = h - 1;
toskew = -(int32)(w + w);
}
diff --git a/third_party/libtiff/tif_jpeg.c b/third_party/libtiff/tif_jpeg.c
index 3b1ed9f..d8b0548 100644
--- a/third_party/libtiff/tif_jpeg.c
+++ b/third_party/libtiff/tif_jpeg.c
@@ -474,7 +474,8 @@
}
#endif
- TIFFFlushData1(tif);
+ if( !TIFFFlushData1(tif) )
+ return FALSE;
sp->dest.next_output_byte = (JOCTET*) tif->tif_rawdata;
sp->dest.free_in_buffer = (size_t) tif->tif_rawdatasize;
@@ -945,7 +946,10 @@
return(0);
if (!data->filepositioned)
{
- TIFFSeekFile(data->tif,data->fileoffset,SEEK_SET);
+ if (TIFFSeekFile(data->tif,data->fileoffset,SEEK_SET) == (toff_t)-1)
+ {
+ return 0;
+ }
data->filepositioned=1;
}
m=data->buffersize;
@@ -1214,35 +1218,37 @@
/* store for all coefficients */
/* See call to jinit_d_coef_controller() from master_selection() */
/* in libjpeg */
- toff_t nRequiredMemory = (toff_t)sp->cinfo.d.image_width *
- sp->cinfo.d.image_height *
- sp->cinfo.d.num_components *
- ((td->td_bitspersample+7)/8);
- /* BLOCK_SMOOTHING_SUPPORTED is generally defined, so we need */
- /* to replicate the logic of jinit_d_coef_controller() */
- if( sp->cinfo.d.progressive_mode )
- nRequiredMemory *= 3;
-#ifndef TIFF_LIBJPEG_LARGEST_MEM_ALLOC
-#define TIFF_LIBJPEG_LARGEST_MEM_ALLOC (100 * 1024 * 1024)
-#endif
+ /* 1 MB for regular libjpeg usage */
+ toff_t nRequiredMemory = 1024 * 1024;
- if( nRequiredMemory > TIFF_LIBJPEG_LARGEST_MEM_ALLOC &&
+ for (ci = 0; ci < sp->cinfo.d.num_components; ci++) {
+ const jpeg_component_info *compptr = &(sp->cinfo.d.comp_info[ci]);
+ if( compptr->h_samp_factor > 0 && compptr->v_samp_factor > 0 )
+ {
+ nRequiredMemory += (toff_t)(
+ ((compptr->width_in_blocks + compptr->h_samp_factor - 1) / compptr->h_samp_factor)) *
+ ((compptr->height_in_blocks + compptr->v_samp_factor - 1) / compptr->v_samp_factor) *
+ sizeof(JBLOCK);
+ }
+ }
+
+ if( sp->cinfo.d.mem->max_memory_to_use > 0 &&
+ nRequiredMemory > (toff_t)(sp->cinfo.d.mem->max_memory_to_use) &&
getenv("LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC") == NULL )
{
- TIFFErrorExt(tif->tif_clientdata, module,
- "Reading this strip would require libjpeg to allocate "
- "at least %u bytes. "
- "This is disabled since above the %u threshold. "
- "You may override this restriction by defining the "
- "LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC environment variable, "
- "or recompile libtiff by defining the "
- "TIFF_LIBJPEG_LARGEST_MEM_ALLOC macro to a value greater "
- "than %u",
- (unsigned)nRequiredMemory,
- (unsigned)TIFF_LIBJPEG_LARGEST_MEM_ALLOC,
- (unsigned)TIFF_LIBJPEG_LARGEST_MEM_ALLOC);
- return (0);
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Reading this image would require libjpeg to allocate "
+ "at least %u bytes. "
+ "This is disabled since above the %u threshold. "
+ "You may override this restriction by defining the "
+ "LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC environment variable, "
+ "or setting the JPEGMEM environment variable to a value greater "
+ "or equal to '%uM'",
+ (unsigned)(nRequiredMemory),
+ (unsigned)(sp->cinfo.d.mem->max_memory_to_use),
+ (unsigned)((nRequiredMemory + 1000000 - 1) / 1000000));
+ return 0;
}
}
@@ -2352,7 +2358,7 @@
switch (tag) {
case TIFFTAG_JPEGTABLES:
*va_arg(ap, uint32*) = sp->jpegtables_length;
- *va_arg(ap, void**) = sp->jpegtables;
+ *va_arg(ap, const void**) = sp->jpegtables;
break;
case TIFFTAG_JPEGQUALITY:
*va_arg(ap, int*) = sp->jpegquality;
@@ -2487,6 +2493,7 @@
{
JPEGState* sp;
+ (void)scheme;
assert(scheme == COMPRESSION_JPEG);
/*
diff --git a/third_party/libtiff/tif_luv.c b/third_party/libtiff/tif_luv.c
index 6fe4858..3bd02e8 100644
--- a/third_party/libtiff/tif_luv.c
+++ b/third_party/libtiff/tif_luv.c
@@ -193,6 +193,7 @@
tmsize_t cc;
int rc;
+ (void)s;
assert(s == 0);
assert(sp != NULL);
@@ -266,6 +267,7 @@
unsigned char* bp;
uint32* tp;
+ (void)s;
assert(s == 0);
assert(sp != NULL);
@@ -326,6 +328,7 @@
tmsize_t cc;
int rc;
+ (void)s;
assert(s == 0);
sp = DecoderState(tif);
assert(sp != NULL);
@@ -447,6 +450,7 @@
int rc=0, mask;
tmsize_t beg;
+ (void)s;
assert(s == 0);
assert(sp != NULL);
npixels = cc / sp->pixel_size;
@@ -541,6 +545,7 @@
uint8* op;
uint32* tp;
+ (void)s;
assert(s == 0);
assert(sp != NULL);
npixels = cc / sp->pixel_size;
@@ -598,6 +603,7 @@
int rc=0, mask;
tmsize_t beg;
+ (void)s;
assert(s == 0);
assert(sp != NULL);
@@ -742,7 +748,7 @@
#undef exp2 /* Conflict with C'99 function */
#define exp2(x) exp(M_LN2*(x))
-static int itrunc(double x, int m)
+static int tiff_itrunc(double x, int m)
{
if( m == SGILOGENCODE_NODITHER )
return (int)x;
@@ -777,9 +783,9 @@
if (Y <= -1.8371976e19)
return (0xffff);
if (Y > 5.4136769e-20)
- return itrunc(256.*(log2(Y) + 64.), em);
+ return tiff_itrunc(256.*(log2(Y) + 64.), em);
if (Y < -5.4136769e-20)
- return (~0x7fff | itrunc(256.*(log2(-Y) + 64.), em));
+ return (~0x7fff | tiff_itrunc(256.*(log2(-Y) + 64.), em));
return (0);
}
@@ -855,7 +861,7 @@
else if (Y <= .00024283)
return (0);
else
- return itrunc(64.*(log2(Y) + 12.), em);
+ return tiff_itrunc(64.*(log2(Y) + 12.), em);
}
#define NANGLES 100
@@ -925,12 +931,12 @@
if (v < UV_VSTART)
return oog_encode(u, v);
- vi = itrunc((v - UV_VSTART)*(1./UV_SQSIZ), em);
+ vi = tiff_itrunc((v - UV_VSTART)*(1./UV_SQSIZ), em);
if (vi >= UV_NVS)
return oog_encode(u, v);
if (u < uv_row[vi].ustart)
return oog_encode(u, v);
- ui = itrunc((u - uv_row[vi].ustart)*(1./UV_SQSIZ), em);
+ ui = tiff_itrunc((u - uv_row[vi].ustart)*(1./UV_SQSIZ), em);
if (ui >= uv_row[vi].nus)
return oog_encode(u, v);
@@ -1099,7 +1105,7 @@
else if (sp->encode_meth == SGILOGENCODE_NODITHER)
Le = (luv3[0]-3314) >> 2;
else
- Le = itrunc(.25*(luv3[0]-3314.), sp->encode_meth);
+ Le = tiff_itrunc(.25*(luv3[0]-3314.), sp->encode_meth);
Ce = uv_encode((luv3[1]+.5)/(1<<15), (luv3[2]+.5)/(1<<15),
sp->encode_meth);
@@ -1155,10 +1161,10 @@
v = 9.*XYZ[1] / s;
}
if (u <= 0.) ue = 0;
- else ue = itrunc(UVSCALE*u, em);
+ else ue = tiff_itrunc(UVSCALE*u, em);
if (ue > 255) ue = 255;
if (v <= 0.) ve = 0;
- else ve = itrunc(UVSCALE*v, em);
+ else ve = tiff_itrunc(UVSCALE*v, em);
if (ve > 255) ve = 255;
/* combine encodings */
return (Le << 16 | ue << 8 | ve);
@@ -1238,8 +1244,8 @@
}
while (n-- > 0) {
*luv++ = (uint32)luv3[0] << 16 |
- (itrunc(luv3[1]*(UVSCALE/(1<<15)), sp->encode_meth) << 8 & 0xff00) |
- (itrunc(luv3[2]*(UVSCALE/(1<<15)), sp->encode_meth) & 0xff);
+ (tiff_itrunc(luv3[1]*(UVSCALE/(1<<15)), sp->encode_meth) << 8 & 0xff00) |
+ (tiff_itrunc(luv3[2]*(UVSCALE/(1<<15)), sp->encode_meth) & 0xff);
luv3 += 3;
}
}
diff --git a/third_party/libtiff/tif_lzw.c b/third_party/libtiff/tif_lzw.c
index 542ada4..bc50870 100644
--- a/third_party/libtiff/tif_lzw.c
+++ b/third_party/libtiff/tif_lzw.c
@@ -214,19 +214,16 @@
return (0);
}
- DecoderState(tif)->dec_codetab = NULL;
- DecoderState(tif)->dec_decode = NULL;
+ sp = DecoderState(tif);
+ sp->dec_codetab = NULL;
+ sp->dec_decode = NULL;
/*
* Setup predictor setup.
*/
(void) TIFFPredictorInit(tif);
-
- sp = DecoderState(tif);
}
- assert(sp != NULL);
-
if (sp->dec_codetab == NULL) {
sp->dec_codetab = (code_t*)_TIFFmalloc(CSIZE*sizeof (code_t));
if (sp->dec_codetab == NULL) {
@@ -1162,6 +1159,7 @@
TIFFInitLZW(TIFF* tif, int scheme)
{
static const char module[] = "TIFFInitLZW";
+ (void)scheme;
assert(scheme == COMPRESSION_LZW);
/*
* Allocate state block so tag methods have storage to record values.
@@ -1219,7 +1217,7 @@
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#endif /* LZW_SUPPORT */
diff --git a/third_party/libtiff/tif_open.c b/third_party/libtiff/tif_open.c
index 3cb53d4..a0e3158 100644
--- a/third_party/libtiff/tif_open.c
+++ b/third_party/libtiff/tif_open.c
@@ -104,6 +104,7 @@
} n;
n.a8[0]=1;
n.a8[1]=0;
+ (void)n;
#ifdef WORDS_BIGENDIAN
assert(n.a16==256);
#else
@@ -165,7 +166,7 @@
/*
* Process library-specific flags in the open mode string.
* The following flags may be used to control intrinsic library
- * behaviour that may or may not be desirable (usually for
+ * behavior that may or may not be desirable (usually for
* compatibility with some application that claims to support
* TIFF but only supports some brain dead idea of what the
* vendor thinks TIFF is):
@@ -206,7 +207,7 @@
* not do right now.
*
* The 'M' and 'm' flags are provided because some virtual memory
- * systems exhibit poor behaviour when large images are mapped.
+ * systems exhibit poor behavior when large images are mapped.
* These options permit clients to control the use of memory-mapped
* files on a per-file basis.
*
diff --git a/third_party/libtiff/tif_pixarlog.c b/third_party/libtiff/tif_pixarlog.c
index e72cc0b..0275bfb 100644
--- a/third_party/libtiff/tif_pixarlog.c
+++ b/third_party/libtiff/tif_pixarlog.c
@@ -1200,7 +1200,8 @@
}
if (sp->stream.avail_out == 0) {
tif->tif_rawcc = tif->tif_rawdatasize;
- TIFFFlushData1(tif);
+ if (!TIFFFlushData1(tif))
+ return 0;
sp->stream.next_out = tif->tif_rawdata;
sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in PixarLogPreEncode */
}
@@ -1230,7 +1231,8 @@
if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) {
tif->tif_rawcc =
tif->tif_rawdatasize - sp->stream.avail_out;
- TIFFFlushData1(tif);
+ if (!TIFFFlushData1(tif))
+ return 0;
sp->stream.next_out = tif->tif_rawdata;
sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in PixarLogPreEncode */
}
@@ -1398,6 +1400,7 @@
PixarLogState* sp;
+ (void)scheme;
assert(scheme == COMPRESSION_PIXARLOG);
/*
diff --git a/third_party/libtiff/tif_predict.c b/third_party/libtiff/tif_predict.c
index b775663..c023397 100644
--- a/third_party/libtiff/tif_predict.c
+++ b/third_party/libtiff/tif_predict.c
@@ -116,7 +116,7 @@
TIFFDirectory* td = &tif->tif_dir;
/* Note: when PredictorSetup() fails, the effets of setupdecode() */
- /* will not be "cancelled" so setupdecode() might be robust to */
+ /* will not be "canceled" so setupdecode() might be robust to */
/* be called several times. */
if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
return 0;
@@ -270,8 +270,8 @@
}
/* Remarks related to C standard compliance in all below functions : */
-/* - to avoid any undefined behaviour, we only operate on unsigned types */
-/* since the behaviour of "overflows" is defined (wrap over) */
+/* - to avoid any undefined behavior, we only operate on unsigned types */
+/* since the behavior of "overflows" is defined (wrap over) */
/* - when storing into the byte stream, we explicitly mask with 0xff so */
/* as to make icc -check=conversions happy (not necessary by the standard) */
diff --git a/third_party/libtiff/tif_read.c b/third_party/libtiff/tif_read.c
index d1acf33..87aa5ea 100644
--- a/third_party/libtiff/tif_read.c
+++ b/third_party/libtiff/tif_read.c
@@ -755,7 +755,7 @@
}
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
-static uint64 NoSantizeSubUInt64(uint64 a, uint64 b)
+static uint64 NoSanitizeSubUInt64(uint64 a, uint64 b)
{
return a - b;
}
@@ -843,7 +843,7 @@
"Read error on strip %lu; "
"got %I64u bytes, expected %I64u",
(unsigned long) strip,
- (unsigned __int64) NoSantizeSubUInt64(tif->tif_size, TIFFGetStrileOffset(tif, strip)),
+ (unsigned __int64) NoSanitizeSubUInt64(tif->tif_size, TIFFGetStrileOffset(tif, strip)),
(unsigned __int64) bytecount);
#else
TIFFErrorExt(tif->tif_clientdata, module,
@@ -851,7 +851,7 @@
"Read error on strip %lu; "
"got %llu bytes, expected %llu",
(unsigned long) strip,
- (unsigned long long) NoSantizeSubUInt64(tif->tif_size, TIFFGetStrileOffset(tif, strip)),
+ (unsigned long long) NoSanitizeSubUInt64(tif->tif_size, TIFFGetStrileOffset(tif, strip)),
(unsigned long long) bytecount);
#endif
tif->tif_curstrip = NOSTRIP;
@@ -1447,8 +1447,16 @@
else
tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, strip);
}
- return ((*tif->tif_predecode)(tif,
- (uint16)(strip / td->td_stripsperimage)));
+ if ((*tif->tif_predecode)(tif,
+ (uint16)(strip / td->td_stripsperimage)) == 0 ) {
+ /* Needed for example for scanline access, if tif_predecode */
+ /* fails, and we try to read the same strip again. Without invalidating */
+ /* tif_curstrip, we'd call tif_decoderow() on a possibly invalid */
+ /* codec state. */
+ tif->tif_curstrip = NOSTRIP;
+ return 0;
+ }
+ return 1;
}
/*
diff --git a/third_party/libtiff/tif_write.c b/third_party/libtiff/tif_write.c
index 33e803c..3af69ab 100644
--- a/third_party/libtiff/tif_write.c
+++ b/third_party/libtiff/tif_write.c
@@ -533,6 +533,13 @@
isUnspecified(tif, FIELD_ROWSPERSTRIP) ?
td->td_samplesperpixel : TIFFNumberOfStrips(tif);
td->td_nstrips = td->td_stripsperimage;
+ /* TIFFWriteDirectoryTagData has a limitation to 0x80000000U bytes */
+ if( td->td_nstrips >= 0x80000000U / ((tif->tif_flags&TIFF_BIGTIFF)?0x8U:0x4U) )
+ {
+ TIFFErrorExt(tif->tif_clientdata, "TIFFSetupStrips",
+ "Too large Strip/Tile Offsets/ByteCounts arrays");
+ return 0;
+ }
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
td->td_stripsperimage /= td->td_samplesperpixel;
td->td_stripoffset_p = (uint64 *)
@@ -661,6 +668,10 @@
if (size == (tmsize_t)(-1)) {
size = (isTiled(tif) ?
tif->tif_tilesize : TIFFStripSize(tif));
+
+ /* Adds 10% margin for cases where compression would expand a bit */
+ if( size < TIFF_TMSIZE_T_MAX - size / 10 )
+ size += size / 10;
/*
* Make raw data buffer at least 8K
*/
diff --git a/third_party/libtiff/tiff.h b/third_party/libtiff/tiff.h
index 5b0a0c9..2d4a476 100644
--- a/third_party/libtiff/tiff.h
+++ b/third_party/libtiff/tiff.h
@@ -119,6 +119,11 @@
* Tag data type information.
*
* Note: RATIONALs are the ratio of two 32-bit integer values.
+ *--:
+ * Note2: TIFF_IFD8 data type is used in tiffFields[]-tag definition in order to distinguish the write-handling
+ of those tags between ClassicTIFF and BigTiff:
+ For ClassicTIFF libtiff writes a 32-bit value and the TIFF_IFD type-id into the file
+ For BigTIFF libtiff writes a 64-bit value and the TIFF_IFD8 type-id into the file
*/
typedef enum {
TIFF_NOTYPE = 0, /* placeholder */
@@ -375,6 +380,7 @@
January 2004 */
#define TIFFTAG_OPIIMAGEID 32781 /* %OPI ImageID
[Adobe TIFF technote] */
+#define TIFFTAG_TIFFANNOTATIONDATA 32932 /* http://web.archive.org/web/20050309141348/http://www.kofile.com/support%20pro/faqs/annospec.htm */
/* tags 32952-32956 are private tags registered to Island Graphics */
#define TIFFTAG_REFPTS 32953 /* image reference points */
#define TIFFTAG_REGIONTACKPOINT 32954 /* region-xform tack point */
@@ -409,8 +415,23 @@
#define TIFFTAG_CFAPATTERN 33422 /* color filter array pattern */
/* tag 33432 is listed in the 6.0 spec w/ unknown ownership */
#define TIFFTAG_COPYRIGHT 33432 /* copyright string */
+/* Tags 33445-33452 are used for GEL fileformat, see
+ * http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf
+ */
+#define TIFFTAG_MD_FILETAG 33445 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */
+#define TIFFTAG_MD_SCALEPIXEL 33446 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */
+#define TIFFTAG_MD_COLORTABLE 33447 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */
+#define TIFFTAG_MD_LABNAME 33448 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */
+#define TIFFTAG_MD_SAMPLEINFO 33449 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */
+#define TIFFTAG_MD_PREPDATE 33450 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */
+#define TIFFTAG_MD_PREPTIME 33451 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */
+#define TIFFTAG_MD_FILEUNITS 33452 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */
/* IPTC TAG from RichTIFF specifications */
#define TIFFTAG_RICHTIFFIPTC 33723
+#define TIFFTAG_INGR_PACKET_DATA_TAG 33918 /* Intergraph Application specific storage. */
+#define TIFFTAG_INGR_FLAG_REGISTERS 33919 /* Intergraph Application specific flags. */
+#define TIFFTAG_IRASB_TRANSORMATION_MATRIX 33920 /* Originally part of Intergraph's GeoTIFF tags, but likely understood by IrasB only. */
+#define TIFFTAG_MODELTIEPOINTTAG 33922 /* GeoTIFF */
/* 34016-34029 are reserved for ANSI IT8 TIFF/IT <dkelly@apago.com) */
#define TIFFTAG_IT8SITE 34016 /* site name */
#define TIFFTAG_IT8COLORSEQUENCE 34017 /* color seq. [RGB,CMYK,etc] */
@@ -432,6 +453,7 @@
#define TIFFTAG_IT8CMYKEQUIVALENT 34032 /* CMYK color equivalents */
/* tags 34232-34236 are private tags registered to Texas Instruments */
#define TIFFTAG_FRAMECOUNT 34232 /* Sequence Frame Count */
+#define TIFFTAG_MODELTRANSFORMATIONTAG 34264 /* Used in interchangeable GeoTIFF files */
/* tag 34377 is private tag registered to Adobe for PhotoShop */
#define TIFFTAG_PHOTOSHOP 34377
/* tags 34665, 34853 and 40965 are documented in EXIF specification */
@@ -451,7 +473,15 @@
#define TIFFTAG_STONITS 37439 /* Sample value to Nits */
/* tag 34929 is a private tag registered to FedEx */
#define TIFFTAG_FEDEX_EDR 34929 /* unknown use */
+#define TIFFTAG_IMAGESOURCEDATA 37724 /* http://justsolve.archiveteam.org/wiki/PSD, http://www.adobe.com/devnet-apps/photoshop/fileformatashtml/ */
#define TIFFTAG_INTEROPERABILITYIFD 40965 /* Pointer to Interoperability private directory */
+#define TIFFTAG_GDAL_METADATA 42112 /* Used by the GDAL library */
+#define TIFFTAG_GDAL_NODATA 42113 /* Used by the GDAL library */
+#define TIFFTAG_OCE_SCANJOB_DESCRIPTION 50215 /* Used in the Oce scanning process */
+#define TIFFTAG_OCE_APPLICATION_SELECTOR 50216 /* Used in the Oce scanning process. */
+#define TIFFTAG_OCE_IDENTIFICATION_NUMBER 50217
+#define TIFFTAG_OCE_IMAGELOGIC_CHARACTERISTICS 50218
+
/* tags 50674 to 50677 are reserved for ESRI */
#define TIFFTAG_LERC_PARAMETERS 50674 /* Stores LERC version and additional compression method */
/* Adobe Digital Negative (DNG) format tags */
@@ -535,6 +565,17 @@
into ICC profile space */
#define TIFFTAG_CURRENTICCPROFILE 50833 /* & */
#define TIFFTAG_CURRENTPREPROFILEMATRIX 50834 /* & */
+
+#define TIFFTAG_RPCCOEFFICIENT 50844 /* Define by GDAL for geospatial georeferencing through RPC: http://geotiff.maptools.org/rpc_prop.html */
+
+#define TIFFTAG_ALIAS_LAYER_METADATA 50784 /* Alias Sketchbook Pro layer usage description. */
+
+/* GeoTIFF DGIWG */
+#define TIFFTAG_TIFF_RSID 50908 /* https://www.awaresystems.be/imaging/tiff/tifftags/tiff_rsid.html */
+#define TIFFTAG_GEO_METADATA 50909 /* https://www.awaresystems.be/imaging/tiff/tifftags/geo_metadata.html */
+
+#define TIFFTAG_EXTRACAMERAPROFILES 50933 /* http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/products/photoshop/pdfs/dng_spec_1.4.0.0.pdf */
+
/* tag 65535 is an undefined tag used by Eastman Kodak */
#define TIFFTAG_DCSHUESHIFTVALUES 65535 /* hue shift correction data */
@@ -615,8 +656,11 @@
#define LERC_ADD_COMPRESSION_DEFLATE 1
#define LERC_ADD_COMPRESSION_ZSTD 2
#define TIFFTAG_LERC_MAXZERROR 65567 /* LERC maximum error */
-#define TIFFTAG_WEBP_LEVEL 65568 /* WebP compression level: WARNING not registered in Adobe-maintained registry */
-#define TIFFTAG_WEBP_LOSSLESS 65569 /* WebP lossless/lossy : WARNING not registered in Adobe-maintained registry */
+#define TIFFTAG_WEBP_LEVEL 65568 /* WebP compression level */
+#define TIFFTAG_WEBP_LOSSLESS 65569 /* WebP lossless/lossy */
+#define TIFFTAG_DEFLATE_SUBCODEC 65570 /* ZIP codec: to get/set the sub-codec to use. Will default to libdeflate when available */
+#define DEFLATE_SUBCODEC_ZLIB 0
+#define DEFLATE_SUBCODEC_LIBDEFLATE 1
/*
* EXIF tags
@@ -626,8 +670,8 @@
#define EXIFTAG_EXPOSUREPROGRAM 34850 /* Exposure program */
#define EXIFTAG_SPECTRALSENSITIVITY 34852 /* Spectral sensitivity */
#define EXIFTAG_ISOSPEEDRATINGS 34855 /* ISO speed rating */
-#define EXIFTAG_OECF 34856 /* Optoelectric conversion
- factor */
+#define EXIFTAG_PHOTOGRAPHICSENSITIVITY 34855 /* Photographic Sensitivity (new name for tag 34855) */
+#define EXIFTAG_OECF 34856 /* Optoelectric conversion factor */
#define EXIFTAG_EXIFVERSION 36864 /* Exif version */
#define EXIFTAG_DATETIMEORIGINAL 36867 /* Date and time of original
data generation */
@@ -679,10 +723,71 @@
#define EXIFTAG_SHARPNESS 41994 /* Sharpness */
#define EXIFTAG_DEVICESETTINGDESCRIPTION 41995 /* Device settings description */
#define EXIFTAG_SUBJECTDISTANCERANGE 41996 /* Subject distance range */
-#define EXIFTAG_GAINCONTROL 41991 /* Gain control */
-#define EXIFTAG_GAINCONTROL 41991 /* Gain control */
#define EXIFTAG_IMAGEUNIQUEID 42016 /* Unique image ID */
+/*--: New for EXIF-Version 2.32, May 2019 ... */
+#define EXIFTAG_SENSITIVITYTYPE 34864 /* The SensitivityType tag indicates which one of the parameters of ISO12232 is the PhotographicSensitivity tag. */
+#define EXIFTAG_STANDARDOUTPUTSENSITIVITY 34865 /* This tag indicates the standard output sensitivity value of a camera or input device defined in ISO 12232. */
+#define EXIFTAG_RECOMMENDEDEXPOSUREINDEX 34866 /* recommended exposure index */
+#define EXIFTAG_ISOSPEED 34867 /* ISO speed value */
+#define EXIFTAG_ISOSPEEDLATITUDEYYY 34868 /* ISO speed latitude yyy */
+#define EXIFTAG_ISOSPEEDLATITUDEZZZ 34869 /* ISO speed latitude zzz */
+#define EXIFTAG_OFFSETTIME 36880 /* offset from UTC of the time of DateTime tag. */
+#define EXIFTAG_OFFSETTIMEORIGINAL 36881 /* offset from UTC of the time of DateTimeOriginal tag. */
+#define EXIFTAG_OFFSETTIMEDIGITIZED 36882 /* offset from UTC of the time of DateTimeDigitized tag. */
+#define EXIFTAG_TEMPERATURE 37888 /* Temperature as the ambient situation at the shot in dergee Celsius */
+#define EXIFTAG_HUMIDITY 37889 /* Humidity as the ambient situation at the shot in percent */
+#define EXIFTAG_PRESSURE 37890 /* Pressure as the ambient situation at the shot hecto-Pascal (hPa) */
+#define EXIFTAG_WATERDEPTH 37891 /* WaterDepth as the ambient situation at the shot in meter (m) */
+#define EXIFTAG_ACCELERATION 37892 /* Acceleration (a scalar regardless of direction) as the ambient situation at the shot in units of mGal (10-5 m/s^2) */
+#define EXIFTAG_CAMERAELEVATIONANGLE 37893 /* Elevation/depression. angle of the orientation of the camera(imaging optical axis) as the ambient situation at the shot in degree from -180deg to +180deg. */
+#define EXIFTAG_CAMERAOWNERNAME 42032 /* owner of a camera */
+#define EXIFTAG_BODYSERIALNUMBER 42033 /* serial number of the body of the camera */
+#define EXIFTAG_LENSSPECIFICATION 42034 /* minimum focal length (in mm), maximum focal length (in mm), minimum F number in the minimum focal length, and minimum F number in the maximum focal length, */
+#define EXIFTAG_LENSMAKE 42035 /* the lens manufacturer */
+#define EXIFTAG_LENSMODEL 42036 /* the lens model name and model number */
+#define EXIFTAG_LENSSERIALNUMBER 42037 /* the serial number of the interchangeable lens */
+#define EXIFTAG_GAMMA 42240 /* value of coefficient gamma */
+#define EXIFTAG_COMPOSITEIMAGE 42080 /* composite image */
+#define EXIFTAG_SOURCEIMAGENUMBEROFCOMPOSITEIMAGE 42081 /* source image number of composite image */
+#define EXIFTAG_SOURCEEXPOSURETIMESOFCOMPOSITEIMAGE 42082 /* source exposure times of composite image */
+
+/*
+ * EXIF-GPS tags (Version 2.31, July 2016)
+ */
+#define GPSTAG_VERSIONID 0 /* Indicates the version of GPSInfoIFD. */
+#define GPSTAG_LATITUDEREF 1 /* Indicates whether the latitude is north or south latitude. */
+#define GPSTAG_LATITUDE 2 /* Indicates the latitude. */
+#define GPSTAG_LONGITUDEREF 3 /* Indicates whether the longitude is east or west longitude. */
+#define GPSTAG_LONGITUDE 4 /* Indicates the longitude. */
+#define GPSTAG_ALTITUDEREF 5 /* Indicates the altitude used as the reference altitude. */
+#define GPSTAG_ALTITUDE 6 /* Indicates the altitude based on the reference in GPSAltitudeRef. */
+#define GPSTAG_TIMESTAMP 7 /* Indicates the time as UTC (Coordinated Universal Time). */
+#define GPSTAG_SATELLITES 8 /* Indicates the GPS satellites used for measurements. */
+#define GPSTAG_STATUS 9 /* Indicates the status of the GPS receiver when the image is recorded. */
+#define GPSTAG_MEASUREMODE 10 /* Indicates the GPS measurement mode. */
+#define GPSTAG_DOP 11 /* Indicates the GPS DOP (data degree of precision). */
+#define GPSTAG_SPEEDREF 12 /* Indicates the unit used to express the GPS receiver speed of movement. */
+#define GPSTAG_SPEED 13 /* Indicates the speed of GPS receiver movement. */
+#define GPSTAG_TRACKREF 14 /* Indicates the reference for giving the direction of GPS receiver movement. */
+#define GPSTAG_TRACK 15 /* Indicates the direction of GPS receiver movement. */
+#define GPSTAG_IMGDIRECTIONREF 16 /* Indicates the reference for giving the direction of the image when it is captured. */
+#define GPSTAG_IMGDIRECTION 17 /* Indicates the direction of the image when it was captured. */
+#define GPSTAG_MAPDATUM 18 /* Indicates the geodetic survey data used by the GPS receiver. (e.g. WGS-84) */
+#define GPSTAG_DESTLATITUDEREF 19 /* Indicates whether the latitude of the destination point is north or south latitude. */
+#define GPSTAG_DESTLATITUDE 20 /* Indicates the latitude of the destination point. */
+#define GPSTAG_DESTLONGITUDEREF 21 /* Indicates whether the longitude of the destination point is east or west longitude. */
+#define GPSTAG_DESTLONGITUDE 22 /* Indicates the longitude of the destination point. */
+#define GPSTAG_DESTBEARINGREF 23 /* Indicates the reference used for giving the bearing to the destination point. */
+#define GPSTAG_DESTBEARING 24 /* Indicates the bearing to the destination point. */
+#define GPSTAG_DESTDISTANCEREF 25 /* Indicates the unit used to express the distance to the destination point. */
+#define GPSTAG_DESTDISTANCE 26 /* Indicates the distance to the destination point. */
+#define GPSTAG_PROCESSINGMETHOD 27 /* A character string recording the name of the method used for location finding. */
+#define GPSTAG_AREAINFORMATION 28 /* A character string recording the name of the GPS area. */
+#define GPSTAG_DATESTAMP 29 /* A character string recording date and time information relative to UTC (Coordinated Universal Time). */
+#define GPSTAG_DIFFERENTIAL 30 /* Indicates whether differential correction is applied to the GPS receiver. */
+#define GPSTAG_GPSHPOSITIONINGERROR 31 /* Indicates horizontal positioning errors in meters. */
+
#endif /* _TIFF_ */
/* vim: set ts=8 sts=8 sw=8 noet: */
diff --git a/third_party/libtiff/tiffio.h b/third_party/libtiff/tiffio.h
index 198481d..6274f09 100644
--- a/third_party/libtiff/tiffio.h
+++ b/third_party/libtiff/tiffio.h
@@ -261,8 +261,10 @@
#define LOGLUV_PUBLIC 1
#endif
-#if !defined(__GNUC__) && !defined(__attribute__)
-# define __attribute__(x) /*nothing*/
+#if defined(__GNUC__) || defined(__attribute__)
+# define TIFF_ATTRIBUTE(x) __attribute__(x)
+#else
+# define TIFF_ATTRIBUTE(x) /*nothing*/
#endif
#if defined(c_plusplus) || defined(__cplusplus)
@@ -350,6 +352,7 @@
extern int TIFFReadDirectory(TIFF* tif);
extern int TIFFReadCustomDirectory(TIFF* tif, toff_t diroff, const TIFFFieldArray* infoarray);
extern int TIFFReadEXIFDirectory(TIFF* tif, toff_t diroff);
+extern int TIFFReadGPSDirectory(TIFF* tif, toff_t diroff);
extern uint64 TIFFScanlineSize64(TIFF* tif);
extern tmsize_t TIFFScanlineSize(TIFF* tif);
extern uint64 TIFFRasterScanlineSize64(TIFF* tif);
@@ -400,6 +403,7 @@
extern int TIFFCreateDirectory(TIFF*);
extern int TIFFCreateCustomDirectory(TIFF*,const TIFFFieldArray*);
extern int TIFFCreateEXIFDirectory(TIFF*);
+extern int TIFFCreateGPSDirectory(TIFF*);
extern int TIFFLastDirectory(TIFF*);
extern int TIFFSetDirectory(TIFF*, uint16);
extern int TIFFSetSubDirectory(TIFF*, uint64);
@@ -450,10 +454,10 @@
TIFFMapFileProc, TIFFUnmapFileProc);
extern const char* TIFFFileName(TIFF*);
extern const char* TIFFSetFileName(TIFF*, const char *);
-extern void TIFFError(const char*, const char*, ...) __attribute__((__format__ (__printf__,2,3)));
-extern void TIFFErrorExt(thandle_t, const char*, const char*, ...) __attribute__((__format__ (__printf__,3,4)));
-extern void TIFFWarning(const char*, const char*, ...) __attribute__((__format__ (__printf__,2,3)));
-extern void TIFFWarningExt(thandle_t, const char*, const char*, ...) __attribute__((__format__ (__printf__,3,4)));
+extern void TIFFError(const char*, const char*, ...) TIFF_ATTRIBUTE((__format__ (__printf__,2,3)));
+extern void TIFFErrorExt(thandle_t, const char*, const char*, ...) TIFF_ATTRIBUTE((__format__ (__printf__,3,4)));
+extern void TIFFWarning(const char*, const char*, ...) TIFF_ATTRIBUTE((__format__ (__printf__,2,3)));
+extern void TIFFWarningExt(thandle_t, const char*, const char*, ...) TIFF_ATTRIBUTE((__format__ (__printf__,3,4)));
extern TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler);
extern TIFFErrorHandlerExt TIFFSetErrorHandlerExt(TIFFErrorHandlerExt);
extern TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler);
diff --git a/third_party/libtiff/tiffiop.h b/third_party/libtiff/tiffiop.h
index ab1b052..70371fc 100644
--- a/third_party/libtiff/tiffiop.h
+++ b/third_party/libtiff/tiffiop.h
@@ -367,6 +367,9 @@
extern void _TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th);
extern int _TIFFDataSize(TIFFDataType type);
+/*--: Rational2Double: Return size of TIFFSetGetFieldType in bytes. */
+extern int _TIFFSetGetFieldSize(TIFFSetGetFieldType setgettype);
+
extern void _TIFFsetByteArray(void**, void*, uint32);
extern void _TIFFsetString(char**, char*);
extern void _TIFFsetShortArray(uint16**, uint16*, uint32);
diff --git a/third_party/libtiff/tiffvers.h b/third_party/libtiff/tiffvers.h
index aa3f613..0cce798 100644
--- a/third_party/libtiff/tiffvers.h
+++ b/third_party/libtiff/tiffvers.h
@@ -1,4 +1,4 @@
-#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.1.0\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc."
+#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.2.0\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc."
/*
* This define can be used in code that requires
* compilation-related definitions specific to a
@@ -6,4 +6,4 @@
* version checking should be done based on the
* string returned by TIFFGetVersion.
*/
-#define TIFFLIB_VERSION 20191103
+#define TIFFLIB_VERSION 20201219