diff options
author | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2022-05-30 10:14:11 +0200 |
---|---|---|
committer | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2022-05-31 15:56:50 +0200 |
commit | 372ff593c65cdea4616cb2d6e1c8a53e6b22674d (patch) | |
tree | 317f99112ee309ca6301c4d767d6bff15b61eacf | |
parent | 798a9283a43592261856af898a9453ef4b2f2167 (diff) |
Update bundled libtiff to version 4.4.0
[ChangeLog][Third-Party Code] Bundled libtiff was updated to version 4.4.0
Pick-to: 6.3 6.2 5.15
Fixes: QTBUG-103337
Task-number: QTBUG-103671
Change-Id: I94a26d2d2186e4ea881588a04b0eafae0432be29
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
32 files changed, 5210 insertions, 2823 deletions
diff --git a/src/3rdparty/libtiff/ChangeLog b/src/3rdparty/libtiff/ChangeLog index 9bda39c..b1eb5cd 100644 --- a/src/3rdparty/libtiff/ChangeLog +++ b/src/3rdparty/libtiff/ChangeLog @@ -1,3 +1,1345 @@ +2022-05-16 Even Rouault <even.rouault@spatialys.com> + + libtiff v4.4.0 released + +2022-05-16 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'pkgconf_abs_path' into 'master' + Handle absolute paths in pkg-config file + + See merge request libtiff/libtiff!333 + +2022-05-16 Miloš Komarčević <miloskomarcevic@aim.com> + + Handle absolute paths in pkg-config file. + +2022-05-15 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'fix-tests-with-ro-source-dir' into 'master' + cmake: allow running the tests with a read-only source directory + + See merge request libtiff/libtiff!332 + +2022-05-15 Alex Richardson <alexrichardson@google.com> + + cmake: allow running the tests with a read-only source directory. + Prior to this commit CTest would invoke all simple_tests tests with the + current working directory set to the source directory. However, some of + the tests (e.g. rewrite) will output files to the current working + directory and will therefore fail when run with a read-only source + directory. This can happen e.g. when testing a cross-compiled version of + libtiff where the sources are mounted read-only in the virtual machine. + + Simply changing the working directory to CMAKE_CURRENT_BINARY_DIR allows + all but raw_decode to pass. The raw_decode test looks for files in the + source directory, and uses the `srcdir` environment variable to find, so + we also have to add a set_tests_properties() call to specify that env var. + +2022-05-14 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'tiffcrop_pipeline_error' into 'master' + tiffcrop: Fixes complain of pipeline "cmake-ninja-arm64" about abs() on... + + See merge request libtiff/libtiff!331 + +2022-05-14 Su Laus <sulau@freenet.de> + + tiffcrop: Fixes complain of pipeline "cmake-ninja-arm64" about abs() on... + +2022-05-14 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'TIFFField_SetGetSize_CountSize' into 'master' + Public functions TIFFFieldSetGetSize() and TIFFieldSetGetCountSize() added. + + See merge request libtiff/libtiff!284 + +2022-05-14 Su Laus <sulau@freenet.de> + + Public functions TIFFFieldSetGetSize() and TIFFieldSetGetCountSize() added. + +2022-05-13 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'jondo-master-patch-87274' into 'master' + Replace add_compile_definitions for CMake versions before 3.12 (#238) + + See merge request libtiff/libtiff!330 + +2022-05-13 Robert Pollak <robert.pollak@posteo.net> + + Replace add_compile_definitions for CMake versions before 3.12 (#238) + +2022-05-13 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'master' into 'master' + Remove incorrect assert. + + See merge request libtiff/libtiff!329 + +2022-05-13 Ben Laurie <benl@google.com> + + Remove incorrect assert. + +2022-05-10 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'Fix_Issue#330' into 'master' + tiffcrop: Fix issue #330 and some more from 320 to 349 + + Closes #330 + + See merge request libtiff/libtiff!298 + +2022-05-10 Su Laus <sulau@freenet.de> + + tiffcrop: Fix issue #330 and some more from 320 to 349. + +2022-05-10 Even Rouault <even.rouault@spatialys.com> + + test_signed_tags.c: fix CID 1504376. + +2022-05-10 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'fix_#29_tiffcp_orientationTag' into 'master' + tiffcp: Fix incomprehensible setting of orientation tag (fixes #29) + + Closes #29 + + See merge request libtiff/libtiff!327 + +2022-05-10 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'palette-8bit' into 'master' + tiff2pdf: handle 8-bit palette colormap + + See merge request libtiff/libtiff!328 + +2022-05-09 Jay Berkenbilt <ejb@ql.org> + + tiff2pdf: handle 8-bit palette colormap. + If all the colors in a palette are in the range [0, 255], treat the + palette as an 8-bit colormap. This workaround already exists elsewhere + in the software including in tiff2ps. + +2022-05-08 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'fix_#40_ReadSignedTags' into 'master' + Reading of signed tags added (fixes #40) + + Closes #40 + + See merge request libtiff/libtiff!326 + +2022-05-08 Su Laus <sulau@freenet.de> + + Reading of signed tags added (fixes #40) + +2022-05-08 Even Rouault <even.rouault@spatialys.com> + + Fix typos in comments. + +2022-05-08 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'fix_400' into 'master' + tiffcp: avoid buffer overflow in "mode" string (fixes #400) + + Closes #400 + + See merge request libtiff/libtiff!323 + +2022-05-08 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'CheckForBigTiff' into 'master' + TIFFIsBigTiff() function added. + + See merge request libtiff/libtiff!325 + +2022-05-08 Su Laus <sulau@freenet.de> + + TIFFIsBigTiff() function added. + +2022-05-01 Su_Laus <sulau@freenet.de> + + tiffcp: Fix incomprehensible setting of orientation tag (fixes #29) + +2022-04-23 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'fix_#8_FreeAnonTag' into 'master' + extra flag for anonymous (unknown) tags (fixes #8) + + Closes #400 et #8 + + See merge request libtiff/libtiff!324 + +2022-04-22 Even Rouault <even.rouault@spatialys.com> + + tif_lzw.c: fix potential out-of-bounds error when trying to read in the same tile/strip after an error has occured (fixes #410) + +2022-04-06 Su_Laus <sulau@freenet.de> + + extra flag for anonymous (unknown) tags (fixes #8) + +2022-04-02 Su_Laus <sulau@freenet.de> + + tiffcp: avoid buffer overflow in "mode" string (fixes #400) + +2022-03-21 Even Rouault <even.rouault@spatialys.com> + + avoid hang in TIFFRewriteDirectory() if a classic file > 4 GB is attempted to be created + Fixes https://github.com/OSGeo/gdal/issues/5479 + +2022-03-19 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'Correct_tag_auto-registration_description' into 'master' + Correct reading description for anonymous tag auto-registration in addingtags.html (closes 353) + + Closes #353 + + See merge request libtiff/libtiff!320 + +2022-03-19 Su Laus <sulau@freenet.de> + + Correct reading description for anonymous tag auto-registration in addingtags.html (closes 353) + +2022-03-18 Even Rouault <even.rouault@spatialys.com> + + tif_lzw.c: avoid harmless unsigned-integer-overflow (https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=45741) + +2022-03-17 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'fix_396' into 'master' + tiffcp: do not try to fetch compressor-specific tags when not appropriate (fixes #396) + + Closes #396 + + See merge request libtiff/libtiff!316 + +2022-03-17 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'Fix_cmake_warnings' into 'master' + Fix some CMake warnings + + See merge request libtiff/libtiff!319 + +2022-03-17 Su Laus <sulau@freenet.de> + + Fix some CMake warnings. + +2022-03-17 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'lzw_decode_improvements' into 'master' + LZWDecode(): major speed improvements + + See merge request libtiff/libtiff!318 + +2022-03-16 Even Rouault <even.rouault@spatialys.com> + + LZWDecode(): major speed improvements. + This mostly comes from dealing specifically with codes that expand to + 2, 3 and 4 bytes or more to avoid branches, and dealing with longer + repeated sequences (e.g. lots of bytes to 0). + + With the following bench.c, execution time is 32% faster on a 8000x8000 + 4 bands uint16 predictor=2 image that has a 1.6x compression ratio. with + gcc 9.4.0, on x86_64 + + bench.c: + ``` + #include "tiffio.h" + #include <stdlib.h> + #include <stdint.h> + + int main(int argc, char* argv[]) + { + if( argc != 2 ) + { + fprintf(stderr, "Usage: ./bench my.tif\n"); + exit(1); + } + TIFF* tif = TIFFOpen(argv[1], "r"); + if( tif == NULL ) + { + fprintf(stderr, "Cannot open %s\n", argv[1]); + exit(1); + } + if( !TIFFIsTiled(tif) ) + { + fprintf(stderr, "Only tiled image supported\n"); + exit(1); + } + int tilesize = (int)TIFFTileSize(tif); + char* c = malloc(tilesize); + if( c == NULL ) + { + fprintf(stderr, "Out of memory\n"); + exit(1); + } + const uint32_t numtiles = TIFFNumberOfTiles(tif); + //int numloops = 4 * (int)(1e9 / ((double)tilesize * numtiles)); + //printf("Number of loops: %d\n", numloops); + int numloops = 1; + for(int i =0; i< numloops; i++) + { + for(uint32_t tileindex = 0; tileindex < numtiles; tileindex++ ) + { + TIFFReadEncodedTile(tif, tileindex, c, tilesize); + } + } + free(c); + TIFFClose(tif); + return 0; + } + ``` + +2022-03-16 Even Rouault <even.rouault@spatialys.com> + + LZWDecode(): modest speed improvement: fetch input data by chunks of the largest natural integer of the architecture + +2022-03-14 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'kmilos-master-patch-45885' into 'master' + Correct fix for the pkgconf file relative paths + + See merge request libtiff/libtiff!317 + +2022-03-10 Even Rouault <even.rouault@spatialys.com> + + tif_lzw.c: make LZW_CHECKEOS non-optional. + + tiffsplit.c: fix compiler warning on 32-bit. + +2022-03-10 Miloš Komarčević <miloskomarcevic@aim.com> + + Correct fix for the pkgconf file relative paths. + +2022-03-10 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'issue-278' into 'master' + fix heap buffer overflow in tiffcp (#278) + + Closes #278 + + See merge request libtiff/libtiff!311 + +2022-03-10 4ugustus <wangdw.augustus@qq.com> + + fix heap buffer overflow in tiffcp (#278) + +2022-03-09 Even Rouault <even.rouault@spatialys.com> + + tiffcp: do not try to fetch compressor-specific tags when not appropriate (fixes #396) + +2022-03-09 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'i_am_a_unsympathetic_person' into 'master' + index.html: make it clear that I'm a unsympathetic person + + See merge request libtiff/libtiff!315 + +2022-03-09 Even Rouault <even.rouault@spatialys.com> + + index.html: make it clear that I'm a unsympathetic person. + +2022-03-08 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'Fix_Issue#395' into 'master' + tiffcrop: fix issue #395: generation of strange section images. + + Closes #395 + + See merge request libtiff/libtiff!312 + +2022-03-08 Su Laus <sulau@freenet.de> + + tiffcrop: fix issue #395: generation of strange section images. + +2022-03-08 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'Fix_Issue#380' into 'master' + tiffcrop: fix issue #380 and #382 heap buffer overflow in extractImageSection + + Closes #382 et #380 + + See merge request libtiff/libtiff!307 + +2022-03-08 Su Laus <sulau@freenet.de> + + tiffcrop: fix issue #380 and #382 heap buffer overflow in extractImageSection + +2022-03-08 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'issue-392' into 'master' + add checks for return value of limitMalloc (#392) + + Closes #392 + + See merge request libtiff/libtiff!314 + +2022-03-08 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'issue-393' into 'master' + fix the FPE in tiffcrop (#393) + + Closes #393 + + See merge request libtiff/libtiff!310 + +2022-03-08 4ugustus <wangdw.augustus@qq.com> + + fix the FPE in tiffcrop (#393) + +2022-03-08 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'kmilos-master-patch-56785' into 'master' + Fix pkgconf file relative paths + + Closes #394 + + See merge request libtiff/libtiff!309 + +2022-03-07 Augustus <wangdw.augustus@qq.com> + + add checks for return value of limitMalloc (#392) + +2022-03-02 Miloš Komarčević <miloskomarcevic@aim.com> + + Fix pkgconf file relative paths. + +2022-02-25 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'fix_385' into 'master' + tif_jbig.c: fix crash when reading a file with multiple IFD in memory-mapped... + + Closes #385 + + See merge request libtiff/libtiff!306 + +2022-02-24 Even Rouault <even.rouault@spatialys.com> + + tif_jbig.c: fix crash when reading a file with multiple IFD in memory-mapped mode and when bit reversal is needed (fixes #385) + +2022-02-24 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'string_size_limit' into 'master' + _TIFFVSetField(): when passing a string without explicit length, check that... + + See merge request libtiff/libtiff!304 + +2022-02-24 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'TIFFClientOpen_cleanup' into 'master' + TIFFClientOpen(): remove useless initializations of tif_rawcc and tif_flags... + + See merge request libtiff/libtiff!303 + +2022-02-20 Even Rouault <even.rouault@spatialys.com> + + Remove extra word in comment. + + TIFFPrintDirectory(): avoid potential multi-threading issue when reading the DotRange tag + The severity of the issue would be low (mix of values displayed) and the + time window where that would occur would be short. + + Constify signature of _TIFFsetXXXXArray() functions, and remove unused _TIFFsetString() + + _TIFFVSetField(): when passing a string without explicit length, check that the length doesn't except the 1 << 31 maximum bytes we support + +2022-02-19 Even Rouault <even.rouault@spatialys.com> + + tiffsplit.c: fix use after free introduced in master per commit 8ed97f401552a2b4300d3c489b03dcada86a21fd (related to #290) + +2022-02-19 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'Fix_Issue#284' into 'master' + tiff2ps: In limitMalloc() check for negative size (fixes #284) + + Closes #284 + + See merge request libtiff/libtiff!300 + +2022-02-19 Su Laus <sulau@freenet.de> + + tiff2ps: In limitMalloc() check for negative size (fixes #284) + +2022-02-19 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'fix_288' into 'master' + tiffinfo: limit more memory allocations using -M switch (fixes #288) + + Closes #288 + + See merge request libtiff/libtiff!299 + +2022-02-19 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'Fix_Issue#290' into 'master' + tiffsplit: limitMalloc() and getopt() introduced and more error messages. (fixes #290) + + Closes #290 + + See merge request libtiff/libtiff!301 + +2022-02-19 Su Laus <sulau@freenet.de> + + tiffsplit: limitMalloc() and getopt() introduced and more error messages. (fixes #290) + +2022-02-19 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'Fix_Issue#273_#275' into 'master' + tiffcrop: buffsize check formula in loadImage() amended (fixes #273,#275) + + Closes #275 et #273 + + See merge request libtiff/libtiff!302 + +2022-02-19 Su Laus <sulau@freenet.de> + + tiffcrop: buffsize check formula in loadImage() amended (fixes #273,#275) + +2022-02-19 Even Rouault <even.rouault@spatialys.com> + + TIFFClientOpen(): remove useless initializations of tif_rawcc and tif_flags after TIFFReadDirectory() + Those initializations date back to the initial commit of libtiff, but I + strongly suspect there are no longer needed those days. + Setting tif_rawcc to (tmsize_t)-1 is weird. AFAICS, nowhere else in the library + -1 is used as a special markeri for that field. Immediately after TIFFReadDirectory() + returns it is set to 0, and this is the value used in tif_read.c/tif_write.c to + reset it. + And setting the TIFF_BUFFERSETUP bit of tif_flags is even more + suspicious as the only place where it is set otherwise is in + TIFFWriteBufferSetup(). I suspect this bogus setting of the flag was the + reason for commit dbf2339a1 where BUFFERCHECK() in addition to checking + the bit also checked the tif_rawdata against nullptr. + + If setting those 2 fields was needed, it would mean that TIFFClientOpen() with the + 'h' hint to disable automatic TIFFReadDirectory() would be broken, + because someone issuing a manual TIFFReadDirectory() couldn't set them, + as being private members. + + The libtiff test suite is happy with that change, and the GDAL one too. + +2022-02-19 Even Rouault <even.rouault@spatialys.com> + + TIFFFetchNormalTag(): speed optimization when reading a (very large) nul-terminated ASCII tag + + TIFFWriteDirectoryTagData(): turn assertion on data length into a runtime check + For example, the assertion could actually be triggered when writing an + ASCII tag with more than 1 << 31 bytes. + +2022-02-17 Even Rouault <even.rouault@spatialys.com> + + TIFFFetchNormalTag(): avoid calling memcpy() with a null source pointer and size of zero (fixes #383) + +2022-02-15 Roger Leigh <rleigh@codelibre.net> + + Merge branch 'tl/fix-cpack' into 'master' + Fix packaging with CPack + + See merge request libtiff/libtiff!292 + +2022-02-11 Even Rouault <even.rouault@spatialys.com> + + tiffinfo: limit more memory allocations using -M switch (fixes #288) + + tif_dirwrite.c: take into account COMPRESSION_JXL. + +2022-02-11 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'predictor_2_64bit' into 'master' + Predictor 2 (horizontal differenciation): support 64-bit + + See merge request libtiff/libtiff!296 + +2022-02-10 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'Fix_Issue#365' into 'master' + tiff2pdf: Fixes issues #365, #258 and #257 related to initializing 't2p->pdf_compressionquality'. + + Closes #257, #258 et #365 + + See merge request libtiff/libtiff!297 + +2022-02-10 Su Laus <sulau@freenet.de> + + tiff2pdf: Fixes issues #365, #258 and #257 related to initializing 't2p->pdf_compressionquality'. + +2022-02-09 Even Rouault <even.rouault@spatialys.com> + + Predictor 2 (horizontal differenciation): support 64-bit. + There's no reason not to support 64-bit. The TIFF 6 specification + doesn't say anything about that (and even mention 4-bit, which we don't + support) + +2022-02-09 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'Fix_Issue#352' into 'master' + tiffcrop.c: Fix issue #352 heap-buffer-overflow by correcting uint32_t underflow. + + Closes #352 + + See merge request libtiff/libtiff!294 + +2022-02-09 Su Laus <sulau@freenet.de> + + tiffcrop.c: Fix issue #352 heap-buffer-overflow by correcting uint32_t underflow. + +2022-02-08 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'custom_dir_EXIF_Coverity_fixes' into 'master' + Fix Coverity Scan report issues for custom_dir_EXIF_231.c and test_directory.c + + See merge request libtiff/libtiff!295 + +2022-02-08 Su Laus <sulau@freenet.de> + + Fix Coverity Scan report issues for custom_dir_EXIF_231.c and test_directory.c + +2022-02-06 Roger Leigh <rleigh@codelibre.net> + + Merge branch 'cmake-test' into 'master' + Correct CMake testing + + Closes #317 + + See merge request libtiff/libtiff!291 + +2022-02-06 Even Rouault <even.rouault@spatialys.com> + + LogLuvEncode32(): avoid undefined behaviour of left shift on a signed integer + + TIFFFetchStripThing(): avoid calling memcpy() with a null source pointer and size of zero (fixes #362) + +2022-02-05 Even Rouault <even.rouault@spatialys.com> + + TIFFReadDirectory(): avoid calling memcpy() with a null source pointer and size of zero (fixes #362) + +2022-01-29 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'Jamaika1-master-patch-68264' into 'master' + Added stdlib.h + + See merge request libtiff/libtiff!293 + +2022-01-29 Jamaika <lukaszcz18@wp.pl> + + tif_win32.c: include stdlib.h. + +2022-01-28 Timothy Lyanguzov <timothy.lyanguzov@sap.com> + + Fix packaging with CPack. + Replace all CMAKE_INSTALL_FULL_<DIR> with CMAKE_INSTALL_<DIR> to allow CPack setting CMAKE_INSTALL_PREFIX + +2022-01-25 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'master' into 'master' + Fix the global-buffer-overflow in tiffset + + See merge request libtiff/libtiff!287 + +2022-01-25 4ugustus <wangdw.augustus@qq.com> + + tiffset: fix global-buffer-overflow for ASCII tags where count is required (fixes #355) + +2022-01-23 Roger Leigh <rleigh@codelibre.net> + + Merge branch 'autogen' into 'master' + Fix autogen.sh permissions issues during mv + + See merge request libtiff/libtiff!290 + +2022-01-23 Roger Leigh <rleigh@codelibre.net> + + Correct CMake testing. + * Use functions rather than macros to avoid problems with variables in + conditions (since macro arguments are not variables) + * Conditionally add to file lists and test program lists based upon the + configuration options (e.g. JPEG and old-JPEG availability) + * Sync tests, files and option usage with current automake usage + +2022-01-19 Will Cohen <willcohen@users.noreply.github.com> + + autogen.sh: mv -f for config.sub and config.guess. + +2022-01-12 Even Rouault <even.rouault@spatialys.com> + + TIFFYCbCrToRGBInit(): avoid Integer-overflow in gdal_TIFFYCbCrToRGBInit. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=43559 + +2022-01-10 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'fix_TIFFFillStrip_wrong_check' into 'master' + Fix sanity check in TIFFFillStrip()/TIFFFillStrile() + + See merge request libtiff/libtiff!288 + +2022-01-10 Even Rouault <even.rouault@spatialys.com> + + TIFFFillStrip()/TIFFFillStrile(): remove useless test. + + Fix sanity check in TIFFFillStrip()/TIFFFillStrile() + A sanity check comparing the compressed vs uncompressed file that was + originally written 'correctly' but relied on undefined behaviour was + changed in 1b5e3b6a23827c33acf19ad50ce5ce78f12b3773 in an incorrect way. + Fix that. Credits to @burn for spotting this in + https://gitlab.com/libtiff/libtiff/-/issues/343#note_806089714 + +2021-12-29 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'Fix_FieldName_NULL' into 'master' + Fix Issue #354 Segmentation Fault due to field_name=NULL + + See merge request libtiff/libtiff!285 + +2021-12-29 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'mingw-static' into 'master' + build: Fix static library imports in mingw + + See merge request libtiff/libtiff!286 + +2021-12-29 Biswapriyo Nath <nathbappai@gmail.com> + + build: Fix static library imports in mingw. + This defines LERC_STATIC while creating libtiff static library + in Win32 platform in presence of lerc library. Otherwise, the + static library import lerc APIs with dllimport attribute and + thus linked with shared lerc library. + +2021-12-28 Su_Laus <sulau@freenet.de> + + Fix Issue #354 Segmentation Fault due to field_name=NULL. + +2021-12-17 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'fix_342' into 'master' + TIFFGetField(TIFFTAG_STRIPBYTECOUNTS/TIFFTAG_STRIPOFFSETS): return error if... + + Closes #342 + + See merge request libtiff/libtiff!283 + +2021-12-16 Even Rouault <even.rouault@spatialys.com> + + TIFFGetField(TIFFTAG_STRIPBYTECOUNTS/TIFFTAG_STRIPOFFSETS): return error if returned pointer is NULL (fixes #342) + + tiff2pdf: validate TIFFGetField(input, TIFFTAG_STRIPBYTECOUNTS, &sbc) return (fixes #342) + +2021-12-16 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'master' into 'master' + fix raw2tiff floating point exception(fixes #338) + + Closes #338 + + See merge request libtiff/libtiff!282 + +2021-12-16 t.feng <t.feng94@foxmail.com> + + raw2tiff: check that band number if not zero to avoid floating point exception(fixes #338) + +2021-12-14 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'fix_337' into 'master' + OJPEG: avoid assertion when using TIFFReadScanline() (fixes #337) + + Closes #337 + + See merge request libtiff/libtiff!280 + +2021-12-13 Even Rouault <even.rouault@spatialys.com> + + OJPEG: avoid assertion when using TIFFReadScanline() (fixes #337) + Note: my analyis of the issue would be that the use of the scanline API + is currently propably broken with OJPEG. + +2021-12-10 Even Rouault <even.rouault@spatialys.com> + + JPEG 12bit: make it easier for GDAL's RENAME_INTERNAL_LIBTIFF_SYMBOLS mode + +2021-12-09 Even Rouault <even.rouault@spatialys.com> + + tif_lzw.c: other warning fixes. + + tif_lzw.c: fix warnings of previous commit. + +2021-12-09 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'lzw_2gb_windows' into 'master' + LZW codec: fix support for strips/tiles > 2 GB on Windows + + See merge request libtiff/libtiff!279 + +2021-12-08 Even Rouault <even.rouault@spatialys.com> + + LZW codec: fix support for strips/tiles > 2 GB on Windows. + +2021-12-07 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'fix_287' into 'master' + tiffinfo: add a -M switch to define the maximum heap allocation, and default... + + Closes #287 + + See merge request libtiff/libtiff!278 + +2021-12-06 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'fix_319' into 'master' + TIFFReadDirectory: fix OJPEG hack (fixes #319) + + Closes #319 + + See merge request libtiff/libtiff!277 + +2021-12-06 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'fix_309' into 'master' + TIFFAppendToStrip(): fix rewrite-in-place logic (fixes #309) + + Closes #309 + + See merge request libtiff/libtiff!276 + +2021-12-05 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'b1' into 'master' + Fix resource leak on error path + + See merge request libtiff/libtiff!263 + +2021-12-05 bonniegong <yuanjungong96@gmail.com> + + rast2tiff: Fix resource leak on error path. + +2021-12-05 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'tiffsplit-leak' into 'master' + tiffsplit.c: Fix memleak before exit + + See merge request libtiff/libtiff!270 + +2021-12-05 Even Rouault <even.rouault@spatialys.com> + + tiffinfo: add a -M switch to define the maximum heap allocation, and default it to 256 MiB (fixes #287) + + tiffinfo: fix read of invalid pointer in TIFFReadRawDataTiled() (fixes #295) + +2021-12-05 Even Rouault <even.rouault@spatialys.com> + + TIFFReadDirectory: fix OJPEG hack (fixes #319) + to avoid having the size of the strip arrays inconsistent with the + number of strips returned by TIFFNumberOfStrips(), which may cause + out-ouf-bounds array read afterwards. + + One of the OJPEG hack that alters SamplesPerPixel may influence the + number of strips. Hence compute tif_dir.td_nstrips only afterwards. + +2021-12-04 Even Rouault <even.rouault@spatialys.com> + + TIFFAppendToStrip(): fix rewrite-in-place logic (fixes #309) + Properly reset tif_curoff when writing strips/tiles + +2021-12-03 Even Rouault <even.rouault@spatialys.com> + + TIFFReInitJPEG_12(): avoid warning about unused variable in -DNDEBUG. + +2021-12-01 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'fix_316' into 'master' + TIFFReadCustomDirectory(): avoid crash when reading SubjectDistance tag on a non EXIF directory + + Closes #316 + + See merge request libtiff/libtiff!273 + +2021-12-01 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'VisualStudio_warnings_suppress' into 'master' + Suppress unnecessary warnings in Visual Studio in AppVeyor test. + + See merge request libtiff/libtiff!234 + +2021-11-30 Even Rouault <even.rouault@spatialys.com> + + TIFFReadCustomDirectory(): avoid crash when reading SubjectDistance tag on a non EXIF directory + Fixes #316 + + The Valgrind trace was + ``` + TIFFReadCustomDirectory: Warning, Unknown field with tag 37382 (0x9206) encountered. + ==3277355== Invalid read of size 1 + ==3277355== at 0x4842B60: memmove (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) + ==3277355== by 0x48BB799: _TIFFmemcpy (tif_unix.c:346) + ==3277355== by 0x485B3CB: _TIFFVSetField (tif_dir.c:647) + ==3277355== by 0x485C125: TIFFVSetField (tif_dir.c:890) + ==3277355== by 0x485BEDC: TIFFSetField (tif_dir.c:834) + ==3277355== by 0x486DA9A: TIFFFetchSubjectDistance (tif_dirread.c:5826) + ==3277355== by 0x4869E35: TIFFReadCustomDirectory (tif_dirread.c:4530) + ==3277355== by 0x4869F0A: TIFFReadGPSDirectory (tif_dirread.c:4564) + ==3277355== by 0x10AA7A: main (tiffinfo.c:171) + ==3277355== Address 0x3fc856aaaaaaaaab is not stack'd, malloc'd or (recently) free'd + ==3277355== + ``` + +2021-11-29 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'add-null-check' into 'master' + Added missing null check. + + See merge request libtiff/libtiff!274 + +2021-11-28 Dirk Lemstra <dirk@lemstra.org> + + Added missing null check. + +2021-11-26 Even Rouault <even.rouault@spatialys.com> + + tif_print.c: remove duplicated if() in previous commit. + +2021-11-26 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'GPS_Print_BugFix' into 'master' + Fix Segmentation fault printing GPS directory if Altitude tag is present (tif_print.c/tiffinfo.c) + + See merge request libtiff/libtiff!272 + +2021-11-26 Su Laus <sulau@freenet.de> + + Fix Segmentation fault printing GPS directory if Altitude tag is present (tif_print.c/tiffinfo.c) + +2021-11-01 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'cmake_tiffconf' into 'master' + Fix STRIPCHOP_DEFAULT value in CMake builds + + See merge request libtiff/libtiff!271 + +2021-11-01 Even Rouault <even.rouault@spatialys.com> + + Fix STRIPCHOP_DEFAULT value in CMake builds. + CMake builds erroneously used value 1 instead of TIFF_STRIPCHOP, which + resulted in strip chopping not being enabled by default. + +2021-10-26 Even Rouault <even.rouault@spatialys.com> + + tif_jpeg.c: typo fix. + +2021-10-24 Han Han <hanhanzhiyeqianke@gmail.com> + + tiffsplit.c: Fix memleak before exit. + Details of the memleak: + $ valgrind --leak-check=full tiffsplit id:001763,sync:fuzzer07,src:001641,+cov + + ==2090657== + ==2090657== HEAP SUMMARY: + ==2090657== in use at exit: 13,517 bytes in 17 blocks + ==2090657== total heap usage: 41 allocs, 24 frees, 29,351 bytes allocated + ==2090657== + ==2090657== 2,473 (1,249 direct, 1,224 indirect) bytes in 1 blocks are definitely lost in loss record 10 of 13 + ==2090657== at 0x484086F: malloc (vg_replace_malloc.c:381) + ==2090657== by 0x48BF35C: TIFFClientOpen (tif_open.c:118) + ==2090657== by 0x48CF058: TIFFFdOpen (tif_unix.c:209) + ==2090657== by 0x48CF0C4: TIFFOpen (tif_unix.c:248) + ==2090657== by 0x10954C: main (tiffsplit.c:91) + ==2090657== + ==2090657== 11,044 (1,300 direct, 9,744 indirect) bytes in 1 blocks are definitely lost in loss record 13 of 13 + ==2090657== at 0x484086F: malloc (vg_replace_malloc.c:381) + ==2090657== by 0x48BF35C: TIFFClientOpen (tif_open.c:118) + ==2090657== by 0x48CF058: TIFFFdOpen (tif_unix.c:209) + ==2090657== by 0x48CF0C4: TIFFOpen (tif_unix.c:248) + ==2090657== by 0x1093D9: main (tiffsplit.c:75) + ==2090657== + ==2090657== LEAK SUMMARY: + ==2090657== definitely lost: 2,549 bytes in 2 blocks + ==2090657== indirectly lost: 10,968 bytes in 15 blocks + ==2090657== possibly lost: 0 bytes in 0 blocks + ==2090657== still reachable: 0 bytes in 0 blocks + ==2090657== suppressed: 0 bytes in 0 blocks + ==2090657== + ==2090657== For lists of detected and suppressed errors, rerun with: -s + ==2090657== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) + +2021-10-20 Even Rouault <even.rouault@spatialys.com> + + tif_webp.c: add explicit cast to please MSVC verbose warnings. + + tif_webp.c: white space fixing. + +2021-10-04 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'work/amyspark/psd-blobs' into 'master' + Enable writing Photoshop blobs + + See merge request libtiff/libtiff!269 + +2021-10-04 L. E. Segovia <amy@amyspark.me> + + Enable writing Photoshop blobs. + +2021-09-29 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'remove_packbits_hack' into 'master' + PackBitsDecode: remove hack for when char is unsigned. + + See merge request libtiff/libtiff!267 + +2021-09-28 Even Rouault <even.rouault@spatialys.com> + + PackBitsDecode: remove hack for when char is unsigned. + The function has a hack for platforms where char is unsigned. This is + better replaced by making bp a int8_t* pointer, which is guaranteed to + be signed. + +2021-09-27 Even Rouault <even.rouault@spatialys.com> + + tiffcrop.c: remove useless 'set but not read' variables. + +2021-09-23 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'fix_gdal_4538' into 'master' + TIFFAppendToStrip(): fix rewrite-in-place logic + + See merge request libtiff/libtiff!266 + +2021-09-23 Even Rouault <even.rouault@spatialys.com> + + TIFFAppendToStrip(): fix rewrite-in-place logic. + reproducable in particular with packbits compression. + + Fixes https://github.com/OSGeo/gdal/issues/4538 + +2021-09-17 Even Rouault <even.rouault@spatialys.com> + + tif_lzw.c: silence compiler warning about set but not used variable with recent clang + +2021-09-07 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'fix_cygwin' into 'master' + Fix build warnings on cygwin about 'argument 1 of type 'float[3]' with... + + See merge request libtiff/libtiff!265 + +2021-09-06 Even Rouault <even.rouault@spatialys.com> + + test/rational_precision2double.c: add missing curly braces to fix -Werror=misleading-indentation + +2021-09-05 Even Rouault <even.rouault@spatialys.com> + + Fix build warnings on cygwin about 'argument 1 of type 'float[3]' with mismatched bound [-Werror=array-parameter=]' + +2021-09-05 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'rewrite-fix' into 'master' + Fix TIFFRewriteDirectory discarding directories after the rewritten one + + See merge request libtiff/libtiff!264 + +2021-09-05 Facundo Tuesca <facu@tuesca.com> + + tif_dirwrite.c: Fix TIFFRewriteDirectory discarding directories. + This fixes a bug caused by the `tif_lastdiroff` optimization when + rewriting directories. + + Rewriting the Nth directory temporarily zeroes the pointer to it + (located in the N-1th directory) and relies on `TIFFLinkDirectory` + traversing the whole directory list to find the zeroed pointer and + linking the rewritten directory to it. Since `TIFFLinkDirectory` skips + the traversal when `tif_lastdiroff` is set, this change unsets it + to force the full traversal when rewriting a directory. + + A test to catch this particular issue is also added. + +2021-09-01 Even Rouault <even.rouault@spatialys.com> + + test_directory.c: fix compiler warnings. + +2021-09-01 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'multipage-optimization' into 'master' + Keep track of last directory to improve performance for large multi-page files + + See merge request libtiff/libtiff!262 + +2021-08-28 Facundo Tuesca <facu@tuesca.com> + + Add field to keep track of last written directory. + This adds a new `tif_lastdiroff` field to the TIFF data structure + and uses it to store the offset of the last written directory. + + Appending a new directory required traversing the whole file + to find the last directory. By keeping track of its offset in this + new field, the search is no longer necessary. + + Since this offset is only stored in-memory, the first directory + append after opening a file will have to transverse the whole + directory list. Subsequent calls will have access to the last + offset, avoiding the transversal. + +2021-08-13 Even Rouault <even.rouault@spatialys.com> + + tif_jpeg.c: fix memory leak on error code path for JPEG 12 bit (CID 1086702) + +2021-07-29 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'jpeg12' into 'master' + Enable JPEG 12bit support with a libjpeg that has a different ABI than the one for 8bit support + + See merge request libtiff/libtiff!261 + +2021-07-28 Even Rouault <even.rouault@spatialys.com> + + Reformat tif_jpeg.c and tif_jpeg_12.c with clang-format-10. + +2021-07-27 Even Rouault <even.rouault@spatialys.com> + + Enable JPEG 12bit support with a libjpeg that has a different ABI than the one for 8bit support + See https://github.com/OSGeo/gdal/pull/4139 for more details + + Note: this hasn't been tested for standalone libtiff builds. + +2021-07-09 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'wip/export-targets' into 'master' + Export tiff targets + + See merge request libtiff/libtiff!258 + +2021-07-09 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'pkgconfig' into 'master' + Add version and requirements to pc file + + See merge request libtiff/libtiff!256 + +2021-07-09 Kai Pastor <8989969-dg0yt@users.noreply.gitlab.com> + + Fix version in libtiff-4.pc.in, and CMake build: Add requirements to pc file + +2021-07-09 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'cmake' into 'master' + Fix build issues with CMake 3.10 + + See merge request libtiff/libtiff!260 + +2021-07-04 Kai Pastor <dg0yt@darc.de> + + Fix reconfiguration with cmake. + + Fix build with CMake 3.10. + +2021-06-28 Milian Wolff <milian.wolff@kdab.com> + + Export tiff targets. + Fixes build when including libtiff as a cmake subproject into + another project and then installing a target from there which + depends on tiff. For example we could end up with: + + ``` + CMake Error in 3rdParty/diplib/CMakeLists.txt: + export called with target "DIP" which requires target "tiff" that is not in + any export set. + ``` + +2021-06-21 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'libjpeg9d_support_simplification' into 'master' + tif_jpeg.c: simplify libjpeg 9d support (refs #266) + + See merge request libtiff/libtiff!257 + +2021-06-20 Even Rouault <even.rouault@spatialys.com> + + tif_jpeg.c: simplify libjpeg 9d support (refs #266) + Credits to Guido Vollbeding for the suggestion + +2021-06-15 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'jpeg_in_tiff_jpeg_9d' into 'master' + tif_jpeg.c: workaround bug of libjpeg 9d that defers Huffman table creation + + Closes #266 + + See merge request libtiff/libtiff!255 + +2021-06-15 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'jpeg_disable_progressive_with_mozjpeg' into 'master' + tif_jpeg.c: do not emit progressive scans with mozjpeg and force optimize_coding + + See merge request libtiff/libtiff!254 + +2021-06-12 Even Rouault <even.rouault@spatialys.com> + + tif_jpeg.c: with mozjpeg, disable emission of Huffman tables in JpegTables tag, and use optimize_coding + +2021-06-10 Even Rouault <even.rouault@spatialys.com> + + tif_jpeg.c: workaround bug of libjpeg 9d that defers Huffman table creation + Fixes #266 + + libjpeg-9d no longer creates default Huffman tables in + jpeg_set_defaults(), which make their emission in the JpegTables tag no + longer possible. Workaround that by borrowing code from libjpeg to + manually create them when they are not initialized. + +2021-06-10 Even Rouault <even.rouault@spatialys.com> + + tif_jpeg.c: do not emit progressive scans with mozjpeg. + Relates to #266 + + - On writing, explicitly disable progressive scans, which is normally + not enabled, except with mozjpeg. + - On reading, emit a warning when encountering progressive scans. + +2021-06-10 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'fix-263' into 'master' + Fix memory leak in tiff2pdf + + See merge request libtiff/libtiff!249 + +2021-06-09 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'diizzyy-master-patch-20521' into 'master' + html: Add missing pages when using CMake + + See merge request libtiff/libtiff!242 + +2021-06-09 Daniel E <daniel.engberg.lists@pyret.net> + + html: Add missing pages when using CMake. + +2021-06-07 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'ci-reenable-cygwin' into 'master' + ci: Re-enable cygwin builds + + See merge request libtiff/libtiff!252 + +2021-06-06 Roger Leigh <rleigh@codelibre.net> + + ci: Re-enable cygwin builds. + +2021-06-06 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'ci-arm64' into 'master' + ci: Add arm64 build + + See merge request libtiff/libtiff!251 + +2021-06-06 Roger Leigh <rleigh@codelibre.net> + + ci: Add arm64 build. + +2021-06-05 Even Rouault <even.rouault@spatialys.com> + + _TIFFRewriteField(): fix when writing a IFD with a single tile that is a sparse one, on big endian hosts + +2021-06-02 Timothy Lyanguzov <timothy.lyanguzov@sap.com> + + Fix memory leak in tiff2pdf. + +2021-06-01 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'lzw_cleanup' into 'master' + tif_lzw.c: cleanup, no functional change + + See merge request libtiff/libtiff!248 + +2021-05-31 Even Rouault <even.rouault@spatialys.com> + + tif_lzw.c: cleanup, no functional change. + +2021-05-22 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'appveyor_disable_cygwin' into 'master' + .appveyor.yml: disable cygwin configs for now as they are broken + + See merge request libtiff/libtiff!247 + +2021-05-22 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'zstd_reuse_objects' into 'master' + ZSTD codec: reuse compressor/decompressor objects + + See merge request libtiff/libtiff!246 + +2021-05-22 Even Rouault <even.rouault@spatialys.com> + + .appveyor.yml: disable cygwin configs for now as they are broken. + + ZSTD codec: reuse compressor/decompressor objects. + No need to recreate them each time in the PreEncode/Decode functions. + They can be reused if already existing. + +2021-05-08 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'adobedeflate-fix' into 'master' + Fix all remaining uses of legacy Deflate compression id and warn on use + + See merge request libtiff/libtiff!245 + +2021-05-08 David Ryskalczyk <david.rysk@gmail.com> + + Fix all remaining uses of legacy Deflate compression id and warn on use. + +2021-05-06 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'improve_tiffinfo_tiffdump_for_gdal_tags' into 'master' + tiffinfo/tiffdump: improve output for GDAL tags + + See merge request libtiff/libtiff!244 + +2021-05-03 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'issue-252' into 'master' + Prevent adding root directory to include list + + Closes #252 et #218 + + See merge request libtiff/libtiff!243 + +2021-05-03 Even Rouault <even.rouault@spatialys.com> + + tiffinfo/tiffdump: improve output for GDAL tags. + +2021-04-29 Timothy Lyanguzov <timothy.lyanguzov@sap.com> + + Prevent adding root directory to include list. + there is a file VERSION in the root directory which clashes with C++20 standard header <version> + "config.h" file is created in "config" subdirectory to prevent adding "-I.." to generated Makefile + + closes #218, #252 + +2021-04-23 Laszlo Boszormenyi (GCS) <gcs@debian.org> + + fix TIFFReadRawStrip man and HTML page typo. + From https://github.com/conda-forge/libtiff-feedstock/blob/master/recipe/patches/fix_TIFFReadRawStrip_man_page_typo.patch + +2021-04-20 Even Rouault <even.rouault@spatialys.com> + + HOWTO-RELEASE: update. + +2021-04-18 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'lerc_zstd_deflate' into 'master' + Make LERC_SUPPORT conditional on ZLIB_SUPPORT. Make display of lerc options in tiffcp depend on actual zstd support. + + See merge request libtiff/libtiff!239 + +2021-04-18 Miguel Medalha <medalist@sapo.pt> + + Make LERC_SUPPORT conditional on ZLIB_SUPPORT. Make display of lerc options in tiffcp depend on actual zstd support. + +2021-04-17 Even Rouault <even.rouault@spatialys.com> + + Merge branch 'vtorri_xz' into 'master' + automatic creation of xz archive when running make distcheck + + See merge request libtiff/libtiff!238 + +2021-04-16 Even Rouault <even.rouault@spatialys.com> + + iptcutil.c: fix bug in EOF comparison, spotted on NetBSD 9 earmv7hf-el. + 2021-04-16 Even Rouault <even.rouault@spatialys.com> libtiff v4.3.0 released diff --git a/src/3rdparty/libtiff/RELEASE-DATE b/src/3rdparty/libtiff/RELEASE-DATE index e74bf2b..dc35e22 100644 --- a/src/3rdparty/libtiff/RELEASE-DATE +++ b/src/3rdparty/libtiff/RELEASE-DATE @@ -1 +1 @@ -20210416 +20220520 diff --git a/src/3rdparty/libtiff/VERSION b/src/3rdparty/libtiff/VERSION index 8089590..fdc6698 100644 --- a/src/3rdparty/libtiff/VERSION +++ b/src/3rdparty/libtiff/VERSION @@ -1 +1 @@ -4.3.0 +4.4.0 diff --git a/src/3rdparty/libtiff/libtiff/libtiff.def b/src/3rdparty/libtiff/libtiff/libtiff.def index b2d03fe..3d2ab75 100644 --- a/src/3rdparty/libtiff/libtiff/libtiff.def +++ b/src/3rdparty/libtiff/libtiff/libtiff.def @@ -29,10 +29,13 @@ EXPORTS TIFFAccessTagMethods TIFFFieldName TIFFFieldPassCount TIFFFieldReadCount + TIFFFieldIsAnonymous TIFFFieldTag TIFFFieldWithName TIFFFieldWithTag TIFFFieldWriteCount + TIFFFieldSetGetSize + TIFFFieldSetGetCountSize TIFFFileName TIFFFileno TIFFFindCODEC @@ -62,6 +65,7 @@ EXPORTS TIFFAccessTagMethods TIFFGetVersion TIFFGetWriteProc TIFFIsBigEndian + TIFFIsBigTIFF TIFFIsByteSwapped TIFFIsCODECConfigured TIFFIsMSB2LSB @@ -177,3 +181,4 @@ EXPORTS TIFFAccessTagMethods _TIFFMultiply64 _TIFFGetExifFields _TIFFGetGpsFields + diff --git a/src/3rdparty/libtiff/libtiff/tif_close.c b/src/3rdparty/libtiff/libtiff/tif_close.c index 674518a..04977bc 100644 --- a/src/3rdparty/libtiff/libtiff/tif_close.c +++ b/src/3rdparty/libtiff/libtiff/tif_close.c @@ -80,10 +80,15 @@ TIFFCleanup(TIFF* tif) for (i = 0; i < tif->tif_nfields; i++) { TIFFField *fld = tif->tif_fields[i]; - if (fld->field_bit == FIELD_CUSTOM && - strncmp("Tag ", fld->field_name, 4) == 0) { - _TIFFfree(fld->field_name); - _TIFFfree(fld); + if (fld->field_name != NULL) { + if (fld->field_bit == FIELD_CUSTOM && + /* caution: tif_fields[i] must not be the beginning of a fields-array. + * Otherwise the following tags are also freed with the first free(). + */ + TIFFFieldIsAnonymous(fld)) { + _TIFFfree(fld->field_name); + _TIFFfree(fld); + } } } diff --git a/src/3rdparty/libtiff/libtiff/tif_color.c b/src/3rdparty/libtiff/libtiff/tif_color.c index 2b962af..20e4168 100644 --- a/src/3rdparty/libtiff/libtiff/tif_color.c +++ b/src/3rdparty/libtiff/libtiff/tif_color.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -58,13 +58,13 @@ TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a, int32_t b, tmp = (float)a / 500.0F + cby; if( tmp < 0.2069F ) *X = cielab->X0 * (tmp - 0.13793F) / 7.787F; - else + else *X = cielab->X0 * tmp * tmp * tmp; tmp = cby - (float)b / 200.0F; if( tmp < 0.2069F ) *Z = cielab->Z0 * (tmp - 0.13793F) / 7.787F; - else + else *Z = cielab->Z0 * tmp * tmp * tmp; } @@ -115,7 +115,7 @@ TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z, } #undef RINT -/* +/* * Allocate conversion state structures and make look_up tables for * the Yr,Yb,Yg <=> r,g,b conversions. */ @@ -165,7 +165,7 @@ TIFFCIELabToRGBInit(TIFFCIELabToRGB* cielab, return 0; } -/* +/* * Convert color value from the YCbCr space to RGB. * The colorspace conversion algorithm comes from the IJG v5a code; * see below for more information on how it works. @@ -174,7 +174,8 @@ TIFFCIELabToRGBInit(TIFFCIELabToRGB* cielab, #define FIX(x) ((int32_t)((x) * (1L<<SHIFT) + 0.5)) #define ONE_HALF ((int32_t)(1<<(SHIFT-1))) #define Code2V(c, RB, RW, CR) ((((c)-(int32_t)(RB))*(float)(CR))/(float)(((RW)-(RB)!=0) ? ((RW)-(RB)) : 1)) -#define CLAMP(f,min,max) ((f)<(min)?(min):(f)>(max)?(max):(f)) +/* !((f)>=(min)) written that way to deal with NaN */ +#define CLAMP(f,min,max) ((!((f)>=(min)))?(min):(f)>(max)?(max):(f)) #define HICLAMP(f,max) ((f)>(max)?(max):(f)) void @@ -235,7 +236,7 @@ TIFFYCbCrToRGBInit(TIFFYCbCrToRGB* ycbcr, float *luma, float *refBlackWhite) { TIFFRGBValue* clamptab; int i; - + #define LumaRed luma[0] #define LumaGreen luma[1] #define LumaBlue luma[2] @@ -262,7 +263,7 @@ TIFFYCbCrToRGBInit(TIFFYCbCrToRGB* ycbcr, float *luma, float *refBlackWhite) #undef LumaBlue #undef LumaGreen #undef LumaRed - + /* * i is the actual input pixel value in the range 0..255 * Cb and Cr values are in the range -128..127 (actually diff --git a/src/3rdparty/libtiff/libtiff/tif_dir.c b/src/3rdparty/libtiff/libtiff/tif_dir.c index a6c254f..e90f14a 100644 --- a/src/3rdparty/libtiff/libtiff/tif_dir.c +++ b/src/3rdparty/libtiff/libtiff/tif_dir.c @@ -40,7 +40,7 @@ #define DATATYPE_IEEEFP 3 /* !IEEE floating point data */ static void -setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size) +setByteArray(void** vpp, const void* vp, size_t nmemb, size_t elem_size) { if (*vpp) { _TIFFfree(*vpp); @@ -54,22 +54,20 @@ setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size) _TIFFmemcpy(*vpp, vp, bytes); } } -void _TIFFsetByteArray(void** vpp, void* vp, uint32_t n) +void _TIFFsetByteArray(void** vpp, const void* vp, uint32_t n) { setByteArray(vpp, vp, n, 1); } -void _TIFFsetString(char** cpp, char* cp) - { setByteArray((void**) cpp, (void*) cp, strlen(cp)+1, 1); } -static void _TIFFsetNString(char** cpp, char* cp, uint32_t n) - { setByteArray((void**) cpp, (void*) cp, n, 1); } -void _TIFFsetShortArray(uint16_t** wpp, uint16_t* wp, uint32_t n) - { setByteArray((void**) wpp, (void*) wp, n, sizeof (uint16_t)); } -void _TIFFsetLongArray(uint32_t** lpp, uint32_t* lp, uint32_t n) - { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint32_t)); } -static void _TIFFsetLong8Array(uint64_t** lpp, uint64_t* lp, uint32_t n) - { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint64_t)); } -void _TIFFsetFloatArray(float** fpp, float* fp, uint32_t n) - { setByteArray((void**) fpp, (void*) fp, n, sizeof (float)); } -void _TIFFsetDoubleArray(double** dpp, double* dp, uint32_t n) - { setByteArray((void**) dpp, (void*) dp, n, sizeof (double)); } +static void _TIFFsetNString(char** cpp, const char* cp, uint32_t n) + { setByteArray((void**) cpp, cp, n, 1); } +void _TIFFsetShortArray(uint16_t** wpp, const uint16_t* wp, uint32_t n) + { setByteArray((void**) wpp, wp, n, sizeof (uint16_t)); } +void _TIFFsetLongArray(uint32_t** lpp, const uint32_t* lp, uint32_t n) + { setByteArray((void**) lpp, lp, n, sizeof (uint32_t)); } +static void _TIFFsetLong8Array(uint64_t** lpp, const uint64_t* lp, uint32_t n) + { setByteArray((void**) lpp, lp, n, sizeof (uint64_t)); } +void _TIFFsetFloatArray(float** fpp, const float* fp, uint32_t n) + { setByteArray((void**) fpp, fp, n, sizeof (float)); } +void _TIFFsetDoubleArray(double** dpp, const double* dp, uint32_t n) + { setByteArray((void**) dpp, dp, n, sizeof (double)); } static void setDoubleArrayOneValue(double** vpp, double value, size_t nmemb) @@ -228,7 +226,7 @@ _TIFFVSetField(TIFF* tif, uint32_t tag, va_list ap) case TIFFTAG_COMPRESSION: v = (uint16_t) va_arg(ap, uint16_vap); /* - * If we're changing the compression scheme, the notify the + * If we're changing the compression scheme, notify the * previous module so that it can cleanup any state it's * setup. */ @@ -335,13 +333,13 @@ _TIFFVSetField(TIFF* tif, uint32_t tag, va_list ap) break; case TIFFTAG_XRESOLUTION: dblval = va_arg(ap, double); - if( dblval < 0 ) + if( dblval != dblval || dblval < 0 ) goto badvaluedouble; td->td_xresolution = _TIFFClampDoubleToFloat( dblval ); break; case TIFFTAG_YRESOLUTION: dblval = va_arg(ap, double); - if( dblval < 0 ) + if( dblval != dblval || dblval < 0 ) goto badvaluedouble; td->td_yresolution = _TIFFClampDoubleToFloat( dblval ); break; @@ -559,11 +557,8 @@ _TIFFVSetField(TIFF* tif, uint32_t tag, va_list ap) /* * Set custom value ... save a copy of the custom tag value. */ - tv_size = _TIFFDataSize(fip->field_type); /*--: Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size. */ - if (fip->field_type == TIFF_RATIONAL || fip->field_type == TIFF_SRATIONAL) { - tv_size = _TIFFSetGetFieldSize(fip->set_field_type); - } + tv_size = TIFFFieldSetGetSize(fip); if (tv_size == 0) { status = 0; TIFFErrorExt(tif->tif_clientdata, module, @@ -576,17 +571,28 @@ _TIFFVSetField(TIFF* tif, uint32_t tag, va_list ap) if (fip->field_type == TIFF_ASCII) { uint32_t ma; - char* mb; + const char* mb; if (fip->field_passcount) { assert(fip->field_writecount==TIFF_VARIABLE2); ma=(uint32_t)va_arg(ap, uint32_t); - mb=(char*)va_arg(ap,char*); + mb=(const char*)va_arg(ap,const char*); } else { - mb=(char*)va_arg(ap,char*); - ma=(uint32_t)(strlen(mb) + 1); + mb=(const char*)va_arg(ap,const char*); + size_t len = strlen(mb) + 1; + if( len >= 0x80000000U ) + { + status = 0; + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Too long string value for \"%s\". " + "Maximum supported is 2147483647 bytes", + tif->tif_name, + fip->field_name); + goto end; + } + ma=(uint32_t)len; } tv->count=ma; setByteArray(&tv->value,mb,ma,1); @@ -1041,11 +1047,15 @@ _TIFFVGetField(TIFF* tif, uint32_t tag, va_list ap) case TIFFTAG_TILEOFFSETS: _TIFFFillStriles( tif ); *va_arg(ap, const uint64_t**) = td->td_stripoffset_p; + if( td->td_stripoffset_p == NULL ) + ret_val = 0; break; case TIFFTAG_STRIPBYTECOUNTS: case TIFFTAG_TILEBYTECOUNTS: _TIFFFillStriles( tif ); *va_arg(ap, const uint64_t**) = td->td_stripbytecount_p; + if( td->td_stripbytecount_p == NULL ) + ret_val = 0; break; case TIFFTAG_MATTEING: *va_arg(ap, uint16_t*) = @@ -1224,7 +1234,7 @@ _TIFFVGetField(TIFF* tif, uint32_t tag, va_list ap) case TIFF_SRATIONAL: { /*-- Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size and return value size. */ - int tv_size = _TIFFSetGetFieldSize(fip->set_field_type); + int tv_size = TIFFFieldSetGetSize(fip); if (tv_size == 8) { *va_arg(ap, double*) = *(double *)val; ret_val = 1; @@ -1819,6 +1829,7 @@ TIFFUnlinkDirectory(TIFF* tif, uint16_t dirn) TIFFDefaultDirectory(tif); tif->tif_diroff = 0; /* force link on next write */ tif->tif_nextdiroff = 0; /* next write must be at end */ + tif->tif_lastdiroff = 0; /* will be updated on next link */ tif->tif_curoff = 0; tif->tif_row = (uint32_t) -1; tif->tif_curstrip = (uint32_t) -1; diff --git a/src/3rdparty/libtiff/libtiff/tif_dir.h b/src/3rdparty/libtiff/libtiff/tif_dir.h index 1782b35..0906564 100644 --- a/src/3rdparty/libtiff/libtiff/tif_dir.h +++ b/src/3rdparty/libtiff/libtiff/tif_dir.h @@ -282,11 +282,11 @@ struct _TIFFFieldArray { }; struct _TIFFField { - uint32_t field_tag; /* field's tag */ + uint32_t field_tag; /* field's tag */ short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */ short field_writecount; /* write count/TIFF_VARIABLE */ TIFFDataType field_type; /* type of associated data */ - uint32_t reserved; /* reserved for future extension */ + uint32_t field_anonymous; /* if true, this is a unknown / anonymous tag */ TIFFSetGetFieldType set_field_type; /* type to be passed to TIFFSetField */ TIFFSetGetFieldType get_field_type; /* type to be passed to TIFFGetField */ unsigned short field_bit; /* bit in fieldsset bit vector */ diff --git a/src/3rdparty/libtiff/libtiff/tif_dirinfo.c b/src/3rdparty/libtiff/libtiff/tif_dirinfo.c index 8565dfb..c30f569 100644 --- a/src/3rdparty/libtiff/libtiff/tif_dirinfo.c +++ b/src/3rdparty/libtiff/libtiff/tif_dirinfo.c @@ -149,7 +149,7 @@ tiffFields[] = { { TIFFTAG_COPYRIGHT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Copyright", NULL }, /* end Pixar tags */ { TIFFTAG_RICHTIFFIPTC, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "RichTIFFIPTC", NULL }, - { TIFFTAG_PHOTOSHOP, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "Photoshop", NULL }, + { TIFFTAG_PHOTOSHOP, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "Photoshop", NULL }, /*--: EXIFIFD and GPSIFD specified as TIFF_LONG by Aware-Systems and not TIFF_IFD8 as in original LibTiff. * However, for IFD-like tags, libtiff uses the data type TIFF_IFD8 in tiffFields[]-tag definition combined with * a special handling procedure in order to write either a 32-bit value and the TIFF_IFD type-id into ClassicTIFF files @@ -162,6 +162,7 @@ tiffFields[] = { { TIFFTAG_FAXRECVTIME, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvTime", NULL }, { TIFFTAG_FAXDCS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxDcs", NULL }, { TIFFTAG_STONITS, 1, 1, TIFF_DOUBLE, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "StoNits", NULL }, + { TIFFTAG_IMAGESOURCEDATA, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "Adobe Photoshop Document Data Block", NULL }, { TIFFTAG_INTEROPERABILITYIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InteroperabilityIFDOffset", NULL }, /* begin DNG tags */ { TIFFTAG_DNGVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DNGVersion", NULL }, @@ -419,11 +420,16 @@ _TIFFSetupFields(TIFF* tif, const TIFFFieldArray* fieldarray) for (i = 0; i < tif->tif_nfields; i++) { TIFFField *fld = tif->tif_fields[i]; - if (fld->field_bit == FIELD_CUSTOM && - strncmp("Tag ", fld->field_name, 4) == 0) { + if (fld->field_name != NULL) { + if (fld->field_bit == FIELD_CUSTOM && + TIFFFieldIsAnonymous(fld)) { _TIFFfree(fld->field_name); + /* caution: tif_fields[i] must not be the beginning of a fields-array. + * Otherwise the following tags are also freed with the first free(). + */ _TIFFfree(fld); } + } } _TIFFfree(tif->tif_fields); @@ -530,7 +536,7 @@ _TIFFPrintFieldInfo(TIFF* tif, FILE* fd) } /* - * Return size of TIFFDataType in bytes + * Return size of TIFFDataType within TIFF-file in bytes */ int TIFFDataWidth(TIFFDataType type) @@ -563,55 +569,29 @@ TIFFDataWidth(TIFFDataType type) } } -/* - * Return size of TIFFDataType in bytes. - * - * XXX: We need a separate function to determine the space needed - * to store the value. For TIFF_RATIONAL values TIFFDataWidth() returns 8, - * but we use 4-byte float to represent rationals. - */ -int -_TIFFDataSize(TIFFDataType type) -{ - switch (type) - { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_ASCII: - case TIFF_UNDEFINED: - return 1; - case TIFF_SHORT: - case TIFF_SSHORT: - return 2; - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_FLOAT: - case TIFF_IFD: - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - return 4; - case TIFF_DOUBLE: - case TIFF_LONG8: - case TIFF_SLONG8: - case TIFF_IFD8: - return 8; - default: - return 0; - } -} -/* - * Rational2Double: - * Return size of TIFFSetGetFieldType in bytes. - * - * XXX: TIFF_RATIONAL values for FIELD_CUSTOM are stored internally as 4-byte float. - * However, some of them should be stored internally as 8-byte double. - * This is now managed by the SetGetField of the tag-definition! +/* + * Return internal storage size of TIFFSetGetFieldType in bytes. + * TIFFSetField() and TIFFGetField() have to provide the parameter accordingly. + * Replaces internal functions _TIFFDataSize() and _TIFFSetGetFieldSize() + * with now extern available function TIFFFieldSetGetSize(). */ -int -_TIFFSetGetFieldSize(TIFFSetGetFieldType setgettype) +int +TIFFFieldSetGetSize(const TIFFField* fip) { - switch (setgettype) +/* + * TIFFSetField() and TIFFGetField() must provide the parameter accordingly to + * the definition of "set_field_type" of the tag definition in dir_info.c. + * This function returns the data size for that purpose. + * + * Furthermore, this data size is also used for the internal storage, + * even for TIFF_RATIONAL values for FIELD_CUSTOM, which are stored internally as 4-byte float, + * but some of them should be stored internally as 8-byte double, + * depending on the "set_field_type" _FLOAT_ or _DOUBLE_. +*/ + if (fip == NULL) return 0; + + switch (fip->set_field_type) { case TIFF_SETGET_UNDEFINED: case TIFF_SETGET_ASCII: @@ -619,7 +599,7 @@ _TIFFSetGetFieldSize(TIFFSetGetFieldType setgettype) case TIFF_SETGET_C16_ASCII: case TIFF_SETGET_C32_ASCII: case TIFF_SETGET_OTHER: - return 0; + return 1; case TIFF_SETGET_UINT8: case TIFF_SETGET_SINT8: case TIFF_SETGET_C0_UINT8: @@ -673,7 +653,48 @@ _TIFFSetGetFieldSize(TIFFSetGetFieldType setgettype) default: return 0; } -} /*-- _TIFFSetGetFieldSize --- */ +} /*-- TIFFFieldSetGetSize() --- */ + +/* + * Return size of count parameter of TIFFSetField() and TIFFGetField() + * and also if it is required: 0=none, 2=uint16_t, 4=uint32_t + */ +int +TIFFFieldSetGetCountSize(const TIFFField* fip) +{ + if (fip == NULL) return 0; + + switch (fip->set_field_type) { + case TIFF_SETGET_C16_ASCII: + case TIFF_SETGET_C16_UINT8: + case TIFF_SETGET_C16_SINT8: + case TIFF_SETGET_C16_UINT16: + case TIFF_SETGET_C16_SINT16: + case TIFF_SETGET_C16_UINT32: + case TIFF_SETGET_C16_SINT32: + case TIFF_SETGET_C16_FLOAT: + case TIFF_SETGET_C16_UINT64: + case TIFF_SETGET_C16_SINT64: + case TIFF_SETGET_C16_DOUBLE: + case TIFF_SETGET_C16_IFD8: + return 2; + case TIFF_SETGET_C32_ASCII: + case TIFF_SETGET_C32_UINT8: + case TIFF_SETGET_C32_SINT8: + case TIFF_SETGET_C32_UINT16: + case TIFF_SETGET_C32_SINT16: + case TIFF_SETGET_C32_UINT32: + case TIFF_SETGET_C32_SINT32: + case TIFF_SETGET_C32_FLOAT: + case TIFF_SETGET_C32_UINT64: + case TIFF_SETGET_C32_SINT64: + case TIFF_SETGET_C32_DOUBLE: + case TIFF_SETGET_C32_IFD8: + return 4; + default: + return 0; + } +} /*-- TIFFFieldSetGetCountSize() --- */ const TIFFField* @@ -788,6 +809,12 @@ TIFFFieldWriteCount(const TIFFField* fip) return fip->field_writecount; } +int +TIFFFieldIsAnonymous(const TIFFField *fip) +{ + return fip->field_anonymous; +} + const TIFFField* _TIFFFindOrRegisterField(TIFF *tif, uint32_t tag, TIFFDataType dt) @@ -819,7 +846,7 @@ _TIFFCreateAnonField(TIFF *tif, uint32_t tag, TIFFDataType field_type) fld->field_readcount = TIFF_VARIABLE2; fld->field_writecount = TIFF_VARIABLE2; fld->field_type = field_type; - fld->reserved = 0; + fld->field_anonymous = 1; /* indicate that this is an anonymous / unknown tag */ switch (field_type) { case TIFF_BYTE: @@ -892,6 +919,8 @@ _TIFFCreateAnonField(TIFF *tif, uint32_t tag, TIFFDataType field_type) /* * note that this name is a special sign to TIFFClose() and * _TIFFSetupFields() to free the field + * Update: + * This special sign is replaced by fld->field_anonymous flag. */ (void) snprintf(fld->field_name, 32, "Tag %d", (int) tag); @@ -1102,7 +1131,7 @@ TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], uint32_t n) tp->field_readcount = info[i].field_readcount; tp->field_writecount = info[i].field_writecount; tp->field_type = info[i].field_type; - tp->reserved = 0; + tp->field_anonymous = 0; tp->set_field_type = _TIFFSetGetType(info[i].field_type, info[i].field_readcount, @@ -1114,6 +1143,11 @@ TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], uint32_t n) tp->field_bit = info[i].field_bit; tp->field_oktochange = info[i].field_oktochange; tp->field_passcount = info[i].field_passcount; + if (info[i].field_name == NULL) { + TIFFErrorExt(tif->tif_clientdata, module, + "Field_name of %d.th allocation tag %d is NULL", i, info[i].field_tag); + return -1; + } tp->field_name = info[i].field_name; tp->field_subfields = NULL; tp++; diff --git a/src/3rdparty/libtiff/libtiff/tif_dirread.c b/src/3rdparty/libtiff/libtiff/tif_dirread.c index d84147a..32653f0 100644 --- a/src/3rdparty/libtiff/libtiff/tif_dirread.c +++ b/src/3rdparty/libtiff/libtiff/tif_dirread.c @@ -38,6 +38,7 @@ #include "tiffiop.h" #include <float.h> #include <stdlib.h> +#include <string.h> #define FAILED_FII ((uint32_t) -1) @@ -61,9 +62,13 @@ enum TIFFReadDirEntryErr { }; static enum TIFFReadDirEntryErr TIFFReadDirEntryByte(TIFF* tif, TIFFDirEntry* direntry, uint8_t* value); +static enum TIFFReadDirEntryErr TIFFReadDirEntrySbyte(TIFF * tif, TIFFDirEntry * direntry, int8_t * value); static enum TIFFReadDirEntryErr TIFFReadDirEntryShort(TIFF* tif, TIFFDirEntry* direntry, uint16_t* value); +static enum TIFFReadDirEntryErr TIFFReadDirEntrySshort(TIFF * tif, TIFFDirEntry * direntry, int16_t * value); static enum TIFFReadDirEntryErr TIFFReadDirEntryLong(TIFF* tif, TIFFDirEntry* direntry, uint32_t* value); +static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong(TIFF * tif, TIFFDirEntry * direntry, int32_t * value); static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8(TIFF* tif, TIFFDirEntry* direntry, uint64_t* value); +static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8(TIFF * tif, TIFFDirEntry * direntry, int64_t * value); static enum TIFFReadDirEntryErr TIFFReadDirEntryFloat(TIFF* tif, TIFFDirEntry* direntry, float* value); static enum TIFFReadDirEntryErr TIFFReadDirEntryDouble(TIFF* tif, TIFFDirEntry* direntry, double* value); static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8(TIFF* tif, TIFFDirEntry* direntry, uint64_t* value); @@ -285,6 +290,98 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryByte(TIFF* tif, TIFFDirEntry* di } } +static enum TIFFReadDirEntryErr TIFFReadDirEntrySbyte(TIFF *tif, TIFFDirEntry *direntry, int8_t *value) +{ + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count != 1) + return(TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: /* Support to read TIFF_UNDEFINED with field_readcount==1 */ + { + uint8_t m; + TIFFReadDirEntryCheckedByte(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeSbyteByte(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(int8_t)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + TIFFReadDirEntryCheckedSbyte(tif, direntry, value); + return(TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16_t m; + TIFFReadDirEntryCheckedShort(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeSbyteShort(m); + if (err != TIFFReadDirEntryErrOk) + return(err); + *value = (int8_t)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16_t m; + TIFFReadDirEntryCheckedSshort(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeSbyteSshort(m); + if (err != TIFFReadDirEntryErrOk) + return(err); + *value = (int8_t)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32_t m; + TIFFReadDirEntryCheckedLong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeSbyteLong(m); + if (err != TIFFReadDirEntryErrOk) + return(err); + *value = (int8_t)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32_t m; + TIFFReadDirEntryCheckedSlong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeSbyteSlong(m); + if (err != TIFFReadDirEntryErrOk) + return(err); + *value = (int8_t)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64_t m; + err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return(err); + err = TIFFReadDirEntryCheckRangeSbyteLong8(m); + if (err != TIFFReadDirEntryErrOk) + return(err); + *value = (int8_t)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64_t m; + err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return(err); + err = TIFFReadDirEntryCheckRangeSbyteSlong8(m); + if (err != TIFFReadDirEntryErrOk) + return(err); + *value = (int8_t)m; + return(TIFFReadDirEntryErrOk); + } + default: + return(TIFFReadDirEntryErrType); + } +} /*-- TIFFReadDirEntrySbyte() --*/ + static enum TIFFReadDirEntryErr TIFFReadDirEntryShort(TIFF* tif, TIFFDirEntry* direntry, uint16_t* value) { enum TIFFReadDirEntryErr err; @@ -369,7 +466,91 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryShort(TIFF* tif, TIFFDirEntry* d default: return(TIFFReadDirEntryErrType); } -} +} /*-- TIFFReadDirEntryShort() --*/ + +static enum TIFFReadDirEntryErr TIFFReadDirEntrySshort(TIFF *tif, TIFFDirEntry *direntry, int16_t *value) +{ + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count != 1) + return(TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t m; + TIFFReadDirEntryCheckedByte(tif, direntry, &m); + *value = (int16_t)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8_t m; + TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); + *value = (int16_t)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16_t m; + TIFFReadDirEntryCheckedShort(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeSshortShort(m); + if (err != TIFFReadDirEntryErrOk) + return(err); + *value = (uint16_t)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + TIFFReadDirEntryCheckedSshort(tif, direntry, value); + return(TIFFReadDirEntryErrOk); + case TIFF_LONG: + { + uint32_t m; + TIFFReadDirEntryCheckedLong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeSshortLong(m); + if (err != TIFFReadDirEntryErrOk) + return(err); + *value = (int16_t)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32_t m; + TIFFReadDirEntryCheckedSlong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeSshortSlong(m); + if (err != TIFFReadDirEntryErrOk) + return(err); + *value = (int16_t)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64_t m; + err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return(err); + err = TIFFReadDirEntryCheckRangeSshortLong8(m); + if (err != TIFFReadDirEntryErrOk) + return(err); + *value = (int16_t)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64_t m; + err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return(err); + err = TIFFReadDirEntryCheckRangeSshortSlong8(m); + if (err != TIFFReadDirEntryErrOk) + return(err); + *value = (int16_t)m; + return(TIFFReadDirEntryErrOk); + } + default: + return(TIFFReadDirEntryErrType); + } +} /*-- TIFFReadDirEntrySshort() --*/ + static enum TIFFReadDirEntryErr TIFFReadDirEntryLong(TIFF* tif, TIFFDirEntry* direntry, uint32_t* value) { @@ -452,7 +633,84 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryLong(TIFF* tif, TIFFDirEntry* di default: return(TIFFReadDirEntryErrType); } -} +} /*-- TIFFReadDirEntryLong() --*/ + +static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong(TIFF *tif, TIFFDirEntry *direntry, int32_t *value) +{ + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count != 1) + return(TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t m; + TIFFReadDirEntryCheckedByte(tif, direntry, &m); + *value = (int32_t)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8_t m; + TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); + *value = (int32_t)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16_t m; + TIFFReadDirEntryCheckedShort(tif, direntry, &m); + *value = (int32_t)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16_t m; + TIFFReadDirEntryCheckedSshort(tif, direntry, &m); + *value = (int32_t)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32_t m; + TIFFReadDirEntryCheckedLong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeSlongLong(m); + if (err != TIFFReadDirEntryErrOk) + return(err); + *value = (int32_t)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + TIFFReadDirEntryCheckedSlong(tif, direntry, value); + return(TIFFReadDirEntryErrOk); + case TIFF_LONG8: + { + uint64_t m; + err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return(err); + err = TIFFReadDirEntryCheckRangeSlongLong8(m); + if (err != TIFFReadDirEntryErrOk) + return(err); + *value = (int32_t)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64_t m; + err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return(err); + err = TIFFReadDirEntryCheckRangeSlongSlong8(m); + if (err != TIFFReadDirEntryErrOk) + return(err); + *value = (int32_t)m; + return(TIFFReadDirEntryErrOk); + } + default: + return(TIFFReadDirEntryErrType); + } +} /*-- TIFFReadDirEntrySlong() --*/ static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8(TIFF* tif, TIFFDirEntry* direntry, uint64_t* value) { @@ -530,7 +788,77 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8(TIFF* tif, TIFFDirEntry* d default: return(TIFFReadDirEntryErrType); } -} +} /*-- TIFFReadDirEntryLong8() --*/ + +static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8(TIFF *tif, TIFFDirEntry *direntry, int64_t *value) +{ + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count != 1) + return(TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t m; + TIFFReadDirEntryCheckedByte(tif, direntry, &m); + *value = (int64_t)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8_t m; + TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); + *value = (int64_t)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16_t m; + TIFFReadDirEntryCheckedShort(tif, direntry, &m); + *value = (int64_t)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16_t m; + TIFFReadDirEntryCheckedSshort(tif, direntry, &m); + *value = (int64_t)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32_t m; + TIFFReadDirEntryCheckedLong(tif, direntry, &m); + *value = (int64_t)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32_t m; + TIFFReadDirEntryCheckedSlong(tif, direntry, &m); + *value = (int64_t)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64_t m; + err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return(err); + err = TIFFReadDirEntryCheckRangeSlong8Long8(m); + if (err != TIFFReadDirEntryErrOk) + return(err); + *value = (int64_t)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + err = TIFFReadDirEntryCheckedSlong8(tif, direntry, value); + return(err); + default: + return(TIFFReadDirEntryErrType); + } +} /*-- TIFFReadDirEntrySlong8() --*/ + static enum TIFFReadDirEntryErr TIFFReadDirEntryFloat(TIFF* tif, TIFFDirEntry* direntry, float* value) { @@ -826,6 +1154,10 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryDataAndRealloc( return TIFFReadDirEntryErrOk; } +/* Caution: if raising that value, make sure int32 / uint32 overflows can't occur + * elsewhere */ +#define MAX_SIZE_TAG_DATA 2147483647U + static enum TIFFReadDirEntryErr TIFFReadDirEntryArrayWithLimit( TIFF* tif, TIFFDirEntry* direntry, uint32_t* count, uint32_t desttypesize, void** value, uint64_t maxcount) @@ -858,9 +1190,9 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryArrayWithLimit( * in either the current data type or the dest data type. This also * avoids problems with overflow of tmsize_t on 32bit systems. */ - if ((uint64_t)(2147483647 / typesize) < target_count64) + if ((uint64_t)(MAX_SIZE_TAG_DATA / typesize) < target_count64) return(TIFFReadDirEntryErrSizesan); - if ((uint64_t)(2147483647 / desttypesize) < target_count64) + if ((uint64_t)(MAX_SIZE_TAG_DATA / desttypesize) < target_count64) return(TIFFReadDirEntryErrSizesan); *count=(uint32_t)target_count64; @@ -3794,50 +4126,7 @@ TIFFReadDirectory(TIFF* tif) MissingRequired(tif,"ImageLength"); goto bad; } - /* - * Setup appropriate structures (by strip or by tile) - */ - if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) { - tif->tif_dir.td_nstrips = TIFFNumberOfStrips(tif); - tif->tif_dir.td_tilewidth = tif->tif_dir.td_imagewidth; - tif->tif_dir.td_tilelength = tif->tif_dir.td_rowsperstrip; - tif->tif_dir.td_tiledepth = tif->tif_dir.td_imagedepth; - tif->tif_flags &= ~TIFF_ISTILED; - } else { - tif->tif_dir.td_nstrips = TIFFNumberOfTiles(tif); - tif->tif_flags |= TIFF_ISTILED; - } - if (!tif->tif_dir.td_nstrips) { - TIFFErrorExt(tif->tif_clientdata, module, - "Cannot handle zero number of %s", - isTiled(tif) ? "tiles" : "strips"); - goto bad; - } - tif->tif_dir.td_stripsperimage = tif->tif_dir.td_nstrips; - if (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE) - tif->tif_dir.td_stripsperimage /= tif->tif_dir.td_samplesperpixel; - if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) { -#ifdef OJPEG_SUPPORT - if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG) && - (isTiled(tif)==0) && - (tif->tif_dir.td_nstrips==1)) { - /* - * XXX: OJPEG hack. - * If a) compression is OJPEG, b) it's not a tiled TIFF, - * and c) the number of strips is 1, - * then we tolerate the absence of stripoffsets tag, - * because, presumably, all required data is in the - * JpegInterchangeFormat stream. - */ - TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS); - } else -#endif - { - MissingRequired(tif, - isTiled(tif) ? "TileOffsets" : "StripOffsets"); - goto bad; - } - } + /* * Second pass: extract other information. */ @@ -4042,41 +4331,6 @@ TIFFReadDirectory(TIFF* tif) } /* -- 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, @@ -4148,6 +4402,88 @@ TIFFReadDirectory(TIFF* tif) } /* + * Setup appropriate structures (by strip or by tile) + * We do that only after the above OJPEG hack which alters SamplesPerPixel + * and thus influences the number of strips in the separate planarconfig. + */ + if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) { + tif->tif_dir.td_nstrips = TIFFNumberOfStrips(tif); + tif->tif_dir.td_tilewidth = tif->tif_dir.td_imagewidth; + tif->tif_dir.td_tilelength = tif->tif_dir.td_rowsperstrip; + tif->tif_dir.td_tiledepth = tif->tif_dir.td_imagedepth; + tif->tif_flags &= ~TIFF_ISTILED; + } else { + tif->tif_dir.td_nstrips = TIFFNumberOfTiles(tif); + tif->tif_flags |= TIFF_ISTILED; + } + if (!tif->tif_dir.td_nstrips) { + TIFFErrorExt(tif->tif_clientdata, module, + "Cannot handle zero number of %s", + isTiled(tif) ? "tiles" : "strips"); + goto bad; + } + tif->tif_dir.td_stripsperimage = tif->tif_dir.td_nstrips; + if (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE) + tif->tif_dir.td_stripsperimage /= tif->tif_dir.td_samplesperpixel; + if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) { +#ifdef OJPEG_SUPPORT + if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG) && + (isTiled(tif)==0) && + (tif->tif_dir.td_nstrips==1)) { + /* + * XXX: OJPEG hack. + * If a) compression is OJPEG, b) it's not a tiled TIFF, + * and c) the number of strips is 1, + * then we tolerate the absence of stripoffsets tag, + * because, presumably, all required data is in the + * JpegInterchangeFormat stream. + */ + TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS); + } else +#endif + { + MissingRequired(tif, + isTiled(tif) ? "TileOffsets" : "StripOffsets"); + goto bad; + } + } + + 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; + } + } + } + + /* * Make sure all non-color channels are extrasamples. * If it's not the case, define them as such. */ @@ -4173,7 +4509,8 @@ TIFFReadDirectory(TIFF* tif) goto bad; } - memcpy(new_sampleinfo, tif->tif_dir.td_sampleinfo, old_extrasamples * sizeof(uint16_t)); + if (old_extrasamples > 0) + memcpy(new_sampleinfo, tif->tif_dir.td_sampleinfo, old_extrasamples * sizeof(uint16_t)); _TIFFsetShortArray(&tif->tif_dir.td_sampleinfo, new_sampleinfo, tif->tif_dir.td_extrasamples); _TIFFfree(new_sampleinfo); } @@ -4527,7 +4864,14 @@ TIFFReadCustomDirectory(TIFF* tif, toff_t diroff, switch (dp->tdir_tag) { case EXIFTAG_SUBJECTDISTANCE: - (void)TIFFFetchSubjectDistance(tif, dp); + if(!TIFFFieldIsAnonymous(fip)) { + /* should only be called on a Exif directory */ + /* when exifFields[] is active */ + (void)TIFFFetchSubjectDistance(tif, dp); + } + else { + (void)TIFFFetchNormalTag(tif, dp, TRUE); + } break; default: (void)TIFFFetchNormalTag(tif, dp, TRUE); @@ -5050,18 +5394,28 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) err=TIFFReadDirEntryByteArray(tif,dp,&data); if (err==TIFFReadDirEntryErrOk) { - uint32_t mb = 0; + size_t mb = 0; int n; if (data != NULL) { - uint8_t* ma = data; - while (mb<(uint32_t)dp->tdir_count) - { - if (*ma==0) - break; - ma++; - mb++; - } + if (dp->tdir_count > 0 && data[dp->tdir_count - 1] == 0) + { + /* optimization: if data is known to be 0 terminated, we can use strlen() */ + mb = strlen((const char*)data); + } + else + { + /* general case. equivalent to non-portable */ + /* mb = strnlen((const char*)data, (uint32_t)dp->tdir_count); */ + uint8_t* ma = data; + while (mb<(uint32_t)dp->tdir_count) + { + if (*ma==0) + break; + ma++; + mb++; + } + } } if (mb+1<(uint32_t)dp->tdir_count) TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" contains null byte in value; value incorrectly truncated during reading due to implementation limitations",fip->field_name); @@ -5069,17 +5423,19 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) { uint8_t* o; TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte",fip->field_name); - if ((uint32_t)dp->tdir_count + 1 != dp->tdir_count + 1) - o=NULL; - else - o=_TIFFmalloc((uint32_t)dp->tdir_count + 1); + /* TIFFReadDirEntryArrayWithLimit() ensures this can't be larger than MAX_SIZE_TAG_DATA */ + assert((uint32_t)dp->tdir_count + 1 == dp->tdir_count + 1); + o=_TIFFmalloc((uint32_t)dp->tdir_count + 1); if (o==NULL) { if (data!=NULL) _TIFFfree(data); return(0); } - _TIFFmemcpy(o,data,(uint32_t)dp->tdir_count); + if (dp->tdir_count > 0 ) + { + _TIFFmemcpy(o,data,(uint32_t)dp->tdir_count); + } o[(uint32_t)dp->tdir_count]=0; if (data!=0) _TIFFfree(data); @@ -5106,6 +5462,19 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) } } break; + case TIFF_SETGET_SINT8: + { + int8_t data = 0; + assert(fip->field_readcount == 1); + assert(fip->field_passcount == 0); + err = TIFFReadDirEntrySbyte(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif, dp->tdir_tag, data)) + return(0); + } + } + break; case TIFF_SETGET_UINT16: { uint16_t data; @@ -5119,6 +5488,19 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) } } break; + case TIFF_SETGET_SINT16: + { + int16_t data; + assert(fip->field_readcount==1); + assert(fip->field_passcount==0); + err=TIFFReadDirEntrySshort(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif,dp->tdir_tag,data)) + return(0); + } + } + break; case TIFF_SETGET_UINT32: { uint32_t data; @@ -5132,6 +5514,19 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) } } break; + case TIFF_SETGET_SINT32: + { + int32_t data; + assert(fip->field_readcount==1); + assert(fip->field_passcount==0); + err=TIFFReadDirEntrySlong(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif,dp->tdir_tag,data)) + return(0); + } + } + break; case TIFF_SETGET_UINT64: { uint64_t data; @@ -5145,6 +5540,19 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) } } break; + case TIFF_SETGET_SINT64: + { + int64_t data; + assert(fip->field_readcount==1); + assert(fip->field_passcount==0); + err=TIFFReadDirEntrySlong8(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif,dp->tdir_tag,data)) + return(0); + } + } + break; case TIFF_SETGET_FLOAT: { float data; @@ -5199,7 +5607,7 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) if (err==TIFFReadDirEntryErrOk) { int m; - assert(data); /* avoid CLang static Analyzer false positive */ + assert(data); /* avoid CLang static Analyzer false positive */ m=TIFFSetField(tif,dp->tdir_tag,data[0],data[1]); _TIFFfree(data); if (!m) @@ -5214,9 +5622,9 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) assert(fip->field_passcount==0); if (dp->tdir_count!=(uint64_t)fip->field_readcount) { TIFFWarningExt(tif->tif_clientdata,module, - "incorrect count for field \"%s\", expected %d, got %"PRIu64, - fip->field_name,(int) fip->field_readcount, dp->tdir_count); - return 0; + "incorrect count for field \"%s\", expected %d, got %"PRIu64, + fip->field_name,(int) fip->field_readcount, dp->tdir_count); + return(0); } else { @@ -5233,13 +5641,43 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) } } break; + case TIFF_SETGET_C0_SINT8: + { + int8_t * data; + assert(fip->field_readcount>=1); + assert(fip->field_passcount==0); + if (dp->tdir_count!=(uint64_t)fip->field_readcount) { + TIFFWarningExt(tif->tif_clientdata, module, + "incorrect count for field \"%s\", expected %d, got %"PRIu64, + fip->field_name, (int)fip->field_readcount, dp->tdir_count); + return(0); + } + else + { + err=TIFFReadDirEntrySbyteArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; case TIFF_SETGET_C0_UINT16: { uint16_t* data; assert(fip->field_readcount>=1); assert(fip->field_passcount==0); - if (dp->tdir_count!=(uint64_t)fip->field_readcount) - /* corrupt file */; + if (dp->tdir_count != (uint64_t)fip->field_readcount) { + TIFFWarningExt(tif->tif_clientdata, module, + "incorrect count for field \"%s\", expected %d, got %"PRIu64, + fip->field_name, (int)fip->field_readcount, dp->tdir_count); + return(0); + } else { err=TIFFReadDirEntryShortArray(tif,dp,&data); @@ -5255,13 +5693,43 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) } } break; + case TIFF_SETGET_C0_SINT16: + { + int16_t* data; + assert(fip->field_readcount>=1); + assert(fip->field_passcount==0); + if (dp->tdir_count != (uint64_t)fip->field_readcount) { + TIFFWarningExt(tif->tif_clientdata, module, + "incorrect count for field \"%s\", expected %d, got %"PRIu64, + fip->field_name, (int)fip->field_readcount, dp->tdir_count); + return(0); + } + else + { + err=TIFFReadDirEntrySshortArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; case TIFF_SETGET_C0_UINT32: { uint32_t* data; assert(fip->field_readcount>=1); assert(fip->field_passcount==0); - if (dp->tdir_count!=(uint64_t)fip->field_readcount) - /* corrupt file */; + if (dp->tdir_count != (uint64_t)fip->field_readcount) { + TIFFWarningExt(tif->tif_clientdata, module, + "incorrect count for field \"%s\", expected %d, got %"PRIu64, + fip->field_name, (int)fip->field_readcount, dp->tdir_count); + return(0); + } else { err=TIFFReadDirEntryLongArray(tif,dp,&data); @@ -5277,13 +5745,93 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) } } break; + case TIFF_SETGET_C0_SINT32: + { + int32_t* data; + assert(fip->field_readcount>=1); + assert(fip->field_passcount==0); + if (dp->tdir_count != (uint64_t)fip->field_readcount) { + TIFFWarningExt(tif->tif_clientdata, module, + "incorrect count for field \"%s\", expected %d, got %"PRIu64, + fip->field_name, (int)fip->field_readcount, dp->tdir_count); + return(0); + } + else + { + err=TIFFReadDirEntrySlongArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; + case TIFF_SETGET_C0_UINT64: + { + uint64_t *data; + assert(fip->field_readcount >= 1); + assert(fip->field_passcount == 0); + if (dp->tdir_count != (uint64_t)fip->field_readcount) { + TIFFWarningExt(tif->tif_clientdata, module, + "incorrect count for field \"%s\", expected %d, got %"PRIu64, + fip->field_name, (int)fip->field_readcount, dp->tdir_count); + return(0); + } else + { + err = TIFFReadDirEntryLong8Array(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, data); + if (data != 0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; + case TIFF_SETGET_C0_SINT64: + { + int64_t *data; + assert(fip->field_readcount >= 1); + assert(fip->field_passcount == 0); + if (dp->tdir_count != (uint64_t)fip->field_readcount) { + TIFFWarningExt(tif->tif_clientdata, module, + "incorrect count for field \"%s\", expected %d, got %"PRIu64, + fip->field_name, (int)fip->field_readcount, dp->tdir_count); + return(0); + } else + { + err = TIFFReadDirEntrySlong8Array(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, data); + if (data != 0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; case TIFF_SETGET_C0_FLOAT: { float* data; assert(fip->field_readcount>=1); assert(fip->field_passcount==0); - if (dp->tdir_count!=(uint64_t)fip->field_readcount) - /* corrupt file */; + if (dp->tdir_count != (uint64_t)fip->field_readcount) { + TIFFWarningExt(tif->tif_clientdata, module, + "incorrect count for field \"%s\", expected %d, got %"PRIu64, + fip->field_name, (int)fip->field_readcount, dp->tdir_count); + return(0); + } else { err=TIFFReadDirEntryFloatArray(tif,dp,&data); @@ -5305,8 +5853,12 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) double* data; assert(fip->field_readcount>=1); assert(fip->field_passcount==0); - if (dp->tdir_count!=(uint64_t)fip->field_readcount) - /* corrupt file */; + if (dp->tdir_count != (uint64_t)fip->field_readcount) { + TIFFWarningExt(tif->tif_clientdata, module, + "incorrect count for field \"%s\", expected %d, got %"PRIu64, + fip->field_name, (int)fip->field_readcount, dp->tdir_count); + return(0); + } else { err=TIFFReadDirEntryDoubleArray(tif,dp,&data); @@ -5371,6 +5923,28 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) } } break; + case TIFF_SETGET_C16_SINT8: + { + int8_t* data; + assert(fip->field_readcount==TIFF_VARIABLE); + assert(fip->field_passcount==1); + if (dp->tdir_count>0xFFFF) + err=TIFFReadDirEntryErrCount; + else + { + err=TIFFReadDirEntrySbyteArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint16_t)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; case TIFF_SETGET_C16_UINT16: { uint16_t* data; @@ -5393,6 +5967,28 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) } } break; + case TIFF_SETGET_C16_SINT16: + { + int16_t* data; + assert(fip->field_readcount==TIFF_VARIABLE); + assert(fip->field_passcount==1); + if (dp->tdir_count>0xFFFF) + err=TIFFReadDirEntryErrCount; + else + { + err=TIFFReadDirEntrySshortArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint16_t)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; case TIFF_SETGET_C16_UINT32: { uint32_t* data; @@ -5415,6 +6011,28 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) } } break; + case TIFF_SETGET_C16_SINT32: + { + int32_t* data; + assert(fip->field_readcount==TIFF_VARIABLE); + assert(fip->field_passcount==1); + if (dp->tdir_count>0xFFFF) + err=TIFFReadDirEntryErrCount; + else + { + err=TIFFReadDirEntrySlongArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint16_t)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; case TIFF_SETGET_C16_UINT64: { uint64_t* data; @@ -5437,6 +6055,28 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) } } break; + case TIFF_SETGET_C16_SINT64: + { + int64_t* data; + assert(fip->field_readcount==TIFF_VARIABLE); + assert(fip->field_passcount==1); + if (dp->tdir_count>0xFFFF) + err=TIFFReadDirEntryErrCount; + else + { + err=TIFFReadDirEntrySlong8Array(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint16_t)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; case TIFF_SETGET_C16_FLOAT: { float* data; @@ -5514,8 +6154,8 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) int m; if( data != 0 && dp->tdir_count > 0 && data[dp->tdir_count-1] != '\0' ) { - TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte. Forcing it to be null",fip->field_name); - data[dp->tdir_count-1] = '\0'; + TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte. Forcing it to be null",fip->field_name); + data[dp->tdir_count-1] = '\0'; } m=TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), data); if (data!=0) @@ -5765,8 +6405,9 @@ TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32_t nstrips, uint64_t** l _TIFFfree(data); return(0); } - _TIFFmemcpy(resizeddata,data, (uint32_t)dir->tdir_count * sizeof(uint64_t)); - _TIFFmemset(resizeddata+(uint32_t)dir->tdir_count, 0, (nstrips - (uint32_t)dir->tdir_count) * sizeof(uint64_t)); + if( dir->tdir_count ) + _TIFFmemcpy(resizeddata,data, (uint32_t)dir->tdir_count * sizeof(uint64_t)); + _TIFFmemset(resizeddata+(uint32_t)dir->tdir_count, 0, (nstrips - (uint32_t)dir->tdir_count) * sizeof(uint64_t)); _TIFFfree(data); data=resizeddata; } diff --git a/src/3rdparty/libtiff/libtiff/tif_dirwrite.c b/src/3rdparty/libtiff/libtiff/tif_dirwrite.c index 12d67be..2fef6d8 100644 --- a/src/3rdparty/libtiff/libtiff/tif_dirwrite.c +++ b/src/3rdparty/libtiff/libtiff/tif_dirwrite.c @@ -300,6 +300,12 @@ TIFFRewriteDirectory( TIFF *tif ) return (0); } } + else if( tif->tif_diroff > 0xFFFFFFFFU ) + { + TIFFErrorExt(tif->tif_clientdata, module, + "tif->tif_diroff exceeds 32 bit range allowed for Classic TIFF"); + return (0); + } else { uint32_t nextdir; @@ -337,6 +343,8 @@ TIFFRewriteDirectory( TIFF *tif ) return (0); } tif->tif_diroff=0; + /* Force a full-traversal to reach the zeroed pointer */ + tif->tif_lastdiroff=0; break; } nextdir=nextnextdir; @@ -403,6 +411,8 @@ TIFFRewriteDirectory( TIFF *tif ) return (0); } tif->tif_diroff=0; + /* Force a full-traversal to reach the zeroed pointer */ + tif->tif_lastdiroff=0; break; } nextdir=nextnextdir; @@ -477,6 +487,12 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64_t* pdiroff) } tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP); } + + if (TIFFFieldSet(tif,FIELD_COMPRESSION) && (tif->tif_dir.td_compression == COMPRESSION_DEFLATE)) { + TIFFWarningExt(tif->tif_clientdata, module, + "Creating TIFF with legacy Deflate codec identifier, " + "COMPRESSION_ADOBE_DEFLATE is more widely supported"); + } dir=NULL; dirmem=NULL; dirsize=0; @@ -814,7 +830,7 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64_t* pdiroff) { /*-- Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size. */ int tv_size; - tv_size = _TIFFSetGetFieldSize(tif->tif_dir.td_customValues[m].info->set_field_type); + tv_size = TIFFFieldSetGetSize(tif->tif_dir.td_customValues[m].info); if (tv_size == 8) { if (!TIFFWriteDirectoryTagRationalDoubleArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) goto bad; @@ -833,7 +849,7 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64_t* pdiroff) { /*-- Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size. */ int tv_size; - tv_size = _TIFFSetGetFieldSize(tif->tif_dir.td_customValues[m].info->set_field_type); + tv_size = TIFFFieldSetGetSize(tif->tif_dir.td_customValues[m].info); if (tv_size == 8) { if (!TIFFWriteDirectoryTagSrationalDoubleArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) goto bad; @@ -1774,10 +1790,12 @@ static int _WriteAsType(TIFF* tif, uint64_t strile_size, uint64_t uncompressed_t else if ( compression == COMPRESSION_JPEG || compression == COMPRESSION_LZW || compression == COMPRESSION_ADOBE_DEFLATE || + compression == COMPRESSION_DEFLATE || compression == COMPRESSION_LZMA || compression == COMPRESSION_LERC || compression == COMPRESSION_ZSTD || - compression == COMPRESSION_WEBP ) + compression == COMPRESSION_WEBP || + compression == COMPRESSION_JXL ) { /* For a few select compression types, we assume that in the worst */ /* case the compressed size will be 10 times the uncompressed size */ @@ -3058,7 +3076,12 @@ TIFFWriteDirectoryTagData(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data"); return(0); } - assert(datalength<0x80000000UL); + if (datalength >= 0x80000000UL) + { + TIFFErrorExt(tif->tif_clientdata,module, + "libtiff does not allow writing more than 2147483647 bytes in a tag"); + return(0); + } if (!WriteOK(tif,data,(tmsize_t)datalength)) { TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data"); @@ -3161,6 +3184,7 @@ TIFFLinkDirectory(TIFF* tif) * First directory, overwrite offset in header. */ tif->tif_header.classic.tiff_diroff = (uint32_t) tif->tif_diroff; + tif->tif_lastdiroff = tif->tif_diroff; (void) TIFFSeekFile(tif,4, SEEK_SET); if (!WriteOK(tif, &m, 4)) { TIFFErrorExt(tif->tif_clientdata, tif->tif_name, @@ -3172,7 +3196,13 @@ TIFFLinkDirectory(TIFF* tif) /* * Not the first directory, search to the last and append. */ - nextdir = tif->tif_header.classic.tiff_diroff; + if (tif->tif_lastdiroff != 0) { + nextdir = (uint32_t) tif->tif_lastdiroff; + } + else { + nextdir = tif->tif_header.classic.tiff_diroff; + } + while(1) { uint16_t dircount; uint32_t nextnextdir; @@ -3203,6 +3233,7 @@ TIFFLinkDirectory(TIFF* tif) "Error writing directory link"); return (0); } + tif->tif_lastdiroff = tif->tif_diroff; break; } nextdir=nextnextdir; @@ -3220,6 +3251,7 @@ TIFFLinkDirectory(TIFF* tif) * First directory, overwrite offset in header. */ tif->tif_header.big.tiff_diroff = tif->tif_diroff; + tif->tif_lastdiroff = tif->tif_diroff; (void) TIFFSeekFile(tif,8, SEEK_SET); if (!WriteOK(tif, &m, 8)) { TIFFErrorExt(tif->tif_clientdata, tif->tif_name, @@ -3231,7 +3263,12 @@ TIFFLinkDirectory(TIFF* tif) /* * Not the first directory, search to the last and append. */ - nextdir = tif->tif_header.big.tiff_diroff; + if (tif->tif_lastdiroff != 0) { + nextdir = tif->tif_lastdiroff; + } + else { + nextdir = tif->tif_header.big.tiff_diroff; + } while(1) { uint64_t dircount64; uint16_t dircount; @@ -3270,6 +3307,7 @@ TIFFLinkDirectory(TIFF* tif) "Error writing directory link"); return (0); } + tif->tif_lastdiroff = tif->tif_diroff; break; } nextdir=nextnextdir; @@ -3668,7 +3706,16 @@ _TIFFRewriteField(TIFF* tif, uint16_t tag, TIFFDataType in_datatype, } else { - memcpy( &entry_offset, buf_to_write, count*TIFFDataWidth(datatype)); + if( count*TIFFDataWidth(datatype) == 4 ) + { + uint32_t value; + memcpy( &value, buf_to_write, count*TIFFDataWidth(datatype)); + entry_offset = value; + } + else + { + memcpy( &entry_offset, buf_to_write, count*TIFFDataWidth(datatype)); + } } _TIFFfree( buf_to_write ); diff --git a/src/3rdparty/libtiff/libtiff/tif_jbig.c b/src/3rdparty/libtiff/libtiff/tif_jbig.c index 7408633..8bfa4ce 100644 --- a/src/3rdparty/libtiff/libtiff/tif_jbig.c +++ b/src/3rdparty/libtiff/libtiff/tif_jbig.c @@ -209,6 +209,16 @@ int TIFFInitJBIG(TIFF* tif, int scheme) */ tif->tif_flags |= TIFF_NOBITREV; tif->tif_flags &= ~TIFF_MAPPED; + /* We may have read from a previous IFD and thus set TIFF_BUFFERMMAP and + * cleared TIFF_MYBUFFER. It is necessary to restore them to their initial + * value to be consistent with the state of a non-memory mapped file. + */ + if (tif->tif_flags&TIFF_BUFFERMMAP) { + tif->tif_rawdata = NULL; + tif->tif_rawdatasize = 0; + tif->tif_flags &= ~TIFF_BUFFERMMAP; + tif->tif_flags |= TIFF_MYBUFFER; + } /* Setup the function pointers for encode, decode, and cleanup. */ tif->tif_setupdecode = JBIGSetupDecode; diff --git a/src/3rdparty/libtiff/libtiff/tif_jpeg.c b/src/3rdparty/libtiff/libtiff/tif_jpeg.c index 6076c11..dc57b85 100644 --- a/src/3rdparty/libtiff/libtiff/tif_jpeg.c +++ b/src/3rdparty/libtiff/libtiff/tif_jpeg.c @@ -2,23 +2,23 @@ * Copyright (c) 1994-1997 Sam Leffler * Copyright (c) 1994-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -44,10 +44,33 @@ */ #include <setjmp.h> -int TIFFFillStrip(TIFF* tif, uint32_t strip); -int TIFFFillTile(TIFF* tif, uint32_t tile); -int TIFFReInitJPEG_12( TIFF *tif, int scheme, int is_encode ); -int TIFFJPEGIsFullStripRequired_12(TIFF* tif); +/* Settings that are independent of libjpeg ABI. Used when reinitializing the */ +/* JPEGState from libjpegs 8 bit to libjpeg 12 bits, which have potentially */ +/* different ABI */ +typedef struct { + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ + TIFFPrintMethod printdir; /* super-class method */ + TIFFStripMethod defsparent; /* super-class method */ + TIFFTileMethod deftparent; /* super-class method */ + + /* pseudo-tag fields */ + void *jpegtables; /* JPEGTables tag value, or NULL */ + uint32_t jpegtables_length; /* number of bytes in same */ + int jpegquality; /* Compression quality level */ + int jpegcolormode; /* Auto RGB<=>YCbCr convert? */ + int jpegtablesmode; /* What to put in JPEGTables */ + + int ycbcrsampling_fetched; + int max_allowed_scan_number; + int has_warned_about_progressive_mode; +} JPEGOtherSettings; + +int TIFFFillStrip(TIFF *tif, uint32_t strip); +int TIFFFillTile(TIFF *tif, uint32_t tile); +int TIFFReInitJPEG_12(TIFF *tif, const JPEGOtherSettings *otherSettings, + int scheme, int is_encode); +int TIFFJPEGIsFullStripRequired_12(TIFF *tif); /* We undefine FAR to avoid conflict with JPEG definition */ @@ -62,7 +85,7 @@ int TIFFJPEGIsFullStripRequired_12(TIFF* tif); a conflicting typedef given the headers which are included. */ #if defined(__BORLANDC__) || defined(__MINGW32__) -# define XMD_H 1 +#define XMD_H 1 #endif /* @@ -80,24 +103,24 @@ int TIFFJPEGIsFullStripRequired_12(TIFF* tif); /* Define "boolean" as unsigned char, not int, per Windows custom. */ #if defined(__WIN32__) && !defined(__MINGW32__) -# ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ - typedef unsigned char boolean; -# endif -# define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ +#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ +typedef unsigned char boolean; +#endif +#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ #endif -#include "jpeglib.h" #include "jerror.h" +#include "jpeglib.h" -/* +/* * Do we want to do special processing suitable for when JSAMPLE is a - * 16bit value? + * 16bit value? */ #if defined(JPEG_LIB_MK1) -# define JPEG_LIB_MK1_OR_12BIT 1 +#define JPEG_LIB_MK1_OR_12BIT 1 #elif BITS_IN_JSAMPLE == 12 -# define JPEG_LIB_MK1_OR_12BIT 1 +#define JPEG_LIB_MK1_OR_12BIT 1 #endif /* @@ -115,9 +138,9 @@ int TIFFJPEGIsFullStripRequired_12(TIFF* tif); * On some machines it may be worthwhile to use _setjmp or sigsetjmp * in place of plain setjmp. These macros will make it easier. */ -#define SETJMP(jbuf) setjmp(jbuf) -#define LONGJMP(jbuf,code) longjmp(jbuf,code) -#define JMP_BUF jmp_buf +#define SETJMP(jbuf) setjmp(jbuf) +#define LONGJMP(jbuf, code) longjmp(jbuf, code) +#define JMP_BUF jmp_buf typedef struct jpeg_destination_mgr jpeg_destination_mgr; typedef struct jpeg_source_mgr jpeg_source_mgr; @@ -137,67 +160,57 @@ typedef struct jpeg_error_mgr jpeg_error_mgr; * and vice versa! */ typedef struct { - union { - struct jpeg_compress_struct c; - struct jpeg_decompress_struct d; - struct jpeg_common_struct comm; - } cinfo; /* NB: must be first */ - int cinfo_initialized; - - jpeg_error_mgr err; /* libjpeg error manager */ - JMP_BUF exit_jmpbuf; /* for catching libjpeg failures */ - - struct jpeg_progress_mgr progress; - /* - * The following two members could be a union, but - * they're small enough that it's not worth the effort. - */ - jpeg_destination_mgr dest; /* data dest for compression */ - jpeg_source_mgr src; /* data source for decompression */ - /* private state */ - TIFF* tif; /* back link needed by some code */ - uint16_t photometric; /* copy of PhotometricInterpretation */ - uint16_t h_sampling; /* luminance sampling factors */ - uint16_t v_sampling; - tmsize_t bytesperline; /* decompressed bytes per scanline */ - /* pointers to intermediate buffers when processing downsampled data */ - JSAMPARRAY ds_buffer[MAX_COMPONENTS]; - int scancount; /* number of "scanlines" accumulated */ - int samplesperclump; - - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ - TIFFPrintMethod printdir; /* super-class method */ - TIFFStripMethod defsparent; /* super-class method */ - TIFFTileMethod deftparent; /* super-class method */ - /* pseudo-tag fields */ - void* jpegtables; /* JPEGTables tag value, or NULL */ - uint32_t jpegtables_length; /* number of bytes in same */ - int jpegquality; /* Compression quality level */ - int jpegcolormode; /* Auto RGB<=>YCbCr convert? */ - int jpegtablesmode; /* What to put in JPEGTables */ - - int ycbcrsampling_fetched; - int max_allowed_scan_number; + union { + struct jpeg_compress_struct c; + struct jpeg_decompress_struct d; + struct jpeg_common_struct comm; + } cinfo; /* NB: must be first */ + int cinfo_initialized; + + jpeg_error_mgr err; /* libjpeg error manager */ + JMP_BUF exit_jmpbuf; /* for catching libjpeg failures */ + + struct jpeg_progress_mgr progress; + /* + * The following two members could be a union, but + * they're small enough that it's not worth the effort. + */ + jpeg_destination_mgr dest; /* data dest for compression */ + jpeg_source_mgr src; /* data source for decompression */ + /* private state */ + TIFF *tif; /* back link needed by some code */ + uint16_t photometric; /* copy of PhotometricInterpretation */ + uint16_t h_sampling; /* luminance sampling factors */ + uint16_t v_sampling; + tmsize_t bytesperline; /* decompressed bytes per scanline */ + /* pointers to intermediate buffers when processing downsampled data */ + JSAMPARRAY ds_buffer[MAX_COMPONENTS]; + int scancount; /* number of "scanlines" accumulated */ + int samplesperclump; + + JPEGOtherSettings otherSettings; } JPEGState; -#define JState(tif) ((JPEGState*)(tif)->tif_data) +#define JState(tif) ((JPEGState *)(tif)->tif_data) -static int JPEGDecode(TIFF* tif, uint8_t* buf, tmsize_t cc, uint16_t s); -static int JPEGDecodeRaw(TIFF* tif, uint8_t* buf, tmsize_t cc, uint16_t s); -static int JPEGEncode(TIFF* tif, uint8_t* buf, tmsize_t cc, uint16_t s); -static int JPEGEncodeRaw(TIFF* tif, uint8_t* buf, tmsize_t cc, uint16_t s); -static int JPEGInitializeLibJPEG(TIFF * tif, int decode ); -static int DecodeRowError(TIFF* tif, uint8_t* buf, tmsize_t cc, uint16_t s); +static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s); +static int JPEGDecodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s); +static int JPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s); +static int JPEGEncodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s); +static int JPEGInitializeLibJPEG(TIFF *tif, int decode); +static int DecodeRowError(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s); -#define FIELD_JPEGTABLES (FIELD_CODEC+0) +#define FIELD_JPEGTABLES (FIELD_CODEC + 0) static const TIFFField jpegFields[] = { - { TIFFTAG_JPEGTABLES, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_C32_UINT8, FIELD_JPEGTABLES, FALSE, TRUE, "JPEGTables", NULL }, - { TIFFTAG_JPEGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL }, - { TIFFTAG_JPEGCOLORMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL }, - { TIFFTAG_JPEGTABLESMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL } -}; + {TIFFTAG_JPEGTABLES, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, + TIFF_SETGET_C32_UINT8, FIELD_JPEGTABLES, FALSE, TRUE, "JPEGTables", NULL}, + {TIFFTAG_JPEGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL}, + {TIFFTAG_JPEGCOLORMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}, + {TIFFTAG_JPEGTABLESMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}}; /* * libjpeg interface layer. @@ -213,16 +226,15 @@ static const TIFFField jpegFields[] = { * IJG routines from jerror.c). These are used for both * compression and decompression. */ -static void -TIFFjpeg_error_exit(j_common_ptr cinfo) -{ - JPEGState *sp = (JPEGState *) cinfo; /* NB: cinfo assumed first */ - char buffer[JMSG_LENGTH_MAX]; +static void TIFFjpeg_error_exit(j_common_ptr cinfo) { + JPEGState *sp = (JPEGState *)cinfo; /* NB: cinfo assumed first */ + char buffer[JMSG_LENGTH_MAX]; - (*cinfo->err->format_message) (cinfo, buffer); - TIFFErrorExt(sp->tif->tif_clientdata, "JPEGLib", "%s", buffer); /* display the error message */ - jpeg_abort(cinfo); /* clean up libjpeg state */ - LONGJMP(sp->exit_jmpbuf, 1); /* return to libtiff caller */ + (*cinfo->err->format_message)(cinfo, buffer); + TIFFErrorExt(sp->tif->tif_clientdata, "JPEGLib", "%s", + buffer); /* display the error message */ + jpeg_abort(cinfo); /* clean up libjpeg state */ + LONGJMP(sp->exit_jmpbuf, 1); /* return to libtiff caller */ } /* @@ -230,203 +242,168 @@ TIFFjpeg_error_exit(j_common_ptr cinfo) * since error_exit does its own thing and trace_level * is never set > 0. */ -static void -TIFFjpeg_output_message(j_common_ptr cinfo) -{ - char buffer[JMSG_LENGTH_MAX]; +static void TIFFjpeg_output_message(j_common_ptr cinfo) { + char buffer[JMSG_LENGTH_MAX]; - (*cinfo->err->format_message) (cinfo, buffer); - TIFFWarningExt(((JPEGState *) cinfo)->tif->tif_clientdata, "JPEGLib", "%s", buffer); + (*cinfo->err->format_message)(cinfo, buffer); + TIFFWarningExt(((JPEGState *)cinfo)->tif->tif_clientdata, "JPEGLib", "%s", + buffer); } /* Avoid the risk of denial-of-service on crafted JPEGs with an insane */ /* number of scans. */ -/* See http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf */ -static void -TIFFjpeg_progress_monitor(j_common_ptr cinfo) -{ - JPEGState *sp = (JPEGState *) cinfo; /* NB: cinfo assumed first */ - if (cinfo->is_decompressor) - { - const int scan_no = - ((j_decompress_ptr)cinfo)->input_scan_number; - if (scan_no >= sp->max_allowed_scan_number) - { - TIFFErrorExt(((JPEGState *) cinfo)->tif->tif_clientdata, - "TIFFjpeg_progress_monitor", - "Scan number %d exceeds maximum scans (%d). This limit " - "can be raised through the LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER " - "environment variable.", - scan_no, sp->max_allowed_scan_number); - - jpeg_abort(cinfo); /* clean up libjpeg state */ - LONGJMP(sp->exit_jmpbuf, 1); /* return to libtiff caller */ - } +/* See + * http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf + */ +static void TIFFjpeg_progress_monitor(j_common_ptr cinfo) { + JPEGState *sp = (JPEGState *)cinfo; /* NB: cinfo assumed first */ + if (cinfo->is_decompressor) { + const int scan_no = ((j_decompress_ptr)cinfo)->input_scan_number; + if (scan_no >= sp->otherSettings.max_allowed_scan_number) { + TIFFErrorExt( + ((JPEGState *)cinfo)->tif->tif_clientdata, + "TIFFjpeg_progress_monitor", + "Scan number %d exceeds maximum scans (%d). This limit " + "can be raised through the LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER " + "environment variable.", + scan_no, sp->otherSettings.max_allowed_scan_number); + + jpeg_abort(cinfo); /* clean up libjpeg state */ + LONGJMP(sp->exit_jmpbuf, 1); /* return to libtiff caller */ } + } } - /* * Interface routines. This layer of routines exists * primarily to limit side-effects from using setjmp. * Also, normal/error returns are converted into return * values per libtiff practice. */ -#define CALLJPEG(sp, fail, op) (SETJMP((sp)->exit_jmpbuf) ? (fail) : (op)) -#define CALLVJPEG(sp, op) CALLJPEG(sp, 0, ((op),1)) +#define CALLJPEG(sp, fail, op) (SETJMP((sp)->exit_jmpbuf) ? (fail) : (op)) +#define CALLVJPEG(sp, op) CALLJPEG(sp, 0, ((op), 1)) -static int -TIFFjpeg_create_compress(JPEGState* sp) -{ - /* initialize JPEG error handling */ - sp->cinfo.c.err = jpeg_std_error(&sp->err); - sp->err.error_exit = TIFFjpeg_error_exit; - sp->err.output_message = TIFFjpeg_output_message; +static int TIFFjpeg_create_compress(JPEGState *sp) { + /* initialize JPEG error handling */ + sp->cinfo.c.err = jpeg_std_error(&sp->err); + sp->err.error_exit = TIFFjpeg_error_exit; + sp->err.output_message = TIFFjpeg_output_message; - /* set client_data to avoid UMR warning from tools like Purify */ - sp->cinfo.c.client_data = NULL; + /* set client_data to avoid UMR warning from tools like Purify */ + sp->cinfo.c.client_data = NULL; - return CALLVJPEG(sp, jpeg_create_compress(&sp->cinfo.c)); + return CALLVJPEG(sp, jpeg_create_compress(&sp->cinfo.c)); } -static int -TIFFjpeg_create_decompress(JPEGState* sp) -{ - /* initialize JPEG error handling */ - sp->cinfo.d.err = jpeg_std_error(&sp->err); - sp->err.error_exit = TIFFjpeg_error_exit; - sp->err.output_message = TIFFjpeg_output_message; +static int TIFFjpeg_create_decompress(JPEGState *sp) { + /* initialize JPEG error handling */ + sp->cinfo.d.err = jpeg_std_error(&sp->err); + sp->err.error_exit = TIFFjpeg_error_exit; + sp->err.output_message = TIFFjpeg_output_message; - /* set client_data to avoid UMR warning from tools like Purify */ - sp->cinfo.d.client_data = NULL; + /* set client_data to avoid UMR warning from tools like Purify */ + sp->cinfo.d.client_data = NULL; - return CALLVJPEG(sp, jpeg_create_decompress(&sp->cinfo.d)); + return CALLVJPEG(sp, jpeg_create_decompress(&sp->cinfo.d)); } -static int -TIFFjpeg_set_defaults(JPEGState* sp) -{ - return CALLVJPEG(sp, jpeg_set_defaults(&sp->cinfo.c)); +static int TIFFjpeg_set_defaults(JPEGState *sp) { + return CALLVJPEG(sp, jpeg_set_defaults(&sp->cinfo.c)); } -static int -TIFFjpeg_set_colorspace(JPEGState* sp, J_COLOR_SPACE colorspace) -{ - return CALLVJPEG(sp, jpeg_set_colorspace(&sp->cinfo.c, colorspace)); +static int TIFFjpeg_set_colorspace(JPEGState *sp, J_COLOR_SPACE colorspace) { + return CALLVJPEG(sp, jpeg_set_colorspace(&sp->cinfo.c, colorspace)); } -static int -TIFFjpeg_set_quality(JPEGState* sp, int quality, boolean force_baseline) -{ - return CALLVJPEG(sp, - jpeg_set_quality(&sp->cinfo.c, quality, force_baseline)); +static int TIFFjpeg_set_quality(JPEGState *sp, int quality, + boolean force_baseline) { + return CALLVJPEG(sp, jpeg_set_quality(&sp->cinfo.c, quality, force_baseline)); } -static int -TIFFjpeg_suppress_tables(JPEGState* sp, boolean suppress) -{ - return CALLVJPEG(sp, jpeg_suppress_tables(&sp->cinfo.c, suppress)); +static int TIFFjpeg_suppress_tables(JPEGState *sp, boolean suppress) { + return CALLVJPEG(sp, jpeg_suppress_tables(&sp->cinfo.c, suppress)); } -static int -TIFFjpeg_start_compress(JPEGState* sp, boolean write_all_tables) -{ - return CALLVJPEG(sp, - jpeg_start_compress(&sp->cinfo.c, write_all_tables)); +static int TIFFjpeg_start_compress(JPEGState *sp, boolean write_all_tables) { + return CALLVJPEG(sp, jpeg_start_compress(&sp->cinfo.c, write_all_tables)); } -static int -TIFFjpeg_write_scanlines(JPEGState* sp, JSAMPARRAY scanlines, int num_lines) -{ - return CALLJPEG(sp, -1, (int) jpeg_write_scanlines(&sp->cinfo.c, - scanlines, (JDIMENSION) num_lines)); +static int TIFFjpeg_write_scanlines(JPEGState *sp, JSAMPARRAY scanlines, + int num_lines) { + return CALLJPEG(sp, -1, + (int)jpeg_write_scanlines(&sp->cinfo.c, scanlines, + (JDIMENSION)num_lines)); } -static int -TIFFjpeg_write_raw_data(JPEGState* sp, JSAMPIMAGE data, int num_lines) -{ - return CALLJPEG(sp, -1, (int) jpeg_write_raw_data(&sp->cinfo.c, - data, (JDIMENSION) num_lines)); +static int TIFFjpeg_write_raw_data(JPEGState *sp, JSAMPIMAGE data, + int num_lines) { + return CALLJPEG( + sp, -1, + (int)jpeg_write_raw_data(&sp->cinfo.c, data, (JDIMENSION)num_lines)); } -static int -TIFFjpeg_finish_compress(JPEGState* sp) -{ - return CALLVJPEG(sp, jpeg_finish_compress(&sp->cinfo.c)); +static int TIFFjpeg_finish_compress(JPEGState *sp) { + return CALLVJPEG(sp, jpeg_finish_compress(&sp->cinfo.c)); } -static int -TIFFjpeg_write_tables(JPEGState* sp) -{ - return CALLVJPEG(sp, jpeg_write_tables(&sp->cinfo.c)); +static int TIFFjpeg_write_tables(JPEGState *sp) { + return CALLVJPEG(sp, jpeg_write_tables(&sp->cinfo.c)); } -static int -TIFFjpeg_read_header(JPEGState* sp, boolean require_image) -{ - return CALLJPEG(sp, -1, jpeg_read_header(&sp->cinfo.d, require_image)); +static int TIFFjpeg_read_header(JPEGState *sp, boolean require_image) { + return CALLJPEG(sp, -1, jpeg_read_header(&sp->cinfo.d, require_image)); } -static int -TIFFjpeg_has_multiple_scans(JPEGState* sp) -{ - return CALLJPEG(sp, 0, jpeg_has_multiple_scans(&sp->cinfo.d)); +static int TIFFjpeg_has_multiple_scans(JPEGState *sp) { + return CALLJPEG(sp, 0, jpeg_has_multiple_scans(&sp->cinfo.d)); } -static int -TIFFjpeg_start_decompress(JPEGState* sp) -{ - const char* sz_max_allowed_scan_number; - /* progress monitor */ - sp->cinfo.d.progress = &sp->progress; - sp->progress.progress_monitor = TIFFjpeg_progress_monitor; - sp->max_allowed_scan_number = 100; - sz_max_allowed_scan_number = getenv("LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER"); - if( sz_max_allowed_scan_number ) - sp->max_allowed_scan_number = atoi(sz_max_allowed_scan_number); +static int TIFFjpeg_start_decompress(JPEGState *sp) { + const char *sz_max_allowed_scan_number; + /* progress monitor */ + sp->cinfo.d.progress = &sp->progress; + sp->progress.progress_monitor = TIFFjpeg_progress_monitor; + sp->otherSettings.max_allowed_scan_number = 100; + sz_max_allowed_scan_number = getenv("LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER"); + if (sz_max_allowed_scan_number) + sp->otherSettings.max_allowed_scan_number = + atoi(sz_max_allowed_scan_number); - return CALLVJPEG(sp, jpeg_start_decompress(&sp->cinfo.d)); + return CALLVJPEG(sp, jpeg_start_decompress(&sp->cinfo.d)); } -static int -TIFFjpeg_read_scanlines(JPEGState* sp, JSAMPARRAY scanlines, int max_lines) -{ - return CALLJPEG(sp, -1, (int) jpeg_read_scanlines(&sp->cinfo.d, - scanlines, (JDIMENSION) max_lines)); +static int TIFFjpeg_read_scanlines(JPEGState *sp, JSAMPARRAY scanlines, + int max_lines) { + return CALLJPEG( + sp, -1, + (int)jpeg_read_scanlines(&sp->cinfo.d, scanlines, (JDIMENSION)max_lines)); } -static int -TIFFjpeg_read_raw_data(JPEGState* sp, JSAMPIMAGE data, int max_lines) -{ - return CALLJPEG(sp, -1, (int) jpeg_read_raw_data(&sp->cinfo.d, - data, (JDIMENSION) max_lines)); +static int TIFFjpeg_read_raw_data(JPEGState *sp, JSAMPIMAGE data, + int max_lines) { + return CALLJPEG( + sp, -1, + (int)jpeg_read_raw_data(&sp->cinfo.d, data, (JDIMENSION)max_lines)); } -static int -TIFFjpeg_finish_decompress(JPEGState* sp) -{ - return CALLJPEG(sp, -1, (int) jpeg_finish_decompress(&sp->cinfo.d)); +static int TIFFjpeg_finish_decompress(JPEGState *sp) { + return CALLJPEG(sp, -1, (int)jpeg_finish_decompress(&sp->cinfo.d)); } -static int -TIFFjpeg_abort(JPEGState* sp) -{ - return CALLVJPEG(sp, jpeg_abort(&sp->cinfo.comm)); +static int TIFFjpeg_abort(JPEGState *sp) { + return CALLVJPEG(sp, jpeg_abort(&sp->cinfo.comm)); } -static int -TIFFjpeg_destroy(JPEGState* sp) -{ - return CALLVJPEG(sp, jpeg_destroy(&sp->cinfo.comm)); +static int TIFFjpeg_destroy(JPEGState *sp) { + return CALLVJPEG(sp, jpeg_destroy(&sp->cinfo.comm)); } -static JSAMPARRAY -TIFFjpeg_alloc_sarray(JPEGState* sp, int pool_id, - JDIMENSION samplesperrow, JDIMENSION numrows) -{ - return CALLJPEG(sp, (JSAMPARRAY) NULL, - (*sp->cinfo.comm.mem->alloc_sarray) - (&sp->cinfo.comm, pool_id, samplesperrow, numrows)); +static JSAMPARRAY TIFFjpeg_alloc_sarray(JPEGState *sp, int pool_id, + JDIMENSION samplesperrow, + JDIMENSION numrows) { + return CALLJPEG(sp, (JSAMPARRAY)NULL, + (*sp->cinfo.comm.mem->alloc_sarray)(&sp->cinfo.comm, pool_id, + samplesperrow, numrows)); } /* @@ -435,130 +412,116 @@ TIFFjpeg_alloc_sarray(JPEGState* sp, int pool_id, * libtiff output buffer. */ -static void -std_init_destination(j_compress_ptr cinfo) -{ - JPEGState* sp = (JPEGState*) cinfo; - TIFF* tif = sp->tif; +static void std_init_destination(j_compress_ptr cinfo) { + JPEGState *sp = (JPEGState *)cinfo; + TIFF *tif = sp->tif; - sp->dest.next_output_byte = (JOCTET*) tif->tif_rawdata; - sp->dest.free_in_buffer = (size_t) tif->tif_rawdatasize; + sp->dest.next_output_byte = (JOCTET *)tif->tif_rawdata; + sp->dest.free_in_buffer = (size_t)tif->tif_rawdatasize; } -static boolean -std_empty_output_buffer(j_compress_ptr cinfo) -{ - JPEGState* sp = (JPEGState*) cinfo; - TIFF* tif = sp->tif; +static boolean std_empty_output_buffer(j_compress_ptr cinfo) { + JPEGState *sp = (JPEGState *)cinfo; + TIFF *tif = sp->tif; - /* the entire buffer has been filled */ - tif->tif_rawcc = tif->tif_rawdatasize; + /* the entire buffer has been filled */ + tif->tif_rawcc = tif->tif_rawdatasize; #ifdef IPPJ_HUFF - /* - * The Intel IPP performance library does not necessarily fill up - * the whole output buffer on each pass, so only dump out the parts - * that have been filled. - * http://trac.osgeo.org/gdal/wiki/JpegIPP - */ - if ( sp->dest.free_in_buffer >= 0 ) { - tif->tif_rawcc = tif->tif_rawdatasize - sp->dest.free_in_buffer; - } + /* + * The Intel IPP performance library does not necessarily fill up + * the whole output buffer on each pass, so only dump out the parts + * that have been filled. + * http://trac.osgeo.org/gdal/wiki/JpegIPP + */ + if (sp->dest.free_in_buffer >= 0) { + tif->tif_rawcc = tif->tif_rawdatasize - sp->dest.free_in_buffer; + } #endif - if( !TIFFFlushData1(tif) ) - return FALSE; - sp->dest.next_output_byte = (JOCTET*) tif->tif_rawdata; - sp->dest.free_in_buffer = (size_t) tif->tif_rawdatasize; + if (!TIFFFlushData1(tif)) + return FALSE; + sp->dest.next_output_byte = (JOCTET *)tif->tif_rawdata; + sp->dest.free_in_buffer = (size_t)tif->tif_rawdatasize; - return (TRUE); + return (TRUE); } -static void -std_term_destination(j_compress_ptr cinfo) -{ - JPEGState* sp = (JPEGState*) cinfo; - TIFF* tif = sp->tif; +static void std_term_destination(j_compress_ptr cinfo) { + JPEGState *sp = (JPEGState *)cinfo; + TIFF *tif = sp->tif; - tif->tif_rawcp = (uint8_t*) sp->dest.next_output_byte; - tif->tif_rawcc = - tif->tif_rawdatasize - (tmsize_t) sp->dest.free_in_buffer; - /* NB: libtiff does the final buffer flush */ + tif->tif_rawcp = (uint8_t *)sp->dest.next_output_byte; + tif->tif_rawcc = tif->tif_rawdatasize - (tmsize_t)sp->dest.free_in_buffer; + /* NB: libtiff does the final buffer flush */ } -static void -TIFFjpeg_data_dest(JPEGState* sp, TIFF* tif) -{ - (void) tif; - sp->cinfo.c.dest = &sp->dest; - sp->dest.init_destination = std_init_destination; - sp->dest.empty_output_buffer = std_empty_output_buffer; - sp->dest.term_destination = std_term_destination; +static void TIFFjpeg_data_dest(JPEGState *sp, TIFF *tif) { + (void)tif; + sp->cinfo.c.dest = &sp->dest; + sp->dest.init_destination = std_init_destination; + sp->dest.empty_output_buffer = std_empty_output_buffer; + sp->dest.term_destination = std_term_destination; } /* * Alternate destination manager for outputting to JPEGTables field. */ -static void -tables_init_destination(j_compress_ptr cinfo) -{ - JPEGState* sp = (JPEGState*) cinfo; - - /* while building, jpegtables_length is allocated buffer size */ - sp->dest.next_output_byte = (JOCTET*) sp->jpegtables; - sp->dest.free_in_buffer = (size_t) sp->jpegtables_length; -} - -static boolean -tables_empty_output_buffer(j_compress_ptr cinfo) -{ - JPEGState* sp = (JPEGState*) cinfo; - void* newbuf; - - /* the entire buffer has been filled; enlarge it by 1000 bytes */ - newbuf = _TIFFrealloc((void*) sp->jpegtables, - (tmsize_t) (sp->jpegtables_length + 1000)); - if (newbuf == NULL) - ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 100); - sp->dest.next_output_byte = (JOCTET*) newbuf + sp->jpegtables_length; - sp->dest.free_in_buffer = (size_t) 1000; - sp->jpegtables = newbuf; - sp->jpegtables_length += 1000; - return (TRUE); -} - -static void -tables_term_destination(j_compress_ptr cinfo) -{ - JPEGState* sp = (JPEGState*) cinfo; - - /* set tables length to number of bytes actually emitted */ - sp->jpegtables_length -= (uint32_t) sp->dest.free_in_buffer; -} - -static int -TIFFjpeg_tables_dest(JPEGState* sp, TIFF* tif) -{ - (void) tif; - /* - * Allocate a working buffer for building tables. - * Initial size is 1000 bytes, which is usually adequate. - */ - if (sp->jpegtables) - _TIFFfree(sp->jpegtables); - sp->jpegtables_length = 1000; - sp->jpegtables = (void*) _TIFFmalloc((tmsize_t) sp->jpegtables_length); - if (sp->jpegtables == NULL) { - sp->jpegtables_length = 0; - TIFFErrorExt(sp->tif->tif_clientdata, "TIFFjpeg_tables_dest", "No space for JPEGTables"); - return (0); - } - sp->cinfo.c.dest = &sp->dest; - sp->dest.init_destination = tables_init_destination; - sp->dest.empty_output_buffer = tables_empty_output_buffer; - sp->dest.term_destination = tables_term_destination; - return (1); +static void tables_init_destination(j_compress_ptr cinfo) { + JPEGState *sp = (JPEGState *)cinfo; + + /* while building, otherSettings.jpegtables_length is allocated buffer size */ + sp->dest.next_output_byte = (JOCTET *)sp->otherSettings.jpegtables; + sp->dest.free_in_buffer = (size_t)sp->otherSettings.jpegtables_length; +} + +static boolean tables_empty_output_buffer(j_compress_ptr cinfo) { + JPEGState *sp = (JPEGState *)cinfo; + void *newbuf; + + /* the entire buffer has been filled; enlarge it by 1000 bytes */ + newbuf = _TIFFrealloc((void *)sp->otherSettings.jpegtables, + (tmsize_t)(sp->otherSettings.jpegtables_length + 1000)); + if (newbuf == NULL) + ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 100); + sp->dest.next_output_byte = + (JOCTET *)newbuf + sp->otherSettings.jpegtables_length; + sp->dest.free_in_buffer = (size_t)1000; + sp->otherSettings.jpegtables = newbuf; + sp->otherSettings.jpegtables_length += 1000; + return (TRUE); +} + +static void tables_term_destination(j_compress_ptr cinfo) { + JPEGState *sp = (JPEGState *)cinfo; + + /* set tables length to number of bytes actually emitted */ + sp->otherSettings.jpegtables_length -= (uint32_t)sp->dest.free_in_buffer; +} + +static int TIFFjpeg_tables_dest(JPEGState *sp, TIFF *tif) { + (void)tif; + /* + * Allocate a working buffer for building tables. + * Initial size is 1000 bytes, which is usually adequate. + */ + if (sp->otherSettings.jpegtables) + _TIFFfree(sp->otherSettings.jpegtables); + sp->otherSettings.jpegtables_length = 1000; + sp->otherSettings.jpegtables = + (void *)_TIFFmalloc((tmsize_t)sp->otherSettings.jpegtables_length); + if (sp->otherSettings.jpegtables == NULL) { + sp->otherSettings.jpegtables_length = 0; + TIFFErrorExt(sp->tif->tif_clientdata, "TIFFjpeg_tables_dest", + "No space for JPEGTables"); + return (0); + } + sp->cinfo.c.dest = &sp->dest; + sp->dest.init_destination = tables_init_destination; + sp->dest.empty_output_buffer = tables_empty_output_buffer; + sp->dest.term_destination = tables_term_destination; + return (1); } /* @@ -566,86 +529,76 @@ TIFFjpeg_tables_dest(JPEGState* sp, TIFF* tif) * These routines supply compressed data to libjpeg. */ -static void -std_init_source(j_decompress_ptr cinfo) -{ - JPEGState* sp = (JPEGState*) cinfo; - TIFF* tif = sp->tif; +static void std_init_source(j_decompress_ptr cinfo) { + JPEGState *sp = (JPEGState *)cinfo; + TIFF *tif = sp->tif; - sp->src.next_input_byte = (const JOCTET*) tif->tif_rawdata; - sp->src.bytes_in_buffer = (size_t) tif->tif_rawcc; + sp->src.next_input_byte = (const JOCTET *)tif->tif_rawdata; + sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc; } -static boolean -std_fill_input_buffer(j_decompress_ptr cinfo) -{ - JPEGState* sp = (JPEGState* ) cinfo; - static const JOCTET dummy_EOI[2] = { 0xFF, JPEG_EOI }; +static boolean std_fill_input_buffer(j_decompress_ptr cinfo) { + JPEGState *sp = (JPEGState *)cinfo; + static const JOCTET dummy_EOI[2] = {0xFF, JPEG_EOI}; #ifdef IPPJ_HUFF - /* - * The Intel IPP performance library does not necessarily read the whole - * input buffer in one pass, so it is possible to get here with data - * yet to read. - * - * We just return without doing anything, until the entire buffer has - * been read. - * http://trac.osgeo.org/gdal/wiki/JpegIPP - */ - if( sp->src.bytes_in_buffer > 0 ) { - return (TRUE); - } + /* + * The Intel IPP performance library does not necessarily read the whole + * input buffer in one pass, so it is possible to get here with data + * yet to read. + * + * We just return without doing anything, until the entire buffer has + * been read. + * http://trac.osgeo.org/gdal/wiki/JpegIPP + */ + if (sp->src.bytes_in_buffer > 0) { + return (TRUE); + } #endif - /* - * Normally the whole strip/tile is read and so we don't need to do - * a fill. In the case of CHUNKY_STRIP_READ_SUPPORT we might not have - * all the data, but the rawdata is refreshed between scanlines and - * we push this into the io machinery in JPEGDecode(). - * http://trac.osgeo.org/gdal/ticket/3894 - */ - - WARNMS(cinfo, JWRN_JPEG_EOF); - /* insert a fake EOI marker */ - sp->src.next_input_byte = dummy_EOI; - sp->src.bytes_in_buffer = 2; - return (TRUE); + /* + * Normally the whole strip/tile is read and so we don't need to do + * a fill. In the case of CHUNKY_STRIP_READ_SUPPORT we might not have + * all the data, but the rawdata is refreshed between scanlines and + * we push this into the io machinery in JPEGDecode(). + * http://trac.osgeo.org/gdal/ticket/3894 + */ + + WARNMS(cinfo, JWRN_JPEG_EOF); + /* insert a fake EOI marker */ + sp->src.next_input_byte = dummy_EOI; + sp->src.bytes_in_buffer = 2; + return (TRUE); } -static void -std_skip_input_data(j_decompress_ptr cinfo, long num_bytes) -{ - JPEGState* sp = (JPEGState*) cinfo; +static void std_skip_input_data(j_decompress_ptr cinfo, long num_bytes) { + JPEGState *sp = (JPEGState *)cinfo; - if (num_bytes > 0) { - if ((size_t)num_bytes > sp->src.bytes_in_buffer) { - /* oops, buffer overrun */ - (void) std_fill_input_buffer(cinfo); - } else { - sp->src.next_input_byte += (size_t) num_bytes; - sp->src.bytes_in_buffer -= (size_t) num_bytes; - } - } + if (num_bytes > 0) { + if ((size_t)num_bytes > sp->src.bytes_in_buffer) { + /* oops, buffer overrun */ + (void)std_fill_input_buffer(cinfo); + } else { + sp->src.next_input_byte += (size_t)num_bytes; + sp->src.bytes_in_buffer -= (size_t)num_bytes; + } + } } -static void -std_term_source(j_decompress_ptr cinfo) -{ - /* No work necessary here */ - (void) cinfo; +static void std_term_source(j_decompress_ptr cinfo) { + /* No work necessary here */ + (void)cinfo; } -static void -TIFFjpeg_data_src(JPEGState* sp) -{ - sp->cinfo.d.src = &sp->src; - sp->src.init_source = std_init_source; - sp->src.fill_input_buffer = std_fill_input_buffer; - sp->src.skip_input_data = std_skip_input_data; - sp->src.resync_to_restart = jpeg_resync_to_restart; - sp->src.term_source = std_term_source; - sp->src.bytes_in_buffer = 0; /* for safety */ - sp->src.next_input_byte = NULL; +static void TIFFjpeg_data_src(JPEGState *sp) { + sp->cinfo.d.src = &sp->src; + sp->src.init_source = std_init_source; + sp->src.fill_input_buffer = std_fill_input_buffer; + sp->src.skip_input_data = std_skip_input_data; + sp->src.resync_to_restart = jpeg_resync_to_restart; + sp->src.term_source = std_term_source; + sp->src.bytes_in_buffer = 0; /* for safety */ + sp->src.next_input_byte = NULL; } /* @@ -653,20 +606,16 @@ TIFFjpeg_data_src(JPEGState* sp) * We can share all the code except for the init routine. */ -static void -tables_init_source(j_decompress_ptr cinfo) -{ - JPEGState* sp = (JPEGState*) cinfo; +static void tables_init_source(j_decompress_ptr cinfo) { + JPEGState *sp = (JPEGState *)cinfo; - sp->src.next_input_byte = (const JOCTET*) sp->jpegtables; - sp->src.bytes_in_buffer = (size_t) sp->jpegtables_length; + sp->src.next_input_byte = (const JOCTET *)sp->otherSettings.jpegtables; + sp->src.bytes_in_buffer = (size_t)sp->otherSettings.jpegtables_length; } -static void -TIFFjpeg_tables_src(JPEGState* sp) -{ - TIFFjpeg_data_src(sp); - sp->src.init_source = tables_init_source; +static void TIFFjpeg_tables_src(JPEGState *sp) { + TIFFjpeg_data_src(sp); + sp->src.init_source = tables_init_source; } /* @@ -676,32 +625,27 @@ TIFFjpeg_tables_src(JPEGState* sp) * when done with strip/tile. * This is also a handy place to compute samplesperclump, bytesperline. */ -static int -alloc_downsampled_buffers(TIFF* tif, jpeg_component_info* comp_info, - int num_components) -{ - JPEGState* sp = JState(tif); - int ci; - jpeg_component_info* compptr; - JSAMPARRAY buf; - int samples_per_clump = 0; - - for (ci = 0, compptr = comp_info; ci < num_components; - ci++, compptr++) { - samples_per_clump += compptr->h_samp_factor * - compptr->v_samp_factor; - buf = TIFFjpeg_alloc_sarray(sp, JPOOL_IMAGE, - compptr->width_in_blocks * DCTSIZE, - (JDIMENSION) (compptr->v_samp_factor*DCTSIZE)); - if (buf == NULL) - return (0); - sp->ds_buffer[ci] = buf; - } - sp->samplesperclump = samples_per_clump; - return (1); +static int alloc_downsampled_buffers(TIFF *tif, jpeg_component_info *comp_info, + int num_components) { + JPEGState *sp = JState(tif); + int ci; + jpeg_component_info *compptr; + JSAMPARRAY buf; + int samples_per_clump = 0; + + for (ci = 0, compptr = comp_info; ci < num_components; ci++, compptr++) { + samples_per_clump += compptr->h_samp_factor * compptr->v_samp_factor; + buf = TIFFjpeg_alloc_sarray(sp, JPOOL_IMAGE, + compptr->width_in_blocks * DCTSIZE, + (JDIMENSION)(compptr->v_samp_factor * DCTSIZE)); + if (buf == NULL) + return (0); + sp->ds_buffer[ci] = buf; + } + sp->samplesperclump = samples_per_clump; + return (1); } - /* * JPEG Decoding. */ @@ -720,333 +664,331 @@ alloc_downsampled_buffers(TIFF* tif, jpeg_component_info* comp_info, #define JPEG_MARKER_DRI 0xDD #define JPEG_MARKER_APP0 0xE0 #define JPEG_MARKER_COM 0xFE -struct JPEGFixupTagsSubsamplingData -{ - TIFF* tif; - void* buffer; - uint32_t buffersize; - uint8_t* buffercurrentbyte; - uint32_t bufferbytesleft; - uint64_t fileoffset; - uint64_t filebytesleft; - uint8_t filepositioned; +struct JPEGFixupTagsSubsamplingData { + TIFF *tif; + void *buffer; + uint32_t buffersize; + uint8_t *buffercurrentbyte; + uint32_t bufferbytesleft; + uint64_t fileoffset; + uint64_t filebytesleft; + uint8_t filepositioned; }; -static void JPEGFixupTagsSubsampling(TIFF* tif); -static int JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData* data); -static int JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData* data, uint8_t* result); -static int JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData* data, uint16_t* result); -static void JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData* data, uint16_t skiplength); +static void JPEGFixupTagsSubsampling(TIFF *tif); +static int +JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData *data); +static int +JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData *data, + uint8_t *result); +static int +JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData *data, + uint16_t *result); +static void +JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData *data, + uint16_t skiplength); #endif -static int -JPEGFixupTags(TIFF* tif) -{ +static int JPEGFixupTags(TIFF *tif) { #ifdef CHECK_JPEG_YCBCR_SUBSAMPLING - JPEGState* sp = JState(tif); - if ((tif->tif_dir.td_photometric==PHOTOMETRIC_YCBCR)&& - (tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)&& - (tif->tif_dir.td_samplesperpixel==3) && - !sp->ycbcrsampling_fetched) - JPEGFixupTagsSubsampling(tif); + JPEGState *sp = JState(tif); + if ((tif->tif_dir.td_photometric == PHOTOMETRIC_YCBCR) && + (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG) && + (tif->tif_dir.td_samplesperpixel == 3) && + !sp->otherSettings.ycbcrsampling_fetched) + JPEGFixupTagsSubsampling(tif); #endif - - return(1); + + return (1); } #ifdef CHECK_JPEG_YCBCR_SUBSAMPLING -static void -JPEGFixupTagsSubsampling(TIFF* tif) -{ - /* - * Some JPEG-in-TIFF produces do not emit the YCBCRSUBSAMPLING values in - * the TIFF tags, but still use non-default (2,2) values within the jpeg - * data stream itself. In order for TIFF applications to work properly - * - for instance to get the strip buffer size right - it is imperative - * that the subsampling be available before we start reading the image - * data normally. This function will attempt to analyze the first strip in - * order to get the sampling values from the jpeg data stream. - * - * Note that JPEGPreDeocode() will produce a fairly loud warning when the - * discovered sampling does not match the default sampling (2,2) or whatever - * was actually in the tiff tags. - * - * See the bug in bugzilla for details: - * - * http://bugzilla.remotesensing.org/show_bug.cgi?id=168 - * - * Frank Warmerdam, July 2002 - * Joris Van Damme, May 2007 - */ - static const char module[] = "JPEGFixupTagsSubsampling"; - struct JPEGFixupTagsSubsamplingData m; - uint64_t fileoffset = TIFFGetStrileOffset(tif, 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 - for instance. */ - return; - } - - m.tif=tif; - m.buffersize=2048; - m.buffer=_TIFFmalloc(m.buffersize); - if (m.buffer==NULL) - { - TIFFWarningExt(tif->tif_clientdata,module, - "Unable to allocate memory for auto-correcting of subsampling values; auto-correcting skipped"); - return; - } - m.buffercurrentbyte=NULL; - m.bufferbytesleft=0; - m.fileoffset=fileoffset; - m.filepositioned=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"); - _TIFFfree(m.buffer); +static void JPEGFixupTagsSubsampling(TIFF *tif) { + /* + * Some JPEG-in-TIFF produces do not emit the YCBCRSUBSAMPLING values in + * the TIFF tags, but still use non-default (2,2) values within the jpeg + * data stream itself. In order for TIFF applications to work properly + * - for instance to get the strip buffer size right - it is imperative + * that the subsampling be available before we start reading the image + * data normally. This function will attempt to analyze the first strip in + * order to get the sampling values from the jpeg data stream. + * + * Note that JPEGPreDeocode() will produce a fairly loud warning when the + * discovered sampling does not match the default sampling (2,2) or whatever + * was actually in the tiff tags. + * + * See the bug in bugzilla for details: + * + * http://bugzilla.remotesensing.org/show_bug.cgi?id=168 + * + * Frank Warmerdam, July 2002 + * Joris Van Damme, May 2007 + */ + static const char module[] = "JPEGFixupTagsSubsampling"; + struct JPEGFixupTagsSubsamplingData m; + uint64_t fileoffset = TIFFGetStrileOffset(tif, 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 + for instance. */ + return; + } + + m.tif = tif; + m.buffersize = 2048; + m.buffer = _TIFFmalloc(m.buffersize); + if (m.buffer == NULL) { + TIFFWarningExt(tif->tif_clientdata, module, + "Unable to allocate memory for auto-correcting of " + "subsampling values; auto-correcting skipped"); + return; + } + m.buffercurrentbyte = NULL; + m.bufferbytesleft = 0; + m.fileoffset = fileoffset; + m.filepositioned = 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"); + _TIFFfree(m.buffer); } static int -JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData* data) -{ - static const char module[] = "JPEGFixupTagsSubsamplingSec"; - uint8_t m; - while (1) - { - while (1) - { - if (!JPEGFixupTagsSubsamplingReadByte(data,&m)) - return(0); - if (m==255) - break; - } - while (1) - { - if (!JPEGFixupTagsSubsamplingReadByte(data,&m)) - return(0); - if (m!=255) - break; - } - switch (m) - { - case JPEG_MARKER_SOI: - /* this type of marker has no data and should be skipped */ - break; - case JPEG_MARKER_COM: - case JPEG_MARKER_APP0: - case JPEG_MARKER_APP0+1: - case JPEG_MARKER_APP0+2: - case JPEG_MARKER_APP0+3: - case JPEG_MARKER_APP0+4: - case JPEG_MARKER_APP0+5: - case JPEG_MARKER_APP0+6: - case JPEG_MARKER_APP0+7: - case JPEG_MARKER_APP0+8: - case JPEG_MARKER_APP0+9: - case JPEG_MARKER_APP0+10: - case JPEG_MARKER_APP0+11: - case JPEG_MARKER_APP0+12: - case JPEG_MARKER_APP0+13: - case JPEG_MARKER_APP0+14: - case JPEG_MARKER_APP0+15: - case JPEG_MARKER_DQT: - case JPEG_MARKER_SOS: - case JPEG_MARKER_DHT: - case JPEG_MARKER_DRI: - /* this type of marker has data, but it has no use to us and should be skipped */ - { - uint16_t n; - if (!JPEGFixupTagsSubsamplingReadWord(data,&n)) - return(0); - if (n<2) - return(0); - n-=2; - if (n>0) - JPEGFixupTagsSubsamplingSkip(data,n); - } - break; - case JPEG_MARKER_SOF0: /* Baseline sequential Huffman */ - case JPEG_MARKER_SOF1: /* Extended sequential Huffman */ - case JPEG_MARKER_SOF2: /* Progressive Huffman: normally not allowed by TechNote, but that doesn't hurt supporting it */ - case JPEG_MARKER_SOF9: /* Extended sequential arithmetic */ - case JPEG_MARKER_SOF10: /* Progressive arithmetic: normally not allowed by TechNote, but that doesn't hurt supporting it */ - /* this marker contains the subsampling factors we're scanning for */ - { - uint16_t n; - uint16_t o; - uint8_t p; - uint8_t ph,pv; - if (!JPEGFixupTagsSubsamplingReadWord(data,&n)) - return(0); - if (n!=8+data->tif->tif_dir.td_samplesperpixel*3) - return(0); - JPEGFixupTagsSubsamplingSkip(data,7); - if (!JPEGFixupTagsSubsamplingReadByte(data,&p)) - return(0); - ph=(p>>4); - pv=(p&15); - JPEGFixupTagsSubsamplingSkip(data,1); - for (o=1; o<data->tif->tif_dir.td_samplesperpixel; o++) - { - JPEGFixupTagsSubsamplingSkip(data,1); - if (!JPEGFixupTagsSubsamplingReadByte(data,&p)) - return(0); - if (p!=0x11) - { - TIFFWarningExt(data->tif->tif_clientdata,module, - "Subsampling values inside JPEG compressed data have no TIFF equivalent, auto-correction of TIFF subsampling values failed"); - return(1); - } - JPEGFixupTagsSubsamplingSkip(data,1); - } - if (((ph!=1)&&(ph!=2)&&(ph!=4))||((pv!=1)&&(pv!=2)&&(pv!=4))) - { - TIFFWarningExt(data->tif->tif_clientdata,module, - "Subsampling values inside JPEG compressed data have no TIFF equivalent, auto-correction of TIFF subsampling values failed"); - return(1); - } - if ((ph!=data->tif->tif_dir.td_ycbcrsubsampling[0])||(pv!=data->tif->tif_dir.td_ycbcrsubsampling[1])) - { - TIFFWarningExt(data->tif->tif_clientdata,module, - "Auto-corrected former TIFF subsampling values [%"PRIu16",%"PRIu16"] to match subsampling values inside JPEG compressed data [%"PRIu8",%"PRIu8"]", - data->tif->tif_dir.td_ycbcrsubsampling[0], - data->tif->tif_dir.td_ycbcrsubsampling[1], - ph, pv); - data->tif->tif_dir.td_ycbcrsubsampling[0]=ph; - data->tif->tif_dir.td_ycbcrsubsampling[1]=pv; - } - } - return(1); - default: - return(0); - } - } +JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData *data) { + static const char module[] = "JPEGFixupTagsSubsamplingSec"; + uint8_t m; + while (1) { + while (1) { + if (!JPEGFixupTagsSubsamplingReadByte(data, &m)) + return (0); + if (m == 255) + break; + } + while (1) { + if (!JPEGFixupTagsSubsamplingReadByte(data, &m)) + return (0); + if (m != 255) + break; + } + switch (m) { + case JPEG_MARKER_SOI: + /* this type of marker has no data and should be skipped */ + break; + case JPEG_MARKER_COM: + case JPEG_MARKER_APP0: + case JPEG_MARKER_APP0 + 1: + case JPEG_MARKER_APP0 + 2: + case JPEG_MARKER_APP0 + 3: + case JPEG_MARKER_APP0 + 4: + case JPEG_MARKER_APP0 + 5: + case JPEG_MARKER_APP0 + 6: + case JPEG_MARKER_APP0 + 7: + case JPEG_MARKER_APP0 + 8: + case JPEG_MARKER_APP0 + 9: + case JPEG_MARKER_APP0 + 10: + case JPEG_MARKER_APP0 + 11: + case JPEG_MARKER_APP0 + 12: + case JPEG_MARKER_APP0 + 13: + case JPEG_MARKER_APP0 + 14: + case JPEG_MARKER_APP0 + 15: + case JPEG_MARKER_DQT: + case JPEG_MARKER_SOS: + case JPEG_MARKER_DHT: + case JPEG_MARKER_DRI: + /* this type of marker has data, but it has no use to us and should be + * skipped */ + { + uint16_t n; + if (!JPEGFixupTagsSubsamplingReadWord(data, &n)) + return (0); + if (n < 2) + return (0); + n -= 2; + if (n > 0) + JPEGFixupTagsSubsamplingSkip(data, n); + } + break; + case JPEG_MARKER_SOF0: /* Baseline sequential Huffman */ + case JPEG_MARKER_SOF1: /* Extended sequential Huffman */ + case JPEG_MARKER_SOF2: /* Progressive Huffman: normally not allowed by + TechNote, but that doesn't hurt supporting it */ + case JPEG_MARKER_SOF9: /* Extended sequential arithmetic */ + case JPEG_MARKER_SOF10: /* Progressive arithmetic: normally not allowed by + TechNote, but that doesn't hurt supporting it */ + /* this marker contains the subsampling factors we're scanning for */ + { + uint16_t n; + uint16_t o; + uint8_t p; + uint8_t ph, pv; + if (!JPEGFixupTagsSubsamplingReadWord(data, &n)) + return (0); + if (n != 8 + data->tif->tif_dir.td_samplesperpixel * 3) + return (0); + JPEGFixupTagsSubsamplingSkip(data, 7); + if (!JPEGFixupTagsSubsamplingReadByte(data, &p)) + return (0); + ph = (p >> 4); + pv = (p & 15); + JPEGFixupTagsSubsamplingSkip(data, 1); + for (o = 1; o < data->tif->tif_dir.td_samplesperpixel; o++) { + JPEGFixupTagsSubsamplingSkip(data, 1); + if (!JPEGFixupTagsSubsamplingReadByte(data, &p)) + return (0); + if (p != 0x11) { + TIFFWarningExt(data->tif->tif_clientdata, module, + "Subsampling values inside JPEG compressed data " + "have no TIFF equivalent, auto-correction of TIFF " + "subsampling values failed"); + return (1); + } + JPEGFixupTagsSubsamplingSkip(data, 1); + } + if (((ph != 1) && (ph != 2) && (ph != 4)) || + ((pv != 1) && (pv != 2) && (pv != 4))) { + TIFFWarningExt( + data->tif->tif_clientdata, module, + "Subsampling values inside JPEG compressed data have no TIFF " + "equivalent, auto-correction of TIFF subsampling values failed"); + return (1); + } + if ((ph != data->tif->tif_dir.td_ycbcrsubsampling[0]) || + (pv != data->tif->tif_dir.td_ycbcrsubsampling[1])) { + TIFFWarningExt( + data->tif->tif_clientdata, module, + "Auto-corrected former TIFF subsampling values [%" PRIu16 + ",%" PRIu16 "] to match subsampling values inside JPEG " + "compressed data [%" PRIu8 ",%" PRIu8 "]", + data->tif->tif_dir.td_ycbcrsubsampling[0], + data->tif->tif_dir.td_ycbcrsubsampling[1], ph, pv); + data->tif->tif_dir.td_ycbcrsubsampling[0] = ph; + data->tif->tif_dir.td_ycbcrsubsampling[1] = pv; + } + } + return (1); + default: + return (0); + } + } } static int -JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData* data, uint8_t* result) -{ - if (data->bufferbytesleft==0) - { - uint32_t m; - if (data->filebytesleft==0) - return(0); - if (!data->filepositioned) - { - if (TIFFSeekFile(data->tif,data->fileoffset,SEEK_SET) == (toff_t)-1) - { - return 0; - } - data->filepositioned=1; - } - m=data->buffersize; - if ((uint64_t)m > data->filebytesleft) - m=(uint32_t)data->filebytesleft; - assert(m<0x80000000UL); - if (TIFFReadFile(data->tif,data->buffer,(tmsize_t)m)!=(tmsize_t)m) - return(0); - data->buffercurrentbyte=data->buffer; - data->bufferbytesleft=m; - data->fileoffset+=m; - data->filebytesleft-=m; - } - *result=*data->buffercurrentbyte; - data->buffercurrentbyte++; - data->bufferbytesleft--; - return(1); +JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData *data, + uint8_t *result) { + if (data->bufferbytesleft == 0) { + uint32_t m; + if (data->filebytesleft == 0) + return (0); + if (!data->filepositioned) { + if (TIFFSeekFile(data->tif, data->fileoffset, SEEK_SET) == (toff_t)-1) { + return 0; + } + data->filepositioned = 1; + } + m = data->buffersize; + if ((uint64_t)m > data->filebytesleft) + m = (uint32_t)data->filebytesleft; + assert(m < 0x80000000UL); + if (TIFFReadFile(data->tif, data->buffer, (tmsize_t)m) != (tmsize_t)m) + return (0); + data->buffercurrentbyte = data->buffer; + data->bufferbytesleft = m; + data->fileoffset += m; + data->filebytesleft -= m; + } + *result = *data->buffercurrentbyte; + data->buffercurrentbyte++; + data->bufferbytesleft--; + return (1); } static int -JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData* data, uint16_t* result) -{ - uint8_t ma; - uint8_t mb; - if (!JPEGFixupTagsSubsamplingReadByte(data,&ma)) - return(0); - if (!JPEGFixupTagsSubsamplingReadByte(data,&mb)) - return(0); - *result=(ma<<8)|mb; - return(1); +JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData *data, + uint16_t *result) { + uint8_t ma; + uint8_t mb; + if (!JPEGFixupTagsSubsamplingReadByte(data, &ma)) + return (0); + if (!JPEGFixupTagsSubsamplingReadByte(data, &mb)) + return (0); + *result = (ma << 8) | mb; + return (1); } static void -JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData* data, uint16_t skiplength) -{ - if ((uint32_t)skiplength <= data->bufferbytesleft) - { - data->buffercurrentbyte+=skiplength; - data->bufferbytesleft-=skiplength; - } - else - { - uint16_t m; - m=(uint16_t)(skiplength - data->bufferbytesleft); - if (m<=data->filebytesleft) - { - data->bufferbytesleft=0; - data->fileoffset+=m; - data->filebytesleft-=m; - data->filepositioned=0; - } - else - { - data->bufferbytesleft=0; - data->filebytesleft=0; - } - } +JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData *data, + uint16_t skiplength) { + if ((uint32_t)skiplength <= data->bufferbytesleft) { + data->buffercurrentbyte += skiplength; + data->bufferbytesleft -= skiplength; + } else { + uint16_t m; + m = (uint16_t)(skiplength - data->bufferbytesleft); + if (m <= data->filebytesleft) { + data->bufferbytesleft = 0; + data->fileoffset += m; + data->filebytesleft -= m; + data->filepositioned = 0; + } else { + data->bufferbytesleft = 0; + data->filebytesleft = 0; + } + } } #endif +static int JPEGSetupDecode(TIFF *tif) { + JPEGState *sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; + +#if defined(JPEG_DUAL_MODE_8_12) && !defined(FROM_TIF_JPEG_12) + if (tif->tif_dir.td_bitspersample == 12) { + /* We pass a pointer to a copy of otherSettings, since */ + /* TIFFReInitJPEG_12() will clear sp */ + JPEGOtherSettings savedOtherSettings = sp->otherSettings; + return TIFFReInitJPEG_12(tif, &savedOtherSettings, COMPRESSION_JPEG, 0); + } +#endif -static int -JPEGSetupDecode(TIFF* tif) -{ - JPEGState* sp = JState(tif); - TIFFDirectory *td = &tif->tif_dir; + JPEGInitializeLibJPEG(tif, TRUE); -#if defined(JPEG_DUAL_MODE_8_12) && !defined(TIFFInitJPEG) - if( tif->tif_dir.td_bitspersample == 12 ) - return TIFFReInitJPEG_12( tif, COMPRESSION_JPEG, 0 ); -#endif + assert(sp != NULL); + assert(sp->cinfo.comm.is_decompressor); - JPEGInitializeLibJPEG( tif, TRUE ); - - assert(sp != NULL); - assert(sp->cinfo.comm.is_decompressor); - - /* Read JPEGTables if it is present */ - if (TIFFFieldSet(tif,FIELD_JPEGTABLES)) { - TIFFjpeg_tables_src(sp); - if(TIFFjpeg_read_header(sp,FALSE) != JPEG_HEADER_TABLES_ONLY) { - TIFFErrorExt(tif->tif_clientdata, "JPEGSetupDecode", "Bogus JPEGTables field"); - return (0); - } - } - - /* Grab parameters that are same for all strips/tiles */ - sp->photometric = td->td_photometric; - switch (sp->photometric) { - case PHOTOMETRIC_YCBCR: - sp->h_sampling = td->td_ycbcrsubsampling[0]; - sp->v_sampling = td->td_ycbcrsubsampling[1]; - break; - default: - /* TIFF 6.0 forbids subsampling of all other color spaces */ - sp->h_sampling = 1; - sp->v_sampling = 1; - break; - } - - /* Set up for reading normal data */ - TIFFjpeg_data_src(sp); - tif->tif_postdecode = _TIFFNoPostDecode; /* override byte swapping */ - return (1); + /* Read JPEGTables if it is present */ + if (TIFFFieldSet(tif, FIELD_JPEGTABLES)) { + TIFFjpeg_tables_src(sp); + if (TIFFjpeg_read_header(sp, FALSE) != JPEG_HEADER_TABLES_ONLY) { + TIFFErrorExt(tif->tif_clientdata, "JPEGSetupDecode", + "Bogus JPEGTables field"); + return (0); + } + } + + /* Grab parameters that are same for all strips/tiles */ + sp->photometric = td->td_photometric; + switch (sp->photometric) { + case PHOTOMETRIC_YCBCR: + sp->h_sampling = td->td_ycbcrsubsampling[0]; + sp->v_sampling = td->td_ycbcrsubsampling[1]; + break; + default: + /* TIFF 6.0 forbids subsampling of all other color spaces */ + sp->h_sampling = 1; + sp->v_sampling = 1; + break; + } + + /* Set up for reading normal data */ + TIFFjpeg_data_src(sp); + tif->tif_postdecode = _TIFFNoPostDecode; /* override byte swapping */ + return (1); } /* Returns 1 if the full strip should be read, even when doing scanline per */ @@ -1056,265 +998,269 @@ JPEGSetupDecode(TIFF* tif) /* Only reads tif->tif_dir.td_bitspersample, tif->tif_rawdata and */ /* tif->tif_rawcc members. */ /* Can be called independently of the usual setup/predecode/decode states */ -int TIFFJPEGIsFullStripRequired(TIFF* tif) -{ - int ret; - JPEGState state; +int TIFFJPEGIsFullStripRequired(TIFF *tif) { + int ret; + JPEGState state; -#if defined(JPEG_DUAL_MODE_8_12) && !defined(TIFFJPEGIsFullStripRequired) - if( tif->tif_dir.td_bitspersample == 12 ) - return TIFFJPEGIsFullStripRequired_12( tif ); +#if defined(JPEG_DUAL_MODE_8_12) && !defined(FROM_TIF_JPEG_12) + if (tif->tif_dir.td_bitspersample == 12) + return TIFFJPEGIsFullStripRequired_12(tif); #endif - memset(&state, 0, sizeof(JPEGState)); - state.tif = tif; + memset(&state, 0, sizeof(JPEGState)); + state.tif = tif; - TIFFjpeg_create_decompress(&state); + TIFFjpeg_create_decompress(&state); - TIFFjpeg_data_src(&state); - - if (TIFFjpeg_read_header(&state, TRUE) != JPEG_HEADER_OK) - { - TIFFjpeg_destroy(&state); - return (0); - } - ret = TIFFjpeg_has_multiple_scans(&state); + TIFFjpeg_data_src(&state); + if (TIFFjpeg_read_header(&state, TRUE) != JPEG_HEADER_OK) { TIFFjpeg_destroy(&state); + return (0); + } + ret = TIFFjpeg_has_multiple_scans(&state); - return ret; + TIFFjpeg_destroy(&state); + + return ret; } /* * Set up for decoding a strip or tile. */ -/*ARGSUSED*/ static int -JPEGPreDecode(TIFF* tif, uint16_t s) -{ - JPEGState *sp = JState(tif); - TIFFDirectory *td = &tif->tif_dir; - static const char module[] = "JPEGPreDecode"; - uint32_t segment_width, segment_height; - int downsampled_output; - int ci; - - assert(sp != NULL); - - if (sp->cinfo.comm.is_decompressor == 0) - { - tif->tif_setupdecode( tif ); - } - - assert(sp->cinfo.comm.is_decompressor); - /* - * Reset decoder state from any previous strip/tile, - * in case application didn't read the whole strip. - */ - if (!TIFFjpeg_abort(sp)) - return (0); - /* - * Read the header for this strip/tile. - */ - - if (TIFFjpeg_read_header(sp, TRUE) != JPEG_HEADER_OK) - return (0); - - tif->tif_rawcp = (uint8_t*) sp->src.next_input_byte; - tif->tif_rawcc = sp->src.bytes_in_buffer; - - /* - * Check image parameters and set decompression parameters. - */ - if (isTiled(tif)) { - segment_width = td->td_tilewidth; - segment_height = td->td_tilelength; - sp->bytesperline = TIFFTileRowSize(tif); - } else { - segment_width = td->td_imagewidth; - segment_height = td->td_imagelength - tif->tif_row; - if (segment_height > td->td_rowsperstrip) - segment_height = td->td_rowsperstrip; - sp->bytesperline = TIFFScanlineSize(tif); - } - if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) { - /* - * For PC 2, scale down the expected strip/tile size - * to match a downsampled component - */ - segment_width = TIFFhowmany_32(segment_width, sp->h_sampling); - segment_height = TIFFhowmany_32(segment_height, sp->v_sampling); - } - if (sp->cinfo.d.image_width < segment_width || - sp->cinfo.d.image_height < segment_height) { - TIFFWarningExt(tif->tif_clientdata, module, - "Improper JPEG strip/tile size, " - "expected %"PRIu32"x%"PRIu32", got %ux%u", - segment_width, segment_height, - sp->cinfo.d.image_width, - sp->cinfo.d.image_height); - } - if( sp->cinfo.d.image_width == segment_width && - sp->cinfo.d.image_height > segment_height && - tif->tif_row + segment_height == td->td_imagelength && - !isTiled(tif) ) { - /* Some files have a last strip, that should be truncated, */ - /* but their JPEG codestream has still the maximum strip */ - /* height. Warn about this as this is non compliant, but */ - /* we can safely recover from that. */ - TIFFWarningExt(tif->tif_clientdata, module, - "JPEG strip size exceeds expected dimensions," - " expected %"PRIu32"x%"PRIu32", got %ux%u", - segment_width, segment_height, - sp->cinfo.d.image_width, sp->cinfo.d.image_height); - } - else if (sp->cinfo.d.image_width > segment_width || - sp->cinfo.d.image_height > segment_height) { - /* - * This case could be dangerous, if the strip or tile size has - * been reported as less than the amount of data jpeg will - * return, some potential security issues arise. Catch this - * case and error out. - */ - TIFFErrorExt(tif->tif_clientdata, module, - "JPEG strip/tile size exceeds expected dimensions," - " expected %"PRIu32"x%"PRIu32", got %ux%u", - segment_width, segment_height, - sp->cinfo.d.image_width, sp->cinfo.d.image_height); - return (0); - } - if (sp->cinfo.d.num_components != - (td->td_planarconfig == PLANARCONFIG_CONTIG ? - td->td_samplesperpixel : 1)) { - TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG component count"); - return (0); - } +/*ARGSUSED*/ static int JPEGPreDecode(TIFF *tif, uint16_t s) { + JPEGState *sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; + static const char module[] = "JPEGPreDecode"; + uint32_t segment_width, segment_height; + int downsampled_output; + int ci; + + assert(sp != NULL); + + if (sp->cinfo.comm.is_decompressor == 0) { + tif->tif_setupdecode(tif); + } + + assert(sp->cinfo.comm.is_decompressor); + /* + * Reset decoder state from any previous strip/tile, + * in case application didn't read the whole strip. + */ + if (!TIFFjpeg_abort(sp)) + return (0); + /* + * Read the header for this strip/tile. + */ + + if (TIFFjpeg_read_header(sp, TRUE) != JPEG_HEADER_OK) + return (0); + + tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte; + tif->tif_rawcc = sp->src.bytes_in_buffer; + + /* + * Check image parameters and set decompression parameters. + */ + if (isTiled(tif)) { + segment_width = td->td_tilewidth; + segment_height = td->td_tilelength; + sp->bytesperline = TIFFTileRowSize(tif); + } else { + segment_width = td->td_imagewidth; + segment_height = td->td_imagelength - tif->tif_row; + if (segment_height > td->td_rowsperstrip) + segment_height = td->td_rowsperstrip; + sp->bytesperline = TIFFScanlineSize(tif); + } + if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) { + /* + * For PC 2, scale down the expected strip/tile size + * to match a downsampled component + */ + segment_width = TIFFhowmany_32(segment_width, sp->h_sampling); + segment_height = TIFFhowmany_32(segment_height, sp->v_sampling); + } + if (sp->cinfo.d.image_width < segment_width || + sp->cinfo.d.image_height < segment_height) { + TIFFWarningExt(tif->tif_clientdata, module, + "Improper JPEG strip/tile size, " + "expected %" PRIu32 "x%" PRIu32 ", got %ux%u", + segment_width, segment_height, sp->cinfo.d.image_width, + sp->cinfo.d.image_height); + } + if (sp->cinfo.d.image_width == segment_width && + sp->cinfo.d.image_height > segment_height && + tif->tif_row + segment_height == td->td_imagelength && !isTiled(tif)) { + /* Some files have a last strip, that should be truncated, */ + /* but their JPEG codestream has still the maximum strip */ + /* height. Warn about this as this is non compliant, but */ + /* we can safely recover from that. */ + TIFFWarningExt(tif->tif_clientdata, module, + "JPEG strip size exceeds expected dimensions," + " expected %" PRIu32 "x%" PRIu32 ", got %ux%u", + segment_width, segment_height, sp->cinfo.d.image_width, + sp->cinfo.d.image_height); + } else if (sp->cinfo.d.image_width > segment_width || + sp->cinfo.d.image_height > segment_height) { + /* + * This case could be dangerous, if the strip or tile size has + * been reported as less than the amount of data jpeg will + * return, some potential security issues arise. Catch this + * case and error out. + */ + TIFFErrorExt(tif->tif_clientdata, module, + "JPEG strip/tile size exceeds expected dimensions," + " expected %" PRIu32 "x%" PRIu32 ", got %ux%u", + segment_width, segment_height, sp->cinfo.d.image_width, + sp->cinfo.d.image_height); + return (0); + } + if (sp->cinfo.d.num_components != (td->td_planarconfig == PLANARCONFIG_CONTIG + ? td->td_samplesperpixel + : 1)) { + TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG component count"); + return (0); + } #ifdef JPEG_LIB_MK1 - if (12 != td->td_bitspersample && 8 != td->td_bitspersample) { - TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG data precision"); - return (0); - } - sp->cinfo.d.data_precision = td->td_bitspersample; - sp->cinfo.d.bits_in_jsample = td->td_bitspersample; + if (12 != td->td_bitspersample && 8 != td->td_bitspersample) { + TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG data precision"); + return (0); + } + sp->cinfo.d.data_precision = td->td_bitspersample; + sp->cinfo.d.bits_in_jsample = td->td_bitspersample; #else - if (sp->cinfo.d.data_precision != td->td_bitspersample) { - TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG data precision"); - return (0); - } + if (sp->cinfo.d.data_precision != td->td_bitspersample) { + TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG data precision"); + return (0); + } #endif - /* In some cases, libjpeg needs to allocate a lot of memory */ - /* http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf */ - if( TIFFjpeg_has_multiple_scans(sp) ) - { - /* In this case libjpeg will need to allocate memory or backing */ - /* store for all coefficients */ - /* See call to jinit_d_coef_controller() from master_selection() */ - /* in libjpeg */ - - /* 1 MB for regular libjpeg usage */ - toff_t nRequiredMemory = 1024 * 1024; - - for (ci = 0; ci < sp->cinfo.d.num_components; ci++) { - const jpeg_component_info *compptr = &(sp->cinfo.d.comp_info[ci]); - if( compptr->h_samp_factor > 0 && compptr->v_samp_factor > 0 ) - { - nRequiredMemory += (toff_t)( - ((compptr->width_in_blocks + compptr->h_samp_factor - 1) / compptr->h_samp_factor)) * - ((compptr->height_in_blocks + compptr->v_samp_factor - 1) / compptr->v_samp_factor) * - sizeof(JBLOCK); - } - } - - if( sp->cinfo.d.mem->max_memory_to_use > 0 && - nRequiredMemory > (toff_t)(sp->cinfo.d.mem->max_memory_to_use) && - getenv("LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC") == NULL ) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Reading this image would require libjpeg to allocate " - "at least %"PRIu64" bytes. " - "This is disabled since above the %ld threshold. " - "You may override this restriction by defining the " - "LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC environment variable, " - "or setting the JPEGMEM environment variable to a value greater " - "or equal to '%"PRIu64"M'", - nRequiredMemory, - sp->cinfo.d.mem->max_memory_to_use, - (nRequiredMemory + 1000000u - 1u) / 1000000u); - return 0; - } - } + if (sp->cinfo.d.progressive_mode && + !sp->otherSettings.has_warned_about_progressive_mode) { + TIFFWarningExt(tif->tif_clientdata, module, + "The JPEG strip/tile is encoded with progressive mode, " + "which is normally not legal for JPEG-in-TIFF.\n" + "libtiff should be able to decode it, but it might " + "cause compatibility issues with other readers"); + sp->otherSettings.has_warned_about_progressive_mode = TRUE; + } + + /* In some cases, libjpeg needs to allocate a lot of memory */ + /* http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf + */ + if (TIFFjpeg_has_multiple_scans(sp)) { + /* In this case libjpeg will need to allocate memory or backing */ + /* store for all coefficients */ + /* See call to jinit_d_coef_controller() from master_selection() */ + /* in libjpeg */ + + /* 1 MB for regular libjpeg usage */ + toff_t nRequiredMemory = 1024 * 1024; + + for (ci = 0; ci < sp->cinfo.d.num_components; ci++) { + const jpeg_component_info *compptr = &(sp->cinfo.d.comp_info[ci]); + if (compptr->h_samp_factor > 0 && compptr->v_samp_factor > 0) { + nRequiredMemory += + (toff_t)(((compptr->width_in_blocks + compptr->h_samp_factor - 1) / + compptr->h_samp_factor)) * + ((compptr->height_in_blocks + compptr->v_samp_factor - 1) / + compptr->v_samp_factor) * + sizeof(JBLOCK); + } + } - if (td->td_planarconfig == PLANARCONFIG_CONTIG) { - /* Component 0 should have expected sampling factors */ - if (sp->cinfo.d.comp_info[0].h_samp_factor != sp->h_sampling || - sp->cinfo.d.comp_info[0].v_samp_factor != sp->v_sampling) { - TIFFErrorExt(tif->tif_clientdata, module, - "Improper JPEG sampling factors %d,%d\n" - "Apparently should be %"PRIu16",%"PRIu16".", - sp->cinfo.d.comp_info[0].h_samp_factor, - sp->cinfo.d.comp_info[0].v_samp_factor, - sp->h_sampling, sp->v_sampling); - return (0); - } - /* Rest should have sampling factors 1,1 */ - for (ci = 1; ci < sp->cinfo.d.num_components; ci++) { - if (sp->cinfo.d.comp_info[ci].h_samp_factor != 1 || - sp->cinfo.d.comp_info[ci].v_samp_factor != 1) { - TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG sampling factors"); - return (0); - } - } - } else { - /* PC 2's single component should have sampling factors 1,1 */ - if (sp->cinfo.d.comp_info[0].h_samp_factor != 1 || - sp->cinfo.d.comp_info[0].v_samp_factor != 1) { - TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG sampling factors"); - return (0); - } - } - downsampled_output = FALSE; - if (td->td_planarconfig == PLANARCONFIG_CONTIG && - sp->photometric == PHOTOMETRIC_YCBCR && - sp->jpegcolormode == JPEGCOLORMODE_RGB) { - /* Convert YCbCr to RGB */ - sp->cinfo.d.jpeg_color_space = JCS_YCbCr; - sp->cinfo.d.out_color_space = JCS_RGB; - } else { - /* Suppress colorspace handling */ - sp->cinfo.d.jpeg_color_space = JCS_UNKNOWN; - sp->cinfo.d.out_color_space = JCS_UNKNOWN; - if (td->td_planarconfig == PLANARCONFIG_CONTIG && - (sp->h_sampling != 1 || sp->v_sampling != 1)) - downsampled_output = TRUE; - /* XXX what about up-sampling? */ - } - if (downsampled_output) { - /* Need to use raw-data interface to libjpeg */ - sp->cinfo.d.raw_data_out = TRUE; + if (sp->cinfo.d.mem->max_memory_to_use > 0 && + nRequiredMemory > (toff_t)(sp->cinfo.d.mem->max_memory_to_use) && + getenv("LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC") == NULL) { + TIFFErrorExt( + tif->tif_clientdata, module, + "Reading this image would require libjpeg to allocate " + "at least %" PRIu64 " bytes. " + "This is disabled since above the %ld threshold. " + "You may override this restriction by defining the " + "LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC environment variable, " + "or setting the JPEGMEM environment variable to a value greater " + "or equal to '%" PRIu64 "M'", + nRequiredMemory, sp->cinfo.d.mem->max_memory_to_use, + (nRequiredMemory + 1000000u - 1u) / 1000000u); + return 0; + } + } + + if (td->td_planarconfig == PLANARCONFIG_CONTIG) { + /* Component 0 should have expected sampling factors */ + if (sp->cinfo.d.comp_info[0].h_samp_factor != sp->h_sampling || + sp->cinfo.d.comp_info[0].v_samp_factor != sp->v_sampling) { + TIFFErrorExt(tif->tif_clientdata, module, + "Improper JPEG sampling factors %d,%d\n" + "Apparently should be %" PRIu16 ",%" PRIu16 ".", + sp->cinfo.d.comp_info[0].h_samp_factor, + sp->cinfo.d.comp_info[0].v_samp_factor, sp->h_sampling, + sp->v_sampling); + return (0); + } + /* Rest should have sampling factors 1,1 */ + for (ci = 1; ci < sp->cinfo.d.num_components; ci++) { + if (sp->cinfo.d.comp_info[ci].h_samp_factor != 1 || + sp->cinfo.d.comp_info[ci].v_samp_factor != 1) { + TIFFErrorExt(tif->tif_clientdata, module, + "Improper JPEG sampling factors"); + return (0); + } + } + } else { + /* PC 2's single component should have sampling factors 1,1 */ + if (sp->cinfo.d.comp_info[0].h_samp_factor != 1 || + sp->cinfo.d.comp_info[0].v_samp_factor != 1) { + TIFFErrorExt(tif->tif_clientdata, module, + "Improper JPEG sampling factors"); + return (0); + } + } + downsampled_output = FALSE; + if (td->td_planarconfig == PLANARCONFIG_CONTIG && + sp->photometric == PHOTOMETRIC_YCBCR && + sp->otherSettings.jpegcolormode == JPEGCOLORMODE_RGB) { + /* Convert YCbCr to RGB */ + sp->cinfo.d.jpeg_color_space = JCS_YCbCr; + sp->cinfo.d.out_color_space = JCS_RGB; + } else { + /* Suppress colorspace handling */ + sp->cinfo.d.jpeg_color_space = JCS_UNKNOWN; + sp->cinfo.d.out_color_space = JCS_UNKNOWN; + if (td->td_planarconfig == PLANARCONFIG_CONTIG && + (sp->h_sampling != 1 || sp->v_sampling != 1)) + downsampled_output = TRUE; + /* XXX what about up-sampling? */ + } + if (downsampled_output) { + /* Need to use raw-data interface to libjpeg */ + sp->cinfo.d.raw_data_out = TRUE; #if JPEG_LIB_VERSION >= 70 - sp->cinfo.d.do_fancy_upsampling = FALSE; + sp->cinfo.d.do_fancy_upsampling = FALSE; #endif /* JPEG_LIB_VERSION >= 70 */ - tif->tif_decoderow = DecodeRowError; - tif->tif_decodestrip = JPEGDecodeRaw; - tif->tif_decodetile = JPEGDecodeRaw; - } else { - /* Use normal interface to libjpeg */ - sp->cinfo.d.raw_data_out = FALSE; - tif->tif_decoderow = JPEGDecode; - tif->tif_decodestrip = JPEGDecode; - tif->tif_decodetile = JPEGDecode; - } - /* Start JPEG decompressor */ - if (!TIFFjpeg_start_decompress(sp)) - return (0); - /* Allocate downsampled-data buffers if needed */ - if (downsampled_output) { - if (!alloc_downsampled_buffers(tif, sp->cinfo.d.comp_info, - sp->cinfo.d.num_components)) - return (0); - sp->scancount = DCTSIZE; /* mark buffer empty */ - } - return (1); + tif->tif_decoderow = DecodeRowError; + tif->tif_decodestrip = JPEGDecodeRaw; + tif->tif_decodetile = JPEGDecodeRaw; + } else { + /* Use normal interface to libjpeg */ + sp->cinfo.d.raw_data_out = FALSE; + tif->tif_decoderow = JPEGDecode; + tif->tif_decodestrip = JPEGDecode; + tif->tif_decodetile = JPEGDecode; + } + /* Start JPEG decompressor */ + if (!TIFFjpeg_start_decompress(sp)) + return (0); + /* Allocate downsampled-data buffers if needed */ + if (downsampled_output) { + if (!alloc_downsampled_buffers(tif, sp->cinfo.d.comp_info, + sp->cinfo.d.num_components)) + return (0); + sp->scancount = DCTSIZE; /* mark buffer empty */ + } + return (1); } /* @@ -1322,1104 +1268,1103 @@ JPEGPreDecode(TIFF* tif, uint16_t s) * "Standard" case: returned data is not downsampled. */ #if !JPEG_LIB_MK1_OR_12BIT -static int -JPEGDecode(TIFF* tif, uint8_t* buf, tmsize_t cc, uint16_t s) -{ - JPEGState *sp = JState(tif); - tmsize_t nrows; - (void) s; +static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) { + JPEGState *sp = JState(tif); + tmsize_t nrows; + (void)s; + + /* + ** Update available information, buffer may have been refilled + ** between decode requests + */ + sp->src.next_input_byte = (const JOCTET *)tif->tif_rawcp; + sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc; + + if (sp->bytesperline == 0) + return 0; - /* - ** Update available information, buffer may have been refilled - ** between decode requests - */ - sp->src.next_input_byte = (const JOCTET*) tif->tif_rawcp; - sp->src.bytes_in_buffer = (size_t) tif->tif_rawcc; - - if( sp->bytesperline == 0 ) - return 0; - - nrows = cc / sp->bytesperline; - if (cc % sp->bytesperline) - TIFFWarningExt(tif->tif_clientdata, tif->tif_name, - "fractional scanline not read"); - - if( nrows > (tmsize_t) sp->cinfo.d.image_height ) - nrows = sp->cinfo.d.image_height; - - /* data is expected to be read in multiples of a scanline */ - if (nrows) - { - do - { - /* - * In the libjpeg6b-9a 8bit case. We read directly into - * the TIFF buffer. - */ - JSAMPROW bufptr = (JSAMPROW)buf; - - if (TIFFjpeg_read_scanlines(sp, &bufptr, 1) != 1) - return (0); - - ++tif->tif_row; - buf += sp->bytesperline; - cc -= sp->bytesperline; - } while (--nrows > 0); - } + nrows = cc / sp->bytesperline; + if (cc % sp->bytesperline) + TIFFWarningExt(tif->tif_clientdata, tif->tif_name, + "fractional scanline not read"); + + if (nrows > (tmsize_t)sp->cinfo.d.image_height) + nrows = sp->cinfo.d.image_height; + + /* data is expected to be read in multiples of a scanline */ + if (nrows) { + do { + /* + * In the libjpeg6b-9a 8bit case. We read directly into + * the TIFF buffer. + */ + JSAMPROW bufptr = (JSAMPROW)buf; - /* Update information on consumed data */ - tif->tif_rawcp = (uint8_t*) sp->src.next_input_byte; - tif->tif_rawcc = sp->src.bytes_in_buffer; - - /* Close down the decompressor if we've finished the strip or tile. */ - return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height - || TIFFjpeg_finish_decompress(sp); + if (TIFFjpeg_read_scanlines(sp, &bufptr, 1) != 1) + return (0); + + ++tif->tif_row; + buf += sp->bytesperline; + cc -= sp->bytesperline; + } while (--nrows > 0); + } + + /* Update information on consumed data */ + tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte; + tif->tif_rawcc = sp->src.bytes_in_buffer; + + /* Close down the decompressor if we've finished the strip or tile. */ + return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height || + TIFFjpeg_finish_decompress(sp); } #endif /* !JPEG_LIB_MK1_OR_12BIT */ #if JPEG_LIB_MK1_OR_12BIT -/*ARGSUSED*/ static int -JPEGDecode(TIFF* tif, uint8_t* buf, tmsize_t cc, uint16_t s) -{ - JPEGState *sp = JState(tif); - tmsize_t nrows; - (void) s; +/*ARGSUSED*/ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, + uint16_t s) { + JPEGState *sp = JState(tif); + tmsize_t nrows; + (void)s; + + /* + ** Update available information, buffer may have been refilled + ** between decode requests + */ + sp->src.next_input_byte = (const JOCTET *)tif->tif_rawcp; + sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc; + + if (sp->bytesperline == 0) + return 0; + + nrows = cc / sp->bytesperline; + if (cc % sp->bytesperline) + TIFFWarningExt(tif->tif_clientdata, tif->tif_name, + "fractional scanline not read"); + + if (nrows > (tmsize_t)sp->cinfo.d.image_height) + nrows = sp->cinfo.d.image_height; + /* data is expected to be read in multiples of a scanline */ + if (nrows) { + JSAMPROW line_work_buf = NULL; + + /* + * For 6B, only use temporary buffer for 12 bit imagery. + * For Mk1 always use it. + */ + if (sp->cinfo.d.data_precision == 12) { + line_work_buf = + (JSAMPROW)_TIFFmalloc(sizeof(short) * sp->cinfo.d.output_width * + sp->cinfo.d.num_components); + } + + do { + if (line_work_buf != NULL) { /* - ** Update available information, buffer may have been refilled - ** between decode requests - */ - sp->src.next_input_byte = (const JOCTET*) tif->tif_rawcp; - sp->src.bytes_in_buffer = (size_t) tif->tif_rawcc; - - if( sp->bytesperline == 0 ) - return 0; - - nrows = cc / sp->bytesperline; - if (cc % sp->bytesperline) - TIFFWarningExt(tif->tif_clientdata, tif->tif_name, - "fractional scanline not read"); - - if( nrows > (tmsize_t) sp->cinfo.d.image_height ) - nrows = sp->cinfo.d.image_height; - - /* data is expected to be read in multiples of a scanline */ - if (nrows) - { - JSAMPROW line_work_buf = NULL; - - /* - * For 6B, only use temporary buffer for 12 bit imagery. - * For Mk1 always use it. - */ - if( sp->cinfo.d.data_precision == 12 ) - { - line_work_buf = (JSAMPROW) - _TIFFmalloc(sizeof(short) * sp->cinfo.d.output_width - * sp->cinfo.d.num_components ); - } - - do - { - if( line_work_buf != NULL ) - { - /* - * In the MK1 case, we always read into a 16bit - * buffer, and then pack down to 12bit or 8bit. - * In 6B case we only read into 16 bit buffer - * for 12bit data, which we need to repack. - */ - if (TIFFjpeg_read_scanlines(sp, &line_work_buf, 1) != 1) - return (0); - - if( sp->cinfo.d.data_precision == 12 ) - { - int value_pairs = (sp->cinfo.d.output_width - * sp->cinfo.d.num_components) / 2; - int iPair; - - for( iPair = 0; iPair < value_pairs; iPair++ ) - { - unsigned char *out_ptr = - ((unsigned char *) buf) + iPair * 3; - JSAMPLE *in_ptr = line_work_buf + iPair * 2; - - out_ptr[0] = (unsigned char)((in_ptr[0] & 0xff0) >> 4); - out_ptr[1] = (unsigned char)(((in_ptr[0] & 0xf) << 4) - | ((in_ptr[1] & 0xf00) >> 8)); - out_ptr[2] = (unsigned char)(((in_ptr[1] & 0xff) >> 0)); - } - } - else if( sp->cinfo.d.data_precision == 8 ) - { - int value_count = (sp->cinfo.d.output_width - * sp->cinfo.d.num_components); - int iValue; - - for( iValue = 0; iValue < value_count; iValue++ ) - { - ((unsigned char *) buf)[iValue] = - line_work_buf[iValue] & 0xff; - } - } - } - - ++tif->tif_row; - buf += sp->bytesperline; - cc -= sp->bytesperline; - } while (--nrows > 0); - - if( line_work_buf != NULL ) - _TIFFfree( line_work_buf ); + * In the MK1 case, we always read into a 16bit + * buffer, and then pack down to 12bit or 8bit. + * In 6B case we only read into 16 bit buffer + * for 12bit data, which we need to repack. + */ + if (TIFFjpeg_read_scanlines(sp, &line_work_buf, 1) != 1) + return (0); + + if (sp->cinfo.d.data_precision == 12) { + int value_pairs = + (sp->cinfo.d.output_width * sp->cinfo.d.num_components) / 2; + int iPair; + + for (iPair = 0; iPair < value_pairs; iPair++) { + unsigned char *out_ptr = ((unsigned char *)buf) + iPair * 3; + JSAMPLE *in_ptr = line_work_buf + iPair * 2; + + out_ptr[0] = (unsigned char)((in_ptr[0] & 0xff0) >> 4); + out_ptr[1] = (unsigned char)(((in_ptr[0] & 0xf) << 4) | + ((in_ptr[1] & 0xf00) >> 8)); + out_ptr[2] = (unsigned char)(((in_ptr[1] & 0xff) >> 0)); + } + } else if (sp->cinfo.d.data_precision == 8) { + int value_count = + (sp->cinfo.d.output_width * sp->cinfo.d.num_components); + int iValue; + + for (iValue = 0; iValue < value_count; iValue++) { + ((unsigned char *)buf)[iValue] = line_work_buf[iValue] & 0xff; + } } + } + + ++tif->tif_row; + buf += sp->bytesperline; + cc -= sp->bytesperline; + } while (--nrows > 0); + + if (line_work_buf != NULL) + _TIFFfree(line_work_buf); + } - /* Update information on consumed data */ - tif->tif_rawcp = (uint8_t*) sp->src.next_input_byte; - tif->tif_rawcc = sp->src.bytes_in_buffer; - - /* Close down the decompressor if we've finished the strip or tile. */ - return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height - || TIFFjpeg_finish_decompress(sp); + /* Update information on consumed data */ + tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte; + tif->tif_rawcc = sp->src.bytes_in_buffer; + + /* Close down the decompressor if we've finished the strip or tile. */ + return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height || + TIFFjpeg_finish_decompress(sp); } #endif /* JPEG_LIB_MK1_OR_12BIT */ -/*ARGSUSED*/ static int -DecodeRowError(TIFF* tif, uint8_t* buf, tmsize_t cc, uint16_t s) +/*ARGSUSED*/ static int DecodeRowError(TIFF *tif, uint8_t *buf, tmsize_t cc, + uint16_t s) { - (void) buf; - (void) cc; - (void) s; + (void)buf; + (void)cc; + (void)s; - TIFFErrorExt(tif->tif_clientdata, "TIFFReadScanline", - "scanline oriented access is not supported for downsampled JPEG compressed images, consider enabling TIFF_JPEGCOLORMODE as JPEGCOLORMODE_RGB." ); - return 0; + TIFFErrorExt(tif->tif_clientdata, "TIFFReadScanline", + "scanline oriented access is not supported for downsampled JPEG " + "compressed images, consider enabling TIFF_JPEGCOLORMODE as " + "JPEGCOLORMODE_RGB."); + return 0; } /* * Decode a chunk of pixels. * Returned data is downsampled per sampling factors. */ -/*ARGSUSED*/ static int -JPEGDecodeRaw(TIFF* tif, uint8_t* buf, tmsize_t cc, uint16_t s) -{ - JPEGState *sp = JState(tif); - tmsize_t nrows; - TIFFDirectory *td = &tif->tif_dir; - (void) s; +/*ARGSUSED*/ static int JPEGDecodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, + uint16_t s) { + JPEGState *sp = JState(tif); + tmsize_t nrows; + TIFFDirectory *td = &tif->tif_dir; + (void)s; + + nrows = sp->cinfo.d.image_height; + /* For last strip, limit number of rows to its truncated height */ + /* even if the codestream height is larger (which is not compliant, */ + /* but that we tolerate) */ + if ((uint32_t)nrows > td->td_imagelength - tif->tif_row && !isTiled(tif)) + nrows = td->td_imagelength - tif->tif_row; - nrows = sp->cinfo.d.image_height; - /* For last strip, limit number of rows to its truncated height */ - /* even if the codestream height is larger (which is not compliant, */ - /* but that we tolerate) */ - if((uint32_t)nrows > td->td_imagelength - tif->tif_row && !isTiled(tif) ) - nrows = td->td_imagelength - tif->tif_row; +#if defined(JPEG_LIB_MK1_OR_12BIT) + unsigned short *tmpbuf = NULL; +#endif - /* data is expected to be read in multiples of a scanline */ - if ( nrows != 0 ) { + /* data is expected to be read in multiples of a scanline */ + if (nrows != 0) { - /* Cb,Cr both have sampling factors 1, so this is correct */ - JDIMENSION clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width; - int samples_per_clump = sp->samplesperclump; + /* Cb,Cr both have sampling factors 1, so this is correct */ + JDIMENSION clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width; + int samples_per_clump = sp->samplesperclump; #if defined(JPEG_LIB_MK1_OR_12BIT) - unsigned short* tmpbuf = _TIFFmalloc(sizeof(unsigned short) * - sp->cinfo.d.output_width * - sp->cinfo.d.num_components); - if(tmpbuf==NULL) { - TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw", - "Out of memory"); - return 0; - } + tmpbuf = _TIFFmalloc(sizeof(unsigned short) * sp->cinfo.d.output_width * + sp->cinfo.d.num_components); + if (tmpbuf == NULL) { + TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw", "Out of memory"); + return 0; + } #endif - do { - jpeg_component_info *compptr; - int ci, clumpoffset; - - if( cc < sp->bytesperline ) { - TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw", - "application buffer not large enough for all data."); - return 0; - } - - /* Reload downsampled-data buffer if needed */ - if (sp->scancount >= DCTSIZE) { - int n = sp->cinfo.d.max_v_samp_factor * DCTSIZE; - if (TIFFjpeg_read_raw_data(sp, sp->ds_buffer, n) != n) - return (0); - sp->scancount = 0; - } - /* - * Fastest way to unseparate data is to make one pass - * over the scanline for each row of each component. - */ - clumpoffset = 0; /* first sample in clump */ - for (ci = 0, compptr = sp->cinfo.d.comp_info; - ci < sp->cinfo.d.num_components; - ci++, compptr++) { - int hsamp = compptr->h_samp_factor; - int vsamp = compptr->v_samp_factor; - int ypos; - - for (ypos = 0; ypos < vsamp; ypos++) { - JSAMPLE *inptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos]; - JDIMENSION nclump; + do { + jpeg_component_info *compptr; + int ci, clumpoffset; + + if (cc < sp->bytesperline) { + TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw", + "application buffer not large enough for all data."); + goto error; + } + + /* Reload downsampled-data buffer if needed */ + if (sp->scancount >= DCTSIZE) { + int n = sp->cinfo.d.max_v_samp_factor * DCTSIZE; + if (TIFFjpeg_read_raw_data(sp, sp->ds_buffer, n) != n) + goto error; + sp->scancount = 0; + } + /* + * Fastest way to unseparate data is to make one pass + * over the scanline for each row of each component. + */ + clumpoffset = 0; /* first sample in clump */ + for (ci = 0, compptr = sp->cinfo.d.comp_info; + ci < sp->cinfo.d.num_components; ci++, compptr++) { + int hsamp = compptr->h_samp_factor; + int vsamp = compptr->v_samp_factor; + int ypos; + + for (ypos = 0; ypos < vsamp; ypos++) { + JSAMPLE *inptr = sp->ds_buffer[ci][sp->scancount * vsamp + ypos]; + JDIMENSION nclump; #if defined(JPEG_LIB_MK1_OR_12BIT) - JSAMPLE *outptr = (JSAMPLE*)tmpbuf + clumpoffset; + JSAMPLE *outptr = (JSAMPLE *)tmpbuf + clumpoffset; #else - JSAMPLE *outptr = (JSAMPLE*)buf + clumpoffset; - 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; - } + JSAMPLE *outptr = (JSAMPLE *)buf + clumpoffset; + 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"); + goto error; + } #endif - if (hsamp == 1) { - /* fast path for at least Cb and Cr */ - for (nclump = clumps_per_line; nclump-- > 0; ) { - outptr[0] = *inptr++; - outptr += samples_per_clump; - } - } else { - int xpos; - - /* general case */ - for (nclump = clumps_per_line; nclump-- > 0; ) { - for (xpos = 0; xpos < hsamp; xpos++) - outptr[xpos] = *inptr++; - outptr += samples_per_clump; - } - } - clumpoffset += hsamp; - } - } + if (hsamp == 1) { + /* fast path for at least Cb and Cr */ + for (nclump = clumps_per_line; nclump-- > 0;) { + outptr[0] = *inptr++; + outptr += samples_per_clump; + } + } else { + int xpos; + + /* general case */ + for (nclump = clumps_per_line; nclump-- > 0;) { + for (xpos = 0; xpos < hsamp; xpos++) + outptr[xpos] = *inptr++; + outptr += samples_per_clump; + } + } + clumpoffset += hsamp; + } + } #if defined(JPEG_LIB_MK1_OR_12BIT) - { - if (sp->cinfo.d.data_precision == 8) - { - int i=0; - int len = sp->cinfo.d.output_width * sp->cinfo.d.num_components; - for (i=0; i<len; i++) - { - ((unsigned char*)buf)[i] = tmpbuf[i] & 0xff; - } - } - else - { /* 12-bit */ - int value_pairs = (sp->cinfo.d.output_width - * sp->cinfo.d.num_components) / 2; - int iPair; - for( iPair = 0; iPair < value_pairs; iPair++ ) - { - unsigned char *out_ptr = ((unsigned char *) buf) + iPair * 3; - JSAMPLE *in_ptr = (JSAMPLE *) (tmpbuf + iPair * 2); - out_ptr[0] = (unsigned char)((in_ptr[0] & 0xff0) >> 4); - out_ptr[1] = (unsigned char)(((in_ptr[0] & 0xf) << 4) - | ((in_ptr[1] & 0xf00) >> 8)); - out_ptr[2] = (unsigned char)(((in_ptr[1] & 0xff) >> 0)); - } - } - } + { + if (sp->cinfo.d.data_precision == 8) { + int i = 0; + int len = sp->cinfo.d.output_width * sp->cinfo.d.num_components; + for (i = 0; i < len; i++) { + ((unsigned char *)buf)[i] = tmpbuf[i] & 0xff; + } + } else { /* 12-bit */ + int value_pairs = + (sp->cinfo.d.output_width * sp->cinfo.d.num_components) / 2; + int iPair; + for (iPair = 0; iPair < value_pairs; iPair++) { + unsigned char *out_ptr = ((unsigned char *)buf) + iPair * 3; + JSAMPLE *in_ptr = (JSAMPLE *)(tmpbuf + iPair * 2); + out_ptr[0] = (unsigned char)((in_ptr[0] & 0xff0) >> 4); + out_ptr[1] = (unsigned char)(((in_ptr[0] & 0xf) << 4) | + ((in_ptr[1] & 0xf00) >> 8)); + out_ptr[2] = (unsigned char)(((in_ptr[1] & 0xff) >> 0)); + } + } + } #endif - sp->scancount ++; - tif->tif_row += sp->v_sampling; + sp->scancount++; + tif->tif_row += sp->v_sampling; - buf += sp->bytesperline; - cc -= sp->bytesperline; + buf += sp->bytesperline; + cc -= sp->bytesperline; - nrows -= sp->v_sampling; - } while (nrows > 0); + nrows -= sp->v_sampling; + } while (nrows > 0); #if defined(JPEG_LIB_MK1_OR_12BIT) - _TIFFfree(tmpbuf); + _TIFFfree(tmpbuf); #endif + } - } + /* Close down the decompressor if done. */ + return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height || + TIFFjpeg_finish_decompress(sp); - /* Close down the decompressor if done. */ - return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height - || TIFFjpeg_finish_decompress(sp); +error: +#if defined(JPEG_LIB_MK1_OR_12BIT) + _TIFFfree(tmpbuf); +#endif + return 0; } - /* * JPEG Encoding. */ -static void -unsuppress_quant_table (JPEGState* sp, int tblno) -{ - JQUANT_TBL* qtbl; - - if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL) - qtbl->sent_table = FALSE; -} - -static void -suppress_quant_table (JPEGState* sp, int tblno) -{ - JQUANT_TBL* qtbl; - - if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL) - qtbl->sent_table = TRUE; -} - -static void -unsuppress_huff_table (JPEGState* sp, int tblno) -{ - JHUFF_TBL* htbl; - - if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL) - htbl->sent_table = FALSE; - if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL) - htbl->sent_table = FALSE; -} - -static void -suppress_huff_table (JPEGState* sp, int tblno) -{ - JHUFF_TBL* htbl; - - if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL) - htbl->sent_table = TRUE; - if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL) - htbl->sent_table = TRUE; +static void unsuppress_quant_table(JPEGState *sp, int tblno) { + JQUANT_TBL *qtbl; + + if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL) + qtbl->sent_table = FALSE; +} + +static void suppress_quant_table(JPEGState *sp, int tblno) { + JQUANT_TBL *qtbl; + + if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL) + qtbl->sent_table = TRUE; +} + +static void unsuppress_huff_table(JPEGState *sp, int tblno) { + JHUFF_TBL *htbl; + + if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL) + htbl->sent_table = FALSE; + if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL) + htbl->sent_table = FALSE; +} + +static void suppress_huff_table(JPEGState *sp, int tblno) { + JHUFF_TBL *htbl; + + if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL) + htbl->sent_table = TRUE; + if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL) + htbl->sent_table = TRUE; +} + +static int prepare_JPEGTables(TIFF *tif) { + JPEGState *sp = JState(tif); + + /* Initialize quant tables for current quality setting */ + if (!TIFFjpeg_set_quality(sp, sp->otherSettings.jpegquality, FALSE)) + return (0); + /* Mark only the tables we want for output */ + /* NB: chrominance tables are currently used only with YCbCr */ + if (!TIFFjpeg_suppress_tables(sp, TRUE)) + return (0); + if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_QUANT) { + unsuppress_quant_table(sp, 0); + if (sp->photometric == PHOTOMETRIC_YCBCR) + unsuppress_quant_table(sp, 1); + } + if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF) { + unsuppress_huff_table(sp, 0); + if (sp->photometric == PHOTOMETRIC_YCBCR) + unsuppress_huff_table(sp, 1); + } + /* Direct libjpeg output into otherSettings.jpegtables */ + if (!TIFFjpeg_tables_dest(sp, tif)) + return (0); + /* Emit tables-only datastream */ + if (!TIFFjpeg_write_tables(sp)) + return (0); + + return (1); +} + +#if defined(JPEG_LIB_VERSION_MAJOR) && \ + (JPEG_LIB_VERSION_MAJOR > 9 || \ + (JPEG_LIB_VERSION_MAJOR == 9 && JPEG_LIB_VERSION_MINOR >= 4)) +/* This is a modified version of std_huff_tables() from jcparam.c + * in libjpeg-9d because it no longer initializes default Huffman + * tables in jpeg_set_defaults(). */ +static void TIFF_std_huff_tables(j_compress_ptr cinfo) { + + if (cinfo->dc_huff_tbl_ptrs[0] == NULL) { + (void)jpeg_std_huff_table((j_common_ptr)cinfo, TRUE, 0); + } + if (cinfo->ac_huff_tbl_ptrs[0] == NULL) { + (void)jpeg_std_huff_table((j_common_ptr)cinfo, FALSE, 0); + } + if (cinfo->dc_huff_tbl_ptrs[1] == NULL) { + (void)jpeg_std_huff_table((j_common_ptr)cinfo, TRUE, 1); + } + if (cinfo->ac_huff_tbl_ptrs[1] == NULL) { + (void)jpeg_std_huff_table((j_common_ptr)cinfo, FALSE, 1); + } } +#endif -static int -prepare_JPEGTables(TIFF* tif) -{ - JPEGState* sp = JState(tif); - - /* Initialize quant tables for current quality setting */ - if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE)) - return (0); - /* Mark only the tables we want for output */ - /* NB: chrominance tables are currently used only with YCbCr */ - if (!TIFFjpeg_suppress_tables(sp, TRUE)) - return (0); - if (sp->jpegtablesmode & JPEGTABLESMODE_QUANT) { - unsuppress_quant_table(sp, 0); - if (sp->photometric == PHOTOMETRIC_YCBCR) - unsuppress_quant_table(sp, 1); - } - if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF) { - unsuppress_huff_table(sp, 0); - if (sp->photometric == PHOTOMETRIC_YCBCR) - unsuppress_huff_table(sp, 1); - } - /* Direct libjpeg output into jpegtables */ - if (!TIFFjpeg_tables_dest(sp, tif)) - return (0); - /* Emit tables-only datastream */ - if (!TIFFjpeg_write_tables(sp)) - return (0); - - return (1); -} - -static int -JPEGSetupEncode(TIFF* tif) -{ - JPEGState* sp = JState(tif); - TIFFDirectory *td = &tif->tif_dir; - static const char module[] = "JPEGSetupEncode"; - -#if defined(JPEG_DUAL_MODE_8_12) && !defined(TIFFInitJPEG) - if( tif->tif_dir.td_bitspersample == 12 ) - return TIFFReInitJPEG_12( tif, COMPRESSION_JPEG, 1 ); +static int JPEGSetupEncode(TIFF *tif) { + JPEGState *sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; + static const char module[] = "JPEGSetupEncode"; + +#if defined(JPEG_DUAL_MODE_8_12) && !defined(FROM_TIF_JPEG_12) + if (tif->tif_dir.td_bitspersample == 12) { + /* We pass a pointer to a copy of otherSettings, since */ + /* TIFFReInitJPEG_12() will clear sp */ + JPEGOtherSettings savedOtherSettings = sp->otherSettings; + return TIFFReInitJPEG_12(tif, &savedOtherSettings, COMPRESSION_JPEG, 1); + } #endif - JPEGInitializeLibJPEG( tif, FALSE ); - - assert(sp != NULL); - assert(!sp->cinfo.comm.is_decompressor); - - sp->photometric = td->td_photometric; - - /* - * Initialize all JPEG parameters to default values. - * Note that jpeg_set_defaults needs legal values for - * in_color_space and input_components. - */ - if (td->td_planarconfig == PLANARCONFIG_CONTIG) { - sp->cinfo.c.input_components = td->td_samplesperpixel; - if (sp->photometric == PHOTOMETRIC_YCBCR) { - if (sp->jpegcolormode == JPEGCOLORMODE_RGB) { - sp->cinfo.c.in_color_space = JCS_RGB; - } else { - sp->cinfo.c.in_color_space = JCS_YCbCr; - } - } else { - if ((td->td_photometric == PHOTOMETRIC_MINISWHITE || td->td_photometric == PHOTOMETRIC_MINISBLACK) && td->td_samplesperpixel == 1) - sp->cinfo.c.in_color_space = JCS_GRAYSCALE; - else if (td->td_photometric == PHOTOMETRIC_RGB && td->td_samplesperpixel == 3) - sp->cinfo.c.in_color_space = JCS_RGB; - else if (td->td_photometric == PHOTOMETRIC_SEPARATED && td->td_samplesperpixel == 4) - sp->cinfo.c.in_color_space = JCS_CMYK; - else - sp->cinfo.c.in_color_space = JCS_UNKNOWN; - } - } else { - sp->cinfo.c.input_components = 1; - sp->cinfo.c.in_color_space = JCS_UNKNOWN; - } - if (!TIFFjpeg_set_defaults(sp)) - return (0); - /* Set per-file parameters */ - switch (sp->photometric) { - case PHOTOMETRIC_YCBCR: - sp->h_sampling = td->td_ycbcrsubsampling[0]; - sp->v_sampling = td->td_ycbcrsubsampling[1]; - if( sp->h_sampling == 0 || sp->v_sampling == 0 ) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Invalig horizontal/vertical sampling value"); - return (0); - } - if( td->td_bitspersample > 16 ) - { - TIFFErrorExt(tif->tif_clientdata, module, - "BitsPerSample %"PRIu16" not allowed for JPEG", - td->td_bitspersample); - return (0); - } - - /* - * A ReferenceBlackWhite field *must* be present since the - * default value is inappropriate for YCbCr. Fill in the - * proper value if application didn't set it. - */ - { - float *ref; - if (!TIFFGetField(tif, TIFFTAG_REFERENCEBLACKWHITE, - &ref)) { - float refbw[6]; - long top = 1L << td->td_bitspersample; - refbw[0] = 0; - refbw[1] = (float)(top-1L); - refbw[2] = (float)(top>>1); - refbw[3] = refbw[1]; - refbw[4] = refbw[2]; - refbw[5] = refbw[1]; - TIFFSetField(tif, TIFFTAG_REFERENCEBLACKWHITE, - refbw); - } - } - break; - case PHOTOMETRIC_PALETTE: /* disallowed by Tech Note */ - case PHOTOMETRIC_MASK: - TIFFErrorExt(tif->tif_clientdata, module, - "PhotometricInterpretation %"PRIu16" not allowed for JPEG", - sp->photometric); - return (0); - default: - /* TIFF 6.0 forbids subsampling of all other color spaces */ - sp->h_sampling = 1; - sp->v_sampling = 1; - break; - } - - /* Verify miscellaneous parameters */ - - /* - * This would need work if libtiff ever supports different - * depths for different components, or if libjpeg ever supports - * run-time selection of depth. Neither is imminent. - */ + JPEGInitializeLibJPEG(tif, FALSE); + + assert(sp != NULL); + assert(!sp->cinfo.comm.is_decompressor); + + sp->photometric = td->td_photometric; + + /* + * Initialize all JPEG parameters to default values. + * Note that jpeg_set_defaults needs legal values for + * in_color_space and input_components. + */ + if (td->td_planarconfig == PLANARCONFIG_CONTIG) { + sp->cinfo.c.input_components = td->td_samplesperpixel; + if (sp->photometric == PHOTOMETRIC_YCBCR) { + if (sp->otherSettings.jpegcolormode == JPEGCOLORMODE_RGB) { + sp->cinfo.c.in_color_space = JCS_RGB; + } else { + sp->cinfo.c.in_color_space = JCS_YCbCr; + } + } else { + if ((td->td_photometric == PHOTOMETRIC_MINISWHITE || + td->td_photometric == PHOTOMETRIC_MINISBLACK) && + td->td_samplesperpixel == 1) + sp->cinfo.c.in_color_space = JCS_GRAYSCALE; + else if (td->td_photometric == PHOTOMETRIC_RGB && + td->td_samplesperpixel == 3) + sp->cinfo.c.in_color_space = JCS_RGB; + else if (td->td_photometric == PHOTOMETRIC_SEPARATED && + td->td_samplesperpixel == 4) + sp->cinfo.c.in_color_space = JCS_CMYK; + else + sp->cinfo.c.in_color_space = JCS_UNKNOWN; + } + } else { + sp->cinfo.c.input_components = 1; + sp->cinfo.c.in_color_space = JCS_UNKNOWN; + } + if (!TIFFjpeg_set_defaults(sp)) + return (0); + + /* mozjpeg by default enables progressive JPEG, which is illegal in + * JPEG-in-TIFF */ + /* So explicitly disable it. */ + if (sp->cinfo.c.num_scans != 0 && + (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF) != 0) { + /* it has been found that mozjpeg could create corrupt strips/tiles */ + /* in non optimize_coding mode. */ + TIFFWarningExt(tif->tif_clientdata, module, + "mozjpeg library likely detected. Disable emission of " + "Huffman tables in JpegTables tag, and use optimize_coding " + "to avoid potential issues"); + sp->otherSettings.jpegtablesmode &= ~JPEGTABLESMODE_HUFF; + } + sp->cinfo.c.num_scans = 0; + sp->cinfo.c.scan_info = NULL; + + /* Set per-file parameters */ + switch (sp->photometric) { + case PHOTOMETRIC_YCBCR: + sp->h_sampling = td->td_ycbcrsubsampling[0]; + sp->v_sampling = td->td_ycbcrsubsampling[1]; + if (sp->h_sampling == 0 || sp->v_sampling == 0) { + TIFFErrorExt(tif->tif_clientdata, module, + "Invalig horizontal/vertical sampling value"); + return (0); + } + if (td->td_bitspersample > 16) { + TIFFErrorExt(tif->tif_clientdata, module, + "BitsPerSample %" PRIu16 " not allowed for JPEG", + td->td_bitspersample); + return (0); + } + + /* + * A ReferenceBlackWhite field *must* be present since the + * default value is inappropriate for YCbCr. Fill in the + * proper value if application didn't set it. + */ + { + float *ref; + if (!TIFFGetField(tif, TIFFTAG_REFERENCEBLACKWHITE, &ref)) { + float refbw[6]; + long top = 1L << td->td_bitspersample; + refbw[0] = 0; + refbw[1] = (float)(top - 1L); + refbw[2] = (float)(top >> 1); + refbw[3] = refbw[1]; + refbw[4] = refbw[2]; + refbw[5] = refbw[1]; + TIFFSetField(tif, TIFFTAG_REFERENCEBLACKWHITE, refbw); + } + } + break; + case PHOTOMETRIC_PALETTE: /* disallowed by Tech Note */ + case PHOTOMETRIC_MASK: + TIFFErrorExt(tif->tif_clientdata, module, + "PhotometricInterpretation %" PRIu16 " not allowed for JPEG", + sp->photometric); + return (0); + default: + /* TIFF 6.0 forbids subsampling of all other color spaces */ + sp->h_sampling = 1; + sp->v_sampling = 1; + break; + } + + /* Verify miscellaneous parameters */ + + /* + * This would need work if libtiff ever supports different + * depths for different components, or if libjpeg ever supports + * run-time selection of depth. Neither is imminent. + */ #ifdef JPEG_LIB_MK1 - /* BITS_IN_JSAMPLE now permits 8 and 12 --- dgilbert */ - if (td->td_bitspersample != 8 && td->td_bitspersample != 12) + /* BITS_IN_JSAMPLE now permits 8 and 12 --- dgilbert */ + if (td->td_bitspersample != 8 && td->td_bitspersample != 12) #else - if (td->td_bitspersample != BITS_IN_JSAMPLE ) + if (td->td_bitspersample != BITS_IN_JSAMPLE) #endif - { - TIFFErrorExt(tif->tif_clientdata, module, "BitsPerSample %"PRIu16" not allowed for JPEG", - td->td_bitspersample); - return (0); - } - sp->cinfo.c.data_precision = td->td_bitspersample; + { + TIFFErrorExt(tif->tif_clientdata, module, + "BitsPerSample %" PRIu16 " not allowed for JPEG", + td->td_bitspersample); + return (0); + } + sp->cinfo.c.data_precision = td->td_bitspersample; #ifdef JPEG_LIB_MK1 - sp->cinfo.c.bits_in_jsample = td->td_bitspersample; + sp->cinfo.c.bits_in_jsample = td->td_bitspersample; +#endif + if (isTiled(tif)) { + if ((td->td_tilelength % (sp->v_sampling * DCTSIZE)) != 0) { + TIFFErrorExt(tif->tif_clientdata, module, + "JPEG tile height must be multiple of %" PRIu32, + (uint32_t)(sp->v_sampling * DCTSIZE)); + return (0); + } + if ((td->td_tilewidth % (sp->h_sampling * DCTSIZE)) != 0) { + TIFFErrorExt(tif->tif_clientdata, module, + "JPEG tile width must be multiple of %" PRIu32, + (uint32_t)(sp->h_sampling * DCTSIZE)); + return (0); + } + } else { + if (td->td_rowsperstrip < td->td_imagelength && + (td->td_rowsperstrip % (sp->v_sampling * DCTSIZE)) != 0) { + TIFFErrorExt(tif->tif_clientdata, module, + "RowsPerStrip must be multiple of %" PRIu32 " for JPEG", + (uint32_t)(sp->v_sampling * DCTSIZE)); + return (0); + } + } + + /* Create a JPEGTables field if appropriate */ + if (sp->otherSettings.jpegtablesmode & + (JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF)) { + if (sp->otherSettings.jpegtables == NULL || + memcmp(sp->otherSettings.jpegtables, "\0\0\0\0\0\0\0\0\0", 8) == 0) { +#if defined(JPEG_LIB_VERSION_MAJOR) && \ + (JPEG_LIB_VERSION_MAJOR > 9 || \ + (JPEG_LIB_VERSION_MAJOR == 9 && JPEG_LIB_VERSION_MINOR >= 4)) + if ((sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF) != 0 && + (sp->cinfo.c.dc_huff_tbl_ptrs[0] == NULL || + sp->cinfo.c.dc_huff_tbl_ptrs[1] == NULL || + sp->cinfo.c.ac_huff_tbl_ptrs[0] == NULL || + sp->cinfo.c.ac_huff_tbl_ptrs[1] == NULL)) { + /* libjpeg-9d no longer initializes default Huffman tables in */ + /* jpeg_set_defaults() */ + TIFF_std_huff_tables(&sp->cinfo.c); + } #endif - if (isTiled(tif)) { - if ((td->td_tilelength % (sp->v_sampling * DCTSIZE)) != 0) { - TIFFErrorExt(tif->tif_clientdata, module, - "JPEG tile height must be multiple of %"PRIu32, - (uint32_t)(sp->v_sampling * DCTSIZE)); - return (0); - } - if ((td->td_tilewidth % (sp->h_sampling * DCTSIZE)) != 0) { - TIFFErrorExt(tif->tif_clientdata, module, - "JPEG tile width must be multiple of %"PRIu32, - (uint32_t)(sp->h_sampling * DCTSIZE)); - return (0); - } - } else { - if (td->td_rowsperstrip < td->td_imagelength && - (td->td_rowsperstrip % (sp->v_sampling * DCTSIZE)) != 0) { - TIFFErrorExt(tif->tif_clientdata, module, - "RowsPerStrip must be multiple of %"PRIu32" for JPEG", - (uint32_t)(sp->v_sampling * DCTSIZE)); - return (0); - } - } - - /* Create a JPEGTables field if appropriate */ - if (sp->jpegtablesmode & (JPEGTABLESMODE_QUANT|JPEGTABLESMODE_HUFF)) { - if( sp->jpegtables == NULL - || memcmp(sp->jpegtables,"\0\0\0\0\0\0\0\0\0",8) == 0 ) - { - if (!prepare_JPEGTables(tif)) - return (0); - /* Mark the field present */ - /* Can't use TIFFSetField since BEENWRITING is already set! */ - tif->tif_flags |= TIFF_DIRTYDIRECT; - TIFFSetFieldBit(tif, FIELD_JPEGTABLES); - } - } else { - /* We do not support application-supplied JPEGTables, */ - /* so mark the field not present */ - TIFFClrFieldBit(tif, FIELD_JPEGTABLES); - } - - /* Direct libjpeg output to libtiff's output buffer */ - TIFFjpeg_data_dest(sp, tif); - - return (1); + + if (!prepare_JPEGTables(tif)) + return (0); + /* Mark the field present */ + /* Can't use TIFFSetField since BEENWRITING is already set! */ + tif->tif_flags |= TIFF_DIRTYDIRECT; + TIFFSetFieldBit(tif, FIELD_JPEGTABLES); + } + } else { + /* We do not support application-supplied JPEGTables, */ + /* so mark the field not present */ + TIFFClrFieldBit(tif, FIELD_JPEGTABLES); + } + + /* Direct libjpeg output to libtiff's output buffer */ + TIFFjpeg_data_dest(sp, tif); + + return (1); } /* * Set encoding state at the start of a strip or tile. */ -static int -JPEGPreEncode(TIFF* tif, uint16_t s) -{ - JPEGState *sp = JState(tif); - TIFFDirectory *td = &tif->tif_dir; - static const char module[] = "JPEGPreEncode"; - uint32_t segment_width, segment_height; - int downsampled_input; - - assert(sp != NULL); - - if (sp->cinfo.comm.is_decompressor == 1) - { - tif->tif_setupencode( tif ); - } - - assert(!sp->cinfo.comm.is_decompressor); - /* - * Set encoding parameters for this strip/tile. - */ - if (isTiled(tif)) { - segment_width = td->td_tilewidth; - segment_height = td->td_tilelength; - sp->bytesperline = TIFFTileRowSize(tif); - } else { - segment_width = td->td_imagewidth; - segment_height = td->td_imagelength - tif->tif_row; - if (segment_height > td->td_rowsperstrip) - segment_height = td->td_rowsperstrip; - sp->bytesperline = TIFFScanlineSize(tif); - } - if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) { - /* for PC 2, scale down the strip/tile size - * to match a downsampled component - */ - segment_width = TIFFhowmany_32(segment_width, sp->h_sampling); - segment_height = TIFFhowmany_32(segment_height, sp->v_sampling); - } - if (segment_width > 65535 || segment_height > 65535) { - TIFFErrorExt(tif->tif_clientdata, module, "Strip/tile too large for JPEG"); - return (0); - } - sp->cinfo.c.image_width = segment_width; - sp->cinfo.c.image_height = segment_height; - downsampled_input = FALSE; - if (td->td_planarconfig == PLANARCONFIG_CONTIG) { - sp->cinfo.c.input_components = td->td_samplesperpixel; - if (sp->photometric == PHOTOMETRIC_YCBCR) { - if (sp->jpegcolormode != JPEGCOLORMODE_RGB) { - if (sp->h_sampling != 1 || sp->v_sampling != 1) - downsampled_input = TRUE; - } - if (!TIFFjpeg_set_colorspace(sp, JCS_YCbCr)) - return (0); - /* - * Set Y sampling factors; - * we assume jpeg_set_colorspace() set the rest to 1 - */ - sp->cinfo.c.comp_info[0].h_samp_factor = sp->h_sampling; - sp->cinfo.c.comp_info[0].v_samp_factor = sp->v_sampling; - } else { - if (!TIFFjpeg_set_colorspace(sp, sp->cinfo.c.in_color_space)) - return (0); - /* jpeg_set_colorspace set all sampling factors to 1 */ - } - } else { - if (!TIFFjpeg_set_colorspace(sp, JCS_UNKNOWN)) - return (0); - sp->cinfo.c.comp_info[0].component_id = s; - /* jpeg_set_colorspace() set sampling factors to 1 */ - if (sp->photometric == PHOTOMETRIC_YCBCR && s > 0) { - sp->cinfo.c.comp_info[0].quant_tbl_no = 1; - sp->cinfo.c.comp_info[0].dc_tbl_no = 1; - sp->cinfo.c.comp_info[0].ac_tbl_no = 1; - } - } - /* ensure libjpeg won't write any extraneous markers */ - sp->cinfo.c.write_JFIF_header = FALSE; - sp->cinfo.c.write_Adobe_marker = FALSE; - /* set up table handling correctly */ - /* calling TIFFjpeg_set_quality() causes quantization tables to be flagged */ - /* as being to be emitted, which we don't want in the JPEGTABLESMODE_QUANT */ - /* mode, so we must manually suppress them. However TIFFjpeg_set_quality() */ - /* should really be called when dealing with files with directories with */ - /* mixed qualities. see http://trac.osgeo.org/gdal/ticket/3539 */ - if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE)) - return (0); - if (sp->jpegtablesmode & JPEGTABLESMODE_QUANT) { - suppress_quant_table(sp, 0); - suppress_quant_table(sp, 1); - } - else { - unsuppress_quant_table(sp, 0); - unsuppress_quant_table(sp, 1); - } - if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF) - { - /* Explicit suppression is only needed if we did not go through the */ - /* prepare_JPEGTables() code path, which may be the case if updating */ - /* an existing file */ - suppress_huff_table(sp, 0); - suppress_huff_table(sp, 1); - sp->cinfo.c.optimize_coding = FALSE; - } - else - sp->cinfo.c.optimize_coding = TRUE; - if (downsampled_input) { - /* Need to use raw-data interface to libjpeg */ - sp->cinfo.c.raw_data_in = TRUE; - tif->tif_encoderow = JPEGEncodeRaw; - tif->tif_encodestrip = JPEGEncodeRaw; - tif->tif_encodetile = JPEGEncodeRaw; - } else { - /* Use normal interface to libjpeg */ - sp->cinfo.c.raw_data_in = FALSE; - tif->tif_encoderow = JPEGEncode; - tif->tif_encodestrip = JPEGEncode; - tif->tif_encodetile = JPEGEncode; - } - /* Start JPEG compressor */ - if (!TIFFjpeg_start_compress(sp, FALSE)) - return (0); - /* Allocate downsampled-data buffers if needed */ - if (downsampled_input) { - if (!alloc_downsampled_buffers(tif, sp->cinfo.c.comp_info, - sp->cinfo.c.num_components)) - return (0); - } - sp->scancount = 0; - - return (1); +static int JPEGPreEncode(TIFF *tif, uint16_t s) { + JPEGState *sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; + static const char module[] = "JPEGPreEncode"; + uint32_t segment_width, segment_height; + int downsampled_input; + + assert(sp != NULL); + + if (sp->cinfo.comm.is_decompressor == 1) { + tif->tif_setupencode(tif); + } + + assert(!sp->cinfo.comm.is_decompressor); + /* + * Set encoding parameters for this strip/tile. + */ + if (isTiled(tif)) { + segment_width = td->td_tilewidth; + segment_height = td->td_tilelength; + sp->bytesperline = TIFFTileRowSize(tif); + } else { + segment_width = td->td_imagewidth; + segment_height = td->td_imagelength - tif->tif_row; + if (segment_height > td->td_rowsperstrip) + segment_height = td->td_rowsperstrip; + sp->bytesperline = TIFFScanlineSize(tif); + } + if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) { + /* for PC 2, scale down the strip/tile size + * to match a downsampled component + */ + segment_width = TIFFhowmany_32(segment_width, sp->h_sampling); + segment_height = TIFFhowmany_32(segment_height, sp->v_sampling); + } + if (segment_width > 65535 || segment_height > 65535) { + TIFFErrorExt(tif->tif_clientdata, module, "Strip/tile too large for JPEG"); + return (0); + } + sp->cinfo.c.image_width = segment_width; + sp->cinfo.c.image_height = segment_height; + downsampled_input = FALSE; + if (td->td_planarconfig == PLANARCONFIG_CONTIG) { + sp->cinfo.c.input_components = td->td_samplesperpixel; + if (sp->photometric == PHOTOMETRIC_YCBCR) { + if (sp->otherSettings.jpegcolormode != JPEGCOLORMODE_RGB) { + if (sp->h_sampling != 1 || sp->v_sampling != 1) + downsampled_input = TRUE; + } + if (!TIFFjpeg_set_colorspace(sp, JCS_YCbCr)) + return (0); + /* + * Set Y sampling factors; + * we assume jpeg_set_colorspace() set the rest to 1 + */ + sp->cinfo.c.comp_info[0].h_samp_factor = sp->h_sampling; + sp->cinfo.c.comp_info[0].v_samp_factor = sp->v_sampling; + } else { + if (!TIFFjpeg_set_colorspace(sp, sp->cinfo.c.in_color_space)) + return (0); + /* jpeg_set_colorspace set all sampling factors to 1 */ + } + } else { + if (!TIFFjpeg_set_colorspace(sp, JCS_UNKNOWN)) + return (0); + sp->cinfo.c.comp_info[0].component_id = s; + /* jpeg_set_colorspace() set sampling factors to 1 */ + if (sp->photometric == PHOTOMETRIC_YCBCR && s > 0) { + sp->cinfo.c.comp_info[0].quant_tbl_no = 1; + sp->cinfo.c.comp_info[0].dc_tbl_no = 1; + sp->cinfo.c.comp_info[0].ac_tbl_no = 1; + } + } + /* ensure libjpeg won't write any extraneous markers */ + sp->cinfo.c.write_JFIF_header = FALSE; + sp->cinfo.c.write_Adobe_marker = FALSE; + /* set up table handling correctly */ + /* calling TIFFjpeg_set_quality() causes quantization tables to be flagged */ + /* as being to be emitted, which we don't want in the JPEGTABLESMODE_QUANT */ + /* mode, so we must manually suppress them. However TIFFjpeg_set_quality() */ + /* should really be called when dealing with files with directories with */ + /* mixed qualities. see http://trac.osgeo.org/gdal/ticket/3539 */ + if (!TIFFjpeg_set_quality(sp, sp->otherSettings.jpegquality, FALSE)) + return (0); + if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_QUANT) { + suppress_quant_table(sp, 0); + suppress_quant_table(sp, 1); + } else { + unsuppress_quant_table(sp, 0); + unsuppress_quant_table(sp, 1); + } + if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF) { + /* Explicit suppression is only needed if we did not go through the */ + /* prepare_JPEGTables() code path, which may be the case if updating */ + /* an existing file */ + suppress_huff_table(sp, 0); + suppress_huff_table(sp, 1); + sp->cinfo.c.optimize_coding = FALSE; + } else + sp->cinfo.c.optimize_coding = TRUE; + if (downsampled_input) { + /* Need to use raw-data interface to libjpeg */ + sp->cinfo.c.raw_data_in = TRUE; + tif->tif_encoderow = JPEGEncodeRaw; + tif->tif_encodestrip = JPEGEncodeRaw; + tif->tif_encodetile = JPEGEncodeRaw; + } else { + /* Use normal interface to libjpeg */ + sp->cinfo.c.raw_data_in = FALSE; + tif->tif_encoderow = JPEGEncode; + tif->tif_encodestrip = JPEGEncode; + tif->tif_encodetile = JPEGEncode; + } + /* Start JPEG compressor */ + if (!TIFFjpeg_start_compress(sp, FALSE)) + return (0); + /* Allocate downsampled-data buffers if needed */ + if (downsampled_input) { + if (!alloc_downsampled_buffers(tif, sp->cinfo.c.comp_info, + sp->cinfo.c.num_components)) + return (0); + } + sp->scancount = 0; + + return (1); } /* * Encode a chunk of pixels. * "Standard" case: incoming data is not downsampled. */ -static int -JPEGEncode(TIFF* tif, uint8_t* buf, tmsize_t cc, uint16_t s) -{ - JPEGState *sp = JState(tif); - tmsize_t nrows; - JSAMPROW bufptr[1]; - short *line16 = NULL; - int line16_count = 0; - - (void) s; - assert(sp != NULL); - /* data is expected to be supplied in multiples of a scanline */ - nrows = cc / sp->bytesperline; - if (cc % sp->bytesperline) - TIFFWarningExt(tif->tif_clientdata, tif->tif_name, - "fractional scanline discarded"); - - /* The last strip will be limited to image size */ - if( !isTiled(tif) && tif->tif_row+nrows > tif->tif_dir.td_imagelength ) - nrows = tif->tif_dir.td_imagelength - tif->tif_row; - - if( sp->cinfo.c.data_precision == 12 ) - { - line16_count = (int)((sp->bytesperline * 2) / 3); - line16 = (short *) _TIFFmalloc(sizeof(short) * line16_count); - if (!line16) - { - TIFFErrorExt(tif->tif_clientdata, - "JPEGEncode", - "Failed to allocate memory"); - - return 0; - } - } - - while (nrows-- > 0) { +static int JPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) { + JPEGState *sp = JState(tif); + tmsize_t nrows; + JSAMPROW bufptr[1]; + short *line16 = NULL; + int line16_count = 0; + + (void)s; + assert(sp != NULL); + /* data is expected to be supplied in multiples of a scanline */ + nrows = cc / sp->bytesperline; + if (cc % sp->bytesperline) + TIFFWarningExt(tif->tif_clientdata, tif->tif_name, + "fractional scanline discarded"); + + /* The last strip will be limited to image size */ + if (!isTiled(tif) && tif->tif_row + nrows > tif->tif_dir.td_imagelength) + nrows = tif->tif_dir.td_imagelength - tif->tif_row; + + if (sp->cinfo.c.data_precision == 12) { + line16_count = (int)((sp->bytesperline * 2) / 3); + line16 = (short *)_TIFFmalloc(sizeof(short) * line16_count); + if (!line16) { + TIFFErrorExt(tif->tif_clientdata, "JPEGEncode", + "Failed to allocate memory"); + + return 0; + } + } - if( sp->cinfo.c.data_precision == 12 ) - { + while (nrows-- > 0) { - int value_pairs = line16_count / 2; - int iPair; + if (sp->cinfo.c.data_precision == 12) { - bufptr[0] = (JSAMPROW) line16; + int value_pairs = line16_count / 2; + int iPair; - for( iPair = 0; iPair < value_pairs; iPair++ ) - { - unsigned char *in_ptr = - ((unsigned char *) buf) + iPair * 3; - JSAMPLE *out_ptr = (JSAMPLE *) (line16 + iPair * 2); + bufptr[0] = (JSAMPROW)line16; - out_ptr[0] = (in_ptr[0] << 4) | ((in_ptr[1] & 0xf0) >> 4); - out_ptr[1] = ((in_ptr[1] & 0x0f) << 8) | in_ptr[2]; - } - } - else - { - bufptr[0] = (JSAMPROW) buf; - } - if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1) - return (0); - if (nrows > 0) - tif->tif_row++; - buf += sp->bytesperline; - } - - if( sp->cinfo.c.data_precision == 12 ) - { - _TIFFfree( line16 ); - } - - return (1); + for (iPair = 0; iPair < value_pairs; iPair++) { + unsigned char *in_ptr = ((unsigned char *)buf) + iPair * 3; + JSAMPLE *out_ptr = (JSAMPLE *)(line16 + iPair * 2); + + out_ptr[0] = (in_ptr[0] << 4) | ((in_ptr[1] & 0xf0) >> 4); + out_ptr[1] = ((in_ptr[1] & 0x0f) << 8) | in_ptr[2]; + } + } else { + bufptr[0] = (JSAMPROW)buf; + } + if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1) + return (0); + if (nrows > 0) + tif->tif_row++; + buf += sp->bytesperline; + } + + if (sp->cinfo.c.data_precision == 12) { + _TIFFfree(line16); + } + + return (1); } /* * Encode a chunk of pixels. * Incoming data is expected to be downsampled per sampling factors. */ -static int -JPEGEncodeRaw(TIFF* tif, uint8_t* buf, tmsize_t cc, uint16_t s) -{ - JPEGState *sp = JState(tif); - JSAMPLE* inptr; - JSAMPLE* outptr; - tmsize_t nrows; - JDIMENSION clumps_per_line, nclump; - int clumpoffset, ci, xpos, ypos; - jpeg_component_info* compptr; - int samples_per_clump = sp->samplesperclump; - tmsize_t bytesperclumpline; - - (void) s; - assert(sp != NULL); - /* 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 = ((((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; - if (cc % bytesperclumpline) - TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "fractional scanline discarded"); - - /* Cb,Cr both have sampling factors 1, so this is correct */ - clumps_per_line = sp->cinfo.c.comp_info[1].downsampled_width; - - while (nrows > 0) { - /* - * Fastest way to separate the data is to make one pass - * over the scanline for each row of each component. - */ - clumpoffset = 0; /* first sample in clump */ - for (ci = 0, compptr = sp->cinfo.c.comp_info; - ci < sp->cinfo.c.num_components; - ci++, compptr++) { - int hsamp = compptr->h_samp_factor; - int vsamp = compptr->v_samp_factor; - int padding = (int) (compptr->width_in_blocks * DCTSIZE - - clumps_per_line * hsamp); - for (ypos = 0; ypos < vsamp; ypos++) { - inptr = ((JSAMPLE*) buf) + clumpoffset; - outptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos]; - if (hsamp == 1) { - /* fast path for at least Cb and Cr */ - for (nclump = clumps_per_line; nclump-- > 0; ) { - *outptr++ = inptr[0]; - inptr += samples_per_clump; - } - } else { - /* general case */ - for (nclump = clumps_per_line; nclump-- > 0; ) { - for (xpos = 0; xpos < hsamp; xpos++) - *outptr++ = inptr[xpos]; - inptr += samples_per_clump; - } - } - /* pad each scanline as needed */ - for (xpos = 0; xpos < padding; xpos++) { - *outptr = outptr[-1]; - outptr++; - } - clumpoffset += hsamp; - } - } - sp->scancount++; - if (sp->scancount >= DCTSIZE) { - int n = sp->cinfo.c.max_v_samp_factor * DCTSIZE; - if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n) - return (0); - sp->scancount = 0; - } - tif->tif_row += sp->v_sampling; - buf += bytesperclumpline; - nrows -= sp->v_sampling; - } - return (1); +static int JPEGEncodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) { + JPEGState *sp = JState(tif); + JSAMPLE *inptr; + JSAMPLE *outptr; + tmsize_t nrows; + JDIMENSION clumps_per_line, nclump; + int clumpoffset, ci, xpos, ypos; + jpeg_component_info *compptr; + int samples_per_clump = sp->samplesperclump; + tmsize_t bytesperclumpline; + + (void)s; + assert(sp != NULL); + /* 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 = + ((((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; + if (cc % bytesperclumpline) + TIFFWarningExt(tif->tif_clientdata, tif->tif_name, + "fractional scanline discarded"); + + /* Cb,Cr both have sampling factors 1, so this is correct */ + clumps_per_line = sp->cinfo.c.comp_info[1].downsampled_width; + + while (nrows > 0) { + /* + * Fastest way to separate the data is to make one pass + * over the scanline for each row of each component. + */ + clumpoffset = 0; /* first sample in clump */ + for (ci = 0, compptr = sp->cinfo.c.comp_info; + ci < sp->cinfo.c.num_components; ci++, compptr++) { + int hsamp = compptr->h_samp_factor; + int vsamp = compptr->v_samp_factor; + int padding = + (int)(compptr->width_in_blocks * DCTSIZE - clumps_per_line * hsamp); + for (ypos = 0; ypos < vsamp; ypos++) { + inptr = ((JSAMPLE *)buf) + clumpoffset; + outptr = sp->ds_buffer[ci][sp->scancount * vsamp + ypos]; + if (hsamp == 1) { + /* fast path for at least Cb and Cr */ + for (nclump = clumps_per_line; nclump-- > 0;) { + *outptr++ = inptr[0]; + inptr += samples_per_clump; + } + } else { + /* general case */ + for (nclump = clumps_per_line; nclump-- > 0;) { + for (xpos = 0; xpos < hsamp; xpos++) + *outptr++ = inptr[xpos]; + inptr += samples_per_clump; + } + } + /* pad each scanline as needed */ + for (xpos = 0; xpos < padding; xpos++) { + *outptr = outptr[-1]; + outptr++; + } + clumpoffset += hsamp; + } + } + sp->scancount++; + if (sp->scancount >= DCTSIZE) { + int n = sp->cinfo.c.max_v_samp_factor * DCTSIZE; + if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n) + return (0); + sp->scancount = 0; + } + tif->tif_row += sp->v_sampling; + buf += bytesperclumpline; + nrows -= sp->v_sampling; + } + return (1); } /* * Finish up at the end of a strip or tile. */ -static int -JPEGPostEncode(TIFF* tif) -{ - JPEGState *sp = JState(tif); - - if (sp->scancount > 0) { - /* - * Need to emit a partial bufferload of downsampled data. - * Pad the data vertically. - */ - int ci, ypos, n; - jpeg_component_info* compptr; - - for (ci = 0, compptr = sp->cinfo.c.comp_info; - ci < sp->cinfo.c.num_components; - ci++, compptr++) { - int vsamp = compptr->v_samp_factor; - tmsize_t row_width = compptr->width_in_blocks * DCTSIZE - * sizeof(JSAMPLE); - for (ypos = sp->scancount * vsamp; - ypos < DCTSIZE * vsamp; ypos++) { - _TIFFmemcpy((void*)sp->ds_buffer[ci][ypos], - (void*)sp->ds_buffer[ci][ypos-1], - row_width); - - } - } - n = sp->cinfo.c.max_v_samp_factor * DCTSIZE; - if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n) - return (0); - } - - return (TIFFjpeg_finish_compress(JState(tif))); -} - -static void -JPEGCleanup(TIFF* tif) -{ - JPEGState *sp = JState(tif); - - assert(sp != 0); - - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; - tif->tif_tagmethods.printdir = sp->printdir; - if( sp->cinfo_initialized ) - TIFFjpeg_destroy(sp); /* release libjpeg resources */ - if (sp->jpegtables) /* tag value */ - _TIFFfree(sp->jpegtables); - _TIFFfree(tif->tif_data); /* release local state */ - tif->tif_data = NULL; +static int JPEGPostEncode(TIFF *tif) { + JPEGState *sp = JState(tif); - _TIFFSetDefaultCompressionState(tif); -} - -static void -JPEGResetUpsampled( TIFF* tif ) -{ - JPEGState* sp = JState(tif); - TIFFDirectory* td = &tif->tif_dir; - - /* - * Mark whether returned data is up-sampled or not so TIFFStripSize - * and TIFFTileSize return values that reflect the true amount of - * data. - */ - tif->tif_flags &= ~TIFF_UPSAMPLED; - if (td->td_planarconfig == PLANARCONFIG_CONTIG) { - if (td->td_photometric == PHOTOMETRIC_YCBCR && - sp->jpegcolormode == JPEGCOLORMODE_RGB) { - tif->tif_flags |= TIFF_UPSAMPLED; - } else { + if (sp->scancount > 0) { + /* + * Need to emit a partial bufferload of downsampled data. + * Pad the data vertically. + */ + int ci, ypos, n; + jpeg_component_info *compptr; + + for (ci = 0, compptr = sp->cinfo.c.comp_info; + ci < sp->cinfo.c.num_components; ci++, compptr++) { + int vsamp = compptr->v_samp_factor; + tmsize_t row_width = compptr->width_in_blocks * DCTSIZE * sizeof(JSAMPLE); + for (ypos = sp->scancount * vsamp; ypos < DCTSIZE * vsamp; ypos++) { + _TIFFmemcpy((void *)sp->ds_buffer[ci][ypos], + (void *)sp->ds_buffer[ci][ypos - 1], row_width); + } + } + n = sp->cinfo.c.max_v_samp_factor * DCTSIZE; + if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n) + return (0); + } + + return (TIFFjpeg_finish_compress(JState(tif))); +} + +static void JPEGCleanup(TIFF *tif) { + JPEGState *sp = JState(tif); + + assert(sp != 0); + + tif->tif_tagmethods.vgetfield = sp->otherSettings.vgetparent; + tif->tif_tagmethods.vsetfield = sp->otherSettings.vsetparent; + tif->tif_tagmethods.printdir = sp->otherSettings.printdir; + if (sp->cinfo_initialized) + TIFFjpeg_destroy(sp); /* release libjpeg resources */ + if (sp->otherSettings.jpegtables) /* tag value */ + _TIFFfree(sp->otherSettings.jpegtables); + _TIFFfree(tif->tif_data); /* release local state */ + tif->tif_data = NULL; + + _TIFFSetDefaultCompressionState(tif); +} + +static void JPEGResetUpsampled(TIFF *tif) { + JPEGState *sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; + + /* + * Mark whether returned data is up-sampled or not so TIFFStripSize + * and TIFFTileSize return values that reflect the true amount of + * data. + */ + tif->tif_flags &= ~TIFF_UPSAMPLED; + if (td->td_planarconfig == PLANARCONFIG_CONTIG) { + if (td->td_photometric == PHOTOMETRIC_YCBCR && + sp->otherSettings.jpegcolormode == JPEGCOLORMODE_RGB) { + tif->tif_flags |= TIFF_UPSAMPLED; + } else { #ifdef notdef - if (td->td_ycbcrsubsampling[0] != 1 || - td->td_ycbcrsubsampling[1] != 1) - ; /* XXX what about up-sampling? */ + if (td->td_ycbcrsubsampling[0] != 1 || td->td_ycbcrsubsampling[1] != 1) + ; /* XXX what about up-sampling? */ #endif - } - } - - /* - * Must recalculate cached tile size in case sampling state changed. - * Should we really be doing this now if image size isn't set? - */ - if( tif->tif_tilesize > 0 ) - tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1); - if( tif->tif_scanlinesize > 0 ) - tif->tif_scanlinesize = TIFFScanlineSize(tif); -} - -static int -JPEGVSetField(TIFF* tif, uint32_t tag, va_list ap) -{ - JPEGState* sp = JState(tif); - const TIFFField* fip; - uint32_t v32; - - assert(sp != NULL); - - switch (tag) { - case TIFFTAG_JPEGTABLES: - v32 = (uint32_t) va_arg(ap, uint32_t); - if (v32 == 0) { - /* XXX */ - return (0); - } - _TIFFsetByteArray(&sp->jpegtables, va_arg(ap, void*), v32); - sp->jpegtables_length = v32; - TIFFSetFieldBit(tif, FIELD_JPEGTABLES); - break; - case TIFFTAG_JPEGQUALITY: - sp->jpegquality = (int) va_arg(ap, int); - return (1); /* pseudo tag */ - case TIFFTAG_JPEGCOLORMODE: - sp->jpegcolormode = (int) va_arg(ap, int); - JPEGResetUpsampled( tif ); - return (1); /* pseudo tag */ - case TIFFTAG_PHOTOMETRIC: - { - int ret_value = (*sp->vsetparent)(tif, tag, ap); - JPEGResetUpsampled( tif ); - return ret_value; - } - case TIFFTAG_JPEGTABLESMODE: - sp->jpegtablesmode = (int) va_arg(ap, int); - return (1); /* pseudo tag */ - case TIFFTAG_YCBCRSUBSAMPLING: - /* mark the fact that we have a real ycbcrsubsampling! */ - sp->ycbcrsampling_fetched = 1; - /* should we be recomputing upsampling info here? */ - return (*sp->vsetparent)(tif, tag, ap); - default: - return (*sp->vsetparent)(tif, tag, ap); - } - - if ((fip = TIFFFieldWithTag(tif, tag)) != NULL) { - TIFFSetFieldBit(tif, fip->field_bit); - } else { - return (0); - } - - tif->tif_flags |= TIFF_DIRTYDIRECT; - return (1); -} - -static int -JPEGVGetField(TIFF* tif, uint32_t tag, va_list ap) -{ - JPEGState* sp = JState(tif); - - assert(sp != NULL); - - switch (tag) { - case TIFFTAG_JPEGTABLES: - *va_arg(ap, uint32_t*) = sp->jpegtables_length; - *va_arg(ap, const void**) = sp->jpegtables; - break; - case TIFFTAG_JPEGQUALITY: - *va_arg(ap, int*) = sp->jpegquality; - break; - case TIFFTAG_JPEGCOLORMODE: - *va_arg(ap, int*) = sp->jpegcolormode; - break; - case TIFFTAG_JPEGTABLESMODE: - *va_arg(ap, int*) = sp->jpegtablesmode; - break; - default: - return (*sp->vgetparent)(tif, tag, ap); - } - return (1); -} - -static void -JPEGPrintDir(TIFF* tif, FILE* fd, long flags) -{ - JPEGState* sp = JState(tif); - - assert(sp != NULL); - (void) flags; - - if( sp != NULL ) { - if (TIFFFieldSet(tif,FIELD_JPEGTABLES)) - fprintf(fd, " JPEG Tables: (%"PRIu32" bytes)\n", - sp->jpegtables_length); - if (sp->printdir) - (*sp->printdir)(tif, fd, flags); - } -} - -static uint32_t -JPEGDefaultStripSize(TIFF* tif, uint32_t s) -{ - JPEGState* sp = JState(tif); - TIFFDirectory *td = &tif->tif_dir; - - s = (*sp->defsparent)(tif, s); - if (s < td->td_imagelength) - s = TIFFroundup_32(s, td->td_ycbcrsubsampling[1] * DCTSIZE); - return (s); -} - -static void -JPEGDefaultTileSize(TIFF* tif, uint32_t* tw, uint32_t* th) -{ - JPEGState* sp = JState(tif); - TIFFDirectory *td = &tif->tif_dir; - - (*sp->deftparent)(tif, tw, th); - *tw = TIFFroundup_32(*tw, td->td_ycbcrsubsampling[0] * DCTSIZE); - *th = TIFFroundup_32(*th, td->td_ycbcrsubsampling[1] * DCTSIZE); + } + } + + /* + * Must recalculate cached tile size in case sampling state changed. + * Should we really be doing this now if image size isn't set? + */ + if (tif->tif_tilesize > 0) + tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1); + if (tif->tif_scanlinesize > 0) + tif->tif_scanlinesize = TIFFScanlineSize(tif); +} + +static int JPEGVSetField(TIFF *tif, uint32_t tag, va_list ap) { + JPEGState *sp = JState(tif); + const TIFFField *fip; + uint32_t v32; + + assert(sp != NULL); + + switch (tag) { + case TIFFTAG_JPEGTABLES: + v32 = (uint32_t)va_arg(ap, uint32_t); + if (v32 == 0) { + /* XXX */ + return (0); + } + _TIFFsetByteArray(&sp->otherSettings.jpegtables, va_arg(ap, void *), v32); + sp->otherSettings.jpegtables_length = v32; + TIFFSetFieldBit(tif, FIELD_JPEGTABLES); + break; + case TIFFTAG_JPEGQUALITY: + sp->otherSettings.jpegquality = (int)va_arg(ap, int); + return (1); /* pseudo tag */ + case TIFFTAG_JPEGCOLORMODE: + sp->otherSettings.jpegcolormode = (int)va_arg(ap, int); + JPEGResetUpsampled(tif); + return (1); /* pseudo tag */ + case TIFFTAG_PHOTOMETRIC: { + int ret_value = (*sp->otherSettings.vsetparent)(tif, tag, ap); + JPEGResetUpsampled(tif); + return ret_value; + } + case TIFFTAG_JPEGTABLESMODE: + sp->otherSettings.jpegtablesmode = (int)va_arg(ap, int); + return (1); /* pseudo tag */ + case TIFFTAG_YCBCRSUBSAMPLING: + /* mark the fact that we have a real ycbcrsubsampling! */ + sp->otherSettings.ycbcrsampling_fetched = 1; + /* should we be recomputing upsampling info here? */ + return (*sp->otherSettings.vsetparent)(tif, tag, ap); + default: + return (*sp->otherSettings.vsetparent)(tif, tag, ap); + } + + if ((fip = TIFFFieldWithTag(tif, tag)) != NULL) { + TIFFSetFieldBit(tif, fip->field_bit); + } else { + return (0); + } + + tif->tif_flags |= TIFF_DIRTYDIRECT; + return (1); +} + +static int JPEGVGetField(TIFF *tif, uint32_t tag, va_list ap) { + JPEGState *sp = JState(tif); + + assert(sp != NULL); + + switch (tag) { + case TIFFTAG_JPEGTABLES: + *va_arg(ap, uint32_t *) = sp->otherSettings.jpegtables_length; + *va_arg(ap, const void **) = sp->otherSettings.jpegtables; + break; + case TIFFTAG_JPEGQUALITY: + *va_arg(ap, int *) = sp->otherSettings.jpegquality; + break; + case TIFFTAG_JPEGCOLORMODE: + *va_arg(ap, int *) = sp->otherSettings.jpegcolormode; + break; + case TIFFTAG_JPEGTABLESMODE: + *va_arg(ap, int *) = sp->otherSettings.jpegtablesmode; + break; + default: + return (*sp->otherSettings.vgetparent)(tif, tag, ap); + } + return (1); +} + +static void JPEGPrintDir(TIFF *tif, FILE *fd, long flags) { + JPEGState *sp = JState(tif); + + assert(sp != NULL); + (void)flags; + + if (sp != NULL) { + if (TIFFFieldSet(tif, FIELD_JPEGTABLES)) + fprintf(fd, " JPEG Tables: (%" PRIu32 " bytes)\n", + sp->otherSettings.jpegtables_length); + if (sp->otherSettings.printdir) + (*sp->otherSettings.printdir)(tif, fd, flags); + } +} + +static uint32_t JPEGDefaultStripSize(TIFF *tif, uint32_t s) { + JPEGState *sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; + + s = (*sp->otherSettings.defsparent)(tif, s); + if (s < td->td_imagelength) + s = TIFFroundup_32(s, td->td_ycbcrsubsampling[1] * DCTSIZE); + return (s); +} + +static void JPEGDefaultTileSize(TIFF *tif, uint32_t *tw, uint32_t *th) { + JPEGState *sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; + + (*sp->otherSettings.deftparent)(tif, tw, th); + *tw = TIFFroundup_32(*tw, td->td_ycbcrsubsampling[0] * DCTSIZE); + *th = TIFFroundup_32(*th, td->td_ycbcrsubsampling[1] * DCTSIZE); } /* * The JPEG library initialized used to be done in TIFFInitJPEG(), but * now that we allow a TIFF file to be opened in update mode it is necessary * to have some way of deciding whether compression or decompression is - * desired other than looking at tif->tif_mode. We accomplish this by + * desired other than looking at tif->tif_mode. We accomplish this by * examining {TILE/STRIP}BYTECOUNTS to see if there is a non-zero entry. - * If so, we assume decompression is desired. + * If so, we assume decompression is desired. * * This is tricky, because TIFFInitJPEG() is called while the directory is * being read, and generally speaking the BYTECOUNTS tag won't have been read * at that point. So we try to defer jpeg library initialization till we * do have that tag ... basically any access that might require the compressor - * or decompressor that occurs after the reading of the directory. + * or decompressor that occurs after the reading of the directory. * * In an ideal world compressors or decompressors would be setup * at the point where a single tile or strip was accessed (for read or write) @@ -2429,175 +2374,163 @@ JPEGDefaultTileSize(TIFF* tif, uint32_t* tw, uint32_t* th) * NFW, Feb 3rd, 2003. */ -static int JPEGInitializeLibJPEG( TIFF * tif, int decompress ) -{ - JPEGState* sp = JState(tif); - - if(sp->cinfo_initialized) - { - if( !decompress && sp->cinfo.comm.is_decompressor ) - TIFFjpeg_destroy( sp ); - else if( decompress && !sp->cinfo.comm.is_decompressor ) - TIFFjpeg_destroy( sp ); - else - return 1; - - sp->cinfo_initialized = 0; - } - - /* - * Initialize libjpeg. - */ - if ( decompress ) { - if (!TIFFjpeg_create_decompress(sp)) - return (0); - } else { - if (!TIFFjpeg_create_compress(sp)) - return (0); +static int JPEGInitializeLibJPEG(TIFF *tif, int decompress) { + JPEGState *sp = JState(tif); + + if (sp->cinfo_initialized) { + if (!decompress && sp->cinfo.comm.is_decompressor) + TIFFjpeg_destroy(sp); + else if (decompress && !sp->cinfo.comm.is_decompressor) + TIFFjpeg_destroy(sp); + else + return 1; + + sp->cinfo_initialized = 0; + } + + /* + * Initialize libjpeg. + */ + if (decompress) { + if (!TIFFjpeg_create_decompress(sp)) + return (0); + } else { + if (!TIFFjpeg_create_compress(sp)) + return (0); #ifndef TIFF_JPEG_MAX_MEMORY_TO_USE #define TIFF_JPEG_MAX_MEMORY_TO_USE (10 * 1024 * 1024) #endif - /* libjpeg turbo 1.5.2 honours max_memory_to_use, but has no backing */ - /* store implementation, so better not set max_memory_to_use ourselves. */ - /* See https://github.com/libjpeg-turbo/libjpeg-turbo/issues/162 */ - if( sp->cinfo.c.mem->max_memory_to_use > 0 ) - { - /* This is to address bug related in ticket GDAL #1795. */ - if (getenv("JPEGMEM") == NULL) - { - /* Increase the max memory usable. This helps when creating files */ - /* with "big" tile, without using libjpeg temporary files. */ - /* For example a 512x512 tile with 3 bands */ - /* requires 1.5 MB which is above libjpeg 1MB default */ - if( sp->cinfo.c.mem->max_memory_to_use < TIFF_JPEG_MAX_MEMORY_TO_USE ) - sp->cinfo.c.mem->max_memory_to_use = TIFF_JPEG_MAX_MEMORY_TO_USE; - } - } + /* libjpeg turbo 1.5.2 honours max_memory_to_use, but has no backing */ + /* store implementation, so better not set max_memory_to_use ourselves. */ + /* See https://github.com/libjpeg-turbo/libjpeg-turbo/issues/162 */ + if (sp->cinfo.c.mem->max_memory_to_use > 0) { + /* This is to address bug related in ticket GDAL #1795. */ + if (getenv("JPEGMEM") == NULL) { + /* Increase the max memory usable. This helps when creating files */ + /* with "big" tile, without using libjpeg temporary files. */ + /* For example a 512x512 tile with 3 bands */ + /* requires 1.5 MB which is above libjpeg 1MB default */ + if (sp->cinfo.c.mem->max_memory_to_use < TIFF_JPEG_MAX_MEMORY_TO_USE) + sp->cinfo.c.mem->max_memory_to_use = TIFF_JPEG_MAX_MEMORY_TO_USE; + } } + } + + sp->cinfo_initialized = TRUE; + + return 1; +} + +/* Common to tif_jpeg.c and tif_jpeg_12.c */ +static void TIFFInitJPEGCommon(TIFF *tif) { + JPEGState *sp; + + sp = JState(tif); + sp->tif = tif; /* back link */ + + /* Default values for codec-specific fields */ + sp->otherSettings.jpegtables = NULL; + sp->otherSettings.jpegtables_length = 0; + sp->otherSettings.jpegquality = 75; /* Default IJG quality */ + sp->otherSettings.jpegcolormode = JPEGCOLORMODE_RAW; + sp->otherSettings.jpegtablesmode = JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF; + sp->otherSettings.ycbcrsampling_fetched = 0; + + tif->tif_tagmethods.vgetfield = JPEGVGetField; /* hook for codec tags */ + tif->tif_tagmethods.vsetfield = JPEGVSetField; /* hook for codec tags */ + tif->tif_tagmethods.printdir = JPEGPrintDir; /* hook for codec tags */ + + /* + * Install codec methods. + */ + tif->tif_fixuptags = JPEGFixupTags; + tif->tif_setupdecode = JPEGSetupDecode; + tif->tif_predecode = JPEGPreDecode; + tif->tif_decoderow = JPEGDecode; + tif->tif_decodestrip = JPEGDecode; + tif->tif_decodetile = JPEGDecode; + tif->tif_setupencode = JPEGSetupEncode; + tif->tif_preencode = JPEGPreEncode; + tif->tif_postencode = JPEGPostEncode; + tif->tif_encoderow = JPEGEncode; + tif->tif_encodestrip = JPEGEncode; + tif->tif_encodetile = JPEGEncode; + tif->tif_cleanup = JPEGCleanup; + + tif->tif_defstripsize = JPEGDefaultStripSize; + tif->tif_deftilesize = JPEGDefaultTileSize; + tif->tif_flags |= TIFF_NOBITREV; /* no bit reversal, please */ + sp->cinfo_initialized = FALSE; +} + +int TIFFInitJPEG(TIFF *tif, int scheme) { + JPEGState *sp; + + (void)scheme; + assert(scheme == COMPRESSION_JPEG); + + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, jpegFields, TIFFArrayCount(jpegFields))) { + TIFFErrorExt(tif->tif_clientdata, "TIFFInitJPEG", + "Merging JPEG codec-specific tags failed"); + return 0; + } - sp->cinfo_initialized = TRUE; - - return 1; -} + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8_t *)_TIFFmalloc(sizeof(JPEGState)); -int -TIFFInitJPEG(TIFF* tif, int scheme) -{ - JPEGState* sp; - - (void)scheme; - assert(scheme == COMPRESSION_JPEG); - - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, jpegFields, TIFFArrayCount(jpegFields))) { - TIFFErrorExt(tif->tif_clientdata, - "TIFFInitJPEG", - "Merging JPEG codec-specific tags failed"); - return 0; - } - - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8_t*) _TIFFmalloc(sizeof (JPEGState)); - - if (tif->tif_data == NULL) { - TIFFErrorExt(tif->tif_clientdata, - "TIFFInitJPEG", "No space for JPEG state block"); - return 0; - } - _TIFFmemset(tif->tif_data, 0, sizeof(JPEGState)); - - sp = JState(tif); - sp->tif = tif; /* back link */ - - /* - * Override parent get/set field methods. - */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = JPEGVGetField; /* hook for codec tags */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = JPEGVSetField; /* hook for codec tags */ - sp->printdir = tif->tif_tagmethods.printdir; - tif->tif_tagmethods.printdir = JPEGPrintDir; /* hook for codec tags */ - - /* Default values for codec-specific fields */ - sp->jpegtables = NULL; - sp->jpegtables_length = 0; - sp->jpegquality = 75; /* Default IJG quality */ - sp->jpegcolormode = JPEGCOLORMODE_RAW; - sp->jpegtablesmode = JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF; - sp->ycbcrsampling_fetched = 0; - - /* - * Install codec methods. - */ - tif->tif_fixuptags = JPEGFixupTags; - tif->tif_setupdecode = JPEGSetupDecode; - tif->tif_predecode = JPEGPreDecode; - tif->tif_decoderow = JPEGDecode; - tif->tif_decodestrip = JPEGDecode; - tif->tif_decodetile = JPEGDecode; - tif->tif_setupencode = JPEGSetupEncode; - tif->tif_preencode = JPEGPreEncode; - tif->tif_postencode = JPEGPostEncode; - tif->tif_encoderow = JPEGEncode; - tif->tif_encodestrip = JPEGEncode; - tif->tif_encodetile = JPEGEncode; - tif->tif_cleanup = JPEGCleanup; - sp->defsparent = tif->tif_defstripsize; - tif->tif_defstripsize = JPEGDefaultStripSize; - sp->deftparent = tif->tif_deftilesize; - tif->tif_deftilesize = JPEGDefaultTileSize; - tif->tif_flags |= TIFF_NOBITREV; /* no bit reversal, please */ - - sp->cinfo_initialized = FALSE; - - /* - ** Create a JPEGTables field if no directory has yet been created. - ** We do this just to ensure that sufficient space is reserved for - ** the JPEGTables field. It will be properly created the right - ** size later. - */ - if( tif->tif_diroff == 0 ) - { + if (tif->tif_data == NULL) { + TIFFErrorExt(tif->tif_clientdata, "TIFFInitJPEG", + "No space for JPEG state block"); + return 0; + } + _TIFFmemset(tif->tif_data, 0, sizeof(JPEGState)); + + sp = JState(tif); + /* + * Override parent get/set field methods. + */ + sp->otherSettings.vgetparent = tif->tif_tagmethods.vgetfield; + sp->otherSettings.vsetparent = tif->tif_tagmethods.vsetfield; + sp->otherSettings.printdir = tif->tif_tagmethods.printdir; + + sp->otherSettings.defsparent = tif->tif_defstripsize; + sp->otherSettings.deftparent = tif->tif_deftilesize; + + TIFFInitJPEGCommon(tif); + + /* + ** Create a JPEGTables field if no directory has yet been created. + ** We do this just to ensure that sufficient space is reserved for + ** the JPEGTables field. It will be properly created the right + ** size later. + */ + if (tif->tif_diroff == 0) { #define SIZE_OF_JPEGTABLES 2000 -/* -The following line assumes incorrectly that all JPEG-in-TIFF files will have -a JPEGTABLES tag generated and causes null-filled JPEGTABLES tags to be written -when the JPEG data is placed with TIFFWriteRawStrip. The field bit should be -set, anyway, later when actual JPEGTABLES header is generated, so removing it -here hopefully is harmless. - TIFFSetFieldBit(tif, FIELD_JPEGTABLES); -*/ - sp->jpegtables_length = SIZE_OF_JPEGTABLES; - sp->jpegtables = (void *) _TIFFmalloc(sp->jpegtables_length); - if (sp->jpegtables) - { - _TIFFmemset(sp->jpegtables, 0, SIZE_OF_JPEGTABLES); - } - else - { - TIFFErrorExt(tif->tif_clientdata, - "TIFFInitJPEG", - "Failed to allocate memory for JPEG tables"); - return 0; - } + /* + The following line assumes incorrectly that all JPEG-in-TIFF files will have + a JPEGTABLES tag generated and causes null-filled JPEGTABLES tags to be + written when the JPEG data is placed with TIFFWriteRawStrip. The field bit + should be set, anyway, later when actual JPEGTABLES header is generated, so + removing it here hopefully is harmless. TIFFSetFieldBit(tif, + FIELD_JPEGTABLES); + */ + sp->otherSettings.jpegtables_length = SIZE_OF_JPEGTABLES; + sp->otherSettings.jpegtables = + (void *)_TIFFmalloc(sp->otherSettings.jpegtables_length); + if (sp->otherSettings.jpegtables) { + _TIFFmemset(sp->otherSettings.jpegtables, 0, SIZE_OF_JPEGTABLES); + } else { + TIFFErrorExt(tif->tif_clientdata, "TIFFInitJPEG", + "Failed to allocate memory for JPEG tables"); + return 0; + } #undef SIZE_OF_JPEGTABLES - } - - return 1; + } + return 1; } #endif /* JPEG_SUPPORT */ - -/* vim: set ts=8 sts=8 sw=8 noet: */ - -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/src/3rdparty/libtiff/libtiff/tif_jpeg_12.c b/src/3rdparty/libtiff/libtiff/tif_jpeg_12.c index b458c25..bec5fb9 100644 --- a/src/3rdparty/libtiff/libtiff/tif_jpeg_12.c +++ b/src/3rdparty/libtiff/libtiff/tif_jpeg_12.c @@ -3,59 +3,52 @@ #if defined(JPEG_DUAL_MODE_8_12) -# define TIFFInitJPEG TIFFInitJPEG_12 -# define TIFFJPEGIsFullStripRequired TIFFJPEGIsFullStripRequired_12 - -int -TIFFInitJPEG_12(TIFF* tif, int scheme); - -# include LIBJPEG_12_PATH - -# include "tif_jpeg.c" - -int TIFFReInitJPEG_12( TIFF *tif, int scheme, int is_encode ) - -{ - JPEGState* sp; - - assert(scheme == COMPRESSION_JPEG); - - sp = JState(tif); - sp->tif = tif; /* back link */ - - /* - * Override parent get/set field methods. - */ - tif->tif_tagmethods.vgetfield = JPEGVGetField; /* hook for codec tags */ - tif->tif_tagmethods.vsetfield = JPEGVSetField; /* hook for codec tags */ - tif->tif_tagmethods.printdir = JPEGPrintDir; /* hook for codec tags */ - - /* - * Install codec methods. - */ - tif->tif_fixuptags = JPEGFixupTags; - tif->tif_setupdecode = JPEGSetupDecode; - tif->tif_predecode = JPEGPreDecode; - tif->tif_decoderow = JPEGDecode; - tif->tif_decodestrip = JPEGDecode; - tif->tif_decodetile = JPEGDecode; - tif->tif_setupencode = JPEGSetupEncode; - tif->tif_preencode = JPEGPreEncode; - tif->tif_postencode = JPEGPostEncode; - tif->tif_encoderow = JPEGEncode; - tif->tif_encodestrip = JPEGEncode; - tif->tif_encodetile = JPEGEncode; - tif->tif_cleanup = JPEGCleanup; - tif->tif_defstripsize = JPEGDefaultStripSize; - tif->tif_deftilesize = JPEGDefaultTileSize; - tif->tif_flags |= TIFF_NOBITREV; /* no bit reversal, please */ - - sp->cinfo_initialized = FALSE; - - if( is_encode ) - return JPEGSetupEncode(tif); - else - return JPEGSetupDecode(tif); +#define FROM_TIF_JPEG_12 + +#ifdef TIFFInitJPEG +#undef TIFFInitJPEG +#endif +#define TIFFInitJPEG TIFFInitJPEG_12 + +#ifdef TIFFJPEGIsFullStripRequired +#undef TIFFJPEGIsFullStripRequired +#endif +#define TIFFJPEGIsFullStripRequired TIFFJPEGIsFullStripRequired_12 + +int TIFFInitJPEG_12(TIFF *tif, int scheme); + +#include LIBJPEG_12_PATH + +#include "tif_jpeg.c" + +int TIFFReInitJPEG_12(TIFF *tif, const JPEGOtherSettings *otherSettings, + int scheme, int is_encode) { + JPEGState *sp; + uint8_t *new_tif_data; + + (void)scheme; + assert(scheme == COMPRESSION_JPEG); + + new_tif_data = (uint8_t *)_TIFFrealloc(tif->tif_data, sizeof(JPEGState)); + + if (new_tif_data == NULL) { + TIFFErrorExt(tif->tif_clientdata, "TIFFReInitJPEG_12", + "No space for JPEG state block"); + return 0; + } + + tif->tif_data = new_tif_data; + _TIFFmemset(tif->tif_data, 0, sizeof(JPEGState)); + + TIFFInitJPEGCommon(tif); + + sp = JState(tif); + sp->otherSettings = *otherSettings; + + if (is_encode) + return JPEGSetupEncode(tif); + else + return JPEGSetupDecode(tif); } #endif /* defined(JPEG_DUAL_MODE_8_12) */ diff --git a/src/3rdparty/libtiff/libtiff/tif_luv.c b/src/3rdparty/libtiff/libtiff/tif_luv.c index 13765ea..72ab366 100644 --- a/src/3rdparty/libtiff/libtiff/tif_luv.c +++ b/src/3rdparty/libtiff/libtiff/tif_luv.c @@ -579,7 +579,7 @@ LogLuvEncode32(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) uint32_t* tp; uint32_t b; tmsize_t occ; - int rc=0, mask; + int rc=0; tmsize_t beg; (void)s; @@ -603,6 +603,7 @@ LogLuvEncode32(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) op = tif->tif_rawcp; occ = tif->tif_rawdatasize - tif->tif_rawcc; for (shft = 24; shft >= 0; shft -=8) { + const uint32_t mask = 0xffU << shft; /* find next run */ for (i = 0; i < npixels; i += rc) { if (occ < 4) { tif->tif_rawcp = op; @@ -612,7 +613,6 @@ LogLuvEncode32(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) op = tif->tif_rawcp; occ = tif->tif_rawdatasize - tif->tif_rawcc; } - mask = 0xff << shft; /* find next run */ for (beg = i; beg < npixels; beg += rc) { b = tp[beg] & mask; rc = 1; @@ -804,7 +804,7 @@ L16fromY(LogLuvState* sp, uint8_t* op, tmsize_t n) static #endif void -XYZtoRGB24(float xyz[3], uint8_t rgb[3]) +XYZtoRGB24(float* xyz, uint8_t* rgb) { double r, g, b; /* assume CCIR-709 primaries */ @@ -958,7 +958,7 @@ uv_decode(double *up, double *vp, int c) /* decode (u',v') index */ static #endif void -LogLuv24toXYZ(uint32_t p, float XYZ[3]) +LogLuv24toXYZ(uint32_t p, float* XYZ) { int Ce; double L, u, v, s, x, y; @@ -986,7 +986,7 @@ LogLuv24toXYZ(uint32_t p, float XYZ[3]) static #endif uint32_t -LogLuv24fromXYZ(float XYZ[3], int em) +LogLuv24fromXYZ(float* XYZ, int em) { int Le, Ce; double u, v, s; @@ -1099,7 +1099,7 @@ Luv24fromLuv48(LogLuvState* sp, uint8_t* op, tmsize_t n) static #endif void -LogLuv32toXYZ(uint32_t p, float XYZ[3]) +LogLuv32toXYZ(uint32_t p, float* XYZ) { double L, u, v, s, x, y; /* decode luminance */ @@ -1124,7 +1124,7 @@ LogLuv32toXYZ(uint32_t p, float XYZ[3]) static #endif uint32_t -LogLuv32fromXYZ(float XYZ[3], int em) +LogLuv32fromXYZ(float* XYZ, int em) { unsigned int Le, ue, ve; double u, v, s; diff --git a/src/3rdparty/libtiff/libtiff/tif_lzw.c b/src/3rdparty/libtiff/libtiff/tif_lzw.c index c06aec4..096824d 100644 --- a/src/3rdparty/libtiff/libtiff/tif_lzw.c +++ b/src/3rdparty/libtiff/libtiff/tif_lzw.c @@ -1,31 +1,32 @@ /* * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * Copyright (c) 2022 Even Rouault * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include "tiffiop.h" #ifdef LZW_SUPPORT /* - * TIFF Library. + * TIFF Library. * Rev 5.0 Lempel-Ziv & Welch Compression Support * * This code is derived from the compress program whose code is @@ -36,8 +37,13 @@ */ #include "tif_predict.h" +#include <stdbool.h> #include <stdio.h> +/* Select the plausible largest natural integer type for the architecture */ +#define SIZEOF_WORDTYPE SIZEOF_SIZE_T +typedef size_t WordType; + /* * NB: The 5.0 spec describes a different algorithm than Aldus * implements. Specifically, Aldus does code length transitions @@ -52,13 +58,6 @@ * Future revisions to the TIFF spec are expected to "clarify this issue". */ #define LZW_COMPAT /* include backwards compatibility code */ -/* - * Each strip of data is supposed to be terminated by a CODE_EOI. - * If the following #define is included, the decoder will also - * check for end-of-strip w/o seeing this code. This makes the - * library more robust, but also slower. - */ -#define LZW_CHECKEOS /* include checks for strips w/o EOI code */ #define MAXCODE(n) ((1L<<(n))-1) /* @@ -92,7 +91,7 @@ typedef struct { unsigned short nbits; /* # of bits/code */ unsigned short maxcode; /* maximum code for lzw_nbits */ unsigned short free_ent; /* next free entry in hash table */ - unsigned long nextdata; /* next bits of i/o */ + WordType nextdata; /* next bits of i/o */ long nextbits; /* # of valid bits in lzw_nextdata */ int rw_mode; /* preserve rw_mode from init */ @@ -119,8 +118,10 @@ typedef struct { typedef struct code_ent { struct code_ent *next; unsigned short length; /* string len, including this token */ - unsigned char value; /* data value */ + /* firstchar should be placed immediately before value in this structure */ unsigned char firstchar; /* first token of string */ + unsigned char value; /* data value */ + bool repeated; } code_t; typedef int (*decodeFunc)(TIFF*, uint8_t*, tmsize_t, uint16_t); @@ -130,25 +131,24 @@ typedef struct { /* Decoding specific data */ long dec_nbitsmask; /* lzw_nbits 1 bits, right adjusted */ - long dec_restart; /* restart count */ -#ifdef LZW_CHECKEOS + tmsize_t dec_restart; /* restart count */ uint64_t dec_bitsleft; /* available bits in raw data */ tmsize_t old_tif_rawcc; /* value of tif_rawcc at the end of the previous TIFLZWDecode() call */ -#endif decodeFunc dec_decode; /* regular or backwards compatible */ code_t* dec_codep; /* current recognized code */ code_t* dec_oldcodep; /* previously recognized code */ code_t* dec_free_entp; /* next free entry */ code_t* dec_maxcodep; /* max available entry */ code_t* dec_codetab; /* kept separate for small machines */ + int read_error; /* whether a read error has occured, and which should cause further reads in the same strip/tile to be aborted */ /* Encoding specific data */ int enc_oldcode; /* last code encountered */ - long enc_checkpoint; /* point at which to clear table */ + tmsize_t enc_checkpoint; /* point at which to clear table */ #define CHECK_GAP 10000 /* enc_ratio check interval */ - long enc_ratio; /* current compression ratio */ - long enc_incount; /* (input) data bytes encoded */ - long enc_outcount; /* encoded (output) bytes */ + tmsize_t enc_ratio; /* current compression ratio */ + tmsize_t enc_incount; /* (input) data bytes encoded */ + tmsize_t enc_outcount; /* encoded (output) bytes */ uint8_t* enc_rawlimit; /* bound on tif_rawdata buffer */ hash_t* enc_hashtab; /* kept separate for small machines */ } LZWCodecState; @@ -167,26 +167,6 @@ static void cl_hash(LZWCodecState*); * LZW Decoder. */ -#ifdef LZW_CHECKEOS -/* - * This check shouldn't be necessary because each - * strip is suppose to be terminated with CODE_EOI. - */ -#define NextCode(_tif, _sp, _bp, _code, _get) { \ - if ((_sp)->dec_bitsleft < (uint64_t)nbits) { \ - TIFFWarningExt(_tif->tif_clientdata, module, \ - "LZWDecode: Strip %"PRIu32" not terminated with EOI code", \ - _tif->tif_curstrip); \ - _code = CODE_EOI; \ - } else { \ - _get(_sp,_bp,_code); \ - (_sp)->dec_bitsleft -= nbits; \ - } \ -} -#else -#define NextCode(tif, sp, bp, code, get) get(sp, bp, code) -#endif - static int LZWFixupTags(TIFF* tif) { @@ -236,17 +216,17 @@ LZWSetupDecode(TIFF* tif) */ code = 255; do { - sp->dec_codetab[code].value = (unsigned char)code; sp->dec_codetab[code].firstchar = (unsigned char)code; + sp->dec_codetab[code].value = (unsigned char)code; + sp->dec_codetab[code].repeated = true; sp->dec_codetab[code].length = 1; sp->dec_codetab[code].next = NULL; } while (code--); /* - * Zero-out the unused entries - */ - /* Silence false positive */ - /* coverity[overrun-buffer-arg] */ - _TIFFmemset(&sp->dec_codetab[CODE_CLEAR], 0, + * Zero-out the unused entries */ + /* Silence false positive */ + /* coverity[overrun-buffer-arg] */ + memset(&sp->dec_codetab[CODE_CLEAR], 0, (CODE_FIRST - CODE_CLEAR) * sizeof (code_t)); } return (1); @@ -316,11 +296,9 @@ LZWPreDecode(TIFF* tif, uint16_t s) sp->dec_restart = 0; sp->dec_nbitsmask = MAXCODE(BITS_MIN); -#ifdef LZW_CHECKEOS sp->dec_bitsleft = 0; - sp->old_tif_rawcc = 0; -#endif - sp->dec_free_entp = sp->dec_codetab + CODE_FIRST; + sp->old_tif_rawcc = 0; + sp->dec_free_entp = sp->dec_codetab - 1 ; // + CODE_FIRST; /* * Zero entries that are not yet filled in. We do * this to guard against bogus input data that causes @@ -328,65 +306,114 @@ LZWPreDecode(TIFF* tif, uint16_t s) * come up with a way to safely bounds-check input codes * while decoding then you can remove this operation. */ - _TIFFmemset(sp->dec_free_entp, 0, (CSIZE-CODE_FIRST)*sizeof (code_t)); - sp->dec_oldcodep = &sp->dec_codetab[-1]; + sp->dec_oldcodep = &sp->dec_codetab[0]; sp->dec_maxcodep = &sp->dec_codetab[sp->dec_nbitsmask-1]; + sp->read_error = 0; return (1); } /* * Decode a "hunk of data". */ -#define GetNextCode(sp, bp, code) { \ - nextdata = (nextdata<<8) | *(bp)++; \ - nextbits += 8; \ - if (nextbits < nbits) { \ - nextdata = (nextdata<<8) | *(bp)++; \ - nextbits += 8; \ - } \ - code = (hcode_t)((nextdata >> (nextbits-nbits)) & nbitsmask); \ - nextbits -= nbits; \ -} -static void -codeLoop(TIFF* tif, const char* module) -{ - TIFFErrorExt(tif->tif_clientdata, module, - "Bogus encoding, loop in the code table; scanline %"PRIu32, - tif->tif_row); -} +/* Get the next 32 or 64-bit from the input data */ +#ifdef WORDS_BIGENDIAN +# define GetNextData(nextdata, bp) memcpy(&nextdata, bp, sizeof(nextdata)) +#elif SIZEOF_WORDTYPE == 8 +# if defined(__GNUC__) && defined(__x86_64__) +# define GetNextData(nextdata, bp) nextdata = __builtin_bswap64(*(uint64_t*)(bp)) +# elif defined(_M_X64) +# define GetNextData(nextdata, bp) nextdata = _byteswap_uint64(*(uint64_t*)(bp)) +# elif defined(__GNUC__) +# define GetNextData(nextdata, bp) memcpy(&nextdata, bp, sizeof(nextdata)); \ + nextdata = __builtin_bswap64(nextdata) +# else +# define GetNextData(nextdata, bp) nextdata = (((uint64_t)bp[0]) << 56) | \ + (((uint64_t)bp[1]) << 48) | \ + (((uint64_t)bp[2]) << 40) | \ + (((uint64_t)bp[3]) << 32) | \ + (((uint64_t)bp[4]) << 24) | \ + (((uint64_t)bp[5]) << 16) | \ + (((uint64_t)bp[6]) << 8) | \ + (((uint64_t)bp[7])) +# endif +#elif SIZEOF_WORDTYPE == 4 +# if defined(__GNUC__) && defined(__i386__) +# define GetNextData(nextdata, bp) nextdata = __builtin_bswap32(*(uint32_t*)(bp)) +# elif defined(_M_X86) +# define GetNextData(nextdata, bp) nextdata = _byteswap_ulong(*(unsigned long*)(bp)) +# elif defined(__GNUC__) +# define GetNextData(nextdata, bp) memcpy(&nextdata, bp, sizeof(nextdata)); \ + nextdata = __builtin_bswap32(nextdata) +# else +# define GetNextData(nextdata, bp) nextdata = (((uint32_t)bp[0]) << 24) | \ + (((uint32_t)bp[1]) << 16) | \ + (((uint32_t)bp[2]) << 8) | \ + (((uint32_t)bp[3])) +# endif +#else +# error "Unhandled SIZEOF_WORDTYPE" +#endif + +#define GetNextCodeLZW() do { \ + nextbits -= nbits; \ + if (nextbits < 0) { \ + if (dec_bitsleft >= 8 * SIZEOF_WORDTYPE) { \ + unsigned codetmp = (unsigned)(nextdata << (-nextbits)); \ + GetNextData(nextdata, bp); \ + bp += SIZEOF_WORDTYPE; \ + nextbits += 8 * SIZEOF_WORDTYPE; \ + dec_bitsleft -= 8 * SIZEOF_WORDTYPE; \ + code = (WordType)((codetmp | (nextdata >> nextbits)) & nbitsmask); \ + break; \ + } \ + else {\ + if( dec_bitsleft < 8) { \ + goto no_eoi; \ + }\ + nextdata = (nextdata<<8) | *(bp)++; \ + nextbits += 8; \ + dec_bitsleft -= 8; \ + if( nextbits < 0 ) { \ + if( dec_bitsleft < 8) { \ + goto no_eoi; \ + }\ + nextdata = (nextdata<<8) | *(bp)++; \ + nextbits += 8; \ + dec_bitsleft -= 8; \ + } \ + } \ + } \ + code = (WordType)((nextdata >> nextbits) & nbitsmask); \ +} while(0) static int LZWDecode(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s) { static const char module[] = "LZWDecode"; LZWCodecState *sp = DecoderState(tif); - char *op = (char*) op0; - long occ = (long) occ0; - char *tp; - unsigned char *bp; - hcode_t code; - int len; + uint8_t *op = (uint8_t*) op0; + tmsize_t occ = occ0; + uint8_t *bp; long nbits, nextbits, nbitsmask; - unsigned long nextdata; - code_t *codep, *free_entp, *maxcodep, *oldcodep; + WordType nextdata; + code_t *free_entp, *maxcodep, *oldcodep; (void) s; assert(sp != NULL); - assert(sp->dec_codetab != NULL); + assert(sp->dec_codetab != NULL); + + if (sp->read_error) { + return 0; + } - /* - Fail if value does not fit in long. - */ - if ((tmsize_t) occ != occ0) - return (0); /* * Restart interrupted output operation. */ if (sp->dec_restart) { - long residue; + tmsize_t residue; - codep = sp->dec_codep; + code_t* codep = sp->dec_codep; residue = codep->length - sp->dec_restart; if (residue > occ) { /* @@ -400,7 +427,7 @@ LZWDecode(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s) codep = codep->next; } while (--residue > occ && codep); if (codep) { - tp = op + occ; + uint8_t* tp = op + occ; do { *--tp = codep->value; codep = codep->next; @@ -413,21 +440,17 @@ LZWDecode(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s) */ op += residue; occ -= residue; - tp = op; + uint8_t* tp = op; do { - int t; - --tp; - t = codep->value; + *--tp = codep->value; codep = codep->next; - *tp = (char)t; } while (--residue && codep); sp->dec_restart = 0; } - bp = (unsigned char *)tif->tif_rawcp; -#ifdef LZW_CHECKEOS + bp = (uint8_t*)tif->tif_rawcp; sp->dec_bitsleft += (((uint64_t)tif->tif_rawcc - sp->old_tif_rawcc) << 3); -#endif + uint64_t dec_bitsleft = sp->dec_bitsleft; nbits = sp->lzw_nbits; nextdata = sp->lzw_nextdata; nextbits = sp->lzw_nextbits; @@ -435,128 +458,236 @@ LZWDecode(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s) oldcodep = sp->dec_oldcodep; free_entp = sp->dec_free_entp; maxcodep = sp->dec_maxcodep; + code_t* const dec_codetab = sp->dec_codetab; + code_t* codep; + + if (occ == 0) { + goto after_loop; + } + +begin: + { + WordType code; + GetNextCodeLZW(); + codep = dec_codetab + code; + if (code >= CODE_FIRST) + goto code_above_or_equal_to_258; + if (code < 256) + goto code_below_256; + if (code == CODE_EOI) + goto after_loop; + goto code_clear; + +code_below_256: + { + if (codep > free_entp) + goto error_code; + free_entp->next = oldcodep; + free_entp->firstchar = oldcodep->firstchar; + free_entp->length = oldcodep->length+1; + free_entp->value = (uint8_t)code; + free_entp->repeated = (bool)(oldcodep->repeated & (oldcodep->value == code)); + if (++free_entp > maxcodep) { + if (++nbits > BITS_MAX) /* should not happen for a conformant encoder */ + nbits = BITS_MAX; + nbitsmask = MAXCODE(nbits); + maxcodep = dec_codetab + nbitsmask-1; + if( free_entp >= &dec_codetab[CSIZE] ) + { + /* At that point, the next valid states are either EOI or a */ + /* CODE_CLEAR. If a regular code is read, at the next */ + /* attempt at registering a new entry, we will error out */ + /* due to setting free_entp before any valid code */ + free_entp = dec_codetab - 1; + } + } + oldcodep = codep; + *op++ = (uint8_t)code; + occ--; + if (occ == 0) + goto after_loop; + goto begin; + } - while (occ > 0) { - NextCode(tif, sp, bp, code, GetNextCode); - if (code == CODE_EOI) - break; - if (code == CODE_CLEAR) { - do { - free_entp = sp->dec_codetab + CODE_FIRST; - _TIFFmemset(free_entp, 0, - (CSIZE - CODE_FIRST) * sizeof (code_t)); - nbits = BITS_MIN; - nbitsmask = MAXCODE(BITS_MIN); - maxcodep = sp->dec_codetab + nbitsmask-1; - NextCode(tif, sp, bp, code, GetNextCode); - } while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */ - if (code == CODE_EOI) - break; - if (code > CODE_CLEAR) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "LZWDecode: Corrupted LZW table at scanline %"PRIu32, - tif->tif_row); - return (0); - } - *op++ = (char)code; - occ--; - oldcodep = sp->dec_codetab + code; - continue; - } - codep = sp->dec_codetab + code; +code_above_or_equal_to_258: + { + /* + * Add the new entry to the code table. + */ + + if (codep >= free_entp) + { + if (codep != free_entp) + goto error_code; + free_entp->value = oldcodep->firstchar; + } + else + { + free_entp->value = codep->firstchar; + } + free_entp->repeated = (bool)(oldcodep->repeated & (oldcodep->value == free_entp->value)); + free_entp->next = oldcodep; + + free_entp->firstchar = oldcodep->firstchar; + free_entp->length = oldcodep->length+1; + if (++free_entp > maxcodep) { + if (++nbits > BITS_MAX) /* should not happen for a conformant encoder */ + nbits = BITS_MAX; + nbitsmask = MAXCODE(nbits); + maxcodep = dec_codetab + nbitsmask-1; + if (free_entp >= &dec_codetab[CSIZE]) + { + /* At that point, the next valid states are either EOI or a */ + /* CODE_CLEAR. If a regular code is read, at the next */ + /* attempt at registering a new entry, we will error out */ + /* due to setting free_entp before any valid code */ + free_entp = dec_codetab - 1; + } + } + oldcodep = codep; + + /* + * Code maps to a string, copy string + * value to output (written in reverse). + */ + /* tiny bit faster on x86_64 to store in unsigned short than int */ + unsigned short len = codep->length; + + if (len < 3) /* equivalent to len == 2 given all other conditions */ + { + if (occ <= 2) + { + if (occ == 2) + { + memcpy(op, &(codep->firstchar), 2); + op += 2; + occ -= 2; + goto after_loop; + } + goto too_short_buffer; + } - /* - * Add the new entry to the code table. - */ - if (free_entp < &sp->dec_codetab[0] || - free_entp >= &sp->dec_codetab[CSIZE]) { - TIFFErrorExt(tif->tif_clientdata, module, - "Corrupted LZW table at scanline %"PRIu32, - tif->tif_row); - return (0); - } + memcpy(op, &(codep->firstchar), 2); + op += 2; + occ -= 2; + goto begin; /* we can save the comparison occ > 0 */ + } + + if (len == 3) + { + if (occ <= 3) + { + if (occ == 3) + { + op[0] = codep->firstchar; + op[1] = codep->next->value; + op[2] = codep->value; + op += 3; + occ -= 3; + goto after_loop; + } + goto too_short_buffer; + } - free_entp->next = oldcodep; - if (free_entp->next < &sp->dec_codetab[0] || - free_entp->next >= &sp->dec_codetab[CSIZE]) { - TIFFErrorExt(tif->tif_clientdata, module, - "Corrupted LZW table at scanline %"PRIu32, - tif->tif_row); - return (0); - } - free_entp->firstchar = free_entp->next->firstchar; - free_entp->length = free_entp->next->length+1; - free_entp->value = (codep < free_entp) ? - codep->firstchar : free_entp->firstchar; - if (++free_entp > maxcodep) { - if (++nbits > BITS_MAX) /* should not happen */ - nbits = BITS_MAX; - nbitsmask = MAXCODE(nbits); - maxcodep = sp->dec_codetab + nbitsmask-1; - } - oldcodep = codep; - if (code >= 256) { - /* - * Code maps to a string, copy string - * value to output (written in reverse). - */ - if(codep->length == 0) { - TIFFErrorExt(tif->tif_clientdata, module, - "Wrong length of decoded string: " - "data probably corrupted at scanline %"PRIu32, - tif->tif_row); - return (0); - } - if (codep->length > occ) { - /* - * String is too long for decode buffer, - * locate portion that will fit, copy to - * the decode buffer, and setup restart - * logic for the next decoding call. - */ - sp->dec_codep = codep; - do { - codep = codep->next; - } while (codep && codep->length > occ); - if (codep) { - sp->dec_restart = (long)occ; - tp = op + occ; - do { - *--tp = codep->value; - codep = codep->next; - } while (--occ && codep); - if (codep) - codeLoop(tif, module); - } - break; - } - len = codep->length; - tp = op + len; - do { - int t; - --tp; - t = codep->value; - codep = codep->next; - *tp = (char)t; - } while (codep && tp > op); - if (codep) { - codeLoop(tif, module); - break; - } - assert(occ >= len); - op += len; - occ -= len; - } else { - *op++ = (char)code; - occ--; - } - } + op[0] = codep->firstchar; + op[1] = codep->next->value; + op[2] = codep->value; + op += 3; + occ -= 3; + goto begin; /* we can save the comparison occ > 0 */ + } + + if (len > occ) + { + goto too_short_buffer; + } + + if (codep->repeated) + { + memset(op, codep->value, len); + op += len; + occ -= len; + if (occ == 0) + goto after_loop; + goto begin; + } + + uint8_t* tp = op + len; + + assert(len >= 4); + + *--tp = codep->value; + codep = codep->next; + *--tp = codep->value; + codep = codep->next; + *--tp = codep->value; + codep = codep->next; + *--tp = codep->value; + if (tp > op) + { + do { + codep = codep->next; + *--tp = codep->value; + } while (tp > op); + } + + assert(occ >= len); + op += len; + occ -= len; + if (occ == 0) + goto after_loop; + goto begin; + } +code_clear: + { + free_entp = dec_codetab + CODE_FIRST; + nbits = BITS_MIN; + nbitsmask = MAXCODE(BITS_MIN); + maxcodep = dec_codetab + nbitsmask-1; + do { + GetNextCodeLZW(); + } while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */ + if (code == CODE_EOI) + goto after_loop; + if (code > CODE_EOI) { + goto error_code; + } + *op++ = (uint8_t)code; + occ--; + oldcodep = dec_codetab + code; + if (occ == 0) + goto after_loop; + goto begin; + } + } + +too_short_buffer: + { + /* + * String is too long for decode buffer, + * locate portion that will fit, copy to + * the decode buffer, and setup restart + * logic for the next decoding call. + */ + sp->dec_codep = codep; + do { + codep = codep->next; + } while (codep->length > occ); + + sp->dec_restart = occ; + uint8_t* tp = op + occ; + do { + *--tp = codep->value; + codep = codep->next; + } while (--occ); + } + +after_loop: tif->tif_rawcc -= (tmsize_t)((uint8_t*) bp - tif->tif_rawcp ); tif->tif_rawcp = (uint8_t*) bp; -#ifdef LZW_CHECKEOS sp->old_tif_rawcc = tif->tif_rawcc; -#endif + sp->dec_bitsleft = dec_bitsleft; sp->lzw_nbits = (unsigned short) nbits; sp->lzw_nextdata = nextdata; sp->lzw_nextbits = nextbits; @@ -567,14 +698,41 @@ LZWDecode(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s) if (occ > 0) { TIFFErrorExt(tif->tif_clientdata, module, - "Not enough data at scanline %"PRIu32" (short %ld bytes)", - tif->tif_row, occ); + "Not enough data at scanline %"PRIu32" (short %"PRIu64" bytes)", + tif->tif_row, (uint64_t)occ); return (0); } return (1); + +no_eoi: + TIFFErrorExt(tif->tif_clientdata, module, + "LZWDecode: Strip %"PRIu32" not terminated with EOI code", + tif->tif_curstrip); + return 0; +error_code: + sp->read_error = 1; + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Using code not yet in table"); + return 0; } #ifdef LZW_COMPAT + +/* + * This check shouldn't be necessary because each + * strip is suppose to be terminated with CODE_EOI. + */ +#define NextCode(_tif, _sp, _bp, _code, _get, dec_bitsleft) { \ + if (dec_bitsleft < (uint64_t)nbits) { \ + TIFFWarningExt(_tif->tif_clientdata, module, \ + "LZWDecode: Strip %"PRIu32" not terminated with EOI code", \ + _tif->tif_curstrip); \ + _code = CODE_EOI; \ + } else { \ + _get(_sp,_bp,_code); \ + dec_bitsleft -= nbits; \ + } \ +} + /* * Decode a "hunk of data" for old images. */ @@ -595,29 +753,24 @@ LZWDecodeCompat(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s) { static const char module[] = "LZWDecodeCompat"; LZWCodecState *sp = DecoderState(tif); - char *op = (char*) op0; - long occ = (long) occ0; - char *tp; - unsigned char *bp; + uint8_t *op = (uint8_t*) op0; + tmsize_t occ = occ0; + uint8_t *tp; + uint8_t *bp; int code, nbits; int len; - long nextbits, nextdata, nbitsmask; + long nextbits, nbitsmask; + WordType nextdata; code_t *codep, *free_entp, *maxcodep, *oldcodep; (void) s; assert(sp != NULL); /* - Fail if value does not fit in long. - */ - if ((tmsize_t) occ != occ0) - return (0); - - /* * Restart interrupted output operation. */ if (sp->dec_restart) { - long residue; + tmsize_t residue; codep = sp->dec_codep; residue = codep->length - sp->dec_restart; @@ -652,10 +805,11 @@ LZWDecodeCompat(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s) sp->dec_restart = 0; } - bp = (unsigned char *)tif->tif_rawcp; -#ifdef LZW_CHECKEOS + bp = (uint8_t*)tif->tif_rawcp; + sp->dec_bitsleft += (((uint64_t)tif->tif_rawcc - sp->old_tif_rawcc) << 3); -#endif + uint64_t dec_bitsleft = sp->dec_bitsleft; + nbits = sp->lzw_nbits; nextdata = sp->lzw_nextdata; nextbits = sp->lzw_nextbits; @@ -665,7 +819,7 @@ LZWDecodeCompat(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s) maxcodep = sp->dec_maxcodep; while (occ > 0) { - NextCode(tif, sp, bp, code, GetNextCodeCompat); + NextCode(tif, sp, bp, code, GetNextCodeCompat, dec_bitsleft); if (code == CODE_EOI) break; if (code == CODE_CLEAR) { @@ -676,7 +830,7 @@ LZWDecodeCompat(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s) nbits = BITS_MIN; nbitsmask = MAXCODE(BITS_MIN); maxcodep = sp->dec_codetab + nbitsmask; - NextCode(tif, sp, bp, code, GetNextCodeCompat); + NextCode(tif, sp, bp, code, GetNextCodeCompat, dec_bitsleft); } while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */ if (code == CODE_EOI) break; @@ -686,7 +840,7 @@ LZWDecodeCompat(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s) tif->tif_row); return (0); } - *op++ = (char)code; + *op++ = (uint8_t)code; occ--; oldcodep = sp->dec_codetab + code; continue; @@ -755,26 +909,24 @@ LZWDecodeCompat(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s) len = codep->length; tp = op + len; do { - int t; - --tp; - t = codep->value; + *--tp = codep->value; codep = codep->next; - *tp = (char)t; } while (codep && tp > op); assert(occ >= len); op += len; occ -= len; } else { - *op++ = (char)code; + *op++ = (uint8_t)code; occ--; } } tif->tif_rawcc -= (tmsize_t)((uint8_t*) bp - tif->tif_rawcp ); tif->tif_rawcp = (uint8_t*) bp; -#ifdef LZW_CHECKEOS + sp->old_tif_rawcc = tif->tif_rawcc; -#endif + sp->dec_bitsleft = dec_bitsleft; + sp->lzw_nbits = (unsigned short)nbits; sp->lzw_nextdata = nextdata; sp->lzw_nextbits = nextbits; @@ -785,8 +937,8 @@ LZWDecodeCompat(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s) if (occ > 0) { TIFFErrorExt(tif->tif_clientdata, module, - "Not enough data at scanline %"PRIu32" (short %ld bytes)", - tif->tif_row, occ); + "Not enough data at scanline %"PRIu32" (short %"PRIu64" bytes)", + tif->tif_row, (uint64_t)occ); return (0); } return (1); @@ -872,16 +1024,16 @@ LZWPreEncode(TIFF* tif, uint16_t s) /* * Encode a chunk of pixels. * - * Uses an open addressing double hashing (no chaining) on the + * Uses an open addressing double hashing (no chaining) on the * prefix code/next character combination. We do a variant of * Knuth's algorithm D (vol. 3, sec. 6.4) along with G. Knott's * relatively-prime secondary probe. Here, the modular division - * first probe is gives way to a faster exclusive-or manipulation. + * first probe is gives way to a faster exclusive-or manipulation. * Also do block compression with an adaptive reset, whereby the * code table is cleared when the compression ratio decreases, * but after the table fills. The variable-length output codes * are re-sized at this point, and a CODE_CLEAR is generated - * for the decoder. + * for the decoder. */ static int LZWEncode(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) @@ -892,8 +1044,8 @@ LZWEncode(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) register int h, c; hcode_t ent; long disp; - long incount, outcount, checkpoint; - unsigned long nextdata; + tmsize_t incount, outcount, checkpoint; + WordType nextdata; long nextbits; int free_ent, maxcode, nbits; uint8_t* op; @@ -1005,7 +1157,7 @@ LZWEncode(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) assert(nbits <= BITS_MAX); maxcode = (int) MAXCODE(nbits); } else if (incount >= checkpoint) { - long rat; + tmsize_t rat; /* * Check compression ratio and, if things seem * to be slipping, clear the hash table and @@ -1057,8 +1209,8 @@ LZWPostEncode(TIFF* tif) register LZWCodecState *sp = EncoderState(tif); uint8_t* op = tif->tif_rawcp; long nextbits = sp->lzw_nextbits; - unsigned long nextdata = sp->lzw_nextdata; - long outcount = sp->enc_outcount; + WordType nextdata = sp->lzw_nextdata; + tmsize_t outcount = sp->enc_outcount; int nbits = sp->lzw_nbits; if (op > sp->enc_rawlimit) { @@ -1092,9 +1244,10 @@ LZWPostEncode(TIFF* tif) } PutNextCode(op, CODE_EOI); /* Explicit 0xff masking to make icc -check=conversions happy */ - if (nextbits > 0) + if (nextbits > 0) *op++ = (unsigned char)((nextdata << (8-nextbits))&0xff); tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); + (void)outcount; return (1); } @@ -1162,7 +1315,7 @@ TIFFInitLZW(TIFF* tif, int scheme) /* * Install codec methods. */ - tif->tif_fixuptags = LZWFixupTags; + tif->tif_fixuptags = LZWFixupTags; tif->tif_setupdecode = LZWSetupDecode; tif->tif_predecode = LZWPreDecode; tif->tif_decoderow = LZWDecode; @@ -1181,7 +1334,7 @@ TIFFInitLZW(TIFF* tif, int scheme) (void) TIFFPredictorInit(tif); return (1); bad: - TIFFErrorExt(tif->tif_clientdata, module, + TIFFErrorExt(tif->tif_clientdata, module, "No space for LZW state block"); return (0); } diff --git a/src/3rdparty/libtiff/libtiff/tif_ojpeg.c b/src/3rdparty/libtiff/libtiff/tif_ojpeg.c index 66cd275..d682395 100644 --- a/src/3rdparty/libtiff/libtiff/tif_ojpeg.c +++ b/src/3rdparty/libtiff/libtiff/tif_ojpeg.c @@ -795,6 +795,17 @@ OJPEGDecode(TIFF* tif, uint8_t* buf, tmsize_t cc, uint16_t s) TIFFErrorExt(tif->tif_clientdata,module,"Cannot decode: decoder not correctly initialized"); return 0; } + if( sp->libjpeg_session_active == 0 ) + { + /* This should normally not happen, except that it does when */ + /* using TIFFReadScanline() which calls OJPEGPostDecode() for */ + /* each scanline, which assumes that a whole strile was read */ + /* and may thus incorrectly consider it has read the whole image, causing */ + /* OJPEGLibjpegSessionAbort() to be called prematurely. */ + /* Triggered by https://gitlab.com/libtiff/libtiff/-/issues/337 */ + TIFFErrorExt(tif->tif_clientdata,module,"Cannot decode: libjpeg_session_active == 0"); + return 0; + } if( sp->error_in_raw_data_decoding ) { return 0; @@ -901,6 +912,13 @@ OJPEGPostDecode(TIFF* tif, uint8_t* buf, tmsize_t cc) OJPEGState* sp=(OJPEGState*)tif->tif_data; (void)buf; (void)cc; + /* This function somehow incorrectly assumes that a whole strile was read, */ + /* which is not true when TIFFReadScanline() is called, */ + /* and may thus incorrectly consider it has read the whole image, causing */ + /* OJPEGLibjpegSessionAbort() to be called prematurely. */ + /* So this logic should be fixed to take into account cc, or disable */ + /* the scan line reading interface. */ + /* Triggered by https://gitlab.com/libtiff/libtiff/-/issues/337 */ sp->write_curstrile++; if (sp->write_curstrile%tif->tif_dir.td_stripsperimage==0) { diff --git a/src/3rdparty/libtiff/libtiff/tif_open.c b/src/3rdparty/libtiff/libtiff/tif_open.c index 9724162..549f56c 100644 --- a/src/3rdparty/libtiff/libtiff/tif_open.c +++ b/src/3rdparty/libtiff/libtiff/tif_open.c @@ -96,7 +96,6 @@ TIFFClientOpen( assert(sizeof(int32_t) == 4); assert(sizeof(uint64_t) == 8); assert(sizeof(int64_t) == 8); - assert(sizeof(tmsize_t)==sizeof(void*)); { union{ uint8_t a8[2]; @@ -354,6 +353,7 @@ TIFFClientOpen( if (!TIFFDefaultDirectory(tif)) goto bad; tif->tif_diroff = 0; + tif->tif_lastdiroff = 0; tif->tif_dirlist = NULL; tif->tif_dirlistsize = 0; tif->tif_dirnumber = 0; @@ -481,8 +481,6 @@ TIFFClientOpen( * Setup initial directory. */ if (TIFFReadDirectory(tif)) { - tif->tif_rawcc = (tmsize_t)-1; - tif->tif_flags |= TIFF_BUFFERSETUP; return (tif); } break; @@ -670,6 +668,15 @@ TIFFIsBigEndian(TIFF* tif) } /* + * Return nonzero if given file is BigTIFF style. + */ +int +TIFFIsBigTIFF(TIFF *tif) +{ + return (tif->tif_header.common.tiff_version == TIFF_VERSION_BIG); +} + +/* * Return pointer to file read method. */ TIFFReadWriteProc diff --git a/src/3rdparty/libtiff/libtiff/tif_packbits.c b/src/3rdparty/libtiff/libtiff/tif_packbits.c index 76569ad..b456863 100644 --- a/src/3rdparty/libtiff/libtiff/tif_packbits.c +++ b/src/3rdparty/libtiff/libtiff/tif_packbits.c @@ -214,23 +214,17 @@ static int PackBitsDecode(TIFF* tif, uint8_t* op, tmsize_t occ, uint16_t s) { static const char module[] = "PackBitsDecode"; - char *bp; + int8_t *bp; tmsize_t cc; long n; int b; (void) s; - bp = (char*) tif->tif_rawcp; + bp = (int8_t*) tif->tif_rawcp; cc = tif->tif_rawcc; while (cc > 0 && occ > 0) { n = (long) *bp++; cc--; - /* - * Watch out for compilers that - * don't sign extend chars... - */ - if (n >= 128) - n -= 256; if (n < 0) { /* replicate next byte -n+1 times */ if (n == -128) /* nop */ continue; diff --git a/src/3rdparty/libtiff/libtiff/tif_predict.c b/src/3rdparty/libtiff/libtiff/tif_predict.c index 4aa4af6..ffe7133 100644 --- a/src/3rdparty/libtiff/libtiff/tif_predict.c +++ b/src/3rdparty/libtiff/libtiff/tif_predict.c @@ -35,13 +35,17 @@ static int horAcc8(TIFF* tif, uint8_t* cp0, tmsize_t cc); static int horAcc16(TIFF* tif, uint8_t* cp0, tmsize_t cc); static int horAcc32(TIFF* tif, uint8_t* cp0, tmsize_t cc); +static int horAcc64(TIFF* tif, uint8_t* cp0, tmsize_t cc); static int swabHorAcc16(TIFF* tif, uint8_t* cp0, tmsize_t cc); static int swabHorAcc32(TIFF* tif, uint8_t* cp0, tmsize_t cc); +static int swabHorAcc64(TIFF* tif, uint8_t* cp0, tmsize_t cc); static int horDiff8(TIFF* tif, uint8_t* cp0, tmsize_t cc); static int horDiff16(TIFF* tif, uint8_t* cp0, tmsize_t cc); static int horDiff32(TIFF* tif, uint8_t* cp0, tmsize_t cc); +static int horDiff64(TIFF* tif, uint8_t* cp0, tmsize_t cc); static int swabHorDiff16(TIFF* tif, uint8_t* cp0, tmsize_t cc); static int swabHorDiff32(TIFF* tif, uint8_t* cp0, tmsize_t cc); +static int swabHorDiff64(TIFF* tif, uint8_t* cp0, tmsize_t cc); static int fpAcc(TIFF* tif, uint8_t* cp0, tmsize_t cc); static int fpDiff(TIFF* tif, uint8_t* cp0, tmsize_t cc); static int PredictorDecodeRow(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s); @@ -64,7 +68,8 @@ PredictorSetup(TIFF* tif) case PREDICTOR_HORIZONTAL: if (td->td_bitspersample != 8 && td->td_bitspersample != 16 - && td->td_bitspersample != 32) { + && td->td_bitspersample != 32 + && td->td_bitspersample != 64) { TIFFErrorExt(tif->tif_clientdata, module, "Horizontal differencing \"Predictor\" not supported with %"PRIu16"-bit samples", td->td_bitspersample); @@ -126,6 +131,7 @@ PredictorSetupDecode(TIFF* tif) case 8: sp->decodepfunc = horAcc8; break; case 16: sp->decodepfunc = horAcc16; break; case 32: sp->decodepfunc = horAcc32; break; + case 64: sp->decodepfunc = horAcc64; break; } /* * Override default decoding method with one that does the @@ -155,6 +161,9 @@ PredictorSetupDecode(TIFF* tif) } else if (sp->decodepfunc == horAcc32) { sp->decodepfunc = swabHorAcc32; tif->tif_postdecode = _TIFFNoPostDecode; + } else if (sp->decodepfunc == horAcc64) { + sp->decodepfunc = swabHorAcc64; + tif->tif_postdecode = _TIFFNoPostDecode; } } } @@ -205,6 +214,7 @@ PredictorSetupEncode(TIFF* tif) case 8: sp->encodepfunc = horDiff8; break; case 16: sp->encodepfunc = horDiff16; break; case 32: sp->encodepfunc = horDiff32; break; + case 64: sp->encodepfunc = horDiff64; break; } /* * Override default encoding method with one that does the @@ -234,6 +244,9 @@ PredictorSetupEncode(TIFF* tif) } else if (sp->encodepfunc == horDiff32) { sp->encodepfunc = swabHorDiff32; tif->tif_postdecode = _TIFFNoPostDecode; + } else if (sp->encodepfunc == horDiff64) { + sp->encodepfunc = swabHorDiff64; + tif->tif_postdecode = _TIFFNoPostDecode; } } } @@ -403,6 +416,41 @@ horAcc32(TIFF* tif, uint8_t* cp0, tmsize_t cc) return 1; } +static int +swabHorAcc64(TIFF* tif, uint8_t* cp0, tmsize_t cc) +{ + uint64_t* wp = (uint64_t*) cp0; + tmsize_t wc = cc / 8; + + TIFFSwabArrayOfLong8(wp, wc); + return horAcc64(tif, cp0, cc); +} + +TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW +static int +horAcc64(TIFF* tif, uint8_t* cp0, tmsize_t cc) +{ + tmsize_t stride = PredictorState(tif)->stride; + uint64_t* wp = (uint64_t*) cp0; + tmsize_t wc = cc / 8; + + if ((cc % (8 * stride)) != 0) + { + TIFFErrorExt(tif->tif_clientdata, "horAcc64", + "%s", "cc%(8*stride))!=0"); + return 0; + } + + if (wc > stride) { + wc -= stride; + do { + REPEAT4(stride, wp[stride] += wp[0]; wp++) + wc -= stride; + } while (wc > 0); + } + return 1; +} + /* * Floating point predictor accumulation routine. */ @@ -638,6 +686,46 @@ swabHorDiff32(TIFF* tif, uint8_t* cp0, tmsize_t cc) return 1; } +TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW +static int +horDiff64(TIFF* tif, uint8_t* cp0, tmsize_t cc) +{ + TIFFPredictorState* sp = PredictorState(tif); + tmsize_t stride = sp->stride; + uint64_t *wp = (uint64_t*) cp0; + tmsize_t wc = cc/8; + + if ((cc % (8 * stride)) != 0) + { + TIFFErrorExt(tif->tif_clientdata, "horDiff64", + "%s", "(cc%(8*stride))!=0"); + return 0; + } + + if (wc > stride) { + wc -= stride; + wp += wc - 1; + do { + REPEAT4(stride, wp[stride] -= wp[0]; wp--) + wc -= stride; + } while (wc > 0); + } + return 1; +} + +static int +swabHorDiff64(TIFF* tif, uint8_t* cp0, tmsize_t cc) +{ + uint64_t* wp = (uint64_t*) cp0; + tmsize_t wc = cc / 8; + + if (!horDiff64(tif, cp0, cc)) + return 0; + + TIFFSwabArrayOfLong8(wp, wc); + return 1; +} + /* * Floating point predictor differencing routine. */ diff --git a/src/3rdparty/libtiff/libtiff/tif_print.c b/src/3rdparty/libtiff/libtiff/tif_print.c index 347dbda..80a9d90 100644 --- a/src/3rdparty/libtiff/libtiff/tif_print.c +++ b/src/3rdparty/libtiff/libtiff/tif_print.c @@ -63,13 +63,33 @@ static const char * const orientNames[] = { }; #define NORIENTNAMES (sizeof (orientNames) / sizeof (orientNames[0])) +static const struct tagname { + uint16_t tag; + const char* name; +} tagnames[] = { + { TIFFTAG_GDAL_METADATA, "GDAL Metadata" }, + { TIFFTAG_GDAL_NODATA, "GDAL NoDataValue" }, +}; +#define NTAGS (sizeof (tagnames) / sizeof (tagnames[0])) + static void _TIFFPrintField(FILE* fd, const TIFFField *fip, uint32_t value_count, void *raw_data) { uint32_t j; - - fprintf(fd, " %s: ", fip->field_name); + + /* Print a user-friendly name for tags of relatively common use, but */ + /* which aren't registered by libtiff itself. */ + const char* field_name = fip->field_name; + if( TIFFFieldIsAnonymous(fip) ) { + for( size_t i = 0; i < NTAGS; ++i ) { + if( fip->field_tag == tagnames[i].tag ) { + field_name = tagnames[i].name; + break; + } + } + } + fprintf(fd, " %s: ", field_name); for(j = 0; j < value_count; j++) { if(fip->field_type == TIFF_BYTE) @@ -88,18 +108,22 @@ _TIFFPrintField(FILE* fd, const TIFFField *fip, fprintf(fd, "%"PRId32, ((int32_t *) raw_data)[j]); else if(fip->field_type == TIFF_IFD) fprintf(fd, "0x%"PRIx32, ((uint32_t *) raw_data)[j]); - else if(fip->field_type == TIFF_RATIONAL - || fip->field_type == TIFF_SRATIONAL - || fip->field_type == TIFF_FLOAT) - fprintf(fd, "%f", ((float *) raw_data)[j]); + else if (fip->field_type == TIFF_RATIONAL + || fip->field_type == TIFF_SRATIONAL) { + int tv_size = TIFFFieldSetGetSize(fip); + if(tv_size==8) + fprintf(fd, "%lf", ((double*)raw_data)[j]); + else + fprintf(fd, "%f", ((float *) raw_data)[j]); + } + else if(fip->field_type == TIFF_FLOAT) + fprintf(fd, "%f", ((float*)raw_data)[j]); else if(fip->field_type == TIFF_LONG8) fprintf(fd, "%"PRIu64, ((uint64_t *) raw_data)[j]); else if(fip->field_type == TIFF_SLONG8) fprintf(fd, "%"PRId64, ((int64_t *) raw_data)[j]); else if(fip->field_type == TIFF_IFD8) fprintf(fd, "0x%"PRIx64, ((uint64_t *) raw_data)[j]); - else if(fip->field_type == TIFF_FLOAT) - fprintf(fd, "%f", ((float *)raw_data)[j]); else if(fip->field_type == TIFF_DOUBLE) fprintf(fd, "%lf", ((double *) raw_data)[j]); else if(fip->field_type == TIFF_ASCII) { @@ -125,7 +149,7 @@ _TIFFPrettyPrintField(TIFF* tif, const TIFFField *fip, FILE* fd, uint32_t tag, (void) tif; /* do not try to pretty print auto-defined fields */ - if (strncmp(fip->field_name,"Tag ", 4) == 0) { + if ( TIFFFieldIsAnonymous(fip) ) { return 0; } @@ -218,7 +242,7 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags) char *sep; long l, n; - fprintf(fd, "TIFF Directory at offset 0x%"PRIu64" (%"PRIx64")\n", + fprintf(fd, "TIFF Directory at offset 0x%"PRIx64" (%"PRIu64")\n", tif->tif_diroff, tif->tif_diroff); if (TIFFFieldSet(tif,FIELD_SUBFILETYPE)) { @@ -549,7 +573,8 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags) const TIFFField *fip; uint32_t value_count; int mem_alloc = 0; - void *raw_data; + void *raw_data = NULL; + uint16_t dotrange[2]; /* must be kept in that scope and not moved in the below TIFFTAG_DOTRANGE specific case */ fip = TIFFFieldWithTag(tif, tag); if(fip == NULL) @@ -583,7 +608,6 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags) handled this way ... likely best if we move it into the directory structure with an explicit field in libtiff 4.1 and assign it a FIELD_ value */ - static uint16_t dotrange[2]; raw_data = dotrange; TIFFGetField(tif, tag, dotrange+0, dotrange+1); } else if (fip->field_type == TIFF_ASCII @@ -594,8 +618,10 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags) if(TIFFGetField(tif, tag, &raw_data) != 1) continue; } else { + /*--: Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size. */ + int tv_size = TIFFFieldSetGetSize(fip); raw_data = _TIFFmalloc( - _TIFFDataSize(fip->field_type) + tv_size * value_count); mem_alloc = 1; if(TIFFGetField(tif, tag, raw_data) != 1) { @@ -611,7 +637,7 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags) * _TIFFPrettyPrintField() fall down and print it as * any other tag. */ - if (!_TIFFPrettyPrintField(tif, fip, fd, tag, value_count, raw_data)) + if (raw_data != NULL && !_TIFFPrettyPrintField(tif, fip, fd, tag, value_count, raw_data)) _TIFFPrintField(fd, fip, value_count, raw_data); if(mem_alloc) diff --git a/src/3rdparty/libtiff/libtiff/tif_read.c b/src/3rdparty/libtiff/libtiff/tif_read.c index a4c60b4..66f2e40 100644 --- a/src/3rdparty/libtiff/libtiff/tif_read.c +++ b/src/3rdparty/libtiff/libtiff/tif_read.c @@ -751,15 +751,12 @@ TIFFFillStrip(TIFF* tif, uint32_t strip) (bytecount - 4096) / 10 > (uint64_t)stripsize ) { uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096; - if( newbytecount == 0 || newbytecount > (uint64_t)TIFF_INT64_MAX ) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Too large strip byte count %"PRIu64", strip %"PRIu32". Limiting to %"PRIu64, - bytecount, - strip, - newbytecount); - bytecount = newbytecount; - } + TIFFErrorExt(tif->tif_clientdata, module, + "Too large strip byte count %"PRIu64", strip %"PRIu32". Limiting to %"PRIu64, + bytecount, + strip, + newbytecount); + bytecount = newbytecount; } } @@ -1145,15 +1142,12 @@ TIFFFillTile(TIFF* tif, uint32_t tile) (bytecount - 4096) / 10 > (uint64_t)stripsize ) { uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096; - if( newbytecount == 0 || newbytecount > (uint64_t)TIFF_INT64_MAX ) - { - TIFFErrorExt(tif->tif_clientdata, module, - "Too large tile byte count %"PRIu64", tile %"PRIu32". Limiting to %"PRIu64, - bytecount, - tile, - newbytecount); - bytecount = newbytecount; - } + TIFFErrorExt(tif->tif_clientdata, module, + "Too large tile byte count %"PRIu64", tile %"PRIu32". Limiting to %"PRIu64, + bytecount, + tile, + newbytecount); + bytecount = newbytecount; } } diff --git a/src/3rdparty/libtiff/libtiff/tif_webp.c b/src/3rdparty/libtiff/libtiff/tif_webp.c index d5b99d3..60ebaca 100644 --- a/src/3rdparty/libtiff/libtiff/tif_webp.c +++ b/src/3rdparty/libtiff/libtiff/tif_webp.c @@ -44,7 +44,7 @@ */ typedef struct { uint16_t nSamples; /* number of samples per pixel */ - + int lossless; /* lossy/lossless compression */ int quality_level; /* compression level */ WebPPicture sPicture; /* WebP Picture */ @@ -52,13 +52,13 @@ typedef struct { uint8_t* pBuffer; /* buffer to hold raw data on encoding */ unsigned int buffer_offset; /* current offset into the buffer */ unsigned int buffer_size; - + WebPIDecoder* psDecoder; /* WebPIDecoder */ WebPDecBuffer sDecBuffer; /* Decoder buffer */ int last_y; /* Last row decoded */ - + int state; /* state flags */ - + TIFFVGetMethod vgetparent; /* super-class method */ TIFFVSetMethod vsetparent; /* super-class method */ } WebPState; @@ -76,7 +76,7 @@ int TWebPDatasetWriter(const uint8_t* data, size_t data_size, { static const char module[] = "TWebPDatasetWriter"; TIFF* tif = (TIFF*)(picture->custom_ptr); - + if ( (tif->tif_rawcc + (tmsize_t)data_size) > tif->tif_rawdatasize ) { TIFFErrorExt(tif->tif_clientdata, module, "Buffer too small by %"TIFF_SIZE_FORMAT" bytes.", @@ -86,7 +86,7 @@ int TWebPDatasetWriter(const uint8_t* data, size_t data_size, _TIFFmemcpy(tif->tif_rawcp, data, data_size); tif->tif_rawcc += data_size; tif->tif_rawcp += data_size; - return 1; + return 1; } } @@ -102,7 +102,7 @@ TWebPEncode(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) assert(sp != NULL); assert(sp->state == LSTATE_INIT_ENCODE); - + if((uint64_t)sp->buffer_offset + (uint64_t)cc > sp->buffer_size ) { @@ -116,7 +116,7 @@ TWebPEncode(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) sp->buffer_offset += (unsigned)cc; return 1; - + } static int @@ -125,11 +125,11 @@ TWebPDecode(TIFF* tif, uint8_t* op, tmsize_t occ, uint16_t s) static const char module[] = "WebPDecode"; VP8StatusCode status = VP8_STATUS_OK; WebPState *sp = DecoderState(tif); - (void) s; + (void) s; assert(sp != NULL); assert(sp->state == LSTATE_INIT_DECODE); - + if (occ % sp->sDecBuffer.u.RGBA.stride) { TIFFErrorExt(tif->tif_clientdata, module, @@ -142,13 +142,13 @@ TWebPDecode(TIFF* tif, uint8_t* op, tmsize_t occ, uint16_t s) if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED) { if (status == VP8_STATUS_INVALID_PARAM) { TIFFErrorExt(tif->tif_clientdata, module, - "Invalid parameter used."); + "Invalid parameter used."); } else if (status == VP8_STATUS_OUT_OF_MEMORY) { TIFFErrorExt(tif->tif_clientdata, module, - "Out of memory."); + "Out of memory."); } else { TIFFErrorExt(tif->tif_clientdata, module, - "Unrecognized error."); + "Unrecognized error."); } return 0; } else { @@ -157,19 +157,19 @@ TWebPDecode(TIFF* tif, uint8_t* op, tmsize_t occ, uint16_t s) /* Returns the RGB/A image decoded so far */ buf = WebPIDecGetRGB(sp->psDecoder, ¤t_y, NULL, NULL, &stride); - + if ((buf != NULL) && (occ <= (tmsize_t)stride * (current_y - sp->last_y))) { - memcpy(op, + memcpy(op, buf + (sp->last_y * stride), occ); tif->tif_rawcp += tif->tif_rawcc; tif->tif_rawcc = 0; - sp->last_y += occ / sp->sDecBuffer.u.RGBA.stride; + sp->last_y += (int)(occ / sp->sDecBuffer.u.RGBA.stride); return 1; } else { - TIFFErrorExt(tif->tif_clientdata, module, "Unable to decode WebP data."); + TIFFErrorExt(tif->tif_clientdata, module, "Unable to decode WebP data."); return 0; } } @@ -227,7 +227,7 @@ TWebPSetupDecode(TIFF* tif) "WEBP driver requires 8 bit unsigned data"); return 0; } - + /* if we were last encoding, terminate this mode */ if (sp->state & LSTATE_INIT_ENCODE) { WebPPictureFree(&sp->sPicture); @@ -256,7 +256,7 @@ TWebPPreDecode(TIFF* tif, uint16_t s) TIFFDirectory* td = &tif->tif_dir; (void) s; assert(sp != NULL); - + if (isTiled(tif)) { segment_width = td->td_tilewidth; segment_height = td->td_tilelength; @@ -275,7 +275,7 @@ TWebPPreDecode(TIFF* tif, uint16_t s) if( (sp->state & LSTATE_INIT_DECODE) == 0 ) tif->tif_setupdecode(tif); - + if (sp->psDecoder != NULL) { WebPIDelete(sp->psDecoder); WebPFreeDecBuffer(&sp->sDecBuffer); @@ -283,29 +283,29 @@ TWebPPreDecode(TIFF* tif, uint16_t s) } sp->last_y = 0; - + WebPInitDecBuffer(&sp->sDecBuffer); - + sp->sDecBuffer.is_external_memory = 0; sp->sDecBuffer.width = segment_width; sp->sDecBuffer.height = segment_height; sp->sDecBuffer.u.RGBA.stride = segment_width * sp->nSamples; sp->sDecBuffer.u.RGBA.size = segment_width * sp->nSamples * segment_height; - + if (sp->nSamples > 3) { sp->sDecBuffer.colorspace = MODE_RGBA; } else { sp->sDecBuffer.colorspace = MODE_RGB; } - + sp->psDecoder = WebPINewDecoder(&sp->sDecBuffer); - + if (sp->psDecoder == NULL) { TIFFErrorExt(tif->tif_clientdata, module, "Unable to allocate WebP decoder."); return 0; } - + return 1; } @@ -315,7 +315,7 @@ TWebPSetupEncode(TIFF* tif) static const char module[] = "WebPSetupEncode"; uint16_t nBitsPerSample = tif->tif_dir.td_bitspersample; uint16_t sampleFormat = tif->tif_dir.td_sampleformat; - + WebPState* sp = EncoderState(tif); assert(sp != NULL); @@ -337,14 +337,14 @@ TWebPSetupEncode(TIFF* tif) sp->nSamples ); return 0; } - + /* check bits per sample and data type */ if ((nBitsPerSample != 8) || (sampleFormat != SAMPLEFORMAT_UINT)) { TIFFErrorExt(tif->tif_clientdata, module, "WEBP driver requires 8 bit unsigned data"); return 0; } - + if (sp->state & LSTATE_INIT_DECODE) { WebPIDelete(sp->psDecoder); WebPFreeDecBuffer(&sp->sDecBuffer); @@ -417,7 +417,7 @@ TWebPPreEncode(TIFF* tif, uint16_t s) } if( segment_width > 16383 || segment_height > 16383 ) { - TIFFErrorExt(tif->tif_clientdata, module, + TIFFErrorExt(tif->tif_clientdata, module, "WEBP maximum image dimensions are 16383 x 16383."); return 0; } @@ -425,12 +425,12 @@ TWebPPreEncode(TIFF* tif, uint16_t s) /* set up buffer for raw data */ /* given above check and that nSamples <= 4, buffer_size is <= 1 GB */ sp->buffer_size = segment_width * segment_height * sp->nSamples; - + if (sp->pBuffer != NULL) { _TIFFfree(sp->pBuffer); - sp->pBuffer = NULL; + sp->pBuffer = NULL; } - + sp->pBuffer = _TIFFmalloc(sp->buffer_size); if( !sp->pBuffer) { TIFFErrorExt(tif->tif_clientdata, module, "Cannot allocate buffer"); @@ -476,7 +476,7 @@ TWebPPostEncode(TIFF* tif) "WebPPictureImportRGB() failed"); return 0; } - + if (!WebPEncode(&sp->sEncoderConfig, &sp->sPicture)) { #if WEBP_ENCODER_ABI_VERSION >= 0x0100 @@ -554,10 +554,10 @@ TWebPCleanup(TIFF* tif) sp->psDecoder = NULL; sp->last_y = 0; } - + if (sp->pBuffer != NULL) { _TIFFfree(sp->pBuffer); - sp->pBuffer = NULL; + sp->pBuffer = NULL; } _TIFFfree(tif->tif_data); @@ -593,7 +593,7 @@ TWebPVSetField(TIFF* tif, uint32_t tag, va_list ap) "Need to upgrade WEBP driver, this version doesn't support " "lossless compression."); return 0; - #endif + #endif default: return (*sp->vsetparent)(tif, tag, ap); } @@ -669,7 +669,7 @@ TIFFInitWebP(TIFF* tif, int scheme) sp->nSamples = 0; sp->psDecoder = NULL; sp->last_y = 0; - + sp->buffer_offset = 0; sp->pBuffer = NULL; diff --git a/src/3rdparty/libtiff/libtiff/tif_win32.c b/src/3rdparty/libtiff/libtiff/tif_win32.c index c6ca151..d617a0f 100644 --- a/src/3rdparty/libtiff/libtiff/tif_win32.c +++ b/src/3rdparty/libtiff/libtiff/tif_win32.c @@ -28,6 +28,7 @@ */ #include "tiffiop.h" +#include <stdlib.h> #include <windows.h> diff --git a/src/3rdparty/libtiff/libtiff/tif_write.c b/src/3rdparty/libtiff/libtiff/tif_write.c index b5ef21d..46e0776 100644 --- a/src/3rdparty/libtiff/libtiff/tif_write.c +++ b/src/3rdparty/libtiff/libtiff/tif_write.c @@ -124,18 +124,12 @@ TIFFWriteScanline(TIFF* tif, void* buf, uint32_t row, uint16_t sample) return (-1); tif->tif_flags |= TIFF_CODERSETUP; } - + tif->tif_rawcc = 0; tif->tif_rawcp = tif->tif_rawdata; - if( td->td_stripbytecount_p[strip] > 0 ) - { - /* if we are writing over existing tiles, zero length */ - td->td_stripbytecount_p[strip] = 0; - - /* this forces TIFFAppendToStrip() to do a seek */ - tif->tif_curoff = 0; - } + /* this informs TIFFAppendToStrip() we have changed strip */ + tif->tif_curoff = 0; if (!(*tif->tif_preencode)(tif, sample)) return (-1); @@ -194,10 +188,6 @@ static int _TIFFReserveLargeEnoughWriteBuffer(TIFF* tif, uint32_t strip_or_tile) (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; } @@ -235,7 +225,7 @@ TIFFWriteEncodedStrip(TIFF* tif, uint32_t strip, void* data, tmsize_t cc) if (!TIFFGrowStrips(tif, 1, module)) return ((tmsize_t) -1); td->td_stripsperimage = - TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip); + TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip); } /* * Handle delayed allocation of data buffer. This @@ -246,8 +236,12 @@ TIFFWriteEncodedStrip(TIFF* tif, uint32_t strip, void* data, tmsize_t cc) return ((tmsize_t) -1); tif->tif_flags |= TIFF_BUF4WRITE; + tif->tif_curstrip = strip; + /* this informs TIFFAppendToStrip() we have changed or reset strip */ + tif->tif_curoff = 0; + if( !_TIFFReserveLargeEnoughWriteBuffer(tif, strip) ) { return ((tmsize_t)(-1)); } @@ -346,7 +340,12 @@ TIFFWriteRawStrip(TIFF* tif, uint32_t strip, void* data, tmsize_t cc) if (!TIFFGrowStrips(tif, 1, module)) return ((tmsize_t) -1); } + tif->tif_curstrip = strip; + + /* this informs TIFFAppendToStrip() we have changed or reset strip */ + tif->tif_curoff = 0; + if (td->td_stripsperimage == 0) { TIFFErrorExt(tif->tif_clientdata, module,"Zero strips per image"); return ((tmsize_t) -1); @@ -412,8 +411,12 @@ TIFFWriteEncodedTile(TIFF* tif, uint32_t tile, void* data, tmsize_t cc) return ((tmsize_t)(-1)); tif->tif_flags |= TIFF_BUF4WRITE; + tif->tif_curtile = tile; + /* this informs TIFFAppendToStrip() we have changed or reset tile */ + tif->tif_curoff = 0; + if( !_TIFFReserveLargeEnoughWriteBuffer(tif, tile) ) { return ((tmsize_t)(-1)); } @@ -421,7 +424,7 @@ TIFFWriteEncodedTile(TIFF* tif, uint32_t tile, void* data, tmsize_t cc) tif->tif_rawcc = 0; tif->tif_rawcp = tif->tif_rawdata; - /* + /* * Compute tiles per row & per column to compute * current row and column */ @@ -583,7 +586,7 @@ TIFFWriteCheck(TIFF* tif, int tiles, const char* module) } _TIFFFillStriles( tif ); - + /* * On the first write verify all the required information * has been setup and initialize any data structures that @@ -600,7 +603,7 @@ TIFFWriteCheck(TIFF* tif, int tiles, const char* module) return (0); } if (tif->tif_dir.td_samplesperpixel == 1) { - /* + /* * Planarconfiguration is irrelevant in case of single band * images and need not be included. We will set it anyway, * because this field is used in other parts of library even @@ -741,18 +744,21 @@ TIFFAppendToStrip(TIFF* tif, uint32_t strip, uint8_t* data, tmsize_t cc) static const char module[] = "TIFFAppendToStrip"; TIFFDirectory *td = &tif->tif_dir; uint64_t m; - int64_t old_byte_count = -1; + int64_t old_byte_count = -1; - if (td->td_stripoffset_p[strip] == 0 || tif->tif_curoff == 0) { + if( tif->tif_curoff == 0 ) + tif->tif_lastvalidoff = 0; + + if (td->td_stripoffset_p[strip] == 0 || tif->tif_curoff == 0) { assert(td->td_nstrips > 0); - if( td->td_stripbytecount_p[strip] != 0 - && td->td_stripoffset_p[strip] != 0 + if( td->td_stripbytecount_p[strip] != 0 + && td->td_stripoffset_p[strip] != 0 && td->td_stripbytecount_p[strip] >= (uint64_t) cc ) { - /* + /* * There is already tile data on disk, and the new tile - * data we have will fit in the same space. The only + * data we have will fit in the same space. The only * aspect of this that is risky is that there could be * more data to append to this strip before we are done * depending on how we are getting called. @@ -763,11 +769,13 @@ TIFFAppendToStrip(TIFF* tif, uint32_t strip, uint8_t* data, tmsize_t cc) (unsigned long)tif->tif_row); return (0); } + + tif->tif_lastvalidoff = td->td_stripoffset_p[strip] + td->td_stripbytecount_p[strip]; } else { - /* - * Seek to end of file, and set that as our location to + /* + * Seek to end of file, and set that as our location to * write this strip. */ td->td_stripoffset_p[strip] = TIFFSeekFile(tif, 0, SEEK_END); @@ -791,6 +799,84 @@ TIFFAppendToStrip(TIFF* tif, uint32_t strip, uint8_t* data, tmsize_t cc) TIFFErrorExt(tif->tif_clientdata, module, "Maximum TIFF file size exceeded"); return (0); } + + if( tif->tif_lastvalidoff != 0 && m > tif->tif_lastvalidoff && + td->td_stripbytecount_p[strip] > 0 ) + { + /* Ouch: we have detected that we are rewriting in place a strip/tile */ + /* with several calls to TIFFAppendToStrip(). The first call was with */ + /* a size smaller than the previous size of the strip/tile, so we */ + /* opted to rewrite in place, but a following call causes us to go */ + /* outsize of the strip/tile area, so we have to finally go for a */ + /* append-at-end-of-file strategy, and start by moving what we already */ + /* wrote. */ + tmsize_t tempSize; + void* temp; + uint64_t offsetRead; + uint64_t offsetWrite; + uint64_t toCopy = td->td_stripbytecount_p[strip]; + + if( toCopy < 1024 * 1024 ) + tempSize = (tmsize_t)toCopy; + else + tempSize = 1024 * 1024; + + offsetRead = td->td_stripoffset_p[strip]; + offsetWrite = TIFFSeekFile(tif, 0, SEEK_END); + + m = offsetWrite + toCopy + cc; + if (!(tif->tif_flags&TIFF_BIGTIFF) && m != (uint32_t)m) + { + TIFFErrorExt(tif->tif_clientdata, module, "Maximum TIFF file size exceeded"); + return (0); + } + + temp = _TIFFmalloc(tempSize); + if (temp == NULL) { + TIFFErrorExt(tif->tif_clientdata, module, "No space for output buffer"); + return (0); + } + + tif->tif_flags |= TIFF_DIRTYSTRIP; + + td->td_stripoffset_p[strip] = offsetWrite; + td->td_stripbytecount_p[strip] = 0; + + /* Move data written by previous calls to us at end of file */ + while( toCopy > 0 ) + { + if( !SeekOK(tif, offsetRead) ) { + TIFFErrorExt(tif->tif_clientdata, module, "Seek error"); + _TIFFfree(temp); + return (0); + } + if( !ReadOK(tif, temp, tempSize) ) { + TIFFErrorExt(tif->tif_clientdata, module, "Cannot read"); + _TIFFfree(temp); + return (0); + } + if (!SeekOK(tif, offsetWrite) ) { + TIFFErrorExt(tif->tif_clientdata, module, "Seek error"); + _TIFFfree(temp); + return (0); + } + if( !WriteOK(tif, temp, tempSize) ) { + TIFFErrorExt(tif->tif_clientdata, module, "Cannot write"); + _TIFFfree(temp); + return (0); + } + offsetRead += tempSize; + offsetWrite += tempSize; + td->td_stripbytecount_p[strip] += tempSize; + toCopy -= tempSize; + } + _TIFFfree(temp); + + /* Append the data of this call */ + offsetWrite += cc; + m = offsetWrite; + } + if (!WriteOK(tif, data, cc)) { TIFFErrorExt(tif->tif_clientdata, module, "Write error at scanline %lu", (unsigned long) tif->tif_row); @@ -801,7 +887,7 @@ TIFFAppendToStrip(TIFF* tif, uint32_t strip, uint8_t* data, tmsize_t cc) if((int64_t) td->td_stripbytecount_p[strip] != old_byte_count ) tif->tif_flags |= TIFF_DIRTYSTRIP; - + return (1); } @@ -845,6 +931,7 @@ void TIFFSetWriteOffset(TIFF* tif, toff_t off) { tif->tif_curoff = off; + tif->tif_lastvalidoff = 0; } /* vim: set ts=8 sts=8 sw=8 noet: */ diff --git a/src/3rdparty/libtiff/libtiff/tif_zstd.c b/src/3rdparty/libtiff/libtiff/tif_zstd.c index 14ac081..960aa90 100644 --- a/src/3rdparty/libtiff/libtiff/tif_zstd.c +++ b/src/3rdparty/libtiff/libtiff/tif_zstd.c @@ -101,18 +101,16 @@ ZSTDPreDecode(TIFF* tif, uint16_t s) if( (sp->state & LSTATE_INIT_DECODE) == 0 ) tif->tif_setupdecode(tif); - if( sp->dstream ) + if( sp->dstream == NULL ) { - ZSTD_freeDStream(sp->dstream); - sp->dstream = NULL; + sp->dstream = ZSTD_createDStream(); + if( sp->dstream == NULL ) { + TIFFErrorExt(tif->tif_clientdata, module, + "Cannot allocate decompression stream"); + return 0; + } } - sp->dstream = ZSTD_createDStream(); - if( sp->dstream == NULL ) { - TIFFErrorExt(tif->tif_clientdata, module, - "Cannot allocate decompression stream"); - return 0; - } zstd_ret = ZSTD_initDStream(sp->dstream); if( ZSTD_isError(zstd_ret) ) { TIFFErrorExt(tif->tif_clientdata, module, @@ -203,15 +201,13 @@ ZSTDPreEncode(TIFF* tif, uint16_t s) if( sp->state != LSTATE_INIT_ENCODE ) tif->tif_setupencode(tif); - if (sp->cstream) { - ZSTD_freeCStream(sp->cstream); - sp->cstream = NULL; - } - sp->cstream = ZSTD_createCStream(); - if( sp->cstream == NULL ) { - TIFFErrorExt(tif->tif_clientdata, module, - "Cannot allocate compression stream"); - return 0; + if (sp->cstream == NULL) { + sp->cstream = ZSTD_createCStream(); + if( sp->cstream == NULL ) { + TIFFErrorExt(tif->tif_clientdata, module, + "Cannot allocate compression stream"); + return 0; + } } zstd_ret = ZSTD_initCStream(sp->cstream, sp->compression_level); diff --git a/src/3rdparty/libtiff/libtiff/tiff.h b/src/3rdparty/libtiff/libtiff/tiff.h index bd79270..4511130 100644 --- a/src/3rdparty/libtiff/libtiff/tiff.h +++ b/src/3rdparty/libtiff/libtiff/tiff.h @@ -196,7 +196,7 @@ typedef enum { /* compression codes 32908-32911 are reserved for Pixar */ #define COMPRESSION_PIXARFILM 32908 /* Pixar companded 10bit LZW */ #define COMPRESSION_PIXARLOG 32909 /* Pixar companded 11bit ZIP */ -#define COMPRESSION_DEFLATE 32946 /* Deflate compression */ +#define COMPRESSION_DEFLATE 32946 /* Deflate compression, legacy tag */ #define COMPRESSION_ADOBE_DEFLATE 8 /* Deflate compression, as recognized by Adobe */ /* compression code 32947 is reserved for Oceana Matrix <dev@oceana.com> */ diff --git a/src/3rdparty/libtiff/libtiff/tiffconf.h.cmake.in b/src/3rdparty/libtiff/libtiff/tiffconf.h.cmake.in index 66ab354..5afbf3b 100644 --- a/src/3rdparty/libtiff/libtiff/tiffconf.h.cmake.in +++ b/src/3rdparty/libtiff/libtiff/tiffconf.h.cmake.in @@ -95,7 +95,7 @@ /* Support strip chopping (whether or not to convert single-strip uncompressed images to multiple strips of ~8Kb to reduce memory usage) */ -#cmakedefine STRIPCHOP_DEFAULT 1 +#cmakedefine STRIPCHOP_DEFAULT TIFF_STRIPCHOP /* Enable SubIFD tag (330) support */ #cmakedefine SUBIFD_SUPPORT 1 diff --git a/src/3rdparty/libtiff/libtiff/tiffio.h b/src/3rdparty/libtiff/libtiff/tiffio.h index c6a192c..18dfd11 100644 --- a/src/3rdparty/libtiff/libtiff/tiffio.h +++ b/src/3rdparty/libtiff/libtiff/tiffio.h @@ -328,6 +328,9 @@ extern TIFFDataType TIFFFieldDataType(const TIFFField*); extern int TIFFFieldPassCount(const TIFFField*); extern int TIFFFieldReadCount(const TIFFField*); extern int TIFFFieldWriteCount(const TIFFField*); +extern int TIFFFieldSetGetSize(const TIFFField*); /* returns internal storage size of TIFFSetGetFieldType in bytes. */ +extern int TIFFFieldSetGetCountSize(const TIFFField*); /* returns size of count parameter 0=none, 2=uint16_t, 4=uint32_t */ +extern int TIFFFieldIsAnonymous(const TIFFField *); typedef int (*TIFFVSetMethod)(TIFF*, uint32_t, va_list); typedef int (*TIFFVGetMethod)(TIFF*, uint32_t, va_list); @@ -384,9 +387,10 @@ extern int TIFFIsByteSwapped(TIFF*); extern int TIFFIsUpSampled(TIFF*); extern int TIFFIsMSB2LSB(TIFF*); extern int TIFFIsBigEndian(TIFF*); +extern int TIFFIsBigTIFF(TIFF*); extern TIFFReadWriteProc TIFFGetReadProc(TIFF*); extern TIFFReadWriteProc TIFFGetWriteProc(TIFF*); -extern TIFFSeekProc TIFFGetSeekProc(TIFF*); +extern TIFFSeekProc TIFFGetSeekProc(TIFF*); extern TIFFCloseProc TIFFGetCloseProc(TIFF*); extern TIFFSizeProc TIFFGetSizeProc(TIFF*); extern TIFFMapFileProc TIFFGetMapFileProc(TIFF*); @@ -483,7 +487,7 @@ extern tmsize_t TIFFWriteEncodedStrip(TIFF* tif, uint32_t strip, void* data, tms extern tmsize_t TIFFWriteRawStrip(TIFF* tif, uint32_t strip, void* data, tmsize_t cc); extern tmsize_t TIFFWriteEncodedTile(TIFF* tif, uint32_t tile, void* data, tmsize_t cc); extern tmsize_t TIFFWriteRawTile(TIFF* tif, uint32_t tile, void* data, tmsize_t cc); -extern int TIFFDataWidth(TIFFDataType); /* table of tag datatype widths */ +extern int TIFFDataWidth(TIFFDataType); /* table of tag datatype widths within TIFF file. */ extern void TIFFSetWriteOffset(TIFF* tif, toff_t off); extern void TIFFSwabShort(uint16_t*); extern void TIFFSwabLong(uint32_t*); diff --git a/src/3rdparty/libtiff/libtiff/tiffiop.h b/src/3rdparty/libtiff/libtiff/tiffiop.h index f1151f5..e3af461 100644 --- a/src/3rdparty/libtiff/libtiff/tiffiop.h +++ b/src/3rdparty/libtiff/libtiff/tiffiop.h @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -43,7 +43,7 @@ #ifdef HAVE_ASSERT_H # include <assert.h> #else -# define assert(x) +# define assert(x) #endif #include "tiffio.h" @@ -117,6 +117,7 @@ struct tiff { #define TIFF_CHOPPEDUPARRAYS 0x4000000U /* set when allocChoppedUpStripArrays() has modified strip array */ uint64_t tif_diroff; /* file offset of current directory */ uint64_t tif_nextdiroff; /* file offset of following directory */ + uint64_t tif_lastdiroff; /* file offset of last directory written so far */ uint64_t* tif_dirlist; /* list of offsets to already seen directories to prevent IFD looping */ uint16_t tif_dirlistsize; /* number of entries in offset list */ uint16_t tif_dirnumber; /* number of already seen directories */ @@ -132,6 +133,7 @@ struct tiff { uint16_t tif_curdir; /* current directory (index) */ uint32_t tif_curstrip; /* current strip for read/write */ uint64_t tif_curoff; /* current offset for read/write */ + uint64_t tif_lastvalidoff; /* last valid offset allowed for rewrite in place. Used only by TIFFAppendToStrip() */ uint64_t tif_dataoff; /* current offset for writing dir */ /* SubIFD support */ uint16_t tif_nsubifd; /* remaining subifds to write */ @@ -337,17 +339,12 @@ extern int TIFFSetCompressionScheme(TIFF* tif, int scheme); extern int TIFFSetDefaultCompressionState(TIFF* tif); extern uint32_t _TIFFDefaultStripSize(TIFF* tif, uint32_t s); extern void _TIFFDefaultTileSize(TIFF* tif, uint32_t* tw, uint32_t* th); -extern int _TIFFDataSize(TIFFDataType type); - -/*--: Rational2Double: Return size of TIFFSetGetFieldType in bytes. */ -extern int _TIFFSetGetFieldSize(TIFFSetGetFieldType setgettype); -extern void _TIFFsetByteArray(void**, void*, uint32_t); -extern void _TIFFsetString(char**, char*); -extern void _TIFFsetShortArray(uint16_t**, uint16_t*, uint32_t); -extern void _TIFFsetLongArray(uint32_t**, uint32_t*, uint32_t); -extern void _TIFFsetFloatArray(float**, float*, uint32_t); -extern void _TIFFsetDoubleArray(double**, double*, uint32_t); +extern void _TIFFsetByteArray(void**, const void*, uint32_t); +extern void _TIFFsetShortArray(uint16_t**, const uint16_t*, uint32_t); +extern void _TIFFsetLongArray(uint32_t**, const uint32_t*, uint32_t); +extern void _TIFFsetFloatArray(float**, const float*, uint32_t); +extern void _TIFFsetDoubleArray(double**, const double*, uint32_t); extern void _TIFFprintAscii(FILE*, const char*); extern void _TIFFprintAsciiTag(FILE*, const char*, const char*); diff --git a/src/3rdparty/libtiff/libtiff/tiffvers.h b/src/3rdparty/libtiff/libtiff/tiffvers.h index dbe5596..084f335 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.3.0\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc." +#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.4.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 20210416 +#define TIFFLIB_VERSION 20220520 diff --git a/src/3rdparty/libtiff/qt_attribution.json b/src/3rdparty/libtiff/qt_attribution.json index 9d7837e..58cd59d 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.3.0", + "Version": "4.4.0", "License": "libtiff License", "LicenseId": "libtiff", "LicenseFile": "COPYRIGHT", |