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