aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/libtiff
diff options
context:
space:
mode:
authorshumkovnd <shumkovnd@yandex-team.com>2023-11-10 14:39:34 +0300
committershumkovnd <shumkovnd@yandex-team.com>2023-11-10 16:42:24 +0300
commit77eb2d3fdcec5c978c64e025ced2764c57c00285 (patch)
treec51edb0748ca8d4a08d7c7323312c27ba1a8b79a /contrib/libs/libtiff
parentdd6d20cadb65582270ac23f4b3b14ae189704b9d (diff)
downloadydb-77eb2d3fdcec5c978c64e025ced2764c57c00285.tar.gz
KIKIMR-19287: add task_stats_drawing script
Diffstat (limited to 'contrib/libs/libtiff')
-rw-r--r--contrib/libs/libtiff/CONTRIBUTING.md19
-rw-r--r--contrib/libs/libtiff/ChangeLog15457
-rw-r--r--contrib/libs/libtiff/LICENSE.md23
-rw-r--r--contrib/libs/libtiff/README.md71
-rw-r--r--contrib/libs/libtiff/VERSION.txt1
-rw-r--r--contrib/libs/libtiff/t4.h284
-rw-r--r--contrib/libs/libtiff/tif_aux.c458
-rw-r--r--contrib/libs/libtiff/tif_close.c158
-rw-r--r--contrib/libs/libtiff/tif_codec.c163
-rw-r--r--contrib/libs/libtiff/tif_color.c322
-rw-r--r--contrib/libs/libtiff/tif_compress.c310
-rw-r--r--contrib/libs/libtiff/tif_config.h166
-rw-r--r--contrib/libs/libtiff/tif_dir.c2308
-rw-r--r--contrib/libs/libtiff/tif_dir.h340
-rw-r--r--contrib/libs/libtiff/tif_dirinfo.c1351
-rw-r--r--contrib/libs/libtiff/tif_dirread.c7894
-rw-r--r--contrib/libs/libtiff/tif_dirwrite.c3613
-rw-r--r--contrib/libs/libtiff/tif_dumpmode.c122
-rw-r--r--contrib/libs/libtiff/tif_error.c132
-rw-r--r--contrib/libs/libtiff/tif_extension.c110
-rw-r--r--contrib/libs/libtiff/tif_fax3.c1735
-rw-r--r--contrib/libs/libtiff/tif_fax3.h648
-rw-r--r--contrib/libs/libtiff/tif_fax3sm.c1261
-rw-r--r--contrib/libs/libtiff/tif_flush.c157
-rw-r--r--contrib/libs/libtiff/tif_getimage.c3360
-rw-r--r--contrib/libs/libtiff/tif_hash_set.c603
-rw-r--r--contrib/libs/libtiff/tif_hash_set.h100
-rw-r--r--contrib/libs/libtiff/tif_jbig.c231
-rw-r--r--contrib/libs/libtiff/tif_jpeg.c2900
-rw-r--r--contrib/libs/libtiff/tif_jpeg_12.c63
-rw-r--r--contrib/libs/libtiff/tif_lerc.c1206
-rw-r--r--contrib/libs/libtiff/tif_luv.c1838
-rw-r--r--contrib/libs/libtiff/tif_lzma.c520
-rw-r--r--contrib/libs/libtiff/tif_lzw.c1458
-rw-r--r--contrib/libs/libtiff/tif_next.c194
-rw-r--r--contrib/libs/libtiff/tif_ojpeg.c2815
-rw-r--r--contrib/libs/libtiff/tif_open.c808
-rw-r--r--contrib/libs/libtiff/tif_packbits.c323
-rw-r--r--contrib/libs/libtiff/tif_pixarlog.c1670
-rw-r--r--contrib/libs/libtiff/tif_predict.c1046
-rw-r--r--contrib/libs/libtiff/tif_predict.h74
-rw-r--r--contrib/libs/libtiff/tif_print.c755
-rw-r--r--contrib/libs/libtiff/tif_read.c1624
-rw-r--r--contrib/libs/libtiff/tif_stream.cxx404
-rw-r--r--contrib/libs/libtiff/tif_strip.c350
-rw-r--r--contrib/libs/libtiff/tif_swab.c329
-rw-r--r--contrib/libs/libtiff/tif_thunder.c198
-rw-r--r--contrib/libs/libtiff/tif_tile.c284
-rw-r--r--contrib/libs/libtiff/tif_unix.c370
-rw-r--r--contrib/libs/libtiff/tif_version.c28
-rw-r--r--contrib/libs/libtiff/tif_warning.c105
-rw-r--r--contrib/libs/libtiff/tif_webp.c800
-rw-r--r--contrib/libs/libtiff/tif_win32.c442
-rw-r--r--contrib/libs/libtiff/tif_write.c960
-rw-r--r--contrib/libs/libtiff/tif_zip.c731
-rw-r--r--contrib/libs/libtiff/tif_zstd.c436
-rw-r--r--contrib/libs/libtiff/tiff.h898
-rw-r--r--contrib/libs/libtiff/tiffconf.h144
-rw-r--r--contrib/libs/libtiff/tiffio.h653
-rw-r--r--contrib/libs/libtiff/tiffiop.h523
-rw-r--r--contrib/libs/libtiff/tiffvers.h30
-rw-r--r--contrib/libs/libtiff/uvcode.h93
-rw-r--r--contrib/libs/libtiff/ya.make93
63 files changed, 66562 insertions, 0 deletions
diff --git a/contrib/libs/libtiff/CONTRIBUTING.md b/contrib/libs/libtiff/CONTRIBUTING.md
new file mode 100644
index 0000000000..1291d61cf7
--- /dev/null
+++ b/contrib/libs/libtiff/CONTRIBUTING.md
@@ -0,0 +1,19 @@
+Contributing
+------------
+
+libtiff uses a ``.clang-format`` file to enforce code formatting rules.
+
+Automatic code reformatting can be done with pre-commit.
+
+Install (once) pre-commit with ``python -m pip install pre-commit``.
+
+Install it (once) in the libtiff git repository with ``pre-commit install``.
+
+Then the rules defined in the ``.pre-commit-config.yaml`` file will be
+enforced at ``git commit`` time, with automatic reformatting.
+
+Due to whole-tree code reformatting done during libtiff 4.5 development,
+``git blame`` information might be misleading. To avoid that, you need
+to modify your git configuration as following to ignore the revision of
+the whole-tree reformatting:
+``git config blame.ignoreRevsFile .git-blame-ignore-revs``.
diff --git a/contrib/libs/libtiff/ChangeLog b/contrib/libs/libtiff/ChangeLog
new file mode 100644
index 0000000000..2124816142
--- /dev/null
+++ b/contrib/libs/libtiff/ChangeLog
@@ -0,0 +1,15457 @@
+2023-06-09 Even Rouault <even.rouault@spatialys.com>
+
+ libtiff v4.5.1 released
+
+2023-06-09 Even Rouault <even.rouault@spatialys.com>
+
+ Merge remote-tracking branch 'sulaus/Rel_4.5.1_preparation'
+
+2023-06-09 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'disable_dng_tags' into 'master'
+ tif_dirinfo.c: disable DNG 1.2->1.6 tags
+
+ Closes #575
+
+ See merge request libtiff/libtiff!497
+
+2023-06-09 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_577' into 'master'
+ CMake related fixes
+
+ Closes #577
+
+ See merge request libtiff/libtiff!496
+
+2023-06-07 Even Rouault <even.rouault@spatialys.com>
+
+ tif_dirinfo.c: disable DNG 1.2->1.6 tags.
+ They were added per b90b20d36d7833f54a1f3014c324f6c21b988006 but it has
+ been found in https://gitlab.com/libtiff/libtiff/-/issues/575 that it
+ could cause compatibity issues with libtiff users, so this addition
+ should be defered for a feature release (likely 4.6.0) and not a patch one.
+
+ Fixes #575
+
+2023-06-06 Timothy Lyanguzov <theta682@gmail.com>
+
+ Apply 1 suggestion(s) to 1 file(s)
+
+2023-06-05 Even Rouault <even.rouault@spatialys.com>
+
+ CI: add testing of find_package(Tiff CONFIG)
+
+ CMake: export TiffConfig.cmake and TiffConfigVersion.cmake files.
+
+ libtiff/CMakeLists.txt: fix export of INTERFACE_INCLUDE_DIRECTORIES.
+
+ libtiff/CMakeLists.txt: correctly define TIFF::tiff alias (fixes #577)
+
+2023-06-05 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'TIFFField_downgrade_errors_to_warnings' into 'master'
+ TIFFFieldWithName() and TIFFFieldWithTag() downgrade errors to warnings.
+
+ See merge request libtiff/libtiff!495
+
+2023-05-28 Su_Laus <sulau@freenet.de>
+
+ TIFFFieldWithName() and TIFFFieldWithTag() downgrade errors to warnings. see https://gitlab.com/libtiff/libtiff/-/issues/575#note_1407633888
+
+2023-05-25 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bebuch-master-patch-58347' into 'master'
+ check if upstream lzma (xz) config was used and bind to it if so
+
+ See merge request libtiff/libtiff!494
+
+2023-05-25 Benjamin Buch <benni.buch@gmail.com>
+
+ check if upstream lzma (xz) config was used and bind to it if so.
+
+2023-05-25 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'upstream-zstd-config' into 'master'
+ check if upstream zstd config was used and bind to it if so
+
+ See merge request libtiff/libtiff!493
+
+2023-05-25 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'cmake_FindDeflate_bugs_see_526' into 'master'
+ CMake: FindDeflate several errors fixed (see #526)
+
+ See merge request libtiff/libtiff!491
+
+2023-05-24 Su_Laus <sulau@freenet.de>
+
+ CMake: FindDeflate several errors (see #526)
+ There are CMake issues if the library is not included in the environment path and only set with CMake -D option.
+ - For FindDeflate.cmake, FindJBIG.cmake, FindLERC.cmake, FindWebP.cmake, FindZSTD.cmake:
+ Set IMPORTED_LOCATION (without debug or release) if neither <library>_LIBRARY_RELEASE nor <library>_LIBRARY_DEBUG were set.
+ - FindDeflate.cmake: Correct code to retrieve library version information from libdeflate.h
+ - FindLERC.cmake version string return added.
+
+2023-05-24 Benjamin Buch <benni.buch@gmail.com>
+
+ prefer shared over static.
+
+ check if upstream zstd config was used and bind to it if so.
+
+2023-05-24 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'master' into 'master'
+ make WebP component name compatible with upstream ConfigWebP.cmake
+
+ See merge request libtiff/libtiff!492
+
+2023-05-24 Benjamin Buch <benni.buch@gmail.com>
+
+ CMake: make WebP component name compatible with upstream ConfigWebP.cmake
+
+2023-05-18 Su_Laus <sulau@freenet.de>
+
+ Prepare release 4.5.1 - Update till 18.05.23 after fix_559_DNG_1.6_passcount_error
+
+ Prepare release 4.5.1.
+
+2023-05-18 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_559_DNG_1.6_passcount_error' into 'master'
+ Fix #559 DNG 1.6 passcount assertion
+
+ Closes #574 et #559
+
+ See merge request libtiff/libtiff!489
+
+2023-05-18 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_557_TagExtender_for_CustomDirectories_not_possible' into 'master'
+ manpage: TIFFSetTagExtender() cannot add tags to custom directories. Closes #557.
+
+ Closes #557
+
+ See merge request libtiff/libtiff!490
+
+2023-05-18 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_559_DNG_1.6_passcount_error' into 'master'
+ Fix #559 DNG 1.6 passcount assertion
+
+ Closes #574 et #559
+
+ See merge request libtiff/libtiff!489
+
+2023-05-18 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_557_TagExtender_for_CustomDirectories_not_possible' into 'master'
+ manpage: TIFFSetTagExtender() cannot add tags to custom directories. Closes #557.
+
+ Closes #557
+
+ See merge request libtiff/libtiff!490
+
+2023-05-17 Su_Laus <sulau@freenet.de>
+
+ Documentation update: TIFFSetTagExtender() cannot add tags to custom directories.
+ Closes #557.
+
+2023-05-16 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_558' into 'master'
+ Hardcode HOST_FILLORDER to FILLORDER_LSB2MSB, and make 'H' flag of TIFFOpen()...
+
+ See merge request libtiff/libtiff!488
+
+2023-05-16 Su_Laus <sulau@freenet.de>
+
+ Fix #559 DNG 1.6 passcount assertion.
+ Amend DNG tags definition introduced with MR 482:
+ - DNG 1.6 tags specified as UTF-8 strings are defined as variable TIFF_BYTE with passcount=TRUE.
+ - For all tags with TIFF_SETGET_C32_UINT8 the readcount and writecount were corrected to -3 (TIFF_VARIABLE2).
+
+ Testprogram to write and read all tags defined within LibTIFF is introduced.
+ It also checks for valid passcount flag setting for the defined tags but some special tags are excluded from that check.
+
+ Closes #559.
+
+2023-05-09 Even Rouault <even.rouault@spatialys.com>
+
+ Hardcode HOST_FILLORDER to FILLORDER_LSB2MSB, and make 'H' flag of TIFFOpen() to warn and an alias of FILLORDER_MSB2LSB
+
+ tif_lerc.c: use WORDS_BIGENDIAN instead of HOST_BIGENDIAN.
+
+2023-05-07 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_484_TIFFDirectory_32_64_bit' into 'master'
+ Fix 484 TIFFDirectory td_fieldsset uses unsigned long which can be 32 or 64 bits.
+
+ Closes #484
+
+ See merge request libtiff/libtiff!471
+
+2023-05-07 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'DNG_1.6_EP_tags' into 'master'
+ Add DNG tags up to version 1.6.0.0 and some TIFF/EP tags and update documentation
+
+ See merge request libtiff/libtiff!482
+
+2023-05-07 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue547' into 'master'
+ do not install libtiff-4.pc when tiff-install is reset
+
+ Closes #547
+
+ See merge request libtiff/libtiff!481
+
+2023-05-06 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_548' into 'master'
+ LZWDecode(): avoid crash when trying to read again from a strip whith a...
+
+ Closes #548
+
+ See merge request libtiff/libtiff!484
+
+2023-05-06 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffcrop_fix_553_multi-image-errors' into 'master'
+ tiffcrop: fix 553 by considering error return of writeSelections()
+
+ Closes #553
+
+ See merge request libtiff/libtiff!485
+
+2023-05-06 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tif_ojpeg_fix-554_FPE' into 'master'
+ tif_ojpeg.c fix 554 by checking for division by zero
+
+ Closes #554
+
+ See merge request libtiff/libtiff!486
+
+2023-05-06 Su Laus <sulau@freenet.de>
+
+ tif_ojpeg.c fix 554 by checking for division by zero.
+
+2023-05-05 Su_Laus <sulau@freenet.de>
+
+ Consider error return of writeSelections(). Fixes #553.
+
+2023-04-29 Even Rouault <even.rouault@spatialys.com>
+
+ LZWDecode(): avoid crash when trying to read again from a strip whith a missing end-of-information marker (fixes #548)
+
+2023-04-25 Su_Laus <sulau@freenet.de>
+
+ Add DNG tags up to version 1.6.0.0 and some TIFF/EP tags and update documentation
+ Amend MR !337 'Add support for DNG tags up to version 1.6.0.0 and some TIFF/EP tags' from Sami Liedes:
+ - Set most tags to OkToChange=1.
+ - Define BATTERYLEVEL tag as ASCII and convert values of rational variant to ASCII.
+ - TIFF documentation updated for tags recognized by LibTiff (DNG 1.6 and others).
+ - TIFF/EP tags added, which are equivalent to EXIF tags. This addresses part of #418 as well.
+ - Definition of tags reformatted (clang-format off) for better readability of tag comments in tiff.h and tif_dirinfo.c
+
+2023-04-23 Roman <kosobrodov@fastmail.fm>
+
+ do not install libtiff-4.pc when tiff-install is reset.
+
+2023-04-21 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'mymaster1' into 'master'
+ fix runtime error: applying zero offset to null pointer
+
+ See merge request libtiff/libtiff!479
+
+2023-04-21 xiaoxiaoafeifei <lliangliang2007@163.com>
+
+ countInkNamesString(): fix `UndefinedBehaviorSanitizer`: applying zero offset to null pointer
+
+2023-03-26 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tif_ovrcache_TIFFSetSubDirectory' into 'master'
+ tif_ovrcache.c: check TIFFSetSubDirectory() return value (CID 1524573)
+
+ See merge request libtiff/libtiff!478
+
+2023-03-26 Even Rouault <even.rouault@spatialys.com>
+
+ tif_ovrcache.c: check TIFFSetSubDirectory() return value (CID 1524573)
+
+2023-03-26 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'even_faster_setdirectory_with_IFDlist' into 'master'
+ Even faster TIFFSetDirectory() using IFD list.
+
+ See merge request libtiff/libtiff!477
+
+2023-03-26 Su Laus <sulau@freenet.de>
+
+ Even faster TIFFSetDirectory() using IFD list.
+
+2023-03-12 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'faster-setdirectory_newMR' into 'master'
+ Optimize relative seeking with TIFFSetDirectory
+
+ See merge request libtiff/libtiff!474
+
+2023-03-12 Su Laus <sulau@freenet.de>
+
+ Optimize relative seeking with TIFFSetDirectory.
+
+2023-03-11 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'master' into 'master'
+ Fix memory leak in tiffcrop.c
+
+ See merge request libtiff/libtiff!475
+
+2023-03-08 zhailiangliang <zhailiangliang@loongson.cn>
+
+ Fix memory leak in tiffcrop.c.
+
+2023-02-23 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'skip-thumbnail-test' into 'master'
+ test: avoid running tool tests if not built
+
+ Closes #421
+
+ See merge request libtiff/libtiff!334
+
+2023-02-22 Sam James <sam@gentoo.org>
+
+ test (cmake): skip script tests if tools aren't built.
+ In Gentoo, we avoid building the tools for multilib (32-bit, x86) builds on
+ amd64/x86_64 because we only need the library to keep binary applications working.
+
+ This causes a test failure in e.g. tiffcp-thumbnail.sh as the 'thumbnail'
+ binary isn't built. Skip it if unavailable.
+
+ Fixes: https://gitlab.com/libtiff/libtiff/-/issues/421
+
+2023-02-22 Sam James <sam@gentoo.org>
+
+ test (autotools): skip script tests if tools aren't built.
+ In Gentoo, we avoid building the tools for multilib (32-bit, x86) builds on
+ amd64/x86_64 because we only need the library to keep binary applications working.
+
+ This causes a test failure in e.g. tiffcp-thumbnail.sh as the 'thumbnail'
+ binary isn't built. Skip it if unavailable.
+
+ Fixes: https://gitlab.com/libtiff/libtiff/-/issues/421
+
+2023-02-16 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_Unlink_first_directory_0' into 'master'
+ Fix TIFFUnlinkDirectory(0) case and unlink of first directory.
+
+ See merge request libtiff/libtiff!460
+
+2023-02-16 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tif_luv_check_NaN_fix_#530' into 'master'
+ tif_luv: Check and correct for NaN data in uv_encode().
+
+ Closes #530
+
+ See merge request libtiff/libtiff!473
+
+2023-02-16 Su_Laus <sulau@freenet.de>
+
+ tif_luv: Check and correct for NaN data in uv_encode().
+ Closes #530
+
+ See merge request !473
+
+2023-02-14 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffcrop_dont_reuse_input_buffer_fix_527' into 'master'
+ tiffcrop: Do not reuse input buffer for subsequent images. Fix issue 527
+
+ Closes #527
+
+ See merge request libtiff/libtiff!472
+
+2023-02-14 Su_Laus <sulau@freenet.de>
+
+ tiffcrop: Do not reuse input buffer for subsequent images. Fix issue 527
+ Reuse of read_buff within loadImage() from previous image is quite unsafe, because other functions (like rotateImage() etc.) reallocate that buffer with different size without updating the local prev_readsize value.
+
+ Closes #527
+
+2023-02-08 Su_Laus <sulau@freenet.de>
+
+ Fix 484 TIFFDirectory td_fieldsset uses unsigned long which can be 32 or 64 bits.
+ Closes #484
+
+2023-02-08 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'test_ifd_loop_detection_fix_CoverityScan_ln_55' into 'master'
+ test_ifd_loop_detection: fix Coverity Scan issue CID 1520750: Null pointer...
+
+ See merge request libtiff/libtiff!470
+
+2023-02-08 Su_Laus <sulau@freenet.de>
+
+ test_ifd_loop_detection: fix Coverity Scan issue CID 1520750: Null pointer dereferences (NULL_RETURNS) line 55.
+
+2023-02-06 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffcrop_fix_CoverityScan_line_9676' into 'master'
+ Fix Coverity Scan issue CID 1520761: Integer handling issues...
+
+ See merge request libtiff/libtiff!469
+
+2023-02-06 Su_Laus <sulau@freenet.de>
+
+ Fix Coverity Scan issue CID 1520761: Integer handling issues (OVERFLOW_BEFORE_WIDEN) tiffcrop.c: 9676 in rotateImage()
+
+2023-02-05 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffcrop_R270_fix#492' into 'master'
+ tiffcrop: Amend rotateImage() not to toggle the input (main) image width and...
+
+ Closes #519, #518, #499, #495, #494, #493 et #492
+
+ See merge request libtiff/libtiff!465
+
+2023-02-05 Su_Laus <sulau@freenet.de>
+
+ tiffcrop: Amend rotateImage() not to toggle the input (main) image width and length parameters when only cropped image sections are rotated. Remove buffptr from region structure because never used.
+ Closes #492 #493 #494 #495 #499 #518 #519
+
+2023-02-05 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffcrop_correctly_update_buffersize_after_rotate_fix#520' into 'master'
+ tiffcrop correctly update buffersize after rotateImage() fix#520
+
+ Closes #520
+
+ See merge request libtiff/libtiff!467
+
+2023-02-05 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffcrop_composite_image_assumption_test_fix#496' into 'master'
+ tiffcrop: added check for assumption on composite images (fixes #496)
+
+ Closes #501, #500, #498, #497 et #496
+
+ See merge request libtiff/libtiff!466
+
+2023-02-05 Su Laus <sulau@freenet.de>
+
+ tiffcrop: added check for assumption on composite images (fixes #496)
+ tiffcrop: For composite images with more than one region, the combined_length or combined_width always needs to be equal, respectively. Otherwise, even the first section/region copy action might cause buffer overrun. This is now checked before the first copy action.
+
+ Closes #496, #497, #498, #500, #501.
+
+2023-02-04 Su_Laus <sulau@freenet.de>
+
+ tiffcrop correctly update buffersize after rotateImage() fix#520 -- enlarge buffsize and check integer overflow within rotateImage().
+
+2023-02-04 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'test_subidf_loop' into 'master'
+ test_ifd_loop_detection: Added test to check loops in SubIFDs that are chained.
+
+ See merge request libtiff/libtiff!464
+
+2023-02-04 Su Laus <sulau@freenet.de>
+
+ test_ifd_loop_detection: Added test to check loops in SubIFDs that are chained.
+
+2023-02-04 Su_Laus <sulau@freenet.de>
+
+ Fix TIFFUnlinkDirectory(0) case and unlink of first directory.
+ If directory number 0 is unlinked, then the base offset variables within LibTiff are not updated. As a result, a subsequent TIFFSetDirectory() first goes to the unlinked former directory number 0.
+
+ In addition, the error case for dirn=0 is handled.
+
+ This MR fixes that by updating the base offset variables tif->tif_header.classic.tiff_diroff and tif->tif_header.big.tiff_diroff.
+
+2023-02-03 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'TiffClose_NULL_ptr_dereferencing_fix_515' into 'master'
+ TIFFClose() avoid NULL pointer dereferencing. fix#515
+
+ Closes #515
+
+ See merge request libtiff/libtiff!468
+
+2023-02-03 Su_Laus <sulau@freenet.de>
+
+ TIFFClose() avoid NULL pointer dereferencing. fix#515.
+ Closes #515
+
+ tiffcrop correctly update buffersize after rotateImage() fix#520 rotateImage() set up a new buffer and calculates its size individually. Therefore, seg_buffs[] size needs to be updated accordingly. Before this fix, the seg_buffs buffer size was calculated with a different formula than within rotateImage().
+ Closes #520.
+
+2023-01-25 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'add_windows_DLL_versioninfo' into 'master'
+ Add versioninfo resource files for DLL and tools compiled with Windows MSVC and MINGW.
+
+ See merge request libtiff/libtiff!455
+
+2023-01-25 Su Laus <sulau@freenet.de>
+
+ Add versioninfo resource files for DLL and tools compiled with Windows MSVC and MINGW.
+
+2023-01-22 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tif_hash_set_order_include' into 'master'
+ tif_hash_set.c: include tif_hash_set.h after tif_config.h to let a chance for...
+
+ See merge request libtiff/libtiff!462
+
+2023-01-22 Even Rouault <even.rouault@spatialys.com>
+
+ tif_hash_set.c: include tif_hash_set.h after tif_config.h to let a chance for GDAL symbol renaming trick
+
+2023-01-22 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_513' into 'master'
+ Fax3: fix failure to decode some fax3 images (fixes #513)
+
+ Closes #513
+
+ See merge request libtiff/libtiff!461
+
+2023-01-21 Even Rouault <even.rouault@spatialys.com>
+
+ Add test for Fax3 decoding issues (refs #513)
+
+2023-01-21 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffcrop_fix_#488' into 'master'
+ tiffcrop: Correct simple copy paste error. Fix #488.
+
+ Closes #488
+
+ See merge request libtiff/libtiff!459
+
+2023-01-21 Su Laus <sulau@freenet.de>
+
+ tiffcrop: Correct simple copy paste error. Fix #488.
+
+2023-01-21 Even Rouault <even.rouault@spatialys.com>
+
+ Fax3: fix failure to decode some fax3 images (fixes #513)
+ Patch by @jsummers26
+
+2023-01-12 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffmedian_fix_#477' into 'master'
+ tiffmedian: avoid zero num_colors, fixes #477
+
+ Closes #477
+
+ See merge request libtiff/libtiff!458
+
+2023-01-12 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fax2ps_fixes_#475' into 'master'
+ fax2ps: fixes #475 buffer overflow in qsort function pcompar.
+
+ Closes #475
+
+ See merge request libtiff/libtiff!457
+
+2023-01-12 Su_Laus <sulau@freenet.de>
+
+ tiffmedian: avoid zero num_colors, fixes #477.
+
+ fax2ps: fixes #475 buffer overflow in qsort function pcompar.
+
+2023-01-09 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_241_tiffset_file_size_limit' into 'master'
+ tiffset: get filesize to allocate only the required memory. Fixes issue #241
+
+ Closes #241
+
+ See merge request libtiff/libtiff!451
+
+2023-01-09 Su Laus <sulau@freenet.de>
+
+ tiffset: get filesize to allocate only the required memory. Fixes issue #241
+
+2023-01-09 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch '_TIFFCleanupIFDOffsetAndNumberMaps' into 'master'
+ Add _TIFFCleanupIFDOffsetAndNumberMaps() and call it from TIFFUnlinkDirectory()
+
+ See merge request libtiff/libtiff!454
+
+2023-01-06 Even Rouault <even.rouault@spatialys.com>
+
+ Remove use of tif_dirnumber.
+
+ TIFFSetSubDirectory(): call _TIFFCleanupIFDOffsetAndNumberMaps()
+
+ struct tiff: remove unused tif_dirlistoff.
+
+ TIFFUnlinkDirectory(): reset tif_dirnumber.
+
+ Add _TIFFCleanupIFDOffsetAndNumberMaps() and call it from TIFFUnlinkDirectory()
+
+2022-12-29 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'cmake_in_files_formatting_sensitive' into 'master'
+ Disable clang-formatting for tif_config.h.cmake.in and tiffconf.h.cmake.in...
+
+ See merge request libtiff/libtiff!452
+
+2022-12-28 Su_Laus <sulau@freenet.de>
+
+ Disable clang-formatting for tif_config.h.cmake.in and tiffconf.h.cmake.in because sensitive for CMake scripts. - explanation added
+
+2022-12-26 Su_Laus <sulau@freenet.de>
+
+ Disable clang-formatting for tif_config.h.cmake.in and tiffconf.h.cmake.in because sensitive for CMake scripts.
+
+2022-12-19 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'manpage_multi-page-TIFF' into 'master'
+ manpage: Add multi page TIFF and SubIFDs description and read / write example.
+
+ See merge request libtiff/libtiff!450
+
+2022-12-19 Su Laus <sulau@freenet.de>
+
+ manpage: Add multi page TIFF and SubIFDs description and read / write example.
+
+2022-12-18 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'TIFFOpen_r+_windows_behaviour' into 'master'
+ Behavior of TIFFOpen() mode "r+" in the Windows implementation adjusted to that of Linux.
+
+ See merge request libtiff/libtiff!449
+
+2022-12-16 Su_Laus <sulau@freenet.de>
+
+ Behavior of TIFFOpen() mode "r+" in the Windows implementation adjusted to that of Linux.
+
+2022-12-15 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'ossfuzz_54343' into 'master'
+ TIFFSetDirectory: avoid harmless unsigned-integer-overflow
+
+ See merge request libtiff/libtiff!447
+
+2022-12-15 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFSetDirectory: avoid harmless unsigned-integer-overflow.
+ Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=54343
+
+2022-12-14 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'ossfuzz_54311' into 'master'
+ TIFFWriteDirectorySec(): avoid harmless unsigned-integer-overflow
+
+ See merge request libtiff/libtiff!446
+
+2022-12-14 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFWriteDirectorySec(): avoid harmless unsigned-integer-overflow.
+ Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=54311
+
+2022-12-14 Even Rouault <even.rouault@spatialys.com>
+
+ libtiff v4.5.0rc2 preparation
+
+2022-12-14 Su_Laus <sulau@freenet.de>
+
+ tiffinfo: update curdir from uint16_t to tdir_t for more than 64k IFD handling.
+
+2022-12-13 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_502' into 'master'
+ Make TIFFSetDirectory(tiff, 65534) work again (fixes #502)
+
+ Closes #502
+
+ See merge request libtiff/libtiff!436
+
+2022-12-13 Even Rouault <even.rouault@spatialys.com>
+
+ Add tests for IFD loop detection.
+
+ Fix IFD loop detection.
+
+ Use UINT_MAX.
+
+ Make TIFF_MAX_DIR_COUNT a autoconf/CMake setting.
+
+2022-12-13 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'build-shared-by-default' into 'master'
+ Restore shared libraries by default
+
+ See merge request libtiff/libtiff!437
+
+2022-12-13 shaun walbridge <shaun.walbridge@gmail.com>
+
+ CMake: restore shared libraries by default for top-level build.
+
+2022-12-12 Even Rouault <even.rouault@spatialys.com>
+
+ Add a TIFF_MAX_DIR_COUNT public #define.
+
+ TIFFCurrentDirectory(), TIFFNumberOfDirectories(), TIFFSetDirectory(), TIFFUnlinkDirectory(): use tdir_t that is now a uint32_t, and raise limit of IFDs to 1048576
+
+ IFD loop checking: use hashmap to avoid quadratic performance.
+
+ Add a hashset/hashmap implementation (ported from GDAL's CPLHashSet)
+
+ Make TIFFSetDirectory(tiff, 65534) work again (fixes #502)
+
+2022-12-11 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'do_not_format_tiffvers_h' into 'master'
+ Revert formatting of tiffvers.h and add TIFFLIB_MAJOR_VERSION, TIFFLIB_MINOR_VERSION, TIFFLIB_MICRO_VERSION defines
+
+ See merge request libtiff/libtiff!434
+
+2022-12-11 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffcrop_exclude_some_comment_from_clang-format' into 'master'
+ tiffcrop: Exclude some comments from clang-format
+
+ See merge request libtiff/libtiff!435
+
+2022-12-11 Su Laus <sulau@freenet.de>
+
+ tiffcrop: Exclude some comments from clang-format.
+
+2022-12-11 Even Rouault <even.rouault@spatialys.com>
+
+ tiffvers.h.in: add clang-format off/on.
+
+2022-12-10 Even Rouault <even.rouault@spatialys.com>
+
+ tiffvers.h: add TIFFLIB_MAJOR_VERSION, TIFFLIB_MINOR_VERSION, TIFFLIB_MICRO_VERSION defines
+ Also add a TIFFLIB_AT_LEAST() macro
+
+ tiffvers.h: revert formatting.
+
+ Exclude reformatting of tiffvers.h which breaks version detection for FindTIFF.cmake
+
+2022-12-09 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'release_4_5_0' into 'master'
+ Prepare v4.5.0 release
+
+ See merge request libtiff/libtiff!433
+
+2022-12-09 Even Rouault <even.rouault@spatialys.com>
+
+ libtiff v4.5.0rc1 preparation
+
+2022-12-08 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'reformat' into 'master'
+ Whole code-base reformatting
+
+ See merge request libtiff/libtiff!431
+
+2022-12-08 Even Rouault <even.rouault@spatialys.com>
+
+ Add .git-blame-ignore-revs.
+
+ tiffcrop: remove version_id and rev_date.
+
+2022-12-08 pre-commit run by Even Rouault <even.rouault-bot@spatialys.com>
+
+ Reformatting in all other directories using 'pre-commit run'
+
+ Reformatting in test/ using 'pre-commit run'
+
+ Reformatting in tools/ using 'pre-commit run'
+
+ Reformatting in libtiff/ using 'pre-commit run'
+
+2022-12-08 Even Rouault <even.rouault@spatialys.com>
+
+ Add .clang-format, .pre-commit-config.yaml and CONTRIBUTING.md.
+
+ Remove vim/emacs formatting footers.
+
+2022-11-29 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_489' into 'master'
+ TIFFWriteRawStrip(): restore capabilities to append data in the current strip (fixes #489)
+
+ Closes #489
+
+ See merge request libtiff/libtiff!430
+
+2022-11-29 Even Rouault <even.rouault@spatialys.com>
+
+ Add test case for scenario of issue #489.
+
+ TIFFWriteRawStrip(): restore capabilities to append data in the current strip (fixes #489)
+ This fixes a regression of libtiff 4.4.0
+
+2022-11-29 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'manpage_re-entrant_error_handler' into 'master'
+ manpage update for re-entrant error handler TIFFErrorExtR(), TIFFOpenExt() and...
+
+ See merge request libtiff/libtiff!427
+
+2022-11-29 Su Laus <sulau@freenet.de>
+
+ manpage update for re-entrant error handler TIFFErrorExtR(), TIFFOpenExt() and...
+
+2022-11-27 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffcrop_fix_#169' into 'master'
+ tiffcrop: Add check if (bps != 1) in writeSingleSection() for...
+
+ Closes #169
+
+ See merge request libtiff/libtiff!429
+
+2022-11-27 Su Laus <sulau@freenet.de>
+
+ tiffcrop: Add check if (bps != 1) in writeSingleSection() for...
+
+2022-11-26 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'TIFFErrorExtR_fix_missing_calls' into 'master'
+ TIFFErrorExt() was not replaced with TIFFErrorExtR() everywhere in libtiff....
+
+ See merge request libtiff/libtiff!428
+
+2022-11-26 Su Laus <sulau@freenet.de>
+
+ TIFFErrorExt() was not replaced with TIFFErrorExtR() everywhere in libtiff....
+
+2022-11-25 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tif_jpeg_build_fix' into 'master'
+ tif_jpeg.c: fix compilation with MSVC (fixes commit 0fd1a81d3547acb8f5be50bbbc3e44bde01c014b)
+
+ See merge request libtiff/libtiff!426
+
+2022-11-25 Even Rouault <even.rouault@spatialys.com>
+
+ tif_jpeg.c: fix compilation with MSVC (fixes commit 0fd1a81d3547acb8f5be50bbbc3e44bde01c014b)
+
+2022-11-25 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_0fd1a81d3547acb8f5be50bbbc3e44bde01c014b' into 'master'
+ JPEGEncode(): fix wrong pointer data type with libjpeg-turbo 2.2dev in 12-bit mode
+
+ See merge request libtiff/libtiff!425
+
+2022-11-25 Even Rouault <even.rouault@spatialys.com>
+
+ JPEGEncode(): fix wrong pointer data type with libjpeg-turbo 2.2dev in 12-bit mode
+ (fixes commit 0fd1a81d3547acb8f5be50bbbc3e44bde01c014b)
+
+2022-11-25 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'libjpegturbo_dual' into 'master'
+ Add support for libjpeg-turbo 2.2-dev 8/12 bit dual mode
+
+ See merge request libtiff/libtiff!422
+
+2022-11-25 Even Rouault <even.rouault@spatialys.com>
+
+ Add support for libjpeg-turbo 2.2-dev 8/12 bit dual mode.
+
+2022-11-23 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'windows-fix' into 'master'
+ libtiff: Fix TIFFOpen* for the Windows platform in tif_unix.c
+
+ See merge request libtiff/libtiff!424
+
+2022-11-23 Francois Bleibel <fbleibel@gmail.com>
+
+ libtiff: Fix TIFFOpen* for the Windows platform in tif_unix.c.
+ I'm not sure where this change was made, but it must have been in a recent update. TIFFOpenWEx is now TIFFOpenWExt, and _TIFFgetMode takes additional arguments.
+
+ Verified: Tested libtiff on a local Windows build.
+
+2022-11-23 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffcrop_signed_vs_unsigned' into 'master'
+ tiffcrop.c: fix warning about signed vs unsigned comparison
+
+ See merge request libtiff/libtiff!423
+
+2022-11-23 Even Rouault <even.rouault@spatialys.com>
+
+ tiffcrop.c: fix warning about signed vs unsigned comparison.
+
+2022-11-23 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'TIFFClientOpenExt_warning_fix' into 'master'
+ TIFFClientOpenExt(): fix warning on 32-bit platforms (master only)
+
+ See merge request libtiff/libtiff!421
+
+2022-11-23 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFClientOpenExt(): fix warning on 32-bit platforms (master only)
+
+2022-11-23 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffcp_TIFFOpenOptionsFree_memleak_fix' into 'master'
+ tiffcp: fix leak of TIFFOpenOptionsAlloc() introduced in latest commit (master only)
+
+ See merge request libtiff/libtiff!420
+
+2022-11-23 Even Rouault <even.rouault@spatialys.com>
+
+ tiffcp: fix leak of TIFFOpenOptionsAlloc() introduced in latest commit (master only)
+ Fixes Coverity CID 1517032
+
+2022-11-23 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'TIFFOpenOptionsSetMaxSingleMemAlloc' into 'master'
+ Add TIFFOpenOptionsSetMaxSingleMemAlloc() to define a limit in bytes for a single memory allocation done by libtiff
+
+ See merge request libtiff/libtiff!419
+
+2022-11-23 Even Rouault <even.rouault@spatialys.com>
+
+ Emit explicit error message when tif_max_single_mem_alloc is exceeded.
+
+ test_open_options: test TIFFOpenOptionsSetMaxSingleMemAlloc()
+
+ Rename test_error_handlers to test_open_options.
+
+ tiffinfo, tiffcp, tiffcrop, tiffsplit, tiff2rgba, tiff2ps: use TIFFOpenOptionsSetMaxSingleMemAlloc()
+
+ Convert uses of _TIFFmalloc/realloc/calloc/free to the Ext functions.
+
+2022-11-22 Even Rouault <even.rouault@spatialys.com>
+
+ Add TIFFOpenOptionsSetMaxSingleMemAlloc()
+ to define a limit in bytes for a single memory allocation done by libtiff.
+
+ Also add internal functions used in replacement of the non Ext ones:
+ void* _TIFFmallocExt(TIFF* tif, tmsize_t s);
+ void* _TIFFcallocExt(TIFF* tif, tmsize_t nmemb, tmsize_t siz);
+ void* _TIFFreallocExt(TIFF* tif, void* p, tmsize_t s);
+ void _TIFFfreeExt(TIFF* tif, void* p);
+
+2022-11-22 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'TIFFOpenEx' into 'master'
+ Add TIFFOpenExt(), TIFFOpenWExt() and TIFFFdOpenExt() with re-entrant error handlers
+
+ See merge request libtiff/libtiff!413
+
+2022-11-21 Even Rouault <even.rouault@spatialys.com>
+
+ Remove TIFFSetErrorHandlerExtR() and TIFFSetWarningHandlerExtR() that were temporarily added in master
+
+ Add a _TIFFErrorEarly() function to be able to use the re-entrant error handler, even before TIFF* is valid
+
+ Rework TIFFOpenExt() and similar to use an opaque TIFFOpenOptions* opts argument, with alloc, free and setters
+
+ Document TIFFOpenExt, TIFFOpenWExt, TIFFFdOpenExt, TIFFClientOpenExt, TIFFSetErrorHandlerExtR, TIFFSetWarningHandlerExtR
+
+2022-11-21 Even Rouault <even.rouault@spatialys.com>
+
+ Add TIFFOpenExt(), TIFFOpenWExt() and TIFFFdOpenExt() with re-entrant error handlers
+ Rename TIFFClientOpenEx() to TIFFClientOpenExt()
+
+ Rework signature of the re-entrant error handlers and of
+ TIFFSetWarningHandlerExt() and TIFFSetErrorHandlerExt()
+
+ Use structures that can be extended as extra argument.
+
+ Leverages and ammends https://gitlab.com/libtiff/libtiff/-/merge_requests/409
+
+2022-11-21 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'manpage_fix485_file-descriptor_clientdata' into 'master'
+ manpage: Correct description of file handle/descriptors tif_fd and tif_clientdata. Closes #485.
+
+ Closes #485
+
+ See merge request libtiff/libtiff!418
+
+2022-11-21 Su Laus <sulau@freenet.de>
+
+ manpage: Correct description of file handle/descriptors tif_fd and tif_clientdata. Closes #485.
+
+2022-11-20 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'manpage_fix440_fix28_TIFFOpen_SubIFD_update' into 'master'
+ manpage: fix28, fix440, update TIFFOpen and SubIFD
+
+ Closes #440 et #28
+
+ See merge request libtiff/libtiff!417
+
+2022-11-20 Su Laus <sulau@freenet.de>
+
+ manpage: fix28, fix440, update TIFFOpen and SubIFD.
+
+2022-11-17 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'cmake_tiff_install_warning' into 'master'
+ CMakeLists.txt: fix warning with -Wdev
+
+ See merge request libtiff/libtiff!416
+
+2022-11-13 Even Rouault <even.rouault@spatialys.com>
+
+ CMakeLists.txt: fix warning with -Wdev.
+ ```
+ CMake Warning (dev) at CMakeLists.txt:62 (option):
+ Policy CMP0077 is not set: option() honors normal variables. Run "cmake
+ --help-policy CMP0077" for policy details. Use the cmake_policy command to
+ set the policy and suppress this warning.
+
+ For compatibility with older versions of CMake, option is clearing the
+ normal variable 'tiff-install'.
+ This warning is for project developers. Use -Wno-dev to suppress it.
+ ```
+
+2022-11-12 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_479' into 'master'
+ _TIFFReadEncodedTileAndAllocBuffer(): avoid excessive memory allocation on...
+
+ See merge request libtiff/libtiff!412
+
+2022-11-12 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'typo_fix' into 'master'
+ tif_dirread.c: fix typo in comment
+
+ See merge request libtiff/libtiff!414
+
+2022-11-12 Even Rouault <even.rouault@spatialys.com>
+
+ tif_dirread.c: fix typo in comment.
+
+2022-11-11 Even Rouault <even.rouault@spatialys.com>
+
+ _TIFFReadEncodedTileAndAllocBuffer(): avoid excessive memory allocation on broken files (fixes #479)
+
+2022-11-10 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bugfix/tiff2pdf-stdout' into 'master'
+ tiff2pdf Don't try to seek into stdout.
+
+ See merge request libtiff/libtiff!367
+
+2022-11-10 Claus-Justus Heine <himself@claus-justus-heine.de>
+
+ tiff2pdf: Don't try to seek into stdout.
+ Fixes #441
+
+2022-11-08 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_coverity_1516759' into 'master'
+ TIFFErrorExtR(): fix Dereference after null check (CID 1516759)
+
+ See merge request libtiff/libtiff!411
+
+2022-11-08 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_ossfuzz_53137' into 'master'
+ TIFFReadRGBATileExt(): fix (unsigned) integer overflow on strips/tiles > 2 GB
+
+ See merge request libtiff/libtiff!410
+
+2022-11-08 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFErrorExtR(): fix Dereference after null check (CID 1516759)
+
+2022-11-08 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'no_sprintf' into 'master'
+ Replace sprintf calls with snprintf
+
+ See merge request libtiff/libtiff!408
+
+2022-11-08 Mark Mentovai <mark@chromium.org>
+
+ Replace sprintf calls with snprintf.
+ This makes it possible to build libtiff without warnings using the macOS
+ 13 SDK. Calls to sprintf are replaced with snprintf, passing appropriate
+ buffer sizes.
+
+ It doesn’t appear that any of the changed uses of sprintf were actually
+ unsafe, so no behavior change is expected aside from SDK compatibility.
+
+ The macOS 13 SDK deprecates sprintf as it’s difficult to use safely. The
+ deprecation warning message is visible when building C++, but it is not
+ normally visible when building plain C code due to a quirk in how
+ sprintf is declared in the SDK. However, the deprecation message is
+ visible when building plain C under Address Sanitizer
+ (-fsanitize=address). This discrepancy was discovered at
+ https://crbug.com/1381706 and reported to Apple with a copy at
+ https://openradar.appspot.com/FB11761475.
+
+ The macOS 13 SDK is packaged in Xcode 14.1, released on 2022-11-01. This
+ also affects the iOS 16 SDK and other 2022-era Apple OS SDKs packaged in
+ Xcode 14.0, released on 2022-09-12.
+
+ libtiff is visible to the Chromium build via PDFium, and this change is
+ needed to allow Chromium to move forward to the macOS 13 SDK.
+
+ This change is limited to the libtiff directory. Other uses of sprintf
+ were found in contrib, test, and tools.
+
+2022-11-08 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'reentrant' into 'master'
+ Add reentrant error functions
+
+ See merge request libtiff/libtiff!409
+
+2022-11-08 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFReadRGBATileExt(): fix (unsigned) integer overflow on strips/tiles > 2 GB
+ Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53137
+
+2022-11-08 Laramie Leavitt <lar@google.com>
+
+ Add reentrant error functions.
+ Prior to this change, libtiff relied on global error handlers,
+ which is problematic when libtiff used by multiple independent
+ libraries from within the same process, as they may unwittingly
+ clobber the error handling, introduce race conditions when setting
+ handlers, or otherwise have unintended side effects.
+
+ This change adds error handlers to the TIFF struct, which are
+ used preferentially when available. The error handlers are invoked
+ when the re-entrant error functions are called:
+
+ void TIFFErrorExtR(TIFF*, const char* module, const char* fmt, ...)
+ void TIFFWarningExtR(TIFF*, const char* module, const char* fmt, ...)
+
+ The handlers have a similar signature to the existing extended
+ handlers, additionally returning an int:
+
+ int TIFFErrorHandlerExtR(thandle_t, const char*, const char*, va_list)
+
+ thandle_t is the userdata passed to TIFFOpen
+ When the handler returns 1, the global handlers are not called.
+
+ Custom error/warning handlers may be installed on a per-file
+ basis by calling the Set functions:
+
+ TIFF* tif = TIFFOpen(...);
+ TIFFSetErrorHandlerExtR(tif, MyErrorHandler);
+ TIFFSetWarningHandlerExtR(tif, MyWarningHandler);
+
+ Additionally, the callsites to TIFFErrorExt and TIFFWarningExt
+ have been updated to call the reentrant versions.
+
+2022-11-08 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffcrop_fix_CoverityScan_tmsize_issue' into 'master'
+ tiffcrop: should fix some Coverity Scan issues OVERFLOW_BEFORE_WIDEN
+
+ See merge request libtiff/libtiff!403
+
+2022-11-08 Su Laus <sulau@freenet.de>
+
+ tiffcrop: should fix some Coverity Scan issues OVERFLOW_BEFORE_WIDEN.
+
+2022-11-02 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'typo_fix' into 'master'
+ tif_dirread.c: fix typo in comment
+
+ See merge request libtiff/libtiff!407
+
+2022-11-02 Even Rouault <even.rouault@spatialys.com>
+
+ tif_dirread.c: fix typo in comment.
+
+2022-10-23 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffcrop_formatting_fix' into 'master'
+ tiffcrop: add casts in TIFFError() to fix compiler warnings
+
+ See merge request libtiff/libtiff!406
+
+2022-10-23 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_482' into 'master'
+ CMake: correctly set default value of 'lzma' option when liblzma is detected (fixes #482)
+
+ Closes #482
+
+ See merge request libtiff/libtiff!404
+
+2022-10-23 Even Rouault <even.rouault@spatialys.com>
+
+ tiffcrop: add casts in TIFFError() to fix compiler warnings.
+
+ CMake: correctly set default value of 'lzma' option when liblzma is detected (fixes #482)
+
+2022-10-20 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_480' into 'master'
+ Fix incorrect printf() formatters introduced in recent commits (fixes #480)
+
+ Closes #480
+
+ See merge request libtiff/libtiff!401
+
+2022-10-19 Even Rouault <even.rouault@spatialys.com>
+
+ Fix incorrect printf() formatters introduced in recent commits (fixes #480)
+
+2022-10-13 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'CLIPPATH_tags_corrected' into 'master'
+ CLIPPATH tags defined twice but differently and also wrongly (#439) - corrected
+
+ Closes #439
+
+ See merge request libtiff/libtiff!366
+
+2022-10-13 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'FIELD_IGNORE_warning-messages' into 'master'
+ Warning messages for FIELD_IGNORE tags for writing and for TIFF_SETGET_UNDEFINED for reading added. (#438)
+
+ Closes #438
+
+ See merge request libtiff/libtiff!365
+
+2022-10-13 Su Laus <sulau@freenet.de>
+
+ Warning messages for FIELD_IGNORE tags for writing and for TIFF_SETGET_UNDEFINED for reading added. (#438)
+
+2022-10-13 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tag-def_COMPRESSION_corrected' into 'master'
+ tif_dirinfo.c TIFFTAG_COMPRESSION and _BITSPERSAMPLE definition corrected
+
+ See merge request libtiff/libtiff!364
+
+2022-10-13 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_getopt_included_twice' into 'master'
+ Fix including module getopt.c twice with CMake and HAVE_GETOPT=false
+
+ See merge request libtiff/libtiff!381
+
+2022-10-13 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffcrop_CoverityScan_fix_PRINTF_ARGS' into 'master'
+ tiffcrop: fix Coverity Scan issues about PRINTF_ARGS.
+
+ See merge request libtiff/libtiff!400
+
+2022-10-13 Su_Laus <sulau@freenet.de>
+
+ tiffcrop fix Coverity Scan issues about PRINTF_ARGS.
+
+2022-10-13 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffcrop_fix_#450_too-many-mode-options' into 'master'
+ tiffcrop: fix #450 too many 'mode' options on command line.
+
+ Closes #470 et #450
+
+ See merge request libtiff/libtiff!384
+
+2022-10-13 Su Laus <sulau@freenet.de>
+
+ tiffcrop: fix #450 too many 'mode' options on command line.
+
+2022-10-13 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffcrop_fix_#435' into 'master'
+ tiffcrop subroutines require a larger buffer (fixes #271, #381, #386, #388, #389, #435)
+
+ Closes #465, #464, #435, #389, #388, #386, #381 et #271
+
+ See merge request libtiff/libtiff!382
+
+2022-10-13 Su Laus <sulau@freenet.de>
+
+ tiffcrop subroutines require a larger buffer (fixes #271, #381, #386, #388, #389, #435)
+
+2022-10-12 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'InkNames_NumberOfInks_handling_revised' into 'master'
+ Revised handling of TIFFTAG_INKNAMES and related TIFFTAG_NUMBEROFINKS value (fixes #149, #150, #152, #168, #250, #269, #398 and #456)
+
+ Closes #474, #463, #387, #456, #398, #269, #250, #168, #152, #150 et #149
+
+ See merge request libtiff/libtiff!385
+
+2022-10-12 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffcrop_fix_#411_#413' into 'master'
+ tiffcrop: disable incompatibility of -Z, -X, -Y, -z options with any PAGE_MODE_x option (fixes #411, #413 and #426)
+
+ Closes #426, #413 et #411
+
+ See merge request libtiff/libtiff!383
+
+2022-10-10 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'TIFFAdvanceDirectory_mapped_uio' into 'master'
+ TIFFAdvanceDirectory(): fix unsigned-integer-overflow in mapped case
+
+ See merge request libtiff/libtiff!398
+
+2022-10-10 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFAdvanceDirectory(): fix unsigned-integer-overflow in mapped case.
+ Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52309
+
+2022-10-08 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffinfo_parse_SubIFDs' into 'master'
+ tiffinfo: Updated to parse through SubIFDs and show their tags.
+
+ See merge request libtiff/libtiff!396
+
+2022-10-08 Su Laus <sulau@freenet.de>
+
+ tiffinfo: Updated to parse through SubIFDs and show their tags.
+
+2022-10-07 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'master' into 'master'
+ Moved linking of CMath::CMath into CMath_LIBRARY check
+
+ See merge request libtiff/libtiff!397
+
+2022-10-07 Frei Herr <herr.frei@googlemail.com>
+
+ Moved linking of CMath::CMath into CMath_LIBRARY check.
+
+2022-10-06 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'rational_precision2double_coverity-fix' into 'master'
+ rational_precision2double.c: Fix issue from Coverity Scan.
+
+ See merge request libtiff/libtiff!395
+
+2022-10-06 Su_Laus <sulau@freenet.de>
+
+ rational_precision2double.c: Fix issue from Coverity Scan.
+
+ Fix including module getopt.c twice with CMake and HAVE_GETOPT=false.
+ The "make-files" for the tools- and test- programmes include the module getopt.c once directly as additional source and then again by including port.lib.
+ This can be avoided by including getopt.c as source in port.lib within port\CMakeLists.txt not with PUBLIC but with PRIVATE.
+
+2022-10-06 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix-455_Improved-IFD-loop-handling' into 'master'
+ Improved IFD-Loop Handling (fixes #455)
+
+ Closes #455
+
+ See merge request libtiff/libtiff!386
+
+2022-10-06 Su Laus <sulau@freenet.de>
+
+ Improved IFD-Loop Handling (fixes #455)
+ IFD infinite looping was not fixed by MR 20 (see #455).
+ An improved IFD loop handling is proposed.
+
+ Basic approach:
+
+ - The order in the entire chain must be checked, and not only whether an offset has already been read once.
+ - To do this, pairs of directory number and offset are stored and checked.
+ - The offset of a directory number can change.
+ - TIFFAdvanceDirectory() must also perform an IFD loop check.
+ - TIFFCheckDirOffset() is replaced by _TIFFCheckDirNumberAndOffset().
+
+ Rules for the check:
+
+ - If an offset is already in the list, it must have the same IFD number. Otherwise it is an IDF loop.
+ - If the offset is not in the list and the IFD number is greater than there are list entries, a new list entry is added.
+ - Otherwise, the offset of the IFD number is updated.
+
+ Reference is also made to old bugzilla bug 2772 and MR 20, which did not solve the general issue.
+ This MR closes #455
+
+2022-10-05 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'fix-cmake-subproject' into 'master'
+ Fix CMake build to be compatible with FetchContent
+
+ See merge request libtiff/libtiff!394
+
+2022-10-04 Timothy Lyanguzov <theta682@gmail.com>
+
+ Apply 9 suggestion(s) to 3 file(s)
+
+2022-10-04 Jeremy Maitin-Shepard <jbms@google.com>
+
+ Fix CMake build to be compatible with FetchContent.
+ Recent versions of CMake have improved support for including
+ dependencies, using the FetchContent module, which allows a dependency
+ to be imported as a subproject and then later found automatically by
+ calls to `find_package`.
+
+ This change makes libtiff's CMake better behaved when used as a
+ sub-project:
+
+ - CMake has a single global namespace for all target names in all
+ sub-projects. This commit renames the following CMake targets:
+
+ - port -> tiff_port
+ - mkg3states -> tiff_mkg3states
+ - faxtable -> tiff_faxtable
+ - release -> tiff_release
+
+ - When building TIFF as a sub-project, it is not normally useful to
+ create install rules for its targets. This commit adds a
+ `tiff-install` option that controls whether the install rules are
+ added and defaults to OFF when libtiff is included as a sub-project.
+
+ - Previously, libtiff set `BUILD_SHARED_LIBS` to ON by default. With
+ this commit, that default is only set if libtiff is the top-level
+ project.
+
+ - When using `find_package(TIFF)`, the targets `TIFF::TIFF` and
+ `TIFF::CXX` are defined. This commit makes libtiff itself define
+ those targets as aliases, to allow other cmake projects to use
+ either `find_package` or `FetchContent` interchangeably.
+
+ - Adds ZSTD_HAVE_DECOMPRESS_STREAM variable which may be set to bypass
+ `check_symbol_exists` call. Fixes
+ https://gitlab.com/libtiff/libtiff/-/issues/472.
+
+2022-09-27 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'getimage_overflow' into 'master'
+ Update getimage to support reading large raster images
+
+ See merge request libtiff/libtiff!389
+
+2022-09-26 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'MinGW-warnings_ipctutil' into 'master'
+ Fix #458: MinGW Windows 64: warning because 'long' is a 32 bits type in...
+
+ Closes #458
+
+ See merge request libtiff/libtiff!391
+
+2022-09-26 Su Laus <sulau@freenet.de>
+
+ Fix #458: MinGW Windows 64: warning because 'long' is a 32 bits type in...
+
+2022-09-16 Eric Siegel <siegel.eric@gmail.com>
+
+ Update getimage to support large raster images.
+
+2022-09-08 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'typo_fix' into 'master'
+ tif_lzw.c: fix typo in code comment
+
+ See merge request libtiff/libtiff!387
+
+2022-09-08 Even Rouault <even.rouault@spatialys.com>
+
+ tif_lzw.c: fix typo in code comment.
+
+2022-08-30 Su_Laus <sulau@freenet.de>
+
+ Revised handling of TIFFTAG_INKNAMES and related TIFFTAG_NUMBEROFINKS value
+ In order to solve the buffer overflow issues related to TIFFTAG_INKNAMES and related TIFFTAG_NUMBEROFINKS value, a revised handling of those tags within LibTiff is proposed:
+
+ Behaviour for writing:
+ `NumberOfInks` MUST fit to the number of inks in the `InkNames` string.
+ `NumberOfInks` is automatically set when `InkNames` is set.
+ If `NumberOfInks` is different to the number of inks within `InkNames` string, that will be corrected and a warning is issued.
+ If `NumberOfInks` is not equal to samplesperpixel only a warning will be issued.
+
+ Behaviour for reading:
+ When reading `InkNames` from a TIFF file, the `NumberOfInks` will be set automatically to the number of inks in `InkNames` string.
+ If `NumberOfInks` is different to the number of inks within `InkNames` string, that will be corrected and a warning is issued.
+ If `NumberOfInks` is not equal to samplesperpixel only a warning will be issued.
+
+ This allows the safe use of the NumberOfInks value to read out the InkNames without buffer overflow
+
+ This MR will close the following issues: #149, #150, #152, #168 (to be checked), #250, #269, #398 and #456.
+
+ It also fixes the old bug at http://bugzilla.maptools.org/show_bug.cgi?id=2599, for which the limitation of `NumberOfInks = SPP` was introduced, which is in my opinion not necessary and does not solve the general issue.
+
+2022-08-25 Su_Laus <sulau@freenet.de>
+
+ tiffcrop: disable incompatibility of -Z, -X, -Y, -z options with any PAGE_MODE_x option (fixes #411 and #413)
+ tiffcrop does not support –Z, -z, -X and –Y options together with any other PAGE_MODE_x options like -H, -V, -P, -J, -K or –S.
+
+ Code analysis:
+
+ With the options –Z, -z, the crop.selections are set to a value > 0. Within main(), this triggers the call of processCropSelections(), which copies the sections from the read_buff into seg_buffs[].
+ In the following code in main(), the only supported step, where that seg_buffs are further handled are within an if-clause with if (page.mode == PAGE_MODE_NONE) .
+
+ Execution of the else-clause often leads to buffer-overflows.
+
+ Therefore, the above option combination is not supported and will be disabled to prevent those buffer-overflows.
+
+ The MR solves issues #411 and #413.
+
+2022-08-21 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffcrop_S-option_mutually_exclusive' into 'master'
+ tiffcrop: -S option mutually exclusive (fixes #349, #414, #422, #423, #424)
+
+ Closes #424, #423, #422, #414 et #349
+
+ See merge request libtiff/libtiff!378
+
+2022-08-20 Su_Laus <sulau@freenet.de>
+
+ tiffcrop -S option: Make decision simpler.
+
+2022-08-20 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'remove_death_commented_code' into 'master'
+ Remove dead code from tif_dirread.c, tif_dirwrite.c and tif_getimage.c
+
+ See merge request libtiff/libtiff!380
+
+2022-08-20 Su Laus <sulau@freenet.de>
+
+ Remove dead code from tif_dirread.c, tif_dirwrite.c and tif_getimage.c.
+
+2022-08-16 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'coverity_fixes' into 'master'
+ Silence Coverity Scan false positive warnings about out-of-bounds access
+
+ See merge request libtiff/libtiff!379
+
+2022-08-16 Even Rouault <even.rouault@spatialys.com>
+
+ tif_zip.c: silence Coverity Scan false positive warnings about out-of-bounds access (CID 1491190, 1491197, 1491201)
+
+ tif_dirread.c: silence Coverity Scan false positive warnings about out-of-bounds access (CID 1491182, 1491186)
+
+2022-08-16 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'default_tag_values_extended' into 'master'
+ Presetting of default tag values extended (e.g. PlanarConfig). (fixes #449)
+
+ Closes #449
+
+ See merge request libtiff/libtiff!377
+
+2022-08-16 Su Laus <sulau@freenet.de>
+
+ Presetting of default tag values extended (e.g. PlanarConfig). (fixes #449)
+
+2022-08-15 Su_Laus <sulau@freenet.de>
+
+ According to Richard Nolde https://gitlab.com/libtiff/libtiff/-/issues/401#note_877637400 the tiffcrop option „-S“ is also mutually exclusive to the other crop options (-X|-Y), -Z and -z.
+ This is now checked and ends tiffcrop if those arguments are not mutually exclusive.
+
+ This MR will fix the following tiffcrop issues: #349, #414, #422, #423, #424
+
+2022-08-09 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'warning_fix' into 'master'
+ Fix warning about shadowing
+
+ See merge request libtiff/libtiff!376
+
+2022-08-09 Even Rouault <even.rouault@spatialys.com>
+
+ Fix warning about shadowing.
+
+2022-08-09 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_225' into 'master'
+ Deal with RichTIFFIPTC tag written with LONG type (fixes #225)
+
+ Closes #225
+
+ See merge request libtiff/libtiff!374
+
+2022-08-09 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'Writing_IFD8_to_ClassicTIFF_bugfix' into 'master'
+ Correcting defects reported by Coverity Scan for MR !369
+
+ See merge request libtiff/libtiff!375
+
+2022-08-09 Su Laus <sulau@freenet.de>
+
+ Correcting defects reported by Coverity Scan for MR !369.
+
+2022-08-09 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_442_Writing_IFD8_to_ClassicTIFF' into 'master'
+ TIFFSetValue(): Writing IFD8 & LONG8 tags to ClassicTIFF corrected (fixes #442)
+
+ Closes #442
+
+ See merge request libtiff/libtiff!369
+
+2022-08-09 Su Laus <sulau@freenet.de>
+
+ TIFFSetValue(): Writing IFD8 & LONG8 tags to ClassicTIFF corrected (fixes #442)
+
+2022-08-09 Even Rouault <even.rouault@spatialys.com>
+
+ Deal with RichTIFFIPTC tag written with LONG type (fixes #225)
+
+2022-08-07 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'manpage-functions-added' into 'master'
+ doc: Missing public functions added to TIFF documentation in Sphinx
+
+ See merge request libtiff/libtiff!372
+
+2022-08-07 Su Laus <sulau@freenet.de>
+
+ doc: Missing public functions added to TIFF documentation in Sphinx.
+
+2022-07-29 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tifjpeg_version_check' into 'master'
+ tif_jpeg.c: allow to pass -DEXPECTED_JPEG_LIB_VERSION=number to do optional...
+
+ See merge request libtiff/libtiff!373
+
+2022-07-29 Even Rouault <even.rouault@spatialys.com>
+
+ tif_jpeg.c: allow to pass -DEXPECTED_JPEG_LIB_VERSION=number to do optional compile-time version check
+
+2022-07-21 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'TIFFReadFromUserBuffer_fix' into 'master'
+ TIFFReadFromUserBuffer(): fix clearing of TIFF_CODERSETUP flag that could...
+
+ See merge request libtiff/libtiff!371
+
+2022-07-21 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFReadFromUserBuffer(): fix clearing of TIFF_CODERSETUP flag that could cause issues with reading JPEG compressed files
+
+2022-07-21 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'vs2022-fixes' into 'master'
+ cmake: Correct duplicate definition of _CRT_SECURE_NO_WARNINGS
+
+ Closes #443
+
+ See merge request libtiff/libtiff!370
+
+2022-07-13 Roger Leigh <rleigh@codelibre.net>
+
+ cmake: Correct duplicate definition of _CRT_SECURE_NO_WARNINGS.
+
+2022-07-13 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'vs2022-fixes' into 'master'
+ cmake: Fixes for Visual Studio 2022
+
+ See merge request libtiff/libtiff!368
+
+2022-07-13 Roger Leigh <rleigh@codelibre.net>
+
+ cmake: Fixes for Visual Studio 2022.
+
+2022-07-03 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'elf-symbol-export' into 'master'
+ Explicit export of versioned ELF symbols
+
+ Closes #437
+
+ See merge request libtiff/libtiff!361
+
+2022-07-03 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_433' into 'master'
+ _TIFFCheckFieldIsValidForCodec(): return FALSE when passed a codec-specific...
+
+ Closes #433
+
+ See merge request libtiff/libtiff!363
+
+2022-07-01 Su_Laus <sulau@freenet.de>
+
+ CLIPPATH tags defined twice but differently and also wrongly.
+ In tif_dirinfo.c the tags for clippath are wrongly defined and the tag TIFFTAG_XCLIPPATHUNITS is even different twice. Therefore, those tags cannot be written / read correctly and may even lead to buffer overflow.
+ E.g.: In the case of TIFFSetField(YCLIPPATHUNITS), a 1 byte storage space is allocated because of TIFF_SETGET_UNDEFINED, in which an int32_t value should be stored because of TIFF_SLONG type definition. Then, an int32_t value is read from that 1 byte storage location.
+
+ The current definition is:
+
+ { TIFFTAG_CLIPPATH, -1, -3, TIFF_BYTE, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ClipPath", NULL },
+ { TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_SLONG, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL },
+ { TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_SBYTE, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL },
+ { TIFFTAG_YCLIPPATHUNITS, 1, 1, TIFF_SLONG, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YClipPathUnits", NULL },
+
+ Whereas the correct definition according to TIFF Specification Supplement 1 (https://www.awaresystems.be/imaging/tiff/specification/TIFFPM6.pdf) should be:
+
+ { TIFFTAG_CLIPPATH, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ClipPath", NULL },
+ { TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL },
+ { TIFFTAG_YCLIPPATHUNITS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YClipPathUnits", NULL },
+
+ Also the set_get_field of the following tag should be corrected from
+
+ { TIFFTAG_INTEROPERABILITYIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InteroperabilityIFDOffset", NULL },
+ to
+ { TIFFTAG_INTEROPERABILITYIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InteroperabilityIFDOffset", NULL },
+
+ However, if those tags schould not be handled by LibTiff because they are deamed as abandoned or unwanted tags, those tags need to be defined with FIELD_IGNORE instead of FIELD_CUSTOM and keeping set_field_type = TIFF_SETGET_UNDEFINED
+
+2022-07-01 Su_Laus <sulau@freenet.de>
+
+ In tif_dirinfo.c the definition for TIFFTAG_COMPRESSION has different settings of field_readcount=TIFF_VARIABLE (-1) and field_writecount=1. The tag is defined with Count=1, thus field_readcount is wrong and should also be 1. Although TIFFTAG_BITSPERSAMPLE is defined with Count:N=SamplesPerPixel, only ONE uint16_t value is passed with TIFFSetField() and TIFFGetField(). However, an array with N=SamplesPerPixel equal values is written into the TIFF file. Shouldn't field_readcount = field_writecount = 1 then? The behaviour of TiffLib does not change, because the handling is coded directly.
+
+2022-06-27 Even Rouault <even.rouault@spatialys.com>
+
+ _TIFFCheckFieldIsValidForCodec(): return FALSE when passed a codec-specific tag and the codec is not configured (fixes #433)
+ This avoids crashes when querying such tags
+
+2022-06-27 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch '16bit_cielab' into 'master'
+ add basic 16bit-cielab support
+
+ See merge request libtiff/libtiff!336
+
+2022-06-27 Caolán McNamara <caolan@skynet.ie>
+
+ Add basic 16bit-cielab support.
+ just a copy of putcontig8bitCIELab that reads 16bit vals but divide l by
+ 257, a and b by 256 before passing to TIFFCIELabToXYZ
+
+ motivation: https://bugs.documentfoundation.org/show_bug.cgi?id=131199
+ the "clavijo16bitlab.tiff" example where tiffinfo says:
+ ```
+ Image Width: 2601 Image Length: 3503
+ Resolution: 96, 96 pixels/inch
+ Bits/Sample: 16
+ Compression Scheme: AdobeDeflate
+ Photometric Interpretation: CIE L*a*b*
+ Orientation: row 0 top, col 0 lhs
+ Samples/Pixel: 3
+ Rows/Strip: 1
+ Planar Configuration: single image plane
+ DateTime: 2020:03:07 10:20:42
+ ```
+
+2022-06-24 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'manpage-fixes' into 'master'
+ Sphinx documentation fixes
+
+ See merge request libtiff/libtiff!362
+
+2022-06-24 Roger Leigh <rleigh@codelibre.net>
+
+ doc: Correct types and cross-references.
+
+ doc: Correct manual page path.
+
+ build: Make rational2double static only for automake.
+ This copies the same logic as used by CMake.
+
+ build: Update autoconf version to 4.5.0 and soname to 6.0.0.
+
+ build: Update autoconf ld-version-script default.
+
+ libtiff: Correct version script for changes since v4.4.0.
+
+ libtiff: Update version script documentation.
+
+ libtiff: Add symbol versioning of all exported symbols.
+
+2022-06-24 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'webp_mem_improvements' into 'master'
+ WEBP codec: avoid temporary buffer and memcpy() on whole tile/strip decoding
+
+ See merge request libtiff/libtiff!360
+
+2022-06-24 Roger Leigh <rleigh@codelibre.net>
+
+ build: Enable symbol versioning by default.
+
+2022-06-24 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'sphinx-manpages' into 'master'
+ doc: Add Sphinx conversion of all manpages
+
+ Closes #361
+
+ See merge request libtiff/libtiff!356
+
+2022-06-24 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'remove-wince' into 'master'
+ Remove obsolete WinCE source file
+
+ See merge request libtiff/libtiff!357
+
+2022-06-23 Even Rouault <even.rouault@spatialys.com>
+
+ WEBP codec: avoid temporary buffer and memcpy() on whole tile/strip decoding
+
+2022-06-22 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'horAcc8_fix' into 'master'
+ tif_predict.c: make horAcc8() work with icc (ICC) 2021.6.0 20220226 -O2
+
+ See merge request libtiff/libtiff!359
+
+2022-06-22 Even Rouault <even.rouault@spatialys.com>
+
+ tif_predict.c: make horAcc8() work with icc (ICC) 2021.6.0 20220226 -O2.
+ For a reason I don't understand, recent ICC generates wrong code in -O2
+ mode for the stride = 3 and 4 cases. The modified code is more
+ straightfoward, so go for it.
+
+2022-06-19 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'ci-restore-old' into 'master'
+ ci: Restore testing with Ubuntu 20.04
+
+ See merge request libtiff/libtiff!358
+
+2022-06-19 Roger Leigh <rleigh@codelibre.net>
+
+ ci: Restore testing with Ubuntu 20.04.
+
+ Remove obsolete WinCE source file.
+
+ doc: Add missing punctuation.
+
+ doc: Remove semicolon from c:function definition.
+
+ doc: Remove remaining HTML entities.
+
+ doc: Improve the build page.
+
+2022-06-18 Roger Leigh <rleigh@codelibre.net>
+
+ doc: Add Sphinx conversion of all manpages.
+
+2022-06-18 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'dist-html' into 'master'
+ build: Distribute and install HTML documentation
+
+ See merge request libtiff/libtiff!352
+
+2022-06-13 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'pkgconfig' into 'master'
+ Adding Requires.private generation
+
+ See merge request libtiff/libtiff!355
+
+2022-06-13 Yishen Miao <mys721tx@gmail.com>
+
+ Adding Requires.private generation.
+ Adds Requires.private generation so that pkg-config can correctly find
+ the dependencies of libtiff.
+
+2022-06-11 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'ci-dist' into 'master'
+ ci: Archive distribution tar and zip files
+
+ See merge request libtiff/libtiff!354
+
+2022-06-11 Roger Leigh <rleigh@codelibre.net>
+
+ ci: Archive distribution tar and zip files.
+
+2022-06-11 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'export_TIFFClampDoubleToUInt32' into 'master'
+ libtiff.def: export _TIFFClampDoubleToUInt32
+
+ See merge request libtiff/libtiff!353
+
+2022-06-11 Even Rouault <even.rouault@spatialys.com>
+
+ libtiff.def: export _TIFFClampDoubleToUInt32.
+
+2022-06-11 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-415+427+428' into 'master'
+ fix the FPE in tiffcrop (#415, #427, and #428)
+
+ Closes #428, #427 et #415
+
+ See merge request libtiff/libtiff!346
+
+2022-06-11 4ugustus <wangdw.augustus@qq.com>
+
+ fix the FPE in tiffcrop (#415, #427, and #428)
+
+2022-06-11 Roger Leigh <rleigh@codelibre.net>
+
+ build: Distribute and install HTML documentation.
+
+2022-06-10 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tif_jpeg_warning_fix' into 'master'
+ tif_jpeg.c: fix error message
+
+ See merge request libtiff/libtiff!351
+
+2022-06-10 Even Rouault <even.rouault@spatialys.com>
+
+ tif_jpeg.c: fix error message.
+
+2022-06-10 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'android_libm' into 'master'
+ Fix dependency on libm on Android
+
+ See merge request libtiff/libtiff!350
+
+2022-06-09 Matthias Kuhn <matthias@opengis.ch>
+
+ Always link to libm if available.
+
+2022-06-05 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'vasyl5-master-patch-97651' into 'master'
+ libtoolize: command not found on macOS.
+
+ See merge request libtiff/libtiff!289
+
+2022-06-05 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'rst-docs' into 'master'
+ Convert HTML documentation to Sphinx RST
+
+ See merge request libtiff/libtiff!349
+
+2022-06-05 Roger Leigh <rleigh@codelibre.net>
+
+ Merge remote-tracking branch 'origin/master' into rst-docs.
+
+2022-06-05 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'cmake-xc-faxtable' into 'master'
+ cmake: Do not build faxtable target when cross-compiling
+
+ See merge request libtiff/libtiff!342
+
+2022-06-05 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'cmake-disable-options' into 'master'
+ Add options for disabling tools, tests, contrib and docs
+
+ See merge request libtiff/libtiff!343
+
+2022-06-05 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'cmake-msvc-options' into 'master'
+ cmake: Add MSVC options when building all libraries and executables
+
+ See merge request libtiff/libtiff!344
+
+2022-06-05 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'cmake-win32-libtiffxx-static' into 'master'
+ cmake: libtiffxx is static on win32
+
+ See merge request libtiff/libtiff!338
+
+2022-06-05 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'licence-file' into 'master'
+ Rename COPYRIGHT to LICENSE.md
+
+ See merge request libtiff/libtiff!345
+
+2022-06-05 Roger Leigh <rleigh@codelibre.net>
+
+ Rename COPYRIGHT to LICENSE.md.
+
+ doc: Fix make distcheck.
+
+ doc: Update automake configuration.
+
+ doc: Do not pass srcdir and builddir to sphinx-build.
+
+ doc: Additional top-level tidying.
+
+ doc: Tidy top-level index.
+
+ doc: Move bugs to project.
+
+ doc: Move misc to project.
+
+ doc: Move all BigTIFF documentation into specification directory.
+ * Remove the BigTIFF proposal since this has long been completed
+ * Update the BigTIFF PR to note completion of the work and replace
+ present with past tense.
+
+ doc: Split release history.
+ This permits the newer releases to be included in the top-level
+ toctree without polluting it with dozens of old releases.
+
+ doc: Correct accents.
+
+ doc: BigTIFF design markup improvements.
+
+ Add doc/_static.
+
+ doc: Move TIFF specification and design notes into subdirectory.
+
+ doc: Move releases into subdirectory.
+
+ doc: Mark up TIFF tech note 2.
+
+ doc: Use sphinxdox theme.
+ The sphix_rtd_theme formats complex tables badly.
+
+ doc: Clean up HTML tags.
+
+2022-06-04 Roger Leigh <rleigh@codelibre.net>
+
+ ci: Install Sphinx manual for use by GitLab pages.
+
+ doc: Use sphinx_rtd_theme.
+
+ Convert HTML documentation to Sphinx RST.
+ * Add CMake build logic
+ * Add Autotools build logic
+ * Move from html/ to doc/
+ * Manual pages are still generated HTML for the time being
+
+ git: Ignore common IDE build files.
+
+2022-06-04 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'ci-ubuntu-22.04' into 'master'
+ ci: Update to use Ubuntu 22.04 CI images
+
+ Closes #429
+
+ See merge request libtiff/libtiff!348
+
+2022-06-04 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'opengl-option' into 'master'
+ cmake: Add tiff-opengl option
+
+ See merge request libtiff/libtiff!340
+
+2022-06-04 Roger Leigh <rleigh@codelibre.net>
+
+ tiffdump: Avoid overflow warning when reading.
+
+ ci: Update to use Ubuntu 22.04 CI images.
+
+2022-06-04 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'master' into 'master'
+ Include stdlib.h in tif_lzw.c.
+
+ See merge request libtiff/libtiff!347
+
+2022-06-04 Brian Ledger <brian.peter.ledger@gmail.com>
+
+ Merge branch 'master' of https://gitlab.com/libtiff/libtiff.
+
+2022-06-04 Brian Ledger <brian.peter.ledger@gmail.com>
+
+ Include stdlib.h in tif_lzw.c.
+ In `tif_lzw.c`, a call is made to `_byteswap_uint64`. This is declared in `stdlib.h`. `stdlib.h` is not included in `tib_lzw.c`, so a name error may occur.
+
+ This change adds `#include stdlib.h` to `tif_lzw.c`, to prevent a name error from occuring when `stdlib.h` is not included.
+
+2022-05-29 Roger Leigh <rleigh@codelibre.net>
+
+ Add options for disabling tools, tests, contrib and docs.
+
+ cmake: Add MSVC options when building all libraries and executables.
+
+ cmake: Do not build faxtable target when cross-compiling.
+
+ cmake: Use add_compile_definitions and add_compile_options.
+ It seems that some CMake versions can't export targets using PRIVATE
+ linking, even though the private target is never used.
+
+ Merge remote-tracking branch 'origin/master' into cmake-msvc-options.
+
+ Merge remote-tracking branch 'origin/master' into cmake-win32-libtiffxx-static
+
+2022-05-29 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'ci-x64' into 'master'
+ ci: Remove arm64 temporarily
+
+ See merge request libtiff/libtiff!341
+
+2022-05-29 Roger Leigh <rleigh@codelibre.net>
+
+ ci: Remove arm64 temporarily.
+
+ autoconf: Add --disable-opengl option.
+
+ cmake: Add tiff-opengl option.
+
+ cmake: Add MSVC options when building all libraries and executables.
+
+ cmake: libtiffxx is static on win32.
+
+2022-05-22 Even Rouault <even.rouault@spatialys.com>
+
+ html/Makefile.am: add v4.4.0.html to docfiles.
+
+2022-05-20 Even Rouault <even.rouault@spatialys.com>
+
+ Update HOWTO-RELEASE with .tar.xz.
+
+ Prepare for release 4.4.0.
+
+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
+
+2021-04-15 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'libjpeg12_cmake' into 'master'
+ libtiff/tif_config.h.cmake.in: surround LIBJPEG_12_PATH by double quotes
+
+ See merge request libtiff/libtiff!237
+
+2021-04-15 Even Rouault <even.rouault@spatialys.com>
+
+ libtiff/tif_config.h.cmake.in: surround LIBJPEG_12_PATH by double quotes
+
+2021-04-14 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'lerc_api_change' into 'master'
+ tif_lerc.c: cope with API breakage in liblerc master
+
+ See merge request libtiff/libtiff!236
+
+2021-04-14 Even Rouault <even.rouault@spatialys.com>
+
+ tif_lerc.c: cope with API breakage in liblerc master.
+
+2021-04-08 Even Rouault <even.rouault@spatialys.com>
+
+ libtiff: remove remaining #ifdef WIN32 and use PRI formatting.
+
+2021-03-10 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'kmilos-master-patch-73187' into 'master'
+ tiffcp: Remove LZW help text, preset not supported
+
+ See merge request libtiff/libtiff!229
+
+2021-03-10 Miloš Komarčević <miloskomarcevic@aim.com>
+
+ tiffcp: Remove LZW help text, preset not supported.
+
+2021-03-10 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'feature/lerc' into 'master'
+ Add LERC Compression Plugin (closes: #213)
+
+ Closes #213
+
+ See merge request libtiff/libtiff!228
+
+2021-03-10 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'cmake-fixes' into 'master'
+ CMake fixes
+
+ Closes #246 et #245
+
+ See merge request libtiff/libtiff!232
+
+2021-03-09 Roger Leigh <rleigh@codelibre.net>
+
+ cmake: Correct FindCMath.
+
+ cmake: Correct ZSTD_USABLE typo.
+
+2021-03-07 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'cmake-find-lib-prefixes' into 'master'
+ cmake: Correct find lib prefixes for Deflate and JBIG
+
+ See merge request libtiff/libtiff!231
+
+2021-03-07 Roger Leigh <rleigh@codelibre.net>
+
+ cmake: FindJBIG uses lib prefix on Windows.
+
+ cmake: FindDeflate uses lib prefix on Windows.
+
+2021-03-07 Even Rouault <even.rouault@spatialys.com>
+
+ TWebPDecode(): avoid potential overflow on multiplication (CID 1472928)
+
+ TIFFReadDirEntryArrayWithLimit(): avoid false positive from Coverity Scan regarding out-of-bounds access (CID 1472927)
+
+ tif_dirwrite.c: avoid setting a variable that is not read afterwards.
+
+2021-03-07 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'coverity-fixes' into 'master'
+ Coverity fixes (high impact)
+
+ See merge request libtiff/libtiff!227
+
+2021-03-07 Roger Leigh <rleigh@codelibre.net>
+
+ Fix high-impact Coverity issues (resource leaks).
+ The issues are in the tests and tiffcrop, not the core library. Real issues, but not high risk.
+
+ Use to test if Coverity integration is performing properly on merge.
+
+2021-03-07 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_tif_fax3_encoder_regression' into 'master'
+ tif_fax3.c: fix master regression in encoder
+
+ See merge request libtiff/libtiff!230
+
+2021-03-07 Even Rouault <even.rouault@spatialys.com>
+
+ tif_fax3.c: fix master regression in encoder.
+ Fix issue introduced in 39a74eede0455ec8ee334dcddf71f5354d508d8b
+
+ Spotted by gdal's tiff_write_76 test
+
+2021-03-07 Antonio Valentino <antonio.valentino@tiscali.it>
+
+ Add LERC support in CMake.
+
+2021-03-07 Antonio Valentino <Antonio.Valentino@esa.int>
+
+ Add LERC support in configure.ac and Makefile.am.
+
+2021-03-07 Antonio Valentino <antonio.valentino@tiscali.it>
+
+ Add LERC support to tiffcp.
+
+2021-03-07 Antonio Valentino <Antonio.Valentino@esa.int>
+
+ Add LERC plugin.
+ The lerc plugin code has been copyed form GDAL.
+
+2021-03-06 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'display_tool_purpose' into 'master'
+ TIFF tools: insert a line of text summarizing each tool's purpose
+
+ See merge request libtiff/libtiff!214
+
+2021-03-06 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'cmake-update' into 'master'
+ CMake updates
+
+ See merge request libtiff/libtiff!224
+
+2021-03-06 Even Rouault <even.rouault@spatialys.com>
+
+ tiff.h: typo fix in comment.
+
+2021-02-15 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'remove-travis' into 'master'
+ ci: Remove unused Travis-CI support
+
+ See merge request libtiff/libtiff!226
+
+2021-02-14 Roger Leigh <rleigh@codelibre.net>
+
+ ci: Remove unused Travis-CI support.
+
+2021-02-14 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'ci-coverity' into 'master'
+ Enable Coverity static analysis with CI pipeline
+
+ See merge request libtiff/libtiff!225
+
+2021-02-14 Roger Leigh <rleigh@codelibre.net>
+
+ ci: Add Coverity static analysis job.
+
+ ci: Use custom libtiff CI image.
+
+2021-02-13 Roger Leigh <rleigh@codelibre.net>
+
+ cmake: Add release target.
+
+ cmake: Remove empty contrib files.
+
+ cmake: Tidy toplevel.
+
+ cmake: Move pkg-config support to PkgConfig.cmake.
+
+ cmake: Move library feature options to CXXLibraryFeatures.cmake.
+
+ cmake: Move C++ support to CXXLibrary.cmake.
+
+ cmake: Add FindCMath to handle libm linking portably.
+
+ cmake: Tidy unused includes.
+
+ cmake: Rename release date to build date.
+
+ cmake: Compute timestamp portably.
+
+ cmake: Remove remaining uses of report_values()
+
+ cmake: Move JPEG12 checks to JPEGCodec.cmake.
+
+ cmake: Move OpenGL checks to OpenGLChecks.cmake.
+
+ cmake: Move OpenGL checks to OpenGLChecks.cmake.
+
+ cmake: Move WebP codec support to WebPCodec.cmake.
+
+ cmake: Use imported targets for WebP.
+
+ cmake: Add FindWebP.
+
+ cmake: Move ZSTD codec support to ZSTDCodec.cmake.
+
+ cmake: Use imported targets for ZSTD.
+
+ cmake: Add FindZSTD.
+
+ cmake: Move LZMA codec support to LZMACodec.cmake.
+
+ cmake: Use imported targets for LibLZMA.
+
+ cmake: Move JBIG codec support to JBIGCodec.cmake.
+
+ cmake: Use imported targets for JBIG.
+
+ cmake: Add FindJBIG.
+
+ cmake: Move PixarLog codec support to PixarLogCodec.cmake.
+
+ cmake: Report system name in configuration report.
+
+ cmake: Move JPEG codec support to JPEGCodec.cmake.
+
+ cmake: Use imported targets for JPEG.
+
+ cmake: Move Deflate codec support to DeflateCodec.cmake.
+
+ cmake: Use imported targets for ZLIB and Deflate.
+
+ cmake: Add FindDeflate.
+
+ cmake: Move symbol checks to SymbolChecks.cmake.
+
+ cmake: Move include checks to IncludeChecks.cmake.
+
+ cmake: Move all autotools logic to separate files.
+
+ cmake: Move internal codec options to InternalCodecs.cmake.
+
+ cmake: Move LFS check to LargeFileSupport.cmake.
+
+ cmake: Move Win32 IO feature to WindowsIOFeature.cmake.
+
+ cmake: Move processor capability checks to ProcessorChecks.cmake.
+
+ cmake: Move type size checks to TypeSizeChecks.cmake.
+
+ cmake: Move linker checks to LinkerChecks.cmake.
+
+ cmake: Move warning options to CompilerChecks.
+
+ cmake: Move version introspection to AutotoolsVersion.cmake.
+
+ cmake: Move compiler checks to CompilerChecks.cmake.
+
+ cmake: Split into helper scripts.
+
+2021-02-08 Roger Leigh <rleigh@codelibre.net>
+
+ cmake: Use target_sources.
+
+ libport: Adjust header and library to only define and link if required.
+ * Make libport an OBJECT library when in use, otherwise a dummy
+ INTERFACE library
+ * libport.h will work if getopt is present or not present. If
+ present, will fall back to <unistd.h>, else will define
+ symbols
+ * Add generated libport_config.h to define HAVE_GETOPT and HAVE_UNISTD_H
+ * dummy.c no longer needed with CMake
+ * libtiff/libtiffxx no longer link with libport
+
+ cmake: Remove unnecessary extra_dist usage.
+ Only makes sense in the context of Automake. Was carried over
+ for reference while porting, but is not needed.
+
+ cmake: Update minimum version and policy version to 3.9.
+
+2021-02-08 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'remove-nmake' into 'master'
+ Remove NMake build support
+
+ See merge request libtiff/libtiff!223
+
+2021-02-08 Roger Leigh <rleigh@codelibre.net>
+
+ Remove NMake build support.
+ The functionality provided by the NMake build is now completely
+ superseded by the CMake build.
+
+2021-02-08 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'warning-fixes' into 'master'
+ Warning fixes
+
+ See merge request libtiff/libtiff!222
+
+2021-02-07 Miguel Medalha <medalist@sapo.pt>
+
+ Update tiffsplit.c.
+
+ Reinsert summary line lost after conflicting merge.
+
+ Merge branch 'master' into 'display_tool_purpose'
+ # Conflicts:
+ # tools/tiffsplit.c
+
+2021-02-06 Roger Leigh <rleigh@codelibre.net>
+
+ ci: Enable fatal warnings with -Werror for AppVeyor/GCC.
+
+ ci: Enable fatal warnings with -Werror for GitLab CI.
+
+ tif_zstd.c: Remove unused variable warning.
+
+ custom_dir_EXIF_231: Remove case statement fallthrough.
+
+ custom_dir_EXIF_231: Correct use of strncpy.
+
+ Correct include order.
+
+ Eliminate implict fallthrough usage.
+ Use simple loops in place of manual loop unrolling. Rely on
+ the compiler optimiser to unroll loops when appropriate.
+
+ Suppress potential unused variable warning.
+
+ Suppress warnings or avoid case statement fallthrough.
+
+2021-02-05 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'c99-ssize_t-fixes' into 'master'
+ C99 ssize_t fixes
+
+ Closes #239
+
+ See merge request libtiff/libtiff!219
+
+2021-02-05 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffsplit-too-many-args' into 'master'
+ tiffsplit.c: exit with EXIT_FAILURE if there are extra args on the command line
+
+ See merge request libtiff/libtiff!209
+
+2021-02-05 Roger Leigh <rleigh@codelibre.net>
+
+ Add additional TIFF_SSIZE_FORMAT uses.
+
+2021-02-04 Roger Leigh <rleigh@codelibre.net>
+
+ NMake fixes for size type formatting.
+
+ Add TIFF_SIZE_FORMAT for portable use of %z.
+ MinGW64 does support %z, but it issues a compiler warning.
+
+ Align Autoconf tif_config.h and CMake tif_config.cmake.in.
+
+ Use TIFF_SSIZE_FORMAT for formatting tmsize_t.
+
+2021-02-04 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'remove-lcc' into 'master'
+ Remove Makefile.lcc
+
+ See merge request libtiff/libtiff!221
+
+2021-02-04 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'remove-scons' into 'master'
+ Remove SCons build
+
+ See merge request libtiff/libtiff!220
+
+2021-02-03 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'c99-snprintf' into 'master'
+ Use C99 snprintf
+
+ See merge request libtiff/libtiff!217
+
+2021-02-03 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'tiff2ps-const' into 'master'
+ tiff2ps.c: string literals must be const char *, not char *
+
+ See merge request libtiff/libtiff!202
+
+2021-02-03 Roger Leigh <rleigh@codelibre.net>
+
+ Remove SCons build.
+ Unmaintained for 16 years.
+
+2021-02-03 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'codec_summary' into 'master'
+ Modify 'CMakeLists.txt' to produce a meaningful summary of external codecs
+
+ See merge request libtiff/libtiff!192
+
+2021-02-03 Roger Leigh <rleigh@codelibre.net>
+
+ Remove Makefile.lcc.
+ Unmaintained for 22 years.
+
+2021-02-02 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'ci-32-bit' into 'master'
+ ci: Build 32- and 64-bit MSVC variants
+
+ See merge request libtiff/libtiff!218
+
+2021-02-01 Roger Leigh <rleigh@codelibre.net>
+
+ ci: Build 32- and 64-bit MSVC variants.
+
+ Use C99 snprintf.
+
+2021-02-01 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'c99-strtol' into 'master'
+ Use C99 strtol, strtoul, strtoll and strtoull
+
+ See merge request libtiff/libtiff!216
+
+2021-01-31 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'c99-inline' into 'master'
+ Use C99 inline
+
+ See merge request libtiff/libtiff!215
+
+2021-01-31 Roger Leigh <rleigh@codelibre.net>
+
+ Use C99 strtol, strtoul, strtoll and strtoull.
+
+ tif_fax3: Use C99 inline.
+
+ Remove inline feature tests and defines.
+ Available as a standard feature with C99.
+
+2021-01-30 Miguel Medalha <medalist@sapo.pt>
+
+ Update raw2tiff.c (remove duplicate description of tool)
+
+2021-01-30 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'c99-format-strings' into 'master'
+ C99 format strings
+
+ See merge request libtiff/libtiff!211
+
+2021-01-29 Miguel Medalha <medalist@sapo.pt>
+
+ Update tiffdither.c (2 tabs caused slight misalignment of lines in usage info output)
+
+2021-01-28 Miguel Medalha <medalist@sapo.pt>
+
+ Update ppm2tiff.c (slight misalignment of lines in usage info output)
+
+ Update tiffset.c (small misalignment of lines in usage info output)
+
+2021-01-28 Medalha <medalist@sapo.pt>
+
+ Display tool purpose.
+
+2021-01-28 Thomas Bernard <miniupnp@free.fr>
+
+ tiff2ps.c: string literals must be const char *, not char *
+
+2021-01-28 Roger Leigh <rleigh@codelibre.net>
+
+ libtiff: Use PRI format flags and remove unnecessary casts.
+
+2021-01-27 Roger Leigh <rleigh@codelibre.net>
+
+ ascii_tag: Use PRI format flags and remove unnecessary casts.
+
+ check_tag: Use PRI format flags and remove unnecessary casts.
+
+ custom_dir_EXIF_231: Use PRI format flags and remove unnecessary casts.
+
+ short_tag: Use PRI format flags and remove unnecessary casts.
+
+ strip_rw: Use PRI format flags and remove unnecessary casts.
+
+ fax2tiff: Use PRI format flags and remove unnecessary casts.
+
+ ppm2tiff: Correct format strings.
+
+ raw2tiff: Use PRI format flags and remove unnecessary casts.
+
+ rgb2ycbcr: Use PRI format flags and remove unnecessary casts.
+
+ tiff2pdf: Use PRI format flags and remove unnecessary casts.
+
+ tiff2ps: Use PRI format flags and remove unnecessary casts.
+
+ tiff2rgba: Use PRI format flags and remove unnecessary casts.
+
+ tiffcmp: Use PRI format flags and remove unnecessary casts.
+
+ tiffcp: Use PRI format flags and remove unnecessary casts.
+
+ tiffcrop: Use PRI format flags and remove unnecessary casts.
+
+ tiffinfo: Use PRI format flags and remove unnecessary casts.
+
+ tiffdump: Use PRI format flags and remove unnecessary casts.
+
+2021-01-27 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'c99-require-stdtypes' into 'master'
+ Use standard C99 integer types
+
+ See merge request libtiff/libtiff!205
+
+2021-01-26 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'reserve_COMPRESSION_JXL' into 'master'
+ tiff.h: reserve COMPRESSION_JXL=50002 for JPEGXL
+
+ See merge request libtiff/libtiff!210
+
+2021-01-22 Even Rouault <even.rouault@spatialys.com>
+
+ tiff.h: reserve COMPRESSION_JXL=50002 for JPEGXL.
+
+2021-01-22 Kurt Schwehr <schwehr@google.com>
+
+ tiffsplit.c: exit with EXIT_FAILURE if there are extra args on the command line
+ e.g. tiffsplit in.tif a_prefix_ junk
+
+2021-01-22 Roger Leigh <rleigh@codelibre.net>
+
+ Add and enable TIFF_DISABLE_DEPRECATED for internal use.
+
+ Add typedef deprecations for GCC/Clang and MSVC.
+
+ Use standard C99 integer types.
+
+2021-01-20 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'ubuntu-zstd-wepb' into 'master'
+ gitlab-ci : use libzstd-dev and libwebp-dev ubuntu packages
+
+ See merge request libtiff/libtiff!208
+
+2021-01-20 Thomas Bernard <miniupnp@free.fr>
+
+ gitlab-ci : use libzstd-dev and libwebp-dev ubuntu packages.
+ should replace !206
+
+2021-01-20 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-232' into 'master'
+ tiff2ps: exit the loop in case of error
+
+ Closes #232
+
+ See merge request libtiff/libtiff!201
+
+2021-01-20 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffsplit-exit-status' into 'master'
+ tiffsplit: Exit with EXIT_FAILURE if unable to open the input file.
+
+ See merge request libtiff/libtiff!207
+
+2021-01-20 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'config-cleanup' into 'master'
+ Remove HAVE_INTTYPES_H, HAVE_LFIND & lfind, HAVE_SEARCH_H & include <search.h>
+
+ See merge request libtiff/libtiff!203
+
+2021-01-19 Kurt Schwehr <schwehr@google.com>
+
+ tiffsplit: Exit with EXIT_FAILURE if unable to open the input file.
+
+2021-01-18 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffcmp' into 'master'
+ tiffcmp: fix comparaison with pixels that are fractional number of bytes
+
+ Closes #53
+
+ See merge request libtiff/libtiff!141
+
+2021-01-15 Kurt Schwehr <schwehr@google.com>
+
+ CMakeLists.txt: Remove search for lfind.
+
+ Remove HAVE_INTTYPES_H, HAVE_LFIND & lfind, HAVE_SEARCH_H & include <search.h>
+ - HAVE_INTTYPES_H is replaced with TIFF_HAVE_INTTYPES_H
+ - tif_dirinfo.c has a static td_lfind
+
+2021-01-15 Thomas Bernard <miniupnp@free.fr>
+
+ tiffcmp: fix comparaison with pixels that are fractional number of bytes
+ For exemple : 4bits per sample + 3 samples per pixel => 1.5 bytes per pixel
+
+ tiff2ps: exit the loop in case of error.
+ fixes #232
+
+2021-01-15 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'rm-strcasecmp' into 'master'
+ Remove port/strcasecmp.c as strcasecmp is not currently used in libtiff.
+
+ Closes #235
+
+ See merge request libtiff/libtiff!199
+
+2021-01-15 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'std-int-types' into 'master'
+ Use standard C99 integer types
+
+ See merge request libtiff/libtiff!185
+
+2021-01-13 Kurt Schwehr <schwehr@google.com>
+
+ Remove port/strcasecmp.c as strcasecmp is not currently used in libtiff.
+ Fixes #235
+
+2021-01-10 Miguel Medalha <medalist@sapo.pt>
+
+ Update CMakeLists.txt. Delete unnecessary line from libdeflate codec support section
+
+2021-01-10 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'include_libport' into 'master'
+ tiff tools and libtiff/mkg3states: include 'libport.h', remove local definition of 'getopt()'
+
+ See merge request libtiff/libtiff!198
+
+2021-01-09 Miguel Medalha <medalist@sapo.pt>
+
+ Update CMakeLists.txt. Cleanup of indentation space. Removal of leading '/' from webp include dir.
+
+2021-01-09 miguel <medalist@sapo.pt>
+
+ cmake: Use target_include_directories correctly.
+
+2021-01-09 Roger Leigh <rleigh@codelibre.net>
+
+ cmake: Use target_include_directories correctly.
+
+ cmake: Drop unnecessary TOOL_INCLUDES.
+
+2021-01-07 Roger Leigh <rleigh@codelibre.net>
+
+ cmake: Use target_include_directories correctly.
+
+2021-01-07 miguel <medalist@sapo.pt>
+
+ tiff tools and libtiff/mkg3states: include 'libport.h', remove local definition of 'getopt()'
+
+2021-01-07 Miguel Medalha <medalist@sapo.pt>
+
+ Update CMakeLists.txt.
+
+2021-01-07 miguel <medalist@sapo.pt>
+
+ tiff tools: include 'libport.h', remove local definition of 'getopt()'
+
+2021-01-06 Roger Leigh <rleigh@codelibre.net>
+
+ Remove conditional use of <string.h>
+
+ cmake: Drop dlfcn.h check.
+
+ cmake: Remove duplicate line.
+
+ Use stdint.h types when available.
+
+2021-01-05 Olivier Paquet <olivier.paquet@gmail.com>
+
+ Merge branch 'iptcutil' into 'master'
+ contrib/iptcutil.c: set '#ifdef _WIN32' (was '#ifdef WIN32', which failed at build time)
+
+ See merge request libtiff/libtiff!197
+
+2021-01-05 miguel <medalist@sapo.pt>
+
+ tiff tools: include 'libport.h', remove local definition of 'getopt()'
+
+ contrib/iptcutil.c - set '#ifdef _WIN32' (was '#ifdef WIN32', which failed at build time)
+
+2021-01-04 Even Rouault <even.rouault@spatialys.com>
+
+ tools/CMakeLists.txt: add comment about rgb2ycbcr and thumbnail not to be installed
+
+2021-01-04 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'revert-5331ed49' into 'master'
+ Revert "Merge branch 'install_targets' into 'master'"
+
+ See merge request libtiff/libtiff!196
+
+2021-01-04 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'drop-wince' into 'master'
+ Remove non-functional WinCE support
+
+ See merge request libtiff/libtiff!188
+
+2021-01-04 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'drop-vms' into 'master'
+ Remove non-functional VMS support
+
+ See merge request libtiff/libtiff!187
+
+2021-01-03 Even Rouault <even.rouault@spatialys.com>
+
+ Revert "Merge branch 'install_targets' into 'master'"
+ This reverts merge request !193
+
+2021-01-03 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffcp_b_parameter' into 'master'
+ tiffcp: Remove unnecessary reference to compression from usage info for -b parameter
+
+ See merge request libtiff/libtiff!189
+
+2021-01-03 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'cmake-faxtable' into 'master'
+ cmake: Add faxtable target
+
+ See merge request libtiff/libtiff!186
+
+2021-01-03 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'install_targets' into 'master'
+ Update 'CMakeLists.txt' from 'tools'.
+
+ See merge request libtiff/libtiff!193
+
+2021-01-03 Miguel Medalha <medalist@sapo.pt>
+
+ Update 'CMakeLists.txt' from 'tools'.
+
+ Update CMakeLists.txt.
+
+2021-01-03 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'usage_info' into 'master'
+ thumbnail: Rename constant variable 'stuff' to 'usage_info'
+
+ See merge request libtiff/libtiff!190
+
+2021-01-03 Miguel Medalha <medalist@sapo.pt>
+
+ Modified 'CMakeLists.txt' to produce a meaningful summary of external codecs support.
+
+ Removed unnecessary reference to compression from usage info for -b parameter
+
+ Constant variable 'stuff' renamed to 'usage_info' for consistency with the other tools
+
+2021-01-02 Roger Leigh <rleigh@codelibre.net>
+
+ Remove non-functional VMS support.
+
+ Remove non-functional WinCE support.
+
+2021-01-02 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'codespell' into 'master'
+ Fix spelling mistakes.
+
+ See merge request libtiff/libtiff!183
+
+2021-01-02 Kurt Schwehr <schwehr@google.com>
+
+ ChangeLog: Remove extraneous character from prior commit - 00fe7828.
+
+2021-01-02 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'codespell-custom_dir_EXIF_231' into 'master'
+ custom_dir_EXIF_231.c: dos2unix and codespell
+
+ See merge request libtiff/libtiff!184
+
+2021-01-01 Roger Leigh <rleigh@codelibre.net>
+
+ mkg3states: Sync generator with current generated file content.
+
+ cmake: Add faxtable and mkg3states targets.
+
+2020-12-31 Kurt Schwehr <schwehr@google.com>
+
+ custom_dir_EXIF_231.c: dos2unix and codespell.
+ additonal, Varable, greather, alwasy
+
+2020-12-31 Kurt Schwehr <schwehr@google.com>
+
+ Fix spelling mistakes.
+ Found with:
+
+ codespell --version
+ 1.17.1
+
+2020-12-29 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'remove-some-vms-ifdef' into 'master'
+ Remove "ifdef VMS" that are no longer necessary.
+
+ See merge request libtiff/libtiff!181
+
+2020-12-29 Kurt Schwehr <schwehr@google.com>
+
+ Remove "ifdef VMS" that are no longer necessary.
+ Both sides of the if are now the same.
+
+2020-12-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ _TIFFBuiltinCODECS should be const.
+
+2020-12-28 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-202' into 'master'
+ tiff2pdf.c: check that tiff_datasize fits in a signed tsize_t
+
+ Closes #202
+
+ See merge request libtiff/libtiff!166
+
+2020-12-28 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'w_report-when-libdeflate-is-found' into 'master'
+ CMakeLists.txt: Report when libdeflate is found
+
+ See merge request libtiff/libtiff!175
+
+2020-12-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ Declare gpsFields as static const.
+
+2020-12-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ Merge branch 'tools-reduce-initialized-data' into 'master'
+ Reduce initialized data by making more data const and simplifying usage() implementation.
+
+ See merge request libtiff/libtiff!180
+
+2020-12-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ Reduce initialized data by making more data const and simplifying usage() implementation.
+
+2020-12-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ Merge branch 'master' into 'master'
+ tiff tools: display of compression methods is now conditional instead of hard-coded
+
+ See merge request libtiff/libtiff!176
+
+2020-12-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ Merge branch 'build' into 'master'
+ Fix wrong URL for fetching config.guess and config.sub
+
+ See merge request libtiff/libtiff!177
+
+2020-12-26 Chocobo1 <Chocobo1@users.noreply.github.com>
+
+ Fix wrong URL for fetching config.guess and config.sub.
+
+2020-12-25 miguel <medalist@sapo.pt>
+
+ tiff tools: made display of compression methods and their parameters conditional on their actual availability
+
+2020-12-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ autogen.sh now updates config.guess and config.sub from master gnulib version.
+
+2020-12-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ Add a https://libtiff.gitlab.io/libtiff/ link.
+
+ Remove stray character in URL area.
+
+ Changes for 4.2.0 release.
+
+ Changes for 4.2.0 release.
+
+2020-12-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff 4.2.0 released.
+
+ * configure.ac: Pass tar-ustar option to AM_INIT_AUTOMAKE rather
+ than tar-pax since ustar POSIX 1003.1-1988 format is more portable
+ than PAX POSIX 1003.1-2001 format.
+
+2020-12-12 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'w_adjust-deflate_names' into 'master'
+ Set 'deflate' to DEFLATE_NAMES, instead of 'libdeflate'
+
+ See merge request libtiff/libtiff!174
+
+2020-12-12 Lemures Lemniscati <lemures.lemniscati@gmail.com>
+
+ Set 'deflate' to DEFLATE_NAMES, instead of 'libdeflate'
+ 'lib' will be automatically added as a prefix while doing find_library()
+
+2020-12-12 Even Rouault <even.rouault@spatialys.com>
+
+ DoubleToRational(): avoid casting NaN to uint32 (fixes #227)
+
+2020-12-12 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_221' into 'master'
+ tiffio.h: do not define __attribute__ but defines TIFF_ATTRIBUTE instead (fixes #221)
+
+ Closes #221
+
+ See merge request libtiff/libtiff!173
+
+2020-12-12 Even Rouault <even.rouault@spatialys.com>
+
+ tiffio.h: do not define __attribute__ but defines TIFF_ATTRIBUTE instead (fixes #221)
+
+2020-12-08 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFReadDirEntryArrayWithLimit(): properly read from offline tag value when we clamp the number of strips to 1.
+ Fixes regression of commit 7057734d986001b7fd6d2afde9667da7754ff2cc on reading
+ a file with StripByteCounts with 1 element (broken) and StripOffsets with
+ 896 elements, and where StripOffsets[0] is correct
+
+ $ tiffdump foo.tif
+ Magic: 0x4949 <little-endian> Version: 0x2a <ClassicTIFF>
+ Directory 0: offset 25725448 (0x1888a08) next 0 (0)
+ SubFileType (254) LONG (4) 1<0>
+ ImageWidth (256) LONG (4) 1<640>
+ ImageLength (257) LONG (4) 1<20098>
+ BitsPerSample (258) SHORT (3) 1<16>
+ Photometric (262) SHORT (3) 1<1>
+ SamplesPerPixel (277) SHORT (3) 1<1>
+ ResolutionUnit (296) SHORT (3) 1<2>
+ StripByteCounts (279) LONG (4) 1<1806>
+ StripOffsets (273) LONG (4) 896<8 648 1288 1928 2568 3208 3848 4488 5128 5768 6408 7048 7688 8328 8968 9608 10248 10888 11528 12168 12808 13448 14088 14728 ...>
+
+2020-12-02 Even Rouault <even.rouault@spatialys.com>
+
+ tif_jpeg.c: avoid potential harmless unsigned integer overflow on data->fileoffset in JPEGFixupTagsSubsamplingSkip() by validating earlier. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28200
+
+2020-11-27 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'Jamaika1-master-patch-47839' into 'master'
+ Change ULARGE_INTEGER to LARGE_INTEGER
+
+ See merge request libtiff/libtiff!170
+
+2020-11-27 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'Jamaika1-master-patch-46397' into 'master'
+ Added stdint.h
+
+ See merge request libtiff/libtiff!171
+
+2020-11-27 Jamaika <lukaszcz18@wp.pl>
+
+ Added stdint.h.
+
+ ``` tif_win32.c: In function '_tiffSizeProc': tif_win32.c:159:23: warning: passing argument 2 of 'GetFileSizeEx' from incompatible pointer type [-Wincompatible-pointer-types] 159 | if (GetFileSizeEx(fd,&m)) | ^~ | | | ULARGE_INTEGER * In file included from c:\msys1021\x86_64-w64-mingw32\include\winbase.h:18, from c:\msys1021\x86_64-w64-mingw32\include\windows.h:70, from tif_win32.c:32: c:\msys1021\x86_64-w64-mingw32\include\fileapi.h:78:73: note: expected 'PLARGE_INTEGER' {aka 'LARGE_INTEGER *'} but argument is of type 'ULARGE_INTEGER *' 78 | WINBASEAPI WINBOOL WINAPI GetFileSizeEx (HANDLE hFile, PLARGE_INTEGER lpFileSize); | ~~~~~~~~~~~~~~~^~~~~~~~~~ ```
+
+2020-11-21 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-113' into 'master'
+ tiffcrop: fix buffer overrun in extractContigSamples24bits()
+
+ Closes #113
+
+ See merge request libtiff/libtiff!169
+
+2020-11-21 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-156' into 'master'
+ tiff2pdf: Check output size before writing
+
+ Closes #156
+
+ See merge request libtiff/libtiff!168
+
+2020-11-21 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-201' into 'master'
+ tiff2pdf: enforce memory limit for tiled pictures too
+
+ Closes #201
+
+ See merge request libtiff/libtiff!167
+
+2020-11-20 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-207' into 'master'
+ enforce (configurable) memory limit in tiff2rgba
+
+ Closes #209 et #207
+
+ See merge request libtiff/libtiff!165
+
+2020-11-20 Even Rouault <even.rouault@spatialys.com>
+
+ tif_lzw.c: avoid false positive -Wnull-dereference of mingw32 gcc 7.3.
+
+2020-11-17 Thomas Bernard <miniupnp@free.fr>
+
+ tiffcrop: fix buffer overrun in extractContigSamples24bits()
+ fixes #113
+
+ tiff2pdf: Check output size before writing.
+ fixes #156
+
+ tiff2pdf: enforce memory limit for tiled pictures too.
+ fixes #201
+
+2020-11-15 Thomas Bernard <miniupnp@free.fr>
+
+ tiff2rgba.1: -M option.
+
+ enforce (configurable) memory limit in tiff2rgba.
+ fixes #207
+ fixes #209
+
+2020-11-14 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-220' into 'master'
+ tiff2pdf.c: properly calculate datasize when saving to JPEG YCbCr
+
+ Closes #220
+
+ See merge request libtiff/libtiff!159
+
+2020-11-14 Thomas Bernard <miniupnp@free.fr>
+
+ tiff2pdf.c: properly calculate datasize when saving to JPEG YCbCr.
+ fixes #220
+
+2020-11-14 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-204' into 'master'
+ avoid buffer overflow while writing jpeg end of file marker
+
+ Closes #204
+
+ See merge request libtiff/libtiff!161
+
+2020-11-14 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-193' into 'master'
+ fix buffer overflow in tiff2ps.c
+
+ Closes #193
+
+ See merge request libtiff/libtiff!162
+
+2020-11-14 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'skal65535-master-patch-91082' into 'master'
+ More overflow fixes for large widths
+
+ See merge request libtiff/libtiff!164
+
+2020-11-14 skal <pascal.massimino@gmail.com>
+
+ More overflow fixes for large width.
+ Also: use INT_MAX instead of hard-coded constants.
+
+2020-11-12 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'skal65535-master-patch-56655' into 'master'
+ Fix potential overflow in gtStripContig()
+
+ See merge request libtiff/libtiff!163
+
+2020-11-12 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-211' into 'master'
+ check for tile width overflow
+
+ Closes #211
+
+ See merge request libtiff/libtiff!160
+
+2020-11-12 skal <pascal.massimino@gmail.com>
+
+ Fix potential overflow in gtStripContig()
+ (w + w) might not fit in int32 if too large.
+
+2020-11-09 Thomas Bernard <miniupnp@free.fr>
+
+ tiff2ps.c: fix buffer overread.
+ fixes #193
+
+ fix undefined behaviour (int shifted too much to the left)
+
+ avoid buffer overflow while writing jpeg end of file marker.
+ fixes #204
+
+ gtTileContig(): check Tile width for overflow.
+ fixes #211
+
+ fix warning messages (v32 is unsigned)
+
+2020-10-26 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFStartStrip(): avoid potential crash in WebP codec when using scanline access on corrupted files. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=26650
+
+2020-10-20 Even Rouault <even.rouault@spatialys.com>
+
+ tif_webp.c: validate tile/strip dimension to avoid unsigned integer overflow in RGBA.size computation
+
+2020-10-19 Even Rouault <even.rouault@spatialys.com>
+
+ tif_zip.c: fix typo in comment.
+
+2020-10-16 Even Rouault <even.rouault@spatialys.com>
+
+ tiff.h: remove irrelevant warning about webp related pseudo-tags not being registered: they are purely internal libtiff concepts
+
+2020-10-16 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'libdeflate' into 'master'
+ Add support for building against libdeflate for faster Zip/Deflate compression/decompression
+
+ See merge request libtiff/libtiff!158
+
+2020-10-16 Even Rouault <even.rouault@spatialys.com>
+
+ test: add testdeflatelaststripextradata.sh.
+
+2020-10-16 Even Rouault <even.rouault@spatialys.com>
+
+ Add support for optional building against libdeflate for faster Zip/Deflate compression/decompression.
+ So we can have 2 kind of builds with the Zip/Deflate codec:
+ - zlib only
+ - zlib + libdeflate
+
+ Speed improvements in the 35%-50% range can be expected when libdeflate is used.
+ Compression level up to 12 is now supported (capped to 9 when zlib is used).
+ Still requires zlib for situations where libdeflate cannot be used (that
+ is for scanline access, since libdeflate has no streaming mode)
+
+ Pseudo-tag TIFFTAG_DEFLATE_SUBCODEC=DEFLATE_SUBCODEC_ZLIB/DEFLATE_SUBCODEC_LIBDEFLATE
+ is added to control which subcodec (zlib or libdeflate) should be used (it defaults
+ of course to libdeflate, when it is available).
+ This is mostly aimed at being used on the writing side, to be able to reproduce
+ output of previous libtiff versions at a binary level, in situations where this would
+ be really needed. Or as a safety belt in case there would be unforeseen issues
+ with using libdeflate.
+ It can be used to know when libdeflate is available at runtime (DEFLATE_SUBCODEC_LIBDEFLATE
+ will be the default value in that situation).
+
+ Of course, deflate codestreams produced by libdeflate can be read by zlib, and vice-versa.
+
+2020-10-14 Even Rouault <even.rouault@spatialys.com>
+
+ tif_webp.c: fix compiler warnings with MSVC.
+
+2020-10-12 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'various_fixes' into 'master'
+ Fix compiler warnings about unused variables when assert() expands to nothing
+
+ See merge request libtiff/libtiff!157
+
+2020-10-12 Even Rouault <even.rouault@spatialys.com>
+
+ .gitignore: add entries for new files in test/
+
+ Fix compiler warnings about unused variables when assert() expands to nothing
+
+2020-10-09 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch '215-cygwin-appveyor-fail' into 'master'
+ Update Appveyor CI build to build with VS2019 image
+
+ Closes #215
+
+ See merge request libtiff/libtiff!154
+
+2020-10-09 Roger Leigh <rleigh@codelibre.net>
+
+ wip.
+
+ wip.
+
+ wip.
+
+ wip.
+
+ wip.
+
+ wip.
+
+2020-10-09 Roger Leigh <rleigh@codelibre.net>
+
+ Merge branch 'TIFF-217_m_lib_path' into 'master'
+ cmake: Do not use absolute libm path
+
+ Closes #217
+
+ See merge request libtiff/libtiff!156
+
+2020-10-09 Roger Leigh <rleigh@codelibre.net>
+
+ cmake: Do not use absolute libm path.
+
+2020-10-08 Even Rouault <even.rouault@spatialys.com>
+
+ tif_fax3.h: restore systematic calls to CLEANUP_RUNS()
+ now that SETVALUE() no longer cause overflows.
+ Those were removed per b351db8be1b4d3f712bdb9424a79d3174cc03202 and
+ 3440ac216463fcad170bbb391491e69730a59ffa.
+
+ As SETVALUE() now returns an error, this allow the decoder to exit.
+
+ Otherwise, the assert(x == lastx) in _TIFFFax3fillruns() can trigger.
+
+ Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=26201
+
+2020-10-06 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'check_TIFFFlushData1' into 'master'
+ FAX/JPEG/LZMA/PixarLog/ZIP/ZSTD codecs: make sure to check TIFFFlushData1() return value
+
+ See merge request libtiff/libtiff!155
+
+2020-10-04 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'shared-memory' into 'master'
+ Set the --shared-memory linker flag for Emscripten builds
+
+ See merge request libtiff/libtiff!153
+
+2020-10-03 Even Rouault <even.rouault@spatialys.com>
+
+ tiff2rgba.c: fix -Wold-style-declaration warning.
+
+ FAX/JPEG/LZMA/PixarLog/ZIP/ZSTD codecs: make sure to check TIFFFlushData1() return value
+
+2020-09-26 Even Rouault <even.rouault@spatialys.com>
+
+ tif_fax3.h: extra buffer overflow checks. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=25934
+
+2020-09-25 Roger Leigh <rleigh@codelibre.net>
+
+ wip.
+
+ wip.
+
+ wip.
+
+ wip.
+
+ wip.
+
+ wip.
+
+ Update AppVeyor image.
+
+ test-appveyor.
+
+2020-09-24 Attila Oláh <atl@google.com>
+
+ Also pass --shared-memory to raw_decode.
+ This is needed when building for Emscripten with *both* WEBP and JPEG
+ support.
+
+ Set the --shared-memory linker flag for Emscripten builds.
+ This is only needed when building with WEBP support, which uses atomics,
+ therefore the linker needs the --shared-memory flag. The flag cannot be
+ added globally because not all executables link against libwebp.
+
+2020-09-22 Even Rouault <even.rouault@spatialys.com>
+
+ tif_fax3.h: return error when a buffer overflow occurs. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=25552 and https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=25849
+
+2020-09-11 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix-float-compare' into 'master'
+ Fix comparison for max negative float value.
+
+ See merge request libtiff/libtiff!152
+
+2020-09-11 Dirk Lemstra <dirk@lemstra.org>
+
+ Fix comparison for max negative float value.
+
+2020-09-07 Even Rouault <even.rouault@spatialys.com>
+
+ Fax3PreDecode(): reset curruns and refruns state variables.
+ to avoid out-of-bounds write triggered by GDAL when repeatedly
+ reading a corrupt strip.
+
+ Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=25493
+
+2020-06-06 Thomas Bernard <miniupnp@free.fr>
+
+ Merge branch 'issue-17' into 'master'
+ normalize tools behaviour regarding -h
+
+ Closes #17
+
+ See merge request libtiff/libtiff!115
+
+2020-05-31 Even Rouault <even.rouault@spatialys.com>
+
+ TWebPSetupEncode(): fix logic problem (and instead of or) in test that checks input is 8bit unsigned data
+
+2020-05-12 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFGetConfiguredCODECs(): fix to avoid wrong structure to be returned for registered (ie non built-in) codecs
+
+2020-05-09 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'zstd-webp-update' into 'master'
+ gitlab-ci: use latest zstd and webp versions
+
+ See merge request libtiff/libtiff!148
+
+2020-05-09 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'deprecated' into 'master'
+ ojpeg: s/Depreciated/Deprecated/
+
+ See merge request libtiff/libtiff!149
+
+2020-05-09 Aaron Boxer <boxerab@gmail.com>
+
+ ojpeg: s/Depreciated/Deprecated/
+
+2020-04-27 Even Rouault <even.rouault@spatialys.com>
+
+ Fix typos.
+
+ tif_jpeg.c: avoid potential division in previous fix (master only)
+
+2020-04-26 Thomas Bernard <miniupnp@free.fr>
+
+ gitlab-ci: use latest zstd and webp versions.
+
+2020-04-26 Even Rouault <even.rouault@spatialys.com>
+
+ tiff.h: fixes to use ASCII only characters (master only)
+
+2020-04-26 Thomas Bernard <miniupnp@free.fr>
+
+ tiffsplit: use EXIT_SUCCESS / EXIT_FAILURE.
+
+ tiffset: print usage on stdout when -h is used.
+ also use EXIT_FAILURE / EXIT_SUCCESS
+ see #17
+
+ tiffmedian: shopw usage on stdout when -h is used.
+ also use EXIT_SUCCESS/EXIT_FAILURE
+ see #17
+
+ tiffinfo: print usage on stdout when -h is used.
+ also use EXIT_FAILURE / EXIT_SUCCESS
+ see #17
+
+ raw2tiff: print usage to stdout when -h is used.
+ see #17
+
+ tiff2pdf: print usage on stdout when -h is used.
+ see #17
+
+ tiffgt: output usage on stdout with -h.
+ also use EXIT_SUCCESS / EXIT_FAILURE
+
+ tiffdump: use EXIT_FAILURE / EXIT_SUCCESS.
+ see #17
+
+ tiffdither: print usage on stdout when -h is used.
+ see #17
+
+2020-04-26 Thomas Bernard <miniupnp@free.fr>
+
+ tiffcrop: -h / -v prints usage/version to stdout.
+ also uses the standard C EXIT_SUCCESS / EXIT_FAILURE
+ macros
+
+ see #17
+
+2020-04-26 Thomas Bernard <miniupnp@free.fr>
+
+ tiffcp: output usage to stdout when using -h.
+ also use EXIT_FAILURE / EXIT_SUCCESS
+ see #17
+
+ tiffcmp: match exit status for posix cmp and diff tools.
+
+ tiff2rgba: output usage to stdout when using -h.
+ also uses std C EXIT_FAILURE / EXIT_SUCCESS
+ see #17
+
+ tiff2ps: sue EXIT_FAILURE / EXIT_SUCCESS.
+ see #17
+
+ tiff2bw: output usage on stdout when using -h.
+ also uses EXIT_SUCCESS / EXIT_FAILURE
+ see #17
+
+ thumbnail: use EXIT_FAILURE / EXIT_SUCCESS.
+ the -h option was already used so it cannot be used for help/usage
+ see #17
+
+ rgb2ycbcr: use EXIT_FAILURE / EXIT_SUCCESS.
+ the -h option was already used so it cannot be used for help/usage
+ see #17
+
+ ppm2tiff: output usage to stdout when using -h option.
+ also uses std C EXIT_SUCCESS / EXIT_FAILURE
+ see #17
+
+ pal2rgb: output usage to stdout when -h is used.
+ see #17
+
+ fax2tiff.c: print usage on stdout when using -h option.
+ see #17
+
+ fax2ps: output usage to stdout when using -h option.
+ also use EXIT_SUCCESS, EXIT_FAILURE from C standard
+
+2020-04-25 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'jpeg_multiscan_dos_logic' into 'master'
+ tif_jpeg.c: revise logic to detect potential excessive memory usage when...
+
+ See merge request libtiff/libtiff!147
+
+2020-04-24 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-176' into 'master'
+ tiff2pdf: get rid of uninitialized memory content
+
+ Closes #176
+
+ See merge request libtiff/libtiff!143
+
+2020-04-24 Even Rouault <even.rouault@spatialys.com>
+
+ tif_jpeg.c: revise logic to detect potential excessive memory usage when decoding multiscan JPEG compressed images
+
+2020-04-19 Thomas Bernard <miniupnp@free.fr>
+
+ tiff2pdf: test the return code of TIFFReadRawStrip() and TIFFReadRawTile()
+
+ tiff2pdf.c: fix some whitespace problems in source.
+
+ tiff2pdf: get rid of uninitialized memory content.
+ fixes #176
+
+2020-04-19 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-18' into 'master'
+ tiffset: pass size for TIFFTAG_INKNAMES
+
+ Closes #18
+
+ See merge request libtiff/libtiff!146
+
+2020-04-18 Olivier Paquet <olivier.paquet@gmail.com>
+
+ Merge branch 'issue-80' into 'master'
+ tiffinfo: fix dump of Tiled images
+
+ Closes #80
+
+ See merge request libtiff/libtiff!144
+
+2020-04-15 Even Rouault <even.rouault@spatialys.com>
+
+ Fix wrong file size checks for memory-mapped BigTIFF files that could lead to image rejection
+
+2020-04-05 Thomas Bernard <miniupnp@free.fr>
+
+ tiffset: pass size for TIFFTAG_INKNAMES.
+ Uses TIFFFieldPassCount() to know which arguments need to be
+ passed to TiffSetField()
+
+ fixes #18
+ see http://bugzilla.maptools.org/show_bug.cgi?id=2202
+
+2020-04-04 Thomas Bernard <miniupnp@free.fr>
+
+ tiffinfo: showdata for tiled images.
+
+ tiffinfo: fix dump of Tiled images.
+ fixes #80
+
+2020-04-03 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-117' into 'master'
+ tiffcrop: enforce memory allocation limit
+
+ Closes #117
+
+ See merge request libtiff/libtiff!140
+
+2020-04-03 Thomas Bernard <miniupnp@free.fr>
+
+ tiffcrop: enforce memory allocation limit.
+ uses -k option to change limit (default to 256MiB)
+ fixes #117 / http://bugzilla.maptools.org/show_bug.cgi?id=2757
+
+2020-04-02 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-45' into 'master'
+ tiffcp: disable strip chopping when trying to convert to JBIG compression
+
+ Closes #45
+
+ See merge request libtiff/libtiff!138
+
+2020-04-02 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-124' into 'master'
+ TIFFGetFields(3tiff): TIFFTAG_*BYTECOUNTS TIFFTAG_*OFFSETS are uint64
+
+ Closes #124
+
+ See merge request libtiff/libtiff!137
+
+2020-04-02 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'aix_itrunc' into 'master'
+ Rename itrunc to fix name clash with a different itrunc in math.h on AIX. Fixes issue #189
+
+ Closes #189
+
+ See merge request libtiff/libtiff!139
+
+2020-04-01 Rob Boehne <robb@datalogics.com>
+
+ Rename itrunc to fix name clash with a different itrunc in math.h on AIX. Fixes issue #189
+
+2020-04-01 Thomas Bernard <miniupnp@free.fr>
+
+ tiffcp: disable strip chopping when trying to convert to JBIG compression
+ fixes #45
+
+2020-03-29 Thomas Bernard <miniupnp@free.fr>
+
+ TIFFGetFields(3tiff): TIFFTAG_*BYTECOUNTS TIFFTAG_*OFFSETS are uint64.
+ fixes #124 / http://bugzilla.maptools.org/show_bug.cgi?id=2774
+
+2020-03-29 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-48' into 'master'
+ tiff2pdf: fix "raw" copy of Deflate streams
+
+ Closes #48
+
+ See merge request libtiff/libtiff!136
+
+2020-03-27 Thomas Bernard <miniupnp@free.fr>
+
+ tiff2pdf: fix "raw" copy of Deflate streams.
+ The Predictor parameter was not copied from the source tiff to the PDF.
+ fixes #48 / http://bugzilla.maptools.org/show_bug.cgi?id=2442
+
+2020-03-26 Thomas Bernard <miniupnp@free.fr>
+
+ tif_fax3: quit Fax3Decode2D() when a buffer overflow occurs.
+ fixes #186
+
+2020-03-24 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-143-144' into 'master'
+ tiffdump: avoid unaligned memory access
+
+ Closes #144 et #143
+
+ See merge request libtiff/libtiff!133
+
+2020-03-24 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-133' into 'master'
+ tiff2pdf: avoid divide by 0
+
+ Closes #133
+
+ See merge request libtiff/libtiff!126
+
+2020-03-24 Thomas Bernard <miniupnp@free.fr>
+
+ tiff2pdf: normalizePoint() macro to normalize the white point.
+
+2020-03-23 Thomas Bernard <miniupnp@free.fr>
+
+ tiffdump: avoid unaligned memory access.
+ fixes #143
+ fixes #144
+
+2020-03-23 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'out-of-memory' into 'master'
+ tiffcp/tiff2pdf/tiff2ps: enforce maximum malloc size
+
+ Closes #153, #84, #116 et #115
+
+ See merge request libtiff/libtiff!130
+
+2020-03-23 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-157' into 'master'
+ tiffset: check memory allocation
+
+ Closes #157
+
+ See merge request libtiff/libtiff!132
+
+2020-03-23 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-185' into 'master'
+ tif_fax3: more buffer overflow checks in Fax3Decode2D()
+
+ Closes #185
+
+ See merge request libtiff/libtiff!131
+
+2020-03-23 Thomas Bernard <miniupnp@free.fr>
+
+ tiffset: check memory allocation.
+ fixes #157 / http://bugzilla.maptools.org/show_bug.cgi?id=2850
+
+ tif_fax3: more buffer overflow checks in Fax3Decode2D()
+ fixes #185
+
+2020-03-21 Thomas Bernard <miniupnp@free.fr>
+
+ tiff2ps: enforce memory allocation limit.
+ fixes #153 / http://bugzilla.maptools.org/show_bug.cgi?id=2845
+
+ tiff2pdf: enforce maximum data size.
+ fixes #116 / http://bugzilla.maptools.org/show_bug.cgi?id=2756
+ fixes #84 / http://bugzilla.maptools.org/show_bug.cgi?id=2683
+
+ update man page for tiffcp regarding the -m option.
+
+ tiffcp.c: _TIFFmalloc() => limitMalloc()
+
+2020-03-21 Thomas Bernard <miniupnp@free.fr>
+
+ tiffcp: enforce maximum malloc size.
+ default is 256MB. use -m option to change
+
+ fixes #115 / http://bugzilla.maptools.org/show_bug.cgi?id=2755
+
+2020-03-21 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-184' into 'master'
+ CmakeLists.txt: define WORDS_BIGENDIAN when the CPU is big endian
+
+ Closes #184
+
+ See merge request libtiff/libtiff!127
+
+2020-03-21 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-44' into 'master'
+ tiff2pdf: "" causes the relevant argument not to be written
+
+ Closes #44
+
+ See merge request libtiff/libtiff!128
+
+2020-03-21 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-56' into 'master'
+ fix man for TIFFReadEncodedStrip(), TIFFStripSize, TIFFVStripSize, TIFFRawStripSize
+
+ Closes #56
+
+ See merge request libtiff/libtiff!129
+
+2020-03-20 Thomas Bernard <miniupnp@free.fr>
+
+ fix man for TIFFReadEncodedStrip(), TIFFStripSize, TIFFVStripSize, TIFFRawStripSize
+ fixes #56
+ http://bugzilla.maptools.org/show_bug.cgi?id=2507
+
+ tiff2pdf: "" causes the relevant argument not to be written.
+ fixes #44
+
+ CmakeLists.txt: define WORDS_BIGENDIAN when the CPU is big endian.
+ fixes #184
+
+2020-03-17 Thomas Bernard <miniupnp@free.fr>
+
+ tiff2pdf: avoid divide by 0.
+ fixes #133 http://bugzilla.maptools.org/show_bug.cgi?id=2796
+
+2020-03-17 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-22' into 'master'
+ do not _tiffMapProc 0 size files
+
+ Closes #22
+
+ See merge request libtiff/libtiff!125
+
+2020-03-13 Thomas Bernard <miniupnp@free.fr>
+
+ tif_win32.c: do not _tiffMapProc() 0 sized files.
+ see #22
+
+ tif_unix.c: do not _tiffMapProc 0 size files.
+ fixes #22
+ http://bugzilla.maptools.org/show_bug.cgi?id=2249
+
+2020-03-12 Even Rouault <even.rouault@spatialys.com>
+
+ tif_fax3.c: fix warning C4018: '<': signed/unsigned mismatch introduced in past commits
+
+2020-03-11 Even Rouault <even.rouault@spatialys.com>
+
+ tiff.h: mention TIFFTAG_RPCCOEFFICIENT, TIFFTAG_TIFF_RSID, TIFFTAG_GEO_METADATA
+
+2020-03-11 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-60' into 'master'
+ added support for more private tags
+
+ Closes #60
+
+ See merge request libtiff/libtiff!124
+
+2020-03-11 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-160' into 'master'
+ Fax3SetupState(): check consistency of rowbytes and rowpixels
+
+ Closes #160
+
+ See merge request libtiff/libtiff!123
+
+2020-03-11 Thomas Bernard <miniupnp@free.fr>
+
+ added support for more private tags.
+ see https://gitlab.com/libtiff/libtiff/-/issues/60
+ bugzilla.maptools.org/show_bug.cgi?id=2525
+
+ closes #60
+
+ original author : art1@andreas-romeyke.de
+
+2020-03-11 Thomas Bernard <miniupnp@free.fr>
+
+ Fax3SetupState(): check consistency of rowbytes and rowpixels.
+ also add some parameter documentation to Fax3Decode1D()
+
+ fixes #160
+ http://bugzilla.maptools.org/show_bug.cgi?id=2854
+
+2020-03-10 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-11-const-pointers' into 'master'
+ Make pointers returned via TIFFGetField const
+
+ Closes #11
+
+ See merge request libtiff/libtiff!118
+
+2020-03-10 Even Rouault <even.rouault@spatialys.com>
+
+ tif_ojpeg.c: relax again too strict sanity checks to allow reading of valid images such as https://gitlab.com/libtiff/libtiff/-/issues/181#note_302535232. Fixes #181
+
+2020-03-09 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-52' into 'master'
+ contrib/win_dib/tiff2dib: fix Uninitialized variable: lpBits
+
+ Closes #52
+
+ See merge request libtiff/libtiff!121
+
+2020-03-09 Thomas Bernard <miniupnp@free.fr>
+
+ contrib/win_dib/tiff2dib: fix Uninitialized variable: lpBits.
+ fixes #52
+ http://bugzilla.maptools.org/show_bug.cgi?id=2469
+
+2020-03-08 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-58' into 'master'
+ Make TIFFTAG_CFAPATTERN variable count
+
+ Closes #58
+
+ See merge request libtiff/libtiff!120
+
+2020-03-08 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-158-no-predictor-in-webp' into 'master'
+ TIFFTAG_PREDICTOR is not supported for WebP
+
+ Closes #158
+
+ See merge request libtiff/libtiff!119
+
+2020-03-08 Sam Hasinoff <hasinoff@google.com>
+
+ Make TIFFTAG_CFAPATTERN variable count.
+ The TIFFTAG_CFAPATTERN tag (33422) from TIFF/EP, recently introduced in libtiff
+ 3363eda09d082e3e1dfffa6281f53085cac51ad3 / http://bugzilla.maptools.org/show_bug.cgi?id=2457
+ is described as having a fixed count of 4.
+ But the TIFF/EP spec says this should support a variable count (= CFARepeatRows * CFARepeatCols):
+
+ TIFF/EP, ISO 12234-2:2001
+ http://www.barrypearson.co.uk/top2009/downloads/TAG2000-22_DIS12234-2.pdf
+ page 18 and 26
+
+2020-03-08 Thomas Bernard <miniupnp@free.fr>
+
+ TIFFTAG_PREDICTOR is not supported for WebP.
+ fixes #158
+ https://gitlab.com/libtiff/libtiff/-/issues/158
+
+ this bug was introduced by 9eacd59fecc4ef593ac17689bc530ab451c8ec14
+ merge request !32
+
+2020-03-07 Adam Goode <adam@spicenitz.org>
+
+ Make the default whitepoint and ycbcrcoeffs arrays const.
+ Now that we are returning const pointers in TIFFGetFieldDefaulted,
+ we can now make these static default arrays const.
+
+ see #11
+
+2020-03-07 Adam Goode <adam@spicenitz.org>
+
+ Make pointers returned via TIFFGetField const.
+ According to http://bugzilla.maptools.org/show_bug.cgi?id=2125#c6
+ callers are not allowed to modify pointer or array values returned from
+ TIFFGetField or the like. So, make this explicit in the documentation
+ by specifying these things as const. Note that this is not an ABI
+ change, since C does not encode const in libraries. Also, this is
+ not really an API change, since the varargs call strips away all
+ the types anyway. So it really is more of a documentation change.
+
+ fixes #11
+
+2020-03-07 Even Rouault <even.rouault@spatialys.com>
+
+ CMake: Skip custom_dir_EXIF_231 test on shared builds to avoid issues on Windows
+
+2020-03-07 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'EXIF231_GPS_upgrade' into 'master'
+ EXIF 2.32 and GPS TIFF-tags and functionality upgraded.
+
+ See merge request libtiff/libtiff!91
+
+2020-03-07 Su_Laus <sulau@freenet.de>
+
+ EXIF 2.32 and GPS tags and functionality upgraded.
+ - Existing EXIF field definition of tags is upgraded to EXIF version 2.3.2
+ - EXIF-GPS structure, tags and access functions are added as special CustomDirectory (like it was done for EXIF).
+ - Test program custom_dir_EXIF_231.c added to test writing/reading of EXID IFD and GPS IFD tags
+ and to highlight some quirks of IFD-handling and peculiarities of reading/writing the different data types.
+ - Reading error for FileSource and SceneType tags corrected.
+
+ - EXIF_GPS_upgrade rebased onto c8c5309b765ef4ff097d2aaffbdb8f403db8967d (Merge branch 'Rational2DoublePrecision_correction' into 'master')
+ and adapted:
+ - tif_dirinfo.c: All rational tags set to TIFF_SETGET_FLOAT but only the GPSTAG_ tags set to TIFF_SETGET_DOUBLE.
+ - custom_dir_EXIF_231.c: Editorials amended and gcc warnings fixed.
+ - CMakeLists.txt: add_test(NAME "custom_dir_EXIF_231" COMMAND "custom_dir_EXIF_231") added.
+
+2020-03-07 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-55' into 'master'
+ ppm2tiff: support any bps value from 1 to 16
+
+ Closes #55
+
+ See merge request libtiff/libtiff!106
+
+2020-03-07 Thomas Bernard <miniupnp@free.fr>
+
+ ppm2tiff: Add test for 16bpc PPM.
+
+ ppm2tiff: remove unused argument warning.
+
+2020-03-07 Ludolf Holzheid <ludolf.holzheid@gmx.de>
+
+ ppm2tiff: support any bps value from 1 to 16.
+ fix #55
+ http://bugzilla.maptools.org/show_bug.cgi?id=2505
+
+ Patch originally submitted by Ludolf Holzheid <ludolf.holzheid@gmx.de>
+
+2020-03-06 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fax-test' into 'master'
+ add test for fax4 decoding
+
+ See merge request libtiff/libtiff!114
+
+2020-03-05 Thomas Bernard <miniupnp@free.fr>
+
+ add test for fax4 decoding.
+ This will check for regression on #46
+ https://gitlab.com/libtiff/libtiff/issues/46
+ http://bugzilla.maptools.org/show_bug.cgi?id=2434
+
+2020-03-05 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'freebsd-tests' into 'master'
+ make tests pass under FreeBSD.
+
+ See merge request libtiff/libtiff!113
+
+2020-03-05 Thomas Bernard <miniupnp@free.fr>
+
+ make tests pass under FreeBSD.
+ the -I option for the GNU diff and the FreeBSD diff
+ behaves differently regarding escaping the ( ) and |
+
+ By using two -I option, we avoid using such charracters.
+
+2020-03-05 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-31' into 'master'
+ HTML
+
+ Closes #31
+
+ See merge request libtiff/libtiff!111
+
+2020-03-05 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-179' into 'master'
+ tif_fax3.h: check for buffer overflow in EXPAND2D before "calling" CLEANUP_RUNS()
+
+ Closes #179
+
+ See merge request libtiff/libtiff!112
+
+2020-03-05 Thomas Bernard <miniupnp@free.fr>
+
+ v4.1.0.html: fix for validation.
+ long <!----------------> comments were replaced
+ because they confused some parsers
+
+ add DOCTYPE on v*.html.
+
+ fix HTML files so they are valid according to https://validator.w3.org.
+
+2020-03-05 Thomas Bernard <miniupnp@free.fr>
+
+ tif_fax3.h: check for buffer overflow in EXPAND2D before "calling" CLEANUP_RUNS()
+ fixes #179
+
+ this fixes the regression introduced in 02bb0175 / 72c4acef
+ ( merge request !110 )
+
+ It may be a better fix to do the overflow check in SETVALUE() but the
+ macro do { } while(0) construct makes it difficult to quit the loop
+ properly.
+
+2020-03-01 Thomas Bernard <miniupnp@free.fr>
+
+ index.html: fix unclosed <tt> tag.
+
+2020-03-01 Thomas Bernard <miniupnp@free.fr>
+
+ html: do not force colors (which are default anyway)
+ If needed, style should be set using CSS.
+
+ fixes #31
+ https://gitlab.com/libtiff/libtiff/issues/31
+ http://bugzilla.maptools.org/show_bug.cgi?id=2326
+
+2020-03-01 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFReadCustomDirectory(): fix potential heap buffer overflow when reading a custom directory, after a regular directory where a codec was active. Fixes https://gitlab.com/libtiff/libtiff/issues/178
+
+2020-03-01 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-46' into 'master'
+ fix decoding of fax4 images
+
+ Closes #46
+
+ See merge request libtiff/libtiff!110
+
+2020-02-29 Thomas Bernard <miniupnp@free.fr>
+
+ tif_fax3: better fix for CVE-2011-0192.
+ There are some legitimate case which were forbidden by the previous fix
+
+ tif_fax3.h: allow 0 length run in DECODE2D.
+ fixes #46
+ https://gitlab.com/libtiff/libtiff/issues/46
+ http://bugzilla.maptools.org/show_bug.cgi?id=2434
+
+2020-02-29 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'mingwlibm' into 'master'
+ Don't use libm with libtiff due to conflict with libmsvcrt
+
+ See merge request libtiff/libtiff!73
+
+2020-02-29 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'Rational2DoublePrecision_correction' into 'master'
+ tif_dirwrite.c: bugfix DoubleToSrational() for plain signed integers
+
+ See merge request libtiff/libtiff!109
+
+2020-02-29 Su_Laus <sulau@freenet.de>
+
+ tif_dirwrite.c: bugfix DoubleToSrational(), which returns plain signed integer values always as unsigned rationals. Add a test into rational_precision2double.c for "-1.0" and some editorials in tif_dirwrite.c. (code is related to 6df997c786928757caea0dd68d26ea5f098f49df changes).
+
+2020-02-29 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue-174' into 'master'
+ tif_fax3.c: check buffer overflow in Fax4Decode()
+
+ Closes #174
+
+ See merge request libtiff/libtiff!108
+
+2020-02-29 Thomas Bernard <miniupnp@free.fr>
+
+ Fax4Decode(): log error message in case of buffer overrun.
+
+ tif_fax3.c: check buffer overflow in Fax4Decode()
+ fixes #174
+
+2020-02-28 Even Rouault <even.rouault@spatialys.com>
+
+ typo fixes in code comments.
+
+ ToRationalEuclideanGCD: remove useless test that confuses Coverity Scan about a potential later modulo by zero
+
+2020-02-27 Even Rouault <even.rouault@spatialys.com>
+
+ tif_dirwrite.c: fix other warnings related to 6df997c786928757caea0dd68d26ea5f098f49df changes
+
+ rational_precision2double.c: fix many warnings, and do not build it on CMake on shared lib builds
+
+ tif_dirwrite.c: fix various warnings found when building GDAL with internal libtiff after 6df997c786928757caea0dd68d26ea5f098f49df changes
+
+ tif_dirwrite.c: qualify ToRationalEuclideanGCD() with static.
+
+2020-02-27 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'Rational2DoublePrecision' into 'master'
+ Rational with Double Precision Upgrade
+
+ See merge request libtiff/libtiff!100
+
+2020-02-27 Su_Laus <sulau@freenet.de>
+
+ Rational with Double Precision Upgrade.
+ Unfortunately, custom rational tags (TIFF_RATIONAL with field_bit=FIELD_CUSTOM) are defined as TIFF_SETGET_DOUBLE
+ but for the reading interface and LibTiff internally they are stored ALWAYS as floating point SINGLE precision.
+ Double precision custom rational tags are not supported by LibTiff.
+
+ For the GPS tags in WGS84 a higher accuracy / precision is needed.
+ Therefore, this upgrade is made, keeping the old interface for the already defined tags and allowing a double precision definition,
+ as well as calculating rationals with higher accuracy / precision.
+ This higher accuracy can be used for newly defined tags like that in EXIF/GPS.
+
+ Refer also to the very old Bugzilla issue 2542 (#69)
+
+ A test file rational_precision2double.c is added, which shows prevention of the old interface to the already defined custom rational tags
+ with the standard library as well as with the upgraded library.
+
+ Also TIFFTAG_XRESOLUTION, TIFFTAG_YRESOLUTION, TIFFTAG_XPOSITION, TIFFTAG_YPOSITION amended from TIFF_SETGET_DOUBLE to TIFF_SETGET_FLOAT and testcase inserted in rational_precision2double.c
+
+2020-02-26 Chris Degawa <ccom@randomderp.com>
+
+ mingw-w64 cmake: Don't find libm.
+ mingw-w64 will provide libm symbols by default without -lm and mingw-64's
+ libm is just a stub.
+
+ This is just to make sure that on systems with msys2 and also cygwin, cmake
+ doesn't find a libm that actually contains math functions.
+
+2020-02-26 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'division-by-zero' into 'master'
+ tools/tiffcp.c: fix potential division by zero
+
+ See merge request libtiff/libtiff!83
+
+2020-02-26 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix-unused-warning' into 'master'
+ warnings: mark conditionally used parameters
+
+ See merge request libtiff/libtiff!49
+
+2020-02-26 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'master' into 'master'
+ fix issue #78 warnings regarding RichTIFFIPTC data type
+
+ Closes #78
+
+ See merge request libtiff/libtiff!99
+
+2020-02-26 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'win64-handle-casts-warn-fix' into 'master'
+ Avoid warnings about casts between HANDLE and int in Win64 builds
+
+ Closes #2
+
+ See merge request libtiff/libtiff!93
+
+2020-02-26 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bug2839' into 'master'
+ raw2tiff: avoid divide by 0
+
+ Closes #151
+
+ See merge request libtiff/libtiff!103
+
+2020-02-26 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bug2669' into 'master'
+ tiff2pdf: palette bound check in t2p_sample_realize_palette()
+
+ Closes #82
+
+ See merge request libtiff/libtiff!104
+
+2020-02-26 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'int-shift' into 'master'
+ tiffcrop: fix asan runtime error caused by integer promotion
+
+ See merge request libtiff/libtiff!105
+
+2020-02-26 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bug-2538' into 'master'
+ libtiff.html: fix function casing
+
+ Closes #68
+
+ See merge request libtiff/libtiff!107
+
+2020-02-16 Thomas Bernard <miniupnp@free.fr>
+
+ raw2tiff: avoid divide by 0.
+ fixes #151 / http://bugzilla.maptools.org/show_bug.cgi?id=2839
+
+ first memcmp() lines before computing correlation
+ and always avoid divide by 0 anyway
+
+2020-02-09 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bug2855' into 'master'
+ tiff2ps: fix heap buffer read overflow in PSDataColorContig()
+
+ Closes #161
+
+ See merge request libtiff/libtiff!102
+
+2020-02-08 Thomas Bernard <miniupnp@free.fr>
+
+ libtiff.html: fix function casing.
+
+ libtiff.html: fix function casing.
+ fixes #68 / http://bugzilla.maptools.org/show_bug.cgi?id=2538
+
+2020-02-08 Thomas Bernard <miniupnp@free.fr>
+
+ tiffcrop: fix asan runtime error caused by integer promotion.
+ tiffcrop.c:4027:20: runtime error: left shift of 190 by 24 places cannot be represented in type 'int'
+
+ C treats (byte << 24) as an int expression.
+ casting explicitly to unsigned type uint32 avoids the problem.
+
+ the same issue has been fixed elsewhere with a24213691616e7cd35aa3e2805493de80c7e4fcf
+
+ I detected the bug with the test file of #86
+
+2020-02-08 Thomas Bernard <miniupnp@free.fr>
+
+ tiff2pdf: palette bound check in t2p_sample_realize_palette()
+ fixes #82
+
+2020-02-08 Thomas Bernard <miniupnp@free.fr>
+
+ tiff2ps: fix heap buffer read overflow in PSDataColorContig()
+ fixes #161 / http://bugzilla.maptools.org/show_bug.cgi?id=2855
+
+ in 05029fb7f1ecf771abaf90b5705b6cab9eb522a7 I missed that 1 extra byte is read
+ in this loop.
+
+2020-02-05 Even Rouault <even.rouault@spatialys.com>
+
+ tif_dirread.c: suppress CLang static Analyzer 9.0 false positive.
+
+2020-02-01 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFSetupStrips: enforce 2GB limitation of Strip/Tile Offsets/ByteCounts arrays
+ TIFFWriteDirectoryTagData() has an assertion that checks that the
+ arrays are not larger than 2GB. So error out earlier if in that situation.
+
+2020-01-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ Simplify nmake configuration for building port directory. Now there is only one boolean setting to enable building strtoll() and strtoull() port functions. The boolean setting enables the necessary port files to be built, but the remainder of the logic is via pre-processor code in the common tif_config.h, which was prepared before entering the port directory to do a build.
+
+2020-01-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ Make sure that tif_config.h is produced prior to entering the port directory and add an include path so that the port files can include tif_config.h. Do not actually include tif_config.h at this time since CMake and Autotools builds are not prepared for that. This issue could be handled by updating the CMake and Autotools builds or by adding a define which directs libport.h to include tif_config.h.
+
+2020-01-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ Fix nmake build mistakes in my last commit:
+ tif_config.vc.h:
+
+ Always define HAVE_STRTOL/HAVE_STRTOUL.
+ Define HAVE_STRTOLL/HAVE_STRTOULL if _MSC_VER >= 1900.
+
+ nmake.opt:
+
+ Provide defaults suitable for MSVC prior to 14.0.
+
+ libport.h:
+
+ The sense of the pre-processor logic was inverted from what it
+ should be. The intention is to only provide the prototype if the
+ function is missing.
+
+2020-01-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ Add nmake build support for manually configuring the 'port' files to be built based on MSVC features. Include tif_config.h in tools/tiffset.c.
+
+2020-01-23 Even Rouault <even.rouault@spatialys.com>
+
+ Adjust previous fix to avoid undue warning in some situations triggered by GDAL
+
+2020-01-12 Even Rouault <even.rouault@spatialys.com>
+
+ _TIFFPartialReadStripArray: bring back support for non-conformant SLONG8 data type
+ Such as in https://github.com/OSGeo/gdal/issues/2165
+
+2020-01-07 Even Rouault <even.rouault@spatialys.com>
+
+ test: add test for single-strip OJPEG file without RowsPerStrip tag (like in CR2 files)
+
+ OJPEGReadHeaderInfo: if rowsperstrip not defined, then assume one-single-strip. Complementary fix to 0356ea76bac908c61160d735f078437ace953bd3
+
+2019-12-16 Angel Sánchez <angelsanchez@inedit.com>
+
+ fix issue #78 warnings regarding RichTIFFIPTC data type.
+
+2019-12-14 Even Rouault <even.rouault@spatialys.com>
+
+ contrib/oss-fuzz/build.sh: fix broken if construct.
+
+2019-11-28 Even Rouault <even.rouault@spatialys.com>
+
+ contrib/oss-fuzz/build.sh: other attempt at fixing build failure.
+
+2019-11-20 Even Rouault <even.rouault@spatialys.com>
+
+ contrib/oss-fuzz/build.sh: install liblzma-dev for x86_64 builds.
+
+2019-11-17 Even Rouault <even.rouault@spatialys.com>
+
+ contrib/oss-fuzz/build.sh: install liblzma-dev:i386 on i386 builds.
+
+2019-11-15 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'cmake-parse' into 'master'
+ CMake: simplify parsing variables from configure
+
+ See merge request libtiff/libtiff!98
+
+2019-11-15 Rolf Eike Beer <eb@emlix.com>
+
+ CMake: simplify parsing variables from configure.
+
+2019-11-14 Even Rouault <even.rouault@spatialys.com>
+
+ contrib/oss-fuzz/build.sh: fix ossfuzz build by statically linking to lzma
+
+2019-11-12 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_ojpeg_172' into 'master'
+ OJPEG: fix broken sanity check added in 4.1.0 (#fixes 172)
+
+ See merge request libtiff/libtiff!97
+
+2019-11-11 Even Rouault <even.rouault@spatialys.com>
+
+ OJPEG: fix broken sanity check added in 4.1.0, and add two OJPEG test files
+
+ test/: add missing generated .sh files.
+
+2019-11-04 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix-missing-checks-TIFFGetField-tiffcrop' into 'master'
+ adds missing checks on TIFFGetField in tiffcrop tool
+
+ Closes #170
+
+ See merge request libtiff/libtiff!96
+
+2019-11-04 Bug Checkers <coolbugcheckers@gmail.com>
+
+ adds missing checks on TIFFGetField in tiffcrop tool (fixes #170)
+
+2019-11-04 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'adds-missing-TIFFClose-rgb2ycbcr' into 'master'
+ adds a missing TIFFClose in rgb2ycbcr tool
+
+ See merge request libtiff/libtiff!95
+
+2019-11-04 Mansour Ahmadi <mansourweb@gmail.com>
+
+ adds a missing TIFFClose in rgb2ycbcr tool.
+
+2019-11-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ libtiff 4.1.0 released.
+
+ Added a step for updating the legacy ChangeLog file.
+
+ Ignore emacs temporary files (ending with tilde character).
+
+ Added release summary page for the 4.1.0 release.
+
+ Fix Cmake HAVE_GETOPT for systems which declare getopt in stdio.h. Fix utility baked-in getopt prototype which appears when HAVE_GETOPT is not defined.
+
+ Fax2tiff.sh needs to remove its output file in advance. Syntax changes so that bash is not required.
+
+2019-10-26 Even Rouault <even.rouault@spatialys.com>
+
+ tif_jpeg.c: extra cast to silence Coverity warning. GDAL CID 1406475.
+
+2019-10-23 Even Rouault <even.rouault@spatialys.com>
+
+ tif_jpeg.c: fix warning added by previous commit (on 32bit builds)
+
+2019-10-23 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'coverity-fixes' into 'master'
+ Coverity fixes
+
+ See merge request libtiff/libtiff!94
+
+2019-10-22 Timothy Lyanguzov <timothy.lyanguzov@sap.com>
+
+ Use 64-bit calculations correctly.
+
+ Fix size calculation to use 64-bit tmsize_t correctly.
+
+ Make bytesperclumpline calculations using tmsize_t type.
+
+2019-10-03 Even Rouault <even.rouault@spatialys.com>
+
+ tif_read: align code of TIFFReadRawStrip() and TIFFReadRawTile() that differed for non good reason. Non-functional change normally. (fixes GitLab #162)
+
+2019-10-01 Even Rouault <even.rouault@spatialys.com>
+
+ HTML: update for GitLab issues.
+
+2019-09-29 Even Rouault <even.rouault@spatialys.com>
+
+ html/v3.5.6-beta.html: redact URL of defunct web site.
+
+ Website: update links to mailing list.
+
+2019-09-17 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFReadAndRealloc(): avoid too large memory allocation attempts. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=17244
+
+2019-09-03 Even Rouault <even.rouault@spatialys.com>
+
+ ByteCountLooksBad and EstimateStripByteCounts: avoid unsigned integer overflows. Fixes https://oss-fuzz.com/testcase-detail/5686156066291712 and https://oss-fuzz.com/testcase-detail/6332499206078464
+
+2019-09-02 Even Rouault <even.rouault@spatialys.com>
+
+ tif_ojpeg.c: avoid relying on isTiled macro being wrapped in ()
+
+ tif_ojpeg.c: avoid use of uninitialized memory on edge/broken file. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16844
+
+ tiff_read_rgba_fuzzer.cc: add a -DSTANDALONE mode for easier reproduction of oss-fuzz reports
+
+2019-09-01 Even Rouault <even.rouault@spatialys.com>
+
+ tif_dirread.c: allocChoppedUpStripArrays(). avoid unsigned integer overflow. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16846
+
+2019-08-27 Even Rouault <even.rouault@spatialys.com>
+
+ tif_ojpeg.c: avoid unsigned integer overflow. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16793
+
+2019-08-26 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFReadDirEntryData(): rewrite to avoid unsigned integer overflow (not a bug). Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16792
+
+ TIFFFetchDirectory(): fix invalid cast from uint64 to tmsize_t. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16784
+
+2019-08-25 Even Rouault <even.rouault@spatialys.com>
+
+ JPEG: avoid use of uninitialized memory on corrupted files.
+ Follow-up of cf3ce6fab894414a336546f62adc57f02590a22c
+ Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16602
+ Credit to OSS Fuzz
+
+2019-08-23 Even Rouault <even.rouault@spatialys.com>
+
+ _TIFFPartialReadStripArray(): avoid unsigned integer overflow. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16685
+
+ OJPEGWriteHeaderInfo(): avoid unsigned integer overflow on strile dimensions close to UINT32_MAX. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16683
+
+ TIFFFillStrip(): avoid harmless unsigned integer overflow. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16653
+
+ EstimateStripByteCounts(): avoid unsigned integer overflow. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16643&
+
+ tif_ojpeg: avoid unsigned integer overflow (probably not a bug). Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16635
+
+ tif_thunder: avoid unsigned integer overflow (not a bug). Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16632
+
+2019-08-22 Even Rouault <even.rouault@spatialys.com>
+
+ _TIFFMultiply32() / _TIFFMultiply64(): avoid relying on unsigned integer overflow (not a bug)
+
+ EstimateStripByteCounts(): avoid unsigned integer overflow.
+
+2019-08-21 Even Rouault <even.rouault@spatialys.com>
+
+ EstimateStripByteCounts(): avoid unsigned integer overflow.
+
+2019-08-20 Even Rouault <even.rouault@spatialys.com>
+
+ EstimateStripByteCounts(): avoid harmless unsigned integer overflow.
+
+ _TIFFPartialReadStripArray(): avoid triggering unsigned integer overflow with -fsanitize=unsigned-integer-overflow (not a bug, this is well defined by itself)
+
+2019-08-18 Even Rouault <even.rouault@spatialys.com>
+
+ tiff2ps: fix use of wrong data type that caused issues (/Height being written as 0) on 64-bit big endian platforms
+
+2019-08-16 Even Rouault <even.rouault@spatialys.com>
+
+ setByteArray(): fix previous commit.
+
+ setByteArray(): avoid potential signed integer overflow. Pointed by Hendra Gunadi. No actual problem known (which does not mean there wouldn't be any. Particularly on 32bit builds)
+
+2019-08-15 Even Rouault <even.rouault@spatialys.com>
+
+ RGBA interface: fix integer overflow potentially causing write heap buffer overflow, especially on 32 bit builds. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16443. Credit to OSS Fuzz
+
+2019-08-14 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_integer_overflow' into 'master'
+ Fix integer overflow in _TIFFCheckMalloc() and other implementation-defined behaviour (CVE-2019-14973)
+
+ See merge request libtiff/libtiff!90
+
+2019-08-13 Even Rouault <even.rouault@spatialys.com>
+
+ Fix integer overflow in _TIFFCheckMalloc() and other implementation-defined behaviour (CVE-2019-14973)
+ _TIFFCheckMalloc()/_TIFFCheckRealloc() used a unsafe way to detect overflow
+ in the multiplication of nmemb and elem_size (which are of type tmsize_t, thus
+ signed), which was especially easily triggered on 32-bit builds (with recent
+ enough compilers that assume that signed multiplication cannot overflow, since
+ this is undefined behaviour by the C standard). The original issue which lead to
+ this fix was triggered from tif_fax3.c
+
+ There were also unsafe (implementation defied), and broken in practice on 64bit
+ builds, ways of checking that a uint64 fits of a (signed) tmsize_t by doing
+ (uint64)(tmsize_t)uint64_var != uint64_var comparisons. Those have no known
+ at that time exploits, but are better to fix in a more bullet-proof way.
+ Or similarly use of (int64)uint64_var <= 0.
+
+2019-08-12 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFClientOpen(): fix memory leak if one of the required callbacks is not provided. Fixed Coverity GDAL CID 1404110
+
+ OJPEGReadBufferFill(): avoid very long processing time on corrupted files. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16400. master only
+
+2019-08-10 Even Rouault <even.rouault@spatialys.com>
+
+ oss-fuzz/tiff_read_rgba_fuzzer.cc: fix wrong env variable value in previous commit
+
+ oss-fuzz/tiff_read_rgba_fuzzer.cc: avoid issue with libjpeg-turbo and MSAN
+
+ OJPEG: fix integer division by zero on corrupted subsampling factors. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=15824. Credit to OSS Fuzz
+
+ Merge branch 'ossfuzz_i386'
+
+ contrib/oss-fuzz/build.sh: fix for i386 build of jbigkit, and use $LIB_FUZZING_ENGINE
+
+2019-08-10 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'patch-1' into 'master'
+ fix two tiny typos
+
+ See merge request libtiff/libtiff!89
+
+2019-08-10 Reto Kromer <rk@reto.ch>
+
+ fix two tiny typos.
+
+2019-08-09 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'patch-1' into 'master'
+ fix a typo in man page
+
+ See merge request libtiff/libtiff!88
+
+2019-08-09 Reto Kromer <rk@reto.ch>
+
+ fix typo.
+
+2019-08-04 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'TIFFTAGID_Zero_reading_IGNORE' into 'master'
+ Suppressed Reading of Tiff tags with ID = 0 (like GPSVERSIONID) corrected.
+
+ See merge request libtiff/libtiff!77
+
+2019-08-04 Su Laus <sulau@freenet.de>
+
+ Reading of Tiff tags with ID = 0 (like GPSVERSIONID) corrected.
+ IGNORE placeholder in tif_dirread.c is now replaced by a field dir_ignore in the TIFFDirEntry structure
+
+ Currently, in tif_dirread.c a special IGNORE value for the tif tags is defined
+ in order to flag status preventing already processed tags from further processing.
+ This irrational behaviour prevents reading of custom tags with id code 0 - like tag GPSVERSIONID from EXIF 2.31 definition.
+
+ An additional field 'tdir_ignore' is now added to the TIFFDirEntry structure and code is changed
+ to allow tags with id code 0 to be read correctly.
+
+ This change was already proposed as pending improvement in tif_dirread.c around line 32.
+
+ Reference is also made to:
+ - Discussion in https://gitlab.com/libtiff/libtiff/merge_requests/39
+ - http://bugzilla.maptools.org/show_bug.cgi?id=2540
+
+ Comments and indentation adapted.
+
+ Preparation to rebase onto master
+
+2019-07-16 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'cmake_amd64' into 'master'
+ CMakeLists.txt: properly set value of HOST_FILLORDER to LSB2MSB for Windows CMake builds
+
+ See merge request libtiff/libtiff!87
+
+2019-07-15 Even Rouault <even.rouault@spatialys.com>
+
+ CMakeLists.txt: properly set value of HOST_FILLORDER to LSB2MSB for Windows CMake builds
+ As can be seen in https://ci.appveyor.com/project/rleigh-codelibre/libtiff-didfs/builds/25846668/job/ory5w098j8wcij9x
+ log, the HOST_FILLORDER is not properly set:
+
+ [00:02:58] -- CMAKE_HOST_SYSTEM_PROCESSOR set to AMD64
+ [00:02:58] -- HOST_FILLORDER set to FILLORDER_MSB2LSB
+
+ The reason is that we match the "amd64.*" lowercase string whereas
+ CMAKE_HOST_SYSTEM_PROCESSOR is set to AMD64 uppercase.
+
+2019-07-09 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFWriteCheck(): call TIFFForceStrileArrayWriting() when needed (should have gone with eaeca6274ae71cdfaeb9f673b6fb0f3cfc0e6ce5) (master only)
+
+2019-07-09 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_chromium_925269' into 'master'
+ OJPEG: avoid use of uninitialized memory on corrupted files
+
+ See merge request libtiff/libtiff!86
+
+2019-07-05 Even Rouault <even.rouault@spatialys.com>
+
+ OJPEG: avoid use of uninitialized memory on corrupted files.
+ Fixes https://bugs.chromium.org/p/chromium/issues/detail?id=925269
+ Patch from Lei Zhang with little adaptations.
+
+2019-06-29 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix-division-by-zero' into 'master'
+ Return infinite distance when denominator is zero.
+
+ See merge request libtiff/libtiff!85
+
+2019-06-29 Dirk Lemstra <dirk@lemstra.org>
+
+ Return infinite distance when denominator is zero.
+
+2019-06-29 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'typetests' into 'master'
+ Add test to check that libtiff types have the correct size
+
+ See merge request libtiff/libtiff!57
+
+2019-05-31 Thomas Bernard <miniupnp@free.fr>
+
+ make TIFF_SSIZE_T the same bitwidth as TIFF_SIZE_T.
+ it was previously the same bitwidth as unsigned char *
+ Pointers can be larger than size_t.
+
+2019-05-31 Thomas Bernard <miniupnp@free.fr>
+
+ Add test to check that libtiff types have the correct size.
+ in configure/CMakeList.txt :
+
+ - TIFF_INT8_T/TIFF_UINT8_T is signed/unsigned char
+ sizeof(char)==1 in C standard
+ - TIFF_INT16_T/TIFF_UINT16_T is signed/unsigned short
+ sizeof(short)>=2 in C standard
+ - TIFF_INT32_T/TIFF_UINT32_T is defined so its sizeof() is 4
+
+ - TIFF_INT64_T/TIFF_UINT64_T is defined so its sizeof() is 8
+
+ - TIFF_SIZE_T is defined so it has same sizeof() than size_t
+
+ - TIFF_SSIZE_T is defined so it has same sizeof() than unsigned char *
+
+2019-05-29 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'defer_strile_writing' into 'master'
+ Add TIFFDeferStrileArrayWriting() and TIFFForceStrileArrayWriting()
+
+ See merge request libtiff/libtiff!82
+
+2019-05-29 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'TIFFReadFromUserBuffer' into 'master'
+ Add TIFFReadFromUserBuffer()
+
+ See merge request libtiff/libtiff!81
+
+2019-05-26 Even Rouault <even.rouault@spatialys.com>
+
+ Fix vulnerability in 'D' (DeferStrileLoad) mode (master only) (fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14908)
+
+2019-05-25 Even Rouault <even.rouault@spatialys.com>
+
+ Replace 'stripped' by 'striped' in error messages.
+
+2019-05-25 Even Rouault <even.rouault@spatialys.com>
+
+ Add TIFFDeferStrileArrayWriting() and TIFFForceStrileArrayWriting()
+ Those advanced writing functions must be used in a particular sequence
+ to make their intended effect. Their aim is to control when/where
+ the [Strip/Tile][Offsets/ByteCounts] arrays are written into the file.
+
+ The purpose of this is to generate 'cloud-optimized geotiff' files where
+ the first KB of the file only contain the IFD entries without the potentially
+ large strile arrays. Those are written afterwards.
+
+ The typical sequence of calls is:
+ TIFFOpen()
+ [ TIFFCreateDirectory(tif) ]
+ Set fields with calls to TIFFSetField(tif, ...)
+ TIFFDeferStrileArrayWriting(tif)
+ TIFFWriteCheck(tif, ...)
+ TIFFWriteDirectory(tif)
+ ... potentially create other directories and come back to the above directory
+ TIFFForceStrileArrayWriting(tif): emit the arrays at the end of file
+
+ See test/defer_strile_writing.c for a practical example.
+
+2019-05-24 Even Rouault <even.rouault@spatialys.com>
+
+ Fix vulnerability introduced by defer strile loading (master only)
+ Found on GDAL with https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14894
+ Disabling the TIFF_DEFERSTRILELOAD bit in ChopupStripArray() was a
+ bad idea since when using TIFFReadDirectory() to reload the directory again
+ would lead to a different value of td_rowsperstrip, which could confuse
+ readers if they relied on the value found initially.
+
+ Fix typo in error message (master only)
+
+2019-05-22 Even Rouault <even.rouault@spatialys.com>
+
+ Add TIFFReadFromUserBuffer()
+ This function replaces the use of TIFFReadEncodedStrip()/TIFFReadEncodedTile()
+ when the user can provide the buffer for the input data, for example when
+ he wants to avoid libtiff to read the strile offset/count values from the
+ [Strip|Tile][Offsets/ByteCounts] array.
+
+ libtiff.def: add missing new symbols.
+
+ test/defer_strile_loading.c: fix warning with Visual C++
+
+ _TIFFRewriteField(): fix for bigtiff case (master only)
+ 116cf67f4c59196605abdb244657c3070c4310af made StripByteCount/TileByteCount to
+ always be rewritten as TIFF_LONG8.
+
+2019-05-21 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'ondemand_strile_offbytecount_loading' into 'master'
+ Make defer strile offset/bytecount loading available at runtime
+
+ See merge request libtiff/libtiff!79
+
+2019-05-21 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bigtiff_write_bytecount_on_long_when_possible' into 'master'
+ Create TileByteCounts/StripByteCounts tag with SHORT (ClassicTIFF/BigTIFF) or LONG (BigTIFF) type when possible
+
+ See merge request libtiff/libtiff!78
+
+2019-05-21 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'html_link' into 'master'
+ libtiff.html, bigtiffpr.html: absolute => relative link
+
+ See merge request libtiff/libtiff!80
+
+2019-05-14 Thomas Bernard <miniupnp@free.fr>
+
+ libtiff.html, bigtiffpr.html: absolute => relative link.
+
+2019-05-10 Even Rouault <even.rouault@spatialys.com>
+
+ Make defer strile offset/bytecount loading available at runtime.
+ ... and add per-strile offset/bytecount loading capabilities.
+
+ Part of this commit makes the behaviour that was previously met when
+ libtiff was compiled with -DDEFER_STRILE_LOAD available for default builds
+ when specifying the new 'D' (Deferred) TIFFOpen() flag. In that mode, the [Tile/Strip][ByteCounts/Offsets]
+ arrays are only loaded when first accessed. This can speed-up the opening
+ of files stored on the network when just metadata retrieval is needed.
+ This mode has been used for years by the GDAL library when compiled with
+ its embedded libtiff copy.
+
+ To avoid potential out-of-tree code (typically codecs) that would use
+ the td_stripbytecount and td_stripoffset array inconditionnaly assuming they
+ have been loaded, those have been suffixed with _p (for protected). The
+ use of the new functions mentioned below is then recommended.
+
+ Another addition of this commit is the capability of loading only the
+ values of the offset/bytecount of the strile of interest instead of the
+ whole array. This is enabled with the new 'O' (Ondemand) flag of TIFFOpen()
+ (which implies 'D'). That behaviour has also been used by GDAL, which hacked
+ into the td_stripoffset/td_stripbytecount arrays directly. The new code
+ added in the _TIFFFetchStrileValue() and _TIFFPartialReadStripArray() internal
+ functions is mostly a port of what was in GDAL GTiff driver previously.
+
+ Related to that, the public TIFFGetStrileOffset[WithErr]() and TIFFGetStrileByteCount[WithErr]()
+ functions have been added to API. They are of particular interest when
+ using sparse files (with offset == bytecount == 0) and you want to detect
+ if a strile is present or not without decompressing the data, or updating
+ an existing sparse file.
+ They will also be used to enable a future enhancement where client code can entirely
+ skip bytecount loading in some situations
+
+ A new test/defer_strile_loading.c test has been added to test the above
+ capabilities.
+
+2019-05-10 Even Rouault <even.rouault@spatialys.com>
+
+ Creation: use SHORT type when possible for StripByteCounts/TileByteCounts
+ This follows the same logic as previous commit.
+
+2019-05-09 Even Rouault <even.rouault@spatialys.com>
+
+ BigTIFF creation: write TileByteCounts/StripByteCounts tag with LONG when possible
+ In most situations of BigTIFF file, the tile/strip sizes are of reasonable size,
+ that is they fit on a 4-byte LONG. So in that case, use LONG instead of LONG8
+ to save some space. For uncompressed file, it is easy to detect such situations
+ by checking at the TIFFTileSize64()/TIFFStripSize64() return. For compressed file,
+ we must take into account the fact that compression may sometimes result in
+ larger compressed data. So we allow this optimization only for a few select
+ compression times, and take a huge security margin (10x factor). We also only
+ apply this optimization on multi-strip files, so as to allow easy on-the-fly
+ growing of single-strip files whose strip size could grow above the 4GB threshold.
+
+ This change is compatible with the BigTIFF specification. According to
+ https://www.awaresystems.be/imaging/tiff/bigtiff.html:
+ "The StripOffsets, StripByteCounts, TileOffsets, and TileByteCounts tags are
+ allowed to have the datatype TIFF_LONG8 in BigTIFF. Old datatypes TIFF_LONG,
+ and TIFF_SHORT where allowed in the TIFF 6.0 specification, are still valid in BigTIFF, too. "
+ On a practical point of view, this is also compatible on reading/writing of
+ older libtiff 4.X versions.
+
+ The only glitch I found, which is rather minor, is when using such a BigTIFF
+ file with TileByteCounts/StripByteCounts written with TIFF_LONG, and updating
+ it with an older libtiff 4.X version with a change in the
+ [Tile/Strip][ByteCounts/Offsets] array. In that case the _TIFFRewriteField()
+ function will rewrite the directory and array with TIFF_LONG8, instead of updating
+ the existing array (this is an issue fixed by this commit). The file will
+ still be valid however, hence the minor severity of this.
+
+2019-05-08 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bug2799' into 'master'
+ fix fax2tiff
+
+ See merge request libtiff/libtiff!55
+
+2019-05-08 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bug_2829' into 'master'
+ WIN32: use tif_win32.c when building with CMake
+
+ See merge request libtiff/libtiff!75
+
+2019-05-06 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'FILESOURCE_SCENETYPE_reading' into 'master'
+ Reading error for FileSource and SceneType tags corrected.
+
+ See merge request libtiff/libtiff!76
+
+2019-05-06 Su Laus <sulau@freenet.de>
+
+ Reading error for FileSource and SceneType tags corrected.
+ EXIF tags FILESOURCE and SCENETYPE are defined as TIFF_UNDEFINED and field_readcount==1!
+ There is a bug in TIFFReadDirEntryByte() preventing to read correctly type TIFF_UNDEFINED fields with field_readcount==1
+ Upgrade of TIFFReadDirEntryByte() with added TIFF_UNDEFINED switch-entry allows libtiff to read those tags correctly.
+
+2019-04-25 Thomas Bernard <miniupnp@free.fr>
+
+ WIN32: use tif_win32.c when building with CMake.
+ see http://bugzilla.maptools.org/show_bug.cgi?id=2829
+
+ the top CMakeLists.txt defines
+ win32_io and USE_WIN32_FILEIO
+
+ WIN32_IO is defined nowhere in CMake (only in automake things)
+
+2019-04-25 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'gitlab_pages' into 'master'
+ Advertise https://libtiff.gitlab.io/libtiff/ as mirror
+
+ See merge request libtiff/libtiff!70
+
+2019-04-25 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bug_2844' into 'master'
+ tiff2ps.c: PSDataColorContig(): avoid heap buffer overrun
+
+ See merge request libtiff/libtiff!69
+
+2019-04-25 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue_2785' into 'master'
+ tiff2pdf.c: don't call t2p_tile_collapse_left() for Ycbcr
+
+ See merge request libtiff/libtiff!64
+
+2019-04-11 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_gdal_1439' into 'master'
+ TIFFWriteEncodedStrip/TIFFWriteEncodedTile: fix rewriting of LZW-compressed data
+
+ See merge request libtiff/libtiff!74
+
+2019-04-11 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFWriteEncodedStrip/TIFFWriteEncodedTile: fix rewriting of LZW-compressed data
+ Fixes https://github.com/OSGeo/gdal/issues/1439
+
+ When rewriting a LZW tile/strip whose existing size is very close to a multiple of
+ 1024 bytes (and larger than 8192 bytes) with compressed data that is larger,
+ the new data was not placed at the end of the file, causing corruption.
+
+2019-04-08 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bug2848' into 'master'
+ tif_luv.c: LogLuvSetupEncode() error must return 0
+
+ See merge request libtiff/libtiff!72
+
+2019-04-03 Thomas Bernard <miniupnp@free.fr>
+
+ build/gitlab-ci: fix typo.
+
+ show test-suite.log in gitlab-ci.
+ useful when build fails
+
+ Add output check for tiff2ps.
+ note : the reference files have been generated in master branch
+
+2019-03-23 Even Rouault <even.rouault@spatialys.com>
+
+ tif_read.c: potentially fix false positive from Coverity Scan. CID 1400288
+
+ tif_read.c: potentially fix false positive from Coverity Scan. CID 1400271
+
+ tif_zip.c: remove dead code. CID 1400360.
+
+ tif_webp.c: remove false positive warning about dereference before null check. CID 1400255
+
+ tif_pixarlog.c: remove dead code. CID 1400342.
+
+ tif_pixarlog.c: avoid false positive Coverity Scan warnings about overflow. CID 1400300 and 1400367
+
+ tif_lzw.c: silence CoverityScan false positive. CID 1400355.
+
+ tif_luv.c: silence CoverityScan false positive. CID 1400231, 1400251, 1400254, 1400272, 1400318, 1400356
+
+ TryChopUpUncompressedBigTiff(): avoid potential division by zero. master only. GDAL Coverity CID 1400263
+
+2019-03-22 Thomas Bernard <miniupnp@free.fr>
+
+ tif_luv.c: LogLuvSetupEncode() error must return 0.
+ see http://bugzilla.maptools.org/show_bug.cgi?id=2848
+
+ if wrongly returning 1, the processing of incorrect file continues,
+ which causes problems.
+
+2019-03-22 Thomas Bernard <miniupnp@free.fr>
+
+ add a test for fax2tiff tool.
+
+2019-02-28 Thomas Bernard <miniupnp@free.fr>
+
+ tiff2pdf.c: don't call t2p_tile_collapse_left() when buffer size is wrong
+ see http://bugzilla.maptools.org/show_bug.cgi?id=2785
+
+ Advertise https://libtiff.gitlab.io/libtiff/ as mirror.
+ I'm put it above the maptools.org mirror because
+ Even Rouault believe at some point it will be completely removed
+
+2019-02-28 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bug_2826' into 'master'
+ tiff2pdf.c: check colormap pointers when loading CMYK with colormap
+
+ See merge request libtiff/libtiff!65
+
+2019-02-28 Thomas Bernard <miniupnp@free.fr>
+
+ tiff2pdf.c: check colormap pointers.
+ Avoid access to non initialized pointers
+ http://bugzilla.maptools.org/show_bug.cgi?id=2826
+
+2019-02-27 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_warnings' into 'master'
+ tiff2ps.c: fix warning caused by integer promotion
+
+ See merge request libtiff/libtiff!68
+
+2019-02-23 Thomas Bernard <miniupnp@free.fr>
+
+ PSDataColorContig(): avoid heap buffer overrun.
+ fixes http://bugzilla.maptools.org/show_bug.cgi?id=2844
+ each iteration of the loop read nc bytes
+
+2019-02-22 Thomas Bernard <miniupnp@free.fr>
+
+ tiff2ps.c: fix warning caused by integer promotion.
+ uint8 value is promoted to int in (value << 24) so -fsanitize
+ yield runtime errors :
+ tiff2ps.c:2969:33: runtime error: left shift of 246 by 24 places cannot be represented in type 'int'
+
+2019-02-22 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'large_strile_improvements' into 'master'
+ Large strile support improvements
+
+ See merge request libtiff/libtiff!63
+
+2019-02-21 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'gitlab-pages' into 'master'
+ ci: Add pages job
+
+ See merge request libtiff/libtiff!45
+
+2019-02-19 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue_2833' into 'master'
+ tiffcp.c: check that (Tile Width)*(Samples/Pixel) do no overflow
+
+ See merge request libtiff/libtiff!60
+
+2019-02-19 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue_2831' into 'master'
+ tiffcrop.c: fix invertImage() for bps 2 and 4
+
+ See merge request libtiff/libtiff!61
+
+2019-02-19 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue_2842' into 'master'
+ move _TIFFClampDoubleToFloat() to tif_aux.c
+
+ See merge request libtiff/libtiff!62
+
+2019-02-19 Even Rouault <even.rouault@spatialys.com>
+
+ tif_zip.c: allow reading and writing strips/tiles with more than 4 GB of compressed or uncompressed data
+
+ tif_dirread.c: when strip chopping is enabled, extend this mechanism to multi-strip uncompressed files with strips larger than 2GB to expose them as strips of ~500 MB
+
+2019-02-19 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'size_t_typo' into 'master'
+ CMakeLists.txt: fix TIFF_SIZE_T
+
+ See merge request libtiff/libtiff!59
+
+2019-02-12 Thomas Bernard <miniupnp@free.fr>
+
+ move _TIFFClampDoubleToFloat() to tif_aux.c.
+ the same function was declared in tif_dir.c and tif_dirwrite.c
+
+ see http://bugzilla.maptools.org/show_bug.cgi?id=2842
+
+2019-02-11 Thomas Bernard <miniupnp@free.fr>
+
+ tiffcrop.c: fix invertImage() for bps 2 and 4.
+ too much bytes were processed, causing a heap buffer overrun
+ http://bugzilla.maptools.org/show_bug.cgi?id=2831
+ the loop counter must be
+ for (col = 0; col < width; col += 8 / bps)
+
+ Also the values were not properly calculated. It should be
+ 255-x, 15-x, 3-x for bps 8, 4, 2.
+
+ But anyway it is easier to invert all bits as 255-x = ~x, etc.
+ (subtracting from a binary number composed of all 1 is like inverting
+ the bits)
+
+2019-02-11 Thomas Bernard <miniupnp@free.fr>
+
+ tiffcp.c: use INT_MAX.
+
+ check that (Tile Width)*(Samples/Pixel) do no overflow.
+ fixes bug 2833
+
+2019-02-03 Thomas Bernard <miniupnp@free.fr>
+
+ CMakeLists.txt: fix TIFF_SIZE_T.
+
+2019-02-02 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'master' into 'master'
+ Fix for simple memory leak that was assigned CVE-2019-6128.
+
+ See merge request libtiff/libtiff!50
+
+2019-02-02 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bug2835' into 'master'
+ tiff2ps: fix heap-buffer-overflow
+
+ See merge request libtiff/libtiff!53
+
+2019-02-02 Even Rouault <even.rouault@spatialys.com>
+
+ Fix warning (use of uninitialized value) added per d0a842c5dbad2609aed43c701a12ed12461d3405 (fixes https://gitlab.com/libtiff/libtiff/merge_requests/54#note_137742985)
+
+2019-02-02 Yuri Aksenov <yuri.aksenov@gmail.com>
+
+ fix fax2tiff.
+ see http://bugzilla.maptools.org/show_bug.cgi?id=2799
+ fixes d9bc8472e72549f29c0062c1cbd3d56f279f3be2
+
+2019-02-02 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffcrop' into 'master'
+ tiffcrop: shut up clang warnings
+
+ See merge request libtiff/libtiff!52
+
+2019-02-01 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bug2833' into 'master'
+ TIFFWriteDirectoryTagTransferfunction() : fix NULL dereferencing
+
+ See merge request libtiff/libtiff!54
+
+2019-02-01 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'gitignore' into 'master'
+ add test/ files to .gitignore
+
+ See merge request libtiff/libtiff!56
+
+2019-02-01 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'master' into 'master'
+ tif_dir: unset transferfunction field if necessary (CVE-2018-19210)
+
+ See merge request libtiff/libtiff!47
+
+2019-01-29 Thomas Bernard <miniupnp@free.fr>
+
+ add test/ files to .gitignore.
+
+2019-01-29 Thomas Bernard <miniupnp@free.fr>
+
+ TIFFWriteDirectoryTagTransferfunction() : fix NULL dereferencing.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2833
+
+ we must check the pointer is not NULL before memcmp() the memory
+
+2019-01-29 Thomas Bernard <miniupnp@free.fr>
+
+ tiff2ps: fix heap-buffer-overflow.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2834
+
+ usually the test (i < byte_count) is OK because the byte_count is divisible by samplesperpixel.
+ But if that is not the case, (i + ncomps) < byte_count should be used, or
+ maybe (i + samplesperpixel) <= byte_count
+
+2019-01-28 Thomas Bernard <miniupnp@free.fr>
+
+ tiffcrop: shut up clang warnings.
+ make the out filename building a bit more simple
+ and remove the use of strcat()
+
+2019-01-23 Scott Gayou <github.scott@gmail.com>
+
+ Fix for simple memory leak that was assigned CVE-2019-6128.
+ pal2rgb failed to free memory on a few errors. This was reported
+ here: http://bugzilla.maptools.org/show_bug.cgi?id=2836.
+
+2019-01-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ Fix tiff2ps error regarding "Inconsistent value of es" by allowing es to be zero. Problem was reported to the tiff mailing list by Julian H. Stacey on January 5, 2019.
+
+2018-12-13 Hugo Lefeuvre <hle@debian.org>
+
+ tif_dir: unset transferfunction field if necessary.
+ The number of entries in the transfer table is determined as following:
+
+ (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1
+
+ This means that whenever td->td_samplesperpixel or td->td_extrasamples are
+ modified we also need to make sure that the number of required entries in
+ the transfer table didn't change.
+
+ If it changed and the number of entries is higher than before we should
+ invalidate the transfer table field and free previously allocated values.
+ In the other case there's nothing to do, additional tf entries won't harm
+ and properly written code will just ignore them since spp - es < 1.
+
+ For instance this situation might happen when reading an OJPEG compressed
+ image with missing SamplesPerPixel tag. In this case the SamplesPerPixel
+ field might be updated after setting the transfer table.
+
+ see http://bugzilla.maptools.org/show_bug.cgi?id=2500
+
+ This commit addresses CVE-2018-19210.
+
+2018-12-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ Do not attempt to re-sync zip stream after reported data error from inflate().
+
+2018-12-07 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'resource-leaks' into 'master'
+ Fix two resource leaks
+
+ See merge request libtiff/libtiff!43
+
+2018-12-07 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'build-jbig' into 'master'
+ add jbig support to the fuzzer
+
+ See merge request libtiff/libtiff!42
+
+2018-12-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ tiffcrop.c: Avoid new clang warning about tools/tiffcrop.c "size argument in 'strncat' call appears to be size of the source".
+
+2018-11-28 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'webp_memleak' into 'master'
+ fixed mem leak in webp compression
+
+ See merge request libtiff/libtiff!48
+
+2018-11-28 Norman Barker <norman.barker@mapbox.com>
+
+ fixed mem leak in webp compression.
+
+2018-11-20 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'lossless_webp' into 'master'
+ fixed lossless webp compression config
+
+ See merge request libtiff/libtiff!46
+
+2018-11-20 Norman Barker <norman.barker@mapbox.com>
+
+ fixed lossless webp compression config.
+
+2018-11-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ snprintf porting fix for Visual Studio 2003.
+
+2018-11-18 Roger Leigh <rleigh@codelibre.net>
+
+ ci: Add pages job.
+
+2018-11-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ Change references from defunct ftp site to https site.
+
+2018-11-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: libtiff 4.0.10 released.
+
+ Change COMPRESSION_ZSTD to 50000 and COMPRESSION_WEBP to 50001.
+
+2018-11-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ Added preliminary release notes for release 4.0.10.
+
+2018-11-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ tiff2pdf: Eliminate compiler warning about snprintf output truncation when formatting pdf_datetime.
+
+2018-11-03 Olivier Paquet <olivier.paquet@gmail.com>
+
+ Merge branch 'no_tif_platform_console' into 'master'
+ Remove builtin support for GUI warning and error message boxes
+
+ See merge request libtiff/libtiff!24
+
+2018-11-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ tiffcrop.c: Eliminate compiler warning about snprintf output truncation when formatting filenum.
+
+ TWebPVGetField(): Add apparently missing break statement impacting TIFFTAG_WEBP_LOSSLESS.
+
+ Eliminate compiler warnings about duplicate definitions of streq/strneq macros.
+
+ Ignore generated files.
+
+ Remove and ignore files which are a product of autogen.sh.
+
+2018-11-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ Fix TIFFErrorExt() formatting of size_t type for 32-bit compiles.
+
+2018-10-30 Even Rouault <even.rouault@spatialys.com>
+
+ tiff2bw: avoid null pointer dereference in case of out of memory situation. Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2819 / CVE-2018-18661
+
+ tiffio.h: fix comment.
+
+2018-10-26 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'header2' into 'master'
+ Fix 725279bd: Standalone tif_predict.h: tiff.h should be tiffiop.h
+
+ See merge request libtiff/libtiff!41
+
+2018-10-26 Kurt Schwehr <schwehr@google.com>
+
+ Fix 725279bd: Standalone tif_predict.h: tiff.h should be tiffiop.h.
+
+2018-10-25 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'headers' into 'master'
+ Add includes to headers to allow them to stand alone.
+
+ See merge request libtiff/libtiff!40
+
+2018-10-24 Kurt Schwehr <schwehr@google.com>
+
+ Add includes to headers to allow them to stand alone.
+ This allows compilers that can do header stand alone header parsing
+ to process libtiff.
+
+2018-10-18 Even Rouault <even.rouault@spatialys.com>
+
+ LZMAPreEncode: emit verbose error if lzma_stream_encoder() fails (typically because not enough memory available)
+
+2018-10-17 Even Rouault <even.rouault@spatialys.com>
+
+ tif_webp.c: fix previous commit that broke scanline decoding.
+
+ tif_webp.c: fix potential read outside libwebp buffer on corrupted images
+
+2018-10-14 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'jbig_decode_overflow' into 'master'
+ JBIG: fix potential out-of-bounds write in JBIGDecode()
+
+ See merge request libtiff/libtiff!38
+
+2018-10-14 Even Rouault <even.rouault@spatialys.com>
+
+ JBIG: fix potential out-of-bounds write in JBIGDecode()
+ JBIGDecode doesn't check if the user provided buffer is large enough
+ to store the JBIG decoded image, which can potentially cause out-of-bounds
+ write in the buffer.
+ This issue was reported and analyzed by Thomas Dullien.
+
+ Also fixes a (harmless) potential use of uninitialized memory when
+ tif->tif_rawsize > tif->tif_rawcc
+
+ And in case libtiff is compiled with CHUNKY_STRIP_READ_SUPPORT, make sure
+ that whole strip data is provided to JBIGDecode()
+
+2018-10-05 Even Rouault <even.rouault@spatialys.com>
+
+ tif_webp.c: fix scanline reading/writing.
+
+ WEBP codec: initialize nSamples in TWebPSetupDecode() and TWebPSetupEncode()
+
+2018-10-05 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tif_webp' into 'master'
+ webp support
+
+ See merge request libtiff/libtiff!32
+
+2018-10-05 Norman Barker <norman.barker@mapbox.com>
+
+ webp in tiff.
+
+2018-09-17 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'master' into 'master'
+ fix three potential vulnerabilities.
+
+ See merge request libtiff/libtiff!33
+
+2018-09-08 Young_X <YangX92@hotmail.com>
+
+ fix out-of-bound read on some tiled images.
+
+ avoid potential int32 overflows in multiply_ms()
+
+ only read/write TIFFTAG_GROUP3OPTIONS or TIFFTAG_GROUP4OPTIONS if compression is COMPRESSION_CCITTFAX3 or COMPRESSION_CCITTFAX4
+
+2018-08-15 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFSetupStrips(): avoid potential uint32 overflow on 32-bit systems with large number of strips. Probably relates to http://bugzilla.maptools.org/show_bug.cgi?id=2788 / CVE-2018-10779
+
+2018-08-07 Even Rouault <even.rouault@spatialys.com>
+
+ ZSTD: fix flush issue that can cause endless loop in ZSTDEncode()
+ Fixes https://github.com/OSGeo/gdal/issues/833
+
+2018-08-07 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_bug_2800' into 'master'
+ Fix libtiff 4.0.8 regression when reading LZW-compressed strips with scanline API
+
+ See merge request libtiff/libtiff!31
+
+2018-08-07 Even Rouault <even.rouault@spatialys.com>
+
+ Fix libtiff 4.0.8 regression when reading LZW-compressed strips with scanline API
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2800
+
+2018-07-05 Even Rouault <even.rouault@spatialys.com>
+
+ Add tag and pseudo-tag definitions for ESRI LERC codec (out of tree codec whose source is at https://github.com/OSGeo/gdal/blob/master/gdal/frmts/gtiff/tif_lerc.c)
+
+2018-07-02 Even Rouault <even.rouault@spatialys.com>
+
+ Fix TIFFTAG_ZSTD_LEVEL pseudo tag value to be > 65536, and the next one in the series
+
+2018-05-25 Stefan Weil <sw@weilnetz.de>
+
+ Remove builtin support for GUI warning and error message boxes.
+ Now warnings always go to the console by default unless applications
+ define their own warning and error handlers.
+
+ GUI applications (and Windows CE) are required to define such handlers.
+
+2018-05-12 Even Rouault <even.rouault@spatialys.com>
+
+ LZWDecodeCompat(): fix potential index-out-of-bounds write. Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2780 / CVE-2018-8905
+ The fix consists in using the similar code LZWDecode() to validate we
+ don't write outside of the output buffer.
+
+ TIFFFetchNormalTag(): avoid (probably false positive) clang-tidy clang-analyzer-core.NullDereference warnings
+
+ TIFFWriteDirectorySec: avoid assertion. Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2795. CVE-2018-10963
+
+2018-05-04 Even Rouault <even.rouault@spatialys.com>
+
+ tif_color.c: fix code comment.
+
+2018-04-17 Even Rouault <even.rouault@mines-paris.org>
+
+ Merge branch 'fuzzer-fix' into 'master'
+ remove a pointless multiplication and a variable that's not necessary
+
+ See merge request libtiff/libtiff!29
+
+2018-04-17 Paul Kehrer <paul.l.kehrer@gmail.com>
+
+ remove a pointless multiplication and a variable that's not necessary.
+
+2018-04-17 Even Rouault <even.rouault@mines-paris.org>
+
+ Merge branch 'ossfuzz' into 'master'
+ move oss-fuzz build script and fuzzer into libtiff tree
+
+ See merge request libtiff/libtiff!28
+
+2018-04-17 Paul Kehrer <paul.l.kehrer@gmail.com>
+
+ move oss-fuzz build script and fuzzer into libtiff tree.
+
+2018-04-14 Even Rouault <even.rouault@spatialys.com>
+
+ _TIFFGetMaxColorChannels: update for LOGLUV, ITULAB and ICCLAB that have 3 color channels
+
+2018-04-12 Even Rouault <even.rouault@spatialys.com>
+
+ Fix MSVC warning.
+
+2018-04-12 Even Rouault <even.rouault@mines-paris.org>
+
+ Merge branch 'master' into 'master'
+ Fix NULL pointer dereference in TIFFPrintDirectory (bugzilla 2778/CVE-2018-7456)
+
+ See merge request libtiff/libtiff!27
+
+2018-04-11 Hugo Lefeuvre <hle@debian.org>
+
+ Fix NULL pointer dereference in TIFFPrintDirectory.
+ The TIFFPrintDirectory function relies on the following assumptions,
+ supposed to be guaranteed by the specification:
+
+ (a) A Transfer Function field is only present if the TIFF file has
+ photometric type < 3.
+
+ (b) If SamplesPerPixel > Color Channels, then the ExtraSamples field
+ has count SamplesPerPixel - (Color Channels) and contains
+ information about supplementary channels.
+
+ While respect of (a) and (b) are essential for the well functioning of
+ TIFFPrintDirectory, no checks are realized neither by the callee nor
+ by TIFFPrintDirectory itself. Hence, following scenarios might happen
+ and trigger the NULL pointer dereference:
+
+ (1) TIFF File of photometric type 4 or more has illegal Transfer
+ Function field.
+
+ (2) TIFF File has photometric type 3 or less and defines a
+ SamplesPerPixel field such that SamplesPerPixel > Color Channels
+ without defining all extra samples in the ExtraSamples fields.
+
+ In this patch, we address both issues with respect of the following
+ principles:
+
+ (A) In the case of (1), the defined transfer table should be printed
+ safely even if it isn't 'legal'. This allows us to avoid expensive
+ checks in TIFFPrintDirectory. Also, it is quite possible that
+ an alternative photometric type would be developed (not part of the
+ standard) and would allow definition of Transfer Table. We want
+ libtiff to be able to handle this scenario out of the box.
+
+ (B) In the case of (2), the transfer table should be printed at its
+ right size, that is if TIFF file has photometric type Palette
+ then the transfer table should have one row and not three, even
+ if two extra samples are declared.
+
+ In order to fulfill (A) we simply add a new 'i < 3' end condition to
+ the broken TIFFPrintDirectory loop. This makes sure that in any case
+ where (b) would be respected but not (a), everything stays fine.
+
+ (B) is fulfilled by the loop condition
+ 'i < td->td_samplesperpixel - td->td_extrasamples'. This is enough as
+ long as (b) is respected.
+
+ Naturally, we also make sure (b) is respected. This is done in the
+ TIFFReadDirectory function by making sure any non-color channel is
+ counted in ExtraSamples.
+
+ This commit addresses CVE-2018-7456.
+
+2018-03-27 Even Rouault <even.rouault@mines-paris.org>
+
+ Merge branch 'tiffset-long8' into 'master'
+ tiffset: Add support for LONG8, SLONG8 and IFD8 field types
+
+ See merge request libtiff/libtiff!25
+
+2018-03-26 Roger Leigh <rleigh@codelibre.net>
+
+ port: Clean up NetBSD sources and headers to build standalone.
+
+2018-03-23 Roger Leigh <rleigh@dundee.ac.uk>
+
+ port: Add strtol, strtoll and strtoull.
+ Also update strtoul. All use the same implementation from NetBSD libc.
+
+ tiffset: Add support for LONG8, SLONG8 and IFD8 field types.
+
+2018-03-17 Even Rouault <even.rouault@spatialys.com>
+
+ ChopUpSingleUncompressedStrip: avoid memory exhaustion (CVE-2017-11613)
+ Rework fix done in 3719385a3fac5cfb20b487619a5f08abbf967cf8 to work in more
+ cases like https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=6979.
+ Credit to OSS Fuzz
+
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2724
+
+2018-03-13 Even Rouault <even.rouault@spatialys.com>
+
+ libtiff/tif_luv.c: rewrite loops in a more readable way (to avoid false positive reports like http://bugzilla.maptools.org/show_bug.cgi?id=2779)
+
+2018-03-13 Even Rouault <even.rouault@mines-paris.org>
+
+ Merge branch 'avoid_memory_exhaustion_in_ChopUpSingleUncompressedStrip' into 'master'
+ ChopUpSingleUncompressedStrip: avoid memory exhaustion (CVE-2017-11613)
+
+ See merge request libtiff/libtiff!26
+
+2018-03-11 Even Rouault <even.rouault@spatialys.com>
+
+ ChopUpSingleUncompressedStrip: avoid memory exhaustion (CVE-2017-11613)
+ In ChopUpSingleUncompressedStrip(), if the computed number of strips is big
+ enough and we are in read only mode, validate that the file size is consistent
+ with that number of strips to avoid useless attempts at allocating a lot of
+ memory for the td_stripbytecount and td_stripoffset arrays.
+
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2724
+
+2018-03-10 Even Rouault <even.rouault@spatialys.com>
+
+ Typo fix in comment.
+
+2018-03-03 Even Rouault <even.rouault@spatialys.com>
+
+ Avoid warning with gcc 8 (partially revert 647b0e8c11ee11896f319b92cf110775f538d75c)
+
+2018-02-25 Even Rouault <even.rouault@mines-paris.org>
+
+ Merge branch 'typos' into 'master'
+ Fix some typos
+
+ See merge request libtiff/libtiff!23
+
+2018-02-24 Stefan Weil <sw@weilnetz.de>
+
+ Fix some typos.
+ Most of them were found by codespell.
+
+2018-02-14 Even Rouault <even.rouault@spatialys.com>
+
+ Typo fix in comment.
+
+ Merge branch 'zstd'
+
+ Add warning about COMPRESSION_ZSTD not being officially registered.
+
+2018-02-14 Even Rouault <even.rouault@mines-paris.org>
+
+ Merge branch 'bug2772' into 'master'
+ Fix for bug 2772
+
+ See merge request libtiff/libtiff!20
+
+2018-02-12 Nathan Baker <nathanb@lenovo-chrome.com>
+
+ Fix for bug 2772.
+ It is possible to craft a TIFF document where the IFD list is circular,
+ leading to an infinite loop while traversing the chain. The libtiff
+ directory reader has a failsafe that will break out of this loop after
+ reading 65535 directory entries, but it will continue processing,
+ consuming time and resources to process what is essentially a bogus TIFF
+ document.
+
+ This change fixes the above behavior by breaking out of processing when
+ a TIFF document has >= 65535 directories and terminating with an error.
+
+2018-02-09 Even Rouault <even.rouault@mines-paris.org>
+
+ Merge branch 'libtiff-as-subdirectory-fixes' into 'master'
+ Prefer target_include_directories
+
+ See merge request libtiff/libtiff!12
+
+2018-02-06 Even Rouault <even.rouault@mines-paris.org>
+
+ Merge branch 'cmake-cleanups' into 'master'
+ Cmake cleanups
+
+ See merge request libtiff/libtiff!11
+
+2018-02-06 Even Rouault <even.rouault@mines-paris.org>
+
+ Merge branch 'check-right-cxx-variable' into 'master'
+ Check right cxx variable
+
+ See merge request libtiff/libtiff!19
+
+2018-02-06 Even Rouault <even.rouault@mines-paris.org>
+
+ Merge branch 'dont-leak-stream-open' into 'master'
+ Fix a memory leak in TIFFStreamOpen
+
+ See merge request libtiff/libtiff!17
+
+2018-02-06 Ben Boeckel <ben.boeckel@kitware.com>
+
+ cmake: check CXX_SUPPORT.
+ This variable is set in response to the `cxx` cache variable; use it
+ instead.
+
+2018-02-04 Olivier Paquet <olivier.paquet@gmail.com>
+
+ Merge branch 'warnings' into 'master'
+ Fix all compiler warnings for default build
+
+ See merge request libtiff/libtiff!16
+
+2018-02-04 Nathan Baker <elitebadger@gmail.com>
+
+ Fix all compiler warnings for default build.
+
+2018-01-30 Paul Kehrer <paul.l.kehrer@gmail.com>
+
+ tabs are hard.
+
+2018-01-29 Paul Kehrer <paul.l.kehrer@gmail.com>
+
+ use hard tabs like the rest of the project.
+
+ Fix a memory leak in TIFFStreamOpen.
+ TIFFStreamOpen allocates a new tiff{o,i}s_data, but if TIFFClientOpen
+ fails then that struct is leaked. Delete it if the returned TIFF * is
+ null.
+
+2018-01-29 Kevin Funk <kfunk@kde.org>
+
+ Bump minimum required CMake version to v2.8.11.
+ Because we use the BUILD_INTERFACE generator expression
+
+2018-01-27 Even Rouault <even.rouault@mines-paris.org>
+
+ Merge branch 'patch-1' into 'master'
+ Update CMakeLists.txt for build fix on Windows
+
+ See merge request libtiff/libtiff!14
+
+2018-01-27 Even Rouault <even.rouault@mines-paris.org>
+
+ Merge branch 'patch-2' into 'master'
+ Update tiffgt.c for build fix on Windows
+
+ See merge request libtiff/libtiff!13
+
+2018-01-25 Olivier Paquet <olivier.paquet@gmail.com>
+
+ Merge branch 'bug2750' into 'master'
+ Add workaround to pal2rgb buffer overflow.
+
+ See merge request libtiff/libtiff!15
+
+2018-01-25 Nathan Baker <elitebadger@gmail.com>
+
+ Add workaround to pal2rgb buffer overflow.
+
+2018-01-23 Andrea <andrea@andreaplanet.com>
+
+ Update tiffgt.c for build fix on Windows.
+
+ Update CMakeLists.txt for build fix on Windows.
+
+2018-01-15 Even Rouault <even.rouault@mines-paris.org>
+
+ Merge branch 'has-attribute-check' into 'master'
+ tiffiop: use __has_attribute to detect the no_sanitize attribute
+
+ See merge request libtiff/libtiff!10
+
+2018-01-15 Ben Boeckel <ben.boeckel@kitware.com>
+
+ cmake: avoid setting hard-coded variables in the cache.
+
+ cmake: avoid an unnecessary intermediate variable.
+
+ cmake: avoid an unnecessary intermediate variable.
+
+ cmake: avoid tautological logic.
+
+ cmake: use check_symbol_exists.
+ This accounts for symbols being provided by macros.
+
+ cmake: remove unused configure checks.
+
+2018-01-12 Kevin Funk <kfunk@kde.org>
+
+ Prefer target_include_directories.
+ When libtiff is included in a super project via a simple
+ `add_subdirectory(libtiff)`, this way the `tiff` library target has all
+ the necessary information to build against it.
+
+ Note: The BUILD_INTERFACE generator expression feature requires at least
+ CMake v2.8.11 if I'm correct.
+
+2018-01-09 Ben Boeckel <ben.boeckel@kitware.com>
+
+ tiffiop: use __has_attribute to detect the no_sanitize attribute.
+
+2017-12-31 Even Rouault <even.rouault@spatialys.com>
+
+ man/TIFFquery.3tiff: remove reference to non-existing TIFFReadStrip() function in TIFFIsByteSwapped() documentation. Patch by Eric Piel. Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2763
+
+ libtiff/tif_dir.c: _TIFFVGetField(): fix heap out-of-bounds access when requesting TIFFTAG_NUMBEROFINKS on a EXIF directory. Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2765. Reported by Google Autofuzz project
+
+ libtiff/tif_print.c: TIFFPrintDirectory(): fix null pointer dereference on corrupted file. Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2770
+
+2017-12-21 Even Rouault <even.rouault@spatialys.com>
+
+ Add libzstd to gitlab-ci.
+
+2017-12-21 Even Rouault <even.rouault@spatialys.com>
+
+ Add ZSTD compression codec.
+ From https://github.com/facebook/zstd
+ "Zstandard, or zstd as short version, is a fast lossless compression
+ algorithm, targeting real-time compression scenarios at zlib-level
+ and better compression ratios. It's backed by a very fast entropy stage,
+ provided by Huff0 and FSE library."
+
+ We require libzstd >= 1.0.0 so as to be able to use streaming compression
+ and decompression methods.
+
+ The default compression level we have selected is 9 (range goes from 1 to 22),
+ which experimentally offers equivalent or better compression ratio than
+ the default deflate/ZIP level of 6, and much faster compression.
+
+ For example on a 6600x4400 16bit image, tiffcp -c zip runs in 10.7 seconds,
+ while tiffcp -c zstd runs in 5.3 seconds. Decompression time for zip is
+ 840 ms, and for zstd 650 ms. File size is 42735936 for zip, and
+ 42586822 for zstd. Similar findings on other images.
+
+ On a 25894x16701 16bit image,
+
+ Compression time Decompression time File size
+
+ ZSTD 35 s 3.2 s 399 700 498
+ ZIP/Deflate 1m 20 s 4.9 s 419 622 336
+
+2017-12-10 Even Rouault <even.rouault@mines-paris.org>
+
+ Merge branch 'fix_cve-2017-9935' into 'master'
+ Fix CVE-2017-9935
+
+ See merge request libtiff/libtiff!7
+
+2017-12-10 Brian May <brian@linuxpenguins.xyz>
+
+ tiff2pdf: Fix apparent incorrect type for transfer table.
+ The standard says the transfer table contains unsigned 16 bit values,
+ I have no idea why we refer to them as floats.
+
+2017-12-10 Brian May <brian@linuxpenguins.xyz>
+
+ tiff2pdf: Fix CVE-2017-9935.
+ Fix for http://bugzilla.maptools.org/show_bug.cgi?id=2704
+
+ This vulnerability - at least for the supplied test case - is because we
+ assume that a tiff will only have one transfer function that is the same
+ for all pages. This is not required by the TIFF standards.
+
+ We than read the transfer function for every page. Depending on the
+ transfer function, we allocate either 2 or 4 bytes to the XREF buffer.
+ We allocate this memory after we read in the transfer function for the
+ page.
+
+ For the first exploit - POC1, this file has 3 pages. For the first page
+ we allocate 2 extra extra XREF entries. Then for the next page 2 more
+ entries. Then for the last page the transfer function changes and we
+ allocate 4 more entries.
+
+ When we read the file into memory, we assume we have 4 bytes extra for
+ each and every page (as per the last transfer function we read). Which
+ is not correct, we only have 2 bytes extra for the first 2 pages. As a
+ result, we end up writing past the end of the buffer.
+
+ There are also some related issues that this also fixes. For example,
+ TIFFGetField can return uninitialized pointer values, and the logic to
+ detect a N=3 vs N=1 transfer function seemed rather strange.
+
+ It is also strange that we declare the transfer functions to be of type
+ float, when the standard says they are unsigned 16 bit values. This is
+ fixed in another patch.
+
+ This patch will check to ensure that the N value for every transfer
+ function is the same for every page. If this changes, we abort with an
+ error. In theory, we should perhaps check that the transfer function
+ itself is identical for every page, however we don't do that due to the
+ confusion of the type of the data in the transfer function.
+
+2017-12-10 Even Rouault <even.rouault@mines-paris.org>
+
+ Merge branch 'undef-warn-fixes' into 'master'
+ Fix a couple of harmless but annoying -Wundef warnings
+
+ See merge request libtiff/libtiff!8
+
+2017-12-07 Vadim Zeitlin <vadim@zeitlins.org>
+
+ Remove tests for undefined SIZEOF_VOIDP.
+ As configure never uses AC_CHECK_SIZEOF(void*), this symbol is never
+ defined and so it doesn't make sense to test it in the code, this just
+ results in -Wundef warnings if they're enabled.
+
+ Avoid harmless -Wundef warnings for __clang_major__
+ Check that we're using Clang before checking its version.
+
+2017-12-02 Even Rouault <even.rouault@mines-paris.org>
+
+ Merge branch 'remove_autogenerated_files' into 'master'
+ Remove autogenerated files
+
+ See merge request libtiff/libtiff!5
+
+2017-12-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ Merge branch 'tif_config_h_includes' into 'master'
+ 'tif_config.h' or 'tiffiop.h' must be included before any system header.
+
+ See merge request libtiff/libtiff!6
+
+2017-12-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ 'tif_config.h' or 'tiffio.h' must be included before any system header.
+
+2017-12-01 Even Rouault <even.rouault@spatialys.com>
+
+ .gitignore: add patterns for build from root.
+
+ Remove remaining .cvsignore files.
+
+ Remove autoconf/automake generated files, and add them to .gitignore.
+
+2017-12-01 Olivier Paquet <olivier.paquet@gmail.com>
+
+ Merge branch 'makedistcheck' into 'master'
+ build/gitlab-ci and build/travis-ci: add a 'make dist' step in autoconf_build()…
+
+ See merge request libtiff/libtiff!4
+
+2017-12-01 Even Rouault <even.rouault@spatialys.com>
+
+ build/gitlab-ci and build/travis-ci: add a 'make dist' step in autoconf_build() target, to check we are release-ready
+
+2017-12-01 Even Rouault <even.rouault@mines-paris.org>
+
+ Merge branch 'git_updates' into 'master'
+ CVS to Git updates
+
+ See merge request libtiff/libtiff!2
+
+2017-12-01 Even Rouault <even.rouault@spatialys.com>
+
+ HOWTO-RELEASE: update to use signed tags.
+
+ README.md: use markdown syntax for hyperlinks.
+
+2017-11-30 Even Rouault <even.rouault@spatialys.com>
+
+ Add .gitignore.
+
+ Regenerate autoconf files.
+
+ Makefile.am: update to reflect removal of README.vms and README -> README.md
+
+ Remove all $Id and $Headers comments with CVS versions.
+
+ HOWTO-RELEASE: update for git.
+
+ Remove outdated .cvsignore.
+
+ Remove outdated commit script.
+
+ Remove README.vms.
+
+ Rename README as README.md, and update content.
+
+ html/index.html: reflect change from CVS to gitlab.
+
+2017-11-30 Olivier Paquet <olivier.paquet@gmail.com>
+
+ Merge branch 'test-ci' into 'master'
+ Update CI configuration
+
+ See merge request libtiff/libtiff!1
+
+2017-11-23 Roger Leigh <rleigh@codelibre.net>
+
+ appveyor: Correct path for git clone and skip artefact archival.
+
+2017-11-22 Roger Leigh <rleigh@codelibre.net>
+
+ travis-ci: Remove unused matrix exclusion.
+
+ Add gitlab-ci build support.
+
+2017-11-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: libtiff 4.0.9 released.
+
+ * html/v4.0.9.html: Add HTML file to document changes in libtiff
+ v4.0.9.
+
+2017-11-17 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_aux.c, tif_getimage.c, tif_read.c: typo fixes in
+ comments.
+
+2017-11-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * test/Makefile.am: Add some tests for tiff2bw.
+
+2017-11-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/tiff2bw.c (main): Free memory allocated in the tiff2bw
+ program. This is in response to the report associated with
+ CVE-2017-16232 but does not solve the extremely high memory usage
+ with the associated POC file.
+
+2017-10-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/tiff2pdf.c (t2p_sample_realize_palette): Fix possible
+ arithmetic overflow in bounds checking code and eliminate
+ comparison between signed and unsigned type.
+
+ * tools/fax2tiff.c (_FAX_Client_Data): Pass FAX_Client_Data as the
+ client data. This client data is not used at all at the moment,
+ but it makes the most sense. Issue that the value of
+ client_data.fd was passed where a pointer is expected was reported
+ via email by Gerald Schade on Sun, 29 Oct 2017.
+
+2017-10-23 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_getimage.c: avoid floating point division by zero in
+ initCIELabConversion()
+ Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3733
+ Credit to OSS Fuzz
+
+2017-10-17 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_jpeg.c: add compatibility with libjpeg-turbo 1.5.2 that
+ honours max_memory_to_use > 0.
+ Cf https://github.com/libjpeg-turbo/libjpeg-turbo/issues/162
+
+2017-10-10 Even Rouault <even.rouault at spatialys.com>
+
+ * nmake.opt: support a DEBUG=1 option, so as to adjust OPTFLAGS and use
+ /MDd runtime in debug mode.
+
+2017-10-01 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiffset.c: fix setting a single value for the ExtraSamples tag
+ (and other tags with variable number of values).
+ So 'tiffset -s ExtraSamples 1 X'. This only worked
+ when setting 2 or more values, but not just one.
+
+2017-09-29 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/libtiff.def: add TIFFReadRGBAStripExt and TIFFReadRGBATileExt
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2735
+
+2017-09-09 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dirread.c: add NULL check to avoid likely false positive
+ null-pointer dereference warning by CLang Static Analyzer.
+
+2017-09-07 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tiffiop.h, tif_aux.c: redirect SeekOK() macro to a _TIFFSeekoK()
+ function that checks if the offset is not bigger than INT64_MAX, so as
+ to avoid a -1 error return code of TIFFSeekFile() to match a required
+ seek to UINT64_MAX/-1.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2726
+ Adapted from proposal by Nicolas Ruff.
+
+2017-08-29 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_jpeg.c: accept reading the last strip of a JPEG compressed
+ file if the codestream height is larger than the truncated height of the
+ strip. Emit a warning in this situation since this is non compliant.
+
+2017-08-28 Even Rouault <even.rouault at spatialys.com>
+
+ * test/Makefile.am: add missing reference to images/quad-lzw-compat.tiff
+ to fix "make distcheck". Patch by Roger Leigh
+
+2017-08-23 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dirwrite.c: replace assertion to tag value not fitting
+ on uint32 when selecting the value of SubIFD tag by runtime check
+ (in TIFFWriteDirectoryTagSubifd()).
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2728
+ Reported by team OWL337
+
+2017-08-23 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dirwrite.c: replace assertion related to not finding the
+ SubIFD tag by runtime check (in TIFFWriteDirectorySec())
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2727
+ Reported by team OWL337
+
+2017-07-24 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_luv.c: further reduce memory requirements for temporary
+ buffer when RowsPerStrip >= image_length in LogLuvInitState() and
+ LogL16InitState().
+ Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2700
+ Credit to OSS Fuzz
+
+2017-07-24 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_getimage.c: fix fromskew computation when to-be-skipped
+ pixel number is not a multiple of the horizontal subsampling, and
+ also in some other cases. Impact putcontig8bitYCbCr44tile,
+ putcontig8bitYCbCr42tile, putcontig8bitYCbCr41tile,
+ putcontig8bitYCbCr21tile and putcontig8bitYCbCr12tile
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2637 (discovered
+ by Agostino Sarubbo)
+ and https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2691 (credit
+ to OSS Fuzz)
+
+2017-07-24 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_getimage.c: gtTileContig() and gtTileSeparate():
+ properly break from loops on error when stoponerr is set, instead
+ of going on iterating on row based loop.
+
+2017-07-18 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_luv.c: LogLuvInitState(): avoid excessive memory
+ allocation when RowsPerStrip tag is missing.
+ Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2683
+ Credit to OSS-Fuzz
+
+2017-07-15 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_read.c: add protection against excessive memory
+ allocation attempts in TIFFReadDirEntryArray() on short files.
+ Effective for mmap'ed case. And non-mmap'ed case, but restricted
+ to 64bit builds.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2675
+
+2017-07-15 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_read.c: in TIFFFetchStripThing(), only grow the
+ arrays that hold StripOffsets/StripByteCounts, when they are smaller
+ than the expected number of striles, up to 1 million striles, and
+ error out beyond. Can be tweaked by setting the environment variable
+ LIBTIFF_STRILE_ARRAY_MAX_RESIZE_COUNT.
+ This partially goes against a change added on 2002-12-17 to accept
+ those arrays of wrong sizes, but is needed to avoid denial of services.
+ Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2350
+ Credit to OSS Fuzz
+
+2017-07-15 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_read.c: TIFFFillStrip() / TIFFFillTile().
+ Complementary fix for http://bugzilla.maptools.org/show_bug.cgi?id=2708
+ in the isMapped() case, so as to avoid excessive memory allocation
+ when we need a temporary buffer but the file is truncated.
+
+2017-07-15 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiff2pdf.c: prevent heap buffer overflow write in "Raw"
+ mode on PlanarConfig=Contig input images.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2715
+ Reported by team OWL337
+
+2017-07-11 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dir.c: avoid potential null pointer dereference in
+ _TIFFVGetField() on corrupted TIFFTAG_NUMBEROFINKS tag instance.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2713
+
+2017-07-11 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_lzw.c: fix potential out-of-buffer read on 1-byte LZW
+ strips. Crashing issue only on memory mapped files, where the strip
+ offset is the last byte of the file, and the file size is a multiple
+ of one page size on the CPU architecture (typically 4096). Credit
+ to myself :-)
+
+2017-07-11 Even Rouault <even.rouault at spatialys.com>
+
+ * test/tiffcp-lzw-compat.sh, test/images/quad-lzw-compat.tiff: new files
+ to test old-style LZW decompression
+ * test/common.sh, Makefile.am, CMakeList.txt: updated with above
+
+2017-07-11 Even Rouault <even.rouault at spatialys.com>
+
+ * refresh autoconf/make stuff with what is on Ubuntu 16.04 (minor changes)
+
+2017-07-11 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_lzw.c: fix 4.0.8 regression in the decoding of old-style LZW
+ compressed files.
+
+2017-07-10 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_pixarlog.c: avoid excessive memory allocation on decoding
+ when RowsPerStrip tag is not defined (and thus td_rowsperstrip == UINT_MAX)
+ Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2554
+ Credit to OSS Fuzz
+
+2017-07-04 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_read.c, tiffiop.h: add a _TIFFReadEncodedTileAndAllocBuffer()
+ and _TIFFReadTileAndAllocBuffer() variants of TIFFReadEncodedTile() and
+ TIFFReadTile() that allocates the decoded buffer only after a first
+ successful TIFFFillTile(). This avoids excessive memory allocation
+ on corrupted files.
+ * libtiff/tif_getimage.c: use _TIFFReadTileAndAllocBuffer().
+ Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2470
+ Credit to OSS Fuzz.
+
+2017-07-04 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_error.c, tif_warning.c: correctly use va_list when both
+ an old-style and new-style warning/error handlers are installed.
+ Patch by Paavo Helde (sent on the mailing list)
+
+2017-07-02 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_read.c: TIFFStartTile(): set tif_rawcc to
+ tif_rawdataloaded when it is set. Similarly to TIFFStartStrip().
+ This issue was revealed by the change of 2017-06-30 in TIFFFileTile(),
+ limiting the number of bytes read. But it could probably have been hit
+ too in CHUNKY_STRIP_READ_SUPPORT mode previously ?
+ Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2454
+ Credit to OSS Fuzz
+
+2017-06-30 Even Rouault <even.rouault at spatialys.com>
+
+ * man: update documentation regarding SubIFD tag and
+ TIFFSetSubDirectory() data type.
+ Patch by Eric Piel
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2671
+
+2017-06-30 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dirwrite.c: in TIFFWriteDirectoryTagCheckedXXXX()
+ functions associated with LONG8/SLONG8 data type, replace assertion that
+ the file is BigTIFF, by a non-fatal error.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2712
+ Reported by team OWL337
+
+2017-06-30 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_read.c, tiffiop.h: add a _TIFFReadEncodedStripAndAllocBuffer()
+ function, variant of TIFFReadEncodedStrip() that allocates the
+ decoded buffer only after a first successful TIFFFillStrip(). This avoids
+ excessive memory allocation on corrupted files.
+ * libtiff/tif_getimage.c: use _TIFFReadEncodedStripAndAllocBuffer().
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2708 and
+ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2433 .
+ Credit to OSS Fuzz
+
+2017-06-30 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_read.c: TIFFFillTile(): add limitation to the number
+ of bytes read in case td_stripbytecount[strip] is bigger than
+ reasonable, so as to avoid excessive memory allocation (similarly to
+ what was done for TIFFFileStrip() on 2017-05-10)
+
+2017-06-29 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tiffiop.h, libtiff/tif_jpeg.c, libtiff/tif_jpeg_12.c,
+ libtiff/tif_read.c: make TIFFReadScanline() works in
+ CHUNKY_STRIP_READ_SUPPORT mode with JPEG stream with multiple scans.
+ Also make configurable through a LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER
+ environment variable the maximum number of scans allowed. Defaults to
+ 100.
+
+2017-06-27 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dirread.c: in TIFFReadDirEntryFloat(), check that a
+ double value can fit in a float before casting. Patch by Nicolas RUFF
+
+2017-06-26 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_jbig.c: fix memory leak in error code path of JBIGDecode()
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2706
+ Reported by team OWL337
+
+2017-06-24 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_jpeg.c: error out at decoding time if anticipated libjpeg
+ memory allocation is above 100 MB. libjpeg in case of multiple scans,
+ which is allowed even in baseline JPEG, if components are spread over several
+ scans and not interleavedin a single one, needs to allocate memory (or
+ backing store) for the whole strip/tile.
+ See http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf
+ This limitation may be overridden by setting the
+ LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC environment variable, or recompiling
+ libtiff with a custom value of TIFF_LIBJPEG_LARGEST_MEM_ALLOC macro.
+
+2017-06-24 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_jpeg.c: add anti-denial of service measure to avoid excessive
+ CPU consumption on progressive JPEGs with a huge number of scans.
+ See http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf
+ Note: only affects libtiff since 2014-12-29 where support of non-baseline JPEG
+ was added.
+
+2017-06-18 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tiffiop.h: add TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW macro to
+ disable CLang warnings raised by -fsanitize=undefined,unsigned-integer-overflow
+ * libtiff/tif_predict.c: decorate legitimate functions where unsigned int
+ overflow occur with TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
+ * libtiff/tif_dirread.c: avoid unsigned int overflow in EstimateStripByteCounts()
+ and BYTECOUNTLOOKSBAD when file is too short.
+ * libtiff/tif_jpeg.c: avoid (harmless) unsigned int overflow on tiled images.
+ * libtiff/tif_fax3.c: avoid unsigned int overflow in Fax3Encode2DRow(). Could
+ potentially be a bug with huge rows.
+ * libtiff/tif_getimage.c: avoid many (harmless) unsigned int overflows.
+
+2017-06-12 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dirread.c: TIFFFetchStripThing(): limit the number of items
+ read in StripOffsets/StripByteCounts tags to the number of strips to avoid
+ excessive memory allocation.
+ Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2215
+ Credit to OSS Fuzz
+
+2017-06-12 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dirread.c: fix regression of libtiff 4.0.8 in
+ ChopUpSingleUncompressedStrip() regarding update of newly single-strip
+ uncompressed files whose bytecount is 0. Before the change of 2016-12-03,
+ the condition bytecount==0 used to trigger an early exit/disabling of
+ strip chop. Re-introduce that in update mode. Otherwise this cause
+ later incorrect setting for the value of StripByCounts/StripOffsets.
+ ( https://trac.osgeo.org/gdal/ticket/6924 )
+
+2017-06-10 Even Rouault <even.rouault at spatialys.com>
+
+ * .appveyor.yml, .travis.yml, build/travis-ci: apply patches
+ 0001-ci-Travis-script-improvements.patch and
+ 0002-ci-Invoke-helper-script-via-shell.patch by Roger Leigh
+ (sent to mailing list)
+
+2017-06-08 Even Rouault <even.rouault at spatialys.com>
+
+ * .travis.yml, build/travis-ci: new files from
+ 0001-ci-Add-Travis-support-for-Linux-builds-with-Autoconf.patch by
+ Roger Leigh (sent to mailing list on 2017-06-08)
+ This patch adds support for the Travis-CI service.
+
+ * .appveyor.yml: new file from
+ 0002-ci-Add-AppVeyor-support.patch by Roger Leigh (sent to mailing
+ list on 2017-06-08)
+ This patch adds a .appveyor.yml file to the top-level. This allows
+ one to opt in to having a branch built on Windows with Cygwin,
+ MinGW and MSVC automatically when a branch is pushed to GitHub,
+ GitLab, BitBucket or any other supported git hosting service.
+
+ * CMakeLists.txt, test/CMakeLists.txt, test/TiffTestCommon.cmake: apply
+ patch 0001-cmake-Improve-Cygwin-and-MingGW-test-support.patch from Roger
+ Leigh (sent to mailing list on 2017-06-08)
+ This patch makes the CMake build system support running the tests
+ with MinGW or Cygwin.
+
+2017-06-08 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_swab.c: if DISABLE_CHECK_TIFFSWABMACROS is defined, do not do
+ the #ifdef TIFFSwabXXX checks. Make it easier for GDAL to rename the symbols
+ of its internal libtiff copy.
+
+2017-06-01 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dirinfo.c, tif_dirread.c: add _TIFFCheckFieldIsValidForCodec(),
+ and use it in TIFFReadDirectory() so as to ignore fields whose tag is a
+ codec-specified tag but this codec is not enabled. This avoids TIFFGetField()
+ to behave differently depending on whether the codec is enabled or not, and
+ thus can avoid stack based buffer overflows in a number of TIFF utilities
+ such as tiffsplit, tiffcmp, thumbnail, etc.
+ Patch derived from 0063-Handle-properly-CODEC-specific-tags.patch
+ (http://bugzilla.maptools.org/show_bug.cgi?id=2580) by Raphaël Hertzog.
+ Fixes:
+ http://bugzilla.maptools.org/show_bug.cgi?id=2580
+ http://bugzilla.maptools.org/show_bug.cgi?id=2693
+ http://bugzilla.maptools.org/show_bug.cgi?id=2625 (CVE-2016-10095)
+ http://bugzilla.maptools.org/show_bug.cgi?id=2564 (CVE-2015-7554)
+ http://bugzilla.maptools.org/show_bug.cgi?id=2561 (CVE-2016-5318)
+ http://bugzilla.maptools.org/show_bug.cgi?id=2499 (CVE-2014-8128)
+ http://bugzilla.maptools.org/show_bug.cgi?id=2441
+ http://bugzilla.maptools.org/show_bug.cgi?id=2433
+
+2017-05-29 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_getimage.c: initYCbCrConversion(): stricter validation for
+ refBlackWhite coefficients values. To avoid invalid float->int32 conversion
+ (when refBlackWhite[0] == 2147483648.f)
+ Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1907
+ Credit to OSS Fuzz
+
+2017-05-29 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_color.c: TIFFYCbCrToRGBInit(): stricter clamping to avoid
+ int32 overflow in TIFFYCbCrtoRGB().
+ Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1844
+ Credit to OSS Fuzz
+
+2017-05-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: libtiff 4.0.8 released.
+
+ * html/v4.0.8.html: Add description of changes targeting the 4.0.8
+ release.
+
+2017-05-20 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_getimage.c: initYCbCrConversion(): stricter validation for
+ refBlackWhite coefficients values. To avoid invalid float->int32 conversion.
+ Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1718
+ Credit to OSS Fuzz
+
+2017-05-18 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_getimage.c: initYCbCrConversion(): check luma[1] is not zero
+ to avoid division by zero.
+ Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1665
+ Credit to OSS Fuzz
+
+2017-05-17 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_read.c: _TIFFVSetField(): fix outside range cast of double to
+ float.
+ Credit to Google Autofuzz project
+
+2017-05-17 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_getimage.c: initYCbCrConversion(): add basic validation of
+ luma and refBlackWhite coefficients (just check they are not NaN for now),
+ to avoid potential float to int overflows.
+ Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1663
+ Credit to OSS Fuzz
+
+2017-05-17 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_pixarlog.c: PixarLogDecode(): resync tif_rawcp with
+ next_in and tif_rawcc with avail_in at beginning and end of function,
+ similarly to what is done in LZWDecode(). Likely needed so that it
+ works properly with latest chnges in tif_read.c in CHUNKY_STRIP_READ_SUPPORT
+ mode. But untested...
+
+2017-05-17 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_lzw.c: update dec_bitsleft at beginning of LZWDecode(),
+ and update tif_rawcc at end of LZWDecode(). This is needed to properly
+ work with the latest chnges in tif_read.c in CHUNKY_STRIP_READ_SUPPORT
+ mode.
+
+2017-05-14 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_luv.c: LogL16InitState(): avoid excessive memory
+ allocation when RowsPerStrip tag is missing.
+ Credit to OSS-Fuzz (locally run, on GDAL)
+
+2017-05-14 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_packbits.c: fix out-of-buffer read in PackBitsDecode()
+ Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1563
+ Credit to OSS-Fuzz
+
+2017-05-13 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_pixarlog.c, tif_luv.c: avoid potential int32
+ overflows in multiply_ms() and add_ms().
+ Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1558
+ Credit to OSS-Fuzz
+
+2017-05-13 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_color.c: avoid potential int32 overflow in
+ TIFFYCbCrToRGBInit()
+ Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1533
+ Credit to OSS-Fuzz
+
+2017-05-13 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_read.c: update tif_rawcc in CHUNKY_STRIP_READ_SUPPORT
+ mode with tif_rawdataloaded when calling TIFFStartStrip() or
+ TIFFFillStripPartial(). This avoids reading beyond tif_rawdata
+ when bytecount > tif_rawdatasize.
+ Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1545.
+ Credit to OSS-Fuzz
+
+2017-05-12 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_read.c: TIFFFillStripPartial():
+ avoid excessive memory allocation in case of shorten files.
+ Only effective on 64 bit builds.
+ Credit to OSS-Fuzz (locally run, on GDAL)
+
+2017-05-12 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_read.c: TIFFFillStripPartial() / TIFFSeek(),
+ avoid potential integer overflows with read_ahead in
+ CHUNKY_STRIP_READ_SUPPORT mode. Should
+ especially occur on 32 bit platforms.
+
+2017-05-10 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_read.c: TIFFFillStrip() and TIFFFillTile():
+ avoid excessive memory allocation in case of shorten files.
+ Only effective on 64 bit builds and non-mapped cases.
+ Credit to OSS-Fuzz (locally run, on GDAL)
+
+2017-05-10 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_zip.c, tif_pixarlog.c, tif_predict.c: fix memory
+ leak when the underlying codec (ZIP, PixarLog) succeeds its
+ setupdecode() method, but PredictorSetup fails.
+ Credit to OSS-Fuzz (locally run, on GDAL)
+
+2017-05-10 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_read.c: TIFFFillStrip(): add limitation to the number
+ of bytes read in case td_stripbytecount[strip] is bigger than
+ reasonable, so as to avoid excessive memory allocation.
+
+2017-04-28 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiff2bw.c: close TIFF handle in error code path.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2677
+
+2017-04-27 Even Rouault <even.rouault at spatialys.com>
+
+ * litiff/tif_fax3.c: avoid crash in Fax3Close() on empty file.
+ Patch by Alan Coopersmith + complement by myself.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2673
+ * tools/fax2tiff.c: emit appropriate message if the input file is
+ empty. Patch by Alan Coopersmith.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2672
+
+2017-04-27 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_ojpeg.c: fix potential memory leak in
+ OJPEGReadHeaderInfoSecTablesQTable, OJPEGReadHeaderInfoSecTablesDcTable
+ and OJPEGReadHeaderInfoSecTablesAcTable
+ Patch by Nicolás Peña.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2670
+
+2017-04-27 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dirread.c: fix memory leak in non DEFER_STRILE_LOAD
+ mode (ie default) when there is both a StripOffsets and
+ TileOffsets tag, or a StripByteCounts and TileByteCounts
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2689
+ * tools/tiff2ps.c: call TIFFClose() in error code paths.
+
+2017-02-25 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_fax3.c, tif_predict.c, tif_getimage.c: fix GCC 7
+ -Wimplicit-fallthrough warnings.
+
+2017-02-18 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_pixarlog.c: fix memory leak in error code path of
+ PixarLogSetupDecode(). Patch by Nicolás Peña.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2665
+
+2017-02-18 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_lzw.c: in LZWPostEncode(), increase, if necessary, the
+ code bit-width after flushing the remaining code and before emitting
+ the EOI code.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=1982
+
+2017-01-31 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_jpeg.c: only run JPEGFixupTagsSubsampling() if the
+ YCbCrSubsampling tag is not explicitly present. This helps a bit to reduce
+ the I/O amount when the tag is present (especially on cloud hosted files).
+
+2017-01-14 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/raw2tiff.c: avoid integer division by zero.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2631
+
+2017-01-12 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_ojpeg.c: fix leak in OJPEGReadHeaderInfoSecTablesQTable,
+ OJPEGReadHeaderInfoSecTablesDcTable and OJPEGReadHeaderInfoSecTablesAcTable
+ when read fails.
+ Patch by Nicolás Peña.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2659
+
+2017-01-11 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_luv.c, tif_lzw.c, tif_packbits.c: return 0 in Encode
+ functions instead of -1 when TIFFFlushData1() fails.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2130
+
+2017-01-11 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiffcp.c: error out cleanly in cpContig2SeparateByRow and
+ cpSeparate2ContigByRow if BitsPerSample != 8 to avoid heap based overflow.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2656 and
+ http://bugzilla.maptools.org/show_bug.cgi?id=2657
+
+2017-01-11 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tiffio.h, tif_unix.c, tif_win32.c, tif_vms.c: add _TIFFcalloc()
+
+ * libtiff/tif_read.c: TIFFReadBufferSetup(): use _TIFFcalloc() to zero
+ initialize tif_rawdata.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2651
+
+2017-01-11 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_getimage.c: add explicit uint32 cast in putagreytile to
+ avoid UndefinedBehaviorSanitizer warning.
+ Patch by Nicolás Peña.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2658
+
+2017-01-11 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_read.c: avoid potential undefined behaviour on signed integer
+ addition in TIFFReadRawStrip1() in isMapped() case.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2650
+
+2017-01-11 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_jpeg.c: validate BitsPerSample in JPEGSetupEncode() to avoid
+ undefined behaviour caused by invalid shift exponent.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2648
+
+2017-01-11 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dir.c, tif_dirread.c, tif_dirwrite.c: implement various clampings
+ of double to other data types to avoid undefined behaviour if the output range
+ isn't big enough to hold the input value.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2643
+ http://bugzilla.maptools.org/show_bug.cgi?id=2642
+ http://bugzilla.maptools.org/show_bug.cgi?id=2646
+ http://bugzilla.maptools.org/show_bug.cgi?id=2647
+
+2017-01-11 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dirread.c: avoid division by floating point 0 in
+ TIFFReadDirEntryCheckedRational() and TIFFReadDirEntryCheckedSrational(),
+ and return 0 in that case (instead of infinity as before presumably)
+ Apparently some sanitizers do not like those divisions by zero.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2644
+
+2017-01-11 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dirwrite.c: in TIFFWriteDirectoryTagCheckedRational, replace
+ assertion by runtime check to error out if passed value is strictly
+ negative.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2535
+
+ * tools/tiffcrop.c: remove extraneous TIFFClose() in error code path, that
+ caused double free.
+ Related to http://bugzilla.maptools.org/show_bug.cgi?id=2535
+
+2017-01-11 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_jpeg.c: avoid integer division by zero in
+ JPEGSetupEncode() when horizontal or vertical sampling is set to 0.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2653
+
+2017-01-03 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_jpeg.c: increase libjpeg max memory usable to
+ 10 MB instead of libjpeg 1MB default. This helps when creating files
+ with "big" tile, without using libjpeg temporary files.
+ Related to https://trac.osgeo.org/gdal/ticket/6757
+
+2016-12-20 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiff2pdf.c: avoid potential heap-based overflow in
+ t2p_readwrite_pdf_image_tile().
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2640
+
+2016-12-20 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiff2pdf.c: avoid potential invalid memory read in
+ t2p_writeproc.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2639
+
+2016-12-20 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiff2pdf.c: fix wrong usage of memcpy() that can trigger
+ unspecified behaviour.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2638
+
+2016-12-18 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_getimage.c: fix potential memory leaks in error code
+ path of TIFFRGBAImageBegin().
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2627
+
+2016-12-18 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiff2pdf.c: prevent heap-based buffer overflow in -j mode
+ on a paletted image. Note: this fix errors out before the overflow
+ happens. There could probably be a better fix.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2635
+
+2016-12-17 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tiffio.h, libtiff/tif_getimage.c: add TIFFReadRGBAStripExt()
+ and TIFFReadRGBATileExt() variants of the functions without ext, with
+ an extra argument to control the stop_on_error behaviour.
+
+2016-12-17 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiff2ps.c: fix 2 heap-based buffer overflows (in PSDataBW
+ and PSDataColorContig). Reported by Agostino Sarubbo.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2633 and
+ http://bugzilla.maptools.org/show_bug.cgi?id=2634.
+
+2016-12-13 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_fax3.h: revert change done on 2016-01-09 that made
+ Param member of TIFFFaxTabEnt structure a uint16 to reduce size of
+ the binary. It happens that the Hylafax software uses the tables that
+ follow this typedef (TIFFFaxMainTable, TIFFFaxWhiteTable,
+ TIFFFaxBlackTable), although they are not in a public libtiff header.
+ Raised by Lee Howard.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2636
+
+2016-12-04 Even Rouault <even.rouault at spatialys.com>
+
+ * html/man/Makefile.am: remove thumbnail.1.html and rgb2ycbcr.1.html
+ from installed pages since the corresponding utilities are no longer
+ installed. Reported by Havard Eidnes
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2606
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_write.c: fix misleading indentation as warned by GCC.
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiffcp.c: replace assert( (bps % 8) == 0 ) by a non assert check.
+ Reported by Agostino Sarubbo.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2605
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiffcp.c: fix uint32 underflow/overflow that can cause heap-based
+ buffer overflow.
+ Reported by Agostino Sarubbo.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2610
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiffcp.c: avoid potential division by zero is BitsPerSamples tag is
+ missing.
+ Reported by Agostino Sarubbo.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2607
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+ * man/Makefile.am: remove thumbnail.1 and rgb2ycbcr.1 from installed man
+ pages since the corresponding utilities are no longer installed.
+ Reported by Havard Eidnes
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2606
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tif_dir.c: when TIFFGetField(, TIFFTAG_NUMBEROFINKS, ) is called,
+ limit the return number of inks to SamplesPerPixel, so that code that parses
+ ink names doesn't go past the end of the buffer.
+ Reported by Agostino Sarubbo.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2599
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiffcp.c: avoid potential division by zero is BitsPerSamples tag is
+ missing.
+ Reported by Agostino Sarubbo.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2597
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiffinfo.c: fix null pointer dereference in -r mode when the image has
+ no StripByteCount tag.
+ Reported by Agostino Sarubbo.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2594
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiffcrop.c: fix integer division by zero when BitsPerSample is missing.
+ Reported by Agostino Sarubbo.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2619
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiffcrop.c: add 3 extra bytes at end of strip buffer in
+ readSeparateStripsIntoBuffer() to avoid read outside of heap allocated buffer.
+ Reported by Agostino Sarubbo.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2621
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiffcrop.c: fix readContigStripsIntoBuffer() in -i (ignore) mode so
+ that the output buffer is correctly incremented to avoid write outside bounds.
+ Reported by Agostino Sarubbo.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2620
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_ojpeg.c: make OJPEGDecode() early exit in case of failure in
+ OJPEGPreDecode(). This will avoid a divide by zero, and potential other issues.
+ Reported by Agostino Sarubbo.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2611
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dirread.c: modify ChopUpSingleUncompressedStrip() to
+ instantiate compute nstrips as TIFFhowmany_32(td->td_imagelength, rowsperstrip),
+ instead of a logic based on the total size of data. Which is faulty is
+ the total size of data is not sufficient to fill the whole image, and thus
+ results in reading outside of the StripByCounts/StripOffsets arrays when
+ using TIFFReadScanline().
+ Reported by Agostino Sarubbo.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2608.
+
+ * libtiff/tif_strip.c: revert the change in TIFFNumberOfStrips() done
+ for http://bugzilla.maptools.org/show_bug.cgi?id=2587 / CVE-2016-9273 since
+ the above change is a better fix that makes it unnecessary.
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_pixarlog.c, libtiff/tif_luv.c: fix heap-based buffer
+ overflow on generation of PixarLog / LUV compressed files, with
+ ColorMap, TransferFunction attached and nasty plays with bitspersample.
+ The fix for LUV has not been tested, but suffers from the same kind
+ of issue of PixarLog.
+ Reported by Agostino Sarubbo.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2604
+
+2016-12-02 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiffcp.c: avoid uint32 underflow in cpDecodedStrips that
+ can cause various issues, such as buffer overflows in the library.
+ Reported by Agostino Sarubbo.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2598
+
+2016-12-02 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_read.c, libtiff/tiffiop.h: fix uint32 overflow in
+ TIFFReadEncodedStrip() that caused an integer division by zero.
+ Reported by Agostino Sarubbo.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2596
+
+2016-11-20 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_getimage.c, libtiff/tif_open.c: add parenthesis to
+ fix cppcheck clarifyCalculation warnings
+ * libtiff/tif_predict.c, libtiff/tif_print.c: fix printf unsigned
+ vs signed formatting (cppcheck invalidPrintfArgType_uint warnings)
+
+2016-11-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/fax2tiff.c (main): Applied patch by Jörg Ahrens to fix
+ passing client data for Win32 builds using tif_win32.c
+ (USE_WIN32_FILEIO defined) for file I/O. Patch was provided via
+ email on November 20, 2016.
+
+2016-11-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff 4.0.7 released.
+
+ * configure.ac: Update for 4.0.7 release.
+
+ * tools/tiffdump.c (ReadDirectory): Remove uint32 cast to
+ _TIFFmalloc() argument which resulted in Coverity report. Added
+ more mutiplication overflow checks.
+
+2016-11-18 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiffcrop.c: Fix memory leak in (recent) error code path.
+ Fixes Coverity 1394415.
+
+2016-11-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_getimage.c: Fix some benign warnings which appear in
+ 64-bit compilation under Microsoft Visual Studio of the form
+ "Arithmetic overflow: 32-bit value is shifted, then cast to 64-bit
+ value. Results might not be an expected value.". Problem was
+ reported on November 16, 2016 on the tiff mailing list.
+
+2016-11-16 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dirread.c: in TIFFFetchNormalTag(), do not dereference
+ NULL pointer when values of tags with TIFF_SETGET_C16_ASCII / TIFF_SETGET_C32_ASCII
+ access are 0-byte arrays.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2593 (regression introduced
+ by previous fix done on 2016-11-11 for CVE-2016-9297).
+ Reported by Henri Salo. Assigned as CVE-2016-9448
+
+2016-11-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/tiffinfo.c (TIFFReadContigTileData): Fix signed/unsigned
+ comparison warning.
+ (TIFFReadSeparateTileData): Fix signed/unsigned comparison
+ warning.
+
+ * tools/tiffcrop.c (readContigTilesIntoBuffer): Fix
+ signed/unsigned comparison warning.
+
+ * html/v4.0.7.html: Add a file to document the pending 4.0.7
+ release.
+
+2016-11-11 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiff2pdf.c: avoid undefined behaviour related to overlapping
+ of source and destination buffer in memcpy() call in
+ t2p_sample_rgbaa_to_rgb()
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2577
+
+2016-11-11 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiff2pdf.c: fix potential integer overflows on 32 bit builds
+ in t2p_read_tiff_size()
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2576
+
+2016-11-11 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_aux.c: fix crash in TIFFVGetFieldDefaulted()
+ when requesting Predictor tag and that the zip/lzw codec is not
+ configured.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2591
+
+2016-11-11 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dirread.c: in TIFFFetchNormalTag(), make sure that
+ values of tags with TIFF_SETGET_C16_ASCII / TIFF_SETGET_C32_ASCII
+ access are null terminated, to avoid potential read outside buffer
+ in _TIFFPrintField().
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2590 (CVE-2016-9297)
+
+2016-11-11 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dirread.c: reject images with OJPEG compression that
+ have no TileOffsets/StripOffsets tag, when OJPEG compression is
+ disabled. Prevent null pointer dereference in TIFFReadRawStrip1()
+ and other functions that expect td_stripbytecount to be non NULL.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2585
+
+2016-11-11 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiffcrop.c: fix multiple uint32 overflows in
+ writeBufferToSeparateStrips(), writeBufferToContigTiles() and
+ writeBufferToSeparateTiles() that could cause heap buffer overflows.
+ Reported by Henri Salo from Nixu Corporation.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2592 (CVE-2016-9532)
+
+2016-11-10 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_strip.c: make TIFFNumberOfStrips() return the td->td_nstrips
+ value when it is non-zero, instead of recomputing it. This is needed in
+ TIFF_STRIPCHOP mode where td_nstrips is modified. Fixes a read outsize of
+ array in tiffsplit (or other utilities using TIFFNumberOfStrips()).
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2587 (CVE-2016-9273)
+
+2016-11-04 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_predic.c: fix memory leaks in error code paths added in
+ previous commit (fix for MSVR 35105)
+
+2016-10-31 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_predict.h, libtiff/tif_predict.c:
+ Replace assertions by runtime checks to avoid assertions in debug mode,
+ or buffer overflows in release mode. Can happen when dealing with
+ unusual tile size like YCbCr with subsampling. Reported as MSVR 35105
+ by Axel Souchet & Vishal Chauhan from the MSRC Vulnerabilities & Mitigations
+ team.
+
+2016-10-26 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/fax2tiff.c: fix segfault when specifying -r without
+ argument. Patch by Yuriy M. Kaminskiy.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2572
+
+2016-10-25 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dir.c: discard values of SMinSampleValue and
+ SMaxSampleValue when they have been read and the value of
+ SamplesPerPixel is changed afterwards (like when reading a
+ OJPEG compressed image with a missing SamplesPerPixel tag,
+ and whose photometric is RGB or YCbCr, forcing SamplesPerPixel
+ being 3). Otherwise when rewriting the directory (for example
+ with tiffset, we will expect 3 values whereas the array had been
+ allocated with just one), thus causing a out of bound read access.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2500
+ (CVE-2014-8127, duplicate: CVE-2016-3658)
+
+ * libtiff/tif_dirwrite.c: avoid null pointer dereference on td_stripoffset
+ when writing directory, if FIELD_STRIPOFFSETS was artificially set
+ for a hack case in OJPEG case.
+ Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2500
+ (CVE-2014-8127, duplicate: CVE-2016-3658)
+
+2016-10-25 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiffinfo.c: fix out-of-bound read on some tiled images.
+ (http://bugzilla.maptools.org/show_bug.cgi?id=2517)
+
+ * libtiff/tif_compress.c: make TIFFNoDecode() return 0 to indicate an
+ error and make upper level read routines treat it accordingly.
+ (linked to the test case of http://bugzilla.maptools.org/show_bug.cgi?id=2517)
+
+2016-10-14 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiffcrop.c: fix out-of-bound read of up to 3 bytes in
+ readContigTilesIntoBuffer(). Reported as MSVR 35092 by Axel Souchet
+ & Vishal Chauhan from the MSRC Vulnerabilities & Mitigations team.
+
+2016-10-09 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiff2pdf.c: fix write buffer overflow of 2 bytes on JPEG
+ compressed images. Reported by Tyler Bohan of Cisco Talos as
+ TALOS-CAN-0187 / CVE-2016-5652.
+ Also prevents writing 2 extra uninitialized bytes to the file stream.
+
+2016-10-08 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiffcp.c: fix out-of-bounds write on tiled images with odd
+ tile width vs image width. Reported as MSVR 35103
+ by Axel Souchet and Vishal Chauhan from the MSRC Vulnerabilities &
+ Mitigations team.
+
+2016-10-08 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiff2pdf.c: fix read -largely- outsize of buffer in
+ t2p_readwrite_pdf_image_tile(), causing crash, when reading a
+ JPEG compressed image with TIFFTAG_JPEGTABLES length being one.
+ Reported as MSVR 35101 by Axel Souchet and Vishal Chauhan from
+ the MSRC Vulnerabilities & Mitigations team. CVE-2016-9453
+
+2016-10-08 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiffcp.c: fix read of undefined variable in case of missing
+ required tags. Found on test case of MSVR 35100.
+ * tools/tiffcrop.c: fix read of undefined buffer in
+ readContigStripsIntoBuffer() due to uint16 overflow. Probably not a
+ security issue but I can be wrong. Reported as MSVR 35100 by Axel
+ Souchet from the MSRC Vulnerabilities & Mitigations team.
+
+2016-09-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * html: Change as many remotesensing.org broken links to a working
+ URL as possible.
+
+2016-09-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_getimage.c (TIFFRGBAImageOK): Reject attempts to
+ read floating point images.
+
+ * libtiff/tif_predict.c (PredictorSetup): Enforce bits-per-sample
+ requirements of floating point predictor (3). Fixes CVE-2016-3622
+ "Divide By Zero in the tiff2rgba tool."
+
+2016-09-23 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiffcrop.c: fix various out-of-bounds write vulnerabilities
+ in heap or stack allocated buffers. Reported as MSVR 35093,
+ MSVR 35096 and MSVR 35097. Discovered by Axel Souchet and Vishal
+ Chauhan from the MSRC Vulnerabilities & Mitigations team.
+ * tools/tiff2pdf.c: fix out-of-bounds write vulnerabilities in
+ heap allocate buffer in t2p_process_jpeg_strip(). Reported as MSVR
+ 35098. Discovered by Axel Souchet and Vishal Chauhan from the MSRC
+ Vulnerabilities & Mitigations team.
+ * libtiff/tif_pixarlog.c: fix out-of-bounds write vulnerabilities
+ in heap allocated buffers. Reported as MSVR 35094. Discovered by
+ Axel Souchet and Vishal Chauhan from the MSRC Vulnerabilities &
+ Mitigations team.
+ * libtiff/tif_write.c: fix issue in error code path of TIFFFlushData1()
+ that didn't reset the tif_rawcc and tif_rawcp members. I'm not
+ completely sure if that could happen in practice outside of the odd
+ behaviour of t2p_seekproc() of tiff2pdf). The report points that a
+ better fix could be to check the return value of TIFFFlushData1() in
+ places where it isn't done currently, but it seems this patch is enough.
+ Reported as MSVR 35095. Discovered by Axel Souchet & Vishal Chauhan &
+ Suha Can from the MSRC Vulnerabilities & Mitigations team.
+
+2016-09-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * html/man/index.html: Comment out links to documentation for
+ abandoned utilities.
+
+2016-09-17 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_lzma.c: typo fix in comment
+
+2016-09-04 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/*.c: fix warnings raised by clang 3.9 -Wcomma
+
+2016-09-03 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dirwrite.c, libtiff/tif_color.c: fix warnings raised
+ by GCC 5 / clang -Wfloat-conversion
+
+2016-08-16 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiffcrop.c: fix C99'ism.
+
+2016-08-15 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiff2bw.c: fix weight computation that could result of color
+ value overflow (no security implication). Fix bugzilla #2550.
+ Patch by Frank Freudenberg.
+
+2016-08-15 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/rgb2ycbcr.c: validate values of -v and -h parameters to
+ avoid potential divide by zero. Fixes CVE-2016-3623 (bugzilla #2569)
+
+2016-08-15 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiffcrop.c: Fix out-of-bounds write in loadImage().
+ From patch libtiff-CVE-2016-3991.patch from
+ libtiff-4.0.3-25.el7_2.src.rpm by Nikola Forro (bugzilla #2543)
+
+2016-08-15 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_pixarlog.c: Fix write buffer overflow in PixarLogEncode
+ if more input samples are provided than expected by PixarLogSetupEncode.
+ Idea based on libtiff-CVE-2016-3990.patch from
+ libtiff-4.0.3-25.el7_2.src.rpm by Nikola Forro, but with different and
+ simpler check. (bugzilla #2544)
+
+2016-08-15 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiff2rgba.c: Fix integer overflow in size of allocated
+ buffer, when -b mode is enabled, that could result in out-of-bounds
+ write. Based initially on patch tiff-CVE-2016-3945.patch from
+ libtiff-4.0.3-25.el7_2.src.rpm by Nikola Forro, with correction for
+ invalid tests that rejected valid files. (bugzilla #2545)
+
+2016-07-11 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiffcrop.c: Avoid access outside of stack allocated array
+ on a tiled separate TIFF with more than 8 samples per pixel.
+ Reported by Kaixiang Zhang of the Cloud Security Team, Qihoo 360
+ (CVE-2016-5321 / CVE-2016-5323 , bugzilla #2558 / #2559)
+
+2016-07-10 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_read.c: Fix out-of-bounds read on
+ memory-mapped files in TIFFReadRawStrip1() and TIFFReadRawTile1()
+ when stripoffset is beyond tmsize_t max value (reported by
+ Mathias Svensson)
+
+2016-07-10 Even Rouault <even.rouault at spatialys.com>
+
+ * tools/tiffdump.c: fix a few misaligned 64-bit reads warned
+ by -fsanitize
+
+2016-07-03 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_read.c: make TIFFReadEncodedStrip() and
+ TIFFReadEncodedTile() directly use user provided buffer when
+ no compression (and other conditions) to save a memcpy().
+
+ * libtiff/tif_write.c: make TIFFWriteEncodedStrip() and
+ TIFFWriteEncodedTile() directly use user provided buffer when
+ no compression to save a memcpy().
+
+2016-07-01 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_luv.c: validate that for COMPRESSION_SGILOG and
+ PHOTOMETRIC_LOGL, there is only one sample per pixel. Avoid
+ potential invalid memory write on corrupted/unexpected images when
+ using the TIFFRGBAImageBegin() interface (reported by
+ Clay Wood)
+
+2016-06-28 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_pixarlog.c: fix potential buffer write overrun in
+ PixarLogDecode() on corrupted/unexpected images (reported by Mathias Svensson)
+ (CVE-2016-5875)
+
+2016-06-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/libtiff.def: Added _TIFFMultiply32 and _TIFFMultiply64
+ to libtiff.def
+
+2016-06-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/Makefile.am: The libtiff tools bmp2tiff, gif2tiff,
+ ras2tiff, sgi2tiff, sgisv, and ycbcr are completely removed from
+ the distribution. The libtiff tools rgb2ycbcr and thumbnail are
+ only built in the build tree for testing. Old files are put in
+ new 'archive' subdirectory of the source repository, but not in
+ distribution archives. These changes are made in order to lessen
+ the maintenance burden.
+
+2016-05-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_config.vc.h (HAVE_SNPRINTF): Add a '1' to the
+ HAVE_SNPRINTF definition.'
+
+2016-05-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_config.vc.h (HAVE_SNPRINTF): Applied patch by Edward
+ Lam to define HAVE_SNPRINTF for Visual Studio 2015.
+
+2016-04-27 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dirread.c: when compiled with DEFER_STRILE_LOAD,
+ fix regression, introduced on 2014-12-23, when reading a one-strip
+ file without a StripByteCounts tag. GDAL #6490
+
+2016-04-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * html/bugs.html: Replace Andrey Kiselev with Bob Friesenhahn for
+ purposes of security issue reporting.
+
+2016-01-23 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/*: upstream typo fixes (mostly contributed by Kurt Schwehr)
+ coming from GDAL internal libtiff
+
+2016-01-09 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_fax3.h: make Param member of TIFFFaxTabEnt structure
+ a uint16 to reduce size of the binary.
+
+2016-01-03 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_read.c, tif_dirread.c: fix indentation issues raised
+ by GCC 6 -Wmisleading-indentation
+
+2015-12-27 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_pixarlog.c: avoid zlib error messages to pass a NULL
+ string to %s formatter, which is undefined behaviour in sprintf().
+
+2015-12-27 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_next.c: fix potential out-of-bound write in NeXTDecode()
+ triggered by http://lcamtuf.coredump.cx/afl/vulns/libtiff5.tif
+ (bugzilla #2508)
+
+2015-12-27 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_luv.c: fix potential out-of-bound writes in decode
+ functions in non debug builds by replacing assert()s by regular if
+ checks (bugzilla #2522).
+ Fix potential out-of-bound reads in case of short input data.
+
+2015-12-26 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_getimage.c: fix out-of-bound reads in TIFFRGBAImage
+ interface in case of unsupported values of SamplesPerPixel/ExtraSamples
+ for LogLUV / CIELab. Add explicit call to TIFFRGBAImageOK() in
+ TIFFRGBAImageBegin(). Fix CVE-2015-8665 reported by limingxing and
+ CVE-2015-8683 reported by zzf of Alibaba.
+
+2015-12-21 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dirread.c: workaround false positive warning of Clang Static
+ Analyzer about null pointer dereference in TIFFCheckDirOffset().
+
+2015-12-19 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_fax3.c: remove dead assignment in Fax3PutEOLgdal(). Found
+ by Clang Static Analyzer
+
+2015-12-18 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dirwrite.c: fix truncation to 32 bit of file offsets in
+ TIFFLinkDirectory() and TIFFWriteDirectorySec() when aligning directory
+ offsets on a even offset (affects BigTIFF). This was a regression of the
+ changeset of 2015-10-19.
+
+2015-12-12 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_write.c: TIFFWriteEncodedStrip() and TIFFWriteEncodedTile()
+ should return -1 in case of failure of tif_encodestrip() as documented
+ * libtiff/tif_dumpmode.c: DumpModeEncode() should return 0 in case of
+ failure so that the above mentioned functions detect the error.
+
+2015-12-06 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/uvcode.h: const'ify uv_code array
+
+2015-12-06 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dirinfo.c: const'ify tiffFields, exifFields,
+ tiffFieldArray and exifFieldArray arrays
+
+2015-12-06 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_print.c: constify photoNames and orientNames arrays
+
+2015-12-06 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_close.c, libtiff/tif_extension.c : rename link
+ variable to avoid -Wshadow warnings
+
+2015-11-22 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/*.c: fix typos in comments (patch by Kurt Schwehr)
+
+2015-11-22 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/*.c: fix MSVC warnings related to cast shortening and
+ assignment within conditional expression
+
+2015-11-18 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/*.c: fix clang -Wshorten-64-to-32 warnings
+
+2015-11-18 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dirread.c: initialize double* data at line 3693 to NULL
+ to please MSVC 2013
+
+2015-11-17 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dirread.c: prevent reading ColorMap or TransferFunction
+ if BitsPerPixel > 24, so as to avoid huge memory allocation and file
+ read attempts
+
+2015-11-02 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dirread.c: remove duplicated assignment (reported by
+ Clang static analyzer)
+
+2015-10-28 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dir.c, libtiff/tif_dirinfo.c, libtiff/tif_compress.c,
+ libtiff/tif_jpeg_12.c: suppress warnings about 'no previous
+ declaration/prototype'
+
+2015-10-19 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tiffiop.h, libtiff/tif_dirwrite.c: suffix constants by U to fix
+ 'warning: negative integer implicitly converted to unsigned type' warning
+ (part of -Wconversion)
+
+2015-10-17 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_dir.c, libtiff/tif_dirread.c, libtiff/tif_getimage.c,
+ libtiff/tif_print.c: fix -Wshadow warnings (only in libtiff/)
+
+2015-09-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff 4.0.6 released.
+
+ * html/v4.0.6.html: Added release notes for 4.0.6.
+
+2015-09-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/tiffgt.c: Silence glut API deprecation warnings on MacOS
+ X. Patch by Roger Leigh.
+
+ * Makefile.am: Added a 'coverity' rule to assist with Coverity
+ submissions.
+
+ * tools/tiff2pdf.c: Fix compiler warning about unused function
+ when JPEG is not available.
+
+ * tools/fax2ps.c (main): Detect failure to write to temporary
+ file.
+
+2015-09-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_dirread.c (TIFFReadDirEntryCheckRangeSlongSlong8):
+ Change implementation so that it does not sometimes overflow the
+ range of a 32-bit int and to avoid a signed vs unsigned compare
+ compiler warning.
+ (TIFF_INT64_MAX): Avoid use of platform-specific large constants.
+ (TIFF_UINT32_MAX): Avoid use of platform-specific large constants.
+
+2015-09-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am (distcheck-hook), configure.ac: Applied patches by
+ Roger Leigh (via tiff mailing list on 2015-09-01) to fix issue
+ with BSD make and to make use of cmake in 'distcheck' target
+ conditional on if cmake is available.
+
+ * CMakeLists.txt, Makefile.am, configure.ac: Applied patches by
+ Roger Leigh (via tiff mailing list on 2015-09-01).
+
+ CMake build is now included in 'distcheck' target.
+
+ Builds with CMake 2.8.9 and newer.
+
+ Tar is now resquested to use POSIX PAX format.
+
+2015-08-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * CMakeLists.txt, libtiff/test/Makefile.am: Applied patches by
+ Roger Leigh (via tiff mailing list on 2015-08-31.
+
+ CMake reads all version information directly from configure.ac to
+ avoid duplication of values. This basically greps over the file
+ for the LIBTIFF_* variables, then translates them to the form
+ needed for cmake. This includes the release version and libtool
+ shared library version information.
+
+ Make shared/static library building configurable. Currently it
+ always builds shared libraries, with static libs having a _static
+ suffix (copying zlib, but it means it's got a non-standard name).
+ CMake has a -DBUILD_SHARED_LIBS=ON|OFF option to select one or the
+ other, which is now used instead. There's now a single "tiff"
+ target to build either shared or static as required, and all the
+ tests and tools are linked with this. Note: the Windows tests fail
+ when linked with a static libtiff (says: libtiff.dll not found).
+ Not really a regression since this was not tested up to this
+ point, and it's likely the unit tests haven't (ever?) been run on
+ Windows with a static libtiff, so there's some additional
+ portability issue here to address. Works fine on UNIX systems,
+ and fine on Windows with the default to build a DLL.
+
+ Add a missing file which wasn't being distributed, causing unit
+ tests to fail. Note that "find . -name '*.cmake'" lists all the
+ CMake files which need distributing in addition to all the
+ CMakeLists.txt files (which now are distributed).
+
+2015-08-31 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_predict.c: pedantic change to add explicit masking
+ with 0xff before casting to uchar in floating-point horizontal
+ differencing and accumulation routines.
+
+2015-08-31 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_predict.c: fix generation of output with 16 bit
+ or 32 bit integer, when byte swapping is needed, in
+ horizontal predictor (#2521). Also fixes decoding when there is
+ a single pixel to code (unlikely case...) and byte swapping is
+ involved.
+
+2015-08-30 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_lzw.c: make nextdata a unsigned type to avoid
+ undefined behaviour with shifts (gcc -fsanitize=shift)
+
+2015-08-30 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_fax3.c, libtiff/tif_lzw.c, libtiff/tif_predict.c:
+ add explicit masking with 0xff before casting
+ to unsigned char (make icc -check=conversions happy)
+
+ * libtiff/tif_predict.c: operate on unsigned datatypes when
+ computing/applying differences to avoid undefined behaviour of
+ signed types (C standard compliance)
+
+2015-08-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: libtiff 4.0.5 released.
+
+2015-08-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * CMakeLists.txt: Applied patch by Roger Leigh (via tiff mailing
+ list on 2015-08-29) to add ld-version-script option to cmake build
+ to match autoconf. Note: defaults to 'on' to be ABI-compatible by
+ default with common Linux distribution builds. Note that the
+ autoconf configure script defaults to 'off'.
+
+ * html/build.html: Applied patch by Roger Leigh (via tiff mailing
+ list on 2015-08-29) to describe how to use CMake to build libtiff.
+
+2015-08-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * html/v4.0.5.html: Added HTML file describing the changes which
+ will appear in the 4.0.5 release.
+
+2015-08-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tiffiop.h: For MinGW comiles, make sure that build
+ supports necessary __MSVCRT_VERSION__ (at least at least 0x800).
+ Otherwise large files can not be supported for POSIX-style I/O.
+
+ * tools/fax2tiff.c (main): Eliminate a compiler warning in 64-bit
+ builds about cast to thandle_t.
+
+ * test/rewrite_tag.c (main): Does not require any arguments.
+
+2015-08-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/CMakeLists.txt, port/snprintf.c: Patch by Roger Leigh to
+ fix build issues when using Cmake due to Windows large file
+ changes.
+
+2015-08-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tiffiop.h: First cut at supporting large files under
+ Microsoft Windows using tif_unix.c and the libtiff tools. This
+ only works if the Windows CDK is new enough to support the APIs
+ used (Visual C++ 2005 or later). Support for large files is not
+ actually tested yet.
+
+2015-08-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_jpeg.c: Applied patch by Räisä Olli to assure that
+ client_data is initialized to a known value, and to report an
+ error on two memory allocation failures.
+
+2015-08-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * CMakeLists.txt: Applied patch by Roger Leigh to fix libtiffxx
+ symbol versioning. Patch was mailed to libtiff list on Thu, 13
+ Aug 2015.
+
+2015-07-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * cmake: Add d suffix to debug libraries with MSVC. Patch #3 of 3
+ by Roger Leigh posted to tiff list on Wed, 1 Jul 2015 15:58:20
+ +0100.
+
+ * cmake: Add extra warning flags. Patch #2 of 3 by Roger Leigh
+ posted to tiff list on Wed, 1 Jul 2015 15:58:20 +0100.
+
+ * cmake: Correct snprintf fallback for VS2015. Patch #1 of 3 by
+ Roger Leigh posted to tiff list on Wed, 1 Jul 2015 15:58:20 +0100.
+
+2015-06-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * CMakeLists.txt: Add CMake patchset by Roger Leigh as posted to
+ libtiff mailing list on Mon, 22 Jun 2015 21:21:01 +0100. Several
+ corrections to ensure that the autotools build still works were
+ added by me. I have not yet tested the build using 'cmake' or
+ MSVC with 'nmake'.
+
+2015-06-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * test/Makefile.am: tiff2rgba-quad-tile.jpg.sh depends on the JPEG
+ library so only execute if JPEG is available.
+
+ * libtiff 4.0.4 released.
+
+ * configure.ac: Add a HAVE_FOO Automake conditional for each
+ add-on library.
+
+ * test/Makefile.am (JPEG_DEPENDENT_CHECK_PROG): raw_decode
+ requires JPEG support to compile. Use Automake conditional to
+ only include it when JPEG support is available.
+
+ * html/build.html: Try to improve the nmake-based VC++ build
+ description.
+
+ * libtiff/tiffconf.vc.h: Build fixes based on testing.
+
+ * libtiff/tif_config.vc.h: Build fixes based on testing.
+
+ * libtiff/libtiff.def: TIFFRasterScanline does not exist so remove
+ export for it.
+
+2015-06-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_config.vc.h: Make adjustments to match the new
+ definitions that configure produces, including for WIN64. Still
+ needs to be tested.
+
+ * configure.ac: For 64-bit MinGW, fix SSIZE_FORMAT formatting
+ specifier. 64-bit MinGW supports 'long long' but support for
+ 'lld' is not assured by the run-time DLLs and so GCC warns.
+ Add TIFF_SIZE_T and TIFF_SIZE_FORMAT to provide a type definition
+ and printf format specifier to deal with printing values of
+ 'size_t' type. In particular, this was necessary for WIN64.
+ Added a configure test for if the system headers provide 'optarg'
+ (normal case) and block out the many explicit 'extern' statements
+ in the utilities. This was found to be necessary under Windows
+ when getopt is in a DLL and the symbols are already imported with
+ dllimport via standard header files.
+
+ * test/raw_decode.c (XMD_H): Avoid conflicting typedefs for INT32
+ and boolean in MinGW build due to including jpeglib.h.
+
+ * test/rewrite_tag.c (main): Fix problem with location of variable
+ declaration.
+
+ * libtiff/libtiff.def: Added exports for TIFFGetConfiguredCODECs,
+ TIFFReadRGBAImageOriented, TIFFSetCompressionScheme,
+ TIFFSwabArrayOfTriples, TIFFVGetFieldDefaulted, _TIFFCheckRealloc,
+ TIFFRasterScanline, TIFFSetErrorHandlerExt,
+ TIFFSetWarningHandlerExt, TIFFNumberOfDirectories,
+ TIFFCreateCustomDirectory, TIFFCreateEXIFDirectory,
+ TIFFWriteCustomDirectory, _TIFFRewriteField as recommended by
+ Roger Leigh and justified by use in libtiff tests, documentation,
+ and changelog notes. Also sorted symbol list and removed
+ duplicate entries.
+
+2015-06-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_getimage.c: Fix four Coverity issues related to
+ unintended sign extension.
+
+2015-06-16 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_unix.c: fix compilation with MSVC (fix by Jeff McKenna)
+
+2015-06-14 Lee Howard <faxguy@howardsilvan.com>
+
+ * libtiff/tif_unix.c: contribution from Vadim Zeitlin on
+ Bugzilla Bug #2510 fixes several harmless but still annoying
+ warnings
+
+ * configure: contribution from Ludolf Holzheid on Bugzilla
+ Bug #2498. Adds an option to select the file I/O style on
+ Windows hosts.
+
+ * libtiff/tif_getimage.c: contribution from Gary Cramblitt
+ on Bugzilla Bug #2409. Correct reading of certain tiled TIFFs.
+
+ * configure, configure.ac: contribution from Marcos H. Woehrmann
+ on Bugzilla Bug #2405. Correct shell equality operator.
+
+ * tools/tiffgt.c (raster_draw): contribution from Jay Berkenbilt
+ on Bugzilla Bug #2401. Appropriately call glFlush().
+
+ * tools/tiff2pdf.c: change ColorTransform from "0" to "1"
+ following Bugzilla Bug #2150.
+
+2015-06-13 Lee Howard <faxguy@howardsilvan.com>
+
+ * libtiff/tif_lzw.c: contribution from Andy Cave - decode
+ files that contain consecutive CODE_CLEAR codes.
+
+ * tools/tiff2pdf.c: contribution from Antti S. Lankila on
+ Bugzilla Bug #2078. Suppress initial output of the header.
+
+ * tools/tiff2pdf.c: contribution from Yuriy M. Kaminskiy -
+ Take care in using the return value from snprintf().
+
+ * tools/tiffcrop.c: contribution from Eduardo Robles Elvira -
+ correctly copy the compression tag from the source TIFF.
+
+ * tools/tiff2ps.c: contribution from Eduardo Robles Elvira -
+ correct sizing and scaling problems with output document.
+
+2015-06-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_jpeg.c (JPEGDecode): Split JPEGDecode() into two
+ clean implementations in order to avoid pre-processor hell. Only
+ one of the implementations is used in a given build.
+
+2015-06-08 Even Rouault <even.rouault at spatialys.com>
+
+ * libtiff/tif_jpeg.c: Fix compilation in BITS_IN_JSAMPLE == 12
+ case
+
+2015-06-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_write.c (TIFFWriteEncodedStrip): Fix Coverity 715975
+ "Division or modulo by zero".
+ (TIFFWriteEncodedTile): Fix Coverity 715976 and 715977 "Division
+ or modulo by zero".
+ (TIFFWriteRawStrip): Fix Coverity 715978 "Division or modulo by
+ zero".
+ (TIFFWriteScanline): Fix Coverity 715979 "Division or modulo by
+ zero".
+
+ * libtiff/tif_read.c (TIFFStartTile): Fix Coverity 715973 and
+ 715974 "Division or modulo by zero".
+
+2015-05-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_dir.c (TIFFNumberOfDirectories): Quiet Coverity
+ 1134470 "Logically dead code" by making the roll-over check
+ explicit.
+
+ * libtiff/tif_luv.c (LogLuvDecodeTile): Fix Coverity 991227
+ "Division or modulo by zero".
+ (LogLuvDecodeStrip): Fix Coverity 991239 "Division or modulo by
+ zero".
+ (LogLuvEncodeStrip): Fix Coverity 991240 "Division or modulo by
+ zero".
+ (LogLuvEncodeTile): Fix Coverity 991241 "Division or modulo by
+ zero".
+
+ * libtiff/tif_dirread.c (TIFFReadDirEntryDoubleArray): Fix
+ Coverity 298626 "Logically dead code".
+ (TIFFReadDirEntryFloatArray): Fix Coverity 298627 "Logically dead
+ code".
+ (TIFFReadDirEntryIfd8Array): Fix Coverity 298628 "Logically dead
+ code".
+ (TIFFReadDirEntrySlong8Array): Fix Coverity 298629 "Logically dead
+ code"
+
+ * libtiff/tif_dir.c (TIFFNumberOfDirectories): Don't depend on ++
+ operator precedenc in evaluation. Might quench Coverity 1134470
+ "Logically dead code".
+
+ * libtiff/tif_jpeg.c (JPEGDecode): Fix Coverity 602597 "Operands
+ don't affect result". This change uses ifdefs to include
+ applicable code based on properties of libjpeg. Still needs to be
+ re-tested with 12-bit "6b" and "MK1".
+
+2015-05-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_dirwrite.c (_TIFFRewriteField): Fix Coverity 1024310
+ "Resource leak".
+
+ * libtiff/tif_ojpeg.c (OJPEGReadHeaderInfoSecStreamDht): Fix
+ Coverity 601720 "Resource leak".
+
+ * libtiff/tif_jpeg.c (JPEGCleanup): Fix Coverity 298624
+ "Dereference before null check".
+
+ * libtiff/tif_ojpeg.c (OJPEGReadBufferFill): Fix Coverity 603400
+ "Missing break in switch".
+
+ * contrib/addtiffo/tif_overview.c (TIFF_DownSample): Check buffer
+ size calculation for overflow.
+
+ * contrib/addtiffo/addtiffo.c (main): Possibly address Coverity
+ 1024226 "Untrusted value as argument".
+
+ * tools/gif2tiff.c (readgifimage): Fix Coverity 1024222 "Untrusted
+ value as argument".
+ (checksignature): Fix Coverity 1024894 "Ignoring number of bytes
+ read".
+ (readextension): Fix Coverity 1024893 "Ignoring number of bytes
+ read".
+ (readgifimage): Fix Coverity 1024890 "Ignoring number of bytes
+ read".
+ (readraster): Fix Coverity 1024891 "Ignoring number of bytes
+ read".
+ (readgifimage): Fix Coverity 1024892 "Ignoring number of bytes
+ read".
+
+ * tools/tiff2pdf.c (t2p_readwrite_pdf_image): Fix Coverity 1024181
+ "Structurally dead code".
+
+ * tools/raw2tiff.c (main): Fix Coverity 1024887 "Unchecked return
+ value from library".
+ (guessSize): Fix Coverity 1024888 "Unchecked return value from
+ library".
+ (guessSize): Fix Coverity 1214162 "Ignoring number of bytes read".
+ (guessSize): Fix Coverity 1024889 "Unchecked return value from
+ library".
+
+ * tools/tiff2pdf.c (t2p_readwrite_pdf_image): Fix Coverity 298621
+ "Resource leak".
+ (t2p_readwrite_pdf_image): Fix Coverity 1024181 "Structurally dead
+ code".
+ (t2p_write_pdf): Fix Coverity 1227690 "Unused value".
+
+2015-05-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * contrib/iptcutil/iptcutil.c (formatIPTC): Fix Coverity 1024468
+ "Infinite loop".
+ (formatIPTC): Fix Coverity 1024727 "Truncated stdio return value".
+ (formatIPTC): Fix Coverity 1214240 "Untrusted loop bound".
+
+2015-05-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * contrib/addtiffo/tif_ovrcache.c (TIFFCreateOvrCache): Fix
+ Coverity 298615 "Resource leak".
+ (TIFFGetOvrBlock): Fix Coverity 1024649 "Unintended sign
+ extension".
+
+ * tools/bmp2tiff.c (main): Fix Coverity 1024225 "Untrusted value
+ as argument".
+ (main): Fix Coverity 1024678 "Unchecked return value from
+ library".
+ (main): Fix Coverity 1024679 "Unchecked return value from
+ library".
+ (main): Fix Coverity 1214160 "Ignoring number of bytes read".
+
+ * contrib/addtiffo/tif_ovrcache.c (TIFFCreateOvrCache): Fix
+ Coverity 298615 "Resource leak".
+
+ * tools/tiffcp.c: Fix Coverity 1024306, 1024307, 1024308, 1024309
+ "Resource leak".
+
+ * tools/tiffsplit.c (cpTiles): Fix Coverity 1024304 "Resource
+ leak".
+ (cpStrips): Fix Coverity 1024305 "Resource leak".
+
+2015-05-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/ras2tiff.c: Fix Sun Raster header definition to be safe
+ for 64-bit systems. Add some header validations. Should fix many
+ Coverity issues.
+ (main): Fix Coverity 1301206: "Integer handling issues (BAD_SHIFT)".
+ (main): Quiet Coverity 1024223 "Untrusted value as argument".
+
+ * tools/tiffmedian.c (GetInputLine): Fix Coverity 1024795 "Nesting
+ level does not match indentation".
+ (get_histogram): Quiet Coverity 1024386 "Out-of-bounds read".
+ This was a benign mis-diagnosis but added code to enforce against
+ buffer overflow.
+
+ * tools/tiffcrop.c (ROTATE_ANY): Fix Coverity 1294542 "Logical
+ vs. bitwise operator".
+ (readContigStripsIntoBuffer): Fix Coverity 1024545 "Division or
+ modulo by zero".
+ (readContigTilesIntoBuffer): Fix Coverity 1024586 "Logically dead
+ code".
+ (writeSingleSection): Fix Coverity 1024796 "Nesting level does not
+ match indentation".
+ (writeCroppedImage): Fix Coverity 1024797 "Nesting level does not
+ match indentation".
+ (loadImage): Fix Coverity 1299741 "Dereference before null check".
+ (loadImage): Fix Coverity 1299740 "Out-of-bounds write".
+
+2015-03-02 Even Rouault <even.rouault@spatialys.com>
+
+ * tools/tiffdither.c: check memory allocations to avoid writing to
+ NULL pointer. Also check multiplication overflow. Fixes #2501,
+ CVE-2014-8128. Derived from patch by Petr Gajdos.
+
+2015-01-26 Even Rouault <even.rouault@spatialys.com>
+
+ * add html/v4.0.4beta.html under version control
+ * HOWTO-RELEASE: write that cvs add html/vX.X.html must be used
+
+2015-01-26 Even Rouault <even.rouault@spatialys.com>
+
+ * libtiff 4.0.4beta released
+
+2015-01-26 Even Rouault <even.rouault@spatialys.com>
+
+ * automake: updated to 1.15
+ * libtool: updated to 2.4.5
+
+2015-01-22 Even Rouault <even.rouault@spatialys.com>
+
+ * tools/tiff2pdf.c: Fix two crashes (oCERT-2014-013)
+
+2015-01-05 Frank Warmerdam <warmerdam@pobox.com>
+
+ * html/bugs.html: remove note about needing to email the tiff mailing
+ list administrator about being approved for membership, this appears
+ not to be true.
+
+2015-01-05 Olivier Paquet <olivier.paquet@gmail.com>
+
+ * tools/tiff2pdf.c: Fixed unsigned integer addition overflow detection.
+
+2015-01-03 Even Rouault <even.rouault@spatialys.com>
+
+ * libtiff/tif_dirread.c: in TIFFCheckDirOffset(), avoid uint16 overflow
+ when reading more than 65535 directories, and effectively error out when
+ reaching that limit.
+
+2014-12-29 Even Rouault <even.rouault@spatialys.com>
+
+ * libtiff/tif_jpeg.c: in JPEGFixupTags(), recognize SOF2, SOF9 and SOF10
+ markers to avoid emitting a warning (even if, according to the TechNote,
+ there are admittedly unusual/not recommended or even forbidden variants, but
+ they do work well with libjpeg for SOF2, and with libjpeg-turbo for SOF2,
+ SOF9 and SOF10).
+ Define in_color_space and input_components to the right values in
+ JPEGSetupEncode(), before calling jpeg_set_defaults(), as specified by
+ libjpeg API documentation, so as to be compatible with mozjpeg library.
+ Note: the default settings of mozjpeg will produce progressive scans, which
+ is forbidden by the TechNote.
+
+2014-12-29 Even Rouault <even.rouault@spatialys.com>
+
+ * libtiff/tif_getimage.c: move test on vertical value of YCbCr subsampling.
+ to avoid buffer leak (fix previous fix, found by Coverity scan)
+
+2014-12-29 Even Rouault <even.rouault@spatialys.com>
+
+ * libtiff/tif_next.c: add new tests to check that we don't read outside of
+ the compressed input stream buffer.
+
+ * libtiff/tif_getimage.c: in OJPEG case, fix checks on strile width/height
+ in the putcontig8bitYCbCr42tile, putcontig8bitYCbCr41tile and
+ putcontig8bitYCbCr21tile cases.
+
+2014-12-27 Even Rouault <even.rouault@spatialys.com>
+
+ * libtiff/tif_dir.c: in TIFFDefaultDirectory(), reset any already existing
+ extended tags installed by user code through the extender mechanism before
+ calling the extender callback (GDAL #5054)
+
+2014-12-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/tiffcrop.c: Fix warnings about variables set but not used.
+
+ * contrib/iptcutil/iptcutil.c: Fix warnings about variables set
+ but not used.
+
+ * tools/tiffgt.c: Fix warnings about unused parameters.
+
+ * libtiff/tif_stream.cxx: Fix warnings about unused parameters.
+
+2014-12-25 Even Rouault <even.rouault@spatialys.com>
+
+ * libtiff/tif_getimage.c, libtiff/tif_ojpeg.c, libtiff/tif_zip.c: fix
+ various typos found by Debian lintian tool (GDAL #5756)
+
+2014-12-24 Even Rouault <even.rouault@spatialys.com>
+
+ * libtiff/tif_getimage.c: avoid divide by zero on invalid YCbCr subsampling.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2235
+
+2014-12-24 Even Rouault <even.rouault@spatialys.com>
+
+ * tools/tiff2pdf.c: fix buffer overflow on some YCbCr JPEG compressed images.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2445
+
+2014-12-24 Even Rouault <even.rouault@spatialys.com>
+
+ * tools/tiff2pdf.c: fix buffer overflow on YCbCr JPEG compressed image.
+ Derived from patch by Petr Gajdos,
+ http://bugzilla.maptools.org/show_bug.cgi?id=2443
+
+2014-12-23 Even Rouault <even.rouault@spatialys.com>
+
+ * libtiff/tif_dirread.c: In EstimateStripByteCounts(), check return code
+ of _TIFFFillStriles(). This solves crashing bug on corrupted
+ images generated by afl.
+
+2014-12-23 Even Rouault <even.rouault@spatialys.com>
+
+ * libtiff/tif_read.c: fix several invalid comparisons of a uint64 value with
+ <= 0 by casting it to int64 first. This solves crashing bug on corrupted
+ images generated by afl.
+
+2014-12-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/tiffdump.c: Guard against arithmetic overflow when
+ calculating allocation buffer sizes.
+
+2014-12-21 Even Rouault <even.rouault@spatialys.com>
+
+ * tools/tiff2bw.c: when Photometric=RGB, the utility only works if
+ SamplesPerPixel = 3. Enforce that
+ http://bugzilla.maptools.org/show_bug.cgi?id=2485 (CVE-2014-8127)
+
+2014-12-21 Even Rouault <even.rouault@spatialys.com>
+
+ * tools/pal2rgb.c, tools/thumbnail.c: fix crash by disabling TIFFTAG_INKNAMES
+ copying. The right fix would be to properly copy it, but not worth the burden
+ for those esoteric utilities.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2484 (CVE-2014-8127)
+
+2014-12-21 Even Rouault <even.rouault@spatialys.com>
+
+ * tools/thumbnail.c: fix out-of-buffer write
+ http://bugzilla.maptools.org/show_bug.cgi?id=2489 (CVE-2014-8128)
+
+2014-12-21 Even Rouault <even.rouault@spatialys.com>
+
+ * tools/thumbnail.c, tools/tiffcmp.c: only read/write TIFFTAG_GROUP3OPTIONS
+ or TIFFTAG_GROUP4OPTIONS if compression is COMPRESSION_CCITTFAX3 or
+ COMPRESSION_CCITTFAX4
+ http://bugzilla.maptools.org/show_bug.cgi?id=2493 (CVE-2014-8128)
+
+2014-12-21 Even Rouault <even.rouault@spatialys.com>
+
+ * libtiff/tif_next.c: check that BitsPerSample = 2. Fixes
+ http://bugzilla.maptools.org/show_bug.cgi?id=2487 (CVE-2014-8129)
+
+2014-12-21 Even Rouault <even.rouault@spatialys.com>
+
+ * tools/tiff2pdf.c: check return code of TIFFGetField() when reading
+ TIFFTAG_SAMPLESPERPIXEL
+
+2014-12-21 Even Rouault <even.rouault@spatialys.com>
+
+ * tools/tiffcp.c: fix crash when converting YCbCr JPEG-compressed to none.
+ Based on patch by Tomasz Buchert (http://bugzilla.maptools.org/show_bug.cgi?id=2480)
+ Description: fix for Debian bug #741451
+ tiffcp crashes when converting JPEG-encoded TIFF to a different
+ encoding (like none or lzw). For example this will probably fail:
+ tiffcp -c none jpeg_encoded_file.tif output.tif
+ The reason is that when the input file contains JPEG data,
+ the tiffcp code forces conversion to RGB space. However,
+ the output normally inherits YCbCr subsampling parameters
+ from the input, which leads to a smaller working buffer
+ than necessary. The buffer is subsequently overrun inside
+ cpStripToTile() (called from writeBufferToContigTiles).
+ Note that the resulting TIFF file would be scrambled even
+ if tiffcp wouldn't crash, since the output file would contain
+ RGB data interpreted as subsampled YCbCr values.
+ This patch fixes the problem by forcing RGB space on the output
+ TIF if the input is JPEG-encoded and output is *not* JPEG-encoded.
+ Author: Tomasz Buchert <tomasz.buchert@inria.fr>
+
+2014-12-21 Even Rouault <even.rouault@spatialys.com>
+
+ Fix various crash bugs on fuzzed images.
+ * libtiff/tif_dir.c: TIFFSetField(): refuse to set negative values for
+ TIFFTAG_XRESOLUTION and TIFFTAG_YRESOLUTION that cause asserts when writing
+ the directory
+ * libtiff/tif_dirread.c: TIFFReadDirectory(): refuse to read ColorMap or
+ TransferFunction if BitsPerSample has not yet been read, otherwise reading
+ it later will cause user code to crash if BitsPerSample > 1
+ * libtiff/tif_getimage.c: TIFFRGBAImageOK(): return FALSE if LOGLUV with
+ SamplesPerPixel != 3, or if CIELAB with SamplesPerPixel != 3 or BitsPerSample != 8
+ * libtiff/tif_next.c: in the "run mode", use tilewidth for tiled images
+ instead of imagewidth to avoid crash
+ * tools/bmp2tiff.c: fix crash due to int overflow related to input BMP dimensions
+ * tools/tiff2pdf.c: fix crash due to invalid tile count (should likely be checked by
+ libtiff too). Detect invalid settings of BitsPerSample/SamplesPerPixel for CIELAB / ITULAB
+ * tools/tiffcrop.c: fix crash due to invalid TileWidth/TileHeight
+ * tools/tiffdump.c: fix crash due to overflow of entry count.
+
+2014-12-15 Even Rouault <even.rouault@spatialys.com>
+
+ * libtiff/tif_jpeg.c: Fix regression introduced on 2010-05-07 that caused
+ all tiles/strips to include quantization tables even when the jpegtablesmode
+ had the JPEGTABLESMODE_QUANT bit set.
+ Also add explicit removal of Huffman tables when jpegtablesmode has the
+ JPEGTABLESMODE_HUFF bit set, which avoids Huffman tables to be emitted in the
+ first tile/strip (only useful in update scenarios. create-only was
+ fine)
+
+2014-12-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/tiff2pdf.c: Assure that memory size calculations for
+ _TIFFmalloc() do not overflow the range of tmsize_t.
+
+2014-12-07 Even Rouault <even.rouault@spatialys.com>
+
+ * tools/thumbnail.c, tools/tiffcrop.c: "fix" heap read over-run found with
+ Valgrind and Address Sanitizer on test suite
+
+2014-12-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/tiff2pdf.c (t2p_read_tiff_init): TIFFTAG_TRANSFERFUNCTION
+ tag can return one channel, with the other two channels set to
+ NULL. The tiff2pdf code was expecting that other two channels
+ were duplicate pointers in the case where there is only one
+ channel. Detect this condition in order to avoid a crash, and
+ presumably perform correctly with just one channel.
+
+2014-12-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/tiffdump.c: Fix double-free bug.
+
+2014-11-27 Even Rouault <even.rouault@spatialys.com>
+
+ * libtiff/tif_config.vc.h: no longer use "#define snprintf _snprintf" with
+ Visual Studio 2015 aka VC 14 aka MSVC 1900
+
+2014-11-20 Even Rouault <even.rouault@spatialys.com>
+
+ * libtiff/tif_lzw.c: prevent potential null dereference of
+ sp->dec_codetab in LZWPreDecode (bug #2459)
+
+ * libtiff/tif_read.c: in TIFFReadBufferSetup(), avoid passing -1 size
+ to TIFFmalloc() if passed user buffer size is 0 (bug #2459)
+
+ * libtiff/tif_ojpeg.c: make Coverity happier (not a bug, #2459)
+
+ * libtiff/tif_dir.c: in _TIFFVGetField() and _TIFFVSetField(), make
+ Coverity happier (not a bug, #2459)
+
+ * libtiff/tif_dirread.c: in TIFFFetchNormalTag(), make Coverity happier
+ (not a bug, #2459)
+
+ * tools/tiff2pdf.c: close PDF file (bug #2479)
+
+ * tools/fax2ps.c: check malloc()/realloc() result (bug #2470)
+
+ * tools/tiffdump.c: detect cycle in TIFF directory chaining (bug #2463)
+ and avoid passing a NULL pointer to read() if seek() failed before (bug #2459)
+
+ * tools/tiffcrop.c: fix segfault if bad value passed to -Z option
+ (bug #2459) and add missing va_end in dump_info (#2459)
+
+ * tools/gif2tif.c: apply patch for CVE-2013-4243 (#2451)
+
+2014-11-20 Even Rouault <even.rouault@spatialys.com>
+ * libtiff/tif_jpeg.c: fix segfault in JPEGFixupTagsSubsampling() on
+ corrupted image where tif->tif_dir.td_stripoffset == NULL (bug #2471)
+
+2014-11-20 Even Rouault <even.rouault@spatialys.com>
+ * automake: updated to 1.14.1
+ * libtool: updated to 2.4.3
+ * HOWTO-RELEASE: small update about autotools building order
+
+2014-10-20 Olivier Paquet <olivier.paquet@gmail.com>
+ * tools/tiff2pdf.c: Preserve input file directory order when pages
+ are tagged with the same page number.
+
+2014-08-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_dirread.c (TIFFReadDirEntryOutputErr): Incorrect
+ count for tag should be a warning rather than an error since
+ errors terminate processing.
+
+2014-06-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/tiff2rgba.c (]): Fixed tiff2rgba usage message in that zip
+ was wrongly described. Fix suggested by Miguel Medalha.
+
+2014-05-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_dirinfo.c (TIFFField) : Fix data type for
+ TIFFTAG_GLOBALPARAMETERSIFD tag. Patch by Steve Underwood.
+ Reviewed and forwarded by Lee Howard.
+
+2013-11-30 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dir.c: fix last fix for TIFFNumberOfDirectories()
+
+2013-10-21 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dir.c: generate error in case of directory count
+ overflow.
+
+2013-10-01 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tiff.h, libtiff/tif_dirinfo.c: add definitions for
+ TIFF/EP CFARepeatPatternDim and CFAPattern tags (bug #2457)
+
+2013-09-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_dir.c (TIFFAdvanceDirectory): If nextdir is found to
+ be defective, then set it to zero before returning error in order
+ to terminate processing of truncated TIFF. Issue found and fix
+ suggested by Richard Nolde.
+
+2013-08-14 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tools/gif2tiff.c: fix possible OOB write (#2452, CVE-2013-4244)
+
+2013-08-13 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tools/gif2tiff.c: Be more careful about corrupt or
+ hostile input files (#2450, CVE-2013-4231)
+
+ * tools/tiff2pdf.c: terminate after failure of allocating
+ ycbcr buffer (bug #2449, CVE-2013-4232)
+
+2013-07-09 Frank Warmerdam <warmerdam@google.com>
+
+ * tools/tiffinfo.c: Default various values fetched with
+ TIFFGetField() to avoid being uninitialized.
+
+2013-05-02 Tom Lane <tgl@sss.pgh.pa.us>
+
+ * tools/tiff2pdf.c: Rewrite JPEG marker parsing in
+ t2p_process_jpeg_strip to be at least marginally competent. The
+ approach is still fundamentally flawed, but at least now it won't
+ stomp all over memory when given bogus input. Fixes CVE-2013-1960.
+
+2013-05-02 Tom Lane <tgl@sss.pgh.pa.us>
+
+ * contrib/dbs/xtiff/xtiff.c, libtiff/tif_codec.c,
+ libtiff/tif_dirinfo.c, tools/rgb2ycbcr.c, tools/tiff2bw.c,
+ tools/tiff2pdf.c, tools/tiff2ps.c, tools/tiffcrop.c,
+ tools/tiffdither.c: Enlarge some fixed-size buffers that weren't
+ large enough, and eliminate substantially all uses of sprintf(buf,
+ ...) in favor of using snprintf(buf, sizeof(buf), ...), so as to
+ protect against overflow of fixed-size buffers. This responds in
+ particular to CVE-2013-1961 concerning overflow in tiff2pdf.c's
+ t2p_write_pdf_page(), but in general it seems like a good idea to
+ deprecate use of sprintf().
+
+2013-03-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Applied patch by Brad Smith to improve pkg-config
+ static linking by adding -lm to Libs.private when needed.
+
+2013-03-05 Tom Lane <tgl@sss.pgh.pa.us>
+
+ * html/man/tiff2ps.1.html, html/man/tiffcp.1.html,
+ html/man/tiffdither.1.html, man/tiff2ps.1, man/tiffcp.1,
+ man/tiffdither.1, tools/tiff2ps.c, tools/tiffcp.c,
+ tools/tiffdither.c: Sync tool usage printouts and man pages with
+ reality (quite a few options had escaped being documented in one
+ or both places). Per an old report from Miroslav Vadkerti.
+
+2013-01-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/tiff2ps.c:Fix bug in auto rotate option code. Once a
+ rotation angle was set by the auto rotate check, it was retained
+ for all pages that followed instead ofa being retested for each
+ page. Patch by Richard Nolde.
+
+2013-01-18 Frank Warmerdam <warmerdam@google.com>
+
+ * libtiff/tif_write.c: tmsize_t related casting warning fixed for
+ 64bit linux.
+
+ * libtiff/tif_read.c: uint64/tmsize_t change for MSVC warnings.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2427
+
+2012-12-20 Tom Lane <tgl@sss.pgh.pa.us>
+
+ * test/raw_decode.c: Relax raw_decode's pixel-value checks so that
+ it will pass with more versions of libjpeg. (There are at least
+ three in active use now, and JPEG_LIB_VERSION doesn't tell us
+ enough to uniquely identify expected results.)
+
+2012-12-12 Tom Lane <tgl@sss.pgh.pa.us>
+
+ * libtiff/tif_print.c: Fix TIFFPrintDirectory's handling of
+ field_passcount fields: it had the TIFF_VARIABLE and
+ TIFF_VARIABLE2 cases backwards.
+
+2012-12-10 Tom Lane <tgl@sss.pgh.pa.us>
+
+ * tools/ppm2tiff.c: Improve previous patch for CVE-2012-4564:
+ check the linebytes calculation too, get the max() calculation
+ straight, avoid redundant error messages, check for malloc
+ failure.
+
+2012-12-10 Tom Lane <tgl@sss.pgh.pa.us>
+
+ * libtiff/tif_pixarlog.c: Improve previous patch for CVE-2012-4447
+ (to enlarge tbuf for possible partial stride at end) so that
+ overflow in the integer addition is detected. Per gripe from
+ Huzaifa Sidhpurwala.
+
+2012-12-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/tiffset.c: tiffset now supports a -u option to unset a
+ tag. Patch by Zach Baker. See
+ http://bugzilla.maptools.org/show_bug.cgi?id=2419
+
+2012-11-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * automake: Update Automake to 1.12.5 release.
+
+ * libtiff/tif_{unix,vms,win32}.c (_TIFFmalloc): ANSI C does not
+ require malloc() to return NULL pointer if requested allocation
+ size is zero. Assure that _TIFFmalloc does.
+
+2012-11-01 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tools/ppm2tiff.c: avoid zero size buffer vulnerability.
+ CVE-2012-4564 - Thanks to Huzaifa Sidhpurwala of the
+ Red Hat Security Response team for the fix.
+
+2012-10-18 Frank Warmerdam <warmerdam@google.com>
+
+ * tif_zip.c: Avoid crash on NULL error messages.
+
+2012-09-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff 4.0.3 released.
+
+2012-09-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am: Update to Automake 1.12.4
+
+2012-08-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.in: Update to Automake 1.12.3
+
+ * libtiff{tiff.h, tif_print.c, tif_dirinfo.c, tif_dirread.c}: Add
+ some TIFF/FX support in libtiff. Add the tag definitions to
+ tiff.h. Add the related TIFF field definitions to tif_dirinfo.c,
+ and also fixes an error in a comment. Adds the photometric values
+ to tif_print.c, and fixes a bug. These changes are by Steve
+ Underwood.
+
+2012-08-13 Frank Warmerdam <warmerdam@google.com>
+
+ * libtiff/tif_write.c: Fix bug rewriting image tiles in a
+ compressed file: http://trac.osgeo.org/gdal/ticket/4771
+
+2012-08-02 Frank Warmerdam <warmerdam@google.com>
+
+ * libtiff/tif_dirread.c: report error in case of mismatch value
+ counts for tags (ie. DotRange).
+
+2012-07-26 Tom Lane <tgl@sss.pgh.pa.us>
+
+ * libtiff/{tiffio.h, tif_dirinfo.c, libtiff.def}: Add six new
+ functions TIFFFieldTag(), TIFFFieldName(), TIFFFieldDataType(),
+ TIFFFieldPassCount(), TIFFFieldReadCount(), TIFFFieldWriteCount()
+ as external accessors for the opaque type TIFFField.
+
+ * tools/tiffset.c: Make tiffset use the above functions instead of
+ relying on library private headers.
+
+2012-07-19 Tom Lane <tgl@sss.pgh.pa.us>
+
+ * tools/tiff2pdf.c: Fix two places where t2p_error didn't get set
+ after a malloc failure. No crash risk AFAICS, but the program
+ might not report exit code 1 as desired. h/t mancha@mac.hush.com
+
+2012-07-18 Tom Lane <tgl@sss.pgh.pa.us>
+
+ * tools/tiff2pdf.c: Fail when TIFFSetDirectory() fails. This
+ prevents core dumps or perhaps even arbitrary code execution when
+ processing a corrupt input file (CVE-2012-3401).
+
+2012-07-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * test/raw_decode.c (main): Test fixes to work with IJG JPEG 7+.
+ IJG JPEG 7+ uses a different upsampling algorithm which produces
+ different numeric results.
+
+ * libtiff/tif_jpeg.c (JPEGPreDecode): Patch from Even Rouault to
+ work with IJG JPEG 7+.
+
+2012-07-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * test/raw_decode.c: Add changes so that test can run with build
+ directory outside of source directory.
+
+2012-07-02 Frank Warmerdam <warmerdam@google.com>
+
+ * libtiff/tif_jpeg.c: Fix handling when writing RGBA jpeg compressed
+ imagery (http://trac.osgeo.org/gdal/ticket/4732)
+
+2012-06-20 Frank Warmerdam <warmerdam@google.com>
+
+ * libtiff/tif_fax3.c: fix memory initialization of runs, only
+ partly done.
+
+ * libtiff/tif_pixarlog.c: Make sure tbuf is large enough for one
+ full "stride" past the end.
+
+2012-06-19 Frank Warmerdam <warmerdam@google.com>
+
+ * libtiff/tif_packbits.c: fix read past end of data buffer.
+
+2012-06-15 Frank Warmerdam <warmerdam@google.com>
+
+ * libtiff 4.0.2 released.
+
+ * tools/tif2pdf.c, tools/tifdump.c: avoid uninitialized variable
+ warnings with clang.
+
+2012-06-15 Tom Lane <tgl@sss.pgh.pa.us>
+
+ * tools/tiff2pdf.c: Defend against integer overflows while
+ calculating required buffer sizes (CVE-2012-2113).
+
+2012-06-12 Frank Warmerdam <warmerdam@google.com>
+
+ * libtiff/tif_print.c: Be careful about printing corrupt inknames.
+
+ * libtiff/tif_fax3.c: Ensure runs array is initialized to zeros.
+
+2012-06-07 Frank Warmerdam <warmerdam@google.com>
+
+ * libtiff/tif_print.c: avoid pretty printing other fields when
+ we don't have the proper amount and type of data or if the field
+ is actually autodefined.
+
+2012-06-05 Frank Warmerdam <warmerdam@google.com>
+
+ * libtiff/tif_tile.c, libtiff/tif_strip.c: Ensure that illegal
+ ycbcrsubsampling values result in a runtime error, not just an
+ assertion.
+
+ * tests/custom_dir.c: Add testing of EXIF and custom directory
+ reading and writing.
+
+ * libtiff/tif_dir.c, libtiff/tiffio.h: Add TIFFCreateCustomDirectory()
+ and TIFFCreateEXIFDirectory() functions.
+
+ * libtiff/tif_dir.c, tif_print.c : Remove FIELD_CUSTOM handling for
+ PAGENUMBER, HALFTONEHINTS, and YCBCRSUBSAMPLING. Implement DOTRANGE
+ differently. This is to avoid using special TIFFGetField/TIFFSetField
+ rules for these fields in non-image directories (like EXIF).
+
+2012-06-04 Frank Warmerdam <warmerdam@google.com>
+
+ * libtiff/tif_jpeg.c: Remove code for fixing up h_sampling and v_sampling
+ in JPEGPreDecode(). If a fixup will be done it needs to be done sooner
+ in JPEGFixupTagsSubsampling() or else buffer sized may be wrong.
+
+2012-06-01 Frank Warmerdam <warmerdam@google.com>
+
+ * tools/tiffinfo.c: Do not try to read image data in EXIF directories.
+
+ * libtiff/tif_getimage.c: added support for _SEPARATED CMYK images.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2379
+
+ * libtiff/tif_unix.c: use strerror() to return a more specific error message
+ on failed open.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2341
+
+ * libtiff/tif_jpeg.c: Fix JPEGDecodeRaw() bugs.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2386
+
+ * tests/decode_raw.c, tests/images/quad-tile.jpg.tiff: add limited support
+ for testing jpeg in tiff image decoding including the "raw" decode interface.
+
+2012-05-31 Frank Warmerdam <warmerdam@google.com>
+
+ * libtiff/tif_jpeg.c: avoid overrunning the end of the output buffer in
+ JPEGDecodeRaw() - mostly likely to occur when there is confusion about
+ sampling values.
+
+ * libtiff/tif_read.c: Make sure tif_rawdatasize is cleared when tif_rawdata is freed.
+
+ * libtiff/tif_getimage.c: Add support for greyscale+alpha c/o Jérémie Laval.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2398
+
+2012-05-29 Frank Warmerdam <warmerdam@google.com>
+
+ * libtiff/tif_dir.c: avoid using specific set/get logic to process fields in custom directories,
+ like EXIF directories. This fixes problems like a tag "320" existing in a custom directory getting
+ processed as if it were a colormap when it isn't really. Damn the wide variety of argument formulations
+ to get/set functions for different tags!
+
+ * libtiff/tif_dir.c: Ensure that we keep track of when tif_rawdata
+ is a pointer into an mmap()ed file via TIFF_BUFFERMMAP flag.
+
+2012-05-24 Frank Warmerdam <warmerdam@google.com>
+
+ * libtiff/tif_pixarlog.c: Allocate working buffer one word larger since we "forward
+ accumulate" and overwrite the end by one word in at least some cases.
+
+2012-05-23 Frank Warmerdam <warmerdam@google.com>
+
+ * libtiff/tif_pixarlog.c: avoid accessing out of the lookup arrays for out of range inputs.
+
+ * tools/tiffinfo.c: initialize h=0 to avoid undefined variable for degenerate files.
+
+ * libtiff/tif_ojpeg.c: if OJPEGWriteHeader() fails once do not bother trying again on
+ the same image.
+
+ * libtiff/tif_ojpeg.c: make things more resilient in the face of files without
+ stripbytecounts or stripoffsets or where loading these fails.
+
+ * libtiff/tif_print.c: be careful about whether min/max values are singular
+ or one per sample.
+
+ * libtiff/tif_print.c: Avoid confusion about count size when printing custom fields.
+ May affect things like ISOSpeedRatings.
+
+ * libtiff/tif_dir.c: avoid one byte past end of ink names reading
+ in some cases.
+
+2012-05-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * man/TIFFGetField.3tiff: Correct the 'count' field type in the
+ example for how to retrieve the value of unsupported tags.
+
+2012-03-30 Frank Warmerdam <warmerdam@google.com>
+
+ * tif_getimage.c: Fix size overflow (zdi-can-1221,CVE-2012-1173)
+ care of Tom Lane @ Red Hat.
+
+2012-02-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff 4.0.1 released.
+
+ * Update automake used to 1.11.3.
+
+ * libtiff/tiffio.h: Use double-underbar syntax in GCC printf
+ attribute specification to lessen the risk of accidental macro
+ substitution. Patch from Vincent Torri.
+
+2012-01-31 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dir.c, libtiff/tif_dirread.c: Extra caution around
+ assumption tag fetching is always successful.
+
+ * libtiff/tif_jpeg.c: Extra caution for case where sp is NULL.
+
+2012-01-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Add support for using library symbol versioning on
+ ELF systems with the GNU linker. Support is enabled via
+ --enable-ld-version-script. Disabled by default for now until
+ there is a decision for how to deploy a libtiff with versioned
+ symbols after libtiff 4.0.0 was already released.
+
+2011-12-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_win32.c: Eliminate some minor 64-bit warnings in
+
+ tif_win32.c. Patch by Edward Lam.
+
+ * configure.ac: Add libtiff private dependency on -llzma for
+ pkg-config. Patch by Mark Brand.
+ Updated Automake to 1.11.2.
+
+2011-12-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff 4.0.0 released.
+
+2011-12-08 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dirread.c, libtiff/tif_read.c: more cautious checking
+ of _TIFFFillStriles() results (#gdal 4372)
+
+2011-12-07 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dirread.c: fixes to deal with invalid files where
+ _TIFFFillStriles() fails, and we try to chop up strips (gdal #4372)
+
+ * libtiff/tif_dirread.c: fix error reporting when there is no
+ tag information struct and name (gdal #4373)
+
+2011-10-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Update GNU libtool to 2.4.2.
+
+ * tools/tiffsplit.c (tiffcp): TIFFGetField count field should be
+ uint32 type for TIFFTAG_JPEGTABLES. Patch by Christophe
+ Deroulers.
+
+2011-06-21 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/libtiff.def: Restore TIFFMergeFieldInfo.
+
+2011-05-31 Jim Meyering <meyering@redhat.com>
+
+ * libtiff/tif_dirread.c (TIFFFetchStripThing): Free "data" also
+ upon failure to allocate "resizeddata".
+ * tools/tiff2ps.c (PSDataBW): Zero buffer *after* checking for
+ allocation failure, not before.
+ * libtiff/tif_ojpeg.c: plug leaks on OJPEG read failure path
+ * tools/rgb2ycbcr.c (cvtRaster): unchecked malloc
+ * libtiff/tif_jpeg.c, tools/tiff2pdf.c, tools/tiff2ps.c: mark
+ NULL-deref and possible overflow
+ * tools/tiff2pdf.c: remove decl+set of set-but-not-used local, "written"
+ * libtiff/tif_jpeg.c (JPEGInitializeLibJPEG): Remove declaration
+ and set of otherwise unused local, data_is_empty.
+ * libtiff/tif_jpeg.c (JPEGDecodeRaw) [JPEG_LIB_MK1_OR_12BIT]:
+ Diagnose out-of-memory failure and return 0 rather than
+ dereferencing NULL.
+
+2011-05-24 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dirread.c: produce special error message for zero tag
+ directories instead of error out on the malloc(0) failure.
+
+2011-05-16 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dirinfo.c: Restore TIFFMergeFieldInfo() and
+ related declarations as they are in active use by libraries
+ such as libgeotiff, and work just fine. (#2315)
+
+2011-04-20 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dirinfo.c,tiffio.h: Remove the obsolete
+ TIFFMergeFieldInfo/TIFFFindFieldInfo/TIFFFindFieldInfoByName API.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2315
+
+ * libtiff/libtiff.def: add some missing (64bit) APIs.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2316
+
+2011-04-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff 4.0.0beta7 released.
+
+2011-04-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Should use AC_CANONICAL_HOST since host specifies
+ the run-time target whereas target is used to specify the final
+ output target if the package is a build tool (like a compiler),
+ which libtiff is not. Resolves libtiff bug 2307 "Use
+ AC_CANONICAL_HOST macro".
+
+2011-04-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Support configuring TIFF_INT64_FORMAT and
+ TIFF_UINT64_FORMAT appropriately for MinGW32.
+
+ * tools/tiffdump.c (ReadDirectory): MinGW32 needs to use WIN32
+ printf conventions for 64-bit types because it uses the WIN32 CRT.
+
+ * libtiff/{tif_dumpmode.c,tif_luv.c,tif_lzw.c,tif_print.c,
+ tif_read.c,tif_strip.c,tif_thunder.c}: MinGW32 needs to use WIN32
+ printf conventions for 64-bit types because it uses the WIN32 CRT.
+
+ * tools/tiff2pdf.c (t2p_write_pdf_string): Fix printf syntax not
+ understood by WIN32 CRT.
+
+ * libtiff/tif_ojpeg.c: Fixes to compile with MinGW32 GCC.
+
+ * tools/fax2ps.c (main): Use tmpfile() rather than mkstemp() since
+ it is much more portable. Tmpfile is included in ISO/IEC
+ 9899:1990 and the WIN32 CRT.
+
+2011-03-26 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tools/tiffset.c: add -d and -sd switches to allow operation on
+ a particular directory, not just the first (jef).
+
+2011-03-21 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_thunder.c: Correct potential buffer overflow with
+ thunder encoded files with wrong bitspersample set. The libtiff
+ development team would like to thank Marin Barbella and TippingPoint's
+ Zero Day Initiative for reporting this vulnerability (ZDI-CAN-1004,
+ CVE-2011-1167).
+ http://bugzilla.maptools.org/show_bug.cgi?id=2300
+
+2011-03-10 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_fax3.h: Fix to last change allowing zero length
+ runs at the start of a scanline - needed for legal cases.
+
+2011-03-02 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_fax3.h: Protect against a fax VL(n) codeword commanding
+ a move left. Without this, a malicious input file can generate an
+ indefinitely large series of runs without a0 ever reaching the right
+ margin, thus overrunning our buffer of run lengths. Per CVE-2011-0192.
+ This is a modified version of a patch proposed by Drew Yao of Apple
+ Product Security. It adds an unexpected() report, and disallows the
+ equality case, since emitting a run without increasing a0 still allows
+ buffer overrun.
+
+2011-02-23 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_jpeg.c: avoid divide by zero in degenerate case (#2296)
+
+ * tools/tiff2rgba.c: close source file on error to make leak
+ detection easier.
+
+ * libtiff/tif_getimage.c: avoid leaks if TIFFRGBAImageBegin() fails.
+
+ http://bugzilla.maptools.org/show_bug.cgi?id=2295
+
+2011-02-22 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_lzma.c: Maintain tif_rawcc/tif_rawcp (CHUNKY_STRING_READ
+ _SUPPORT)
+
+2011-02-18 Frank Warmerdam <warmerdam@pobox.com>
+
+ * configure.ac, configure: Added support for --enable-chunky-strip-read
+ configure option to enable the experimental feature from a couple
+ months ago for reading big strips in chunks.
+
+ * configure.ac, tif_read.c, tif_readdir.c, tif_dir.h, tiffiop.h,
+ tif_write.c, tif_print.c, tif_jpeg.c, tif_dirwrite.c, tif_write.c:
+ Implement optional support for deferring the load of strip/tile
+ offset and size tags for optimized scanning of directories. Enabled
+ with the --enable-defer-strile-load configure option (DEFER_STRILE_LOAD
+ #define in tif_config.h).
+
+2011-02-11 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_print.c: remove unused variable.
+
+2011-02-09 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_win32.c: avoid error/warning buffer overrun problem
+ with non-console (popup message) builds on win32.
+
+ http://bugzilla.maptools.org/show_bug.cgi?id=2293
+
+2011-01-24 Olivier Paquet <olivier.paquet@gmail.com>
+
+ * libtiff/{tif_dir.{h,c}, tif_dirinfo.c, tif_dirread.c, tif_dirwrite.c,
+ tif_print.c, tiff.h, tiffiop.h} : Added support for
+ TIFFTAG_SMINSAMPLEVALUE and TIFFTAG_SMAXSAMPLEVALUE to have different
+ values for each sample. Presents the min/max of all samples by default for
+ compatibility. TIFFSetField/TIFFGetField can be made to handle those tags
+ as arrays by changing the new TIFFTAG_PERSAMPLE pseudo tag.
+ http://www.asmail.be/msg0055458208.html
+
+2011-01-06 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_pixarlog.c: Note that tif_rawcc/tif_rawcp are not
+ maintained.
+
+ * libtiff/tif_zip.c: Maintain tif_rawcc/tif_rawcp when decoding
+ for CHUNKY_STRIP_READ_SUPPORT.
+
+ * libtiff/tif_jpeg.c: ensure that rawcc and rawcp are maintained
+ during JPEGPreDecode and JPEGDecode calls.
+ * libtiff/tif_read.c: larger read ahead for CHUNKY_STRIP_READ_SUPPORT,
+ as compression formats like JPEG keep 16 lines interleaved in a sense
+ and might need to touch quite a bit of data.
+
+ http://trac.osgeo.org/gdal/ticket/3894
+
+2011-01-03 Lee Howard <faxguy@howardsilvan.com>
+
+ * libtiff/tif_jpeg.c: Fix regressions with 2 and 3 band images
+ caused by commit on 2010-12-14. Submitted by e-mail from
+ Even Rouault <even.rouault@mines-paris.org>
+
+2010-12-31 Olivier Paquet <olivier.paquet@gmail.com>
+
+ * libtiff/tif_dirwrite.c: Fixed writing of TIFFTAG_REFERENCEBLACKWHITE.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2266
+
+2010-12-23 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffcp.c, man/tiffcp.1: Added support for specifying the
+ compression level parameter (preset) for Deflate and LZMA encoders,
+ e.g "-c lzma:p1" or "-c zip:p9".
+
+ * libtiff/tif_lzma.c: Properly set the LZMA2 compression level
+ (preset) in LZMAVSetField().
+
+2010-12-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/Makefile.am (libtiff_la_SOURCES): Added tif_lzma.c to
+ Makefile.
+
+2010-12-14 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * configure.ac, libtiff/{tif_codec.c, tif_config.h.in, tiff.h,
+ tiffiop.h, tif_lzma.c}, tools/tiffcp.c, man/tiffcp.1: Implement a new
+ TIFF compression scheme LZMA reserving a new value 34925 for
+ Compression tag. As per
+ bug http://bugzilla.maptools.org/show_bug.cgi?id=2221
+
+2010-12-14 Lee Howard <faxguy@howardsilvan.com>
+
+ * libtiff/tif_dirread.c: tolerate some cases where
+ FIELD_COLORMAP is missing
+ http://bugzilla.maptools.org/show_bug.cgi?id=2189
+
+2010-12-14 Lee Howard <faxguy@howardsilvan.com>
+
+ * libtiff/tif_read.c: change read_ahead to tmsize_t
+ http://bugzilla.maptools.org/show_bug.cgi?id=2222
+
+2010-12-14 Lee Howard <faxguy@howardsilvan.com>
+
+ * configure.ac, libtiff/Makefile.am: Build tif_win32.c on
+ Windows except on Cygwin
+ http://bugzilla.maptools.org/show_bug.cgi?id=2224
+
+2010-12-14 Lee Howard <faxguy@howardsilvan.com>
+
+ * tools/gif2tiff.c: fix buffer overrun
+ http://bugzilla.maptools.org/show_bug.cgi?id=2270
+
+2010-12-14 Lee Howard <faxguy@howardsilvan.com>
+
+ * libtiff/tif_jpeg.c: reduce usage of JCS_UNKNOWN in order
+ to improve compatibility with various viewers
+ submitted by e-mail from Dwight Kelly <dkelly@apago.com>
+
+2010-12-13 Lee Howard <faxguy@howardsilvan.com>
+
+ * tools/fax2ps.c: be consistent with page-numbering
+ http://bugzilla.maptools.org/show_bug.cgi?id=2225
+
+2010-12-13 Lee Howard <faxguy@howardsilvan.com>
+
+ * libtiff/tif_color.c: prevent crash in handling bad TIFFs
+ resolves CVE-2010-2595
+ http://bugzilla.maptools.org/show_bug.cgi?id=2208
+
+2010-12-13 Lee Howard <faxguy@howardsilvan.com>
+
+ * tools/tiffcrop.c: new release by Richard Nolde
+ http://bugzilla.maptools.org/show_bug.cgi?id=2004
+
+2010-12-12 Lee Howard <faxguy@howardsilvan.com>
+
+ * tools/tiff2pdf.c: fix colors for images with RGBA
+ interleaved data
+ http://bugzilla.maptools.org/show_bug.cgi?id=2250
+
+2010-12-12 Lee Howard <faxguy@howardsilvan.com>
+
+ * libtiff/tif_dirread.c: fix for Zeiss LSM and Canon CR2 files
+ http://bugzilla.maptools.org/show_bug.cgi?id=2164
+
+2010-12-11 Lee Howard <faxguy@howardsilvan.com>
+
+ * tools/tiff2pdf.c: remove invalid duplication for Lab
+ http://bugzilla.maptools.org/show_bug.cgi?id=2162
+
+2010-12-11 Lee Howard <faxguy@howardsilvan.com>
+
+ * libtiff/tif_jpeg.c: fix use of clumplines calculation
+ http://bugzilla.maptools.org/show_bug.cgi?id=2149
+
+2010-12-11 Lee Howard <faxguy@howardsilvan.com>
+
+ * tools/fax2ps.c: replace unsafe tmpfile() with mkstemp()
+ http://bugzilla.maptools.org/show_bug.cgi?id=2118
+
+2010-12-11 Lee Howard <faxguy@howardsilvan.com>
+
+ * libtiff/tif_ojpeg.c, libtiff/tif_pixarlog.c,
+ libtiff/tif_zip.c: fix build errors for VC6
+ http://bugzilla.maptools.org/show_bug.cgi?id=2105
+
+2010-12-11 Lee Howard <faxguy@howardsilvan.com>
+
+ * libtiff/tif_stream.cxx: warnings cleanup
+ http://bugzilla.maptools.org/show_bug.cgi?id=2091
+ * libtiff/tif_dirread.c: warnings cleanup
+ http://bugzilla.maptools.org/show_bug.cgi?id=2092
+
+2010-12-11 Lee Howard <faxguy@howardsilvan.com>
+
+ * tools/tiff2pdf.c: add fill-page option
+ http://bugzilla.maptools.org/show_bug.cgi?id=2051
+
+2010-12-11 Lee Howard <faxguy@howardsilvan.com>
+
+ * libtiff/tif_dirread.c: modify warnings
+ http://bugzilla.maptools.org/show_bug.cgi?id=2016
+
+2010-12-11 Lee Howard <faxguy@howardsilvan.com>
+
+ * libtiff/tif_ojpeg.c: fix buffer overflow on problem data
+ http://bugzilla.maptools.org/show_bug.cgi?id=1999
+
+2010-12-11 Lee Howard <faxguy@howardsilvan.com>
+
+ * tools/tiffinfoce.c: strip byte counts are uint64* now
+
+2010-12-11 Lee Howard <faxguy@howardsilvan.com>
+
+ * libtiff/tif_ojpeg.c: fix crash when reading a TIFF with a zero
+ or missing byte-count tag
+ * tools/tiffsplit.c: abort when reading a TIFF without a byte-count
+ per http://bugzilla.maptools.org/show_bug.cgi?id=1996
+
+2010-12-08 Lee Howard <faxguy@howardsilvan.com>
+
+ * libtiff/tif_dirread.c: fix crash when reading a badly-constructed
+ TIFF per http://bugzilla.maptools.org/show_bug.cgi?id=1994
+
+2010-12-06 Lee Howard <faxguy@howardsilvan.com>
+
+ * libtiff/tif_open.c: Fix mode check before opening a file.
+ http://bugzilla.maptools.org/show_bug.cgi?id=1906
+
+2010-11-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff-4.pc.in: Added libtiff pkg-config .pc file support.
+ Patch by Vincent Torri.
+
+2010-10-21 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tools/tiffinfo.c: avoid direct reference to _TIFFerrorHandler.
+
+ * libtiff/tif_config.vc.h: define snprintf to _snprintf for tiff2pdf.
+
+ * libtiff/libtiff.def: export _TIFFCheckMalloc for tools.
+
+2010-09-25 Lee Howard <faxguy@howardsilvan.com>
+
+ * tools/tiff2ps.c: improvements and enhancements from Richard Nolde
+ with additional command line options for Document Title,
+ Document Creator, and Page Orientation
+
+2010-07-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/tiffcrop.c: Patch from Richard Nolde to avoid a
+ potentially unterminated buffer due to using an exceptionally long
+ file name.
+
+2010-07-08 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiff2pdf.c: Fixed ID buffer filling in
+ t2p_write_pdf_trailer(), thanks to Dmitry V. Levin.
+
+2010-07-07 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dirread.c: Really reset the tag count in CheckDirCount()
+ to expected value as the warning message suggests. As per bug
+ http://bugzilla.maptools.org/show_bug.cgi?id=1963
+
+2010-07-06 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffset.c: Properly handle TIFFTAG_PAGENUMBER,
+ TIFFTAG_HALFTONEHINTS, TIFFTAG_YCBCRSUBSAMPLING, TIFFTAG_DOTRANGE
+ which should be set by value.
+
+ * libtiff/tif_dirinfo.c: Don't use assertions in _TIFFFieldWithTag()
+ and _TIFFFieldWithName() if the tag is not found in the tag table.
+ This should be normal situation and returned NULL value should be
+ properly handled by the caller.
+
+2010-07-02 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_getimage.c: Avoid wrong math du to the signed/unsigned
+ integer type conversions. As per bug
+ http://bugzilla.maptools.org/show_bug.cgi?id=2207
+
+ * tools/{tiff2bw.c, thumbnail.c, pal2rgb.c}: Fix the count for
+ WhitePoint tag as per bug
+ http://bugzilla.maptools.org/show_bug.cgi?id=2042
+
+ * libtiff/tif_getimage.c: Check the number of samples per pixel when
+ working with YCbCr image in PickContigCase(). As per bug
+ http://bugzilla.maptools.org/show_bug.cgi?id=2216
+
+ * libtiff/tif_dir.c: Set the bogus post-decoding hook when processing
+ TIFFTAG_BITSPERSAMPLE in _TIFFVSetField() for the case of 8 bit when
+ we don't need any post-processing. That helps to reset the hook if we
+ previously set this field to some other value and the hook was
+ initialized accordingly. As per bug
+ http://bugzilla.maptools.org/show_bug.cgi?id=2035
+
+2010-07-01 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffgt.c: Properly check the raster buffer allocations for
+ integer overflows. As per bug
+ http://bugzilla.maptools.org/show_bug.cgi?id=2108
+
+ * m4/acinclude.m4: Update GL/GLU/GLUt/Pthread macros from the
+ upstream.
+
+ * libtiff/{tif_aux.c, tif_strip.c, tif_tile.c, tiffiop.h}: Move
+ multiply_32() and multiply_64() functions into tif_aux.c file and
+ rename them into _TIFFMultiply32() and _TIFFMultiply64() respectively.
+
+2010-06-30 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiff2pdf.c: Better generation of ID field in
+ t2p_write_pdf_trailer(). Get rid of GCC aliasing warnings.
+
+ * tools/tiff2pdf.c: Fixed computation of the tile buffer size when
+ converting JPEG encoded tiles.
+
+ * tools/tiff2pdf.c: Better handling of string fields, use static
+ string buffers instead of dynamically allocated, use strncpy() instead
+ of strcpy(), control the string lengths.
+
+2010-06-25 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffcp.c: Initialize buffer arrays with zero to avoid
+ referencing to uninitialized memory in some cases (e.g. when tile size
+ set bigger than the image size).
+
+2010-06-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/tiffcrop.c: Patch from Richard Nolde. Reject YCbCr
+ subsampled data since tiffcrop currently doesn't support it. Fix
+ JPEG support.
+
+2010-06-13 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dirinfo.c: Fix invocation of tag compare function (#2201)
+
+ * tools/tiff2pdf.c: Fix assorted bugs in tiff2pdf: missing "return"
+ in t2p_read_tiff_size() causes t2p->tiff_datasize to be set entirely
+ wrong for COMPRESSION_JPEG case, resulting in memory stomp if actual
+ size is larger. Also, there are a bunch of places that try to
+ memset() a malloc'd buffer before checking for malloc failure, which
+ would result in core dump if there actually were a failure. (#2211)
+
+2010-06-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tiffiop.h (TIFFSafeMultiply): Need more castings to
+ avoid compiler warnings if parameter types are not sign
+ consistent.
+
+ * libtiff 4.0.0alpha6 released.
+
+ * tools/tiffcrop.c: Applied patch from Richard Nolde: Corrected
+ European page size dimensions. Added an option to allow the user
+ to specify a custom page size on the command line. Fix the case
+ where a page size specified with a fractional part was being
+ coerced to an integer by retyping the variables that define the
+ paper size.
+
+ * html/index.html: Update for the 3.9.3 release.
+
+ * tools/tiffcp.c (tiffcp): Applied Tom Lane's patch to reject
+ YCbCr subsampled data since tiffcp currently doesn't support it.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2097
+
+ * Update libtool to version 2.2.10.
+
+2010-06-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tiffiop.h (TIFFSafeMultiply): Work properly if
+ multiplier is zero.
+
+2010-06-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_fax3.c (Fax3SetupState): Yesterday's fix for
+ CVE-2010-1411 was not complete.
+
+ * libtiff/tiffiop.h (TIFFSafeMultiply): New macro to safely
+ multiply two integers. Returns zero if there is an integer
+ overflow.
+
+ * tools/tiffcp.c (main): tiffcp should not leak memory if an error
+ is reported when reading the input file.
+
+2010-06-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Update libtool to version 2.2.8.
+
+ * libtiff/tif_fax3.c (Fax3SetupState): Avoid under-allocation of
+ buffer due to integer overflow in TIFFroundup() and several other
+ potential overflows. In conjunction with the fix to TIFFhowmany(),
+ fixes CVE-2010-1411.
+
+ * libtiff/tiffiop.h (TIFFhowmany): Return zero if parameters would
+ result in an integer overflow. This causes TIFFroundup() to also
+ return zero if there would be an integer overflow.
+
+ * contrib: Add an emacs formatting mode footer to all source files
+ so that emacs can be effectively used.
+
+2010-06-03 Oliver Chen Feng <scip8183@gmail.com>
+
+ * libtiff/tools/tiffcp.c: add a new option -x to force merged tiff
+ file PAGENUMBER value in sequence for users who care the page
+ sequence, this will also prevent tiff2pdf from creating pdf file from
+ the merged tiff file with wrong page sequence.
+
+2010-05-08 Olivier Paquet <olivier.paquet@gmail.com>
+
+ * libtiff/tif_dirread.c: Restored TIFFReadDirEntryFloat function in order
+ to add missing TIFF_SETGET_FLOAT case to TIFFFetchNormalTag.
+ * libtiff/tif_dirinfo.c: Use correct set_field_type for
+ TIFFTAG_PIXAR_FOVCOT so it is readable again (regression from 3.9.2).
+ http://bugzilla.maptools.org/show_bug.cgi?id=2192
+
+2010-05-07 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_jpeg.c: Ensure that quality is always set in
+ JPEGPreEncode(), not just when we want to output local tables.
+ Otherwise the quality used during compression may not be right and
+ might not match the tables in the tables tag. This bug only occurs
+ when seeking between directories in the midst of writing blocks.
+ http://trac.osgeo.org/gdal/ticket/3539
+
+2010-05-06 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * html/man/TIFFGetField.3tiff.html, html/man/TIFFSetField.3tiff.html:
+ Regenerated from the source.
+
+2010-05-05 Olivier Paquet <olivier.paquet@gmail.com>
+
+ * libtiff/tif_print.c: Fixed printing of TIFFTAG_REFERENCEBLACKWHITE which
+ had stopped working. Also made it always print 6 floats instead of
+ 2*SamplesPerPixel.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2191
+ http://bugzilla.maptools.org/show_bug.cgi?id=2186
+ * man/TIFFGetField.3tiff, man/TIFFSetField.3tiff: Fixed doc to reflect the
+ fact that libtiff considers TIFFTAG_REFERENCEBLACKWHITE to be 6 floats.
+
+2010-05-05 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_jpeg.c: Fix to use memcmp(), not memcpy() when checking
+ if the jpeg table was written. This is a fix for the last fix on 04-21.
+
+2010-04-21 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_jpeg.c: avoid preparing jpeg tables every time
+ JPEGSetupEncode() is called if the tables already seem to be
+ established. This prevents spurious updates and rewriting of
+ directories with jpegtables when doing updates to existing images.
+ http://trac.osgeo.org/gdal/ticket/3539
+
+2010-04-20 Olivier Paquet <olivier.paquet@gmail.com>
+
+ * libtiff/tif_dirinfo.c: Use correct set_field_type for
+ TIFFTAG_PIXAR_IMAGEFULLWIDTH, TIFFTAG_PIXAR_IMAGEFULLLENGTH,
+ TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN and TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA.
+ They were unreadable with TIFF_SETGET_UNDEFINED, a regression from 3.9.2.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2139
+
+2010-04-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_dir.c (_TIFFVSetField): Add a special error case for
+ when the tag count value is zero. Error handling is still a
+ regression since in 3.9.2, empty tags are skipped (with a warning)
+ rather than returning a hard error and refusing to read the file.
+
+ * tools/ppm2tiff.c (main): While case for parsing comment line
+ requires extra parenthesis to work as expected. Reported by
+ Thomas Sinclair.
+
+2010-04-02 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_read.c (primarily): Add support for
+ CHUNKY_STRIP_READ_SUPPORT where large strips are
+ read in chunks for applications using TIFFReadScanline().
+ This is intended to make it more practical work with very
+ large compressed one-strip files. Feature is off by default.
+ Enable by defining CHUNK_STRIP_READ_SUPPORT as a macro.
+ http://trac.osgeo.org/gdal/ticket/3514
+
+2010-03-31 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_flush.c: Use TIFFRewriteDirectory() when flushing
+ directories so previously placed directories will be migrated to
+ the end of file if needed.
+
+2010-03-30 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_lzw.c: change type of dec_bitsleft field to uint64
+ to support operating on strips/tiles of more than 256MB.
+ http://trac.osgeo.org/gdal/ticket/3512
+
+2010-03-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_aux.c (_TIFFCheckRealloc): Improve error message so
+ that it is clearly a memory allocation error message, and also
+ includes the size of the allocation request.
+
+2010-02-22 Lee Howard <faxguy@howardsilvan.com>
+
+ * libtiff/tif_jpeg.c: Do not generate a JPEGTables tag when creating
+ the JPEG TIFF as is is not required in order to prevent it from
+ being unused and filled with invalid data. (Leave it to be
+ generated by later activity.)
+ http://bugzilla.maptools.org/show_bug.cgi?id=2135
+ * tools/tiff2pdf.c: Write the JPEG SOI headers into the TIFF strip
+ data rather than skipping them. This fixes the ability to view in
+ Acrobat Reader, Evince, and Ghostscript.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2135
+ * libtiff/tif_fax3.c: Don't return error on badly-terminated MMR
+ strips.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2029
+
+2009-12-03 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_jpeg.c: Made JPEGDecodeRaw() check for buffer overruns.
+ Made so that when working with downsampled images a stub function
+ reporting an error is used for tif_decoderow. We cannot meaningfully
+ support reading scanlines in this situation. (#1936)
+
+ * libtiff/tif_jpeg.c: Ensure that tif_scanlinesize is computed after
+ resetting of the upsampling values (gdal:#3259).
+ http://bugzilla.maptools.org/show_bug.cgi?id=1936
+
+2009-11-30 Frank Warmerdam <warmerdam@pobox.com>
+
+ * contrib/dbs/tiff-grayscale.c, contrib/tif-palette.c,
+ tools/ras2tiff.c: Fix resource leaks on error.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2121
+
+ * libtiff/tif_{aux.c,dir.c,dir.h,dirinfo.c}: Return to handling
+ TIFFTAG_REFERENCEBLACKWHITE as a field in the TIFF directory instead
+ of as a custom(generic) field to avoid a potential reentrancy problem.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2125
+
+ * libtiff/tif_color.c, libtiff/tif_getimage.c, libtiff/tiffio.h,
+ man/TIFFcolor.3tiff: Make TIFFDisplay argument in TIFFCIELabToRGBInit
+ const, and display_sRGB static and const.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2124
+
+2009-11-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff 4.0.0alpha5 released.
+
+2009-11-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/tiffcrop.c: Updated tiffcrop from Richard Nolde. This
+ version has undergone substantial testing with arbitrary sample
+ bit depths. Also eliminates GCC compilation warnings.
+
+2009-11-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * port/libport.h: Add extern declarations for getopt standard
+ globals.
+
+2009-10-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_lzw.c (LZWDecode, LZWDecodeCompat): Fix warnings
+ noticed in 64-bit build of libtiff with Visual Studio 2005.
+ Resolves "Bug 2067 - Visual Studio 2005 64-bit warnings in
+ tif_lzw.c", http://bugzilla.maptools.org/show_bug.cgi?id=2067
+
+ * libtiff/tif_pixarlog.c (PixarLogEncode): Fix non-important
+ warning noticed in Visual Studio 2005 build. Resolves "Bug 2068 -
+ Visual Studio 2005 64-bit warning in tif_pixarlog.c",
+ http://bugzilla.maptools.org/show_bug.cgi?id=2068
+
+2009-10-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_dirread.c: Eliminate GCC "dereferencing type-punned
+ pointer" warnings.
+
+2009-10-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * html/tools.html: Add manual page links, and a summary
+ description of tiffcrop.
+
+2009-10-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: x86_64 should use the same fill order as i386.
+
+2009-09-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/tiffcrop.c, man/tiffcrop.1: New tiffcrop from Richard
+ Nolde. Major updates to add significant functionality for reading
+ and writing tile based images with bit depths not a multiple of 8
+ which cannot be handled by tiffcp.
+
+2009-09-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_ojpeg.c (OJPEGWriteHeaderInfo): IJG JPEG 7 needs
+ do_fancy_upsampling=FALSE in order to read raw data. Resolves
+ "Bug 2090 - OJPEG crash with libjpeg v7".
+ http://bugzilla.maptools.org/show_bug.cgi?id=2090
+
+2009-09-03 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_getimage.c: Fixed error recognition handling in RGBA
+ interface when stoponerror is set.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2071
+
+2009-08-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/{tiffcrop.c,tiffgt.c}: Applied patch from Oden Eriksson to
+ fix build with gcc when using the "-Wformat
+ -Werror=format-security" flags.
+
+2009-08-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * test/{bmp2tiff_palette.sh, bmp2tiff_rgb.sh, gif2tiff.sh,
+ ppm2tiff_pbm.sh, ppm2tiff_pgm.sh, ppm2tiff_ppm.sh}: Additional
+ utilities tests.
+
+2009-08-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/tiffinfo.c: tiffinfo should return error status to the
+ caller. Register a private error callback to accomplish that.
+
+ * test/Makefile.am (TIFFIMAGES): Add test images in BMP, GIF, and
+ PNM formats so that we will be able to test more of the tools.
+ While adding these test images I notice that bmp2tiff and gif2tiff
+ only support ancient versions of their respective formats.
+
+2009-08-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff 4.0.0alpha4 released.
+
+ * HOWTO-RELEASE: Improved release instructions.
+
+2009-08-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * man/{TIFFClose.3tiff,raw2tiff.1,tiffcmp.1,tiffsplit.1}: Applied
+ fixes for "Bug 2023 - nroff errors in manual pages".
+ http://bugzilla.maptools.org/show_bug.cgi?id=2023
+
+ * tools/{rgb2ycbcr.c, tiff2rgba.c}: Applied fixes for "Bug 2079 -
+ CVE-2009-2347 libtiff: integer overflows in various inter-color
+ space conversion tools".
+ http://bugzilla.maptools.org/show_bug.cgi?id=2079
+
+ * libtiff/tif_print.c (TIFFPrintDirectory): Apply fix from Jay
+ Berkenbilt for "Bug 2024 - possible null pointer dereference with
+ one-line fix".
+ http://bugzilla.maptools.org/show_bug.cgi?id=2024
+
+ * libtiff/tif_dirread.c (TIFFReadCustomDirectory): Apply patch
+ from Jay Berkenbilt for "Bug 1895 - logic error in tif_dirread.c:
+ segfault after setting tdir_tag = IGNORE".
+ http://bugzilla.maptools.org/show_bug.cgi?id=1895
+
+2009-08-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * test/Makefile.am, test/tiffcrop*.sh: Split previously existing
+ tiffcrop.sh into a collection of many specific tests. Re-wrote
+ all of the existing tests to be based on some simple shell
+ functions. Make distcheck works again.
+
+ Export certain variables (MAKE, MAKEFLAGS, MEMCHECK) to tests and
+ added 'memcheck' and 'ptrcheck' targets to make it easy to run the
+ tests under valgrind.
+
+2009-08-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * test/tiffcp-logluv.sh: Fix test so that it works with a VPATH
+ build.
+
+ * test/Makefile.am (AUTOMAKE_OPTIONS): Colorized tests was not
+ actually activated since it needed to be enabled in this
+ Makefile.am. Also activated parallel-tests mode since it offers
+ useful features such as per-test .log files and a summary test
+ report .log file.
+
+2009-08-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Updated autotools. Autoconf 2.64, Automake 1.11,
+ libtool 2.2.6. Enabled support for silent build rules
+ (--enable-silent-rules or 'make V=0') and colorized tests.
+
+ * html/{index.html, v3.9.0.html}: Update for 3.9.0 release.
+
+2009-06-30 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tests/tiffcp-logluv.sh: minimal testing of sgilog compression.
+
+ * tools/tiffcp.c: add -c sgilog support.
+
+ * libtiff/tif_luv.c: correct return codes from encoderow to be
+ 1 on success instead of zero.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2069
+
+ * libtiff/tif_lzw.c: back out patch from #2065 and apply patch from
+ #1085 for a better underflow fix that errors properly.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2065
+ http://bugzilla.maptools.org/show_bug.cgi?id=1985
+
+2009-06-26 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_strip.c: Remove an inappropriate assertion that often
+ fails on oddly sized 12bit jpeg compressed ycbcr images.
+
+2009-06-22 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_lzw.c: Fix buffer underflow bug.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2065
+
+2009-06-21 Frank Warmerdam <warmerdam@pobox.com>
+
+ * configure.ac, libtiff/tif_jpeg.c, libtiff/tif_jpeg_12.c: add support
+ for dual mode 8/12 bit jpeg support.
+
+2009-06-03 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_write.c: do not override the planar configuration to be
+ contig for one sample files if planar configuration is already set.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2057
+
+2009-06-02 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/libtiff.def: Add TIFFUnsetField.
+
+2009-05-03 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/{tif_jpeg.c,tif_ojpeg.c,tif_getimage.c}: Fixed various
+ error reports to use "%s" as format string.
+ http://trac.osgeo.org/gdal/ticket/2976
+
+2009-03-12 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/{tif_fax3.c,tif_jpeg.c,tif_ojpeg.c}: Fix printdir chaining
+ for some codecs (#2020).
+
+2009-02-12 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_luv.c: Fix handling of tiled logluv images.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2005
+
+2009-02-09 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dirread.c: Improve allocation safety when allocated
+ buffer for large tags. (#1998) Related to (#1993)
+
+2009-02-06 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tools/tiffcrop.c: Don't default image->res_unit to INCH. Now the
+ test suite should pass.
+
+2009-02-05 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dirread.c: Re-incorporated a sanity check on tag size,
+ but at the 2GB boundary to avoid overflow on 32bit systems.
+ http://bugzilla.maptools.org/show_bug.cgi?id=1993
+
+ * libtiff/tif_dirread.c: Remove some assertions that blow due to
+ corrupt files rather than in response to library internal
+ inconsistencies.
+ http://bugzilla.maptools.org/show_bug.cgi?id=1995
+ http://bugzilla.maptools.org/show_bug.cgi?id=1991
+
+ * libtiff/tif_dirread.c: Fixed testing for failed result from
+ TIFFReadDirectoryFindFieldInfo().
+ http://bugzilla.maptools.org/show_bug.cgi?id=1992
+
+2009-01-23 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_predict.c: Add support for 32bit integer horz. predictors.
+ http://bugzilla.maptools.org/show_bug.cgi?id=1911
+
+ * libtiff/tif_dirwrite.c: Fix byte swapping of next directory offset.
+
+ http://bugzilla.maptools.org/show_bug.cgi?id=1924
+
+ * tools/tiffcrop.c: initialize xres/yres values.
+
+ * test/*.sh - default ${srcdir} to local directory.
+
+ * test/common.sh - start verbose mode after common settings.
+
+ * libtiff/tif_dirinfo.c: Replace lfind() with local equivalent to
+ avoid type mismatches on different platforms.
+ http://bugzilla.maptools.org/show_bug.cgi?id=1889
+
+2009-01-22 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tools/{fax2tiff.c,thumbnail.c,tiff2pdf.c,tiff2ps.c,tiffdump.c,
+ tiffsplit.c}: avoid warnings, mostly 32bit/64bit casting issues.
+
+ * port,tools: Introduce libport.h, and include in tools if NEED_LIBPORT
+ defined, primarily to reduce prototype warnings on windows.
+
+ * libtiff/tif_dirinfo.c,tif_dirread.c: Avoid warnings
+ about unused parameters, and uninitialized variables.
+
+2009-01-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * test/common.sh: Execute tests like 'make VERBOSE=TRUE check' in
+ order to trace full execution detail while executing the test suite.
+
+2009-01-20 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tools/tiffsplit.c: fix sampleformat to be shortv instead of longv.
+
+2009-01-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * test/Makefile.am (CLEANFILES): Make sure that test output files
+ are removed by 'make clean'
+
+ * Update autotools for 4.0.0 beta3
+
+ * 4.0.0 beta3 produced.
+
+2009-01-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * test/tiffcrop.sh: New test script for tiffcrop from Richard
+ Nolde.
+
+ * tools/tiff2ps.c: Remove spurious message to stderr.
+
+2009-01-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/tiff2ps.c: Incorporated significant functionality update
+ from Richard Nolde. In particular, support for rotating the image
+ by 90, 180, 270, and 'auto' has been added.
+
+ * man/tiffcrop.1: Incorporated documentation updates from Richard
+ Nolde.
+
+ * tools/tiffcrop.c: Incorporated significant functionality update
+ from Richard Nolde.
+
+2008-12-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tiffio.h: GCC will now validate format specifications
+ for TIFFError(), TIFFErrorExt(), TIFFWarning(), and
+ TIFFWarningExt() in order to reveal bugs.
+
+ * Many fixes throughout to work better as a 64-bit build.
+
+2008-12-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/{tiff2pdf.c, tiff2ps.c, tiffinfo.c}: Offset and length
+ tags now require 64-bit parameter rather than 32-bit.
+
+ * libtiff/tif_dirread.c: Fixed issues with unaligned access to
+ 64-bit values.
+
+ * tools/thumbnail.c: Eliminate crash noticed while running test
+ suite.
+
+2008-12-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_ojpeg.c (OJPEGLibjpegJpegSourceMgrFillInputBuffer):
+ Initialize stack variables to avoid compiler warning.
+
+ * tools/tiffinfoce.c (main): Use toff_t for offset type when
+ retrieving offset of EXIF IFD.
+
+ * libtiff/tiffio.h: Undeprecate toff_t and restore its use in the
+ TIFFClientOpen() callback and other external function definitions.
+
+ * tools/tiffinfo.c (main): Offset to EXIF IFD requires a 64-bit
+ type now. Fixes crash when dumping files containing an EXIF IFD.
+
+ * m4/libtool.m4: Update to libtool 2.2.6.
+
+2008-12-21 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dir.c, tiffio.h: Introduce TIFFUnsetField() function.
+
+ * libtiff/tif_jpeg.c: Avoid errors if the application writes a full
+ strip for the last partial strip in a jpeg compressed file.
+ http://bugzilla.maptools.org/show_bug.cgi?id=1981
+
+2008-10-29 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_flush.c: Make sure that BEENWRITING is cleared when
+ we take the shortcut to only update the strip/tile offsets in place.
+ http://trac.osgeo.org/gdal/ticket/2621
+
+2008-10-21 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_jbig.c: Support the JBIG-KIT 2.0 (compatibility with
+ the older versions retained).
+
+2008-10-09 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_jpeg.c: Add #ifdefs for changes needed if using
+ IPP enabled version of libjpeg from Intel.
+ http://bugzilla.maptools.org/show_bug.cgi?id=1951
+
+2008-09-05 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffsplit.c: Use byte counts of proper size (uint64).
+ Required for libtiff 4.0.
+
+ * tools/tiffsplit.c: Use dynamically allocated array instead of static
+ when constructing output file names.
+
+2008-09-03 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffsplit.c: Get rid of unsafe strcpy()/strcat() calls when
+ doing the filename/path construction.
+
+ * tools/tiff2pdf.c: More appropriate format string in
+ t2p_write_pdf_string(); avoid signed/unsigned mismatch.
+
+ * libtiff/tif_lzw.c: Properly zero out the codetable. As per bug
+
+ http://bugzilla.maptools.org/show_bug.cgi?id=1929
+
+ * libtiff/tif_lzw.c: Properly zero out the string table. Fixes
+ CVE-2008-2327 security issue.
+
+2008-09-01 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dirread.c: Avoid unused TIFFReadDirEntryFloat() function.
+
+ * libtiff/tif_dirwrite.c: modified to write IFDs as either IFD8 or IFD
+ depending on whether the file is bigtiff or classic tiff.
+ http://bugzilla.maptools.org/show_bug.cgi?id=1917
+
+2008-08-12 Edward Lam <edward@sidefx.com>
+
+ * tools/tiffdump.c: When compiling for Microsoft Windows, apply
+ consistent (__int64) casting when testing if _lseeki64 has
+ successfully sought as requested. This is necessary for large
+ file support to work since off_t is only 32-bit.
+
+2008-07-29 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tif_strip.c: Replace assertions related to samplesperpixel != 3 or
+ the subsampling values not being 1, 2 or 4 (for jpeg compressed images)
+ with control logic to return runtime errors (c/o Even Rouault) (#1927).
+
+2008-06-17 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tools/tiffcrop.c: Fix some portability problems.
+
+ * libtiff/tif_ojpeg.c: Use same jpeg/win32 boolean/FAR hacks as are
+ used in tif_jpeg.c.
+
+ * libtiff/tif_win32.c: Ensure TIFFOpenW() uses same FILE_SHARE flags
+ as TIFFOpen().
+
+2008-06-01 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dirwrite.c: Fix alignment problems affecting architectures
+ like Sparc/Solaris.
+ http://bugzilla.maptools.org/show_bug.cgi?id=1892
+
+2008-05-27 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff.def: Add TIFFFindField
+ http://bugzilla.maptools.org/show_bug.cgi?id=1891
+
+2008-05-26 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tif_config.*.h, tiffconf.*.h: Remove SIZEOF_LONG definition, unused.
+
+ * li2008-04-15 Andrey Kiselev <dron@ak4719.spb.edu>
+
+btiff/tif_win32.c: Replace custom Win32 memory api with generic
+ POSIX one. No apparent value to use of GlobalAlloc() in the modern
+ age. http://bugzilla.maptools.org/show_bug.cgi?id=1885
+
+ * libtiff/tiffconf.vc.h: Added JBIG_SUPPORT and MDI_SUPPORT items
+ in windows version (care of Edward Lam).
+
+2008-05-24 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tif_codec.c: Avoid NULL pointer dereferencing for exotic
+ compression codec codes.
+
+ * tif_dirwrite.c: fix potential memory leak.
+
+ * tif_dirread.c: Fix unchecked malloc result.
+
+2008-05-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * test {tiff2pdf.sh tiff2ps-EPS1.sh tiff2ps-PS1.sh tiff2ps-PS2.sh
+ tiff2ps-PS3.sh tiffcp-g3-1d-fill.sh tiffcp-g3-1d.sh
+ tiffcp-g3-2d-fill.sh tiffcp-g3-2d.sh tiffcp-g3.sh tiffcp-g4.sh
+ tiffcp-split-join.sh tiffcp-split.sh tiffcp-thumbnail.sh
+ tiffdump.sh tiffinfo.sh}: Added more test scripts based on
+ suggestions from Lee Howard posted to the tiff list on 13 Sep
+ 2007.
+
+2008-05-23 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_fax3.c: Add an assert in an effort to detect a
+ possible runtime problem reported by coverity.
+
+ * contrib/iptcutil/iptcutil.c: Fixed memory leak of str.
+
+ * tools/tiffcrop.c, man/tiffcrop.1: Major update from Richard Nolde.
+ http://bugzilla.maptools.org/show_bug.cgi?id=1888
+
+ * tools/tiffdither.c: remove dead onestrip code. avoid memory leak.
+
+ * tools/rgb2ycbcr.c: fix memory leak of raster buffer.
+
+ * tools/tiffcp.c: Simplify inknames code to avoid pointless test.
+ Cleanup scanline allocation to avoid coverity warning.
+
+ * tools/thumbnail.c: Check for TIFFOpen() failure.
+
+2008-05-18 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dirinfo.c: Use TIFF_SETGET_ASCII for PIXAR_TEXTUREFORMAT
+ and PIXAR_WRAPMODES instead of TIFF_SETGET_UNDEFINED. Not exactly clear
+ why this is needed.
+
+2008-05-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am (ACLOCAL_AMFLAGS): Libtool 2.2.4 does not like
+ "ACLOCAL_AMFLAGS=-I ./m4". It wants "ACLOCAL_AMFLAGS=-I m4".
+
+2008-04-15 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * test/: Test suite updated. Everything is passed now.
+
+ * libtiff/tif_dirinfo.c: Fixed description of the
+ TIFFTAG_NUMBEROFINKS tag.
+
+2008-04-14 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_dirread.c, tif_dirwrite.c, tiffiop.h}:
+ Get rid of some of "dereferencing type-punned" warnings by converting
+ tdir_offset field of TIFFDirEntry structure into union.
+
+2008-04-10 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_flush.c, tif_dirwrite.c, tiffio.h, tiffiop.h}:
+ TIFFRewriteField() renamed into _TIFFRewriteField() and moved out
+ from the public interface. Type of its 'count' parameter changed
+ from uint32 to tmsize_t.
+
+ * /libtiff/tiffiop.h: Make tif_nfields and tif_nfieldscompat fields
+ of the tiff structure have the size_t type instead of uint32.
+
+2008-04-09 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffdump.c: Added support for MSVS 6.0.
+
+ * libtiff/tif_dirread.c: Use custom functions _TIFFUInt64ToFloat()
+ and _TIFFUInt64ToDouble() to convert 64-bit integers into floating
+ point values on MSVS 6.0 platform.
+
+2008-03-14 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tif_dirread.c: Removed sanity checks on tags larger than 4MB in
+ TIFFReadDirEntryArray() since they are interfering with seemingly
+ legitimate files. http://trac.osgeo.org/gdal/ticket/2005
+
+2008-02-09 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * tif_dirread.c: Added handling for the case of number of values for
+ PageNumber tag different from 2 (previously resulted in an assert
+ indicating lack of handling and was forgotten about)
+
+2008-02-01 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_jpeg.c: Do not try to fixup subsampling tags based on
+ the actual jpeg data stream if the first strip/tile has zero size.
+ This is the case when GDAL creates a new file with zero sizes, closes
+ and reopens it.
+
+2008-01-07 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tools/tiff2ps.c: fix up 64bit issues (from Edward Lam).
+
+2008-01-01 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dirwrite.c: #ifdef out lots of unused functions.
+
+ * Makefile.vc, libtiff/Makefile.vc, tools/Makefile.vc: Improve clean
+ targets.
+
+ * tools/tiffinfo.c, tools/tiffcmp.c, tools/gif2tiff.c, tools/bmp2tiff.c
+ tools/tiff2pdf.c: Fix 64-bit warnings when compiling under MSVC 2005
+ (x64).
+
+ * tools/tiffset.c: Changes to reflect the fact that TIFFFieldWithTag()
+ and TIFFFieldWithName() now return TIFFField pointers instead of
+ TIFFFieldInfo pointers.
+
+ * tools/tiffdump.c: Added ssize_t typedef on Windows since it doesn't
+ exist. This makes it compile again on Windows
+
+ * tif_aux.c, tif_getimage.c, tif_next.c, tif_predict.c, tif_win32.c,
+ tiffconf.vc.h: Various 64bit fixes from Edward Lam identified on win64.
+
+ * test/rewrite_tag.c: New test for TIFFRewriteField().
+
+2007-12-31 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tif_dirwrite.c: Added TIFFRewriteField(). This new function
+ rewrites one field "on disk" updating an existing directory
+ entry. Lots of limitations still...
+
+ * tiffiop.h, tif_write.c, tif_dirread.c, tif_flush.c: Keep track of
+ TIFF_DIRTYSTRIP separately from TIFF_DIRTYDIRECT to indicate that
+ the strip offset/size values are dirty but nothing else about the
+ directory is dirty. In flush handle "just stripmaps dirty" as a
+ special case that just rewrites these values without otherwise
+ modifying the directory on disk using TIFFRewriteField().
+
+ We also modify logic so that in update mode the directory is not
+ marked dirty on read, but only when something is changed. This
+ means we need to keep track of updates to the stripmap stuff in
+ TIFFAppendToStrip().
+
+2007-12-10 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tif_jpeg.c: Improve ability to switch between encoding and decoding
+ in the jpeg code (gdal bug #2033).
+
+2007-11-23 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tif_dir.c, tif_dirread.c, tif_dirwrite.c, tif_read.c, tif_write.c,
+ tiffiop.h: Added TIFF_BUF4WRITE flag to indicate if contents of the
+ rawcp/rawcc buffer are for writing and thus may require flushing.
+ Necessary to distinguish whether they need to be written to disk when
+ in mixed read/write mode and doing a mixture of writing followed by
+ reading. http://trac.osgeo.org/gdal/ticket/1758
+
+2007-11-23 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * configure.com, libtiff/tif_vms.c: Better OpenVMS support. Patches
+ from Alexey Chupahin.
+
+2007-11-02 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tif_write.c: Rip out the fancy logic in TIFFAppendToStrip() for
+ establishing if an existing tile can be rewritten to the same location
+ by comparing the current size to all the other blocks in the same
+ directory. This is dangerous in many situations and can easily
+ corrupt a file. (observed in esoteric GDAL situation that's hard to
+ document). This change involves leaving the stripbytecount[] values
+ unaltered till TIFFAppendToStrip(). Now we only write a block back
+ to the same location it used to be at if the new data is the same
+ size or smaller - otherwise we move it to the end of file.
+
+ * tif_dirwrite.c: Try to avoid writing out a full readbuffer of tile
+ data when writing the directory just because we have BEENWRITING at
+ some point in the past. This was causing odd junk to be written out
+ in a tile of data when a single tile had an interleaving of reading
+ and writing with reading last. (highlighted by gdal
+ autotest/gcore/tif_write.py test 7.
+
+ * tif_predict.c: use working buffer in PredictorEncodeTile to avoid
+ modifying callers buffer.
+ http://trac.osgeo.org/gdal/ticket/1965
+
+ * tif_predict.c/h: more fixes related to last item, keeping a
+ distinct pfunc for encode and decode cases as these were getting
+ mixed up sometimes.
+ http://trac.osgeo.org/gdal/ticket/1948
+
+2007-11-01 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tif_predict.c/h, tif_lzw.c, tif_zip.c: Improvements so that
+ predictor based encoding and decoding works in read-write update
+ mode properly.
+ http://trac.osgeo.org/gdal/ticket/1948
+
+2007-10-24 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * tif_dirread.c: Fixed problem with bogus file triggering
+ assert(td->td_planarconfig == PLANARCONFIG_CONTIG) in
+ ChopUpSingleUncompressedStrip
+
+2007-10-22 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * tif_jpeg.c: Resolved buffer incrementation bug that lead to faulty images
+ at best, access violation at worst, when subsampled JPEG compressed imagery
+ is decoded without the JPEG_COLORMODE feature
+
+2007-10-11 Frank Warmerdam <warmerdam@pobox.com>
+
+ * html/index.html: Update "people responsible" section.
+
+2007-10-05 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tools/tiff2pdf.c: Fix problem with alpha setting in some cases
+ as reported on the mailing list.
+
+2007-10-01 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * changed some more incorrect %lud printf flags to %lu
+
+2007-09-29 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * tif_dirread.c: Strip chopping interfered badly with uncompressed
+ subsampled images because it tried to divide subsampled rowblocks,
+ leading to all sorts of errors throughout the library for these
+ images. Fixed by making strip chopping divide in row counts that
+ are a multiple of vertical subsampling value.
+
+2007-09-28 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * tif_dirread.c: Logical cast working around compiler warning
+
+ * tif_read.c: Correction of some error flags and parameter lists
+
+2007-09-27 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * tif_dirread.c: Made calculation of td_maxsamplevalue more robust
+ when dealing with large bitspersample values, shutting up purification
+ tools that warn about truncation, though it remains incorrect and
+ indicates a conceptual problem there.
+
+ * tif_open.c: Moved early exit in case of 'h' flag (to disable reading
+ of first IFD) to proper place because it badly interfered with memory
+ mapping, resulting in mapping flag even with dummy mapping functions
+ that returned 0 whilst at the same time the mapping tif_size wasn't
+ set, thus resulting in continuous incorrect beyond-eof errors.
+
+2007-09-24 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * tif_dirinfo.c: Fixed (MSVC) compiler reports about
+ inconsistent use of const in tiffFields and exifFields definition
+
+2007-09-20 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tif_dirwrite.c: Always write tile/strip offsets and sizes
+ using LONG8 type when output format is BigTIFF. The
+ TIFFWriteDirectoryTagLongLong8Array() function was restructured
+ accordingly.
+
+ * tif_dirread.c: Improvements to error reporting text in
+ TIFFFetchDirectory().
+
+2007-09-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * test/images: Added a small collection of test images for use by
+ test programs and scripts.
+ * test/tiffinfo.sh: A trivial example test script.
+ * test/common.sh: Added small script for setting the environment
+ used by script-based tests.
+
+2007-08-24 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tif_dirwrite.c: Write the tif_nextdiroff value instead of a fixed
+ zero when writing directory contents to preserve the ability to
+ rewrite directories in place, even in the middle of a directory
+ chain.
+
+ * tif_dirinfo.c: _TIFFMergeFields() now only merges in field
+ definitions that are missing. Existing definitions are silently
+ ignored.
+
+ * tif_dirread.c: Add runtime error for fields for which no definition
+ is found (in addition to an assert for developers) in
+ TIFFFetchNormalTag(). Not sure if this is needed, but it seems
+ prudent.
+
+2007-08-10 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * libtiff/tif_getimage.c: removed SubsamplingHor and SubsamplingVer
+ from _TIFFRGBAImage structure to revert unwanted ABI change.
+
+2007-08-10 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * libtiff/tif_win32.c: use SetFilePointer instead of
+ SetFilePointerEx, as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1580
+
+2007-07-19 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_stream.cxx: Put all callback functions declarations
+ inside extern "C" block.
+
+ * libtiff/{tif_lzw.c, tif_luv.c, tif_dumpmode.c, tif_print.c,
+ tif_read.c, tif_strip.c, tif_thunder.c}: Use "%I64d" printf()
+ formatter instead of "%lld" with MSVC compiler.
+
+ * libtiff/{tiffiop.h, tif_aux.c}: Added _TIFFUInt64ToFloat() and
+ _TIFFUInt64ToDouble() functions.
+
+2007-07-18 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dirread.c: Handle the case of MSVC 6 when using 64-bit
+ integer constants.
+
+ * libtiff/{Makefile.am, Makefile.v}: Do not distribute tiffconf.h,
+ remove tif_config.h/tiffconf.h during cleaning. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1573
+
+ * libtiff/tif_unix.c: Do not use O_LARGEFILE. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1577
+
+2007-07-13 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff 4.0.0alpha released.
+
+2007-07-12 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiff2pdf.c: Added missed extern optind as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1567
+
+ * libtiff/{tif_close.c, tif_dirinfo.c, tiffiop.c, tif_dirread.c,
+ tif_dir.h, tif_dir.c, tiffio.h}: Transition to the new-style tag
+ extending scheme completed.
+
+2007-07-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_stream.cxx: Adapt to use toff_t again. Update to
+ use standard C++ library size types and attempt to detect overflow
+ cases.
+
+2007-07-08 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_jpeg.c, tif_dir.h, tif_dir.c, tif_dirinfo.c, tiffio.h,
+ tif_ojpeg.c, tif_print.c, tif_fax3.c, tif_dirread.c}: More work on new
+ tag extending scheme. Use the new scheme everywhere.
+
+ * libtiff/{tif_zip.c, tif_predict.c, tif_pixarlog.c, tif_luv.c,
+ tif_fax3.c, tif_dirread.c, tif_dirwrite.c, tif_close.c, tif_ojpeg.c,
+ tif_jpeg.c, tif_dirinfo.c, tif_dir.h, tiffio.h, tiffiop.h}:
+ TIFFFIeldInfo structure replaced with TIFFField structure.
+ TIFFFieldInfo retained for the backward compatibility.
+
+2007-07-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/tiff2pdf.c: Fix a compile problem when JPEG_SUPPORT is not
+ defined.
+
+2007-07-04 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_dir.c, tiff.h, tiffio.h, libtiff.def}: Unused
+ TIFFReassignTagToIgnore() function and TIFFIgnoreSense enumeration
+ removed.
+
+ * libtiff/{tif_dirinfo.c, tif_fax3.c, tif_jbig.c, tif_jpeg.c}: Move
+ tags TIFFTAG_FAXRECVPARAMS, TIFFTAG_FAXSUBADDRESS,
+ TIFFTAG_FAXRECVTIME and TIFFTAG_FAXDCS to the common tag directory.
+ These tags are not codec-specific and relate to image content, so
+ process them as other normal tags.
+
+ * libtiff/{tiffio.h, tif_dir.h}: TIFFTagValue structure moved from the
+ public tiffio.h to private tif_dir.h.
+
+ * contrib/{acorn, mac-cw, mac-mpw}: Removed as unmaintained and
+ outdated.
+
+2007-07-03 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff{tif_acorn.c, tif_apple.c, tif_atari.c, tif_msdos.c,
+ tif_win3.c}: Obsoleted portability stuff removed.
+
+ * tools/tiff2ps.c: Added support 16-bit images as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1566
+
+ Patch from William Bader.
+
+ * tools/tiff2pdf.c: Fix for TIFFTAG_JPEGTABLES tag fetching and
+ significant upgrade of the whole utility as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1560
+
+ Now we don't need tiffiop.h in tiff2pdf anymore and will open output
+ PDF file using TIFFClientOpen() machinery as it is implemented
+ by Leon Bottou.
+
+2007-06-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Fix typo when substituting value for unsigned 8 bit type.
+ Added support for a TIFF_PTRDIFF_T type to use when doing pointer arithmetic.
+ Added support for a TIFF_SSIZE_T in order to return memory sizes but still
+ allow returning -1 for errors.
+ * libtiff/tiffconf.vc.h: Add porting type definitions for WIN32.
+
+2007-06-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * port/strtoull.c: New porting function in case strtoull() is not
+ available on the target system.
+ * configure.ac: Add configure support for determining sized types
+ in a portable way and performing necessary substitutions in
+ tif_config.h and tiffconf.h. Updated tiff.h to use the new
+ definitions.
+
+2007-04-27 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiff2pdf.c: Check the tmpfile() return status as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=154
+
+2007-04-07 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_dir.h, tif_dirread.c, tif_dirinfo.c, tif_jpeg.c,
+ tif_fax3.c, tif_jbig.c, tif_luv.c, tif_ojpeg.c, tif_pixarlog.c,
+ tif_predict.c, tif_zip.c}: Finally fix bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1274
+
+ by introducing _TIFFMergeFieldInfo() returning integer error status
+ instead of void in case of problems with field merging (e.g., if the
+ field with such a tag already registered). TIFFMergeFieldInfo() in
+ public API remains void. Use _TIFFMergeFieldInfo() everywhere and
+ check returned value.
+
+2007-04-07 Frank Warmerdam <warmerdam@pobox.com>
+
+ * contrib/addtiffo/tif_overview.c: Fix problems with odd sized output
+ blocks in TIFF_DownSample_Subsampled() (bug 1542).
+
+2007-04-06 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_jpeg.c: Changed JPEGInitializeLibJPEG() so that it
+ will convert from decompressor to compressor or compress to decompress
+ if required by the force arguments. This works around a problem in
+ where the JPEGFixupTestSubsampling() may cause a decompressor to
+ be setup on a directory when later a compressor is required with the
+ force flag set. Occurs with the addtiffo program for instance.
+
+2007-04-06 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffcrop.c, man/tiffcrop.1: Significant update in
+ functionality from Richard Nolde. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1525
+
+2007-03-28 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_fax3.c: "inline static" -> "static inline" for IRIC CC.
+
+2007-03-17 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * start of BigTIFF upgrade - CVS HEAD unstable until further notice
+
+2007-03-07 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * libtiff/tif_getimage.c: workaround for 'Fractional scanline' error reading
+ OJPEG images with rowsperstrip that is not a multiple of vertical subsampling
+ factor. This bug is mentioned in:
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1390
+ http://www.asmail.be/msg0054766825.html
+
+2007-03-07 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * libtiff/tif_win32.c: made inclusion of windows.h unconditional
+
+ * libtiff/tif_win32.c: replaced preprocessor indication for consiously
+ unused arguments by standard C indication for the same
+
+2007-02-27 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dirread.c: Use uint32 type instead of tsize_t in byte
+ counters in TIFFFetchData(). Should finally fix the issue
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=890
+
+2007-02-24 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffset.c: Properly handle tags with TIFF_VARIABLE writecount.
+ As per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1350
+
+ * libtiff/tif_dirread.c: Added special function to handle
+ SubjectDistance EXIF tag as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1362
+
+ * tools/tiff2pdf.c: Do not assume inches when the resolution units
+ do not specified. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1366
+
+ * tools/{tiffcp.c, tiffcrop.c}: Do not change RowsPerStrip value if
+ it was set as infinite. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1368
+
+ * tools/tiffcrop.c, man/tiffcrop.1: New tiffcrop utility contributed
+ by Richard Nolde. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1383
+
+2007-02-22 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dir.c: Workaround for incorrect TIFFs with
+ ExtraSamples == 999 produced by Corel Draw. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1490
+
+ * libtiff/{tif_dirread.c, tif_read.c}: Type of the byte counters
+ changed from tsize_t to uint32 to be able to work with data arrays
+ larger than 2GB. Fixes bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=890
+
+ Idea submitted by Matt Hancher.
+
+2007-01-31 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tif2rgba.c: This utility does not work properly on big-endian
+ architectures. It was fixed including the bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1149
+
+2007-01-15 Mateusz Loskot <mateusz@loskot.net>
+
+ * Submitted libtiff port for Windows CE platform
+ * libtiff/tif_config.wince.h: Added configuration header for WinCE.
+ * libtiff/tiffconf.wince.h: Ported old configuration header for WinCE.
+ * libtiff/tif_wince.c: Added WinCE-specific implementation of some
+ functions from tif_win32.c.
+ * libtiff/tif_win32.c: Disabled some functions already reimplemented in tif_wince.c.
+ * libtiff/tiffiop.h, port/lfind.c: Added conditional include of some
+ standard header files for Windows CE build.
+ * tools/tiffinfoce.c: Ported tiffinfo utility for Windows CE.
+
+2006-11-19 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_write.c: TIFFAppendToStrip() - clear sorted flag if
+ we move a strip.
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1359
+
+2006-10-13 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dir.c: More fixes for vulnerabilities, reported
+ in Gentoo bug ():
+
+ http://bugs.gentoo.org/show_bug.cgi?id=142383
+
+ * libtiff/contrib/dbs/xtiff/xtiff.c: Make xtiff utility compilable.
+ Though it is still far from the state of being working and useful.
+
+2006-10-12 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_fax3.c: Save the state of printdir codec dependent
+ method.
+
+ * libtiff/tif_jpeg.c: Save the state of printdir codec dependent method
+ as per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1273
+
+ * libtiff/tif_win32.c: Fixed problem with offset value manipulation
+ as per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1322
+
+ * libtiff/{tif_read.c, tif_jpeg.c, tif_dir.c}: More fixes for
+ vulnerabilities, reported in Gentoo bug ():
+
+ http://bugs.gentoo.org/show_bug.cgi?id=142383
+
+2006-09-28 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_fax3.c, tif_next.c, tif_pixarlog.c}: Fixed multiple
+ vulnerabilities, as per Gentoo bug ():
+
+ http://bugs.gentoo.org/show_bug.cgi?id=142383
+
+2006-09-27 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_lzw.c, libtiff/tif_zip.c: Fixed problems with mixing
+ encoding and decoding on the same read-write TIFF handle. The LZW
+ code can now maintain encode and decode state at the same time. The
+ ZIP code will switch back and forth as needed.
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=757
+
+2006-09-20 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff: Rename config.h.vc and tif_config.h.vc to config.vc.h and
+ tif_config.vc.h for easier identification by folks using an IDE.
+
+2006-07-25 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tif_msdos.c: Avoid handle leak for failed opens. c/o Thierry Pierron
+
+2006-07-19 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tif_dirwrite.c: take care not to flush out buffer of strip/tile
+ data in _TIFFWriteDirectory if TIFF_BEENWRITING not set. Relates
+ to bug report by Peng Gao with black strip at bottom of images.
+
+2006-07-12 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tif_dirwrite.c: make sure to use uint32 for wordcount in
+ TIFFWriteNormanTag if writecount is VARIABLE2 for ASCII fields.
+ It already seems to have been done for other field types. Needed
+ for "tiffset" on files with geotiff ascii text.
+
+2006-07-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * {configure.ac, libtiff/tif_config.h.vc, libtiff/tif_jbig.c}
+ (JBIGDecode): jbg_newlen is not available in older JBIG-KIT and
+ its use does not appear to be required, so use it only when it is
+ available.
+
+2006-06-24 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dirinfo.c: Added missed EXIF tag ColorSpace (40961).
+
+ * libtiff/tif_dirread.c: Move IFD fetching code in the separate
+ function TIFFFetchDirectory() avoiding code duplication in
+ TIFFReadDirectory() and TIFFReadCustomDirectory().
+
+2006-06-19 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tools/tiff2pdf.c: Fix handling of -q values.
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=587
+
+2006-06-17 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tif_readdir.c: Added case in EstimateStripByteCounts() for tiled
+ files. Modified TIFFReadDirectory() to not invoke
+ EstimateStripByteCounts() for case where entry 0 and 1 are unequal
+ but one of them is zero.
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1204
+
+2006-06-08 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_open.c, tif_dirread.c, tiffiop.h}: Move IFD looping
+ checking code in the separate function TIFFCheckDirOffset().
+
+ * libtiff/tif_aux.c: Added _TIFFCheckRealloc() function.
+
+ * tools/tiffcmp.c: Fixed floating point comparison logic as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1191
+
+ * libtiff/tif_fax3.c: Fixed problems in fax decoder as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1194
+
+ * tools/tiff2pdf.c: Fixed buffer overflow condition in
+ t2p_write_pdf_string() as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1196
+
+2006-06-07 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * {configure, configure.ac, libtiff/tif_jbig.c, tools/tiffcp.c}: Added
+ support for JBIG compression scheme (34661 code) contributed by Lee
+ Howard. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=896
+
+ * configure, configure.ac: OJPEG support enabled by default.
+
+ * contrib/ojpeg/: Removed. New OJPEG support does not need this patch.
+
+2006-06-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/{tif_dirinfo.c, tif_print.c} : Fix crash in
+ TIFFPrintDirectory(). Joris Van Damme authored the fix.
+
+2006-04-21 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiff2pdf.c: Unified line ending characters (always use '\n')
+ as per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1163
+
+ * README.vms, Makefile.am, configure.com, libtiff/{Makefile.am,
+ tif_config.h-vms, tif_stream.cxx, tif_vms.c, tiffconf.h-vms}:
+ Added support for OpenVMS by Alexey Chupahin, elvis_75@mail.ru.
+
+2006-04-20 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/{fax2ps.c, fax2tiff.c, ppm2tiff.c, ras2tiff.c, tiff2pdf.c}:
+ Properly set the binary mode for stdin stream as per bug
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1141
+
+ * man/{bmp2tiff.1, fax2ps.1, fax2tiff.1, gif2tiff.1, ras2tiff.1,
+ raw2tiff.1, rgb2ycbcr.1, sgi2tiff.1, tiff2bw.1, tiff2pdf.1, tiff2ps.1,
+ tiff2rgba.1, tiffcmp.1, tiffcp.1, tiffdither.1, tiffdump.1, tiffgt.1,
+ tiffset.1}: Improvements in page formatting as per bug
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1140
+
+ * html/tools.html, html/man/Makefile.am, tools/tiff2pdf.c: Fixed
+ typos as per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1139
+
+2006-04-18 Frank Warmerdam <warmerdam@pobox.com>
+
+ * nmake.opt: use /EHsc for VS2005 compatibility. Also define
+ _CRT_SECURE_NO_DEPRECATE to avoid noise on VS2005.
+
+2006-04-12 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * libtiff/tif_getimage.c: Added support for planarconfig separate
+ non-subsampled YCbCr (i.e. separate YCbCr with subsampling [1,1])
+
+2006-04-11 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * libtiff/tif_getimage.c: Revision of all RGB(A) put routines
+ - Conversion of unassociated alpha to associated alpha now done with
+ more performant LUT, and calculation more correct
+ - Conversion of 16bit data to 8bit data now done with
+ more performant LUT, and calculation more correct
+ - Bugfix of handling of 16bit RGB with unassociated alpha
+
+2006-04-11 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * libtiff/tif_getimage.c:
+ - When there is no alpha, gtTileSeparate and gtStripSeparate allocated
+ buffer for alpha strile and filled it, only to never read it back.
+ Removed allocation and fill.
+ - Minor rename of vars in gtTileSeparate and gtStripSeparate
+ anticipating planned functionality extension
+
+2006-04-08 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * libtiff/tif_getimage.c: renamed pickTileContigCase to PickContigCase
+ and pickTileSeparateCase to PickSeparateCase as both work on strips as
+ well
+
+ * libtiff/tif_getimage.c: moved img->get selection from
+ TIFFRGBAImageBegin into PickContigCase and PickSeparateCase to create
+ logical hook for planned functionality extension
+
+2006-04-08 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * libtiff/tif_ojpeg.c: resolved memory leak that was a consequence
+ of inappropriate use of jpeg_abort instead of jpeg_destroy
+
+2006-04-07 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * libtiff/tif_getimage.c: replaced usage of TIFFScanlineSize in
+ gtStripContig with TIFFNewScanlineSize so as to fix buggy behaviour
+ on subsampled images - this ought to get sorted when we feel brave
+ enough to replace TIFFScanlineSize altogether
+
+ * libtiff/tif_ojpeg.c: fixed bug in OJPEGReadSkip
+
+2006-04-04 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * libtiff/tiffio.h: added new type tstrile_t
+
+ * libtiff/tif_dir.h: changed types of td_stripsperimage and td_nstrips
+ to new tstrile_t, types of td_stripoffset and td_stripbytecount to
+ toff_t*
+
+ * libtiff/tif_ojpeg.c: totally new implementation
+
+ * libtiff/tif_dirread.c: added several hacks to suit new support of
+ OJPEG
+
+ * libtiff/tif_getimage.c: removed TIFFTAG_JPEGCOLORMODE handling
+ of OJPEG images in favor of tif_getimage.c native handling of
+ YCbCr and desubsampling
+
+2006-03-29 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_jpeg.c: JPEGVSetField() so that altering the photometric
+ interpretation causes the "upsampled" flag to be recomputed. Fixes
+ peculiar bug where photometric flag had to be set before jpegcolormode
+ flag.
+
+2006-03-25 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * libtiff/tif_jpeg.c: strip size related bugfix in encode raw
+
+ * libtiff/tif_strip.c: temporarily added two new versions of
+ TIFFScanlineSize
+ - TIFFNewScanlineSize: proposed new version, after all related
+ issues and side-effects are sorted out
+ - TIFFOldScanlineSize: old version, from prior to 2006-03-21 change
+ This needs further sorting out.
+
+2006-03-25 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * contrib/addtiffo/tif_ovrcache.c: bugfix to correctly pass size
+ of last truncated strip data to TIFFWriteEncodedStrip
+
+2006-03-25 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * libtiff/{tif_jpeg.c, tif_strip.c}: bugfix of tif_jpeg decode raw
+
+2006-03-25 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * libtiff/tif_getimage.c: bugfix/rewrite of putcontig8bitYCbCr22tile
+
+ * libtiff/tif_getimage.c: added putcontig8bitYCbCr12tile
+
+ * libtiff/tif_read.c: added support for new TIFF_NOREADRAW flag to
+ prepare the path for new tif_ojpeg.c
+
+2006-03-23 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff 3.8.2 released.
+
+ * tools/Makefile.am: Use runtime paths linker flags when rpath
+ option enabled.
+
+2006-03-21 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/libtiff.def: Added missed exports as per bug
+ http://bugzilla.remotesensing.org/attachment.cgi?id=337
+
+ * contrib/addtiffo/Makefile.vc, libtiff/Makefile.vc, port/Makefile.vc,
+ tools/Makefile.vc: Makefiles improvements as per bug
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1128
+
+ * nmake.opt libtiff/{tif_config.h.vc, tif_unix.c, tiffio.h},
+ tools/{fax2ps.c, fax2tiff.c, tiff2pdf.c}: Fixed win32 I/O functions
+ usage as per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1127
+
+ * libtiff/tif_strip.c: Take subsampling in account when calculating
+ TIFFScanlineSize().
+
+ * tools/tiffcp.c: Do not set RowsPerStrip bigger than image length.
+
+2006-03-17 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/fax2tiff.c: Fixed wrong TIFFerror() invocations as per bug
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1125
+
+ * tools/fax2ps.c: Fixed reading the input stream from stdin as per bug
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1124
+
+2006-03-16 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tiffiop.h: Added declaration for
+ _TIFFSetDefaultCompressionState().
+
+ * libtiff/{tif_jpeg.c, tif_fax3.c, tif_zip.c, tif_pixarlog.c,
+ tif_lzw.c, tif_luv.c}: Use _TIFFSetDefaultCompressionState() in all
+ codec cleanup methods. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1120
+
+2006-03-15 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_jpeg.c: Do not cleanup codec state in TIFFInitJPEG(). As
+ per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1119
+
+ * tools/raw2tiff.c: Do not set RowsPerStrip larger than ImageLength.
+ As per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1110
+
+ * libtiff/tiffiop.h: dblparam_t typedef removed; GLOBALDATA macro
+ removed; move here the STRIP_SIZE_DEFAULT macro definition.
+
+ * libtiff/{tif_dirread.c, tif_strip.c}: Removed STRIP_SIZE_DEFAULT
+ macro definition.
+
+ * libtiff/tif_dir.c: Use double type instead of dblparam_t.
+
+2006-03-14 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dirread.c: Do not check the PlanarConfig tag presence
+ in TIFFReadDirectory, because it is always set at the start of
+ function and we allow TIFFs without that tag set.
+
+2005-03-13 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff 3.8.1 released.
+
+2006-03-07 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dirread.c: Fixed error reporting in TIFFFetchAnyArray()
+ function as per bug
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1102
+
+ * libtiff/tif_dirread.c: More wise check for integer overflow
+ condition as per bug
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1102
+
+ * libtiff/{tif_jpeg.c, tif_pixarlog.c, tif_fax3.c, tif_zip.c}:
+ Properly restore setfield/getfield methods in cleanup functions. As
+ per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1102
+
+2006-03-03 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_predict.c, tif_predict.h}: Added new function
+ TIFFPredictorCleanup() to restore parent decode/encode/field methods.
+
+ * libtiff/{tif_lzw.c, tif_pixarlog.c, tif_zip.c}: Use
+ TIFFPredictorCleanup() in codec cleanup methods. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1102
+
+ * libtiff/tif_dirread.c: Fixed integer overflow condition in
+ TIFFFetchData() function. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1102
+
+2006-03-01 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_ojpeg.c: Set the ReferenceBlackWhite with the
+ TIFFSetField() method, not directly. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1043
+
+ * tools/ppm2tiff.c: Added support for PBM files as per bug
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1044
+
+2006-02-27 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_write.c: Small code rearrangement in TIFFWriteScanline()
+ to avoid crash as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1081.
+
+2006-02-26 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiff2pdf.c: Functions t2p_sample_rgbaa_to_rgb() and
+ t2p_sample_rgba_to_rgb() was used in place of each other, that was
+ resulted in problems with RGBA images with associated alpha.
+ As per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1097
+
+2006-02-23 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dirwrite.c: Properly write TIFFTAG_DOTRANGE tag as per
+ bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1088.
+
+ * libtiff/tif_print.c: Properly read TIFFTAG_PAGENUMBER,
+ TIFFTAG_HALFTONEHINTS, TIFFTAG_YCBCRSUBSAMPLING and TIFFTAG_DOTRANGE
+ tags as per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1088.
+
+ * tools/tiff2ps.c: Properly scale all the pages when converting
+ multipage TIFF with /width/height/center options set. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1080
+
+2006-02-15 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiff2pdf.c: Do not create output file until all option checks
+ will be done. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1072
+
+ * tools/bmp2tiff.c: Added ability to create multipage TIFFs from the
+ list of input files as per bug:
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1077
+
+2006-02-09 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_tile.c: Fix error reporting in TIFFCheckTile() as per
+ bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1063.
+
+ * tools/tiffgt.c: Avoid crashing in case of image unsupported by
+ TIFFRGBAImage interface.
+
+ * libtiff/tif_color.c: Avoid overflow in case of wrong input as per
+ bug http://bugzilla.remotesensing.org/show_bug.cgi?id=1065.
+
+2006-02-07 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tools/tiff2pdf.c: Fixed support for non-YCbCr encoded JPEG
+ compressed TIFF files, per submission from Dan Cobra.
+
+2006-02-07 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_dirread.c, tif_packbits.c, tif_win32.c}: Properly
+ cast values to avoid warnings. As per bug
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1033.
+
+ * libtiff/tif_dirinfo.c: Use TIFF_NOTYPE instead of 0 when
+ appropriate. As per bug
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1033.
+
+ * libtiff/tif_aux.c: Fixed type of temporary variable in
+ _TIFFCheckMalloc() as per bug
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1033.
+
+2006-02-06 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_aux.c: Return static array when fetching default
+ YCbCrCoefficients (another problem, reported a the
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1029 entry).
+
+2006-02-03 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dir.c: Special handling for PageNumber, HalftoneHints,
+ YCbCrSubsampling and DotRange tags as per bugs
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1029
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1034
+
+ * libtiff/tif_dirread.c: Use _TIFFGetExifFieldInfo() instead of
+ _TIFFGetFieldInfo() in TIFFReadEXIFDirectory() call as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1026.
+
+2006-01-23 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtool related stuff updated from the 2.1a branch.
+
+2006-01-11 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tools/bmp2tiff,pal2rgb,ppm2tiff,ras2tiff,raw2tiff,sgi2tiff,
+ tiff2bw,tiffcp: Fixed jpeg option processing so -c jpeg:r:50 works
+ properly as per bug:
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1025
+
+2006-01-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Fix with_default_strip_size comparison as reported
+ by Norihiko Murase.
+
+2006-01-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * test/Makefile.am (LIBTIFF): Due to linking against libtiff
+ incorrectly, tests were not actually testing the uninstalled
+ libtiff. Now they are.
+
+2006-01-04 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dirinfo.c: Change definitions for TIFFTAG_ICCPROFILE,
+ TIFFTAG_PHOTOSHOP, TIFFTAG_RICHTIFFIPTC, TIFFTAG_XMLPACKET: readcount
+ should be uint32 value.
+
+2006-01-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * html/man/Makefile.am (htmldoc): Fix htmldoc rule so that it can
+ be used if build directory is not the same as source directory.
+ * man/{TIFFGetField.3tiff, TIFFSetField.3tiff}: Documented
+ TIFFTAG_PHOTOSHOP, TIFFTAG_RICHTIFFIPTC, and TIFFTAG_XMLPACKET,
+ and re-sorted tag names in alphabetical order.
+
+2005-12-29 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff 3.8.0 released.
+
+2005-12-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/bmp2tiff.c (main): Fixed warning regarding returning
+ inconsistent types from a condition.
+ * tools/tiffcmp.c (CheckLongTag): Eliminate warning due to printf
+ format.
+ * tools/bmp2tiff.c: Reduce compilation warnings on big-endian CPUs.
+
+2005-12-28 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * html/{index.html, support.hml, libtiff.html}: Cleaned up HTML
+
+2005-12-27 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tiffio.h: Added VC_EXTRALEAN definition before including
+ windows.h, to reduce the compile time.
+
+2005-12-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_jpeg.c: Improve compilation under MinGW.
+
+2005-12-26 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_dir.c, tif_dir.h, tif_dirread.c, tif_dirinfo.c}:
+ tiffFieldInfo and exifFieldInfo arrays definitions moved back to
+ tif_dirinfo.c; added _TIFFGetFieldInfo() and _TIFFGetExifFieldInfo()
+ private functions to retrieve FieldInfo arrays.
+
+2005-12-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * html/build.html: Added some additional instructions for when
+ building using MSVC under Windows. Also fixed two HTML syntax
+ errors and used HTML Tidy to tidy up the HTML syntax and
+ formatting.
+
+2005-12-24 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_aux.c, tif_dir.c, tif_dir.h, tif_dirwrite.c,
+ tif_print.c, tif_getimage.c}: Make InkSet, NumberOfInks, DotRange and
+ StoNits tags custom.
+
+2005-12-23 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_aux.c, tif_dir.c, tif_dir.h, tif_print.c}: Make
+ WhitePoint tag custom.
+
+ * libtiff/{tif_dir.h, tiff.h}: More EXIF tags added.
+
+2005-12-23 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * libtiff/tiffio.h: fixed typo that potentially resulted in
+ redefininition of USE_WIN32_FILEIO
+
+ * libtiff/*: Added more 'dual-mode' error handling: Done TIFFWarning
+ calls in core LibTiff.
+
+2005-12-21 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_dir.c, tif_dir.h, tif_print.c}: Make RichTIFFIPTC,
+ Photoshop and ICCProfile tags custom.
+
+2005-12-21 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * libtiff/*, contrib/*: Added 'dual-mode' error handling, enabling
+ newer code to get context indicator in error handler and still
+ remain compatible with older code: Done TIFFError calls everywhere
+ except in tools
+
+2005-12-20 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffcp.c: Added many error reporting messages; fixed integer
+ overflow as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=789
+
+2005-12-16 Frank Warmerdam <warmerdam@pobox.com>
+
+ * contrib/addtiffo/*: Major upgrade by Joris to support subsampled
+ YCbCr images in jpeg compressed TIFF files.
+
+2005-12-14 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffcp.c: Return non-zero status when reading fails (again).
+
+2005-12-13 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffcp.c: Return non-zero status when reading fails.
+
+2005-12-12 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_dir.h, tiff.h}: Added more EXIF tags.
+
+2005-12-09 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_dir.c, tif_dir.h, tif_print.c}: Make XMLPacket tag
+ custom.
+
+ * tools/tiffinfo.c: Print EXIF directory contents if exist.
+
+ * libtiff/tiff.h: Few EXIF tag numbers added.
+
+ * libtiff/{tif_dirinfo.c, tif_dirread.c, tif_dir.h, tif_dir.c,
+ tiffio.h}: Preliminary support to read custom directories. New
+ functions: TIFFReadCustomDirectory() and TIFFReadEXIFDirectory().
+
+2005-12-07 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_dirinfo.c, tif_dirread.c, tif_dir.h, tif_dir.c}:
+ More work to implement custom directory read support.
+
+ * libtiff/{tif_aux.c, tif_dirinfo.c, tif_dirread.c, tif_dir.h,
+ tif_dir.c, tif_print.c}: Make YCbCrCoefficients and ReferenceBlackWhite
+ tags custom.
+
+2005-12-05 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dirread.c: One more workaround for broken
+ StripByteCounts tag. Handle the case when StripByteCounts array filled
+ with completely wrong values.
+
+2005-11-30 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dirinfo.c: Release file descriptor in case of failure
+ in the TIFFOpenW() function as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1003
+
+ * libtiff/tif_dirinfo.c: Correctly use bsearch() and lfind()
+ functions as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1008
+
+2005-11-20 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tif_open.c, tiff.h, tiffdump.c: Incorporate preliminary support
+ for MS MDI format.
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=1002
+
+ * .cvsignore: many files added, and a few update according
+ to suggestion of Brad HArds on tiff mailing list.
+
+2005-11-03 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/libtiff.def, tiffiop.h, tiffio.h: Made TIFFFreeDirectory
+ public.
+
+2005-10-31 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/fax2tiff.c: Properly calculate sizes of temporary arrays
+ as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=943
+
+ * tools/fax2tiff.c: Added option '-r' to set RowsPerStrip parameter
+ as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=944
+
+ * tools/tiffdump.c: Fixed typeshift and typemask arrays initialization
+ problem as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=946
+
+ * tools/bmp2tiff.c: Fixed possible integer overflow error as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=965
+
+ * libtiff/tif_dirinfo.c: Make XResolution, YResolution and
+ ResolutionUnit tags modifiable during write process. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=977
+
+ * tools/tiffsplit.c: Copy fax related fields over split parts
+ as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=983
+
+2005-10-21 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tif_dirread.c: Don't try and split single strips into "0" strips
+ in ChopUpSingleUncompressedStrip. This happens in some degenerate
+ cases (like 1x1 files with stripbytecounts==0 (gtsmall.jp2 embed tiff)
+
+2005-10-20 Joris Van Damme <joris.at.lebbeke@skynet.be>
+
+ * tif_fax3.c: changed 'at scanline ...' style warning/errors
+ with incorrect use of tif_row, to 'at line ... of
+ strip/tile ...' style
+
+2005-10-15 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tif_write.c: fixed setting of planarconfig as per bug report
+ on the mailing list from Joris.
+
+2005-10-07 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * configure.ac, configure, nmake.opt, libtiff/{tif_config.h,
+ tif_dirread.c}: Make the default strip size configurable via the
+ --with-default-strip-size and STRIP_SIZE_DEFAULT options.
+
+2005-09-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * html/support.html: Fixed link to documentation on Greg Ward's
+ LogLuv TIFF format.
+
+2005-09-28 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffdump.c: Fixed crash when reading malformed tags.
+
+2005-09-20 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiff2pdf.c: Added missed 'break' statement as per bug
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=932
+
+2005-09-12 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff 3.7.4 released.
+
+ * {configure, configure.ac, Makefile.am, autogen.sh}: Applied patch
+ from Patrick Welche (all scripts moved in the 'config' and 'm4'
+ directories).
+
+2005-09-12 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_open.c: reintroduce seek to avoid problem on solaris.
+
+2005-09-05 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dir.c: When prefreeing tv->value in TIFFSetFieldV
+ also set it to NULL to avoid double free when re-setting custom
+ string fields as per:
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=922
+
+2005-08-12 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_print.c: avoid signed/unsigned warning.
+
+ * libtiff/tif_dirread.c: removed unused variable.
+
+2005-07-30 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dir.c: Fixed up support for swapping "double complex"
+ values (128 bits as 2 64 bits doubles). GDAL gcore tests now
+ pass on bigendian (macosx) system.
+
+2005-07-28 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_aux.c, tif_dirread.c, tif_fax3.c, tiffiop.h}: Rename
+ CheckMalloc() function to _TIFFCheckMalloc() and make it available
+ globally as an internal helper routine.
+
+2005-07-27 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dir.c: More improvements in the "pass by value" part of
+ the custom tags handling code.
+
+2005-07-26 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_dirread.c, tif_dirinfo.c}: Do not upcast BYTEs to
+ SHORTs in the TIFFFetchByteArray(). Remove TIFFFetchExtraSamples()
+ function, use TIFFFetchNormalTag() instead as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=831
+
+ Remove TIFFFetchExtraSamples() function, use TIFFFetchNormalTag()
+ instead.
+
+ * libtiff/tiffconf.h.in: One more attempt to fix the AIX bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=39
+
+2005-07-25 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_print.c: Fixed printing of the BYTE and SBYTE arrays.
+
+ * tools/tiffdump.c: Added support for TIFF_IFD datatype.
+
+2005-07-21 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_write.c: Do not check the PlanarConfiguration field in
+ the TIFFWriteCheck() function in case of single band images (as per
+ TIFF spec).
+
+2005-07-12 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * SConstruct, libtiff/SConstruct: Added the first very preliminary
+ support for SCons software building tool (http://www.scons.org/).
+ This is experimental infrastructure and it will exist along with the
+ autotools mechanics.
+
+2005-07-07 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * port/{getopt.c, strcasecmp.c, strtoul.c}: Update modules from
+ the NetBSD source tree (the old 4-clause BSD license changed to
+ the new 3-clause one).
+
+ * configure.ac, port/lfind.c, libtiff/tiffiop.h: Added lfind()
+ replacement module.
+
+ * port/dummy.c: Make the dummy function static.
+
+2005-07-06 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffcp.c: Fixed WhitePoint tag copying.
+
+ * libtiff/{tif_dir.c, tif_dir.h, tif_dirinfo.c, tif_print.c}:
+ Make FieldOfViewCotangent, MatrixWorldToScreen, MatrixWorldToCamera,
+ ImageFullWidth, ImageFullLength and PrimaryChromaticities tags custom.
+
+2005-07-04 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff 3.7.3 released.
+
+ * configure, configure.ac: Do not use empty -R option when linking
+ with --enable-rpath.
+
+2005-07-01 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tiffiop.h, tif_open.c}: Added open option 'h' to avoid
+ reading the first IFD when needed. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=875
+
+ * libtiff/tif_color.c: Better use of TIFFmin() macro to avoid side
+ effects.
+
+2005-06-23 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiff2pdf.c: Print two characters per loop in the
+ t2p_write_pdf_trailer(). As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=594
+
+ * tools/tiffgt.c: Use MacOS X OpenGL framework when appropriate. As
+ per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=844
+
+ * acinclude.m4: Updated to latest OpenGL test macros versions.
+
+ * libtiff/tiff.h: Use correct int size on Sparc 64bit/Sun compiler
+ platform. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=855
+
+2005-06-14 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dirinfo.c: Added support for ClipPath, XClipPathUnits
+ and YClipPathUnits tags.
+
+2005-06-07 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * contrib/addtiffo/tif_ovrcache.c: Properly extract tile/strip size;
+ use pixel sized shift in contiguous case.
+
+2005-06-06 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * contrib/addtiffo/{tif_overview.c, tif_ovrcache.c, tif_ovrcache.h}:
+ Make overviews working for contiguous images.
+
+2005-06-03 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_open.c: Replace runtime endianness check with the compile
+ time one.
+
+ * libtiff/tif_predict.c: Floating point predictor now works on
+ big-endian hosts.
+
+2005-06-01 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dir.c: Use _TIFFsetString() function when read custom
+ ASCII values.
+
+ * libtiff/{tif_dirinfo.c, tif_dir.h, tif_dir.c, tif_print.c}: Make
+ DocumentName, Artist, HostComputer, ImageDescription, Make, Model,
+ Copyright, DateTime, PageName, TextureFormat, TextureWrapModes and
+ TargetPrinter tags custom.
+
+ * libtiff/tif_jpeg.c: Cleanup the codec state depending on
+ TIFF_CODERSETUP flag (to fix memry leaks).
+
+ * libtiff/tif_jpeg.c: Initialize JPEGTables array with zero after
+ allocating.
+
+2005-05-26 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * configure.ac, libtiff/Makefile.am: Added workaround for
+ OpenBSD/MirOS soname problem as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=838
+
+ * libtiff/tif_dirwrite.c: Use tdir_count when calling
+ TIFFCvtNativeToIEEEDouble() in the TIFFWriteDoubleArray() function as
+ per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=845
+
+2005-05-25 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/ppm2tiff.c: Fixed format string when read PPM file header with
+ the fscanf() function. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=861
+
+ * libtiff/{tif_dirinfo.c, tif_print.c}: TIFFFetchByteArray() returns
+ uint16 array when fetching the BYTE and SBYTE filds, so we should
+ consider result as pointer to uint16 array and not as array of chars.
+ As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=831
+
+ * libtiff/tif_dir.c: More efficient custom tags retrieval as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=830
+
+ * libtiff/tif_win32.c: Use FILE_SHARE_READ | FILE_SHARE_WRITE share
+ mode in CreateFile() call as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=829
+
+ * libtiff/Makefile.am: Fixed parallel compilation of the libtiff and
+ libtiffxx libraries as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=826
+
+ * contrib/addtiffo/{tif_overview.c, tif_ovrcache.h}: Sinchronized with
+ GDAL.
+
+2005-05-23 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_jpeg.c: Substantial fix for addtiffo problems with
+ JPEG encoded TIFF files. Pre-allocate lots of space for jpegtables
+ in directory.
+
+2005-05-22 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dirread.c: Changed the code that computes
+ stripbytecount[0] if it appears bogus to ignore if stripoffset[0] is
+ zero. This is a common case with GDAL indicating a "null" tile/strip.
+
+2005-05-17 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffsplit.c: Check for JPEGTables tag presence before copying.
+
+2005-05-06 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dirread.c: Applied similar change to
+ TIFFFetchPerSampleLongs and TIFFFetchPerSampleAnys.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=843
+
+ * libtiff/tif_jpeg.c: added LIB_JPEG_MK1 support in JPEGDecodeRaw().
+
+2005-05-06 Andrey Kiselev <dron@ak4719.spb.edu>
+ * tools/tiff2pdfr.c, man/tiff2pdf.1: Calculate the tile width properly;
+ added new option '-b' to use interpolation in output PDF files (Bruno
+ Ledoux).
+
+2005-05-05 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dirread.c: Ensure that broken files with too many
+ values in PerSampleShorts work ok instead of crashing.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=843
+
+2005-04-27 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffdither.c: Copy the PhotometricInterpretation tag from the
+ input file.
+
+2005-04-15 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_predict.c: Added ability to encode floating point
+ predictor, as per TIFF Technical Note 3.
+
+2005-04-14 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_predict.h, tif_predict.c}: Added ability to decode
+ floating point predictor, as per TIFF Technical Note 3.
+
+2005-04-13 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tiffio.h, tiffiop.h, tif_dir.c, tif_read.c, tif_swab.c}:
+ Added _TIFFSwab24BitData() and TIFFSwabArrayOfLong() functions used to
+ swap 24-bit floating point values.
+
+ * libtiff/tiff.h: Added predictor constants.
+
+2005-04-08 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tiffiop.h, tif_dir.c}: Use uint32 type for appropriate
+ values in _TIFFVSetField() function. Inspired by the bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=816
+
+ * man/TIFFSetField.3tiff: Fixed definition of the TIFFTAG_INKNAMES tag
+ as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=816
+
+2005-03-30 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_open.c: Do not read header in case the output file
+ should be truncated (Ron).
+
+ * libtiff/{tif_dirinfo.c, tif_config.h.vc}: Use lfind() instead
+ of bsearch() in _TIFFFindFieldInfoByName() function (Ron).
+
+ * libtiff/{tiff.h, tif_dirinfo.c}: Fixes in EXIF tag ordering (Ron).
+
+2005-03-22 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * configure.ac, libtiff/Makefile.am: Use libtool machinery to pass
+ rpath option.
+
+2005-03-21 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_dir.c, tif_print.c}: Handle all data types in custom
+ tags.
+
+2005-03-18 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/dirinfo.c: Added DNG tags.
+
+ * libtiff/{tif_dir.c, tif_print.c}: More improvements in custom tag
+ handling code.
+
+ * libtiff/tiff.h: More comments; added missed DNG tag (LensInfo);
+ added DNG 1.1.0.0 tags.
+
+ * tools/tif2pdf.c: Fixed problem with alpha channel handling as per
+ bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=794
+
+ * man/TIFFGetField.3tiff: Add a note about autoregistered tags.
+
+2005-03-17 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * nmake.opt: Build with Win32 CRT library by default.
+
+ * tools/tiff2ps.c: Fixed typo in page size handling code.
+
+ * libtiff/{tif_dir.c, tif_print.c}: Support for custom tags, passed
+ by value.
+
+ * libtiff/{tiff.h, tif_dirinfo.c, tiffiop.h}: Added EXIF related tags.
+
+2005-03-15 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff 3.7.2 released.
+
+2005-03-09 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffcmp.c: Added ability to compare the 32-bit integer and
+ floating point data; complain on unsupported bit depths.
+
+2005-03-05 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tif_stream.cxx: Use ios namespace instead of ios_base to support
+ GCC 2.95.
+
+ * libtiff/{tiff.h, tif_fax3.tif, tif_jpeg.c}: Applied correct patch from
+ Lee Howard for HylaFax DCS tag
+ (see http://bugzilla.remotesensing.org/show_bug.cgi?id=771)
+
+2005-03-04 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * configure, configure.ac: Use -rpath option instead of -R as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=732
+
+ * libtiff/{tiff.h, tif_fax3.tif, tif_jpeg.c}: Applied patch from Lee
+ Howard to support a new tag TIFFTAG_FAXDCS (34911) used in HylaFax
+ software. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=771
+
+ * nmake.opt, html/build.html: Add more comments, change the config
+ file organization a bit as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=764
+
+ * tools/tiffcmp.c: Use properly sized buffer in short arrays comparison
+ as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=785
+
+2005-03-03 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dirread.c: More logic to guess missed strip size as per
+ bug http://bugzilla.remotesensing.org/show_bug.cgi?id=705
+
+ * tools/fax2ps.c: Replace insecure mktemp() function with the
+ tmpfile() as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=786
+
+2005-02-04 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tiff.h: Changed the int8 definition to be always signed char
+ as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=727
+
+ * libtiff/tiffio.h: Move TIFFOpenW() function into the extern "C"{}
+ block as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=763
+
+2005-02-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/tiffgt.c: Fix problem on big-endian CPUs so that images
+ display more correctly. Images display brighter than they should
+ on a Sun workstation.
+
+2005-02-03 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dirread.c: Estimate strip size in case of wrong or
+ suspicious values in the tags. As per bugs
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=705
+
+ and
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=320
+
+ * tools/tiff2ps.c: Fixed problem with page sizes as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=742
+
+2005-01-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tiff.h (TIFFTAG_TILEWIDTH): Corrected description.
+ (TIFFTAG_TILELENGTH): Corrected description.
+
+2005-01-30 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * configure.ac: Fixes for --with-docdir option as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=759
+
+ * libtiff/tif_open.c: Remove unnesessary TIFFSeekFile() call as per
+ bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=756
+
+ * libtiff/tif_stream.cxx: Fixes for C++ stream interface from
+ Michael Rinne and Edward Lam.
+
+2005-01-15 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * configure.ac: Make the documentation directory location configurable
+ via the --with-docdir option (as suggested by Jeremy C. Reed).
+
+ * libtiff/tif_color.c: Use double as the second argument of pow()
+ function in TIFFCIELabToRGBInit(). As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=741
+
+ * libtiff/tif_pixarlog.c: Avoid warnings when converting float to
+ integer as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=740
+
+ * libtiff/tif_getimage.c: Always fill the error message buffer in
+ TIFFRGBAImageBegin() as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=739
+
+2005-01-12 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_jpeg.c: Added ability to read/write the fax specific
+ TIFFTAG_FAXRECVPARAMS, TIFFTAG_FAXSUBADDRESS and TIFFTAG_FAXRECVTIME
+ tags as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=736
+
+ * libtiff/tif_win32.c: Fixed message formatting in functions
+ Win32WarningHandler() and Win32ErrorHandler() as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=735
+
+ * tools/tiff2ps.c: Interpret the -w and -h options independently. As
+ per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=689
+
+2005-01-11 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tiffio.h: Move the color conversion routines in the 'extern
+ "C"' section as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=727
+
+ * libtiff/tiff.h: Restore back the workaround for AIX Visual Age C
+ compiler to avoid double definition of BSD types as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=39
+
+ * libtiff/Makefile.am: Place the C++ stream API in the separate
+ library called libtiffxx to avoid unneeded dependencies. Probably
+ there will be more C++ API in the future. As per bugs
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=733
+
+ and
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=730
+
+2005-01-05 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffdump.c: Fixed problem when read broken TIFFs with the
+ wrong tag counts (Dmitry V. Levin, Martin Pitt).
+
+ * configure.ac: Replace --disable-c++ with the --disable-cxx option as
+ per bug http://bugzilla.remotesensing.org/show_bug.cgi?id=730
+
+2004-12-25 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_getimage.c: More fixes for multiple-alpha-channelled
+ RGB-images as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=713
+
+
+ * tools/tiffset.c: Convert character option to integer value as per
+ bug http://bugzilla.remotesensing.org/show_bug.cgi?id=725
+
+2004-12-20 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff 3.7.1 released.
+
+ * html/tiffset.1.html: Add missed manual page as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=678
+
+ * libtiff/tiff.h: Revert back libtiff data type definitions as per
+ bug http://bugzilla.remotesensing.org/show_bug.cgi?id=687
+
+2004-12-19 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dirread.c: Do not forget about TIFF_VARIABLE2 when
+ checking for tag count in TIFFReadDirectory() function. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=713
+
+ * libtiff/{tif_dirread.c, tif_fax3.c}: More argument checking in
+ CheckMallock() function.
+
+ * libtiff/tif_getimage.c: Support for multiple-alpha-channelled
+ RGB-images as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=718
+
+2004-12-15 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_getimage.c: #define A1 bracketing for clean build on
+ SunPro compiler.
+
+2004-12-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * autogen.sh: aclocal and autoheader should be executed after
+ libtoolize. Also add '-I .' to aclocal invocation to check
+ current directory for macros.
+
+2004-12-10 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dirwrite.c: Always write TIFFTAG_SUBIFD using LONG type
+ as per bugs
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=703
+
+ and
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=704
+
+2004-12-04 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * nmake.opt: Link with the user32.lib in windowed mode. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=697
+
+ * libtiff/tif_win32.c: Use char* strings instead of TCHAR in windowed
+ mode as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=697
+
+ * libtiff/tif_config.in.vc: Removed unneeded definitions for
+ read/open/close/lseek functions to fix the
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=680
+
+2004-12-03 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_dir.c, tif_dirread.c}: Remove TIFFReassignTagToIgnore()
+ call from the TIFFReadDirectory() function. TIFFReassignTagToIgnore
+ must be removed in the future, as it was never used properly. As per
+ bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=692
+
+2004-11-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_jpeg.c: Added a work-around in order to allow
+ compilation with the heavily modified version of libjpeg delivered
+ with Cygwin.
+
+2004-11-29 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dir.c: Properly handle tags, which have the uint32
+ counts. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=693
+
+ * tools/fax2ps.c: Be able to extract the first page (#0). As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=690
+
+2004-11-28 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_unix.c: Make UNIX module compilable (and usable)
+ on Windows.
+
+ * nmake.opt: Add missed DLLNAME variable.
+
+2004-11-26 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/makefile.vc: make it easier to rename the libtiff DLL.
+
+2004-11-24 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * man/libtiff.3tiff: Improvements in the "LIST OF ROUTINES" table as
+ per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=545
+
+ * man/tiffset.1: Added manual page for tiffset tool written by Jay
+ Berkenbilt. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=678
+
+2004-11-23 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_error.c: fixed TIFFerror call to be TIFFError.
+
+2004-11-21 Frank Warmerdam <warmerdam@pobox.com>
+
+ * html/document.html: Updated Adobe web links as per email from Joris.
+
+2004-11-21 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tiffio.hxx, tiffio.h}: C++ stream interface moved to new
+ file tiffio.hxx. We don't have any C++ in tiffio.h, those who want to
+ use C++ streams should #include <tiffio.hxx>.
+
+2004-11-13 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tiff.h: Added Adobe DNG tags.
+
+ * libtiff/tif_win32.c: Typo fixed.
+
+ * libtiff/{tif_stream.cxx, tiffio.h}: C++ stream interface updated to
+ be compliant with the latest standard. Appropriate additions in
+ makefiles now completed.
+
+2004-11-11 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffset.c, libtiff/tif_dirinfo.c: Properly handle the
+ different tag types. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=600
+
+2004-11-10 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_aux.c: Set the appropriate ReferenceBlackWhite array for
+ YCbCr image which lacks that tag (noted by Hans Petter Selasky).
+
+2004-11-09 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_color.c: Division by zero fixed (Hans Petter Selasky).
+
+2004-11-07 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_stream.cxx, tiffio.h}: Added C++ stream interface
+ contributed by Edward Lam (see
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=654 for details).
+ Though no changes in any makefiles yet.
+
+2004-11-05 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_open.c: Removed close() in TIFFClientOpen() if file
+ is bad. This is the callers responsibility.
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=651
+
+2004-11-05 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tiffio.h, tif_win32.c, libtiff.def}: Added TIFFOpenW()
+ function to work with the double byte strings (used to represent
+ filenames in some locales). As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=625
+
+ * libtiff/tif_dirread.c: Fixed problem when fetching BitsPerSample and
+ Compression tags of type LONG from broken TIFFS as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=662
+
+ * libtiff/tif_dirinfo.c: Fixed definition for TIFFTAG_RICHTIFFIPTC,
+ the writecount should have uint32 type. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=662
+
+ * libtiff/tif_write.c: Fixed wrong if() statement in
+ TIFFAppendToStrip() function as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=660
+
+2004-11-04 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dirinfo.c: Change definition for TIFFTAG_EXTRASAMPLES
+ field. The caller should supply a count when setting this field. As
+ per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=648
+
+ * libtiff/{tif_jpeg.c, tif_ojpeg.c}: TIFFTAG_JPEGTABLES should have
+ uint32 count. Use this type everywhere.
+
+2004-11-03 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_next.c: avoid use of u_long and u_char types. Bug 653.
+
+2004-11-02 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tools/tiff2rgba.c: removed extra newlines in usage message.
+
+2004-10-30 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dirwrite.c: Improvements in tag writing code.
+
+ * tools/tiff2ps.c: Fixed wrong variable data type when read Position
+ tags (Tristan Hill).
+
+2004-10-30 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tiffiop.h: added fallback definition of assert() if we
+ don't have assert.h.
+
+2004-10-29 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_fax3.c: Fixed case with the wrong decode routines
+ choosing when the incorrect Group4Options tag set. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=323
+
+ * libtiff/tif_dirwrite.c: Fixed problem with passing count variable of
+ wrong type when writing the TIFF_BYTE/TIFF_SBYTE tags in
+ TIFFWriteNormalTag().
+
+2004-10-28 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiff2ps.c: Fixed wrong variable data type when read Resolution
+ tags (Peter Fales).
+
+ * tools/{bmp2tiff.c, raw2tiff.c}: Get rid of stream I/O functions.
+
+2004-10-28 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tools/tiff2pdf.c: added casts to avoid warnings.
+
+ * libtiff/libtiff.def: Added several more entry points required
+ to link fax2tiff.c against the DLL on windows.
+
+2004-10-27 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * configure, configure.ac: Added --enable-rpath option to embed linker
+ paths into library binary.
+
+2004-10-26 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffset.c: Check the malloc return value (Dmitry V. Levin).
+
+ * libtiff/{tif_strip.c, tif_tile.c}: Zero division problem fixed
+ (Vladimir Nadvornik, Dmitry V. Levin).
+
+2004-10-16 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff 3.7.0 released.
+
+2004-10-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tif_jpeg.c: There seems to be no need to include stdio.h
+ in this file so its inclusion is removed. Including stdio.h
+ sometimes incurs an INT32 typedef conflict between MinGW's
+ basetsd.h and libjpeg's jmorecfg.h.
+
+2004-10-15 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * man/bmp2tiff.1: Added manual page for bmp2tiff utility.
+
+2004-10-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/tiffcmp.c (leof): Renamed from 'eof' in order to avoid
+ conflict noticed under MinGW.
+ * ltmain.sh: Fix for MinGW compilation.
+
+2004-10-13 Frank Warmerdam <warmerdam@pobox.com>
+
+ * man/tiffsplit.1: Fixed to indicate using aaa-zzz, not aa-zz.
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=635
+
+2004-10-12 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_dirread.c, tif_jpeg.c, tif_luv.c, tif_ojpeg.c,
+ tif_pixarlog.c, tif_write.c}: Handle the zero strip/tile sizes
+ properly (Dmitry V. Levin, Marcus Meissner).
+
+2004-10-11 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dirinfo.c: Type of the TIFFTAG_SUBIFD field changed
+ to TIFF_IFD.
+
+2004-10-10 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/bmp2tif.c: Check the space allocation results.
+
+2004-10-09 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dir.c: Initialize td_tilewidth and td_tilelength fields
+ of the TIFFDirectory structure with the 0 instead of -1 to avoid
+ confusing integer overflows in TIFFTileRowSize() for striped images.
+
+ * tools/tiff2pdf.c: Fixed TransferFunction tag handling reported
+ by Ross A. Finlayson.
+
+ * libtiff/tif_dir.c: Fixed custom tags handling as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=629
+
+2004-10-08 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dirinfo.c: Fix bug with tif_foundfield and reallocation
+ of tif_fieldinfo.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=630
+
+2004-10-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * contrib/iptcutil/README: Added the missing README which goes
+ along with iptcutil.
+
+2004-10-03 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_compress.c: Improved error reporting in
+ TIFFGetConfiguredCODECs() (Dmitry V. Levin).
+
+2004-10-02 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff 3.7.0beta2 released.
+
+ * libtiff/{tif_aux.c, tif_compress.c, tif_dirinfo.c, tif_dirwrite.c,
+ tif_extension.c, tif_fax3.c, tif_luv.c, tif_packbits.c,
+ tif_pixarlog.c, tif_write.c}: Added checks for failed memory
+ allocations and integer overflows (Dmitry V. Levin).
+
+ * libtiff/tiff.h: Missed TIFF_BIGTIFF_VERSION constant added.
+
+2004-10-01 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_open.c: added a more informative message if a BigTIFF
+ file is opened.
+
+2004-09-30 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dirinfo.c: changed type of XMLPacket (tag 700) to
+ TIFFTAG_BYTE instead of TIFFTAG_UNDEFINED to comply with the info
+ in the Adobe XMP Specification.
+
+2004-09-29 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_jpeg.c, tif_pixarlog.c}: Use _TIFFmemset() instead of
+ memset().
+
+ * libtiff/{tif_dirread.c, tif_strip.c, tif_tile.c}: Applied patches
+ from Dmitry V. Levin to fix possible integer overflow problems.
+
+2004-09-28 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_getimage.c: Check for allocated buffers before clearing
+ (Dmitry V. Levin).
+
+2004-09-26 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_dir.h, tif_dir.c, tif_dirread.c, tif_write.c}:
+ Optimize checking for the strip bounds.
+
+ * libtiff/{tif_dirread.c, tif_strip.c}: TIFFScanlineSize() and
+ TIFFRasterScanlineSize() functions report zero in the case of integer
+ overflow now. Properly handle this case in TIFFReadDirectory()
+ (patches from Dmitry V. Levin).
+
+2004-09-25 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_dirinfo.c, tif_strip.c, tif_tile.c}: Use TIFFhowmany8()
+ macro where appropriate.
+
+ * tools/tiff2bw.c: Write ImageWidth/Height tags to output file, as
+ noted by Gennady Khokhorin.
+
+ * libtiff/tif_dirread.c: Always check the return values, returned
+ by the _TIFFmalloc() (Dmitry V. Levin).
+
+ * libtiff/tif_dir.c: Fixed possible integer overflow _TIFFset*Array()
+ functions (Dmitry V. Levin).
+
+ * libtiff/{tif_dirread.c, tif_dir.c, tif_write.c}:
+ Potential memory leak fixed in TIFFReadDirectory(), _TIFFVSetField(),
+ TIFFGrowStrips() (found by Dmitry V. Levin).
+
+2004-09-24 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tiffio.h, tif_compress.c}: Added TIFFGetConfiguredCODECs()
+ to get the list of configured codecs.
+
+ * libtiff/{tiffiop.h, tif_dirread.c}: More overflow fixes from
+ Dmitry V. Levin.
+
+2004-09-23 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dirread.c: Applied patch from Dmitry V. Levin to fix
+ possible integer overflow in CheckMalloc() function.
+
+2004-09-22 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tiffiop.h, tif_strip.c}: Use TIFFhowmany8() macro instead
+ of plain TIFFhowmany() where appropriate.
+
+2004-09-21 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_getimage.c: Initialize arrays after space allocation.
+
+2004-09-19 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff 3.7.0beta released.
+
+ * libtiff/{tif_luv.c, tif_next.c, tif_thunder.c}: Several buffer
+ overruns fixed, as noted by Chris Evans.
+
+2004-09-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * commit: Added a script to make it more convenient to commit
+ updates. The CVS commit message is extracted from this ChangeLog
+ file.
+
+2004-09-14 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * configure.ac, configure, aclocal.m4, libtiff/{mkspans.c, tif_fax3.c,
+ tif_getimage.c, tif_luv.c, tif_lzw.c, tif_ojpeg.c, tif_packbits.c,
+ tif_predict.c, tif_read.c, tif_swab.c, tif_thunder.c, tif_write.c,
+ tif_dir.c, tif_dirread.c, tif_dirwrite.c, tif_jpeg.c, tif_dirinfo.c,
+ tif_vms.c, tif_print.c, tif_strip.c, tif_tile.c, tif_dir.h,
+ tif_config.h.in, tiffiop.h}:
+ Get rid of BSD data types (u_char, u_short, u_int, u_long).
+
+2004-09-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtiff/tiff.h: Fix column tagging. Reference current Adobe XMP
+ specification. Reference libtiff bug tracking system to submit
+ private tag additions.
+
+2004-09-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tools/tiffgt.c: Include "tif_config.h".
+
+ * configure.ac: Use AM_PROG_CC_C_O since it is now needed to build
+ tiffgt. This results in the 'compile' script being added to the
+ project.
+
+ * tools/Makefile.am (tiffgt_CFLAGS): Add extra build options
+ required to find OpenGL headers necessary to build tiffgt. Also
+ ensure that the libtiff that we built is used rather than some other
+ libtiff installed on the system.
+
+2004-09-12 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * configure.ac, acinclude.m4, aclocal.m4: New macros to detect GLUT
+ libraries.
+
+2004-09-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Pass library configuration defines via
+ tif_config.h rather than extending CPPFLAGS. Configure a
+ libtiff/tiffconf.h in order to satisfy application requirements
+ (not used by library build). Do not define _POSIX_C_SOURCE=2 since
+ this causes failure to build on systems which properly respect
+ this request.
+
+ * libtiff/tiffconf.h.in: New file to act as the template for the
+ configured tiffconf.h
+
+ * libtiff/files.lst (HDRS): Install the configured tiffconf.h.
+
+2004-09-10 Frank Warmerdam <warmerdam@pobox.com>
+
+ * html/internals.html: Split off a discussion of adding new tags
+ into addingtags.html.
+
+2004-09-10 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * test/{ascii_tag.c, long_tag.c}: Preliminary test suite added.
+
+ * tools/tiff2pdf.c: Fixed reading TransferFunction tag as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=590
+
+ * libtiff/tif_print.c: Fixes in InkNames and NumberOfInks reporting.
+
+ * libtiff/tif_dirread.c: Don't reject to read tags of the
+ SamplesPerPixel size when the tag count is greater than number of
+ samples as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=576
+
+ * libtiff/tiff.h: Use _TIFF_DATA_TYPEDEFS_ guardian to switch off
+ defining int8/uint8/... etc. types. As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=607
+
+2004-09-09 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tools/tiff2ps.c, tools/tiffmedian.c: fiddle with include files
+ to avoid compile warnings about getopt() and a few other things.
+
+2004-09-02 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dirread.c: Use memcpy() function instead of pointer
+ assigning magic in TIFFFetchFloat().
+
+2004-09-01 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tiffio.h, tif_open.c}: Applied patches from Joris Van Damme
+ to avoid requirement for tiffiop.h inclusion in some applications. See
+ here
+
+ http://www.asmail.be/msg0054799560.html
+
+ for details.
+
+ * tools/fax2tiff.c: Use the new functions in the code.
+
+2004-08-25 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiff2pdf.c: Initialize arrays properly.
+
+ * tools/tiff2ps.c: Avoid zero division in setupPageState() function;
+ properly initialize array in PSDataBW().
+
+2004-08-24 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiff2pdf.c: More fixes for bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=590
+
+ from Ross Finlayson.
+
+2004-08-23 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiff2ps.c: Fixed problem with uninitialized values.
+
+ * libtiff/tif_dir.c: Initialize tif_foundfield data member in the
+ TIFFDefaultDirectory() (in addition to 2004-08-19 fix).
+
+ * tools/tiff2pdf.c: Fixed a bunch of problems as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=590
+
+2004-08-20 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiff2pdf.c: Applied patch from Ross Finlayson that checks
+ that the input file has compression, photometric interpretation,
+ etcetra, tags or if not than a more descriptive error is returned.
+
+ * libtiff/tif_dirread.c: Fixed problem in TIFFReadDirectory() in the
+ code, responsible for tag data type checking.
+
+2004-08-19 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tiffiop.h, tif_dirinfo.c}: Fixed problem with the static
+ variable as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=593
+
+2004-08-16 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/ras2tiff.c: Fixed issue with missed big-endian checks as per
+ bug http://bugzilla.remotesensing.org/show_bug.cgi?id=586
+
+2004-08-01 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_config.h.in, tif_config.h.vc}: config.h.in and
+ config.h.vc files renamed in the tif_config.h.in and tif_config.h.vc.
+
+2004-07-24 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_lzw.c: LZW compression code is merged back from the
+ separate package. All libtiff tools are updated to not advertise an
+ abcence of LZW support.
+
+2004-07-12 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tiffio.h: Revert thandle_t back to void* type.
+
+2004-07-11 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_read.c, tif_tile.c, tif_strip.c}: Fixes in error
+ messages, as suggested by Bernd Herd.
+
+2004-07-03 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dir.c: Call TIFFError() instead of producing warnings
+ when setting custom tags by value. Reported by Eric Fieleke.
+
+2004-06-14 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/bmp2tiff.c: Add missed RawsPerStrip setting.
+
+2004-06-08 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/bmp2tiff.c: Added new utility to convert Windows BMP files
+ into TIFFs.
+
+2004-06-07 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff 3.7.0alpha released.
+
+2004-06-06 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tiff.h, tif_dirwrite.c, tif_fax3.c, tif_packbits.c,}: Get rid
+ of ugly 64-bit hacks, replace them with the clever (autoconf based )
+ ones :-).
+
+ * libtiff/tiffio.h: Define thandle_t as int, not void* (may cause
+ problems in 64-bit environment).
+
+2004-06-05 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffset.c: tiffset now can set any libtiff supported tags.
+ Tags can be supplied by the mnemonic name or number.
+
+ * libtiff/{tiffio.h, tif_dir.h, tif_dirinfo.c,}: Added two new
+ functions TIFFFindFieldInfoByName() and TIFFFieldWithName().
+
+2004-05-27 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_ojpeg.c: Fixed problem with duplicated SOI and SOF
+ markers as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=581
+
+2004-05-24 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffsplit.c: Don't forget to copy Photometric
+ Interpretation tag.
+
+2004-05-20 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_open.c, tiffio.h}: New function added:
+ TIFFIsBigEndian(). Function returns nonzero if given was file written
+ in big-endian order.
+
+ * tools/tiffsplit.c: Fixed problem with unproperly written multibyte
+ files. Now output files will be written using the same byte order
+ flag as in the input image. See
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=574
+
+ for details.
+
+2004-05-19 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_print.c: added (untested) support for printing
+ SSHORT, SLONG and SRATIONAL fields.
+
+ * tools/tiffcp.c: close output file on normal exit.
+
+2004-05-17 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_fax3.c: Avoid reading CCITT compression options
+ if compression type mismatches. See
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=565
+
+2004-04-30 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_strip.c: Never return 0 from the
+ TIFFNumberOfStrips().
+
+2004-04-29 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dirread.c: Workaround for broken TIFF writers which
+ store single SampleFormat value for multisampled images. See
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=562
+
+2004-04-25 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * configure.ac, libtiff/{tiff.h, config.h.in}: Added tests for int8,
+ int16 and int32 types to avoid complains on some compilers. Details at
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=39
+
+2004-04-20 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiff2pdf.c: Fixed problem with unaligned access as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=555
+
+2004-04-14 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_write.c: Allow in-place updating of the compressed
+ images (don't work properly with all codecs). For details see GDAL bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=534
+
+2004-04-06 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_jpeg.c: Workaround for wrong sampling factors used
+ in the Intergarph JPEG compressed TIFF images as per bug:
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=532
+
+2004-04-04 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_open.c: close clientdata if TIFFClientOpen() fails
+ via bad2.
+
+2004-03-26 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffcp.c: Properly set Photometric Interpretation in case of
+ JPEG compression of grayscale images.
+
+ * tools/tiffcp.c: Don't emit warnings when Orientation tag does not
+ present in the input image.
+
+2004-03-19 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * {many}: The first attempt to switch to autotools.
+
+2004-03-03 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_open.c: Use dummy mmap/munmap functions in
+ TIFFClientOpen() when the appropriate client functions was not
+ supplied by user.
+
+2004-03-02 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tools/ycbcr.c: fixed main() declaration as per:
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=513
+
+2004-02-26 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffsplit.c: Copy JPEGTables tag contents for JPEG compressed
+ images. Reported by Artem Mirolubov.
+
+ * libtiff/tif_dirread.c: Fixed problem with handling TIFF_UNDEFINED
+ tag type in TIFFFetchNormalTag() as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=508
+
+2004-02-17 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_codec.c: Fixed typo in TIFFInitPackBits name as per:
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=494
+
+2004-02-05 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_fax3.c: Fixed problem with CCITT encoding modes as per
+ bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=483
+
+ But we need more work on fax codec to support update mode.
+
+2004-01-30 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/libtiff.def: Added TIFFCurrentDirOffset, TIFFWriteCheck,
+ TIFFRGBAImageOK, and TIFFNumberOfDirectories as suggested by
+ Scott Reynolds.
+
+2004-01-29 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tiff.h: Fixed tag definitions for TIFFTAG_YCLIPPATHUNITS
+ and TIFFTAG_INDEXED as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=475
+
+ * libtiff/{tif_win32.c, tif_unix.c}: Check whether the pointer is
+ NULL before proceeding further as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=474
+
+ Check results, returned by the TIFFFdOpen() before returning and close
+ file if TIFFFdOpen() failed as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=468
+
+ * libtiff/tif_open.c: More fixes for
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=468
+
+2004-01-28 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{libtiff.def, tif_close.c, tiffio.h, tif_open.c}: Separate
+ TIFFCleanup() from the TIFFClose() in order to fix the bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=468
+
+ * tools/tiffcp.c: Fixed problem with wrong interpretation of the
+ InkNames tag as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=466
+
+ Memory leak fixed.
+
+2004-01-21 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dirwrite.c: Fixed handling of writable ASCII tags that
+ are field_passcount=TRUE properly. Arguably anonymous custom tags
+ should be declared as passcount=FALSE, but I don't want to change
+ that without a careful review.
+
+2004-01-20 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_write.c: Fixed reporting size of the buffer in case of
+ stripped image in TIFFWriteBufferSetup(). As per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=460
+
+2004-01-11 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dir.c: Incomplete cleanup in TIFFFreeDirectory(),
+ patch from Gerben Koopmans.
+
+ * libtiff/tif_dirread.c: Check field_passcount value before setting
+ the value of undefined type, patch from Gerben Koopmans.
+
+2004-01-02 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffcp.c: Fixed problem with wrong Photometric setting for
+ non-RGB images.
+
+2003-12-31 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_win32.c: Fixed problem with _TIFFrealloc() when the NULL
+ pointer passed. Patch supplied by Larry Grill.
+
+ * libtiff/{tiff.h, tif_fax3.c}:Fixes for AMD 64 platform as
+ suggested by Jeremy C. Reed.
+
+2003-12-26 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff 3.6.1 released.
+
+2003-12-24 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * config.guess, config.sub: Updated from the recent upstream.
+
+2003-12-22 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_color, tif_getimage.c, tiffio.h}, man/TIFFcolor.3t:
+ More cleanups in color conversion interface, added appropriate manual
+ page.
+
+2003-12-19 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_extension.c, tif_dirinfo.c, tiff.h}: Warnings fixed as
+ per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=357
+
+ * tools/tiff2ps.c: Added support for alpha channel. Fixes
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=428
+
+ * libtiff/{libtiff.def, tif_color.c, tif_getimage.c, tiffio.h}:
+ Interface for Lab->RGB color conversion is finally cleaned up.
+ Added support for ReferenceBlackWhite tag handling when converted from
+ YCbCr color space. The latter closes
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=120
+
+2003-12-07 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_getimage.c, tiffio.h}: Avoid warnings.
+
+ * libtiff/makefile.vc, tools/makefile.vc: Support for IJG JPEG
+ library.
+
+2003-12-06 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_getimage.c, tif_aux.c}: Read WhitePoint tag from the
+ file and properly use it for CIE Lab->RGB transform.
+
+2003-12-04 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_getimage.c, tif_color.c, tiffio.h}: YCbCr->RGB
+ conversion routines now in the tif_color.c module. New function
+ TIFFYCbCrtoRGB() available in TIFF API.
+
+ * libtiff/tif_dirwrite.c: Handle TIFF_IFD tag type correctly.
+
+2003-12-03 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_getimage.c, tif_color.c, tiffio.h}: Improvements in
+ CIE Lab conversion code. Start moving YCbCr stuff to the tif_color.c
+ module.
+
+ * libtiff/{tif_getimage.c, tiffio.h}, man{TIFFReadRGBAImage.3t,
+ TIFFReadRGBAStrip.3t, TIFFReadRGBATile.3t, TIFFRGBAImage.3t}:
+ Finally resolved problems with orientation handling. TIFFRGBAImage
+ interface now properly supports all possible orientations, i.e. images
+ will be flipped both in horizontal and vertical directions if
+ required. 'Known bugs' section now removed from the appropriate manual
+ pages. Closed bug entry:
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=322
+
+2003-12-02 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dir.c: Fixed order of the parameters in TIFFError()
+ function calls as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=440
+
+2003-11-28 Ross Finlayson <libtiff@apexinternetsoftware.com>
+
+ * tools/tiff2pdf.c: Some bugs fixed.
+
+2003-11-27 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_luv.c: Fixed bug in 48-bit to 24-bit conversion routine,
+ reported by Antonio Scuri.
+
+ * man/tiff2pdf.1: Few improvements in page layout.
+
+ * Makefile.in, /man/Makefile.in, /html/man/tiff2pdf.1.html:
+ Added support for tiff2pdf manual page.
+
+2003-11-26 Ross Finlayson <libtiff@apexinternetsoftware.com>
+
+ * /man/tiff2pdf.1: File added to repository.
+
+2003-11-26 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * Makefile.in, /tools/{Makefile.in, makefile.vc}:
+ Added support for tiff2pdf utility.
+
+2003-11-25 Ross Finlayson <libtiff@apexinternetsoftware.com>
+
+ * /tools/tiff2pdf.c: File added to repository.
+
+2003-11-22 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * /tools/raw2tiff.c: sqrtf() replaced with sqrt().
+
+2003-11-21 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * /tools/raw2tiff.c: #include <getopt.h> removed.
+
+ * tools/{Makefile.in, tiffgt.c}: Unmaintained and platform dependent
+ sgigt utility removed and replaced with the completely rewritten
+ portable tiffgt tool (depend on OpenGL and GLUT). Initial revision,
+ there is a lot of things to improve.
+
+ * libtiff/tif_ojpeg.c: TIFFVGetField() function now can properly
+ extract the fields from the OJPEG files. Patch supplied by Ross
+ Finlayson.
+
+ * libtiff/{tiffio.h, tif_codec.c}, man/{libtiff.3t, TIFFcodec.3t}:
+ Added new function TIFFIsCODECConfigured(), suggested by Ross
+ Finlayson.
+
+2003-11-18 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dirinfo.c: Implemented binary search in
+ _TIFFMergeFieldInfo(). Patch supplied by Ross Finlayson.
+
+ * libtiff/tif_dir.h: _TIFFFindOrRegisterdInfo declaration replaced
+ with _TIFFFindOrRegisterFieldInfo as reported by Ross Finlayson.
+
+2003-11-17 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tif_dirread.c: do not mark all anonymously defined tags to be
+ IGNOREd.
+
+2003-11-17 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * contrib/pds/{tif_pdsdirread.c, tif_pdsdirwrite.c}: Use
+ TIFFDataWidth() function instead of tiffDataWidth array.
+
+2003-11-16 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tiff.h, tif_dirinfo.c}: Added support for IFD (13)
+ datatype, introduced in "Adobe PageMaker TIFF Tech. Notes".
+
+2003-11-15 Frank Warmerdam <warmerdam@pobox.com>
+
+ * Makefile.in: fixed missing backslash for tif_color.c in list.
+
+2003-11-13 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_color.c, tif_getimage.c, tiffio.h, Makefile.in}:
+ New color space conversion code: CIE L*a*b* 1976 images now supported
+ by the TIFFRGBAImage interface. All introduced routines go to new
+ module tif_color.c. Eventually all color conversion functions should
+ be moved there.
+
+2003-11-12 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/{ras2tiff.c, rasterfile.h}: Properly determine SUN Rasterfiles
+ with the reverse byte order (it is reported by the magic header
+ field). Problem reported by Andreas Wiesmann.
+
+ * tools/raw2tiff.c, man/raw2tiff.1: Few improvements in correlation
+ calculation function. Guessing mechanics now documented in manual page.
+
+2003-11-11 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/raw2tiff.c: Implemented image size guessing using
+ correlation coefficient calculation between two neighbour lines.
+
+2003-11-09 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_tile.c: remove spurious use of "s" (sample) in the
+ planarconfig_contig case in TIFFComputeTile().
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=387
+
+2003-11-09 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tiffiop.h: New macros: TIFFmax, TIFFmin and TIFFrint.
+
+2003-11-07 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tiffio.h, tif_strip.c}, man/{TIFFstrip.3t, libtiff.3t}:
+ Added TIFFRawStripSize() function as suggested by Chris Hanson.
+
+2003-11-03 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_lzw.c, tif_fax3.c}: Proper support for update mode as
+ per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=424
+
+2003-10-29 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/libtiff.def: Added TIFFReadRGBAImageOriented.
+
+ * html/build.html: Added note about GNU make requirement.
+
+2003-10-25 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * Makefile.in: Fixes in using MAKEFLAGS as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=418
+
+ * port/install.sh.in: Option -p added to the mkdir command to create
+ all directory tree structure before installing.
+
+2003-10-18 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * /tools/tiff2ps.c: #include <strings.h> replaced with the
+ #include <string.h>.
+
+2003-10-16 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * Makefile.in: Add an absolute path to the test_pics.sh call.
+
+2003-10-12 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tiffcomp.h: #define _BSDTYPES_DEFINED when defining BSD
+ typedefs.
+
+2003-10-09 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * configure, libtiff/{Makefile.in, mkversion.c}:
+ Relative buildings fixed.
+
+ * tools/Makefile.in: Added "-I../libtiff" to the tiffset building
+ rule.
+
+2003-10-07 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * Makefile.in: Added missed v3.6.0.html.
+
+ * libtiff/tiffio.h: Typo fixed: ORIENTATION_BOTTOMLEFT replaced with
+ ORIENTATION_BOTLEFT.
+
+2003-10-04 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * 3.6.0 final release.
+
+2003-10-03 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tif_getimage.c, tiffio.h}, man/TIFFReadRGBAImage.3t: New
+ function TIFFReadRGBAImageOriented() implemented to retrieve raster
+ array with user-specified origin position as suggested by Jason Frank.
+ See
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=322
+
+ for details.
+
+ * tools/tiff2rgba.c: Switched to use TIFFReadRGBAImageOriented()
+ instead of TIFFReadRGBAImage().
+
+ * tools/tiff2ps.c: Fixed possible endless loop as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=404
+
+2003-09-30 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dirread.c: Check field counter against number of fields
+ in order to fix
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=366
+
+ * libtiff/tif_fax3.c: Fix wrong line numbering as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=342
+
+2003-09-25 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/{tiffiop.h, tif_dirread.c, tif_dir.c, tif_open.c,
+ tif_close.c}: Store a list of opened IFD to prevent looping as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=383
+
+2003-09-23 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dirread.c: More fixes for EstimateStripByteCounts(). See
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=358
+
+2003-08-21 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffmedian.c: int declaration replaced with the uint32 to
+ support large images as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=382
+
+2003-08-12 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/Makefile.in: Fixed problem with building in different
+ directory.
+
+ * tools/tiff2ps.c: Added missing #include <strings.h>.
+
+ * libtiff/tif_dirwrite.c: More fixes for custom tags code
+ from Ashley Dreier.
+
+2003-08-07 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiff2ps.c: Added page size setting when creating PS Level 2.
+ Patch submitted by Balatoni Denes (with corrections from Tom
+ Kacvinsky).
+
+ * tools/tiff2ps.c: Fixed PS comment emitted when FlateDecode is
+ being used. Reported by Tom Kacvinsky.
+
+ * libtiff/tif_dirwrite.c: Fixed problem with custom tags writing,
+ reported by Ashley Dreier.
+
+ * libtiff/tif_print.c: Fixed problem with float tags reading, support
+ for printing RATIONAL and BYTE tags added.
+
+2003-08-05 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_lzw.c: Move LZW codec state block allocation back to
+ TIFFInitLZW(), because its initialization in LZWSetupDecode() cause
+ problems with predictor initialization. Remove O_RDONLY check during
+ state block allocation to be able open LZW compressed files in update
+ mode.
+
+ Problem exist for libtiff version of the tif_lzw.c module. One from
+ lzw-compression-kit hasn't such troubles.
+
+2003-08-04 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_write.c: modified tif_write.c so that the various
+ encoded write functions use tif_postdecode() to apply byte order
+ swapping (swab) to the application passed data buffer if the same
+ would be done when reading. This allows us to write pixel data with
+ more than 8 bits per sample to existing files of a non-native byte
+ order. One side effect of this change is the applications buffer
+ itself is altered in this case by the act of writing.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=171
+
+2003-07-25 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_open.c: avoid signed/unsigned casting warning
+ initializing typemask as per patch from J.A. Strother.
+
+ * tools/tiffcp.c: fixed signed/unsigned casting warning.
+
+ * libtiff/tif_print.c: dos2unix conversion.
+
+ * tools/tiffsplit.c: increased the maximum number of pages that
+ can be split. Patch provided by Andrew J. Montalenti.
+
+2003-07-11 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/raw2tiff.c: Added option `-p' to explicitly select color
+ space of input image data. Closes
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=364
+
+2003-07-08 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tif_aux.c, tif_codec.c, tif_dir.c, tif_dirread.c, tif_extension.c,
+ tif_fax3.c, tif_getimage.c, tif_luv.c, tif_lzw.c, tif_next.c,
+ tif_packbits.c, tif_predict.c, tif_print.c, tif_swab.c, tif_thunder.c:
+ avoid casting warning at /W4.
+
+2003-07-03 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/thumbnail.c: Memory leak fixed as reported by Robert S. Kissel.
+
+2003-06-30 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_pixarlog.c: Unused variables removed.
+
+ * libtiff/{tif_dirread.c, tif_dir.c}: Fixed problem with
+ EstimateStripByteCounts() as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=358
+
+ * libtiff/{tif_dirwrite.c, tif_packbits.c}: Fixed compilation on
+ 64-bit architectures as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=357
+
+ * libtiff/tif_dirinfo.c: TIFFDataWidth() returns 0 in case of
+ unknown data type.
+
+2003-06-19 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_print.c: fixed some serious bugs when printing
+ custom tags ... almost certain to crash.
+
+ * libtiff/tif_dirread.c: Don't ignore custom fields that are
+ autodefined. Not sure how this got to be like this.
+
+2003-06-18 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * 3.6.0 Beta2 released.
+
+ * tools/tiffcmp.c, man/tiffcmp.1: Fixed problem with unused data
+ comparing as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=349
+
+ `-z' option now can be used to set the number of reported different
+ bytes.
+
+2003-06-09 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffcp.c, man/tiffcp.1: Added possibility to specify value -1
+ to -r option to get the entire image as one strip. See
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=343
+
+ for details.
+
+2003-06-04 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffcp.c: Set the correct RowsPerStrip and PageNumber
+ values as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=343
+
+2003-05-27 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_jpeg.c: modified segment_height calculation to always
+ be a full height tile for tiled images. Also changed error to just
+ be a warning.
+
+2003-05-25 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/fax2tiff.c: Page numbering fixed, as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=341
+
+2003-05-20 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * contrib/ojpeg/{Makefile.in, jdhuff.h, jinclude.h, ojpeg.c, README},
+ configure, Makefile.in: Switched back to the old behaviour. Likely
+ better solution should be found for OJPEG support.
+
+2003-05-11 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/mkversion.c: Fixed problem with wrong string size when
+ reading RELEASE-DATE file.
+
+2003-05-07 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiff2ps.c: Fixed bug in Ascii85EncodeBlock() function: array
+ index was out of range.
+
+2003-05-06 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * contrib/ojpeg/{Makefile.in, jdhuff.h, jinclude.h, ojpeg.c, README},
+ configure, Makefile.in: Improved libtiff compilation with OJPEG
+ support. Now no need for patching IJG JPEG library, hack required by
+ libtiff will be compiled and used in-place. Implemented with
+ suggestion and help from Bill Allombert, Debian's libjpeg maintainer.
+
+ * libtiff/tif_aux.c: Properly handle TIFFTAG_PREDICTOR in
+ TIFFVGetFieldDefaulted() function.
+
+2003-05-05 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/ppm2tiff.c: PPM header parser improved: now able to skip
+ comments.
+
+ * tools/tiffdither.c: Fixed problem with bit fill order tag setting:
+ was not copied from source image.
+
+ * libtiff/getimage.c: Workaround for some images without correct
+ info about alpha channel as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=331
+
+2003-04-29 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiff2ps.c, man/tiff2ps.1: Add ability to generate PS Level 3.
+ It basically allows one to use the /flateDecode filter for ZIP
+ compressed TIFF images. Patch supplied by Tom Kacvinsky. Fixes
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=328
+
+ * tools/tiff2ps.c: Force deadzone printing when EPS output specified
+ as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=325
+
+2003-04-17 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dirread.c: Removed additional check for StripByteCounts
+ due to problems with multidirectory images. Quality of error messages
+ improved.
+
+2003-04-16 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiffcp.c: Fixed problem with colorspace conversion for JPEG
+ encoded images. See bug entries
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=275
+
+ and
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=23
+
+ * libtiff/tif_dirread.c: Additional check for StripByteCounts
+ correctness. Fixes
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=320
+
+2003-03-12 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/{fax2ps.c, fax2tiff.c, gif2tiff.c, pal2rgb.c, ppm2tiff.c,
+ ras2tiff.c, raw2tiff.c, rgb2ycbcr.c, thumbnail.c, tiff2bw.c,
+ tiff2ps.c, tiff2rgba.c, tiffcp.c, tiffdither.c, tiffinfo.c,
+ tiffmedian.c}: Added library version reporting facility to all tools.
+
+2003-03-06 Frank Warmerdam <warmerdam@pobox.com>
+
+ * port/install.sh.in: Fixed problems with install producing paths
+ like ///usr/local/lib on cygwin.
+
+2003-02-27 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/fax2tiff.c, man/fax2tiff.1: New switch (-X) to set width of
+ raw input page. Patch supplied by Julien Gaulmin. See
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=293
+
+ for details.
+
+2003-02-26 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dir.c: fixed up the tif_postdecode settings
+ responsible for byte swapping complex image data.
+
+ * libtiff/tif_lzw.c: fixed so that decoder state isn't allocated till
+ LZWSetupDecode(). Needed to read LZW files in "r+" mode.
+
+2003-02-07 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/ppm2tiff.c: Fixed problem with too many arguments.
+
+2003-02-04 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/raw2tiff.c: Memory leak fixed.
+
+2003-02-03 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/fax2tiff.c, man/fax2tiff.1: Applied patch from Julien Gaulmin
+ (thanks, Julien!). More switches for fax2tiff tool for better control
+ of input and output. Details at
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=272
+
+2003-02-03 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_jpeg.c: Modified to defer initialization of jpeg
+ library so that we can check if there is already any tile/strip data
+ before deciding between creating a compressor or a decompressor.
+
+2003-01-31 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_write.c: TIFFWriteCheck() now fails if the image is
+ a pre-existing compressed image. That is, image writing to
+ pre-existing compressed images is not allowed.
+
+ * libtiff/tif_open.c: Removed error if opening a compressed file
+ in update mode.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=198
+
+2003-01-31 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * config.guess, config.sub: Updated to recent upstream versions.
+
+2003-01-15 Frank Warmerdam <warmerdam@pobox.com>
+
+ * cut 3.6.0 Beta release.
+
+2002-12-20 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/fax2ps.c, man/fax2ps.1: Page size was determined
+ in wrong way as per bug
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=239
+
+2002-12-17 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dirread.c: Allow wrong sized arrays in
+ TIFFFetchStripThing().
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=49
+
+2002-12-02 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dir.c: fix problem with test on td_customValueCount.
+ Was using realloc even first time. Fix by Igor Venevtsev.
+
+2002-11-30 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dir.c: fixed bug with resetting an existing custom
+ field value.
+
+ * libtiff/tif_dir.c: Fixed potential problem with ascii "custom"
+ tags in TIFFVGetField() ... added missing break.
+
+2002-10-14 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tools/tiff2ps.c: fixes a problem where "tiff2ps -1e" did not make
+ the scanline buffer long enough when writing rgb triplets.
+ The scanline needs to be 3 X the number of dots or else it will
+ contain an incomplete triplet and programs that try to separate
+ the eps by redefining the colorimage operator will get messed up.
+ Patch supplied by William Bader.
+
+ * Makefile.in: added tif_extension.c to file list as per
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=218.
+
+2002-10-11 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * configure, config.site, libtiff/{tif_unix.c, Makefile.in}: Fix for
+ large files (>2GiB) supporting. New option in the config.site:
+ LARGEFILE="yes". Should be enough for I/O of the large files.
+
+2002-10-10 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/html/v3.6.0.html: new release notes.
+
+ * libtiff/index.html: removed faq, cvs snapshot cruft. Added email
+ link for Andrey. Pointer to v3.6.0.html.
+
+ * libtiff/Makefile.in: added direct rule for tiffvers.h for release.
+
+2002-10-07 Andrey Kiselev <dron@ak4719.spb.edu>
+ * tools/tiff2ps.c, man/tiff2ps.1: Applied patch form Sebastian Eken
+ (thanks, Sebastian!). New switches:
+ -b # for a bottom margin of # inches
+ -c center image
+ -l # for a left margin of # inches
+ -r rotate the image by 180 degrees
+ New features merged with code for shrinking/overlapping.
+ Previously added -c and -n switches (for overriding PS units) renamed
+ in -x and -y respectively.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=200
+
+ * html/man/*.html: Updated from actual manual pages.
+
+2002-10-06 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_jpeg.c: fixed problem with boolean defined with wrong
+ size on windows. Use #define boolean hack.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=188
+
+ * libtiff/tiff.h: Don't do special type handling in tiff.h unless
+ USING_VISUALAGE is defined.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=39
+
+2002-10-03 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tiff.h: added COMPRESSION_JP2000.
+
+2002-10-02 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_dirread.c: Another fix for the fetching SBYTE arrays
+ by the TIFFFetchByteArray() function. Should finally resolve
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=52
+
+ * configure: Set -DPIXARLOG_SUPPORT option along with -DZIP_SUPPORT
+
+ * html/Makefile.in: New targets added: html and groffhtml for
+ producing HTML representations of the manual pages automatically.
+ html target uses man2html tool, groffhtml uses groff tool.
+
+2002-09-29 Frank Warmerdam <warmerdam@pobox.com>
+
+ * configure, libtiff/Makefile.in: Added SCO OpenServer 5.0.6 support
+ from John H. DuBois III.
+
+2002-09-15 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * Makefile.in, /man/{raw2tiff.1, Makefile.in, libtiff.3}: Added
+ manual page for raw2tiff(1) tool.
+
+2002-09-12 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * /libtiff/{tiffio.h, tif_dir.h}: TIFFDataWidth() declaration moved to
+ the tiffio.h header file.
+
+ * Makefile.in, /man/{TIFFDataWidth.3t, Makefile.in, libtiff.3}: Added
+ manual page for TIFFDataWidth() function
+
+2002-09-08 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dirread.c: Expand v[2] to v[4] in TIFFFetchShortPair()
+ as per http://bugzilla.remotesensing.org/show_bug.cgi?id=196.
+
+ * tools/tiff2ps.c: Don't emit BeginData/EndData DSC comments
+ since we are unable to properly include the amount to skip.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=80
+
+2002-09-02 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * /libtiff/tif_dirread.c: Fixed problem with SBYTE type data fetching
+ in TIFFFetchByteArray(). Problem described at
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=52
+
+2002-08-22 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * /libtiff/tif_dirinfo.c: Further additions to free custom fields
+ in _TIFFSetupFieldInfo() function.
+ See http://bugzilla.remotesensing.org/show_bug.cgi?id=169 for details.
+
+ * /libtiff/tif_lzw.c: Additional consistency checking added in
+ LZWDecode() and LZWDecodeCompat().
+ Fixes http://bugzilla.remotesensing.org/show_bug.cgi?id=190
+ and http://bugzilla.remotesensing.org/show_bug.cgi?id=100
+
+ * /libtiff/tif_lzw.c:
+ Added check for valid code lengths in LZWDecode() and
+ LZWDecodeCompat(). Fixes
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=115
+
+2002-08-16 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * /libtiff/{Makefile.vc, libtiff.def}:
+ Missed declarations added.
+
+2002-08-15 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tif_getimage.c: Ensure that TIFFRGBAImageBegin() returns the
+ return code from the underlying pick function.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=177
+
+ * tif_dir.h: changed FIELD_CODEC to 66 from 64 to avoid overlap
+ with FIELD_CUSTOM as mentioned in bug 169.
+
+ * tif_close.c: added logic to free dynamically created anonymous
+ field definitions to correct a small memory leak.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=169
+
+2002-08-10 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * /tools/{raw2tiff.c, Makefile.in, Makefile.lcc, Makefile.vc}:
+ New tool: raw2tiff --- raw images to TIFF converter. No manual page yet.
+
+2002-07-31 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_jpeg.c: Fixed problem with setting of nrows in
+ JPEGDecode() as per bugzilla bug (issue 1):
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=129
+
+ * libtiff/{tif_jpeg.c,tif_strip.c,tif_print.c}: Hacked tif_jpeg.c to
+ fetch TIFFTAG_YCBCRSUBSAMPLING from the jpeg data stream if it isn't
+ present in the tiff tags.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=168
+
+ * libtiff/tif_read.c, libtiff/tif_write.c: TIFFReadScanline() and
+ TIFFWriteScanline() now set tif_row explicitly in case the codec has
+ fooled with the value.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=129
+
+2002-06-22 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * /tools/tiff2ps.c: Added workaround for some software that may crash
+ when last strip of image contains fewer number of scanlines than
+ specified by the `/Height' variable. See
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=164
+ for explanation.
+
+2002-06-21 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiff2ps, man/tiff2ps.1: New functionality for tiff2ps utility:
+ splitting long images in several pages. See
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=142 for explanation.
+ Patch granted by John Williams <williams@morinda.com>.
+
+2002-06-11 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/contrib/win95: renamed to contrib/win_dib. Added new
+ Tiffile.cpp example of converting TIFF files into a DIB on Win32.
+ This one is described in:
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=143
+
+ * libtiff/tif_ojpeg.c: Major upgrade from Scott. See details at:
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=156
+
+2002-05-10 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiff2ps: New commandline switches to override resolution
+ units obtained from the input file. Closes
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=131
+
+2002-04-26 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/libtiff.def: Added missed declaration.
+
+2002-04-22 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/fax2tiff.c: Updated to reflect latest changes in libtiff.
+ Closes http://bugzilla.remotesensing.org/show_bug.cgi?id=125
+
+2002-04-20 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_open.c: Pointers to custom procedures
+ in TIFFClientOpen() are checked to be not NULL-pointers.
+
+2002-04-18 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/libtiff.def: Added missed declarations.
+
+ * libtiff/tif_pixarlog.c: Updated for using tif_tagmethods structure.
+
+2002-04-16 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_lzw.c: Additional checks for data integrity introduced.
+ Should finally close
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=100
+
+2002-04-10 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/tiff2ps: Division by zero fixed.
+ Closes http://bugzilla.remotesensing.org/show_bug.cgi?id=88
+
+2002-04-09 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/: tif_dirwrite.c, tif_write.c, tiffio.h:
+ TIFFCheckpointDirectory() routine added.
+ Closes http://bugzilla.remotesensing.org/show_bug.cgi?id=124
+
+ * man/: TIFFWriteDirectory.3t, Makefile.in: Added description
+ for the new function.
+
+2002-04-08 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/: tif_codec.c, tif_compress.c, tiffiop.h: Introduced
+ additional members tif->tif_decodestatus and tif->tif_encodestatus
+ for correct handling of unconfigured codecs (we should not try to read
+ data or to define data size without correct codecs).
+
+ * libtiff/tif_getimage.c: The way of codecs checking in TIFFRGBAImageOK
+ changed. Now it has used tif->tif_decodestatus and
+ tif->tif_encodestatus.
+ Should fix http://bugzilla.remotesensing.org/show_bug.cgi?id=119 (in
+ case of __cvs_8.tif test image).
+
+ * libtiff/: tif_dirinfo.c, tif_dirread.c: Somebody makes a bug in
+ tif_dirread.c when TIFFCreateAnonFieldInfo was introduced.
+ Closes http://bugzilla.remotesensing.org/show_bug.cgi?id=119 in case
+ of _cvs_00000-00.tif, _cvs_00000-01.tif and _cvs_00000-02.tif.
+
+2002-04-04 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/: tif_lzw.c: Assertions in LZWDecode and LZWDecodeCompat
+ replaced by warnings. Now libtiff should read corrupted LZW-compressed
+ files by skipping bad strips.
+ Closes http://bugzilla.remotesensing.org/show_bug.cgi?id=100
+
+2002-04-03 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dirwrite.c: Removed some dead code.
+
+ * libtiff/*: Cleanup some warnings.
+
+ * libtiff/tif_dir.c: Fixed bug with count returned by TIFFGetField()
+ for variable length FIELD_CUSTOM values. Was int * but should be
+ u_short *.
+
+2002-04-01 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * tools/: tifcp.c: Added support for 'Orientation' tag in tiffcp
+ utility (at cpStripToTile routine).
+
+2002-03-27 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tif_dirread.c: avoid div-by-zero if rowbytes is zero in chop func.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=111
+
+ * tif_print.c: Fixed so that ASCII FIELD_CUSTOM values with
+ passcount set FALSE can be printed (such as TIFFTAG_SOFTWARE).
+
+ * libtiff/tif_dir.c,tif_dirinfo.c,tif_dir.h,tif_ojpeg.c: modified so
+ that TIFFTAG_SOFTWARE uses FIELD_CUSTOM as an example.
+
+2002-03-26 Dwight Kelly <dbmalloc@remotesensing.org>
+
+ * libtiff/: tiff.h, tif_dir.c, tif_dir.h, tif_dirinfo.c, tif_dirread.c,
+ tif_dirwrite.c: Added get/put code for new tag XMLPACKET as defined
+ in Adobe XMP Technote. Added missing INKSET tag value from TIFF 6.0 spec
+ INKSET_MULTIINK (=2). Added missing tags from Adobe TIFF technotes:
+ CLIPPATH, XCLIPPATHUNITS, YCLIPPATHUNITS, OPIIMAGEID, OPIPROXY and
+ INDEXED. Added PHOTOMETRIC tag value from TIFF technote 4 ICCLAB (=9).
+
+2002-03-26 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/: tif_getimage.c: TIFFReadRGBAStrip and TIFFReadRGBATile
+ now also uses TIFFRGBAImageOK before reading. This is additional fix
+ for http://bugzilla.remotesensing.org/show_bug.cgi?id=110
+
+2002-03-25 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/: tif_getimage.c: Additional check for supported
+ codecs added in TIFFRGBAImageOK and TIFFReadRGBAImage now uses
+ TIFFRGBAImageOK before reading.
+ Closes http://bugzilla.remotesensing.org/show_bug.cgi?id=110
+
+2002-03-15 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/: tif_dir.c, tif_dir.h, tif_dirinfo.c, tif_dirread.c,
+ tif_dirwrite.c: Added routine TIFFDataWidth for detrmining
+ TIFFDataType sizes instead of working with tiffDataWidth array
+ directly. Should prevent out-of-borders bugs in case of unknown or
+ broken data types. EstimateStripByteCounts routine modified, so it
+ won't work when tags with unknown sizes founded.
+ Closes http://bugzilla.remotesensing.org/show_bug.cgi?id=109
+
+2002-03-13 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/tif_getimage.c: Added support for correct handling
+ `Orientation' tag in gtTileContig. Should be added in other gt*
+ functions as well, but I have not images for testing yet. Partially
+ resolves http://bugzilla.remotesensing.org/show_bug.cgi?id=23
+
+2002-03-10 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/: tif_dirinfo.c, tif_dirwrite.c: Added possibility to
+ read broken TIFFs with LONG type used for TIFFTAG_COMPRESSION,
+ TIFFTAG_BITSPERSAMPLE, TIFFTAG_PHOTOMETRIC. Closes
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=99
+
+2002-03-08 Andrey Kiselev <dron@ak4719.spb.edu>
+
+ * libtiff/Makefile.in, tools/Makefile.in: Shared library will not
+ be stripped when installing, utility binaries will do. Closes
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=93
+
+2002-02-28 Frank Warmerdam <warmerdam@pobox.com>
+
+ * man/TIFFGetField: fixed type of TIFFTAG_COPYRIGHT.
+
+ * man/libtiff.3t: added copyright tag info.
+
+2002-02-11 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/{tiff.h,tif_fax3.c}: Add support for __arch64__.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=94
+
+ * man/Makefile.in: Patch DESTDIR handling
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=95
+
+ * configure: OpenBSD changes for Sparc64 and DSO version.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=96
+
+2002-02-05 Frank Warmerdam <warmerdam@pobox.com>
+
+ * config.site/configure: added support for OJPEG=yes option to enable
+ OJPEG support from config.site.
+
+2002-01-27 Frank Warmerdam <warmerdam@pobox.com>
+
+ * html/document.html: fixed links for TIFf 6 docs.
+
+2002-01-18 Frank Warmerdam <warmerdam@pobox.com>
+
+ * config.guess, config.sub: Updated from ftp.gnu.org/pub/config.
+
+ * libtiff/tif_read.c: Fixed TIFFReadEncodedStrip() to fail if the
+ decodestrip function returns anything not greater than zero as per
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=97
+
+ * configure: Modify CheckForBigEndian so it can work in a cross
+ compiled situation.
+
+2002-01-16 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tools/tiffdump.c: include TIFFTAG_JPEGTABLES in tag list.
+
+ * tools/tiffset.c: fix bug in error reporting.
+
+ * tools/tiffcp.c: fix several warnings that show up with -Wall.
+
+2002-01-04 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_jpeg.c: fixed computation of segment_width for
+ tiles files to avoid error about it not matching the
+ cinfo.d.image_width values ("JPEGPreDecode: Improper JPEG strip/tile
+ size.") for ITIFF files. Apparently the problem was incorporated since
+ 3.5.5, presumably during the OJPEG/JPEG work recently.
+
+2001-12-15 Frank Warmerdam <warmerdam@pobox.com>
+
+ * configure, libtiff/Makefile.in: Changes for building on MacOS 10.1.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=94
+
+ * libtiff/tif_getimage.c: If DEFAULT_EXTRASAMPLE_AS_ALPHA is 1
+ (defined in tiffconf.h - 1 by default) then the RGBA interface
+ will assume that a fourth extra sample is ASSOCALPHA if the
+ EXTRASAMPLE value isn't set for it. This changes the behaviour of
+ the library, but makes it work better with RGBA files produced by
+ lots of applications that don't mark the alpha values properly.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=93
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=65
+
+2001-12-12 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_jpeg.c: allow jpeg data stream sampling values to
+ override those from tiff directory. This makes this work with
+ ImageGear generated files.
+
+2001-12-07 Frank Warmerdam <warmerdam@pobox.com>
+
+ * html/Makefile.in: added missing images per bug 92.
+
+ * port/Makefile.in: fixed clean target per bug 92.
+
+2001-11-28 Frank Warmerdam <warmerdam@pobox.com>
+
+ * Reissue 3.5.7 release.
+
+ * libtiff/mkversion.c: Fix output of TIFF_VERSION to be
+ YYYYMMDD so that it is increasing over time.
+
+ * Makefile.in: Ensure that tiffvers.h is regenerated in the
+ make release target.
+
+ * Makefile.in: added libtiff/tiffvers.h to the release file list.
+
+2001-11-23 Frank Warmerdam <warmerdam@pobox.com>
+
+ * added html/v3.5.7.html, updated html/index.html.
+
+ * Makefile.in: added contrib/addtiffo/tif_ovrcache.{c,h}.
+
+2001-11-15 Frank Warmerdam <warmerdam@pobox.com>
+
+ * configure: fixed test for -lm.
+
+2001-11-02 Frank Warmerdam <warmerdam@pobox.com>
+
+ * Added PHOTOMETRIC_ITULAB as per bug 90.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=90
+
+2001-10-10 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tiff.h: I have created COMPRESSION_CCITT_T4,
+ COMPRESSION_CCITT_T6, TIFFTAG_T4OPTIONS and TIFFTAG_T6OPTIONS aliases
+ in keeping with TIFF 6.0 standard in tiff.h
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=83
+
+2001-09-26 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dirwrite.c: added TIFFRewriteDirectory() function.
+ Updated TIFFWriteDirectory man page to include TIFFRewriteDirectory.
+
+2001-09-24 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_lzw.c: Avoid MS VC++ 5.0 optimization bug.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=78
+
+ * libtiff/tif_lzw.c: added dummy LZWSetupEncode() to report an
+ error about LZW not being available.
+
+ * libtiff/tif_dir.c: propagate failure to initialize compression
+ back from TIFFSetField() as an error status, so applications can
+ detect failure.
+
+ * libtiff/tif_dir.c: removed the auto replacement of
+ COMPRESSION_LZW with COMPRESSION_NONE in _TIFFVSetField().
+
+ * Removed Makefile, tools/Makefile, port/install.sh, man/Makefile
+ from CVS as they are all supposed to be auto-generated by configure.
+
+2001-09-22 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_ojpeg.c: new update from Scott.
+
+2001-09-09 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtif/tif_fax3.c: Removed #ifdef PURIFY logic, and modified to
+ always use the "safe" version, even if there is a very slight
+ cost in performance.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=54
+
+ * libtiff/Makefile.in: Fixed @DSOSUB_VERSION to be @DSOSUF_VERSION@
+ in two places.
+
+ * libtiff/tif_getimage.c: Fixed problem with reading strips or
+ tiles that don't start on a tile boundary. Fix contributed by
+ Josep Vallverdu (from HP), and further described in bug 47.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=47
+
+ * tools/tiff2ps.c: added OJPEG YCbCr to RGB support.
+
+ * libtiff/tif_ojpeg.c: Applied substantial patch from Scott.
+
+2001-09-06 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_packbits.c: fixed memory overrun error.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=77
+
+2001-08-31 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_getimage.c: relax handling of contig case where
+ there are extra samples that are supposed to be ignored. This
+ should now work for 8bit greyscale or paletted images.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=75
+
+2001-08-28 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_getimage.c: Don't complain for CMYK (separated)
+ images with more than four samples per pixel. See:
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=73
+
+2001-08-10 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_getimage.c: Use memmove() instead of TIFFmemcpy()
+ in TIFFReadRGBATile() to avoid issues in cases of overlapping
+ buffers. See Bug 69 in Bugzilla.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=69
+
+ * tools/tiff2rgba.c: fixed getopt() call so that -b works again.
+
+2001-08-09 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tiff.h, libtiff/tif_fax3.c: added check for __LP64__
+ when checking for 64 bit architectures as per bugzilla bug 67.
+
+2001-07-27 Frank Warmerdam <warmerdam@pobox.com>
+
+ * man/Makefile.in: add TIFFClientOpen link as per debian submitted
+ bug 66.
+
+2001-07-20 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_jpeg.c: Define HAVE_BOOLEAN on windows if RPCNDR.H
+ has been included.
+
+2001-07-19 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_open.c: Seek back to zero after failed read,
+ before writing header.
+
+2001-07-18 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_ojpeg.c: updates from Scott. Handles colors
+ much better. Now depends on having patched libjpeg as per
+ patch in contrib/ojpeg/*.
+
+2001-07-17 Frank Warmerdam <warmerdam@pobox.com>
+
+ * */Makefile.in: added DESTDIR support.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=60
+
+2001-07-16 Frank Warmerdam <warmerdam@pobox.com>
+
+ * configure, libtiff/Makefile.in: applied OpenBSD patches
+ as per:
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=61
+
+2001-06-28 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_getimage.c: Fixed so that failure is properly
+ reported by gtTileContig, gtStripContig, gtTileSeparate and
+ gtStripSeparate.
+
+ See http://bugzilla.remotesensing.org/show_bug.cgi?id=51
+
+ * tiffcmp.c: Fixed multi samples per pixel support for ContigCompare.
+ Updated bug section of tiffcmp.1 to note tiled file issues.
+
+ See http://bugzilla.remotesensing.org/show_bug.cgi?id=53
+
+2001-06-22 Frank Warmerdam <warmerdam@pobox.com>
+
+ * configure: Changes for DSO generation on AIX provided by
+ John Marquart <jomarqua@indiana.edu>.
+
+ * configure, libtiff/Makeifle.in: Modified to build DSOs properly
+ on Darwin thanks to Robert Krajewski (rpk@alum.mit.edu) and
+ Keisuke Fujii (fujiik@jlcuxf.kek.jp).
+
+2001-06-13 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tools/tiff2rgba.c: added -n flag to avoid emitting alpha component.
+
+ * man/tiff2rgba.1: new
+
+2001-05-22 Frank Warmerdam <warmerdam@pobox.com>
+
+ * Added tiffset and tif_ojpeg to the dist lists in Makefile.in.
+
+2001-05-13 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tools/thumbnail.c: changed default output compression
+ to packbits from LZW since LZW isn't generally available.
+
+2001-05-12 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_ojpeg.c: New.
+ libtiff/tif_jpeg.c, tiffconf.h, tif_getimage.c: changes related
+ to OJPEG support.
+
+ Scott Marovich <marovich@hpl.hp.com> supplied OJPEG support.
+
+2001-05-11 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tiff.h: removed, it duplicates libtiff/tiff.h.
+
+2001-05-08 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dirinfo.c: moved pixar and copyright flags to
+ ensure everything is in order.
+
+ * libtiff/libtiff.def: added TIFFCreateDirectory and
+ TIFFDefaultStripSize as per:
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=46
+
+2001-05-02 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dirinfo.c: Modified the TIFF_BYTE definition for
+ TIFFTAG_PHOTOSHOP to use a writecount of TIFF_VARIABLE2 (-3) to
+ force use of uint32 counts instead of short counts.
+
+ * libtiff/tif_dirwrite.c: Added support for TIFF_VARIABLE2 in the
+ case of writing TIFF_BYTE/TIFF_SBYTE fields.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=43
+
+2001-05-01 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_dirinfo.c: removed duplicate TIFFTAG_PHOTOSHOP as per
+ bug report http://bugzilla.remotesensing.org/show_bug.cgi?id=44
+
+2001-04-05 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tiffio.h: removed C++ style comment.
+
+ * configure: fixed up SCRIPT_SH/SHELL handling.
+
+ * Makefile.in: Fixed SCRIPT_SH/SHELL handling.
+
+ * config.guess: documented more variables as per bug 40.
+
+2001-04-03 Frank Warmerdam <warmerdam@pobox.com>
+
+ * configure, *Makefile.in: Various changes to improve configuration
+ for HP/UX specifically, and also in general. They include:
+ - Try to handle /usr/bin/sh instead of /bin/sh where necessary.
+ - Upgrade to HP/UX 10.x+ compiler, linker and dso options.
+ - Fixed mmap() test to avoid MMAP_FIXED ... it isn't available on HP
+ - Use -${MAKEFLAGS} in sub makes from makefiles.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=40
+
+2001-04-02 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tiff.h: Applied hac to try and resolve the problem
+ with the inttypes.h include file on AIX.
+
+ See http://bugzilla.remotesensing.org/show_bug.cgi?id=39
+
+ * VERSION: update to 3.5.7 beta in preparation for release.
+
+ * configure/config.site: modified to check if -lm is needed for
+ MACHDEPLIBS if not supplied by config.site. Needed for Darwin.
+
+ * config.guess: updated wholesale to an FSF version apparently
+ from 1998 (as opposed to 1994). This is mainly inspired by
+ providing for MacOS X support.
+
+2001-03-29 Frank Warmerdam <warmerdam@pobox.com>
+
+ * configure, Makefile.in, etc: added support for OPTIMIZER being
+ set from config.site.
+
+2001-03-28 Frank Warmerdam <warmerdam@pobox.com>
+
+ * fax2ps.c: Helge (libtiff at oldach.net) submitted fix:
+
+ Here's a fix for fax2ps that corrects behaviour for non-Letter paper
+ sizes. It fixes two problems:
+
+ Without scaling (-S) the fax is now centered on the page size specified
+ with -H and/or -W. Before, fax2ps was using an obscure and practically
+ useless algorithm to allocate the image relative to Letter sized paper
+ which sometime sled to useless whitespace on the paper, while at the
+ same time cutting of the faxes printable area at the opposite border.
+
+ Second, scaling now preserves aspect ratio, which makes unusual faxes
+ (in particular short ones) print properly.
+
+ See http://bugzilla.remotesensing.org/show_bug.cgi?id=35
+
+ * tiff2ps.c/tiff2ps.1: Substantial changes to tiff2ps by
+ Bruce A. Mallett. See check message for detailed information
+ on all the changes, including a faster encoder, fixes for level
+ 2 PostScript, and support for the imagemask operator.
+
+2001-03-27 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tiffio.h: Changed "#if LOGLUV_PUBLIC" to
+ "#ifdef LOGLUV_PUBLIC" so it will work with VisualAge on AIX.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=39
+
+2001-03-16 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tif_dirinfo.c: moved definition of copyright tag in field list.
+ Apparently they have to be in sorted order by tag id.
+
+2001-03-13 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tif_getimage.c: Added support for 16bit minisblack/miniswhite
+ images in RGBA interface.
+
+2001-03-02 Frank Warmerdam <warmerdam@pobox.com>
+
+ * Added TIFFTAG_COPYRIGHT support.
+
+2001-02-19 Frank Warmerdam <warmerdam@pobox.com>
+
+ * Brent Roman contributed updated tiffcp utility (and tiffcp.1)
+ with support for extracting subimages with the ,n syntax, and also
+ adding the -b bias removal flag.
+
+2001-02-16 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/libtiff.def: Brent Roman submitted new version adding
+ several missing entry points.
+
+ * libtiff/tif_dirinfo.c: don't declare tiffFieldInfo static on VMS.
+ Some sort of weird VMS thing.
+
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=31
+
+ * tif_luv.c/tiff.h/tiffio.h:
+ New version of TIFF LogLuv (SGILOG) modules contributed by Greg Ward
+ (greg@shutterfly.com). He writes:
+
+ 1) I improved the gamut-mapping function in tif_luv.c for imaginary
+ colors, because some images were being super-saturated on the input
+ side and this resulted in some strange color shifts in the output.
+
+ 2) I added a psuedotag in tiff.h to control random dithering during
+ LogLuv encoding. This is turned off by default for 32-bit LogLuv and
+ on for 24-bit LogLuv output. Dithering improves the average color
+ accuracy over the image.
+
+ 3) I added a #define for LOG_LUV_PUBLIC, which is enabled by default in
+ tiffio.h, to expose internal routines for converting between LogLuv and
+ XYZ coordinates. This is helpful for writing more efficient,
+ specialized conversion routines, especially for reading LogLuv files.
+
+ Changes applied with minor edits.
+
+2001-01-23 Frank Warmerdam <warmerdam@pobox.com>
+
+ * tif_fax3.c: keep rw_mode flag internal to fax3 state to remember
+ whether we are encoding or decoding. This is to ensure graceful
+ recovery if TIFFClientOpen() discovers an attempt to open a compressed
+ file for "r+" access, and subsequently close it, as it resets the
+ tif_mode flag to O_RDONLY in this case to avoid writes, confusing the
+ compressor's concept of whether it is in encode or decode mode.
+
+2001-01-08 Mike Welles <mike@bangstate.com>
+
+ * Makefile.in: Now cleaning up after itself after creating the .tar.gz and .zip
+
+2001-01-07 Frank Warmerdam <warmerdam@pobox.com>
+
+ * html/libtiff.html: Fixed arguments in example for TIFFRGBAImageGet()
+ as per bug report by Patrick Connor.
+
+2000-12-28 Frank Warmerdam <warmerdam@pobox.com>
+
+ * Added RELEASE-DATE file to release file list.
+
+ * Fixed libtiff/makefile.vc to make tiffvers.h not version.h.
+
+2000-12-22 Mike Welles <mike@bangstate.com>
+ * added link to CVS mirror from index.html
+
+ * updated html/internals.html to note that LZW compression is
+ not supported by default.
+
+2000-12-22 Frank Warmerdam <warmerdam@pobox.com>
+
+ * updated html/libtiff.html to not point at Niles' old JPL web site
+ for the man pages, point at www.libtiff.org.
+
+2000-12-21 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/tif_apple.c: Applied "Carbon" support patches supplied by
+ Leonard Rosenthol <leonardr@lazerware.com>. May interfere
+ with correct building on older systems. If so, please let me know.
+
+2000-12-19 Mike Welles <mike@bangsate.com>
+
+ * Took out LZW Encoding from tif_lzw.c
+
+ * Created HOWTO-RELEASE
+
+ * Created html/v3.5.6.html
+
+ * updated index.html
+
+2000-12-01 Frank Warmerdam <warmerdam@pobox.com>
+
+ * Added patches for EOFB support in tif_fax3.c and tif_fax3.h.
+ Patches supplied by Frank Cringle <fdc@cliwe.ping.de>
+ Example file at: ftp://ftp.remotesensing.org/pub/libtiff/eofb_396.tif
+
+2000-11-24 Frank Warmerdam <warmerdam@pobox.com>
+
+ * libtiff/Makefile.in: Added an installPrivateHdrs and install-private
+ target so that the private headers required by libgeotiff can be
+ installed with the others. They are not installed by default.
+
+ * libtiff/Makefile.in: Added @MACHLIBDEPS@ to LINUXdso and GNULDdso
+ targets so libtiff.so will be built with an explicit dependency
+ on libm.so.
+
+ * libtiff/Makefile.in: Use softlinks to link libtiff.so.3 to
+ libtiff.so.3.5.5.
+
+ * libtiff/Makefile.in & configure: Remove all references to the ALPHA
+ file, or ALPHA version logic. Added stuff about DIST_POINT in
+ place of DIST_TYPE and the alpha release number stuff.
+
+2000-11-22 Frank Warmerdam <warmerdam@pobox.com>
+
+ * I have applied a patch from Steffen Moeller <moeller@ebi.ac.uk> to
+ the configure script so that it now accepts the --prefix, and
+ --exec-prefix directives.
+
+2000-11-13 Frank Warmerdam <warmerda@cs46980-c>
+
+ * I have made a variety of modifications in an effort to ensure the
+ TIFFLIB_VERSION macro is automatically generated from the RELEASE-DATE
+ file which seems to be updated regularly.
+
+ o mkversion.c now reads RELEASE-DATE and emits TIFFLIB_VERSION in
+ version include file.
+ o renamed version.h to tiffvers.h because we now have to install it
+ with the public libtiff include files.
+ o include tiffvers.h in tiffio.h.
+ o updated tif_version.c to use tiffvers.h.
+ o Updated Makefile.in accordingly.
+
+ * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=25
+ I have updated the win32 detection rules in tiffcomp.h.
+
+2000-10-20 Frank Warmerdam <warmerda@cs46980-c>
+
+ * tif_getimage.c: Fixed RGBA translation for YCbCr images for which
+ the strip/tile width and height aren't multiples of the sampling size.
+ See http://bugzilla.remotesensing.org/show_bug.cgi?id=20
+ Some patches from Rick LaMont of Dot C Software.
+
+ * Modified tif_packbits.c encoder to avoid compressing more
+ data than provided if rowsize doesn't factor into provided data
+ (such as occurs for YCbCr).
+
+2000-10-19 Frank Warmerdam <warmerda@cs46980-c>
+
+ * tools/rgb2ycbcr.c: fixed output strip size to account for vertical
+ roundup if rows_per_strip not a multiple of vertical sample size.
+
+2000-10-16 Frank Warmerdam <warmerda@cs46980-c>
+
+ * tif_dir.c: Clear TIFF_ISTILED flag in TIFFDefaultDirectory
+ as per http://bugzilla.remotesensing.org/show_bug.cgi?id=18
+ from vandrove@vc.cvut.cz.
+
+ * Modified tif_packbits.c decoding to avoid overrunning the
+ output buffer, and to issue a warning if data needs to be
+ discarded. See http://bugzilla.remotesensing.org/show_bug.cgi?id=18
+
+2000-10-12 Frank Warmerdam <warmerda@cs46980-c>
+
+ * Modified tiff2bw to ensure portions add to 100%, and that
+ white is properly recovered.
+
+ See bug http://bugzilla.remotesensing.org/show_bug.cgi?id=15
+ Patch c/o Stanislav Brabec <utx@penguin.cz>
+
+2000-09-30 Frank Warmerdam <warmerda@cs46980-c>
+
+ * Modified TIFFClientOpen() to emit an error on an attempt to
+ open a comperessed file for update (O_RDWR/r+) access. This is
+ because the compressor/decompressor code gets very confused when
+ the mode is O_RDWR, assuming this means writing only. See
+ bug http://bugzilla.remotesensing.org/show_bug.cgi?id=13
+
+2000-09-27 Frank Warmerdam <warmerda@cs46980-c>
+
+ * Added GNULDdso target an`d switched linux and freebsd to use it.
+
+2000-09-26 Frank Warmerdam <warmerda@cs46980-c>
+
+ * Applied patch for 0x0000 sequences in tif_fax3.h's definition
+ of EXPAND1D() as per bug 11 (from Roman).
+
+2000-09-25 Frank Warmerdam <warmerda@cs46980-c>
+ * Fixed tiffcomp.h to avoid win32 stuff if unix #defined, to improve
+ cygwin compatibility.
+
+ * Applied patch from Roman Shpount to tif_fax3.c. This seems to
+ be a proper fix to the buffer sizing problem. See
+ http://bugzilla.remotesensing.org/show_bug.cgi?id=11
+
+ * Fixed tif_getimage.c to fix overrun bug with YCbCr images without
+ downsampling. http://bugzilla.remotesensing.org/show_bug.cgi?id=10
+ Thanks to Nick Lamb <njl98r@ecs.soton.ac.uk> for reporting the
+ bug and proving the patch.
+
+2000-09-18 Frank Warmerdam <warmerda@cs46980-c>
+
+ * Fixed tif_jpeg.c so avoid destroying the decompressor before
+ we are done access data thanks to bug report from:
+ Michael Eckstein <eckstein@gepro.cz>.
+
+ * Reverted tif_flush change.
+
+2000-09-14 Frank Warmerdam <warmerda@cs46980-c>
+
+ * tif_flush.c: Changed so that TIFFFlushData() doesn't return an
+ error when TIFF_BEENWRITING is not set. This ensures that the
+ directory contents can still be flushed by TIFFFlush().
+
+2000-08-14 Frank Warmerdam <warmerda@rommel.atlsci.com>
+
+ * tif_open.c: Don't set MMAP for O_RDWR files.
+
+ * tif_open.c: Set STRIPCHOP_DEFAULT for O_RDWR as well as O_RDONLY
+ so that files opened for update can be strip chopped too.
+
+ * tif_read.c: fixed up bug with files missing rowsperstrip and
+ the strips per separation fix done a few weeks ago.
+
+2000-07-17 Frank Warmerdam <warmerda@cs46980-c>
+
+ * Tentatively added support for SAMPLEFORMAT_COMPLEXIEEEFP, and
+ SAMPLEFORMAT_COMPLEXINT.
+
+2000-07-13 Mike Welles <mike@onshore.com>
+
+ * index.html, bugs.html: added bugzilla info.
+
+2000-07-12 Frank Warmerdam <warmerda@rommel.atlsci.com>
+
+ * tif_read.c: fix subtle bug with determining the number of
+ rows for strips that are the last strip in a separation but
+ not the last strip of all in TIFFReadEncodedStrip().
+
+ * Applied 16/32 bit fix to tif_fax3.c. Fix supplied by
+ Peter Skarpetis <peters@serendipity-software.com.au>
+
+2000-06-15 Frank Warmerdam <warmerda@rommel.atlsci.com>
+
+ * Modified tiffio.h logic with regard to including windows.h. It
+ won't include it when building with __CYGWIN__.
+
+2000-05-11 Frank Warmerdam <warmerda@cs46980-c>
+
+ * README: update to mention www.libtiff.org, don't list Sam's old
+ email address.
+
+ * configure: Fixed DSO test for Linux as per patch from
+ Jan Van Buggenhout <chipzz@Ace.ULYSSIS.Student.KULeuven.Ac.Be>.
+
+2000-04-21 Frank Warmerdam <warmerda@rommel.atlsci.com>
+
+ * libtiff/tif_dirread.c: Don't use estimate strip byte count for
+ one tile/strip images with an offset, and byte count of zero. These
+ could be "unpopulated" images.
+
+2000-04-18 Frank Warmerdam <warmerda@rommel.atlsci.com>
+
+ * contrib/addtiffo: Added "averaging" resampling option.
+
+ * tools/tiffsplit.c: Copy TIFFTAG_SAMPLEFORMAT.
+
+Tue Apr 18 16:18:08 2000 Frank Warmerdam <warmerda@esabot.atlsci.com>
+
+ * tools/Makefile.in: Modified to install properly on SGI.
+
+2000-04-12 Mike Welles <mike@onshore.com>
+ * configure: Fixed stupid mistake in libc6 test on Linux
+
+2000-04-04 Mike Welles <mike@onshore.com>
+ * tif_win32.c: Applied patch to fix overreads and ovverwrites
+ caught by BoundsChecker. From Arvan Pritchard
+ <arvan.pritchard@infomatix.co.uk> (untested).
+
+ * tif_getimage.c: Applied patch to silence VC6 warnings. From
+ Arvan Pritchard <arvan.pritchard@informatix.co.uk>
+
+ * tif_lzw.c: Applied patch to silence VC6 warnings. From
+ Arvan Pritchard <arvan.pritchard@informatix.co.uk>
+
+2000-03-28 Frank Warmerdam <warmerda@cs46980-c>
+
+ * Added contrib/stream (stream io) code submitted by Avi Bleiweiss.
+
+2000-03-28 Frank Warmerdam <warmerda@cs46980-c> *** 3.5.5 release ***
+
+ * fax2ps: Fixed mixup of width and height in bounding box statement
+ as per submission by Nalin Dahyabhai <nalin@redhat.com>.
+
+2000-03-27 Mike Welles <mike@onshore.com>
+
+ * fax2ps: Modified printruns to take uint32 instead of uint16.
+ Patch courtesy of Bernt Herd <herd@herdsoft.com>
+
+2000-03-20 Mike Welles <mike@onshore.com>
+
+ * configure: added test for libc6 for linux targets. Bug reported by
+ Stanislav Brabec <utx@k332.feld.cvut.cz>
+
+ * Added 3.5 docs to html/Makefile.in.
+ Thanks to Stanislav Brabec <utx@k332.feld.cvut.cz>
+
+ * configure: fixed bugs in sed scripts
+ (applied sed script s:/@:s;@:;s:/s;;:;: to configure).
+ fix submitted to Stanislav Brabec <utx@k332.feld.cvut.cz>
+
+ * tools/iptcutil was not in files list, and wasn't being
+ added to tar archive. Updated Makefile.in.
+
+2000-03-17 Frank Warmerdam <warmerda@cs46980-c>
+
+ * tif_fax3.c: Fixed serious bug introduced during the uint16->uint32
+ conversion for the run arrays.
+
+2000-03-03 Frank Warmerdam <warmerda@cs46980-c.mtnk1.on.wave.home.com>
+
+ * Set td_sampleformat default to SAMPLEFORMAT_UINT instead of
+ SAMPLEFORMAT_VOID in TIFFDefaultDirectory() in tif_dir.c.
+
+2000-03-02 Frank Warmerdam <warmerda@cs46980-c.mtnk1.on.wave.home.com>
+
+ * Added "GetDefaulted" support for TIFFTAG_SAMPLEFORMAT in tif_aux.c.
+
+ * Patched tif_fax3.c so that dsp->runs is allocated a bit bigger
+ to avoid overruns encountered with frle_bug.tif.
+
+Tue Feb 15 22:01:05 2000 Frank Warmerdam <warmerda@gdal.velocet.ca>
+
+ * Fixed tools/tiffcmp so that stopondiff testing works.
+ Patch care of Joseph Orost <joe@sanskrit.lz.att.com>.
+
+2000-01-28 <warmerda@CS46980-B>
+
+ * Modified tif_unix.c to support 2-4GB seeks if USE_64BIT_API is
+ set to 1, and added default (off) setting in tiffconf.h. This
+ should eventually be set by the configure script somehow.
+
+ The original work on all these 2-4GB changes was done by
+ Peter Smith (psmith@creo.com).
+
+ * Modified tif_win32.c to support 2-4GB seeks.
+
+ * tentatively changed toff_t to be unsigned instead of signed to
+ facilitate support for 2-4GB files.
+
+ * Updated a variety of files to use toff_t. Fixed some mixups
+ between toff_t and tsize_t.
+
+Fri Jan 28 10:13:49 2000 Frank Warmerdam <warmerda@gdal.velocet.ca>
+
+ * Largely reimplemented contrib/addtiffo to avoid temp files,
+ updating the TIFF file in place. Fixed a few other bugs to.
+
+ * Set tif_rawdatasize to zero when freeing raw data buffer in
+ TIFFWriteDirectory().
+
+ * Enabled "REWRITE_HACK" in tif_write.c by default.
+
+ * Fix bug in tif_write.c when switching between reading one directory
+ and writing to another.
+
+ * Made TIFFWriteCheck() public, and added TIFFCreateDirectory()
+
+Wed Jan 5 12:37:48 2000 Frank Warmerdam <warmerda@gdal.velocet.ca>
+
+ * Added TIFFmemory(3t) functions to libtiff.def.
+
+Tue Jan 4 13:39:00 2000 Frank Warmerdam <warmerda@gdal.velocet.ca>
+
+ * Added libtiff/libtiff.def to TIFFILES distribution list.
+
+Mon Dec 27 12:13:39 EST 1999 Mike Welles <mike@onshore.com>
+
+ * Created lzw compression kit, as a new module (libtiff-lzw-compression-kit).
+
+ * Altered descriptions in tools to reflect "by default" lzw not supported
+
+ * Updated index.html to note lzw compression kit.
+
+Tue Dec 21 14:01:51 1999 Frank Warmerdam <warmerda@gdal.velocet.ca>
+
+ * Added fax3sm_winnt.c to distribution list in Makefile.in.
+
+Tue Dec 21 11:04:45 EST 1999 Mike Welles <mike@onshore.com> *** 3.5.4 release ***
+
+ * Aadded Pixar tag support. Contributed by Phil Beffery <phil@pixar.com>
+
+ * Made one more change to tif_dir.c for removal of LZW compression. Also added notice
+ when LZW compression invoked.
+
+ * Changed default compression in tools to TIFF_PACKBITS, and changed usage descriptions
+ in tools to reflect removal of LZW compression
+
+Mon Dec 20 18:39:02 EST 1999 Mike Welles <mike@onshore.com>
+
+ * Fixed bug that caused LZW (non) compression to segfault. Added
+ warning about LZW compression removed being removed, and why.
+
+ * Added nostrip to install in tools/Makefile.in so that debugging
+ symbols are kept.
+
+Tue Dec 7 12:04:47 EST 1999 Mike Welles <mike@onshore.com>
+
+ * Added patch from Ivo Penzar <ivo.penzar@infolink-software.com>,
+ supporting Adobe ZIP deflate. Untested.
+
+Sat Dec 4 15:47:11 1999 Frank Warmerdam <warmerda@gdal.velocet.ca>
+
+ * Made Packbits the default compression in tools/tiff2rgba.c instead
+ of LZW.
+
+Tue Nov 30 14:41:43 1999 Frank Warmerdam <warmerda@gdal.velocet.ca> *** 3.5.3. release ***
+
+ * Added tif_luv to contrib/djgpp/Makefile.lib.
+
+Tue Nov 30 14:15:32 EST 1999 Mike Welles <mike@onshore.com>
+
+ * Added zip creation to release makefile target
+
+ * Added html for TIFFWriteTile.3t man page.
+
+Tue Nov 30 09:20:16 1999 Frank Warmerdam <warmerda@gdal.velocet.ca>
+
+ * Added some changes to tif_write.c to support rewriting existing
+ fixed sized tiles and strips. Code mods disabled by default, only
+ enabled if REWRITE_HACK is defined for now.
+
+Mon Nov 29 11:43:42 1999 Frank Warmerdam <warmerda@gdal.velocet.ca>
+
+ * Added TIFFWriteTile.3t man page.
+
+Sun Nov 28 20:36:18 1999 Frank Warmerdam <warmerda@gdal.velocet.ca>
+
+ * Added notes on use of makefile.vc in build.html, and fixed
+ email subscription address.
+
+199-11-28 Mike Welles <mike@onshore.com>
+
+ * Fixed apocalypse-inducing y2k bug in contrib/ras/ras2tiff.c
+
+ * Did some casts cleaning up to reduce compiler warnings in tif_fax3.c,
+ from Bruce Carmeron <cameron@petris.com> -- modifications of
+ changes made by Frank (sun cc still complained on cast).
+
+ * Added tiffconf.h to install target per request from Bill
+ Radcliffe <billr@corbis.com>: "We need a way for ImageMagick to
+ know features have been compiled into the TIFF library in order to
+ handle things properly".
+
+Sat Nov 27 16:49:21 1999 Frank Warmerdam <warmerda@gdal.velocet.ca>
+
+ * fixed various VC++ warnings as suggested by Gilles Vollant
+ <info@winimage.com>.
+
+Wed Nov 24 12:08:16 1999 Frank Warmerdam <warmerda@gdal.velocet.ca>
+
+ * Modified TIFFquery.3t man pages info on TIFFIsByteSwapped() to
+ not imply applications are responsible for image data swapping.
+
+1999-11-22 Mike Welles <mike@onshore.com>
+ * HTML-ized the man pages, added to html/man
+
+ * Removed LZW Compression to comply with Unisys patent extortion.
+
+1999-09-29 Mike Welles <mike@onshore.com>
+ * Corrected one remaining 16 -> 32 bit value in tif_fax3.c,
+ From Ivo Penzar <ivo.penzar@infolink-software.com.
+
+ * Added patch from Ivo Penzar to have TiffAdvanceDirectory handle
+ memory mapped files. <ivo.penzar@infolink-software.com>
+
+1999-09-26 Mike Welles <mike@onshore.com> *** 3.5.2 release ***
+ * Corrected alpha versioning.
+
+ * Removed distinction between alpha and release targets in Makefile.in.
+
+ * added release.stamp target, which tags cvs tree, and updates
+ "RELEASE-DATE"
+
+ * added releasediff target, which diffs tree with source as of
+ date in "RELEASE-DATE"
+
+ * Ticked up version to 3.5.2 (alpha 01 -- but I think we'll moving
+ away from alpha/non-alpha distinctions).
+
+ * updated html to reflect release
+
+1999-09-23 <warmerda@CS46980-B>
+
+ * Set O_BINARY for tif_unix.c open() ... used on cygwin for instance.
+
+ * Added CYGWIN case in configure.
+
+Fri Sep 17 00:13:51 CEST 1999 Mike Welles <mike@onshore.com>
+
+ * Applied Francois Dagand's patch to handle fax decompression bug.
+ (sizes >= 65536 were failing)
+
+Tue Sep 14 21:31:43 1999 Frank Warmerdam <warmerda@gdal.velocet.ca>
+
+ * Applied "a" mode fix to tif_win32.c/TIFFOpen() as suggested
+ by Christopher Lawton <clawton@mathworks.com>
+
+Wed Sep 8 08:19:18 1999 Frank Warmerdam <warmerda@gdal.velocet.ca>
+
+ * Added IRIX/gcc, and OSF/1 4.x support on behalf of
+ Albert Chin-A-Young <china@thewrittenword.com>
+
+ * Added TIFFReassignTagToIgnore() API on behalf of
+ Bruce Cameron <cameron@petris.com>. Man page still pending.
+
+Wed Aug 25 11:39:07 1999 Frank Warmerdam <warmerda@gdal.velocet.ca>
+
+ * Added test target in Makefile, test_pics.sh script and pics/*.rpt
+ files to provide for a rudimentary testsuite.
+
+ * Added contrib/tags back from old distribution ... fixed up a bit.
+
+1999-08-16 <warmerda@CS46980-B>
+
+ * Added simple makefile.vc makefiles for building with MS VC++
+ on Windows NT/98/95 in console mode. Stuff in contrib/win* make give
+ better solutions for some users.
+
+Mon Aug 16 21:52:11 1999 Frank Warmerdam <warmerda@gdal.velocet.ca>
+
+ * Added addtiffo (add overviews to a TIFF file) in contrib. Didn't
+ put it in tools since part of it is in C++.
+
+1999-08-16 Michael L. Welles <mike@kurtz.fake>
+
+ * Updated html/index.html with anon CVS instructions.
+
+Mon Aug 16 13:18:41 1999 Frank Warmerdam <warmerda@gdal.velocet.ca>
+
+ * pre-remove so link before softlink in LINUXdso action in
+ libtiff/Makefile.in to avoid failure on LINUXdso builds other than
+ the first.
+
+ * Fixed problem with cvtcmap() in tif_getimage.c modifying the
+ colormaps owned by the TIFF handle itself when trying to fixup wrong
+ (eight bit) colormaps. Corrected by maintaining a private copy of
+ the colormap.
+
+ * Added TIFFReadRGBATile()/TIFFReadRGBAStrip() support in
+ tif_getimage.c.
+
+ * CVS Repository placed at remotesensing.org. ChangeLog added.
diff --git a/contrib/libs/libtiff/LICENSE.md b/contrib/libs/libtiff/LICENSE.md
new file mode 100644
index 0000000000..55b65673ed
--- /dev/null
+++ b/contrib/libs/libtiff/LICENSE.md
@@ -0,0 +1,23 @@
+# LibTIFF license
+
+Copyright © 1988-1997 Sam Leffler\
+Copyright © 1991-1997 Silicon Graphics, Inc.
+
+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.
+
+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
+OF THIS SOFTWARE.
diff --git a/contrib/libs/libtiff/README.md b/contrib/libs/libtiff/README.md
new file mode 100644
index 0000000000..2573dab14f
--- /dev/null
+++ b/contrib/libs/libtiff/README.md
@@ -0,0 +1,71 @@
+TIFF Software Distribution
+--------------------------
+This file is just a placeholder; all the documentation is now in
+HTML in the html directory. To view the documentation point your
+favorite WWW viewer at html/index.html;
+
+e.g.
+
+ firefox html/index.html
+
+If you don't have an HTML viewer then you can read the HTML source
+or fetch a PostScript version of this documentation from the directory
+
+ http://download.osgeo.org/libtiff/
+
+If you can't hack either of these options then basically what you
+want to do is:
+
+ % ./configure
+ % make
+ % su
+ # make install
+
+More information, email contacts, and mailing list information can be
+found online at http://www.simplesystems.org/libtiff/
+
+Source code repository
+----------------------
+
+[GitLab](https://gitlab.com/libtiff/libtiff)
+
+Bug database
+------------
+
+[GitLab issues](https://gitlab.com/libtiff/libtiff/issues)
+
+Previously, the project used
+[Bugzilla](http://bugzilla.maptools.org/buglist.cgi?product=libtiff). This
+is no longer in use, and all remaining issues have been migrated to GitLab.
+
+Use and Copyright
+-----------------
+Silicon Graphics has seen fit to allow us to give this work away. It
+is free. There is no support or guarantee of any sort as to its
+operations, correctness, or whatever. If you do anything useful with
+all or parts of it you need to honor the copyright notices. I would
+also be interested in knowing about it and, hopefully, be acknowledged.
+
+The legal way of saying that is:
+
+Copyright (c) 1988-1997 Sam Leffler
+Copyright (c) 1991-1997 Silicon Graphics, Inc.
+
+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.
+
+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
+OF THIS SOFTWARE.
diff --git a/contrib/libs/libtiff/VERSION.txt b/contrib/libs/libtiff/VERSION.txt
new file mode 100644
index 0000000000..4404a17bae
--- /dev/null
+++ b/contrib/libs/libtiff/VERSION.txt
@@ -0,0 +1 @@
+4.5.1
diff --git a/contrib/libs/libtiff/t4.h b/contrib/libs/libtiff/t4.h
new file mode 100644
index 0000000000..f933d4a336
--- /dev/null
+++ b/contrib/libs/libtiff/t4.h
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _T4_
+#define _T4_
+/*
+ * CCITT T.4 1D Huffman runlength codes and
+ * related definitions. Given the small sizes
+ * of these tables it does not seem
+ * worthwhile to make code & length 8 bits.
+ */
+typedef struct tableentry
+{
+ unsigned short length; /* bit length of g3 code */
+ unsigned short code; /* g3 code */
+ short runlen; /* run length in bits */
+} tableentry;
+
+#define EOL 0x001 /* EOL code value - 0000 0000 0000 1 */
+
+/* status values returned instead of a run length */
+#define G3CODE_EOL -1 /* NB: ACT_EOL - ACT_WRUNT */
+#define G3CODE_INVALID -2 /* NB: ACT_INVALID - ACT_WRUNT */
+#define G3CODE_EOF -3 /* end of input data */
+#define G3CODE_INCOMP -4 /* incomplete run code */
+
+/*
+ * Note that these tables are ordered such that the
+ * index into the table is known to be either the
+ * run length, or (run length / 64) + a fixed offset.
+ *
+ * NB: The G3CODE_INVALID entries are only used
+ * during state generation (see mkg3states.c).
+ */
+#ifdef G3CODES
+const tableentry TIFFFaxWhiteCodes[] = {
+ {8, 0x35, 0}, /* 0011 0101 */
+ {6, 0x7, 1}, /* 0001 11 */
+ {4, 0x7, 2}, /* 0111 */
+ {4, 0x8, 3}, /* 1000 */
+ {4, 0xB, 4}, /* 1011 */
+ {4, 0xC, 5}, /* 1100 */
+ {4, 0xE, 6}, /* 1110 */
+ {4, 0xF, 7}, /* 1111 */
+ {5, 0x13, 8}, /* 1001 1 */
+ {5, 0x14, 9}, /* 1010 0 */
+ {5, 0x7, 10}, /* 0011 1 */
+ {5, 0x8, 11}, /* 0100 0 */
+ {6, 0x8, 12}, /* 0010 00 */
+ {6, 0x3, 13}, /* 0000 11 */
+ {6, 0x34, 14}, /* 1101 00 */
+ {6, 0x35, 15}, /* 1101 01 */
+ {6, 0x2A, 16}, /* 1010 10 */
+ {6, 0x2B, 17}, /* 1010 11 */
+ {7, 0x27, 18}, /* 0100 111 */
+ {7, 0xC, 19}, /* 0001 100 */
+ {7, 0x8, 20}, /* 0001 000 */
+ {7, 0x17, 21}, /* 0010 111 */
+ {7, 0x3, 22}, /* 0000 011 */
+ {7, 0x4, 23}, /* 0000 100 */
+ {7, 0x28, 24}, /* 0101 000 */
+ {7, 0x2B, 25}, /* 0101 011 */
+ {7, 0x13, 26}, /* 0010 011 */
+ {7, 0x24, 27}, /* 0100 100 */
+ {7, 0x18, 28}, /* 0011 000 */
+ {8, 0x2, 29}, /* 0000 0010 */
+ {8, 0x3, 30}, /* 0000 0011 */
+ {8, 0x1A, 31}, /* 0001 1010 */
+ {8, 0x1B, 32}, /* 0001 1011 */
+ {8, 0x12, 33}, /* 0001 0010 */
+ {8, 0x13, 34}, /* 0001 0011 */
+ {8, 0x14, 35}, /* 0001 0100 */
+ {8, 0x15, 36}, /* 0001 0101 */
+ {8, 0x16, 37}, /* 0001 0110 */
+ {8, 0x17, 38}, /* 0001 0111 */
+ {8, 0x28, 39}, /* 0010 1000 */
+ {8, 0x29, 40}, /* 0010 1001 */
+ {8, 0x2A, 41}, /* 0010 1010 */
+ {8, 0x2B, 42}, /* 0010 1011 */
+ {8, 0x2C, 43}, /* 0010 1100 */
+ {8, 0x2D, 44}, /* 0010 1101 */
+ {8, 0x4, 45}, /* 0000 0100 */
+ {8, 0x5, 46}, /* 0000 0101 */
+ {8, 0xA, 47}, /* 0000 1010 */
+ {8, 0xB, 48}, /* 0000 1011 */
+ {8, 0x52, 49}, /* 0101 0010 */
+ {8, 0x53, 50}, /* 0101 0011 */
+ {8, 0x54, 51}, /* 0101 0100 */
+ {8, 0x55, 52}, /* 0101 0101 */
+ {8, 0x24, 53}, /* 0010 0100 */
+ {8, 0x25, 54}, /* 0010 0101 */
+ {8, 0x58, 55}, /* 0101 1000 */
+ {8, 0x59, 56}, /* 0101 1001 */
+ {8, 0x5A, 57}, /* 0101 1010 */
+ {8, 0x5B, 58}, /* 0101 1011 */
+ {8, 0x4A, 59}, /* 0100 1010 */
+ {8, 0x4B, 60}, /* 0100 1011 */
+ {8, 0x32, 61}, /* 0011 0010 */
+ {8, 0x33, 62}, /* 0011 0011 */
+ {8, 0x34, 63}, /* 0011 0100 */
+ {5, 0x1B, 64}, /* 1101 1 */
+ {5, 0x12, 128}, /* 1001 0 */
+ {6, 0x17, 192}, /* 0101 11 */
+ {7, 0x37, 256}, /* 0110 111 */
+ {8, 0x36, 320}, /* 0011 0110 */
+ {8, 0x37, 384}, /* 0011 0111 */
+ {8, 0x64, 448}, /* 0110 0100 */
+ {8, 0x65, 512}, /* 0110 0101 */
+ {8, 0x68, 576}, /* 0110 1000 */
+ {8, 0x67, 640}, /* 0110 0111 */
+ {9, 0xCC, 704}, /* 0110 0110 0 */
+ {9, 0xCD, 768}, /* 0110 0110 1 */
+ {9, 0xD2, 832}, /* 0110 1001 0 */
+ {9, 0xD3, 896}, /* 0110 1001 1 */
+ {9, 0xD4, 960}, /* 0110 1010 0 */
+ {9, 0xD5, 1024}, /* 0110 1010 1 */
+ {9, 0xD6, 1088}, /* 0110 1011 0 */
+ {9, 0xD7, 1152}, /* 0110 1011 1 */
+ {9, 0xD8, 1216}, /* 0110 1100 0 */
+ {9, 0xD9, 1280}, /* 0110 1100 1 */
+ {9, 0xDA, 1344}, /* 0110 1101 0 */
+ {9, 0xDB, 1408}, /* 0110 1101 1 */
+ {9, 0x98, 1472}, /* 0100 1100 0 */
+ {9, 0x99, 1536}, /* 0100 1100 1 */
+ {9, 0x9A, 1600}, /* 0100 1101 0 */
+ {6, 0x18, 1664}, /* 0110 00 */
+ {9, 0x9B, 1728}, /* 0100 1101 1 */
+ {11, 0x8, 1792}, /* 0000 0001 000 */
+ {11, 0xC, 1856}, /* 0000 0001 100 */
+ {11, 0xD, 1920}, /* 0000 0001 101 */
+ {12, 0x12, 1984}, /* 0000 0001 0010 */
+ {12, 0x13, 2048}, /* 0000 0001 0011 */
+ {12, 0x14, 2112}, /* 0000 0001 0100 */
+ {12, 0x15, 2176}, /* 0000 0001 0101 */
+ {12, 0x16, 2240}, /* 0000 0001 0110 */
+ {12, 0x17, 2304}, /* 0000 0001 0111 */
+ {12, 0x1C, 2368}, /* 0000 0001 1100 */
+ {12, 0x1D, 2432}, /* 0000 0001 1101 */
+ {12, 0x1E, 2496}, /* 0000 0001 1110 */
+ {12, 0x1F, 2560}, /* 0000 0001 1111 */
+ {12, 0x1, G3CODE_EOL}, /* 0000 0000 0001 */
+ {9, 0x1, G3CODE_INVALID}, /* 0000 0000 1 */
+ {10, 0x1, G3CODE_INVALID}, /* 0000 0000 01 */
+ {11, 0x1, G3CODE_INVALID}, /* 0000 0000 001 */
+ {12, 0x0, G3CODE_INVALID}, /* 0000 0000 0000 */
+};
+
+const tableentry TIFFFaxBlackCodes[] = {
+ {10, 0x37, 0}, /* 0000 1101 11 */
+ {3, 0x2, 1}, /* 010 */
+ {2, 0x3, 2}, /* 11 */
+ {2, 0x2, 3}, /* 10 */
+ {3, 0x3, 4}, /* 011 */
+ {4, 0x3, 5}, /* 0011 */
+ {4, 0x2, 6}, /* 0010 */
+ {5, 0x3, 7}, /* 0001 1 */
+ {6, 0x5, 8}, /* 0001 01 */
+ {6, 0x4, 9}, /* 0001 00 */
+ {7, 0x4, 10}, /* 0000 100 */
+ {7, 0x5, 11}, /* 0000 101 */
+ {7, 0x7, 12}, /* 0000 111 */
+ {8, 0x4, 13}, /* 0000 0100 */
+ {8, 0x7, 14}, /* 0000 0111 */
+ {9, 0x18, 15}, /* 0000 1100 0 */
+ {10, 0x17, 16}, /* 0000 0101 11 */
+ {10, 0x18, 17}, /* 0000 0110 00 */
+ {10, 0x8, 18}, /* 0000 0010 00 */
+ {11, 0x67, 19}, /* 0000 1100 111 */
+ {11, 0x68, 20}, /* 0000 1101 000 */
+ {11, 0x6C, 21}, /* 0000 1101 100 */
+ {11, 0x37, 22}, /* 0000 0110 111 */
+ {11, 0x28, 23}, /* 0000 0101 000 */
+ {11, 0x17, 24}, /* 0000 0010 111 */
+ {11, 0x18, 25}, /* 0000 0011 000 */
+ {12, 0xCA, 26}, /* 0000 1100 1010 */
+ {12, 0xCB, 27}, /* 0000 1100 1011 */
+ {12, 0xCC, 28}, /* 0000 1100 1100 */
+ {12, 0xCD, 29}, /* 0000 1100 1101 */
+ {12, 0x68, 30}, /* 0000 0110 1000 */
+ {12, 0x69, 31}, /* 0000 0110 1001 */
+ {12, 0x6A, 32}, /* 0000 0110 1010 */
+ {12, 0x6B, 33}, /* 0000 0110 1011 */
+ {12, 0xD2, 34}, /* 0000 1101 0010 */
+ {12, 0xD3, 35}, /* 0000 1101 0011 */
+ {12, 0xD4, 36}, /* 0000 1101 0100 */
+ {12, 0xD5, 37}, /* 0000 1101 0101 */
+ {12, 0xD6, 38}, /* 0000 1101 0110 */
+ {12, 0xD7, 39}, /* 0000 1101 0111 */
+ {12, 0x6C, 40}, /* 0000 0110 1100 */
+ {12, 0x6D, 41}, /* 0000 0110 1101 */
+ {12, 0xDA, 42}, /* 0000 1101 1010 */
+ {12, 0xDB, 43}, /* 0000 1101 1011 */
+ {12, 0x54, 44}, /* 0000 0101 0100 */
+ {12, 0x55, 45}, /* 0000 0101 0101 */
+ {12, 0x56, 46}, /* 0000 0101 0110 */
+ {12, 0x57, 47}, /* 0000 0101 0111 */
+ {12, 0x64, 48}, /* 0000 0110 0100 */
+ {12, 0x65, 49}, /* 0000 0110 0101 */
+ {12, 0x52, 50}, /* 0000 0101 0010 */
+ {12, 0x53, 51}, /* 0000 0101 0011 */
+ {12, 0x24, 52}, /* 0000 0010 0100 */
+ {12, 0x37, 53}, /* 0000 0011 0111 */
+ {12, 0x38, 54}, /* 0000 0011 1000 */
+ {12, 0x27, 55}, /* 0000 0010 0111 */
+ {12, 0x28, 56}, /* 0000 0010 1000 */
+ {12, 0x58, 57}, /* 0000 0101 1000 */
+ {12, 0x59, 58}, /* 0000 0101 1001 */
+ {12, 0x2B, 59}, /* 0000 0010 1011 */
+ {12, 0x2C, 60}, /* 0000 0010 1100 */
+ {12, 0x5A, 61}, /* 0000 0101 1010 */
+ {12, 0x66, 62}, /* 0000 0110 0110 */
+ {12, 0x67, 63}, /* 0000 0110 0111 */
+ {10, 0xF, 64}, /* 0000 0011 11 */
+ {12, 0xC8, 128}, /* 0000 1100 1000 */
+ {12, 0xC9, 192}, /* 0000 1100 1001 */
+ {12, 0x5B, 256}, /* 0000 0101 1011 */
+ {12, 0x33, 320}, /* 0000 0011 0011 */
+ {12, 0x34, 384}, /* 0000 0011 0100 */
+ {12, 0x35, 448}, /* 0000 0011 0101 */
+ {13, 0x6C, 512}, /* 0000 0011 0110 0 */
+ {13, 0x6D, 576}, /* 0000 0011 0110 1 */
+ {13, 0x4A, 640}, /* 0000 0010 0101 0 */
+ {13, 0x4B, 704}, /* 0000 0010 0101 1 */
+ {13, 0x4C, 768}, /* 0000 0010 0110 0 */
+ {13, 0x4D, 832}, /* 0000 0010 0110 1 */
+ {13, 0x72, 896}, /* 0000 0011 1001 0 */
+ {13, 0x73, 960}, /* 0000 0011 1001 1 */
+ {13, 0x74, 1024}, /* 0000 0011 1010 0 */
+ {13, 0x75, 1088}, /* 0000 0011 1010 1 */
+ {13, 0x76, 1152}, /* 0000 0011 1011 0 */
+ {13, 0x77, 1216}, /* 0000 0011 1011 1 */
+ {13, 0x52, 1280}, /* 0000 0010 1001 0 */
+ {13, 0x53, 1344}, /* 0000 0010 1001 1 */
+ {13, 0x54, 1408}, /* 0000 0010 1010 0 */
+ {13, 0x55, 1472}, /* 0000 0010 1010 1 */
+ {13, 0x5A, 1536}, /* 0000 0010 1101 0 */
+ {13, 0x5B, 1600}, /* 0000 0010 1101 1 */
+ {13, 0x64, 1664}, /* 0000 0011 0010 0 */
+ {13, 0x65, 1728}, /* 0000 0011 0010 1 */
+ {11, 0x8, 1792}, /* 0000 0001 000 */
+ {11, 0xC, 1856}, /* 0000 0001 100 */
+ {11, 0xD, 1920}, /* 0000 0001 101 */
+ {12, 0x12, 1984}, /* 0000 0001 0010 */
+ {12, 0x13, 2048}, /* 0000 0001 0011 */
+ {12, 0x14, 2112}, /* 0000 0001 0100 */
+ {12, 0x15, 2176}, /* 0000 0001 0101 */
+ {12, 0x16, 2240}, /* 0000 0001 0110 */
+ {12, 0x17, 2304}, /* 0000 0001 0111 */
+ {12, 0x1C, 2368}, /* 0000 0001 1100 */
+ {12, 0x1D, 2432}, /* 0000 0001 1101 */
+ {12, 0x1E, 2496}, /* 0000 0001 1110 */
+ {12, 0x1F, 2560}, /* 0000 0001 1111 */
+ {12, 0x1, G3CODE_EOL}, /* 0000 0000 0001 */
+ {9, 0x1, G3CODE_INVALID}, /* 0000 0000 1 */
+ {10, 0x1, G3CODE_INVALID}, /* 0000 0000 01 */
+ {11, 0x1, G3CODE_INVALID}, /* 0000 0000 001 */
+ {12, 0x0, G3CODE_INVALID}, /* 0000 0000 0000 */
+};
+#else
+extern const tableentry TIFFFaxWhiteCodes[];
+extern const tableentry TIFFFaxBlackCodes[];
+#endif
+#endif /* _T4_ */
diff --git a/contrib/libs/libtiff/tif_aux.c b/contrib/libs/libtiff/tif_aux.c
new file mode 100644
index 0000000000..49855bb0b2
--- /dev/null
+++ b/contrib/libs/libtiff/tif_aux.c
@@ -0,0 +1,458 @@
+/*
+ * Copyright (c) 1991-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Auxiliary Support Routines.
+ */
+#include "tif_predict.h"
+#include "tiffiop.h"
+#include <float.h>
+#include <math.h>
+
+uint32_t _TIFFMultiply32(TIFF *tif, uint32_t first, uint32_t second,
+ const char *where)
+{
+ if (second && first > UINT32_MAX / second)
+ {
+ TIFFErrorExtR(tif, where, "Integer overflow in %s", where);
+ return 0;
+ }
+
+ return first * second;
+}
+
+uint64_t _TIFFMultiply64(TIFF *tif, uint64_t first, uint64_t second,
+ const char *where)
+{
+ if (second && first > UINT64_MAX / second)
+ {
+ TIFFErrorExtR(tif, where, "Integer overflow in %s", where);
+ return 0;
+ }
+
+ return first * second;
+}
+
+tmsize_t _TIFFMultiplySSize(TIFF *tif, tmsize_t first, tmsize_t second,
+ const char *where)
+{
+ if (first <= 0 || second <= 0)
+ {
+ if (tif != NULL && where != NULL)
+ {
+ TIFFErrorExtR(tif, where,
+ "Invalid argument to _TIFFMultiplySSize() in %s",
+ where);
+ }
+ return 0;
+ }
+
+ if (first > TIFF_TMSIZE_T_MAX / second)
+ {
+ if (tif != NULL && where != NULL)
+ {
+ TIFFErrorExtR(tif, where, "Integer overflow in %s", where);
+ }
+ return 0;
+ }
+ return first * second;
+}
+
+tmsize_t _TIFFCastUInt64ToSSize(TIFF *tif, uint64_t val, const char *module)
+{
+ if (val > (uint64_t)TIFF_TMSIZE_T_MAX)
+ {
+ if (tif != NULL && module != NULL)
+ {
+ TIFFErrorExtR(tif, module, "Integer overflow");
+ }
+ return 0;
+ }
+ return (tmsize_t)val;
+}
+
+void *_TIFFCheckRealloc(TIFF *tif, void *buffer, tmsize_t nmemb,
+ tmsize_t elem_size, const char *what)
+{
+ void *cp = NULL;
+ tmsize_t count = _TIFFMultiplySSize(tif, nmemb, elem_size, NULL);
+ /*
+ * Check for integer overflow.
+ */
+ if (count != 0)
+ {
+ cp = _TIFFreallocExt(tif, buffer, count);
+ }
+
+ if (cp == NULL)
+ {
+ TIFFErrorExtR(tif, tif->tif_name,
+ "Failed to allocate memory for %s "
+ "(%" TIFF_SSIZE_FORMAT " elements of %" TIFF_SSIZE_FORMAT
+ " bytes each)",
+ what, nmemb, elem_size);
+ }
+
+ return cp;
+}
+
+void *_TIFFCheckMalloc(TIFF *tif, tmsize_t nmemb, tmsize_t elem_size,
+ const char *what)
+{
+ return _TIFFCheckRealloc(tif, NULL, nmemb, elem_size, what);
+}
+
+static int TIFFDefaultTransferFunction(TIFF *tif, TIFFDirectory *td)
+{
+ uint16_t **tf = td->td_transferfunction;
+ tmsize_t i, n, nbytes;
+
+ tf[0] = tf[1] = tf[2] = 0;
+ if (td->td_bitspersample >= sizeof(tmsize_t) * 8 - 2)
+ return 0;
+
+ n = ((tmsize_t)1) << td->td_bitspersample;
+ nbytes = n * sizeof(uint16_t);
+ tf[0] = (uint16_t *)_TIFFmallocExt(tif, nbytes);
+ if (tf[0] == NULL)
+ return 0;
+ tf[0][0] = 0;
+ for (i = 1; i < n; i++)
+ {
+ double t = (double)i / ((double)n - 1.);
+ tf[0][i] = (uint16_t)floor(65535. * pow(t, 2.2) + .5);
+ }
+
+ if (td->td_samplesperpixel - td->td_extrasamples > 1)
+ {
+ tf[1] = (uint16_t *)_TIFFmallocExt(tif, nbytes);
+ if (tf[1] == NULL)
+ goto bad;
+ _TIFFmemcpy(tf[1], tf[0], nbytes);
+ tf[2] = (uint16_t *)_TIFFmallocExt(tif, nbytes);
+ if (tf[2] == NULL)
+ goto bad;
+ _TIFFmemcpy(tf[2], tf[0], nbytes);
+ }
+ return 1;
+
+bad:
+ if (tf[0])
+ _TIFFfreeExt(tif, tf[0]);
+ if (tf[1])
+ _TIFFfreeExt(tif, tf[1]);
+ if (tf[2])
+ _TIFFfreeExt(tif, tf[2]);
+ tf[0] = tf[1] = tf[2] = 0;
+ return 0;
+}
+
+static int TIFFDefaultRefBlackWhite(TIFF *tif, TIFFDirectory *td)
+{
+ int i;
+
+ td->td_refblackwhite = (float *)_TIFFmallocExt(tif, 6 * sizeof(float));
+ if (td->td_refblackwhite == NULL)
+ return 0;
+ if (td->td_photometric == PHOTOMETRIC_YCBCR)
+ {
+ /*
+ * YCbCr (Class Y) images must have the ReferenceBlackWhite
+ * tag set. Fix the broken images, which lacks that tag.
+ */
+ td->td_refblackwhite[0] = 0.0F;
+ td->td_refblackwhite[1] = td->td_refblackwhite[3] =
+ td->td_refblackwhite[5] = 255.0F;
+ td->td_refblackwhite[2] = td->td_refblackwhite[4] = 128.0F;
+ }
+ else
+ {
+ /*
+ * Assume RGB (Class R)
+ */
+ for (i = 0; i < 3; i++)
+ {
+ td->td_refblackwhite[2 * i + 0] = 0;
+ td->td_refblackwhite[2 * i + 1] =
+ (float)((1L << td->td_bitspersample) - 1L);
+ }
+ }
+ return 1;
+}
+
+/*
+ * Like TIFFGetField, but return any default
+ * value if the tag is not present in the directory.
+ *
+ * NB: We use the value in the directory, rather than
+ * explicit values so that defaults exist only one
+ * place in the library -- in TIFFDefaultDirectory.
+ */
+int TIFFVGetFieldDefaulted(TIFF *tif, uint32_t tag, va_list ap)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+
+ if (TIFFVGetField(tif, tag, ap))
+ return (1);
+ switch (tag)
+ {
+ case TIFFTAG_SUBFILETYPE:
+ *va_arg(ap, uint32_t *) = td->td_subfiletype;
+ return (1);
+ case TIFFTAG_BITSPERSAMPLE:
+ *va_arg(ap, uint16_t *) = td->td_bitspersample;
+ return (1);
+ case TIFFTAG_THRESHHOLDING:
+ *va_arg(ap, uint16_t *) = td->td_threshholding;
+ return (1);
+ case TIFFTAG_FILLORDER:
+ *va_arg(ap, uint16_t *) = td->td_fillorder;
+ return (1);
+ case TIFFTAG_ORIENTATION:
+ *va_arg(ap, uint16_t *) = td->td_orientation;
+ return (1);
+ case TIFFTAG_SAMPLESPERPIXEL:
+ *va_arg(ap, uint16_t *) = td->td_samplesperpixel;
+ return (1);
+ case TIFFTAG_ROWSPERSTRIP:
+ *va_arg(ap, uint32_t *) = td->td_rowsperstrip;
+ return (1);
+ case TIFFTAG_MINSAMPLEVALUE:
+ *va_arg(ap, uint16_t *) = td->td_minsamplevalue;
+ return (1);
+ case TIFFTAG_MAXSAMPLEVALUE:
+ {
+ uint16_t maxsamplevalue;
+ /* td_bitspersample=1 is always set in TIFFDefaultDirectory().
+ * Therefore, td_maxsamplevalue has to be re-calculated in
+ * TIFFGetFieldDefaulted(). */
+ if (td->td_bitspersample > 0)
+ {
+ /* This shift operation into a uint16_t limits the value to
+ * 65535 even if td_bitspersamle is > 16 */
+ if (td->td_bitspersample <= 16)
+ {
+ maxsamplevalue = (1 << td->td_bitspersample) -
+ 1; /* 2**(BitsPerSample) - 1 */
+ }
+ else
+ {
+ maxsamplevalue = 65535;
+ }
+ }
+ else
+ {
+ maxsamplevalue = 0;
+ }
+ *va_arg(ap, uint16_t *) = maxsamplevalue;
+ return (1);
+ }
+ case TIFFTAG_PLANARCONFIG:
+ *va_arg(ap, uint16_t *) = td->td_planarconfig;
+ return (1);
+ case TIFFTAG_RESOLUTIONUNIT:
+ *va_arg(ap, uint16_t *) = td->td_resolutionunit;
+ return (1);
+ case TIFFTAG_PREDICTOR:
+ {
+ TIFFPredictorState *sp = (TIFFPredictorState *)tif->tif_data;
+ if (sp == NULL)
+ {
+ TIFFErrorExtR(
+ tif, tif->tif_name,
+ "Cannot get \"Predictor\" tag as plugin is not configured");
+ *va_arg(ap, uint16_t *) = 0;
+ return 0;
+ }
+ *va_arg(ap, uint16_t *) = (uint16_t)sp->predictor;
+ return 1;
+ }
+ case TIFFTAG_DOTRANGE:
+ *va_arg(ap, uint16_t *) = 0;
+ *va_arg(ap, uint16_t *) = (1 << td->td_bitspersample) - 1;
+ return (1);
+ case TIFFTAG_INKSET:
+ *va_arg(ap, uint16_t *) = INKSET_CMYK;
+ return 1;
+ case TIFFTAG_NUMBEROFINKS:
+ *va_arg(ap, uint16_t *) = 4;
+ return (1);
+ case TIFFTAG_EXTRASAMPLES:
+ *va_arg(ap, uint16_t *) = td->td_extrasamples;
+ *va_arg(ap, const uint16_t **) = td->td_sampleinfo;
+ return (1);
+ case TIFFTAG_MATTEING:
+ *va_arg(ap, uint16_t *) =
+ (td->td_extrasamples == 1 &&
+ td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
+ return (1);
+ case TIFFTAG_TILEDEPTH:
+ *va_arg(ap, uint32_t *) = td->td_tiledepth;
+ return (1);
+ case TIFFTAG_DATATYPE:
+ *va_arg(ap, uint16_t *) = td->td_sampleformat - 1;
+ return (1);
+ case TIFFTAG_SAMPLEFORMAT:
+ *va_arg(ap, uint16_t *) = td->td_sampleformat;
+ return (1);
+ case TIFFTAG_IMAGEDEPTH:
+ *va_arg(ap, uint32_t *) = td->td_imagedepth;
+ return (1);
+ case TIFFTAG_YCBCRCOEFFICIENTS:
+ {
+ /* defaults are from CCIR Recommendation 601-1 */
+ static const float ycbcrcoeffs[] = {0.299f, 0.587f, 0.114f};
+ *va_arg(ap, const float **) = ycbcrcoeffs;
+ return 1;
+ }
+ case TIFFTAG_YCBCRSUBSAMPLING:
+ *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[0];
+ *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[1];
+ return (1);
+ case TIFFTAG_YCBCRPOSITIONING:
+ *va_arg(ap, uint16_t *) = td->td_ycbcrpositioning;
+ return (1);
+ case TIFFTAG_WHITEPOINT:
+ {
+ /* TIFF 6.0 specification tells that it is no default
+ value for the WhitePoint, but AdobePhotoshop TIFF
+ Technical Note tells that it should be CIE D50. */
+ static const float whitepoint[] = {
+ D50_X0 / (D50_X0 + D50_Y0 + D50_Z0),
+ D50_Y0 / (D50_X0 + D50_Y0 + D50_Z0)};
+ *va_arg(ap, const float **) = whitepoint;
+ return 1;
+ }
+ case TIFFTAG_TRANSFERFUNCTION:
+ if (!td->td_transferfunction[0] &&
+ !TIFFDefaultTransferFunction(tif, td))
+ {
+ TIFFErrorExtR(tif, tif->tif_name,
+ "No space for \"TransferFunction\" tag");
+ return (0);
+ }
+ *va_arg(ap, const uint16_t **) = td->td_transferfunction[0];
+ if (td->td_samplesperpixel - td->td_extrasamples > 1)
+ {
+ *va_arg(ap, const uint16_t **) = td->td_transferfunction[1];
+ *va_arg(ap, const uint16_t **) = td->td_transferfunction[2];
+ }
+ return (1);
+ case TIFFTAG_REFERENCEBLACKWHITE:
+ if (!td->td_refblackwhite && !TIFFDefaultRefBlackWhite(tif, td))
+ return (0);
+ *va_arg(ap, const float **) = td->td_refblackwhite;
+ return (1);
+ }
+ return 0;
+}
+
+/*
+ * Like TIFFGetField, but return any default
+ * value if the tag is not present in the directory.
+ */
+int TIFFGetFieldDefaulted(TIFF *tif, uint32_t tag, ...)
+{
+ int ok;
+ va_list ap;
+
+ va_start(ap, tag);
+ ok = TIFFVGetFieldDefaulted(tif, tag, ap);
+ va_end(ap);
+ return (ok);
+}
+
+struct _Int64Parts
+{
+ int32_t low, high;
+};
+
+typedef union
+{
+ struct _Int64Parts part;
+ int64_t value;
+} _Int64;
+
+float _TIFFUInt64ToFloat(uint64_t ui64)
+{
+ _Int64 i;
+
+ i.value = ui64;
+ if (i.part.high >= 0)
+ {
+ return (float)i.value;
+ }
+ else
+ {
+ long double df;
+ df = (long double)i.value;
+ df += 18446744073709551616.0; /* adding 2**64 */
+ return (float)df;
+ }
+}
+
+double _TIFFUInt64ToDouble(uint64_t ui64)
+{
+ _Int64 i;
+
+ i.value = ui64;
+ if (i.part.high >= 0)
+ {
+ return (double)i.value;
+ }
+ else
+ {
+ long double df;
+ df = (long double)i.value;
+ df += 18446744073709551616.0; /* adding 2**64 */
+ return (double)df;
+ }
+}
+
+float _TIFFClampDoubleToFloat(double val)
+{
+ if (val > FLT_MAX)
+ return FLT_MAX;
+ if (val < -FLT_MAX)
+ return -FLT_MAX;
+ return (float)val;
+}
+
+uint32_t _TIFFClampDoubleToUInt32(double val)
+{
+ if (val < 0)
+ return 0;
+ if (val > 0xFFFFFFFFU || val != val)
+ return 0xFFFFFFFFU;
+ return (uint32_t)val;
+}
+
+int _TIFFSeekOK(TIFF *tif, toff_t off)
+{
+ /* Huge offsets, especially -1 / UINT64_MAX, can cause issues */
+ /* See http://bugzilla.maptools.org/show_bug.cgi?id=2726 */
+ return off <= (~(uint64_t)0) / 2 && TIFFSeekFile(tif, off, SEEK_SET) == off;
+}
diff --git a/contrib/libs/libtiff/tif_close.c b/contrib/libs/libtiff/tif_close.c
new file mode 100644
index 0000000000..907d7f139b
--- /dev/null
+++ b/contrib/libs/libtiff/tif_close.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ */
+#include "tiffiop.h"
+#include <string.h>
+
+/************************************************************************/
+/* TIFFCleanup() */
+/************************************************************************/
+
+/**
+ * Auxiliary function to free the TIFF structure. Given structure will be
+ * completely freed, so you should save opened file handle and pointer
+ * to the close procedure in external variables before calling
+ * _TIFFCleanup(), if you will need these ones to close the file.
+ *
+ * @param tif A TIFF pointer.
+ */
+
+void TIFFCleanup(TIFF *tif)
+{
+ /*
+ * Flush buffered data and directory (if dirty).
+ */
+ if (tif->tif_mode != O_RDONLY)
+ TIFFFlush(tif);
+ (*tif->tif_cleanup)(tif);
+ TIFFFreeDirectory(tif);
+
+ _TIFFCleanupIFDOffsetAndNumberMaps(tif);
+
+ /*
+ * Clean up client info links.
+ */
+ while (tif->tif_clientinfo)
+ {
+ TIFFClientInfoLink *psLink = tif->tif_clientinfo;
+
+ tif->tif_clientinfo = psLink->next;
+ _TIFFfreeExt(tif, psLink->name);
+ _TIFFfreeExt(tif, psLink);
+ }
+
+ if (tif->tif_rawdata && (tif->tif_flags & TIFF_MYBUFFER))
+ _TIFFfreeExt(tif, tif->tif_rawdata);
+ if (isMapped(tif))
+ TIFFUnmapFileContents(tif, tif->tif_base, (toff_t)tif->tif_size);
+
+ /*
+ * Clean up custom fields.
+ */
+ if (tif->tif_fields && tif->tif_nfields > 0)
+ {
+ uint32_t i;
+
+ for (i = 0; i < tif->tif_nfields; i++)
+ {
+ TIFFField *fld = tif->tif_fields[i];
+ 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))
+ {
+ _TIFFfreeExt(tif, fld->field_name);
+ _TIFFfreeExt(tif, fld);
+ }
+ }
+ }
+
+ _TIFFfreeExt(tif, tif->tif_fields);
+ }
+
+ if (tif->tif_nfieldscompat > 0)
+ {
+ uint32_t i;
+
+ for (i = 0; i < tif->tif_nfieldscompat; i++)
+ {
+ if (tif->tif_fieldscompat[i].allocated_size)
+ _TIFFfreeExt(tif, tif->tif_fieldscompat[i].fields);
+ }
+ _TIFFfreeExt(tif, tif->tif_fieldscompat);
+ }
+
+ _TIFFfreeExt(NULL, tif);
+}
+
+/************************************************************************/
+/* _TIFFCleanupIFDOffsetAndNumberMaps() */
+/************************************************************************/
+
+void _TIFFCleanupIFDOffsetAndNumberMaps(TIFF *tif)
+{
+ if (tif->tif_map_dir_offset_to_number)
+ {
+ TIFFHashSetDestroy(tif->tif_map_dir_offset_to_number);
+ tif->tif_map_dir_offset_to_number = NULL;
+ }
+ if (tif->tif_map_dir_number_to_offset)
+ {
+ TIFFHashSetDestroy(tif->tif_map_dir_number_to_offset);
+ tif->tif_map_dir_number_to_offset = NULL;
+ }
+}
+
+/************************************************************************/
+/* TIFFClose() */
+/************************************************************************/
+
+/**
+ * Close a previously opened TIFF file.
+ *
+ * TIFFClose closes a file that was previously opened with TIFFOpen().
+ * Any buffered data are flushed to the file, including the contents of
+ * the current directory (if modified); and all resources are reclaimed.
+ *
+ * @param tif A TIFF pointer.
+ */
+
+void TIFFClose(TIFF *tif)
+{
+ if (tif != NULL)
+ {
+ TIFFCloseProc closeproc = tif->tif_closeproc;
+ thandle_t fd = tif->tif_clientdata;
+
+ TIFFCleanup(tif);
+ (void)(*closeproc)(fd);
+ }
+}
diff --git a/contrib/libs/libtiff/tif_codec.c b/contrib/libs/libtiff/tif_codec.c
new file mode 100644
index 0000000000..d499b63a58
--- /dev/null
+++ b/contrib/libs/libtiff/tif_codec.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library
+ *
+ * Builtin Compression Scheme Configuration Support.
+ */
+#include "tiffiop.h"
+
+static int NotConfigured(TIFF *, int);
+
+#ifndef LZW_SUPPORT
+#define TIFFInitLZW NotConfigured
+#endif
+#ifndef PACKBITS_SUPPORT
+#define TIFFInitPackBits NotConfigured
+#endif
+#ifndef THUNDER_SUPPORT
+#define TIFFInitThunderScan NotConfigured
+#endif
+#ifndef NEXT_SUPPORT
+#define TIFFInitNeXT NotConfigured
+#endif
+#ifndef JPEG_SUPPORT
+#define TIFFInitJPEG NotConfigured
+#endif
+#ifndef OJPEG_SUPPORT
+#define TIFFInitOJPEG NotConfigured
+#endif
+#ifndef CCITT_SUPPORT
+#define TIFFInitCCITTRLE NotConfigured
+#define TIFFInitCCITTRLEW NotConfigured
+#define TIFFInitCCITTFax3 NotConfigured
+#define TIFFInitCCITTFax4 NotConfigured
+#endif
+#ifndef JBIG_SUPPORT
+#define TIFFInitJBIG NotConfigured
+#endif
+#ifndef ZIP_SUPPORT
+#define TIFFInitZIP NotConfigured
+#endif
+#ifndef PIXARLOG_SUPPORT
+#define TIFFInitPixarLog NotConfigured
+#endif
+#ifndef LOGLUV_SUPPORT
+#define TIFFInitSGILog NotConfigured
+#endif
+#ifndef LERC_SUPPORT
+#define TIFFInitLERC NotConfigured
+#endif
+#ifndef LZMA_SUPPORT
+#define TIFFInitLZMA NotConfigured
+#endif
+#ifndef ZSTD_SUPPORT
+#define TIFFInitZSTD NotConfigured
+#endif
+#ifndef WEBP_SUPPORT
+#define TIFFInitWebP NotConfigured
+#endif
+
+/*
+ * Compression schemes statically built into the library.
+ */
+const TIFFCodec _TIFFBuiltinCODECS[] = {
+ {"None", COMPRESSION_NONE, TIFFInitDumpMode},
+ {"LZW", COMPRESSION_LZW, TIFFInitLZW},
+ {"PackBits", COMPRESSION_PACKBITS, TIFFInitPackBits},
+ {"ThunderScan", COMPRESSION_THUNDERSCAN, TIFFInitThunderScan},
+ {"NeXT", COMPRESSION_NEXT, TIFFInitNeXT},
+ {"JPEG", COMPRESSION_JPEG, TIFFInitJPEG},
+ {"Old-style JPEG", COMPRESSION_OJPEG, TIFFInitOJPEG},
+ {"CCITT RLE", COMPRESSION_CCITTRLE, TIFFInitCCITTRLE},
+ {"CCITT RLE/W", COMPRESSION_CCITTRLEW, TIFFInitCCITTRLEW},
+ {"CCITT Group 3", COMPRESSION_CCITTFAX3, TIFFInitCCITTFax3},
+ {"CCITT Group 4", COMPRESSION_CCITTFAX4, TIFFInitCCITTFax4},
+ {"ISO JBIG", COMPRESSION_JBIG, TIFFInitJBIG},
+ {"Deflate", COMPRESSION_DEFLATE, TIFFInitZIP},
+ {"AdobeDeflate", COMPRESSION_ADOBE_DEFLATE, TIFFInitZIP},
+ {"PixarLog", COMPRESSION_PIXARLOG, TIFFInitPixarLog},
+ {"SGILog", COMPRESSION_SGILOG, TIFFInitSGILog},
+ {"SGILog24", COMPRESSION_SGILOG24, TIFFInitSGILog},
+ {"LZMA", COMPRESSION_LZMA, TIFFInitLZMA},
+ {"ZSTD", COMPRESSION_ZSTD, TIFFInitZSTD},
+ {"WEBP", COMPRESSION_WEBP, TIFFInitWebP},
+ {"LERC", COMPRESSION_LERC, TIFFInitLERC},
+ {NULL, 0, NULL}};
+
+static int _notConfigured(TIFF *tif)
+{
+ const TIFFCodec *c = TIFFFindCODEC(tif->tif_dir.td_compression);
+ char compression_code[20];
+
+ snprintf(compression_code, sizeof(compression_code), "%" PRIu16,
+ tif->tif_dir.td_compression);
+ TIFFErrorExtR(tif, tif->tif_name,
+ "%s compression support is not configured",
+ c ? c->name : compression_code);
+ return (0);
+}
+
+static int NotConfigured(TIFF *tif, int scheme)
+{
+ (void)scheme;
+
+ tif->tif_fixuptags = _notConfigured;
+ tif->tif_decodestatus = FALSE;
+ tif->tif_setupdecode = _notConfigured;
+ tif->tif_encodestatus = FALSE;
+ tif->tif_setupencode = _notConfigured;
+ return (1);
+}
+
+/************************************************************************/
+/* TIFFIsCODECConfigured() */
+/************************************************************************/
+
+/**
+ * Check whether we have working codec for the specific coding scheme.
+ *
+ * @return returns 1 if the codec is configured and working. Otherwise
+ * 0 will be returned.
+ */
+
+int TIFFIsCODECConfigured(uint16_t scheme)
+{
+ const TIFFCodec *codec = TIFFFindCODEC(scheme);
+
+ if (codec == NULL)
+ {
+ return 0;
+ }
+ if (codec->init == NULL)
+ {
+ return 0;
+ }
+ if (codec->init != NotConfigured)
+ {
+ return 1;
+ }
+ return 0;
+}
diff --git a/contrib/libs/libtiff/tif_color.c b/contrib/libs/libtiff/tif_color.c
new file mode 100644
index 0000000000..2d7dcac6fe
--- /dev/null
+++ b/contrib/libs/libtiff/tif_color.c
@@ -0,0 +1,322 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * CIE L*a*b* to CIE XYZ and CIE XYZ to RGB conversion routines are taken
+ * from the VIPS library (http://www.vips.ecs.soton.ac.uk) with
+ * the permission of John Cupitt, the VIPS author.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Color space conversion routines.
+ */
+
+#include "tiffiop.h"
+#include <math.h>
+
+/*
+ * Convert color value from the CIE L*a*b* 1976 space to CIE XYZ.
+ */
+void TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a, int32_t b,
+ float *X, float *Y, float *Z)
+{
+ TIFFCIELab16ToXYZ(cielab, l * 257, a * 256, b * 256, X, Y, Z);
+}
+
+/*
+ * For CIELab encoded in 16 bits, L is an unsigned integer range [0,65535].
+ * The a* and b* components are signed integers range [-32768,32767]. The 16
+ * bit chrominance values are encoded as 256 times the 1976 CIE a* and b*
+ * values
+ */
+void TIFFCIELab16ToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a,
+ int32_t b, float *X, float *Y, float *Z)
+{
+ float L = (float)l * 100.0F / 65535.0F;
+ float cby, tmp;
+
+ if (L < 8.856F)
+ {
+ *Y = (L * cielab->Y0) / 903.292F;
+ cby = 7.787F * (*Y / cielab->Y0) + 16.0F / 116.0F;
+ }
+ else
+ {
+ cby = (L + 16.0F) / 116.0F;
+ *Y = cielab->Y0 * cby * cby * cby;
+ }
+
+ tmp = (float)a / 256.0F / 500.0F + cby;
+ if (tmp < 0.2069F)
+ *X = cielab->X0 * (tmp - 0.13793F) / 7.787F;
+ else
+ *X = cielab->X0 * tmp * tmp * tmp;
+
+ tmp = cby - (float)b / 256.0F / 200.0F;
+ if (tmp < 0.2069F)
+ *Z = cielab->Z0 * (tmp - 0.13793F) / 7.787F;
+ else
+ *Z = cielab->Z0 * tmp * tmp * tmp;
+}
+
+#define RINT(R) ((uint32_t)((R) > 0 ? ((R) + 0.5) : ((R)-0.5)))
+/*
+ * Convert color value from the XYZ space to RGB.
+ */
+void TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z,
+ uint32_t *r, uint32_t *g, uint32_t *b)
+{
+ int i;
+ float Yr, Yg, Yb;
+ float *matrix = &cielab->display.d_mat[0][0];
+
+ /* Multiply through the matrix to get luminosity values. */
+ Yr = matrix[0] * X + matrix[1] * Y + matrix[2] * Z;
+ Yg = matrix[3] * X + matrix[4] * Y + matrix[5] * Z;
+ Yb = matrix[6] * X + matrix[7] * Y + matrix[8] * Z;
+
+ /* Clip input */
+ Yr = TIFFmax(Yr, cielab->display.d_Y0R);
+ Yg = TIFFmax(Yg, cielab->display.d_Y0G);
+ Yb = TIFFmax(Yb, cielab->display.d_Y0B);
+
+ /* Avoid overflow in case of wrong input values */
+ Yr = TIFFmin(Yr, cielab->display.d_YCR);
+ Yg = TIFFmin(Yg, cielab->display.d_YCG);
+ Yb = TIFFmin(Yb, cielab->display.d_YCB);
+
+ /* Turn luminosity to colour value. */
+ i = (int)((Yr - cielab->display.d_Y0R) / cielab->rstep);
+ i = TIFFmin(cielab->range, i);
+ *r = RINT(cielab->Yr2r[i]);
+
+ i = (int)((Yg - cielab->display.d_Y0G) / cielab->gstep);
+ i = TIFFmin(cielab->range, i);
+ *g = RINT(cielab->Yg2g[i]);
+
+ i = (int)((Yb - cielab->display.d_Y0B) / cielab->bstep);
+ i = TIFFmin(cielab->range, i);
+ *b = RINT(cielab->Yb2b[i]);
+
+ /* Clip output. */
+ *r = TIFFmin(*r, cielab->display.d_Vrwr);
+ *g = TIFFmin(*g, cielab->display.d_Vrwg);
+ *b = TIFFmin(*b, cielab->display.d_Vrwb);
+}
+#undef RINT
+
+/*
+ * Allocate conversion state structures and make look_up tables for
+ * the Yr,Yb,Yg <=> r,g,b conversions.
+ */
+int TIFFCIELabToRGBInit(TIFFCIELabToRGB *cielab, const TIFFDisplay *display,
+ float *refWhite)
+{
+ int i;
+ double dfGamma;
+
+ cielab->range = CIELABTORGB_TABLE_RANGE;
+
+ _TIFFmemcpy(&cielab->display, display, sizeof(TIFFDisplay));
+
+ /* Red */
+ dfGamma = 1.0 / cielab->display.d_gammaR;
+ cielab->rstep =
+ (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
+ for (i = 0; i <= cielab->range; i++)
+ {
+ cielab->Yr2r[i] = cielab->display.d_Vrwr *
+ ((float)pow((double)i / cielab->range, dfGamma));
+ }
+
+ /* Green */
+ dfGamma = 1.0 / cielab->display.d_gammaG;
+ cielab->gstep =
+ (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
+ for (i = 0; i <= cielab->range; i++)
+ {
+ cielab->Yg2g[i] = cielab->display.d_Vrwg *
+ ((float)pow((double)i / cielab->range, dfGamma));
+ }
+
+ /* Blue */
+ dfGamma = 1.0 / cielab->display.d_gammaB;
+ cielab->bstep =
+ (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
+ for (i = 0; i <= cielab->range; i++)
+ {
+ cielab->Yb2b[i] = cielab->display.d_Vrwb *
+ ((float)pow((double)i / cielab->range, dfGamma));
+ }
+
+ /* Init reference white point */
+ cielab->X0 = refWhite[0];
+ cielab->Y0 = refWhite[1];
+ cielab->Z0 = refWhite[2];
+
+ 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.
+ */
+#define SHIFT 16
+#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))
+/* !((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 TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32_t Y, int32_t Cb, int32_t Cr,
+ uint32_t *r, uint32_t *g, uint32_t *b)
+{
+ int32_t i;
+
+ /* XXX: Only 8-bit YCbCr input supported for now */
+ Y = HICLAMP(Y, 255);
+ Cb = CLAMP(Cb, 0, 255);
+ Cr = CLAMP(Cr, 0, 255);
+
+ i = ycbcr->Y_tab[Y] + ycbcr->Cr_r_tab[Cr];
+ *r = CLAMP(i, 0, 255);
+ i = ycbcr->Y_tab[Y] +
+ (int)((ycbcr->Cb_g_tab[Cb] + ycbcr->Cr_g_tab[Cr]) >> SHIFT);
+ *g = CLAMP(i, 0, 255);
+ i = ycbcr->Y_tab[Y] + ycbcr->Cb_b_tab[Cb];
+ *b = CLAMP(i, 0, 255);
+}
+
+/* Clamp function for sanitization purposes. Normally clamping should not */
+/* occur for well behaved chroma and refBlackWhite coefficients */
+static float CLAMPw(float v, float vmin, float vmax)
+{
+ if (v < vmin)
+ {
+ /* printf("%f clamped to %f\n", v, vmin); */
+ return vmin;
+ }
+ if (v > vmax)
+ {
+ /* printf("%f clamped to %f\n", v, vmax); */
+ return vmax;
+ }
+ return v;
+}
+
+/*
+ * Initialize the YCbCr->RGB conversion tables. The conversion
+ * is done according to the 6.0 spec:
+ *
+ * R = Y + Cr*(2 - 2*LumaRed)
+ * B = Y + Cb*(2 - 2*LumaBlue)
+ * G = Y
+ * - LumaBlue*Cb*(2-2*LumaBlue)/LumaGreen
+ * - LumaRed*Cr*(2-2*LumaRed)/LumaGreen
+ *
+ * To avoid floating point arithmetic the fractional constants that
+ * come out of the equations are represented as fixed point values
+ * in the range 0...2^16. We also eliminate multiplications by
+ * pre-calculating possible values indexed by Cb and Cr (this code
+ * assumes conversion is being done for 8-bit samples).
+ */
+int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *ycbcr, float *luma, float *refBlackWhite)
+{
+ TIFFRGBValue *clamptab;
+ int i;
+
+#define LumaRed luma[0]
+#define LumaGreen luma[1]
+#define LumaBlue luma[2]
+
+ clamptab =
+ (TIFFRGBValue *)((uint8_t *)ycbcr +
+ TIFFroundup_32(sizeof(TIFFYCbCrToRGB), sizeof(long)));
+ _TIFFmemset(clamptab, 0, 256); /* v < 0 => 0 */
+ ycbcr->clamptab = (clamptab += 256);
+ for (i = 0; i < 256; i++)
+ clamptab[i] = (TIFFRGBValue)i;
+ _TIFFmemset(clamptab + 256, 255, 2 * 256); /* v > 255 => 255 */
+ ycbcr->Cr_r_tab = (int *)(clamptab + 3 * 256);
+ ycbcr->Cb_b_tab = ycbcr->Cr_r_tab + 256;
+ ycbcr->Cr_g_tab = (int32_t *)(ycbcr->Cb_b_tab + 256);
+ ycbcr->Cb_g_tab = ycbcr->Cr_g_tab + 256;
+ ycbcr->Y_tab = ycbcr->Cb_g_tab + 256;
+
+ {
+ float f1 = 2 - 2 * LumaRed;
+ int32_t D1 = FIX(CLAMP(f1, 0.0F, 2.0F));
+ float f2 = LumaRed * f1 / LumaGreen;
+ int32_t D2 = -FIX(CLAMP(f2, 0.0F, 2.0F));
+ float f3 = 2 - 2 * LumaBlue;
+ int32_t D3 = FIX(CLAMP(f3, 0.0F, 2.0F));
+ float f4 = LumaBlue * f3 / LumaGreen;
+ int32_t D4 = -FIX(CLAMP(f4, 0.0F, 2.0F));
+ int x;
+
+#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
+ * they are in a range defined by the ReferenceBlackWhite
+ * tag) so there is some range shifting to do here when
+ * constructing tables indexed by the raw pixel data.
+ */
+ for (i = 0, x = -128; i < 256; i++, x++)
+ {
+ int32_t Cr = (int32_t)CLAMPw(Code2V(x, refBlackWhite[4] - 128.0F,
+ refBlackWhite[5] - 128.0F, 127),
+ -128.0F * 32, 128.0F * 32);
+ int32_t Cb = (int32_t)CLAMPw(Code2V(x, refBlackWhite[2] - 128.0F,
+ refBlackWhite[3] - 128.0F, 127),
+ -128.0F * 32, 128.0F * 32);
+
+ ycbcr->Cr_r_tab[i] = (int32_t)((D1 * Cr + ONE_HALF) >> SHIFT);
+ ycbcr->Cb_b_tab[i] = (int32_t)((D3 * Cb + ONE_HALF) >> SHIFT);
+ ycbcr->Cr_g_tab[i] = D2 * Cr;
+ ycbcr->Cb_g_tab[i] = D4 * Cb + ONE_HALF;
+ ycbcr->Y_tab[i] = (int32_t)CLAMPw(
+ Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255),
+ -128.0F * 32, 128.0F * 32);
+ }
+ }
+
+ return 0;
+}
+#undef HICLAMP
+#undef CLAMP
+#undef Code2V
+#undef SHIFT
+#undef ONE_HALF
+#undef FIX
diff --git a/contrib/libs/libtiff/tif_compress.c b/contrib/libs/libtiff/tif_compress.c
new file mode 100644
index 0000000000..c6e17d3e11
--- /dev/null
+++ b/contrib/libs/libtiff/tif_compress.c
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library
+ *
+ * Compression Scheme Configuration Support.
+ */
+#include "tiffiop.h"
+
+static int TIFFNoEncode(TIFF *tif, const char *method)
+{
+ const TIFFCodec *c = TIFFFindCODEC(tif->tif_dir.td_compression);
+
+ if (c)
+ {
+ TIFFErrorExtR(tif, tif->tif_name, "%s %s encoding is not implemented",
+ c->name, method);
+ }
+ else
+ {
+ TIFFErrorExtR(tif, tif->tif_name,
+ "Compression scheme %" PRIu16
+ " %s encoding is not implemented",
+ tif->tif_dir.td_compression, method);
+ }
+ return (-1);
+}
+
+int _TIFFNoRowEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
+{
+ (void)pp;
+ (void)cc;
+ (void)s;
+ return (TIFFNoEncode(tif, "scanline"));
+}
+
+int _TIFFNoStripEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
+{
+ (void)pp;
+ (void)cc;
+ (void)s;
+ return (TIFFNoEncode(tif, "strip"));
+}
+
+int _TIFFNoTileEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
+{
+ (void)pp;
+ (void)cc;
+ (void)s;
+ return (TIFFNoEncode(tif, "tile"));
+}
+
+static int TIFFNoDecode(TIFF *tif, const char *method)
+{
+ const TIFFCodec *c = TIFFFindCODEC(tif->tif_dir.td_compression);
+
+ if (c)
+ TIFFErrorExtR(tif, tif->tif_name, "%s %s decoding is not implemented",
+ c->name, method);
+ else
+ TIFFErrorExtR(tif, tif->tif_name,
+ "Compression scheme %" PRIu16
+ " %s decoding is not implemented",
+ tif->tif_dir.td_compression, method);
+ return (0);
+}
+
+static int _TIFFNoFixupTags(TIFF *tif)
+{
+ (void)tif;
+ return (1);
+}
+
+int _TIFFNoRowDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
+{
+ (void)pp;
+ (void)cc;
+ (void)s;
+ return (TIFFNoDecode(tif, "scanline"));
+}
+
+int _TIFFNoStripDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
+{
+ (void)pp;
+ (void)cc;
+ (void)s;
+ return (TIFFNoDecode(tif, "strip"));
+}
+
+int _TIFFNoTileDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
+{
+ (void)pp;
+ (void)cc;
+ (void)s;
+ return (TIFFNoDecode(tif, "tile"));
+}
+
+int _TIFFNoSeek(TIFF *tif, uint32_t off)
+{
+ (void)off;
+ TIFFErrorExtR(tif, tif->tif_name,
+ "Compression algorithm does not support random access");
+ return (0);
+}
+
+int _TIFFNoPreCode(TIFF *tif, uint16_t s)
+{
+ (void)tif;
+ (void)s;
+ return (1);
+}
+
+static int _TIFFtrue(TIFF *tif)
+{
+ (void)tif;
+ return (1);
+}
+static void _TIFFvoid(TIFF *tif) { (void)tif; }
+
+void _TIFFSetDefaultCompressionState(TIFF *tif)
+{
+ tif->tif_fixuptags = _TIFFNoFixupTags;
+ tif->tif_decodestatus = TRUE;
+ tif->tif_setupdecode = _TIFFtrue;
+ tif->tif_predecode = _TIFFNoPreCode;
+ tif->tif_decoderow = _TIFFNoRowDecode;
+ tif->tif_decodestrip = _TIFFNoStripDecode;
+ tif->tif_decodetile = _TIFFNoTileDecode;
+ tif->tif_encodestatus = TRUE;
+ tif->tif_setupencode = _TIFFtrue;
+ tif->tif_preencode = _TIFFNoPreCode;
+ tif->tif_postencode = _TIFFtrue;
+ tif->tif_encoderow = _TIFFNoRowEncode;
+ tif->tif_encodestrip = _TIFFNoStripEncode;
+ tif->tif_encodetile = _TIFFNoTileEncode;
+ tif->tif_close = _TIFFvoid;
+ tif->tif_seek = _TIFFNoSeek;
+ tif->tif_cleanup = _TIFFvoid;
+ tif->tif_defstripsize = _TIFFDefaultStripSize;
+ tif->tif_deftilesize = _TIFFDefaultTileSize;
+ tif->tif_flags &= ~(TIFF_NOBITREV | TIFF_NOREADRAW);
+}
+
+int TIFFSetCompressionScheme(TIFF *tif, int scheme)
+{
+ const TIFFCodec *c = TIFFFindCODEC((uint16_t)scheme);
+
+ _TIFFSetDefaultCompressionState(tif);
+ /*
+ * Don't treat an unknown compression scheme as an error.
+ * This permits applications to open files with data that
+ * the library does not have builtin support for, but which
+ * may still be meaningful.
+ */
+ return (c ? (*c->init)(tif, scheme) : 1);
+}
+
+/*
+ * Other compression schemes may be registered. Registered
+ * schemes can also override the builtin versions provided
+ * by this library.
+ */
+typedef struct _codec
+{
+ struct _codec *next;
+ TIFFCodec *info;
+} codec_t;
+static codec_t *registeredCODECS = NULL;
+
+const TIFFCodec *TIFFFindCODEC(uint16_t scheme)
+{
+ const TIFFCodec *c;
+ codec_t *cd;
+
+ for (cd = registeredCODECS; cd; cd = cd->next)
+ if (cd->info->scheme == scheme)
+ return ((const TIFFCodec *)cd->info);
+ for (c = _TIFFBuiltinCODECS; c->name; c++)
+ if (c->scheme == scheme)
+ return (c);
+ return ((const TIFFCodec *)0);
+}
+
+TIFFCodec *TIFFRegisterCODEC(uint16_t scheme, const char *name,
+ TIFFInitMethod init)
+{
+ codec_t *cd = (codec_t *)_TIFFmallocExt(
+ NULL,
+ (tmsize_t)(sizeof(codec_t) + sizeof(TIFFCodec) + strlen(name) + 1));
+
+ if (cd != NULL)
+ {
+ cd->info = (TIFFCodec *)((uint8_t *)cd + sizeof(codec_t));
+ cd->info->name = (char *)((uint8_t *)cd->info + sizeof(TIFFCodec));
+ strcpy(cd->info->name, name);
+ cd->info->scheme = scheme;
+ cd->info->init = init;
+ cd->next = registeredCODECS;
+ registeredCODECS = cd;
+ }
+ else
+ {
+ TIFFErrorExt(0, "TIFFRegisterCODEC",
+ "No space to register compression scheme %s", name);
+ return NULL;
+ }
+ return (cd->info);
+}
+
+void TIFFUnRegisterCODEC(TIFFCodec *c)
+{
+ codec_t *cd;
+ codec_t **pcd;
+
+ for (pcd = &registeredCODECS; (cd = *pcd) != NULL; pcd = &cd->next)
+ if (cd->info == c)
+ {
+ *pcd = cd->next;
+ _TIFFfreeExt(NULL, cd);
+ return;
+ }
+ TIFFErrorExt(0, "TIFFUnRegisterCODEC",
+ "Cannot remove compression scheme %s; not registered",
+ c->name);
+}
+
+/************************************************************************/
+/* TIFFGetConfisuredCODECs() */
+/************************************************************************/
+
+/**
+ * Get list of configured codecs, both built-in and registered by user.
+ * Caller is responsible to free this structure.
+ *
+ * @return returns array of TIFFCodec records (the last record should be NULL)
+ * or NULL if function failed.
+ */
+
+TIFFCodec *TIFFGetConfiguredCODECs()
+{
+ int i = 1;
+ codec_t *cd;
+ const TIFFCodec *c;
+ TIFFCodec *codecs = NULL;
+ TIFFCodec *new_codecs;
+
+ for (cd = registeredCODECS; cd; cd = cd->next)
+ {
+ new_codecs =
+ (TIFFCodec *)_TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec));
+ if (!new_codecs)
+ {
+ _TIFFfreeExt(NULL, codecs);
+ return NULL;
+ }
+ codecs = new_codecs;
+ _TIFFmemcpy(codecs + i - 1, cd->info, sizeof(TIFFCodec));
+ i++;
+ }
+ for (c = _TIFFBuiltinCODECS; c->name; c++)
+ {
+ if (TIFFIsCODECConfigured(c->scheme))
+ {
+ new_codecs = (TIFFCodec *)_TIFFreallocExt(NULL, codecs,
+ i * sizeof(TIFFCodec));
+ if (!new_codecs)
+ {
+ _TIFFfreeExt(NULL, codecs);
+ return NULL;
+ }
+ codecs = new_codecs;
+ _TIFFmemcpy(codecs + i - 1, (const void *)c, sizeof(TIFFCodec));
+ i++;
+ }
+ }
+
+ new_codecs =
+ (TIFFCodec *)_TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec));
+ if (!new_codecs)
+ {
+ _TIFFfreeExt(NULL, codecs);
+ return NULL;
+ }
+ codecs = new_codecs;
+ _TIFFmemset(codecs + i - 1, 0, sizeof(TIFFCodec));
+
+ return codecs;
+}
diff --git a/contrib/libs/libtiff/tif_config.h b/contrib/libs/libtiff/tif_config.h
new file mode 100644
index 0000000000..53c84d59a0
--- /dev/null
+++ b/contrib/libs/libtiff/tif_config.h
@@ -0,0 +1,166 @@
+/* clang-format off */
+/* clang-format disabled because CMake scripts are very sensitive to the
+ * formatting of this file. configure_file variables of type "" are
+ * modified by clang-format and won't be substituted.
+ */
+
+/* libtiff/tif_config.h.cmake.in. Not generated, but originated from autoheader. */
+/* This file must be kept up-to-date with needed substitutions from libtiff/tif_config.h.in. */
+
+#include "tiffconf.h"
+
+/* Support CCITT Group 3 & 4 algorithms */
+#define CCITT_SUPPORT 1
+
+/* Pick up YCbCr subsampling info from the JPEG data stream to support files
+ lacking the tag (default enabled). */
+#define CHECK_JPEG_YCBCR_SUBSAMPLING 1
+
+/* enable partial strip reading for large strips (experimental) */
+/* #undef CHUNKY_STRIP_READ_SUPPORT */
+
+/* Support C++ stream API (requires C++ compiler) */
+#define CXX_SUPPORT 1
+
+/* enable deferred strip/tile offset/size loading (experimental) */
+/* #undef DEFER_STRILE_LOAD */
+
+/* Define to 1 if you have the <assert.h> header file. */
+#define HAVE_ASSERT_H 1
+
+/* Define to 1 if you have the declaration of `optarg', and to 0 if you don't. */
+#define HAVE_DECL_OPTARG 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
+/* #undef HAVE_FSEEKO */
+
+/* Define to 1 if you have the `getopt' function. */
+#define HAVE_GETOPT 1
+
+/* Define to 1 if you have the <GLUT/glut.h> header file. */
+/* #undef HAVE_GLUT_GLUT_H */
+
+/* Define to 1 if you have the <GL/glut.h> header file. */
+/* #undef HAVE_GL_GLUT_H */
+
+/* Define to 1 if you have the <GL/glu.h> header file. */
+/* #undef HAVE_GL_GLU_H */
+
+/* Define to 1 if you have the <GL/gl.h> header file. */
+/* #undef HAVE_GL_GL_H */
+
+/* Define to 1 if you have the <io.h> header file. */
+/* #undef HAVE_IO_H */
+
+/* Define to 1 if you have the `jbg_newlen' function. */
+/* #undef HAVE_JBG_NEWLEN */
+
+/* Define to 1 if you have the `mmap' function. */
+#define HAVE_MMAP 1
+
+/* Define to 1 if you have the <OpenGL/glu.h> header file. */
+/* #undef HAVE_OPENGL_GLU_H */
+
+/* Define to 1 if you have the <OpenGL/gl.h> header file. */
+/* #undef HAVE_OPENGL_GL_H */
+
+/* Define to 1 if you have the `setmode' function. */
+/* #undef HAVE_SETMODE */
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* 8/12 bit libjpeg dual mode enabled */
+/* #undef JPEG_DUAL_MODE_8_12 */
+
+/* Support LERC compression */
+/* #undef LERC_SUPPORT */
+
+/* 12bit libjpeg primary include file with path */
+#define LIBJPEG_12_PATH ""
+
+/* Support LZMA2 compression */
+#define LZMA_SUPPORT 1
+
+/* Name of package */
+#define PACKAGE "LibTIFF Software"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "tiff@lists.maptools.org"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "LibTIFF Software"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "LibTIFF Software 4.5.1"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "tiff"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "4.5.1"
+
+/* Size of size_t */
+#define SIZEOF_SIZE_T 8
+
+/* Default size of the strip in bytes (when strip chopping enabled) */
+#define STRIP_SIZE_DEFAULT 8192
+
+/** Maximum number of TIFF IFDs that libtiff can iterate through in a file. */
+#define TIFF_MAX_DIR_COUNT 1048576
+
+/* define to use win32 IO system */
+/* #undef USE_WIN32_FILEIO */
+
+/* Version number of package */
+#define VERSION "4.5.1"
+
+/* Support WEBP compression */
+#define WEBP_SUPPORT 1
+
+/* Support ZSTD compression */
+#define ZSTD_SUPPORT 1
+
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+# undef WORDS_BIGENDIAN
+# endif
+#endif
+
+#if !defined(__MINGW32__)
+# define TIFF_SIZE_FORMAT "zu"
+#endif
+#if SIZEOF_SIZE_T == 8
+# define TIFF_SSIZE_FORMAT PRId64
+# if defined(__MINGW32__)
+# define TIFF_SIZE_FORMAT PRIu64
+# endif
+#elif SIZEOF_SIZE_T == 4
+# define TIFF_SSIZE_FORMAT PRId32
+# if defined(__MINGW32__)
+# define TIFF_SIZE_FORMAT PRIu32
+# endif
+#else
+# error "Unsupported size_t size; please submit a bug report"
+#endif
+
+/* clang-format on */
diff --git a/contrib/libs/libtiff/tif_dir.c b/contrib/libs/libtiff/tif_dir.c
new file mode 100644
index 0000000000..f1adf080a0
--- /dev/null
+++ b/contrib/libs/libtiff/tif_dir.c
@@ -0,0 +1,2308 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Directory Tag Get & Set Routines.
+ * (and also some miscellaneous stuff)
+ */
+#include "tiffiop.h"
+#include <float.h> /*--: for Rational2Double */
+#include <limits.h>
+
+/*
+ * These are used in the backwards compatibility code...
+ */
+#define DATATYPE_VOID 0 /* !untyped data */
+#define DATATYPE_INT 1 /* !signed integer data */
+#define DATATYPE_UINT 2 /* !unsigned integer data */
+#define DATATYPE_IEEEFP 3 /* !IEEE floating point data */
+
+static void setByteArray(TIFF *tif, void **vpp, const void *vp, size_t nmemb,
+ size_t elem_size)
+{
+ if (*vpp)
+ {
+ _TIFFfreeExt(tif, *vpp);
+ *vpp = 0;
+ }
+ if (vp)
+ {
+ tmsize_t bytes = _TIFFMultiplySSize(NULL, nmemb, elem_size, NULL);
+ if (bytes)
+ *vpp = (void *)_TIFFmallocExt(tif, bytes);
+ if (*vpp)
+ _TIFFmemcpy(*vpp, vp, bytes);
+ }
+}
+void _TIFFsetByteArray(void **vpp, const void *vp, uint32_t n)
+{
+ setByteArray(NULL, vpp, vp, n, 1);
+}
+void _TIFFsetByteArrayExt(TIFF *tif, void **vpp, const void *vp, uint32_t n)
+{
+ setByteArray(tif, vpp, vp, n, 1);
+}
+
+static void _TIFFsetNString(TIFF *tif, char **cpp, const char *cp, uint32_t n)
+{
+ setByteArray(tif, (void **)cpp, cp, n, 1);
+}
+
+void _TIFFsetShortArray(uint16_t **wpp, const uint16_t *wp, uint32_t n)
+{
+ setByteArray(NULL, (void **)wpp, wp, n, sizeof(uint16_t));
+}
+void _TIFFsetShortArrayExt(TIFF *tif, uint16_t **wpp, const uint16_t *wp,
+ uint32_t n)
+{
+ setByteArray(tif, (void **)wpp, wp, n, sizeof(uint16_t));
+}
+
+void _TIFFsetLongArray(uint32_t **lpp, const uint32_t *lp, uint32_t n)
+{
+ setByteArray(NULL, (void **)lpp, lp, n, sizeof(uint32_t));
+}
+void _TIFFsetLongArrayExt(TIFF *tif, uint32_t **lpp, const uint32_t *lp,
+ uint32_t n)
+{
+ setByteArray(tif, (void **)lpp, lp, n, sizeof(uint32_t));
+}
+
+static void _TIFFsetLong8Array(TIFF *tif, uint64_t **lpp, const uint64_t *lp,
+ uint32_t n)
+{
+ setByteArray(tif, (void **)lpp, lp, n, sizeof(uint64_t));
+}
+
+void _TIFFsetFloatArray(float **fpp, const float *fp, uint32_t n)
+{
+ setByteArray(NULL, (void **)fpp, fp, n, sizeof(float));
+}
+void _TIFFsetFloatArrayExt(TIFF *tif, float **fpp, const float *fp, uint32_t n)
+{
+ setByteArray(tif, (void **)fpp, fp, n, sizeof(float));
+}
+
+void _TIFFsetDoubleArray(double **dpp, const double *dp, uint32_t n)
+{
+ setByteArray(NULL, (void **)dpp, dp, n, sizeof(double));
+}
+void _TIFFsetDoubleArrayExt(TIFF *tif, double **dpp, const double *dp,
+ uint32_t n)
+{
+ setByteArray(tif, (void **)dpp, dp, n, sizeof(double));
+}
+
+static void setDoubleArrayOneValue(TIFF *tif, double **vpp, double value,
+ size_t nmemb)
+{
+ if (*vpp)
+ _TIFFfreeExt(tif, *vpp);
+ *vpp = _TIFFmallocExt(tif, nmemb * sizeof(double));
+ if (*vpp)
+ {
+ while (nmemb--)
+ ((double *)*vpp)[nmemb] = value;
+ }
+}
+
+/*
+ * Install extra samples information.
+ */
+static int setExtraSamples(TIFF *tif, va_list ap, uint32_t *v)
+{
+/* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */
+#define EXTRASAMPLE_COREL_UNASSALPHA 999
+
+ uint16_t *va;
+ uint32_t i;
+ TIFFDirectory *td = &tif->tif_dir;
+ static const char module[] = "setExtraSamples";
+
+ *v = (uint16_t)va_arg(ap, uint16_vap);
+ if ((uint16_t)*v > td->td_samplesperpixel)
+ return 0;
+ va = va_arg(ap, uint16_t *);
+ if (*v > 0 && va == NULL) /* typically missing param */
+ return 0;
+ for (i = 0; i < *v; i++)
+ {
+ if (va[i] > EXTRASAMPLE_UNASSALPHA)
+ {
+ /*
+ * XXX: Corel Draw is known to produce incorrect
+ * ExtraSamples tags which must be patched here if we
+ * want to be able to open some of the damaged TIFF
+ * files:
+ */
+ if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA)
+ va[i] = EXTRASAMPLE_UNASSALPHA;
+ else
+ return 0;
+ }
+ }
+
+ if (td->td_transferfunction[0] != NULL &&
+ (td->td_samplesperpixel - *v > 1) &&
+ !(td->td_samplesperpixel - td->td_extrasamples > 1))
+ {
+ TIFFWarningExtR(tif, module,
+ "ExtraSamples tag value is changing, "
+ "but TransferFunction was read with a different value. "
+ "Canceling it");
+ TIFFClrFieldBit(tif, FIELD_TRANSFERFUNCTION);
+ _TIFFfreeExt(tif, td->td_transferfunction[0]);
+ td->td_transferfunction[0] = NULL;
+ }
+
+ td->td_extrasamples = (uint16_t)*v;
+ _TIFFsetShortArrayExt(tif, &td->td_sampleinfo, va, td->td_extrasamples);
+ return 1;
+
+#undef EXTRASAMPLE_COREL_UNASSALPHA
+}
+
+/*
+ * Count ink names separated by \0. Returns
+ * zero if the ink names are not as expected.
+ */
+static uint16_t countInkNamesString(TIFF *tif, uint32_t slen, const char *s)
+{
+ uint16_t i = 0;
+
+ if (slen > 0)
+ {
+ const char *ep = s + slen;
+ const char *cp = s;
+ do
+ {
+ for (; cp < ep && *cp != '\0'; cp++)
+ {
+ }
+ if (cp >= ep)
+ goto bad;
+ cp++; /* skip \0 */
+ i++;
+ } while (cp < ep);
+ return (i);
+ }
+bad:
+ TIFFErrorExtR(tif, "TIFFSetField",
+ "%s: Invalid InkNames value; no NUL at given buffer end "
+ "location %" PRIu32 ", after %" PRIu16 " ink",
+ tif->tif_name, slen, i);
+ return (0);
+}
+
+static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
+{
+ static const char module[] = "_TIFFVSetField";
+
+ TIFFDirectory *td = &tif->tif_dir;
+ int status = 1;
+ uint32_t v32, v;
+ double dblval;
+ char *s;
+ const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
+ uint32_t standard_tag = tag;
+ if (fip == NULL) /* cannot happen since OkToChangeTag() already checks it */
+ return 0;
+ /*
+ * We want to force the custom code to be used for custom
+ * fields even if the tag happens to match a well known
+ * one - important for reinterpreted handling of standard
+ * tag values in custom directories (i.e. EXIF)
+ */
+ if (fip->field_bit == FIELD_CUSTOM)
+ {
+ standard_tag = 0;
+ }
+
+ switch (standard_tag)
+ {
+ case TIFFTAG_SUBFILETYPE:
+ td->td_subfiletype = (uint32_t)va_arg(ap, uint32_t);
+ break;
+ case TIFFTAG_IMAGEWIDTH:
+ td->td_imagewidth = (uint32_t)va_arg(ap, uint32_t);
+ break;
+ case TIFFTAG_IMAGELENGTH:
+ td->td_imagelength = (uint32_t)va_arg(ap, uint32_t);
+ break;
+ case TIFFTAG_BITSPERSAMPLE:
+ td->td_bitspersample = (uint16_t)va_arg(ap, uint16_vap);
+ /*
+ * If the data require post-decoding processing to byte-swap
+ * samples, set it up here. Note that since tags are required
+ * to be ordered, compression code can override this behavior
+ * in the setup method if it wants to roll the post decoding
+ * work in with its normal work.
+ */
+ if (tif->tif_flags & TIFF_SWAB)
+ {
+ if (td->td_bitspersample == 8)
+ tif->tif_postdecode = _TIFFNoPostDecode;
+ else if (td->td_bitspersample == 16)
+ tif->tif_postdecode = _TIFFSwab16BitData;
+ else if (td->td_bitspersample == 24)
+ tif->tif_postdecode = _TIFFSwab24BitData;
+ else if (td->td_bitspersample == 32)
+ tif->tif_postdecode = _TIFFSwab32BitData;
+ else if (td->td_bitspersample == 64)
+ tif->tif_postdecode = _TIFFSwab64BitData;
+ else if (td->td_bitspersample == 128) /* two 64's */
+ tif->tif_postdecode = _TIFFSwab64BitData;
+ }
+ break;
+ case TIFFTAG_COMPRESSION:
+ v = (uint16_t)va_arg(ap, uint16_vap);
+ /*
+ * If we're changing the compression scheme, notify the
+ * previous module so that it can cleanup any state it's
+ * setup.
+ */
+ if (TIFFFieldSet(tif, FIELD_COMPRESSION))
+ {
+ if ((uint32_t)td->td_compression == v)
+ break;
+ (*tif->tif_cleanup)(tif);
+ tif->tif_flags &= ~TIFF_CODERSETUP;
+ }
+ /*
+ * Setup new compression routine state.
+ */
+ if ((status = TIFFSetCompressionScheme(tif, v)) != 0)
+ td->td_compression = (uint16_t)v;
+ else
+ status = 0;
+ break;
+ case TIFFTAG_PHOTOMETRIC:
+ td->td_photometric = (uint16_t)va_arg(ap, uint16_vap);
+ break;
+ case TIFFTAG_THRESHHOLDING:
+ td->td_threshholding = (uint16_t)va_arg(ap, uint16_vap);
+ break;
+ case TIFFTAG_FILLORDER:
+ v = (uint16_t)va_arg(ap, uint16_vap);
+ if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB)
+ goto badvalue;
+ td->td_fillorder = (uint16_t)v;
+ break;
+ case TIFFTAG_ORIENTATION:
+ v = (uint16_t)va_arg(ap, uint16_vap);
+ if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v)
+ goto badvalue;
+ else
+ td->td_orientation = (uint16_t)v;
+ break;
+ case TIFFTAG_SAMPLESPERPIXEL:
+ v = (uint16_t)va_arg(ap, uint16_vap);
+ if (v == 0)
+ goto badvalue;
+ if (v != td->td_samplesperpixel)
+ {
+ /* See http://bugzilla.maptools.org/show_bug.cgi?id=2500 */
+ if (td->td_sminsamplevalue != NULL)
+ {
+ TIFFWarningExtR(tif, module,
+ "SamplesPerPixel tag value is changing, "
+ "but SMinSampleValue tag was read with a "
+ "different value. Canceling it");
+ TIFFClrFieldBit(tif, FIELD_SMINSAMPLEVALUE);
+ _TIFFfreeExt(tif, td->td_sminsamplevalue);
+ td->td_sminsamplevalue = NULL;
+ }
+ if (td->td_smaxsamplevalue != NULL)
+ {
+ TIFFWarningExtR(tif, module,
+ "SamplesPerPixel tag value is changing, "
+ "but SMaxSampleValue tag was read with a "
+ "different value. Canceling it");
+ TIFFClrFieldBit(tif, FIELD_SMAXSAMPLEVALUE);
+ _TIFFfreeExt(tif, td->td_smaxsamplevalue);
+ td->td_smaxsamplevalue = NULL;
+ }
+ /* Test if 3 transfer functions instead of just one are now
+ needed See http://bugzilla.maptools.org/show_bug.cgi?id=2820
+ */
+ if (td->td_transferfunction[0] != NULL &&
+ (v - td->td_extrasamples > 1) &&
+ !(td->td_samplesperpixel - td->td_extrasamples > 1))
+ {
+ TIFFWarningExtR(tif, module,
+ "SamplesPerPixel tag value is changing, "
+ "but TransferFunction was read with a "
+ "different value. Canceling it");
+ TIFFClrFieldBit(tif, FIELD_TRANSFERFUNCTION);
+ _TIFFfreeExt(tif, td->td_transferfunction[0]);
+ td->td_transferfunction[0] = NULL;
+ }
+ }
+ td->td_samplesperpixel = (uint16_t)v;
+ break;
+ case TIFFTAG_ROWSPERSTRIP:
+ v32 = (uint32_t)va_arg(ap, uint32_t);
+ if (v32 == 0)
+ goto badvalue32;
+ td->td_rowsperstrip = v32;
+ if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS))
+ {
+ td->td_tilelength = v32;
+ td->td_tilewidth = td->td_imagewidth;
+ }
+ break;
+ case TIFFTAG_MINSAMPLEVALUE:
+ td->td_minsamplevalue = (uint16_t)va_arg(ap, uint16_vap);
+ break;
+ case TIFFTAG_MAXSAMPLEVALUE:
+ td->td_maxsamplevalue = (uint16_t)va_arg(ap, uint16_vap);
+ break;
+ case TIFFTAG_SMINSAMPLEVALUE:
+ if (tif->tif_flags & TIFF_PERSAMPLE)
+ _TIFFsetDoubleArrayExt(tif, &td->td_sminsamplevalue,
+ va_arg(ap, double *),
+ td->td_samplesperpixel);
+ else
+ setDoubleArrayOneValue(tif, &td->td_sminsamplevalue,
+ va_arg(ap, double),
+ td->td_samplesperpixel);
+ break;
+ case TIFFTAG_SMAXSAMPLEVALUE:
+ if (tif->tif_flags & TIFF_PERSAMPLE)
+ _TIFFsetDoubleArrayExt(tif, &td->td_smaxsamplevalue,
+ va_arg(ap, double *),
+ td->td_samplesperpixel);
+ else
+ setDoubleArrayOneValue(tif, &td->td_smaxsamplevalue,
+ va_arg(ap, double),
+ td->td_samplesperpixel);
+ break;
+ case TIFFTAG_XRESOLUTION:
+ dblval = va_arg(ap, double);
+ if (dblval != dblval || dblval < 0)
+ goto badvaluedouble;
+ td->td_xresolution = _TIFFClampDoubleToFloat(dblval);
+ break;
+ case TIFFTAG_YRESOLUTION:
+ dblval = va_arg(ap, double);
+ if (dblval != dblval || dblval < 0)
+ goto badvaluedouble;
+ td->td_yresolution = _TIFFClampDoubleToFloat(dblval);
+ break;
+ case TIFFTAG_PLANARCONFIG:
+ v = (uint16_t)va_arg(ap, uint16_vap);
+ if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE)
+ goto badvalue;
+ td->td_planarconfig = (uint16_t)v;
+ break;
+ case TIFFTAG_XPOSITION:
+ td->td_xposition = _TIFFClampDoubleToFloat(va_arg(ap, double));
+ break;
+ case TIFFTAG_YPOSITION:
+ td->td_yposition = _TIFFClampDoubleToFloat(va_arg(ap, double));
+ break;
+ case TIFFTAG_RESOLUTIONUNIT:
+ v = (uint16_t)va_arg(ap, uint16_vap);
+ if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v)
+ goto badvalue;
+ td->td_resolutionunit = (uint16_t)v;
+ break;
+ case TIFFTAG_PAGENUMBER:
+ td->td_pagenumber[0] = (uint16_t)va_arg(ap, uint16_vap);
+ td->td_pagenumber[1] = (uint16_t)va_arg(ap, uint16_vap);
+ break;
+ case TIFFTAG_HALFTONEHINTS:
+ td->td_halftonehints[0] = (uint16_t)va_arg(ap, uint16_vap);
+ td->td_halftonehints[1] = (uint16_t)va_arg(ap, uint16_vap);
+ break;
+ case TIFFTAG_COLORMAP:
+ v32 = (uint32_t)(1L << td->td_bitspersample);
+ _TIFFsetShortArrayExt(tif, &td->td_colormap[0],
+ va_arg(ap, uint16_t *), v32);
+ _TIFFsetShortArrayExt(tif, &td->td_colormap[1],
+ va_arg(ap, uint16_t *), v32);
+ _TIFFsetShortArrayExt(tif, &td->td_colormap[2],
+ va_arg(ap, uint16_t *), v32);
+ break;
+ case TIFFTAG_EXTRASAMPLES:
+ if (!setExtraSamples(tif, ap, &v))
+ goto badvalue;
+ break;
+ case TIFFTAG_MATTEING:
+ td->td_extrasamples = (((uint16_t)va_arg(ap, uint16_vap)) != 0);
+ if (td->td_extrasamples)
+ {
+ uint16_t sv = EXTRASAMPLE_ASSOCALPHA;
+ _TIFFsetShortArrayExt(tif, &td->td_sampleinfo, &sv, 1);
+ }
+ break;
+ case TIFFTAG_TILEWIDTH:
+ v32 = (uint32_t)va_arg(ap, uint32_t);
+ if (v32 % 16)
+ {
+ if (tif->tif_mode != O_RDONLY)
+ goto badvalue32;
+ TIFFWarningExtR(
+ tif, tif->tif_name,
+ "Nonstandard tile width %" PRIu32 ", convert file", v32);
+ }
+ td->td_tilewidth = v32;
+ tif->tif_flags |= TIFF_ISTILED;
+ break;
+ case TIFFTAG_TILELENGTH:
+ v32 = (uint32_t)va_arg(ap, uint32_t);
+ if (v32 % 16)
+ {
+ if (tif->tif_mode != O_RDONLY)
+ goto badvalue32;
+ TIFFWarningExtR(
+ tif, tif->tif_name,
+ "Nonstandard tile length %" PRIu32 ", convert file", v32);
+ }
+ td->td_tilelength = v32;
+ tif->tif_flags |= TIFF_ISTILED;
+ break;
+ case TIFFTAG_TILEDEPTH:
+ v32 = (uint32_t)va_arg(ap, uint32_t);
+ if (v32 == 0)
+ goto badvalue32;
+ td->td_tiledepth = v32;
+ break;
+ case TIFFTAG_DATATYPE:
+ v = (uint16_t)va_arg(ap, uint16_vap);
+ switch (v)
+ {
+ case DATATYPE_VOID:
+ v = SAMPLEFORMAT_VOID;
+ break;
+ case DATATYPE_INT:
+ v = SAMPLEFORMAT_INT;
+ break;
+ case DATATYPE_UINT:
+ v = SAMPLEFORMAT_UINT;
+ break;
+ case DATATYPE_IEEEFP:
+ v = SAMPLEFORMAT_IEEEFP;
+ break;
+ default:
+ goto badvalue;
+ }
+ td->td_sampleformat = (uint16_t)v;
+ break;
+ case TIFFTAG_SAMPLEFORMAT:
+ v = (uint16_t)va_arg(ap, uint16_vap);
+ if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v)
+ goto badvalue;
+ td->td_sampleformat = (uint16_t)v;
+
+ /* Try to fix up the SWAB function for complex data. */
+ if (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT &&
+ td->td_bitspersample == 32 &&
+ tif->tif_postdecode == _TIFFSwab32BitData)
+ tif->tif_postdecode = _TIFFSwab16BitData;
+ else if ((td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT ||
+ td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP) &&
+ td->td_bitspersample == 64 &&
+ tif->tif_postdecode == _TIFFSwab64BitData)
+ tif->tif_postdecode = _TIFFSwab32BitData;
+ break;
+ case TIFFTAG_IMAGEDEPTH:
+ td->td_imagedepth = (uint32_t)va_arg(ap, uint32_t);
+ break;
+ case TIFFTAG_SUBIFD:
+ if ((tif->tif_flags & TIFF_INSUBIFD) == 0)
+ {
+ td->td_nsubifd = (uint16_t)va_arg(ap, uint16_vap);
+ _TIFFsetLong8Array(tif, &td->td_subifd,
+ (uint64_t *)va_arg(ap, uint64_t *),
+ (uint32_t)td->td_nsubifd);
+ }
+ else
+ {
+ TIFFErrorExtR(tif, module, "%s: Sorry, cannot nest SubIFDs",
+ tif->tif_name);
+ status = 0;
+ }
+ break;
+ case TIFFTAG_YCBCRPOSITIONING:
+ td->td_ycbcrpositioning = (uint16_t)va_arg(ap, uint16_vap);
+ break;
+ case TIFFTAG_YCBCRSUBSAMPLING:
+ td->td_ycbcrsubsampling[0] = (uint16_t)va_arg(ap, uint16_vap);
+ td->td_ycbcrsubsampling[1] = (uint16_t)va_arg(ap, uint16_vap);
+ break;
+ case TIFFTAG_TRANSFERFUNCTION:
+ {
+ uint32_t i;
+ v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
+ for (i = 0; i < v; i++)
+ _TIFFsetShortArrayExt(tif, &td->td_transferfunction[i],
+ va_arg(ap, uint16_t *),
+ 1U << td->td_bitspersample);
+ break;
+ }
+ case TIFFTAG_REFERENCEBLACKWHITE:
+ /* XXX should check for null range */
+ _TIFFsetFloatArrayExt(tif, &td->td_refblackwhite,
+ va_arg(ap, float *), 6);
+ break;
+ case TIFFTAG_INKNAMES:
+ {
+ v = (uint16_t)va_arg(ap, uint16_vap);
+ s = va_arg(ap, char *);
+ uint16_t ninksinstring;
+ ninksinstring = countInkNamesString(tif, v, s);
+ status = ninksinstring > 0;
+ if (ninksinstring > 0)
+ {
+ _TIFFsetNString(tif, &td->td_inknames, s, v);
+ td->td_inknameslen = v;
+ /* Set NumberOfInks to the value ninksinstring */
+ if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS))
+ {
+ if (td->td_numberofinks != ninksinstring)
+ {
+ TIFFErrorExtR(
+ tif, module,
+ "Warning %s; Tag %s:\n Value %" PRIu16
+ " of NumberOfInks is different from the number of "
+ "inks %" PRIu16
+ ".\n -> NumberOfInks value adapted to %" PRIu16 "",
+ tif->tif_name, fip->field_name, td->td_numberofinks,
+ ninksinstring, ninksinstring);
+ td->td_numberofinks = ninksinstring;
+ }
+ }
+ else
+ {
+ td->td_numberofinks = ninksinstring;
+ TIFFSetFieldBit(tif, FIELD_NUMBEROFINKS);
+ }
+ if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
+ {
+ if (td->td_numberofinks != td->td_samplesperpixel)
+ {
+ TIFFErrorExtR(tif, module,
+ "Warning %s; Tag %s:\n Value %" PRIu16
+ " of NumberOfInks is different from the "
+ "SamplesPerPixel value %" PRIu16 "",
+ tif->tif_name, fip->field_name,
+ td->td_numberofinks,
+ td->td_samplesperpixel);
+ }
+ }
+ }
+ }
+ break;
+ case TIFFTAG_NUMBEROFINKS:
+ v = (uint16_t)va_arg(ap, uint16_vap);
+ /* If InkNames already set also NumberOfInks is set accordingly and
+ * should be equal */
+ if (TIFFFieldSet(tif, FIELD_INKNAMES))
+ {
+ if (v != td->td_numberofinks)
+ {
+ TIFFErrorExtR(
+ tif, module,
+ "Error %s; Tag %s:\n It is not possible to set the "
+ "value %" PRIu32
+ " for NumberOfInks\n which is different from the "
+ "number of inks in the InkNames tag (%" PRIu16 ")",
+ tif->tif_name, fip->field_name, v, td->td_numberofinks);
+ /* Do not set / overwrite number of inks already set by
+ * InkNames case accordingly. */
+ status = 0;
+ }
+ }
+ else
+ {
+ td->td_numberofinks = (uint16_t)v;
+ if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
+ {
+ if (td->td_numberofinks != td->td_samplesperpixel)
+ {
+ TIFFErrorExtR(tif, module,
+ "Warning %s; Tag %s:\n Value %" PRIu32
+ " of NumberOfInks is different from the "
+ "SamplesPerPixel value %" PRIu16 "",
+ tif->tif_name, fip->field_name, v,
+ td->td_samplesperpixel);
+ }
+ }
+ }
+ break;
+ case TIFFTAG_PERSAMPLE:
+ v = (uint16_t)va_arg(ap, uint16_vap);
+ if (v == PERSAMPLE_MULTI)
+ tif->tif_flags |= TIFF_PERSAMPLE;
+ else
+ tif->tif_flags &= ~TIFF_PERSAMPLE;
+ break;
+ default:
+ {
+ TIFFTagValue *tv;
+ int tv_size, iCustom;
+
+ /*
+ * This can happen if multiple images are open with different
+ * codecs which have private tags. The global tag information
+ * table may then have tags that are valid for one file but not
+ * the other. If the client tries to set a tag that is not valid
+ * for the image's codec then we'll arrive here. This
+ * happens, for example, when tiffcp is used to convert between
+ * compression schemes and codec-specific tags are blindly copied.
+ *
+ * This also happens when a FIELD_IGNORE tag is written.
+ */
+ if (fip->field_bit == FIELD_IGNORE)
+ {
+ TIFFErrorExtR(
+ tif, module,
+ "%s: Ignored %stag \"%s\" (not supported by libtiff)",
+ tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
+ fip->field_name);
+ status = 0;
+ break;
+ }
+ if (fip->field_bit != FIELD_CUSTOM)
+ {
+ TIFFErrorExtR(
+ tif, module,
+ "%s: Invalid %stag \"%s\" (not supported by codec)",
+ tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
+ fip->field_name);
+ status = 0;
+ break;
+ }
+
+ /*
+ * Find the existing entry for this custom value.
+ */
+ tv = NULL;
+ for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++)
+ {
+ if (td->td_customValues[iCustom].info->field_tag == tag)
+ {
+ tv = td->td_customValues + iCustom;
+ if (tv->value != NULL)
+ {
+ _TIFFfreeExt(tif, tv->value);
+ tv->value = NULL;
+ }
+ break;
+ }
+ }
+
+ /*
+ * Grow the custom list if the entry was not found.
+ */
+ if (tv == NULL)
+ {
+ TIFFTagValue *new_customValues;
+
+ td->td_customValueCount++;
+ new_customValues = (TIFFTagValue *)_TIFFreallocExt(
+ tif, td->td_customValues,
+ sizeof(TIFFTagValue) * td->td_customValueCount);
+ if (!new_customValues)
+ {
+ TIFFErrorExtR(tif, module,
+ "%s: Failed to allocate space for list of "
+ "custom values",
+ tif->tif_name);
+ status = 0;
+ goto end;
+ }
+
+ td->td_customValues = new_customValues;
+
+ tv = td->td_customValues + (td->td_customValueCount - 1);
+ tv->info = fip;
+ tv->value = NULL;
+ tv->count = 0;
+ }
+
+ /*
+ * Set custom value ... save a copy of the custom tag value.
+ */
+ /*--: Rational2Double: For Rationals evaluate "set_field_type" to
+ * determine internal storage size. */
+ tv_size = TIFFFieldSetGetSize(fip);
+ if (tv_size == 0)
+ {
+ status = 0;
+ TIFFErrorExtR(tif, module, "%s: Bad field type %d for \"%s\"",
+ tif->tif_name, fip->field_type, fip->field_name);
+ goto end;
+ }
+
+ if (fip->field_type == TIFF_ASCII)
+ {
+ uint32_t ma;
+ const char *mb;
+ if (fip->field_passcount)
+ {
+ assert(fip->field_writecount == TIFF_VARIABLE2);
+ ma = (uint32_t)va_arg(ap, uint32_t);
+ mb = (const char *)va_arg(ap, const char *);
+ }
+ else
+ {
+ mb = (const char *)va_arg(ap, const char *);
+ size_t len = strlen(mb) + 1;
+ if (len >= 0x80000000U)
+ {
+ status = 0;
+ TIFFErrorExtR(tif, 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(tif, &tv->value, mb, ma, 1);
+ }
+ else
+ {
+ if (fip->field_passcount)
+ {
+ if (fip->field_writecount == TIFF_VARIABLE2)
+ tv->count = (uint32_t)va_arg(ap, uint32_t);
+ else
+ tv->count = (int)va_arg(ap, int);
+ }
+ else if (fip->field_writecount == TIFF_VARIABLE ||
+ fip->field_writecount == TIFF_VARIABLE2)
+ tv->count = 1;
+ else if (fip->field_writecount == TIFF_SPP)
+ tv->count = td->td_samplesperpixel;
+ else
+ tv->count = fip->field_writecount;
+
+ if (tv->count == 0)
+ {
+ status = 0;
+ TIFFWarningExtR(tif, module,
+ "%s: Null count for \"%s\" (type "
+ "%d, writecount %d, passcount %d)",
+ tif->tif_name, fip->field_name,
+ fip->field_type, fip->field_writecount,
+ fip->field_passcount);
+ goto end;
+ }
+
+ tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size,
+ "custom tag binary object");
+ if (!tv->value)
+ {
+ status = 0;
+ goto end;
+ }
+
+ if (fip->field_tag == TIFFTAG_DOTRANGE &&
+ strcmp(fip->field_name, "DotRange") == 0)
+ {
+ /* TODO: This is an evil exception and should not have been
+ 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 */
+ uint16_t v2[2];
+ v2[0] = (uint16_t)va_arg(ap, int);
+ v2[1] = (uint16_t)va_arg(ap, int);
+ _TIFFmemcpy(tv->value, &v2, 4);
+ }
+
+ else if (fip->field_passcount ||
+ fip->field_writecount == TIFF_VARIABLE ||
+ fip->field_writecount == TIFF_VARIABLE2 ||
+ fip->field_writecount == TIFF_SPP || tv->count > 1)
+ {
+ /*--: Rational2Double: For Rationals tv_size is set above to
+ * 4 or 8 according to fip->set_field_type! */
+ _TIFFmemcpy(tv->value, va_arg(ap, void *),
+ tv->count * tv_size);
+ /* Test here for too big values for LONG8, SLONG8 in
+ * ClassicTIFF and delete custom field from custom list */
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ if (tv->info->field_type == TIFF_LONG8)
+ {
+ uint64_t *pui64 = (uint64_t *)tv->value;
+ for (int i = 0; i < tv->count; i++)
+ {
+ if (pui64[i] > 0xffffffffu)
+ {
+ TIFFErrorExtR(
+ tif, module,
+ "%s: Bad LONG8 value %" PRIu64
+ " at %d. array position for \"%s\" tag "
+ "%d in ClassicTIFF. Tag won't be "
+ "written to file",
+ tif->tif_name, pui64[i], i,
+ fip->field_name, tag);
+ goto badvalueifd8long8;
+ }
+ }
+ }
+ else if (tv->info->field_type == TIFF_SLONG8)
+ {
+ int64_t *pi64 = (int64_t *)tv->value;
+ for (int i = 0; i < tv->count; i++)
+ {
+ if (pi64[i] > 2147483647 ||
+ pi64[i] < (-2147483647 - 1))
+ {
+ TIFFErrorExtR(
+ tif, module,
+ "%s: Bad SLONG8 value %" PRIi64
+ " at %d. array position for \"%s\" tag "
+ "%d in ClassicTIFF. Tag won't be "
+ "written to file",
+ tif->tif_name, pi64[i], i,
+ fip->field_name, tag);
+ goto badvalueifd8long8;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ char *val = (char *)tv->value;
+ assert(tv->count == 1);
+
+ switch (fip->field_type)
+ {
+ case TIFF_BYTE:
+ case TIFF_UNDEFINED:
+ {
+ uint8_t v2 = (uint8_t)va_arg(ap, int);
+ _TIFFmemcpy(val, &v2, tv_size);
+ }
+ break;
+ case TIFF_SBYTE:
+ {
+ int8_t v2 = (int8_t)va_arg(ap, int);
+ _TIFFmemcpy(val, &v2, tv_size);
+ }
+ break;
+ case TIFF_SHORT:
+ {
+ uint16_t v2 = (uint16_t)va_arg(ap, int);
+ _TIFFmemcpy(val, &v2, tv_size);
+ }
+ break;
+ case TIFF_SSHORT:
+ {
+ int16_t v2 = (int16_t)va_arg(ap, int);
+ _TIFFmemcpy(val, &v2, tv_size);
+ }
+ break;
+ case TIFF_LONG:
+ case TIFF_IFD:
+ {
+ uint32_t v2 = va_arg(ap, uint32_t);
+ _TIFFmemcpy(val, &v2, tv_size);
+ }
+ break;
+ case TIFF_SLONG:
+ {
+ int32_t v2 = va_arg(ap, int32_t);
+ _TIFFmemcpy(val, &v2, tv_size);
+ }
+ break;
+ case TIFF_LONG8:
+ case TIFF_IFD8:
+ {
+ uint64_t v2 = va_arg(ap, uint64_t);
+ _TIFFmemcpy(val, &v2, tv_size);
+ /* Test here for too big values for ClassicTIFF and
+ * delete custom field from custom list */
+ if (!(tif->tif_flags & TIFF_BIGTIFF) &&
+ (v2 > 0xffffffffu))
+ {
+ TIFFErrorExtR(
+ tif, module,
+ "%s: Bad LONG8 or IFD8 value %" PRIu64
+ " for \"%s\" tag %d in ClassicTIFF. Tag "
+ "won't be written to file",
+ tif->tif_name, v2, fip->field_name, tag);
+ goto badvalueifd8long8;
+ }
+ }
+ break;
+ case TIFF_SLONG8:
+ {
+ int64_t v2 = va_arg(ap, int64_t);
+ _TIFFmemcpy(val, &v2, tv_size);
+ /* Test here for too big values for ClassicTIFF and
+ * delete custom field from custom list */
+ if (!(tif->tif_flags & TIFF_BIGTIFF) &&
+ ((v2 > 2147483647) || (v2 < (-2147483647 - 1))))
+ {
+ TIFFErrorExtR(
+ tif, module,
+ "%s: Bad SLONG8 value %" PRIi64
+ " for \"%s\" tag %d in ClassicTIFF. Tag "
+ "won't be written to file",
+ tif->tif_name, v2, fip->field_name, tag);
+ goto badvalueifd8long8;
+ }
+ }
+ break;
+ case TIFF_RATIONAL:
+ case TIFF_SRATIONAL:
+ /*-- Rational2Double: For Rationals tv_size is set
+ * above to 4 or 8 according to fip->set_field_type!
+ */
+ {
+ if (tv_size == 8)
+ {
+ double v2 = va_arg(ap, double);
+ _TIFFmemcpy(val, &v2, tv_size);
+ }
+ else
+ {
+ /*-- default should be tv_size == 4 */
+ float v3 = (float)va_arg(ap, double);
+ _TIFFmemcpy(val, &v3, tv_size);
+ /*-- ToDo: After Testing, this should be
+ * removed and tv_size==4 should be set as
+ * default. */
+ if (tv_size != 4)
+ {
+ TIFFErrorExtR(
+ tif, module,
+ "Rational2Double: .set_field_type "
+ "in not 4 but %d",
+ tv_size);
+ }
+ }
+ }
+ break;
+ case TIFF_FLOAT:
+ {
+ float v2 =
+ _TIFFClampDoubleToFloat(va_arg(ap, double));
+ _TIFFmemcpy(val, &v2, tv_size);
+ }
+ break;
+ case TIFF_DOUBLE:
+ {
+ double v2 = va_arg(ap, double);
+ _TIFFmemcpy(val, &v2, tv_size);
+ }
+ break;
+ default:
+ _TIFFmemset(val, 0, tv_size);
+ status = 0;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (status)
+ {
+ const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
+ if (fip2)
+ TIFFSetFieldBit(tif, fip2->field_bit);
+ tif->tif_flags |= TIFF_DIRTYDIRECT;
+ }
+
+end:
+ va_end(ap);
+ return (status);
+badvalue:
+{
+ const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
+ TIFFErrorExtR(tif, module, "%s: Bad value %" PRIu32 " for \"%s\" tag",
+ tif->tif_name, v, fip2 ? fip2->field_name : "Unknown");
+ va_end(ap);
+}
+ return (0);
+badvalue32:
+{
+ const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
+ TIFFErrorExtR(tif, module, "%s: Bad value %" PRIu32 " for \"%s\" tag",
+ tif->tif_name, v32, fip2 ? fip2->field_name : "Unknown");
+ va_end(ap);
+}
+ return (0);
+badvaluedouble:
+{
+ const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
+ TIFFErrorExtR(tif, module, "%s: Bad value %f for \"%s\" tag", tif->tif_name,
+ dblval, fip2 ? fip2->field_name : "Unknown");
+ va_end(ap);
+}
+ return (0);
+badvalueifd8long8:
+{
+ /* Error message issued already above. */
+ TIFFTagValue *tv2 = NULL;
+ int iCustom2, iC2;
+ /* Find the existing entry for this custom value. */
+ for (iCustom2 = 0; iCustom2 < td->td_customValueCount; iCustom2++)
+ {
+ if (td->td_customValues[iCustom2].info->field_tag == tag)
+ {
+ tv2 = td->td_customValues + (iCustom2);
+ break;
+ }
+ }
+ if (tv2 != NULL)
+ {
+ /* Remove custom field from custom list */
+ if (tv2->value != NULL)
+ {
+ _TIFFfreeExt(tif, tv2->value);
+ tv2->value = NULL;
+ }
+ /* Shorten list and close gap in customValues list.
+ * Re-allocation of td_customValues not necessary here. */
+ td->td_customValueCount--;
+ for (iC2 = iCustom2; iC2 < td->td_customValueCount; iC2++)
+ {
+ td->td_customValues[iC2] = td->td_customValues[iC2 + 1];
+ }
+ }
+ else
+ {
+ assert(0);
+ }
+ va_end(ap);
+}
+ return (0);
+} /*-- _TIFFVSetField() --*/
+
+/*
+ * Return 1/0 according to whether or not
+ * it is permissible to set the tag's value.
+ * Note that we allow ImageLength to be changed
+ * so that we can append and extend to images.
+ * Any other tag may not be altered once writing
+ * has commenced, unless its value has no effect
+ * on the format of the data that is written.
+ */
+static int OkToChangeTag(TIFF *tif, uint32_t tag)
+{
+ const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
+ if (!fip)
+ { /* unknown tag */
+ TIFFErrorExtR(tif, "TIFFSetField", "%s: Unknown %stag %" PRIu32,
+ tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag);
+ return (0);
+ }
+ if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) &&
+ !fip->field_oktochange)
+ {
+ /*
+ * Consult info table to see if tag can be changed
+ * after we've started writing. We only allow changes
+ * to those tags that don't/shouldn't affect the
+ * compression and/or format of the data.
+ */
+ TIFFErrorExtR(tif, "TIFFSetField",
+ "%s: Cannot modify tag \"%s\" while writing",
+ tif->tif_name, fip->field_name);
+ return (0);
+ }
+ return (1);
+}
+
+/*
+ * Record the value of a field in the
+ * internal directory structure. The
+ * field will be written to the file
+ * when/if the directory structure is
+ * updated.
+ */
+int TIFFSetField(TIFF *tif, uint32_t tag, ...)
+{
+ va_list ap;
+ int status;
+
+ va_start(ap, tag);
+ status = TIFFVSetField(tif, tag, ap);
+ va_end(ap);
+ return (status);
+}
+
+/*
+ * Clear the contents of the field in the internal structure.
+ */
+int TIFFUnsetField(TIFF *tif, uint32_t tag)
+{
+ const TIFFField *fip = TIFFFieldWithTag(tif, tag);
+ TIFFDirectory *td = &tif->tif_dir;
+
+ if (!fip)
+ return 0;
+
+ if (fip->field_bit != FIELD_CUSTOM)
+ TIFFClrFieldBit(tif, fip->field_bit);
+ else
+ {
+ TIFFTagValue *tv = NULL;
+ int i;
+
+ for (i = 0; i < td->td_customValueCount; i++)
+ {
+
+ tv = td->td_customValues + i;
+ if (tv->info->field_tag == tag)
+ break;
+ }
+
+ if (i < td->td_customValueCount)
+ {
+ _TIFFfreeExt(tif, tv->value);
+ for (; i < td->td_customValueCount - 1; i++)
+ {
+ td->td_customValues[i] = td->td_customValues[i + 1];
+ }
+ td->td_customValueCount--;
+ }
+ }
+
+ tif->tif_flags |= TIFF_DIRTYDIRECT;
+
+ return (1);
+}
+
+/*
+ * Like TIFFSetField, but taking a varargs
+ * parameter list. This routine is useful
+ * for building higher-level interfaces on
+ * top of the library.
+ */
+int TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
+{
+ return OkToChangeTag(tif, tag)
+ ? (*tif->tif_tagmethods.vsetfield)(tif, tag, ap)
+ : 0;
+}
+
+static int _TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ int ret_val = 1;
+ uint32_t standard_tag = tag;
+ const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
+ if (fip == NULL) /* cannot happen since TIFFGetField() already checks it */
+ return 0;
+
+ /*
+ * We want to force the custom code to be used for custom
+ * fields even if the tag happens to match a well known
+ * one - important for reinterpreted handling of standard
+ * tag values in custom directories (i.e. EXIF)
+ */
+ if (fip->field_bit == FIELD_CUSTOM)
+ {
+ standard_tag = 0;
+ }
+
+ switch (standard_tag)
+ {
+ case TIFFTAG_SUBFILETYPE:
+ *va_arg(ap, uint32_t *) = td->td_subfiletype;
+ break;
+ case TIFFTAG_IMAGEWIDTH:
+ *va_arg(ap, uint32_t *) = td->td_imagewidth;
+ break;
+ case TIFFTAG_IMAGELENGTH:
+ *va_arg(ap, uint32_t *) = td->td_imagelength;
+ break;
+ case TIFFTAG_BITSPERSAMPLE:
+ *va_arg(ap, uint16_t *) = td->td_bitspersample;
+ break;
+ case TIFFTAG_COMPRESSION:
+ *va_arg(ap, uint16_t *) = td->td_compression;
+ break;
+ case TIFFTAG_PHOTOMETRIC:
+ *va_arg(ap, uint16_t *) = td->td_photometric;
+ break;
+ case TIFFTAG_THRESHHOLDING:
+ *va_arg(ap, uint16_t *) = td->td_threshholding;
+ break;
+ case TIFFTAG_FILLORDER:
+ *va_arg(ap, uint16_t *) = td->td_fillorder;
+ break;
+ case TIFFTAG_ORIENTATION:
+ *va_arg(ap, uint16_t *) = td->td_orientation;
+ break;
+ case TIFFTAG_SAMPLESPERPIXEL:
+ *va_arg(ap, uint16_t *) = td->td_samplesperpixel;
+ break;
+ case TIFFTAG_ROWSPERSTRIP:
+ *va_arg(ap, uint32_t *) = td->td_rowsperstrip;
+ break;
+ case TIFFTAG_MINSAMPLEVALUE:
+ *va_arg(ap, uint16_t *) = td->td_minsamplevalue;
+ break;
+ case TIFFTAG_MAXSAMPLEVALUE:
+ *va_arg(ap, uint16_t *) = td->td_maxsamplevalue;
+ break;
+ case TIFFTAG_SMINSAMPLEVALUE:
+ if (tif->tif_flags & TIFF_PERSAMPLE)
+ *va_arg(ap, double **) = td->td_sminsamplevalue;
+ else
+ {
+ /* libtiff historically treats this as a single value. */
+ uint16_t i;
+ double v = td->td_sminsamplevalue[0];
+ for (i = 1; i < td->td_samplesperpixel; ++i)
+ if (td->td_sminsamplevalue[i] < v)
+ v = td->td_sminsamplevalue[i];
+ *va_arg(ap, double *) = v;
+ }
+ break;
+ case TIFFTAG_SMAXSAMPLEVALUE:
+ if (tif->tif_flags & TIFF_PERSAMPLE)
+ *va_arg(ap, double **) = td->td_smaxsamplevalue;
+ else
+ {
+ /* libtiff historically treats this as a single value. */
+ uint16_t i;
+ double v = td->td_smaxsamplevalue[0];
+ for (i = 1; i < td->td_samplesperpixel; ++i)
+ if (td->td_smaxsamplevalue[i] > v)
+ v = td->td_smaxsamplevalue[i];
+ *va_arg(ap, double *) = v;
+ }
+ break;
+ case TIFFTAG_XRESOLUTION:
+ *va_arg(ap, float *) = td->td_xresolution;
+ break;
+ case TIFFTAG_YRESOLUTION:
+ *va_arg(ap, float *) = td->td_yresolution;
+ break;
+ case TIFFTAG_PLANARCONFIG:
+ *va_arg(ap, uint16_t *) = td->td_planarconfig;
+ break;
+ case TIFFTAG_XPOSITION:
+ *va_arg(ap, float *) = td->td_xposition;
+ break;
+ case TIFFTAG_YPOSITION:
+ *va_arg(ap, float *) = td->td_yposition;
+ break;
+ case TIFFTAG_RESOLUTIONUNIT:
+ *va_arg(ap, uint16_t *) = td->td_resolutionunit;
+ break;
+ case TIFFTAG_PAGENUMBER:
+ *va_arg(ap, uint16_t *) = td->td_pagenumber[0];
+ *va_arg(ap, uint16_t *) = td->td_pagenumber[1];
+ break;
+ case TIFFTAG_HALFTONEHINTS:
+ *va_arg(ap, uint16_t *) = td->td_halftonehints[0];
+ *va_arg(ap, uint16_t *) = td->td_halftonehints[1];
+ break;
+ case TIFFTAG_COLORMAP:
+ *va_arg(ap, const uint16_t **) = td->td_colormap[0];
+ *va_arg(ap, const uint16_t **) = td->td_colormap[1];
+ *va_arg(ap, const uint16_t **) = td->td_colormap[2];
+ break;
+ case TIFFTAG_STRIPOFFSETS:
+ 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 *) =
+ (td->td_extrasamples == 1 &&
+ td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
+ break;
+ case TIFFTAG_EXTRASAMPLES:
+ *va_arg(ap, uint16_t *) = td->td_extrasamples;
+ *va_arg(ap, const uint16_t **) = td->td_sampleinfo;
+ break;
+ case TIFFTAG_TILEWIDTH:
+ *va_arg(ap, uint32_t *) = td->td_tilewidth;
+ break;
+ case TIFFTAG_TILELENGTH:
+ *va_arg(ap, uint32_t *) = td->td_tilelength;
+ break;
+ case TIFFTAG_TILEDEPTH:
+ *va_arg(ap, uint32_t *) = td->td_tiledepth;
+ break;
+ case TIFFTAG_DATATYPE:
+ switch (td->td_sampleformat)
+ {
+ case SAMPLEFORMAT_UINT:
+ *va_arg(ap, uint16_t *) = DATATYPE_UINT;
+ break;
+ case SAMPLEFORMAT_INT:
+ *va_arg(ap, uint16_t *) = DATATYPE_INT;
+ break;
+ case SAMPLEFORMAT_IEEEFP:
+ *va_arg(ap, uint16_t *) = DATATYPE_IEEEFP;
+ break;
+ case SAMPLEFORMAT_VOID:
+ *va_arg(ap, uint16_t *) = DATATYPE_VOID;
+ break;
+ }
+ break;
+ case TIFFTAG_SAMPLEFORMAT:
+ *va_arg(ap, uint16_t *) = td->td_sampleformat;
+ break;
+ case TIFFTAG_IMAGEDEPTH:
+ *va_arg(ap, uint32_t *) = td->td_imagedepth;
+ break;
+ case TIFFTAG_SUBIFD:
+ *va_arg(ap, uint16_t *) = td->td_nsubifd;
+ *va_arg(ap, const uint64_t **) = td->td_subifd;
+ break;
+ case TIFFTAG_YCBCRPOSITIONING:
+ *va_arg(ap, uint16_t *) = td->td_ycbcrpositioning;
+ break;
+ case TIFFTAG_YCBCRSUBSAMPLING:
+ *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[0];
+ *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[1];
+ break;
+ case TIFFTAG_TRANSFERFUNCTION:
+ *va_arg(ap, const uint16_t **) = td->td_transferfunction[0];
+ if (td->td_samplesperpixel - td->td_extrasamples > 1)
+ {
+ *va_arg(ap, const uint16_t **) = td->td_transferfunction[1];
+ *va_arg(ap, const uint16_t **) = td->td_transferfunction[2];
+ }
+ else
+ {
+ *va_arg(ap, const uint16_t **) = NULL;
+ *va_arg(ap, const uint16_t **) = NULL;
+ }
+ break;
+ case TIFFTAG_REFERENCEBLACKWHITE:
+ *va_arg(ap, const float **) = td->td_refblackwhite;
+ break;
+ case TIFFTAG_INKNAMES:
+ *va_arg(ap, const char **) = td->td_inknames;
+ break;
+ case TIFFTAG_NUMBEROFINKS:
+ *va_arg(ap, uint16_t *) = td->td_numberofinks;
+ break;
+ default:
+ {
+ int i;
+
+ /*
+ * This can happen if multiple images are open
+ * with different codecs which have private
+ * tags. The global tag information table may
+ * then have tags that are valid for one file
+ * but not the other. If the client tries to
+ * get a tag that is not valid for the image's
+ * codec then we'll arrive here.
+ */
+ if (fip->field_bit != FIELD_CUSTOM)
+ {
+ TIFFErrorExtR(tif, "_TIFFVGetField",
+ "%s: Invalid %stag \"%s\" "
+ "(not supported by codec)",
+ tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
+ fip->field_name);
+ ret_val = 0;
+ break;
+ }
+
+ /*
+ * Do we have a custom value?
+ */
+ ret_val = 0;
+ for (i = 0; i < td->td_customValueCount; i++)
+ {
+ TIFFTagValue *tv = td->td_customValues + i;
+
+ if (tv->info->field_tag != tag)
+ continue;
+
+ if (fip->field_passcount)
+ {
+ if (fip->field_readcount == TIFF_VARIABLE2)
+ *va_arg(ap, uint32_t *) = (uint32_t)tv->count;
+ else /* Assume TIFF_VARIABLE */
+ *va_arg(ap, uint16_t *) = (uint16_t)tv->count;
+ *va_arg(ap, const void **) = tv->value;
+ ret_val = 1;
+ }
+ else if (fip->field_tag == TIFFTAG_DOTRANGE &&
+ strcmp(fip->field_name, "DotRange") == 0)
+ {
+ /* TODO: This is an evil exception and should not have been
+ 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 */
+ *va_arg(ap, uint16_t *) = ((uint16_t *)tv->value)[0];
+ *va_arg(ap, uint16_t *) = ((uint16_t *)tv->value)[1];
+ ret_val = 1;
+ }
+ else
+ {
+ if (fip->field_type == TIFF_ASCII ||
+ fip->field_readcount == TIFF_VARIABLE ||
+ fip->field_readcount == TIFF_VARIABLE2 ||
+ fip->field_readcount == TIFF_SPP || tv->count > 1)
+ {
+ *va_arg(ap, void **) = tv->value;
+ ret_val = 1;
+ }
+ else
+ {
+ char *val = (char *)tv->value;
+ assert(tv->count == 1);
+ switch (fip->field_type)
+ {
+ case TIFF_BYTE:
+ case TIFF_UNDEFINED:
+ *va_arg(ap, uint8_t *) = *(uint8_t *)val;
+ ret_val = 1;
+ break;
+ case TIFF_SBYTE:
+ *va_arg(ap, int8_t *) = *(int8_t *)val;
+ ret_val = 1;
+ break;
+ case TIFF_SHORT:
+ *va_arg(ap, uint16_t *) = *(uint16_t *)val;
+ ret_val = 1;
+ break;
+ case TIFF_SSHORT:
+ *va_arg(ap, int16_t *) = *(int16_t *)val;
+ ret_val = 1;
+ break;
+ case TIFF_LONG:
+ case TIFF_IFD:
+ *va_arg(ap, uint32_t *) = *(uint32_t *)val;
+ ret_val = 1;
+ break;
+ case TIFF_SLONG:
+ *va_arg(ap, int32_t *) = *(int32_t *)val;
+ ret_val = 1;
+ break;
+ case TIFF_LONG8:
+ case TIFF_IFD8:
+ *va_arg(ap, uint64_t *) = *(uint64_t *)val;
+ ret_val = 1;
+ break;
+ case TIFF_SLONG8:
+ *va_arg(ap, int64_t *) = *(int64_t *)val;
+ ret_val = 1;
+ break;
+ case TIFF_RATIONAL:
+ case TIFF_SRATIONAL:
+ {
+ /*-- Rational2Double: For Rationals evaluate
+ * "set_field_type" to determine internal
+ * storage size and return value size. */
+ int tv_size = TIFFFieldSetGetSize(fip);
+ if (tv_size == 8)
+ {
+ *va_arg(ap, double *) = *(double *)val;
+ ret_val = 1;
+ }
+ else
+ {
+ /*-- default should be tv_size == 4 */
+ *va_arg(ap, float *) = *(float *)val;
+ ret_val = 1;
+ /*-- ToDo: After Testing, this should be
+ * removed and tv_size==4 should be set as
+ * default. */
+ if (tv_size != 4)
+ {
+ TIFFErrorExtR(
+ tif, "_TIFFVGetField",
+ "Rational2Double: .set_field_type "
+ "in not 4 but %d",
+ tv_size);
+ }
+ }
+ }
+ break;
+ case TIFF_FLOAT:
+ *va_arg(ap, float *) = *(float *)val;
+ ret_val = 1;
+ break;
+ case TIFF_DOUBLE:
+ *va_arg(ap, double *) = *(double *)val;
+ ret_val = 1;
+ break;
+ default:
+ ret_val = 0;
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+ return (ret_val);
+}
+
+/*
+ * Return the value of a field in the
+ * internal directory structure.
+ */
+int TIFFGetField(TIFF *tif, uint32_t tag, ...)
+{
+ int status;
+ va_list ap;
+
+ va_start(ap, tag);
+ status = TIFFVGetField(tif, tag, ap);
+ va_end(ap);
+ return (status);
+}
+
+/*
+ * Like TIFFGetField, but taking a varargs
+ * parameter list. This routine is useful
+ * for building higher-level interfaces on
+ * top of the library.
+ */
+int TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap)
+{
+ const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
+ return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit))
+ ? (*tif->tif_tagmethods.vgetfield)(tif, tag, ap)
+ : 0);
+}
+
+#define CleanupField(member) \
+ { \
+ if (td->member) \
+ { \
+ _TIFFfreeExt(tif, td->member); \
+ td->member = 0; \
+ } \
+ }
+
+/*
+ * Release storage associated with a directory.
+ */
+void TIFFFreeDirectory(TIFF *tif)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ int i;
+
+ _TIFFmemset(td->td_fieldsset, 0, sizeof(td->td_fieldsset));
+ CleanupField(td_sminsamplevalue);
+ CleanupField(td_smaxsamplevalue);
+ CleanupField(td_colormap[0]);
+ CleanupField(td_colormap[1]);
+ CleanupField(td_colormap[2]);
+ CleanupField(td_sampleinfo);
+ CleanupField(td_subifd);
+ CleanupField(td_inknames);
+ CleanupField(td_refblackwhite);
+ CleanupField(td_transferfunction[0]);
+ CleanupField(td_transferfunction[1]);
+ CleanupField(td_transferfunction[2]);
+ CleanupField(td_stripoffset_p);
+ CleanupField(td_stripbytecount_p);
+ td->td_stripoffsetbyteallocsize = 0;
+ TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
+ TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
+
+ /* Cleanup custom tag values */
+ for (i = 0; i < td->td_customValueCount; i++)
+ {
+ if (td->td_customValues[i].value)
+ _TIFFfreeExt(tif, td->td_customValues[i].value);
+ }
+
+ td->td_customValueCount = 0;
+ CleanupField(td_customValues);
+
+ _TIFFmemset(&(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
+ _TIFFmemset(&(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
+}
+#undef CleanupField
+
+/*
+ * Client Tag extension support (from Niles Ritter).
+ */
+static TIFFExtendProc _TIFFextender = (TIFFExtendProc)NULL;
+
+TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc extender)
+{
+ TIFFExtendProc prev = _TIFFextender;
+ _TIFFextender = extender;
+ return (prev);
+}
+
+/*
+ * Setup for a new directory. Should we automatically call
+ * TIFFWriteDirectory() if the current one is dirty?
+ *
+ * The newly created directory will not exist on the file till
+ * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called.
+ */
+int TIFFCreateDirectory(TIFF *tif)
+{
+ TIFFDefaultDirectory(tif);
+ tif->tif_diroff = 0;
+ tif->tif_nextdiroff = 0;
+ tif->tif_curoff = 0;
+ tif->tif_row = (uint32_t)-1;
+ tif->tif_curstrip = (uint32_t)-1;
+
+ return 0;
+}
+
+int TIFFCreateCustomDirectory(TIFF *tif, const TIFFFieldArray *infoarray)
+{
+ TIFFDefaultDirectory(tif);
+
+ /*
+ * Reset the field definitions to match the application provided list.
+ * Hopefully TIFFDefaultDirectory() won't have done anything irreversible
+ * based on it's assumption this is an image directory.
+ */
+ _TIFFSetupFields(tif, infoarray);
+
+ tif->tif_diroff = 0;
+ tif->tif_nextdiroff = 0;
+ tif->tif_curoff = 0;
+ tif->tif_row = (uint32_t)-1;
+ tif->tif_curstrip = (uint32_t)-1;
+ /* invalidate directory index */
+ tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
+ /* invalidate IFD loop lists */
+ _TIFFCleanupIFDOffsetAndNumberMaps(tif);
+ /* To be able to return from SubIFD or custom-IFD to main-IFD */
+ tif->tif_setdirectory_force_absolute = TRUE;
+
+ return 0;
+}
+
+int TIFFCreateEXIFDirectory(TIFF *tif)
+{
+ const TIFFFieldArray *exifFieldArray;
+ exifFieldArray = _TIFFGetExifFields();
+ return TIFFCreateCustomDirectory(tif, exifFieldArray);
+}
+
+/*
+ * Creates the EXIF GPS custom directory
+ */
+int TIFFCreateGPSDirectory(TIFF *tif)
+{
+ const TIFFFieldArray *gpsFieldArray;
+ gpsFieldArray = _TIFFGetGpsFields();
+ return TIFFCreateCustomDirectory(tif, gpsFieldArray);
+}
+
+/*
+ * Setup a default directory structure.
+ */
+int TIFFDefaultDirectory(TIFF *tif)
+{
+ register TIFFDirectory *td = &tif->tif_dir;
+ const TIFFFieldArray *tiffFieldArray;
+
+ tiffFieldArray = _TIFFGetFields();
+ _TIFFSetupFields(tif, tiffFieldArray);
+
+ _TIFFmemset(td, 0, sizeof(*td));
+ td->td_fillorder = FILLORDER_MSB2LSB;
+ td->td_bitspersample = 1;
+ td->td_threshholding = THRESHHOLD_BILEVEL;
+ td->td_orientation = ORIENTATION_TOPLEFT;
+ td->td_samplesperpixel = 1;
+ td->td_rowsperstrip = (uint32_t)-1;
+ td->td_tilewidth = 0;
+ td->td_tilelength = 0;
+ td->td_tiledepth = 1;
+#ifdef STRIPBYTECOUNTSORTED_UNUSED
+ td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */
+#endif
+ td->td_resolutionunit = RESUNIT_INCH;
+ td->td_sampleformat = SAMPLEFORMAT_UINT;
+ td->td_imagedepth = 1;
+ td->td_ycbcrsubsampling[0] = 2;
+ td->td_ycbcrsubsampling[1] = 2;
+ td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
+ tif->tif_postdecode = _TIFFNoPostDecode;
+ tif->tif_foundfield = NULL;
+ tif->tif_tagmethods.vsetfield = _TIFFVSetField;
+ tif->tif_tagmethods.vgetfield = _TIFFVGetField;
+ tif->tif_tagmethods.printdir = NULL;
+ /* additional default values */
+ td->td_planarconfig = PLANARCONFIG_CONTIG;
+ td->td_compression = COMPRESSION_NONE;
+ td->td_subfiletype = 0;
+ td->td_minsamplevalue = 0;
+ /* td_bitspersample=1 is always set in TIFFDefaultDirectory().
+ * Therefore, td_maxsamplevalue has to be re-calculated in
+ * TIFFGetFieldDefaulted(). */
+ td->td_maxsamplevalue = 1; /* Default for td_bitspersample=1 */
+ td->td_extrasamples = 0;
+ td->td_sampleinfo = NULL;
+
+ /*
+ * Give client code a chance to install their own
+ * tag extensions & methods, prior to compression overloads,
+ * but do some prior cleanup first.
+ * (http://trac.osgeo.org/gdal/ticket/5054)
+ */
+ if (tif->tif_nfieldscompat > 0)
+ {
+ uint32_t i;
+
+ for (i = 0; i < tif->tif_nfieldscompat; i++)
+ {
+ if (tif->tif_fieldscompat[i].allocated_size)
+ _TIFFfreeExt(tif, tif->tif_fieldscompat[i].fields);
+ }
+ _TIFFfreeExt(tif, tif->tif_fieldscompat);
+ tif->tif_nfieldscompat = 0;
+ tif->tif_fieldscompat = NULL;
+ }
+ if (_TIFFextender)
+ (*_TIFFextender)(tif);
+ (void)TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
+ /*
+ * NB: The directory is marked dirty as a result of setting
+ * up the default compression scheme. However, this really
+ * isn't correct -- we want TIFF_DIRTYDIRECT to be set only
+ * if the user does something. We could just do the setup
+ * by hand, but it seems better to use the normal mechanism
+ * (i.e. TIFFSetField).
+ */
+ tif->tif_flags &= ~TIFF_DIRTYDIRECT;
+
+ /*
+ * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19
+ * we clear the ISTILED flag when setting up a new directory.
+ * Should we also be clearing stuff like INSUBIFD?
+ */
+ tif->tif_flags &= ~TIFF_ISTILED;
+
+ return (1);
+}
+
+static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
+ tdir_t *nextdirnum)
+{
+ static const char module[] = "TIFFAdvanceDirectory";
+
+ /* Add this directory to the directory list, if not already in. */
+ if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff))
+ {
+ TIFFErrorExtR(tif, module,
+ "Starting directory %u at offset 0x%" PRIx64 " (%" PRIu64
+ ") might cause an IFD loop",
+ *nextdirnum, *nextdiroff, *nextdiroff);
+ *nextdiroff = 0;
+ *nextdirnum = 0;
+ return (0);
+ }
+
+ if (isMapped(tif))
+ {
+ uint64_t poff = *nextdiroff;
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ tmsize_t poffa, poffb, poffc, poffd;
+ uint16_t dircount;
+ uint32_t nextdir32;
+ poffa = (tmsize_t)poff;
+ poffb = poffa + sizeof(uint16_t);
+ if (((uint64_t)poffa != poff) || (poffb < poffa) ||
+ (poffb < (tmsize_t)sizeof(uint16_t)) || (poffb > tif->tif_size))
+ {
+ TIFFErrorExtR(tif, module, "Error fetching directory count");
+ *nextdiroff = 0;
+ return (0);
+ }
+ _TIFFmemcpy(&dircount, tif->tif_base + poffa, sizeof(uint16_t));
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(&dircount);
+ poffc = poffb + dircount * 12;
+ poffd = poffc + sizeof(uint32_t);
+ if ((poffc < poffb) || (poffc < dircount * 12) || (poffd < poffc) ||
+ (poffd < (tmsize_t)sizeof(uint32_t)) || (poffd > tif->tif_size))
+ {
+ TIFFErrorExtR(tif, module, "Error fetching directory link");
+ return (0);
+ }
+ if (off != NULL)
+ *off = (uint64_t)poffc;
+ _TIFFmemcpy(&nextdir32, tif->tif_base + poffc, sizeof(uint32_t));
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&nextdir32);
+ *nextdiroff = nextdir32;
+ }
+ else
+ {
+ tmsize_t poffa, poffb, poffc, poffd;
+ uint64_t dircount64;
+ uint16_t dircount16;
+ if (poff > (uint64_t)TIFF_TMSIZE_T_MAX - sizeof(uint64_t))
+ {
+ TIFFErrorExtR(tif, module, "Error fetching directory count");
+ return (0);
+ }
+ poffa = (tmsize_t)poff;
+ poffb = poffa + sizeof(uint64_t);
+ if (poffb > tif->tif_size)
+ {
+ TIFFErrorExtR(tif, module, "Error fetching directory count");
+ return (0);
+ }
+ _TIFFmemcpy(&dircount64, tif->tif_base + poffa, sizeof(uint64_t));
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&dircount64);
+ if (dircount64 > 0xFFFF)
+ {
+ TIFFErrorExtR(tif, module,
+ "Sanity check on directory count failed");
+ return (0);
+ }
+ dircount16 = (uint16_t)dircount64;
+ if (poffb > TIFF_TMSIZE_T_MAX - (tmsize_t)(dircount16 * 20) -
+ (tmsize_t)sizeof(uint64_t))
+ {
+ TIFFErrorExtR(tif, module, "Error fetching directory link");
+ return (0);
+ }
+ poffc = poffb + dircount16 * 20;
+ poffd = poffc + sizeof(uint64_t);
+ if (poffd > tif->tif_size)
+ {
+ TIFFErrorExtR(tif, module, "Error fetching directory link");
+ return (0);
+ }
+ if (off != NULL)
+ *off = (uint64_t)poffc;
+ _TIFFmemcpy(nextdiroff, tif->tif_base + poffc, sizeof(uint64_t));
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(nextdiroff);
+ }
+ }
+ else
+ {
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ uint16_t dircount;
+ uint32_t nextdir32;
+ if (!SeekOK(tif, *nextdiroff) ||
+ !ReadOK(tif, &dircount, sizeof(uint16_t)))
+ {
+ TIFFErrorExtR(tif, module, "%s: Error fetching directory count",
+ tif->tif_name);
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(&dircount);
+ if (off != NULL)
+ *off = TIFFSeekFile(tif, dircount * 12, SEEK_CUR);
+ else
+ (void)TIFFSeekFile(tif, dircount * 12, SEEK_CUR);
+ if (!ReadOK(tif, &nextdir32, sizeof(uint32_t)))
+ {
+ TIFFErrorExtR(tif, module, "%s: Error fetching directory link",
+ tif->tif_name);
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&nextdir32);
+ *nextdiroff = nextdir32;
+ }
+ else
+ {
+ uint64_t dircount64;
+ uint16_t dircount16;
+ if (!SeekOK(tif, *nextdiroff) ||
+ !ReadOK(tif, &dircount64, sizeof(uint64_t)))
+ {
+ TIFFErrorExtR(tif, module, "%s: Error fetching directory count",
+ tif->tif_name);
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&dircount64);
+ if (dircount64 > 0xFFFF)
+ {
+ TIFFErrorExtR(tif, module, "Error fetching directory count");
+ return (0);
+ }
+ dircount16 = (uint16_t)dircount64;
+ if (off != NULL)
+ *off = TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR);
+ else
+ (void)TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR);
+ if (!ReadOK(tif, nextdiroff, sizeof(uint64_t)))
+ {
+ TIFFErrorExtR(tif, module, "%s: Error fetching directory link",
+ tif->tif_name);
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(nextdiroff);
+ }
+ }
+ if (*nextdiroff != 0)
+ {
+ (*nextdirnum)++;
+ /* Check next directory for IFD looping and if so, set it as last
+ * directory. */
+ if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff))
+ {
+ TIFFWarningExtR(
+ tif, module,
+ "the next directory %u at offset 0x%" PRIx64 " (%" PRIu64
+ ") might be an IFD loop. Treating directory %d as "
+ "last directory",
+ *nextdirnum, *nextdiroff, *nextdiroff, (int)(*nextdirnum) - 1);
+ *nextdiroff = 0;
+ (*nextdirnum)--;
+ }
+ }
+ return (1);
+}
+
+/*
+ * Count the number of directories in a file.
+ */
+tdir_t TIFFNumberOfDirectories(TIFF *tif)
+{
+ uint64_t nextdiroff;
+ tdir_t nextdirnum;
+ tdir_t n;
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ nextdiroff = tif->tif_header.classic.tiff_diroff;
+ else
+ nextdiroff = tif->tif_header.big.tiff_diroff;
+ nextdirnum = 0;
+ n = 0;
+ while (nextdiroff != 0 &&
+ TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum))
+ {
+ ++n;
+ }
+ return (n);
+}
+
+/*
+ * Set the n-th directory as the current directory.
+ * NB: Directories are numbered starting at 0.
+ */
+int TIFFSetDirectory(TIFF *tif, tdir_t dirn)
+{
+ uint64_t nextdiroff;
+ tdir_t nextdirnum = 0;
+ tdir_t n;
+
+ if (tif->tif_setdirectory_force_absolute)
+ {
+ /* tif_setdirectory_force_absolute=1 will force parsing the main IFD
+ * chain from the beginning, thus IFD directory list needs to be cleared
+ * from possible SubIFD offsets.
+ */
+ _TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */
+ }
+
+ /* Even faster path, if offset is available within IFD loop hash list. */
+ if (!tif->tif_setdirectory_force_absolute &&
+ _TIFFGetOffsetFromDirNumber(tif, dirn, &nextdiroff))
+ {
+ /* Set parameters for following TIFFReadDirectory() below. */
+ tif->tif_nextdiroff = nextdiroff;
+ tif->tif_curdir = dirn;
+ /* Reset to relative stepping */
+ tif->tif_setdirectory_force_absolute = FALSE;
+ }
+ else
+ {
+
+ /* Fast path when we just advance relative to the current directory:
+ * start at the current dir offset and continue to seek from there.
+ * Check special cases when relative is not allowed:
+ * - jump back from SubIFD or custom directory
+ * - right after TIFFWriteDirectory() jump back to that directory
+ * using TIFFSetDirectory() */
+ const int relative = (dirn >= tif->tif_curdir) &&
+ (tif->tif_diroff != 0) &&
+ !tif->tif_setdirectory_force_absolute;
+
+ if (relative)
+ {
+ nextdiroff = tif->tif_diroff;
+ dirn -= tif->tif_curdir;
+ nextdirnum = tif->tif_curdir;
+ }
+ else if (!(tif->tif_flags & TIFF_BIGTIFF))
+ nextdiroff = tif->tif_header.classic.tiff_diroff;
+ else
+ nextdiroff = tif->tif_header.big.tiff_diroff;
+
+ /* Reset to relative stepping */
+ tif->tif_setdirectory_force_absolute = FALSE;
+
+ for (n = dirn; n > 0 && nextdiroff != 0; n--)
+ if (!TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum))
+ return (0);
+ /* If the n-th directory could not be reached (does not exist),
+ * return here without touching anything further. */
+ if (nextdiroff == 0 || n > 0)
+ return (0);
+
+ tif->tif_nextdiroff = nextdiroff;
+
+ /* Set curdir to the actual directory index. */
+ if (relative)
+ tif->tif_curdir += dirn - n;
+ else
+ tif->tif_curdir = dirn - n;
+ }
+
+ /* The -1 decrement is because TIFFReadDirectory will increment
+ * tif_curdir after successfully reading the directory. */
+ if (tif->tif_curdir == 0)
+ tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
+ else
+ tif->tif_curdir--;
+ return (TIFFReadDirectory(tif));
+}
+
+/*
+ * Set the current directory to be the directory
+ * located at the specified file offset. This interface
+ * is used mainly to access directories linked with
+ * the SubIFD tag (e.g. thumbnail images).
+ */
+int TIFFSetSubDirectory(TIFF *tif, uint64_t diroff)
+{
+ /* Match nextdiroff and curdir for consistent IFD-loop checking.
+ * Only with TIFFSetSubDirectory() the IFD list can be corrupted with
+ * invalid offsets within the main IFD tree. In the case of several subIFDs
+ * of a main image, there are two possibilities that are not even mutually
+ * exclusive. a.) The subIFD tag contains an array with all offsets of the
+ * subIFDs. b.) The SubIFDs are concatenated with their NextIFD parameters.
+ * (refer to
+ * https://www.awaresystems.be/imaging/tiff/specification/TIFFPM6.pdf.)
+ */
+ int retval;
+ uint32_t curdir = 0;
+ int8_t probablySubIFD = 0;
+ if (diroff == 0)
+ {
+ /* Special case to invalidate the tif_lastdiroff member. */
+ tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
+ }
+ else
+ {
+ if (!_TIFFGetDirNumberFromOffset(tif, diroff, &curdir))
+ {
+ /* Non-existing offsets might point to a SubIFD or invalid IFD.*/
+ probablySubIFD = 1;
+ }
+ /* -1 because TIFFReadDirectory() will increment tif_curdir. */
+ tif->tif_curdir =
+ curdir == 0 ? TIFF_NON_EXISTENT_DIR_NUMBER : curdir - 1;
+ }
+
+ tif->tif_nextdiroff = diroff;
+ retval = TIFFReadDirectory(tif);
+ /* If failed, curdir was not incremented in TIFFReadDirectory(), so set it
+ * back, but leave it for diroff==0. */
+ if (!retval && diroff != 0)
+ {
+ if (tif->tif_curdir == TIFF_NON_EXISTENT_DIR_NUMBER)
+ tif->tif_curdir = 0;
+ else
+ tif->tif_curdir++;
+ }
+ if (retval && probablySubIFD)
+ {
+ /* Reset IFD list to start new one for SubIFD chain and also start
+ * SubIFD chain with tif_curdir=0. */
+ _TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */
+ tif->tif_curdir = 0; /* first directory of new chain */
+ /* add this offset to new IFD list */
+ _TIFFCheckDirNumberAndOffset(tif, tif->tif_curdir, diroff);
+ /* To be able to return from SubIFD or custom-IFD to main-IFD */
+ tif->tif_setdirectory_force_absolute = TRUE;
+ }
+ return (retval);
+}
+
+/*
+ * Return file offset of the current directory.
+ */
+uint64_t TIFFCurrentDirOffset(TIFF *tif) { return (tif->tif_diroff); }
+
+/*
+ * Return an indication of whether or not we are
+ * at the last directory in the file.
+ */
+int TIFFLastDirectory(TIFF *tif) { return (tif->tif_nextdiroff == 0); }
+
+/*
+ * Unlink the specified directory from the directory chain.
+ * Note: First directory starts with number dirn=1.
+ * This is different to TIFFSetDirectory() where the first directory starts with
+ * zero.
+ */
+int TIFFUnlinkDirectory(TIFF *tif, tdir_t dirn)
+{
+ static const char module[] = "TIFFUnlinkDirectory";
+ uint64_t nextdir;
+ tdir_t nextdirnum;
+ uint64_t off;
+ tdir_t n;
+
+ if (tif->tif_mode == O_RDONLY)
+ {
+ TIFFErrorExtR(tif, module,
+ "Can not unlink directory in read-only file");
+ return (0);
+ }
+ if (dirn == 0)
+ {
+ TIFFErrorExtR(tif, module,
+ "For TIFFUnlinkDirectory() first directory starts with "
+ "number 1 and not 0");
+ return (0);
+ }
+ /*
+ * Go to the directory before the one we want
+ * to unlink and nab the offset of the link
+ * field we'll need to patch.
+ */
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ nextdir = tif->tif_header.classic.tiff_diroff;
+ off = 4;
+ }
+ else
+ {
+ nextdir = tif->tif_header.big.tiff_diroff;
+ off = 8;
+ }
+ nextdirnum = 0; /* First directory is dirn=0 */
+
+ for (n = dirn - 1; n > 0; n--)
+ {
+ if (nextdir == 0)
+ {
+ TIFFErrorExtR(tif, module, "Directory %u does not exist", dirn);
+ return (0);
+ }
+ if (!TIFFAdvanceDirectory(tif, &nextdir, &off, &nextdirnum))
+ return (0);
+ }
+ /*
+ * Advance to the directory to be unlinked and fetch
+ * the offset of the directory that follows.
+ */
+ if (!TIFFAdvanceDirectory(tif, &nextdir, NULL, &nextdirnum))
+ return (0);
+ /*
+ * Go back and patch the link field of the preceding
+ * directory to point to the offset of the directory
+ * that follows.
+ */
+ (void)TIFFSeekFile(tif, off, SEEK_SET);
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ uint32_t nextdir32;
+ nextdir32 = (uint32_t)nextdir;
+ assert((uint64_t)nextdir32 == nextdir);
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&nextdir32);
+ if (!WriteOK(tif, &nextdir32, sizeof(uint32_t)))
+ {
+ TIFFErrorExtR(tif, module, "Error writing directory link");
+ return (0);
+ }
+ }
+ else
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&nextdir);
+ if (!WriteOK(tif, &nextdir, sizeof(uint64_t)))
+ {
+ TIFFErrorExtR(tif, module, "Error writing directory link");
+ return (0);
+ }
+ }
+
+ /* For dirn=1 (first directory) also update the libtiff internal
+ * base offset variables. */
+ if (dirn == 1)
+ {
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ tif->tif_header.classic.tiff_diroff = (uint32_t)nextdir;
+ else
+ tif->tif_header.big.tiff_diroff = nextdir;
+ }
+
+ /*
+ * Leave directory state setup safely. We don't have
+ * facilities for doing inserting and removing directories,
+ * so it's safest to just invalidate everything. This
+ * means that the caller can only append to the directory
+ * chain.
+ */
+ (*tif->tif_cleanup)(tif);
+ if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
+ {
+ _TIFFfreeExt(tif, tif->tif_rawdata);
+ tif->tif_rawdata = NULL;
+ tif->tif_rawcc = 0;
+ tif->tif_rawdataoff = 0;
+ tif->tif_rawdataloaded = 0;
+ }
+ tif->tif_flags &= ~(TIFF_BEENWRITING | TIFF_BUFFERSETUP | TIFF_POSTENCODE |
+ TIFF_BUF4WRITE);
+ TIFFFreeDirectory(tif);
+ 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;
+ tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
+ _TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */
+ return (1);
+}
diff --git a/contrib/libs/libtiff/tif_dir.h b/contrib/libs/libtiff/tif_dir.h
new file mode 100644
index 0000000000..9eaf22f8e6
--- /dev/null
+++ b/contrib/libs/libtiff/tif_dir.h
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _TIFFDIR_
+#define _TIFFDIR_
+
+#include "tiff.h"
+#include "tiffio.h"
+
+/*
+ * ``Library-private'' Directory-related Definitions.
+ */
+
+typedef struct
+{
+ const TIFFField *info;
+ int count;
+ void *value;
+} TIFFTagValue;
+
+/*
+ * TIFF Image File Directories are comprised of a table of field
+ * descriptors of the form shown below. The table is sorted in
+ * ascending order by tag. The values associated with each entry are
+ * disjoint and may appear anywhere in the file (so long as they are
+ * placed on a word boundary).
+ *
+ * If the value is 4 bytes or less, in ClassicTIFF, or 8 bytes or less in
+ * BigTIFF, then it is placed in the offset field to save space. If so,
+ * it is left-justified in the offset field.
+ */
+typedef struct
+{
+ uint16_t tdir_tag; /* see below */
+ uint16_t tdir_type; /* data type; see below */
+ uint64_t tdir_count; /* number of items; length in spec */
+ union
+ {
+ uint16_t toff_short;
+ uint32_t toff_long;
+ uint64_t toff_long8;
+ } tdir_offset; /* either offset or the data itself if fits */
+ uint8_t tdir_ignore; /* flag status to ignore tag when parsing tags in
+ tif_dirread.c */
+} TIFFDirEntry;
+
+/*
+ * Internal format of a TIFF directory entry.
+ */
+typedef struct
+{
+#define FIELDSET_ITEMS 4
+ /* bit vector of fields that are set */
+ uint32_t td_fieldsset[FIELDSET_ITEMS];
+
+ uint32_t td_imagewidth, td_imagelength, td_imagedepth;
+ uint32_t td_tilewidth, td_tilelength, td_tiledepth;
+ uint32_t td_subfiletype;
+ uint16_t td_bitspersample;
+ uint16_t td_sampleformat;
+ uint16_t td_compression;
+ uint16_t td_photometric;
+ uint16_t td_threshholding;
+ uint16_t td_fillorder;
+ uint16_t td_orientation;
+ uint16_t td_samplesperpixel;
+ uint32_t td_rowsperstrip;
+ uint16_t td_minsamplevalue, td_maxsamplevalue;
+ double *td_sminsamplevalue;
+ double *td_smaxsamplevalue;
+ float td_xresolution, td_yresolution;
+ uint16_t td_resolutionunit;
+ uint16_t td_planarconfig;
+ float td_xposition, td_yposition;
+ uint16_t td_pagenumber[2];
+ uint16_t *td_colormap[3];
+ uint16_t td_halftonehints[2];
+ uint16_t td_extrasamples;
+ uint16_t *td_sampleinfo;
+ /* even though the name is misleading, td_stripsperimage is the number
+ * of striles (=strips or tiles) per plane, and td_nstrips the total
+ * number of striles */
+ uint32_t td_stripsperimage;
+ uint32_t td_nstrips; /* size of offset & bytecount arrays */
+ uint64_t
+ *td_stripoffset_p; /* should be accessed with TIFFGetStrileOffset */
+ uint64_t *td_stripbytecount_p; /* should be accessed with
+ TIFFGetStrileByteCount */
+ uint32_t
+ td_stripoffsetbyteallocsize; /* number of elements currently allocated
+ for td_stripoffset/td_stripbytecount.
+ Only used if TIFF_LAZYSTRILELOAD is set
+ */
+#ifdef STRIPBYTECOUNTSORTED_UNUSED
+ int td_stripbytecountsorted; /* is the bytecount array sorted ascending? */
+#endif
+ TIFFDirEntry td_stripoffset_entry; /* for deferred loading */
+ TIFFDirEntry td_stripbytecount_entry; /* for deferred loading */
+ uint16_t td_nsubifd;
+ uint64_t *td_subifd;
+ /* YCbCr parameters */
+ uint16_t td_ycbcrsubsampling[2];
+ uint16_t td_ycbcrpositioning;
+ /* Colorimetry parameters */
+ uint16_t *td_transferfunction[3];
+ float *td_refblackwhite;
+ /* CMYK parameters */
+ int td_inknameslen;
+ char *td_inknames;
+ uint16_t td_numberofinks; /* number of inks in InkNames string */
+
+ int td_customValueCount;
+ TIFFTagValue *td_customValues;
+
+ unsigned char
+ td_deferstrilearraywriting; /* see TIFFDeferStrileArrayWriting() */
+} TIFFDirectory;
+
+/*
+ * Field flags used to indicate fields that have been set in a directory, and
+ * to reference fields when manipulating a directory.
+ */
+
+/*
+ * FIELD_IGNORE is used to signify tags that are to be processed but otherwise
+ * ignored. This permits antiquated tags to be quietly read and discarded.
+ * Note that a bit *is* allocated for ignored tags; this is understood by the
+ * directory reading logic which uses this fact to avoid special-case handling
+ */
+#define FIELD_IGNORE 0
+
+/* multi-item fields */
+#define FIELD_IMAGEDIMENSIONS 1
+#define FIELD_TILEDIMENSIONS 2
+#define FIELD_RESOLUTION 3
+#define FIELD_POSITION 4
+
+/* single-item fields */
+#define FIELD_SUBFILETYPE 5
+#define FIELD_BITSPERSAMPLE 6
+#define FIELD_COMPRESSION 7
+#define FIELD_PHOTOMETRIC 8
+#define FIELD_THRESHHOLDING 9
+#define FIELD_FILLORDER 10
+#define FIELD_ORIENTATION 15
+#define FIELD_SAMPLESPERPIXEL 16
+#define FIELD_ROWSPERSTRIP 17
+#define FIELD_MINSAMPLEVALUE 18
+#define FIELD_MAXSAMPLEVALUE 19
+#define FIELD_PLANARCONFIG 20
+#define FIELD_RESOLUTIONUNIT 22
+#define FIELD_PAGENUMBER 23
+#define FIELD_STRIPBYTECOUNTS 24
+#define FIELD_STRIPOFFSETS 25
+#define FIELD_COLORMAP 26
+#define FIELD_EXTRASAMPLES 31
+#define FIELD_SAMPLEFORMAT 32
+#define FIELD_SMINSAMPLEVALUE 33
+#define FIELD_SMAXSAMPLEVALUE 34
+#define FIELD_IMAGEDEPTH 35
+#define FIELD_TILEDEPTH 36
+#define FIELD_HALFTONEHINTS 37
+#define FIELD_YCBCRSUBSAMPLING 39
+#define FIELD_YCBCRPOSITIONING 40
+#define FIELD_REFBLACKWHITE 41
+#define FIELD_TRANSFERFUNCTION 44
+#define FIELD_INKNAMES 46
+#define FIELD_SUBIFD 49
+#define FIELD_NUMBEROFINKS 50
+/* FIELD_CUSTOM (see tiffio.h) 65 */
+/* end of support for well-known tags; codec-private tags follow */
+#define FIELD_CODEC 66 /* base of codec-private tags */
+
+/*
+ * Pseudo-tags don't normally need field bits since they are not written to an
+ * output file (by definition). The library also has express logic to always
+ * query a codec for a pseudo-tag so allocating a field bit for one is a
+ * waste. If codec wants to promote the notion of a pseudo-tag being ``set''
+ * or ``unset'' then it can do using internal state flags without polluting
+ * the field bit space defined for real tags.
+ */
+#define FIELD_PSEUDO 0
+
+#define FIELD_LAST (32 * FIELDSET_ITEMS - 1)
+
+#define BITn(n) (((uint32_t)1L) << ((n)&0x1f))
+#define BITFIELDn(tif, n) ((tif)->tif_dir.td_fieldsset[(n) / 32])
+#define TIFFFieldSet(tif, field) (BITFIELDn(tif, field) & BITn(field))
+#define TIFFSetFieldBit(tif, field) (BITFIELDn(tif, field) |= BITn(field))
+#define TIFFClrFieldBit(tif, field) (BITFIELDn(tif, field) &= ~BITn(field))
+
+#define FieldSet(fields, f) (fields[(f) / 32] & BITn(f))
+#define ResetFieldBit(fields, f) (fields[(f) / 32] &= ~BITn(f))
+
+typedef enum
+{
+ TIFF_SETGET_UNDEFINED = 0,
+ TIFF_SETGET_ASCII = 1,
+ TIFF_SETGET_UINT8 = 2,
+ TIFF_SETGET_SINT8 = 3,
+ TIFF_SETGET_UINT16 = 4,
+ TIFF_SETGET_SINT16 = 5,
+ TIFF_SETGET_UINT32 = 6,
+ TIFF_SETGET_SINT32 = 7,
+ TIFF_SETGET_UINT64 = 8,
+ TIFF_SETGET_SINT64 = 9,
+ TIFF_SETGET_FLOAT = 10,
+ TIFF_SETGET_DOUBLE = 11,
+ TIFF_SETGET_IFD8 = 12,
+ TIFF_SETGET_INT = 13,
+ TIFF_SETGET_UINT16_PAIR = 14,
+ TIFF_SETGET_C0_ASCII = 15,
+ TIFF_SETGET_C0_UINT8 = 16,
+ TIFF_SETGET_C0_SINT8 = 17,
+ TIFF_SETGET_C0_UINT16 = 18,
+ TIFF_SETGET_C0_SINT16 = 19,
+ TIFF_SETGET_C0_UINT32 = 20,
+ TIFF_SETGET_C0_SINT32 = 21,
+ TIFF_SETGET_C0_UINT64 = 22,
+ TIFF_SETGET_C0_SINT64 = 23,
+ TIFF_SETGET_C0_FLOAT = 24,
+ TIFF_SETGET_C0_DOUBLE = 25,
+ TIFF_SETGET_C0_IFD8 = 26,
+ TIFF_SETGET_C16_ASCII = 27,
+ TIFF_SETGET_C16_UINT8 = 28,
+ TIFF_SETGET_C16_SINT8 = 29,
+ TIFF_SETGET_C16_UINT16 = 30,
+ TIFF_SETGET_C16_SINT16 = 31,
+ TIFF_SETGET_C16_UINT32 = 32,
+ TIFF_SETGET_C16_SINT32 = 33,
+ TIFF_SETGET_C16_UINT64 = 34,
+ TIFF_SETGET_C16_SINT64 = 35,
+ TIFF_SETGET_C16_FLOAT = 36,
+ TIFF_SETGET_C16_DOUBLE = 37,
+ TIFF_SETGET_C16_IFD8 = 38,
+ TIFF_SETGET_C32_ASCII = 39,
+ TIFF_SETGET_C32_UINT8 = 40,
+ TIFF_SETGET_C32_SINT8 = 41,
+ TIFF_SETGET_C32_UINT16 = 42,
+ TIFF_SETGET_C32_SINT16 = 43,
+ TIFF_SETGET_C32_UINT32 = 44,
+ TIFF_SETGET_C32_SINT32 = 45,
+ TIFF_SETGET_C32_UINT64 = 46,
+ TIFF_SETGET_C32_SINT64 = 47,
+ TIFF_SETGET_C32_FLOAT = 48,
+ TIFF_SETGET_C32_DOUBLE = 49,
+ TIFF_SETGET_C32_IFD8 = 50,
+ TIFF_SETGET_OTHER = 51
+} TIFFSetGetFieldType;
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+ extern const TIFFFieldArray *_TIFFGetFields(void);
+ extern const TIFFFieldArray *_TIFFGetExifFields(void);
+ extern const TIFFFieldArray *_TIFFGetGpsFields(void);
+ extern void _TIFFSetupFields(TIFF *tif, const TIFFFieldArray *infoarray);
+ extern void _TIFFPrintFieldInfo(TIFF *, FILE *);
+
+ extern int _TIFFFillStriles(TIFF *);
+
+ typedef enum
+ {
+ tfiatImage,
+ tfiatExif,
+ tfiatGps, /* EXIF-GPS fields array type */
+ tfiatOther
+ } TIFFFieldArrayType;
+
+ struct _TIFFFieldArray
+ {
+ TIFFFieldArrayType type; /* array type, will be used to determine if IFD
+ is image and such */
+ uint32_t allocated_size; /* 0 if array is constant, other if modified by
+ future definition extension support */
+ uint32_t count; /* number of elements in fields array */
+ TIFFField *fields; /* actual field info */
+ };
+
+ struct _TIFFField
+ {
+ 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
+ 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 */
+ unsigned char field_oktochange; /* if true, can change while writing */
+ unsigned char field_passcount; /* if true, pass dir count on set */
+ char *field_name; /* ASCII name */
+ TIFFFieldArray *field_subfields; /* if field points to child ifds, child
+ ifd field definition array */
+ };
+
+ extern int _TIFFMergeFields(TIFF *, const TIFFField[], uint32_t);
+ extern const TIFFField *_TIFFFindOrRegisterField(TIFF *, uint32_t,
+ TIFFDataType);
+ extern TIFFField *_TIFFCreateAnonField(TIFF *, uint32_t, TIFFDataType);
+ extern int _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag);
+ extern int _TIFFCheckDirNumberAndOffset(TIFF *tif, tdir_t dirn,
+ uint64_t diroff);
+ extern int _TIFFGetDirNumberFromOffset(TIFF *tif, uint64_t diroff,
+ tdir_t *dirn);
+ extern int _TIFFGetOffsetFromDirNumber(TIFF *tif, tdir_t dirn,
+ uint64_t *diroff);
+ extern int _TIFFRemoveEntryFromDirectoryListByOffset(TIFF *tif,
+ uint64_t diroff);
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* _TIFFDIR_ */
diff --git a/contrib/libs/libtiff/tif_dirinfo.c b/contrib/libs/libtiff/tif_dirinfo.c
new file mode 100644
index 0000000000..0e705e81e3
--- /dev/null
+++ b/contrib/libs/libtiff/tif_dirinfo.c
@@ -0,0 +1,1351 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Core Directory Tag Support.
+ */
+#include "tiffiop.h"
+#include <stdlib.h>
+
+/*
+ * NOTE: THIS ARRAY IS ASSUMED TO BE SORTED BY TAG.
+ *
+ * NOTE: The second field (field_readcount) and third field (field_writecount)
+ * sometimes use the values TIFF_VARIABLE (-1), TIFF_VARIABLE2 (-3)
+ * and TIFF_SPP (-2). The macros should be used but would throw off
+ * the formatting of the code, so please interpret the -1, -2 and -3
+ * values accordingly.
+ */
+
+/* const object should be initialized */
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4132)
+#endif
+static const TIFFFieldArray tiffFieldArray;
+static const TIFFFieldArray exifFieldArray;
+static const TIFFFieldArray gpsFieldArray;
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+/*--: Rational2Double: --
+ * The Rational2Double upgraded libtiff functionality allows the definition and
+ * achievement of true double-precision accuracy for TIFF tags of RATIONAL type
+ * and field_bit=FIELD_CUSTOM using the set_field_type = TIFF_SETGET_DOUBLE.
+ * Unfortunately, that changes the old implemented interface for TIFFGetField().
+ * In order to keep the old TIFFGetField() interface behavior those tags have to
+ * be redefined with set_field_type = TIFF_SETGET_FLOAT!
+ *
+ * Rational custom arrays are already defined as _Cxx_FLOAT, thus can stay.
+ *
+ */
+
+/* clang-format off */ /* for better readability of tag comments */
+static const TIFFField tiffFields[] = {
+ {TIFFTAG_SUBFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_SUBFILETYPE, 1, 0, "SubfileType", NULL},
+ {TIFFTAG_OSUBFILETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "OldSubfileType", NULL},
+ {TIFFTAG_IMAGEWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDIMENSIONS, 0, 0, "ImageWidth", NULL},
+ {TIFFTAG_IMAGELENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDIMENSIONS, 1, 0, "ImageLength", NULL},
+ {TIFFTAG_BITSPERSAMPLE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_BITSPERSAMPLE, 0, 0, "BitsPerSample", NULL},
+ {TIFFTAG_COMPRESSION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_COMPRESSION, 0, 0, "Compression", NULL},
+ {TIFFTAG_PHOTOMETRIC, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_PHOTOMETRIC, 0, 0, "PhotometricInterpretation", NULL},
+ {TIFFTAG_THRESHHOLDING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_THRESHHOLDING, 1, 0, "Threshholding", NULL},
+ {TIFFTAG_CELLWIDTH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CellWidth", NULL},
+ {TIFFTAG_CELLLENGTH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CellLength", NULL},
+ {TIFFTAG_FILLORDER, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_FILLORDER, 0, 0, "FillOrder", NULL},
+ {TIFFTAG_DOCUMENTNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DocumentName", NULL},
+ {TIFFTAG_IMAGEDESCRIPTION, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageDescription", NULL},
+ {TIFFTAG_MAKE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Make", NULL},
+ {TIFFTAG_MODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Model", NULL},
+ {TIFFTAG_STRIPOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPOFFSETS, 0, 0, "StripOffsets", NULL},
+ {TIFFTAG_ORIENTATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_ORIENTATION, 0, 0, "Orientation", NULL},
+ {TIFFTAG_SAMPLESPERPIXEL, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLESPERPIXEL, 0, 0, "SamplesPerPixel", NULL},
+ {TIFFTAG_ROWSPERSTRIP, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_ROWSPERSTRIP, 0, 0, "RowsPerStrip", NULL},
+ {TIFFTAG_STRIPBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "StripByteCounts", NULL},
+ {TIFFTAG_MINSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_MINSAMPLEVALUE, 1, 0, "MinSampleValue", NULL},
+ {TIFFTAG_MAXSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_MAXSAMPLEVALUE, 1, 0, "MaxSampleValue", NULL},
+ {TIFFTAG_XRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "XResolution", NULL},
+ {TIFFTAG_YRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "YResolution", NULL},
+ {TIFFTAG_PLANARCONFIG, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_PLANARCONFIG, 0, 0, "PlanarConfiguration", NULL},
+ {TIFFTAG_PAGENAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PageName", NULL},
+ {TIFFTAG_XPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "XPosition", NULL},
+ {TIFFTAG_YPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "YPosition", NULL},
+ {TIFFTAG_FREEOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeOffsets", NULL},
+ {TIFFTAG_FREEBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeByteCounts", NULL},
+ {TIFFTAG_GRAYRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseUnit", NULL},
+ {TIFFTAG_GRAYRESPONSECURVE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseCurve", NULL},
+ {TIFFTAG_RESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTIONUNIT, 1, 0, "ResolutionUnit", NULL},
+ {TIFFTAG_PAGENUMBER, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_PAGENUMBER, 1, 0, "PageNumber", NULL},
+ {TIFFTAG_COLORRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "ColorResponseUnit", NULL},
+ {TIFFTAG_TRANSFERFUNCTION, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_TRANSFERFUNCTION, 1, 0, "TransferFunction", NULL},
+ {TIFFTAG_SOFTWARE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Software", NULL},
+ {TIFFTAG_DATETIME, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTime", NULL},
+ {TIFFTAG_ARTIST, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Artist", NULL},
+ {TIFFTAG_HOSTCOMPUTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "HostComputer", NULL},
+ {TIFFTAG_WHITEPOINT, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhitePoint", NULL},
+ {TIFFTAG_PRIMARYCHROMATICITIES, 6, 6, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PrimaryChromaticities", NULL},
+ {TIFFTAG_COLORMAP, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_COLORMAP, 1, 0, "ColorMap", NULL},
+ {TIFFTAG_HALFTONEHINTS, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_HALFTONEHINTS, 1, 0, "HalftoneHints", NULL},
+ {TIFFTAG_TILEWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDIMENSIONS, 0, 0, "TileWidth", NULL},
+ {TIFFTAG_TILELENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDIMENSIONS, 0, 0, "TileLength", NULL},
+ {TIFFTAG_TILEOFFSETS, -1, 1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPOFFSETS, 0, 0, "TileOffsets", NULL},
+ {TIFFTAG_TILEBYTECOUNTS, -1, 1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "TileByteCounts", NULL},
+ {TIFFTAG_SUBIFD, -1, -1, TIFF_IFD8, 0, TIFF_SETGET_C16_IFD8, TIFF_SETGET_UNDEFINED, FIELD_SUBIFD, 1, 1, "SubIFD", (TIFFFieldArray *)&tiffFieldArray},
+ {TIFFTAG_INKSET, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InkSet", NULL},
+ {TIFFTAG_INKNAMES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_C16_ASCII, TIFF_SETGET_UNDEFINED, FIELD_INKNAMES, 1, 1, "InkNames", NULL},
+ {TIFFTAG_NUMBEROFINKS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_NUMBEROFINKS, 1, 0, "NumberOfInks", NULL},
+ {TIFFTAG_DOTRANGE, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DotRange", NULL},
+ {TIFFTAG_TARGETPRINTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TargetPrinter", NULL},
+ {TIFFTAG_EXTRASAMPLES, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 1, "ExtraSamples", NULL},
+ {TIFFTAG_SAMPLEFORMAT, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLEFORMAT, 0, 0, "SampleFormat", NULL},
+ {TIFFTAG_SMINSAMPLEVALUE, -2, -1, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_SMINSAMPLEVALUE, 1, 0, "SMinSampleValue", NULL},
+ {TIFFTAG_SMAXSAMPLEVALUE, -2, -1, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_SMAXSAMPLEVALUE, 1, 0, "SMaxSampleValue", NULL},
+ {TIFFTAG_CLIPPATH, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ClipPath", NULL},
+ {TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL},
+ {TIFFTAG_YCLIPPATHUNITS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YClipPathUnits", NULL},
+ {TIFFTAG_YCBCRCOEFFICIENTS, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YCbCrCoefficients", NULL},
+ {TIFFTAG_YCBCRSUBSAMPLING, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_YCBCRSUBSAMPLING, 0, 0, "YCbCrSubsampling", NULL},
+ {TIFFTAG_YCBCRPOSITIONING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_YCBCRPOSITIONING, 0, 0, "YCbCrPositioning", NULL},
+ {TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_REFBLACKWHITE, 1, 0, "ReferenceBlackWhite", NULL},
+ {TIFFTAG_XMLPACKET, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "XMLPacket", NULL},
+ /* begin SGI tags */
+ {TIFFTAG_MATTEING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 0, "Matteing", NULL},
+ {TIFFTAG_DATATYPE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLEFORMAT, 0, 0, "DataType", NULL},
+ {TIFFTAG_IMAGEDEPTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDEPTH, 0, 0, "ImageDepth", NULL},
+ {TIFFTAG_TILEDEPTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDEPTH, 0, 0, "TileDepth", NULL},
+ /* end SGI tags */
+ /* begin Pixar tags */
+ {TIFFTAG_PIXAR_IMAGEFULLWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageFullWidth", NULL},
+ {TIFFTAG_PIXAR_IMAGEFULLLENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageFullLength", NULL},
+ {TIFFTAG_PIXAR_TEXTUREFORMAT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TextureFormat", NULL},
+ {TIFFTAG_PIXAR_WRAPMODES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TextureWrapModes", NULL},
+ {TIFFTAG_PIXAR_FOVCOT, 1, 1, TIFF_FLOAT, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FieldOfViewCotangent", NULL},
+ {TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToScreen", NULL},
+ {TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToCamera", NULL},
+ {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, 1, 1, "RichTIFFIPTC", 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 or a 64-bit value and the TIFF_IFD8 type-id into BigTIFF files. */
+ {TIFFTAG_EXIFIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EXIFIFDOffset", (TIFFFieldArray *)&exifFieldArray},
+ {TIFFTAG_ICCPROFILE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ICC Profile", NULL},
+ {TIFFTAG_GPSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GPSIFDOffset", (TIFFFieldArray *)&gpsFieldArray},
+ {TIFFTAG_FAXRECVPARAMS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvParams", NULL},
+ {TIFFTAG_FAXSUBADDRESS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxSubAddress", NULL},
+ {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_IFD8, 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, 1, 0, "DNGVersion", NULL},
+ {TIFFTAG_DNGBACKWARDVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DNGBackwardVersion", NULL},
+ {TIFFTAG_UNIQUECAMERAMODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "UniqueCameraModel", NULL},
+ {TIFFTAG_LOCALIZEDCAMERAMODEL, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "LocalizedCameraModel", NULL},
+ {TIFFTAG_CFAPLANECOLOR, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CFAPlaneColor", NULL},
+ {TIFFTAG_CFALAYOUT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CFALayout", NULL},
+ {TIFFTAG_LINEARIZATIONTABLE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "LinearizationTable", NULL},
+ {TIFFTAG_BLACKLEVELREPEATDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BlackLevelRepeatDim", NULL},
+ {TIFFTAG_BLACKLEVEL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "BlackLevel", NULL},
+ {TIFFTAG_BLACKLEVELDELTAH, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "BlackLevelDeltaH", NULL},
+ {TIFFTAG_BLACKLEVELDELTAV, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "BlackLevelDeltaV", NULL},
+ {TIFFTAG_WHITELEVEL, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "WhiteLevel", NULL},
+ {TIFFTAG_DEFAULTSCALE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DefaultScale", NULL},
+ {TIFFTAG_BESTQUALITYSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BestQualityScale", NULL},
+ {TIFFTAG_DEFAULTCROPORIGIN, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DefaultCropOrigin", NULL},
+ {TIFFTAG_DEFAULTCROPSIZE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DefaultCropSize", NULL},
+ {TIFFTAG_COLORMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ColorMatrix1", NULL},
+ {TIFFTAG_COLORMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ColorMatrix2", NULL},
+ {TIFFTAG_CAMERACALIBRATION1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CameraCalibration1", NULL},
+ {TIFFTAG_CAMERACALIBRATION2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CameraCalibration2", NULL},
+ {TIFFTAG_REDUCTIONMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ReductionMatrix1", NULL},
+ {TIFFTAG_REDUCTIONMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ReductionMatrix2", NULL},
+ {TIFFTAG_ANALOGBALANCE, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "AnalogBalance", NULL},
+ {TIFFTAG_ASSHOTNEUTRAL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "AsShotNeutral", NULL},
+ {TIFFTAG_ASSHOTWHITEXY, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "AsShotWhiteXY", NULL},
+ {TIFFTAG_BASELINEEXPOSURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BaselineExposure", NULL},
+ {TIFFTAG_BASELINENOISE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BaselineNoise", NULL},
+ {TIFFTAG_BASELINESHARPNESS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BaselineSharpness", NULL},
+ {TIFFTAG_BAYERGREENSPLIT, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BayerGreenSplit", NULL},
+ {TIFFTAG_LINEARRESPONSELIMIT, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LinearResponseLimit", NULL},
+ {TIFFTAG_CAMERASERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraSerialNumber", NULL},
+ {TIFFTAG_LENSINFO, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensInfo", NULL},
+ {TIFFTAG_CHROMABLURRADIUS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ChromaBlurRadius", NULL},
+ {TIFFTAG_ANTIALIASSTRENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "AntiAliasStrength", NULL},
+ {TIFFTAG_SHADOWSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ShadowScale", NULL},
+ {TIFFTAG_DNGPRIVATEDATA, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "DNGPrivateData", NULL},
+ {TIFFTAG_MAKERNOTESAFETY, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MakerNoteSafety", NULL},
+ {TIFFTAG_CALIBRATIONILLUMINANT1, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CalibrationIlluminant1", NULL},
+ {TIFFTAG_CALIBRATIONILLUMINANT2, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CalibrationIlluminant2", NULL},
+ {TIFFTAG_RAWDATAUNIQUEID, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RawDataUniqueID", NULL},
+ {TIFFTAG_ORIGINALRAWFILENAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OriginalRawFileName", NULL},
+ {TIFFTAG_ORIGINALRAWFILEDATA, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OriginalRawFileData", NULL},
+ {TIFFTAG_ACTIVEAREA, 4, 4, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ActiveArea", NULL},
+ {TIFFTAG_MASKEDAREAS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "MaskedAreas", NULL},
+ {TIFFTAG_ASSHOTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "AsShotICCProfile", NULL},
+ {TIFFTAG_ASSHOTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "AsShotPreProfileMatrix", NULL},
+ {TIFFTAG_CURRENTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CurrentICCProfile", NULL},
+ {TIFFTAG_CURRENTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CurrentPreProfileMatrix", NULL},
+ {TIFFTAG_PERSAMPLE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "PerSample", NULL},
+#if 0
+ /* TODO: revert above #if 0 for TIFF 4.6.0 */
+
+ /* begin DNG 1.2.0.0 tags */
+ {TIFFTAG_COLORIMETRICREFERENCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ColorimetricReference", NULL},
+ {TIFFTAG_CAMERACALIBRATIONSIGNATURE, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CameraCalibrationSignature", NULL},
+ {TIFFTAG_PROFILECALIBRATIONSIGNATURE, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileCalibrationSignature", NULL},
+ {TIFFTAG_EXTRACAMERAPROFILES, -1, -1, TIFF_IFD8, 0, TIFF_SETGET_C16_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ExtraCameraProfiles", NULL},
+ {TIFFTAG_ASSHOTPROFILENAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "AsShotProfileName", NULL},
+ {TIFFTAG_NOISEREDUCTIONAPPLIED, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "NoiseReductionApplied", NULL},
+ {TIFFTAG_PROFILENAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileName", NULL},
+ {TIFFTAG_PROFILEHUESATMAPDIMS, 3, 3, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ProfileHueSatMapDims", NULL},
+ {TIFFTAG_PROFILEHUESATMAPDATA1, -1, -1, TIFF_FLOAT, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileHueSatMapData1", NULL},
+ {TIFFTAG_PROFILEHUESATMAPDATA2, -1, -1, TIFF_FLOAT, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileHueSatMapData2", NULL},
+ {TIFFTAG_PROFILETONECURVE, -1, -1, TIFF_FLOAT, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileToneCurve", NULL},
+ {TIFFTAG_PROFILEEMBEDPOLICY, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ProfileEmbedPolicy", NULL},
+ {TIFFTAG_PROFILECOPYRIGHT, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileCopyright", NULL},
+ {TIFFTAG_FORWARDMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ForwardMatrix1", NULL},
+ {TIFFTAG_FORWARDMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ForwardMatrix2", NULL},
+ {TIFFTAG_PREVIEWAPPLICATIONNAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "PreviewApplicationName", NULL},
+ {TIFFTAG_PREVIEWAPPLICATIONVERSION, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "PreviewApplicationVersion", NULL},
+ {TIFFTAG_PREVIEWSETTINGSNAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "PreviewSettingsName", NULL},
+ {TIFFTAG_PREVIEWSETTINGSDIGEST, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PreviewSettingsDigest", NULL},
+ {TIFFTAG_PREVIEWCOLORSPACE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PreviewColorSpace", NULL},
+ {TIFFTAG_PREVIEWDATETIME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PreviewDateTime", NULL},
+ {TIFFTAG_RAWIMAGEDIGEST, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RawImageDigest", NULL},
+ {TIFFTAG_ORIGINALRAWFILEDIGEST, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OriginalRawFileDigest", NULL},
+ {TIFFTAG_SUBTILEBLOCKSIZE, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubTileBlockSize", NULL},
+ {TIFFTAG_ROWINTERLEAVEFACTOR, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RowInterleaveFactor", NULL},
+ {TIFFTAG_PROFILELOOKTABLEDIMS, 3, 3, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ProfileLookTableDims", NULL},
+ {TIFFTAG_PROFILELOOKTABLEDATA, -1, -1, TIFF_FLOAT, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileLookTableData", NULL},
+ /* begin DNG 1.3.0.0 tags */
+ {TIFFTAG_OPCODELIST1, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OpcodeList1", NULL},
+ {TIFFTAG_OPCODELIST2, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OpcodeList2", NULL},
+ {TIFFTAG_OPCODELIST3, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OpcodeList3", NULL},
+ {TIFFTAG_NOISEPROFILE, -1, -1, TIFF_DOUBLE, 0, TIFF_SETGET_C16_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "NoiseProfile", NULL},
+ /* begin DNG 1.4.0.0 tags */
+ {TIFFTAG_DEFAULTUSERCROP, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DefaultUserCrop", NULL},
+ {TIFFTAG_DEFAULTBLACKRENDER, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DefaultBlackRender", NULL},
+ {TIFFTAG_BASELINEEXPOSUREOFFSET, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BaselineExposureOffset", NULL},
+ {TIFFTAG_PROFILELOOKTABLEENCODING, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ProfileLookTableEncoding", NULL},
+ {TIFFTAG_PROFILEHUESATMAPENCODING, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ProfileHueSatMapEncoding", NULL},
+ {TIFFTAG_ORIGINALDEFAULTFINALSIZE, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OriginalDefaultFinalSize", NULL},
+ {TIFFTAG_ORIGINALBESTQUALITYFINALSIZE, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OriginalBestQualityFinalSize", NULL},
+ {TIFFTAG_ORIGINALDEFAULTCROPSIZE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OriginalDefaultCropSize", NULL}, /* could also be rational */
+ {TIFFTAG_NEWRAWIMAGEDIGEST, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "NewRawImageDigest", NULL},
+ {TIFFTAG_RAWTOPREVIEWGAIN, 1, 1, TIFF_DOUBLE, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RawToPreviewGain", NULL},
+ /* begin DNG 1.5.0.0 tags */
+ {TIFFTAG_DEPTHFORMAT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DepthFormat", NULL},
+ {TIFFTAG_DEPTHNEAR, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DepthNear", NULL},
+ {TIFFTAG_DEPTHFAR, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DepthFar", NULL},
+ {TIFFTAG_DEPTHUNITS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DepthUnits", NULL},
+ {TIFFTAG_DEPTHMEASURETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DepthMeasureType", NULL},
+ {TIFFTAG_ENHANCEPARAMS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EnhanceParams", NULL},
+ /* begin DNG 1.6.0.0 tags */
+ {TIFFTAG_PROFILEGAINTABLEMAP, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileGainTableMap", NULL},
+ {TIFFTAG_SEMANTICNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SemanticName", NULL},
+ {TIFFTAG_SEMANTICINSTANCEID, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SemanticInstanceID", NULL},
+ {TIFFTAG_MASKSUBAREA, 4, 4, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MaskSubArea", NULL},
+ {TIFFTAG_RGBTABLES, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "RGBTables", NULL},
+ {TIFFTAG_CALIBRATIONILLUMINANT3, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CalibrationIlluminant3", NULL},
+ {TIFFTAG_COLORMATRIX3, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ColorMatrix3", NULL},
+ {TIFFTAG_CAMERACALIBRATION3, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CameraCalibration3", NULL},
+ {TIFFTAG_REDUCTIONMATRIX3, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ReductionMatrix3", NULL},
+ {TIFFTAG_PROFILEHUESATMAPDATA3, -1, -1, TIFF_FLOAT, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileHueSatMapData3", NULL},
+ {TIFFTAG_FORWARDMATRIX3, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ForwardMatrix3", NULL},
+ {TIFFTAG_ILLUMINANTDATA1, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "IlluminantData1", NULL},
+ {TIFFTAG_ILLUMINANTDATA2, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "IlluminantData2", NULL},
+ {TIFFTAG_ILLUMINANTDATA3, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "IlluminantData3", NULL},
+ /* end DNG tags */
+ /* begin TIFF/EP tags */
+ {TIFFTAG_EP_CFAREPEATPATTERNDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP CFARepeatPatternDim", NULL},
+ {TIFFTAG_EP_CFAPATTERN, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP CFAPattern", NULL},
+ /* TIFFTAG_EP_BATTERYLEVEL can be RATIONAL or ASCII.
+ * LibTiff defines it as ASCII and converts RATIONAL to an ASCII string. */
+ {TIFFTAG_EP_BATTERYLEVEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP BatteryLevel", NULL},
+ {TIFFTAG_EP_INTERLACE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP Interlace", NULL},
+ /* TIFFTAG_EP_IPTC_NAA and TIFFTAG_RICHTIFFIPTC share the same tag number (33723)
+ * LibTIFF type is UNDEFINED or BYTE, but often times incorrectly specified as LONG, because TIFF/EP (ISO/DIS 12234-2) specifies type LONG or ASCII. */
+ {TIFFTAG_EP_TIMEZONEOFFSET, -1, -1, TIFF_SSHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP TimeZoneOffset", NULL},
+ {TIFFTAG_EP_SELFTIMERMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP SelfTimerMode", NULL},
+ {TIFFTAG_EP_FLASHENERGY, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP FlashEnergy", NULL},
+ {TIFFTAG_EP_SPATIALFREQUENCYRESPONSE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP SpatialFrequencyResponse", NULL},
+ {TIFFTAG_EP_NOISE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP Noise", NULL},
+ {TIFFTAG_EP_FOCALPLANEXRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP FocalPlaneXResolution", NULL},
+ {TIFFTAG_EP_FOCALPLANEYRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP FocalPlaneYResolution", NULL},
+ {TIFFTAG_EP_FOCALPLANERESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP FocalPlaneResolutionUnit", NULL},
+ {TIFFTAG_EP_IMAGENUMBER, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP ImageNumber", NULL}, /* or SHORT */
+ {TIFFTAG_EP_SECURITYCLASSIFICATION, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP SecurityClassification", NULL},
+ {TIFFTAG_EP_IMAGEHISTORY, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP ImageHistory", NULL},
+ {TIFFTAG_EP_EXPOSUREINDEX, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP ExposureIndex", NULL},
+ {TIFFTAG_EP_STANDARDID, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP StandardId", NULL},
+ {TIFFTAG_EP_SENSINGMETHOD, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP SensingMethod", NULL},
+ /* TIFF/EP tags equivalent to EXIF tags, sometimes defined differently. */
+ {TIFFTAG_EP_EXPOSURETIME, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP ExposureTime", NULL}, /*N=1 or 2 */
+ {TIFFTAG_EP_FNUMBER, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP FNumber", NULL},
+ {TIFFTAG_EP_EXPOSUREPROGRAM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP ExposureProgram", NULL},
+ {TIFFTAG_EP_SPECTRALSENSITIVITY, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP SpectralSensitivity", NULL},
+ {TIFFTAG_EP_ISOSPEEDRATINGS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP ISOSpeedRatings", NULL},
+ {TIFFTAG_EP_OECF, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP OptoelectricConversionFactor", NULL},
+ {TIFFTAG_EP_DATETIMEORIGINAL, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP DateTimeOriginal", NULL},
+ {TIFFTAG_EP_COMPRESSEDBITSPERPIXEL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP CompressedBitsPerPixel", NULL},
+ {TIFFTAG_EP_SHUTTERSPEEDVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP ShutterSpeedValue", NULL},
+ {TIFFTAG_EP_APERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP ApertureValue", NULL},
+ {TIFFTAG_EP_BRIGHTNESSVALUE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP BrightnessValue", NULL},
+ {TIFFTAG_EP_EXPOSUREBIASVALUE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP ExposureBiasValue", NULL}, /*N=1 or 2 */
+ {TIFFTAG_EP_MAXAPERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP MaxApertureValue", NULL},
+ {TIFFTAG_EP_SUBJECTDISTANCE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP SubjectDistance", NULL},
+ {TIFFTAG_EP_METERINGMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP MeteringMode", NULL},
+ {TIFFTAG_EP_LIGHTSOURCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP LightSource", NULL},
+ {TIFFTAG_EP_FLASH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP Flash", NULL},
+ {TIFFTAG_EP_FOCALLENGTH, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP FocalLength", NULL},
+ {TIFFTAG_EP_SUBJECTLOCATION, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP SubjectLocation", NULL},
+ /* end TIFF/EP tags */
+#endif
+ /* begin TIFF/FX tags */
+ {TIFFTAG_INDEXED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Indexed", NULL},
+ {TIFFTAG_GLOBALPARAMETERSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GlobalParametersIFD", NULL},
+ {TIFFTAG_PROFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ProfileType", NULL},
+ {TIFFTAG_FAXPROFILE, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FaxProfile", NULL},
+ {TIFFTAG_CODINGMETHODS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CodingMethods", NULL},
+ {TIFFTAG_VERSIONYEAR, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "VersionYear", NULL},
+ {TIFFTAG_MODENUMBER, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ModeNumber", NULL},
+ {TIFFTAG_DECODE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "Decode", NULL},
+ {TIFFTAG_IMAGEBASECOLOR, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ImageBaseColor", NULL},
+ {TIFFTAG_T82OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "T82Options", NULL},
+ {TIFFTAG_STRIPROWCOUNTS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "StripRowCounts", NULL},
+ {TIFFTAG_IMAGELAYER, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageLayer", NULL},
+ /* end TIFF/FX tags */
+ /* begin pseudo tags */
+};
+
+/*
+ * EXIF tags (Version 2.31, July 2016 plus version 2.32 May 2019)
+ */
+static const TIFFField exifFields[] = {
+ {EXIFTAG_EXPOSURETIME, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureTime", NULL},
+ {EXIFTAG_FNUMBER, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FNumber", NULL},
+ {EXIFTAG_EXPOSUREPROGRAM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureProgram", NULL},
+ {EXIFTAG_SPECTRALSENSITIVITY, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SpectralSensitivity", NULL},
+ /* After EXIF 2.2.1 ISOSpeedRatings is named PhotographicSensitivity. In addition, while "Count=Any", only 1 count should be used. */
+ {EXIFTAG_ISOSPEEDRATINGS, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ISOSpeedRatings", NULL},
+ {EXIFTAG_OECF, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OptoelectricConversionFactor", NULL},
+ {EXIFTAG_SENSITIVITYTYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SensitivityType", NULL},
+ {EXIFTAG_STANDARDOUTPUTSENSITIVITY, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "StandardOutputSensitivity", NULL},
+ {EXIFTAG_RECOMMENDEDEXPOSUREINDEX, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RecommendedExposureIndex", NULL},
+ {EXIFTAG_ISOSPEED, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeed", NULL},
+ {EXIFTAG_ISOSPEEDLATITUDEYYY, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeedLatitudeyyy", NULL},
+ {EXIFTAG_ISOSPEEDLATITUDEZZZ, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeedLatitudezzz", NULL},
+ {EXIFTAG_EXIFVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExifVersion", NULL},
+ {EXIFTAG_DATETIMEORIGINAL, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeOriginal", NULL},
+ {EXIFTAG_DATETIMEDIGITIZED, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeDigitized", NULL},
+ {EXIFTAG_OFFSETTIME, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTime", NULL},
+ {EXIFTAG_OFFSETTIMEORIGINAL, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTimeOriginal", NULL},
+ {EXIFTAG_OFFSETTIMEDIGITIZED, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTimeDigitized", NULL},
+ {EXIFTAG_COMPONENTSCONFIGURATION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ComponentsConfiguration", NULL},
+ {EXIFTAG_COMPRESSEDBITSPERPIXEL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CompressedBitsPerPixel", NULL},
+ {EXIFTAG_SHUTTERSPEEDVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ShutterSpeedValue", NULL},
+ {EXIFTAG_APERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ApertureValue", NULL},
+ {EXIFTAG_BRIGHTNESSVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BrightnessValue", NULL},
+ {EXIFTAG_EXPOSUREBIASVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureBiasValue", NULL},
+ {EXIFTAG_MAXAPERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MaxApertureValue", NULL},
+ /*--: EXIFTAG_SUBJECTDISTANCE: LibTiff returns value of "-1" if numerator equals 4294967295 (0xFFFFFFFF) to indicate infinite distance!
+ * However, there are two other EXIF tags where numerator indicates a special value and six other cases where the denominator indicates special values,
+ * which are not treated within LibTiff!! */
+ {EXIFTAG_SUBJECTDISTANCE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistance", NULL},
+ {EXIFTAG_METERINGMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MeteringMode", NULL},
+ {EXIFTAG_LIGHTSOURCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LightSource", NULL},
+ {EXIFTAG_FLASH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Flash", NULL},
+ {EXIFTAG_FOCALLENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLength", NULL},
+ {EXIFTAG_SUBJECTAREA, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SubjectArea", NULL},
+ {EXIFTAG_MAKERNOTE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "MakerNote", NULL},
+ {EXIFTAG_USERCOMMENT, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "UserComment", NULL},
+ {EXIFTAG_SUBSECTIME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTime", NULL},
+ {EXIFTAG_SUBSECTIMEORIGINAL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeOriginal", NULL},
+ {EXIFTAG_SUBSECTIMEDIGITIZED, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeDigitized", NULL},
+ {EXIFTAG_TEMPERATURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Temperature", NULL},
+ {EXIFTAG_HUMIDITY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Humidity", NULL},
+ {EXIFTAG_PRESSURE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Pressure", NULL},
+ {EXIFTAG_WATERDEPTH, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WaterDepth", NULL},
+ {EXIFTAG_ACCELERATION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Acceleration", NULL},
+ {EXIFTAG_CAMERAELEVATIONANGLE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraElevationAngle", NULL},
+ {EXIFTAG_FLASHPIXVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashpixVersion", NULL},
+ {EXIFTAG_COLORSPACE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ColorSpace", NULL},
+ {EXIFTAG_PIXELXDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelXDimension", NULL},
+ {EXIFTAG_PIXELYDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelYDimension", NULL},
+ {EXIFTAG_RELATEDSOUNDFILE, 13, 13, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RelatedSoundFile", NULL},
+ {EXIFTAG_FLASHENERGY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashEnergy", NULL},
+ {EXIFTAG_SPATIALFREQUENCYRESPONSE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SpatialFrequencyResponse", NULL},
+ {EXIFTAG_FOCALPLANEXRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneXResolution", NULL},
+ {EXIFTAG_FOCALPLANEYRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneYResolution", NULL},
+ {EXIFTAG_FOCALPLANERESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneResolutionUnit", NULL},
+ {EXIFTAG_SUBJECTLOCATION, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectLocation", NULL},
+ {EXIFTAG_EXPOSUREINDEX, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureIndex", NULL},
+ {EXIFTAG_SENSINGMETHOD, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SensingMethod", NULL},
+ {EXIFTAG_FILESOURCE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FileSource", NULL},
+ {EXIFTAG_SCENETYPE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneType", NULL},
+ {EXIFTAG_CFAPATTERN, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CFAPattern", NULL},
+ {EXIFTAG_CUSTOMRENDERED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CustomRendered", NULL},
+ {EXIFTAG_EXPOSUREMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureMode", NULL},
+ {EXIFTAG_WHITEBALANCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhiteBalance", NULL},
+ {EXIFTAG_DIGITALZOOMRATIO, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DigitalZoomRatio", NULL},
+ {EXIFTAG_FOCALLENGTHIN35MMFILM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLengthIn35mmFilm", NULL},
+ {EXIFTAG_SCENECAPTURETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneCaptureType", NULL},
+ {EXIFTAG_GAINCONTROL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GainControl", NULL},
+ {EXIFTAG_CONTRAST, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Contrast", NULL},
+ {EXIFTAG_SATURATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Saturation", NULL},
+ {EXIFTAG_SHARPNESS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Sharpness", NULL},
+ {EXIFTAG_DEVICESETTINGDESCRIPTION, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "DeviceSettingDescription", NULL},
+ {EXIFTAG_SUBJECTDISTANCERANGE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistanceRange", NULL},
+ {EXIFTAG_IMAGEUNIQUEID, 33, 33, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageUniqueID", NULL},
+ {EXIFTAG_CAMERAOWNERNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraOwnerName", NULL},
+ {EXIFTAG_BODYSERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BodySerialNumber", NULL},
+ {EXIFTAG_LENSSPECIFICATION, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensSpecification", NULL},
+ {EXIFTAG_LENSMAKE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensMake", NULL},
+ {EXIFTAG_LENSMODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensModel", NULL},
+ {EXIFTAG_LENSSERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensSerialNumber", NULL},
+ {EXIFTAG_GAMMA, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Gamma", NULL},
+ {EXIFTAG_COMPOSITEIMAGE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CompositeImage", NULL},
+ {EXIFTAG_SOURCEIMAGENUMBEROFCOMPOSITEIMAGE, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SourceImageNumberOfCompositeImage", NULL},
+ {EXIFTAG_SOURCEEXPOSURETIMESOFCOMPOSITEIMAGE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1,
+ "SourceExposureTimesOfCompositeImage", NULL}};
+/*
+ * EXIF-GPS tags (Version 2.31, July 2016; nothing changed for version 2.32 May
+ * 2019)
+ */
+
+static const TIFFField gpsFields[] = {
+ /* For the GPS tag definitions in gpsFields[] the standard definition for Rationals is TIFF_SETGET_DOUBLE and TIFF_SETGET_C0_FLOAT.
+ *-- ATTENTION: After the upgrade with Rational2Double, the GPSTAG values can now be written and also read in double precision!
+ * In order to achieve double precision for GPS tags: Standard definitions for GPSTAG is kept to TIFF_SETGET_DOUBLE
+ * and TIFF_SETGET_C0_FLOAT is changed to TIFF_SETGET_C0_DOUBLE.
+ */
+ {GPSTAG_VERSIONID, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UINT8, FIELD_CUSTOM, 1, 0, "VersionID", NULL},
+ {GPSTAG_LATITUDEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LatitudeRef", NULL},
+ {GPSTAG_LATITUDE, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Latitude", NULL},
+ {GPSTAG_LONGITUDEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LongitudeRef", NULL},
+ {GPSTAG_LONGITUDE, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Longitude", NULL},
+ {GPSTAG_ALTITUDEREF, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "AltitudeRef", NULL},
+ {GPSTAG_ALTITUDE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Altitude", NULL},
+ {GPSTAG_TIMESTAMP, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TimeStamp", NULL},
+ {GPSTAG_SATELLITES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Satellites", NULL},
+ {GPSTAG_STATUS, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Status", NULL},
+ {GPSTAG_MEASUREMODE, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MeasureMode", NULL},
+ {GPSTAG_DOP, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DOP", NULL},
+ {GPSTAG_SPEEDREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SpeedRef", NULL},
+ {GPSTAG_SPEED, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Speed", NULL},
+ {GPSTAG_TRACKREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TrackRef", NULL},
+ {GPSTAG_TRACK, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Track", NULL},
+ {GPSTAG_IMGDIRECTIONREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImgDirectionRef", NULL},
+ {GPSTAG_IMGDIRECTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImgDirection", NULL},
+ {GPSTAG_MAPDATUM, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MapDatum", NULL},
+ {GPSTAG_DESTLATITUDEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestLatitudeRef", NULL},
+ {GPSTAG_DESTLATITUDE, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestLatitude", NULL},
+ {GPSTAG_DESTLONGITUDEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestLongitudeRef", NULL},
+ {GPSTAG_DESTLONGITUDE, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestLongitude", NULL},
+ {GPSTAG_DESTBEARINGREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestBearingRef", NULL},
+ {GPSTAG_DESTBEARING, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestBearing", NULL},
+ {GPSTAG_DESTDISTANCEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestDistanceRef", NULL},
+ {GPSTAG_DESTDISTANCE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestDistance", NULL},
+ {GPSTAG_PROCESSINGMETHOD, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProcessingMethod", NULL},
+ {GPSTAG_AREAINFORMATION, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "AreaInformation", NULL},
+ {GPSTAG_DATESTAMP, 11, 11, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateStamp", NULL},
+ {GPSTAG_DIFFERENTIAL, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Differential", NULL},
+ {GPSTAG_GPSHPOSITIONINGERROR, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "HorizontalPositioningError", NULL}};
+/* clang-format on */ /* was off for better readability of tag comments */
+
+static const TIFFFieldArray tiffFieldArray = {
+ tfiatImage, 0, TIFFArrayCount(tiffFields), (TIFFField *)tiffFields};
+static const TIFFFieldArray exifFieldArray = {
+ tfiatExif, 0, TIFFArrayCount(exifFields), (TIFFField *)exifFields};
+static const TIFFFieldArray gpsFieldArray = {
+ tfiatGps, 0, TIFFArrayCount(gpsFields), (TIFFField *)gpsFields};
+
+/*
+ * We have our own local lfind() equivalent to avoid subtle differences
+ * in types passed to lfind() on different systems.
+ */
+
+static void *td_lfind(const void *key, const void *base, size_t *nmemb,
+ size_t size, int (*compar)(const void *, const void *))
+{
+ char *element, *end;
+
+ end = (char *)base + *nmemb * size;
+ for (element = (char *)base; element < end; element += size)
+ if (!compar(key, element)) /* key found */
+ return element;
+
+ return NULL;
+}
+
+const TIFFFieldArray *_TIFFGetFields(void) { return (&tiffFieldArray); }
+
+const TIFFFieldArray *_TIFFGetExifFields(void) { return (&exifFieldArray); }
+
+const TIFFFieldArray *_TIFFGetGpsFields(void) { return (&gpsFieldArray); }
+
+void _TIFFSetupFields(TIFF *tif, const TIFFFieldArray *fieldarray)
+{
+ if (tif->tif_fields && tif->tif_nfields > 0)
+ {
+ uint32_t i;
+
+ for (i = 0; i < tif->tif_nfields; i++)
+ {
+ TIFFField *fld = tif->tif_fields[i];
+ if (fld->field_name != NULL)
+ {
+ if (fld->field_bit == FIELD_CUSTOM && TIFFFieldIsAnonymous(fld))
+ {
+ _TIFFfreeExt(tif, 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().
+ */
+ _TIFFfreeExt(tif, fld);
+ }
+ }
+ }
+
+ _TIFFfreeExt(tif, tif->tif_fields);
+ tif->tif_fields = NULL;
+ tif->tif_nfields = 0;
+ }
+ if (!_TIFFMergeFields(tif, fieldarray->fields, fieldarray->count))
+ {
+ TIFFErrorExtR(tif, "_TIFFSetupFields", "Setting up field info failed");
+ }
+}
+
+static int tagCompare(const void *a, const void *b)
+{
+ const TIFFField *ta = *(const TIFFField **)a;
+ const TIFFField *tb = *(const TIFFField **)b;
+ /* NB: be careful of return values for 16-bit platforms */
+ if (ta->field_tag != tb->field_tag)
+ return (int)ta->field_tag - (int)tb->field_tag;
+ else
+ return (ta->field_type == TIFF_ANY)
+ ? 0
+ : ((int)tb->field_type - (int)ta->field_type);
+}
+
+static int tagNameCompare(const void *a, const void *b)
+{
+ const TIFFField *ta = *(const TIFFField **)a;
+ const TIFFField *tb = *(const TIFFField **)b;
+ int ret = strcmp(ta->field_name, tb->field_name);
+
+ if (ret)
+ return ret;
+ else
+ return (ta->field_type == TIFF_ANY)
+ ? 0
+ : ((int)tb->field_type - (int)ta->field_type);
+}
+
+int _TIFFMergeFields(TIFF *tif, const TIFFField info[], uint32_t n)
+{
+ static const char module[] = "_TIFFMergeFields";
+ static const char reason[] = "for fields array";
+ /* TIFFField** tp; */
+ uint32_t i;
+
+ tif->tif_foundfield = NULL;
+
+ if (tif->tif_fields && tif->tif_nfields > 0)
+ {
+ tif->tif_fields = (TIFFField **)_TIFFCheckRealloc(
+ tif, tif->tif_fields, (tif->tif_nfields + n), sizeof(TIFFField *),
+ reason);
+ }
+ else
+ {
+ tif->tif_fields =
+ (TIFFField **)_TIFFCheckMalloc(tif, n, sizeof(TIFFField *), reason);
+ }
+ if (!tif->tif_fields)
+ {
+ TIFFErrorExtR(tif, module, "Failed to allocate fields array");
+ return 0;
+ }
+
+ /* tp = tif->tif_fields + tif->tif_nfields; */
+ for (i = 0; i < n; i++)
+ {
+ const TIFFField *fip = TIFFFindField(tif, info[i].field_tag, TIFF_ANY);
+
+ /* only add definitions that aren't already present */
+ if (!fip)
+ {
+ tif->tif_fields[tif->tif_nfields] = (TIFFField *)(info + i);
+ tif->tif_nfields++;
+ }
+ }
+
+ /* Sort the field info by tag number */
+ qsort(tif->tif_fields, tif->tif_nfields, sizeof(TIFFField *), tagCompare);
+
+ return n;
+}
+
+void _TIFFPrintFieldInfo(TIFF *tif, FILE *fd)
+{
+ uint32_t i;
+
+ fprintf(fd, "%s: \n", tif->tif_name);
+ for (i = 0; i < tif->tif_nfields; i++)
+ {
+ const TIFFField *fip = tif->tif_fields[i];
+ fprintf(fd, "field[%2d] %5lu, %2d, %2d, %d, %2d, %5s, %5s, %s\n",
+ (int)i, (unsigned long)fip->field_tag, fip->field_readcount,
+ fip->field_writecount, fip->field_type, fip->field_bit,
+ fip->field_oktochange ? "TRUE" : "FALSE",
+ fip->field_passcount ? "TRUE" : "FALSE", fip->field_name);
+ }
+}
+
+/*
+ * Return size of TIFFDataType within TIFF-file in bytes
+ */
+int TIFFDataWidth(TIFFDataType type)
+{
+ switch (type)
+ {
+ case 0: /* nothing */
+ case TIFF_BYTE:
+ case TIFF_ASCII:
+ case TIFF_SBYTE:
+ 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:
+ return 4;
+ case TIFF_RATIONAL:
+ case TIFF_SRATIONAL:
+ case TIFF_DOUBLE:
+ case TIFF_LONG8:
+ case TIFF_SLONG8:
+ case TIFF_IFD8:
+ return 8;
+ default:
+ return 0; /* will return 0 for unknown types */
+ }
+}
+
+/*
+ * 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 TIFFFieldSetGetSize(const TIFFField *fip)
+{
+ /*
+ * 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:
+ case TIFF_SETGET_C0_ASCII:
+ case TIFF_SETGET_C16_ASCII:
+ case TIFF_SETGET_C32_ASCII:
+ case TIFF_SETGET_OTHER:
+ return 1;
+ case TIFF_SETGET_UINT8:
+ case TIFF_SETGET_SINT8:
+ case TIFF_SETGET_C0_UINT8:
+ case TIFF_SETGET_C0_SINT8:
+ case TIFF_SETGET_C16_UINT8:
+ case TIFF_SETGET_C16_SINT8:
+ case TIFF_SETGET_C32_UINT8:
+ case TIFF_SETGET_C32_SINT8:
+ return 1;
+ case TIFF_SETGET_UINT16:
+ case TIFF_SETGET_SINT16:
+ case TIFF_SETGET_C0_UINT16:
+ case TIFF_SETGET_C0_SINT16:
+ case TIFF_SETGET_C16_UINT16:
+ case TIFF_SETGET_C16_SINT16:
+ case TIFF_SETGET_C32_UINT16:
+ case TIFF_SETGET_C32_SINT16:
+ return 2;
+ case TIFF_SETGET_INT:
+ case TIFF_SETGET_UINT32:
+ case TIFF_SETGET_SINT32:
+ case TIFF_SETGET_FLOAT:
+ case TIFF_SETGET_UINT16_PAIR:
+ case TIFF_SETGET_C0_UINT32:
+ case TIFF_SETGET_C0_SINT32:
+ case TIFF_SETGET_C0_FLOAT:
+ case TIFF_SETGET_C16_UINT32:
+ case TIFF_SETGET_C16_SINT32:
+ case TIFF_SETGET_C16_FLOAT:
+ case TIFF_SETGET_C32_UINT32:
+ case TIFF_SETGET_C32_SINT32:
+ case TIFF_SETGET_C32_FLOAT:
+ return 4;
+ case TIFF_SETGET_UINT64:
+ case TIFF_SETGET_SINT64:
+ case TIFF_SETGET_DOUBLE:
+ case TIFF_SETGET_IFD8:
+ case TIFF_SETGET_C0_UINT64:
+ case TIFF_SETGET_C0_SINT64:
+ case TIFF_SETGET_C0_DOUBLE:
+ case TIFF_SETGET_C0_IFD8:
+ case TIFF_SETGET_C16_UINT64:
+ case TIFF_SETGET_C16_SINT64:
+ case TIFF_SETGET_C16_DOUBLE:
+ case TIFF_SETGET_C16_IFD8:
+ case TIFF_SETGET_C32_UINT64:
+ case TIFF_SETGET_C32_SINT64:
+ case TIFF_SETGET_C32_DOUBLE:
+ case TIFF_SETGET_C32_IFD8:
+ return 8;
+ default:
+ return 0;
+ }
+} /*-- 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 *TIFFFindField(TIFF *tif, uint32_t tag, TIFFDataType dt)
+{
+ TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, 0, NULL, NULL};
+ TIFFField *pkey = &key;
+ const TIFFField **ret;
+ if (tif->tif_foundfield && tif->tif_foundfield->field_tag == tag &&
+ (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type))
+ return tif->tif_foundfield;
+
+ /* If we are invoked with no field information, then just return. */
+ if (!tif->tif_fields)
+ return NULL;
+
+ /* NB: use sorted search (e.g. binary search) */
+
+ key.field_tag = tag;
+ key.field_type = dt;
+
+ ret = (const TIFFField **)bsearch(&pkey, tif->tif_fields, tif->tif_nfields,
+ sizeof(TIFFField *), tagCompare);
+ return tif->tif_foundfield = (ret ? *ret : NULL);
+}
+
+static const TIFFField *_TIFFFindFieldByName(TIFF *tif, const char *field_name,
+ TIFFDataType dt)
+{
+ TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, 0, NULL, NULL};
+ TIFFField *pkey = &key;
+ const TIFFField **ret;
+ if (tif->tif_foundfield &&
+ streq(tif->tif_foundfield->field_name, field_name) &&
+ (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type))
+ return (tif->tif_foundfield);
+
+ /* If we are invoked with no field information, then just return. */
+ if (!tif->tif_fields)
+ return NULL;
+
+ /* NB: use linear search since list is sorted by key#, not name */
+
+ key.field_name = (char *)field_name;
+ key.field_type = dt;
+
+ ret =
+ (const TIFFField **)td_lfind(&pkey, tif->tif_fields, &tif->tif_nfields,
+ sizeof(TIFFField *), tagNameCompare);
+
+ return tif->tif_foundfield = (ret ? *ret : NULL);
+}
+
+const TIFFField *TIFFFieldWithTag(TIFF *tif, uint32_t tag)
+{
+ const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
+ if (!fip)
+ {
+ TIFFWarningExtR(tif, "TIFFFieldWithTag", "Warning, unknown tag 0x%x",
+ (unsigned int)tag);
+ }
+ return (fip);
+}
+
+const TIFFField *TIFFFieldWithName(TIFF *tif, const char *field_name)
+{
+ const TIFFField *fip = _TIFFFindFieldByName(tif, field_name, TIFF_ANY);
+ if (!fip)
+ {
+ TIFFWarningExtR(tif, "TIFFFieldWithName", "Warning, unknown tag %s",
+ field_name);
+ }
+ return (fip);
+}
+
+uint32_t TIFFFieldTag(const TIFFField *fip) { return fip->field_tag; }
+
+const char *TIFFFieldName(const TIFFField *fip) { return fip->field_name; }
+
+TIFFDataType TIFFFieldDataType(const TIFFField *fip) { return fip->field_type; }
+
+int TIFFFieldPassCount(const TIFFField *fip) { return fip->field_passcount; }
+
+int TIFFFieldReadCount(const TIFFField *fip) { return fip->field_readcount; }
+
+int 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)
+
+{
+ const TIFFField *fld;
+
+ fld = TIFFFindField(tif, tag, dt);
+ if (fld == NULL)
+ {
+ fld = _TIFFCreateAnonField(tif, tag, dt);
+ if (!_TIFFMergeFields(tif, fld, 1))
+ return NULL;
+ }
+
+ return fld;
+}
+
+TIFFField *_TIFFCreateAnonField(TIFF *tif, uint32_t tag,
+ TIFFDataType field_type)
+{
+ TIFFField *fld;
+ (void)tif;
+
+ fld = (TIFFField *)_TIFFmallocExt(tif, sizeof(TIFFField));
+ if (fld == NULL)
+ return NULL;
+ _TIFFmemset(fld, 0, sizeof(TIFFField));
+
+ fld->field_tag = tag;
+ fld->field_readcount = TIFF_VARIABLE2;
+ fld->field_writecount = TIFF_VARIABLE2;
+ fld->field_type = field_type;
+ fld->field_anonymous =
+ 1; /* indicate that this is an anonymous / unknown tag */
+ switch (field_type)
+ {
+ case TIFF_BYTE:
+ case TIFF_UNDEFINED:
+ fld->set_field_type = TIFF_SETGET_C32_UINT8;
+ fld->get_field_type = TIFF_SETGET_C32_UINT8;
+ break;
+ case TIFF_ASCII:
+ fld->set_field_type = TIFF_SETGET_C32_ASCII;
+ fld->get_field_type = TIFF_SETGET_C32_ASCII;
+ break;
+ case TIFF_SHORT:
+ fld->set_field_type = TIFF_SETGET_C32_UINT16;
+ fld->get_field_type = TIFF_SETGET_C32_UINT16;
+ break;
+ case TIFF_LONG:
+ fld->set_field_type = TIFF_SETGET_C32_UINT32;
+ fld->get_field_type = TIFF_SETGET_C32_UINT32;
+ break;
+ case TIFF_RATIONAL:
+ case TIFF_SRATIONAL:
+ case TIFF_FLOAT:
+ fld->set_field_type = TIFF_SETGET_C32_FLOAT;
+ fld->get_field_type = TIFF_SETGET_C32_FLOAT;
+ break;
+ case TIFF_SBYTE:
+ fld->set_field_type = TIFF_SETGET_C32_SINT8;
+ fld->get_field_type = TIFF_SETGET_C32_SINT8;
+ break;
+ case TIFF_SSHORT:
+ fld->set_field_type = TIFF_SETGET_C32_SINT16;
+ fld->get_field_type = TIFF_SETGET_C32_SINT16;
+ break;
+ case TIFF_SLONG:
+ fld->set_field_type = TIFF_SETGET_C32_SINT32;
+ fld->get_field_type = TIFF_SETGET_C32_SINT32;
+ break;
+ case TIFF_DOUBLE:
+ fld->set_field_type = TIFF_SETGET_C32_DOUBLE;
+ fld->get_field_type = TIFF_SETGET_C32_DOUBLE;
+ break;
+ case TIFF_IFD:
+ case TIFF_IFD8:
+ fld->set_field_type = TIFF_SETGET_C32_IFD8;
+ fld->get_field_type = TIFF_SETGET_C32_IFD8;
+ break;
+ case TIFF_LONG8:
+ fld->set_field_type = TIFF_SETGET_C32_UINT64;
+ fld->get_field_type = TIFF_SETGET_C32_UINT64;
+ break;
+ case TIFF_SLONG8:
+ fld->set_field_type = TIFF_SETGET_C32_SINT64;
+ fld->get_field_type = TIFF_SETGET_C32_SINT64;
+ break;
+ default:
+ fld->set_field_type = TIFF_SETGET_UNDEFINED;
+ fld->get_field_type = TIFF_SETGET_UNDEFINED;
+ break;
+ }
+ fld->field_bit = FIELD_CUSTOM;
+ fld->field_oktochange = TRUE;
+ fld->field_passcount = TRUE;
+ fld->field_name = (char *)_TIFFmallocExt(tif, 32);
+ if (fld->field_name == NULL)
+ {
+ _TIFFfreeExt(tif, fld);
+ return NULL;
+ }
+ fld->field_subfields = NULL;
+
+ /*
+ * 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);
+
+ return fld;
+}
+
+/****************************************************************************
+ * O B S O L E T E D I N T E R F A C E S
+ *
+ * Don't use this stuff in your applications, it may be removed in the future
+ * libtiff versions.
+ ****************************************************************************/
+
+static TIFFSetGetFieldType _TIFFSetGetType(TIFFDataType type, short count,
+ unsigned char passcount)
+{
+ if (type == TIFF_ASCII && count == TIFF_VARIABLE && passcount == 0)
+ return TIFF_SETGET_ASCII;
+
+ else if (count == 1 && passcount == 0)
+ {
+ switch (type)
+ {
+ case TIFF_BYTE:
+ case TIFF_UNDEFINED:
+ return TIFF_SETGET_UINT8;
+ case TIFF_ASCII:
+ return TIFF_SETGET_ASCII;
+ case TIFF_SHORT:
+ return TIFF_SETGET_UINT16;
+ case TIFF_LONG:
+ return TIFF_SETGET_UINT32;
+ case TIFF_RATIONAL:
+ case TIFF_SRATIONAL:
+ case TIFF_FLOAT:
+ return TIFF_SETGET_FLOAT;
+ case TIFF_SBYTE:
+ return TIFF_SETGET_SINT8;
+ case TIFF_SSHORT:
+ return TIFF_SETGET_SINT16;
+ case TIFF_SLONG:
+ return TIFF_SETGET_SINT32;
+ case TIFF_DOUBLE:
+ return TIFF_SETGET_DOUBLE;
+ case TIFF_IFD:
+ case TIFF_IFD8:
+ return TIFF_SETGET_IFD8;
+ case TIFF_LONG8:
+ return TIFF_SETGET_UINT64;
+ case TIFF_SLONG8:
+ return TIFF_SETGET_SINT64;
+ default:
+ return TIFF_SETGET_UNDEFINED;
+ }
+ }
+
+ else if (count >= 1 && passcount == 0)
+ {
+ switch (type)
+ {
+ case TIFF_BYTE:
+ case TIFF_UNDEFINED:
+ return TIFF_SETGET_C0_UINT8;
+ case TIFF_ASCII:
+ return TIFF_SETGET_C0_ASCII;
+ case TIFF_SHORT:
+ return TIFF_SETGET_C0_UINT16;
+ case TIFF_LONG:
+ return TIFF_SETGET_C0_UINT32;
+ case TIFF_RATIONAL:
+ case TIFF_SRATIONAL:
+ case TIFF_FLOAT:
+ return TIFF_SETGET_C0_FLOAT;
+ case TIFF_SBYTE:
+ return TIFF_SETGET_C0_SINT8;
+ case TIFF_SSHORT:
+ return TIFF_SETGET_C0_SINT16;
+ case TIFF_SLONG:
+ return TIFF_SETGET_C0_SINT32;
+ case TIFF_DOUBLE:
+ return TIFF_SETGET_C0_DOUBLE;
+ case TIFF_IFD:
+ case TIFF_IFD8:
+ return TIFF_SETGET_C0_IFD8;
+ case TIFF_LONG8:
+ return TIFF_SETGET_C0_UINT64;
+ case TIFF_SLONG8:
+ return TIFF_SETGET_C0_SINT64;
+ default:
+ return TIFF_SETGET_UNDEFINED;
+ }
+ }
+
+ else if (count == TIFF_VARIABLE && passcount == 1)
+ {
+ switch (type)
+ {
+ case TIFF_BYTE:
+ case TIFF_UNDEFINED:
+ return TIFF_SETGET_C16_UINT8;
+ case TIFF_ASCII:
+ return TIFF_SETGET_C16_ASCII;
+ case TIFF_SHORT:
+ return TIFF_SETGET_C16_UINT16;
+ case TIFF_LONG:
+ return TIFF_SETGET_C16_UINT32;
+ case TIFF_RATIONAL:
+ case TIFF_SRATIONAL:
+ case TIFF_FLOAT:
+ return TIFF_SETGET_C16_FLOAT;
+ case TIFF_SBYTE:
+ return TIFF_SETGET_C16_SINT8;
+ case TIFF_SSHORT:
+ return TIFF_SETGET_C16_SINT16;
+ case TIFF_SLONG:
+ return TIFF_SETGET_C16_SINT32;
+ case TIFF_DOUBLE:
+ return TIFF_SETGET_C16_DOUBLE;
+ case TIFF_IFD:
+ case TIFF_IFD8:
+ return TIFF_SETGET_C16_IFD8;
+ case TIFF_LONG8:
+ return TIFF_SETGET_C16_UINT64;
+ case TIFF_SLONG8:
+ return TIFF_SETGET_C16_SINT64;
+ default:
+ return TIFF_SETGET_UNDEFINED;
+ }
+ }
+
+ else if (count == TIFF_VARIABLE2 && passcount == 1)
+ {
+ switch (type)
+ {
+ case TIFF_BYTE:
+ case TIFF_UNDEFINED:
+ return TIFF_SETGET_C32_UINT8;
+ case TIFF_ASCII:
+ return TIFF_SETGET_C32_ASCII;
+ case TIFF_SHORT:
+ return TIFF_SETGET_C32_UINT16;
+ case TIFF_LONG:
+ return TIFF_SETGET_C32_UINT32;
+ case TIFF_RATIONAL:
+ case TIFF_SRATIONAL:
+ case TIFF_FLOAT:
+ return TIFF_SETGET_C32_FLOAT;
+ case TIFF_SBYTE:
+ return TIFF_SETGET_C32_SINT8;
+ case TIFF_SSHORT:
+ return TIFF_SETGET_C32_SINT16;
+ case TIFF_SLONG:
+ return TIFF_SETGET_C32_SINT32;
+ case TIFF_DOUBLE:
+ return TIFF_SETGET_C32_DOUBLE;
+ case TIFF_IFD:
+ case TIFF_IFD8:
+ return TIFF_SETGET_C32_IFD8;
+ case TIFF_LONG8:
+ return TIFF_SETGET_C32_UINT64;
+ case TIFF_SLONG8:
+ return TIFF_SETGET_C32_SINT64;
+ default:
+ return TIFF_SETGET_UNDEFINED;
+ }
+ }
+
+ return TIFF_SETGET_UNDEFINED;
+}
+
+int TIFFMergeFieldInfo(TIFF *tif, const TIFFFieldInfo info[], uint32_t n)
+{
+ static const char module[] = "TIFFMergeFieldInfo";
+ static const char reason[] = "for fields array";
+ TIFFField *tp;
+ size_t nfields;
+ uint32_t i;
+
+ if (tif->tif_nfieldscompat > 0)
+ {
+ tif->tif_fieldscompat = (TIFFFieldArray *)_TIFFCheckRealloc(
+ tif, tif->tif_fieldscompat, tif->tif_nfieldscompat + 1,
+ sizeof(TIFFFieldArray), reason);
+ }
+ else
+ {
+ tif->tif_fieldscompat = (TIFFFieldArray *)_TIFFCheckMalloc(
+ tif, 1, sizeof(TIFFFieldArray), reason);
+ }
+ if (!tif->tif_fieldscompat)
+ {
+ TIFFErrorExtR(tif, module, "Failed to allocate fields array");
+ return -1;
+ }
+ nfields = tif->tif_nfieldscompat++;
+
+ tif->tif_fieldscompat[nfields].type = tfiatOther;
+ tif->tif_fieldscompat[nfields].allocated_size = n;
+ tif->tif_fieldscompat[nfields].count = n;
+ tif->tif_fieldscompat[nfields].fields =
+ (TIFFField *)_TIFFCheckMalloc(tif, n, sizeof(TIFFField), reason);
+ if (!tif->tif_fieldscompat[nfields].fields)
+ {
+ TIFFErrorExtR(tif, module, "Failed to allocate fields array");
+ return -1;
+ }
+
+ tp = tif->tif_fieldscompat[nfields].fields;
+ for (i = 0; i < n; i++)
+ {
+ tp->field_tag = info[i].field_tag;
+ tp->field_readcount = info[i].field_readcount;
+ tp->field_writecount = info[i].field_writecount;
+ tp->field_type = info[i].field_type;
+ tp->field_anonymous = 0;
+ tp->set_field_type =
+ _TIFFSetGetType(info[i].field_type, info[i].field_readcount,
+ info[i].field_passcount);
+ tp->get_field_type =
+ _TIFFSetGetType(info[i].field_type, info[i].field_readcount,
+ info[i].field_passcount);
+ 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)
+ {
+ TIFFErrorExtR(tif, 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++;
+ }
+
+ if (!_TIFFMergeFields(tif, tif->tif_fieldscompat[nfields].fields, n))
+ {
+ TIFFErrorExtR(tif, module, "Setting up field info failed");
+ return -1;
+ }
+
+ return 0;
+}
+
+int _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag)
+{
+ /* Filter out non-codec specific tags */
+ switch (tag)
+ {
+ /* Shared tags */
+ case TIFFTAG_PREDICTOR:
+ /* JPEG tags */
+ case TIFFTAG_JPEGTABLES:
+ /* OJPEG tags */
+ case TIFFTAG_JPEGIFOFFSET:
+ case TIFFTAG_JPEGIFBYTECOUNT:
+ case TIFFTAG_JPEGQTABLES:
+ case TIFFTAG_JPEGDCTABLES:
+ case TIFFTAG_JPEGACTABLES:
+ case TIFFTAG_JPEGPROC:
+ case TIFFTAG_JPEGRESTARTINTERVAL:
+ /* CCITT* */
+ case TIFFTAG_BADFAXLINES:
+ case TIFFTAG_CLEANFAXDATA:
+ case TIFFTAG_CONSECUTIVEBADFAXLINES:
+ case TIFFTAG_GROUP3OPTIONS:
+ case TIFFTAG_GROUP4OPTIONS:
+ /* LERC */
+ case TIFFTAG_LERC_PARAMETERS:
+ break;
+ default:
+ return 1;
+ }
+ if (!TIFFIsCODECConfigured(tif->tif_dir.td_compression))
+ {
+ return 0;
+ }
+ /* Check if codec specific tags are allowed for the current
+ * compression scheme (codec) */
+ switch (tif->tif_dir.td_compression)
+ {
+ case COMPRESSION_LZW:
+ if (tag == TIFFTAG_PREDICTOR)
+ return 1;
+ break;
+ case COMPRESSION_PACKBITS:
+ /* No codec-specific tags */
+ break;
+ case COMPRESSION_THUNDERSCAN:
+ /* No codec-specific tags */
+ break;
+ case COMPRESSION_NEXT:
+ /* No codec-specific tags */
+ break;
+ case COMPRESSION_JPEG:
+ if (tag == TIFFTAG_JPEGTABLES)
+ return 1;
+ break;
+ case COMPRESSION_OJPEG:
+ switch (tag)
+ {
+ case TIFFTAG_JPEGIFOFFSET:
+ case TIFFTAG_JPEGIFBYTECOUNT:
+ case TIFFTAG_JPEGQTABLES:
+ case TIFFTAG_JPEGDCTABLES:
+ case TIFFTAG_JPEGACTABLES:
+ case TIFFTAG_JPEGPROC:
+ case TIFFTAG_JPEGRESTARTINTERVAL:
+ return 1;
+ }
+ break;
+ case COMPRESSION_CCITTRLE:
+ case COMPRESSION_CCITTRLEW:
+ case COMPRESSION_CCITTFAX3:
+ case COMPRESSION_CCITTFAX4:
+ switch (tag)
+ {
+ case TIFFTAG_BADFAXLINES:
+ case TIFFTAG_CLEANFAXDATA:
+ case TIFFTAG_CONSECUTIVEBADFAXLINES:
+ return 1;
+ case TIFFTAG_GROUP3OPTIONS:
+ if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX3)
+ return 1;
+ break;
+ case TIFFTAG_GROUP4OPTIONS:
+ if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4)
+ return 1;
+ break;
+ }
+ break;
+ case COMPRESSION_JBIG:
+ /* No codec-specific tags */
+ break;
+ case COMPRESSION_DEFLATE:
+ case COMPRESSION_ADOBE_DEFLATE:
+ if (tag == TIFFTAG_PREDICTOR)
+ return 1;
+ break;
+ case COMPRESSION_PIXARLOG:
+ if (tag == TIFFTAG_PREDICTOR)
+ return 1;
+ break;
+ case COMPRESSION_SGILOG:
+ case COMPRESSION_SGILOG24:
+ /* No codec-specific tags */
+ break;
+ case COMPRESSION_LZMA:
+ if (tag == TIFFTAG_PREDICTOR)
+ return 1;
+ break;
+ case COMPRESSION_ZSTD:
+ if (tag == TIFFTAG_PREDICTOR)
+ return 1;
+ break;
+ case COMPRESSION_LERC:
+ if (tag == TIFFTAG_LERC_PARAMETERS)
+ return 1;
+ break;
+ }
+ return 0;
+}
diff --git a/contrib/libs/libtiff/tif_dirread.c b/contrib/libs/libtiff/tif_dirread.c
new file mode 100644
index 0000000000..abdc772b86
--- /dev/null
+++ b/contrib/libs/libtiff/tif_dirread.c
@@ -0,0 +1,7894 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Directory Read Support Routines.
+ */
+
+/* Suggested pending improvements:
+ * - add a field 'field_info' to the TIFFDirEntry structure, and set that with
+ * the pointer to the appropriate TIFFField structure early on in
+ * TIFFReadDirectory, so as to eliminate current possibly repetitive lookup.
+ */
+
+#include "tiffconf.h"
+#include "tiffiop.h"
+#include <float.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define FAILED_FII ((uint32_t)-1)
+
+#ifdef HAVE_IEEEFP
+#define TIFFCvtIEEEFloatToNative(tif, n, fp)
+#define TIFFCvtIEEEDoubleToNative(tif, n, dp)
+#else
+extern void TIFFCvtIEEEFloatToNative(TIFF *, uint32_t, float *);
+extern void TIFFCvtIEEEDoubleToNative(TIFF *, uint32_t, double *);
+#endif
+
+enum TIFFReadDirEntryErr
+{
+ TIFFReadDirEntryErrOk = 0,
+ TIFFReadDirEntryErrCount = 1,
+ TIFFReadDirEntryErrType = 2,
+ TIFFReadDirEntryErrIo = 3,
+ TIFFReadDirEntryErrRange = 4,
+ TIFFReadDirEntryErrPsdif = 5,
+ TIFFReadDirEntryErrSizesan = 6,
+ TIFFReadDirEntryErrAlloc = 7,
+};
+
+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);
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t *count,
+ uint32_t desttypesize, void **value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryByteArray(TIFF *tif, TIFFDirEntry *direntry, uint8_t **value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntrySbyteArray(TIFF *tif, TIFFDirEntry *direntry, int8_t **value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryShortArray(TIFF *tif, TIFFDirEntry *direntry, uint16_t **value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntrySshortArray(TIFF *tif, TIFFDirEntry *direntry, int16_t **value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntrySlongArray(TIFF *tif, TIFFDirEntry *direntry, int32_t **value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryLong8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntrySlong8Array(TIFF *tif, TIFFDirEntry *direntry, int64_t **value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryFloatArray(TIFF *tif, TIFFDirEntry *direntry, float **value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryDoubleArray(TIFF *tif, TIFFDirEntry *direntry, double **value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryIfd8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value);
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryPersampleShort(TIFF *tif, TIFFDirEntry *direntry,
+ uint16_t *value);
+
+static void TIFFReadDirEntryCheckedByte(TIFF *tif, TIFFDirEntry *direntry,
+ uint8_t *value);
+static void TIFFReadDirEntryCheckedSbyte(TIFF *tif, TIFFDirEntry *direntry,
+ int8_t *value);
+static void TIFFReadDirEntryCheckedShort(TIFF *tif, TIFFDirEntry *direntry,
+ uint16_t *value);
+static void TIFFReadDirEntryCheckedSshort(TIFF *tif, TIFFDirEntry *direntry,
+ int16_t *value);
+static void TIFFReadDirEntryCheckedLong(TIFF *tif, TIFFDirEntry *direntry,
+ uint32_t *value);
+static void TIFFReadDirEntryCheckedSlong(TIFF *tif, TIFFDirEntry *direntry,
+ int32_t *value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckedLong8(TIFF *tif, TIFFDirEntry *direntry,
+ uint64_t *value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckedSlong8(TIFF *tif, TIFFDirEntry *direntry,
+ int64_t *value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckedRational(TIFF *tif, TIFFDirEntry *direntry,
+ double *value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckedSrational(TIFF *tif, TIFFDirEntry *direntry,
+ double *value);
+static void TIFFReadDirEntryCheckedFloat(TIFF *tif, TIFFDirEntry *direntry,
+ float *value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckedDouble(TIFF *tif, TIFFDirEntry *direntry, double *value);
+#if 0
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckedRationalDirect(TIFF *tif, TIFFDirEntry *direntry,
+ TIFFRational_t *value);
+#endif
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeByteSbyte(int8_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeByteShort(uint16_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeByteSshort(int16_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeByteLong(uint32_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeByteSlong(int32_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeByteLong8(uint64_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeByteSlong8(int64_t value);
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSbyteByte(uint8_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSbyteShort(uint16_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSbyteSshort(int16_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSbyteLong(uint32_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSbyteSlong(int32_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSbyteLong8(uint64_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSbyteSlong8(int64_t value);
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeShortSbyte(int8_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeShortSshort(int16_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeShortLong(uint32_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeShortSlong(int32_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeShortLong8(uint64_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeShortSlong8(int64_t value);
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSshortShort(uint16_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSshortLong(uint32_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSshortSlong(int32_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSshortLong8(uint64_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSshortSlong8(int64_t value);
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLongSbyte(int8_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLongSshort(int16_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLongSlong(int32_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLongLong8(uint64_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLongSlong8(int64_t value);
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSlongLong(uint32_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSlongLong8(uint64_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSlongSlong8(int64_t value);
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLong8Sbyte(int8_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLong8Sshort(int16_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLong8Slong(int32_t value);
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLong8Slong8(int64_t value);
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSlong8Long8(uint64_t value);
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF *tif, uint64_t offset,
+ tmsize_t size, void *dest);
+static void TIFFReadDirEntryOutputErr(TIFF *tif, enum TIFFReadDirEntryErr err,
+ const char *module, const char *tagname,
+ int recover);
+
+static void TIFFReadDirectoryCheckOrder(TIFF *tif, TIFFDirEntry *dir,
+ uint16_t dircount);
+static TIFFDirEntry *TIFFReadDirectoryFindEntry(TIFF *tif, TIFFDirEntry *dir,
+ uint16_t dircount,
+ uint16_t tagid);
+static void TIFFReadDirectoryFindFieldInfo(TIFF *tif, uint16_t tagid,
+ uint32_t *fii);
+
+static int EstimateStripByteCounts(TIFF *tif, TIFFDirEntry *dir,
+ uint16_t dircount);
+static void MissingRequired(TIFF *, const char *);
+static int CheckDirCount(TIFF *, TIFFDirEntry *, uint32_t);
+static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff,
+ TIFFDirEntry **pdir, uint64_t *nextdiroff);
+static int TIFFFetchNormalTag(TIFF *, TIFFDirEntry *, int recover);
+static int TIFFFetchStripThing(TIFF *tif, TIFFDirEntry *dir, uint32_t nstrips,
+ uint64_t **lpp);
+static int TIFFFetchSubjectDistance(TIFF *, TIFFDirEntry *);
+static void ChopUpSingleUncompressedStrip(TIFF *);
+static void TryChopUpUncompressedBigTiff(TIFF *);
+static uint64_t TIFFReadUInt64(const uint8_t *value);
+static int _TIFFGetMaxColorChannels(uint16_t photometric);
+
+static int _TIFFFillStrilesInternal(TIFF *tif, int loadStripByteCount);
+
+typedef union _UInt64Aligned_t
+{
+ double d;
+ uint64_t l;
+ uint32_t i[2];
+ uint16_t s[4];
+ uint8_t c[8];
+} UInt64Aligned_t;
+
+/*
+ Unaligned safe copy of a uint64_t value from an octet array.
+*/
+static uint64_t TIFFReadUInt64(const uint8_t *value)
+{
+ UInt64Aligned_t result;
+
+ result.c[0] = value[0];
+ result.c[1] = value[1];
+ result.c[2] = value[2];
+ result.c[3] = value[3];
+ result.c[4] = value[4];
+ result.c[5] = value[5];
+ result.c[6] = value[6];
+ result.c[7] = value[7];
+
+ return result.l;
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryByte(TIFF *tif, TIFFDirEntry *direntry, uint8_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 */
+ TIFFReadDirEntryCheckedByte(tif, direntry, value);
+ return (TIFFReadDirEntryErrOk);
+ case TIFF_SBYTE:
+ {
+ int8_t m;
+ TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
+ err = TIFFReadDirEntryCheckRangeByteSbyte(m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ *value = (uint8_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SHORT:
+ {
+ uint16_t m;
+ TIFFReadDirEntryCheckedShort(tif, direntry, &m);
+ err = TIFFReadDirEntryCheckRangeByteShort(m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ *value = (uint8_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SSHORT:
+ {
+ int16_t m;
+ TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
+ err = TIFFReadDirEntryCheckRangeByteSshort(m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ *value = (uint8_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_LONG:
+ {
+ uint32_t m;
+ TIFFReadDirEntryCheckedLong(tif, direntry, &m);
+ err = TIFFReadDirEntryCheckRangeByteLong(m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ *value = (uint8_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SLONG:
+ {
+ int32_t m;
+ TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
+ err = TIFFReadDirEntryCheckRangeByteSlong(m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ *value = (uint8_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_LONG8:
+ {
+ uint64_t m;
+ err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ err = TIFFReadDirEntryCheckRangeByteLong8(m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ *value = (uint8_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SLONG8:
+ {
+ int64_t m;
+ err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ err = TIFFReadDirEntryCheckRangeByteSlong8(m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ *value = (uint8_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ default:
+ return (TIFFReadDirEntryErrType);
+ }
+}
+
+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;
+ if (direntry->tdir_count != 1)
+ return (TIFFReadDirEntryErrCount);
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ {
+ uint8_t m;
+ TIFFReadDirEntryCheckedByte(tif, direntry, &m);
+ *value = (uint16_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SBYTE:
+ {
+ int8_t m;
+ TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
+ err = TIFFReadDirEntryCheckRangeShortSbyte(m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ *value = (uint16_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SHORT:
+ TIFFReadDirEntryCheckedShort(tif, direntry, value);
+ return (TIFFReadDirEntryErrOk);
+ case TIFF_SSHORT:
+ {
+ int16_t m;
+ TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
+ err = TIFFReadDirEntryCheckRangeShortSshort(m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ *value = (uint16_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_LONG:
+ {
+ uint32_t m;
+ TIFFReadDirEntryCheckedLong(tif, direntry, &m);
+ err = TIFFReadDirEntryCheckRangeShortLong(m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ *value = (uint16_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SLONG:
+ {
+ int32_t m;
+ TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
+ err = TIFFReadDirEntryCheckRangeShortSlong(m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ *value = (uint16_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_LONG8:
+ {
+ uint64_t m;
+ err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ err = TIFFReadDirEntryCheckRangeShortLong8(m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ *value = (uint16_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SLONG8:
+ {
+ int64_t m;
+ err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ err = TIFFReadDirEntryCheckRangeShortSlong8(m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ *value = (uint16_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ 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)
+{
+ 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 = (uint32_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SBYTE:
+ {
+ int8_t m;
+ TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
+ err = TIFFReadDirEntryCheckRangeLongSbyte(m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ *value = (uint32_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SHORT:
+ {
+ uint16_t m;
+ TIFFReadDirEntryCheckedShort(tif, direntry, &m);
+ *value = (uint32_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SSHORT:
+ {
+ int16_t m;
+ TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
+ err = TIFFReadDirEntryCheckRangeLongSshort(m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ *value = (uint32_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_LONG:
+ TIFFReadDirEntryCheckedLong(tif, direntry, value);
+ return (TIFFReadDirEntryErrOk);
+ case TIFF_SLONG:
+ {
+ int32_t m;
+ TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
+ err = TIFFReadDirEntryCheckRangeLongSlong(m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ *value = (uint32_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_LONG8:
+ {
+ uint64_t m;
+ err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ err = TIFFReadDirEntryCheckRangeLongLong8(m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ *value = (uint32_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SLONG8:
+ {
+ int64_t m;
+ err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ err = TIFFReadDirEntryCheckRangeLongSlong8(m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ *value = (uint32_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ 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)
+{
+ 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 = (uint64_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SBYTE:
+ {
+ int8_t m;
+ TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
+ err = TIFFReadDirEntryCheckRangeLong8Sbyte(m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ *value = (uint64_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SHORT:
+ {
+ uint16_t m;
+ TIFFReadDirEntryCheckedShort(tif, direntry, &m);
+ *value = (uint64_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SSHORT:
+ {
+ int16_t m;
+ TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
+ err = TIFFReadDirEntryCheckRangeLong8Sshort(m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ *value = (uint64_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_LONG:
+ {
+ uint32_t m;
+ TIFFReadDirEntryCheckedLong(tif, direntry, &m);
+ *value = (uint64_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SLONG:
+ {
+ int32_t m;
+ TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
+ err = TIFFReadDirEntryCheckRangeLong8Slong(m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ *value = (uint64_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_LONG8:
+ err = TIFFReadDirEntryCheckedLong8(tif, direntry, value);
+ return (err);
+ case TIFF_SLONG8:
+ {
+ int64_t m;
+ err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ err = TIFFReadDirEntryCheckRangeLong8Slong8(m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ *value = (uint64_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ 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)
+{
+ 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 = (float)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SBYTE:
+ {
+ int8_t m;
+ TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
+ *value = (float)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SHORT:
+ {
+ uint16_t m;
+ TIFFReadDirEntryCheckedShort(tif, direntry, &m);
+ *value = (float)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SSHORT:
+ {
+ int16_t m;
+ TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
+ *value = (float)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_LONG:
+ {
+ uint32_t m;
+ TIFFReadDirEntryCheckedLong(tif, direntry, &m);
+ *value = (float)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SLONG:
+ {
+ int32_t m;
+ TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
+ *value = (float)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_LONG8:
+ {
+ uint64_t m;
+ err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+#if defined(__WIN32__) && (_MSC_VER < 1500)
+ /*
+ * XXX: MSVC 6.0 does not support conversion
+ * of 64-bit integers into floating point
+ * values.
+ */
+ *value = _TIFFUInt64ToFloat(m);
+#else
+ *value = (float)m;
+#endif
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SLONG8:
+ {
+ int64_t m;
+ err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ *value = (float)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_RATIONAL:
+ {
+ double m;
+ err = TIFFReadDirEntryCheckedRational(tif, direntry, &m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ *value = (float)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SRATIONAL:
+ {
+ double m;
+ err = TIFFReadDirEntryCheckedSrational(tif, direntry, &m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ *value = (float)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_FLOAT:
+ TIFFReadDirEntryCheckedFloat(tif, direntry, value);
+ return (TIFFReadDirEntryErrOk);
+ case TIFF_DOUBLE:
+ {
+ double m;
+ err = TIFFReadDirEntryCheckedDouble(tif, direntry, &m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ if ((m > FLT_MAX) || (m < -FLT_MAX))
+ return (TIFFReadDirEntryErrRange);
+ *value = (float)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ default:
+ return (TIFFReadDirEntryErrType);
+ }
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryDouble(TIFF *tif, TIFFDirEntry *direntry, double *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 = (double)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SBYTE:
+ {
+ int8_t m;
+ TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
+ *value = (double)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SHORT:
+ {
+ uint16_t m;
+ TIFFReadDirEntryCheckedShort(tif, direntry, &m);
+ *value = (double)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SSHORT:
+ {
+ int16_t m;
+ TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
+ *value = (double)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_LONG:
+ {
+ uint32_t m;
+ TIFFReadDirEntryCheckedLong(tif, direntry, &m);
+ *value = (double)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SLONG:
+ {
+ int32_t m;
+ TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
+ *value = (double)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_LONG8:
+ {
+ uint64_t m;
+ err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+#if defined(__WIN32__) && (_MSC_VER < 1500)
+ /*
+ * XXX: MSVC 6.0 does not support conversion
+ * of 64-bit integers into floating point
+ * values.
+ */
+ *value = _TIFFUInt64ToDouble(m);
+#else
+ *value = (double)m;
+#endif
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SLONG8:
+ {
+ int64_t m;
+ err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ *value = (double)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_RATIONAL:
+ err = TIFFReadDirEntryCheckedRational(tif, direntry, value);
+ return (err);
+ case TIFF_SRATIONAL:
+ err = TIFFReadDirEntryCheckedSrational(tif, direntry, value);
+ return (err);
+ case TIFF_FLOAT:
+ {
+ float m;
+ TIFFReadDirEntryCheckedFloat(tif, direntry, &m);
+ *value = (double)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_DOUBLE:
+ err = TIFFReadDirEntryCheckedDouble(tif, direntry, value);
+ return (err);
+ default:
+ return (TIFFReadDirEntryErrType);
+ }
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryIfd8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value)
+{
+ enum TIFFReadDirEntryErr err;
+ if (direntry->tdir_count != 1)
+ return (TIFFReadDirEntryErrCount);
+ switch (direntry->tdir_type)
+ {
+ case TIFF_LONG:
+ case TIFF_IFD:
+ {
+ uint32_t m;
+ TIFFReadDirEntryCheckedLong(tif, direntry, &m);
+ *value = (uint64_t)m;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_LONG8:
+ case TIFF_IFD8:
+ err = TIFFReadDirEntryCheckedLong8(tif, direntry, value);
+ return (err);
+ default:
+ return (TIFFReadDirEntryErrType);
+ }
+}
+
+#define INITIAL_THRESHOLD (1024 * 1024)
+#define THRESHOLD_MULTIPLIER 10
+#define MAX_THRESHOLD \
+ (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * \
+ INITIAL_THRESHOLD)
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryDataAndRealloc(TIFF *tif,
+ uint64_t offset,
+ tmsize_t size,
+ void **pdest)
+{
+#if SIZEOF_SIZE_T == 8
+ tmsize_t threshold = INITIAL_THRESHOLD;
+#endif
+ tmsize_t already_read = 0;
+
+ assert(!isMapped(tif));
+
+ if (!SeekOK(tif, offset))
+ return (TIFFReadDirEntryErrIo);
+
+ /* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */
+ /* so as to avoid allocating too much memory in case the file is too */
+ /* short. We could ask for the file size, but this might be */
+ /* expensive with some I/O layers (think of reading a gzipped file) */
+ /* Restrict to 64 bit processes, so as to avoid reallocs() */
+ /* on 32 bit processes where virtual memory is scarce. */
+ while (already_read < size)
+ {
+ void *new_dest;
+ tmsize_t bytes_read;
+ tmsize_t to_read = size - already_read;
+#if SIZEOF_SIZE_T == 8
+ if (to_read >= threshold && threshold < MAX_THRESHOLD)
+ {
+ to_read = threshold;
+ threshold *= THRESHOLD_MULTIPLIER;
+ }
+#endif
+
+ new_dest =
+ (uint8_t *)_TIFFreallocExt(tif, *pdest, already_read + to_read);
+ if (new_dest == NULL)
+ {
+ TIFFErrorExtR(tif, tif->tif_name,
+ "Failed to allocate memory for %s "
+ "(%" TIFF_SSIZE_FORMAT
+ " elements of %" TIFF_SSIZE_FORMAT " bytes each)",
+ "TIFFReadDirEntryArray", (tmsize_t)1,
+ already_read + to_read);
+ return TIFFReadDirEntryErrAlloc;
+ }
+ *pdest = new_dest;
+
+ bytes_read = TIFFReadFile(tif, (char *)*pdest + already_read, to_read);
+ already_read += bytes_read;
+ if (bytes_read != to_read)
+ {
+ return TIFFReadDirEntryErrIo;
+ }
+ }
+ 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)
+{
+ int typesize;
+ uint32_t datasize;
+ void *data;
+ uint64_t target_count64;
+ int original_datasize_clamped;
+ typesize = TIFFDataWidth(direntry->tdir_type);
+
+ target_count64 =
+ (direntry->tdir_count > maxcount) ? maxcount : direntry->tdir_count;
+
+ if ((target_count64 == 0) || (typesize == 0))
+ {
+ *value = 0;
+ return (TIFFReadDirEntryErrOk);
+ }
+ (void)desttypesize;
+
+ /* We just want to know if the original tag size is more than 4 bytes
+ * (classic TIFF) or 8 bytes (BigTIFF)
+ */
+ original_datasize_clamped =
+ ((direntry->tdir_count > 10) ? 10 : (int)direntry->tdir_count) *
+ typesize;
+
+ /*
+ * As a sanity check, make sure we have no more than a 2GB tag array
+ * 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)(MAX_SIZE_TAG_DATA / typesize) < target_count64)
+ return (TIFFReadDirEntryErrSizesan);
+ if ((uint64_t)(MAX_SIZE_TAG_DATA / desttypesize) < target_count64)
+ return (TIFFReadDirEntryErrSizesan);
+
+ *count = (uint32_t)target_count64;
+ datasize = (*count) * typesize;
+ assert((tmsize_t)datasize > 0);
+
+ if (isMapped(tif) && datasize > (uint64_t)tif->tif_size)
+ return TIFFReadDirEntryErrIo;
+
+ if (!isMapped(tif) && (((tif->tif_flags & TIFF_BIGTIFF) && datasize > 8) ||
+ (!(tif->tif_flags & TIFF_BIGTIFF) && datasize > 4)))
+ {
+ data = NULL;
+ }
+ else
+ {
+ data = _TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray");
+ if (data == 0)
+ return (TIFFReadDirEntryErrAlloc);
+ }
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ /* Only the condition on original_datasize_clamped. The second
+ * one is implied, but Coverity Scan cannot see it. */
+ if (original_datasize_clamped <= 4 && datasize <= 4)
+ _TIFFmemcpy(data, &direntry->tdir_offset, datasize);
+ else
+ {
+ enum TIFFReadDirEntryErr err;
+ uint32_t offset = direntry->tdir_offset.toff_long;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&offset);
+ if (isMapped(tif))
+ err = TIFFReadDirEntryData(tif, (uint64_t)offset,
+ (tmsize_t)datasize, data);
+ else
+ err = TIFFReadDirEntryDataAndRealloc(tif, (uint64_t)offset,
+ (tmsize_t)datasize, &data);
+ if (err != TIFFReadDirEntryErrOk)
+ {
+ _TIFFfreeExt(tif, data);
+ return (err);
+ }
+ }
+ }
+ else
+ {
+ /* See above comment for the Classic TIFF case */
+ if (original_datasize_clamped <= 8 && datasize <= 8)
+ _TIFFmemcpy(data, &direntry->tdir_offset, datasize);
+ else
+ {
+ enum TIFFReadDirEntryErr err;
+ uint64_t offset = direntry->tdir_offset.toff_long8;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&offset);
+ if (isMapped(tif))
+ err = TIFFReadDirEntryData(tif, (uint64_t)offset,
+ (tmsize_t)datasize, data);
+ else
+ err = TIFFReadDirEntryDataAndRealloc(tif, (uint64_t)offset,
+ (tmsize_t)datasize, &data);
+ if (err != TIFFReadDirEntryErrOk)
+ {
+ _TIFFfreeExt(tif, data);
+ return (err);
+ }
+ }
+ }
+ *value = data;
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t *count,
+ uint32_t desttypesize, void **value)
+{
+ return TIFFReadDirEntryArrayWithLimit(tif, direntry, count, desttypesize,
+ value, ~((uint64_t)0));
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryByteArray(TIFF *tif, TIFFDirEntry *direntry, uint8_t **value)
+{
+ enum TIFFReadDirEntryErr err;
+ uint32_t count;
+ void *origdata;
+ uint8_t *data;
+ switch (direntry->tdir_type)
+ {
+ case TIFF_ASCII:
+ case TIFF_UNDEFINED:
+ case TIFF_BYTE:
+ case TIFF_SBYTE:
+ case TIFF_SHORT:
+ case TIFF_SSHORT:
+ case TIFF_LONG:
+ case TIFF_SLONG:
+ case TIFF_LONG8:
+ case TIFF_SLONG8:
+ break;
+ default:
+ return (TIFFReadDirEntryErrType);
+ }
+ err = TIFFReadDirEntryArray(tif, direntry, &count, 1, &origdata);
+ if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
+ {
+ *value = 0;
+ return (err);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_ASCII:
+ case TIFF_UNDEFINED:
+ case TIFF_BYTE:
+ *value = (uint8_t *)origdata;
+ return (TIFFReadDirEntryErrOk);
+ case TIFF_SBYTE:
+ {
+ int8_t *m;
+ uint32_t n;
+ m = (int8_t *)origdata;
+ for (n = 0; n < count; n++)
+ {
+ err = TIFFReadDirEntryCheckRangeByteSbyte(*m);
+ if (err != TIFFReadDirEntryErrOk)
+ {
+ _TIFFfreeExt(tif, origdata);
+ return (err);
+ }
+ m++;
+ }
+ *value = (uint8_t *)origdata;
+ return (TIFFReadDirEntryErrOk);
+ }
+ }
+ data = (uint8_t *)_TIFFmallocExt(tif, count);
+ if (data == 0)
+ {
+ _TIFFfreeExt(tif, origdata);
+ return (TIFFReadDirEntryErrAlloc);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_SHORT:
+ {
+ uint16_t *ma;
+ uint8_t *mb;
+ uint32_t n;
+ ma = (uint16_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(ma);
+ err = TIFFReadDirEntryCheckRangeByteShort(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (uint8_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SSHORT:
+ {
+ int16_t *ma;
+ uint8_t *mb;
+ uint32_t n;
+ ma = (int16_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort((uint16_t *)ma);
+ err = TIFFReadDirEntryCheckRangeByteSshort(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (uint8_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG:
+ {
+ uint32_t *ma;
+ uint8_t *mb;
+ uint32_t n;
+ ma = (uint32_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(ma);
+ err = TIFFReadDirEntryCheckRangeByteLong(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (uint8_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG:
+ {
+ int32_t *ma;
+ uint8_t *mb;
+ uint32_t n;
+ ma = (int32_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong((uint32_t *)ma);
+ err = TIFFReadDirEntryCheckRangeByteSlong(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (uint8_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG8:
+ {
+ uint64_t *ma;
+ uint8_t *mb;
+ uint32_t n;
+ ma = (uint64_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(ma);
+ err = TIFFReadDirEntryCheckRangeByteLong8(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (uint8_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG8:
+ {
+ int64_t *ma;
+ uint8_t *mb;
+ uint32_t n;
+ ma = (int64_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8((uint64_t *)ma);
+ err = TIFFReadDirEntryCheckRangeByteSlong8(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (uint8_t)(*ma++);
+ }
+ }
+ break;
+ }
+ _TIFFfreeExt(tif, origdata);
+ if (err != TIFFReadDirEntryErrOk)
+ {
+ _TIFFfreeExt(tif, data);
+ return (err);
+ }
+ *value = data;
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntrySbyteArray(TIFF *tif, TIFFDirEntry *direntry, int8_t **value)
+{
+ enum TIFFReadDirEntryErr err;
+ uint32_t count;
+ void *origdata;
+ int8_t *data;
+ switch (direntry->tdir_type)
+ {
+ case TIFF_UNDEFINED:
+ case TIFF_BYTE:
+ case TIFF_SBYTE:
+ case TIFF_SHORT:
+ case TIFF_SSHORT:
+ case TIFF_LONG:
+ case TIFF_SLONG:
+ case TIFF_LONG8:
+ case TIFF_SLONG8:
+ break;
+ default:
+ return (TIFFReadDirEntryErrType);
+ }
+ err = TIFFReadDirEntryArray(tif, direntry, &count, 1, &origdata);
+ if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
+ {
+ *value = 0;
+ return (err);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_UNDEFINED:
+ case TIFF_BYTE:
+ {
+ uint8_t *m;
+ uint32_t n;
+ m = (uint8_t *)origdata;
+ for (n = 0; n < count; n++)
+ {
+ err = TIFFReadDirEntryCheckRangeSbyteByte(*m);
+ if (err != TIFFReadDirEntryErrOk)
+ {
+ _TIFFfreeExt(tif, origdata);
+ return (err);
+ }
+ m++;
+ }
+ *value = (int8_t *)origdata;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SBYTE:
+ *value = (int8_t *)origdata;
+ return (TIFFReadDirEntryErrOk);
+ }
+ data = (int8_t *)_TIFFmallocExt(tif, count);
+ if (data == 0)
+ {
+ _TIFFfreeExt(tif, origdata);
+ return (TIFFReadDirEntryErrAlloc);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_SHORT:
+ {
+ uint16_t *ma;
+ int8_t *mb;
+ uint32_t n;
+ ma = (uint16_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(ma);
+ err = TIFFReadDirEntryCheckRangeSbyteShort(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (int8_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SSHORT:
+ {
+ int16_t *ma;
+ int8_t *mb;
+ uint32_t n;
+ ma = (int16_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort((uint16_t *)ma);
+ err = TIFFReadDirEntryCheckRangeSbyteSshort(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (int8_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG:
+ {
+ uint32_t *ma;
+ int8_t *mb;
+ uint32_t n;
+ ma = (uint32_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(ma);
+ err = TIFFReadDirEntryCheckRangeSbyteLong(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (int8_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG:
+ {
+ int32_t *ma;
+ int8_t *mb;
+ uint32_t n;
+ ma = (int32_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong((uint32_t *)ma);
+ err = TIFFReadDirEntryCheckRangeSbyteSlong(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (int8_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG8:
+ {
+ uint64_t *ma;
+ int8_t *mb;
+ uint32_t n;
+ ma = (uint64_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(ma);
+ err = TIFFReadDirEntryCheckRangeSbyteLong8(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (int8_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG8:
+ {
+ int64_t *ma;
+ int8_t *mb;
+ uint32_t n;
+ ma = (int64_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8((uint64_t *)ma);
+ err = TIFFReadDirEntryCheckRangeSbyteSlong8(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (int8_t)(*ma++);
+ }
+ }
+ break;
+ }
+ _TIFFfreeExt(tif, origdata);
+ if (err != TIFFReadDirEntryErrOk)
+ {
+ _TIFFfreeExt(tif, data);
+ return (err);
+ }
+ *value = data;
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryShortArray(TIFF *tif, TIFFDirEntry *direntry, uint16_t **value)
+{
+ enum TIFFReadDirEntryErr err;
+ uint32_t count;
+ void *origdata;
+ uint16_t *data;
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ case TIFF_SBYTE:
+ case TIFF_SHORT:
+ case TIFF_SSHORT:
+ case TIFF_LONG:
+ case TIFF_SLONG:
+ case TIFF_LONG8:
+ case TIFF_SLONG8:
+ break;
+ default:
+ return (TIFFReadDirEntryErrType);
+ }
+ err = TIFFReadDirEntryArray(tif, direntry, &count, 2, &origdata);
+ if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
+ {
+ *value = 0;
+ return (err);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_SHORT:
+ *value = (uint16_t *)origdata;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfShort(*value, count);
+ return (TIFFReadDirEntryErrOk);
+ case TIFF_SSHORT:
+ {
+ int16_t *m;
+ uint32_t n;
+ m = (int16_t *)origdata;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort((uint16_t *)m);
+ err = TIFFReadDirEntryCheckRangeShortSshort(*m);
+ if (err != TIFFReadDirEntryErrOk)
+ {
+ _TIFFfreeExt(tif, origdata);
+ return (err);
+ }
+ m++;
+ }
+ *value = (uint16_t *)origdata;
+ return (TIFFReadDirEntryErrOk);
+ }
+ }
+ data = (uint16_t *)_TIFFmallocExt(tif, count * 2);
+ if (data == 0)
+ {
+ _TIFFfreeExt(tif, origdata);
+ return (TIFFReadDirEntryErrAlloc);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ {
+ uint8_t *ma;
+ uint16_t *mb;
+ uint32_t n;
+ ma = (uint8_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ *mb++ = (uint16_t)(*ma++);
+ }
+ break;
+ case TIFF_SBYTE:
+ {
+ int8_t *ma;
+ uint16_t *mb;
+ uint32_t n;
+ ma = (int8_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ err = TIFFReadDirEntryCheckRangeShortSbyte(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (uint16_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG:
+ {
+ uint32_t *ma;
+ uint16_t *mb;
+ uint32_t n;
+ ma = (uint32_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(ma);
+ err = TIFFReadDirEntryCheckRangeShortLong(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (uint16_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG:
+ {
+ int32_t *ma;
+ uint16_t *mb;
+ uint32_t n;
+ ma = (int32_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong((uint32_t *)ma);
+ err = TIFFReadDirEntryCheckRangeShortSlong(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (uint16_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG8:
+ {
+ uint64_t *ma;
+ uint16_t *mb;
+ uint32_t n;
+ ma = (uint64_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(ma);
+ err = TIFFReadDirEntryCheckRangeShortLong8(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (uint16_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG8:
+ {
+ int64_t *ma;
+ uint16_t *mb;
+ uint32_t n;
+ ma = (int64_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8((uint64_t *)ma);
+ err = TIFFReadDirEntryCheckRangeShortSlong8(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (uint16_t)(*ma++);
+ }
+ }
+ break;
+ }
+ _TIFFfreeExt(tif, origdata);
+ if (err != TIFFReadDirEntryErrOk)
+ {
+ _TIFFfreeExt(tif, data);
+ return (err);
+ }
+ *value = data;
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntrySshortArray(TIFF *tif, TIFFDirEntry *direntry, int16_t **value)
+{
+ enum TIFFReadDirEntryErr err;
+ uint32_t count;
+ void *origdata;
+ int16_t *data;
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ case TIFF_SBYTE:
+ case TIFF_SHORT:
+ case TIFF_SSHORT:
+ case TIFF_LONG:
+ case TIFF_SLONG:
+ case TIFF_LONG8:
+ case TIFF_SLONG8:
+ break;
+ default:
+ return (TIFFReadDirEntryErrType);
+ }
+ err = TIFFReadDirEntryArray(tif, direntry, &count, 2, &origdata);
+ if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
+ {
+ *value = 0;
+ return (err);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_SHORT:
+ {
+ uint16_t *m;
+ uint32_t n;
+ m = (uint16_t *)origdata;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(m);
+ err = TIFFReadDirEntryCheckRangeSshortShort(*m);
+ if (err != TIFFReadDirEntryErrOk)
+ {
+ _TIFFfreeExt(tif, origdata);
+ return (err);
+ }
+ m++;
+ }
+ *value = (int16_t *)origdata;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SSHORT:
+ *value = (int16_t *)origdata;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfShort((uint16_t *)(*value), count);
+ return (TIFFReadDirEntryErrOk);
+ }
+ data = (int16_t *)_TIFFmallocExt(tif, count * 2);
+ if (data == 0)
+ {
+ _TIFFfreeExt(tif, origdata);
+ return (TIFFReadDirEntryErrAlloc);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ {
+ uint8_t *ma;
+ int16_t *mb;
+ uint32_t n;
+ ma = (uint8_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ *mb++ = (int16_t)(*ma++);
+ }
+ break;
+ case TIFF_SBYTE:
+ {
+ int8_t *ma;
+ int16_t *mb;
+ uint32_t n;
+ ma = (int8_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ *mb++ = (int16_t)(*ma++);
+ }
+ break;
+ case TIFF_LONG:
+ {
+ uint32_t *ma;
+ int16_t *mb;
+ uint32_t n;
+ ma = (uint32_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(ma);
+ err = TIFFReadDirEntryCheckRangeSshortLong(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (int16_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG:
+ {
+ int32_t *ma;
+ int16_t *mb;
+ uint32_t n;
+ ma = (int32_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong((uint32_t *)ma);
+ err = TIFFReadDirEntryCheckRangeSshortSlong(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (int16_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG8:
+ {
+ uint64_t *ma;
+ int16_t *mb;
+ uint32_t n;
+ ma = (uint64_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(ma);
+ err = TIFFReadDirEntryCheckRangeSshortLong8(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (int16_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG8:
+ {
+ int64_t *ma;
+ int16_t *mb;
+ uint32_t n;
+ ma = (int64_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8((uint64_t *)ma);
+ err = TIFFReadDirEntryCheckRangeSshortSlong8(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (int16_t)(*ma++);
+ }
+ }
+ break;
+ }
+ _TIFFfreeExt(tif, origdata);
+ if (err != TIFFReadDirEntryErrOk)
+ {
+ _TIFFfreeExt(tif, data);
+ return (err);
+ }
+ *value = data;
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value)
+{
+ enum TIFFReadDirEntryErr err;
+ uint32_t count;
+ void *origdata;
+ uint32_t *data;
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ case TIFF_SBYTE:
+ case TIFF_SHORT:
+ case TIFF_SSHORT:
+ case TIFF_LONG:
+ case TIFF_SLONG:
+ case TIFF_LONG8:
+ case TIFF_SLONG8:
+ break;
+ default:
+ return (TIFFReadDirEntryErrType);
+ }
+ err = TIFFReadDirEntryArray(tif, direntry, &count, 4, &origdata);
+ if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
+ {
+ *value = 0;
+ return (err);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_LONG:
+ *value = (uint32_t *)origdata;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfLong(*value, count);
+ return (TIFFReadDirEntryErrOk);
+ case TIFF_SLONG:
+ {
+ int32_t *m;
+ uint32_t n;
+ m = (int32_t *)origdata;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong((uint32_t *)m);
+ err = TIFFReadDirEntryCheckRangeLongSlong(*m);
+ if (err != TIFFReadDirEntryErrOk)
+ {
+ _TIFFfreeExt(tif, origdata);
+ return (err);
+ }
+ m++;
+ }
+ *value = (uint32_t *)origdata;
+ return (TIFFReadDirEntryErrOk);
+ }
+ }
+ data = (uint32_t *)_TIFFmallocExt(tif, count * 4);
+ if (data == 0)
+ {
+ _TIFFfreeExt(tif, origdata);
+ return (TIFFReadDirEntryErrAlloc);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ {
+ uint8_t *ma;
+ uint32_t *mb;
+ uint32_t n;
+ ma = (uint8_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ *mb++ = (uint32_t)(*ma++);
+ }
+ break;
+ case TIFF_SBYTE:
+ {
+ int8_t *ma;
+ uint32_t *mb;
+ uint32_t n;
+ ma = (int8_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ err = TIFFReadDirEntryCheckRangeLongSbyte(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (uint32_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SHORT:
+ {
+ uint16_t *ma;
+ uint32_t *mb;
+ uint32_t n;
+ ma = (uint16_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(ma);
+ *mb++ = (uint32_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SSHORT:
+ {
+ int16_t *ma;
+ uint32_t *mb;
+ uint32_t n;
+ ma = (int16_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort((uint16_t *)ma);
+ err = TIFFReadDirEntryCheckRangeLongSshort(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (uint32_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG8:
+ {
+ uint64_t *ma;
+ uint32_t *mb;
+ uint32_t n;
+ ma = (uint64_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(ma);
+ err = TIFFReadDirEntryCheckRangeLongLong8(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (uint32_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG8:
+ {
+ int64_t *ma;
+ uint32_t *mb;
+ uint32_t n;
+ ma = (int64_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8((uint64_t *)ma);
+ err = TIFFReadDirEntryCheckRangeLongSlong8(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (uint32_t)(*ma++);
+ }
+ }
+ break;
+ }
+ _TIFFfreeExt(tif, origdata);
+ if (err != TIFFReadDirEntryErrOk)
+ {
+ _TIFFfreeExt(tif, data);
+ return (err);
+ }
+ *value = data;
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntrySlongArray(TIFF *tif, TIFFDirEntry *direntry, int32_t **value)
+{
+ enum TIFFReadDirEntryErr err;
+ uint32_t count;
+ void *origdata;
+ int32_t *data;
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ case TIFF_SBYTE:
+ case TIFF_SHORT:
+ case TIFF_SSHORT:
+ case TIFF_LONG:
+ case TIFF_SLONG:
+ case TIFF_LONG8:
+ case TIFF_SLONG8:
+ break;
+ default:
+ return (TIFFReadDirEntryErrType);
+ }
+ err = TIFFReadDirEntryArray(tif, direntry, &count, 4, &origdata);
+ if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
+ {
+ *value = 0;
+ return (err);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_LONG:
+ {
+ uint32_t *m;
+ uint32_t n;
+ m = (uint32_t *)origdata;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong((uint32_t *)m);
+ err = TIFFReadDirEntryCheckRangeSlongLong(*m);
+ if (err != TIFFReadDirEntryErrOk)
+ {
+ _TIFFfreeExt(tif, origdata);
+ return (err);
+ }
+ m++;
+ }
+ *value = (int32_t *)origdata;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SLONG:
+ *value = (int32_t *)origdata;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfLong((uint32_t *)(*value), count);
+ return (TIFFReadDirEntryErrOk);
+ }
+ data = (int32_t *)_TIFFmallocExt(tif, count * 4);
+ if (data == 0)
+ {
+ _TIFFfreeExt(tif, origdata);
+ return (TIFFReadDirEntryErrAlloc);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ {
+ uint8_t *ma;
+ int32_t *mb;
+ uint32_t n;
+ ma = (uint8_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ *mb++ = (int32_t)(*ma++);
+ }
+ break;
+ case TIFF_SBYTE:
+ {
+ int8_t *ma;
+ int32_t *mb;
+ uint32_t n;
+ ma = (int8_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ *mb++ = (int32_t)(*ma++);
+ }
+ break;
+ case TIFF_SHORT:
+ {
+ uint16_t *ma;
+ int32_t *mb;
+ uint32_t n;
+ ma = (uint16_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(ma);
+ *mb++ = (int32_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SSHORT:
+ {
+ int16_t *ma;
+ int32_t *mb;
+ uint32_t n;
+ ma = (int16_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort((uint16_t *)ma);
+ *mb++ = (int32_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG8:
+ {
+ uint64_t *ma;
+ int32_t *mb;
+ uint32_t n;
+ ma = (uint64_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(ma);
+ err = TIFFReadDirEntryCheckRangeSlongLong8(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (int32_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG8:
+ {
+ int64_t *ma;
+ int32_t *mb;
+ uint32_t n;
+ ma = (int64_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8((uint64_t *)ma);
+ err = TIFFReadDirEntryCheckRangeSlongSlong8(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (int32_t)(*ma++);
+ }
+ }
+ break;
+ }
+ _TIFFfreeExt(tif, origdata);
+ if (err != TIFFReadDirEntryErrOk)
+ {
+ _TIFFfreeExt(tif, data);
+ return (err);
+ }
+ *value = data;
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryLong8ArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry,
+ uint64_t **value, uint64_t maxcount)
+{
+ enum TIFFReadDirEntryErr err;
+ uint32_t count;
+ void *origdata;
+ uint64_t *data;
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ case TIFF_SBYTE:
+ case TIFF_SHORT:
+ case TIFF_SSHORT:
+ case TIFF_LONG:
+ case TIFF_SLONG:
+ case TIFF_LONG8:
+ case TIFF_SLONG8:
+ break;
+ default:
+ return (TIFFReadDirEntryErrType);
+ }
+ err = TIFFReadDirEntryArrayWithLimit(tif, direntry, &count, 8, &origdata,
+ maxcount);
+ if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
+ {
+ *value = 0;
+ return (err);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_LONG8:
+ *value = (uint64_t *)origdata;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfLong8(*value, count);
+ return (TIFFReadDirEntryErrOk);
+ case TIFF_SLONG8:
+ {
+ int64_t *m;
+ uint32_t n;
+ m = (int64_t *)origdata;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8((uint64_t *)m);
+ err = TIFFReadDirEntryCheckRangeLong8Slong8(*m);
+ if (err != TIFFReadDirEntryErrOk)
+ {
+ _TIFFfreeExt(tif, origdata);
+ return (err);
+ }
+ m++;
+ }
+ *value = (uint64_t *)origdata;
+ return (TIFFReadDirEntryErrOk);
+ }
+ }
+ data = (uint64_t *)_TIFFmallocExt(tif, count * 8);
+ if (data == 0)
+ {
+ _TIFFfreeExt(tif, origdata);
+ return (TIFFReadDirEntryErrAlloc);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ {
+ uint8_t *ma;
+ uint64_t *mb;
+ uint32_t n;
+ ma = (uint8_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ *mb++ = (uint64_t)(*ma++);
+ }
+ break;
+ case TIFF_SBYTE:
+ {
+ int8_t *ma;
+ uint64_t *mb;
+ uint32_t n;
+ ma = (int8_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ err = TIFFReadDirEntryCheckRangeLong8Sbyte(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (uint64_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SHORT:
+ {
+ uint16_t *ma;
+ uint64_t *mb;
+ uint32_t n;
+ ma = (uint16_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(ma);
+ *mb++ = (uint64_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SSHORT:
+ {
+ int16_t *ma;
+ uint64_t *mb;
+ uint32_t n;
+ ma = (int16_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort((uint16_t *)ma);
+ err = TIFFReadDirEntryCheckRangeLong8Sshort(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (uint64_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG:
+ {
+ uint32_t *ma;
+ uint64_t *mb;
+ uint32_t n;
+ ma = (uint32_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(ma);
+ *mb++ = (uint64_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG:
+ {
+ int32_t *ma;
+ uint64_t *mb;
+ uint32_t n;
+ ma = (int32_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong((uint32_t *)ma);
+ err = TIFFReadDirEntryCheckRangeLong8Slong(*ma);
+ if (err != TIFFReadDirEntryErrOk)
+ break;
+ *mb++ = (uint64_t)(*ma++);
+ }
+ }
+ break;
+ }
+ _TIFFfreeExt(tif, origdata);
+ if (err != TIFFReadDirEntryErrOk)
+ {
+ _TIFFfreeExt(tif, data);
+ return (err);
+ }
+ *value = data;
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryLong8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value)
+{
+ return TIFFReadDirEntryLong8ArrayWithLimit(tif, direntry, value,
+ ~((uint64_t)0));
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntrySlong8Array(TIFF *tif, TIFFDirEntry *direntry, int64_t **value)
+{
+ enum TIFFReadDirEntryErr err;
+ uint32_t count;
+ void *origdata;
+ int64_t *data;
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ case TIFF_SBYTE:
+ case TIFF_SHORT:
+ case TIFF_SSHORT:
+ case TIFF_LONG:
+ case TIFF_SLONG:
+ case TIFF_LONG8:
+ case TIFF_SLONG8:
+ break;
+ default:
+ return (TIFFReadDirEntryErrType);
+ }
+ err = TIFFReadDirEntryArray(tif, direntry, &count, 8, &origdata);
+ if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
+ {
+ *value = 0;
+ return (err);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_LONG8:
+ {
+ uint64_t *m;
+ uint32_t n;
+ m = (uint64_t *)origdata;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(m);
+ err = TIFFReadDirEntryCheckRangeSlong8Long8(*m);
+ if (err != TIFFReadDirEntryErrOk)
+ {
+ _TIFFfreeExt(tif, origdata);
+ return (err);
+ }
+ m++;
+ }
+ *value = (int64_t *)origdata;
+ return (TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SLONG8:
+ *value = (int64_t *)origdata;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfLong8((uint64_t *)(*value), count);
+ return (TIFFReadDirEntryErrOk);
+ }
+ data = (int64_t *)_TIFFmallocExt(tif, count * 8);
+ if (data == 0)
+ {
+ _TIFFfreeExt(tif, origdata);
+ return (TIFFReadDirEntryErrAlloc);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ {
+ uint8_t *ma;
+ int64_t *mb;
+ uint32_t n;
+ ma = (uint8_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ *mb++ = (int64_t)(*ma++);
+ }
+ break;
+ case TIFF_SBYTE:
+ {
+ int8_t *ma;
+ int64_t *mb;
+ uint32_t n;
+ ma = (int8_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ *mb++ = (int64_t)(*ma++);
+ }
+ break;
+ case TIFF_SHORT:
+ {
+ uint16_t *ma;
+ int64_t *mb;
+ uint32_t n;
+ ma = (uint16_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(ma);
+ *mb++ = (int64_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SSHORT:
+ {
+ int16_t *ma;
+ int64_t *mb;
+ uint32_t n;
+ ma = (int16_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort((uint16_t *)ma);
+ *mb++ = (int64_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG:
+ {
+ uint32_t *ma;
+ int64_t *mb;
+ uint32_t n;
+ ma = (uint32_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(ma);
+ *mb++ = (int64_t)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG:
+ {
+ int32_t *ma;
+ int64_t *mb;
+ uint32_t n;
+ ma = (int32_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong((uint32_t *)ma);
+ *mb++ = (int64_t)(*ma++);
+ }
+ }
+ break;
+ }
+ _TIFFfreeExt(tif, origdata);
+ *value = data;
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryFloatArray(TIFF *tif, TIFFDirEntry *direntry, float **value)
+{
+ enum TIFFReadDirEntryErr err;
+ uint32_t count;
+ void *origdata;
+ float *data;
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ case TIFF_SBYTE:
+ case TIFF_SHORT:
+ case TIFF_SSHORT:
+ case TIFF_LONG:
+ case TIFF_SLONG:
+ case TIFF_LONG8:
+ case TIFF_SLONG8:
+ case TIFF_RATIONAL:
+ case TIFF_SRATIONAL:
+ case TIFF_FLOAT:
+ case TIFF_DOUBLE:
+ break;
+ default:
+ return (TIFFReadDirEntryErrType);
+ }
+ err = TIFFReadDirEntryArray(tif, direntry, &count, 4, &origdata);
+ if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
+ {
+ *value = 0;
+ return (err);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_FLOAT:
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfLong((uint32_t *)origdata, count);
+ TIFFCvtIEEEDoubleToNative(tif, count, (float *)origdata);
+ *value = (float *)origdata;
+ return (TIFFReadDirEntryErrOk);
+ }
+ data = (float *)_TIFFmallocExt(tif, count * sizeof(float));
+ if (data == 0)
+ {
+ _TIFFfreeExt(tif, origdata);
+ return (TIFFReadDirEntryErrAlloc);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ {
+ uint8_t *ma;
+ float *mb;
+ uint32_t n;
+ ma = (uint8_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ *mb++ = (float)(*ma++);
+ }
+ break;
+ case TIFF_SBYTE:
+ {
+ int8_t *ma;
+ float *mb;
+ uint32_t n;
+ ma = (int8_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ *mb++ = (float)(*ma++);
+ }
+ break;
+ case TIFF_SHORT:
+ {
+ uint16_t *ma;
+ float *mb;
+ uint32_t n;
+ ma = (uint16_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(ma);
+ *mb++ = (float)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SSHORT:
+ {
+ int16_t *ma;
+ float *mb;
+ uint32_t n;
+ ma = (int16_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort((uint16_t *)ma);
+ *mb++ = (float)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG:
+ {
+ uint32_t *ma;
+ float *mb;
+ uint32_t n;
+ ma = (uint32_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(ma);
+ *mb++ = (float)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG:
+ {
+ int32_t *ma;
+ float *mb;
+ uint32_t n;
+ ma = (int32_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong((uint32_t *)ma);
+ *mb++ = (float)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG8:
+ {
+ uint64_t *ma;
+ float *mb;
+ uint32_t n;
+ ma = (uint64_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(ma);
+#if defined(__WIN32__) && (_MSC_VER < 1500)
+ /*
+ * XXX: MSVC 6.0 does not support
+ * conversion of 64-bit integers into
+ * floating point values.
+ */
+ *mb++ = _TIFFUInt64ToFloat(*ma++);
+#else
+ *mb++ = (float)(*ma++);
+#endif
+ }
+ }
+ break;
+ case TIFF_SLONG8:
+ {
+ int64_t *ma;
+ float *mb;
+ uint32_t n;
+ ma = (int64_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8((uint64_t *)ma);
+ *mb++ = (float)(*ma++);
+ }
+ }
+ break;
+ case TIFF_RATIONAL:
+ {
+ uint32_t *ma;
+ uint32_t maa;
+ uint32_t mab;
+ float *mb;
+ uint32_t n;
+ ma = (uint32_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(ma);
+ maa = *ma++;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(ma);
+ mab = *ma++;
+ if (mab == 0)
+ *mb++ = 0.0;
+ else
+ *mb++ = (float)maa / (float)mab;
+ }
+ }
+ break;
+ case TIFF_SRATIONAL:
+ {
+ uint32_t *ma;
+ int32_t maa;
+ uint32_t mab;
+ float *mb;
+ uint32_t n;
+ ma = (uint32_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(ma);
+ maa = *(int32_t *)ma;
+ ma++;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(ma);
+ mab = *ma++;
+ if (mab == 0)
+ *mb++ = 0.0;
+ else
+ *mb++ = (float)maa / (float)mab;
+ }
+ }
+ break;
+ case TIFF_DOUBLE:
+ {
+ double *ma;
+ float *mb;
+ uint32_t n;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfLong8((uint64_t *)origdata, count);
+ TIFFCvtIEEEDoubleToNative(tif, count, (double *)origdata);
+ ma = (double *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ double val = *ma++;
+ if (val > FLT_MAX)
+ val = FLT_MAX;
+ else if (val < -FLT_MAX)
+ val = -FLT_MAX;
+ *mb++ = (float)val;
+ }
+ }
+ break;
+ }
+ _TIFFfreeExt(tif, origdata);
+ *value = data;
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryDoubleArray(TIFF *tif, TIFFDirEntry *direntry, double **value)
+{
+ enum TIFFReadDirEntryErr err;
+ uint32_t count;
+ void *origdata;
+ double *data;
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ case TIFF_SBYTE:
+ case TIFF_SHORT:
+ case TIFF_SSHORT:
+ case TIFF_LONG:
+ case TIFF_SLONG:
+ case TIFF_LONG8:
+ case TIFF_SLONG8:
+ case TIFF_RATIONAL:
+ case TIFF_SRATIONAL:
+ case TIFF_FLOAT:
+ case TIFF_DOUBLE:
+ break;
+ default:
+ return (TIFFReadDirEntryErrType);
+ }
+ err = TIFFReadDirEntryArray(tif, direntry, &count, 8, &origdata);
+ if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
+ {
+ *value = 0;
+ return (err);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_DOUBLE:
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfLong8((uint64_t *)origdata, count);
+ TIFFCvtIEEEDoubleToNative(tif, count, (double *)origdata);
+ *value = (double *)origdata;
+ return (TIFFReadDirEntryErrOk);
+ }
+ data = (double *)_TIFFmallocExt(tif, count * sizeof(double));
+ if (data == 0)
+ {
+ _TIFFfreeExt(tif, origdata);
+ return (TIFFReadDirEntryErrAlloc);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ {
+ uint8_t *ma;
+ double *mb;
+ uint32_t n;
+ ma = (uint8_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ *mb++ = (double)(*ma++);
+ }
+ break;
+ case TIFF_SBYTE:
+ {
+ int8_t *ma;
+ double *mb;
+ uint32_t n;
+ ma = (int8_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ *mb++ = (double)(*ma++);
+ }
+ break;
+ case TIFF_SHORT:
+ {
+ uint16_t *ma;
+ double *mb;
+ uint32_t n;
+ ma = (uint16_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(ma);
+ *mb++ = (double)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SSHORT:
+ {
+ int16_t *ma;
+ double *mb;
+ uint32_t n;
+ ma = (int16_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort((uint16_t *)ma);
+ *mb++ = (double)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG:
+ {
+ uint32_t *ma;
+ double *mb;
+ uint32_t n;
+ ma = (uint32_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(ma);
+ *mb++ = (double)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG:
+ {
+ int32_t *ma;
+ double *mb;
+ uint32_t n;
+ ma = (int32_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong((uint32_t *)ma);
+ *mb++ = (double)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG8:
+ {
+ uint64_t *ma;
+ double *mb;
+ uint32_t n;
+ ma = (uint64_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(ma);
+#if defined(__WIN32__) && (_MSC_VER < 1500)
+ /*
+ * XXX: MSVC 6.0 does not support
+ * conversion of 64-bit integers into
+ * floating point values.
+ */
+ *mb++ = _TIFFUInt64ToDouble(*ma++);
+#else
+ *mb++ = (double)(*ma++);
+#endif
+ }
+ }
+ break;
+ case TIFF_SLONG8:
+ {
+ int64_t *ma;
+ double *mb;
+ uint32_t n;
+ ma = (int64_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8((uint64_t *)ma);
+ *mb++ = (double)(*ma++);
+ }
+ }
+ break;
+ case TIFF_RATIONAL:
+ {
+ uint32_t *ma;
+ uint32_t maa;
+ uint32_t mab;
+ double *mb;
+ uint32_t n;
+ ma = (uint32_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(ma);
+ maa = *ma++;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(ma);
+ mab = *ma++;
+ if (mab == 0)
+ *mb++ = 0.0;
+ else
+ *mb++ = (double)maa / (double)mab;
+ }
+ }
+ break;
+ case TIFF_SRATIONAL:
+ {
+ uint32_t *ma;
+ int32_t maa;
+ uint32_t mab;
+ double *mb;
+ uint32_t n;
+ ma = (uint32_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(ma);
+ maa = *(int32_t *)ma;
+ ma++;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(ma);
+ mab = *ma++;
+ if (mab == 0)
+ *mb++ = 0.0;
+ else
+ *mb++ = (double)maa / (double)mab;
+ }
+ }
+ break;
+ case TIFF_FLOAT:
+ {
+ float *ma;
+ double *mb;
+ uint32_t n;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfLong((uint32_t *)origdata, count);
+ TIFFCvtIEEEFloatToNative(tif, count, (float *)origdata);
+ ma = (float *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ *mb++ = (double)(*ma++);
+ }
+ break;
+ }
+ _TIFFfreeExt(tif, origdata);
+ *value = data;
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryIfd8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value)
+{
+ enum TIFFReadDirEntryErr err;
+ uint32_t count;
+ void *origdata;
+ uint64_t *data;
+ switch (direntry->tdir_type)
+ {
+ case TIFF_LONG:
+ case TIFF_LONG8:
+ case TIFF_IFD:
+ case TIFF_IFD8:
+ break;
+ default:
+ return (TIFFReadDirEntryErrType);
+ }
+ err = TIFFReadDirEntryArray(tif, direntry, &count, 8, &origdata);
+ if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
+ {
+ *value = 0;
+ return (err);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_LONG8:
+ case TIFF_IFD8:
+ *value = (uint64_t *)origdata;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfLong8(*value, count);
+ return (TIFFReadDirEntryErrOk);
+ }
+ data = (uint64_t *)_TIFFmallocExt(tif, count * 8);
+ if (data == 0)
+ {
+ _TIFFfreeExt(tif, origdata);
+ return (TIFFReadDirEntryErrAlloc);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_LONG:
+ case TIFF_IFD:
+ {
+ uint32_t *ma;
+ uint64_t *mb;
+ uint32_t n;
+ ma = (uint32_t *)origdata;
+ mb = data;
+ for (n = 0; n < count; n++)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(ma);
+ *mb++ = (uint64_t)(*ma++);
+ }
+ }
+ break;
+ }
+ _TIFFfreeExt(tif, origdata);
+ *value = data;
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryPersampleShort(TIFF *tif, TIFFDirEntry *direntry,
+ uint16_t *value)
+{
+ enum TIFFReadDirEntryErr err;
+ uint16_t *m;
+ uint16_t *na;
+ uint16_t nb;
+ if (direntry->tdir_count < (uint64_t)tif->tif_dir.td_samplesperpixel)
+ return (TIFFReadDirEntryErrCount);
+ err = TIFFReadDirEntryShortArray(tif, direntry, &m);
+ if (err != TIFFReadDirEntryErrOk || m == NULL)
+ return (err);
+ na = m;
+ nb = tif->tif_dir.td_samplesperpixel;
+ *value = *na++;
+ nb--;
+ while (nb > 0)
+ {
+ if (*na++ != *value)
+ {
+ err = TIFFReadDirEntryErrPsdif;
+ break;
+ }
+ nb--;
+ }
+ _TIFFfreeExt(tif, m);
+ return (err);
+}
+
+static void TIFFReadDirEntryCheckedByte(TIFF *tif, TIFFDirEntry *direntry,
+ uint8_t *value)
+{
+ (void)tif;
+ *value = *(uint8_t *)(&direntry->tdir_offset);
+}
+
+static void TIFFReadDirEntryCheckedSbyte(TIFF *tif, TIFFDirEntry *direntry,
+ int8_t *value)
+{
+ (void)tif;
+ *value = *(int8_t *)(&direntry->tdir_offset);
+}
+
+static void TIFFReadDirEntryCheckedShort(TIFF *tif, TIFFDirEntry *direntry,
+ uint16_t *value)
+{
+ *value = direntry->tdir_offset.toff_short;
+ /* *value=*(uint16_t*)(&direntry->tdir_offset); */
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(value);
+}
+
+static void TIFFReadDirEntryCheckedSshort(TIFF *tif, TIFFDirEntry *direntry,
+ int16_t *value)
+{
+ *value = *(int16_t *)(&direntry->tdir_offset);
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort((uint16_t *)value);
+}
+
+static void TIFFReadDirEntryCheckedLong(TIFF *tif, TIFFDirEntry *direntry,
+ uint32_t *value)
+{
+ *value = *(uint32_t *)(&direntry->tdir_offset);
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(value);
+}
+
+static void TIFFReadDirEntryCheckedSlong(TIFF *tif, TIFFDirEntry *direntry,
+ int32_t *value)
+{
+ *value = *(int32_t *)(&direntry->tdir_offset);
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong((uint32_t *)value);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckedLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value)
+{
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ enum TIFFReadDirEntryErr err;
+ uint32_t offset = direntry->tdir_offset.toff_long;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&offset);
+ err = TIFFReadDirEntryData(tif, offset, 8, value);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ }
+ else
+ *value = direntry->tdir_offset.toff_long8;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(value);
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckedSlong8(TIFF *tif, TIFFDirEntry *direntry, int64_t *value)
+{
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ enum TIFFReadDirEntryErr err;
+ uint32_t offset = direntry->tdir_offset.toff_long;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&offset);
+ err = TIFFReadDirEntryData(tif, offset, 8, value);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ }
+ else
+ *value = *(int64_t *)(&direntry->tdir_offset);
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8((uint64_t *)value);
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckedRational(TIFF *tif, TIFFDirEntry *direntry,
+ double *value)
+{
+ UInt64Aligned_t m;
+
+ assert(sizeof(double) == 8);
+ assert(sizeof(uint64_t) == 8);
+ assert(sizeof(uint32_t) == 4);
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ enum TIFFReadDirEntryErr err;
+ uint32_t offset = direntry->tdir_offset.toff_long;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&offset);
+ err = TIFFReadDirEntryData(tif, offset, 8, m.i);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ }
+ else
+ m.l = direntry->tdir_offset.toff_long8;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfLong(m.i, 2);
+ /* Not completely sure what we should do when m.i[1]==0, but some */
+ /* sanitizers do not like division by 0.0: */
+ /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */
+ if (m.i[0] == 0 || m.i[1] == 0)
+ *value = 0.0;
+ else
+ *value = (double)m.i[0] / (double)m.i[1];
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckedSrational(TIFF *tif, TIFFDirEntry *direntry,
+ double *value)
+{
+ UInt64Aligned_t m;
+ assert(sizeof(double) == 8);
+ assert(sizeof(uint64_t) == 8);
+ assert(sizeof(int32_t) == 4);
+ assert(sizeof(uint32_t) == 4);
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ enum TIFFReadDirEntryErr err;
+ uint32_t offset = direntry->tdir_offset.toff_long;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&offset);
+ err = TIFFReadDirEntryData(tif, offset, 8, m.i);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ }
+ else
+ m.l = direntry->tdir_offset.toff_long8;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfLong(m.i, 2);
+ /* Not completely sure what we should do when m.i[1]==0, but some */
+ /* sanitizers do not like division by 0.0: */
+ /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */
+ if ((int32_t)m.i[0] == 0 || m.i[1] == 0)
+ *value = 0.0;
+ else
+ *value = (double)((int32_t)m.i[0]) / (double)m.i[1];
+ return (TIFFReadDirEntryErrOk);
+}
+
+#if 0
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckedRationalDirect(TIFF *tif, TIFFDirEntry *direntry,
+ TIFFRational_t *value)
+{ /*--: SetGetRATIONAL_directly:_CustomTag: Read rational (and signed rationals)
+ directly --*/
+ UInt64Aligned_t m;
+
+ assert(sizeof(double) == 8);
+ assert(sizeof(uint64_t) == 8);
+ assert(sizeof(uint32_t) == 4);
+
+ if (direntry->tdir_count != 1)
+ return (TIFFReadDirEntryErrCount);
+
+ if (direntry->tdir_type != TIFF_RATIONAL &&
+ direntry->tdir_type != TIFF_SRATIONAL)
+ return (TIFFReadDirEntryErrType);
+
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ enum TIFFReadDirEntryErr err;
+ uint32_t offset = direntry->tdir_offset.toff_long;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&offset);
+ err = TIFFReadDirEntryData(tif, offset, 8, m.i);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ }
+ else
+ {
+ m.l = direntry->tdir_offset.toff_long8;
+ }
+
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfLong(m.i, 2);
+
+ value->uNum = m.i[0];
+ value->uDenom = m.i[1];
+ return (TIFFReadDirEntryErrOk);
+} /*-- TIFFReadDirEntryCheckedRationalDirect() --*/
+#endif
+
+static void TIFFReadDirEntryCheckedFloat(TIFF *tif, TIFFDirEntry *direntry,
+ float *value)
+{
+ union
+ {
+ float f;
+ uint32_t i;
+ } float_union;
+ assert(sizeof(float) == 4);
+ assert(sizeof(uint32_t) == 4);
+ assert(sizeof(float_union) == 4);
+ float_union.i = *(uint32_t *)(&direntry->tdir_offset);
+ *value = float_union.f;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong((uint32_t *)value);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckedDouble(TIFF *tif, TIFFDirEntry *direntry, double *value)
+{
+ assert(sizeof(double) == 8);
+ assert(sizeof(uint64_t) == 8);
+ assert(sizeof(UInt64Aligned_t) == 8);
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ enum TIFFReadDirEntryErr err;
+ uint32_t offset = direntry->tdir_offset.toff_long;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&offset);
+ err = TIFFReadDirEntryData(tif, offset, 8, value);
+ if (err != TIFFReadDirEntryErrOk)
+ return (err);
+ }
+ else
+ {
+ UInt64Aligned_t uint64_union;
+ uint64_union.l = direntry->tdir_offset.toff_long8;
+ *value = uint64_union.d;
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8((uint64_t *)value);
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeByteSbyte(int8_t value)
+{
+ if (value < 0)
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeByteShort(uint16_t value)
+{
+ if (value > 0xFF)
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeByteSshort(int16_t value)
+{
+ if ((value < 0) || (value > 0xFF))
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeByteLong(uint32_t value)
+{
+ if (value > 0xFF)
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeByteSlong(int32_t value)
+{
+ if ((value < 0) || (value > 0xFF))
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeByteLong8(uint64_t value)
+{
+ if (value > 0xFF)
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeByteSlong8(int64_t value)
+{
+ if ((value < 0) || (value > 0xFF))
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSbyteByte(uint8_t value)
+{
+ if (value > 0x7F)
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSbyteShort(uint16_t value)
+{
+ if (value > 0x7F)
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSbyteSshort(int16_t value)
+{
+ if ((value < -0x80) || (value > 0x7F))
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSbyteLong(uint32_t value)
+{
+ if (value > 0x7F)
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSbyteSlong(int32_t value)
+{
+ if ((value < -0x80) || (value > 0x7F))
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSbyteLong8(uint64_t value)
+{
+ if (value > 0x7F)
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSbyteSlong8(int64_t value)
+{
+ if ((value < -0x80) || (value > 0x7F))
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeShortSbyte(int8_t value)
+{
+ if (value < 0)
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeShortSshort(int16_t value)
+{
+ if (value < 0)
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeShortLong(uint32_t value)
+{
+ if (value > 0xFFFF)
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeShortSlong(int32_t value)
+{
+ if ((value < 0) || (value > 0xFFFF))
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeShortLong8(uint64_t value)
+{
+ if (value > 0xFFFF)
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeShortSlong8(int64_t value)
+{
+ if ((value < 0) || (value > 0xFFFF))
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSshortShort(uint16_t value)
+{
+ if (value > 0x7FFF)
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSshortLong(uint32_t value)
+{
+ if (value > 0x7FFF)
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSshortSlong(int32_t value)
+{
+ if ((value < -0x8000) || (value > 0x7FFF))
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSshortLong8(uint64_t value)
+{
+ if (value > 0x7FFF)
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSshortSlong8(int64_t value)
+{
+ if ((value < -0x8000) || (value > 0x7FFF))
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLongSbyte(int8_t value)
+{
+ if (value < 0)
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLongSshort(int16_t value)
+{
+ if (value < 0)
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLongSlong(int32_t value)
+{
+ if (value < 0)
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLongLong8(uint64_t value)
+{
+ if (value > UINT32_MAX)
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLongSlong8(int64_t value)
+{
+ if ((value < 0) || (value > (int64_t)UINT32_MAX))
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSlongLong(uint32_t value)
+{
+ if (value > 0x7FFFFFFFUL)
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+/* Check that the 8-byte unsigned value can fit in a 4-byte unsigned range */
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSlongLong8(uint64_t value)
+{
+ if (value > 0x7FFFFFFF)
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+/* Check that the 8-byte signed value can fit in a 4-byte signed range */
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSlongSlong8(int64_t value)
+{
+ if ((value < 0 - ((int64_t)0x7FFFFFFF + 1)) || (value > 0x7FFFFFFF))
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLong8Sbyte(int8_t value)
+{
+ if (value < 0)
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLong8Sshort(int16_t value)
+{
+ if (value < 0)
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLong8Slong(int32_t value)
+{
+ if (value < 0)
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLong8Slong8(int64_t value)
+{
+ if (value < 0)
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSlong8Long8(uint64_t value)
+{
+ if (value > INT64_MAX)
+ return (TIFFReadDirEntryErrRange);
+ else
+ return (TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF *tif, uint64_t offset,
+ tmsize_t size, void *dest)
+{
+ assert(size > 0);
+ if (!isMapped(tif))
+ {
+ if (!SeekOK(tif, offset))
+ return (TIFFReadDirEntryErrIo);
+ if (!ReadOK(tif, dest, size))
+ return (TIFFReadDirEntryErrIo);
+ }
+ else
+ {
+ size_t ma, mb;
+ ma = (size_t)offset;
+ if ((uint64_t)ma != offset || ma > (~(size_t)0) - (size_t)size)
+ {
+ return TIFFReadDirEntryErrIo;
+ }
+ mb = ma + size;
+ if (mb > (uint64_t)tif->tif_size)
+ return (TIFFReadDirEntryErrIo);
+ _TIFFmemcpy(dest, tif->tif_base + ma, size);
+ }
+ return (TIFFReadDirEntryErrOk);
+}
+
+static void TIFFReadDirEntryOutputErr(TIFF *tif, enum TIFFReadDirEntryErr err,
+ const char *module, const char *tagname,
+ int recover)
+{
+ if (!recover)
+ {
+ switch (err)
+ {
+ case TIFFReadDirEntryErrCount:
+ TIFFErrorExtR(tif, module, "Incorrect count for \"%s\"",
+ tagname);
+ break;
+ case TIFFReadDirEntryErrType:
+ TIFFErrorExtR(tif, module, "Incompatible type for \"%s\"",
+ tagname);
+ break;
+ case TIFFReadDirEntryErrIo:
+ TIFFErrorExtR(tif, module, "IO error during reading of \"%s\"",
+ tagname);
+ break;
+ case TIFFReadDirEntryErrRange:
+ TIFFErrorExtR(tif, module, "Incorrect value for \"%s\"",
+ tagname);
+ break;
+ case TIFFReadDirEntryErrPsdif:
+ TIFFErrorExtR(
+ tif, module,
+ "Cannot handle different values per sample for \"%s\"",
+ tagname);
+ break;
+ case TIFFReadDirEntryErrSizesan:
+ TIFFErrorExtR(tif, module,
+ "Sanity check on size of \"%s\" value failed",
+ tagname);
+ break;
+ case TIFFReadDirEntryErrAlloc:
+ TIFFErrorExtR(tif, module, "Out of memory reading of \"%s\"",
+ tagname);
+ break;
+ default:
+ assert(0); /* we should never get here */
+ break;
+ }
+ }
+ else
+ {
+ switch (err)
+ {
+ case TIFFReadDirEntryErrCount:
+ TIFFWarningExtR(tif, module,
+ "Incorrect count for \"%s\"; tag ignored",
+ tagname);
+ break;
+ case TIFFReadDirEntryErrType:
+ TIFFWarningExtR(tif, module,
+ "Incompatible type for \"%s\"; tag ignored",
+ tagname);
+ break;
+ case TIFFReadDirEntryErrIo:
+ TIFFWarningExtR(
+ tif, module,
+ "IO error during reading of \"%s\"; tag ignored", tagname);
+ break;
+ case TIFFReadDirEntryErrRange:
+ TIFFWarningExtR(tif, module,
+ "Incorrect value for \"%s\"; tag ignored",
+ tagname);
+ break;
+ case TIFFReadDirEntryErrPsdif:
+ TIFFWarningExtR(tif, module,
+ "Cannot handle different values per sample for "
+ "\"%s\"; tag ignored",
+ tagname);
+ break;
+ case TIFFReadDirEntryErrSizesan:
+ TIFFWarningExtR(
+ tif, module,
+ "Sanity check on size of \"%s\" value failed; tag ignored",
+ tagname);
+ break;
+ case TIFFReadDirEntryErrAlloc:
+ TIFFWarningExtR(tif, module,
+ "Out of memory reading of \"%s\"; tag ignored",
+ tagname);
+ break;
+ default:
+ assert(0); /* we should never get here */
+ break;
+ }
+ }
+}
+
+/*
+ * Return the maximum number of color channels specified for a given photometric
+ * type. 0 is returned if photometric type isn't supported or no default value
+ * is defined by the specification.
+ */
+static int _TIFFGetMaxColorChannels(uint16_t photometric)
+{
+ switch (photometric)
+ {
+ case PHOTOMETRIC_PALETTE:
+ case PHOTOMETRIC_MINISWHITE:
+ case PHOTOMETRIC_MINISBLACK:
+ return 1;
+ case PHOTOMETRIC_YCBCR:
+ case PHOTOMETRIC_RGB:
+ case PHOTOMETRIC_CIELAB:
+ case PHOTOMETRIC_LOGLUV:
+ case PHOTOMETRIC_ITULAB:
+ case PHOTOMETRIC_ICCLAB:
+ return 3;
+ case PHOTOMETRIC_SEPARATED:
+ case PHOTOMETRIC_MASK:
+ return 4;
+ case PHOTOMETRIC_LOGL:
+ case PHOTOMETRIC_CFA:
+ default:
+ return 0;
+ }
+}
+
+static int ByteCountLooksBad(TIFF *tif)
+{
+ /*
+ * Assume we have wrong StripByteCount value (in case
+ * of single strip) in following cases:
+ * - it is equal to zero along with StripOffset;
+ * - it is larger than file itself (in case of uncompressed
+ * image);
+ * - it is smaller than the size of the bytes per row
+ * multiplied on the number of rows. The last case should
+ * not be checked in the case of writing new image,
+ * because we may do not know the exact strip size
+ * until the whole image will be written and directory
+ * dumped out.
+ */
+ uint64_t bytecount = TIFFGetStrileByteCount(tif, 0);
+ uint64_t offset = TIFFGetStrileOffset(tif, 0);
+ uint64_t filesize;
+
+ if (offset == 0)
+ return 0;
+ if (bytecount == 0)
+ return 1;
+ if (tif->tif_dir.td_compression != COMPRESSION_NONE)
+ return 0;
+ filesize = TIFFGetFileSize(tif);
+ if (offset <= filesize && bytecount > filesize - offset)
+ return 1;
+ if (tif->tif_mode == O_RDONLY)
+ {
+ uint64_t scanlinesize = TIFFScanlineSize64(tif);
+ if (tif->tif_dir.td_imagelength > 0 &&
+ scanlinesize > UINT64_MAX / tif->tif_dir.td_imagelength)
+ {
+ return 1;
+ }
+ if (bytecount < scanlinesize * tif->tif_dir.td_imagelength)
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Read the next TIFF directory from a file and convert it to the internal
+ * format. We read directories sequentially.
+ */
+int TIFFReadDirectory(TIFF *tif)
+{
+ static const char module[] = "TIFFReadDirectory";
+ TIFFDirEntry *dir;
+ uint16_t dircount;
+ TIFFDirEntry *dp;
+ uint16_t di;
+ const TIFFField *fip;
+ uint32_t fii = FAILED_FII;
+ toff_t nextdiroff;
+ int bitspersample_read = FALSE;
+ int color_channels;
+
+ if (tif->tif_nextdiroff == 0)
+ {
+ /* In this special case, tif_diroff needs also to be set to 0.
+ * This is behind the last IFD, thus no checking or reading necessary.
+ */
+ tif->tif_diroff = tif->tif_nextdiroff;
+ return 0;
+ }
+
+ nextdiroff = tif->tif_nextdiroff;
+ /* tif_curdir++ and tif_nextdiroff should only be updated after SUCCESSFUL
+ * reading of the directory. Otherwise, invalid IFD offsets could corrupt
+ * the IFD list. */
+ if (!_TIFFCheckDirNumberAndOffset(tif,
+ tif->tif_curdir ==
+ TIFF_NON_EXISTENT_DIR_NUMBER
+ ? 0
+ : tif->tif_curdir + 1,
+ nextdiroff))
+ {
+ return 0; /* bad offset (IFD looping or more than TIFF_MAX_DIR_COUNT
+ IFDs) */
+ }
+ dircount = TIFFFetchDirectory(tif, nextdiroff, &dir, &tif->tif_nextdiroff);
+ if (!dircount)
+ {
+ TIFFErrorExtR(tif, module,
+ "Failed to read directory at offset %" PRIu64,
+ nextdiroff);
+ return 0;
+ }
+ /* Set global values after a valid directory has been fetched.
+ * tif_diroff is already set to nextdiroff in TIFFFetchDirectory() in the
+ * beginning. */
+ if (tif->tif_curdir == TIFF_NON_EXISTENT_DIR_NUMBER)
+ tif->tif_curdir = 0;
+ else
+ tif->tif_curdir++;
+ (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */
+
+ TIFFReadDirectoryCheckOrder(tif, dir, dircount);
+
+ /*
+ * Mark duplicates of any tag to be ignored (bugzilla 1994)
+ * to avoid certain pathological problems.
+ */
+ {
+ TIFFDirEntry *ma;
+ uint16_t mb;
+ for (ma = dir, mb = 0; mb < dircount; ma++, mb++)
+ {
+ TIFFDirEntry *na;
+ uint16_t nb;
+ for (na = ma + 1, nb = mb + 1; nb < dircount; na++, nb++)
+ {
+ if (ma->tdir_tag == na->tdir_tag)
+ {
+ na->tdir_ignore = TRUE;
+ }
+ }
+ }
+ }
+
+ tif->tif_flags &= ~TIFF_BEENWRITING; /* reset before new dir */
+ tif->tif_flags &= ~TIFF_BUF4WRITE; /* reset before new dir */
+ tif->tif_flags &= ~TIFF_CHOPPEDUPARRAYS;
+
+ /* free any old stuff and reinit */
+ TIFFFreeDirectory(tif);
+ TIFFDefaultDirectory(tif);
+ /*
+ * Electronic Arts writes gray-scale TIFF files
+ * without a PlanarConfiguration directory entry.
+ * Thus we setup a default value here, even though
+ * the TIFF spec says there is no default value.
+ * After PlanarConfiguration is preset in TIFFDefaultDirectory()
+ * the following setting is not needed, but does not harm either.
+ */
+ TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+ /*
+ * Setup default value and then make a pass over
+ * the fields to check type and tag information,
+ * and to extract info required to size data
+ * structures. A second pass is made afterwards
+ * to read in everything not taken in the first pass.
+ * But we must process the Compression tag first
+ * in order to merge in codec-private tag definitions (otherwise
+ * we may get complaints about unknown tags). However, the
+ * Compression tag may be dependent on the SamplesPerPixel
+ * tag value because older TIFF specs permitted Compression
+ * to be written as a SamplesPerPixel-count tag entry.
+ * Thus if we don't first figure out the correct SamplesPerPixel
+ * tag value then we may end up ignoring the Compression tag
+ * value because it has an incorrect count value (if the
+ * true value of SamplesPerPixel is not 1).
+ */
+ dp =
+ TIFFReadDirectoryFindEntry(tif, dir, dircount, TIFFTAG_SAMPLESPERPIXEL);
+ if (dp)
+ {
+ if (!TIFFFetchNormalTag(tif, dp, 0))
+ goto bad;
+ dp->tdir_ignore = TRUE;
+ }
+ dp = TIFFReadDirectoryFindEntry(tif, dir, dircount, TIFFTAG_COMPRESSION);
+ if (dp)
+ {
+ /*
+ * The 5.0 spec says the Compression tag has one value, while
+ * earlier specs say it has one value per sample. Because of
+ * this, we accept the tag if one value is supplied with either
+ * count.
+ */
+ uint16_t value;
+ enum TIFFReadDirEntryErr err;
+ err = TIFFReadDirEntryShort(tif, dp, &value);
+ if (err == TIFFReadDirEntryErrCount)
+ err = TIFFReadDirEntryPersampleShort(tif, dp, &value);
+ if (err != TIFFReadDirEntryErrOk)
+ {
+ TIFFReadDirEntryOutputErr(tif, err, module, "Compression", 0);
+ goto bad;
+ }
+ if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, value))
+ goto bad;
+ dp->tdir_ignore = TRUE;
+ }
+ else
+ {
+ if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE))
+ goto bad;
+ }
+ /*
+ * First real pass over the directory.
+ */
+ for (di = 0, dp = dir; di < dircount; di++, dp++)
+ {
+ if (!dp->tdir_ignore)
+ {
+ TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii);
+ if (fii == FAILED_FII)
+ {
+ TIFFWarningExtR(tif, module,
+ "Unknown field with tag %" PRIu16 " (0x%" PRIx16
+ ") encountered",
+ dp->tdir_tag, dp->tdir_tag);
+ /* the following knowingly leaks the
+ anonymous field structure */
+ if (!_TIFFMergeFields(
+ tif,
+ _TIFFCreateAnonField(tif, dp->tdir_tag,
+ (TIFFDataType)dp->tdir_type),
+ 1))
+ {
+ TIFFWarningExtR(
+ tif, module,
+ "Registering anonymous field with tag %" PRIu16
+ " (0x%" PRIx16 ") failed",
+ dp->tdir_tag, dp->tdir_tag);
+ dp->tdir_ignore = TRUE;
+ }
+ else
+ {
+ TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii);
+ assert(fii != FAILED_FII);
+ }
+ }
+ }
+ if (!dp->tdir_ignore)
+ {
+ fip = tif->tif_fields[fii];
+ if (fip->field_bit == FIELD_IGNORE)
+ dp->tdir_ignore = TRUE;
+ else
+ {
+ switch (dp->tdir_tag)
+ {
+ case TIFFTAG_STRIPOFFSETS:
+ case TIFFTAG_STRIPBYTECOUNTS:
+ case TIFFTAG_TILEOFFSETS:
+ case TIFFTAG_TILEBYTECOUNTS:
+ TIFFSetFieldBit(tif, fip->field_bit);
+ break;
+ case TIFFTAG_IMAGEWIDTH:
+ case TIFFTAG_IMAGELENGTH:
+ case TIFFTAG_IMAGEDEPTH:
+ case TIFFTAG_TILELENGTH:
+ case TIFFTAG_TILEWIDTH:
+ case TIFFTAG_TILEDEPTH:
+ case TIFFTAG_PLANARCONFIG:
+ case TIFFTAG_ROWSPERSTRIP:
+ case TIFFTAG_EXTRASAMPLES:
+ if (!TIFFFetchNormalTag(tif, dp, 0))
+ goto bad;
+ dp->tdir_ignore = TRUE;
+ break;
+ default:
+ if (!_TIFFCheckFieldIsValidForCodec(tif, dp->tdir_tag))
+ dp->tdir_ignore = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ /*
+ * XXX: OJPEG hack.
+ * If a) compression is OJPEG, b) planarconfig tag says it's separate,
+ * c) strip offsets/bytecounts tag are both present and
+ * d) both contain exactly one value, then we consistently find
+ * that the buggy implementation of the buggy compression scheme
+ * matches contig planarconfig best. So we 'fix-up' the tag here
+ */
+ if ((tif->tif_dir.td_compression == COMPRESSION_OJPEG) &&
+ (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE))
+ {
+ if (!_TIFFFillStriles(tif))
+ goto bad;
+ dp = TIFFReadDirectoryFindEntry(tif, dir, dircount,
+ TIFFTAG_STRIPOFFSETS);
+ if ((dp != 0) && (dp->tdir_count == 1))
+ {
+ dp = TIFFReadDirectoryFindEntry(tif, dir, dircount,
+ TIFFTAG_STRIPBYTECOUNTS);
+ if ((dp != 0) && (dp->tdir_count == 1))
+ {
+ tif->tif_dir.td_planarconfig = PLANARCONFIG_CONTIG;
+ TIFFWarningExtR(tif, module,
+ "Planarconfig tag value assumed incorrect, "
+ "assuming data is contig instead of chunky");
+ }
+ }
+ }
+ /*
+ * Allocate directory structure and setup defaults.
+ */
+ if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS))
+ {
+ TIFFWarningExtR(tif, module, "TIFF directory is missing required ImageLength field");
+ }
+
+ /*
+ * Second pass: extract other information.
+ */
+ for (di = 0, dp = dir; di < dircount; di++, dp++)
+ {
+ if (!dp->tdir_ignore)
+ {
+ switch (dp->tdir_tag)
+ {
+ case TIFFTAG_MINSAMPLEVALUE:
+ case TIFFTAG_MAXSAMPLEVALUE:
+ case TIFFTAG_BITSPERSAMPLE:
+ case TIFFTAG_DATATYPE:
+ case TIFFTAG_SAMPLEFORMAT:
+ /*
+ * The MinSampleValue, MaxSampleValue, BitsPerSample
+ * DataType and SampleFormat tags are supposed to be
+ * written as one value/sample, but some vendors
+ * incorrectly write one value only -- so we accept
+ * that as well (yuck). Other vendors write correct
+ * value for NumberOfSamples, but incorrect one for
+ * BitsPerSample and friends, and we will read this
+ * too.
+ */
+ {
+ uint16_t value;
+ enum TIFFReadDirEntryErr err;
+ err = TIFFReadDirEntryShort(tif, dp, &value);
+ if (err == TIFFReadDirEntryErrCount)
+ err =
+ TIFFReadDirEntryPersampleShort(tif, dp, &value);
+ if (err != TIFFReadDirEntryErrOk)
+ {
+ fip = TIFFFieldWithTag(tif, dp->tdir_tag);
+ TIFFReadDirEntryOutputErr(
+ tif, err, module,
+ fip ? fip->field_name : "unknown tagname", 0);
+ goto bad;
+ }
+ if (!TIFFSetField(tif, dp->tdir_tag, value))
+ goto bad;
+ if (dp->tdir_tag == TIFFTAG_BITSPERSAMPLE)
+ bitspersample_read = TRUE;
+ }
+ break;
+ case TIFFTAG_SMINSAMPLEVALUE:
+ case TIFFTAG_SMAXSAMPLEVALUE:
+ {
+
+ double *data = NULL;
+ enum TIFFReadDirEntryErr err;
+ uint32_t saved_flags;
+ int m;
+ if (dp->tdir_count !=
+ (uint64_t)tif->tif_dir.td_samplesperpixel)
+ err = TIFFReadDirEntryErrCount;
+ else
+ err = TIFFReadDirEntryDoubleArray(tif, dp, &data);
+ if (err != TIFFReadDirEntryErrOk)
+ {
+ fip = TIFFFieldWithTag(tif, dp->tdir_tag);
+ TIFFReadDirEntryOutputErr(
+ tif, err, module,
+ fip ? fip->field_name : "unknown tagname", 0);
+ goto bad;
+ }
+ saved_flags = tif->tif_flags;
+ tif->tif_flags |= TIFF_PERSAMPLE;
+ m = TIFFSetField(tif, dp->tdir_tag, data);
+ tif->tif_flags = saved_flags;
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ goto bad;
+ }
+ break;
+ case TIFFTAG_STRIPOFFSETS:
+ case TIFFTAG_TILEOFFSETS:
+ switch (dp->tdir_type)
+ {
+ case TIFF_SHORT:
+ case TIFF_LONG:
+ case TIFF_LONG8:
+ break;
+ default:
+ /* Warn except if directory typically created with
+ * TIFFDeferStrileArrayWriting() */
+ if (!(tif->tif_mode == O_RDWR &&
+ dp->tdir_count == 0 && dp->tdir_type == 0 &&
+ dp->tdir_offset.toff_long8 == 0))
+ {
+ fip = TIFFFieldWithTag(tif, dp->tdir_tag);
+ TIFFWarningExtR(
+ tif, module, "Invalid data type for tag %s",
+ fip ? fip->field_name : "unknown tagname");
+ }
+ break;
+ }
+ _TIFFmemcpy(&(tif->tif_dir.td_stripoffset_entry), dp,
+ sizeof(TIFFDirEntry));
+ break;
+ case TIFFTAG_STRIPBYTECOUNTS:
+ case TIFFTAG_TILEBYTECOUNTS:
+ switch (dp->tdir_type)
+ {
+ case TIFF_SHORT:
+ case TIFF_LONG:
+ case TIFF_LONG8:
+ break;
+ default:
+ /* Warn except if directory typically created with
+ * TIFFDeferStrileArrayWriting() */
+ if (!(tif->tif_mode == O_RDWR &&
+ dp->tdir_count == 0 && dp->tdir_type == 0 &&
+ dp->tdir_offset.toff_long8 == 0))
+ {
+ fip = TIFFFieldWithTag(tif, dp->tdir_tag);
+ TIFFWarningExtR(
+ tif, module, "Invalid data type for tag %s",
+ fip ? fip->field_name : "unknown tagname");
+ }
+ break;
+ }
+ _TIFFmemcpy(&(tif->tif_dir.td_stripbytecount_entry), dp,
+ sizeof(TIFFDirEntry));
+ break;
+ case TIFFTAG_COLORMAP:
+ case TIFFTAG_TRANSFERFUNCTION:
+ {
+ enum TIFFReadDirEntryErr err;
+ uint32_t countpersample;
+ uint32_t countrequired;
+ uint32_t incrementpersample;
+ uint16_t *value = NULL;
+ /* It would be dangerous to instantiate those tag values */
+ /* since if td_bitspersample has not yet been read (due to
+ */
+ /* unordered tags), it could be read afterwards with a */
+ /* values greater than the default one (1), which may cause
+ */
+ /* crashes in user code */
+ if (!bitspersample_read)
+ {
+ fip = TIFFFieldWithTag(tif, dp->tdir_tag);
+ TIFFWarningExtR(
+ tif, module,
+ "Ignoring %s since BitsPerSample tag not found",
+ fip ? fip->field_name : "unknown tagname");
+ continue;
+ }
+ /* ColorMap or TransferFunction for high bit */
+ /* depths do not make much sense and could be */
+ /* used as a denial of service vector */
+ if (tif->tif_dir.td_bitspersample > 24)
+ {
+ fip = TIFFFieldWithTag(tif, dp->tdir_tag);
+ TIFFWarningExtR(
+ tif, module,
+ "Ignoring %s because BitsPerSample=%" PRIu16 ">24",
+ fip ? fip->field_name : "unknown tagname",
+ tif->tif_dir.td_bitspersample);
+ continue;
+ }
+ countpersample = (1U << tif->tif_dir.td_bitspersample);
+ if ((dp->tdir_tag == TIFFTAG_TRANSFERFUNCTION) &&
+ (dp->tdir_count == (uint64_t)countpersample))
+ {
+ countrequired = countpersample;
+ incrementpersample = 0;
+ }
+ else
+ {
+ countrequired = 3 * countpersample;
+ incrementpersample = countpersample;
+ }
+ if (dp->tdir_count != (uint64_t)countrequired)
+ err = TIFFReadDirEntryErrCount;
+ else
+ err = TIFFReadDirEntryShortArray(tif, dp, &value);
+ if (err != TIFFReadDirEntryErrOk)
+ {
+ fip = TIFFFieldWithTag(tif, dp->tdir_tag);
+ TIFFReadDirEntryOutputErr(
+ tif, err, module,
+ fip ? fip->field_name : "unknown tagname", 1);
+ }
+ else
+ {
+ TIFFSetField(tif, dp->tdir_tag, value,
+ value + incrementpersample,
+ value + 2 * incrementpersample);
+ _TIFFfreeExt(tif, value);
+ }
+ }
+ break;
+ /* BEGIN REV 4.0 COMPATIBILITY */
+ case TIFFTAG_OSUBFILETYPE:
+ {
+ uint16_t valueo;
+ uint32_t value;
+ if (TIFFReadDirEntryShort(tif, dp, &valueo) ==
+ TIFFReadDirEntryErrOk)
+ {
+ switch (valueo)
+ {
+ case OFILETYPE_REDUCEDIMAGE:
+ value = FILETYPE_REDUCEDIMAGE;
+ break;
+ case OFILETYPE_PAGE:
+ value = FILETYPE_PAGE;
+ break;
+ default:
+ value = 0;
+ break;
+ }
+ if (value != 0)
+ TIFFSetField(tif, TIFFTAG_SUBFILETYPE, value);
+ }
+ }
+ break;
+ /* END REV 4.0 COMPATIBILITY */
+#if 0
+ case TIFFTAG_EP_BATTERYLEVEL:
+ /* TIFFTAG_EP_BATTERYLEVEL can be RATIONAL or ASCII.
+ * LibTiff defines it as ASCII and converts RATIONAL to an
+ * ASCII string. */
+ switch (dp->tdir_type)
+ {
+ case TIFF_RATIONAL:
+ {
+ /* Read rational and convert to ASCII*/
+ enum TIFFReadDirEntryErr err;
+ TIFFRational_t rValue;
+ err = TIFFReadDirEntryCheckedRationalDirect(
+ tif, dp, &rValue);
+ if (err != TIFFReadDirEntryErrOk)
+ {
+ fip = TIFFFieldWithTag(tif, dp->tdir_tag);
+ TIFFReadDirEntryOutputErr(
+ tif, err, module,
+ fip ? fip->field_name : "unknown tagname",
+ 1);
+ }
+ else
+ {
+ char szAux[32];
+ snprintf(szAux, sizeof(szAux) - 1, "%d/%d",
+ rValue.uNum, rValue.uDenom);
+ TIFFSetField(tif, dp->tdir_tag, szAux);
+ }
+ }
+ break;
+ case TIFF_ASCII:
+ (void)TIFFFetchNormalTag(tif, dp, TRUE);
+ break;
+ default:
+ fip = TIFFFieldWithTag(tif, dp->tdir_tag);
+ TIFFWarningExtR(tif, module,
+ "Invalid data type for tag %s. "
+ "ASCII or RATIONAL expected",
+ fip ? fip->field_name
+ : "unknown tagname");
+ break;
+ }
+ break;
+#endif
+ default:
+ (void)TIFFFetchNormalTag(tif, dp, TRUE);
+ break;
+ }
+ } /* -- if (!dp->tdir_ignore) */
+ } /* -- for-loop -- */
+
+ /*
+ * OJPEG hack:
+ * - If a) compression is OJPEG, and b) photometric tag is missing,
+ * then we consistently find that photometric should be YCbCr
+ * - If a) compression is OJPEG, and b) photometric tag says it's RGB,
+ * then we consistently find that the buggy implementation of the
+ * buggy compression scheme matches photometric YCbCr instead.
+ * - If a) compression is OJPEG, and b) bitspersample tag is missing,
+ * then we consistently find bitspersample should be 8.
+ * - If a) compression is OJPEG, b) samplesperpixel tag is missing,
+ * and c) photometric is RGB or YCbCr, then we consistently find
+ * samplesperpixel should be 3
+ * - If a) compression is OJPEG, b) samplesperpixel tag is missing,
+ * and c) photometric is MINISWHITE or MINISBLACK, then we consistently
+ * find samplesperpixel should be 3
+ */
+ if (tif->tif_dir.td_compression == COMPRESSION_OJPEG)
+ {
+ if (!TIFFFieldSet(tif, FIELD_PHOTOMETRIC))
+ {
+ TIFFWarningExtR(
+ tif, module,
+ "Photometric tag is missing, assuming data is YCbCr");
+ if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR))
+ goto bad;
+ }
+ else if (tif->tif_dir.td_photometric == PHOTOMETRIC_RGB)
+ {
+ tif->tif_dir.td_photometric = PHOTOMETRIC_YCBCR;
+ TIFFWarningExtR(tif, module,
+ "Photometric tag value assumed incorrect, "
+ "assuming data is YCbCr instead of RGB");
+ }
+ if (!TIFFFieldSet(tif, FIELD_BITSPERSAMPLE))
+ {
+ TIFFWarningExtR(
+ tif, module,
+ "BitsPerSample tag is missing, assuming 8 bits per sample");
+ if (!TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8))
+ goto bad;
+ }
+ if (!TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
+ {
+ if (tif->tif_dir.td_photometric == PHOTOMETRIC_RGB)
+ {
+ TIFFWarningExtR(tif, module,
+ "SamplesPerPixel tag is missing, "
+ "assuming correct SamplesPerPixel value is 3");
+ if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3))
+ goto bad;
+ }
+ if (tif->tif_dir.td_photometric == PHOTOMETRIC_YCBCR)
+ {
+ TIFFWarningExtR(tif, module,
+ "SamplesPerPixel tag is missing, "
+ "applying correct SamplesPerPixel value of 3");
+ if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3))
+ goto bad;
+ }
+ else if ((tif->tif_dir.td_photometric == PHOTOMETRIC_MINISWHITE) ||
+ (tif->tif_dir.td_photometric == PHOTOMETRIC_MINISBLACK))
+ {
+ /*
+ * SamplesPerPixel tag is missing, but is not required
+ * by spec. Assume correct SamplesPerPixel value of 1.
+ */
+ if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1))
+ goto bad;
+ }
+ }
+ }
+
+ /*
+ * 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)
+ {
+ TIFFErrorExtR(tif, 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.
+ */
+ color_channels = _TIFFGetMaxColorChannels(tif->tif_dir.td_photometric);
+ if (color_channels &&
+ tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples >
+ color_channels)
+ {
+ uint16_t old_extrasamples;
+ uint16_t *new_sampleinfo;
+
+ TIFFWarningExtR(
+ tif, module,
+ "Sum of Photometric type-related "
+ "color channels and ExtraSamples doesn't match SamplesPerPixel. "
+ "Defining non-color channels as ExtraSamples.");
+
+ old_extrasamples = tif->tif_dir.td_extrasamples;
+ tif->tif_dir.td_extrasamples =
+ (uint16_t)(tif->tif_dir.td_samplesperpixel - color_channels);
+
+ // sampleinfo should contain information relative to these new extra
+ // samples
+ new_sampleinfo = (uint16_t *)_TIFFcallocExt(
+ tif, tif->tif_dir.td_extrasamples, sizeof(uint16_t));
+ if (!new_sampleinfo)
+ {
+ TIFFErrorExtR(tif, module,
+ "Failed to allocate memory for "
+ "temporary new sampleinfo array "
+ "(%" PRIu16 " 16 bit elements)",
+ tif->tif_dir.td_extrasamples);
+ goto bad;
+ }
+
+ if (old_extrasamples > 0)
+ memcpy(new_sampleinfo, tif->tif_dir.td_sampleinfo,
+ old_extrasamples * sizeof(uint16_t));
+ _TIFFsetShortArrayExt(tif, &tif->tif_dir.td_sampleinfo, new_sampleinfo,
+ tif->tif_dir.td_extrasamples);
+ _TIFFfreeExt(tif, new_sampleinfo);
+ }
+
+ /*
+ * Verify Palette image has a Colormap.
+ */
+ if (tif->tif_dir.td_photometric == PHOTOMETRIC_PALETTE &&
+ !TIFFFieldSet(tif, FIELD_COLORMAP))
+ {
+ if (tif->tif_dir.td_bitspersample >= 8 &&
+ tif->tif_dir.td_samplesperpixel == 3)
+ tif->tif_dir.td_photometric = PHOTOMETRIC_RGB;
+ else if (tif->tif_dir.td_bitspersample >= 8)
+ tif->tif_dir.td_photometric = PHOTOMETRIC_MINISBLACK;
+ else
+ {
+ MissingRequired(tif, "Colormap");
+ goto bad;
+ }
+ }
+ /*
+ * OJPEG hack:
+ * We do no further messing with strip/tile offsets/bytecounts in OJPEG
+ * TIFFs
+ */
+ if (tif->tif_dir.td_compression != COMPRESSION_OJPEG)
+ {
+ /*
+ * Attempt to deal with a missing StripByteCounts tag.
+ */
+ if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS))
+ {
+ /*
+ * Some manufacturers violate the spec by not giving
+ * the size of the strips. In this case, assume there
+ * is one uncompressed strip of data.
+ */
+ if ((tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG &&
+ tif->tif_dir.td_nstrips > 1) ||
+ (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE &&
+ tif->tif_dir.td_nstrips !=
+ (uint32_t)tif->tif_dir.td_samplesperpixel))
+ {
+ MissingRequired(tif, "StripByteCounts");
+ goto bad;
+ }
+ TIFFWarningExtR(
+ tif, module,
+ "TIFF directory is missing required "
+ "\"StripByteCounts\" field, calculating from imagelength");
+ if (EstimateStripByteCounts(tif, dir, dircount) < 0)
+ goto bad;
+ }
+ else if (tif->tif_dir.td_nstrips == 1 &&
+ !(tif->tif_flags & TIFF_ISTILED) && ByteCountLooksBad(tif))
+ {
+ /*
+ * XXX: Plexus (and others) sometimes give a value of
+ * zero for a tag when they don't know what the
+ * correct value is! Try and handle the simple case
+ * of estimating the size of a one strip image.
+ */
+ TIFFWarningExtR(tif, module,
+ "Bogus \"StripByteCounts\" field, ignoring and "
+ "calculating from imagelength");
+ if (EstimateStripByteCounts(tif, dir, dircount) < 0)
+ goto bad;
+ }
+ else if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD) &&
+ tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG &&
+ tif->tif_dir.td_nstrips > 2 &&
+ tif->tif_dir.td_compression == COMPRESSION_NONE &&
+ TIFFGetStrileByteCount(tif, 0) !=
+ TIFFGetStrileByteCount(tif, 1) &&
+ TIFFGetStrileByteCount(tif, 0) != 0 &&
+ TIFFGetStrileByteCount(tif, 1) != 0)
+ {
+ /*
+ * XXX: Some vendors fill StripByteCount array with
+ * absolutely wrong values (it can be equal to
+ * StripOffset array, for example). Catch this case
+ * here.
+ *
+ * We avoid this check if deferring strile loading
+ * as it would always force us to load the strip/tile
+ * information.
+ */
+ TIFFWarningExtR(tif, module,
+ "Wrong \"StripByteCounts\" field, ignoring and "
+ "calculating from imagelength");
+ if (EstimateStripByteCounts(tif, dir, dircount) < 0)
+ goto bad;
+ }
+ }
+ if (dir)
+ {
+ _TIFFfreeExt(tif, dir);
+ dir = NULL;
+ }
+ if (!TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE))
+ {
+ if (tif->tif_dir.td_bitspersample >= 16)
+ tif->tif_dir.td_maxsamplevalue = 0xFFFF;
+ else
+ tif->tif_dir.td_maxsamplevalue =
+ (uint16_t)((1L << tif->tif_dir.td_bitspersample) - 1);
+ }
+
+#ifdef STRIPBYTECOUNTSORTED_UNUSED
+ /*
+ * XXX: We can optimize checking for the strip bounds using the sorted
+ * bytecounts array. See also comments for TIFFAppendToStrip()
+ * function in tif_write.c.
+ */
+ if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD) && tif->tif_dir.td_nstrips > 1)
+ {
+ uint32_t strip;
+
+ tif->tif_dir.td_stripbytecountsorted = 1;
+ for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++)
+ {
+ if (TIFFGetStrileOffset(tif, strip - 1) >
+ TIFFGetStrileOffset(tif, strip))
+ {
+ tif->tif_dir.td_stripbytecountsorted = 0;
+ break;
+ }
+ }
+ }
+#endif
+
+ /*
+ * An opportunity for compression mode dependent tag fixup
+ */
+ (*tif->tif_fixuptags)(tif);
+
+ /*
+ * Some manufacturers make life difficult by writing
+ * large amounts of uncompressed data as a single strip.
+ * This is contrary to the recommendations of the spec.
+ * The following makes an attempt at breaking such images
+ * into strips closer to the recommended 8k bytes. A
+ * side effect, however, is that the RowsPerStrip tag
+ * value may be changed.
+ */
+ if ((tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG) &&
+ (tif->tif_dir.td_nstrips == 1) &&
+ (tif->tif_dir.td_compression == COMPRESSION_NONE) &&
+ ((tif->tif_flags & (TIFF_STRIPCHOP | TIFF_ISTILED)) == TIFF_STRIPCHOP))
+ {
+ ChopUpSingleUncompressedStrip(tif);
+ }
+
+ /* There are also uncompressed striped files with strips larger than */
+ /* 2 GB, which make them unfriendly with a lot of code. If possible, */
+ /* try to expose smaller "virtual" strips. */
+ if (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG &&
+ tif->tif_dir.td_compression == COMPRESSION_NONE &&
+ (tif->tif_flags & (TIFF_STRIPCHOP | TIFF_ISTILED)) == TIFF_STRIPCHOP &&
+ TIFFStripSize64(tif) > 0x7FFFFFFFUL)
+ {
+ TryChopUpUncompressedBigTiff(tif);
+ }
+
+ /*
+ * Clear the dirty directory flag.
+ */
+ tif->tif_flags &= ~TIFF_DIRTYDIRECT;
+ tif->tif_flags &= ~TIFF_DIRTYSTRIP;
+
+ /*
+ * Reinitialize i/o since we are starting on a new directory.
+ */
+ tif->tif_row = (uint32_t)-1;
+ tif->tif_curstrip = (uint32_t)-1;
+ tif->tif_col = (uint32_t)-1;
+ tif->tif_curtile = (uint32_t)-1;
+ tif->tif_tilesize = (tmsize_t)-1;
+
+ tif->tif_scanlinesize = TIFFScanlineSize(tif);
+ if (!tif->tif_scanlinesize)
+ {
+ TIFFWarningExtR(tif, module, "Cannot handle zero scanline size");
+ }
+
+ if (isTiled(tif))
+ {
+ tif->tif_tilesize = TIFFTileSize(tif);
+ if (!tif->tif_tilesize)
+ {
+ TIFFWarningExtR(tif, module, "Cannot handle zero tile size");
+ }
+ }
+ else
+ {
+ if (!TIFFStripSize(tif))
+ {
+ TIFFWarningExt(tif, module, "Cannot handle zero strip size");
+ }
+ }
+ return (1);
+bad:
+ if (dir)
+ _TIFFfreeExt(tif, dir);
+ return (0);
+}
+
+static void TIFFReadDirectoryCheckOrder(TIFF *tif, TIFFDirEntry *dir,
+ uint16_t dircount)
+{
+ static const char module[] = "TIFFReadDirectoryCheckOrder";
+ uint16_t m;
+ uint16_t n;
+ TIFFDirEntry *o;
+ m = 0;
+ for (n = 0, o = dir; n < dircount; n++, o++)
+ {
+ if (o->tdir_tag < m)
+ {
+ TIFFWarningExtR(tif, module,
+ "Invalid TIFF directory; tags are not sorted in "
+ "ascending order");
+ break;
+ }
+ m = o->tdir_tag + 1;
+ }
+}
+
+static TIFFDirEntry *TIFFReadDirectoryFindEntry(TIFF *tif, TIFFDirEntry *dir,
+ uint16_t dircount,
+ uint16_t tagid)
+{
+ TIFFDirEntry *m;
+ uint16_t n;
+ (void)tif;
+ for (m = dir, n = 0; n < dircount; m++, n++)
+ {
+ if (m->tdir_tag == tagid)
+ return (m);
+ }
+ return (0);
+}
+
+static void TIFFReadDirectoryFindFieldInfo(TIFF *tif, uint16_t tagid,
+ uint32_t *fii)
+{
+ int32_t ma, mb, mc;
+ ma = -1;
+ mc = (int32_t)tif->tif_nfields;
+ while (1)
+ {
+ if (ma + 1 == mc)
+ {
+ *fii = FAILED_FII;
+ return;
+ }
+ mb = (ma + mc) / 2;
+ if (tif->tif_fields[mb]->field_tag == (uint32_t)tagid)
+ break;
+ if (tif->tif_fields[mb]->field_tag < (uint32_t)tagid)
+ ma = mb;
+ else
+ mc = mb;
+ }
+ while (1)
+ {
+ if (mb == 0)
+ break;
+ if (tif->tif_fields[mb - 1]->field_tag != (uint32_t)tagid)
+ break;
+ mb--;
+ }
+ *fii = mb;
+}
+
+/*
+ * Read custom directory from the arbitrary offset.
+ * The code is very similar to TIFFReadDirectory().
+ */
+int TIFFReadCustomDirectory(TIFF *tif, toff_t diroff,
+ const TIFFFieldArray *infoarray)
+{
+ static const char module[] = "TIFFReadCustomDirectory";
+ TIFFDirEntry *dir;
+ uint16_t dircount;
+ TIFFDirEntry *dp;
+ uint16_t di;
+ const TIFFField *fip;
+ uint32_t fii;
+ (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */
+ _TIFFSetupFields(tif, infoarray);
+ dircount = TIFFFetchDirectory(tif, diroff, &dir, NULL);
+ if (!dircount)
+ {
+ TIFFWarningExtR(tif, module,
+ "Failed to read custom directory at offset %" PRIu64,
+ diroff);
+ return 0;
+ }
+ TIFFFreeDirectory(tif);
+ _TIFFmemset(&tif->tif_dir, 0, sizeof(TIFFDirectory));
+ TIFFReadDirectoryCheckOrder(tif, dir, dircount);
+ for (di = 0, dp = dir; di < dircount; di++, dp++)
+ {
+ TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii);
+ if (fii == FAILED_FII)
+ {
+ TIFFWarningExtR(tif, module,
+ "Unknown field with tag %" PRIu16 " (0x%" PRIx16
+ ") encountered",
+ dp->tdir_tag, dp->tdir_tag);
+ if (!_TIFFMergeFields(
+ tif,
+ _TIFFCreateAnonField(tif, dp->tdir_tag,
+ (TIFFDataType)dp->tdir_type),
+ 1))
+ {
+ TIFFWarningExtR(tif, module,
+ "Registering anonymous field with tag %" PRIu16
+ " (0x%" PRIx16 ") failed",
+ dp->tdir_tag, dp->tdir_tag);
+ dp->tdir_ignore = TRUE;
+ }
+ else
+ {
+ TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii);
+ assert(fii != FAILED_FII);
+ }
+ }
+ if (!dp->tdir_ignore)
+ {
+ fip = tif->tif_fields[fii];
+ if (fip->field_bit == FIELD_IGNORE)
+ dp->tdir_ignore = TRUE;
+ else
+ {
+ /* check data type */
+ while ((fip->field_type != TIFF_ANY) &&
+ (fip->field_type != dp->tdir_type))
+ {
+ fii++;
+ if ((fii == tif->tif_nfields) ||
+ (tif->tif_fields[fii]->field_tag !=
+ (uint32_t)dp->tdir_tag))
+ {
+ fii = 0xFFFF;
+ break;
+ }
+ fip = tif->tif_fields[fii];
+ }
+ if (fii == 0xFFFF)
+ {
+ TIFFWarningExtR(tif, module,
+ "Wrong data type %" PRIu16
+ " for \"%s\"; tag ignored",
+ dp->tdir_type, fip->field_name);
+ dp->tdir_ignore = TRUE;
+ }
+ else
+ {
+ /* check count if known in advance */
+ if ((fip->field_readcount != TIFF_VARIABLE) &&
+ (fip->field_readcount != TIFF_VARIABLE2))
+ {
+ uint32_t expected;
+ if (fip->field_readcount == TIFF_SPP)
+ expected =
+ (uint32_t)tif->tif_dir.td_samplesperpixel;
+ else
+ expected = (uint32_t)fip->field_readcount;
+ if (!CheckDirCount(tif, dp, expected))
+ dp->tdir_ignore = TRUE;
+ }
+ }
+ }
+ if (!dp->tdir_ignore)
+ {
+ switch (dp->tdir_tag)
+ {
+ case EXIFTAG_SUBJECTDISTANCE:
+ 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);
+ break;
+ }
+ } /*-- if (!dp->tdir_ignore) */
+ }
+ }
+ /* To be able to return from SubIFD or custom-IFD to main-IFD */
+ tif->tif_setdirectory_force_absolute = TRUE;
+ if (dir)
+ _TIFFfreeExt(tif, dir);
+ return 1;
+}
+
+/*
+ * EXIF is important special case of custom IFD, so we have a special
+ * function to read it.
+ */
+int TIFFReadEXIFDirectory(TIFF *tif, toff_t diroff)
+{
+ const TIFFFieldArray *exifFieldArray;
+ exifFieldArray = _TIFFGetExifFields();
+ return TIFFReadCustomDirectory(tif, diroff, exifFieldArray);
+}
+
+/*
+ *--: EXIF-GPS custom directory reading as another special case of custom IFD.
+ */
+int TIFFReadGPSDirectory(TIFF *tif, toff_t diroff)
+{
+ const TIFFFieldArray *gpsFieldArray;
+ gpsFieldArray = _TIFFGetGpsFields();
+ return TIFFReadCustomDirectory(tif, diroff, gpsFieldArray);
+}
+
+static int EstimateStripByteCounts(TIFF *tif, TIFFDirEntry *dir,
+ uint16_t dircount)
+{
+ static const char module[] = "EstimateStripByteCounts";
+
+ TIFFDirEntry *dp;
+ TIFFDirectory *td = &tif->tif_dir;
+ uint32_t strip;
+
+ /* Do not try to load stripbytecount as we will compute it */
+ if (!_TIFFFillStrilesInternal(tif, 0))
+ return -1;
+
+ if (td->td_stripbytecount_p)
+ _TIFFfreeExt(tif, td->td_stripbytecount_p);
+ td->td_stripbytecount_p = (uint64_t *)_TIFFCheckMalloc(
+ tif, td->td_nstrips, sizeof(uint64_t), "for \"StripByteCounts\" array");
+ if (td->td_stripbytecount_p == NULL)
+ return -1;
+
+ if (td->td_compression != COMPRESSION_NONE)
+ {
+ uint64_t space;
+ uint64_t filesize;
+ uint16_t n;
+ filesize = TIFFGetFileSize(tif);
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ space = sizeof(TIFFHeaderClassic) + 2 + dircount * 12 + 4;
+ else
+ space = sizeof(TIFFHeaderBig) + 8 + dircount * 20 + 8;
+ /* calculate amount of space used by indirect values */
+ for (dp = dir, n = dircount; n > 0; n--, dp++)
+ {
+ uint32_t typewidth;
+ uint64_t datasize;
+ typewidth = TIFFDataWidth((TIFFDataType)dp->tdir_type);
+ if (typewidth == 0)
+ {
+ TIFFErrorExtR(
+ tif, module,
+ "Cannot determine size of unknown tag type %" PRIu16,
+ dp->tdir_type);
+ return -1;
+ }
+ if (dp->tdir_count > UINT64_MAX / typewidth)
+ return -1;
+ datasize = (uint64_t)typewidth * dp->tdir_count;
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ if (datasize <= 4)
+ datasize = 0;
+ }
+ else
+ {
+ if (datasize <= 8)
+ datasize = 0;
+ }
+ if (space > UINT64_MAX - datasize)
+ return -1;
+ space += datasize;
+ }
+ if (filesize < space)
+ /* we should perhaps return in error ? */
+ space = filesize;
+ else
+ space = filesize - space;
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
+ space /= td->td_samplesperpixel;
+ for (strip = 0; strip < td->td_nstrips; strip++)
+ td->td_stripbytecount_p[strip] = space;
+ /*
+ * This gross hack handles the case were the offset to
+ * the last strip is past the place where we think the strip
+ * should begin. Since a strip of data must be contiguous,
+ * it's safe to assume that we've overestimated the amount
+ * of data in the strip and trim this number back accordingly.
+ */
+ strip--;
+ if (td->td_stripoffset_p[strip] >
+ UINT64_MAX - td->td_stripbytecount_p[strip])
+ return -1;
+ if (td->td_stripoffset_p[strip] + td->td_stripbytecount_p[strip] >
+ filesize)
+ {
+ if (td->td_stripoffset_p[strip] >= filesize)
+ {
+ /* Not sure what we should in that case... */
+ td->td_stripbytecount_p[strip] = 0;
+ }
+ else
+ {
+ td->td_stripbytecount_p[strip] =
+ filesize - td->td_stripoffset_p[strip];
+ }
+ }
+ }
+ else if (isTiled(tif))
+ {
+ uint64_t bytespertile = TIFFTileSize64(tif);
+
+ for (strip = 0; strip < td->td_nstrips; strip++)
+ td->td_stripbytecount_p[strip] = bytespertile;
+ }
+ else
+ {
+ uint64_t rowbytes = TIFFScanlineSize64(tif);
+ uint32_t rowsperstrip = td->td_imagelength / td->td_stripsperimage;
+ for (strip = 0; strip < td->td_nstrips; strip++)
+ {
+ if (rowbytes > 0 && rowsperstrip > UINT64_MAX / rowbytes)
+ return -1;
+ td->td_stripbytecount_p[strip] = rowbytes * rowsperstrip;
+ }
+ }
+ TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
+ if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
+ td->td_rowsperstrip = td->td_imagelength;
+ return 1;
+}
+
+static void MissingRequired(TIFF *tif, const char *tagname)
+{
+ static const char module[] = "MissingRequired";
+
+ TIFFWarningExtR(tif, module,
+ "TIFF directory is missing required \"%s\" field", tagname);
+}
+
+static unsigned long hashFuncOffsetToNumber(const void *elt)
+{
+ const TIFFOffsetAndDirNumber *offsetAndDirNumber =
+ (const TIFFOffsetAndDirNumber *)elt;
+ const uint32_t hash = (uint32_t)(offsetAndDirNumber->offset >> 32) ^
+ ((uint32_t)offsetAndDirNumber->offset & 0xFFFFFFFFU);
+ return hash;
+}
+
+static bool equalFuncOffsetToNumber(const void *elt1, const void *elt2)
+{
+ const TIFFOffsetAndDirNumber *offsetAndDirNumber1 =
+ (const TIFFOffsetAndDirNumber *)elt1;
+ const TIFFOffsetAndDirNumber *offsetAndDirNumber2 =
+ (const TIFFOffsetAndDirNumber *)elt2;
+ return offsetAndDirNumber1->offset == offsetAndDirNumber2->offset;
+}
+
+static unsigned long hashFuncNumberToOffset(const void *elt)
+{
+ const TIFFOffsetAndDirNumber *offsetAndDirNumber =
+ (const TIFFOffsetAndDirNumber *)elt;
+ return offsetAndDirNumber->dirNumber;
+}
+
+static bool equalFuncNumberToOffset(const void *elt1, const void *elt2)
+{
+ const TIFFOffsetAndDirNumber *offsetAndDirNumber1 =
+ (const TIFFOffsetAndDirNumber *)elt1;
+ const TIFFOffsetAndDirNumber *offsetAndDirNumber2 =
+ (const TIFFOffsetAndDirNumber *)elt2;
+ return offsetAndDirNumber1->dirNumber == offsetAndDirNumber2->dirNumber;
+}
+
+/*
+ * Check the directory number and offset against the list of already seen
+ * directory numbers and offsets. This is a trick to prevent IFD looping.
+ * The one can create TIFF file with looped directory pointers. We will
+ * maintain a list of already seen directories and check every IFD offset
+ * and its IFD number against that list. However, the offset of an IFD number
+ * can change - e.g. when writing updates to file.
+ * Returns 1 if all is ok; 0 if last directory or IFD loop is encountered,
+ * or an error has occurred.
+ */
+int _TIFFCheckDirNumberAndOffset(TIFF *tif, tdir_t dirn, uint64_t diroff)
+{
+ if (diroff == 0) /* no more directories */
+ return 0;
+
+ if (tif->tif_map_dir_offset_to_number == NULL)
+ {
+ tif->tif_map_dir_offset_to_number = TIFFHashSetNew(
+ hashFuncOffsetToNumber, equalFuncOffsetToNumber, free);
+ if (tif->tif_map_dir_offset_to_number == NULL)
+ {
+ TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset",
+ "Not enough memory");
+ return 1;
+ }
+ }
+
+ if (tif->tif_map_dir_number_to_offset == NULL)
+ {
+ /* No free callback for this map, as it shares the same items as
+ * tif->tif_map_dir_offset_to_number. */
+ tif->tif_map_dir_number_to_offset = TIFFHashSetNew(
+ hashFuncNumberToOffset, equalFuncNumberToOffset, NULL);
+ if (tif->tif_map_dir_number_to_offset == NULL)
+ {
+ TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset",
+ "Not enough memory");
+ return 1;
+ }
+ }
+
+ /* Check if offset is already in the list:
+ * - yes: check, if offset is at the same IFD number - if not, it is an IFD
+ * loop
+ * - no: add to list or update offset at that IFD number
+ */
+ TIFFOffsetAndDirNumber entry;
+ entry.offset = diroff;
+ entry.dirNumber = dirn;
+
+ TIFFOffsetAndDirNumber *foundEntry =
+ (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
+ tif->tif_map_dir_offset_to_number, &entry);
+ if (foundEntry)
+ {
+ if (foundEntry->dirNumber == dirn)
+ {
+ return 1;
+ }
+ else
+ {
+ TIFFWarningExtR(tif, "_TIFFCheckDirNumberAndOffset",
+ "TIFF directory %d has IFD looping to directory %u "
+ "at offset 0x%" PRIx64 " (%" PRIu64 ")",
+ (int)dirn - 1, foundEntry->dirNumber, diroff,
+ diroff);
+ return 0;
+ }
+ }
+
+ /* Check if offset of an IFD has been changed and update offset of that IFD
+ * number. */
+ foundEntry = (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
+ tif->tif_map_dir_number_to_offset, &entry);
+ if (foundEntry)
+ {
+ if (foundEntry->offset != diroff)
+ {
+ TIFFOffsetAndDirNumber entryOld;
+ entryOld.offset = foundEntry->offset;
+ entryOld.dirNumber = dirn;
+ /* We must remove first from tif_map_dir_number_to_offset as the */
+ /* entry is owned (and thus freed) by */
+ /* tif_map_dir_offset_to_number */
+ TIFFOffsetAndDirNumber *foundEntryOld =
+ (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
+ tif->tif_map_dir_number_to_offset, &entryOld);
+ if (foundEntryOld)
+ {
+ TIFFHashSetRemove(tif->tif_map_dir_number_to_offset,
+ foundEntryOld);
+ }
+ foundEntryOld = (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
+ tif->tif_map_dir_offset_to_number, &entryOld);
+ if (foundEntryOld)
+ {
+ TIFFHashSetRemove(tif->tif_map_dir_offset_to_number,
+ foundEntryOld);
+ }
+
+ TIFFOffsetAndDirNumber *entryPtr = (TIFFOffsetAndDirNumber *)malloc(
+ sizeof(TIFFOffsetAndDirNumber));
+ if (entryPtr == NULL)
+ {
+ return 0;
+ }
+
+ /* Add IFD offset and dirn to IFD directory list */
+ *entryPtr = entry;
+
+ if (!TIFFHashSetInsert(tif->tif_map_dir_offset_to_number, entryPtr))
+ {
+ TIFFErrorExtR(
+ tif, "_TIFFCheckDirNumberAndOffset",
+ "Insertion in tif_map_dir_offset_to_number failed");
+ return 0;
+ }
+ if (!TIFFHashSetInsert(tif->tif_map_dir_number_to_offset, entryPtr))
+ {
+ TIFFErrorExtR(
+ tif, "_TIFFCheckDirNumberAndOffset",
+ "Insertion in tif_map_dir_number_to_offset failed");
+ return 0;
+ }
+ }
+ return 1;
+ }
+
+ /* Arbitrary (hopefully big enough) limit */
+ if (TIFFHashSetSize(tif->tif_map_dir_offset_to_number) >=
+ TIFF_MAX_DIR_COUNT)
+ {
+ TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset",
+ "Cannot handle more than %u TIFF directories",
+ TIFF_MAX_DIR_COUNT);
+ return 0;
+ }
+
+ TIFFOffsetAndDirNumber *entryPtr =
+ (TIFFOffsetAndDirNumber *)malloc(sizeof(TIFFOffsetAndDirNumber));
+ if (entryPtr == NULL)
+ {
+ TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset",
+ "malloc(sizeof(TIFFOffsetAndDirNumber)) failed");
+ return 0;
+ }
+
+ /* Add IFD offset and dirn to IFD directory list */
+ *entryPtr = entry;
+
+ if (!TIFFHashSetInsert(tif->tif_map_dir_offset_to_number, entryPtr))
+ {
+ TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset",
+ "Insertion in tif_map_dir_offset_to_number failed");
+ return 0;
+ }
+ if (!TIFFHashSetInsert(tif->tif_map_dir_number_to_offset, entryPtr))
+ {
+ TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset",
+ "Insertion in tif_map_dir_number_to_offset failed");
+ return 0;
+ }
+
+ return 1;
+} /* --- _TIFFCheckDirNumberAndOffset() ---*/
+
+/*
+ * Retrieve the matching IFD directory number of a given IFD offset
+ * from the list of directories already seen.
+ * Returns 1 if the offset was in the list and the directory number
+ * can be returned.
+ * Otherwise returns 0 or if an error occurred.
+ */
+int _TIFFGetDirNumberFromOffset(TIFF *tif, uint64_t diroff, tdir_t *dirn)
+{
+ if (diroff == 0) /* no more directories */
+ return 0;
+
+ /* Check if offset is already in the list and return matching directory
+ * number. Otherwise update IFD list using TIFFNumberOfDirectories() and
+ * search again in IFD list.
+ */
+ if (tif->tif_map_dir_offset_to_number == NULL)
+ return 0;
+ TIFFOffsetAndDirNumber entry;
+ entry.offset = diroff;
+ entry.dirNumber = 0; /* not used */
+
+ TIFFOffsetAndDirNumber *foundEntry =
+ (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
+ tif->tif_map_dir_offset_to_number, &entry);
+ if (foundEntry)
+ {
+ *dirn = foundEntry->dirNumber;
+ return 1;
+ }
+
+ /* This updates the directory list for all main-IFDs in the file. */
+ TIFFNumberOfDirectories(tif);
+
+ foundEntry = (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
+ tif->tif_map_dir_offset_to_number, &entry);
+ if (foundEntry)
+ {
+ *dirn = foundEntry->dirNumber;
+ return 1;
+ }
+
+ return 0;
+} /*--- _TIFFGetDirNumberFromOffset() ---*/
+
+/*
+ * Retrieve the matching IFD directory offset of a given IFD number
+ * from the list of directories already seen.
+ * Returns 1 if the offset was in the list of already seen IFDs and the
+ * directory offset can be returned. The directory list is not updated.
+ * Otherwise returns 0 or if an error occurred.
+ */
+int _TIFFGetOffsetFromDirNumber(TIFF *tif, tdir_t dirn, uint64_t *diroff)
+{
+
+ if (tif->tif_map_dir_number_to_offset == NULL)
+ return 0;
+ TIFFOffsetAndDirNumber entry;
+ entry.offset = 0; /* not used */
+ entry.dirNumber = dirn;
+
+ TIFFOffsetAndDirNumber *foundEntry =
+ (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
+ tif->tif_map_dir_number_to_offset, &entry);
+ if (foundEntry)
+ {
+ *diroff = foundEntry->offset;
+ return 1;
+ }
+
+ return 0;
+} /*--- _TIFFGetOffsetFromDirNumber() ---*/
+
+/*
+ * Remove an entry from the directory list of already seen directories
+ * by directory offset.
+ * If an entry is to be removed from the list, it is also okay if the entry
+ * is not in the list or the list does not exist.
+ */
+int _TIFFRemoveEntryFromDirectoryListByOffset(TIFF *tif, uint64_t diroff)
+{
+ if (tif->tif_map_dir_offset_to_number == NULL)
+ return 1;
+
+ TIFFOffsetAndDirNumber entryOld;
+ entryOld.offset = diroff;
+ entryOld.dirNumber = 0;
+ /* We must remove first from tif_map_dir_number_to_offset as the
+ * entry is owned (and thus freed) by tif_map_dir_offset_to_number.
+ * However, we need firstly to find the directory number from offset. */
+
+ TIFFOffsetAndDirNumber *foundEntryOldOff =
+ (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
+ tif->tif_map_dir_offset_to_number, &entryOld);
+ if (foundEntryOldOff)
+ {
+ entryOld.dirNumber = foundEntryOldOff->dirNumber;
+ if (tif->tif_map_dir_number_to_offset != NULL)
+ {
+ TIFFOffsetAndDirNumber *foundEntryOldDir =
+ (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
+ tif->tif_map_dir_number_to_offset, &entryOld);
+ if (foundEntryOldDir)
+ {
+ TIFFHashSetRemove(tif->tif_map_dir_number_to_offset,
+ foundEntryOldDir);
+ TIFFHashSetRemove(tif->tif_map_dir_offset_to_number,
+ foundEntryOldOff);
+ return 1;
+ }
+ }
+ else
+ {
+ TIFFErrorExtR(tif, "_TIFFRemoveEntryFromDirectoryListByOffset",
+ "Unexpectedly tif_map_dir_number_to_offset is "
+ "missing but tif_map_dir_offset_to_number exists.");
+ return 0;
+ }
+ }
+ return 1;
+} /*--- _TIFFRemoveEntryFromDirectoryListByOffset() ---*/
+
+/*
+ * Check the count field of a directory entry against a known value. The
+ * caller is expected to skip/ignore the tag if there is a mismatch.
+ */
+static int CheckDirCount(TIFF *tif, TIFFDirEntry *dir, uint32_t count)
+{
+ if ((uint64_t)count > dir->tdir_count)
+ {
+ const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag);
+ TIFFWarningExtR(tif, tif->tif_name,
+ "incorrect count for field \"%s\" (%" PRIu64
+ ", expecting %" PRIu32 "); tag ignored",
+ fip ? fip->field_name : "unknown tagname",
+ dir->tdir_count, count);
+ return (0);
+ }
+ else if ((uint64_t)count < dir->tdir_count)
+ {
+ const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag);
+ TIFFWarningExtR(tif, tif->tif_name,
+ "incorrect count for field \"%s\" (%" PRIu64
+ ", expecting %" PRIu32 "); tag trimmed",
+ fip ? fip->field_name : "unknown tagname",
+ dir->tdir_count, count);
+ dir->tdir_count = count;
+ return (1);
+ }
+ return (1);
+}
+
+/*
+ * Read IFD structure from the specified offset. If the pointer to
+ * nextdiroff variable has been specified, read it too. Function returns a
+ * number of fields in the directory or 0 if failed.
+ */
+static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff,
+ TIFFDirEntry **pdir, uint64_t *nextdiroff)
+{
+ static const char module[] = "TIFFFetchDirectory";
+
+ void *origdir;
+ uint16_t dircount16;
+ uint32_t dirsize;
+ TIFFDirEntry *dir;
+ uint8_t *ma;
+ TIFFDirEntry *mb;
+ uint16_t n;
+
+ assert(pdir);
+
+ tif->tif_diroff = diroff;
+ if (nextdiroff)
+ *nextdiroff = 0;
+ if (!isMapped(tif))
+ {
+ if (!SeekOK(tif, tif->tif_diroff))
+ {
+ TIFFErrorExtR(tif, module,
+ "%s: Seek error accessing TIFF directory",
+ tif->tif_name);
+ return 0;
+ }
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ if (!ReadOK(tif, &dircount16, sizeof(uint16_t)))
+ {
+ TIFFErrorExtR(tif, module,
+ "%s: Can not read TIFF directory count",
+ tif->tif_name);
+ return 0;
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(&dircount16);
+ if (dircount16 > 4096)
+ {
+ TIFFErrorExtR(tif, module,
+ "Sanity check on directory count failed, this is "
+ "probably not a valid IFD offset");
+ return 0;
+ }
+ dirsize = 12;
+ }
+ else
+ {
+ uint64_t dircount64;
+ if (!ReadOK(tif, &dircount64, sizeof(uint64_t)))
+ {
+ TIFFErrorExtR(tif, module,
+ "%s: Can not read TIFF directory count",
+ tif->tif_name);
+ return 0;
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&dircount64);
+ if (dircount64 > 4096)
+ {
+ TIFFErrorExtR(tif, module,
+ "Sanity check on directory count failed, this is "
+ "probably not a valid IFD offset");
+ return 0;
+ }
+ dircount16 = (uint16_t)dircount64;
+ dirsize = 20;
+ }
+ origdir = _TIFFCheckMalloc(tif, dircount16, dirsize,
+ "to read TIFF directory");
+ if (origdir == NULL)
+ return 0;
+ if (!ReadOK(tif, origdir, (tmsize_t)(dircount16 * dirsize)))
+ {
+ TIFFErrorExtR(tif, module, "%.100s: Can not read TIFF directory",
+ tif->tif_name);
+ _TIFFfreeExt(tif, origdir);
+ return 0;
+ }
+ /*
+ * Read offset to next directory for sequential scans if
+ * needed.
+ */
+ if (nextdiroff)
+ {
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ uint32_t nextdiroff32;
+ if (!ReadOK(tif, &nextdiroff32, sizeof(uint32_t)))
+ nextdiroff32 = 0;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&nextdiroff32);
+ *nextdiroff = nextdiroff32;
+ }
+ else
+ {
+ if (!ReadOK(tif, nextdiroff, sizeof(uint64_t)))
+ *nextdiroff = 0;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(nextdiroff);
+ }
+ }
+ }
+ else
+ {
+ tmsize_t m;
+ tmsize_t off;
+ if (tif->tif_diroff > (uint64_t)INT64_MAX)
+ {
+ TIFFErrorExtR(tif, module, "Can not read TIFF directory count");
+ return (0);
+ }
+ off = (tmsize_t)tif->tif_diroff;
+
+ /*
+ * Check for integer overflow when validating the dir_off,
+ * otherwise a very high offset may cause an OOB read and
+ * crash the client. Make two comparisons instead of
+ *
+ * off + sizeof(uint16_t) > tif->tif_size
+ *
+ * to avoid overflow.
+ */
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ m = off + sizeof(uint16_t);
+ if ((m < off) || (m < (tmsize_t)sizeof(uint16_t)) ||
+ (m > tif->tif_size))
+ {
+ TIFFErrorExtR(tif, module, "Can not read TIFF directory count");
+ return 0;
+ }
+ else
+ {
+ _TIFFmemcpy(&dircount16, tif->tif_base + off, sizeof(uint16_t));
+ }
+ off += sizeof(uint16_t);
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(&dircount16);
+ if (dircount16 > 4096)
+ {
+ TIFFErrorExtR(tif, module,
+ "Sanity check on directory count failed, this is "
+ "probably not a valid IFD offset");
+ return 0;
+ }
+ dirsize = 12;
+ }
+ else
+ {
+ uint64_t dircount64;
+ m = off + sizeof(uint64_t);
+ if ((m < off) || (m < (tmsize_t)sizeof(uint64_t)) ||
+ (m > tif->tif_size))
+ {
+ TIFFErrorExtR(tif, module, "Can not read TIFF directory count");
+ return 0;
+ }
+ else
+ {
+ _TIFFmemcpy(&dircount64, tif->tif_base + off, sizeof(uint64_t));
+ }
+ off += sizeof(uint64_t);
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&dircount64);
+ if (dircount64 > 4096)
+ {
+ TIFFErrorExtR(tif, module,
+ "Sanity check on directory count failed, this is "
+ "probably not a valid IFD offset");
+ return 0;
+ }
+ dircount16 = (uint16_t)dircount64;
+ dirsize = 20;
+ }
+ if (dircount16 == 0)
+ {
+ TIFFWarningExtR(tif, module,
+ "Sanity check on directory count failed, zero tag "
+ "directories not supported");
+ return 0;
+ }
+ origdir = _TIFFCheckMalloc(tif, dircount16, dirsize,
+ "to read TIFF directory");
+ if (origdir == NULL)
+ return 0;
+ m = off + dircount16 * dirsize;
+ if ((m < off) || (m < (tmsize_t)(dircount16 * dirsize)) ||
+ (m > tif->tif_size))
+ {
+ TIFFErrorExtR(tif, module, "Can not read TIFF directory");
+ _TIFFfreeExt(tif, origdir);
+ return 0;
+ }
+ else
+ {
+ _TIFFmemcpy(origdir, tif->tif_base + off, dircount16 * dirsize);
+ }
+ if (nextdiroff)
+ {
+ off += dircount16 * dirsize;
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ uint32_t nextdiroff32;
+ m = off + sizeof(uint32_t);
+ if ((m < off) || (m < (tmsize_t)sizeof(uint32_t)) ||
+ (m > tif->tif_size))
+ nextdiroff32 = 0;
+ else
+ _TIFFmemcpy(&nextdiroff32, tif->tif_base + off,
+ sizeof(uint32_t));
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&nextdiroff32);
+ *nextdiroff = nextdiroff32;
+ }
+ else
+ {
+ m = off + sizeof(uint64_t);
+ if ((m < off) || (m < (tmsize_t)sizeof(uint64_t)) ||
+ (m > tif->tif_size))
+ *nextdiroff = 0;
+ else
+ _TIFFmemcpy(nextdiroff, tif->tif_base + off,
+ sizeof(uint64_t));
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(nextdiroff);
+ }
+ }
+ }
+ dir = (TIFFDirEntry *)_TIFFCheckMalloc(
+ tif, dircount16, sizeof(TIFFDirEntry), "to read TIFF directory");
+ if (dir == 0)
+ {
+ _TIFFfreeExt(tif, origdir);
+ return 0;
+ }
+ ma = (uint8_t *)origdir;
+ mb = dir;
+ for (n = 0; n < dircount16; n++)
+ {
+ mb->tdir_ignore = FALSE;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort((uint16_t *)ma);
+ mb->tdir_tag = *(uint16_t *)ma;
+ ma += sizeof(uint16_t);
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort((uint16_t *)ma);
+ mb->tdir_type = *(uint16_t *)ma;
+ ma += sizeof(uint16_t);
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong((uint32_t *)ma);
+ mb->tdir_count = (uint64_t)(*(uint32_t *)ma);
+ ma += sizeof(uint32_t);
+ mb->tdir_offset.toff_long8 = 0;
+ *(uint32_t *)(&mb->tdir_offset) = *(uint32_t *)ma;
+ ma += sizeof(uint32_t);
+ }
+ else
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8((uint64_t *)ma);
+ mb->tdir_count = TIFFReadUInt64(ma);
+ ma += sizeof(uint64_t);
+ mb->tdir_offset.toff_long8 = TIFFReadUInt64(ma);
+ ma += sizeof(uint64_t);
+ }
+ mb++;
+ }
+ _TIFFfreeExt(tif, origdir);
+ *pdir = dir;
+ return dircount16;
+}
+
+/*
+ * Fetch a tag that is not handled by special case code.
+ */
+static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover)
+{
+ static const char module[] = "TIFFFetchNormalTag";
+ enum TIFFReadDirEntryErr err;
+ uint32_t fii;
+ const TIFFField *fip = NULL;
+ TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii);
+ if (fii == FAILED_FII)
+ {
+ TIFFErrorExtR(tif, "TIFFFetchNormalTag",
+ "No definition found for tag %" PRIu16, dp->tdir_tag);
+ return 0;
+ }
+ fip = tif->tif_fields[fii];
+ assert(fip != NULL); /* should not happen */
+ assert(fip->set_field_type !=
+ TIFF_SETGET_OTHER); /* if so, we shouldn't arrive here but deal with
+ this in specialized code */
+ assert(fip->set_field_type !=
+ TIFF_SETGET_INT); /* if so, we shouldn't arrive here as this is only
+ the case for pseudo-tags */
+ err = TIFFReadDirEntryErrOk;
+ switch (fip->set_field_type)
+ {
+ case TIFF_SETGET_UNDEFINED:
+ TIFFErrorExtR(
+ tif, "TIFFFetchNormalTag",
+ "Defined set_field_type of custom tag %u (%s) is "
+ "TIFF_SETGET_UNDEFINED and thus tag is not read from file",
+ fip->field_tag, fip->field_name);
+ break;
+ case TIFF_SETGET_ASCII:
+ {
+ uint8_t *data;
+ assert(fip->field_passcount == 0);
+ err = TIFFReadDirEntryByteArray(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ size_t mb = 0;
+ int n;
+ if (data != NULL)
+ {
+ 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)
+ TIFFWarningExtR(
+ tif, module,
+ "ASCII value for tag \"%s\" contains null byte in "
+ "value; value incorrectly truncated during reading due "
+ "to implementation limitations",
+ fip->field_name);
+ else if (mb + 1 > (uint32_t)dp->tdir_count)
+ {
+ uint8_t *o;
+ TIFFWarningExtR(
+ tif, module,
+ "ASCII value for tag \"%s\" does not end in null byte",
+ fip->field_name);
+ /* TIFFReadDirEntryArrayWithLimit() ensures this can't be
+ * larger than MAX_SIZE_TAG_DATA */
+ assert((uint32_t)dp->tdir_count + 1 == dp->tdir_count + 1);
+ o = _TIFFmallocExt(tif, (uint32_t)dp->tdir_count + 1);
+ if (o == NULL)
+ {
+ if (data != NULL)
+ _TIFFfreeExt(tif, data);
+ return (0);
+ }
+ if (dp->tdir_count > 0)
+ {
+ _TIFFmemcpy(o, data, (uint32_t)dp->tdir_count);
+ }
+ o[(uint32_t)dp->tdir_count] = 0;
+ if (data != 0)
+ _TIFFfreeExt(tif, data);
+ data = o;
+ }
+ n = TIFFSetField(tif, dp->tdir_tag, data);
+ if (data != 0)
+ _TIFFfreeExt(tif, data);
+ if (!n)
+ return (0);
+ }
+ }
+ break;
+ case TIFF_SETGET_UINT8:
+ {
+ uint8_t data = 0;
+ assert(fip->field_readcount == 1);
+ assert(fip->field_passcount == 0);
+ err = TIFFReadDirEntryByte(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ if (!TIFFSetField(tif, dp->tdir_tag, data))
+ return (0);
+ }
+ }
+ 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;
+ assert(fip->field_readcount == 1);
+ assert(fip->field_passcount == 0);
+ err = TIFFReadDirEntryShort(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ if (!TIFFSetField(tif, dp->tdir_tag, data))
+ return (0);
+ }
+ }
+ 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;
+ assert(fip->field_readcount == 1);
+ assert(fip->field_passcount == 0);
+ err = TIFFReadDirEntryLong(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ if (!TIFFSetField(tif, dp->tdir_tag, data))
+ return (0);
+ }
+ }
+ 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;
+ assert(fip->field_readcount == 1);
+ assert(fip->field_passcount == 0);
+ err = TIFFReadDirEntryLong8(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ if (!TIFFSetField(tif, dp->tdir_tag, data))
+ return (0);
+ }
+ }
+ 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;
+ assert(fip->field_readcount == 1);
+ assert(fip->field_passcount == 0);
+ err = TIFFReadDirEntryFloat(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ if (!TIFFSetField(tif, dp->tdir_tag, data))
+ return (0);
+ }
+ }
+ break;
+ case TIFF_SETGET_DOUBLE:
+ {
+ double data;
+ assert(fip->field_readcount == 1);
+ assert(fip->field_passcount == 0);
+ err = TIFFReadDirEntryDouble(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ if (!TIFFSetField(tif, dp->tdir_tag, data))
+ return (0);
+ }
+ }
+ break;
+ case TIFF_SETGET_IFD8:
+ {
+ uint64_t data;
+ assert(fip->field_readcount == 1);
+ assert(fip->field_passcount == 0);
+ err = TIFFReadDirEntryIfd8(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ if (!TIFFSetField(tif, dp->tdir_tag, data))
+ return (0);
+ }
+ }
+ break;
+ case TIFF_SETGET_UINT16_PAIR:
+ {
+ uint16_t *data;
+ assert(fip->field_readcount == 2);
+ assert(fip->field_passcount == 0);
+ if (dp->tdir_count != 2)
+ {
+ TIFFWarningExtR(tif, module,
+ "incorrect count for field \"%s\", expected 2, "
+ "got %" PRIu64,
+ fip->field_name, dp->tdir_count);
+ return (0);
+ }
+ err = TIFFReadDirEntryShortArray(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ int m;
+ assert(data); /* avoid CLang static Analyzer false positive */
+ m = TIFFSetField(tif, dp->tdir_tag, data[0], data[1]);
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ break;
+ case TIFF_SETGET_C0_UINT8:
+ {
+ uint8_t *data;
+ assert(fip->field_readcount >= 1);
+ assert(fip->field_passcount == 0);
+ if (dp->tdir_count != (uint64_t)fip->field_readcount)
+ {
+ TIFFWarningExtR(tif, module,
+ "incorrect count for field \"%s\", expected "
+ "%d, got %" PRIu64,
+ fip->field_name, (int)fip->field_readcount,
+ dp->tdir_count);
+ return (0);
+ }
+ else
+ {
+ err = TIFFReadDirEntryByteArray(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m = TIFFSetField(tif, dp->tdir_tag, data);
+ if (data != 0)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ }
+ 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)
+ {
+ TIFFWarningExtR(tif, 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)
+ _TIFFfreeExt(tif, 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)
+ {
+ TIFFWarningExtR(tif, 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);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m = TIFFSetField(tif, dp->tdir_tag, data);
+ if (data != 0)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ }
+ 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)
+ {
+ TIFFWarningExtR(tif, 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)
+ _TIFFfreeExt(tif, 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)
+ {
+ TIFFWarningExtR(tif, 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);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m = TIFFSetField(tif, dp->tdir_tag, data);
+ if (data != 0)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ }
+ 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)
+ {
+ TIFFWarningExtR(tif, 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)
+ _TIFFfreeExt(tif, 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)
+ {
+ TIFFWarningExtR(tif, 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)
+ _TIFFfreeExt(tif, 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)
+ {
+ TIFFWarningExtR(tif, 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)
+ _TIFFfreeExt(tif, 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)
+ {
+ TIFFWarningExtR(tif, 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);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m = TIFFSetField(tif, dp->tdir_tag, data);
+ if (data != 0)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ }
+ break;
+ /*--: Rational2Double: Extend for Double Arrays and Rational-Arrays read
+ * into Double-Arrays. */
+ case TIFF_SETGET_C0_DOUBLE:
+ {
+ double *data;
+ assert(fip->field_readcount >= 1);
+ assert(fip->field_passcount == 0);
+ if (dp->tdir_count != (uint64_t)fip->field_readcount)
+ {
+ TIFFWarningExtR(tif, 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);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m = TIFFSetField(tif, dp->tdir_tag, data);
+ if (data != 0)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ }
+ break;
+ case TIFF_SETGET_C16_ASCII:
+ {
+ uint8_t *data;
+ assert(fip->field_readcount == TIFF_VARIABLE);
+ assert(fip->field_passcount == 1);
+ if (dp->tdir_count > 0xFFFF)
+ err = TIFFReadDirEntryErrCount;
+ else
+ {
+ err = TIFFReadDirEntryByteArray(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ int m;
+ if (data != 0 && dp->tdir_count > 0 &&
+ data[dp->tdir_count - 1] != '\0')
+ {
+ TIFFWarningExtR(
+ tif, 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,
+ (uint16_t)(dp->tdir_count), data);
+ if (data != 0)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ }
+ break;
+ case TIFF_SETGET_C16_UINT8:
+ {
+ uint8_t *data;
+ assert(fip->field_readcount == TIFF_VARIABLE);
+ assert(fip->field_passcount == 1);
+ if (dp->tdir_count > 0xFFFF)
+ err = TIFFReadDirEntryErrCount;
+ else
+ {
+ err = TIFFReadDirEntryByteArray(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m = TIFFSetField(tif, dp->tdir_tag,
+ (uint16_t)(dp->tdir_count), data);
+ if (data != 0)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ }
+ 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)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ }
+ break;
+ case TIFF_SETGET_C16_UINT16:
+ {
+ uint16_t *data;
+ assert(fip->field_readcount == TIFF_VARIABLE);
+ assert(fip->field_passcount == 1);
+ if (dp->tdir_count > 0xFFFF)
+ err = TIFFReadDirEntryErrCount;
+ else
+ {
+ err = TIFFReadDirEntryShortArray(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m = TIFFSetField(tif, dp->tdir_tag,
+ (uint16_t)(dp->tdir_count), data);
+ if (data != 0)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ }
+ 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)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ }
+ break;
+ case TIFF_SETGET_C16_UINT32:
+ {
+ uint32_t *data;
+ assert(fip->field_readcount == TIFF_VARIABLE);
+ assert(fip->field_passcount == 1);
+ if (dp->tdir_count > 0xFFFF)
+ err = TIFFReadDirEntryErrCount;
+ else
+ {
+ err = TIFFReadDirEntryLongArray(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m = TIFFSetField(tif, dp->tdir_tag,
+ (uint16_t)(dp->tdir_count), data);
+ if (data != 0)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ }
+ 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)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ }
+ break;
+ case TIFF_SETGET_C16_UINT64:
+ {
+ uint64_t *data;
+ assert(fip->field_readcount == TIFF_VARIABLE);
+ assert(fip->field_passcount == 1);
+ if (dp->tdir_count > 0xFFFF)
+ err = TIFFReadDirEntryErrCount;
+ else
+ {
+ err = TIFFReadDirEntryLong8Array(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m = TIFFSetField(tif, dp->tdir_tag,
+ (uint16_t)(dp->tdir_count), data);
+ if (data != 0)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ }
+ 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)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ }
+ break;
+ case TIFF_SETGET_C16_FLOAT:
+ {
+ float *data;
+ assert(fip->field_readcount == TIFF_VARIABLE);
+ assert(fip->field_passcount == 1);
+ if (dp->tdir_count > 0xFFFF)
+ err = TIFFReadDirEntryErrCount;
+ else
+ {
+ err = TIFFReadDirEntryFloatArray(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m = TIFFSetField(tif, dp->tdir_tag,
+ (uint16_t)(dp->tdir_count), data);
+ if (data != 0)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ }
+ break;
+ case TIFF_SETGET_C16_DOUBLE:
+ {
+ double *data;
+ assert(fip->field_readcount == TIFF_VARIABLE);
+ assert(fip->field_passcount == 1);
+ if (dp->tdir_count > 0xFFFF)
+ err = TIFFReadDirEntryErrCount;
+ else
+ {
+ err = TIFFReadDirEntryDoubleArray(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m = TIFFSetField(tif, dp->tdir_tag,
+ (uint16_t)(dp->tdir_count), data);
+ if (data != 0)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ }
+ break;
+ case TIFF_SETGET_C16_IFD8:
+ {
+ uint64_t *data;
+ assert(fip->field_readcount == TIFF_VARIABLE);
+ assert(fip->field_passcount == 1);
+ if (dp->tdir_count > 0xFFFF)
+ err = TIFFReadDirEntryErrCount;
+ else
+ {
+ err = TIFFReadDirEntryIfd8Array(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m = TIFFSetField(tif, dp->tdir_tag,
+ (uint16_t)(dp->tdir_count), data);
+ if (data != 0)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ }
+ break;
+ case TIFF_SETGET_C32_ASCII:
+ {
+ uint8_t *data;
+ assert(fip->field_readcount == TIFF_VARIABLE2);
+ assert(fip->field_passcount == 1);
+ err = TIFFReadDirEntryByteArray(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ int m;
+ if (data != 0 && dp->tdir_count > 0 &&
+ data[dp->tdir_count - 1] != '\0')
+ {
+ TIFFWarningExtR(tif, 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)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ break;
+ case TIFF_SETGET_C32_UINT8:
+ {
+ uint8_t *data;
+ uint32_t count = 0;
+ assert(fip->field_readcount == TIFF_VARIABLE2);
+ assert(fip->field_passcount == 1);
+ if (fip->field_tag == TIFFTAG_RICHTIFFIPTC &&
+ dp->tdir_type == TIFF_LONG)
+ {
+ /* Adobe's software (wrongly) writes RichTIFFIPTC tag with
+ * data type LONG instead of UNDEFINED. Work around this
+ * frequently found issue */
+ void *origdata;
+ err = TIFFReadDirEntryArray(tif, dp, &count, 4, &origdata);
+ if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
+ {
+ data = NULL;
+ }
+ else
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfLong((uint32_t *)origdata, count);
+ data = (uint8_t *)origdata;
+ count = (uint32_t)(count * 4);
+ }
+ }
+ else
+ {
+ err = TIFFReadDirEntryByteArray(tif, dp, &data);
+ count = (uint32_t)(dp->tdir_count);
+ }
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m = TIFFSetField(tif, dp->tdir_tag, count, data);
+ if (data != 0)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ break;
+ case TIFF_SETGET_C32_SINT8:
+ {
+ int8_t *data = NULL;
+ assert(fip->field_readcount == TIFF_VARIABLE2);
+ assert(fip->field_passcount == 1);
+ err = TIFFReadDirEntrySbyteArray(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
+ data);
+ if (data != 0)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ break;
+ case TIFF_SETGET_C32_UINT16:
+ {
+ uint16_t *data;
+ assert(fip->field_readcount == TIFF_VARIABLE2);
+ assert(fip->field_passcount == 1);
+ err = TIFFReadDirEntryShortArray(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
+ data);
+ if (data != 0)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ break;
+ case TIFF_SETGET_C32_SINT16:
+ {
+ int16_t *data = NULL;
+ assert(fip->field_readcount == TIFF_VARIABLE2);
+ assert(fip->field_passcount == 1);
+ err = TIFFReadDirEntrySshortArray(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
+ data);
+ if (data != 0)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ break;
+ case TIFF_SETGET_C32_UINT32:
+ {
+ uint32_t *data;
+ assert(fip->field_readcount == TIFF_VARIABLE2);
+ assert(fip->field_passcount == 1);
+ err = TIFFReadDirEntryLongArray(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
+ data);
+ if (data != 0)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ break;
+ case TIFF_SETGET_C32_SINT32:
+ {
+ int32_t *data = NULL;
+ assert(fip->field_readcount == TIFF_VARIABLE2);
+ assert(fip->field_passcount == 1);
+ err = TIFFReadDirEntrySlongArray(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
+ data);
+ if (data != 0)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ break;
+ case TIFF_SETGET_C32_UINT64:
+ {
+ uint64_t *data;
+ assert(fip->field_readcount == TIFF_VARIABLE2);
+ assert(fip->field_passcount == 1);
+ err = TIFFReadDirEntryLong8Array(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
+ data);
+ if (data != 0)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ break;
+ case TIFF_SETGET_C32_SINT64:
+ {
+ int64_t *data = NULL;
+ assert(fip->field_readcount == TIFF_VARIABLE2);
+ assert(fip->field_passcount == 1);
+ err = TIFFReadDirEntrySlong8Array(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
+ data);
+ if (data != 0)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ break;
+ case TIFF_SETGET_C32_FLOAT:
+ {
+ float *data;
+ assert(fip->field_readcount == TIFF_VARIABLE2);
+ assert(fip->field_passcount == 1);
+ err = TIFFReadDirEntryFloatArray(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
+ data);
+ if (data != 0)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ break;
+ case TIFF_SETGET_C32_DOUBLE:
+ {
+ double *data;
+ assert(fip->field_readcount == TIFF_VARIABLE2);
+ assert(fip->field_passcount == 1);
+ err = TIFFReadDirEntryDoubleArray(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
+ data);
+ if (data != 0)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ break;
+ case TIFF_SETGET_C32_IFD8:
+ {
+ uint64_t *data;
+ assert(fip->field_readcount == TIFF_VARIABLE2);
+ assert(fip->field_passcount == 1);
+ err = TIFFReadDirEntryIfd8Array(tif, dp, &data);
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
+ data);
+ if (data != 0)
+ _TIFFfreeExt(tif, data);
+ if (!m)
+ return (0);
+ }
+ }
+ break;
+ default:
+ assert(0); /* we should never get here */
+ break;
+ }
+ if (err != TIFFReadDirEntryErrOk)
+ {
+ TIFFReadDirEntryOutputErr(tif, err, module, fip->field_name, recover);
+ return (0);
+ }
+ return (1);
+}
+
+/*
+ * Fetch a set of offsets or lengths.
+ * While this routine says "strips", in fact it's also used for tiles.
+ */
+static int TIFFFetchStripThing(TIFF *tif, TIFFDirEntry *dir, uint32_t nstrips,
+ uint64_t **lpp)
+{
+ static const char module[] = "TIFFFetchStripThing";
+ enum TIFFReadDirEntryErr err;
+ uint64_t *data;
+ err = TIFFReadDirEntryLong8ArrayWithLimit(tif, dir, &data, nstrips);
+ if (err != TIFFReadDirEntryErrOk)
+ {
+ const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag);
+ TIFFReadDirEntryOutputErr(tif, err, module,
+ fip ? fip->field_name : "unknown tagname", 0);
+ return (0);
+ }
+ if (dir->tdir_count < (uint64_t)nstrips)
+ {
+ uint64_t *resizeddata;
+ const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag);
+ const char *pszMax = getenv("LIBTIFF_STRILE_ARRAY_MAX_RESIZE_COUNT");
+ uint32_t max_nstrips = 1000000;
+ if (pszMax)
+ max_nstrips = (uint32_t)atoi(pszMax);
+ TIFFReadDirEntryOutputErr(tif, TIFFReadDirEntryErrCount, module,
+ fip ? fip->field_name : "unknown tagname",
+ (nstrips <= max_nstrips));
+
+ if (nstrips > max_nstrips)
+ {
+ _TIFFfreeExt(tif, data);
+ return (0);
+ }
+
+ resizeddata = (uint64_t *)_TIFFCheckMalloc(
+ tif, nstrips, sizeof(uint64_t), "for strip array");
+ if (resizeddata == 0)
+ {
+ _TIFFfreeExt(tif, data);
+ return (0);
+ }
+ 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));
+ _TIFFfreeExt(tif, data);
+ data = resizeddata;
+ }
+ *lpp = data;
+ return (1);
+}
+
+/*
+ * Fetch and set the SubjectDistance EXIF tag.
+ */
+static int TIFFFetchSubjectDistance(TIFF *tif, TIFFDirEntry *dir)
+{
+ static const char module[] = "TIFFFetchSubjectDistance";
+ enum TIFFReadDirEntryErr err;
+ UInt64Aligned_t m;
+ m.l = 0;
+ assert(sizeof(double) == 8);
+ assert(sizeof(uint64_t) == 8);
+ assert(sizeof(uint32_t) == 4);
+ if (dir->tdir_count != 1)
+ err = TIFFReadDirEntryErrCount;
+ else if (dir->tdir_type != TIFF_RATIONAL)
+ err = TIFFReadDirEntryErrType;
+ else
+ {
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ uint32_t offset;
+ offset = *(uint32_t *)(&dir->tdir_offset);
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&offset);
+ err = TIFFReadDirEntryData(tif, offset, 8, m.i);
+ }
+ else
+ {
+ m.l = dir->tdir_offset.toff_long8;
+ err = TIFFReadDirEntryErrOk;
+ }
+ }
+ if (err == TIFFReadDirEntryErrOk)
+ {
+ double n;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfLong(m.i, 2);
+ if (m.i[0] == 0)
+ n = 0.0;
+ else if (m.i[0] == 0xFFFFFFFF || m.i[1] == 0)
+ /*
+ * XXX: Numerator 0xFFFFFFFF means that we have infinite
+ * distance. Indicate that with a negative floating point
+ * SubjectDistance value.
+ */
+ n = -1.0;
+ else
+ n = (double)m.i[0] / (double)m.i[1];
+ return (TIFFSetField(tif, dir->tdir_tag, n));
+ }
+ else
+ {
+ TIFFReadDirEntryOutputErr(tif, err, module, "SubjectDistance", TRUE);
+ return (0);
+ }
+}
+
+static void allocChoppedUpStripArrays(TIFF *tif, uint32_t nstrips,
+ uint64_t stripbytes,
+ uint32_t rowsperstrip)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ uint64_t bytecount;
+ uint64_t offset;
+ uint64_t last_offset;
+ uint64_t last_bytecount;
+ uint32_t i;
+ uint64_t *newcounts;
+ uint64_t *newoffsets;
+
+ offset = TIFFGetStrileOffset(tif, 0);
+ last_offset = TIFFGetStrileOffset(tif, td->td_nstrips - 1);
+ last_bytecount = TIFFGetStrileByteCount(tif, td->td_nstrips - 1);
+ if (last_offset > UINT64_MAX - last_bytecount ||
+ last_offset + last_bytecount < offset)
+ {
+ return;
+ }
+ bytecount = last_offset + last_bytecount - offset;
+
+ newcounts =
+ (uint64_t *)_TIFFCheckMalloc(tif, nstrips, sizeof(uint64_t),
+ "for chopped \"StripByteCounts\" array");
+ newoffsets = (uint64_t *)_TIFFCheckMalloc(
+ tif, nstrips, sizeof(uint64_t), "for chopped \"StripOffsets\" array");
+ if (newcounts == NULL || newoffsets == NULL)
+ {
+ /*
+ * Unable to allocate new strip information, give up and use
+ * the original one strip information.
+ */
+ if (newcounts != NULL)
+ _TIFFfreeExt(tif, newcounts);
+ if (newoffsets != NULL)
+ _TIFFfreeExt(tif, newoffsets);
+ return;
+ }
+
+ /*
+ * Fill the strip information arrays with new bytecounts and offsets
+ * that reflect the broken-up format.
+ */
+ for (i = 0; i < nstrips; i++)
+ {
+ if (stripbytes > bytecount)
+ stripbytes = bytecount;
+ newcounts[i] = stripbytes;
+ newoffsets[i] = stripbytes ? offset : 0;
+ offset += stripbytes;
+ bytecount -= stripbytes;
+ }
+
+ /*
+ * Replace old single strip info with multi-strip info.
+ */
+ td->td_stripsperimage = td->td_nstrips = nstrips;
+ TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
+
+ _TIFFfreeExt(tif, td->td_stripbytecount_p);
+ _TIFFfreeExt(tif, td->td_stripoffset_p);
+ td->td_stripbytecount_p = newcounts;
+ td->td_stripoffset_p = newoffsets;
+#ifdef STRIPBYTECOUNTSORTED_UNUSED
+ td->td_stripbytecountsorted = 1;
+#endif
+ tif->tif_flags |= TIFF_CHOPPEDUPARRAYS;
+}
+
+/*
+ * Replace a single strip (tile) of uncompressed data by multiple strips
+ * (tiles), each approximately STRIP_SIZE_DEFAULT bytes. This is useful for
+ * dealing with large images or for dealing with machines with a limited
+ * amount memory.
+ */
+static void ChopUpSingleUncompressedStrip(TIFF *tif)
+{
+ register TIFFDirectory *td = &tif->tif_dir;
+ uint64_t bytecount;
+ uint64_t offset;
+ uint32_t rowblock;
+ uint64_t rowblockbytes;
+ uint64_t stripbytes;
+ uint32_t nstrips;
+ uint32_t rowsperstrip;
+
+ bytecount = TIFFGetStrileByteCount(tif, 0);
+ /* On a newly created file, just re-opened to be filled, we */
+ /* don't want strip chop to trigger as it is going to cause issues */
+ /* later ( StripOffsets and StripByteCounts improperly filled) . */
+ if (bytecount == 0 && tif->tif_mode != O_RDONLY)
+ return;
+ offset = TIFFGetStrileByteCount(tif, 0);
+ assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
+ if ((td->td_photometric == PHOTOMETRIC_YCBCR) && (!isUpSampled(tif)))
+ rowblock = td->td_ycbcrsubsampling[1];
+ else
+ rowblock = 1;
+ rowblockbytes = TIFFVTileSize64(tif, rowblock);
+ /*
+ * Make the rows hold at least one scanline, but fill specified amount
+ * of data if possible.
+ */
+ if (rowblockbytes > STRIP_SIZE_DEFAULT)
+ {
+ stripbytes = rowblockbytes;
+ rowsperstrip = rowblock;
+ }
+ else if (rowblockbytes > 0)
+ {
+ uint32_t rowblocksperstrip;
+ rowblocksperstrip = (uint32_t)(STRIP_SIZE_DEFAULT / rowblockbytes);
+ rowsperstrip = rowblocksperstrip * rowblock;
+ stripbytes = rowblocksperstrip * rowblockbytes;
+ }
+ else
+ return;
+
+ /*
+ * never increase the number of rows per strip
+ */
+ if (rowsperstrip >= td->td_rowsperstrip)
+ return;
+ nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip);
+ if (nstrips == 0)
+ return;
+
+ /* If we are going to allocate a lot of memory, make sure that the */
+ /* file is as big as needed */
+ if (tif->tif_mode == O_RDONLY && nstrips > 1000000 &&
+ (offset >= TIFFGetFileSize(tif) ||
+ stripbytes > (TIFFGetFileSize(tif) - offset) / (nstrips - 1)))
+ {
+ return;
+ }
+
+ allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip);
+}
+
+/*
+ * Replace a file with contiguous strips > 2 GB of uncompressed data by
+ * multiple smaller strips. This is useful for
+ * dealing with large images or for dealing with machines with a limited
+ * amount memory.
+ */
+static void TryChopUpUncompressedBigTiff(TIFF *tif)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ uint32_t rowblock;
+ uint64_t rowblockbytes;
+ uint32_t i;
+ uint64_t stripsize;
+ uint32_t rowblocksperstrip;
+ uint32_t rowsperstrip;
+ uint64_t stripbytes;
+ uint32_t nstrips;
+
+ stripsize = TIFFStripSize64(tif);
+
+ assert(tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG);
+ assert(tif->tif_dir.td_compression == COMPRESSION_NONE);
+ assert((tif->tif_flags & (TIFF_STRIPCHOP | TIFF_ISTILED)) ==
+ TIFF_STRIPCHOP);
+ assert(stripsize > 0x7FFFFFFFUL);
+
+ /* On a newly created file, just re-opened to be filled, we */
+ /* don't want strip chop to trigger as it is going to cause issues */
+ /* later ( StripOffsets and StripByteCounts improperly filled) . */
+ if (TIFFGetStrileByteCount(tif, 0) == 0 && tif->tif_mode != O_RDONLY)
+ return;
+
+ if ((td->td_photometric == PHOTOMETRIC_YCBCR) && (!isUpSampled(tif)))
+ rowblock = td->td_ycbcrsubsampling[1];
+ else
+ rowblock = 1;
+ rowblockbytes = TIFFVStripSize64(tif, rowblock);
+ if (rowblockbytes == 0 || rowblockbytes > 0x7FFFFFFFUL)
+ {
+ /* In case of file with gigantic width */
+ return;
+ }
+
+ /* Check that the strips are contiguous and of the expected size */
+ for (i = 0; i < td->td_nstrips; i++)
+ {
+ if (i == td->td_nstrips - 1)
+ {
+ if (TIFFGetStrileByteCount(tif, i) <
+ TIFFVStripSize64(tif,
+ td->td_imagelength - i * td->td_rowsperstrip))
+ {
+ return;
+ }
+ }
+ else
+ {
+ if (TIFFGetStrileByteCount(tif, i) != stripsize)
+ {
+ return;
+ }
+ if (i > 0 && TIFFGetStrileOffset(tif, i) !=
+ TIFFGetStrileOffset(tif, i - 1) +
+ TIFFGetStrileByteCount(tif, i - 1))
+ {
+ return;
+ }
+ }
+ }
+
+ /* Aim for 512 MB strips (that will still be manageable by 32 bit builds */
+ rowblocksperstrip = (uint32_t)(512 * 1024 * 1024 / rowblockbytes);
+ if (rowblocksperstrip == 0)
+ rowblocksperstrip = 1;
+ rowsperstrip = rowblocksperstrip * rowblock;
+ stripbytes = rowblocksperstrip * rowblockbytes;
+ assert(stripbytes <= 0x7FFFFFFFUL);
+
+ nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip);
+ if (nstrips == 0)
+ return;
+
+ /* If we are going to allocate a lot of memory, make sure that the */
+ /* file is as big as needed */
+ if (tif->tif_mode == O_RDONLY && nstrips > 1000000)
+ {
+ uint64_t last_offset = TIFFGetStrileOffset(tif, td->td_nstrips - 1);
+ uint64_t filesize = TIFFGetFileSize(tif);
+ uint64_t last_bytecount =
+ TIFFGetStrileByteCount(tif, td->td_nstrips - 1);
+ if (last_offset > filesize || last_bytecount > filesize - last_offset)
+ {
+ return;
+ }
+ }
+
+ allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip);
+}
+
+TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
+static uint64_t _TIFFUnsanitizedAddUInt64AndInt(uint64_t a, int b)
+{
+ return a + b;
+}
+
+/* Read the value of [Strip|Tile]Offset or [Strip|Tile]ByteCount around
+ * strip/tile of number strile. Also fetch the neighbouring values using a
+ * 4096 byte page size.
+ */
+static int _TIFFPartialReadStripArray(TIFF *tif, TIFFDirEntry *dirent,
+ int strile, uint64_t *panVals)
+{
+ static const char module[] = "_TIFFPartialReadStripArray";
+#define IO_CACHE_PAGE_SIZE 4096
+
+ size_t sizeofval;
+ const int bSwab = (tif->tif_flags & TIFF_SWAB) != 0;
+ int sizeofvalint;
+ uint64_t nBaseOffset;
+ uint64_t nOffset;
+ uint64_t nOffsetStartPage;
+ uint64_t nOffsetEndPage;
+ tmsize_t nToRead;
+ tmsize_t nRead;
+ uint64_t nLastStripOffset;
+ int iStartBefore;
+ int i;
+ const uint32_t arraySize = tif->tif_dir.td_stripoffsetbyteallocsize;
+ unsigned char buffer[2 * IO_CACHE_PAGE_SIZE];
+
+ assert(dirent->tdir_count > 4);
+
+ if (dirent->tdir_type == TIFF_SHORT)
+ {
+ sizeofval = sizeof(uint16_t);
+ }
+ else if (dirent->tdir_type == TIFF_LONG)
+ {
+ sizeofval = sizeof(uint32_t);
+ }
+ else if (dirent->tdir_type == TIFF_LONG8)
+ {
+ sizeofval = sizeof(uint64_t);
+ }
+ else if (dirent->tdir_type == TIFF_SLONG8)
+ {
+ /* Non conformant but used by some images as in */
+ /* https://github.com/OSGeo/gdal/issues/2165 */
+ sizeofval = sizeof(int64_t);
+ }
+ else
+ {
+ TIFFErrorExtR(tif, module,
+ "Invalid type for [Strip|Tile][Offset/ByteCount] tag");
+ panVals[strile] = 0;
+ return 0;
+ }
+ sizeofvalint = (int)(sizeofval);
+
+ if (tif->tif_flags & TIFF_BIGTIFF)
+ {
+ uint64_t offset = dirent->tdir_offset.toff_long8;
+ if (bSwab)
+ TIFFSwabLong8(&offset);
+ nBaseOffset = offset;
+ }
+ else
+ {
+ uint32_t offset = dirent->tdir_offset.toff_long;
+ if (bSwab)
+ TIFFSwabLong(&offset);
+ nBaseOffset = offset;
+ }
+ /* To avoid later unsigned integer overflows */
+ if (nBaseOffset > (uint64_t)INT64_MAX)
+ {
+ TIFFErrorExtR(tif, module, "Cannot read offset/size for strile %d",
+ strile);
+ panVals[strile] = 0;
+ return 0;
+ }
+ nOffset = nBaseOffset + sizeofval * strile;
+ nOffsetStartPage = (nOffset / IO_CACHE_PAGE_SIZE) * IO_CACHE_PAGE_SIZE;
+ nOffsetEndPage = nOffsetStartPage + IO_CACHE_PAGE_SIZE;
+
+ if (nOffset + sizeofval > nOffsetEndPage)
+ nOffsetEndPage += IO_CACHE_PAGE_SIZE;
+#undef IO_CACHE_PAGE_SIZE
+
+ nLastStripOffset = nBaseOffset + arraySize * sizeofval;
+ if (nLastStripOffset < nOffsetEndPage)
+ nOffsetEndPage = nLastStripOffset;
+ if (nOffsetStartPage >= nOffsetEndPage)
+ {
+ TIFFErrorExtR(tif, module, "Cannot read offset/size for strile %d",
+ strile);
+ panVals[strile] = 0;
+ return 0;
+ }
+ if (!SeekOK(tif, nOffsetStartPage))
+ {
+ panVals[strile] = 0;
+ return 0;
+ }
+
+ nToRead = (tmsize_t)(nOffsetEndPage - nOffsetStartPage);
+ nRead = TIFFReadFile(tif, buffer, nToRead);
+ if (nRead < nToRead)
+ {
+ TIFFErrorExtR(tif, module,
+ "Cannot read offset/size for strile around ~%d", strile);
+ return 0;
+ }
+ iStartBefore = -(int)((nOffset - nOffsetStartPage) / sizeofval);
+ if (strile + iStartBefore < 0)
+ iStartBefore = -strile;
+ for (i = iStartBefore;
+ (uint32_t)(strile + i) < arraySize &&
+ _TIFFUnsanitizedAddUInt64AndInt(nOffset, (i + 1) * sizeofvalint) <=
+ nOffsetEndPage;
+ ++i)
+ {
+ if (dirent->tdir_type == TIFF_SHORT)
+ {
+ uint16_t val;
+ memcpy(&val,
+ buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
+ sizeof(val));
+ if (bSwab)
+ TIFFSwabShort(&val);
+ panVals[strile + i] = val;
+ }
+ else if (dirent->tdir_type == TIFF_LONG)
+ {
+ uint32_t val;
+ memcpy(&val,
+ buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
+ sizeof(val));
+ if (bSwab)
+ TIFFSwabLong(&val);
+ panVals[strile + i] = val;
+ }
+ else if (dirent->tdir_type == TIFF_LONG8)
+ {
+ uint64_t val;
+ memcpy(&val,
+ buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
+ sizeof(val));
+ if (bSwab)
+ TIFFSwabLong8(&val);
+ panVals[strile + i] = val;
+ }
+ else /* if( dirent->tdir_type == TIFF_SLONG8 ) */
+ {
+ /* Non conformant data type */
+ int64_t val;
+ memcpy(&val,
+ buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
+ sizeof(val));
+ if (bSwab)
+ TIFFSwabLong8((uint64_t *)&val);
+ panVals[strile + i] = (uint64_t)val;
+ }
+ }
+ return 1;
+}
+
+static int _TIFFFetchStrileValue(TIFF *tif, uint32_t strile,
+ TIFFDirEntry *dirent, uint64_t **parray)
+{
+ static const char module[] = "_TIFFFetchStrileValue";
+ TIFFDirectory *td = &tif->tif_dir;
+ if (strile >= dirent->tdir_count)
+ {
+ return 0;
+ }
+ if (strile >= td->td_stripoffsetbyteallocsize)
+ {
+ uint32_t nStripArrayAllocBefore = td->td_stripoffsetbyteallocsize;
+ uint32_t nStripArrayAllocNew;
+ uint64_t nArraySize64;
+ size_t nArraySize;
+ uint64_t *offsetArray;
+ uint64_t *bytecountArray;
+
+ if (strile > 1000000)
+ {
+ uint64_t filesize = TIFFGetFileSize(tif);
+ /* Avoid excessive memory allocation attempt */
+ /* For such a big blockid we need at least a TIFF_LONG per strile */
+ /* for the offset array. */
+ if (strile > filesize / sizeof(uint32_t))
+ {
+ TIFFErrorExtR(tif, module, "File too short");
+ return 0;
+ }
+ }
+
+ if (td->td_stripoffsetbyteallocsize == 0 &&
+ td->td_nstrips < 1024 * 1024)
+ {
+ nStripArrayAllocNew = td->td_nstrips;
+ }
+ else
+ {
+#define TIFF_MAX(a, b) (((a) > (b)) ? (a) : (b))
+#define TIFF_MIN(a, b) (((a) < (b)) ? (a) : (b))
+ nStripArrayAllocNew = TIFF_MAX(strile + 1, 1024U * 512U);
+ if (nStripArrayAllocNew < 0xFFFFFFFFU / 2)
+ nStripArrayAllocNew *= 2;
+ nStripArrayAllocNew = TIFF_MIN(nStripArrayAllocNew, td->td_nstrips);
+ }
+ assert(strile < nStripArrayAllocNew);
+ nArraySize64 = (uint64_t)sizeof(uint64_t) * nStripArrayAllocNew;
+ nArraySize = (size_t)(nArraySize64);
+#if SIZEOF_SIZE_T == 4
+ if (nArraySize != nArraySize64)
+ {
+ TIFFErrorExtR(tif, module,
+ "Cannot allocate strip offset and bytecount arrays");
+ return 0;
+ }
+#endif
+ offsetArray = (uint64_t *)(_TIFFreallocExt(tif, td->td_stripoffset_p,
+ nArraySize));
+ bytecountArray = (uint64_t *)(_TIFFreallocExt(
+ tif, td->td_stripbytecount_p, nArraySize));
+ if (offsetArray)
+ td->td_stripoffset_p = offsetArray;
+ if (bytecountArray)
+ td->td_stripbytecount_p = bytecountArray;
+ if (offsetArray && bytecountArray)
+ {
+ td->td_stripoffsetbyteallocsize = nStripArrayAllocNew;
+ /* Initialize new entries to ~0 / -1 */
+ /* coverity[overrun-buffer-arg] */
+ memset(td->td_stripoffset_p + nStripArrayAllocBefore, 0xFF,
+ (td->td_stripoffsetbyteallocsize - nStripArrayAllocBefore) *
+ sizeof(uint64_t));
+ /* coverity[overrun-buffer-arg] */
+ memset(td->td_stripbytecount_p + nStripArrayAllocBefore, 0xFF,
+ (td->td_stripoffsetbyteallocsize - nStripArrayAllocBefore) *
+ sizeof(uint64_t));
+ }
+ else
+ {
+ TIFFErrorExtR(tif, module,
+ "Cannot allocate strip offset and bytecount arrays");
+ _TIFFfreeExt(tif, td->td_stripoffset_p);
+ td->td_stripoffset_p = NULL;
+ _TIFFfreeExt(tif, td->td_stripbytecount_p);
+ td->td_stripbytecount_p = NULL;
+ td->td_stripoffsetbyteallocsize = 0;
+ }
+ }
+ if (*parray == NULL || strile >= td->td_stripoffsetbyteallocsize)
+ return 0;
+
+ if (~((*parray)[strile]) == 0)
+ {
+ if (!_TIFFPartialReadStripArray(tif, dirent, strile, *parray))
+ {
+ (*parray)[strile] = 0;
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static uint64_t _TIFFGetStrileOffsetOrByteCountValue(TIFF *tif, uint32_t strile,
+ TIFFDirEntry *dirent,
+ uint64_t **parray,
+ int *pbErr)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ if (pbErr)
+ *pbErr = 0;
+ if ((tif->tif_flags & TIFF_DEFERSTRILELOAD) &&
+ !(tif->tif_flags & TIFF_CHOPPEDUPARRAYS))
+ {
+ if (!(tif->tif_flags & TIFF_LAZYSTRILELOAD) ||
+ /* If the values may fit in the toff_long/toff_long8 member */
+ /* then use _TIFFFillStriles to simplify _TIFFFetchStrileValue */
+ dirent->tdir_count <= 4)
+ {
+ if (!_TIFFFillStriles(tif))
+ {
+ if (pbErr)
+ *pbErr = 1;
+ /* Do not return, as we want this function to always */
+ /* return the same value if called several times with */
+ /* the same arguments */
+ }
+ }
+ else
+ {
+ if (!_TIFFFetchStrileValue(tif, strile, dirent, parray))
+ {
+ if (pbErr)
+ *pbErr = 1;
+ return 0;
+ }
+ }
+ }
+ if (*parray == NULL || strile >= td->td_nstrips)
+ {
+ if (pbErr)
+ *pbErr = 1;
+ return 0;
+ }
+ return (*parray)[strile];
+}
+
+/* Return the value of the TileOffsets/StripOffsets array for the specified
+ * tile/strile */
+uint64_t TIFFGetStrileOffset(TIFF *tif, uint32_t strile)
+{
+ return TIFFGetStrileOffsetWithErr(tif, strile, NULL);
+}
+
+/* Return the value of the TileOffsets/StripOffsets array for the specified
+ * tile/strile */
+uint64_t TIFFGetStrileOffsetWithErr(TIFF *tif, uint32_t strile, int *pbErr)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ return _TIFFGetStrileOffsetOrByteCountValue(tif, strile,
+ &(td->td_stripoffset_entry),
+ &(td->td_stripoffset_p), pbErr);
+}
+
+/* Return the value of the TileByteCounts/StripByteCounts array for the
+ * specified tile/strile */
+uint64_t TIFFGetStrileByteCount(TIFF *tif, uint32_t strile)
+{
+ return TIFFGetStrileByteCountWithErr(tif, strile, NULL);
+}
+
+/* Return the value of the TileByteCounts/StripByteCounts array for the
+ * specified tile/strile */
+uint64_t TIFFGetStrileByteCountWithErr(TIFF *tif, uint32_t strile, int *pbErr)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ return _TIFFGetStrileOffsetOrByteCountValue(
+ tif, strile, &(td->td_stripbytecount_entry), &(td->td_stripbytecount_p),
+ pbErr);
+}
+
+int _TIFFFillStriles(TIFF *tif) { return _TIFFFillStrilesInternal(tif, 1); }
+
+static int _TIFFFillStrilesInternal(TIFF *tif, int loadStripByteCount)
+{
+ register TIFFDirectory *td = &tif->tif_dir;
+ int return_value = 1;
+
+ /* Do not do anything if TIFF_DEFERSTRILELOAD is not set */
+ if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD) ||
+ (tif->tif_flags & TIFF_CHOPPEDUPARRAYS) != 0)
+ return 1;
+
+ if (tif->tif_flags & TIFF_LAZYSTRILELOAD)
+ {
+ /* In case of lazy loading, reload completely the arrays */
+ _TIFFfreeExt(tif, td->td_stripoffset_p);
+ _TIFFfreeExt(tif, td->td_stripbytecount_p);
+ td->td_stripoffset_p = NULL;
+ td->td_stripbytecount_p = NULL;
+ td->td_stripoffsetbyteallocsize = 0;
+ tif->tif_flags &= ~TIFF_LAZYSTRILELOAD;
+ }
+
+ /* If stripoffset array is already loaded, exit with success */
+ if (td->td_stripoffset_p != NULL)
+ return 1;
+
+ /* If tdir_count was canceled, then we already got there, but in error */
+ if (td->td_stripoffset_entry.tdir_count == 0)
+ return 0;
+
+ if (!TIFFFetchStripThing(tif, &(td->td_stripoffset_entry), td->td_nstrips,
+ &td->td_stripoffset_p))
+ {
+ return_value = 0;
+ }
+
+ if (loadStripByteCount &&
+ !TIFFFetchStripThing(tif, &(td->td_stripbytecount_entry),
+ td->td_nstrips, &td->td_stripbytecount_p))
+ {
+ return_value = 0;
+ }
+
+ _TIFFmemset(&(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
+ _TIFFmemset(&(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
+
+#ifdef STRIPBYTECOUNTSORTED_UNUSED
+ if (tif->tif_dir.td_nstrips > 1 && return_value == 1)
+ {
+ uint32_t strip;
+
+ tif->tif_dir.td_stripbytecountsorted = 1;
+ for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++)
+ {
+ if (tif->tif_dir.td_stripoffset_p[strip - 1] >
+ tif->tif_dir.td_stripoffset_p[strip])
+ {
+ tif->tif_dir.td_stripbytecountsorted = 0;
+ break;
+ }
+ }
+ }
+#endif
+
+ return return_value;
+}
diff --git a/contrib/libs/libtiff/tif_dirwrite.c b/contrib/libs/libtiff/tif_dirwrite.c
new file mode 100644
index 0000000000..a6a485f862
--- /dev/null
+++ b/contrib/libs/libtiff/tif_dirwrite.c
@@ -0,0 +1,3613 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Directory Write Support Routines.
+ */
+#include "tiffiop.h"
+#include <float.h> /*--: for Rational2Double */
+#include <math.h> /*--: for Rational2Double */
+
+#ifdef HAVE_IEEEFP
+#define TIFFCvtNativeToIEEEFloat(tif, n, fp)
+#define TIFFCvtNativeToIEEEDouble(tif, n, dp)
+#else
+extern void TIFFCvtNativeToIEEEFloat(TIFF *tif, uint32_t n, float *fp);
+extern void TIFFCvtNativeToIEEEDouble(TIFF *tif, uint32_t n, double *dp);
+#endif
+
+static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
+ uint64_t *pdiroff);
+
+static int TIFFWriteDirectoryTagSampleformatArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag, uint32_t count,
+ double *value);
+
+static int TIFFWriteDirectoryTagAscii(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, char *value);
+static int TIFFWriteDirectoryTagUndefinedArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, uint8_t *value);
+static int TIFFWriteDirectoryTagByteArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, uint8_t *value);
+static int TIFFWriteDirectoryTagSbyteArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, int8_t *value);
+static int TIFFWriteDirectoryTagShort(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint16_t value);
+static int TIFFWriteDirectoryTagShortArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, uint16_t *value);
+static int TIFFWriteDirectoryTagShortPerSample(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint16_t value);
+static int TIFFWriteDirectoryTagSshortArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, int16_t *value);
+static int TIFFWriteDirectoryTagLong(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t value);
+static int TIFFWriteDirectoryTagLongArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, uint32_t *value);
+static int TIFFWriteDirectoryTagSlongArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, int32_t *value);
+static int TIFFWriteDirectoryTagLong8Array(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, uint64_t *value);
+static int TIFFWriteDirectoryTagSlong8Array(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, int64_t *value);
+static int TIFFWriteDirectoryTagRational(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ double value);
+static int TIFFWriteDirectoryTagRationalArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, float *value);
+static int TIFFWriteDirectoryTagSrationalArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, float *value);
+static int TIFFWriteDirectoryTagFloatArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, float *value);
+static int TIFFWriteDirectoryTagDoubleArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, double *value);
+static int TIFFWriteDirectoryTagIfdArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, uint32_t *value);
+static int TIFFWriteDirectoryTagShortLong(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t value);
+static int TIFFWriteDirectoryTagLongLong8Array(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, uint64_t *value);
+static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, uint64_t *value);
+static int TIFFWriteDirectoryTagColormap(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir);
+static int TIFFWriteDirectoryTagTransferfunction(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir);
+static int TIFFWriteDirectoryTagSubifd(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir);
+
+static int TIFFWriteDirectoryTagCheckedAscii(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, char *value);
+static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag,
+ uint32_t count,
+ uint8_t *value);
+static int TIFFWriteDirectoryTagCheckedByteArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag, uint32_t count,
+ uint8_t *value);
+static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag, uint32_t count,
+ int8_t *value);
+static int TIFFWriteDirectoryTagCheckedShort(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint16_t value);
+static int TIFFWriteDirectoryTagCheckedShortArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag, uint32_t count,
+ uint16_t *value);
+static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag, uint32_t count,
+ int16_t *value);
+static int TIFFWriteDirectoryTagCheckedLong(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t value);
+static int TIFFWriteDirectoryTagCheckedLongArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag, uint32_t count,
+ uint32_t *value);
+static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag, uint32_t count,
+ int32_t *value);
+static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag, uint32_t count,
+ uint64_t *value);
+static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag, uint32_t count,
+ int64_t *value);
+static int TIFFWriteDirectoryTagCheckedRational(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ double value);
+static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag,
+ uint32_t count,
+ float *value);
+static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag,
+ uint32_t count,
+ float *value);
+
+/*--: Rational2Double: New functions to support true double-precision for custom
+ * rational tag types. */
+static int TIFFWriteDirectoryTagRationalDoubleArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag,
+ uint32_t count,
+ double *value);
+static int TIFFWriteDirectoryTagSrationalDoubleArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag,
+ uint32_t count,
+ double *value);
+static int
+TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, double *value);
+static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray(
+ TIFF *tif, uint32_t *ndir, TIFFDirEntry *dir, uint16_t tag, uint32_t count,
+ double *value);
+static void DoubleToRational(double value, uint32_t *num, uint32_t *denom);
+static void DoubleToSrational(double value, int32_t *num, int32_t *denom);
+
+static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag, uint32_t count,
+ float *value);
+static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag, uint32_t count,
+ double *value);
+static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count,
+ uint32_t *value);
+static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag, uint32_t count,
+ uint64_t *value);
+
+static int TIFFWriteDirectoryTagData(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint16_t datatype, uint32_t count,
+ uint32_t datalength, void *data);
+
+static int TIFFLinkDirectory(TIFF *);
+
+/*
+ * Write the contents of the current directory
+ * to the specified file. This routine doesn't
+ * handle overwriting a directory with auxiliary
+ * storage that's been changed.
+ */
+int TIFFWriteDirectory(TIFF *tif)
+{
+ return TIFFWriteDirectorySec(tif, TRUE, TRUE, NULL);
+}
+
+/*
+ * This is an advanced writing function that must be used in a particular
+ * sequence, and generally together with TIFFForceStrileArrayWriting(),
+ * to make its intended effect. Its aim is to modify the location
+ * where the [Strip/Tile][Offsets/ByteCounts] arrays are located in the file.
+ * More precisely, when TIFFWriteCheck() will be called, the tag entries for
+ * those arrays will be written with type = count = offset = 0 as a temporary
+ * value.
+ *
+ * Its effect is only valid for the current directory, and before
+ * TIFFWriteDirectory() is first called, and will be reset when
+ * changing directory.
+ *
+ * The typical sequence of calls is:
+ * TIFFOpen()
+ * [ TIFFCreateDirectory(tif) ]
+ * Set fields with calls to TIFFSetField(tif, ...)
+ * TIFFDeferStrileArrayWriting(tif)
+ * TIFFWriteCheck(tif, ...)
+ * TIFFWriteDirectory(tif)
+ * ... potentially create other directories and come back to the above directory
+ * TIFFForceStrileArrayWriting(tif): emit the arrays at the end of file
+ *
+ * Returns 1 in case of success, 0 otherwise.
+ */
+int TIFFDeferStrileArrayWriting(TIFF *tif)
+{
+ static const char module[] = "TIFFDeferStrileArrayWriting";
+ if (tif->tif_mode == O_RDONLY)
+ {
+ TIFFErrorExtR(tif, tif->tif_name, "File opened in read-only mode");
+ return 0;
+ }
+ if (tif->tif_diroff != 0)
+ {
+ TIFFErrorExtR(tif, module, "Directory has already been written");
+ return 0;
+ }
+
+ tif->tif_dir.td_deferstrilearraywriting = TRUE;
+ return 1;
+}
+
+/*
+ * Similar to TIFFWriteDirectory(), writes the directory out
+ * but leaves all data structures in memory so that it can be
+ * written again. This will make a partially written TIFF file
+ * readable before it is successfully completed/closed.
+ */
+int TIFFCheckpointDirectory(TIFF *tif)
+{
+ int rc;
+ /* Setup the strips arrays, if they haven't already been. */
+ if (tif->tif_dir.td_stripoffset_p == NULL)
+ (void)TIFFSetupStrips(tif);
+ rc = TIFFWriteDirectorySec(tif, TRUE, FALSE, NULL);
+ (void)TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END));
+ return rc;
+}
+
+int TIFFWriteCustomDirectory(TIFF *tif, uint64_t *pdiroff)
+{
+ return TIFFWriteDirectorySec(tif, FALSE, FALSE, pdiroff);
+}
+
+/*
+ * Similar to TIFFWriteDirectory(), but if the directory has already
+ * been written once, it is relocated to the end of the file, in case it
+ * has changed in size. Note that this will result in the loss of the
+ * previously used directory space.
+ */
+int TIFFRewriteDirectory(TIFF *tif)
+{
+ static const char module[] = "TIFFRewriteDirectory";
+
+ /* We don't need to do anything special if it hasn't been written. */
+ if (tif->tif_diroff == 0)
+ return TIFFWriteDirectory(tif);
+
+ /*
+ * Find and zero the pointer to this directory, so that TIFFLinkDirectory
+ * will cause it to be added after this directories current pre-link.
+ */
+ uint64_t torewritediroff = tif->tif_diroff;
+
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ if (tif->tif_header.classic.tiff_diroff == tif->tif_diroff)
+ {
+ tif->tif_header.classic.tiff_diroff = 0;
+ tif->tif_diroff = 0;
+
+ TIFFSeekFile(tif, 4, SEEK_SET);
+ if (!WriteOK(tif, &(tif->tif_header.classic.tiff_diroff), 4))
+ {
+ TIFFErrorExtR(tif, tif->tif_name, "Error updating TIFF header");
+ return (0);
+ }
+ }
+ else if (tif->tif_diroff > 0xFFFFFFFFU)
+ {
+ TIFFErrorExtR(tif, module,
+ "tif->tif_diroff exceeds 32 bit range allowed for "
+ "Classic TIFF");
+ return (0);
+ }
+ else
+ {
+ uint32_t nextdir;
+ nextdir = tif->tif_header.classic.tiff_diroff;
+ while (1)
+ {
+ uint16_t dircount;
+ uint32_t nextnextdir;
+
+ if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount, 2))
+ {
+ TIFFErrorExtR(tif, module,
+ "Error fetching directory count");
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(&dircount);
+ (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET);
+ if (!ReadOK(tif, &nextnextdir, 4))
+ {
+ TIFFErrorExtR(tif, module, "Error fetching directory link");
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&nextnextdir);
+ if (nextnextdir == tif->tif_diroff)
+ {
+ uint32_t m;
+ m = 0;
+ (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12,
+ SEEK_SET);
+ if (!WriteOK(tif, &m, 4))
+ {
+ TIFFErrorExtR(tif, module,
+ "Error writing directory link");
+ return (0);
+ }
+ tif->tif_diroff = 0;
+ /* Force a full-traversal to reach the zeroed pointer */
+ tif->tif_lastdiroff = 0;
+ break;
+ }
+ nextdir = nextnextdir;
+ }
+ }
+ /* Remove skipped offset from IFD loop directory list. */
+ _TIFFRemoveEntryFromDirectoryListByOffset(tif, torewritediroff);
+ }
+ else
+ {
+ if (tif->tif_header.big.tiff_diroff == tif->tif_diroff)
+ {
+ tif->tif_header.big.tiff_diroff = 0;
+ tif->tif_diroff = 0;
+
+ TIFFSeekFile(tif, 8, SEEK_SET);
+ if (!WriteOK(tif, &(tif->tif_header.big.tiff_diroff), 8))
+ {
+ TIFFErrorExtR(tif, tif->tif_name, "Error updating TIFF header");
+ return (0);
+ }
+ }
+ else
+ {
+ uint64_t nextdir;
+ nextdir = tif->tif_header.big.tiff_diroff;
+ while (1)
+ {
+ uint64_t dircount64;
+ uint16_t dircount;
+ uint64_t nextnextdir;
+
+ if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount64, 8))
+ {
+ TIFFErrorExtR(tif, module,
+ "Error fetching directory count");
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&dircount64);
+ if (dircount64 > 0xFFFF)
+ {
+ TIFFErrorExtR(tif, module,
+ "Sanity check on tag count failed, likely "
+ "corrupt TIFF");
+ return (0);
+ }
+ dircount = (uint16_t)dircount64;
+ (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET);
+ if (!ReadOK(tif, &nextnextdir, 8))
+ {
+ TIFFErrorExtR(tif, module, "Error fetching directory link");
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&nextnextdir);
+ if (nextnextdir == tif->tif_diroff)
+ {
+ uint64_t m;
+ m = 0;
+ (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20,
+ SEEK_SET);
+ if (!WriteOK(tif, &m, 8))
+ {
+ TIFFErrorExtR(tif, module,
+ "Error writing directory link");
+ return (0);
+ }
+ tif->tif_diroff = 0;
+ /* Force a full-traversal to reach the zeroed pointer */
+ tif->tif_lastdiroff = 0;
+ break;
+ }
+ nextdir = nextnextdir;
+ }
+ }
+ /* Remove skipped offset from IFD loop directory list. */
+ _TIFFRemoveEntryFromDirectoryListByOffset(tif, torewritediroff);
+ }
+
+ /*
+ * Now use TIFFWriteDirectory() normally.
+ */
+
+ return TIFFWriteDirectory(tif);
+}
+
+static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
+ uint64_t *pdiroff)
+{
+ static const char module[] = "TIFFWriteDirectorySec";
+ uint32_t ndir;
+ TIFFDirEntry *dir;
+ uint32_t dirsize;
+ void *dirmem;
+ uint32_t m;
+ if (tif->tif_mode == O_RDONLY)
+ return (1);
+
+ _TIFFFillStriles(tif);
+
+ /*
+ * Clear write state so that subsequent images with
+ * different characteristics get the right buffers
+ * setup for them.
+ */
+ if (imagedone)
+ {
+ if (tif->tif_flags & TIFF_POSTENCODE)
+ {
+ tif->tif_flags &= ~TIFF_POSTENCODE;
+ if (!(*tif->tif_postencode)(tif))
+ {
+ TIFFErrorExtR(tif, module,
+ "Error post-encoding before directory write");
+ return (0);
+ }
+ }
+ (*tif->tif_close)(tif); /* shutdown encoder */
+ /*
+ * Flush any data that might have been written
+ * by the compression close+cleanup routines. But
+ * be careful not to write stuff if we didn't add data
+ * in the previous steps as the "rawcc" data may well be
+ * a previously read tile/strip in mixed read/write mode.
+ */
+ if (tif->tif_rawcc > 0 && (tif->tif_flags & TIFF_BEENWRITING) != 0)
+ {
+ if (!TIFFFlushData1(tif))
+ {
+ TIFFErrorExtR(tif, module,
+ "Error flushing data before directory write");
+ return (0);
+ }
+ }
+ if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
+ {
+ _TIFFfreeExt(tif, tif->tif_rawdata);
+ tif->tif_rawdata = NULL;
+ tif->tif_rawcc = 0;
+ tif->tif_rawdatasize = 0;
+ tif->tif_rawdataoff = 0;
+ tif->tif_rawdataloaded = 0;
+ }
+ tif->tif_flags &= ~(TIFF_BEENWRITING | TIFF_BUFFERSETUP);
+ }
+
+ if (TIFFFieldSet(tif, FIELD_COMPRESSION) &&
+ (tif->tif_dir.td_compression == COMPRESSION_DEFLATE))
+ {
+ TIFFWarningExtR(tif, module,
+ "Creating TIFF with legacy Deflate codec identifier, "
+ "COMPRESSION_ADOBE_DEFLATE is more widely supported");
+ }
+ dir = NULL;
+ dirmem = NULL;
+ dirsize = 0;
+ while (1)
+ {
+ ndir = 0;
+ if (isimage)
+ {
+ if (TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS))
+ {
+ if (!TIFFWriteDirectoryTagShortLong(tif, &ndir, dir,
+ TIFFTAG_IMAGEWIDTH,
+ tif->tif_dir.td_imagewidth))
+ goto bad;
+ if (!TIFFWriteDirectoryTagShortLong(
+ tif, &ndir, dir, TIFFTAG_IMAGELENGTH,
+ tif->tif_dir.td_imagelength))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_TILEDIMENSIONS))
+ {
+ if (!TIFFWriteDirectoryTagShortLong(tif, &ndir, dir,
+ TIFFTAG_TILEWIDTH,
+ tif->tif_dir.td_tilewidth))
+ goto bad;
+ if (!TIFFWriteDirectoryTagShortLong(tif, &ndir, dir,
+ TIFFTAG_TILELENGTH,
+ tif->tif_dir.td_tilelength))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_RESOLUTION))
+ {
+ if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir,
+ TIFFTAG_XRESOLUTION,
+ tif->tif_dir.td_xresolution))
+ goto bad;
+ if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir,
+ TIFFTAG_YRESOLUTION,
+ tif->tif_dir.td_yresolution))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_POSITION))
+ {
+ if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir,
+ TIFFTAG_XPOSITION,
+ tif->tif_dir.td_xposition))
+ goto bad;
+ if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir,
+ TIFFTAG_YPOSITION,
+ tif->tif_dir.td_yposition))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_SUBFILETYPE))
+ {
+ if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir,
+ TIFFTAG_SUBFILETYPE,
+ tif->tif_dir.td_subfiletype))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_BITSPERSAMPLE))
+ {
+ if (!TIFFWriteDirectoryTagShortPerSample(
+ tif, &ndir, dir, TIFFTAG_BITSPERSAMPLE,
+ tif->tif_dir.td_bitspersample))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_COMPRESSION))
+ {
+ if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
+ TIFFTAG_COMPRESSION,
+ tif->tif_dir.td_compression))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_PHOTOMETRIC))
+ {
+ if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
+ TIFFTAG_PHOTOMETRIC,
+ tif->tif_dir.td_photometric))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_THRESHHOLDING))
+ {
+ if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
+ TIFFTAG_THRESHHOLDING,
+ tif->tif_dir.td_threshholding))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_FILLORDER))
+ {
+ if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
+ TIFFTAG_FILLORDER,
+ tif->tif_dir.td_fillorder))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_ORIENTATION))
+ {
+ if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
+ TIFFTAG_ORIENTATION,
+ tif->tif_dir.td_orientation))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
+ {
+ if (!TIFFWriteDirectoryTagShort(
+ tif, &ndir, dir, TIFFTAG_SAMPLESPERPIXEL,
+ tif->tif_dir.td_samplesperpixel))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
+ {
+ if (!TIFFWriteDirectoryTagShortLong(
+ tif, &ndir, dir, TIFFTAG_ROWSPERSTRIP,
+ tif->tif_dir.td_rowsperstrip))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_MINSAMPLEVALUE))
+ {
+ if (!TIFFWriteDirectoryTagShortPerSample(
+ tif, &ndir, dir, TIFFTAG_MINSAMPLEVALUE,
+ tif->tif_dir.td_minsamplevalue))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE))
+ {
+ if (!TIFFWriteDirectoryTagShortPerSample(
+ tif, &ndir, dir, TIFFTAG_MAXSAMPLEVALUE,
+ tif->tif_dir.td_maxsamplevalue))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_PLANARCONFIG))
+ {
+ if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
+ TIFFTAG_PLANARCONFIG,
+ tif->tif_dir.td_planarconfig))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_RESOLUTIONUNIT))
+ {
+ if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
+ TIFFTAG_RESOLUTIONUNIT,
+ tif->tif_dir.td_resolutionunit))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_PAGENUMBER))
+ {
+ if (!TIFFWriteDirectoryTagShortArray(
+ tif, &ndir, dir, TIFFTAG_PAGENUMBER, 2,
+ &tif->tif_dir.td_pagenumber[0]))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS))
+ {
+ if (!isTiled(tif))
+ {
+ if (!TIFFWriteDirectoryTagLongLong8Array(
+ tif, &ndir, dir, TIFFTAG_STRIPBYTECOUNTS,
+ tif->tif_dir.td_nstrips,
+ tif->tif_dir.td_stripbytecount_p))
+ goto bad;
+ }
+ else
+ {
+ if (!TIFFWriteDirectoryTagLongLong8Array(
+ tif, &ndir, dir, TIFFTAG_TILEBYTECOUNTS,
+ tif->tif_dir.td_nstrips,
+ tif->tif_dir.td_stripbytecount_p))
+ goto bad;
+ }
+ }
+ if (TIFFFieldSet(tif, FIELD_STRIPOFFSETS))
+ {
+ if (!isTiled(tif))
+ {
+ /* td_stripoffset_p might be NULL in an odd OJPEG case. See
+ * tif_dirread.c around line 3634.
+ * XXX: OJPEG hack.
+ * If a) compression is OJPEG, b) it's not a tiled TIFF,
+ * 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.
+ * We can get here when using tiffset on such a file.
+ * See http://bugzilla.maptools.org/show_bug.cgi?id=2500
+ */
+ if (tif->tif_dir.td_stripoffset_p != NULL &&
+ !TIFFWriteDirectoryTagLongLong8Array(
+ tif, &ndir, dir, TIFFTAG_STRIPOFFSETS,
+ tif->tif_dir.td_nstrips,
+ tif->tif_dir.td_stripoffset_p))
+ goto bad;
+ }
+ else
+ {
+ if (!TIFFWriteDirectoryTagLongLong8Array(
+ tif, &ndir, dir, TIFFTAG_TILEOFFSETS,
+ tif->tif_dir.td_nstrips,
+ tif->tif_dir.td_stripoffset_p))
+ goto bad;
+ }
+ }
+ if (TIFFFieldSet(tif, FIELD_COLORMAP))
+ {
+ if (!TIFFWriteDirectoryTagColormap(tif, &ndir, dir))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_EXTRASAMPLES))
+ {
+ if (tif->tif_dir.td_extrasamples)
+ {
+ uint16_t na;
+ uint16_t *nb;
+ TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, &na, &nb);
+ if (!TIFFWriteDirectoryTagShortArray(
+ tif, &ndir, dir, TIFFTAG_EXTRASAMPLES, na, nb))
+ goto bad;
+ }
+ }
+ if (TIFFFieldSet(tif, FIELD_SAMPLEFORMAT))
+ {
+ if (!TIFFWriteDirectoryTagShortPerSample(
+ tif, &ndir, dir, TIFFTAG_SAMPLEFORMAT,
+ tif->tif_dir.td_sampleformat))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_SMINSAMPLEVALUE))
+ {
+ if (!TIFFWriteDirectoryTagSampleformatArray(
+ tif, &ndir, dir, TIFFTAG_SMINSAMPLEVALUE,
+ tif->tif_dir.td_samplesperpixel,
+ tif->tif_dir.td_sminsamplevalue))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_SMAXSAMPLEVALUE))
+ {
+ if (!TIFFWriteDirectoryTagSampleformatArray(
+ tif, &ndir, dir, TIFFTAG_SMAXSAMPLEVALUE,
+ tif->tif_dir.td_samplesperpixel,
+ tif->tif_dir.td_smaxsamplevalue))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_IMAGEDEPTH))
+ {
+ if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir,
+ TIFFTAG_IMAGEDEPTH,
+ tif->tif_dir.td_imagedepth))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_TILEDEPTH))
+ {
+ if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir,
+ TIFFTAG_TILEDEPTH,
+ tif->tif_dir.td_tiledepth))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_HALFTONEHINTS))
+ {
+ if (!TIFFWriteDirectoryTagShortArray(
+ tif, &ndir, dir, TIFFTAG_HALFTONEHINTS, 2,
+ &tif->tif_dir.td_halftonehints[0]))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_YCBCRSUBSAMPLING))
+ {
+ if (!TIFFWriteDirectoryTagShortArray(
+ tif, &ndir, dir, TIFFTAG_YCBCRSUBSAMPLING, 2,
+ &tif->tif_dir.td_ycbcrsubsampling[0]))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_YCBCRPOSITIONING))
+ {
+ if (!TIFFWriteDirectoryTagShort(
+ tif, &ndir, dir, TIFFTAG_YCBCRPOSITIONING,
+ tif->tif_dir.td_ycbcrpositioning))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_REFBLACKWHITE))
+ {
+ if (!TIFFWriteDirectoryTagRationalArray(
+ tif, &ndir, dir, TIFFTAG_REFERENCEBLACKWHITE, 6,
+ tif->tif_dir.td_refblackwhite))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_TRANSFERFUNCTION))
+ {
+ if (!TIFFWriteDirectoryTagTransferfunction(tif, &ndir, dir))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_INKNAMES))
+ {
+ if (!TIFFWriteDirectoryTagAscii(
+ tif, &ndir, dir, TIFFTAG_INKNAMES,
+ tif->tif_dir.td_inknameslen, tif->tif_dir.td_inknames))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS))
+ {
+ if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
+ TIFFTAG_NUMBEROFINKS,
+ tif->tif_dir.td_numberofinks))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif, FIELD_SUBIFD))
+ {
+ if (!TIFFWriteDirectoryTagSubifd(tif, &ndir, dir))
+ goto bad;
+ }
+ {
+ uint32_t n;
+ for (n = 0; n < tif->tif_nfields; n++)
+ {
+ const TIFFField *o;
+ o = tif->tif_fields[n];
+ if ((o->field_bit >= FIELD_CODEC) &&
+ (TIFFFieldSet(tif, o->field_bit)))
+ {
+ switch (o->get_field_type)
+ {
+ case TIFF_SETGET_ASCII:
+ {
+ uint32_t pa;
+ char *pb;
+ assert(o->field_type == TIFF_ASCII);
+ assert(o->field_readcount == TIFF_VARIABLE);
+ assert(o->field_passcount == 0);
+ TIFFGetField(tif, o->field_tag, &pb);
+ pa = (uint32_t)(strlen(pb));
+ if (!TIFFWriteDirectoryTagAscii(
+ tif, &ndir, dir, (uint16_t)o->field_tag,
+ pa, pb))
+ goto bad;
+ }
+ break;
+ case TIFF_SETGET_UINT16:
+ {
+ uint16_t p;
+ assert(o->field_type == TIFF_SHORT);
+ assert(o->field_readcount == 1);
+ assert(o->field_passcount == 0);
+ TIFFGetField(tif, o->field_tag, &p);
+ if (!TIFFWriteDirectoryTagShort(
+ tif, &ndir, dir, (uint16_t)o->field_tag,
+ p))
+ goto bad;
+ }
+ break;
+ case TIFF_SETGET_UINT32:
+ {
+ uint32_t p;
+ assert(o->field_type == TIFF_LONG);
+ assert(o->field_readcount == 1);
+ assert(o->field_passcount == 0);
+ TIFFGetField(tif, o->field_tag, &p);
+ if (!TIFFWriteDirectoryTagLong(
+ tif, &ndir, dir, (uint16_t)o->field_tag,
+ p))
+ goto bad;
+ }
+ break;
+ case TIFF_SETGET_C32_UINT8:
+ {
+ uint32_t pa;
+ void *pb;
+ assert(o->field_type == TIFF_UNDEFINED);
+ assert(o->field_readcount == TIFF_VARIABLE2);
+ assert(o->field_passcount == 1);
+ TIFFGetField(tif, o->field_tag, &pa, &pb);
+ if (!TIFFWriteDirectoryTagUndefinedArray(
+ tif, &ndir, dir, (uint16_t)o->field_tag,
+ pa, pb))
+ goto bad;
+ }
+ break;
+ default:
+ TIFFErrorExtR(
+ tif, module,
+ "Cannot write tag %" PRIu32 " (%s)",
+ TIFFFieldTag(o),
+ o->field_name ? o->field_name : "unknown");
+ goto bad;
+ }
+ }
+ }
+ }
+ }
+ for (m = 0; m < (uint32_t)(tif->tif_dir.td_customValueCount); m++)
+ {
+ uint16_t tag =
+ (uint16_t)tif->tif_dir.td_customValues[m].info->field_tag;
+ uint32_t count = tif->tif_dir.td_customValues[m].count;
+ switch (tif->tif_dir.td_customValues[m].info->field_type)
+ {
+ case TIFF_ASCII:
+ if (!TIFFWriteDirectoryTagAscii(
+ tif, &ndir, dir, tag, count,
+ tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_UNDEFINED:
+ if (!TIFFWriteDirectoryTagUndefinedArray(
+ tif, &ndir, dir, tag, count,
+ tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_BYTE:
+ if (!TIFFWriteDirectoryTagByteArray(
+ tif, &ndir, dir, tag, count,
+ tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_SBYTE:
+ if (!TIFFWriteDirectoryTagSbyteArray(
+ tif, &ndir, dir, tag, count,
+ tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_SHORT:
+ if (!TIFFWriteDirectoryTagShortArray(
+ tif, &ndir, dir, tag, count,
+ tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_SSHORT:
+ if (!TIFFWriteDirectoryTagSshortArray(
+ tif, &ndir, dir, tag, count,
+ tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_LONG:
+ if (!TIFFWriteDirectoryTagLongArray(
+ tif, &ndir, dir, tag, count,
+ tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_SLONG:
+ if (!TIFFWriteDirectoryTagSlongArray(
+ tif, &ndir, dir, tag, count,
+ tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_LONG8:
+ if (!TIFFWriteDirectoryTagLong8Array(
+ tif, &ndir, dir, tag, count,
+ tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_SLONG8:
+ if (!TIFFWriteDirectoryTagSlong8Array(
+ tif, &ndir, dir, tag, count,
+ tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_RATIONAL:
+ {
+ /*-- Rational2Double: For Rationals evaluate
+ * "set_field_type" to determine internal storage size. */
+ int tv_size;
+ 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;
+ }
+ else
+ {
+ /*-- default should be tv_size == 4 */
+ if (!TIFFWriteDirectoryTagRationalArray(
+ tif, &ndir, dir, tag, count,
+ tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ /*-- ToDo: After Testing, this should be removed and
+ * tv_size==4 should be set as default. */
+ if (tv_size != 4)
+ {
+ TIFFErrorExtR(tif,
+ "TIFFLib: _TIFFWriteDirectorySec()",
+ "Rational2Double: .set_field_type is "
+ "not 4 but %d",
+ tv_size);
+ }
+ }
+ }
+ break;
+ case TIFF_SRATIONAL:
+ {
+ /*-- Rational2Double: For Rationals evaluate
+ * "set_field_type" to determine internal storage size. */
+ int tv_size;
+ 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;
+ }
+ else
+ {
+ /*-- default should be tv_size == 4 */
+ if (!TIFFWriteDirectoryTagSrationalArray(
+ tif, &ndir, dir, tag, count,
+ tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ /*-- ToDo: After Testing, this should be removed and
+ * tv_size==4 should be set as default. */
+ if (tv_size != 4)
+ {
+ TIFFErrorExtR(tif,
+ "TIFFLib: _TIFFWriteDirectorySec()",
+ "Rational2Double: .set_field_type is "
+ "not 4 but %d",
+ tv_size);
+ }
+ }
+ }
+ break;
+ case TIFF_FLOAT:
+ if (!TIFFWriteDirectoryTagFloatArray(
+ tif, &ndir, dir, tag, count,
+ tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_DOUBLE:
+ if (!TIFFWriteDirectoryTagDoubleArray(
+ tif, &ndir, dir, tag, count,
+ tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_IFD:
+ if (!TIFFWriteDirectoryTagIfdArray(
+ tif, &ndir, dir, tag, count,
+ tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_IFD8:
+ if (!TIFFWriteDirectoryTagIfdIfd8Array(
+ tif, &ndir, dir, tag, count,
+ tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ default:
+ assert(0); /* we should never get here */
+ break;
+ }
+ }
+ if (dir != NULL)
+ break;
+ dir = _TIFFmallocExt(tif, ndir * sizeof(TIFFDirEntry));
+ if (dir == NULL)
+ {
+ TIFFErrorExtR(tif, module, "Out of memory");
+ goto bad;
+ }
+ if (isimage)
+ {
+ if ((tif->tif_diroff == 0) && (!TIFFLinkDirectory(tif)))
+ goto bad;
+ }
+ else
+ tif->tif_diroff =
+ (TIFFSeekFile(tif, 0, SEEK_END) + 1) & (~((toff_t)1));
+ if (pdiroff != NULL)
+ *pdiroff = tif->tif_diroff;
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ dirsize = 2 + ndir * 12 + 4;
+ else
+ dirsize = 8 + ndir * 20 + 8;
+ tif->tif_dataoff = tif->tif_diroff + dirsize;
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ tif->tif_dataoff = (uint32_t)tif->tif_dataoff;
+ if ((tif->tif_dataoff < tif->tif_diroff) ||
+ (tif->tif_dataoff < (uint64_t)dirsize))
+ {
+ TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
+ goto bad;
+ }
+ if (tif->tif_dataoff & 1)
+ tif->tif_dataoff++;
+ if (isimage)
+ {
+ if (tif->tif_curdir == TIFF_NON_EXISTENT_DIR_NUMBER)
+ tif->tif_curdir = 0;
+ else
+ tif->tif_curdir++;
+ }
+ }
+ if (isimage)
+ {
+ if (TIFFFieldSet(tif, FIELD_SUBIFD) && (tif->tif_subifdoff == 0))
+ {
+ uint32_t na;
+ TIFFDirEntry *nb;
+ for (na = 0, nb = dir;; na++, nb++)
+ {
+ if (na == ndir)
+ {
+ TIFFErrorExtR(tif, module, "Cannot find SubIFD tag");
+ goto bad;
+ }
+ if (nb->tdir_tag == TIFFTAG_SUBIFD)
+ break;
+ }
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ tif->tif_subifdoff = tif->tif_diroff + 2 + na * 12 + 8;
+ else
+ tif->tif_subifdoff = tif->tif_diroff + 8 + na * 20 + 12;
+ }
+ }
+ dirmem = _TIFFmallocExt(tif, dirsize);
+ if (dirmem == NULL)
+ {
+ TIFFErrorExtR(tif, module, "Out of memory");
+ goto bad;
+ }
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ uint8_t *n;
+ uint32_t nTmp;
+ TIFFDirEntry *o;
+ n = dirmem;
+ *(uint16_t *)n = (uint16_t)ndir;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort((uint16_t *)n);
+ n += 2;
+ o = dir;
+ for (m = 0; m < ndir; m++)
+ {
+ *(uint16_t *)n = o->tdir_tag;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort((uint16_t *)n);
+ n += 2;
+ *(uint16_t *)n = o->tdir_type;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort((uint16_t *)n);
+ n += 2;
+ nTmp = (uint32_t)o->tdir_count;
+ _TIFFmemcpy(n, &nTmp, 4);
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong((uint32_t *)n);
+ n += 4;
+ /* This is correct. The data has been */
+ /* swabbed previously in TIFFWriteDirectoryTagData */
+ _TIFFmemcpy(n, &o->tdir_offset, 4);
+ n += 4;
+ o++;
+ }
+ nTmp = (uint32_t)tif->tif_nextdiroff;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&nTmp);
+ _TIFFmemcpy(n, &nTmp, 4);
+ }
+ else
+ {
+ uint8_t *n;
+ TIFFDirEntry *o;
+ n = dirmem;
+ *(uint64_t *)n = ndir;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8((uint64_t *)n);
+ n += 8;
+ o = dir;
+ for (m = 0; m < ndir; m++)
+ {
+ *(uint16_t *)n = o->tdir_tag;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort((uint16_t *)n);
+ n += 2;
+ *(uint16_t *)n = o->tdir_type;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort((uint16_t *)n);
+ n += 2;
+ _TIFFmemcpy(n, &o->tdir_count, 8);
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8((uint64_t *)n);
+ n += 8;
+ _TIFFmemcpy(n, &o->tdir_offset, 8);
+ n += 8;
+ o++;
+ }
+ _TIFFmemcpy(n, &tif->tif_nextdiroff, 8);
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8((uint64_t *)n);
+ }
+ _TIFFfreeExt(tif, dir);
+ dir = NULL;
+ if (!SeekOK(tif, tif->tif_diroff))
+ {
+ TIFFErrorExtR(tif, module, "IO error writing directory");
+ goto bad;
+ }
+ if (!WriteOK(tif, dirmem, (tmsize_t)dirsize))
+ {
+ TIFFErrorExtR(tif, module, "IO error writing directory");
+ goto bad;
+ }
+ _TIFFfreeExt(tif, dirmem);
+ if (imagedone)
+ {
+ TIFFFreeDirectory(tif);
+ tif->tif_flags &= ~TIFF_DIRTYDIRECT;
+ tif->tif_flags &= ~TIFF_DIRTYSTRIP;
+ (*tif->tif_cleanup)(tif);
+ /*
+ * Reset directory-related state for subsequent
+ * directories.
+ */
+ TIFFCreateDirectory(tif);
+ }
+ return (1);
+bad:
+ if (dir != NULL)
+ _TIFFfreeExt(tif, dir);
+ if (dirmem != NULL)
+ _TIFFfreeExt(tif, dirmem);
+ return (0);
+}
+
+static int8_t TIFFClampDoubleToInt8(double val)
+{
+ if (val > 127)
+ return 127;
+ if (val < -128 || val != val)
+ return -128;
+ return (int8_t)val;
+}
+
+static int16_t TIFFClampDoubleToInt16(double val)
+{
+ if (val > 32767)
+ return 32767;
+ if (val < -32768 || val != val)
+ return -32768;
+ return (int16_t)val;
+}
+
+static int32_t TIFFClampDoubleToInt32(double val)
+{
+ if (val > 0x7FFFFFFF)
+ return 0x7FFFFFFF;
+ if (val < -0x7FFFFFFF - 1 || val != val)
+ return -0x7FFFFFFF - 1;
+ return (int32_t)val;
+}
+
+static uint8_t TIFFClampDoubleToUInt8(double val)
+{
+ if (val < 0)
+ return 0;
+ if (val > 255 || val != val)
+ return 255;
+ return (uint8_t)val;
+}
+
+static uint16_t TIFFClampDoubleToUInt16(double val)
+{
+ if (val < 0)
+ return 0;
+ if (val > 65535 || val != val)
+ return 65535;
+ return (uint16_t)val;
+}
+
+static uint32_t TIFFClampDoubleToUInt32(double val)
+{
+ if (val < 0)
+ return 0;
+ if (val > 0xFFFFFFFFU || val != val)
+ return 0xFFFFFFFFU;
+ return (uint32_t)val;
+}
+
+static int TIFFWriteDirectoryTagSampleformatArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag, uint32_t count,
+ double *value)
+{
+ static const char module[] = "TIFFWriteDirectoryTagSampleformatArray";
+ void *conv;
+ uint32_t i;
+ int ok;
+ conv = _TIFFmallocExt(tif, count * sizeof(double));
+ if (conv == NULL)
+ {
+ TIFFErrorExtR(tif, module, "Out of memory");
+ return (0);
+ }
+
+ switch (tif->tif_dir.td_sampleformat)
+ {
+ case SAMPLEFORMAT_IEEEFP:
+ if (tif->tif_dir.td_bitspersample <= 32)
+ {
+ for (i = 0; i < count; ++i)
+ ((float *)conv)[i] = _TIFFClampDoubleToFloat(value[i]);
+ ok = TIFFWriteDirectoryTagFloatArray(tif, ndir, dir, tag, count,
+ (float *)conv);
+ }
+ else
+ {
+ ok = TIFFWriteDirectoryTagDoubleArray(tif, ndir, dir, tag,
+ count, value);
+ }
+ break;
+ case SAMPLEFORMAT_INT:
+ if (tif->tif_dir.td_bitspersample <= 8)
+ {
+ for (i = 0; i < count; ++i)
+ ((int8_t *)conv)[i] = TIFFClampDoubleToInt8(value[i]);
+ ok = TIFFWriteDirectoryTagSbyteArray(tif, ndir, dir, tag, count,
+ (int8_t *)conv);
+ }
+ else if (tif->tif_dir.td_bitspersample <= 16)
+ {
+ for (i = 0; i < count; ++i)
+ ((int16_t *)conv)[i] = TIFFClampDoubleToInt16(value[i]);
+ ok = TIFFWriteDirectoryTagSshortArray(tif, ndir, dir, tag,
+ count, (int16_t *)conv);
+ }
+ else
+ {
+ for (i = 0; i < count; ++i)
+ ((int32_t *)conv)[i] = TIFFClampDoubleToInt32(value[i]);
+ ok = TIFFWriteDirectoryTagSlongArray(tif, ndir, dir, tag, count,
+ (int32_t *)conv);
+ }
+ break;
+ case SAMPLEFORMAT_UINT:
+ if (tif->tif_dir.td_bitspersample <= 8)
+ {
+ for (i = 0; i < count; ++i)
+ ((uint8_t *)conv)[i] = TIFFClampDoubleToUInt8(value[i]);
+ ok = TIFFWriteDirectoryTagByteArray(tif, ndir, dir, tag, count,
+ (uint8_t *)conv);
+ }
+ else if (tif->tif_dir.td_bitspersample <= 16)
+ {
+ for (i = 0; i < count; ++i)
+ ((uint16_t *)conv)[i] = TIFFClampDoubleToUInt16(value[i]);
+ ok = TIFFWriteDirectoryTagShortArray(tif, ndir, dir, tag, count,
+ (uint16_t *)conv);
+ }
+ else
+ {
+ for (i = 0; i < count; ++i)
+ ((uint32_t *)conv)[i] = TIFFClampDoubleToUInt32(value[i]);
+ ok = TIFFWriteDirectoryTagLongArray(tif, ndir, dir, tag, count,
+ (uint32_t *)conv);
+ }
+ break;
+ default:
+ ok = 0;
+ }
+
+ _TIFFfreeExt(tif, conv);
+ return (ok);
+}
+
+static int TIFFWriteDirectoryTagAscii(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, char *value)
+{
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+ return (
+ TIFFWriteDirectoryTagCheckedAscii(tif, ndir, dir, tag, count, value));
+}
+
+static int TIFFWriteDirectoryTagUndefinedArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, uint8_t *value)
+{
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+ return (TIFFWriteDirectoryTagCheckedUndefinedArray(tif, ndir, dir, tag,
+ count, value));
+}
+
+static int TIFFWriteDirectoryTagByteArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, uint8_t *value)
+{
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+ return (TIFFWriteDirectoryTagCheckedByteArray(tif, ndir, dir, tag, count,
+ value));
+}
+
+static int TIFFWriteDirectoryTagSbyteArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, int8_t *value)
+{
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+ return (TIFFWriteDirectoryTagCheckedSbyteArray(tif, ndir, dir, tag, count,
+ value));
+}
+
+static int TIFFWriteDirectoryTagShort(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint16_t value)
+{
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+ return (TIFFWriteDirectoryTagCheckedShort(tif, ndir, dir, tag, value));
+}
+
+static int TIFFWriteDirectoryTagShortArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, uint16_t *value)
+{
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+ return (TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, tag, count,
+ value));
+}
+
+static int TIFFWriteDirectoryTagShortPerSample(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint16_t value)
+{
+ static const char module[] = "TIFFWriteDirectoryTagShortPerSample";
+ uint16_t *m;
+ uint16_t *na;
+ uint16_t nb;
+ int o;
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+ m = _TIFFmallocExt(tif, tif->tif_dir.td_samplesperpixel * sizeof(uint16_t));
+ if (m == NULL)
+ {
+ TIFFErrorExtR(tif, module, "Out of memory");
+ return (0);
+ }
+ for (na = m, nb = 0; nb < tif->tif_dir.td_samplesperpixel; na++, nb++)
+ *na = value;
+ o = TIFFWriteDirectoryTagCheckedShortArray(
+ tif, ndir, dir, tag, tif->tif_dir.td_samplesperpixel, m);
+ _TIFFfreeExt(tif, m);
+ return (o);
+}
+
+static int TIFFWriteDirectoryTagSshortArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, int16_t *value)
+{
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+ return (TIFFWriteDirectoryTagCheckedSshortArray(tif, ndir, dir, tag, count,
+ value));
+}
+
+static int TIFFWriteDirectoryTagLong(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t value)
+{
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+ return (TIFFWriteDirectoryTagCheckedLong(tif, ndir, dir, tag, value));
+}
+
+static int TIFFWriteDirectoryTagLongArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, uint32_t *value)
+{
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+ return (TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count,
+ value));
+}
+
+static int TIFFWriteDirectoryTagSlongArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, int32_t *value)
+{
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+ return (TIFFWriteDirectoryTagCheckedSlongArray(tif, ndir, dir, tag, count,
+ value));
+}
+
+/************************************************************************/
+/* TIFFWriteDirectoryTagLong8Array() */
+/* */
+/* Write either Long8 or Long array depending on file type. */
+/************************************************************************/
+static int TIFFWriteDirectoryTagLong8Array(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, uint64_t *value)
+{
+ static const char module[] = "TIFFWriteDirectoryTagLong8Array";
+ uint64_t *ma;
+ uint32_t mb;
+ uint32_t *p;
+ uint32_t *q;
+ int o;
+
+ /* is this just a counting pass? */
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+
+ /* We always write Long8 for BigTIFF, no checking needed. */
+ if (tif->tif_flags & TIFF_BIGTIFF)
+ return (TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag,
+ count, value));
+
+ /*
+ ** For classic tiff we want to verify everything is in range for long
+ ** and convert to long format.
+ */
+ p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
+ if (p == NULL)
+ {
+ TIFFErrorExtR(tif, module, "Out of memory");
+ return (0);
+ }
+
+ for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
+ {
+ if (*ma > 0xFFFFFFFF)
+ {
+ TIFFErrorExtR(tif, module,
+ "Attempt to write unsigned long value %" PRIu64
+ " larger than 0xFFFFFFFF for tag %d in Classic TIFF "
+ "file. TIFF file writing aborted",
+ *ma, tag);
+ _TIFFfreeExt(tif, p);
+ return (0);
+ }
+ *q = (uint32_t)(*ma);
+ }
+
+ o = TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count, p);
+ _TIFFfreeExt(tif, p);
+
+ return (o);
+}
+
+/************************************************************************/
+/* TIFFWriteDirectoryTagSlong8Array() */
+/* */
+/* Write either SLong8 or SLong array depending on file type. */
+/************************************************************************/
+static int TIFFWriteDirectoryTagSlong8Array(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, int64_t *value)
+{
+ static const char module[] = "TIFFWriteDirectoryTagSlong8Array";
+ int64_t *ma;
+ uint32_t mb;
+ int32_t *p;
+ int32_t *q;
+ int o;
+
+ /* is this just a counting pass? */
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+ /* We always write SLong8 for BigTIFF, no checking needed. */
+ if (tif->tif_flags & TIFF_BIGTIFF)
+ return (TIFFWriteDirectoryTagCheckedSlong8Array(tif, ndir, dir, tag,
+ count, value));
+
+ /*
+ ** For classic tiff we want to verify everything is in range for signed-long
+ ** and convert to signed-long format.
+ */
+ p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
+ if (p == NULL)
+ {
+ TIFFErrorExtR(tif, module, "Out of memory");
+ return (0);
+ }
+
+ for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
+ {
+ if (*ma > (2147483647))
+ {
+ TIFFErrorExtR(tif, module,
+ "Attempt to write signed long value %" PRIi64
+ " larger than 0x7FFFFFFF (2147483647) for tag %d in "
+ "Classic TIFF file. TIFF writing to file aborted",
+ *ma, tag);
+ _TIFFfreeExt(tif, p);
+ return (0);
+ }
+ else if (*ma < (-2147483647 - 1))
+ {
+ TIFFErrorExtR(tif, module,
+ "Attempt to write signed long value %" PRIi64
+ " smaller than 0x80000000 (-2147483648) for tag %d "
+ "in Classic TIFF file. TIFF writing to file aborted",
+ *ma, tag);
+ _TIFFfreeExt(tif, p);
+ return (0);
+ }
+ *q = (int32_t)(*ma);
+ }
+
+ o = TIFFWriteDirectoryTagCheckedSlongArray(tif, ndir, dir, tag, count, p);
+ _TIFFfreeExt(tif, p);
+
+ return (o);
+}
+
+static int TIFFWriteDirectoryTagRational(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ double value)
+{
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+ return (TIFFWriteDirectoryTagCheckedRational(tif, ndir, dir, tag, value));
+}
+
+static int TIFFWriteDirectoryTagRationalArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, float *value)
+{
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+ return (TIFFWriteDirectoryTagCheckedRationalArray(tif, ndir, dir, tag,
+ count, value));
+}
+
+static int TIFFWriteDirectoryTagSrationalArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, float *value)
+{
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+ return (TIFFWriteDirectoryTagCheckedSrationalArray(tif, ndir, dir, tag,
+ count, value));
+}
+
+/*-- Rational2Double: additional write functions */
+static int TIFFWriteDirectoryTagRationalDoubleArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag,
+ uint32_t count,
+ double *value)
+{
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+ return (TIFFWriteDirectoryTagCheckedRationalDoubleArray(tif, ndir, dir, tag,
+ count, value));
+}
+
+static int TIFFWriteDirectoryTagSrationalDoubleArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag,
+ uint32_t count,
+ double *value)
+{
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+ return (TIFFWriteDirectoryTagCheckedSrationalDoubleArray(
+ tif, ndir, dir, tag, count, value));
+}
+
+static int TIFFWriteDirectoryTagFloatArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, float *value)
+{
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+ return (TIFFWriteDirectoryTagCheckedFloatArray(tif, ndir, dir, tag, count,
+ value));
+}
+
+static int TIFFWriteDirectoryTagDoubleArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, double *value)
+{
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+ return (TIFFWriteDirectoryTagCheckedDoubleArray(tif, ndir, dir, tag, count,
+ value));
+}
+
+static int TIFFWriteDirectoryTagIfdArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, uint32_t *value)
+{
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+ return (TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, tag, count,
+ value));
+}
+
+static int TIFFWriteDirectoryTagShortLong(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t value)
+{
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+ if (value <= 0xFFFF)
+ return (TIFFWriteDirectoryTagCheckedShort(tif, ndir, dir, tag,
+ (uint16_t)value));
+ else
+ return (TIFFWriteDirectoryTagCheckedLong(tif, ndir, dir, tag, value));
+}
+
+static int _WriteAsType(TIFF *tif, uint64_t strile_size,
+ uint64_t uncompressed_threshold)
+{
+ const uint16_t compression = tif->tif_dir.td_compression;
+ if (compression == COMPRESSION_NONE)
+ {
+ return strile_size > uncompressed_threshold;
+ }
+ else if (compression == COMPRESSION_JPEG ||
+ compression == COMPRESSION_LZW ||
+ compression == COMPRESSION_ADOBE_DEFLATE ||
+ compression == COMPRESSION_DEFLATE ||
+ compression == COMPRESSION_LZMA ||
+ compression == COMPRESSION_LERC ||
+ compression == COMPRESSION_ZSTD ||
+ 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 */
+ /* This is overly pessismistic ! */
+ return strile_size >= uncompressed_threshold / 10;
+ }
+ return 1;
+}
+
+static int WriteAsLong8(TIFF *tif, uint64_t strile_size)
+{
+ return _WriteAsType(tif, strile_size, 0xFFFFFFFFU);
+}
+
+static int WriteAsLong4(TIFF *tif, uint64_t strile_size)
+{
+ return _WriteAsType(tif, strile_size, 0xFFFFU);
+}
+
+/************************************************************************/
+/* TIFFWriteDirectoryTagLongLong8Array() */
+/* */
+/* Write out LONG8 array and write a SHORT/LONG/LONG8 depending */
+/* on strile size and Classic/BigTIFF mode. */
+/************************************************************************/
+
+static int TIFFWriteDirectoryTagLongLong8Array(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, uint64_t *value)
+{
+ static const char module[] = "TIFFWriteDirectoryTagLongLong8Array";
+ int o;
+ int write_aslong4;
+
+ /* is this just a counting pass? */
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+
+ if (tif->tif_dir.td_deferstrilearraywriting)
+ {
+ return TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_NOTYPE, 0, 0,
+ NULL);
+ }
+
+ if (tif->tif_flags & TIFF_BIGTIFF)
+ {
+ int write_aslong8 = 1;
+ /* In the case of ByteCounts array, we may be able to write them on */
+ /* LONG if the strip/tilesize is not too big. */
+ /* Also do that for count > 1 in the case someone would want to create
+ */
+ /* a single-strip file with a growing height, in which case using */
+ /* LONG8 will be safer. */
+ if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
+ {
+ write_aslong8 = WriteAsLong8(tif, TIFFStripSize64(tif));
+ }
+ else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
+ {
+ write_aslong8 = WriteAsLong8(tif, TIFFTileSize64(tif));
+ }
+ if (write_aslong8)
+ {
+ return TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag,
+ count, value);
+ }
+ }
+
+ write_aslong4 = 1;
+ if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
+ {
+ write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif));
+ }
+ else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
+ {
+ write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif));
+ }
+ if (write_aslong4)
+ {
+ /*
+ ** For classic tiff we want to verify everything is in range for LONG
+ ** and convert to long format.
+ */
+
+ uint32_t *p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
+ uint32_t *q;
+ uint64_t *ma;
+ uint32_t mb;
+
+ if (p == NULL)
+ {
+ TIFFErrorExtR(tif, module, "Out of memory");
+ return (0);
+ }
+
+ for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
+ {
+ if (*ma > 0xFFFFFFFF)
+ {
+ TIFFErrorExtR(tif, module,
+ "Attempt to write value larger than 0xFFFFFFFF "
+ "in LONG array.");
+ _TIFFfreeExt(tif, p);
+ return (0);
+ }
+ *q = (uint32_t)(*ma);
+ }
+
+ o = TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count,
+ p);
+ _TIFFfreeExt(tif, p);
+ }
+ else
+ {
+ uint16_t *p = _TIFFmallocExt(tif, count * sizeof(uint16_t));
+ uint16_t *q;
+ uint64_t *ma;
+ uint32_t mb;
+
+ if (p == NULL)
+ {
+ TIFFErrorExtR(tif, module, "Out of memory");
+ return (0);
+ }
+
+ for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
+ {
+ if (*ma > 0xFFFF)
+ {
+ /* Should not happen normally given the check we did before */
+ TIFFErrorExtR(tif, module,
+ "Attempt to write value larger than 0xFFFF in "
+ "SHORT array.");
+ _TIFFfreeExt(tif, p);
+ return (0);
+ }
+ *q = (uint16_t)(*ma);
+ }
+
+ o = TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, tag, count,
+ p);
+ _TIFFfreeExt(tif, p);
+ }
+
+ return (o);
+}
+
+/************************************************************************/
+/* TIFFWriteDirectoryTagIfdIfd8Array() */
+/* */
+/* Write either IFD8 or IFD array depending on file type. */
+/************************************************************************/
+
+static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, uint64_t *value)
+{
+ static const char module[] = "TIFFWriteDirectoryTagIfdIfd8Array";
+ uint64_t *ma;
+ uint32_t mb;
+ uint32_t *p;
+ uint32_t *q;
+ int o;
+
+ /* is this just a counting pass? */
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+
+ /* We always write IFD8 for BigTIFF, no checking needed. */
+ if (tif->tif_flags & TIFF_BIGTIFF)
+ return TIFFWriteDirectoryTagCheckedIfd8Array(tif, ndir, dir, tag, count,
+ value);
+
+ /*
+ ** For classic tiff we want to verify everything is in range for IFD
+ ** and convert to long format.
+ */
+
+ p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
+ if (p == NULL)
+ {
+ TIFFErrorExtR(tif, module, "Out of memory");
+ return (0);
+ }
+
+ for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
+ {
+ if (*ma > 0xFFFFFFFF)
+ {
+ TIFFErrorExtR(tif, module,
+ "Attempt to write value larger than 0xFFFFFFFF in "
+ "Classic TIFF file.");
+ _TIFFfreeExt(tif, p);
+ return (0);
+ }
+ *q = (uint32_t)(*ma);
+ }
+
+ o = TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, tag, count, p);
+ _TIFFfreeExt(tif, p);
+
+ return (o);
+}
+
+static int TIFFWriteDirectoryTagColormap(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir)
+{
+ static const char module[] = "TIFFWriteDirectoryTagColormap";
+ uint32_t m;
+ uint16_t *n;
+ int o;
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+ m = (1 << tif->tif_dir.td_bitspersample);
+ n = _TIFFmallocExt(tif, 3 * m * sizeof(uint16_t));
+ if (n == NULL)
+ {
+ TIFFErrorExtR(tif, module, "Out of memory");
+ return (0);
+ }
+ _TIFFmemcpy(&n[0], tif->tif_dir.td_colormap[0], m * sizeof(uint16_t));
+ _TIFFmemcpy(&n[m], tif->tif_dir.td_colormap[1], m * sizeof(uint16_t));
+ _TIFFmemcpy(&n[2 * m], tif->tif_dir.td_colormap[2], m * sizeof(uint16_t));
+ o = TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, TIFFTAG_COLORMAP,
+ 3 * m, n);
+ _TIFFfreeExt(tif, n);
+ return (o);
+}
+
+static int TIFFWriteDirectoryTagTransferfunction(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir)
+{
+ static const char module[] = "TIFFWriteDirectoryTagTransferfunction";
+ uint32_t m;
+ uint16_t n;
+ uint16_t *o;
+ int p;
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+ m = (1 << tif->tif_dir.td_bitspersample);
+ n = tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples;
+ /*
+ * Check if the table can be written as a single column,
+ * or if it must be written as 3 columns. Note that we
+ * write a 3-column tag if there are 2 samples/pixel and
+ * a single column of data won't suffice--hmm.
+ */
+ if (n > 3)
+ n = 3;
+ if (n == 3)
+ {
+ if (tif->tif_dir.td_transferfunction[2] == NULL ||
+ !_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],
+ tif->tif_dir.td_transferfunction[2],
+ m * sizeof(uint16_t)))
+ n = 2;
+ }
+ if (n == 2)
+ {
+ if (tif->tif_dir.td_transferfunction[1] == NULL ||
+ !_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],
+ tif->tif_dir.td_transferfunction[1],
+ m * sizeof(uint16_t)))
+ n = 1;
+ }
+ if (n == 0)
+ n = 1;
+ o = _TIFFmallocExt(tif, n * m * sizeof(uint16_t));
+ if (o == NULL)
+ {
+ TIFFErrorExtR(tif, module, "Out of memory");
+ return (0);
+ }
+ _TIFFmemcpy(&o[0], tif->tif_dir.td_transferfunction[0],
+ m * sizeof(uint16_t));
+ if (n > 1)
+ _TIFFmemcpy(&o[m], tif->tif_dir.td_transferfunction[1],
+ m * sizeof(uint16_t));
+ if (n > 2)
+ _TIFFmemcpy(&o[2 * m], tif->tif_dir.td_transferfunction[2],
+ m * sizeof(uint16_t));
+ p = TIFFWriteDirectoryTagCheckedShortArray(
+ tif, ndir, dir, TIFFTAG_TRANSFERFUNCTION, n * m, o);
+ _TIFFfreeExt(tif, o);
+ return (p);
+}
+
+static int TIFFWriteDirectoryTagSubifd(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir)
+{
+ static const char module[] = "TIFFWriteDirectoryTagSubifd";
+ uint64_t m;
+ int n;
+ if (tif->tif_dir.td_nsubifd == 0)
+ return (1);
+ if (dir == NULL)
+ {
+ (*ndir)++;
+ return (1);
+ }
+ m = tif->tif_dataoff;
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ uint32_t *o;
+ uint64_t *pa;
+ uint32_t *pb;
+ uint16_t p;
+ o = _TIFFmallocExt(tif, tif->tif_dir.td_nsubifd * sizeof(uint32_t));
+ if (o == NULL)
+ {
+ TIFFErrorExtR(tif, module, "Out of memory");
+ return (0);
+ }
+ pa = tif->tif_dir.td_subifd;
+ pb = o;
+ for (p = 0; p < tif->tif_dir.td_nsubifd; p++)
+ {
+ assert(pa != 0);
+
+ /* Could happen if an classicTIFF has a SubIFD of type LONG8 (which
+ * is illegal) */
+ if (*pa > 0xFFFFFFFFUL)
+ {
+ TIFFErrorExtR(tif, module, "Illegal value for SubIFD tag");
+ _TIFFfreeExt(tif, o);
+ return (0);
+ }
+ *pb++ = (uint32_t)(*pa++);
+ }
+ n = TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, TIFFTAG_SUBIFD,
+ tif->tif_dir.td_nsubifd, o);
+ _TIFFfreeExt(tif, o);
+ }
+ else
+ n = TIFFWriteDirectoryTagCheckedIfd8Array(
+ tif, ndir, dir, TIFFTAG_SUBIFD, tif->tif_dir.td_nsubifd,
+ tif->tif_dir.td_subifd);
+ if (!n)
+ return (0);
+ /*
+ * Total hack: if this directory includes a SubIFD
+ * tag then force the next <n> directories to be
+ * written as ``sub directories'' of this one. This
+ * is used to write things like thumbnails and
+ * image masks that one wants to keep out of the
+ * normal directory linkage access mechanism.
+ */
+ tif->tif_flags |= TIFF_INSUBIFD;
+ tif->tif_nsubifd = tif->tif_dir.td_nsubifd;
+ if (tif->tif_dir.td_nsubifd == 1)
+ tif->tif_subifdoff = 0;
+ else
+ tif->tif_subifdoff = m;
+ return (1);
+}
+
+static int TIFFWriteDirectoryTagCheckedAscii(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, char *value)
+{
+ assert(sizeof(char) == 1);
+ return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_ASCII, count,
+ count, value));
+}
+
+static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag,
+ uint32_t count,
+ uint8_t *value)
+{
+ assert(sizeof(uint8_t) == 1);
+ return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_UNDEFINED,
+ count, count, value));
+}
+
+static int TIFFWriteDirectoryTagCheckedByteArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag, uint32_t count,
+ uint8_t *value)
+{
+ assert(sizeof(uint8_t) == 1);
+ return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_BYTE, count,
+ count, value));
+}
+
+static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag, uint32_t count,
+ int8_t *value)
+{
+ assert(sizeof(int8_t) == 1);
+ return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SBYTE, count,
+ count, value));
+}
+
+static int TIFFWriteDirectoryTagCheckedShort(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint16_t value)
+{
+ uint16_t m;
+ assert(sizeof(uint16_t) == 2);
+ m = value;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(&m);
+ return (
+ TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SHORT, 1, 2, &m));
+}
+
+static int TIFFWriteDirectoryTagCheckedShortArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag, uint32_t count,
+ uint16_t *value)
+{
+ assert(count < 0x80000000);
+ assert(sizeof(uint16_t) == 2);
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfShort(value, count);
+ return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SHORT, count,
+ count * 2, value));
+}
+
+static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag, uint32_t count,
+ int16_t *value)
+{
+ assert(count < 0x80000000);
+ assert(sizeof(int16_t) == 2);
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfShort((uint16_t *)value, count);
+ return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SSHORT, count,
+ count * 2, value));
+}
+
+static int TIFFWriteDirectoryTagCheckedLong(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t value)
+{
+ uint32_t m;
+ assert(sizeof(uint32_t) == 4);
+ m = value;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&m);
+ return (
+ TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG, 1, 4, &m));
+}
+
+static int TIFFWriteDirectoryTagCheckedLongArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag, uint32_t count,
+ uint32_t *value)
+{
+ assert(count < 0x40000000);
+ assert(sizeof(uint32_t) == 4);
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfLong(value, count);
+ return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG, count,
+ count * 4, value));
+}
+
+static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag, uint32_t count,
+ int32_t *value)
+{
+ assert(count < 0x40000000);
+ assert(sizeof(int32_t) == 4);
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfLong((uint32_t *)value, count);
+ return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SLONG, count,
+ count * 4, value));
+}
+
+static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag, uint32_t count,
+ uint64_t *value)
+{
+ assert(count < 0x20000000);
+ assert(sizeof(uint64_t) == 8);
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ TIFFErrorExtR(tif, "TIFFWriteDirectoryTagCheckedLong8Array",
+ "LONG8 not allowed for ClassicTIFF");
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfLong8(value, count);
+ return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG8, count,
+ count * 8, value));
+}
+
+static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag, uint32_t count,
+ int64_t *value)
+{
+ assert(count < 0x20000000);
+ assert(sizeof(int64_t) == 8);
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ TIFFErrorExtR(tif, "TIFFWriteDirectoryTagCheckedSlong8Array",
+ "SLONG8 not allowed for ClassicTIFF");
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfLong8((uint64_t *)value, count);
+ return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SLONG8, count,
+ count * 8, value));
+}
+
+static int TIFFWriteDirectoryTagCheckedRational(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ double value)
+{
+ static const char module[] = "TIFFWriteDirectoryTagCheckedRational";
+ uint32_t m[2];
+ assert(sizeof(uint32_t) == 4);
+ if (value < 0)
+ {
+ TIFFErrorExtR(tif, module, "Negative value is illegal");
+ return 0;
+ }
+ else if (value != value)
+ {
+ TIFFErrorExtR(tif, module, "Not-a-number value is illegal");
+ return 0;
+ }
+ /*--Rational2Double: New function also used for non-custom rational tags.
+ * However, could be omitted here, because
+ * TIFFWriteDirectoryTagCheckedRational() is not used by code for custom
+ * tags, only by code for named-tiff-tags like FIELD_RESOLUTION and
+ * FIELD_POSITION */
+ else
+ {
+ DoubleToRational(value, &m[0], &m[1]);
+ }
+
+ if (tif->tif_flags & TIFF_SWAB)
+ {
+ TIFFSwabLong(&m[0]);
+ TIFFSwabLong(&m[1]);
+ }
+ return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, 1, 8,
+ &m[0]));
+}
+
+static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag,
+ uint32_t count,
+ float *value)
+{
+ static const char module[] = "TIFFWriteDirectoryTagCheckedRationalArray";
+ uint32_t *m;
+ float *na;
+ uint32_t *nb;
+ uint32_t nc;
+ int o;
+ assert(sizeof(uint32_t) == 4);
+ m = _TIFFmallocExt(tif, count * 2 * sizeof(uint32_t));
+ if (m == NULL)
+ {
+ TIFFErrorExtR(tif, module, "Out of memory");
+ return (0);
+ }
+ for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
+ {
+ DoubleToRational(*na, &nb[0], &nb[1]);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfLong(m, count * 2);
+ o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, count,
+ count * 8, &m[0]);
+ _TIFFfreeExt(tif, m);
+ return (o);
+}
+
+static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag,
+ uint32_t count,
+ float *value)
+{
+ static const char module[] = "TIFFWriteDirectoryTagCheckedSrationalArray";
+ int32_t *m;
+ float *na;
+ int32_t *nb;
+ uint32_t nc;
+ int o;
+ assert(sizeof(int32_t) == 4);
+ m = _TIFFmallocExt(tif, count * 2 * sizeof(int32_t));
+ if (m == NULL)
+ {
+ TIFFErrorExtR(tif, module, "Out of memory");
+ return (0);
+ }
+ for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
+ {
+ DoubleToSrational(*na, &nb[0], &nb[1]);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfLong((uint32_t *)m, count * 2);
+ o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SRATIONAL, count,
+ count * 8, &m[0]);
+ _TIFFfreeExt(tif, m);
+ return (o);
+}
+
+/*-- Rational2Double: additional write functions for double arrays */
+static int
+TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, double *value)
+{
+ static const char module[] =
+ "TIFFWriteDirectoryTagCheckedRationalDoubleArray";
+ uint32_t *m;
+ double *na;
+ uint32_t *nb;
+ uint32_t nc;
+ int o;
+ assert(sizeof(uint32_t) == 4);
+ m = _TIFFmallocExt(tif, count * 2 * sizeof(uint32_t));
+ if (m == NULL)
+ {
+ TIFFErrorExtR(tif, module, "Out of memory");
+ return (0);
+ }
+ for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
+ {
+ DoubleToRational(*na, &nb[0], &nb[1]);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfLong(m, count * 2);
+ o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, count,
+ count * 8, &m[0]);
+ _TIFFfreeExt(tif, m);
+ return (o);
+} /*-- TIFFWriteDirectoryTagCheckedRationalDoubleArray() ------- */
+
+static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray(
+ TIFF *tif, uint32_t *ndir, TIFFDirEntry *dir, uint16_t tag, uint32_t count,
+ double *value)
+{
+ static const char module[] =
+ "TIFFWriteDirectoryTagCheckedSrationalDoubleArray";
+ int32_t *m;
+ double *na;
+ int32_t *nb;
+ uint32_t nc;
+ int o;
+ assert(sizeof(int32_t) == 4);
+ m = _TIFFmallocExt(tif, count * 2 * sizeof(int32_t));
+ if (m == NULL)
+ {
+ TIFFErrorExtR(tif, module, "Out of memory");
+ return (0);
+ }
+ for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
+ {
+ DoubleToSrational(*na, &nb[0], &nb[1]);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfLong((uint32_t *)m, count * 2);
+ o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SRATIONAL, count,
+ count * 8, &m[0]);
+ _TIFFfreeExt(tif, m);
+ return (o);
+} /*--- TIFFWriteDirectoryTagCheckedSrationalDoubleArray() -------- */
+
+/** ----- Rational2Double: Double To Rational Conversion
+----------------------------------------------------------
+* There is a mathematical theorem to convert real numbers into a rational
+(integer fraction) number.
+* This is called "continuous fraction" which uses the Euclidean algorithm to
+find the greatest common divisor (GCD).
+* (ref. e.g. https://de.wikipedia.org/wiki/Kettenbruch or
+https://en.wikipedia.org/wiki/Continued_fraction
+* https://en.wikipedia.org/wiki/Euclidean_algorithm)
+* The following functions implement the
+* - ToRationalEuclideanGCD() auxiliary function which mainly
+implements euclidean GCD
+* - DoubleToRational() conversion function for un-signed
+rationals
+* - DoubleToSrational() conversion function for signed rationals
+------------------------------------------------------------------------------------------------------------------*/
+
+/**---- ToRationalEuclideanGCD() -----------------------------------------
+* Calculates the rational fractional of a double input value
+* using the Euclidean algorithm to find the greatest common divisor (GCD)
+------------------------------------------------------------------------*/
+static void ToRationalEuclideanGCD(double value, int blnUseSignedRange,
+ int blnUseSmallRange, uint64_t *ullNum,
+ uint64_t *ullDenom)
+{
+ /* Internally, the integer variables can be bigger than the external ones,
+ * as long as the result will fit into the external variable size.
+ */
+ uint64_t numSum[3] = {0, 1, 0}, denomSum[3] = {1, 0, 0};
+ uint64_t aux, bigNum, bigDenom;
+ uint64_t returnLimit;
+ int i;
+ uint64_t nMax;
+ double fMax;
+ unsigned long maxDenom;
+ /*-- nMax and fMax defines the initial accuracy of the starting fractional,
+ * or better, the highest used integer numbers used within the starting
+ * fractional (bigNum/bigDenom). There are two approaches, which can
+ * accidentally lead to different accuracies just depending on the value.
+ * Therefore, blnUseSmallRange steers this behavior.
+ * For long long nMax = ((9223372036854775807-1)/2); for long nMax =
+ * ((2147483647-1)/2);
+ */
+ if (blnUseSmallRange)
+ {
+ nMax = (uint64_t)((2147483647 - 1) / 2); /* for ULONG range */
+ }
+ else
+ {
+ nMax = ((9223372036854775807 - 1) / 2); /* for ULLONG range */
+ }
+ fMax = (double)nMax;
+
+ /*-- For the Euclidean GCD define the denominator range, so that it stays
+ * within size of unsigned long variables. maxDenom should be LONG_MAX for
+ * negative values and ULONG_MAX for positive ones. Also the final returned
+ * value of ullNum and ullDenom is limited according to signed- or
+ * unsigned-range.
+ */
+ if (blnUseSignedRange)
+ {
+ maxDenom = 2147483647UL; /*LONG_MAX = 0x7FFFFFFFUL*/
+ returnLimit = maxDenom;
+ }
+ else
+ {
+ maxDenom = 0xFFFFFFFFUL; /*ULONG_MAX = 0xFFFFFFFFUL*/
+ returnLimit = maxDenom;
+ }
+
+ /*-- First generate a rational fraction (bigNum/bigDenom) which represents
+ *the value as a rational number with the highest accuracy. Therefore,
+ *uint64_t (uint64_t) is needed. This rational fraction is then reduced
+ *using the Euclidean algorithm to find the greatest common divisor (GCD).
+ * bigNum = big numinator of value without fraction (or cut residual
+ *fraction) bigDenom = big denominator of value
+ *-- Break-criteria so that uint64_t cast to "bigNum" introduces no error
+ *and bigDenom has no overflow, and stop with enlargement of fraction when
+ *the double-value of it reaches an integer number without fractional part.
+ */
+ bigDenom = 1;
+ while ((value != floor(value)) && (value < fMax) && (bigDenom < nMax))
+ {
+ bigDenom <<= 1;
+ value *= 2;
+ }
+ bigNum = (uint64_t)value;
+
+ /*-- Start Euclidean algorithm to find the greatest common divisor (GCD) --
+ */
+#define MAX_ITERATIONS 64
+ for (i = 0; i < MAX_ITERATIONS; i++)
+ {
+ uint64_t val;
+ /* if bigDenom is not zero, calculate integer part of fraction. */
+ if (bigDenom == 0)
+ {
+ break;
+ }
+ val = bigNum / bigDenom;
+
+ /* Set bigDenom to reminder of bigNum/bigDenom and bigNum to previous
+ * denominator bigDenom. */
+ aux = bigNum;
+ bigNum = bigDenom;
+ bigDenom = aux % bigDenom;
+
+ /* calculate next denominator and check for its given maximum */
+ aux = val;
+ if (denomSum[1] * val + denomSum[0] >= maxDenom)
+ {
+ aux = (maxDenom - denomSum[0]) / denomSum[1];
+ if (aux * 2 >= val || denomSum[1] >= maxDenom)
+ i = (MAX_ITERATIONS +
+ 1); /* exit but execute rest of for-loop */
+ else
+ break;
+ }
+ /* calculate next numerator to numSum2 and save previous one to numSum0;
+ * numSum1 just copy of numSum2. */
+ numSum[2] = aux * numSum[1] + numSum[0];
+ numSum[0] = numSum[1];
+ numSum[1] = numSum[2];
+ /* calculate next denominator to denomSum2 and save previous one to
+ * denomSum0; denomSum1 just copy of denomSum2. */
+ denomSum[2] = aux * denomSum[1] + denomSum[0];
+ denomSum[0] = denomSum[1];
+ denomSum[1] = denomSum[2];
+ }
+
+ /*-- Check and adapt for final variable size and return values; reduces
+ * internal accuracy; denominator is kept in ULONG-range with maxDenom -- */
+ while (numSum[1] > returnLimit || denomSum[1] > returnLimit)
+ {
+ numSum[1] = numSum[1] / 2;
+ denomSum[1] = denomSum[1] / 2;
+ }
+
+ /* return values */
+ *ullNum = numSum[1];
+ *ullDenom = denomSum[1];
+
+} /*-- ToRationalEuclideanGCD() -------------- */
+
+/**---- DoubleToRational() -----------------------------------------------
+* Calculates the rational fractional of a double input value
+* for UN-SIGNED rationals,
+* using the Euclidean algorithm to find the greatest common divisor (GCD)
+------------------------------------------------------------------------*/
+static void DoubleToRational(double value, uint32_t *num, uint32_t *denom)
+{
+ /*---- UN-SIGNED RATIONAL ---- */
+ double dblDiff, dblDiff2;
+ uint64_t ullNum, ullDenom, ullNum2, ullDenom2;
+
+ /*-- Check for negative values. If so it is an error. */
+ /* Test written that way to catch NaN */
+ if (!(value >= 0))
+ {
+ *num = *denom = 0;
+ TIFFErrorExt(0, "TIFFLib: DoubleToRational()",
+ " Negative Value for Unsigned Rational given.");
+ return;
+ }
+
+ /*-- Check for too big numbers (> ULONG_MAX) -- */
+ if (value > 0xFFFFFFFFUL)
+ {
+ *num = 0xFFFFFFFFU;
+ *denom = 0;
+ return;
+ }
+ /*-- Check for easy integer numbers -- */
+ if (value == (uint32_t)(value))
+ {
+ *num = (uint32_t)value;
+ *denom = 1;
+ return;
+ }
+ /*-- Check for too small numbers for "unsigned long" type rationals -- */
+ if (value < 1.0 / (double)0xFFFFFFFFUL)
+ {
+ *num = 0;
+ *denom = 0xFFFFFFFFU;
+ return;
+ }
+
+ /*-- There are two approaches using the Euclidean algorithm,
+ * which can accidentally lead to different accuracies just depending on
+ * the value. Try both and define which one was better.
+ */
+ ToRationalEuclideanGCD(value, FALSE, FALSE, &ullNum, &ullDenom);
+ ToRationalEuclideanGCD(value, FALSE, TRUE, &ullNum2, &ullDenom2);
+ /*-- Double-Check, that returned values fit into ULONG :*/
+ if (ullNum > 0xFFFFFFFFUL || ullDenom > 0xFFFFFFFFUL ||
+ ullNum2 > 0xFFFFFFFFUL || ullDenom2 > 0xFFFFFFFFUL)
+ {
+ TIFFErrorExt(0, "TIFFLib: DoubleToRational()",
+ " Num or Denom exceeds ULONG: val=%14.6f, num=%12" PRIu64
+ ", denom=%12" PRIu64 " | num2=%12" PRIu64
+ ", denom2=%12" PRIu64 "",
+ value, ullNum, ullDenom, ullNum2, ullDenom2);
+ assert(0);
+ }
+
+ /* Check, which one has higher accuracy and take that. */
+ dblDiff = fabs(value - ((double)ullNum / (double)ullDenom));
+ dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2));
+ if (dblDiff < dblDiff2)
+ {
+ *num = (uint32_t)ullNum;
+ *denom = (uint32_t)ullDenom;
+ }
+ else
+ {
+ *num = (uint32_t)ullNum2;
+ *denom = (uint32_t)ullDenom2;
+ }
+} /*-- DoubleToRational() -------------- */
+
+/**---- DoubleToSrational() -----------------------------------------------
+* Calculates the rational fractional of a double input value
+* for SIGNED rationals,
+* using the Euclidean algorithm to find the greatest common divisor (GCD)
+------------------------------------------------------------------------*/
+static void DoubleToSrational(double value, int32_t *num, int32_t *denom)
+{
+ /*---- SIGNED RATIONAL ----*/
+ int neg = 1;
+ double dblDiff, dblDiff2;
+ uint64_t ullNum, ullDenom, ullNum2, ullDenom2;
+
+ /*-- Check for negative values and use then the positive one for internal
+ * calculations, but take the sign into account before returning. */
+ if (value < 0)
+ {
+ neg = -1;
+ value = -value;
+ }
+
+ /*-- Check for too big numbers (> LONG_MAX) -- */
+ if (value > 0x7FFFFFFFL)
+ {
+ *num = 0x7FFFFFFFL;
+ *denom = 0;
+ return;
+ }
+ /*-- Check for easy numbers -- */
+ if (value == (int32_t)(value))
+ {
+ *num = (int32_t)(neg * value);
+ *denom = 1;
+ return;
+ }
+ /*-- Check for too small numbers for "long" type rationals -- */
+ if (value < 1.0 / (double)0x7FFFFFFFL)
+ {
+ *num = 0;
+ *denom = 0x7FFFFFFFL;
+ return;
+ }
+
+ /*-- There are two approaches using the Euclidean algorithm,
+ * which can accidentally lead to different accuracies just depending on
+ * the value. Try both and define which one was better. Furthermore, set
+ * behavior of ToRationalEuclideanGCD() to the range of signed-long.
+ */
+ ToRationalEuclideanGCD(value, TRUE, FALSE, &ullNum, &ullDenom);
+ ToRationalEuclideanGCD(value, TRUE, TRUE, &ullNum2, &ullDenom2);
+ /*-- Double-Check, that returned values fit into LONG :*/
+ if (ullNum > 0x7FFFFFFFL || ullDenom > 0x7FFFFFFFL ||
+ ullNum2 > 0x7FFFFFFFL || ullDenom2 > 0x7FFFFFFFL)
+ {
+ TIFFErrorExt(0, "TIFFLib: DoubleToSrational()",
+ " Num or Denom exceeds LONG: val=%14.6f, num=%12" PRIu64
+ ", denom=%12" PRIu64 " | num2=%12" PRIu64
+ ", denom2=%12" PRIu64 "",
+ neg * value, ullNum, ullDenom, ullNum2, ullDenom2);
+ assert(0);
+ }
+
+ /* Check, which one has higher accuracy and take that. */
+ dblDiff = fabs(value - ((double)ullNum / (double)ullDenom));
+ dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2));
+ if (dblDiff < dblDiff2)
+ {
+ *num = (int32_t)(neg * (long)ullNum);
+ *denom = (int32_t)ullDenom;
+ }
+ else
+ {
+ *num = (int32_t)(neg * (long)ullNum2);
+ *denom = (int32_t)ullDenom2;
+ }
+} /*-- DoubleToSrational() --------------*/
+
+static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag, uint32_t count,
+ float *value)
+{
+ assert(count < 0x40000000);
+ assert(sizeof(float) == 4);
+ TIFFCvtNativeToIEEEFloat(tif, count, &value);
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfFloat(value, count);
+ return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_FLOAT, count,
+ count * 4, value));
+}
+
+static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag, uint32_t count,
+ double *value)
+{
+ assert(count < 0x20000000);
+ assert(sizeof(double) == 8);
+ TIFFCvtNativeToIEEEDouble(tif, count, &value);
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfDouble(value, count);
+ return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_DOUBLE, count,
+ count * 8, value));
+}
+
+static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint32_t count, uint32_t *value)
+{
+ assert(count < 0x40000000);
+ assert(sizeof(uint32_t) == 4);
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfLong(value, count);
+ return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_IFD, count,
+ count * 4, value));
+}
+
+static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir,
+ uint16_t tag, uint32_t count,
+ uint64_t *value)
+{
+ assert(count < 0x20000000);
+ assert(sizeof(uint64_t) == 8);
+ assert(tif->tif_flags & TIFF_BIGTIFF);
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfLong8(value, count);
+ return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_IFD8, count,
+ count * 8, value));
+}
+
+static int TIFFWriteDirectoryTagData(TIFF *tif, uint32_t *ndir,
+ TIFFDirEntry *dir, uint16_t tag,
+ uint16_t datatype, uint32_t count,
+ uint32_t datalength, void *data)
+{
+ static const char module[] = "TIFFWriteDirectoryTagData";
+ uint32_t m;
+ m = 0;
+ while (m < (*ndir))
+ {
+ assert(dir[m].tdir_tag != tag);
+ if (dir[m].tdir_tag > tag)
+ break;
+ m++;
+ }
+ if (m < (*ndir))
+ {
+ uint32_t n;
+ for (n = *ndir; n > m; n--)
+ dir[n] = dir[n - 1];
+ }
+ dir[m].tdir_tag = tag;
+ dir[m].tdir_type = datatype;
+ dir[m].tdir_count = count;
+ dir[m].tdir_offset.toff_long8 = 0;
+ if (datalength <= ((tif->tif_flags & TIFF_BIGTIFF) ? 0x8U : 0x4U))
+ {
+ if (data && datalength)
+ {
+ _TIFFmemcpy(&dir[m].tdir_offset, data, datalength);
+ }
+ }
+ else
+ {
+ uint64_t na, nb;
+ na = tif->tif_dataoff;
+ nb = na + datalength;
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ nb = (uint32_t)nb;
+ if ((nb < na) || (nb < datalength))
+ {
+ TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
+ return (0);
+ }
+ if (!SeekOK(tif, na))
+ {
+ TIFFErrorExtR(tif, module, "IO error writing tag data");
+ return (0);
+ }
+ if (datalength >= 0x80000000UL)
+ {
+ TIFFErrorExtR(tif, module,
+ "libtiff does not allow writing more than 2147483647 "
+ "bytes in a tag");
+ return (0);
+ }
+ if (!WriteOK(tif, data, (tmsize_t)datalength))
+ {
+ TIFFErrorExtR(tif, module, "IO error writing tag data");
+ return (0);
+ }
+ tif->tif_dataoff = nb;
+ if (tif->tif_dataoff & 1)
+ tif->tif_dataoff++;
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ uint32_t o;
+ o = (uint32_t)na;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&o);
+ _TIFFmemcpy(&dir[m].tdir_offset, &o, 4);
+ }
+ else
+ {
+ dir[m].tdir_offset.toff_long8 = na;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&dir[m].tdir_offset.toff_long8);
+ }
+ }
+ (*ndir)++;
+ return (1);
+}
+
+/*
+ * Link the current directory into the directory chain for the file.
+ */
+static int TIFFLinkDirectory(TIFF *tif)
+{
+ static const char module[] = "TIFFLinkDirectory";
+
+ tif->tif_diroff = (TIFFSeekFile(tif, 0, SEEK_END) + 1) & (~((toff_t)1));
+
+ /*
+ * Handle SubIFDs
+ */
+ if (tif->tif_flags & TIFF_INSUBIFD)
+ {
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ uint32_t m;
+ m = (uint32_t)tif->tif_diroff;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&m);
+ (void)TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
+ if (!WriteOK(tif, &m, 4))
+ {
+ TIFFErrorExtR(tif, module,
+ "Error writing SubIFD directory link");
+ return (0);
+ }
+ /*
+ * Advance to the next SubIFD or, if this is
+ * the last one configured, revert back to the
+ * normal directory linkage.
+ */
+ if (--tif->tif_nsubifd)
+ tif->tif_subifdoff += 4;
+ else
+ tif->tif_flags &= ~TIFF_INSUBIFD;
+ return (1);
+ }
+ else
+ {
+ uint64_t m;
+ m = tif->tif_diroff;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&m);
+ (void)TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
+ if (!WriteOK(tif, &m, 8))
+ {
+ TIFFErrorExtR(tif, module,
+ "Error writing SubIFD directory link");
+ return (0);
+ }
+ /*
+ * Advance to the next SubIFD or, if this is
+ * the last one configured, revert back to the
+ * normal directory linkage.
+ */
+ if (--tif->tif_nsubifd)
+ tif->tif_subifdoff += 8;
+ else
+ tif->tif_flags &= ~TIFF_INSUBIFD;
+ return (1);
+ }
+ }
+
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ uint32_t m;
+ uint32_t nextdir;
+ m = (uint32_t)(tif->tif_diroff);
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&m);
+ if (tif->tif_header.classic.tiff_diroff == 0)
+ {
+ /*
+ * 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))
+ {
+ TIFFErrorExtR(tif, tif->tif_name, "Error writing TIFF header");
+ return (0);
+ }
+ return (1);
+ }
+ /*
+ * Not the first directory, search to the last and append.
+ */
+ 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;
+
+ if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount, 2))
+ {
+ TIFFErrorExtR(tif, module, "Error fetching directory count");
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(&dircount);
+ (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET);
+ if (!ReadOK(tif, &nextnextdir, 4))
+ {
+ TIFFErrorExtR(tif, module, "Error fetching directory link");
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&nextnextdir);
+ if (nextnextdir == 0)
+ {
+ (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET);
+ if (!WriteOK(tif, &m, 4))
+ {
+ TIFFErrorExtR(tif, module, "Error writing directory link");
+ return (0);
+ }
+ tif->tif_lastdiroff = tif->tif_diroff;
+ break;
+ }
+ nextdir = nextnextdir;
+ }
+ }
+ else
+ {
+ uint64_t m;
+ uint64_t nextdir;
+ m = tif->tif_diroff;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&m);
+ if (tif->tif_header.big.tiff_diroff == 0)
+ {
+ /*
+ * 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))
+ {
+ TIFFErrorExtR(tif, tif->tif_name, "Error writing TIFF header");
+ return (0);
+ }
+ return (1);
+ }
+ /*
+ * Not the first directory, search to the last and append.
+ */
+ 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;
+ uint64_t nextnextdir;
+
+ if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount64, 8))
+ {
+ TIFFErrorExtR(tif, module, "Error fetching directory count");
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&dircount64);
+ if (dircount64 > 0xFFFF)
+ {
+ TIFFErrorExtR(
+ tif, module,
+ "Sanity check on tag count failed, likely corrupt TIFF");
+ return (0);
+ }
+ dircount = (uint16_t)dircount64;
+ (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET);
+ if (!ReadOK(tif, &nextnextdir, 8))
+ {
+ TIFFErrorExtR(tif, module, "Error fetching directory link");
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&nextnextdir);
+ if (nextnextdir == 0)
+ {
+ (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET);
+ if (!WriteOK(tif, &m, 8))
+ {
+ TIFFErrorExtR(tif, module, "Error writing directory link");
+ return (0);
+ }
+ tif->tif_lastdiroff = tif->tif_diroff;
+ break;
+ }
+ nextdir = nextnextdir;
+ }
+ }
+ return (1);
+}
+
+/************************************************************************/
+/* TIFFRewriteField() */
+/* */
+/* Rewrite a field in the directory on disk without regard to */
+/* updating the TIFF directory structure in memory. Currently */
+/* only supported for field that already exist in the on-disk */
+/* directory. Mainly used for updating stripoffset / */
+/* stripbytecount values after the directory is already on */
+/* disk. */
+/* */
+/* Returns zero on failure, and one on success. */
+/************************************************************************/
+
+int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype,
+ tmsize_t count, void *data)
+{
+ static const char module[] = "TIFFResetField";
+ /* const TIFFField* fip = NULL; */
+ uint16_t dircount;
+ tmsize_t dirsize;
+ uint8_t direntry_raw[20];
+ uint16_t entry_tag = 0;
+ uint16_t entry_type = 0;
+ uint64_t entry_count = 0;
+ uint64_t entry_offset = 0;
+ int value_in_entry = 0;
+ uint64_t read_offset;
+ uint8_t *buf_to_write = NULL;
+ TIFFDataType datatype;
+
+ /* -------------------------------------------------------------------- */
+ /* Find field definition. */
+ /* -------------------------------------------------------------------- */
+ /*fip =*/TIFFFindField(tif, tag, TIFF_ANY);
+
+ /* -------------------------------------------------------------------- */
+ /* Do some checking this is a straight forward case. */
+ /* -------------------------------------------------------------------- */
+ if (isMapped(tif))
+ {
+ TIFFErrorExtR(
+ tif, module,
+ "Memory mapped files not currently supported for this operation.");
+ return 0;
+ }
+
+ if (tif->tif_diroff == 0)
+ {
+ TIFFErrorExtR(
+ tif, module,
+ "Attempt to reset field on directory not already on disk.");
+ return 0;
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* Read the directory entry count. */
+ /* -------------------------------------------------------------------- */
+ if (!SeekOK(tif, tif->tif_diroff))
+ {
+ TIFFErrorExtR(tif, module, "%s: Seek error accessing TIFF directory",
+ tif->tif_name);
+ return 0;
+ }
+
+ read_offset = tif->tif_diroff;
+
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ if (!ReadOK(tif, &dircount, sizeof(uint16_t)))
+ {
+ TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory count",
+ tif->tif_name);
+ return 0;
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(&dircount);
+ dirsize = 12;
+ read_offset += 2;
+ }
+ else
+ {
+ uint64_t dircount64;
+ if (!ReadOK(tif, &dircount64, sizeof(uint64_t)))
+ {
+ TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory count",
+ tif->tif_name);
+ return 0;
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&dircount64);
+ dircount = (uint16_t)dircount64;
+ dirsize = 20;
+ read_offset += 8;
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* Read through directory to find target tag. */
+ /* -------------------------------------------------------------------- */
+ while (dircount > 0)
+ {
+ if (!ReadOK(tif, direntry_raw, dirsize))
+ {
+ TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory entry.",
+ tif->tif_name);
+ return 0;
+ }
+
+ memcpy(&entry_tag, direntry_raw + 0, sizeof(uint16_t));
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(&entry_tag);
+
+ if (entry_tag == tag)
+ break;
+
+ read_offset += dirsize;
+ }
+
+ if (entry_tag != tag)
+ {
+ TIFFErrorExtR(tif, module, "%s: Could not find tag %" PRIu16 ".",
+ tif->tif_name, tag);
+ return 0;
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* Extract the type, count and offset for this entry. */
+ /* -------------------------------------------------------------------- */
+ memcpy(&entry_type, direntry_raw + 2, sizeof(uint16_t));
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(&entry_type);
+
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ uint32_t value;
+
+ memcpy(&value, direntry_raw + 4, sizeof(uint32_t));
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&value);
+ entry_count = value;
+
+ memcpy(&value, direntry_raw + 8, sizeof(uint32_t));
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&value);
+ entry_offset = value;
+ }
+ else
+ {
+ memcpy(&entry_count, direntry_raw + 4, sizeof(uint64_t));
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&entry_count);
+
+ memcpy(&entry_offset, direntry_raw + 12, sizeof(uint64_t));
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&entry_offset);
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* When a dummy tag was written due to TIFFDeferStrileArrayWriting() */
+ /* -------------------------------------------------------------------- */
+ if (entry_offset == 0 && entry_count == 0 && entry_type == 0)
+ {
+ if (tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS)
+ {
+ entry_type =
+ (tif->tif_flags & TIFF_BIGTIFF) ? TIFF_LONG8 : TIFF_LONG;
+ }
+ else
+ {
+ int write_aslong8 = 1;
+ if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
+ {
+ write_aslong8 = WriteAsLong8(tif, TIFFStripSize64(tif));
+ }
+ else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
+ {
+ write_aslong8 = WriteAsLong8(tif, TIFFTileSize64(tif));
+ }
+ if (write_aslong8)
+ {
+ entry_type = TIFF_LONG8;
+ }
+ else
+ {
+ int write_aslong4 = 1;
+ if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
+ {
+ write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif));
+ }
+ else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
+ {
+ write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif));
+ }
+ if (write_aslong4)
+ {
+ entry_type = TIFF_LONG;
+ }
+ else
+ {
+ entry_type = TIFF_SHORT;
+ }
+ }
+ }
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* What data type do we want to write this as? */
+ /* -------------------------------------------------------------------- */
+ if (TIFFDataWidth(in_datatype) == 8 && !(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ if (in_datatype == TIFF_LONG8)
+ datatype = entry_type == TIFF_SHORT ? TIFF_SHORT : TIFF_LONG;
+ else if (in_datatype == TIFF_SLONG8)
+ datatype = TIFF_SLONG;
+ else if (in_datatype == TIFF_IFD8)
+ datatype = TIFF_IFD;
+ else
+ datatype = in_datatype;
+ }
+ else
+ {
+ if (in_datatype == TIFF_LONG8 &&
+ (entry_type == TIFF_SHORT || entry_type == TIFF_LONG ||
+ entry_type == TIFF_LONG8))
+ datatype = entry_type;
+ else if (in_datatype == TIFF_SLONG8 &&
+ (entry_type == TIFF_SLONG || entry_type == TIFF_SLONG8))
+ datatype = entry_type;
+ else if (in_datatype == TIFF_IFD8 &&
+ (entry_type == TIFF_IFD || entry_type == TIFF_IFD8))
+ datatype = entry_type;
+ else
+ datatype = in_datatype;
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* Prepare buffer of actual data to write. This includes */
+ /* swabbing as needed. */
+ /* -------------------------------------------------------------------- */
+ buf_to_write = (uint8_t *)_TIFFCheckMalloc(
+ tif, count, TIFFDataWidth(datatype), "for field buffer.");
+ if (!buf_to_write)
+ return 0;
+
+ if (datatype == in_datatype)
+ memcpy(buf_to_write, data, count * TIFFDataWidth(datatype));
+ else if (datatype == TIFF_SLONG && in_datatype == TIFF_SLONG8)
+ {
+ tmsize_t i;
+
+ for (i = 0; i < count; i++)
+ {
+ ((int32_t *)buf_to_write)[i] = (int32_t)((int64_t *)data)[i];
+ if ((int64_t)((int32_t *)buf_to_write)[i] != ((int64_t *)data)[i])
+ {
+ _TIFFfreeExt(tif, buf_to_write);
+ TIFFErrorExtR(tif, module,
+ "Value exceeds 32bit range of output type.");
+ return 0;
+ }
+ }
+ }
+ else if ((datatype == TIFF_LONG && in_datatype == TIFF_LONG8) ||
+ (datatype == TIFF_IFD && in_datatype == TIFF_IFD8))
+ {
+ tmsize_t i;
+
+ for (i = 0; i < count; i++)
+ {
+ ((uint32_t *)buf_to_write)[i] = (uint32_t)((uint64_t *)data)[i];
+ if ((uint64_t)((uint32_t *)buf_to_write)[i] !=
+ ((uint64_t *)data)[i])
+ {
+ _TIFFfreeExt(tif, buf_to_write);
+ TIFFErrorExtR(tif, module,
+ "Value exceeds 32bit range of output type.");
+ return 0;
+ }
+ }
+ }
+ else if (datatype == TIFF_SHORT && in_datatype == TIFF_LONG8)
+ {
+ tmsize_t i;
+
+ for (i = 0; i < count; i++)
+ {
+ ((uint16_t *)buf_to_write)[i] = (uint16_t)((uint64_t *)data)[i];
+ if ((uint64_t)((uint16_t *)buf_to_write)[i] !=
+ ((uint64_t *)data)[i])
+ {
+ _TIFFfreeExt(tif, buf_to_write);
+ TIFFErrorExtR(tif, module,
+ "Value exceeds 16bit range of output type.");
+ return 0;
+ }
+ }
+ }
+ else
+ {
+ TIFFErrorExtR(tif, module, "Unhandled type conversion.");
+ return 0;
+ }
+
+ if (TIFFDataWidth(datatype) > 1 && (tif->tif_flags & TIFF_SWAB))
+ {
+ if (TIFFDataWidth(datatype) == 2)
+ TIFFSwabArrayOfShort((uint16_t *)buf_to_write, count);
+ else if (TIFFDataWidth(datatype) == 4)
+ TIFFSwabArrayOfLong((uint32_t *)buf_to_write, count);
+ else if (TIFFDataWidth(datatype) == 8)
+ TIFFSwabArrayOfLong8((uint64_t *)buf_to_write, count);
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* Is this a value that fits into the directory entry? */
+ /* -------------------------------------------------------------------- */
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ if (TIFFDataWidth(datatype) * count <= 4)
+ {
+ entry_offset = read_offset + 8;
+ value_in_entry = 1;
+ }
+ }
+ else
+ {
+ if (TIFFDataWidth(datatype) * count <= 8)
+ {
+ entry_offset = read_offset + 12;
+ value_in_entry = 1;
+ }
+ }
+
+ if ((tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS) &&
+ tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0)
+ {
+ tif->tif_dir.td_stripoffset_entry.tdir_type = datatype;
+ tif->tif_dir.td_stripoffset_entry.tdir_count = count;
+ }
+ else if ((tag == TIFFTAG_TILEBYTECOUNTS ||
+ tag == TIFFTAG_STRIPBYTECOUNTS) &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0)
+ {
+ tif->tif_dir.td_stripbytecount_entry.tdir_type = datatype;
+ tif->tif_dir.td_stripbytecount_entry.tdir_count = count;
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* If the tag type, and count match, then we just write it out */
+ /* over the old values without altering the directory entry at */
+ /* all. */
+ /* -------------------------------------------------------------------- */
+ if (entry_count == (uint64_t)count && entry_type == (uint16_t)datatype)
+ {
+ if (!SeekOK(tif, entry_offset))
+ {
+ _TIFFfreeExt(tif, buf_to_write);
+ TIFFErrorExtR(tif, module,
+ "%s: Seek error accessing TIFF directory",
+ tif->tif_name);
+ return 0;
+ }
+ if (!WriteOK(tif, buf_to_write, count * TIFFDataWidth(datatype)))
+ {
+ _TIFFfreeExt(tif, buf_to_write);
+ TIFFErrorExtR(tif, module, "Error writing directory link");
+ return (0);
+ }
+
+ _TIFFfreeExt(tif, buf_to_write);
+ return 1;
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* Otherwise, we write the new tag data at the end of the file. */
+ /* -------------------------------------------------------------------- */
+ if (!value_in_entry)
+ {
+ entry_offset = TIFFSeekFile(tif, 0, SEEK_END);
+
+ if (!WriteOK(tif, buf_to_write, count * TIFFDataWidth(datatype)))
+ {
+ _TIFFfreeExt(tif, buf_to_write);
+ TIFFErrorExtR(tif, module, "Error writing directory link");
+ return (0);
+ }
+ }
+ else
+ {
+ 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));
+ }
+ }
+
+ _TIFFfreeExt(tif, buf_to_write);
+ buf_to_write = 0;
+
+ /* -------------------------------------------------------------------- */
+ /* Adjust the directory entry. */
+ /* -------------------------------------------------------------------- */
+ entry_type = datatype;
+ entry_count = (uint64_t)count;
+ memcpy(direntry_raw + 2, &entry_type, sizeof(uint16_t));
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort((uint16_t *)(direntry_raw + 2));
+
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ uint32_t value;
+
+ value = (uint32_t)entry_count;
+ memcpy(direntry_raw + 4, &value, sizeof(uint32_t));
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong((uint32_t *)(direntry_raw + 4));
+
+ value = (uint32_t)entry_offset;
+ memcpy(direntry_raw + 8, &value, sizeof(uint32_t));
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong((uint32_t *)(direntry_raw + 8));
+ }
+ else
+ {
+ memcpy(direntry_raw + 4, &entry_count, sizeof(uint64_t));
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8((uint64_t *)(direntry_raw + 4));
+
+ memcpy(direntry_raw + 12, &entry_offset, sizeof(uint64_t));
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8((uint64_t *)(direntry_raw + 12));
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* Write the directory entry out to disk. */
+ /* -------------------------------------------------------------------- */
+ if (!SeekOK(tif, read_offset))
+ {
+ TIFFErrorExtR(tif, module, "%s: Seek error accessing TIFF directory",
+ tif->tif_name);
+ return 0;
+ }
+
+ if (!WriteOK(tif, direntry_raw, dirsize))
+ {
+ TIFFErrorExtR(tif, module, "%s: Can not write TIFF directory entry.",
+ tif->tif_name);
+ return 0;
+ }
+
+ return 1;
+}
diff --git a/contrib/libs/libtiff/tif_dumpmode.c b/contrib/libs/libtiff/tif_dumpmode.c
new file mode 100644
index 0000000000..267d5d2d7a
--- /dev/null
+++ b/contrib/libs/libtiff/tif_dumpmode.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * "Null" Compression Algorithm Support.
+ */
+#include "tiffiop.h"
+
+static int DumpFixupTags(TIFF *tif)
+{
+ (void)tif;
+ return (1);
+}
+
+/*
+ * Encode a hunk of pixels.
+ */
+static int DumpModeEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
+{
+ (void)s;
+ while (cc > 0)
+ {
+ tmsize_t n;
+
+ n = cc;
+ if (tif->tif_rawcc + n > tif->tif_rawdatasize)
+ n = tif->tif_rawdatasize - tif->tif_rawcc;
+
+ assert(n > 0);
+
+ /*
+ * Avoid copy if client has setup raw
+ * data buffer to avoid extra copy.
+ */
+ if (tif->tif_rawcp != pp)
+ _TIFFmemcpy(tif->tif_rawcp, pp, n);
+ tif->tif_rawcp += n;
+ tif->tif_rawcc += n;
+ pp += n;
+ cc -= n;
+ if (tif->tif_rawcc >= tif->tif_rawdatasize && !TIFFFlushData1(tif))
+ return (0);
+ }
+ return (1);
+}
+
+/*
+ * Decode a hunk of pixels.
+ */
+static int DumpModeDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
+{
+ static const char module[] = "DumpModeDecode";
+ (void)s;
+ if (tif->tif_rawcc < cc)
+ {
+ TIFFErrorExtR(tif, module,
+ "Not enough data for scanline %" PRIu32
+ ", expected a request for at most %" TIFF_SSIZE_FORMAT
+ " bytes, got a request for %" TIFF_SSIZE_FORMAT " bytes",
+ tif->tif_row, tif->tif_rawcc, cc);
+ return (0);
+ }
+ /*
+ * Avoid copy if client has setup raw
+ * data buffer to avoid extra copy.
+ */
+ if (tif->tif_rawcp != buf)
+ _TIFFmemcpy(buf, tif->tif_rawcp, cc);
+ tif->tif_rawcp += cc;
+ tif->tif_rawcc -= cc;
+ return (1);
+}
+
+/*
+ * Seek forwards nrows in the current strip.
+ */
+static int DumpModeSeek(TIFF *tif, uint32_t nrows)
+{
+ tif->tif_rawcp += nrows * tif->tif_scanlinesize;
+ tif->tif_rawcc -= nrows * tif->tif_scanlinesize;
+ return (1);
+}
+
+/*
+ * Initialize dump mode.
+ */
+int TIFFInitDumpMode(TIFF *tif, int scheme)
+{
+ (void)scheme;
+ tif->tif_fixuptags = DumpFixupTags;
+ tif->tif_decoderow = DumpModeDecode;
+ tif->tif_decodestrip = DumpModeDecode;
+ tif->tif_decodetile = DumpModeDecode;
+ tif->tif_encoderow = DumpModeEncode;
+ tif->tif_encodestrip = DumpModeEncode;
+ tif->tif_encodetile = DumpModeEncode;
+ tif->tif_seek = DumpModeSeek;
+ return (1);
+}
diff --git a/contrib/libs/libtiff/tif_error.c b/contrib/libs/libtiff/tif_error.c
new file mode 100644
index 0000000000..ac0b9c373a
--- /dev/null
+++ b/contrib/libs/libtiff/tif_error.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ */
+#include "tiffiop.h"
+
+TIFFErrorHandlerExt _TIFFerrorHandlerExt = NULL;
+
+TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler handler)
+{
+ TIFFErrorHandler prev = _TIFFerrorHandler;
+ _TIFFerrorHandler = handler;
+ return (prev);
+}
+
+TIFFErrorHandlerExt TIFFSetErrorHandlerExt(TIFFErrorHandlerExt handler)
+{
+ TIFFErrorHandlerExt prev = _TIFFerrorHandlerExt;
+ _TIFFerrorHandlerExt = handler;
+ return (prev);
+}
+
+void TIFFError(const char *module, const char *fmt, ...)
+{
+ va_list ap;
+ if (_TIFFerrorHandler)
+ {
+ va_start(ap, fmt);
+ (*_TIFFerrorHandler)(module, fmt, ap);
+ va_end(ap);
+ }
+ if (_TIFFerrorHandlerExt)
+ {
+ va_start(ap, fmt);
+ (*_TIFFerrorHandlerExt)(0, module, fmt, ap);
+ va_end(ap);
+ }
+}
+
+void TIFFErrorExt(thandle_t fd, const char *module, const char *fmt, ...)
+{
+ va_list ap;
+ if (_TIFFerrorHandler)
+ {
+ va_start(ap, fmt);
+ (*_TIFFerrorHandler)(module, fmt, ap);
+ va_end(ap);
+ }
+ if (_TIFFerrorHandlerExt)
+ {
+ va_start(ap, fmt);
+ (*_TIFFerrorHandlerExt)(fd, module, fmt, ap);
+ va_end(ap);
+ }
+}
+
+void _TIFFErrorEarly(TIFFOpenOptions *opts, thandle_t clientdata,
+ const char *module, const char *fmt, ...)
+{
+ va_list ap;
+ if (opts && opts->errorhandler)
+ {
+ va_start(ap, fmt);
+ int stop = opts->errorhandler(NULL, opts->errorhandler_user_data,
+ module, fmt, ap);
+ va_end(ap);
+ if (stop)
+ return;
+ }
+ if (_TIFFerrorHandler)
+ {
+ va_start(ap, fmt);
+ (*_TIFFerrorHandler)(module, fmt, ap);
+ va_end(ap);
+ }
+ if (_TIFFerrorHandlerExt)
+ {
+ va_start(ap, fmt);
+ (*_TIFFerrorHandlerExt)(clientdata, module, fmt, ap);
+ va_end(ap);
+ }
+}
+
+void TIFFErrorExtR(TIFF *tif, const char *module, const char *fmt, ...)
+{
+ va_list ap;
+ if (tif && tif->tif_errorhandler)
+ {
+ va_start(ap, fmt);
+ int stop = (*tif->tif_errorhandler)(
+ tif, tif->tif_errorhandler_user_data, module, fmt, ap);
+ va_end(ap);
+ if (stop)
+ return;
+ }
+ if (_TIFFerrorHandler)
+ {
+ va_start(ap, fmt);
+ (*_TIFFerrorHandler)(module, fmt, ap);
+ va_end(ap);
+ }
+ if (_TIFFerrorHandlerExt)
+ {
+ va_start(ap, fmt);
+ (*_TIFFerrorHandlerExt)(tif ? tif->tif_clientdata : NULL, module, fmt,
+ ap);
+ va_end(ap);
+ }
+}
diff --git a/contrib/libs/libtiff/tif_extension.c b/contrib/libs/libtiff/tif_extension.c
new file mode 100644
index 0000000000..1a09e987a5
--- /dev/null
+++ b/contrib/libs/libtiff/tif_extension.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Various routines support external extension of the tag set, and other
+ * application extension capabilities.
+ */
+
+#include "tiffiop.h"
+
+int TIFFGetTagListCount(TIFF *tif)
+
+{
+ TIFFDirectory *td = &tif->tif_dir;
+
+ return td->td_customValueCount;
+}
+
+uint32_t TIFFGetTagListEntry(TIFF *tif, int tag_index)
+
+{
+ TIFFDirectory *td = &tif->tif_dir;
+
+ if (tag_index < 0 || tag_index >= td->td_customValueCount)
+ return (uint32_t)(-1);
+ else
+ return td->td_customValues[tag_index].info->field_tag;
+}
+
+/*
+** This provides read/write access to the TIFFTagMethods within the TIFF
+** structure to application code without giving access to the private
+** TIFF structure.
+*/
+TIFFTagMethods *TIFFAccessTagMethods(TIFF *tif)
+
+{
+ return &(tif->tif_tagmethods);
+}
+
+void *TIFFGetClientInfo(TIFF *tif, const char *name)
+
+{
+ TIFFClientInfoLink *psLink = tif->tif_clientinfo;
+
+ while (psLink != NULL && strcmp(psLink->name, name) != 0)
+ psLink = psLink->next;
+
+ if (psLink != NULL)
+ return psLink->data;
+ else
+ return NULL;
+}
+
+void TIFFSetClientInfo(TIFF *tif, void *data, const char *name)
+
+{
+ TIFFClientInfoLink *psLink = tif->tif_clientinfo;
+
+ /*
+ ** Do we have an existing link with this name? If so, just
+ ** set it.
+ */
+ while (psLink != NULL && strcmp(psLink->name, name) != 0)
+ psLink = psLink->next;
+
+ if (psLink != NULL)
+ {
+ psLink->data = data;
+ return;
+ }
+
+ /*
+ ** Create a new link.
+ */
+
+ psLink =
+ (TIFFClientInfoLink *)_TIFFmallocExt(tif, sizeof(TIFFClientInfoLink));
+ assert(psLink != NULL);
+ psLink->next = tif->tif_clientinfo;
+ psLink->name = (char *)_TIFFmallocExt(tif, (tmsize_t)(strlen(name) + 1));
+ assert(psLink->name != NULL);
+ strcpy(psLink->name, name);
+ psLink->data = data;
+
+ tif->tif_clientinfo = psLink;
+}
diff --git a/contrib/libs/libtiff/tif_fax3.c b/contrib/libs/libtiff/tif_fax3.c
new file mode 100644
index 0000000000..a3c645cb68
--- /dev/null
+++ b/contrib/libs/libtiff/tif_fax3.c
@@ -0,0 +1,1735 @@
+/*
+ * Copyright (c) 1990-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+#include "tiffiop.h"
+#ifdef CCITT_SUPPORT
+/*
+ * TIFF Library.
+ *
+ * CCITT Group 3 (T.4) and Group 4 (T.6) Compression Support.
+ *
+ * This file contains support for decoding and encoding TIFF
+ * compression algorithms 2, 3, 4, and 32771.
+ *
+ * Decoder support is derived, with permission, from the code
+ * in Frank Cringle's viewfax program;
+ * Copyright (C) 1990, 1995 Frank D. Cringle.
+ */
+#include "tif_fax3.h"
+#define G3CODES
+#include "t4.h"
+#include <stdio.h>
+
+/*
+ * Compression+decompression state blocks are
+ * derived from this ``base state'' block.
+ */
+typedef struct
+{
+ int rw_mode; /* O_RDONLY for decode, else encode */
+ int mode; /* operating mode */
+ tmsize_t rowbytes; /* bytes in a decoded scanline */
+ uint32_t rowpixels; /* pixels in a scanline */
+
+ uint16_t cleanfaxdata; /* CleanFaxData tag */
+ uint32_t badfaxrun; /* BadFaxRun tag */
+ uint32_t badfaxlines; /* BadFaxLines tag */
+ uint32_t groupoptions; /* Group 3/4 options tag */
+
+ TIFFVGetMethod vgetparent; /* super-class method */
+ TIFFVSetMethod vsetparent; /* super-class method */
+ TIFFPrintMethod printdir; /* super-class method */
+} Fax3BaseState;
+#define Fax3State(tif) ((Fax3BaseState *)(tif)->tif_data)
+
+typedef enum
+{
+ G3_1D,
+ G3_2D
+} Ttag;
+typedef struct
+{
+ Fax3BaseState b;
+
+ /* Decoder state info */
+ const unsigned char *bitmap; /* bit reversal table */
+ uint32_t data; /* current i/o byte/word */
+ int bit; /* current i/o bit in byte */
+ int EOLcnt; /* count of EOL codes recognized */
+ TIFFFaxFillFunc fill; /* fill routine */
+ uint32_t *runs; /* b&w runs for current/previous row */
+ uint32_t nruns; /* size of the refruns / curruns arrays */
+ uint32_t *refruns; /* runs for reference line */
+ uint32_t *curruns; /* runs for current line */
+
+ /* Encoder state info */
+ Ttag tag; /* encoding state */
+ unsigned char *refline; /* reference line for 2d decoding */
+ int k; /* #rows left that can be 2d encoded */
+ int maxk; /* max #rows that can be 2d encoded */
+
+ int line;
+} Fax3CodecState;
+#define DecoderState(tif) ((Fax3CodecState *)Fax3State(tif))
+#define EncoderState(tif) ((Fax3CodecState *)Fax3State(tif))
+
+#define is2DEncoding(sp) (sp->b.groupoptions & GROUP3OPT_2DENCODING)
+#define isAligned(p, t) ((((size_t)(p)) & (sizeof(t) - 1)) == 0)
+
+/*
+ * Group 3 and Group 4 Decoding.
+ */
+
+/*
+ * These macros glue the TIFF library state to
+ * the state expected by Frank's decoder.
+ */
+#define DECLARE_STATE(tif, sp, mod) \
+ static const char module[] = mod; \
+ Fax3CodecState *sp = DecoderState(tif); \
+ int a0; /* reference element */ \
+ int lastx = sp->b.rowpixels; /* last element in row */ \
+ uint32_t BitAcc; /* bit accumulator */ \
+ int BitsAvail; /* # valid bits in BitAcc */ \
+ int RunLength; /* length of current run */ \
+ unsigned char *cp; /* next byte of input data */ \
+ unsigned char *ep; /* end of input data */ \
+ uint32_t *pa; /* place to stuff next run */ \
+ uint32_t *thisrun; /* current row's run array */ \
+ int EOLcnt; /* # EOL codes recognized */ \
+ const unsigned char *bitmap = sp->bitmap; /* input data bit reverser */ \
+ const TIFFFaxTabEnt *TabEnt
+#define DECLARE_STATE_2D(tif, sp, mod) \
+ DECLARE_STATE(tif, sp, mod); \
+ int b1; /* next change on prev line */ \
+ uint32_t \
+ *pb /* next run in reference line */ /* \
+ * Load any state that may be \
+ * changed during decoding. \
+ */
+#define CACHE_STATE(tif, sp) \
+ do \
+ { \
+ BitAcc = sp->data; \
+ BitsAvail = sp->bit; \
+ EOLcnt = sp->EOLcnt; \
+ cp = (unsigned char *)tif->tif_rawcp; \
+ ep = cp + tif->tif_rawcc; \
+ } while (0)
+/*
+ * Save state possibly changed during decoding.
+ */
+#define UNCACHE_STATE(tif, sp) \
+ do \
+ { \
+ sp->bit = BitsAvail; \
+ sp->data = BitAcc; \
+ sp->EOLcnt = EOLcnt; \
+ tif->tif_rawcc -= (tmsize_t)((uint8_t *)cp - tif->tif_rawcp); \
+ tif->tif_rawcp = (uint8_t *)cp; \
+ } while (0)
+
+/*
+ * Setup state for decoding a strip.
+ */
+static int Fax3PreDecode(TIFF *tif, uint16_t s)
+{
+ Fax3CodecState *sp = DecoderState(tif);
+
+ (void)s;
+ assert(sp != NULL);
+ sp->bit = 0; /* force initial read */
+ sp->data = 0;
+ sp->EOLcnt = 0; /* force initial scan for EOL */
+ /*
+ * Decoder assumes lsb-to-msb bit order. Note that we select
+ * this here rather than in Fax3SetupState so that viewers can
+ * hold the image open, fiddle with the FillOrder tag value,
+ * and then re-decode the image. Otherwise they'd need to close
+ * and open the image to get the state reset.
+ */
+ sp->bitmap =
+ TIFFGetBitRevTable(tif->tif_dir.td_fillorder != FILLORDER_LSB2MSB);
+ sp->curruns = sp->runs;
+ if (sp->refruns)
+ { /* init reference line to white */
+ sp->refruns = sp->runs + sp->nruns;
+ sp->refruns[0] = (uint32_t)sp->b.rowpixels;
+ sp->refruns[1] = 0;
+ }
+ sp->line = 0;
+ return (1);
+}
+
+/*
+ * Routine for handling various errors/conditions.
+ * Note how they are "glued into the decoder" by
+ * overriding the definitions used by the decoder.
+ */
+
+static void Fax3Unexpected(const char *module, TIFF *tif, uint32_t line,
+ uint32_t a0)
+{
+ TIFFErrorExtR(tif, module,
+ "Bad code word at line %" PRIu32 " of %s %" PRIu32
+ " (x %" PRIu32 ")",
+ line, isTiled(tif) ? "tile" : "strip",
+ (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0);
+}
+#define unexpected(table, a0) Fax3Unexpected(module, tif, sp->line, a0)
+
+static void Fax3Extension(const char *module, TIFF *tif, uint32_t line,
+ uint32_t a0)
+{
+ TIFFErrorExtR(tif, module,
+ "Uncompressed data (not supported) at line %" PRIu32
+ " of %s %" PRIu32 " (x %" PRIu32 ")",
+ line, isTiled(tif) ? "tile" : "strip",
+ (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0);
+}
+#define extension(a0) Fax3Extension(module, tif, sp->line, a0)
+
+static void Fax3BadLength(const char *module, TIFF *tif, uint32_t line,
+ uint32_t a0, uint32_t lastx)
+{
+ TIFFWarningExtR(tif, module,
+ "%s at line %" PRIu32 " of %s %" PRIu32 " (got %" PRIu32
+ ", expected %" PRIu32 ")",
+ a0 < lastx ? "Premature EOL" : "Line length mismatch", line,
+ isTiled(tif) ? "tile" : "strip",
+ (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0,
+ lastx);
+}
+#define badlength(a0, lastx) Fax3BadLength(module, tif, sp->line, a0, lastx)
+
+static void Fax3PrematureEOF(const char *module, TIFF *tif, uint32_t line,
+ uint32_t a0)
+{
+ TIFFWarningExtR(tif, module,
+ "Premature EOF at line %" PRIu32 " of %s %" PRIu32
+ " (x %" PRIu32 ")",
+ line, isTiled(tif) ? "tile" : "strip",
+ (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0);
+}
+#define prematureEOF(a0) Fax3PrematureEOF(module, tif, sp->line, a0)
+
+#define Nop
+
+/**
+ * Decode the requested amount of G3 1D-encoded data.
+ * @param buf destination buffer
+ * @param occ available bytes in destination buffer
+ * @param s number of planes (ignored)
+ * @returns 1 for success, -1 in case of error
+ */
+static int Fax3Decode1D(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
+{
+ DECLARE_STATE(tif, sp, "Fax3Decode1D");
+ (void)s;
+ if (occ % sp->b.rowbytes)
+ {
+ TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
+ return (-1);
+ }
+ CACHE_STATE(tif, sp);
+ thisrun = sp->curruns;
+ while (occ > 0)
+ {
+ a0 = 0;
+ RunLength = 0;
+ pa = thisrun;
+#ifdef FAX3_DEBUG
+ printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d\n", BitAcc, BitsAvail);
+ printf("-------------------- %" PRIu32 "\n", tif->tif_row);
+ fflush(stdout);
+#endif
+ SYNC_EOL(EOF1D);
+ EXPAND1D(EOF1Da);
+ (*sp->fill)(buf, thisrun, pa, lastx);
+ buf += sp->b.rowbytes;
+ occ -= sp->b.rowbytes;
+ sp->line++;
+ continue;
+ EOF1D: /* premature EOF */
+ CLEANUP_RUNS();
+ EOF1Da: /* premature EOF */
+ (*sp->fill)(buf, thisrun, pa, lastx);
+ UNCACHE_STATE(tif, sp);
+ return (-1);
+ }
+ UNCACHE_STATE(tif, sp);
+ return (1);
+}
+
+#define SWAP(t, a, b) \
+ { \
+ t x; \
+ x = (a); \
+ (a) = (b); \
+ (b) = x; \
+ }
+/*
+ * Decode the requested amount of G3 2D-encoded data.
+ */
+static int Fax3Decode2D(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
+{
+ DECLARE_STATE_2D(tif, sp, "Fax3Decode2D");
+ int is1D; /* current line is 1d/2d-encoded */
+ (void)s;
+ if (occ % sp->b.rowbytes)
+ {
+ TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
+ return (-1);
+ }
+ CACHE_STATE(tif, sp);
+ while (occ > 0)
+ {
+ a0 = 0;
+ RunLength = 0;
+ pa = thisrun = sp->curruns;
+#ifdef FAX3_DEBUG
+ printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d EOLcnt = %d", BitAcc,
+ BitsAvail, EOLcnt);
+#endif
+ SYNC_EOL(EOF2D);
+ NeedBits8(1, EOF2D);
+ is1D = GetBits(1); /* 1D/2D-encoding tag bit */
+ ClrBits(1);
+#ifdef FAX3_DEBUG
+ printf(" %s\n-------------------- %" PRIu32 "\n", is1D ? "1D" : "2D",
+ tif->tif_row);
+ fflush(stdout);
+#endif
+ pb = sp->refruns;
+ b1 = *pb++;
+ if (is1D)
+ EXPAND1D(EOF2Da);
+ else
+ EXPAND2D(EOF2Da);
+ (*sp->fill)(buf, thisrun, pa, lastx);
+ if (pa < thisrun + sp->nruns)
+ {
+ SETVALUE(0); /* imaginary change for reference */
+ }
+ SWAP(uint32_t *, sp->curruns, sp->refruns);
+ buf += sp->b.rowbytes;
+ occ -= sp->b.rowbytes;
+ sp->line++;
+ continue;
+ EOF2D: /* premature EOF */
+ CLEANUP_RUNS();
+ EOF2Da: /* premature EOF */
+ (*sp->fill)(buf, thisrun, pa, lastx);
+ UNCACHE_STATE(tif, sp);
+ return (-1);
+ }
+ UNCACHE_STATE(tif, sp);
+ return (1);
+}
+#undef SWAP
+
+#define FILL(n, cp) \
+ for (int32_t ifill = 0; ifill < (n); ++ifill) \
+ { \
+ (cp)[ifill] = 0xff; \
+ } \
+ (cp) += (n);
+
+#define ZERO(n, cp) \
+ for (int32_t izero = 0; izero < (n); ++izero) \
+ { \
+ (cp)[izero] = 0; \
+ } \
+ (cp) += (n);
+
+/*
+ * Bit-fill a row according to the white/black
+ * runs generated during G3/G4 decoding.
+ */
+void _TIFFFax3fillruns(unsigned char *buf, uint32_t *runs, uint32_t *erun,
+ uint32_t lastx)
+{
+ static const unsigned char _fillmasks[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
+ 0xf8, 0xfc, 0xfe, 0xff};
+ unsigned char *cp;
+ uint32_t x, bx, run;
+ int32_t n, nw;
+ int64_t *lp;
+
+ if ((erun - runs) & 1)
+ *erun++ = 0;
+ x = 0;
+ for (; runs < erun; runs += 2)
+ {
+ run = runs[0];
+ if (x + run > lastx || run > lastx)
+ run = runs[0] = (uint32_t)(lastx - x);
+ if (run)
+ {
+ cp = buf + (x >> 3);
+ bx = x & 7;
+ if (run > 8 - bx)
+ {
+ if (bx)
+ { /* align to byte boundary */
+ *cp++ &= 0xff << (8 - bx);
+ run -= 8 - bx;
+ }
+ if ((n = run >> 3) != 0)
+ { /* multiple bytes to fill */
+ if ((n / sizeof(int64_t)) > 1)
+ {
+ /*
+ * Align to int64_tword boundary and fill.
+ */
+ for (; n && !isAligned(cp, int64_t); n--)
+ *cp++ = 0x00;
+ lp = (int64_t *)cp;
+ nw = (int32_t)(n / sizeof(int64_t));
+ n -= nw * sizeof(int64_t);
+ do
+ {
+ *lp++ = 0L;
+ } while (--nw);
+ cp = (unsigned char *)lp;
+ }
+ ZERO(n, cp);
+ run &= 7;
+ }
+ if (run)
+ cp[0] &= 0xff >> run;
+ }
+ else
+ cp[0] &= ~(_fillmasks[run] >> bx);
+ x += runs[0];
+ }
+ run = runs[1];
+ if (x + run > lastx || run > lastx)
+ run = runs[1] = lastx - x;
+ if (run)
+ {
+ cp = buf + (x >> 3);
+ bx = x & 7;
+ if (run > 8 - bx)
+ {
+ if (bx)
+ { /* align to byte boundary */
+ *cp++ |= 0xff >> bx;
+ run -= 8 - bx;
+ }
+ if ((n = run >> 3) != 0)
+ { /* multiple bytes to fill */
+ if ((n / sizeof(int64_t)) > 1)
+ {
+ /*
+ * Align to int64_t boundary and fill.
+ */
+ for (; n && !isAligned(cp, int64_t); n--)
+ *cp++ = 0xff;
+ lp = (int64_t *)cp;
+ nw = (int32_t)(n / sizeof(int64_t));
+ n -= nw * sizeof(int64_t);
+ do
+ {
+ *lp++ = -1L;
+ } while (--nw);
+ cp = (unsigned char *)lp;
+ }
+ FILL(n, cp);
+ run &= 7;
+ }
+ /* Explicit 0xff masking to make icc -check=conversions happy */
+ if (run)
+ cp[0] = (unsigned char)((cp[0] | (0xff00 >> run)) & 0xff);
+ }
+ else
+ cp[0] |= _fillmasks[run] >> bx;
+ x += runs[1];
+ }
+ }
+ assert(x == lastx);
+}
+#undef ZERO
+#undef FILL
+
+static int Fax3FixupTags(TIFF *tif)
+{
+ (void)tif;
+ return (1);
+}
+
+/*
+ * Setup G3/G4-related compression/decompression state
+ * before data is processed. This routine is called once
+ * per image -- it sets up different state based on whether
+ * or not decoding or encoding is being done and whether
+ * 1D- or 2D-encoded data is involved.
+ */
+static int Fax3SetupState(TIFF *tif)
+{
+ static const char module[] = "Fax3SetupState";
+ TIFFDirectory *td = &tif->tif_dir;
+ Fax3BaseState *sp = Fax3State(tif);
+ int needsRefLine;
+ Fax3CodecState *dsp = (Fax3CodecState *)Fax3State(tif);
+ tmsize_t rowbytes;
+ uint32_t rowpixels;
+
+ if (td->td_bitspersample != 1)
+ {
+ TIFFErrorExtR(tif, module,
+ "Bits/sample must be 1 for Group 3/4 encoding/decoding");
+ return (0);
+ }
+ /*
+ * Calculate the scanline/tile widths.
+ */
+ if (isTiled(tif))
+ {
+ rowbytes = TIFFTileRowSize(tif);
+ rowpixels = td->td_tilewidth;
+ }
+ else
+ {
+ rowbytes = TIFFScanlineSize(tif);
+ rowpixels = td->td_imagewidth;
+ }
+ if ((int64_t)rowbytes < ((int64_t)rowpixels + 7) / 8)
+ {
+ TIFFErrorExtR(tif, module,
+ "Inconsistent number of bytes per row : rowbytes=%" PRId64
+ " rowpixels=%" PRIu32,
+ (int64_t)rowbytes, rowpixels);
+ return (0);
+ }
+ sp->rowbytes = rowbytes;
+ sp->rowpixels = rowpixels;
+ /*
+ * Allocate any additional space required for decoding/encoding.
+ */
+ needsRefLine = ((sp->groupoptions & GROUP3OPT_2DENCODING) ||
+ td->td_compression == COMPRESSION_CCITTFAX4);
+
+ /*
+ Assure that allocation computations do not overflow.
+
+ TIFFroundup and TIFFSafeMultiply return zero on integer overflow
+ */
+ dsp->runs = (uint32_t *)NULL;
+ dsp->nruns = TIFFroundup_32(rowpixels + 1, 32);
+ if (needsRefLine)
+ {
+ dsp->nruns = TIFFSafeMultiply(uint32_t, dsp->nruns, 2);
+ }
+ if ((dsp->nruns == 0) || (TIFFSafeMultiply(uint32_t, dsp->nruns, 2) == 0))
+ {
+ TIFFErrorExtR(tif, tif->tif_name,
+ "Row pixels integer overflow (rowpixels %" PRIu32 ")",
+ rowpixels);
+ return (0);
+ }
+ dsp->runs = (uint32_t *)_TIFFCheckMalloc(
+ tif, TIFFSafeMultiply(uint32_t, dsp->nruns, 2), sizeof(uint32_t),
+ "for Group 3/4 run arrays");
+ if (dsp->runs == NULL)
+ return (0);
+ memset(dsp->runs, 0,
+ TIFFSafeMultiply(uint32_t, dsp->nruns, 2) * sizeof(uint32_t));
+ dsp->curruns = dsp->runs;
+ if (needsRefLine)
+ dsp->refruns = dsp->runs + dsp->nruns;
+ else
+ dsp->refruns = NULL;
+ if (td->td_compression == COMPRESSION_CCITTFAX3 && is2DEncoding(dsp))
+ { /* NB: default is 1D routine */
+ tif->tif_decoderow = Fax3Decode2D;
+ tif->tif_decodestrip = Fax3Decode2D;
+ tif->tif_decodetile = Fax3Decode2D;
+ }
+
+ if (needsRefLine)
+ { /* 2d encoding */
+ Fax3CodecState *esp = EncoderState(tif);
+ /*
+ * 2d encoding requires a scanline
+ * buffer for the ``reference line''; the
+ * scanline against which delta encoding
+ * is referenced. The reference line must
+ * be initialized to be ``white'' (done elsewhere).
+ */
+ esp->refline = (unsigned char *)_TIFFmallocExt(tif, rowbytes);
+ if (esp->refline == NULL)
+ {
+ TIFFErrorExtR(tif, module, "No space for Group 3/4 reference line");
+ return (0);
+ }
+ }
+ else /* 1d encoding */
+ EncoderState(tif)->refline = NULL;
+
+ return (1);
+}
+
+/*
+ * CCITT Group 3 FAX Encoding.
+ */
+
+#define Fax3FlushBits(tif, sp) \
+ { \
+ if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) \
+ { \
+ if (!TIFFFlushData1(tif)) \
+ return 0; \
+ } \
+ *(tif)->tif_rawcp++ = (uint8_t)(sp)->data; \
+ (tif)->tif_rawcc++; \
+ (sp)->data = 0, (sp)->bit = 8; \
+ }
+#define _FlushBits(tif) \
+ { \
+ if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) \
+ { \
+ if (!TIFFFlushData1(tif)) \
+ return 0; \
+ } \
+ *(tif)->tif_rawcp++ = (uint8_t)data; \
+ (tif)->tif_rawcc++; \
+ data = 0, bit = 8; \
+ }
+static const int _msbmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f,
+ 0x1f, 0x3f, 0x7f, 0xff};
+#define _PutBits(tif, bits, length) \
+ { \
+ while (length > bit) \
+ { \
+ data |= bits >> (length - bit); \
+ length -= bit; \
+ _FlushBits(tif); \
+ } \
+ assert(length < 9); \
+ data |= (bits & _msbmask[length]) << (bit - length); \
+ bit -= length; \
+ if (bit == 0) \
+ _FlushBits(tif); \
+ }
+
+/*
+ * Write a variable-length bit-value to
+ * the output stream. Values are
+ * assumed to be at most 16 bits.
+ */
+static int Fax3PutBits(TIFF *tif, unsigned int bits, unsigned int length)
+{
+ Fax3CodecState *sp = EncoderState(tif);
+ unsigned int bit = sp->bit;
+ int data = sp->data;
+
+ _PutBits(tif, bits, length);
+
+ sp->data = data;
+ sp->bit = bit;
+ return 1;
+}
+
+/*
+ * Write a code to the output stream.
+ */
+#define putcode(tif, te) Fax3PutBits(tif, (te)->code, (te)->length)
+
+#ifdef FAX3_DEBUG
+#define DEBUG_COLOR(w) (tab == TIFFFaxWhiteCodes ? w "W" : w "B")
+#define DEBUG_PRINT(what, len) \
+ { \
+ int t; \
+ printf("%08" PRIX32 "/%-2d: %s%5d\t", data, bit, DEBUG_COLOR(what), \
+ len); \
+ for (t = length - 1; t >= 0; t--) \
+ putchar(code & (1 << t) ? '1' : '0'); \
+ putchar('\n'); \
+ }
+#endif
+
+/*
+ * Write the sequence of codes that describes
+ * the specified span of zero's or one's. The
+ * appropriate table that holds the make-up and
+ * terminating codes is supplied.
+ */
+static int putspan(TIFF *tif, int32_t span, const tableentry *tab)
+{
+ Fax3CodecState *sp = EncoderState(tif);
+ unsigned int bit = sp->bit;
+ int data = sp->data;
+ unsigned int code, length;
+
+ while (span >= 2624)
+ {
+ const tableentry *te = &tab[63 + (2560 >> 6)];
+ code = te->code;
+ length = te->length;
+#ifdef FAX3_DEBUG
+ DEBUG_PRINT("MakeUp", te->runlen);
+#endif
+ _PutBits(tif, code, length);
+ span -= te->runlen;
+ }
+ if (span >= 64)
+ {
+ const tableentry *te = &tab[63 + (span >> 6)];
+ assert(te->runlen == 64 * (span >> 6));
+ code = te->code;
+ length = te->length;
+#ifdef FAX3_DEBUG
+ DEBUG_PRINT("MakeUp", te->runlen);
+#endif
+ _PutBits(tif, code, length);
+ span -= te->runlen;
+ }
+ code = tab[span].code;
+ length = tab[span].length;
+#ifdef FAX3_DEBUG
+ DEBUG_PRINT(" Term", tab[span].runlen);
+#endif
+ _PutBits(tif, code, length);
+
+ sp->data = data;
+ sp->bit = bit;
+
+ return 1;
+}
+
+/*
+ * Write an EOL code to the output stream. The zero-fill
+ * logic for byte-aligning encoded scanlines is handled
+ * here. We also handle writing the tag bit for the next
+ * scanline when doing 2d encoding.
+ */
+static int Fax3PutEOL(TIFF *tif)
+{
+ Fax3CodecState *sp = EncoderState(tif);
+ unsigned int bit = sp->bit;
+ int data = sp->data;
+ unsigned int code, length, tparm;
+
+ if (sp->b.groupoptions & GROUP3OPT_FILLBITS)
+ {
+ /*
+ * Force bit alignment so EOL will terminate on
+ * a byte boundary. That is, force the bit alignment
+ * to 16-12 = 4 before putting out the EOL code.
+ */
+ int align = 8 - 4;
+ if (align != sp->bit)
+ {
+ if (align > sp->bit)
+ align = sp->bit + (8 - align);
+ else
+ align = sp->bit - align;
+ tparm = align;
+ _PutBits(tif, 0, tparm);
+ }
+ }
+ code = EOL;
+ length = 12;
+ if (is2DEncoding(sp))
+ {
+ code = (code << 1) | (sp->tag == G3_1D);
+ length++;
+ }
+ _PutBits(tif, code, length);
+
+ sp->data = data;
+ sp->bit = bit;
+
+ return 1;
+}
+
+/*
+ * Reset encoding state at the start of a strip.
+ */
+static int Fax3PreEncode(TIFF *tif, uint16_t s)
+{
+ Fax3CodecState *sp = EncoderState(tif);
+
+ (void)s;
+ assert(sp != NULL);
+ sp->bit = 8;
+ sp->data = 0;
+ sp->tag = G3_1D;
+ /*
+ * This is necessary for Group 4; otherwise it isn't
+ * needed because the first scanline of each strip ends
+ * up being copied into the refline.
+ */
+ if (sp->refline)
+ _TIFFmemset(sp->refline, 0x00, sp->b.rowbytes);
+ if (is2DEncoding(sp))
+ {
+ float res = tif->tif_dir.td_yresolution;
+ /*
+ * The CCITT spec says that when doing 2d encoding, you
+ * should only do it on K consecutive scanlines, where K
+ * depends on the resolution of the image being encoded
+ * (2 for <= 200 lpi, 4 for > 200 lpi). Since the directory
+ * code initializes td_yresolution to 0, this code will
+ * select a K of 2 unless the YResolution tag is set
+ * appropriately. (Note also that we fudge a little here
+ * and use 150 lpi to avoid problems with units conversion.)
+ */
+ if (tif->tif_dir.td_resolutionunit == RESUNIT_CENTIMETER)
+ res *= 2.54f; /* convert to inches */
+ sp->maxk = (res > 150 ? 4 : 2);
+ sp->k = sp->maxk - 1;
+ }
+ else
+ sp->k = sp->maxk = 0;
+ sp->line = 0;
+ return (1);
+}
+
+static const unsigned char zeroruns[256] = {
+ 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, /* 0x00 - 0x0f */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x10 - 0x1f */
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x20 - 0x2f */
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x30 - 0x3f */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4f */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x50 - 0x5f */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6f */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x70 - 0x7f */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8f */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9f */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 - 0xaf */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 - 0xbf */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 - 0xcf */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 - 0xdf */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 - 0xef */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xf0 - 0xff */
+};
+static const unsigned char oneruns[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 - 0x0f */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1f */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 - 0x2f */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30 - 0x3f */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 - 0x4f */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 - 0x5f */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x6f */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x7f */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x80 - 0x8f */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x90 - 0x9f */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xa0 - 0xaf */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xb0 - 0xbf */
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xc0 - 0xcf */
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xd0 - 0xdf */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xe0 - 0xef */
+ 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, /* 0xf0 - 0xff */
+};
+
+/*
+ * Find a span of ones or zeros using the supplied
+ * table. The ``base'' of the bit string is supplied
+ * along with the start+end bit indices.
+ */
+static inline int32_t find0span(unsigned char *bp, int32_t bs, int32_t be)
+{
+ int32_t bits = be - bs;
+ int32_t n, span;
+
+ bp += bs >> 3;
+ /*
+ * Check partial byte on lhs.
+ */
+ if (bits > 0 && (n = (bs & 7)) != 0)
+ {
+ span = zeroruns[(*bp << n) & 0xff];
+ if (span > 8 - n) /* table value too generous */
+ span = 8 - n;
+ if (span > bits) /* constrain span to bit range */
+ span = bits;
+ if (n + span < 8) /* doesn't extend to edge of byte */
+ return (span);
+ bits -= span;
+ bp++;
+ }
+ else
+ span = 0;
+ if (bits >= (int32_t)(2 * 8 * sizeof(int64_t)))
+ {
+ int64_t *lp;
+ /*
+ * Align to int64_t boundary and check int64_t words.
+ */
+ while (!isAligned(bp, int64_t))
+ {
+ if (*bp != 0x00)
+ return (span + zeroruns[*bp]);
+ span += 8;
+ bits -= 8;
+ bp++;
+ }
+ lp = (int64_t *)bp;
+ while ((bits >= (int32_t)(8 * sizeof(int64_t))) && (0 == *lp))
+ {
+ span += 8 * sizeof(int64_t);
+ bits -= 8 * sizeof(int64_t);
+ lp++;
+ }
+ bp = (unsigned char *)lp;
+ }
+ /*
+ * Scan full bytes for all 0's.
+ */
+ while (bits >= 8)
+ {
+ if (*bp != 0x00) /* end of run */
+ return (span + zeroruns[*bp]);
+ span += 8;
+ bits -= 8;
+ bp++;
+ }
+ /*
+ * Check partial byte on rhs.
+ */
+ if (bits > 0)
+ {
+ n = zeroruns[*bp];
+ span += (n > bits ? bits : n);
+ }
+ return (span);
+}
+
+static inline int32_t find1span(unsigned char *bp, int32_t bs, int32_t be)
+{
+ int32_t bits = be - bs;
+ int32_t n, span;
+
+ bp += bs >> 3;
+ /*
+ * Check partial byte on lhs.
+ */
+ if (bits > 0 && (n = (bs & 7)) != 0)
+ {
+ span = oneruns[(*bp << n) & 0xff];
+ if (span > 8 - n) /* table value too generous */
+ span = 8 - n;
+ if (span > bits) /* constrain span to bit range */
+ span = bits;
+ if (n + span < 8) /* doesn't extend to edge of byte */
+ return (span);
+ bits -= span;
+ bp++;
+ }
+ else
+ span = 0;
+ if (bits >= (int32_t)(2 * 8 * sizeof(int64_t)))
+ {
+ int64_t *lp;
+ /*
+ * Align to int64_t boundary and check int64_t words.
+ */
+ while (!isAligned(bp, int64_t))
+ {
+ if (*bp != 0xff)
+ return (span + oneruns[*bp]);
+ span += 8;
+ bits -= 8;
+ bp++;
+ }
+ lp = (int64_t *)bp;
+ while ((bits >= (int32_t)(8 * sizeof(int64_t))) &&
+ (~((uint64_t)0) == (uint64_t)*lp))
+ {
+ span += 8 * sizeof(int64_t);
+ bits -= 8 * sizeof(int64_t);
+ lp++;
+ }
+ bp = (unsigned char *)lp;
+ }
+ /*
+ * Scan full bytes for all 1's.
+ */
+ while (bits >= 8)
+ {
+ if (*bp != 0xff) /* end of run */
+ return (span + oneruns[*bp]);
+ span += 8;
+ bits -= 8;
+ bp++;
+ }
+ /*
+ * Check partial byte on rhs.
+ */
+ if (bits > 0)
+ {
+ n = oneruns[*bp];
+ span += (n > bits ? bits : n);
+ }
+ return (span);
+}
+
+/*
+ * Return the offset of the next bit in the range
+ * [bs..be] that is different from the specified
+ * color. The end, be, is returned if no such bit
+ * exists.
+ */
+#define finddiff(_cp, _bs, _be, _color) \
+ (_bs + (_color ? find1span(_cp, _bs, _be) : find0span(_cp, _bs, _be)))
+/*
+ * Like finddiff, but also check the starting bit
+ * against the end in case start > end.
+ */
+#define finddiff2(_cp, _bs, _be, _color) \
+ (_bs < _be ? finddiff(_cp, _bs, _be, _color) : _be)
+
+/*
+ * 1d-encode a row of pixels. The encoding is
+ * a sequence of all-white or all-black spans
+ * of pixels encoded with Huffman codes.
+ */
+static int Fax3Encode1DRow(TIFF *tif, unsigned char *bp, uint32_t bits)
+{
+ Fax3CodecState *sp = EncoderState(tif);
+ int32_t span;
+ uint32_t bs = 0;
+
+ for (;;)
+ {
+ span = find0span(bp, bs, bits); /* white span */
+ if (!putspan(tif, span, TIFFFaxWhiteCodes))
+ return 0;
+ bs += span;
+ if (bs >= bits)
+ break;
+ span = find1span(bp, bs, bits); /* black span */
+ if (!putspan(tif, span, TIFFFaxBlackCodes))
+ return 0;
+ bs += span;
+ if (bs >= bits)
+ break;
+ }
+ if (sp->b.mode & (FAXMODE_BYTEALIGN | FAXMODE_WORDALIGN))
+ {
+ if (sp->bit != 8) /* byte-align */
+ Fax3FlushBits(tif, sp);
+ if ((sp->b.mode & FAXMODE_WORDALIGN) &&
+ !isAligned(tif->tif_rawcp, uint16_t))
+ Fax3FlushBits(tif, sp);
+ }
+ return (1);
+}
+
+static const tableentry horizcode = {3, 0x1, 0}; /* 001 */
+static const tableentry passcode = {4, 0x1, 0}; /* 0001 */
+static const tableentry vcodes[7] = {
+ {7, 0x03, 0}, /* 0000 011 */
+ {6, 0x03, 0}, /* 0000 11 */
+ {3, 0x03, 0}, /* 011 */
+ {1, 0x1, 0}, /* 1 */
+ {3, 0x2, 0}, /* 010 */
+ {6, 0x02, 0}, /* 0000 10 */
+ {7, 0x02, 0} /* 0000 010 */
+};
+
+/*
+ * 2d-encode a row of pixels. Consult the CCITT
+ * documentation for the algorithm.
+ */
+static int Fax3Encode2DRow(TIFF *tif, unsigned char *bp, unsigned char *rp,
+ uint32_t bits)
+{
+#define PIXEL(buf, ix) ((((buf)[(ix) >> 3]) >> (7 - ((ix)&7))) & 1)
+ uint32_t a0 = 0;
+ uint32_t a1 = (PIXEL(bp, 0) != 0 ? 0 : finddiff(bp, 0, bits, 0));
+ uint32_t b1 = (PIXEL(rp, 0) != 0 ? 0 : finddiff(rp, 0, bits, 0));
+ uint32_t a2, b2;
+
+ for (;;)
+ {
+ b2 = finddiff2(rp, b1, bits, PIXEL(rp, b1));
+ if (b2 >= a1)
+ {
+ /* Naive computation triggers
+ * -fsanitize=undefined,unsigned-integer-overflow */
+ /* although it is correct unless the difference between both is < 31
+ * bit */
+ /* int32_t d = b1 - a1; */
+ int32_t d = (b1 >= a1 && b1 - a1 <= 3U) ? (int32_t)(b1 - a1)
+ : (b1 < a1 && a1 - b1 <= 3U) ? -(int32_t)(a1 - b1)
+ : 0x7FFFFFFF;
+ if (!(-3 <= d && d <= 3))
+ { /* horizontal mode */
+ a2 = finddiff2(bp, a1, bits, PIXEL(bp, a1));
+ if (!putcode(tif, &horizcode))
+ return 0;
+ if (a0 + a1 == 0 || PIXEL(bp, a0) == 0)
+ {
+ if (!putspan(tif, a1 - a0, TIFFFaxWhiteCodes))
+ return 0;
+ if (!putspan(tif, a2 - a1, TIFFFaxBlackCodes))
+ return 0;
+ }
+ else
+ {
+ if (!putspan(tif, a1 - a0, TIFFFaxBlackCodes))
+ return 0;
+ if (!putspan(tif, a2 - a1, TIFFFaxWhiteCodes))
+ return 0;
+ }
+ a0 = a2;
+ }
+ else
+ { /* vertical mode */
+ if (!putcode(tif, &vcodes[d + 3]))
+ return 0;
+ a0 = a1;
+ }
+ }
+ else
+ { /* pass mode */
+ if (!putcode(tif, &passcode))
+ return 0;
+ a0 = b2;
+ }
+ if (a0 >= bits)
+ break;
+ a1 = finddiff(bp, a0, bits, PIXEL(bp, a0));
+ b1 = finddiff(rp, a0, bits, !PIXEL(bp, a0));
+ b1 = finddiff(rp, b1, bits, PIXEL(bp, a0));
+ }
+ return (1);
+#undef PIXEL
+}
+
+/*
+ * Encode a buffer of pixels.
+ */
+static int Fax3Encode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
+{
+ static const char module[] = "Fax3Encode";
+ Fax3CodecState *sp = EncoderState(tif);
+ (void)s;
+ if (cc % sp->b.rowbytes)
+ {
+ TIFFErrorExtR(tif, module, "Fractional scanlines cannot be written");
+ return (0);
+ }
+ while (cc > 0)
+ {
+ if ((sp->b.mode & FAXMODE_NOEOL) == 0)
+ {
+ if (!Fax3PutEOL(tif))
+ return 0;
+ }
+ if (is2DEncoding(sp))
+ {
+ if (sp->tag == G3_1D)
+ {
+ if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels))
+ return (0);
+ sp->tag = G3_2D;
+ }
+ else
+ {
+ if (!Fax3Encode2DRow(tif, bp, sp->refline, sp->b.rowpixels))
+ return (0);
+ sp->k--;
+ }
+ if (sp->k == 0)
+ {
+ sp->tag = G3_1D;
+ sp->k = sp->maxk - 1;
+ }
+ else
+ _TIFFmemcpy(sp->refline, bp, sp->b.rowbytes);
+ }
+ else
+ {
+ if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels))
+ return (0);
+ }
+ bp += sp->b.rowbytes;
+ cc -= sp->b.rowbytes;
+ }
+ return (1);
+}
+
+static int Fax3PostEncode(TIFF *tif)
+{
+ Fax3CodecState *sp = EncoderState(tif);
+
+ if (sp->bit != 8)
+ Fax3FlushBits(tif, sp);
+ return (1);
+}
+
+static int _Fax3Close(TIFF *tif)
+{
+ if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0 && tif->tif_rawcp)
+ {
+ Fax3CodecState *sp = EncoderState(tif);
+ unsigned int code = EOL;
+ unsigned int length = 12;
+ int i;
+
+ if (is2DEncoding(sp))
+ {
+ code = (code << 1) | (sp->tag == G3_1D);
+ length++;
+ }
+ for (i = 0; i < 6; i++)
+ Fax3PutBits(tif, code, length);
+ Fax3FlushBits(tif, sp);
+ }
+ return 1;
+}
+
+static void Fax3Close(TIFF *tif) { _Fax3Close(tif); }
+
+static void Fax3Cleanup(TIFF *tif)
+{
+ Fax3CodecState *sp = DecoderState(tif);
+
+ assert(sp != 0);
+
+ tif->tif_tagmethods.vgetfield = sp->b.vgetparent;
+ tif->tif_tagmethods.vsetfield = sp->b.vsetparent;
+ tif->tif_tagmethods.printdir = sp->b.printdir;
+
+ if (sp->runs)
+ _TIFFfreeExt(tif, sp->runs);
+ if (sp->refline)
+ _TIFFfreeExt(tif, sp->refline);
+
+ _TIFFfreeExt(tif, tif->tif_data);
+ tif->tif_data = NULL;
+
+ _TIFFSetDefaultCompressionState(tif);
+}
+
+#define FIELD_BADFAXLINES (FIELD_CODEC + 0)
+#define FIELD_CLEANFAXDATA (FIELD_CODEC + 1)
+#define FIELD_BADFAXRUN (FIELD_CODEC + 2)
+
+#define FIELD_OPTIONS (FIELD_CODEC + 7)
+
+static const TIFFField faxFields[] = {
+ {TIFFTAG_FAXMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED,
+ FIELD_PSEUDO, FALSE, FALSE, "FaxMode", NULL},
+ {TIFFTAG_FAXFILLFUNC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_OTHER,
+ TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "FaxFillFunc", NULL},
+ {TIFFTAG_BADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32,
+ TIFF_SETGET_UINT32, FIELD_BADFAXLINES, TRUE, FALSE, "BadFaxLines", NULL},
+ {TIFFTAG_CLEANFAXDATA, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16,
+ TIFF_SETGET_UINT16, FIELD_CLEANFAXDATA, TRUE, FALSE, "CleanFaxData", NULL},
+ {TIFFTAG_CONSECUTIVEBADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32,
+ TIFF_SETGET_UINT32, FIELD_BADFAXRUN, TRUE, FALSE, "ConsecutiveBadFaxLines",
+ NULL}};
+static const TIFFField fax3Fields[] = {
+ {TIFFTAG_GROUP3OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32,
+ TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group3Options", NULL},
+};
+static const TIFFField fax4Fields[] = {
+ {TIFFTAG_GROUP4OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32,
+ TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group4Options", NULL},
+};
+
+static int Fax3VSetField(TIFF *tif, uint32_t tag, va_list ap)
+{
+ Fax3BaseState *sp = Fax3State(tif);
+ const TIFFField *fip;
+
+ assert(sp != 0);
+ assert(sp->vsetparent != 0);
+
+ switch (tag)
+ {
+ case TIFFTAG_FAXMODE:
+ sp->mode = (int)va_arg(ap, int);
+ return 1; /* NB: pseudo tag */
+ case TIFFTAG_FAXFILLFUNC:
+ DecoderState(tif)->fill = va_arg(ap, TIFFFaxFillFunc);
+ return 1; /* NB: pseudo tag */
+ case TIFFTAG_GROUP3OPTIONS:
+ /* XXX: avoid reading options if compression mismatches. */
+ if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX3)
+ sp->groupoptions = (uint32_t)va_arg(ap, uint32_t);
+ break;
+ case TIFFTAG_GROUP4OPTIONS:
+ /* XXX: avoid reading options if compression mismatches. */
+ if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4)
+ sp->groupoptions = (uint32_t)va_arg(ap, uint32_t);
+ break;
+ case TIFFTAG_BADFAXLINES:
+ sp->badfaxlines = (uint32_t)va_arg(ap, uint32_t);
+ break;
+ case TIFFTAG_CLEANFAXDATA:
+ sp->cleanfaxdata = (uint16_t)va_arg(ap, uint16_vap);
+ break;
+ case TIFFTAG_CONSECUTIVEBADFAXLINES:
+ sp->badfaxrun = (uint32_t)va_arg(ap, uint32_t);
+ break;
+ 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 Fax3VGetField(TIFF *tif, uint32_t tag, va_list ap)
+{
+ Fax3BaseState *sp = Fax3State(tif);
+
+ assert(sp != 0);
+
+ switch (tag)
+ {
+ case TIFFTAG_FAXMODE:
+ *va_arg(ap, int *) = sp->mode;
+ break;
+ case TIFFTAG_FAXFILLFUNC:
+ *va_arg(ap, TIFFFaxFillFunc *) = DecoderState(tif)->fill;
+ break;
+ case TIFFTAG_GROUP3OPTIONS:
+ case TIFFTAG_GROUP4OPTIONS:
+ *va_arg(ap, uint32_t *) = sp->groupoptions;
+ break;
+ case TIFFTAG_BADFAXLINES:
+ *va_arg(ap, uint32_t *) = sp->badfaxlines;
+ break;
+ case TIFFTAG_CLEANFAXDATA:
+ *va_arg(ap, uint16_t *) = sp->cleanfaxdata;
+ break;
+ case TIFFTAG_CONSECUTIVEBADFAXLINES:
+ *va_arg(ap, uint32_t *) = sp->badfaxrun;
+ break;
+ default:
+ return (*sp->vgetparent)(tif, tag, ap);
+ }
+ return (1);
+}
+
+static void Fax3PrintDir(TIFF *tif, FILE *fd, long flags)
+{
+ Fax3BaseState *sp = Fax3State(tif);
+
+ assert(sp != 0);
+
+ (void)flags;
+ if (TIFFFieldSet(tif, FIELD_OPTIONS))
+ {
+ const char *sep = " ";
+ if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4)
+ {
+ fprintf(fd, " Group 4 Options:");
+ if (sp->groupoptions & GROUP4OPT_UNCOMPRESSED)
+ fprintf(fd, "%suncompressed data", sep);
+ }
+ else
+ {
+
+ fprintf(fd, " Group 3 Options:");
+ if (sp->groupoptions & GROUP3OPT_2DENCODING)
+ {
+ fprintf(fd, "%s2-d encoding", sep);
+ sep = "+";
+ }
+ if (sp->groupoptions & GROUP3OPT_FILLBITS)
+ {
+ fprintf(fd, "%sEOL padding", sep);
+ sep = "+";
+ }
+ if (sp->groupoptions & GROUP3OPT_UNCOMPRESSED)
+ fprintf(fd, "%suncompressed data", sep);
+ }
+ fprintf(fd, " (%" PRIu32 " = 0x%" PRIx32 ")\n", sp->groupoptions,
+ sp->groupoptions);
+ }
+ if (TIFFFieldSet(tif, FIELD_CLEANFAXDATA))
+ {
+ fprintf(fd, " Fax Data:");
+ switch (sp->cleanfaxdata)
+ {
+ case CLEANFAXDATA_CLEAN:
+ fprintf(fd, " clean");
+ break;
+ case CLEANFAXDATA_REGENERATED:
+ fprintf(fd, " receiver regenerated");
+ break;
+ case CLEANFAXDATA_UNCLEAN:
+ fprintf(fd, " uncorrected errors");
+ break;
+ }
+ fprintf(fd, " (%" PRIu16 " = 0x%" PRIx16 ")\n", sp->cleanfaxdata,
+ sp->cleanfaxdata);
+ }
+ if (TIFFFieldSet(tif, FIELD_BADFAXLINES))
+ fprintf(fd, " Bad Fax Lines: %" PRIu32 "\n", sp->badfaxlines);
+ if (TIFFFieldSet(tif, FIELD_BADFAXRUN))
+ fprintf(fd, " Consecutive Bad Fax Lines: %" PRIu32 "\n",
+ sp->badfaxrun);
+ if (sp->printdir)
+ (*sp->printdir)(tif, fd, flags);
+}
+
+static int InitCCITTFax3(TIFF *tif)
+{
+ static const char module[] = "InitCCITTFax3";
+ Fax3BaseState *sp;
+
+ /*
+ * Merge codec-specific tag information.
+ */
+ if (!_TIFFMergeFields(tif, faxFields, TIFFArrayCount(faxFields)))
+ {
+ TIFFErrorExtR(tif, "InitCCITTFax3",
+ "Merging common CCITT Fax codec-specific tags failed");
+ return 0;
+ }
+
+ /*
+ * Allocate state block so tag methods have storage to record values.
+ */
+ tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(Fax3CodecState));
+
+ if (tif->tif_data == NULL)
+ {
+ TIFFErrorExtR(tif, module, "No space for state block");
+ return (0);
+ }
+ _TIFFmemset(tif->tif_data, 0, sizeof(Fax3CodecState));
+
+ sp = Fax3State(tif);
+ sp->rw_mode = tif->tif_mode;
+
+ /*
+ * Override parent get/set field methods.
+ */
+ sp->vgetparent = tif->tif_tagmethods.vgetfield;
+ tif->tif_tagmethods.vgetfield = Fax3VGetField; /* hook for codec tags */
+ sp->vsetparent = tif->tif_tagmethods.vsetfield;
+ tif->tif_tagmethods.vsetfield = Fax3VSetField; /* hook for codec tags */
+ sp->printdir = tif->tif_tagmethods.printdir;
+ tif->tif_tagmethods.printdir = Fax3PrintDir; /* hook for codec tags */
+ sp->groupoptions = 0;
+
+ if (sp->rw_mode == O_RDONLY) /* FIXME: improve for in place update */
+ tif->tif_flags |= TIFF_NOBITREV; /* decoder does bit reversal */
+ DecoderState(tif)->runs = NULL;
+ TIFFSetField(tif, TIFFTAG_FAXFILLFUNC, _TIFFFax3fillruns);
+ EncoderState(tif)->refline = NULL;
+
+ /*
+ * Install codec methods.
+ */
+ tif->tif_fixuptags = Fax3FixupTags;
+ tif->tif_setupdecode = Fax3SetupState;
+ tif->tif_predecode = Fax3PreDecode;
+ tif->tif_decoderow = Fax3Decode1D;
+ tif->tif_decodestrip = Fax3Decode1D;
+ tif->tif_decodetile = Fax3Decode1D;
+ tif->tif_setupencode = Fax3SetupState;
+ tif->tif_preencode = Fax3PreEncode;
+ tif->tif_postencode = Fax3PostEncode;
+ tif->tif_encoderow = Fax3Encode;
+ tif->tif_encodestrip = Fax3Encode;
+ tif->tif_encodetile = Fax3Encode;
+ tif->tif_close = Fax3Close;
+ tif->tif_cleanup = Fax3Cleanup;
+
+ return (1);
+}
+
+int TIFFInitCCITTFax3(TIFF *tif, int scheme)
+{
+ (void)scheme;
+ if (InitCCITTFax3(tif))
+ {
+ /*
+ * Merge codec-specific tag information.
+ */
+ if (!_TIFFMergeFields(tif, fax3Fields, TIFFArrayCount(fax3Fields)))
+ {
+ TIFFErrorExtR(tif, "TIFFInitCCITTFax3",
+ "Merging CCITT Fax 3 codec-specific tags failed");
+ return 0;
+ }
+
+ /*
+ * The default format is Class/F-style w/o RTC.
+ */
+ return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_CLASSF);
+ }
+ else
+ return 01;
+}
+
+/*
+ * CCITT Group 4 (T.6) Facsimile-compatible
+ * Compression Scheme Support.
+ */
+
+#define SWAP(t, a, b) \
+ { \
+ t x; \
+ x = (a); \
+ (a) = (b); \
+ (b) = x; \
+ }
+/*
+ * Decode the requested amount of G4-encoded data.
+ */
+static int Fax4Decode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
+{
+ DECLARE_STATE_2D(tif, sp, "Fax4Decode");
+ (void)s;
+ if (occ % sp->b.rowbytes)
+ {
+ TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
+ return (-1);
+ }
+ CACHE_STATE(tif, sp);
+ while (occ > 0)
+ {
+ a0 = 0;
+ RunLength = 0;
+ pa = thisrun = sp->curruns;
+ pb = sp->refruns;
+ b1 = *pb++;
+#ifdef FAX3_DEBUG
+ printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d\n", BitAcc, BitsAvail);
+ printf("-------------------- %d\n", tif->tif_row);
+ fflush(stdout);
+#endif
+ EXPAND2D(EOFG4);
+ if (EOLcnt)
+ goto EOFG4;
+ if (((lastx + 7) >> 3) > (int)occ) /* check for buffer overrun */
+ {
+ TIFFErrorExtR(tif, module,
+ "Buffer overrun detected : %" TIFF_SSIZE_FORMAT
+ " bytes available, %d bits needed",
+ occ, lastx);
+ return -1;
+ }
+ (*sp->fill)(buf, thisrun, pa, lastx);
+ SETVALUE(0); /* imaginary change for reference */
+ SWAP(uint32_t *, sp->curruns, sp->refruns);
+ buf += sp->b.rowbytes;
+ occ -= sp->b.rowbytes;
+ sp->line++;
+ continue;
+ EOFG4:
+ NeedBits16(13, BADG4);
+ BADG4:
+#ifdef FAX3_DEBUG
+ if (GetBits(13) != 0x1001)
+ fputs("Bad EOFB\n", stderr);
+#endif
+ ClrBits(13);
+ if (((lastx + 7) >> 3) > (int)occ) /* check for buffer overrun */
+ {
+ TIFFErrorExtR(tif, module,
+ "Buffer overrun detected : %" TIFF_SSIZE_FORMAT
+ " bytes available, %d bits needed",
+ occ, lastx);
+ return -1;
+ }
+ (*sp->fill)(buf, thisrun, pa, lastx);
+ UNCACHE_STATE(tif, sp);
+ return (sp->line ? 1 : -1); /* don't error on badly-terminated strips */
+ }
+ UNCACHE_STATE(tif, sp);
+ return (1);
+}
+#undef SWAP
+
+/*
+ * Encode the requested amount of data.
+ */
+static int Fax4Encode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
+{
+ static const char module[] = "Fax4Encode";
+ Fax3CodecState *sp = EncoderState(tif);
+ (void)s;
+ if (cc % sp->b.rowbytes)
+ {
+ TIFFErrorExtR(tif, module, "Fractional scanlines cannot be written");
+ return (0);
+ }
+ while (cc > 0)
+ {
+ if (!Fax3Encode2DRow(tif, bp, sp->refline, sp->b.rowpixels))
+ return (0);
+ _TIFFmemcpy(sp->refline, bp, sp->b.rowbytes);
+ bp += sp->b.rowbytes;
+ cc -= sp->b.rowbytes;
+ }
+ return (1);
+}
+
+static int Fax4PostEncode(TIFF *tif)
+{
+ Fax3CodecState *sp = EncoderState(tif);
+
+ /* terminate strip w/ EOFB */
+ Fax3PutBits(tif, EOL, 12);
+ Fax3PutBits(tif, EOL, 12);
+ if (sp->bit != 8)
+ Fax3FlushBits(tif, sp);
+ return (1);
+}
+
+int TIFFInitCCITTFax4(TIFF *tif, int scheme)
+{
+ (void)scheme;
+ if (InitCCITTFax3(tif))
+ { /* reuse G3 support */
+ /*
+ * Merge codec-specific tag information.
+ */
+ if (!_TIFFMergeFields(tif, fax4Fields, TIFFArrayCount(fax4Fields)))
+ {
+ TIFFErrorExtR(tif, "TIFFInitCCITTFax4",
+ "Merging CCITT Fax 4 codec-specific tags failed");
+ return 0;
+ }
+
+ tif->tif_decoderow = Fax4Decode;
+ tif->tif_decodestrip = Fax4Decode;
+ tif->tif_decodetile = Fax4Decode;
+ tif->tif_encoderow = Fax4Encode;
+ tif->tif_encodestrip = Fax4Encode;
+ tif->tif_encodetile = Fax4Encode;
+ tif->tif_postencode = Fax4PostEncode;
+ /*
+ * Suppress RTC at the end of each strip.
+ */
+ return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_NORTC);
+ }
+ else
+ return (0);
+}
+
+/*
+ * CCITT Group 3 1-D Modified Huffman RLE Compression Support.
+ * (Compression algorithms 2 and 32771)
+ */
+
+/*
+ * Decode the requested amount of RLE-encoded data.
+ */
+static int Fax3DecodeRLE(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
+{
+ DECLARE_STATE(tif, sp, "Fax3DecodeRLE");
+ int mode = sp->b.mode;
+ (void)s;
+ if (occ % sp->b.rowbytes)
+ {
+ TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
+ return (-1);
+ }
+ CACHE_STATE(tif, sp);
+ thisrun = sp->curruns;
+ while (occ > 0)
+ {
+ a0 = 0;
+ RunLength = 0;
+ pa = thisrun;
+#ifdef FAX3_DEBUG
+ printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d\n", BitAcc, BitsAvail);
+ printf("-------------------- %" PRIu32 "\n", tif->tif_row);
+ fflush(stdout);
+#endif
+ EXPAND1D(EOFRLE);
+ (*sp->fill)(buf, thisrun, pa, lastx);
+ /*
+ * Cleanup at the end of the row.
+ */
+ if (mode & FAXMODE_BYTEALIGN)
+ {
+ int n = BitsAvail - (BitsAvail & ~7);
+ ClrBits(n);
+ }
+ else if (mode & FAXMODE_WORDALIGN)
+ {
+ int n = BitsAvail - (BitsAvail & ~15);
+ ClrBits(n);
+ if (BitsAvail == 0 && !isAligned(cp, uint16_t))
+ cp++;
+ }
+ buf += sp->b.rowbytes;
+ occ -= sp->b.rowbytes;
+ sp->line++;
+ continue;
+ EOFRLE: /* premature EOF */
+ (*sp->fill)(buf, thisrun, pa, lastx);
+ UNCACHE_STATE(tif, sp);
+ return (-1);
+ }
+ UNCACHE_STATE(tif, sp);
+ return (1);
+}
+
+int TIFFInitCCITTRLE(TIFF *tif, int scheme)
+{
+ (void)scheme;
+ if (InitCCITTFax3(tif))
+ { /* reuse G3 support */
+ tif->tif_decoderow = Fax3DecodeRLE;
+ tif->tif_decodestrip = Fax3DecodeRLE;
+ tif->tif_decodetile = Fax3DecodeRLE;
+ /*
+ * Suppress RTC+EOLs when encoding and byte-align data.
+ */
+ return TIFFSetField(tif, TIFFTAG_FAXMODE,
+ FAXMODE_NORTC | FAXMODE_NOEOL | FAXMODE_BYTEALIGN);
+ }
+ else
+ return (0);
+}
+
+int TIFFInitCCITTRLEW(TIFF *tif, int scheme)
+{
+ (void)scheme;
+ if (InitCCITTFax3(tif))
+ { /* reuse G3 support */
+ tif->tif_decoderow = Fax3DecodeRLE;
+ tif->tif_decodestrip = Fax3DecodeRLE;
+ tif->tif_decodetile = Fax3DecodeRLE;
+ /*
+ * Suppress RTC+EOLs when encoding and word-align data.
+ */
+ return TIFFSetField(tif, TIFFTAG_FAXMODE,
+ FAXMODE_NORTC | FAXMODE_NOEOL | FAXMODE_WORDALIGN);
+ }
+ else
+ return (0);
+}
+#endif /* CCITT_SUPPORT */
diff --git a/contrib/libs/libtiff/tif_fax3.h b/contrib/libs/libtiff/tif_fax3.h
new file mode 100644
index 0000000000..e095009bba
--- /dev/null
+++ b/contrib/libs/libtiff/tif_fax3.h
@@ -0,0 +1,648 @@
+/*
+ * Copyright (c) 1990-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _FAX3_
+#define _FAX3_
+/*
+ * TIFF Library.
+ *
+ * CCITT Group 3 (T.4) and Group 4 (T.6) Decompression Support.
+ *
+ * Decoder support is derived, with permission, from the code
+ * in Frank Cringle's viewfax program;
+ * Copyright (C) 1990, 1995 Frank D. Cringle.
+ */
+#include "tiff.h"
+
+/*
+ * To override the default routine used to image decoded
+ * spans one can use the pseudo tag TIFFTAG_FAXFILLFUNC.
+ * The routine must have the type signature given below;
+ * for example:
+ *
+ * fillruns(unsigned char* buf, uint32_t* runs, uint32_t* erun, uint32_t lastx)
+ *
+ * where buf is place to set the bits, runs is the array of b&w run
+ * lengths (white then black), erun is the last run in the array, and
+ * lastx is the width of the row in pixels. Fill routines can assume
+ * the run array has room for at least lastx runs and can overwrite
+ * data in the run array as needed (e.g. to append zero runs to bring
+ * the count up to a nice multiple).
+ */
+typedef void (*TIFFFaxFillFunc)(unsigned char *, uint32_t *, uint32_t *,
+ uint32_t);
+
+/*
+ * The default run filler; made external for other decoders.
+ */
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+ extern void _TIFFFax3fillruns(unsigned char *, uint32_t *, uint32_t *,
+ uint32_t);
+#if defined(__cplusplus)
+}
+#endif
+
+/* finite state machine codes */
+#define S_Null 0
+#define S_Pass 1
+#define S_Horiz 2
+#define S_V0 3
+#define S_VR 4
+#define S_VL 5
+#define S_Ext 6
+#define S_TermW 7
+#define S_TermB 8
+#define S_MakeUpW 9
+#define S_MakeUpB 10
+#define S_MakeUp 11
+#define S_EOL 12
+
+/* WARNING: do not change the layout of this structure as the HylaFAX software
+ */
+/* really depends on it. See http://bugzilla.maptools.org/show_bug.cgi?id=2636
+ */
+typedef struct
+{ /* state table entry */
+ unsigned char State; /* see above */
+ unsigned char Width; /* width of code in bits */
+ uint32_t Param; /* unsigned 32-bit run length in bits (holds on 16 bit
+ actually, but cannot be changed. See above warning) */
+} TIFFFaxTabEnt;
+
+extern const TIFFFaxTabEnt TIFFFaxMainTable[];
+extern const TIFFFaxTabEnt TIFFFaxWhiteTable[];
+extern const TIFFFaxTabEnt TIFFFaxBlackTable[];
+
+/*
+ * The following macros define the majority of the G3/G4 decoder
+ * algorithm using the state tables defined elsewhere. To build
+ * a decoder you need some setup code and some glue code. Note
+ * that you may also need/want to change the way the NeedBits*
+ * macros get input data if, for example, you know the data to be
+ * decoded is properly aligned and oriented (doing so before running
+ * the decoder can be a big performance win).
+ *
+ * Consult the decoder in the TIFF library for an idea of what you
+ * need to define and setup to make use of these definitions.
+ *
+ * NB: to enable a debugging version of these macros define FAX3_DEBUG
+ * before including this file. Trace output goes to stdout.
+ */
+
+#ifndef EndOfData
+#define EndOfData() (cp >= ep)
+#endif
+/*
+ * Need <=8 or <=16 bits of input data. Unlike viewfax we
+ * cannot use/assume a word-aligned, properly bit swizzled
+ * input data set because data may come from an arbitrarily
+ * aligned, read-only source such as a memory-mapped file.
+ * Note also that the viewfax decoder does not check for
+ * running off the end of the input data buffer. This is
+ * possible for G3-encoded data because it prescans the input
+ * data to count EOL markers, but can cause problems for G4
+ * data. In any event, we don't prescan and must watch for
+ * running out of data since we can't permit the library to
+ * scan past the end of the input data buffer.
+ *
+ * Finally, note that we must handle remaindered data at the end
+ * of a strip specially. The coder asks for a fixed number of
+ * bits when scanning for the next code. This may be more bits
+ * than are actually present in the data stream. If we appear
+ * to run out of data but still have some number of valid bits
+ * remaining then we makeup the requested amount with zeros and
+ * return successfully. If the returned data is incorrect then
+ * we should be called again and get a premature EOF error;
+ * otherwise we should get the right answer.
+ */
+#ifndef NeedBits8
+#define NeedBits8(n, eoflab) \
+ do \
+ { \
+ if (BitsAvail < (n)) \
+ { \
+ if (EndOfData()) \
+ { \
+ if (BitsAvail == 0) /* no valid bits */ \
+ goto eoflab; \
+ BitsAvail = (n); /* pad with zeros */ \
+ } \
+ else \
+ { \
+ BitAcc |= ((uint32_t)bitmap[*cp++]) << BitsAvail; \
+ BitsAvail += 8; \
+ } \
+ } \
+ } while (0)
+#endif
+#ifndef NeedBits16
+#define NeedBits16(n, eoflab) \
+ do \
+ { \
+ if (BitsAvail < (n)) \
+ { \
+ if (EndOfData()) \
+ { \
+ if (BitsAvail == 0) /* no valid bits */ \
+ goto eoflab; \
+ BitsAvail = (n); /* pad with zeros */ \
+ } \
+ else \
+ { \
+ BitAcc |= ((uint32_t)bitmap[*cp++]) << BitsAvail; \
+ if ((BitsAvail += 8) < (n)) \
+ { \
+ if (EndOfData()) \
+ { \
+ /* NB: we know BitsAvail is non-zero here */ \
+ BitsAvail = (n); /* pad with zeros */ \
+ } \
+ else \
+ { \
+ BitAcc |= ((uint32_t)bitmap[*cp++]) << BitsAvail; \
+ BitsAvail += 8; \
+ } \
+ } \
+ } \
+ } \
+ } while (0)
+#endif
+#define GetBits(n) (BitAcc & ((1 << (n)) - 1))
+#define ClrBits(n) \
+ do \
+ { \
+ BitsAvail -= (n); \
+ BitAcc >>= (n); \
+ } while (0)
+
+#ifdef FAX3_DEBUG
+static const char *StateNames[] = {
+ "Null ", "Pass ", "Horiz ", "V0 ", "VR ", "VL ", "Ext ",
+ "TermW ", "TermB ", "MakeUpW", "MakeUpB", "MakeUp ", "EOL ",
+};
+#define DEBUG_SHOW putchar(BitAcc & (1 << t) ? '1' : '0')
+#define LOOKUP8(wid, tab, eoflab) \
+ do \
+ { \
+ int t; \
+ NeedBits8(wid, eoflab); \
+ TabEnt = tab + GetBits(wid); \
+ printf("%08lX/%d: %s%5d\t", (long)BitAcc, BitsAvail, \
+ StateNames[TabEnt->State], TabEnt->Param); \
+ for (t = 0; t < TabEnt->Width; t++) \
+ DEBUG_SHOW; \
+ putchar('\n'); \
+ fflush(stdout); \
+ ClrBits(TabEnt->Width); \
+ } while (0)
+#define LOOKUP16(wid, tab, eoflab) \
+ do \
+ { \
+ int t; \
+ NeedBits16(wid, eoflab); \
+ TabEnt = tab + GetBits(wid); \
+ printf("%08lX/%d: %s%5d\t", (long)BitAcc, BitsAvail, \
+ StateNames[TabEnt->State], TabEnt->Param); \
+ for (t = 0; t < TabEnt->Width; t++) \
+ DEBUG_SHOW; \
+ putchar('\n'); \
+ fflush(stdout); \
+ ClrBits(TabEnt->Width); \
+ } while (0)
+
+#define SETVALUE(x) \
+ do \
+ { \
+ *pa++ = RunLength + (x); \
+ printf("SETVALUE: %d\t%d\n", RunLength + (x), a0); \
+ a0 += x; \
+ RunLength = 0; \
+ } while (0)
+#else
+#define LOOKUP8(wid, tab, eoflab) \
+ do \
+ { \
+ NeedBits8(wid, eoflab); \
+ TabEnt = tab + GetBits(wid); \
+ ClrBits(TabEnt->Width); \
+ } while (0)
+#define LOOKUP16(wid, tab, eoflab) \
+ do \
+ { \
+ NeedBits16(wid, eoflab); \
+ TabEnt = tab + GetBits(wid); \
+ ClrBits(TabEnt->Width); \
+ } while (0)
+
+/*
+ * Append a run to the run length array for the
+ * current row and reset decoding state.
+ */
+#define SETVALUE(x) \
+ do \
+ { \
+ if (pa >= thisrun + sp->nruns) \
+ { \
+ TIFFErrorExtR(tif, module, "Buffer overflow at line %u of %s %u", \
+ sp->line, isTiled(tif) ? "tile" : "strip", \
+ isTiled(tif) ? tif->tif_curtile \
+ : tif->tif_curstrip); \
+ return (-1); \
+ } \
+ *pa++ = RunLength + (x); \
+ a0 += (x); \
+ RunLength = 0; \
+ } while (0)
+#endif
+
+/*
+ * Synchronize input decoding at the start of each
+ * row by scanning for an EOL (if appropriate) and
+ * skipping any trash data that might be present
+ * after a decoding error. Note that the decoding
+ * done elsewhere that recognizes an EOL only consumes
+ * 11 consecutive zero bits. This means that if EOLcnt
+ * is non-zero then we still need to scan for the final flag
+ * bit that is part of the EOL code.
+ */
+#define SYNC_EOL(eoflab) \
+ do \
+ { \
+ if (EOLcnt == 0) \
+ { \
+ for (;;) \
+ { \
+ NeedBits16(11, eoflab); \
+ if (GetBits(11) == 0) \
+ break; \
+ ClrBits(1); \
+ } \
+ } \
+ for (;;) \
+ { \
+ NeedBits8(8, eoflab); \
+ if (GetBits(8)) \
+ break; \
+ ClrBits(8); \
+ } \
+ while (GetBits(1) == 0) \
+ ClrBits(1); \
+ ClrBits(1); /* EOL bit */ \
+ EOLcnt = 0; /* reset EOL counter/flag */ \
+ } while (0)
+
+/*
+ * Cleanup the array of runs after decoding a row.
+ * We adjust final runs to insure the user buffer is not
+ * overwritten and/or undecoded area is white filled.
+ */
+#define CLEANUP_RUNS() \
+ do \
+ { \
+ if (RunLength) \
+ SETVALUE(0); \
+ if (a0 != lastx) \
+ { \
+ badlength(a0, lastx); \
+ while (a0 > lastx && pa > thisrun) \
+ a0 -= *--pa; \
+ if (a0 < lastx) \
+ { \
+ if (a0 < 0) \
+ a0 = 0; \
+ if ((pa - thisrun) & 1) \
+ SETVALUE(0); \
+ SETVALUE(lastx - a0); \
+ } \
+ else if (a0 > lastx) \
+ { \
+ SETVALUE(lastx); \
+ SETVALUE(0); \
+ } \
+ } \
+ } while (0)
+
+/*
+ * Decode a line of 1D-encoded data.
+ *
+ * The line expanders are written as macros so that they can be reused
+ * but still have direct access to the local variables of the "calling"
+ * function.
+ *
+ * Note that unlike the original version we have to explicitly test for
+ * a0 >= lastx after each black/white run is decoded. This is because
+ * the original code depended on the input data being zero-padded to
+ * insure the decoder recognized an EOL before running out of data.
+ */
+#define EXPAND1D(eoflab) \
+ do \
+ { \
+ for (;;) \
+ { \
+ for (;;) \
+ { \
+ LOOKUP16(12, TIFFFaxWhiteTable, eof1d); \
+ switch (TabEnt->State) \
+ { \
+ case S_EOL: \
+ EOLcnt = 1; \
+ goto done1d; \
+ case S_TermW: \
+ SETVALUE(TabEnt->Param); \
+ goto doneWhite1d; \
+ case S_MakeUpW: \
+ case S_MakeUp: \
+ a0 += TabEnt->Param; \
+ RunLength += TabEnt->Param; \
+ break; \
+ default: \
+ unexpected("WhiteTable", a0); \
+ goto done1d; \
+ } \
+ } \
+ doneWhite1d: \
+ if (a0 >= lastx) \
+ goto done1d; \
+ for (;;) \
+ { \
+ LOOKUP16(13, TIFFFaxBlackTable, eof1d); \
+ switch (TabEnt->State) \
+ { \
+ case S_EOL: \
+ EOLcnt = 1; \
+ goto done1d; \
+ case S_TermB: \
+ SETVALUE(TabEnt->Param); \
+ goto doneBlack1d; \
+ case S_MakeUpB: \
+ case S_MakeUp: \
+ a0 += TabEnt->Param; \
+ RunLength += TabEnt->Param; \
+ break; \
+ default: \
+ unexpected("BlackTable", a0); \
+ goto done1d; \
+ } \
+ } \
+ doneBlack1d: \
+ if (a0 >= lastx) \
+ goto done1d; \
+ if (*(pa - 1) == 0 && *(pa - 2) == 0) \
+ pa -= 2; \
+ } \
+ eof1d: \
+ prematureEOF(a0); \
+ CLEANUP_RUNS(); \
+ goto eoflab; \
+ done1d: \
+ CLEANUP_RUNS(); \
+ } while (0)
+
+/*
+ * Update the value of b1 using the array
+ * of runs for the reference line.
+ */
+#define CHECK_b1 \
+ do \
+ { \
+ if (pa != thisrun) \
+ while (b1 <= a0 && b1 < lastx) \
+ { \
+ if (pb + 1 >= sp->refruns + sp->nruns) \
+ { \
+ TIFFErrorExtR( \
+ tif, module, "Buffer overflow at line %u of %s %u", \
+ sp->line, isTiled(tif) ? "tile" : "strip", \
+ isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
+ return (-1); \
+ } \
+ b1 += pb[0] + pb[1]; \
+ pb += 2; \
+ } \
+ } while (0)
+
+/*
+ * Expand a row of 2D-encoded data.
+ */
+#define EXPAND2D(eoflab) \
+ do \
+ { \
+ while (a0 < lastx) \
+ { \
+ if (pa >= thisrun + sp->nruns) \
+ { \
+ TIFFErrorExtR( \
+ tif, module, "Buffer overflow at line %u of %s %u", \
+ sp->line, isTiled(tif) ? "tile" : "strip", \
+ isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
+ return (-1); \
+ } \
+ LOOKUP8(7, TIFFFaxMainTable, eof2d); \
+ switch (TabEnt->State) \
+ { \
+ case S_Pass: \
+ CHECK_b1; \
+ if (pb + 1 >= sp->refruns + sp->nruns) \
+ { \
+ TIFFErrorExtR(tif, module, \
+ "Buffer overflow at line %u of %s %u", \
+ sp->line, \
+ isTiled(tif) ? "tile" : "strip", \
+ isTiled(tif) ? tif->tif_curtile \
+ : tif->tif_curstrip); \
+ return (-1); \
+ } \
+ b1 += *pb++; \
+ RunLength += b1 - a0; \
+ a0 = b1; \
+ b1 += *pb++; \
+ break; \
+ case S_Horiz: \
+ if ((pa - thisrun) & 1) \
+ { \
+ for (;;) \
+ { /* black first */ \
+ LOOKUP16(13, TIFFFaxBlackTable, eof2d); \
+ switch (TabEnt->State) \
+ { \
+ case S_TermB: \
+ SETVALUE(TabEnt->Param); \
+ goto doneWhite2da; \
+ case S_MakeUpB: \
+ case S_MakeUp: \
+ a0 += TabEnt->Param; \
+ RunLength += TabEnt->Param; \
+ break; \
+ default: \
+ goto badBlack2d; \
+ } \
+ } \
+ doneWhite2da:; \
+ for (;;) \
+ { /* then white */ \
+ LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \
+ switch (TabEnt->State) \
+ { \
+ case S_TermW: \
+ SETVALUE(TabEnt->Param); \
+ goto doneBlack2da; \
+ case S_MakeUpW: \
+ case S_MakeUp: \
+ a0 += TabEnt->Param; \
+ RunLength += TabEnt->Param; \
+ break; \
+ default: \
+ goto badWhite2d; \
+ } \
+ } \
+ doneBlack2da:; \
+ } \
+ else \
+ { \
+ for (;;) \
+ { /* white first */ \
+ LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \
+ switch (TabEnt->State) \
+ { \
+ case S_TermW: \
+ SETVALUE(TabEnt->Param); \
+ goto doneWhite2db; \
+ case S_MakeUpW: \
+ case S_MakeUp: \
+ a0 += TabEnt->Param; \
+ RunLength += TabEnt->Param; \
+ break; \
+ default: \
+ goto badWhite2d; \
+ } \
+ } \
+ doneWhite2db:; \
+ for (;;) \
+ { /* then black */ \
+ LOOKUP16(13, TIFFFaxBlackTable, eof2d); \
+ switch (TabEnt->State) \
+ { \
+ case S_TermB: \
+ SETVALUE(TabEnt->Param); \
+ goto doneBlack2db; \
+ case S_MakeUpB: \
+ case S_MakeUp: \
+ a0 += TabEnt->Param; \
+ RunLength += TabEnt->Param; \
+ break; \
+ default: \
+ goto badBlack2d; \
+ } \
+ } \
+ doneBlack2db:; \
+ } \
+ CHECK_b1; \
+ break; \
+ case S_V0: \
+ CHECK_b1; \
+ SETVALUE(b1 - a0); \
+ if (pb >= sp->refruns + sp->nruns) \
+ { \
+ TIFFErrorExtR(tif, module, \
+ "Buffer overflow at line %u of %s %u", \
+ sp->line, \
+ isTiled(tif) ? "tile" : "strip", \
+ isTiled(tif) ? tif->tif_curtile \
+ : tif->tif_curstrip); \
+ return (-1); \
+ } \
+ b1 += *pb++; \
+ break; \
+ case S_VR: \
+ CHECK_b1; \
+ SETVALUE(b1 - a0 + TabEnt->Param); \
+ if (pb >= sp->refruns + sp->nruns) \
+ { \
+ TIFFErrorExtR(tif, module, \
+ "Buffer overflow at line %u of %s %u", \
+ sp->line, \
+ isTiled(tif) ? "tile" : "strip", \
+ isTiled(tif) ? tif->tif_curtile \
+ : tif->tif_curstrip); \
+ return (-1); \
+ } \
+ b1 += *pb++; \
+ break; \
+ case S_VL: \
+ CHECK_b1; \
+ if (b1 < (int)(a0 + TabEnt->Param)) \
+ { \
+ unexpected("VL", a0); \
+ goto eol2d; \
+ } \
+ SETVALUE(b1 - a0 - TabEnt->Param); \
+ b1 -= *--pb; \
+ break; \
+ case S_Ext: \
+ *pa++ = lastx - a0; \
+ extension(a0); \
+ goto eol2d; \
+ case S_EOL: \
+ *pa++ = lastx - a0; \
+ NeedBits8(4, eof2d); \
+ if (GetBits(4)) \
+ unexpected("EOL", a0); \
+ ClrBits(4); \
+ EOLcnt = 1; \
+ goto eol2d; \
+ default: \
+ badMain2d: \
+ unexpected("MainTable", a0); \
+ goto eol2d; \
+ badBlack2d: \
+ unexpected("BlackTable", a0); \
+ goto eol2d; \
+ badWhite2d: \
+ unexpected("WhiteTable", a0); \
+ goto eol2d; \
+ eof2d: \
+ prematureEOF(a0); \
+ CLEANUP_RUNS(); \
+ goto eoflab; \
+ } \
+ } \
+ if (RunLength) \
+ { \
+ if (RunLength + a0 < lastx) \
+ { \
+ /* expect a final V0 */ \
+ NeedBits8(1, eof2d); \
+ if (!GetBits(1)) \
+ goto badMain2d; \
+ ClrBits(1); \
+ } \
+ SETVALUE(0); \
+ } \
+ eol2d: \
+ CLEANUP_RUNS(); \
+ } while (0)
+#endif /* _FAX3_ */
diff --git a/contrib/libs/libtiff/tif_fax3sm.c b/contrib/libs/libtiff/tif_fax3sm.c
new file mode 100644
index 0000000000..ba2fc532e8
--- /dev/null
+++ b/contrib/libs/libtiff/tif_fax3sm.c
@@ -0,0 +1,1261 @@
+/* WARNING, this file was automatically generated by the
+ mkg3states program */
+#include <stdint.h>
+#include "tiff.h"
+#include "tif_fax3.h"
+ const TIFFFaxTabEnt TIFFFaxMainTable[128] = {
+{12,7,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},
+{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{5,6,2},{3,1,0},{5,3,1},{3,1,0},
+{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},
+{4,3,1},{3,1,0},{5,7,3},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},
+{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{4,6,2},{3,1,0},
+{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0},
+{2,3,0},{3,1,0},{4,3,1},{3,1,0},{6,7,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},
+{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},
+{5,6,2},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},
+{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{4,7,3},{3,1,0},{5,3,1},{3,1,0},
+{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},
+{4,3,1},{3,1,0},{4,6,2},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},
+{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0}
+};
+ const TIFFFaxTabEnt TIFFFaxWhiteTable[4096] = {
+{12,11,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
+{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
+{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},
+{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},
+{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8},
+{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
+{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1792},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
+{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},
+{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},
+{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5},
+{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},
+{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
+{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
+{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},
+{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},
+{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},
+{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17},
+{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},
+{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},
+{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6},
+{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1856},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
+{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8},
+{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},
+{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},
+{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},
+{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},
+{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
+{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
+{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},
+{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},
+{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},
+{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
+{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},
+{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
+{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{11,12,2112},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
+{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
+{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},
+{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},
+{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},
+{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
+{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
+{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},
+{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},
+{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},
+{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},
+{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
+{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2368},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
+{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},
+{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},
+{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},
+{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},
+{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},
+{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},
+{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},
+{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
+{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},
+{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},
+{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},
+{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},
+{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},
+{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
+{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{11,12,1984},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
+{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},
+{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},
+{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},
+{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
+{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},
+{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
+{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
+{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
+{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},
+{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},
+{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},
+{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
+{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1920},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
+{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},
+{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},
+{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},
+{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},
+{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
+{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
+{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},
+{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},
+{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},
+{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},
+{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},
+{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},
+{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},
+{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2240},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
+{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},
+{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},
+{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},
+{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},
+{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},
+{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
+{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
+{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},
+{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},
+{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},
+{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
+{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},
+{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
+{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{11,12,2496},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
+{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
+{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},
+{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},
+{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},
+{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
+{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{12,11,0},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
+{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},
+{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},
+{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5},
+{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},
+{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
+{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1792},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
+{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6},
+{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},
+{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},
+{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17},
+{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},
+{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},
+{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},
+{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
+{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},
+{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},
+{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},
+{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},
+{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128},
+{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
+{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{11,11,1856},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
+{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},
+{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},
+{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6},
+{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
+{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},
+{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
+{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
+{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
+{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},
+{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},
+{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8},
+{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
+{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2176},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
+{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},
+{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},
+{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5},
+{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},
+{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
+{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
+{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},
+{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},
+{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},
+{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17},
+{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},
+{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},
+{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6},
+{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2432},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
+{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8},
+{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},
+{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},
+{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},
+{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},
+{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
+{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
+{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},
+{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},
+{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},
+{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
+{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},
+{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
+{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{11,12,2048},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
+{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
+{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},
+{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},
+{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},
+{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
+{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
+{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},
+{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},
+{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},
+{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},
+{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
+{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1920},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
+{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},
+{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},
+{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},
+{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},
+{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},
+{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},
+{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},
+{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
+{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},
+{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},
+{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},
+{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},
+{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},
+{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
+{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{11,12,2304},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
+{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},
+{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},
+{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},
+{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
+{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},
+{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
+{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
+{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
+{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},
+{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},
+{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},
+{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
+{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2560},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
+{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},
+{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},
+{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},
+{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},
+{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
+{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}
+};
+ const TIFFFaxTabEnt TIFFFaxBlackTable[8192] = {
+{12,11,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1792},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,11,23},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,20},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,11,25},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,128},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,56},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,30},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1856},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,57},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,11,21},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,54},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,52},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,48},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{11,12,2112},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,44},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,36},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,384},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,28},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,60},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,40},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2368},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{11,12,1984},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,50},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,34},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1664},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,26},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1408},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,32},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1920},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,61},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,42},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{10,13,1024},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,13,768},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,62},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2240},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,46},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,38},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,512},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,11,19},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,24},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,22},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{11,12,2496},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{12,11,0},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1792},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,23},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,20},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,11,25},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{10,12,192},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1280},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,31},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{11,11,1856},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,58},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,11,21},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,896},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,640},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,49},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2176},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,45},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,37},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{10,12,448},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,29},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,13,1536},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,41},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2432},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{11,12,2048},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,51},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,35},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,320},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,27},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,59},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,33},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1920},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,256},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,43},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,13,1152},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,55},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,63},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{11,12,2304},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,47},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,39},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,53},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,19},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,24},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,22},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2560},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{12,11,0},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1792},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,23},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,11,20},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,25},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,12,128},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,56},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,30},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{11,11,1856},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,57},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,21},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,54},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,52},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,48},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2112},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,44},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,36},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,12,384},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,28},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,60},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,40},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{11,12,2368},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,1984},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,50},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,34},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{10,13,1728},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,26},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,13,1472},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,32},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1920},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,61},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,42},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1088},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,832},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,62},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{11,12,2240},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,46},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,38},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,576},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,19},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,11,24},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,22},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2496},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{12,11,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{11,11,1792},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,23},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,11,20},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,25},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,192},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1344},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,31},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1856},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,58},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,21},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{10,13,960},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,13,704},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,49},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2176},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,45},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,37},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,448},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,29},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1600},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,41},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{11,12,2432},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2048},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,51},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,35},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,12,320},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,27},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,59},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,33},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{11,11,1920},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,256},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,43},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1216},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,55},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,63},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2304},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,47},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,39},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,53},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,19},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,11,24},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,11,22},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2560},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2}
+};
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/contrib/libs/libtiff/tif_flush.c b/contrib/libs/libtiff/tif_flush.c
new file mode 100644
index 0000000000..ff9c1e247a
--- /dev/null
+++ b/contrib/libs/libtiff/tif_flush.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ */
+#include "tiffiop.h"
+
+int TIFFFlush(TIFF *tif)
+{
+ if (tif->tif_mode == O_RDONLY)
+ return 1;
+
+ if (!TIFFFlushData(tif))
+ return (0);
+
+ /* In update (r+) mode we try to detect the case where
+ only the strip/tile map has been altered, and we try to
+ rewrite only that portion of the directory without
+ making any other changes */
+
+ if ((tif->tif_flags & TIFF_DIRTYSTRIP) &&
+ !(tif->tif_flags & TIFF_DIRTYDIRECT) && tif->tif_mode == O_RDWR)
+ {
+ if (TIFFForceStrileArrayWriting(tif))
+ return 1;
+ }
+
+ if ((tif->tif_flags & (TIFF_DIRTYDIRECT | TIFF_DIRTYSTRIP)) &&
+ !TIFFRewriteDirectory(tif))
+ return (0);
+
+ return (1);
+}
+
+/*
+ * This is an advanced writing function that must be used in a particular
+ * sequence, and together with TIFFDeferStrileArrayWriting(),
+ * to make its intended effect. Its aim is to force the writing of
+ * the [Strip/Tile][Offsets/ByteCounts] arrays at the end of the file, when
+ * they have not yet been rewritten.
+ *
+ * The typical sequence of calls is:
+ * TIFFOpen()
+ * [ TIFFCreateDirectory(tif) ]
+ * Set fields with calls to TIFFSetField(tif, ...)
+ * TIFFDeferStrileArrayWriting(tif)
+ * TIFFWriteCheck(tif, ...)
+ * TIFFWriteDirectory(tif)
+ * ... potentially create other directories and come back to the above directory
+ * TIFFForceStrileArrayWriting(tif)
+ *
+ * Returns 1 in case of success, 0 otherwise.
+ */
+int TIFFForceStrileArrayWriting(TIFF *tif)
+{
+ static const char module[] = "TIFFForceStrileArrayWriting";
+ const int isTiled = TIFFIsTiled(tif);
+
+ if (tif->tif_mode == O_RDONLY)
+ {
+ TIFFErrorExtR(tif, tif->tif_name, "File opened in read-only mode");
+ return 0;
+ }
+ if (tif->tif_diroff == 0)
+ {
+ TIFFErrorExtR(tif, module, "Directory has not yet been written");
+ return 0;
+ }
+ if ((tif->tif_flags & TIFF_DIRTYDIRECT) != 0)
+ {
+ TIFFErrorExtR(tif, module,
+ "Directory has changes other than the strile arrays. "
+ "TIFFRewriteDirectory() should be called instead");
+ return 0;
+ }
+
+ if (!(tif->tif_flags & TIFF_DIRTYSTRIP))
+ {
+ if (!(tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0))
+ {
+ TIFFErrorExtR(tif, module,
+ "Function not called together with "
+ "TIFFDeferStrileArrayWriting()");
+ return 0;
+ }
+
+ if (tif->tif_dir.td_stripoffset_p == NULL && !TIFFSetupStrips(tif))
+ return 0;
+ }
+
+ if (_TIFFRewriteField(tif,
+ isTiled ? TIFFTAG_TILEOFFSETS : TIFFTAG_STRIPOFFSETS,
+ TIFF_LONG8, tif->tif_dir.td_nstrips,
+ tif->tif_dir.td_stripoffset_p) &&
+ _TIFFRewriteField(
+ tif, isTiled ? TIFFTAG_TILEBYTECOUNTS : TIFFTAG_STRIPBYTECOUNTS,
+ TIFF_LONG8, tif->tif_dir.td_nstrips,
+ tif->tif_dir.td_stripbytecount_p))
+ {
+ tif->tif_flags &= ~TIFF_DIRTYSTRIP;
+ tif->tif_flags &= ~TIFF_BEENWRITING;
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
+ * Flush buffered data to the file.
+ *
+ * Frank Warmerdam'2000: I modified this to return 1 if TIFF_BEENWRITING
+ * is not set, so that TIFFFlush() will proceed to write out the directory.
+ * The documentation says returning 1 is an error indicator, but not having
+ * been writing isn't exactly a an error. Hopefully this doesn't cause
+ * problems for other people.
+ */
+int TIFFFlushData(TIFF *tif)
+{
+ if ((tif->tif_flags & TIFF_BEENWRITING) == 0)
+ return (1);
+ if (tif->tif_flags & TIFF_POSTENCODE)
+ {
+ tif->tif_flags &= ~TIFF_POSTENCODE;
+ if (!(*tif->tif_postencode)(tif))
+ return (0);
+ }
+ return (TIFFFlushData1(tif));
+}
diff --git a/contrib/libs/libtiff/tif_getimage.c b/contrib/libs/libtiff/tif_getimage.c
new file mode 100644
index 0000000000..41f7dfd77e
--- /dev/null
+++ b/contrib/libs/libtiff/tif_getimage.c
@@ -0,0 +1,3360 @@
+/*
+ * Copyright (c) 1991-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library
+ *
+ * Read and return a packed RGBA image.
+ */
+#include "tiffiop.h"
+#include <limits.h>
+#include <stdio.h>
+
+static int gtTileContig(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t);
+static int gtTileSeparate(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t);
+static int gtStripContig(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t);
+static int gtStripSeparate(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t);
+static int PickContigCase(TIFFRGBAImage *);
+static int PickSeparateCase(TIFFRGBAImage *);
+
+static int BuildMapUaToAa(TIFFRGBAImage *img);
+static int BuildMapBitdepth16To8(TIFFRGBAImage *img);
+
+static const char photoTag[] = "PhotometricInterpretation";
+
+/*
+ * Helper constants used in Orientation tag handling
+ */
+#define FLIP_VERTICALLY 0x01
+#define FLIP_HORIZONTALLY 0x02
+
+#define EMSG_BUF_SIZE 1024
+
+/*
+ * Color conversion constants. We will define display types here.
+ */
+
+static const TIFFDisplay display_sRGB = {
+ {/* XYZ -> luminance matrix */
+ {3.2410F, -1.5374F, -0.4986F},
+ {-0.9692F, 1.8760F, 0.0416F},
+ {0.0556F, -0.2040F, 1.0570F}},
+ 100.0F,
+ 100.0F,
+ 100.0F, /* Light o/p for reference white */
+ 255,
+ 255,
+ 255, /* Pixel values for ref. white */
+ 1.0F,
+ 1.0F,
+ 1.0F, /* Residual light o/p for black pixel */
+ 2.4F,
+ 2.4F,
+ 2.4F, /* Gamma values for the three guns */
+};
+
+/*
+ * Check the image to see if TIFFReadRGBAImage can deal with it.
+ * 1/0 is returned according to whether or not the image can
+ * be handled. If 0 is returned, emsg contains the reason
+ * why it is being rejected.
+ */
+int TIFFRGBAImageOK(TIFF *tif, char emsg[EMSG_BUF_SIZE])
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ uint16_t photometric;
+ int colorchannels;
+
+ if (!tif->tif_decodestatus)
+ {
+ snprintf(emsg, EMSG_BUF_SIZE,
+ "Sorry, requested compression method is not configured");
+ return (0);
+ }
+ switch (td->td_bitspersample)
+ {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ case 16:
+ break;
+ default:
+ snprintf(emsg, EMSG_BUF_SIZE,
+ "Sorry, can not handle images with %" PRIu16
+ "-bit samples",
+ td->td_bitspersample);
+ return (0);
+ }
+ if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP)
+ {
+ snprintf(
+ emsg, EMSG_BUF_SIZE,
+ "Sorry, can not handle images with IEEE floating-point samples");
+ return (0);
+ }
+ colorchannels = td->td_samplesperpixel - td->td_extrasamples;
+ if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric))
+ {
+ switch (colorchannels)
+ {
+ case 1:
+ photometric = PHOTOMETRIC_MINISBLACK;
+ break;
+ case 3:
+ photometric = PHOTOMETRIC_RGB;
+ break;
+ default:
+ snprintf(emsg, EMSG_BUF_SIZE, "Missing needed %s tag",
+ photoTag);
+ return (0);
+ }
+ }
+ switch (photometric)
+ {
+ case PHOTOMETRIC_MINISWHITE:
+ case PHOTOMETRIC_MINISBLACK:
+ case PHOTOMETRIC_PALETTE:
+ if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
+ td->td_samplesperpixel != 1 && td->td_bitspersample < 8)
+ {
+ snprintf(
+ emsg, EMSG_BUF_SIZE,
+ "Sorry, can not handle contiguous data with %s=%" PRIu16
+ ", "
+ "and %s=%" PRIu16 " and Bits/Sample=%" PRIu16 "",
+ photoTag, photometric, "Samples/pixel",
+ td->td_samplesperpixel, td->td_bitspersample);
+ return (0);
+ }
+ /*
+ * We should likely validate that any extra samples are either
+ * to be ignored, or are alpha, and if alpha we should try to use
+ * them. But for now we won't bother with this.
+ */
+ break;
+ case PHOTOMETRIC_YCBCR:
+ /*
+ * TODO: if at all meaningful and useful, make more complete
+ * support check here, or better still, refactor to let supporting
+ * code decide whether there is support and what meaningful
+ * error to return
+ */
+ break;
+ case PHOTOMETRIC_RGB:
+ if (colorchannels < 3)
+ {
+ snprintf(emsg, EMSG_BUF_SIZE,
+ "Sorry, can not handle RGB image with %s=%d",
+ "Color channels", colorchannels);
+ return (0);
+ }
+ break;
+ case PHOTOMETRIC_SEPARATED:
+ {
+ uint16_t inkset;
+ TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
+ if (inkset != INKSET_CMYK)
+ {
+ snprintf(emsg, EMSG_BUF_SIZE,
+ "Sorry, can not handle separated image with %s=%d",
+ "InkSet", inkset);
+ return 0;
+ }
+ if (td->td_samplesperpixel < 4)
+ {
+ snprintf(
+ emsg, EMSG_BUF_SIZE,
+ "Sorry, can not handle separated image with %s=%" PRIu16,
+ "Samples/pixel", td->td_samplesperpixel);
+ return 0;
+ }
+ break;
+ }
+ case PHOTOMETRIC_LOGL:
+ if (td->td_compression != COMPRESSION_SGILOG)
+ {
+ snprintf(emsg, EMSG_BUF_SIZE,
+ "Sorry, LogL data must have %s=%d", "Compression",
+ COMPRESSION_SGILOG);
+ return (0);
+ }
+ break;
+ case PHOTOMETRIC_LOGLUV:
+ if (td->td_compression != COMPRESSION_SGILOG &&
+ td->td_compression != COMPRESSION_SGILOG24)
+ {
+ snprintf(emsg, EMSG_BUF_SIZE,
+ "Sorry, LogLuv data must have %s=%d or %d",
+ "Compression", COMPRESSION_SGILOG,
+ COMPRESSION_SGILOG24);
+ return (0);
+ }
+ if (td->td_planarconfig != PLANARCONFIG_CONTIG)
+ {
+ snprintf(emsg, EMSG_BUF_SIZE,
+ "Sorry, can not handle LogLuv images with %s=%" PRIu16,
+ "Planarconfiguration", td->td_planarconfig);
+ return (0);
+ }
+ if (td->td_samplesperpixel != 3 || colorchannels != 3)
+ {
+ snprintf(emsg, EMSG_BUF_SIZE,
+ "Sorry, can not handle image with %s=%" PRIu16
+ ", %s=%d",
+ "Samples/pixel", td->td_samplesperpixel,
+ "colorchannels", colorchannels);
+ return 0;
+ }
+ break;
+ case PHOTOMETRIC_CIELAB:
+ if (td->td_samplesperpixel != 3 || colorchannels != 3 ||
+ (td->td_bitspersample != 8 && td->td_bitspersample != 16))
+ {
+ snprintf(emsg, EMSG_BUF_SIZE,
+ "Sorry, can not handle image with %s=%" PRIu16
+ ", %s=%d and %s=%" PRIu16,
+ "Samples/pixel", td->td_samplesperpixel,
+ "colorchannels", colorchannels, "Bits/sample",
+ td->td_bitspersample);
+ return 0;
+ }
+ break;
+ default:
+ snprintf(emsg, EMSG_BUF_SIZE,
+ "Sorry, can not handle image with %s=%" PRIu16, photoTag,
+ photometric);
+ return (0);
+ }
+ return (1);
+}
+
+void TIFFRGBAImageEnd(TIFFRGBAImage *img)
+{
+ if (img->Map)
+ {
+ _TIFFfreeExt(img->tif, img->Map);
+ img->Map = NULL;
+ }
+ if (img->BWmap)
+ {
+ _TIFFfreeExt(img->tif, img->BWmap);
+ img->BWmap = NULL;
+ }
+ if (img->PALmap)
+ {
+ _TIFFfreeExt(img->tif, img->PALmap);
+ img->PALmap = NULL;
+ }
+ if (img->ycbcr)
+ {
+ _TIFFfreeExt(img->tif, img->ycbcr);
+ img->ycbcr = NULL;
+ }
+ if (img->cielab)
+ {
+ _TIFFfreeExt(img->tif, img->cielab);
+ img->cielab = NULL;
+ }
+ if (img->UaToAa)
+ {
+ _TIFFfreeExt(img->tif, img->UaToAa);
+ img->UaToAa = NULL;
+ }
+ if (img->Bitdepth16To8)
+ {
+ _TIFFfreeExt(img->tif, img->Bitdepth16To8);
+ img->Bitdepth16To8 = NULL;
+ }
+
+ if (img->redcmap)
+ {
+ _TIFFfreeExt(img->tif, img->redcmap);
+ _TIFFfreeExt(img->tif, img->greencmap);
+ _TIFFfreeExt(img->tif, img->bluecmap);
+ img->redcmap = img->greencmap = img->bluecmap = NULL;
+ }
+}
+
+static int isCCITTCompression(TIFF *tif)
+{
+ uint16_t compress;
+ TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress);
+ return (compress == COMPRESSION_CCITTFAX3 ||
+ compress == COMPRESSION_CCITTFAX4 ||
+ compress == COMPRESSION_CCITTRLE ||
+ compress == COMPRESSION_CCITTRLEW);
+}
+
+int TIFFRGBAImageBegin(TIFFRGBAImage *img, TIFF *tif, int stop,
+ char emsg[EMSG_BUF_SIZE])
+{
+ uint16_t *sampleinfo;
+ uint16_t extrasamples;
+ uint16_t planarconfig;
+ uint16_t compress;
+ int colorchannels;
+ uint16_t *red_orig, *green_orig, *blue_orig;
+ int n_color;
+
+ if (!TIFFRGBAImageOK(tif, emsg))
+ return 0;
+
+ /* Initialize to normal values */
+ img->row_offset = 0;
+ img->col_offset = 0;
+ img->redcmap = NULL;
+ img->greencmap = NULL;
+ img->bluecmap = NULL;
+ img->Map = NULL;
+ img->BWmap = NULL;
+ img->PALmap = NULL;
+ img->ycbcr = NULL;
+ img->cielab = NULL;
+ img->UaToAa = NULL;
+ img->Bitdepth16To8 = NULL;
+ img->req_orientation = ORIENTATION_BOTLEFT; /* It is the default */
+
+ img->tif = tif;
+ img->stoponerr = stop;
+ TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample);
+ switch (img->bitspersample)
+ {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ case 16:
+ break;
+ default:
+ snprintf(emsg, EMSG_BUF_SIZE,
+ "Sorry, can not handle images with %" PRIu16
+ "-bit samples",
+ img->bitspersample);
+ goto fail_return;
+ }
+ img->alpha = 0;
+ TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel);
+ TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, &extrasamples,
+ &sampleinfo);
+ if (extrasamples >= 1)
+ {
+ switch (sampleinfo[0])
+ {
+ case EXTRASAMPLE_UNSPECIFIED: /* Workaround for some images without
+ */
+ if (img->samplesperpixel >
+ 3) /* correct info about alpha channel */
+ img->alpha = EXTRASAMPLE_ASSOCALPHA;
+ break;
+ case EXTRASAMPLE_ASSOCALPHA: /* data is pre-multiplied */
+ case EXTRASAMPLE_UNASSALPHA: /* data is not pre-multiplied */
+ img->alpha = sampleinfo[0];
+ break;
+ }
+ }
+
+#ifdef DEFAULT_EXTRASAMPLE_AS_ALPHA
+ if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric))
+ img->photometric = PHOTOMETRIC_MINISWHITE;
+
+ if (extrasamples == 0 && img->samplesperpixel == 4 &&
+ img->photometric == PHOTOMETRIC_RGB)
+ {
+ img->alpha = EXTRASAMPLE_ASSOCALPHA;
+ extrasamples = 1;
+ }
+#endif
+
+ colorchannels = img->samplesperpixel - extrasamples;
+ TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress);
+ TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
+ if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric))
+ {
+ switch (colorchannels)
+ {
+ case 1:
+ if (isCCITTCompression(tif))
+ img->photometric = PHOTOMETRIC_MINISWHITE;
+ else
+ img->photometric = PHOTOMETRIC_MINISBLACK;
+ break;
+ case 3:
+ img->photometric = PHOTOMETRIC_RGB;
+ break;
+ default:
+ snprintf(emsg, EMSG_BUF_SIZE, "Missing needed %s tag",
+ photoTag);
+ goto fail_return;
+ }
+ }
+ switch (img->photometric)
+ {
+ case PHOTOMETRIC_PALETTE:
+ if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &red_orig, &green_orig,
+ &blue_orig))
+ {
+ snprintf(emsg, EMSG_BUF_SIZE,
+ "Missing required \"Colormap\" tag");
+ goto fail_return;
+ }
+
+ /* copy the colormaps so we can modify them */
+ n_color = (1U << img->bitspersample);
+ img->redcmap =
+ (uint16_t *)_TIFFmallocExt(tif, sizeof(uint16_t) * n_color);
+ img->greencmap =
+ (uint16_t *)_TIFFmallocExt(tif, sizeof(uint16_t) * n_color);
+ img->bluecmap =
+ (uint16_t *)_TIFFmallocExt(tif, sizeof(uint16_t) * n_color);
+ if (!img->redcmap || !img->greencmap || !img->bluecmap)
+ {
+ snprintf(emsg, EMSG_BUF_SIZE,
+ "Out of memory for colormap copy");
+ goto fail_return;
+ }
+
+ _TIFFmemcpy(img->redcmap, red_orig, n_color * 2);
+ _TIFFmemcpy(img->greencmap, green_orig, n_color * 2);
+ _TIFFmemcpy(img->bluecmap, blue_orig, n_color * 2);
+
+ /* fall through... */
+ case PHOTOMETRIC_MINISWHITE:
+ case PHOTOMETRIC_MINISBLACK:
+ if (planarconfig == PLANARCONFIG_CONTIG &&
+ img->samplesperpixel != 1 && img->bitspersample < 8)
+ {
+ snprintf(
+ emsg, EMSG_BUF_SIZE,
+ "Sorry, can not handle contiguous data with %s=%" PRIu16
+ ", "
+ "and %s=%" PRIu16 " and Bits/Sample=%" PRIu16,
+ photoTag, img->photometric, "Samples/pixel",
+ img->samplesperpixel, img->bitspersample);
+ goto fail_return;
+ }
+ break;
+ case PHOTOMETRIC_YCBCR:
+ /* It would probably be nice to have a reality check here. */
+ if (planarconfig == PLANARCONFIG_CONTIG)
+ /* can rely on libjpeg to convert to RGB */
+ /* XXX should restore current state on exit */
+ switch (compress)
+ {
+ case COMPRESSION_JPEG:
+ /*
+ * TODO: when complete tests verify complete
+ * desubsampling and YCbCr handling, remove use of
+ * TIFFTAG_JPEGCOLORMODE in favor of tif_getimage.c
+ * native handling
+ */
+ TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE,
+ JPEGCOLORMODE_RGB);
+ img->photometric = PHOTOMETRIC_RGB;
+ break;
+ default:
+ /* do nothing */;
+ break;
+ }
+ /*
+ * TODO: if at all meaningful and useful, make more complete
+ * support check here, or better still, refactor to let supporting
+ * code decide whether there is support and what meaningful
+ * error to return
+ */
+ break;
+ case PHOTOMETRIC_RGB:
+ if (colorchannels < 3)
+ {
+ snprintf(emsg, EMSG_BUF_SIZE,
+ "Sorry, can not handle RGB image with %s=%d",
+ "Color channels", colorchannels);
+ goto fail_return;
+ }
+ break;
+ case PHOTOMETRIC_SEPARATED:
+ {
+ uint16_t inkset;
+ TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
+ if (inkset != INKSET_CMYK)
+ {
+ snprintf(
+ emsg, EMSG_BUF_SIZE,
+ "Sorry, can not handle separated image with %s=%" PRIu16,
+ "InkSet", inkset);
+ goto fail_return;
+ }
+ if (img->samplesperpixel < 4)
+ {
+ snprintf(
+ emsg, EMSG_BUF_SIZE,
+ "Sorry, can not handle separated image with %s=%" PRIu16,
+ "Samples/pixel", img->samplesperpixel);
+ goto fail_return;
+ }
+ }
+ break;
+ case PHOTOMETRIC_LOGL:
+ if (compress != COMPRESSION_SGILOG)
+ {
+ snprintf(emsg, EMSG_BUF_SIZE,
+ "Sorry, LogL data must have %s=%d", "Compression",
+ COMPRESSION_SGILOG);
+ goto fail_return;
+ }
+ TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
+ img->photometric = PHOTOMETRIC_MINISBLACK; /* little white lie */
+ img->bitspersample = 8;
+ break;
+ case PHOTOMETRIC_LOGLUV:
+ if (compress != COMPRESSION_SGILOG &&
+ compress != COMPRESSION_SGILOG24)
+ {
+ snprintf(emsg, EMSG_BUF_SIZE,
+ "Sorry, LogLuv data must have %s=%d or %d",
+ "Compression", COMPRESSION_SGILOG,
+ COMPRESSION_SGILOG24);
+ goto fail_return;
+ }
+ if (planarconfig != PLANARCONFIG_CONTIG)
+ {
+ snprintf(emsg, EMSG_BUF_SIZE,
+ "Sorry, can not handle LogLuv images with %s=%" PRIu16,
+ "Planarconfiguration", planarconfig);
+ return (0);
+ }
+ TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
+ img->photometric = PHOTOMETRIC_RGB; /* little white lie */
+ img->bitspersample = 8;
+ break;
+ case PHOTOMETRIC_CIELAB:
+ break;
+ default:
+ snprintf(emsg, EMSG_BUF_SIZE,
+ "Sorry, can not handle image with %s=%" PRIu16, photoTag,
+ img->photometric);
+ goto fail_return;
+ }
+ TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width);
+ TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height);
+ TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation);
+ img->isContig =
+ !(planarconfig == PLANARCONFIG_SEPARATE && img->samplesperpixel > 1);
+ if (img->isContig)
+ {
+ if (!PickContigCase(img))
+ {
+ snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle image");
+ goto fail_return;
+ }
+ }
+ else
+ {
+ if (!PickSeparateCase(img))
+ {
+ snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle image");
+ goto fail_return;
+ }
+ }
+ return 1;
+
+fail_return:
+ TIFFRGBAImageEnd(img);
+ return 0;
+}
+
+int TIFFRGBAImageGet(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
+ uint32_t h)
+{
+ if (img->get == NULL)
+ {
+ TIFFErrorExtR(img->tif, TIFFFileName(img->tif),
+ "No \"get\" routine setup");
+ return (0);
+ }
+ if (img->put.any == NULL)
+ {
+ TIFFErrorExtR(
+ img->tif, TIFFFileName(img->tif),
+ "No \"put\" routine setupl; probably can not handle image format");
+ return (0);
+ }
+ return (*img->get)(img, raster, w, h);
+}
+
+/*
+ * Read the specified image into an ABGR-format rastertaking in account
+ * specified orientation.
+ */
+int TIFFReadRGBAImageOriented(TIFF *tif, uint32_t rwidth, uint32_t rheight,
+ uint32_t *raster, int orientation, int stop)
+{
+ char emsg[EMSG_BUF_SIZE] = "";
+ TIFFRGBAImage img;
+ int ok;
+
+ if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop, emsg))
+ {
+ img.req_orientation = (uint16_t)orientation;
+ /* XXX verify rwidth and rheight against width and height */
+ ok = TIFFRGBAImageGet(&img, raster + (rheight - img.height) * rwidth,
+ rwidth, img.height);
+ TIFFRGBAImageEnd(&img);
+ }
+ else
+ {
+ TIFFErrorExtR(tif, TIFFFileName(tif), "%s", emsg);
+ ok = 0;
+ }
+ return (ok);
+}
+
+/*
+ * Read the specified image into an ABGR-format raster. Use bottom left
+ * origin for raster by default.
+ */
+int TIFFReadRGBAImage(TIFF *tif, uint32_t rwidth, uint32_t rheight,
+ uint32_t *raster, int stop)
+{
+ return TIFFReadRGBAImageOriented(tif, rwidth, rheight, raster,
+ ORIENTATION_BOTLEFT, stop);
+}
+
+static int setorientation(TIFFRGBAImage *img)
+{
+ switch (img->orientation)
+ {
+ case ORIENTATION_TOPLEFT:
+ case ORIENTATION_LEFTTOP:
+ if (img->req_orientation == ORIENTATION_TOPRIGHT ||
+ img->req_orientation == ORIENTATION_RIGHTTOP)
+ return FLIP_HORIZONTALLY;
+ else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
+ img->req_orientation == ORIENTATION_RIGHTBOT)
+ return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
+ else if (img->req_orientation == ORIENTATION_BOTLEFT ||
+ img->req_orientation == ORIENTATION_LEFTBOT)
+ return FLIP_VERTICALLY;
+ else
+ return 0;
+ case ORIENTATION_TOPRIGHT:
+ case ORIENTATION_RIGHTTOP:
+ if (img->req_orientation == ORIENTATION_TOPLEFT ||
+ img->req_orientation == ORIENTATION_LEFTTOP)
+ return FLIP_HORIZONTALLY;
+ else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
+ img->req_orientation == ORIENTATION_RIGHTBOT)
+ return FLIP_VERTICALLY;
+ else if (img->req_orientation == ORIENTATION_BOTLEFT ||
+ img->req_orientation == ORIENTATION_LEFTBOT)
+ return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
+ else
+ return 0;
+ case ORIENTATION_BOTRIGHT:
+ case ORIENTATION_RIGHTBOT:
+ if (img->req_orientation == ORIENTATION_TOPLEFT ||
+ img->req_orientation == ORIENTATION_LEFTTOP)
+ return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
+ else if (img->req_orientation == ORIENTATION_TOPRIGHT ||
+ img->req_orientation == ORIENTATION_RIGHTTOP)
+ return FLIP_VERTICALLY;
+ else if (img->req_orientation == ORIENTATION_BOTLEFT ||
+ img->req_orientation == ORIENTATION_LEFTBOT)
+ return FLIP_HORIZONTALLY;
+ else
+ return 0;
+ case ORIENTATION_BOTLEFT:
+ case ORIENTATION_LEFTBOT:
+ if (img->req_orientation == ORIENTATION_TOPLEFT ||
+ img->req_orientation == ORIENTATION_LEFTTOP)
+ return FLIP_VERTICALLY;
+ else if (img->req_orientation == ORIENTATION_TOPRIGHT ||
+ img->req_orientation == ORIENTATION_RIGHTTOP)
+ return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
+ else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
+ img->req_orientation == ORIENTATION_RIGHTBOT)
+ return FLIP_HORIZONTALLY;
+ else
+ return 0;
+ default: /* NOTREACHED */
+ return 0;
+ }
+}
+
+/*
+ * Get an tile-organized image that has
+ * PlanarConfiguration contiguous if SamplesPerPixel > 1
+ * or
+ * SamplesPerPixel == 1
+ */
+static int gtTileContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
+ uint32_t h)
+{
+ TIFF *tif = img->tif;
+ tileContigRoutine put = img->put.contig;
+ uint32_t col, row, y, rowstoread;
+ tmsize_t pos;
+ uint32_t tw, th;
+ unsigned char *buf = NULL;
+ int32_t fromskew, toskew;
+ uint32_t nrow;
+ int ret = 1, flip;
+ uint32_t this_tw, tocol;
+ int32_t this_toskew, leftmost_toskew;
+ int32_t leftmost_fromskew;
+ uint32_t leftmost_tw;
+ tmsize_t bufsize;
+
+ bufsize = TIFFTileSize(tif);
+ if (bufsize == 0)
+ {
+ TIFFErrorExtR(tif, TIFFFileName(tif), "%s", "No space for tile buffer");
+ return (0);
+ }
+
+ TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
+ TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
+
+ flip = setorientation(img);
+ if (flip & FLIP_VERTICALLY)
+ {
+ if ((tw + w) > INT_MAX)
+ {
+ TIFFErrorExtR(tif, TIFFFileName(tif), "%s",
+ "unsupported tile size (too wide)");
+ return (0);
+ }
+ y = h - 1;
+ toskew = -(int32_t)(tw + w);
+ }
+ else
+ {
+ if (tw > (INT_MAX + w))
+ {
+ TIFFErrorExtR(tif, TIFFFileName(tif), "%s",
+ "unsupported tile size (too wide)");
+ return (0);
+ }
+ y = 0;
+ toskew = -(int32_t)(tw - w);
+ }
+
+ /*
+ * Leftmost tile is clipped on left side if col_offset > 0.
+ */
+ leftmost_fromskew = img->col_offset % tw;
+ leftmost_tw = tw - leftmost_fromskew;
+ leftmost_toskew = toskew + leftmost_fromskew;
+ for (row = 0; ret != 0 && row < h; row += nrow)
+ {
+ rowstoread = th - (row + img->row_offset) % th;
+ nrow = (row + rowstoread > h ? h - row : rowstoread);
+ fromskew = leftmost_fromskew;
+ this_tw = leftmost_tw;
+ this_toskew = leftmost_toskew;
+ tocol = 0;
+ col = img->col_offset;
+ while (tocol < w)
+ {
+ if (_TIFFReadTileAndAllocBuffer(tif, (void **)&buf, bufsize, col,
+ row + img->row_offset, 0,
+ 0) == (tmsize_t)(-1) &&
+ (buf == NULL || img->stoponerr))
+ {
+ ret = 0;
+ break;
+ }
+ pos = ((row + img->row_offset) % th) * TIFFTileRowSize(tif) +
+ ((tmsize_t)fromskew * img->samplesperpixel);
+ if (tocol + this_tw > w)
+ {
+ /*
+ * Rightmost tile is clipped on right side.
+ */
+ fromskew = tw - (w - tocol);
+ this_tw = tw - fromskew;
+ this_toskew = toskew + fromskew;
+ }
+ tmsize_t roffset = (tmsize_t)y * w + tocol;
+ (*put)(img, raster + roffset, tocol, y, this_tw, nrow, fromskew,
+ this_toskew, buf + pos);
+ tocol += this_tw;
+ col += this_tw;
+ /*
+ * After the leftmost tile, tiles are no longer clipped on left
+ * side.
+ */
+ fromskew = 0;
+ this_tw = tw;
+ this_toskew = toskew;
+ }
+
+ y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow);
+ }
+ _TIFFfreeExt(img->tif, buf);
+
+ if (flip & FLIP_HORIZONTALLY)
+ {
+ uint32_t line;
+
+ for (line = 0; line < h; line++)
+ {
+ uint32_t *left = raster + (line * w);
+ uint32_t *right = left + w - 1;
+
+ while (left < right)
+ {
+ uint32_t temp = *left;
+ *left = *right;
+ *right = temp;
+ left++;
+ right--;
+ }
+ }
+ }
+
+ return (ret);
+}
+
+/*
+ * Get an tile-organized image that has
+ * SamplesPerPixel > 1
+ * PlanarConfiguration separated
+ * We assume that all such images are RGB.
+ */
+static int gtTileSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
+ uint32_t h)
+{
+ TIFF *tif = img->tif;
+ tileSeparateRoutine put = img->put.separate;
+ uint32_t col, row, y, rowstoread;
+ tmsize_t pos;
+ uint32_t tw, th;
+ unsigned char *buf = NULL;
+ unsigned char *p0 = NULL;
+ unsigned char *p1 = NULL;
+ unsigned char *p2 = NULL;
+ unsigned char *pa = NULL;
+ tmsize_t tilesize;
+ tmsize_t bufsize;
+ int32_t fromskew, toskew;
+ int alpha = img->alpha;
+ uint32_t nrow;
+ int ret = 1, flip;
+ uint16_t colorchannels;
+ uint32_t this_tw, tocol;
+ int32_t this_toskew, leftmost_toskew;
+ int32_t leftmost_fromskew;
+ uint32_t leftmost_tw;
+
+ tilesize = TIFFTileSize(tif);
+ bufsize =
+ _TIFFMultiplySSize(tif, alpha ? 4 : 3, tilesize, "gtTileSeparate");
+ if (bufsize == 0)
+ {
+ return (0);
+ }
+
+ TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
+ TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
+
+ flip = setorientation(img);
+ if (flip & FLIP_VERTICALLY)
+ {
+ if ((tw + w) > INT_MAX)
+ {
+ TIFFErrorExtR(tif, TIFFFileName(tif), "%s",
+ "unsupported tile size (too wide)");
+ return (0);
+ }
+ y = h - 1;
+ toskew = -(int32_t)(tw + w);
+ }
+ else
+ {
+ if (tw > (INT_MAX + w))
+ {
+ TIFFErrorExtR(tif, TIFFFileName(tif), "%s",
+ "unsupported tile size (too wide)");
+ return (0);
+ }
+ y = 0;
+ toskew = -(int32_t)(tw - w);
+ }
+
+ switch (img->photometric)
+ {
+ case PHOTOMETRIC_MINISWHITE:
+ case PHOTOMETRIC_MINISBLACK:
+ case PHOTOMETRIC_PALETTE:
+ colorchannels = 1;
+ break;
+
+ default:
+ colorchannels = 3;
+ break;
+ }
+
+ /*
+ * Leftmost tile is clipped on left side if col_offset > 0.
+ */
+ leftmost_fromskew = img->col_offset % tw;
+ leftmost_tw = tw - leftmost_fromskew;
+ leftmost_toskew = toskew + leftmost_fromskew;
+ for (row = 0; ret != 0 && row < h; row += nrow)
+ {
+ rowstoread = th - (row + img->row_offset) % th;
+ nrow = (row + rowstoread > h ? h - row : rowstoread);
+ fromskew = leftmost_fromskew;
+ this_tw = leftmost_tw;
+ this_toskew = leftmost_toskew;
+ tocol = 0;
+ col = img->col_offset;
+ while (tocol < w)
+ {
+ if (buf == NULL)
+ {
+ if (_TIFFReadTileAndAllocBuffer(tif, (void **)&buf, bufsize,
+ col, row + img->row_offset, 0,
+ 0) == (tmsize_t)(-1) &&
+ (buf == NULL || img->stoponerr))
+ {
+ ret = 0;
+ break;
+ }
+ p0 = buf;
+ if (colorchannels == 1)
+ {
+ p2 = p1 = p0;
+ pa = (alpha ? (p0 + 3 * tilesize) : NULL);
+ }
+ else
+ {
+ p1 = p0 + tilesize;
+ p2 = p1 + tilesize;
+ pa = (alpha ? (p2 + tilesize) : NULL);
+ }
+ }
+ else if (TIFFReadTile(tif, p0, col, row + img->row_offset, 0, 0) ==
+ (tmsize_t)(-1) &&
+ img->stoponerr)
+ {
+ ret = 0;
+ break;
+ }
+ if (colorchannels > 1 &&
+ TIFFReadTile(tif, p1, col, row + img->row_offset, 0, 1) ==
+ (tmsize_t)(-1) &&
+ img->stoponerr)
+ {
+ ret = 0;
+ break;
+ }
+ if (colorchannels > 1 &&
+ TIFFReadTile(tif, p2, col, row + img->row_offset, 0, 2) ==
+ (tmsize_t)(-1) &&
+ img->stoponerr)
+ {
+ ret = 0;
+ break;
+ }
+ if (alpha &&
+ TIFFReadTile(tif, pa, col, row + img->row_offset, 0,
+ colorchannels) == (tmsize_t)(-1) &&
+ img->stoponerr)
+ {
+ ret = 0;
+ break;
+ }
+
+ pos = ((row + img->row_offset) % th) * TIFFTileRowSize(tif) +
+ ((tmsize_t)fromskew * img->samplesperpixel);
+ if (tocol + this_tw > w)
+ {
+ /*
+ * Rightmost tile is clipped on right side.
+ */
+ fromskew = tw - (w - tocol);
+ this_tw = tw - fromskew;
+ this_toskew = toskew + fromskew;
+ }
+ tmsize_t roffset = (tmsize_t)y * w + tocol;
+ (*put)(img, raster + roffset, tocol, y, this_tw, nrow, fromskew,
+ this_toskew, p0 + pos, p1 + pos, p2 + pos,
+ (alpha ? (pa + pos) : NULL));
+ tocol += this_tw;
+ col += this_tw;
+ /*
+ * After the leftmost tile, tiles are no longer clipped on left
+ * side.
+ */
+ fromskew = 0;
+ this_tw = tw;
+ this_toskew = toskew;
+ }
+
+ y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow);
+ }
+
+ if (flip & FLIP_HORIZONTALLY)
+ {
+ uint32_t line;
+
+ for (line = 0; line < h; line++)
+ {
+ uint32_t *left = raster + (line * w);
+ uint32_t *right = left + w - 1;
+
+ while (left < right)
+ {
+ uint32_t temp = *left;
+ *left = *right;
+ *right = temp;
+ left++;
+ right--;
+ }
+ }
+ }
+
+ _TIFFfreeExt(img->tif, buf);
+ return (ret);
+}
+
+/*
+ * Get a strip-organized image that has
+ * PlanarConfiguration contiguous if SamplesPerPixel > 1
+ * or
+ * SamplesPerPixel == 1
+ */
+static int gtStripContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
+ uint32_t h)
+{
+ TIFF *tif = img->tif;
+ tileContigRoutine put = img->put.contig;
+ uint32_t row, y, nrow, nrowsub, rowstoread;
+ tmsize_t pos;
+ unsigned char *buf = NULL;
+ uint32_t rowsperstrip;
+ uint16_t subsamplinghor, subsamplingver;
+ uint32_t imagewidth = img->width;
+ tmsize_t scanline;
+ int32_t fromskew, toskew;
+ int ret = 1, flip;
+ tmsize_t maxstripsize;
+
+ TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, &subsamplinghor,
+ &subsamplingver);
+ if (subsamplingver == 0)
+ {
+ TIFFErrorExtR(tif, TIFFFileName(tif),
+ "Invalid vertical YCbCr subsampling");
+ return (0);
+ }
+
+ maxstripsize = TIFFStripSize(tif);
+
+ flip = setorientation(img);
+ if (flip & FLIP_VERTICALLY)
+ {
+ if (w > INT_MAX)
+ {
+ TIFFErrorExtR(tif, TIFFFileName(tif), "Width overflow");
+ return (0);
+ }
+ y = h - 1;
+ toskew = -(int32_t)(w + w);
+ }
+ else
+ {
+ y = 0;
+ toskew = -(int32_t)(w - w);
+ }
+
+ TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
+
+ scanline = TIFFScanlineSize(tif);
+ fromskew = (w < imagewidth ? imagewidth - w : 0);
+ for (row = 0; row < h; row += nrow)
+ {
+ uint32_t temp;
+ rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
+ nrow = (row + rowstoread > h ? h - row : rowstoread);
+ nrowsub = nrow;
+ if ((nrowsub % subsamplingver) != 0)
+ nrowsub += subsamplingver - nrowsub % subsamplingver;
+ temp = (row + img->row_offset) % rowsperstrip + nrowsub;
+ if (scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline))
+ {
+ TIFFErrorExtR(tif, TIFFFileName(tif),
+ "Integer overflow in gtStripContig");
+ return 0;
+ }
+ if (_TIFFReadEncodedStripAndAllocBuffer(
+ tif, TIFFComputeStrip(tif, row + img->row_offset, 0),
+ (void **)(&buf), maxstripsize,
+ temp * scanline) == (tmsize_t)(-1) &&
+ (buf == NULL || img->stoponerr))
+ {
+ ret = 0;
+ break;
+ }
+
+ pos = ((row + img->row_offset) % rowsperstrip) * scanline +
+ ((tmsize_t)img->col_offset * img->samplesperpixel);
+ tmsize_t roffset = (tmsize_t)y * w;
+ (*put)(img, raster + roffset, 0, y, w, nrow, fromskew, toskew,
+ buf + pos);
+ y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow);
+ }
+
+ if (flip & FLIP_HORIZONTALLY)
+ {
+ uint32_t line;
+
+ for (line = 0; line < h; line++)
+ {
+ uint32_t *left = raster + (line * w);
+ uint32_t *right = left + w - 1;
+
+ while (left < right)
+ {
+ uint32_t temp = *left;
+ *left = *right;
+ *right = temp;
+ left++;
+ right--;
+ }
+ }
+ }
+
+ _TIFFfreeExt(img->tif, buf);
+ return (ret);
+}
+
+/*
+ * Get a strip-organized image with
+ * SamplesPerPixel > 1
+ * PlanarConfiguration separated
+ * We assume that all such images are RGB.
+ */
+static int gtStripSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
+ uint32_t h)
+{
+ TIFF *tif = img->tif;
+ tileSeparateRoutine put = img->put.separate;
+ unsigned char *buf = NULL;
+ unsigned char *p0 = NULL, *p1 = NULL, *p2 = NULL, *pa = NULL;
+ uint32_t row, y, nrow, rowstoread;
+ tmsize_t pos;
+ tmsize_t scanline;
+ uint32_t rowsperstrip, offset_row;
+ uint32_t imagewidth = img->width;
+ tmsize_t stripsize;
+ tmsize_t bufsize;
+ int32_t fromskew, toskew;
+ int alpha = img->alpha;
+ int ret = 1, flip;
+ uint16_t colorchannels;
+
+ stripsize = TIFFStripSize(tif);
+ bufsize =
+ _TIFFMultiplySSize(tif, alpha ? 4 : 3, stripsize, "gtStripSeparate");
+ if (bufsize == 0)
+ {
+ return (0);
+ }
+
+ flip = setorientation(img);
+ if (flip & FLIP_VERTICALLY)
+ {
+ if (w > INT_MAX)
+ {
+ TIFFErrorExtR(tif, TIFFFileName(tif), "Width overflow");
+ return (0);
+ }
+ y = h - 1;
+ toskew = -(int32_t)(w + w);
+ }
+ else
+ {
+ y = 0;
+ toskew = -(int32_t)(w - w);
+ }
+
+ switch (img->photometric)
+ {
+ case PHOTOMETRIC_MINISWHITE:
+ case PHOTOMETRIC_MINISBLACK:
+ case PHOTOMETRIC_PALETTE:
+ colorchannels = 1;
+ break;
+
+ default:
+ colorchannels = 3;
+ break;
+ }
+
+ TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
+ scanline = TIFFScanlineSize(tif);
+ fromskew = (w < imagewidth ? imagewidth - w : 0);
+ for (row = 0; row < h; row += nrow)
+ {
+ uint32_t temp;
+ rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
+ nrow = (row + rowstoread > h ? h - row : rowstoread);
+ offset_row = row + img->row_offset;
+ temp = (row + img->row_offset) % rowsperstrip + nrow;
+ if (scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline))
+ {
+ TIFFErrorExtR(tif, TIFFFileName(tif),
+ "Integer overflow in gtStripSeparate");
+ return 0;
+ }
+ if (buf == NULL)
+ {
+ if (_TIFFReadEncodedStripAndAllocBuffer(
+ tif, TIFFComputeStrip(tif, offset_row, 0), (void **)&buf,
+ bufsize, temp * scanline) == (tmsize_t)(-1) &&
+ (buf == NULL || img->stoponerr))
+ {
+ ret = 0;
+ break;
+ }
+ p0 = buf;
+ if (colorchannels == 1)
+ {
+ p2 = p1 = p0;
+ pa = (alpha ? (p0 + 3 * stripsize) : NULL);
+ }
+ else
+ {
+ p1 = p0 + stripsize;
+ p2 = p1 + stripsize;
+ pa = (alpha ? (p2 + stripsize) : NULL);
+ }
+ }
+ else if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0),
+ p0, temp * scanline) == (tmsize_t)(-1) &&
+ img->stoponerr)
+ {
+ ret = 0;
+ break;
+ }
+ if (colorchannels > 1 &&
+ TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1), p1,
+ temp * scanline) == (tmsize_t)(-1) &&
+ img->stoponerr)
+ {
+ ret = 0;
+ break;
+ }
+ if (colorchannels > 1 &&
+ TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2), p2,
+ temp * scanline) == (tmsize_t)(-1) &&
+ img->stoponerr)
+ {
+ ret = 0;
+ break;
+ }
+ if (alpha)
+ {
+ if (TIFFReadEncodedStrip(
+ tif, TIFFComputeStrip(tif, offset_row, colorchannels), pa,
+ temp * scanline) == (tmsize_t)(-1) &&
+ img->stoponerr)
+ {
+ ret = 0;
+ break;
+ }
+ }
+
+ pos = ((row + img->row_offset) % rowsperstrip) * scanline +
+ ((tmsize_t)img->col_offset * img->samplesperpixel);
+ tmsize_t roffset = (tmsize_t)y * w;
+ (*put)(img, raster + roffset, 0, y, w, nrow, fromskew, toskew, p0 + pos,
+ p1 + pos, p2 + pos, (alpha ? (pa + pos) : NULL));
+ y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow);
+ }
+
+ if (flip & FLIP_HORIZONTALLY)
+ {
+ uint32_t line;
+
+ for (line = 0; line < h; line++)
+ {
+ uint32_t *left = raster + (line * w);
+ uint32_t *right = left + w - 1;
+
+ while (left < right)
+ {
+ uint32_t temp = *left;
+ *left = *right;
+ *right = temp;
+ left++;
+ right--;
+ }
+ }
+ }
+
+ _TIFFfreeExt(img->tif, buf);
+ return (ret);
+}
+
+/*
+ * The following routines move decoded data returned
+ * from the TIFF library into rasters filled with packed
+ * ABGR pixels (i.e. suitable for passing to lrecwrite.)
+ *
+ * The routines have been created according to the most
+ * important cases and optimized. PickContigCase and
+ * PickSeparateCase analyze the parameters and select
+ * the appropriate "get" and "put" routine to use.
+ */
+#define REPEAT8(op) \
+ REPEAT4(op); \
+ REPEAT4(op)
+#define REPEAT4(op) \
+ REPEAT2(op); \
+ REPEAT2(op)
+#define REPEAT2(op) \
+ op; \
+ op
+#define CASE8(x, op) \
+ switch (x) \
+ { \
+ case 7: \
+ op; /*-fallthrough*/ \
+ case 6: \
+ op; /*-fallthrough*/ \
+ case 5: \
+ op; /*-fallthrough*/ \
+ case 4: \
+ op; /*-fallthrough*/ \
+ case 3: \
+ op; /*-fallthrough*/ \
+ case 2: \
+ op; /*-fallthrough*/ \
+ case 1: \
+ op; \
+ }
+#define CASE4(x, op) \
+ switch (x) \
+ { \
+ case 3: \
+ op; /*-fallthrough*/ \
+ case 2: \
+ op; /*-fallthrough*/ \
+ case 1: \
+ op; \
+ }
+#define NOP
+
+#define UNROLL8(w, op1, op2) \
+ { \
+ uint32_t _x; \
+ for (_x = w; _x >= 8; _x -= 8) \
+ { \
+ op1; \
+ REPEAT8(op2); \
+ } \
+ if (_x > 0) \
+ { \
+ op1; \
+ CASE8(_x, op2); \
+ } \
+ }
+#define UNROLL4(w, op1, op2) \
+ { \
+ uint32_t _x; \
+ for (_x = w; _x >= 4; _x -= 4) \
+ { \
+ op1; \
+ REPEAT4(op2); \
+ } \
+ if (_x > 0) \
+ { \
+ op1; \
+ CASE4(_x, op2); \
+ } \
+ }
+#define UNROLL2(w, op1, op2) \
+ { \
+ uint32_t _x; \
+ for (_x = w; _x >= 2; _x -= 2) \
+ { \
+ op1; \
+ REPEAT2(op2); \
+ } \
+ if (_x) \
+ { \
+ op1; \
+ op2; \
+ } \
+ }
+
+#define SKEW(r, g, b, skew) \
+ { \
+ r += skew; \
+ g += skew; \
+ b += skew; \
+ }
+#define SKEW4(r, g, b, a, skew) \
+ { \
+ r += skew; \
+ g += skew; \
+ b += skew; \
+ a += skew; \
+ }
+
+#define A1 (((uint32_t)0xffL) << 24)
+#define PACK(r, g, b) \
+ ((uint32_t)(r) | ((uint32_t)(g) << 8) | ((uint32_t)(b) << 16) | A1)
+#define PACK4(r, g, b, a) \
+ ((uint32_t)(r) | ((uint32_t)(g) << 8) | ((uint32_t)(b) << 16) | \
+ ((uint32_t)(a) << 24))
+#define W2B(v) (((v) >> 8) & 0xff)
+/* TODO: PACKW should have be made redundant in favor of Bitdepth16To8 LUT */
+#define PACKW(r, g, b) \
+ ((uint32_t)W2B(r) | ((uint32_t)W2B(g) << 8) | ((uint32_t)W2B(b) << 16) | A1)
+#define PACKW4(r, g, b, a) \
+ ((uint32_t)W2B(r) | ((uint32_t)W2B(g) << 8) | ((uint32_t)W2B(b) << 16) | \
+ ((uint32_t)W2B(a) << 24))
+
+#define DECLAREContigPutFunc(name) \
+ static void name(TIFFRGBAImage *img, uint32_t *cp, uint32_t x, uint32_t y, \
+ uint32_t w, uint32_t h, int32_t fromskew, int32_t toskew, \
+ unsigned char *pp)
+
+/*
+ * 8-bit palette => colormap/RGB
+ */
+DECLAREContigPutFunc(put8bitcmaptile)
+{
+ uint32_t **PALmap = img->PALmap;
+ int samplesperpixel = img->samplesperpixel;
+
+ (void)y;
+ for (; h > 0; --h)
+ {
+ for (x = w; x > 0; --x)
+ {
+ *cp++ = PALmap[*pp][0];
+ pp += samplesperpixel;
+ }
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 4-bit palette => colormap/RGB
+ */
+DECLAREContigPutFunc(put4bitcmaptile)
+{
+ uint32_t **PALmap = img->PALmap;
+
+ (void)x;
+ (void)y;
+ fromskew /= 2;
+ for (; h > 0; --h)
+ {
+ uint32_t *bw;
+ UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++);
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 2-bit palette => colormap/RGB
+ */
+DECLAREContigPutFunc(put2bitcmaptile)
+{
+ uint32_t **PALmap = img->PALmap;
+
+ (void)x;
+ (void)y;
+ fromskew /= 4;
+ for (; h > 0; --h)
+ {
+ uint32_t *bw;
+ UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++);
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 1-bit palette => colormap/RGB
+ */
+DECLAREContigPutFunc(put1bitcmaptile)
+{
+ uint32_t **PALmap = img->PALmap;
+
+ (void)x;
+ (void)y;
+ fromskew /= 8;
+ for (; h > 0; --h)
+ {
+ uint32_t *bw;
+ UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++);
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 8-bit greyscale => colormap/RGB
+ */
+DECLAREContigPutFunc(putgreytile)
+{
+ int samplesperpixel = img->samplesperpixel;
+ uint32_t **BWmap = img->BWmap;
+
+ (void)y;
+ for (; h > 0; --h)
+ {
+ for (x = w; x > 0; --x)
+ {
+ *cp++ = BWmap[*pp][0];
+ pp += samplesperpixel;
+ }
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 8-bit greyscale with associated alpha => colormap/RGBA
+ */
+DECLAREContigPutFunc(putagreytile)
+{
+ int samplesperpixel = img->samplesperpixel;
+ uint32_t **BWmap = img->BWmap;
+
+ (void)y;
+ for (; h > 0; --h)
+ {
+ for (x = w; x > 0; --x)
+ {
+ *cp++ = BWmap[*pp][0] & ((uint32_t) * (pp + 1) << 24 | ~A1);
+ pp += samplesperpixel;
+ }
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 16-bit greyscale => colormap/RGB
+ */
+DECLAREContigPutFunc(put16bitbwtile)
+{
+ int samplesperpixel = img->samplesperpixel;
+ uint32_t **BWmap = img->BWmap;
+
+ (void)y;
+ for (; h > 0; --h)
+ {
+ uint16_t *wp = (uint16_t *)pp;
+
+ for (x = w; x > 0; --x)
+ {
+ /* use high order byte of 16bit value */
+
+ *cp++ = BWmap[*wp >> 8][0];
+ pp += 2 * samplesperpixel;
+ wp += samplesperpixel;
+ }
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 1-bit bilevel => colormap/RGB
+ */
+DECLAREContigPutFunc(put1bitbwtile)
+{
+ uint32_t **BWmap = img->BWmap;
+
+ (void)x;
+ (void)y;
+ fromskew /= 8;
+ for (; h > 0; --h)
+ {
+ uint32_t *bw;
+ UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++);
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 2-bit greyscale => colormap/RGB
+ */
+DECLAREContigPutFunc(put2bitbwtile)
+{
+ uint32_t **BWmap = img->BWmap;
+
+ (void)x;
+ (void)y;
+ fromskew /= 4;
+ for (; h > 0; --h)
+ {
+ uint32_t *bw;
+ UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++);
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 4-bit greyscale => colormap/RGB
+ */
+DECLAREContigPutFunc(put4bitbwtile)
+{
+ uint32_t **BWmap = img->BWmap;
+
+ (void)x;
+ (void)y;
+ fromskew /= 2;
+ for (; h > 0; --h)
+ {
+ uint32_t *bw;
+ UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++);
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 8-bit packed samples, no Map => RGB
+ */
+DECLAREContigPutFunc(putRGBcontig8bittile)
+{
+ int samplesperpixel = img->samplesperpixel;
+
+ (void)x;
+ (void)y;
+ fromskew *= samplesperpixel;
+ for (; h > 0; --h)
+ {
+ UNROLL8(w, NOP, *cp++ = PACK(pp[0], pp[1], pp[2]);
+ pp += samplesperpixel);
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 8-bit packed samples => RGBA w/ associated alpha
+ * (known to have Map == NULL)
+ */
+DECLAREContigPutFunc(putRGBAAcontig8bittile)
+{
+ int samplesperpixel = img->samplesperpixel;
+
+ (void)x;
+ (void)y;
+ fromskew *= samplesperpixel;
+ for (; h > 0; --h)
+ {
+ UNROLL8(w, NOP, *cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]);
+ pp += samplesperpixel);
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 8-bit packed samples => RGBA w/ unassociated alpha
+ * (known to have Map == NULL)
+ */
+DECLAREContigPutFunc(putRGBUAcontig8bittile)
+{
+ int samplesperpixel = img->samplesperpixel;
+ (void)y;
+ fromskew *= samplesperpixel;
+ for (; h > 0; --h)
+ {
+ uint32_t r, g, b, a;
+ uint8_t *m;
+ for (x = w; x > 0; --x)
+ {
+ a = pp[3];
+ m = img->UaToAa + ((size_t)a << 8);
+ r = m[pp[0]];
+ g = m[pp[1]];
+ b = m[pp[2]];
+ *cp++ = PACK4(r, g, b, a);
+ pp += samplesperpixel;
+ }
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 16-bit packed samples => RGB
+ */
+DECLAREContigPutFunc(putRGBcontig16bittile)
+{
+ int samplesperpixel = img->samplesperpixel;
+ uint16_t *wp = (uint16_t *)pp;
+ (void)y;
+ fromskew *= samplesperpixel;
+ for (; h > 0; --h)
+ {
+ for (x = w; x > 0; --x)
+ {
+ *cp++ = PACK(img->Bitdepth16To8[wp[0]], img->Bitdepth16To8[wp[1]],
+ img->Bitdepth16To8[wp[2]]);
+ wp += samplesperpixel;
+ }
+ cp += toskew;
+ wp += fromskew;
+ }
+}
+
+/*
+ * 16-bit packed samples => RGBA w/ associated alpha
+ * (known to have Map == NULL)
+ */
+DECLAREContigPutFunc(putRGBAAcontig16bittile)
+{
+ int samplesperpixel = img->samplesperpixel;
+ uint16_t *wp = (uint16_t *)pp;
+ (void)y;
+ fromskew *= samplesperpixel;
+ for (; h > 0; --h)
+ {
+ for (x = w; x > 0; --x)
+ {
+ *cp++ = PACK4(img->Bitdepth16To8[wp[0]], img->Bitdepth16To8[wp[1]],
+ img->Bitdepth16To8[wp[2]], img->Bitdepth16To8[wp[3]]);
+ wp += samplesperpixel;
+ }
+ cp += toskew;
+ wp += fromskew;
+ }
+}
+
+/*
+ * 16-bit packed samples => RGBA w/ unassociated alpha
+ * (known to have Map == NULL)
+ */
+DECLAREContigPutFunc(putRGBUAcontig16bittile)
+{
+ int samplesperpixel = img->samplesperpixel;
+ uint16_t *wp = (uint16_t *)pp;
+ (void)y;
+ fromskew *= samplesperpixel;
+ for (; h > 0; --h)
+ {
+ uint32_t r, g, b, a;
+ uint8_t *m;
+ for (x = w; x > 0; --x)
+ {
+ a = img->Bitdepth16To8[wp[3]];
+ m = img->UaToAa + ((size_t)a << 8);
+ r = m[img->Bitdepth16To8[wp[0]]];
+ g = m[img->Bitdepth16To8[wp[1]]];
+ b = m[img->Bitdepth16To8[wp[2]]];
+ *cp++ = PACK4(r, g, b, a);
+ wp += samplesperpixel;
+ }
+ cp += toskew;
+ wp += fromskew;
+ }
+}
+
+/*
+ * 8-bit packed CMYK samples w/o Map => RGB
+ *
+ * NB: The conversion of CMYK->RGB is *very* crude.
+ */
+DECLAREContigPutFunc(putRGBcontig8bitCMYKtile)
+{
+ int samplesperpixel = img->samplesperpixel;
+ uint16_t r, g, b, k;
+
+ (void)x;
+ (void)y;
+ fromskew *= samplesperpixel;
+ for (; h > 0; --h)
+ {
+ UNROLL8(w, NOP, k = 255 - pp[3]; r = (k * (255 - pp[0])) / 255;
+ g = (k * (255 - pp[1])) / 255; b = (k * (255 - pp[2])) / 255;
+ *cp++ = PACK(r, g, b); pp += samplesperpixel);
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 8-bit packed CMYK samples w/Map => RGB
+ *
+ * NB: The conversion of CMYK->RGB is *very* crude.
+ */
+DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile)
+{
+ int samplesperpixel = img->samplesperpixel;
+ TIFFRGBValue *Map = img->Map;
+ uint16_t r, g, b, k;
+
+ (void)y;
+ fromskew *= samplesperpixel;
+ for (; h > 0; --h)
+ {
+ for (x = w; x > 0; --x)
+ {
+ k = 255 - pp[3];
+ r = (k * (255 - pp[0])) / 255;
+ g = (k * (255 - pp[1])) / 255;
+ b = (k * (255 - pp[2])) / 255;
+ *cp++ = PACK(Map[r], Map[g], Map[b]);
+ pp += samplesperpixel;
+ }
+ pp += fromskew;
+ cp += toskew;
+ }
+}
+
+#define DECLARESepPutFunc(name) \
+ static void name(TIFFRGBAImage *img, uint32_t *cp, uint32_t x, uint32_t y, \
+ uint32_t w, uint32_t h, int32_t fromskew, int32_t toskew, \
+ unsigned char *r, unsigned char *g, unsigned char *b, \
+ unsigned char *a)
+
+/*
+ * 8-bit unpacked samples => RGB
+ */
+DECLARESepPutFunc(putRGBseparate8bittile)
+{
+ (void)img;
+ (void)x;
+ (void)y;
+ (void)a;
+ for (; h > 0; --h)
+ {
+ UNROLL8(w, NOP, *cp++ = PACK(*r++, *g++, *b++));
+ SKEW(r, g, b, fromskew);
+ cp += toskew;
+ }
+}
+
+/*
+ * 8-bit unpacked samples => RGBA w/ associated alpha
+ */
+DECLARESepPutFunc(putRGBAAseparate8bittile)
+{
+ (void)img;
+ (void)x;
+ (void)y;
+ for (; h > 0; --h)
+ {
+ UNROLL8(w, NOP, *cp++ = PACK4(*r++, *g++, *b++, *a++));
+ SKEW4(r, g, b, a, fromskew);
+ cp += toskew;
+ }
+}
+
+/*
+ * 8-bit unpacked CMYK samples => RGBA
+ */
+DECLARESepPutFunc(putCMYKseparate8bittile)
+{
+ (void)img;
+ (void)y;
+ for (; h > 0; --h)
+ {
+ uint32_t rv, gv, bv, kv;
+ for (x = w; x > 0; --x)
+ {
+ kv = 255 - *a++;
+ rv = (kv * (255 - *r++)) / 255;
+ gv = (kv * (255 - *g++)) / 255;
+ bv = (kv * (255 - *b++)) / 255;
+ *cp++ = PACK4(rv, gv, bv, 255);
+ }
+ SKEW4(r, g, b, a, fromskew);
+ cp += toskew;
+ }
+}
+
+/*
+ * 8-bit unpacked samples => RGBA w/ unassociated alpha
+ */
+DECLARESepPutFunc(putRGBUAseparate8bittile)
+{
+ (void)img;
+ (void)y;
+ for (; h > 0; --h)
+ {
+ uint32_t rv, gv, bv, av;
+ uint8_t *m;
+ for (x = w; x > 0; --x)
+ {
+ av = *a++;
+ m = img->UaToAa + ((size_t)av << 8);
+ rv = m[*r++];
+ gv = m[*g++];
+ bv = m[*b++];
+ *cp++ = PACK4(rv, gv, bv, av);
+ }
+ SKEW4(r, g, b, a, fromskew);
+ cp += toskew;
+ }
+}
+
+/*
+ * 16-bit unpacked samples => RGB
+ */
+DECLARESepPutFunc(putRGBseparate16bittile)
+{
+ uint16_t *wr = (uint16_t *)r;
+ uint16_t *wg = (uint16_t *)g;
+ uint16_t *wb = (uint16_t *)b;
+ (void)img;
+ (void)y;
+ (void)a;
+ for (; h > 0; --h)
+ {
+ for (x = 0; x < w; x++)
+ *cp++ = PACK(img->Bitdepth16To8[*wr++], img->Bitdepth16To8[*wg++],
+ img->Bitdepth16To8[*wb++]);
+ SKEW(wr, wg, wb, fromskew);
+ cp += toskew;
+ }
+}
+
+/*
+ * 16-bit unpacked samples => RGBA w/ associated alpha
+ */
+DECLARESepPutFunc(putRGBAAseparate16bittile)
+{
+ uint16_t *wr = (uint16_t *)r;
+ uint16_t *wg = (uint16_t *)g;
+ uint16_t *wb = (uint16_t *)b;
+ uint16_t *wa = (uint16_t *)a;
+ (void)img;
+ (void)y;
+ for (; h > 0; --h)
+ {
+ for (x = 0; x < w; x++)
+ *cp++ = PACK4(img->Bitdepth16To8[*wr++], img->Bitdepth16To8[*wg++],
+ img->Bitdepth16To8[*wb++], img->Bitdepth16To8[*wa++]);
+ SKEW4(wr, wg, wb, wa, fromskew);
+ cp += toskew;
+ }
+}
+
+/*
+ * 16-bit unpacked samples => RGBA w/ unassociated alpha
+ */
+DECLARESepPutFunc(putRGBUAseparate16bittile)
+{
+ uint16_t *wr = (uint16_t *)r;
+ uint16_t *wg = (uint16_t *)g;
+ uint16_t *wb = (uint16_t *)b;
+ uint16_t *wa = (uint16_t *)a;
+ (void)img;
+ (void)y;
+ for (; h > 0; --h)
+ {
+ uint32_t r2, g2, b2, a2;
+ uint8_t *m;
+ for (x = w; x > 0; --x)
+ {
+ a2 = img->Bitdepth16To8[*wa++];
+ m = img->UaToAa + ((size_t)a2 << 8);
+ r2 = m[img->Bitdepth16To8[*wr++]];
+ g2 = m[img->Bitdepth16To8[*wg++]];
+ b2 = m[img->Bitdepth16To8[*wb++]];
+ *cp++ = PACK4(r2, g2, b2, a2);
+ }
+ SKEW4(wr, wg, wb, wa, fromskew);
+ cp += toskew;
+ }
+}
+
+/*
+ * 8-bit packed CIE L*a*b 1976 samples => RGB
+ */
+DECLAREContigPutFunc(putcontig8bitCIELab8)
+{
+ float X, Y, Z;
+ uint32_t r, g, b;
+ (void)y;
+ fromskew *= 3;
+ for (; h > 0; --h)
+ {
+ for (x = w; x > 0; --x)
+ {
+ TIFFCIELabToXYZ(img->cielab, (unsigned char)pp[0],
+ (signed char)pp[1], (signed char)pp[2], &X, &Y, &Z);
+ TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b);
+ *cp++ = PACK(r, g, b);
+ pp += 3;
+ }
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 16-bit packed CIE L*a*b 1976 samples => RGB
+ */
+DECLAREContigPutFunc(putcontig8bitCIELab16)
+{
+ float X, Y, Z;
+ uint32_t r, g, b;
+ uint16_t *wp = (uint16_t *)pp;
+ (void)y;
+ fromskew *= 3;
+ for (; h > 0; --h)
+ {
+ for (x = w; x > 0; --x)
+ {
+ TIFFCIELab16ToXYZ(img->cielab, (uint16_t)wp[0], (int16_t)wp[1],
+ (int16_t)wp[2], &X, &Y, &Z);
+ TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b);
+ *cp++ = PACK(r, g, b);
+ wp += 3;
+ }
+ cp += toskew;
+ wp += fromskew;
+ }
+}
+
+/*
+ * YCbCr -> RGB conversion and packing routines.
+ */
+
+#define YCbCrtoRGB(dst, Y) \
+ { \
+ uint32_t r, g, b; \
+ TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b); \
+ dst = PACK(r, g, b); \
+ }
+
+/*
+ * 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB
+ */
+DECLAREContigPutFunc(putcontig8bitYCbCr44tile)
+{
+ uint32_t *cp1 = cp + w + toskew;
+ uint32_t *cp2 = cp1 + w + toskew;
+ uint32_t *cp3 = cp2 + w + toskew;
+ int32_t incr = 3 * w + 4 * toskew;
+
+ (void)y;
+ /* adjust fromskew */
+ fromskew = (fromskew / 4) * (4 * 2 + 2);
+ if ((h & 3) == 0 && (w & 3) == 0)
+ {
+ for (; h >= 4; h -= 4)
+ {
+ x = w >> 2;
+ do
+ {
+ int32_t Cb = pp[16];
+ int32_t Cr = pp[17];
+
+ YCbCrtoRGB(cp[0], pp[0]);
+ YCbCrtoRGB(cp[1], pp[1]);
+ YCbCrtoRGB(cp[2], pp[2]);
+ YCbCrtoRGB(cp[3], pp[3]);
+ YCbCrtoRGB(cp1[0], pp[4]);
+ YCbCrtoRGB(cp1[1], pp[5]);
+ YCbCrtoRGB(cp1[2], pp[6]);
+ YCbCrtoRGB(cp1[3], pp[7]);
+ YCbCrtoRGB(cp2[0], pp[8]);
+ YCbCrtoRGB(cp2[1], pp[9]);
+ YCbCrtoRGB(cp2[2], pp[10]);
+ YCbCrtoRGB(cp2[3], pp[11]);
+ YCbCrtoRGB(cp3[0], pp[12]);
+ YCbCrtoRGB(cp3[1], pp[13]);
+ YCbCrtoRGB(cp3[2], pp[14]);
+ YCbCrtoRGB(cp3[3], pp[15]);
+
+ cp += 4;
+ cp1 += 4;
+ cp2 += 4;
+ cp3 += 4;
+ pp += 18;
+ } while (--x);
+ cp += incr;
+ cp1 += incr;
+ cp2 += incr;
+ cp3 += incr;
+ pp += fromskew;
+ }
+ }
+ else
+ {
+ while (h > 0)
+ {
+ for (x = w; x > 0;)
+ {
+ int32_t Cb = pp[16];
+ int32_t Cr = pp[17];
+ switch (x)
+ {
+ default:
+ switch (h)
+ {
+ default:
+ YCbCrtoRGB(cp3[3], pp[15]); /* FALLTHROUGH */
+ case 3:
+ YCbCrtoRGB(cp2[3], pp[11]); /* FALLTHROUGH */
+ case 2:
+ YCbCrtoRGB(cp1[3], pp[7]); /* FALLTHROUGH */
+ case 1:
+ YCbCrtoRGB(cp[3], pp[3]); /* FALLTHROUGH */
+ } /* FALLTHROUGH */
+ case 3:
+ switch (h)
+ {
+ default:
+ YCbCrtoRGB(cp3[2], pp[14]); /* FALLTHROUGH */
+ case 3:
+ YCbCrtoRGB(cp2[2], pp[10]); /* FALLTHROUGH */
+ case 2:
+ YCbCrtoRGB(cp1[2], pp[6]); /* FALLTHROUGH */
+ case 1:
+ YCbCrtoRGB(cp[2], pp[2]); /* FALLTHROUGH */
+ } /* FALLTHROUGH */
+ case 2:
+ switch (h)
+ {
+ default:
+ YCbCrtoRGB(cp3[1], pp[13]); /* FALLTHROUGH */
+ case 3:
+ YCbCrtoRGB(cp2[1], pp[9]); /* FALLTHROUGH */
+ case 2:
+ YCbCrtoRGB(cp1[1], pp[5]); /* FALLTHROUGH */
+ case 1:
+ YCbCrtoRGB(cp[1], pp[1]); /* FALLTHROUGH */
+ } /* FALLTHROUGH */
+ case 1:
+ switch (h)
+ {
+ default:
+ YCbCrtoRGB(cp3[0], pp[12]); /* FALLTHROUGH */
+ case 3:
+ YCbCrtoRGB(cp2[0], pp[8]); /* FALLTHROUGH */
+ case 2:
+ YCbCrtoRGB(cp1[0], pp[4]); /* FALLTHROUGH */
+ case 1:
+ YCbCrtoRGB(cp[0], pp[0]); /* FALLTHROUGH */
+ } /* FALLTHROUGH */
+ }
+ if (x < 4)
+ {
+ cp += x;
+ cp1 += x;
+ cp2 += x;
+ cp3 += x;
+ x = 0;
+ }
+ else
+ {
+ cp += 4;
+ cp1 += 4;
+ cp2 += 4;
+ cp3 += 4;
+ x -= 4;
+ }
+ pp += 18;
+ }
+ if (h <= 4)
+ break;
+ h -= 4;
+ cp += incr;
+ cp1 += incr;
+ cp2 += incr;
+ cp3 += incr;
+ pp += fromskew;
+ }
+ }
+}
+
+/*
+ * 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB
+ */
+DECLAREContigPutFunc(putcontig8bitYCbCr42tile)
+{
+ uint32_t *cp1 = cp + w + toskew;
+ int32_t incr = 2 * toskew + w;
+
+ (void)y;
+ fromskew = (fromskew / 4) * (4 * 2 + 2);
+ if ((w & 3) == 0 && (h & 1) == 0)
+ {
+ for (; h >= 2; h -= 2)
+ {
+ x = w >> 2;
+ do
+ {
+ int32_t Cb = pp[8];
+ int32_t Cr = pp[9];
+
+ YCbCrtoRGB(cp[0], pp[0]);
+ YCbCrtoRGB(cp[1], pp[1]);
+ YCbCrtoRGB(cp[2], pp[2]);
+ YCbCrtoRGB(cp[3], pp[3]);
+ YCbCrtoRGB(cp1[0], pp[4]);
+ YCbCrtoRGB(cp1[1], pp[5]);
+ YCbCrtoRGB(cp1[2], pp[6]);
+ YCbCrtoRGB(cp1[3], pp[7]);
+
+ cp += 4;
+ cp1 += 4;
+ pp += 10;
+ } while (--x);
+ cp += incr;
+ cp1 += incr;
+ pp += fromskew;
+ }
+ }
+ else
+ {
+ while (h > 0)
+ {
+ for (x = w; x > 0;)
+ {
+ int32_t Cb = pp[8];
+ int32_t Cr = pp[9];
+ switch (x)
+ {
+ default:
+ switch (h)
+ {
+ default:
+ YCbCrtoRGB(cp1[3], pp[7]); /* FALLTHROUGH */
+ case 1:
+ YCbCrtoRGB(cp[3], pp[3]); /* FALLTHROUGH */
+ } /* FALLTHROUGH */
+ case 3:
+ switch (h)
+ {
+ default:
+ YCbCrtoRGB(cp1[2], pp[6]); /* FALLTHROUGH */
+ case 1:
+ YCbCrtoRGB(cp[2], pp[2]); /* FALLTHROUGH */
+ } /* FALLTHROUGH */
+ case 2:
+ switch (h)
+ {
+ default:
+ YCbCrtoRGB(cp1[1], pp[5]); /* FALLTHROUGH */
+ case 1:
+ YCbCrtoRGB(cp[1], pp[1]); /* FALLTHROUGH */
+ } /* FALLTHROUGH */
+ case 1:
+ switch (h)
+ {
+ default:
+ YCbCrtoRGB(cp1[0], pp[4]); /* FALLTHROUGH */
+ case 1:
+ YCbCrtoRGB(cp[0], pp[0]); /* FALLTHROUGH */
+ } /* FALLTHROUGH */
+ }
+ if (x < 4)
+ {
+ cp += x;
+ cp1 += x;
+ x = 0;
+ }
+ else
+ {
+ cp += 4;
+ cp1 += 4;
+ x -= 4;
+ }
+ pp += 10;
+ }
+ if (h <= 2)
+ break;
+ h -= 2;
+ cp += incr;
+ cp1 += incr;
+ pp += fromskew;
+ }
+ }
+}
+
+/*
+ * 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB
+ */
+DECLAREContigPutFunc(putcontig8bitYCbCr41tile)
+{
+ (void)y;
+ fromskew = (fromskew / 4) * (4 * 1 + 2);
+ do
+ {
+ x = w >> 2;
+ while (x > 0)
+ {
+ int32_t Cb = pp[4];
+ int32_t Cr = pp[5];
+
+ YCbCrtoRGB(cp[0], pp[0]);
+ YCbCrtoRGB(cp[1], pp[1]);
+ YCbCrtoRGB(cp[2], pp[2]);
+ YCbCrtoRGB(cp[3], pp[3]);
+
+ cp += 4;
+ pp += 6;
+ x--;
+ }
+
+ if ((w & 3) != 0)
+ {
+ int32_t Cb = pp[4];
+ int32_t Cr = pp[5];
+
+ switch ((w & 3))
+ {
+ case 3:
+ YCbCrtoRGB(cp[2], pp[2]); /*-fallthrough*/
+ case 2:
+ YCbCrtoRGB(cp[1], pp[1]); /*-fallthrough*/
+ case 1:
+ YCbCrtoRGB(cp[0], pp[0]); /*-fallthrough*/
+ case 0:
+ break;
+ }
+
+ cp += (w & 3);
+ pp += 6;
+ }
+
+ cp += toskew;
+ pp += fromskew;
+ } while (--h);
+}
+
+/*
+ * 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB
+ */
+DECLAREContigPutFunc(putcontig8bitYCbCr22tile)
+{
+ uint32_t *cp2;
+ int32_t incr = 2 * toskew + w;
+ (void)y;
+ fromskew = (fromskew / 2) * (2 * 2 + 2);
+ cp2 = cp + w + toskew;
+ while (h >= 2)
+ {
+ x = w;
+ while (x >= 2)
+ {
+ uint32_t Cb = pp[4];
+ uint32_t Cr = pp[5];
+ YCbCrtoRGB(cp[0], pp[0]);
+ YCbCrtoRGB(cp[1], pp[1]);
+ YCbCrtoRGB(cp2[0], pp[2]);
+ YCbCrtoRGB(cp2[1], pp[3]);
+ cp += 2;
+ cp2 += 2;
+ pp += 6;
+ x -= 2;
+ }
+ if (x == 1)
+ {
+ uint32_t Cb = pp[4];
+ uint32_t Cr = pp[5];
+ YCbCrtoRGB(cp[0], pp[0]);
+ YCbCrtoRGB(cp2[0], pp[2]);
+ cp++;
+ cp2++;
+ pp += 6;
+ }
+ cp += incr;
+ cp2 += incr;
+ pp += fromskew;
+ h -= 2;
+ }
+ if (h == 1)
+ {
+ x = w;
+ while (x >= 2)
+ {
+ uint32_t Cb = pp[4];
+ uint32_t Cr = pp[5];
+ YCbCrtoRGB(cp[0], pp[0]);
+ YCbCrtoRGB(cp[1], pp[1]);
+ cp += 2;
+ cp2 += 2;
+ pp += 6;
+ x -= 2;
+ }
+ if (x == 1)
+ {
+ uint32_t Cb = pp[4];
+ uint32_t Cr = pp[5];
+ YCbCrtoRGB(cp[0], pp[0]);
+ }
+ }
+}
+
+/*
+ * 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB
+ */
+DECLAREContigPutFunc(putcontig8bitYCbCr21tile)
+{
+ (void)y;
+ fromskew = (fromskew / 2) * (2 * 1 + 2);
+ do
+ {
+ x = w >> 1;
+ while (x > 0)
+ {
+ int32_t Cb = pp[2];
+ int32_t Cr = pp[3];
+
+ YCbCrtoRGB(cp[0], pp[0]);
+ YCbCrtoRGB(cp[1], pp[1]);
+
+ cp += 2;
+ pp += 4;
+ x--;
+ }
+
+ if ((w & 1) != 0)
+ {
+ int32_t Cb = pp[2];
+ int32_t Cr = pp[3];
+
+ YCbCrtoRGB(cp[0], pp[0]);
+
+ cp += 1;
+ pp += 4;
+ }
+
+ cp += toskew;
+ pp += fromskew;
+ } while (--h);
+}
+
+/*
+ * 8-bit packed YCbCr samples w/ 1,2 subsampling => RGB
+ */
+DECLAREContigPutFunc(putcontig8bitYCbCr12tile)
+{
+ uint32_t *cp2;
+ int32_t incr = 2 * toskew + w;
+ (void)y;
+ fromskew = (fromskew / 1) * (1 * 2 + 2);
+ cp2 = cp + w + toskew;
+ while (h >= 2)
+ {
+ x = w;
+ do
+ {
+ uint32_t Cb = pp[2];
+ uint32_t Cr = pp[3];
+ YCbCrtoRGB(cp[0], pp[0]);
+ YCbCrtoRGB(cp2[0], pp[1]);
+ cp++;
+ cp2++;
+ pp += 4;
+ } while (--x);
+ cp += incr;
+ cp2 += incr;
+ pp += fromskew;
+ h -= 2;
+ }
+ if (h == 1)
+ {
+ x = w;
+ do
+ {
+ uint32_t Cb = pp[2];
+ uint32_t Cr = pp[3];
+ YCbCrtoRGB(cp[0], pp[0]);
+ cp++;
+ pp += 4;
+ } while (--x);
+ }
+}
+
+/*
+ * 8-bit packed YCbCr samples w/ no subsampling => RGB
+ */
+DECLAREContigPutFunc(putcontig8bitYCbCr11tile)
+{
+ (void)y;
+ fromskew = (fromskew / 1) * (1 * 1 + 2);
+ do
+ {
+ x = w; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */
+ do
+ {
+ int32_t Cb = pp[1];
+ int32_t Cr = pp[2];
+
+ YCbCrtoRGB(*cp++, pp[0]);
+
+ pp += 3;
+ } while (--x);
+ cp += toskew;
+ pp += fromskew;
+ } while (--h);
+}
+
+/*
+ * 8-bit packed YCbCr samples w/ no subsampling => RGB
+ */
+DECLARESepPutFunc(putseparate8bitYCbCr11tile)
+{
+ (void)y;
+ (void)a;
+ /* TODO: naming of input vars is still off, change obfuscating declaration
+ * inside define, or resolve obfuscation */
+ for (; h > 0; --h)
+ {
+ x = w;
+ do
+ {
+ uint32_t dr, dg, db;
+ TIFFYCbCrtoRGB(img->ycbcr, *r++, *g++, *b++, &dr, &dg, &db);
+ *cp++ = PACK(dr, dg, db);
+ } while (--x);
+ SKEW(r, g, b, fromskew);
+ cp += toskew;
+ }
+}
+#undef YCbCrtoRGB
+
+static int isInRefBlackWhiteRange(float f)
+{
+ return f > (float)(-0x7FFFFFFF + 128) && f < (float)0x7FFFFFFF;
+}
+
+static int initYCbCrConversion(TIFFRGBAImage *img)
+{
+ static const char module[] = "initYCbCrConversion";
+
+ float *luma, *refBlackWhite;
+
+ if (img->ycbcr == NULL)
+ {
+ img->ycbcr = (TIFFYCbCrToRGB *)_TIFFmallocExt(
+ img->tif, TIFFroundup_32(sizeof(TIFFYCbCrToRGB), sizeof(long)) +
+ 4 * 256 * sizeof(TIFFRGBValue) +
+ 2 * 256 * sizeof(int) + 3 * 256 * sizeof(int32_t));
+ if (img->ycbcr == NULL)
+ {
+ TIFFErrorExtR(img->tif, module,
+ "No space for YCbCr->RGB conversion state");
+ return (0);
+ }
+ }
+
+ TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma);
+ TIFFGetFieldDefaulted(img->tif, TIFFTAG_REFERENCEBLACKWHITE,
+ &refBlackWhite);
+
+ /* Do some validation to avoid later issues. Detect NaN for now */
+ /* and also if lumaGreen is zero since we divide by it later */
+ if (luma[0] != luma[0] || luma[1] != luma[1] || luma[1] == 0.0 ||
+ luma[2] != luma[2])
+ {
+ TIFFErrorExtR(img->tif, module,
+ "Invalid values for YCbCrCoefficients tag");
+ return (0);
+ }
+
+ if (!isInRefBlackWhiteRange(refBlackWhite[0]) ||
+ !isInRefBlackWhiteRange(refBlackWhite[1]) ||
+ !isInRefBlackWhiteRange(refBlackWhite[2]) ||
+ !isInRefBlackWhiteRange(refBlackWhite[3]) ||
+ !isInRefBlackWhiteRange(refBlackWhite[4]) ||
+ !isInRefBlackWhiteRange(refBlackWhite[5]))
+ {
+ TIFFErrorExtR(img->tif, module,
+ "Invalid values for ReferenceBlackWhite tag");
+ return (0);
+ }
+
+ if (TIFFYCbCrToRGBInit(img->ycbcr, luma, refBlackWhite) < 0)
+ return (0);
+ return (1);
+}
+
+static tileContigRoutine initCIELabConversion(TIFFRGBAImage *img)
+{
+ static const char module[] = "initCIELabConversion";
+
+ float *whitePoint;
+ float refWhite[3];
+
+ TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint);
+ if (whitePoint[1] == 0.0f)
+ {
+ TIFFErrorExtR(img->tif, module, "Invalid value for WhitePoint tag.");
+ return NULL;
+ }
+
+ if (!img->cielab)
+ {
+ img->cielab = (TIFFCIELabToRGB *)_TIFFmallocExt(
+ img->tif, sizeof(TIFFCIELabToRGB));
+ if (!img->cielab)
+ {
+ TIFFErrorExtR(img->tif, module,
+ "No space for CIE L*a*b*->RGB conversion state.");
+ return NULL;
+ }
+ }
+
+ refWhite[1] = 100.0F;
+ refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1];
+ refWhite[2] =
+ (1.0F - whitePoint[0] - whitePoint[1]) / whitePoint[1] * refWhite[1];
+ if (TIFFCIELabToRGBInit(img->cielab, &display_sRGB, refWhite) < 0)
+ {
+ TIFFErrorExtR(img->tif, module,
+ "Failed to initialize CIE L*a*b*->RGB conversion state.");
+ _TIFFfreeExt(img->tif, img->cielab);
+ return NULL;
+ }
+
+ if (img->bitspersample == 8)
+ return putcontig8bitCIELab8;
+ else if (img->bitspersample == 16)
+ return putcontig8bitCIELab16;
+ return NULL;
+}
+
+/*
+ * Greyscale images with less than 8 bits/sample are handled
+ * with a table to avoid lots of shifts and masks. The table
+ * is setup so that put*bwtile (below) can retrieve 8/bitspersample
+ * pixel values simply by indexing into the table with one
+ * number.
+ */
+static int makebwmap(TIFFRGBAImage *img)
+{
+ TIFFRGBValue *Map = img->Map;
+ int bitspersample = img->bitspersample;
+ int nsamples = 8 / bitspersample;
+ int i;
+ uint32_t *p;
+
+ if (nsamples == 0)
+ nsamples = 1;
+
+ img->BWmap = (uint32_t **)_TIFFmallocExt(
+ img->tif,
+ 256 * sizeof(uint32_t *) + (256 * nsamples * sizeof(uint32_t)));
+ if (img->BWmap == NULL)
+ {
+ TIFFErrorExtR(img->tif, TIFFFileName(img->tif),
+ "No space for B&W mapping table");
+ return (0);
+ }
+ p = (uint32_t *)(img->BWmap + 256);
+ for (i = 0; i < 256; i++)
+ {
+ TIFFRGBValue c;
+ img->BWmap[i] = p;
+ switch (bitspersample)
+ {
+#define GREY(x) \
+ c = Map[x]; \
+ *p++ = PACK(c, c, c);
+ case 1:
+ GREY(i >> 7);
+ GREY((i >> 6) & 1);
+ GREY((i >> 5) & 1);
+ GREY((i >> 4) & 1);
+ GREY((i >> 3) & 1);
+ GREY((i >> 2) & 1);
+ GREY((i >> 1) & 1);
+ GREY(i & 1);
+ break;
+ case 2:
+ GREY(i >> 6);
+ GREY((i >> 4) & 3);
+ GREY((i >> 2) & 3);
+ GREY(i & 3);
+ break;
+ case 4:
+ GREY(i >> 4);
+ GREY(i & 0xf);
+ break;
+ case 8:
+ case 16:
+ GREY(i);
+ break;
+ }
+#undef GREY
+ }
+ return (1);
+}
+
+/*
+ * Construct a mapping table to convert from the range
+ * of the data samples to [0,255] --for display. This
+ * process also handles inverting B&W images when needed.
+ */
+static int setupMap(TIFFRGBAImage *img)
+{
+ int32_t x, range;
+
+ range = (int32_t)((1L << img->bitspersample) - 1);
+
+ /* treat 16 bit the same as eight bit */
+ if (img->bitspersample == 16)
+ range = (int32_t)255;
+
+ img->Map = (TIFFRGBValue *)_TIFFmallocExt(
+ img->tif, (range + 1) * sizeof(TIFFRGBValue));
+ if (img->Map == NULL)
+ {
+ TIFFErrorExtR(img->tif, TIFFFileName(img->tif),
+ "No space for photometric conversion table");
+ return (0);
+ }
+ if (img->photometric == PHOTOMETRIC_MINISWHITE)
+ {
+ for (x = 0; x <= range; x++)
+ img->Map[x] = (TIFFRGBValue)(((range - x) * 255) / range);
+ }
+ else
+ {
+ for (x = 0; x <= range; x++)
+ img->Map[x] = (TIFFRGBValue)((x * 255) / range);
+ }
+ if (img->bitspersample <= 16 &&
+ (img->photometric == PHOTOMETRIC_MINISBLACK ||
+ img->photometric == PHOTOMETRIC_MINISWHITE))
+ {
+ /*
+ * Use photometric mapping table to construct
+ * unpacking tables for samples <= 8 bits.
+ */
+ if (!makebwmap(img))
+ return (0);
+ /* no longer need Map, free it */
+ _TIFFfreeExt(img->tif, img->Map);
+ img->Map = NULL;
+ }
+ return (1);
+}
+
+static int checkcmap(TIFFRGBAImage *img)
+{
+ uint16_t *r = img->redcmap;
+ uint16_t *g = img->greencmap;
+ uint16_t *b = img->bluecmap;
+ long n = 1L << img->bitspersample;
+
+ while (n-- > 0)
+ if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
+ return (16);
+ return (8);
+}
+
+static void cvtcmap(TIFFRGBAImage *img)
+{
+ uint16_t *r = img->redcmap;
+ uint16_t *g = img->greencmap;
+ uint16_t *b = img->bluecmap;
+ long i;
+
+ for (i = (1L << img->bitspersample) - 1; i >= 0; i--)
+ {
+#define CVT(x) ((uint16_t)((x) >> 8))
+ r[i] = CVT(r[i]);
+ g[i] = CVT(g[i]);
+ b[i] = CVT(b[i]);
+#undef CVT
+ }
+}
+
+/*
+ * Palette images with <= 8 bits/sample are handled
+ * with a table to avoid lots of shifts and masks. The table
+ * is setup so that put*cmaptile (below) can retrieve 8/bitspersample
+ * pixel values simply by indexing into the table with one
+ * number.
+ */
+static int makecmap(TIFFRGBAImage *img)
+{
+ int bitspersample = img->bitspersample;
+ int nsamples = 8 / bitspersample;
+ uint16_t *r = img->redcmap;
+ uint16_t *g = img->greencmap;
+ uint16_t *b = img->bluecmap;
+ uint32_t *p;
+ int i;
+
+ img->PALmap = (uint32_t **)_TIFFmallocExt(
+ img->tif,
+ 256 * sizeof(uint32_t *) + (256 * nsamples * sizeof(uint32_t)));
+ if (img->PALmap == NULL)
+ {
+ TIFFErrorExtR(img->tif, TIFFFileName(img->tif),
+ "No space for Palette mapping table");
+ return (0);
+ }
+ p = (uint32_t *)(img->PALmap + 256);
+ for (i = 0; i < 256; i++)
+ {
+ TIFFRGBValue c;
+ img->PALmap[i] = p;
+#define CMAP(x) \
+ c = (TIFFRGBValue)x; \
+ *p++ = PACK(r[c] & 0xff, g[c] & 0xff, b[c] & 0xff);
+ switch (bitspersample)
+ {
+ case 1:
+ CMAP(i >> 7);
+ CMAP((i >> 6) & 1);
+ CMAP((i >> 5) & 1);
+ CMAP((i >> 4) & 1);
+ CMAP((i >> 3) & 1);
+ CMAP((i >> 2) & 1);
+ CMAP((i >> 1) & 1);
+ CMAP(i & 1);
+ break;
+ case 2:
+ CMAP(i >> 6);
+ CMAP((i >> 4) & 3);
+ CMAP((i >> 2) & 3);
+ CMAP(i & 3);
+ break;
+ case 4:
+ CMAP(i >> 4);
+ CMAP(i & 0xf);
+ break;
+ case 8:
+ CMAP(i);
+ break;
+ }
+#undef CMAP
+ }
+ return (1);
+}
+
+/*
+ * Construct any mapping table used
+ * by the associated put routine.
+ */
+static int buildMap(TIFFRGBAImage *img)
+{
+ switch (img->photometric)
+ {
+ case PHOTOMETRIC_RGB:
+ case PHOTOMETRIC_YCBCR:
+ case PHOTOMETRIC_SEPARATED:
+ if (img->bitspersample == 8)
+ break;
+ /* fall through... */
+ case PHOTOMETRIC_MINISBLACK:
+ case PHOTOMETRIC_MINISWHITE:
+ if (!setupMap(img))
+ return (0);
+ break;
+ case PHOTOMETRIC_PALETTE:
+ /*
+ * Convert 16-bit colormap to 8-bit (unless it looks
+ * like an old-style 8-bit colormap).
+ */
+ if (checkcmap(img) == 16)
+ cvtcmap(img);
+ else
+ TIFFWarningExtR(img->tif, TIFFFileName(img->tif),
+ "Assuming 8-bit colormap");
+ /*
+ * Use mapping table and colormap to construct
+ * unpacking tables for samples < 8 bits.
+ */
+ if (img->bitspersample <= 8 && !makecmap(img))
+ return (0);
+ break;
+ }
+ return (1);
+}
+
+/*
+ * Select the appropriate conversion routine for packed data.
+ */
+static int PickContigCase(TIFFRGBAImage *img)
+{
+ img->get = TIFFIsTiled(img->tif) ? gtTileContig : gtStripContig;
+ img->put.contig = NULL;
+ switch (img->photometric)
+ {
+ case PHOTOMETRIC_RGB:
+ switch (img->bitspersample)
+ {
+ case 8:
+ if (img->alpha == EXTRASAMPLE_ASSOCALPHA &&
+ img->samplesperpixel >= 4)
+ img->put.contig = putRGBAAcontig8bittile;
+ else if (img->alpha == EXTRASAMPLE_UNASSALPHA &&
+ img->samplesperpixel >= 4)
+ {
+ if (BuildMapUaToAa(img))
+ img->put.contig = putRGBUAcontig8bittile;
+ }
+ else if (img->samplesperpixel >= 3)
+ img->put.contig = putRGBcontig8bittile;
+ break;
+ case 16:
+ if (img->alpha == EXTRASAMPLE_ASSOCALPHA &&
+ img->samplesperpixel >= 4)
+ {
+ if (BuildMapBitdepth16To8(img))
+ img->put.contig = putRGBAAcontig16bittile;
+ }
+ else if (img->alpha == EXTRASAMPLE_UNASSALPHA &&
+ img->samplesperpixel >= 4)
+ {
+ if (BuildMapBitdepth16To8(img) && BuildMapUaToAa(img))
+ img->put.contig = putRGBUAcontig16bittile;
+ }
+ else if (img->samplesperpixel >= 3)
+ {
+ if (BuildMapBitdepth16To8(img))
+ img->put.contig = putRGBcontig16bittile;
+ }
+ break;
+ }
+ break;
+ case PHOTOMETRIC_SEPARATED:
+ if (img->samplesperpixel >= 4 && buildMap(img))
+ {
+ if (img->bitspersample == 8)
+ {
+ if (!img->Map)
+ img->put.contig = putRGBcontig8bitCMYKtile;
+ else
+ img->put.contig = putRGBcontig8bitCMYKMaptile;
+ }
+ }
+ break;
+ case PHOTOMETRIC_PALETTE:
+ if (buildMap(img))
+ {
+ switch (img->bitspersample)
+ {
+ case 8:
+ img->put.contig = put8bitcmaptile;
+ break;
+ case 4:
+ img->put.contig = put4bitcmaptile;
+ break;
+ case 2:
+ img->put.contig = put2bitcmaptile;
+ break;
+ case 1:
+ img->put.contig = put1bitcmaptile;
+ break;
+ }
+ }
+ break;
+ case PHOTOMETRIC_MINISWHITE:
+ case PHOTOMETRIC_MINISBLACK:
+ if (buildMap(img))
+ {
+ switch (img->bitspersample)
+ {
+ case 16:
+ img->put.contig = put16bitbwtile;
+ break;
+ case 8:
+ if (img->alpha && img->samplesperpixel == 2)
+ img->put.contig = putagreytile;
+ else
+ img->put.contig = putgreytile;
+ break;
+ case 4:
+ img->put.contig = put4bitbwtile;
+ break;
+ case 2:
+ img->put.contig = put2bitbwtile;
+ break;
+ case 1:
+ img->put.contig = put1bitbwtile;
+ break;
+ }
+ }
+ break;
+ case PHOTOMETRIC_YCBCR:
+ if ((img->bitspersample == 8) && (img->samplesperpixel == 3))
+ {
+ if (initYCbCrConversion(img) != 0)
+ {
+ /*
+ * The 6.0 spec says that subsampling must be
+ * one of 1, 2, or 4, and that vertical subsampling
+ * must always be <= horizontal subsampling; so
+ * there are only a few possibilities and we just
+ * enumerate the cases.
+ * Joris: added support for the [1,2] case, nonetheless, to
+ * accommodate some OJPEG files
+ */
+ uint16_t SubsamplingHor;
+ uint16_t SubsamplingVer;
+ TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING,
+ &SubsamplingHor, &SubsamplingVer);
+ switch ((SubsamplingHor << 4) | SubsamplingVer)
+ {
+ case 0x44:
+ img->put.contig = putcontig8bitYCbCr44tile;
+ break;
+ case 0x42:
+ img->put.contig = putcontig8bitYCbCr42tile;
+ break;
+ case 0x41:
+ img->put.contig = putcontig8bitYCbCr41tile;
+ break;
+ case 0x22:
+ img->put.contig = putcontig8bitYCbCr22tile;
+ break;
+ case 0x21:
+ img->put.contig = putcontig8bitYCbCr21tile;
+ break;
+ case 0x12:
+ img->put.contig = putcontig8bitYCbCr12tile;
+ break;
+ case 0x11:
+ img->put.contig = putcontig8bitYCbCr11tile;
+ break;
+ }
+ }
+ }
+ break;
+ case PHOTOMETRIC_CIELAB:
+ if (img->samplesperpixel == 3 && buildMap(img))
+ {
+ if (img->bitspersample == 8 || img->bitspersample == 16)
+ img->put.contig = initCIELabConversion(img);
+ break;
+ }
+ }
+ return ((img->get != NULL) && (img->put.contig != NULL));
+}
+
+/*
+ * Select the appropriate conversion routine for unpacked data.
+ *
+ * NB: we assume that unpacked single channel data is directed
+ * to the "packed routines.
+ */
+static int PickSeparateCase(TIFFRGBAImage *img)
+{
+ img->get = TIFFIsTiled(img->tif) ? gtTileSeparate : gtStripSeparate;
+ img->put.separate = NULL;
+ switch (img->photometric)
+ {
+ case PHOTOMETRIC_MINISWHITE:
+ case PHOTOMETRIC_MINISBLACK:
+ /* greyscale images processed pretty much as RGB by gtTileSeparate
+ */
+ case PHOTOMETRIC_RGB:
+ switch (img->bitspersample)
+ {
+ case 8:
+ if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
+ img->put.separate = putRGBAAseparate8bittile;
+ else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
+ {
+ if (BuildMapUaToAa(img))
+ img->put.separate = putRGBUAseparate8bittile;
+ }
+ else
+ img->put.separate = putRGBseparate8bittile;
+ break;
+ case 16:
+ if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
+ {
+ if (BuildMapBitdepth16To8(img))
+ img->put.separate = putRGBAAseparate16bittile;
+ }
+ else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
+ {
+ if (BuildMapBitdepth16To8(img) && BuildMapUaToAa(img))
+ img->put.separate = putRGBUAseparate16bittile;
+ }
+ else
+ {
+ if (BuildMapBitdepth16To8(img))
+ img->put.separate = putRGBseparate16bittile;
+ }
+ break;
+ }
+ break;
+ case PHOTOMETRIC_SEPARATED:
+ if (img->bitspersample == 8 && img->samplesperpixel == 4)
+ {
+ img->alpha =
+ 1; // Not alpha, but seems like the only way to get 4th band
+ img->put.separate = putCMYKseparate8bittile;
+ }
+ break;
+ case PHOTOMETRIC_YCBCR:
+ if ((img->bitspersample == 8) && (img->samplesperpixel == 3))
+ {
+ if (initYCbCrConversion(img) != 0)
+ {
+ uint16_t hs, vs;
+ TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING,
+ &hs, &vs);
+ switch ((hs << 4) | vs)
+ {
+ case 0x11:
+ img->put.separate = putseparate8bitYCbCr11tile;
+ break;
+ /* TODO: add other cases here */
+ }
+ }
+ }
+ break;
+ }
+ return ((img->get != NULL) && (img->put.separate != NULL));
+}
+
+static int BuildMapUaToAa(TIFFRGBAImage *img)
+{
+ static const char module[] = "BuildMapUaToAa";
+ uint8_t *m;
+ uint16_t na, nv;
+ assert(img->UaToAa == NULL);
+ img->UaToAa = _TIFFmallocExt(img->tif, 65536);
+ if (img->UaToAa == NULL)
+ {
+ TIFFErrorExtR(img->tif, module, "Out of memory");
+ return (0);
+ }
+ m = img->UaToAa;
+ for (na = 0; na < 256; na++)
+ {
+ for (nv = 0; nv < 256; nv++)
+ *m++ = (uint8_t)((nv * na + 127) / 255);
+ }
+ return (1);
+}
+
+static int BuildMapBitdepth16To8(TIFFRGBAImage *img)
+{
+ static const char module[] = "BuildMapBitdepth16To8";
+ uint8_t *m;
+ uint32_t n;
+ assert(img->Bitdepth16To8 == NULL);
+ img->Bitdepth16To8 = _TIFFmallocExt(img->tif, 65536);
+ if (img->Bitdepth16To8 == NULL)
+ {
+ TIFFErrorExtR(img->tif, module, "Out of memory");
+ return (0);
+ }
+ m = img->Bitdepth16To8;
+ for (n = 0; n < 65536; n++)
+ *m++ = (uint8_t)((n + 128) / 257);
+ return (1);
+}
+
+/*
+ * Read a whole strip off data from the file, and convert to RGBA form.
+ * If this is the last strip, then it will only contain the portion of
+ * the strip that is actually within the image space. The result is
+ * organized in bottom to top form.
+ */
+
+int TIFFReadRGBAStrip(TIFF *tif, uint32_t row, uint32_t *raster)
+
+{
+ return TIFFReadRGBAStripExt(tif, row, raster, 0);
+}
+
+int TIFFReadRGBAStripExt(TIFF *tif, uint32_t row, uint32_t *raster,
+ int stop_on_error)
+
+{
+ char emsg[EMSG_BUF_SIZE] = "";
+ TIFFRGBAImage img;
+ int ok;
+ uint32_t rowsperstrip, rows_to_read;
+
+ if (TIFFIsTiled(tif))
+ {
+ TIFFErrorExtR(tif, TIFFFileName(tif),
+ "Can't use TIFFReadRGBAStrip() with tiled file.");
+ return (0);
+ }
+
+ TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
+ if ((row % rowsperstrip) != 0)
+ {
+ TIFFErrorExtR(
+ tif, TIFFFileName(tif),
+ "Row passed to TIFFReadRGBAStrip() must be first in a strip.");
+ return (0);
+ }
+
+ if (TIFFRGBAImageOK(tif, emsg) &&
+ TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg))
+ {
+
+ img.row_offset = row;
+ img.col_offset = 0;
+
+ if (row + rowsperstrip > img.height)
+ rows_to_read = img.height - row;
+ else
+ rows_to_read = rowsperstrip;
+
+ ok = TIFFRGBAImageGet(&img, raster, img.width, rows_to_read);
+
+ TIFFRGBAImageEnd(&img);
+ }
+ else
+ {
+ TIFFErrorExtR(tif, TIFFFileName(tif), "%s", emsg);
+ ok = 0;
+ }
+
+ return (ok);
+}
+
+/*
+ * Read a whole tile off data from the file, and convert to RGBA form.
+ * The returned RGBA data is organized from bottom to top of tile,
+ * and may include zeroed areas if the tile extends off the image.
+ */
+
+int TIFFReadRGBATile(TIFF *tif, uint32_t col, uint32_t row, uint32_t *raster)
+
+{
+ return TIFFReadRGBATileExt(tif, col, row, raster, 0);
+}
+
+int TIFFReadRGBATileExt(TIFF *tif, uint32_t col, uint32_t row, uint32_t *raster,
+ int stop_on_error)
+{
+ char emsg[EMSG_BUF_SIZE] = "";
+ TIFFRGBAImage img;
+ int ok;
+ uint32_t tile_xsize, tile_ysize;
+ uint32_t read_xsize, read_ysize;
+ uint32_t i_row;
+
+ /*
+ * Verify that our request is legal - on a tile file, and on a
+ * tile boundary.
+ */
+
+ if (!TIFFIsTiled(tif))
+ {
+ TIFFErrorExtR(tif, TIFFFileName(tif),
+ "Can't use TIFFReadRGBATile() with striped file.");
+ return (0);
+ }
+
+ TIFFGetFieldDefaulted(tif, TIFFTAG_TILEWIDTH, &tile_xsize);
+ TIFFGetFieldDefaulted(tif, TIFFTAG_TILELENGTH, &tile_ysize);
+ if ((col % tile_xsize) != 0 || (row % tile_ysize) != 0)
+ {
+ TIFFErrorExtR(tif, TIFFFileName(tif),
+ "Row/col passed to TIFFReadRGBATile() must be top"
+ "left corner of a tile.");
+ return (0);
+ }
+
+ /*
+ * Setup the RGBA reader.
+ */
+
+ if (!TIFFRGBAImageOK(tif, emsg) ||
+ !TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg))
+ {
+ TIFFErrorExtR(tif, TIFFFileName(tif), "%s", emsg);
+ return (0);
+ }
+
+ /*
+ * The TIFFRGBAImageGet() function doesn't allow us to get off the
+ * edge of the image, even to fill an otherwise valid tile. So we
+ * figure out how much we can read, and fix up the tile buffer to
+ * a full tile configuration afterwards.
+ */
+
+ if (row + tile_ysize > img.height)
+ read_ysize = img.height - row;
+ else
+ read_ysize = tile_ysize;
+
+ if (col + tile_xsize > img.width)
+ read_xsize = img.width - col;
+ else
+ read_xsize = tile_xsize;
+
+ /*
+ * Read the chunk of imagery.
+ */
+
+ img.row_offset = row;
+ img.col_offset = col;
+
+ ok = TIFFRGBAImageGet(&img, raster, read_xsize, read_ysize);
+
+ TIFFRGBAImageEnd(&img);
+
+ /*
+ * If our read was incomplete we will need to fix up the tile by
+ * shifting the data around as if a full tile of data is being returned.
+ *
+ * This is all the more complicated because the image is organized in
+ * bottom to top format.
+ */
+
+ if (read_xsize == tile_xsize && read_ysize == tile_ysize)
+ return (ok);
+
+ for (i_row = 0; i_row < read_ysize; i_row++)
+ {
+ memmove(raster + (size_t)(tile_ysize - i_row - 1) * tile_xsize,
+ raster + (size_t)(read_ysize - i_row - 1) * read_xsize,
+ read_xsize * sizeof(uint32_t));
+ _TIFFmemset(raster + (size_t)(tile_ysize - i_row - 1) * tile_xsize +
+ read_xsize,
+ 0, sizeof(uint32_t) * (tile_xsize - read_xsize));
+ }
+
+ for (i_row = read_ysize; i_row < tile_ysize; i_row++)
+ {
+ _TIFFmemset(raster + (size_t)(tile_ysize - i_row - 1) * tile_xsize, 0,
+ sizeof(uint32_t) * tile_xsize);
+ }
+
+ return (ok);
+}
diff --git a/contrib/libs/libtiff/tif_hash_set.c b/contrib/libs/libtiff/tif_hash_set.c
new file mode 100644
index 0000000000..9792c63f47
--- /dev/null
+++ b/contrib/libs/libtiff/tif_hash_set.c
@@ -0,0 +1,603 @@
+/**********************************************************************
+ *
+ * Name: tif_hash_set.c
+ * Purpose: Hash set functions.
+ * Author: Even Rouault, <even dot rouault at spatialys.com>
+ *
+ **********************************************************************
+ * Copyright (c) 2008-2009, Even Rouault <even dot rouault at spatialys.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+
+#include "tif_config.h"
+
+#include "tif_hash_set.h"
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/** List element structure. */
+typedef struct _TIFFList TIFFList;
+
+/** List element structure. */
+struct _TIFFList
+{
+ /*! Pointer to the data object. Should be allocated and freed by the
+ * caller.
+ * */
+ void *pData;
+ /*! Pointer to the next element in list. NULL, if current element is the
+ * last one.
+ */
+ struct _TIFFList *psNext;
+};
+
+struct _TIFFHashSet
+{
+ TIFFHashSetHashFunc fnHashFunc;
+ TIFFHashSetEqualFunc fnEqualFunc;
+ TIFFHashSetFreeEltFunc fnFreeEltFunc;
+ TIFFList **tabList;
+ int nSize;
+ int nIndiceAllocatedSize;
+ int nAllocatedSize;
+ TIFFList *psRecyclingList;
+ int nRecyclingListSize;
+ bool bRehash;
+#ifdef HASH_DEBUG
+ int nCollisions;
+#endif
+};
+
+static const int anPrimes[] = {
+ 53, 97, 193, 389, 769, 1543, 3079,
+ 6151, 12289, 24593, 49157, 98317, 196613, 393241,
+ 786433, 1572869, 3145739, 6291469, 12582917, 25165843, 50331653,
+ 100663319, 201326611, 402653189, 805306457, 1610612741};
+
+/************************************************************************/
+/* TIFFHashSetHashPointer() */
+/************************************************************************/
+
+/**
+ * Hash function for an arbitrary pointer
+ *
+ * @param elt the arbitrary pointer to hash
+ *
+ * @return the hash value of the pointer
+ */
+
+static unsigned long TIFFHashSetHashPointer(const void *elt)
+{
+ return (unsigned long)(uintptr_t)((void *)(elt));
+}
+
+/************************************************************************/
+/* TIFFHashSetEqualPointer() */
+/************************************************************************/
+
+/**
+ * Equality function for arbitrary pointers
+ *
+ * @param elt1 the first arbitrary pointer to compare
+ * @param elt2 the second arbitrary pointer to compare
+ *
+ * @return true if the pointers are equal
+ */
+
+static bool TIFFHashSetEqualPointer(const void *elt1, const void *elt2)
+{
+ return elt1 == elt2;
+}
+
+/************************************************************************/
+/* TIFFHashSetNew() */
+/************************************************************************/
+
+/**
+ * Creates a new hash set
+ *
+ * The hash function must return a hash value for the elements to insert.
+ * If fnHashFunc is NULL, TIFFHashSetHashPointer will be used.
+ *
+ * The equal function must return if two elements are equal.
+ * If fnEqualFunc is NULL, TIFFHashSetEqualPointer will be used.
+ *
+ * The free function is used to free elements inserted in the hash set,
+ * when the hash set is destroyed, when elements are removed or replaced.
+ * If fnFreeEltFunc is NULL, elements inserted into the hash set will not be
+ * freed.
+ *
+ * @param fnHashFunc hash function. May be NULL.
+ * @param fnEqualFunc equal function. May be NULL.
+ * @param fnFreeEltFunc element free function. May be NULL.
+ *
+ * @return a new hash set
+ */
+
+TIFFHashSet *TIFFHashSetNew(TIFFHashSetHashFunc fnHashFunc,
+ TIFFHashSetEqualFunc fnEqualFunc,
+ TIFFHashSetFreeEltFunc fnFreeEltFunc)
+{
+ TIFFHashSet *set = (TIFFHashSet *)malloc(sizeof(TIFFHashSet));
+ if (set == NULL)
+ return NULL;
+ set->fnHashFunc = fnHashFunc ? fnHashFunc : TIFFHashSetHashPointer;
+ set->fnEqualFunc = fnEqualFunc ? fnEqualFunc : TIFFHashSetEqualPointer;
+ set->fnFreeEltFunc = fnFreeEltFunc;
+ set->nSize = 0;
+ set->tabList = (TIFFList **)(calloc(sizeof(TIFFList *), 53));
+ if (set->tabList == NULL)
+ {
+ free(set);
+ return NULL;
+ }
+ set->nIndiceAllocatedSize = 0;
+ set->nAllocatedSize = 53;
+ set->psRecyclingList = NULL;
+ set->nRecyclingListSize = 0;
+ set->bRehash = false;
+#ifdef HASH_DEBUG
+ set->nCollisions = 0;
+#endif
+ return set;
+}
+
+/************************************************************************/
+/* TIFFHashSetSize() */
+/************************************************************************/
+
+/**
+ * Returns the number of elements inserted in the hash set
+ *
+ * Note: this is not the internal size of the hash set
+ *
+ * @param set the hash set
+ *
+ * @return the number of elements in the hash set
+ */
+
+int TIFFHashSetSize(const TIFFHashSet *set)
+{
+ assert(set != NULL);
+ return set->nSize;
+}
+
+/************************************************************************/
+/* TIFFHashSetGetNewListElt() */
+/************************************************************************/
+
+static TIFFList *TIFFHashSetGetNewListElt(TIFFHashSet *set)
+{
+ if (set->psRecyclingList)
+ {
+ TIFFList *psRet = set->psRecyclingList;
+ psRet->pData = NULL;
+ set->nRecyclingListSize--;
+ set->psRecyclingList = psRet->psNext;
+ return psRet;
+ }
+
+ return (TIFFList *)malloc(sizeof(TIFFList));
+}
+
+/************************************************************************/
+/* TIFFHashSetReturnListElt() */
+/************************************************************************/
+
+static void TIFFHashSetReturnListElt(TIFFHashSet *set, TIFFList *psList)
+{
+ if (set->nRecyclingListSize < 128)
+ {
+ psList->psNext = set->psRecyclingList;
+ set->psRecyclingList = psList;
+ set->nRecyclingListSize++;
+ }
+ else
+ {
+ free(psList);
+ }
+}
+
+/************************************************************************/
+/* TIFFHashSetClearInternal() */
+/************************************************************************/
+
+static void TIFFHashSetClearInternal(TIFFHashSet *set, bool bFinalize)
+{
+ assert(set != NULL);
+ for (int i = 0; i < set->nAllocatedSize; i++)
+ {
+ TIFFList *cur = set->tabList[i];
+ while (cur)
+ {
+ if (set->fnFreeEltFunc)
+ set->fnFreeEltFunc(cur->pData);
+ TIFFList *psNext = cur->psNext;
+ if (bFinalize)
+ free(cur);
+ else
+ TIFFHashSetReturnListElt(set, cur);
+ cur = psNext;
+ }
+ set->tabList[i] = NULL;
+ }
+ set->bRehash = false;
+}
+
+/************************************************************************/
+/* TIFFListDestroy() */
+/************************************************************************/
+
+/**
+ * Destroy a list. Caller responsible for freeing data objects contained in
+ * list elements.
+ *
+ * @param psList pointer to list head.
+ *
+ */
+
+static void TIFFListDestroy(TIFFList *psList)
+{
+ TIFFList *psCurrent = psList;
+
+ while (psCurrent)
+ {
+ TIFFList *const psNext = psCurrent->psNext;
+ free(psCurrent);
+ psCurrent = psNext;
+ }
+}
+
+/************************************************************************/
+/* TIFFHashSetDestroy() */
+/************************************************************************/
+
+/**
+ * Destroys an allocated hash set.
+ *
+ * This function also frees the elements if a free function was
+ * provided at the creation of the hash set.
+ *
+ * @param set the hash set
+ */
+
+void TIFFHashSetDestroy(TIFFHashSet *set)
+{
+ if (set)
+ {
+ TIFFHashSetClearInternal(set, true);
+ free(set->tabList);
+ TIFFListDestroy(set->psRecyclingList);
+ free(set);
+ }
+}
+
+#ifdef notused
+/************************************************************************/
+/* TIFFHashSetClear() */
+/************************************************************************/
+
+/**
+ * Clear all elements from a hash set.
+ *
+ * This function also frees the elements if a free function was
+ * provided at the creation of the hash set.
+ *
+ * @param set the hash set
+ */
+
+void TIFFHashSetClear(TIFFHashSet *set)
+{
+ TIFFHashSetClearInternal(set, false);
+ set->nIndiceAllocatedSize = 0;
+ set->nAllocatedSize = 53;
+#ifdef HASH_DEBUG
+ set->nCollisions = 0;
+#endif
+ set->nSize = 0;
+}
+
+/************************************************************************/
+/* TIFFHashSetForeach() */
+/************************************************************************/
+
+/**
+ * Walk through the hash set and runs the provided function on all the
+ * elements
+ *
+ * This function is provided the user_data argument of TIFFHashSetForeach.
+ * It must return true to go on the walk through the hash set, or FALSE to
+ * make it stop.
+ *
+ * Note : the structure of the hash set must *NOT* be modified during the
+ * walk.
+ *
+ * @param set the hash set.
+ * @param fnIterFunc the function called on each element.
+ * @param user_data the user data provided to the function.
+ */
+
+void TIFFHashSetForeach(TIFFHashSet *set, TIFFHashSetIterEltFunc fnIterFunc,
+ void *user_data)
+{
+ assert(set != NULL);
+ if (!fnIterFunc)
+ return;
+
+ for (int i = 0; i < set->nAllocatedSize; i++)
+ {
+ TIFFList *cur = set->tabList[i];
+ while (cur)
+ {
+ if (!fnIterFunc(cur->pData, user_data))
+ return;
+
+ cur = cur->psNext;
+ }
+ }
+}
+#endif
+
+/************************************************************************/
+/* TIFFHashSetRehash() */
+/************************************************************************/
+
+static bool TIFFHashSetRehash(TIFFHashSet *set)
+{
+ int nNewAllocatedSize = anPrimes[set->nIndiceAllocatedSize];
+ TIFFList **newTabList =
+ (TIFFList **)(calloc(sizeof(TIFFList *), nNewAllocatedSize));
+ if (newTabList == NULL)
+ return false;
+#ifdef HASH_DEBUG
+ TIFFDebug("TIFFHASH",
+ "hashSet=%p, nSize=%d, nCollisions=%d, "
+ "fCollisionRate=%.02f",
+ set, set->nSize, set->nCollisions,
+ set->nCollisions * 100.0 / set->nSize);
+ set->nCollisions = 0;
+#endif
+ for (int i = 0; i < set->nAllocatedSize; i++)
+ {
+ TIFFList *cur = set->tabList[i];
+ while (cur)
+ {
+ const unsigned long nNewHashVal =
+ set->fnHashFunc(cur->pData) % nNewAllocatedSize;
+#ifdef HASH_DEBUG
+ if (newTabList[nNewHashVal])
+ set->nCollisions++;
+#endif
+ TIFFList *psNext = cur->psNext;
+ cur->psNext = newTabList[nNewHashVal];
+ newTabList[nNewHashVal] = cur;
+ cur = psNext;
+ }
+ }
+ free(set->tabList);
+ set->tabList = newTabList;
+ set->nAllocatedSize = nNewAllocatedSize;
+ set->bRehash = false;
+ return true;
+}
+
+/************************************************************************/
+/* TIFFHashSetFindPtr() */
+/************************************************************************/
+
+static void **TIFFHashSetFindPtr(TIFFHashSet *set, const void *elt)
+{
+ const unsigned long nHashVal = set->fnHashFunc(elt) % set->nAllocatedSize;
+ TIFFList *cur = set->tabList[nHashVal];
+ while (cur)
+ {
+ if (set->fnEqualFunc(cur->pData, elt))
+ return &cur->pData;
+ cur = cur->psNext;
+ }
+ return NULL;
+}
+
+/************************************************************************/
+/* TIFFHashSetInsert() */
+/************************************************************************/
+
+/**
+ * Inserts an element into a hash set.
+ *
+ * If the element was already inserted in the hash set, the previous
+ * element is replaced by the new element. If a free function was provided,
+ * it is used to free the previously inserted element
+ *
+ * @param set the hash set
+ * @param elt the new element to insert in the hash set
+ *
+ * @return true if success. If false is returned, elt has not been inserted,
+ * but TIFFHashSetInsert() will have run the free function if provided.
+ */
+
+bool TIFFHashSetInsert(TIFFHashSet *set, void *elt)
+{
+ assert(set != NULL);
+ void **pElt = TIFFHashSetFindPtr(set, elt);
+ if (pElt)
+ {
+ if (set->fnFreeEltFunc)
+ set->fnFreeEltFunc(*pElt);
+
+ *pElt = elt;
+ return true;
+ }
+
+ if (set->nSize >= 2 * set->nAllocatedSize / 3 ||
+ (set->bRehash && set->nIndiceAllocatedSize > 0 &&
+ set->nSize <= set->nAllocatedSize / 2))
+ {
+ set->nIndiceAllocatedSize++;
+ if (!TIFFHashSetRehash(set))
+ {
+ set->nIndiceAllocatedSize--;
+ if (set->fnFreeEltFunc)
+ set->fnFreeEltFunc(elt);
+ return false;
+ }
+ }
+
+ const unsigned long nHashVal = set->fnHashFunc(elt) % set->nAllocatedSize;
+#ifdef HASH_DEBUG
+ if (set->tabList[nHashVal])
+ set->nCollisions++;
+#endif
+
+ TIFFList *new_elt = TIFFHashSetGetNewListElt(set);
+ if (new_elt == NULL)
+ {
+ if (set->fnFreeEltFunc)
+ set->fnFreeEltFunc(elt);
+ return false;
+ }
+ new_elt->pData = elt;
+ new_elt->psNext = set->tabList[nHashVal];
+ set->tabList[nHashVal] = new_elt;
+ set->nSize++;
+
+ return true;
+}
+
+/************************************************************************/
+/* TIFFHashSetLookup() */
+/************************************************************************/
+
+/**
+ * Returns the element found in the hash set corresponding to the element to
+ * look up The element must not be modified.
+ *
+ * @param set the hash set
+ * @param elt the element to look up in the hash set
+ *
+ * @return the element found in the hash set or NULL
+ */
+
+void *TIFFHashSetLookup(TIFFHashSet *set, const void *elt)
+{
+ assert(set != NULL);
+ void **pElt = TIFFHashSetFindPtr(set, elt);
+ if (pElt)
+ return *pElt;
+
+ return NULL;
+}
+
+/************************************************************************/
+/* TIFFHashSetRemoveInternal() */
+/************************************************************************/
+
+static bool TIFFHashSetRemoveInternal(TIFFHashSet *set, const void *elt,
+ bool bDeferRehash)
+{
+ assert(set != NULL);
+ if (set->nIndiceAllocatedSize > 0 && set->nSize <= set->nAllocatedSize / 2)
+ {
+ set->nIndiceAllocatedSize--;
+ if (bDeferRehash)
+ set->bRehash = true;
+ else
+ {
+ if (!TIFFHashSetRehash(set))
+ {
+ set->nIndiceAllocatedSize++;
+ return false;
+ }
+ }
+ }
+
+ int nHashVal = (int)(set->fnHashFunc(elt) % set->nAllocatedSize);
+ TIFFList *cur = set->tabList[nHashVal];
+ TIFFList *prev = NULL;
+ while (cur)
+ {
+ if (set->fnEqualFunc(cur->pData, elt))
+ {
+ if (prev)
+ prev->psNext = cur->psNext;
+ else
+ set->tabList[nHashVal] = cur->psNext;
+
+ if (set->fnFreeEltFunc)
+ set->fnFreeEltFunc(cur->pData);
+
+ TIFFHashSetReturnListElt(set, cur);
+#ifdef HASH_DEBUG
+ if (set->tabList[nHashVal])
+ set->nCollisions--;
+#endif
+ set->nSize--;
+ return true;
+ }
+ prev = cur;
+ cur = cur->psNext;
+ }
+ return false;
+}
+
+/************************************************************************/
+/* TIFFHashSetRemove() */
+/************************************************************************/
+
+/**
+ * Removes an element from a hash set
+ *
+ * @param set the hash set
+ * @param elt the new element to remove from the hash set
+ *
+ * @return true if the element was in the hash set
+ */
+
+bool TIFFHashSetRemove(TIFFHashSet *set, const void *elt)
+{
+ return TIFFHashSetRemoveInternal(set, elt, false);
+}
+
+#ifdef notused
+/************************************************************************/
+/* TIFFHashSetRemoveDeferRehash() */
+/************************************************************************/
+
+/**
+ * Removes an element from a hash set.
+ *
+ * This will defer potential rehashing of the set to later calls to
+ * TIFFHashSetInsert() or TIFFHashSetRemove().
+ *
+ * @param set the hash set
+ * @param elt the new element to remove from the hash set
+ *
+ * @return true if the element was in the hash set
+ */
+
+bool TIFFHashSetRemoveDeferRehash(TIFFHashSet *set, const void *elt)
+{
+ return TIFFHashSetRemoveInternal(set, elt, true);
+}
+#endif
diff --git a/contrib/libs/libtiff/tif_hash_set.h b/contrib/libs/libtiff/tif_hash_set.h
new file mode 100644
index 0000000000..f60e2c675e
--- /dev/null
+++ b/contrib/libs/libtiff/tif_hash_set.h
@@ -0,0 +1,100 @@
+/**********************************************************************
+ * $Id$
+ *
+ * Name: tif_hash_set.h
+ * Project: TIFF - Common Portability Library
+ * Purpose: Hash set functions.
+ * Author: Even Rouault, <even dot rouault at spatialys.com>
+ *
+ **********************************************************************
+ * Copyright (c) 2008-2009, Even Rouault <even dot rouault at spatialys.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+
+#ifndef TIFF_HASH_SET_H_INCLUDED
+#define TIFF_HASH_SET_H_INCLUDED
+
+#include <stdbool.h>
+
+/**
+ * \file tif_hash_set.h
+ *
+ * Hash set implementation.
+ *
+ * An hash set is a data structure that holds elements that are unique
+ * according to a comparison function. Operations on the hash set, such as
+ * insertion, removal or lookup, are supposed to be fast if an efficient
+ * "hash" function is provided.
+ */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ /* Types */
+
+ /** Opaque type for a hash set */
+ typedef struct _TIFFHashSet TIFFHashSet;
+
+ /** TIFFHashSetHashFunc */
+ typedef unsigned long (*TIFFHashSetHashFunc)(const void *elt);
+
+ /** TIFFHashSetEqualFunc */
+ typedef bool (*TIFFHashSetEqualFunc)(const void *elt1, const void *elt2);
+
+ /** TIFFHashSetFreeEltFunc */
+ typedef void (*TIFFHashSetFreeEltFunc)(void *elt);
+
+ /* Functions */
+
+ TIFFHashSet *TIFFHashSetNew(TIFFHashSetHashFunc fnHashFunc,
+ TIFFHashSetEqualFunc fnEqualFunc,
+ TIFFHashSetFreeEltFunc fnFreeEltFunc);
+
+ void TIFFHashSetDestroy(TIFFHashSet *set);
+
+ int TIFFHashSetSize(const TIFFHashSet *set);
+
+#ifdef notused
+ void TIFFHashSetClear(TIFFHashSet *set);
+
+ /** TIFFHashSetIterEltFunc */
+ typedef int (*TIFFHashSetIterEltFunc)(void *elt, void *user_data);
+
+ void TIFFHashSetForeach(TIFFHashSet *set, TIFFHashSetIterEltFunc fnIterFunc,
+ void *user_data);
+#endif
+
+ bool TIFFHashSetInsert(TIFFHashSet *set, void *elt);
+
+ void *TIFFHashSetLookup(TIFFHashSet *set, const void *elt);
+
+ bool TIFFHashSetRemove(TIFFHashSet *set, const void *elt);
+
+#ifdef notused
+ bool TIFFHashSetRemoveDeferRehash(TIFFHashSet *set, const void *elt);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TIFF_HASH_SET_H_INCLUDED */
diff --git a/contrib/libs/libtiff/tif_jbig.c b/contrib/libs/libtiff/tif_jbig.c
new file mode 100644
index 0000000000..a0f879f95d
--- /dev/null
+++ b/contrib/libs/libtiff/tif_jbig.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * JBIG Compression Algorithm Support.
+ * Contributed by Lee Howard <faxguy@deanox.com>
+ *
+ */
+
+#include "tiffiop.h"
+
+#ifdef JBIG_SUPPORT
+#error #include "jbig.h"
+
+static int JBIGSetupDecode(TIFF *tif)
+{
+ if (TIFFNumberOfStrips(tif) != 1)
+ {
+ TIFFErrorExtR(tif, "JBIG",
+ "Multistrip images not supported in decoder");
+ return 0;
+ }
+
+ return 1;
+}
+
+static int JBIGDecode(TIFF *tif, uint8_t *buffer, tmsize_t size, uint16_t s)
+{
+ struct jbg_dec_state decoder;
+ int decodeStatus = 0;
+ unsigned char *pImage = NULL;
+ unsigned long decodedSize;
+ (void)s;
+
+ if (isFillOrder(tif, tif->tif_dir.td_fillorder))
+ {
+ TIFFReverseBits(tif->tif_rawcp, tif->tif_rawcc);
+ }
+
+ jbg_dec_init(&decoder);
+
+#if defined(HAVE_JBG_NEWLEN)
+ jbg_newlen(tif->tif_rawcp, (size_t)tif->tif_rawcc);
+ /*
+ * I do not check the return status of jbg_newlen because even if this
+ * function fails it does not necessarily mean that decoding the image
+ * will fail. It is generally only needed for received fax images
+ * that do not contain the actual length of the image in the BIE
+ * header. I do not log when an error occurs because that will cause
+ * problems when converting JBIG encoded TIFF's to
+ * PostScript. As long as the actual image length is contained in the
+ * BIE header jbg_dec_in should succeed.
+ */
+#endif /* HAVE_JBG_NEWLEN */
+
+ decodeStatus = jbg_dec_in(&decoder, (unsigned char *)tif->tif_rawcp,
+ (size_t)tif->tif_rawcc, NULL);
+ if (JBG_EOK != decodeStatus)
+ {
+ /*
+ * XXX: JBG_EN constant was defined in pre-2.0 releases of the
+ * JBIG-KIT. Since the 2.0 the error reporting functions were
+ * changed. We will handle both cases here.
+ */
+ TIFFErrorExtR(tif, "JBIG", "Error (%d) decoding: %s", decodeStatus,
+#if defined(JBG_EN)
+ jbg_strerror(decodeStatus, JBG_EN)
+#else
+ jbg_strerror(decodeStatus)
+#endif
+ );
+ jbg_dec_free(&decoder);
+ return 0;
+ }
+
+ decodedSize = jbg_dec_getsize(&decoder);
+ if ((tmsize_t)decodedSize < size)
+ {
+ TIFFWarningExtR(tif, "JBIG",
+ "Only decoded %lu bytes, whereas %" TIFF_SSIZE_FORMAT
+ " requested",
+ decodedSize, size);
+ }
+ else if ((tmsize_t)decodedSize > size)
+ {
+ TIFFErrorExtR(tif, "JBIG",
+ "Decoded %lu bytes, whereas %" TIFF_SSIZE_FORMAT
+ " were requested",
+ decodedSize, size);
+ jbg_dec_free(&decoder);
+ return 0;
+ }
+ pImage = jbg_dec_getimage(&decoder, 0);
+ _TIFFmemcpy(buffer, pImage, decodedSize);
+ jbg_dec_free(&decoder);
+
+ tif->tif_rawcp += tif->tif_rawcc;
+ tif->tif_rawcc = 0;
+
+ return 1;
+}
+
+static int JBIGSetupEncode(TIFF *tif)
+{
+ if (TIFFNumberOfStrips(tif) != 1)
+ {
+ TIFFErrorExtR(tif, "JBIG",
+ "Multistrip images not supported in encoder");
+ return 0;
+ }
+
+ return 1;
+}
+
+static int JBIGCopyEncodedData(TIFF *tif, unsigned char *pp, size_t cc,
+ uint16_t s)
+{
+ (void)s;
+ while (cc > 0)
+ {
+ tmsize_t n = (tmsize_t)cc;
+
+ if (tif->tif_rawcc + n > tif->tif_rawdatasize)
+ {
+ n = tif->tif_rawdatasize - tif->tif_rawcc;
+ }
+
+ assert(n > 0);
+ _TIFFmemcpy(tif->tif_rawcp, pp, n);
+ tif->tif_rawcp += n;
+ tif->tif_rawcc += n;
+ pp += n;
+ cc -= (size_t)n;
+ if (tif->tif_rawcc >= tif->tif_rawdatasize && !TIFFFlushData1(tif))
+ {
+ return (-1);
+ }
+ }
+
+ return (1);
+}
+
+static void JBIGOutputBie(unsigned char *buffer, size_t len, void *userData)
+{
+ TIFF *tif = (TIFF *)userData;
+
+ if (isFillOrder(tif, tif->tif_dir.td_fillorder))
+ {
+ TIFFReverseBits(buffer, (tmsize_t)len);
+ }
+
+ JBIGCopyEncodedData(tif, buffer, len, 0);
+}
+
+static int JBIGEncode(TIFF *tif, uint8_t *buffer, tmsize_t size, uint16_t s)
+{
+ TIFFDirectory *dir = &tif->tif_dir;
+ struct jbg_enc_state encoder;
+
+ (void)size, (void)s;
+
+ jbg_enc_init(&encoder, dir->td_imagewidth, dir->td_imagelength, 1, &buffer,
+ JBIGOutputBie, tif);
+ /*
+ * jbg_enc_out does the "real" encoding. As data is encoded,
+ * JBIGOutputBie is called, which writes the data to the directory.
+ */
+ jbg_enc_out(&encoder);
+ jbg_enc_free(&encoder);
+
+ return 1;
+}
+
+int TIFFInitJBIG(TIFF *tif, int scheme)
+{
+ (void)scheme;
+ assert(scheme == COMPRESSION_JBIG);
+
+ /*
+ * These flags are set so the JBIG Codec can control when to reverse
+ * bits and when not to and to allow the jbig decoder and bit reverser
+ * to write to memory when necessary.
+ */
+ 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;
+ tif->tif_decodestrip = JBIGDecode;
+
+ tif->tif_setupencode = JBIGSetupEncode;
+ tif->tif_encodestrip = JBIGEncode;
+
+ return 1;
+}
+
+#endif /* JBIG_SUPPORT */
diff --git a/contrib/libs/libtiff/tif_jpeg.c b/contrib/libs/libtiff/tif_jpeg.c
new file mode 100644
index 0000000000..250144f211
--- /dev/null
+++ b/contrib/libs/libtiff/tif_jpeg.c
@@ -0,0 +1,2900 @@
+/*
+ * Copyright (c) 1994-1997 Sam Leffler
+ * Copyright (c) 1994-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+#define WIN32_LEAN_AND_MEAN
+#define VC_EXTRALEAN
+
+#include "tiffiop.h"
+#include <stdlib.h>
+
+#ifdef JPEG_SUPPORT
+
+/*
+ * TIFF Library
+ *
+ * JPEG Compression support per TIFF Technical Note #2
+ * (*not* per the original TIFF 6.0 spec).
+ *
+ * This file is simply an interface to the libjpeg library written by
+ * the Independent JPEG Group. You need release 5 or later of the IJG
+ * code, which you can find on the Internet at ftp.uu.net:/graphics/jpeg/.
+ *
+ * Contributed by Tom Lane <tgl@sss.pgh.pa.us>.
+ */
+#include <setjmp.h>
+
+/* 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 */
+
+#ifdef FAR
+#undef FAR
+#endif
+
+/*
+ Libjpeg's jmorecfg.h defines INT16 and INT32, but only if XMD_H is
+ not defined. Unfortunately, the MinGW and Borland compilers include
+ a typedef for INT32, which causes a conflict. MSVC does not include
+ a conflicting typedef given the headers which are included.
+*/
+#if defined(__BORLANDC__) || defined(__MINGW32__)
+#define XMD_H 1
+#endif
+
+/*
+ The windows RPCNDR.H file defines boolean, but defines it with the
+ unsigned char size. You should compile JPEG library using appropriate
+ definitions in jconfig.h header, but many users compile library in wrong
+ way. That causes errors of the following type:
+
+ "JPEGLib: JPEG parameter struct mismatch: library thinks size is 432,
+ caller expects 464"
+
+ For such users we will fix the problem here. See install.doc file from
+ the JPEG library distribution for details.
+*/
+
+/* 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 */
+#endif
+
+#include "jerror.h"
+#include "jpeglib.h"
+
+/* Do optional compile-time version check */
+#if defined(EXPECTED_JPEG_LIB_VERSION) && !defined(LIBJPEG_12_PATH)
+#if EXPECTED_JPEG_LIB_VERSION != JPEG_LIB_VERSION
+#error EXPECTED_JPEG_LIB_VERSION != JPEG_LIB_VERSION
+#endif
+#endif
+
+/*
+ * Do we want to do special processing suitable for when JSAMPLE is a
+ * 16bit value?
+ */
+
+/* HAVE_JPEGTURBO_DUAL_MODE_8_12 is defined for libjpeg-turbo >= 2.2 which
+ * adds a dual-mode 8/12 bit API in the same library.
+ */
+
+#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12)
+#define JPEG_DUAL_MODE_8_12
+/* Start by undefining BITS_IN_JSAMPLE which is always set to 8 in libjpeg-turbo
+ * >= 2.2 Cf
+ * https://github.com/libjpeg-turbo/libjpeg-turbo/commit/8b9bc4b9635a2a047fb23ebe70c9acd728d3f99b
+ */
+#undef BITS_IN_JSAMPLE
+/* libjpeg-turbo >= 2.2 adds J12xxxx datatypes for the 12-bit mode. */
+#if defined(FROM_TIF_JPEG_12)
+#define BITS_IN_JSAMPLE 12
+#define TIFF_JSAMPLE J12SAMPLE
+#define TIFF_JSAMPARRAY J12SAMPARRAY
+#define TIFF_JSAMPIMAGE J12SAMPIMAGE
+#define TIFF_JSAMPROW J12SAMPROW
+#else
+#define BITS_IN_JSAMPLE 8
+#define TIFF_JSAMPLE JSAMPLE
+#define TIFF_JSAMPARRAY JSAMPARRAY
+#define TIFF_JSAMPIMAGE JSAMPIMAGE
+#define TIFF_JSAMPROW JSAMPROW
+#endif
+#else
+#define TIFF_JSAMPLE JSAMPLE
+#define TIFF_JSAMPARRAY JSAMPARRAY
+#define TIFF_JSAMPIMAGE JSAMPIMAGE
+#define TIFF_JSAMPROW JSAMPROW
+#endif
+
+#if defined(JPEG_LIB_MK1)
+#define JPEG_LIB_MK1_OR_12BIT 1
+#elif BITS_IN_JSAMPLE == 12
+#define JPEG_LIB_MK1_OR_12BIT 1
+#endif
+
+/*
+ * We are using width_in_blocks which is supposed to be private to
+ * libjpeg. Unfortunately, the libjpeg delivered with Cygwin has
+ * renamed this member to width_in_data_units. Since the header has
+ * also renamed a define, use that unique define name in order to
+ * detect the problem header and adjust to suit.
+ */
+#if defined(D_MAX_DATA_UNITS_IN_MCU)
+#define width_in_blocks width_in_data_units
+#endif
+
+/*
+ * 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
+
+typedef struct jpeg_destination_mgr jpeg_destination_mgr;
+typedef struct jpeg_source_mgr jpeg_source_mgr;
+typedef struct jpeg_error_mgr jpeg_error_mgr;
+
+/*
+ * State block for each open TIFF file using
+ * libjpeg to do JPEG compression/decompression.
+ *
+ * libjpeg's visible state is either a jpeg_compress_struct
+ * or jpeg_decompress_struct depending on which way we
+ * are going. comm can be used to refer to the fields
+ * which are common to both.
+ *
+ * NB: cinfo is required to be the first member of JPEGState,
+ * so we can safely cast JPEGState* -> jpeg_xxx_struct*
+ * 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 */
+ TIFF_JSAMPARRAY ds_buffer[MAX_COMPONENTS];
+ int scancount; /* number of "scanlines" accumulated */
+ int samplesperclump;
+
+ JPEGOtherSettings otherSettings;
+} JPEGState;
+
+#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);
+
+#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}};
+
+/*
+ * libjpeg interface layer.
+ *
+ * We use setjmp/longjmp to return control to libtiff
+ * when a fatal error is encountered within the JPEG
+ * library. We also direct libjpeg error and warning
+ * messages through the appropriate libtiff handlers.
+ */
+
+/*
+ * Error handling routines (these replace corresponding
+ * 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];
+
+ (*cinfo->err->format_message)(cinfo, buffer);
+ TIFFErrorExtR(sp->tif, "JPEGLib", "%s",
+ buffer); /* display the error message */
+ jpeg_abort(cinfo); /* clean up libjpeg state */
+ LONGJMP(sp->exit_jmpbuf, 1); /* return to libtiff caller */
+}
+
+/*
+ * This routine is invoked only for warning messages,
+ * 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];
+
+ (*cinfo->err->format_message)(cinfo, buffer);
+ TIFFWarningExtR(((JPEGState *)cinfo)->tif, "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->otherSettings.max_allowed_scan_number)
+ {
+ TIFFErrorExtR(
+ ((JPEGState *)cinfo)->tif, "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))
+
+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;
+
+ 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;
+
+ /* 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));
+}
+
+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_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_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, TIFF_JSAMPARRAY scanlines,
+ int num_lines)
+{
+#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) && BITS_IN_JSAMPLE == 12
+ return CALLJPEG(sp, -1,
+ (int)jpeg12_write_scanlines(&sp->cinfo.c, scanlines,
+ (JDIMENSION)num_lines));
+#else
+ return CALLJPEG(sp, -1,
+ (int)jpeg_write_scanlines(&sp->cinfo.c, scanlines,
+ (JDIMENSION)num_lines));
+#endif
+}
+
+static int TIFFjpeg_write_raw_data(JPEGState *sp, TIFF_JSAMPIMAGE data,
+ int num_lines)
+{
+#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) && BITS_IN_JSAMPLE == 12
+ return CALLJPEG(
+ sp, -1,
+ (int)jpeg12_write_raw_data(&sp->cinfo.c, data, (JDIMENSION)num_lines));
+#else
+ return CALLJPEG(
+ sp, -1,
+ (int)jpeg_write_raw_data(&sp->cinfo.c, data, (JDIMENSION)num_lines));
+#endif
+}
+
+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_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_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));
+}
+
+static int TIFFjpeg_read_scanlines(JPEGState *sp, TIFF_JSAMPARRAY scanlines,
+ int max_lines)
+{
+#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) && BITS_IN_JSAMPLE == 12
+ return CALLJPEG(sp, -1,
+ (int)jpeg12_read_scanlines(&sp->cinfo.d, scanlines,
+ (JDIMENSION)max_lines));
+#else
+ return CALLJPEG(sp, -1,
+ (int)jpeg_read_scanlines(&sp->cinfo.d, scanlines,
+ (JDIMENSION)max_lines));
+#endif
+}
+
+static int TIFFjpeg_read_raw_data(JPEGState *sp, TIFF_JSAMPIMAGE data,
+ int max_lines)
+{
+#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) && BITS_IN_JSAMPLE == 12
+ return CALLJPEG(
+ sp, -1,
+ (int)jpeg12_read_raw_data(&sp->cinfo.d, data, (JDIMENSION)max_lines));
+#else
+ return CALLJPEG(
+ sp, -1,
+ (int)jpeg_read_raw_data(&sp->cinfo.d, data, (JDIMENSION)max_lines));
+#endif
+}
+
+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_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));
+}
+
+/*
+ * JPEG library destination data manager.
+ * These routines direct compressed data from libjpeg into the
+ * libtiff output buffer.
+ */
+
+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;
+}
+
+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;
+
+#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;
+ }
+#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;
+
+ return (TRUE);
+}
+
+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 */
+}
+
+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, 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 =
+ _TIFFreallocExt(sp->tif, (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)
+ _TIFFfreeExt(tif, sp->otherSettings.jpegtables);
+ sp->otherSettings.jpegtables_length = 1000;
+ sp->otherSettings.jpegtables = (void *)_TIFFmallocExt(
+ tif, (tmsize_t)sp->otherSettings.jpegtables_length);
+ if (sp->otherSettings.jpegtables == NULL)
+ {
+ sp->otherSettings.jpegtables_length = 0;
+ TIFFErrorExtR(sp->tif, "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);
+}
+
+/*
+ * JPEG library source data manager.
+ * These routines supply compressed data to libjpeg.
+ */
+
+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;
+}
+
+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);
+ }
+#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);
+}
+
+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;
+ }
+ }
+}
+
+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;
+}
+
+/*
+ * Alternate source manager for reading from JPEGTables.
+ * We can share all the code except for the init routine.
+ */
+
+static void tables_init_source(j_decompress_ptr cinfo)
+{
+ JPEGState *sp = (JPEGState *)cinfo;
+
+ 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;
+}
+
+/*
+ * Allocate downsampled-data buffers needed for downsampled I/O.
+ * We use values computed in jpeg_start_compress or jpeg_start_decompress.
+ * We use libjpeg's allocator so that buffers will be released automatically
+ * 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;
+ TIFF_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 = (TIFF_JSAMPARRAY)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.
+ */
+
+#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING
+
+#define JPEG_MARKER_SOF0 0xC0
+#define JPEG_MARKER_SOF1 0xC1
+#define JPEG_MARKER_SOF2 0xC2
+#define JPEG_MARKER_SOF9 0xC9
+#define JPEG_MARKER_SOF10 0xCA
+#define JPEG_MARKER_DHT 0xC4
+#define JPEG_MARKER_SOI 0xD8
+#define JPEG_MARKER_SOS 0xDA
+#define JPEG_MARKER_DQT 0xDB
+#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;
+};
+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)
+{
+#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->otherSettings.ycbcrsampling_fetched)
+ JPEGFixupTagsSubsampling(tif);
+#endif
+
+ 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 = _TIFFmallocExt(tif, m.buffersize);
+ if (m.buffer == NULL)
+ {
+ TIFFWarningExtR(tif, 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))
+ TIFFWarningExtR(
+ tif, module,
+ "Unable to auto-correct subsampling values, likely corrupt JPEG "
+ "compressed data in first strip/tile; auto-correcting skipped");
+ _TIFFfreeExt(tif, 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)
+ {
+ TIFFWarningExtR(data->tif, 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)))
+ {
+ TIFFWarningExtR(data->tif, 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]))
+ {
+ TIFFWarningExtR(
+ data->tif, 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);
+}
+
+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);
+}
+
+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;
+ }
+ }
+}
+
+#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
+
+ 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)
+ {
+ TIFFErrorExtR(tif, "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 */
+/* scanline decoding. This happens when the JPEG stream uses multiple scans. */
+/* Currently only called in CHUNKY_STRIP_READ_SUPPORT mode through */
+/* scanline interface. */
+/* 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;
+
+#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;
+
+ 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_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)
+ {
+ TIFFWarningExtR(tif, 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. */
+ TIFFWarningExtR(tif, 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.
+ */
+ TIFFErrorExtR(tif, 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))
+ {
+ TIFFErrorExtR(tif, module, "Improper JPEG component count");
+ return (0);
+ }
+#ifdef JPEG_LIB_MK1
+ if (12 != td->td_bitspersample && 8 != td->td_bitspersample)
+ {
+ TIFFErrorExtR(tif, 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)
+ {
+ TIFFErrorExtR(tif, module, "Improper JPEG data precision");
+ return (0);
+ }
+#endif
+
+ if (sp->cinfo.d.progressive_mode &&
+ !sp->otherSettings.has_warned_about_progressive_mode)
+ {
+ TIFFWarningExtR(tif, 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 (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)
+ {
+ TIFFErrorExtR(
+ tif, 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)
+ {
+ TIFFErrorExtR(tif, 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)
+ {
+ TIFFErrorExtR(tif, 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)
+ {
+ TIFFErrorExtR(tif, 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;
+#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);
+}
+
+/*
+ * Decode a chunk of pixels.
+ * "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;
+
+ /*
+ ** 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)
+ TIFFWarningExtR(tif, 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);
+ }
+
+ /* 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;
+
+ /*
+ ** 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)
+ TIFFWarningExtR(tif, 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)
+ {
+ TIFF_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 = (TIFF_JSAMPROW)_TIFFmallocExt(
+ tif, 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;
+ TIFF_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)
+ _TIFFfreeExt(tif, 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);
+}
+#endif /* JPEG_LIB_MK1_OR_12BIT */
+
+/*ARGSUSED*/ static int DecodeRowError(TIFF *tif, uint8_t *buf, tmsize_t cc,
+ uint16_t s)
+
+{
+ (void)buf;
+ (void)cc;
+ (void)s;
+
+ TIFFErrorExtR(
+ tif, "TIFFReadScanline",
+ "scanline oriented access is not supported for downsampled JPEG "
+ "compressed images, consider enabling TIFFTAG_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;
+
+ 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)
+ {
+
+ /* 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)
+ tmpbuf = _TIFFmallocExt(tif, sizeof(unsigned short) *
+ sp->cinfo.d.output_width *
+ sp->cinfo.d.num_components);
+ if (tmpbuf == NULL)
+ {
+ TIFFErrorExtR(tif, "JPEGDecodeRaw", "Out of memory");
+ return 0;
+ }
+#endif
+
+ do
+ {
+ jpeg_component_info *compptr;
+ int ci, clumpoffset;
+
+ if (cc < sp->bytesperline)
+ {
+ TIFFErrorExtR(
+ tif, "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++)
+ {
+ TIFF_JSAMPLE *inptr =
+ sp->ds_buffer[ci][sp->scancount * vsamp + ypos];
+ JDIMENSION nclump;
+#if defined(JPEG_LIB_MK1_OR_12BIT)
+ TIFF_JSAMPLE *outptr = (TIFF_JSAMPLE *)tmpbuf + clumpoffset;
+#else
+ TIFF_JSAMPLE *outptr = (TIFF_JSAMPLE *)buf + clumpoffset;
+ if (cc < (tmsize_t)(clumpoffset +
+ (tmsize_t)samples_per_clump *
+ (clumps_per_line - 1) +
+ hsamp))
+ {
+ TIFFErrorExtR(
+ tif, "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 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));
+ }
+ }
+ }
+#endif
+
+ sp->scancount++;
+ tif->tif_row += sp->v_sampling;
+
+ buf += sp->bytesperline;
+ cc -= sp->bytesperline;
+
+ nrows -= sp->v_sampling;
+ } while (nrows > 0);
+
+#if defined(JPEG_LIB_MK1_OR_12BIT)
+ _TIFFfreeExt(tif, tmpbuf);
+#endif
+ }
+
+ /* 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)
+ _TIFFfreeExt(tif, 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 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 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->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. */
+ TIFFWarningExtR(
+ tif, 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)
+ {
+ TIFFErrorExtR(tif, module,
+ "Invalig horizontal/vertical sampling value");
+ return (0);
+ }
+ if (td->td_bitspersample > 16)
+ {
+ TIFFErrorExtR(tif, 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:
+ TIFFErrorExtR(tif, 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)
+#else
+ if (td->td_bitspersample != BITS_IN_JSAMPLE)
+#endif
+ {
+ TIFFErrorExtR(tif, 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;
+#endif
+ if (isTiled(tif))
+ {
+ if ((td->td_tilelength % (sp->v_sampling * DCTSIZE)) != 0)
+ {
+ TIFFErrorExtR(tif, 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)
+ {
+ TIFFErrorExtR(tif, 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)
+ {
+ TIFFErrorExtR(tif, 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 (!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)
+ {
+ TIFFErrorExtR(tif, 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;
+ TIFF_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)
+ TIFFWarningExtR(tif, 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 *)_TIFFmallocExt(tif, sizeof(short) * line16_count);
+ if (!line16)
+ {
+ TIFFErrorExtR(tif, "JPEGEncode", "Failed to allocate memory");
+
+ return 0;
+ }
+ }
+
+ while (nrows-- > 0)
+ {
+
+ if (sp->cinfo.c.data_precision == 12)
+ {
+
+ int value_pairs = line16_count / 2;
+ int iPair;
+
+ bufptr[0] = (TIFF_JSAMPROW)line16;
+
+ for (iPair = 0; iPair < value_pairs; iPair++)
+ {
+ unsigned char *in_ptr = ((unsigned char *)buf) + iPair * 3;
+ TIFF_JSAMPLE *out_ptr = (TIFF_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] = (TIFF_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)
+ {
+ _TIFFfreeExt(tif, 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);
+ TIFF_JSAMPLE *inptr;
+ TIFF_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)
+ TIFFWarningExtR(tif, 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 = ((TIFF_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->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 */
+ _TIFFfreeExt(tif, sp->otherSettings.jpegtables);
+ _TIFFfreeExt(tif, 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? */
+#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);
+ }
+ _TIFFsetByteArrayExt(tif, &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
+ * examining {TILE/STRIP}BYTECOUNTS to see if there is a non-zero entry.
+ * 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.
+ *
+ * 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)
+ * so that stuff like update of missing tiles, or replacement of tiles could
+ * be done. However, we aren't trying to crack that nut just yet ...
+ *
+ * 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);
+#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;
+ }
+ }
+ }
+
+ 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)))
+ {
+ TIFFErrorExtR(tif, "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 *)_TIFFmallocExt(tif, sizeof(JPEGState));
+
+ if (tif->tif_data == NULL)
+ {
+ TIFFErrorExtR(tif, "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->otherSettings.jpegtables_length = SIZE_OF_JPEGTABLES;
+ sp->otherSettings.jpegtables =
+ (void *)_TIFFmallocExt(tif, sp->otherSettings.jpegtables_length);
+ if (sp->otherSettings.jpegtables)
+ {
+ _TIFFmemset(sp->otherSettings.jpegtables, 0, SIZE_OF_JPEGTABLES);
+ }
+ else
+ {
+ TIFFErrorExtR(tif, "TIFFInitJPEG",
+ "Failed to allocate memory for JPEG tables");
+ return 0;
+ }
+#undef SIZE_OF_JPEGTABLES
+ }
+ return 1;
+}
+#endif /* JPEG_SUPPORT */
diff --git a/contrib/libs/libtiff/tif_jpeg_12.c b/contrib/libs/libtiff/tif_jpeg_12.c
new file mode 100644
index 0000000000..a8db8beafb
--- /dev/null
+++ b/contrib/libs/libtiff/tif_jpeg_12.c
@@ -0,0 +1,63 @@
+
+#include "tiffiop.h"
+
+#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12)
+#define JPEG_DUAL_MODE_8_12
+#endif
+
+#if defined(JPEG_DUAL_MODE_8_12)
+
+#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);
+
+#if !defined(HAVE_JPEGTURBO_DUAL_MODE_8_12)
+#error #include LIBJPEG_12_PATH
+#endif
+
+#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 *)_TIFFreallocExt(tif, tif->tif_data, sizeof(JPEGState));
+
+ if (new_tif_data == NULL)
+ {
+ TIFFErrorExtR(tif, "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/contrib/libs/libtiff/tif_lerc.c b/contrib/libs/libtiff/tif_lerc.c
new file mode 100644
index 0000000000..19d330f392
--- /dev/null
+++ b/contrib/libs/libtiff/tif_lerc.c
@@ -0,0 +1,1206 @@
+/*
+ * Copyright (c) 2018, Even Rouault
+ * Author: <even.rouault at spatialys.com>
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+#include "tiffiop.h"
+#ifdef LERC_SUPPORT
+/*
+ * TIFF Library.
+ *
+ * LERC Compression Support
+ *
+ */
+
+#error #include "Lerc_c_api.h"
+#include "zlib.h"
+#ifdef ZSTD_SUPPORT
+#include "zstd.h"
+#endif
+
+#if LIBDEFLATE_SUPPORT
+#error #include "libdeflate.h"
+#endif
+#define LIBDEFLATE_MAX_COMPRESSION_LEVEL 12
+
+#include <assert.h>
+
+#define LSTATE_INIT_DECODE 0x01
+#define LSTATE_INIT_ENCODE 0x02
+
+#ifndef LERC_AT_LEAST_VERSION
+#define LERC_AT_LEAST_VERSION(maj, min, patch) 0
+#endif
+
+/*
+ * State block for each open TIFF file using LERC compression/decompression.
+ */
+typedef struct
+{
+ double maxzerror; /* max z error */
+ int lerc_version;
+ int additional_compression;
+ int zstd_compress_level; /* zstd */
+ int zipquality; /* deflate */
+ int state; /* state flags */
+
+ uint32_t segment_width;
+ uint32_t segment_height;
+
+ unsigned int uncompressed_size;
+ unsigned int uncompressed_alloc;
+ uint8_t *uncompressed_buffer;
+ unsigned int uncompressed_offset;
+
+ unsigned int mask_size;
+ uint8_t *mask_buffer;
+
+ unsigned int compressed_size;
+ void *compressed_buffer;
+
+#if LIBDEFLATE_SUPPORT
+ struct libdeflate_decompressor *libdeflate_dec;
+ struct libdeflate_compressor *libdeflate_enc;
+#endif
+
+ TIFFVGetMethod vgetparent; /* super-class method */
+ TIFFVSetMethod vsetparent; /* super-class method */
+} LERCState;
+
+#define LState(tif) ((LERCState *)(tif)->tif_data)
+#define DecoderState(tif) LState(tif)
+#define EncoderState(tif) LState(tif)
+
+static int LERCEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
+static int LERCDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s);
+
+static int LERCFixupTags(TIFF *tif)
+{
+ (void)tif;
+ return 1;
+}
+
+static int LERCSetupDecode(TIFF *tif)
+{
+ LERCState *sp = DecoderState(tif);
+
+ assert(sp != NULL);
+
+ /* if we were last encoding, terminate this mode */
+ if (sp->state & LSTATE_INIT_ENCODE)
+ {
+ sp->state = 0;
+ }
+
+ sp->state |= LSTATE_INIT_DECODE;
+ return 1;
+}
+
+static int GetLercDataType(TIFF *tif)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ static const char module[] = "GetLercDataType";
+
+ if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 8)
+ {
+ return 0;
+ }
+
+ if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 8)
+ {
+ return 1;
+ }
+
+ if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 16)
+ {
+ return 2;
+ }
+
+ if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 16)
+ {
+ return 3;
+ }
+
+ if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 32)
+ {
+ return 4;
+ }
+
+ if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 32)
+ {
+ return 5;
+ }
+
+ if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
+ td->td_bitspersample == 32)
+ {
+ return 6;
+ }
+
+ if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
+ td->td_bitspersample == 64)
+ {
+ return 7;
+ }
+
+ TIFFErrorExtR(
+ tif, module,
+ "Unsupported combination of SampleFormat and td_bitspersample");
+ return -1;
+}
+
+static int SetupUncompressedBuffer(TIFF *tif, LERCState *sp, const char *module)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ uint64_t new_size_64;
+ uint64_t new_alloc_64;
+ unsigned int new_size;
+ unsigned int new_alloc;
+
+ sp->uncompressed_offset = 0;
+
+ if (isTiled(tif))
+ {
+ sp->segment_width = td->td_tilewidth;
+ sp->segment_height = td->td_tilelength;
+ }
+ else
+ {
+ sp->segment_width = td->td_imagewidth;
+ sp->segment_height = td->td_imagelength - tif->tif_row;
+ if (sp->segment_height > td->td_rowsperstrip)
+ sp->segment_height = td->td_rowsperstrip;
+ }
+
+ new_size_64 = (uint64_t)sp->segment_width * sp->segment_height *
+ (td->td_bitspersample / 8);
+ if (td->td_planarconfig == PLANARCONFIG_CONTIG)
+ {
+ new_size_64 *= td->td_samplesperpixel;
+ }
+
+ new_size = (unsigned int)new_size_64;
+ sp->uncompressed_size = new_size;
+
+ /* add some margin as we are going to use it also to store deflate/zstd
+ * compressed data */
+ new_alloc_64 = 100 + new_size_64 + new_size_64 / 3;
+#ifdef ZSTD_SUPPORT
+ {
+ size_t zstd_max = ZSTD_compressBound((size_t)new_size_64);
+ if (new_alloc_64 < zstd_max)
+ {
+ new_alloc_64 = zstd_max;
+ }
+ }
+#endif
+ new_alloc = (unsigned int)new_alloc_64;
+ if (new_alloc != new_alloc_64)
+ {
+ TIFFErrorExtR(tif, module, "Too large uncompressed strip/tile");
+ _TIFFfreeExt(tif, sp->uncompressed_buffer);
+ sp->uncompressed_buffer = 0;
+ sp->uncompressed_alloc = 0;
+ return 0;
+ }
+
+ if (sp->uncompressed_alloc < new_alloc)
+ {
+ _TIFFfreeExt(tif, sp->uncompressed_buffer);
+ sp->uncompressed_buffer = _TIFFmallocExt(tif, new_alloc);
+ if (!sp->uncompressed_buffer)
+ {
+ TIFFErrorExtR(tif, module, "Cannot allocate buffer");
+ _TIFFfreeExt(tif, sp->uncompressed_buffer);
+ sp->uncompressed_buffer = 0;
+ sp->uncompressed_alloc = 0;
+ return 0;
+ }
+ sp->uncompressed_alloc = new_alloc;
+ }
+
+ if ((td->td_planarconfig == PLANARCONFIG_CONTIG &&
+ td->td_extrasamples > 0 &&
+ td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA &&
+ GetLercDataType(tif) == 1) ||
+ (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
+ (td->td_planarconfig == PLANARCONFIG_SEPARATE ||
+ td->td_samplesperpixel == 1) &&
+ (td->td_bitspersample == 32 || td->td_bitspersample == 64)))
+ {
+ unsigned int mask_size = sp->segment_width * sp->segment_height;
+ if (sp->mask_size < mask_size)
+ {
+ void *mask_buffer =
+ _TIFFreallocExt(tif, sp->mask_buffer, mask_size);
+ if (mask_buffer == NULL)
+ {
+ TIFFErrorExtR(tif, module, "Cannot allocate buffer");
+ sp->mask_size = 0;
+ _TIFFfreeExt(tif, sp->uncompressed_buffer);
+ sp->uncompressed_buffer = 0;
+ sp->uncompressed_alloc = 0;
+ return 0;
+ }
+ sp->mask_buffer = (uint8_t *)mask_buffer;
+ sp->mask_size = mask_size;
+ }
+ }
+
+ return 1;
+}
+
+/*
+ * Setup state for decoding a strip.
+ */
+static int LERCPreDecode(TIFF *tif, uint16_t s)
+{
+ static const char module[] = "LERCPreDecode";
+ lerc_status lerc_ret;
+ TIFFDirectory *td = &tif->tif_dir;
+ LERCState *sp = DecoderState(tif);
+ int lerc_data_type;
+ unsigned int infoArray[8];
+ unsigned nomask_bands = td->td_samplesperpixel;
+ int ndims;
+ int use_mask = 0;
+ uint8_t *lerc_data = tif->tif_rawcp;
+ unsigned int lerc_data_size = (unsigned int)tif->tif_rawcc;
+
+ (void)s;
+ assert(sp != NULL);
+ if (sp->state != LSTATE_INIT_DECODE)
+ tif->tif_setupdecode(tif);
+
+ lerc_data_type = GetLercDataType(tif);
+ if (lerc_data_type < 0)
+ return 0;
+
+ if (!SetupUncompressedBuffer(tif, sp, module))
+ return 0;
+
+ if (sp->additional_compression != LERC_ADD_COMPRESSION_NONE)
+ {
+ if (sp->compressed_size < sp->uncompressed_alloc)
+ {
+ _TIFFfreeExt(tif, sp->compressed_buffer);
+ sp->compressed_buffer = _TIFFmallocExt(tif, sp->uncompressed_alloc);
+ if (!sp->compressed_buffer)
+ {
+ sp->compressed_size = 0;
+ return 0;
+ }
+ sp->compressed_size = sp->uncompressed_alloc;
+ }
+ }
+
+ if (sp->additional_compression == LERC_ADD_COMPRESSION_DEFLATE)
+ {
+#if LIBDEFLATE_SUPPORT
+ enum libdeflate_result res;
+ size_t lerc_data_sizet = 0;
+ if (sp->libdeflate_dec == NULL)
+ {
+ sp->libdeflate_dec = libdeflate_alloc_decompressor();
+ if (sp->libdeflate_dec == NULL)
+ {
+ TIFFErrorExtR(tif, module, "Cannot allocate decompressor");
+ return 0;
+ }
+ }
+
+ res = libdeflate_zlib_decompress(
+ sp->libdeflate_dec, tif->tif_rawcp, (size_t)tif->tif_rawcc,
+ sp->compressed_buffer, sp->compressed_size, &lerc_data_sizet);
+ if (res != LIBDEFLATE_SUCCESS)
+ {
+ TIFFErrorExtR(tif, module, "Decoding error at scanline %lu",
+ (unsigned long)tif->tif_row);
+ return 0;
+ }
+ assert(lerc_data_sizet == (unsigned int)lerc_data_sizet);
+ lerc_data = sp->compressed_buffer;
+ lerc_data_size = (unsigned int)lerc_data_sizet;
+#else
+ z_stream strm;
+ int zlib_ret;
+
+ memset(&strm, 0, sizeof(strm));
+ strm.zalloc = NULL;
+ strm.zfree = NULL;
+ strm.opaque = NULL;
+ zlib_ret = inflateInit(&strm);
+ if (zlib_ret != Z_OK)
+ {
+ TIFFErrorExtR(tif, module, "inflateInit() failed");
+ inflateEnd(&strm);
+ return 0;
+ }
+
+ strm.avail_in = (uInt)tif->tif_rawcc;
+ strm.next_in = tif->tif_rawcp;
+ strm.avail_out = sp->compressed_size;
+ strm.next_out = sp->compressed_buffer;
+ zlib_ret = inflate(&strm, Z_FINISH);
+ if (zlib_ret != Z_STREAM_END && zlib_ret != Z_OK)
+ {
+ TIFFErrorExtR(tif, module, "inflate() failed");
+ inflateEnd(&strm);
+ return 0;
+ }
+ lerc_data = sp->compressed_buffer;
+ lerc_data_size = sp->compressed_size - strm.avail_out;
+ inflateEnd(&strm);
+#endif
+ }
+ else if (sp->additional_compression == LERC_ADD_COMPRESSION_ZSTD)
+ {
+#ifdef ZSTD_SUPPORT
+ size_t zstd_ret;
+
+ zstd_ret = ZSTD_decompress(sp->compressed_buffer, sp->compressed_size,
+ tif->tif_rawcp, tif->tif_rawcc);
+ if (ZSTD_isError(zstd_ret))
+ {
+ TIFFErrorExtR(tif, module, "Error in ZSTD_decompress(): %s",
+ ZSTD_getErrorName(zstd_ret));
+ return 0;
+ }
+
+ lerc_data = sp->compressed_buffer;
+ lerc_data_size = (unsigned int)zstd_ret;
+#else
+ TIFFErrorExtR(tif, module, "ZSTD support missing");
+ return 0;
+#endif
+ }
+ else if (sp->additional_compression != LERC_ADD_COMPRESSION_NONE)
+ {
+ TIFFErrorExtR(tif, module, "Unhandled additional compression");
+ return 0;
+ }
+
+ lerc_ret =
+ lerc_getBlobInfo(lerc_data, lerc_data_size, infoArray, NULL, 8, 0);
+ if (lerc_ret != 0)
+ {
+ TIFFErrorExtR(tif, module, "lerc_getBlobInfo() failed");
+ return 0;
+ }
+
+ /* If the configuration is compatible of a LERC mask, and that the */
+ /* LERC info has dim == samplesperpixel - 1, then there is a LERC */
+ /* mask. */
+ if (td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_extrasamples > 0 &&
+ td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA &&
+ GetLercDataType(tif) == 1 &&
+ infoArray[2] == td->td_samplesperpixel - 1U)
+ {
+ use_mask = 1;
+ nomask_bands--;
+ }
+ else if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
+ (td->td_planarconfig == PLANARCONFIG_SEPARATE ||
+ td->td_samplesperpixel == 1) &&
+ (td->td_bitspersample == 32 || td->td_bitspersample == 64))
+ {
+ use_mask = 1;
+ }
+
+ ndims = td->td_planarconfig == PLANARCONFIG_CONTIG ? nomask_bands : 1;
+
+ /* Info returned in infoArray is { version, dataType, nDim, nCols,
+ nRows, nBands, nValidPixels, blobSize } */
+ if (infoArray[0] != (unsigned)sp->lerc_version)
+ {
+ TIFFWarningExtR(tif, module,
+ "Unexpected version number: %d. Expected: %d",
+ infoArray[0], sp->lerc_version);
+ }
+ if (infoArray[1] != (unsigned)lerc_data_type)
+ {
+ TIFFErrorExtR(tif, module, "Unexpected dataType: %d. Expected: %d",
+ infoArray[1], lerc_data_type);
+ return 0;
+ }
+ if (infoArray[2] != (unsigned)ndims)
+ {
+ TIFFErrorExtR(tif, module, "Unexpected nDim: %d. Expected: %d",
+ infoArray[2], ndims);
+ return 0;
+ }
+ if (infoArray[3] != sp->segment_width)
+ {
+ TIFFErrorExtR(tif, module, "Unexpected nCols: %d. Expected: %du",
+ infoArray[3], sp->segment_width);
+ return 0;
+ }
+ if (infoArray[4] != sp->segment_height)
+ {
+ TIFFErrorExtR(tif, module, "Unexpected nRows: %d. Expected: %u",
+ infoArray[4], sp->segment_height);
+ return 0;
+ }
+ if (infoArray[5] != 1)
+ {
+ TIFFErrorExtR(tif, module, "Unexpected nBands: %d. Expected: %d",
+ infoArray[5], 1);
+ return 0;
+ }
+ if (infoArray[7] != lerc_data_size)
+ {
+ TIFFErrorExtR(tif, module, "Unexpected blobSize: %d. Expected: %u",
+ infoArray[7], lerc_data_size);
+ return 0;
+ }
+
+ lerc_ret = lerc_decode(lerc_data, lerc_data_size,
+#if LERC_AT_LEAST_VERSION(3, 0, 0)
+ use_mask ? 1 : 0,
+#endif
+ use_mask ? sp->mask_buffer : NULL, ndims,
+ sp->segment_width, sp->segment_height, 1,
+ lerc_data_type, sp->uncompressed_buffer);
+ if (lerc_ret != 0)
+ {
+ TIFFErrorExtR(tif, module, "lerc_decode() failed");
+ return 0;
+ }
+
+ /* Interleave alpha mask with other samples. */
+ if (use_mask && GetLercDataType(tif) == 1)
+ {
+ unsigned src_stride =
+ (td->td_samplesperpixel - 1) * (td->td_bitspersample / 8);
+ unsigned dst_stride =
+ td->td_samplesperpixel * (td->td_bitspersample / 8);
+ unsigned i = sp->segment_width * sp->segment_height;
+ /* Operate from end to begin to be able to move in place */
+ while (i > 0 && i > nomask_bands)
+ {
+ i--;
+ sp->uncompressed_buffer[i * dst_stride + td->td_samplesperpixel -
+ 1] = 255 * sp->mask_buffer[i];
+ memcpy(sp->uncompressed_buffer + i * dst_stride,
+ sp->uncompressed_buffer + i * src_stride, src_stride);
+ }
+ /* First pixels must use memmove due to overlapping areas */
+ while (i > 0)
+ {
+ i--;
+ sp->uncompressed_buffer[i * dst_stride + td->td_samplesperpixel -
+ 1] = 255 * sp->mask_buffer[i];
+ memmove(sp->uncompressed_buffer + i * dst_stride,
+ sp->uncompressed_buffer + i * src_stride, src_stride);
+ }
+ }
+ else if (use_mask && td->td_sampleformat == SAMPLEFORMAT_IEEEFP)
+ {
+ const unsigned nb_pixels = sp->segment_width * sp->segment_height;
+ unsigned i;
+#if WORDS_BIGENDIAN
+ const unsigned char nan_bytes[] = {0x7f, 0xc0, 0, 0};
+#else
+ const unsigned char nan_bytes[] = {0, 0, 0xc0, 0x7f};
+#endif
+ float nan_float32;
+ memcpy(&nan_float32, nan_bytes, 4);
+
+ if (td->td_bitspersample == 32)
+ {
+ for (i = 0; i < nb_pixels; i++)
+ {
+ if (sp->mask_buffer[i] == 0)
+ ((float *)sp->uncompressed_buffer)[i] = nan_float32;
+ }
+ }
+ else
+ {
+ const double nan_float64 = nan_float32;
+ for (i = 0; i < nb_pixels; i++)
+ {
+ if (sp->mask_buffer[i] == 0)
+ ((double *)sp->uncompressed_buffer)[i] = nan_float64;
+ }
+ }
+ }
+
+ return 1;
+}
+
+/*
+ * Decode a strip, tile or scanline.
+ */
+static int LERCDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
+{
+ static const char module[] = "LERCDecode";
+ LERCState *sp = DecoderState(tif);
+
+ (void)s;
+ assert(sp != NULL);
+ assert(sp->state == LSTATE_INIT_DECODE);
+
+ if (sp->uncompressed_buffer == 0)
+ {
+ TIFFErrorExtR(tif, module, "Uncompressed buffer not allocated");
+ return 0;
+ }
+
+ if ((uint64_t)sp->uncompressed_offset + (uint64_t)occ >
+ sp->uncompressed_size)
+ {
+ TIFFErrorExtR(tif, module, "Too many bytes read");
+ return 0;
+ }
+
+ memcpy(op, sp->uncompressed_buffer + sp->uncompressed_offset, occ);
+ sp->uncompressed_offset += (unsigned)occ;
+
+ return 1;
+}
+
+static int LERCSetupEncode(TIFF *tif)
+{
+ LERCState *sp = EncoderState(tif);
+
+ assert(sp != NULL);
+ if (sp->state & LSTATE_INIT_DECODE)
+ {
+ sp->state = 0;
+ }
+
+ sp->state |= LSTATE_INIT_ENCODE;
+
+ return 1;
+}
+
+/*
+ * Reset encoding state at the start of a strip.
+ */
+static int LERCPreEncode(TIFF *tif, uint16_t s)
+{
+ static const char module[] = "LERCPreEncode";
+ LERCState *sp = EncoderState(tif);
+ int lerc_data_type;
+
+ (void)s;
+ assert(sp != NULL);
+ if (sp->state != LSTATE_INIT_ENCODE)
+ tif->tif_setupencode(tif);
+
+ lerc_data_type = GetLercDataType(tif);
+ if (lerc_data_type < 0)
+ return 0;
+
+ if (!SetupUncompressedBuffer(tif, sp, module))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Encode a chunk of pixels.
+ */
+static int LERCEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
+{
+ static const char module[] = "LERCEncode";
+ LERCState *sp = EncoderState(tif);
+
+ (void)s;
+ assert(sp != NULL);
+ assert(sp->state == LSTATE_INIT_ENCODE);
+
+ if ((uint64_t)sp->uncompressed_offset + (uint64_t)cc >
+ sp->uncompressed_size)
+ {
+ TIFFErrorExtR(tif, module, "Too many bytes written");
+ return 0;
+ }
+
+ memcpy(sp->uncompressed_buffer + sp->uncompressed_offset, bp, cc);
+ sp->uncompressed_offset += (unsigned)cc;
+
+ return 1;
+}
+
+/*
+ * Finish off an encoded strip by flushing it.
+ */
+static int LERCPostEncode(TIFF *tif)
+{
+ lerc_status lerc_ret;
+ static const char module[] = "LERCPostEncode";
+ LERCState *sp = EncoderState(tif);
+ unsigned int numBytes = 0;
+ unsigned int numBytesWritten = 0;
+ TIFFDirectory *td = &tif->tif_dir;
+ int use_mask = 0;
+ unsigned dst_nbands = td->td_samplesperpixel;
+
+ if (sp->uncompressed_offset != sp->uncompressed_size)
+ {
+ TIFFErrorExtR(tif, module, "Unexpected number of bytes in the buffer");
+ return 0;
+ }
+
+ /* Extract alpha mask (if containing only 0 and 255 values, */
+ /* and compact array of regular bands */
+ if (td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_extrasamples > 0 &&
+ td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA &&
+ GetLercDataType(tif) == 1)
+ {
+ const unsigned dst_stride =
+ (td->td_samplesperpixel - 1) * (td->td_bitspersample / 8);
+ const unsigned src_stride =
+ td->td_samplesperpixel * (td->td_bitspersample / 8);
+ unsigned i = 0;
+ const unsigned nb_pixels = sp->segment_width * sp->segment_height;
+
+ use_mask = 1;
+ for (i = 0; i < nb_pixels; i++)
+ {
+ int v = sp->uncompressed_buffer[i * src_stride +
+ td->td_samplesperpixel - 1];
+ if (v != 0 && v != 255)
+ {
+ use_mask = 0;
+ break;
+ }
+ }
+
+ if (use_mask)
+ {
+ dst_nbands--;
+ /* First pixels must use memmove due to overlapping areas */
+ for (i = 0; i < dst_nbands && i < nb_pixels; i++)
+ {
+ memmove(sp->uncompressed_buffer + i * dst_stride,
+ sp->uncompressed_buffer + i * src_stride, dst_stride);
+ sp->mask_buffer[i] =
+ sp->uncompressed_buffer[i * src_stride +
+ td->td_samplesperpixel - 1];
+ }
+ for (; i < nb_pixels; i++)
+ {
+ memcpy(sp->uncompressed_buffer + i * dst_stride,
+ sp->uncompressed_buffer + i * src_stride, dst_stride);
+ sp->mask_buffer[i] =
+ sp->uncompressed_buffer[i * src_stride +
+ td->td_samplesperpixel - 1];
+ }
+ }
+ }
+ else if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
+ (td->td_planarconfig == PLANARCONFIG_SEPARATE ||
+ dst_nbands == 1) &&
+ (td->td_bitspersample == 32 || td->td_bitspersample == 64))
+ {
+ /* Check for NaN values */
+ unsigned i;
+ const unsigned nb_pixels = sp->segment_width * sp->segment_height;
+ if (td->td_bitspersample == 32)
+ {
+ for (i = 0; i < nb_pixels; i++)
+ {
+ const float val = ((float *)sp->uncompressed_buffer)[i];
+ if (val != val)
+ {
+ use_mask = 1;
+ break;
+ }
+ }
+ }
+ else
+ {
+ for (i = 0; i < nb_pixels; i++)
+ {
+ const double val = ((double *)sp->uncompressed_buffer)[i];
+ if (val != val)
+ {
+ use_mask = 1;
+ break;
+ }
+ }
+ }
+
+ if (use_mask)
+ {
+ if (td->td_bitspersample == 32)
+ {
+ for (i = 0; i < nb_pixels; i++)
+ {
+ const float val = ((float *)sp->uncompressed_buffer)[i];
+ sp->mask_buffer[i] = (val == val) ? 255 : 0;
+ }
+ }
+ else
+ {
+ for (i = 0; i < nb_pixels; i++)
+ {
+ const double val = ((double *)sp->uncompressed_buffer)[i];
+ sp->mask_buffer[i] = (val == val) ? 255 : 0;
+ }
+ }
+ }
+ }
+
+#if 0
+ lerc_ret = lerc_computeCompressedSize(
+ sp->uncompressed_buffer,
+ sp->lerc_version,
+ GetLercDataType(tif),
+ td->td_planarconfig == PLANARCONFIG_CONTIG ?
+ dst_nbands : 1,
+ sp->segment_width,
+ sp->segment_height,
+ 1,
+ use_mask ? sp->mask_buffer : NULL,
+ sp->maxzerror,
+ &numBytes);
+ if( lerc_ret != 0 )
+ {
+ TIFFErrorExtR(tif, module,
+ "lerc_computeCompressedSize() failed");
+ return 0;
+ }
+#else
+ numBytes = sp->uncompressed_alloc;
+#endif
+
+ if (sp->compressed_size < numBytes)
+ {
+ _TIFFfreeExt(tif, sp->compressed_buffer);
+ sp->compressed_buffer = _TIFFmallocExt(tif, numBytes);
+ if (!sp->compressed_buffer)
+ {
+ sp->compressed_size = 0;
+ return 0;
+ }
+ sp->compressed_size = numBytes;
+ }
+
+ lerc_ret = lerc_encodeForVersion(
+ sp->uncompressed_buffer, sp->lerc_version, GetLercDataType(tif),
+ td->td_planarconfig == PLANARCONFIG_CONTIG ? dst_nbands : 1,
+ sp->segment_width, sp->segment_height, 1,
+#if LERC_AT_LEAST_VERSION(3, 0, 0)
+ use_mask ? 1 : 0,
+#endif
+ use_mask ? sp->mask_buffer : NULL, sp->maxzerror, sp->compressed_buffer,
+ sp->compressed_size, &numBytesWritten);
+ if (lerc_ret != 0)
+ {
+ TIFFErrorExtR(tif, module, "lerc_encode() failed");
+ return 0;
+ }
+ assert(numBytesWritten < numBytes);
+
+ if (sp->additional_compression == LERC_ADD_COMPRESSION_DEFLATE)
+ {
+#if LIBDEFLATE_SUPPORT
+ if (sp->libdeflate_enc == NULL)
+ {
+ /* To get results as good as zlib, we ask for an extra */
+ /* level of compression */
+ sp->libdeflate_enc = libdeflate_alloc_compressor(
+ sp->zipquality == Z_DEFAULT_COMPRESSION ? 7
+ : sp->zipquality >= 6 && sp->zipquality <= 9
+ ? sp->zipquality + 1
+ : sp->zipquality);
+ if (sp->libdeflate_enc == NULL)
+ {
+ TIFFErrorExtR(tif, module, "Cannot allocate compressor");
+ return 0;
+ }
+ }
+
+ /* Should not happen normally */
+ if (libdeflate_zlib_compress_bound(
+ sp->libdeflate_enc, numBytesWritten) > sp->uncompressed_alloc)
+ {
+ TIFFErrorExtR(tif, module,
+ "Output buffer for libdeflate too small");
+ return 0;
+ }
+
+ tif->tif_rawcc = libdeflate_zlib_compress(
+ sp->libdeflate_enc, sp->compressed_buffer, numBytesWritten,
+ sp->uncompressed_buffer, sp->uncompressed_alloc);
+
+ if (tif->tif_rawcc == 0)
+ {
+ TIFFErrorExtR(tif, module, "Encoder error at scanline %lu",
+ (unsigned long)tif->tif_row);
+ return 0;
+ }
+#else
+ z_stream strm;
+ int zlib_ret;
+ int cappedQuality = sp->zipquality;
+ if (cappedQuality > Z_BEST_COMPRESSION)
+ cappedQuality = Z_BEST_COMPRESSION;
+
+ memset(&strm, 0, sizeof(strm));
+ strm.zalloc = NULL;
+ strm.zfree = NULL;
+ strm.opaque = NULL;
+ zlib_ret = deflateInit(&strm, cappedQuality);
+ if (zlib_ret != Z_OK)
+ {
+ TIFFErrorExtR(tif, module, "deflateInit() failed");
+ return 0;
+ }
+
+ strm.avail_in = numBytesWritten;
+ strm.next_in = sp->compressed_buffer;
+ strm.avail_out = sp->uncompressed_alloc;
+ strm.next_out = sp->uncompressed_buffer;
+ zlib_ret = deflate(&strm, Z_FINISH);
+ if (zlib_ret == Z_STREAM_END)
+ {
+ tif->tif_rawcc = sp->uncompressed_alloc - strm.avail_out;
+ }
+ deflateEnd(&strm);
+ if (zlib_ret != Z_STREAM_END)
+ {
+ TIFFErrorExtR(tif, module, "deflate() failed");
+ return 0;
+ }
+#endif
+ {
+ int ret;
+ uint8_t *tif_rawdata_backup = tif->tif_rawdata;
+ tif->tif_rawdata = sp->uncompressed_buffer;
+ ret = TIFFFlushData1(tif);
+ tif->tif_rawdata = tif_rawdata_backup;
+ if (!ret)
+ {
+ return 0;
+ }
+ }
+ }
+ else if (sp->additional_compression == LERC_ADD_COMPRESSION_ZSTD)
+ {
+#ifdef ZSTD_SUPPORT
+ size_t zstd_ret = ZSTD_compress(
+ sp->uncompressed_buffer, sp->uncompressed_alloc,
+ sp->compressed_buffer, numBytesWritten, sp->zstd_compress_level);
+ if (ZSTD_isError(zstd_ret))
+ {
+ TIFFErrorExtR(tif, module, "Error in ZSTD_compress(): %s",
+ ZSTD_getErrorName(zstd_ret));
+ return 0;
+ }
+
+ {
+ int ret;
+ uint8_t *tif_rawdata_backup = tif->tif_rawdata;
+ tif->tif_rawdata = sp->uncompressed_buffer;
+ tif->tif_rawcc = zstd_ret;
+ ret = TIFFFlushData1(tif);
+ tif->tif_rawdata = tif_rawdata_backup;
+ if (!ret)
+ {
+ return 0;
+ }
+ }
+#else
+ TIFFErrorExtR(tif, module, "ZSTD support missing");
+ return 0;
+#endif
+ }
+ else if (sp->additional_compression != LERC_ADD_COMPRESSION_NONE)
+ {
+ TIFFErrorExtR(tif, module, "Unhandled additional compression");
+ return 0;
+ }
+ else
+ {
+ int ret;
+ uint8_t *tif_rawdata_backup = tif->tif_rawdata;
+ tif->tif_rawdata = sp->compressed_buffer;
+ tif->tif_rawcc = numBytesWritten;
+ ret = TIFFFlushData1(tif);
+ tif->tif_rawdata = tif_rawdata_backup;
+ if (!ret)
+ return 0;
+ }
+
+ return 1;
+}
+
+static void LERCCleanup(TIFF *tif)
+{
+ LERCState *sp = LState(tif);
+
+ assert(sp != 0);
+
+ tif->tif_tagmethods.vgetfield = sp->vgetparent;
+ tif->tif_tagmethods.vsetfield = sp->vsetparent;
+
+ _TIFFfreeExt(tif, sp->uncompressed_buffer);
+ _TIFFfreeExt(tif, sp->compressed_buffer);
+ _TIFFfreeExt(tif, sp->mask_buffer);
+
+#if LIBDEFLATE_SUPPORT
+ if (sp->libdeflate_dec)
+ libdeflate_free_decompressor(sp->libdeflate_dec);
+ if (sp->libdeflate_enc)
+ libdeflate_free_compressor(sp->libdeflate_enc);
+#endif
+
+ _TIFFfreeExt(tif, sp);
+ tif->tif_data = NULL;
+
+ _TIFFSetDefaultCompressionState(tif);
+}
+
+static const TIFFField LERCFields[] = {
+ {TIFFTAG_LERC_PARAMETERS, TIFF_VARIABLE2, TIFF_VARIABLE2, TIFF_LONG, 0,
+ TIFF_SETGET_C32_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, FALSE, TRUE,
+ "LercParameters", NULL},
+ {TIFFTAG_LERC_MAXZERROR, 0, 0, TIFF_ANY, 0, TIFF_SETGET_DOUBLE,
+ TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "LercMaximumError",
+ NULL},
+ {TIFFTAG_LERC_VERSION, 0, 0, TIFF_ANY, 0, TIFF_SETGET_UINT32,
+ TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "LercVersion", NULL},
+ {TIFFTAG_LERC_ADD_COMPRESSION, 0, 0, TIFF_ANY, 0, TIFF_SETGET_UINT32,
+ TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE,
+ "LercAdditionalCompression", NULL},
+ {TIFFTAG_ZSTD_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
+ TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE,
+ "ZSTD zstd_compress_level", NULL},
+ {TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
+ TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL},
+};
+
+static int LERCVSetFieldBase(TIFF *tif, uint32_t tag, ...)
+{
+ LERCState *sp = LState(tif);
+ int ret;
+ va_list ap;
+ va_start(ap, tag);
+ ret = (*sp->vsetparent)(tif, tag, ap);
+ va_end(ap);
+ return ret;
+}
+
+static int LERCVSetField(TIFF *tif, uint32_t tag, va_list ap)
+{
+ static const char module[] = "LERCVSetField";
+ LERCState *sp = LState(tif);
+
+ switch (tag)
+ {
+ case TIFFTAG_LERC_PARAMETERS:
+ {
+ uint32_t count = va_arg(ap, int);
+ int *params = va_arg(ap, int *);
+ if (count < 2)
+ {
+ TIFFErrorExtR(tif, module,
+ "Invalid count for LercParameters: %u", count);
+ return 0;
+ }
+ sp->lerc_version = params[0];
+ sp->additional_compression = params[1];
+ return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, count,
+ params);
+ }
+ case TIFFTAG_LERC_MAXZERROR:
+ sp->maxzerror = va_arg(ap, double);
+ return 1;
+ case TIFFTAG_LERC_VERSION:
+ {
+ int params[2] = {0, 0};
+ int version = va_arg(ap, int);
+ if (version != LERC_VERSION_2_4)
+ {
+ TIFFErrorExtR(tif, module, "Invalid value for LercVersion: %d",
+ version);
+ return 0;
+ }
+ sp->lerc_version = version;
+ params[0] = sp->lerc_version;
+ params[1] = sp->additional_compression;
+ return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, 2, params);
+ }
+ case TIFFTAG_LERC_ADD_COMPRESSION:
+ {
+ int params[2] = {0, 0};
+ int additional_compression = va_arg(ap, int);
+#ifndef ZSTD_SUPPORT
+ if (additional_compression == LERC_ADD_COMPRESSION_ZSTD)
+ {
+ TIFFErrorExtR(tif, module,
+ "LERC_ZSTD requested, but ZSTD not available");
+ return 0;
+ }
+#endif
+ if (additional_compression != LERC_ADD_COMPRESSION_NONE &&
+ additional_compression != LERC_ADD_COMPRESSION_DEFLATE &&
+ additional_compression != LERC_ADD_COMPRESSION_ZSTD)
+ {
+ TIFFErrorExtR(tif, module,
+ "Invalid value for LercAdditionalCompression: %d",
+ additional_compression);
+ return 0;
+ }
+ sp->additional_compression = additional_compression;
+ params[0] = sp->lerc_version;
+ params[1] = sp->additional_compression;
+ return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, 2, params);
+ }
+#ifdef ZSTD_SUPPORT
+ case TIFFTAG_ZSTD_LEVEL:
+ {
+ sp->zstd_compress_level = (int)va_arg(ap, int);
+ if (sp->zstd_compress_level <= 0 ||
+ sp->zstd_compress_level > ZSTD_maxCLevel())
+ {
+ TIFFWarningExtR(tif, module,
+ "ZSTD_LEVEL should be between 1 and %d",
+ ZSTD_maxCLevel());
+ }
+ return 1;
+ }
+#endif
+ case TIFFTAG_ZIPQUALITY:
+ {
+ sp->zipquality = (int)va_arg(ap, int);
+ if (sp->zipquality < Z_DEFAULT_COMPRESSION ||
+ sp->zipquality > LIBDEFLATE_MAX_COMPRESSION_LEVEL)
+ {
+ TIFFErrorExtR(
+ tif, module,
+ "Invalid ZipQuality value. Should be in [-1,%d] range",
+ LIBDEFLATE_MAX_COMPRESSION_LEVEL);
+ return 0;
+ }
+
+#if LIBDEFLATE_SUPPORT
+ if (sp->libdeflate_enc)
+ {
+ libdeflate_free_compressor(sp->libdeflate_enc);
+ sp->libdeflate_enc = NULL;
+ }
+#endif
+
+ return (1);
+ }
+ default:
+ return (*sp->vsetparent)(tif, tag, ap);
+ }
+ /*NOTREACHED*/
+}
+
+static int LERCVGetField(TIFF *tif, uint32_t tag, va_list ap)
+{
+ LERCState *sp = LState(tif);
+
+ switch (tag)
+ {
+ case TIFFTAG_LERC_MAXZERROR:
+ *va_arg(ap, double *) = sp->maxzerror;
+ break;
+ case TIFFTAG_LERC_VERSION:
+ *va_arg(ap, int *) = sp->lerc_version;
+ break;
+ case TIFFTAG_LERC_ADD_COMPRESSION:
+ *va_arg(ap, int *) = sp->additional_compression;
+ break;
+ case TIFFTAG_ZSTD_LEVEL:
+ *va_arg(ap, int *) = sp->zstd_compress_level;
+ break;
+ case TIFFTAG_ZIPQUALITY:
+ *va_arg(ap, int *) = sp->zipquality;
+ break;
+ default:
+ return (*sp->vgetparent)(tif, tag, ap);
+ }
+ return 1;
+}
+
+int TIFFInitLERC(TIFF *tif, int scheme)
+{
+ static const char module[] = "TIFFInitLERC";
+ LERCState *sp;
+
+ (void)scheme;
+ assert(scheme == COMPRESSION_LERC);
+
+ /*
+ * Merge codec-specific tag information.
+ */
+ if (!_TIFFMergeFields(tif, LERCFields, TIFFArrayCount(LERCFields)))
+ {
+ TIFFErrorExtR(tif, module, "Merging LERC codec-specific tags failed");
+ return 0;
+ }
+
+ /*
+ * Allocate state block so tag methods have storage to record values.
+ */
+ tif->tif_data = (uint8_t *)_TIFFcallocExt(tif, 1, sizeof(LERCState));
+ if (tif->tif_data == NULL)
+ goto bad;
+ sp = LState(tif);
+
+ /*
+ * Override parent get/set field methods.
+ */
+ sp->vgetparent = tif->tif_tagmethods.vgetfield;
+ tif->tif_tagmethods.vgetfield = LERCVGetField; /* hook for codec tags */
+ sp->vsetparent = tif->tif_tagmethods.vsetfield;
+ tif->tif_tagmethods.vsetfield = LERCVSetField; /* hook for codec tags */
+
+ /*
+ * Install codec methods.
+ */
+ tif->tif_fixuptags = LERCFixupTags;
+ tif->tif_setupdecode = LERCSetupDecode;
+ tif->tif_predecode = LERCPreDecode;
+ tif->tif_decoderow = LERCDecode;
+ tif->tif_decodestrip = LERCDecode;
+ tif->tif_decodetile = LERCDecode;
+ tif->tif_setupencode = LERCSetupEncode;
+ tif->tif_preencode = LERCPreEncode;
+ tif->tif_postencode = LERCPostEncode;
+ tif->tif_encoderow = LERCEncode;
+ tif->tif_encodestrip = LERCEncode;
+ tif->tif_encodetile = LERCEncode;
+ tif->tif_cleanup = LERCCleanup;
+
+ /* Default values for codec-specific fields */
+ TIFFSetField(tif, TIFFTAG_LERC_VERSION, LERC_VERSION_2_4);
+ TIFFSetField(tif, TIFFTAG_LERC_ADD_COMPRESSION, LERC_ADD_COMPRESSION_NONE);
+ sp->maxzerror = 0.0;
+ sp->zstd_compress_level = 9; /* default comp. level */
+ sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */
+ sp->state = 0;
+
+ return 1;
+bad:
+ TIFFErrorExtR(tif, module, "No space for LERC state block");
+ return 0;
+}
+#endif /* LERC_SUPPORT */
diff --git a/contrib/libs/libtiff/tif_luv.c b/contrib/libs/libtiff/tif_luv.c
new file mode 100644
index 0000000000..021756d5d6
--- /dev/null
+++ b/contrib/libs/libtiff/tif_luv.c
@@ -0,0 +1,1838 @@
+/*
+ * Copyright (c) 1997 Greg Ward Larson
+ * Copyright (c) 1997 Silicon Graphics, Inc.
+ *
+ * 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, Greg Larson 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, Greg Larson 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.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER, GREG LARSON 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
+ * OF THIS SOFTWARE.
+ */
+
+#include "tiffiop.h"
+#ifdef LOGLUV_SUPPORT
+
+/*
+ * TIFF Library.
+ * LogLuv compression support for high dynamic range images.
+ *
+ * Contributed by Greg Larson.
+ *
+ * LogLuv image support uses the TIFF library to store 16 or 10-bit
+ * log luminance values with 8 bits each of u and v or a 14-bit index.
+ *
+ * The codec can take as input and produce as output 32-bit IEEE float values
+ * as well as 16-bit integer values. A 16-bit luminance is interpreted
+ * as a sign bit followed by a 15-bit integer that is converted
+ * to and from a linear magnitude using the transformation:
+ *
+ * L = 2^( (Le+.5)/256 - 64 ) # real from 15-bit
+ *
+ * Le = floor( 256*(log2(L) + 64) ) # 15-bit from real
+ *
+ * The actual conversion to world luminance units in candelas per sq. meter
+ * requires an additional multiplier, which is stored in the TIFFTAG_STONITS.
+ * This value is usually set such that a reasonable exposure comes from
+ * clamping decoded luminances above 1 to 1 in the displayed image.
+ *
+ * The 16-bit values for u and v may be converted to real values by dividing
+ * each by 32768. (This allows for negative values, which aren't useful as
+ * far as we know, but are left in case of future improvements in human
+ * color vision.)
+ *
+ * Conversion from (u,v), which is actually the CIE (u',v') system for
+ * you color scientists, is accomplished by the following transformation:
+ *
+ * u = 4*x / (-2*x + 12*y + 3)
+ * v = 9*y / (-2*x + 12*y + 3)
+ *
+ * x = 9*u / (6*u - 16*v + 12)
+ * y = 4*v / (6*u - 16*v + 12)
+ *
+ * This process is greatly simplified by passing 32-bit IEEE floats
+ * for each of three CIE XYZ coordinates. The codec then takes care
+ * of conversion to and from LogLuv, though the application is still
+ * responsible for interpreting the TIFFTAG_STONITS calibration factor.
+ *
+ * By definition, a CIE XYZ vector of [1 1 1] corresponds to a neutral white
+ * point of (x,y)=(1/3,1/3). However, most color systems assume some other
+ * white point, such as D65, and an absolute color conversion to XYZ then
+ * to another color space with a different white point may introduce an
+ * unwanted color cast to the image. It is often desirable, therefore, to
+ * perform a white point conversion that maps the input white to [1 1 1]
+ * in XYZ, then record the original white point using the TIFFTAG_WHITEPOINT
+ * tag value. A decoder that demands absolute color calibration may use
+ * this white point tag to get back the original colors, but usually it
+ * will be ignored and the new white point will be used instead that
+ * matches the output color space.
+ *
+ * Pixel information is compressed into one of two basic encodings, depending
+ * on the setting of the compression tag, which is one of COMPRESSION_SGILOG
+ * or COMPRESSION_SGILOG24. For COMPRESSION_SGILOG, greyscale data is
+ * stored as:
+ *
+ * 1 15
+ * |-+---------------|
+ *
+ * COMPRESSION_SGILOG color data is stored as:
+ *
+ * 1 15 8 8
+ * |-+---------------|--------+--------|
+ * S Le ue ve
+ *
+ * For the 24-bit COMPRESSION_SGILOG24 color format, the data is stored as:
+ *
+ * 10 14
+ * |----------|--------------|
+ * Le' Ce
+ *
+ * There is no sign bit in the 24-bit case, and the (u,v) chromaticity is
+ * encoded as an index for optimal color resolution. The 10 log bits are
+ * defined by the following conversions:
+ *
+ * L = 2^((Le'+.5)/64 - 12) # real from 10-bit
+ *
+ * Le' = floor( 64*(log2(L) + 12) ) # 10-bit from real
+ *
+ * The 10 bits of the smaller format may be converted into the 15 bits of
+ * the larger format by multiplying by 4 and adding 13314. Obviously,
+ * a smaller range of magnitudes is covered (about 5 orders of magnitude
+ * instead of 38), and the lack of a sign bit means that negative luminances
+ * are not allowed. (Well, they aren't allowed in the real world, either,
+ * but they are useful for certain types of image processing.)
+ *
+ * The desired user format is controlled by the setting the internal
+ * pseudo tag TIFFTAG_SGILOGDATAFMT to one of:
+ * SGILOGDATAFMT_FLOAT = IEEE 32-bit float XYZ values
+ * SGILOGDATAFMT_16BIT = 16-bit integer encodings of logL, u and v
+ * Raw data i/o is also possible using:
+ * SGILOGDATAFMT_RAW = 32-bit unsigned integer with encoded pixel
+ * In addition, the following decoding is provided for ease of display:
+ * SGILOGDATAFMT_8BIT = 8-bit default RGB gamma-corrected values
+ *
+ * For grayscale images, we provide the following data formats:
+ * SGILOGDATAFMT_FLOAT = IEEE 32-bit float Y values
+ * SGILOGDATAFMT_16BIT = 16-bit integer w/ encoded luminance
+ * SGILOGDATAFMT_8BIT = 8-bit gray monitor values
+ *
+ * Note that the COMPRESSION_SGILOG applies a simple run-length encoding
+ * scheme by separating the logL, u and v bytes for each row and applying
+ * a PackBits type of compression. Since the 24-bit encoding is not
+ * adaptive, the 32-bit color format takes less space in many cases.
+ *
+ * Further control is provided over the conversion from higher-resolution
+ * formats to final encoded values through the pseudo tag
+ * TIFFTAG_SGILOGENCODE:
+ * SGILOGENCODE_NODITHER = do not dither encoded values
+ * SGILOGENCODE_RANDITHER = apply random dithering during encoding
+ *
+ * The default value of this tag is SGILOGENCODE_NODITHER for
+ * COMPRESSION_SGILOG to maximize run-length encoding and
+ * SGILOGENCODE_RANDITHER for COMPRESSION_SGILOG24 to turn
+ * quantization errors into noise.
+ */
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/*
+ * State block for each open TIFF
+ * file using LogLuv compression/decompression.
+ */
+typedef struct logLuvState LogLuvState;
+
+struct logLuvState
+{
+ int encoder_state; /* 1 if encoder correctly initialized */
+ int user_datafmt; /* user data format */
+ int encode_meth; /* encoding method */
+ int pixel_size; /* bytes per pixel */
+
+ uint8_t *tbuf; /* translation buffer */
+ tmsize_t tbuflen; /* buffer length */
+ void (*tfunc)(LogLuvState *, uint8_t *, tmsize_t);
+
+ TIFFVSetMethod vgetparent; /* super-class method */
+ TIFFVSetMethod vsetparent; /* super-class method */
+};
+
+#define DecoderState(tif) ((LogLuvState *)(tif)->tif_data)
+#define EncoderState(tif) ((LogLuvState *)(tif)->tif_data)
+
+#define SGILOGDATAFMT_UNKNOWN -1
+
+#define MINRUN 4 /* minimum run length */
+
+/*
+ * Decode a string of 16-bit gray pixels.
+ */
+static int LogL16Decode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
+{
+ static const char module[] = "LogL16Decode";
+ LogLuvState *sp = DecoderState(tif);
+ int shft;
+ tmsize_t i;
+ tmsize_t npixels;
+ unsigned char *bp;
+ int16_t *tp;
+ int16_t b;
+ tmsize_t cc;
+ int rc;
+
+ (void)s;
+ assert(s == 0);
+ assert(sp != NULL);
+
+ npixels = occ / sp->pixel_size;
+
+ if (sp->user_datafmt == SGILOGDATAFMT_16BIT)
+ tp = (int16_t *)op;
+ else
+ {
+ if (sp->tbuflen < npixels)
+ {
+ TIFFErrorExtR(tif, module, "Translation buffer too short");
+ return (0);
+ }
+ tp = (int16_t *)sp->tbuf;
+ }
+ _TIFFmemset((void *)tp, 0, npixels * sizeof(tp[0]));
+
+ bp = (unsigned char *)tif->tif_rawcp;
+ cc = tif->tif_rawcc;
+ /* get each byte string */
+ for (shft = 8; shft >= 0; shft -= 8)
+ {
+ for (i = 0; i < npixels && cc > 0;)
+ {
+ if (*bp >= 128)
+ { /* run */
+ if (cc < 2)
+ break;
+ rc = *bp++ + (2 - 128);
+ b = (int16_t)(*bp++ << shft);
+ cc -= 2;
+ while (rc-- && i < npixels)
+ tp[i++] |= b;
+ }
+ else
+ { /* non-run */
+ rc = *bp++; /* nul is noop */
+ while (--cc && rc-- && i < npixels)
+ tp[i++] |= (int16_t)*bp++ << shft;
+ }
+ }
+ if (i != npixels)
+ {
+ TIFFErrorExtR(tif, module,
+ "Not enough data at row %" PRIu32
+ " (short %" TIFF_SSIZE_FORMAT " pixels)",
+ tif->tif_row, npixels - i);
+ tif->tif_rawcp = (uint8_t *)bp;
+ tif->tif_rawcc = cc;
+ return (0);
+ }
+ }
+ (*sp->tfunc)(sp, op, npixels);
+ tif->tif_rawcp = (uint8_t *)bp;
+ tif->tif_rawcc = cc;
+ return (1);
+}
+
+/*
+ * Decode a string of 24-bit pixels.
+ */
+static int LogLuvDecode24(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
+{
+ static const char module[] = "LogLuvDecode24";
+ LogLuvState *sp = DecoderState(tif);
+ tmsize_t cc;
+ tmsize_t i;
+ tmsize_t npixels;
+ unsigned char *bp;
+ uint32_t *tp;
+
+ (void)s;
+ assert(s == 0);
+ assert(sp != NULL);
+
+ npixels = occ / sp->pixel_size;
+
+ if (sp->user_datafmt == SGILOGDATAFMT_RAW)
+ tp = (uint32_t *)op;
+ else
+ {
+ if (sp->tbuflen < npixels)
+ {
+ TIFFErrorExtR(tif, module, "Translation buffer too short");
+ return (0);
+ }
+ tp = (uint32_t *)sp->tbuf;
+ }
+ /* copy to array of uint32_t */
+ bp = (unsigned char *)tif->tif_rawcp;
+ cc = tif->tif_rawcc;
+ for (i = 0; i < npixels && cc >= 3; i++)
+ {
+ tp[i] = bp[0] << 16 | bp[1] << 8 | bp[2];
+ bp += 3;
+ cc -= 3;
+ }
+ tif->tif_rawcp = (uint8_t *)bp;
+ tif->tif_rawcc = cc;
+ if (i != npixels)
+ {
+ TIFFErrorExtR(tif, module,
+ "Not enough data at row %" PRIu32
+ " (short %" TIFF_SSIZE_FORMAT " pixels)",
+ tif->tif_row, npixels - i);
+ return (0);
+ }
+ (*sp->tfunc)(sp, op, npixels);
+ return (1);
+}
+
+/*
+ * Decode a string of 32-bit pixels.
+ */
+static int LogLuvDecode32(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
+{
+ static const char module[] = "LogLuvDecode32";
+ LogLuvState *sp;
+ int shft;
+ tmsize_t i;
+ tmsize_t npixels;
+ unsigned char *bp;
+ uint32_t *tp;
+ uint32_t b;
+ tmsize_t cc;
+ int rc;
+
+ (void)s;
+ assert(s == 0);
+ sp = DecoderState(tif);
+ assert(sp != NULL);
+
+ npixels = occ / sp->pixel_size;
+
+ if (sp->user_datafmt == SGILOGDATAFMT_RAW)
+ tp = (uint32_t *)op;
+ else
+ {
+ if (sp->tbuflen < npixels)
+ {
+ TIFFErrorExtR(tif, module, "Translation buffer too short");
+ return (0);
+ }
+ tp = (uint32_t *)sp->tbuf;
+ }
+ _TIFFmemset((void *)tp, 0, npixels * sizeof(tp[0]));
+
+ bp = (unsigned char *)tif->tif_rawcp;
+ cc = tif->tif_rawcc;
+ /* get each byte string */
+ for (shft = 24; shft >= 0; shft -= 8)
+ {
+ for (i = 0; i < npixels && cc > 0;)
+ {
+ if (*bp >= 128)
+ { /* run */
+ if (cc < 2)
+ break;
+ rc = *bp++ + (2 - 128);
+ b = (uint32_t)*bp++ << shft;
+ cc -= 2;
+ while (rc-- && i < npixels)
+ tp[i++] |= b;
+ }
+ else
+ { /* non-run */
+ rc = *bp++; /* nul is noop */
+ while (--cc && rc-- && i < npixels)
+ tp[i++] |= (uint32_t)*bp++ << shft;
+ }
+ }
+ if (i != npixels)
+ {
+ TIFFErrorExtR(tif, module,
+ "Not enough data at row %" PRIu32
+ " (short %" TIFF_SSIZE_FORMAT " pixels)",
+ tif->tif_row, npixels - i);
+ tif->tif_rawcp = (uint8_t *)bp;
+ tif->tif_rawcc = cc;
+ return (0);
+ }
+ }
+ (*sp->tfunc)(sp, op, npixels);
+ tif->tif_rawcp = (uint8_t *)bp;
+ tif->tif_rawcc = cc;
+ return (1);
+}
+
+/*
+ * Decode a strip of pixels. We break it into rows to
+ * maintain synchrony with the encode algorithm, which
+ * is row by row.
+ */
+static int LogLuvDecodeStrip(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
+{
+ tmsize_t rowlen = TIFFScanlineSize(tif);
+
+ if (rowlen == 0)
+ return 0;
+
+ assert(cc % rowlen == 0);
+ while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s))
+ {
+ bp += rowlen;
+ cc -= rowlen;
+ }
+ return (cc == 0);
+}
+
+/*
+ * Decode a tile of pixels. We break it into rows to
+ * maintain synchrony with the encode algorithm, which
+ * is row by row.
+ */
+static int LogLuvDecodeTile(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
+{
+ tmsize_t rowlen = TIFFTileRowSize(tif);
+
+ if (rowlen == 0)
+ return 0;
+
+ assert(cc % rowlen == 0);
+ while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s))
+ {
+ bp += rowlen;
+ cc -= rowlen;
+ }
+ return (cc == 0);
+}
+
+/*
+ * Encode a row of 16-bit pixels.
+ */
+static int LogL16Encode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
+{
+ static const char module[] = "LogL16Encode";
+ LogLuvState *sp = EncoderState(tif);
+ int shft;
+ tmsize_t i;
+ tmsize_t j;
+ tmsize_t npixels;
+ uint8_t *op;
+ int16_t *tp;
+ int16_t b;
+ tmsize_t occ;
+ int rc = 0, mask;
+ tmsize_t beg;
+
+ (void)s;
+ assert(s == 0);
+ assert(sp != NULL);
+ npixels = cc / sp->pixel_size;
+
+ if (sp->user_datafmt == SGILOGDATAFMT_16BIT)
+ tp = (int16_t *)bp;
+ else
+ {
+ tp = (int16_t *)sp->tbuf;
+ if (sp->tbuflen < npixels)
+ {
+ TIFFErrorExtR(tif, module, "Translation buffer too short");
+ return (0);
+ }
+ (*sp->tfunc)(sp, bp, npixels);
+ }
+ /* compress each byte string */
+ op = tif->tif_rawcp;
+ occ = tif->tif_rawdatasize - tif->tif_rawcc;
+ for (shft = 8; shft >= 0; shft -= 8)
+ {
+ for (i = 0; i < npixels; i += rc)
+ {
+ if (occ < 4)
+ {
+ tif->tif_rawcp = op;
+ tif->tif_rawcc = tif->tif_rawdatasize - occ;
+ if (!TIFFFlushData1(tif))
+ return (0);
+ 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 = (int16_t)(tp[beg] & mask);
+ rc = 1;
+ while (rc < 127 + 2 && beg + rc < npixels &&
+ (tp[beg + rc] & mask) == b)
+ rc++;
+ if (rc >= MINRUN)
+ break; /* long enough */
+ }
+ if (beg - i > 1 && beg - i < MINRUN)
+ {
+ b = (int16_t)(tp[i] & mask); /*check short run */
+ j = i + 1;
+ while ((tp[j++] & mask) == b)
+ if (j == beg)
+ {
+ *op++ = (uint8_t)(128 - 2 + j - i);
+ *op++ = (uint8_t)(b >> shft);
+ occ -= 2;
+ i = beg;
+ break;
+ }
+ }
+ while (i < beg)
+ { /* write out non-run */
+ if ((j = beg - i) > 127)
+ j = 127;
+ if (occ < j + 3)
+ {
+ tif->tif_rawcp = op;
+ tif->tif_rawcc = tif->tif_rawdatasize - occ;
+ if (!TIFFFlushData1(tif))
+ return (0);
+ op = tif->tif_rawcp;
+ occ = tif->tif_rawdatasize - tif->tif_rawcc;
+ }
+ *op++ = (uint8_t)j;
+ occ--;
+ while (j--)
+ {
+ *op++ = (uint8_t)(tp[i++] >> shft & 0xff);
+ occ--;
+ }
+ }
+ if (rc >= MINRUN)
+ { /* write out run */
+ *op++ = (uint8_t)(128 - 2 + rc);
+ *op++ = (uint8_t)(tp[beg] >> shft & 0xff);
+ occ -= 2;
+ }
+ else
+ rc = 0;
+ }
+ }
+ tif->tif_rawcp = op;
+ tif->tif_rawcc = tif->tif_rawdatasize - occ;
+
+ return (1);
+}
+
+/*
+ * Encode a row of 24-bit pixels.
+ */
+static int LogLuvEncode24(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
+{
+ static const char module[] = "LogLuvEncode24";
+ LogLuvState *sp = EncoderState(tif);
+ tmsize_t i;
+ tmsize_t npixels;
+ tmsize_t occ;
+ uint8_t *op;
+ uint32_t *tp;
+
+ (void)s;
+ assert(s == 0);
+ assert(sp != NULL);
+ npixels = cc / sp->pixel_size;
+
+ if (sp->user_datafmt == SGILOGDATAFMT_RAW)
+ tp = (uint32_t *)bp;
+ else
+ {
+ tp = (uint32_t *)sp->tbuf;
+ if (sp->tbuflen < npixels)
+ {
+ TIFFErrorExtR(tif, module, "Translation buffer too short");
+ return (0);
+ }
+ (*sp->tfunc)(sp, bp, npixels);
+ }
+ /* write out encoded pixels */
+ op = tif->tif_rawcp;
+ occ = tif->tif_rawdatasize - tif->tif_rawcc;
+ for (i = npixels; i--;)
+ {
+ if (occ < 3)
+ {
+ tif->tif_rawcp = op;
+ tif->tif_rawcc = tif->tif_rawdatasize - occ;
+ if (!TIFFFlushData1(tif))
+ return (0);
+ op = tif->tif_rawcp;
+ occ = tif->tif_rawdatasize - tif->tif_rawcc;
+ }
+ *op++ = (uint8_t)(*tp >> 16);
+ *op++ = (uint8_t)(*tp >> 8 & 0xff);
+ *op++ = (uint8_t)(*tp++ & 0xff);
+ occ -= 3;
+ }
+ tif->tif_rawcp = op;
+ tif->tif_rawcc = tif->tif_rawdatasize - occ;
+
+ return (1);
+}
+
+/*
+ * Encode a row of 32-bit pixels.
+ */
+static int LogLuvEncode32(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
+{
+ static const char module[] = "LogLuvEncode32";
+ LogLuvState *sp = EncoderState(tif);
+ int shft;
+ tmsize_t i;
+ tmsize_t j;
+ tmsize_t npixels;
+ uint8_t *op;
+ uint32_t *tp;
+ uint32_t b;
+ tmsize_t occ;
+ int rc = 0;
+ tmsize_t beg;
+
+ (void)s;
+ assert(s == 0);
+ assert(sp != NULL);
+
+ npixels = cc / sp->pixel_size;
+
+ if (sp->user_datafmt == SGILOGDATAFMT_RAW)
+ tp = (uint32_t *)bp;
+ else
+ {
+ tp = (uint32_t *)sp->tbuf;
+ if (sp->tbuflen < npixels)
+ {
+ TIFFErrorExtR(tif, module, "Translation buffer too short");
+ return (0);
+ }
+ (*sp->tfunc)(sp, bp, npixels);
+ }
+ /* compress each byte string */
+ 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;
+ tif->tif_rawcc = tif->tif_rawdatasize - occ;
+ if (!TIFFFlushData1(tif))
+ return (0);
+ op = tif->tif_rawcp;
+ occ = tif->tif_rawdatasize - tif->tif_rawcc;
+ }
+ for (beg = i; beg < npixels; beg += rc)
+ {
+ b = tp[beg] & mask;
+ rc = 1;
+ while (rc < 127 + 2 && beg + rc < npixels &&
+ (tp[beg + rc] & mask) == b)
+ rc++;
+ if (rc >= MINRUN)
+ break; /* long enough */
+ }
+ if (beg - i > 1 && beg - i < MINRUN)
+ {
+ b = tp[i] & mask; /* check short run */
+ j = i + 1;
+ while ((tp[j++] & mask) == b)
+ if (j == beg)
+ {
+ *op++ = (uint8_t)(128 - 2 + j - i);
+ *op++ = (uint8_t)(b >> shft);
+ occ -= 2;
+ i = beg;
+ break;
+ }
+ }
+ while (i < beg)
+ { /* write out non-run */
+ if ((j = beg - i) > 127)
+ j = 127;
+ if (occ < j + 3)
+ {
+ tif->tif_rawcp = op;
+ tif->tif_rawcc = tif->tif_rawdatasize - occ;
+ if (!TIFFFlushData1(tif))
+ return (0);
+ op = tif->tif_rawcp;
+ occ = tif->tif_rawdatasize - tif->tif_rawcc;
+ }
+ *op++ = (uint8_t)j;
+ occ--;
+ while (j--)
+ {
+ *op++ = (uint8_t)(tp[i++] >> shft & 0xff);
+ occ--;
+ }
+ }
+ if (rc >= MINRUN)
+ { /* write out run */
+ *op++ = (uint8_t)(128 - 2 + rc);
+ *op++ = (uint8_t)(tp[beg] >> shft & 0xff);
+ occ -= 2;
+ }
+ else
+ rc = 0;
+ }
+ }
+ tif->tif_rawcp = op;
+ tif->tif_rawcc = tif->tif_rawdatasize - occ;
+
+ return (1);
+}
+
+/*
+ * Encode a strip of pixels. We break it into rows to
+ * avoid encoding runs across row boundaries.
+ */
+static int LogLuvEncodeStrip(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
+{
+ tmsize_t rowlen = TIFFScanlineSize(tif);
+
+ if (rowlen == 0)
+ return 0;
+
+ assert(cc % rowlen == 0);
+ while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1)
+ {
+ bp += rowlen;
+ cc -= rowlen;
+ }
+ return (cc == 0);
+}
+
+/*
+ * Encode a tile of pixels. We break it into rows to
+ * avoid encoding runs across row boundaries.
+ */
+static int LogLuvEncodeTile(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
+{
+ tmsize_t rowlen = TIFFTileRowSize(tif);
+
+ if (rowlen == 0)
+ return 0;
+
+ assert(cc % rowlen == 0);
+ while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1)
+ {
+ bp += rowlen;
+ cc -= rowlen;
+ }
+ return (cc == 0);
+}
+
+/*
+ * Encode/Decode functions for converting to and from user formats.
+ */
+
+#include "uvcode.h"
+
+#ifndef UVSCALE
+#define U_NEU 0.210526316
+#define V_NEU 0.473684211
+#define UVSCALE 410.
+#endif
+
+#ifndef M_LN2
+#define M_LN2 0.69314718055994530942
+#endif
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+#undef log2 /* Conflict with C'99 function */
+#define log2(x) ((1. / M_LN2) * log(x))
+#undef exp2 /* Conflict with C'99 function */
+#define exp2(x) exp(M_LN2 *(x))
+
+static int tiff_itrunc(double x, int m)
+{
+ if (m == SGILOGENCODE_NODITHER)
+ return (int)x;
+ /* Silence CoverityScan warning about bad crypto function */
+ /* coverity[dont_call] */
+ return (int)(x + rand() * (1. / RAND_MAX) - .5);
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+ double
+ LogL16toY(int p16) /* compute luminance from 16-bit LogL */
+{
+ int Le = p16 & 0x7fff;
+ double Y;
+
+ if (!Le)
+ return (0.);
+ Y = exp(M_LN2 / 256. * (Le + .5) - M_LN2 * 64.);
+ return (!(p16 & 0x8000) ? Y : -Y);
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+ int
+ LogL16fromY(double Y, int em) /* get 16-bit LogL from Y */
+{
+ if (Y >= 1.8371976e19)
+ return (0x7fff);
+ if (Y <= -1.8371976e19)
+ return (0xffff);
+ if (Y > 5.4136769e-20)
+ return tiff_itrunc(256. * (log2(Y) + 64.), em);
+ if (Y < -5.4136769e-20)
+ return (~0x7fff | tiff_itrunc(256. * (log2(-Y) + 64.), em));
+ return (0);
+}
+
+static void L16toY(LogLuvState *sp, uint8_t *op, tmsize_t n)
+{
+ int16_t *l16 = (int16_t *)sp->tbuf;
+ float *yp = (float *)op;
+
+ while (n-- > 0)
+ *yp++ = (float)LogL16toY(*l16++);
+}
+
+static void L16toGry(LogLuvState *sp, uint8_t *op, tmsize_t n)
+{
+ int16_t *l16 = (int16_t *)sp->tbuf;
+ uint8_t *gp = (uint8_t *)op;
+
+ while (n-- > 0)
+ {
+ double Y = LogL16toY(*l16++);
+ *gp++ = (uint8_t)((Y <= 0.) ? 0
+ : (Y >= 1.) ? 255
+ : (int)(256. * sqrt(Y)));
+ }
+}
+
+static void L16fromY(LogLuvState *sp, uint8_t *op, tmsize_t n)
+{
+ int16_t *l16 = (int16_t *)sp->tbuf;
+ float *yp = (float *)op;
+
+ while (n-- > 0)
+ *l16++ = (int16_t)(LogL16fromY(*yp++, sp->encode_meth));
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+ void
+ XYZtoRGB24(float *xyz, uint8_t *rgb)
+{
+ double r, g, b;
+ /* assume CCIR-709 primaries */
+ r = 2.690 * xyz[0] + -1.276 * xyz[1] + -0.414 * xyz[2];
+ g = -1.022 * xyz[0] + 1.978 * xyz[1] + 0.044 * xyz[2];
+ b = 0.061 * xyz[0] + -0.224 * xyz[1] + 1.163 * xyz[2];
+ /* assume 2.0 gamma for speed */
+ /* could use integer sqrt approx., but this is probably faster */
+ rgb[0] = (uint8_t)((r <= 0.) ? 0 : (r >= 1.) ? 255 : (int)(256. * sqrt(r)));
+ rgb[1] = (uint8_t)((g <= 0.) ? 0 : (g >= 1.) ? 255 : (int)(256. * sqrt(g)));
+ rgb[2] = (uint8_t)((b <= 0.) ? 0 : (b >= 1.) ? 255 : (int)(256. * sqrt(b)));
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+ double
+ LogL10toY(int p10) /* compute luminance from 10-bit LogL */
+{
+ if (p10 == 0)
+ return (0.);
+ return (exp(M_LN2 / 64. * (p10 + .5) - M_LN2 * 12.));
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+ int
+ LogL10fromY(double Y, int em) /* get 10-bit LogL from Y */
+{
+ if (Y >= 15.742)
+ return (0x3ff);
+ else if (Y <= .00024283)
+ return (0);
+ else
+ return tiff_itrunc(64. * (log2(Y) + 12.), em);
+}
+
+#define NANGLES 100
+#define uv2ang(u, v) \
+ ((NANGLES * .499999999 / M_PI) * atan2((v)-V_NEU, (u)-U_NEU) + .5 * NANGLES)
+
+static int oog_encode(double u, double v) /* encode out-of-gamut chroma */
+{
+ static int oog_table[NANGLES];
+ static int initialized = 0;
+ register int i;
+
+ if (!initialized)
+ { /* set up perimeter table */
+ double eps[NANGLES], ua, va, ang, epsa;
+ int ui, vi, ustep;
+ for (i = NANGLES; i--;)
+ eps[i] = 2.;
+ for (vi = UV_NVS; vi--;)
+ {
+ va = UV_VSTART + (vi + .5) * UV_SQSIZ;
+ ustep = uv_row[vi].nus - 1;
+ if (vi == UV_NVS - 1 || vi == 0 || ustep <= 0)
+ ustep = 1;
+ for (ui = uv_row[vi].nus - 1; ui >= 0; ui -= ustep)
+ {
+ ua = uv_row[vi].ustart + (ui + .5) * UV_SQSIZ;
+ ang = uv2ang(ua, va);
+ i = (int)ang;
+ epsa = fabs(ang - (i + .5));
+ if (epsa < eps[i])
+ {
+ oog_table[i] = uv_row[vi].ncum + ui;
+ eps[i] = epsa;
+ }
+ }
+ }
+ for (i = NANGLES; i--;) /* fill any holes */
+ if (eps[i] > 1.5)
+ {
+ int i1, i2;
+ for (i1 = 1; i1 < NANGLES / 2; i1++)
+ if (eps[(i + i1) % NANGLES] < 1.5)
+ break;
+ for (i2 = 1; i2 < NANGLES / 2; i2++)
+ if (eps[(i + NANGLES - i2) % NANGLES] < 1.5)
+ break;
+ if (i1 < i2)
+ oog_table[i] = oog_table[(i + i1) % NANGLES];
+ else
+ oog_table[i] = oog_table[(i + NANGLES - i2) % NANGLES];
+ }
+ initialized = 1;
+ }
+ i = (int)uv2ang(u, v); /* look up hue angle */
+ return (oog_table[i]);
+}
+
+#undef uv2ang
+#undef NANGLES
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+ int
+ uv_encode(double u, double v, int em) /* encode (u',v') coordinates */
+{
+ register int vi, ui;
+
+ /* check for NaN */
+ if (u != u || v != v)
+ {
+ u = U_NEU;
+ v = V_NEU;
+ }
+
+ if (v < UV_VSTART)
+ return oog_encode(u, v);
+ vi = tiff_itrunc((v - UV_VSTART) * (1. / UV_SQSIZ), em);
+ if (vi >= UV_NVS)
+ return oog_encode(u, v);
+ if (u < uv_row[vi].ustart)
+ return oog_encode(u, v);
+ ui = tiff_itrunc((u - uv_row[vi].ustart) * (1. / UV_SQSIZ), em);
+ if (ui >= uv_row[vi].nus)
+ return oog_encode(u, v);
+
+ return (uv_row[vi].ncum + ui);
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+ int
+ uv_decode(double *up, double *vp, int c) /* decode (u',v') index */
+{
+ int upper, lower;
+ register int ui, vi;
+
+ if (c < 0 || c >= UV_NDIVS)
+ return (-1);
+ lower = 0; /* binary search */
+ upper = UV_NVS;
+ while (upper - lower > 1)
+ {
+ vi = (lower + upper) >> 1;
+ ui = c - uv_row[vi].ncum;
+ if (ui > 0)
+ lower = vi;
+ else if (ui < 0)
+ upper = vi;
+ else
+ {
+ lower = vi;
+ break;
+ }
+ }
+ vi = lower;
+ ui = c - uv_row[vi].ncum;
+ *up = uv_row[vi].ustart + (ui + .5) * UV_SQSIZ;
+ *vp = UV_VSTART + (vi + .5) * UV_SQSIZ;
+ return (0);
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+ void
+ LogLuv24toXYZ(uint32_t p, float *XYZ)
+{
+ int Ce;
+ double L, u, v, s, x, y;
+ /* decode luminance */
+ L = LogL10toY(p >> 14 & 0x3ff);
+ if (L <= 0.)
+ {
+ XYZ[0] = XYZ[1] = XYZ[2] = 0.;
+ return;
+ }
+ /* decode color */
+ Ce = p & 0x3fff;
+ if (uv_decode(&u, &v, Ce) < 0)
+ {
+ u = U_NEU;
+ v = V_NEU;
+ }
+ s = 1. / (6. * u - 16. * v + 12.);
+ x = 9. * u * s;
+ y = 4. * v * s;
+ /* convert to XYZ */
+ XYZ[0] = (float)(x / y * L);
+ XYZ[1] = (float)L;
+ XYZ[2] = (float)((1. - x - y) / y * L);
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+ uint32_t
+ LogLuv24fromXYZ(float *XYZ, int em)
+{
+ int Le, Ce;
+ double u, v, s;
+ /* encode luminance */
+ Le = LogL10fromY(XYZ[1], em);
+ /* encode color */
+ s = XYZ[0] + 15. * XYZ[1] + 3. * XYZ[2];
+ if (!Le || s <= 0.)
+ {
+ u = U_NEU;
+ v = V_NEU;
+ }
+ else
+ {
+ u = 4. * XYZ[0] / s;
+ v = 9. * XYZ[1] / s;
+ }
+ Ce = uv_encode(u, v, em);
+ if (Ce < 0) /* never happens */
+ Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER);
+ /* combine encodings */
+ return (Le << 14 | Ce);
+}
+
+static void Luv24toXYZ(LogLuvState *sp, uint8_t *op, tmsize_t n)
+{
+ uint32_t *luv = (uint32_t *)sp->tbuf;
+ float *xyz = (float *)op;
+
+ while (n-- > 0)
+ {
+ LogLuv24toXYZ(*luv, xyz);
+ xyz += 3;
+ luv++;
+ }
+}
+
+static void Luv24toLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n)
+{
+ uint32_t *luv = (uint32_t *)sp->tbuf;
+ int16_t *luv3 = (int16_t *)op;
+
+ while (n-- > 0)
+ {
+ double u, v;
+
+ *luv3++ = (int16_t)((*luv >> 12 & 0xffd) + 13314);
+ if (uv_decode(&u, &v, *luv & 0x3fff) < 0)
+ {
+ u = U_NEU;
+ v = V_NEU;
+ }
+ *luv3++ = (int16_t)(u * (1L << 15));
+ *luv3++ = (int16_t)(v * (1L << 15));
+ luv++;
+ }
+}
+
+static void Luv24toRGB(LogLuvState *sp, uint8_t *op, tmsize_t n)
+{
+ uint32_t *luv = (uint32_t *)sp->tbuf;
+ uint8_t *rgb = (uint8_t *)op;
+
+ while (n-- > 0)
+ {
+ float xyz[3];
+
+ LogLuv24toXYZ(*luv++, xyz);
+ XYZtoRGB24(xyz, rgb);
+ rgb += 3;
+ }
+}
+
+static void Luv24fromXYZ(LogLuvState *sp, uint8_t *op, tmsize_t n)
+{
+ uint32_t *luv = (uint32_t *)sp->tbuf;
+ float *xyz = (float *)op;
+
+ while (n-- > 0)
+ {
+ *luv++ = LogLuv24fromXYZ(xyz, sp->encode_meth);
+ xyz += 3;
+ }
+}
+
+static void Luv24fromLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n)
+{
+ uint32_t *luv = (uint32_t *)sp->tbuf;
+ int16_t *luv3 = (int16_t *)op;
+
+ while (n-- > 0)
+ {
+ int Le, Ce;
+
+ if (luv3[0] <= 0)
+ Le = 0;
+ else if (luv3[0] >= (1 << 12) + 3314)
+ Le = (1 << 10) - 1;
+ else if (sp->encode_meth == SGILOGENCODE_NODITHER)
+ Le = (luv3[0] - 3314) >> 2;
+ else
+ Le = tiff_itrunc(.25 * (luv3[0] - 3314.), sp->encode_meth);
+
+ Ce = uv_encode((luv3[1] + .5) / (1 << 15), (luv3[2] + .5) / (1 << 15),
+ sp->encode_meth);
+ if (Ce < 0) /* never happens */
+ Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER);
+ *luv++ = (uint32_t)Le << 14 | Ce;
+ luv3 += 3;
+ }
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+ void
+ LogLuv32toXYZ(uint32_t p, float *XYZ)
+{
+ double L, u, v, s, x, y;
+ /* decode luminance */
+ L = LogL16toY((int)p >> 16);
+ if (L <= 0.)
+ {
+ XYZ[0] = XYZ[1] = XYZ[2] = 0.;
+ return;
+ }
+ /* decode color */
+ u = 1. / UVSCALE * ((p >> 8 & 0xff) + .5);
+ v = 1. / UVSCALE * ((p & 0xff) + .5);
+ s = 1. / (6. * u - 16. * v + 12.);
+ x = 9. * u * s;
+ y = 4. * v * s;
+ /* convert to XYZ */
+ XYZ[0] = (float)(x / y * L);
+ XYZ[1] = (float)L;
+ XYZ[2] = (float)((1. - x - y) / y * L);
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+ uint32_t
+ LogLuv32fromXYZ(float *XYZ, int em)
+{
+ unsigned int Le, ue, ve;
+ double u, v, s;
+ /* encode luminance */
+ Le = (unsigned int)LogL16fromY(XYZ[1], em);
+ /* encode color */
+ s = XYZ[0] + 15. * XYZ[1] + 3. * XYZ[2];
+ if (!Le || s <= 0.)
+ {
+ u = U_NEU;
+ v = V_NEU;
+ }
+ else
+ {
+ u = 4. * XYZ[0] / s;
+ v = 9. * XYZ[1] / s;
+ }
+ if (u <= 0.)
+ ue = 0;
+ else
+ ue = tiff_itrunc(UVSCALE * u, em);
+ if (ue > 255)
+ ue = 255;
+ if (v <= 0.)
+ ve = 0;
+ else
+ ve = tiff_itrunc(UVSCALE * v, em);
+ if (ve > 255)
+ ve = 255;
+ /* combine encodings */
+ return (Le << 16 | ue << 8 | ve);
+}
+
+static void Luv32toXYZ(LogLuvState *sp, uint8_t *op, tmsize_t n)
+{
+ uint32_t *luv = (uint32_t *)sp->tbuf;
+ float *xyz = (float *)op;
+
+ while (n-- > 0)
+ {
+ LogLuv32toXYZ(*luv++, xyz);
+ xyz += 3;
+ }
+}
+
+static void Luv32toLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n)
+{
+ uint32_t *luv = (uint32_t *)sp->tbuf;
+ int16_t *luv3 = (int16_t *)op;
+
+ while (n-- > 0)
+ {
+ double u, v;
+
+ *luv3++ = (int16_t)(*luv >> 16);
+ u = 1. / UVSCALE * ((*luv >> 8 & 0xff) + .5);
+ v = 1. / UVSCALE * ((*luv & 0xff) + .5);
+ *luv3++ = (int16_t)(u * (1L << 15));
+ *luv3++ = (int16_t)(v * (1L << 15));
+ luv++;
+ }
+}
+
+static void Luv32toRGB(LogLuvState *sp, uint8_t *op, tmsize_t n)
+{
+ uint32_t *luv = (uint32_t *)sp->tbuf;
+ uint8_t *rgb = (uint8_t *)op;
+
+ while (n-- > 0)
+ {
+ float xyz[3];
+
+ LogLuv32toXYZ(*luv++, xyz);
+ XYZtoRGB24(xyz, rgb);
+ rgb += 3;
+ }
+}
+
+static void Luv32fromXYZ(LogLuvState *sp, uint8_t *op, tmsize_t n)
+{
+ uint32_t *luv = (uint32_t *)sp->tbuf;
+ float *xyz = (float *)op;
+
+ while (n-- > 0)
+ {
+ *luv++ = LogLuv32fromXYZ(xyz, sp->encode_meth);
+ xyz += 3;
+ }
+}
+
+static void Luv32fromLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n)
+{
+ uint32_t *luv = (uint32_t *)sp->tbuf;
+ int16_t *luv3 = (int16_t *)op;
+
+ if (sp->encode_meth == SGILOGENCODE_NODITHER)
+ {
+ while (n-- > 0)
+ {
+ *luv++ = (uint32_t)luv3[0] << 16 |
+ (luv3[1] * (uint32_t)(UVSCALE + .5) >> 7 & 0xff00) |
+ (luv3[2] * (uint32_t)(UVSCALE + .5) >> 15 & 0xff);
+ luv3 += 3;
+ }
+ return;
+ }
+ while (n-- > 0)
+ {
+ *luv++ =
+ (uint32_t)luv3[0] << 16 |
+ (tiff_itrunc(luv3[1] * (UVSCALE / (1 << 15)), sp->encode_meth)
+ << 8 &
+ 0xff00) |
+ (tiff_itrunc(luv3[2] * (UVSCALE / (1 << 15)), sp->encode_meth) &
+ 0xff);
+ luv3 += 3;
+ }
+}
+
+static void _logLuvNop(LogLuvState *sp, uint8_t *op, tmsize_t n)
+{
+ (void)sp;
+ (void)op;
+ (void)n;
+}
+
+static int LogL16GuessDataFmt(TIFFDirectory *td)
+{
+#define PACK(s, b, f) (((b) << 6) | ((s) << 3) | (f))
+ switch (
+ PACK(td->td_samplesperpixel, td->td_bitspersample, td->td_sampleformat))
+ {
+ case PACK(1, 32, SAMPLEFORMAT_IEEEFP):
+ return (SGILOGDATAFMT_FLOAT);
+ case PACK(1, 16, SAMPLEFORMAT_VOID):
+ case PACK(1, 16, SAMPLEFORMAT_INT):
+ case PACK(1, 16, SAMPLEFORMAT_UINT):
+ return (SGILOGDATAFMT_16BIT);
+ case PACK(1, 8, SAMPLEFORMAT_VOID):
+ case PACK(1, 8, SAMPLEFORMAT_UINT):
+ return (SGILOGDATAFMT_8BIT);
+ }
+#undef PACK
+ return (SGILOGDATAFMT_UNKNOWN);
+}
+
+static tmsize_t multiply_ms(tmsize_t m1, tmsize_t m2)
+{
+ return _TIFFMultiplySSize(NULL, m1, m2, NULL);
+}
+
+static int LogL16InitState(TIFF *tif)
+{
+ static const char module[] = "LogL16InitState";
+ TIFFDirectory *td = &tif->tif_dir;
+ LogLuvState *sp = DecoderState(tif);
+
+ assert(sp != NULL);
+ assert(td->td_photometric == PHOTOMETRIC_LOGL);
+
+ if (td->td_samplesperpixel != 1)
+ {
+ TIFFErrorExtR(tif, module,
+ "Sorry, can not handle LogL image with %s=%" PRIu16,
+ "Samples/pixel", td->td_samplesperpixel);
+ return 0;
+ }
+
+ /* for some reason, we can't do this in TIFFInitLogL16 */
+ if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN)
+ sp->user_datafmt = LogL16GuessDataFmt(td);
+ switch (sp->user_datafmt)
+ {
+ case SGILOGDATAFMT_FLOAT:
+ sp->pixel_size = sizeof(float);
+ break;
+ case SGILOGDATAFMT_16BIT:
+ sp->pixel_size = sizeof(int16_t);
+ break;
+ case SGILOGDATAFMT_8BIT:
+ sp->pixel_size = sizeof(uint8_t);
+ break;
+ default:
+ TIFFErrorExtR(tif, module,
+ "No support for converting user data format to LogL");
+ return (0);
+ }
+ if (isTiled(tif))
+ sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength);
+ else if (td->td_rowsperstrip < td->td_imagelength)
+ sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip);
+ else
+ sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_imagelength);
+ if (multiply_ms(sp->tbuflen, sizeof(int16_t)) == 0 ||
+ (sp->tbuf = (uint8_t *)_TIFFmallocExt(
+ tif, sp->tbuflen * sizeof(int16_t))) == NULL)
+ {
+ TIFFErrorExtR(tif, module, "No space for SGILog translation buffer");
+ return (0);
+ }
+ return (1);
+}
+
+static int LogLuvGuessDataFmt(TIFFDirectory *td)
+{
+ int guess;
+
+ /*
+ * If the user didn't tell us their datafmt,
+ * take our best guess from the bitspersample.
+ */
+#define PACK(a, b) (((a) << 3) | (b))
+ switch (PACK(td->td_bitspersample, td->td_sampleformat))
+ {
+ case PACK(32, SAMPLEFORMAT_IEEEFP):
+ guess = SGILOGDATAFMT_FLOAT;
+ break;
+ case PACK(32, SAMPLEFORMAT_VOID):
+ case PACK(32, SAMPLEFORMAT_UINT):
+ case PACK(32, SAMPLEFORMAT_INT):
+ guess = SGILOGDATAFMT_RAW;
+ break;
+ case PACK(16, SAMPLEFORMAT_VOID):
+ case PACK(16, SAMPLEFORMAT_INT):
+ case PACK(16, SAMPLEFORMAT_UINT):
+ guess = SGILOGDATAFMT_16BIT;
+ break;
+ case PACK(8, SAMPLEFORMAT_VOID):
+ case PACK(8, SAMPLEFORMAT_UINT):
+ guess = SGILOGDATAFMT_8BIT;
+ break;
+ default:
+ guess = SGILOGDATAFMT_UNKNOWN;
+ break;
+#undef PACK
+ }
+ /*
+ * Double-check samples per pixel.
+ */
+ switch (td->td_samplesperpixel)
+ {
+ case 1:
+ if (guess != SGILOGDATAFMT_RAW)
+ guess = SGILOGDATAFMT_UNKNOWN;
+ break;
+ case 3:
+ if (guess == SGILOGDATAFMT_RAW)
+ guess = SGILOGDATAFMT_UNKNOWN;
+ break;
+ default:
+ guess = SGILOGDATAFMT_UNKNOWN;
+ break;
+ }
+ return (guess);
+}
+
+static int LogLuvInitState(TIFF *tif)
+{
+ static const char module[] = "LogLuvInitState";
+ TIFFDirectory *td = &tif->tif_dir;
+ LogLuvState *sp = DecoderState(tif);
+
+ assert(sp != NULL);
+ assert(td->td_photometric == PHOTOMETRIC_LOGLUV);
+
+ /* for some reason, we can't do this in TIFFInitLogLuv */
+ if (td->td_planarconfig != PLANARCONFIG_CONTIG)
+ {
+ TIFFErrorExtR(tif, module,
+ "SGILog compression cannot handle non-contiguous data");
+ return (0);
+ }
+ if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN)
+ sp->user_datafmt = LogLuvGuessDataFmt(td);
+ switch (sp->user_datafmt)
+ {
+ case SGILOGDATAFMT_FLOAT:
+ sp->pixel_size = 3 * sizeof(float);
+ break;
+ case SGILOGDATAFMT_16BIT:
+ sp->pixel_size = 3 * sizeof(int16_t);
+ break;
+ case SGILOGDATAFMT_RAW:
+ sp->pixel_size = sizeof(uint32_t);
+ break;
+ case SGILOGDATAFMT_8BIT:
+ sp->pixel_size = 3 * sizeof(uint8_t);
+ break;
+ default:
+ TIFFErrorExtR(
+ tif, module,
+ "No support for converting user data format to LogLuv");
+ return (0);
+ }
+ if (isTiled(tif))
+ sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength);
+ else if (td->td_rowsperstrip < td->td_imagelength)
+ sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip);
+ else
+ sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_imagelength);
+ if (multiply_ms(sp->tbuflen, sizeof(uint32_t)) == 0 ||
+ (sp->tbuf = (uint8_t *)_TIFFmallocExt(
+ tif, sp->tbuflen * sizeof(uint32_t))) == NULL)
+ {
+ TIFFErrorExtR(tif, module, "No space for SGILog translation buffer");
+ return (0);
+ }
+ return (1);
+}
+
+static int LogLuvFixupTags(TIFF *tif)
+{
+ (void)tif;
+ return (1);
+}
+
+static int LogLuvSetupDecode(TIFF *tif)
+{
+ static const char module[] = "LogLuvSetupDecode";
+ LogLuvState *sp = DecoderState(tif);
+ TIFFDirectory *td = &tif->tif_dir;
+
+ tif->tif_postdecode = _TIFFNoPostDecode;
+ switch (td->td_photometric)
+ {
+ case PHOTOMETRIC_LOGLUV:
+ if (!LogLuvInitState(tif))
+ break;
+ if (td->td_compression == COMPRESSION_SGILOG24)
+ {
+ tif->tif_decoderow = LogLuvDecode24;
+ switch (sp->user_datafmt)
+ {
+ case SGILOGDATAFMT_FLOAT:
+ sp->tfunc = Luv24toXYZ;
+ break;
+ case SGILOGDATAFMT_16BIT:
+ sp->tfunc = Luv24toLuv48;
+ break;
+ case SGILOGDATAFMT_8BIT:
+ sp->tfunc = Luv24toRGB;
+ break;
+ }
+ }
+ else
+ {
+ tif->tif_decoderow = LogLuvDecode32;
+ switch (sp->user_datafmt)
+ {
+ case SGILOGDATAFMT_FLOAT:
+ sp->tfunc = Luv32toXYZ;
+ break;
+ case SGILOGDATAFMT_16BIT:
+ sp->tfunc = Luv32toLuv48;
+ break;
+ case SGILOGDATAFMT_8BIT:
+ sp->tfunc = Luv32toRGB;
+ break;
+ }
+ }
+ return (1);
+ case PHOTOMETRIC_LOGL:
+ if (!LogL16InitState(tif))
+ break;
+ tif->tif_decoderow = LogL16Decode;
+ switch (sp->user_datafmt)
+ {
+ case SGILOGDATAFMT_FLOAT:
+ sp->tfunc = L16toY;
+ break;
+ case SGILOGDATAFMT_8BIT:
+ sp->tfunc = L16toGry;
+ break;
+ }
+ return (1);
+ default:
+ TIFFErrorExtR(tif, module,
+ "Inappropriate photometric interpretation %" PRIu16
+ " for SGILog compression; %s",
+ td->td_photometric, "must be either LogLUV or LogL");
+ break;
+ }
+ return (0);
+}
+
+static int LogLuvSetupEncode(TIFF *tif)
+{
+ static const char module[] = "LogLuvSetupEncode";
+ LogLuvState *sp = EncoderState(tif);
+ TIFFDirectory *td = &tif->tif_dir;
+
+ switch (td->td_photometric)
+ {
+ case PHOTOMETRIC_LOGLUV:
+ if (!LogLuvInitState(tif))
+ return (0);
+ if (td->td_compression == COMPRESSION_SGILOG24)
+ {
+ tif->tif_encoderow = LogLuvEncode24;
+ switch (sp->user_datafmt)
+ {
+ case SGILOGDATAFMT_FLOAT:
+ sp->tfunc = Luv24fromXYZ;
+ break;
+ case SGILOGDATAFMT_16BIT:
+ sp->tfunc = Luv24fromLuv48;
+ break;
+ case SGILOGDATAFMT_RAW:
+ break;
+ default:
+ goto notsupported;
+ }
+ }
+ else
+ {
+ tif->tif_encoderow = LogLuvEncode32;
+ switch (sp->user_datafmt)
+ {
+ case SGILOGDATAFMT_FLOAT:
+ sp->tfunc = Luv32fromXYZ;
+ break;
+ case SGILOGDATAFMT_16BIT:
+ sp->tfunc = Luv32fromLuv48;
+ break;
+ case SGILOGDATAFMT_RAW:
+ break;
+ default:
+ goto notsupported;
+ }
+ }
+ break;
+ case PHOTOMETRIC_LOGL:
+ if (!LogL16InitState(tif))
+ return (0);
+ tif->tif_encoderow = LogL16Encode;
+ switch (sp->user_datafmt)
+ {
+ case SGILOGDATAFMT_FLOAT:
+ sp->tfunc = L16fromY;
+ break;
+ case SGILOGDATAFMT_16BIT:
+ break;
+ default:
+ goto notsupported;
+ }
+ break;
+ default:
+ TIFFErrorExtR(tif, module,
+ "Inappropriate photometric interpretation %" PRIu16
+ " for SGILog compression; %s",
+ td->td_photometric, "must be either LogLUV or LogL");
+ return (0);
+ }
+ sp->encoder_state = 1;
+ return (1);
+notsupported:
+ TIFFErrorExtR(tif, module,
+ "SGILog compression supported only for %s, or raw data",
+ td->td_photometric == PHOTOMETRIC_LOGL ? "Y, L" : "XYZ, Luv");
+ return (0);
+}
+
+static void LogLuvClose(TIFF *tif)
+{
+ LogLuvState *sp = (LogLuvState *)tif->tif_data;
+ TIFFDirectory *td = &tif->tif_dir;
+
+ assert(sp != 0);
+ /*
+ * For consistency, we always want to write out the same
+ * bitspersample and sampleformat for our TIFF file,
+ * regardless of the data format being used by the application.
+ * Since this routine is called after tags have been set but
+ * before they have been recorded in the file, we reset them here.
+ * Note: this is really a nasty approach. See PixarLogClose
+ */
+ if (sp->encoder_state)
+ {
+ /* See PixarLogClose. Might avoid issues with tags whose size depends
+ * on those below, but not completely sure this is enough. */
+ td->td_samplesperpixel =
+ (td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3;
+ td->td_bitspersample = 16;
+ td->td_sampleformat = SAMPLEFORMAT_INT;
+ }
+}
+
+static void LogLuvCleanup(TIFF *tif)
+{
+ LogLuvState *sp = (LogLuvState *)tif->tif_data;
+
+ assert(sp != 0);
+
+ tif->tif_tagmethods.vgetfield = sp->vgetparent;
+ tif->tif_tagmethods.vsetfield = sp->vsetparent;
+
+ if (sp->tbuf)
+ _TIFFfreeExt(tif, sp->tbuf);
+ _TIFFfreeExt(tif, sp);
+ tif->tif_data = NULL;
+
+ _TIFFSetDefaultCompressionState(tif);
+}
+
+static int LogLuvVSetField(TIFF *tif, uint32_t tag, va_list ap)
+{
+ static const char module[] = "LogLuvVSetField";
+ LogLuvState *sp = DecoderState(tif);
+ int bps, fmt;
+
+ switch (tag)
+ {
+ case TIFFTAG_SGILOGDATAFMT:
+ sp->user_datafmt = (int)va_arg(ap, int);
+ /*
+ * Tweak the TIFF header so that the rest of libtiff knows what
+ * size of data will be passed between app and library, and
+ * assume that the app knows what it is doing and is not
+ * confused by these header manipulations...
+ */
+ switch (sp->user_datafmt)
+ {
+ case SGILOGDATAFMT_FLOAT:
+ bps = 32;
+ fmt = SAMPLEFORMAT_IEEEFP;
+ break;
+ case SGILOGDATAFMT_16BIT:
+ bps = 16;
+ fmt = SAMPLEFORMAT_INT;
+ break;
+ case SGILOGDATAFMT_RAW:
+ bps = 32;
+ fmt = SAMPLEFORMAT_UINT;
+ TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
+ break;
+ case SGILOGDATAFMT_8BIT:
+ bps = 8;
+ fmt = SAMPLEFORMAT_UINT;
+ break;
+ default:
+ TIFFErrorExtR(
+ tif, tif->tif_name,
+ "Unknown data format %d for LogLuv compression",
+ sp->user_datafmt);
+ return (0);
+ }
+ TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
+ TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, fmt);
+ /*
+ * Must recalculate sizes should bits/sample change.
+ */
+ tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)-1;
+ tif->tif_scanlinesize = TIFFScanlineSize(tif);
+ return (1);
+ case TIFFTAG_SGILOGENCODE:
+ sp->encode_meth = (int)va_arg(ap, int);
+ if (sp->encode_meth != SGILOGENCODE_NODITHER &&
+ sp->encode_meth != SGILOGENCODE_RANDITHER)
+ {
+ TIFFErrorExtR(tif, module,
+ "Unknown encoding %d for LogLuv compression",
+ sp->encode_meth);
+ return (0);
+ }
+ return (1);
+ default:
+ return (*sp->vsetparent)(tif, tag, ap);
+ }
+}
+
+static int LogLuvVGetField(TIFF *tif, uint32_t tag, va_list ap)
+{
+ LogLuvState *sp = (LogLuvState *)tif->tif_data;
+
+ switch (tag)
+ {
+ case TIFFTAG_SGILOGDATAFMT:
+ *va_arg(ap, int *) = sp->user_datafmt;
+ return (1);
+ default:
+ return (*sp->vgetparent)(tif, tag, ap);
+ }
+}
+
+static const TIFFField LogLuvFields[] = {
+ {TIFFTAG_SGILOGDATAFMT, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT,
+ TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "SGILogDataFmt", NULL},
+ {TIFFTAG_SGILOGENCODE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT,
+ TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "SGILogEncode", NULL}};
+
+int TIFFInitSGILog(TIFF *tif, int scheme)
+{
+ static const char module[] = "TIFFInitSGILog";
+ LogLuvState *sp;
+
+ assert(scheme == COMPRESSION_SGILOG24 || scheme == COMPRESSION_SGILOG);
+
+ /*
+ * Merge codec-specific tag information.
+ */
+ if (!_TIFFMergeFields(tif, LogLuvFields, TIFFArrayCount(LogLuvFields)))
+ {
+ TIFFErrorExtR(tif, module, "Merging SGILog codec-specific tags failed");
+ return 0;
+ }
+
+ /*
+ * Allocate state block so tag methods have storage to record values.
+ */
+ tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(LogLuvState));
+ if (tif->tif_data == NULL)
+ goto bad;
+ sp = (LogLuvState *)tif->tif_data;
+ _TIFFmemset((void *)sp, 0, sizeof(*sp));
+ sp->user_datafmt = SGILOGDATAFMT_UNKNOWN;
+ sp->encode_meth = (scheme == COMPRESSION_SGILOG24) ? SGILOGENCODE_RANDITHER
+ : SGILOGENCODE_NODITHER;
+ sp->tfunc = _logLuvNop;
+
+ /*
+ * Install codec methods.
+ * NB: tif_decoderow & tif_encoderow are filled
+ * in at setup time.
+ */
+ tif->tif_fixuptags = LogLuvFixupTags;
+ tif->tif_setupdecode = LogLuvSetupDecode;
+ tif->tif_decodestrip = LogLuvDecodeStrip;
+ tif->tif_decodetile = LogLuvDecodeTile;
+ tif->tif_setupencode = LogLuvSetupEncode;
+ tif->tif_encodestrip = LogLuvEncodeStrip;
+ tif->tif_encodetile = LogLuvEncodeTile;
+ tif->tif_close = LogLuvClose;
+ tif->tif_cleanup = LogLuvCleanup;
+
+ /*
+ * Override parent get/set field methods.
+ */
+ sp->vgetparent = tif->tif_tagmethods.vgetfield;
+ tif->tif_tagmethods.vgetfield = LogLuvVGetField; /* hook for codec tags */
+ sp->vsetparent = tif->tif_tagmethods.vsetfield;
+ tif->tif_tagmethods.vsetfield = LogLuvVSetField; /* hook for codec tags */
+
+ return (1);
+bad:
+ TIFFErrorExtR(tif, module, "%s: No space for LogLuv state block",
+ tif->tif_name);
+ return (0);
+}
+#endif /* LOGLUV_SUPPORT */
diff --git a/contrib/libs/libtiff/tif_lzma.c b/contrib/libs/libtiff/tif_lzma.c
new file mode 100644
index 0000000000..4cfd5e8821
--- /dev/null
+++ b/contrib/libs/libtiff/tif_lzma.c
@@ -0,0 +1,520 @@
+/*
+ * Copyright (c) 2010, Andrey Kiselev <dron@ak4719.spb.edu>
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+#include "tiffiop.h"
+#ifdef LZMA_SUPPORT
+/*
+ * TIFF Library.
+ *
+ * LZMA2 Compression Support
+ *
+ * You need an LZMA2 SDK to link with. See http://tukaani.org/xz/ for details.
+ *
+ * The codec is derived from ZLIB codec (tif_zip.c).
+ */
+
+#include "lzma.h"
+#include "tif_predict.h"
+
+#include <stdio.h>
+
+/*
+ * State block for each open TIFF file using LZMA2 compression/decompression.
+ */
+typedef struct
+{
+ TIFFPredictorState predict;
+ lzma_stream stream;
+ lzma_filter filters[LZMA_FILTERS_MAX + 1];
+ lzma_options_delta opt_delta; /* delta filter options */
+ lzma_options_lzma opt_lzma; /* LZMA2 filter options */
+ int preset; /* compression level */
+ lzma_check check; /* type of the integrity check */
+ int state; /* state flags */
+#define LSTATE_INIT_DECODE 0x01
+#define LSTATE_INIT_ENCODE 0x02
+
+ TIFFVGetMethod vgetparent; /* super-class method */
+ TIFFVSetMethod vsetparent; /* super-class method */
+} LZMAState;
+
+#define LState(tif) ((LZMAState *)(tif)->tif_data)
+#define DecoderState(tif) LState(tif)
+#define EncoderState(tif) LState(tif)
+
+static int LZMAEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
+static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s);
+
+static const char *LZMAStrerror(lzma_ret ret)
+{
+ switch (ret)
+ {
+ case LZMA_OK:
+ return "operation completed successfully";
+ case LZMA_STREAM_END:
+ return "end of stream was reached";
+ case LZMA_NO_CHECK:
+ return "input stream has no integrity check";
+ case LZMA_UNSUPPORTED_CHECK:
+ return "cannot calculate the integrity check";
+ case LZMA_GET_CHECK:
+ return "integrity check type is now available";
+ case LZMA_MEM_ERROR:
+ return "cannot allocate memory";
+ case LZMA_MEMLIMIT_ERROR:
+ return "memory usage limit was reached";
+ case LZMA_FORMAT_ERROR:
+ return "file format not recognized";
+ case LZMA_OPTIONS_ERROR:
+ return "invalid or unsupported options";
+ case LZMA_DATA_ERROR:
+ return "data is corrupt";
+ case LZMA_BUF_ERROR:
+ return "no progress is possible (stream is truncated or corrupt)";
+ case LZMA_PROG_ERROR:
+ return "programming error";
+ default:
+ return "unidentified liblzma error";
+ }
+}
+
+static int LZMAFixupTags(TIFF *tif)
+{
+ (void)tif;
+ return 1;
+}
+
+static int LZMASetupDecode(TIFF *tif)
+{
+ LZMAState *sp = DecoderState(tif);
+
+ assert(sp != NULL);
+
+ /* if we were last encoding, terminate this mode */
+ if (sp->state & LSTATE_INIT_ENCODE)
+ {
+ lzma_end(&sp->stream);
+ sp->state = 0;
+ }
+
+ sp->state |= LSTATE_INIT_DECODE;
+ return 1;
+}
+
+/*
+ * Setup state for decoding a strip.
+ */
+static int LZMAPreDecode(TIFF *tif, uint16_t s)
+{
+ static const char module[] = "LZMAPreDecode";
+ LZMAState *sp = DecoderState(tif);
+ lzma_ret ret;
+
+ (void)s;
+ assert(sp != NULL);
+
+ if ((sp->state & LSTATE_INIT_DECODE) == 0)
+ tif->tif_setupdecode(tif);
+
+ sp->stream.next_in = tif->tif_rawdata;
+ sp->stream.avail_in = (size_t)tif->tif_rawcc;
+ if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc)
+ {
+ TIFFErrorExtR(tif, module,
+ "Liblzma cannot deal with buffers this size");
+ return 0;
+ }
+
+ /*
+ * Disable memory limit when decoding. UINT64_MAX is a flag to disable
+ * the limit, we are passing (uint64_t)-1 which should be the same.
+ */
+ ret = lzma_stream_decoder(&sp->stream, (uint64_t)-1, 0);
+ if (ret != LZMA_OK)
+ {
+ TIFFErrorExtR(tif, module, "Error initializing the stream decoder, %s",
+ LZMAStrerror(ret));
+ return 0;
+ }
+ return 1;
+}
+
+static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
+{
+ static const char module[] = "LZMADecode";
+ LZMAState *sp = DecoderState(tif);
+
+ (void)s;
+ assert(sp != NULL);
+ assert(sp->state == LSTATE_INIT_DECODE);
+
+ sp->stream.next_in = tif->tif_rawcp;
+ sp->stream.avail_in = (size_t)tif->tif_rawcc;
+
+ sp->stream.next_out = op;
+ sp->stream.avail_out = (size_t)occ;
+ if ((tmsize_t)sp->stream.avail_out != occ)
+ {
+ TIFFErrorExtR(tif, module,
+ "Liblzma cannot deal with buffers this size");
+ return 0;
+ }
+
+ do
+ {
+ /*
+ * Save the current stream state to properly recover from the
+ * decoding errors later.
+ */
+ const uint8_t *next_in = sp->stream.next_in;
+ size_t avail_in = sp->stream.avail_in;
+
+ lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN);
+ if (ret == LZMA_STREAM_END)
+ break;
+ if (ret == LZMA_MEMLIMIT_ERROR)
+ {
+ lzma_ret r =
+ lzma_stream_decoder(&sp->stream, lzma_memusage(&sp->stream), 0);
+ if (r != LZMA_OK)
+ {
+ TIFFErrorExtR(tif, module,
+ "Error initializing the stream decoder, %s",
+ LZMAStrerror(r));
+ break;
+ }
+ sp->stream.next_in = next_in;
+ sp->stream.avail_in = avail_in;
+ continue;
+ }
+ if (ret != LZMA_OK)
+ {
+ TIFFErrorExtR(tif, module,
+ "Decoding error at scanline %" PRIu32 ", %s",
+ tif->tif_row, LZMAStrerror(ret));
+ break;
+ }
+ } while (sp->stream.avail_out > 0);
+ if (sp->stream.avail_out != 0)
+ {
+ TIFFErrorExtR(tif, module,
+ "Not enough data at scanline %" PRIu32
+ " (short %" TIFF_SIZE_FORMAT " bytes)",
+ tif->tif_row, sp->stream.avail_out);
+ return 0;
+ }
+
+ tif->tif_rawcp = (uint8_t *)sp->stream.next_in; /* cast away const */
+ tif->tif_rawcc = sp->stream.avail_in;
+
+ return 1;
+}
+
+static int LZMASetupEncode(TIFF *tif)
+{
+ LZMAState *sp = EncoderState(tif);
+
+ assert(sp != NULL);
+ if (sp->state & LSTATE_INIT_DECODE)
+ {
+ lzma_end(&sp->stream);
+ sp->state = 0;
+ }
+
+ sp->state |= LSTATE_INIT_ENCODE;
+ return 1;
+}
+
+/*
+ * Reset encoding state at the start of a strip.
+ */
+static int LZMAPreEncode(TIFF *tif, uint16_t s)
+{
+ static const char module[] = "LZMAPreEncode";
+ LZMAState *sp = EncoderState(tif);
+ lzma_ret ret;
+
+ (void)s;
+ assert(sp != NULL);
+ if (sp->state != LSTATE_INIT_ENCODE)
+ tif->tif_setupencode(tif);
+
+ sp->stream.next_out = tif->tif_rawdata;
+ sp->stream.avail_out = (size_t)tif->tif_rawdatasize;
+ if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
+ {
+ TIFFErrorExtR(tif, module,
+ "Liblzma cannot deal with buffers this size");
+ return 0;
+ }
+ ret = lzma_stream_encoder(&sp->stream, sp->filters, sp->check);
+ if (ret != LZMA_OK)
+ {
+ TIFFErrorExtR(tif, module, "Error in lzma_stream_encoder(): %s",
+ LZMAStrerror(ret));
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * Encode a chunk of pixels.
+ */
+static int LZMAEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
+{
+ static const char module[] = "LZMAEncode";
+ LZMAState *sp = EncoderState(tif);
+
+ assert(sp != NULL);
+ assert(sp->state == LSTATE_INIT_ENCODE);
+
+ (void)s;
+ sp->stream.next_in = bp;
+ sp->stream.avail_in = (size_t)cc;
+ if ((tmsize_t)sp->stream.avail_in != cc)
+ {
+ TIFFErrorExtR(tif, module,
+ "Liblzma cannot deal with buffers this size");
+ return 0;
+ }
+ do
+ {
+ lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN);
+ if (ret != LZMA_OK)
+ {
+ TIFFErrorExtR(tif, module,
+ "Encoding error at scanline %" PRIu32 ", %s",
+ tif->tif_row, LZMAStrerror(ret));
+ return 0;
+ }
+ if (sp->stream.avail_out == 0)
+ {
+ tif->tif_rawcc = tif->tif_rawdatasize;
+ if (!TIFFFlushData1(tif))
+ return 0;
+ sp->stream.next_out = tif->tif_rawdata;
+ sp->stream.avail_out =
+ (size_t)
+ tif->tif_rawdatasize; /* this is a safe typecast, as check
+ is made already in LZMAPreEncode */
+ }
+ } while (sp->stream.avail_in > 0);
+ return 1;
+}
+
+/*
+ * Finish off an encoded strip by flushing the last
+ * string and tacking on an End Of Information code.
+ */
+static int LZMAPostEncode(TIFF *tif)
+{
+ static const char module[] = "LZMAPostEncode";
+ LZMAState *sp = EncoderState(tif);
+ lzma_ret ret;
+
+ sp->stream.avail_in = 0;
+ do
+ {
+ ret = lzma_code(&sp->stream, LZMA_FINISH);
+ switch (ret)
+ {
+ case LZMA_STREAM_END:
+ case LZMA_OK:
+ if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
+ {
+ tif->tif_rawcc =
+ tif->tif_rawdatasize - sp->stream.avail_out;
+ if (!TIFFFlushData1(tif))
+ return 0;
+ sp->stream.next_out = tif->tif_rawdata;
+ sp->stream.avail_out =
+ (size_t)
+ tif->tif_rawdatasize; /* this is a safe typecast, as
+ check is made already in
+ ZIPPreEncode */
+ }
+ break;
+ default:
+ TIFFErrorExtR(tif, module, "Liblzma error: %s",
+ LZMAStrerror(ret));
+ return 0;
+ }
+ } while (ret != LZMA_STREAM_END);
+ return 1;
+}
+
+static void LZMACleanup(TIFF *tif)
+{
+ LZMAState *sp = LState(tif);
+
+ assert(sp != 0);
+
+ (void)TIFFPredictorCleanup(tif);
+
+ tif->tif_tagmethods.vgetfield = sp->vgetparent;
+ tif->tif_tagmethods.vsetfield = sp->vsetparent;
+
+ if (sp->state)
+ {
+ lzma_end(&sp->stream);
+ sp->state = 0;
+ }
+ _TIFFfreeExt(tif, sp);
+ tif->tif_data = NULL;
+
+ _TIFFSetDefaultCompressionState(tif);
+}
+
+static int LZMAVSetField(TIFF *tif, uint32_t tag, va_list ap)
+{
+ static const char module[] = "LZMAVSetField";
+ LZMAState *sp = LState(tif);
+
+ switch (tag)
+ {
+ case TIFFTAG_LZMAPRESET:
+ sp->preset = (int)va_arg(ap, int);
+ lzma_lzma_preset(&sp->opt_lzma, sp->preset);
+ if (sp->state & LSTATE_INIT_ENCODE)
+ {
+ lzma_ret ret =
+ lzma_stream_encoder(&sp->stream, sp->filters, sp->check);
+ if (ret != LZMA_OK)
+ {
+ TIFFErrorExtR(tif, module, "Liblzma error: %s",
+ LZMAStrerror(ret));
+ }
+ }
+ return 1;
+ default:
+ return (*sp->vsetparent)(tif, tag, ap);
+ }
+ /*NOTREACHED*/
+}
+
+static int LZMAVGetField(TIFF *tif, uint32_t tag, va_list ap)
+{
+ LZMAState *sp = LState(tif);
+
+ switch (tag)
+ {
+ case TIFFTAG_LZMAPRESET:
+ *va_arg(ap, int *) = sp->preset;
+ break;
+ default:
+ return (*sp->vgetparent)(tif, tag, ap);
+ }
+ return 1;
+}
+
+static const TIFFField lzmaFields[] = {
+ {TIFFTAG_LZMAPRESET, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
+ TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE,
+ "LZMA2 Compression Preset", NULL},
+};
+
+int TIFFInitLZMA(TIFF *tif, int scheme)
+{
+ static const char module[] = "TIFFInitLZMA";
+ LZMAState *sp;
+ lzma_stream tmp_stream = LZMA_STREAM_INIT;
+
+ (void)scheme;
+ assert(scheme == COMPRESSION_LZMA);
+
+ /*
+ * Merge codec-specific tag information.
+ */
+ if (!_TIFFMergeFields(tif, lzmaFields, TIFFArrayCount(lzmaFields)))
+ {
+ TIFFErrorExtR(tif, module, "Merging LZMA2 codec-specific tags failed");
+ return 0;
+ }
+
+ /*
+ * Allocate state block so tag methods have storage to record values.
+ */
+ tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(LZMAState));
+ if (tif->tif_data == NULL)
+ goto bad;
+ sp = LState(tif);
+ memcpy(&sp->stream, &tmp_stream, sizeof(lzma_stream));
+
+ /*
+ * Override parent get/set field methods.
+ */
+ sp->vgetparent = tif->tif_tagmethods.vgetfield;
+ tif->tif_tagmethods.vgetfield = LZMAVGetField; /* hook for codec tags */
+ sp->vsetparent = tif->tif_tagmethods.vsetfield;
+ tif->tif_tagmethods.vsetfield = LZMAVSetField; /* hook for codec tags */
+
+ /* Default values for codec-specific fields */
+ sp->preset = LZMA_PRESET_DEFAULT; /* default comp. level */
+ sp->check = LZMA_CHECK_NONE;
+ sp->state = 0;
+
+ /* Data filters. So far we are using delta and LZMA2 filters only. */
+ sp->opt_delta.type = LZMA_DELTA_TYPE_BYTE;
+ /*
+ * The sample size in bytes seems to be reasonable distance for delta
+ * filter.
+ */
+ sp->opt_delta.dist = (tif->tif_dir.td_bitspersample % 8)
+ ? 1
+ : tif->tif_dir.td_bitspersample / 8;
+ sp->filters[0].id = LZMA_FILTER_DELTA;
+ sp->filters[0].options = &sp->opt_delta;
+
+ lzma_lzma_preset(&sp->opt_lzma, sp->preset);
+ sp->filters[1].id = LZMA_FILTER_LZMA2;
+ sp->filters[1].options = &sp->opt_lzma;
+
+ sp->filters[2].id = LZMA_VLI_UNKNOWN;
+ sp->filters[2].options = NULL;
+
+ /*
+ * Install codec methods.
+ */
+ tif->tif_fixuptags = LZMAFixupTags;
+ tif->tif_setupdecode = LZMASetupDecode;
+ tif->tif_predecode = LZMAPreDecode;
+ tif->tif_decoderow = LZMADecode;
+ tif->tif_decodestrip = LZMADecode;
+ tif->tif_decodetile = LZMADecode;
+ tif->tif_setupencode = LZMASetupEncode;
+ tif->tif_preencode = LZMAPreEncode;
+ tif->tif_postencode = LZMAPostEncode;
+ tif->tif_encoderow = LZMAEncode;
+ tif->tif_encodestrip = LZMAEncode;
+ tif->tif_encodetile = LZMAEncode;
+ tif->tif_cleanup = LZMACleanup;
+ /*
+ * Setup predictor setup.
+ */
+ (void)TIFFPredictorInit(tif);
+ return 1;
+bad:
+ TIFFErrorExtR(tif, module, "No space for LZMA2 state block");
+ return 0;
+}
+#endif /* LZMA_SUPPORT */
diff --git a/contrib/libs/libtiff/tif_lzw.c b/contrib/libs/libtiff/tif_lzw.c
new file mode 100644
index 0000000000..d631fa1049
--- /dev/null
+++ b/contrib/libs/libtiff/tif_lzw.c
@@ -0,0 +1,1458 @@
+/*
+ * 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
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+#include "tiffiop.h"
+#ifdef LZW_SUPPORT
+/*
+ * TIFF Library.
+ * Rev 5.0 Lempel-Ziv & Welch Compression Support
+ *
+ * This code is derived from the compress program whose code is
+ * derived from software contributed to Berkeley by James A. Woods,
+ * derived from original work by Spencer Thomas and Joseph Orost.
+ *
+ * The original Berkeley copyright notice appears below in its entirety.
+ */
+#include "tif_predict.h"
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.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
+ * one code earlier than should be done (for real LZW).
+ * Earlier versions of this library implemented the correct
+ * LZW algorithm, but emitted codes in a bit order opposite
+ * to the TIFF spec. Thus, to maintain compatibility w/ Aldus
+ * we interpret MSB-LSB ordered codes to be images written w/
+ * old versions of this library, but otherwise adhere to the
+ * Aldus "off by one" algorithm.
+ *
+ * Future revisions to the TIFF spec are expected to "clarify this issue".
+ */
+#define LZW_COMPAT /* include backwards compatibility code */
+
+#define MAXCODE(n) ((1L << (n)) - 1)
+/*
+ * The TIFF spec specifies that encoded bit
+ * strings range from 9 to 12 bits.
+ */
+#define BITS_MIN 9 /* start with 9 bits */
+#define BITS_MAX 12 /* max of 12 bit strings */
+/* predefined codes */
+#define CODE_CLEAR 256 /* code to clear string table */
+#define CODE_EOI 257 /* end-of-information code */
+#define CODE_FIRST 258 /* first free code entry */
+#define CODE_MAX MAXCODE(BITS_MAX)
+#define HSIZE 9001L /* 91% occupancy */
+#define HSHIFT (13 - 8)
+#ifdef LZW_COMPAT
+/* NB: +1024 is for compatibility with old files */
+#define CSIZE (MAXCODE(BITS_MAX) + 1024L)
+#else
+#define CSIZE (MAXCODE(BITS_MAX) + 1L)
+#endif
+
+/*
+ * State block for each open TIFF file using LZW
+ * compression/decompression. Note that the predictor
+ * state block must be first in this data structure.
+ */
+typedef struct
+{
+ TIFFPredictorState predict; /* predictor super class */
+
+ unsigned short nbits; /* # of bits/code */
+ unsigned short maxcode; /* maximum code for lzw_nbits */
+ unsigned short free_ent; /* next free entry in hash table */
+ WordType nextdata; /* next bits of i/o */
+ long nextbits; /* # of valid bits in lzw_nextdata */
+
+ int rw_mode; /* preserve rw_mode from init */
+} LZWBaseState;
+
+#define lzw_nbits base.nbits
+#define lzw_maxcode base.maxcode
+#define lzw_free_ent base.free_ent
+#define lzw_nextdata base.nextdata
+#define lzw_nextbits base.nextbits
+
+/*
+ * Encoding-specific state.
+ */
+typedef uint16_t hcode_t; /* codes fit in 16 bits */
+typedef struct
+{
+ long hash;
+ hcode_t code;
+} hash_t;
+
+/*
+ * Decoding-specific state.
+ */
+typedef struct code_ent
+{
+ struct code_ent *next;
+ unsigned short length; /* string len, including this token */
+ /* 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);
+
+typedef struct
+{
+ LZWBaseState base;
+
+ /* Decoding specific data */
+ long dec_nbitsmask; /* lzw_nbits 1 bits, right adjusted */
+ 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 */
+ 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 occurred, and which should cause
+ further reads in the same strip/tile to be aborted */
+
+ /* Encoding specific data */
+ int enc_oldcode; /* last code encountered */
+ tmsize_t enc_checkpoint; /* point at which to clear table */
+#define CHECK_GAP 10000 /* enc_ratio check interval */
+ 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;
+
+#define LZWState(tif) ((LZWBaseState *)(tif)->tif_data)
+#define DecoderState(tif) ((LZWCodecState *)LZWState(tif))
+#define EncoderState(tif) ((LZWCodecState *)LZWState(tif))
+
+static int LZWDecode(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s);
+#ifdef LZW_COMPAT
+static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s);
+#endif
+static void cl_hash(LZWCodecState *);
+
+/*
+ * LZW Decoder.
+ */
+
+static int LZWFixupTags(TIFF *tif)
+{
+ (void)tif;
+ return (1);
+}
+
+static int LZWSetupDecode(TIFF *tif)
+{
+ static const char module[] = "LZWSetupDecode";
+ LZWCodecState *sp = DecoderState(tif);
+ int code;
+
+ if (sp == NULL)
+ {
+ /*
+ * Allocate state block so tag methods have storage to record
+ * values.
+ */
+ tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(LZWCodecState));
+ if (tif->tif_data == NULL)
+ {
+ TIFFErrorExtR(tif, module, "No space for LZW state block");
+ return (0);
+ }
+
+ sp = DecoderState(tif);
+ sp->dec_codetab = NULL;
+ sp->dec_decode = NULL;
+
+ /*
+ * Setup predictor setup.
+ */
+ (void)TIFFPredictorInit(tif);
+ }
+
+ if (sp->dec_codetab == NULL)
+ {
+ sp->dec_codetab = (code_t *)_TIFFmallocExt(tif, CSIZE * sizeof(code_t));
+ if (sp->dec_codetab == NULL)
+ {
+ TIFFErrorExtR(tif, module, "No space for LZW code table");
+ return (0);
+ }
+ /*
+ * Pre-load the table.
+ */
+ code = 255;
+ do
+ {
+ 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] */
+ memset(&sp->dec_codetab[CODE_CLEAR], 0,
+ (CODE_FIRST - CODE_CLEAR) * sizeof(code_t));
+ }
+ return (1);
+}
+
+/*
+ * Setup state for decoding a strip.
+ */
+static int LZWPreDecode(TIFF *tif, uint16_t s)
+{
+ static const char module[] = "LZWPreDecode";
+ LZWCodecState *sp = DecoderState(tif);
+
+ (void)s;
+ assert(sp != NULL);
+ if (sp->dec_codetab == NULL)
+ {
+ tif->tif_setupdecode(tif);
+ if (sp->dec_codetab == NULL)
+ return (0);
+ }
+
+ /*
+ * Check for old bit-reversed codes.
+ */
+ if (tif->tif_rawcc >= 2 && tif->tif_rawdata[0] == 0 &&
+ (tif->tif_rawdata[1] & 0x1))
+ {
+#ifdef LZW_COMPAT
+ if (!sp->dec_decode)
+ {
+ TIFFWarningExtR(tif, module, "Old-style LZW codes, convert file");
+ /*
+ * Override default decoding methods with
+ * ones that deal with the old coding.
+ * Otherwise the predictor versions set
+ * above will call the compatibility routines
+ * through the dec_decode method.
+ */
+ tif->tif_decoderow = LZWDecodeCompat;
+ tif->tif_decodestrip = LZWDecodeCompat;
+ tif->tif_decodetile = LZWDecodeCompat;
+ /*
+ * If doing horizontal differencing, must
+ * re-setup the predictor logic since we
+ * switched the basic decoder methods...
+ */
+ (*tif->tif_setupdecode)(tif);
+ sp->dec_decode = LZWDecodeCompat;
+ }
+ sp->lzw_maxcode = MAXCODE(BITS_MIN);
+#else /* !LZW_COMPAT */
+ if (!sp->dec_decode)
+ {
+ TIFFErrorExtR(tif, module, "Old-style LZW codes not supported");
+ sp->dec_decode = LZWDecode;
+ }
+ return (0);
+#endif /* !LZW_COMPAT */
+ }
+ else
+ {
+ sp->lzw_maxcode = MAXCODE(BITS_MIN) - 1;
+ sp->dec_decode = LZWDecode;
+ }
+ sp->lzw_nbits = BITS_MIN;
+ sp->lzw_nextbits = 0;
+ sp->lzw_nextdata = 0;
+
+ sp->dec_restart = 0;
+ sp->dec_nbitsmask = MAXCODE(BITS_MIN);
+ sp->dec_bitsleft = 0;
+ 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
+ * us to index into undefined entries. If you can
+ * come up with a way to safely bounds-check input codes
+ * while decoding then you can remove this operation.
+ */
+ 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".
+ */
+
+/* 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);
+ uint8_t *op = (uint8_t *)op0;
+ tmsize_t occ = occ0;
+ uint8_t *bp;
+ long nbits, nextbits, nbitsmask;
+ WordType nextdata;
+ code_t *free_entp, *maxcodep, *oldcodep;
+
+ (void)s;
+ assert(sp != NULL);
+ assert(sp->dec_codetab != NULL);
+
+ if (sp->read_error)
+ {
+ TIFFErrorExtR(tif, module,
+ "LZWDecode: Scanline %" PRIu32 " cannot be read due to "
+ "previous error",
+ tif->tif_row);
+ return 0;
+ }
+
+ /*
+ * Restart interrupted output operation.
+ */
+ if (sp->dec_restart)
+ {
+ tmsize_t residue;
+
+ code_t *codep = sp->dec_codep;
+ residue = codep->length - sp->dec_restart;
+ if (residue > occ)
+ {
+ /*
+ * Residue from previous decode is sufficient
+ * to satisfy decode request. Skip to the
+ * start of the decoded string, place decoded
+ * values in the output buffer, and return.
+ */
+ sp->dec_restart += occ;
+ do
+ {
+ codep = codep->next;
+ } while (--residue > occ && codep);
+ if (codep)
+ {
+ uint8_t *tp = op + occ;
+ do
+ {
+ *--tp = codep->value;
+ codep = codep->next;
+ } while (--occ && codep);
+ }
+ return (1);
+ }
+ /*
+ * Residue satisfies only part of the decode request.
+ */
+ op += residue;
+ occ -= residue;
+ uint8_t *tp = op;
+ do
+ {
+ *--tp = codep->value;
+ codep = codep->next;
+ } while (--residue && codep);
+ sp->dec_restart = 0;
+ }
+
+ bp = (uint8_t *)tif->tif_rawcp;
+ sp->dec_bitsleft += (((uint64_t)tif->tif_rawcc - sp->old_tif_rawcc) << 3);
+ uint64_t dec_bitsleft = sp->dec_bitsleft;
+ nbits = sp->lzw_nbits;
+ nextdata = sp->lzw_nextdata;
+ nextbits = sp->lzw_nextbits;
+ nbitsmask = sp->dec_nbitsmask;
+ 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;
+}
+
+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;
+ }
+
+ 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;
+ }
+
+ 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;
+ sp->old_tif_rawcc = tif->tif_rawcc;
+ sp->dec_bitsleft = dec_bitsleft;
+ sp->lzw_nbits = (unsigned short)nbits;
+ sp->lzw_nextdata = nextdata;
+ sp->lzw_nextbits = nextbits;
+ sp->dec_nbitsmask = nbitsmask;
+ sp->dec_oldcodep = oldcodep;
+ sp->dec_free_entp = free_entp;
+ sp->dec_maxcodep = maxcodep;
+
+ if (occ > 0)
+ {
+ TIFFErrorExtR(tif, module,
+ "Not enough data at scanline %" PRIu32 " (short %" PRIu64
+ " bytes)",
+ tif->tif_row, (uint64_t)occ);
+ return (0);
+ }
+ return (1);
+
+no_eoi:
+ sp->read_error = 1;
+ TIFFErrorExtR(tif, module,
+ "LZWDecode: Strip %" PRIu32 " not terminated with EOI code",
+ tif->tif_curstrip);
+ return 0;
+error_code:
+ sp->read_error = 1;
+ TIFFErrorExtR(tif, 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) \
+ { \
+ TIFFWarningExtR(_tif, 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.
+ */
+#define GetNextCodeCompat(sp, bp, code) \
+ { \
+ nextdata |= (unsigned long)*(bp)++ << nextbits; \
+ nextbits += 8; \
+ if (nextbits < nbits) \
+ { \
+ nextdata |= (unsigned long)*(bp)++ << nextbits; \
+ nextbits += 8; \
+ } \
+ code = (hcode_t)(nextdata & nbitsmask); \
+ nextdata >>= nbits; \
+ nextbits -= nbits; \
+ }
+
+static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
+{
+ static const char module[] = "LZWDecodeCompat";
+ LZWCodecState *sp = DecoderState(tif);
+ uint8_t *op = (uint8_t *)op0;
+ tmsize_t occ = occ0;
+ uint8_t *tp;
+ uint8_t *bp;
+ int code, nbits;
+ int len;
+ long nextbits, nbitsmask;
+ WordType nextdata;
+ code_t *codep, *free_entp, *maxcodep, *oldcodep;
+
+ (void)s;
+ assert(sp != NULL);
+
+ /*
+ * Restart interrupted output operation.
+ */
+ if (sp->dec_restart)
+ {
+ tmsize_t residue;
+
+ codep = sp->dec_codep;
+ residue = codep->length - sp->dec_restart;
+ if (residue > occ)
+ {
+ /*
+ * Residue from previous decode is sufficient
+ * to satisfy decode request. Skip to the
+ * start of the decoded string, place decoded
+ * values in the output buffer, and return.
+ */
+ sp->dec_restart += occ;
+ do
+ {
+ codep = codep->next;
+ } while (--residue > occ);
+ tp = op + occ;
+ do
+ {
+ *--tp = codep->value;
+ codep = codep->next;
+ } while (--occ);
+ return (1);
+ }
+ /*
+ * Residue satisfies only part of the decode request.
+ */
+ op += residue;
+ occ -= residue;
+ tp = op;
+ do
+ {
+ *--tp = codep->value;
+ codep = codep->next;
+ } while (--residue);
+ sp->dec_restart = 0;
+ }
+
+ bp = (uint8_t *)tif->tif_rawcp;
+
+ sp->dec_bitsleft += (((uint64_t)tif->tif_rawcc - sp->old_tif_rawcc) << 3);
+ uint64_t dec_bitsleft = sp->dec_bitsleft;
+
+ nbits = sp->lzw_nbits;
+ nextdata = sp->lzw_nextdata;
+ nextbits = sp->lzw_nextbits;
+ nbitsmask = sp->dec_nbitsmask;
+ oldcodep = sp->dec_oldcodep;
+ free_entp = sp->dec_free_entp;
+ maxcodep = sp->dec_maxcodep;
+
+ while (occ > 0)
+ {
+ NextCode(tif, sp, bp, code, GetNextCodeCompat, dec_bitsleft);
+ 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;
+ NextCode(tif, sp, bp, code, GetNextCodeCompat, dec_bitsleft);
+ } while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */
+ if (code == CODE_EOI)
+ break;
+ if (code > CODE_CLEAR)
+ {
+ TIFFErrorExtR(
+ tif, tif->tif_name,
+ "LZWDecode: Corrupted LZW table at scanline %" PRIu32,
+ tif->tif_row);
+ return (0);
+ }
+ *op++ = (uint8_t)code;
+ occ--;
+ oldcodep = sp->dec_codetab + code;
+ continue;
+ }
+ codep = sp->dec_codetab + code;
+
+ /*
+ * Add the new entry to the code table.
+ */
+ if (free_entp < &sp->dec_codetab[0] ||
+ free_entp >= &sp->dec_codetab[CSIZE])
+ {
+ TIFFErrorExtR(tif, module,
+ "Corrupted LZW table at scanline %" PRIu32,
+ tif->tif_row);
+ return (0);
+ }
+
+ free_entp->next = oldcodep;
+ if (free_entp->next < &sp->dec_codetab[0] ||
+ free_entp->next >= &sp->dec_codetab[CSIZE])
+ {
+ TIFFErrorExtR(tif, 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;
+ }
+ oldcodep = codep;
+ if (code >= 256)
+ {
+ /*
+ * Code maps to a string, copy string
+ * value to output (written in reverse).
+ */
+ if (codep->length == 0)
+ {
+ TIFFErrorExtR(
+ tif, 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->length > occ);
+ sp->dec_restart = occ;
+ tp = op + occ;
+ do
+ {
+ *--tp = codep->value;
+ codep = codep->next;
+ } while (--occ);
+ break;
+ }
+ len = codep->length;
+ tp = op + len;
+ do
+ {
+ *--tp = codep->value;
+ codep = codep->next;
+ } while (codep && tp > op);
+ assert(occ >= len);
+ op += len;
+ occ -= len;
+ }
+ else
+ {
+ *op++ = (uint8_t)code;
+ occ--;
+ }
+ }
+
+ tif->tif_rawcc -= (tmsize_t)((uint8_t *)bp - tif->tif_rawcp);
+ tif->tif_rawcp = (uint8_t *)bp;
+
+ sp->old_tif_rawcc = tif->tif_rawcc;
+ sp->dec_bitsleft = dec_bitsleft;
+
+ sp->lzw_nbits = (unsigned short)nbits;
+ sp->lzw_nextdata = nextdata;
+ sp->lzw_nextbits = nextbits;
+ sp->dec_nbitsmask = nbitsmask;
+ sp->dec_oldcodep = oldcodep;
+ sp->dec_free_entp = free_entp;
+ sp->dec_maxcodep = maxcodep;
+
+ if (occ > 0)
+ {
+ TIFFErrorExtR(tif, module,
+ "Not enough data at scanline %" PRIu32 " (short %" PRIu64
+ " bytes)",
+ tif->tif_row, (uint64_t)occ);
+ return (0);
+ }
+ return (1);
+}
+#endif /* LZW_COMPAT */
+
+/*
+ * LZW Encoding.
+ */
+
+static int LZWSetupEncode(TIFF *tif)
+{
+ static const char module[] = "LZWSetupEncode";
+ LZWCodecState *sp = EncoderState(tif);
+
+ assert(sp != NULL);
+ sp->enc_hashtab = (hash_t *)_TIFFmallocExt(tif, HSIZE * sizeof(hash_t));
+ if (sp->enc_hashtab == NULL)
+ {
+ TIFFErrorExtR(tif, module, "No space for LZW hash table");
+ return (0);
+ }
+ return (1);
+}
+
+/*
+ * Reset encoding state at the start of a strip.
+ */
+static int LZWPreEncode(TIFF *tif, uint16_t s)
+{
+ LZWCodecState *sp = EncoderState(tif);
+
+ (void)s;
+ assert(sp != NULL);
+
+ if (sp->enc_hashtab == NULL)
+ {
+ tif->tif_setupencode(tif);
+ }
+
+ sp->lzw_nbits = BITS_MIN;
+ sp->lzw_maxcode = MAXCODE(BITS_MIN);
+ sp->lzw_free_ent = CODE_FIRST;
+ sp->lzw_nextbits = 0;
+ sp->lzw_nextdata = 0;
+ sp->enc_checkpoint = CHECK_GAP;
+ sp->enc_ratio = 0;
+ sp->enc_incount = 0;
+ sp->enc_outcount = 0;
+ /*
+ * The 4 here insures there is space for 2 max-sized
+ * codes in LZWEncode and LZWPostDecode.
+ */
+ sp->enc_rawlimit = tif->tif_rawdata + tif->tif_rawdatasize - 1 - 4;
+ cl_hash(sp); /* clear hash table */
+ sp->enc_oldcode = (hcode_t)-1; /* generates CODE_CLEAR in LZWEncode */
+ return (1);
+}
+
+#define CALCRATIO(sp, rat) \
+ { \
+ if (incount > 0x007fffff) \
+ { /* NB: shift will overflow */ \
+ rat = outcount >> 8; \
+ rat = (rat == 0 ? 0x7fffffff : incount / rat); \
+ } \
+ else \
+ rat = (incount << 8) / outcount; \
+ }
+
+/* Explicit 0xff masking to make icc -check=conversions happy */
+#define PutNextCode(op, c) \
+ { \
+ nextdata = (nextdata << nbits) | c; \
+ nextbits += nbits; \
+ *op++ = (unsigned char)((nextdata >> (nextbits - 8)) & 0xff); \
+ nextbits -= 8; \
+ if (nextbits >= 8) \
+ { \
+ *op++ = (unsigned char)((nextdata >> (nextbits - 8)) & 0xff); \
+ nextbits -= 8; \
+ } \
+ outcount += nbits; \
+ }
+
+/*
+ * Encode a chunk of pixels.
+ *
+ * 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.
+ * 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.
+ */
+static int LZWEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
+{
+ register LZWCodecState *sp = EncoderState(tif);
+ register long fcode;
+ register hash_t *hp;
+ register int h, c;
+ hcode_t ent;
+ long disp;
+ tmsize_t incount, outcount, checkpoint;
+ WordType nextdata;
+ long nextbits;
+ int free_ent, maxcode, nbits;
+ uint8_t *op;
+ uint8_t *limit;
+
+ (void)s;
+ if (sp == NULL)
+ return (0);
+
+ assert(sp->enc_hashtab != NULL);
+
+ /*
+ * Load local state.
+ */
+ incount = sp->enc_incount;
+ outcount = sp->enc_outcount;
+ checkpoint = sp->enc_checkpoint;
+ nextdata = sp->lzw_nextdata;
+ nextbits = sp->lzw_nextbits;
+ free_ent = sp->lzw_free_ent;
+ maxcode = sp->lzw_maxcode;
+ nbits = sp->lzw_nbits;
+ op = tif->tif_rawcp;
+ limit = sp->enc_rawlimit;
+ ent = (hcode_t)sp->enc_oldcode;
+
+ if (ent == (hcode_t)-1 && cc > 0)
+ {
+ /*
+ * NB: This is safe because it can only happen
+ * at the start of a strip where we know there
+ * is space in the data buffer.
+ */
+ PutNextCode(op, CODE_CLEAR);
+ ent = *bp++;
+ cc--;
+ incount++;
+ }
+ while (cc > 0)
+ {
+ c = *bp++;
+ cc--;
+ incount++;
+ fcode = ((long)c << BITS_MAX) + ent;
+ h = (c << HSHIFT) ^ ent; /* xor hashing */
+#ifdef _WINDOWS
+ /*
+ * Check hash index for an overflow.
+ */
+ if (h >= HSIZE)
+ h -= HSIZE;
+#endif
+ hp = &sp->enc_hashtab[h];
+ if (hp->hash == fcode)
+ {
+ ent = hp->code;
+ continue;
+ }
+ if (hp->hash >= 0)
+ {
+ /*
+ * Primary hash failed, check secondary hash.
+ */
+ disp = HSIZE - h;
+ if (h == 0)
+ disp = 1;
+ do
+ {
+ /*
+ * Avoid pointer arithmetic because of
+ * wraparound problems with segments.
+ */
+ if ((h -= disp) < 0)
+ h += HSIZE;
+ hp = &sp->enc_hashtab[h];
+ if (hp->hash == fcode)
+ {
+ ent = hp->code;
+ goto hit;
+ }
+ } while (hp->hash >= 0);
+ }
+ /*
+ * New entry, emit code and add to table.
+ */
+ /*
+ * Verify there is space in the buffer for the code
+ * and any potential Clear code that might be emitted
+ * below. The value of limit is setup so that there
+ * are at least 4 bytes free--room for 2 codes.
+ */
+ if (op > limit)
+ {
+ tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata);
+ if (!TIFFFlushData1(tif))
+ return 0;
+ op = tif->tif_rawdata;
+ }
+ PutNextCode(op, ent);
+ ent = (hcode_t)c;
+ hp->code = (hcode_t)(free_ent++);
+ hp->hash = fcode;
+ if (free_ent == CODE_MAX - 1)
+ {
+ /* table is full, emit clear code and reset */
+ cl_hash(sp);
+ sp->enc_ratio = 0;
+ incount = 0;
+ outcount = 0;
+ free_ent = CODE_FIRST;
+ PutNextCode(op, CODE_CLEAR);
+ nbits = BITS_MIN;
+ maxcode = MAXCODE(BITS_MIN);
+ }
+ else
+ {
+ /*
+ * If the next entry is going to be too big for
+ * the code size, then increase it, if possible.
+ */
+ if (free_ent > maxcode)
+ {
+ nbits++;
+ assert(nbits <= BITS_MAX);
+ maxcode = (int)MAXCODE(nbits);
+ }
+ else if (incount >= checkpoint)
+ {
+ tmsize_t rat;
+ /*
+ * Check compression ratio and, if things seem
+ * to be slipping, clear the hash table and
+ * reset state. The compression ratio is a
+ * 24+8-bit fractional number.
+ */
+ checkpoint = incount + CHECK_GAP;
+ CALCRATIO(sp, rat);
+ if (rat <= sp->enc_ratio)
+ {
+ cl_hash(sp);
+ sp->enc_ratio = 0;
+ incount = 0;
+ outcount = 0;
+ free_ent = CODE_FIRST;
+ PutNextCode(op, CODE_CLEAR);
+ nbits = BITS_MIN;
+ maxcode = MAXCODE(BITS_MIN);
+ }
+ else
+ sp->enc_ratio = rat;
+ }
+ }
+ hit:;
+ }
+
+ /*
+ * Restore global state.
+ */
+ sp->enc_incount = incount;
+ sp->enc_outcount = outcount;
+ sp->enc_checkpoint = checkpoint;
+ sp->enc_oldcode = ent;
+ sp->lzw_nextdata = nextdata;
+ sp->lzw_nextbits = nextbits;
+ sp->lzw_free_ent = (unsigned short)free_ent;
+ sp->lzw_maxcode = (unsigned short)maxcode;
+ sp->lzw_nbits = (unsigned short)nbits;
+ tif->tif_rawcp = op;
+ return (1);
+}
+
+/*
+ * Finish off an encoded strip by flushing the last
+ * string and tacking on an End Of Information code.
+ */
+static int LZWPostEncode(TIFF *tif)
+{
+ register LZWCodecState *sp = EncoderState(tif);
+ uint8_t *op = tif->tif_rawcp;
+ long nextbits = sp->lzw_nextbits;
+ WordType nextdata = sp->lzw_nextdata;
+ tmsize_t outcount = sp->enc_outcount;
+ int nbits = sp->lzw_nbits;
+
+ if (op > sp->enc_rawlimit)
+ {
+ tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata);
+ if (!TIFFFlushData1(tif))
+ return 0;
+ op = tif->tif_rawdata;
+ }
+ if (sp->enc_oldcode != (hcode_t)-1)
+ {
+ int free_ent = sp->lzw_free_ent;
+
+ PutNextCode(op, sp->enc_oldcode);
+ sp->enc_oldcode = (hcode_t)-1;
+ free_ent++;
+
+ if (free_ent == CODE_MAX - 1)
+ {
+ /* table is full, emit clear code and reset */
+ outcount = 0;
+ PutNextCode(op, CODE_CLEAR);
+ nbits = BITS_MIN;
+ }
+ else
+ {
+ /*
+ * If the next entry is going to be too big for
+ * the code size, then increase it, if possible.
+ */
+ if (free_ent > sp->lzw_maxcode)
+ {
+ nbits++;
+ assert(nbits <= BITS_MAX);
+ }
+ }
+ }
+ PutNextCode(op, CODE_EOI);
+ /* Explicit 0xff masking to make icc -check=conversions happy */
+ if (nextbits > 0)
+ *op++ = (unsigned char)((nextdata << (8 - nextbits)) & 0xff);
+ tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata);
+ (void)outcount;
+ return (1);
+}
+
+/*
+ * Reset encoding hash table.
+ */
+static void cl_hash(LZWCodecState *sp)
+{
+ register hash_t *hp = &sp->enc_hashtab[HSIZE - 1];
+ register long i = HSIZE - 8;
+
+ do
+ {
+ i -= 8;
+ hp[-7].hash = -1;
+ hp[-6].hash = -1;
+ hp[-5].hash = -1;
+ hp[-4].hash = -1;
+ hp[-3].hash = -1;
+ hp[-2].hash = -1;
+ hp[-1].hash = -1;
+ hp[0].hash = -1;
+ hp -= 8;
+ } while (i >= 0);
+ for (i += 8; i > 0; i--, hp--)
+ hp->hash = -1;
+}
+
+static void LZWCleanup(TIFF *tif)
+{
+ (void)TIFFPredictorCleanup(tif);
+
+ assert(tif->tif_data != 0);
+
+ if (DecoderState(tif)->dec_codetab)
+ _TIFFfreeExt(tif, DecoderState(tif)->dec_codetab);
+
+ if (EncoderState(tif)->enc_hashtab)
+ _TIFFfreeExt(tif, EncoderState(tif)->enc_hashtab);
+
+ _TIFFfreeExt(tif, tif->tif_data);
+ tif->tif_data = NULL;
+
+ _TIFFSetDefaultCompressionState(tif);
+}
+
+int TIFFInitLZW(TIFF *tif, int scheme)
+{
+ static const char module[] = "TIFFInitLZW";
+ (void)scheme;
+ assert(scheme == COMPRESSION_LZW);
+ /*
+ * Allocate state block so tag methods have storage to record values.
+ */
+ tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(LZWCodecState));
+ if (tif->tif_data == NULL)
+ goto bad;
+ DecoderState(tif)->dec_codetab = NULL;
+ DecoderState(tif)->dec_decode = NULL;
+ EncoderState(tif)->enc_hashtab = NULL;
+ LZWState(tif)->rw_mode = tif->tif_mode;
+
+ /*
+ * Install codec methods.
+ */
+ tif->tif_fixuptags = LZWFixupTags;
+ tif->tif_setupdecode = LZWSetupDecode;
+ tif->tif_predecode = LZWPreDecode;
+ tif->tif_decoderow = LZWDecode;
+ tif->tif_decodestrip = LZWDecode;
+ tif->tif_decodetile = LZWDecode;
+ tif->tif_setupencode = LZWSetupEncode;
+ tif->tif_preencode = LZWPreEncode;
+ tif->tif_postencode = LZWPostEncode;
+ tif->tif_encoderow = LZWEncode;
+ tif->tif_encodestrip = LZWEncode;
+ tif->tif_encodetile = LZWEncode;
+ tif->tif_cleanup = LZWCleanup;
+ /*
+ * Setup predictor setup.
+ */
+ (void)TIFFPredictorInit(tif);
+ return (1);
+bad:
+ TIFFErrorExtR(tif, module, "No space for LZW state block");
+ return (0);
+}
+
+/*
+ * Copyright (c) 1985, 1986 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * James A. Woods, derived from original work by Spencer Thomas
+ * and Joseph Orost.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#endif /* LZW_SUPPORT */
diff --git a/contrib/libs/libtiff/tif_next.c b/contrib/libs/libtiff/tif_next.c
new file mode 100644
index 0000000000..f000574ee7
--- /dev/null
+++ b/contrib/libs/libtiff/tif_next.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+#include "tiffiop.h"
+#ifdef NEXT_SUPPORT
+/*
+ * TIFF Library.
+ *
+ * NeXT 2-bit Grey Scale Compression Algorithm Support
+ */
+
+#define SETPIXEL(op, v) \
+ { \
+ switch (npixels++ & 3) \
+ { \
+ case 0: \
+ op[0] = (unsigned char)((v) << 6); \
+ break; \
+ case 1: \
+ op[0] |= (v) << 4; \
+ break; \
+ case 2: \
+ op[0] |= (v) << 2; \
+ break; \
+ case 3: \
+ *op++ |= (v); \
+ op_offset++; \
+ break; \
+ } \
+ }
+
+#define LITERALROW 0x00
+#define LITERALSPAN 0x40
+#define WHITE ((1 << 2) - 1)
+
+static int NeXTDecode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
+{
+ static const char module[] = "NeXTDecode";
+ unsigned char *bp, *op;
+ tmsize_t cc;
+ uint8_t *row;
+ tmsize_t scanline, n;
+
+ (void)s;
+ /*
+ * Each scanline is assumed to start off as all
+ * white (we assume a PhotometricInterpretation
+ * of ``min-is-black'').
+ */
+ for (op = (unsigned char *)buf, cc = occ; cc-- > 0;)
+ *op++ = 0xff;
+
+ bp = (unsigned char *)tif->tif_rawcp;
+ cc = tif->tif_rawcc;
+ scanline = tif->tif_scanlinesize;
+ if (occ % scanline)
+ {
+ TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
+ return (0);
+ }
+ for (row = buf; cc > 0 && occ > 0; occ -= scanline, row += scanline)
+ {
+ n = *bp++;
+ cc--;
+ switch (n)
+ {
+ case LITERALROW:
+ /*
+ * The entire scanline is given as literal values.
+ */
+ if (cc < scanline)
+ goto bad;
+ _TIFFmemcpy(row, bp, scanline);
+ bp += scanline;
+ cc -= scanline;
+ break;
+ case LITERALSPAN:
+ {
+ tmsize_t off;
+ /*
+ * The scanline has a literal span that begins at some
+ * offset.
+ */
+ if (cc < 4)
+ goto bad;
+ off = (bp[0] * 256) + bp[1];
+ n = (bp[2] * 256) + bp[3];
+ if (cc < 4 + n || off + n > scanline)
+ goto bad;
+ _TIFFmemcpy(row + off, bp + 4, n);
+ bp += 4 + n;
+ cc -= 4 + n;
+ break;
+ }
+ default:
+ {
+ uint32_t npixels = 0, grey;
+ tmsize_t op_offset = 0;
+ uint32_t imagewidth = tif->tif_dir.td_imagewidth;
+ if (isTiled(tif))
+ imagewidth = tif->tif_dir.td_tilewidth;
+
+ /*
+ * The scanline is composed of a sequence of constant
+ * color ``runs''. We shift into ``run mode'' and
+ * interpret bytes as codes of the form
+ * <color><npixels> until we've filled the scanline.
+ */
+ op = row;
+ for (;;)
+ {
+ grey = (uint32_t)((n >> 6) & 0x3);
+ n &= 0x3f;
+ /*
+ * Ensure the run does not exceed the scanline
+ * bounds, potentially resulting in a security
+ * issue.
+ */
+ while (n-- > 0 && npixels < imagewidth &&
+ op_offset < scanline)
+ SETPIXEL(op, grey);
+ if (npixels >= imagewidth)
+ break;
+ if (op_offset >= scanline)
+ {
+ TIFFErrorExtR(tif, module,
+ "Invalid data for scanline %" PRIu32,
+ tif->tif_row);
+ return (0);
+ }
+ if (cc == 0)
+ goto bad;
+ n = *bp++;
+ cc--;
+ }
+ break;
+ }
+ }
+ }
+ tif->tif_rawcp = (uint8_t *)bp;
+ tif->tif_rawcc = cc;
+ return (1);
+bad:
+ TIFFErrorExtR(tif, module, "Not enough data for scanline %" PRIu32,
+ tif->tif_row);
+ return (0);
+}
+
+static int NeXTPreDecode(TIFF *tif, uint16_t s)
+{
+ static const char module[] = "NeXTPreDecode";
+ TIFFDirectory *td = &tif->tif_dir;
+ (void)s;
+
+ if (td->td_bitspersample != 2)
+ {
+ TIFFErrorExtR(tif, module, "Unsupported BitsPerSample = %" PRIu16,
+ td->td_bitspersample);
+ return (0);
+ }
+ return (1);
+}
+
+int TIFFInitNeXT(TIFF *tif, int scheme)
+{
+ (void)scheme;
+ tif->tif_predecode = NeXTPreDecode;
+ tif->tif_decoderow = NeXTDecode;
+ tif->tif_decodestrip = NeXTDecode;
+ tif->tif_decodetile = NeXTDecode;
+ return (1);
+}
+#endif /* NEXT_SUPPORT */
diff --git a/contrib/libs/libtiff/tif_ojpeg.c b/contrib/libs/libtiff/tif_ojpeg.c
new file mode 100644
index 0000000000..ea572091e5
--- /dev/null
+++ b/contrib/libs/libtiff/tif_ojpeg.c
@@ -0,0 +1,2815 @@
+/* WARNING: The type of JPEG encapsulation defined by the TIFF Version 6.0
+ specification is now totally obsolete and deprecated for new applications and
+ images. This file was was created solely in order to read unconverted images
+ still present on some users' computer systems. It will never be extended
+ to write such files. Writing new-style JPEG compressed TIFFs is implemented
+ in tif_jpeg.c.
+
+ The code is carefully crafted to robustly read all gathered JPEG-in-TIFF
+ testfiles, and anticipate as much as possible all other... But still, it may
+ fail on some. If you encounter problems, please report them on the TIFF
+ mailing list and/or to Joris Van Damme <info@awaresystems.be>.
+
+ Please read the file called "TIFF Technical Note #2" if you need to be
+ convinced this compression scheme is bad and breaks TIFF. That document
+ is linked to from the LibTiff site <http://www.remotesensing.org/libtiff/>
+ and from AWare Systems' TIFF section
+ <http://www.awaresystems.be/imaging/tiff.html>. It is also absorbed
+ in Adobe's specification supplements, marked "draft" up to this day, but
+ supported by the TIFF community.
+
+ This file interfaces with Release 6B of the JPEG Library written by the
+ Independent JPEG Group. Previous versions of this file required a hack inside
+ the LibJpeg library. This version no longer requires that. Remember to
+ remove the hack if you update from the old version.
+
+ Copyright (c) Joris Van Damme <info@awaresystems.be>
+ Copyright (c) AWare Systems <http://www.awaresystems.be/>
+
+ The licence agreement for this file is the same as the rest of the LibTiff
+ library.
+
+ IN NO EVENT SHALL JORIS VAN DAMME OR AWARE SYSTEMS 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
+ OF THIS SOFTWARE.
+
+ Joris Van Damme and/or AWare Systems may be available for custom
+ development. If you like what you see, and need anything similar or related,
+ contact <info@awaresystems.be>.
+*/
+
+/* What is what, and what is not?
+
+ This decoder starts with an input stream, that is essentially the
+ JpegInterchangeFormat stream, if any, followed by the strile data, if any.
+ This stream is read in OJPEGReadByte and related functions.
+
+ It analyzes the start of this stream, until it encounters non-marker data,
+ i.e. compressed image data. Some of the header markers it sees have no actual
+ content, like the SOI marker, and APP/COM markers that really shouldn't even
+ be there. Some other markers do have content, and the valuable bits and
+ pieces of information in these markers are saved, checking all to verify that
+ the stream is more or less within expected bounds. This happens inside the
+ OJPEGReadHeaderInfoSecStreamXxx functions.
+
+ Some OJPEG imagery contains no valid JPEG header markers. This situation is
+ picked up on if we've seen no SOF marker when we're at the start of the
+ compressed image data. In this case, the tables are read from JpegXxxTables
+ tags, and the other bits and pieces of information is initialized to its most
+ basic value. This is implemented in the OJPEGReadHeaderInfoSecTablesXxx
+ functions.
+
+ When this is complete, a good and valid JPEG header can be assembled, and
+ this is passed through to LibJpeg. When that's done, the remainder of the
+ input stream, i.e. the compressed image data, can be passed through
+ unchanged. This is done in OJPEGWriteStream functions.
+
+ LibTiff rightly expects to know the subsampling values before decompression.
+ Just like in new-style JPEG-in-TIFF, though, or even more so, actually, the
+ YCbCrsubsampling tag is notoriously unreliable. To correct these tag values
+ with the ones inside the JPEG stream, the first part of the input stream is
+ pre-scanned in OJPEGSubsamplingCorrect, making no note of any other data,
+ reporting no warnings or errors, up to the point where either these values
+ are read, or it's clear they aren't there. This means that some of the data
+ is read twice, but we feel speed in correcting these values is important
+ enough to warrant this sacrifice. Although there is currently no define or
+ other configuration mechanism to disable this behavior, the actual header
+ scanning is build to robustly respond with error report if it should
+ encounter an uncorrected mismatch of subsampling values. See
+ OJPEGReadHeaderInfoSecStreamSof.
+
+ The restart interval and restart markers are the most tricky part... The
+ restart interval can be specified in a tag. It can also be set inside the
+ input JPEG stream. It can be used inside the input JPEG stream. If reading
+ from strile data, we've consistently discovered the need to insert restart
+ markers in between the different striles, as is also probably the most likely
+ interpretation of the original TIFF 6.0 specification. With all this setting
+ of interval, and actual use of markers that is not predictable at the time of
+ valid JPEG header assembly, the restart thing may turn out the Achilles heel
+ of this implementation. Fortunately, most OJPEG writer vendors succeed in
+ reading back what they write, which may be the reason why we've been able to
+ discover ways that seem to work.
+
+ Some special provision is made for planarconfig separate OJPEG files. These
+ seem to consistently contain header info, a SOS marker, a plane, SOS marker,
+ plane, SOS, and plane. This may or may not be a valid JPEG configuration, we
+ don't know and don't care. We want LibTiff to be able to access the planes
+ individually, without huge buffering inside LibJpeg, anyway. So we compose
+ headers to feed to LibJpeg, in this case, that allow us to pass a single
+ plane such that LibJpeg sees a valid single-channel JPEG stream. Locating
+ subsequent SOS markers, and thus subsequent planes, is done inside
+ OJPEGReadSecondarySos.
+
+ The benefit of the scheme is... that it works, basically. We know of no other
+ that does. It works without checking software tag, or otherwise going about
+ things in an OJPEG flavor specific manner. Instead, it is a single scheme,
+ that covers the cases with and without JpegInterchangeFormat, with and
+ without striles, with part of the header in JpegInterchangeFormat and
+ remainder in first strile, etc. It is forgiving and robust, may likely work
+ with OJPEG flavors we've not seen yet, and makes most out of the data.
+
+ Another nice side-effect is that a complete JPEG single valid stream is build
+ if planarconfig is not separate (vast majority). We may one day use that to
+ build converters to JPEG, and/or to new-style JPEG compression inside TIFF.
+
+ A disadvantage is the lack of random access to the individual striles. This
+ is the reason for much of the complicated restart-and-position stuff inside
+ OJPEGPreDecode. Applications would do well accessing all striles in order, as
+ this will result in a single sequential scan of the input stream, and no
+ restarting of LibJpeg decoding session.
+*/
+
+#define WIN32_LEAN_AND_MEAN
+#define VC_EXTRALEAN
+
+#include "tiffiop.h"
+#ifdef OJPEG_SUPPORT
+
+/* Configuration defines here are:
+ * JPEG_ENCAP_EXTERNAL: The normal way to call libjpeg, uses longjump. In some
+ * environments, like eg LibTiffDelphi, this is not possible. For this reason,
+ * the actual calls to libjpeg, with longjump stuff, are encapsulated in
+ * dedicated functions. When JPEG_ENCAP_EXTERNAL is defined, these encapsulating
+ * functions are declared external to this unit, and can be defined elsewhere to
+ * use stuff other then longjump. The default mode, without JPEG_ENCAP_EXTERNAL,
+ * implements the call encapsulators here, internally, with normal longjump.
+ * SETJMP, LONGJMP, JMP_BUF: On some machines/environments a longjump equivalent
+ * is conveniently available, but still it may be worthwhile to use _setjmp or
+ * sigsetjmp in place of plain setjmp. These macros will make it easier. It is
+ * useless to fiddle with these if you define JPEG_ENCAP_EXTERNAL. OJPEG_BUFFER:
+ * Define the size of the desired buffer here. Should be small enough so as to
+ * guarantee instant processing, optimal streaming and optimal use of processor
+ * cache, but also big enough so as to not result in significant call overhead.
+ * It should be at least a few bytes to accommodate some structures (this is
+ * verified in asserts), but it would not be sensible to make it this small
+ * anyway, and it should be at most 64K since it is indexed with uint16_t. We
+ * recommend 2K. EGYPTIANWALK: You could also define EGYPTIANWALK here, but it
+ * is not used anywhere and has absolutely no effect. That is why most people
+ * insist the EGYPTIANWALK is a bit silly.
+ */
+
+/* define LIBJPEG_ENCAP_EXTERNAL */
+#define SETJMP(jbuf) setjmp(jbuf)
+#define LONGJMP(jbuf, code) longjmp(jbuf, code)
+#define JMP_BUF jmp_buf
+#define OJPEG_BUFFER 2048
+/* define EGYPTIANWALK */
+
+#define JPEG_MARKER_SOF0 0xC0
+#define JPEG_MARKER_SOF1 0xC1
+#define JPEG_MARKER_SOF3 0xC3
+#define JPEG_MARKER_DHT 0xC4
+#define JPEG_MARKER_RST0 0XD0
+#define JPEG_MARKER_SOI 0xD8
+#define JPEG_MARKER_EOI 0xD9
+#define JPEG_MARKER_SOS 0xDA
+#define JPEG_MARKER_DQT 0xDB
+#define JPEG_MARKER_DRI 0xDD
+#define JPEG_MARKER_APP0 0xE0
+#define JPEG_MARKER_COM 0xFE
+
+#define FIELD_OJPEG_JPEGINTERCHANGEFORMAT (FIELD_CODEC + 0)
+#define FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH (FIELD_CODEC + 1)
+#define FIELD_OJPEG_JPEGQTABLES (FIELD_CODEC + 2)
+#define FIELD_OJPEG_JPEGDCTABLES (FIELD_CODEC + 3)
+#define FIELD_OJPEG_JPEGACTABLES (FIELD_CODEC + 4)
+#define FIELD_OJPEG_JPEGPROC (FIELD_CODEC + 5)
+#define FIELD_OJPEG_JPEGRESTARTINTERVAL (FIELD_CODEC + 6)
+
+static const TIFFField ojpegFields[] = {
+ {TIFFTAG_JPEGIFOFFSET, 1, 1, TIFF_LONG8, 0, TIFF_SETGET_UINT64,
+ TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGINTERCHANGEFORMAT, TRUE, FALSE,
+ "JpegInterchangeFormat", NULL},
+ {TIFFTAG_JPEGIFBYTECOUNT, 1, 1, TIFF_LONG8, 0, TIFF_SETGET_UINT64,
+ TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH, TRUE,
+ FALSE, "JpegInterchangeFormatLength", NULL},
+ {TIFFTAG_JPEGQTABLES, TIFF_VARIABLE2, TIFF_VARIABLE2, TIFF_LONG8, 0,
+ TIFF_SETGET_C32_UINT64, TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGQTABLES,
+ FALSE, TRUE, "JpegQTables", NULL},
+ {TIFFTAG_JPEGDCTABLES, TIFF_VARIABLE2, TIFF_VARIABLE2, TIFF_LONG8, 0,
+ TIFF_SETGET_C32_UINT64, TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGDCTABLES,
+ FALSE, TRUE, "JpegDcTables", NULL},
+ {TIFFTAG_JPEGACTABLES, TIFF_VARIABLE2, TIFF_VARIABLE2, TIFF_LONG8, 0,
+ TIFF_SETGET_C32_UINT64, TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGACTABLES,
+ FALSE, TRUE, "JpegAcTables", NULL},
+ {TIFFTAG_JPEGPROC, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16,
+ TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGPROC, FALSE, FALSE, "JpegProc",
+ NULL},
+ {TIFFTAG_JPEGRESTARTINTERVAL, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16,
+ TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGRESTARTINTERVAL, FALSE, FALSE,
+ "JpegRestartInterval", NULL},
+};
+
+#ifndef LIBJPEG_ENCAP_EXTERNAL
+#include <setjmp.h>
+#endif
+
+/* We undefine FAR to avoid conflict with JPEG definition */
+
+#ifdef FAR
+#undef FAR
+#endif
+
+/*
+ Libjpeg's jmorecfg.h defines INT16 and INT32, but only if XMD_H is
+ not defined. Unfortunately, the MinGW and Borland compilers include
+ a typedef for INT32, which causes a conflict. MSVC does not include
+ a conflicting typedef given the headers which are included.
+*/
+#if defined(__BORLANDC__) || defined(__MINGW32__)
+#define XMD_H 1
+#endif
+
+/* 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 */
+#endif
+
+#include "jerror.h"
+#include "jpeglib.h"
+
+typedef struct jpeg_error_mgr jpeg_error_mgr;
+typedef struct jpeg_common_struct jpeg_common_struct;
+typedef struct jpeg_decompress_struct jpeg_decompress_struct;
+typedef struct jpeg_source_mgr jpeg_source_mgr;
+
+typedef enum
+{
+ osibsNotSetYet,
+ osibsJpegInterchangeFormat,
+ osibsStrile,
+ osibsEof
+} OJPEGStateInBufferSource;
+
+typedef enum
+{
+ ososSoi,
+ ososQTable0,
+ ososQTable1,
+ ososQTable2,
+ ososQTable3,
+ ososDcTable0,
+ ososDcTable1,
+ ososDcTable2,
+ ososDcTable3,
+ ososAcTable0,
+ ososAcTable1,
+ ososAcTable2,
+ ososAcTable3,
+ ososDri,
+ ososSof,
+ ososSos,
+ ososCompressed,
+ ososRst,
+ ososEoi
+} OJPEGStateOutState;
+
+typedef struct
+{
+ TIFF *tif;
+ int decoder_ok;
+ int error_in_raw_data_decoding;
+#ifndef LIBJPEG_ENCAP_EXTERNAL
+ JMP_BUF exit_jmpbuf;
+#endif
+ TIFFVGetMethod vgetparent;
+ TIFFVSetMethod vsetparent;
+ TIFFPrintMethod printdir;
+ uint64_t file_size;
+ uint32_t image_width;
+ uint32_t image_length;
+ uint32_t strile_width;
+ uint32_t strile_length;
+ uint32_t strile_length_total;
+ uint8_t samples_per_pixel;
+ uint8_t plane_sample_offset;
+ uint8_t samples_per_pixel_per_plane;
+ uint64_t jpeg_interchange_format;
+ uint64_t jpeg_interchange_format_length;
+ uint8_t jpeg_proc;
+ uint8_t subsamplingcorrect;
+ uint8_t subsamplingcorrect_done;
+ uint8_t subsampling_tag;
+ uint8_t subsampling_hor;
+ uint8_t subsampling_ver;
+ uint8_t subsampling_force_desubsampling_inside_decompression;
+ uint8_t qtable_offset_count;
+ uint8_t dctable_offset_count;
+ uint8_t actable_offset_count;
+ uint64_t qtable_offset[3];
+ uint64_t dctable_offset[3];
+ uint64_t actable_offset[3];
+ uint8_t *qtable[4];
+ uint8_t *dctable[4];
+ uint8_t *actable[4];
+ uint16_t restart_interval;
+ uint8_t restart_index;
+ uint8_t sof_log;
+ uint8_t sof_marker_id;
+ uint32_t sof_x;
+ uint32_t sof_y;
+ uint8_t sof_c[3];
+ uint8_t sof_hv[3];
+ uint8_t sof_tq[3];
+ uint8_t sos_cs[3];
+ uint8_t sos_tda[3];
+ struct
+ {
+ uint8_t log;
+ OJPEGStateInBufferSource in_buffer_source;
+ uint32_t in_buffer_next_strile;
+ uint64_t in_buffer_file_pos;
+ uint64_t in_buffer_file_togo;
+ } sos_end[3];
+ uint8_t readheader_done;
+ uint8_t writeheader_done;
+ uint16_t write_cursample;
+ uint32_t write_curstrile;
+ uint8_t libjpeg_session_active;
+ uint8_t libjpeg_jpeg_query_style;
+ jpeg_error_mgr libjpeg_jpeg_error_mgr;
+ jpeg_decompress_struct libjpeg_jpeg_decompress_struct;
+ jpeg_source_mgr libjpeg_jpeg_source_mgr;
+ uint8_t subsampling_convert_log;
+ uint32_t subsampling_convert_ylinelen;
+ uint32_t subsampling_convert_ylines;
+ uint32_t subsampling_convert_clinelen;
+ uint32_t subsampling_convert_clines;
+ uint32_t subsampling_convert_ybuflen;
+ uint32_t subsampling_convert_cbuflen;
+ uint32_t subsampling_convert_ycbcrbuflen;
+ uint8_t *subsampling_convert_ycbcrbuf;
+ uint8_t *subsampling_convert_ybuf;
+ uint8_t *subsampling_convert_cbbuf;
+ uint8_t *subsampling_convert_crbuf;
+ uint32_t subsampling_convert_ycbcrimagelen;
+ uint8_t **subsampling_convert_ycbcrimage;
+ uint32_t subsampling_convert_clinelenout;
+ uint32_t subsampling_convert_state;
+ uint32_t bytes_per_line; /* if the codec outputs subsampled data, a 'line'
+ in bytes_per_line */
+ uint32_t lines_per_strile; /* and lines_per_strile means subsampling_ver
+ desubsampled rows */
+ OJPEGStateInBufferSource in_buffer_source;
+ uint32_t in_buffer_next_strile;
+ uint32_t in_buffer_strile_count;
+ uint64_t in_buffer_file_pos;
+ uint8_t in_buffer_file_pos_log;
+ uint64_t in_buffer_file_togo;
+ uint16_t in_buffer_togo;
+ uint8_t *in_buffer_cur;
+ uint8_t in_buffer[OJPEG_BUFFER];
+ OJPEGStateOutState out_state;
+ uint8_t out_buffer[OJPEG_BUFFER];
+ uint8_t *skip_buffer;
+} OJPEGState;
+
+static int OJPEGVGetField(TIFF *tif, uint32_t tag, va_list ap);
+static int OJPEGVSetField(TIFF *tif, uint32_t tag, va_list ap);
+static void OJPEGPrintDir(TIFF *tif, FILE *fd, long flags);
+
+static int OJPEGFixupTags(TIFF *tif);
+static int OJPEGSetupDecode(TIFF *tif);
+static int OJPEGPreDecode(TIFF *tif, uint16_t s);
+static int OJPEGPreDecodeSkipRaw(TIFF *tif);
+static int OJPEGPreDecodeSkipScanlines(TIFF *tif);
+static int OJPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s);
+static int OJPEGDecodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc);
+static int OJPEGDecodeScanlines(TIFF *tif, uint8_t *buf, tmsize_t cc);
+static void OJPEGPostDecode(TIFF *tif, uint8_t *buf, tmsize_t cc);
+static int OJPEGSetupEncode(TIFF *tif);
+static int OJPEGPreEncode(TIFF *tif, uint16_t s);
+static int OJPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s);
+static int OJPEGPostEncode(TIFF *tif);
+static void OJPEGCleanup(TIFF *tif);
+
+static void OJPEGSubsamplingCorrect(TIFF *tif);
+static int OJPEGReadHeaderInfo(TIFF *tif);
+static int OJPEGReadSecondarySos(TIFF *tif, uint16_t s);
+static int OJPEGWriteHeaderInfo(TIFF *tif);
+static void OJPEGLibjpegSessionAbort(TIFF *tif);
+
+static int OJPEGReadHeaderInfoSec(TIFF *tif);
+static int OJPEGReadHeaderInfoSecStreamDri(TIFF *tif);
+static int OJPEGReadHeaderInfoSecStreamDqt(TIFF *tif);
+static int OJPEGReadHeaderInfoSecStreamDht(TIFF *tif);
+static int OJPEGReadHeaderInfoSecStreamSof(TIFF *tif, uint8_t marker_id);
+static int OJPEGReadHeaderInfoSecStreamSos(TIFF *tif);
+static int OJPEGReadHeaderInfoSecTablesQTable(TIFF *tif);
+static int OJPEGReadHeaderInfoSecTablesDcTable(TIFF *tif);
+static int OJPEGReadHeaderInfoSecTablesAcTable(TIFF *tif);
+
+static int OJPEGReadBufferFill(OJPEGState *sp);
+static int OJPEGReadByte(OJPEGState *sp, uint8_t *byte);
+static int OJPEGReadBytePeek(OJPEGState *sp, uint8_t *byte);
+static void OJPEGReadByteAdvance(OJPEGState *sp);
+static int OJPEGReadWord(OJPEGState *sp, uint16_t *word);
+static int OJPEGReadBlock(OJPEGState *sp, uint16_t len, void *mem);
+static void OJPEGReadSkip(OJPEGState *sp, uint16_t len);
+
+static int OJPEGWriteStream(TIFF *tif, void **mem, uint32_t *len);
+static void OJPEGWriteStreamSoi(TIFF *tif, void **mem, uint32_t *len);
+static void OJPEGWriteStreamQTable(TIFF *tif, uint8_t table_index, void **mem,
+ uint32_t *len);
+static void OJPEGWriteStreamDcTable(TIFF *tif, uint8_t table_index, void **mem,
+ uint32_t *len);
+static void OJPEGWriteStreamAcTable(TIFF *tif, uint8_t table_index, void **mem,
+ uint32_t *len);
+static void OJPEGWriteStreamDri(TIFF *tif, void **mem, uint32_t *len);
+static void OJPEGWriteStreamSof(TIFF *tif, void **mem, uint32_t *len);
+static void OJPEGWriteStreamSos(TIFF *tif, void **mem, uint32_t *len);
+static int OJPEGWriteStreamCompressed(TIFF *tif, void **mem, uint32_t *len);
+static void OJPEGWriteStreamRst(TIFF *tif, void **mem, uint32_t *len);
+static void OJPEGWriteStreamEoi(TIFF *tif, void **mem, uint32_t *len);
+
+#ifdef LIBJPEG_ENCAP_EXTERNAL
+extern int jpeg_create_decompress_encap(OJPEGState *sp,
+ jpeg_decompress_struct *cinfo);
+extern int jpeg_read_header_encap(OJPEGState *sp, jpeg_decompress_struct *cinfo,
+ uint8_t require_image);
+extern int jpeg_start_decompress_encap(OJPEGState *sp,
+ jpeg_decompress_struct *cinfo);
+extern int jpeg_read_scanlines_encap(OJPEGState *sp,
+ jpeg_decompress_struct *cinfo,
+ void *scanlines, uint32_t max_lines);
+extern int jpeg_read_raw_data_encap(OJPEGState *sp,
+ jpeg_decompress_struct *cinfo, void *data,
+ uint32_t max_lines);
+extern void jpeg_encap_unwind(TIFF *tif);
+#else
+static int jpeg_create_decompress_encap(OJPEGState *sp,
+ jpeg_decompress_struct *j);
+static int jpeg_read_header_encap(OJPEGState *sp, jpeg_decompress_struct *cinfo,
+ uint8_t require_image);
+static int jpeg_start_decompress_encap(OJPEGState *sp,
+ jpeg_decompress_struct *cinfo);
+static int jpeg_read_scanlines_encap(OJPEGState *sp,
+ jpeg_decompress_struct *cinfo,
+ void *scanlines, uint32_t max_lines);
+static int jpeg_read_raw_data_encap(OJPEGState *sp,
+ jpeg_decompress_struct *cinfo, void *data,
+ uint32_t max_lines);
+static void jpeg_encap_unwind(TIFF *tif);
+#endif
+
+static void OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct *cinfo);
+static void OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct *cinfo);
+static void OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct *cinfo);
+static boolean
+OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct *cinfo);
+static void
+OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct *cinfo,
+ long num_bytes);
+static boolean
+OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct *cinfo,
+ int desired);
+static void OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct *cinfo);
+
+int TIFFInitOJPEG(TIFF *tif, int scheme)
+{
+ static const char module[] = "TIFFInitOJPEG";
+ OJPEGState *sp;
+
+ (void)scheme;
+ assert(scheme == COMPRESSION_OJPEG);
+
+ /*
+ * Merge codec-specific tag information.
+ */
+ if (!_TIFFMergeFields(tif, ojpegFields, TIFFArrayCount(ojpegFields)))
+ {
+ TIFFErrorExtR(tif, module,
+ "Merging Old JPEG codec-specific tags failed");
+ return 0;
+ }
+
+ /* state block */
+ sp = _TIFFmallocExt(tif, sizeof(OJPEGState));
+ if (sp == NULL)
+ {
+ TIFFErrorExtR(tif, module, "No space for OJPEG state block");
+ return (0);
+ }
+ _TIFFmemset(sp, 0, sizeof(OJPEGState));
+ sp->tif = tif;
+ sp->jpeg_proc = 1;
+ sp->subsampling_hor = 2;
+ sp->subsampling_ver = 2;
+ TIFFSetField(tif, TIFFTAG_YCBCRSUBSAMPLING, 2, 2);
+ /* tif codec methods */
+ tif->tif_fixuptags = OJPEGFixupTags;
+ tif->tif_setupdecode = OJPEGSetupDecode;
+ tif->tif_predecode = OJPEGPreDecode;
+ tif->tif_postdecode = OJPEGPostDecode;
+ tif->tif_decoderow = OJPEGDecode;
+ tif->tif_decodestrip = OJPEGDecode;
+ tif->tif_decodetile = OJPEGDecode;
+ tif->tif_setupencode = OJPEGSetupEncode;
+ tif->tif_preencode = OJPEGPreEncode;
+ tif->tif_postencode = OJPEGPostEncode;
+ tif->tif_encoderow = OJPEGEncode;
+ tif->tif_encodestrip = OJPEGEncode;
+ tif->tif_encodetile = OJPEGEncode;
+ tif->tif_cleanup = OJPEGCleanup;
+ tif->tif_data = (uint8_t *)sp;
+ /* tif tag methods */
+ sp->vgetparent = tif->tif_tagmethods.vgetfield;
+ tif->tif_tagmethods.vgetfield = OJPEGVGetField;
+ sp->vsetparent = tif->tif_tagmethods.vsetfield;
+ tif->tif_tagmethods.vsetfield = OJPEGVSetField;
+ sp->printdir = tif->tif_tagmethods.printdir;
+ tif->tif_tagmethods.printdir = OJPEGPrintDir;
+ /* Some OJPEG files don't have strip or tile offsets or bytecounts tags.
+ Some others do, but have totally meaningless or corrupt values
+ in these tags. In these cases, the JpegInterchangeFormat stream is
+ reliable. In any case, this decoder reads the compressed data itself,
+ from the most reliable locations, and we need to notify encapsulating
+ LibTiff not to read raw strips or tiles for us. */
+ tif->tif_flags |= TIFF_NOREADRAW;
+ return (1);
+}
+
+static int OJPEGVGetField(TIFF *tif, uint32_t tag, va_list ap)
+{
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ switch (tag)
+ {
+ case TIFFTAG_JPEGIFOFFSET:
+ *va_arg(ap, uint64_t *) = (uint64_t)sp->jpeg_interchange_format;
+ break;
+ case TIFFTAG_JPEGIFBYTECOUNT:
+ *va_arg(ap, uint64_t *) =
+ (uint64_t)sp->jpeg_interchange_format_length;
+ break;
+ case TIFFTAG_YCBCRSUBSAMPLING:
+ if (sp->subsamplingcorrect_done == 0)
+ OJPEGSubsamplingCorrect(tif);
+ *va_arg(ap, uint16_t *) = (uint16_t)sp->subsampling_hor;
+ *va_arg(ap, uint16_t *) = (uint16_t)sp->subsampling_ver;
+ break;
+ case TIFFTAG_JPEGQTABLES:
+ *va_arg(ap, uint32_t *) = (uint32_t)sp->qtable_offset_count;
+ *va_arg(ap, const void **) = (const void *)sp->qtable_offset;
+ break;
+ case TIFFTAG_JPEGDCTABLES:
+ *va_arg(ap, uint32_t *) = (uint32_t)sp->dctable_offset_count;
+ *va_arg(ap, const void **) = (const void *)sp->dctable_offset;
+ break;
+ case TIFFTAG_JPEGACTABLES:
+ *va_arg(ap, uint32_t *) = (uint32_t)sp->actable_offset_count;
+ *va_arg(ap, const void **) = (const void *)sp->actable_offset;
+ break;
+ case TIFFTAG_JPEGPROC:
+ *va_arg(ap, uint16_t *) = (uint16_t)sp->jpeg_proc;
+ break;
+ case TIFFTAG_JPEGRESTARTINTERVAL:
+ *va_arg(ap, uint16_t *) = sp->restart_interval;
+ break;
+ default:
+ return (*sp->vgetparent)(tif, tag, ap);
+ }
+ return (1);
+}
+
+static int OJPEGVSetField(TIFF *tif, uint32_t tag, va_list ap)
+{
+ static const char module[] = "OJPEGVSetField";
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ uint32_t ma;
+ uint64_t *mb;
+ uint32_t n;
+ const TIFFField *fip;
+
+ switch (tag)
+ {
+ case TIFFTAG_JPEGIFOFFSET:
+ sp->jpeg_interchange_format = (uint64_t)va_arg(ap, uint64_t);
+ break;
+ case TIFFTAG_JPEGIFBYTECOUNT:
+ sp->jpeg_interchange_format_length = (uint64_t)va_arg(ap, uint64_t);
+ break;
+ case TIFFTAG_YCBCRSUBSAMPLING:
+ sp->subsampling_tag = 1;
+ sp->subsampling_hor = (uint8_t)va_arg(ap, uint16_vap);
+ sp->subsampling_ver = (uint8_t)va_arg(ap, uint16_vap);
+ tif->tif_dir.td_ycbcrsubsampling[0] = sp->subsampling_hor;
+ tif->tif_dir.td_ycbcrsubsampling[1] = sp->subsampling_ver;
+ break;
+ case TIFFTAG_JPEGQTABLES:
+ ma = (uint32_t)va_arg(ap, uint32_t);
+ if (ma != 0)
+ {
+ if (ma > 3)
+ {
+ TIFFErrorExtR(tif, module,
+ "JpegQTables tag has incorrect count");
+ return (0);
+ }
+ sp->qtable_offset_count = (uint8_t)ma;
+ mb = (uint64_t *)va_arg(ap, uint64_t *);
+ for (n = 0; n < ma; n++)
+ sp->qtable_offset[n] = mb[n];
+ }
+ break;
+ case TIFFTAG_JPEGDCTABLES:
+ ma = (uint32_t)va_arg(ap, uint32_t);
+ if (ma != 0)
+ {
+ if (ma > 3)
+ {
+ TIFFErrorExtR(tif, module,
+ "JpegDcTables tag has incorrect count");
+ return (0);
+ }
+ sp->dctable_offset_count = (uint8_t)ma;
+ mb = (uint64_t *)va_arg(ap, uint64_t *);
+ for (n = 0; n < ma; n++)
+ sp->dctable_offset[n] = mb[n];
+ }
+ break;
+ case TIFFTAG_JPEGACTABLES:
+ ma = (uint32_t)va_arg(ap, uint32_t);
+ if (ma != 0)
+ {
+ if (ma > 3)
+ {
+ TIFFErrorExtR(tif, module,
+ "JpegAcTables tag has incorrect count");
+ return (0);
+ }
+ sp->actable_offset_count = (uint8_t)ma;
+ mb = (uint64_t *)va_arg(ap, uint64_t *);
+ for (n = 0; n < ma; n++)
+ sp->actable_offset[n] = mb[n];
+ }
+ break;
+ case TIFFTAG_JPEGPROC:
+ sp->jpeg_proc = (uint8_t)va_arg(ap, uint16_vap);
+ break;
+ case TIFFTAG_JPEGRESTARTINTERVAL:
+ sp->restart_interval = (uint16_t)va_arg(ap, uint16_vap);
+ break;
+ default:
+ return (*sp->vsetparent)(tif, tag, ap);
+ }
+ fip = TIFFFieldWithTag(tif, tag);
+ if (fip == NULL) /* shouldn't happen */
+ return (0);
+ TIFFSetFieldBit(tif, fip->field_bit);
+ tif->tif_flags |= TIFF_DIRTYDIRECT;
+ return (1);
+}
+
+static void OJPEGPrintDir(TIFF *tif, FILE *fd, long flags)
+{
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ uint8_t m;
+ (void)flags;
+ assert(sp != NULL);
+ if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGINTERCHANGEFORMAT))
+ fprintf(fd, " JpegInterchangeFormat: %" PRIu64 "\n",
+ (uint64_t)sp->jpeg_interchange_format);
+ if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH))
+ fprintf(fd, " JpegInterchangeFormatLength: %" PRIu64 "\n",
+ (uint64_t)sp->jpeg_interchange_format_length);
+ if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGQTABLES))
+ {
+ fprintf(fd, " JpegQTables:");
+ for (m = 0; m < sp->qtable_offset_count; m++)
+ fprintf(fd, " %" PRIu64, (uint64_t)sp->qtable_offset[m]);
+ fprintf(fd, "\n");
+ }
+ if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGDCTABLES))
+ {
+ fprintf(fd, " JpegDcTables:");
+ for (m = 0; m < sp->dctable_offset_count; m++)
+ fprintf(fd, " %" PRIu64, (uint64_t)sp->dctable_offset[m]);
+ fprintf(fd, "\n");
+ }
+ if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGACTABLES))
+ {
+ fprintf(fd, " JpegAcTables:");
+ for (m = 0; m < sp->actable_offset_count; m++)
+ fprintf(fd, " %" PRIu64, (uint64_t)sp->actable_offset[m]);
+ fprintf(fd, "\n");
+ }
+ if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGPROC))
+ fprintf(fd, " JpegProc: %" PRIu8 "\n", sp->jpeg_proc);
+ if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGRESTARTINTERVAL))
+ fprintf(fd, " JpegRestartInterval: %" PRIu16 "\n",
+ sp->restart_interval);
+ if (sp->printdir)
+ (*sp->printdir)(tif, fd, flags);
+}
+
+static int OJPEGFixupTags(TIFF *tif)
+{
+ (void)tif;
+ return (1);
+}
+
+static int OJPEGSetupDecode(TIFF *tif)
+{
+ static const char module[] = "OJPEGSetupDecode";
+ TIFFWarningExtR(tif, module,
+ "Deprecated and troublesome old-style JPEG compression "
+ "mode, please convert to new-style JPEG compression and "
+ "notify vendor of writing software");
+ return (1);
+}
+
+static int OJPEGPreDecode(TIFF *tif, uint16_t s)
+{
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ uint32_t m;
+ if (sp->subsamplingcorrect_done == 0)
+ OJPEGSubsamplingCorrect(tif);
+ if (sp->readheader_done == 0)
+ {
+ if (OJPEGReadHeaderInfo(tif) == 0)
+ return (0);
+ }
+ if (sp->sos_end[s].log == 0)
+ {
+ if (OJPEGReadSecondarySos(tif, s) == 0)
+ return (0);
+ }
+ if (isTiled(tif))
+ m = tif->tif_curtile;
+ else
+ m = tif->tif_curstrip;
+ if ((sp->writeheader_done != 0) &&
+ ((sp->write_cursample != s) || (sp->write_curstrile > m)))
+ {
+ if (sp->libjpeg_session_active != 0)
+ OJPEGLibjpegSessionAbort(tif);
+ sp->writeheader_done = 0;
+ }
+ if (sp->writeheader_done == 0)
+ {
+ sp->plane_sample_offset = (uint8_t)s;
+ sp->write_cursample = s;
+ sp->write_curstrile = s * tif->tif_dir.td_stripsperimage;
+ if ((sp->in_buffer_file_pos_log == 0) ||
+ (sp->in_buffer_file_pos - sp->in_buffer_togo !=
+ sp->sos_end[s].in_buffer_file_pos))
+ {
+ sp->in_buffer_source = sp->sos_end[s].in_buffer_source;
+ sp->in_buffer_next_strile = sp->sos_end[s].in_buffer_next_strile;
+ sp->in_buffer_file_pos = sp->sos_end[s].in_buffer_file_pos;
+ sp->in_buffer_file_pos_log = 0;
+ sp->in_buffer_file_togo = sp->sos_end[s].in_buffer_file_togo;
+ sp->in_buffer_togo = 0;
+ sp->in_buffer_cur = 0;
+ }
+ if (OJPEGWriteHeaderInfo(tif) == 0)
+ return (0);
+ }
+ while (sp->write_curstrile < m)
+ {
+ if (sp->libjpeg_jpeg_query_style == 0)
+ {
+ if (OJPEGPreDecodeSkipRaw(tif) == 0)
+ return (0);
+ }
+ else
+ {
+ if (OJPEGPreDecodeSkipScanlines(tif) == 0)
+ return (0);
+ }
+ sp->write_curstrile++;
+ }
+ sp->decoder_ok = 1;
+ return (1);
+}
+
+static int OJPEGPreDecodeSkipRaw(TIFF *tif)
+{
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ uint32_t m;
+ m = sp->lines_per_strile;
+ if (sp->subsampling_convert_state != 0)
+ {
+ if (sp->subsampling_convert_clines - sp->subsampling_convert_state >= m)
+ {
+ sp->subsampling_convert_state += m;
+ if (sp->subsampling_convert_state == sp->subsampling_convert_clines)
+ sp->subsampling_convert_state = 0;
+ return (1);
+ }
+ m -= sp->subsampling_convert_clines - sp->subsampling_convert_state;
+ sp->subsampling_convert_state = 0;
+ sp->error_in_raw_data_decoding = 0;
+ }
+ while (m >= sp->subsampling_convert_clines)
+ {
+ if (jpeg_read_raw_data_encap(sp, &(sp->libjpeg_jpeg_decompress_struct),
+ sp->subsampling_convert_ycbcrimage,
+ sp->subsampling_ver * 8) == 0)
+ return (0);
+ m -= sp->subsampling_convert_clines;
+ }
+ if (m > 0)
+ {
+ if (jpeg_read_raw_data_encap(sp, &(sp->libjpeg_jpeg_decompress_struct),
+ sp->subsampling_convert_ycbcrimage,
+ sp->subsampling_ver * 8) == 0)
+ return (0);
+ sp->subsampling_convert_state = m;
+ }
+ return (1);
+}
+
+static int OJPEGPreDecodeSkipScanlines(TIFF *tif)
+{
+ static const char module[] = "OJPEGPreDecodeSkipScanlines";
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ uint32_t m;
+ if (sp->skip_buffer == NULL)
+ {
+ sp->skip_buffer = _TIFFmallocExt(tif, sp->bytes_per_line);
+ if (sp->skip_buffer == NULL)
+ {
+ TIFFErrorExtR(tif, module, "Out of memory");
+ return (0);
+ }
+ }
+ for (m = 0; m < sp->lines_per_strile; m++)
+ {
+ if (jpeg_read_scanlines_encap(sp, &(sp->libjpeg_jpeg_decompress_struct),
+ &sp->skip_buffer, 1) == 0)
+ return (0);
+ }
+ return (1);
+}
+
+static int OJPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
+{
+ static const char module[] = "OJPEGDecode";
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ (void)s;
+ if (!sp->decoder_ok)
+ {
+ TIFFErrorExtR(tif, 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 */
+ TIFFErrorExtR(tif, module,
+ "Cannot decode: libjpeg_session_active == 0");
+ return 0;
+ }
+ if (sp->error_in_raw_data_decoding)
+ {
+ return 0;
+ }
+ if (sp->libjpeg_jpeg_query_style == 0)
+ {
+ if (OJPEGDecodeRaw(tif, buf, cc) == 0)
+ return (0);
+ }
+ else
+ {
+ if (OJPEGDecodeScanlines(tif, buf, cc) == 0)
+ return (0);
+ }
+ return (1);
+}
+
+static int OJPEGDecodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc)
+{
+ static const char module[] = "OJPEGDecodeRaw";
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ uint8_t *m;
+ tmsize_t n;
+ uint8_t *oy;
+ uint8_t *ocb;
+ uint8_t *ocr;
+ uint8_t *p;
+ uint32_t q;
+ uint8_t *r;
+ uint8_t sx, sy;
+ if (cc % sp->bytes_per_line != 0)
+ {
+ TIFFErrorExtR(tif, module, "Fractional scanline not read");
+ return (0);
+ }
+ assert(cc > 0);
+ m = buf;
+ n = cc;
+ do
+ {
+ if (sp->subsampling_convert_state == 0)
+ {
+ if (jpeg_read_raw_data_encap(sp,
+ &(sp->libjpeg_jpeg_decompress_struct),
+ sp->subsampling_convert_ycbcrimage,
+ sp->subsampling_ver * 8) == 0)
+ {
+ sp->error_in_raw_data_decoding = 1;
+ return (0);
+ }
+ }
+ oy = sp->subsampling_convert_ybuf +
+ sp->subsampling_convert_state * sp->subsampling_ver *
+ sp->subsampling_convert_ylinelen;
+ ocb = sp->subsampling_convert_cbbuf +
+ sp->subsampling_convert_state * sp->subsampling_convert_clinelen;
+ ocr = sp->subsampling_convert_crbuf +
+ sp->subsampling_convert_state * sp->subsampling_convert_clinelen;
+ p = m;
+ for (q = 0; q < sp->subsampling_convert_clinelenout; q++)
+ {
+ r = oy;
+ for (sy = 0; sy < sp->subsampling_ver; sy++)
+ {
+ for (sx = 0; sx < sp->subsampling_hor; sx++)
+ *p++ = *r++;
+ r += sp->subsampling_convert_ylinelen - sp->subsampling_hor;
+ }
+ oy += sp->subsampling_hor;
+ *p++ = *ocb++;
+ *p++ = *ocr++;
+ }
+ sp->subsampling_convert_state++;
+ if (sp->subsampling_convert_state == sp->subsampling_convert_clines)
+ sp->subsampling_convert_state = 0;
+ m += sp->bytes_per_line;
+ n -= sp->bytes_per_line;
+ } while (n > 0);
+ return (1);
+}
+
+static int OJPEGDecodeScanlines(TIFF *tif, uint8_t *buf, tmsize_t cc)
+{
+ static const char module[] = "OJPEGDecodeScanlines";
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ uint8_t *m;
+ tmsize_t n;
+ if (cc % sp->bytes_per_line != 0)
+ {
+ TIFFErrorExtR(tif, module, "Fractional scanline not read");
+ return (0);
+ }
+ assert(cc > 0);
+ m = buf;
+ n = cc;
+ do
+ {
+ if (jpeg_read_scanlines_encap(sp, &(sp->libjpeg_jpeg_decompress_struct),
+ &m, 1) == 0)
+ return (0);
+ m += sp->bytes_per_line;
+ n -= sp->bytes_per_line;
+ } while (n > 0);
+ return (1);
+}
+
+static void 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)
+ {
+ assert(sp->libjpeg_session_active != 0);
+ OJPEGLibjpegSessionAbort(tif);
+ sp->writeheader_done = 0;
+ }
+}
+
+static int OJPEGSetupEncode(TIFF *tif)
+{
+ static const char module[] = "OJPEGSetupEncode";
+ TIFFErrorExtR(
+ tif, module,
+ "OJPEG encoding not supported; use new-style JPEG compression instead");
+ return (0);
+}
+
+static int OJPEGPreEncode(TIFF *tif, uint16_t s)
+{
+ static const char module[] = "OJPEGPreEncode";
+ (void)s;
+ TIFFErrorExtR(
+ tif, module,
+ "OJPEG encoding not supported; use new-style JPEG compression instead");
+ return (0);
+}
+
+static int OJPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
+{
+ static const char module[] = "OJPEGEncode";
+ (void)buf;
+ (void)cc;
+ (void)s;
+ TIFFErrorExtR(
+ tif, module,
+ "OJPEG encoding not supported; use new-style JPEG compression instead");
+ return (0);
+}
+
+static int OJPEGPostEncode(TIFF *tif)
+{
+ static const char module[] = "OJPEGPostEncode";
+ TIFFErrorExtR(
+ tif, module,
+ "OJPEG encoding not supported; use new-style JPEG compression instead");
+ return (0);
+}
+
+static void OJPEGCleanup(TIFF *tif)
+{
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ if (sp != 0)
+ {
+ tif->tif_tagmethods.vgetfield = sp->vgetparent;
+ tif->tif_tagmethods.vsetfield = sp->vsetparent;
+ tif->tif_tagmethods.printdir = sp->printdir;
+ if (sp->qtable[0] != 0)
+ _TIFFfreeExt(tif, sp->qtable[0]);
+ if (sp->qtable[1] != 0)
+ _TIFFfreeExt(tif, sp->qtable[1]);
+ if (sp->qtable[2] != 0)
+ _TIFFfreeExt(tif, sp->qtable[2]);
+ if (sp->qtable[3] != 0)
+ _TIFFfreeExt(tif, sp->qtable[3]);
+ if (sp->dctable[0] != 0)
+ _TIFFfreeExt(tif, sp->dctable[0]);
+ if (sp->dctable[1] != 0)
+ _TIFFfreeExt(tif, sp->dctable[1]);
+ if (sp->dctable[2] != 0)
+ _TIFFfreeExt(tif, sp->dctable[2]);
+ if (sp->dctable[3] != 0)
+ _TIFFfreeExt(tif, sp->dctable[3]);
+ if (sp->actable[0] != 0)
+ _TIFFfreeExt(tif, sp->actable[0]);
+ if (sp->actable[1] != 0)
+ _TIFFfreeExt(tif, sp->actable[1]);
+ if (sp->actable[2] != 0)
+ _TIFFfreeExt(tif, sp->actable[2]);
+ if (sp->actable[3] != 0)
+ _TIFFfreeExt(tif, sp->actable[3]);
+ if (sp->libjpeg_session_active != 0)
+ OJPEGLibjpegSessionAbort(tif);
+ if (sp->subsampling_convert_ycbcrbuf != 0)
+ _TIFFfreeExt(tif, sp->subsampling_convert_ycbcrbuf);
+ if (sp->subsampling_convert_ycbcrimage != 0)
+ _TIFFfreeExt(tif, sp->subsampling_convert_ycbcrimage);
+ if (sp->skip_buffer != 0)
+ _TIFFfreeExt(tif, sp->skip_buffer);
+ _TIFFfreeExt(tif, sp);
+ tif->tif_data = NULL;
+ _TIFFSetDefaultCompressionState(tif);
+ }
+}
+
+static void OJPEGSubsamplingCorrect(TIFF *tif)
+{
+ static const char module[] = "OJPEGSubsamplingCorrect";
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ uint8_t mh;
+ uint8_t mv;
+
+ assert(sp->subsamplingcorrect_done == 0);
+ if ((tif->tif_dir.td_samplesperpixel != 3) ||
+ ((tif->tif_dir.td_photometric != PHOTOMETRIC_YCBCR) &&
+ (tif->tif_dir.td_photometric != PHOTOMETRIC_ITULAB)))
+ {
+ if (sp->subsampling_tag != 0)
+ TIFFWarningExtR(tif, module,
+ "Subsampling tag not appropriate for this "
+ "Photometric and/or SamplesPerPixel");
+ sp->subsampling_hor = 1;
+ sp->subsampling_ver = 1;
+ sp->subsampling_force_desubsampling_inside_decompression = 0;
+ }
+ else
+ {
+ sp->subsamplingcorrect_done = 1;
+ mh = sp->subsampling_hor;
+ mv = sp->subsampling_ver;
+ sp->subsamplingcorrect = 1;
+ OJPEGReadHeaderInfoSec(tif);
+ if (sp->subsampling_force_desubsampling_inside_decompression != 0)
+ {
+ sp->subsampling_hor = 1;
+ sp->subsampling_ver = 1;
+ }
+ sp->subsamplingcorrect = 0;
+ if (((sp->subsampling_hor != mh) || (sp->subsampling_ver != mv)) &&
+ (sp->subsampling_force_desubsampling_inside_decompression == 0))
+ {
+ if (sp->subsampling_tag == 0)
+ TIFFWarningExtR(
+ tif, module,
+ "Subsampling tag is not set, yet subsampling inside JPEG "
+ "data [%" PRIu8 ",%" PRIu8
+ "] does not match default values [2,2]; assuming "
+ "subsampling inside JPEG data is correct",
+ sp->subsampling_hor, sp->subsampling_ver);
+ else
+ TIFFWarningExtR(
+ tif, module,
+ "Subsampling inside JPEG data [%" PRIu8 ",%" PRIu8
+ "] does not match subsampling tag values [%" PRIu8
+ ",%" PRIu8
+ "]; assuming subsampling inside JPEG data is correct",
+ sp->subsampling_hor, sp->subsampling_ver, mh, mv);
+ }
+ if (sp->subsampling_force_desubsampling_inside_decompression != 0)
+ {
+ if (sp->subsampling_tag == 0)
+ TIFFWarningExtR(
+ tif, module,
+ "Subsampling tag is not set, yet subsampling inside JPEG "
+ "data does not match default values [2,2] (nor any other "
+ "values allowed in TIFF); assuming subsampling inside JPEG "
+ "data is correct and desubsampling inside JPEG "
+ "decompression");
+ else
+ TIFFWarningExtR(
+ tif, module,
+ "Subsampling inside JPEG data does not match subsampling "
+ "tag values [%" PRIu8 ",%" PRIu8
+ "] (nor any other values allowed in TIFF); assuming "
+ "subsampling inside JPEG data is correct and desubsampling "
+ "inside JPEG decompression",
+ mh, mv);
+ }
+ if (sp->subsampling_force_desubsampling_inside_decompression == 0)
+ {
+ if (sp->subsampling_hor < sp->subsampling_ver)
+ TIFFWarningExtR(tif, module,
+ "Subsampling values [%" PRIu8 ",%" PRIu8
+ "] are not allowed in TIFF",
+ sp->subsampling_hor, sp->subsampling_ver);
+ }
+ }
+ sp->subsamplingcorrect_done = 1;
+}
+
+static int OJPEGReadHeaderInfo(TIFF *tif)
+{
+ static const char module[] = "OJPEGReadHeaderInfo";
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ assert(sp->readheader_done == 0);
+ sp->image_width = tif->tif_dir.td_imagewidth;
+ sp->image_length = tif->tif_dir.td_imagelength;
+ if (isTiled(tif))
+ {
+ sp->strile_width = tif->tif_dir.td_tilewidth;
+ sp->strile_length = tif->tif_dir.td_tilelength;
+ sp->strile_length_total =
+ ((sp->image_length + sp->strile_length - 1) / sp->strile_length) *
+ sp->strile_length;
+ }
+ else
+ {
+ sp->strile_width = sp->image_width;
+ sp->strile_length = tif->tif_dir.td_rowsperstrip;
+ if (sp->strile_length == (uint32_t)-1)
+ sp->strile_length = sp->image_length;
+ sp->strile_length_total = sp->image_length;
+ }
+ if (tif->tif_dir.td_samplesperpixel == 1)
+ {
+ sp->samples_per_pixel = 1;
+ sp->plane_sample_offset = 0;
+ sp->samples_per_pixel_per_plane = sp->samples_per_pixel;
+ sp->subsampling_hor = 1;
+ sp->subsampling_ver = 1;
+ }
+ else
+ {
+ if (tif->tif_dir.td_samplesperpixel != 3)
+ {
+ TIFFErrorExtR(tif, module,
+ "SamplesPerPixel %" PRIu8
+ " not supported for this compression scheme",
+ sp->samples_per_pixel);
+ return (0);
+ }
+ sp->samples_per_pixel = 3;
+ sp->plane_sample_offset = 0;
+ if (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG)
+ sp->samples_per_pixel_per_plane = 3;
+ else
+ sp->samples_per_pixel_per_plane = 1;
+ }
+ if (sp->strile_length < sp->image_length)
+ {
+ if (((sp->subsampling_hor != 1) && (sp->subsampling_hor != 2) &&
+ (sp->subsampling_hor != 4)) ||
+ ((sp->subsampling_ver != 1) && (sp->subsampling_ver != 2) &&
+ (sp->subsampling_ver != 4)))
+ {
+ TIFFErrorExtR(tif, module, "Invalid subsampling values");
+ return (0);
+ }
+ if (sp->strile_length % (sp->subsampling_ver * 8) != 0)
+ {
+ TIFFErrorExtR(tif, module,
+ "Incompatible vertical subsampling and image "
+ "strip/tile length");
+ return (0);
+ }
+ sp->restart_interval =
+ (uint16_t)(((sp->strile_width + sp->subsampling_hor * 8 - 1) /
+ (sp->subsampling_hor * 8)) *
+ (sp->strile_length / (sp->subsampling_ver * 8)));
+ }
+ if (OJPEGReadHeaderInfoSec(tif) == 0)
+ return (0);
+ sp->sos_end[0].log = 1;
+ sp->sos_end[0].in_buffer_source = sp->in_buffer_source;
+ sp->sos_end[0].in_buffer_next_strile = sp->in_buffer_next_strile;
+ sp->sos_end[0].in_buffer_file_pos =
+ sp->in_buffer_file_pos - sp->in_buffer_togo;
+ sp->sos_end[0].in_buffer_file_togo =
+ sp->in_buffer_file_togo + sp->in_buffer_togo;
+ sp->readheader_done = 1;
+ return (1);
+}
+
+static int OJPEGReadSecondarySos(TIFF *tif, uint16_t s)
+{
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ uint8_t m;
+ assert(s > 0);
+ assert(s < 3);
+ assert(sp->sos_end[0].log != 0);
+ assert(sp->sos_end[s].log == 0);
+ sp->plane_sample_offset = (uint8_t)(s - 1);
+ while (sp->sos_end[sp->plane_sample_offset].log == 0)
+ sp->plane_sample_offset--;
+ sp->in_buffer_source =
+ sp->sos_end[sp->plane_sample_offset].in_buffer_source;
+ sp->in_buffer_next_strile =
+ sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile;
+ sp->in_buffer_file_pos =
+ sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos;
+ sp->in_buffer_file_pos_log = 0;
+ sp->in_buffer_file_togo =
+ sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo;
+ sp->in_buffer_togo = 0;
+ sp->in_buffer_cur = 0;
+ while (sp->plane_sample_offset < s)
+ {
+ do
+ {
+ if (OJPEGReadByte(sp, &m) == 0)
+ return (0);
+ if (m == 255)
+ {
+ do
+ {
+ if (OJPEGReadByte(sp, &m) == 0)
+ return (0);
+ if (m != 255)
+ break;
+ } while (1);
+ if (m == JPEG_MARKER_SOS)
+ break;
+ }
+ } while (1);
+ sp->plane_sample_offset++;
+ if (OJPEGReadHeaderInfoSecStreamSos(tif) == 0)
+ return (0);
+ sp->sos_end[sp->plane_sample_offset].log = 1;
+ sp->sos_end[sp->plane_sample_offset].in_buffer_source =
+ sp->in_buffer_source;
+ sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile =
+ sp->in_buffer_next_strile;
+ sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos =
+ sp->in_buffer_file_pos - sp->in_buffer_togo;
+ sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo =
+ sp->in_buffer_file_togo + sp->in_buffer_togo;
+ }
+ return (1);
+}
+
+static int OJPEGWriteHeaderInfo(TIFF *tif)
+{
+ static const char module[] = "OJPEGWriteHeaderInfo";
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ uint8_t **m;
+ uint32_t n;
+ /* if a previous attempt failed, don't try again */
+ if (sp->libjpeg_session_active != 0)
+ return 0;
+ sp->out_state = ososSoi;
+ sp->restart_index = 0;
+ jpeg_std_error(&(sp->libjpeg_jpeg_error_mgr));
+ sp->libjpeg_jpeg_error_mgr.output_message =
+ OJPEGLibjpegJpegErrorMgrOutputMessage;
+ sp->libjpeg_jpeg_error_mgr.error_exit = OJPEGLibjpegJpegErrorMgrErrorExit;
+ sp->libjpeg_jpeg_decompress_struct.err = &(sp->libjpeg_jpeg_error_mgr);
+ sp->libjpeg_jpeg_decompress_struct.client_data = (void *)tif;
+ if (jpeg_create_decompress_encap(
+ sp, &(sp->libjpeg_jpeg_decompress_struct)) == 0)
+ return (0);
+ sp->libjpeg_session_active = 1;
+ sp->libjpeg_jpeg_source_mgr.bytes_in_buffer = 0;
+ sp->libjpeg_jpeg_source_mgr.init_source =
+ OJPEGLibjpegJpegSourceMgrInitSource;
+ sp->libjpeg_jpeg_source_mgr.fill_input_buffer =
+ OJPEGLibjpegJpegSourceMgrFillInputBuffer;
+ sp->libjpeg_jpeg_source_mgr.skip_input_data =
+ OJPEGLibjpegJpegSourceMgrSkipInputData;
+ sp->libjpeg_jpeg_source_mgr.resync_to_restart =
+ OJPEGLibjpegJpegSourceMgrResyncToRestart;
+ sp->libjpeg_jpeg_source_mgr.term_source =
+ OJPEGLibjpegJpegSourceMgrTermSource;
+ sp->libjpeg_jpeg_decompress_struct.src = &(sp->libjpeg_jpeg_source_mgr);
+ if (jpeg_read_header_encap(sp, &(sp->libjpeg_jpeg_decompress_struct), 1) ==
+ 0)
+ return (0);
+ if ((sp->subsampling_force_desubsampling_inside_decompression == 0) &&
+ (sp->samples_per_pixel_per_plane > 1))
+ {
+ sp->libjpeg_jpeg_decompress_struct.raw_data_out = 1;
+#if JPEG_LIB_VERSION >= 70
+ sp->libjpeg_jpeg_decompress_struct.do_fancy_upsampling = FALSE;
+#endif
+ sp->libjpeg_jpeg_query_style = 0;
+ if (sp->subsampling_convert_log == 0)
+ {
+ assert(sp->subsampling_convert_ycbcrbuf == 0);
+ assert(sp->subsampling_convert_ycbcrimage == 0);
+ /* Check for division by zero. */
+ if (sp->subsampling_hor == 0 || sp->subsampling_ver == 0)
+ return (0);
+ sp->subsampling_convert_ylinelen =
+ ((sp->strile_width + sp->subsampling_hor * 8 - 1) /
+ (sp->subsampling_hor * 8) * sp->subsampling_hor * 8);
+ sp->subsampling_convert_ylines = sp->subsampling_ver * 8;
+ sp->subsampling_convert_clinelen =
+ sp->subsampling_convert_ylinelen / sp->subsampling_hor;
+ sp->subsampling_convert_clines = 8;
+ sp->subsampling_convert_ybuflen = sp->subsampling_convert_ylinelen *
+ sp->subsampling_convert_ylines;
+ sp->subsampling_convert_cbuflen = sp->subsampling_convert_clinelen *
+ sp->subsampling_convert_clines;
+ sp->subsampling_convert_ycbcrbuflen =
+ sp->subsampling_convert_ybuflen +
+ 2 * sp->subsampling_convert_cbuflen;
+ /* The calloc is not normally necessary, except in some edge/broken
+ * cases */
+ /* for example for a tiled image of height 1 with a tile height of 1
+ * and subsampling_hor=subsampling_ver=2 */
+ /* In that case, libjpeg will only fill the 8 first lines of the 16
+ * lines */
+ /* See https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16844
+ */
+ /* Even if this case is allowed (?), its handling is broken because
+ * OJPEGPreDecode() should also likely */
+ /* reset subsampling_convert_state to 0 when changing tile. */
+ sp->subsampling_convert_ycbcrbuf =
+ _TIFFcallocExt(tif, 1, sp->subsampling_convert_ycbcrbuflen);
+ if (sp->subsampling_convert_ycbcrbuf == 0)
+ {
+ TIFFErrorExtR(tif, module, "Out of memory");
+ return (0);
+ }
+ sp->subsampling_convert_ybuf = sp->subsampling_convert_ycbcrbuf;
+ sp->subsampling_convert_cbbuf =
+ sp->subsampling_convert_ybuf + sp->subsampling_convert_ybuflen;
+ sp->subsampling_convert_crbuf =
+ sp->subsampling_convert_cbbuf + sp->subsampling_convert_cbuflen;
+ sp->subsampling_convert_ycbcrimagelen =
+ 3 + sp->subsampling_convert_ylines +
+ 2 * sp->subsampling_convert_clines;
+ sp->subsampling_convert_ycbcrimage = _TIFFmallocExt(
+ tif, sp->subsampling_convert_ycbcrimagelen * sizeof(uint8_t *));
+ if (sp->subsampling_convert_ycbcrimage == 0)
+ {
+ TIFFErrorExtR(tif, module, "Out of memory");
+ return (0);
+ }
+ m = sp->subsampling_convert_ycbcrimage;
+ *m++ = (uint8_t *)(sp->subsampling_convert_ycbcrimage + 3);
+ *m++ = (uint8_t *)(sp->subsampling_convert_ycbcrimage + 3 +
+ sp->subsampling_convert_ylines);
+ *m++ = (uint8_t *)(sp->subsampling_convert_ycbcrimage + 3 +
+ sp->subsampling_convert_ylines +
+ sp->subsampling_convert_clines);
+ for (n = 0; n < sp->subsampling_convert_ylines; n++)
+ *m++ = sp->subsampling_convert_ybuf +
+ n * sp->subsampling_convert_ylinelen;
+ for (n = 0; n < sp->subsampling_convert_clines; n++)
+ *m++ = sp->subsampling_convert_cbbuf +
+ n * sp->subsampling_convert_clinelen;
+ for (n = 0; n < sp->subsampling_convert_clines; n++)
+ *m++ = sp->subsampling_convert_crbuf +
+ n * sp->subsampling_convert_clinelen;
+ sp->subsampling_convert_clinelenout =
+ sp->strile_width / sp->subsampling_hor +
+ ((sp->strile_width % sp->subsampling_hor) != 0 ? 1 : 0);
+ sp->subsampling_convert_state = 0;
+ sp->error_in_raw_data_decoding = 0;
+ sp->bytes_per_line =
+ sp->subsampling_convert_clinelenout *
+ (sp->subsampling_ver * sp->subsampling_hor + 2);
+ sp->lines_per_strile =
+ sp->strile_length / sp->subsampling_ver +
+ ((sp->strile_length % sp->subsampling_ver) != 0 ? 1 : 0);
+ sp->subsampling_convert_log = 1;
+ }
+ }
+ else
+ {
+ sp->libjpeg_jpeg_decompress_struct.jpeg_color_space = JCS_UNKNOWN;
+ sp->libjpeg_jpeg_decompress_struct.out_color_space = JCS_UNKNOWN;
+ sp->libjpeg_jpeg_query_style = 1;
+ sp->bytes_per_line = sp->samples_per_pixel_per_plane * sp->strile_width;
+ sp->lines_per_strile = sp->strile_length;
+ }
+ if (jpeg_start_decompress_encap(sp,
+ &(sp->libjpeg_jpeg_decompress_struct)) == 0)
+ return (0);
+ if (sp->libjpeg_jpeg_decompress_struct.image_width != sp->strile_width)
+ {
+ TIFFErrorExtR(tif, module,
+ "jpeg_start_decompress() returned image_width = %u, "
+ "expected %" PRIu32,
+ sp->libjpeg_jpeg_decompress_struct.image_width,
+ sp->strile_width);
+ return 0;
+ }
+ if (sp->libjpeg_jpeg_decompress_struct.max_h_samp_factor !=
+ sp->subsampling_hor ||
+ sp->libjpeg_jpeg_decompress_struct.max_v_samp_factor !=
+ sp->subsampling_ver)
+ {
+ TIFFErrorExtR(tif, module,
+ "jpeg_start_decompress() returned max_h_samp_factor = %d "
+ "and max_v_samp_factor = %d, expected %" PRIu8
+ " and %" PRIu8,
+ sp->libjpeg_jpeg_decompress_struct.max_h_samp_factor,
+ sp->libjpeg_jpeg_decompress_struct.max_v_samp_factor,
+ sp->subsampling_hor, sp->subsampling_ver);
+ return 0;
+ }
+
+ sp->writeheader_done = 1;
+ return (1);
+}
+
+static void OJPEGLibjpegSessionAbort(TIFF *tif)
+{
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ assert(sp->libjpeg_session_active != 0);
+ jpeg_destroy((jpeg_common_struct *)(&(sp->libjpeg_jpeg_decompress_struct)));
+ sp->libjpeg_session_active = 0;
+}
+
+static int OJPEGReadHeaderInfoSec(TIFF *tif)
+{
+ static const char module[] = "OJPEGReadHeaderInfoSec";
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ uint8_t m;
+ uint16_t n;
+ uint8_t o;
+ if (sp->file_size == 0)
+ sp->file_size = TIFFGetFileSize(tif);
+ if (sp->jpeg_interchange_format != 0)
+ {
+ if (sp->jpeg_interchange_format >= sp->file_size)
+ {
+ sp->jpeg_interchange_format = 0;
+ sp->jpeg_interchange_format_length = 0;
+ }
+ else
+ {
+ if ((sp->jpeg_interchange_format_length == 0) ||
+ (sp->jpeg_interchange_format >
+ UINT64_MAX - sp->jpeg_interchange_format_length) ||
+ (sp->jpeg_interchange_format +
+ sp->jpeg_interchange_format_length >
+ sp->file_size))
+ sp->jpeg_interchange_format_length =
+ sp->file_size - sp->jpeg_interchange_format;
+ }
+ }
+ sp->in_buffer_source = osibsNotSetYet;
+ sp->in_buffer_next_strile = 0;
+ sp->in_buffer_strile_count = tif->tif_dir.td_nstrips;
+ sp->in_buffer_file_togo = 0;
+ sp->in_buffer_togo = 0;
+ do
+ {
+ if (OJPEGReadBytePeek(sp, &m) == 0)
+ return (0);
+ if (m != 255)
+ break;
+ OJPEGReadByteAdvance(sp);
+ do
+ {
+ if (OJPEGReadByte(sp, &m) == 0)
+ return (0);
+ } while (m == 255);
+ 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:
+ /* this type of marker has data, but it has no use to us (and no
+ * place here) and should be skipped */
+ if (OJPEGReadWord(sp, &n) == 0)
+ return (0);
+ if (n < 2)
+ {
+ if (sp->subsamplingcorrect == 0)
+ TIFFErrorExtR(tif, module, "Corrupt JPEG data");
+ return (0);
+ }
+ if (n > 2)
+ OJPEGReadSkip(sp, n - 2);
+ break;
+ case JPEG_MARKER_DRI:
+ if (OJPEGReadHeaderInfoSecStreamDri(tif) == 0)
+ return (0);
+ break;
+ case JPEG_MARKER_DQT:
+ if (OJPEGReadHeaderInfoSecStreamDqt(tif) == 0)
+ return (0);
+ break;
+ case JPEG_MARKER_DHT:
+ if (OJPEGReadHeaderInfoSecStreamDht(tif) == 0)
+ return (0);
+ break;
+ case JPEG_MARKER_SOF0:
+ case JPEG_MARKER_SOF1:
+ case JPEG_MARKER_SOF3:
+ if (OJPEGReadHeaderInfoSecStreamSof(tif, m) == 0)
+ return (0);
+ if (sp->subsamplingcorrect != 0)
+ return (1);
+ break;
+ case JPEG_MARKER_SOS:
+ if (sp->subsamplingcorrect != 0)
+ return (1);
+ assert(sp->plane_sample_offset == 0);
+ if (OJPEGReadHeaderInfoSecStreamSos(tif) == 0)
+ return (0);
+ break;
+ default:
+ TIFFErrorExtR(tif, module,
+ "Unknown marker type %" PRIu8 " in JPEG data", m);
+ return (0);
+ }
+ } while (m != JPEG_MARKER_SOS);
+ if (sp->subsamplingcorrect)
+ return (1);
+ if (sp->sof_log == 0)
+ {
+ if (OJPEGReadHeaderInfoSecTablesQTable(tif) == 0)
+ return (0);
+ sp->sof_marker_id = JPEG_MARKER_SOF0;
+ for (o = 0; o < sp->samples_per_pixel; o++)
+ sp->sof_c[o] = o;
+ sp->sof_hv[0] = ((sp->subsampling_hor << 4) | sp->subsampling_ver);
+ for (o = 1; o < sp->samples_per_pixel; o++)
+ sp->sof_hv[o] = 17;
+ sp->sof_x = sp->strile_width;
+ sp->sof_y = sp->strile_length_total;
+ sp->sof_log = 1;
+ if (OJPEGReadHeaderInfoSecTablesDcTable(tif) == 0)
+ return (0);
+ if (OJPEGReadHeaderInfoSecTablesAcTable(tif) == 0)
+ return (0);
+ for (o = 1; o < sp->samples_per_pixel; o++)
+ sp->sos_cs[o] = o;
+ }
+ return (1);
+}
+
+static int OJPEGReadHeaderInfoSecStreamDri(TIFF *tif)
+{
+ /* This could easily cause trouble in some cases... but no such cases have
+ occurred so far */
+ static const char module[] = "OJPEGReadHeaderInfoSecStreamDri";
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ uint16_t m;
+ if (OJPEGReadWord(sp, &m) == 0)
+ return (0);
+ if (m != 4)
+ {
+ TIFFErrorExtR(tif, module, "Corrupt DRI marker in JPEG data");
+ return (0);
+ }
+ if (OJPEGReadWord(sp, &m) == 0)
+ return (0);
+ sp->restart_interval = m;
+ return (1);
+}
+
+static int OJPEGReadHeaderInfoSecStreamDqt(TIFF *tif)
+{
+ /* this is a table marker, and it is to be saved as a whole for exact
+ * pushing on the jpeg stream later on */
+ static const char module[] = "OJPEGReadHeaderInfoSecStreamDqt";
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ uint16_t m;
+ uint32_t na;
+ uint8_t *nb;
+ uint8_t o;
+ if (OJPEGReadWord(sp, &m) == 0)
+ return (0);
+ if (m <= 2)
+ {
+ if (sp->subsamplingcorrect == 0)
+ TIFFErrorExtR(tif, module, "Corrupt DQT marker in JPEG data");
+ return (0);
+ }
+ if (sp->subsamplingcorrect != 0)
+ OJPEGReadSkip(sp, m - 2);
+ else
+ {
+ m -= 2;
+ do
+ {
+ if (m < 65)
+ {
+ TIFFErrorExtR(tif, module, "Corrupt DQT marker in JPEG data");
+ return (0);
+ }
+ na = sizeof(uint32_t) + 69;
+ nb = _TIFFmallocExt(tif, na);
+ if (nb == 0)
+ {
+ TIFFErrorExtR(tif, module, "Out of memory");
+ return (0);
+ }
+ *(uint32_t *)nb = na;
+ nb[sizeof(uint32_t)] = 255;
+ nb[sizeof(uint32_t) + 1] = JPEG_MARKER_DQT;
+ nb[sizeof(uint32_t) + 2] = 0;
+ nb[sizeof(uint32_t) + 3] = 67;
+ if (OJPEGReadBlock(sp, 65, &nb[sizeof(uint32_t) + 4]) == 0)
+ {
+ _TIFFfreeExt(tif, nb);
+ return (0);
+ }
+ o = nb[sizeof(uint32_t) + 4] & 15;
+ if (3 < o)
+ {
+ TIFFErrorExtR(tif, module, "Corrupt DQT marker in JPEG data");
+ _TIFFfreeExt(tif, nb);
+ return (0);
+ }
+ if (sp->qtable[o] != 0)
+ _TIFFfreeExt(tif, sp->qtable[o]);
+ sp->qtable[o] = nb;
+ m -= 65;
+ } while (m > 0);
+ }
+ return (1);
+}
+
+static int OJPEGReadHeaderInfoSecStreamDht(TIFF *tif)
+{
+ /* this is a table marker, and it is to be saved as a whole for exact
+ * pushing on the jpeg stream later on */
+ /* TODO: the following assumes there is only one table in this marker... but
+ * i'm not quite sure that assumption is guaranteed correct */
+ static const char module[] = "OJPEGReadHeaderInfoSecStreamDht";
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ uint16_t m;
+ uint32_t na;
+ uint8_t *nb;
+ uint8_t o;
+ if (OJPEGReadWord(sp, &m) == 0)
+ return (0);
+ if (m <= 2)
+ {
+ if (sp->subsamplingcorrect == 0)
+ TIFFErrorExtR(tif, module, "Corrupt DHT marker in JPEG data");
+ return (0);
+ }
+ if (sp->subsamplingcorrect != 0)
+ {
+ OJPEGReadSkip(sp, m - 2);
+ }
+ else
+ {
+ na = sizeof(uint32_t) + 2 + m;
+ nb = _TIFFmallocExt(tif, na);
+ if (nb == 0)
+ {
+ TIFFErrorExtR(tif, module, "Out of memory");
+ return (0);
+ }
+ *(uint32_t *)nb = na;
+ nb[sizeof(uint32_t)] = 255;
+ nb[sizeof(uint32_t) + 1] = JPEG_MARKER_DHT;
+ nb[sizeof(uint32_t) + 2] = (m >> 8);
+ nb[sizeof(uint32_t) + 3] = (m & 255);
+ if (OJPEGReadBlock(sp, m - 2, &nb[sizeof(uint32_t) + 4]) == 0)
+ {
+ _TIFFfreeExt(tif, nb);
+ return (0);
+ }
+ o = nb[sizeof(uint32_t) + 4];
+ if ((o & 240) == 0)
+ {
+ if (3 < o)
+ {
+ TIFFErrorExtR(tif, module, "Corrupt DHT marker in JPEG data");
+ _TIFFfreeExt(tif, nb);
+ return (0);
+ }
+ if (sp->dctable[o] != 0)
+ _TIFFfreeExt(tif, sp->dctable[o]);
+ sp->dctable[o] = nb;
+ }
+ else
+ {
+ if ((o & 240) != 16)
+ {
+ TIFFErrorExtR(tif, module, "Corrupt DHT marker in JPEG data");
+ _TIFFfreeExt(tif, nb);
+ return (0);
+ }
+ o &= 15;
+ if (3 < o)
+ {
+ TIFFErrorExtR(tif, module, "Corrupt DHT marker in JPEG data");
+ _TIFFfreeExt(tif, nb);
+ return (0);
+ }
+ if (sp->actable[o] != 0)
+ _TIFFfreeExt(tif, sp->actable[o]);
+ sp->actable[o] = nb;
+ }
+ }
+ return (1);
+}
+
+static int OJPEGReadHeaderInfoSecStreamSof(TIFF *tif, uint8_t marker_id)
+{
+ /* this marker needs to be checked, and part of its data needs to be saved
+ * for regeneration later on */
+ static const char module[] = "OJPEGReadHeaderInfoSecStreamSof";
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ uint16_t m;
+ uint16_t n;
+ uint8_t o;
+ uint16_t p;
+ uint16_t q;
+ if (sp->sof_log != 0)
+ {
+ TIFFErrorExtR(tif, module, "Corrupt JPEG data");
+ return (0);
+ }
+ if (sp->subsamplingcorrect == 0)
+ sp->sof_marker_id = marker_id;
+ /* Lf: data length */
+ if (OJPEGReadWord(sp, &m) == 0)
+ return (0);
+ if (m < 11)
+ {
+ if (sp->subsamplingcorrect == 0)
+ TIFFErrorExtR(tif, module, "Corrupt SOF marker in JPEG data");
+ return (0);
+ }
+ m -= 8;
+ if (m % 3 != 0)
+ {
+ if (sp->subsamplingcorrect == 0)
+ TIFFErrorExtR(tif, module, "Corrupt SOF marker in JPEG data");
+ return (0);
+ }
+ n = m / 3;
+ if (sp->subsamplingcorrect == 0)
+ {
+ if (n != sp->samples_per_pixel)
+ {
+ TIFFErrorExtR(
+ tif, module,
+ "JPEG compressed data indicates unexpected number of samples");
+ return (0);
+ }
+ }
+ /* P: Sample precision */
+ if (OJPEGReadByte(sp, &o) == 0)
+ return (0);
+ if (o != 8)
+ {
+ if (sp->subsamplingcorrect == 0)
+ TIFFErrorExtR(tif, module,
+ "JPEG compressed data indicates unexpected number of "
+ "bits per sample");
+ return (0);
+ }
+ /* Y: Number of lines, X: Number of samples per line */
+ if (sp->subsamplingcorrect)
+ OJPEGReadSkip(sp, 4);
+ else
+ {
+ /* Y: Number of lines */
+ if (OJPEGReadWord(sp, &p) == 0)
+ return (0);
+ if (((uint32_t)p < sp->image_length) &&
+ ((uint32_t)p < sp->strile_length_total))
+ {
+ TIFFErrorExtR(tif, module,
+ "JPEG compressed data indicates unexpected height");
+ return (0);
+ }
+ sp->sof_y = p;
+ /* X: Number of samples per line */
+ if (OJPEGReadWord(sp, &p) == 0)
+ return (0);
+ if (((uint32_t)p < sp->image_width) && ((uint32_t)p < sp->strile_width))
+ {
+ TIFFErrorExtR(tif, module,
+ "JPEG compressed data indicates unexpected width");
+ return (0);
+ }
+ if ((uint32_t)p > sp->strile_width)
+ {
+ TIFFErrorExtR(tif, module,
+ "JPEG compressed data image width exceeds expected "
+ "image width");
+ return (0);
+ }
+ sp->sof_x = p;
+ }
+ /* Nf: Number of image components in frame */
+ if (OJPEGReadByte(sp, &o) == 0)
+ return (0);
+ if (o != n)
+ {
+ if (sp->subsamplingcorrect == 0)
+ TIFFErrorExtR(tif, module, "Corrupt SOF marker in JPEG data");
+ return (0);
+ }
+ /* per component stuff */
+ /* TODO: double-check that flow implies that n cannot be as big as to make
+ * us overflow sof_c, sof_hv and sof_tq arrays */
+ for (q = 0; q < n; q++)
+ {
+ /* C: Component identifier */
+ if (OJPEGReadByte(sp, &o) == 0)
+ return (0);
+ if (sp->subsamplingcorrect == 0)
+ sp->sof_c[q] = o;
+ /* H: Horizontal sampling factor, and V: Vertical sampling factor */
+ if (OJPEGReadByte(sp, &o) == 0)
+ return (0);
+ if (sp->subsamplingcorrect != 0)
+ {
+ if (q == 0)
+ {
+ sp->subsampling_hor = (o >> 4);
+ sp->subsampling_ver = (o & 15);
+ if (((sp->subsampling_hor != 1) && (sp->subsampling_hor != 2) &&
+ (sp->subsampling_hor != 4)) ||
+ ((sp->subsampling_ver != 1) && (sp->subsampling_ver != 2) &&
+ (sp->subsampling_ver != 4)))
+ sp->subsampling_force_desubsampling_inside_decompression =
+ 1;
+ }
+ else
+ {
+ if (o != 17)
+ sp->subsampling_force_desubsampling_inside_decompression =
+ 1;
+ }
+ }
+ else
+ {
+ sp->sof_hv[q] = o;
+ if (sp->subsampling_force_desubsampling_inside_decompression == 0)
+ {
+ if (q == 0)
+ {
+ if (o != ((sp->subsampling_hor << 4) | sp->subsampling_ver))
+ {
+ TIFFErrorExtR(tif, module,
+ "JPEG compressed data indicates "
+ "unexpected subsampling values");
+ return (0);
+ }
+ }
+ else
+ {
+ if (o != 17)
+ {
+ TIFFErrorExtR(tif, module,
+ "JPEG compressed data indicates "
+ "unexpected subsampling values");
+ return (0);
+ }
+ }
+ }
+ }
+ /* Tq: Quantization table destination selector */
+ if (OJPEGReadByte(sp, &o) == 0)
+ return (0);
+ if (sp->subsamplingcorrect == 0)
+ sp->sof_tq[q] = o;
+ }
+ if (sp->subsamplingcorrect == 0)
+ sp->sof_log = 1;
+ return (1);
+}
+
+static int OJPEGReadHeaderInfoSecStreamSos(TIFF *tif)
+{
+ /* this marker needs to be checked, and part of its data needs to be saved
+ * for regeneration later on */
+ static const char module[] = "OJPEGReadHeaderInfoSecStreamSos";
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ uint16_t m;
+ uint8_t n;
+ uint8_t o;
+ assert(sp->subsamplingcorrect == 0);
+ if (sp->sof_log == 0)
+ {
+ TIFFErrorExtR(tif, module, "Corrupt SOS marker in JPEG data");
+ return (0);
+ }
+ /* Ls */
+ if (OJPEGReadWord(sp, &m) == 0)
+ return (0);
+ if (m != 6 + sp->samples_per_pixel_per_plane * 2)
+ {
+ TIFFErrorExtR(tif, module, "Corrupt SOS marker in JPEG data");
+ return (0);
+ }
+ /* Ns */
+ if (OJPEGReadByte(sp, &n) == 0)
+ return (0);
+ if (n != sp->samples_per_pixel_per_plane)
+ {
+ TIFFErrorExtR(tif, module, "Corrupt SOS marker in JPEG data");
+ return (0);
+ }
+ /* Cs, Td, and Ta */
+ for (o = 0; o < sp->samples_per_pixel_per_plane; o++)
+ {
+ /* Cs */
+ if (OJPEGReadByte(sp, &n) == 0)
+ return (0);
+ sp->sos_cs[sp->plane_sample_offset + o] = n;
+ /* Td and Ta */
+ if (OJPEGReadByte(sp, &n) == 0)
+ return (0);
+ sp->sos_tda[sp->plane_sample_offset + o] = n;
+ }
+ /* skip Ss, Se, Ah, en Al -> no check, as per Tom Lane recommendation, as
+ * per LibJpeg source */
+ OJPEGReadSkip(sp, 3);
+ return (1);
+}
+
+static int OJPEGReadHeaderInfoSecTablesQTable(TIFF *tif)
+{
+ static const char module[] = "OJPEGReadHeaderInfoSecTablesQTable";
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ uint8_t m;
+ uint8_t n;
+ uint32_t oa;
+ uint8_t *ob;
+ uint32_t p;
+ if (sp->qtable_offset[0] == 0)
+ {
+ TIFFErrorExtR(tif, module, "Missing JPEG tables");
+ return (0);
+ }
+ sp->in_buffer_file_pos_log = 0;
+ for (m = 0; m < sp->samples_per_pixel; m++)
+ {
+ if ((sp->qtable_offset[m] != 0) &&
+ ((m == 0) || (sp->qtable_offset[m] != sp->qtable_offset[m - 1])))
+ {
+ for (n = 0; n < m - 1; n++)
+ {
+ if (sp->qtable_offset[m] == sp->qtable_offset[n])
+ {
+ TIFFErrorExtR(tif, module, "Corrupt JpegQTables tag value");
+ return (0);
+ }
+ }
+ oa = sizeof(uint32_t) + 69;
+ ob = _TIFFmallocExt(tif, oa);
+ if (ob == 0)
+ {
+ TIFFErrorExtR(tif, module, "Out of memory");
+ return (0);
+ }
+ *(uint32_t *)ob = oa;
+ ob[sizeof(uint32_t)] = 255;
+ ob[sizeof(uint32_t) + 1] = JPEG_MARKER_DQT;
+ ob[sizeof(uint32_t) + 2] = 0;
+ ob[sizeof(uint32_t) + 3] = 67;
+ ob[sizeof(uint32_t) + 4] = m;
+ TIFFSeekFile(tif, sp->qtable_offset[m], SEEK_SET);
+ p = (uint32_t)TIFFReadFile(tif, &ob[sizeof(uint32_t) + 5], 64);
+ if (p != 64)
+ {
+ _TIFFfreeExt(tif, ob);
+ return (0);
+ }
+ if (sp->qtable[m] != 0)
+ _TIFFfreeExt(tif, sp->qtable[m]);
+ sp->qtable[m] = ob;
+ sp->sof_tq[m] = m;
+ }
+ else
+ sp->sof_tq[m] = sp->sof_tq[m - 1];
+ }
+ return (1);
+}
+
+static int OJPEGReadHeaderInfoSecTablesDcTable(TIFF *tif)
+{
+ static const char module[] = "OJPEGReadHeaderInfoSecTablesDcTable";
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ uint8_t m;
+ uint8_t n;
+ uint8_t o[16];
+ uint32_t p;
+ uint32_t q;
+ uint32_t ra;
+ uint8_t *rb;
+ if (sp->dctable_offset[0] == 0)
+ {
+ TIFFErrorExtR(tif, module, "Missing JPEG tables");
+ return (0);
+ }
+ sp->in_buffer_file_pos_log = 0;
+ for (m = 0; m < sp->samples_per_pixel; m++)
+ {
+ if ((sp->dctable_offset[m] != 0) &&
+ ((m == 0) || (sp->dctable_offset[m] != sp->dctable_offset[m - 1])))
+ {
+ for (n = 0; n < m - 1; n++)
+ {
+ if (sp->dctable_offset[m] == sp->dctable_offset[n])
+ {
+ TIFFErrorExtR(tif, module,
+ "Corrupt JpegDcTables tag value");
+ return (0);
+ }
+ }
+ TIFFSeekFile(tif, sp->dctable_offset[m], SEEK_SET);
+ p = (uint32_t)TIFFReadFile(tif, o, 16);
+ if (p != 16)
+ return (0);
+ q = 0;
+ for (n = 0; n < 16; n++)
+ q += o[n];
+ ra = sizeof(uint32_t) + 21 + q;
+ rb = _TIFFmallocExt(tif, ra);
+ if (rb == 0)
+ {
+ TIFFErrorExtR(tif, module, "Out of memory");
+ return (0);
+ }
+ *(uint32_t *)rb = ra;
+ rb[sizeof(uint32_t)] = 255;
+ rb[sizeof(uint32_t) + 1] = JPEG_MARKER_DHT;
+ rb[sizeof(uint32_t) + 2] = (uint8_t)((19 + q) >> 8);
+ rb[sizeof(uint32_t) + 3] = ((19 + q) & 255);
+ rb[sizeof(uint32_t) + 4] = m;
+ for (n = 0; n < 16; n++)
+ rb[sizeof(uint32_t) + 5 + n] = o[n];
+ p = (uint32_t)TIFFReadFile(tif, &(rb[sizeof(uint32_t) + 21]), q);
+ if (p != q)
+ {
+ _TIFFfreeExt(tif, rb);
+ return (0);
+ }
+ if (sp->dctable[m] != 0)
+ _TIFFfreeExt(tif, sp->dctable[m]);
+ sp->dctable[m] = rb;
+ sp->sos_tda[m] = (m << 4);
+ }
+ else
+ sp->sos_tda[m] = sp->sos_tda[m - 1];
+ }
+ return (1);
+}
+
+static int OJPEGReadHeaderInfoSecTablesAcTable(TIFF *tif)
+{
+ static const char module[] = "OJPEGReadHeaderInfoSecTablesAcTable";
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ uint8_t m;
+ uint8_t n;
+ uint8_t o[16];
+ uint32_t p;
+ uint32_t q;
+ uint32_t ra;
+ uint8_t *rb;
+ if (sp->actable_offset[0] == 0)
+ {
+ TIFFErrorExtR(tif, module, "Missing JPEG tables");
+ return (0);
+ }
+ sp->in_buffer_file_pos_log = 0;
+ for (m = 0; m < sp->samples_per_pixel; m++)
+ {
+ if ((sp->actable_offset[m] != 0) &&
+ ((m == 0) || (sp->actable_offset[m] != sp->actable_offset[m - 1])))
+ {
+ for (n = 0; n < m - 1; n++)
+ {
+ if (sp->actable_offset[m] == sp->actable_offset[n])
+ {
+ TIFFErrorExtR(tif, module,
+ "Corrupt JpegAcTables tag value");
+ return (0);
+ }
+ }
+ TIFFSeekFile(tif, sp->actable_offset[m], SEEK_SET);
+ p = (uint32_t)TIFFReadFile(tif, o, 16);
+ if (p != 16)
+ return (0);
+ q = 0;
+ for (n = 0; n < 16; n++)
+ q += o[n];
+ ra = sizeof(uint32_t) + 21 + q;
+ rb = _TIFFmallocExt(tif, ra);
+ if (rb == 0)
+ {
+ TIFFErrorExtR(tif, module, "Out of memory");
+ return (0);
+ }
+ *(uint32_t *)rb = ra;
+ rb[sizeof(uint32_t)] = 255;
+ rb[sizeof(uint32_t) + 1] = JPEG_MARKER_DHT;
+ rb[sizeof(uint32_t) + 2] = (uint8_t)((19 + q) >> 8);
+ rb[sizeof(uint32_t) + 3] = ((19 + q) & 255);
+ rb[sizeof(uint32_t) + 4] = (16 | m);
+ for (n = 0; n < 16; n++)
+ rb[sizeof(uint32_t) + 5 + n] = o[n];
+ p = (uint32_t)TIFFReadFile(tif, &(rb[sizeof(uint32_t) + 21]), q);
+ if (p != q)
+ {
+ _TIFFfreeExt(tif, rb);
+ return (0);
+ }
+ if (sp->actable[m] != 0)
+ _TIFFfreeExt(tif, sp->actable[m]);
+ sp->actable[m] = rb;
+ sp->sos_tda[m] = (sp->sos_tda[m] | m);
+ }
+ else
+ sp->sos_tda[m] = (sp->sos_tda[m] | (sp->sos_tda[m - 1] & 15));
+ }
+ return (1);
+}
+
+static int OJPEGReadBufferFill(OJPEGState *sp)
+{
+ uint16_t m;
+ tmsize_t n;
+ /* TODO: double-check: when subsamplingcorrect is set, no call to
+ * TIFFErrorExt or TIFFWarningExt should be made in any other case, seek or
+ * read errors should be passed through */
+ do
+ {
+ if (sp->in_buffer_file_togo != 0)
+ {
+ if (sp->in_buffer_file_pos_log == 0)
+ {
+ TIFFSeekFile(sp->tif, sp->in_buffer_file_pos, SEEK_SET);
+ sp->in_buffer_file_pos_log = 1;
+ }
+ m = OJPEG_BUFFER;
+ if ((uint64_t)m > sp->in_buffer_file_togo)
+ m = (uint16_t)sp->in_buffer_file_togo;
+ n = TIFFReadFile(sp->tif, sp->in_buffer, (tmsize_t)m);
+ if (n == 0)
+ return (0);
+ assert(n > 0);
+ assert(n <= OJPEG_BUFFER);
+ assert(n < 65536);
+ assert((uint64_t)n <= sp->in_buffer_file_togo);
+ m = (uint16_t)n;
+ sp->in_buffer_togo = m;
+ sp->in_buffer_cur = sp->in_buffer;
+ sp->in_buffer_file_togo -= m;
+ sp->in_buffer_file_pos += m;
+ break;
+ }
+ sp->in_buffer_file_pos_log = 0;
+ switch (sp->in_buffer_source)
+ {
+ case osibsNotSetYet:
+ if (sp->jpeg_interchange_format != 0)
+ {
+ sp->in_buffer_file_pos = sp->jpeg_interchange_format;
+ sp->in_buffer_file_togo =
+ sp->jpeg_interchange_format_length;
+ }
+ sp->in_buffer_source = osibsJpegInterchangeFormat;
+ break;
+ case osibsJpegInterchangeFormat:
+ sp->in_buffer_source = osibsStrile;
+ break;
+ case osibsStrile:
+ if (sp->in_buffer_next_strile == sp->in_buffer_strile_count)
+ sp->in_buffer_source = osibsEof;
+ else
+ {
+ int err = 0;
+ sp->in_buffer_file_pos = TIFFGetStrileOffsetWithErr(
+ sp->tif, sp->in_buffer_next_strile, &err);
+ if (err)
+ return 0;
+ if (sp->in_buffer_file_pos != 0)
+ {
+ uint64_t bytecount = TIFFGetStrileByteCountWithErr(
+ sp->tif, sp->in_buffer_next_strile, &err);
+ if (err)
+ return 0;
+ if (sp->in_buffer_file_pos >= sp->file_size)
+ sp->in_buffer_file_pos = 0;
+ else if (bytecount == 0)
+ sp->in_buffer_file_togo =
+ sp->file_size - sp->in_buffer_file_pos;
+ else
+ {
+ sp->in_buffer_file_togo = bytecount;
+ if (sp->in_buffer_file_togo == 0)
+ sp->in_buffer_file_pos = 0;
+ else if (sp->in_buffer_file_pos >
+ UINT64_MAX - sp->in_buffer_file_togo ||
+ sp->in_buffer_file_pos +
+ sp->in_buffer_file_togo >
+ sp->file_size)
+ sp->in_buffer_file_togo =
+ sp->file_size - sp->in_buffer_file_pos;
+ }
+ }
+ sp->in_buffer_next_strile++;
+ }
+ break;
+ default:
+ return (0);
+ }
+ } while (1);
+ return (1);
+}
+
+static int OJPEGReadByte(OJPEGState *sp, uint8_t *byte)
+{
+ if (sp->in_buffer_togo == 0)
+ {
+ if (OJPEGReadBufferFill(sp) == 0)
+ return (0);
+ assert(sp->in_buffer_togo > 0);
+ }
+ *byte = *(sp->in_buffer_cur);
+ sp->in_buffer_cur++;
+ sp->in_buffer_togo--;
+ return (1);
+}
+
+static int OJPEGReadBytePeek(OJPEGState *sp, uint8_t *byte)
+{
+ if (sp->in_buffer_togo == 0)
+ {
+ if (OJPEGReadBufferFill(sp) == 0)
+ return (0);
+ assert(sp->in_buffer_togo > 0);
+ }
+ *byte = *(sp->in_buffer_cur);
+ return (1);
+}
+
+static void OJPEGReadByteAdvance(OJPEGState *sp)
+{
+ assert(sp->in_buffer_togo > 0);
+ sp->in_buffer_cur++;
+ sp->in_buffer_togo--;
+}
+
+static int OJPEGReadWord(OJPEGState *sp, uint16_t *word)
+{
+ uint8_t m;
+ if (OJPEGReadByte(sp, &m) == 0)
+ return (0);
+ *word = (m << 8);
+ if (OJPEGReadByte(sp, &m) == 0)
+ return (0);
+ *word |= m;
+ return (1);
+}
+
+static int OJPEGReadBlock(OJPEGState *sp, uint16_t len, void *mem)
+{
+ uint16_t mlen;
+ uint8_t *mmem;
+ uint16_t n;
+ assert(len > 0);
+ mlen = len;
+ mmem = mem;
+ do
+ {
+ if (sp->in_buffer_togo == 0)
+ {
+ if (OJPEGReadBufferFill(sp) == 0)
+ return (0);
+ assert(sp->in_buffer_togo > 0);
+ }
+ n = mlen;
+ if (n > sp->in_buffer_togo)
+ n = sp->in_buffer_togo;
+ _TIFFmemcpy(mmem, sp->in_buffer_cur, n);
+ sp->in_buffer_cur += n;
+ sp->in_buffer_togo -= n;
+ mlen -= n;
+ mmem += n;
+ } while (mlen > 0);
+ return (1);
+}
+
+static void OJPEGReadSkip(OJPEGState *sp, uint16_t len)
+{
+ uint16_t m;
+ uint16_t n;
+ m = len;
+ n = m;
+ if (n > sp->in_buffer_togo)
+ n = sp->in_buffer_togo;
+ sp->in_buffer_cur += n;
+ sp->in_buffer_togo -= n;
+ m -= n;
+ if (m > 0)
+ {
+ assert(sp->in_buffer_togo == 0);
+ n = m;
+ if ((uint64_t)n > sp->in_buffer_file_togo)
+ n = (uint16_t)sp->in_buffer_file_togo;
+ sp->in_buffer_file_pos += n;
+ sp->in_buffer_file_togo -= n;
+ sp->in_buffer_file_pos_log = 0;
+ /* we don't skip past jpeginterchangeformat/strile block...
+ * if that is asked from us, we're dealing with totally bazurk
+ * data anyway, and we've not seen this happening on any
+ * testfile, so we might as well likely cause some other
+ * meaningless error to be passed at some later time
+ */
+ }
+}
+
+static int OJPEGWriteStream(TIFF *tif, void **mem, uint32_t *len)
+{
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ *len = 0;
+ do
+ {
+ assert(sp->out_state <= ososEoi);
+ switch (sp->out_state)
+ {
+ case ososSoi:
+ OJPEGWriteStreamSoi(tif, mem, len);
+ break;
+ case ososQTable0:
+ OJPEGWriteStreamQTable(tif, 0, mem, len);
+ break;
+ case ososQTable1:
+ OJPEGWriteStreamQTable(tif, 1, mem, len);
+ break;
+ case ososQTable2:
+ OJPEGWriteStreamQTable(tif, 2, mem, len);
+ break;
+ case ososQTable3:
+ OJPEGWriteStreamQTable(tif, 3, mem, len);
+ break;
+ case ososDcTable0:
+ OJPEGWriteStreamDcTable(tif, 0, mem, len);
+ break;
+ case ososDcTable1:
+ OJPEGWriteStreamDcTable(tif, 1, mem, len);
+ break;
+ case ososDcTable2:
+ OJPEGWriteStreamDcTable(tif, 2, mem, len);
+ break;
+ case ososDcTable3:
+ OJPEGWriteStreamDcTable(tif, 3, mem, len);
+ break;
+ case ososAcTable0:
+ OJPEGWriteStreamAcTable(tif, 0, mem, len);
+ break;
+ case ososAcTable1:
+ OJPEGWriteStreamAcTable(tif, 1, mem, len);
+ break;
+ case ososAcTable2:
+ OJPEGWriteStreamAcTable(tif, 2, mem, len);
+ break;
+ case ososAcTable3:
+ OJPEGWriteStreamAcTable(tif, 3, mem, len);
+ break;
+ case ososDri:
+ OJPEGWriteStreamDri(tif, mem, len);
+ break;
+ case ososSof:
+ OJPEGWriteStreamSof(tif, mem, len);
+ break;
+ case ososSos:
+ OJPEGWriteStreamSos(tif, mem, len);
+ break;
+ case ososCompressed:
+ if (OJPEGWriteStreamCompressed(tif, mem, len) == 0)
+ return (0);
+ break;
+ case ososRst:
+ OJPEGWriteStreamRst(tif, mem, len);
+ break;
+ case ososEoi:
+ OJPEGWriteStreamEoi(tif, mem, len);
+ break;
+ }
+ } while (*len == 0);
+ return (1);
+}
+
+static void OJPEGWriteStreamSoi(TIFF *tif, void **mem, uint32_t *len)
+{
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ assert(OJPEG_BUFFER >= 2);
+ sp->out_buffer[0] = 255;
+ sp->out_buffer[1] = JPEG_MARKER_SOI;
+ *len = 2;
+ *mem = (void *)sp->out_buffer;
+ sp->out_state++;
+}
+
+static void OJPEGWriteStreamQTable(TIFF *tif, uint8_t table_index, void **mem,
+ uint32_t *len)
+{
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ if (sp->qtable[table_index] != 0)
+ {
+ *mem = (void *)(sp->qtable[table_index] + sizeof(uint32_t));
+ *len = *((uint32_t *)sp->qtable[table_index]) - sizeof(uint32_t);
+ }
+ sp->out_state++;
+}
+
+static void OJPEGWriteStreamDcTable(TIFF *tif, uint8_t table_index, void **mem,
+ uint32_t *len)
+{
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ if (sp->dctable[table_index] != 0)
+ {
+ *mem = (void *)(sp->dctable[table_index] + sizeof(uint32_t));
+ *len = *((uint32_t *)sp->dctable[table_index]) - sizeof(uint32_t);
+ }
+ sp->out_state++;
+}
+
+static void OJPEGWriteStreamAcTable(TIFF *tif, uint8_t table_index, void **mem,
+ uint32_t *len)
+{
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ if (sp->actable[table_index] != 0)
+ {
+ *mem = (void *)(sp->actable[table_index] + sizeof(uint32_t));
+ *len = *((uint32_t *)sp->actable[table_index]) - sizeof(uint32_t);
+ }
+ sp->out_state++;
+}
+
+static void OJPEGWriteStreamDri(TIFF *tif, void **mem, uint32_t *len)
+{
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ assert(OJPEG_BUFFER >= 6);
+ if (sp->restart_interval != 0)
+ {
+ sp->out_buffer[0] = 255;
+ sp->out_buffer[1] = JPEG_MARKER_DRI;
+ sp->out_buffer[2] = 0;
+ sp->out_buffer[3] = 4;
+ sp->out_buffer[4] = (sp->restart_interval >> 8);
+ sp->out_buffer[5] = (sp->restart_interval & 255);
+ *len = 6;
+ *mem = (void *)sp->out_buffer;
+ }
+ sp->out_state++;
+}
+
+static void OJPEGWriteStreamSof(TIFF *tif, void **mem, uint32_t *len)
+{
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ uint8_t m;
+ assert(OJPEG_BUFFER >= 2 + 8 + sp->samples_per_pixel_per_plane * 3);
+ assert(255 >= 8 + sp->samples_per_pixel_per_plane * 3);
+ sp->out_buffer[0] = 255;
+ sp->out_buffer[1] = sp->sof_marker_id;
+ /* Lf */
+ sp->out_buffer[2] = 0;
+ sp->out_buffer[3] = 8 + sp->samples_per_pixel_per_plane * 3;
+ /* P */
+ sp->out_buffer[4] = 8;
+ /* Y */
+ sp->out_buffer[5] = (uint8_t)(sp->sof_y >> 8);
+ sp->out_buffer[6] = (sp->sof_y & 255);
+ /* X */
+ sp->out_buffer[7] = (uint8_t)(sp->sof_x >> 8);
+ sp->out_buffer[8] = (sp->sof_x & 255);
+ /* Nf */
+ sp->out_buffer[9] = sp->samples_per_pixel_per_plane;
+ for (m = 0; m < sp->samples_per_pixel_per_plane; m++)
+ {
+ /* C */
+ sp->out_buffer[10 + m * 3] = sp->sof_c[sp->plane_sample_offset + m];
+ /* H and V */
+ sp->out_buffer[10 + m * 3 + 1] =
+ sp->sof_hv[sp->plane_sample_offset + m];
+ /* Tq */
+ sp->out_buffer[10 + m * 3 + 2] =
+ sp->sof_tq[sp->plane_sample_offset + m];
+ }
+ *len = 10 + sp->samples_per_pixel_per_plane * 3;
+ *mem = (void *)sp->out_buffer;
+ sp->out_state++;
+}
+
+static void OJPEGWriteStreamSos(TIFF *tif, void **mem, uint32_t *len)
+{
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ uint8_t m;
+ assert(OJPEG_BUFFER >= 2 + 6 + sp->samples_per_pixel_per_plane * 2);
+ assert(255 >= 6 + sp->samples_per_pixel_per_plane * 2);
+ sp->out_buffer[0] = 255;
+ sp->out_buffer[1] = JPEG_MARKER_SOS;
+ /* Ls */
+ sp->out_buffer[2] = 0;
+ sp->out_buffer[3] = 6 + sp->samples_per_pixel_per_plane * 2;
+ /* Ns */
+ sp->out_buffer[4] = sp->samples_per_pixel_per_plane;
+ for (m = 0; m < sp->samples_per_pixel_per_plane; m++)
+ {
+ /* Cs */
+ sp->out_buffer[5 + m * 2] = sp->sos_cs[sp->plane_sample_offset + m];
+ /* Td and Ta */
+ sp->out_buffer[5 + m * 2 + 1] =
+ sp->sos_tda[sp->plane_sample_offset + m];
+ }
+ /* Ss */
+ sp->out_buffer[5 + sp->samples_per_pixel_per_plane * 2] = 0;
+ /* Se */
+ sp->out_buffer[5 + sp->samples_per_pixel_per_plane * 2 + 1] = 63;
+ /* Ah and Al */
+ sp->out_buffer[5 + sp->samples_per_pixel_per_plane * 2 + 2] = 0;
+ *len = 8 + sp->samples_per_pixel_per_plane * 2;
+ *mem = (void *)sp->out_buffer;
+ sp->out_state++;
+}
+
+static int OJPEGWriteStreamCompressed(TIFF *tif, void **mem, uint32_t *len)
+{
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ if (sp->in_buffer_togo == 0)
+ {
+ if (OJPEGReadBufferFill(sp) == 0)
+ return (0);
+ assert(sp->in_buffer_togo > 0);
+ }
+ *len = sp->in_buffer_togo;
+ *mem = (void *)sp->in_buffer_cur;
+ sp->in_buffer_togo = 0;
+ if (sp->in_buffer_file_togo == 0)
+ {
+ switch (sp->in_buffer_source)
+ {
+ case osibsStrile:
+ if (sp->in_buffer_next_strile < sp->in_buffer_strile_count)
+ sp->out_state = ososRst;
+ else
+ sp->out_state = ososEoi;
+ break;
+ case osibsEof:
+ sp->out_state = ososEoi;
+ break;
+ default:
+ break;
+ }
+ }
+ return (1);
+}
+
+static void OJPEGWriteStreamRst(TIFF *tif, void **mem, uint32_t *len)
+{
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ assert(OJPEG_BUFFER >= 2);
+ sp->out_buffer[0] = 255;
+ sp->out_buffer[1] = JPEG_MARKER_RST0 + sp->restart_index;
+ sp->restart_index++;
+ if (sp->restart_index == 8)
+ sp->restart_index = 0;
+ *len = 2;
+ *mem = (void *)sp->out_buffer;
+ sp->out_state = ososCompressed;
+}
+
+static void OJPEGWriteStreamEoi(TIFF *tif, void **mem, uint32_t *len)
+{
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ assert(OJPEG_BUFFER >= 2);
+ sp->out_buffer[0] = 255;
+ sp->out_buffer[1] = JPEG_MARKER_EOI;
+ *len = 2;
+ *mem = (void *)sp->out_buffer;
+}
+
+#ifndef LIBJPEG_ENCAP_EXTERNAL
+static int jpeg_create_decompress_encap(OJPEGState *sp,
+ jpeg_decompress_struct *cinfo)
+{
+ if (SETJMP(sp->exit_jmpbuf))
+ return 0;
+ else
+ {
+ jpeg_create_decompress(cinfo);
+ return 1;
+ }
+}
+#endif
+
+#ifndef LIBJPEG_ENCAP_EXTERNAL
+static int jpeg_read_header_encap(OJPEGState *sp, jpeg_decompress_struct *cinfo,
+ uint8_t require_image)
+{
+ if (SETJMP(sp->exit_jmpbuf))
+ return 0;
+ else
+ {
+ jpeg_read_header(cinfo, require_image);
+ return 1;
+ }
+}
+#endif
+
+#ifndef LIBJPEG_ENCAP_EXTERNAL
+static int jpeg_start_decompress_encap(OJPEGState *sp,
+ jpeg_decompress_struct *cinfo)
+{
+ if (SETJMP(sp->exit_jmpbuf))
+ return 0;
+ else
+ {
+ jpeg_start_decompress(cinfo);
+ return 1;
+ }
+}
+#endif
+
+#ifndef LIBJPEG_ENCAP_EXTERNAL
+static int jpeg_read_scanlines_encap(OJPEGState *sp,
+ jpeg_decompress_struct *cinfo,
+ void *scanlines, uint32_t max_lines)
+{
+ if (SETJMP(sp->exit_jmpbuf))
+ return 0;
+ else
+ {
+ jpeg_read_scanlines(cinfo, scanlines, max_lines);
+ return 1;
+ }
+}
+#endif
+
+#ifndef LIBJPEG_ENCAP_EXTERNAL
+static int jpeg_read_raw_data_encap(OJPEGState *sp,
+ jpeg_decompress_struct *cinfo, void *data,
+ uint32_t max_lines)
+{
+ if (SETJMP(sp->exit_jmpbuf))
+ return 0;
+ else
+ {
+ jpeg_read_raw_data(cinfo, data, max_lines);
+ return 1;
+ }
+}
+#endif
+
+#ifndef LIBJPEG_ENCAP_EXTERNAL
+static void jpeg_encap_unwind(TIFF *tif)
+{
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ LONGJMP(sp->exit_jmpbuf, 1);
+}
+#endif
+
+static void OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct *cinfo)
+{
+ char buffer[JMSG_LENGTH_MAX];
+ (*cinfo->err->format_message)(cinfo, buffer);
+ TIFFWarningExtR(((TIFF *)(cinfo->client_data)), "LibJpeg", "%s", buffer);
+}
+
+static void OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct *cinfo)
+{
+ char buffer[JMSG_LENGTH_MAX];
+ (*cinfo->err->format_message)(cinfo, buffer);
+ TIFFErrorExtR(((TIFF *)(cinfo->client_data)), "LibJpeg", "%s", buffer);
+ jpeg_encap_unwind((TIFF *)(cinfo->client_data));
+}
+
+static void OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct *cinfo)
+{
+ (void)cinfo;
+}
+
+static boolean
+OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct *cinfo)
+{
+ TIFF *tif = (TIFF *)cinfo->client_data;
+ OJPEGState *sp = (OJPEGState *)tif->tif_data;
+ void *mem = 0;
+ uint32_t len = 0U;
+ if (OJPEGWriteStream(tif, &mem, &len) == 0)
+ {
+ TIFFErrorExtR(tif, "LibJpeg", "Premature end of JPEG data");
+ jpeg_encap_unwind(tif);
+ }
+ sp->libjpeg_jpeg_source_mgr.bytes_in_buffer = len;
+ sp->libjpeg_jpeg_source_mgr.next_input_byte = mem;
+ return (1);
+}
+
+static void
+OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct *cinfo,
+ long num_bytes)
+{
+ TIFF *tif = (TIFF *)cinfo->client_data;
+ (void)num_bytes;
+ TIFFErrorExtR(tif, "LibJpeg", "Unexpected error");
+ jpeg_encap_unwind(tif);
+}
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4702) /* unreachable code */
+#endif
+static boolean
+OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct *cinfo,
+ int desired)
+{
+ TIFF *tif = (TIFF *)cinfo->client_data;
+ (void)desired;
+ TIFFErrorExtR(tif, "LibJpeg", "Unexpected error");
+ jpeg_encap_unwind(tif);
+ return (0);
+}
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+static void OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct *cinfo)
+{
+ (void)cinfo;
+}
+
+#endif
diff --git a/contrib/libs/libtiff/tif_open.c b/contrib/libs/libtiff/tif_open.c
new file mode 100644
index 0000000000..23fcf81c43
--- /dev/null
+++ b/contrib/libs/libtiff/tif_open.c
@@ -0,0 +1,808 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ */
+#include "tiffiop.h"
+#include <limits.h>
+
+/*
+ * Dummy functions to fill the omitted client procedures.
+ */
+static int _tiffDummyMapProc(thandle_t fd, void **pbase, toff_t *psize)
+{
+ (void)fd;
+ (void)pbase;
+ (void)psize;
+ return (0);
+}
+
+static void _tiffDummyUnmapProc(thandle_t fd, void *base, toff_t size)
+{
+ (void)fd;
+ (void)base;
+ (void)size;
+}
+
+int _TIFFgetMode(TIFFOpenOptions *opts, thandle_t clientdata, const char *mode,
+ const char *module)
+{
+ int m = -1;
+
+ switch (mode[0])
+ {
+ case 'r':
+ m = O_RDONLY;
+ if (mode[1] == '+')
+ m = O_RDWR;
+ break;
+ case 'w':
+ case 'a':
+ m = O_RDWR | O_CREAT;
+ if (mode[0] == 'w')
+ m |= O_TRUNC;
+ break;
+ default:
+ _TIFFErrorEarly(opts, clientdata, module, "\"%s\": Bad mode", mode);
+ break;
+ }
+ return (m);
+}
+
+TIFFOpenOptions *TIFFOpenOptionsAlloc()
+{
+ TIFFOpenOptions *opts =
+ (TIFFOpenOptions *)_TIFFcalloc(1, sizeof(TIFFOpenOptions));
+ return opts;
+}
+
+void TIFFOpenOptionsFree(TIFFOpenOptions *opts) { _TIFFfree(opts); }
+
+/** Define a limit in bytes for a single memory allocation done by libtiff.
+ * If max_single_mem_alloc is set to 0, no other limit that the underlying
+ * _TIFFmalloc() will be applied, which is the default.
+ */
+void TIFFOpenOptionsSetMaxSingleMemAlloc(TIFFOpenOptions *opts,
+ tmsize_t max_single_mem_alloc)
+{
+ opts->max_single_mem_alloc = max_single_mem_alloc;
+}
+
+void TIFFOpenOptionsSetErrorHandlerExtR(TIFFOpenOptions *opts,
+ TIFFErrorHandlerExtR handler,
+ void *errorhandler_user_data)
+{
+ opts->errorhandler = handler;
+ opts->errorhandler_user_data = errorhandler_user_data;
+}
+
+void TIFFOpenOptionsSetWarningHandlerExtR(TIFFOpenOptions *opts,
+ TIFFErrorHandlerExtR handler,
+ void *warnhandler_user_data)
+{
+ opts->warnhandler = handler;
+ opts->warnhandler_user_data = warnhandler_user_data;
+}
+
+static void _TIFFEmitErrorAboveMaxSingleMemAlloc(TIFF *tif,
+ const char *pszFunction,
+ tmsize_t s)
+{
+ TIFFErrorExtR(tif, pszFunction,
+ "Memory allocation of %" PRIu64
+ " bytes is beyond the %" PRIu64
+ " byte limit defined in open options",
+ (uint64_t)s, (uint64_t)tif->tif_max_single_mem_alloc);
+}
+
+/** malloc() version that takes into account memory-specific open options */
+void *_TIFFmallocExt(TIFF *tif, tmsize_t s)
+{
+ if (tif != NULL && tif->tif_max_single_mem_alloc > 0 &&
+ s > tif->tif_max_single_mem_alloc)
+ {
+ _TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFmallocExt", s);
+ return NULL;
+ }
+ return _TIFFmalloc(s);
+}
+
+/** calloc() version that takes into account memory-specific open options */
+void *_TIFFcallocExt(TIFF *tif, tmsize_t nmemb, tmsize_t siz)
+{
+ if (tif != NULL && tif->tif_max_single_mem_alloc > 0)
+ {
+ if (nmemb <= 0 || siz <= 0 || nmemb > TIFF_TMSIZE_T_MAX / siz)
+ return NULL;
+ if (nmemb * siz > tif->tif_max_single_mem_alloc)
+ {
+ _TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFcallocExt",
+ nmemb * siz);
+ return NULL;
+ }
+ }
+ return _TIFFcalloc(nmemb, siz);
+}
+
+/** realloc() version that takes into account memory-specific open options */
+void *_TIFFreallocExt(TIFF *tif, void *p, tmsize_t s)
+{
+ if (tif != NULL && tif->tif_max_single_mem_alloc > 0 &&
+ s > tif->tif_max_single_mem_alloc)
+ {
+ _TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFreallocExt", s);
+ return NULL;
+ }
+ return _TIFFrealloc(p, s);
+}
+
+/** free() version that takes into account memory-specific open options */
+void _TIFFfreeExt(TIFF *tif, void *p)
+{
+ (void)tif;
+ _TIFFfree(p);
+}
+
+TIFF *TIFFClientOpen(const char *name, const char *mode, thandle_t clientdata,
+ TIFFReadWriteProc readproc, TIFFReadWriteProc writeproc,
+ TIFFSeekProc seekproc, TIFFCloseProc closeproc,
+ TIFFSizeProc sizeproc, TIFFMapFileProc mapproc,
+ TIFFUnmapFileProc unmapproc)
+{
+ return TIFFClientOpenExt(name, mode, clientdata, readproc, writeproc,
+ seekproc, closeproc, sizeproc, mapproc, unmapproc,
+ NULL);
+}
+
+TIFF *TIFFClientOpenExt(const char *name, const char *mode,
+ thandle_t clientdata, TIFFReadWriteProc readproc,
+ TIFFReadWriteProc writeproc, TIFFSeekProc seekproc,
+ TIFFCloseProc closeproc, TIFFSizeProc sizeproc,
+ TIFFMapFileProc mapproc, TIFFUnmapFileProc unmapproc,
+ TIFFOpenOptions *opts)
+{
+ static const char module[] = "TIFFClientOpenExt";
+ TIFF *tif;
+ int m;
+ const char *cp;
+
+ /* The following are configuration checks. They should be redundant, but
+ * should not compile to any actual code in an optimised release build
+ * anyway. If any of them fail, (makefile-based or other) configuration is
+ * not correct */
+ assert(sizeof(uint8_t) == 1);
+ assert(sizeof(int8_t) == 1);
+ assert(sizeof(uint16_t) == 2);
+ assert(sizeof(int16_t) == 2);
+ assert(sizeof(uint32_t) == 4);
+ assert(sizeof(int32_t) == 4);
+ assert(sizeof(uint64_t) == 8);
+ assert(sizeof(int64_t) == 8);
+ {
+ union
+ {
+ uint8_t a8[2];
+ uint16_t a16;
+ } n;
+ n.a8[0] = 1;
+ n.a8[1] = 0;
+ (void)n;
+#ifdef WORDS_BIGENDIAN
+ assert(n.a16 == 256);
+#else
+ assert(n.a16 == 1);
+#endif
+ }
+
+ m = _TIFFgetMode(opts, clientdata, mode, module);
+ if (m == -1)
+ goto bad2;
+ tmsize_t size_to_alloc = (tmsize_t)(sizeof(TIFF) + strlen(name) + 1);
+ if (opts && opts->max_single_mem_alloc > 0 &&
+ size_to_alloc > opts->max_single_mem_alloc)
+ {
+ _TIFFErrorEarly(opts, clientdata, module,
+ "%s: Memory allocation of %" PRIu64
+ " bytes is beyond the %" PRIu64
+ " byte limit defined in open options",
+ name, (uint64_t)size_to_alloc,
+ (uint64_t)opts->max_single_mem_alloc);
+ goto bad2;
+ }
+ tif = (TIFF *)_TIFFmallocExt(NULL, size_to_alloc);
+ if (tif == NULL)
+ {
+ _TIFFErrorEarly(opts, clientdata, module,
+ "%s: Out of memory (TIFF structure)", name);
+ goto bad2;
+ }
+ _TIFFmemset(tif, 0, sizeof(*tif));
+ tif->tif_name = (char *)tif + sizeof(TIFF);
+ strcpy(tif->tif_name, name);
+ tif->tif_mode = m & ~(O_CREAT | O_TRUNC);
+ tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER; /* non-existent directory */
+ tif->tif_curoff = 0;
+ tif->tif_curstrip = (uint32_t)-1; /* invalid strip */
+ tif->tif_row = (uint32_t)-1; /* read/write pre-increment */
+ tif->tif_clientdata = clientdata;
+ tif->tif_readproc = readproc;
+ tif->tif_writeproc = writeproc;
+ tif->tif_seekproc = seekproc;
+ tif->tif_closeproc = closeproc;
+ tif->tif_sizeproc = sizeproc;
+ tif->tif_mapproc = mapproc ? mapproc : _tiffDummyMapProc;
+ tif->tif_unmapproc = unmapproc ? unmapproc : _tiffDummyUnmapProc;
+ if (opts)
+ {
+ tif->tif_errorhandler = opts->errorhandler;
+ tif->tif_errorhandler_user_data = opts->errorhandler_user_data;
+ tif->tif_warnhandler = opts->warnhandler;
+ tif->tif_warnhandler_user_data = opts->warnhandler_user_data;
+ tif->tif_max_single_mem_alloc = opts->max_single_mem_alloc;
+ }
+
+ if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc)
+ {
+ TIFFErrorExtR(tif, module,
+ "One of the client procedures is NULL pointer.");
+ _TIFFfreeExt(NULL, tif);
+ goto bad2;
+ }
+
+ _TIFFSetDefaultCompressionState(tif); /* setup default state */
+ /*
+ * Default is to return data MSB2LSB and enable the
+ * use of memory-mapped files and strip chopping when
+ * a file is opened read-only.
+ */
+ tif->tif_flags = FILLORDER_MSB2LSB;
+ if (m == O_RDONLY)
+ tif->tif_flags |= TIFF_MAPPED;
+
+#ifdef STRIPCHOP_DEFAULT
+ if (m == O_RDONLY || m == O_RDWR)
+ tif->tif_flags |= STRIPCHOP_DEFAULT;
+#endif
+
+ /*
+ * Process library-specific flags in the open mode string.
+ * The following flags may be used to control intrinsic library
+ * behavior that may or may not be desirable (usually for
+ * compatibility with some application that claims to support
+ * TIFF but only supports some brain dead idea of what the
+ * vendor thinks TIFF is):
+ *
+ * 'l' use little-endian byte order for creating a file
+ * 'b' use big-endian byte order for creating a file
+ * 'L' read/write information using LSB2MSB bit order
+ * 'B' read/write information using MSB2LSB bit order
+ * 'H' read/write information using host bit order
+ * 'M' enable use of memory-mapped files when supported
+ * 'm' disable use of memory-mapped files
+ * 'C' enable strip chopping support when reading
+ * 'c' disable strip chopping support
+ * 'h' read TIFF header only, do not load the first IFD
+ * '4' ClassicTIFF for creating a file (default)
+ * '8' BigTIFF for creating a file
+ * 'D' enable use of deferred strip/tile offset/bytecount array loading.
+ * 'O' on-demand loading of values instead of whole array loading (implies
+ * D)
+ *
+ * The use of the 'l' and 'b' flags is strongly discouraged.
+ * These flags are provided solely because numerous vendors,
+ * typically on the PC, do not correctly support TIFF; they
+ * only support the Intel little-endian byte order. This
+ * support is not configured by default because it supports
+ * the violation of the TIFF spec that says that readers *MUST*
+ * support both byte orders. It is strongly recommended that
+ * you not use this feature except to deal with busted apps
+ * that write invalid TIFF. And even in those cases you should
+ * bang on the vendors to fix their software.
+ *
+ * The 'L', 'B', and 'H' flags are intended for applications
+ * that can optimize operations on data by using a particular
+ * bit order. By default the library returns data in MSB2LSB
+ * bit order for compatibility with older versions of this
+ * library. Returning data in the bit order of the native CPU
+ * makes the most sense but also requires applications to check
+ * the value of the FillOrder tag; something they probably do
+ * not do right now.
+ *
+ * The 'M' and 'm' flags are provided because some virtual memory
+ * systems exhibit poor behavior when large images are mapped.
+ * These options permit clients to control the use of memory-mapped
+ * files on a per-file basis.
+ *
+ * The 'C' and 'c' flags are provided because the library support
+ * for chopping up large strips into multiple smaller strips is not
+ * application-transparent and as such can cause problems. The 'c'
+ * option permits applications that only want to look at the tags,
+ * for example, to get the unadulterated TIFF tag information.
+ */
+ for (cp = mode; *cp; cp++)
+ switch (*cp)
+ {
+ case 'b':
+#ifndef WORDS_BIGENDIAN
+ if (m & O_CREAT)
+ tif->tif_flags |= TIFF_SWAB;
+#endif
+ break;
+ case 'l':
+#ifdef WORDS_BIGENDIAN
+ if ((m & O_CREAT))
+ tif->tif_flags |= TIFF_SWAB;
+#endif
+ break;
+ case 'B':
+ tif->tif_flags =
+ (tif->tif_flags & ~TIFF_FILLORDER) | FILLORDER_MSB2LSB;
+ break;
+ case 'L':
+ tif->tif_flags =
+ (tif->tif_flags & ~TIFF_FILLORDER) | FILLORDER_LSB2MSB;
+ break;
+ case 'H':
+ TIFFWarningExtR(tif, name,
+ "H(ost) mode is deprecated. Since "
+ "libtiff 4.5.1, it is an alias of 'B' / "
+ "FILLORDER_MSB2LSB.");
+ tif->tif_flags =
+ (tif->tif_flags & ~TIFF_FILLORDER) | FILLORDER_MSB2LSB;
+ break;
+ case 'M':
+ if (m == O_RDONLY)
+ tif->tif_flags |= TIFF_MAPPED;
+ break;
+ case 'm':
+ if (m == O_RDONLY)
+ tif->tif_flags &= ~TIFF_MAPPED;
+ break;
+ case 'C':
+ if (m == O_RDONLY)
+ tif->tif_flags |= TIFF_STRIPCHOP;
+ break;
+ case 'c':
+ if (m == O_RDONLY)
+ tif->tif_flags &= ~TIFF_STRIPCHOP;
+ break;
+ case 'h':
+ tif->tif_flags |= TIFF_HEADERONLY;
+ break;
+ case '8':
+ if (m & O_CREAT)
+ tif->tif_flags |= TIFF_BIGTIFF;
+ break;
+ case 'D':
+ tif->tif_flags |= TIFF_DEFERSTRILELOAD;
+ break;
+ case 'O':
+ if (m == O_RDONLY)
+ tif->tif_flags |=
+ (TIFF_LAZYSTRILELOAD | TIFF_DEFERSTRILELOAD);
+ break;
+ }
+
+#ifdef DEFER_STRILE_LOAD
+ /* Compatibility with old DEFER_STRILE_LOAD compilation flag */
+ /* Probably unneeded, since to the best of my knowledge (E. Rouault) */
+ /* GDAL was the only user of this, and will now use the new 'D' flag */
+ tif->tif_flags |= TIFF_DEFERSTRILELOAD;
+#endif
+
+ /*
+ * Read in TIFF header.
+ */
+ if ((m & O_TRUNC) ||
+ !ReadOK(tif, &tif->tif_header, sizeof(TIFFHeaderClassic)))
+ {
+ if (tif->tif_mode == O_RDONLY)
+ {
+ TIFFErrorExtR(tif, name, "Cannot read TIFF header");
+ goto bad;
+ }
+/*
+ * Setup header and write.
+ */
+#ifdef WORDS_BIGENDIAN
+ tif->tif_header.common.tiff_magic =
+ (tif->tif_flags & TIFF_SWAB) ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN;
+#else
+ tif->tif_header.common.tiff_magic =
+ (tif->tif_flags & TIFF_SWAB) ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN;
+#endif
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ {
+ tif->tif_header.common.tiff_version = TIFF_VERSION_CLASSIC;
+ tif->tif_header.classic.tiff_diroff = 0;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(&tif->tif_header.common.tiff_version);
+ tif->tif_header_size = sizeof(TIFFHeaderClassic);
+ }
+ else
+ {
+ tif->tif_header.common.tiff_version = TIFF_VERSION_BIG;
+ tif->tif_header.big.tiff_offsetsize = 8;
+ tif->tif_header.big.tiff_unused = 0;
+ tif->tif_header.big.tiff_diroff = 0;
+ if (tif->tif_flags & TIFF_SWAB)
+ {
+ TIFFSwabShort(&tif->tif_header.common.tiff_version);
+ TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize);
+ }
+ tif->tif_header_size = sizeof(TIFFHeaderBig);
+ }
+ /*
+ * The doc for "fopen" for some STD_C_LIBs says that if you
+ * open a file for modify ("+"), then you must fseek (or
+ * fflush?) between any freads and fwrites. This is not
+ * necessary on most systems, but has been shown to be needed
+ * on Solaris.
+ */
+ TIFFSeekFile(tif, 0, SEEK_SET);
+ if (!WriteOK(tif, &tif->tif_header, (tmsize_t)(tif->tif_header_size)))
+ {
+ TIFFErrorExtR(tif, name, "Error writing TIFF header");
+ goto bad;
+ }
+ /*
+ * Setup the byte order handling.
+ */
+ if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN)
+ {
+#ifndef WORDS_BIGENDIAN
+ tif->tif_flags |= TIFF_SWAB;
+#endif
+ }
+ else
+ {
+#ifdef WORDS_BIGENDIAN
+ tif->tif_flags |= TIFF_SWAB;
+#endif
+ }
+ /*
+ * Setup default directory.
+ */
+ if (!TIFFDefaultDirectory(tif))
+ goto bad;
+ tif->tif_diroff = 0;
+ tif->tif_lastdiroff = 0;
+ tif->tif_setdirectory_force_absolute = FALSE;
+ return (tif);
+ }
+ /*
+ * Setup the byte order handling.
+ */
+ if (tif->tif_header.common.tiff_magic != TIFF_BIGENDIAN &&
+ tif->tif_header.common.tiff_magic != TIFF_LITTLEENDIAN
+#if MDI_SUPPORT
+ &&
+#if HOST_BIGENDIAN
+ tif->tif_header.common.tiff_magic != MDI_BIGENDIAN
+#else
+ tif->tif_header.common.tiff_magic != MDI_LITTLEENDIAN
+#endif
+ )
+ {
+ TIFFErrorExtR(tif, name,
+ "Not a TIFF or MDI file, bad magic number %" PRIu16
+ " (0x%" PRIx16 ")",
+#else
+ )
+ {
+ TIFFErrorExtR(tif, name,
+ "Not a TIFF file, bad magic number %" PRIu16
+ " (0x%" PRIx16 ")",
+#endif
+ tif->tif_header.common.tiff_magic,
+ tif->tif_header.common.tiff_magic);
+ goto bad;
+ }
+ if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN)
+ {
+#ifndef WORDS_BIGENDIAN
+ tif->tif_flags |= TIFF_SWAB;
+#endif
+ }
+ else
+ {
+#ifdef WORDS_BIGENDIAN
+ tif->tif_flags |= TIFF_SWAB;
+#endif
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(&tif->tif_header.common.tiff_version);
+ if ((tif->tif_header.common.tiff_version != TIFF_VERSION_CLASSIC) &&
+ (tif->tif_header.common.tiff_version != TIFF_VERSION_BIG))
+ {
+ TIFFErrorExtR(tif, name,
+ "Not a TIFF file, bad version number %" PRIu16
+ " (0x%" PRIx16 ")",
+ tif->tif_header.common.tiff_version,
+ tif->tif_header.common.tiff_version);
+ goto bad;
+ }
+ if (tif->tif_header.common.tiff_version == TIFF_VERSION_CLASSIC)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&tif->tif_header.classic.tiff_diroff);
+ tif->tif_header_size = sizeof(TIFFHeaderClassic);
+ }
+ else
+ {
+ if (!ReadOK(tif,
+ ((uint8_t *)(&tif->tif_header) + sizeof(TIFFHeaderClassic)),
+ (sizeof(TIFFHeaderBig) - sizeof(TIFFHeaderClassic))))
+ {
+ TIFFErrorExtR(tif, name, "Cannot read TIFF header");
+ goto bad;
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ {
+ TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize);
+ TIFFSwabLong8(&tif->tif_header.big.tiff_diroff);
+ }
+ if (tif->tif_header.big.tiff_offsetsize != 8)
+ {
+ TIFFErrorExtR(tif, name,
+ "Not a TIFF file, bad BigTIFF offsetsize %" PRIu16
+ " (0x%" PRIx16 ")",
+ tif->tif_header.big.tiff_offsetsize,
+ tif->tif_header.big.tiff_offsetsize);
+ goto bad;
+ }
+ if (tif->tif_header.big.tiff_unused != 0)
+ {
+ TIFFErrorExtR(tif, name,
+ "Not a TIFF file, bad BigTIFF unused %" PRIu16
+ " (0x%" PRIx16 ")",
+ tif->tif_header.big.tiff_unused,
+ tif->tif_header.big.tiff_unused);
+ goto bad;
+ }
+ tif->tif_header_size = sizeof(TIFFHeaderBig);
+ tif->tif_flags |= TIFF_BIGTIFF;
+ }
+ tif->tif_flags |= TIFF_MYBUFFER;
+ tif->tif_rawcp = tif->tif_rawdata = 0;
+ tif->tif_rawdatasize = 0;
+ tif->tif_rawdataoff = 0;
+ tif->tif_rawdataloaded = 0;
+
+ switch (mode[0])
+ {
+ case 'r':
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ tif->tif_nextdiroff = tif->tif_header.classic.tiff_diroff;
+ else
+ tif->tif_nextdiroff = tif->tif_header.big.tiff_diroff;
+ /*
+ * Try to use a memory-mapped file if the client
+ * has not explicitly suppressed usage with the
+ * 'm' flag in the open mode (see above).
+ */
+ if (tif->tif_flags & TIFF_MAPPED)
+ {
+ toff_t n;
+ if (TIFFMapFileContents(tif, (void **)(&tif->tif_base), &n))
+ {
+ tif->tif_size = (tmsize_t)n;
+ assert((toff_t)tif->tif_size == n);
+ }
+ else
+ tif->tif_flags &= ~TIFF_MAPPED;
+ }
+ /*
+ * Sometimes we do not want to read the first directory (for
+ * example, it may be broken) and want to proceed to other
+ * directories. I this case we use the TIFF_HEADERONLY flag to open
+ * file and return immediately after reading TIFF header.
+ */
+ if (tif->tif_flags & TIFF_HEADERONLY)
+ return (tif);
+
+ /*
+ * Setup initial directory.
+ */
+ if (TIFFReadDirectory(tif))
+ {
+ return (tif);
+ }
+ break;
+ case 'a':
+ /*
+ * New directories are automatically append
+ * to the end of the directory chain when they
+ * are written out (see TIFFWriteDirectory).
+ */
+ if (!TIFFDefaultDirectory(tif))
+ goto bad;
+ return (tif);
+ }
+bad:
+ tif->tif_mode = O_RDONLY; /* XXX avoid flush */
+ TIFFCleanup(tif);
+bad2:
+ return ((TIFF *)0);
+}
+
+/*
+ * Query functions to access private data.
+ */
+
+/*
+ * Return open file's name.
+ */
+const char *TIFFFileName(TIFF *tif) { return (tif->tif_name); }
+
+/*
+ * Set the file name.
+ */
+const char *TIFFSetFileName(TIFF *tif, const char *name)
+{
+ const char *old_name = tif->tif_name;
+ tif->tif_name = (char *)name;
+ return (old_name);
+}
+
+/*
+ * Return open file's I/O descriptor.
+ */
+int TIFFFileno(TIFF *tif) { return (tif->tif_fd); }
+
+/*
+ * Set open file's I/O descriptor, and return previous value.
+ */
+int TIFFSetFileno(TIFF *tif, int fd)
+{
+ int old_fd = tif->tif_fd;
+ tif->tif_fd = fd;
+ return old_fd;
+}
+
+/*
+ * Return open file's clientdata.
+ */
+thandle_t TIFFClientdata(TIFF *tif) { return (tif->tif_clientdata); }
+
+/*
+ * Set open file's clientdata, and return previous value.
+ */
+thandle_t TIFFSetClientdata(TIFF *tif, thandle_t newvalue)
+{
+ thandle_t m = tif->tif_clientdata;
+ tif->tif_clientdata = newvalue;
+ return m;
+}
+
+/*
+ * Return read/write mode.
+ */
+int TIFFGetMode(TIFF *tif) { return (tif->tif_mode); }
+
+/*
+ * Return read/write mode.
+ */
+int TIFFSetMode(TIFF *tif, int mode)
+{
+ int old_mode = tif->tif_mode;
+ tif->tif_mode = mode;
+ return (old_mode);
+}
+
+/*
+ * Return nonzero if file is organized in
+ * tiles; zero if organized as strips.
+ */
+int TIFFIsTiled(TIFF *tif) { return (isTiled(tif)); }
+
+/*
+ * Return current row being read/written.
+ */
+uint32_t TIFFCurrentRow(TIFF *tif) { return (tif->tif_row); }
+
+/*
+ * Return index of the current directory.
+ */
+tdir_t TIFFCurrentDirectory(TIFF *tif) { return (tif->tif_curdir); }
+
+/*
+ * Return current strip.
+ */
+uint32_t TIFFCurrentStrip(TIFF *tif) { return (tif->tif_curstrip); }
+
+/*
+ * Return current tile.
+ */
+uint32_t TIFFCurrentTile(TIFF *tif) { return (tif->tif_curtile); }
+
+/*
+ * Return nonzero if the file has byte-swapped data.
+ */
+int TIFFIsByteSwapped(TIFF *tif) { return ((tif->tif_flags & TIFF_SWAB) != 0); }
+
+/*
+ * Return nonzero if the data is returned up-sampled.
+ */
+int TIFFIsUpSampled(TIFF *tif) { return (isUpSampled(tif)); }
+
+/*
+ * Return nonzero if the data is returned in MSB-to-LSB bit order.
+ */
+int TIFFIsMSB2LSB(TIFF *tif) { return (isFillOrder(tif, FILLORDER_MSB2LSB)); }
+
+/*
+ * Return nonzero if given file was written in big-endian order.
+ */
+int TIFFIsBigEndian(TIFF *tif)
+{
+ return (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN);
+}
+
+/*
+ * 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 TIFFGetReadProc(TIFF *tif) { return (tif->tif_readproc); }
+
+/*
+ * Return pointer to file write method.
+ */
+TIFFReadWriteProc TIFFGetWriteProc(TIFF *tif) { return (tif->tif_writeproc); }
+
+/*
+ * Return pointer to file seek method.
+ */
+TIFFSeekProc TIFFGetSeekProc(TIFF *tif) { return (tif->tif_seekproc); }
+
+/*
+ * Return pointer to file close method.
+ */
+TIFFCloseProc TIFFGetCloseProc(TIFF *tif) { return (tif->tif_closeproc); }
+
+/*
+ * Return pointer to file size requesting method.
+ */
+TIFFSizeProc TIFFGetSizeProc(TIFF *tif) { return (tif->tif_sizeproc); }
+
+/*
+ * Return pointer to memory mapping method.
+ */
+TIFFMapFileProc TIFFGetMapFileProc(TIFF *tif) { return (tif->tif_mapproc); }
+
+/*
+ * Return pointer to memory unmapping method.
+ */
+TIFFUnmapFileProc TIFFGetUnmapFileProc(TIFF *tif)
+{
+ return (tif->tif_unmapproc);
+}
diff --git a/contrib/libs/libtiff/tif_packbits.c b/contrib/libs/libtiff/tif_packbits.c
new file mode 100644
index 0000000000..62849f8f3c
--- /dev/null
+++ b/contrib/libs/libtiff/tif_packbits.c
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+#include "tiffiop.h"
+#ifdef PACKBITS_SUPPORT
+/*
+ * TIFF Library.
+ *
+ * PackBits Compression Algorithm Support
+ */
+#include <stdio.h>
+
+static int PackBitsPreEncode(TIFF *tif, uint16_t s)
+{
+ (void)s;
+
+ tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(tmsize_t));
+ if (tif->tif_data == NULL)
+ return (0);
+ /*
+ * Calculate the scanline/tile-width size in bytes.
+ */
+ if (isTiled(tif))
+ *(tmsize_t *)tif->tif_data = TIFFTileRowSize(tif);
+ else
+ *(tmsize_t *)tif->tif_data = TIFFScanlineSize(tif);
+ return (1);
+}
+
+static int PackBitsPostEncode(TIFF *tif)
+{
+ if (tif->tif_data)
+ _TIFFfreeExt(tif, tif->tif_data);
+ return (1);
+}
+
+/*
+ * Encode a run of pixels.
+ */
+static int PackBitsEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
+{
+ unsigned char *bp = (unsigned char *)buf;
+ uint8_t *op;
+ uint8_t *ep;
+ uint8_t *lastliteral;
+ long n, slop;
+ int b;
+ enum
+ {
+ BASE,
+ LITERAL,
+ RUN,
+ LITERAL_RUN
+ } state;
+
+ (void)s;
+ op = tif->tif_rawcp;
+ ep = tif->tif_rawdata + tif->tif_rawdatasize;
+ state = BASE;
+ lastliteral = 0;
+ while (cc > 0)
+ {
+ /*
+ * Find the longest string of identical bytes.
+ */
+ b = *bp++;
+ cc--;
+ n = 1;
+ for (; cc > 0 && b == *bp; cc--, bp++)
+ n++;
+ again:
+ if (op + 2 >= ep)
+ { /* insure space for new data */
+ /*
+ * Be careful about writing the last
+ * literal. Must write up to that point
+ * and then copy the remainder to the
+ * front of the buffer.
+ */
+ if (state == LITERAL || state == LITERAL_RUN)
+ {
+ slop = (long)(op - lastliteral);
+ tif->tif_rawcc += (tmsize_t)(lastliteral - tif->tif_rawcp);
+ if (!TIFFFlushData1(tif))
+ return (0);
+ op = tif->tif_rawcp;
+ while (slop-- > 0)
+ *op++ = *lastliteral++;
+ lastliteral = tif->tif_rawcp;
+ }
+ else
+ {
+ tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp);
+ if (!TIFFFlushData1(tif))
+ return (0);
+ op = tif->tif_rawcp;
+ }
+ }
+ switch (state)
+ {
+ case BASE: /* initial state, set run/literal */
+ if (n > 1)
+ {
+ state = RUN;
+ if (n > 128)
+ {
+ *op++ = (uint8_t)-127;
+ *op++ = (uint8_t)b;
+ n -= 128;
+ goto again;
+ }
+ *op++ = (uint8_t)(-(n - 1));
+ *op++ = (uint8_t)b;
+ }
+ else
+ {
+ lastliteral = op;
+ *op++ = 0;
+ *op++ = (uint8_t)b;
+ state = LITERAL;
+ }
+ break;
+ case LITERAL: /* last object was literal string */
+ if (n > 1)
+ {
+ state = LITERAL_RUN;
+ if (n > 128)
+ {
+ *op++ = (uint8_t)-127;
+ *op++ = (uint8_t)b;
+ n -= 128;
+ goto again;
+ }
+ *op++ = (uint8_t)(-(n - 1)); /* encode run */
+ *op++ = (uint8_t)b;
+ }
+ else
+ { /* extend literal */
+ if (++(*lastliteral) == 127)
+ state = BASE;
+ *op++ = (uint8_t)b;
+ }
+ break;
+ case RUN: /* last object was run */
+ if (n > 1)
+ {
+ if (n > 128)
+ {
+ *op++ = (uint8_t)-127;
+ *op++ = (uint8_t)b;
+ n -= 128;
+ goto again;
+ }
+ *op++ = (uint8_t)(-(n - 1));
+ *op++ = (uint8_t)b;
+ }
+ else
+ {
+ lastliteral = op;
+ *op++ = 0;
+ *op++ = (uint8_t)b;
+ state = LITERAL;
+ }
+ break;
+ case LITERAL_RUN: /* literal followed by a run */
+ /*
+ * Check to see if previous run should
+ * be converted to a literal, in which
+ * case we convert literal-run-literal
+ * to a single literal.
+ */
+ if (n == 1 && op[-2] == (uint8_t)-1 && *lastliteral < 126)
+ {
+ state = (((*lastliteral) += 2) == 127 ? BASE : LITERAL);
+ op[-2] = op[-1]; /* replicate */
+ }
+ else
+ state = RUN;
+ goto again;
+ }
+ }
+ tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp);
+ tif->tif_rawcp = op;
+ return (1);
+}
+
+/*
+ * Encode a rectangular chunk of pixels. We break it up
+ * into row-sized pieces to insure that encoded runs do
+ * not span rows. Otherwise, there can be problems with
+ * the decoder if data is read, for example, by scanlines
+ * when it was encoded by strips.
+ */
+static int PackBitsEncodeChunk(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
+{
+ tmsize_t rowsize = *(tmsize_t *)tif->tif_data;
+
+ while (cc > 0)
+ {
+ tmsize_t chunk = rowsize;
+
+ if (cc < chunk)
+ chunk = cc;
+
+ if (PackBitsEncode(tif, bp, chunk, s) < 0)
+ return (-1);
+ bp += chunk;
+ cc -= chunk;
+ }
+ return (1);
+}
+
+static int PackBitsDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
+{
+ static const char module[] = "PackBitsDecode";
+ int8_t *bp;
+ tmsize_t cc;
+ long n;
+ int b;
+
+ (void)s;
+ bp = (int8_t *)tif->tif_rawcp;
+ cc = tif->tif_rawcc;
+ while (cc > 0 && occ > 0)
+ {
+ n = (long)*bp++;
+ cc--;
+ if (n < 0)
+ { /* replicate next byte -n+1 times */
+ if (n == -128) /* nop */
+ continue;
+ n = -n + 1;
+ if (occ < (tmsize_t)n)
+ {
+ TIFFWarningExtR(tif, module,
+ "Discarding %" TIFF_SSIZE_FORMAT
+ " bytes to avoid buffer overrun",
+ (tmsize_t)n - occ);
+ n = (long)occ;
+ }
+ if (cc == 0)
+ {
+ TIFFWarningExtR(
+ tif, module,
+ "Terminating PackBitsDecode due to lack of data.");
+ break;
+ }
+ occ -= n;
+ b = *bp++;
+ cc--;
+ while (n-- > 0)
+ *op++ = (uint8_t)b;
+ }
+ else
+ { /* copy next n+1 bytes literally */
+ if (occ < (tmsize_t)(n + 1))
+ {
+ TIFFWarningExtR(tif, module,
+ "Discarding %" TIFF_SSIZE_FORMAT
+ " bytes to avoid buffer overrun",
+ (tmsize_t)n - occ + 1);
+ n = (long)occ - 1;
+ }
+ if (cc < (tmsize_t)(n + 1))
+ {
+ TIFFWarningExtR(
+ tif, module,
+ "Terminating PackBitsDecode due to lack of data.");
+ break;
+ }
+ _TIFFmemcpy(op, bp, ++n);
+ op += n;
+ occ -= n;
+ bp += n;
+ cc -= n;
+ }
+ }
+ tif->tif_rawcp = (uint8_t *)bp;
+ tif->tif_rawcc = cc;
+ if (occ > 0)
+ {
+ TIFFErrorExtR(tif, module, "Not enough data for scanline %" PRIu32,
+ tif->tif_row);
+ return (0);
+ }
+ return (1);
+}
+
+int TIFFInitPackBits(TIFF *tif, int scheme)
+{
+ (void)scheme;
+ tif->tif_decoderow = PackBitsDecode;
+ tif->tif_decodestrip = PackBitsDecode;
+ tif->tif_decodetile = PackBitsDecode;
+ tif->tif_preencode = PackBitsPreEncode;
+ tif->tif_postencode = PackBitsPostEncode;
+ tif->tif_encoderow = PackBitsEncode;
+ tif->tif_encodestrip = PackBitsEncodeChunk;
+ tif->tif_encodetile = PackBitsEncodeChunk;
+ return (1);
+}
+#endif /* PACKBITS_SUPPORT */
diff --git a/contrib/libs/libtiff/tif_pixarlog.c b/contrib/libs/libtiff/tif_pixarlog.c
new file mode 100644
index 0000000000..5c0346b6ec
--- /dev/null
+++ b/contrib/libs/libtiff/tif_pixarlog.c
@@ -0,0 +1,1670 @@
+/*
+ * Copyright (c) 1996-1997 Sam Leffler
+ * Copyright (c) 1996 Pixar
+ *
+ * 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
+ * Pixar, 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 Pixar, 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.
+ *
+ * IN NO EVENT SHALL PIXAR, 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
+ * OF THIS SOFTWARE.
+ */
+
+#include "tiffiop.h"
+#ifdef PIXARLOG_SUPPORT
+
+/*
+ * TIFF Library.
+ * PixarLog Compression Support
+ *
+ * Contributed by Dan McCoy.
+ *
+ * PixarLog film support uses the TIFF library to store companded
+ * 11 bit values into a tiff file, which are compressed using the
+ * zip compressor.
+ *
+ * The codec can take as input and produce as output 32-bit IEEE float values
+ * as well as 16-bit or 8-bit unsigned integer values.
+ *
+ * On writing any of the above are converted into the internal
+ * 11-bit log format. In the case of 8 and 16 bit values, the
+ * input is assumed to be unsigned linear color values that represent
+ * the range 0-1. In the case of IEEE values, the 0-1 range is assumed to
+ * be the normal linear color range, in addition over 1 values are
+ * accepted up to a value of about 25.0 to encode "hot" highlights and such.
+ * The encoding is lossless for 8-bit values, slightly lossy for the
+ * other bit depths. The actual color precision should be better
+ * than the human eye can perceive with extra room to allow for
+ * error introduced by further image computation. As with any quantized
+ * color format, it is possible to perform image calculations which
+ * expose the quantization error. This format should certainly be less
+ * susceptible to such errors than standard 8-bit encodings, but more
+ * susceptible than straight 16-bit or 32-bit encodings.
+ *
+ * On reading the internal format is converted to the desired output format.
+ * The program can request which format it desires by setting the internal
+ * pseudo tag TIFFTAG_PIXARLOGDATAFMT to one of these possible values:
+ * PIXARLOGDATAFMT_FLOAT = provide IEEE float values.
+ * PIXARLOGDATAFMT_16BIT = provide unsigned 16-bit integer values
+ * PIXARLOGDATAFMT_8BIT = provide unsigned 8-bit integer values
+ *
+ * alternately PIXARLOGDATAFMT_8BITABGR provides unsigned 8-bit integer
+ * values with the difference that if there are exactly three or four channels
+ * (rgb or rgba) it swaps the channel order (bgr or abgr).
+ *
+ * PIXARLOGDATAFMT_11BITLOG provides the internal encoding directly
+ * packed in 16-bit values. However no tools are supplied for interpreting
+ * these values.
+ *
+ * "hot" (over 1.0) areas written in floating point get clamped to
+ * 1.0 in the integer data types.
+ *
+ * When the file is closed after writing, the bit depth and sample format
+ * are set always to appear as if 8-bit data has been written into it.
+ * That way a naive program unaware of the particulars of the encoding
+ * gets the format it is most likely able to handle.
+ *
+ * The codec does it's own horizontal differencing step on the coded
+ * values so the libraries predictor stuff should be turned off.
+ * The codec also handle byte swapping the encoded values as necessary
+ * since the library does not have the information necessary
+ * to know the bit depth of the raw unencoded buffer.
+ *
+ * NOTE: This decoder does not appear to update tif_rawcp, and tif_rawcc.
+ * This can cause problems with the implementation of CHUNKY_STRIP_READ_SUPPORT
+ * as noted in http://trac.osgeo.org/gdal/ticket/3894. FrankW - Jan'11
+ */
+
+#include "tif_predict.h"
+#include "zlib.h"
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* Tables for converting to/from 11 bit coded values */
+
+#define TSIZE 2048 /* decode table size (11-bit tokens) */
+#define TSIZEP1 2049 /* Plus one for slop */
+#define ONE 1250 /* token value of 1.0 exactly */
+#define RATIO 1.004 /* nominal ratio for log part */
+
+#define CODE_MASK 0x7ff /* 11 bits. */
+
+static float Fltsize;
+static float LogK1, LogK2;
+
+#define REPEAT(n, op) \
+ { \
+ int i; \
+ i = n; \
+ do \
+ { \
+ i--; \
+ op; \
+ } while (i > 0); \
+ }
+
+static void horizontalAccumulateF(uint16_t *wp, int n, int stride, float *op,
+ float *ToLinearF)
+{
+ register unsigned int cr, cg, cb, ca, mask;
+ register float t0, t1, t2, t3;
+
+ if (n >= stride)
+ {
+ mask = CODE_MASK;
+ if (stride == 3)
+ {
+ t0 = ToLinearF[cr = (wp[0] & mask)];
+ t1 = ToLinearF[cg = (wp[1] & mask)];
+ t2 = ToLinearF[cb = (wp[2] & mask)];
+ op[0] = t0;
+ op[1] = t1;
+ op[2] = t2;
+ n -= 3;
+ while (n > 0)
+ {
+ wp += 3;
+ op += 3;
+ n -= 3;
+ t0 = ToLinearF[(cr += wp[0]) & mask];
+ t1 = ToLinearF[(cg += wp[1]) & mask];
+ t2 = ToLinearF[(cb += wp[2]) & mask];
+ op[0] = t0;
+ op[1] = t1;
+ op[2] = t2;
+ }
+ }
+ else if (stride == 4)
+ {
+ t0 = ToLinearF[cr = (wp[0] & mask)];
+ t1 = ToLinearF[cg = (wp[1] & mask)];
+ t2 = ToLinearF[cb = (wp[2] & mask)];
+ t3 = ToLinearF[ca = (wp[3] & mask)];
+ op[0] = t0;
+ op[1] = t1;
+ op[2] = t2;
+ op[3] = t3;
+ n -= 4;
+ while (n > 0)
+ {
+ wp += 4;
+ op += 4;
+ n -= 4;
+ t0 = ToLinearF[(cr += wp[0]) & mask];
+ t1 = ToLinearF[(cg += wp[1]) & mask];
+ t2 = ToLinearF[(cb += wp[2]) & mask];
+ t3 = ToLinearF[(ca += wp[3]) & mask];
+ op[0] = t0;
+ op[1] = t1;
+ op[2] = t2;
+ op[3] = t3;
+ }
+ }
+ else
+ {
+ REPEAT(stride, *op = ToLinearF[*wp & mask]; wp++; op++)
+ n -= stride;
+ while (n > 0)
+ {
+ REPEAT(stride, wp[stride] += *wp; *op = ToLinearF[*wp & mask];
+ wp++; op++)
+ n -= stride;
+ }
+ }
+ }
+}
+
+static void horizontalAccumulate12(uint16_t *wp, int n, int stride, int16_t *op,
+ float *ToLinearF)
+{
+ register unsigned int cr, cg, cb, ca, mask;
+ register float t0, t1, t2, t3;
+
+#define SCALE12 2048.0F
+#define CLAMP12(t) (((t) < 3071) ? (uint16_t)(t) : 3071)
+
+ if (n >= stride)
+ {
+ mask = CODE_MASK;
+ if (stride == 3)
+ {
+ t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12;
+ t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12;
+ t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12;
+ op[0] = CLAMP12(t0);
+ op[1] = CLAMP12(t1);
+ op[2] = CLAMP12(t2);
+ n -= 3;
+ while (n > 0)
+ {
+ wp += 3;
+ op += 3;
+ n -= 3;
+ t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12;
+ t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12;
+ t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12;
+ op[0] = CLAMP12(t0);
+ op[1] = CLAMP12(t1);
+ op[2] = CLAMP12(t2);
+ }
+ }
+ else if (stride == 4)
+ {
+ t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12;
+ t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12;
+ t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12;
+ t3 = ToLinearF[ca = (wp[3] & mask)] * SCALE12;
+ op[0] = CLAMP12(t0);
+ op[1] = CLAMP12(t1);
+ op[2] = CLAMP12(t2);
+ op[3] = CLAMP12(t3);
+ n -= 4;
+ while (n > 0)
+ {
+ wp += 4;
+ op += 4;
+ n -= 4;
+ t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12;
+ t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12;
+ t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12;
+ t3 = ToLinearF[(ca += wp[3]) & mask] * SCALE12;
+ op[0] = CLAMP12(t0);
+ op[1] = CLAMP12(t1);
+ op[2] = CLAMP12(t2);
+ op[3] = CLAMP12(t3);
+ }
+ }
+ else
+ {
+ REPEAT(stride, t0 = ToLinearF[*wp & mask] * SCALE12;
+ *op = CLAMP12(t0); wp++; op++)
+ n -= stride;
+ while (n > 0)
+ {
+ REPEAT(stride, wp[stride] += *wp;
+ t0 = ToLinearF[wp[stride] & mask] * SCALE12;
+ *op = CLAMP12(t0); wp++; op++)
+ n -= stride;
+ }
+ }
+ }
+}
+
+static void horizontalAccumulate16(uint16_t *wp, int n, int stride,
+ uint16_t *op, uint16_t *ToLinear16)
+{
+ register unsigned int cr, cg, cb, ca, mask;
+
+ if (n >= stride)
+ {
+ mask = CODE_MASK;
+ if (stride == 3)
+ {
+ op[0] = ToLinear16[cr = (wp[0] & mask)];
+ op[1] = ToLinear16[cg = (wp[1] & mask)];
+ op[2] = ToLinear16[cb = (wp[2] & mask)];
+ n -= 3;
+ while (n > 0)
+ {
+ wp += 3;
+ op += 3;
+ n -= 3;
+ op[0] = ToLinear16[(cr += wp[0]) & mask];
+ op[1] = ToLinear16[(cg += wp[1]) & mask];
+ op[2] = ToLinear16[(cb += wp[2]) & mask];
+ }
+ }
+ else if (stride == 4)
+ {
+ op[0] = ToLinear16[cr = (wp[0] & mask)];
+ op[1] = ToLinear16[cg = (wp[1] & mask)];
+ op[2] = ToLinear16[cb = (wp[2] & mask)];
+ op[3] = ToLinear16[ca = (wp[3] & mask)];
+ n -= 4;
+ while (n > 0)
+ {
+ wp += 4;
+ op += 4;
+ n -= 4;
+ op[0] = ToLinear16[(cr += wp[0]) & mask];
+ op[1] = ToLinear16[(cg += wp[1]) & mask];
+ op[2] = ToLinear16[(cb += wp[2]) & mask];
+ op[3] = ToLinear16[(ca += wp[3]) & mask];
+ }
+ }
+ else
+ {
+ REPEAT(stride, *op = ToLinear16[*wp & mask]; wp++; op++)
+ n -= stride;
+ while (n > 0)
+ {
+ REPEAT(stride, wp[stride] += *wp; *op = ToLinear16[*wp & mask];
+ wp++; op++)
+ n -= stride;
+ }
+ }
+ }
+}
+
+/*
+ * Returns the log encoded 11-bit values with the horizontal
+ * differencing undone.
+ */
+static void horizontalAccumulate11(uint16_t *wp, int n, int stride,
+ uint16_t *op)
+{
+ register unsigned int cr, cg, cb, ca, mask;
+
+ if (n >= stride)
+ {
+ mask = CODE_MASK;
+ if (stride == 3)
+ {
+ op[0] = wp[0];
+ op[1] = wp[1];
+ op[2] = wp[2];
+ cr = wp[0];
+ cg = wp[1];
+ cb = wp[2];
+ n -= 3;
+ while (n > 0)
+ {
+ wp += 3;
+ op += 3;
+ n -= 3;
+ op[0] = (uint16_t)((cr += wp[0]) & mask);
+ op[1] = (uint16_t)((cg += wp[1]) & mask);
+ op[2] = (uint16_t)((cb += wp[2]) & mask);
+ }
+ }
+ else if (stride == 4)
+ {
+ op[0] = wp[0];
+ op[1] = wp[1];
+ op[2] = wp[2];
+ op[3] = wp[3];
+ cr = wp[0];
+ cg = wp[1];
+ cb = wp[2];
+ ca = wp[3];
+ n -= 4;
+ while (n > 0)
+ {
+ wp += 4;
+ op += 4;
+ n -= 4;
+ op[0] = (uint16_t)((cr += wp[0]) & mask);
+ op[1] = (uint16_t)((cg += wp[1]) & mask);
+ op[2] = (uint16_t)((cb += wp[2]) & mask);
+ op[3] = (uint16_t)((ca += wp[3]) & mask);
+ }
+ }
+ else
+ {
+ REPEAT(stride, *op = *wp & mask; wp++; op++)
+ n -= stride;
+ while (n > 0)
+ {
+ REPEAT(stride, wp[stride] += *wp; *op = *wp & mask; wp++; op++)
+ n -= stride;
+ }
+ }
+ }
+}
+
+static void horizontalAccumulate8(uint16_t *wp, int n, int stride,
+ unsigned char *op, unsigned char *ToLinear8)
+{
+ register unsigned int cr, cg, cb, ca, mask;
+
+ if (n >= stride)
+ {
+ mask = CODE_MASK;
+ if (stride == 3)
+ {
+ op[0] = ToLinear8[cr = (wp[0] & mask)];
+ op[1] = ToLinear8[cg = (wp[1] & mask)];
+ op[2] = ToLinear8[cb = (wp[2] & mask)];
+ n -= 3;
+ while (n > 0)
+ {
+ n -= 3;
+ wp += 3;
+ op += 3;
+ op[0] = ToLinear8[(cr += wp[0]) & mask];
+ op[1] = ToLinear8[(cg += wp[1]) & mask];
+ op[2] = ToLinear8[(cb += wp[2]) & mask];
+ }
+ }
+ else if (stride == 4)
+ {
+ op[0] = ToLinear8[cr = (wp[0] & mask)];
+ op[1] = ToLinear8[cg = (wp[1] & mask)];
+ op[2] = ToLinear8[cb = (wp[2] & mask)];
+ op[3] = ToLinear8[ca = (wp[3] & mask)];
+ n -= 4;
+ while (n > 0)
+ {
+ n -= 4;
+ wp += 4;
+ op += 4;
+ op[0] = ToLinear8[(cr += wp[0]) & mask];
+ op[1] = ToLinear8[(cg += wp[1]) & mask];
+ op[2] = ToLinear8[(cb += wp[2]) & mask];
+ op[3] = ToLinear8[(ca += wp[3]) & mask];
+ }
+ }
+ else
+ {
+ REPEAT(stride, *op = ToLinear8[*wp & mask]; wp++; op++)
+ n -= stride;
+ while (n > 0)
+ {
+ REPEAT(stride, wp[stride] += *wp; *op = ToLinear8[*wp & mask];
+ wp++; op++)
+ n -= stride;
+ }
+ }
+ }
+}
+
+static void horizontalAccumulate8abgr(uint16_t *wp, int n, int stride,
+ unsigned char *op,
+ unsigned char *ToLinear8)
+{
+ register unsigned int cr, cg, cb, ca, mask;
+ register unsigned char t0, t1, t2, t3;
+
+ if (n >= stride)
+ {
+ mask = CODE_MASK;
+ if (stride == 3)
+ {
+ op[0] = 0;
+ t1 = ToLinear8[cb = (wp[2] & mask)];
+ t2 = ToLinear8[cg = (wp[1] & mask)];
+ t3 = ToLinear8[cr = (wp[0] & mask)];
+ op[1] = t1;
+ op[2] = t2;
+ op[3] = t3;
+ n -= 3;
+ while (n > 0)
+ {
+ n -= 3;
+ wp += 3;
+ op += 4;
+ op[0] = 0;
+ t1 = ToLinear8[(cb += wp[2]) & mask];
+ t2 = ToLinear8[(cg += wp[1]) & mask];
+ t3 = ToLinear8[(cr += wp[0]) & mask];
+ op[1] = t1;
+ op[2] = t2;
+ op[3] = t3;
+ }
+ }
+ else if (stride == 4)
+ {
+ t0 = ToLinear8[ca = (wp[3] & mask)];
+ t1 = ToLinear8[cb = (wp[2] & mask)];
+ t2 = ToLinear8[cg = (wp[1] & mask)];
+ t3 = ToLinear8[cr = (wp[0] & mask)];
+ op[0] = t0;
+ op[1] = t1;
+ op[2] = t2;
+ op[3] = t3;
+ n -= 4;
+ while (n > 0)
+ {
+ n -= 4;
+ wp += 4;
+ op += 4;
+ t0 = ToLinear8[(ca += wp[3]) & mask];
+ t1 = ToLinear8[(cb += wp[2]) & mask];
+ t2 = ToLinear8[(cg += wp[1]) & mask];
+ t3 = ToLinear8[(cr += wp[0]) & mask];
+ op[0] = t0;
+ op[1] = t1;
+ op[2] = t2;
+ op[3] = t3;
+ }
+ }
+ else
+ {
+ REPEAT(stride, *op = ToLinear8[*wp & mask]; wp++; op++)
+ n -= stride;
+ while (n > 0)
+ {
+ REPEAT(stride, wp[stride] += *wp; *op = ToLinear8[*wp & mask];
+ wp++; op++)
+ n -= stride;
+ }
+ }
+ }
+}
+
+/*
+ * State block for each open TIFF
+ * file using PixarLog compression/decompression.
+ */
+typedef struct
+{
+ TIFFPredictorState predict;
+ z_stream stream;
+ tmsize_t tbuf_size; /* only set/used on reading for now */
+ uint16_t *tbuf;
+ uint16_t stride;
+ int state;
+ int user_datafmt;
+ int quality;
+#define PLSTATE_INIT 1
+
+ TIFFVSetMethod vgetparent; /* super-class method */
+ TIFFVSetMethod vsetparent; /* super-class method */
+
+ float *ToLinearF;
+ uint16_t *ToLinear16;
+ unsigned char *ToLinear8;
+ uint16_t *FromLT2;
+ uint16_t *From14; /* Really for 16-bit data, but we shift down 2 */
+ uint16_t *From8;
+
+} PixarLogState;
+
+static int PixarLogMakeTables(TIFF *tif, PixarLogState *sp)
+{
+
+ /*
+ * We make several tables here to convert between various external
+ * representations (float, 16-bit, and 8-bit) and the internal
+ * 11-bit companded representation. The 11-bit representation has two
+ * distinct regions. A linear bottom end up through .018316 in steps
+ * of about .000073, and a region of constant ratio up to about 25.
+ * These floating point numbers are stored in the main table ToLinearF.
+ * All other tables are derived from this one. The tables (and the
+ * ratios) are continuous at the internal seam.
+ */
+
+ int nlin, lt2size;
+ int i, j;
+ double b, c, linstep, v;
+ float *ToLinearF;
+ uint16_t *ToLinear16;
+ unsigned char *ToLinear8;
+ uint16_t *FromLT2;
+ uint16_t *From14; /* Really for 16-bit data, but we shift down 2 */
+ uint16_t *From8;
+
+ c = log(RATIO);
+ nlin = (int)(1. / c); /* nlin must be an integer */
+ c = 1. / nlin;
+ b = exp(-c * ONE); /* multiplicative scale factor [b*exp(c*ONE) = 1] */
+ linstep = b * c * exp(1.);
+
+ LogK1 = (float)(1. / c); /* if (v >= 2) token = k1*log(v*k2) */
+ LogK2 = (float)(1. / b);
+ lt2size = (int)(2. / linstep) + 1;
+ FromLT2 = (uint16_t *)_TIFFmallocExt(tif, lt2size * sizeof(uint16_t));
+ From14 = (uint16_t *)_TIFFmallocExt(tif, 16384 * sizeof(uint16_t));
+ From8 = (uint16_t *)_TIFFmallocExt(tif, 256 * sizeof(uint16_t));
+ ToLinearF = (float *)_TIFFmallocExt(tif, TSIZEP1 * sizeof(float));
+ ToLinear16 = (uint16_t *)_TIFFmallocExt(tif, TSIZEP1 * sizeof(uint16_t));
+ ToLinear8 =
+ (unsigned char *)_TIFFmallocExt(tif, TSIZEP1 * sizeof(unsigned char));
+ if (FromLT2 == NULL || From14 == NULL || From8 == NULL ||
+ ToLinearF == NULL || ToLinear16 == NULL || ToLinear8 == NULL)
+ {
+ if (FromLT2)
+ _TIFFfreeExt(tif, FromLT2);
+ if (From14)
+ _TIFFfreeExt(tif, From14);
+ if (From8)
+ _TIFFfreeExt(tif, From8);
+ if (ToLinearF)
+ _TIFFfreeExt(tif, ToLinearF);
+ if (ToLinear16)
+ _TIFFfreeExt(tif, ToLinear16);
+ if (ToLinear8)
+ _TIFFfreeExt(tif, ToLinear8);
+ sp->FromLT2 = NULL;
+ sp->From14 = NULL;
+ sp->From8 = NULL;
+ sp->ToLinearF = NULL;
+ sp->ToLinear16 = NULL;
+ sp->ToLinear8 = NULL;
+ return 0;
+ }
+
+ j = 0;
+
+ for (i = 0; i < nlin; i++)
+ {
+ v = i * linstep;
+ ToLinearF[j++] = (float)v;
+ }
+
+ for (i = nlin; i < TSIZE; i++)
+ ToLinearF[j++] = (float)(b * exp(c * i));
+
+ ToLinearF[2048] = ToLinearF[2047];
+
+ for (i = 0; i < TSIZEP1; i++)
+ {
+ v = ToLinearF[i] * 65535.0 + 0.5;
+ ToLinear16[i] = (v > 65535.0) ? 65535 : (uint16_t)v;
+ v = ToLinearF[i] * 255.0 + 0.5;
+ ToLinear8[i] = (v > 255.0) ? 255 : (unsigned char)v;
+ }
+
+ j = 0;
+ for (i = 0; i < lt2size; i++)
+ {
+ if ((i * linstep) * (i * linstep) > ToLinearF[j] * ToLinearF[j + 1])
+ j++;
+ FromLT2[i] = (uint16_t)j;
+ }
+
+ /*
+ * Since we lose info anyway on 16-bit data, we set up a 14-bit
+ * table and shift 16-bit values down two bits on input.
+ * saves a little table space.
+ */
+ j = 0;
+ for (i = 0; i < 16384; i++)
+ {
+ while ((i / 16383.) * (i / 16383.) > ToLinearF[j] * ToLinearF[j + 1])
+ j++;
+ From14[i] = (uint16_t)j;
+ }
+
+ j = 0;
+ for (i = 0; i < 256; i++)
+ {
+ while ((i / 255.) * (i / 255.) > ToLinearF[j] * ToLinearF[j + 1])
+ j++;
+ From8[i] = (uint16_t)j;
+ }
+
+ Fltsize = (float)(lt2size / 2);
+
+ sp->ToLinearF = ToLinearF;
+ sp->ToLinear16 = ToLinear16;
+ sp->ToLinear8 = ToLinear8;
+ sp->FromLT2 = FromLT2;
+ sp->From14 = From14;
+ sp->From8 = From8;
+
+ return 1;
+}
+
+#define DecoderState(tif) ((PixarLogState *)(tif)->tif_data)
+#define EncoderState(tif) ((PixarLogState *)(tif)->tif_data)
+
+static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
+static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s);
+
+#define PIXARLOGDATAFMT_UNKNOWN -1
+
+static int PixarLogGuessDataFmt(TIFFDirectory *td)
+{
+ int guess = PIXARLOGDATAFMT_UNKNOWN;
+ int format = td->td_sampleformat;
+
+ /* If the user didn't tell us his datafmt,
+ * take our best guess from the bitspersample.
+ */
+ switch (td->td_bitspersample)
+ {
+ case 32:
+ if (format == SAMPLEFORMAT_IEEEFP)
+ guess = PIXARLOGDATAFMT_FLOAT;
+ break;
+ case 16:
+ if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
+ guess = PIXARLOGDATAFMT_16BIT;
+ break;
+ case 12:
+ if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_INT)
+ guess = PIXARLOGDATAFMT_12BITPICIO;
+ break;
+ case 11:
+ if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
+ guess = PIXARLOGDATAFMT_11BITLOG;
+ break;
+ case 8:
+ if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
+ guess = PIXARLOGDATAFMT_8BIT;
+ break;
+ }
+
+ return guess;
+}
+
+static tmsize_t multiply_ms(tmsize_t m1, tmsize_t m2)
+{
+ return _TIFFMultiplySSize(NULL, m1, m2, NULL);
+}
+
+static tmsize_t add_ms(tmsize_t m1, tmsize_t m2)
+{
+ assert(m1 >= 0 && m2 >= 0);
+ /* if either input is zero, assume overflow already occurred */
+ if (m1 == 0 || m2 == 0)
+ return 0;
+ else if (m1 > TIFF_TMSIZE_T_MAX - m2)
+ return 0;
+
+ return m1 + m2;
+}
+
+static int PixarLogFixupTags(TIFF *tif)
+{
+ (void)tif;
+ return (1);
+}
+
+static int PixarLogSetupDecode(TIFF *tif)
+{
+ static const char module[] = "PixarLogSetupDecode";
+ TIFFDirectory *td = &tif->tif_dir;
+ PixarLogState *sp = DecoderState(tif);
+ tmsize_t tbuf_size;
+ uint32_t strip_height;
+
+ assert(sp != NULL);
+
+ /* This function can possibly be called several times by */
+ /* PredictorSetupDecode() if this function succeeds but */
+ /* PredictorSetup() fails */
+ if ((sp->state & PLSTATE_INIT) != 0)
+ return 1;
+
+ strip_height = td->td_rowsperstrip;
+ if (strip_height > td->td_imagelength)
+ strip_height = td->td_imagelength;
+
+ /* Make sure no byte swapping happens on the data
+ * after decompression. */
+ tif->tif_postdecode = _TIFFNoPostDecode;
+
+ /* for some reason, we can't do this in TIFFInitPixarLog */
+
+ sp->stride =
+ (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel
+ : 1);
+ tbuf_size = multiply_ms(
+ multiply_ms(multiply_ms(sp->stride, td->td_imagewidth), strip_height),
+ sizeof(uint16_t));
+ /* add one more stride in case input ends mid-stride */
+ tbuf_size = add_ms(tbuf_size, sizeof(uint16_t) * sp->stride);
+ if (tbuf_size == 0)
+ return (0); /* TODO: this is an error return without error report
+ through TIFFErrorExt */
+ sp->tbuf = (uint16_t *)_TIFFmallocExt(tif, tbuf_size);
+ if (sp->tbuf == NULL)
+ return (0);
+ sp->tbuf_size = tbuf_size;
+ if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
+ sp->user_datafmt = PixarLogGuessDataFmt(td);
+ if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
+ {
+ _TIFFfreeExt(tif, sp->tbuf);
+ sp->tbuf = NULL;
+ sp->tbuf_size = 0;
+ TIFFErrorExtR(tif, module,
+ "PixarLog compression can't handle bits depth/data "
+ "format combination (depth: %" PRIu16 ")",
+ td->td_bitspersample);
+ return (0);
+ }
+
+ if (inflateInit(&sp->stream) != Z_OK)
+ {
+ _TIFFfreeExt(tif, sp->tbuf);
+ sp->tbuf = NULL;
+ sp->tbuf_size = 0;
+ TIFFErrorExtR(tif, module, "%s",
+ sp->stream.msg ? sp->stream.msg : "(null)");
+ return (0);
+ }
+ else
+ {
+ sp->state |= PLSTATE_INIT;
+ return (1);
+ }
+}
+
+/*
+ * Setup state for decoding a strip.
+ */
+static int PixarLogPreDecode(TIFF *tif, uint16_t s)
+{
+ static const char module[] = "PixarLogPreDecode";
+ PixarLogState *sp = DecoderState(tif);
+
+ (void)s;
+ assert(sp != NULL);
+ sp->stream.next_in = tif->tif_rawdata;
+ assert(sizeof(sp->stream.avail_in) == 4); /* if this assert gets raised,
+ we need to simplify this code to reflect a ZLib that is likely updated
+ to deal with 8byte memory sizes, though this code will respond
+ appropriately even before we simplify it */
+ sp->stream.avail_in = (uInt)tif->tif_rawcc;
+ if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc)
+ {
+ TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size");
+ return (0);
+ }
+ return (inflateReset(&sp->stream) == Z_OK);
+}
+
+static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
+{
+ static const char module[] = "PixarLogDecode";
+ TIFFDirectory *td = &tif->tif_dir;
+ PixarLogState *sp = DecoderState(tif);
+ tmsize_t i;
+ tmsize_t nsamples;
+ int llen;
+ uint16_t *up;
+
+ switch (sp->user_datafmt)
+ {
+ case PIXARLOGDATAFMT_FLOAT:
+ nsamples = occ / sizeof(float); /* XXX float == 32 bits */
+ break;
+ case PIXARLOGDATAFMT_16BIT:
+ case PIXARLOGDATAFMT_12BITPICIO:
+ case PIXARLOGDATAFMT_11BITLOG:
+ nsamples = occ / sizeof(uint16_t); /* XXX uint16_t == 16 bits */
+ break;
+ case PIXARLOGDATAFMT_8BIT:
+ case PIXARLOGDATAFMT_8BITABGR:
+ nsamples = occ;
+ break;
+ default:
+ TIFFErrorExtR(tif, module,
+ "%" PRIu16 " bit input not supported in PixarLog",
+ td->td_bitspersample);
+ return 0;
+ }
+
+ llen = sp->stride * td->td_imagewidth;
+
+ (void)s;
+ assert(sp != NULL);
+
+ sp->stream.next_in = tif->tif_rawcp;
+ sp->stream.avail_in = (uInt)tif->tif_rawcc;
+
+ sp->stream.next_out = (unsigned char *)sp->tbuf;
+ assert(sizeof(sp->stream.avail_out) == 4); /* if this assert gets raised,
+ we need to simplify this code to reflect a ZLib that is likely updated
+ to deal with 8byte memory sizes, though this code will respond
+ appropriately even before we simplify it */
+ sp->stream.avail_out = (uInt)(nsamples * sizeof(uint16_t));
+ if (sp->stream.avail_out != nsamples * sizeof(uint16_t))
+ {
+ TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size");
+ return (0);
+ }
+ /* Check that we will not fill more than what was allocated */
+ if ((tmsize_t)sp->stream.avail_out > sp->tbuf_size)
+ {
+ TIFFErrorExtR(tif, module, "sp->stream.avail_out > sp->tbuf_size");
+ return (0);
+ }
+ do
+ {
+ int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
+ if (state == Z_STREAM_END)
+ {
+ break; /* XXX */
+ }
+ if (state == Z_DATA_ERROR)
+ {
+ TIFFErrorExtR(
+ tif, module, "Decoding error at scanline %" PRIu32 ", %s",
+ tif->tif_row, sp->stream.msg ? sp->stream.msg : "(null)");
+ return (0);
+ }
+ if (state != Z_OK)
+ {
+ TIFFErrorExtR(tif, module, "ZLib error: %s",
+ sp->stream.msg ? sp->stream.msg : "(null)");
+ return (0);
+ }
+ } while (sp->stream.avail_out > 0);
+
+ /* hopefully, we got all the bytes we needed */
+ if (sp->stream.avail_out != 0)
+ {
+ TIFFErrorExtR(tif, module,
+ "Not enough data at scanline %" PRIu32
+ " (short %u bytes)",
+ tif->tif_row, sp->stream.avail_out);
+ return (0);
+ }
+
+ tif->tif_rawcp = sp->stream.next_in;
+ tif->tif_rawcc = sp->stream.avail_in;
+
+ up = sp->tbuf;
+ /* Swap bytes in the data if from a different endian machine. */
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfShort(up, nsamples);
+
+ /*
+ * if llen is not an exact multiple of nsamples, the decode operation
+ * may overflow the output buffer, so truncate it enough to prevent
+ * that but still salvage as much data as possible.
+ */
+ if (nsamples % llen)
+ {
+ TIFFWarningExtR(tif, module,
+ "stride %d is not a multiple of sample count, "
+ "%" TIFF_SSIZE_FORMAT ", data truncated.",
+ llen, nsamples);
+ nsamples -= nsamples % llen;
+ }
+
+ for (i = 0; i < nsamples; i += llen, up += llen)
+ {
+ switch (sp->user_datafmt)
+ {
+ case PIXARLOGDATAFMT_FLOAT:
+ horizontalAccumulateF(up, llen, sp->stride, (float *)op,
+ sp->ToLinearF);
+ op += llen * sizeof(float);
+ break;
+ case PIXARLOGDATAFMT_16BIT:
+ horizontalAccumulate16(up, llen, sp->stride, (uint16_t *)op,
+ sp->ToLinear16);
+ op += llen * sizeof(uint16_t);
+ break;
+ case PIXARLOGDATAFMT_12BITPICIO:
+ horizontalAccumulate12(up, llen, sp->stride, (int16_t *)op,
+ sp->ToLinearF);
+ op += llen * sizeof(int16_t);
+ break;
+ case PIXARLOGDATAFMT_11BITLOG:
+ horizontalAccumulate11(up, llen, sp->stride, (uint16_t *)op);
+ op += llen * sizeof(uint16_t);
+ break;
+ case PIXARLOGDATAFMT_8BIT:
+ horizontalAccumulate8(up, llen, sp->stride, (unsigned char *)op,
+ sp->ToLinear8);
+ op += llen * sizeof(unsigned char);
+ break;
+ case PIXARLOGDATAFMT_8BITABGR:
+ horizontalAccumulate8abgr(up, llen, sp->stride,
+ (unsigned char *)op, sp->ToLinear8);
+ op += llen * sizeof(unsigned char);
+ break;
+ default:
+ TIFFErrorExtR(tif, module, "Unsupported bits/sample: %" PRIu16,
+ td->td_bitspersample);
+ return (0);
+ }
+ }
+
+ return (1);
+}
+
+static int PixarLogSetupEncode(TIFF *tif)
+{
+ static const char module[] = "PixarLogSetupEncode";
+ TIFFDirectory *td = &tif->tif_dir;
+ PixarLogState *sp = EncoderState(tif);
+ tmsize_t tbuf_size;
+
+ assert(sp != NULL);
+
+ /* for some reason, we can't do this in TIFFInitPixarLog */
+
+ sp->stride =
+ (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel
+ : 1);
+ tbuf_size =
+ multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth),
+ td->td_rowsperstrip),
+ sizeof(uint16_t));
+ if (tbuf_size == 0)
+ return (0); /* TODO: this is an error return without error report
+ through TIFFErrorExt */
+ sp->tbuf = (uint16_t *)_TIFFmallocExt(tif, tbuf_size);
+ if (sp->tbuf == NULL)
+ return (0);
+ if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
+ sp->user_datafmt = PixarLogGuessDataFmt(td);
+ if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
+ {
+ TIFFErrorExtR(tif, module,
+ "PixarLog compression can't handle %" PRIu16
+ " bit linear encodings",
+ td->td_bitspersample);
+ return (0);
+ }
+
+ if (deflateInit(&sp->stream, sp->quality) != Z_OK)
+ {
+ TIFFErrorExtR(tif, module, "%s",
+ sp->stream.msg ? sp->stream.msg : "(null)");
+ return (0);
+ }
+ else
+ {
+ sp->state |= PLSTATE_INIT;
+ return (1);
+ }
+}
+
+/*
+ * Reset encoding state at the start of a strip.
+ */
+static int PixarLogPreEncode(TIFF *tif, uint16_t s)
+{
+ static const char module[] = "PixarLogPreEncode";
+ PixarLogState *sp = EncoderState(tif);
+
+ (void)s;
+ assert(sp != NULL);
+ sp->stream.next_out = tif->tif_rawdata;
+ assert(sizeof(sp->stream.avail_out) == 4); /* if this assert gets raised,
+ we need to simplify this code to reflect a ZLib that is likely updated
+ to deal with 8byte memory sizes, though this code will respond
+ appropriately even before we simplify it */
+ sp->stream.avail_out = (uInt)tif->tif_rawdatasize;
+ if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
+ {
+ TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size");
+ return (0);
+ }
+ return (deflateReset(&sp->stream) == Z_OK);
+}
+
+static void horizontalDifferenceF(float *ip, int n, int stride, uint16_t *wp,
+ uint16_t *FromLT2)
+{
+ int32_t r1, g1, b1, a1, r2, g2, b2, a2, mask;
+ float fltsize = Fltsize;
+
+#define CLAMP(v) \
+ ((v < (float)0.) ? 0 \
+ : (v < (float)2.) ? FromLT2[(int)(v * fltsize)] \
+ : (v > (float)24.2) ? 2047 \
+ : LogK1 * log(v * LogK2) + 0.5)
+
+ mask = CODE_MASK;
+ if (n >= stride)
+ {
+ if (stride == 3)
+ {
+ r2 = wp[0] = (uint16_t)CLAMP(ip[0]);
+ g2 = wp[1] = (uint16_t)CLAMP(ip[1]);
+ b2 = wp[2] = (uint16_t)CLAMP(ip[2]);
+ n -= 3;
+ while (n > 0)
+ {
+ n -= 3;
+ wp += 3;
+ ip += 3;
+ r1 = (int32_t)CLAMP(ip[0]);
+ wp[0] = (uint16_t)((r1 - r2) & mask);
+ r2 = r1;
+ g1 = (int32_t)CLAMP(ip[1]);
+ wp[1] = (uint16_t)((g1 - g2) & mask);
+ g2 = g1;
+ b1 = (int32_t)CLAMP(ip[2]);
+ wp[2] = (uint16_t)((b1 - b2) & mask);
+ b2 = b1;
+ }
+ }
+ else if (stride == 4)
+ {
+ r2 = wp[0] = (uint16_t)CLAMP(ip[0]);
+ g2 = wp[1] = (uint16_t)CLAMP(ip[1]);
+ b2 = wp[2] = (uint16_t)CLAMP(ip[2]);
+ a2 = wp[3] = (uint16_t)CLAMP(ip[3]);
+ n -= 4;
+ while (n > 0)
+ {
+ n -= 4;
+ wp += 4;
+ ip += 4;
+ r1 = (int32_t)CLAMP(ip[0]);
+ wp[0] = (uint16_t)((r1 - r2) & mask);
+ r2 = r1;
+ g1 = (int32_t)CLAMP(ip[1]);
+ wp[1] = (uint16_t)((g1 - g2) & mask);
+ g2 = g1;
+ b1 = (int32_t)CLAMP(ip[2]);
+ wp[2] = (uint16_t)((b1 - b2) & mask);
+ b2 = b1;
+ a1 = (int32_t)CLAMP(ip[3]);
+ wp[3] = (uint16_t)((a1 - a2) & mask);
+ a2 = a1;
+ }
+ }
+ else
+ {
+ REPEAT(stride, wp[0] = (uint16_t)CLAMP(ip[0]); wp++; ip++)
+ n -= stride;
+ while (n > 0)
+ {
+ REPEAT(stride,
+ wp[0] = (uint16_t)(((int32_t)CLAMP(ip[0]) -
+ (int32_t)CLAMP(ip[-stride])) &
+ mask);
+ wp++; ip++)
+ n -= stride;
+ }
+ }
+ }
+}
+
+static void horizontalDifference16(unsigned short *ip, int n, int stride,
+ unsigned short *wp, uint16_t *From14)
+{
+ register int r1, g1, b1, a1, r2, g2, b2, a2, mask;
+
+/* assumption is unsigned pixel values */
+#undef CLAMP
+#define CLAMP(v) From14[(v) >> 2]
+
+ mask = CODE_MASK;
+ if (n >= stride)
+ {
+ if (stride == 3)
+ {
+ r2 = wp[0] = CLAMP(ip[0]);
+ g2 = wp[1] = CLAMP(ip[1]);
+ b2 = wp[2] = CLAMP(ip[2]);
+ n -= 3;
+ while (n > 0)
+ {
+ n -= 3;
+ wp += 3;
+ ip += 3;
+ r1 = CLAMP(ip[0]);
+ wp[0] = (uint16_t)((r1 - r2) & mask);
+ r2 = r1;
+ g1 = CLAMP(ip[1]);
+ wp[1] = (uint16_t)((g1 - g2) & mask);
+ g2 = g1;
+ b1 = CLAMP(ip[2]);
+ wp[2] = (uint16_t)((b1 - b2) & mask);
+ b2 = b1;
+ }
+ }
+ else if (stride == 4)
+ {
+ r2 = wp[0] = CLAMP(ip[0]);
+ g2 = wp[1] = CLAMP(ip[1]);
+ b2 = wp[2] = CLAMP(ip[2]);
+ a2 = wp[3] = CLAMP(ip[3]);
+ n -= 4;
+ while (n > 0)
+ {
+ n -= 4;
+ wp += 4;
+ ip += 4;
+ r1 = CLAMP(ip[0]);
+ wp[0] = (uint16_t)((r1 - r2) & mask);
+ r2 = r1;
+ g1 = CLAMP(ip[1]);
+ wp[1] = (uint16_t)((g1 - g2) & mask);
+ g2 = g1;
+ b1 = CLAMP(ip[2]);
+ wp[2] = (uint16_t)((b1 - b2) & mask);
+ b2 = b1;
+ a1 = CLAMP(ip[3]);
+ wp[3] = (uint16_t)((a1 - a2) & mask);
+ a2 = a1;
+ }
+ }
+ else
+ {
+ REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++)
+ n -= stride;
+ while (n > 0)
+ {
+ REPEAT(stride,
+ wp[0] = (uint16_t)((CLAMP(ip[0]) - CLAMP(ip[-stride])) &
+ mask);
+ wp++; ip++)
+ n -= stride;
+ }
+ }
+ }
+}
+
+static void horizontalDifference8(unsigned char *ip, int n, int stride,
+ unsigned short *wp, uint16_t *From8)
+{
+ register int r1, g1, b1, a1, r2, g2, b2, a2, mask;
+
+#undef CLAMP
+#define CLAMP(v) (From8[(v)])
+
+ mask = CODE_MASK;
+ if (n >= stride)
+ {
+ if (stride == 3)
+ {
+ r2 = wp[0] = CLAMP(ip[0]);
+ g2 = wp[1] = CLAMP(ip[1]);
+ b2 = wp[2] = CLAMP(ip[2]);
+ n -= 3;
+ while (n > 0)
+ {
+ n -= 3;
+ r1 = CLAMP(ip[3]);
+ wp[3] = (uint16_t)((r1 - r2) & mask);
+ r2 = r1;
+ g1 = CLAMP(ip[4]);
+ wp[4] = (uint16_t)((g1 - g2) & mask);
+ g2 = g1;
+ b1 = CLAMP(ip[5]);
+ wp[5] = (uint16_t)((b1 - b2) & mask);
+ b2 = b1;
+ wp += 3;
+ ip += 3;
+ }
+ }
+ else if (stride == 4)
+ {
+ r2 = wp[0] = CLAMP(ip[0]);
+ g2 = wp[1] = CLAMP(ip[1]);
+ b2 = wp[2] = CLAMP(ip[2]);
+ a2 = wp[3] = CLAMP(ip[3]);
+ n -= 4;
+ while (n > 0)
+ {
+ n -= 4;
+ r1 = CLAMP(ip[4]);
+ wp[4] = (uint16_t)((r1 - r2) & mask);
+ r2 = r1;
+ g1 = CLAMP(ip[5]);
+ wp[5] = (uint16_t)((g1 - g2) & mask);
+ g2 = g1;
+ b1 = CLAMP(ip[6]);
+ wp[6] = (uint16_t)((b1 - b2) & mask);
+ b2 = b1;
+ a1 = CLAMP(ip[7]);
+ wp[7] = (uint16_t)((a1 - a2) & mask);
+ a2 = a1;
+ wp += 4;
+ ip += 4;
+ }
+ }
+ else
+ {
+ REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++)
+ n -= stride;
+ while (n > 0)
+ {
+ REPEAT(stride,
+ wp[0] = (uint16_t)((CLAMP(ip[0]) - CLAMP(ip[-stride])) &
+ mask);
+ wp++; ip++)
+ n -= stride;
+ }
+ }
+ }
+}
+
+/*
+ * Encode a chunk of pixels.
+ */
+static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
+{
+ static const char module[] = "PixarLogEncode";
+ TIFFDirectory *td = &tif->tif_dir;
+ PixarLogState *sp = EncoderState(tif);
+ tmsize_t i;
+ tmsize_t n;
+ int llen;
+ unsigned short *up;
+
+ (void)s;
+
+ switch (sp->user_datafmt)
+ {
+ case PIXARLOGDATAFMT_FLOAT:
+ n = cc / sizeof(float); /* XXX float == 32 bits */
+ break;
+ case PIXARLOGDATAFMT_16BIT:
+ case PIXARLOGDATAFMT_12BITPICIO:
+ case PIXARLOGDATAFMT_11BITLOG:
+ n = cc / sizeof(uint16_t); /* XXX uint16_t == 16 bits */
+ break;
+ case PIXARLOGDATAFMT_8BIT:
+ case PIXARLOGDATAFMT_8BITABGR:
+ n = cc;
+ break;
+ default:
+ TIFFErrorExtR(tif, module,
+ "%" PRIu16 " bit input not supported in PixarLog",
+ td->td_bitspersample);
+ return 0;
+ }
+
+ llen = sp->stride * td->td_imagewidth;
+ /* Check against the number of elements (of size uint16_t) of sp->tbuf */
+ if (n > ((tmsize_t)td->td_rowsperstrip * llen))
+ {
+ TIFFErrorExtR(tif, module, "Too many input bytes provided");
+ return 0;
+ }
+
+ for (i = 0, up = sp->tbuf; i < n; i += llen, up += llen)
+ {
+ switch (sp->user_datafmt)
+ {
+ case PIXARLOGDATAFMT_FLOAT:
+ horizontalDifferenceF((float *)bp, llen, sp->stride, up,
+ sp->FromLT2);
+ bp += llen * sizeof(float);
+ break;
+ case PIXARLOGDATAFMT_16BIT:
+ horizontalDifference16((uint16_t *)bp, llen, sp->stride, up,
+ sp->From14);
+ bp += llen * sizeof(uint16_t);
+ break;
+ case PIXARLOGDATAFMT_8BIT:
+ horizontalDifference8((unsigned char *)bp, llen, sp->stride, up,
+ sp->From8);
+ bp += llen * sizeof(unsigned char);
+ break;
+ default:
+ TIFFErrorExtR(tif, module,
+ "%" PRIu16 " bit input not supported in PixarLog",
+ td->td_bitspersample);
+ return 0;
+ }
+ }
+
+ sp->stream.next_in = (unsigned char *)sp->tbuf;
+ assert(sizeof(sp->stream.avail_in) == 4); /* if this assert gets raised,
+ we need to simplify this code to reflect a ZLib that is likely updated
+ to deal with 8byte memory sizes, though this code will respond
+ appropriately even before we simplify it */
+ sp->stream.avail_in = (uInt)(n * sizeof(uint16_t));
+ if ((sp->stream.avail_in / sizeof(uint16_t)) != (uInt)n)
+ {
+ TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size");
+ return (0);
+ }
+
+ do
+ {
+ if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK)
+ {
+ TIFFErrorExtR(tif, module, "Encoder error: %s",
+ sp->stream.msg ? sp->stream.msg : "(null)");
+ return (0);
+ }
+ if (sp->stream.avail_out == 0)
+ {
+ tif->tif_rawcc = tif->tif_rawdatasize;
+ if (!TIFFFlushData1(tif))
+ return 0;
+ sp->stream.next_out = tif->tif_rawdata;
+ sp->stream.avail_out =
+ (uInt)tif
+ ->tif_rawdatasize; /* this is a safe typecast, as check is
+ made already in PixarLogPreEncode */
+ }
+ } while (sp->stream.avail_in > 0);
+ return (1);
+}
+
+/*
+ * Finish off an encoded strip by flushing the last
+ * string and tacking on an End Of Information code.
+ */
+
+static int PixarLogPostEncode(TIFF *tif)
+{
+ static const char module[] = "PixarLogPostEncode";
+ PixarLogState *sp = EncoderState(tif);
+ int state;
+
+ sp->stream.avail_in = 0;
+
+ do
+ {
+ state = deflate(&sp->stream, Z_FINISH);
+ switch (state)
+ {
+ case Z_STREAM_END:
+ case Z_OK:
+ if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
+ {
+ tif->tif_rawcc =
+ tif->tif_rawdatasize - sp->stream.avail_out;
+ if (!TIFFFlushData1(tif))
+ return 0;
+ sp->stream.next_out = tif->tif_rawdata;
+ sp->stream.avail_out =
+ (uInt)tif->tif_rawdatasize; /* this is a safe typecast,
+ as check is made already
+ in PixarLogPreEncode */
+ }
+ break;
+ default:
+ TIFFErrorExtR(tif, module, "ZLib error: %s",
+ sp->stream.msg ? sp->stream.msg : "(null)");
+ return (0);
+ }
+ } while (state != Z_STREAM_END);
+ return (1);
+}
+
+static void PixarLogClose(TIFF *tif)
+{
+ PixarLogState *sp = (PixarLogState *)tif->tif_data;
+ TIFFDirectory *td = &tif->tif_dir;
+
+ assert(sp != 0);
+ /* In a really sneaky (and really incorrect, and untruthful, and
+ * troublesome, and error-prone) maneuver that completely goes against
+ * the spirit of TIFF, and breaks TIFF, on close, we covertly
+ * modify both bitspersample and sampleformat in the directory to
+ * indicate 8-bit linear. This way, the decode "just works" even for
+ * readers that don't know about PixarLog, or how to set
+ * the PIXARLOGDATFMT pseudo-tag.
+ */
+
+ if (sp->state & PLSTATE_INIT)
+ {
+ /* We test the state to avoid an issue such as in
+ * http://bugzilla.maptools.org/show_bug.cgi?id=2604
+ * What appends in that case is that the bitspersample is 1 and
+ * a TransferFunction is set. The size of the TransferFunction
+ * depends on 1<<bitspersample. So if we increase it, an access
+ * out of the buffer will happen at directory flushing.
+ * Another option would be to clear those targs.
+ */
+ td->td_bitspersample = 8;
+ td->td_sampleformat = SAMPLEFORMAT_UINT;
+ }
+}
+
+static void PixarLogCleanup(TIFF *tif)
+{
+ PixarLogState *sp = (PixarLogState *)tif->tif_data;
+
+ assert(sp != 0);
+
+ (void)TIFFPredictorCleanup(tif);
+
+ tif->tif_tagmethods.vgetfield = sp->vgetparent;
+ tif->tif_tagmethods.vsetfield = sp->vsetparent;
+
+ if (sp->FromLT2)
+ _TIFFfreeExt(tif, sp->FromLT2);
+ if (sp->From14)
+ _TIFFfreeExt(tif, sp->From14);
+ if (sp->From8)
+ _TIFFfreeExt(tif, sp->From8);
+ if (sp->ToLinearF)
+ _TIFFfreeExt(tif, sp->ToLinearF);
+ if (sp->ToLinear16)
+ _TIFFfreeExt(tif, sp->ToLinear16);
+ if (sp->ToLinear8)
+ _TIFFfreeExt(tif, sp->ToLinear8);
+ if (sp->state & PLSTATE_INIT)
+ {
+ if (tif->tif_mode == O_RDONLY)
+ inflateEnd(&sp->stream);
+ else
+ deflateEnd(&sp->stream);
+ }
+ if (sp->tbuf)
+ _TIFFfreeExt(tif, sp->tbuf);
+ _TIFFfreeExt(tif, sp);
+ tif->tif_data = NULL;
+
+ _TIFFSetDefaultCompressionState(tif);
+}
+
+static int PixarLogVSetField(TIFF *tif, uint32_t tag, va_list ap)
+{
+ static const char module[] = "PixarLogVSetField";
+ PixarLogState *sp = (PixarLogState *)tif->tif_data;
+ int result;
+
+ switch (tag)
+ {
+ case TIFFTAG_PIXARLOGQUALITY:
+ sp->quality = (int)va_arg(ap, int);
+ if (tif->tif_mode != O_RDONLY && (sp->state & PLSTATE_INIT))
+ {
+ if (deflateParams(&sp->stream, sp->quality,
+ Z_DEFAULT_STRATEGY) != Z_OK)
+ {
+ TIFFErrorExtR(tif, module, "ZLib error: %s",
+ sp->stream.msg ? sp->stream.msg : "(null)");
+ return (0);
+ }
+ }
+ return (1);
+ case TIFFTAG_PIXARLOGDATAFMT:
+ sp->user_datafmt = (int)va_arg(ap, int);
+ /* Tweak the TIFF header so that the rest of libtiff knows what
+ * size of data will be passed between app and library, and
+ * assume that the app knows what it is doing and is not
+ * confused by these header manipulations...
+ */
+ switch (sp->user_datafmt)
+ {
+ case PIXARLOGDATAFMT_8BIT:
+ case PIXARLOGDATAFMT_8BITABGR:
+ TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
+ TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
+ break;
+ case PIXARLOGDATAFMT_11BITLOG:
+ TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
+ TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
+ break;
+ case PIXARLOGDATAFMT_12BITPICIO:
+ TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
+ TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
+ break;
+ case PIXARLOGDATAFMT_16BIT:
+ TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
+ TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
+ break;
+ case PIXARLOGDATAFMT_FLOAT:
+ TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 32);
+ TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT,
+ SAMPLEFORMAT_IEEEFP);
+ break;
+ }
+ /*
+ * Must recalculate sizes should bits/sample change.
+ */
+ tif->tif_tilesize =
+ isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1);
+ tif->tif_scanlinesize = TIFFScanlineSize(tif);
+ result = 1; /* NB: pseudo tag */
+ break;
+ default:
+ result = (*sp->vsetparent)(tif, tag, ap);
+ }
+ return (result);
+}
+
+static int PixarLogVGetField(TIFF *tif, uint32_t tag, va_list ap)
+{
+ PixarLogState *sp = (PixarLogState *)tif->tif_data;
+
+ switch (tag)
+ {
+ case TIFFTAG_PIXARLOGQUALITY:
+ *va_arg(ap, int *) = sp->quality;
+ break;
+ case TIFFTAG_PIXARLOGDATAFMT:
+ *va_arg(ap, int *) = sp->user_datafmt;
+ break;
+ default:
+ return (*sp->vgetparent)(tif, tag, ap);
+ }
+ return (1);
+}
+
+static const TIFFField pixarlogFields[] = {
+ {TIFFTAG_PIXARLOGDATAFMT, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
+ TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL},
+ {TIFFTAG_PIXARLOGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
+ TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}};
+
+int TIFFInitPixarLog(TIFF *tif, int scheme)
+{
+ static const char module[] = "TIFFInitPixarLog";
+
+ PixarLogState *sp;
+
+ (void)scheme;
+ assert(scheme == COMPRESSION_PIXARLOG);
+
+ /*
+ * Merge codec-specific tag information.
+ */
+ if (!_TIFFMergeFields(tif, pixarlogFields, TIFFArrayCount(pixarlogFields)))
+ {
+ TIFFErrorExtR(tif, module,
+ "Merging PixarLog codec-specific tags failed");
+ return 0;
+ }
+
+ /*
+ * Allocate state block so tag methods have storage to record values.
+ */
+ tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(PixarLogState));
+ if (tif->tif_data == NULL)
+ goto bad;
+ sp = (PixarLogState *)tif->tif_data;
+ _TIFFmemset(sp, 0, sizeof(*sp));
+ sp->stream.data_type = Z_BINARY;
+ sp->user_datafmt = PIXARLOGDATAFMT_UNKNOWN;
+
+ /*
+ * Install codec methods.
+ */
+ tif->tif_fixuptags = PixarLogFixupTags;
+ tif->tif_setupdecode = PixarLogSetupDecode;
+ tif->tif_predecode = PixarLogPreDecode;
+ tif->tif_decoderow = PixarLogDecode;
+ tif->tif_decodestrip = PixarLogDecode;
+ tif->tif_decodetile = PixarLogDecode;
+ tif->tif_setupencode = PixarLogSetupEncode;
+ tif->tif_preencode = PixarLogPreEncode;
+ tif->tif_postencode = PixarLogPostEncode;
+ tif->tif_encoderow = PixarLogEncode;
+ tif->tif_encodestrip = PixarLogEncode;
+ tif->tif_encodetile = PixarLogEncode;
+ tif->tif_close = PixarLogClose;
+ tif->tif_cleanup = PixarLogCleanup;
+
+ /* Override SetField so we can handle our private pseudo-tag */
+ sp->vgetparent = tif->tif_tagmethods.vgetfield;
+ tif->tif_tagmethods.vgetfield = PixarLogVGetField; /* hook for codec tags */
+ sp->vsetparent = tif->tif_tagmethods.vsetfield;
+ tif->tif_tagmethods.vsetfield = PixarLogVSetField; /* hook for codec tags */
+
+ /* Default values for codec-specific fields */
+ sp->quality = Z_DEFAULT_COMPRESSION; /* default comp. level */
+ sp->state = 0;
+
+ /* we don't wish to use the predictor,
+ * the default is none, which predictor value 1
+ */
+ (void)TIFFPredictorInit(tif);
+
+ /*
+ * build the companding tables
+ */
+ PixarLogMakeTables(tif, sp);
+
+ return (1);
+bad:
+ TIFFErrorExtR(tif, module, "No space for PixarLog state block");
+ return (0);
+}
+#endif /* PIXARLOG_SUPPORT */
diff --git a/contrib/libs/libtiff/tif_predict.c b/contrib/libs/libtiff/tif_predict.c
new file mode 100644
index 0000000000..386b5fe82a
--- /dev/null
+++ b/contrib/libs/libtiff/tif_predict.c
@@ -0,0 +1,1046 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Predictor Tag Support (used by multiple codecs).
+ */
+#include "tif_predict.h"
+#include "tiffiop.h"
+
+#define PredictorState(tif) ((TIFFPredictorState *)(tif)->tif_data)
+
+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);
+static int PredictorDecodeTile(TIFF *tif, uint8_t *op0, tmsize_t occ0,
+ uint16_t s);
+static int PredictorEncodeRow(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
+static int PredictorEncodeTile(TIFF *tif, uint8_t *bp0, tmsize_t cc0,
+ uint16_t s);
+
+static int PredictorSetup(TIFF *tif)
+{
+ static const char module[] = "PredictorSetup";
+
+ TIFFPredictorState *sp = PredictorState(tif);
+ TIFFDirectory *td = &tif->tif_dir;
+
+ switch (sp->predictor) /* no differencing */
+ {
+ case PREDICTOR_NONE:
+ return 1;
+ case PREDICTOR_HORIZONTAL:
+ if (td->td_bitspersample != 8 && td->td_bitspersample != 16 &&
+ td->td_bitspersample != 32 && td->td_bitspersample != 64)
+ {
+ TIFFErrorExtR(tif, module,
+ "Horizontal differencing \"Predictor\" not "
+ "supported with %" PRIu16 "-bit samples",
+ td->td_bitspersample);
+ return 0;
+ }
+ break;
+ case PREDICTOR_FLOATINGPOINT:
+ if (td->td_sampleformat != SAMPLEFORMAT_IEEEFP)
+ {
+ TIFFErrorExtR(
+ tif, module,
+ "Floating point \"Predictor\" not supported with %" PRIu16
+ " data format",
+ td->td_sampleformat);
+ return 0;
+ }
+ if (td->td_bitspersample != 16 && td->td_bitspersample != 24 &&
+ td->td_bitspersample != 32 && td->td_bitspersample != 64)
+ { /* Should 64 be allowed? */
+ TIFFErrorExtR(
+ tif, module,
+ "Floating point \"Predictor\" not supported with %" PRIu16
+ "-bit samples",
+ td->td_bitspersample);
+ return 0;
+ }
+ break;
+ default:
+ TIFFErrorExtR(tif, module, "\"Predictor\" value %d not supported",
+ sp->predictor);
+ return 0;
+ }
+ sp->stride =
+ (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel
+ : 1);
+ /*
+ * Calculate the scanline/tile-width size in bytes.
+ */
+ if (isTiled(tif))
+ sp->rowsize = TIFFTileRowSize(tif);
+ else
+ sp->rowsize = TIFFScanlineSize(tif);
+ if (sp->rowsize == 0)
+ return 0;
+
+ return 1;
+}
+
+static int PredictorSetupDecode(TIFF *tif)
+{
+ TIFFPredictorState *sp = PredictorState(tif);
+ TIFFDirectory *td = &tif->tif_dir;
+
+ /* Note: when PredictorSetup() fails, the effets of setupdecode() */
+ /* will not be "canceled" so setupdecode() might be robust to */
+ /* be called several times. */
+ if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
+ return 0;
+
+ if (sp->predictor == 2)
+ {
+ switch (td->td_bitspersample)
+ {
+ 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
+ * predictor stuff.
+ */
+ if (tif->tif_decoderow != PredictorDecodeRow)
+ {
+ sp->decoderow = tif->tif_decoderow;
+ tif->tif_decoderow = PredictorDecodeRow;
+ sp->decodestrip = tif->tif_decodestrip;
+ tif->tif_decodestrip = PredictorDecodeTile;
+ sp->decodetile = tif->tif_decodetile;
+ tif->tif_decodetile = PredictorDecodeTile;
+ }
+
+ /*
+ * If the data is horizontally differenced 16-bit data that
+ * requires byte-swapping, then it must be byte swapped before
+ * the accumulation step. We do this with a special-purpose
+ * routine and override the normal post decoding logic that
+ * the library setup when the directory was read.
+ */
+ if (tif->tif_flags & TIFF_SWAB)
+ {
+ if (sp->decodepfunc == horAcc16)
+ {
+ sp->decodepfunc = swabHorAcc16;
+ tif->tif_postdecode = _TIFFNoPostDecode;
+ }
+ else if (sp->decodepfunc == horAcc32)
+ {
+ sp->decodepfunc = swabHorAcc32;
+ tif->tif_postdecode = _TIFFNoPostDecode;
+ }
+ else if (sp->decodepfunc == horAcc64)
+ {
+ sp->decodepfunc = swabHorAcc64;
+ tif->tif_postdecode = _TIFFNoPostDecode;
+ }
+ }
+ }
+
+ else if (sp->predictor == 3)
+ {
+ sp->decodepfunc = fpAcc;
+ /*
+ * Override default decoding method with one that does the
+ * predictor stuff.
+ */
+ if (tif->tif_decoderow != PredictorDecodeRow)
+ {
+ sp->decoderow = tif->tif_decoderow;
+ tif->tif_decoderow = PredictorDecodeRow;
+ sp->decodestrip = tif->tif_decodestrip;
+ tif->tif_decodestrip = PredictorDecodeTile;
+ sp->decodetile = tif->tif_decodetile;
+ tif->tif_decodetile = PredictorDecodeTile;
+ }
+ /*
+ * The data should not be swapped outside of the floating
+ * point predictor, the accumulation routine should return
+ * byres in the native order.
+ */
+ if (tif->tif_flags & TIFF_SWAB)
+ {
+ tif->tif_postdecode = _TIFFNoPostDecode;
+ }
+ /*
+ * Allocate buffer to keep the decoded bytes before
+ * rearranging in the right order
+ */
+ }
+
+ return 1;
+}
+
+static int PredictorSetupEncode(TIFF *tif)
+{
+ TIFFPredictorState *sp = PredictorState(tif);
+ TIFFDirectory *td = &tif->tif_dir;
+
+ if (!(*sp->setupencode)(tif) || !PredictorSetup(tif))
+ return 0;
+
+ if (sp->predictor == 2)
+ {
+ switch (td->td_bitspersample)
+ {
+ 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
+ * predictor stuff.
+ */
+ if (tif->tif_encoderow != PredictorEncodeRow)
+ {
+ sp->encoderow = tif->tif_encoderow;
+ tif->tif_encoderow = PredictorEncodeRow;
+ sp->encodestrip = tif->tif_encodestrip;
+ tif->tif_encodestrip = PredictorEncodeTile;
+ sp->encodetile = tif->tif_encodetile;
+ tif->tif_encodetile = PredictorEncodeTile;
+ }
+
+ /*
+ * If the data is horizontally differenced 16-bit data that
+ * requires byte-swapping, then it must be byte swapped after
+ * the differentiation step. We do this with a special-purpose
+ * routine and override the normal post decoding logic that
+ * the library setup when the directory was read.
+ */
+ if (tif->tif_flags & TIFF_SWAB)
+ {
+ if (sp->encodepfunc == horDiff16)
+ {
+ sp->encodepfunc = swabHorDiff16;
+ tif->tif_postdecode = _TIFFNoPostDecode;
+ }
+ else if (sp->encodepfunc == horDiff32)
+ {
+ sp->encodepfunc = swabHorDiff32;
+ tif->tif_postdecode = _TIFFNoPostDecode;
+ }
+ else if (sp->encodepfunc == horDiff64)
+ {
+ sp->encodepfunc = swabHorDiff64;
+ tif->tif_postdecode = _TIFFNoPostDecode;
+ }
+ }
+ }
+
+ else if (sp->predictor == 3)
+ {
+ sp->encodepfunc = fpDiff;
+ /*
+ * Override default encoding method with one that does the
+ * predictor stuff.
+ */
+ if (tif->tif_encoderow != PredictorEncodeRow)
+ {
+ sp->encoderow = tif->tif_encoderow;
+ tif->tif_encoderow = PredictorEncodeRow;
+ sp->encodestrip = tif->tif_encodestrip;
+ tif->tif_encodestrip = PredictorEncodeTile;
+ sp->encodetile = tif->tif_encodetile;
+ tif->tif_encodetile = PredictorEncodeTile;
+ }
+ }
+
+ return 1;
+}
+
+#define REPEAT4(n, op) \
+ switch (n) \
+ { \
+ default: \
+ { \
+ tmsize_t i; \
+ for (i = n - 4; i > 0; i--) \
+ { \
+ op; \
+ } \
+ } /*-fallthrough*/ \
+ case 4: \
+ op; /*-fallthrough*/ \
+ case 3: \
+ op; /*-fallthrough*/ \
+ case 2: \
+ op; /*-fallthrough*/ \
+ case 1: \
+ op; /*-fallthrough*/ \
+ case 0:; \
+ }
+
+/* Remarks related to C standard compliance in all below functions : */
+/* - to avoid any undefined behavior, we only operate on unsigned types */
+/* since the behavior of "overflows" is defined (wrap over) */
+/* - when storing into the byte stream, we explicitly mask with 0xff so */
+/* as to make icc -check=conversions happy (not necessary by the standard) */
+
+TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
+static int horAcc8(TIFF *tif, uint8_t *cp0, tmsize_t cc)
+{
+ tmsize_t stride = PredictorState(tif)->stride;
+
+ unsigned char *cp = (unsigned char *)cp0;
+ if ((cc % stride) != 0)
+ {
+ TIFFErrorExtR(tif, "horAcc8", "%s", "(cc%stride)!=0");
+ return 0;
+ }
+
+ if (cc > stride)
+ {
+ /*
+ * Pipeline the most common cases.
+ */
+ if (stride == 3)
+ {
+ unsigned int cr = cp[0];
+ unsigned int cg = cp[1];
+ unsigned int cb = cp[2];
+ tmsize_t i = stride;
+ for (; i < cc; i += stride)
+ {
+ cp[i + 0] = (unsigned char)((cr += cp[i + 0]) & 0xff);
+ cp[i + 1] = (unsigned char)((cg += cp[i + 1]) & 0xff);
+ cp[i + 2] = (unsigned char)((cb += cp[i + 2]) & 0xff);
+ }
+ }
+ else if (stride == 4)
+ {
+ unsigned int cr = cp[0];
+ unsigned int cg = cp[1];
+ unsigned int cb = cp[2];
+ unsigned int ca = cp[3];
+ tmsize_t i = stride;
+ for (; i < cc; i += stride)
+ {
+ cp[i + 0] = (unsigned char)((cr += cp[i + 0]) & 0xff);
+ cp[i + 1] = (unsigned char)((cg += cp[i + 1]) & 0xff);
+ cp[i + 2] = (unsigned char)((cb += cp[i + 2]) & 0xff);
+ cp[i + 3] = (unsigned char)((ca += cp[i + 3]) & 0xff);
+ }
+ }
+ else
+ {
+ cc -= stride;
+ do
+ {
+ REPEAT4(stride,
+ cp[stride] = (unsigned char)((cp[stride] + *cp) & 0xff);
+ cp++)
+ cc -= stride;
+ } while (cc > 0);
+ }
+ }
+ return 1;
+}
+
+static int swabHorAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
+{
+ uint16_t *wp = (uint16_t *)cp0;
+ tmsize_t wc = cc / 2;
+
+ TIFFSwabArrayOfShort(wp, wc);
+ return horAcc16(tif, cp0, cc);
+}
+
+TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
+static int horAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
+{
+ tmsize_t stride = PredictorState(tif)->stride;
+ uint16_t *wp = (uint16_t *)cp0;
+ tmsize_t wc = cc / 2;
+
+ if ((cc % (2 * stride)) != 0)
+ {
+ TIFFErrorExtR(tif, "horAcc16", "%s", "cc%(2*stride))!=0");
+ return 0;
+ }
+
+ if (wc > stride)
+ {
+ wc -= stride;
+ do
+ {
+ REPEAT4(stride, wp[stride] = (uint16_t)(((unsigned int)wp[stride] +
+ (unsigned int)wp[0]) &
+ 0xffff);
+ wp++)
+ wc -= stride;
+ } while (wc > 0);
+ }
+ return 1;
+}
+
+static int swabHorAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
+{
+ uint32_t *wp = (uint32_t *)cp0;
+ tmsize_t wc = cc / 4;
+
+ TIFFSwabArrayOfLong(wp, wc);
+ return horAcc32(tif, cp0, cc);
+}
+
+TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
+static int horAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
+{
+ tmsize_t stride = PredictorState(tif)->stride;
+ uint32_t *wp = (uint32_t *)cp0;
+ tmsize_t wc = cc / 4;
+
+ if ((cc % (4 * stride)) != 0)
+ {
+ TIFFErrorExtR(tif, "horAcc32", "%s", "cc%(4*stride))!=0");
+ return 0;
+ }
+
+ if (wc > stride)
+ {
+ wc -= stride;
+ do
+ {
+ REPEAT4(stride, wp[stride] += wp[0]; wp++)
+ wc -= stride;
+ } while (wc > 0);
+ }
+ 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)
+ {
+ TIFFErrorExtR(tif, "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.
+ */
+static int fpAcc(TIFF *tif, uint8_t *cp0, tmsize_t cc)
+{
+ tmsize_t stride = PredictorState(tif)->stride;
+ uint32_t bps = tif->tif_dir.td_bitspersample / 8;
+ tmsize_t wc = cc / bps;
+ tmsize_t count = cc;
+ uint8_t *cp = (uint8_t *)cp0;
+ uint8_t *tmp;
+
+ if (cc % (bps * stride) != 0)
+ {
+ TIFFErrorExtR(tif, "fpAcc", "%s", "cc%(bps*stride))!=0");
+ return 0;
+ }
+
+ tmp = (uint8_t *)_TIFFmallocExt(tif, cc);
+ if (!tmp)
+ return 0;
+
+ while (count > stride)
+ {
+ REPEAT4(stride,
+ cp[stride] = (unsigned char)((cp[stride] + cp[0]) & 0xff);
+ cp++)
+ count -= stride;
+ }
+
+ _TIFFmemcpy(tmp, cp0, cc);
+ cp = (uint8_t *)cp0;
+ for (count = 0; count < wc; count++)
+ {
+ uint32_t byte;
+ for (byte = 0; byte < bps; byte++)
+ {
+#if WORDS_BIGENDIAN
+ cp[bps * count + byte] = tmp[byte * wc + count];
+#else
+ cp[bps * count + byte] = tmp[(bps - byte - 1) * wc + count];
+#endif
+ }
+ }
+ _TIFFfreeExt(tif, tmp);
+ return 1;
+}
+
+/*
+ * Decode a scanline and apply the predictor routine.
+ */
+static int PredictorDecodeRow(TIFF *tif, uint8_t *op0, tmsize_t occ0,
+ uint16_t s)
+{
+ TIFFPredictorState *sp = PredictorState(tif);
+
+ assert(sp != NULL);
+ assert(sp->decoderow != NULL);
+ assert(sp->decodepfunc != NULL);
+
+ if ((*sp->decoderow)(tif, op0, occ0, s))
+ {
+ return (*sp->decodepfunc)(tif, op0, occ0);
+ }
+ else
+ return 0;
+}
+
+/*
+ * Decode a tile/strip and apply the predictor routine.
+ * Note that horizontal differencing must be done on a
+ * row-by-row basis. The width of a "row" has already
+ * been calculated at pre-decode time according to the
+ * strip/tile dimensions.
+ */
+static int PredictorDecodeTile(TIFF *tif, uint8_t *op0, tmsize_t occ0,
+ uint16_t s)
+{
+ TIFFPredictorState *sp = PredictorState(tif);
+
+ assert(sp != NULL);
+ assert(sp->decodetile != NULL);
+
+ if ((*sp->decodetile)(tif, op0, occ0, s))
+ {
+ tmsize_t rowsize = sp->rowsize;
+ assert(rowsize > 0);
+ if ((occ0 % rowsize) != 0)
+ {
+ TIFFErrorExtR(tif, "PredictorDecodeTile", "%s",
+ "occ0%rowsize != 0");
+ return 0;
+ }
+ assert(sp->decodepfunc != NULL);
+ while (occ0 > 0)
+ {
+ if (!(*sp->decodepfunc)(tif, op0, rowsize))
+ return 0;
+ occ0 -= rowsize;
+ op0 += rowsize;
+ }
+ return 1;
+ }
+ else
+ return 0;
+}
+
+TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
+static int horDiff8(TIFF *tif, uint8_t *cp0, tmsize_t cc)
+{
+ TIFFPredictorState *sp = PredictorState(tif);
+ tmsize_t stride = sp->stride;
+ unsigned char *cp = (unsigned char *)cp0;
+
+ if ((cc % stride) != 0)
+ {
+ TIFFErrorExtR(tif, "horDiff8", "%s", "(cc%stride)!=0");
+ return 0;
+ }
+
+ if (cc > stride)
+ {
+ cc -= stride;
+ /*
+ * Pipeline the most common cases.
+ */
+ if (stride == 3)
+ {
+ unsigned int r1, g1, b1;
+ unsigned int r2 = cp[0];
+ unsigned int g2 = cp[1];
+ unsigned int b2 = cp[2];
+ do
+ {
+ r1 = cp[3];
+ cp[3] = (unsigned char)((r1 - r2) & 0xff);
+ r2 = r1;
+ g1 = cp[4];
+ cp[4] = (unsigned char)((g1 - g2) & 0xff);
+ g2 = g1;
+ b1 = cp[5];
+ cp[5] = (unsigned char)((b1 - b2) & 0xff);
+ b2 = b1;
+ cp += 3;
+ } while ((cc -= 3) > 0);
+ }
+ else if (stride == 4)
+ {
+ unsigned int r1, g1, b1, a1;
+ unsigned int r2 = cp[0];
+ unsigned int g2 = cp[1];
+ unsigned int b2 = cp[2];
+ unsigned int a2 = cp[3];
+ do
+ {
+ r1 = cp[4];
+ cp[4] = (unsigned char)((r1 - r2) & 0xff);
+ r2 = r1;
+ g1 = cp[5];
+ cp[5] = (unsigned char)((g1 - g2) & 0xff);
+ g2 = g1;
+ b1 = cp[6];
+ cp[6] = (unsigned char)((b1 - b2) & 0xff);
+ b2 = b1;
+ a1 = cp[7];
+ cp[7] = (unsigned char)((a1 - a2) & 0xff);
+ a2 = a1;
+ cp += 4;
+ } while ((cc -= 4) > 0);
+ }
+ else
+ {
+ cp += cc - 1;
+ do
+ {
+ REPEAT4(stride,
+ cp[stride] =
+ (unsigned char)((cp[stride] - cp[0]) & 0xff);
+ cp--)
+ } while ((cc -= stride) > 0);
+ }
+ }
+ return 1;
+}
+
+TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
+static int horDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
+{
+ TIFFPredictorState *sp = PredictorState(tif);
+ tmsize_t stride = sp->stride;
+ uint16_t *wp = (uint16_t *)cp0;
+ tmsize_t wc = cc / 2;
+
+ if ((cc % (2 * stride)) != 0)
+ {
+ TIFFErrorExtR(tif, "horDiff8", "%s", "(cc%(2*stride))!=0");
+ return 0;
+ }
+
+ if (wc > stride)
+ {
+ wc -= stride;
+ wp += wc - 1;
+ do
+ {
+ REPEAT4(stride, wp[stride] = (uint16_t)(((unsigned int)wp[stride] -
+ (unsigned int)wp[0]) &
+ 0xffff);
+ wp--)
+ wc -= stride;
+ } while (wc > 0);
+ }
+ return 1;
+}
+
+static int swabHorDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
+{
+ uint16_t *wp = (uint16_t *)cp0;
+ tmsize_t wc = cc / 2;
+
+ if (!horDiff16(tif, cp0, cc))
+ return 0;
+
+ TIFFSwabArrayOfShort(wp, wc);
+ return 1;
+}
+
+TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
+static int horDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
+{
+ TIFFPredictorState *sp = PredictorState(tif);
+ tmsize_t stride = sp->stride;
+ uint32_t *wp = (uint32_t *)cp0;
+ tmsize_t wc = cc / 4;
+
+ if ((cc % (4 * stride)) != 0)
+ {
+ TIFFErrorExtR(tif, "horDiff32", "%s", "(cc%(4*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 swabHorDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
+{
+ uint32_t *wp = (uint32_t *)cp0;
+ tmsize_t wc = cc / 4;
+
+ if (!horDiff32(tif, cp0, cc))
+ return 0;
+
+ TIFFSwabArrayOfLong(wp, wc);
+ 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)
+ {
+ TIFFErrorExtR(tif, "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.
+ */
+TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
+static int fpDiff(TIFF *tif, uint8_t *cp0, tmsize_t cc)
+{
+ tmsize_t stride = PredictorState(tif)->stride;
+ uint32_t bps = tif->tif_dir.td_bitspersample / 8;
+ tmsize_t wc = cc / bps;
+ tmsize_t count;
+ uint8_t *cp = (uint8_t *)cp0;
+ uint8_t *tmp;
+
+ if ((cc % (bps * stride)) != 0)
+ {
+ TIFFErrorExtR(tif, "fpDiff", "%s", "(cc%(bps*stride))!=0");
+ return 0;
+ }
+
+ tmp = (uint8_t *)_TIFFmallocExt(tif, cc);
+ if (!tmp)
+ return 0;
+
+ _TIFFmemcpy(tmp, cp0, cc);
+ for (count = 0; count < wc; count++)
+ {
+ uint32_t byte;
+ for (byte = 0; byte < bps; byte++)
+ {
+#if WORDS_BIGENDIAN
+ cp[byte * wc + count] = tmp[bps * count + byte];
+#else
+ cp[(bps - byte - 1) * wc + count] = tmp[bps * count + byte];
+#endif
+ }
+ }
+ _TIFFfreeExt(tif, tmp);
+
+ cp = (uint8_t *)cp0;
+ cp += cc - stride - 1;
+ for (count = cc; count > stride; count -= stride)
+ REPEAT4(stride,
+ cp[stride] = (unsigned char)((cp[stride] - cp[0]) & 0xff);
+ cp--)
+ return 1;
+}
+
+static int PredictorEncodeRow(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
+{
+ TIFFPredictorState *sp = PredictorState(tif);
+
+ assert(sp != NULL);
+ assert(sp->encodepfunc != NULL);
+ assert(sp->encoderow != NULL);
+
+ /* XXX horizontal differencing alters user's data XXX */
+ if (!(*sp->encodepfunc)(tif, bp, cc))
+ return 0;
+ return (*sp->encoderow)(tif, bp, cc, s);
+}
+
+static int PredictorEncodeTile(TIFF *tif, uint8_t *bp0, tmsize_t cc0,
+ uint16_t s)
+{
+ static const char module[] = "PredictorEncodeTile";
+ TIFFPredictorState *sp = PredictorState(tif);
+ uint8_t *working_copy;
+ tmsize_t cc = cc0, rowsize;
+ unsigned char *bp;
+ int result_code;
+
+ assert(sp != NULL);
+ assert(sp->encodepfunc != NULL);
+ assert(sp->encodetile != NULL);
+
+ /*
+ * Do predictor manipulation in a working buffer to avoid altering
+ * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965
+ */
+ working_copy = (uint8_t *)_TIFFmallocExt(tif, cc0);
+ if (working_copy == NULL)
+ {
+ TIFFErrorExtR(tif, module,
+ "Out of memory allocating %" PRId64 " byte temp buffer.",
+ (int64_t)cc0);
+ return 0;
+ }
+ memcpy(working_copy, bp0, cc0);
+ bp = working_copy;
+
+ rowsize = sp->rowsize;
+ assert(rowsize > 0);
+ if ((cc0 % rowsize) != 0)
+ {
+ TIFFErrorExtR(tif, "PredictorEncodeTile", "%s", "(cc0%rowsize)!=0");
+ _TIFFfreeExt(tif, working_copy);
+ return 0;
+ }
+ while (cc > 0)
+ {
+ (*sp->encodepfunc)(tif, bp, rowsize);
+ cc -= rowsize;
+ bp += rowsize;
+ }
+ result_code = (*sp->encodetile)(tif, working_copy, cc0, s);
+
+ _TIFFfreeExt(tif, working_copy);
+
+ return result_code;
+}
+
+#define FIELD_PREDICTOR (FIELD_CODEC + 0) /* XXX */
+
+static const TIFFField predictFields[] = {
+ {TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16,
+ TIFF_SETGET_UINT16, FIELD_PREDICTOR, FALSE, FALSE, "Predictor", NULL},
+};
+
+static int PredictorVSetField(TIFF *tif, uint32_t tag, va_list ap)
+{
+ TIFFPredictorState *sp = PredictorState(tif);
+
+ assert(sp != NULL);
+ assert(sp->vsetparent != NULL);
+
+ switch (tag)
+ {
+ case TIFFTAG_PREDICTOR:
+ sp->predictor = (uint16_t)va_arg(ap, uint16_vap);
+ TIFFSetFieldBit(tif, FIELD_PREDICTOR);
+ break;
+ default:
+ return (*sp->vsetparent)(tif, tag, ap);
+ }
+ tif->tif_flags |= TIFF_DIRTYDIRECT;
+ return 1;
+}
+
+static int PredictorVGetField(TIFF *tif, uint32_t tag, va_list ap)
+{
+ TIFFPredictorState *sp = PredictorState(tif);
+
+ assert(sp != NULL);
+ assert(sp->vgetparent != NULL);
+
+ switch (tag)
+ {
+ case TIFFTAG_PREDICTOR:
+ *va_arg(ap, uint16_t *) = (uint16_t)sp->predictor;
+ break;
+ default:
+ return (*sp->vgetparent)(tif, tag, ap);
+ }
+ return 1;
+}
+
+static void PredictorPrintDir(TIFF *tif, FILE *fd, long flags)
+{
+ TIFFPredictorState *sp = PredictorState(tif);
+
+ (void)flags;
+ if (TIFFFieldSet(tif, FIELD_PREDICTOR))
+ {
+ fprintf(fd, " Predictor: ");
+ switch (sp->predictor)
+ {
+ case 1:
+ fprintf(fd, "none ");
+ break;
+ case 2:
+ fprintf(fd, "horizontal differencing ");
+ break;
+ case 3:
+ fprintf(fd, "floating point predictor ");
+ break;
+ }
+ fprintf(fd, "%d (0x%x)\n", sp->predictor, sp->predictor);
+ }
+ if (sp->printdir)
+ (*sp->printdir)(tif, fd, flags);
+}
+
+int TIFFPredictorInit(TIFF *tif)
+{
+ TIFFPredictorState *sp = PredictorState(tif);
+
+ assert(sp != 0);
+
+ /*
+ * Merge codec-specific tag information.
+ */
+ if (!_TIFFMergeFields(tif, predictFields, TIFFArrayCount(predictFields)))
+ {
+ TIFFErrorExtR(tif, "TIFFPredictorInit",
+ "Merging Predictor codec-specific tags failed");
+ return 0;
+ }
+
+ /*
+ * Override parent get/set field methods.
+ */
+ sp->vgetparent = tif->tif_tagmethods.vgetfield;
+ tif->tif_tagmethods.vgetfield =
+ PredictorVGetField; /* hook for predictor tag */
+ sp->vsetparent = tif->tif_tagmethods.vsetfield;
+ tif->tif_tagmethods.vsetfield =
+ PredictorVSetField; /* hook for predictor tag */
+ sp->printdir = tif->tif_tagmethods.printdir;
+ tif->tif_tagmethods.printdir =
+ PredictorPrintDir; /* hook for predictor tag */
+
+ sp->setupdecode = tif->tif_setupdecode;
+ tif->tif_setupdecode = PredictorSetupDecode;
+ sp->setupencode = tif->tif_setupencode;
+ tif->tif_setupencode = PredictorSetupEncode;
+
+ sp->predictor = 1; /* default value */
+ sp->encodepfunc = NULL; /* no predictor routine */
+ sp->decodepfunc = NULL; /* no predictor routine */
+ return 1;
+}
+
+int TIFFPredictorCleanup(TIFF *tif)
+{
+ TIFFPredictorState *sp = PredictorState(tif);
+
+ assert(sp != 0);
+
+ tif->tif_tagmethods.vgetfield = sp->vgetparent;
+ tif->tif_tagmethods.vsetfield = sp->vsetparent;
+ tif->tif_tagmethods.printdir = sp->printdir;
+ tif->tif_setupdecode = sp->setupdecode;
+ tif->tif_setupencode = sp->setupencode;
+
+ return 1;
+}
diff --git a/contrib/libs/libtiff/tif_predict.h b/contrib/libs/libtiff/tif_predict.h
new file mode 100644
index 0000000000..de77328352
--- /dev/null
+++ b/contrib/libs/libtiff/tif_predict.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1995-1997 Sam Leffler
+ * Copyright (c) 1995-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _TIFFPREDICT_
+#define _TIFFPREDICT_
+
+#include "tiffio.h"
+#include "tiffiop.h"
+
+/*
+ * ``Library-private'' Support for the Predictor Tag
+ */
+
+typedef int (*TIFFEncodeDecodeMethod)(TIFF *tif, uint8_t *buf, tmsize_t size);
+
+/*
+ * Codecs that want to support the Predictor tag must place
+ * this structure first in their private state block so that
+ * the predictor code can cast tif_data to find its state.
+ */
+typedef struct
+{
+ int predictor; /* predictor tag value */
+ tmsize_t stride; /* sample stride over data */
+ tmsize_t rowsize; /* tile/strip row size */
+
+ TIFFCodeMethod encoderow; /* parent codec encode/decode row */
+ TIFFCodeMethod encodestrip; /* parent codec encode/decode strip */
+ TIFFCodeMethod encodetile; /* parent codec encode/decode tile */
+ TIFFEncodeDecodeMethod encodepfunc; /* horizontal differencer */
+
+ TIFFCodeMethod decoderow; /* parent codec encode/decode row */
+ TIFFCodeMethod decodestrip; /* parent codec encode/decode strip */
+ TIFFCodeMethod decodetile; /* parent codec encode/decode tile */
+ TIFFEncodeDecodeMethod decodepfunc; /* horizontal accumulator */
+
+ TIFFVGetMethod vgetparent; /* super-class method */
+ TIFFVSetMethod vsetparent; /* super-class method */
+ TIFFPrintMethod printdir; /* super-class method */
+ TIFFBoolMethod setupdecode; /* super-class method */
+ TIFFBoolMethod setupencode; /* super-class method */
+} TIFFPredictorState;
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+ extern int TIFFPredictorInit(TIFF *);
+ extern int TIFFPredictorCleanup(TIFF *);
+#if defined(__cplusplus)
+}
+#endif
+#endif /* _TIFFPREDICT_ */
diff --git a/contrib/libs/libtiff/tif_print.c b/contrib/libs/libtiff/tif_print.c
new file mode 100644
index 0000000000..2b7fd1765a
--- /dev/null
+++ b/contrib/libs/libtiff/tif_print.c
@@ -0,0 +1,755 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Directory Printing Support
+ */
+#include "tiffiop.h"
+#include <stdio.h>
+
+#include <ctype.h>
+
+static void _TIFFprintAsciiBounded(FILE *fd, const char *cp, size_t max_chars);
+
+static const char *const photoNames[] = {
+ "min-is-white", /* PHOTOMETRIC_MINISWHITE */
+ "min-is-black", /* PHOTOMETRIC_MINISBLACK */
+ "RGB color", /* PHOTOMETRIC_RGB */
+ "palette color (RGB from colormap)", /* PHOTOMETRIC_PALETTE */
+ "transparency mask", /* PHOTOMETRIC_MASK */
+ "separated", /* PHOTOMETRIC_SEPARATED */
+ "YCbCr", /* PHOTOMETRIC_YCBCR */
+ "7 (0x7)",
+ "CIE L*a*b*", /* PHOTOMETRIC_CIELAB */
+ "ICC L*a*b*", /* PHOTOMETRIC_ICCLAB */
+ "ITU L*a*b*" /* PHOTOMETRIC_ITULAB */
+};
+#define NPHOTONAMES (sizeof(photoNames) / sizeof(photoNames[0]))
+
+static const char *const orientNames[] = {
+ "0 (0x0)",
+ "row 0 top, col 0 lhs", /* ORIENTATION_TOPLEFT */
+ "row 0 top, col 0 rhs", /* ORIENTATION_TOPRIGHT */
+ "row 0 bottom, col 0 rhs", /* ORIENTATION_BOTRIGHT */
+ "row 0 bottom, col 0 lhs", /* ORIENTATION_BOTLEFT */
+ "row 0 lhs, col 0 top", /* ORIENTATION_LEFTTOP */
+ "row 0 rhs, col 0 top", /* ORIENTATION_RIGHTTOP */
+ "row 0 rhs, col 0 bottom", /* ORIENTATION_RIGHTBOT */
+ "row 0 lhs, col 0 bottom", /* ORIENTATION_LEFTBOT */
+};
+#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;
+
+ /* 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)
+ fprintf(fd, "%" PRIu8, ((uint8_t *)raw_data)[j]);
+ else if (fip->field_type == TIFF_UNDEFINED)
+ fprintf(fd, "0x%" PRIx8, ((uint8_t *)raw_data)[j]);
+ else if (fip->field_type == TIFF_SBYTE)
+ fprintf(fd, "%" PRId8, ((int8_t *)raw_data)[j]);
+ else if (fip->field_type == TIFF_SHORT)
+ fprintf(fd, "%" PRIu16, ((uint16_t *)raw_data)[j]);
+ else if (fip->field_type == TIFF_SSHORT)
+ fprintf(fd, "%" PRId16, ((int16_t *)raw_data)[j]);
+ else if (fip->field_type == TIFF_LONG)
+ fprintf(fd, "%" PRIu32, ((uint32_t *)raw_data)[j]);
+ else if (fip->field_type == TIFF_SLONG)
+ 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)
+ {
+ 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_DOUBLE)
+ fprintf(fd, "%lf", ((double *)raw_data)[j]);
+ else if (fip->field_type == TIFF_ASCII)
+ {
+ fprintf(fd, "%s", (char *)raw_data);
+ break;
+ }
+ else
+ {
+ fprintf(fd, "<unsupported data type in TIFFPrint>");
+ break;
+ }
+
+ if (j < value_count - 1)
+ fprintf(fd, ",");
+ }
+
+ fprintf(fd, "\n");
+}
+
+static int _TIFFPrettyPrintField(TIFF *tif, const TIFFField *fip, FILE *fd,
+ uint32_t tag, uint32_t value_count,
+ void *raw_data)
+{
+ (void)tif;
+
+ /* do not try to pretty print auto-defined fields */
+ if (TIFFFieldIsAnonymous(fip))
+ {
+ return 0;
+ }
+
+ switch (tag)
+ {
+ case TIFFTAG_INKSET:
+ if (value_count == 2 && fip->field_type == TIFF_SHORT)
+ {
+ fprintf(fd, " Ink Set: ");
+ switch (*((uint16_t *)raw_data))
+ {
+ case INKSET_CMYK:
+ fprintf(fd, "CMYK\n");
+ break;
+ default:
+ fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n",
+ *((uint16_t *)raw_data),
+ *((uint16_t *)raw_data));
+ break;
+ }
+ return 1;
+ }
+ return 0;
+
+ case TIFFTAG_DOTRANGE:
+ if (value_count == 2 && fip->field_type == TIFF_SHORT)
+ {
+ fprintf(fd, " Dot Range: %" PRIu16 "-%" PRIu16 "\n",
+ ((uint16_t *)raw_data)[0], ((uint16_t *)raw_data)[1]);
+ return 1;
+ }
+ return 0;
+
+ case TIFFTAG_WHITEPOINT:
+ if (value_count == 2 && fip->field_type == TIFF_RATIONAL)
+ {
+ fprintf(fd, " White Point: %g-%g\n", ((float *)raw_data)[0],
+ ((float *)raw_data)[1]);
+ return 1;
+ }
+ return 0;
+
+ case TIFFTAG_XMLPACKET:
+ {
+ uint32_t i;
+
+ fprintf(fd, " XMLPacket (XMP Metadata):\n");
+ for (i = 0; i < value_count; i++)
+ fputc(((char *)raw_data)[i], fd);
+ fprintf(fd, "\n");
+ return 1;
+ }
+ case TIFFTAG_RICHTIFFIPTC:
+ fprintf(fd, " RichTIFFIPTC Data: <present>, %" PRIu32 " bytes\n",
+ value_count);
+ return 1;
+
+ case TIFFTAG_PHOTOSHOP:
+ fprintf(fd, " Photoshop Data: <present>, %" PRIu32 " bytes\n",
+ value_count);
+ return 1;
+
+ case TIFFTAG_ICCPROFILE:
+ fprintf(fd, " ICC Profile: <present>, %" PRIu32 " bytes\n",
+ value_count);
+ return 1;
+
+ case TIFFTAG_STONITS:
+ if (value_count == 1 && fip->field_type == TIFF_DOUBLE)
+ {
+ fprintf(fd, " Sample to Nits conversion factor: %.4e\n",
+ *((double *)raw_data));
+ return 1;
+ }
+ return 0;
+ }
+
+ return 0;
+}
+
+/*
+ * Print the contents of the current directory
+ * to the specified stdio file stream.
+ */
+void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ char *sep;
+ long l, n;
+
+ fprintf(fd, "TIFF Directory at offset 0x%" PRIx64 " (%" PRIu64 ")\n",
+ tif->tif_diroff, tif->tif_diroff);
+ if (TIFFFieldSet(tif, FIELD_SUBFILETYPE))
+ {
+ fprintf(fd, " Subfile Type:");
+ sep = " ";
+ if (td->td_subfiletype & FILETYPE_REDUCEDIMAGE)
+ {
+ fprintf(fd, "%sreduced-resolution image", sep);
+ sep = "/";
+ }
+ if (td->td_subfiletype & FILETYPE_PAGE)
+ {
+ fprintf(fd, "%smulti-page document", sep);
+ sep = "/";
+ }
+ if (td->td_subfiletype & FILETYPE_MASK)
+ fprintf(fd, "%stransparency mask", sep);
+ fprintf(fd, " (%" PRIu32 " = 0x%" PRIx32 ")\n", td->td_subfiletype,
+ td->td_subfiletype);
+ }
+ if (TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS))
+ {
+ fprintf(fd, " Image Width: %" PRIu32 " Image Length: %" PRIu32,
+ td->td_imagewidth, td->td_imagelength);
+ if (TIFFFieldSet(tif, FIELD_IMAGEDEPTH))
+ fprintf(fd, " Image Depth: %" PRIu32, td->td_imagedepth);
+ fprintf(fd, "\n");
+ }
+ if (TIFFFieldSet(tif, FIELD_TILEDIMENSIONS))
+ {
+ fprintf(fd, " Tile Width: %" PRIu32 " Tile Length: %" PRIu32,
+ td->td_tilewidth, td->td_tilelength);
+ if (TIFFFieldSet(tif, FIELD_TILEDEPTH))
+ fprintf(fd, " Tile Depth: %" PRIu32, td->td_tiledepth);
+ fprintf(fd, "\n");
+ }
+ if (TIFFFieldSet(tif, FIELD_RESOLUTION))
+ {
+ fprintf(fd, " Resolution: %g, %g", td->td_xresolution,
+ td->td_yresolution);
+ if (TIFFFieldSet(tif, FIELD_RESOLUTIONUNIT))
+ {
+ switch (td->td_resolutionunit)
+ {
+ case RESUNIT_NONE:
+ fprintf(fd, " (unitless)");
+ break;
+ case RESUNIT_INCH:
+ fprintf(fd, " pixels/inch");
+ break;
+ case RESUNIT_CENTIMETER:
+ fprintf(fd, " pixels/cm");
+ break;
+ default:
+ fprintf(fd, " (unit %" PRIu16 " = 0x%" PRIx16 ")",
+ td->td_resolutionunit, td->td_resolutionunit);
+ break;
+ }
+ }
+ fprintf(fd, "\n");
+ }
+ if (TIFFFieldSet(tif, FIELD_POSITION))
+ fprintf(fd, " Position: %g, %g\n", td->td_xposition, td->td_yposition);
+ if (TIFFFieldSet(tif, FIELD_BITSPERSAMPLE))
+ fprintf(fd, " Bits/Sample: %" PRIu16 "\n", td->td_bitspersample);
+ if (TIFFFieldSet(tif, FIELD_SAMPLEFORMAT))
+ {
+ fprintf(fd, " Sample Format: ");
+ switch (td->td_sampleformat)
+ {
+ case SAMPLEFORMAT_VOID:
+ fprintf(fd, "void\n");
+ break;
+ case SAMPLEFORMAT_INT:
+ fprintf(fd, "signed integer\n");
+ break;
+ case SAMPLEFORMAT_UINT:
+ fprintf(fd, "unsigned integer\n");
+ break;
+ case SAMPLEFORMAT_IEEEFP:
+ fprintf(fd, "IEEE floating point\n");
+ break;
+ case SAMPLEFORMAT_COMPLEXINT:
+ fprintf(fd, "complex signed integer\n");
+ break;
+ case SAMPLEFORMAT_COMPLEXIEEEFP:
+ fprintf(fd, "complex IEEE floating point\n");
+ break;
+ default:
+ fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n",
+ td->td_sampleformat, td->td_sampleformat);
+ break;
+ }
+ }
+ if (TIFFFieldSet(tif, FIELD_COMPRESSION))
+ {
+ const TIFFCodec *c = TIFFFindCODEC(td->td_compression);
+ fprintf(fd, " Compression Scheme: ");
+ if (c)
+ fprintf(fd, "%s\n", c->name);
+ else
+ fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", td->td_compression,
+ td->td_compression);
+ }
+ if (TIFFFieldSet(tif, FIELD_PHOTOMETRIC))
+ {
+ fprintf(fd, " Photometric Interpretation: ");
+ if (td->td_photometric < NPHOTONAMES)
+ fprintf(fd, "%s\n", photoNames[td->td_photometric]);
+ else
+ {
+ switch (td->td_photometric)
+ {
+ case PHOTOMETRIC_LOGL:
+ fprintf(fd, "CIE Log2(L)\n");
+ break;
+ case PHOTOMETRIC_LOGLUV:
+ fprintf(fd, "CIE Log2(L) (u',v')\n");
+ break;
+ default:
+ fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n",
+ td->td_photometric, td->td_photometric);
+ break;
+ }
+ }
+ }
+ if (TIFFFieldSet(tif, FIELD_EXTRASAMPLES) && td->td_extrasamples)
+ {
+ uint16_t i;
+ fprintf(fd, " Extra Samples: %" PRIu16 "<", td->td_extrasamples);
+ sep = "";
+ for (i = 0; i < td->td_extrasamples; i++)
+ {
+ switch (td->td_sampleinfo[i])
+ {
+ case EXTRASAMPLE_UNSPECIFIED:
+ fprintf(fd, "%sunspecified", sep);
+ break;
+ case EXTRASAMPLE_ASSOCALPHA:
+ fprintf(fd, "%sassoc-alpha", sep);
+ break;
+ case EXTRASAMPLE_UNASSALPHA:
+ fprintf(fd, "%sunassoc-alpha", sep);
+ break;
+ default:
+ fprintf(fd, "%s%" PRIu16 " (0x%" PRIx16 ")", sep,
+ td->td_sampleinfo[i], td->td_sampleinfo[i]);
+ break;
+ }
+ sep = ", ";
+ }
+ fprintf(fd, ">\n");
+ }
+ if (TIFFFieldSet(tif, FIELD_INKNAMES))
+ {
+ char *cp;
+ uint16_t i;
+ fprintf(fd, " Ink Names: ");
+ i = td->td_samplesperpixel;
+ sep = "";
+ for (cp = td->td_inknames;
+ i > 0 && cp < td->td_inknames + td->td_inknameslen;
+ cp = strchr(cp, '\0') + 1, i--)
+ {
+ size_t max_chars = td->td_inknameslen - (cp - td->td_inknames);
+ fputs(sep, fd);
+ _TIFFprintAsciiBounded(fd, cp, max_chars);
+ sep = ", ";
+ }
+ fputs("\n", fd);
+ }
+ if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS))
+ {
+ fprintf(fd, " NumberOfInks: %d\n", td->td_numberofinks);
+ }
+ if (TIFFFieldSet(tif, FIELD_THRESHHOLDING))
+ {
+ fprintf(fd, " Thresholding: ");
+ switch (td->td_threshholding)
+ {
+ case THRESHHOLD_BILEVEL:
+ fprintf(fd, "bilevel art scan\n");
+ break;
+ case THRESHHOLD_HALFTONE:
+ fprintf(fd, "halftone or dithered scan\n");
+ break;
+ case THRESHHOLD_ERRORDIFFUSE:
+ fprintf(fd, "error diffused\n");
+ break;
+ default:
+ fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n",
+ td->td_threshholding, td->td_threshholding);
+ break;
+ }
+ }
+ if (TIFFFieldSet(tif, FIELD_FILLORDER))
+ {
+ fprintf(fd, " FillOrder: ");
+ switch (td->td_fillorder)
+ {
+ case FILLORDER_MSB2LSB:
+ fprintf(fd, "msb-to-lsb\n");
+ break;
+ case FILLORDER_LSB2MSB:
+ fprintf(fd, "lsb-to-msb\n");
+ break;
+ default:
+ fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", td->td_fillorder,
+ td->td_fillorder);
+ break;
+ }
+ }
+ if (TIFFFieldSet(tif, FIELD_YCBCRSUBSAMPLING))
+ {
+ fprintf(fd, " YCbCr Subsampling: %" PRIu16 ", %" PRIu16 "\n",
+ td->td_ycbcrsubsampling[0], td->td_ycbcrsubsampling[1]);
+ }
+ if (TIFFFieldSet(tif, FIELD_YCBCRPOSITIONING))
+ {
+ fprintf(fd, " YCbCr Positioning: ");
+ switch (td->td_ycbcrpositioning)
+ {
+ case YCBCRPOSITION_CENTERED:
+ fprintf(fd, "centered\n");
+ break;
+ case YCBCRPOSITION_COSITED:
+ fprintf(fd, "cosited\n");
+ break;
+ default:
+ fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n",
+ td->td_ycbcrpositioning, td->td_ycbcrpositioning);
+ break;
+ }
+ }
+ if (TIFFFieldSet(tif, FIELD_HALFTONEHINTS))
+ fprintf(fd, " Halftone Hints: light %" PRIu16 " dark %" PRIu16 "\n",
+ td->td_halftonehints[0], td->td_halftonehints[1]);
+ if (TIFFFieldSet(tif, FIELD_ORIENTATION))
+ {
+ fprintf(fd, " Orientation: ");
+ if (td->td_orientation < NORIENTNAMES)
+ fprintf(fd, "%s\n", orientNames[td->td_orientation]);
+ else
+ fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", td->td_orientation,
+ td->td_orientation);
+ }
+ if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
+ fprintf(fd, " Samples/Pixel: %" PRIx16 "\n", td->td_samplesperpixel);
+ if (TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
+ {
+ fprintf(fd, " Rows/Strip: ");
+ if (td->td_rowsperstrip == (uint32_t)-1)
+ fprintf(fd, "(infinite)\n");
+ else
+ fprintf(fd, "%" PRIu32 "\n", td->td_rowsperstrip);
+ }
+ if (TIFFFieldSet(tif, FIELD_MINSAMPLEVALUE))
+ fprintf(fd, " Min Sample Value: %" PRIu16 "\n", td->td_minsamplevalue);
+ if (TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE))
+ fprintf(fd, " Max Sample Value: %" PRIu16 "\n", td->td_maxsamplevalue);
+ if (TIFFFieldSet(tif, FIELD_SMINSAMPLEVALUE))
+ {
+ int i;
+ int count =
+ (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1;
+ fprintf(fd, " SMin Sample Value:");
+ for (i = 0; i < count; ++i)
+ fprintf(fd, " %g", td->td_sminsamplevalue[i]);
+ fprintf(fd, "\n");
+ }
+ if (TIFFFieldSet(tif, FIELD_SMAXSAMPLEVALUE))
+ {
+ int i;
+ int count =
+ (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1;
+ fprintf(fd, " SMax Sample Value:");
+ for (i = 0; i < count; ++i)
+ fprintf(fd, " %g", td->td_smaxsamplevalue[i]);
+ fprintf(fd, "\n");
+ }
+ if (TIFFFieldSet(tif, FIELD_PLANARCONFIG))
+ {
+ fprintf(fd, " Planar Configuration: ");
+ switch (td->td_planarconfig)
+ {
+ case PLANARCONFIG_CONTIG:
+ fprintf(fd, "single image plane\n");
+ break;
+ case PLANARCONFIG_SEPARATE:
+ fprintf(fd, "separate image planes\n");
+ break;
+ default:
+ fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n",
+ td->td_planarconfig, td->td_planarconfig);
+ break;
+ }
+ }
+ if (TIFFFieldSet(tif, FIELD_PAGENUMBER))
+ fprintf(fd, " Page Number: %" PRIu16 "-%" PRIu16 "\n",
+ td->td_pagenumber[0], td->td_pagenumber[1]);
+ if (TIFFFieldSet(tif, FIELD_COLORMAP))
+ {
+ fprintf(fd, " Color Map: ");
+ if (flags & TIFFPRINT_COLORMAP)
+ {
+ fprintf(fd, "\n");
+ n = 1L << td->td_bitspersample;
+ for (l = 0; l < n; l++)
+ fprintf(fd, " %5ld: %5" PRIu16 " %5" PRIu16 " %5" PRIu16 "\n",
+ l, td->td_colormap[0][l], td->td_colormap[1][l],
+ td->td_colormap[2][l]);
+ }
+ else
+ fprintf(fd, "(present)\n");
+ }
+ if (TIFFFieldSet(tif, FIELD_REFBLACKWHITE))
+ {
+ int i;
+ fprintf(fd, " Reference Black/White:\n");
+ for (i = 0; i < 3; i++)
+ fprintf(fd, " %2d: %5g %5g\n", i,
+ td->td_refblackwhite[2 * i + 0],
+ td->td_refblackwhite[2 * i + 1]);
+ }
+ if (TIFFFieldSet(tif, FIELD_TRANSFERFUNCTION))
+ {
+ fprintf(fd, " Transfer Function: ");
+ if (flags & TIFFPRINT_CURVES)
+ {
+ fprintf(fd, "\n");
+ n = 1L << td->td_bitspersample;
+ for (l = 0; l < n; l++)
+ {
+ uint16_t i;
+ fprintf(fd, " %2ld: %5" PRIu16, l,
+ td->td_transferfunction[0][l]);
+ for (i = 1;
+ i < td->td_samplesperpixel - td->td_extrasamples && i < 3;
+ i++)
+ fprintf(fd, " %5" PRIu16, td->td_transferfunction[i][l]);
+ fputc('\n', fd);
+ }
+ }
+ else
+ fprintf(fd, "(present)\n");
+ }
+ if (TIFFFieldSet(tif, FIELD_SUBIFD) && (td->td_subifd))
+ {
+ uint16_t i;
+ fprintf(fd, " SubIFD Offsets:");
+ for (i = 0; i < td->td_nsubifd; i++)
+ fprintf(fd, " %5" PRIu64, td->td_subifd[i]);
+ fputc('\n', fd);
+ }
+
+ /*
+ ** Custom tag support.
+ */
+ {
+ int i;
+ short count;
+
+ count = (short)TIFFGetTagListCount(tif);
+ for (i = 0; i < count; i++)
+ {
+ uint32_t tag = TIFFGetTagListEntry(tif, i);
+ const TIFFField *fip;
+ uint32_t value_count;
+ int mem_alloc = 0;
+ 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)
+ continue;
+
+ if (fip->field_passcount)
+ {
+ if (fip->field_readcount == TIFF_VARIABLE2)
+ {
+ if (TIFFGetField(tif, tag, &value_count, &raw_data) != 1)
+ continue;
+ }
+ else if (fip->field_readcount == TIFF_VARIABLE)
+ {
+ uint16_t small_value_count;
+ if (TIFFGetField(tif, tag, &small_value_count, &raw_data) !=
+ 1)
+ continue;
+ value_count = small_value_count;
+ }
+ else
+ {
+ assert(fip->field_readcount == TIFF_VARIABLE ||
+ fip->field_readcount == TIFF_VARIABLE2);
+ continue;
+ }
+ }
+ else
+ {
+ if (fip->field_readcount == TIFF_VARIABLE ||
+ fip->field_readcount == TIFF_VARIABLE2)
+ value_count = 1;
+ else if (fip->field_readcount == TIFF_SPP)
+ value_count = td->td_samplesperpixel;
+ else
+ value_count = fip->field_readcount;
+ if (fip->field_tag == TIFFTAG_DOTRANGE &&
+ strcmp(fip->field_name, "DotRange") == 0)
+ {
+ /* TODO: This is an evil exception and should not have been
+ 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 */
+ raw_data = dotrange;
+ TIFFGetField(tif, tag, dotrange + 0, dotrange + 1);
+ }
+ else if (fip->field_type == TIFF_ASCII ||
+ fip->field_readcount == TIFF_VARIABLE ||
+ fip->field_readcount == TIFF_VARIABLE2 ||
+ fip->field_readcount == TIFF_SPP || value_count > 1)
+ {
+ 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 = _TIFFmallocExt(tif, tv_size * value_count);
+ mem_alloc = 1;
+ if (TIFFGetField(tif, tag, raw_data) != 1)
+ {
+ _TIFFfreeExt(tif, raw_data);
+ continue;
+ }
+ }
+ }
+
+ /*
+ * Catch the tags which needs to be specially handled
+ * and pretty print them. If tag not handled in
+ * _TIFFPrettyPrintField() fall down and print it as
+ * any other tag.
+ */
+ if (raw_data != NULL &&
+ !_TIFFPrettyPrintField(tif, fip, fd, tag, value_count,
+ raw_data))
+ _TIFFPrintField(fd, fip, value_count, raw_data);
+
+ if (mem_alloc)
+ _TIFFfreeExt(tif, raw_data);
+ }
+ }
+
+ if (tif->tif_tagmethods.printdir)
+ (*tif->tif_tagmethods.printdir)(tif, fd, flags);
+
+ if ((flags & TIFFPRINT_STRIPS) && TIFFFieldSet(tif, FIELD_STRIPOFFSETS))
+ {
+ uint32_t s;
+
+ fprintf(fd, " %" PRIu32 " %s:\n", td->td_nstrips,
+ isTiled(tif) ? "Tiles" : "Strips");
+ for (s = 0; s < td->td_nstrips; s++)
+ fprintf(fd, " %3" PRIu32 ": [%8" PRIu64 ", %8" PRIu64 "]\n", s,
+ TIFFGetStrileOffset(tif, s),
+ TIFFGetStrileByteCount(tif, s));
+ }
+}
+
+void _TIFFprintAscii(FILE *fd, const char *cp)
+{
+ _TIFFprintAsciiBounded(fd, cp, strlen(cp));
+}
+
+static void _TIFFprintAsciiBounded(FILE *fd, const char *cp, size_t max_chars)
+{
+ for (; max_chars > 0 && *cp != '\0'; cp++, max_chars--)
+ {
+ const char *tp;
+
+ if (isprint((int)*cp))
+ {
+ fputc(*cp, fd);
+ continue;
+ }
+ for (tp = "\tt\bb\rr\nn\vv"; *tp; tp++)
+ if (*tp++ == *cp)
+ break;
+ if (*tp)
+ fprintf(fd, "\\%c", *tp);
+ else
+ fprintf(fd, "\\%03o", *cp & 0xff);
+ }
+}
+
+void _TIFFprintAsciiTag(FILE *fd, const char *name, const char *value)
+{
+ fprintf(fd, " %s: \"", name);
+ _TIFFprintAscii(fd, value);
+ fprintf(fd, "\"\n");
+}
diff --git a/contrib/libs/libtiff/tif_read.c b/contrib/libs/libtiff/tif_read.c
new file mode 100644
index 0000000000..4fec83969e
--- /dev/null
+++ b/contrib/libs/libtiff/tif_read.c
@@ -0,0 +1,1624 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ * Scanline-oriented Read Support
+ */
+#include "tiffiop.h"
+#include <stdio.h>
+
+int TIFFFillStrip(TIFF *tif, uint32_t strip);
+int TIFFFillTile(TIFF *tif, uint32_t tile);
+static int TIFFStartStrip(TIFF *tif, uint32_t strip);
+static int TIFFStartTile(TIFF *tif, uint32_t tile);
+static int TIFFCheckRead(TIFF *, int);
+static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf,
+ tmsize_t size, const char *module);
+static tmsize_t TIFFReadRawTile1(TIFF *tif, uint32_t tile, void *buf,
+ tmsize_t size, const char *module);
+
+#define NOSTRIP ((uint32_t)(-1)) /* undefined state */
+#define NOTILE ((uint32_t)(-1)) /* undefined state */
+
+#define INITIAL_THRESHOLD (1024 * 1024)
+#define THRESHOLD_MULTIPLIER 10
+#define MAX_THRESHOLD \
+ (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * \
+ INITIAL_THRESHOLD)
+
+#define TIFF_INT64_MAX ((((int64_t)0x7FFFFFFF) << 32) | 0xFFFFFFFF)
+
+/* Read 'size' bytes in tif_rawdata buffer starting at offset 'rawdata_offset'
+ * Returns 1 in case of success, 0 otherwise. */
+static int TIFFReadAndRealloc(TIFF *tif, tmsize_t size, tmsize_t rawdata_offset,
+ int is_strip, uint32_t strip_or_tile,
+ const char *module)
+{
+#if SIZEOF_SIZE_T == 8
+ tmsize_t threshold = INITIAL_THRESHOLD;
+#endif
+ tmsize_t already_read = 0;
+
+#if SIZEOF_SIZE_T != 8
+ /* On 32 bit processes, if the request is large enough, check against */
+ /* file size */
+ if (size > 1000 * 1000 * 1000)
+ {
+ uint64_t filesize = TIFFGetFileSize(tif);
+ if ((uint64_t)size >= filesize)
+ {
+ TIFFErrorExtR(tif, module,
+ "Chunk size requested is larger than file size.");
+ return 0;
+ }
+ }
+#endif
+
+ /* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */
+ /* so as to avoid allocating too much memory in case the file is too */
+ /* short. We could ask for the file size, but this might be */
+ /* expensive with some I/O layers (think of reading a gzipped file) */
+ /* Restrict to 64 bit processes, so as to avoid reallocs() */
+ /* on 32 bit processes where virtual memory is scarce. */
+ while (already_read < size)
+ {
+ tmsize_t bytes_read;
+ tmsize_t to_read = size - already_read;
+#if SIZEOF_SIZE_T == 8
+ if (to_read >= threshold && threshold < MAX_THRESHOLD &&
+ already_read + to_read + rawdata_offset > tif->tif_rawdatasize)
+ {
+ to_read = threshold;
+ threshold *= THRESHOLD_MULTIPLIER;
+ }
+#endif
+ if (already_read + to_read + rawdata_offset > tif->tif_rawdatasize)
+ {
+ uint8_t *new_rawdata;
+ assert((tif->tif_flags & TIFF_MYBUFFER) != 0);
+ tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64(
+ (uint64_t)already_read + to_read + rawdata_offset, 1024);
+ if (tif->tif_rawdatasize == 0)
+ {
+ TIFFErrorExtR(tif, module, "Invalid buffer size");
+ return 0;
+ }
+ new_rawdata =
+ (uint8_t *)_TIFFrealloc(tif->tif_rawdata, tif->tif_rawdatasize);
+ if (new_rawdata == 0)
+ {
+ TIFFErrorExtR(tif, module,
+ "No space for data buffer at scanline %" PRIu32,
+ tif->tif_row);
+ _TIFFfreeExt(tif, tif->tif_rawdata);
+ tif->tif_rawdata = 0;
+ tif->tif_rawdatasize = 0;
+ return 0;
+ }
+ tif->tif_rawdata = new_rawdata;
+ }
+ if (tif->tif_rawdata == NULL)
+ {
+ /* should not happen in practice but helps CoverityScan */
+ return 0;
+ }
+
+ bytes_read = TIFFReadFile(
+ tif, tif->tif_rawdata + rawdata_offset + already_read, to_read);
+ already_read += bytes_read;
+ if (bytes_read != to_read)
+ {
+ memset(tif->tif_rawdata + rawdata_offset + already_read, 0,
+ tif->tif_rawdatasize - rawdata_offset - already_read);
+ if (is_strip)
+ {
+ TIFFErrorExtR(tif, module,
+ "Read error at scanline %" PRIu32
+ "; got %" TIFF_SSIZE_FORMAT " bytes, "
+ "expected %" TIFF_SSIZE_FORMAT,
+ tif->tif_row, already_read, size);
+ }
+ else
+ {
+ TIFFErrorExtR(tif, module,
+ "Read error at row %" PRIu32 ", col %" PRIu32
+ ", tile %" PRIu32 "; "
+ "got %" TIFF_SSIZE_FORMAT
+ " bytes, expected %" TIFF_SSIZE_FORMAT "",
+ tif->tif_row, tif->tif_col, strip_or_tile,
+ already_read, size);
+ }
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int TIFFFillStripPartial(TIFF *tif, int strip, tmsize_t read_ahead,
+ int restart)
+{
+ static const char module[] = "TIFFFillStripPartial";
+ register TIFFDirectory *td = &tif->tif_dir;
+ tmsize_t unused_data;
+ uint64_t read_offset;
+ tmsize_t to_read;
+ tmsize_t read_ahead_mod;
+ /* tmsize_t bytecountm; */
+
+ /*
+ * Expand raw data buffer, if needed, to hold data
+ * strip coming from file (perhaps should set upper
+ * bound on the size of a buffer we'll use?).
+ */
+
+ /* bytecountm=(tmsize_t) TIFFGetStrileByteCount(tif, strip); */
+
+ /* Not completely sure where the * 2 comes from, but probably for */
+ /* an exponentional growth strategy of tif_rawdatasize */
+ if (read_ahead < TIFF_TMSIZE_T_MAX / 2)
+ read_ahead_mod = read_ahead * 2;
+ else
+ read_ahead_mod = read_ahead;
+ if (read_ahead_mod > tif->tif_rawdatasize)
+ {
+ assert(restart);
+
+ tif->tif_curstrip = NOSTRIP;
+ if ((tif->tif_flags & TIFF_MYBUFFER) == 0)
+ {
+ TIFFErrorExtR(tif, module,
+ "Data buffer too small to hold part of strip %d",
+ strip);
+ return (0);
+ }
+ }
+
+ if (restart)
+ {
+ tif->tif_rawdataloaded = 0;
+ tif->tif_rawdataoff = 0;
+ }
+
+ /*
+ ** If we are reading more data, move any unused data to the
+ ** start of the buffer.
+ */
+ if (tif->tif_rawdataloaded > 0)
+ unused_data =
+ tif->tif_rawdataloaded - (tif->tif_rawcp - tif->tif_rawdata);
+ else
+ unused_data = 0;
+
+ if (unused_data > 0)
+ {
+ assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0);
+ memmove(tif->tif_rawdata, tif->tif_rawcp, unused_data);
+ }
+
+ /*
+ ** Seek to the point in the file where more data should be read.
+ */
+ read_offset = TIFFGetStrileOffset(tif, strip) + tif->tif_rawdataoff +
+ tif->tif_rawdataloaded;
+
+ if (!SeekOK(tif, read_offset))
+ {
+ TIFFErrorExtR(tif, module,
+ "Seek error at scanline %" PRIu32 ", strip %d",
+ tif->tif_row, strip);
+ return 0;
+ }
+
+ /*
+ ** How much do we want to read?
+ */
+ if (read_ahead_mod > tif->tif_rawdatasize)
+ to_read = read_ahead_mod - unused_data;
+ else
+ to_read = tif->tif_rawdatasize - unused_data;
+ if ((uint64_t)to_read > TIFFGetStrileByteCount(tif, strip) -
+ tif->tif_rawdataoff - tif->tif_rawdataloaded)
+ {
+ to_read = (tmsize_t)TIFFGetStrileByteCount(tif, strip) -
+ tif->tif_rawdataoff - tif->tif_rawdataloaded;
+ }
+
+ assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0);
+ if (!TIFFReadAndRealloc(tif, to_read, unused_data, 1, /* is_strip */
+ 0, /* strip_or_tile */
+ module))
+ {
+ return 0;
+ }
+
+ tif->tif_rawdataoff =
+ tif->tif_rawdataoff + tif->tif_rawdataloaded - unused_data;
+ tif->tif_rawdataloaded = unused_data + to_read;
+
+ tif->tif_rawcc = tif->tif_rawdataloaded;
+ tif->tif_rawcp = tif->tif_rawdata;
+
+ if (!isFillOrder(tif, td->td_fillorder) &&
+ (tif->tif_flags & TIFF_NOBITREV) == 0)
+ {
+ assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0);
+ TIFFReverseBits(tif->tif_rawdata + unused_data, to_read);
+ }
+
+ /*
+ ** When starting a strip from the beginning we need to
+ ** restart the decoder.
+ */
+ if (restart)
+ {
+
+#ifdef JPEG_SUPPORT
+ /* A bit messy since breaks the codec abstraction. Ultimately */
+ /* there should be a function pointer for that, but it seems */
+ /* only JPEG is affected. */
+ /* For JPEG, if there are multiple scans (can generally be known */
+ /* with the read_ahead used), we need to read the whole strip */
+ if (tif->tif_dir.td_compression == COMPRESSION_JPEG &&
+ (uint64_t)tif->tif_rawcc < TIFFGetStrileByteCount(tif, strip))
+ {
+ if (TIFFJPEGIsFullStripRequired(tif))
+ {
+ return TIFFFillStrip(tif, strip);
+ }
+ }
+#endif
+
+ return TIFFStartStrip(tif, strip);
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+/*
+ * Seek to a random row+sample in a file.
+ *
+ * Only used by TIFFReadScanline, and is only used on
+ * strip organized files. We do some tricky stuff to try
+ * and avoid reading the whole compressed raw data for big
+ * strips.
+ */
+static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample)
+{
+ register TIFFDirectory *td = &tif->tif_dir;
+ uint32_t strip;
+ int whole_strip;
+ tmsize_t read_ahead = 0;
+
+ /*
+ ** Establish what strip we are working from.
+ */
+ if (row >= td->td_imagelength)
+ { /* out of range */
+ TIFFErrorExtR(tif, tif->tif_name,
+ "%" PRIu32 ": Row out of range, max %" PRIu32 "", row,
+ td->td_imagelength);
+ return (0);
+ }
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
+ {
+ if (sample >= td->td_samplesperpixel)
+ {
+ TIFFErrorExtR(tif, tif->tif_name,
+ "%" PRIu16 ": Sample out of range, max %" PRIu16 "",
+ sample, td->td_samplesperpixel);
+ return (0);
+ }
+ strip = (uint32_t)sample * td->td_stripsperimage +
+ row / td->td_rowsperstrip;
+ }
+ else
+ strip = row / td->td_rowsperstrip;
+
+ /*
+ * Do we want to treat this strip as one whole chunk or
+ * read it a few lines at a time?
+ */
+#if defined(CHUNKY_STRIP_READ_SUPPORT)
+ whole_strip = TIFFGetStrileByteCount(tif, strip) < 10 || isMapped(tif);
+ if (td->td_compression == COMPRESSION_LERC ||
+ td->td_compression == COMPRESSION_JBIG)
+ {
+ /* Ideally plugins should have a way to declare they don't support
+ * chunk strip */
+ whole_strip = 1;
+ }
+#else
+ whole_strip = 1;
+#endif
+
+ if (!whole_strip)
+ {
+ /* 16 is for YCbCr mode where we may need to read 16 */
+ /* lines at a time to get a decompressed line, and 5000 */
+ /* is some constant value, for example for JPEG tables */
+ if (tif->tif_scanlinesize < TIFF_TMSIZE_T_MAX / 16 &&
+ tif->tif_scanlinesize * 16 < TIFF_TMSIZE_T_MAX - 5000)
+ {
+ read_ahead = tif->tif_scanlinesize * 16 + 5000;
+ }
+ else
+ {
+ read_ahead = tif->tif_scanlinesize;
+ }
+ }
+
+ /*
+ * If we haven't loaded this strip, do so now, possibly
+ * only reading the first part.
+ */
+ if (strip != tif->tif_curstrip)
+ { /* different strip, refill */
+
+ if (whole_strip)
+ {
+ if (!TIFFFillStrip(tif, strip))
+ return (0);
+ }
+ else
+ {
+ if (!TIFFFillStripPartial(tif, strip, read_ahead, 1))
+ return 0;
+ }
+ }
+
+ /*
+ ** If we already have some data loaded, do we need to read some more?
+ */
+ else if (!whole_strip)
+ {
+ if (((tif->tif_rawdata + tif->tif_rawdataloaded) - tif->tif_rawcp) <
+ read_ahead &&
+ (uint64_t)tif->tif_rawdataoff + tif->tif_rawdataloaded <
+ TIFFGetStrileByteCount(tif, strip))
+ {
+ if (!TIFFFillStripPartial(tif, strip, read_ahead, 0))
+ return 0;
+ }
+ }
+
+ if (row < tif->tif_row)
+ {
+ /*
+ * Moving backwards within the same strip: backup
+ * to the start and then decode forward (below).
+ *
+ * NB: If you're planning on lots of random access within a
+ * strip, it's better to just read and decode the entire
+ * strip, and then access the decoded data in a random fashion.
+ */
+
+ if (tif->tif_rawdataoff != 0)
+ {
+ if (!TIFFFillStripPartial(tif, strip, read_ahead, 1))
+ return 0;
+ }
+ else
+ {
+ if (!TIFFStartStrip(tif, strip))
+ return (0);
+ }
+ }
+
+ if (row != tif->tif_row)
+ {
+ /*
+ * Seek forward to the desired row.
+ */
+
+ /* TODO: Will this really work with partial buffers? */
+
+ if (!(*tif->tif_seek)(tif, row - tif->tif_row))
+ return (0);
+ tif->tif_row = row;
+ }
+
+ return (1);
+}
+
+int TIFFReadScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
+{
+ int e;
+
+ if (!TIFFCheckRead(tif, 0))
+ return (-1);
+ if ((e = TIFFSeek(tif, row, sample)) != 0)
+ {
+ /*
+ * Decompress desired row into user buffer.
+ */
+ e = (*tif->tif_decoderow)(tif, (uint8_t *)buf, tif->tif_scanlinesize,
+ sample);
+
+ /* we are now poised at the beginning of the next row */
+ tif->tif_row = row + 1;
+
+ if (e)
+ (*tif->tif_postdecode)(tif, (uint8_t *)buf, tif->tif_scanlinesize);
+ }
+ return (e > 0 ? 1 : -1);
+}
+
+/*
+ * Calculate the strip size according to the number of
+ * rows in the strip (check for truncated last strip on any
+ * of the separations).
+ */
+static tmsize_t TIFFReadEncodedStripGetStripSize(TIFF *tif, uint32_t strip,
+ uint16_t *pplane)
+{
+ static const char module[] = "TIFFReadEncodedStrip";
+ TIFFDirectory *td = &tif->tif_dir;
+ uint32_t rowsperstrip;
+ uint32_t stripsperplane;
+ uint32_t stripinplane;
+ uint32_t rows;
+ tmsize_t stripsize;
+ if (!TIFFCheckRead(tif, 0))
+ return ((tmsize_t)(-1));
+ if (strip >= td->td_nstrips)
+ {
+ TIFFErrorExtR(tif, module,
+ "%" PRIu32 ": Strip out of range, max %" PRIu32, strip,
+ td->td_nstrips);
+ return ((tmsize_t)(-1));
+ }
+
+ rowsperstrip = td->td_rowsperstrip;
+ if (rowsperstrip > td->td_imagelength)
+ rowsperstrip = td->td_imagelength;
+ stripsperplane =
+ TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip);
+ stripinplane = (strip % stripsperplane);
+ if (pplane)
+ *pplane = (uint16_t)(strip / stripsperplane);
+ rows = td->td_imagelength - stripinplane * rowsperstrip;
+ if (rows > rowsperstrip)
+ rows = rowsperstrip;
+ stripsize = TIFFVStripSize(tif, rows);
+ if (stripsize == 0)
+ return ((tmsize_t)(-1));
+ return stripsize;
+}
+
+/*
+ * Read a strip of data and decompress the specified
+ * amount into the user-supplied buffer.
+ */
+tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32_t strip, void *buf,
+ tmsize_t size)
+{
+ static const char module[] = "TIFFReadEncodedStrip";
+ TIFFDirectory *td = &tif->tif_dir;
+ tmsize_t stripsize;
+ uint16_t plane;
+
+ stripsize = TIFFReadEncodedStripGetStripSize(tif, strip, &plane);
+ if (stripsize == ((tmsize_t)(-1)))
+ return ((tmsize_t)(-1));
+
+ /* shortcut to avoid an extra memcpy() */
+ if (td->td_compression == COMPRESSION_NONE && size != (tmsize_t)(-1) &&
+ size >= stripsize && !isMapped(tif) &&
+ ((tif->tif_flags & TIFF_NOREADRAW) == 0))
+ {
+ if (TIFFReadRawStrip1(tif, strip, buf, stripsize, module) != stripsize)
+ return ((tmsize_t)(-1));
+
+ if (!isFillOrder(tif, td->td_fillorder) &&
+ (tif->tif_flags & TIFF_NOBITREV) == 0)
+ TIFFReverseBits(buf, stripsize);
+
+ (*tif->tif_postdecode)(tif, buf, stripsize);
+ return (stripsize);
+ }
+
+ if ((size != (tmsize_t)(-1)) && (size < stripsize))
+ stripsize = size;
+ if (!TIFFFillStrip(tif, strip))
+ return ((tmsize_t)(-1));
+ if ((*tif->tif_decodestrip)(tif, buf, stripsize, plane) <= 0)
+ return ((tmsize_t)(-1));
+ (*tif->tif_postdecode)(tif, buf, stripsize);
+ return (stripsize);
+}
+
+/* Variant of TIFFReadEncodedStrip() that does
+ * * if *buf == NULL, *buf = _TIFFmallocExt(tif, bufsizetoalloc) only after
+ * TIFFFillStrip() has succeeded. This avoid excessive memory allocation in case
+ * of truncated file.
+ * * calls regular TIFFReadEncodedStrip() if *buf != NULL
+ */
+tmsize_t _TIFFReadEncodedStripAndAllocBuffer(TIFF *tif, uint32_t strip,
+ void **buf,
+ tmsize_t bufsizetoalloc,
+ tmsize_t size_to_read)
+{
+ tmsize_t this_stripsize;
+ uint16_t plane;
+
+ if (*buf != NULL)
+ {
+ return TIFFReadEncodedStrip(tif, strip, *buf, size_to_read);
+ }
+
+ this_stripsize = TIFFReadEncodedStripGetStripSize(tif, strip, &plane);
+ if (this_stripsize == ((tmsize_t)(-1)))
+ return ((tmsize_t)(-1));
+
+ if ((size_to_read != (tmsize_t)(-1)) && (size_to_read < this_stripsize))
+ this_stripsize = size_to_read;
+ if (!TIFFFillStrip(tif, strip))
+ return ((tmsize_t)(-1));
+
+ *buf = _TIFFmallocExt(tif, bufsizetoalloc);
+ if (*buf == NULL)
+ {
+ TIFFErrorExtR(tif, TIFFFileName(tif), "No space for strip buffer");
+ return ((tmsize_t)(-1));
+ }
+ _TIFFmemset(*buf, 0, bufsizetoalloc);
+
+ if ((*tif->tif_decodestrip)(tif, *buf, this_stripsize, plane) <= 0)
+ return ((tmsize_t)(-1));
+ (*tif->tif_postdecode)(tif, *buf, this_stripsize);
+ return (this_stripsize);
+}
+
+static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf,
+ tmsize_t size, const char *module)
+{
+ assert((tif->tif_flags & TIFF_NOREADRAW) == 0);
+ if (!isMapped(tif))
+ {
+ tmsize_t cc;
+
+ if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip)))
+ {
+ TIFFErrorExtR(tif, module,
+ "Seek error at scanline %" PRIu32 ", strip %" PRIu32,
+ tif->tif_row, strip);
+ return ((tmsize_t)(-1));
+ }
+ cc = TIFFReadFile(tif, buf, size);
+ if (cc != size)
+ {
+ TIFFErrorExtR(tif, module,
+ "Read error at scanline %" PRIu32
+ "; got %" TIFF_SSIZE_FORMAT
+ " bytes, expected %" TIFF_SSIZE_FORMAT,
+ tif->tif_row, cc, size);
+ return ((tmsize_t)(-1));
+ }
+ }
+ else
+ {
+ tmsize_t ma = 0;
+ tmsize_t n;
+ if ((TIFFGetStrileOffset(tif, strip) > (uint64_t)TIFF_TMSIZE_T_MAX) ||
+ ((ma = (tmsize_t)TIFFGetStrileOffset(tif, strip)) > tif->tif_size))
+ {
+ n = 0;
+ }
+ else if (ma > TIFF_TMSIZE_T_MAX - size)
+ {
+ n = 0;
+ }
+ else
+ {
+ tmsize_t mb = ma + size;
+ if (mb > tif->tif_size)
+ n = tif->tif_size - ma;
+ else
+ n = size;
+ }
+ if (n != size)
+ {
+ TIFFErrorExtR(tif, module,
+ "Read error at scanline %" PRIu32 ", strip %" PRIu32
+ "; got %" TIFF_SSIZE_FORMAT
+ " bytes, expected %" TIFF_SSIZE_FORMAT,
+ tif->tif_row, strip, n, size);
+ return ((tmsize_t)(-1));
+ }
+ _TIFFmemcpy(buf, tif->tif_base + ma, size);
+ }
+ return (size);
+}
+
+static tmsize_t TIFFReadRawStripOrTile2(TIFF *tif, uint32_t strip_or_tile,
+ int is_strip, tmsize_t size,
+ const char *module)
+{
+ assert(!isMapped(tif));
+ assert((tif->tif_flags & TIFF_NOREADRAW) == 0);
+
+ if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip_or_tile)))
+ {
+ if (is_strip)
+ {
+ TIFFErrorExtR(tif, module,
+ "Seek error at scanline %" PRIu32 ", strip %" PRIu32,
+ tif->tif_row, strip_or_tile);
+ }
+ else
+ {
+ TIFFErrorExtR(tif, module,
+ "Seek error at row %" PRIu32 ", col %" PRIu32
+ ", tile %" PRIu32,
+ tif->tif_row, tif->tif_col, strip_or_tile);
+ }
+ return ((tmsize_t)(-1));
+ }
+
+ if (!TIFFReadAndRealloc(tif, size, 0, is_strip, strip_or_tile, module))
+ {
+ return ((tmsize_t)(-1));
+ }
+
+ return (size);
+}
+
+/*
+ * Read a strip of data from the file.
+ */
+tmsize_t TIFFReadRawStrip(TIFF *tif, uint32_t strip, void *buf, tmsize_t size)
+{
+ static const char module[] = "TIFFReadRawStrip";
+ TIFFDirectory *td = &tif->tif_dir;
+ uint64_t bytecount64;
+ tmsize_t bytecountm;
+
+ if (!TIFFCheckRead(tif, 0))
+ return ((tmsize_t)(-1));
+ if (strip >= td->td_nstrips)
+ {
+ TIFFErrorExtR(tif, module,
+ "%" PRIu32 ": Strip out of range, max %" PRIu32, strip,
+ td->td_nstrips);
+ return ((tmsize_t)(-1));
+ }
+ if (tif->tif_flags & TIFF_NOREADRAW)
+ {
+ TIFFErrorExtR(tif, module,
+ "Compression scheme does not support access to raw "
+ "uncompressed data");
+ return ((tmsize_t)(-1));
+ }
+ bytecount64 = TIFFGetStrileByteCount(tif, strip);
+ if (size != (tmsize_t)(-1) && (uint64_t)size <= bytecount64)
+ bytecountm = size;
+ else
+ bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module);
+ if (bytecountm == 0)
+ {
+ return ((tmsize_t)(-1));
+ }
+ return (TIFFReadRawStrip1(tif, strip, buf, bytecountm, module));
+}
+
+TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
+static uint64_t NoSanitizeSubUInt64(uint64_t a, uint64_t b) { return a - b; }
+
+/*
+ * Read the specified strip and setup for decoding. The data buffer is
+ * expanded, as necessary, to hold the strip's data.
+ */
+int TIFFFillStrip(TIFF *tif, uint32_t strip)
+{
+ static const char module[] = "TIFFFillStrip";
+ TIFFDirectory *td = &tif->tif_dir;
+
+ if ((tif->tif_flags & TIFF_NOREADRAW) == 0)
+ {
+ uint64_t bytecount = TIFFGetStrileByteCount(tif, strip);
+ if (bytecount == 0 || bytecount > (uint64_t)TIFF_INT64_MAX)
+ {
+ TIFFErrorExtR(tif, module,
+ "Invalid strip byte count %" PRIu64
+ ", strip %" PRIu32,
+ bytecount, strip);
+ return (0);
+ }
+
+ /* To avoid excessive memory allocations: */
+ /* Byte count should normally not be larger than a number of */
+ /* times the uncompressed size plus some margin */
+ if (bytecount > 1024 * 1024)
+ {
+ /* 10 and 4096 are just values that could be adjusted. */
+ /* Hopefully they are safe enough for all codecs */
+ tmsize_t stripsize = TIFFStripSize(tif);
+ if (stripsize != 0 && (bytecount - 4096) / 10 > (uint64_t)stripsize)
+ {
+ uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096;
+ TIFFErrorExtR(tif, module,
+ "Too large strip byte count %" PRIu64
+ ", strip %" PRIu32 ". Limiting to %" PRIu64,
+ bytecount, strip, newbytecount);
+ bytecount = newbytecount;
+ }
+ }
+
+ if (isMapped(tif))
+ {
+ /*
+ * We must check for overflow, potentially causing
+ * an OOB read. Instead of simple
+ *
+ * TIFFGetStrileOffset(tif, strip)+bytecount > tif->tif_size
+ *
+ * comparison (which can overflow) we do the following
+ * two comparisons:
+ */
+ if (bytecount > (uint64_t)tif->tif_size ||
+ TIFFGetStrileOffset(tif, strip) >
+ (uint64_t)tif->tif_size - bytecount)
+ {
+ /*
+ * This error message might seem strange, but
+ * it's what would happen if a read were done
+ * instead.
+ */
+ TIFFErrorExtR(
+ tif, module,
+
+ "Read error on strip %" PRIu32 "; "
+ "got %" PRIu64 " bytes, expected %" PRIu64,
+ strip,
+ NoSanitizeSubUInt64(tif->tif_size,
+ TIFFGetStrileOffset(tif, strip)),
+ bytecount);
+ tif->tif_curstrip = NOSTRIP;
+ return (0);
+ }
+ }
+
+ if (isMapped(tif) && (isFillOrder(tif, td->td_fillorder) ||
+ (tif->tif_flags & TIFF_NOBITREV)))
+ {
+ /*
+ * The image is mapped into memory and we either don't
+ * need to flip bits or the compression routine is
+ * going to handle this operation itself. In this
+ * case, avoid copying the raw data and instead just
+ * reference the data from the memory mapped file
+ * image. This assumes that the decompression
+ * routines do not modify the contents of the raw data
+ * buffer (if they try to, the application will get a
+ * fault since the file is mapped read-only).
+ */
+ if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
+ {
+ _TIFFfreeExt(tif, tif->tif_rawdata);
+ tif->tif_rawdata = NULL;
+ tif->tif_rawdatasize = 0;
+ }
+ tif->tif_flags &= ~TIFF_MYBUFFER;
+ tif->tif_rawdatasize = (tmsize_t)bytecount;
+ tif->tif_rawdata =
+ tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, strip);
+ tif->tif_rawdataoff = 0;
+ tif->tif_rawdataloaded = (tmsize_t)bytecount;
+
+ /*
+ * When we have tif_rawdata reference directly into the memory
+ * mapped file we need to be pretty careful about how we use the
+ * rawdata. It is not a general purpose working buffer as it
+ * normally otherwise is. So we keep track of this fact to avoid
+ * using it improperly.
+ */
+ tif->tif_flags |= TIFF_BUFFERMMAP;
+ }
+ else
+ {
+ /*
+ * Expand raw data buffer, if needed, to hold data
+ * strip coming from file (perhaps should set upper
+ * bound on the size of a buffer we'll use?).
+ */
+ tmsize_t bytecountm;
+ bytecountm = (tmsize_t)bytecount;
+ if ((uint64_t)bytecountm != bytecount)
+ {
+ TIFFErrorExtR(tif, module, "Integer overflow");
+ return (0);
+ }
+ if (bytecountm > tif->tif_rawdatasize)
+ {
+ tif->tif_curstrip = NOSTRIP;
+ if ((tif->tif_flags & TIFF_MYBUFFER) == 0)
+ {
+ TIFFErrorExtR(
+ tif, module,
+ "Data buffer too small to hold strip %" PRIu32, strip);
+ return (0);
+ }
+ }
+ if (tif->tif_flags & TIFF_BUFFERMMAP)
+ {
+ tif->tif_curstrip = NOSTRIP;
+ tif->tif_rawdata = NULL;
+ tif->tif_rawdatasize = 0;
+ tif->tif_flags &= ~TIFF_BUFFERMMAP;
+ }
+
+ if (isMapped(tif))
+ {
+ if (bytecountm > tif->tif_rawdatasize &&
+ !TIFFReadBufferSetup(tif, 0, bytecountm))
+ {
+ return (0);
+ }
+ if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata, bytecountm,
+ module) != bytecountm)
+ {
+ return (0);
+ }
+ }
+ else
+ {
+ if (TIFFReadRawStripOrTile2(tif, strip, 1, bytecountm,
+ module) != bytecountm)
+ {
+ return (0);
+ }
+ }
+
+ tif->tif_rawdataoff = 0;
+ tif->tif_rawdataloaded = bytecountm;
+
+ if (!isFillOrder(tif, td->td_fillorder) &&
+ (tif->tif_flags & TIFF_NOBITREV) == 0)
+ TIFFReverseBits(tif->tif_rawdata, bytecountm);
+ }
+ }
+ return (TIFFStartStrip(tif, strip));
+}
+
+/*
+ * Tile-oriented Read Support
+ * Contributed by Nancy Cam (Silicon Graphics).
+ */
+
+/*
+ * Read and decompress a tile of data. The
+ * tile is selected by the (x,y,z,s) coordinates.
+ */
+tmsize_t TIFFReadTile(TIFF *tif, void *buf, uint32_t x, uint32_t y, uint32_t z,
+ uint16_t s)
+{
+ if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s))
+ return ((tmsize_t)(-1));
+ return (TIFFReadEncodedTile(tif, TIFFComputeTile(tif, x, y, z, s), buf,
+ (tmsize_t)(-1)));
+}
+
+/*
+ * Read a tile of data and decompress the specified
+ * amount into the user-supplied buffer.
+ */
+tmsize_t TIFFReadEncodedTile(TIFF *tif, uint32_t tile, void *buf, tmsize_t size)
+{
+ static const char module[] = "TIFFReadEncodedTile";
+ TIFFDirectory *td = &tif->tif_dir;
+ tmsize_t tilesize = tif->tif_tilesize;
+
+ if (!TIFFCheckRead(tif, 1))
+ return ((tmsize_t)(-1));
+ if (tile >= td->td_nstrips)
+ {
+ TIFFErrorExtR(tif, module,
+ "%" PRIu32 ": Tile out of range, max %" PRIu32, tile,
+ td->td_nstrips);
+ return ((tmsize_t)(-1));
+ }
+
+ /* shortcut to avoid an extra memcpy() */
+ if (td->td_compression == COMPRESSION_NONE && size != (tmsize_t)(-1) &&
+ size >= tilesize && !isMapped(tif) &&
+ ((tif->tif_flags & TIFF_NOREADRAW) == 0))
+ {
+ if (TIFFReadRawTile1(tif, tile, buf, tilesize, module) != tilesize)
+ return ((tmsize_t)(-1));
+
+ if (!isFillOrder(tif, td->td_fillorder) &&
+ (tif->tif_flags & TIFF_NOBITREV) == 0)
+ TIFFReverseBits(buf, tilesize);
+
+ (*tif->tif_postdecode)(tif, buf, tilesize);
+ return (tilesize);
+ }
+
+ if (size == (tmsize_t)(-1))
+ size = tilesize;
+ else if (size > tilesize)
+ size = tilesize;
+ if (TIFFFillTile(tif, tile) &&
+ (*tif->tif_decodetile)(tif, (uint8_t *)buf, size,
+ (uint16_t)(tile / td->td_stripsperimage)))
+ {
+ (*tif->tif_postdecode)(tif, (uint8_t *)buf, size);
+ return (size);
+ }
+ else
+ return ((tmsize_t)(-1));
+}
+
+/* Variant of TIFFReadTile() that does
+ * * if *buf == NULL, *buf = _TIFFmallocExt(tif, bufsizetoalloc) only after
+ * TIFFFillTile() has succeeded. This avoid excessive memory allocation in case
+ * of truncated file.
+ * * calls regular TIFFReadEncodedTile() if *buf != NULL
+ */
+tmsize_t _TIFFReadTileAndAllocBuffer(TIFF *tif, void **buf,
+ tmsize_t bufsizetoalloc, uint32_t x,
+ uint32_t y, uint32_t z, uint16_t s)
+{
+ if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s))
+ return ((tmsize_t)(-1));
+ return (_TIFFReadEncodedTileAndAllocBuffer(
+ tif, TIFFComputeTile(tif, x, y, z, s), buf, bufsizetoalloc,
+ (tmsize_t)(-1)));
+}
+
+/* Variant of TIFFReadEncodedTile() that does
+ * * if *buf == NULL, *buf = _TIFFmallocExt(tif, bufsizetoalloc) only after
+ * TIFFFillTile() has succeeded. This avoid excessive memory allocation in case
+ * of truncated file.
+ * * calls regular TIFFReadEncodedTile() if *buf != NULL
+ */
+tmsize_t _TIFFReadEncodedTileAndAllocBuffer(TIFF *tif, uint32_t tile,
+ void **buf, tmsize_t bufsizetoalloc,
+ tmsize_t size_to_read)
+{
+ static const char module[] = "_TIFFReadEncodedTileAndAllocBuffer";
+ TIFFDirectory *td = &tif->tif_dir;
+ tmsize_t tilesize = tif->tif_tilesize;
+
+ if (*buf != NULL)
+ {
+ return TIFFReadEncodedTile(tif, tile, *buf, size_to_read);
+ }
+
+ if (!TIFFCheckRead(tif, 1))
+ return ((tmsize_t)(-1));
+ if (tile >= td->td_nstrips)
+ {
+ TIFFErrorExtR(tif, module,
+ "%" PRIu32 ": Tile out of range, max %" PRIu32, tile,
+ td->td_nstrips);
+ return ((tmsize_t)(-1));
+ }
+
+ if (!TIFFFillTile(tif, tile))
+ return ((tmsize_t)(-1));
+
+ /* Sanity checks to avoid excessive memory allocation */
+ /* Cf https://gitlab.com/libtiff/libtiff/-/issues/479 */
+ if (td->td_compression == COMPRESSION_NONE)
+ {
+ if (tif->tif_rawdatasize != tilesize)
+ {
+ TIFFErrorExtR(tif, TIFFFileName(tif),
+ "Invalid tile byte count for tile %u. "
+ "Expected %" PRIu64 ", got %" PRIu64,
+ tile, (uint64_t)tilesize,
+ (uint64_t)tif->tif_rawdatasize);
+ return ((tmsize_t)(-1));
+ }
+ }
+ else
+ {
+ /* Max compression ratio experimentally determined. Might be fragile...
+ * Only apply this heuristics to situations where the memory allocation
+ * would be big, to avoid breaking nominal use cases.
+ */
+ const int maxCompressionRatio =
+ td->td_compression == COMPRESSION_ZSTD ? 33000
+ : td->td_compression == COMPRESSION_JXL
+ ?
+ /* Evaluated on a 8000x8000 tile */
+ 25000 * (td->td_planarconfig == PLANARCONFIG_CONTIG
+ ? td->td_samplesperpixel
+ : 1)
+ : td->td_compression == COMPRESSION_LZMA ? 7000 : 1000;
+ if (bufsizetoalloc > 100 * 1000 * 1000 &&
+ tif->tif_rawdatasize < tilesize / maxCompressionRatio)
+ {
+ TIFFErrorExtR(tif, TIFFFileName(tif),
+ "Likely invalid tile byte count for tile %u. "
+ "Uncompressed tile size is %" PRIu64 ", "
+ "compressed one is %" PRIu64,
+ tile, (uint64_t)tilesize,
+ (uint64_t)tif->tif_rawdatasize);
+ return ((tmsize_t)(-1));
+ }
+ }
+
+ *buf = _TIFFmallocExt(tif, bufsizetoalloc);
+ if (*buf == NULL)
+ {
+ TIFFErrorExtR(tif, TIFFFileName(tif), "No space for tile buffer");
+ return ((tmsize_t)(-1));
+ }
+ _TIFFmemset(*buf, 0, bufsizetoalloc);
+
+ if (size_to_read == (tmsize_t)(-1))
+ size_to_read = tilesize;
+ else if (size_to_read > tilesize)
+ size_to_read = tilesize;
+ if ((*tif->tif_decodetile)(tif, (uint8_t *)*buf, size_to_read,
+ (uint16_t)(tile / td->td_stripsperimage)))
+ {
+ (*tif->tif_postdecode)(tif, (uint8_t *)*buf, size_to_read);
+ return (size_to_read);
+ }
+ else
+ return ((tmsize_t)(-1));
+}
+
+static tmsize_t TIFFReadRawTile1(TIFF *tif, uint32_t tile, void *buf,
+ tmsize_t size, const char *module)
+{
+ assert((tif->tif_flags & TIFF_NOREADRAW) == 0);
+ if (!isMapped(tif))
+ {
+ tmsize_t cc;
+
+ if (!SeekOK(tif, TIFFGetStrileOffset(tif, tile)))
+ {
+ TIFFErrorExtR(tif, module,
+ "Seek error at row %" PRIu32 ", col %" PRIu32
+ ", tile %" PRIu32,
+ tif->tif_row, tif->tif_col, tile);
+ return ((tmsize_t)(-1));
+ }
+ cc = TIFFReadFile(tif, buf, size);
+ if (cc != size)
+ {
+ TIFFErrorExtR(tif, module,
+ "Read error at row %" PRIu32 ", col %" PRIu32
+ "; got %" TIFF_SSIZE_FORMAT
+ " bytes, expected %" TIFF_SSIZE_FORMAT,
+ tif->tif_row, tif->tif_col, cc, size);
+ return ((tmsize_t)(-1));
+ }
+ }
+ else
+ {
+ tmsize_t ma, mb;
+ tmsize_t n;
+ ma = (tmsize_t)TIFFGetStrileOffset(tif, tile);
+ mb = ma + size;
+ if ((TIFFGetStrileOffset(tif, tile) > (uint64_t)TIFF_TMSIZE_T_MAX) ||
+ (ma > tif->tif_size))
+ n = 0;
+ else if ((mb < ma) || (mb < size) || (mb > tif->tif_size))
+ n = tif->tif_size - ma;
+ else
+ n = size;
+ if (n != size)
+ {
+ TIFFErrorExtR(tif, module,
+ "Read error at row %" PRIu32 ", col %" PRIu32
+ ", tile %" PRIu32 "; got %" TIFF_SSIZE_FORMAT
+ " bytes, expected %" TIFF_SSIZE_FORMAT,
+ tif->tif_row, tif->tif_col, tile, n, size);
+ return ((tmsize_t)(-1));
+ }
+ _TIFFmemcpy(buf, tif->tif_base + ma, size);
+ }
+ return (size);
+}
+
+/*
+ * Read a tile of data from the file.
+ */
+tmsize_t TIFFReadRawTile(TIFF *tif, uint32_t tile, void *buf, tmsize_t size)
+{
+ static const char module[] = "TIFFReadRawTile";
+ TIFFDirectory *td = &tif->tif_dir;
+ uint64_t bytecount64;
+ tmsize_t bytecountm;
+
+ if (!TIFFCheckRead(tif, 1))
+ return ((tmsize_t)(-1));
+ if (tile >= td->td_nstrips)
+ {
+ TIFFErrorExtR(tif, module,
+ "%" PRIu32 ": Tile out of range, max %" PRIu32, tile,
+ td->td_nstrips);
+ return ((tmsize_t)(-1));
+ }
+ if (tif->tif_flags & TIFF_NOREADRAW)
+ {
+ TIFFErrorExtR(tif, module,
+ "Compression scheme does not support access to raw "
+ "uncompressed data");
+ return ((tmsize_t)(-1));
+ }
+ bytecount64 = TIFFGetStrileByteCount(tif, tile);
+ if (size != (tmsize_t)(-1) && (uint64_t)size <= bytecount64)
+ bytecountm = size;
+ else
+ bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module);
+ if (bytecountm == 0)
+ {
+ return ((tmsize_t)(-1));
+ }
+ return (TIFFReadRawTile1(tif, tile, buf, bytecountm, module));
+}
+
+/*
+ * Read the specified tile and setup for decoding. The data buffer is
+ * expanded, as necessary, to hold the tile's data.
+ */
+int TIFFFillTile(TIFF *tif, uint32_t tile)
+{
+ static const char module[] = "TIFFFillTile";
+ TIFFDirectory *td = &tif->tif_dir;
+
+ if ((tif->tif_flags & TIFF_NOREADRAW) == 0)
+ {
+ uint64_t bytecount = TIFFGetStrileByteCount(tif, tile);
+ if (bytecount == 0 || bytecount > (uint64_t)TIFF_INT64_MAX)
+ {
+ TIFFErrorExtR(tif, module,
+ "%" PRIu64 ": Invalid tile byte count, tile %" PRIu32,
+ bytecount, tile);
+ return (0);
+ }
+
+ /* To avoid excessive memory allocations: */
+ /* Byte count should normally not be larger than a number of */
+ /* times the uncompressed size plus some margin */
+ if (bytecount > 1024 * 1024)
+ {
+ /* 10 and 4096 are just values that could be adjusted. */
+ /* Hopefully they are safe enough for all codecs */
+ tmsize_t stripsize = TIFFTileSize(tif);
+ if (stripsize != 0 && (bytecount - 4096) / 10 > (uint64_t)stripsize)
+ {
+ uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096;
+ TIFFErrorExtR(tif, module,
+ "Too large tile byte count %" PRIu64
+ ", tile %" PRIu32 ". Limiting to %" PRIu64,
+ bytecount, tile, newbytecount);
+ bytecount = newbytecount;
+ }
+ }
+
+ if (isMapped(tif))
+ {
+ /*
+ * We must check for overflow, potentially causing
+ * an OOB read. Instead of simple
+ *
+ * TIFFGetStrileOffset(tif, tile)+bytecount > tif->tif_size
+ *
+ * comparison (which can overflow) we do the following
+ * two comparisons:
+ */
+ if (bytecount > (uint64_t)tif->tif_size ||
+ TIFFGetStrileOffset(tif, tile) >
+ (uint64_t)tif->tif_size - bytecount)
+ {
+ tif->tif_curtile = NOTILE;
+ return (0);
+ }
+ }
+
+ if (isMapped(tif) && (isFillOrder(tif, td->td_fillorder) ||
+ (tif->tif_flags & TIFF_NOBITREV)))
+ {
+ /*
+ * The image is mapped into memory and we either don't
+ * need to flip bits or the compression routine is
+ * going to handle this operation itself. In this
+ * case, avoid copying the raw data and instead just
+ * reference the data from the memory mapped file
+ * image. This assumes that the decompression
+ * routines do not modify the contents of the raw data
+ * buffer (if they try to, the application will get a
+ * fault since the file is mapped read-only).
+ */
+ if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
+ {
+ _TIFFfreeExt(tif, tif->tif_rawdata);
+ tif->tif_rawdata = NULL;
+ tif->tif_rawdatasize = 0;
+ }
+ tif->tif_flags &= ~TIFF_MYBUFFER;
+
+ tif->tif_rawdatasize = (tmsize_t)bytecount;
+ tif->tif_rawdata =
+ tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, tile);
+ tif->tif_rawdataoff = 0;
+ tif->tif_rawdataloaded = (tmsize_t)bytecount;
+ tif->tif_flags |= TIFF_BUFFERMMAP;
+ }
+ else
+ {
+ /*
+ * Expand raw data buffer, if needed, to hold data
+ * tile coming from file (perhaps should set upper
+ * bound on the size of a buffer we'll use?).
+ */
+ tmsize_t bytecountm;
+ bytecountm = (tmsize_t)bytecount;
+ if ((uint64_t)bytecountm != bytecount)
+ {
+ TIFFErrorExtR(tif, module, "Integer overflow");
+ return (0);
+ }
+ if (bytecountm > tif->tif_rawdatasize)
+ {
+ tif->tif_curtile = NOTILE;
+ if ((tif->tif_flags & TIFF_MYBUFFER) == 0)
+ {
+ TIFFErrorExtR(tif, module,
+ "Data buffer too small to hold tile %" PRIu32,
+ tile);
+ return (0);
+ }
+ }
+ if (tif->tif_flags & TIFF_BUFFERMMAP)
+ {
+ tif->tif_curtile = NOTILE;
+ tif->tif_rawdata = NULL;
+ tif->tif_rawdatasize = 0;
+ tif->tif_flags &= ~TIFF_BUFFERMMAP;
+ }
+
+ if (isMapped(tif))
+ {
+ if (bytecountm > tif->tif_rawdatasize &&
+ !TIFFReadBufferSetup(tif, 0, bytecountm))
+ {
+ return (0);
+ }
+ if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata, bytecountm,
+ module) != bytecountm)
+ {
+ return (0);
+ }
+ }
+ else
+ {
+ if (TIFFReadRawStripOrTile2(tif, tile, 0, bytecountm, module) !=
+ bytecountm)
+ {
+ return (0);
+ }
+ }
+
+ tif->tif_rawdataoff = 0;
+ tif->tif_rawdataloaded = bytecountm;
+
+ if (tif->tif_rawdata != NULL &&
+ !isFillOrder(tif, td->td_fillorder) &&
+ (tif->tif_flags & TIFF_NOBITREV) == 0)
+ TIFFReverseBits(tif->tif_rawdata, tif->tif_rawdataloaded);
+ }
+ }
+ return (TIFFStartTile(tif, tile));
+}
+
+/*
+ * Setup the raw data buffer in preparation for
+ * reading a strip of raw data. If the buffer
+ * is specified as zero, then a buffer of appropriate
+ * size is allocated by the library. Otherwise,
+ * the client must guarantee that the buffer is
+ * large enough to hold any individual strip of
+ * raw data.
+ */
+int TIFFReadBufferSetup(TIFF *tif, void *bp, tmsize_t size)
+{
+ static const char module[] = "TIFFReadBufferSetup";
+
+ assert((tif->tif_flags & TIFF_NOREADRAW) == 0);
+ tif->tif_flags &= ~TIFF_BUFFERMMAP;
+
+ if (tif->tif_rawdata)
+ {
+ if (tif->tif_flags & TIFF_MYBUFFER)
+ _TIFFfreeExt(tif, tif->tif_rawdata);
+ tif->tif_rawdata = NULL;
+ tif->tif_rawdatasize = 0;
+ }
+ if (bp)
+ {
+ tif->tif_rawdatasize = size;
+ tif->tif_rawdata = (uint8_t *)bp;
+ tif->tif_flags &= ~TIFF_MYBUFFER;
+ }
+ else
+ {
+ tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64((uint64_t)size, 1024);
+ if (tif->tif_rawdatasize == 0)
+ {
+ TIFFErrorExtR(tif, module, "Invalid buffer size");
+ return (0);
+ }
+ /* Initialize to zero to avoid uninitialized buffers in case of */
+ /* short reads (http://bugzilla.maptools.org/show_bug.cgi?id=2651) */
+ tif->tif_rawdata =
+ (uint8_t *)_TIFFcallocExt(tif, 1, tif->tif_rawdatasize);
+ tif->tif_flags |= TIFF_MYBUFFER;
+ }
+ if (tif->tif_rawdata == NULL)
+ {
+ TIFFErrorExtR(tif, module,
+ "No space for data buffer at scanline %" PRIu32,
+ tif->tif_row);
+ tif->tif_rawdatasize = 0;
+ return (0);
+ }
+ return (1);
+}
+
+/*
+ * Set state to appear as if a
+ * strip has just been read in.
+ */
+static int TIFFStartStrip(TIFF *tif, uint32_t strip)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+
+ if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
+ {
+ if (!(*tif->tif_setupdecode)(tif))
+ return (0);
+ tif->tif_flags |= TIFF_CODERSETUP;
+ }
+ tif->tif_curstrip = strip;
+ tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
+ tif->tif_flags &= ~TIFF_BUF4WRITE;
+
+ if (tif->tif_flags & TIFF_NOREADRAW)
+ {
+ tif->tif_rawcp = NULL;
+ tif->tif_rawcc = 0;
+ }
+ else
+ {
+ tif->tif_rawcp = tif->tif_rawdata;
+ if (tif->tif_rawdataloaded > 0)
+ tif->tif_rawcc = tif->tif_rawdataloaded;
+ else
+ tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, strip);
+ }
+ if ((*tif->tif_predecode)(tif, (uint16_t)(strip / td->td_stripsperimage)) ==
+ 0)
+ {
+ /* Needed for example for scanline access, if tif_predecode */
+ /* fails, and we try to read the same strip again. Without invalidating
+ */
+ /* tif_curstrip, we'd call tif_decoderow() on a possibly invalid */
+ /* codec state. */
+ tif->tif_curstrip = NOSTRIP;
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * Set state to appear as if a
+ * tile has just been read in.
+ */
+static int TIFFStartTile(TIFF *tif, uint32_t tile)
+{
+ static const char module[] = "TIFFStartTile";
+ TIFFDirectory *td = &tif->tif_dir;
+ uint32_t howmany32;
+
+ if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
+ {
+ if (!(*tif->tif_setupdecode)(tif))
+ return (0);
+ tif->tif_flags |= TIFF_CODERSETUP;
+ }
+ tif->tif_curtile = tile;
+ howmany32 = TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth);
+ if (howmany32 == 0)
+ {
+ TIFFErrorExtR(tif, module, "Zero tiles");
+ return 0;
+ }
+ tif->tif_row = (tile % howmany32) * td->td_tilelength;
+ howmany32 = TIFFhowmany_32(td->td_imagelength, td->td_tilelength);
+ if (howmany32 == 0)
+ {
+ TIFFErrorExtR(tif, module, "Zero tiles");
+ return 0;
+ }
+ tif->tif_col = (tile % howmany32) * td->td_tilewidth;
+ tif->tif_flags &= ~TIFF_BUF4WRITE;
+ if (tif->tif_flags & TIFF_NOREADRAW)
+ {
+ tif->tif_rawcp = NULL;
+ tif->tif_rawcc = 0;
+ }
+ else
+ {
+ tif->tif_rawcp = tif->tif_rawdata;
+ if (tif->tif_rawdataloaded > 0)
+ tif->tif_rawcc = tif->tif_rawdataloaded;
+ else
+ tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, tile);
+ }
+ return (
+ (*tif->tif_predecode)(tif, (uint16_t)(tile / td->td_stripsperimage)));
+}
+
+static int TIFFCheckRead(TIFF *tif, int tiles)
+{
+ if (tif->tif_mode == O_WRONLY)
+ {
+ TIFFErrorExtR(tif, tif->tif_name, "File not open for reading");
+ return (0);
+ }
+ if (tiles ^ isTiled(tif))
+ {
+ TIFFErrorExtR(tif, tif->tif_name,
+ tiles ? "Can not read tiles from a striped image"
+ : "Can not read scanlines from a tiled image");
+ return (0);
+ }
+ return (1);
+}
+
+/* Use the provided input buffer (inbuf, insize) and decompress it into
+ * (outbuf, outsize).
+ * This function replaces the use of
+ * TIFFReadEncodedStrip()/TIFFReadEncodedTile() when the user can provide the
+ * buffer for the input data, for example when he wants to avoid libtiff to read
+ * the strile offset/count values from the [Strip|Tile][Offsets/ByteCounts]
+ * array. inbuf content must be writable (if bit reversal is needed) Returns 1
+ * in case of success, 0 otherwise.
+ */
+int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf,
+ tmsize_t insize, void *outbuf, tmsize_t outsize)
+{
+ static const char module[] = "TIFFReadFromUserBuffer";
+ TIFFDirectory *td = &tif->tif_dir;
+ int ret = 1;
+ uint32_t old_tif_flags = tif->tif_flags;
+ tmsize_t old_rawdatasize = tif->tif_rawdatasize;
+ void *old_rawdata = tif->tif_rawdata;
+
+ if (tif->tif_mode == O_WRONLY)
+ {
+ TIFFErrorExtR(tif, tif->tif_name, "File not open for reading");
+ return 0;
+ }
+ if (tif->tif_flags & TIFF_NOREADRAW)
+ {
+ TIFFErrorExtR(tif, module,
+ "Compression scheme does not support access to raw "
+ "uncompressed data");
+ return 0;
+ }
+
+ tif->tif_flags &= ~TIFF_MYBUFFER;
+ tif->tif_flags |= TIFF_BUFFERMMAP;
+ tif->tif_rawdatasize = insize;
+ tif->tif_rawdata = inbuf;
+ tif->tif_rawdataoff = 0;
+ tif->tif_rawdataloaded = insize;
+
+ if (!isFillOrder(tif, td->td_fillorder) &&
+ (tif->tif_flags & TIFF_NOBITREV) == 0)
+ {
+ TIFFReverseBits(inbuf, insize);
+ }
+
+ if (TIFFIsTiled(tif))
+ {
+ if (!TIFFStartTile(tif, strile) ||
+ !(*tif->tif_decodetile)(tif, (uint8_t *)outbuf, outsize,
+ (uint16_t)(strile / td->td_stripsperimage)))
+ {
+ ret = 0;
+ }
+ }
+ else
+ {
+ uint32_t rowsperstrip = td->td_rowsperstrip;
+ uint32_t stripsperplane;
+ if (rowsperstrip > td->td_imagelength)
+ rowsperstrip = td->td_imagelength;
+ stripsperplane =
+ TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip);
+ if (!TIFFStartStrip(tif, strile) ||
+ !(*tif->tif_decodestrip)(tif, (uint8_t *)outbuf, outsize,
+ (uint16_t)(strile / stripsperplane)))
+ {
+ ret = 0;
+ }
+ }
+ if (ret)
+ {
+ (*tif->tif_postdecode)(tif, (uint8_t *)outbuf, outsize);
+ }
+
+ if (!isFillOrder(tif, td->td_fillorder) &&
+ (tif->tif_flags & TIFF_NOBITREV) == 0)
+ {
+ TIFFReverseBits(inbuf, insize);
+ }
+
+ tif->tif_flags = (old_tif_flags & (TIFF_MYBUFFER | TIFF_BUFFERMMAP)) |
+ (tif->tif_flags & ~(TIFF_MYBUFFER | TIFF_BUFFERMMAP));
+ tif->tif_rawdatasize = old_rawdatasize;
+ tif->tif_rawdata = old_rawdata;
+ tif->tif_rawdataoff = 0;
+ tif->tif_rawdataloaded = 0;
+
+ return ret;
+}
+
+void _TIFFNoPostDecode(TIFF *tif, uint8_t *buf, tmsize_t cc)
+{
+ (void)tif;
+ (void)buf;
+ (void)cc;
+}
+
+void _TIFFSwab16BitData(TIFF *tif, uint8_t *buf, tmsize_t cc)
+{
+ (void)tif;
+ assert((cc & 1) == 0);
+ TIFFSwabArrayOfShort((uint16_t *)buf, cc / 2);
+}
+
+void _TIFFSwab24BitData(TIFF *tif, uint8_t *buf, tmsize_t cc)
+{
+ (void)tif;
+ assert((cc % 3) == 0);
+ TIFFSwabArrayOfTriples((uint8_t *)buf, cc / 3);
+}
+
+void _TIFFSwab32BitData(TIFF *tif, uint8_t *buf, tmsize_t cc)
+{
+ (void)tif;
+ assert((cc & 3) == 0);
+ TIFFSwabArrayOfLong((uint32_t *)buf, cc / 4);
+}
+
+void _TIFFSwab64BitData(TIFF *tif, uint8_t *buf, tmsize_t cc)
+{
+ (void)tif;
+ assert((cc & 7) == 0);
+ TIFFSwabArrayOfDouble((double *)buf, cc / 8);
+}
diff --git a/contrib/libs/libtiff/tif_stream.cxx b/contrib/libs/libtiff/tif_stream.cxx
new file mode 100644
index 0000000000..92ea273c56
--- /dev/null
+++ b/contrib/libs/libtiff/tif_stream.cxx
@@ -0,0 +1,404 @@
+/*
+ * Copyright (c) 1988-1996 Sam Leffler
+ * Copyright (c) 1991-1996 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library UNIX-specific Routines.
+ */
+#include "tiffiop.h"
+#include <iostream>
+
+using namespace std;
+
+/*
+ ISO C++ uses a 'std::streamsize' type to define counts. This makes
+ it similar to, (but perhaps not the same as) size_t.
+
+ The std::ios::pos_type is used to represent stream positions as used
+ by tellg(), tellp(), seekg(), and seekp(). This makes it similar to
+ (but perhaps not the same as) 'off_t'. The std::ios::streampos type
+ is used for character streams, but is documented to not be an
+ integral type anymore, so it should *not* be assigned to an integral
+ type.
+
+ The std::ios::off_type is used to specify relative offsets needed by
+ the variants of seekg() and seekp() which accept a relative offset
+ argument.
+
+ Useful prototype knowledge:
+
+ Obtain read position
+ ios::pos_type basic_istream::tellg()
+
+ Set read position
+ basic_istream& basic_istream::seekg(ios::pos_type)
+ basic_istream& basic_istream::seekg(ios::off_type, ios_base::seekdir)
+
+ Read data
+ basic_istream& istream::read(char *str, streamsize count)
+
+ Number of characters read in last unformatted read
+ streamsize istream::gcount();
+
+ Obtain write position
+ ios::pos_type basic_ostream::tellp()
+
+ Set write position
+ basic_ostream& basic_ostream::seekp(ios::pos_type)
+ basic_ostream& basic_ostream::seekp(ios::off_type, ios_base::seekdir)
+
+ Write data
+ basic_ostream& ostream::write(const char *str, streamsize count)
+*/
+
+struct tiffis_data;
+struct tiffos_data;
+
+extern "C"
+{
+
+ static tmsize_t _tiffosReadProc(thandle_t, void *, tmsize_t);
+ static tmsize_t _tiffisReadProc(thandle_t fd, void *buf, tmsize_t size);
+ static tmsize_t _tiffosWriteProc(thandle_t fd, void *buf, tmsize_t size);
+ static tmsize_t _tiffisWriteProc(thandle_t, void *, tmsize_t);
+ static uint64_t _tiffosSeekProc(thandle_t fd, uint64_t off, int whence);
+ static uint64_t _tiffisSeekProc(thandle_t fd, uint64_t off, int whence);
+ static uint64_t _tiffosSizeProc(thandle_t fd);
+ static uint64_t _tiffisSizeProc(thandle_t fd);
+ static int _tiffosCloseProc(thandle_t fd);
+ static int _tiffisCloseProc(thandle_t fd);
+ static int _tiffDummyMapProc(thandle_t, void **base, toff_t *size);
+ static void _tiffDummyUnmapProc(thandle_t, void *base, toff_t size);
+ static TIFF *_tiffStreamOpen(const char *name, const char *mode, void *fd);
+
+ struct tiffis_data
+ {
+ istream *stream;
+ ios::pos_type start_pos;
+ };
+
+ struct tiffos_data
+ {
+ ostream *stream;
+ ios::pos_type start_pos;
+ };
+
+ static tmsize_t _tiffosReadProc(thandle_t, void *, tmsize_t) { return 0; }
+
+ static tmsize_t _tiffisReadProc(thandle_t fd, void *buf, tmsize_t size)
+ {
+ tiffis_data *data = reinterpret_cast<tiffis_data *>(fd);
+
+ // Verify that type does not overflow.
+ streamsize request_size = size;
+ if (static_cast<tmsize_t>(request_size) != size)
+ return static_cast<tmsize_t>(-1);
+
+ data->stream->read((char *)buf, request_size);
+
+ return static_cast<tmsize_t>(data->stream->gcount());
+ }
+
+ static tmsize_t _tiffosWriteProc(thandle_t fd, void *buf, tmsize_t size)
+ {
+ tiffos_data *data = reinterpret_cast<tiffos_data *>(fd);
+ ostream *os = data->stream;
+ ios::pos_type pos = os->tellp();
+
+ // Verify that type does not overflow.
+ streamsize request_size = size;
+ if (static_cast<tmsize_t>(request_size) != size)
+ return static_cast<tmsize_t>(-1);
+
+ os->write(reinterpret_cast<const char *>(buf), request_size);
+
+ return static_cast<tmsize_t>(os->tellp() - pos);
+ }
+
+ static tmsize_t _tiffisWriteProc(thandle_t, void *, tmsize_t) { return 0; }
+
+ static uint64_t _tiffosSeekProc(thandle_t fd, uint64_t off, int whence)
+ {
+ tiffos_data *data = reinterpret_cast<tiffos_data *>(fd);
+ ostream *os = data->stream;
+
+ // if the stream has already failed, don't do anything
+ if (os->fail())
+ return static_cast<uint64_t>(-1);
+
+ switch (whence)
+ {
+ case SEEK_SET:
+ {
+ // Compute 64-bit offset
+ uint64_t new_offset =
+ static_cast<uint64_t>(data->start_pos) + off;
+
+ // Verify that value does not overflow
+ ios::off_type offset = static_cast<ios::off_type>(new_offset);
+ if (static_cast<uint64_t>(offset) != new_offset)
+ return static_cast<uint64_t>(-1);
+
+ os->seekp(offset, ios::beg);
+ break;
+ }
+ case SEEK_CUR:
+ {
+ // Verify that value does not overflow
+ ios::off_type offset = static_cast<ios::off_type>(off);
+ if (static_cast<uint64_t>(offset) != off)
+ return static_cast<uint64_t>(-1);
+
+ os->seekp(offset, ios::cur);
+ break;
+ }
+ case SEEK_END:
+ {
+ // Verify that value does not overflow
+ ios::off_type offset = static_cast<ios::off_type>(off);
+ if (static_cast<uint64_t>(offset) != off)
+ return static_cast<uint64_t>(-1);
+
+ os->seekp(offset, ios::end);
+ break;
+ }
+ }
+
+ // Attempt to workaround problems with seeking past the end of the
+ // stream. ofstream doesn't have a problem with this but
+ // ostrstream/ostringstream does. In that situation, add intermediate
+ // '\0' characters.
+ if (os->fail())
+ {
+ ios::iostate old_state;
+ ios::pos_type origin;
+
+ old_state = os->rdstate();
+ // reset the fail bit or else tellp() won't work below
+ os->clear(os->rdstate() & ~ios::failbit);
+ switch (whence)
+ {
+ case SEEK_SET:
+ default:
+ origin = data->start_pos;
+ break;
+ case SEEK_CUR:
+ origin = os->tellp();
+ break;
+ case SEEK_END:
+ os->seekp(0, ios::end);
+ origin = os->tellp();
+ break;
+ }
+ // restore original stream state
+ os->clear(old_state);
+
+ // only do something if desired seek position is valid
+ if ((static_cast<uint64_t>(origin) + off) >
+ static_cast<uint64_t>(data->start_pos))
+ {
+ uint64_t num_fill;
+
+ // clear the fail bit
+ os->clear(os->rdstate() & ~ios::failbit);
+
+ // extend the stream to the expected size
+ os->seekp(0, ios::end);
+ num_fill = (static_cast<uint64_t>(origin)) + off - os->tellp();
+ for (uint64_t i = 0; i < num_fill; i++)
+ os->put('\0');
+
+ // retry the seek
+ os->seekp(static_cast<ios::off_type>(
+ static_cast<uint64_t>(origin) + off),
+ ios::beg);
+ }
+ }
+
+ return static_cast<uint64_t>(os->tellp());
+ }
+
+ static uint64_t _tiffisSeekProc(thandle_t fd, uint64_t off, int whence)
+ {
+ tiffis_data *data = reinterpret_cast<tiffis_data *>(fd);
+
+ switch (whence)
+ {
+ case SEEK_SET:
+ {
+ // Compute 64-bit offset
+ uint64_t new_offset =
+ static_cast<uint64_t>(data->start_pos) + off;
+
+ // Verify that value does not overflow
+ ios::off_type offset = static_cast<ios::off_type>(new_offset);
+ if (static_cast<uint64_t>(offset) != new_offset)
+ return static_cast<uint64_t>(-1);
+
+ data->stream->seekg(offset, ios::beg);
+ break;
+ }
+ case SEEK_CUR:
+ {
+ // Verify that value does not overflow
+ ios::off_type offset = static_cast<ios::off_type>(off);
+ if (static_cast<uint64_t>(offset) != off)
+ return static_cast<uint64_t>(-1);
+
+ data->stream->seekg(offset, ios::cur);
+ break;
+ }
+ case SEEK_END:
+ {
+ // Verify that value does not overflow
+ ios::off_type offset = static_cast<ios::off_type>(off);
+ if (static_cast<uint64_t>(offset) != off)
+ return static_cast<uint64_t>(-1);
+
+ data->stream->seekg(offset, ios::end);
+ break;
+ }
+ }
+
+ return (uint64_t)(data->stream->tellg() - data->start_pos);
+ }
+
+ static uint64_t _tiffosSizeProc(thandle_t fd)
+ {
+ tiffos_data *data = reinterpret_cast<tiffos_data *>(fd);
+ ostream *os = data->stream;
+ ios::pos_type pos = os->tellp();
+ ios::pos_type len;
+
+ os->seekp(0, ios::end);
+ len = os->tellp();
+ os->seekp(pos);
+
+ return (uint64_t)len;
+ }
+
+ static uint64_t _tiffisSizeProc(thandle_t fd)
+ {
+ tiffis_data *data = reinterpret_cast<tiffis_data *>(fd);
+ ios::pos_type pos = data->stream->tellg();
+ ios::pos_type len;
+
+ data->stream->seekg(0, ios::end);
+ len = data->stream->tellg();
+ data->stream->seekg(pos);
+
+ return (uint64_t)len;
+ }
+
+ static int _tiffosCloseProc(thandle_t fd)
+ {
+ // Our stream was not allocated by us, so it shouldn't be closed by us.
+ delete reinterpret_cast<tiffos_data *>(fd);
+ return 0;
+ }
+
+ static int _tiffisCloseProc(thandle_t fd)
+ {
+ // Our stream was not allocated by us, so it shouldn't be closed by us.
+ delete reinterpret_cast<tiffis_data *>(fd);
+ return 0;
+ }
+
+ static int _tiffDummyMapProc(thandle_t, void **base, toff_t *size)
+ {
+ (void)base;
+ (void)size;
+ return (0);
+ }
+
+ static void _tiffDummyUnmapProc(thandle_t, void *base, toff_t size)
+ {
+ (void)base;
+ (void)size;
+ }
+
+ /*
+ * Open a TIFF file descriptor for read/writing.
+ */
+ static TIFF *_tiffStreamOpen(const char *name, const char *mode, void *fd)
+ {
+ TIFF *tif;
+
+ if (strchr(mode, 'w'))
+ {
+ tiffos_data *data = new tiffos_data;
+ data->stream = reinterpret_cast<ostream *>(fd);
+ data->start_pos = data->stream->tellp();
+
+ // Open for writing.
+ tif = TIFFClientOpen(
+ name, mode, reinterpret_cast<thandle_t>(data), _tiffosReadProc,
+ _tiffosWriteProc, _tiffosSeekProc, _tiffosCloseProc,
+ _tiffosSizeProc, _tiffDummyMapProc, _tiffDummyUnmapProc);
+ if (!tif)
+ {
+ delete data;
+ }
+ }
+ else
+ {
+ tiffis_data *data = new tiffis_data;
+ data->stream = reinterpret_cast<istream *>(fd);
+ data->start_pos = data->stream->tellg();
+ // Open for reading.
+ tif = TIFFClientOpen(
+ name, mode, reinterpret_cast<thandle_t>(data), _tiffisReadProc,
+ _tiffisWriteProc, _tiffisSeekProc, _tiffisCloseProc,
+ _tiffisSizeProc, _tiffDummyMapProc, _tiffDummyUnmapProc);
+ if (!tif)
+ {
+ delete data;
+ }
+ }
+
+ return (tif);
+ }
+
+} /* extern "C" */
+
+TIFF *TIFFStreamOpen(const char *name, ostream *os)
+{
+ // If os is either a ostrstream or ostringstream, and has no data
+ // written to it yet, then tellp() will return -1 which will break us.
+ // We workaround this by writing out a dummy character and
+ // then seek back to the beginning.
+ if (!os->fail() && static_cast<int>(os->tellp()) < 0)
+ {
+ *os << '\0';
+ os->seekp(0);
+ }
+
+ // NB: We don't support mapped files with streams so add 'm'
+ return _tiffStreamOpen(name, "wm", os);
+}
+
+TIFF *TIFFStreamOpen(const char *name, istream *is)
+{
+ // NB: We don't support mapped files with streams so add 'm'
+ return _tiffStreamOpen(name, "rm", is);
+}
diff --git a/contrib/libs/libtiff/tif_strip.c b/contrib/libs/libtiff/tif_strip.c
new file mode 100644
index 0000000000..1348b19e4f
--- /dev/null
+++ b/contrib/libs/libtiff/tif_strip.c
@@ -0,0 +1,350 @@
+/*
+ * Copyright (c) 1991-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Strip-organized Image Support Routines.
+ */
+#include "tiffiop.h"
+
+/*
+ * Compute which strip a (row,sample) value is in.
+ */
+uint32_t TIFFComputeStrip(TIFF *tif, uint32_t row, uint16_t sample)
+{
+ static const char module[] = "TIFFComputeStrip";
+ TIFFDirectory *td = &tif->tif_dir;
+ uint32_t strip;
+
+ strip = row / td->td_rowsperstrip;
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
+ {
+ if (sample >= td->td_samplesperpixel)
+ {
+ TIFFErrorExtR(tif, module, "%lu: Sample out of range, max %lu",
+ (unsigned long)sample,
+ (unsigned long)td->td_samplesperpixel);
+ return (0);
+ }
+ strip += (uint32_t)sample * td->td_stripsperimage;
+ }
+ return (strip);
+}
+
+/*
+ * Compute how many strips are in an image.
+ */
+uint32_t TIFFNumberOfStrips(TIFF *tif)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ uint32_t nstrips;
+
+ nstrips = (td->td_rowsperstrip == (uint32_t)-1
+ ? 1
+ : TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip));
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
+ nstrips =
+ _TIFFMultiply32(tif, nstrips, (uint32_t)td->td_samplesperpixel,
+ "TIFFNumberOfStrips");
+ return (nstrips);
+}
+
+/*
+ * Compute the # bytes in a variable height, row-aligned strip.
+ */
+uint64_t TIFFVStripSize64(TIFF *tif, uint32_t nrows)
+{
+ static const char module[] = "TIFFVStripSize64";
+ TIFFDirectory *td = &tif->tif_dir;
+ if (nrows == (uint32_t)(-1))
+ nrows = td->td_imagelength;
+ if ((td->td_planarconfig == PLANARCONFIG_CONTIG) &&
+ (td->td_photometric == PHOTOMETRIC_YCBCR) && (!isUpSampled(tif)))
+ {
+ /*
+ * Packed YCbCr data contain one Cb+Cr for every
+ * HorizontalSampling*VerticalSampling Y values.
+ * Must also roundup width and height when calculating
+ * since images that are not a multiple of the
+ * horizontal/vertical subsampling area include
+ * YCbCr data for the extended image.
+ */
+ uint16_t ycbcrsubsampling[2];
+ uint16_t samplingblock_samples;
+ uint32_t samplingblocks_hor;
+ uint32_t samplingblocks_ver;
+ uint64_t samplingrow_samples;
+ uint64_t samplingrow_size;
+ if (td->td_samplesperpixel != 3)
+ {
+ TIFFErrorExtR(tif, module, "Invalid td_samplesperpixel value");
+ return 0;
+ }
+ TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
+ ycbcrsubsampling + 0, ycbcrsubsampling + 1);
+ if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 &&
+ ycbcrsubsampling[0] != 4) ||
+ (ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 &&
+ ycbcrsubsampling[1] != 4))
+ {
+ TIFFErrorExtR(tif, module, "Invalid YCbCr subsampling (%dx%d)",
+ ycbcrsubsampling[0], ycbcrsubsampling[1]);
+ return 0;
+ }
+ samplingblock_samples = ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2;
+ samplingblocks_hor =
+ TIFFhowmany_32(td->td_imagewidth, ycbcrsubsampling[0]);
+ samplingblocks_ver = TIFFhowmany_32(nrows, ycbcrsubsampling[1]);
+ samplingrow_samples = _TIFFMultiply64(tif, samplingblocks_hor,
+ samplingblock_samples, module);
+ samplingrow_size = TIFFhowmany8_64(_TIFFMultiply64(
+ tif, samplingrow_samples, td->td_bitspersample, module));
+ return (
+ _TIFFMultiply64(tif, samplingrow_size, samplingblocks_ver, module));
+ }
+ else
+ return (_TIFFMultiply64(tif, nrows, TIFFScanlineSize64(tif), module));
+}
+tmsize_t TIFFVStripSize(TIFF *tif, uint32_t nrows)
+{
+ static const char module[] = "TIFFVStripSize";
+ uint64_t m;
+ m = TIFFVStripSize64(tif, nrows);
+ return _TIFFCastUInt64ToSSize(tif, m, module);
+}
+
+/*
+ * Compute the # bytes in a raw strip.
+ */
+uint64_t TIFFRawStripSize64(TIFF *tif, uint32_t strip)
+{
+ static const char module[] = "TIFFRawStripSize64";
+ uint64_t bytecount = TIFFGetStrileByteCount(tif, strip);
+
+ if (bytecount == 0)
+ {
+ TIFFErrorExtR(tif, module,
+ "%" PRIu64 ": Invalid strip byte count, strip %lu",
+ (uint64_t)bytecount, (unsigned long)strip);
+ bytecount = (uint64_t)-1;
+ }
+
+ return bytecount;
+}
+tmsize_t TIFFRawStripSize(TIFF *tif, uint32_t strip)
+{
+ static const char module[] = "TIFFRawStripSize";
+ uint64_t m;
+ tmsize_t n;
+ m = TIFFRawStripSize64(tif, strip);
+ if (m == (uint64_t)(-1))
+ n = (tmsize_t)(-1);
+ else
+ {
+ n = (tmsize_t)m;
+ if ((uint64_t)n != m)
+ {
+ TIFFErrorExtR(tif, module, "Integer overflow");
+ n = 0;
+ }
+ }
+ return (n);
+}
+
+/*
+ * Compute the # bytes in a (row-aligned) strip.
+ *
+ * Note that if RowsPerStrip is larger than the
+ * recorded ImageLength, then the strip size is
+ * truncated to reflect the actual space required
+ * to hold the strip.
+ */
+uint64_t TIFFStripSize64(TIFF *tif)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ uint32_t rps = td->td_rowsperstrip;
+ if (rps > td->td_imagelength)
+ rps = td->td_imagelength;
+ return (TIFFVStripSize64(tif, rps));
+}
+tmsize_t TIFFStripSize(TIFF *tif)
+{
+ static const char module[] = "TIFFStripSize";
+ uint64_t m;
+ m = TIFFStripSize64(tif);
+ return _TIFFCastUInt64ToSSize(tif, m, module);
+}
+
+/*
+ * Compute a default strip size based on the image
+ * characteristics and a requested value. If the
+ * request is <1 then we choose a strip size according
+ * to certain heuristics.
+ */
+uint32_t TIFFDefaultStripSize(TIFF *tif, uint32_t request)
+{
+ return (*tif->tif_defstripsize)(tif, request);
+}
+
+uint32_t _TIFFDefaultStripSize(TIFF *tif, uint32_t s)
+{
+ if ((int32_t)s < 1)
+ {
+ /*
+ * If RowsPerStrip is unspecified, try to break the
+ * image up into strips that are approximately
+ * STRIP_SIZE_DEFAULT bytes long.
+ */
+ uint64_t scanlinesize;
+ uint64_t rows;
+ scanlinesize = TIFFScanlineSize64(tif);
+ if (scanlinesize == 0)
+ scanlinesize = 1;
+ rows = (uint64_t)STRIP_SIZE_DEFAULT / scanlinesize;
+ if (rows == 0)
+ rows = 1;
+ else if (rows > 0xFFFFFFFF)
+ rows = 0xFFFFFFFF;
+ s = (uint32_t)rows;
+ }
+ return (s);
+}
+
+/*
+ * Return the number of bytes to read/write in a call to
+ * one of the scanline-oriented i/o routines. Note that
+ * this number may be 1/samples-per-pixel if data is
+ * stored as separate planes.
+ * The ScanlineSize in case of YCbCrSubsampling is defined as the
+ * strip size divided by the strip height, i.e. the size of a pack of vertical
+ * subsampling lines divided by vertical subsampling. It should thus make
+ * sense when multiplied by a multiple of vertical subsampling.
+ */
+uint64_t TIFFScanlineSize64(TIFF *tif)
+{
+ static const char module[] = "TIFFScanlineSize64";
+ TIFFDirectory *td = &tif->tif_dir;
+ uint64_t scanline_size;
+ if (td->td_planarconfig == PLANARCONFIG_CONTIG)
+ {
+ if ((td->td_photometric == PHOTOMETRIC_YCBCR) &&
+ (td->td_samplesperpixel == 3) && (!isUpSampled(tif)))
+ {
+ uint16_t ycbcrsubsampling[2];
+ uint16_t samplingblock_samples;
+ uint32_t samplingblocks_hor;
+ uint64_t samplingrow_samples;
+ uint64_t samplingrow_size;
+ if (td->td_samplesperpixel != 3)
+ {
+ TIFFErrorExtR(tif, module, "Invalid td_samplesperpixel value");
+ return 0;
+ }
+ TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
+ ycbcrsubsampling + 0, ycbcrsubsampling + 1);
+ if (((ycbcrsubsampling[0] != 1) && (ycbcrsubsampling[0] != 2) &&
+ (ycbcrsubsampling[0] != 4)) ||
+ ((ycbcrsubsampling[1] != 1) && (ycbcrsubsampling[1] != 2) &&
+ (ycbcrsubsampling[1] != 4)))
+ {
+ TIFFErrorExtR(tif, module, "Invalid YCbCr subsampling");
+ return 0;
+ }
+ samplingblock_samples =
+ ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2;
+ samplingblocks_hor =
+ TIFFhowmany_32(td->td_imagewidth, ycbcrsubsampling[0]);
+ samplingrow_samples = _TIFFMultiply64(
+ tif, samplingblocks_hor, samplingblock_samples, module);
+ samplingrow_size =
+ TIFFhowmany_64(_TIFFMultiply64(tif, samplingrow_samples,
+ td->td_bitspersample, module),
+ 8);
+ scanline_size = (samplingrow_size / ycbcrsubsampling[1]);
+ }
+ else
+ {
+ uint64_t scanline_samples;
+ scanline_samples = _TIFFMultiply64(tif, td->td_imagewidth,
+ td->td_samplesperpixel, module);
+ scanline_size =
+ TIFFhowmany_64(_TIFFMultiply64(tif, scanline_samples,
+ td->td_bitspersample, module),
+ 8);
+ }
+ }
+ else
+ {
+ scanline_size =
+ TIFFhowmany_64(_TIFFMultiply64(tif, td->td_imagewidth,
+ td->td_bitspersample, module),
+ 8);
+ }
+ if (scanline_size == 0)
+ {
+ TIFFWarningExtR(tif, module, "Computed scanline size is zero");
+ return 0;
+ }
+ return (scanline_size);
+}
+tmsize_t TIFFScanlineSize(TIFF *tif)
+{
+ static const char module[] = "TIFFScanlineSize";
+ uint64_t m;
+ m = TIFFScanlineSize64(tif);
+ return _TIFFCastUInt64ToSSize(tif, m, module);
+}
+
+/*
+ * Return the number of bytes required to store a complete
+ * decoded and packed raster scanline (as opposed to the
+ * I/O size returned by TIFFScanlineSize which may be less
+ * if data is store as separate planes).
+ */
+uint64_t TIFFRasterScanlineSize64(TIFF *tif)
+{
+ static const char module[] = "TIFFRasterScanlineSize64";
+ TIFFDirectory *td = &tif->tif_dir;
+ uint64_t scanline;
+
+ scanline =
+ _TIFFMultiply64(tif, td->td_bitspersample, td->td_imagewidth, module);
+ if (td->td_planarconfig == PLANARCONFIG_CONTIG)
+ {
+ scanline =
+ _TIFFMultiply64(tif, scanline, td->td_samplesperpixel, module);
+ return (TIFFhowmany8_64(scanline));
+ }
+ else
+ return (_TIFFMultiply64(tif, TIFFhowmany8_64(scanline),
+ td->td_samplesperpixel, module));
+}
+tmsize_t TIFFRasterScanlineSize(TIFF *tif)
+{
+ static const char module[] = "TIFFRasterScanlineSize";
+ uint64_t m;
+ m = TIFFRasterScanlineSize64(tif);
+ return _TIFFCastUInt64ToSSize(tif, m, module);
+}
diff --git a/contrib/libs/libtiff/tif_swab.c b/contrib/libs/libtiff/tif_swab.c
new file mode 100644
index 0000000000..827b025ce7
--- /dev/null
+++ b/contrib/libs/libtiff/tif_swab.c
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library Bit & Byte Swapping Support.
+ *
+ * XXX We assume short = 16-bits and long = 32-bits XXX
+ */
+#include "tiffiop.h"
+
+#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabShort)
+void TIFFSwabShort(uint16_t *wp)
+{
+ register unsigned char *cp = (unsigned char *)wp;
+ unsigned char t;
+ assert(sizeof(uint16_t) == 2);
+ t = cp[1];
+ cp[1] = cp[0];
+ cp[0] = t;
+}
+#endif
+
+#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabLong)
+void TIFFSwabLong(uint32_t *lp)
+{
+ register unsigned char *cp = (unsigned char *)lp;
+ unsigned char t;
+ assert(sizeof(uint32_t) == 4);
+ t = cp[3];
+ cp[3] = cp[0];
+ cp[0] = t;
+ t = cp[2];
+ cp[2] = cp[1];
+ cp[1] = t;
+}
+#endif
+
+#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabLong8)
+void TIFFSwabLong8(uint64_t *lp)
+{
+ register unsigned char *cp = (unsigned char *)lp;
+ unsigned char t;
+ assert(sizeof(uint64_t) == 8);
+ t = cp[7];
+ cp[7] = cp[0];
+ cp[0] = t;
+ t = cp[6];
+ cp[6] = cp[1];
+ cp[1] = t;
+ t = cp[5];
+ cp[5] = cp[2];
+ cp[2] = t;
+ t = cp[4];
+ cp[4] = cp[3];
+ cp[3] = t;
+}
+#endif
+
+#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfShort)
+void TIFFSwabArrayOfShort(register uint16_t *wp, tmsize_t n)
+{
+ register unsigned char *cp;
+ register unsigned char t;
+ assert(sizeof(uint16_t) == 2);
+ /* XXX unroll loop some */
+ while (n-- > 0)
+ {
+ cp = (unsigned char *)wp;
+ t = cp[1];
+ cp[1] = cp[0];
+ cp[0] = t;
+ wp++;
+ }
+}
+#endif
+
+#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfTriples)
+void TIFFSwabArrayOfTriples(register uint8_t *tp, tmsize_t n)
+{
+ unsigned char *cp;
+ unsigned char t;
+
+ /* XXX unroll loop some */
+ while (n-- > 0)
+ {
+ cp = (unsigned char *)tp;
+ t = cp[2];
+ cp[2] = cp[0];
+ cp[0] = t;
+ tp += 3;
+ }
+}
+#endif
+
+#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfLong)
+void TIFFSwabArrayOfLong(register uint32_t *lp, tmsize_t n)
+{
+ register unsigned char *cp;
+ register unsigned char t;
+ assert(sizeof(uint32_t) == 4);
+ /* XXX unroll loop some */
+ while (n-- > 0)
+ {
+ cp = (unsigned char *)lp;
+ t = cp[3];
+ cp[3] = cp[0];
+ cp[0] = t;
+ t = cp[2];
+ cp[2] = cp[1];
+ cp[1] = t;
+ lp++;
+ }
+}
+#endif
+
+#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfLong8)
+void TIFFSwabArrayOfLong8(register uint64_t *lp, tmsize_t n)
+{
+ register unsigned char *cp;
+ register unsigned char t;
+ assert(sizeof(uint64_t) == 8);
+ /* XXX unroll loop some */
+ while (n-- > 0)
+ {
+ cp = (unsigned char *)lp;
+ t = cp[7];
+ cp[7] = cp[0];
+ cp[0] = t;
+ t = cp[6];
+ cp[6] = cp[1];
+ cp[1] = t;
+ t = cp[5];
+ cp[5] = cp[2];
+ cp[2] = t;
+ t = cp[4];
+ cp[4] = cp[3];
+ cp[3] = t;
+ lp++;
+ }
+}
+#endif
+
+#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabFloat)
+void TIFFSwabFloat(float *fp)
+{
+ register unsigned char *cp = (unsigned char *)fp;
+ unsigned char t;
+ assert(sizeof(float) == 4);
+ t = cp[3];
+ cp[3] = cp[0];
+ cp[0] = t;
+ t = cp[2];
+ cp[2] = cp[1];
+ cp[1] = t;
+}
+#endif
+
+#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfFloat)
+void TIFFSwabArrayOfFloat(register float *fp, tmsize_t n)
+{
+ register unsigned char *cp;
+ register unsigned char t;
+ assert(sizeof(float) == 4);
+ /* XXX unroll loop some */
+ while (n-- > 0)
+ {
+ cp = (unsigned char *)fp;
+ t = cp[3];
+ cp[3] = cp[0];
+ cp[0] = t;
+ t = cp[2];
+ cp[2] = cp[1];
+ cp[1] = t;
+ fp++;
+ }
+}
+#endif
+
+#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabDouble)
+void TIFFSwabDouble(double *dp)
+{
+ register unsigned char *cp = (unsigned char *)dp;
+ unsigned char t;
+ assert(sizeof(double) == 8);
+ t = cp[7];
+ cp[7] = cp[0];
+ cp[0] = t;
+ t = cp[6];
+ cp[6] = cp[1];
+ cp[1] = t;
+ t = cp[5];
+ cp[5] = cp[2];
+ cp[2] = t;
+ t = cp[4];
+ cp[4] = cp[3];
+ cp[3] = t;
+}
+#endif
+
+#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfDouble)
+void TIFFSwabArrayOfDouble(double *dp, tmsize_t n)
+{
+ register unsigned char *cp;
+ register unsigned char t;
+ assert(sizeof(double) == 8);
+ /* XXX unroll loop some */
+ while (n-- > 0)
+ {
+ cp = (unsigned char *)dp;
+ t = cp[7];
+ cp[7] = cp[0];
+ cp[0] = t;
+ t = cp[6];
+ cp[6] = cp[1];
+ cp[1] = t;
+ t = cp[5];
+ cp[5] = cp[2];
+ cp[2] = t;
+ t = cp[4];
+ cp[4] = cp[3];
+ cp[3] = t;
+ dp++;
+ }
+}
+#endif
+
+/*
+ * Bit reversal tables. TIFFBitRevTable[<byte>] gives
+ * the bit reversed value of <byte>. Used in various
+ * places in the library when the FillOrder requires
+ * bit reversal of byte values (e.g. CCITT Fax 3
+ * encoding/decoding). TIFFNoBitRevTable is provided
+ * for algorithms that want an equivalent table that
+ * do not reverse bit values.
+ */
+static const unsigned char TIFFBitRevTable[256] = {
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0,
+ 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4,
+ 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc,
+ 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca,
+ 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6,
+ 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1,
+ 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9,
+ 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd,
+ 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3,
+ 0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7,
+ 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf,
+ 0x3f, 0xbf, 0x7f, 0xff};
+static const unsigned char TIFFNoBitRevTable[256] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
+ 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
+ 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53,
+ 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
+ 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
+ 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
+ 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
+ 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb,
+ 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
+ 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
+ 0xfc, 0xfd, 0xfe, 0xff,
+};
+
+const unsigned char *TIFFGetBitRevTable(int reversed)
+{
+ return (reversed ? TIFFBitRevTable : TIFFNoBitRevTable);
+}
+
+void TIFFReverseBits(uint8_t *cp, tmsize_t n)
+{
+ for (; n > 8; n -= 8)
+ {
+ cp[0] = TIFFBitRevTable[cp[0]];
+ cp[1] = TIFFBitRevTable[cp[1]];
+ cp[2] = TIFFBitRevTable[cp[2]];
+ cp[3] = TIFFBitRevTable[cp[3]];
+ cp[4] = TIFFBitRevTable[cp[4]];
+ cp[5] = TIFFBitRevTable[cp[5]];
+ cp[6] = TIFFBitRevTable[cp[6]];
+ cp[7] = TIFFBitRevTable[cp[7]];
+ cp += 8;
+ }
+ while (n-- > 0)
+ {
+ *cp = TIFFBitRevTable[*cp];
+ cp++;
+ }
+}
diff --git a/contrib/libs/libtiff/tif_thunder.c b/contrib/libs/libtiff/tif_thunder.c
new file mode 100644
index 0000000000..1f97362ca3
--- /dev/null
+++ b/contrib/libs/libtiff/tif_thunder.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+#include "tiffiop.h"
+#include <assert.h>
+#ifdef THUNDER_SUPPORT
+/*
+ * TIFF Library.
+ *
+ * ThunderScan 4-bit Compression Algorithm Support
+ */
+
+/*
+ * ThunderScan uses an encoding scheme designed for
+ * 4-bit pixel values. Data is encoded in bytes, with
+ * each byte split into a 2-bit code word and a 6-bit
+ * data value. The encoding gives raw data, runs of
+ * pixels, or pixel values encoded as a delta from the
+ * previous pixel value. For the latter, either 2-bit
+ * or 3-bit delta values are used, with the deltas packed
+ * into a single byte.
+ */
+#define THUNDER_DATA 0x3f /* mask for 6-bit data */
+#define THUNDER_CODE 0xc0 /* mask for 2-bit code word */
+/* code values */
+#define THUNDER_RUN 0x00 /* run of pixels w/ encoded count */
+#define THUNDER_2BITDELTAS 0x40 /* 3 pixels w/ encoded 2-bit deltas */
+#define DELTA2_SKIP 2 /* skip code for 2-bit deltas */
+#define THUNDER_3BITDELTAS 0x80 /* 2 pixels w/ encoded 3-bit deltas */
+#define DELTA3_SKIP 4 /* skip code for 3-bit deltas */
+#define THUNDER_RAW 0xc0 /* raw data encoded */
+
+static const int twobitdeltas[4] = {0, 1, 0, -1};
+static const int threebitdeltas[8] = {0, 1, 2, 3, 0, -3, -2, -1};
+
+#define SETPIXEL(op, v) \
+ { \
+ lastpixel = (v)&0xf; \
+ if (npixels < maxpixels) \
+ { \
+ if (npixels++ & 1) \
+ *op++ |= lastpixel; \
+ else \
+ op[0] = (uint8_t)(lastpixel << 4); \
+ } \
+ }
+
+static int ThunderSetupDecode(TIFF *tif)
+{
+ static const char module[] = "ThunderSetupDecode";
+
+ if (tif->tif_dir.td_bitspersample != 4)
+ {
+ TIFFErrorExtR(tif, module,
+ "Wrong bitspersample value (%d), Thunder decoder only "
+ "supports 4bits per sample.",
+ (int)tif->tif_dir.td_bitspersample);
+ return 0;
+ }
+
+ return (1);
+}
+
+static int ThunderDecode(TIFF *tif, uint8_t *op, tmsize_t maxpixels)
+{
+ static const char module[] = "ThunderDecode";
+ register unsigned char *bp;
+ register tmsize_t cc;
+ unsigned int lastpixel;
+ tmsize_t npixels;
+
+ bp = (unsigned char *)tif->tif_rawcp;
+ cc = tif->tif_rawcc;
+ lastpixel = 0;
+ npixels = 0;
+ while (cc > 0 && npixels < maxpixels)
+ {
+ int n, delta;
+
+ n = *bp++;
+ cc--;
+ switch (n & THUNDER_CODE)
+ {
+ case THUNDER_RUN: /* pixel run */
+ /*
+ * Replicate the last pixel n times,
+ * where n is the lower-order 6 bits.
+ */
+ if (npixels & 1)
+ {
+ op[0] |= lastpixel;
+ lastpixel = *op++;
+ npixels++;
+ n--;
+ }
+ else
+ lastpixel |= lastpixel << 4;
+ npixels += n;
+ if (npixels < maxpixels)
+ {
+ for (; n > 0; n -= 2)
+ *op++ = (uint8_t)lastpixel;
+ }
+ if (n == -1)
+ *--op &= 0xf0;
+ lastpixel &= 0xf;
+ break;
+ case THUNDER_2BITDELTAS: /* 2-bit deltas */
+ if ((delta = ((n >> 4) & 3)) != DELTA2_SKIP)
+ SETPIXEL(op,
+ (unsigned)((int)lastpixel + twobitdeltas[delta]));
+ if ((delta = ((n >> 2) & 3)) != DELTA2_SKIP)
+ SETPIXEL(op,
+ (unsigned)((int)lastpixel + twobitdeltas[delta]));
+ if ((delta = (n & 3)) != DELTA2_SKIP)
+ SETPIXEL(op,
+ (unsigned)((int)lastpixel + twobitdeltas[delta]));
+ break;
+ case THUNDER_3BITDELTAS: /* 3-bit deltas */
+ if ((delta = ((n >> 3) & 7)) != DELTA3_SKIP)
+ SETPIXEL(
+ op, (unsigned)((int)lastpixel + threebitdeltas[delta]));
+ if ((delta = (n & 7)) != DELTA3_SKIP)
+ SETPIXEL(
+ op, (unsigned)((int)lastpixel + threebitdeltas[delta]));
+ break;
+ case THUNDER_RAW: /* raw data */
+ SETPIXEL(op, n);
+ break;
+ }
+ }
+ tif->tif_rawcp = (uint8_t *)bp;
+ tif->tif_rawcc = cc;
+ if (npixels != maxpixels)
+ {
+ TIFFErrorExtR(tif, module,
+ "%s data at scanline %lu (%" PRIu64 " != %" PRIu64 ")",
+ npixels < maxpixels ? "Not enough" : "Too much",
+ (unsigned long)tif->tif_row, (uint64_t)npixels,
+ (uint64_t)maxpixels);
+ return (0);
+ }
+
+ return (1);
+}
+
+static int ThunderDecodeRow(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
+{
+ static const char module[] = "ThunderDecodeRow";
+ uint8_t *row = buf;
+
+ (void)s;
+ if (occ % tif->tif_scanlinesize)
+ {
+ TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
+ return (0);
+ }
+ while (occ > 0)
+ {
+ if (!ThunderDecode(tif, row, tif->tif_dir.td_imagewidth))
+ return (0);
+ occ -= tif->tif_scanlinesize;
+ row += tif->tif_scanlinesize;
+ }
+ return (1);
+}
+
+int TIFFInitThunderScan(TIFF *tif, int scheme)
+{
+ (void)scheme;
+
+ tif->tif_setupdecode = ThunderSetupDecode;
+ tif->tif_decoderow = ThunderDecodeRow;
+ tif->tif_decodestrip = ThunderDecodeRow;
+ return (1);
+}
+#endif /* THUNDER_SUPPORT */
diff --git a/contrib/libs/libtiff/tif_tile.c b/contrib/libs/libtiff/tif_tile.c
new file mode 100644
index 0000000000..f07032f731
--- /dev/null
+++ b/contrib/libs/libtiff/tif_tile.c
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 1991-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Tiled Image Support Routines.
+ */
+#include "tiffiop.h"
+
+/*
+ * Compute which tile an (x,y,z,s) value is in.
+ */
+uint32_t TIFFComputeTile(TIFF *tif, uint32_t x, uint32_t y, uint32_t z,
+ uint16_t s)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ uint32_t dx = td->td_tilewidth;
+ uint32_t dy = td->td_tilelength;
+ uint32_t dz = td->td_tiledepth;
+ uint32_t tile = 1;
+
+ if (td->td_imagedepth == 1)
+ z = 0;
+ if (dx == (uint32_t)-1)
+ dx = td->td_imagewidth;
+ if (dy == (uint32_t)-1)
+ dy = td->td_imagelength;
+ if (dz == (uint32_t)-1)
+ dz = td->td_imagedepth;
+ if (dx != 0 && dy != 0 && dz != 0)
+ {
+ uint32_t xpt = TIFFhowmany_32(td->td_imagewidth, dx);
+ uint32_t ypt = TIFFhowmany_32(td->td_imagelength, dy);
+ uint32_t zpt = TIFFhowmany_32(td->td_imagedepth, dz);
+
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
+ tile = (xpt * ypt * zpt) * s + (xpt * ypt) * (z / dz) +
+ xpt * (y / dy) + x / dx;
+ else
+ tile = (xpt * ypt) * (z / dz) + xpt * (y / dy) + x / dx;
+ }
+ return (tile);
+}
+
+/*
+ * Check an (x,y,z,s) coordinate
+ * against the image bounds.
+ */
+int TIFFCheckTile(TIFF *tif, uint32_t x, uint32_t y, uint32_t z, uint16_t s)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+
+ if (x >= td->td_imagewidth)
+ {
+ TIFFErrorExtR(tif, tif->tif_name, "%lu: Col out of range, max %lu",
+ (unsigned long)x, (unsigned long)(td->td_imagewidth - 1));
+ return (0);
+ }
+ if (y >= td->td_imagelength)
+ {
+ TIFFErrorExtR(tif, tif->tif_name, "%lu: Row out of range, max %lu",
+ (unsigned long)y,
+ (unsigned long)(td->td_imagelength - 1));
+ return (0);
+ }
+ if (z >= td->td_imagedepth)
+ {
+ TIFFErrorExtR(tif, tif->tif_name, "%lu: Depth out of range, max %lu",
+ (unsigned long)z, (unsigned long)(td->td_imagedepth - 1));
+ return (0);
+ }
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE &&
+ s >= td->td_samplesperpixel)
+ {
+ TIFFErrorExtR(tif, tif->tif_name, "%lu: Sample out of range, max %lu",
+ (unsigned long)s,
+ (unsigned long)(td->td_samplesperpixel - 1));
+ return (0);
+ }
+ return (1);
+}
+
+/*
+ * Compute how many tiles are in an image.
+ */
+uint32_t TIFFNumberOfTiles(TIFF *tif)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ uint32_t dx = td->td_tilewidth;
+ uint32_t dy = td->td_tilelength;
+ uint32_t dz = td->td_tiledepth;
+ uint32_t ntiles;
+
+ if (dx == (uint32_t)-1)
+ dx = td->td_imagewidth;
+ if (dy == (uint32_t)-1)
+ dy = td->td_imagelength;
+ if (dz == (uint32_t)-1)
+ dz = td->td_imagedepth;
+ ntiles =
+ (dx == 0 || dy == 0 || dz == 0)
+ ? 0
+ : _TIFFMultiply32(
+ tif,
+ _TIFFMultiply32(tif, TIFFhowmany_32(td->td_imagewidth, dx),
+ TIFFhowmany_32(td->td_imagelength, dy),
+ "TIFFNumberOfTiles"),
+ TIFFhowmany_32(td->td_imagedepth, dz), "TIFFNumberOfTiles");
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
+ ntiles = _TIFFMultiply32(tif, ntiles, td->td_samplesperpixel,
+ "TIFFNumberOfTiles");
+ return (ntiles);
+}
+
+/*
+ * Compute the # bytes in each row of a tile.
+ */
+uint64_t TIFFTileRowSize64(TIFF *tif)
+{
+ static const char module[] = "TIFFTileRowSize64";
+ TIFFDirectory *td = &tif->tif_dir;
+ uint64_t rowsize;
+ uint64_t tilerowsize;
+
+ if (td->td_tilelength == 0)
+ {
+ TIFFErrorExtR(tif, module, "Tile length is zero");
+ return 0;
+ }
+ if (td->td_tilewidth == 0)
+ {
+ TIFFErrorExtR(tif, module, "Tile width is zero");
+ return (0);
+ }
+ rowsize = _TIFFMultiply64(tif, td->td_bitspersample, td->td_tilewidth,
+ "TIFFTileRowSize");
+ if (td->td_planarconfig == PLANARCONFIG_CONTIG)
+ {
+ if (td->td_samplesperpixel == 0)
+ {
+ TIFFErrorExtR(tif, module, "Samples per pixel is zero");
+ return 0;
+ }
+ rowsize = _TIFFMultiply64(tif, rowsize, td->td_samplesperpixel,
+ "TIFFTileRowSize");
+ }
+ tilerowsize = TIFFhowmany8_64(rowsize);
+ if (tilerowsize == 0)
+ {
+ TIFFErrorExtR(tif, module, "Computed tile row size is zero");
+ return 0;
+ }
+ return (tilerowsize);
+}
+tmsize_t TIFFTileRowSize(TIFF *tif)
+{
+ static const char module[] = "TIFFTileRowSize";
+ uint64_t m;
+ m = TIFFTileRowSize64(tif);
+ return _TIFFCastUInt64ToSSize(tif, m, module);
+}
+
+/*
+ * Compute the # bytes in a variable length, row-aligned tile.
+ */
+uint64_t TIFFVTileSize64(TIFF *tif, uint32_t nrows)
+{
+ static const char module[] = "TIFFVTileSize64";
+ TIFFDirectory *td = &tif->tif_dir;
+ if (td->td_tilelength == 0 || td->td_tilewidth == 0 ||
+ td->td_tiledepth == 0)
+ return (0);
+ if ((td->td_planarconfig == PLANARCONFIG_CONTIG) &&
+ (td->td_photometric == PHOTOMETRIC_YCBCR) &&
+ (td->td_samplesperpixel == 3) && (!isUpSampled(tif)))
+ {
+ /*
+ * Packed YCbCr data contain one Cb+Cr for every
+ * HorizontalSampling*VerticalSampling Y values.
+ * Must also roundup width and height when calculating
+ * since images that are not a multiple of the
+ * horizontal/vertical subsampling area include
+ * YCbCr data for the extended image.
+ */
+ uint16_t ycbcrsubsampling[2];
+ uint16_t samplingblock_samples;
+ uint32_t samplingblocks_hor;
+ uint32_t samplingblocks_ver;
+ uint64_t samplingrow_samples;
+ uint64_t samplingrow_size;
+ TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
+ ycbcrsubsampling + 0, ycbcrsubsampling + 1);
+ if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 &&
+ ycbcrsubsampling[0] != 4) ||
+ (ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 &&
+ ycbcrsubsampling[1] != 4))
+ {
+ TIFFErrorExtR(tif, module, "Invalid YCbCr subsampling (%dx%d)",
+ ycbcrsubsampling[0], ycbcrsubsampling[1]);
+ return 0;
+ }
+ samplingblock_samples = ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2;
+ samplingblocks_hor =
+ TIFFhowmany_32(td->td_tilewidth, ycbcrsubsampling[0]);
+ samplingblocks_ver = TIFFhowmany_32(nrows, ycbcrsubsampling[1]);
+ samplingrow_samples = _TIFFMultiply64(tif, samplingblocks_hor,
+ samplingblock_samples, module);
+ samplingrow_size = TIFFhowmany8_64(_TIFFMultiply64(
+ tif, samplingrow_samples, td->td_bitspersample, module));
+ return (
+ _TIFFMultiply64(tif, samplingrow_size, samplingblocks_ver, module));
+ }
+ else
+ return (_TIFFMultiply64(tif, nrows, TIFFTileRowSize64(tif), module));
+}
+tmsize_t TIFFVTileSize(TIFF *tif, uint32_t nrows)
+{
+ static const char module[] = "TIFFVTileSize";
+ uint64_t m;
+ m = TIFFVTileSize64(tif, nrows);
+ return _TIFFCastUInt64ToSSize(tif, m, module);
+}
+
+/*
+ * Compute the # bytes in a row-aligned tile.
+ */
+uint64_t TIFFTileSize64(TIFF *tif)
+{
+ return (TIFFVTileSize64(tif, tif->tif_dir.td_tilelength));
+}
+tmsize_t TIFFTileSize(TIFF *tif)
+{
+ static const char module[] = "TIFFTileSize";
+ uint64_t m;
+ m = TIFFTileSize64(tif);
+ return _TIFFCastUInt64ToSSize(tif, m, module);
+}
+
+/*
+ * Compute a default tile size based on the image
+ * characteristics and a requested value. If a
+ * request is <1 then we choose a size according
+ * to certain heuristics.
+ */
+void TIFFDefaultTileSize(TIFF *tif, uint32_t *tw, uint32_t *th)
+{
+ (*tif->tif_deftilesize)(tif, tw, th);
+}
+
+void _TIFFDefaultTileSize(TIFF *tif, uint32_t *tw, uint32_t *th)
+{
+ (void)tif;
+ if (*(int32_t *)tw < 1)
+ *tw = 256;
+ if (*(int32_t *)th < 1)
+ *th = 256;
+ /* roundup to a multiple of 16 per the spec */
+ if (*tw & 0xf)
+ *tw = TIFFroundup_32(*tw, 16);
+ if (*th & 0xf)
+ *th = TIFFroundup_32(*th, 16);
+}
diff --git a/contrib/libs/libtiff/tif_unix.c b/contrib/libs/libtiff/tif_unix.c
new file mode 100644
index 0000000000..34dd53b98c
--- /dev/null
+++ b/contrib/libs/libtiff/tif_unix.c
@@ -0,0 +1,370 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library UNIX-specific Routines. These are should also work with the
+ * Windows Common RunTime Library.
+ */
+
+#include "tif_config.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include <errno.h>
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+
+#include "tiffiop.h"
+
+#define TIFF_IO_MAX 2147483647U
+
+typedef union fd_as_handle_union
+{
+ int fd;
+ thandle_t h;
+} fd_as_handle_union_t;
+
+static tmsize_t _tiffReadProc(thandle_t fd, void *buf, tmsize_t size)
+{
+ fd_as_handle_union_t fdh;
+ const size_t bytes_total = (size_t)size;
+ size_t bytes_read;
+ tmsize_t count = -1;
+ if ((tmsize_t)bytes_total != size)
+ {
+ errno = EINVAL;
+ return (tmsize_t)-1;
+ }
+ fdh.h = fd;
+ for (bytes_read = 0; bytes_read < bytes_total; bytes_read += count)
+ {
+ char *buf_offset = (char *)buf + bytes_read;
+ size_t io_size = bytes_total - bytes_read;
+ if (io_size > TIFF_IO_MAX)
+ io_size = TIFF_IO_MAX;
+ count = read(fdh.fd, buf_offset, (TIFFIOSize_t)io_size);
+ if (count <= 0)
+ break;
+ }
+ if (count < 0)
+ return (tmsize_t)-1;
+ return (tmsize_t)bytes_read;
+}
+
+static tmsize_t _tiffWriteProc(thandle_t fd, void *buf, tmsize_t size)
+{
+ fd_as_handle_union_t fdh;
+ const size_t bytes_total = (size_t)size;
+ size_t bytes_written;
+ tmsize_t count = -1;
+ if ((tmsize_t)bytes_total != size)
+ {
+ errno = EINVAL;
+ return (tmsize_t)-1;
+ }
+ fdh.h = fd;
+ for (bytes_written = 0; bytes_written < bytes_total; bytes_written += count)
+ {
+ const char *buf_offset = (char *)buf + bytes_written;
+ size_t io_size = bytes_total - bytes_written;
+ if (io_size > TIFF_IO_MAX)
+ io_size = TIFF_IO_MAX;
+ count = write(fdh.fd, buf_offset, (TIFFIOSize_t)io_size);
+ if (count <= 0)
+ break;
+ }
+ if (count < 0)
+ return (tmsize_t)-1;
+ return (tmsize_t)bytes_written;
+ /* return ((tmsize_t) write(fdh.fd, buf, bytes_total)); */
+}
+
+static uint64_t _tiffSeekProc(thandle_t fd, uint64_t off, int whence)
+{
+ fd_as_handle_union_t fdh;
+ _TIFF_off_t off_io = (_TIFF_off_t)off;
+ if ((uint64_t)off_io != off)
+ {
+ errno = EINVAL;
+ return (uint64_t)-1; /* this is really gross */
+ }
+ fdh.h = fd;
+ return ((uint64_t)_TIFF_lseek_f(fdh.fd, off_io, whence));
+}
+
+static int _tiffCloseProc(thandle_t fd)
+{
+ fd_as_handle_union_t fdh;
+ fdh.h = fd;
+ return (close(fdh.fd));
+}
+
+static uint64_t _tiffSizeProc(thandle_t fd)
+{
+ _TIFF_stat_s sb;
+ fd_as_handle_union_t fdh;
+ fdh.h = fd;
+ if (_TIFF_fstat_f(fdh.fd, &sb) < 0)
+ return (0);
+ else
+ return ((uint64_t)sb.st_size);
+}
+
+#ifdef HAVE_MMAP
+#include <sys/mman.h>
+
+static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize)
+{
+ uint64_t size64 = _tiffSizeProc(fd);
+ tmsize_t sizem = (tmsize_t)size64;
+ if (size64 && (uint64_t)sizem == size64)
+ {
+ fd_as_handle_union_t fdh;
+ fdh.h = fd;
+ *pbase =
+ (void *)mmap(0, (size_t)sizem, PROT_READ, MAP_SHARED, fdh.fd, 0);
+ if (*pbase != (void *)-1)
+ {
+ *psize = (tmsize_t)sizem;
+ return (1);
+ }
+ }
+ return (0);
+}
+
+static void _tiffUnmapProc(thandle_t fd, void *base, toff_t size)
+{
+ (void)fd;
+ (void)munmap(base, (off_t)size);
+}
+#else /* !HAVE_MMAP */
+static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize)
+{
+ (void)fd;
+ (void)pbase;
+ (void)psize;
+ return (0);
+}
+
+static void _tiffUnmapProc(thandle_t fd, void *base, toff_t size)
+{
+ (void)fd;
+ (void)base;
+ (void)size;
+}
+#endif /* !HAVE_MMAP */
+
+/*
+ * Open a TIFF file descriptor for read/writing.
+ */
+TIFF *TIFFFdOpen(int fd, const char *name, const char *mode)
+{
+ return TIFFFdOpenExt(fd, name, mode, NULL);
+}
+
+TIFF *TIFFFdOpenExt(int fd, const char *name, const char *mode,
+ TIFFOpenOptions *opts)
+{
+ TIFF *tif;
+
+ fd_as_handle_union_t fdh;
+ fdh.fd = fd;
+ tif = TIFFClientOpenExt(name, mode, fdh.h, _tiffReadProc, _tiffWriteProc,
+ _tiffSeekProc, _tiffCloseProc, _tiffSizeProc,
+ _tiffMapProc, _tiffUnmapProc, opts);
+ if (tif)
+ tif->tif_fd = fd;
+ return (tif);
+}
+
+/*
+ * Open a TIFF file for read/writing.
+ */
+TIFF *TIFFOpen(const char *name, const char *mode)
+{
+ return TIFFOpenExt(name, mode, NULL);
+}
+
+TIFF *TIFFOpenExt(const char *name, const char *mode, TIFFOpenOptions *opts)
+{
+ static const char module[] = "TIFFOpen";
+ int m, fd;
+ TIFF *tif;
+
+ m = _TIFFgetMode(opts, NULL, mode, module);
+ if (m == -1)
+ return ((TIFF *)0);
+
+/* for cygwin and mingw */
+#ifdef O_BINARY
+ m |= O_BINARY;
+#endif
+
+ fd = open(name, m, 0666);
+ if (fd < 0)
+ {
+ if (errno > 0 && strerror(errno) != NULL)
+ {
+ _TIFFErrorEarly(opts, NULL, module, "%s: %s", name,
+ strerror(errno));
+ }
+ else
+ {
+ _TIFFErrorEarly(opts, NULL, module, "%s: Cannot open", name);
+ }
+ return ((TIFF *)0);
+ }
+
+ tif = TIFFFdOpenExt((int)fd, name, mode, opts);
+ if (!tif)
+ close(fd);
+ return tif;
+}
+
+#ifdef __WIN32__
+#include <windows.h>
+/*
+ * Open a TIFF file with a Unicode filename, for read/writing.
+ */
+TIFF *TIFFOpenW(const wchar_t *name, const char *mode)
+{
+ return TIFFOpenWExt(name, mode, NULL);
+}
+TIFF *TIFFOpenWExt(const wchar_t *name, const char *mode, TIFFOpenOptions *opts)
+{
+ static const char module[] = "TIFFOpenW";
+ int m, fd;
+ int mbsize;
+ char *mbname;
+ TIFF *tif;
+
+ m = _TIFFgetMode(opts, NULL, mode, module);
+ if (m == -1)
+ return ((TIFF *)0);
+
+/* for cygwin and mingw */
+#ifdef O_BINARY
+ m |= O_BINARY;
+#endif
+
+ fd = _wopen(name, m, 0666);
+ if (fd < 0)
+ {
+ _TIFFErrorEarly(opts, NULL, module, "%ls: Cannot open", name);
+ return ((TIFF *)0);
+ }
+
+ mbname = NULL;
+ mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL);
+ if (mbsize > 0)
+ {
+ mbname = _TIFFmalloc(mbsize);
+ if (!mbname)
+ {
+ _TIFFErrorEarly(
+ opts, NULL, module,
+ "Can't allocate space for filename conversion buffer");
+ return ((TIFF *)0);
+ }
+
+ WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize, NULL, NULL);
+ }
+
+ tif = TIFFFdOpenExt((int)fd, (mbname != NULL) ? mbname : "<unknown>", mode,
+ opts);
+
+ _TIFFfree(mbname);
+
+ if (!tif)
+ close(fd);
+ return tif;
+}
+#endif
+
+void *_TIFFmalloc(tmsize_t s)
+{
+ if (s == 0)
+ return ((void *)NULL);
+
+ return (malloc((size_t)s));
+}
+
+void *_TIFFcalloc(tmsize_t nmemb, tmsize_t siz)
+{
+ if (nmemb == 0 || siz == 0)
+ return ((void *)NULL);
+
+ return calloc((size_t)nmemb, (size_t)siz);
+}
+
+void _TIFFfree(void *p) { free(p); }
+
+void *_TIFFrealloc(void *p, tmsize_t s) { return (realloc(p, (size_t)s)); }
+
+void _TIFFmemset(void *p, int v, tmsize_t c) { memset(p, v, (size_t)c); }
+
+void _TIFFmemcpy(void *d, const void *s, tmsize_t c)
+{
+ memcpy(d, s, (size_t)c);
+}
+
+int _TIFFmemcmp(const void *p1, const void *p2, tmsize_t c)
+{
+ return (memcmp(p1, p2, (size_t)c));
+}
+
+static void unixWarningHandler(const char *module, const char *fmt, va_list ap)
+{
+ if (module != NULL)
+ fprintf(stderr, "%s: ", module);
+ fprintf(stderr, "Warning, ");
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, ".\n");
+}
+TIFFErrorHandler _TIFFwarningHandler = unixWarningHandler;
+
+static void unixErrorHandler(const char *module, const char *fmt, va_list ap)
+{
+ if (module != NULL)
+ fprintf(stderr, "%s: ", module);
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, ".\n");
+}
+TIFFErrorHandler _TIFFerrorHandler = unixErrorHandler;
diff --git a/contrib/libs/libtiff/tif_version.c b/contrib/libs/libtiff/tif_version.c
new file mode 100644
index 0000000000..0b6c9bc00a
--- /dev/null
+++ b/contrib/libs/libtiff/tif_version.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 1992-1997 Sam Leffler
+ * Copyright (c) 1992-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+#include "tiffiop.h"
+
+static const char TIFFVersion[] = TIFFLIB_VERSION_STR;
+
+const char *TIFFGetVersion(void) { return (TIFFVersion); }
diff --git a/contrib/libs/libtiff/tif_warning.c b/contrib/libs/libtiff/tif_warning.c
new file mode 100644
index 0000000000..5468de55f2
--- /dev/null
+++ b/contrib/libs/libtiff/tif_warning.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ */
+#include "tiffiop.h"
+
+TIFFErrorHandlerExt _TIFFwarningHandlerExt = NULL;
+
+TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler handler)
+{
+ TIFFErrorHandler prev = _TIFFwarningHandler;
+ _TIFFwarningHandler = handler;
+ return (prev);
+}
+
+TIFFErrorHandlerExt TIFFSetWarningHandlerExt(TIFFErrorHandlerExt handler)
+{
+ TIFFErrorHandlerExt prev = _TIFFwarningHandlerExt;
+ _TIFFwarningHandlerExt = handler;
+ return (prev);
+}
+
+void TIFFWarning(const char *module, const char *fmt, ...)
+{
+ va_list ap;
+ if (_TIFFwarningHandler)
+ {
+ va_start(ap, fmt);
+ (*_TIFFwarningHandler)(module, fmt, ap);
+ va_end(ap);
+ }
+ if (_TIFFwarningHandlerExt)
+ {
+ va_start(ap, fmt);
+ (*_TIFFwarningHandlerExt)(0, module, fmt, ap);
+ va_end(ap);
+ }
+}
+
+void TIFFWarningExt(thandle_t fd, const char *module, const char *fmt, ...)
+{
+ va_list ap;
+ if (_TIFFwarningHandler)
+ {
+ va_start(ap, fmt);
+ (*_TIFFwarningHandler)(module, fmt, ap);
+ va_end(ap);
+ }
+ if (_TIFFwarningHandlerExt)
+ {
+ va_start(ap, fmt);
+ (*_TIFFwarningHandlerExt)(fd, module, fmt, ap);
+ va_end(ap);
+ }
+}
+
+void TIFFWarningExtR(TIFF *tif, const char *module, const char *fmt, ...)
+{
+ va_list ap;
+ if (tif && tif->tif_warnhandler)
+ {
+ va_start(ap, fmt);
+ int stop = (*tif->tif_warnhandler)(tif, tif->tif_warnhandler_user_data,
+ module, fmt, ap);
+ va_end(ap);
+ if (stop)
+ return;
+ }
+ if (_TIFFwarningHandler)
+ {
+ va_start(ap, fmt);
+ (*_TIFFwarningHandler)(module, fmt, ap);
+ va_end(ap);
+ }
+ if (_TIFFwarningHandlerExt)
+ {
+ va_start(ap, fmt);
+ (*_TIFFwarningHandlerExt)(tif ? tif->tif_clientdata : 0, module, fmt,
+ ap);
+ va_end(ap);
+ }
+}
diff --git a/contrib/libs/libtiff/tif_webp.c b/contrib/libs/libtiff/tif_webp.c
new file mode 100644
index 0000000000..07db7cce25
--- /dev/null
+++ b/contrib/libs/libtiff/tif_webp.c
@@ -0,0 +1,800 @@
+/*
+ * Copyright (c) 2018, Mapbox
+ * Author: <norman.barker at mapbox.com>
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+#include "tiffiop.h"
+#ifdef WEBP_SUPPORT
+/*
+ * TIFF Library.
+ *
+ * WEBP Compression Support
+ *
+ */
+
+#include "webp/decode.h"
+#include "webp/encode.h"
+
+#include <stdbool.h>
+#include <stdio.h>
+
+#define LSTATE_INIT_DECODE 0x01
+#define LSTATE_INIT_ENCODE 0x02
+/*
+ * State block for each open TIFF
+ * file using WEBP compression/decompression.
+ */
+typedef struct
+{
+ uint16_t nSamples; /* number of samples per pixel */
+
+ int lossless; /* lossy/lossless compression */
+ int quality_level; /* compression level */
+ WebPPicture sPicture; /* WebP Picture */
+ WebPConfig sEncoderConfig; /* WebP encoder config */
+ 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;
+
+#define LState(tif) ((WebPState *)(tif)->tif_data)
+#define DecoderState(tif) LState(tif)
+#define EncoderState(tif) LState(tif)
+
+static int TWebPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
+static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s);
+
+static int TWebPDatasetWriter(const uint8_t *data, size_t data_size,
+ const WebPPicture *const picture)
+{
+ static const char module[] = "TWebPDatasetWriter";
+ TIFF *tif = (TIFF *)(picture->custom_ptr);
+
+ if ((tif->tif_rawcc + (tmsize_t)data_size) > tif->tif_rawdatasize)
+ {
+ TIFFErrorExtR(
+ tif, module, "Buffer too small by %" TIFF_SIZE_FORMAT " bytes.",
+ (size_t)(tif->tif_rawcc + data_size - tif->tif_rawdatasize));
+ return 0;
+ }
+ else
+ {
+ _TIFFmemcpy(tif->tif_rawcp, data, data_size);
+ tif->tif_rawcc += data_size;
+ tif->tif_rawcp += data_size;
+ return 1;
+ }
+}
+
+/*
+ * Encode a chunk of pixels.
+ */
+static int TWebPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
+{
+ static const char module[] = "TWebPEncode";
+ WebPState *sp = EncoderState(tif);
+ (void)s;
+
+ assert(sp != NULL);
+ assert(sp->state == LSTATE_INIT_ENCODE);
+
+ if ((uint64_t)sp->buffer_offset + (uint64_t)cc > sp->buffer_size)
+ {
+ TIFFErrorExtR(tif, module, "Too many bytes to be written");
+ return 0;
+ }
+
+ memcpy(sp->pBuffer + sp->buffer_offset, bp, cc);
+ sp->buffer_offset += (unsigned)cc;
+
+ return 1;
+}
+
+static int 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);
+ uint32_t segment_width, segment_height;
+ bool decode_whole_strile = false;
+
+ (void)s;
+
+ assert(sp != NULL);
+ assert(sp->state == LSTATE_INIT_DECODE);
+
+ if (sp->psDecoder == NULL)
+ {
+ TIFFDirectory *td = &tif->tif_dir;
+ uint32_t buffer_size;
+
+ if (isTiled(tif))
+ {
+ segment_width = td->td_tilewidth;
+ segment_height = td->td_tilelength;
+ }
+ 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;
+ }
+
+ buffer_size = segment_width * segment_height * sp->nSamples;
+ if (occ == (tmsize_t)buffer_size)
+ {
+ /* If decoding the whole strip/tile, we can directly use the */
+ /* output buffer */
+ decode_whole_strile = true;
+ }
+ else if (sp->pBuffer == NULL || buffer_size > sp->buffer_size)
+ {
+ if (sp->pBuffer != NULL)
+ {
+ _TIFFfreeExt(tif, sp->pBuffer);
+ sp->pBuffer = NULL;
+ }
+
+ sp->pBuffer = _TIFFmallocExt(tif, buffer_size);
+ if (!sp->pBuffer)
+ {
+ TIFFErrorExtR(tif, module, "Cannot allocate buffer");
+ return 0;
+ }
+ sp->buffer_size = buffer_size;
+ }
+
+ sp->last_y = 0;
+
+ WebPInitDecBuffer(&sp->sDecBuffer);
+
+ sp->sDecBuffer.is_external_memory = 1;
+ sp->sDecBuffer.width = segment_width;
+ sp->sDecBuffer.height = segment_height;
+ sp->sDecBuffer.u.RGBA.rgba = decode_whole_strile ? op : sp->pBuffer;
+ sp->sDecBuffer.u.RGBA.stride = segment_width * sp->nSamples;
+ sp->sDecBuffer.u.RGBA.size = buffer_size;
+
+ if (sp->nSamples > 3)
+ {
+ sp->sDecBuffer.colorspace = MODE_RGBA;
+ }
+ else
+ {
+ sp->sDecBuffer.colorspace = MODE_RGB;
+ }
+
+ sp->psDecoder = WebPINewDecoder(&sp->sDecBuffer);
+
+ if (sp->psDecoder == NULL)
+ {
+ TIFFErrorExtR(tif, module, "Unable to allocate WebP decoder.");
+ return 0;
+ }
+ }
+
+ if (occ % sp->sDecBuffer.u.RGBA.stride)
+ {
+ TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
+ return 0;
+ }
+
+ status = WebPIAppend(sp->psDecoder, tif->tif_rawcp, tif->tif_rawcc);
+
+ if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED)
+ {
+ if (status == VP8_STATUS_INVALID_PARAM)
+ {
+ TIFFErrorExtR(tif, module, "Invalid parameter used.");
+ }
+ else if (status == VP8_STATUS_OUT_OF_MEMORY)
+ {
+ TIFFErrorExtR(tif, module, "Out of memory.");
+ }
+ else
+ {
+ TIFFErrorExtR(tif, module, "Unrecognized error.");
+ }
+ return 0;
+ }
+ else
+ {
+ int current_y, stride;
+ uint8_t *buf;
+
+ /* 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)))
+ {
+ const int numberOfExpectedLines =
+ (int)(occ / sp->sDecBuffer.u.RGBA.stride);
+ if (decode_whole_strile)
+ {
+ if (current_y != numberOfExpectedLines)
+ {
+ TIFFErrorExtR(tif, module,
+ "Unable to decode WebP data: less lines than "
+ "expected.");
+ return 0;
+ }
+ }
+ else
+ {
+ memcpy(op, buf + (sp->last_y * stride), occ);
+ }
+
+ tif->tif_rawcp += tif->tif_rawcc;
+ tif->tif_rawcc = 0;
+ sp->last_y += numberOfExpectedLines;
+
+ if (decode_whole_strile)
+ {
+ /* We can now free the decoder as we're completely done */
+ if (sp->psDecoder != NULL)
+ {
+ WebPIDelete(sp->psDecoder);
+ WebPFreeDecBuffer(&sp->sDecBuffer);
+ sp->psDecoder = NULL;
+ }
+ }
+ return 1;
+ }
+ else
+ {
+ TIFFErrorExtR(tif, module, "Unable to decode WebP data.");
+ return 0;
+ }
+ }
+}
+
+static int TWebPFixupTags(TIFF *tif)
+{
+ (void)tif;
+ if (tif->tif_dir.td_planarconfig != PLANARCONFIG_CONTIG)
+ {
+ static const char module[] = "TWebPFixupTags";
+ TIFFErrorExtR(tif, module,
+ "TIFF WEBP requires data to be stored contiguously in "
+ "RGB e.g. RGBRGBRGB "
+#if WEBP_ENCODER_ABI_VERSION >= 0x0100
+ "or RGBARGBARGBA"
+#endif
+ );
+ return 0;
+ }
+ return 1;
+}
+
+static int TWebPSetupDecode(TIFF *tif)
+{
+ static const char module[] = "WebPSetupDecode";
+ uint16_t nBitsPerSample = tif->tif_dir.td_bitspersample;
+ uint16_t sampleFormat = tif->tif_dir.td_sampleformat;
+
+ WebPState *sp = DecoderState(tif);
+ assert(sp != NULL);
+
+ sp->nSamples = tif->tif_dir.td_samplesperpixel;
+
+ /* check band count */
+ if (sp->nSamples != 3
+#if WEBP_ENCODER_ABI_VERSION >= 0x0100
+ && sp->nSamples != 4
+#endif
+ )
+ {
+ TIFFErrorExtR(tif, module,
+ "WEBP driver doesn't support %d bands. Must be 3 (RGB) "
+#if WEBP_ENCODER_ABI_VERSION >= 0x0100
+ "or 4 (RGBA) "
+#endif
+ "bands.",
+ sp->nSamples);
+ return 0;
+ }
+
+ /* check bits per sample and data type */
+ if ((nBitsPerSample != 8) && (sampleFormat != 1))
+ {
+ TIFFErrorExtR(tif, module, "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);
+ if (sp->pBuffer != NULL)
+ {
+ _TIFFfreeExt(tif, sp->pBuffer);
+ sp->pBuffer = NULL;
+ }
+ sp->buffer_offset = 0;
+ sp->state = 0;
+ }
+
+ sp->state |= LSTATE_INIT_DECODE;
+
+ return 1;
+}
+
+/*
+ * Setup state for decoding a strip.
+ */
+static int TWebPPreDecode(TIFF *tif, uint16_t s)
+{
+ static const char module[] = "TWebPPreDecode";
+ uint32_t segment_width, segment_height;
+ WebPState *sp = DecoderState(tif);
+ TIFFDirectory *td = &tif->tif_dir;
+ (void)s;
+ assert(sp != NULL);
+
+ if (isTiled(tif))
+ {
+ segment_width = td->td_tilewidth;
+ segment_height = td->td_tilelength;
+ }
+ 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;
+ }
+
+ if (segment_width > 16383 || segment_height > 16383)
+ {
+ TIFFErrorExtR(tif, module,
+ "WEBP maximum image dimensions are 16383 x 16383.");
+ return 0;
+ }
+
+ if ((sp->state & LSTATE_INIT_DECODE) == 0)
+ tif->tif_setupdecode(tif);
+
+ if (sp->psDecoder != NULL)
+ {
+ WebPIDelete(sp->psDecoder);
+ WebPFreeDecBuffer(&sp->sDecBuffer);
+ sp->psDecoder = NULL;
+ }
+
+ return 1;
+}
+
+static int 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);
+
+ sp->nSamples = tif->tif_dir.td_samplesperpixel;
+
+ /* check band count */
+ if (sp->nSamples != 3
+#if WEBP_ENCODER_ABI_VERSION >= 0x0100
+ && sp->nSamples != 4
+#endif
+ )
+ {
+ TIFFErrorExtR(tif, module,
+ "WEBP driver doesn't support %d bands. Must be 3 (RGB) "
+#if WEBP_ENCODER_ABI_VERSION >= 0x0100
+ "or 4 (RGBA) "
+#endif
+ "bands.",
+ sp->nSamples);
+ return 0;
+ }
+
+ /* check bits per sample and data type */
+ if ((nBitsPerSample != 8) || (sampleFormat != SAMPLEFORMAT_UINT))
+ {
+ TIFFErrorExtR(tif, module, "WEBP driver requires 8 bit unsigned data");
+ return 0;
+ }
+
+ if (sp->state & LSTATE_INIT_DECODE)
+ {
+ WebPIDelete(sp->psDecoder);
+ WebPFreeDecBuffer(&sp->sDecBuffer);
+ sp->psDecoder = NULL;
+ sp->last_y = 0;
+ sp->state = 0;
+ }
+
+ sp->state |= LSTATE_INIT_ENCODE;
+
+ if (!WebPPictureInit(&sp->sPicture))
+ {
+ TIFFErrorExtR(tif, module, "Error initializing WebP picture.");
+ return 0;
+ }
+
+ if (!WebPConfigInitInternal(&sp->sEncoderConfig, WEBP_PRESET_DEFAULT,
+ (float)sp->quality_level,
+ WEBP_ENCODER_ABI_VERSION))
+ {
+ TIFFErrorExtR(tif, module,
+ "Error creating WebP encoder configuration.");
+ return 0;
+ }
+
+// WebPConfigInitInternal above sets lossless to false
+#if WEBP_ENCODER_ABI_VERSION >= 0x0100
+ sp->sEncoderConfig.lossless = sp->lossless;
+ if (sp->lossless)
+ {
+ sp->sPicture.use_argb = 1;
+ }
+#endif
+
+ if (!WebPValidateConfig(&sp->sEncoderConfig))
+ {
+ TIFFErrorExtR(tif, module, "Error with WebP encoder configuration.");
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Reset encoding state at the start of a strip.
+ */
+static int TWebPPreEncode(TIFF *tif, uint16_t s)
+{
+ static const char module[] = "TWebPPreEncode";
+ uint32_t segment_width, segment_height;
+ WebPState *sp = EncoderState(tif);
+ TIFFDirectory *td = &tif->tif_dir;
+
+ (void)s;
+
+ assert(sp != NULL);
+ if (sp->state != LSTATE_INIT_ENCODE)
+ tif->tif_setupencode(tif);
+
+ /*
+ * Set encoding parameters for this strip/tile.
+ */
+ if (isTiled(tif))
+ {
+ segment_width = td->td_tilewidth;
+ segment_height = td->td_tilelength;
+ }
+ 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;
+ }
+
+ if (segment_width > 16383 || segment_height > 16383)
+ {
+ TIFFErrorExtR(tif, module,
+ "WEBP maximum image dimensions are 16383 x 16383.");
+ return 0;
+ }
+
+ /* 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)
+ {
+ _TIFFfreeExt(tif, sp->pBuffer);
+ sp->pBuffer = NULL;
+ }
+
+ sp->pBuffer = _TIFFmallocExt(tif, sp->buffer_size);
+ if (!sp->pBuffer)
+ {
+ TIFFErrorExtR(tif, module, "Cannot allocate buffer");
+ return 0;
+ }
+ sp->buffer_offset = 0;
+
+ sp->sPicture.width = segment_width;
+ sp->sPicture.height = segment_height;
+ sp->sPicture.writer = TWebPDatasetWriter;
+ sp->sPicture.custom_ptr = tif;
+
+ return 1;
+}
+
+/*
+ * Finish off an encoded strip by flushing it.
+ */
+static int TWebPPostEncode(TIFF *tif)
+{
+ static const char module[] = "WebPPostEncode";
+ int64_t stride;
+ WebPState *sp = EncoderState(tif);
+ assert(sp != NULL);
+
+ assert(sp->state == LSTATE_INIT_ENCODE);
+
+ stride = (int64_t)sp->sPicture.width * sp->nSamples;
+
+#if WEBP_ENCODER_ABI_VERSION >= 0x0100
+ if (sp->nSamples == 4)
+ {
+ if (!WebPPictureImportRGBA(&sp->sPicture, sp->pBuffer, (int)stride))
+ {
+ TIFFErrorExtR(tif, module, "WebPPictureImportRGBA() failed");
+ return 0;
+ }
+ }
+ else
+#endif
+ if (!WebPPictureImportRGB(&sp->sPicture, sp->pBuffer, (int)stride))
+ {
+ TIFFErrorExtR(tif, module, "WebPPictureImportRGB() failed");
+ return 0;
+ }
+
+ if (!WebPEncode(&sp->sEncoderConfig, &sp->sPicture))
+ {
+
+#if WEBP_ENCODER_ABI_VERSION >= 0x0100
+ const char *pszErrorMsg = NULL;
+ switch (sp->sPicture.error_code)
+ {
+ case VP8_ENC_ERROR_OUT_OF_MEMORY:
+ pszErrorMsg = "Out of memory";
+ break;
+ case VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY:
+ pszErrorMsg = "Out of memory while flushing bits";
+ break;
+ case VP8_ENC_ERROR_NULL_PARAMETER:
+ pszErrorMsg = "A pointer parameter is NULL";
+ break;
+ case VP8_ENC_ERROR_INVALID_CONFIGURATION:
+ pszErrorMsg = "Configuration is invalid";
+ break;
+ case VP8_ENC_ERROR_BAD_DIMENSION:
+ pszErrorMsg = "Picture has invalid width/height";
+ break;
+ case VP8_ENC_ERROR_PARTITION0_OVERFLOW:
+ pszErrorMsg = "Partition is bigger than 512k. Try using less "
+ "SEGMENTS, or increase PARTITION_LIMIT value";
+ break;
+ case VP8_ENC_ERROR_PARTITION_OVERFLOW:
+ pszErrorMsg = "Partition is bigger than 16M";
+ break;
+ case VP8_ENC_ERROR_BAD_WRITE:
+ pszErrorMsg = "Error while fludshing bytes";
+ break;
+ case VP8_ENC_ERROR_FILE_TOO_BIG:
+ pszErrorMsg = "File is bigger than 4G";
+ break;
+ case VP8_ENC_ERROR_USER_ABORT:
+ pszErrorMsg = "User interrupted";
+ break;
+ default:
+ TIFFErrorExtR(tif, module,
+ "WebPEncode returned an unknown error code: %d",
+ sp->sPicture.error_code);
+ pszErrorMsg = "Unknown WebP error type.";
+ break;
+ }
+ TIFFErrorExtR(tif, module, "WebPEncode() failed : %s", pszErrorMsg);
+#else
+ TIFFErrorExtR(tif, module, "Error in WebPEncode()");
+#endif
+ return 0;
+ }
+
+ sp->sPicture.custom_ptr = NULL;
+
+ if (!TIFFFlushData1(tif))
+ {
+ TIFFErrorExtR(tif, module, "Error flushing TIFF WebP encoder.");
+ return 0;
+ }
+
+ return 1;
+}
+
+static void TWebPCleanup(TIFF *tif)
+{
+ WebPState *sp = LState(tif);
+
+ assert(sp != 0);
+
+ tif->tif_tagmethods.vgetfield = sp->vgetparent;
+ tif->tif_tagmethods.vsetfield = sp->vsetparent;
+
+ if (sp->state & LSTATE_INIT_ENCODE)
+ {
+ WebPPictureFree(&sp->sPicture);
+ }
+
+ if (sp->psDecoder != NULL)
+ {
+ WebPIDelete(sp->psDecoder);
+ WebPFreeDecBuffer(&sp->sDecBuffer);
+ sp->psDecoder = NULL;
+ sp->last_y = 0;
+ }
+
+ if (sp->pBuffer != NULL)
+ {
+ _TIFFfreeExt(tif, sp->pBuffer);
+ sp->pBuffer = NULL;
+ }
+
+ _TIFFfreeExt(tif, tif->tif_data);
+ tif->tif_data = NULL;
+
+ _TIFFSetDefaultCompressionState(tif);
+}
+
+static int TWebPVSetField(TIFF *tif, uint32_t tag, va_list ap)
+{
+ static const char module[] = "WebPVSetField";
+ WebPState *sp = LState(tif);
+
+ switch (tag)
+ {
+ case TIFFTAG_WEBP_LEVEL:
+ sp->quality_level = (int)va_arg(ap, int);
+ if (sp->quality_level <= 0 || sp->quality_level > 100.0f)
+ {
+ TIFFWarningExtR(tif, module,
+ "WEBP_LEVEL should be between 1 and 100");
+ }
+ return 1;
+ case TIFFTAG_WEBP_LOSSLESS:
+#if WEBP_ENCODER_ABI_VERSION >= 0x0100
+ sp->lossless = va_arg(ap, int);
+ if (sp->lossless)
+ {
+ sp->quality_level = 100;
+ }
+ return 1;
+#else
+ TIFFErrorExtR(
+ tif, module,
+ "Need to upgrade WEBP driver, this version doesn't support "
+ "lossless compression.");
+ return 0;
+#endif
+ default:
+ return (*sp->vsetparent)(tif, tag, ap);
+ }
+ /*NOTREACHED*/
+}
+
+static int TWebPVGetField(TIFF *tif, uint32_t tag, va_list ap)
+{
+ WebPState *sp = LState(tif);
+
+ switch (tag)
+ {
+ case TIFFTAG_WEBP_LEVEL:
+ *va_arg(ap, int *) = sp->quality_level;
+ break;
+ case TIFFTAG_WEBP_LOSSLESS:
+ *va_arg(ap, int *) = sp->lossless;
+ break;
+ default:
+ return (*sp->vgetparent)(tif, tag, ap);
+ }
+ return 1;
+}
+
+static const TIFFField TWebPFields[] = {
+ {TIFFTAG_WEBP_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
+ TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "WEBP quality", NULL},
+ {TIFFTAG_WEBP_LOSSLESS, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
+ TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "WEBP lossless/lossy",
+ NULL},
+};
+
+int TIFFInitWebP(TIFF *tif, int scheme)
+{
+ static const char module[] = "TIFFInitWebP";
+ WebPState *sp;
+
+ (void)scheme;
+ assert(scheme == COMPRESSION_WEBP);
+
+ /*
+ * Merge codec-specific tag information.
+ */
+ if (!_TIFFMergeFields(tif, TWebPFields, TIFFArrayCount(TWebPFields)))
+ {
+ TIFFErrorExtR(tif, module, "Merging WebP codec-specific tags failed");
+ return 0;
+ }
+
+ /*
+ * Allocate state block so tag methods have storage to record values.
+ */
+ tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(WebPState));
+ if (tif->tif_data == NULL)
+ goto bad;
+ sp = LState(tif);
+
+ /*
+ * Override parent get/set field methods.
+ */
+ sp->vgetparent = tif->tif_tagmethods.vgetfield;
+ tif->tif_tagmethods.vgetfield = TWebPVGetField; /* hook for codec tags */
+ sp->vsetparent = tif->tif_tagmethods.vsetfield;
+ tif->tif_tagmethods.vsetfield = TWebPVSetField; /* hook for codec tags */
+
+ /* Default values for codec-specific fields */
+ sp->quality_level = 75; /* default comp. level */
+ sp->lossless = 0; /* default to false */
+ sp->state = 0;
+ sp->nSamples = 0;
+ sp->psDecoder = NULL;
+ sp->last_y = 0;
+
+ sp->buffer_offset = 0;
+ sp->pBuffer = NULL;
+
+ /*
+ * Install codec methods.
+ * Notes:
+ * encoderow is not supported
+ */
+ tif->tif_fixuptags = TWebPFixupTags;
+ tif->tif_setupdecode = TWebPSetupDecode;
+ tif->tif_predecode = TWebPPreDecode;
+ tif->tif_decoderow = TWebPDecode;
+ tif->tif_decodestrip = TWebPDecode;
+ tif->tif_decodetile = TWebPDecode;
+ tif->tif_setupencode = TWebPSetupEncode;
+ tif->tif_preencode = TWebPPreEncode;
+ tif->tif_postencode = TWebPPostEncode;
+ tif->tif_encoderow = TWebPEncode;
+ tif->tif_encodestrip = TWebPEncode;
+ tif->tif_encodetile = TWebPEncode;
+ tif->tif_cleanup = TWebPCleanup;
+
+ return 1;
+bad:
+ TIFFErrorExtR(tif, module, "No space for WebP state block");
+ return 0;
+}
+
+#endif /* WEBP_SUPPORT */
diff --git a/contrib/libs/libtiff/tif_win32.c b/contrib/libs/libtiff/tif_win32.c
new file mode 100644
index 0000000000..1a6b86dffb
--- /dev/null
+++ b/contrib/libs/libtiff/tif_win32.c
@@ -0,0 +1,442 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library Win32-specific Routines. Adapted from tif_unix.c 4/5/95 by
+ * Scott Wagner (wagner@itek.com), Itek Graphix, Rochester, NY USA
+ */
+
+#include "tiffiop.h"
+#include <stdlib.h>
+
+#include <windows.h>
+
+/*
+ CreateFileA/CreateFileW return type 'HANDLE' while TIFFFdOpen() takes 'int',
+ which is formally incompatible and can even seemingly be of different size:
+ HANDLE is 64 bit under Win64, while int is still 32 bits there.
+
+ However, only the lower 32 bits of a HANDLE are significant under Win64 as,
+ for interoperability reasons, they must have the same values in 32- and
+ 64-bit programs running on the same system, see
+
+ https://docs.microsoft.com/en-us/windows/win32/winprog64/interprocess-communication
+
+ Because of this, it is safe to define the following trivial functions for
+ casting between ints and HANDLEs, which are only really needed to avoid
+ compiler warnings (and, perhaps, to make the code slightly more clear).
+ Note that using the intermediate cast to "intptr_t" is crucial for warning
+ avoidance, as this integer type has the same size as HANDLE in all builds.
+*/
+
+static inline thandle_t thandle_from_int(int ifd)
+{
+ return (thandle_t)(intptr_t)ifd;
+}
+
+static inline int thandle_to_int(thandle_t fd) { return (int)(intptr_t)fd; }
+
+static tmsize_t _tiffReadProc(thandle_t fd, void *buf, tmsize_t size)
+{
+ /* tmsize_t is 64bit on 64bit systems, but the WinAPI ReadFile takes
+ * 32bit sizes, so we loop through the data in suitable 32bit sized
+ * chunks */
+ uint8_t *ma;
+ uint64_t mb;
+ DWORD n;
+ DWORD o;
+ tmsize_t p;
+ ma = (uint8_t *)buf;
+ mb = size;
+ p = 0;
+ while (mb > 0)
+ {
+ n = 0x80000000UL;
+ if ((uint64_t)n > mb)
+ n = (DWORD)mb;
+ if (!ReadFile(fd, (LPVOID)ma, n, &o, NULL))
+ return (0);
+ ma += o;
+ mb -= o;
+ p += o;
+ if (o != n)
+ break;
+ }
+ return (p);
+}
+
+static tmsize_t _tiffWriteProc(thandle_t fd, void *buf, tmsize_t size)
+{
+ /* tmsize_t is 64bit on 64bit systems, but the WinAPI WriteFile takes
+ * 32bit sizes, so we loop through the data in suitable 32bit sized
+ * chunks */
+ uint8_t *ma;
+ uint64_t mb;
+ DWORD n;
+ DWORD o;
+ tmsize_t p;
+ ma = (uint8_t *)buf;
+ mb = size;
+ p = 0;
+ while (mb > 0)
+ {
+ n = 0x80000000UL;
+ if ((uint64_t)n > mb)
+ n = (DWORD)mb;
+ if (!WriteFile(fd, (LPVOID)ma, n, &o, NULL))
+ return (0);
+ ma += o;
+ mb -= o;
+ p += o;
+ if (o != n)
+ break;
+ }
+ return (p);
+}
+
+static uint64_t _tiffSeekProc(thandle_t fd, uint64_t off, int whence)
+{
+ LARGE_INTEGER offli;
+ DWORD dwMoveMethod;
+ offli.QuadPart = off;
+ switch (whence)
+ {
+ case SEEK_SET:
+ dwMoveMethod = FILE_BEGIN;
+ break;
+ case SEEK_CUR:
+ dwMoveMethod = FILE_CURRENT;
+ break;
+ case SEEK_END:
+ dwMoveMethod = FILE_END;
+ break;
+ default:
+ dwMoveMethod = FILE_BEGIN;
+ break;
+ }
+ offli.LowPart =
+ SetFilePointer(fd, offli.LowPart, &offli.HighPart, dwMoveMethod);
+ if ((offli.LowPart == INVALID_SET_FILE_POINTER) &&
+ (GetLastError() != NO_ERROR))
+ offli.QuadPart = 0;
+ return (offli.QuadPart);
+}
+
+static int _tiffCloseProc(thandle_t fd) { return (CloseHandle(fd) ? 0 : -1); }
+
+static uint64_t _tiffSizeProc(thandle_t fd)
+{
+ LARGE_INTEGER m;
+ if (GetFileSizeEx(fd, &m))
+ return (m.QuadPart);
+ else
+ return (0);
+}
+
+static int _tiffDummyMapProc(thandle_t fd, void **pbase, toff_t *psize)
+{
+ (void)fd;
+ (void)pbase;
+ (void)psize;
+ return (0);
+}
+
+/*
+ * From "Hermann Josef Hill" <lhill@rhein-zeitung.de>:
+ *
+ * Windows uses both a handle and a pointer for file mapping,
+ * but according to the SDK documentation and Richter's book
+ * "Advanced Windows Programming" it is safe to free the handle
+ * after obtaining the file mapping pointer
+ *
+ * This removes a nasty OS dependency and cures a problem
+ * with Visual C++ 5.0
+ */
+static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize)
+{
+ uint64_t size;
+ tmsize_t sizem;
+ HANDLE hMapFile;
+
+ size = _tiffSizeProc(fd);
+ sizem = (tmsize_t)size;
+ if (!size || (uint64_t)sizem != size)
+ return (0);
+
+ /* By passing in 0 for the maximum file size, it specifies that we
+ create a file mapping object for the full file size. */
+ hMapFile = CreateFileMapping(fd, NULL, PAGE_READONLY, 0, 0, NULL);
+ if (hMapFile == NULL)
+ return (0);
+ *pbase = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0);
+ CloseHandle(hMapFile);
+ if (*pbase == NULL)
+ return (0);
+ *psize = size;
+ return (1);
+}
+
+static void _tiffDummyUnmapProc(thandle_t fd, void *base, toff_t size)
+{
+ (void)fd;
+ (void)base;
+ (void)size;
+}
+
+static void _tiffUnmapProc(thandle_t fd, void *base, toff_t size)
+{
+ (void)fd;
+ (void)size;
+ UnmapViewOfFile(base);
+}
+
+/*
+ * Open a TIFF file descriptor for read/writing.
+ * Note that TIFFFdOpen and TIFFOpen recognise the character 'u' in the mode
+ * string, which forces the file to be opened unmapped.
+ */
+TIFF *TIFFFdOpen(int ifd, const char *name, const char *mode)
+{
+ return TIFFFdOpenExt(ifd, name, mode, NULL);
+}
+
+TIFF *TIFFFdOpenExt(int ifd, const char *name, const char *mode,
+ TIFFOpenOptions *opts)
+{
+ TIFF *tif;
+ int fSuppressMap;
+ int m;
+
+ fSuppressMap = 0;
+ for (m = 0; mode[m] != 0; m++)
+ {
+ if (mode[m] == 'u')
+ {
+ fSuppressMap = 1;
+ break;
+ }
+ }
+
+ tif = TIFFClientOpenExt(
+ name, mode, thandle_from_int(ifd), _tiffReadProc, _tiffWriteProc,
+ _tiffSeekProc, _tiffCloseProc, _tiffSizeProc,
+ fSuppressMap ? _tiffDummyMapProc : _tiffMapProc,
+ fSuppressMap ? _tiffDummyUnmapProc : _tiffUnmapProc, opts);
+ if (tif)
+ tif->tif_fd = ifd;
+ return (tif);
+}
+
+#ifndef _WIN32_WCE
+
+/*
+ * Open a TIFF file for read/writing.
+ */
+TIFF *TIFFOpen(const char *name, const char *mode)
+{
+ return TIFFOpenExt(name, mode, NULL);
+}
+
+TIFF *TIFFOpenExt(const char *name, const char *mode, TIFFOpenOptions *opts)
+{
+ static const char module[] = "TIFFOpen";
+ thandle_t fd;
+ int m;
+ DWORD dwMode;
+ TIFF *tif;
+
+ m = _TIFFgetMode(opts, NULL, mode, module);
+
+ switch (m)
+ {
+ case O_RDONLY:
+ dwMode = OPEN_EXISTING;
+ break;
+ case O_RDWR:
+ dwMode = OPEN_EXISTING;
+ break;
+ case O_RDWR | O_CREAT:
+ dwMode = OPEN_ALWAYS;
+ break;
+ case O_RDWR | O_TRUNC:
+ dwMode = CREATE_ALWAYS;
+ break;
+ case O_RDWR | O_CREAT | O_TRUNC:
+ dwMode = CREATE_ALWAYS;
+ break;
+ default:
+ return ((TIFF *)0);
+ }
+
+ fd = (thandle_t)CreateFileA(
+ name, (m == O_RDONLY) ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE),
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode,
+ (m == O_RDONLY) ? FILE_ATTRIBUTE_READONLY : FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (fd == INVALID_HANDLE_VALUE)
+ {
+ _TIFFErrorEarly(opts, NULL, module, "%s: Cannot open", name);
+ return ((TIFF *)0);
+ }
+
+ tif = TIFFFdOpenExt(thandle_to_int(fd), name, mode, opts);
+ if (!tif)
+ CloseHandle(fd);
+ return tif;
+}
+
+/*
+ * Open a TIFF file with a Unicode filename, for read/writing.
+ */
+TIFF *TIFFOpenW(const wchar_t *name, const char *mode)
+{
+ return TIFFOpenWExt(name, mode, NULL);
+}
+
+TIFF *TIFFOpenWExt(const wchar_t *name, const char *mode, TIFFOpenOptions *opts)
+{
+ static const char module[] = "TIFFOpenW";
+ thandle_t fd;
+ int m;
+ DWORD dwMode;
+ int mbsize;
+ char *mbname;
+ TIFF *tif;
+
+ m = _TIFFgetMode(opts, NULL, mode, module);
+
+ switch (m)
+ {
+ case O_RDONLY:
+ dwMode = OPEN_EXISTING;
+ break;
+ case O_RDWR:
+ dwMode = OPEN_EXISTING;
+ break;
+ case O_RDWR | O_CREAT:
+ dwMode = OPEN_ALWAYS;
+ break;
+ case O_RDWR | O_TRUNC:
+ dwMode = CREATE_ALWAYS;
+ break;
+ case O_RDWR | O_CREAT | O_TRUNC:
+ dwMode = CREATE_ALWAYS;
+ break;
+ default:
+ return ((TIFF *)0);
+ }
+
+ fd = (thandle_t)CreateFileW(
+ name, (m == O_RDONLY) ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE),
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode,
+ (m == O_RDONLY) ? FILE_ATTRIBUTE_READONLY : FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (fd == INVALID_HANDLE_VALUE)
+ {
+ _TIFFErrorEarly(opts, NULL, module, "%S: Cannot open", name);
+ return ((TIFF *)0);
+ }
+
+ mbname = NULL;
+ mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL);
+ if (mbsize > 0)
+ {
+ mbname = (char *)_TIFFmalloc(mbsize);
+ if (!mbname)
+ {
+ _TIFFErrorEarly(
+ opts, NULL, module,
+ "Can't allocate space for filename conversion buffer");
+ return ((TIFF *)0);
+ }
+
+ WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize, NULL, NULL);
+ }
+
+ tif = TIFFFdOpenExt(thandle_to_int(fd),
+ (mbname != NULL) ? mbname : "<unknown>", mode, opts);
+ if (!tif)
+ CloseHandle(fd);
+
+ _TIFFfree(mbname);
+
+ return tif;
+}
+
+#endif /* ndef _WIN32_WCE */
+
+void *_TIFFmalloc(tmsize_t s)
+{
+ if (s == 0)
+ return ((void *)NULL);
+
+ return (malloc((size_t)s));
+}
+
+void *_TIFFcalloc(tmsize_t nmemb, tmsize_t siz)
+{
+ if (nmemb == 0 || siz == 0)
+ return ((void *)NULL);
+
+ return calloc((size_t)nmemb, (size_t)siz);
+}
+
+void _TIFFfree(void *p) { free(p); }
+
+void *_TIFFrealloc(void *p, tmsize_t s) { return (realloc(p, (size_t)s)); }
+
+void _TIFFmemset(void *p, int v, tmsize_t c) { memset(p, v, (size_t)c); }
+
+void _TIFFmemcpy(void *d, const void *s, tmsize_t c)
+{
+ memcpy(d, s, (size_t)c);
+}
+
+int _TIFFmemcmp(const void *p1, const void *p2, tmsize_t c)
+{
+ return (memcmp(p1, p2, (size_t)c));
+}
+
+#ifndef _WIN32_WCE
+
+static void Win32WarningHandler(const char *module, const char *fmt, va_list ap)
+{
+ if (module != NULL)
+ fprintf(stderr, "%s: ", module);
+ fprintf(stderr, "Warning, ");
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, ".\n");
+}
+TIFFErrorHandler _TIFFwarningHandler = Win32WarningHandler;
+
+static void Win32ErrorHandler(const char *module, const char *fmt, va_list ap)
+{
+ if (module != NULL)
+ fprintf(stderr, "%s: ", module);
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, ".\n");
+}
+TIFFErrorHandler _TIFFerrorHandler = Win32ErrorHandler;
+
+#endif /* ndef _WIN32_WCE */
diff --git a/contrib/libs/libtiff/tif_write.c b/contrib/libs/libtiff/tif_write.c
new file mode 100644
index 0000000000..6631a782fd
--- /dev/null
+++ b/contrib/libs/libtiff/tif_write.c
@@ -0,0 +1,960 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Scanline-oriented Write Support
+ */
+#include "tiffiop.h"
+#include <stdio.h>
+
+#define STRIPINCR 20 /* expansion factor on strip array */
+
+#define WRITECHECKSTRIPS(tif, module) \
+ (((tif)->tif_flags & TIFF_BEENWRITING) || TIFFWriteCheck((tif), 0, module))
+#define WRITECHECKTILES(tif, module) \
+ (((tif)->tif_flags & TIFF_BEENWRITING) || TIFFWriteCheck((tif), 1, module))
+#define BUFFERCHECK(tif) \
+ ((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) || \
+ TIFFWriteBufferSetup((tif), NULL, (tmsize_t)-1))
+
+static int TIFFGrowStrips(TIFF *tif, uint32_t delta, const char *module);
+static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
+ tmsize_t cc);
+
+int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
+{
+ static const char module[] = "TIFFWriteScanline";
+ register TIFFDirectory *td;
+ int status, imagegrew = 0;
+ uint32_t strip;
+
+ if (!WRITECHECKSTRIPS(tif, module))
+ return (-1);
+ /*
+ * Handle delayed allocation of data buffer. This
+ * permits it to be sized more intelligently (using
+ * directory information).
+ */
+ if (!BUFFERCHECK(tif))
+ return (-1);
+ tif->tif_flags |= TIFF_BUF4WRITE; /* not strictly sure this is right*/
+
+ td = &tif->tif_dir;
+ /*
+ * Extend image length if needed
+ * (but only for PlanarConfig=1).
+ */
+ if (row >= td->td_imagelength)
+ { /* extend image */
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
+ {
+ TIFFErrorExtR(
+ tif, module,
+ "Can not change \"ImageLength\" when using separate planes");
+ return (-1);
+ }
+ td->td_imagelength = row + 1;
+ imagegrew = 1;
+ }
+ /*
+ * Calculate strip and check for crossings.
+ */
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
+ {
+ if (sample >= td->td_samplesperpixel)
+ {
+ TIFFErrorExtR(tif, module, "%lu: Sample out of range, max %lu",
+ (unsigned long)sample,
+ (unsigned long)td->td_samplesperpixel);
+ return (-1);
+ }
+ strip = sample * td->td_stripsperimage + row / td->td_rowsperstrip;
+ }
+ else
+ strip = row / td->td_rowsperstrip;
+ /*
+ * Check strip array to make sure there's space. We don't support
+ * dynamically growing files that have data organized in separate
+ * bitplanes because it's too painful. In that case we require that
+ * the imagelength be set properly before the first write (so that the
+ * strips array will be fully allocated above).
+ */
+ if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module))
+ return (-1);
+ if (strip != tif->tif_curstrip)
+ {
+ /*
+ * Changing strips -- flush any data present.
+ */
+ if (!TIFFFlushData(tif))
+ return (-1);
+ tif->tif_curstrip = strip;
+ /*
+ * Watch out for a growing image. The value of strips/image
+ * will initially be 1 (since it can't be deduced until the
+ * imagelength is known).
+ */
+ if (strip >= td->td_stripsperimage && imagegrew)
+ td->td_stripsperimage =
+ TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);
+ if (td->td_stripsperimage == 0)
+ {
+ TIFFErrorExtR(tif, module, "Zero strips per image");
+ return (-1);
+ }
+ tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
+ if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
+ {
+ if (!(*tif->tif_setupencode)(tif))
+ return (-1);
+ tif->tif_flags |= TIFF_CODERSETUP;
+ }
+
+ tif->tif_rawcc = 0;
+ tif->tif_rawcp = tif->tif_rawdata;
+
+ /* this informs TIFFAppendToStrip() we have changed strip */
+ tif->tif_curoff = 0;
+
+ if (!(*tif->tif_preencode)(tif, sample))
+ return (-1);
+ tif->tif_flags |= TIFF_POSTENCODE;
+ }
+ /*
+ * Ensure the write is either sequential or at the
+ * beginning of a strip (or that we can randomly
+ * access the data -- i.e. no encoding).
+ */
+ if (row != tif->tif_row)
+ {
+ if (row < tif->tif_row)
+ {
+ /*
+ * Moving backwards within the same strip:
+ * backup to the start and then decode
+ * forward (below).
+ */
+ tif->tif_row =
+ (strip % td->td_stripsperimage) * td->td_rowsperstrip;
+ tif->tif_rawcp = tif->tif_rawdata;
+ }
+ /*
+ * Seek forward to the desired row.
+ */
+ if (!(*tif->tif_seek)(tif, row - tif->tif_row))
+ return (-1);
+ tif->tif_row = row;
+ }
+
+ /* swab if needed - note that source buffer will be altered */
+ tif->tif_postdecode(tif, (uint8_t *)buf, tif->tif_scanlinesize);
+
+ status = (*tif->tif_encoderow)(tif, (uint8_t *)buf, tif->tif_scanlinesize,
+ sample);
+
+ /* we are now poised at the beginning of the next row */
+ tif->tif_row = row + 1;
+ return (status);
+}
+
+/* Make sure that at the first attempt of rewriting a tile/strip, we will have
+ */
+/* more bytes available in the output buffer than the previous byte count, */
+/* so that TIFFAppendToStrip() will detect the overflow when it is called the
+ * first */
+/* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
+static int _TIFFReserveLargeEnoughWriteBuffer(TIFF *tif, uint32_t strip_or_tile)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ if (td->td_stripbytecount_p[strip_or_tile] > 0)
+ {
+ /* The +1 is to ensure at least one extra bytes */
+ /* The +4 is because the LZW encoder flushes 4 bytes before the limit */
+ uint64_t safe_buffer_size =
+ (uint64_t)(td->td_stripbytecount_p[strip_or_tile] + 1 + 4);
+ if (tif->tif_rawdatasize <= (tmsize_t)safe_buffer_size)
+ {
+ if (!(TIFFWriteBufferSetup(
+ tif, NULL,
+ (tmsize_t)TIFFroundup_64(safe_buffer_size, 1024))))
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/*
+ * Encode the supplied data and write it to the
+ * specified strip.
+ *
+ * NB: Image length must be setup before writing.
+ */
+tmsize_t TIFFWriteEncodedStrip(TIFF *tif, uint32_t strip, void *data,
+ tmsize_t cc)
+{
+ static const char module[] = "TIFFWriteEncodedStrip";
+ TIFFDirectory *td = &tif->tif_dir;
+ uint16_t sample;
+
+ if (!WRITECHECKSTRIPS(tif, module))
+ return ((tmsize_t)-1);
+ /*
+ * Check strip array to make sure there's space.
+ * We don't support dynamically growing files that
+ * have data organized in separate bitplanes because
+ * it's too painful. In that case we require that
+ * the imagelength be set properly before the first
+ * write (so that the strips array will be fully
+ * allocated above).
+ */
+ if (strip >= td->td_nstrips)
+ {
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
+ {
+ TIFFErrorExtR(
+ tif, module,
+ "Can not grow image by strips when using separate planes");
+ return ((tmsize_t)-1);
+ }
+ if (!TIFFGrowStrips(tif, 1, module))
+ return ((tmsize_t)-1);
+ td->td_stripsperimage =
+ TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);
+ }
+ /*
+ * Handle delayed allocation of data buffer. This
+ * permits it to be sized according to the directory
+ * info.
+ */
+ if (!BUFFERCHECK(tif))
+ 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));
+ }
+
+ tif->tif_rawcc = 0;
+ tif->tif_rawcp = tif->tif_rawdata;
+
+ if (td->td_stripsperimage == 0)
+ {
+ TIFFErrorExtR(tif, module, "Zero strips per image");
+ return ((tmsize_t)-1);
+ }
+
+ tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
+ if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
+ {
+ if (!(*tif->tif_setupencode)(tif))
+ return ((tmsize_t)-1);
+ tif->tif_flags |= TIFF_CODERSETUP;
+ }
+
+ tif->tif_flags &= ~TIFF_POSTENCODE;
+
+ /* shortcut to avoid an extra memcpy() */
+ if (td->td_compression == COMPRESSION_NONE)
+ {
+ /* swab if needed - note that source buffer will be altered */
+ tif->tif_postdecode(tif, (uint8_t *)data, cc);
+
+ if (!isFillOrder(tif, td->td_fillorder) &&
+ (tif->tif_flags & TIFF_NOBITREV) == 0)
+ TIFFReverseBits((uint8_t *)data, cc);
+
+ if (cc > 0 && !TIFFAppendToStrip(tif, strip, (uint8_t *)data, cc))
+ return ((tmsize_t)-1);
+ return (cc);
+ }
+
+ sample = (uint16_t)(strip / td->td_stripsperimage);
+ if (!(*tif->tif_preencode)(tif, sample))
+ return ((tmsize_t)-1);
+
+ /* swab if needed - note that source buffer will be altered */
+ tif->tif_postdecode(tif, (uint8_t *)data, cc);
+
+ if (!(*tif->tif_encodestrip)(tif, (uint8_t *)data, cc, sample))
+ return ((tmsize_t)-1);
+ if (!(*tif->tif_postencode)(tif))
+ return ((tmsize_t)-1);
+ if (!isFillOrder(tif, td->td_fillorder) &&
+ (tif->tif_flags & TIFF_NOBITREV) == 0)
+ TIFFReverseBits(tif->tif_rawdata, tif->tif_rawcc);
+ if (tif->tif_rawcc > 0 &&
+ !TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc))
+ return ((tmsize_t)-1);
+ tif->tif_rawcc = 0;
+ tif->tif_rawcp = tif->tif_rawdata;
+ return (cc);
+}
+
+/*
+ * Write the supplied data to the specified strip.
+ *
+ * NB: Image length must be setup before writing.
+ */
+tmsize_t TIFFWriteRawStrip(TIFF *tif, uint32_t strip, void *data, tmsize_t cc)
+{
+ static const char module[] = "TIFFWriteRawStrip";
+ TIFFDirectory *td = &tif->tif_dir;
+
+ if (!WRITECHECKSTRIPS(tif, module))
+ return ((tmsize_t)-1);
+ /*
+ * Check strip array to make sure there's space.
+ * We don't support dynamically growing files that
+ * have data organized in separate bitplanes because
+ * it's too painful. In that case we require that
+ * the imagelength be set properly before the first
+ * write (so that the strips array will be fully
+ * allocated above).
+ */
+ if (strip >= td->td_nstrips)
+ {
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
+ {
+ TIFFErrorExtR(
+ tif, module,
+ "Can not grow image by strips when using separate planes");
+ return ((tmsize_t)-1);
+ }
+ /*
+ * Watch out for a growing image. The value of
+ * strips/image will initially be 1 (since it
+ * can't be deduced until the imagelength is known).
+ */
+ if (strip >= td->td_stripsperimage)
+ td->td_stripsperimage =
+ TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);
+ if (!TIFFGrowStrips(tif, 1, module))
+ return ((tmsize_t)-1);
+ }
+
+ if (tif->tif_curstrip != strip)
+ {
+ tif->tif_curstrip = strip;
+
+ /* this informs TIFFAppendToStrip() we have changed or reset strip */
+ tif->tif_curoff = 0;
+ }
+
+ if (td->td_stripsperimage == 0)
+ {
+ TIFFErrorExtR(tif, module, "Zero strips per image");
+ return ((tmsize_t)-1);
+ }
+ tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
+ return (TIFFAppendToStrip(tif, strip, (uint8_t *)data, cc) ? cc
+ : (tmsize_t)-1);
+}
+
+/*
+ * Write and compress a tile of data. The
+ * tile is selected by the (x,y,z,s) coordinates.
+ */
+tmsize_t TIFFWriteTile(TIFF *tif, void *buf, uint32_t x, uint32_t y, uint32_t z,
+ uint16_t s)
+{
+ if (!TIFFCheckTile(tif, x, y, z, s))
+ return ((tmsize_t)(-1));
+ /*
+ * NB: A tile size of -1 is used instead of tif_tilesize knowing
+ * that TIFFWriteEncodedTile will clamp this to the tile size.
+ * This is done because the tile size may not be defined until
+ * after the output buffer is setup in TIFFWriteBufferSetup.
+ */
+ return (TIFFWriteEncodedTile(tif, TIFFComputeTile(tif, x, y, z, s), buf,
+ (tmsize_t)(-1)));
+}
+
+/*
+ * Encode the supplied data and write it to the
+ * specified tile. There must be space for the
+ * data. The function clamps individual writes
+ * to a tile to the tile size, but does not (and
+ * can not) check that multiple writes to the same
+ * tile do not write more than tile size data.
+ *
+ * NB: Image length must be setup before writing; this
+ * interface does not support automatically growing
+ * the image on each write (as TIFFWriteScanline does).
+ */
+tmsize_t TIFFWriteEncodedTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc)
+{
+ static const char module[] = "TIFFWriteEncodedTile";
+ TIFFDirectory *td;
+ uint16_t sample;
+ uint32_t howmany32;
+
+ if (!WRITECHECKTILES(tif, module))
+ return ((tmsize_t)(-1));
+ td = &tif->tif_dir;
+ if (tile >= td->td_nstrips)
+ {
+ TIFFErrorExtR(tif, module, "Tile %lu out of range, max %lu",
+ (unsigned long)tile, (unsigned long)td->td_nstrips);
+ return ((tmsize_t)(-1));
+ }
+ /*
+ * Handle delayed allocation of data buffer. This
+ * permits it to be sized more intelligently (using
+ * directory information).
+ */
+ if (!BUFFERCHECK(tif))
+ 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));
+ }
+
+ tif->tif_rawcc = 0;
+ tif->tif_rawcp = tif->tif_rawdata;
+
+ /*
+ * Compute tiles per row & per column to compute
+ * current row and column
+ */
+ howmany32 = TIFFhowmany_32(td->td_imagelength, td->td_tilelength);
+ if (howmany32 == 0)
+ {
+ TIFFErrorExtR(tif, module, "Zero tiles");
+ return ((tmsize_t)(-1));
+ }
+ tif->tif_row = (tile % howmany32) * td->td_tilelength;
+ howmany32 = TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth);
+ if (howmany32 == 0)
+ {
+ TIFFErrorExtR(tif, module, "Zero tiles");
+ return ((tmsize_t)(-1));
+ }
+ tif->tif_col = (tile % howmany32) * td->td_tilewidth;
+
+ if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
+ {
+ if (!(*tif->tif_setupencode)(tif))
+ return ((tmsize_t)(-1));
+ tif->tif_flags |= TIFF_CODERSETUP;
+ }
+ tif->tif_flags &= ~TIFF_POSTENCODE;
+
+ /*
+ * Clamp write amount to the tile size. This is mostly
+ * done so that callers can pass in some large number
+ * (e.g. -1) and have the tile size used instead.
+ */
+ if (cc < 1 || cc > tif->tif_tilesize)
+ cc = tif->tif_tilesize;
+
+ /* shortcut to avoid an extra memcpy() */
+ if (td->td_compression == COMPRESSION_NONE)
+ {
+ /* swab if needed - note that source buffer will be altered */
+ tif->tif_postdecode(tif, (uint8_t *)data, cc);
+
+ if (!isFillOrder(tif, td->td_fillorder) &&
+ (tif->tif_flags & TIFF_NOBITREV) == 0)
+ TIFFReverseBits((uint8_t *)data, cc);
+
+ if (cc > 0 && !TIFFAppendToStrip(tif, tile, (uint8_t *)data, cc))
+ return ((tmsize_t)-1);
+ return (cc);
+ }
+
+ sample = (uint16_t)(tile / td->td_stripsperimage);
+ if (!(*tif->tif_preencode)(tif, sample))
+ return ((tmsize_t)(-1));
+ /* swab if needed - note that source buffer will be altered */
+ tif->tif_postdecode(tif, (uint8_t *)data, cc);
+
+ if (!(*tif->tif_encodetile)(tif, (uint8_t *)data, cc, sample))
+ return ((tmsize_t)-1);
+ if (!(*tif->tif_postencode)(tif))
+ return ((tmsize_t)(-1));
+ if (!isFillOrder(tif, td->td_fillorder) &&
+ (tif->tif_flags & TIFF_NOBITREV) == 0)
+ TIFFReverseBits((uint8_t *)tif->tif_rawdata, tif->tif_rawcc);
+ if (tif->tif_rawcc > 0 &&
+ !TIFFAppendToStrip(tif, tile, tif->tif_rawdata, tif->tif_rawcc))
+ return ((tmsize_t)(-1));
+ tif->tif_rawcc = 0;
+ tif->tif_rawcp = tif->tif_rawdata;
+ return (cc);
+}
+
+/*
+ * Write the supplied data to the specified strip.
+ * There must be space for the data; we don't check
+ * if strips overlap!
+ *
+ * NB: Image length must be setup before writing; this
+ * interface does not support automatically growing
+ * the image on each write (as TIFFWriteScanline does).
+ */
+tmsize_t TIFFWriteRawTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc)
+{
+ static const char module[] = "TIFFWriteRawTile";
+
+ if (!WRITECHECKTILES(tif, module))
+ return ((tmsize_t)(-1));
+ if (tile >= tif->tif_dir.td_nstrips)
+ {
+ TIFFErrorExtR(tif, module, "Tile %lu out of range, max %lu",
+ (unsigned long)tile,
+ (unsigned long)tif->tif_dir.td_nstrips);
+ return ((tmsize_t)(-1));
+ }
+ return (TIFFAppendToStrip(tif, tile, (uint8_t *)data, cc) ? cc
+ : (tmsize_t)(-1));
+}
+
+#define isUnspecified(tif, f) \
+ (TIFFFieldSet(tif, f) && (tif)->tif_dir.td_imagelength == 0)
+
+int TIFFSetupStrips(TIFF *tif)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+
+ if (isTiled(tif))
+ td->td_stripsperimage = isUnspecified(tif, FIELD_TILEDIMENSIONS)
+ ? td->td_samplesperpixel
+ : TIFFNumberOfTiles(tif);
+ else
+ td->td_stripsperimage = isUnspecified(tif, FIELD_ROWSPERSTRIP)
+ ? td->td_samplesperpixel
+ : TIFFNumberOfStrips(tif);
+ td->td_nstrips = td->td_stripsperimage;
+ /* TIFFWriteDirectoryTagData has a limitation to 0x80000000U bytes */
+ if (td->td_nstrips >=
+ 0x80000000U / ((tif->tif_flags & TIFF_BIGTIFF) ? 0x8U : 0x4U))
+ {
+ TIFFErrorExtR(tif, "TIFFSetupStrips",
+ "Too large Strip/Tile Offsets/ByteCounts arrays");
+ return 0;
+ }
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
+ td->td_stripsperimage /= td->td_samplesperpixel;
+ td->td_stripoffset_p = (uint64_t *)_TIFFCheckMalloc(
+ tif, td->td_nstrips, sizeof(uint64_t), "for \"StripOffsets\" array");
+ td->td_stripbytecount_p = (uint64_t *)_TIFFCheckMalloc(
+ tif, td->td_nstrips, sizeof(uint64_t), "for \"StripByteCounts\" array");
+ if (td->td_stripoffset_p == NULL || td->td_stripbytecount_p == NULL)
+ return (0);
+ /*
+ * Place data at the end-of-file
+ * (by setting offsets to zero).
+ */
+ _TIFFmemset(td->td_stripoffset_p, 0, td->td_nstrips * sizeof(uint64_t));
+ _TIFFmemset(td->td_stripbytecount_p, 0, td->td_nstrips * sizeof(uint64_t));
+ TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
+ TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
+ return (1);
+}
+#undef isUnspecified
+
+/*
+ * Verify file is writable and that the directory
+ * information is setup properly. In doing the latter
+ * we also "freeze" the state of the directory so
+ * that important information is not changed.
+ */
+int TIFFWriteCheck(TIFF *tif, int tiles, const char *module)
+{
+ if (tif->tif_mode == O_RDONLY)
+ {
+ TIFFErrorExtR(tif, module, "File not open for writing");
+ return (0);
+ }
+ if (tiles ^ isTiled(tif))
+ {
+ TIFFErrorExtR(tif, module,
+ tiles ? "Can not write tiles to a striped image"
+ : "Can not write scanlines to a tiled image");
+ return (0);
+ }
+
+ _TIFFFillStriles(tif);
+
+ /*
+ * On the first write verify all the required information
+ * has been setup and initialize any data structures that
+ * had to wait until directory information was set.
+ * Note that a lot of our work is assumed to remain valid
+ * because we disallow any of the important parameters
+ * from changing after we start writing (i.e. once
+ * TIFF_BEENWRITING is set, TIFFSetField will only allow
+ * the image's length to be changed).
+ */
+ if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS))
+ {
+ TIFFErrorExtR(tif, module,
+ "Must set \"ImageWidth\" before writing data");
+ return (0);
+ }
+ if (tif->tif_dir.td_stripoffset_p == NULL && !TIFFSetupStrips(tif))
+ {
+ tif->tif_dir.td_nstrips = 0;
+ TIFFErrorExtR(tif, module, "No space for %s arrays",
+ isTiled(tif) ? "tile" : "strip");
+ return (0);
+ }
+ if (isTiled(tif))
+ {
+ tif->tif_tilesize = TIFFTileSize(tif);
+ if (tif->tif_tilesize == 0)
+ return (0);
+ }
+ else
+ tif->tif_tilesize = (tmsize_t)(-1);
+ tif->tif_scanlinesize = TIFFScanlineSize(tif);
+ if (tif->tif_scanlinesize == 0)
+ return (0);
+ tif->tif_flags |= TIFF_BEENWRITING;
+
+ if (tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 &&
+ !(tif->tif_flags & TIFF_DIRTYDIRECT))
+ {
+ TIFFForceStrileArrayWriting(tif);
+ }
+
+ return (1);
+}
+
+/*
+ * Setup the raw data buffer used for encoding.
+ */
+int TIFFWriteBufferSetup(TIFF *tif, void *bp, tmsize_t size)
+{
+ static const char module[] = "TIFFWriteBufferSetup";
+
+ if (tif->tif_rawdata)
+ {
+ if (tif->tif_flags & TIFF_MYBUFFER)
+ {
+ _TIFFfreeExt(tif, tif->tif_rawdata);
+ tif->tif_flags &= ~TIFF_MYBUFFER;
+ }
+ tif->tif_rawdata = NULL;
+ }
+ if (size == (tmsize_t)(-1))
+ {
+ size = (isTiled(tif) ? tif->tif_tilesize : TIFFStripSize(tif));
+
+ /* Adds 10% margin for cases where compression would expand a bit */
+ if (size < TIFF_TMSIZE_T_MAX - size / 10)
+ size += size / 10;
+ /*
+ * Make raw data buffer at least 8K
+ */
+ if (size < 8 * 1024)
+ size = 8 * 1024;
+ bp = NULL; /* NB: force malloc */
+ }
+ if (bp == NULL)
+ {
+ bp = _TIFFmallocExt(tif, size);
+ if (bp == NULL)
+ {
+ TIFFErrorExtR(tif, module, "No space for output buffer");
+ return (0);
+ }
+ tif->tif_flags |= TIFF_MYBUFFER;
+ }
+ else
+ tif->tif_flags &= ~TIFF_MYBUFFER;
+ tif->tif_rawdata = (uint8_t *)bp;
+ tif->tif_rawdatasize = size;
+ tif->tif_rawcc = 0;
+ tif->tif_rawcp = tif->tif_rawdata;
+ tif->tif_flags |= TIFF_BUFFERSETUP;
+ return (1);
+}
+
+/*
+ * Grow the strip data structures by delta strips.
+ */
+static int TIFFGrowStrips(TIFF *tif, uint32_t delta, const char *module)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ uint64_t *new_stripoffset;
+ uint64_t *new_stripbytecount;
+
+ assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
+ new_stripoffset = (uint64_t *)_TIFFreallocExt(
+ tif, td->td_stripoffset_p, (td->td_nstrips + delta) * sizeof(uint64_t));
+ new_stripbytecount = (uint64_t *)_TIFFreallocExt(
+ tif, td->td_stripbytecount_p,
+ (td->td_nstrips + delta) * sizeof(uint64_t));
+ if (new_stripoffset == NULL || new_stripbytecount == NULL)
+ {
+ if (new_stripoffset)
+ _TIFFfreeExt(tif, new_stripoffset);
+ if (new_stripbytecount)
+ _TIFFfreeExt(tif, new_stripbytecount);
+ td->td_nstrips = 0;
+ TIFFErrorExtR(tif, module, "No space to expand strip arrays");
+ return (0);
+ }
+ td->td_stripoffset_p = new_stripoffset;
+ td->td_stripbytecount_p = new_stripbytecount;
+ _TIFFmemset(td->td_stripoffset_p + td->td_nstrips, 0,
+ delta * sizeof(uint64_t));
+ _TIFFmemset(td->td_stripbytecount_p + td->td_nstrips, 0,
+ delta * sizeof(uint64_t));
+ td->td_nstrips += delta;
+ tif->tif_flags |= TIFF_DIRTYDIRECT;
+
+ return (1);
+}
+
+/*
+ * Append the data to the specified strip.
+ */
+static int 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;
+
+ 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 &&
+ 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
+ * 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.
+ */
+ if (!SeekOK(tif, td->td_stripoffset_p[strip]))
+ {
+ TIFFErrorExtR(tif, module, "Seek error at scanline %lu",
+ (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
+ * write this strip.
+ */
+ td->td_stripoffset_p[strip] = TIFFSeekFile(tif, 0, SEEK_END);
+ tif->tif_flags |= TIFF_DIRTYSTRIP;
+ }
+
+ tif->tif_curoff = td->td_stripoffset_p[strip];
+
+ /*
+ * We are starting a fresh strip/tile, so set the size to zero.
+ */
+ old_byte_count = td->td_stripbytecount_p[strip];
+ td->td_stripbytecount_p[strip] = 0;
+ }
+
+ m = tif->tif_curoff + cc;
+ if (!(tif->tif_flags & TIFF_BIGTIFF))
+ m = (uint32_t)m;
+ if ((m < tif->tif_curoff) || (m < (uint64_t)cc))
+ {
+ TIFFErrorExtR(tif, 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)
+ {
+ TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
+ return (0);
+ }
+
+ temp = _TIFFmallocExt(tif, tempSize);
+ if (temp == NULL)
+ {
+ TIFFErrorExtR(tif, 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))
+ {
+ TIFFErrorExtR(tif, module, "Seek error");
+ _TIFFfreeExt(tif, temp);
+ return (0);
+ }
+ if (!ReadOK(tif, temp, tempSize))
+ {
+ TIFFErrorExtR(tif, module, "Cannot read");
+ _TIFFfreeExt(tif, temp);
+ return (0);
+ }
+ if (!SeekOK(tif, offsetWrite))
+ {
+ TIFFErrorExtR(tif, module, "Seek error");
+ _TIFFfreeExt(tif, temp);
+ return (0);
+ }
+ if (!WriteOK(tif, temp, tempSize))
+ {
+ TIFFErrorExtR(tif, module, "Cannot write");
+ _TIFFfreeExt(tif, temp);
+ return (0);
+ }
+ offsetRead += tempSize;
+ offsetWrite += tempSize;
+ td->td_stripbytecount_p[strip] += tempSize;
+ toCopy -= tempSize;
+ }
+ _TIFFfreeExt(tif, temp);
+
+ /* Append the data of this call */
+ offsetWrite += cc;
+ m = offsetWrite;
+ }
+
+ if (!WriteOK(tif, data, cc))
+ {
+ TIFFErrorExtR(tif, module, "Write error at scanline %lu",
+ (unsigned long)tif->tif_row);
+ return (0);
+ }
+ tif->tif_curoff = m;
+ td->td_stripbytecount_p[strip] += cc;
+
+ if ((int64_t)td->td_stripbytecount_p[strip] != old_byte_count)
+ tif->tif_flags |= TIFF_DIRTYSTRIP;
+
+ return (1);
+}
+
+/*
+ * Internal version of TIFFFlushData that can be
+ * called by ``encodestrip routines'' w/o concern
+ * for infinite recursion.
+ */
+int TIFFFlushData1(TIFF *tif)
+{
+ if (tif->tif_rawcc > 0 && tif->tif_flags & TIFF_BUF4WRITE)
+ {
+ if (!isFillOrder(tif, tif->tif_dir.td_fillorder) &&
+ (tif->tif_flags & TIFF_NOBITREV) == 0)
+ TIFFReverseBits((uint8_t *)tif->tif_rawdata, tif->tif_rawcc);
+ if (!TIFFAppendToStrip(
+ tif, isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip,
+ tif->tif_rawdata, tif->tif_rawcc))
+ {
+ /* We update those variables even in case of error since there's */
+ /* code that doesn't really check the return code of this */
+ /* function */
+ tif->tif_rawcc = 0;
+ tif->tif_rawcp = tif->tif_rawdata;
+ return (0);
+ }
+ tif->tif_rawcc = 0;
+ tif->tif_rawcp = tif->tif_rawdata;
+ }
+ return (1);
+}
+
+/*
+ * Set the current write offset. This should only be
+ * used to set the offset to a known previous location
+ * (very carefully), or to 0 so that the next write gets
+ * appended to the end of the file.
+ */
+void TIFFSetWriteOffset(TIFF *tif, toff_t off)
+{
+ tif->tif_curoff = off;
+ tif->tif_lastvalidoff = 0;
+}
diff --git a/contrib/libs/libtiff/tif_zip.c b/contrib/libs/libtiff/tif_zip.c
new file mode 100644
index 0000000000..53344f3e9d
--- /dev/null
+++ b/contrib/libs/libtiff/tif_zip.c
@@ -0,0 +1,731 @@
+/*
+ * Copyright (c) 1995-1997 Sam Leffler
+ * Copyright (c) 1995-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+#include "tiffiop.h"
+#ifdef ZIP_SUPPORT
+/*
+ * TIFF Library.
+ *
+ * ZIP (aka Deflate) Compression Support
+ *
+ * This file is an interface to the zlib library written by
+ * Jean-loup Gailly and Mark Adler. You must use version 1.0 or later
+ * of the library.
+ *
+ * Optionally, libdeflate (https://github.com/ebiggers/libdeflate) may be used
+ * to do the compression and decompression, but only for whole strips and tiles.
+ * For scanline access, zlib will be sued as a fallback.
+ */
+#include "tif_predict.h"
+#include "zlib.h"
+
+#if LIBDEFLATE_SUPPORT
+#error #include "libdeflate.h"
+#endif
+#define LIBDEFLATE_MAX_COMPRESSION_LEVEL 12
+
+#include <stdio.h>
+
+/*
+ * Sigh, ZLIB_VERSION is defined as a string so there's no
+ * way to do a proper check here. Instead we guess based
+ * on the presence of #defines that were added between the
+ * 0.95 and 1.0 distributions.
+ */
+#if !defined(Z_NO_COMPRESSION) || !defined(Z_DEFLATED)
+#error "Antiquated ZLIB software; you must use version 1.0 or later"
+#endif
+
+#define SAFE_MSG(sp) ((sp)->stream.msg == NULL ? "" : (sp)->stream.msg)
+
+/*
+ * State block for each open TIFF
+ * file using ZIP compression/decompression.
+ */
+typedef struct
+{
+ TIFFPredictorState predict;
+ z_stream stream;
+ int zipquality; /* compression level */
+ int state; /* state flags */
+ int subcodec; /* DEFLATE_SUBCODEC_ZLIB or DEFLATE_SUBCODEC_LIBDEFLATE */
+#if LIBDEFLATE_SUPPORT
+ int libdeflate_state; /* -1 = until first time ZIPEncode() / ZIPDecode() is
+ called, 0 = use zlib, 1 = use libdeflate */
+ struct libdeflate_decompressor *libdeflate_dec;
+ struct libdeflate_compressor *libdeflate_enc;
+#endif
+#define ZSTATE_INIT_DECODE 0x01
+#define ZSTATE_INIT_ENCODE 0x02
+
+ TIFFVGetMethod vgetparent; /* super-class method */
+ TIFFVSetMethod vsetparent; /* super-class method */
+} ZIPState;
+
+#define ZState(tif) ((ZIPState *)(tif)->tif_data)
+#define DecoderState(tif) ZState(tif)
+#define EncoderState(tif) ZState(tif)
+
+static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
+static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s);
+
+static int ZIPFixupTags(TIFF *tif)
+{
+ (void)tif;
+ return (1);
+}
+
+static int ZIPSetupDecode(TIFF *tif)
+{
+ static const char module[] = "ZIPSetupDecode";
+ ZIPState *sp = DecoderState(tif);
+
+ assert(sp != NULL);
+
+ /* if we were last encoding, terminate this mode */
+ if (sp->state & ZSTATE_INIT_ENCODE)
+ {
+ deflateEnd(&sp->stream);
+ sp->state = 0;
+ }
+
+ /* This function can possibly be called several times by */
+ /* PredictorSetupDecode() if this function succeeds but */
+ /* PredictorSetup() fails */
+ if ((sp->state & ZSTATE_INIT_DECODE) == 0 &&
+ inflateInit(&sp->stream) != Z_OK)
+ {
+ TIFFErrorExtR(tif, module, "%s", SAFE_MSG(sp));
+ return (0);
+ }
+ else
+ {
+ sp->state |= ZSTATE_INIT_DECODE;
+ return (1);
+ }
+}
+
+/*
+ * Setup state for decoding a strip.
+ */
+static int ZIPPreDecode(TIFF *tif, uint16_t s)
+{
+ ZIPState *sp = DecoderState(tif);
+
+ (void)s;
+ assert(sp != NULL);
+
+ if ((sp->state & ZSTATE_INIT_DECODE) == 0)
+ tif->tif_setupdecode(tif);
+
+#if LIBDEFLATE_SUPPORT
+ sp->libdeflate_state = -1;
+#endif
+ sp->stream.next_in = tif->tif_rawdata;
+ assert(sizeof(sp->stream.avail_in) == 4); /* if this assert gets raised,
+ we need to simplify this code to reflect a ZLib that is likely updated
+ to deal with 8byte memory sizes, though this code will respond
+ appropriately even before we simplify it */
+ sp->stream.avail_in = (uint64_t)tif->tif_rawcc < 0xFFFFFFFFU
+ ? (uInt)tif->tif_rawcc
+ : 0xFFFFFFFFU;
+ return (inflateReset(&sp->stream) == Z_OK);
+}
+
+static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
+{
+ static const char module[] = "ZIPDecode";
+ ZIPState *sp = DecoderState(tif);
+
+ (void)s;
+ assert(sp != NULL);
+ assert(sp->state == ZSTATE_INIT_DECODE);
+
+#if LIBDEFLATE_SUPPORT
+ if (sp->libdeflate_state == 1)
+ return 0;
+
+ /* If we have libdeflate support and we are asked to read a whole */
+ /* strip/tile, then go for using it */
+ do
+ {
+ TIFFDirectory *td = &tif->tif_dir;
+
+ if (sp->libdeflate_state == 0)
+ break;
+ if (sp->subcodec == DEFLATE_SUBCODEC_ZLIB)
+ break;
+
+ /* Check if we are in the situation where we can use libdeflate */
+ if (isTiled(tif))
+ {
+ if (TIFFTileSize64(tif) != (uint64_t)occ)
+ break;
+ }
+ else
+ {
+ uint32_t strip_height = td->td_imagelength - tif->tif_row;
+ if (strip_height > td->td_rowsperstrip)
+ strip_height = td->td_rowsperstrip;
+ if (TIFFVStripSize64(tif, strip_height) != (uint64_t)occ)
+ break;
+ }
+
+ /* Check for overflow */
+ if ((size_t)tif->tif_rawcc != (uint64_t)tif->tif_rawcc)
+ break;
+ if ((size_t)occ != (uint64_t)occ)
+ break;
+
+ /* Go for decompression using libdeflate */
+ {
+ enum libdeflate_result res;
+ if (sp->libdeflate_dec == NULL)
+ {
+ sp->libdeflate_dec = libdeflate_alloc_decompressor();
+ if (sp->libdeflate_dec == NULL)
+ {
+ break;
+ }
+ }
+
+ sp->libdeflate_state = 1;
+
+ res = libdeflate_zlib_decompress(sp->libdeflate_dec, tif->tif_rawcp,
+ (size_t)tif->tif_rawcc, op,
+ (size_t)occ, NULL);
+
+ tif->tif_rawcp += tif->tif_rawcc;
+ tif->tif_rawcc = 0;
+
+ /* We accept LIBDEFLATE_INSUFFICIENT_SPACE has a return */
+ /* There are odd files in the wild where the last strip, when */
+ /* it is smaller in height than td_rowsperstrip, actually contains
+ */
+ /* data for td_rowsperstrip lines. Just ignore that silently. */
+ if (res != LIBDEFLATE_SUCCESS &&
+ res != LIBDEFLATE_INSUFFICIENT_SPACE)
+ {
+ TIFFErrorExtR(tif, module, "Decoding error at scanline %lu",
+ (unsigned long)tif->tif_row);
+ return 0;
+ }
+
+ return 1;
+ }
+ } while (0);
+ sp->libdeflate_state = 0;
+#endif /* LIBDEFLATE_SUPPORT */
+
+ sp->stream.next_in = tif->tif_rawcp;
+
+ sp->stream.next_out = op;
+ assert(sizeof(sp->stream.avail_out) == 4); /* if this assert gets raised,
+ we need to simplify this code to reflect a ZLib that is likely updated
+ to deal with 8byte memory sizes, though this code will respond
+ appropriately even before we simplify it */
+ do
+ {
+ int state;
+ uInt avail_in_before = (uint64_t)tif->tif_rawcc <= 0xFFFFFFFFU
+ ? (uInt)tif->tif_rawcc
+ : 0xFFFFFFFFU;
+ uInt avail_out_before =
+ (uint64_t)occ < 0xFFFFFFFFU ? (uInt)occ : 0xFFFFFFFFU;
+ sp->stream.avail_in = avail_in_before;
+ sp->stream.avail_out = avail_out_before;
+ /* coverity[overrun-buffer-arg] */
+ state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
+ tif->tif_rawcc -= (avail_in_before - sp->stream.avail_in);
+ occ -= (avail_out_before - sp->stream.avail_out);
+ if (state == Z_STREAM_END)
+ break;
+ if (state == Z_DATA_ERROR)
+ {
+ TIFFErrorExtR(tif, module, "Decoding error at scanline %lu, %s",
+ (unsigned long)tif->tif_row, SAFE_MSG(sp));
+ return (0);
+ }
+ if (state != Z_OK)
+ {
+ TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp));
+ return (0);
+ }
+ } while (occ > 0);
+ if (occ != 0)
+ {
+ TIFFErrorExtR(tif, module,
+ "Not enough data at scanline %lu (short %" PRIu64
+ " bytes)",
+ (unsigned long)tif->tif_row, (uint64_t)occ);
+ return (0);
+ }
+
+ tif->tif_rawcp = sp->stream.next_in;
+
+ return (1);
+}
+
+static int ZIPSetupEncode(TIFF *tif)
+{
+ static const char module[] = "ZIPSetupEncode";
+ ZIPState *sp = EncoderState(tif);
+ int cappedQuality;
+
+ assert(sp != NULL);
+ if (sp->state & ZSTATE_INIT_DECODE)
+ {
+ inflateEnd(&sp->stream);
+ sp->state = 0;
+ }
+
+ cappedQuality = sp->zipquality;
+ if (cappedQuality > Z_BEST_COMPRESSION)
+ cappedQuality = Z_BEST_COMPRESSION;
+
+ if (deflateInit(&sp->stream, cappedQuality) != Z_OK)
+ {
+ TIFFErrorExtR(tif, module, "%s", SAFE_MSG(sp));
+ return (0);
+ }
+ else
+ {
+ sp->state |= ZSTATE_INIT_ENCODE;
+ return (1);
+ }
+}
+
+/*
+ * Reset encoding state at the start of a strip.
+ */
+static int ZIPPreEncode(TIFF *tif, uint16_t s)
+{
+ ZIPState *sp = EncoderState(tif);
+
+ (void)s;
+ assert(sp != NULL);
+ if (sp->state != ZSTATE_INIT_ENCODE)
+ tif->tif_setupencode(tif);
+
+#if LIBDEFLATE_SUPPORT
+ sp->libdeflate_state = -1;
+#endif
+ sp->stream.next_out = tif->tif_rawdata;
+ assert(sizeof(sp->stream.avail_out) == 4); /* if this assert gets raised,
+ we need to simplify this code to reflect a ZLib that is likely updated
+ to deal with 8byte memory sizes, though this code will respond
+ appropriately even before we simplify it */
+ sp->stream.avail_out = (uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU
+ ? (uInt)tif->tif_rawdatasize
+ : 0xFFFFFFFFU;
+ return (deflateReset(&sp->stream) == Z_OK);
+}
+
+/*
+ * Encode a chunk of pixels.
+ */
+static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
+{
+ static const char module[] = "ZIPEncode";
+ ZIPState *sp = EncoderState(tif);
+
+ assert(sp != NULL);
+ assert(sp->state == ZSTATE_INIT_ENCODE);
+
+ (void)s;
+
+#if LIBDEFLATE_SUPPORT
+ if (sp->libdeflate_state == 1)
+ return 0;
+
+ /* If we have libdeflate support and we are asked to write a whole */
+ /* strip/tile, then go for using it */
+ do
+ {
+ TIFFDirectory *td = &tif->tif_dir;
+
+ if (sp->libdeflate_state == 0)
+ break;
+ if (sp->subcodec == DEFLATE_SUBCODEC_ZLIB)
+ break;
+
+ /* Libdeflate does not support the 0-compression level */
+ if (sp->zipquality == Z_NO_COMPRESSION)
+ break;
+
+ /* Check if we are in the situation where we can use libdeflate */
+ if (isTiled(tif))
+ {
+ if (TIFFTileSize64(tif) != (uint64_t)cc)
+ break;
+ }
+ else
+ {
+ uint32_t strip_height = td->td_imagelength - tif->tif_row;
+ if (strip_height > td->td_rowsperstrip)
+ strip_height = td->td_rowsperstrip;
+ if (TIFFVStripSize64(tif, strip_height) != (uint64_t)cc)
+ break;
+ }
+
+ /* Check for overflow */
+ if ((size_t)tif->tif_rawdatasize != (uint64_t)tif->tif_rawdatasize)
+ break;
+ if ((size_t)cc != (uint64_t)cc)
+ break;
+
+ /* Go for compression using libdeflate */
+ {
+ size_t nCompressedBytes;
+ if (sp->libdeflate_enc == NULL)
+ {
+ /* To get results as good as zlib, we asked for an extra */
+ /* level of compression */
+ sp->libdeflate_enc = libdeflate_alloc_compressor(
+ sp->zipquality == Z_DEFAULT_COMPRESSION ? 7
+ : sp->zipquality >= 6 && sp->zipquality <= 9
+ ? sp->zipquality + 1
+ : sp->zipquality);
+ if (sp->libdeflate_enc == NULL)
+ {
+ TIFFErrorExtR(tif, module, "Cannot allocate compressor");
+ break;
+ }
+ }
+
+ /* Make sure the output buffer is large enough for the worse case.
+ */
+ /* In TIFFWriteBufferSetup(), when libtiff allocates the buffer */
+ /* we've taken a 10% margin over the uncompressed size, which should
+ */
+ /* be large enough even for the the worse case scenario. */
+ if (libdeflate_zlib_compress_bound(sp->libdeflate_enc, (size_t)cc) >
+ (size_t)tif->tif_rawdatasize)
+ {
+ break;
+ }
+
+ sp->libdeflate_state = 1;
+ nCompressedBytes = libdeflate_zlib_compress(
+ sp->libdeflate_enc, bp, (size_t)cc, tif->tif_rawdata,
+ (size_t)tif->tif_rawdatasize);
+
+ if (nCompressedBytes == 0)
+ {
+ TIFFErrorExtR(tif, module, "Encoder error at scanline %lu",
+ (unsigned long)tif->tif_row);
+ return 0;
+ }
+
+ tif->tif_rawcc = nCompressedBytes;
+
+ if (!TIFFFlushData1(tif))
+ return 0;
+
+ return 1;
+ }
+ } while (0);
+ sp->libdeflate_state = 0;
+#endif /* LIBDEFLATE_SUPPORT */
+
+ sp->stream.next_in = bp;
+ assert(sizeof(sp->stream.avail_in) == 4); /* if this assert gets raised,
+ we need to simplify this code to reflect a ZLib that is likely updated
+ to deal with 8byte memory sizes, though this code will respond
+ appropriately even before we simplify it */
+ do
+ {
+ uInt avail_in_before =
+ (uint64_t)cc <= 0xFFFFFFFFU ? (uInt)cc : 0xFFFFFFFFU;
+ sp->stream.avail_in = avail_in_before;
+ /* coverity[overrun-buffer-arg] */
+ if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK)
+ {
+ TIFFErrorExtR(tif, module, "Encoder error: %s", SAFE_MSG(sp));
+ return (0);
+ }
+ if (sp->stream.avail_out == 0)
+ {
+ tif->tif_rawcc = tif->tif_rawdatasize;
+ if (!TIFFFlushData1(tif))
+ return 0;
+ sp->stream.next_out = tif->tif_rawdata;
+ sp->stream.avail_out = (uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU
+ ? (uInt)tif->tif_rawdatasize
+ : 0xFFFFFFFFU;
+ }
+ cc -= (avail_in_before - sp->stream.avail_in);
+ } while (cc > 0);
+ return (1);
+}
+
+/*
+ * Finish off an encoded strip by flushing the last
+ * string and tacking on an End Of Information code.
+ */
+static int ZIPPostEncode(TIFF *tif)
+{
+ static const char module[] = "ZIPPostEncode";
+ ZIPState *sp = EncoderState(tif);
+ int state;
+
+#if LIBDEFLATE_SUPPORT
+ if (sp->libdeflate_state == 1)
+ return 1;
+#endif
+
+ sp->stream.avail_in = 0;
+ do
+ {
+ state = deflate(&sp->stream, Z_FINISH);
+ switch (state)
+ {
+ case Z_STREAM_END:
+ case Z_OK:
+ if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
+ {
+ tif->tif_rawcc =
+ tif->tif_rawdatasize - sp->stream.avail_out;
+ if (!TIFFFlushData1(tif))
+ return 0;
+ sp->stream.next_out = tif->tif_rawdata;
+ sp->stream.avail_out =
+ (uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU
+ ? (uInt)tif->tif_rawdatasize
+ : 0xFFFFFFFFU;
+ }
+ break;
+ default:
+ TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp));
+ return (0);
+ }
+ } while (state != Z_STREAM_END);
+ return (1);
+}
+
+static void ZIPCleanup(TIFF *tif)
+{
+ ZIPState *sp = ZState(tif);
+
+ assert(sp != 0);
+
+ (void)TIFFPredictorCleanup(tif);
+
+ tif->tif_tagmethods.vgetfield = sp->vgetparent;
+ tif->tif_tagmethods.vsetfield = sp->vsetparent;
+
+ if (sp->state & ZSTATE_INIT_ENCODE)
+ {
+ deflateEnd(&sp->stream);
+ sp->state = 0;
+ }
+ else if (sp->state & ZSTATE_INIT_DECODE)
+ {
+ inflateEnd(&sp->stream);
+ sp->state = 0;
+ }
+
+#if LIBDEFLATE_SUPPORT
+ if (sp->libdeflate_dec)
+ libdeflate_free_decompressor(sp->libdeflate_dec);
+ if (sp->libdeflate_enc)
+ libdeflate_free_compressor(sp->libdeflate_enc);
+#endif
+
+ _TIFFfreeExt(tif, sp);
+ tif->tif_data = NULL;
+
+ _TIFFSetDefaultCompressionState(tif);
+}
+
+static int ZIPVSetField(TIFF *tif, uint32_t tag, va_list ap)
+{
+ static const char module[] = "ZIPVSetField";
+ ZIPState *sp = ZState(tif);
+
+ switch (tag)
+ {
+ case TIFFTAG_ZIPQUALITY:
+ sp->zipquality = (int)va_arg(ap, int);
+ if (sp->zipquality < Z_DEFAULT_COMPRESSION ||
+ sp->zipquality > LIBDEFLATE_MAX_COMPRESSION_LEVEL)
+ {
+ TIFFErrorExtR(
+ tif, module,
+ "Invalid ZipQuality value. Should be in [-1,%d] range",
+ LIBDEFLATE_MAX_COMPRESSION_LEVEL);
+ return 0;
+ }
+
+ if (sp->state & ZSTATE_INIT_ENCODE)
+ {
+ int cappedQuality = sp->zipquality;
+ if (cappedQuality > Z_BEST_COMPRESSION)
+ cappedQuality = Z_BEST_COMPRESSION;
+ if (deflateParams(&sp->stream, cappedQuality,
+ Z_DEFAULT_STRATEGY) != Z_OK)
+ {
+ TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp));
+ return (0);
+ }
+ }
+
+#if LIBDEFLATE_SUPPORT
+ if (sp->libdeflate_enc)
+ {
+ libdeflate_free_compressor(sp->libdeflate_enc);
+ sp->libdeflate_enc = NULL;
+ }
+#endif
+
+ return (1);
+
+ case TIFFTAG_DEFLATE_SUBCODEC:
+ sp->subcodec = (int)va_arg(ap, int);
+ if (sp->subcodec != DEFLATE_SUBCODEC_ZLIB &&
+ sp->subcodec != DEFLATE_SUBCODEC_LIBDEFLATE)
+ {
+ TIFFErrorExtR(tif, module, "Invalid DeflateCodec value.");
+ return 0;
+ }
+#if !LIBDEFLATE_SUPPORT
+ if (sp->subcodec == DEFLATE_SUBCODEC_LIBDEFLATE)
+ {
+ TIFFErrorExtR(tif, module,
+ "DeflateCodec = DEFLATE_SUBCODEC_LIBDEFLATE "
+ "unsupported in this build");
+ return 0;
+ }
+#endif
+ return 1;
+
+ default:
+ return (*sp->vsetparent)(tif, tag, ap);
+ }
+ /*NOTREACHED*/
+}
+
+static int ZIPVGetField(TIFF *tif, uint32_t tag, va_list ap)
+{
+ ZIPState *sp = ZState(tif);
+
+ switch (tag)
+ {
+ case TIFFTAG_ZIPQUALITY:
+ *va_arg(ap, int *) = sp->zipquality;
+ break;
+
+ case TIFFTAG_DEFLATE_SUBCODEC:
+ *va_arg(ap, int *) = sp->subcodec;
+ break;
+
+ default:
+ return (*sp->vgetparent)(tif, tag, ap);
+ }
+ return (1);
+}
+
+static const TIFFField zipFields[] = {
+ {TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
+ TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL},
+ {TIFFTAG_DEFLATE_SUBCODEC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
+ TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL},
+};
+
+int TIFFInitZIP(TIFF *tif, int scheme)
+{
+ static const char module[] = "TIFFInitZIP";
+ ZIPState *sp;
+
+ assert((scheme == COMPRESSION_DEFLATE) ||
+ (scheme == COMPRESSION_ADOBE_DEFLATE));
+#ifdef NDEBUG
+ (void)scheme;
+#endif
+
+ /*
+ * Merge codec-specific tag information.
+ */
+ if (!_TIFFMergeFields(tif, zipFields, TIFFArrayCount(zipFields)))
+ {
+ TIFFErrorExtR(tif, module,
+ "Merging Deflate codec-specific tags failed");
+ return 0;
+ }
+
+ /*
+ * Allocate state block so tag methods have storage to record values.
+ */
+ tif->tif_data = (uint8_t *)_TIFFcallocExt(tif, sizeof(ZIPState), 1);
+ if (tif->tif_data == NULL)
+ goto bad;
+ sp = ZState(tif);
+ sp->stream.zalloc = NULL;
+ sp->stream.zfree = NULL;
+ sp->stream.opaque = NULL;
+ sp->stream.data_type = Z_BINARY;
+
+ /*
+ * Override parent get/set field methods.
+ */
+ sp->vgetparent = tif->tif_tagmethods.vgetfield;
+ tif->tif_tagmethods.vgetfield = ZIPVGetField; /* hook for codec tags */
+ sp->vsetparent = tif->tif_tagmethods.vsetfield;
+ tif->tif_tagmethods.vsetfield = ZIPVSetField; /* hook for codec tags */
+
+ /* Default values for codec-specific fields */
+ sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */
+ sp->state = 0;
+#if LIBDEFLATE_SUPPORT
+ sp->subcodec = DEFLATE_SUBCODEC_LIBDEFLATE;
+#else
+ sp->subcodec = DEFLATE_SUBCODEC_ZLIB;
+#endif
+
+ /*
+ * Install codec methods.
+ */
+ tif->tif_fixuptags = ZIPFixupTags;
+ tif->tif_setupdecode = ZIPSetupDecode;
+ tif->tif_predecode = ZIPPreDecode;
+ tif->tif_decoderow = ZIPDecode;
+ tif->tif_decodestrip = ZIPDecode;
+ tif->tif_decodetile = ZIPDecode;
+ tif->tif_setupencode = ZIPSetupEncode;
+ tif->tif_preencode = ZIPPreEncode;
+ tif->tif_postencode = ZIPPostEncode;
+ tif->tif_encoderow = ZIPEncode;
+ tif->tif_encodestrip = ZIPEncode;
+ tif->tif_encodetile = ZIPEncode;
+ tif->tif_cleanup = ZIPCleanup;
+ /*
+ * Setup predictor setup.
+ */
+ (void)TIFFPredictorInit(tif);
+ return (1);
+bad:
+ TIFFErrorExtR(tif, module, "No space for ZIP state block");
+ return (0);
+}
+#endif /* ZIP_SUPPORT */
diff --git a/contrib/libs/libtiff/tif_zstd.c b/contrib/libs/libtiff/tif_zstd.c
new file mode 100644
index 0000000000..646993103d
--- /dev/null
+++ b/contrib/libs/libtiff/tif_zstd.c
@@ -0,0 +1,436 @@
+/*
+ * Copyright (c) 2017, Planet Labs
+ * Author: <even.rouault at spatialys.com>
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+#include "tiffiop.h"
+#ifdef ZSTD_SUPPORT
+/*
+ * TIFF Library.
+ *
+ * ZSTD Compression Support
+ *
+ */
+
+#include "tif_predict.h"
+#include "zstd.h"
+
+#include <stdio.h>
+
+/*
+ * State block for each open TIFF file using ZSTD compression/decompression.
+ */
+typedef struct
+{
+ TIFFPredictorState predict;
+ ZSTD_DStream *dstream;
+ ZSTD_CStream *cstream;
+ int compression_level; /* compression level */
+ ZSTD_outBuffer out_buffer;
+ int state; /* state flags */
+#define LSTATE_INIT_DECODE 0x01
+#define LSTATE_INIT_ENCODE 0x02
+
+ TIFFVGetMethod vgetparent; /* super-class method */
+ TIFFVSetMethod vsetparent; /* super-class method */
+} ZSTDState;
+
+#define LState(tif) ((ZSTDState *)(tif)->tif_data)
+#define DecoderState(tif) LState(tif)
+#define EncoderState(tif) LState(tif)
+
+static int ZSTDEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
+static int ZSTDDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s);
+
+static int ZSTDFixupTags(TIFF *tif)
+{
+ (void)tif;
+ return 1;
+}
+
+static int ZSTDSetupDecode(TIFF *tif)
+{
+ ZSTDState *sp = DecoderState(tif);
+
+ assert(sp != NULL);
+
+ /* if we were last encoding, terminate this mode */
+ if (sp->state & LSTATE_INIT_ENCODE)
+ {
+ ZSTD_freeCStream(sp->cstream);
+ sp->cstream = NULL;
+ sp->state = 0;
+ }
+
+ sp->state |= LSTATE_INIT_DECODE;
+ return 1;
+}
+
+/*
+ * Setup state for decoding a strip.
+ */
+static int ZSTDPreDecode(TIFF *tif, uint16_t s)
+{
+ static const char module[] = "ZSTDPreDecode";
+ ZSTDState *sp = DecoderState(tif);
+ size_t zstd_ret;
+
+ (void)s;
+ assert(sp != NULL);
+
+ if ((sp->state & LSTATE_INIT_DECODE) == 0)
+ tif->tif_setupdecode(tif);
+
+ if (sp->dstream == NULL)
+ {
+ sp->dstream = ZSTD_createDStream();
+ if (sp->dstream == NULL)
+ {
+ TIFFErrorExtR(tif, module, "Cannot allocate decompression stream");
+ return 0;
+ }
+ }
+
+ zstd_ret = ZSTD_initDStream(sp->dstream);
+ if (ZSTD_isError(zstd_ret))
+ {
+ TIFFErrorExtR(tif, module, "Error in ZSTD_initDStream(): %s",
+ ZSTD_getErrorName(zstd_ret));
+ return 0;
+ }
+
+ return 1;
+}
+
+static int ZSTDDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
+{
+ static const char module[] = "ZSTDDecode";
+ ZSTDState *sp = DecoderState(tif);
+ ZSTD_inBuffer in_buffer;
+ ZSTD_outBuffer out_buffer;
+ size_t zstd_ret;
+
+ (void)s;
+ assert(sp != NULL);
+ assert(sp->state == LSTATE_INIT_DECODE);
+
+ in_buffer.src = tif->tif_rawcp;
+ in_buffer.size = (size_t)tif->tif_rawcc;
+ in_buffer.pos = 0;
+
+ out_buffer.dst = op;
+ out_buffer.size = (size_t)occ;
+ out_buffer.pos = 0;
+
+ do
+ {
+ zstd_ret = ZSTD_decompressStream(sp->dstream, &out_buffer, &in_buffer);
+ if (ZSTD_isError(zstd_ret))
+ {
+ TIFFErrorExtR(tif, module, "Error in ZSTD_decompressStream(): %s",
+ ZSTD_getErrorName(zstd_ret));
+ return 0;
+ }
+ } while (zstd_ret != 0 && in_buffer.pos < in_buffer.size &&
+ out_buffer.pos < out_buffer.size);
+
+ if (out_buffer.pos < (size_t)occ)
+ {
+ TIFFErrorExtR(tif, module,
+ "Not enough data at scanline %lu (short %lu bytes)",
+ (unsigned long)tif->tif_row,
+ (unsigned long)((size_t)occ - out_buffer.pos));
+ return 0;
+ }
+
+ tif->tif_rawcp += in_buffer.pos;
+ tif->tif_rawcc -= in_buffer.pos;
+
+ return 1;
+}
+
+static int ZSTDSetupEncode(TIFF *tif)
+{
+ ZSTDState *sp = EncoderState(tif);
+
+ assert(sp != NULL);
+ if (sp->state & LSTATE_INIT_DECODE)
+ {
+ ZSTD_freeDStream(sp->dstream);
+ sp->dstream = NULL;
+ sp->state = 0;
+ }
+
+ sp->state |= LSTATE_INIT_ENCODE;
+ return 1;
+}
+
+/*
+ * Reset encoding state at the start of a strip.
+ */
+static int ZSTDPreEncode(TIFF *tif, uint16_t s)
+{
+ static const char module[] = "ZSTDPreEncode";
+ ZSTDState *sp = EncoderState(tif);
+ size_t zstd_ret;
+
+ (void)s;
+ assert(sp != NULL);
+ if (sp->state != LSTATE_INIT_ENCODE)
+ tif->tif_setupencode(tif);
+
+ if (sp->cstream == NULL)
+ {
+ sp->cstream = ZSTD_createCStream();
+ if (sp->cstream == NULL)
+ {
+ TIFFErrorExtR(tif, module, "Cannot allocate compression stream");
+ return 0;
+ }
+ }
+
+ zstd_ret = ZSTD_initCStream(sp->cstream, sp->compression_level);
+ if (ZSTD_isError(zstd_ret))
+ {
+ TIFFErrorExtR(tif, module, "Error in ZSTD_initCStream(): %s",
+ ZSTD_getErrorName(zstd_ret));
+ return 0;
+ }
+
+ sp->out_buffer.dst = tif->tif_rawdata;
+ sp->out_buffer.size = (size_t)tif->tif_rawdatasize;
+ sp->out_buffer.pos = 0;
+
+ return 1;
+}
+
+/*
+ * Encode a chunk of pixels.
+ */
+static int ZSTDEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
+{
+ static const char module[] = "ZSTDEncode";
+ ZSTDState *sp = EncoderState(tif);
+ ZSTD_inBuffer in_buffer;
+ size_t zstd_ret;
+
+ assert(sp != NULL);
+ assert(sp->state == LSTATE_INIT_ENCODE);
+
+ (void)s;
+
+ in_buffer.src = bp;
+ in_buffer.size = (size_t)cc;
+ in_buffer.pos = 0;
+
+ do
+ {
+ zstd_ret =
+ ZSTD_compressStream(sp->cstream, &sp->out_buffer, &in_buffer);
+ if (ZSTD_isError(zstd_ret))
+ {
+ TIFFErrorExtR(tif, module, "Error in ZSTD_compressStream(): %s",
+ ZSTD_getErrorName(zstd_ret));
+ return 0;
+ }
+ if (sp->out_buffer.pos == sp->out_buffer.size)
+ {
+ tif->tif_rawcc = tif->tif_rawdatasize;
+ if (!TIFFFlushData1(tif))
+ return 0;
+ sp->out_buffer.dst = tif->tif_rawcp;
+ sp->out_buffer.pos = 0;
+ }
+ } while (in_buffer.pos < in_buffer.size);
+
+ return 1;
+}
+
+/*
+ * Finish off an encoded strip by flushing it.
+ */
+static int ZSTDPostEncode(TIFF *tif)
+{
+ static const char module[] = "ZSTDPostEncode";
+ ZSTDState *sp = EncoderState(tif);
+ size_t zstd_ret;
+
+ do
+ {
+ zstd_ret = ZSTD_endStream(sp->cstream, &sp->out_buffer);
+ if (ZSTD_isError(zstd_ret))
+ {
+ TIFFErrorExtR(tif, module, "Error in ZSTD_endStream(): %s",
+ ZSTD_getErrorName(zstd_ret));
+ return 0;
+ }
+ if (sp->out_buffer.pos > 0)
+ {
+ tif->tif_rawcc = sp->out_buffer.pos;
+ if (!TIFFFlushData1(tif))
+ return 0;
+ sp->out_buffer.dst = tif->tif_rawcp;
+ sp->out_buffer.pos = 0;
+ }
+ } while (zstd_ret != 0);
+ return 1;
+}
+
+static void ZSTDCleanup(TIFF *tif)
+{
+ ZSTDState *sp = LState(tif);
+
+ assert(sp != 0);
+
+ (void)TIFFPredictorCleanup(tif);
+
+ tif->tif_tagmethods.vgetfield = sp->vgetparent;
+ tif->tif_tagmethods.vsetfield = sp->vsetparent;
+
+ if (sp->dstream)
+ {
+ ZSTD_freeDStream(sp->dstream);
+ sp->dstream = NULL;
+ }
+ if (sp->cstream)
+ {
+ ZSTD_freeCStream(sp->cstream);
+ sp->cstream = NULL;
+ }
+ _TIFFfreeExt(tif, sp);
+ tif->tif_data = NULL;
+
+ _TIFFSetDefaultCompressionState(tif);
+}
+
+static int ZSTDVSetField(TIFF *tif, uint32_t tag, va_list ap)
+{
+ static const char module[] = "ZSTDVSetField";
+ ZSTDState *sp = LState(tif);
+
+ switch (tag)
+ {
+ case TIFFTAG_ZSTD_LEVEL:
+ sp->compression_level = (int)va_arg(ap, int);
+ if (sp->compression_level <= 0 ||
+ sp->compression_level > ZSTD_maxCLevel())
+ {
+ TIFFWarningExtR(tif, module,
+ "ZSTD_LEVEL should be between 1 and %d",
+ ZSTD_maxCLevel());
+ }
+ return 1;
+ default:
+ return (*sp->vsetparent)(tif, tag, ap);
+ }
+ /*NOTREACHED*/
+}
+
+static int ZSTDVGetField(TIFF *tif, uint32_t tag, va_list ap)
+{
+ ZSTDState *sp = LState(tif);
+
+ switch (tag)
+ {
+ case TIFFTAG_ZSTD_LEVEL:
+ *va_arg(ap, int *) = sp->compression_level;
+ break;
+ default:
+ return (*sp->vgetparent)(tif, tag, ap);
+ }
+ return 1;
+}
+
+static const TIFFField ZSTDFields[] = {
+ {TIFFTAG_ZSTD_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
+ TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "ZSTD compression_level",
+ NULL},
+};
+
+int TIFFInitZSTD(TIFF *tif, int scheme)
+{
+ static const char module[] = "TIFFInitZSTD";
+ ZSTDState *sp;
+
+ (void)scheme;
+ assert(scheme == COMPRESSION_ZSTD);
+
+ /*
+ * Merge codec-specific tag information.
+ */
+ if (!_TIFFMergeFields(tif, ZSTDFields, TIFFArrayCount(ZSTDFields)))
+ {
+ TIFFErrorExtR(tif, module, "Merging ZSTD codec-specific tags failed");
+ return 0;
+ }
+
+ /*
+ * Allocate state block so tag methods have storage to record values.
+ */
+ tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(ZSTDState));
+ if (tif->tif_data == NULL)
+ goto bad;
+ sp = LState(tif);
+
+ /*
+ * Override parent get/set field methods.
+ */
+ sp->vgetparent = tif->tif_tagmethods.vgetfield;
+ tif->tif_tagmethods.vgetfield = ZSTDVGetField; /* hook for codec tags */
+ sp->vsetparent = tif->tif_tagmethods.vsetfield;
+ tif->tif_tagmethods.vsetfield = ZSTDVSetField; /* hook for codec tags */
+
+ /* Default values for codec-specific fields */
+ sp->compression_level = 9; /* default comp. level */
+ sp->state = 0;
+ sp->dstream = 0;
+ sp->cstream = 0;
+ sp->out_buffer.dst = NULL;
+ sp->out_buffer.size = 0;
+ sp->out_buffer.pos = 0;
+
+ /*
+ * Install codec methods.
+ */
+ tif->tif_fixuptags = ZSTDFixupTags;
+ tif->tif_setupdecode = ZSTDSetupDecode;
+ tif->tif_predecode = ZSTDPreDecode;
+ tif->tif_decoderow = ZSTDDecode;
+ tif->tif_decodestrip = ZSTDDecode;
+ tif->tif_decodetile = ZSTDDecode;
+ tif->tif_setupencode = ZSTDSetupEncode;
+ tif->tif_preencode = ZSTDPreEncode;
+ tif->tif_postencode = ZSTDPostEncode;
+ tif->tif_encoderow = ZSTDEncode;
+ tif->tif_encodestrip = ZSTDEncode;
+ tif->tif_encodetile = ZSTDEncode;
+ tif->tif_cleanup = ZSTDCleanup;
+ /*
+ * Setup predictor setup.
+ */
+ (void)TIFFPredictorInit(tif);
+ return 1;
+bad:
+ TIFFErrorExtR(tif, module, "No space for ZSTD state block");
+ return 0;
+}
+#endif /* ZSTD_SUPPORT */
diff --git a/contrib/libs/libtiff/tiff.h b/contrib/libs/libtiff/tiff.h
new file mode 100644
index 0000000000..b2d118668f
--- /dev/null
+++ b/contrib/libs/libtiff/tiff.h
@@ -0,0 +1,898 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _TIFF_
+#define _TIFF_
+
+#include "tiffconf.h"
+
+/*
+ * Tag Image File Format (TIFF)
+ *
+ * Based on Rev 6.0 from:
+ * Developer's Desk
+ * Aldus Corporation
+ * 411 First Ave. South
+ * Suite 200
+ * Seattle, WA 98104
+ * 206-622-5500
+ *
+ * (http://partners.adobe.com/asn/developer/PDFS/TN/TIFF6.pdf)
+ *
+ * For BigTIFF design notes see the following links
+ * http://www.remotesensing.org/libtiff/bigtiffdesign.html
+ * http://www.awaresystems.be/imaging/tiff/bigtiff.html
+ */
+
+#define TIFF_VERSION_CLASSIC 42
+#define TIFF_VERSION_BIG 43
+
+#define TIFF_BIGENDIAN 0x4d4d
+#define TIFF_LITTLEENDIAN 0x4949
+#define MDI_LITTLEENDIAN 0x5045
+#define MDI_BIGENDIAN 0x4550
+
+/*
+ * Intrinsic data types required by the file format:
+ *
+ * 8-bit quantities int8_t/uint_8_t
+ * 16-bit quantities int16_t/uint_16_t
+ * 32-bit quantities int32_t/uint_32_t
+ * 64-bit quantities int64_t/uint_64_t
+ * strings unsigned char*
+ */
+#ifdef __GNUC__
+#define TIFF_GCC_DEPRECATED __attribute__((deprecated))
+#else
+#define TIFF_GCC_DEPRECATED
+#endif
+#ifdef _MSC_VER
+#define TIFF_MSC_DEPRECATED \
+ __declspec(deprecated("libtiff type deprecated; please use corresponding " \
+ "C99 stdint.h type"))
+#else
+#define TIFF_MSC_DEPRECATED
+#endif
+
+#ifndef TIFF_DISABLE_DEPRECATED
+typedef TIFF_MSC_DEPRECATED int8_t int8 TIFF_GCC_DEPRECATED;
+typedef TIFF_MSC_DEPRECATED uint8_t uint8 TIFF_GCC_DEPRECATED;
+
+typedef TIFF_MSC_DEPRECATED int16_t int16 TIFF_GCC_DEPRECATED;
+typedef TIFF_MSC_DEPRECATED uint16_t uint16 TIFF_GCC_DEPRECATED;
+
+typedef TIFF_MSC_DEPRECATED int32_t int32 TIFF_GCC_DEPRECATED;
+typedef TIFF_MSC_DEPRECATED uint32_t uint32 TIFF_GCC_DEPRECATED;
+
+typedef TIFF_MSC_DEPRECATED int64_t int64 TIFF_GCC_DEPRECATED;
+typedef TIFF_MSC_DEPRECATED uint64_t uint64 TIFF_GCC_DEPRECATED;
+#endif /* TIFF_DISABLE_DEPRECATED */
+
+/*
+ * Some types as promoted in a variable argument list
+ * We use uint16_vap rather then directly using int, because this way
+ * we document the type we actually want to pass through, conceptually,
+ * rather then confusing the issue by merely stating the type it gets
+ * promoted to
+ */
+
+typedef int uint16_vap;
+
+/*
+ * TIFF header.
+ */
+typedef struct
+{
+ uint16_t tiff_magic; /* magic number (defines byte order) */
+ uint16_t tiff_version; /* TIFF version number */
+} TIFFHeaderCommon;
+typedef struct
+{
+ uint16_t tiff_magic; /* magic number (defines byte order) */
+ uint16_t tiff_version; /* TIFF version number */
+ uint32_t tiff_diroff; /* byte offset to first directory */
+} TIFFHeaderClassic;
+typedef struct
+{
+ uint16_t tiff_magic; /* magic number (defines byte order) */
+ uint16_t tiff_version; /* TIFF version number */
+ uint16_t tiff_offsetsize; /* size of offsets, should be 8 */
+ uint16_t tiff_unused; /* unused word, should be 0 */
+ uint64_t tiff_diroff; /* byte offset to first directory */
+} TIFFHeaderBig;
+
+/*
+ * NB: In the comments below,
+ * - items marked with a + are obsoleted by revision 5.0,
+ * - items marked with a ! are introduced in revision 6.0.
+ * - items marked with a % are introduced post revision 6.0.
+ * - items marked with a $ are obsoleted by revision 6.0.
+ * - items marked with a & are introduced by Adobe DNG specification.
+ */
+
+/*
+ * Tag data type information.
+ *
+ * Note: RATIONALs are the ratio of two 32-bit integer values.
+ *--:
+ * Note2: TIFF_IFD8 data type is used in tiffFields[]-tag definition in order to
+ distinguish the write-handling of those tags between ClassicTIFF and BigTiff:
+ For ClassicTIFF libtiff writes a 32-bit value and the TIFF_IFD
+ type-id into the file For BigTIFF libtiff writes a 64-bit value and the
+ TIFF_IFD8 type-id into the file
+ */
+typedef enum
+{
+ TIFF_NOTYPE = 0, /* placeholder */
+ TIFF_BYTE = 1, /* 8-bit unsigned integer */
+ TIFF_ASCII = 2, /* 8-bit bytes w/ last byte null */
+ TIFF_SHORT = 3, /* 16-bit unsigned integer */
+ TIFF_LONG = 4, /* 32-bit unsigned integer */
+ TIFF_RATIONAL = 5, /* 64-bit unsigned fraction */
+ TIFF_SBYTE = 6, /* !8-bit signed integer */
+ TIFF_UNDEFINED = 7, /* !8-bit untyped data */
+ TIFF_SSHORT = 8, /* !16-bit signed integer */
+ TIFF_SLONG = 9, /* !32-bit signed integer */
+ TIFF_SRATIONAL = 10, /* !64-bit signed fraction */
+ TIFF_FLOAT = 11, /* !32-bit IEEE floating point */
+ TIFF_DOUBLE = 12, /* !64-bit IEEE floating point */
+ TIFF_IFD = 13, /* %32-bit unsigned integer (offset) */
+ TIFF_LONG8 = 16, /* BigTIFF 64-bit unsigned integer */
+ TIFF_SLONG8 = 17, /* BigTIFF 64-bit signed integer */
+ TIFF_IFD8 = 18 /* BigTIFF 64-bit unsigned integer (offset) */
+} TIFFDataType;
+
+/*
+ * TIFF Tag Definitions.
+ */
+/* clang-format off */ /* for better readability of tag comments */
+#define TIFFTAG_SUBFILETYPE 254 /* subfile data descriptor */
+#define FILETYPE_REDUCEDIMAGE 0x1 /* reduced resolution version */
+#define FILETYPE_PAGE 0x2 /* one page of many */
+#define FILETYPE_MASK 0x4 /* transparency mask */
+#define TIFFTAG_OSUBFILETYPE 255 /* +kind of data in subfile */
+#define OFILETYPE_IMAGE 1 /* full resolution image data */
+#define OFILETYPE_REDUCEDIMAGE 2 /* reduced size image data */
+#define OFILETYPE_PAGE 3 /* one page of many */
+#define TIFFTAG_IMAGEWIDTH 256 /* image width in pixels */
+#define TIFFTAG_IMAGELENGTH 257 /* image height in pixels */
+#define TIFFTAG_BITSPERSAMPLE 258 /* bits per channel (sample) */
+#define TIFFTAG_COMPRESSION 259 /* data compression technique */
+#define COMPRESSION_NONE 1 /* dump mode */
+#define COMPRESSION_CCITTRLE 2 /* CCITT modified Huffman RLE */
+#define COMPRESSION_CCITTFAX3 3 /* CCITT Group 3 fax encoding */
+#define COMPRESSION_CCITT_T4 3 /* CCITT T.4 (TIFF 6 name) */
+#define COMPRESSION_CCITTFAX4 4 /* CCITT Group 4 fax encoding */
+#define COMPRESSION_CCITT_T6 4 /* CCITT T.6 (TIFF 6 name) */
+#define COMPRESSION_LZW 5 /* Lempel-Ziv & Welch */
+#define COMPRESSION_OJPEG 6 /* !6.0 JPEG */
+#define COMPRESSION_JPEG 7 /* %JPEG DCT compression */
+#define COMPRESSION_T85 9 /* !TIFF/FX T.85 JBIG compression */
+#define COMPRESSION_T43 10 /* !TIFF/FX T.43 colour by layered JBIG compression */
+#define COMPRESSION_NEXT 32766 /* NeXT 2-bit RLE */
+#define COMPRESSION_CCITTRLEW 32771 /* #1 w/ word alignment */
+#define COMPRESSION_PACKBITS 32773 /* Macintosh RLE */
+#define COMPRESSION_THUNDERSCAN 32809 /* ThunderScan RLE */
+/* codes 32895-32898 are reserved for ANSI IT8 TIFF/IT <dkelly@apago.com) */
+#define COMPRESSION_IT8CTPAD 32895 /* IT8 CT w/padding */
+#define COMPRESSION_IT8LW 32896 /* IT8 Linework RLE */
+#define COMPRESSION_IT8MP 32897 /* IT8 Monochrome picture */
+#define COMPRESSION_IT8BL 32898 /* IT8 Binary line art */
+/* 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, legacy tag */
+#define COMPRESSION_ADOBE_DEFLATE 8 /* Deflate compression, as recognized by Adobe */
+/* compression code 32947 is reserved for Oceana Matrix <dev@oceana.com> */
+#define COMPRESSION_DCS 32947 /* Kodak DCS encoding */
+#define COMPRESSION_JBIG 34661 /* ISO JBIG */
+#define COMPRESSION_SGILOG 34676 /* SGI Log Luminance RLE */
+#define COMPRESSION_SGILOG24 34677 /* SGI Log 24-bit packed */
+#define COMPRESSION_JP2000 34712 /* Leadtools JPEG2000 */
+#define COMPRESSION_LERC 34887 /* ESRI Lerc codec: https://github.com/Esri/lerc */
+/* compression codes 34887-34889 are reserved for ESRI */
+#define COMPRESSION_LZMA 34925 /* LZMA2 */
+#define COMPRESSION_ZSTD 50000 /* ZSTD: WARNING not registered in Adobe-maintained registry */
+#define COMPRESSION_WEBP 50001 /* WEBP: WARNING not registered in Adobe-maintained registry */
+#define COMPRESSION_JXL 50002 /* JPEGXL: WARNING not registered in Adobe-maintained registry */
+#define TIFFTAG_PHOTOMETRIC 262 /* photometric interpretation */
+#define PHOTOMETRIC_MINISWHITE 0 /* min value is white */
+#define PHOTOMETRIC_MINISBLACK 1 /* min value is black */
+#define PHOTOMETRIC_RGB 2 /* RGB color model */
+#define PHOTOMETRIC_PALETTE 3 /* color map indexed */
+#define PHOTOMETRIC_MASK 4 /* $holdout mask */
+#define PHOTOMETRIC_SEPARATED 5 /* !color separations */
+#define PHOTOMETRIC_YCBCR 6 /* !CCIR 601 */
+#define PHOTOMETRIC_CIELAB 8 /* !1976 CIE L*a*b* */
+#define PHOTOMETRIC_ICCLAB 9 /* ICC L*a*b* [Adobe TIFF Technote 4] */
+#define PHOTOMETRIC_ITULAB 10 /* ITU L*a*b* */
+#define PHOTOMETRIC_CFA 32803 /* color filter array */
+#define PHOTOMETRIC_LOGL 32844 /* CIE Log2(L) */
+#define PHOTOMETRIC_LOGLUV 32845 /* CIE Log2(L) (u',v') */
+#define TIFFTAG_THRESHHOLDING 263 /* +thresholding used on data */
+#define THRESHHOLD_BILEVEL 1 /* b&w art scan */
+#define THRESHHOLD_HALFTONE 2 /* or dithered scan */
+#define THRESHHOLD_ERRORDIFFUSE 3 /* usually floyd-steinberg */
+#define TIFFTAG_CELLWIDTH 264 /* +dithering matrix width */
+#define TIFFTAG_CELLLENGTH 265 /* +dithering matrix height */
+#define TIFFTAG_FILLORDER 266 /* data order within a byte */
+#define FILLORDER_MSB2LSB 1 /* most significant -> least */
+#define FILLORDER_LSB2MSB 2 /* least significant -> most */
+#define TIFFTAG_DOCUMENTNAME 269 /* name of doc. image is from */
+#define TIFFTAG_IMAGEDESCRIPTION 270 /* info about image */
+#define TIFFTAG_MAKE 271 /* scanner manufacturer name */
+#define TIFFTAG_MODEL 272 /* scanner model name/number */
+#define TIFFTAG_STRIPOFFSETS 273 /* offsets to data strips */
+#define TIFFTAG_ORIENTATION 274 /* +image orientation */
+#define ORIENTATION_TOPLEFT 1 /* row 0 top, col 0 lhs */
+#define ORIENTATION_TOPRIGHT 2 /* row 0 top, col 0 rhs */
+#define ORIENTATION_BOTRIGHT 3 /* row 0 bottom, col 0 rhs */
+#define ORIENTATION_BOTLEFT 4 /* row 0 bottom, col 0 lhs */
+#define ORIENTATION_LEFTTOP 5 /* row 0 lhs, col 0 top */
+#define ORIENTATION_RIGHTTOP 6 /* row 0 rhs, col 0 top */
+#define ORIENTATION_RIGHTBOT 7 /* row 0 rhs, col 0 bottom */
+#define ORIENTATION_LEFTBOT 8 /* row 0 lhs, col 0 bottom */
+#define TIFFTAG_SAMPLESPERPIXEL 277 /* samples per pixel */
+#define TIFFTAG_ROWSPERSTRIP 278 /* rows per strip of data */
+#define TIFFTAG_STRIPBYTECOUNTS 279 /* bytes counts for strips */
+#define TIFFTAG_MINSAMPLEVALUE 280 /* +minimum sample value */
+#define TIFFTAG_MAXSAMPLEVALUE 281 /* +maximum sample value */
+#define TIFFTAG_XRESOLUTION 282 /* pixels/resolution in x */
+#define TIFFTAG_YRESOLUTION 283 /* pixels/resolution in y */
+#define TIFFTAG_PLANARCONFIG 284 /* storage organization */
+#define PLANARCONFIG_CONTIG 1 /* single image plane */
+#define PLANARCONFIG_SEPARATE 2 /* separate planes of data */
+#define TIFFTAG_PAGENAME 285 /* page name image is from */
+#define TIFFTAG_XPOSITION 286 /* x page offset of image lhs */
+#define TIFFTAG_YPOSITION 287 /* y page offset of image lhs */
+#define TIFFTAG_FREEOFFSETS 288 /* +byte offset to free block */
+#define TIFFTAG_FREEBYTECOUNTS 289 /* +sizes of free blocks */
+#define TIFFTAG_GRAYRESPONSEUNIT 290 /* $gray scale curve accuracy */
+#define GRAYRESPONSEUNIT_10S 1 /* tenths of a unit */
+#define GRAYRESPONSEUNIT_100S 2 /* hundredths of a unit */
+#define GRAYRESPONSEUNIT_1000S 3 /* thousandths of a unit */
+#define GRAYRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */
+#define GRAYRESPONSEUNIT_100000S 5 /* hundred-thousandths */
+#define TIFFTAG_GRAYRESPONSECURVE 291 /* $gray scale response curve */
+#define TIFFTAG_GROUP3OPTIONS 292 /* 32 flag bits */
+#define TIFFTAG_T4OPTIONS 292 /* TIFF 6.0 proper name alias */
+#define GROUP3OPT_2DENCODING 0x1 /* 2-dimensional coding */
+#define GROUP3OPT_UNCOMPRESSED 0x2 /* data not compressed */
+#define GROUP3OPT_FILLBITS 0x4 /* fill to byte boundary */
+#define TIFFTAG_GROUP4OPTIONS 293 /* 32 flag bits */
+#define TIFFTAG_T6OPTIONS 293 /* TIFF 6.0 proper name */
+#define GROUP4OPT_UNCOMPRESSED 0x2 /* data not compressed */
+#define TIFFTAG_RESOLUTIONUNIT 296 /* units of resolutions */
+#define RESUNIT_NONE 1 /* no meaningful units */
+#define RESUNIT_INCH 2 /* english */
+#define RESUNIT_CENTIMETER 3 /* metric */
+#define TIFFTAG_PAGENUMBER 297 /* page numbers of multi-page */
+#define TIFFTAG_COLORRESPONSEUNIT 300 /* $color curve accuracy */
+#define COLORRESPONSEUNIT_10S 1 /* tenths of a unit */
+#define COLORRESPONSEUNIT_100S 2 /* hundredths of a unit */
+#define COLORRESPONSEUNIT_1000S 3 /* thousandths of a unit */
+#define COLORRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */
+#define COLORRESPONSEUNIT_100000S 5 /* hundred-thousandths */
+#define TIFFTAG_TRANSFERFUNCTION 301 /* !colorimetry info */
+#define TIFFTAG_SOFTWARE 305 /* name & release */
+#define TIFFTAG_DATETIME 306 /* creation date and time */
+#define TIFFTAG_ARTIST 315 /* creator of image */
+#define TIFFTAG_HOSTCOMPUTER 316 /* machine where created */
+#define TIFFTAG_PREDICTOR 317 /* prediction scheme w/ LZW */
+#define PREDICTOR_NONE 1 /* no prediction scheme used */
+#define PREDICTOR_HORIZONTAL 2 /* horizontal differencing */
+#define PREDICTOR_FLOATINGPOINT 3 /* floating point predictor */
+#define TIFFTAG_WHITEPOINT 318 /* image white point */
+#define TIFFTAG_PRIMARYCHROMATICITIES 319 /* !primary chromaticities */
+#define TIFFTAG_COLORMAP 320 /* RGB map for palette image */
+#define TIFFTAG_HALFTONEHINTS 321 /* !highlight+shadow info */
+#define TIFFTAG_TILEWIDTH 322 /* !tile width in pixels */
+#define TIFFTAG_TILELENGTH 323 /* !tile height in pixels */
+#define TIFFTAG_TILEOFFSETS 324 /* !offsets to data tiles */
+#define TIFFTAG_TILEBYTECOUNTS 325 /* !byte counts for tiles */
+#define TIFFTAG_BADFAXLINES 326 /* lines w/ wrong pixel count */
+#define TIFFTAG_CLEANFAXDATA 327 /* regenerated line info */
+#define CLEANFAXDATA_CLEAN 0 /* no errors detected */
+#define CLEANFAXDATA_REGENERATED 1 /* receiver regenerated lines */
+#define CLEANFAXDATA_UNCLEAN 2 /* uncorrected errors exist */
+#define TIFFTAG_CONSECUTIVEBADFAXLINES 328 /* max consecutive bad lines */
+#define TIFFTAG_SUBIFD 330 /* subimage descriptors */
+#define TIFFTAG_INKSET 332 /* !inks in separated image */
+#define INKSET_CMYK 1 /* !cyan-magenta-yellow-black color */
+#define INKSET_MULTIINK 2 /* !multi-ink or hi-fi color */
+#define TIFFTAG_INKNAMES 333 /* !ascii names of inks */
+#define TIFFTAG_NUMBEROFINKS 334 /* !number of inks */
+#define TIFFTAG_DOTRANGE 336 /* !0% and 100% dot codes */
+#define TIFFTAG_TARGETPRINTER 337 /* !separation target */
+#define TIFFTAG_EXTRASAMPLES 338 /* !info about extra samples */
+#define EXTRASAMPLE_UNSPECIFIED 0 /* !unspecified data */
+#define EXTRASAMPLE_ASSOCALPHA 1 /* !associated alpha data */
+#define EXTRASAMPLE_UNASSALPHA 2 /* !unassociated alpha data */
+#define TIFFTAG_SAMPLEFORMAT 339 /* !data sample format */
+#define SAMPLEFORMAT_UINT 1 /* !unsigned integer data */
+#define SAMPLEFORMAT_INT 2 /* !signed integer data */
+#define SAMPLEFORMAT_IEEEFP 3 /* !IEEE floating point data */
+#define SAMPLEFORMAT_VOID 4 /* !untyped data */
+#define SAMPLEFORMAT_COMPLEXINT 5 /* !complex signed int */
+#define SAMPLEFORMAT_COMPLEXIEEEFP 6 /* !complex ieee floating */
+#define TIFFTAG_SMINSAMPLEVALUE 340 /* !variable MinSampleValue */
+#define TIFFTAG_SMAXSAMPLEVALUE 341 /* !variable MaxSampleValue */
+#define TIFFTAG_CLIPPATH 343 /* %ClipPath [Adobe TIFF technote 2] */
+#define TIFFTAG_XCLIPPATHUNITS 344 /* %XClipPathUnits [Adobe TIFF technote 2] */
+#define TIFFTAG_YCLIPPATHUNITS 345 /* %YClipPathUnits [Adobe TIFF technote 2] */
+#define TIFFTAG_INDEXED 346 /* %Indexed [Adobe TIFF Technote 3] */
+#define TIFFTAG_JPEGTABLES 347 /* %JPEG table stream */
+#define TIFFTAG_OPIPROXY 351 /* %OPI Proxy [Adobe TIFF technote] */
+/* Tags 400-435 are from the TIFF/FX spec */
+#define TIFFTAG_GLOBALPARAMETERSIFD 400 /* ! */
+#define TIFFTAG_PROFILETYPE 401 /* ! */
+#define PROFILETYPE_UNSPECIFIED 0 /* ! */
+#define PROFILETYPE_G3_FAX 1 /* ! */
+#define TIFFTAG_FAXPROFILE 402 /* ! */
+#define FAXPROFILE_S 1 /* !TIFF/FX FAX profile S */
+#define FAXPROFILE_F 2 /* !TIFF/FX FAX profile F */
+#define FAXPROFILE_J 3 /* !TIFF/FX FAX profile J */
+#define FAXPROFILE_C 4 /* !TIFF/FX FAX profile C */
+#define FAXPROFILE_L 5 /* !TIFF/FX FAX profile L */
+#define FAXPROFILE_M 6 /* !TIFF/FX FAX profile LM */
+#define TIFFTAG_CODINGMETHODS 403 /* !TIFF/FX coding methods */
+#define CODINGMETHODS_T4_1D (1 << 1) /* !T.4 1D */
+#define CODINGMETHODS_T4_2D (1 << 2) /* !T.4 2D */
+#define CODINGMETHODS_T6 (1 << 3) /* !T.6 */
+#define CODINGMETHODS_T85 (1 << 4) /* !T.85 JBIG */
+#define CODINGMETHODS_T42 (1 << 5) /* !T.42 JPEG */
+#define CODINGMETHODS_T43 (1 << 6) /* !T.43 colour by layered JBIG */
+#define TIFFTAG_VERSIONYEAR 404 /* !TIFF/FX version year */
+#define TIFFTAG_MODENUMBER 405 /* !TIFF/FX mode number */
+#define TIFFTAG_DECODE 433 /* !TIFF/FX decode */
+#define TIFFTAG_IMAGEBASECOLOR 434 /* !TIFF/FX image base colour */
+#define TIFFTAG_T82OPTIONS 435 /* !TIFF/FX T.82 options */
+/*
+ * Tags 512-521 are obsoleted by Technical Note #2 which specifies a
+ * revised JPEG-in-TIFF scheme.
+ */
+#define TIFFTAG_JPEGPROC 512 /* !JPEG processing algorithm */
+#define JPEGPROC_BASELINE 1 /* !baseline sequential */
+#define JPEGPROC_LOSSLESS 14 /* !Huffman coded lossless */
+#define TIFFTAG_JPEGIFOFFSET 513 /* !pointer to SOI marker */
+#define TIFFTAG_JPEGIFBYTECOUNT 514 /* !JFIF stream length */
+#define TIFFTAG_JPEGRESTARTINTERVAL 515 /* !restart interval length */
+#define TIFFTAG_JPEGLOSSLESSPREDICTORS 517 /* !lossless proc predictor */
+#define TIFFTAG_JPEGPOINTTRANSFORM 518 /* !lossless point transform */
+#define TIFFTAG_JPEGQTABLES 519 /* !Q matrix offsets */
+#define TIFFTAG_JPEGDCTABLES 520 /* !DCT table offsets */
+#define TIFFTAG_JPEGACTABLES 521 /* !AC coefficient offsets */
+#define TIFFTAG_YCBCRCOEFFICIENTS 529 /* !RGB -> YCbCr transform */
+#define TIFFTAG_YCBCRSUBSAMPLING 530 /* !YCbCr subsampling factors */
+#define TIFFTAG_YCBCRPOSITIONING 531 /* !subsample positioning */
+#define YCBCRPOSITION_CENTERED 1 /* !as in PostScript Level 2 */
+#define YCBCRPOSITION_COSITED 2 /* !as in CCIR 601-1 */
+#define TIFFTAG_REFERENCEBLACKWHITE 532 /* !colorimetry info */
+#define TIFFTAG_STRIPROWCOUNTS 559 /* !TIFF/FX strip row counts */
+#define TIFFTAG_XMLPACKET 700 /* %XML packet [Adobe XMP Specification, January 2004 */
+#define TIFFTAG_OPIIMAGEID 32781 /* %OPI ImageID [Adobe TIFF technote] */
+/* For eiStream Annotation Specification, Version 1.00.06 see
+ * http://web.archive.org/web/20050309141348/http://www.kofile.com/support%20pro/faqs/annospec.htm */
+#define TIFFTAG_TIFFANNOTATIONDATA 32932
+/* tags 32952-32956 are private tags registered to Island Graphics */
+#define TIFFTAG_REFPTS 32953 /* image reference points */
+#define TIFFTAG_REGIONTACKPOINT 32954 /* region-xform tack point */
+#define TIFFTAG_REGIONWARPCORNERS 32955 /* warp quadrilateral */
+#define TIFFTAG_REGIONAFFINE 32956 /* affine transformation mat */
+/* tags 32995-32999 are private tags registered to SGI */
+#define TIFFTAG_MATTEING 32995 /* $use ExtraSamples */
+#define TIFFTAG_DATATYPE 32996 /* $use SampleFormat */
+#define TIFFTAG_IMAGEDEPTH 32997 /* z depth of image */
+#define TIFFTAG_TILEDEPTH 32998 /* z depth/data tile */
+/* tags 33300-33309 are private tags registered to Pixar */
+/*
+ * TIFFTAG_PIXAR_IMAGEFULLWIDTH and TIFFTAG_PIXAR_IMAGEFULLLENGTH
+ * are set when an image has been cropped out of a larger image.
+ * They reflect the size of the original uncropped image.
+ * The TIFFTAG_XPOSITION and TIFFTAG_YPOSITION can be used
+ * to determine the position of the smaller image in the larger one.
+ */
+#define TIFFTAG_PIXAR_IMAGEFULLWIDTH 33300 /* full image size in x */
+#define TIFFTAG_PIXAR_IMAGEFULLLENGTH 33301 /* full image size in y */
+/* Tags 33302-33306 are used to identify special image modes and data
+ * used by Pixar's texture formats.
+ */
+#define TIFFTAG_PIXAR_TEXTUREFORMAT 33302 /* texture map format */
+#define TIFFTAG_PIXAR_WRAPMODES 33303 /* s & t wrap modes */
+#define TIFFTAG_PIXAR_FOVCOT 33304 /* cotan(fov) for env. maps */
+#define TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN 33305
+#define TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA 33306
+/* tag 33405 is a private tag registered to Eastman Kodak */
+#define TIFFTAG_WRITERSERIALNUMBER 33405 /* device serial number */
+#define TIFFTAG_CFAREPEATPATTERNDIM 33421 /* (alias for TIFFTAG_EP_CFAREPEATPATTERNDIM)*/
+#define TIFFTAG_CFAPATTERN 33422 /* (alias for TIFFTAG_EP_CFAPATTERN) */
+#define TIFFTAG_BATTERYLEVEL 33423 /* (alias for TIFFTAG_EP_BATTERYLEVEL) */
+/* tag 33432 is listed in the 6.0 spec w/ unknown ownership */
+#define TIFFTAG_COPYRIGHT 33432 /* copyright string */
+/* Tags 33445-33452 are used for Molecular Dynamics GEL fileformat,
+ * see http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf
+ * (2023: the above web site is unavailable but tags are explained briefly at
+ * https://www.awaresystems.be/imaging/tiff/tifftags/docs/gel.html
+ */
+#define TIFFTAG_MD_FILETAG 33445 /* Specifies the pixel data format encoding in the GEL file format. */
+#define TIFFTAG_MD_SCALEPIXEL 33446 /* scale factor */
+#define TIFFTAG_MD_COLORTABLE 33447 /* conversion from 16bit to 8bit */
+#define TIFFTAG_MD_LABNAME 33448 /* name of the lab that scanned this file. */
+#define TIFFTAG_MD_SAMPLEINFO 33449 /* information about the scanned GEL sample */
+#define TIFFTAG_MD_PREPDATE 33450 /* information about the date the sample was prepared YY/MM/DD */
+#define TIFFTAG_MD_PREPTIME 33451 /* information about the time the sample was prepared HH:MM*/
+#define TIFFTAG_MD_FILEUNITS 33452 /* Units for data in this file, as used in the GEL file format. */
+/* IPTC TAG from RichTIFF specifications */
+#define TIFFTAG_RICHTIFFIPTC 33723
+#define TIFFTAG_INGR_PACKET_DATA_TAG 33918 /* Intergraph Application specific storage. */
+#define TIFFTAG_INGR_FLAG_REGISTERS 33919 /* Intergraph Application specific flags. */
+#define TIFFTAG_IRASB_TRANSORMATION_MATRIX 33920 /* Originally part of Intergraph's GeoTIFF tags, but likely understood by IrasB only. */
+#define TIFFTAG_MODELTIEPOINTTAG 33922 /* GeoTIFF */
+/* 34016-34029 are reserved for ANSI IT8 TIFF/IT <dkelly@apago.com) */
+#define TIFFTAG_IT8SITE 34016 /* site name */
+#define TIFFTAG_IT8COLORSEQUENCE 34017 /* color seq. [RGB,CMYK,etc] */
+#define TIFFTAG_IT8HEADER 34018 /* DDES Header */
+#define TIFFTAG_IT8RASTERPADDING 34019 /* raster scanline padding */
+#define TIFFTAG_IT8BITSPERRUNLENGTH 34020 /* # of bits in short run */
+#define TIFFTAG_IT8BITSPEREXTENDEDRUNLENGTH 34021 /* # of bits in long run */
+#define TIFFTAG_IT8COLORTABLE 34022 /* LW colortable */
+#define TIFFTAG_IT8IMAGECOLORINDICATOR 34023 /* BP/BL image color switch */
+#define TIFFTAG_IT8BKGCOLORINDICATOR 34024 /* BP/BL bg color switch */
+#define TIFFTAG_IT8IMAGECOLORVALUE 34025 /* BP/BL image color value */
+#define TIFFTAG_IT8BKGCOLORVALUE 34026 /* BP/BL bg color value */
+#define TIFFTAG_IT8PIXELINTENSITYRANGE 34027 /* MP pixel intensity value */
+#define TIFFTAG_IT8TRANSPARENCYINDICATOR 34028 /* HC transparency switch */
+#define TIFFTAG_IT8COLORCHARACTERIZATION 34029 /* color character. table */
+#define TIFFTAG_IT8HCUSAGE 34030 /* HC usage indicator */
+#define TIFFTAG_IT8TRAPINDICATOR 34031 /* Trapping indicator (untrapped=0, trapped=1) */
+#define TIFFTAG_IT8CMYKEQUIVALENT 34032 /* CMYK color equivalents */
+/* tags 34232-34236 are private tags registered to Texas Instruments */
+#define TIFFTAG_FRAMECOUNT 34232 /* Sequence Frame Count */
+#define TIFFTAG_MODELTRANSFORMATIONTAG 34264 /* Used in interchangeable GeoTIFF files */
+/* tag 34377 is private tag registered to Adobe for PhotoShop */
+#define TIFFTAG_PHOTOSHOP 34377
+/* tags 34665, 34853 and 40965 are documented in EXIF specification */
+#define TIFFTAG_EXIFIFD 34665 /* Pointer to EXIF private directory */
+/* tag 34750 is a private tag registered to Adobe? */
+#define TIFFTAG_ICCPROFILE 34675 /* ICC profile data */
+#define TIFFTAG_IMAGELAYER 34732 /* !TIFF/FX image layer information */
+/* tag 34750 is a private tag registered to Pixel Magic */
+#define TIFFTAG_JBIGOPTIONS 34750 /* JBIG options */
+#define TIFFTAG_GPSIFD 34853 /* Pointer to EXIF GPS private directory */
+/* tags 34908-34914 are private tags registered to SGI */
+#define TIFFTAG_FAXRECVPARAMS 34908 /* encoded Class 2 ses. params */
+#define TIFFTAG_FAXSUBADDRESS 34909 /* received SubAddr string */
+#define TIFFTAG_FAXRECVTIME 34910 /* receive time (secs) */
+#define TIFFTAG_FAXDCS 34911 /* encoded fax ses. params, Table 2/T.30 */
+/* tags 37439-37443 are registered to SGI <gregl@sgi.com> */
+#define TIFFTAG_STONITS 37439 /* Sample value to Nits */
+/* tag 34929 is a private tag registered to FedEx */
+#define TIFFTAG_FEDEX_EDR 34929 /* unknown use */
+#define TIFFTAG_IMAGESOURCEDATA 37724 /* http://justsolve.archiveteam.org/wiki/PSD, http://www.adobe.com/devnet-apps/photoshop/fileformatashtml/ */
+#define TIFFTAG_INTEROPERABILITYIFD 40965 /* Pointer to EXIF Interoperability private directory */
+#define TIFFTAG_GDAL_METADATA 42112 /* Used by the GDAL library */
+#define TIFFTAG_GDAL_NODATA 42113 /* Used by the GDAL library */
+#define TIFFTAG_OCE_SCANJOB_DESCRIPTION 50215 /* Used in the Oce scanning process */
+#define TIFFTAG_OCE_APPLICATION_SELECTOR 50216 /* Used in the Oce scanning process. */
+#define TIFFTAG_OCE_IDENTIFICATION_NUMBER 50217
+#define TIFFTAG_OCE_IMAGELOGIC_CHARACTERISTICS 50218
+/* tags 50674 to 50677 are reserved for ESRI */
+#define TIFFTAG_LERC_PARAMETERS 50674 /* Stores LERC version and additional compression method */
+
+/* Adobe Digital Negative (DNG) format tags */
+#define TIFFTAG_DNGVERSION 50706 /* &DNG version number */
+#define TIFFTAG_DNGBACKWARDVERSION 50707 /* &DNG compatibility version */
+#define TIFFTAG_UNIQUECAMERAMODEL 50708 /* &name for the camera model */
+#define TIFFTAG_LOCALIZEDCAMERAMODEL 50709 /* &localized camera model name (UTF-8) */
+#define TIFFTAG_CFAPLANECOLOR 50710 /* &CFAPattern->LinearRaw space mapping */
+#define TIFFTAG_CFALAYOUT 50711 /* &spatial layout of the CFA */
+#define TIFFTAG_LINEARIZATIONTABLE 50712 /* &lookup table description */
+#define TIFFTAG_BLACKLEVELREPEATDIM 50713 /* &repeat pattern size for the BlackLevel tag */
+#define TIFFTAG_BLACKLEVEL 50714 /* &zero light encoding level */
+#define TIFFTAG_BLACKLEVELDELTAH 50715 /* &zero light encoding level differences (columns) */
+#define TIFFTAG_BLACKLEVELDELTAV 50716 /* &zero light encoding level differences (rows) */
+#define TIFFTAG_WHITELEVEL 50717 /* &fully saturated encoding level */
+#define TIFFTAG_DEFAULTSCALE 50718 /* &default scale factors */
+#define TIFFTAG_DEFAULTCROPORIGIN 50719 /* &origin of the final image area */
+#define TIFFTAG_DEFAULTCROPSIZE 50720 /* &size of the final image area */
+#define TIFFTAG_COLORMATRIX1 50721 /* &XYZ->reference color space transformation matrix 1 */
+#define TIFFTAG_COLORMATRIX2 50722 /* &XYZ->reference color space transformation matrix 2 */
+#define TIFFTAG_CAMERACALIBRATION1 50723 /* &calibration matrix 1 */
+#define TIFFTAG_CAMERACALIBRATION2 50724 /* &calibration matrix 2 */
+#define TIFFTAG_REDUCTIONMATRIX1 50725 /* &dimensionality reduction matrix 1 */
+#define TIFFTAG_REDUCTIONMATRIX2 50726 /* &dimensionality reduction matrix 2 */
+#define TIFFTAG_ANALOGBALANCE 50727 /* &gain applied the stored raw values*/
+#define TIFFTAG_ASSHOTNEUTRAL 50728 /* &selected white balance in linear reference space */
+#define TIFFTAG_ASSHOTWHITEXY 50729 /* &selected white balance in x-y chromaticity coordinates */
+#define TIFFTAG_BASELINEEXPOSURE 50730 /* &how much to move the zero point */
+#define TIFFTAG_BASELINENOISE 50731 /* &relative noise level */
+#define TIFFTAG_BASELINESHARPNESS 50732 /* &relative amount of sharpening */
+/* TIFFTAG_BAYERGREENSPLIT: &how closely the values of the green pixels in the blue/green rows
+ * track the values of the green pixels in the red/green rows */
+#define TIFFTAG_BAYERGREENSPLIT 50733
+#define TIFFTAG_LINEARRESPONSELIMIT 50734 /* &non-linear encoding range */
+#define TIFFTAG_CAMERASERIALNUMBER 50735 /* &camera's serial number */
+#define TIFFTAG_LENSINFO 50736 /* info about the lens */
+#define TIFFTAG_CHROMABLURRADIUS 50737 /* &chroma blur radius */
+#define TIFFTAG_ANTIALIASSTRENGTH 50738 /* &relative strength of the camera's anti-alias filter */
+#define TIFFTAG_SHADOWSCALE 50739 /* &used by Adobe Camera Raw */
+#define TIFFTAG_DNGPRIVATEDATA 50740 /* &manufacturer's private data */
+#define TIFFTAG_MAKERNOTESAFETY 50741 /* &whether the EXIF MakerNote tag is safe to preserve along with the rest of the EXIF data */
+#define TIFFTAG_CALIBRATIONILLUMINANT1 50778 /* &illuminant 1 */
+#define TIFFTAG_CALIBRATIONILLUMINANT2 50779 /* &illuminant 2 */
+#define TIFFTAG_BESTQUALITYSCALE 50780 /* &best quality multiplier */
+#define TIFFTAG_RAWDATAUNIQUEID 50781 /* &unique identifier for the raw image data */
+#define TIFFTAG_ORIGINALRAWFILENAME 50827 /* &file name of the original raw file (UTF-8) */
+#define TIFFTAG_ORIGINALRAWFILEDATA 50828 /* &contents of the original raw file */
+#define TIFFTAG_ACTIVEAREA 50829 /* &active (non-masked) pixels of the sensor */
+#define TIFFTAG_MASKEDAREAS 50830 /* &list of coordinates of fully masked pixels */
+#define TIFFTAG_ASSHOTICCPROFILE 50831 /* &these two tags used to */
+#define TIFFTAG_ASSHOTPREPROFILEMATRIX 50832 /* map cameras's color space into ICC profile space */
+#define TIFFTAG_CURRENTICCPROFILE 50833 /* & */
+#define TIFFTAG_CURRENTPREPROFILEMATRIX 50834 /* & */
+
+/* DNG 1.2.0.0 */
+#define TIFFTAG_COLORIMETRICREFERENCE 50879 /* &colorimetric reference */
+#define TIFFTAG_CAMERACALIBRATIONSIGNATURE 50931 /* &camera calibration signature (UTF-8) */
+#define TIFFTAG_PROFILECALIBRATIONSIGNATURE 50932 /* &profile calibration signature (UTF-8) */
+/* TIFFTAG_EXTRACAMERAPROFILES 50933 &extra camera profiles : is already defined for GeoTIFF DGIWG */
+#define TIFFTAG_ASSHOTPROFILENAME 50934 /* &as shot profile name (UTF-8) */
+#define TIFFTAG_NOISEREDUCTIONAPPLIED 50935 /* &amount of applied noise reduction */
+#define TIFFTAG_PROFILENAME 50936 /* &camera profile name (UTF-8) */
+#define TIFFTAG_PROFILEHUESATMAPDIMS 50937 /* &dimensions of HSV mapping */
+#define TIFFTAG_PROFILEHUESATMAPDATA1 50938 /* &first HSV mapping table */
+#define TIFFTAG_PROFILEHUESATMAPDATA2 50939 /* &second HSV mapping table */
+#define TIFFTAG_PROFILETONECURVE 50940 /* &default tone curve */
+#define TIFFTAG_PROFILEEMBEDPOLICY 50941 /* &profile embedding policy */
+#define TIFFTAG_PROFILECOPYRIGHT 50942 /* &profile copyright information (UTF-8) */
+#define TIFFTAG_FORWARDMATRIX1 50964 /* &matrix for mapping white balanced camera colors to XYZ D50 */
+#define TIFFTAG_FORWARDMATRIX2 50965 /* &matrix for mapping white balanced camera colors to XYZ D50 */
+#define TIFFTAG_PREVIEWAPPLICATIONNAME 50966 /* &name of application that created preview (UTF-8) */
+#define TIFFTAG_PREVIEWAPPLICATIONVERSION 50967 /* &version of application that created preview (UTF-8) */
+#define TIFFTAG_PREVIEWSETTINGSNAME 50968 /* &name of conversion settings (UTF-8) */
+#define TIFFTAG_PREVIEWSETTINGSDIGEST 50969 /* &unique id of conversion settings */
+#define TIFFTAG_PREVIEWCOLORSPACE 50970 /* &preview color space */
+#define TIFFTAG_PREVIEWDATETIME 50971 /* &date/time preview was rendered */
+#define TIFFTAG_RAWIMAGEDIGEST 50972 /* &md5 of raw image data */
+#define TIFFTAG_ORIGINALRAWFILEDIGEST 50973 /* &md5 of the data stored in the OriginalRawFileData tag */
+#define TIFFTAG_SUBTILEBLOCKSIZE 50974 /* &subtile block size */
+#define TIFFTAG_ROWINTERLEAVEFACTOR 50975 /* &number of interleaved fields */
+#define TIFFTAG_PROFILELOOKTABLEDIMS 50981 /* &num of input samples in each dim of default "look" table */
+#define TIFFTAG_PROFILELOOKTABLEDATA 50982 /* &default "look" table for use as starting point */
+
+/* DNG 1.3.0.0 */
+#define TIFFTAG_OPCODELIST1 51008 /* &opcodes that should be applied to raw image after reading */
+#define TIFFTAG_OPCODELIST2 51009 /* &opcodes that should be applied after mapping to linear reference */
+#define TIFFTAG_OPCODELIST3 51022 /* &opcodes that should be applied after demosaicing */
+#define TIFFTAG_NOISEPROFILE 51041 /* &noise profile */
+
+/* DNG 1.4.0.0 */
+#define TIFFTAG_DEFAULTUSERCROP 51125 /* &default user crop rectangle in relative coords */
+#define TIFFTAG_DEFAULTBLACKRENDER 51110 /* &black rendering hint */
+#define TIFFTAG_BASELINEEXPOSUREOFFSET 51109 /* &baseline exposure offset */
+#define TIFFTAG_PROFILELOOKTABLEENCODING 51108 /* &3D LookTable indexing conversion */
+#define TIFFTAG_PROFILEHUESATMAPENCODING 51107 /* &3D HueSatMap indexing conversion */
+#define TIFFTAG_ORIGINALDEFAULTFINALSIZE 51089 /* &default final size of larger original file for this proxy */
+#define TIFFTAG_ORIGINALBESTQUALITYFINALSIZE 51090 /* &best quality final size of larger original file for this proxy */
+#define TIFFTAG_ORIGINALDEFAULTCROPSIZE 51091 /* &the default crop size of larger original file for this proxy */
+#define TIFFTAG_NEWRAWIMAGEDIGEST 51111 /* &modified MD5 digest of the raw image data */
+#define TIFFTAG_RAWTOPREVIEWGAIN 51112 /* &The gain between the main raw FD and the preview IFD containing this tag */
+
+/* DNG 1.5.0.0 */
+#define TIFFTAG_DEPTHFORMAT 51177 /* &encoding of the depth data in the file */
+#define TIFFTAG_DEPTHNEAR 51178 /* &distance from the camera represented by value 0 in the depth map */
+#define TIFFTAG_DEPTHFAR 51179 /* &distance from the camera represented by the maximum value in the depth map */
+#define TIFFTAG_DEPTHUNITS 51180 /* &measurement units for DepthNear and DepthFar */
+#define TIFFTAG_DEPTHMEASURETYPE 51181 /* &measurement geometry for the depth map */
+#define TIFFTAG_ENHANCEPARAMS 51182 /* &a string that documents how the enhanced image data was processed. */
+
+/* DNG 1.6.0.0 */
+#define TIFFTAG_PROFILEGAINTABLEMAP 52525 /* &spatially varying gain tables that can be applied as starting point */
+#define TIFFTAG_SEMANTICNAME 52526 /* &a string that identifies the semantic mask */
+#define TIFFTAG_SEMANTICINSTANCEID 52528 /* &a string that identifies a specific instance in a semantic mask */
+#define TIFFTAG_MASKSUBAREA 52536 /* &the crop rectangle of this IFD's mask, relative to the main image */
+#define TIFFTAG_RGBTABLES 52543 /* &color transforms to apply to masked image regions */
+#define TIFFTAG_CALIBRATIONILLUMINANT3 52529 /* &the illuminant used for the third set of color calibration tags */
+#define TIFFTAG_COLORMATRIX3 52531 /* &matrix to convert XYZ values to reference camera native color space under CalibrationIlluminant3 */
+#define TIFFTAG_CAMERACALIBRATION3 52530 /* &matrix to transform reference camera native space values to individual camera native space values under CalibrationIlluminant3 */
+#define TIFFTAG_REDUCTIONMATRIX3 52538 /* &dimensionality reduction matrix for use in color conversion to XYZ under CalibrationIlluminant3 */
+#define TIFFTAG_PROFILEHUESATMAPDATA3 52537 /* &the data for the third HSV table */
+#define TIFFTAG_FORWARDMATRIX3 52532 /* &matrix to map white balanced camera colors to XYZ D50 */
+#define TIFFTAG_ILLUMINANTDATA1 52533 /* &data for the first calibration illuminant */
+#define TIFFTAG_ILLUMINANTDATA2 52534 /* &data for the second calibration illuminant */
+#define TIFFTAG_ILLUMINANTDATA3 53535 /* &data for the third calibration illuminant */
+
+/* TIFF/EP */
+#define TIFFTAG_EP_CFAREPEATPATTERNDIM 33421 /* dimensions of CFA pattern */
+#define TIFFTAG_EP_CFAPATTERN 33422 /* color filter array pattern */
+#define TIFFTAG_EP_BATTERYLEVEL 33423 /* battery level (rational or ASCII) */
+#define TIFFTAG_EP_INTERLACE 34857 /* Number of multi-field images */
+/* TIFFTAG_EP_IPTC_NAA and TIFFTAG_RICHTIFFIPTC share the same tag number (33723)
+ * LibTIFF type is UNDEFINED or BYTE, but often times incorrectly specified as LONG,
+ * because TIFF/EP (ISO/DIS 12234-2) specifies type LONG or ASCII. */
+#define TIFFTAG_EP_IPTC_NAA 33723 /* Alias IPTC/NAA Newspaper Association RichTIFF */
+#define TIFFTAG_EP_TIMEZONEOFFSET 34858 /* Time zone offset relative to UTC */
+#define TIFFTAG_EP_SELFTIMERMODE 34859 /* Number of seconds capture was delayed from button press */
+#define TIFFTAG_EP_FLASHENERGY 37387 /* Flash energy, or range if there is uncertainty */
+#define TIFFTAG_EP_SPATIALFREQUENCYRESPONSE 37388 /* Spatial frequency response */
+#define TIFFTAG_EP_NOISE 37389 /* Camera noise measurement values */
+#define TIFFTAG_EP_FOCALPLANEXRESOLUTION 37390 /* Focal plane X resolution */
+#define TIFFTAG_EP_FOCALPLANEYRESOLUTION 37391 /* Focal plane Y resolution */
+#define TIFFTAG_EP_FOCALPLANERESOLUTIONUNIT 37392 /* Focal plane resolution unit */
+#define TIFFTAG_EP_IMAGENUMBER 37393 /* Number of image when several of burst shot stored in same TIFF/EP */
+#define TIFFTAG_EP_SECURITYCLASSIFICATION 37394 /* Security classification */
+#define TIFFTAG_EP_IMAGEHISTORY 37395 /* Record of what has been done to the image */
+#define TIFFTAG_EP_EXPOSUREINDEX 37397 /* Exposure index */
+#define TIFFTAG_EP_STANDARDID 37398 /* TIFF/EP standard version, n.n.n.n */
+#define TIFFTAG_EP_SENSINGMETHOD 37399 /* Type of image sensor */
+/*
+ * TIFF/EP tags equivalent to EXIF tags
+ * Note that TIFF-EP and EXIF use nearly the same metadata tag set, but TIFF-EP stores the tags in IFD 0,
+ * while EXIF store the tags in a separate IFD. Either location is allowed by DNG, but the EXIF location is preferred.
+ */
+#define TIFFTAG_EP_EXPOSURETIME 33434 /* Exposure time */
+#define TIFFTAG_EP_FNUMBER 33437 /* F number */
+#define TIFFTAG_EP_EXPOSUREPROGRAM 34850 /* Exposure program */
+#define TIFFTAG_EP_SPECTRALSENSITIVITY 34852 /* Spectral sensitivity */
+#define TIFFTAG_EP_ISOSPEEDRATINGS 34855 /* ISO speed rating */
+#define TIFFTAG_EP_OECF 34856 /* Optoelectric conversion factor */
+#define TIFFTAG_EP_DATETIMEORIGINAL 36867 /* Date and time of original data generation */
+#define TIFFTAG_EP_COMPRESSEDBITSPERPIXEL 37122 /* Image compression mode */
+#define TIFFTAG_EP_SHUTTERSPEEDVALUE 37377 /* Shutter speed */
+#define TIFFTAG_EP_APERTUREVALUE 37378 /* Aperture */
+#define TIFFTAG_EP_BRIGHTNESSVALUE 37379 /* Brightness */
+#define TIFFTAG_EP_EXPOSUREBIASVALUE 37380 /* Exposure bias */
+#define TIFFTAG_EP_MAXAPERTUREVALUE 37381 /* Maximum lens aperture */
+#define TIFFTAG_EP_SUBJECTDISTANCE 37382 /* Subject distance */
+#define TIFFTAG_EP_METERINGMODE 37383 /* Metering mode */
+#define TIFFTAG_EP_LIGHTSOURCE 37384 /* Light source */
+#define TIFFTAG_EP_FLASH 37385 /* Flash */
+#define TIFFTAG_EP_FOCALLENGTH 37386 /* Lens focal length */
+#define TIFFTAG_EP_SUBJECTLOCATION 37396 /* Subject location (area) */
+
+#define TIFFTAG_RPCCOEFFICIENT 50844 /* Define by GDAL for geospatial georeferencing through RPC: http://geotiff.maptools.org/rpc_prop.html */
+#define TIFFTAG_ALIAS_LAYER_METADATA 50784 /* Alias Sketchbook Pro layer usage description. */
+
+/* GeoTIFF DGIWG */
+#define TIFFTAG_TIFF_RSID 50908 /* https://www.awaresystems.be/imaging/tiff/tifftags/tiff_rsid.html */
+#define TIFFTAG_GEO_METADATA 50909 /* https://www.awaresystems.be/imaging/tiff/tifftags/geo_metadata.html */
+#define TIFFTAG_EXTRACAMERAPROFILES 50933 /* http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/products/photoshop/pdfs/dng_spec_1.4.0.0.pdf */
+
+/* tag 65535 is an undefined tag used by Eastman Kodak */
+#define TIFFTAG_DCSHUESHIFTVALUES 65535 /* hue shift correction data */
+
+/*
+ * The following are ``pseudo tags'' that can be used to control
+ * codec-specific functionality. These tags are not written to file.
+ * Note that these values start at 0xffff+1 so that they'll never
+ * collide with Aldus-assigned tags.
+ *
+ * If you want your private pseudo tags ``registered'' (i.e. added to
+ * this file), please post a bug report via the tracking system at
+ * http://www.remotesensing.org/libtiff/bugs.html with the appropriate
+ * C definitions to add.
+ */
+#define TIFFTAG_FAXMODE 65536 /* Group 3/4 format control */
+#define FAXMODE_CLASSIC 0x0000 /* default, include RTC */
+#define FAXMODE_NORTC 0x0001 /* no RTC at end of data */
+#define FAXMODE_NOEOL 0x0002 /* no EOL code at end of row */
+#define FAXMODE_BYTEALIGN 0x0004 /* byte align row */
+#define FAXMODE_WORDALIGN 0x0008 /* word align row */
+#define FAXMODE_CLASSF FAXMODE_NORTC /* TIFF Class F */
+#define TIFFTAG_JPEGQUALITY 65537 /* Compression quality level */
+/* Note: quality level is on the IJG 0-100 scale. Default value is 75 */
+#define TIFFTAG_JPEGCOLORMODE 65538 /* Auto RGB<=>YCbCr convert? */
+#define JPEGCOLORMODE_RAW 0x0000 /* no conversion (default) */
+#define JPEGCOLORMODE_RGB 0x0001 /* do auto conversion */
+#define TIFFTAG_JPEGTABLESMODE 65539 /* What to put in JPEGTables */
+#define JPEGTABLESMODE_QUANT 0x0001 /* include quantization tbls */
+#define JPEGTABLESMODE_HUFF 0x0002 /* include Huffman tbls */
+/* Note: default is JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF */
+#define TIFFTAG_FAXFILLFUNC 65540 /* G3/G4 fill function */
+#define TIFFTAG_PIXARLOGDATAFMT 65549 /* PixarLogCodec I/O data sz */
+#define PIXARLOGDATAFMT_8BIT 0 /* regular u_char samples */
+#define PIXARLOGDATAFMT_8BITABGR 1 /* ABGR-order u_chars */
+#define PIXARLOGDATAFMT_11BITLOG 2 /* 11-bit log-encoded (raw) */
+#define PIXARLOGDATAFMT_12BITPICIO 3 /* as per PICIO (1.0==2048) */
+#define PIXARLOGDATAFMT_16BIT 4 /* signed short samples */
+#define PIXARLOGDATAFMT_FLOAT 5 /* IEEE float samples */
+/* 65550-65556 are allocated to Oceana Matrix <dev@oceana.com> */
+#define TIFFTAG_DCSIMAGERTYPE 65550 /* imager model & filter */
+#define DCSIMAGERMODEL_M3 0 /* M3 chip (1280 x 1024) */
+#define DCSIMAGERMODEL_M5 1 /* M5 chip (1536 x 1024) */
+#define DCSIMAGERMODEL_M6 2 /* M6 chip (3072 x 2048) */
+#define DCSIMAGERFILTER_IR 0 /* infrared filter */
+#define DCSIMAGERFILTER_MONO 1 /* monochrome filter */
+#define DCSIMAGERFILTER_CFA 2 /* color filter array */
+#define DCSIMAGERFILTER_OTHER 3 /* other filter */
+#define TIFFTAG_DCSINTERPMODE 65551 /* interpolation mode */
+#define DCSINTERPMODE_NORMAL 0x0 /* whole image, default */
+#define DCSINTERPMODE_PREVIEW 0x1 /* preview of image (384x256) */
+#define TIFFTAG_DCSBALANCEARRAY 65552 /* color balance values */
+#define TIFFTAG_DCSCORRECTMATRIX 65553 /* color correction values */
+#define TIFFTAG_DCSGAMMA 65554 /* gamma value */
+#define TIFFTAG_DCSTOESHOULDERPTS 65555 /* toe & shoulder points */
+#define TIFFTAG_DCSCALIBRATIONFD 65556 /* calibration file desc */
+/* Note: quality level is on the ZLIB 1-9 scale. Default value is -1 */
+#define TIFFTAG_ZIPQUALITY 65557 /* compression quality level */
+#define TIFFTAG_PIXARLOGQUALITY 65558 /* PixarLog uses same scale */
+/* 65559 is allocated to Oceana Matrix <dev@oceana.com> */
+#define TIFFTAG_DCSCLIPRECTANGLE 65559 /* area of image to acquire */
+#define TIFFTAG_SGILOGDATAFMT 65560 /* SGILog user data format */
+#define SGILOGDATAFMT_FLOAT 0 /* IEEE float samples */
+#define SGILOGDATAFMT_16BIT 1 /* 16-bit samples */
+#define SGILOGDATAFMT_RAW 2 /* uninterpreted data */
+#define SGILOGDATAFMT_8BIT 3 /* 8-bit RGB monitor values */
+#define TIFFTAG_SGILOGENCODE 65561 /* SGILog data encoding control*/
+#define SGILOGENCODE_NODITHER 0 /* do not dither encoded values*/
+#define SGILOGENCODE_RANDITHER 1 /* randomly dither encd values */
+#define TIFFTAG_LZMAPRESET 65562 /* LZMA2 preset (compression level) */
+#define TIFFTAG_PERSAMPLE 65563 /* interface for per sample tags */
+#define PERSAMPLE_MERGED 0 /* present as a single value */
+#define PERSAMPLE_MULTI 1 /* present as multiple values */
+#define TIFFTAG_ZSTD_LEVEL 65564 /* ZSTD compression level */
+#define TIFFTAG_LERC_VERSION 65565 /* LERC version */
+#define LERC_VERSION_2_4 4
+#define TIFFTAG_LERC_ADD_COMPRESSION 65566 /* LERC additional compression */
+#define LERC_ADD_COMPRESSION_NONE 0
+#define LERC_ADD_COMPRESSION_DEFLATE 1
+#define LERC_ADD_COMPRESSION_ZSTD 2
+#define TIFFTAG_LERC_MAXZERROR 65567 /* LERC maximum error */
+#define TIFFTAG_WEBP_LEVEL 65568 /* WebP compression level */
+#define TIFFTAG_WEBP_LOSSLESS 65569 /* WebP lossless/lossy */
+#define TIFFTAG_DEFLATE_SUBCODEC 65570 /* ZIP codec: to get/set the sub-codec to use. Will default to libdeflate when available */
+#define DEFLATE_SUBCODEC_ZLIB 0
+#define DEFLATE_SUBCODEC_LIBDEFLATE 1
+
+/*
+ * EXIF tags
+ */
+#define EXIFTAG_EXPOSURETIME 33434 /* Exposure time */
+#define EXIFTAG_FNUMBER 33437 /* F number */
+#define EXIFTAG_EXPOSUREPROGRAM 34850 /* Exposure program */
+#define EXIFTAG_SPECTRALSENSITIVITY 34852 /* Spectral sensitivity */
+/* After EXIF 2.2.1 ISOSpeedRatings is named PhotographicSensitivity.
+ In addition, while "Count=Any", only 1 count should be used. */
+#define EXIFTAG_ISOSPEEDRATINGS 34855 /* ISO speed rating */
+#define EXIFTAG_PHOTOGRAPHICSENSITIVITY 34855 /* Photographic Sensitivity (new name for tag 34855) */
+#define EXIFTAG_OECF 34856 /* Optoelectric conversion factor */
+#define EXIFTAG_EXIFVERSION 36864 /* Exif version */
+#define EXIFTAG_DATETIMEORIGINAL 36867 /* Date and time of original data generation */
+#define EXIFTAG_DATETIMEDIGITIZED 36868 /* Date and time of digital data generation */
+#define EXIFTAG_COMPONENTSCONFIGURATION 37121 /* Meaning of each component */
+#define EXIFTAG_COMPRESSEDBITSPERPIXEL 37122 /* Image compression mode */
+#define EXIFTAG_SHUTTERSPEEDVALUE 37377 /* Shutter speed */
+#define EXIFTAG_APERTUREVALUE 37378 /* Aperture */
+#define EXIFTAG_BRIGHTNESSVALUE 37379 /* Brightness */
+#define EXIFTAG_EXPOSUREBIASVALUE 37380 /* Exposure bias */
+#define EXIFTAG_MAXAPERTUREVALUE 37381 /* Maximum lens aperture */
+#define EXIFTAG_SUBJECTDISTANCE 37382 /* Subject distance */
+#define EXIFTAG_METERINGMODE 37383 /* Metering mode */
+#define EXIFTAG_LIGHTSOURCE 37384 /* Light source */
+#define EXIFTAG_FLASH 37385 /* Flash */
+#define EXIFTAG_FOCALLENGTH 37386 /* Lens focal length */
+#define EXIFTAG_SUBJECTAREA 37396 /* Subject area */
+#define EXIFTAG_MAKERNOTE 37500 /* Manufacturer notes */
+#define EXIFTAG_USERCOMMENT 37510 /* User comments */
+#define EXIFTAG_SUBSECTIME 37520 /* DateTime subseconds */
+#define EXIFTAG_SUBSECTIMEORIGINAL 37521 /* DateTimeOriginal subseconds */
+#define EXIFTAG_SUBSECTIMEDIGITIZED 37522 /* DateTimeDigitized subseconds */
+#define EXIFTAG_FLASHPIXVERSION 40960 /* Supported Flashpix version */
+#define EXIFTAG_COLORSPACE 40961 /* Color space information */
+#define EXIFTAG_PIXELXDIMENSION 40962 /* Valid image width */
+#define EXIFTAG_PIXELYDIMENSION 40963 /* Valid image height */
+#define EXIFTAG_RELATEDSOUNDFILE 40964 /* Related audio file */
+#define EXIFTAG_FLASHENERGY 41483 /* Flash energy */
+#define EXIFTAG_SPATIALFREQUENCYRESPONSE 41484 /* Spatial frequency response */
+#define EXIFTAG_FOCALPLANEXRESOLUTION 41486 /* Focal plane X resolution */
+#define EXIFTAG_FOCALPLANEYRESOLUTION 41487 /* Focal plane Y resolution */
+#define EXIFTAG_FOCALPLANERESOLUTIONUNIT 41488 /* Focal plane resolution unit */
+#define EXIFTAG_SUBJECTLOCATION 41492 /* Subject location */
+#define EXIFTAG_EXPOSUREINDEX 41493 /* Exposure index */
+#define EXIFTAG_SENSINGMETHOD 41495 /* Sensing method */
+#define EXIFTAG_FILESOURCE 41728 /* File source */
+#define EXIFTAG_SCENETYPE 41729 /* Scene type */
+#define EXIFTAG_CFAPATTERN 41730 /* CFA pattern */
+#define EXIFTAG_CUSTOMRENDERED 41985 /* Custom image processing */
+#define EXIFTAG_EXPOSUREMODE 41986 /* Exposure mode */
+#define EXIFTAG_WHITEBALANCE 41987 /* White balance */
+#define EXIFTAG_DIGITALZOOMRATIO 41988 /* Digital zoom ratio */
+#define EXIFTAG_FOCALLENGTHIN35MMFILM 41989 /* Focal length in 35 mm film */
+#define EXIFTAG_SCENECAPTURETYPE 41990 /* Scene capture type */
+#define EXIFTAG_GAINCONTROL 41991 /* Gain control */
+#define EXIFTAG_CONTRAST 41992 /* Contrast */
+#define EXIFTAG_SATURATION 41993 /* Saturation */
+#define EXIFTAG_SHARPNESS 41994 /* Sharpness */
+#define EXIFTAG_DEVICESETTINGDESCRIPTION 41995 /* Device settings description */
+#define EXIFTAG_SUBJECTDISTANCERANGE 41996 /* Subject distance range */
+#define EXIFTAG_IMAGEUNIQUEID 42016 /* Unique image ID */
+
+/*--: New for EXIF-Version 2.32, May 2019 ... */
+#define EXIFTAG_SENSITIVITYTYPE 34864 /* The SensitivityType tag indicates which one of the parameters of ISO12232 is the PhotographicSensitivity tag. */
+#define EXIFTAG_STANDARDOUTPUTSENSITIVITY 34865 /* This tag indicates the standard output sensitivity value of a camera or input device defined in ISO 12232. */
+#define EXIFTAG_RECOMMENDEDEXPOSUREINDEX 34866 /* recommended exposure index */
+#define EXIFTAG_ISOSPEED 34867 /* ISO speed value */
+#define EXIFTAG_ISOSPEEDLATITUDEYYY 34868 /* ISO speed latitude yyy */
+#define EXIFTAG_ISOSPEEDLATITUDEZZZ 34869 /* ISO speed latitude zzz */
+#define EXIFTAG_OFFSETTIME 36880 /* offset from UTC of the time of DateTime tag. */
+#define EXIFTAG_OFFSETTIMEORIGINAL 36881 /* offset from UTC of the time of DateTimeOriginal tag. */
+#define EXIFTAG_OFFSETTIMEDIGITIZED 36882 /* offset from UTC of the time of DateTimeDigitized tag. */
+#define EXIFTAG_TEMPERATURE 37888 /* Temperature as the ambient situation at the shot in dergee Celsius */
+#define EXIFTAG_HUMIDITY 37889 /* Humidity as the ambient situation at the shot in percent */
+#define EXIFTAG_PRESSURE 37890 /* Pressure as the ambient situation at the shot hecto-Pascal (hPa) */
+#define EXIFTAG_WATERDEPTH 37891 /* WaterDepth as the ambient situation at the shot in meter (m) */
+#define EXIFTAG_ACCELERATION 37892 /* Acceleration (a scalar regardless of direction) as the ambientsituation at the shot in units of mGal (10-5 m/s^2) */
+/* EXIFTAG_CAMERAELEVATIONANGLE: Elevation/depression. angle of the orientation of the camera(imaging optical axis)
+ * as the ambient situation at the shot in degree from -180deg to +180deg. */
+#define EXIFTAG_CAMERAELEVATIONANGLE 37893
+#define EXIFTAG_CAMERAOWNERNAME 42032 /* owner of a camera */
+#define EXIFTAG_BODYSERIALNUMBER 42033 /* serial number of the body of the camera */
+/* EXIFTAG_LENSSPECIFICATION: minimum focal length (in mm), maximum focal length (in mm),minimum F number in the minimum focal length,
+ * and minimum F number in the maximum focal length, */
+#define EXIFTAG_LENSSPECIFICATION 42034
+#define EXIFTAG_LENSMAKE 42035 /* the lens manufacturer */
+#define EXIFTAG_LENSMODEL 42036 /* the lens model name and model number */
+#define EXIFTAG_LENSSERIALNUMBER 42037 /* the serial number of the interchangeable lens */
+#define EXIFTAG_GAMMA 42240 /* value of coefficient gamma */
+#define EXIFTAG_COMPOSITEIMAGE 42080 /* composite image */
+#define EXIFTAG_SOURCEIMAGENUMBEROFCOMPOSITEIMAGE 42081 /* source image number of composite image */
+#define EXIFTAG_SOURCEEXPOSURETIMESOFCOMPOSITEIMAGE 42082 /* source exposure times of composite image */
+
+/*
+ * EXIF-GPS tags (Version 2.31, July 2016)
+ */
+#define GPSTAG_VERSIONID 0 /* Indicates the version of GPSInfoIFD. */
+#define GPSTAG_LATITUDEREF 1 /* Indicates whether the latitude is north or south latitude. */
+#define GPSTAG_LATITUDE 2 /* Indicates the latitude. */
+#define GPSTAG_LONGITUDEREF 3 /* Indicates whether the longitude is east or west longitude. */
+#define GPSTAG_LONGITUDE 4 /* Indicates the longitude. */
+#define GPSTAG_ALTITUDEREF 5 /* Indicates the altitude used as the reference altitude. */
+#define GPSTAG_ALTITUDE 6 /* Indicates the altitude based on the reference in GPSAltitudeRef. */
+#define GPSTAG_TIMESTAMP 7 /*Indicates the time as UTC (Coordinated Universal Time). */
+#define GPSTAG_SATELLITES 8 /*Indicates the GPS satellites used for measurements. */
+#define GPSTAG_STATUS 9 /* Indicates the status of the GPS receiver when the image is recorded. */
+#define GPSTAG_MEASUREMODE 10 /* Indicates the GPS measurement mode. */
+#define GPSTAG_DOP 11 /* Indicates the GPS DOP (data degree of precision). */
+#define GPSTAG_SPEEDREF 12 /* Indicates the unit used to express the GPS receiver speed of movement. */
+#define GPSTAG_SPEED 13 /* Indicates the speed of GPS receiver movement. */
+#define GPSTAG_TRACKREF 14 /* Indicates the reference for giving the direction of GPS receiver movement. */
+#define GPSTAG_TRACK 15 /* Indicates the direction of GPS receiver movement. */
+#define GPSTAG_IMGDIRECTIONREF 16 /* Indicates the reference for giving the direction of the image when it is captured. */
+#define GPSTAG_IMGDIRECTION 17 /* Indicates the direction of the image when it was captured. */
+#define GPSTAG_MAPDATUM 18 /* Indicates the geodetic survey data used by the GPS receiver. (e.g. WGS-84) */
+#define GPSTAG_DESTLATITUDEREF 19 /* Indicates whether the latitude of the destination point is north or south latitude. */
+#define GPSTAG_DESTLATITUDE 20 /* Indicates the latitude of the destination point. */
+#define GPSTAG_DESTLONGITUDEREF 21 /* Indicates whether the longitude of the destination point is east or west longitude. */
+#define GPSTAG_DESTLONGITUDE 22 /* Indicates the longitude of the destination point. */
+#define GPSTAG_DESTBEARINGREF 23 /* Indicates the reference used for giving the bearing to the destination point. */
+#define GPSTAG_DESTBEARING 24 /* Indicates the bearing to the destination point. */
+#define GPSTAG_DESTDISTANCEREF 25 /* Indicates the unit used to express the distance to the destination point. */
+#define GPSTAG_DESTDISTANCE 26 /* Indicates the distance to the destination point. */
+#define GPSTAG_PROCESSINGMETHOD 27 /* A character string recording the name of the method used for location finding. */
+#define GPSTAG_AREAINFORMATION 28 /* A character string recording the name of the GPS area. */
+#define GPSTAG_DATESTAMP 29 /* A character string recording date and time information relative to UTC (Coordinated Universal Time). */
+#define GPSTAG_DIFFERENTIAL 30 /* Indicates whether differential correction is applied to the GPS receiver. */
+#define GPSTAG_GPSHPOSITIONINGERROR 31 /* Indicates horizontal positioning errors in meters. */
+
+#endif /* _TIFF_ */
diff --git a/contrib/libs/libtiff/tiffconf.h b/contrib/libs/libtiff/tiffconf.h
new file mode 100644
index 0000000000..97d19e1abd
--- /dev/null
+++ b/contrib/libs/libtiff/tiffconf.h
@@ -0,0 +1,144 @@
+/*
+ Configuration defines for installed libtiff.
+ This file maintained for backward compatibility. Do not use definitions
+ from this file in your programs.
+*/
+
+/* clang-format off */
+/* clang-format disabled because CMake scripts are very sensitive to the
+ * formatting of this file. configure_file variables of type "" are
+ * modified by clang-format and won't be substituted.
+ */
+
+#ifndef _TIFFCONF_
+#define _TIFFCONF_
+
+
+#include <stddef.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+
+/* Signed 16-bit type */
+#define TIFF_INT16_T int16_t
+
+/* Signed 32-bit type */
+#define TIFF_INT32_T int32_t
+
+/* Signed 64-bit type */
+#define TIFF_INT64_T int64_t
+
+/* Signed 8-bit type */
+#define TIFF_INT8_T int8_t
+
+/* Unsigned 16-bit type */
+#define TIFF_UINT16_T uint16_t
+
+/* Unsigned 32-bit type */
+#define TIFF_UINT32_T uint32_t
+
+/* Unsigned 64-bit type */
+#define TIFF_UINT64_T uint64_t
+
+/* Unsigned 8-bit type */
+#define TIFF_UINT8_T uint8_t
+
+/* Signed size type */
+#define TIFF_SSIZE_T int64_t
+
+/* Compatibility stuff. */
+
+/* Define as 0 or 1 according to the floating point format supported by the
+ machine */
+#define HAVE_IEEEFP 1
+
+/* The concept of HOST_FILLORDER is broken. Since libtiff 4.5.1
+ * this macro will always be hardcoded to FILLORDER_LSB2MSB on all
+ * architectures, to reflect past long behavior of doing so on x86 architecture.
+ * Note however that the default FillOrder used by libtiff is FILLORDER_MSB2LSB,
+ * as mandated per the TIFF specification.
+ * The influence of HOST_FILLORDER is only when passing the 'H' mode in
+ * TIFFOpen().
+ * You should NOT rely on this macro to decide the CPU endianness!
+ * This macro will be removed in libtiff 4.6
+ */
+#define HOST_FILLORDER FILLORDER_LSB2MSB
+
+/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian
+ (Intel) */
+#define HOST_BIGENDIAN 0
+
+/* Support CCITT Group 3 & 4 algorithms */
+#define CCITT_SUPPORT 1
+
+/* Support JPEG compression (requires IJG JPEG library) */
+#define JPEG_SUPPORT 1
+
+/* Support JBIG compression (requires JBIG-KIT library) */
+/* #undef JBIG_SUPPORT */
+
+/* Support LERC compression */
+/* #undef LERC_SUPPORT */
+
+/* Support LogLuv high dynamic range encoding */
+#define LOGLUV_SUPPORT 1
+
+/* Support LZW algorithm */
+#define LZW_SUPPORT 1
+
+/* Support NeXT 2-bit RLE algorithm */
+#define NEXT_SUPPORT 1
+
+/* Support Old JPEG compresson (read contrib/ojpeg/README first! Compilation
+ fails with unpatched IJG JPEG library) */
+#define OJPEG_SUPPORT 1
+
+/* Support Macintosh PackBits algorithm */
+#define PACKBITS_SUPPORT 1
+
+/* Support Pixar log-format algorithm (requires Zlib) */
+#define PIXARLOG_SUPPORT 1
+
+/* Support ThunderScan 4-bit RLE algorithm */
+#define THUNDER_SUPPORT 1
+
+/* Support Deflate compression */
+#define ZIP_SUPPORT 1
+
+/* Support libdeflate enhanced compression */
+/* #undef LIBDEFLATE_SUPPORT */
+
+/* Support strip chopping (whether or not to convert single-strip uncompressed
+ images to multiple strips of ~8Kb to reduce memory usage) */
+#define STRIPCHOP_DEFAULT TIFF_STRIPCHOP
+
+/* Enable SubIFD tag (330) support */
+#define SUBIFD_SUPPORT 1
+
+/* Treat extra sample as alpha (default enabled). The RGBA interface will
+ treat a fourth sample with no EXTRASAMPLE_ value as being ASSOCALPHA. Many
+ packages produce RGBA files but don't mark the alpha properly. */
+#define DEFAULT_EXTRASAMPLE_AS_ALPHA 1
+
+/* Pick up YCbCr subsampling info from the JPEG data stream to support files
+ lacking the tag (default enabled). */
+#define CHECK_JPEG_YCBCR_SUBSAMPLING 1
+
+/* Support MS MDI magic number files as TIFF */
+#define MDI_SUPPORT 1
+
+/*
+ * Feature support definitions.
+ * XXX: These macros are obsoleted. Don't use them in your apps!
+ * Macros stays here for backward compatibility and should be always defined.
+ */
+#define COLORIMETRY_SUPPORT
+#define YCBCR_SUPPORT
+#define CMYK_SUPPORT
+#define ICC_SUPPORT
+#define PHOTOSHOP_SUPPORT
+#define IPTC_SUPPORT
+
+#endif /* _TIFFCONF_ */
+
+/* clang-format on */
diff --git a/contrib/libs/libtiff/tiffio.h b/contrib/libs/libtiff/tiffio.h
new file mode 100644
index 0000000000..20460542f6
--- /dev/null
+++ b/contrib/libs/libtiff/tiffio.h
@@ -0,0 +1,653 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _TIFFIO_
+#define _TIFFIO_
+
+/*
+ * TIFF I/O Library Definitions.
+ */
+#include "tiff.h"
+#include "tiffvers.h"
+
+/*
+ * TIFF is defined as an incomplete type to hide the
+ * library's internal data structures from clients.
+ */
+typedef struct tiff TIFF;
+
+/*
+ * The following typedefs define the intrinsic size of
+ * data types used in the *exported* interfaces. These
+ * definitions depend on the proper definition of types
+ * in tiff.h. Note also that the varargs interface used
+ * to pass tag types and values uses the types defined in
+ * tiff.h directly.
+ *
+ * NB: ttag_t is unsigned int and not unsigned short because
+ * ANSI C requires that the type before the ellipsis be a
+ * promoted type (i.e. one of int, unsigned int, pointer,
+ * or double) and because we defined pseudo-tags that are
+ * outside the range of legal Aldus-assigned tags.
+ * NB: tsize_t is signed and not unsigned because some functions
+ * return -1.
+ * NB: toff_t is not off_t for many reasons; TIFFs max out at
+ * 32-bit file offsets, and BigTIFF maxes out at 64-bit
+ * offsets being the most important, and to ensure use of
+ * a consistently unsigned type across architectures.
+ * Prior to libtiff 4.0, this was an unsigned 32 bit type.
+ */
+/*
+ * this is the machine addressing size type, only it's signed, so make it
+ * int32_t on 32bit machines, int64_t on 64bit machines
+ */
+typedef TIFF_SSIZE_T tmsize_t;
+#define TIFF_TMSIZE_T_MAX (tmsize_t)(SIZE_MAX >> 1)
+
+typedef uint64_t toff_t; /* file offset */
+/* the following are deprecated and should be replaced by their defining
+ counterparts */
+typedef uint32_t ttag_t; /* directory tag */
+typedef uint32_t tdir_t; /* directory index */
+typedef uint16_t tsample_t; /* sample number */
+typedef uint32_t tstrile_t; /* strip or tile number */
+typedef tstrile_t tstrip_t; /* strip number */
+typedef tstrile_t ttile_t; /* tile number */
+typedef tmsize_t tsize_t; /* i/o size in bytes */
+typedef void *tdata_t; /* image data ref */
+
+#if !defined(__WIN32__) && (defined(_WIN32) || defined(WIN32))
+#define __WIN32__
+#endif
+
+/*
+ * On windows you should define USE_WIN32_FILEIO if you are using tif_win32.c
+ * or AVOID_WIN32_FILEIO if you are using something else (like tif_unix.c).
+ *
+ * By default tif_unix.c is assumed.
+ */
+
+#if defined(_WINDOWS) || defined(__WIN32__) || defined(_Windows)
+#if !defined(__CYGWIN) && !defined(AVOID_WIN32_FILEIO) && \
+ !defined(USE_WIN32_FILEIO)
+#define AVOID_WIN32_FILEIO
+#endif
+#endif
+
+#if defined(USE_WIN32_FILEIO)
+#define VC_EXTRALEAN
+#include <windows.h>
+#ifdef __WIN32__
+DECLARE_HANDLE(thandle_t); /* Win32 file handle */
+#else
+typedef HFILE thandle_t; /* client data handle */
+#endif /* __WIN32__ */
+#else
+typedef void *thandle_t; /* client data handle */
+#endif /* USE_WIN32_FILEIO */
+
+/*
+ * Flags to pass to TIFFPrintDirectory to control
+ * printing of data structures that are potentially
+ * very large. Bit-or these flags to enable printing
+ * multiple items.
+ */
+#define TIFFPRINT_NONE 0x0 /* no extra info */
+#define TIFFPRINT_STRIPS 0x1 /* strips/tiles info */
+#define TIFFPRINT_CURVES 0x2 /* color/gray response curves */
+#define TIFFPRINT_COLORMAP 0x4 /* colormap */
+#define TIFFPRINT_JPEGQTABLES 0x100 /* JPEG Q matrices */
+#define TIFFPRINT_JPEGACTABLES 0x200 /* JPEG AC tables */
+#define TIFFPRINT_JPEGDCTABLES 0x200 /* JPEG DC tables */
+
+/*
+ * Colour conversion stuff
+ */
+
+/* reference white */
+#define D65_X0 (95.0470F)
+#define D65_Y0 (100.0F)
+#define D65_Z0 (108.8827F)
+
+#define D50_X0 (96.4250F)
+#define D50_Y0 (100.0F)
+#define D50_Z0 (82.4680F)
+
+/* Structure for holding information about a display device. */
+
+typedef unsigned char TIFFRGBValue; /* 8-bit samples */
+
+typedef struct
+{
+ float d_mat[3][3]; /* XYZ -> luminance matrix */
+ float d_YCR; /* Light o/p for reference white */
+ float d_YCG;
+ float d_YCB;
+ uint32_t d_Vrwr; /* Pixel values for ref. white */
+ uint32_t d_Vrwg;
+ uint32_t d_Vrwb;
+ float d_Y0R; /* Residual light for black pixel */
+ float d_Y0G;
+ float d_Y0B;
+ float d_gammaR; /* Gamma values for the three guns */
+ float d_gammaG;
+ float d_gammaB;
+} TIFFDisplay;
+
+typedef struct
+{ /* YCbCr->RGB support */
+ TIFFRGBValue *clamptab; /* range clamping table */
+ int *Cr_r_tab;
+ int *Cb_b_tab;
+ int32_t *Cr_g_tab;
+ int32_t *Cb_g_tab;
+ int32_t *Y_tab;
+} TIFFYCbCrToRGB;
+
+typedef struct
+{ /* CIE Lab 1976->RGB support */
+ int range; /* Size of conversion table */
+#define CIELABTORGB_TABLE_RANGE 1500
+ float rstep, gstep, bstep;
+ float X0, Y0, Z0; /* Reference white point */
+ TIFFDisplay display;
+ float Yr2r[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yr to r */
+ float Yg2g[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yg to g */
+ float Yb2b[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yb to b */
+} TIFFCIELabToRGB;
+
+/*
+ * RGBA-style image support.
+ */
+typedef struct _TIFFRGBAImage TIFFRGBAImage;
+/*
+ * The image reading and conversion routines invoke
+ * ``put routines'' to copy/image/whatever tiles of
+ * raw image data. A default set of routines are
+ * provided to convert/copy raw image data to 8-bit
+ * packed ABGR format rasters. Applications can supply
+ * alternate routines that unpack the data into a
+ * different format or, for example, unpack the data
+ * and draw the unpacked raster on the display.
+ */
+typedef void (*tileContigRoutine)(TIFFRGBAImage *, uint32_t *, uint32_t,
+ uint32_t, uint32_t, uint32_t, int32_t,
+ int32_t, unsigned char *);
+typedef void (*tileSeparateRoutine)(TIFFRGBAImage *, uint32_t *, uint32_t,
+ uint32_t, uint32_t, uint32_t, int32_t,
+ int32_t, unsigned char *, unsigned char *,
+ unsigned char *, unsigned char *);
+/*
+ * RGBA-reader state.
+ */
+struct _TIFFRGBAImage
+{
+ TIFF *tif; /* image handle */
+ int stoponerr; /* stop on read error */
+ int isContig; /* data is packed/separate */
+ int alpha; /* type of alpha data present */
+ uint32_t width; /* image width */
+ uint32_t height; /* image height */
+ uint16_t bitspersample; /* image bits/sample */
+ uint16_t samplesperpixel; /* image samples/pixel */
+ uint16_t orientation; /* image orientation */
+ uint16_t req_orientation; /* requested orientation */
+ uint16_t photometric; /* image photometric interp */
+ uint16_t *redcmap; /* colormap palette */
+ uint16_t *greencmap;
+ uint16_t *bluecmap;
+ /* get image data routine */
+ int (*get)(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t);
+ /* put decoded strip/tile */
+ union
+ {
+ void (*any)(TIFFRGBAImage *);
+ tileContigRoutine contig;
+ tileSeparateRoutine separate;
+ } put;
+ TIFFRGBValue *Map; /* sample mapping array */
+ uint32_t **BWmap; /* black&white map */
+ uint32_t **PALmap; /* palette image map */
+ TIFFYCbCrToRGB *ycbcr; /* YCbCr conversion state */
+ TIFFCIELabToRGB *cielab; /* CIE L*a*b conversion state */
+
+ uint8_t *UaToAa; /* Unassociated alpha to associated alpha conversion LUT */
+ uint8_t *Bitdepth16To8; /* LUT for conversion from 16bit to 8bit values */
+
+ int row_offset;
+ int col_offset;
+};
+
+/*
+ * Macros for extracting components from the
+ * packed ABGR form returned by TIFFReadRGBAImage.
+ */
+#define TIFFGetR(abgr) ((abgr)&0xff)
+#define TIFFGetG(abgr) (((abgr) >> 8) & 0xff)
+#define TIFFGetB(abgr) (((abgr) >> 16) & 0xff)
+#define TIFFGetA(abgr) (((abgr) >> 24) & 0xff)
+
+/*
+ * A CODEC is a software package that implements decoding,
+ * encoding, or decoding+encoding of a compression algorithm.
+ * The library provides a collection of builtin codecs.
+ * More codecs may be registered through calls to the library
+ * and/or the builtin implementations may be overridden.
+ */
+typedef int (*TIFFInitMethod)(TIFF *, int);
+typedef struct
+{
+ char *name;
+ uint16_t scheme;
+ TIFFInitMethod init;
+} TIFFCodec;
+
+typedef struct
+{
+ uint32_t uNum;
+ uint32_t uDenom;
+} TIFFRational_t;
+
+#include <stdarg.h>
+#include <stdio.h>
+
+/* share internal LogLuv conversion routines? */
+#ifndef LOGLUV_PUBLIC
+#define LOGLUV_PUBLIC 1
+#endif
+
+#if defined(__GNUC__) || defined(__clang__) || defined(__attribute__)
+#define TIFF_ATTRIBUTE(x) __attribute__(x)
+#else
+#define TIFF_ATTRIBUTE(x) /*nothing*/
+#endif
+
+#if defined(c_plusplus) || defined(__cplusplus)
+extern "C"
+{
+#endif
+ typedef void (*TIFFErrorHandler)(const char *, const char *, va_list);
+ typedef void (*TIFFErrorHandlerExt)(thandle_t, const char *, const char *,
+ va_list);
+ typedef int (*TIFFErrorHandlerExtR)(TIFF *, void *user_data, const char *,
+ const char *, va_list);
+ typedef tmsize_t (*TIFFReadWriteProc)(thandle_t, void *, tmsize_t);
+ typedef toff_t (*TIFFSeekProc)(thandle_t, toff_t, int);
+ typedef int (*TIFFCloseProc)(thandle_t);
+ typedef toff_t (*TIFFSizeProc)(thandle_t);
+ typedef int (*TIFFMapFileProc)(thandle_t, void **base, toff_t *size);
+ typedef void (*TIFFUnmapFileProc)(thandle_t, void *base, toff_t size);
+ typedef void (*TIFFExtendProc)(TIFF *);
+
+ extern const char *TIFFGetVersion(void);
+
+ extern const TIFFCodec *TIFFFindCODEC(uint16_t);
+ extern TIFFCodec *TIFFRegisterCODEC(uint16_t, const char *, TIFFInitMethod);
+ extern void TIFFUnRegisterCODEC(TIFFCodec *);
+ extern int TIFFIsCODECConfigured(uint16_t);
+ extern TIFFCodec *TIFFGetConfiguredCODECs(void);
+
+ /*
+ * Auxiliary functions.
+ */
+
+ extern void *_TIFFmalloc(tmsize_t s);
+ extern void *_TIFFcalloc(tmsize_t nmemb, tmsize_t siz);
+ extern void *_TIFFrealloc(void *p, tmsize_t s);
+ extern void _TIFFmemset(void *p, int v, tmsize_t c);
+ extern void _TIFFmemcpy(void *d, const void *s, tmsize_t c);
+ extern int _TIFFmemcmp(const void *p1, const void *p2, tmsize_t c);
+ extern void _TIFFfree(void *p);
+
+ /*
+ ** Stuff, related to tag handling and creating custom tags.
+ */
+ extern int TIFFGetTagListCount(TIFF *);
+ extern uint32_t TIFFGetTagListEntry(TIFF *, int tag_index);
+
+#define TIFF_ANY TIFF_NOTYPE /* for field descriptor searching */
+#define TIFF_VARIABLE -1 /* marker for variable length tags */
+#define TIFF_SPP -2 /* marker for SamplesPerPixel tags */
+#define TIFF_VARIABLE2 -3 /* marker for uint32_t var-length tags */
+
+#define FIELD_CUSTOM 65
+
+ typedef struct _TIFFField TIFFField;
+ typedef struct _TIFFFieldArray TIFFFieldArray;
+
+ extern const TIFFField *TIFFFindField(TIFF *, uint32_t, TIFFDataType);
+ extern const TIFFField *TIFFFieldWithTag(TIFF *, uint32_t);
+ extern const TIFFField *TIFFFieldWithName(TIFF *, const char *);
+
+ extern uint32_t TIFFFieldTag(const TIFFField *);
+ extern const char *TIFFFieldName(const TIFFField *);
+ 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);
+ typedef void (*TIFFPrintMethod)(TIFF *, FILE *, long);
+
+ typedef struct
+ {
+ TIFFVSetMethod vsetfield; /* tag set routine */
+ TIFFVGetMethod vgetfield; /* tag get routine */
+ TIFFPrintMethod printdir; /* directory print routine */
+ } TIFFTagMethods;
+
+ extern TIFFTagMethods *TIFFAccessTagMethods(TIFF *);
+ extern void *TIFFGetClientInfo(TIFF *, const char *);
+ extern void TIFFSetClientInfo(TIFF *, void *, const char *);
+
+ extern void TIFFCleanup(TIFF *tif);
+ extern void TIFFClose(TIFF *tif);
+ extern int TIFFFlush(TIFF *tif);
+ extern int TIFFFlushData(TIFF *tif);
+ extern int TIFFGetField(TIFF *tif, uint32_t tag, ...);
+ extern int TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap);
+ extern int TIFFGetFieldDefaulted(TIFF *tif, uint32_t tag, ...);
+ extern int TIFFVGetFieldDefaulted(TIFF *tif, uint32_t tag, va_list ap);
+ extern int TIFFReadDirectory(TIFF *tif);
+ extern int TIFFReadCustomDirectory(TIFF *tif, toff_t diroff,
+ const TIFFFieldArray *infoarray);
+ extern int TIFFReadEXIFDirectory(TIFF *tif, toff_t diroff);
+ extern int TIFFReadGPSDirectory(TIFF *tif, toff_t diroff);
+ extern uint64_t TIFFScanlineSize64(TIFF *tif);
+ extern tmsize_t TIFFScanlineSize(TIFF *tif);
+ extern uint64_t TIFFRasterScanlineSize64(TIFF *tif);
+ extern tmsize_t TIFFRasterScanlineSize(TIFF *tif);
+ extern uint64_t TIFFStripSize64(TIFF *tif);
+ extern tmsize_t TIFFStripSize(TIFF *tif);
+ extern uint64_t TIFFRawStripSize64(TIFF *tif, uint32_t strip);
+ extern tmsize_t TIFFRawStripSize(TIFF *tif, uint32_t strip);
+ extern uint64_t TIFFVStripSize64(TIFF *tif, uint32_t nrows);
+ extern tmsize_t TIFFVStripSize(TIFF *tif, uint32_t nrows);
+ extern uint64_t TIFFTileRowSize64(TIFF *tif);
+ extern tmsize_t TIFFTileRowSize(TIFF *tif);
+ extern uint64_t TIFFTileSize64(TIFF *tif);
+ extern tmsize_t TIFFTileSize(TIFF *tif);
+ extern uint64_t TIFFVTileSize64(TIFF *tif, uint32_t nrows);
+ extern tmsize_t TIFFVTileSize(TIFF *tif, uint32_t nrows);
+ extern uint32_t TIFFDefaultStripSize(TIFF *tif, uint32_t request);
+ extern void TIFFDefaultTileSize(TIFF *, uint32_t *, uint32_t *);
+ extern int TIFFFileno(TIFF *);
+ extern int TIFFSetFileno(TIFF *, int);
+ extern thandle_t TIFFClientdata(TIFF *);
+ extern thandle_t TIFFSetClientdata(TIFF *, thandle_t);
+ extern int TIFFGetMode(TIFF *);
+ extern int TIFFSetMode(TIFF *, int);
+ extern int TIFFIsTiled(TIFF *);
+ 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 TIFFCloseProc TIFFGetCloseProc(TIFF *);
+ extern TIFFSizeProc TIFFGetSizeProc(TIFF *);
+ extern TIFFMapFileProc TIFFGetMapFileProc(TIFF *);
+ extern TIFFUnmapFileProc TIFFGetUnmapFileProc(TIFF *);
+ extern uint32_t TIFFCurrentRow(TIFF *);
+ extern tdir_t TIFFCurrentDirectory(TIFF *);
+ extern tdir_t TIFFNumberOfDirectories(TIFF *);
+ extern uint64_t TIFFCurrentDirOffset(TIFF *);
+ extern uint32_t TIFFCurrentStrip(TIFF *);
+ extern uint32_t TIFFCurrentTile(TIFF *tif);
+ extern int TIFFReadBufferSetup(TIFF *tif, void *bp, tmsize_t size);
+ extern int TIFFWriteBufferSetup(TIFF *tif, void *bp, tmsize_t size);
+ extern int TIFFSetupStrips(TIFF *);
+ extern int TIFFWriteCheck(TIFF *, int, const char *);
+ extern void TIFFFreeDirectory(TIFF *);
+ extern int TIFFCreateDirectory(TIFF *);
+ extern int TIFFCreateCustomDirectory(TIFF *, const TIFFFieldArray *);
+ extern int TIFFCreateEXIFDirectory(TIFF *);
+ extern int TIFFCreateGPSDirectory(TIFF *);
+ extern int TIFFLastDirectory(TIFF *);
+ extern int TIFFSetDirectory(TIFF *, tdir_t);
+ extern int TIFFSetSubDirectory(TIFF *, uint64_t);
+ extern int TIFFUnlinkDirectory(TIFF *, tdir_t);
+ extern int TIFFSetField(TIFF *, uint32_t, ...);
+ extern int TIFFVSetField(TIFF *, uint32_t, va_list);
+ extern int TIFFUnsetField(TIFF *, uint32_t);
+ extern int TIFFWriteDirectory(TIFF *);
+ extern int TIFFWriteCustomDirectory(TIFF *, uint64_t *);
+ extern int TIFFCheckpointDirectory(TIFF *);
+ extern int TIFFRewriteDirectory(TIFF *);
+ extern int TIFFDeferStrileArrayWriting(TIFF *);
+ extern int TIFFForceStrileArrayWriting(TIFF *);
+
+#if defined(c_plusplus) || defined(__cplusplus)
+ extern void TIFFPrintDirectory(TIFF *, FILE *, long = 0);
+ extern int TIFFReadScanline(TIFF *tif, void *buf, uint32_t row,
+ uint16_t sample = 0);
+ extern int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row,
+ uint16_t sample = 0);
+ extern int TIFFReadRGBAImage(TIFF *, uint32_t, uint32_t, uint32_t *,
+ int = 0);
+ extern int TIFFReadRGBAImageOriented(TIFF *, uint32_t, uint32_t, uint32_t *,
+ int = ORIENTATION_BOTLEFT, int = 0);
+#else
+extern void TIFFPrintDirectory(TIFF *, FILE *, long);
+extern int TIFFReadScanline(TIFF *tif, void *buf, uint32_t row,
+ uint16_t sample);
+extern int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row,
+ uint16_t sample);
+extern int TIFFReadRGBAImage(TIFF *, uint32_t, uint32_t, uint32_t *, int);
+extern int TIFFReadRGBAImageOriented(TIFF *, uint32_t, uint32_t, uint32_t *,
+ int, int);
+#endif
+
+ extern int TIFFReadRGBAStrip(TIFF *, uint32_t, uint32_t *);
+ extern int TIFFReadRGBATile(TIFF *, uint32_t, uint32_t, uint32_t *);
+ extern int TIFFReadRGBAStripExt(TIFF *, uint32_t, uint32_t *,
+ int stop_on_error);
+ extern int TIFFReadRGBATileExt(TIFF *, uint32_t, uint32_t, uint32_t *,
+ int stop_on_error);
+ extern int TIFFRGBAImageOK(TIFF *, char[1024]);
+ extern int TIFFRGBAImageBegin(TIFFRGBAImage *, TIFF *, int, char[1024]);
+ extern int TIFFRGBAImageGet(TIFFRGBAImage *, uint32_t *, uint32_t,
+ uint32_t);
+ extern void TIFFRGBAImageEnd(TIFFRGBAImage *);
+
+ extern const char *TIFFFileName(TIFF *);
+ extern const char *TIFFSetFileName(TIFF *, const char *);
+ extern void TIFFError(const char *, const char *, ...)
+ TIFF_ATTRIBUTE((__format__(__printf__, 2, 3)));
+ extern void TIFFErrorExt(thandle_t, const char *, const char *, ...)
+ TIFF_ATTRIBUTE((__format__(__printf__, 3, 4)));
+ extern void TIFFWarning(const char *, const char *, ...)
+ TIFF_ATTRIBUTE((__format__(__printf__, 2, 3)));
+ extern void TIFFWarningExt(thandle_t, const char *, const char *, ...)
+ TIFF_ATTRIBUTE((__format__(__printf__, 3, 4)));
+ extern TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler);
+ extern TIFFErrorHandlerExt TIFFSetErrorHandlerExt(TIFFErrorHandlerExt);
+ extern TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler);
+ extern TIFFErrorHandlerExt TIFFSetWarningHandlerExt(TIFFErrorHandlerExt);
+
+ extern void TIFFWarningExtR(TIFF *, const char *, const char *, ...)
+ TIFF_ATTRIBUTE((__format__(__printf__, 3, 4)));
+ extern void TIFFErrorExtR(TIFF *, const char *, const char *, ...)
+ TIFF_ATTRIBUTE((__format__(__printf__, 3, 4)));
+
+ typedef struct TIFFOpenOptions TIFFOpenOptions;
+ extern TIFFOpenOptions *TIFFOpenOptionsAlloc(void);
+ extern void TIFFOpenOptionsFree(TIFFOpenOptions *);
+ extern void
+ TIFFOpenOptionsSetMaxSingleMemAlloc(TIFFOpenOptions *opts,
+ tmsize_t max_single_mem_alloc);
+ extern void
+ TIFFOpenOptionsSetErrorHandlerExtR(TIFFOpenOptions *opts,
+ TIFFErrorHandlerExtR handler,
+ void *errorhandler_user_data);
+ extern void
+ TIFFOpenOptionsSetWarningHandlerExtR(TIFFOpenOptions *opts,
+ TIFFErrorHandlerExtR handler,
+ void *warnhandler_user_data);
+
+ extern TIFF *TIFFOpen(const char *, const char *);
+ extern TIFF *TIFFOpenExt(const char *, const char *, TIFFOpenOptions *opts);
+#ifdef __WIN32__
+ extern TIFF *TIFFOpenW(const wchar_t *, const char *);
+ extern TIFF *TIFFOpenWExt(const wchar_t *, const char *,
+ TIFFOpenOptions *opts);
+#endif /* __WIN32__ */
+ extern TIFF *TIFFFdOpen(int, const char *, const char *);
+ extern TIFF *TIFFFdOpenExt(int, const char *, const char *,
+ TIFFOpenOptions *opts);
+ extern TIFF *TIFFClientOpen(const char *, const char *, thandle_t,
+ TIFFReadWriteProc, TIFFReadWriteProc,
+ TIFFSeekProc, TIFFCloseProc, TIFFSizeProc,
+ TIFFMapFileProc, TIFFUnmapFileProc);
+ extern TIFF *TIFFClientOpenExt(const char *, const char *, thandle_t,
+ TIFFReadWriteProc, TIFFReadWriteProc,
+ TIFFSeekProc, TIFFCloseProc, TIFFSizeProc,
+ TIFFMapFileProc, TIFFUnmapFileProc,
+ TIFFOpenOptions *opts);
+ extern TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc);
+ extern uint32_t TIFFComputeTile(TIFF *tif, uint32_t x, uint32_t y,
+ uint32_t z, uint16_t s);
+ extern int TIFFCheckTile(TIFF *tif, uint32_t x, uint32_t y, uint32_t z,
+ uint16_t s);
+ extern uint32_t TIFFNumberOfTiles(TIFF *);
+ extern tmsize_t TIFFReadTile(TIFF *tif, void *buf, uint32_t x, uint32_t y,
+ uint32_t z, uint16_t s);
+ extern tmsize_t TIFFWriteTile(TIFF *tif, void *buf, uint32_t x, uint32_t y,
+ uint32_t z, uint16_t s);
+ extern uint32_t TIFFComputeStrip(TIFF *, uint32_t, uint16_t);
+ extern uint32_t TIFFNumberOfStrips(TIFF *);
+ extern tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32_t strip, void *buf,
+ tmsize_t size);
+ extern tmsize_t TIFFReadRawStrip(TIFF *tif, uint32_t strip, void *buf,
+ tmsize_t size);
+ extern tmsize_t TIFFReadEncodedTile(TIFF *tif, uint32_t tile, void *buf,
+ tmsize_t size);
+ extern tmsize_t TIFFReadRawTile(TIFF *tif, uint32_t tile, void *buf,
+ tmsize_t size);
+ extern int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf,
+ tmsize_t insize, void *outbuf,
+ tmsize_t outsize);
+ extern tmsize_t TIFFWriteEncodedStrip(TIFF *tif, uint32_t strip, void *data,
+ tmsize_t cc);
+ 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 within TIFF file. */
+ extern void TIFFSetWriteOffset(TIFF *tif, toff_t off);
+ extern void TIFFSwabShort(uint16_t *);
+ extern void TIFFSwabLong(uint32_t *);
+ extern void TIFFSwabLong8(uint64_t *);
+ extern void TIFFSwabFloat(float *);
+ extern void TIFFSwabDouble(double *);
+ extern void TIFFSwabArrayOfShort(uint16_t *wp, tmsize_t n);
+ extern void TIFFSwabArrayOfTriples(uint8_t *tp, tmsize_t n);
+ extern void TIFFSwabArrayOfLong(uint32_t *lp, tmsize_t n);
+ extern void TIFFSwabArrayOfLong8(uint64_t *lp, tmsize_t n);
+ extern void TIFFSwabArrayOfFloat(float *fp, tmsize_t n);
+ extern void TIFFSwabArrayOfDouble(double *dp, tmsize_t n);
+ extern void TIFFReverseBits(uint8_t *cp, tmsize_t n);
+ extern const unsigned char *TIFFGetBitRevTable(int);
+
+ extern uint64_t TIFFGetStrileOffset(TIFF *tif, uint32_t strile);
+ extern uint64_t TIFFGetStrileByteCount(TIFF *tif, uint32_t strile);
+ extern uint64_t TIFFGetStrileOffsetWithErr(TIFF *tif, uint32_t strile,
+ int *pbErr);
+ extern uint64_t TIFFGetStrileByteCountWithErr(TIFF *tif, uint32_t strile,
+ int *pbErr);
+
+#ifdef LOGLUV_PUBLIC
+#define U_NEU 0.210526316
+#define V_NEU 0.473684211
+#define UVSCALE 410.
+ extern double LogL16toY(int);
+ extern double LogL10toY(int);
+ extern void XYZtoRGB24(float *, uint8_t *);
+ extern int uv_decode(double *, double *, int);
+ extern void LogLuv24toXYZ(uint32_t, float *);
+ extern void LogLuv32toXYZ(uint32_t, float *);
+#if defined(c_plusplus) || defined(__cplusplus)
+ extern int LogL16fromY(double, int = SGILOGENCODE_NODITHER);
+ extern int LogL10fromY(double, int = SGILOGENCODE_NODITHER);
+ extern int uv_encode(double, double, int = SGILOGENCODE_NODITHER);
+ extern uint32_t LogLuv24fromXYZ(float *, int = SGILOGENCODE_NODITHER);
+ extern uint32_t LogLuv32fromXYZ(float *, int = SGILOGENCODE_NODITHER);
+#else
+ extern int LogL16fromY(double, int);
+ extern int LogL10fromY(double, int);
+ extern int uv_encode(double, double, int);
+ extern uint32_t LogLuv24fromXYZ(float *, int);
+ extern uint32_t LogLuv32fromXYZ(float *, int);
+#endif
+#endif /* LOGLUV_PUBLIC */
+
+ extern int TIFFCIELabToRGBInit(TIFFCIELabToRGB *, const TIFFDisplay *,
+ float *);
+ extern void TIFFCIELabToXYZ(TIFFCIELabToRGB *, uint32_t, int32_t, int32_t,
+ float *, float *, float *);
+ extern void TIFFXYZToRGB(TIFFCIELabToRGB *, float, float, float, uint32_t *,
+ uint32_t *, uint32_t *);
+
+ extern int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *, float *, float *);
+ extern void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *, uint32_t, int32_t, int32_t,
+ uint32_t *, uint32_t *, uint32_t *);
+
+ /****************************************************************************
+ * O B S O L E T E D I N T E R F A C E S
+ *
+ * Don't use this stuff in your applications, it may be removed in the
+ *future libtiff versions.
+ ****************************************************************************/
+ typedef struct
+ {
+ ttag_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 */
+ unsigned short field_bit; /* bit in fieldsset bit vector */
+ unsigned char field_oktochange; /* if true, can change while writing */
+ unsigned char field_passcount; /* if true, pass dir count on set */
+ char *field_name; /* ASCII name */
+ } TIFFFieldInfo;
+
+ extern int TIFFMergeFieldInfo(TIFF *, const TIFFFieldInfo[], uint32_t);
+
+#if defined(c_plusplus) || defined(__cplusplus)
+}
+#endif
+
+#endif /* _TIFFIO_ */
diff --git a/contrib/libs/libtiff/tiffiop.h b/contrib/libs/libtiff/tiffiop.h
new file mode 100644
index 0000000000..fbf7b0700b
--- /dev/null
+++ b/contrib/libs/libtiff/tiffiop.h
@@ -0,0 +1,523 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * 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.
+ *
+ * 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
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _TIFFIOP_
+#define _TIFFIOP_
+/*
+ * ``Library-private'' definitions.
+ */
+
+#include "tif_config.h"
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include <string.h>
+
+#ifdef HAVE_ASSERT_H
+#include <assert.h>
+#else
+#define assert(x)
+#endif
+
+#include "tif_hash_set.h"
+#include "tiffio.h"
+
+#include "tif_dir.h"
+
+#include <limits.h>
+
+#ifndef STRIP_SIZE_DEFAULT
+#define STRIP_SIZE_DEFAULT 8192
+#endif
+
+#ifndef TIFF_MAX_DIR_COUNT
+#define TIFF_MAX_DIR_COUNT 1048576
+#endif
+
+#define TIFF_NON_EXISTENT_DIR_NUMBER UINT_MAX
+
+#define streq(a, b) (strcmp(a, b) == 0)
+#define strneq(a, b, n) (strncmp(a, b, n) == 0)
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+typedef struct client_info
+{
+ struct client_info *next;
+ void *data;
+ char *name;
+} TIFFClientInfoLink;
+
+/*
+ * Typedefs for ``method pointers'' used internally.
+ * these are deprecated and provided only for backwards compatibility.
+ */
+typedef unsigned char tidataval_t; /* internal image data value type */
+typedef tidataval_t *tidata_t; /* reference to internal image data */
+
+typedef void (*TIFFVoidMethod)(TIFF *);
+typedef int (*TIFFBoolMethod)(TIFF *);
+typedef int (*TIFFPreMethod)(TIFF *, uint16_t);
+typedef int (*TIFFCodeMethod)(TIFF *tif, uint8_t *buf, tmsize_t size,
+ uint16_t sample);
+typedef int (*TIFFSeekMethod)(TIFF *, uint32_t);
+typedef void (*TIFFPostMethod)(TIFF *tif, uint8_t *buf, tmsize_t size);
+typedef uint32_t (*TIFFStripMethod)(TIFF *, uint32_t);
+typedef void (*TIFFTileMethod)(TIFF *, uint32_t *, uint32_t *);
+
+struct TIFFOffsetAndDirNumber
+{
+ uint64_t offset;
+ tdir_t dirNumber;
+};
+typedef struct TIFFOffsetAndDirNumber TIFFOffsetAndDirNumber;
+
+struct tiff
+{
+ char *tif_name; /* name of open file */
+ int tif_fd; /* open file descriptor */
+ int tif_mode; /* open mode (O_*) */
+ uint32_t tif_flags;
+#define TIFF_FILLORDER 0x00003U /* natural bit fill order for machine */
+#define TIFF_DIRTYHEADER 0x00004U /* header must be written on close */
+#define TIFF_DIRTYDIRECT 0x00008U /* current directory must be written */
+#define TIFF_BUFFERSETUP 0x00010U /* data buffers setup */
+#define TIFF_CODERSETUP 0x00020U /* encoder/decoder setup done */
+#define TIFF_BEENWRITING 0x00040U /* written 1+ scanlines to file */
+#define TIFF_SWAB 0x00080U /* byte swap file information */
+#define TIFF_NOBITREV 0x00100U /* inhibit bit reversal logic */
+#define TIFF_MYBUFFER 0x00200U /* my raw data buffer; free on close */
+#define TIFF_ISTILED 0x00400U /* file is tile, not strip- based */
+#define TIFF_MAPPED 0x00800U /* file is mapped into memory */
+#define TIFF_POSTENCODE 0x01000U /* need call to postencode routine */
+#define TIFF_INSUBIFD 0x02000U /* currently writing a subifd */
+#define TIFF_UPSAMPLED 0x04000U /* library is doing data up-sampling */
+#define TIFF_STRIPCHOP 0x08000U /* enable strip chopping support */
+#define TIFF_HEADERONLY \
+ 0x10000U /* read header only, do not process the first directory */
+#define TIFF_NOREADRAW \
+ 0x20000U /* skip reading of raw uncompressed image data */
+#define TIFF_INCUSTOMIFD 0x40000U /* currently writing a custom IFD */
+#define TIFF_BIGTIFF 0x80000U /* read/write bigtiff */
+#define TIFF_BUF4WRITE 0x100000U /* rawcc bytes are for writing */
+#define TIFF_DIRTYSTRIP 0x200000U /* stripoffsets/stripbytecount dirty*/
+#define TIFF_PERSAMPLE 0x400000U /* get/set per sample tags as arrays */
+#define TIFF_BUFFERMMAP \
+ 0x800000U /* read buffer (tif_rawdata) points into mmap() memory */
+#define TIFF_DEFERSTRILELOAD \
+ 0x1000000U /* defer strip/tile offset/bytecount array loading. */
+#define TIFF_LAZYSTRILELOAD \
+ 0x2000000U /* lazy/ondemand loading of strip/tile offset/bytecount values. \
+ Only used if TIFF_DEFERSTRILELOAD is set and in read-only \
+ mode */
+#define TIFF_CHOPPEDUPARRAYS \
+ 0x4000000U /* set when allocChoppedUpStripArrays() has modified strip \
+ array */
+ uint64_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 */
+ TIFFHashSet *tif_map_dir_offset_to_number;
+ TIFFHashSet *tif_map_dir_number_to_offset;
+ int tif_setdirectory_force_absolute; /* switch between relative and absolute
+ stepping in TIFFSetDirectory() */
+ TIFFDirectory tif_dir; /* internal rep of current directory */
+ TIFFDirectory
+ tif_customdir; /* custom IFDs are separated from the main ones */
+ union
+ {
+ TIFFHeaderCommon common;
+ TIFFHeaderClassic classic;
+ TIFFHeaderBig big;
+ } tif_header;
+ uint16_t tif_header_size; /* file's header block and its length */
+ uint32_t tif_row; /* current scanline */
+ tdir_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 */
+ uint64_t tif_subifdoff; /* offset for patching SubIFD link */
+ /* tiling support */
+ uint32_t tif_col; /* current column (offset by row too) */
+ uint32_t tif_curtile; /* current tile for read/write */
+ tmsize_t tif_tilesize; /* # of bytes in a tile */
+ /* compression scheme hooks */
+ int tif_decodestatus;
+ TIFFBoolMethod tif_fixuptags; /* called in TIFFReadDirectory */
+ TIFFBoolMethod tif_setupdecode; /* called once before predecode */
+ TIFFPreMethod tif_predecode; /* pre- row/strip/tile decoding */
+ TIFFBoolMethod tif_setupencode; /* called once before preencode */
+ int tif_encodestatus;
+ TIFFPreMethod tif_preencode; /* pre- row/strip/tile encoding */
+ TIFFBoolMethod tif_postencode; /* post- row/strip/tile encoding */
+ TIFFCodeMethod tif_decoderow; /* scanline decoding routine */
+ TIFFCodeMethod tif_encoderow; /* scanline encoding routine */
+ TIFFCodeMethod tif_decodestrip; /* strip decoding routine */
+ TIFFCodeMethod tif_encodestrip; /* strip encoding routine */
+ TIFFCodeMethod tif_decodetile; /* tile decoding routine */
+ TIFFCodeMethod tif_encodetile; /* tile encoding routine */
+ TIFFVoidMethod tif_close; /* cleanup-on-close routine */
+ TIFFSeekMethod tif_seek; /* position within a strip routine */
+ TIFFVoidMethod tif_cleanup; /* cleanup state routine */
+ TIFFStripMethod tif_defstripsize; /* calculate/constrain strip size */
+ TIFFTileMethod tif_deftilesize; /* calculate/constrain tile size */
+ uint8_t *tif_data; /* compression scheme private data */
+ /* input/output buffering */
+ tmsize_t tif_scanlinesize; /* # of bytes in a scanline */
+ tmsize_t tif_scanlineskew; /* scanline skew for reading strips */
+ uint8_t *tif_rawdata; /* raw data buffer */
+ tmsize_t tif_rawdatasize; /* # of bytes in raw data buffer */
+ tmsize_t tif_rawdataoff; /* rawdata offset within strip */
+ tmsize_t tif_rawdataloaded; /* amount of data in rawdata */
+ uint8_t *tif_rawcp; /* current spot in raw buffer */
+ tmsize_t tif_rawcc; /* bytes unread from raw buffer */
+ /* memory-mapped file support */
+ uint8_t *tif_base; /* base of mapped file */
+ tmsize_t tif_size; /* size of mapped file region (bytes, thus tmsize_t) */
+ TIFFMapFileProc tif_mapproc; /* map file method */
+ TIFFUnmapFileProc tif_unmapproc; /* unmap file method */
+ /* input/output callback methods */
+ thandle_t tif_clientdata; /* callback parameter */
+ TIFFReadWriteProc tif_readproc; /* read method */
+ TIFFReadWriteProc tif_writeproc; /* write method */
+ TIFFSeekProc tif_seekproc; /* lseek method */
+ TIFFCloseProc tif_closeproc; /* close method */
+ TIFFSizeProc tif_sizeproc; /* filesize method */
+ /* post-decoding support */
+ TIFFPostMethod tif_postdecode; /* post decoding routine */
+ /* tag support */
+ TIFFField **tif_fields; /* sorted table of registered tags */
+ size_t tif_nfields; /* # entries in registered tag table */
+ const TIFFField *tif_foundfield; /* cached pointer to already found tag */
+ TIFFTagMethods tif_tagmethods; /* tag get/set/print routines */
+ TIFFClientInfoLink *tif_clientinfo; /* extra client information. */
+ /* Backward compatibility stuff. We need these two fields for
+ * setting up an old tag extension scheme. */
+ TIFFFieldArray *tif_fieldscompat;
+ size_t tif_nfieldscompat;
+ /* Error handler support */
+ TIFFErrorHandlerExtR tif_errorhandler;
+ void *tif_errorhandler_user_data;
+ TIFFErrorHandlerExtR tif_warnhandler;
+ void *tif_warnhandler_user_data;
+ tmsize_t tif_max_single_mem_alloc; /* in bytes. 0 for unlimited */
+};
+
+struct TIFFOpenOptions
+{
+ TIFFErrorHandlerExtR errorhandler; /* may be NULL */
+ void *errorhandler_user_data; /* may be NULL */
+ TIFFErrorHandlerExtR warnhandler; /* may be NULL */
+ void *warnhandler_user_data; /* may be NULL */
+ tmsize_t max_single_mem_alloc; /* in bytes. 0 for unlimited */
+};
+
+#define isPseudoTag(t) (t > 0xffff) /* is tag value normal or pseudo */
+
+#define isTiled(tif) (((tif)->tif_flags & TIFF_ISTILED) != 0)
+#define isMapped(tif) (((tif)->tif_flags & TIFF_MAPPED) != 0)
+#define isFillOrder(tif, o) (((tif)->tif_flags & (o)) != 0)
+#define isUpSampled(tif) (((tif)->tif_flags & TIFF_UPSAMPLED) != 0)
+#define TIFFReadFile(tif, buf, size) \
+ ((*(tif)->tif_readproc)((tif)->tif_clientdata, (buf), (size)))
+#define TIFFWriteFile(tif, buf, size) \
+ ((*(tif)->tif_writeproc)((tif)->tif_clientdata, (buf), (size)))
+#define TIFFSeekFile(tif, off, whence) \
+ ((*(tif)->tif_seekproc)((tif)->tif_clientdata, (off), (whence)))
+#define TIFFCloseFile(tif) ((*(tif)->tif_closeproc)((tif)->tif_clientdata))
+#define TIFFGetFileSize(tif) ((*(tif)->tif_sizeproc)((tif)->tif_clientdata))
+#define TIFFMapFileContents(tif, paddr, psize) \
+ ((*(tif)->tif_mapproc)((tif)->tif_clientdata, (paddr), (psize)))
+#define TIFFUnmapFileContents(tif, addr, size) \
+ ((*(tif)->tif_unmapproc)((tif)->tif_clientdata, (addr), (size)))
+
+/*
+ * Default Read/Seek/Write definitions.
+ */
+#ifndef ReadOK
+#define ReadOK(tif, buf, size) (TIFFReadFile((tif), (buf), (size)) == (size))
+#endif
+#ifndef SeekOK
+#define SeekOK(tif, off) _TIFFSeekOK(tif, off)
+#endif
+#ifndef WriteOK
+#define WriteOK(tif, buf, size) (TIFFWriteFile((tif), (buf), (size)) == (size))
+#endif
+
+/* NB: the uint32_t casts are to silence certain ANSI-C compilers */
+#define TIFFhowmany_32(x, y) \
+ (((uint32_t)x < (0xffffffff - (uint32_t)(y - 1))) \
+ ? ((((uint32_t)(x)) + (((uint32_t)(y)) - 1)) / ((uint32_t)(y))) \
+ : 0U)
+/* Variant of TIFFhowmany_32() that doesn't return 0 if x close to MAXUINT. */
+/* Caution: TIFFhowmany_32_maxuint_compat(x,y)*y might overflow */
+#define TIFFhowmany_32_maxuint_compat(x, y) \
+ (((uint32_t)(x) / (uint32_t)(y)) + \
+ ((((uint32_t)(x) % (uint32_t)(y)) != 0) ? 1 : 0))
+#define TIFFhowmany8_32(x) \
+ (((x)&0x07) ? ((uint32_t)(x) >> 3) + 1 : (uint32_t)(x) >> 3)
+#define TIFFroundup_32(x, y) (TIFFhowmany_32(x, y) * (y))
+#define TIFFhowmany_64(x, y) \
+ ((((uint64_t)(x)) + (((uint64_t)(y)) - 1)) / ((uint64_t)(y)))
+#define TIFFhowmany8_64(x) \
+ (((x)&0x07) ? ((uint64_t)(x) >> 3) + 1 : (uint64_t)(x) >> 3)
+#define TIFFroundup_64(x, y) (TIFFhowmany_64(x, y) * (y))
+
+/* Safe multiply which returns zero if there is an *unsigned* integer overflow.
+ * This macro is not safe for *signed* integer types */
+#define TIFFSafeMultiply(t, v, m) \
+ ((((t)(m) != (t)0) && (((t)(((v) * (m)) / (m))) == (t)(v))) \
+ ? (t)((v) * (m)) \
+ : (t)0)
+
+#define TIFFmax(A, B) ((A) > (B) ? (A) : (B))
+#define TIFFmin(A, B) ((A) < (B) ? (A) : (B))
+
+#define TIFFArrayCount(a) (sizeof(a) / sizeof((a)[0]))
+
+/*
+ Support for large files.
+
+ Windows read/write APIs support only 'unsigned int' rather than 'size_t'.
+ Windows off_t is only 32-bit, even in 64-bit builds.
+*/
+#if defined(HAVE_FSEEKO)
+/*
+ Use fseeko() and ftello() if they are available since they use
+ 'off_t' rather than 'long'. It is wrong to use fseeko() and
+ ftello() only on systems with special LFS support since some systems
+ (e.g. FreeBSD) support a 64-bit off_t by default.
+
+ For MinGW, __MSVCRT_VERSION__ must be at least 0x800 to expose these
+ interfaces. The MinGW compiler must support the requested version. MinGW
+ does not distribute the CRT (it is supplied by Microsoft) so the correct CRT
+ must be available on the target computer in order for the program to run.
+*/
+#if defined(HAVE_FSEEKO)
+#define fseek(stream, offset, whence) fseeko(stream, offset, whence)
+#define ftell(stream, offset, whence) ftello(stream, offset, whence)
+#endif
+#endif
+#if defined(__WIN32__) && !(defined(_MSC_VER) && _MSC_VER < 1400) && \
+ !(defined(__MSVCRT_VERSION__) && __MSVCRT_VERSION__ < 0x800)
+typedef unsigned int TIFFIOSize_t;
+#define _TIFF_lseek_f(fildes, offset, whence) \
+ _lseeki64(fildes, /* __int64 */ offset, whence)
+/* #define _TIFF_tell_f(fildes) /\* __int64 *\/ _telli64(fildes) */
+#define _TIFF_fseek_f(stream, offset, whence) \
+ _fseeki64(stream, /* __int64 */ offset, whence)
+#define _TIFF_fstat_f(fildes, stat_buff) \
+ _fstati64(fildes, /* struct _stati64 */ stat_buff)
+/* #define _TIFF_ftell_f(stream) /\* __int64 *\/ _ftelli64(stream) */
+/* #define _TIFF_stat_f(path,stat_buff) _stati64(path,/\* struct _stati64 *\/
+ * stat_buff) */
+#define _TIFF_stat_s struct _stati64
+#define _TIFF_off_t __int64
+#else
+typedef size_t TIFFIOSize_t;
+#define _TIFF_lseek_f(fildes, offset, whence) lseek(fildes, offset, whence)
+/* #define _TIFF_tell_f(fildes) (_TIFF_lseek_f(fildes,0,SEEK_CUR)) */
+#define _TIFF_fseek_f(stream, offset, whence) fseek(stream, offset, whence)
+#define _TIFF_fstat_f(fildes, stat_buff) fstat(fildes, stat_buff)
+/* #define _TIFF_ftell_f(stream) ftell(stream) */
+/* #define _TIFF_stat_f(path,stat_buff) stat(path,stat_buff) */
+#define _TIFF_stat_s struct stat
+#define _TIFF_off_t off_t
+#endif
+
+#if defined(__has_attribute) && defined(__clang__)
+#if __has_attribute(no_sanitize)
+#define TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW \
+ __attribute__((no_sanitize("unsigned-integer-overflow")))
+#else
+#define TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
+#endif
+#else
+#define TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
+#endif
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+ extern int _TIFFgetMode(TIFFOpenOptions *opts, thandle_t clientdata,
+ const char *mode, const char *module);
+ extern int _TIFFNoRowEncode(TIFF *tif, uint8_t *pp, tmsize_t cc,
+ uint16_t s);
+ extern int _TIFFNoStripEncode(TIFF *tif, uint8_t *pp, tmsize_t cc,
+ uint16_t s);
+ extern int _TIFFNoTileEncode(TIFF *, uint8_t *pp, tmsize_t cc, uint16_t s);
+ extern int _TIFFNoRowDecode(TIFF *tif, uint8_t *pp, tmsize_t cc,
+ uint16_t s);
+ extern int _TIFFNoStripDecode(TIFF *tif, uint8_t *pp, tmsize_t cc,
+ uint16_t s);
+ extern int _TIFFNoTileDecode(TIFF *, uint8_t *pp, tmsize_t cc, uint16_t s);
+ extern void _TIFFNoPostDecode(TIFF *tif, uint8_t *buf, tmsize_t cc);
+ extern int _TIFFNoPreCode(TIFF *tif, uint16_t s);
+ extern int _TIFFNoSeek(TIFF *tif, uint32_t off);
+ extern void _TIFFSwab16BitData(TIFF *tif, uint8_t *buf, tmsize_t cc);
+ extern void _TIFFSwab24BitData(TIFF *tif, uint8_t *buf, tmsize_t cc);
+ extern void _TIFFSwab32BitData(TIFF *tif, uint8_t *buf, tmsize_t cc);
+ extern void _TIFFSwab64BitData(TIFF *tif, uint8_t *buf, tmsize_t cc);
+ extern int TIFFFlushData1(TIFF *tif);
+ extern int TIFFDefaultDirectory(TIFF *tif);
+ extern void _TIFFSetDefaultCompressionState(TIFF *tif);
+ extern int _TIFFRewriteField(TIFF *, uint16_t, TIFFDataType, tmsize_t,
+ void *);
+ 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 void _TIFFsetByteArray(void **, const void *, uint32_t);
+ extern void _TIFFsetByteArrayExt(TIFF *, void **, const void *, uint32_t);
+ extern void _TIFFsetShortArray(uint16_t **, const uint16_t *, uint32_t);
+ extern void _TIFFsetShortArrayExt(TIFF *, uint16_t **, const uint16_t *,
+ uint32_t);
+ extern void _TIFFsetLongArray(uint32_t **, const uint32_t *, uint32_t);
+ extern void _TIFFsetLongArrayExt(TIFF *, uint32_t **, const uint32_t *,
+ uint32_t);
+ extern void _TIFFsetFloatArray(float **, const float *, uint32_t);
+ extern void _TIFFsetFloatArrayExt(TIFF *, float **, const float *,
+ uint32_t);
+ extern void _TIFFsetDoubleArray(double **, const double *, uint32_t);
+ extern void _TIFFsetDoubleArrayExt(TIFF *, double **, const double *,
+ uint32_t);
+
+ extern void _TIFFprintAscii(FILE *, const char *);
+ extern void _TIFFprintAsciiTag(FILE *, const char *, const char *);
+
+ extern TIFFErrorHandler _TIFFwarningHandler;
+ extern TIFFErrorHandler _TIFFerrorHandler;
+ extern TIFFErrorHandlerExt _TIFFwarningHandlerExt;
+ extern TIFFErrorHandlerExt _TIFFerrorHandlerExt;
+ void _TIFFErrorEarly(TIFFOpenOptions *opts, thandle_t clientdata,
+ const char *module, const char *fmt, ...)
+ TIFF_ATTRIBUTE((__format__(__printf__, 4, 5)));
+
+ extern uint32_t _TIFFMultiply32(TIFF *, uint32_t, uint32_t, const char *);
+ extern uint64_t _TIFFMultiply64(TIFF *, uint64_t, uint64_t, const char *);
+ extern tmsize_t _TIFFMultiplySSize(TIFF *, tmsize_t, tmsize_t,
+ const char *);
+ extern tmsize_t _TIFFCastUInt64ToSSize(TIFF *, uint64_t, const char *);
+ extern void *_TIFFCheckMalloc(TIFF *, tmsize_t, tmsize_t, const char *);
+ extern void *_TIFFCheckRealloc(TIFF *, void *, tmsize_t, tmsize_t,
+ const char *);
+
+ extern double _TIFFUInt64ToDouble(uint64_t);
+ extern float _TIFFUInt64ToFloat(uint64_t);
+
+ extern float _TIFFClampDoubleToFloat(double);
+ extern uint32_t _TIFFClampDoubleToUInt32(double);
+
+ extern void _TIFFCleanupIFDOffsetAndNumberMaps(TIFF *tif);
+
+ extern tmsize_t _TIFFReadEncodedStripAndAllocBuffer(TIFF *tif,
+ uint32_t strip,
+ void **buf,
+ tmsize_t bufsizetoalloc,
+ tmsize_t size_to_read);
+ extern tmsize_t _TIFFReadEncodedTileAndAllocBuffer(TIFF *tif, uint32_t tile,
+ void **buf,
+ tmsize_t bufsizetoalloc,
+ tmsize_t size_to_read);
+ extern tmsize_t _TIFFReadTileAndAllocBuffer(TIFF *tif, void **buf,
+ tmsize_t bufsizetoalloc,
+ uint32_t x, uint32_t y,
+ uint32_t z, uint16_t s);
+ extern int _TIFFSeekOK(TIFF *tif, toff_t off);
+
+ extern int TIFFInitDumpMode(TIFF *, int);
+#ifdef PACKBITS_SUPPORT
+ extern int TIFFInitPackBits(TIFF *, int);
+#endif
+#ifdef CCITT_SUPPORT
+ extern int TIFFInitCCITTRLE(TIFF *, int), TIFFInitCCITTRLEW(TIFF *, int);
+ extern int TIFFInitCCITTFax3(TIFF *, int), TIFFInitCCITTFax4(TIFF *, int);
+#endif
+#ifdef THUNDER_SUPPORT
+ extern int TIFFInitThunderScan(TIFF *, int);
+#endif
+#ifdef NEXT_SUPPORT
+ extern int TIFFInitNeXT(TIFF *, int);
+#endif
+#ifdef LZW_SUPPORT
+ extern int TIFFInitLZW(TIFF *, int);
+#endif
+#ifdef OJPEG_SUPPORT
+ extern int TIFFInitOJPEG(TIFF *, int);
+#endif
+#ifdef JPEG_SUPPORT
+ extern int TIFFInitJPEG(TIFF *, int);
+ extern int TIFFJPEGIsFullStripRequired(TIFF *);
+#endif
+#ifdef JBIG_SUPPORT
+ extern int TIFFInitJBIG(TIFF *, int);
+#endif
+#ifdef ZIP_SUPPORT
+ extern int TIFFInitZIP(TIFF *, int);
+#endif
+#ifdef PIXARLOG_SUPPORT
+ extern int TIFFInitPixarLog(TIFF *, int);
+#endif
+#ifdef LOGLUV_SUPPORT
+ extern int TIFFInitSGILog(TIFF *, int);
+#endif
+#ifdef LERC_SUPPORT
+ extern int TIFFInitLERC(TIFF *tif, int);
+#endif
+#ifdef LZMA_SUPPORT
+ extern int TIFFInitLZMA(TIFF *, int);
+#endif
+#ifdef ZSTD_SUPPORT
+ extern int TIFFInitZSTD(TIFF *, int);
+#endif
+#ifdef WEBP_SUPPORT
+ extern int TIFFInitWebP(TIFF *, int);
+#endif
+ extern const TIFFCodec _TIFFBuiltinCODECS[];
+ extern void TIFFCIELab16ToXYZ(TIFFCIELabToRGB *, uint32_t l, int32_t a,
+ int32_t b, float *, float *, float *);
+
+ extern void *_TIFFmallocExt(TIFF *tif, tmsize_t s);
+ extern void *_TIFFcallocExt(TIFF *tif, tmsize_t nmemb, tmsize_t siz);
+ extern void *_TIFFreallocExt(TIFF *tif, void *p, tmsize_t s);
+ extern void _TIFFfreeExt(TIFF *tif, void *p);
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* _TIFFIOP_ */
diff --git a/contrib/libs/libtiff/tiffvers.h b/contrib/libs/libtiff/tiffvers.h
new file mode 100644
index 0000000000..ed847760c2
--- /dev/null
+++ b/contrib/libs/libtiff/tiffvers.h
@@ -0,0 +1,30 @@
+/* clang-format off */
+
+/* clang-format disabled because FindTIFF.cmake is very sensitive to the
+ * formatting of below line being a single line.
+ */
+#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.5.1\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
+ * version or versions of the library. Runtime
+ * version checking should be done based on the
+ * string returned by TIFFGetVersion.
+ */
+#define TIFFLIB_VERSION 20230609
+
+/* The following defines have been added in 4.5.0 */
+#define TIFFLIB_MAJOR_VERSION 4
+#define TIFFLIB_MINOR_VERSION 5
+#define TIFFLIB_MICRO_VERSION 1
+
+/* Macro added in 4.5.0. Returns TRUE if the current libtiff version is
+ * greater or equal to major.minor.micro
+ */
+#define TIFFLIB_AT_LEAST(major, minor, micro) \
+ (TIFFLIB_MAJOR_VERSION > (major) || \
+ (TIFFLIB_MAJOR_VERSION == (major) && TIFFLIB_MINOR_VERSION > (minor)) || \
+ (TIFFLIB_MAJOR_VERSION == (major) && TIFFLIB_MINOR_VERSION == (minor) && \
+ TIFFLIB_MICRO_VERSION >= (micro)))
+
+/* clang-format on */
diff --git a/contrib/libs/libtiff/uvcode.h b/contrib/libs/libtiff/uvcode.h
new file mode 100644
index 0000000000..fc87729244
--- /dev/null
+++ b/contrib/libs/libtiff/uvcode.h
@@ -0,0 +1,93 @@
+/* Version 1.0 generated April 7, 1997 by Greg Ward Larson, SGI */
+#define UV_SQSIZ (float)0.003500
+#define UV_NDIVS 16289
+#define UV_VSTART (float)0.016940
+#define UV_NVS 163
+static const struct
+{
+ float ustart;
+ short nus, ncum;
+} uv_row[UV_NVS] = {
+ {(float)0.247663, 4, 0}, {(float)0.243779, 6, 4},
+ {(float)0.241684, 7, 10}, {(float)0.237874, 9, 17},
+ {(float)0.235906, 10, 26}, {(float)0.232153, 12, 36},
+ {(float)0.228352, 14, 48}, {(float)0.226259, 15, 62},
+ {(float)0.222371, 17, 77}, {(float)0.220410, 18, 94},
+ {(float)0.214710, 21, 112}, {(float)0.212714, 22, 133},
+ {(float)0.210721, 23, 155}, {(float)0.204976, 26, 178},
+ {(float)0.202986, 27, 204}, {(float)0.199245, 29, 231},
+ {(float)0.195525, 31, 260}, {(float)0.193560, 32, 291},
+ {(float)0.189878, 34, 323}, {(float)0.186216, 36, 357},
+ {(float)0.186216, 36, 393}, {(float)0.182592, 38, 429},
+ {(float)0.179003, 40, 467}, {(float)0.175466, 42, 507},
+ {(float)0.172001, 44, 549}, {(float)0.172001, 44, 593},
+ {(float)0.168612, 46, 637}, {(float)0.168612, 46, 683},
+ {(float)0.163575, 49, 729}, {(float)0.158642, 52, 778},
+ {(float)0.158642, 52, 830}, {(float)0.158642, 52, 882},
+ {(float)0.153815, 55, 934}, {(float)0.153815, 55, 989},
+ {(float)0.149097, 58, 1044}, {(float)0.149097, 58, 1102},
+ {(float)0.142746, 62, 1160}, {(float)0.142746, 62, 1222},
+ {(float)0.142746, 62, 1284}, {(float)0.138270, 65, 1346},
+ {(float)0.138270, 65, 1411}, {(float)0.138270, 65, 1476},
+ {(float)0.132166, 69, 1541}, {(float)0.132166, 69, 1610},
+ {(float)0.126204, 73, 1679}, {(float)0.126204, 73, 1752},
+ {(float)0.126204, 73, 1825}, {(float)0.120381, 77, 1898},
+ {(float)0.120381, 77, 1975}, {(float)0.120381, 77, 2052},
+ {(float)0.120381, 77, 2129}, {(float)0.112962, 82, 2206},
+ {(float)0.112962, 82, 2288}, {(float)0.112962, 82, 2370},
+ {(float)0.107450, 86, 2452}, {(float)0.107450, 86, 2538},
+ {(float)0.107450, 86, 2624}, {(float)0.107450, 86, 2710},
+ {(float)0.100343, 91, 2796}, {(float)0.100343, 91, 2887},
+ {(float)0.100343, 91, 2978}, {(float)0.095126, 95, 3069},
+ {(float)0.095126, 95, 3164}, {(float)0.095126, 95, 3259},
+ {(float)0.095126, 95, 3354}, {(float)0.088276, 100, 3449},
+ {(float)0.088276, 100, 3549}, {(float)0.088276, 100, 3649},
+ {(float)0.088276, 100, 3749}, {(float)0.081523, 105, 3849},
+ {(float)0.081523, 105, 3954}, {(float)0.081523, 105, 4059},
+ {(float)0.081523, 105, 4164}, {(float)0.074861, 110, 4269},
+ {(float)0.074861, 110, 4379}, {(float)0.074861, 110, 4489},
+ {(float)0.074861, 110, 4599}, {(float)0.068290, 115, 4709},
+ {(float)0.068290, 115, 4824}, {(float)0.068290, 115, 4939},
+ {(float)0.068290, 115, 5054}, {(float)0.063573, 119, 5169},
+ {(float)0.063573, 119, 5288}, {(float)0.063573, 119, 5407},
+ {(float)0.063573, 119, 5526}, {(float)0.057219, 124, 5645},
+ {(float)0.057219, 124, 5769}, {(float)0.057219, 124, 5893},
+ {(float)0.057219, 124, 6017}, {(float)0.050985, 129, 6141},
+ {(float)0.050985, 129, 6270}, {(float)0.050985, 129, 6399},
+ {(float)0.050985, 129, 6528}, {(float)0.050985, 129, 6657},
+ {(float)0.044859, 134, 6786}, {(float)0.044859, 134, 6920},
+ {(float)0.044859, 134, 7054}, {(float)0.044859, 134, 7188},
+ {(float)0.040571, 138, 7322}, {(float)0.040571, 138, 7460},
+ {(float)0.040571, 138, 7598}, {(float)0.040571, 138, 7736},
+ {(float)0.036339, 142, 7874}, {(float)0.036339, 142, 8016},
+ {(float)0.036339, 142, 8158}, {(float)0.036339, 142, 8300},
+ {(float)0.032139, 146, 8442}, {(float)0.032139, 146, 8588},
+ {(float)0.032139, 146, 8734}, {(float)0.032139, 146, 8880},
+ {(float)0.027947, 150, 9026}, {(float)0.027947, 150, 9176},
+ {(float)0.027947, 150, 9326}, {(float)0.023739, 154, 9476},
+ {(float)0.023739, 154, 9630}, {(float)0.023739, 154, 9784},
+ {(float)0.023739, 154, 9938}, {(float)0.019504, 158, 10092},
+ {(float)0.019504, 158, 10250}, {(float)0.019504, 158, 10408},
+ {(float)0.016976, 161, 10566}, {(float)0.016976, 161, 10727},
+ {(float)0.016976, 161, 10888}, {(float)0.016976, 161, 11049},
+ {(float)0.012639, 165, 11210}, {(float)0.012639, 165, 11375},
+ {(float)0.012639, 165, 11540}, {(float)0.009991, 168, 11705},
+ {(float)0.009991, 168, 11873}, {(float)0.009991, 168, 12041},
+ {(float)0.009016, 170, 12209}, {(float)0.009016, 170, 12379},
+ {(float)0.009016, 170, 12549}, {(float)0.006217, 173, 12719},
+ {(float)0.006217, 173, 12892}, {(float)0.005097, 175, 13065},
+ {(float)0.005097, 175, 13240}, {(float)0.005097, 175, 13415},
+ {(float)0.003909, 177, 13590}, {(float)0.003909, 177, 13767},
+ {(float)0.002340, 177, 13944}, {(float)0.002389, 170, 14121},
+ {(float)0.001068, 164, 14291}, {(float)0.001653, 157, 14455},
+ {(float)0.000717, 150, 14612}, {(float)0.001614, 143, 14762},
+ {(float)0.000270, 136, 14905}, {(float)0.000484, 129, 15041},
+ {(float)0.001103, 123, 15170}, {(float)0.001242, 115, 15293},
+ {(float)0.001188, 109, 15408}, {(float)0.001011, 103, 15517},
+ {(float)0.000709, 97, 15620}, {(float)0.000301, 89, 15717},
+ {(float)0.002416, 82, 15806}, {(float)0.003251, 76, 15888},
+ {(float)0.003246, 69, 15964}, {(float)0.004141, 62, 16033},
+ {(float)0.005963, 55, 16095}, {(float)0.008839, 47, 16150},
+ {(float)0.010490, 40, 16197}, {(float)0.016994, 31, 16237},
+ {(float)0.023659, 21, 16268},
+};
diff --git a/contrib/libs/libtiff/ya.make b/contrib/libs/libtiff/ya.make
new file mode 100644
index 0000000000..32e01ab8bd
--- /dev/null
+++ b/contrib/libs/libtiff/ya.make
@@ -0,0 +1,93 @@
+# Generated by devtools/yamaker from nixpkgs 22.11.
+
+LIBRARY()
+
+LICENSE(
+ BSD-3-Clause AND
+ BSLA AND
+ MIT AND
+ libtiff
+)
+
+LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
+
+VERSION(4.5.1)
+
+ORIGINAL_SOURCE(https://gitlab.com/api/v4/projects/libtiff%2Flibtiff/repository/archive.tar.gz?sha=v4.5.1)
+
+PEERDIR(
+ contrib/libs/libjpeg-turbo
+ contrib/libs/libwebp
+ contrib/libs/lzma
+ contrib/libs/zlib
+ contrib/libs/zstd
+)
+
+ADDINCL(
+ GLOBAL contrib/libs/libtiff
+ contrib/libs/libjpeg-turbo
+ contrib/libs/libwebp
+ contrib/libs/zstd/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_UTIL()
+
+SRCS(
+ tif_aux.c
+ tif_close.c
+ tif_codec.c
+ tif_color.c
+ tif_compress.c
+ tif_dir.c
+ tif_dirinfo.c
+ tif_dirread.c
+ tif_dirwrite.c
+ tif_dumpmode.c
+ tif_error.c
+ tif_extension.c
+ tif_fax3.c
+ tif_fax3sm.c
+ tif_flush.c
+ tif_getimage.c
+ tif_hash_set.c
+ tif_jbig.c
+ tif_jpeg.c
+ tif_jpeg_12.c
+ tif_lerc.c
+ tif_luv.c
+ tif_lzma.c
+ tif_lzw.c
+ tif_next.c
+ tif_ojpeg.c
+ tif_open.c
+ tif_packbits.c
+ tif_pixarlog.c
+ tif_predict.c
+ tif_print.c
+ tif_read.c
+ tif_stream.cxx
+ tif_strip.c
+ tif_swab.c
+ tif_thunder.c
+ tif_tile.c
+ tif_version.c
+ tif_warning.c
+ tif_webp.c
+ tif_write.c
+ tif_zip.c
+ tif_zstd.c
+)
+
+IF (OS_WINDOWS)
+ SRCS(
+ tif_win32.c
+ )
+ELSE()
+ SRCS(
+ tif_unix.c
+ )
+ENDIF()
+
+END()