summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEirik Aavitsland <eirik.aavitsland@qt.io>2019-11-05 09:58:05 +0100
committerEirik Aavitsland <eirik.aavitsland@qt.io>2019-11-06 10:39:19 +0100
commitba1fb21bc61a2075c7fd058e7f7ba5caf7d2f400 (patch)
treeb91253586ae2d1d1c6f1c35cfc6df252edf925fb
parent9fe1f2e918d39031852805f1add23125c061d3c3 (diff)
Update bundled libtiff to version 4.1.05.13
[ChangeLog][Third-Party Code] Bundled libtiff was updated to version 4.1.0 Change-Id: I3e841863c5cf8588bf62b6520f34e64909394998 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io> Reviewed-by: Liang Qi <liang.qi@qt.io>
-rw-r--r--src/3rdparty/libtiff/ChangeLog884
-rw-r--r--src/3rdparty/libtiff/RELEASE-DATE2
-rw-r--r--src/3rdparty/libtiff/VERSION2
-rw-r--r--src/3rdparty/libtiff/libtiff/libtiff.def7
-rw-r--r--src/3rdparty/libtiff/libtiff/mkg3states.c2
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_aux.c26
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_config.h2
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_config.h.in2
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_dir.c67
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_dir.h12
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_dirread.c1239
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_dirwrite.c343
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_flush.c118
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_getimage.c2
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_jpeg.c17
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_luv.c17
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_lzw.c2
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_ojpeg.c91
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_open.c18
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_pixarlog.c9
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_print.c10
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_read.c226
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_strip.c3
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_thunder.c10
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_write.c138
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_zip.c58
-rw-r--r--src/3rdparty/libtiff/libtiff/tiffio.h10
-rw-r--r--src/3rdparty/libtiff/libtiff/tiffiop.h15
-rw-r--r--src/3rdparty/libtiff/libtiff/tiffvers.h4
-rw-r--r--src/3rdparty/libtiff/port/snprintf.c4
-rw-r--r--src/3rdparty/libtiff/qt_attribution.json2
31 files changed, 2630 insertions, 712 deletions
diff --git a/src/3rdparty/libtiff/ChangeLog b/src/3rdparty/libtiff/ChangeLog
index 1f50e20..01e2182 100644
--- a/src/3rdparty/libtiff/ChangeLog
+++ b/src/3rdparty/libtiff/ChangeLog
@@ -1,3 +1,887 @@
+2019-11-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ libtiff 4.1.0 released.
+
+ Added a step for updating the legacy ChangeLog file.
+
+ Ignore emacs temporary files (ending with tilde character).
+
+ Added release summary page for the 4.1.0 release.
+
+ Fix Cmake HAVE_GETOPT for systems which declare getopt in stdio.h. Fix utility baked-in getopt prototype which appears when HAVE_GETOPT is not defined.
+
+ Fax2tiff.sh needs to remove its output file in advance. Syntax changes so that bash is not required.
+
+2019-10-26 Even Rouault <even.rouault@spatialys.com>
+
+ tif_jpeg.c: extra cast to silence Coverity warning. GDAL CID 1406475.
+
+2019-10-23 Even Rouault <even.rouault@spatialys.com>
+
+ tif_jpeg.c: fix warning added by previous commit (on 32bit builds)
+
+2019-10-23 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'coverity-fixes' into 'master'
+ Coverity fixes
+
+ See merge request libtiff/libtiff!94
+
+2019-10-22 Timothy Lyanguzov <timothy.lyanguzov@sap.com>
+
+ Use 64-bit calculations correctly.
+
+ Fix size calculation to use 64-bit tmsize_t correctly.
+
+ Make bytesperclumpline calculations using tmsize_t type.
+
+2019-10-03 Even Rouault <even.rouault@spatialys.com>
+
+ tif_read: align code of TIFFReadRawStrip() and TIFFReadRawTile() that differed for non good reason. Non-functional change normally. (fixes GitLab #162)
+
+2019-10-01 Even Rouault <even.rouault@spatialys.com>
+
+ HTML: update for GitLab issues.
+
+2019-09-29 Even Rouault <even.rouault@spatialys.com>
+
+ html/v3.5.6-beta.html: redact URL of defunct web site.
+
+ Website: update links to mailing list.
+
+2019-09-17 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFReadAndRealloc(): avoid too large memory allocation attempts. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=17244
+
+2019-09-03 Even Rouault <even.rouault@spatialys.com>
+
+ ByteCountLooksBad and EstimateStripByteCounts: avoid unsigned integer overflows. Fixes https://oss-fuzz.com/testcase-detail/5686156066291712 and https://oss-fuzz.com/testcase-detail/6332499206078464
+
+2019-09-02 Even Rouault <even.rouault@spatialys.com>
+
+ tif_ojpeg.c: avoid relying on isTiled macro being wrapped in ()
+
+ tif_ojpeg.c: avoid use of uninitialized memory on edge/broken file. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16844
+
+ tiff_read_rgba_fuzzer.cc: add a -DSTANDALONE mode for easier reproduction of oss-fuzz reports
+
+2019-09-01 Even Rouault <even.rouault@spatialys.com>
+
+ tif_dirread.c: allocChoppedUpStripArrays(). avoid unsigned integer overflow. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16846
+
+2019-08-27 Even Rouault <even.rouault@spatialys.com>
+
+ tif_ojpeg.c: avoid unsigned integer overflow. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16793
+
+2019-08-26 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFReadDirEntryData(): rewrite to avoid unsigned integer overflow (not a bug). Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16792
+
+ TIFFFetchDirectory(): fix invalid cast from uint64 to tmsize_t. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16784
+
+2019-08-25 Even Rouault <even.rouault@spatialys.com>
+
+ JPEG: avoid use of unintialized memory on corrupted files.
+ Follow-up of cf3ce6fab894414a336546f62adc57f02590a22c
+ Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16602
+ Credit to OSS Fuzz
+
+2019-08-23 Even Rouault <even.rouault@spatialys.com>
+
+ _TIFFPartialReadStripArray(): avoid unsigned integer overflow. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16685
+
+ OJPEGWriteHeaderInfo(): avoid unsigned integer overflow on strile dimensions close to UINT32_MAX. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16683
+
+ TIFFFillStrip(): avoid harmless unsigned integer overflow. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16653
+
+ EstimateStripByteCounts(): avoid unsigned integer overflow. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16643&
+
+ tif_ojpeg: avoid unsigned integer overflow (probably not a bug). Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16635
+
+ tif_thunder: avoid unsigned integer overflow (not a bug). Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16632
+
+2019-08-22 Even Rouault <even.rouault@spatialys.com>
+
+ _TIFFMultiply32() / _TIFFMultiply64(): avoid relying on unsigned integer overflow (not a bug)
+
+ EstimateStripByteCounts(): avoid unsigned integer overflow.
+
+2019-08-21 Even Rouault <even.rouault@spatialys.com>
+
+ EstimateStripByteCounts(): avoid unsigned integer overflow.
+
+2019-08-20 Even Rouault <even.rouault@spatialys.com>
+
+ EstimateStripByteCounts(): avoid harmless unsigned integer overflow.
+
+ _TIFFPartialReadStripArray(): avoid triggering unsigned integer overflow with -fsanitize=unsigned-integer-overflow (not a bug, this is well defined by itself)
+
+2019-08-18 Even Rouault <even.rouault@spatialys.com>
+
+ tiff2ps: fix use of wrong data type that caused issues (/Height being written as 0) on 64-bit big endian platforms
+
+2019-08-16 Even Rouault <even.rouault@spatialys.com>
+
+ setByteArray(): fix previous commit.
+
+ setByteArray(): avoid potential signed integer overflow. Pointed by Hendra Gunadi. No actual problem known (which does not mean there wouldn't be any. Particularly on 32bit builds)
+
+2019-08-15 Even Rouault <even.rouault@spatialys.com>
+
+ RGBA interface: fix integer overflow potentially causing write heap buffer overflow, especially on 32 bit builds. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16443. Credit to OSS Fuzz
+
+2019-08-14 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_integer_overflow' into 'master'
+ Fix integer overflow in _TIFFCheckMalloc() and other implementation-defined behaviour (CVE-2019-14973)
+
+ See merge request libtiff/libtiff!90
+
+2019-08-13 Even Rouault <even.rouault@spatialys.com>
+
+ Fix integer overflow in _TIFFCheckMalloc() and other implementation-defined behaviour (CVE-2019-14973)
+ _TIFFCheckMalloc()/_TIFFCheckRealloc() used a unsafe way to detect overflow
+ in the multiplication of nmemb and elem_size (which are of type tmsize_t, thus
+ signed), which was especially easily triggered on 32-bit builds (with recent
+ enough compilers that assume that signed multiplication cannot overflow, since
+ this is undefined behaviour by the C standard). The original issue which lead to
+ this fix was trigged from tif_fax3.c
+
+ There were also unsafe (implementation defied), and broken in practice on 64bit
+ builds, ways of checking that a uint64 fits of a (signed) tmsize_t by doing
+ (uint64)(tmsize_t)uint64_var != uint64_var comparisons. Those have no known
+ at that time exploits, but are better to fix in a more bullet-proof way.
+ Or similarly use of (int64)uint64_var <= 0.
+
+2019-08-12 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFClientOpen(): fix memory leak if one of the required callbacks is not provided. Fixed Coverity GDAL CID 1404110
+
+ OJPEGReadBufferFill(): avoid very long processing time on corrupted files. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16400. master only
+
+2019-08-10 Even Rouault <even.rouault@spatialys.com>
+
+ oss-fuzz/tiff_read_rgba_fuzzer.cc: fix wrong env variable value in previous commit
+
+ oss-fuzz/tiff_read_rgba_fuzzer.cc: avoid issue with libjpeg-turbo and MSAN
+
+ OJPEG: fix integer division by zero on corrupted subsampling factors. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=15824. Credit to OSS Fuzz
+
+ Merge branch 'ossfuzz_i386'
+
+ contrib/oss-fuzz/build.sh: fix for i386 build of jbigkit, and use $LIB_FUZZING_ENGINE
+
+2019-08-10 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'patch-1' into 'master'
+ fix two tiny typos
+
+ See merge request libtiff/libtiff!89
+
+2019-08-10 Reto Kromer <rk@reto.ch>
+
+ fix two tiny typos.
+
+2019-08-09 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'patch-1' into 'master'
+ fix a typo in man page
+
+ See merge request libtiff/libtiff!88
+
+2019-08-09 Reto Kromer <rk@reto.ch>
+
+ fix typo.
+
+2019-08-04 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'TIFFTAGID_Zero_reading_IGNORE' into 'master'
+ Suppressed Reading of Tiff tags with ID = 0 (like GPSVERSIONID) corrected.
+
+ See merge request libtiff/libtiff!77
+
+2019-08-04 Su Laus <sulau@freenet.de>
+
+ Reading of Tiff tags with ID = 0 (like GPSVERSIONID) corrected.
+ IGNORE placeholder in tif_dirread.c is now replaced by a field dir_ignore in the TIFFDirEntry structure
+
+ Currently, in tif_dirread.c a special IGNORE value for the tif tags is defined
+ in order to flag status preventing already processed tags from further processing.
+ This irrational behaviour prevents reading of custom tags with id code 0 - like tag GPSVERSIONID from EXIF 2.31 definition.
+
+ An additional field 'tdir_ignore' is now added to the TIFFDirEntry structure and code is changed
+ to allow tags with id code 0 to be read correctly.
+
+ This change was already proposed as pending improvement in tif_dirread.c around line 32.
+
+ Reference is also made to:
+ - Discussion in https://gitlab.com/libtiff/libtiff/merge_requests/39
+ - http://bugzilla.maptools.org/show_bug.cgi?id=2540
+
+ Comments and indention adapted.
+
+ Preparation to rebase onto master
+
+2019-07-16 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'cmake_amd64' into 'master'
+ CMakeLists.txt: properly set value of HOST_FILLORDER to LSB2MSB for Windows CMake builds
+
+ See merge request libtiff/libtiff!87
+
+2019-07-15 Even Rouault <even.rouault@spatialys.com>
+
+ CMakeLists.txt: properly set value of HOST_FILLORDER to LSB2MSB for Windows CMake builds
+ As can be seen in https://ci.appveyor.com/project/rleigh-codelibre/libtiff-didfs/builds/25846668/job/ory5w098j8wcij9x
+ log, the HOST_FILLORDER is not properly set:
+
+ [00:02:58] -- CMAKE_HOST_SYSTEM_PROCESSOR set to AMD64
+ [00:02:58] -- HOST_FILLORDER set to FILLORDER_MSB2LSB
+
+ Ther reason is that we match the "amd64.*" lowercase string whereas
+ CMAKE_HOST_SYSTEM_PROCESSOR is set to AMD64 uppercase.
+
+2019-07-09 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFWriteCheck(): call TIFFForceStrileArrayWriting() when needed (should have gone with eaeca6274ae71cdfaeb9f673b6fb0f3cfc0e6ce5) (master only)
+
+2019-07-09 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_chromium_925269' into 'master'
+ OJPEG: avoid use of unintialized memory on corrupted files
+
+ See merge request libtiff/libtiff!86
+
+2019-07-05 Even Rouault <even.rouault@spatialys.com>
+
+ OJPEG: avoid use of unintialized memory on corrupted files.
+ Fixes https://bugs.chromium.org/p/chromium/issues/detail?id=925269
+ Patch from Lei Zhang with little adaptations.
+
+2019-06-29 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix-division-by-zero' into 'master'
+ Return infinite distance when denominator is zero.
+
+ See merge request libtiff/libtiff!85
+
+2019-06-29 Dirk Lemstra <dirk@lemstra.org>
+
+ Return infinite distance when denominator is zero.
+
+2019-06-29 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'typetests' into 'master'
+ Add test to check that libtiff types have the correct size
+
+ See merge request libtiff/libtiff!57
+
+2019-05-31 Thomas Bernard <miniupnp@free.fr>
+
+ make TIFF_SSIZE_T the same bitwidth as TIFF_SIZE_T.
+ it was previously the same bitwidth as unsigned char *
+ Pointers can be larger than size_t.
+
+2019-05-31 Thomas Bernard <miniupnp@free.fr>
+
+ Add test to check that libtiff types have the correct size.
+ in configure/CMakeList.txt :
+
+ - TIFF_INT8_T/TIFF_UINT8_T is signed/unsigned char
+ sizeof(char)==1 in C standard
+ - TIFF_INT16_T/TIFF_UINT16_T is signed/unsigned short
+ sizeof(short)>=2 in C standard
+ - TIFF_INT32_T/TIFF_UINT32_T is defined so its sizeof() is 4
+
+ - TIFF_INT64_T/TIFF_UINT64_T is defined so its sizeof() is 8
+
+ - TIFF_SIZE_T is defined so it has same sizeof() than size_t
+
+ - TIFF_SSIZE_T is defined so it has same sizeof() than unsigned char *
+
+2019-05-29 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'defer_strile_writing' into 'master'
+ Add TIFFDeferStrileArrayWriting() and TIFFForceStrileArrayWriting()
+
+ See merge request libtiff/libtiff!82
+
+2019-05-29 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'TIFFReadFromUserBuffer' into 'master'
+ Add TIFFReadFromUserBuffer()
+
+ See merge request libtiff/libtiff!81
+
+2019-05-26 Even Rouault <even.rouault@spatialys.com>
+
+ Fix vulnerability in 'D' (DeferStrileLoad) mode (master only) (fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14908)
+
+2019-05-25 Even Rouault <even.rouault@spatialys.com>
+
+ Replace 'stripped' by 'striped' in error messages.
+
+2019-05-25 Even Rouault <even.rouault@spatialys.com>
+
+ Add TIFFDeferStrileArrayWriting() and TIFFForceStrileArrayWriting()
+ Those advanced writing functions must be used in a particular sequence
+ to make their intended effect. Their aim is to control when/where
+ the [Strip/Tile][Offsets/ByteCounts] arrays are written into the file.
+
+ The purpose of this is to generate 'cloud-optimized geotiff' files where
+ the first KB of the file only contain the IFD entries without the potentially
+ large strile arrays. Those are written afterwards.
+
+ 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
+
+ See test/defer_strile_writing.c for a practical example.
+
+2019-05-24 Even Rouault <even.rouault@spatialys.com>
+
+ Fix vulnerability introduced by defer strile loading (master only)
+ Found on GDAL with https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14894
+ Disabling the TIFF_DEFERSTRILELOAD bit in ChopupStripArray() was a
+ bad idea since when using TIFFReadDirectory() to reload the directory again
+ would lead to a different value of td_rowsperstrip, which could confuse
+ readers if they relied on the value found initially.
+
+ Fix typo in error message (master only)
+
+2019-05-22 Even Rouault <even.rouault@spatialys.com>
+
+ Add TIFFReadFromUserBuffer()
+ 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.
+
+ libtiff.def: add missing new symbols.
+
+ test/defer_strile_loading.c: fix warning with Visual C++
+
+ _TIFFRewriteField(): fix for bigtiff case (master only)
+ 116cf67f4c59196605abdb244657c3070c4310af made StripByteCount/TileByteCount to
+ always be rewritten as TIFF_LONG8.
+
+2019-05-21 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'ondemand_strile_offbytecount_loading' into 'master'
+ Make defer strile offset/bytecount loading available at runtime
+
+ See merge request libtiff/libtiff!79
+
+2019-05-21 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bigtiff_write_bytecount_on_long_when_possible' into 'master'
+ Create TileByteCounts/StripByteCounts tag with SHORT (ClassicTIFF/BigTIFF) or LONG (BigTIFF) type when possible
+
+ See merge request libtiff/libtiff!78
+
+2019-05-21 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'html_link' into 'master'
+ libtiff.html, bigtiffpr.html: absolute => relative link
+
+ See merge request libtiff/libtiff!80
+
+2019-05-14 Thomas Bernard <miniupnp@free.fr>
+
+ libtiff.html, bigtiffpr.html: absolute => relative link.
+
+2019-05-10 Even Rouault <even.rouault@spatialys.com>
+
+ Make defer strile offset/bytecount loading available at runtime.
+ ... and add per-strile offset/bytecount loading capabilities.
+
+ Part of this commit makes the behaviour that was previously met when
+ libtiff was compiled with -DDEFER_STRILE_LOAD available for default builds
+ when specifying the new 'D' (Deferred) TIFFOpen() flag. In that mode, the [Tile/Strip][ByteCounts/Offsets]
+ arrays are only loaded when first accessed. This can speed-up the opening
+ of files stored on the network when just metadata retrieval is needed.
+ This mode has been used for years by the GDAL library when compiled with
+ its embeded libtiff copy.
+
+ To avoid potential out-of-tree code (typically codecs) that would use
+ the td_stripbytecount and td_stripoffset array inconditionnaly assuming they
+ have been loaded, those have been suffixed with _p (for protected). The
+ use of the new functions mentionned below is then recommended.
+
+ Another addition of this commit is the capability of loading only the
+ values of the offset/bytecount of the strile of interest instead of the
+ whole array. This is enabled with the new 'O' (Ondemand) flag of TIFFOpen()
+ (which implies 'D'). That behaviour has also been used by GDAL, which hacked
+ into the td_stripoffset/td_stripbytecount arrays directly. The new code
+ added in the _TIFFFetchStrileValue() and _TIFFPartialReadStripArray() internal
+ functions is mostly a port of what was in GDAL GTiff driver previously.
+
+ Related to that, the public TIFFGetStrileOffset[WithErr]() and TIFFGetStrileByteCount[WithErr]()
+ functions have been added to API. They are of particular interest when
+ using sparse files (with offset == bytecount == 0) and you want to detect
+ if a strile is present or not without decompressing the data, or updating
+ an existing sparse file.
+ They will also be used to enable a future enhancement where client code can entirely
+ skip bytecount loading in some situtations
+
+ A new test/defer_strile_loading.c test has been added to test the above
+ capabilities.
+
+2019-05-10 Even Rouault <even.rouault@spatialys.com>
+
+ Creation: use SHORT type when possible for StripByteCounts/TileByteCounts
+ This follows the same logic as previous commit.
+
+2019-05-09 Even Rouault <even.rouault@spatialys.com>
+
+ BigTIFF creation: write TileByteCounts/StripByteCounts tag with LONG when possible
+ In most situations of BigTIFF file, the tile/strip sizes are of reasonable size,
+ that is they fit on a 4-byte LONG. So in that case, use LONG instead of LONG8
+ to save some space. For uncompressed file, it is easy to detect such situations
+ by checking at the TIFFTileSize64()/TIFFStripSize64() return. For compressed file,
+ we must take into account the fact that compression may sometimes result in
+ larger compressed data. So we allow this optimization only for a few select
+ compression times, and take a huge security margin (10x factor). We also only
+ apply this optimization on multi-strip files, so as to allow easy on-the-fly
+ growing of single-strip files whose strip size could grow above the 4GB threshold.
+
+ This change is compatible with the BigTIFF specification. According to
+ https://www.awaresystems.be/imaging/tiff/bigtiff.html:
+ "The StripOffsets, StripByteCounts, TileOffsets, and TileByteCounts tags are
+ allowed to have the datatype TIFF_LONG8 in BigTIFF. Old datatypes TIFF_LONG,
+ and TIFF_SHORT where allowed in the TIFF 6.0 specification, are still valid in BigTIFF, too. "
+ On a practical point of view, this is also compatible on reading/writing of
+ older libtiff 4.X versions.
+
+ The only glitch I found, which is rather minor, is when using such a BigTIFF
+ file with TileByteCounts/StripByteCounts written with TIFF_LONG, and updating
+ it with an older libtiff 4.X version with a change in the
+ [Tile/Strip][ByteCounts/Offsets] array. In that case the _TIFFRewriteField()
+ function will rewrite the directory and array with TIFF_LONG8, instead of updating
+ the existing array (this is an issue fixed by this commit). The file will
+ still be valid however, hence the minor severity of this.
+
+2019-05-08 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bug2799' into 'master'
+ fix fax2tiff
+
+ See merge request libtiff/libtiff!55
+
+2019-05-08 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bug_2829' into 'master'
+ WIN32: use tif_win32.c when building with CMake
+
+ See merge request libtiff/libtiff!75
+
+2019-05-06 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'FILESOURCE_SCENETYPE_reading' into 'master'
+ Reading error for FileSource and SceneType tags corrected.
+
+ See merge request libtiff/libtiff!76
+
+2019-05-06 Su Laus <sulau@freenet.de>
+
+ Reading error for FileSource and SceneType tags corrected.
+ EXIF tags FILESOURCE and SCENETYPE are defined as TIFF_UNDEFINED and field_readcount==1!
+ There is a bug in TIFFReadDirEntryByte() preventing to read correctly type TIFF_UNDEFINED fields with field_readcount==1
+ Upgrade of TIFFReadDirEntryByte() with added TIFF_UNDEFINED switch-entry allows libtiff to read those tags correctly.
+
+2019-04-25 Thomas Bernard <miniupnp@free.fr>
+
+ WIN32: use tif_win32.c when building with CMake.
+ see http://bugzilla.maptools.org/show_bug.cgi?id=2829
+
+ the top CMakeLists.txt defines
+ win32_io and USE_WIN32_FILEIO
+
+ WIN32_IO is defined nowhere in CMake (only in automake things)
+
+2019-04-25 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'gitlab_pages' into 'master'
+ Advertise https://libtiff.gitlab.io/libtiff/ as mirror
+
+ See merge request libtiff/libtiff!70
+
+2019-04-25 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bug_2844' into 'master'
+ tiff2ps.c: PSDataColorContig(): avoid heap buffer overrun
+
+ See merge request libtiff/libtiff!69
+
+2019-04-25 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue_2785' into 'master'
+ tiff2pdf.c: don't call t2p_tile_collapse_left() for Ycbcr
+
+ See merge request libtiff/libtiff!64
+
+2019-04-11 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_gdal_1439' into 'master'
+ TIFFWriteEncodedStrip/TIFFWriteEncodedTile: fix rewriting of LZW-compressed data
+
+ See merge request libtiff/libtiff!74
+
+2019-04-11 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFWriteEncodedStrip/TIFFWriteEncodedTile: fix rewriting of LZW-compressed data
+ Fixes https://github.com/OSGeo/gdal/issues/1439
+
+ When rewriting a LZW tile/strip whose existing size is very close to a multiple of
+ 1024 bytes (and larger than 8192 bytes) with compressed data that is larger,
+ the new data was not placed at the end of the file, causing corruption.
+
+2019-04-08 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bug2848' into 'master'
+ tif_luv.c: LogLuvSetupEncode() error must return 0
+
+ See merge request libtiff/libtiff!72
+
+2019-04-03 Thomas Bernard <miniupnp@free.fr>
+
+ build/gitlab-ci: fix typo.
+
+ show test-suite.log in gitlab-ci.
+ useful when build fails
+
+ Add output check for tiff2ps.
+ note : the reference files have been generated in master branch
+
+2019-03-23 Even Rouault <even.rouault@spatialys.com>
+
+ tif_read.c: potentially fix false positive from Coverity Scan. CID 1400288
+
+ tif_read.c: potentially fix false positive from Coverity Scan. CID 1400271
+
+ tif_zip.c: remove dead code. CID 1400360.
+
+ tif_webp.c: remove false positive warning about dereference before null check. CID 1400255
+
+ tif_pixarlog.c: remove dead code. CID 1400342.
+
+ tif_pixarlog.c: avoid false positive Coverity Scan warnings about overflow. CID 1400300 and 1400367
+
+ tif_lzw.c: silence CoverityScan false positive. CID 1400355.
+
+ tif_luv.c: silence CoverityScan false positive. CID 1400231, 1400251, 1400254, 1400272, 1400318, 1400356
+
+ TryChopUpUncompressedBigTiff(): avoid potential division by zero. master only. GDAL Coverity CID 1400263
+
+2019-03-22 Thomas Bernard <miniupnp@free.fr>
+
+ tif_luv.c: LogLuvSetupEncode() error must return 0.
+ see http://bugzilla.maptools.org/show_bug.cgi?id=2848
+
+ if wrongly returning 1, the processing of incorrect file continues,
+ which causes problems.
+
+2019-03-22 Thomas Bernard <miniupnp@free.fr>
+
+ add a test for fax2tiff tool.
+
+2019-02-28 Thomas Bernard <miniupnp@free.fr>
+
+ tiff2pdf.c: don't call t2p_tile_collapse_left() when buffer size is wrong
+ see http://bugzilla.maptools.org/show_bug.cgi?id=2785
+
+ Advertise https://libtiff.gitlab.io/libtiff/ as mirror.
+ I'm put it above the maptools.org mirror because
+ Even Rouault believe at some point it will be completely removed
+
+2019-02-28 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bug_2826' into 'master'
+ tiff2pdf.c: check colormap pointers when loading CMYK with colormap
+
+ See merge request libtiff/libtiff!65
+
+2019-02-28 Thomas Bernard <miniupnp@free.fr>
+
+ tiff2pdf.c: check colormap pointers.
+ Avoid access to non initialized pointers
+ http://bugzilla.maptools.org/show_bug.cgi?id=2826
+
+2019-02-27 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_warnings' into 'master'
+ tiff2ps.c: fix warning caused by integer promotion
+
+ See merge request libtiff/libtiff!68
+
+2019-02-23 Thomas Bernard <miniupnp@free.fr>
+
+ PSDataColorContig(): avoid heap buffer overrun.
+ fixes http://bugzilla.maptools.org/show_bug.cgi?id=2844
+ each iteration of the loop read nc bytes
+
+2019-02-22 Thomas Bernard <miniupnp@free.fr>
+
+ tiff2ps.c: fix warning caused by integer promotion.
+ uint8 value is promoted to int in (value << 24) so -fsanitize
+ yield runtime errors :
+ tiff2ps.c:2969:33: runtime error: left shift of 246 by 24 places cannot be represented in type 'int'
+
+2019-02-22 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'large_strile_improvements' into 'master'
+ Large strile support improvements
+
+ See merge request libtiff/libtiff!63
+
+2019-02-21 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'gitlab-pages' into 'master'
+ ci: Add pages job
+
+ See merge request libtiff/libtiff!45
+
+2019-02-19 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue_2833' into 'master'
+ tiffcp.c: check that (Tile Width)*(Samples/Pixel) do no overflow
+
+ See merge request libtiff/libtiff!60
+
+2019-02-19 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue_2831' into 'master'
+ tiffcrop.c: fix invertImage() for bps 2 and 4
+
+ See merge request libtiff/libtiff!61
+
+2019-02-19 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue_2842' into 'master'
+ move _TIFFClampDoubleToFloat() to tif_aux.c
+
+ See merge request libtiff/libtiff!62
+
+2019-02-19 Even Rouault <even.rouault@spatialys.com>
+
+ tif_zip.c: allow reading and writing strips/tiles with more than 4 GB of compressed or uncompressed data
+
+ tif_dirread.c: when strip chopping is enabled, extend this mechanism to multi-strip uncompressed files with strips larger than 2GB to expose them as strips of ~500 MB
+
+2019-02-19 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'size_t_typo' into 'master'
+ CMakeLists.txt: fix TIFF_SIZE_T
+
+ See merge request libtiff/libtiff!59
+
+2019-02-12 Thomas Bernard <miniupnp@free.fr>
+
+ move _TIFFClampDoubleToFloat() to tif_aux.c.
+ the same function was declared in tif_dir.c and tif_dirwrite.c
+
+ see http://bugzilla.maptools.org/show_bug.cgi?id=2842
+
+2019-02-11 Thomas Bernard <miniupnp@free.fr>
+
+ tiffcrop.c: fix invertImage() for bps 2 and 4.
+ too much bytes were processed, causing a heap buffer overrun
+ http://bugzilla.maptools.org/show_bug.cgi?id=2831
+ the loop counter must be
+ for (col = 0; col < width; col += 8 / bps)
+
+ Also the values were not properly calculated. It should be
+ 255-x, 15-x, 3-x for bps 8, 4, 2.
+
+ But anyway it is easyer to invert all bits as 255-x = ~x, etc.
+ (substracting from a binary number composed of all 1 is like inverting
+ the bits)
+
+2019-02-11 Thomas Bernard <miniupnp@free.fr>
+
+ tiffcp.c: use INT_MAX.
+
+ check that (Tile Width)*(Samples/Pixel) do no overflow.
+ fixes bug 2833
+
+2019-02-03 Thomas Bernard <miniupnp@free.fr>
+
+ CMakeLists.txt: fix TIFF_SIZE_T.
+
+2019-02-02 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'master' into 'master'
+ Fix for simple memory leak that was assigned CVE-2019-6128.
+
+ See merge request libtiff/libtiff!50
+
+2019-02-02 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bug2835' into 'master'
+ tiff2ps: fix heap-buffer-overflow
+
+ See merge request libtiff/libtiff!53
+
+2019-02-02 Even Rouault <even.rouault@spatialys.com>
+
+ Fix warning (use of uninitialized value) added per d0a842c5dbad2609aed43c701a12ed12461d3405 (fixes https://gitlab.com/libtiff/libtiff/merge_requests/54#note_137742985)
+
+2019-02-02 Yuri Aksenov <yuri.aksenov@gmail.com>
+
+ fix fax2tiff.
+ see http://bugzilla.maptools.org/show_bug.cgi?id=2799
+ fixes d9bc8472e72549f29c0062c1cbd3d56f279f3be2
+
+2019-02-02 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffcrop' into 'master'
+ tiffcrop: shut up clang warnings
+
+ See merge request libtiff/libtiff!52
+
+2019-02-01 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bug2833' into 'master'
+ TIFFWriteDirectoryTagTransferfunction() : fix NULL dereferencing
+
+ See merge request libtiff/libtiff!54
+
+2019-02-01 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'gitignore' into 'master'
+ add test/ files to .gitignore
+
+ See merge request libtiff/libtiff!56
+
+2019-02-01 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'master' into 'master'
+ tif_dir: unset transferfunction field if necessary (CVE-2018-19210)
+
+ See merge request libtiff/libtiff!47
+
+2019-01-29 Thomas Bernard <miniupnp@free.fr>
+
+ add test/ files to .gitignore.
+
+2019-01-29 Thomas Bernard <miniupnp@free.fr>
+
+ TIFFWriteDirectoryTagTransferfunction() : fix NULL dereferencing.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2833
+
+ we must check the pointer is not NULL before memcmp() the memory
+
+2019-01-29 Thomas Bernard <miniupnp@free.fr>
+
+ tiff2ps: fix heap-buffer-overflow.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2834
+
+ usually the test (i < byte_count) is OK because the byte_count is divisible by samplesperpixel.
+ But if that is not the case, (i + ncomps) < byte_count should be used, or
+ maybe (i + samplesperpixel) <= byte_count
+
+2019-01-28 Thomas Bernard <miniupnp@free.fr>
+
+ tiffcrop: shut up clang warnings.
+ make the out filename building a bit more simple
+ and remove the use of strcat()
+
+2019-01-23 Scott Gayou <github.scott@gmail.com>
+
+ Fix for simple memory leak that was assigned CVE-2019-6128.
+ pal2rgb failed to free memory on a few errors. This was reported
+ here: http://bugzilla.maptools.org/show_bug.cgi?id=2836.
+
+2019-01-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ Fix tiff2ps error regarding "Inconsistent value of es" by allowing es to be zero. Problem was reported to the tiff mailing list by Julian H. Stacey on January 5, 2019.
+
+2018-12-13 Hugo Lefeuvre <hle@debian.org>
+
+ tif_dir: unset transferfunction field if necessary.
+ The number of entries in the transfer table is determined as following:
+
+ (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1
+
+ This means that whenever td->td_samplesperpixel or td->td_extrasamples are
+ modified we also need to make sure that the number of required entries in
+ the transfer table didn't change.
+
+ If it changed and the number of entries is higher than before we should
+ invalidate the transfer table field and free previously allocated values.
+ In the other case there's nothing to do, additional tf entries won't harm
+ and properly written code will just ignore them since spp - es < 1.
+
+ For instance this situation might happen when reading an OJPEG compressed
+ image with missing SamplesPerPixel tag. In this case the SamplesPerPixel
+ field might be updated after setting the transfer table.
+
+ see http://bugzilla.maptools.org/show_bug.cgi?id=2500
+
+ This commit addresses CVE-2018-19210.
+
+2018-12-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ Do not attempt to re-sync zip stream after reported data error from inflate().
+
+2018-12-07 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'resource-leaks' into 'master'
+ Fix two resource leaks
+
+ See merge request libtiff/libtiff!43
+
+2018-12-07 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'build-jbig' into 'master'
+ add jbig support to the fuzzer
+
+ See merge request libtiff/libtiff!42
+
+2018-12-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ tiffcrop.c: Avoid new clang warning about tools/tiffcrop.c "size argument in 'strncat' call appears to be size of the source".
+
+2018-11-28 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'webp_memleak' into 'master'
+ fixed mem leak in webp compression
+
+ See merge request libtiff/libtiff!48
+
+2018-11-28 Norman Barker <norman.barker@mapbox.com>
+
+ fixed mem leak in webp compression.
+
+2018-11-20 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'lossless_webp' into 'master'
+ fixed lossless webp compression config
+
+ See merge request libtiff/libtiff!46
+
+2018-11-20 Norman Barker <norman.barker@mapbox.com>
+
+ fixed lossless webp compression config.
+
+2018-11-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ snprintf porting fix for Visual Studio 2003.
+
+2018-11-18 Roger Leigh <rleigh@codelibre.net>
+
+ ci: Add pages job.
+
+2018-11-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ Change references from defunct ftp site to https site.
+
2018-11-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
* configure.ac: libtiff 4.0.10 released.
diff --git a/src/3rdparty/libtiff/RELEASE-DATE b/src/3rdparty/libtiff/RELEASE-DATE
index 94d1f0c..ad4fa62 100644
--- a/src/3rdparty/libtiff/RELEASE-DATE
+++ b/src/3rdparty/libtiff/RELEASE-DATE
@@ -1 +1 @@
-20181110
+20191103
diff --git a/src/3rdparty/libtiff/VERSION b/src/3rdparty/libtiff/VERSION
index 2d2d681..ee74734 100644
--- a/src/3rdparty/libtiff/VERSION
+++ b/src/3rdparty/libtiff/VERSION
@@ -1 +1 @@
-4.0.10
+4.1.0
diff --git a/src/3rdparty/libtiff/libtiff/libtiff.def b/src/3rdparty/libtiff/libtiff/libtiff.def
index 341c719..e34fac5 100644
--- a/src/3rdparty/libtiff/libtiff/libtiff.def
+++ b/src/3rdparty/libtiff/libtiff/libtiff.def
@@ -20,6 +20,7 @@ EXPORTS TIFFAccessTagMethods
TIFFDataWidth
TIFFDefaultStripSize
TIFFDefaultTileSize
+ TIFFDeferStrileArrayWriting
TIFFError
TIFFErrorExt
TIFFFdOpen
@@ -37,6 +38,7 @@ EXPORTS TIFFAccessTagMethods
TIFFFindField
TIFFFlush
TIFFFlushData
+ TIFFForceStrileArrayWriting
TIFFFreeDirectory
TIFFGetBitRevTable
TIFFGetClientInfo
@@ -49,6 +51,10 @@ EXPORTS TIFFAccessTagMethods
TIFFGetReadProc
TIFFGetSeekProc
TIFFGetSizeProc
+ TIFFGetStrileByteCount
+ TIFFGetStrileByteCountWithErr
+ TIFFGetStrileOffset
+ TIFFGetStrileOffsetWithErr
TIFFGetTagListCount
TIFFGetTagListEntry
TIFFGetUnmapFileProc
@@ -82,6 +88,7 @@ EXPORTS TIFFAccessTagMethods
TIFFReadEXIFDirectory
TIFFReadEncodedStrip
TIFFReadEncodedTile
+ TIFFReadFromUserBuffer
TIFFReadRGBAImage
TIFFReadRGBAImageOriented
TIFFReadRGBAStrip
diff --git a/src/3rdparty/libtiff/libtiff/mkg3states.c b/src/3rdparty/libtiff/libtiff/mkg3states.c
index 54fc059..2cb9174 100644
--- a/src/3rdparty/libtiff/libtiff/mkg3states.c
+++ b/src/3rdparty/libtiff/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/src/3rdparty/libtiff/libtiff/tif_aux.c b/src/3rdparty/libtiff/libtiff/tif_aux.c
index 33fb8a4..8188db5 100644
--- a/src/3rdparty/libtiff/libtiff/tif_aux.c
+++ b/src/3rdparty/libtiff/libtiff/tif_aux.c
@@ -30,31 +30,28 @@
#include "tiffiop.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
@@ -396,6 +393,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/src/3rdparty/libtiff/libtiff/tif_config.h b/src/3rdparty/libtiff/libtiff/tif_config.h
index 7306e52..73c602f 100644
--- a/src/3rdparty/libtiff/libtiff/tif_config.h
+++ b/src/3rdparty/libtiff/libtiff/tif_config.h
@@ -32,7 +32,7 @@
packages produce RGBA files but don't mark the alpha properly. */
/* #undef DEFAULT_EXTRASAMPLE_AS_ALPHA */
-/* enable deferred strip/tile offset/size loading (experimental) */
+/* enable deferred strip/tile offset/size loading */
/* #undef DEFER_STRILE_LOAD */
/* Define to 1 if you have the <assert.h> header file. */
diff --git a/src/3rdparty/libtiff/libtiff/tif_config.h.in b/src/3rdparty/libtiff/libtiff/tif_config.h.in
index eae07aa..523da3e 100644
--- a/src/3rdparty/libtiff/libtiff/tif_config.h.in
+++ b/src/3rdparty/libtiff/libtiff/tif_config.h.in
@@ -21,7 +21,7 @@
packages produce RGBA files but don't mark the alpha properly. */
#undef DEFAULT_EXTRASAMPLE_AS_ALPHA
-/* enable deferred strip/tile offset/size loading (experimental) */
+/* enable deferred strip/tile offset/size loading */
#undef DEFER_STRILE_LOAD
/* Define to 1 if you have the <assert.h> header file. */
diff --git a/src/3rdparty/libtiff/libtiff/tif_dir.c b/src/3rdparty/libtiff/libtiff/tif_dir.c
index 6f0b487..1e0a76c 100644
--- a/src/3rdparty/libtiff/libtiff/tif_dir.c
+++ b/src/3rdparty/libtiff/libtiff/tif_dir.c
@@ -29,7 +29,6 @@
* (and also some miscellaneous stuff)
*/
#include "tiffiop.h"
-#include <float.h>
/*
* These are used in the backwards compatibility code...
@@ -47,8 +46,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 +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;
@@ -1002,12 +1018,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 +1282,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 +1297,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 +1386,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/src/3rdparty/libtiff/libtiff/tif_dir.h b/src/3rdparty/libtiff/libtiff/tif_dir.h
index b2f5e69..e7f0667 100644
--- a/src/3rdparty/libtiff/libtiff/tif_dir.h
+++ b/src/3rdparty/libtiff/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/src/3rdparty/libtiff/libtiff/tif_dirread.c b/src/3rdparty/libtiff/libtiff/tif_dirread.c
index e80a3b1..6f90941 100644
--- a/src/3rdparty/libtiff/libtiff/tif_dirread.c
+++ b/src/3rdparty/libtiff/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/src/3rdparty/libtiff/libtiff/tif_dirwrite.c b/src/3rdparty/libtiff/libtiff/tif_dirwrite.c
index c15a28d..9e4d306 100644
--- a/src/3rdparty/libtiff/libtiff/tif_dirwrite.c
+++ b/src/3rdparty/libtiff/libtiff/tif_dirwrite.c
@@ -28,7 +28,6 @@
* Directory Write Support Routines.
*/
#include "tiffiop.h"
-#include <float.h>
#ifdef HAVE_IEEEFP
#define TIFFCvtNativeToIEEEFloat(tif, n, fp)
@@ -183,6 +182,51 @@ TIFFWriteDirectory(TIFF* tif)
}
/*
+ * 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
* written again. This will make a partially written TIFF file
@@ -193,7 +237,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 +572,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 +585,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 +596,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 +990,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 +1064,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 +1696,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 +1750,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 +2026,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 +2563,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;
@@ -2821,12 +2961,59 @@ _TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype,
}
/* -------------------------------------------------------------------- */
+/* 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 +3021,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 +3084,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 +3138,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 +3206,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/src/3rdparty/libtiff/libtiff/tif_flush.c b/src/3rdparty/libtiff/libtiff/tif_flush.c
index 881fac5..f7fa207 100644
--- a/src/3rdparty/libtiff/libtiff/tif_flush.c
+++ b/src/3rdparty/libtiff/libtiff/tif_flush.c
@@ -45,36 +45,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)
}
/*
+ * 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.
*
* Frank Warmerdam'2000: I modified this to return 1 if TIFF_BEENWRITING
diff --git a/src/3rdparty/libtiff/libtiff/tif_getimage.c b/src/3rdparty/libtiff/libtiff/tif_getimage.c
index a389ffb..4da785d 100644
--- a/src/3rdparty/libtiff/libtiff/tif_getimage.c
+++ b/src/3rdparty/libtiff/libtiff/tif_getimage.c
@@ -2969,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/src/3rdparty/libtiff/libtiff/tif_jpeg.c b/src/3rdparty/libtiff/libtiff/tif_jpeg.c
index f2ddc33..93ae2ea 100644
--- a/src/3rdparty/libtiff/libtiff/tif_jpeg.c
+++ b/src/3rdparty/libtiff/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/src/3rdparty/libtiff/libtiff/tif_luv.c b/src/3rdparty/libtiff/libtiff/tif_luv.c
index 46d2dff..6fe4858 100644
--- a/src/3rdparty/libtiff/libtiff/tif_luv.c
+++ b/src/3rdparty/libtiff/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
@@ -1501,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) {
@@ -1534,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:
@@ -1550,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/src/3rdparty/libtiff/libtiff/tif_lzw.c b/src/3rdparty/libtiff/libtiff/tif_lzw.c
index ac685dd..21064f2 100644
--- a/src/3rdparty/libtiff/libtiff/tif_lzw.c
+++ b/src/3rdparty/libtiff/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/src/3rdparty/libtiff/libtiff/tif_ojpeg.c b/src/3rdparty/libtiff/libtiff/tif_ojpeg.c
index 27385d8..bf0d1a2 100644
--- a/src/3rdparty/libtiff/libtiff/tif_ojpeg.c
+++ b/src/3rdparty/libtiff/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/src/3rdparty/libtiff/libtiff/tif_open.c b/src/3rdparty/libtiff/libtiff/tif_open.c
index c574c45..3cb53d4 100644
--- a/src/3rdparty/libtiff/libtiff/tif_open.c
+++ b/src/3rdparty/libtiff/libtiff/tif_open.c
@@ -131,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;
@@ -181,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,
@@ -262,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/src/3rdparty/libtiff/libtiff/tif_pixarlog.c b/src/3rdparty/libtiff/libtiff/tif_pixarlog.c
index 12c2372..6264090 100644
--- a/src/3rdparty/libtiff/libtiff/tif_pixarlog.c
+++ b/src/3rdparty/libtiff/libtiff/tif_pixarlog.c
@@ -637,12 +637,13 @@ PixarLogGuessDataFmt(TIFFDirectory *td)
static tmsize_t
multiply_ms(tmsize_t m1, tmsize_t m2)
{
- return _TIFFMultiplySSize(NULL, m1, m2, NULL);
+ 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;
@@ -812,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",
@@ -1148,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/src/3rdparty/libtiff/libtiff/tif_print.c b/src/3rdparty/libtiff/libtiff/tif_print.c
index 1d86adb..a073794 100644
--- a/src/3rdparty/libtiff/libtiff/tif_print.c
+++ b/src/3rdparty/libtiff/libtiff/tif_print.c
@@ -652,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;
@@ -665,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/src/3rdparty/libtiff/libtiff/tif_read.c b/src/3rdparty/libtiff/libtiff/tif_read.c
index aa31054..527fadd 100644
--- a/src/3rdparty/libtiff/libtiff/tif_read.c
+++ b/src/3rdparty/libtiff/libtiff/tif_read.c
@@ -60,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 */
@@ -102,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);
@@ -169,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 */
@@ -223,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)) {
@@ -240,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;
}
@@ -282,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) )
{
@@ -341,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 )
@@ -396,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;
@@ -593,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);
@@ -628,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;
}
@@ -673,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,
@@ -714,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))
@@ -732,16 +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];
- bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount, module);
- if (bytecountm == 0) {
+ 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.
@@ -752,12 +768,9 @@ 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];
+ 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,
@@ -810,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
@@ -828,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,
@@ -836,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;
@@ -865,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;
@@ -1080,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,
@@ -1119,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;
@@ -1177,11 +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 = _TIFFCastUInt64ToSSize(tif, bytecount64, module);
- if( bytecountm == 0 ) {
+ 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));
@@ -1197,12 +1206,9 @@ 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];
+ 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,
@@ -1255,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);
}
@@ -1290,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;
@@ -1349,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);
@@ -1416,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);
@@ -1439,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)));
@@ -1456,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);
@@ -1489,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)));
@@ -1504,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/src/3rdparty/libtiff/libtiff/tif_strip.c b/src/3rdparty/libtiff/libtiff/tif_strip.c
index 2366acf..c08c60a 100644
--- a/src/3rdparty/libtiff/libtiff/tif_strip.c
+++ b/src/3rdparty/libtiff/libtiff/tif_strip.c
@@ -140,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)
{
diff --git a/src/3rdparty/libtiff/libtiff/tif_thunder.c b/src/3rdparty/libtiff/libtiff/tif_thunder.c
index 2388dbb..db6383a 100644
--- a/src/3rdparty/libtiff/libtiff/tif_thunder.c
+++ b/src/3rdparty/libtiff/libtiff/tif_thunder.c
@@ -122,17 +122,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/src/3rdparty/libtiff/libtiff/tif_write.c b/src/3rdparty/libtiff/libtiff/tif_write.c
index a31ecd1..33e803c 100644
--- a/src/3rdparty/libtiff/libtiff/tif_write.c
+++ b/src/3rdparty/libtiff/libtiff/tif_write.c
@@ -128,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;
@@ -176,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.
@@ -222,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);
@@ -234,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() */
@@ -402,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;
@@ -537,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);
@@ -572,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);
}
@@ -610,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");
@@ -628,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);
}
@@ -684,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)
@@ -697,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;
@@ -720,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
@@ -734,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);
@@ -747,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;
@@ -774,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/src/3rdparty/libtiff/libtiff/tif_zip.c b/src/3rdparty/libtiff/libtiff/tif_zip.c
index 9d4bceb..c750773 100644
--- a/src/3rdparty/libtiff/libtiff/tif_zip.c
+++ b/src/3rdparty/libtiff/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/src/3rdparty/libtiff/libtiff/tiffio.h b/src/3rdparty/libtiff/libtiff/tiffio.h
index 31c2e67..198481d 100644
--- a/src/3rdparty/libtiff/libtiff/tiffio.h
+++ b/src/3rdparty/libtiff/libtiff/tiffio.h
@@ -411,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);
@@ -468,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);
@@ -488,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/src/3rdparty/libtiff/libtiff/tiffiop.h b/src/3rdparty/libtiff/libtiff/tiffiop.h
index 558484f..45a7932 100644
--- a/src/3rdparty/libtiff/libtiff/tiffiop.h
+++ b/src/3rdparty/libtiff/libtiff/tiffiop.h
@@ -80,6 +80,16 @@ extern int snprintf(char* str, size_t size, const char* format, ...);
#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;
@@ -130,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 */
@@ -379,6 +392,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,
diff --git a/src/3rdparty/libtiff/libtiff/tiffvers.h b/src/3rdparty/libtiff/libtiff/tiffvers.h
index 403d61b..aa3f613 100644
--- a/src/3rdparty/libtiff/libtiff/tiffvers.h
+++ b/src/3rdparty/libtiff/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
diff --git a/src/3rdparty/libtiff/port/snprintf.c b/src/3rdparty/libtiff/port/snprintf.c
index 1c4ac08..3542ab7 100644
--- a/src/3rdparty/libtiff/port/snprintf.c
+++ b/src/3rdparty/libtiff/port/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/src/3rdparty/libtiff/qt_attribution.json b/src/3rdparty/libtiff/qt_attribution.json
index e4f2db3..d51ee4a 100644
--- a/src/3rdparty/libtiff/qt_attribution.json
+++ b/src/3rdparty/libtiff/qt_attribution.json
@@ -6,7 +6,7 @@
"Description": "",
"Homepage": "http://www.simplesystems.org/libtiff/",
- "Version": "4.0.10",
+ "Version": "4.1.0",
"License": "libtiff License",
"LicenseId": "libtiff",
"LicenseFile": "COPYRIGHT",