From 13c4dc0e69d25a3f415a622d87013ddae8d949e2 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Mon, 23 Mar 2020 18:43:45 +0000 Subject: [PATCH] 3rdparty: update libtiff 4.0.10 => 4.1.0 - https://gitlab.com/libtiff/libtiff/-/tags/v4.1.0 --- 3rdparty/libtiff/CMakeLists.txt | 14 +- 3rdparty/libtiff/snprintf.c | 4 + 3rdparty/libtiff/tif_aux.c | 10 ++ 3rdparty/libtiff/tif_config.h.cmake.in | 2 +- 3rdparty/libtiff/tif_dir.c | 50 ++++-- 3rdparty/libtiff/tif_dirread.c | 210 ++++++++++++++++++++----- 3rdparty/libtiff/tif_dirwrite.c | 18 +-- 3rdparty/libtiff/tif_luv.c | 11 +- 3rdparty/libtiff/tif_lzw.c | 2 + 3rdparty/libtiff/tif_pixarlog.c | 6 +- 3rdparty/libtiff/tif_read.c | 8 +- 3rdparty/libtiff/tif_webp.c | 45 ++++-- 3rdparty/libtiff/tif_zip.c | 58 +++---- 3rdparty/libtiff/tiffiop.h | 2 + 14 files changed, 300 insertions(+), 140 deletions(-) diff --git a/3rdparty/libtiff/CMakeLists.txt b/3rdparty/libtiff/CMakeLists.txt index 2319b9853e..16cb598955 100644 --- a/3rdparty/libtiff/CMakeLists.txt +++ b/3rdparty/libtiff/CMakeLists.txt @@ -126,30 +126,30 @@ endif() if(SIZEOF_UNSIGNED_INT EQUAL SIZEOF_SIZE_T) set(TIFF_SIZE_T "unsigned int") set(TIFF_SIZE_FORMAT "%u") + set(TIFF_SSIZE_T "signed int") + set(TIFF_SSIZE_FORMAT "%d") elseif(SIZEOF_UNSIGNED_LONG EQUAL SIZEOF_SIZE_T) set(TIFF_SIZE_T "unsigned long") set(TIFF_SIZE_FORMAT "%lu") + set(TIFF_SSIZE_T "signed long") + set(TIFF_SSIZE_FORMAT "%ld") elseif(SIZEOF_UNSIGNED_LONG_LONG EQUAL SIZEOF_SIZE_T) set(TIFF_SIZE_T "unsigned long") if(MINGW) set(TIFF_SIZE_FORMAT "%I64u") + set(TIFF_SSIZE_FORMAT "%I64d") else() set(TIFF_SIZE_FORMAT "%llu") + set(TIFF_SSIZE_FORMAT "%lld") endif() endif() if(SIZEOF_SIGNED_INT EQUAL SIZEOF_UNSIGNED_CHAR_P) - set(TIFF_SSIZE_T "signed int") - set(TIFF_SSIZE_FORMAT "%d") elseif(SIZEOF_SIGNED_LONG EQUAL SIZEOF_UNSIGNED_CHAR_P) - set(TIFF_SSIZE_T "signed long") - set(TIFF_SSIZE_FORMAT "%ld") elseif(SIZEOF_SIGNED_LONG_LONG EQUAL SIZEOF_UNSIGNED_CHAR_P) set(TIFF_SSIZE_T "signed long long") if(MINGW) - set(TIFF_SSIZE_FORMAT "%I64d") else() - set(TIFF_SSIZE_FORMAT "%lld") endif() endif() @@ -216,6 +216,8 @@ endif() set(fillorder FILLORDER_MSB2LSB) if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "i.*86.*" OR CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "amd64.*" OR + # AMD64 on Windows + CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "AMD64" OR CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86_64.*") set(fillorder FILLORDER_LSB2MSB) endif() diff --git a/3rdparty/libtiff/snprintf.c b/3rdparty/libtiff/snprintf.c index 1c4ac08786..3542ab759b 100644 --- a/3rdparty/libtiff/snprintf.c +++ b/3rdparty/libtiff/snprintf.c @@ -16,7 +16,11 @@ int _TIFF_vsnprintf_f(char* str, size_t size, const char* format, va_list ap) int count = -1; if (size != 0) +#if _MSC_VER <= 1310 + count = _vsnprintf(str, size, format, ap); +#else count = _vsnprintf_s(str, size, _TRUNCATE, format, ap); +#endif if (count == -1) count = _vscprintf(format, ap); diff --git a/3rdparty/libtiff/tif_aux.c b/3rdparty/libtiff/tif_aux.c index 4ece162faa..90d30214c6 100644 --- a/3rdparty/libtiff/tif_aux.c +++ b/3rdparty/libtiff/tif_aux.c @@ -30,6 +30,7 @@ #include "tiffiop.h" #include "tif_predict.h" #include +#include uint32 _TIFFMultiply32(TIFF* tif, uint32 first, uint32 second, const char* where) @@ -357,6 +358,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/3rdparty/libtiff/tif_config.h.cmake.in b/3rdparty/libtiff/tif_config.h.cmake.in index 6ea3eff3a9..2414460338 100644 --- a/3rdparty/libtiff/tif_config.h.cmake.in +++ b/3rdparty/libtiff/tif_config.h.cmake.in @@ -216,7 +216,7 @@ #endif /* Number of bits in a file offset, on hosts where this is settable. */ -//disabled for OpenCV CMakeLists.txt: #define _FILE_OFFSET_BITS @FILE_OFFSET_BITS@ +#define _FILE_OFFSET_BITS @FILE_OFFSET_BITS@ /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ diff --git a/3rdparty/libtiff/tif_dir.c b/3rdparty/libtiff/tif_dir.c index 6f0b48798b..b4ecd44f95 100644 --- a/3rdparty/libtiff/tif_dir.c +++ b/3rdparty/libtiff/tif_dir.c @@ -29,7 +29,6 @@ * (and also some miscellaneous stuff) */ #include "tiffiop.h" -#include /* * These are used in the backwards compatibility code... @@ -88,13 +87,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 +117,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 +166,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 +289,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 +336,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 +351,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 +377,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 +700,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; diff --git a/3rdparty/libtiff/tif_dirread.c b/3rdparty/libtiff/tif_dirread.c index e80a3b13e8..1fdcb0997a 100644 --- a/3rdparty/libtiff/tif_dirread.c +++ b/3rdparty/libtiff/tif_dirread.c @@ -164,6 +164,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); @@ -4246,6 +4247,19 @@ TIFFReadDirectory(TIFF* tif) ChopUpSingleUncompressedStrip(tif); } + /* There are also uncompressed stripped 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 ) + { + if ( !_TIFFFillStriles(tif) || !tif->tif_dir.td_stripbytecount ) + return 0; + TryChopUpUncompressedBigTiff(tif); + } + /* * Clear the dirty directory flag. */ @@ -5699,6 +5713,63 @@ 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; + uint32 i; + uint64 *newcounts; + uint64 *newoffsets; + + 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. + */ + offset = td->td_stripoffset[0]; + bytecount = td->td_stripoffset[td->td_nstrips-1] + + td->td_stripbytecount[td->td_nstrips-1] - offset; + 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); + _TIFFfree(td->td_stripoffset); + td->td_stripbytecount = newcounts; + td->td_stripoffset = newoffsets; + td->td_stripbytecountsorted = 1; +} + + /* * Replace a single strip (tile) of uncompressed data by multiple strips * (tiles), each approximately STRIP_SIZE_DEFAULT bytes. This is useful for @@ -5714,11 +5785,8 @@ ChopUpSingleUncompressedStrip(TIFF* tif) uint32 rowblock; uint64 rowblockbytes; uint64 stripbytes; - uint32 strip; uint32 nstrips; uint32 rowsperstrip; - uint64* newcounts; - uint64* newoffsets; bytecount = td->td_stripbytecount[0]; /* On a newly created file, just re-opened to be filled, we */ @@ -5769,46 +5837,106 @@ 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); } + +/* + * 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 ) +{ + 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( td->td_stripbytecount[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( td->td_stripbytecount[i] < TIFFVStripSize64( + tif, td->td_imagelength - i * td->td_rowsperstrip ) ) + { + return; + } + } + else + { + if( td->td_stripbytecount[i] != stripsize ) + { + return; + } + if( i > 0 && td->td_stripoffset[i] != + td->td_stripoffset[i-1] + td->td_stripbytecount[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 && + (td->td_stripoffset[td->td_nstrips-1] > TIFFGetFileSize(tif) || + td->td_stripoffset[td->td_nstrips-1] + + td->td_stripbytecount[td->td_nstrips-1] > TIFFGetFileSize(tif)) ) + { + return; + } + + allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip); +} + + + int _TIFFFillStriles( TIFF *tif ) { return _TIFFFillStrilesInternal( tif, 1 ); diff --git a/3rdparty/libtiff/tif_dirwrite.c b/3rdparty/libtiff/tif_dirwrite.c index c15a28dbd8..83c01b24f2 100644 --- a/3rdparty/libtiff/tif_dirwrite.c +++ b/3rdparty/libtiff/tif_dirwrite.c @@ -28,7 +28,6 @@ * Directory Write Support Routines. */ #include "tiffiop.h" -#include #ifdef HAVE_IEEEFP #define TIFFCvtNativeToIEEEFloat(tif, n, fp) @@ -946,15 +945,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 +1019,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 @@ -1893,12 +1883,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) diff --git a/3rdparty/libtiff/tif_luv.c b/3rdparty/libtiff/tif_luv.c index aa35ea07d1..192fa26188 100644 --- a/3rdparty/libtiff/tif_luv.c +++ b/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 diff --git a/3rdparty/libtiff/tif_lzw.c b/3rdparty/libtiff/tif_lzw.c index ac685dd740..21064f29ae 100644 --- a/3rdparty/libtiff/tif_lzw.c +++ b/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/3rdparty/libtiff/tif_pixarlog.c b/3rdparty/libtiff/tif_pixarlog.c index 7438d69215..b1e48d99c9 100644 --- a/3rdparty/libtiff/tif_pixarlog.c +++ b/3rdparty/libtiff/tif_pixarlog.c @@ -640,6 +640,7 @@ PixarLogGuessDataFmt(TIFFDirectory *td) static tmsize_t multiply_ms(tmsize_t m1, tmsize_t m2) { + assert(m1 >= 0 && m2 >= 0); if( m1 == 0 || m2 > TIFF_TMSIZE_T_MAX / m1 ) return 0; return m1 * m2; @@ -648,6 +649,7 @@ multiply_ms(tmsize_t m1, tmsize_t m2) 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 +819,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", diff --git a/3rdparty/libtiff/tif_read.c b/3rdparty/libtiff/tif_read.c index e63810cc78..79c470cbf1 100644 --- a/3rdparty/libtiff/tif_read.c +++ b/3rdparty/libtiff/tif_read.c @@ -103,6 +103,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); @@ -1367,7 +1372,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); diff --git a/3rdparty/libtiff/tif_webp.c b/3rdparty/libtiff/tif_webp.c index a002f481da..22665f2d2b 100644 --- a/3rdparty/libtiff/tif_webp.c +++ b/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/3rdparty/libtiff/tif_zip.c b/3rdparty/libtiff/tif_zip.c index 9d4bceb179..c75077349e 100644 --- a/3rdparty/libtiff/tif_zip.c +++ b/3rdparty/libtiff/tif_zip.c @@ -124,7 +124,6 @@ ZIPSetupDecode(TIFF* tif) static int ZIPPreDecode(TIFF* tif, uint16 s) { - static const char module[] = "ZIPPreDecode"; ZIPState* sp = DecoderState(tif); (void) s; @@ -138,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); } @@ -158,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); } @@ -229,7 +220,6 @@ ZIPSetupEncode(TIFF* tif) static int ZIPPreEncode(TIFF* tif, uint16 s) { - static const char module[] = "ZIPPreEncode"; ZIPState *sp = EncoderState(tif); (void) s; @@ -242,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); } @@ -269,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", @@ -286,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); } @@ -314,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/3rdparty/libtiff/tiffiop.h b/3rdparty/libtiff/tiffiop.h index 186c291f5d..47a553aa54 100644 --- a/3rdparty/libtiff/tiffiop.h +++ b/3rdparty/libtiff/tiffiop.h @@ -374,6 +374,8 @@ 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,