Upgrade LibTIFF to 4.0.8

This CL upgrades LibTIFF, removing patch files that correspond to bugs
that have been resolved in 4.0.8.

Change-Id: Id99d2fc9b3f25993dcb60cf1558b73674eb725bf
Reviewed-on: https://pdfium-review.googlesource.com/8490
Reviewed-by: dsinclair <dsinclair@chromium.org>
Commit-Queue: Nicolás Peña <npm@chromium.org>
diff --git a/third_party/libtiff/0010-fix-leak-imagebegin.patch b/third_party/libtiff/0010-fix-leak-imagebegin.patch
deleted file mode 100644
index 41aaf91..0000000
--- a/third_party/libtiff/0010-fix-leak-imagebegin.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-diff --git a/third_party/libtiff/tif_getimage.c b/third_party/libtiff/tif_getimage.c
-index 8523793..97fa94d 100644
---- a/third_party/libtiff/tif_getimage.c
-+++ b/third_party/libtiff/tif_getimage.c
-@@ -478,10 +478,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
-        return 1;
- 
-   fail_return:
--        _TIFFfree( img->redcmap );
--        _TIFFfree( img->greencmap );
--        _TIFFfree( img->bluecmap );
--        img->redcmap = img->greencmap = img->bluecmap = NULL;
-+        TIFFRGBAImageEnd(img);
-         return 0;
- }
diff --git a/third_party/libtiff/0011-fix-leak-imagebegin2.patch b/third_party/libtiff/0011-fix-leak-imagebegin2.patch
deleted file mode 100644
index 6d8e402..0000000
--- a/third_party/libtiff/0011-fix-leak-imagebegin2.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-diff --git a/third_party/libtiff/tif_getimage.c b/third_party/libtiff/tif_getimage.c
-index 66ace060e..6e605c441 100644
---- a/third_party/libtiff/tif_getimage.c
-+++ b/third_party/libtiff/tif_getimage.c
-@@ -284,6 +283,13 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
- 	img->redcmap = NULL;
- 	img->greencmap = NULL;
- 	img->bluecmap = NULL;
-+	img->Map = NULL;
-+	img->BWmap = NULL;
-+	img->PALmap = NULL;
-+	img->ycbcr = NULL;
-+	img->cielab = NULL;
-+	img->UaToAa = NULL;
-+	img->Bitdepth16To8 = NULL;
- 	img->req_orientation = ORIENTATION_BOTLEFT;     /* It is the default */
- 
- 	img->tif = tif;
-@@ -476,13 +468,6 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
- 			    photoTag, img->photometric);
-                         goto fail_return;
- 	}
--	img->Map = NULL;
--	img->BWmap = NULL;
--	img->PALmap = NULL;
--	img->ycbcr = NULL;
--	img->cielab = NULL;
--	img->UaToAa = NULL;
--	img->Bitdepth16To8 = NULL;
- 	TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width);
- 	TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height);
- 	TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation);
diff --git a/third_party/libtiff/0012-initialize-tif-rawdata.patch b/third_party/libtiff/0012-initialize-tif-rawdata.patch
deleted file mode 100644
index 2543b89..0000000
--- a/third_party/libtiff/0012-initialize-tif-rawdata.patch
+++ /dev/null
@@ -1,14 +0,0 @@
-diff --git a/third_party/libtiff/tif_read.c b/third_party/libtiff/tif_read.c
-index 5cb419bd4..548b1f5ea 100644
---- a/third_party/libtiff/tif_read.c
-+++ b/third_party/libtiff/tif_read.c
-@@ -936,6 +936,9 @@ TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size)
- 		    return (0);
- 		}
- 		tif->tif_rawdata = (uint8*) _TIFFmalloc(tif->tif_rawdatasize);
-+		if (tif->tif_rawdata)
-+			memset(tif->tif_rawdata, 0, tif->tif_rawdatasize);
-+
- 		tif->tif_flags |= TIFF_MYBUFFER;
- 	}
- 	if (tif->tif_rawdata == NULL) {
diff --git a/third_party/libtiff/0013-validate-refblackwhite.patch b/third_party/libtiff/0013-validate-refblackwhite.patch
deleted file mode 100644
index a314fbd..0000000
--- a/third_party/libtiff/0013-validate-refblackwhite.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-diff --git a/third_party/libtiff/tif_dir.c b/third_party/libtiff/tif_dir.c
-index 73212c02d..16ce3d3ce 100644
---- a/third_party/libtiff/tif_dir.c
-+++ b/third_party/libtiff/tif_dir.c
-@@ -426,6 +426,14 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
- 	case TIFFTAG_REFERENCEBLACKWHITE:
- 		/* XXX should check for null range */
- 		_TIFFsetFloatArray(&td->td_refblackwhite, va_arg(ap, float*), 6);
-+		for (int i = 0; i < 6; i++) {
-+			if (isnan(td->td_refblackwhite[i])) {
-+				if (i % 2 == 0)
-+					td->td_refblackwhite[i] = 0;
-+				else
-+					td->td_refblackwhite[i] = pow(2, td->td_bitspersample) - 1;
-+			}
-+		}
- 		break;
- 	case TIFFTAG_INKNAMES:
- 		v = (uint16) va_arg(ap, uint16_vap);
diff --git a/third_party/libtiff/0014-cast-to-unsigned-in-putagreytile.patch b/third_party/libtiff/0014-cast-to-unsigned-in-putagreytile.patch
deleted file mode 100644
index 00336b1..0000000
--- a/third_party/libtiff/0014-cast-to-unsigned-in-putagreytile.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/third_party/libtiff/tif_getimage.c b/third_party/libtiff/tif_getimage.c
-index 1cf6ac6b4..2861cdd1e 100644
---- a/third_party/libtiff/tif_getimage.c
-+++ b/third_party/libtiff/tif_getimage.c
-@@ -1281,7 +1281,7 @@ DECLAREContigPutFunc(putagreytile)
-     while (h-- > 0) {
-        for (x = w; x-- > 0;)
-         {
--            *cp++ = BWmap[*pp][0] & (*(pp+1) << 24 | ~A1);
-+            *cp++ = BWmap[*pp][0] & ((uint32)*(pp+1) << 24 | ~A1);
-             pp += samplesperpixel;
-         }
-        cp += toskew;
diff --git a/third_party/libtiff/0015-fix-leaks-in-tif_ojpeg.patch b/third_party/libtiff/0015-fix-leaks-in-tif_ojpeg.patch
deleted file mode 100644
index d2ddd4a..0000000
--- a/third_party/libtiff/0015-fix-leaks-in-tif_ojpeg.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-diff --git a/third_party/libtiff/tif_ojpeg.c b/third_party/libtiff/tif_ojpeg.c
-index e128887bf..465f9ebc4 100644
---- a/third_party/libtiff/tif_ojpeg.c
-+++ b/third_party/libtiff/tif_ojpeg.c
-@@ -1791,7 +1791,12 @@ OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif)
- 			TIFFSeekFile(tif,sp->qtable_offset[m],SEEK_SET); 
- 			p=(uint32)TIFFReadFile(tif,&ob[sizeof(uint32)+5],64);
- 			if (p!=64)
-+			{
-+				_TIFFfree(ob);
- 				return(0);
-+			}
-+			if (sp->qtable[m]!=0)
-+				_TIFFfree(sp->qtable[m]);
- 			sp->qtable[m]=ob;
- 			sp->sof_tq[m]=m;
- 		}
-@@ -1860,7 +1855,12 @@ OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif)
- 				rb[sizeof(uint32)+5+n]=o[n];
- 			p=(uint32)TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q);
- 			if (p!=q)
-+			{
-+				_TIFFfree(rb);
- 				return(0);
-+			}
-+			if (sp->dctable[m]!=0)
-+				_TIFFfree(sp->dctable[m]);
- 			sp->dctable[m]=rb;
- 			sp->sos_tda[m]=(m<<4);
- 		}
-@@ -1929,7 +1919,12 @@ OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif)
- 				rb[sizeof(uint32)+5+n]=o[n];
- 			p=(uint32)TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q);
- 			if (p!=q)
-+			{
-+				_TIFFfree(rb);
- 				return(0);
-+			}
-+			if (sp->actable[m])
-+				_TIFFfree(sp->actable[m]);
- 			sp->actable[m]=rb;
- 			sp->sos_tda[m]=(sp->sos_tda[m]|m);
- 		}
diff --git a/third_party/libtiff/0018-fix-leak-in-PredictorSetupDecode.patch b/third_party/libtiff/0018-fix-leak-in-PredictorSetupDecode.patch
deleted file mode 100644
index e7758eb..0000000
--- a/third_party/libtiff/0018-fix-leak-in-PredictorSetupDecode.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-diff --git a/third_party/libtiff/tif_predict.c b/third_party/libtiff/tif_predict.c
-index 1bb78e209..0b185d2e2 100644
---- a/third_party/libtiff/tif_predict.c
-+++ b/third_party/libtiff/tif_predict.c
-@@ -118,7 +118,10 @@ PredictorSetupDecode(TIFF* tif)
- 	TIFFDirectory* td = &tif->tif_dir;
- 
- 	if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
-+	{
-+		(*tif->tif_cleanup)(tif);
- 		return 0;
-+	}
- 
- 	if (sp->predictor == 2) {
- 		switch (td->td_bitspersample) {
diff --git a/third_party/libtiff/0019-oom-TIFFReadDirEntryArray.patch b/third_party/libtiff/0019-oom-TIFFReadDirEntryArray.patch
deleted file mode 100644
index 1144e06..0000000
--- a/third_party/libtiff/0019-oom-TIFFReadDirEntryArray.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-diff --git a/third_party/libtiff/tif_dirread.c b/third_party/libtiff/tif_dirread.c
-index 7dd944483..d50b39a80 100644
---- a/third_party/libtiff/tif_dirread.c
-+++ b/third_party/libtiff/tif_dirread.c
-@@ -790,44 +790,43 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* d
-        *count=(uint32)direntry->tdir_count;
-        datasize=(*count)*typesize;
-        assert((tmsize_t)datasize>0);
--       data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray");
--       if (data==0)
--               return(TIFFReadDirEntryErrAlloc);
-+       const uint32 small_alloc_threshold=(tif->tif_flags&TIFF_BIGTIFF)? 8 : 4;
-+       if (datasize <= small_alloc_threshold)
-+       {
-+               data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray");
-+               if (data==0)
-+                       return(TIFFReadDirEntryErrAlloc);
-+               _TIFFmemcpy(data,&direntry->tdir_offset,datasize);
-+               *value=data;
-+               return(TIFFReadDirEntryErrOk);
-+       }
-+       uint64 offset;
-        if (!(tif->tif_flags&TIFF_BIGTIFF))
-        {
--               if (datasize<=4)
--                       _TIFFmemcpy(data,&direntry->tdir_offset,datasize);
--               else
--               {
--                       enum TIFFReadDirEntryErr err;
--                       uint32 offset = direntry->tdir_offset.toff_long;
--                       if (tif->tif_flags&TIFF_SWAB)
--                               TIFFSwabLong(&offset);
--                       err=TIFFReadDirEntryData(tif,(uint64)offset,(tmsize_t)datasize,data);
--                       if (err!=TIFFReadDirEntryErrOk)
--                       {
--                               _TIFFfree(data);
--                               return(err);
--                       }
--               }
-+               uint32 small_offset=direntry->tdir_offset.toff_long;
-+               if (tif->tif_flags&TIFF_SWAB)
-+                       TIFFSwabLong(&small_offset);
-+               offset=(uint64)small_offset;
-        }
-        else
-        {
--               if (datasize<=8)
--                       _TIFFmemcpy(data,&direntry->tdir_offset,datasize);
--               else
--               {
--                       enum TIFFReadDirEntryErr err;
--                       uint64 offset = direntry->tdir_offset.toff_long8;
--                       if (tif->tif_flags&TIFF_SWAB)
--                               TIFFSwabLong8(&offset);
--                       err=TIFFReadDirEntryData(tif,offset,(tmsize_t)datasize,data);
--                       if (err!=TIFFReadDirEntryErrOk)
--                       {
--                               _TIFFfree(data);
--                               return(err);
--                       }
--               }
-+               offset = direntry->tdir_offset.toff_long8;
-+               if (tif->tif_flags&TIFF_SWAB)
-+                       TIFFSwabLong8(&offset);
-+       }
-+       if ((uint64)(-1) - offset < datasize)
-+               return(TIFFReadDirEntryErrIo);
-+       const uint64 size=isMapped(tif)? (uint64)tif->tif_size : TIFFGetFileSize(tif);
-+       if (offset + datasize > size)
-+               return(TIFFReadDirEntryErrIo);
-+       data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray");
-+       if (data==0)
-+               return(TIFFReadDirEntryErrAlloc);
-+       enum TIFFReadDirEntryErr err=TIFFReadDirEntryData(tif,offset,(tmsize_t)datasize,data);
-+       if (err!=TIFFReadDirEntryErrOk)
-+       {
-+               _TIFFfree(data);
-+               return(err);
-        }
-        *value=data;
-        return(TIFFReadDirEntryErrOk);
diff --git a/third_party/libtiff/0020-upstream-security-fixes.patch b/third_party/libtiff/0020-upstream-security-fixes.patch
deleted file mode 100644
index 139b79d..0000000
--- a/third_party/libtiff/0020-upstream-security-fixes.patch
+++ /dev/null
@@ -1,270 +0,0 @@
-diff --git a/third_party/libtiff/tif_dir.c b/third_party/libtiff/tif_dir.c
-index 4b3632ab1..81b849374 100644
---- a/third_party/libtiff/tif_dir.c
-+++ b/third_party/libtiff/tif_dir.c
-@@ -862,6 +862,32 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
-        if( fip == NULL ) /* cannot happen since TIFFGetField() already checks it */
-            return 0;
-        
-+       if( tag == TIFFTAG_NUMBEROFINKS )
-+       {
-+               int i;
-+               for (i = 0; i < td->td_customValueCount; i++) {
-+                       uint16 val;
-+                       TIFFTagValue *tv = td->td_customValues + i;
-+                       if (tv->info->field_tag != tag)
-+                               continue;
-+                       val = *(uint16 *)tv->value;
-+                       /* Truncate to SamplesPerPixel, since the */
-+                       /* setting code for INKNAMES assume that there are SamplesPerPixel */
-+                       /* inknames. */
-+                       /* Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2599 */
-+                       if( val > td->td_samplesperpixel )
-+                       {
-+                               TIFFWarningExt(tif->tif_clientdata,"_TIFFVGetField",
-+                                                          "Truncating NumberOfInks from %u to %u",
-+                                                          val, td->td_samplesperpixel);
-+                               val = td->td_samplesperpixel;
-+                       }
-+                       *va_arg(ap, uint16*) = val;
-+                       return 1;
-+               }
-+               return 0;
-+       }
-+
-        /*
-         * We want to force the custom code to be used for custom
-         * fields even if the tag happens to match a well known 
-diff --git a/third_party/libtiff/tif_dirread.c b/third_party/libtiff/tif_dirread.c
-index d50b39a80..7dbcf6d86 100644
---- a/third_party/libtiff/tif_dirread.c
-+++ b/third_party/libtiff/tif_dirread.c
-@@ -5503,8 +5503,7 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
-        uint64 rowblockbytes;
-        uint64 stripbytes;
-        uint32 strip;
--       uint64 nstrips64;
--       uint32 nstrips32;
-+       uint32 nstrips;
-        uint32 rowsperstrip;
-        uint64* newcounts;
-        uint64* newoffsets;
-@@ -5535,18 +5534,17 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
-            return;
- 
-        /*
--        * never increase the number of strips in an image
-+        * never increase the number of rows per strip
-         */
-        if (rowsperstrip >= td->td_rowsperstrip)
-                return;
--       nstrips64 = TIFFhowmany_64(bytecount, stripbytes);
--       if ((nstrips64==0)||(nstrips64>0xFFFFFFFF)) /* something is wonky, do nothing. */
--           return;
--       nstrips32 = (uint32)nstrips64;
-+       nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip);
-+       if( nstrips == 0 )
-+               return;
- 
--       newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64),
-+       newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
-                                "for chopped \"StripByteCounts\" array");
--       newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64),
-+       newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
-                                "for chopped \"StripOffsets\" array");
-        if (newcounts == NULL || newoffsets == NULL) {
-                /*
-@@ -5563,18 +5561,18 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
-         * Fill the strip information arrays with new bytecounts and offsets
-         * that reflect the broken-up format.
-         */
--       for (strip = 0; strip < nstrips32; strip++) {
-+       for (strip = 0; strip < nstrips; strip++) {
-                if (stripbytes > bytecount)
-                        stripbytes = bytecount;
-                newcounts[strip] = stripbytes;
--               newoffsets[strip] = offset;
-+               newoffsets[strip] = stripbytes ? offset : 0;
-                offset += stripbytes;
-                bytecount -= stripbytes;
-        }
-        /*
-         * Replace old single strip info with multi-strip info.
-         */
--       td->td_stripsperimage = td->td_nstrips = nstrips32;
-+       td->td_stripsperimage = td->td_nstrips = nstrips;
-        TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
- 
-        _TIFFfree(td->td_stripbytecount);
-diff --git a/third_party/libtiff/tif_luv.c b/third_party/libtiff/tif_luv.c
-index ca08f30a7..220c15034 100644
---- a/third_party/libtiff/tif_luv.c
-+++ b/third_party/libtiff/tif_luv.c
-@@ -158,6 +158,7 @@
- typedef struct logLuvState LogLuvState;
- 
- struct logLuvState {
-+       int                     encoder_state;  /* 1 if encoder correctly initialized */
-        int                     user_datafmt;   /* user data format */
-        int                     encode_meth;    /* encoding method */
-        int                     pixel_size;     /* bytes per pixel */
-@@ -1552,6 +1553,7 @@ LogLuvSetupEncode(TIFF* tif)
-                    td->td_photometric, "must be either LogLUV or LogL");
-                break;
-        }
-+       sp->encoder_state = 1;
-        return (1);
- notsupported:
-        TIFFErrorExt(tif->tif_clientdata, module,
-@@ -1563,19 +1565,27 @@ notsupported:
- static void
- LogLuvClose(TIFF* tif)
- {
-+       LogLuvState* sp = (LogLuvState*) tif->tif_data;
-        TIFFDirectory *td = &tif->tif_dir;
- 
-+       assert(sp != 0);
-        /*
-         * For consistency, we always want to write out the same
-         * bitspersample and sampleformat for our TIFF file,
-         * regardless of the data format being used by the application.
-         * Since this routine is called after tags have been set but
-         * before they have been recorded in the file, we reset them here.
-+        * Note: this is really a nasty approach. See PixarLogClose
-         */
--       td->td_samplesperpixel =
--           (td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3;
--       td->td_bitspersample = 16;
--       td->td_sampleformat = SAMPLEFORMAT_INT;
-+       if( sp->encoder_state )
-+       {
-+               /* See PixarLogClose. Might avoid issues with tags whose size depends
-+                * on those below, but not completely sure this is enough. */
-+               td->td_samplesperpixel =
-+                       (td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3;
-+               td->td_bitspersample = 16;
-+               td->td_sampleformat = SAMPLEFORMAT_INT;
-+       }
- }
- 
- static void
-diff --git a/third_party/libtiff/tif_ojpeg.c b/third_party/libtiff/tif_ojpeg.c
-index e128887bf..cb84be96b 100644
---- a/third_party/libtiff/tif_ojpeg.c
-+++ b/third_party/libtiff/tif_ojpeg.c
-@@ -253,6 +253,7 @@ typedef enum {
- 
- typedef struct {
-        TIFF* tif;
-+       int decoder_ok;
-        #ifndef LIBJPEG_ENCAP_EXTERNAL
-        JMP_BUF exit_jmpbuf;
-        #endif
-@@ -731,6 +732,7 @@ OJPEGPreDecode(TIFF* tif, uint16 s)
-                }
-                sp->write_curstrile++;
-        }
-+       sp->decoder_ok = 1;
-        return(1);
- }
- 
-@@ -793,8 +795,14 @@ OJPEGPreDecodeSkipScanlines(TIFF* tif)
- static int
- OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
- {
-+       static const char module[]="OJPEGDecode";
-        OJPEGState* sp=(OJPEGState*)tif->tif_data;
-        (void)s;
-+       if( !sp->decoder_ok )
-+       {
-+               TIFFErrorExt(tif->tif_clientdata,module,"Cannot decode: decoder not correctly initialized");
-+               return 0;
-+       }
-        if (sp->libjpeg_jpeg_query_style==0)
-        {
-                if (OJPEGDecodeRaw(tif,buf,cc)==0)
-diff --git a/third_party/libtiff/tif_pixarlog.c b/third_party/libtiff/tif_pixarlog.c
-index 8f6ca8f63..e6574ec3d 100644
---- a/third_party/libtiff/tif_pixarlog.c
-+++ b/third_party/libtiff/tif_pixarlog.c
-@@ -1233,8 +1233,10 @@ PixarLogPostEncode(TIFF* tif)
- static void
- PixarLogClose(TIFF* tif)
- {
-+       PixarLogState* sp = (PixarLogState*) tif->tif_data;
-        TIFFDirectory *td = &tif->tif_dir;
- 
-+       assert(sp != 0);
-        /* In a really sneaky (and really incorrect, and untruthful, and
-         * troublesome, and error-prone) maneuver that completely goes against
-         * the spirit of TIFF, and breaks TIFF, on close, we covertly
-@@ -1243,8 +1245,19 @@ PixarLogClose(TIFF* tif)
-         * readers that don't know about PixarLog, or how to set
-         * the PIXARLOGDATFMT pseudo-tag.
-         */
--       td->td_bitspersample = 8;
--       td->td_sampleformat = SAMPLEFORMAT_UINT;
-+
-+       if (sp->state&PLSTATE_INIT) {
-+               /* We test the state to avoid an issue such as in
-+                * http://bugzilla.maptools.org/show_bug.cgi?id=2604
-+                * What appends in that case is that the bitspersample is 1 and
-+                * a TransferFunction is set. The size of the TransferFunction
-+                * depends on 1<<bitspersample. So if we increase it, an access
-+                * out of the buffer will happen at directory flushing.
-+                * Another option would be to clear those targs. 
-+                */
-+               td->td_bitspersample = 8;
-+               td->td_sampleformat = SAMPLEFORMAT_UINT;
-+       }
- }
- 
- static void
-diff --git a/third_party/libtiff/tif_read.c b/third_party/libtiff/tif_read.c
-index 795153bbf..1ba100e54 100644
---- a/third_party/libtiff/tif_read.c
-+++ b/third_party/libtiff/tif_read.c
-@@ -346,7 +346,7 @@ TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
-        rowsperstrip=td->td_rowsperstrip;
-        if (rowsperstrip>td->td_imagelength)
-                rowsperstrip=td->td_imagelength;
--       stripsperplane=((td->td_imagelength+rowsperstrip-1)/rowsperstrip);
-+       stripsperplane= TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip);
-        stripinplane=(strip%stripsperplane);
-        plane=(uint16)(strip/stripsperplane);
-        rows=td->td_imagelength-stripinplane*rowsperstrip;
-diff --git a/third_party/libtiff/tif_strip.c b/third_party/libtiff/tif_strip.c
-index b6098dd31..3b55285cd 100644
---- a/third_party/libtiff/tif_strip.c
-+++ b/third_party/libtiff/tif_strip.c
-@@ -63,15 +63,6 @@ TIFFNumberOfStrips(TIFF* tif)
-        TIFFDirectory *td = &tif->tif_dir;
-        uint32 nstrips;
- 
--    /* If the value was already computed and store in td_nstrips, then return it,
--       since ChopUpSingleUncompressedStrip might have altered and resized the
--       since the td_stripbytecount and td_stripoffset arrays to the new value
--       after the initial affectation of td_nstrips = TIFFNumberOfStrips() in
--       tif_dirread.c ~line 3612.
--       See http://bugzilla.maptools.org/show_bug.cgi?id=2587 */
--    if( td->td_nstrips )
--        return td->td_nstrips;
--
-        nstrips = (td->td_rowsperstrip == (uint32) -1 ? 1 :
-             TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip));
-        if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
-diff --git a/third_party/libtiff/tiffiop.h b/third_party/libtiff/tiffiop.h
-index b6db1e932..1925a6b5e 100644
---- a/third_party/libtiff/tiffiop.h
-+++ b/third_party/libtiff/tiffiop.h
-@@ -249,6 +249,10 @@ struct tiff {
- #define TIFFhowmany_32(x, y) (((uint32)x < (0xffffffff - (uint32)(y-1))) ? \
-                           ((((uint32)(x))+(((uint32)(y))-1))/((uint32)(y))) : \
-                           0U)
-+/* Variant of TIFFhowmany_32() that doesn't return 0 if x close to MAXUINT. */
-+/* Caution: TIFFhowmany_32_maxuint_compat(x,y)*y might overflow */
-+#define TIFFhowmany_32_maxuint_compat(x, y) \
-+                          (((uint32)(x) / (uint32)(y)) + ((((uint32)(x) % (uint32)(y)) != 0) ? 1 : 0))
- #define TIFFhowmany8_32(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3)
- #define TIFFroundup_32(x, y) (TIFFhowmany_32(x,y)*(y))
- #define TIFFhowmany_64(x, y) ((((uint64)(x))+(((uint64)(y))-1))/((uint64)(y)))
diff --git a/third_party/libtiff/0021-oom-TIFFFillStrip.patch b/third_party/libtiff/0021-oom-TIFFFillStrip.patch
deleted file mode 100644
index a64dc5e..0000000
--- a/third_party/libtiff/0021-oom-TIFFFillStrip.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-diff --git a/third_party/libtiff/tif_read.c b/third_party/libtiff/tif_read.c
-index 1ba100e54..c25e7e79f 100644
---- a/third_party/libtiff/tif_read.c
-+++ b/third_party/libtiff/tif_read.c
-@@ -616,6 +616,13 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
-                                TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
-                                return(0);
-                        }
-+                       const tmsize_t size=isMapped(tif)? tif->tif_size : (tmsize_t)TIFFGetFileSize(tif);
-+                       if (bytecountm > size) {
-+                               TIFFErrorExt(tif->tif_clientdata, module,
-+                                       "Requested read strip size %lu is too large",
-+                                       (unsigned long) strip);
-+                               return (0);
-+                       }
-                        if (bytecountm > tif->tif_rawdatasize) {
-                                tif->tif_curstrip = NOSTRIP;
-                                if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
diff --git a/third_party/libtiff/0022-upstream-patch-0012.patch b/third_party/libtiff/0022-upstream-patch-0012.patch
deleted file mode 100644
index ce9b5eb..0000000
--- a/third_party/libtiff/0022-upstream-patch-0012.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-diff --git a/third_party/libtiff/tif_read.c b/third_party/libtiff/tif_read.c
-index c25e7e79f..47686a473 100644
---- a/third_party/libtiff/tif_read.c
-+++ b/third_party/libtiff/tif_read.c
-@@ -983,9 +983,9 @@ TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size)
-                                 "Invalid buffer size");
-                    return (0);
-                }
--               tif->tif_rawdata = (uint8*) _TIFFmalloc(tif->tif_rawdatasize);
--               if (tif->tif_rawdata)
--                       memset(tif->tif_rawdata, 0, tif->tif_rawdatasize);
-+               /* Initialize to zero to avoid uninitialized buffers in case of */
-+                /* short reads (http://bugzilla.maptools.org/show_bug.cgi?id=2651) */
-+               tif->tif_rawdata = (uint8*) _TIFFcalloc(1, tif->tif_rawdatasize);
- 
-                tif->tif_flags |= TIFF_MYBUFFER;
-        }
-diff --git a/third_party/libtiff/tiffio.h b/third_party/libtiff/tiffio.h
-index dd6c9a429..7d0da761f 100644
---- a/third_party/libtiff/tiffio.h
-+++ b/third_party/libtiff/tiffio.h
-@@ -293,6 +293,7 @@ extern TIFFCodec* TIFFGetConfiguredCODECs(void);
-  */
- 
- extern void* _TIFFmalloc(tmsize_t s);
-+extern void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz);
- extern void* _TIFFrealloc(void* p, tmsize_t s);
- extern void _TIFFmemset(void* p, int v, tmsize_t c);
- extern void _TIFFmemcpy(void* d, const void* s, tmsize_t c);
diff --git a/third_party/libtiff/0023-upstream-security-fixes.patch b/third_party/libtiff/0023-upstream-security-fixes.patch
deleted file mode 100644
index 3566e48..0000000
--- a/third_party/libtiff/0023-upstream-security-fixes.patch
+++ /dev/null
@@ -1,353 +0,0 @@
-diff --git a/third_party/libtiff/tif_dir.c b/third_party/libtiff/tif_dir.c
-index 81b849374..72148411f 100644
---- a/third_party/libtiff/tif_dir.c
-+++ b/third_party/libtiff/tif_dir.c
-@@ -31,6 +31,7 @@
-  * (and also some miscellaneous stuff)
-  */
- #include "tiffiop.h"
-+#include <float.h>
- 
- /*
-  * These are used in the backwards compatibility code...
-@@ -154,6 +155,15 @@ bad:
-        return (0);
- }
- 
-+static float TIFFClampDoubleToFloat( double val )
-+{
-+    if( val > FLT_MAX )
-+        return FLT_MAX;
-+    if( val < -FLT_MAX )
-+        return -FLT_MAX;
-+    return (float)val;
-+}
-+
- static int
- _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
- {
-@@ -312,13 +322,13 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
-         dblval = va_arg(ap, double);
-         if( dblval < 0 )
-             goto badvaluedouble;
--               td->td_xresolution = (float) dblval;
-+               td->td_xresolution = TIFFClampDoubleToFloat( dblval );
-                break;
-        case TIFFTAG_YRESOLUTION:
-         dblval = va_arg(ap, double);
-         if( dblval < 0 )
-             goto badvaluedouble;
--               td->td_yresolution = (float) dblval;
-+               td->td_yresolution = TIFFClampDoubleToFloat( dblval );
-                break;
-        case TIFFTAG_PLANARCONFIG:
-                v = (uint16) va_arg(ap, uint16_vap);
-@@ -327,10 +337,10 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
-                td->td_planarconfig = (uint16) v;
-                break;
-        case TIFFTAG_XPOSITION:
--               td->td_xposition = (float) va_arg(ap, double);
-+               td->td_xposition = TIFFClampDoubleToFloat( va_arg(ap, double) );
-                break;
-        case TIFFTAG_YPOSITION:
--               td->td_yposition = (float) va_arg(ap, double);
-+               td->td_yposition = TIFFClampDoubleToFloat( va_arg(ap, double) );
-                break;
-        case TIFFTAG_RESOLUTIONUNIT:
-                v = (uint16) va_arg(ap, uint16_vap);
-diff --git a/third_party/libtiff/tif_dirread.c b/third_party/libtiff/tif_dirread.c
-index 7dbcf6d86..0926e1625 100644
---- a/third_party/libtiff/tif_dirread.c
-+++ b/third_party/libtiff/tif_dirread.c
-@@ -40,6 +40,7 @@
-  */
- 
- #include "tiffiop.h"
-+#include <float.h>
- 
- #define IGNORE 0          /* tag placeholder used below */
- #define FAILED_FII    ((uint32) -1)
-@@ -2405,7 +2406,14 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryFloatArray(TIFF* tif, TIFFDirEnt
-                                ma=(double*)origdata;
-                                mb=data;
-                                for (n=0; n<count; n++)
--                                       *mb++=(float)(*ma++);
-+                               {
-+                                       double val = *ma++;
-+                                       if( val > FLT_MAX )
-+                                               val = FLT_MAX;
-+                                       else if( val < -FLT_MAX )
-+                                               val = -FLT_MAX;
-+                                       *mb++=(float)val;
-+                               }
-                        }
-                        break;
-        }
-@@ -2871,7 +2879,10 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedRational(TIFF* tif, TIFFD
-                m.l = direntry->tdir_offset.toff_long8;
-        if (tif->tif_flags&TIFF_SWAB)
-                TIFFSwabArrayOfLong(m.i,2);
--       if (m.i[0]==0)
-+       /* Not completely sure what we should do when m.i[1]==0, but some */
-+       /* sanitizers do not like division by 0.0: */
-+       /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */
-+       if (m.i[0]==0 || m.i[1]==0)
-                *value=0.0;
-        else
-                *value=(double)m.i[0]/(double)m.i[1];
-@@ -2899,7 +2910,10 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSrational(TIFF* tif, TIFF
-                m.l=direntry->tdir_offset.toff_long8;
-        if (tif->tif_flags&TIFF_SWAB)
-                TIFFSwabArrayOfLong(m.i,2);
--       if ((int32)m.i[0]==0)
-+       /* Not completely sure what we should do when m.i[1]==0, but some */
-+       /* sanitizers do not like division by 0.0: */
-+       /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */
-+       if ((int32)m.i[0]==0 || m.i[1]==0)
-                *value=0.0;
-        else
-                *value=(double)((int32)m.i[0])/(double)m.i[1];
-diff --git a/third_party/libtiff/tif_dirwrite.c b/third_party/libtiff/tif_dirwrite.c
-index d34f6f611..f4d8034ec 100644
---- a/third_party/libtiff/tif_dirwrite.c
-+++ b/third_party/libtiff/tif_dirwrite.c
-@@ -30,6 +30,7 @@
-  * Directory Write Support Routines.
-  */
- #include "tiffiop.h"
-+#include <float.h>
- 
- #ifdef HAVE_IEEEFP
- #define TIFFCvtNativeToIEEEFloat(tif, n, fp)
-@@ -939,6 +940,69 @@ bad:
-        return(0);
- }
- 
-+static float TIFFClampDoubleToFloat( double val )
-+{
-+    if( val > FLT_MAX )
-+        return FLT_MAX;
-+    if( val < -FLT_MAX )
-+        return -FLT_MAX;
-+    return (float)val;
-+}
-+
-+static int8 TIFFClampDoubleToInt8( double val )
-+{
-+    if( val > 127 )
-+        return 127;
-+    if( val < -128 || val != val )
-+        return -128;
-+    return (int8)val;
-+}
-+
-+static int16 TIFFClampDoubleToInt16( double val )
-+{
-+    if( val > 32767 )
-+        return 32767;
-+    if( val < -32768 || val != val )
-+        return -32768;
-+    return (int16)val;
-+}
-+
-+static int32 TIFFClampDoubleToInt32( double val )
-+{
-+    if( val > 0x7FFFFFFF )
-+        return 0x7FFFFFFF;
-+    if( val < -0x7FFFFFFF-1 || val != val )
-+        return -0x7FFFFFFF-1;
-+    return (int32)val;
-+}
-+
-+static uint8 TIFFClampDoubleToUInt8( double val )
-+{
-+    if( val < 0 )
-+        return 0;
-+    if( val > 255 || val != val )
-+        return 255;
-+    return (uint8)val;
-+}
-+
-+static uint16 TIFFClampDoubleToUInt16( double val )
-+{
-+    if( val < 0 )
-+        return 0;
-+    if( val > 65535 || val != val )
-+        return 65535;
-+    return (uint16)val;
-+}
-+
-+static uint32 TIFFClampDoubleToUInt32( double val )
-+{
-+    if( val < 0 )
-+        return 0;
-+    if( val > 0xFFFFFFFFU || val != val )
-+        return 0xFFFFFFFFU;
-+    return (uint32)val;
-+}
-+
- static int
- TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
- {
-@@ -959,7 +1023,7 @@ TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* di
-                        if (tif->tif_dir.td_bitspersample<=32)
-                        {
-                                for (i = 0; i < count; ++i)
--                                       ((float*)conv)[i] = (float)value[i];
-+                                       ((float*)conv)[i] = TIFFClampDoubleToFloat(value[i]);
-                                ok = TIFFWriteDirectoryTagFloatArray(tif,ndir,dir,tag,count,(float*)conv);
-                        }
-                        else
-@@ -971,19 +1035,19 @@ TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* di
-                        if (tif->tif_dir.td_bitspersample<=8)
-                        {
-                                for (i = 0; i < count; ++i)
--                                       ((int8*)conv)[i] = (int8)value[i];
-+                                       ((int8*)conv)[i] = TIFFClampDoubleToInt8(value[i]);
-                                ok = TIFFWriteDirectoryTagSbyteArray(tif,ndir,dir,tag,count,(int8*)conv);
-                        }
-                        else if (tif->tif_dir.td_bitspersample<=16)
-                        {
-                                for (i = 0; i < count; ++i)
--                                       ((int16*)conv)[i] = (int16)value[i];
-+                                       ((int16*)conv)[i] = TIFFClampDoubleToInt16(value[i]);
-                                ok = TIFFWriteDirectoryTagSshortArray(tif,ndir,dir,tag,count,(int16*)conv);
-                        }
-                        else
-                        {
-                                for (i = 0; i < count; ++i)
--                                       ((int32*)conv)[i] = (int32)value[i];
-+                                       ((int32*)conv)[i] = TIFFClampDoubleToInt32(value[i]);
-                                ok = TIFFWriteDirectoryTagSlongArray(tif,ndir,dir,tag,count,(int32*)conv);
-                        }
-                        break;
-@@ -991,19 +1055,19 @@ TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* di
-                        if (tif->tif_dir.td_bitspersample<=8)
-                        {
-                                for (i = 0; i < count; ++i)
--                                       ((uint8*)conv)[i] = (uint8)value[i];
-+                                       ((uint8*)conv)[i] = TIFFClampDoubleToUInt8(value[i]);
-                                ok = TIFFWriteDirectoryTagByteArray(tif,ndir,dir,tag,count,(uint8*)conv);
-                        }
-                        else if (tif->tif_dir.td_bitspersample<=16)
-                        {
-                                for (i = 0; i < count; ++i)
--                                       ((uint16*)conv)[i] = (uint16)value[i];
-+                                       ((uint16*)conv)[i] = TIFFClampDoubleToUInt16(value[i]);
-                                ok = TIFFWriteDirectoryTagShortArray(tif,ndir,dir,tag,count,(uint16*)conv);
-                        }
-                        else
-                        {
-                                for (i = 0; i < count; ++i)
--                                       ((uint32*)conv)[i] = (uint32)value[i];
-+                                       ((uint32*)conv)[i] = TIFFClampDoubleToUInt32(value[i]);
-                                ok = TIFFWriteDirectoryTagLongArray(tif,ndir,dir,tag,count,(uint32*)conv);
-                        }
-                        break;
-@@ -2094,15 +2158,25 @@ TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* d
- static int
- TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
- {
-+       static const char module[] = "TIFFWriteDirectoryTagCheckedRational";
-        uint32 m[2];
--       assert(value>=0.0);
-        assert(sizeof(uint32)==4);
--       if (value<=0.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;
-+       }
-+       else if (value==0.0)
-        {
-                m[0]=0;
-                m[1]=1;
-        }
--       else if (value==(double)(uint32)value)
-+       else if (value <= 0xFFFFFFFFU && value==(double)(uint32)value)
-        {
-                m[0]=(uint32)value;
-                m[1]=1;
-@@ -2143,12 +2217,13 @@ TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry*
-        }
-        for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++)
-        {
--               if (*na<=0.0)
-+               if (*na<=0.0 || *na != *na)
-                {
-                        nb[0]=0;
-                        nb[1]=1;
-                }
--               else if (*na==(float)(uint32)(*na))
-+               else if (*na >= 0 && *na <= (float)0xFFFFFFFFU &&
-+                                       *na==(float)(uint32)(*na))
-                {
-                        nb[0]=(uint32)(*na);
-                        nb[1]=1;
-diff --git a/third_party/libtiff/tif_jpeg.c b/third_party/libtiff/tif_jpeg.c
-index abd0b0aa2..4f154a7c2 100644
---- a/third_party/libtiff/tif_jpeg.c
-+++ b/third_party/libtiff/tif_jpeg.c
-@@ -1634,6 +1634,20 @@ JPEGSetupEncode(TIFF* tif)
-        case PHOTOMETRIC_YCBCR:
-                sp->h_sampling = td->td_ycbcrsubsampling[0];
-                sp->v_sampling = td->td_ycbcrsubsampling[1];
-+               if( sp->h_sampling == 0 || sp->v_sampling == 0 )
-+               {
-+                       TIFFErrorExt(tif->tif_clientdata, module,
-+                                       "Invalig horizontal/vertical sampling value");
-+                       return (0);
-+               }
-+               if( td->td_bitspersample > 16 )
-+               {
-+                       TIFFErrorExt(tif->tif_clientdata, module,
-+                                                       "BitsPerSample %d not allowed for JPEG",
-+                                                       td->td_bitspersample);
-+                       return (0);
-+               }
-+
-                /*
-                 * A ReferenceBlackWhite field *must* be present since the
-                 * default value is inappropriate for YCbCr.  Fill in the
-diff --git a/third_party/libtiff/tif_read.c b/third_party/libtiff/tif_read.c
-index 47686a473..c916ac8ac 100644
---- a/third_party/libtiff/tif_read.c
-+++ b/third_party/libtiff/tif_read.c
-@@ -420,16 +420,25 @@ TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,
-                        return ((tmsize_t)(-1));
-                }
-        } else {
--               tmsize_t ma,mb;
-+               tmsize_t ma;
-                tmsize_t n;
--               ma=(tmsize_t)td->td_stripoffset[strip];
--               mb=ma+size;
--               if ((td->td_stripoffset[strip] > (uint64)TIFF_TMSIZE_T_MAX)||(ma>tif->tif_size))
-+               if ((td->td_stripoffset[strip] > (uint64)TIFF_TMSIZE_T_MAX)||
-+                               ((ma=(tmsize_t)td->td_stripoffset[strip])>tif->tif_size))
-+               {
-                        n=0;
--               else if ((mb<ma)||(mb<size)||(mb>tif->tif_size))
--                       n=tif->tif_size-ma;
-+               }
-+               else if( ma > TIFF_TMSIZE_T_MAX - size )
-+               {
-+                       n=0;
-+               }
-                else
--                       n=size;
-+               {
-+                       tmsize_t mb=ma+size;
-+                       if (mb>tif->tif_size)
-+                               n=tif->tif_size-ma;
-+                       else
-+                               n=size;
-+               }
-                if (n!=size) {
- #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
-                        TIFFErrorExt(tif->tif_clientdata, module,
diff --git a/third_party/libtiff/0024-upstream-PackBitsDecode-fix.patch b/third_party/libtiff/0024-upstream-PackBitsDecode-fix.patch
deleted file mode 100644
index eaae797..0000000
--- a/third_party/libtiff/0024-upstream-PackBitsDecode-fix.patch
+++ /dev/null
@@ -1,17 +0,0 @@
-diff --git a/third_party/libtiff/tif_packbits.c b/third_party/libtiff/tif_packbits.c
-index d2a0165de..92185e7f7 100644
---- a/third_party/libtiff/tif_packbits.c
-+++ b/third_party/libtiff/tif_packbits.c
-@@ -244,6 +244,12 @@ PackBitsDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
-                                    (unsigned long) ((tmsize_t)n - occ));
-                                n = (long)occ;
-                        }
-+                       if( cc == 0 )
-+                       {
-+                               TIFFWarningExt(tif->tif_clientdata, module,
-+                                              "Terminating PackBitsDecode due to lack of data.");
-+                               break;
-+                       }
-                        occ -= n;
-                        b = *bp++;
-                        cc--;
diff --git a/third_party/libtiff/0025-upstream-OOM-gtTileContig.patch b/third_party/libtiff/0025-upstream-OOM-gtTileContig.patch
index 8149230..d4d3d70 100644
--- a/third_party/libtiff/0025-upstream-OOM-gtTileContig.patch
+++ b/third_party/libtiff/0025-upstream-OOM-gtTileContig.patch
@@ -1,5 +1,5 @@
 diff --git a/third_party/libtiff/tif_getimage.c b/third_party/libtiff/tif_getimage.c
-index 84cc1d1a7..d1f1f45ac 100644
+index 53c938a89..03c9a81fb 100644
 --- a/third_party/libtiff/tif_getimage.c
 +++ b/third_party/libtiff/tif_getimage.c
 @@ -627,7 +627,7 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
@@ -114,7 +114,7 @@
 +                                pa = (alpha?(p2+tilesize):NULL);
 +                            }
 +                        }
-+                       else if (TIFFReadTile(tif, p0, col,
++                       else if (TIFFReadTile(tif, p0, col,  
                             row+img->row_offset,0,0)==(tmsize_t)(-1) && img->stoponerr)
                         {
                                 ret = 0;
@@ -204,50 +204,50 @@
                 nrow = (row + rowstoread > h ? h - row : rowstoread);
                 offset_row = row + img->row_offset;
 -               if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0),
-+    if( buf == NULL )
-+         {
-+             if (_TIFFReadEncodedStripAndAllocBuffer(
-+                     tif, TIFFComputeStrip(tif, offset_row, 0),
-+                     (void**) &buf, bufsize,
-+                     ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
-+                 && (buf == NULL || img->stoponerr))
-+             {
-+                     ret = 0;
-+                     break;
-+             }
-+             p0 = buf;
-+             if( colorchannels == 1 )
-+             {
-+                 p2 = p1 = p0;
-+                 pa = (alpha?(p0+3*stripsize):NULL);
-+             }
-+             else
-+             {
-+                 p1 = p0 + stripsize;
-+                 p2 = p1 + stripsize;
-+                 pa = (alpha?(p2+stripsize):NULL);
-+             }
-+         }
++                if( buf == NULL )
++                {
++                    if (_TIFFReadEncodedStripAndAllocBuffer(
++                            tif, TIFFComputeStrip(tif, offset_row, 0),
++                            (void**) &buf, bufsize,
++                            ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
++                        && (buf == NULL || img->stoponerr))
++                    {
++                            ret = 0;
++                            break;
++                    }
++                    p0 = buf;
++                    if( colorchannels == 1 )
++                    {
++                        p2 = p1 = p0;
++                        pa = (alpha?(p0+3*stripsize):NULL);
++                    }
++                    else
++                    {
++                        p1 = p0 + stripsize;
++                        p2 = p1 + stripsize;
++                        pa = (alpha?(p2+stripsize):NULL);
++                    }
++                }
 +               else if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0),
                     p0, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
                     && img->stoponerr)
                 {
 diff --git a/third_party/libtiff/tif_read.c b/third_party/libtiff/tif_read.c
-index c916ac8ac..12c331b12 100644
+index cc4f5d2f6..ad0a778c0 100644
 --- a/third_party/libtiff/tif_read.c
 +++ b/third_party/libtiff/tif_read.c
-@@ -315,18 +315,16 @@ TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
+@@ -442,18 +442,17 @@ TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
  }
  
  /*
 - * Read a strip of data and decompress the specified
 - * amount into the user-supplied buffer.
-- */
--tmsize_t
--TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
 + * Calculate the strip size according to the number of
 + * rows in the strip (check for truncated last strip on any
-+ * of the separations). */
++ * of the separations).
+  */
+-tmsize_t
+-TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
 +static tmsize_t TIFFReadEncodedStripGetStripSize(TIFF* tif, uint32 strip, uint16* pplane)
  {
         static const char module[] = "TIFFReadEncodedStrip";
@@ -259,7 +259,7 @@
         uint32 rows;
         tmsize_t stripsize;
         if (!TIFFCheckRead(tif,0))
-@@ -338,23 +336,37 @@ TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
+@@ -465,23 +464,37 @@ TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
                     (unsigned long)td->td_nstrips);
                 return((tmsize_t)(-1));
         }
@@ -282,8 +282,8 @@
         stripsize=TIFFVStripSize(tif,rows);
         if (stripsize==0)
                 return((tmsize_t)(-1));
-+  return stripsize;
-+ }
++    return stripsize;
++}
 +
 +/*
 + * Read a strip of data and decompress the specified
@@ -299,11 +299,11 @@
 +
 +  stripsize=TIFFReadEncodedStripGetStripSize(tif, strip, &plane);
 +  if (stripsize==((tmsize_t)(-1)))
-+    return((tmsize_t)(-1));
++      return((tmsize_t)(-1));
  
      /* shortcut to avoid an extra memcpy() */
      if( td->td_compression == COMPRESSION_NONE &&
-@@ -383,6 +395,49 @@ TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
+@@ -510,6 +523,50 @@ TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
         return(stripsize);
  }
  
@@ -350,14 +350,14 @@
 +
 +}
 +
++
  static tmsize_t
  TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,
      const char* module)
-@@ -730,6 +785,78 @@ TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size)
+@@ -939,6 +996,78 @@ TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size)
                 return ((tmsize_t)(-1));
  }
  
-+
 +/* Variant of TIFFReadTile() that does 
 + * * if *buf == NULL, *buf = _TIFFmalloc(bufsizetoalloc) only after TIFFFillTile() has
 + *   suceeded. This avoid excessive memory allocation in case of truncated
@@ -429,11 +429,12 @@
 +        return ((tmsize_t)(-1));
 +}
 +
++
  static tmsize_t
  TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* module)
  {
 diff --git a/third_party/libtiff/tiffiop.h b/third_party/libtiff/tiffiop.h
-index 1925a6b5e..c42ebef43 100644
+index 7e415c750..6fb47de5b 100644
 --- a/third_party/libtiff/tiffiop.h
 +++ b/third_party/libtiff/tiffiop.h
 @@ -364,6 +364,20 @@ extern void* _TIFFCheckRealloc(TIFF*, void*, tmsize_t, tmsize_t, const char*);
@@ -444,7 +445,6 @@
 +_TIFFReadEncodedStripAndAllocBuffer(TIFF* tif, uint32 strip,
 +                                    void **buf, tmsize_t bufsizetoalloc,
 +                                    tmsize_t size_to_read);
-+
 +extern tmsize_t
 +_TIFFReadEncodedTileAndAllocBuffer(TIFF* tif, uint32 tile,
 +                                    void **buf, tmsize_t bufsizetoalloc,
@@ -454,6 +454,7 @@
 +                            void **buf, tmsize_t bufsizetoalloc,
 +                            uint32 x, uint32 y, uint32 z, uint16 s);
 +
++
  extern int TIFFInitDumpMode(TIFF*, int);
  #ifdef PACKBITS_SUPPORT
  extern int TIFFInitPackBits(TIFF*, int);
diff --git a/third_party/libtiff/README.pdfium b/third_party/libtiff/README.pdfium
index e6602f8..285a628 100644
--- a/third_party/libtiff/README.pdfium
+++ b/third_party/libtiff/README.pdfium
@@ -1,6 +1,6 @@
 Name: LibTIFF
-URL: http://www.remotesensing.org/libtiff/
-Version: 4.0.7
+URL: http://www.simplesystems.org/libtiff/
+Version: 4.0.8
 Security Critical: yes
 License: BSD
 
@@ -15,18 +15,5 @@
 0006-HeapBufferOverflow-ChopUpSingleUncompressedStrip.patch: Fix a heap buffer overflow
 0007-uninitialized-value.patch: Fix potentially uninitialized dircount value
 0008-HeapBufferOverflow-ChopUpSingleUncompressedStrip.patch: Fix a heap buffer overflow
-0010-fix-leak-imagebegin: Fix a leak when TIFFRGBAImageBegin fails
-0011-fix-leak-imagebegin2: Apply upstream fix related to our previous patch
-0012-initialize-tif-rawdata.patch: Initialize tif_rawdata to guard against unitialized access
-0013-validate-refblackwhite.patch: Make sure the refblackwhite values aren't nan.
-0014-cast-to-unsigned-in-putagreytile.patch: casting to avoid undefined shifts.
-0015-fix-leaks-in-tif_ojpeg.patch: fix direct leaks in tif_ojpeg.c methods
 0017-safe_skews_in_gtTileContig.patch: return error if to/from skews overflow from int32.
-0018-fix-leak-in-PredictorSetupDecode.patch: call tif->tif_cleanup if the setup fails.
-0019-oom-TIFFReadDirEntryArray.patch: OOM in tif_dirread.c (patch should be replaced when upstream fixes http://bugzilla.maptools.org/show_bug.cgi?id=2675).
-0020-upstream-security-fixes.patch: patch our copy with several upstream security fixes.
-0021-oom-TIFFFillStrip.patch: Try to avoid out-of-memory in tif_read.c
-0022-upstream-patch-0012.patch: Use the upstream solution corresponding to patch 0012.
-0023-upstream-security-fixes.patch: more upstream patches related to security issues.
-0024-upstream-PackBitsDecode-fix.patch: fix Heap-buffer-overflow in tif_packbits.c.
-0025-upstream-OOM-gtTileContig: allocates the decoded buffer only after a first successful TIFFFillStrip.
\ No newline at end of file
+0025-upstream-OOM-gtTileContig: allocates the decoded buffer only after a first successful TIFFFillStrip.
diff --git a/third_party/libtiff/tif_color.c b/third_party/libtiff/tif_color.c
index 89194c2..8b8418c 100644
--- a/third_party/libtiff/tif_color.c
+++ b/third_party/libtiff/tif_color.c
@@ -1,4 +1,4 @@
-/* $Id: tif_color.c,v 1.22 2016-09-04 21:32:56 erouault Exp $ */
+/* $Id: tif_color.c,v 1.23 2017-05-13 18:17:34 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -199,6 +199,23 @@
 	*b = CLAMP(i, 0, 255);
 }
 
+/* Clamp function for sanitization purposes. Normally clamping should not */
+/* occur for well behaved chroma and refBlackWhite coefficients */
+static float CLAMPw(float v, float vmin, float vmax)
+{
+    if( v < vmin )
+    {
+        /* printf("%f clamped to %f\n", v, vmin); */
+        return vmin;
+    }
+    if( v > vmax )
+    {
+        /* printf("%f clamped to %f\n", v, vmax); */
+        return vmax;
+    }
+    return v;
+}
+
 /*
  * Initialize the YCbCr->RGB conversion tables.  The conversion
  * is done according to the 6.0 spec:
@@ -238,10 +255,10 @@
     ycbcr->Cb_g_tab = ycbcr->Cr_g_tab + 256;
     ycbcr->Y_tab = ycbcr->Cb_g_tab + 256;
 
-    { float f1 = 2-2*LumaRed;		int32 D1 = FIX(f1);
-      float f2 = LumaRed*f1/LumaGreen;	int32 D2 = -FIX(f2);
-      float f3 = 2-2*LumaBlue;		int32 D3 = FIX(f3);
-      float f4 = LumaBlue*f3/LumaGreen;	int32 D4 = -FIX(f4);
+    { float f1 = 2-2*LumaRed;		int32 D1 = FIX(CLAMP(f1,0.0F,2.0F));
+      float f2 = LumaRed*f1/LumaGreen;	int32 D2 = -FIX(CLAMP(f2,0.0F,2.0F));
+      float f3 = 2-2*LumaBlue;		int32 D3 = FIX(CLAMP(f3,0.0F,2.0F));
+      float f4 = LumaBlue*f3/LumaGreen;	int32 D4 = -FIX(CLAMP(f4,0.0F,2.0F));
       int x;
 
 #undef LumaBlue
@@ -256,17 +273,20 @@
        * constructing tables indexed by the raw pixel data.
        */
       for (i = 0, x = -128; i < 256; i++, x++) {
-	    int32 Cr = (int32)Code2V(x, refBlackWhite[4] - 128.0F,
-			    refBlackWhite[5] - 128.0F, 127);
-	    int32 Cb = (int32)Code2V(x, refBlackWhite[2] - 128.0F,
-			    refBlackWhite[3] - 128.0F, 127);
+	    int32 Cr = (int32)CLAMPw(Code2V(x, refBlackWhite[4] - 128.0F,
+			    refBlackWhite[5] - 128.0F, 127),
+                            -128.0F * 64, 128.0F * 64);
+	    int32 Cb = (int32)CLAMPw(Code2V(x, refBlackWhite[2] - 128.0F,
+			    refBlackWhite[3] - 128.0F, 127),
+                            -128.0F * 64, 128.0F * 64);
 
 	    ycbcr->Cr_r_tab[i] = (int32)((D1*Cr + ONE_HALF)>>SHIFT);
 	    ycbcr->Cb_b_tab[i] = (int32)((D3*Cb + ONE_HALF)>>SHIFT);
 	    ycbcr->Cr_g_tab[i] = D2*Cr;
 	    ycbcr->Cb_g_tab[i] = D4*Cb + ONE_HALF;
 	    ycbcr->Y_tab[i] =
-		    (int32)Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255);
+		    (int32)CLAMPw(Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255),
+                                  -128.0F * 64, 128.0F * 64);
       }
     }
 
diff --git a/third_party/libtiff/tif_dir.c b/third_party/libtiff/tif_dir.c
index 7214841..a883949 100644
--- a/third_party/libtiff/tif_dir.c
+++ b/third_party/libtiff/tif_dir.c
@@ -1,4 +1,4 @@
-/* $Id: tif_dir.c,v 1.127 2016-10-25 21:35:15 erouault Exp $ */
+/* $Id: tif_dir.c,v 1.130 2017-05-17 21:54:05 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -460,14 +460,6 @@
 	case TIFFTAG_REFERENCEBLACKWHITE:
 		/* XXX should check for null range */
 		_TIFFsetFloatArray(&td->td_refblackwhite, va_arg(ap, float*), 6);
-		for (int i = 0; i < 6; i++) {
-			if (isnan(td->td_refblackwhite[i])) {
-				if (i % 2 == 0)
-					td->td_refblackwhite[i] = 0;
-				else
-					td->td_refblackwhite[i] = pow(2, td->td_bitspersample) - 1;
-			}
-		}
 		break;
 	case TIFFTAG_INKNAMES:
 		v = (uint16) va_arg(ap, uint16_vap);
@@ -694,7 +686,7 @@
 				case TIFF_SRATIONAL:
 				case TIFF_FLOAT:
 					{
-						float v2 = (float)va_arg(ap, double);
+						float v2 = TIFFClampDoubleToFloat(va_arg(ap, double));
 						_TIFFmemcpy(val, &v2, tv_size);
 					}
 					break;
@@ -872,31 +864,31 @@
 	if( fip == NULL ) /* cannot happen since TIFFGetField() already checks it */
 	    return 0;
 	
-	if( tag == TIFFTAG_NUMBEROFINKS )
-	{
-		int i;
-		for (i = 0; i < td->td_customValueCount; i++) {
-			uint16 val;
-			TIFFTagValue *tv = td->td_customValues + i;
-			if (tv->info->field_tag != tag)
-				continue;
-			val = *(uint16 *)tv->value;
-			/* Truncate to SamplesPerPixel, since the */
-			/* setting code for INKNAMES assume that there are SamplesPerPixel */
-			/* inknames. */
-			/* Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2599 */
-			if( val > td->td_samplesperpixel )
-			{
-				TIFFWarningExt(tif->tif_clientdata,"_TIFFVGetField",
-							   "Truncating NumberOfInks from %u to %u",
-							   val, td->td_samplesperpixel);
-				val = td->td_samplesperpixel;
-			}
-			*va_arg(ap, uint16*) = val;
-			return 1;
-		}
-		return 0;
-	}
+        if( tag == TIFFTAG_NUMBEROFINKS )
+        {
+            int i;
+            for (i = 0; i < td->td_customValueCount; i++) {
+                uint16 val;
+                TIFFTagValue *tv = td->td_customValues + i;
+                if (tv->info->field_tag != tag)
+                    continue;
+                val = *(uint16 *)tv->value;
+                /* Truncate to SamplesPerPixel, since the */
+                /* setting code for INKNAMES assume that there are SamplesPerPixel */
+                /* inknames. */
+                /* Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2599 */
+                if( val > td->td_samplesperpixel )
+                {
+                    TIFFWarningExt(tif->tif_clientdata,"_TIFFVGetField",
+                                   "Truncating NumberOfInks from %u to %u",
+                                   val, td->td_samplesperpixel);
+                    val = td->td_samplesperpixel;
+                }
+                *va_arg(ap, uint16*) = val;
+                return 1;
+            }
+            return 0;
+        }
 
 	/*
 	 * We want to force the custom code to be used for custom
diff --git a/third_party/libtiff/tif_dirread.c b/third_party/libtiff/tif_dirread.c
index 0926e16..385ed12 100644
--- a/third_party/libtiff/tif_dirread.c
+++ b/third_party/libtiff/tif_dirread.c
@@ -1,4 +1,4 @@
-/* $Id: tif_dirread.c,v 1.204 2016-11-16 15:14:15 erouault Exp $ */
+/* $Id: tif_dirread.c,v 1.208 2017-04-27 15:46:22 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -791,43 +791,44 @@
 	*count=(uint32)direntry->tdir_count;
 	datasize=(*count)*typesize;
 	assert((tmsize_t)datasize>0);
-	const uint32 small_alloc_threshold=(tif->tif_flags&TIFF_BIGTIFF)? 8 : 4;
-	if (datasize <= small_alloc_threshold)
-	{
-		data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray");
-		if (data==0)
-			return(TIFFReadDirEntryErrAlloc);
-		_TIFFmemcpy(data,&direntry->tdir_offset,datasize);
-		*value=data;
-		return(TIFFReadDirEntryErrOk);
-	}
-	uint64 offset;
-	if (!(tif->tif_flags&TIFF_BIGTIFF))
-	{
-		uint32 small_offset=direntry->tdir_offset.toff_long;
-		if (tif->tif_flags&TIFF_SWAB)
-			TIFFSwabLong(&small_offset);
-		offset=(uint64)small_offset;
-	}
-	else
-	{
-		offset = direntry->tdir_offset.toff_long8;
-		if (tif->tif_flags&TIFF_SWAB)
-			TIFFSwabLong8(&offset);
-	}
-	if ((uint64)(-1) - offset < datasize)
-		return(TIFFReadDirEntryErrIo);
-	const uint64 size=isMapped(tif)? (uint64)tif->tif_size : TIFFGetFileSize(tif);
-	if (offset + datasize > size)
-		return(TIFFReadDirEntryErrIo);
 	data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray");
 	if (data==0)
 		return(TIFFReadDirEntryErrAlloc);
-	enum TIFFReadDirEntryErr err=TIFFReadDirEntryData(tif,offset,(tmsize_t)datasize,data);
-	if (err!=TIFFReadDirEntryErrOk)
+	if (!(tif->tif_flags&TIFF_BIGTIFF))
 	{
-		_TIFFfree(data);
-		return(err);
+		if (datasize<=4)
+			_TIFFmemcpy(data,&direntry->tdir_offset,datasize);
+		else
+		{
+			enum TIFFReadDirEntryErr err;
+			uint32 offset = direntry->tdir_offset.toff_long;
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabLong(&offset);
+			err=TIFFReadDirEntryData(tif,(uint64)offset,(tmsize_t)datasize,data);
+			if (err!=TIFFReadDirEntryErrOk)
+			{
+				_TIFFfree(data);
+				return(err);
+			}
+		}
+	}
+	else
+	{
+		if (datasize<=8)
+			_TIFFmemcpy(data,&direntry->tdir_offset,datasize);
+		else
+		{
+			enum TIFFReadDirEntryErr err;
+			uint64 offset = direntry->tdir_offset.toff_long8;
+			if (tif->tif_flags&TIFF_SWAB)
+				TIFFSwabLong8(&offset);
+			err=TIFFReadDirEntryData(tif,offset,(tmsize_t)datasize,data);
+			if (err!=TIFFReadDirEntryErrOk)
+			{
+				_TIFFfree(data);
+				return(err);
+			}
+		}
 	}
 	*value=data;
 	return(TIFFReadDirEntryErrOk);
@@ -2406,14 +2407,14 @@
 				ma=(double*)origdata;
 				mb=data;
 				for (n=0; n<count; n++)
-				{
-					double val = *ma++;
-					if( val > FLT_MAX )
-						val = FLT_MAX;
-					else if( val < -FLT_MAX )
-						val = -FLT_MAX;
-					*mb++=(float)val;
-				}
+                                {
+                                    double val = *ma++;
+                                    if( val > FLT_MAX )
+                                        val = FLT_MAX;
+                                    else if( val < -FLT_MAX )
+                                        val = -FLT_MAX;
+                                    *mb++=(float)val;
+                                }
 			}
 			break;
 	}
@@ -2879,9 +2880,9 @@
 		m.l = direntry->tdir_offset.toff_long8;
 	if (tif->tif_flags&TIFF_SWAB)
 		TIFFSwabArrayOfLong(m.i,2);
-	/* Not completely sure what we should do when m.i[1]==0, but some */
-	/* sanitizers do not like division by 0.0: */
-	/* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */
+        /* Not completely sure what we should do when m.i[1]==0, but some */
+        /* sanitizers do not like division by 0.0: */
+        /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */
 	if (m.i[0]==0 || m.i[1]==0)
 		*value=0.0;
 	else
@@ -2910,9 +2911,9 @@
 		m.l=direntry->tdir_offset.toff_long8;
 	if (tif->tif_flags&TIFF_SWAB)
 		TIFFSwabArrayOfLong(m.i,2);
-	/* Not completely sure what we should do when m.i[1]==0, but some */
-	/* sanitizers do not like division by 0.0: */
-	/* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */
+        /* Not completely sure what we should do when m.i[1]==0, but some */
+        /* sanitizers do not like division by 0.0: */
+        /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */
 	if ((int32)m.i[0]==0 || m.i[1]==0)
 		*value=0.0;
 	else
@@ -3737,6 +3738,14 @@
                                 _TIFFmemcpy( &(tif->tif_dir.td_stripoffset_entry),
                                              dp, sizeof(TIFFDirEntry) );
 #else                          
+                                if( tif->tif_dir.td_stripoffset != NULL )
+                                {
+                                    TIFFErrorExt(tif->tif_clientdata, module,
+                                        "tif->tif_dir.td_stripoffset is "
+                                        "already allocated. Likely duplicated "
+                                        "StripOffsets/TileOffsets tag");
+                                    goto bad;
+                                }
 				if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripoffset))  
 					goto bad;
 #endif                                
@@ -3747,7 +3756,15 @@
                                 _TIFFmemcpy( &(tif->tif_dir.td_stripbytecount_entry),
                                              dp, sizeof(TIFFDirEntry) );
 #else                          
-				if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripbytecount))  
+                                if( tif->tif_dir.td_stripbytecount != NULL )
+                                {
+                                    TIFFErrorExt(tif->tif_clientdata, module,
+                                        "tif->tif_dir.td_stripbytecount is "
+                                        "already allocated. Likely duplicated "
+                                        "StripByteCounts/TileByteCounts tag");
+                                    goto bad;
+                                }
+                                if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripbytecount))  
 					goto bad;
 #endif                                
 				break;
@@ -5552,9 +5569,9 @@
 	 */
 	if (rowsperstrip >= td->td_rowsperstrip)
 		return;
-	nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip);
-	if( nstrips == 0 )
-		return;
+        nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip);
+        if( nstrips == 0 )
+            return;
 
 	newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
 				"for chopped \"StripByteCounts\" array");
diff --git a/third_party/libtiff/tif_dirwrite.c b/third_party/libtiff/tif_dirwrite.c
index f4d8034..f733968 100644
--- a/third_party/libtiff/tif_dirwrite.c
+++ b/third_party/libtiff/tif_dirwrite.c
@@ -1,4 +1,4 @@
-/* $Id: tif_dirwrite.c,v 1.83 2016-10-25 21:35:15 erouault Exp $ */
+/* $Id: tif_dirwrite.c,v 1.85 2017-01-11 16:09:02 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -2158,19 +2158,19 @@
 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;
+        }
 	else if (value==0.0)
 	{
 		m[0]=0;
@@ -2223,7 +2223,7 @@
 			nb[1]=1;
 		}
 		else if (*na >= 0 && *na <= (float)0xFFFFFFFFU &&
-					*na==(float)(uint32)(*na))
+                         *na==(float)(uint32)(*na))
 		{
 			nb[0]=(uint32)(*na);
 			nb[1]=1;
diff --git a/third_party/libtiff/tif_fax3.c b/third_party/libtiff/tif_fax3.c
index 16bb4d3..087cedd 100644
--- a/third_party/libtiff/tif_fax3.c
+++ b/third_party/libtiff/tif_fax3.c
@@ -1,4 +1,4 @@
-/* $Id: tif_fax3.c,v 1.78 2016-09-04 21:32:56 erouault Exp $ */
+/* $Id: tif_fax3.c,v 1.80 2017-04-27 19:50:01 erouault Exp $ */
 
 /*
  * Copyright (c) 1990-1997 Sam Leffler
@@ -329,34 +329,64 @@
 #if SIZEOF_UNSIGNED_LONG == 8
 # define FILL(n, cp)							    \
     switch (n) {							    \
-    case 15:(cp)[14] = 0xff; case 14:(cp)[13] = 0xff; case 13: (cp)[12] = 0xff;\
-    case 12:(cp)[11] = 0xff; case 11:(cp)[10] = 0xff; case 10: (cp)[9] = 0xff;\
-    case  9: (cp)[8] = 0xff; case  8: (cp)[7] = 0xff; case  7: (cp)[6] = 0xff;\
-    case  6: (cp)[5] = 0xff; case  5: (cp)[4] = 0xff; case  4: (cp)[3] = 0xff;\
-    case  3: (cp)[2] = 0xff; case  2: (cp)[1] = 0xff;			      \
-    case  1: (cp)[0] = 0xff; (cp) += (n); case 0:  ;			      \
+    case 15:(cp)[14] = 0xff; /*-fallthrough*/ \
+    case 14:(cp)[13] = 0xff; /*-fallthrough*/ \
+    case 13:(cp)[12] = 0xff; /*-fallthrough*/ \
+    case 12:(cp)[11] = 0xff; /*-fallthrough*/ \
+    case 11:(cp)[10] = 0xff; /*-fallthrough*/ \
+    case 10: (cp)[9] = 0xff; /*-fallthrough*/ \
+    case  9: (cp)[8] = 0xff; /*-fallthrough*/ \
+    case  8: (cp)[7] = 0xff; /*-fallthrough*/ \
+    case  7: (cp)[6] = 0xff; /*-fallthrough*/ \
+    case  6: (cp)[5] = 0xff; /*-fallthrough*/ \
+    case  5: (cp)[4] = 0xff; /*-fallthrough*/ \
+    case  4: (cp)[3] = 0xff; /*-fallthrough*/ \
+    case  3: (cp)[2] = 0xff; /*-fallthrough*/ \
+    case  2: (cp)[1] = 0xff; /*-fallthrough*/ \
+    case  1: (cp)[0] = 0xff; (cp) += (n); /*-fallthrough*/ \
+    case 0:  ;			      \
     }
 # define ZERO(n, cp)							\
     switch (n) {							\
-    case 15:(cp)[14] = 0; case 14:(cp)[13] = 0; case 13: (cp)[12] = 0;	\
-    case 12:(cp)[11] = 0; case 11:(cp)[10] = 0; case 10: (cp)[9] = 0;	\
-    case  9: (cp)[8] = 0; case  8: (cp)[7] = 0; case  7: (cp)[6] = 0;	\
-    case  6: (cp)[5] = 0; case  5: (cp)[4] = 0; case  4: (cp)[3] = 0;	\
-    case  3: (cp)[2] = 0; case  2: (cp)[1] = 0;				\
-    case  1: (cp)[0] = 0; (cp) += (n); case 0:  ;			\
+    case 15:(cp)[14] = 0; /*-fallthrough*/ \
+    case 14:(cp)[13] = 0; /*-fallthrough*/ \
+    case 13:(cp)[12] = 0; /*-fallthrough*/ \
+    case 12:(cp)[11] = 0; /*-fallthrough*/ \
+    case 11:(cp)[10] = 0; /*-fallthrough*/ \
+    case 10: (cp)[9] = 0; /*-fallthrough*/ \
+    case  9: (cp)[8] = 0; /*-fallthrough*/ \
+    case  8: (cp)[7] = 0; /*-fallthrough*/ \
+    case  7: (cp)[6] = 0; /*-fallthrough*/ \
+    case  6: (cp)[5] = 0; /*-fallthrough*/ \
+    case  5: (cp)[4] = 0; /*-fallthrough*/ \
+    case  4: (cp)[3] = 0; /*-fallthrough*/ \
+    case  3: (cp)[2] = 0; /*-fallthrough*/ \
+    case  2: (cp)[1] = 0; /*-fallthrough*/ \
+    case  1: (cp)[0] = 0; (cp) += (n); /*-fallthrough*/ \
+    case 0:  ;			\
     }
 #else
 # define FILL(n, cp)							    \
     switch (n) {							    \
-    case 7: (cp)[6] = 0xff; case 6: (cp)[5] = 0xff; case 5: (cp)[4] = 0xff; \
-    case 4: (cp)[3] = 0xff; case 3: (cp)[2] = 0xff; case 2: (cp)[1] = 0xff; \
-    case 1: (cp)[0] = 0xff; (cp) += (n); case 0:  ;			    \
+    case 7: (cp)[6] = 0xff; /*-fallthrough*/ \
+    case 6: (cp)[5] = 0xff; /*-fallthrough*/ \
+    case 5: (cp)[4] = 0xff; /*-fallthrough*/ \
+    case 4: (cp)[3] = 0xff; /*-fallthrough*/ \
+    case 3: (cp)[2] = 0xff; /*-fallthrough*/ \
+    case 2: (cp)[1] = 0xff; /*-fallthrough*/ \
+    case 1: (cp)[0] = 0xff; (cp) += (n);  /*-fallthrough*/ \
+    case 0:  ;			    \
     }
 # define ZERO(n, cp)							\
     switch (n) {							\
-    case 7: (cp)[6] = 0; case 6: (cp)[5] = 0; case 5: (cp)[4] = 0;	\
-    case 4: (cp)[3] = 0; case 3: (cp)[2] = 0; case 2: (cp)[1] = 0;	\
-    case 1: (cp)[0] = 0; (cp) += (n); case 0:  ;			\
+    case 7: (cp)[6] = 0; /*-fallthrough*/ \
+    case 6: (cp)[5] = 0; /*-fallthrough*/ \
+    case 5: (cp)[4] = 0; /*-fallthrough*/ \
+    case 4: (cp)[3] = 0; /*-fallthrough*/ \
+    case 3: (cp)[2] = 0; /*-fallthrough*/ \
+    case 2: (cp)[1] = 0; /*-fallthrough*/ \
+    case 1: (cp)[0] = 0; (cp) += (n); /*-fallthrough*/ \
+    case 0:  ;			\
     }
 #endif
 
@@ -1099,7 +1129,7 @@
 static void
 Fax3Close(TIFF* tif)
 {
-	if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0) {
+	if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0 && tif->tif_rawcp) {
 		Fax3CodecState* sp = EncoderState(tif);
 		unsigned int code = EOL;
 		unsigned int length = 12;
@@ -1321,6 +1351,7 @@
 		    "No space for state block");
 		return (0);
 	}
+	_TIFFmemset(tif->tif_data, 0, sizeof (Fax3CodecState));
 
 	sp = Fax3State(tif);
         sp->rw_mode = tif->tif_mode;
diff --git a/third_party/libtiff/tif_fax3.h b/third_party/libtiff/tif_fax3.h
index e0b2ca6..8a43505 100644
--- a/third_party/libtiff/tif_fax3.h
+++ b/third_party/libtiff/tif_fax3.h
@@ -1,4 +1,4 @@
-/* $Id: tif_fax3.h,v 1.11 2016-01-23 21:20:34 erouault Exp $ */
+/* $Id: tif_fax3.h,v 1.13 2016-12-14 18:36:27 faxguy Exp $ */
 
 /*
  * Copyright (c) 1990-1997 Sam Leffler
@@ -81,10 +81,12 @@
 #define S_MakeUp   11
 #define S_EOL      12
 
+/* WARNING: do not change the layout of this structure as the HylaFAX software */
+/* really depends on it. See http://bugzilla.maptools.org/show_bug.cgi?id=2636 */
 typedef struct {                /* state table entry */
 	unsigned char State;    /* see above */
 	unsigned char Width;    /* width of code in bits */
-	uint16 Param;           /* unsigned 16-bit run length in bits */
+	uint32 Param;           /* unsigned 32-bit run length in bits (holds on 16 bit actually, but cannot be changed. See above warning) */
 } TIFFFaxTabEnt;
 
 extern const TIFFFaxTabEnt TIFFFaxMainTable[];
diff --git a/third_party/libtiff/tif_getimage.c b/third_party/libtiff/tif_getimage.c
index d1f1f45..03c9a81 100644
--- a/third_party/libtiff/tif_getimage.c
+++ b/third_party/libtiff/tif_getimage.c
@@ -1,4 +1,4 @@
-/* $Id: tif_getimage.c,v 1.98 2016-11-18 02:47:45 bfriesen Exp $ */
+/* $Id: tif_getimage.c,v 1.106 2017-05-20 11:29:02 erouault Exp $ */
 
 /*
  * Copyright (c) 1991-1997 Sam Leffler
@@ -495,7 +495,7 @@
 	return 1;
 
   fail_return:
-        TIFFRGBAImageEnd(img);
+        TIFFRGBAImageEnd( img );
         return 0;
 }
 
@@ -736,7 +736,7 @@
 	    this_toskew = toskew;
 	}
 
-        y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
+        y += ((flip & FLIP_VERTICALLY) ? -(int32) nrow : (int32) nrow);
     }
     _TIFFfree(buf);
 
@@ -864,7 +864,7 @@
                                 pa = (alpha?(p2+tilesize):NULL);
                             }
                         }
-			else if (TIFFReadTile(tif, p0, col,
+			else if (TIFFReadTile(tif, p0, col,  
 			    row+img->row_offset,0,0)==(tmsize_t)(-1) && img->stoponerr)
 			{
 				ret = 0;
@@ -918,7 +918,7 @@
 			this_toskew = toskew;
 		}
 
-		y += (flip & FLIP_VERTICALLY ?-(int32) nrow : (int32) nrow);
+		y += ((flip & FLIP_VERTICALLY) ?-(int32) nrow : (int32) nrow);
 	}
 
 	if (flip & FLIP_HORIZONTALLY) {
@@ -1006,7 +1006,7 @@
 		pos = ((row + img->row_offset) % rowsperstrip) * scanline + \
 			((tmsize_t) img->col_offset * img->samplesperpixel);
 		(*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, buf + pos);
-		y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
+		y += ((flip & FLIP_VERTICALLY) ? -(int32) nrow : (int32) nrow);
 	}
 
 	if (flip & FLIP_HORIZONTALLY) {
@@ -1093,31 +1093,31 @@
 		rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
 		nrow = (row + rowstoread > h ? h - row : rowstoread);
 		offset_row = row + img->row_offset;
-    if( buf == NULL )
-	  {
-	      if (_TIFFReadEncodedStripAndAllocBuffer(
-	              tif, TIFFComputeStrip(tif, offset_row, 0),
-	              (void**) &buf, bufsize,
-	              ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
-	          && (buf == NULL || img->stoponerr))
-	      {
-	              ret = 0;
-	              break;
-	      }
-	      p0 = buf;
-	      if( colorchannels == 1 )
-	      {
-	          p2 = p1 = p0;
-	          pa = (alpha?(p0+3*stripsize):NULL);
-	      }
-	      else
-	      {
-	          p1 = p0 + stripsize;
-	          p2 = p1 + stripsize;
-	          pa = (alpha?(p2+stripsize):NULL);
-	      }
-	  }
- 		else if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0),
+                if( buf == NULL )
+                {
+                    if (_TIFFReadEncodedStripAndAllocBuffer(
+                            tif, TIFFComputeStrip(tif, offset_row, 0),
+                            (void**) &buf, bufsize,
+                            ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
+                        && (buf == NULL || img->stoponerr))
+                    {
+                            ret = 0;
+                            break;
+                    }
+                    p0 = buf;
+                    if( colorchannels == 1 )
+                    {
+                        p2 = p1 = p0;
+                        pa = (alpha?(p0+3*stripsize):NULL);
+                    }
+                    else
+                    {
+                        p1 = p0 + stripsize;
+                        p2 = p1 + stripsize;
+                        pa = (alpha?(p2+stripsize):NULL);
+                    }
+                }
+		else if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0),
 		    p0, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
 		    && img->stoponerr)
 		{
@@ -1155,7 +1155,7 @@
 			((tmsize_t) img->col_offset * img->samplesperpixel);
 		(*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, p0 + pos, p1 + pos,
 		    p2 + pos, (alpha?(pa+pos):NULL));
-		y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
+		y += ((flip & FLIP_VERTICALLY) ? -(int32) nrow : (int32) nrow);
 	}
 
 	if (flip & FLIP_HORIZONTALLY) {
@@ -1194,11 +1194,15 @@
 #define	REPEAT2(op)	op; op
 #define	CASE8(x,op)			\
     switch (x) {			\
-    case 7: op; case 6: op; case 5: op;	\
-    case 4: op; case 3: op; case 2: op;	\
+    case 7: op; /*-fallthrough*/ \
+    case 6: op; /*-fallthrough*/ \
+    case 5: op; /*-fallthrough*/ \
+    case 4: op; /*-fallthrough*/ \
+    case 3: op; /*-fallthrough*/ \
+    case 2: op; /*-fallthrough*/ \
     case 1: op;				\
     }
-#define	CASE4(x,op)	switch (x) { case 3: op; case 2: op; case 1: op; }
+#define	CASE4(x,op)	switch (x) { case 3: op; /*-fallthrough*/ case 2: op; /*-fallthrough*/ case 1: op; }
 #define	NOP
 
 #define	UNROLL8(w, op1, op2) {		\
@@ -2104,9 +2108,9 @@
 	    int32 Cr = pp[5];
 
             switch( (w&3) ) {
-              case 3: YCbCrtoRGB(cp [2], pp[2]);
-              case 2: YCbCrtoRGB(cp [1], pp[1]);
-              case 1: YCbCrtoRGB(cp [0], pp[0]);
+              case 3: YCbCrtoRGB(cp [2], pp[2]); /*-fallthrough*/
+              case 2: YCbCrtoRGB(cp [1], pp[1]); /*-fallthrough*/
+              case 1: YCbCrtoRGB(cp [0], pp[0]); /*-fallthrough*/
               case 0: break;
             }
 
@@ -2296,6 +2300,11 @@
 }
 #undef YCbCrtoRGB
 
+static int isInRefBlackWhiteRange(float f)
+{
+    return f >= (float)(-0x7FFFFFFF + 128) && f <= (float)0x7FFFFFFF;
+}
+
 static int
 initYCbCrConversion(TIFFRGBAImage* img)
 {
@@ -2320,6 +2329,31 @@
 	TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma);
 	TIFFGetFieldDefaulted(img->tif, TIFFTAG_REFERENCEBLACKWHITE,
 	    &refBlackWhite);
+
+        /* Do some validation to avoid later issues. Detect NaN for now */
+        /* and also if lumaGreen is zero since we divide by it later */
+        if( luma[0] != luma[0] ||
+            luma[1] != luma[1] ||
+            luma[1] == 0.0 ||
+            luma[2] != luma[2] )
+        {
+            TIFFErrorExt(img->tif->tif_clientdata, module,
+                "Invalid values for YCbCrCoefficients tag");
+            return (0);
+        }
+
+        if( !isInRefBlackWhiteRange(refBlackWhite[0]) ||
+            !isInRefBlackWhiteRange(refBlackWhite[1]) ||
+            !isInRefBlackWhiteRange(refBlackWhite[2]) ||
+            !isInRefBlackWhiteRange(refBlackWhite[3]) ||
+            !isInRefBlackWhiteRange(refBlackWhite[4]) ||
+            !isInRefBlackWhiteRange(refBlackWhite[5]) )
+        {
+            TIFFErrorExt(img->tif->tif_clientdata, module,
+                "Invalid values for ReferenceBlackWhite tag");
+            return (0);
+        }
+
 	if (TIFFYCbCrToRGBInit(img->ycbcr, luma, refBlackWhite) < 0)
 		return(0);
 	return (1);
@@ -2874,6 +2908,13 @@
 TIFFReadRGBAStrip(TIFF* tif, uint32 row, uint32 * raster )
 
 {
+    return TIFFReadRGBAStripExt(tif, row, raster, 0 );
+}
+
+int
+TIFFReadRGBAStripExt(TIFF* tif, uint32 row, uint32 * raster, int stop_on_error)
+
+{
     char 	emsg[1024] = "";
     TIFFRGBAImage img;
     int 	ok;
@@ -2894,7 +2935,7 @@
 		return (0);
     }
 
-    if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, 0, emsg)) {
+    if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg)) {
 
         img.row_offset = row;
         img.col_offset = 0;
@@ -2925,6 +2966,13 @@
 TIFFReadRGBATile(TIFF* tif, uint32 col, uint32 row, uint32 * raster)
 
 {
+    return TIFFReadRGBATileExt(tif, col, row, raster, 0 );
+}
+
+
+int
+TIFFReadRGBATileExt(TIFF* tif, uint32 col, uint32 row, uint32 * raster, int stop_on_error )
+{
     char 	emsg[1024] = "";
     TIFFRGBAImage img;
     int 	ok;
@@ -2959,7 +3007,7 @@
      */
     
     if (!TIFFRGBAImageOK(tif, emsg) 
-	|| !TIFFRGBAImageBegin(&img, tif, 0, emsg)) {
+	|| !TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg)) {
 	    TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
 	    return( 0 );
     }
diff --git a/third_party/libtiff/tif_jpeg.c b/third_party/libtiff/tif_jpeg.c
index 4f154a7..df06e03 100644
--- a/third_party/libtiff/tif_jpeg.c
+++ b/third_party/libtiff/tif_jpeg.c
@@ -1,4 +1,4 @@
-/* $Id: tif_jpeg.c,v 1.123 2016-01-23 21:20:34 erouault Exp $ */
+/* $Id: tif_jpeg.c,v 1.127 2017-01-31 13:02:27 erouault Exp $ */
 
 /*
  * Copyright (c) 1994-1997 Sam Leffler
@@ -705,9 +705,11 @@
 JPEGFixupTags(TIFF* tif)
 {
 #ifdef CHECK_JPEG_YCBCR_SUBSAMPLING
+        JPEGState* sp = JState(tif);
 	if ((tif->tif_dir.td_photometric==PHOTOMETRIC_YCBCR)&&
 	    (tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)&&
-	    (tif->tif_dir.td_samplesperpixel==3))
+	    (tif->tif_dir.td_samplesperpixel==3) &&
+            !sp->ycbcrsampling_fetched)
 		JPEGFixupTagsSubsampling(tif);
 #endif
         
@@ -1634,19 +1636,19 @@
 	case PHOTOMETRIC_YCBCR:
 		sp->h_sampling = td->td_ycbcrsubsampling[0];
 		sp->v_sampling = td->td_ycbcrsubsampling[1];
-		if( sp->h_sampling == 0 || sp->v_sampling == 0 )
-		{
-			TIFFErrorExt(tif->tif_clientdata, module,
-					"Invalig horizontal/vertical sampling value");
-			return (0);
-		}
-		if( td->td_bitspersample > 16 )
-		{
-			TIFFErrorExt(tif->tif_clientdata, module,
-							"BitsPerSample %d not allowed for JPEG",
-							td->td_bitspersample);
-			return (0);
-		}
+                if( sp->h_sampling == 0 || sp->v_sampling == 0 )
+                {
+                    TIFFErrorExt(tif->tif_clientdata, module,
+                            "Invalig horizontal/vertical sampling value");
+                    return (0);
+                }
+                if( td->td_bitspersample > 16 )
+                {
+                    TIFFErrorExt(tif->tif_clientdata, module,
+                                 "BitsPerSample %d not allowed for JPEG",
+                                 td->td_bitspersample);
+                    return (0);
+                }
 
 		/*
 		 * A ReferenceBlackWhite field *must* be present since the
@@ -2313,6 +2315,15 @@
     } else {
         if (!TIFFjpeg_create_compress(sp))
             return (0);
+#ifndef TIFF_JPEG_MAX_MEMORY_TO_USE
+#define TIFF_JPEG_MAX_MEMORY_TO_USE (10 * 1024 * 1024)
+#endif
+        /* Increase the max memory usable. This helps when creating files */
+        /* with "big" tile, without using libjpeg temporary files. */
+        /* For example a 512x512 tile with 3 bands */
+        /* requires 1.5 MB which is above libjpeg 1MB default */
+        if( sp->cinfo.c.mem->max_memory_to_use < TIFF_JPEG_MAX_MEMORY_TO_USE )
+            sp->cinfo.c.mem->max_memory_to_use = TIFF_JPEG_MAX_MEMORY_TO_USE;
     }
 
     sp->cinfo_initialized = TRUE;
diff --git a/third_party/libtiff/tif_luv.c b/third_party/libtiff/tif_luv.c
index 220c150..59d0a74 100644
--- a/third_party/libtiff/tif_luv.c
+++ b/third_party/libtiff/tif_luv.c
@@ -1,4 +1,4 @@
-/* $Id: tif_luv.c,v 1.43 2016-09-04 21:32:56 erouault Exp $ */
+/* $Id: tif_luv.c,v 1.47 2017-05-14 10:17:27 erouault Exp $ */
 
 /*
  * Copyright (c) 1997 Greg Ward Larson
@@ -158,7 +158,7 @@
 typedef struct logLuvState LogLuvState;
 
 struct logLuvState {
-	int                     encoder_state;  /* 1 if encoder correctly initialized */
+        int                     encoder_state;  /* 1 if encoder correctly initialized */
 	int                     user_datafmt;   /* user data format */
 	int                     encode_meth;    /* encoding method */
 	int                     pixel_size;     /* bytes per pixel */
@@ -473,7 +473,7 @@
 				tif->tif_rawcp = op;
 				tif->tif_rawcc = tif->tif_rawdatasize - occ;
 				if (!TIFFFlushData1(tif))
-					return (-1);
+					return (0);
 				op = tif->tif_rawcp;
 				occ = tif->tif_rawdatasize - tif->tif_rawcc;
 			}
@@ -505,7 +505,7 @@
 					tif->tif_rawcp = op;
 					tif->tif_rawcc = tif->tif_rawdatasize - occ;
 					if (!TIFFFlushData1(tif))
-						return (-1);
+						return (0);
 					op = tif->tif_rawcp;
 					occ = tif->tif_rawdatasize - tif->tif_rawcc;
 				}
@@ -565,7 +565,7 @@
 			tif->tif_rawcp = op;
 			tif->tif_rawcc = tif->tif_rawdatasize - occ;
 			if (!TIFFFlushData1(tif))
-				return (-1);
+				return (0);
 			op = tif->tif_rawcp;
 			occ = tif->tif_rawdatasize - tif->tif_rawcc;
 		}
@@ -624,7 +624,7 @@
 				tif->tif_rawcp = op;
 				tif->tif_rawcc = tif->tif_rawdatasize - occ;
 				if (!TIFFFlushData1(tif))
-					return (-1);
+					return (0);
 				op = tif->tif_rawcp;
 				occ = tif->tif_rawdatasize - tif->tif_rawcc;
 			}
@@ -656,7 +656,7 @@
 					tif->tif_rawcp = op;
 					tif->tif_rawcc = tif->tif_rawdatasize - occ;
 					if (!TIFFFlushData1(tif))
-						return (-1);
+						return (0);
 					op = tif->tif_rawcp;
 					occ = tif->tif_rawdatasize - tif->tif_rawcc;
 				}
@@ -1264,15 +1264,16 @@
 	return (SGILOGDATAFMT_UNKNOWN);
 }
 
+
+#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0))
+#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1)
+
 static tmsize_t
 multiply_ms(tmsize_t m1, tmsize_t m2)
 {
-	tmsize_t bytes = m1 * m2;
-
-	if (m1 && bytes / m1 != m2)
-		bytes = 0;
-
-	return bytes;
+        if( m1 == 0 || m2 > TIFF_TMSIZE_T_MAX / m1 )
+            return 0;
+        return m1 * m2;
 }
 
 static int
@@ -1313,8 +1314,10 @@
 	}
         if( isTiled(tif) )
             sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength);
-        else
+        else if( td->td_rowsperstrip != (uint32)-1 )
             sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip);
+        else
+            sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_imagelength);
 	if (multiply_ms(sp->tbuflen, sizeof (int16)) == 0 ||
 	    (sp->tbuf = (uint8*) _TIFFmalloc(sp->tbuflen * sizeof (int16))) == NULL) {
 		TIFFErrorExt(tif->tif_clientdata, module, "No space for SGILog translation buffer");
@@ -1565,7 +1568,7 @@
 static void
 LogLuvClose(TIFF* tif)
 {
-	LogLuvState* sp = (LogLuvState*) tif->tif_data;
+        LogLuvState* sp = (LogLuvState*) tif->tif_data;
 	TIFFDirectory *td = &tif->tif_dir;
 
 	assert(sp != 0);
@@ -1575,17 +1578,17 @@
 	 * regardless of the data format being used by the application.
 	 * Since this routine is called after tags have been set but
 	 * before they have been recorded in the file, we reset them here.
-	 * Note: this is really a nasty approach. See PixarLogClose
+         * Note: this is really a nasty approach. See PixarLogClose
 	 */
-	if( sp->encoder_state )
-	{
-		/* See PixarLogClose. Might avoid issues with tags whose size depends
-		 * on those below, but not completely sure this is enough. */
-		td->td_samplesperpixel =
-			(td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3;
-		td->td_bitspersample = 16;
-		td->td_sampleformat = SAMPLEFORMAT_INT;
-	}
+        if( sp->encoder_state )
+        {
+            /* See PixarLogClose. Might avoid issues with tags whose size depends
+             * on those below, but not completely sure this is enough. */
+            td->td_samplesperpixel =
+                (td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3;
+            td->td_bitspersample = 16;
+            td->td_sampleformat = SAMPLEFORMAT_INT;
+        }
 }
 
 static void
diff --git a/third_party/libtiff/tif_lzw.c b/third_party/libtiff/tif_lzw.c
index 240e19c..5f1acf8 100644
--- a/third_party/libtiff/tif_lzw.c
+++ b/third_party/libtiff/tif_lzw.c
@@ -1,4 +1,4 @@
-/* $Id: tif_lzw.c,v 1.52 2016-09-04 21:32:56 erouault Exp $ */
+/* $Id: tif_lzw.c,v 1.55 2017-05-17 09:38:58 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -318,7 +318,7 @@
 	sp->dec_restart = 0;
 	sp->dec_nbitsmask = MAXCODE(BITS_MIN);
 #ifdef LZW_CHECKEOS
-	sp->dec_bitsleft = ((uint64)tif->tif_rawcc) << 3;
+	sp->dec_bitsleft = 0;
 #endif
 	sp->dec_free_entp = sp->dec_codetab + CODE_FIRST;
 	/*
@@ -425,6 +425,9 @@
 	}
 
 	bp = (unsigned char *)tif->tif_rawcp;
+#ifdef LZW_CHECKEOS
+	sp->dec_bitsleft = (((uint64)tif->tif_rawcc) << 3);
+#endif
 	nbits = sp->lzw_nbits;
 	nextdata = sp->lzw_nextdata;
 	nextbits = sp->lzw_nextbits;
@@ -549,6 +552,7 @@
 		}
 	}
 
+	tif->tif_rawcc -= (tmsize_t)( (uint8*) bp - tif->tif_rawcp );
 	tif->tif_rawcp = (uint8*) bp;
 	sp->lzw_nbits = (unsigned short) nbits;
 	sp->lzw_nextdata = nextdata;
@@ -969,7 +973,8 @@
 		 */
 		if (op > limit) {
 			tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata);
-			TIFFFlushData1(tif);
+			if( !TIFFFlushData1(tif) )
+                            return 0;
 			op = tif->tif_rawdata;
 		}
 		PutNextCode(op, ent);
@@ -1054,12 +1059,32 @@
 
 	if (op > sp->enc_rawlimit) {
 		tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata);
-		TIFFFlushData1(tif);
+		if( !TIFFFlushData1(tif) )
+                    return 0;
 		op = tif->tif_rawdata;
 	}
 	if (sp->enc_oldcode != (hcode_t) -1) {
+                int free_ent = sp->lzw_free_ent;
+
 		PutNextCode(op, sp->enc_oldcode);
 		sp->enc_oldcode = (hcode_t) -1;
+                free_ent ++;
+
+                if (free_ent == CODE_MAX-1) {
+                        /* table is full, emit clear code and reset */
+                        outcount = 0;
+                        PutNextCode(op, CODE_CLEAR);
+                        nbits = BITS_MIN;
+                } else {
+                        /*
+                        * If the next entry is going to be too big for
+                        * the code size, then increase it, if possible.
+                        */
+                        if (free_ent > sp->lzw_maxcode) {
+                                nbits++;
+                                assert(nbits <= BITS_MAX);
+                        }
+                }
 	}
 	PutNextCode(op, CODE_EOI);
         /* Explicit 0xff masking to make icc -check=conversions happy */
diff --git a/third_party/libtiff/tif_ojpeg.c b/third_party/libtiff/tif_ojpeg.c
index cb84be9..60e4eca 100644
--- a/third_party/libtiff/tif_ojpeg.c
+++ b/third_party/libtiff/tif_ojpeg.c
@@ -1,4 +1,4 @@
-/* $Id: tif_ojpeg.c,v 1.65 2016-09-04 21:32:56 erouault Exp $ */
+/* $Id: tif_ojpeg.c,v 1.69 2017-04-27 17:29:26 erouault Exp $ */
 
 /* WARNING: The type of JPEG encapsulation defined by the TIFF Version 6.0
    specification is now totally obsolete and deprecated for new applications and
@@ -253,7 +253,7 @@
 
 typedef struct {
 	TIFF* tif;
-	int decoder_ok;
+        int decoder_ok;
 	#ifndef LIBJPEG_ENCAP_EXTERNAL
 	JMP_BUF exit_jmpbuf;
 	#endif
@@ -795,14 +795,14 @@
 static int
 OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
 {
-	static const char module[]="OJPEGDecode";
+        static const char module[]="OJPEGDecode";
 	OJPEGState* sp=(OJPEGState*)tif->tif_data;
 	(void)s;
-	if( !sp->decoder_ok )
-	{
-		TIFFErrorExt(tif->tif_clientdata,module,"Cannot decode: decoder not correctly initialized");
-		return 0;
-	}
+        if( !sp->decoder_ok )
+        {
+            TIFFErrorExt(tif->tif_clientdata,module,"Cannot decode: decoder not correctly initialized");
+            return 0;
+        }
 	if (sp->libjpeg_jpeg_query_style==0)
 	{
 		if (OJPEGDecodeRaw(tif,buf,cc)==0)
@@ -1799,10 +1799,10 @@
 			TIFFSeekFile(tif,sp->qtable_offset[m],SEEK_SET); 
 			p=(uint32)TIFFReadFile(tif,&ob[sizeof(uint32)+5],64);
 			if (p!=64)
-			{
-				_TIFFfree(ob);
+                        {
+                                _TIFFfree(ob);
 				return(0);
-			}
+                        }
 			if (sp->qtable[m]!=0)
 				_TIFFfree(sp->qtable[m]);
 			sp->qtable[m]=ob;
@@ -1868,10 +1868,10 @@
 				rb[sizeof(uint32)+5+n]=o[n];
 			p=(uint32)TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q);
 			if (p!=q)
-			{
-				_TIFFfree(rb);
+                        {
+                                _TIFFfree(rb);
 				return(0);
-			}
+                        }
 			if (sp->dctable[m]!=0)
 				_TIFFfree(sp->dctable[m]);
 			sp->dctable[m]=rb;
@@ -1937,11 +1937,11 @@
 				rb[sizeof(uint32)+5+n]=o[n];
 			p=(uint32)TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q);
 			if (p!=q)
-			{
-				_TIFFfree(rb);
+                        {
+                                _TIFFfree(rb);
 				return(0);
-			}
-			if (sp->actable[m])
+                        }
+			if (sp->actable[m]!=0)
 				_TIFFfree(sp->actable[m]);
 			sp->actable[m]=rb;
 			sp->sos_tda[m]=(sp->sos_tda[m]|m);
diff --git a/third_party/libtiff/tif_open.c b/third_party/libtiff/tif_open.c
index 5c9036e..a7279e1 100644
--- a/third_party/libtiff/tif_open.c
+++ b/third_party/libtiff/tif_open.c
@@ -1,4 +1,4 @@
-/* $Id: tif_open.c,v 1.47 2016-01-23 21:20:34 erouault Exp $ */
+/* $Id: tif_open.c,v 1.48 2016-11-20 22:29:47 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -279,10 +279,10 @@
 		 * Setup header and write.
 		 */
 		#ifdef WORDS_BIGENDIAN
-		tif->tif_header.common.tiff_magic = tif->tif_flags & TIFF_SWAB
+		tif->tif_header.common.tiff_magic = (tif->tif_flags & TIFF_SWAB)
 		    ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN;
 		#else
-		tif->tif_header.common.tiff_magic = tif->tif_flags & TIFF_SWAB
+		tif->tif_header.common.tiff_magic = (tif->tif_flags & TIFF_SWAB)
 		    ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN;
 		#endif
 		if (!(tif->tif_flags&TIFF_BIGTIFF))
diff --git a/third_party/libtiff/tif_packbits.c b/third_party/libtiff/tif_packbits.c
index 92185e7..18904b0 100644
--- a/third_party/libtiff/tif_packbits.c
+++ b/third_party/libtiff/tif_packbits.c
@@ -1,4 +1,4 @@
-/* $Id: tif_packbits.c,v 1.24 2016-09-04 21:32:56 erouault Exp $ */
+/* $Id: tif_packbits.c,v 1.26 2017-05-14 02:26:07 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -99,7 +99,7 @@
 				slop = (long)(op - lastliteral);
 				tif->tif_rawcc += (tmsize_t)(lastliteral - tif->tif_rawcp);
 				if (!TIFFFlushData1(tif))
-					return (-1);
+					return (0);
 				op = tif->tif_rawcp;
 				while (slop-- > 0)
 					*op++ = *lastliteral++;
@@ -107,7 +107,7 @@
 			} else {
 				tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp);
 				if (!TIFFFlushData1(tif))
-					return (-1);
+					return (0);
 				op = tif->tif_rawcp;
 			}
 		}
diff --git a/third_party/libtiff/tif_pixarlog.c b/third_party/libtiff/tif_pixarlog.c
index c2903bf..f226395 100644
--- a/third_party/libtiff/tif_pixarlog.c
+++ b/third_party/libtiff/tif_pixarlog.c
@@ -1,4 +1,4 @@
-/* $Id: tif_pixarlog.c,v 1.48 2016-09-23 22:12:18 erouault Exp $ */
+/* $Id: tif_pixarlog.c,v 1.53 2017-05-17 09:53:06 erouault Exp $ */
 
 /*
  * Copyright (c) 1996-1997 Sam Leffler
@@ -636,29 +636,27 @@
 	return guess;
 }
 
+#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0))
+#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1)
+
 static tmsize_t
 multiply_ms(tmsize_t m1, tmsize_t m2)
 {
-	tmsize_t bytes = m1 * m2;
-
-	if (m1 && bytes / m1 != m2)
-		bytes = 0;
-
-	return bytes;
+        if( m1 == 0 || m2 > TIFF_TMSIZE_T_MAX / m1 )
+            return 0;
+        return m1 * m2;
 }
 
 static tmsize_t
 add_ms(tmsize_t m1, tmsize_t m2)
 {
-	tmsize_t bytes = m1 + m2;
-
 	/* if either input is zero, assume overflow already occurred */
 	if (m1 == 0 || m2 == 0)
-		bytes = 0;
-	else if (bytes <= m1 || bytes <= m2)
-		bytes = 0;
+		return 0;
+	else if (m1 > TIFF_TMSIZE_T_MAX - m2)
+		return 0;
 
-	return bytes;
+	return m1 + m2;
 }
 
 static int
@@ -678,6 +676,12 @@
 
 	assert(sp != NULL);
 
+	/* This function can possibly be called several times by */
+	/* PredictorSetupDecode() if this function succeeds but */
+	/* PredictorSetup() fails */
+	if( (sp->state & PLSTATE_INIT) != 0 )
+		return 1;
+
 	/* Make sure no byte swapping happens on the data
 	 * after decompression. */
 	tif->tif_postdecode = _TIFFNoPostDecode;  
@@ -699,6 +703,9 @@
 	if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
 		sp->user_datafmt = PixarLogGuessDataFmt(td);
 	if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) {
+                _TIFFfree(sp->tbuf);
+                sp->tbuf = NULL;
+                sp->tbuf_size = 0;
 		TIFFErrorExt(tif->tif_clientdata, module,
 			"PixarLog compression can't handle bits depth/data format combination (depth: %d)", 
 			td->td_bitspersample);
@@ -706,6 +713,9 @@
 	}
 
 	if (inflateInit(&sp->stream) != Z_OK) {
+                _TIFFfree(sp->tbuf);
+                sp->tbuf = NULL;
+                sp->tbuf_size = 0;
 		TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg ? sp->stream.msg : "(null)");
 		return (0);
 	} else {
@@ -774,6 +784,10 @@
 
 	(void) s;
 	assert(sp != NULL);
+
+        sp->stream.next_in = tif->tif_rawcp;
+	sp->stream.avail_in = (uInt) tif->tif_rawcc;
+
 	sp->stream.next_out = (unsigned char *) sp->tbuf;
 	assert(sizeof(sp->stream.avail_out)==4);  /* if this assert gets raised,
 	    we need to simplify this code to reflect a ZLib that is likely updated
@@ -819,6 +833,9 @@
 		return (0);
 	}
 
+        tif->tif_rawcp = sp->stream.next_in;
+        tif->tif_rawcc = sp->stream.avail_in;
+
 	up = sp->tbuf;
 	/* Swap bytes in the data if from a different endian machine. */
 	if (tif->tif_flags & TIFF_SWAB)
@@ -1233,7 +1250,7 @@
 static void
 PixarLogClose(TIFF* tif)
 {
-	PixarLogState* sp = (PixarLogState*) tif->tif_data;
+        PixarLogState* sp = (PixarLogState*) tif->tif_data;
 	TIFFDirectory *td = &tif->tif_dir;
 
 	assert(sp != 0);
@@ -1246,18 +1263,18 @@
 	 * the PIXARLOGDATFMT pseudo-tag.
 	 */
 
-	if (sp->state&PLSTATE_INIT) {
-		/* We test the state to avoid an issue such as in
-		 * http://bugzilla.maptools.org/show_bug.cgi?id=2604
-		 * What appends in that case is that the bitspersample is 1 and
-		 * a TransferFunction is set. The size of the TransferFunction
-		 * depends on 1<<bitspersample. So if we increase it, an access
-		 * out of the buffer will happen at directory flushing.
-		 * Another option would be to clear those targs. 
-		 */
-		td->td_bitspersample = 8;
-		td->td_sampleformat = SAMPLEFORMAT_UINT;
-	}
+        if (sp->state&PLSTATE_INIT) {
+            /* We test the state to avoid an issue such as in
+             * http://bugzilla.maptools.org/show_bug.cgi?id=2604
+             * What appends in that case is that the bitspersample is 1 and
+             * a TransferFunction is set. The size of the TransferFunction
+             * depends on 1<<bitspersample. So if we increase it, an access
+             * out of the buffer will happen at directory flushing.
+             * Another option would be to clear those targs. 
+             */
+            td->td_bitspersample = 8;
+            td->td_sampleformat = SAMPLEFORMAT_UINT;
+        }
 }
 
 static void
diff --git a/third_party/libtiff/tif_predict.c b/third_party/libtiff/tif_predict.c
index 1bb78e2..7a60a39 100644
--- a/third_party/libtiff/tif_predict.c
+++ b/third_party/libtiff/tif_predict.c
@@ -1,4 +1,4 @@
-/* $Id: tif_predict.c,v 1.40 2016-11-04 09:19:13 erouault Exp $ */
+/* $Id: tif_predict.c,v 1.43 2017-05-10 15:21:16 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -117,11 +117,11 @@
 	TIFFPredictorState* sp = PredictorState(tif);
 	TIFFDirectory* td = &tif->tif_dir;
 
+	/* Note: when PredictorSetup() fails, the effets of setupdecode() */
+	/* will not be "cancelled" so setupdecode() might be robust to */
+	/* be called several times. */
 	if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
-	{
-		(*tif->tif_cleanup)(tif);
 		return 0;
-	}
 
 	if (sp->predictor == 2) {
 		switch (td->td_bitspersample) {
@@ -262,11 +262,12 @@
 
 #define REPEAT4(n, op)		\
     switch (n) {		\
-    default: { tmsize_t i; for (i = n-4; i > 0; i--) { op; } } \
-    case 4:  op;		\
-    case 3:  op;		\
-    case 2:  op;		\
-    case 1:  op;		\
+    default: { \
+        tmsize_t i; for (i = n-4; i > 0; i--) { op; } }  /*-fallthrough*/  \
+    case 4:  op; /*-fallthrough*/ \
+    case 3:  op; /*-fallthrough*/ \
+    case 2:  op; /*-fallthrough*/ \
+    case 1:  op; /*-fallthrough*/ \
     case 0:  ;			\
     }
 
@@ -800,7 +801,7 @@
 			case 2: fprintf(fd, "horizontal differencing "); break;
 			case 3: fprintf(fd, "floating point predictor "); break;
 		}
-		fprintf(fd, "%u (0x%x)\n", sp->predictor, sp->predictor);
+		fprintf(fd, "%d (0x%x)\n", sp->predictor, sp->predictor);
 	}
 	if (sp->printdir)
 		(*sp->printdir)(tif, fd, flags);
diff --git a/third_party/libtiff/tif_print.c b/third_party/libtiff/tif_print.c
index 186f2ee..24d4b98 100644
--- a/third_party/libtiff/tif_print.c
+++ b/third_party/libtiff/tif_print.c
@@ -1,4 +1,4 @@
-/* $Id: tif_print.c,v 1.64 2015-12-06 22:19:56 erouault Exp $ */
+/* $Id: tif_print.c,v 1.65 2016-11-20 22:31:22 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -262,7 +262,7 @@
 		if (td->td_subfiletype & FILETYPE_MASK)
 			fprintf(fd, "%stransparency mask", sep);
 		fprintf(fd, " (%lu = 0x%lx)\n",
-		    (long) td->td_subfiletype, (long) td->td_subfiletype);
+		    (unsigned long) td->td_subfiletype, (long) td->td_subfiletype);
 	}
 	if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS)) {
 		fprintf(fd, "  Image Width: %lu Image Length: %lu",
@@ -521,7 +521,7 @@
 			fprintf(fd, "\n");
 			n = 1L<<td->td_bitspersample;
 			for (l = 0; l < n; l++)
-				fprintf(fd, "   %5lu: %5u %5u %5u\n",
+				fprintf(fd, "   %5ld: %5u %5u %5u\n",
 				    l,
 				    td->td_colormap[0][l],
 				    td->td_colormap[1][l],
@@ -544,7 +544,7 @@
 			n = 1L<<td->td_bitspersample;
 			for (l = 0; l < n; l++) {
 				uint16 i;
-				fprintf(fd, "    %2lu: %5u",
+				fprintf(fd, "    %2ld: %5u",
 				    l, td->td_transferfunction[0][l]);
 				for (i = 1; i < td->td_samplesperpixel; i++)
 					fprintf(fd, " %5u",
@@ -661,7 +661,7 @@
 		uint32 s;
 
 		fprintf(fd, "  %lu %s:\n",
-		    (long) td->td_nstrips,
+		    (unsigned long) td->td_nstrips,
 		    isTiled(tif) ? "Tiles" : "Strips");
 		for (s = 0; s < td->td_nstrips; s++)
 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
diff --git a/third_party/libtiff/tif_read.c b/third_party/libtiff/tif_read.c
index 12c331b..ad0a778 100644
--- a/third_party/libtiff/tif_read.c
+++ b/third_party/libtiff/tif_read.c
@@ -1,4 +1,4 @@
-/* $Id: tif_read.c,v 1.49 2016-07-10 18:00:21 erouault Exp $ */
+/* $Id: tif_read.c,v 1.59 2017-05-13 15:34:06 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -47,6 +47,121 @@
 #define NOSTRIP ((uint32)(-1))       /* undefined state */
 #define NOTILE ((uint32)(-1))         /* undefined state */
 
+#define INITIAL_THRESHOLD (1024 * 1024)
+#define THRESHOLD_MULTIPLIER 10
+#define MAX_THRESHOLD (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * INITIAL_THRESHOLD)
+
+/* Read 'size' bytes in tif_rawdata buffer starting at offset 'rawdata_offset'
+ * Returns 1 in case of success, 0 otherwise. */
+static int TIFFReadAndRealloc( TIFF* tif, tmsize_t size,
+                               tmsize_t rawdata_offset,
+                               int is_strip, uint32 strip_or_tile,
+                               const char* module )
+{
+#if SIZEOF_VOIDP == 8 || SIZEOF_SIZE_T == 8
+        tmsize_t threshold = INITIAL_THRESHOLD;
+#endif
+        tmsize_t already_read = 0;
+
+        /* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */
+        /* so as to avoid allocating too much memory in case the file is too */
+        /* short. We could ask for the file size, but this might be */
+        /* expensive with some I/O layers (think of reading a gzipped file) */
+        /* Restrict to 64 bit processes, so as to avoid reallocs() */
+        /* on 32 bit processes where virtual memory is scarce.  */
+        while( already_read < size )
+        {
+            tmsize_t bytes_read;
+            tmsize_t to_read = size - already_read;
+#if SIZEOF_VOIDP == 8 || SIZEOF_SIZE_T == 8
+            if( to_read >= threshold && threshold < MAX_THRESHOLD &&
+                already_read + to_read + rawdata_offset > tif->tif_rawdatasize )
+            {
+                to_read = threshold;
+                threshold *= THRESHOLD_MULTIPLIER;
+            }
+#endif
+            if (already_read + to_read + rawdata_offset > tif->tif_rawdatasize) {
+                uint8* new_rawdata;
+                assert((tif->tif_flags & TIFF_MYBUFFER) != 0);
+                tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64(
+                        (uint64)already_read + to_read + rawdata_offset, 1024);
+                if (tif->tif_rawdatasize==0) {
+                    TIFFErrorExt(tif->tif_clientdata, module,
+                                "Invalid buffer size");
+                    return 0;
+                }
+                new_rawdata = (uint8*) _TIFFrealloc(
+                                tif->tif_rawdata, tif->tif_rawdatasize);
+                if( new_rawdata == 0 )
+                {
+                    TIFFErrorExt(tif->tif_clientdata, module,
+                        "No space for data buffer at scanline %lu",
+                        (unsigned long) tif->tif_row);
+                    _TIFFfree(tif->tif_rawdata);
+                    tif->tif_rawdata = 0;
+                    tif->tif_rawdatasize = 0;
+                    return 0;
+                }
+                tif->tif_rawdata = new_rawdata;
+            }
+
+            bytes_read = TIFFReadFile(tif,
+                tif->tif_rawdata + rawdata_offset + already_read, to_read);
+            already_read += bytes_read;
+            if (bytes_read != to_read) {
+                memset( tif->tif_rawdata + rawdata_offset + already_read, 0,
+                        tif->tif_rawdatasize - rawdata_offset - already_read );
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+                if( is_strip )
+                {
+                    TIFFErrorExt(tif->tif_clientdata, module,
+                        "Read error at scanline %lu; got %I64u bytes, "
+                        "expected %I64u",
+                                        (unsigned long) tif->tif_row,
+                                        (unsigned __int64) already_read,
+                                        (unsigned __int64) size);
+                }
+                else
+                {
+                    TIFFErrorExt(tif->tif_clientdata, module,
+                        "Read error at row %lu, col %lu, tile %lu; "
+                        "got %I64u bytes, expected %I64u",
+                                        (unsigned long) tif->tif_row,
+                                        (unsigned long) tif->tif_col,
+                                        (unsigned long) strip_or_tile,
+                                        (unsigned __int64) already_read,
+                                        (unsigned __int64) size);
+                }
+#else
+                if( is_strip )
+                {
+                    TIFFErrorExt(tif->tif_clientdata, module,
+                        "Read error at scanline %lu; got %llu bytes, "
+                        "expected %llu",
+                                        (unsigned long) tif->tif_row,
+                                        (unsigned long long) already_read,
+                                        (unsigned long long) size);
+                }
+                else
+                {
+                    TIFFErrorExt(tif->tif_clientdata, module,
+                        "Read error at row %lu, col %lu, tile %lu; "
+                        "got %llu bytes, expected %llu",
+                                        (unsigned long) tif->tif_row,
+                                        (unsigned long) tif->tif_col,
+                                        (unsigned long) strip_or_tile,
+                                        (unsigned long long) already_read,
+                                        (unsigned long long) size);
+                }
+#endif
+                return 0;
+            }
+        }
+        return 1;
+}
+
+
 static int
 TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
 {
@@ -54,7 +169,8 @@
 	register TIFFDirectory *td = &tif->tif_dir;
         tmsize_t unused_data;
         uint64 read_offset;
-        tmsize_t cc, to_read;
+        tmsize_t to_read;
+        tmsize_t read_ahead_mod;
         /* tmsize_t bytecountm; */
         
         if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
@@ -67,7 +183,14 @@
          */
 
         /* bytecountm=(tmsize_t) td->td_stripbytecount[strip]; */
-        if (read_ahead*2 > tif->tif_rawdatasize) {
+
+        /* Not completely sure where the * 2 comes from, but probably for */
+        /* an exponentional growth strategy of tif_rawdatasize */
+        if( read_ahead < TIFF_TMSIZE_T_MAX / 2 )
+                read_ahead_mod = read_ahead * 2;
+        else
+                read_ahead_mod = read_ahead;
+        if (read_ahead_mod > tif->tif_rawdatasize) {
                 assert( restart );
                 
                 tif->tif_curstrip = NOSTRIP;
@@ -77,8 +200,6 @@
                                      (unsigned long) strip);
                         return (0);
                 }
-                if (!TIFFReadBufferSetup(tif, 0, read_ahead*2))
-                        return (0);
         }
 
         if( restart )
@@ -118,7 +239,10 @@
         /*
         ** How much do we want to read?
         */
-        to_read = tif->tif_rawdatasize - unused_data;
+        if( read_ahead_mod > tif->tif_rawdatasize )
+                to_read = read_ahead_mod - unused_data;
+        else
+                to_read = tif->tif_rawdatasize - unused_data;
         if( (uint64) to_read > td->td_stripbytecount[strip] 
             - tif->tif_rawdataoff - tif->tif_rawdataloaded )
         {
@@ -127,25 +251,14 @@
         }
 
 	assert((tif->tif_flags&TIFF_BUFFERMMAP)==0);
-        cc = TIFFReadFile(tif, tif->tif_rawdata + unused_data, to_read);
-
-        if (cc != to_read) {
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
-                TIFFErrorExt(tif->tif_clientdata, module,
-                             "Read error at scanline %lu; got %I64u bytes, expected %I64u",
-                             (unsigned long) tif->tif_row,
-                             (unsigned __int64) cc,
-                             (unsigned __int64) to_read);
-#else
-                TIFFErrorExt(tif->tif_clientdata, module,
-                             "Read error at scanline %lu; got %llu bytes, expected %llu",
-                             (unsigned long) tif->tif_row,
-                             (unsigned long long) cc,
-                             (unsigned long long) to_read);
-#endif
+        if( !TIFFReadAndRealloc( tif, to_read, unused_data,
+                                 1, /* is_strip */
+                                 0, /* strip_or_tile */
+                                 module) )
+        {
                 return 0;
         }
-        
+
         tif->tif_rawdataoff = tif->tif_rawdataoff + tif->tif_rawdataloaded - unused_data ;
         tif->tif_rawdataloaded = unused_data + to_read;
 
@@ -164,7 +277,10 @@
         if( restart )
                 return TIFFStartStrip(tif, strip);
         else
+        {
+                tif->tif_rawcc = tif->tif_rawdataloaded;
                 return 1;
+        }
 }
 
 /*
@@ -219,7 +335,18 @@
         
         if( !whole_strip )
         {
-                read_ahead = tif->tif_scanlinesize * 16 + 5000;
+                /* 16 is for YCbCr mode where we may need to read 16 */
+                /* lines at a time to get a decompressed line, and 5000 */
+                /* is some constant value, for example for JPEG tables */
+                if( tif->tif_scanlinesize < TIFF_TMSIZE_T_MAX / 16 &&
+                    tif->tif_scanlinesize * 16 < TIFF_TMSIZE_T_MAX - 5000 )
+                {
+                        read_ahead = tif->tif_scanlinesize * 16 + 5000;
+                }
+                else
+                {
+                        read_ahead = tif->tif_scanlinesize;
+                }
         }
 
         /*
@@ -317,7 +444,8 @@
 /*
  * Calculate the strip size according to the number of
  * rows in the strip (check for truncated last strip on any
- * of the separations). */
+ * of the separations).
+ */
 static tmsize_t TIFFReadEncodedStripGetStripSize(TIFF* tif, uint32 strip, uint16* pplane)
 {
 	static const char module[] = "TIFFReadEncodedStrip";
@@ -349,8 +477,8 @@
 	stripsize=TIFFVStripSize(tif,rows);
 	if (stripsize==0)
 		return((tmsize_t)(-1));
-  return stripsize;
- }
+    return stripsize;
+}
 
 /*
  * Read a strip of data and decompress the specified
@@ -366,7 +494,7 @@
 
   stripsize=TIFFReadEncodedStripGetStripSize(tif, strip, &plane);
   if (stripsize==((tmsize_t)(-1)))
-    return((tmsize_t)(-1));
+      return((tmsize_t)(-1));
 
     /* shortcut to avoid an extra memcpy() */
     if( td->td_compression == COMPRESSION_NONE &&
@@ -438,6 +566,7 @@
 
 }
 
+
 static tmsize_t
 TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,
     const char* module)
@@ -475,25 +604,25 @@
 			return ((tmsize_t)(-1));
 		}
 	} else {
-		tmsize_t ma;
+		tmsize_t ma = 0;
 		tmsize_t n;
 		if ((td->td_stripoffset[strip] > (uint64)TIFF_TMSIZE_T_MAX)||
-				((ma=(tmsize_t)td->td_stripoffset[strip])>tif->tif_size))
-		{
-			n=0;
-		}
-		else if( ma > TIFF_TMSIZE_T_MAX - size )
-		{
-			n=0;
-		}
-		else
-		{
-			tmsize_t mb=ma+size;
-			if (mb>tif->tif_size)
-				n=tif->tif_size-ma;
-			else
-				n=size;
-		}
+                    ((ma=(tmsize_t)td->td_stripoffset[strip])>tif->tif_size))
+                {
+                    n=0;
+                }
+                else if( ma > TIFF_TMSIZE_T_MAX - size )
+                {
+                    n=0;
+                }
+                else
+                {
+                    tmsize_t mb=ma+size;
+                    if (mb>tif->tif_size)
+                            n=tif->tif_size-ma;
+                    else
+                            n=size;
+                }
 		if (n!=size) {
 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
 			TIFFErrorExt(tif->tif_clientdata, module,
@@ -518,6 +647,43 @@
 	return (size);
 }
 
+static tmsize_t
+TIFFReadRawStripOrTile2(TIFF* tif, uint32 strip_or_tile, int is_strip,
+                        tmsize_t size, const char* module)
+{
+        TIFFDirectory *td = &tif->tif_dir;
+
+        assert( !isMapped(tif) );
+        assert((tif->tif_flags&TIFF_NOREADRAW)==0);
+
+        if (!SeekOK(tif, td->td_stripoffset[strip_or_tile])) {
+            if( is_strip )
+            {
+                TIFFErrorExt(tif->tif_clientdata, module,
+                    "Seek error at scanline %lu, strip %lu",
+                    (unsigned long) tif->tif_row,
+                    (unsigned long) strip_or_tile);
+            }
+            else
+            {
+                TIFFErrorExt(tif->tif_clientdata, module,
+                    "Seek error at row %lu, col %lu, tile %lu",
+                    (unsigned long) tif->tif_row,
+                    (unsigned long) tif->tif_col,
+                    (unsigned long) strip_or_tile);
+            }
+            return ((tmsize_t)(-1));
+        }
+
+        if( !TIFFReadAndRealloc( tif, size, 0, is_strip,
+                                 strip_or_tile, module ) )
+        {
+            return ((tmsize_t)(-1));
+        }
+
+        return (size);
+}
+
 /*
  * Read a strip of data from the file.
  */
@@ -599,6 +765,39 @@
 #endif
 			return (0);
 		}
+
+		/* To avoid excessive memory allocations: */
+		/* Byte count should normally not be larger than a number of */
+		/* times the uncompressed size plus some margin */
+                if( bytecount > 1024 * 1024 )
+                {
+			/* 10 and 4096 are just values that could be adjusted. */
+			/* Hopefully they are safe enough for all codecs */
+			tmsize_t stripsize = TIFFStripSize(tif);
+			if( stripsize != 0 &&
+			    (bytecount - 4096) / 10 > (uint64)stripsize  )
+			{
+				uint64 newbytecount = (uint64)stripsize * 10 + 4096;
+				if( (int64)newbytecount >= 0 )
+				{
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+					TIFFWarningExt(tif->tif_clientdata, module,
+					  "Too large strip byte count %I64u, strip %lu. Limiting to %I64u",
+					     (unsigned __int64) bytecount,
+					     (unsigned long) strip,
+					     (unsigned __int64) newbytecount);
+#else
+					TIFFErrorExt(tif->tif_clientdata, module,
+					  "Too large strip byte count %llu, strip %lu. Limiting to %llu",
+					     (unsigned long long) bytecount,
+					     (unsigned long) strip,
+					     (unsigned long long) newbytecount);
+#endif
+					bytecount = newbytecount;
+				}
+			}
+		}
+
 		if (isMapped(tif) &&
 		    (isFillOrder(tif, td->td_fillorder)
 		    || (tif->tif_flags & TIFF_NOBITREV))) {
@@ -680,13 +879,6 @@
 				TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
 				return(0);
 			}
-			const tmsize_t size=isMapped(tif)? tif->tif_size : (tmsize_t)TIFFGetFileSize(tif);
-			if (bytecountm > size) {
-				TIFFErrorExt(tif->tif_clientdata, module,
-					"Requested read strip size %lu is too large",
-					(unsigned long) strip);
-				return (0);
-			}
 			if (bytecountm > tif->tif_rawdatasize) {
 				tif->tif_curstrip = NOSTRIP;
 				if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
@@ -695,17 +887,36 @@
 					    (unsigned long) strip);
 					return (0);
 				}
-				if (!TIFFReadBufferSetup(tif, 0, bytecountm))
-					return (0);
 			}
 			if (tif->tif_flags&TIFF_BUFFERMMAP) {
 				tif->tif_curstrip = NOSTRIP;
-				if (!TIFFReadBufferSetup(tif, 0, bytecountm))
-					return (0);
+				tif->tif_rawdata = NULL;
+				tif->tif_rawdatasize = 0;
+				tif->tif_flags &= ~TIFF_BUFFERMMAP;
 			}
-			if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata,
-				bytecountm, module) != bytecountm)
-				return (0);
+
+			if( isMapped(tif) )
+			{
+				if (bytecountm > tif->tif_rawdatasize &&
+				    !TIFFReadBufferSetup(tif, 0, bytecountm))
+				{
+					return (0);
+				}
+				if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata,
+				    bytecountm, module) != bytecountm)
+				{
+					return (0);
+				}
+			}
+			else
+			{
+				if (TIFFReadRawStripOrTile2(tif, strip, 1,
+				    bytecountm, module) != bytecountm)
+				{
+					return (0);
+				}
+			}
+
 
                         tif->tif_rawdataoff = 0;
                         tif->tif_rawdataloaded = bytecountm;
@@ -785,7 +996,6 @@
 		return ((tmsize_t)(-1));
 }
 
-
 /* Variant of TIFFReadTile() that does 
  * * if *buf == NULL, *buf = _TIFFmalloc(bufsizetoalloc) only after TIFFFillTile() has
  *   suceeded. This avoid excessive memory allocation in case of truncated
@@ -857,6 +1067,7 @@
         return ((tmsize_t)(-1));
 }
 
+
 static tmsize_t
 TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* module)
 {
@@ -1060,18 +1271,36 @@
 					    (unsigned long) tile);
 					return (0);
 				}
-				if (!TIFFReadBufferSetup(tif, 0, bytecountm))
-					return (0);
 			}
 			if (tif->tif_flags&TIFF_BUFFERMMAP) {
 				tif->tif_curtile = NOTILE;
-				if (!TIFFReadBufferSetup(tif, 0, bytecountm))
-					return (0);
+				tif->tif_rawdata = NULL;
+				tif->tif_rawdatasize = 0;
+				tif->tif_flags &= ~TIFF_BUFFERMMAP;
 			}
 
-			if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata,
-			    bytecountm, module) != bytecountm)
-				return (0);
+			if( isMapped(tif) )
+			{
+				if (bytecountm > tif->tif_rawdatasize &&
+				    !TIFFReadBufferSetup(tif, 0, bytecountm))
+				{
+					return (0);
+				}
+				if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata,
+				    bytecountm, module) != bytecountm)
+				{
+					return (0);
+				}
+			}
+			else
+			{
+				if (TIFFReadRawStripOrTile2(tif, tile, 0,
+				    bytecountm, module) != bytecountm)
+				{
+					return (0);
+				}
+			}
+
 
                         tif->tif_rawdataoff = 0;
                         tif->tif_rawdataloaded = bytecountm;
@@ -1122,7 +1351,6 @@
 		/* Initialize to zero to avoid uninitialized buffers in case of */
                 /* short reads (http://bugzilla.maptools.org/show_bug.cgi?id=2651) */
 		tif->tif_rawdata = (uint8*) _TIFFcalloc(1, tif->tif_rawdatasize);
-
 		tif->tif_flags |= TIFF_MYBUFFER;
 	}
 	if (tif->tif_rawdata == NULL) {
@@ -1164,7 +1392,10 @@
 	else
 	{
 		tif->tif_rawcp = tif->tif_rawdata;
-		tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[strip];
+		if( tif->tif_rawdataloaded > 0 )
+			tif->tif_rawcc = tif->tif_rawdataloaded;
+		else
+			tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[strip];
 	}
 	return ((*tif->tif_predecode)(tif,
 			(uint16)(strip / td->td_stripsperimage)));
diff --git a/third_party/libtiff/tif_strip.c b/third_party/libtiff/tif_strip.c
index 3b55285..6e9f2ef 100644
--- a/third_party/libtiff/tif_strip.c
+++ b/third_party/libtiff/tif_strip.c
@@ -1,4 +1,4 @@
-/* $Id: tif_strip.c,v 1.37 2016-11-09 23:00:49 erouault Exp $ */
+/* $Id: tif_strip.c,v 1.38 2016-12-03 11:02:15 erouault Exp $ */
 
 /*
  * Copyright (c) 1991-1997 Sam Leffler
diff --git a/third_party/libtiff/tif_write.c b/third_party/libtiff/tif_write.c
index 34c4d81..4c216ec 100644
--- a/third_party/libtiff/tif_write.c
+++ b/third_party/libtiff/tif_write.c
@@ -1,4 +1,4 @@
-/* $Id: tif_write.c,v 1.45 2016-09-23 22:12:18 erouault Exp $ */
+/* $Id: tif_write.c,v 1.46 2016-12-03 21:57:44 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -476,22 +476,22 @@
     sample = (uint16)(tile/td->td_stripsperimage);
     if (!(*tif->tif_preencode)(tif, sample))
         return ((tmsize_t)(-1));
-        /* swab if needed - note that source buffer will be altered */
-	tif->tif_postdecode( tif, (uint8*) data, cc );
+    /* swab if needed - note that source buffer will be altered */
+    tif->tif_postdecode( tif, (uint8*) data, cc );
 
-	if (!(*tif->tif_encodetile)(tif, (uint8*) data, cc, sample))
-		return ((tmsize_t) -1);
-	if (!(*tif->tif_postencode)(tif))
-		return ((tmsize_t)(-1));
-	if (!isFillOrder(tif, td->td_fillorder) &&
-	    (tif->tif_flags & TIFF_NOBITREV) == 0)
-		TIFFReverseBits((uint8*)tif->tif_rawdata, tif->tif_rawcc);
-	if (tif->tif_rawcc > 0 && !TIFFAppendToStrip(tif, tile,
-	    tif->tif_rawdata, tif->tif_rawcc))
-		return ((tmsize_t)(-1));
-	tif->tif_rawcc = 0;
-	tif->tif_rawcp = tif->tif_rawdata;
-	return (cc);
+    if (!(*tif->tif_encodetile)(tif, (uint8*) data, cc, sample))
+            return ((tmsize_t) -1);
+    if (!(*tif->tif_postencode)(tif))
+            return ((tmsize_t)(-1));
+    if (!isFillOrder(tif, td->td_fillorder) &&
+        (tif->tif_flags & TIFF_NOBITREV) == 0)
+            TIFFReverseBits((uint8*)tif->tif_rawdata, tif->tif_rawcc);
+    if (tif->tif_rawcc > 0 && !TIFFAppendToStrip(tif, tile,
+        tif->tif_rawdata, tif->tif_rawcc))
+            return ((tmsize_t)(-1));
+    tif->tif_rawcc = 0;
+    tif->tif_rawcp = tif->tif_rawdata;
+    return (cc);
 }
 
 /*
diff --git a/third_party/libtiff/tif_zip.c b/third_party/libtiff/tif_zip.c
index 8c35aea..42943fb 100644
--- a/third_party/libtiff/tif_zip.c
+++ b/third_party/libtiff/tif_zip.c
@@ -1,4 +1,4 @@
-/* $Id: tif_zip.c,v 1.36 2016-11-12 16:48:28 erouault Exp $ */
+/* $Id: tif_zip.c,v 1.37 2017-05-10 15:21:16 erouault Exp $ */
 
 /*
  * Copyright (c) 1995-1997 Sam Leffler
@@ -107,7 +107,11 @@
 	    sp->state = 0;
 	}
 
-	if (inflateInit(&sp->stream) != Z_OK) {
+	/* This function can possibly be called several times by */
+	/* PredictorSetupDecode() if this function succeeds but */
+	/* PredictorSetup() fails */
+	if ((sp->state & ZSTATE_INIT_DECODE) == 0 &&
+	    inflateInit(&sp->stream) != Z_OK) {
 		TIFFErrorExt(tif->tif_clientdata, module, "%s", SAFE_MSG(sp));
 		return (0);
 	} else {
diff --git a/third_party/libtiff/tiffio.h b/third_party/libtiff/tiffio.h
index 7d0da76..f1d2fdc 100644
--- a/third_party/libtiff/tiffio.h
+++ b/third_party/libtiff/tiffio.h
@@ -1,4 +1,4 @@
-/* $Id: tiffio.h,v 1.92 2016-01-23 21:20:34 erouault Exp $ */
+/* $Id: tiffio.h,v 1.94 2017-01-11 19:02:49 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -432,6 +432,8 @@
 
 extern int TIFFReadRGBAStrip(TIFF*, uint32, uint32 * );
 extern int TIFFReadRGBATile(TIFF*, uint32, uint32, uint32 * );
+extern int TIFFReadRGBAStripExt(TIFF*, uint32, uint32 *, int stop_on_error );
+extern int TIFFReadRGBATileExt(TIFF*, uint32, uint32, uint32 *, int stop_on_error );
 extern int TIFFRGBAImageOK(TIFF*, char [1024]);
 extern int TIFFRGBAImageBegin(TIFFRGBAImage*, TIFF*, int, char [1024]);
 extern int TIFFRGBAImageGet(TIFFRGBAImage*, uint32*, uint32, uint32);
diff --git a/third_party/libtiff/tiffiop.h b/third_party/libtiff/tiffiop.h
index c42ebef..6fb47de 100644
--- a/third_party/libtiff/tiffiop.h
+++ b/third_party/libtiff/tiffiop.h
@@ -1,4 +1,4 @@
-/* $Id: tiffiop.h,v 1.89 2016-01-23 21:20:34 erouault Exp $ */
+/* $Id: tiffiop.h,v 1.90 2016-12-02 21:56:56 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -368,7 +368,6 @@
 _TIFFReadEncodedStripAndAllocBuffer(TIFF* tif, uint32 strip,
                                     void **buf, tmsize_t bufsizetoalloc,
                                     tmsize_t size_to_read);
-
 extern tmsize_t
 _TIFFReadEncodedTileAndAllocBuffer(TIFF* tif, uint32 tile,
                                     void **buf, tmsize_t bufsizetoalloc,
@@ -378,6 +377,7 @@
                             void **buf, tmsize_t bufsizetoalloc,
                             uint32 x, uint32 y, uint32 z, uint16 s);
 
+
 extern int TIFFInitDumpMode(TIFF*, int);
 #ifdef PACKBITS_SUPPORT
 extern int TIFFInitPackBits(TIFF*, int);
diff --git a/third_party/libtiff/tiffvers.h b/third_party/libtiff/tiffvers.h
index fe55c72..890e433 100644
--- a/third_party/libtiff/tiffvers.h
+++ b/third_party/libtiff/tiffvers.h
@@ -1,4 +1,4 @@
-#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.0.7\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc."
+#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.0.8\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 20161119
+#define TIFFLIB_VERSION 20170521