summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEirik Aavitsland <eirik.aavitsland@qt.io>2022-05-30 10:14:11 +0200
committerEirik Aavitsland <eirik.aavitsland@qt.io>2022-05-31 15:56:50 +0200
commit372ff593c65cdea4616cb2d6e1c8a53e6b22674d (patch)
tree317f99112ee309ca6301c4d767d6bff15b61eacf
parent798a9283a43592261856af898a9453ef4b2f2167 (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>
-rw-r--r--src/3rdparty/libtiff/ChangeLog1342
-rw-r--r--src/3rdparty/libtiff/RELEASE-DATE2
-rw-r--r--src/3rdparty/libtiff/VERSION2
-rw-r--r--src/3rdparty/libtiff/libtiff/libtiff.def5
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_close.c13
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_color.c31
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_dir.c67
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_dir.h4
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_dirinfo.c142
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_dirread.c873
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_dirwrite.c61
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_jbig.c10
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_jpeg.c4191
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_jpeg_12.c99
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_luv.c14
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_lzw.c661
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_ojpeg.c18
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_open.c13
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_packbits.c10
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_predict.c90
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_print.c54
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_read.c30
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_webp.c76
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_win32.c1
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_write.c139
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_zstd.c32
-rw-r--r--src/3rdparty/libtiff/libtiff/tiff.h2
-rw-r--r--src/3rdparty/libtiff/libtiff/tiffconf.h.cmake.in2
-rw-r--r--src/3rdparty/libtiff/libtiff/tiffio.h8
-rw-r--r--src/3rdparty/libtiff/libtiff/tiffiop.h35
-rw-r--r--src/3rdparty/libtiff/libtiff/tiffvers.h4
-rw-r--r--src/3rdparty/libtiff/qt_attribution.json2
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, &current_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",