https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f87faf670321c45bc750d…
commit f87faf670321c45bc750dbd2e233b6a5db714313
Author: Thomas Faber <thomas.faber(a)reactos.org>
AuthorDate: Sun Dec 8 12:36:30 2019 +0100
Commit: Thomas Faber <thomas.faber(a)reactos.org>
CommitDate: Sun Dec 8 16:49:57 2019 +0100
[LIBTIFF] Update to version 4.1.0. CORE-16550
---
dll/3rdparty/libtiff/mkg3states.c | 2 +-
dll/3rdparty/libtiff/tif_aux.c | 75 +-
dll/3rdparty/libtiff/tif_dir.c | 66 +-
dll/3rdparty/libtiff/tif_dirread.c | 1239 +++++++++++++++++++--------
dll/3rdparty/libtiff/tif_dirwrite.c | 342 ++++++--
dll/3rdparty/libtiff/tif_flush.c | 118 ++-
dll/3rdparty/libtiff/tif_getimage.c | 34 +-
dll/3rdparty/libtiff/tif_jpeg.c | 17 +-
dll/3rdparty/libtiff/tif_luv.c | 25 +-
dll/3rdparty/libtiff/tif_lzw.c | 2 +
dll/3rdparty/libtiff/tif_ojpeg.c | 91 +-
dll/3rdparty/libtiff/tif_open.c | 19 +-
dll/3rdparty/libtiff/tif_packbits.c | 1 -
dll/3rdparty/libtiff/tif_pixarlog.c | 18 +-
dll/3rdparty/libtiff/tif_print.c | 11 +-
dll/3rdparty/libtiff/tif_read.c | 256 ++++--
dll/3rdparty/libtiff/tif_strip.c | 39 +-
dll/3rdparty/libtiff/tif_thunder.c | 10 +-
dll/3rdparty/libtiff/tif_tile.c | 28 +-
dll/3rdparty/libtiff/tif_version.c | 1 -
dll/3rdparty/libtiff/tif_webp.c | 45 +-
dll/3rdparty/libtiff/tif_write.c | 139 +--
dll/3rdparty/libtiff/tif_zip.c | 61 +-
media/doc/3rd Party Files.txt | 2 +-
sdk/include/reactos/libs/libtiff/tif_dir.h | 12 +-
sdk/include/reactos/libs/libtiff/tiffio.h | 15 +-
sdk/include/reactos/libs/libtiff/tiffiop.h | 22 +-
sdk/include/reactos/libs/libtiff/tiffvers.h | 4 +-
28 files changed, 1848 insertions(+), 846 deletions(-)
diff --git a/dll/3rdparty/libtiff/mkg3states.c b/dll/3rdparty/libtiff/mkg3states.c
index 54fc0599874..2cb9174c672 100644
--- a/dll/3rdparty/libtiff/mkg3states.c
+++ b/dll/3rdparty/libtiff/mkg3states.c
@@ -40,7 +40,7 @@
#include "tif_fax3.h"
#ifndef HAVE_GETOPT
-extern int getopt(int, char**, char*);
+extern int getopt(int argc, char * const argv[], const char *optstring);
#endif
#define streq(a,b) (strcmp(a,b) == 0)
diff --git a/dll/3rdparty/libtiff/tif_aux.c b/dll/3rdparty/libtiff/tif_aux.c
index f70f533f1c7..ef3f456ad8f 100644
--- a/dll/3rdparty/libtiff/tif_aux.c
+++ b/dll/3rdparty/libtiff/tif_aux.c
@@ -31,31 +31,66 @@
#include <precomp.h>
#include "tif_predict.h"
#include <math.h>
+#include <float.h>
uint32
_TIFFMultiply32(TIFF* tif, uint32 first, uint32 second, const char* where)
{
- uint32 bytes = first * second;
-
- if (second && bytes / second != first) {
+ if (second && first > TIFF_UINT32_MAX / second) {
TIFFErrorExt(tif->tif_clientdata, where, "Integer overflow in %s",
where);
- bytes = 0;
+ return 0;
}
- return bytes;
+ return first * second;
}
uint64
_TIFFMultiply64(TIFF* tif, uint64 first, uint64 second, const char* where)
{
- uint64 bytes = first * second;
-
- if (second && bytes / second != first) {
+ if (second && first > TIFF_UINT64_MAX / second) {
TIFFErrorExt(tif->tif_clientdata, where, "Integer overflow in %s",
where);
- bytes = 0;
+ return 0;
}
- return bytes;
+ return first * second;
+}
+
+tmsize_t
+_TIFFMultiplySSize(TIFF* tif, tmsize_t first, tmsize_t second, const char* where)
+{
+ if( first <= 0 || second <= 0 )
+ {
+ if( tif != NULL && where != NULL )
+ {
+ TIFFErrorExt(tif->tif_clientdata, where,
+ "Invalid argument to _TIFFMultiplySSize() in %s",
where);
+ }
+ return 0;
+ }
+
+ if( first > TIFF_TMSIZE_T_MAX / second )
+ {
+ if( tif != NULL && where != NULL )
+ {
+ TIFFErrorExt(tif->tif_clientdata, where,
+ "Integer overflow in %s", where);
+ }
+ return 0;
+ }
+ return first * second;
+}
+
+tmsize_t _TIFFCastUInt64ToSSize(TIFF* tif, uint64 val, const char* module)
+{
+ if( val > (uint64)TIFF_TMSIZE_T_MAX )
+ {
+ if( tif != NULL && module != NULL )
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
+ }
+ return 0;
+ }
+ return (tmsize_t)val;
}
void*
@@ -63,13 +98,14 @@ _TIFFCheckRealloc(TIFF* tif, void* buffer,
tmsize_t nmemb, tmsize_t elem_size, const char* what)
{
void* cp = NULL;
- tmsize_t bytes = nmemb * elem_size;
-
+ tmsize_t count = _TIFFMultiplySSize(tif, nmemb, elem_size, NULL);
/*
- * XXX: Check for integer overflow.
+ * Check for integer overflow.
*/
- if (nmemb && elem_size && bytes / elem_size == nmemb)
- cp = _TIFFrealloc(buffer, bytes);
+ if (count != 0)
+ {
+ cp = _TIFFrealloc(buffer, count);
+ }
if (cp == NULL) {
TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
@@ -358,6 +394,15 @@ _TIFFUInt64ToDouble(uint64 ui64)
}
}
+float _TIFFClampDoubleToFloat( double val )
+{
+ if( val > FLT_MAX )
+ return FLT_MAX;
+ if( val < -FLT_MAX )
+ return -FLT_MAX;
+ return (float)val;
+}
+
int _TIFFSeekOK(TIFF* tif, toff_t off)
{
/* Huge offsets, especially -1 / UINT64_MAX, can cause issues */
diff --git a/dll/3rdparty/libtiff/tif_dir.c b/dll/3rdparty/libtiff/tif_dir.c
index 66c40790548..96d0002cfc2 100644
--- a/dll/3rdparty/libtiff/tif_dir.c
+++ b/dll/3rdparty/libtiff/tif_dir.c
@@ -47,8 +47,8 @@ setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size)
*vpp = 0;
}
if (vp) {
- tmsize_t bytes = (tmsize_t)(nmemb * elem_size);
- if (elem_size && bytes / elem_size == nmemb)
+ tmsize_t bytes = _TIFFMultiplySSize(NULL, nmemb, elem_size, NULL);
+ if (bytes)
*vpp = (void*) _TIFFmalloc(bytes);
if (*vpp)
_TIFFmemcpy(*vpp, vp, bytes);
@@ -88,13 +88,15 @@ setDoubleArrayOneValue(double** vpp, double value, size_t nmemb)
* Install extra samples information.
*/
static int
-setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v)
+setExtraSamples(TIFF* tif, va_list ap, uint32* v)
{
/* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */
#define EXTRASAMPLE_COREL_UNASSALPHA 999
uint16* va;
uint32 i;
+ TIFFDirectory* td = &tif->tif_dir;
+ static const char module[] = "setExtraSamples";
*v = (uint16) va_arg(ap, uint16_vap);
if ((uint16) *v > td->td_samplesperpixel)
@@ -116,6 +118,18 @@ setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v)
return 0;
}
}
+
+ if ( td->td_transferfunction[0] != NULL && (td->td_samplesperpixel
- *v > 1) &&
+ !(td->td_samplesperpixel - td->td_extrasamples > 1))
+ {
+ TIFFWarningExt(tif->tif_clientdata,module,
+ "ExtraSamples tag value is changing, "
+ "but TransferFunction was read with a different value.
Cancelling it");
+ TIFFClrFieldBit(tif,FIELD_TRANSFERFUNCTION);
+ _TIFFfree(td->td_transferfunction[0]);
+ td->td_transferfunction[0] = NULL;
+ }
+
td->td_extrasamples = (uint16) *v;
_TIFFsetShortArray(&td->td_sampleinfo, va, td->td_extrasamples);
return 1;
@@ -153,15 +167,6 @@ 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)
{
@@ -285,6 +290,18 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
_TIFFfree(td->td_smaxsamplevalue);
td->td_smaxsamplevalue = NULL;
}
+ /* Test if 3 transfer functions instead of just one are now needed
+ See
http://bugzilla.maptools.org/show_bug.cgi?id=2820 */
+ if( td->td_transferfunction[0] != NULL && (v -
td->td_extrasamples > 1) &&
+ !(td->td_samplesperpixel - td->td_extrasamples > 1))
+ {
+ TIFFWarningExt(tif->tif_clientdata,module,
+ "SamplesPerPixel tag value is changing, "
+ "but TransferFunction was read with a different value.
Cancelling it");
+ TIFFClrFieldBit(tif,FIELD_TRANSFERFUNCTION);
+ _TIFFfree(td->td_transferfunction[0]);
+ td->td_transferfunction[0] = NULL;
+ }
}
td->td_samplesperpixel = (uint16) v;
break;
@@ -320,13 +337,13 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
dblval = va_arg(ap, double);
if( dblval < 0 )
goto badvaluedouble;
- td->td_xresolution = TIFFClampDoubleToFloat( dblval );
+ td->td_xresolution = _TIFFClampDoubleToFloat( dblval );
break;
case TIFFTAG_YRESOLUTION:
dblval = va_arg(ap, double);
if( dblval < 0 )
goto badvaluedouble;
- td->td_yresolution = TIFFClampDoubleToFloat( dblval );
+ td->td_yresolution = _TIFFClampDoubleToFloat( dblval );
break;
case TIFFTAG_PLANARCONFIG:
v = (uint16) va_arg(ap, uint16_vap);
@@ -335,10 +352,10 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
td->td_planarconfig = (uint16) v;
break;
case TIFFTAG_XPOSITION:
- td->td_xposition = TIFFClampDoubleToFloat( va_arg(ap, double) );
+ td->td_xposition = _TIFFClampDoubleToFloat( va_arg(ap, double) );
break;
case TIFFTAG_YPOSITION:
- td->td_yposition = TIFFClampDoubleToFloat( va_arg(ap, double) );
+ td->td_yposition = _TIFFClampDoubleToFloat( va_arg(ap, double) );
break;
case TIFFTAG_RESOLUTIONUNIT:
v = (uint16) va_arg(ap, uint16_vap);
@@ -361,7 +378,7 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
_TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32);
break;
case TIFFTAG_EXTRASAMPLES:
- if (!setExtraSamples(td, ap, &v))
+ if (!setExtraSamples(tif, ap, &v))
goto badvalue;
break;
case TIFFTAG_MATTEING:
@@ -684,7 +701,7 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
case TIFF_SRATIONAL:
case TIFF_FLOAT:
{
- float v2 = TIFFClampDoubleToFloat(va_arg(ap, double));
+ float v2 = _TIFFClampDoubleToFloat(va_arg(ap, double));
_TIFFmemcpy(val, &v2, tv_size);
}
break;
@@ -1002,12 +1019,12 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
case TIFFTAG_STRIPOFFSETS:
case TIFFTAG_TILEOFFSETS:
_TIFFFillStriles( tif );
- *va_arg(ap, uint64**) = td->td_stripoffset;
+ *va_arg(ap, uint64**) = td->td_stripoffset_p;
break;
case TIFFTAG_STRIPBYTECOUNTS:
case TIFFTAG_TILEBYTECOUNTS:
_TIFFFillStriles( tif );
- *va_arg(ap, uint64**) = td->td_stripbytecount;
+ *va_arg(ap, uint64**) = td->td_stripbytecount_p;
break;
case TIFFTAG_MATTEING:
*va_arg(ap, uint16*) =
@@ -1266,8 +1283,9 @@ TIFFFreeDirectory(TIFF* tif)
CleanupField(td_transferfunction[0]);
CleanupField(td_transferfunction[1]);
CleanupField(td_transferfunction[2]);
- CleanupField(td_stripoffset);
- CleanupField(td_stripbytecount);
+ CleanupField(td_stripoffset_p);
+ CleanupField(td_stripbytecount_p);
+ td->td_stripoffsetbyteallocsize = 0;
TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
@@ -1280,10 +1298,8 @@ TIFFFreeDirectory(TIFF* tif)
td->td_customValueCount = 0;
CleanupField(td_customValues);
-#if defined(DEFER_STRILE_LOAD)
_TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
_TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
-#endif
}
#undef CleanupField
@@ -1371,7 +1387,9 @@ TIFFDefaultDirectory(TIFF* tif)
td->td_tilewidth = 0;
td->td_tilelength = 0;
td->td_tiledepth = 1;
+#ifdef STRIPBYTECOUNTSORTED_UNUSED
td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */
+#endif
td->td_resolutionunit = RESUNIT_INCH;
td->td_sampleformat = SAMPLEFORMAT_UINT;
td->td_imagedepth = 1;
diff --git a/dll/3rdparty/libtiff/tif_dirread.c b/dll/3rdparty/libtiff/tif_dirread.c
index ad33d6272f0..432c5f84421 100644
--- a/dll/3rdparty/libtiff/tif_dirread.c
+++ b/dll/3rdparty/libtiff/tif_dirread.c
@@ -29,9 +29,6 @@
*/
/* Suggested pending improvements:
- * - add a field 'ignore' to the TIFFDirEntry structure, to flag status,
- * eliminating current use of the IGNORE value, and therefore eliminating
- * current irrational behaviour on tags with tag id code 0
* - add a field 'field_info' to the TIFFDirEntry structure, and set that with
* the pointer to the appropriate TIFFField structure early on in
* TIFFReadDirectory, so as to eliminate current possibly repetitive lookup.
@@ -41,9 +38,13 @@
#include <float.h>
#include <stdlib.h>
-#define IGNORE 0 /* tag placeholder used below */
#define FAILED_FII ((uint32) -1)
+/*
+ * Largest 64-bit signed integer value.
+ */
+#define TIFF_INT64_MAX ((int64)(TIFF_UINT64_MAX >> 1))
+
#ifdef HAVE_IEEEFP
# define TIFFCvtIEEEFloatToNative(tif, n, fp)
# define TIFFCvtIEEEDoubleToNative(tif, n, dp)
@@ -164,6 +165,7 @@ static int TIFFFetchNormalTag(TIFF*, TIFFDirEntry*, int recover);
static int TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uint64**
lpp);
static int TIFFFetchSubjectDistance(TIFF*, TIFFDirEntry*);
static void ChopUpSingleUncompressedStrip(TIFF*);
+static void TryChopUpUncompressedBigTiff(TIFF*);
static uint64 TIFFReadUInt64(const uint8 *value);
static int _TIFFGetMaxColorChannels(uint16 photometric);
@@ -205,6 +207,7 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryByte(TIFF* tif,
TIFFDirEntry* di
switch (direntry->tdir_type)
{
case TIFF_BYTE:
+ case TIFF_UNDEFINED: /* Support to read TIFF_UNDEFINED with field_readcount==1 */
TIFFReadDirEntryCheckedByte(tif,direntry,value);
return(TIFFReadDirEntryErrOk);
case TIFF_SBYTE:
@@ -3287,11 +3290,6 @@ static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeLongSlong(int32 value)
return(TIFFReadDirEntryErrOk);
}
-/*
- * Largest 32-bit unsigned integer value.
- */
-#define TIFF_UINT32_MAX 0xFFFFFFFFU
-
static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeLongLong8(uint64 value)
{
@@ -3310,8 +3308,6 @@ TIFFReadDirEntryCheckRangeLongSlong8(int64 value)
return(TIFFReadDirEntryErrOk);
}
-#undef TIFF_UINT32_MAX
-
static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSlongLong(uint32 value)
{
@@ -3377,11 +3373,6 @@ TIFFReadDirEntryCheckRangeLong8Slong8(int64 value)
return(TIFFReadDirEntryErrOk);
}
-/*
- * Largest 64-bit signed integer value.
- */
-#define TIFF_INT64_MAX ((int64)(((uint64) ~0) >> 1))
-
static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSlong8Long8(uint64 value)
{
@@ -3391,8 +3382,6 @@ TIFFReadDirEntryCheckRangeSlong8Long8(uint64 value)
return(TIFFReadDirEntryErrOk);
}
-#undef TIFF_INT64_MAX
-
static enum TIFFReadDirEntryErr
TIFFReadDirEntryData(TIFF* tif, uint64 offset, tmsize_t size, void* dest)
{
@@ -3405,13 +3394,13 @@ TIFFReadDirEntryData(TIFF* tif, uint64 offset, tmsize_t size,
void* dest)
} else {
size_t ma,mb;
ma=(size_t)offset;
+ if( (uint64)ma!=offset ||
+ ma > (~(size_t)0) - (size_t)size )
+ {
+ return TIFFReadDirEntryErrIo;
+ }
mb=ma+size;
- if (((uint64)ma!=offset)
- || (mb < ma)
- || (mb - ma != (size_t) size)
- || (mb < (size_t)size)
- || (mb > (size_t)tif->tif_size)
- )
+ if (mb > (size_t)tif->tif_size)
return(TIFFReadDirEntryErrIo);
_TIFFmemcpy(dest,tif->tif_base+ma,size);
}
@@ -3534,6 +3523,49 @@ static int _TIFFGetMaxColorChannels( uint16 photometric )
}
}
+static int ByteCountLooksBad(TIFF* tif)
+{
+ /*
+ * Assume we have wrong StripByteCount value (in case
+ * of single strip) in following cases:
+ * - it is equal to zero along with StripOffset;
+ * - it is larger than file itself (in case of uncompressed
+ * image);
+ * - it is smaller than the size of the bytes per row
+ * multiplied on the number of rows. The last case should
+ * not be checked in the case of writing new image,
+ * because we may do not know the exact strip size
+ * until the whole image will be written and directory
+ * dumped out.
+ */
+ uint64 bytecount = TIFFGetStrileByteCount(tif, 0);
+ uint64 offset = TIFFGetStrileOffset(tif, 0);
+ uint64 filesize;
+
+ if( offset == 0 )
+ return 0;
+ if (bytecount == 0)
+ return 1;
+ if ( tif->tif_dir.td_compression != COMPRESSION_NONE )
+ return 0;
+ filesize = TIFFGetFileSize(tif);
+ if( offset <= filesize && bytecount > filesize - offset )
+ return 1;
+ if( tif->tif_mode == O_RDONLY )
+ {
+ uint64 scanlinesize = TIFFScanlineSize64(tif);
+ if( tif->tif_dir.td_imagelength > 0 &&
+ scanlinesize > TIFF_UINT64_MAX / tif->tif_dir.td_imagelength )
+ {
+ return 1;
+ }
+ if( bytecount < scanlinesize * tif->tif_dir.td_imagelength)
+ return 1;
+ }
+ return 0;
+}
+
+
/*
* Read the next TIFF directory from a file and convert it to the internal
* format. We read directories sequentially.
@@ -3580,14 +3612,17 @@ TIFFReadDirectory(TIFF* tif)
uint16 nb;
for (na=ma+1, nb=mb+1; nb<dircount; na++, nb++)
{
- if (ma->tdir_tag==na->tdir_tag)
- na->tdir_tag=IGNORE;
+ if (ma->tdir_tag == na->tdir_tag) {
+ na->tdir_ignore = TRUE;
+ }
}
}
}
tif->tif_flags &= ~TIFF_BEENWRITING; /* reset before new dir */
tif->tif_flags &= ~TIFF_BUF4WRITE; /* reset before new dir */
+ tif->tif_flags &= ~TIFF_CHOPPEDUPARRAYS;
+
/* free any old stuff and reinit */
TIFFFreeDirectory(tif);
TIFFDefaultDirectory(tif);
@@ -3620,7 +3655,7 @@ TIFFReadDirectory(TIFF* tif)
{
if (!TIFFFetchNormalTag(tif,dp,0))
goto bad;
- dp->tdir_tag=IGNORE;
+ dp->tdir_ignore = TRUE;
}
dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_COMPRESSION);
if (dp)
@@ -3643,7 +3678,7 @@ TIFFReadDirectory(TIFF* tif)
}
if (!TIFFSetField(tif,TIFFTAG_COMPRESSION,value))
goto bad;
- dp->tdir_tag=IGNORE;
+ dp->tdir_ignore = TRUE;
}
else
{
@@ -3655,7 +3690,7 @@ TIFFReadDirectory(TIFF* tif)
*/
for (di=0, dp=dir; di<dircount; di++, dp++)
{
- if (dp->tdir_tag!=IGNORE)
+ if (!dp->tdir_ignore)
{
TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
if (fii == FAILED_FII)
@@ -3663,8 +3698,8 @@ TIFFReadDirectory(TIFF* tif)
TIFFWarningExt(tif->tif_clientdata, module,
"Unknown field with tag %d (0x%x) encountered",
dp->tdir_tag,dp->tdir_tag);
- /* the following knowingly leaks the
- anonymous field structure */
+ /* the following knowingly leaks the
+ anonymous field structure */
if (!_TIFFMergeFields(tif,
_TIFFCreateAnonField(tif,
dp->tdir_tag,
@@ -3675,18 +3710,18 @@ TIFFReadDirectory(TIFF* tif)
"Registering anonymous field with tag %d (0x%x) failed",
dp->tdir_tag,
dp->tdir_tag);
- dp->tdir_tag=IGNORE;
+ dp->tdir_ignore = TRUE;
} else {
TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
assert(fii != FAILED_FII);
}
}
}
- if (dp->tdir_tag!=IGNORE)
+ if (!dp->tdir_ignore)
{
fip=tif->tif_fields[fii];
if (fip->field_bit==FIELD_IGNORE)
- dp->tdir_tag=IGNORE;
+ dp->tdir_ignore = TRUE;
else
{
switch (dp->tdir_tag)
@@ -3708,12 +3743,12 @@ TIFFReadDirectory(TIFF* tif)
case TIFFTAG_EXTRASAMPLES:
if (!TIFFFetchNormalTag(tif,dp,0))
goto bad;
- dp->tdir_tag=IGNORE;
+ dp->tdir_ignore = TRUE;
+ break;
+ default:
+ if( !_TIFFCheckFieldIsValidForCodec(tif, dp->tdir_tag) )
+ dp->tdir_ignore = TRUE;
break;
- default:
- if( !_TIFFCheckFieldIsValidForCodec(tif,
dp->tdir_tag) )
- dp->tdir_tag=IGNORE;
- break;
}
}
}
@@ -3729,8 +3764,8 @@ TIFFReadDirectory(TIFF* tif)
if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG)&&
(tif->tif_dir.td_planarconfig==PLANARCONFIG_SEPARATE))
{
- if (!_TIFFFillStriles(tif))
- goto bad;
+ if (!_TIFFFillStriles(tif))
+ goto bad;
dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_STRIPOFFSETS);
if ((dp!=0)&&(dp->tdir_count==1))
{
@@ -3802,190 +3837,200 @@ TIFFReadDirectory(TIFF* tif)
*/
for (di=0, dp=dir; di<dircount; di++, dp++)
{
- switch (dp->tdir_tag)
- {
- case IGNORE:
- break;
- case TIFFTAG_MINSAMPLEVALUE:
- case TIFFTAG_MAXSAMPLEVALUE:
- case TIFFTAG_BITSPERSAMPLE:
- case TIFFTAG_DATATYPE:
- case TIFFTAG_SAMPLEFORMAT:
- /*
- * The MinSampleValue, MaxSampleValue, BitsPerSample
- * DataType and SampleFormat tags are supposed to be
- * written as one value/sample, but some vendors
- * incorrectly write one value only -- so we accept
- * that as well (yuck). Other vendors write correct
- * value for NumberOfSamples, but incorrect one for
- * BitsPerSample and friends, and we will read this
- * too.
- */
- {
- uint16 value;
- enum TIFFReadDirEntryErr err;
- err=TIFFReadDirEntryShort(tif,dp,&value);
- if (err==TIFFReadDirEntryErrCount)
- err=TIFFReadDirEntryPersampleShort(tif,dp,&value);
- if (err!=TIFFReadDirEntryErrOk)
- {
- fip = TIFFFieldWithTag(tif,dp->tdir_tag);
- TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown
tagname",0);
- goto bad;
- }
- if (!TIFFSetField(tif,dp->tdir_tag,value))
- goto bad;
- if( dp->tdir_tag == TIFFTAG_BITSPERSAMPLE )
- bitspersample_read = TRUE;
- }
- break;
- case TIFFTAG_SMINSAMPLEVALUE:
- case TIFFTAG_SMAXSAMPLEVALUE:
- {
-
- double *data = NULL;
- enum TIFFReadDirEntryErr err;
- uint32 saved_flags;
- int m;
- if (dp->tdir_count != (uint64)tif->tif_dir.td_samplesperpixel)
- err = TIFFReadDirEntryErrCount;
- else
- err = TIFFReadDirEntryDoubleArray(tif, dp, &data);
- if (err!=TIFFReadDirEntryErrOk)
- {
- fip = TIFFFieldWithTag(tif,dp->tdir_tag);
- TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown
tagname",0);
- goto bad;
- }
- saved_flags = tif->tif_flags;
- tif->tif_flags |= TIFF_PERSAMPLE;
- m = TIFFSetField(tif,dp->tdir_tag,data);
- tif->tif_flags = saved_flags;
- _TIFFfree(data);
- if (!m)
- goto bad;
- }
- break;
- case TIFFTAG_STRIPOFFSETS:
- case TIFFTAG_TILEOFFSETS:
-#if defined(DEFER_STRILE_LOAD)
- _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
- break;
- case TIFFTAG_STRIPBYTECOUNTS:
- case TIFFTAG_TILEBYTECOUNTS:
-#if defined(DEFER_STRILE_LOAD)
- _TIFFmemcpy(
&(tif->tif_dir.td_stripbytecount_entry),
- dp, sizeof(TIFFDirEntry) );
-#else
- 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;
- case TIFFTAG_COLORMAP:
- case TIFFTAG_TRANSFERFUNCTION:
- {
- enum TIFFReadDirEntryErr err;
- uint32 countpersample;
- uint32 countrequired;
- uint32 incrementpersample;
- uint16* value=NULL;
- /* It would be dangerous to instantiate those tag values */
- /* since if td_bitspersample has not yet been read (due to */
- /* unordered tags), it could be read afterwards with a */
- /* values greater than the default one (1), which may cause */
- /* crashes in user code */
- if( !bitspersample_read )
- {
- fip = TIFFFieldWithTag(tif,dp->tdir_tag);
- TIFFWarningExt(tif->tif_clientdata,module,
- "Ignoring %s since BitsPerSample tag not
found",
- fip ? fip->field_name : "unknown
tagname");
- continue;
- }
- /* ColorMap or TransferFunction for high bit */
- /* depths do not make much sense and could be */
- /* used as a denial of service vector */
- if (tif->tif_dir.td_bitspersample > 24)
- {
- fip = TIFFFieldWithTag(tif,dp->tdir_tag);
- TIFFWarningExt(tif->tif_clientdata,module,
- "Ignoring %s because BitsPerSample=%d>24",
- fip ? fip->field_name : "unknown tagname",
- tif->tif_dir.td_bitspersample);
- continue;
- }
- countpersample=(1U<<tif->tif_dir.td_bitspersample);
- if
((dp->tdir_tag==TIFFTAG_TRANSFERFUNCTION)&&(dp->tdir_count==(uint64)countpersample))
+ if (!dp->tdir_ignore) {
+ switch (dp->tdir_tag)
+ {
+ case TIFFTAG_MINSAMPLEVALUE:
+ case TIFFTAG_MAXSAMPLEVALUE:
+ case TIFFTAG_BITSPERSAMPLE:
+ case TIFFTAG_DATATYPE:
+ case TIFFTAG_SAMPLEFORMAT:
+ /*
+ * The MinSampleValue, MaxSampleValue, BitsPerSample
+ * DataType and SampleFormat tags are supposed to be
+ * written as one value/sample, but some vendors
+ * incorrectly write one value only -- so we accept
+ * that as well (yuck). Other vendors write correct
+ * value for NumberOfSamples, but incorrect one for
+ * BitsPerSample and friends, and we will read this
+ * too.
+ */
{
- countrequired=countpersample;
- incrementpersample=0;
+ uint16 value;
+ enum TIFFReadDirEntryErr err;
+ err=TIFFReadDirEntryShort(tif,dp,&value);
+ if (err==TIFFReadDirEntryErrCount)
+ err=TIFFReadDirEntryPersampleShort(tif,dp,&value);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ fip = TIFFFieldWithTag(tif,dp->tdir_tag);
+ TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown
tagname",0);
+ goto bad;
+ }
+ if (!TIFFSetField(tif,dp->tdir_tag,value))
+ goto bad;
+ if( dp->tdir_tag == TIFFTAG_BITSPERSAMPLE )
+ bitspersample_read = TRUE;
}
- else
+ break;
+ case TIFFTAG_SMINSAMPLEVALUE:
+ case TIFFTAG_SMAXSAMPLEVALUE:
{
- countrequired=3*countpersample;
- incrementpersample=countpersample;
+
+ double *data = NULL;
+ enum TIFFReadDirEntryErr err;
+ uint32 saved_flags;
+ int m;
+ if (dp->tdir_count != (uint64)tif->tif_dir.td_samplesperpixel)
+ err = TIFFReadDirEntryErrCount;
+ else
+ err = TIFFReadDirEntryDoubleArray(tif, dp, &data);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ fip = TIFFFieldWithTag(tif,dp->tdir_tag);
+ TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown
tagname",0);
+ goto bad;
+ }
+ saved_flags = tif->tif_flags;
+ tif->tif_flags |= TIFF_PERSAMPLE;
+ m = TIFFSetField(tif,dp->tdir_tag,data);
+ tif->tif_flags = saved_flags;
+ _TIFFfree(data);
+ if (!m)
+ goto bad;
}
- if (dp->tdir_count!=(uint64)countrequired)
- err=TIFFReadDirEntryErrCount;
- else
- err=TIFFReadDirEntryShortArray(tif,dp,&value);
- if (err!=TIFFReadDirEntryErrOk)
- {
- fip = TIFFFieldWithTag(tif,dp->tdir_tag);
- TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown
tagname",1);
- }
- else
+ break;
+ case TIFFTAG_STRIPOFFSETS:
+ case TIFFTAG_TILEOFFSETS:
+ _TIFFmemcpy( &(tif->tif_dir.td_stripoffset_entry),
+ dp, sizeof(TIFFDirEntry) );
+ break;
+ case TIFFTAG_STRIPBYTECOUNTS:
+ case TIFFTAG_TILEBYTECOUNTS:
+ _TIFFmemcpy( &(tif->tif_dir.td_stripbytecount_entry),
+ dp, sizeof(TIFFDirEntry) );
+ break;
+ case TIFFTAG_COLORMAP:
+ case TIFFTAG_TRANSFERFUNCTION:
{
- TIFFSetField(tif,dp->tdir_tag,value,value+incrementpersample,value+2*incrementpersample);
- _TIFFfree(value);
+ enum TIFFReadDirEntryErr err;
+ uint32 countpersample;
+ uint32 countrequired;
+ uint32 incrementpersample;
+ uint16* value=NULL;
+ /* It would be dangerous to instantiate those tag values */
+ /* since if td_bitspersample has not yet been read (due to */
+ /* unordered tags), it could be read afterwards with a */
+ /* values greater than the default one (1), which may cause */
+ /* crashes in user code */
+ if( !bitspersample_read )
+ {
+ fip = TIFFFieldWithTag(tif,dp->tdir_tag);
+ TIFFWarningExt(tif->tif_clientdata,module,
+ "Ignoring %s since BitsPerSample tag not found",
+ fip ? fip->field_name : "unknown tagname");
+ continue;
+ }
+ /* ColorMap or TransferFunction for high bit */
+ /* depths do not make much sense and could be */
+ /* used as a denial of service vector */
+ if (tif->tif_dir.td_bitspersample > 24)
+ {
+ fip = TIFFFieldWithTag(tif,dp->tdir_tag);
+ TIFFWarningExt(tif->tif_clientdata,module,
+ "Ignoring %s because BitsPerSample=%d>24",
+ fip ? fip->field_name : "unknown tagname",
+ tif->tif_dir.td_bitspersample);
+ continue;
+ }
+ countpersample=(1U<<tif->tif_dir.td_bitspersample);
+ if
((dp->tdir_tag==TIFFTAG_TRANSFERFUNCTION)&&(dp->tdir_count==(uint64)countpersample))
+ {
+ countrequired=countpersample;
+ incrementpersample=0;
+ }
+ else
+ {
+ countrequired=3*countpersample;
+ incrementpersample=countpersample;
+ }
+ if (dp->tdir_count!=(uint64)countrequired)
+ err=TIFFReadDirEntryErrCount;
+ else
+ err=TIFFReadDirEntryShortArray(tif,dp,&value);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ fip = TIFFFieldWithTag(tif,dp->tdir_tag);
+ TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown
tagname",1);
+ }
+ else
+ {
+ TIFFSetField(tif,dp->tdir_tag,value,value+incrementpersample,value+2*incrementpersample);
+ _TIFFfree(value);
+ }
}
- }
- break;
+ break;
/* BEGIN REV 4.0 COMPATIBILITY */
- case TIFFTAG_OSUBFILETYPE:
- {
- uint16 valueo;
- uint32 value;
- if (TIFFReadDirEntryShort(tif,dp,&valueo)==TIFFReadDirEntryErrOk)
+ case TIFFTAG_OSUBFILETYPE:
{
- switch (valueo)
+ uint16 valueo;
+ uint32 value;
+ if (TIFFReadDirEntryShort(tif,dp,&valueo)==TIFFReadDirEntryErrOk)
{
- case OFILETYPE_REDUCEDIMAGE: value=FILETYPE_REDUCEDIMAGE; break;
- case OFILETYPE_PAGE: value=FILETYPE_PAGE; break;
- default: value=0; break;
+ switch (valueo)
+ {
+ case OFILETYPE_REDUCEDIMAGE: value=FILETYPE_REDUCEDIMAGE; break;
+ case OFILETYPE_PAGE: value=FILETYPE_PAGE; break;
+ default: value=0; break;
+ }
+ if (value!=0)
+ TIFFSetField(tif,TIFFTAG_SUBFILETYPE,value);
}
- if (value!=0)
- TIFFSetField(tif,TIFFTAG_SUBFILETYPE,value);
}
- }
- break;
+ break;
/* END REV 4.0 COMPATIBILITY */
- default:
- (void) TIFFFetchNormalTag(tif, dp, TRUE);
- break;
- }
- }
+ default:
+ (void) TIFFFetchNormalTag(tif, dp, TRUE);
+ break;
+ }
+ } /* -- if (!dp->tdir_ignore) */
+ } /* -- for-loop -- */
+
+ if( tif->tif_mode == O_RDWR &&
+ tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 )
+ {
+ /* Directory typically created with TIFFDeferStrileArrayWriting() */
+ TIFFSetupStrips(tif);
+ }
+ else if( !(tif->tif_flags&TIFF_DEFERSTRILELOAD) )
+ {
+ if( tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 )
+ {
+ if
(!TIFFFetchStripThing(tif,&(tif->tif_dir.td_stripoffset_entry),
+ tif->tif_dir.td_nstrips,
+ &tif->tif_dir.td_stripoffset_p))
+ {
+ goto bad;
+ }
+ }
+ if( tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 )
+ {
+ if
(!TIFFFetchStripThing(tif,&(tif->tif_dir.td_stripbytecount_entry),
+ tif->tif_dir.td_nstrips,
+ &tif->tif_dir.td_stripbytecount_p))
+ {
+ goto bad;
+ }
+ }
+ }
+
/*
* OJPEG hack:
* - If a) compression is OJPEG, and b) photometric tag is missing,
@@ -4128,33 +4173,10 @@ TIFFReadDirectory(TIFF* tif)
"\"StripByteCounts\" field, calculating from imagelength");
if (EstimateStripByteCounts(tif, dir, dircount) < 0)
goto bad;
- /*
- * Assume we have wrong StripByteCount value (in case
- * of single strip) in following cases:
- * - it is equal to zero along with StripOffset;
- * - it is larger than file itself (in case of uncompressed
- * image);
- * - it is smaller than the size of the bytes per row
- * multiplied on the number of rows. The last case should
- * not be checked in the case of writing new image,
- * because we may do not know the exact strip size
- * until the whole image will be written and directory
- * dumped out.
- */
- #define BYTECOUNTLOOKSBAD \
- ( (tif->tif_dir.td_stripbytecount[0] == 0 &&
tif->tif_dir.td_stripoffset[0] != 0) || \
- (tif->tif_dir.td_compression == COMPRESSION_NONE && \
- (tif->tif_dir.td_stripoffset[0] <= TIFFGetFileSize(tif) && \
- tif->tif_dir.td_stripbytecount[0] > TIFFGetFileSize(tif) -
tif->tif_dir.td_stripoffset[0])) || \
- (tif->tif_mode == O_RDONLY && \
- tif->tif_dir.td_compression == COMPRESSION_NONE && \
- tif->tif_dir.td_stripbytecount[0] < TIFFScanlineSize64(tif) *
tif->tif_dir.td_imagelength) )
} else if (tif->tif_dir.td_nstrips == 1
&& !(tif->tif_flags&TIFF_ISTILED)
- && _TIFFFillStriles(tif)
- && tif->tif_dir.td_stripoffset[0] != 0
- && BYTECOUNTLOOKSBAD) {
+ && ByteCountLooksBad(tif)) {
/*
* XXX: Plexus (and others) sometimes give a value of
* zero for a tag when they don't know what the
@@ -4166,13 +4188,13 @@ TIFFReadDirectory(TIFF* tif)
if(EstimateStripByteCounts(tif, dir, dircount) < 0)
goto bad;
-#if !defined(DEFER_STRILE_LOAD)
- } else if (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG
+ } else if (!(tif->tif_flags&TIFF_DEFERSTRILELOAD)
+ && tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG
&& tif->tif_dir.td_nstrips > 2
&& tif->tif_dir.td_compression == COMPRESSION_NONE
- && tif->tif_dir.td_stripbytecount[0] !=
tif->tif_dir.td_stripbytecount[1]
- && tif->tif_dir.td_stripbytecount[0] != 0
- && tif->tif_dir.td_stripbytecount[1] != 0 ) {
+ && TIFFGetStrileByteCount(tif, 0) != TIFFGetStrileByteCount(tif, 1)
+ && TIFFGetStrileByteCount(tif, 0) != 0
+ && TIFFGetStrileByteCount(tif, 1) != 0 ) {
/*
* XXX: Some vendors fill StripByteCount array with
* absolutely wrong values (it can be equal to
@@ -4187,7 +4209,6 @@ TIFFReadDirectory(TIFF* tif)
"Wrong \"StripByteCounts\" field, ignoring and calculating from
imagelength");
if (EstimateStripByteCounts(tif, dir, dircount) < 0)
goto bad;
-#endif /* !defined(DEFER_STRILE_LOAD) */
}
}
if (dir)
@@ -4202,26 +4223,27 @@ TIFFReadDirectory(TIFF* tif)
else
tif->tif_dir.td_maxsamplevalue =
(uint16)((1L<<tif->tif_dir.td_bitspersample)-1);
}
+
+#ifdef STRIPBYTECOUNTSORTED_UNUSED
/*
* XXX: We can optimize checking for the strip bounds using the sorted
* bytecounts array. See also comments for TIFFAppendToStrip()
* function in tif_write.c.
*/
-#if !defined(DEFER_STRILE_LOAD)
- if (tif->tif_dir.td_nstrips > 1) {
+ if (!(tif->tif_flags&TIFF_DEFERSTRILELOAD) && tif->tif_dir.td_nstrips
> 1) {
uint32 strip;
tif->tif_dir.td_stripbytecountsorted = 1;
for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) {
- if (tif->tif_dir.td_stripoffset[strip - 1] >
- tif->tif_dir.td_stripoffset[strip]) {
+ if (TIFFGetStrileOffset(tif, strip - 1) >
+ TIFFGetStrileOffset(tif, strip)) {
tif->tif_dir.td_stripbytecountsorted = 0;
break;
}
}
}
-#endif /* !defined(DEFER_STRILE_LOAD) */
-
+#endif
+
/*
* An opportunity for compression mode dependent tag fixup
*/
@@ -4240,11 +4262,20 @@ TIFFReadDirectory(TIFF* tif)
(tif->tif_dir.td_nstrips==1)&&
(tif->tif_dir.td_compression==COMPRESSION_NONE)&&
((tif->tif_flags&(TIFF_STRIPCHOP|TIFF_ISTILED))==TIFF_STRIPCHOP))
- {
- if ( !_TIFFFillStriles(tif) || !tif->tif_dir.td_stripbytecount )
- return 0;
- ChopUpSingleUncompressedStrip(tif);
- }
+ {
+ ChopUpSingleUncompressedStrip(tif);
+ }
+
+ /* There are also uncompressed striped files with strips larger than */
+ /* 2 GB, which make them unfriendly with a lot of code. If possible, */
+ /* try to expose smaller "virtual" strips. */
+ if( tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG &&
+ tif->tif_dir.td_compression == COMPRESSION_NONE &&
+ (tif->tif_flags&(TIFF_STRIPCHOP|TIFF_ISTILED)) == TIFF_STRIPCHOP
&&
+ TIFFStripSize64(tif) > 0x7FFFFFFFUL )
+ {
+ TryChopUpUncompressedBigTiff(tif);
+ }
/*
* Clear the dirty directory flag.
@@ -4396,17 +4427,17 @@ TIFFReadCustomDirectory(TIFF* tif, toff_t diroff,
TIFFWarningExt(tif->tif_clientdata, module,
"Registering anonymous field with tag %d (0x%x) failed",
dp->tdir_tag, dp->tdir_tag);
- dp->tdir_tag=IGNORE;
+ dp->tdir_ignore = TRUE;
} else {
TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
assert( fii != FAILED_FII );
}
}
- if (dp->tdir_tag!=IGNORE)
+ if (!dp->tdir_ignore)
{
fip=tif->tif_fields[fii];
if (fip->field_bit==FIELD_IGNORE)
- dp->tdir_tag=IGNORE;
+ dp->tdir_ignore = TRUE;
else
{
/* check data type */
@@ -4426,7 +4457,7 @@ TIFFReadCustomDirectory(TIFF* tif, toff_t diroff,
TIFFWarningExt(tif->tif_clientdata, module,
"Wrong data type %d for \"%s\"; tag ignored",
dp->tdir_type,fip->field_name);
- dp->tdir_tag=IGNORE;
+ dp->tdir_ignore = TRUE;
}
else
{
@@ -4440,21 +4471,21 @@ TIFFReadCustomDirectory(TIFF* tif, toff_t diroff,
else
expected=(uint32)fip->field_readcount;
if (!CheckDirCount(tif,dp,expected))
- dp->tdir_tag=IGNORE;
+ dp->tdir_ignore = TRUE;
}
}
}
- switch (dp->tdir_tag)
- {
- case IGNORE:
- break;
- case EXIFTAG_SUBJECTDISTANCE:
- (void) TIFFFetchSubjectDistance(tif,dp);
- break;
- default:
- (void) TIFFFetchNormalTag(tif, dp, TRUE);
- break;
- }
+ if (!dp->tdir_ignore) {
+ switch (dp->tdir_tag)
+ {
+ case EXIFTAG_SUBJECTDISTANCE:
+ (void)TIFFFetchSubjectDistance(tif, dp);
+ break;
+ default:
+ (void)TIFFFetchNormalTag(tif, dp, TRUE);
+ break;
+ }
+ } /*-- if (!dp->tdir_ignore) */
}
}
if (dir)
@@ -4487,12 +4518,12 @@ EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16
dircount)
if( !_TIFFFillStrilesInternal( tif, 0 ) )
return -1;
- if (td->td_stripbytecount)
- _TIFFfree(td->td_stripbytecount);
- td->td_stripbytecount = (uint64*)
+ if (td->td_stripbytecount_p)
+ _TIFFfree(td->td_stripbytecount_p);
+ td->td_stripbytecount_p = (uint64*)
_TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64),
"for \"StripByteCounts\" array");
- if( td->td_stripbytecount == NULL )
+ if( td->td_stripbytecount_p == NULL )
return -1;
if (td->td_compression != COMPRESSION_NONE) {
@@ -4516,6 +4547,8 @@ EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16
dircount)
dp->tdir_type);
return -1;
}
+ if( dp->tdir_count > TIFF_UINT64_MAX / typewidth )
+ return -1;
datasize=(uint64)typewidth*dp->tdir_count;
if (!(tif->tif_flags&TIFF_BIGTIFF))
{
@@ -4527,6 +4560,8 @@ EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16
dircount)
if (datasize<=8)
datasize=0;
}
+ if( space > TIFF_UINT64_MAX - datasize )
+ return -1;
space+=datasize;
}
if( filesize < space )
@@ -4537,7 +4572,7 @@ EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16
dircount)
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
space /= td->td_samplesperpixel;
for (strip = 0; strip < td->td_nstrips; strip++)
- td->td_stripbytecount[strip] = space;
+ td->td_stripbytecount_p[strip] = space;
/*
* This gross hack handles the case were the offset to
* the last strip is past the place where we think the strip
@@ -4546,18 +4581,30 @@ EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16
dircount)
* of data in the strip and trim this number back accordingly.
*/
strip--;
- if (td->td_stripoffset[strip]+td->td_stripbytecount[strip] > filesize)
- td->td_stripbytecount[strip] = filesize - td->td_stripoffset[strip];
+ if (td->td_stripoffset_p[strip] > TIFF_UINT64_MAX -
td->td_stripbytecount_p[strip])
+ return -1;
+ if (td->td_stripoffset_p[strip]+td->td_stripbytecount_p[strip] > filesize) {
+ if( td->td_stripoffset_p[strip] >= filesize ) {
+ /* Not sure what we should in that case... */
+ td->td_stripbytecount_p[strip] = 0;
+ } else {
+ td->td_stripbytecount_p[strip] = filesize -
td->td_stripoffset_p[strip];
+ }
+ }
} else if (isTiled(tif)) {
uint64 bytespertile = TIFFTileSize64(tif);
for (strip = 0; strip < td->td_nstrips; strip++)
- td->td_stripbytecount[strip] = bytespertile;
+ td->td_stripbytecount_p[strip] = bytespertile;
} else {
uint64 rowbytes = TIFFScanlineSize64(tif);
uint32 rowsperstrip = td->td_imagelength/td->td_stripsperimage;
for (strip = 0; strip < td->td_nstrips; strip++)
- td->td_stripbytecount[strip] = rowbytes * rowsperstrip;
+ {
+ if( rowbytes > 0 && rowsperstrip > TIFF_UINT64_MAX /
rowbytes )
+ return -1;
+ td->td_stripbytecount_p[strip] = rowbytes * rowsperstrip;
+ }
}
TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
@@ -4751,12 +4798,13 @@ TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntry** pdir,
}
} else {
tmsize_t m;
- tmsize_t off = (tmsize_t) tif->tif_diroff;
- if ((uint64)off!=tif->tif_diroff)
+ tmsize_t off;
+ if (tif->tif_diroff > (uint64)TIFF_INT64_MAX)
{
TIFFErrorExt(tif->tif_clientdata,module,"Can not read TIFF directory
count");
return(0);
}
+ off = (tmsize_t) tif->tif_diroff;
/*
* Check for integer overflow when validating the dir_off,
@@ -4874,6 +4922,7 @@ TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntry** pdir,
mb=dir;
for (n=0; n<dircount16; n++)
{
+ mb->tdir_ignore = FALSE;
if (tif->tif_flags&TIFF_SWAB)
TIFFSwabShort((uint16*)ma);
mb->tdir_tag=*(uint16*)ma;
@@ -4888,6 +4937,7 @@ TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntry** pdir,
TIFFSwabLong((uint32*)ma);
mb->tdir_count=(uint64)(*(uint32*)ma);
ma+=sizeof(uint32);
+ mb->tdir_offset.toff_long8=0;
*(uint32*)(&mb->tdir_offset)=*(uint32*)ma;
ma+=sizeof(uint32);
}
@@ -5681,7 +5731,7 @@ TIFFFetchSubjectDistance(TIFF* tif, TIFFDirEntry* dir)
TIFFSwabArrayOfLong(m.i,2);
if (m.i[0]==0)
n=0.0;
- else if (m.i[0]==0xFFFFFFFF)
+ else if (m.i[0]==0xFFFFFFFF || m.i[1]==0)
/*
* XXX: Numerator 0xFFFFFFFF means that we have infinite
* distance. Indicate that with a negative floating point
@@ -5699,6 +5749,75 @@ TIFFFetchSubjectDistance(TIFF* tif, TIFFDirEntry* dir)
}
}
+static void allocChoppedUpStripArrays(TIFF* tif, uint32 nstrips,
+ uint64 stripbytes, uint32 rowsperstrip)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ uint64 bytecount;
+ uint64 offset;
+ uint64 last_offset;
+ uint64 last_bytecount;
+ uint32 i;
+ uint64 *newcounts;
+ uint64 *newoffsets;
+
+ offset = TIFFGetStrileOffset(tif, 0);
+ last_offset = TIFFGetStrileOffset(tif, td->td_nstrips-1);
+ last_bytecount = TIFFGetStrileByteCount(tif, td->td_nstrips-1);
+ if( last_offset > TIFF_UINT64_MAX - last_bytecount ||
+ last_offset + last_bytecount < offset )
+ {
+ return;
+ }
+ bytecount = last_offset + last_bytecount - offset;
+
+ newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
+ "for chopped \"StripByteCounts\"
array");
+ newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
+ "for chopped \"StripOffsets\" array");
+ if (newcounts == NULL || newoffsets == NULL) {
+ /*
+ * Unable to allocate new strip information, give up and use
+ * the original one strip information.
+ */
+ if (newcounts != NULL)
+ _TIFFfree(newcounts);
+ if (newoffsets != NULL)
+ _TIFFfree(newoffsets);
+ return;
+ }
+
+ /*
+ * Fill the strip information arrays with new bytecounts and offsets
+ * that reflect the broken-up format.
+ */
+ for (i = 0; i < nstrips; i++)
+ {
+ if (stripbytes > bytecount)
+ stripbytes = bytecount;
+ newcounts[i] = stripbytes;
+ newoffsets[i] = stripbytes ? offset : 0;
+ offset += stripbytes;
+ bytecount -= stripbytes;
+ }
+
+ /*
+ * Replace old single strip info with multi-strip info.
+ */
+ td->td_stripsperimage = td->td_nstrips = nstrips;
+ TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
+
+ _TIFFfree(td->td_stripbytecount_p);
+ _TIFFfree(td->td_stripoffset_p);
+ td->td_stripbytecount_p = newcounts;
+ td->td_stripoffset_p = newoffsets;
+#ifdef STRIPBYTECOUNTSORTED_UNUSED
+ td->td_stripbytecountsorted = 1;
+#endif
+ tif->tif_flags |= TIFF_CHOPPEDUPARRAYS;
+}
+
+
/*
* Replace a single strip (tile) of uncompressed data by multiple strips
* (tiles), each approximately STRIP_SIZE_DEFAULT bytes. This is useful for
@@ -5714,19 +5833,16 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
uint32 rowblock;
uint64 rowblockbytes;
uint64 stripbytes;
- uint32 strip;
uint32 nstrips;
uint32 rowsperstrip;
- uint64* newcounts;
- uint64* newoffsets;
- bytecount = td->td_stripbytecount[0];
+ bytecount = TIFFGetStrileByteCount(tif, 0);
/* On a newly created file, just re-opened to be filled, we */
/* don't want strip chop to trigger as it is going to cause issues */
/* later ( StripOffsets and StripByteCounts improperly filled) . */
if( bytecount == 0 && tif->tif_mode != O_RDONLY )
return;
- offset = td->td_stripoffset[0];
+ offset = TIFFGetStrileByteCount(tif, 0);
assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
if ((td->td_photometric == PHOTOMETRIC_YCBCR)&&
(!isUpSampled(tif)))
@@ -5769,98 +5885,503 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
return;
}
- newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
- "for chopped \"StripByteCounts\" array");
- newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
- "for chopped \"StripOffsets\" array");
- if (newcounts == NULL || newoffsets == NULL) {
- /*
- * Unable to allocate new strip information, give up and use
- * the original one strip information.
- */
- if (newcounts != NULL)
- _TIFFfree(newcounts);
- if (newoffsets != NULL)
- _TIFFfree(newoffsets);
- return;
- }
- /*
- * Fill the strip information arrays with new bytecounts and offsets
- * that reflect the broken-up format.
- */
- for (strip = 0; strip < nstrips; strip++) {
- if (stripbytes > bytecount)
- stripbytes = bytecount;
- newcounts[strip] = stripbytes;
- newoffsets[strip] = stripbytes ? offset : 0;
- offset += stripbytes;
- bytecount -= stripbytes;
- }
- /*
- * Replace old single strip info with multi-strip info.
- */
- td->td_stripsperimage = td->td_nstrips = nstrips;
- TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
-
- _TIFFfree(td->td_stripbytecount);
- _TIFFfree(td->td_stripoffset);
- td->td_stripbytecount = newcounts;
- td->td_stripoffset = newoffsets;
- td->td_stripbytecountsorted = 1;
+ allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip);
}
-int _TIFFFillStriles( TIFF *tif )
+
+/*
+ * Replace a file with contiguous strips > 2 GB of uncompressed data by
+ * multiple smaller strips. This is useful for
+ * dealing with large images or for dealing with machines with a limited
+ * amount memory.
+ */
+static void TryChopUpUncompressedBigTiff( TIFF* tif )
{
- return _TIFFFillStrilesInternal( tif, 1 );
+ TIFFDirectory *td = &tif->tif_dir;
+ uint32 rowblock;
+ uint64 rowblockbytes;
+ uint32 i;
+ uint64 stripsize;
+ uint32 rowblocksperstrip;
+ uint32 rowsperstrip;
+ uint64 stripbytes;
+ uint32 nstrips;
+
+ stripsize = TIFFStripSize64(tif);
+
+ assert( tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG );
+ assert( tif->tif_dir.td_compression == COMPRESSION_NONE );
+ assert( (tif->tif_flags&(TIFF_STRIPCHOP|TIFF_ISTILED)) == TIFF_STRIPCHOP );
+ assert( stripsize > 0x7FFFFFFFUL );
+
+ /* On a newly created file, just re-opened to be filled, we */
+ /* don't want strip chop to trigger as it is going to cause issues */
+ /* later ( StripOffsets and StripByteCounts improperly filled) . */
+ if( TIFFGetStrileByteCount(tif, 0) == 0 && tif->tif_mode != O_RDONLY )
+ return;
+
+ if ((td->td_photometric == PHOTOMETRIC_YCBCR)&&
+ (!isUpSampled(tif)))
+ rowblock = td->td_ycbcrsubsampling[1];
+ else
+ rowblock = 1;
+ rowblockbytes = TIFFVStripSize64(tif, rowblock);
+ if( rowblockbytes == 0 || rowblockbytes > 0x7FFFFFFFUL )
+ {
+ /* In case of file with gigantic width */
+ return;
+ }
+
+ /* Check that the strips are contiguous and of the expected size */
+ for( i = 0; i < td->td_nstrips; i++ )
+ {
+ if( i == td->td_nstrips - 1 )
+ {
+ if( TIFFGetStrileByteCount(tif, i) < TIFFVStripSize64(
+ tif, td->td_imagelength - i * td->td_rowsperstrip ) )
+ {
+ return;
+ }
+ }
+ else
+ {
+ if( TIFFGetStrileByteCount(tif, i) != stripsize )
+ {
+ return;
+ }
+ if( i > 0 && TIFFGetStrileOffset(tif, i) !=
+ TIFFGetStrileOffset(tif, i-1) + TIFFGetStrileByteCount(tif, i-1) )
+ {
+ return;
+ }
+ }
+ }
+
+ /* Aim for 512 MB strips (that will still be manageable by 32 bit builds */
+ rowblocksperstrip = (uint32) (512 * 1024 * 1024 / rowblockbytes);
+ if( rowblocksperstrip == 0 )
+ rowblocksperstrip = 1;
+ rowsperstrip = rowblocksperstrip * rowblock;
+ stripbytes = rowblocksperstrip * rowblockbytes;
+ assert( stripbytes <= 0x7FFFFFFFUL );
+
+ nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip);
+ if( nstrips == 0 )
+ return;
+
+ /* If we are going to allocate a lot of memory, make sure that the */
+ /* file is as big as needed */
+ if( tif->tif_mode == O_RDONLY &&
+ nstrips > 1000000 )
+ {
+ uint64 last_offset = TIFFGetStrileOffset(tif, td->td_nstrips-1);
+ uint64 filesize = TIFFGetFileSize(tif);
+ uint64 last_bytecount = TIFFGetStrileByteCount(tif, td->td_nstrips-1);
+ if( last_offset > filesize ||
+ last_bytecount > filesize - last_offset )
+ {
+ return;
+ }
+ }
+
+ allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip);
}
-static int _TIFFFillStrilesInternal( TIFF *tif, int loadStripByteCount )
+
+TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
+static uint64 _TIFFUnsanitizedAddUInt64AndInt(uint64 a, int b)
{
-#if defined(DEFER_STRILE_LOAD)
- register TIFFDirectory *td = &tif->tif_dir;
- int return_value = 1;
+ return a + b;
+}
- if( td->td_stripoffset != NULL )
- return 1;
+/* Read the value of [Strip|Tile]Offset or [Strip|Tile]ByteCount around
+ * strip/tile of number strile. Also fetch the neighbouring values using a
+ * 4096 byte page size.
+ */
+static
+int _TIFFPartialReadStripArray( TIFF* tif, TIFFDirEntry* dirent,
+ int strile, uint64* panVals )
+{
+ static const char module[] = "_TIFFPartialReadStripArray";
+#define IO_CACHE_PAGE_SIZE 4096
+
+ size_t sizeofval;
+ const int bSwab = (tif->tif_flags & TIFF_SWAB) != 0;
+ int sizeofvalint;
+ uint64 nBaseOffset;
+ uint64 nOffset;
+ uint64 nOffsetStartPage;
+ uint64 nOffsetEndPage;
+ tmsize_t nToRead;
+ tmsize_t nRead;
+ uint64 nLastStripOffset;
+ int iStartBefore;
+ int i;
+ const uint32 arraySize = tif->tif_dir.td_stripoffsetbyteallocsize;
+ unsigned char buffer[2 * IO_CACHE_PAGE_SIZE];
+
+ assert( dirent->tdir_count > 4 );
+
+ if( dirent->tdir_type == TIFF_SHORT )
+ {
+ sizeofval = sizeof(uint16);
+ }
+ else if( dirent->tdir_type == TIFF_LONG )
+ {
+ sizeofval = sizeof(uint32);
+ }
+ else if( dirent->tdir_type == TIFF_LONG8 )
+ {
+ sizeofval = sizeof(uint64);
+ }
+ else
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Invalid type for [Strip|Tile][Offset/ByteCount] tag");
+ panVals[strile] = 0;
+ return 0;
+ }
+ sizeofvalint = (int)(sizeofval);
- if( td->td_stripoffset_entry.tdir_count == 0 )
+ if( tif->tif_flags&TIFF_BIGTIFF )
+ {
+ uint64 offset = dirent->tdir_offset.toff_long8;
+ if( bSwab )
+ TIFFSwabLong8(&offset);
+ nBaseOffset = offset;
+ }
+ else
+ {
+ uint32 offset = dirent->tdir_offset.toff_long;
+ if( bSwab )
+ TIFFSwabLong(&offset);
+ nBaseOffset = offset;
+ }
+ /* To avoid later unsigned integer overflows */
+ if( nBaseOffset > (uint64)TIFF_INT64_MAX )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Cannot read offset/size for strile %d", strile);
+ panVals[strile] = 0;
+ return 0;
+ }
+ nOffset = nBaseOffset + sizeofval * strile;
+ nOffsetStartPage =
+ (nOffset / IO_CACHE_PAGE_SIZE) * IO_CACHE_PAGE_SIZE;
+ nOffsetEndPage = nOffsetStartPage + IO_CACHE_PAGE_SIZE;
+
+ if( nOffset + sizeofval > nOffsetEndPage )
+ nOffsetEndPage += IO_CACHE_PAGE_SIZE;
+#undef IO_CACHE_PAGE_SIZE
+
+ nLastStripOffset = nBaseOffset + arraySize * sizeofval;
+ if( nLastStripOffset < nOffsetEndPage )
+ nOffsetEndPage = nLastStripOffset;
+ if( nOffsetStartPage >= nOffsetEndPage )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Cannot read offset/size for strile %d", strile);
+ panVals[strile] = 0;
+ return 0;
+ }
+ if (!SeekOK(tif,nOffsetStartPage))
+ {
+ panVals[strile] = 0;
+ return 0;
+ }
+
+ nToRead = (tmsize_t)(nOffsetEndPage - nOffsetStartPage);
+ nRead = TIFFReadFile(tif, buffer, nToRead);
+ if( nRead < nToRead )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Cannot read offset/size for strile around ~%d", strile);
+ return 0;
+ }
+ iStartBefore = -(int)((nOffset - nOffsetStartPage) / sizeofval);
+ if( strile + iStartBefore < 0 )
+ iStartBefore = -strile;
+ for( i = iStartBefore;
+ (uint32)(strile + i) < arraySize &&
+ _TIFFUnsanitizedAddUInt64AndInt(nOffset, (i + 1) * sizeofvalint) <=
nOffsetEndPage;
+ ++i )
+ {
+ if( sizeofval == sizeof(uint16) )
+ {
+ uint16 val;
+ memcpy(&val,
+ buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
+ sizeof(val));
+ if( bSwab )
+ TIFFSwabShort(&val);
+ panVals[strile + i] = val;
+ }
+ else if( sizeofval == sizeof(uint32) )
+ {
+ uint32 val;
+ memcpy(&val,
+ buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
+ sizeof(val));
+ if( bSwab )
+ TIFFSwabLong(&val);
+ panVals[strile + i] = val;
+ }
+ else
+ {
+ uint64 val;
+ memcpy(&val,
+ buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
+ sizeof(val));
+ if( bSwab )
+ TIFFSwabLong8(&val);
+ panVals[strile + i] = val;
+ }
+ }
+ return 1;
+}
+
+static int _TIFFFetchStrileValue(TIFF* tif,
+ uint32 strile,
+ TIFFDirEntry* dirent,
+ uint64** parray)
+{
+ static const char module[] = "_TIFFFetchStrileValue";
+ TIFFDirectory *td = &tif->tif_dir;
+ if( strile >= dirent->tdir_count )
+ {
+ return 0;
+ }
+ if( strile >= td->td_stripoffsetbyteallocsize )
+ {
+ uint32 nStripArrayAllocBefore = td->td_stripoffsetbyteallocsize;
+ uint32 nStripArrayAllocNew;
+ uint64 nArraySize64;
+ size_t nArraySize;
+ uint64* offsetArray;
+ uint64* bytecountArray;
+
+ if( strile > 1000000 )
+ {
+ uint64 filesize = TIFFGetFileSize(tif);
+ /* Avoid excessive memory allocation attempt */
+ /* For such a big blockid we need at least a TIFF_LONG per strile */
+ /* for the offset array. */
+ if( strile > filesize / sizeof(uint32) )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module, "File too
short");
return 0;
+ }
+ }
- if (!TIFFFetchStripThing(tif,&(td->td_stripoffset_entry),
- td->td_nstrips,&td->td_stripoffset))
+ if( td->td_stripoffsetbyteallocsize == 0 &&
+ td->td_nstrips < 1024 * 1024 )
{
- return_value = 0;
+ nStripArrayAllocNew = td->td_nstrips;
+ }
+ else
+ {
+#define TIFF_MAX(a,b) (((a)>(b)) ? (a) : (b))
+#define TIFF_MIN(a,b) (((a)<(b)) ? (a) : (b))
+ nStripArrayAllocNew = TIFF_MAX(strile + 1, 1024U * 512U );
+ if( nStripArrayAllocNew < 0xFFFFFFFFU / 2 )
+ nStripArrayAllocNew *= 2;
+ nStripArrayAllocNew = TIFF_MIN(nStripArrayAllocNew, td->td_nstrips);
+ }
+ assert( strile < nStripArrayAllocNew );
+ nArraySize64 = (uint64)sizeof(uint64) * nStripArrayAllocNew;
+ nArraySize = (size_t)(nArraySize64);
+#if SIZEOF_SIZE_T == 4
+ if( nArraySize != nArraySize64 )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Cannot allocate strip offset and bytecount arrays");
+ return 0;
}
+#endif
+ offsetArray = (uint64*)(
+ _TIFFrealloc( td->td_stripoffset_p, nArraySize ) );
+ bytecountArray = (uint64*)(
+ _TIFFrealloc( td->td_stripbytecount_p, nArraySize ) );
+ if( offsetArray )
+ td->td_stripoffset_p = offsetArray;
+ if( bytecountArray )
+ td->td_stripbytecount_p = bytecountArray;
+ if( offsetArray && bytecountArray )
+ {
+ td->td_stripoffsetbyteallocsize = nStripArrayAllocNew;
+ /* Initialize new entries to ~0 / -1 */
+ memset(td->td_stripoffset_p + nStripArrayAllocBefore,
+ 0xFF,
+ (td->td_stripoffsetbyteallocsize - nStripArrayAllocBefore) *
sizeof(uint64) );
+ memset(td->td_stripbytecount_p + nStripArrayAllocBefore,
+ 0xFF,
+ (td->td_stripoffsetbyteallocsize - nStripArrayAllocBefore) *
sizeof(uint64) );
+ }
+ else
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Cannot allocate strip offset and bytecount arrays");
+ _TIFFfree(td->td_stripoffset_p);
+ td->td_stripoffset_p = NULL;
+ _TIFFfree(td->td_stripbytecount_p);
+ td->td_stripbytecount_p = NULL;
+ td->td_stripoffsetbyteallocsize = 0;
+ }
+ }
+ if( *parray == NULL || strile >= td->td_stripoffsetbyteallocsize )
+ return 0;
- if (loadStripByteCount &&
- !TIFFFetchStripThing(tif,&(td->td_stripbytecount_entry),
- td->td_nstrips,&td->td_stripbytecount))
+ if( ~((*parray)[strile]) == 0 )
+ {
+ if( !_TIFFPartialReadStripArray( tif, dirent, strile, *parray ) )
{
- return_value = 0;
+ (*parray)[strile] = 0;
+ return 0;
}
+ }
- _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
- _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
+ return 1;
+}
- if (tif->tif_dir.td_nstrips > 1 && return_value == 1 ) {
- uint32 strip;
+static uint64 _TIFFGetStrileOffsetOrByteCountValue(TIFF *tif, uint32 strile,
+ TIFFDirEntry* dirent,
+ uint64** parray,
+ int *pbErr)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ if( pbErr )
+ *pbErr = 0;
+ if( (tif->tif_flags&TIFF_DEFERSTRILELOAD) &&
!(tif->tif_flags&TIFF_CHOPPEDUPARRAYS) )
+ {
+ if( !(tif->tif_flags&TIFF_LAZYSTRILELOAD) ||
+ /* If the values may fit in the toff_long/toff_long8 member */
+ /* then use _TIFFFillStriles to simplify _TIFFFetchStrileValue */
+ dirent->tdir_count <= 4 )
+ {
+ if( !_TIFFFillStriles(tif) )
+ {
+ if( pbErr )
+ *pbErr = 1;
+ /* Do not return, as we want this function to always */
+ /* return the same value if called several times with */
+ /* the same arguments */
+ }
+ }
+ else
+ {
+ if( !_TIFFFetchStrileValue(tif, strile, dirent, parray) )
+ {
+ if( pbErr )
+ *pbErr = 1;
+ return 0;
+ }
+ }
+ }
+ if( *parray == NULL || strile >= td->td_nstrips )
+ {
+ if( pbErr )
+ *pbErr = 1;
+ return 0;
+ }
+ return (*parray)[strile];
+}
- tif->tif_dir.td_stripbytecountsorted = 1;
- for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) {
- if (tif->tif_dir.td_stripoffset[strip - 1] >
- tif->tif_dir.td_stripoffset[strip]) {
- tif->tif_dir.td_stripbytecountsorted = 0;
- break;
- }
- }
- }
+/* Return the value of the TileOffsets/StripOffsets array for the specified tile/strile
*/
+uint64 TIFFGetStrileOffset(TIFF *tif, uint32 strile)
+{
+ return TIFFGetStrileOffsetWithErr(tif, strile, NULL);
+}
+
+/* Return the value of the TileOffsets/StripOffsets array for the specified tile/strile
*/
+uint64 TIFFGetStrileOffsetWithErr(TIFF *tif, uint32 strile, int *pbErr)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ return _TIFFGetStrileOffsetOrByteCountValue(tif, strile,
+ &(td->td_stripoffset_entry),
+ &(td->td_stripoffset_p), pbErr);
+}
+
+/* Return the value of the TileByteCounts/StripByteCounts array for the specified
tile/strile */
+uint64 TIFFGetStrileByteCount(TIFF *tif, uint32 strile)
+{
+ return TIFFGetStrileByteCountWithErr(tif, strile, NULL);
+}
+
+/* Return the value of the TileByteCounts/StripByteCounts array for the specified
tile/strile */
+uint64 TIFFGetStrileByteCountWithErr(TIFF *tif, uint32 strile, int *pbErr)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ return _TIFFGetStrileOffsetOrByteCountValue(tif, strile,
+ &(td->td_stripbytecount_entry),
+ &(td->td_stripbytecount_p), pbErr);
+}
- return return_value;
-#else /* !defined(DEFER_STRILE_LOAD) */
- (void) tif;
- (void) loadStripByteCount;
+
+int _TIFFFillStriles( TIFF *tif )
+{
+ return _TIFFFillStrilesInternal( tif, 1 );
+}
+
+static int _TIFFFillStrilesInternal( TIFF *tif, int loadStripByteCount )
+{
+ register TIFFDirectory *td = &tif->tif_dir;
+ int return_value = 1;
+
+ /* Do not do anything if TIFF_DEFERSTRILELOAD is not set */
+ if( !(tif->tif_flags&TIFF_DEFERSTRILELOAD) ||
(tif->tif_flags&TIFF_CHOPPEDUPARRAYS) != 0 )
return 1;
-#endif
+
+ if( tif->tif_flags&TIFF_LAZYSTRILELOAD )
+ {
+ /* In case of lazy loading, reload completely the arrays */
+ _TIFFfree(td->td_stripoffset_p);
+ _TIFFfree(td->td_stripbytecount_p);
+ td->td_stripoffset_p = NULL;
+ td->td_stripbytecount_p = NULL;
+ td->td_stripoffsetbyteallocsize = 0;
+ tif->tif_flags &= ~TIFF_LAZYSTRILELOAD;
+ }
+
+ /* If stripoffset array is already loaded, exit with success */
+ if( td->td_stripoffset_p != NULL )
+ return 1;
+
+ /* If tdir_count was cancelled, then we already got there, but in error */
+ if( td->td_stripoffset_entry.tdir_count == 0 )
+ return 0;
+
+ if (!TIFFFetchStripThing(tif,&(td->td_stripoffset_entry),
+ td->td_nstrips,&td->td_stripoffset_p))
+ {
+ return_value = 0;
+ }
+
+ if (loadStripByteCount &&
+ !TIFFFetchStripThing(tif,&(td->td_stripbytecount_entry),
+ td->td_nstrips,&td->td_stripbytecount_p))
+ {
+ return_value = 0;
+ }
+
+ _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
+ _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
+
+#ifdef STRIPBYTECOUNTSORTED_UNUSED
+ if (tif->tif_dir.td_nstrips > 1 && return_value == 1 ) {
+ uint32 strip;
+
+ tif->tif_dir.td_stripbytecountsorted = 1;
+ for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) {
+ if (tif->tif_dir.td_stripoffset_p[strip - 1] >
+ tif->tif_dir.td_stripoffset_p[strip]) {
+ tif->tif_dir.td_stripbytecountsorted = 0;
+ break;
+ }
+ }
+ }
+#endif
+
+ return return_value;
}
diff --git a/dll/3rdparty/libtiff/tif_dirwrite.c b/dll/3rdparty/libtiff/tif_dirwrite.c
index acc41c89662..f9a38f682df 100644
--- a/dll/3rdparty/libtiff/tif_dirwrite.c
+++ b/dll/3rdparty/libtiff/tif_dirwrite.c
@@ -182,6 +182,51 @@ TIFFWriteDirectory(TIFF* tif)
return TIFFWriteDirectorySec(tif,TRUE,TRUE,NULL);
}
+/*
+ * This is an advanced writing function that must be used in a particular
+ * sequence, and generally together with TIFFForceStrileArrayWriting(),
+ * to make its intended effect. Its aim is to modify the location
+ * where the [Strip/Tile][Offsets/ByteCounts] arrays are located in the file.
+ * More precisely, when TIFFWriteCheck() will be called, the tag entries for
+ * those arrays will be written with type = count = offset = 0 as a temporary
+ * value.
+ *
+ * Its effect is only valid for the current directory, and before
+ * TIFFWriteDirectory() is first called, and will be reset when
+ * changing directory.
+ *
+ * The typical sequence of calls is:
+ * TIFFOpen()
+ * [ TIFFCreateDirectory(tif) ]
+ * Set fields with calls to TIFFSetField(tif, ...)
+ * TIFFDeferStrileArrayWriting(tif)
+ * TIFFWriteCheck(tif, ...)
+ * TIFFWriteDirectory(tif)
+ * ... potentially create other directories and come back to the above directory
+ * TIFFForceStrileArrayWriting(tif): emit the arrays at the end of file
+ *
+ * Returns 1 in case of success, 0 otherwise.
+ */
+int TIFFDeferStrileArrayWriting(TIFF* tif)
+{
+ static const char module[] = "TIFFDeferStrileArrayWriting";
+ if (tif->tif_mode == O_RDONLY)
+ {
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "File opened in read-only mode");
+ return 0;
+ }
+ if( tif->tif_diroff != 0 )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Directory has already been written");
+ return 0;
+ }
+
+ tif->tif_dir.td_deferstrilearraywriting = TRUE;
+ return 1;
+}
+
/*
* Similar to TIFFWriteDirectory(), writes the directory out
* but leaves all data structures in memory so that it can be
@@ -193,7 +238,7 @@ TIFFCheckpointDirectory(TIFF* tif)
{
int rc;
/* Setup the strips arrays, if they haven't already been. */
- if (tif->tif_dir.td_stripoffset == NULL)
+ if (tif->tif_dir.td_stripoffset_p == NULL)
(void) TIFFSetupStrips(tif);
rc = TIFFWriteDirectorySec(tif,TRUE,FALSE,NULL);
(void) TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END));
@@ -528,12 +573,12 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64*
pdiroff)
{
if (!isTiled(tif))
{
- if
(!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount))
+ if
(!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount_p))
goto bad;
}
else
{
- if
(!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount))
+ if
(!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount_p))
goto bad;
}
}
@@ -541,7 +586,7 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64*
pdiroff)
{
if (!isTiled(tif))
{
- /* td_stripoffset might be NULL in an odd OJPEG case. See
+ /* td_stripoffset_p might be NULL in an odd OJPEG case. See
* tif_dirread.c around line 3634.
* XXX: OJPEG hack.
* If a) compression is OJPEG, b) it's not a tiled TIFF,
@@ -552,13 +597,13 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64*
pdiroff)
* We can get here when using tiffset on such a file.
* See
http://bugzilla.maptools.org/show_bug.cgi?id=2500
*/
- if (tif->tif_dir.td_stripoffset != NULL &&
-
!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset))
+ if (tif->tif_dir.td_stripoffset_p != NULL &&
+
!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset_p))
goto bad;
}
else
{
- if
(!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset))
+ if
(!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset_p))
goto bad;
}
}
@@ -946,15 +991,6 @@ 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 )
@@ -1029,7 +1065,7 @@ TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir,
TIFFDirEntry* di
if (tif->tif_dir.td_bitspersample<=32)
{
for (i = 0; i < count; ++i)
- ((float*)conv)[i] = TIFFClampDoubleToFloat(value[i]);
+ ((float*)conv)[i] = _TIFFClampDoubleToFloat(value[i]);
ok = TIFFWriteDirectoryTagFloatArray(tif,ndir,dir,tag,count,(float*)conv);
}
else
@@ -1661,22 +1697,52 @@ TIFFWriteDirectoryTagShortLong(TIFF* tif, uint32* ndir,
TIFFDirEntry* dir, uint1
return(TIFFWriteDirectoryTagCheckedLong(tif,ndir,dir,tag,value));
}
+static int _WriteAsType(TIFF* tif, uint64 strile_size, uint64 uncompressed_threshold)
+{
+ const uint16 compression = tif->tif_dir.td_compression;
+ if ( compression == COMPRESSION_NONE )
+ {
+ return strile_size > uncompressed_threshold;
+ }
+ else if ( compression == COMPRESSION_JPEG ||
+ compression == COMPRESSION_LZW ||
+ compression == COMPRESSION_ADOBE_DEFLATE ||
+ compression == COMPRESSION_LZMA ||
+ compression == COMPRESSION_LERC ||
+ compression == COMPRESSION_ZSTD ||
+ compression == COMPRESSION_WEBP )
+ {
+ /* For a few select compression types, we assume that in the worst */
+ /* case the compressed size will be 10 times the uncompressed size */
+ /* This is overly pessismistic ! */
+ return strile_size >= uncompressed_threshold / 10;
+ }
+ return 1;
+}
+
+static int WriteAsLong8(TIFF* tif, uint64 strile_size)
+{
+ return _WriteAsType(tif, strile_size, 0xFFFFFFFFU);
+}
+
+static int WriteAsLong4(TIFF* tif, uint64 strile_size)
+{
+ return _WriteAsType(tif, strile_size, 0xFFFFU);
+}
+
/************************************************************************/
/* TIFFWriteDirectoryTagLongLong8Array() */
/* */
-/* Write out LONG8 array as LONG8 for BigTIFF or LONG for */
-/* Classic TIFF with some checking. */
+/* Write out LONG8 array and write a SHORT/LONG/LONG8 depending */
+/* on strile size and Classic/BigTIFF mode. */
/************************************************************************/
static int
TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16
tag, uint32 count, uint64* value)
{
static const char module[] = "TIFFWriteDirectoryTagLongLong8Array";
- uint64* ma;
- uint32 mb;
- uint32* p;
- uint32* q;
int o;
+ int write_aslong4;
/* is this just a counting pass? */
if (dir==NULL)
@@ -1685,37 +1751,105 @@ TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32* ndir,
TIFFDirEntry* dir,
return(1);
}
- /* We always write LONG8 for BigTIFF, no checking needed. */
- if( tif->tif_flags&TIFF_BIGTIFF )
- return TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,
- tag,count,value);
-
- /*
- ** For classic tiff we want to verify everything is in range for LONG
- ** and convert to long format.
- */
+ if( tif->tif_dir.td_deferstrilearraywriting )
+ {
+ return TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_NOTYPE, 0, 0, NULL);
+ }
- p = _TIFFmalloc(count*sizeof(uint32));
- if (p==NULL)
+ if( tif->tif_flags&TIFF_BIGTIFF )
{
- TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
- return(0);
+ int write_aslong8 = 1;
+ /* In the case of ByteCounts array, we may be able to write them on */
+ /* LONG if the strip/tilesize is not too big. */
+ /* Also do that for count > 1 in the case someone would want to create */
+ /* a single-strip file with a growing height, in which case using */
+ /* LONG8 will be safer. */
+ if( count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS )
+ {
+ write_aslong8 = WriteAsLong8(tif, TIFFStripSize64(tif));
+ }
+ else if( count > 1 && tag == TIFFTAG_TILEBYTECOUNTS )
+ {
+ write_aslong8 = WriteAsLong8(tif, TIFFTileSize64(tif));
+ }
+ if( write_aslong8 )
+ {
+ return TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,
+ tag,count,value);
+ }
}
- for (q=p, ma=value, mb=0; mb<count; ma++, mb++, q++)
+ write_aslong4 = 1;
+ if( count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS )
{
- if (*ma>0xFFFFFFFF)
+ write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif));
+ }
+ else if( count > 1 && tag == TIFFTAG_TILEBYTECOUNTS )
+ {
+ write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif));
+ }
+ if( write_aslong4 )
+ {
+ /*
+ ** For classic tiff we want to verify everything is in range for LONG
+ ** and convert to long format.
+ */
+
+ uint32* p = _TIFFmalloc(count*sizeof(uint32));
+ uint32* q;
+ uint64* ma;
+ uint32 mb;
+
+ if (p==NULL)
{
- TIFFErrorExt(tif->tif_clientdata,module,
- "Attempt to write value larger than 0xFFFFFFFF in Classic
TIFF file.");
- _TIFFfree(p);
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
return(0);
}
- *q= (uint32)(*ma);
+
+ for (q=p, ma=value, mb=0; mb<count; ma++, mb++, q++)
+ {
+ if (*ma>0xFFFFFFFF)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,
+ "Attempt to write value larger than 0xFFFFFFFF in LONG
array.");
+ _TIFFfree(p);
+ return(0);
+ }
+ *q= (uint32)(*ma);
+ }
+
+ o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,p);
+ _TIFFfree(p);
}
+ else
+ {
+ uint16* p = _TIFFmalloc(count*sizeof(uint16));
+ uint16* q;
+ uint64* ma;
+ uint32 mb;
- o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,p);
- _TIFFfree(p);
+ if (p==NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+
+ for (q=p, ma=value, mb=0; mb<count; ma++, mb++, q++)
+ {
+ if (*ma>0xFFFF)
+ {
+ /* Should not happen normally given the check we did before */
+ TIFFErrorExt(tif->tif_clientdata,module,
+ "Attempt to write value larger than 0xFFFF in SHORT
array.");
+ _TIFFfree(p);
+ return(0);
+ }
+ *q= (uint16)(*ma);
+ }
+
+ o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,count,p);
+ _TIFFfree(p);
+ }
return(o);
}
@@ -1893,12 +2027,14 @@ TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32* ndir,
TIFFDirEntry* dir
n=3;
if (n==3)
{
- if
(!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16)))
+ if (tif->tif_dir.td_transferfunction[2] == NULL ||
+
!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16)))
n=2;
}
if (n==2)
{
- if
(!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16)))
+ if (tif->tif_dir.td_transferfunction[1] == NULL ||
+
!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16)))
n=1;
}
if (n==0)
@@ -2428,7 +2564,12 @@ TIFFWriteDirectoryTagData(TIFF* tif, uint32* ndir, TIFFDirEntry*
dir, uint16 tag
dir[m].tdir_count=count;
dir[m].tdir_offset.toff_long8 = 0;
if (datalength<=((tif->tif_flags&TIFF_BIGTIFF)?0x8U:0x4U))
- _TIFFmemcpy(&dir[m].tdir_offset,data,datalength);
+ {
+ if( data && datalength )
+ {
+ _TIFFmemcpy(&dir[m].tdir_offset,data,datalength);
+ }
+ }
else
{
uint64 na,nb;
@@ -2820,13 +2961,60 @@ _TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType
in_datatype,
TIFFSwabLong8( &entry_offset );
}
+/* -------------------------------------------------------------------- */
+/* When a dummy tag was written due to TIFFDeferStrileArrayWriting() */
+/* -------------------------------------------------------------------- */
+ if( entry_offset == 0 && entry_count == 0 && entry_type == 0 )
+ {
+ if( tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS )
+ {
+ entry_type = (tif->tif_flags&TIFF_BIGTIFF) ? TIFF_LONG8 : TIFF_LONG;
+ }
+ else
+ {
+ int write_aslong8 = 1;
+ if( count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS )
+ {
+ write_aslong8 = WriteAsLong8(tif, TIFFStripSize64(tif));
+ }
+ else if( count > 1 && tag == TIFFTAG_TILEBYTECOUNTS )
+ {
+ write_aslong8 = WriteAsLong8(tif, TIFFTileSize64(tif));
+ }
+ if( write_aslong8 )
+ {
+ entry_type = TIFF_LONG8;
+ }
+ else
+ {
+ int write_aslong4 = 1;
+ if( count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS )
+ {
+ write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif));
+ }
+ else if( count > 1 && tag == TIFFTAG_TILEBYTECOUNTS )
+ {
+ write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif));
+ }
+ if( write_aslong4 )
+ {
+ entry_type = TIFF_LONG;
+ }
+ else
+ {
+ entry_type = TIFF_SHORT;
+ }
+ }
+ }
+ }
+
/* -------------------------------------------------------------------- */
/* What data type do we want to write this as? */
/* -------------------------------------------------------------------- */
if( TIFFDataWidth(in_datatype) == 8 && !(tif->tif_flags&TIFF_BIGTIFF)
)
{
if( in_datatype == TIFF_LONG8 )
- datatype = TIFF_LONG;
+ datatype = entry_type == TIFF_SHORT ? TIFF_SHORT : TIFF_LONG;
else if( in_datatype == TIFF_SLONG8 )
datatype = TIFF_SLONG;
else if( in_datatype == TIFF_IFD8 )
@@ -2834,8 +3022,21 @@ _TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype,
else
datatype = in_datatype;
}
- else
- datatype = in_datatype;
+ else
+ {
+ if( in_datatype == TIFF_LONG8 &&
+ (entry_type == TIFF_SHORT || entry_type == TIFF_LONG ||
+ entry_type == TIFF_LONG8 ) )
+ datatype = entry_type;
+ else if( in_datatype == TIFF_SLONG8 &&
+ (entry_type == TIFF_SLONG || entry_type == TIFF_SLONG8 ) )
+ datatype = entry_type;
+ else if( in_datatype == TIFF_IFD8 &&
+ (entry_type == TIFF_IFD || entry_type == TIFF_IFD8 ) )
+ datatype = entry_type;
+ else
+ datatype = in_datatype;
+ }
/* -------------------------------------------------------------------- */
/* Prepare buffer of actual data to write. This includes */
@@ -2884,6 +3085,29 @@ _TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype,
}
}
}
+ else if( datatype == TIFF_SHORT && in_datatype == TIFF_LONG8 )
+ {
+ tmsize_t i;
+
+ for( i = 0; i < count; i++ )
+ {
+ ((uint16 *) buf_to_write)[i] =
+ (uint16) ((uint64 *) data)[i];
+ if( (uint64) ((uint16 *) buf_to_write)[i] != ((uint64 *) data)[i] )
+ {
+ _TIFFfree( buf_to_write );
+ TIFFErrorExt( tif->tif_clientdata, module,
+ "Value exceeds 16bit range of output type." );
+ return 0;
+ }
+ }
+ }
+ else
+ {
+ TIFFErrorExt( tif->tif_clientdata, module,
+ "Unhandled type conversion." );
+ return 0;
+ }
if( TIFFDataWidth(datatype) > 1 && (tif->tif_flags&TIFF_SWAB) )
{
@@ -2915,6 +3139,23 @@ _TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype,
}
}
+ if( (tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS) &&
+ tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 )
+ {
+ tif->tif_dir.td_stripoffset_entry.tdir_type = datatype;
+ tif->tif_dir.td_stripoffset_entry.tdir_count = count;
+ }
+ else if( (tag == TIFFTAG_TILEBYTECOUNTS || tag == TIFFTAG_STRIPBYTECOUNTS)
&&
+ tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 )
+ {
+ tif->tif_dir.td_stripbytecount_entry.tdir_type = datatype;
+ tif->tif_dir.td_stripbytecount_entry.tdir_count = count;
+ }
+
/* -------------------------------------------------------------------- */
/* If the tag type, and count match, then we just write it out */
/* over the old values without altering the directory entry at */
@@ -2966,6 +3207,7 @@ _TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype,
/* Adjust the directory entry. */
/* -------------------------------------------------------------------- */
entry_type = datatype;
+ entry_count = (uint64)count;
memcpy( direntry_raw + 2, &entry_type, sizeof(uint16) );
if (tif->tif_flags&TIFF_SWAB)
TIFFSwabShort( (uint16 *) (direntry_raw + 2) );
diff --git a/dll/3rdparty/libtiff/tif_flush.c b/dll/3rdparty/libtiff/tif_flush.c
index d76738a1915..773def11c13 100644
--- a/dll/3rdparty/libtiff/tif_flush.c
+++ b/dll/3rdparty/libtiff/tif_flush.c
@@ -46,36 +46,8 @@ TIFFFlush(TIFF* tif)
&& !(tif->tif_flags & TIFF_DIRTYDIRECT)
&& tif->tif_mode == O_RDWR )
{
- uint64 *offsets=NULL, *sizes=NULL;
-
- if( TIFFIsTiled(tif) )
- {
- if( TIFFGetField( tif, TIFFTAG_TILEOFFSETS, &offsets )
- && TIFFGetField( tif, TIFFTAG_TILEBYTECOUNTS, &sizes )
- && _TIFFRewriteField( tif, TIFFTAG_TILEOFFSETS, TIFF_LONG8,
- tif->tif_dir.td_nstrips, offsets )
- && _TIFFRewriteField( tif, TIFFTAG_TILEBYTECOUNTS, TIFF_LONG8,
- tif->tif_dir.td_nstrips, sizes ) )
- {
- tif->tif_flags &= ~TIFF_DIRTYSTRIP;
- tif->tif_flags &= ~TIFF_BEENWRITING;
- return 1;
- }
- }
- else
- {
- if( TIFFGetField( tif, TIFFTAG_STRIPOFFSETS, &offsets )
- && TIFFGetField( tif, TIFFTAG_STRIPBYTECOUNTS, &sizes )
- && _TIFFRewriteField( tif, TIFFTAG_STRIPOFFSETS, TIFF_LONG8,
- tif->tif_dir.td_nstrips, offsets )
- && _TIFFRewriteField( tif, TIFFTAG_STRIPBYTECOUNTS, TIFF_LONG8,
- tif->tif_dir.td_nstrips, sizes ) )
- {
- tif->tif_flags &= ~TIFF_DIRTYSTRIP;
- tif->tif_flags &= ~TIFF_BEENWRITING;
- return 1;
- }
- }
+ if( TIFFForceStrileArrayWriting(tif) )
+ return 1;
}
if ((tif->tif_flags & (TIFF_DIRTYDIRECT|TIFF_DIRTYSTRIP))
@@ -85,6 +57,92 @@ TIFFFlush(TIFF* tif)
return (1);
}
+/*
+ * This is an advanced writing function that must be used in a particular
+ * sequence, and together with TIFFDeferStrileArrayWriting(),
+ * to make its intended effect. Its aim is to force the writing of
+ * the [Strip/Tile][Offsets/ByteCounts] arrays at the end of the file, when
+ * they have not yet been rewritten.
+ *
+ * The typical sequence of calls is:
+ * TIFFOpen()
+ * [ TIFFCreateDirectory(tif) ]
+ * Set fields with calls to TIFFSetField(tif, ...)
+ * TIFFDeferStrileArrayWriting(tif)
+ * TIFFWriteCheck(tif, ...)
+ * TIFFWriteDirectory(tif)
+ * ... potentially create other directories and come back to the above directory
+ * TIFFForceStrileArrayWriting(tif)
+ *
+ * Returns 1 in case of success, 0 otherwise.
+ */
+int TIFFForceStrileArrayWriting(TIFF* tif)
+{
+ static const char module[] = "TIFFForceStrileArrayWriting";
+ const int isTiled = TIFFIsTiled(tif);
+
+ if (tif->tif_mode == O_RDONLY)
+ {
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "File opened in read-only mode");
+ return 0;
+ }
+ if( tif->tif_diroff == 0 )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Directory has not yet been written");
+ return 0;
+ }
+ if( (tif->tif_flags & TIFF_DIRTYDIRECT) != 0 )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Directory has changes other than the strile arrays. "
+ "TIFFRewriteDirectory() should be called instead");
+ return 0;
+ }
+
+ if( !(tif->tif_flags & TIFF_DIRTYSTRIP) )
+ {
+ if( !(tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0) )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Function not called together with "
+ "TIFFDeferStrileArrayWriting()");
+ return 0;
+ }
+
+ if (tif->tif_dir.td_stripoffset_p == NULL && !TIFFSetupStrips(tif))
+ return 0;
+ }
+
+ if( _TIFFRewriteField( tif,
+ isTiled ? TIFFTAG_TILEOFFSETS :
+ TIFFTAG_STRIPOFFSETS,
+ TIFF_LONG8,
+ tif->tif_dir.td_nstrips,
+ tif->tif_dir.td_stripoffset_p )
+ && _TIFFRewriteField( tif,
+ isTiled ? TIFFTAG_TILEBYTECOUNTS :
+ TIFFTAG_STRIPBYTECOUNTS,
+ TIFF_LONG8,
+ tif->tif_dir.td_nstrips,
+ tif->tif_dir.td_stripbytecount_p ) )
+ {
+ tif->tif_flags &= ~TIFF_DIRTYSTRIP;
+ tif->tif_flags &= ~TIFF_BEENWRITING;
+ return 1;
+ }
+
+ return 0;
+}
+
/*
* Flush buffered data to the file.
*
diff --git a/dll/3rdparty/libtiff/tif_getimage.c b/dll/3rdparty/libtiff/tif_getimage.c
index 7fc00d6ab65..c2f5d294093 100644
--- a/dll/3rdparty/libtiff/tif_getimage.c
+++ b/dll/3rdparty/libtiff/tif_getimage.c
@@ -755,9 +755,8 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32
h)
uint32 leftmost_tw;
tilesize = TIFFTileSize(tif);
- bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,tilesize);
+ bufsize = _TIFFMultiplySSize(tif, alpha?4:3,tilesize, "gtTileSeparate");
if (bufsize == 0) {
- TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in
%s", "gtTileSeparate");
return (0);
}
@@ -950,16 +949,23 @@ gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32
h)
fromskew = (w < imagewidth ? imagewidth - w : 0);
for (row = 0; row < h; row += nrow)
{
+ uint32 temp;
rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
nrow = (row + rowstoread > h ? h - row : rowstoread);
nrowsub = nrow;
if ((nrowsub%subsamplingver)!=0)
nrowsub+=subsamplingver-nrowsub%subsamplingver;
+ temp = (row + img->row_offset)%rowsperstrip + nrowsub;
+ if( scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline) )
+ {
+ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in
gtStripContig");
+ return 0;
+ }
if (_TIFFReadEncodedStripAndAllocBuffer(tif,
TIFFComputeStrip(tif,row+img->row_offset, 0),
(void**)(&buf),
maxstripsize,
- ((row + img->row_offset)%rowsperstrip + nrowsub) * scanline)==(tmsize_t)(-1)
+ temp * scanline)==(tmsize_t)(-1)
&& (buf == NULL || img->stoponerr))
{
ret = 0;
@@ -1019,9 +1025,8 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32
h)
uint16 colorchannels;
stripsize = TIFFStripSize(tif);
- bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,stripsize);
+ bufsize = _TIFFMultiplySSize(tif,alpha?4:3,stripsize, "gtStripSeparate");
if (bufsize == 0) {
- TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in
%s", "gtStripSeparate");
return (0);
}
@@ -1053,15 +1058,22 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w,
uint32 h)
fromskew = (w < imagewidth ? imagewidth - w : 0);
for (row = 0; row < h; row += nrow)
{
+ uint32 temp;
rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
nrow = (row + rowstoread > h ? h - row : rowstoread);
offset_row = row + img->row_offset;
+ temp = (row + img->row_offset)%rowsperstrip + nrow;
+ if( scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX /
scanline) )
+ {
+ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
"Integer overflow in gtStripSeparate");
+ return 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)
+ temp * scanline)==(tmsize_t)(-1)
&& (buf == NULL || img->stoponerr))
{
ret = 0;
@@ -1081,7 +1093,7 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32
h)
}
}
else if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0),
- p0, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
+ p0, temp * scanline)==(tmsize_t)(-1)
&& img->stoponerr)
{
ret = 0;
@@ -1089,7 +1101,7 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32
h)
}
if (colorchannels > 1
&& TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif,
offset_row, 1),
- p1, ((row + img->row_offset)%rowsperstrip
+ nrow) * scanline) == (tmsize_t)(-1)
+ p1, temp * scanline) == (tmsize_t)(-1)
&& img->stoponerr)
{
ret = 0;
@@ -1097,7 +1109,7 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32
h)
}
if (colorchannels > 1
&& TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif,
offset_row, 2),
- p2, ((row + img->row_offset)%rowsperstrip
+ nrow) * scanline) == (tmsize_t)(-1)
+ p2, temp * scanline) == (tmsize_t)(-1)
&& img->stoponerr)
{
ret = 0;
@@ -1106,7 +1118,7 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32
h)
if (alpha)
{
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, colorchannels),
- pa, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
+ pa, temp * scanline)==(tmsize_t)(-1)
&& img->stoponerr)
{
ret = 0;
@@ -2957,7 +2969,7 @@ TIFFReadRGBATileExt(TIFF* tif, uint32 col, uint32 row, uint32 *
raster, int stop
if( !TIFFIsTiled( tif ) )
{
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
- "Can't use TIFFReadRGBATile() with stripped file.");
+ "Can't use TIFFReadRGBATile() with striped file.");
return (0);
}
diff --git a/dll/3rdparty/libtiff/tif_jpeg.c b/dll/3rdparty/libtiff/tif_jpeg.c
index f2ddc331a0e..93ae2ead1de 100644
--- a/dll/3rdparty/libtiff/tif_jpeg.c
+++ b/dll/3rdparty/libtiff/tif_jpeg.c
@@ -780,12 +780,9 @@ JPEGFixupTagsSubsampling(TIFF* tif)
*/
static const char module[] = "JPEGFixupTagsSubsampling";
struct JPEGFixupTagsSubsamplingData m;
+ uint64 fileoffset = TIFFGetStrileOffset(tif, 0);
- _TIFFFillStriles( tif );
-
- if( tif->tif_dir.td_stripbytecount == NULL
- || tif->tif_dir.td_stripoffset == NULL
- || tif->tif_dir.td_stripbytecount[0] == 0 )
+ if( fileoffset == 0 )
{
/* Do not even try to check if the first strip/tile does not
yet exist, as occurs when GDAL has created a new NULL file
@@ -804,9 +801,9 @@ JPEGFixupTagsSubsampling(TIFF* tif)
}
m.buffercurrentbyte=NULL;
m.bufferbytesleft=0;
- m.fileoffset=tif->tif_dir.td_stripoffset[0];
+ m.fileoffset=fileoffset;
m.filepositioned=0;
- m.filebytesleft=tif->tif_dir.td_stripbytecount[0];
+ m.filebytesleft=TIFFGetStrileByteCount(tif, 0);
if (!JPEGFixupTagsSubsamplingSec(&m))
TIFFWarningExt(tif->tif_clientdata,module,
"Unable to auto-correct subsampling values, likely corrupt JPEG compressed
data in first strip/tile; auto-correcting skipped");
@@ -1566,7 +1563,7 @@ JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
JSAMPLE *outptr = (JSAMPLE*)tmpbuf + clumpoffset;
#else
JSAMPLE *outptr = (JSAMPLE*)buf + clumpoffset;
- if (cc < (tmsize_t) (clumpoffset + samples_per_clump*(clumps_per_line-1) +
hsamp)) {
+ if (cc < (tmsize_t)(clumpoffset + (tmsize_t)samples_per_clump*(clumps_per_line-1)
+ hsamp)) {
TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw",
"application buffer not large enough for all data, possible subsampling
issue");
return 0;
@@ -2126,8 +2123,8 @@ JPEGEncodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
/* data is expected to be supplied in multiples of a clumpline */
/* a clumpline is equivalent to v_sampling desubsampled scanlines */
/* TODO: the following calculation of bytesperclumpline, should substitute calculation
of sp->bytesperline, except that it is per v_sampling lines */
- bytesperclumpline =
(((sp->cinfo.c.image_width+sp->h_sampling-1)/sp->h_sampling)
- *(sp->h_sampling*sp->v_sampling+2)*sp->cinfo.c.data_precision+7)
+ bytesperclumpline =
((((tmsize_t)sp->cinfo.c.image_width+sp->h_sampling-1)/sp->h_sampling)
+
*((tmsize_t)sp->h_sampling*sp->v_sampling+2)*sp->cinfo.c.data_precision+7)
/8;
nrows = ( cc / bytesperclumpline ) * sp->v_sampling;
diff --git a/dll/3rdparty/libtiff/tif_luv.c b/dll/3rdparty/libtiff/tif_luv.c
index 3b9e6337f7d..dfebd1855b9 100644
--- a/dll/3rdparty/libtiff/tif_luv.c
+++ b/dll/3rdparty/libtiff/tif_luv.c
@@ -742,9 +742,14 @@ LogLuvEncodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
#undef exp2 /* Conflict with C'99 function */
#define exp2(x) exp(M_LN2*(x))
-#define itrunc(x,m) ((m)==SGILOGENCODE_NODITHER ? \
- (int)(x) : \
- (int)((x) + rand()*(1./RAND_MAX) - .5))
+static int itrunc(double x, int m)
+{
+ if( m == SGILOGENCODE_NODITHER )
+ return (int)x;
+ /* Silence CoverityScan warning about bad crypto function */
+ /* coverity[dont_call] */
+ return (int)(x + rand()*(1./RAND_MAX) - .5);
+}
#if !LOGLUV_PUBLIC
static
@@ -1264,16 +1269,10 @@ LogL16GuessDataFmt(TIFFDirectory *td)
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)
{
- if( m1 == 0 || m2 > TIFF_TMSIZE_T_MAX / m1 )
- return 0;
- return m1 * m2;
+ return _TIFFMultiplySSize(NULL, m1, m2, NULL);
}
static int
@@ -1507,7 +1506,7 @@ LogLuvSetupEncode(TIFF* tif)
switch (td->td_photometric) {
case PHOTOMETRIC_LOGLUV:
if (!LogLuvInitState(tif))
- break;
+ return (0);
if (td->td_compression == COMPRESSION_SGILOG24) {
tif->tif_encoderow = LogLuvEncode24;
switch (sp->user_datafmt) {
@@ -1540,7 +1539,7 @@ LogLuvSetupEncode(TIFF* tif)
break;
case PHOTOMETRIC_LOGL:
if (!LogL16InitState(tif))
- break;
+ return (0);
tif->tif_encoderow = LogL16Encode;
switch (sp->user_datafmt) {
case SGILOGDATAFMT_FLOAT:
@@ -1556,7 +1555,7 @@ LogLuvSetupEncode(TIFF* tif)
TIFFErrorExt(tif->tif_clientdata, module,
"Inappropriate photometric interpretation %d for SGILog compression;
%s",
td->td_photometric, "must be either LogLUV or LogL");
- break;
+ return (0);
}
sp->encoder_state = 1;
return (1);
diff --git a/dll/3rdparty/libtiff/tif_lzw.c b/dll/3rdparty/libtiff/tif_lzw.c
index 47260533e6e..9c06935158d 100644
--- a/dll/3rdparty/libtiff/tif_lzw.c
+++ b/dll/3rdparty/libtiff/tif_lzw.c
@@ -247,6 +247,8 @@ LZWSetupDecode(TIFF* tif)
/*
* Zero-out the unused entries
*/
+ /* Silence false positive */
+ /* coverity[overrun-buffer-arg] */
_TIFFmemset(&sp->dec_codetab[CODE_CLEAR], 0,
(CODE_FIRST - CODE_CLEAR) * sizeof (code_t));
}
diff --git a/dll/3rdparty/libtiff/tif_ojpeg.c b/dll/3rdparty/libtiff/tif_ojpeg.c
index 27385d8c47d..bf0d1a2a092 100644
--- a/dll/3rdparty/libtiff/tif_ojpeg.c
+++ b/dll/3rdparty/libtiff/tif_ojpeg.c
@@ -243,6 +243,7 @@ typedef enum {
typedef struct {
TIFF* tif;
int decoder_ok;
+ int error_in_raw_data_decoding;
#ifndef LIBJPEG_ENCAP_EXTERNAL
JMP_BUF exit_jmpbuf;
#endif
@@ -678,7 +679,7 @@ OJPEGPreDecode(TIFF* tif, uint16 s)
if (OJPEGReadSecondarySos(tif,s)==0)
return(0);
}
- if isTiled(tif)
+ if (isTiled(tif))
m=tif->tif_curtile;
else
m=tif->tif_curstrip;
@@ -742,6 +743,7 @@ OJPEGPreDecodeSkipRaw(TIFF* tif)
}
m-=sp->subsampling_convert_clines-sp->subsampling_convert_state;
sp->subsampling_convert_state=0;
+ sp->error_in_raw_data_decoding=0;
}
while (m>=sp->subsampling_convert_clines)
{
@@ -792,6 +794,10 @@ OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
TIFFErrorExt(tif->tif_clientdata,module,"Cannot decode: decoder not
correctly initialized");
return 0;
}
+ if( sp->error_in_raw_data_decoding )
+ {
+ return 0;
+ }
if (sp->libjpeg_jpeg_query_style==0)
{
if (OJPEGDecodeRaw(tif,buf,cc)==0)
@@ -831,8 +837,41 @@ OJPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc)
{
if (sp->subsampling_convert_state==0)
{
+ const jpeg_decompress_struct* cinfo = &sp->libjpeg_jpeg_decompress_struct;
+ int width = 0;
+ int last_col_width = 0;
+ int jpeg_bytes;
+ int expected_bytes;
+ int i;
+ if (cinfo->MCUs_per_row == 0)
+ {
+ sp->error_in_raw_data_decoding = 1;
+ return 0;
+ }
+ for (i = 0; i < cinfo->comps_in_scan; ++i)
+ {
+ const jpeg_component_info* info = cinfo->cur_comp_info[i];
+#if JPEG_LIB_VERSION >= 70
+ width += info->MCU_width * info->DCT_h_scaled_size;
+ last_col_width += info->last_col_width * info->DCT_h_scaled_size;
+#else
+ width += info->MCU_width * info->DCT_scaled_size;
+ last_col_width += info->last_col_width * info->DCT_scaled_size;
+#endif
+ }
+ jpeg_bytes = (cinfo->MCUs_per_row - 1) * width + last_col_width;
+ expected_bytes = sp->subsampling_convert_clinelenout * sp->subsampling_ver *
sp->subsampling_hor;
+ if (jpeg_bytes != expected_bytes)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Inconsistent number of MCU in
codestream");
+ sp->error_in_raw_data_decoding = 1;
+ return(0);
+ }
if
(jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0)
+ {
+ sp->error_in_raw_data_decoding = 1;
return(0);
+ }
}
oy=sp->subsampling_convert_ybuf+sp->subsampling_convert_state*sp->subsampling_ver*sp->subsampling_convert_ylinelen;
ocb=sp->subsampling_convert_cbbuf+sp->subsampling_convert_state*sp->subsampling_convert_clinelen;
@@ -990,7 +1029,6 @@ OJPEGSubsamplingCorrect(TIFF* tif)
OJPEGState* sp=(OJPEGState*)tif->tif_data;
uint8 mh;
uint8 mv;
- _TIFFFillStriles( tif );
assert(sp->subsamplingcorrect_done==0);
if ((tif->tif_dir.td_samplesperpixel!=3) ||
((tif->tif_dir.td_photometric!=PHOTOMETRIC_YCBCR) &&
@@ -1046,7 +1084,7 @@ OJPEGReadHeaderInfo(TIFF* tif)
assert(sp->readheader_done==0);
sp->image_width=tif->tif_dir.td_imagewidth;
sp->image_length=tif->tif_dir.td_imagelength;
- if isTiled(tif)
+ if (isTiled(tif))
{
sp->strile_width=tif->tif_dir.td_tilewidth;
sp->strile_length=tif->tif_dir.td_tilelength;
@@ -1082,6 +1120,12 @@ OJPEGReadHeaderInfo(TIFF* tif)
}
if (sp->strile_length<sp->image_length)
{
+ if (((sp->subsampling_hor!=1) && (sp->subsampling_hor!=2) &&
(sp->subsampling_hor!=4)) ||
+ ((sp->subsampling_ver!=1) && (sp->subsampling_ver!=2) &&
(sp->subsampling_ver!=4)))
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Invalid subsampling values");
+ return(0);
+ }
if (sp->strile_length%(sp->subsampling_ver*8)!=0)
{
TIFFErrorExt(tif->tif_clientdata,module,"Incompatible vertical subsampling and
image strip/tile length");
@@ -1197,7 +1241,13 @@ OJPEGWriteHeaderInfo(TIFF* tif)
sp->subsampling_convert_ybuflen=sp->subsampling_convert_ylinelen*sp->subsampling_convert_ylines;
sp->subsampling_convert_cbuflen=sp->subsampling_convert_clinelen*sp->subsampling_convert_clines;
sp->subsampling_convert_ycbcrbuflen=sp->subsampling_convert_ybuflen+2*sp->subsampling_convert_cbuflen;
- sp->subsampling_convert_ycbcrbuf=_TIFFmalloc(sp->subsampling_convert_ycbcrbuflen);
+ /* The calloc is not normally necessary, except in some
edge/broken cases */
+ /* for example for a tiled image of height 1 with a tile height
of 1 and subsampling_hor=subsampling_ver=2 */
+ /* In that case, libjpeg will only fill the 8 first lines of the
16 lines */
+ /* See
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16844 */
+ /* Even if this case is allowed (?), its handling is broken
because OJPEGPreDecode() should also likely */
+ /* reset subsampling_convert_state to 0 when changing tile. */
+ sp->subsampling_convert_ycbcrbuf=_TIFFcalloc(1,
sp->subsampling_convert_ycbcrbuflen);
if (sp->subsampling_convert_ycbcrbuf==0)
{
TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
@@ -1223,10 +1273,11 @@ OJPEGWriteHeaderInfo(TIFF* tif)
*m++=sp->subsampling_convert_cbbuf+n*sp->subsampling_convert_clinelen;
for (n=0; n<sp->subsampling_convert_clines; n++)
*m++=sp->subsampling_convert_crbuf+n*sp->subsampling_convert_clinelen;
- sp->subsampling_convert_clinelenout=((sp->strile_width+sp->subsampling_hor-1)/sp->subsampling_hor);
+ sp->subsampling_convert_clinelenout=sp->strile_width/sp->subsampling_hor +
((sp->strile_width % sp->subsampling_hor) != 0 ? 1 : 0);
sp->subsampling_convert_state=0;
+ sp->error_in_raw_data_decoding=0;
sp->bytes_per_line=sp->subsampling_convert_clinelenout*(sp->subsampling_ver*sp->subsampling_hor+2);
- sp->lines_per_strile=((sp->strile_length+sp->subsampling_ver-1)/sp->subsampling_ver);
+ sp->lines_per_strile=sp->strile_length/sp->subsampling_ver +
((sp->strile_length % sp->subsampling_ver) != 0 ? 1 : 0);
sp->subsampling_convert_log=1;
}
}
@@ -1272,7 +1323,9 @@ OJPEGReadHeaderInfoSec(TIFF* tif)
}
else
{
- if ((sp->jpeg_interchange_format_length==0) ||
(sp->jpeg_interchange_format+sp->jpeg_interchange_format_length>sp->file_size))
+ if ((sp->jpeg_interchange_format_length==0) ||
+ (sp->jpeg_interchange_format > TIFF_UINT64_MAX -
sp->jpeg_interchange_format_length) ||
+
(sp->jpeg_interchange_format+sp->jpeg_interchange_format_length>sp->file_size))
sp->jpeg_interchange_format_length=sp->file_size-sp->jpeg_interchange_format;
}
}
@@ -1989,32 +2042,30 @@ OJPEGReadBufferFill(OJPEGState* sp)
sp->in_buffer_source=osibsStrile;
break;
case osibsStrile:
- if (!_TIFFFillStriles( sp->tif )
- || sp->tif->tif_dir.td_stripoffset == NULL
- || sp->tif->tif_dir.td_stripbytecount == NULL)
- return 0;
-
if (sp->in_buffer_next_strile==sp->in_buffer_strile_count)
sp->in_buffer_source=osibsEof;
else
{
- sp->in_buffer_file_pos=sp->tif->tif_dir.td_stripoffset[sp->in_buffer_next_strile];
+ int err = 0;
+ sp->in_buffer_file_pos=TIFFGetStrileOffsetWithErr(sp->tif,
sp->in_buffer_next_strile, &err);
+ if( err )
+ return 0;
if (sp->in_buffer_file_pos!=0)
{
+ uint64 bytecount = TIFFGetStrileByteCountWithErr(sp->tif,
sp->in_buffer_next_strile, &err);
+ if( err )
+ return 0;
if (sp->in_buffer_file_pos>=sp->file_size)
sp->in_buffer_file_pos=0;
- else if (sp->tif->tif_dir.td_stripbytecount==NULL)
+ else if (bytecount==0)
sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos;
else
{
- if (sp->tif->tif_dir.td_stripbytecount == 0) {
- TIFFErrorExt(sp->tif->tif_clientdata,sp->tif->tif_name,"Strip
byte counts are missing");
- return(0);
- }
- sp->in_buffer_file_togo=sp->tif->tif_dir.td_stripbytecount[sp->in_buffer_next_strile];
+ sp->in_buffer_file_togo=bytecount;
if (sp->in_buffer_file_togo==0)
sp->in_buffer_file_pos=0;
- else if
(sp->in_buffer_file_pos+sp->in_buffer_file_togo>sp->file_size)
+ else if (sp->in_buffer_file_pos > TIFF_UINT64_MAX -
sp->in_buffer_file_togo ||
+
sp->in_buffer_file_pos+sp->in_buffer_file_togo>sp->file_size)
sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos;
}
}
diff --git a/dll/3rdparty/libtiff/tif_open.c b/dll/3rdparty/libtiff/tif_open.c
index 7a9f074c8ea..7576bb9ea85 100644
--- a/dll/3rdparty/libtiff/tif_open.c
+++ b/dll/3rdparty/libtiff/tif_open.c
@@ -25,7 +25,6 @@
/*
* TIFF Library.
*/
-
#include <precomp.h>
/*
@@ -132,6 +131,7 @@ TIFFClientOpen(
if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc) {
TIFFErrorExt(clientdata, module,
"One of the client procedures is NULL pointer.");
+ _TIFFfree(tif);
goto bad2;
}
tif->tif_readproc = readproc;
@@ -182,6 +182,8 @@ TIFFClientOpen(
* 'h' read TIFF header only, do not load the first IFD
* '4' ClassicTIFF for creating a file (default)
* '8' BigTIFF for creating a file
+ * 'D' enable use of deferred strip/tile offset/bytecount array loading.
+ * 'O' on-demand loading of values instead of whole array loading
(implies D)
*
* The use of the 'l' and 'b' flags is strongly discouraged.
* These flags are provided solely because numerous vendors,
@@ -263,7 +265,22 @@ TIFFClientOpen(
if (m&O_CREAT)
tif->tif_flags |= TIFF_BIGTIFF;
break;
+ case 'D':
+ tif->tif_flags |= TIFF_DEFERSTRILELOAD;
+ break;
+ case 'O':
+ if( m == O_RDONLY )
+ tif->tif_flags |= (TIFF_LAZYSTRILELOAD | TIFF_DEFERSTRILELOAD);
+ break;
}
+
+#ifdef DEFER_STRILE_LOAD
+ /* Compatibility with old DEFER_STRILE_LOAD compilation flag */
+ /* Probably unneeded, since to the best of my knowledge (E. Rouault) */
+ /* GDAL was the only user of this, and will now use the new 'D' flag */
+ tif->tif_flags |= TIFF_DEFERSTRILELOAD;
+#endif
+
/*
* Read in TIFF header.
*/
diff --git a/dll/3rdparty/libtiff/tif_packbits.c b/dll/3rdparty/libtiff/tif_packbits.c
index f464e177390..bfeef474d0a 100644
--- a/dll/3rdparty/libtiff/tif_packbits.c
+++ b/dll/3rdparty/libtiff/tif_packbits.c
@@ -23,7 +23,6 @@
*/
#include <precomp.h>
-
#ifdef PACKBITS_SUPPORT
/*
* TIFF Library.
diff --git a/dll/3rdparty/libtiff/tif_pixarlog.c b/dll/3rdparty/libtiff/tif_pixarlog.c
index 655a12b597e..203db187a79 100644
--- a/dll/3rdparty/libtiff/tif_pixarlog.c
+++ b/dll/3rdparty/libtiff/tif_pixarlog.c
@@ -90,8 +90,8 @@
#include "tif_predict.h"
#include "zlib.h"
-//#include <stdio.h>
-//#include <stdlib.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <math.h>
/* Tables for converting to/from 11 bit coded values */
@@ -634,20 +634,16 @@ PixarLogGuessDataFmt(TIFFDirectory *td)
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)
{
- if( m1 == 0 || m2 > TIFF_TMSIZE_T_MAX / m1 )
- return 0;
- return m1 * m2;
+ return _TIFFMultiplySSize(NULL, m1, m2, NULL);
}
static tmsize_t
add_ms(tmsize_t m1, tmsize_t m2)
{
+ assert(m1 >= 0 && m2 >= 0);
/* if either input is zero, assume overflow already occurred */
if (m1 == 0 || m2 == 0)
return 0;
@@ -817,9 +813,7 @@ PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
TIFFErrorExt(tif->tif_clientdata, module,
"Decoding error at scanline %lu, %s",
(unsigned long) tif->tif_row, sp->stream.msg ? sp->stream.msg :
"(null)");
- if (inflateSync(&sp->stream) != Z_OK)
- return (0);
- continue;
+ return (0);
}
if (state != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
@@ -1153,7 +1147,7 @@ PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
llen = sp->stride * td->td_imagewidth;
/* Check against the number of elements (of size uint16) of sp->tbuf */
- if( n > (tmsize_t)(td->td_rowsperstrip * llen) )
+ if( n > ((tmsize_t)td->td_rowsperstrip * llen) )
{
TIFFErrorExt(tif->tif_clientdata, module,
"Too many input bytes provided");
diff --git a/dll/3rdparty/libtiff/tif_print.c b/dll/3rdparty/libtiff/tif_print.c
index b5a3e8cb7c5..50caec33501 100644
--- a/dll/3rdparty/libtiff/tif_print.c
+++ b/dll/3rdparty/libtiff/tif_print.c
@@ -27,7 +27,6 @@
*
* Directory Printing Support
*/
-
#include <precomp.h>
//#include <stdio.h>
@@ -653,8 +652,6 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
if (tif->tif_tagmethods.printdir)
(*tif->tif_tagmethods.printdir)(tif, fd, flags);
- _TIFFFillStriles( tif );
-
if ((flags & TIFFPRINT_STRIPS) &&
TIFFFieldSet(tif,FIELD_STRIPOFFSETS)) {
uint32 s;
@@ -666,13 +663,13 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
fprintf(fd, " %3lu: [%8I64u, %8I64u]\n",
(unsigned long) s,
- td->td_stripoffset ? (unsigned __int64) td->td_stripoffset[s] : 0,
- td->td_stripbytecount ? (unsigned __int64) td->td_stripbytecount[s] : 0);
+ (unsigned __int64) TIFFGetStrileOffset(tif, s),
+ (unsigned __int64) TIFFGetStrileByteCount(tif, s));
#else
fprintf(fd, " %3lu: [%8llu, %8llu]\n",
(unsigned long) s,
- td->td_stripoffset ? (unsigned long long) td->td_stripoffset[s] : 0,
- td->td_stripbytecount ? (unsigned long long) td->td_stripbytecount[s] : 0);
+ (unsigned long long) TIFFGetStrileOffset(tif, s),
+ (unsigned long long) TIFFGetStrileByteCount(tif, s));
#endif
}
}
diff --git a/dll/3rdparty/libtiff/tif_read.c b/dll/3rdparty/libtiff/tif_read.c
index 78c23aa5115..61e05dc2588 100644
--- a/dll/3rdparty/libtiff/tif_read.c
+++ b/dll/3rdparty/libtiff/tif_read.c
@@ -29,9 +29,6 @@
#include <precomp.h>
//#include <stdio.h>
-#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0))
-#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1)
-
int TIFFFillStrip(TIFF* tif, uint32 strip);
int TIFFFillTile(TIFF* tif, uint32 tile);
static int TIFFStartStrip(TIFF* tif, uint32 strip);
@@ -49,6 +46,8 @@ TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const
char* m
#define THRESHOLD_MULTIPLIER 10
#define MAX_THRESHOLD (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER
* INITIAL_THRESHOLD)
+#define TIFF_INT64_MAX ((((int64)0x7FFFFFFF) << 32) | 0xFFFFFFFF)
+
/* 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,
@@ -61,6 +60,22 @@ static int TIFFReadAndRealloc( TIFF* tif, tmsize_t size,
#endif
tmsize_t already_read = 0;
+
+#if SIZEOF_SIZE_T != 8
+ /* On 32 bit processes, if the request is large enough, check against */
+ /* file size */
+ if( size > 1000 * 1000 * 1000 )
+ {
+ uint64 filesize = TIFFGetFileSize(tif);
+ if( (uint64)size >= filesize )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Chunk size requested is larger than file
size.");
+ return 0;
+ }
+ }
+#endif
+
/* 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 */
@@ -103,6 +118,11 @@ static int TIFFReadAndRealloc( TIFF* tif, tmsize_t size,
}
tif->tif_rawdata = new_rawdata;
}
+ if( tif->tif_rawdata == NULL )
+ {
+ /* should not happen in practice but helps CoverityScan */
+ return 0;
+ }
bytes_read = TIFFReadFile(tif,
tif->tif_rawdata + rawdata_offset + already_read, to_read);
@@ -170,17 +190,14 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int
restart )
tmsize_t to_read;
tmsize_t read_ahead_mod;
/* tmsize_t bytecountm; */
-
- if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
- return 0;
-
+
/*
* Expand raw data buffer, if needed, to hold data
* strip coming from file (perhaps should set upper
* bound on the size of a buffer we'll use?).
*/
- /* bytecountm=(tmsize_t) td->td_stripbytecount[strip]; */
+ /* bytecountm=(tmsize_t) TIFFGetStrileByteCount(tif, strip); */
/* Not completely sure where the * 2 comes from, but probably for */
/* an exponentional growth strategy of tif_rawdatasize */
@@ -224,7 +241,7 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int
restart )
/*
** Seek to the point in the file where more data should be read.
*/
- read_offset = td->td_stripoffset[strip]
+ read_offset = TIFFGetStrileOffset(tif, strip)
+ tif->tif_rawdataoff + tif->tif_rawdataloaded;
if (!SeekOK(tif, read_offset)) {
@@ -241,10 +258,10 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int
restart )
to_read = read_ahead_mod - unused_data;
else
to_read = tif->tif_rawdatasize - unused_data;
- if( (uint64) to_read > td->td_stripbytecount[strip]
+ if( (uint64) to_read > TIFFGetStrileByteCount(tif, strip)
- tif->tif_rawdataoff - tif->tif_rawdataloaded )
{
- to_read = (tmsize_t) td->td_stripbytecount[strip]
+ to_read = (tmsize_t) TIFFGetStrileByteCount(tif, strip)
- tif->tif_rawdataoff - tif->tif_rawdataloaded;
}
@@ -283,7 +300,7 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int
restart )
/* For JPEG, if there are multiple scans (can generally be known */
/* with the read_ahead used), we need to read the whole strip */
if( tif->tif_dir.td_compression==COMPRESSION_JPEG &&
- (uint64)tif->tif_rawcc < td->td_stripbytecount[strip] )
+ (uint64)tif->tif_rawcc < TIFFGetStrileByteCount(tif, strip) )
{
if( TIFFJPEGIsFullStripRequired(tif) )
{
@@ -342,9 +359,7 @@ TIFFSeek(TIFF* tif, uint32 row, uint16 sample )
* read it a few lines at a time?
*/
#if defined(CHUNKY_STRIP_READ_SUPPORT)
- if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
- return 0;
- whole_strip = tif->tif_dir.td_stripbytecount[strip] < 10
+ whole_strip = TIFFGetStrileByteCount(tif, strip) < 10
|| isMapped(tif);
if( td->td_compression == COMPRESSION_LERC ||
td->td_compression == COMPRESSION_JBIG )
@@ -397,7 +412,7 @@ TIFFSeek(TIFF* tif, uint32 row, uint16 sample )
else if( !whole_strip )
{
if( ((tif->tif_rawdata + tif->tif_rawdataloaded) -
tif->tif_rawcp) < read_ahead
- && (uint64) tif->tif_rawdataoff+tif->tif_rawdataloaded
< td->td_stripbytecount[strip] )
+ && (uint64) tif->tif_rawdataoff+tif->tif_rawdataloaded
< TIFFGetStrileByteCount(tif, strip) )
{
if( !TIFFFillStripPartial(tif,strip,read_ahead,0) )
return 0;
@@ -594,16 +609,11 @@ static tmsize_t
TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,
const char* module)
{
- TIFFDirectory *td = &tif->tif_dir;
-
- if (!_TIFFFillStriles( tif ))
- return ((tmsize_t)(-1));
-
assert((tif->tif_flags&TIFF_NOREADRAW)==0);
if (!isMapped(tif)) {
tmsize_t cc;
- if (!SeekOK(tif, td->td_stripoffset[strip])) {
+ if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip))) {
TIFFErrorExt(tif->tif_clientdata, module,
"Seek error at scanline %lu, strip %lu",
(unsigned long) tif->tif_row, (unsigned long) strip);
@@ -629,8 +639,8 @@ TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,
} else {
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))
+ if ((TIFFGetStrileOffset(tif, strip) > (uint64)TIFF_TMSIZE_T_MAX)||
+ ((ma=(tmsize_t)TIFFGetStrileOffset(tif,
strip))>tif->tif_size))
{
n=0;
}
@@ -674,12 +684,10 @@ 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 (!SeekOK(tif, TIFFGetStrileOffset(tif, strip_or_tile))) {
if( is_strip )
{
TIFFErrorExt(tif->tif_clientdata, module,
@@ -715,7 +723,7 @@ TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
{
static const char module[] = "TIFFReadRawStrip";
TIFFDirectory *td = &tif->tif_dir;
- uint64 bytecount;
+ uint64 bytecount64;
tmsize_t bytecountm;
if (!TIFFCheckRead(tif, 0))
@@ -733,31 +741,23 @@ TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
"Compression scheme does not support access to raw uncompressed data");
return ((tmsize_t)(-1));
}
- bytecount = td->td_stripbytecount[strip];
- if ((int64)bytecount <= 0) {
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
- TIFFErrorExt(tif->tif_clientdata, module,
- "%I64u: Invalid strip byte count, strip %lu",
- (unsigned __int64) bytecount,
- (unsigned long) strip);
-#else
- TIFFErrorExt(tif->tif_clientdata, module,
- "%llu: Invalid strip byte count, strip %lu",
- (unsigned long long) bytecount,
- (unsigned long) strip);
-#endif
- return ((tmsize_t)(-1));
- }
- bytecountm = (tmsize_t)bytecount;
- if ((uint64)bytecountm!=bytecount) {
- TIFFErrorExt(tif->tif_clientdata, module, "Integer overflow");
+ bytecount64 = TIFFGetStrileByteCount(tif, strip);
+ if (size != (tmsize_t)(-1) && (uint64)size <= bytecount64)
+ bytecountm = size;
+ else
+ bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module);
+ if( bytecountm == 0 ) {
return ((tmsize_t)(-1));
}
- if (size != (tmsize_t)(-1) && size < bytecountm)
- bytecountm = size;
return (TIFFReadRawStrip1(tif, strip, buf, bytecountm, module));
}
+TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
+static uint64 NoSantizeSubUInt64(uint64 a, uint64 b)
+{
+ return a - b;
+}
+
/*
* Read the specified strip and setup for decoding. The data buffer is
* expanded, as necessary, to hold the strip's data.
@@ -768,13 +768,10 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
static const char module[] = "TIFFFillStrip";
TIFFDirectory *td = &tif->tif_dir;
- if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
- return 0;
-
if ((tif->tif_flags&TIFF_NOREADRAW)==0)
{
- uint64 bytecount = td->td_stripbytecount[strip];
- if ((int64)bytecount <= 0) {
+ uint64 bytecount = TIFFGetStrileByteCount(tif, strip);
+ if( bytecount == 0 || bytecount > (uint64)TIFF_INT64_MAX ) {
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFErrorExt(tif->tif_clientdata, module,
"Invalid strip byte count %I64u, strip %lu",
@@ -801,7 +798,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
(bytecount - 4096) / 10 > (uint64)stripsize )
{
uint64 newbytecount = (uint64)stripsize * 10 + 4096;
- if( (int64)newbytecount >= 0 )
+ if( newbytecount == 0 || newbytecount > (uint64)TIFF_INT64_MAX )
{
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFWarningExt(tif->tif_clientdata, module,
@@ -826,13 +823,13 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
* We must check for overflow, potentially causing
* an OOB read. Instead of simple
*
- * td->td_stripoffset[strip]+bytecount > tif->tif_size
+ * TIFFGetStrileOffset(tif, strip)+bytecount > tif->tif_size
*
* comparison (which can overflow) we do the following
* two comparisons:
*/
if (bytecount > (uint64)tif->tif_size ||
- td->td_stripoffset[strip] > (uint64)tif->tif_size - bytecount) {
+ TIFFGetStrileOffset(tif, strip) > (uint64)tif->tif_size - bytecount) {
/*
* This error message might seem strange, but
* it's what would happen if a read were done
@@ -844,7 +841,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
"Read error on strip %lu; "
"got %I64u bytes, expected %I64u",
(unsigned long) strip,
- (unsigned __int64) tif->tif_size - td->td_stripoffset[strip],
+ (unsigned __int64) NoSantizeSubUInt64(tif->tif_size, TIFFGetStrileOffset(tif,
strip)),
(unsigned __int64) bytecount);
#else
TIFFErrorExt(tif->tif_clientdata, module,
@@ -852,7 +849,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
"Read error on strip %lu; "
"got %llu bytes, expected %llu",
(unsigned long) strip,
- (unsigned long long) tif->tif_size - td->td_stripoffset[strip],
+ (unsigned long long) NoSantizeSubUInt64(tif->tif_size, TIFFGetStrileOffset(tif,
strip)),
(unsigned long long) bytecount);
#endif
tif->tif_curstrip = NOSTRIP;
@@ -881,7 +878,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
}
tif->tif_flags &= ~TIFF_MYBUFFER;
tif->tif_rawdatasize = (tmsize_t)bytecount;
- tif->tif_rawdata = tif->tif_base + (tmsize_t)td->td_stripoffset[strip];
+ tif->tif_rawdata = tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, strip);
tif->tif_rawdataoff = 0;
tif->tif_rawdataloaded = (tmsize_t) bytecount;
@@ -1096,16 +1093,11 @@ _TIFFReadEncodedTileAndAllocBuffer(TIFF* tif, uint32 tile,
static tmsize_t
TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* module)
{
- TIFFDirectory *td = &tif->tif_dir;
-
- if (!_TIFFFillStriles( tif ))
- return ((tmsize_t)(-1));
-
assert((tif->tif_flags&TIFF_NOREADRAW)==0);
if (!isMapped(tif)) {
tmsize_t cc;
- if (!SeekOK(tif, td->td_stripoffset[tile])) {
+ if (!SeekOK(tif, TIFFGetStrileOffset(tif, tile))) {
TIFFErrorExt(tif->tif_clientdata, module,
"Seek error at row %lu, col %lu, tile %lu",
(unsigned long) tif->tif_row,
@@ -1135,9 +1127,9 @@ TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size,
const char* m
} else {
tmsize_t ma,mb;
tmsize_t n;
- ma=(tmsize_t)td->td_stripoffset[tile];
+ ma=(tmsize_t)TIFFGetStrileOffset(tif, tile);
mb=ma+size;
- if ((td->td_stripoffset[tile] >
(uint64)TIFF_TMSIZE_T_MAX)||(ma>tif->tif_size))
+ if ((TIFFGetStrileOffset(tif, tile) >
(uint64)TIFF_TMSIZE_T_MAX)||(ma>tif->tif_size))
n=0;
else if ((mb<ma)||(mb<size)||(mb>tif->tif_size))
n=tif->tif_size-ma;
@@ -1193,13 +1185,12 @@ TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size)
"Compression scheme does not support access to raw uncompressed data");
return ((tmsize_t)(-1));
}
- bytecount64 = td->td_stripbytecount[tile];
- if (size != (tmsize_t)(-1) && (uint64)size < bytecount64)
- bytecount64 = (uint64)size;
- bytecountm = (tmsize_t)bytecount64;
- if ((uint64)bytecountm!=bytecount64)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
+ bytecount64 = TIFFGetStrileByteCount(tif, tile);
+ if (size != (tmsize_t)(-1) && (uint64)size <= bytecount64)
+ bytecountm = size;
+ else
+ bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module);
+ if( bytecountm == 0 ) {
return ((tmsize_t)(-1));
}
return (TIFFReadRawTile1(tif, tile, buf, bytecountm, module));
@@ -1215,13 +1206,10 @@ TIFFFillTile(TIFF* tif, uint32 tile)
static const char module[] = "TIFFFillTile";
TIFFDirectory *td = &tif->tif_dir;
- if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
- return 0;
-
if ((tif->tif_flags&TIFF_NOREADRAW)==0)
{
- uint64 bytecount = td->td_stripbytecount[tile];
- if ((int64)bytecount <= 0) {
+ uint64 bytecount = TIFFGetStrileByteCount(tif, tile);
+ if( bytecount == 0 || bytecount > (uint64)TIFF_INT64_MAX ) {
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFErrorExt(tif->tif_clientdata, module,
"%I64u: Invalid tile byte count, tile %lu",
@@ -1248,7 +1236,7 @@ TIFFFillTile(TIFF* tif, uint32 tile)
(bytecount - 4096) / 10 > (uint64)stripsize )
{
uint64 newbytecount = (uint64)stripsize * 10 + 4096;
- if( (int64)newbytecount >= 0 )
+ if( newbytecount == 0 || newbytecount > (uint64)TIFF_INT64_MAX )
{
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFWarningExt(tif->tif_clientdata, module,
@@ -1273,13 +1261,13 @@ TIFFFillTile(TIFF* tif, uint32 tile)
* We must check for overflow, potentially causing
* an OOB read. Instead of simple
*
- * td->td_stripoffset[tile]+bytecount > tif->tif_size
+ * TIFFGetStrileOffset(tif, tile)+bytecount > tif->tif_size
*
* comparison (which can overflow) we do the following
* two comparisons:
*/
if (bytecount > (uint64)tif->tif_size ||
- td->td_stripoffset[tile] > (uint64)tif->tif_size - bytecount) {
+ TIFFGetStrileOffset(tif, tile) > (uint64)tif->tif_size - bytecount) {
tif->tif_curtile = NOTILE;
return (0);
}
@@ -1308,7 +1296,7 @@ TIFFFillTile(TIFF* tif, uint32 tile)
tif->tif_rawdatasize = (tmsize_t)bytecount;
tif->tif_rawdata =
- tif->tif_base + (tmsize_t)td->td_stripoffset[tile];
+ tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, tile);
tif->tif_rawdataoff = 0;
tif->tif_rawdataloaded = (tmsize_t) bytecount;
tif->tif_flags |= TIFF_BUFFERMMAP;
@@ -1367,7 +1355,8 @@ TIFFFillTile(TIFF* tif, uint32 tile)
tif->tif_rawdataoff = 0;
tif->tif_rawdataloaded = bytecountm;
- if (!isFillOrder(tif, td->td_fillorder) &&
+ if (tif->tif_rawdata != NULL &&
+ !isFillOrder(tif, td->td_fillorder) &&
(tif->tif_flags & TIFF_NOBITREV) == 0)
TIFFReverseBits(tif->tif_rawdata,
tif->tif_rawdataloaded);
@@ -1434,9 +1423,6 @@ TIFFStartStrip(TIFF* tif, uint32 strip)
{
TIFFDirectory *td = &tif->tif_dir;
- if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
- return 0;
-
if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
if (!(*tif->tif_setupdecode)(tif))
return (0);
@@ -1457,7 +1443,7 @@ TIFFStartStrip(TIFF* tif, uint32 strip)
if( tif->tif_rawdataloaded > 0 )
tif->tif_rawcc = tif->tif_rawdataloaded;
else
- tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[strip];
+ tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, strip);
}
return ((*tif->tif_predecode)(tif,
(uint16)(strip / td->td_stripsperimage)));
@@ -1474,9 +1460,6 @@ TIFFStartTile(TIFF* tif, uint32 tile)
TIFFDirectory *td = &tif->tif_dir;
uint32 howmany32;
- if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
- return 0;
-
if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
if (!(*tif->tif_setupdecode)(tif))
return (0);
@@ -1507,7 +1490,7 @@ TIFFStartTile(TIFF* tif, uint32 tile)
if( tif->tif_rawdataloaded > 0 )
tif->tif_rawcc = tif->tif_rawdataloaded;
else
- tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[tile];
+ tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, tile);
}
return ((*tif->tif_predecode)(tif,
(uint16)(tile/td->td_stripsperimage)));
@@ -1522,13 +1505,100 @@ TIFFCheckRead(TIFF* tif, int tiles)
}
if (tiles ^ isTiled(tif)) {
TIFFErrorExt(tif->tif_clientdata, tif->tif_name, tiles ?
- "Can not read tiles from a stripped image" :
+ "Can not read tiles from a striped image" :
"Can not read scanlines from a tiled image");
return (0);
}
return (1);
}
+/* Use the provided input buffer (inbuf, insize) and decompress it into
+ * (outbuf, outsize).
+ * This function replaces the use of TIFFReadEncodedStrip()/TIFFReadEncodedTile()
+ * when the user can provide the buffer for the input data, for example when
+ * he wants to avoid libtiff to read the strile offset/count values from the
+ * [Strip|Tile][Offsets/ByteCounts] array.
+ * inbuf content must be writable (if bit reversal is needed)
+ * Returns 1 in case of success, 0 otherwise.
+ */
+int TIFFReadFromUserBuffer(TIFF* tif, uint32 strile,
+ void* inbuf, tmsize_t insize,
+ void* outbuf, tmsize_t outsize)
+{
+ static const char module[] = "TIFFReadFromUserBuffer";
+ TIFFDirectory *td = &tif->tif_dir;
+ int ret = 1;
+ uint32 old_tif_flags = tif->tif_flags;
+ tmsize_t old_rawdatasize = tif->tif_rawdatasize;
+ void* old_rawdata = tif->tif_rawdata;
+
+ if (tif->tif_mode == O_WRONLY) {
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "File not open for
reading");
+ return 0;
+ }
+ if (tif->tif_flags&TIFF_NOREADRAW)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Compression scheme does not support access to raw uncompressed
data");
+ return 0;
+ }
+
+ tif->tif_flags &= ~TIFF_MYBUFFER;
+ tif->tif_flags |= TIFF_BUFFERMMAP;
+ tif->tif_rawdatasize = insize;
+ tif->tif_rawdata = inbuf;
+ tif->tif_rawdataoff = 0;
+ tif->tif_rawdataloaded = insize;
+
+ if (!isFillOrder(tif, td->td_fillorder) &&
+ (tif->tif_flags & TIFF_NOBITREV) == 0)
+ {
+ TIFFReverseBits(inbuf, insize);
+ }
+
+ if( TIFFIsTiled(tif) )
+ {
+ if( !TIFFStartTile(tif, strile) ||
+ !(*tif->tif_decodetile)(tif, (uint8*) outbuf, outsize,
+ (uint16)(strile/td->td_stripsperimage)) )
+ {
+ ret = 0;
+ }
+ }
+ else
+ {
+ uint32 rowsperstrip=td->td_rowsperstrip;
+ uint32 stripsperplane;
+ if (rowsperstrip>td->td_imagelength)
+ rowsperstrip=td->td_imagelength;
+ stripsperplane= TIFFhowmany_32_maxuint_compat(td->td_imagelength,
rowsperstrip);
+ if( !TIFFStartStrip(tif, strile) ||
+ !(*tif->tif_decodestrip)(tif, (uint8*) outbuf, outsize,
+ (uint16)(strile/stripsperplane)) )
+ {
+ ret = 0;
+ }
+ }
+ if( ret )
+ {
+ (*tif->tif_postdecode)(tif, (uint8*) outbuf, outsize);
+ }
+
+ if (!isFillOrder(tif, td->td_fillorder) &&
+ (tif->tif_flags & TIFF_NOBITREV) == 0)
+ {
+ TIFFReverseBits(inbuf, insize);
+ }
+
+ tif->tif_flags = old_tif_flags;
+ tif->tif_rawdatasize = old_rawdatasize;
+ tif->tif_rawdata = old_rawdata;
+ tif->tif_rawdataoff = 0;
+ tif->tif_rawdataloaded = 0;
+
+ return ret;
+}
+
void
_TIFFNoPostDecode(TIFF* tif, uint8* buf, tmsize_t cc)
{
diff --git a/dll/3rdparty/libtiff/tif_strip.c b/dll/3rdparty/libtiff/tif_strip.c
index d468714a48a..0e4ed85872d 100644
--- a/dll/3rdparty/libtiff/tif_strip.c
+++ b/dll/3rdparty/libtiff/tif_strip.c
@@ -27,7 +27,6 @@
*
* Strip-organized Image Support Routines.
*/
-
#include <precomp.h>
/*
@@ -130,15 +129,8 @@ TIFFVStripSize(TIFF* tif, uint32 nrows)
{
static const char module[] = "TIFFVStripSize";
uint64 m;
- tmsize_t n;
m=TIFFVStripSize64(tif,nrows);
- n=(tmsize_t)m;
- if ((uint64)n!=m)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
- n=0;
- }
- return(n);
+ return _TIFFCastUInt64ToSSize(tif, m, module);
}
/*
@@ -148,8 +140,7 @@ uint64
TIFFRawStripSize64(TIFF* tif, uint32 strip)
{
static const char module[] = "TIFFRawStripSize64";
- TIFFDirectory* td = &tif->tif_dir;
- uint64 bytecount = td->td_stripbytecount[strip];
+ uint64 bytecount = TIFFGetStrileByteCount(tif, strip);
if (bytecount == 0)
{
@@ -212,15 +203,8 @@ TIFFStripSize(TIFF* tif)
{
static const char module[] = "TIFFStripSize";
uint64 m;
- tmsize_t n;
m=TIFFStripSize64(tif);
- n=(tmsize_t)m;
- if ((uint64)n!=m)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
- n=0;
- }
- return(n);
+ return _TIFFCastUInt64ToSSize(tif, m, module);
}
/*
@@ -331,14 +315,8 @@ TIFFScanlineSize(TIFF* tif)
{
static const char module[] = "TIFFScanlineSize";
uint64 m;
- tmsize_t n;
m=TIFFScanlineSize64(tif);
- n=(tmsize_t)m;
- if ((uint64)n!=m) {
- TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow");
- n=0;
- }
- return(n);
+ return _TIFFCastUInt64ToSSize(tif, m, module);
}
/*
@@ -367,15 +345,8 @@ TIFFRasterScanlineSize(TIFF* tif)
{
static const char module[] = "TIFFRasterScanlineSize";
uint64 m;
- tmsize_t n;
m=TIFFRasterScanlineSize64(tif);
- n=(tmsize_t)m;
- if ((uint64)n!=m)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow");
- n=0;
- }
- return(n);
+ return _TIFFCastUInt64ToSSize(tif, m, module);
}
/* vim: set ts=8 sts=8 sw=8 noet: */
diff --git a/dll/3rdparty/libtiff/tif_thunder.c b/dll/3rdparty/libtiff/tif_thunder.c
index cec87703227..08a2d2bbbaf 100644
--- a/dll/3rdparty/libtiff/tif_thunder.c
+++ b/dll/3rdparty/libtiff/tif_thunder.c
@@ -123,17 +123,17 @@ ThunderDecode(TIFF* tif, uint8* op, tmsize_t maxpixels)
break;
case THUNDER_2BITDELTAS: /* 2-bit deltas */
if ((delta = ((n >> 4) & 3)) != DELTA2_SKIP)
- SETPIXEL(op, lastpixel + twobitdeltas[delta]);
+ SETPIXEL(op, (unsigned)((int)lastpixel + twobitdeltas[delta]));
if ((delta = ((n >> 2) & 3)) != DELTA2_SKIP)
- SETPIXEL(op, lastpixel + twobitdeltas[delta]);
+ SETPIXEL(op, (unsigned)((int)lastpixel + twobitdeltas[delta]));
if ((delta = (n & 3)) != DELTA2_SKIP)
- SETPIXEL(op, lastpixel + twobitdeltas[delta]);
+ SETPIXEL(op, (unsigned)((int)lastpixel + twobitdeltas[delta]));
break;
case THUNDER_3BITDELTAS: /* 3-bit deltas */
if ((delta = ((n >> 3) & 7)) != DELTA3_SKIP)
- SETPIXEL(op, lastpixel + threebitdeltas[delta]);
+ SETPIXEL(op, (unsigned)((int)lastpixel + threebitdeltas[delta]));
if ((delta = (n & 7)) != DELTA3_SKIP)
- SETPIXEL(op, lastpixel + threebitdeltas[delta]);
+ SETPIXEL(op, (unsigned)((int)lastpixel + threebitdeltas[delta]));
break;
case THUNDER_RAW: /* raw data */
SETPIXEL(op, n);
diff --git a/dll/3rdparty/libtiff/tif_tile.c b/dll/3rdparty/libtiff/tif_tile.c
index 36a0000dbbb..77126af759f 100644
--- a/dll/3rdparty/libtiff/tif_tile.c
+++ b/dll/3rdparty/libtiff/tif_tile.c
@@ -27,7 +27,6 @@
*
* Tiled Image Support Routines.
*/
-
#include <precomp.h>
/*
@@ -182,15 +181,8 @@ TIFFTileRowSize(TIFF* tif)
{
static const char module[] = "TIFFTileRowSize";
uint64 m;
- tmsize_t n;
m=TIFFTileRowSize64(tif);
- n=(tmsize_t)m;
- if ((uint64)n!=m)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
- n=0;
- }
- return(n);
+ return _TIFFCastUInt64ToSSize(tif, m, module);
}
/*
@@ -249,15 +241,8 @@ TIFFVTileSize(TIFF* tif, uint32 nrows)
{
static const char module[] = "TIFFVTileSize";
uint64 m;
- tmsize_t n;
m=TIFFVTileSize64(tif,nrows);
- n=(tmsize_t)m;
- if ((uint64)n!=m)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
- n=0;
- }
- return(n);
+ return _TIFFCastUInt64ToSSize(tif, m, module);
}
/*
@@ -273,15 +258,8 @@ TIFFTileSize(TIFF* tif)
{
static const char module[] = "TIFFTileSize";
uint64 m;
- tmsize_t n;
m=TIFFTileSize64(tif);
- n=(tmsize_t)m;
- if ((uint64)n!=m)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
- n=0;
- }
- return(n);
+ return _TIFFCastUInt64ToSSize(tif, m, module);
}
/*
diff --git a/dll/3rdparty/libtiff/tif_version.c b/dll/3rdparty/libtiff/tif_version.c
index 0139cdb4e9b..f0ccf27e4c2 100644
--- a/dll/3rdparty/libtiff/tif_version.c
+++ b/dll/3rdparty/libtiff/tif_version.c
@@ -21,7 +21,6 @@
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
-
#include <precomp.h>
static const char TIFFVersion[] = TIFFLIB_VERSION_STR;
diff --git a/dll/3rdparty/libtiff/tif_webp.c b/dll/3rdparty/libtiff/tif_webp.c
index a002f481daa..22665f2d2b9 100644
--- a/dll/3rdparty/libtiff/tif_webp.c
+++ b/dll/3rdparty/libtiff/tif_webp.c
@@ -349,6 +349,12 @@ TWebPSetupEncode(TIFF* tif)
sp->state |= LSTATE_INIT_ENCODE;
+ if (!WebPPictureInit(&sp->sPicture)) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Error initializing WebP picture.");
+ return 0;
+ }
+
if (!WebPConfigInitInternal(&sp->sEncoderConfig, WEBP_PRESET_DEFAULT,
sp->quality_level,
WEBP_ENCODER_ABI_VERSION)) {
@@ -357,9 +363,13 @@ TWebPSetupEncode(TIFF* tif)
return 0;
}
-#if WEBP_ENCODER_ABI_VERSION >= 0x0100
- sp->sEncoderConfig.lossless = sp->lossless;
-#endif
+ // WebPConfigInitInternal above sets lossless to false
+ #if WEBP_ENCODER_ABI_VERSION >= 0x0100
+ sp->sEncoderConfig.lossless = sp->lossless;
+ if (sp->lossless) {
+ sp->sPicture.use_argb = 1;
+ }
+ #endif
if (!WebPValidateConfig(&sp->sEncoderConfig)) {
TIFFErrorExt(tif->tif_clientdata, module,
@@ -367,12 +377,6 @@ TWebPSetupEncode(TIFF* tif)
return 0;
}
- if (!WebPPictureInit(&sp->sPicture)) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Error initializing WebP picture.");
- return 0;
- }
-
return 1;
}
@@ -415,6 +419,12 @@ TWebPPreEncode(TIFF* tif, uint16 s)
/* set up buffer for raw data */
/* given above check and that nSamples <= 4, buffer_size is <= 1 GB */
sp->buffer_size = segment_width * segment_height * sp->nSamples;
+
+ if (sp->pBuffer != NULL) {
+ _TIFFfree(sp->pBuffer);
+ sp->pBuffer = NULL;
+ }
+
sp->pBuffer = _TIFFmalloc(sp->buffer_size);
if( !sp->pBuffer) {
TIFFErrorExt(tif->tif_clientdata, module, "Cannot allocate buffer");
@@ -460,7 +470,7 @@ TWebPPostEncode(TIFF* tif)
"WebPPictureImportRGB() failed");
return 0;
}
-
+
if (!WebPEncode(&sp->sEncoderConfig, &sp->sPicture)) {
#if WEBP_ENCODER_ABI_VERSION >= 0x0100
@@ -540,15 +550,13 @@ TWebPCleanup(TIFF* tif)
}
if (sp->pBuffer != NULL) {
- _TIFFfree(sp->pBuffer);
- sp->pBuffer = NULL;
+ _TIFFfree(sp->pBuffer);
+ sp->pBuffer = NULL;
}
- if (tif->tif_data) {
- _TIFFfree(tif->tif_data);
- tif->tif_data = NULL;
- }
-
+ _TIFFfree(tif->tif_data);
+ tif->tif_data = NULL;
+
_TIFFSetDefaultCompressionState(tif);
}
@@ -570,6 +578,9 @@ TWebPVSetField(TIFF* tif, uint32 tag, va_list ap)
case TIFFTAG_WEBP_LOSSLESS:
#if WEBP_ENCODER_ABI_VERSION >= 0x0100
sp->lossless = va_arg(ap, int);
+ if (sp->lossless){
+ sp->quality_level = 100.0f;
+ }
return 1;
#else
TIFFErrorExt(tif->tif_clientdata, module,
diff --git a/dll/3rdparty/libtiff/tif_write.c b/dll/3rdparty/libtiff/tif_write.c
index 32603fe5636..7b5a01174c5 100644
--- a/dll/3rdparty/libtiff/tif_write.c
+++ b/dll/3rdparty/libtiff/tif_write.c
@@ -27,7 +27,6 @@
*
* Scanline-oriented Write Support
*/
-
#include <precomp.h>
//#include <stdio.h>
@@ -129,10 +128,10 @@ TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata;
- if( td->td_stripbytecount[strip] > 0 )
+ if( td->td_stripbytecount_p[strip] > 0 )
{
/* if we are writing over existing tiles, zero length */
- td->td_stripbytecount[strip] = 0;
+ td->td_stripbytecount_p[strip] = 0;
/* this forces TIFFAppendToStrip() to do a seek */
tif->tif_curoff = 0;
@@ -177,6 +176,32 @@ TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
return (status);
}
+/* Make sure that at the first attempt of rewriting a tile/strip, we will have */
+/* more bytes available in the output buffer than the previous byte count, */
+/* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
+/* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
+static int _TIFFReserveLargeEnoughWriteBuffer(TIFF* tif, uint32 strip_or_tile)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ if( td->td_stripbytecount_p[strip_or_tile] > 0 )
+ {
+ /* The +1 is to ensure at least one extra bytes */
+ /* The +4 is because the LZW encoder flushes 4 bytes before the limit */
+ uint64 safe_buffer_size = (uint64)(td->td_stripbytecount_p[strip_or_tile] + 1
+ 4);
+ if( tif->tif_rawdatasize <= (tmsize_t)safe_buffer_size )
+ {
+ if( !(TIFFWriteBufferSetup(tif, NULL,
+ (tmsize_t)TIFFroundup_64(safe_buffer_size, 1024))) )
+ return 0;
+ }
+
+ /* Force TIFFAppendToStrip() to consider placing data at end
+ of file. */
+ tif->tif_curoff = 0;
+ }
+ return 1;
+}
+
/*
* Encode the supplied data and write it to the
* specified strip.
@@ -223,6 +248,13 @@ TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t
cc)
tif->tif_flags |= TIFF_BUF4WRITE;
tif->tif_curstrip = strip;
+ if( !_TIFFReserveLargeEnoughWriteBuffer(tif, strip) ) {
+ return ((tmsize_t)(-1));
+ }
+
+ tif->tif_rawcc = 0;
+ tif->tif_rawcp = tif->tif_rawdata;
+
if (td->td_stripsperimage == 0) {
TIFFErrorExt(tif->tif_clientdata, module, "Zero strips per
image");
return ((tmsize_t) -1);
@@ -235,27 +267,6 @@ TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t
cc)
tif->tif_flags |= TIFF_CODERSETUP;
}
- if( td->td_stripbytecount[strip] > 0 )
- {
- /* Make sure that at the first attempt of rewriting the tile, we will have
*/
- /* more bytes available in the output buffer than the previous byte count,
*/
- /* so that TIFFAppendToStrip() will detect the overflow when it is called the
first */
- /* time if the new compressed tile is bigger than the older one. (GDAL #4771)
*/
- if( tif->tif_rawdatasize <= (tmsize_t)td->td_stripbytecount[strip]
)
- {
- if( !(TIFFWriteBufferSetup(tif, NULL,
- (tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[strip] +
1), 1024))) )
- return ((tmsize_t)(-1));
- }
-
- /* Force TIFFAppendToStrip() to consider placing data at end
- of file. */
- tif->tif_curoff = 0;
- }
-
- tif->tif_rawcc = 0;
- tif->tif_rawcp = tif->tif_rawdata;
-
tif->tif_flags &= ~TIFF_POSTENCODE;
/* shortcut to avoid an extra memcpy() */
@@ -403,22 +414,8 @@ TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t
cc)
tif->tif_flags |= TIFF_BUF4WRITE;
tif->tif_curtile = tile;
- if( td->td_stripbytecount[tile] > 0 )
- {
- /* Make sure that at the first attempt of rewriting the tile, we will have
*/
- /* more bytes available in the output buffer than the previous byte count,
*/
- /* so that TIFFAppendToStrip() will detect the overflow when it is called the
first */
- /* time if the new compressed tile is bigger than the older one. (GDAL #4771)
*/
- if( tif->tif_rawdatasize <= (tmsize_t) td->td_stripbytecount[tile]
)
- {
- if( !(TIFFWriteBufferSetup(tif, NULL,
- (tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[tile] +
1), 1024))) )
- return ((tmsize_t)(-1));
- }
-
- /* Force TIFFAppendToStrip() to consider placing data at end
- of file. */
- tif->tif_curoff = 0;
+ if( !_TIFFReserveLargeEnoughWriteBuffer(tif, tile) ) {
+ return ((tmsize_t)(-1));
}
tif->tif_rawcc = 0;
@@ -538,20 +535,20 @@ TIFFSetupStrips(TIFF* tif)
td->td_nstrips = td->td_stripsperimage;
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
td->td_stripsperimage /= td->td_samplesperpixel;
- td->td_stripoffset = (uint64 *)
+ td->td_stripoffset_p = (uint64 *)
_TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64),
"for \"StripOffsets\" array");
- td->td_stripbytecount = (uint64 *)
+ td->td_stripbytecount_p = (uint64 *)
_TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64),
"for \"StripByteCounts\" array");
- if (td->td_stripoffset == NULL || td->td_stripbytecount == NULL)
+ if (td->td_stripoffset_p == NULL || td->td_stripbytecount_p == NULL)
return (0);
/*
* Place data at the end-of-file
* (by setting offsets to zero).
*/
- _TIFFmemset(td->td_stripoffset, 0, td->td_nstrips*sizeof (uint64));
- _TIFFmemset(td->td_stripbytecount, 0, td->td_nstrips*sizeof (uint64));
+ _TIFFmemset(td->td_stripoffset_p, 0, td->td_nstrips*sizeof (uint64));
+ _TIFFmemset(td->td_stripbytecount_p, 0, td->td_nstrips*sizeof (uint64));
TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
return (1);
@@ -573,7 +570,7 @@ TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
}
if (tiles ^ isTiled(tif)) {
TIFFErrorExt(tif->tif_clientdata, module, tiles ?
- "Can not write tiles to a stripped image" :
+ "Can not write tiles to a striped image" :
"Can not write scanlines to a tiled image");
return (0);
}
@@ -611,7 +608,7 @@ TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
return (0);
}
}
- if (tif->tif_dir.td_stripoffset == NULL && !TIFFSetupStrips(tif)) {
+ if (tif->tif_dir.td_stripoffset_p == NULL && !TIFFSetupStrips(tif)) {
tif->tif_dir.td_nstrips = 0;
TIFFErrorExt(tif->tif_clientdata, module, "No space for %s arrays",
isTiled(tif) ? "tile" : "strip");
@@ -629,6 +626,20 @@ TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
if (tif->tif_scanlinesize == 0)
return (0);
tif->tif_flags |= TIFF_BEENWRITING;
+
+ if( tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0
&&
+ !(tif->tif_flags & TIFF_DIRTYDIRECT) )
+ {
+ TIFFForceStrileArrayWriting(tif);
+ }
+
return (1);
}
@@ -685,9 +696,9 @@ TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module)
uint64* new_stripbytecount;
assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
- new_stripoffset = (uint64*)_TIFFrealloc(td->td_stripoffset,
+ new_stripoffset = (uint64*)_TIFFrealloc(td->td_stripoffset_p,
(td->td_nstrips + delta) * sizeof (uint64));
- new_stripbytecount = (uint64*)_TIFFrealloc(td->td_stripbytecount,
+ new_stripbytecount = (uint64*)_TIFFrealloc(td->td_stripbytecount_p,
(td->td_nstrips + delta) * sizeof (uint64));
if (new_stripoffset == NULL || new_stripbytecount == NULL) {
if (new_stripoffset)
@@ -698,11 +709,11 @@ TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module)
TIFFErrorExt(tif->tif_clientdata, module, "No space to expand strip
arrays");
return (0);
}
- td->td_stripoffset = new_stripoffset;
- td->td_stripbytecount = new_stripbytecount;
- _TIFFmemset(td->td_stripoffset + td->td_nstrips,
+ td->td_stripoffset_p = new_stripoffset;
+ td->td_stripbytecount_p = new_stripbytecount;
+ _TIFFmemset(td->td_stripoffset_p + td->td_nstrips,
0, delta*sizeof (uint64));
- _TIFFmemset(td->td_stripbytecount + td->td_nstrips,
+ _TIFFmemset(td->td_stripbytecount_p + td->td_nstrips,
0, delta*sizeof (uint64));
td->td_nstrips += delta;
tif->tif_flags |= TIFF_DIRTYDIRECT;
@@ -721,12 +732,12 @@ TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t
cc)
uint64 m;
int64 old_byte_count = -1;
- if (td->td_stripoffset[strip] == 0 || tif->tif_curoff == 0) {
+ if (td->td_stripoffset_p[strip] == 0 || tif->tif_curoff == 0) {
assert(td->td_nstrips > 0);
- if( td->td_stripbytecount[strip] != 0
- && td->td_stripoffset[strip] != 0
- && td->td_stripbytecount[strip] >= (uint64) cc )
+ if( td->td_stripbytecount_p[strip] != 0
+ && td->td_stripoffset_p[strip] != 0
+ && td->td_stripbytecount_p[strip] >= (uint64) cc )
{
/*
* There is already tile data on disk, and the new tile
@@ -735,7 +746,7 @@ TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc)
* more data to append to this strip before we are done
* depending on how we are getting called.
*/
- if (!SeekOK(tif, td->td_stripoffset[strip])) {
+ if (!SeekOK(tif, td->td_stripoffset_p[strip])) {
TIFFErrorExt(tif->tif_clientdata, module,
"Seek error at scanline %lu",
(unsigned long)tif->tif_row);
@@ -748,17 +759,17 @@ TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t
cc)
* Seek to end of file, and set that as our location to
* write this strip.
*/
- td->td_stripoffset[strip] = TIFFSeekFile(tif, 0, SEEK_END);
+ td->td_stripoffset_p[strip] = TIFFSeekFile(tif, 0, SEEK_END);
tif->tif_flags |= TIFF_DIRTYSTRIP;
}
- tif->tif_curoff = td->td_stripoffset[strip];
+ tif->tif_curoff = td->td_stripoffset_p[strip];
/*
* We are starting a fresh strip/tile, so set the size to zero.
*/
- old_byte_count = td->td_stripbytecount[strip];
- td->td_stripbytecount[strip] = 0;
+ old_byte_count = td->td_stripbytecount_p[strip];
+ td->td_stripbytecount_p[strip] = 0;
}
m = tif->tif_curoff+cc;
@@ -775,9 +786,9 @@ TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc)
return (0);
}
tif->tif_curoff = m;
- td->td_stripbytecount[strip] += cc;
+ td->td_stripbytecount_p[strip] += cc;
- if( (int64) td->td_stripbytecount[strip] != old_byte_count )
+ if( (int64) td->td_stripbytecount_p[strip] != old_byte_count )
tif->tif_flags |= TIFF_DIRTYSTRIP;
return (1);
diff --git a/dll/3rdparty/libtiff/tif_zip.c b/dll/3rdparty/libtiff/tif_zip.c
index 6dc64b2d034..c30aefd049d 100644
--- a/dll/3rdparty/libtiff/tif_zip.c
+++ b/dll/3rdparty/libtiff/tif_zip.c
@@ -23,7 +23,6 @@
*/
#include <precomp.h>
-
#ifdef ZIP_SUPPORT
/*
* TIFF Library.
@@ -48,7 +47,7 @@
#include "tif_predict.h"
#include "zlib.h"
-//#include <stdio.h>
+#include <stdio.h>
/*
* Sigh, ZLIB_VERSION is defined as a string so there's no
@@ -125,7 +124,6 @@ ZIPSetupDecode(TIFF* tif)
static int
ZIPPreDecode(TIFF* tif, uint16 s)
{
- static const char module[] = "ZIPPreDecode";
ZIPState* sp = DecoderState(tif);
(void) s;
@@ -139,12 +137,7 @@ ZIPPreDecode(TIFF* tif, uint16 s)
we need to simplify this code to reflect a ZLib that is likely updated
to deal with 8byte memory sizes, though this code will respond
appropriately even before we simplify it */
- sp->stream.avail_in = (uInt) tif->tif_rawcc;
- if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc)
- {
- TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this
size");
- return (0);
- }
+ sp->stream.avail_in = (uint64)tif->tif_rawcc < 0xFFFFFFFFU ? (uInt)
tif->tif_rawcc : 0xFFFFFFFFU;
return (inflateReset(&sp->stream) == Z_OK);
}
@@ -159,46 +152,43 @@ ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
assert(sp->state == ZSTATE_INIT_DECODE);
sp->stream.next_in = tif->tif_rawcp;
- sp->stream.avail_in = (uInt) tif->tif_rawcc;
sp->stream.next_out = op;
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
to deal with 8byte memory sizes, though this code will respond
appropriately even before we simplify it */
- sp->stream.avail_out = (uInt) occ;
- if ((tmsize_t)sp->stream.avail_out != occ)
- {
- TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this
size");
- return (0);
- }
do {
- int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
+ int state;
+ uInt avail_in_before = (uint64)tif->tif_rawcc <= 0xFFFFFFFFU ?
(uInt)tif->tif_rawcc : 0xFFFFFFFFU;
+ uInt avail_out_before = (uint64)occ < 0xFFFFFFFFU ? (uInt) occ :
0xFFFFFFFFU;
+ sp->stream.avail_in = avail_in_before;
+ sp->stream.avail_out = avail_out_before;
+ state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
+ tif->tif_rawcc -= (avail_in_before - sp->stream.avail_in);
+ occ -= (avail_out_before - sp->stream.avail_out);
if (state == Z_STREAM_END)
break;
if (state == Z_DATA_ERROR) {
TIFFErrorExt(tif->tif_clientdata, module,
"Decoding error at scanline %lu, %s",
(unsigned long) tif->tif_row, SAFE_MSG(sp));
- if (inflateSync(&sp->stream) != Z_OK)
- return (0);
- continue;
+ return (0);
}
if (state != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module,
"ZLib error: %s", SAFE_MSG(sp));
return (0);
}
- } while (sp->stream.avail_out > 0);
- if (sp->stream.avail_out != 0) {
+ } while (occ > 0);
+ if (occ != 0) {
TIFFErrorExt(tif->tif_clientdata, module,
"Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT "
bytes)",
- (unsigned long) tif->tif_row, (TIFF_UINT64_T) sp->stream.avail_out);
+ (unsigned long) tif->tif_row, (TIFF_UINT64_T) occ);
return (0);
}
tif->tif_rawcp = sp->stream.next_in;
- tif->tif_rawcc = sp->stream.avail_in;
return (1);
}
@@ -230,7 +220,6 @@ ZIPSetupEncode(TIFF* tif)
static int
ZIPPreEncode(TIFF* tif, uint16 s)
{
- static const char module[] = "ZIPPreEncode";
ZIPState *sp = EncoderState(tif);
(void) s;
@@ -243,12 +232,7 @@ ZIPPreEncode(TIFF* tif, uint16 s)
we need to simplify this code to reflect a ZLib that is likely updated
to deal with 8byte memory sizes, though this code will respond
appropriately even before we simplify it */
- sp->stream.avail_out = (uInt)tif->tif_rawdatasize;
- if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
- {
- TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this
size");
- return (0);
- }
+ sp->stream.avail_out = (uint64)tif->tif_rawdatasize <= 0xFFFFFFFFU ?
(uInt)tif->tif_rawdatasize : 0xFFFFFFFFU;
return (deflateReset(&sp->stream) == Z_OK);
}
@@ -270,13 +254,9 @@ ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
we need to simplify this code to reflect a ZLib that is likely updated
to deal with 8byte memory sizes, though this code will respond
appropriately even before we simplify it */
- sp->stream.avail_in = (uInt) cc;
- if ((tmsize_t)sp->stream.avail_in != cc)
- {
- TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this
size");
- return (0);
- }
do {
+ uInt avail_in_before = (uint64)cc <= 0xFFFFFFFFU ? (uInt)cc :
0xFFFFFFFFU;
+ sp->stream.avail_in = avail_in_before;
if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module,
"Encoder error: %s",
@@ -287,9 +267,10 @@ ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
tif->tif_rawcc = tif->tif_rawdatasize;
TIFFFlushData1(tif);
sp->stream.next_out = tif->tif_rawdata;
- sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast,
as check is made already in ZIPPreEncode */
+ sp->stream.avail_out = (uint64)tif->tif_rawdatasize <= 0xFFFFFFFFU ?
(uInt)tif->tif_rawdatasize : 0xFFFFFFFFU;
}
- } while (sp->stream.avail_in > 0);
+ cc -= (avail_in_before - sp->stream.avail_in);
+ } while (cc > 0);
return (1);
}
@@ -315,7 +296,7 @@ ZIPPostEncode(TIFF* tif)
tif->tif_rawcc = tif->tif_rawdatasize - sp->stream.avail_out;
TIFFFlushData1(tif);
sp->stream.next_out = tif->tif_rawdata;
- sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe
typecast, as check is made already in ZIPPreEncode */
+ sp->stream.avail_out = (uint64)tif->tif_rawdatasize <= 0xFFFFFFFFU ?
(uInt)tif->tif_rawdatasize : 0xFFFFFFFFU;
}
break;
default:
diff --git a/media/doc/3rd Party Files.txt b/media/doc/3rd Party Files.txt
index 7863c686f99..c9c06ee34a9 100644
--- a/media/doc/3rd Party Files.txt
+++ b/media/doc/3rd Party Files.txt
@@ -79,7 +79,7 @@ Used Version: 9c
Website:
http://www.ijg.org/
Title: libtiff
-Used Version: 4.0.10
+Used Version: 4.1.0
Website:
http://www.simplesystems.org/libtiff/
Title: mbed TLS
diff --git a/sdk/include/reactos/libs/libtiff/tif_dir.h
b/sdk/include/reactos/libs/libtiff/tif_dir.h
index b2f5e694883..e7f06673c2c 100644
--- a/sdk/include/reactos/libs/libtiff/tif_dir.h
+++ b/sdk/include/reactos/libs/libtiff/tif_dir.h
@@ -58,6 +58,7 @@ typedef struct {
uint32 toff_long;
uint64 toff_long8;
} tdir_offset; /* either offset or the data itself if fits */
+ uint8 tdir_ignore; /* flag status to ignore tag when parsing tags in tif_dirread.c */
} TIFFDirEntry;
/*
@@ -97,13 +98,14 @@ typedef struct {
* number of striles */
uint32 td_stripsperimage;
uint32 td_nstrips; /* size of offset & bytecount arrays */
- uint64* td_stripoffset;
- uint64* td_stripbytecount;
+ uint64* td_stripoffset_p; /* should be accessed with TIFFGetStrileOffset */
+ uint64* td_stripbytecount_p; /* should be accessed with TIFFGetStrileByteCount */
+ uint32 td_stripoffsetbyteallocsize; /* number of elements currently allocated
for td_stripoffset/td_stripbytecount. Only used if TIFF_LAZYSTRILELOAD is set */
+#ifdef STRIPBYTECOUNTSORTED_UNUSED
int td_stripbytecountsorted; /* is the bytecount array sorted ascending? */
-#if defined(DEFER_STRILE_LOAD)
+#endif
TIFFDirEntry td_stripoffset_entry; /* for deferred loading */
TIFFDirEntry td_stripbytecount_entry; /* for deferred loading */
-#endif
uint16 td_nsubifd;
uint64* td_subifd;
/* YCbCr parameters */
@@ -118,6 +120,8 @@ typedef struct {
int td_customValueCount;
TIFFTagValue *td_customValues;
+
+ unsigned char td_deferstrilearraywriting; /* see TIFFDeferStrileArrayWriting()
*/
} TIFFDirectory;
/*
diff --git a/sdk/include/reactos/libs/libtiff/tiffio.h
b/sdk/include/reactos/libs/libtiff/tiffio.h
index e8065495f12..198481d53f8 100644
--- a/sdk/include/reactos/libs/libtiff/tiffio.h
+++ b/sdk/include/reactos/libs/libtiff/tiffio.h
@@ -94,12 +94,7 @@ typedef void* tdata_t; /* image data ref */
#if defined(USE_WIN32_FILEIO)
# define VC_EXTRALEAN
-#ifdef __REACTOS__
-# define WIN32_NO_STATUS
-# include <windef.h>
-#else /* __REACTOS__ */
# include <windows.h>
-#endif /* __REACTOS__ */
# ifdef __WIN32__
DECLARE_HANDLE(thandle_t); /* Win32 file handle */
# else
@@ -416,6 +411,8 @@ extern int TIFFWriteDirectory(TIFF *);
extern int TIFFWriteCustomDirectory(TIFF *, uint64 *);
extern int TIFFCheckpointDirectory(TIFF *);
extern int TIFFRewriteDirectory(TIFF *);
+extern int TIFFDeferStrileArrayWriting(TIFF *);
+extern int TIFFForceStrileArrayWriting(TIFF* );
#if defined(c_plusplus) || defined(__cplusplus)
extern void TIFFPrintDirectory(TIFF*, FILE*, long = 0);
@@ -473,6 +470,9 @@ extern tmsize_t TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void*
buf, tmsize_
extern tmsize_t TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size);
extern tmsize_t TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size);
extern tmsize_t TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size);
+extern int TIFFReadFromUserBuffer(TIFF* tif, uint32 strile,
+ void* inbuf, tmsize_t insize,
+ void* outbuf, tmsize_t outsize);
extern tmsize_t TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc);
extern tmsize_t TIFFWriteRawStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc);
extern tmsize_t TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc);
@@ -493,6 +493,11 @@ extern void TIFFSwabArrayOfDouble(double* dp, tmsize_t n);
extern void TIFFReverseBits(uint8* cp, tmsize_t n);
extern const unsigned char* TIFFGetBitRevTable(int);
+extern uint64 TIFFGetStrileOffset(TIFF *tif, uint32 strile);
+extern uint64 TIFFGetStrileByteCount(TIFF *tif, uint32 strile);
+extern uint64 TIFFGetStrileOffsetWithErr(TIFF *tif, uint32 strile, int *pbErr);
+extern uint64 TIFFGetStrileByteCountWithErr(TIFF *tif, uint32 strile, int *pbErr);
+
#ifdef LOGLUV_PUBLIC
#define U_NEU 0.210526316
#define V_NEU 0.473684211
diff --git a/sdk/include/reactos/libs/libtiff/tiffiop.h
b/sdk/include/reactos/libs/libtiff/tiffiop.h
index 186c291f5d7..45a79323bfb 100644
--- a/sdk/include/reactos/libs/libtiff/tiffiop.h
+++ b/sdk/include/reactos/libs/libtiff/tiffiop.h
@@ -77,6 +77,19 @@ extern int snprintf(char* str, size_t size, const char* format, ...);
#define FALSE 0
#endif
+#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0))
+#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1)
+
+/*
+ * Largest 32-bit unsigned integer value.
+ */
+#define TIFF_UINT32_MAX 0xFFFFFFFFU
+
+/*
+ * Largest 64-bit unsigned integer value.
+ */
+#define TIFF_UINT64_MAX (((uint64)(TIFF_UINT32_MAX)) << 32 | TIFF_UINT32_MAX)
+
typedef struct client_info {
struct client_info *next;
void *data;
@@ -127,6 +140,9 @@ struct tiff {
#define TIFF_DIRTYSTRIP 0x200000U /* stripoffsets/stripbytecount dirty*/
#define TIFF_PERSAMPLE 0x400000U /* get/set per sample tags as arrays */
#define TIFF_BUFFERMMAP 0x800000U /* read buffer (tif_rawdata) points into mmap()
memory */
+ #define TIFF_DEFERSTRILELOAD 0x1000000U /* defer strip/tile offset/bytecount
array loading. */
+ #define TIFF_LAZYSTRILELOAD 0x2000000U /* lazy/ondemand loading of strip/tile
offset/bytecount values. Only used if TIFF_DEFERSTRILELOAD is set and in read-only mode
*/
+ #define TIFF_CHOPPEDUPARRAYS 0x4000000U /* set when allocChoppedUpStripArrays()
has modified strip array */
uint64 tif_diroff; /* file offset of current directory */
uint64 tif_nextdiroff; /* file offset of following directory */
uint64* tif_dirlist; /* list of offsets to already seen directories to
prevent IFD looping */
@@ -258,7 +274,7 @@ struct tiff {
#define TIFFhowmany8_64(x)
(((x)&0x07)?((uint64)(x)>>3)+1:(uint64)(x)>>3)
#define TIFFroundup_64(x, y) (TIFFhowmany_64(x,y)*(y))
-/* Safe multiply which returns zero if there is an integer overflow */
+/* Safe multiply which returns zero if there is an *unsigned* integer overflow. This
macro is not safe for *signed* integer types */
#define TIFFSafeMultiply(t,v,m) ((((t)(m) != (t)0) && (((t)(((v)*(m))/(m))) ==
(t)(v))) ? (t)((v)*(m)) : (t)0)
#define TIFFmax(A,B) ((A)>(B)?(A):(B))
@@ -368,12 +384,16 @@ extern TIFFErrorHandlerExt _TIFFerrorHandlerExt;
extern uint32 _TIFFMultiply32(TIFF*, uint32, uint32, const char*);
extern uint64 _TIFFMultiply64(TIFF*, uint64, uint64, const char*);
+extern tmsize_t _TIFFMultiplySSize(TIFF*, tmsize_t, tmsize_t, const char*);
+extern tmsize_t _TIFFCastUInt64ToSSize(TIFF*, uint64, const char*);
extern void* _TIFFCheckMalloc(TIFF*, tmsize_t, tmsize_t, const char*);
extern void* _TIFFCheckRealloc(TIFF*, void*, tmsize_t, tmsize_t, const char*);
extern double _TIFFUInt64ToDouble(uint64);
extern float _TIFFUInt64ToFloat(uint64);
+extern float _TIFFClampDoubleToFloat(double);
+
extern tmsize_t
_TIFFReadEncodedStripAndAllocBuffer(TIFF* tif, uint32 strip,
void **buf, tmsize_t bufsizetoalloc,
diff --git a/sdk/include/reactos/libs/libtiff/tiffvers.h
b/sdk/include/reactos/libs/libtiff/tiffvers.h
index 403d61be04b..aa3f613e73f 100644
--- a/sdk/include/reactos/libs/libtiff/tiffvers.h
+++ b/sdk/include/reactos/libs/libtiff/tiffvers.h
@@ -1,4 +1,4 @@
-#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.0.10\nCopyright (c) 1988-1996 Sam
Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc."
+#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.1.0\nCopyright (c) 1988-1996 Sam
Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc."
/*
* This define can be used in code that requires
* compilation-related definitions specific to a
@@ -6,4 +6,4 @@
* version checking should be done based on the
* string returned by TIFFGetVersion.
*/
-#define TIFFLIB_VERSION 20181110
+#define TIFFLIB_VERSION 20191103