From 5b526645b61e09e5076a1cca3f4b689227f3ea4b Mon Sep 17 00:00:00 2001 From: Xingchen Date: Thu, 3 Sep 2026 19:29:33 +0800 Subject: [PATCH] Merge pull request #29838 from Xingchen1224:libtiff-4.7.2-upgrade 3rdparty/libtiff: Upgrade libtiff to 4.7.2 - #29838 [Feature Request] Upgrade libtiff to 4.7.2 (https://libtiff.gitlab.io/libtiff/releases/v4.7.2.html) ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [ ] There is a reference to the original bug report and related work - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake --- 3rdparty/libtiff/CMakeLists.txt | 2 +- 3rdparty/libtiff/ChangeLog | 2336 +++++++++++++++++++++++++++++++ 3rdparty/libtiff/RELEASE-DATE | 2 +- 3rdparty/libtiff/tif_aux.c | 127 +- 3rdparty/libtiff/tif_close.c | 6 +- 3rdparty/libtiff/tif_color.c | 81 +- 3rdparty/libtiff/tif_compress.c | 48 +- 3rdparty/libtiff/tif_dir.c | 145 +- 3rdparty/libtiff/tif_dir.h | 16 +- 3rdparty/libtiff/tif_dirinfo.c | 154 +- 3rdparty/libtiff/tif_dirread.c | 323 +++-- 3rdparty/libtiff/tif_dirwrite.c | 364 +++-- 3rdparty/libtiff/tif_dumpmode.c | 21 +- 3rdparty/libtiff/tif_fax3.c | 253 ++-- 3rdparty/libtiff/tif_fax3.h | 138 +- 3rdparty/libtiff/tif_getimage.c | 432 +++--- 3rdparty/libtiff/tif_hash_set.c | 43 +- 3rdparty/libtiff/tif_jbig.c | 11 +- 3rdparty/libtiff/tif_jpeg.c | 392 +++--- 3rdparty/libtiff/tif_lerc.c | 148 +- 3rdparty/libtiff/tif_luv.c | 165 +-- 3rdparty/libtiff/tif_lzma.c | 65 +- 3rdparty/libtiff/tif_lzw.c | 82 +- 3rdparty/libtiff/tif_next.c | 15 +- 3rdparty/libtiff/tif_ojpeg.c | 302 ++-- 3rdparty/libtiff/tif_open.c | 35 +- 3rdparty/libtiff/tif_packbits.c | 21 +- 3rdparty/libtiff/tif_pixarlog.c | 237 +++- 3rdparty/libtiff/tif_predict.c | 16 +- 3rdparty/libtiff/tif_print.c | 92 +- 3rdparty/libtiff/tif_read.c | 370 +++-- 3rdparty/libtiff/tif_strip.c | 56 +- 3rdparty/libtiff/tif_swab.c | 40 +- 3rdparty/libtiff/tif_thunder.c | 22 +- 3rdparty/libtiff/tif_tile.c | 95 +- 3rdparty/libtiff/tif_unix.c | 19 +- 3rdparty/libtiff/tif_webp.c | 57 +- 3rdparty/libtiff/tif_win32.c | 15 +- 3rdparty/libtiff/tif_write.c | 181 ++- 3rdparty/libtiff/tif_zip.c | 38 +- 3rdparty/libtiff/tif_zstd.c | 6 +- 3rdparty/libtiff/tiffio.h | 19 +- 3rdparty/libtiff/tiffiop.h | 62 +- 43 files changed, 5352 insertions(+), 1700 deletions(-) diff --git a/3rdparty/libtiff/CMakeLists.txt b/3rdparty/libtiff/CMakeLists.txt index 95936f74eb..967ac608b9 100644 --- a/3rdparty/libtiff/CMakeLists.txt +++ b/3rdparty/libtiff/CMakeLists.txt @@ -359,7 +359,7 @@ endif() set(LIBTIFF_MAJOR_VERSION "4") set(LIBTIFF_MINOR_VERSION "7") -set(LIBTIFF_MICRO_VERSION "1") +set(LIBTIFF_MICRO_VERSION "2") set(LIBTIFF_VERSION "${LIBTIFF_MAJOR_VERSION}.${LIBTIFF_MINOR_VERSION}.${LIBTIFF_MICRO_VERSION}") file(READ "RELEASE-DATE" LIBTIFF_RELEASE_DATE content) diff --git a/3rdparty/libtiff/ChangeLog b/3rdparty/libtiff/ChangeLog index 9079ce34c7..2e59290ae3 100644 --- a/3rdparty/libtiff/ChangeLog +++ b/3rdparty/libtiff/ChangeLog @@ -1,3 +1,2339 @@ +2026-06-27 Even Rouault + + libtiff 4.7.2 release + +2026-06-27 Even Rouault + + Merge branch 'revert_mr_910' into 'master' + Revert "_TIFFSetDefaultCompressionState(): reset postdecode callback" + + Closes #860 + + See merge request libtiff/libtiff!915 + +2026-06-27 Even Rouault + + Merge branch 'mr_810_revert' into 'master' + Revert "tif_jbig.c don't discard validly decoded data if errors occur" + + See merge request libtiff/libtiff!914 + +2026-06-27 Even Rouault + + Merge branch 'rst_formatting_fix' into 'master' + v4.7.2.rst: formatting fix + + See merge request libtiff/libtiff!913 + +2026-06-27 Even Rouault + + Revert "_TIFFSetDefaultCompressionState(): reset postdecode callback" + This reverts commit b7a73279cc83e39a2d3425d69185281009f7554a. + + Fixes #860, but re-opens #795 + +2026-06-27 Even Rouault + + Revert "tif_jbig.c don't discard validly decoded data if errors occur" + This reverts commit fd4e85614c479b9cac7b4d961648cac6f15ad81f. + + This causes a null-ptr deref in jbigkit on some corrupted images. See https://gitlab.com/libtiff/libtiff/-/merge_requests/810#note_3500232812 + +2026-06-27 Even Rouault + + v4.7.2.rst: formatting fix. + +2026-06-25 Even Rouault + + Merge branch 'fix_859' into 'master' + Revert "OJPEG: fix nullptr deref when changing compression method from OJPEG to something else" + + Closes #795 + + See merge request libtiff/libtiff!910 + +2026-06-25 Even Rouault + + Merge branch 'tif_jbig-benign_errors' into 'master' + tif_jbig.c don't discard validly decoded data if errors occur + + See merge request libtiff/libtiff!810 + +2026-06-25 Lee Howard + + tif_jbig.c don't discard validly decoded data if errors occur. + +2026-06-25 Even Rouault + + _TIFFSetDefaultCompressionState(): reset postdecode callback. + Fixes #795 + + Revert "OJPEG: fix nullptr deref when changing compression method from OJPEG to something else" + This reverts commit 04607e3ce091ac0579317f185ab2cc378c3f6d39. + +2026-06-19 Even Rouault + + Merge branch 'add_missing_export_symbols' into 'master' + libtiff.def/libtiff.map: add semi-public/private symbols added recently + + Closes #857 + + See merge request libtiff/libtiff!902 + +2026-06-19 Even Rouault + + tiffdump.c: fix build error on Windows. + + libtiff/tiffiop.h: fix ftell() macro in HAVE_FSEEKO case. + + libtiff.def/libtiff.map: add semi-public/private symbols added recently. + +2026-06-18 Even Rouault + + Merge branch 'issue-846-integer_overflow' into 'master' + Harden integer size and offset calculations in libtiff, tools, and contrib + + See merge request libtiff/libtiff!897 + +2026-06-18 Even Rouault + + Merge branch 'issue-850-Luv32fromLuv48' into 'master' + Fix signed left-shift UB in LogLuv RANDITHER encoding (#850) + + See merge request libtiff/libtiff!898 + +2026-06-18 Even Rouault + + Merge branch 'issue-854-TIFFReadAndRealloc' into 'master' + Handle negative TIFFReadFile results before state updates (#854) + + See merge request libtiff/libtiff!901 + +2026-06-16 waugustus + + Handle negative TIFFReadFile results before state updates (#854) + + Harden integer size and offset calculations in libtiff, tools, and contrib + +2026-06-12 waugustus + + Fix signed left-shift UB in LogLuv RANDITHER encoding (#850) + +2026-06-10 Even Rouault + + Merge branch 'patch-1' into 'master' + oss-fuzz: fix broken build + + See merge request libtiff/libtiff!896 + +2026-06-10 david korczynski + + oss-fuzz: fix broken build. + +2026-06-08 Even Rouault + + Merge branch 'DumpModeDecode_signedness_warning' into 'master' + DumpModeSeek(): fix -Wsign-compare on 32 bit platforms + + See merge request libtiff/libtiff!894 + +2026-06-08 Even Rouault + + DumpModeSeek(): fix -Wsign-compare on 32 bit platforms. + +2026-06-08 Even Rouault + + Merge branch 'formatting_fixes' into 'master' + Formatting fixes (apply pre-commit run --all) + + See merge request libtiff/libtiff!893 + +2026-06-08 Even Rouault + + Formatting fixes (apply pre-commit run --all) + +2026-06-08 Even Rouault + + Merge branch 'fix/ojpeg-overflow-and-misc-fixes' into 'master' + Fix integer overflows, copy-paste bug, and loop underflow + + See merge request libtiff/libtiff!891 + +2026-06-08 Even Rouault + + Merge branch 'jpegdecoderaw-uninit-heap' into 'master' + JPEGDecodeRaw: initialize output buffer to avoid returning uninitialized memory + + See merge request libtiff/libtiff!892 + +2026-06-06 evilgensec + + JPEGDecodeRaw: initialize output buffer to avoid returning uninitialized memory + JPEGDecodeRaw() (the YCbCr-subsampled "raw" decode path) writes at most + sp->cinfo.d.image_height rows, and within each scanline only the + clumps_per_line clumps derived from the JPEG codestream width. When a + strip/tile is declared larger than the embedded JPEG SOF dimensions -- + which JPEGPreDecode() only warns about rather than rejecting -- the + unwritten tail of the caller's buffer is left untouched and returned as + decoded data. + + Callers such as TIFFReadEncodedStrip/TIFFReadEncodedTile (and the tools + built on them: tiffinfo -d, tiff2rgba, plus downstream users like GDAL + and tiff2pdf) hand in an uninitialized malloc'd buffer, so the contents + of previously freed heap are disclosed to the consumer. The amount of + leaked data scales with the declared strip/tile height. + + JPEGDecode() already zeroes its output buffer for this case, but + JPEGDecodeRaw() does not. A conditional memset mirroring JPEGDecode()'s + dimension test is not sufficient here: for subsampled data the per-clump + write stride can leave part of the caller buffer untouched even for + spec-compliant images, so the buffer is zeroed unconditionally before the + decode loop. + +2026-05-31 Anthony Hurtado + + tiff2pdf.c: add overflow checks to RGBA/RGBAA sample count computation. + The YCBCR-to-RGB conversion path uses TIFFSafeMultiply for the + tiff_width * tiff_length computation, but the RGBA-to-RGB and + RGBAA-to-RGB paths perform raw uint32_t multiplication. The same + inconsistency exists in the tile path with tiles_tilewidth * + tiles_tilelength. + + For crafted TIFF files with large dimensions, the unchecked + multiplication overflows and passes a wrong sample count to + t2p_sample_rgba_to_rgb / t2p_sample_rgbaa_to_rgb, causing + out-of-bounds buffer access in those conversion functions. + + Add TIFFSafeMultiply overflow checks consistent with the YCBCR path, + covering both the image path (tiff_width * tiff_length) and the tile + path (tiles_tilewidth * tiles_tilelength). + +2026-05-31 Anthony Hurtado + + tiffcrop.c: fix integer overflow in extractImageSection. + The computations img_width * spp * bps and sect_width * spp * bps are + performed in uint32_t (img_width/sect_width are uint32_t, spp/bps are + uint16_t promoted to int, but the product is truncated back to uint32_t + when assigned). For images with large dimensions and high bit depth, + these products can overflow, producing incorrect img_rowsize and + full_bytes values that lead to out-of-bounds buffer access. + + Use uint64_t intermediates and check against UINT32_MAX before use. + +2026-05-31 Anthony Hurtado + + tif_write.c: fix OOB read and underflow in TIFFAppendToStrip copy loop. + When TIFFAppendToStrip needs to relocate strip data to the end of the + file, it copies in chunks of tempSize (up to 1 MB). On the final + iteration, toCopy may be less than tempSize, but the loop unconditionally + reads and writes tempSize bytes. This causes: + + 1. OOB file read past the end of the original strip data + 2. uint64_t underflow when toCopy -= tempSize wraps, causing the loop + to run indefinitely + + Introduce a chunkSize variable that is min(toCopy, tempSize) to + correctly handle the final partial iteration. + +2026-05-31 Anthony Hurtado + + tif_dirread.c: fix copy-paste bug in ChopUpSingleUncompressedStrip. + Line 8024 assigns offset = TIFFGetStrileByteCount(tif, 0) but should + use TIFFGetStrileOffset(tif, 0). The variable is used at lines + 8061-8063 to perform a file-size sanity check that prevents excessive + memory allocation when chopping a single-strip TIFF into multiple + strips. + + With the byte count instead of the offset, the sanity check compares + the wrong value against the file size, allowing a crafted uncompressed + single-strip TIFF with a small byte count but large nstrips to bypass + the guard and trigger excessive allocation from TIFFReadDirectory(). + +2026-05-31 Anthony Hurtado + + tif_ojpeg.c: fix integer overflow in subsampling buffer allocation. + The computation of subsampling_convert_ybuflen (ylinelen * ylines), + subsampling_convert_cbuflen (clinelen * clines), and their sum + subsampling_convert_ycbcrbuflen is performed in uint32_t and can + silently overflow for large strile_width values. The existing overflow + check at line 1362 only guards the ylinelen addition, not the + subsequent multiplications. + + When the product wraps to a small value, _TIFFcallocExt allocates an + undersized buffer. Row pointers are then computed using the + non-overflowed stride, pointing past the allocation. Libjpeg writes + decompressed scanline data through these out-of-bounds pointers, + causing heap buffer overflow. + + Use 64-bit intermediates for the multiplications and check against + UINT32_MAX before truncating back to uint32_t. Return an error + instead of proceeding with a corrupted allocation size. + +2026-05-29 Even Rouault + + Merge branch 'issue-832-raw2tiff' into 'master' + Fix integer wraparound checks in raw2tiff/tiffcrop and add missing zero-divisor guards in tiff2rgba (#832). + + See merge request libtiff/libtiff!885 + +2026-05-29 Even Rouault + + Merge branch 'issue-836-tiffcrop' into 'master' + tiffcrop: Fix tiffcrop composite crop buffer sizing (#836) + + See merge request libtiff/libtiff!884 + +2026-05-29 Even Rouault + + Merge branch 'fix/compute-tile-strip-overflow' into 'master' + TIFFComputeTile/TIFFComputeStrip: use overflow-checked multiplication + + See merge request libtiff/libtiff!890 + +2026-05-29 Even Rouault + + Merge branch 'fix/dumpmode-seek-oob' into 'master' + DumpModeSeek: add bounds check to prevent OOB pointer advance + + See merge request libtiff/libtiff!888 + +2026-05-29 Anthony Hurtado + + TIFFComputeTile/TIFFComputeStrip: use overflow-checked multiplication. + TIFFComputeTile() computes xpt * ypt * zpt using raw uint32_t + multiplication that can silently overflow for images with small tile + dimensions and large image dimensions. The wrapped result is used as a + tile index into the strip offset/bytecount arrays, causing out-of-bounds + array access. + + TIFFComputeStrip() has the same issue with (uint32_t)sample * + td_stripsperimage. + + Replace raw multiplication with _TIFFMultiply32() in both functions, + consistent with their TIFFNumberOf* counterparts in the same files. + _TIFFMultiply32() reports an error and returns 0 on overflow instead of + silently wrapping. Added early return when overflow is detected (result + is 0 but operands are non-zero) to prevent using a bogus index. + +2026-05-29 Anthony Hurtado + + DumpModeSeek: add bounds check to prevent OOB pointer advance. + DumpModeSeek() advances tif_rawcp by nrows * td_scanlinesize without + any bounds check against tif_rawcc (remaining buffer bytes). A crafted + TIFF with COMPRESSION_NONE can trigger an arbitrary forward seek past + the raw data buffer, causing subsequent DumpModeDecode() calls to read + from out-of-bounds heap memory. + + Added pre-multiplication overflow check using TIFF_TMSIZE_T_MAX + division (avoiding undefined behavior from signed overflow detection), + then bounds check against tif_rawcc before advancing the pointer. + + Note the contrast with DumpModeDecode() in the same file, which + correctly checks tif_rawcc < cc before any access. + +2026-05-29 Even Rouault + + Merge branch 'fix/growstrips-uaf' into 'master' + TIFFGrowStrips: fix use-after-free on partial realloc failure + + See merge request libtiff/libtiff!889 + +2026-05-29 Anthony Hurtado + + TIFFGrowStrips: fix use-after-free on partial realloc failure. + TIFFGrowStrips() performs two realloc calls for td_stripoffset_p and + td_stripbytecount_p. If the first realloc succeeds (potentially moving + the allocation) but the second fails, the error path frees the new + pointer while td->td_stripoffset_p still points to the old (now-freed) + memory. When TIFFFreeDirectory() later frees td_stripoffset_p, it + triggers a double-free of the dangling pointer. + + Fix by updating each struct member immediately after its successful + realloc, before attempting the second realloc. If either realloc fails, + the struct members point to valid memory (either the successfully + reallocated block or the original unchanged block), preventing any + dangling pointer. + +2026-05-25 waugustus + + Address review feedback for overflow guard fixes. + +2026-05-14 Even Rouault + + Merge branch 'issue-844-_TIFFReserveLargeEnoughWriteBuffer' into 'master' + Fix NULL dereference in _TIFFReserveLargeEnoughWriteBuffer() by validating the strip bytecount array before accessing it (#844) + + See merge request libtiff/libtiff!886 + +2026-05-14 waugustus + + Fix NULL dereference in _TIFFReserveLargeEnoughWriteBuffer() by validating the strip bytecount array before accessing it. + + Fix integer wraparound checks in raw2tiff/tiffcrop and add missing zero-divisor guards in tiff2rgba (#832). + +2026-05-11 Even Rouault + + Merge branch 'fix_834_835_836' into 'master' + tiffcrop: fix uint32 overflows in writeImageSections and getCropOffsets + + Closes #834, #835, and #836 + + See merge request libtiff/libtiff!879 + +2026-05-09 waugustus + + tiffcrop: fix byte carry for left/right composite bit offsets. + + tiffcrop: recompute composite crop dimensions before allocation. + +2026-05-09 Even Rouault + + Merge branch 'issue-828-horizontalAccumulate8abgr' into 'master' + pixarlog: complete ABGR bounds check for multi-row strip decoding + + See merge request libtiff/libtiff!883 + +2026-05-09 Even Rouault + + Merge branch 'fix_830' into 'master' + TIFFRGBAImage: avoid int overflows in put functions + + Closes #830 + + See merge request libtiff/libtiff!881 + +2026-05-07 Even Rouault + + Merge branch 'fix_831' into 'master' + TIFFFillStrip/Tile(): avoid excessive memory allocation + + Closes #831 + + See merge request libtiff/libtiff!880 + +2026-05-07 Even Rouault + + TIFFFillStrip/Tile(): avoid excessive memory allocation. + Closes #831 + +2026-05-07 Even Rouault + + Merge branch 'fix_823' into 'master' + Doc: TIFFFdOpen(): clarify role of filename parameter + + Closes #823 + + See merge request libtiff/libtiff!882 + +2026-05-07 Even Rouault + + Merge branch 'fix_788_Write_IFDLoop' into 'master' + TIFFLinkDirectory() checks for IFD loops (fixes 788) + + Closes #788 + + See merge request libtiff/libtiff!878 + +2026-05-07 Su Laus + + TIFFLinkDirectory() checks for IFD loops (fixes 788) + +2026-05-07 waugustus + + pixarlog: error out on invalid ABGR output buffer sizes. + + pixarlog: complete ABGR bounds check for multi-row strip decoding. + +2026-05-05 Niels Provos + + tiffcrop: simplify safeAccumUInt32 overflow check. + Use the canonical unsigned-overflow idiom (a > MAX - b) instead of a + uint64_t cast, per maintainer suggestion. + +2026-05-05 Even Rouault + + Doc: TIFFFdOpen(): clarify role of filename parameter. + Fixes #823 + + TIFFRGBAImage: avoid int overflows in put functions. + Fixes #830 + +2026-05-04 Even Rouault + + Merge branch 'TIFFGetMaxCompressionRatio' into 'master' + Add TIFFGetMaxCompressionRatio() and use it in _TIFFReadEncoded[Tile|Strip)AndAllocBuffer() + + Closes #781 + + See merge request libtiff/libtiff!872 + +2026-05-03 Niels Provos + + tiffcrop: fix uint32 overflows in writeImageSections and getCropOffsets. + Three uint32 wraps in tiffcrop allowed crafted TIFFs to bypass + loadImage()'s buffer-size guard: + + * writeImageSections:8301 computed sectsize via ceil((n+7)/8.0) (double), + which overcounts bytes-per-row by 1 vs. loadImage:7209's integer + (n+7)/8, then multiplied in uint32. Now uses uint64_t with the same + integer formula and rejects results exceeding UINT32_MAX-3. + + * getCropOffsets accumulates crop->combined_{width,length} in uint32 + across zones for all four EDGE_* branches; sums >= 2^32 wrap and + under-size the crop_buff allocation in processCropSelections. A + safeAccumUInt32() helper now guards each accumulation. + + Fixes #834, #835, #836. + +2026-04-29 Even Rouault + + Merge branch 'fix_826' into 'master' + JPEG decompressor: initialize output buffer when JPEG image is smaller than... + + Closes #826 + + See merge request libtiff/libtiff!877 + +2026-04-29 Even Rouault + + JPEG decompressor: initialize output buffer when JPEG image is smaller than strile dimension to avoid heap memory disclosure + Fixes #826 + +2026-04-28 Even Rouault + + Merge branch 'fix_ossfuzz_506737072' into 'master' + TIFFAdvanceDirectory(): avoid potential read heap-buffer-overflow in mmap code... + + See merge request libtiff/libtiff!876 + +2026-04-28 Even Rouault + + TIFFAdvanceDirectory(): avoid potential read heap-buffer-overflow in mmap code path on 32 bit builds + Fixes https://issues.oss-fuzz.com/issues/506737072 + + ``` + ==250==ERROR: AddressSanitizer: SEGV on unknown address 0x73402dbf (pc 0xf7cc6656 bp 0xff9cc408 sp 0xff9cbfb8 T0) + ==250==The signal is caused by a READ memory access. + 0 0xf7cc6656 in libc.so.6 + 1 0x5763d373 in __asan_memcpy /src/llvm-project/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:63:3 + 2 0x57f675ba in gdal__TIFFmemcpy gdal/frmts/gtiff/libtiff/tif_vsi.c:174:2 + 3 0x57f631a9 in gdal_TIFFAdvanceDirectory gdal/frmts/gtiff/libtiff/tif_dir.c:1878:13 + ``` + + with + ``` + $ tiffdump test.tif + test.tif: + Magic: 0x4949 Version: 0x2a + Directory 0: offset 8 (0x8) next 2147483647 (0x7fffffff) + [...] + ``` + +2026-04-25 Roger Leigh + + Merge branch 'cmake-macos-framework' into 'master' + Build: Support for iOS-derived builds + + See merge request libtiff/libtiff!780 + +2026-04-25 Roger Leigh + + cmake: Fix bundle identifiers to use reverse-DNS format. + PRODUCT_BUNDLE_IDENTIFIER and MACOSX_FRAMEWORK_IDENTIFIER must use + reverse-DNS dot notation (com.gitlab.libtiff.libtiff_tiff), not + URL-style slashes which are not valid in bundle ID strings. + +2026-04-25 Treata11 + + cmake: Incorporate improvements from treata11/cmake-macos-framework. + - .gitignore: add build* to ignore build directories + - CMakeLists.txt: add framework build status message in configure summary + - libtiff/CMakeLists.txt: refactor duplicate if(tiff-framework) blocks + into a set_framework_properties(target headers_var) macro, eliminating + repetition between the tiff and tiffxx targets + - tools/CMakeLists.txt: extract install target list into libtiff_tools + variable for clarity + +2026-04-25 Roger Leigh + + cmake: Fix and improve Apple framework build support. + - Fix FRAMEWORK_VERSION to use conventional letter "A" instead of the + full version string, which incorrectly named the Versions/ directory + - Remove FRAMEWORK/BUNDLE properties from fax2ps and other executables; + only shared libraries can be frameworks, and framework linking is + implicit for executables via target_link_libraries + - Remove BUNDLE DESTINATION from tools install rule; CLI tools are not + app bundles + - Add framework properties to tiffxx (C++ wrapper library), including + FRAMEWORK DESTINATION in its install rule + - Move OPENGL_SUPPORT=OFF for embedded Apple platforms into the root + CMakeLists.txt, gated on CMAKE_SYSTEM_NAME rather than tiff-framework, + so it is driven by platform identity and applies before subdirectories + are processed + - Default tiff-framework to ON for non-Darwin Apple platforms (iOS, + tvOS, watchOS, visionOS) where .dylib is not permitted by the App + Store; keep OFF on macOS where .dylib is the conventional format + - Short-circuit HAVE_LD_VERSION_SCRIPT=FALSE on Apple unconditionally, + since ld64 does not support --version-script, avoiding a noisy probe + +2026-04-25 Treata11 + + Build: Support for iOS-derived builds. + +2026-04-25 Roger Leigh + + Merge branch 'oss-fuzz' into 'master' + Add fuzzer for libtiff write logic + + See merge request libtiff/libtiff!875 + +2026-04-25 Roger Leigh + + Remove unused __TIFFSafeMultiply macro and MAX_SIZE constant. + +2026-04-25 Arthur Chan + + Fix formatting and build script. + + Fix formatting accordingly. + + Create new fuzzer and integrate to libtiff. + +2026-04-25 Roger Leigh + + Merge branch 'fix-bufoverflow' into 'master' + tiffcrop: avoid buffer overflow in combineSeparateTileSamplesBytes() + + See merge request libtiff/libtiff!848 + +2026-04-25 Roger Leigh + + Merge branch 'tiffsplit-kostasl' into 'master' + tiffsplit: use 7-digit numbered output names + + See merge request libtiff/libtiff!874 + +2026-04-25 Kostas Lagogiannis + + tiffsplit: use 7-digit numbered output names. + +2026-04-25 Roger Leigh + + Merge branch 'issue-824-horizontalAccumulate8abgr' into 'master' + pixarlog: fix heap-buffer-overflow in 8BITABGR decode with stride 3 (#824) + + See merge request libtiff/libtiff!873 + +2026-04-25 Roger Leigh + + Merge branch 'fix/thumbnail-integer-overflow' into 'master' + thumbnail: prevent integer overflow by capping row count at 256 + + See merge request libtiff/libtiff!852 + +2026-04-25 Roger Leigh + + Merge branch 'support_arm64_arm64ec' into 'master' + Enable support for arm64EC + + See merge request libtiff/libtiff!830 + +2026-04-25 Roger Leigh + + Merge branch 'cmake-turbojpeg' into 'master' + cmake: Use TurboJPEG CONFIG by default + + Closes #767 + + See merge request libtiff/libtiff!806 + +2026-04-25 Roger Leigh + + cmake: JPEG dual mode requires both functions. + + cmake: Update JPEG dual mode check to use correct library target. + + cmake: Update JPEG dual mode check to use check_symbol_exists. + * The existing approach failed with clang due to it not using declared symbols + + cmake: Enable 8-/12-bit modes with TurboJPEG CONFIG. + + cmake: Use TurboJPEG CONFIG by default. + +2026-04-24 waugustus + + pixarlog: add comment explaining 4-byte advance in ABGR decode. + +2026-04-23 waugustus + + pixarlog: fix heap-buffer-overflow in 8BITABGR decode with stride 3 (#824) + +2026-04-22 Even Rouault + + Add libtiff/README_for_libtiff_developpers.md and reference it in various GetMaxCompressionRatio() functions + +2026-04-22 Even Rouault + + Merge branch 'issue-816-tiffcrop' into 'master' + tiffcrop: size separated region buffers from actual dimensions (#816) + + See merge request libtiff/libtiff!871 + +2026-04-21 Even Rouault + + Add TIFFGetMaxCompressionRatio() and use it in _TIFFReadEncoded[Tile|Strip)AndAllocBuffer() + ```rst + + .. c:function:: uint64_t TIFFGetMaxCompressionRatio(TIFF *tif); + + Description + ----------- + + :c:func:`TIFFGetMaxCompressionRatio` returns the maximum compression ratio + for the current codec, which is typically achieved for a uncompressed buffer + with all bytes at zero. + + This function can be used to determine if the compressed size of a strip or tile + is realistic compared to the expected uncompressed size, to prevent some + denial-of-service scenarios. + + Depending on the codec, it may take into account the strip or tile size, + number of samples per pixel, etc. + + Some codecs don't implement that method, or only for a subset of configurations, + and may return 0 when the maximum compression ratio is unknown. + + Return values + ------------- + + 0 is returned if no maximum compression ratio is known. + 1 is returned when there is no compression. + Values strictly bigger than 1 are returned when a maximum compression ratio is + known. + ``` + + Fixes #781 + +2026-04-21 waugustus + + tiffcrop: size separated region buffers from actual dimensions. + +2026-04-21 Even Rouault + + Merge branch 'reformat' into 'master' + Update pre-commit clang-format to v22.1.3 and apply 'pre-commit run --all' + + See merge request libtiff/libtiff!870 + +2026-04-20 Even Rouault + + Update pre-commit clang-format to v22.1.3 and apply 'pre-commit run --all' + +2026-04-20 Even Rouault + + Merge branch 'warning_fixes_armhf_32bit' into 'master' + Fix warning fixes with arm-linux-gnueabihf-gcc-13 + + See merge request libtiff/libtiff!868 + +2026-04-20 Even Rouault + + Fix warning fixes with arm-linux-gnueabihf-gcc-13. + Fixes + ``` + /home/runner/work/gdal/gdal/frmts/gtiff/libtiff/tiffiop.h:296:68: error: comparison of integer expressions of different signedness: 'tmsize_t' {aka 'long int'} and 'long unsigned int' [-Werror=sign-compare] + 296 | #define ReadOK(tif, buf, size) (TIFFReadFile((tif), (buf), (size)) == (size)) + | ^~ + /home/runner/work/gdal/gdal/frmts/gtiff/libtiff/tif_dirread.c:6141:14: note: in expansion of macro 'ReadOK' + 6141 | if (!ReadOK(tif, origdir, (tmsize_t)dircount16 * dirsize)) + | ^~~~~~ + /home/runner/work/gdal/gdal/frmts/gtiff/libtiff/tif_dirread.c:6270:29: error: comparison of integer expressions of different signedness: 'tmsize_t' {aka 'long int'} and 'long unsigned int' [-Werror=sign-compare] + 6270 | if ((m < off) || (m < (tmsize_t)dircount16 * dirsize) || + | ^ + ``` + +2026-04-20 Roger Leigh + + Merge branch 'warning-additions5' into 'master' + Add extra warnings, with a focus upon the preprocessor + + See merge request libtiff/libtiff!805 + +2026-04-19 Roger Leigh + + tif_write: Make expression less ambiguous. + + tif_config: Don't check if macro defined when undefined. + +2026-04-18 Roger Leigh + + Run clang-format on all modified files. + Suggested-by: Timothy Lyanguzov + Co-Authored-By: Claude Opus 4.6 (1M context) + +2026-04-18 Roger Leigh + + Use lowercase float literal suffixes. + Replace all uppercase F float literal suffixes with the more conventional + lowercase f across all source files for consistency. + + Suggested-by: Timothy Lyanguzov + Co-Authored-By: Claude Opus 4.6 (1M context) + +2026-04-18 Roger Leigh + + Simplify cmake byte order version check. + The CMAKE_VERSION >= 3.20 guard is redundant since CMAKE_C_BYTE_ORDER + is only defined by CMake 3.20+. If it's defined, the version is already + sufficient. + + Suggested-by: Timothy Lyanguzov + Co-Authored-By: Claude Opus 4.6 (1M context) + +2026-04-18 Roger Leigh + + Add -Wtrampolines to extra-warnings. + + Add -Walloc-zero to extra-warnings. + + Add -Wstringop-overflow=4 to extra-warnings. + + Add -Warray-bounds=3 to extra-warnings. + + Add -Wvla to extra-warnings. + + Add -Wnested-externs to extra-warnings. + + Add -Wold-style-definition to extra-warnings. + + Add -Wundef to extra-warnings. + + cmake: Add extra broken-warnings. + * Will promote to extra-warnings after testing + + cmake: Unset /W3 before setting /W4. + + tools: Use HAVE_UNISTD_H consistently. + + cmake: Suppress warnings in Windows system headers. + + tif_jpeg: Use HAVE_DECL_OPTARG consistently. + + tif_jpeg: Use JPEG_LIB_MK1_OR_12BIT consistently. + + port: Correct HAVE_GETOPT and HAVE_UNISTD_H usage. + + cmake: Modernise endianness checks. + + Correct WORDS_BIGENDIAN to always be defined to 1 or 0. + + Add extra MSVC warnings. + +2026-04-18 Roger Leigh + + Merge branch 'warning-additions4' into 'master' + Add additional warnings, primarily floating precision conversions and integer arithmetic conversions + + See merge request libtiff/libtiff!804 + +2026-04-18 Roger Leigh + + Merge remote-tracking branch 'origin/master' into warning-additions4. + +2026-04-12 Even Rouault + + Merge branch 'fix-integer-overflows' into 'master' + fix: add integer overflow checks to allocation size calculations + + See merge request libtiff/libtiff!862 + +2026-04-12 mohammadmseet-hue + + fix: add integer overflow checks to allocation size calculations. + Several allocation sites compute buffer sizes using unchecked 32-bit + multiplication of attacker-controlled TIFF tag values. When the product + exceeds UINT32_MAX, the result wraps to a small value, causing undersized + allocations followed by heap buffer overflows. + + Changes across 2 files (5 overflow sites): + + - tif_dirwrite.c: 4 unchecked count*sizeof() replaced with + _TIFFCheckMalloc + - tif_print.c: 1 tv_size*value_count replaced with _TIFFCheckMalloc + + All 158 existing tests pass. + +2026-04-11 Even Rouault + + Merge branch 'fix_777_part1_division_by_zero_and_move_params_to_tif_dir' into 'master' + tif_read.c: Fixed division by zero in TIFFStartStrip() by correctly initialising the parameters and checking for zero (fixes #777 first part) + + See merge request libtiff/libtiff!863 + +2026-04-10 Su_Laus + + Some editorials due to suggestions. + +2026-04-09 Even Rouault + + Merge branch 'master' into 'master' + Check result of _TIFFCheckRealloc + + See merge request libtiff/libtiff!865 + +2026-04-08 Roger Leigh + + Widen pointer-offset arithmetic in tif_getimage.c. + Cast `line` to `size_t` before multiplying by `w` in the horizontal + flip loops, so the pointer offset computation happens at pointer + width rather than uint32_t. Prevents overflow for large images + where line * w exceeds UINT32_MAX. + +2026-04-08 Roger Leigh + + Move widening casts inside arithmetic scope (additional cases) + Extend the approach from 96ea0393 to additional cases: place widening + casts on operands rather than wrapping the arithmetic result, so the + computation happens at the wider type. This covers additions, + subtractions, and multiplications used for memory sizes, buffer + offsets, and function arguments. + + For cases where the moved cast creates a same-precedence ambiguity + (e.g. in % or / expressions), add grouping parentheses to preserve + the original semantics. + +2026-04-07 Aymeric Esparre + + Check result of _TIFFCheckRealloc to prevent memory leaks and segmentation fault when reallocation fails. + +2026-04-06 Su_Laus + + tif_read.c: Fixed division by zero in TIFFStartStrip() by correctly initialising the parameters and checking for zero (resolves the first issue from #777) + Move the tif-directory related parameters tif_scanlinesize, tif_tilesize, tif_row, tif_curstrip, tif_col, tif_curtile, tif_tilesize from the tif structure to the tif_dir structure. + Initialise these parameters not only in TIFFClientOpenExt(), but also in TIFFDefaultDirectory() using the new function _TIFFResetTifDirAndInitStrileCounters(). + The partial initialisation of these parameters is removed from TIFFReadDirectory(), TIFFCreateDirectory(), TIFFCreateCustomDirectory() and TIFFUnlinkDirectory(), where TIFFDefaultDirectory() and thus _TIFFResetTifDirAndInitStrileCounters() is called. + + In TIFFStartStrip(), check for td_stripsperimage == 0 to avoid division by zero. + + This initialisation resolves the first issue from #777. + +2026-04-05 Roger Leigh + + Move widening casts inside multiplication scope. + Place widening casts where the multiplication is performed rather + than wrapping the entire result. This ensures arithmetic happens + at the wider type, reducing the chance of overflow. + + For sizeof patterns, cast the non-sizeof operand to (size_t) + before multiplication: (tmsize_t)((size_t)count * sizeof(type)). + For integer arithmetic, cast the variable directly: + constant + (uint64_t)dircount * constant + constant. + +2026-04-05 Roger Leigh + + Use dircount64 directly to avoid unnecessary narrowing and widening. + Where dircount64 (uint64_t) is already validated and in scope, use it + directly in multiplication instead of narrowing to uint16_t and casting + back. Remove the now-unused dircount/dircount16 variables from the + affected blocks. + + Add TIFF_FLOAT_EQ/TIFF_DOUBLE_EQ macros and use throughout. + Define TIFF_FLOAT_EQ and TIFF_DOUBLE_EQ macros in tiffiop.h to + centralise the fabs/fabsf-based float equality pattern used to + suppress -Wfloat-equal warnings. Replace all inline occurrences + across library, tools, and test files with the new macros. + + Use lowercase float literal suffixes. + Replace all uppercase F float literal suffixes with the more conventional + lowercase f across all source files for consistency. + +2026-04-05 Roger Leigh + + Remove redundant (size_t) casts in tmsize_t allocation expressions. + When the count operand is already unsigned (uint16_t, uint32_t, + uint64_t), the intermediate (size_t) cast in expressions like + (tmsize_t)((size_t)count * sizeof(T)) is redundant — the + multiplication with sizeof (which returns size_t) already promotes + the unsigned count via the usual arithmetic conversions. + + Simplify to (tmsize_t)(count * sizeof(T)) for all 40 occurrences + where the count is unsigned. Retain the (size_t) cast for the 18 + occurrences where the count is signed (int, tmsize_t, int32_t). + +2026-04-05 Roger Leigh + + Simplify typecasts using unsigned constant suffixes and better types. + Use U-suffixed constants (1U, 255U, 12U, 20U) instead of explicit + (uint32_t) casts on expressions. Change CMYK local variables from + uint16_t/uint32_t to unsigned int to match the natural arithmetic + type. Remove redundant intermediate casts: inner (int16_t) before + shift in tif_luv.c, unnecessary (size_t) wrapping in tif_dirread.c, + and redundant (double) on already-double variables in tiff2ps.c. + + tif_color: Use 1.0F instead of 1 in Code2V ternary and remove redundant cast + Use a float literal for the fallback value so both branches of the + ternary have the same type, and drop the now-unnecessary outer (float) + cast. + + test: Fix -Wconversion warnings in test_transferfunction_write_read.c. + Add explicit (size_t) and (tmsize_t) casts in buffer size calculations + to prevent implicit integer conversion warnings when computing + allocation sizes and memcmp lengths. + + test: Fix -Wdouble-promotion and operator precedence warnings in test_write_read_tags.c + Add (double) casts on float arguments to printf and in float-to-double + arithmetic. Fix operator precedence in (short)(i + 1) * 7 which casts + before multiplying — should be (short)((i + 1) * 7). + + test: Fix -Wdouble-promotion warnings in rational_precision2double.c. + Add explicit (double) casts on float arguments passed to variadic + functions (printf, TIFFSetField) and in arithmetic expressions where + float is implicitly promoted to double. + + test: Use check_tag.h include in tifftest.h instead of inline declarations + Replace the inline function declarations with an include of check_tag.h + which provides the canonical declarations for CheckShortField, + CheckShortPairedField, and CheckLongField. + + test: Use tifftest.h include instead of extern declaration in long_tag.c + Replace the bare extern declaration of CheckLongField with an include + of tifftest.h, which provides all check function declarations via + check_tag.h. Fixes -Wmissing-prototypes style warning. + + Add -Wunused-macros to extra-warnings. + + Add -Wmisleading-indentation to extra-warnings. + + Add -Wunused-local-typedefs to extra-warnings. + + Add -Wmissing-include-dirs to extra-warnings. + + Add -Wbool-operation to extra-warnings. + + Add -Wunreachable-code to extra-warnings. + + Add -Wdangling-else to extra-warnings. + + Add -Wno-int-to-pointer-cast to extra-warnings. + + Add -Wlogical-not-parentheses to extra-warnings. + + Add -Wlogical-op to extra-warnings. + + Add -Wsizeof-pointer-memaccess to extra-warnings. + + Add -Wsizeof-pointer-div to extra-warnings. + + Add -Wsizeof-array-div to extra-warnings. + + Add -Wredundant-decls to extra-warnings. + + Add -Wmissing-declarations to extra-warnings. + + Add -Wunused-parameter to extra-warnings. + + Add -Wduplicated-cond to extra-warnings. + + Add -Wduplicated-branches to extra-warnings. + + Add -Wuninitialized to extra-warnings. + + Add -Wfloat-equal to extra-warnings. + + Add -Wfloat-conversion to extra-warnings. + + Add -Wdouble-promotion to extra-warnings. + + Add -Warith-conversion to extra-warnings. + + Add -Wsign-conversion to extra-warnings. + + Fix -Wconversion warnings with Clang. + Cast bitwise NOT results to avoid implicit integer conversion + warnings on unsigned char and uint16_t. + +2026-04-04 Even Rouault + + Merge branch 'tif_jpeg_warning_fix' into 'master' + tif_jpeg.c: fix MSVC compiler warning + + See merge request libtiff/libtiff!861 + +2026-04-04 Even Rouault + + tif_jpeg.c: fix MSVC compiler warning. + Fixes MSVC 19.44.35225.0: + D:\a\gdal\gdal\frmts\gtiff\libtiff\tif_jpeg.c(2036,40): error C2220: the following warning is treated as an error [D:\a\gdal\gdal\build\frmts\gtiff\libtiff\libtiff.vcxproj] + D:\a\gdal\gdal\frmts\gtiff\libtiff\tif_jpeg.c(2036,40): warning C4334: '<<': result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?) [D: + + Reformatting fix. + +2026-04-04 Roger Leigh + + Merge branch 'warning-additions3' into 'master' + Add additional warnings: write-strings and conversion + + See merge request libtiff/libtiff!802 + +2026-04-04 Roger Leigh + + tiff_ojpeg: Correct cast. + + tiff2ps: Simplify casts in ps_bytesperrow calculation. + + iptcutil: Don't check if unsigned value is less than zero. + + Merge remote-tracking branch 'origin/master' into warning-additions3. + +2026-04-04 Vladimir D. Seleznev + + tiffcrop: Remove dead code in combineSeparateTileSamplesBytes() + +2026-04-01 Even Rouault + + Merge branch 'issue-808-put1bitbwtile' into 'master' + tif_getimage: reject tile widths that would overflow toskew (#808) + + See merge request libtiff/libtiff!860 + +2026-04-01 Even Rouault + + Merge branch 'fix_805' into 'master' + TIFFVTileSize64(): in YCbCr contig non upsampled mode, validate td_samplesperpixel==3 + + Closes #805 + + See merge request libtiff/libtiff!859 + +2026-04-01 waugustus + + tif_getimage: reject tile widths that would overflow toskew (#808) + +2026-03-29 Even Rouault + + Merge branch 'fix_777_part2_null_pointer_dereferencing' into 'master' + TIFFAppendToStrip(): add some checks to avoid null-pointer-dereferencing (fixes #777 second issue) + + Closes #777 + + See merge request libtiff/libtiff!853 + +2026-03-29 Even Rouault + + Merge branch 'issue_802_tiffcmp' into 'master' + tiffcmp: validate scanline buffer sizes in mixed planar comparison to prevent out-of-bounds reads (#802) + + See merge request libtiff/libtiff!855 + + Fixes #802 + +2026-03-29 Even Rouault + + Merge branch 'issue-803-tiffcrop' into 'master' + tiffcrop: Fix heap-buffer-overflow in composite mode by allocating buffer based on final image layout instead of region-based bufftotal (#803) + + See merge request libtiff/libtiff!856 + +2026-03-29 4ugustus + + tiffcrop: Fix heap-buffer-overflow in composite mode by allocating buffer based on final image layout instead of region-based bufftotal + Fixes #803 + +2026-03-29 Even Rouault + + Merge branch 'issue-804-tiff2pdf' into 'master' + tiff2pdf: Fix integer overflow in RGBA raster allocation in tiff2pdf by validating size computation before _TIFFrealloc() (#804) + + See merge request libtiff/libtiff!857 + +2026-03-29 4ugustus + + tiff2pdf: Fix integer overflow in RGBA raster allocation in tiff2pdf by validating size computation before _TIFFrealloc() + Fixes #804 + +2026-03-29 Even Rouault + + TIFFVTileSize64(): in YCbCr contig non upsampled mode, validate td_samplesperpixel==3 + to reflect the same check as done in TIFFVStripSize64(). + Actually unify both implementations to avoid them drifting apart. + + Adapted from proposed fix of https://gitlab.com/libtiff/libtiff/-/merge_requests/858 + by Quang Luong (@gabezrupp) + + Avoids out-of-bounds access in raw decoding mode on malformed files. + + Fixes #805 + +2026-03-26 waugustus + + tiffcmp: validate scanline buffer sizes in mixed planar comparison to prevent out-of-bounds reads (#802) + +2026-03-23 Even Rouault + + Merge branch 'fix-partial-read-overflow' into 'master' + Fix integer overflow in _TIFFPartialReadStripArray on 32-bit + + See merge request libtiff/libtiff!854 + +2026-03-23 Koda Reef + + Fix integer overflow in _TIFFPartialReadStripArray on 32-bit. + MR !851 fixed an identical overflow at line 8248 by adding a + (uint64_t) cast to prevent 32-bit wraparound in the multiplication + of sizeofval * strile. The same function has the same unchecked + pattern at line 8256 where arraySize * sizeofval can wrap on + 32-bit platforms where size_t is 32-bit. + + Apply the same (uint64_t) cast to ensure the multiplication is + performed in 64-bit arithmetic before addition with nBaseOffset. + +2026-03-22 dataisland + + thumbnail: improve integer overflow check for image memory allocation. + + thumbnail: add integer overflow check for image memory allocation. + +2026-03-22 Even Rouault + + Merge branch '_TIFFPartialReadStripArray_overflow' into 'master' + _TIFFPartialReadStripArray(): avoid potential (unsigned) integer overflow in... + + See merge request libtiff/libtiff!851 + +2026-03-22 Su_Laus + + TIFFAppendToStrip(): add some checks to avoid null-pointer-dereferencing (fixes #777 second issue). + +2026-03-22 dataisland + + thumbnail: prevent integer overflow by capping row count at 256. + +2026-03-21 Even Rouault + + _TIFFPartialReadStripArray(): avoid potential (unsigned) integer overflow in file offset computation, on 32 bit builds + +2026-03-21 Even Rouault + + Merge branch 'fix/rgb2ycbcr-crash' into 'master' + rgb2ycbcr: fix integer overflow check for pixel count calculation + + See merge request libtiff/libtiff!850 + +2026-03-19 dataisland + + rgb2ycbcr: fix integer overflow check for pixel count calculation. + +2026-03-18 Even Rouault + + Merge branch 'fix/thumbnail-nullptr-deref' into 'master' + thumbnail: validate strip/tile byte-count fields before raw copy + + See merge request libtiff/libtiff!847 + +2026-03-18 Even Rouault + + Merge branch 'pixarlog_warning_fixes' into 'master' + tif_pixarlog.c: fix -Wshorten-64-to-32 warnings + + See merge request libtiff/libtiff!849 + +2026-03-18 Even Rouault + + tif_pixarlog.c: fix -Wshorten-64-to-32 warnings. + Fixes + ``` + /home/runner/work/gdal/gdal/frmts/gtiff/libtiff/tif_pixarlog.c:958:43: error: implicit conversion loses integer precision: 'tmsize_t' (aka 'long') to 'int' [-Werror,-Wshorten-64-to-32] + 958 | horizontalAccumulateF(up, llen, sp->stride, (float *)op, + | ~~~~~~~~~~~~~~~~~~~~~ ^~~~ + /home/runner/work/gdal/gdal/frmts/gtiff/libtiff/tif_pixarlog.c:963:44: error: implicit conversion loses integer precision: 'tmsize_t' (aka 'long') to 'int' [-Werror,-Wshorten-64-to-32] + 963 | horizontalAccumulate16(up, llen, sp->stride, (uint16_t *)op, + | ~~~~~~~~~~~~~~~~~~~~~~ ^~~~ + /home/runner/work/gdal/gdal/frmts/gtiff/libtiff/tif_pixarlog.c:968:44: error: implicit conversion loses integer precision: 'tmsize_t' (aka 'long') to 'int' [-Werror,-Wshorten-64-to-32] + 968 | horizontalAccumulate12(up, llen, sp->stride, (int16_t *)op, + | ~~~~~~~~~~~~~~~~~~~~~~ ^~~~ + /home/runner/work/gdal/gdal/frmts/gtiff/libtiff/tif_pixarlog.c:973:44: error: implicit conversion loses integer precision: 'tmsize_t' (aka 'long') to 'int' [-Werror,-Wshorten-64-to-32] + 973 | horizontalAccumulate11(up, llen, sp->stride, (uint16_t *)op); + | ~~~~~~~~~~~~~~~~~~~~~~ ^~~~ + /home/runner/work/gdal/gdal/frmts/gtiff/libtiff/tif_pixarlog.c:977:43: error: implicit conversion loses integer precision: 'tmsize_t' (aka 'long') to 'int' [-Werror,-Wshorten-64-to-32] + 977 | horizontalAccumulate8(up, llen, sp->stride, (unsigned char *)op, + | ~~~~~~~~~~~~~~~~~~~~~ ^~~~ + /home/runner/work/gdal/gdal/frmts/gtiff/libtiff/tif_pixarlog.c:982:47: error: implicit conversion loses integer precision: 'tmsize_t' (aka 'long') to 'int' [-Werror,-Wshorten-64-to-32] + 982 | horizontalAccumulate8abgr(up, llen, sp->stride, + | ~~~~~~~~~~~~~~~~~~~~~~~~~ ^~~~ + /home/runner/work/gdal/gdal/frmts/gtiff/libtiff/tif_pixarlog.c:1349:52: error: implicit conversion loses integer precision: 'tmsize_t' (aka 'long') to 'int' [-Werror,-Wshorten-64-to-32] + 1349 | horizontalDifferenceF((float *)bp, llen, sp->stride, up, + | ~~~~~~~~~~~~~~~~~~~~~ ^~~~ + /home/runner/work/gdal/gdal/frmts/gtiff/libtiff/tif_pixarlog.c:1354:56: error: implicit conversion loses integer precision: 'tmsize_t' (aka 'long') to 'int' [-Werror,-Wshorten-64-to-32] + 1354 | horizontalDifference16((uint16_t *)bp, llen, sp->stride, up, + | ~~~~~~~~~~~~~~~~~~~~~~ ^~~~ + /home/runner/work/gdal/gdal/frmts/gtiff/libtiff/tif_pixarlog.c:1359:60: error: implicit conversion loses integer precision: 'tmsize_t' (aka 'long') to 'int' [-Werror,-Wshorten-64-to-32] + 1359 | horizontalDifference8((unsigned char *)bp, llen, sp->stride, up, + | ~~~~~~~~~~~~~~~~~~~~~ ^~~~ + ``` + +2026-03-17 Even Rouault + + Merge branch 'fix_773' into 'master' + JPEG: fix generation of tiled 12-bit JPEG compressed files with libjpeg-turbo 3.0.3 + + Closes #773 + + See merge request libtiff/libtiff!846 + +2026-03-17 Even Rouault + + Merge branch 'fix_789' into 'master' + PixarLog: fix undoing horizontal differencing when SamplesPerPixel != 3 and 4 + + Closes #789 + + See merge request libtiff/libtiff!845 + +2026-03-17 Even Rouault + + Merge branch 'fix_795' into 'master' + OJPEG: fix nullptr deref when changing compression method from OJPEG to something else + + Closes #795 + + See merge request libtiff/libtiff!844 + +2026-03-17 Even Rouault + + Merge branch 'fix_796' into 'master' + OJPEG codec: fix potential integer overflow/out-of-bounds access + + Closes #796 + + See merge request libtiff/libtiff!843 + +2026-03-17 Even Rouault + + Merge branch 'fix_797' into 'master' + PixarLog codec: fix potential integer overflow/out-of-bounds access + + Closes #797 + + See merge request libtiff/libtiff!842 + +2026-03-17 dataisland + + thumbnail.c: add error handling for missing strip and tile byte counts. + +2026-03-16 Even Rouault + + _TIFFSetDefaultPostDecode(): improve code comment for bitspersample == 128 + +2026-03-16 Even Rouault + + JPEG: fix generation of tiled 12-bit JPEG compressed files with libjpeg-turbo 3.0.3 + Fixes #773 + + Patch by D. R. Commander. (@dcommander) + +2026-03-16 Even Rouault + + PixarLog: fix undoing horizontal differencing when SamplesPerPixel != 3 and 4 + Patch by Christoph Gohlke (@cgohlke) + + Fixes #789 + +2026-03-16 Even Rouault + + OJPEG: fix nullptr deref when changing compression method from OJPEG to something else + Fixes #795 + + OJPEG codec: fix potential integer overflow/out-of-bounds access. + Fixes #796 + + PixarLog codec: fix potential integer overflow/out-of-bounds access. + Fixes #797 + +2026-03-16 Even Rouault + + Merge branch 'thumbnail_build_fix' into 'master' + thumbnail.c: add missing include (master only) + + See merge request libtiff/libtiff!841 + +2026-03-15 Even Rouault + + thumbnail.c: add missing include (master only) + +2026-03-15 Even Rouault + + Merge branch 'formatting_fixes' into 'master' + Formatting fixes + + See merge request libtiff/libtiff!840 + +2026-03-15 Roger Leigh + + thumbnail: Include tiffiop.h for _TIFFMultiply32. + + Merge remote-tracking branch 'origin/master' into warning-additions3. + +2026-03-15 Even Rouault + + Merge branch 'issue-790-median' into 'master' + fix UAF in tiffmedian (#790) + + See merge request libtiff/libtiff!831 + +2026-03-15 Even Rouault + + Merge branch 'issue-790-thumbnail' into 'master' + fix Out-of-Bounds Write in thumbnail (#790) + + See merge request libtiff/libtiff!832 + +2026-03-15 Even Rouault + + Merge branch 'issue-790-tiffsplit' into 'master' + fix global-buffer-overflow in tiffsplit (#790) + + See merge request libtiff/libtiff!833 + +2026-03-15 Even Rouault + + Merge branch 'issue-790-tiffcrop' into 'master' + fix undefined behaviour in tiffcrop (#790) + + See merge request libtiff/libtiff!834 + +2026-03-15 Even Rouault + + Merge branch 'issue-792-put16bitbwtile' into 'master' + fix inconsistent fromskew handling in put16bitbwtile (#792) + + See merge request libtiff/libtiff!836 + +2026-03-15 Roger Leigh + + Simplify casts using more appropriate types. + + Add -Wconversion to extra-warnings. + + Add -Wc99-c11-compat to extra-warnings. + + Add -Wwrite-strings to extra-warnings. + +2026-03-15 Even Rouault + + Formatting fixes. + +2026-03-15 Even Rouault + + Merge branch 'issue_799_strtoul' into 'master' + tools: validate numeric command-line arguments (#799) + + See merge request libtiff/libtiff!839 + +2026-03-15 Even Rouault + + Merge branch 'fix_798' into 'master' + putcontig8bitYCbCr44tile: fix wrong fromskew computation + + Closes #798 + + See merge request libtiff/libtiff!838 + +2026-03-13 waugustus + + tools: validate numeric command-line arguments (#799) + +2026-03-13 Even Rouault + + putcontig8bitYCbCr44tile: fix wrong fromskew computation. + Fix error introduced in 06155116f6ee7f910ac5a8a60e0852c621d72306 + + Fixes #798 + +2026-03-11 waugustus + + fix inconsistent fromskew handling in put16bitbwtile (#792) + +2026-03-03 4ugustus + + Simplify cleanup by removing redundant NULL check. + +2026-03-03 waugustus + + fix undefined behaviour in tiffcrop (#790) + + fix global-buffer-overflow in tiffsplit (#790) + + fix oob write in thumbnail (#790) + + fix UAF in tiffmedian(#790) + +2026-02-26 amaldika + + Enable support for arm64EC. + +2026-02-24 Roger Leigh + + Merge branch 'ci-cygwin-runner' into 'master' + ci: Use dedicated runner for Cygwin builds + + See merge request libtiff/libtiff!829 + +2026-02-24 Roger Leigh + + ci: Correct Cygwin invocation to use proper PATH settings. + + ci: Run Cygwin bash shell directly. + + ci: Use dedicated runner for Cygwin builds. + +2026-02-23 Even Rouault + + Merge branch 'fix_787' into 'master' + TIFFReadRGBAImage(): prevent integer overflow and later heap overflow on... + + Closes #787 + + See merge request libtiff/libtiff!828 + +2026-02-23 Roger Leigh + + Merge branch 'ci-vs-windows-containers' into 'master' + CI: Add Windows container builds for visual studio + + See merge request libtiff/libtiff!827 + +2026-02-22 Even Rouault + + TIFFReadRGBAImage(): prevent integer overflow and later heap overflow on images with huge width in YCbCr tile decoding functions + Fixes https://gitlab.com/libtiff/libtiff/-/issues/787 + +2026-02-22 Roger Leigh + + test: Correct MSVC warnings. + + Use Windows Containers for VS2022 and VS2026 builds. + +2026-02-14 Even Rouault + + Merge branch 'issue-784-tiffcrop' into 'master' + fix stack-overflow in #784 + + See merge request libtiff/libtiff!823 + +2026-02-14 Even Rouault + + Merge branch 'issue-782-TIFFPrintDirectory' into 'master' + Fix NULL pointer deference in TIFFPrintDirectory in #782 + + See merge request libtiff/libtiff!824 + +2026-02-14 waugustus + + fix null pointer deference in #782. + +2026-02-12 waugustus + + fix stack-overflow in #784. + +2026-02-11 Even Rouault + + Merge branch 'formatting_fixes' into 'master' + Formatting fixes + + See merge request libtiff/libtiff!822 + +2026-02-10 Even Rouault + + Formatting fixes. + +2026-02-08 Even Rouault + + Merge branch 'ci-cygwin' into 'master' + CI: Switch Cygwin builds to use Windows Docker image + + See merge request libtiff/libtiff!821 + +2026-02-06 Roger Leigh + + CI: Switch MinGW builds to use Windows Docker image. + Co-Authored-By: Claude Opus 4.6 + + ci: Revert to use powershell. + +2026-02-06 Roger Leigh + + CI: Add bash tag to Cygwin Docker jobs. + Route Cygwin jobs to a dedicated runner with shell=bash, since the + Cygwin Docker image does not contain pwsh. + + Co-Authored-By: Claude Opus 4.6 + +2026-02-06 Roger Leigh + + CI: Switch Cygwin builds to use Windows Docker image. + Use the codelibre/containers/cygwin-libtiff Docker image instead of + bare-metal Cygwin runners. This simplifies the script invocation since + the container's default shell is already Cygwin bash. + + Co-Authored-By: Claude Opus 4.6 + +2026-02-02 Even Rouault + + Merge branch 'tiffdump_unaligned_memory_access_fix_776' into 'master' + tiffdump: Avoid unaligned memory access for tag field values. + + Closes #776 + + See merge request libtiff/libtiff!816 + +2026-02-02 Su Laus + + tiffdump: Avoid unaligned memory access for tag field values. + +2026-02-02 Even Rouault + + Merge branch 'change_EXIF_tags_type_to_LONG8' into 'master' + Change EXIF and GPS tag type from IFD8 to LONG8 - EXIF-specification - #739 + + Closes #739 + + See merge request libtiff/libtiff!819 + +2026-02-02 Even Rouault + + Merge branch 'amend_tools_and_test_for_CPP_compatibility' into 'master' + Amend test and tools for cxx compatibility - mainly "const char *". + + See merge request libtiff/libtiff!820 + +2026-02-01 Su_Laus + + Amend test and tools for cxx compatibility - mainly "const char *". Some additional re-formating due to clang-format. + +2026-01-30 Su_Laus + + CPP compatibility. + + Change EXIF and GPS tag type from IFD8 to LONG8 (UINT64) to fulfill current EXIF-specification. + Closes #739 + +2026-01-22 Even Rouault + + Merge branch 'ojpeg-eof-return' into 'master' + ojpeg: prevent EOF infinite loop (fixes commit 2a3d55b) + + See merge request libtiff/libtiff!818 + +2026-01-22 Lovell Fuller + + ojpeg: prevent EOF infinite loop (fixes commit 2a3d55b) + +2026-01-22 Bob Friesenhahn + + Merge branch 'tif_dirread.c-duplicate-TIFF_SETGET_C0_IFD8' into 'master' + Eliminate duplicate case TIFF_SETGET_C0_IFD8 + + See merge request libtiff/libtiff!817 + +2026-01-22 Bob Friesenhahn + + Eliminate duplicate case TIFF_SETGET_C0_IFD8. + +2026-01-21 Even Rouault + + Merge branch 'tiffcp-770' into 'master' + tiffcp - avoid integer overflow in iskew and oskew, #770 + + See merge request libtiff/libtiff!813 + +2026-01-21 Even Rouault + + Merge branch 'align_handling_of_LONG8_IFD8_tags' into 'master' + Align writing and reading of TIFF_LONG8 and TIFF_IFD8 tags. + + See merge request libtiff/libtiff!773 + +2026-01-20 Even Rouault + + Merge branch 'fax2tiff-759' into 'master' + fax2tiff: avoid endless loop on corrupt input, #759 + + See merge request libtiff/libtiff!807 + +2026-01-20 Even Rouault + + Merge branch 'tiffsplit-769' into 'master' + tiffsplit: check filename length, #769 + + See merge request libtiff/libtiff!808 + +2026-01-19 Roger Leigh + + Merge branch 'warning-additions2' into 'master' + Add additional compiler warnings to extra-warnings + + See merge request libtiff/libtiff!800 + +2026-01-09 Lee Howard + + tiffcp - avoid integer overflow in iskew and oskew, #770. + +2025-12-31 Lee Howard + + tiffsplit: check filename length, #769. + + fax2tiff: avoid endless loop on corrupt input, #759. + +2025-12-29 Roger Leigh + + Merge remote-tracking branch 'origin/master' into warning-additions2. + +2025-12-27 Roger Leigh + + Merge branch 'fix_ossfuzz_471945501' into 'master' + JPEGDecode(): fix memory leak in error code path + + See merge request libtiff/libtiff!803 + +2025-12-27 Even Rouault + + JPEGDecode(): fix memory leak in error code path. + Fixes https://issues.oss-fuzz.com/issues/471945501 + +2025-12-25 Even Rouault + + Merge branch 'warning-additions' into 'master' + ci: Build CMake builds with extra-warnings + + See merge request libtiff/libtiff!798 + +2025-12-25 Roger Leigh + + Merge branch 'ossfuzz_471472003' into 'master' + TIFFFillStrip(): prevent harmless unsigned integer overflow + + See merge request libtiff/libtiff!801 + +2025-12-25 Roger Leigh + + Add version guards for LZMA enums. + + Add -Wswitch-enum to extra-warnings. + * Fix warnings + + Add -Wswitch-default to extra-warnings. + * Fix warnings + +2025-12-25 Even Rouault + + TIFFFillStrip(): prevent harmless unsigned integer overflow. + Fixes https://issues.oss-fuzz.com/issues/471472003 + +2025-12-24 Roger Leigh + + Add -Wstrict-prototypes and -Wmissing-prototypes to extra-warnings. + * Add 'static' keyword to file-local functions that lack external visibility + * Create header files for functions shared between test source files + + Add -Wshadow to extra-warnings. + + Add -Wnull-dereference to extra-warnings. + +2025-12-24 Roger Leigh + + Merge branch 'fix_ossfuzz_471328917' into 'master' + _TIFFGetStrileOffsetOrByteCountValue(): fix potential crash on corrupted files... + + See merge request libtiff/libtiff!799 + +2025-12-24 Roger Leigh + + Correct -Wformat errors. + Fix format string mismatches where the format specifier doesn't match + the argument type: + + - Change %d to %u for unsigned int/uint32_t arguments + - Change %u to %d for signed int arguments + - Add casts where needed for printf family functions + - Use PRIu64/PRIi64 for uint64_t/int64_t arguments + + Fix -Wformat-nonliteral warnings + + Add TIFF_ATTRIBUTE((__format__(__printf__, N, 0))) to functions that + accept format strings as parameters (va_list style). The 0 indicates + no variadic arguments to check since the format is validated at the + call site. + +2025-12-24 Roger Leigh + + Correct -pedantic errors. + * Missing void in function declarations + * Extra semicolons + + ci: Build CMake builds with extra-warnings. + * Split extra-warnings into extra-warnings and broken-warnings + * extra-warnings initially only uses -pedantic -Wextra + * Warnings will be moved from broken-warnings to extra-warnings + once the CI builds have proved them safe to use + + ci: Pre-build is static. + * Includes additional test source files + +2025-12-24 Even Rouault + + _TIFFGetStrileOffsetOrByteCountValue(): fix potential crash on corrupted files when file opened in 'O' mode + Fixes https://issues.oss-fuzz.com/issues/471328917 + +2025-12-23 Even Rouault + + Merge branch 'typo_fix' into 'master' + tif_dirread.c: fix typo in code comment (master only) + + See merge request libtiff/libtiff!797 + +2025-12-23 Even Rouault + + tif_dirread.c: fix typo in code comment (master only) + +2025-12-22 Roger Leigh + + Merge branch 'fix_ossfuzz_470691578' into 'master' + TIFFReadDirectory(): re-set TIFF_LAZYSTRILELOAD if file opened in 'O' mode + + See merge request libtiff/libtiff!793 + +2025-12-22 Even Rouault + + Rework TIFF_LAZYSTRILELOAD flag. + +2025-12-22 Even Rouault + + TIFFReadDirectory(): re-set TIFF_LAZYSTRILELOAD if file opened in 'O' mode + This fixes a potential heap write buffer overflow when reading a + corrupted file, with multiple IFDs, and when iterating over those IFDs, + and when the file was opened in 'O' mode. + + Fixes https://issues.oss-fuzz.com/issues/470691578 + +2025-12-21 Roger Leigh + + Merge branch 'ci-vcpkg' into 'master' + ci: Use vcpkg installation specific to libtiff + + See merge request libtiff/libtiff!792 + +2025-12-21 Roger Leigh + + ci: Use vcpkg installation specific to libtiff. + +2025-12-21 Roger Leigh + + Merge branch 'cpp-check' into 'master' + Add explicit casts for void* and int-to-enum conversions + + See merge request libtiff/libtiff!791 + +2025-12-21 Roger Leigh + + ci: enforce MSVC /W4 warnings. + + Correct MSVC /W4 warnings. + * Shadowing (add local_ prefix) + * Conversion (add casts) + * Initialisation (initialise with value) + +2025-12-20 Roger Leigh + + tif_dirinfo: Restore MSVC warning disable 4132. + + ci: Run compatibility checks before main builds. + + Allow tif_jbig to compile with C++ compiler. + + cmake: Improve tiff_target_compile_as_cxx implementation. + + tif_dir: Correct C++ circular dependency warning. + +2025-12-18 Roger Leigh + + ci: Test C++ compatibility mode. + +2025-12-18 Roger Leigh + + Add CMake options for C++ compatibility checking. + Add two new CMake options to help maintain C++ compatibility: + + 1. cxx-compat-warnings: Enables -Wc++-compat flag (GCC/Clang) which + warns about using C++ keywords as identifiers and some enum/int + conversions. This is limited and won't catch all issues. + + 2. cxx-compat-mode: Compiles C source files as C++17 using -x c++ + (GCC/Clang) or /TP (MSVC). This catches all C++ incompatibilities + as compile errors, including: + - implicit void* to typed pointer conversions + - register storage class (removed in C++17) + - goto/switch jumping over variable initialization + - enum arithmetic and implicit conversions + + Usage: + cmake -Dcxx-compat-warnings=ON .. # Light checking + cmake -Dcxx-compat-mode=ON .. # Full C++ compilation + +2025-12-18 Roger Leigh + + Fix remaining C++ compatibility issues. + - tif_compress.c: Cast const away for strcpy to initialized const char* field + - tif_jpeg.c: Add unsigned short* cast for malloc result + - tif_ojpeg.c: Add JSAMPARRAY and JSAMPIMAGE casts for jpeg functions + - tif_print.c: Change sep variable from char* to const char* + - mkspans.c: Convert K&R style functions to ANSI C, add return type to main + + Add more explicit void* to typed pointer casts in tools. + Additional C++ compatibility fixes for implicit void* to typed pointer + conversions that are not allowed in C++. These files had function calls + where void* (tdata_t) was passed to functions expecting typed pointers + like uint8_t* or unsigned char*. + +2025-12-18 Roger Leigh + + Add explicit casts for void* and int-to-enum conversions. + C++ is stricter about type conversions than C: + + 1. void* to typed pointer: In C++ you cannot implicitly convert void* + to a typed pointer. Add explicit casts for custom tag value pointers + passed to TIFFWriteDirectoryTag* functions. + + 2. Integer to enum: C++ requires explicit casts when assigning integer + types to enum types. Add casts for: + - TIFFDataWidth() calls where tdir_type (uint16_t) is passed + - TIFFDataType assignments from uint16_t entry_type + + Files modified: + - tif_dirwrite.c: Cast td_customValues[m].value to appropriate types + for each TIFF type (char*, uint8_t*, int8_t*, uint16_t*, etc.) + and cast entry_type to TIFFDataType where needed + - tif_dirread.c: Cast tdir_type to TIFFDataType for TIFFDataWidth calls + +2025-12-18 Roger Leigh + + Merge branch 'ci-windows' into 'master' + ci: Add Windows builds + + See merge request libtiff/libtiff!790 + +2025-12-17 Roger Leigh + + Add .gitattributes. + + ci: Corrections for Cygwin and MinGW builds. + + ci: Restrict most jobs to libtiff/libtiff. + +2025-12-16 Roger Leigh + + ci: Add Windows builds. + + ci: Drop AppVeyor use. + +2025-12-16 Even Rouault + + Merge branch 'TIFFReadDirEntryPersampleShort_zero' into 'master' + TIFFReadDirEntryPersampleShort(): reject tags with tdir_count=0 (master only) + + Closes #764 + + See merge request libtiff/libtiff!788 + +2025-12-16 Even Rouault + + Merge branch 'tiffFieldArray_msvc_warning' into 'master' + tif_dirinfo.c: re-add MSVC warning suppression (master only) + + See merge request libtiff/libtiff!789 + +2025-12-16 Even Rouault + + tif_dirinfo.c: re-add MSVC warning suppression (master only) + It has been removed by a recent commit, but is still needed to get a + warning free build when using most verbose warning levels. + +2025-12-16 Even Rouault + + TIFFReadDirEntryPersampleShort(): reject tags with tdir_count=0 (master only) + This amends commit b8fda5eeb8567d63f37e18b24a37e7e4d7a5bfdc that could + lead to reading uninitialized variables. + + Fixes #764 + +2025-12-16 Roger Leigh + + Merge branch 'ci-linux' into 'master' + ci: Use Linux Docker runner + + See merge request libtiff/libtiff!787 + +2025-12-15 Roger Leigh + + ci: Use Linux Docker runner. + +2025-12-15 Roger Leigh + + Merge branch 'ci-macos' into 'master' + ci: Add MacOS and FreeBSD builds + + See merge request libtiff/libtiff!786 + +2025-12-15 Roger Leigh + + ci: Add MacOS and FreeBSD builds. + +2025-12-14 Roger Leigh + + Merge branch 'fix-enum-cpp-compat' into 'master' + Fix enum-related C++ compatibility issues + + See merge request libtiff/libtiff!785 + +2025-12-14 Roger Leigh + + Merge branch 'fix-goto-variable-init' into 'master' + Fix goto bypassing variable initialisation + + See merge request libtiff/libtiff!783 + +2025-12-14 Roger Leigh + + Merge remote-tracking branch 'origin/master' into fix-goto-variable-init + +2025-12-14 Roger Leigh + + Merge branch 'explicit-cast-void-pointer' into 'master' + Add explicit casts for void* to typed pointer conversions + + See merge request libtiff/libtiff!782 + +2025-12-14 Roger Leigh + + Merge branch 'const-char-literals-data' into 'master' + Use const char* for string literals and const data + + See merge request libtiff/libtiff!781 + +2025-12-14 Roger Leigh + + Merge branch 'remove-register-keyword' into 'master' + Remove use of register keyword + + See merge request libtiff/libtiff!779 + +2025-12-14 Roger Leigh + + Merge branch 'configure-ac-require-ac-2-71' into 'master' + configure.ac: Require bootstrap with at least Autoconf 2.71 + + See merge request libtiff/libtiff!784 + +2025-12-14 Roger Leigh + + Add explicit casts for void* to typed pointer conversions. + C++ requires explicit casts when converting from void* to typed pointers, + unlike C which allows implicit conversion. This change adds the necessary + casts to all memory allocation results (_TIFFmallocExt, _TIFFcallocExt, + _TIFFreallocExt) and other void* assignments throughout the codebase. + + Files modified: + - tif_dir.c: Cast for double* allocation + - tif_dirread.c: Casts for uint8_t* allocations + - tif_dirwrite.c: Multiple casts for various typed pointer allocations + - tif_getimage.c: Casts for uint8_t* allocations + - tif_jpeg.c: Cast for uint8_t* buffer assignment + - tif_ojpeg.c: Multiple casts for OJPEGState*, uint8_t*, uint8_t** allocations + - tif_read.c: Casts for uint8_t* and function pointer arguments + - tif_webp.c: Casts for uint8_t* allocations + - tif_zip.c: Cast for TIFF* from opaque pointer + + C++ requires explicit casts when assigning void* (from malloc, realloc, + _TIFFmalloc, etc.) to typed pointers. Add casts in: + + - tools/fax2tiff.c: rowbuf, refbuf, tif_rawdata allocations + - tools/raw2tiff.c: buf1, buf2 allocations + - tools/tiff2ps.c: ascii85_p allocations + - tools/tiffcrop.c: tilebuf, buff, new_buff, next_buff allocations + - tools/tiffinfo.c: subIFDoffsets allocation + - test/rewrite_tag.c: buf allocation + - test/test_IFD_enlargement.c: pbufLine allocation + - test/test_RGBAImage.c: pbufLine allocation + - test/test_transferfunction_write_read.c: pTransferFunctionData, bufLine + +2025-12-14 Roger Leigh + + Fix goto bypassing variable initialisation. + C++ does not allow a goto statement to jump past a variable declaration + with initialisation. + +2025-12-14 Roger Leigh + + Fix enum initialisation and bitwise operations. + C++ doesn't allow implicit int-to-enum conversions. Fix by: + - Using enum value PIXEL instead of 0 for InterleavingType initialisation + - Adding explicit (t2p_cs_t) casts for bitwise OR/XOR operations on t2p_cs_t + - Adding explicit (t2p_sample_t) cast for bitwise OR on t2p_sample_t + + Files modified: + - tools/raw2tiff.c: InterleavingType initialisation + - tools/tiff2pdf.c: t2p_cs_t and t2p_sample_t bitwise operations + +2025-12-14 Roger Leigh + + Fix enum-related C++ compatibility issues. + C++ is stricter than C about enum types: + 1. Cannot use ++ operator on enum types directly - must cast through int + 2. Cannot initialize enum members with integer literals - must use enum values + 3. Cannot forward declare const objects without initialization + + Changes: + - tif_ojpeg.c: Replace sp->out_state++ with explicit cast pattern + sp->out_state = (OJPEGStateOutState)(sp->out_state + 1) + - tif_dirinfo.c: Use TIFF_SETGET_UNDEFINED instead of 0 for + TIFFSetGetFieldType member in TIFFField struct initialization + - tif_dirinfo.c: Use #ifdef __cplusplus to handle forward declarations + of const TIFFFieldArray objects differently for C vs C++ + +2025-12-13 Bob Friesenhahn + + configure.ac: Require bootstrap with at least Autoconf 2.71. + +2025-12-13 Roger Leigh + + Use const char* for string literals and const data. + Change TIFFCodec::name, TIFFField::field_name, and TIFFFieldInfo::field_name + from char* to const char* to allow assignment of string literals without + warnings in C++ mode. + + For dynamically allocated field names (anonymous tags), use a local buffer + variable before assigning to the const field. Add explicit (void*) casts + when freeing these dynamically allocated names. + +2025-12-13 Roger Leigh + + Merge branch 'cmake-cmath-avoid-imported-target_neroburner' into 'master' + cmake: Replace CMath::CMath with direct link to avoid export + + Closes #625 + + See merge request libtiff/libtiff!764 + +2025-12-13 Roger Leigh + + Merge branch 'cmake-allow_all_find_package_capitalizations' into 'master' + cmake: install tiff-config.cmake to allow all capitalizations + + See merge request libtiff/libtiff!763 + +2025-12-13 Roger Leigh + + Merge branch 'cmake_mingw_soversion' into 'master' + CMake: add SOVERSION to DLLs for MinGW builds + + See merge request libtiff/libtiff!392 + +2025-12-12 Roger Leigh + + Remove use of register keyword. + * register is not particularly useful with modern optimising + compilers + * If compiling as C++, it's not compatible with C++17 and + newer, which have removed support for the register + keyword + +2025-12-07 Even Rouault + + Merge branch 'fix_679_tiff2ps_check_for_double_to_int32' into 'master' + Checking the range of double values in tiff2ps before converting to int32_t. Closes #679 + + Closes #679 + + See merge request libtiff/libtiff!777 + +2025-12-07 Su Laus + + Checking the range of double values in tiff2ps before converting to int32_t. Closes #679 + +2025-12-07 Even Rouault + + Merge branch 'SampleFormat_not_SamplesPerPixel' into 'master' + TIFFReadDirEntryPersampleShort(): be tolerant to tags like SampleFormat not... + + See merge request libtiff/libtiff!770 + +2025-12-07 Even Rouault + + Merge branch 'fix_Coverity_tiffdump_false-positive_tainted_data' into 'master' + Silence Coverity Scan warning about tainted_data in tiffdump. + + See merge request libtiff/libtiff!774 + +2025-12-07 Even Rouault + + Merge branch 'validate-data_precision' into 'master' + tif_jpeg: reject mismatched JPEG data precision to avoid write overflow + + See merge request libtiff/libtiff!776 + +2025-12-05 Even Rouault + + Merge branch 'fix_755_TIFFMergeFields_nfields_not_reset_to_zero' into 'master' + Fix #755: In _TIFFMergeFields() set tif_nfields to zero if buffer cannot be re-allocated to avoid NULL ptr dereference. + + Closes #755 + + See merge request libtiff/libtiff!775 + +2025-12-01 Mikhail Khachaiants + + tif_jpeg: reject mismatched JPEG data precision to avoid write overflow. + Ensure TIFF BitsPerSample matches both BITS_IN_JSAMPLE and the JPEG + header data_precision for JPEG-compressed images. This prevents + under-sized scanline buffers that can lead to write buffer overflows + in jdcolor.c/null_convert when decoding malformed inputs. + +2025-11-29 Su_Laus + + In _TIFFMergeFields() set tif_nfields to zero if buffer cannot be re-allocated to avoid NULL pointer dereference in TIFFReadDirectoryFindFieldInfo(). + Closes #755 + + Silence Coverity Scan warning about tainted_data: Passing tainted expression *datamem to PrintData, which uses it as a divisor or modulus. False positive because division by zero is checked in PrintData(). + +2025-11-29 Even Rouault + Su Laus + + Apply 2 suggestion(s) to 1 file(s) + +2025-11-29 Su_Laus + + Align writing and reading of TIFF_LONG8 and TIFF_IFD8 tags. + +2025-11-29 Even Rouault + + Merge branch 'warning_fixes' into 'master' + Fix compiler warnings with clang 18 + + See merge request libtiff/libtiff!771 + +2025-11-29 Even Rouault + + Merge branch 'fix_AppVeyor_mingw_error_after_MR_issue-753' into 'master' + Fix bug introduced by MR libtiff/libtiff!769 - AppVeyor mingw - + + See merge request libtiff/libtiff!772 + +2025-11-28 Su_Laus + + Fix bug introduced by MR libtiff/libtiff!769 (issue-753-putcontig8bitYCbCr42tile) and revealed by mingw build in AppVeyor. + +2025-11-25 Even Rouault + + Fix compiler warnings with clang 18. + +2025-11-25 Even Rouault + + Merge branch 'issue-751-tiffcrop' into 'master' + Fix: avoid dangling pointer in loadImage by clearing *read_ptr after free (#751) + + See merge request libtiff/libtiff!766 + +2025-11-25 Even Rouault + + Merge branch 'issue-752-tiffcrop' into 'master' + tiffcrop: fix undefined behavior in reverseSamples32bits() (#752) + + See merge request libtiff/libtiff!767 + +2025-11-25 Even Rouault + + Merge branch 'fix_750_ipctutil_out_of_bound_read_search_semicolon' into 'master' + Prevent convertHTMLcodes() in iptcutil.c. to perform out-of-bound read. Fixes #750 + + Closes #750 + + See merge request libtiff/libtiff!768 + +2025-11-25 Even Rouault + + Merge branch 'issue-753-putcontig8bitYCbCr42tile' into 'master' + Reject invalid YCbCr subsampling when image dimensions are smaller than the subsampling block to prevent out-of-bounds writes. (#753) + + See merge request libtiff/libtiff!769 + +2025-11-25 Even Rouault + + TIFFReadDirEntryPersampleShort(): be tolerant to tags like SampleFormat not having 1 or SamplesPerPixel values + Fixes https://github.com/OSGeo/gdal/issues/13465 + +2025-11-24 waugustus + + Reject invalid YCbCr subsampling when image dimensions are smaller than the subsampling block to prevent out-of-bounds writes. (#753) + +2025-11-11 waugustus + + tiffcrop: fix undefined behavior in reverseSamples32bits() (#752) + +2025-11-10 waugustus + + Fix: avoid dangling pointer in loadImage by clearing *read_ptr after free + When reusing the read buffer, freeing the old buffer left *read_ptr pointing + to freed memory and could lead to use-after-free or double-free in callers. + Clear *read_ptr after freeing and write back the newly allocated buffer on + success. + +2025-11-08 Su_Laus + + Prevent convertHTMLcodes() function in contrib/iptcutil/iptcutil.c. to perform an out-of-bounds read while searching for the semicolon. + Closes #750 + +2025-11-06 Even Rouault + + Merge branch 'fix_749_stripbytecounts_array_null_pointer_to_rewrite' into 'master' + Check td_stripbytecount_p and td_stripoffset_p for NULL pointer before (re-)writing to file. + + Closes #749 + + See merge request libtiff/libtiff!765 + +2025-11-04 Su_Laus + + Check td_stripbytecount_p and td_stripoffset_p for NULL pointer before (re-)writing to file. + Closes #749 + +2025-09-17 Reinhold Gschweicher + + cmake: rename TiffConfig.cmake.in to tiff-config.cmake.in. + As requested by code review and to make it more coherent. + +2025-09-15 Reinhold Gschweicher + + cmake: Replace CMath::CMath with direct link to avoid export. + Link with CMATH_LIBRARIES instead of CMath::CMath. While this + will still be exported, it will be available on the host system. + + Port of original commit: + 67f73084ca824e6c2465c47a5b67b16b5beca569 + + co-authored: Roger Leigh + +2025-09-15 Reinhold Gschweicher + + cmake: install tiff-config.cmake to allow all capitalizations. + Rename `TiffConfig.cmake` to `tiff-config.cmake` to allow all + capitalizations of `find_package(TIFF)` to be found. + +2025-09-12 Even Rouault + + Merge branch '4.7.1_preparation' into 'master' + Prepare for 4.7.1 release + + See merge request libtiff/libtiff!762 + 2025-09-11 Even Rouault Merge branch 'raw2tiff-742' into 'master' diff --git a/3rdparty/libtiff/RELEASE-DATE b/3rdparty/libtiff/RELEASE-DATE index cc3bc45669..4fff66f6b5 100644 --- a/3rdparty/libtiff/RELEASE-DATE +++ b/3rdparty/libtiff/RELEASE-DATE @@ -1 +1 @@ -20250911 +20260627 diff --git a/3rdparty/libtiff/tif_aux.c b/3rdparty/libtiff/tif_aux.c index 31b240070c..1b2db76867 100644 --- a/3rdparty/libtiff/tif_aux.c +++ b/3rdparty/libtiff/tif_aux.c @@ -56,6 +56,21 @@ uint64_t _TIFFMultiply64(TIFF *tif, uint64_t first, uint64_t second, return first * second; } +uint64_t _TIFFAdd64(TIFF *tif, uint64_t first, uint64_t second, + const char *where) +{ + if (first > UINT64_MAX - second) + { + if (tif != NULL && where != NULL) + { + 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) { @@ -81,6 +96,30 @@ tmsize_t _TIFFMultiplySSize(TIFF *tif, tmsize_t first, tmsize_t second, return first * second; } +tmsize_t _TIFFAddSSize(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 _TIFFAddSSize() 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) @@ -94,6 +133,55 @@ tmsize_t _TIFFCastUInt64ToSSize(TIFF *tif, uint64_t val, const char *module) return (tmsize_t)val; } +uint32_t _TIFFCastUInt64ToUInt32(TIFF *tif, uint64_t val, const char *module) +{ + if (val > UINT32_MAX) + { + if (tif != NULL && module != NULL) + { + TIFFErrorExtR(tif, module, "Integer overflow"); + } + return 0; + } + return (uint32_t)val; +} + +tmsize_t _TIFFComputeRowOffset(TIFF *tif, tmsize_t rowstride, uint32_t row, + const char *where) +{ + if (row == 0) + return 0; + return _TIFFMultiplySSize(tif, rowstride, (tmsize_t)row, where); +} + +uint64_t _TIFFComputeBitOffset(TIFF *tif, uint32_t col, uint16_t spp, + uint16_t bps, const char *where) +{ + uint64_t samples = _TIFFMultiply64(tif, col, spp, where); + if (samples == 0 && col != 0) + return 0; + return _TIFFMultiply64(tif, samples, bps, where); +} + +/* + * Returns 0 on overflow or invalid zero-sized row inputs. Callers that + * intentionally allow empty rows should not use this helper directly. + */ +uint64_t _TIFFComputeRowSize64(TIFF *tif, uint32_t width, uint16_t spp, + uint16_t bps, const char *where) +{ + uint64_t samples = _TIFFMultiply64(tif, width, spp, where); + uint64_t bits; + if (samples == 0) + return 0; + + bits = _TIFFMultiply64(tif, samples, bps, where); + if (bits == 0) + return 0; + + return TIFFhowmany8_64(bits); +} + void *_TIFFCheckRealloc(TIFF *tif, void *buffer, tmsize_t nmemb, tmsize_t elem_size, const char *what) { @@ -137,8 +225,8 @@ static int TIFFDefaultTransferFunction(TIFF *tif, TIFFDirectory *td) if (td->td_bitspersample > 24) return 0; - n = ((tmsize_t)1) << td->td_bitspersample; - nbytes = n * sizeof(uint16_t); + n = (tmsize_t)(1ULL << td->td_bitspersample); + nbytes = (tmsize_t)((uint64_t)n * sizeof(uint16_t)); tf[0] = (uint16_t *)_TIFFmallocExt(tif, nbytes); if (tf[0] == NULL) return 0; @@ -186,10 +274,10 @@ static int TIFFDefaultRefBlackWhite(TIFF *tif, TIFFDirectory *td) * 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[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; + td->td_refblackwhite[5] = 255.0f; + td->td_refblackwhite[2] = td->td_refblackwhite[4] = 128.0f; } else { @@ -199,8 +287,11 @@ static int TIFFDefaultRefBlackWhite(TIFF *tif, TIFFDirectory *td) 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); + if (td->td_bitspersample < 64) + td->td_refblackwhite[2 * i + 1] = + (float)((1ULL << td->td_bitspersample) - 1ULL); + else + td->td_refblackwhite[2 * i + 1] = (float)UINT64_MAX; } } return 1; @@ -258,8 +349,8 @@ int TIFFVGetFieldDefaulted(TIFF *tif, uint32_t tag, va_list ap) * 65535 even if td_bitspersamle is > 16 */ if (td->td_bitspersample <= 16) { - maxsamplevalue = (1 << td->td_bitspersample) - - 1; /* 2**(BitsPerSample) - 1 */ + maxsamplevalue = (uint16_t)((1U << td->td_bitspersample) - + 1); /* 2**(BitsPerSample) - 1 */ } else { @@ -295,7 +386,11 @@ int TIFFVGetFieldDefaulted(TIFF *tif, uint32_t tag, va_list ap) } case TIFFTAG_DOTRANGE: *va_arg(ap, uint16_t *) = 0; - *va_arg(ap, uint16_t *) = (1 << td->td_bitspersample) - 1; + if (td->td_bitspersample <= 16) + *va_arg(ap, uint16_t *) = + (uint16_t)((1U << td->td_bitspersample) - 1); + else + *va_arg(ap, uint16_t *) = 65535; return (1); case TIFFTAG_INKSET: *va_arg(ap, uint16_t *) = INKSET_CMYK; @@ -309,14 +404,14 @@ int TIFFVGetFieldDefaulted(TIFF *tif, uint32_t tag, va_list ap) return (1); case TIFFTAG_MATTEING: *va_arg(ap, uint16_t *) = - (td->td_extrasamples == 1 && + (td->td_extrasamples == 1 && td->td_sampleinfo && 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; + *va_arg(ap, uint16_t *) = (uint16_t)(td->td_sampleformat - 1); return (1); case TIFFTAG_SAMPLEFORMAT: *va_arg(ap, uint16_t *) = td->td_sampleformat; @@ -369,6 +464,8 @@ int TIFFVGetFieldDefaulted(TIFF *tif, uint32_t tag, va_list ap) return (0); *va_arg(ap, const float **) = td->td_refblackwhite; return (1); + default: + break; } return 0; } @@ -390,9 +487,9 @@ int TIFFGetFieldDefaulted(TIFF *tif, uint32_t tag, ...) float _TIFFClampDoubleToFloat(double val) { - if (val > FLT_MAX) + if (val > (double)FLT_MAX) return FLT_MAX; - if (val < -FLT_MAX) + if (val < -(double)FLT_MAX) return -FLT_MAX; return (float)val; } @@ -401,7 +498,7 @@ uint32_t _TIFFClampDoubleToUInt32(double val) { if (val < 0) return 0; - if (val > 0xFFFFFFFFU || val != val) + if (val > 0xFFFFFFFFU || isnan(val)) return 0xFFFFFFFFU; return (uint32_t)val; } diff --git a/3rdparty/libtiff/tif_close.c b/3rdparty/libtiff/tif_close.c index d498010740..e60aba7113 100644 --- a/3rdparty/libtiff/tif_close.c +++ b/3rdparty/libtiff/tif_close.c @@ -88,7 +88,7 @@ void TIFFCleanup(TIFF *tif) */ TIFFFieldIsAnonymous(fld)) { - _TIFFfreeExt(tif, fld->field_name); + _TIFFfreeExt(tif, (void *)fld->field_name); _TIFFfreeExt(tif, fld); } } @@ -121,7 +121,7 @@ void TIFFCleanup(TIFF *tif) } /************************************************************************/ -/* _TIFFCleanupIFDOffsetAndNumberMaps() */ +/* _TIFFCleanupIFDOffsetAndNumberMaps() */ /************************************************************************/ void _TIFFCleanupIFDOffsetAndNumberMaps(TIFF *tif) @@ -139,7 +139,7 @@ void _TIFFCleanupIFDOffsetAndNumberMaps(TIFF *tif) } /************************************************************************/ -/* TIFFClose() */ +/* TIFFClose() */ /************************************************************************/ /** diff --git a/3rdparty/libtiff/tif_color.c b/3rdparty/libtiff/tif_color.c index a52fdacba5..4a17914a44 100644 --- a/3rdparty/libtiff/tif_color.c +++ b/3rdparty/libtiff/tif_color.c @@ -55,34 +55,34 @@ void TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a, int32_t b, 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 L = (float)l * 100.0f / 65535.0f; float cby, tmp; - if (L < 8.856F) + if (L < 8.856f) { - *Y = (L * cielab->Y0) / 903.292F; - cby = 7.787F * (*Y / cielab->Y0) + 16.0F / 116.0F; + *Y = (L * cielab->Y0) / 903.292f; + cby = 7.787f * (*Y / cielab->Y0) + 16.0f / 116.0f; } else { - cby = (L + 16.0F) / 116.0F; + 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; + 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; + 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))) +#define RINT(R) ((uint32_t)((R) > 0 ? ((R) + 0.5f) : ((R) - 0.5f))) /* * Convert color value from the XYZ space to RGB. */ @@ -143,32 +143,32 @@ int TIFFCIELabToRGBInit(TIFFCIELabToRGB *cielab, const TIFFDisplay *display, _TIFFmemcpy(&cielab->display, display, sizeof(TIFFDisplay)); /* Red */ - dfGamma = 1.0 / cielab->display.d_gammaR; + dfGamma = 1.0 / (double)cielab->display.d_gammaR; cielab->rstep = - (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range; + (cielab->display.d_YCR - cielab->display.d_Y0R) / (float)cielab->range; for (i = 0; i <= (size_t)cielab->range; i++) { - cielab->Yr2r[i] = cielab->display.d_Vrwr * + cielab->Yr2r[i] = (float)cielab->display.d_Vrwr * ((float)pow((double)i / cielab->range, dfGamma)); } /* Green */ - dfGamma = 1.0 / cielab->display.d_gammaG; + dfGamma = 1.0 / (double)cielab->display.d_gammaG; cielab->gstep = - (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range; + (cielab->display.d_YCR - cielab->display.d_Y0R) / (float)cielab->range; for (i = 0; i <= (size_t)cielab->range; i++) { - cielab->Yg2g[i] = cielab->display.d_Vrwg * + cielab->Yg2g[i] = (float)cielab->display.d_Vrwg * ((float)pow((double)i / cielab->range, dfGamma)); } /* Blue */ - dfGamma = 1.0 / cielab->display.d_gammaB; + dfGamma = 1.0 / (double)cielab->display.d_gammaB; cielab->bstep = - (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range; + (cielab->display.d_YCR - cielab->display.d_Y0R) / (float)cielab->range; for (i = 0; i <= (size_t)cielab->range; i++) { - cielab->Yb2b[i] = cielab->display.d_Vrwb * + cielab->Yb2b[i] = (float)cielab->display.d_Vrwb * ((float)pow((double)i / cielab->range, dfGamma)); } @@ -186,11 +186,11 @@ int TIFFCIELabToRGBInit(TIFFCIELabToRGB *cielab, const TIFFDisplay *display, * see below for more information on how it works. */ #define SHIFT 16 -#define FIX(x) ((int32_t)((x) * (1L << SHIFT) + 0.5)) +#define FIX(x) ((int32_t)((double)(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)) + (((float)((c) - (int32_t)(RB)) * (float)(CR)) / \ + ((!TIFF_FLOAT_EQ((RW), (RB))) ? ((RW) - (RB)) : 1.0f)) /* !((f)>=(min)) written that way to deal with NaN */ #define CLAMP(f, min, max) \ ((!((f) >= (min))) ? (min) : (f) > (max) ? (max) : (f)) @@ -207,12 +207,12 @@ void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32_t Y, int32_t Cb, int32_t Cr, Cr = CLAMP(Cr, 0, 255); i = ycbcr->Y_tab[Y] + ycbcr->Cr_r_tab[Cr]; - *r = CLAMP(i, 0, 255); + *r = (uint32_t)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); + ((ycbcr->Cb_g_tab[Cb] + ycbcr->Cr_g_tab[Cr]) >> SHIFT); + *g = (uint32_t)CLAMP(i, 0, 255); i = ycbcr->Y_tab[Y] + ycbcr->Cb_b_tab[Cb]; - *b = CLAMP(i, 0, 255); + *b = (uint32_t)CLAMP(i, 0, 255); } /* Clamp function for sanitization purposes. Normally clamping should not */ @@ -258,8 +258,7 @@ int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *ycbcr, float *luma, float *refBlackWhite) #define LumaBlue luma[2] clamptab = - (TIFFRGBValue *)((uint8_t *)ycbcr + - TIFFroundup_32(sizeof(TIFFYCbCrToRGB), sizeof(long))); + (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++) @@ -273,13 +272,13 @@ int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *ycbcr, float *luma, float *refBlackWhite) { float f1 = 2 - 2 * LumaRed; - int32_t D1 = FIX(CLAMP(f1, 0.0F, 2.0F)); + 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)); + 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)); + 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)); + int32_t D4 = -FIX(CLAMP(f4, 0.0f, 2.0f)); int x; #undef LumaBlue @@ -295,12 +294,12 @@ int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *ycbcr, float *luma, float *refBlackWhite) */ 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); + 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); @@ -308,7 +307,7 @@ int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *ycbcr, float *luma, float *refBlackWhite) 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); + -128.0f * 32, 128.0f * 32); } } diff --git a/3rdparty/libtiff/tif_compress.c b/3rdparty/libtiff/tif_compress.c index c6e17d3e11..3002083f12 100644 --- a/3rdparty/libtiff/tif_compress.c +++ b/3rdparty/libtiff/tif_compress.c @@ -139,6 +139,18 @@ static int _TIFFtrue(TIFF *tif) } static void _TIFFvoid(TIFF *tif) { (void)tif; } +static uint64_t _TIFFDefaultGetMaxCompressionRatio(TIFF *tif) +{ + (void)tif; + return 0; /* unknown */ +} + +static uint64_t _TIFFGetMaxCompressionRatioOne(TIFF *tif) +{ + (void)tif; + return 1; /* no compression */ +} + void _TIFFSetDefaultCompressionState(TIFF *tif) { tif->tif_fixuptags = _TIFFNoFixupTags; @@ -160,6 +172,7 @@ void _TIFFSetDefaultCompressionState(TIFF *tif) tif->tif_cleanup = _TIFFvoid; tif->tif_defstripsize = _TIFFDefaultStripSize; tif->tif_deftilesize = _TIFFDefaultTileSize; + tif->tif_getmaxcompressionratio = _TIFFDefaultGetMaxCompressionRatio; tif->tif_flags &= ~(TIFF_NOBITREV | TIFF_NOREADRAW); } @@ -168,6 +181,8 @@ int TIFFSetCompressionScheme(TIFF *tif, int scheme) const TIFFCodec *c = TIFFFindCODEC((uint16_t)scheme); _TIFFSetDefaultCompressionState(tif); + if (scheme == COMPRESSION_NONE) + tif->tif_getmaxcompressionratio = _TIFFGetMaxCompressionRatioOne; /* * Don't treat an unknown compression scheme as an error. * This permits applications to open files with data that @@ -177,6 +192,13 @@ int TIFFSetCompressionScheme(TIFF *tif, int scheme) return (c ? (*c->init)(tif, scheme) : 1); } +uint64_t TIFFGetMaxCompressionRatio(TIFF *tif) +{ + if (tif->tif_getmaxcompressionratio) + return tif->tif_getmaxcompressionratio(tif); + return 0; +} + /* * Other compression schemes may be registered. Registered * schemes can also override the builtin versions provided @@ -200,7 +222,7 @@ const TIFFCodec *TIFFFindCODEC(uint16_t scheme) for (c = _TIFFBuiltinCODECS; c->name; c++) if (c->scheme == scheme) return (c); - return ((const TIFFCodec *)0); + return NULL; } TIFFCodec *TIFFRegisterCODEC(uint16_t scheme, const char *name, @@ -212,9 +234,11 @@ TIFFCodec *TIFFRegisterCODEC(uint16_t scheme, const char *name, if (cd != NULL) { + char *codec_name; cd->info = (TIFFCodec *)((uint8_t *)cd + sizeof(codec_t)); - cd->info->name = (char *)((uint8_t *)cd->info + sizeof(TIFFCodec)); - strcpy(cd->info->name, name); + codec_name = (char *)((uint8_t *)cd->info + sizeof(TIFFCodec)); + strcpy(codec_name, name); + cd->info->name = codec_name; cd->info->scheme = scheme; cd->info->init = init; cd->next = registeredCODECS; @@ -247,7 +271,7 @@ void TIFFUnRegisterCODEC(TIFFCodec *c) } /************************************************************************/ -/* TIFFGetConfisuredCODECs() */ +/* TIFFGetConfiguredCODECs() */ /************************************************************************/ /** @@ -258,7 +282,7 @@ void TIFFUnRegisterCODEC(TIFFCodec *c) * or NULL if function failed. */ -TIFFCodec *TIFFGetConfiguredCODECs() +TIFFCodec *TIFFGetConfiguredCODECs(void) { int i = 1; codec_t *cd; @@ -268,8 +292,8 @@ TIFFCodec *TIFFGetConfiguredCODECs() for (cd = registeredCODECS; cd; cd = cd->next) { - new_codecs = - (TIFFCodec *)_TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec)); + new_codecs = (TIFFCodec *)_TIFFreallocExt( + NULL, codecs, (tmsize_t)((size_t)i * sizeof(TIFFCodec))); if (!new_codecs) { _TIFFfreeExt(NULL, codecs); @@ -283,21 +307,21 @@ TIFFCodec *TIFFGetConfiguredCODECs() { if (TIFFIsCODECConfigured(c->scheme)) { - new_codecs = (TIFFCodec *)_TIFFreallocExt(NULL, codecs, - i * sizeof(TIFFCodec)); + new_codecs = (TIFFCodec *)_TIFFreallocExt( + NULL, codecs, (tmsize_t)((size_t)i * sizeof(TIFFCodec))); if (!new_codecs) { _TIFFfreeExt(NULL, codecs); return NULL; } codecs = new_codecs; - _TIFFmemcpy(codecs + i - 1, (const void *)c, sizeof(TIFFCodec)); + _TIFFmemcpy(codecs + i - 1, c, sizeof(TIFFCodec)); i++; } } - new_codecs = - (TIFFCodec *)_TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec)); + new_codecs = (TIFFCodec *)_TIFFreallocExt( + NULL, codecs, (tmsize_t)((size_t)i * sizeof(TIFFCodec))); if (!new_codecs) { _TIFFfreeExt(NULL, codecs); diff --git a/3rdparty/libtiff/tif_dir.c b/3rdparty/libtiff/tif_dir.c index 7421c738db..999a2452f3 100644 --- a/3rdparty/libtiff/tif_dir.c +++ b/3rdparty/libtiff/tif_dir.c @@ -31,6 +31,7 @@ #include "tiffiop.h" #include /*--: for Rational2Double */ #include +#include /* * These are used in the backwards compatibility code... @@ -50,7 +51,8 @@ static void setByteArray(TIFF *tif, void **vpp, const void *vp, size_t nmemb, } if (vp) { - tmsize_t bytes = _TIFFMultiplySSize(NULL, nmemb, elem_size, NULL); + tmsize_t bytes = _TIFFMultiplySSize(NULL, (tmsize_t)nmemb, + (tmsize_t)elem_size, NULL); if (bytes) *vpp = (void *)_TIFFmallocExt(tif, bytes); if (*vpp) @@ -121,7 +123,8 @@ static void setDoubleArrayOneValue(TIFF *tif, double **vpp, double value, { if (*vpp) _TIFFfreeExt(tif, *vpp); - *vpp = _TIFFmallocExt(tif, nmemb * sizeof(double)); + *vpp = (double *)_TIFFmallocExt(tif, + (tmsize_t)nmemb * (tmsize_t)sizeof(double)); if (*vpp) { while (nmemb--) @@ -294,7 +297,7 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap) /* * Setup new compression routine state. */ - if ((status = TIFFSetCompressionScheme(tif, v)) != 0) + if ((status = TIFFSetCompressionScheme(tif, (int)v)) != 0) td->td_compression = (uint16_t)v; else status = 0; @@ -402,13 +405,13 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap) break; case TIFFTAG_XRESOLUTION: dblval = va_arg(ap, double); - if (dblval != dblval || dblval < 0) + if (isnan(dblval) || dblval < 0) goto badvaluedouble; td->td_xresolution = _TIFFClampDoubleToFloat(dblval); break; case TIFFTAG_YRESOLUTION: dblval = va_arg(ap, double); - if (dblval != dblval || dblval < 0) + if (isnan(dblval) || dblval < 0) goto badvaluedouble; td->td_yresolution = _TIFFClampDoubleToFloat(dblval); break; @@ -439,7 +442,12 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap) td->td_halftonehints[1] = (uint16_t)va_arg(ap, uint16_vap); break; case TIFFTAG_COLORMAP: - v32 = (uint32_t)(1L << td->td_bitspersample); + if (td->td_bitspersample >= 32) + { + v = td->td_bitspersample; + goto badvalue; + } + v32 = 1U << td->td_bitspersample; _TIFFsetShortArrayExt(tif, &td->td_colormap[0], va_arg(ap, uint16_t *), v32); _TIFFsetShortArrayExt(tif, &td->td_colormap[1], @@ -557,11 +565,17 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap) case TIFFTAG_TRANSFERFUNCTION: { uint32_t i; + uint32_t count; + if (td->td_bitspersample >= 32) + { + v = td->td_bitspersample; + goto badvalue; + } + count = 1U << td->td_bitspersample; 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); + va_arg(ap, uint16_t *), count); break; } case TIFFTAG_REFERENCEBLACKWHITE: @@ -579,7 +593,7 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap) if (ninksinstring > 0) { _TIFFsetNString(tif, &td->td_inknames, s, v); - td->td_inknameslen = v; + td->td_inknameslen = (int)v; /* Set NumberOfInks to the value ninksinstring */ if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS)) { @@ -725,7 +739,8 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap) new_customValues = (TIFFTagValue *)_TIFFreallocExt( tif, td->td_customValues, - sizeof(TIFFTagValue) * (td->td_customValueCount + 1)); + (tmsize_t)(sizeof(TIFFTagValue) * + (size_t)(td->td_customValueCount + 1))); if (!new_customValues) { TIFFErrorExtR(tif, module, @@ -754,7 +769,7 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap) if (tv_size == 0) { status = 0; - TIFFErrorExtR(tif, module, "%s: Bad field type %d for \"%s\"", + TIFFErrorExtR(tif, module, "%s: Bad field type %u for \"%s\"", tif->tif_name, fip->field_type, fip->field_name); goto end; } @@ -784,7 +799,7 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap) } ma = (uint32_t)len; } - tv->count = ma; + tv->count = (int)ma; setByteArray(tif, &tv->value, mb, ma, 1); } else @@ -792,9 +807,9 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap) if (fip->field_passcount) { if (fip->field_writecount == TIFF_VARIABLE2) - tv->count = (uint32_t)va_arg(ap, uint32_t); + tv->count = (int)va_arg(ap, uint32_t); else - tv->count = (int)va_arg(ap, int); + tv->count = va_arg(ap, int); } else if (fip->field_writecount == TIFF_VARIABLE || fip->field_writecount == TIFF_VARIABLE2) @@ -808,7 +823,7 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap) { TIFFWarningExtR(tif, module, "%s: Null count for \"%s\" (type " - "%d, writecount %d, passcount %d)", + "%u, writecount %d, passcount %d)", tif->tif_name, fip->field_name, fip->field_type, fip->field_writecount, fip->field_passcount); @@ -845,11 +860,12 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap) * 4 or 8 according to fip->set_get_field_type! */ _TIFFmemcpy(tv->value, va_arg(ap, void *), tv->count * tv_size); - /* Test here for too big values for LONG8, SLONG8 in + /* Test here for too big values for LONG8, IFD8, SLONG8 in * ClassicTIFF and delete custom field from custom list */ if (!(tif->tif_flags & TIFF_BIGTIFF)) { - if (tv->info->field_type == TIFF_LONG8) + if (tv->info->field_type == TIFF_LONG8 || + tv->info->field_type == TIFF_IFD8) { uint64_t *pui64 = (uint64_t *)tv->value; for (int i = 0; i < tv->count; i++) @@ -858,12 +874,15 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap) { TIFFErrorExtR( tif, module, - "%s: Bad LONG8 value %" PRIu64 + "%s: Bad %s value %" PRIu64 " at %d. array position for \"%s\" tag " - "%d in ClassicTIFF. Tag won't be " + "%u in ClassicTIFF. Tag won't be " "written to file", - tif->tif_name, pui64[i], i, - fip->field_name, tag); + tif->tif_name, + (tv->info->field_type == TIFF_LONG8 + ? "LONG8" + : "IFD8"), + pui64[i], i, fip->field_name, tag); goto badvalueifd8long8; } } @@ -880,7 +899,7 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap) tif, module, "%s: Bad SLONG8 value %" PRIi64 " at %d. array position for \"%s\" tag " - "%d in ClassicTIFF. Tag won't be " + "%u in ClassicTIFF. Tag won't be " "written to file", tif->tif_name, pi64[i], i, fip->field_name, tag); @@ -948,7 +967,7 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap) TIFFErrorExtR( tif, module, "%s: Bad LONG8 or IFD8 value %" PRIu64 - " for \"%s\" tag %d in ClassicTIFF. Tag " + " for \"%s\" tag %u in ClassicTIFF. Tag " "won't be written to file", tif->tif_name, v2, fip->field_name, tag); goto badvalueifd8long8; @@ -967,7 +986,7 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap) TIFFErrorExtR( tif, module, "%s: Bad SLONG8 value %" PRIi64 - " for \"%s\" tag %d in ClassicTIFF. Tag " + " for \"%s\" tag %u in ClassicTIFF. Tag " "won't be written to file", tif->tif_name, v2, fip->field_name, tag); goto badvalueifd8long8; @@ -1018,6 +1037,8 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap) _TIFFmemcpy(val, &v2, tv_size); } break; + case TIFF_NOTYPE: + case TIFF_ASCII: default: _TIFFmemset(val, 0, tv_size); status = 0; @@ -1345,7 +1366,7 @@ static int _TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap) break; case TIFFTAG_MATTEING: *va_arg(ap, uint16_t *) = - (td->td_extrasamples == 1 && + (td->td_extrasamples == 1 && td->td_sampleinfo && td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA); break; case TIFFTAG_EXTRASAMPLES: @@ -1376,6 +1397,8 @@ static int _TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap) case SAMPLEFORMAT_VOID: *va_arg(ap, uint16_t *) = DATATYPE_VOID; break; + default: + break; } break; case TIFFTAG_SAMPLEFORMAT: @@ -1562,6 +1585,8 @@ static int _TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap) *va_arg(ap, double *) = *(double *)val; ret_val = 1; break; + case TIFF_NOTYPE: + case TIFF_ASCII: default: ret_val = 0; break; @@ -1613,6 +1638,21 @@ int TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap) } \ } +/* + * Reset tif->tif_dir structure to zero and + * initialize some IFD strile counter and index parameters. + */ +void _TIFFResetTifDirAndInitStrileCounters(TIFFDirectory *td) +{ + _TIFFmemset(td, 0, sizeof(*td)); + td->td_curstrip = NOSTRIP; /* invalid strip = NOSTRIP */ + td->td_row = (uint32_t)-1; /* read/write pre-increment */ + td->td_col = (uint32_t)-1; /* read/write pre-increment */ + td->td_scanlinesize = 0; /* initialize to zero */ + td->td_curtile = NOTILE; /* invalid tile = NOTILE */ + td->td_tilesize = (tmsize_t)-1; /* invalidate tilezize */ +} + /* * Release storage associated with a directory. */ @@ -1664,6 +1704,7 @@ void TIFFFreeDirectory(TIFF *tif) tif->tif_dir.td_dirdatasize_Noffsets = 0; } tif->tif_dir.td_iswrittentofile = FALSE; + /* Note: tif->tif_dir structure is set to zero in TIFFDefaultDirectory() */ } #undef CleanupField @@ -1694,10 +1735,7 @@ int TIFFCreateDirectory(TIFF *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; tif->tif_dir.td_iswrittentofile = FALSE; - return 0; } @@ -1717,15 +1755,12 @@ int TIFFCreateCustomDirectory(TIFF *tif, const TIFFFieldArray *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; } @@ -1751,13 +1786,14 @@ int TIFFCreateGPSDirectory(TIFF *tif) */ int TIFFDefaultDirectory(TIFF *tif) { - register TIFFDirectory *td = &tif->tif_dir; + TIFFDirectory *td = &tif->tif_dir; const TIFFFieldArray *tiffFieldArray; tiffFieldArray = _TIFFGetFields(); _TIFFSetupFields(tif, tiffFieldArray); - - _TIFFmemset(td, 0, sizeof(*td)); + /* Reset tif->tif_dir structure to zero and + * initialize some IFD strile counter and index parameters. */ + _TIFFResetTifDirAndInitStrileCounters(td); td->td_fillorder = FILLORDER_MSB2LSB; td->td_bitspersample = 1; td->td_threshholding = THRESHHOLD_BILEVEL; @@ -1860,10 +1896,8 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off, 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)) + if (poff > (uint64_t)TIFF_TMSIZE_T_MAX - sizeof(uint16_t) || + poff > (uint64_t)tif->tif_size - sizeof(uint16_t)) { TIFFErrorExtR(tif, module, "%s:%d: %s: Error fetching directory count", @@ -1871,13 +1905,20 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off, *nextdiroff = 0; return (0); } + poffa = (tmsize_t)poff; + poffb = poffa + (tmsize_t)sizeof(uint16_t); _TIFFmemcpy(&dircount, tif->tif_base + poffa, sizeof(uint16_t)); if (tif->tif_flags & TIFF_SWAB) TIFFSwabShort(&dircount); + if (poffb > + TIFF_TMSIZE_T_MAX - dircount * 12 - (tmsize_t)sizeof(uint32_t)) + { + TIFFErrorExtR(tif, module, "Error fetching directory link"); + return (0); + } 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)) + poffd = poffc + (tmsize_t)sizeof(uint32_t); + if (poffd > tif->tif_size) { TIFFErrorExtR(tif, module, "Error fetching directory link"); return (0); @@ -1893,7 +1934,6 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off, { 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, @@ -1902,7 +1942,7 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off, return (0); } poffa = (tmsize_t)poff; - poffb = poffa + sizeof(uint64_t); + poffb = poffa + (tmsize_t)sizeof(uint64_t); if (poffb > tif->tif_size) { TIFFErrorExtR(tif, module, @@ -1919,15 +1959,14 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off, "Sanity check on directory count failed"); return (0); } - dircount16 = (uint16_t)dircount64; - if (poffb > TIFF_TMSIZE_T_MAX - (tmsize_t)(dircount16 * 20) - + if (poffb > TIFF_TMSIZE_T_MAX - (tmsize_t)(dircount64 * 20) - (tmsize_t)sizeof(uint64_t)) { TIFFErrorExtR(tif, module, "Error fetching directory link"); return (0); } - poffc = poffb + dircount16 * 20; - poffd = poffc + sizeof(uint64_t); + poffc = poffb + (tmsize_t)(dircount64 * 20); + poffd = poffc + (tmsize_t)sizeof(uint64_t); if (poffd > tif->tif_size) { TIFFErrorExtR(tif, module, "Error fetching directory link"); @@ -1957,9 +1996,9 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off, if (tif->tif_flags & TIFF_SWAB) TIFFSwabShort(&dircount); if (off != NULL) - *off = TIFFSeekFile(tif, dircount * 12, SEEK_CUR); + *off = TIFFSeekFile(tif, dircount * 12U, SEEK_CUR); else - (void)TIFFSeekFile(tif, dircount * 12, SEEK_CUR); + (void)TIFFSeekFile(tif, dircount * 12U, SEEK_CUR); if (!ReadOK(tif, &nextdir32, sizeof(uint32_t))) { TIFFErrorExtR(tif, module, "%s: Error fetching directory link", @@ -1973,7 +2012,6 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off, else { uint64_t dircount64; - uint16_t dircount16; if (!SeekOK(tif, *nextdiroff) || !ReadOK(tif, &dircount64, sizeof(uint64_t))) { @@ -1991,11 +2029,10 @@ static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off, __FILE__, __LINE__, tif->tif_name); return (0); } - dircount16 = (uint16_t)dircount64; if (off != NULL) - *off = TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR); + *off = TIFFSeekFile(tif, dircount64 * 20, SEEK_CUR); else - (void)TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR); + (void)TIFFSeekFile(tif, dircount64 * 20, SEEK_CUR); if (!ReadOK(tif, nextdiroff, sizeof(uint64_t))) { TIFFErrorExtR(tif, module, "%s: Error fetching directory link", @@ -2354,8 +2391,6 @@ int TIFFUnlinkDirectory(TIFF *tif, tdir_t dirn) 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; if (tif->tif_curdircount > 0) tif->tif_curdircount--; diff --git a/3rdparty/libtiff/tif_dir.h b/3rdparty/libtiff/tif_dir.h index 44270f7097..aed9722228 100644 --- a/3rdparty/libtiff/tif_dir.h +++ b/3rdparty/libtiff/tif_dir.h @@ -104,6 +104,16 @@ typedef struct uint16_t td_halftonehints[2]; uint16_t td_extrasamples; uint16_t *td_sampleinfo; + /* strip support */ + uint32_t td_row; /* current scanline */ + uint32_t td_curstrip; /* current strip for read/write */ + tmsize_t td_scanlinesize; /* # of bytes in a scanline */ +#define NOSTRIP ((uint32_t)(-1)) /* undefined state */ + /* tiling support */ + uint32_t td_col; /* current column (offset by row too) */ + uint32_t td_curtile; /* current tile for read/write */ + tmsize_t td_tilesize; /* # of bytes in a tile */ +#define NOTILE ((uint32_t)(-1)) /* undefined state */ /* 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 */ @@ -164,6 +174,8 @@ typedef struct entries. */ } TIFFDirectory; +extern void _TIFFResetTifDirAndInitStrileCounters(TIFFDirectory *td); + /* * Field flags used to indicate fields that have been set in a directory, and * to reference fields when manipulating a directory. @@ -231,7 +243,7 @@ typedef struct #define FIELD_LAST (32 * FIELDSET_ITEMS - 1) -#define BITn(n) (((uint32_t)1L) << ((n)&0x1f)) +#define BITn(n) (1U << ((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)) @@ -340,7 +352,7 @@ extern "C" 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 */ + const char *field_name; /* ASCII name */ TIFFFieldArray *field_subfields; /* if field points to child ifds, child ifd field definition array */ }; diff --git a/3rdparty/libtiff/tif_dirinfo.c b/3rdparty/libtiff/tif_dirinfo.c index c038497cf4..9218661b72 100644 --- a/3rdparty/libtiff/tif_dirinfo.c +++ b/3rdparty/libtiff/tif_dirinfo.c @@ -40,17 +40,47 @@ * values accordingly. */ -/* const object should be initialized */ -#ifdef _MSC_VER +/* Forward declarations - definition follows after field arrays. + * Note: In C, we can forward declare static const objects and define them + * later. In C++, we need extern for the declaration, then define without + * extern. Since these are only used within this file via pointers, we use a + * workaround that works in both C and C++: declare as extern here, define as + * static later, but actually we need a different approach for C++ + * compatibility. + * + * For C/C++ compatibility, we define a simple struct that holds the pointer + * and initialize it after the arrays are defined. + */ +#ifdef __cplusplus +/* C++ doesn't allow forward declaration of const objects, so we use extern */ +extern const TIFFFieldArray tiffFieldArray; +extern const TIFFFieldArray exifFieldArray; +extern const TIFFFieldArray gpsFieldArray; +#else +/* C allows forward declaration of const objects, but C++ doesn't. + * We disable the C++-compat warning for this section since these circular + * dependencies are unavoidable with static initialization. */ +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++-compat" +#elif defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wc++-compat" +#elif defined(_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 +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#elif defined(__clang__) +#pragma clang diagnostic pop +#elif defined(_MSC_VER) #pragma warning(pop) #endif +#endif /*--: Rational2Double: -- * The Rational2Double upgraded libtiff functionality allows the definition and * achievement of true double-precision accuracy for TIFF tags of RATIONAL type @@ -152,9 +182,9 @@ static const TIFFField tiffFields[] = { /*--: 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, FIELD_CUSTOM, 1, 0, "EXIFIFDOffset", (TIFFFieldArray *)&exifFieldArray}, + {TIFFTAG_EXIFIFD, 1, 1, TIFF_LONG8, 0, TIFF_SETGET_UINT64, FIELD_CUSTOM, 1, 0, "EXIFIFDOffset", (TIFFFieldArray *)&exifFieldArray}, {TIFFTAG_ICCPROFILE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, FIELD_CUSTOM, 1, 1, "ICC Profile", NULL}, - {TIFFTAG_GPSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, FIELD_CUSTOM, 1, 0, "GPSIFDOffset", (TIFFFieldArray *)&gpsFieldArray}, + {TIFFTAG_GPSIFD, 1, 1, TIFF_LONG8, 0, TIFF_SETGET_UINT64, FIELD_CUSTOM, 1, 0, "GPSIFDOffset", (TIFFFieldArray *)&gpsFieldArray}, {TIFFTAG_FAXRECVPARAMS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvParams", NULL}, {TIFFTAG_FAXSUBADDRESS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxSubAddress", NULL}, {TIFFTAG_FAXRECVTIME, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvTime", NULL}, @@ -479,12 +509,36 @@ static const TIFFField gpsFields[] = { {GPSTAG_GPSHPOSITIONINGERROR, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, FIELD_CUSTOM, 1, 0, "HorizontalPositioningError", NULL}}; /* clang-format on */ /* was off for better readability of tag comments */ +#ifdef __cplusplus +/* In C++, the forward declaration used extern, so definitions must not be + * static */ +const TIFFFieldArray tiffFieldArray = { + tfiatImage, 0, TIFFArrayCount(tiffFields), (TIFFField *)tiffFields}; +const TIFFFieldArray exifFieldArray = {tfiatExif, 0, TIFFArrayCount(exifFields), + (TIFFField *)exifFields}; +const TIFFFieldArray gpsFieldArray = {tfiatGps, 0, TIFFArrayCount(gpsFields), + (TIFFField *)gpsFields}; +#else +/* Suppress C++-compat warning for the definitions as well */ +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++-compat" +#elif defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wc++-compat" +#endif 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}; +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#elif defined(__clang__) +#pragma clang diagnostic pop +#endif +#endif /* * We have our own local lfind() equivalent to avoid subtle differences @@ -523,7 +577,7 @@ void _TIFFSetupFields(TIFF *tif, const TIFFFieldArray *fieldarray) { if (fld->field_bit == FIELD_CUSTOM && TIFFFieldIsAnonymous(fld)) { - _TIFFfreeExt(tif, fld->field_name); + _TIFFfreeExt(tif, (void *)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(). @@ -579,22 +633,26 @@ int _TIFFMergeFields(TIFF *tif, const TIFFField info[], uint32_t n) tif->tif_foundfield = NULL; + TIFFField **tif_newfields = 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); + tif_newfields = (TIFFField **)_TIFFCheckRealloc( + tif, tif->tif_fields, (tmsize_t)tif->tif_nfields + n, + (tmsize_t)sizeof(TIFFField *), reason); } else { - tif->tif_fields = + tif_newfields = (TIFFField **)_TIFFCheckMalloc(tif, n, sizeof(TIFFField *), reason); } - if (!tif->tif_fields) + if (!tif_newfields) { + tif->tif_nfields = 0; TIFFErrorExtR(tif, module, "Failed to allocate fields array"); return 0; } + tif->tif_fields = tif_newfields; /* tp = tif->tif_fields + tif->tif_nfields; */ for (i = 0; i < n; i++) @@ -612,7 +670,7 @@ int _TIFFMergeFields(TIFF *tif, const TIFFField info[], uint32_t n) /* Sort the field info by tag number */ qsort(tif->tif_fields, tif->tif_nfields, sizeof(TIFFField *), tagCompare); - return n; + return (int)n; } void _TIFFPrintFieldInfo(TIFF *tif, FILE *fd) @@ -623,7 +681,7 @@ void _TIFFPrintFieldInfo(TIFF *tif, FILE *fd) 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", + fprintf(fd, "field[%2d] %5lu, %2d, %2d, %u, %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", @@ -787,6 +845,34 @@ int TIFFFieldSetGetCountSize(const TIFFField *fip) case TIFF_SETGET_C32_DOUBLE: case TIFF_SETGET_C32_IFD8: return 4; + case TIFF_SETGET_UNDEFINED: + case TIFF_SETGET_ASCII: + case TIFF_SETGET_UINT8: + case TIFF_SETGET_SINT8: + case TIFF_SETGET_UINT16: + case TIFF_SETGET_SINT16: + case TIFF_SETGET_UINT32: + case TIFF_SETGET_SINT32: + case TIFF_SETGET_UINT64: + case TIFF_SETGET_SINT64: + case TIFF_SETGET_FLOAT: + case TIFF_SETGET_DOUBLE: + case TIFF_SETGET_IFD8: + case TIFF_SETGET_INT: + case TIFF_SETGET_UINT16_PAIR: + case TIFF_SETGET_C0_ASCII: + case TIFF_SETGET_C0_UINT8: + case TIFF_SETGET_C0_SINT8: + case TIFF_SETGET_C0_UINT16: + case TIFF_SETGET_C0_SINT16: + case TIFF_SETGET_C0_UINT32: + case TIFF_SETGET_C0_SINT32: + case TIFF_SETGET_C0_UINT64: + case TIFF_SETGET_C0_SINT64: + case TIFF_SETGET_C0_FLOAT: + case TIFF_SETGET_C0_DOUBLE: + case TIFF_SETGET_C0_IFD8: + case TIFF_SETGET_OTHER: default: return 0; } @@ -794,7 +880,8 @@ int TIFFFieldSetGetCountSize(const TIFFField *fip) const TIFFField *TIFFFindField(TIFF *tif, uint32_t tag, TIFFDataType dt) { - TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, NULL, NULL}; + TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, TIFF_SETGET_UNDEFINED, + 0, 0, 0, NULL, NULL}; TIFFField *pkey = &key; const TIFFField **ret; if (tif->tif_foundfield && tif->tif_foundfield->field_tag == tag && @@ -818,7 +905,8 @@ const TIFFField *TIFFFindField(TIFF *tif, uint32_t tag, TIFFDataType dt) static const TIFFField *_TIFFFindFieldByName(TIFF *tif, const char *field_name, TIFFDataType dt) { - TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, NULL, NULL}; + TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, TIFF_SETGET_UNDEFINED, + 0, 0, 0, NULL, NULL}; TIFFField *pkey = &key; const TIFFField **ret; if (tif->tif_foundfield && @@ -876,7 +964,10 @@ 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; } +int TIFFFieldIsAnonymous(const TIFFField *fip) +{ + return (int)fip->field_anonymous; +} const TIFFField *_TIFFFindOrRegisterField(TIFF *tif, uint32_t tag, TIFFDataType dt) @@ -954,6 +1045,7 @@ TIFFField *_TIFFCreateAnonField(TIFF *tif, uint32_t tag, case TIFF_SLONG8: fld->set_get_field_type = TIFF_SETGET_C32_SINT64; break; + case TIFF_NOTYPE: default: fld->set_get_field_type = TIFF_SETGET_UNDEFINED; break; @@ -961,8 +1053,8 @@ TIFFField *_TIFFCreateAnonField(TIFF *tif, uint32_t tag, 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) + char *field_name_buf = (char *)_TIFFmallocExt(tif, 32); + if (field_name_buf == NULL) { _TIFFfreeExt(tif, fld); return NULL; @@ -975,7 +1067,8 @@ TIFFField *_TIFFCreateAnonField(TIFF *tif, uint32_t tag, * Update: * This special sign is replaced by fld->field_anonymous flag. */ - (void)snprintf(fld->field_name, 32, "Tag %d", (int)tag); + (void)snprintf(field_name_buf, 32, "Tag %d", (int)tag); + fld->field_name = field_name_buf; return fld; } @@ -1025,6 +1118,7 @@ static TIFFSetGetFieldType _TIFFSetGetType(TIFFDataType type, short count, return TIFF_SETGET_UINT64; case TIFF_SLONG8: return TIFF_SETGET_SINT64; + case TIFF_NOTYPE: default: return TIFF_SETGET_UNDEFINED; } @@ -1062,6 +1156,7 @@ static TIFFSetGetFieldType _TIFFSetGetType(TIFFDataType type, short count, return TIFF_SETGET_C0_UINT64; case TIFF_SLONG8: return TIFF_SETGET_C0_SINT64; + case TIFF_NOTYPE: default: return TIFF_SETGET_UNDEFINED; } @@ -1099,6 +1194,7 @@ static TIFFSetGetFieldType _TIFFSetGetType(TIFFDataType type, short count, return TIFF_SETGET_C16_UINT64; case TIFF_SLONG8: return TIFF_SETGET_C16_SINT64; + case TIFF_NOTYPE: default: return TIFF_SETGET_UNDEFINED; } @@ -1136,6 +1232,7 @@ static TIFFSetGetFieldType _TIFFSetGetType(TIFFDataType type, short count, return TIFF_SETGET_C32_UINT64; case TIFF_SLONG8: return TIFF_SETGET_C32_SINT64; + case TIFF_NOTYPE: default: return TIFF_SETGET_UNDEFINED; } @@ -1152,22 +1249,25 @@ int TIFFMergeFieldInfo(TIFF *tif, const TIFFFieldInfo info[], uint32_t n) size_t nfields; uint32_t i; + TIFFFieldArray *tif_newfieldscompat = NULL; + if (tif->tif_nfieldscompat > 0) { - tif->tif_fieldscompat = (TIFFFieldArray *)_TIFFCheckRealloc( - tif, tif->tif_fieldscompat, tif->tif_nfieldscompat + 1, - sizeof(TIFFFieldArray), reason); + tif_newfieldscompat = (TIFFFieldArray *)_TIFFCheckRealloc( + tif, tif->tif_fieldscompat, (tmsize_t)tif->tif_nfieldscompat + 1, + (tmsize_t)sizeof(TIFFFieldArray), reason); } else { - tif->tif_fieldscompat = (TIFFFieldArray *)_TIFFCheckMalloc( + tif_newfieldscompat = (TIFFFieldArray *)_TIFFCheckMalloc( tif, 1, sizeof(TIFFFieldArray), reason); } - if (!tif->tif_fieldscompat) + if (!tif_newfieldscompat) { TIFFErrorExtR(tif, module, "Failed to allocate fields array"); return -1; } + tif->tif_fieldscompat = tif_newfieldscompat; nfields = tif->tif_nfieldscompat++; tif->tif_fieldscompat[nfields].type = tfiatOther; @@ -1309,6 +1409,8 @@ int _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag) case TIFFTAG_JPEGPROC: case TIFFTAG_JPEGRESTARTINTERVAL: return 1; + default: + break; } break; case COMPRESSION_CCITTRLE: @@ -1329,6 +1431,8 @@ int _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag) if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) return 1; break; + default: + break; } break; case COMPRESSION_JBIG: @@ -1359,6 +1463,8 @@ int _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag) if (tag == TIFFTAG_LERC_PARAMETERS) return 1; break; + default: + break; } return 0; } diff --git a/3rdparty/libtiff/tif_dirread.c b/3rdparty/libtiff/tif_dirread.c index 7f0aeb1544..806b56f12b 100644 --- a/3rdparty/libtiff/tif_dirread.c +++ b/3rdparty/libtiff/tif_dirread.c @@ -597,7 +597,7 @@ TIFFReadDirEntrySshort(TIFF *tif, TIFFDirEntry *direntry, int16_t *value) err = TIFFReadDirEntryCheckRangeSshortShort(m); if (err != TIFFReadDirEntryErrOk) return (err); - *value = (uint16_t)m; + *value = (int16_t)m; return (TIFFReadDirEntryErrOk); } case TIFF_SSHORT: @@ -695,6 +695,7 @@ TIFFReadDirEntryLong(TIFF *tif, TIFFDirEntry *direntry, uint32_t *value) return (TIFFReadDirEntryErrOk); } case TIFF_LONG: + case TIFF_IFD: TIFFReadDirEntryCheckedLong(tif, direntry, value); return (TIFFReadDirEntryErrOk); case TIFF_SLONG: @@ -708,6 +709,7 @@ TIFFReadDirEntryLong(TIFF *tif, TIFFDirEntry *direntry, uint32_t *value) return (TIFFReadDirEntryErrOk); } case TIFF_LONG8: + case TIFF_IFD8: { uint64_t m; err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); @@ -857,6 +859,7 @@ TIFFReadDirEntryLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value) return (TIFFReadDirEntryErrOk); } case TIFF_LONG: + case TIFF_IFD: { uint32_t m; TIFFReadDirEntryCheckedLong(tif, direntry, &m); @@ -874,6 +877,7 @@ TIFFReadDirEntryLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value) return (TIFFReadDirEntryErrOk); } case TIFF_LONG8: + case TIFF_IFD8: err = TIFFReadDirEntryCheckedLong8(tif, direntry, value); return (err); case TIFF_SLONG8: @@ -1058,7 +1062,7 @@ TIFFReadDirEntryFloat(TIFF *tif, TIFFDirEntry *direntry, float *value) err = TIFFReadDirEntryCheckedDouble(tif, direntry, &m); if (err != TIFFReadDirEntryErrOk) return (err); - if ((m > FLT_MAX) || (m < -FLT_MAX)) + if ((m > (double)FLT_MAX) || (m < -(double)FLT_MAX)) return (TIFFReadDirEntryErrRange); *value = (float)m; return (TIFFReadDirEntryErrOk); @@ -1237,6 +1241,8 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryDataAndRealloc(TIFF *tif, *pdest = new_dest; bytes_read = TIFFReadFile(tif, (char *)*pdest + already_read, to_read); + if (bytes_read < 0) + return TIFFReadDirEntryErrIo; already_read += bytes_read; if (bytes_read != to_read) { @@ -1260,7 +1266,7 @@ TIFFReadDirEntryArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry, void *data; uint64_t target_count64; int original_datasize_clamped; - typesize = TIFFDataWidth(direntry->tdir_type); + typesize = TIFFDataWidth((TIFFDataType)direntry->tdir_type); target_count64 = (direntry->tdir_count > maxcount) ? maxcount : direntry->tdir_count; @@ -1284,13 +1290,13 @@ TIFFReadDirEntryArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry, * 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) + if ((uint64_t)(MAX_SIZE_TAG_DATA / (unsigned int)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; + datasize = (uint32_t)(*count) * (unsigned int)typesize; assert((tmsize_t)datasize > 0); if (datasize > 100 * 1024 * 1024) @@ -1440,6 +1446,8 @@ TIFFReadDirEntryByteArray(TIFF *tif, TIFFDirEntry *direntry, uint8_t **value) *value = (uint8_t *)origdata; return (TIFFReadDirEntryErrOk); } + default: + break; } data = (uint8_t *)_TIFFmallocExt(tif, count); if (data == 0) @@ -1557,6 +1565,8 @@ TIFFReadDirEntryByteArray(TIFF *tif, TIFFDirEntry *direntry, uint8_t **value) } } break; + default: + break; } _TIFFfreeExt(tif, origdata); if (err != TIFFReadDirEntryErrOk) @@ -1620,6 +1630,8 @@ TIFFReadDirEntrySbyteArray(TIFF *tif, TIFFDirEntry *direntry, int8_t **value) case TIFF_SBYTE: *value = (int8_t *)origdata; return (TIFFReadDirEntryErrOk); + default: + break; } data = (int8_t *)_TIFFmallocExt(tif, count); if (data == 0) @@ -1737,6 +1749,8 @@ TIFFReadDirEntrySbyteArray(TIFF *tif, TIFFDirEntry *direntry, int8_t **value) } } break; + default: + break; } _TIFFfreeExt(tif, origdata); if (err != TIFFReadDirEntryErrOk) @@ -1802,6 +1816,8 @@ TIFFReadDirEntryShortArray(TIFF *tif, TIFFDirEntry *direntry, uint16_t **value) *value = (uint16_t *)origdata; return (TIFFReadDirEntryErrOk); } + default: + break; } data = (uint16_t *)_TIFFmallocExt(tif, count * 2); if (data == 0) @@ -1910,6 +1926,8 @@ TIFFReadDirEntryShortArray(TIFF *tif, TIFFDirEntry *direntry, uint16_t **value) } } break; + default: + break; } _TIFFfreeExt(tif, origdata); if (err != TIFFReadDirEntryErrOk) @@ -1975,6 +1993,8 @@ TIFFReadDirEntrySshortArray(TIFF *tif, TIFFDirEntry *direntry, int16_t **value) if (tif->tif_flags & TIFF_SWAB) TIFFSwabArrayOfShort((uint16_t *)(*value), count); return (TIFFReadDirEntryErrOk); + default: + break; } data = (int16_t *)_TIFFmallocExt(tif, count * 2); if (data == 0) @@ -2078,6 +2098,8 @@ TIFFReadDirEntrySshortArray(TIFF *tif, TIFFDirEntry *direntry, int16_t **value) } } break; + default: + break; } _TIFFfreeExt(tif, origdata); if (err != TIFFReadDirEntryErrOk) @@ -2106,6 +2128,8 @@ TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value) case TIFF_SLONG: case TIFF_LONG8: case TIFF_SLONG8: + case TIFF_IFD: + case TIFF_IFD8: break; default: return (TIFFReadDirEntryErrType); @@ -2119,6 +2143,7 @@ TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value) switch (direntry->tdir_type) { case TIFF_LONG: + case TIFF_IFD: *value = (uint32_t *)origdata; if (tif->tif_flags & TIFF_SWAB) TIFFSwabArrayOfLong(*value, count); @@ -2143,6 +2168,8 @@ TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value) *value = (uint32_t *)origdata; return (TIFFReadDirEntryErrOk); } + default: + break; } data = (uint32_t *)_TIFFmallocExt(tif, count * 4); if (data == 0) @@ -2213,6 +2240,7 @@ TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value) } break; case TIFF_LONG8: + case TIFF_IFD8: { uint64_t *ma; uint32_t *mb; @@ -2248,6 +2276,8 @@ TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value) } } break; + default: + break; } _TIFFfreeExt(tif, origdata); if (err != TIFFReadDirEntryErrOk) @@ -2313,6 +2343,8 @@ TIFFReadDirEntrySlongArray(TIFF *tif, TIFFDirEntry *direntry, int32_t **value) if (tif->tif_flags & TIFF_SWAB) TIFFSwabArrayOfLong((uint32_t *)(*value), count); return (TIFFReadDirEntryErrOk); + default: + break; } data = (int32_t *)_TIFFmallocExt(tif, count * 4); if (data == 0) @@ -2410,6 +2442,8 @@ TIFFReadDirEntrySlongArray(TIFF *tif, TIFFDirEntry *direntry, int32_t **value) } } break; + default: + break; } _TIFFfreeExt(tif, origdata); if (err != TIFFReadDirEntryErrOk) @@ -2439,6 +2473,8 @@ TIFFReadDirEntryLong8ArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry, case TIFF_SLONG: case TIFF_LONG8: case TIFF_SLONG8: + case TIFF_IFD: + case TIFF_IFD8: break; default: return (TIFFReadDirEntryErrType); @@ -2453,6 +2489,7 @@ TIFFReadDirEntryLong8ArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry, switch (direntry->tdir_type) { case TIFF_LONG8: + case TIFF_IFD8: *value = (uint64_t *)origdata; if (tif->tif_flags & TIFF_SWAB) TIFFSwabArrayOfLong8(*value, count); @@ -2477,6 +2514,8 @@ TIFFReadDirEntryLong8ArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry, *value = (uint64_t *)origdata; return (TIFFReadDirEntryErrOk); } + default: + break; } data = (uint64_t *)_TIFFmallocExt(tif, count * 8); if (data == 0) @@ -2547,6 +2586,7 @@ TIFFReadDirEntryLong8ArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry, } break; case TIFF_LONG: + case TIFF_IFD: { uint32_t *ma; uint64_t *mb; @@ -2579,6 +2619,8 @@ TIFFReadDirEntryLong8ArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry, } } break; + default: + break; } _TIFFfreeExt(tif, origdata); if (err != TIFFReadDirEntryErrOk) @@ -2651,6 +2693,8 @@ TIFFReadDirEntrySlong8Array(TIFF *tif, TIFFDirEntry *direntry, int64_t **value) if (tif->tif_flags & TIFF_SWAB) TIFFSwabArrayOfLong8((uint64_t *)(*value), count); return (TIFFReadDirEntryErrOk); + default: + break; } data = (int64_t *)_TIFFmallocExt(tif, count * 8); if (data == 0) @@ -2742,6 +2786,8 @@ TIFFReadDirEntrySlong8Array(TIFF *tif, TIFFDirEntry *direntry, int64_t **value) } } break; + default: + break; } _TIFFfreeExt(tif, origdata); *value = data; @@ -2787,8 +2833,11 @@ TIFFReadDirEntryFloatArray(TIFF *tif, TIFFDirEntry *direntry, float **value) TIFFCvtIEEEFloatToNative(tif, count, (float *)origdata); *value = (float *)origdata; return (TIFFReadDirEntryErrOk); + default: + break; } - data = (float *)_TIFFmallocExt(tif, count * sizeof(float)); + data = + (float *)_TIFFmallocExt(tif, (tmsize_t)((size_t)count * sizeof(float))); if (data == 0) { _TIFFfreeExt(tif, origdata); @@ -2970,14 +3019,16 @@ TIFFReadDirEntryFloatArray(TIFF *tif, TIFFDirEntry *direntry, float **value) for (n = 0; n < count; n++) { double val = *ma++; - if (val > FLT_MAX) - val = FLT_MAX; - else if (val < -FLT_MAX) - val = -FLT_MAX; + if (val > (double)FLT_MAX) + val = (double)FLT_MAX; + else if (val < -(double)FLT_MAX) + val = -(double)FLT_MAX; *mb++ = (float)val; } } break; + default: + break; } _TIFFfreeExt(tif, origdata); *value = data; @@ -3023,8 +3074,11 @@ TIFFReadDirEntryDoubleArray(TIFF *tif, TIFFDirEntry *direntry, double **value) TIFFCvtIEEEDoubleToNative(tif, count, (double *)origdata); *value = (double *)origdata; return (TIFFReadDirEntryErrOk); + default: + break; } - data = (double *)_TIFFmallocExt(tif, count * sizeof(double)); + data = (double *)_TIFFmallocExt(tif, + (tmsize_t)((size_t)count * sizeof(double))); if (data == 0) { _TIFFfreeExt(tif, origdata); @@ -3207,6 +3261,8 @@ TIFFReadDirEntryDoubleArray(TIFF *tif, TIFFDirEntry *direntry, double **value) *mb++ = (double)(*ma++); } break; + default: + break; } _TIFFfreeExt(tif, origdata); *value = data; @@ -3244,6 +3300,8 @@ TIFFReadDirEntryIfd8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value) if (tif->tif_flags & TIFF_SWAB) TIFFSwabArrayOfLong8(*value, count); return (TIFFReadDirEntryErrOk); + default: + break; } data = (uint64_t *)_TIFFmallocExt(tif, count * 8); if (data == 0) @@ -3269,6 +3327,8 @@ TIFFReadDirEntryIfd8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value) } } break; + default: + break; } _TIFFfreeExt(tif, origdata); *value = data; @@ -3283,13 +3343,42 @@ TIFFReadDirEntryPersampleShort(TIFF *tif, TIFFDirEntry *direntry, uint16_t *m; uint16_t *na; uint16_t nb; - if (direntry->tdir_count < (uint64_t)tif->tif_dir.td_samplesperpixel) - return (TIFFReadDirEntryErrCount); + if (direntry->tdir_count != (uint64_t)tif->tif_dir.td_samplesperpixel) + { + const TIFFField *fip = TIFFFieldWithTag(tif, direntry->tdir_tag); + if (direntry->tdir_count == 0) + { + return TIFFReadDirEntryErrCount; + } + else if (direntry->tdir_count < + (uint64_t)tif->tif_dir.td_samplesperpixel) + { + TIFFWarningExtR( + tif, "TIFFReadDirEntryPersampleShort", + "Tag %s entry count is %" PRIu64 + " , whereas it should be SamplesPerPixel=%d. Assuming that " + "missing entries are all at the value of the first one", + fip ? fip->field_name : "unknown tagname", direntry->tdir_count, + tif->tif_dir.td_samplesperpixel); + } + else + { + TIFFWarningExtR(tif, "TIFFReadDirEntryPersampleShort", + "Tag %s entry count is %" PRIu64 + " , whereas it should be SamplesPerPixel=%d. " + "Ignoring extra entries", + fip ? fip->field_name : "unknown tagname", + direntry->tdir_count, + tif->tif_dir.td_samplesperpixel); + } + } err = TIFFReadDirEntryShortArray(tif, direntry, &m); if (err != TIFFReadDirEntryErrOk || m == NULL) return (err); na = m; nb = tif->tif_dir.td_samplesperpixel; + if (direntry->tdir_count < nb) + nb = (uint16_t)direntry->tdir_count; *value = *na++; nb--; while (nb > 0) @@ -3908,7 +3997,7 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF *tif, uint64_t offset, { return TIFFReadDirEntryErrIo; } - mb = ma + size; + mb = (uint64_t)ma + (uint64_t)size; if (mb > (uint64_t)tif->tif_size) return (TIFFReadDirEntryErrIo); _TIFFmemcpy(dest, tif->tif_base + ma, size); @@ -3955,6 +4044,7 @@ static void TIFFReadDirEntryOutputErr(TIFF *tif, enum TIFFReadDirEntryErr err, TIFFErrorExtR(tif, module, "Out of memory reading of \"%s\"", tagname); break; + case TIFFReadDirEntryErrOk: default: assert(0); /* we should never get here */ break; @@ -4001,6 +4091,7 @@ static void TIFFReadDirEntryOutputErr(TIFF *tif, enum TIFFReadDirEntryErr err, "Out of memory reading of \"%s\"; tag ignored", tagname); break; + case TIFFReadDirEntryErrOk: default: assert(0); /* we should never get here */ break; @@ -4086,7 +4177,8 @@ static int ByteCountLooksBad(TIFF *tif) */ static bool EvaluateIFDdatasizeReading(TIFF *tif, TIFFDirEntry *dp) { - const uint64_t data_width = TIFFDataWidth(dp->tdir_type); + const uint64_t data_width = + (uint64_t)TIFFDataWidth((TIFFDataType)dp->tdir_type); if (data_width != 0 && dp->tdir_count > UINT64_MAX / data_width) { TIFFErrorExtR(tif, "EvaluateIFDdatasizeReading", @@ -4173,9 +4265,9 @@ static void CalcFinalIFDdatasizeReading(TIFF *tif, uint16_t dircount) /* Get offset of end of IFD entry space. */ uint64_t IFDendoffset; if (!(tif->tif_flags & TIFF_BIGTIFF)) - IFDendoffset = tif->tif_diroff + 2 + dircount * 12 + 4; + IFDendoffset = tif->tif_diroff + 2 + (uint64_t)dircount * 12 + 4; else - IFDendoffset = tif->tif_diroff + 8 + dircount * 20 + 8; + IFDendoffset = tif->tif_diroff + 8 + (uint64_t)dircount * 20 + 8; /* Check which offsets are right behind IFD entries. However, LibTIFF * increments the writing address for every external data to an even offset. @@ -4224,9 +4316,9 @@ static void CalcFinalIFDdatasizeReading(TIFF *tif, uint16_t dircount) /* Finally, add the size of the IFD tag entries themselves. */ if (!(tif->tif_flags & TIFF_BIGTIFF)) - tif->tif_dir.td_dirdatasize_read = 2 + dircount * 12 + 4 + size; + tif->tif_dir.td_dirdatasize_read = 2U + dircount * 12U + 4U + size; else - tif->tif_dir.td_dirdatasize_read = 8 + dircount * 20 + 8 + size; + tif->tif_dir.td_dirdatasize_read = 8U + dircount * 20U + 8U + size; } /*-- CalcFinalIFDdatasizeReading() --*/ /* @@ -4298,7 +4390,8 @@ int TIFFReadDirectory(TIFF *tif) { TIFFDirEntry *na; uint16_t nb; - for (na = ma + 1, nb = mb + 1; nb < dircount; na++, nb++) + for (na = ma + 1, nb = (uint16_t)(mb + 1); nb < dircount; + na++, nb++) { if (ma->tdir_tag == na->tdir_tag) { @@ -4312,7 +4405,15 @@ int TIFFReadDirectory(TIFF *tif) tif->tif_flags &= ~TIFF_BUF4WRITE; /* reset before new dir */ tif->tif_flags &= ~TIFF_CHOPPEDUPARRAYS; - /* free any old stuff and reinit */ + /* When changing directory, in deferred strile loading mode, we must also + * unset the TIFF_LAZYSTRILELOAD_DONE bit if it was initially set, + * to make sure the strile offset/bytecount are read again (when they fit + * in the tag data area). + */ + tif->tif_flags &= ~TIFF_LAZYSTRILELOAD_DONE; + + /* Free any old stuff and reinit i/o and other parameters within + * TIFFDefaultDirectory() since we are starting on a new directory. */ TIFFFreeDirectory(tif); TIFFDefaultDirectory(tif); @@ -4325,7 +4426,8 @@ int TIFFReadDirectory(TIFF *tif) * checking. Note: Counter are reset within TIFFFreeDirectory(). */ tif->tif_dir.td_dirdatasize_offsets = (TIFFEntryOffsetAndLength *)_TIFFmallocExt( - tif, dircount * sizeof(TIFFEntryOffsetAndLength)); + tif, + (tmsize_t)((size_t)dircount * sizeof(TIFFEntryOffsetAndLength))); if (tif->tif_dir.td_dirdatasize_offsets == NULL) { TIFFErrorExtR( @@ -4788,8 +4890,8 @@ int TIFFReadDirectory(TIFF *tif) (void)TIFFFetchNormalTag(tif, dp, TRUE); break; } /* -- switch (dp->tdir_tag) -- */ - } /* -- if (!dp->tdir_ignore) */ - } /* -- for-loop -- */ + } /* -- if (!dp->tdir_ignore) */ + } /* -- for-loop -- */ /* Evaluate final IFD data size. */ CalcFinalIFDdatasizeReading(tif, dircount); @@ -5098,7 +5200,7 @@ int TIFFReadDirectory(TIFF *tif) tif->tif_dir.td_maxsamplevalue = 0xFFFF; else tif->tif_dir.td_maxsamplevalue = - (uint16_t)((1L << tif->tif_dir.td_bitspersample) - 1); + (uint16_t)((1 << tif->tif_dir.td_bitspersample) - 1); } #ifdef STRIPBYTECOUNTSORTED_UNUSED @@ -5164,16 +5266,10 @@ int TIFFReadDirectory(TIFF *tif) tif->tif_flags &= ~TIFF_DIRTYSTRIP; /* - * Reinitialize i/o since we are starting on a new directory. + * Reinitialize some further 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) + tif->tif_dir.td_scanlinesize = TIFFScanlineSize(tif); + if (!tif->tif_dir.td_scanlinesize) { TIFFErrorExtR(tif, module, "Cannot handle zero scanline size"); return (0); @@ -5181,8 +5277,8 @@ int TIFFReadDirectory(TIFF *tif) if (isTiled(tif)) { - tif->tif_tilesize = TIFFTileSize(tif); - if (!tif->tif_tilesize) + tif->tif_dir.td_tilesize = TIFFTileSize(tif); + if (!tif->tif_dir.td_tilesize) { TIFFErrorExtR(tif, module, "Cannot handle zero tile size"); return (0); @@ -5220,7 +5316,7 @@ static void TIFFReadDirectoryCheckOrder(TIFF *tif, TIFFDirEntry *dir, "ascending order"); break; } - m = o->tdir_tag + 1; + m = o->tdir_tag + 1U; } } @@ -5268,7 +5364,7 @@ static void TIFFReadDirectoryFindFieldInfo(TIFF *tif, uint16_t tagid, break; mb--; } - *fii = mb; + *fii = (uint32_t)mb; } /* @@ -5308,7 +5404,8 @@ int TIFFReadCustomDirectory(TIFF *tif, toff_t diroff, { TIFFDirEntry *na; uint16_t nb; - for (na = ma + 1, nb = mb + 1; nb < dircount; na++, nb++) + for (na = ma + 1, nb = (uint16_t)(mb + 1); nb < dircount; + na++, nb++) { if (ma->tdir_tag == na->tdir_tag) { @@ -5333,7 +5430,8 @@ int TIFFReadCustomDirectory(TIFF *tif, toff_t diroff, * checking. Note: Counter are reset within TIFFFreeDirectory(). */ tif->tif_dir.td_dirdatasize_offsets = (TIFFEntryOffsetAndLength *)_TIFFmallocExt( - tif, dircount * sizeof(TIFFEntryOffsetAndLength)); + tif, + (tmsize_t)((size_t)dircount * sizeof(TIFFEntryOffsetAndLength))); if (tif->tif_dir.td_dirdatasize_offsets == NULL) { TIFFErrorExtR( @@ -5515,15 +5613,17 @@ static int EstimateStripByteCounts(TIFF *tif, TIFFDirEntry *dir, uint64_t space; uint16_t n; if (!(tif->tif_flags & TIFF_BIGTIFF)) - space = sizeof(TIFFHeaderClassic) + 2 + dircount * 12 + 4; + space = sizeof(TIFFHeaderClassic) + 2 + + (unsigned long)dircount * 12 + 4; else - space = sizeof(TIFFHeaderBig) + 8 + dircount * 20 + 8; + space = + sizeof(TIFFHeaderBig) + 8 + (unsigned long)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); + typewidth = (uint32_t)TIFFDataWidth((TIFFDataType)dp->tdir_type); if (typewidth == 0) { TIFFErrorExtR( @@ -5786,7 +5886,7 @@ int _TIFFCheckDirNumberAndOffset(TIFF *tif, tdir_t dirn, uint64_t diroff) { TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset", "Cannot handle more than %u TIFF directories", - TIFF_MAX_DIR_COUNT); + (unsigned)TIFF_MAX_DIR_COUNT); return 0; } @@ -6048,7 +6148,7 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff, "to read TIFF directory"); if (origdir == NULL) return 0; - if (!ReadOK(tif, origdir, (tmsize_t)(dircount16 * dirsize))) + if (!ReadOK(tif, origdir, (tmsize_t)dircount16 * dirsize)) { TIFFErrorExtR(tif, module, "%.100s: Can not read TIFF directory", tif->tif_name); @@ -6101,9 +6201,9 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff, */ if (!(tif->tif_flags & TIFF_BIGTIFF)) { - m = off + sizeof(uint16_t); - if ((m < off) || (m < (tmsize_t)sizeof(uint16_t)) || - (m > tif->tif_size)) + m = (tmsize_t)((uint64_t)off + sizeof(uint16_t)); + if ((m < off) || ((uint64_t)m < sizeof(uint16_t)) || + ((uint64_t)m > (uint64_t)tif->tif_size)) { TIFFErrorExtR(tif, module, "Can not read TIFF directory count"); return 0; @@ -6112,7 +6212,7 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff, { _TIFFmemcpy(&dircount16, tif->tif_base + off, sizeof(uint16_t)); } - off += sizeof(uint16_t); + off = (tmsize_t)((uint64_t)off + sizeof(uint16_t)); if (tif->tif_flags & TIFF_SWAB) TIFFSwabShort(&dircount16); if (dircount16 > 4096) @@ -6127,9 +6227,9 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff, else { uint64_t dircount64; - m = off + sizeof(uint64_t); - if ((m < off) || (m < (tmsize_t)sizeof(uint64_t)) || - (m > tif->tif_size)) + m = (tmsize_t)((uint64_t)off + sizeof(uint64_t)); + if ((m < off) || ((uint64_t)m < sizeof(uint64_t)) || + ((uint64_t)m > (uint64_t)tif->tif_size)) { TIFFErrorExtR(tif, module, "Can not read TIFF directory count"); return 0; @@ -6138,7 +6238,7 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff, { _TIFFmemcpy(&dircount64, tif->tif_base + off, sizeof(uint64_t)); } - off += sizeof(uint64_t); + off = (tmsize_t)((uint64_t)off + sizeof(uint64_t)); if (tif->tif_flags & TIFF_SWAB) TIFFSwabLong8(&dircount64); if (dircount64 > 4096) @@ -6177,7 +6277,7 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff, if (origdir == NULL) return 0; m = off + dircount16 * dirsize; - if ((m < off) || (m < (tmsize_t)(dircount16 * dirsize)) || + if ((m < off) || (m < (tmsize_t)dircount16 * (tmsize_t)dirsize) || (m > tif->tif_size)) { TIFFErrorExtR(tif, module, "Can not read TIFF directory"); @@ -6186,7 +6286,8 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff, } else { - _TIFFmemcpy(origdir, tif->tif_base + off, dircount16 * dirsize); + _TIFFmemcpy(origdir, tif->tif_base + off, + (tmsize_t)dircount16 * dirsize); } if (nextdiroff) { @@ -6194,9 +6295,9 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff, 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)) + m = (tmsize_t)((uint64_t)off + sizeof(uint32_t)); + if ((m < off) || ((uint64_t)m < sizeof(uint32_t)) || + ((uint64_t)m > (uint64_t)tif->tif_size)) nextdiroff32 = 0; else _TIFFmemcpy(&nextdiroff32, tif->tif_base + off, @@ -6207,9 +6308,9 @@ static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff, } else { - m = off + sizeof(uint64_t); - if ((m < off) || (m < (tmsize_t)sizeof(uint64_t)) || - (m > tif->tif_size)) + m = (tmsize_t)((uint64_t)off + sizeof(uint64_t)); + if ((m < off) || ((uint64_t)m < sizeof(uint64_t)) || + ((uint64_t)m > (uint64_t)tif->tif_size)) *nextdiroff = 0; else _TIFFmemcpy(nextdiroff, tif->tif_base + off, @@ -6355,8 +6456,8 @@ static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover) /* TIFFReadDirEntryArrayWithLimit() ensures this can't be * larger than MAX_SIZE_TAG_DATA */ assert((uint32_t)dp->tdir_count + 1 == dp->tdir_count + 1); - uint8_t *o = - _TIFFmallocExt(tif, (uint32_t)dp->tdir_count + 1); + uint8_t *o = (uint8_t *)_TIFFmallocExt( + tif, (uint32_t)dp->tdir_count + 1); if (o == NULL) { if (data != NULL) @@ -6498,7 +6599,7 @@ static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover) { if (!EvaluateIFDdatasizeReading(tif, dp)) return 0; - if (!TIFFSetField(tif, dp->tdir_tag, data)) + if (!TIFFSetField(tif, dp->tdir_tag, (double)data)) return (0); } } @@ -6910,6 +7011,41 @@ static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover) } } break; + case TIFF_SETGET_C0_IFD8: + { + 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 = TIFFReadDirEntryIfd8Array(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + if (!EvaluateIFDdatasizeReading(tif, dp)) + { + if (data != 0) + _TIFFfreeExt(tif, data); + return 0; + } + 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; @@ -6938,8 +7074,8 @@ static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover) "byte. Forcing it to be null", fip->field_name); /* Enlarge buffer and add terminating null. */ - uint8_t *o = - _TIFFmallocExt(tif, (uint32_t)dp->tdir_count + 1); + uint8_t *o = (uint8_t *)_TIFFmallocExt( + tif, (uint32_t)dp->tdir_count + 1); if (o == NULL) { if (data != NULL) @@ -7309,8 +7445,8 @@ static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover) "in null byte. Forcing it to be null", fip->field_name); /* Enlarge buffer and add terminating null. */ - uint8_t *o = - _TIFFmallocExt(tif, (uint32_t)dp->tdir_count + 1); + uint8_t *o = (uint8_t *)_TIFFmallocExt( + tif, (uint32_t)dp->tdir_count + 1); if (o == NULL) { if (data != NULL) @@ -7624,6 +7760,11 @@ static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover) } } break; + case TIFF_SETGET_INT: + case TIFF_SETGET_C0_ASCII: + case TIFF_SETGET_OTHER: + assert(0); /* these should not arrive here */ + break; default: assert(0); /* we should never get here */ break; @@ -7700,9 +7841,10 @@ static int TIFFFetchStripThing(TIFF *tif, TIFFDirEntry *dir, uint32_t nstrips, } if (dir->tdir_count) _TIFFmemcpy(resizeddata, data, - (uint32_t)dir->tdir_count * sizeof(uint64_t)); + (tmsize_t)((size_t)dir->tdir_count * sizeof(uint64_t))); _TIFFmemset(resizeddata + (uint32_t)dir->tdir_count, 0, - (nstrips - (uint32_t)dir->tdir_count) * sizeof(uint64_t)); + (tmsize_t)((size_t)(nstrips - (uint32_t)dir->tdir_count) * + sizeof(uint64_t))); _TIFFfreeExt(tif, data); data = resizeddata; } @@ -7866,7 +8008,7 @@ static void allocChoppedUpStripArrays(TIFF *tif, uint32_t nstrips, */ static void ChopUpSingleUncompressedStrip(TIFF *tif) { - register TIFFDirectory *td = &tif->tif_dir; + TIFFDirectory *td = &tif->tif_dir; uint64_t bytecount; uint64_t offset; uint32_t rowblock; @@ -7881,7 +8023,7 @@ static void ChopUpSingleUncompressedStrip(TIFF *tif) /* later ( StripOffsets and StripByteCounts improperly filled) . */ if (bytecount == 0 && tif->tif_mode != O_RDONLY) return; - offset = TIFFGetStrileByteCount(tif, 0); + offset = TIFFGetStrileOffset(tif, 0); assert(td->td_planarconfig == PLANARCONFIG_CONTIG); if ((td->td_photometric == PHOTOMETRIC_YCBCR) && (!isUpSampled(tif))) rowblock = td->td_ycbcrsubsampling[1]; @@ -8032,7 +8174,7 @@ static void TryChopUpUncompressedBigTiff(TIFF *tif) TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW static uint64_t _TIFFUnsanitizedAddUInt64AndInt(uint64_t a, int b) { - return a + b; + return a + (uint64_t)b; } /* Read the value of [Strip|Tile]Offset or [Strip|Tile]ByteCount around @@ -8111,7 +8253,7 @@ static int _TIFFPartialReadStripArray(TIFF *tif, TIFFDirEntry *dirent, panVals[strile] = 0; return 0; } - nOffset = nBaseOffset + sizeofval * strile; + nOffset = nBaseOffset + (uint64_t)sizeofval * (uint64_t)strile; nOffsetStartPage = (nOffset / IO_CACHE_PAGE_SIZE) * IO_CACHE_PAGE_SIZE; nOffsetEndPage = nOffsetStartPage + IO_CACHE_PAGE_SIZE; @@ -8119,7 +8261,7 @@ static int _TIFFPartialReadStripArray(TIFF *tif, TIFFDirEntry *dirent, nOffsetEndPage += IO_CACHE_PAGE_SIZE; #undef IO_CACHE_PAGE_SIZE - nLastStripOffset = nBaseOffset + arraySize * sizeofval; + nLastStripOffset = nBaseOffset + (uint64_t)arraySize * sizeofval; if (nLastStripOffset < nOffsetEndPage) nOffsetEndPage = nLastStripOffset; if (nOffsetStartPage >= nOffsetEndPage) @@ -8254,9 +8396,9 @@ static int _TIFFFetchStrileValue(TIFF *tif, uint32_t strile, } #endif offsetArray = (uint64_t *)(_TIFFreallocExt(tif, td->td_stripoffset_p, - nArraySize)); + (tmsize_t)nArraySize)); bytecountArray = (uint64_t *)(_TIFFreallocExt( - tif, td->td_stripbytecount_p, nArraySize)); + tif, td->td_stripbytecount_p, (tmsize_t)nArraySize)); if (offsetArray) td->td_stripoffset_p = offsetArray; if (bytecountArray) @@ -8290,7 +8432,7 @@ static int _TIFFFetchStrileValue(TIFF *tif, uint32_t strile, if (~((*parray)[strile]) == 0) { - if (!_TIFFPartialReadStripArray(tif, dirent, strile, *parray)) + if (!_TIFFPartialReadStripArray(tif, dirent, (int)strile, *parray)) { (*parray)[strile] = 0; return 0; @@ -8308,10 +8450,26 @@ static uint64_t _TIFFGetStrileOffsetOrByteCountValue(TIFF *tif, uint32_t strile, TIFFDirectory *td = &tif->tif_dir; if (pbErr) *pbErr = 0; + + /* Avoid the "dirent->tdir_count <= 4" code path for one of + * StripOffsets/StripByteCounts, and the other code path for the other one, + * which will lead to inconsistencies and potential out-of-bounds reads. + */ + if ((td->td_stripoffset_entry.tdir_count <= 4) != + (td->td_stripbytecount_entry.tdir_count <= 4)) + { + TIFFErrorExtR(tif, "_TIFFGetStrileOffsetOrByteCountValue", + "Inconsistent directory count between StripOffsets and " + "StripByteCounts"); + if (pbErr) + *pbErr = 1; + return 0; + } + if ((tif->tif_flags & TIFF_DEFERSTRILELOAD) && !(tif->tif_flags & TIFF_CHOPPEDUPARRAYS)) { - if (!(tif->tif_flags & TIFF_LAZYSTRILELOAD) || + if (!(tif->tif_flags & TIFF_LAZYSTRILELOAD_ASKED) || /* If the values may fit in the toff_long/toff_long8 member */ /* then use _TIFFFillStriles to simplify _TIFFFetchStrileValue */ dirent->tdir_count <= 4) @@ -8382,7 +8540,7 @@ int _TIFFFillStriles(TIFF *tif) { return _TIFFFillStrilesInternal(tif, 1); } static int _TIFFFillStrilesInternal(TIFF *tif, int loadStripByteCount) { - register TIFFDirectory *td = &tif->tif_dir; + TIFFDirectory *td = &tif->tif_dir; int return_value = 1; /* Do not do anything if TIFF_DEFERSTRILELOAD is not set */ @@ -8390,7 +8548,8 @@ static int _TIFFFillStrilesInternal(TIFF *tif, int loadStripByteCount) (tif->tif_flags & TIFF_CHOPPEDUPARRAYS) != 0) return 1; - if (tif->tif_flags & TIFF_LAZYSTRILELOAD) + if ((tif->tif_flags & TIFF_LAZYSTRILELOAD_ASKED) && + !(tif->tif_flags & TIFF_LAZYSTRILELOAD_DONE)) { /* In case of lazy loading, reload completely the arrays */ _TIFFfreeExt(tif, td->td_stripoffset_p); @@ -8398,7 +8557,7 @@ static int _TIFFFillStrilesInternal(TIFF *tif, int loadStripByteCount) td->td_stripoffset_p = NULL; td->td_stripbytecount_p = NULL; td->td_stripoffsetbyteallocsize = 0; - tif->tif_flags &= ~TIFF_LAZYSTRILELOAD; + tif->tif_flags |= TIFF_LAZYSTRILELOAD_DONE; } /* If stripoffset array is already loaded, exit with success */ diff --git a/3rdparty/libtiff/tif_dirwrite.c b/3rdparty/libtiff/tif_dirwrite.c index bc5ada0f2b..5da087e295 100644 --- a/3rdparty/libtiff/tif_dirwrite.c +++ b/3rdparty/libtiff/tif_dirwrite.c @@ -365,7 +365,7 @@ static int TIFFRewriteDirectorySec(TIFF *tif, int isimage, int imagedone, } if (tif->tif_flags & TIFF_SWAB) TIFFSwabShort(&dircount); - (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET); + (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12U, SEEK_SET); if (!ReadOK(tif, &nextnextdir, 4)) { TIFFErrorExtR(tif, module, "Error fetching directory link"); @@ -377,7 +377,7 @@ static int TIFFRewriteDirectorySec(TIFF *tif, int isimage, int imagedone, { uint32_t m; m = 0; - (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, + (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12U, SEEK_SET); if (!WriteOK(tif, &m, 4)) { @@ -417,7 +417,6 @@ static int TIFFRewriteDirectorySec(TIFF *tif, int isimage, int imagedone, while (1) { uint64_t dircount64; - uint16_t dircount; uint64_t nextnextdir; if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount64, 8)) @@ -435,8 +434,8 @@ static int TIFFRewriteDirectorySec(TIFF *tif, int isimage, int imagedone, "corrupt TIFF"); return (0); } - dircount = (uint16_t)dircount64; - (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET); + (void)TIFFSeekFile(tif, nextdir + 8 + dircount64 * 20, + SEEK_SET); if (!ReadOK(tif, &nextnextdir, 8)) { TIFFErrorExtR(tif, module, "Error fetching directory link"); @@ -448,7 +447,7 @@ static int TIFFRewriteDirectorySec(TIFF *tif, int isimage, int imagedone, { uint64_t m; m = 0; - (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, + (void)TIFFSeekFile(tif, nextdir + 8 + dircount64 * 20, SEEK_SET); if (!WriteOK(tif, &m, 8)) { @@ -592,24 +591,24 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone, } if (TIFFFieldSet(tif, FIELD_RESOLUTION)) { - if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir, - TIFFTAG_XRESOLUTION, - tif->tif_dir.td_xresolution)) + if (!TIFFWriteDirectoryTagRational( + tif, &ndir, dir, TIFFTAG_XRESOLUTION, + (double)tif->tif_dir.td_xresolution)) goto bad; - if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir, - TIFFTAG_YRESOLUTION, - tif->tif_dir.td_yresolution)) + if (!TIFFWriteDirectoryTagRational( + tif, &ndir, dir, TIFFTAG_YRESOLUTION, + (double)tif->tif_dir.td_yresolution)) goto bad; } if (TIFFFieldSet(tif, FIELD_POSITION)) { - if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir, - TIFFTAG_XPOSITION, - tif->tif_dir.td_xposition)) + if (!TIFFWriteDirectoryTagRational( + tif, &ndir, dir, TIFFTAG_XPOSITION, + (double)tif->tif_dir.td_xposition)) goto bad; - if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir, - TIFFTAG_YPOSITION, - tif->tif_dir.td_yposition)) + if (!TIFFWriteDirectoryTagRational( + tif, &ndir, dir, TIFFTAG_YPOSITION, + (double)tif->tif_dir.td_yposition)) goto bad; } if (TIFFFieldSet(tif, FIELD_SUBFILETYPE)) @@ -712,6 +711,14 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone, } if (TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) { + /* Check td_stripbytecount_p for NULL pointer (bug#749) */ + if (tif->tif_dir.td_stripbytecount_p == NULL) + { + TIFFErrorExtR( + tif, module, + "StripByteCount array is not set, pointer is NULL"); + goto bad; + } if (!isTiled(tif)) { if (!TIFFWriteDirectoryTagLongLong8Array( @@ -731,6 +738,14 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone, } if (TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) { + /* Check td_stripoffset_p for NULL pointer (bug#749) */ + if (tif->tif_dir.td_stripoffset_p == NULL) + { + TIFFErrorExtR( + tif, module, + "StripByteOffset array is not set, pointer is NULL"); + goto bad; + } if (!isTiled(tif)) { /* td_stripoffset_p might be NULL in an odd OJPEG case. See @@ -851,7 +866,8 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone, { if (!TIFFWriteDirectoryTagAscii( tif, &ndir, dir, TIFFTAG_INKNAMES, - tif->tif_dir.td_inknameslen, tif->tif_dir.td_inknames)) + (uint32_t)tif->tif_dir.td_inknameslen, + tif->tif_dir.td_inknames)) goto bad; } if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS)) @@ -932,10 +948,58 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone, TIFFGetField(tif, o->field_tag, &pa, &pb); if (!TIFFWriteDirectoryTagUndefinedArray( tif, &ndir, dir, (uint16_t)o->field_tag, - pa, pb)) + pa, (uint8_t *)pb)) goto bad; } break; + case TIFF_SETGET_UNDEFINED: + case TIFF_SETGET_SINT8: + case TIFF_SETGET_SINT16: + case TIFF_SETGET_SINT32: + case TIFF_SETGET_UINT64: + case TIFF_SETGET_SINT64: + case TIFF_SETGET_FLOAT: + case TIFF_SETGET_DOUBLE: + case TIFF_SETGET_IFD8: + case TIFF_SETGET_INT: + case TIFF_SETGET_UINT16_PAIR: + case TIFF_SETGET_C0_ASCII: + case TIFF_SETGET_C0_UINT8: + case TIFF_SETGET_C0_SINT8: + case TIFF_SETGET_C0_UINT16: + case TIFF_SETGET_C0_SINT16: + case TIFF_SETGET_C0_UINT32: + case TIFF_SETGET_C0_SINT32: + case TIFF_SETGET_C0_UINT64: + case TIFF_SETGET_C0_SINT64: + case TIFF_SETGET_C0_FLOAT: + case TIFF_SETGET_C0_DOUBLE: + case TIFF_SETGET_C0_IFD8: + 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_UINT64: + case TIFF_SETGET_C16_SINT64: + case TIFF_SETGET_C16_FLOAT: + case TIFF_SETGET_C16_DOUBLE: + case TIFF_SETGET_C16_IFD8: + case TIFF_SETGET_C32_ASCII: + 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_UINT64: + case TIFF_SETGET_C32_SINT64: + case TIFF_SETGET_C32_FLOAT: + case TIFF_SETGET_C32_DOUBLE: + case TIFF_SETGET_C32_IFD8: + case TIFF_SETGET_UINT8: + case TIFF_SETGET_OTHER: default: TIFFErrorExtR( tif, module, @@ -954,67 +1018,67 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone, { uint16_t tag = (uint16_t)tif->tif_dir.td_customValues[m].info->field_tag; - uint32_t count = tif->tif_dir.td_customValues[m].count; + uint32_t count = (uint32_t)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)) + (char *)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)) + (uint8_t *)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)) + (uint8_t *)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)) + (int8_t *)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)) + (uint16_t *)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)) + (int16_t *)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)) + (uint32_t *)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)) + (int32_t *)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)) + (uint64_t *)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)) + (int64_t *)tif->tif_dir.td_customValues[m].value)) goto bad; break; case TIFF_RATIONAL: @@ -1029,7 +1093,8 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone, { if (!TIFFWriteDirectoryTagRationalDoubleArray( tif, &ndir, dir, tag, count, - tif->tif_dir.td_customValues[m].value)) + (double *)tif->tif_dir.td_customValues[m] + .value)) goto bad; } else @@ -1037,7 +1102,7 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone, /*-- default should be tv_size == 4 */ if (!TIFFWriteDirectoryTagRationalArray( tif, &ndir, dir, tag, count, - tif->tif_dir.td_customValues[m].value)) + (float *)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. */ @@ -1064,7 +1129,8 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone, { if (!TIFFWriteDirectoryTagSrationalDoubleArray( tif, &ndir, dir, tag, count, - tif->tif_dir.td_customValues[m].value)) + (double *)tif->tif_dir.td_customValues[m] + .value)) goto bad; } else @@ -1072,7 +1138,7 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone, /*-- default should be tv_size == 4 */ if (!TIFFWriteDirectoryTagSrationalArray( tif, &ndir, dir, tag, count, - tif->tif_dir.td_customValues[m].value)) + (float *)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. */ @@ -1090,27 +1156,28 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone, case TIFF_FLOAT: if (!TIFFWriteDirectoryTagFloatArray( tif, &ndir, dir, tag, count, - tif->tif_dir.td_customValues[m].value)) + (float *)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)) + (double *)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)) + (uint32_t *)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)) + (uint64_t *)tif->tif_dir.td_customValues[m].value)) goto bad; break; + case TIFF_NOTYPE: default: assert(0); /* we should never get here */ break; @@ -1128,7 +1195,8 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone, tif->tif_dir.td_dirdatasize_write += 8 + ndir * 20 + 8; /* Setup a new directory within first pass. */ - dir = _TIFFmallocExt(tif, ndir * sizeof(TIFFDirEntry)); + dir = (TIFFDirEntry *)_TIFFmallocExt( + tif, (tmsize_t)((size_t)ndir * sizeof(TIFFDirEntry))); if (dir == NULL) { TIFFErrorExtR(tif, module, "Out of memory"); @@ -1238,7 +1306,7 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone, uint8_t *n; uint32_t nTmp; TIFFDirEntry *o; - n = dirmem; + n = (uint8_t *)dirmem; *(uint16_t *)n = (uint16_t)ndir; if (tif->tif_flags & TIFF_SWAB) TIFFSwabShort((uint16_t *)n); @@ -1274,7 +1342,7 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone, { uint8_t *n; TIFFDirEntry *o; - n = dirmem; + n = (uint8_t *)dirmem; *(uint64_t *)n = ndir; if (tif->tif_flags & TIFF_SWAB) TIFFSwabLong8((uint64_t *)n); @@ -1405,7 +1473,7 @@ static int8_t TIFFClampDoubleToInt8(double val) { if (val > 127) return 127; - if (val < -128 || val != val) + if (val < -128 || isnan(val)) return -128; return (int8_t)val; } @@ -1414,7 +1482,7 @@ static int16_t TIFFClampDoubleToInt16(double val) { if (val > 32767) return 32767; - if (val < -32768 || val != val) + if (val < -32768 || isnan(val)) return -32768; return (int16_t)val; } @@ -1423,7 +1491,7 @@ static int32_t TIFFClampDoubleToInt32(double val) { if (val > 0x7FFFFFFF) return 0x7FFFFFFF; - if (val < -0x7FFFFFFF - 1 || val != val) + if (val < -0x7FFFFFFF - 1 || isnan(val)) return -0x7FFFFFFF - 1; return (int32_t)val; } @@ -1432,7 +1500,7 @@ static uint8_t TIFFClampDoubleToUInt8(double val) { if (val < 0) return 0; - if (val > 255 || val != val) + if (val > 255 || isnan(val)) return 255; return (uint8_t)val; } @@ -1441,7 +1509,7 @@ static uint16_t TIFFClampDoubleToUInt16(double val) { if (val < 0) return 0; - if (val > 65535 || val != val) + if (val > 65535 || isnan(val)) return 65535; return (uint16_t)val; } @@ -1450,7 +1518,7 @@ static uint32_t TIFFClampDoubleToUInt32(double val) { if (val < 0) return 0; - if (val > 0xFFFFFFFFU || val != val) + if (val > 0xFFFFFFFFU || isnan(val)) return 0xFFFFFFFFU; return (uint32_t)val; } @@ -1464,7 +1532,7 @@ static int TIFFWriteDirectoryTagSampleformatArray(TIFF *tif, uint32_t *ndir, void *conv; uint32_t i; int ok; - conv = _TIFFmallocExt(tif, count * sizeof(double)); + conv = _TIFFmallocExt(tif, (tmsize_t)((size_t)count * sizeof(double))); if (conv == NULL) { TIFFErrorExtR(tif, module, "Out of memory"); @@ -1603,7 +1671,9 @@ static int TIFFWriteDirectoryTagShortPerSample(TIFF *tif, uint32_t *ndir, return (TIFFWriteDirectoryTagCheckedShortArray( tif, ndir, dir, tag, tif->tif_dir.td_samplesperpixel, NULL)); } - m = _TIFFmallocExt(tif, tif->tif_dir.td_samplesperpixel * sizeof(uint16_t)); + m = (uint16_t *)_TIFFmallocExt( + tif, + (tmsize_t)((size_t)tif->tif_dir.td_samplesperpixel * sizeof(uint16_t))); if (m == NULL) { TIFFErrorExtR(tif, module, "Out of memory"); @@ -1664,14 +1734,6 @@ static int TIFFWriteDirectoryTagLong8Array(TIFF *tif, uint32_t *ndir, uint32_t *q; int o; - /* is this just a counting pass? */ - if (dir == NULL) - { - /* only evaluate IFD data size and inc. ndir */ - return (TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag, - count, value)); - } - /* We always write Long8 for BigTIFF, no checking needed. */ if (tif->tif_flags & TIFF_BIGTIFF) return (TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag, @@ -1681,7 +1743,8 @@ static int TIFFWriteDirectoryTagLong8Array(TIFF *tif, uint32_t *ndir, ** 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)); + p = (uint32_t *)_TIFFmallocExt( + tif, (tmsize_t)((size_t)count * sizeof(uint32_t))); if (p == NULL) { TIFFErrorExtR(tif, module, "Out of memory"); @@ -1725,13 +1788,6 @@ static int TIFFWriteDirectoryTagSlong8Array(TIFF *tif, uint32_t *ndir, int32_t *q; int o; - /* is this just a counting pass? */ - if (dir == NULL) - { - /* only evaluate IFD data size and inc. ndir */ - return (TIFFWriteDirectoryTagCheckedSlong8Array(tif, ndir, dir, tag, - count, value)); - } /* We always write SLong8 for BigTIFF, no checking needed. */ if (tif->tif_flags & TIFF_BIGTIFF) return (TIFFWriteDirectoryTagCheckedSlong8Array(tif, ndir, dir, tag, @@ -1741,7 +1797,8 @@ static int TIFFWriteDirectoryTagSlong8Array(TIFF *tif, uint32_t *ndir, ** 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)); + p = (int32_t *)_TIFFmallocExt(tif, + (tmsize_t)((size_t)count * sizeof(uint32_t))); if (p == NULL) { TIFFErrorExtR(tif, module, "Out of memory"); @@ -1960,7 +2017,8 @@ static int TIFFWriteDirectoryTagLongLong8Array(TIFF *tif, uint32_t *ndir, ** and convert to long format. */ - uint32_t *p = _TIFFmallocExt(tif, count * sizeof(uint32_t)); + uint32_t *p = (uint32_t *)_TIFFmallocExt( + tif, (tmsize_t)((size_t)count * sizeof(uint32_t))); uint32_t *q; uint64_t *ma; uint32_t mb; @@ -1990,7 +2048,8 @@ static int TIFFWriteDirectoryTagLongLong8Array(TIFF *tif, uint32_t *ndir, } else { - uint16_t *p = _TIFFmallocExt(tif, count * sizeof(uint16_t)); + uint16_t *p = (uint16_t *)_TIFFmallocExt( + tif, (tmsize_t)((size_t)count * sizeof(uint16_t))); uint16_t *q; uint64_t *ma; uint32_t mb; @@ -2050,7 +2109,8 @@ static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF *tif, uint32_t *ndir, ** and convert to long format. */ - p = _TIFFmallocExt(tif, count * sizeof(uint32_t)); + p = (uint32_t *)_TIFFmallocExt( + tif, (tmsize_t)((size_t)count * sizeof(uint32_t))); if (p == NULL) { TIFFErrorExtR(tif, module, "Out of memory"); @@ -2101,26 +2161,45 @@ static int TIFFWriteDirectoryTagColormap(TIFF *tif, uint32_t *ndir, { static const char module[] = "TIFFWriteDirectoryTagColormap"; uint32_t m; + uint32_t count; + uint64_t count64; + tmsize_t total_values; + tmsize_t plane_bytes; uint16_t *n; int o; - m = (1 << tif->tif_dir.td_bitspersample); + if (tif->tif_dir.td_bitspersample >= 32) + { + TIFFErrorExtR(tif, module, "BitsPerSample too large for Colormap"); + return (0); + } + m = 1U << tif->tif_dir.td_bitspersample; + count64 = _TIFFMultiply64(tif, 3U, m, module); + if (count64 == 0) + return (0); + count = _TIFFCastUInt64ToUInt32(tif, count64, module); + total_values = _TIFFCastUInt64ToSSize(tif, count64, module); + plane_bytes = _TIFFCastUInt64ToSSize( + tif, _TIFFMultiply64(tif, m, sizeof(uint16_t), module), module); + if (count == 0 || total_values == 0 || plane_bytes == 0) + return (0); if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */ { - EvaluateIFDdatasizeWrite(tif, 3 * m, sizeof(uint16_t), ndir); + EvaluateIFDdatasizeWrite(tif, count, sizeof(uint16_t), ndir); return 1; } - n = _TIFFmallocExt(tif, 3 * m * sizeof(uint16_t)); + n = (uint16_t *)_TIFFCheckMalloc(tif, total_values, sizeof(uint16_t), + module); 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)); + _TIFFmemcpy(&n[0], tif->tif_dir.td_colormap[0], plane_bytes); + _TIFFmemcpy(&n[m], tif->tif_dir.td_colormap[1], plane_bytes); + _TIFFmemcpy(&n[2 * m], tif->tif_dir.td_colormap[2], plane_bytes); o = TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, TIFFTAG_COLORMAP, - 3 * m, n); + count, n); _TIFFfreeExt(tif, n); return (o); } @@ -2130,13 +2209,27 @@ static int TIFFWriteDirectoryTagTransferfunction(TIFF *tif, uint32_t *ndir, { static const char module[] = "TIFFWriteDirectoryTagTransferfunction"; uint32_t m; + uint32_t count; + uint64_t count64; + tmsize_t total_values; + tmsize_t plane_bytes; uint16_t n; uint16_t *o; int p; /* TIFFTAG_TRANSFERFUNCTION expects (1 or 3) pointer to arrays with - * (1 << BitsPerSample) * uint16_t values. + * 2**BitsPerSample uint16_t values. */ - m = (1 << tif->tif_dir.td_bitspersample); + if (tif->tif_dir.td_bitspersample >= 32) + { + TIFFErrorExtR(tif, module, + "BitsPerSample too large for TransferFunction"); + return (0); + } + m = 1U << tif->tif_dir.td_bitspersample; + plane_bytes = _TIFFCastUInt64ToSSize( + tif, _TIFFMultiply64(tif, m, sizeof(uint16_t), module), module); + if (plane_bytes == 0) + return (0); /* clang-format off */ n = (tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples) > 1 ? 3 : 1; /* clang-format on */ @@ -2161,35 +2254,39 @@ static int TIFFWriteDirectoryTagTransferfunction(TIFF *tif, uint32_t *ndir, if (n == 3) { if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0], - tif->tif_dir.td_transferfunction[2], - m * sizeof(uint16_t)) && + tif->tif_dir.td_transferfunction[2], plane_bytes) && !_TIFFmemcmp(tif->tif_dir.td_transferfunction[0], - tif->tif_dir.td_transferfunction[1], - m * sizeof(uint16_t))) + tif->tif_dir.td_transferfunction[1], plane_bytes)) n = 1; } + count64 = _TIFFMultiply64(tif, n, m, module); + if (count64 == 0) + return (0); + count = _TIFFCastUInt64ToUInt32(tif, count64, module); + total_values = _TIFFCastUInt64ToSSize(tif, count64, module); + if (count == 0 || total_values == 0) + return (0); if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */ { - EvaluateIFDdatasizeWrite(tif, n * m, 2, ndir); + EvaluateIFDdatasizeWrite(tif, count, 2, ndir); return 1; } - o = _TIFFmallocExt(tif, n * m * sizeof(uint16_t)); + o = (uint16_t *)_TIFFCheckMalloc(tif, total_values, sizeof(uint16_t), + module); if (o == NULL) { TIFFErrorExtR(tif, module, "Out of memory"); return (0); } - _TIFFmemcpy(&o[0], tif->tif_dir.td_transferfunction[0], - m * sizeof(uint16_t)); + _TIFFmemcpy(&o[0], tif->tif_dir.td_transferfunction[0], plane_bytes); if (n > 1) - _TIFFmemcpy(&o[m], tif->tif_dir.td_transferfunction[1], - m * sizeof(uint16_t)); + _TIFFmemcpy(&o[m], tif->tif_dir.td_transferfunction[1], plane_bytes); if (n > 2) _TIFFmemcpy(&o[2 * m], tif->tif_dir.td_transferfunction[2], - m * sizeof(uint16_t)); + plane_bytes); p = TIFFWriteDirectoryTagCheckedShortArray( - tif, ndir, dir, TIFFTAG_TRANSFERFUNCTION, n * m, o); + tif, ndir, dir, TIFFTAG_TRANSFERFUNCTION, count, o); _TIFFfreeExt(tif, o); return (p); } @@ -2209,7 +2306,9 @@ static int TIFFWriteDirectoryTagSubifd(TIFF *tif, uint32_t *ndir, uint64_t *pa; uint32_t *pb; uint16_t p; - o = _TIFFmallocExt(tif, tif->tif_dir.td_nsubifd * sizeof(uint32_t)); + o = (uint32_t *)_TIFFmallocExt( + tif, + (tmsize_t)((size_t)tif->tif_dir.td_nsubifd * sizeof(uint32_t))); if (o == NULL) { TIFFErrorExtR(tif, module, "Out of memory"); @@ -2494,7 +2593,7 @@ static int TIFFWriteDirectoryTagCheckedRational(TIFF *tif, uint32_t *ndir, TIFFErrorExtR(tif, module, "Negative value is illegal"); return 0; } - else if (value != value) + else if (isnan(value)) { TIFFErrorExtR(tif, module, "Not-a-number value is illegal"); return 0; @@ -2537,7 +2636,8 @@ static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF *tif, uint32_t *ndir, EvaluateIFDdatasizeWrite(tif, count * 2, sizeof(uint32_t), ndir); return 1; } - m = _TIFFmallocExt(tif, count * 2 * sizeof(uint32_t)); + m = (uint32_t *)_TIFFCheckMalloc(tif, count, 2 * sizeof(uint32_t), + "for rational array"); if (m == NULL) { TIFFErrorExtR(tif, module, "Out of memory"); @@ -2545,7 +2645,7 @@ static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF *tif, uint32_t *ndir, } for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++) { - DoubleToRational(*na, &nb[0], &nb[1]); + DoubleToRational((double)*na, &nb[0], &nb[1]); } if (tif->tif_flags & TIFF_SWAB) TIFFSwabArrayOfLong(m, count * 2); @@ -2573,7 +2673,8 @@ static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF *tif, uint32_t *ndir, EvaluateIFDdatasizeWrite(tif, count * 2, sizeof(int32_t), ndir); return 1; } - m = _TIFFmallocExt(tif, count * 2 * sizeof(int32_t)); + m = (int32_t *)_TIFFCheckMalloc(tif, count, 2 * sizeof(int32_t), + "for srational array"); if (m == NULL) { TIFFErrorExtR(tif, module, "Out of memory"); @@ -2581,7 +2682,7 @@ static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF *tif, uint32_t *ndir, } for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++) { - DoubleToSrational(*na, &nb[0], &nb[1]); + DoubleToSrational((double)*na, &nb[0], &nb[1]); } if (tif->tif_flags & TIFF_SWAB) TIFFSwabArrayOfLong((uint32_t *)m, count * 2); @@ -2610,7 +2711,8 @@ TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF *tif, uint32_t *ndir, EvaluateIFDdatasizeWrite(tif, count * 2, sizeof(uint32_t), ndir); return 1; } - m = _TIFFmallocExt(tif, count * 2 * sizeof(uint32_t)); + m = (uint32_t *)_TIFFCheckMalloc(tif, count, 2 * sizeof(uint32_t), + "for rational double array"); if (m == NULL) { TIFFErrorExtR(tif, module, "Out of memory"); @@ -2618,7 +2720,7 @@ TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF *tif, uint32_t *ndir, } for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++) { - DoubleToRational(*na, &nb[0], &nb[1]); + DoubleToRational((double)*na, &nb[0], &nb[1]); } if (tif->tif_flags & TIFF_SWAB) TIFFSwabArrayOfLong(m, count * 2); @@ -2645,7 +2747,8 @@ static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray( EvaluateIFDdatasizeWrite(tif, count * 2, sizeof(int32_t), ndir); return 1; } - m = _TIFFmallocExt(tif, count * 2 * sizeof(int32_t)); + m = (int32_t *)_TIFFCheckMalloc(tif, count, 2 * sizeof(int32_t), + "for srational double array"); if (m == NULL) { TIFFErrorExtR(tif, module, "Out of memory"); @@ -2653,7 +2756,7 @@ static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray( } for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++) { - DoubleToSrational(*na, &nb[0], &nb[1]); + DoubleToSrational((double)*na, &nb[0], &nb[1]); } if (tif->tif_flags & TIFF_SWAB) TIFFSwabArrayOfLong((uint32_t *)m, count * 2); @@ -2744,7 +2847,8 @@ static void ToRationalEuclideanGCD(double value, int blnUseSignedRange, *the double-value of it reaches an integer number without fractional part. */ bigDenom = 1; - while ((value != floor(value)) && (value < fMax) && (bigDenom < nMax)) + while ((!TIFF_DOUBLE_EQ(value, floor(value))) && (value < fMax) && + (bigDenom < nMax)) { bigDenom <<= 1; value *= 2; @@ -2836,7 +2940,7 @@ static void DoubleToRational(double value, uint32_t *num, uint32_t *denom) return; } /*-- Check for easy integer numbers -- */ - if (value == (uint32_t)(value)) + if (TIFF_DOUBLE_EQ(value, (double)(uint32_t)value)) { *num = (uint32_t)value; *denom = 1; @@ -2911,7 +3015,7 @@ static void DoubleToSrational(double value, int32_t *num, int32_t *denom) return; } /*-- Check for easy numbers -- */ - if (value == (int32_t)(value)) + if (TIFF_DOUBLE_EQ(value, (double)(int32_t)value)) { *num = (int32_t)(neg * value); *denom = 1; @@ -3231,6 +3335,14 @@ static int TIFFLinkDirectory(TIFF *tif) uint16_t dircount; uint32_t nextnextdir; + /* Update IDF loop list and check for IFD loop. + * ndir is IFD ID plus one. */ + if (!_TIFFCheckDirNumberAndOffset(tif, ndir - 1, nextdir)) + { + TIFFErrorExtR(tif, module, "Error IFD loop detected"); + return 0; /* bad offset (IFD looping or more than + TIFF_MAX_DIR_COUNT IFDs) */ + } if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount, 2)) { TIFFErrorExtR(tif, module, "Error fetching directory count"); @@ -3238,7 +3350,7 @@ static int TIFFLinkDirectory(TIFF *tif) } if (tif->tif_flags & TIFF_SWAB) TIFFSwabShort(&dircount); - (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET); + (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12U, SEEK_SET); if (!ReadOK(tif, &nextnextdir, 4)) { TIFFErrorExtR(tif, module, "Error fetching directory link"); @@ -3248,7 +3360,7 @@ static int TIFFLinkDirectory(TIFF *tif) TIFFSwabLong(&nextnextdir); if (nextnextdir == 0) { - (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET); + (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12U, SEEK_SET); if (!WriteOK(tif, &m, 4)) { TIFFErrorExtR(tif, module, "Error writing directory link"); @@ -3306,9 +3418,15 @@ static int TIFFLinkDirectory(TIFF *tif) while (1) { uint64_t dircount64; - uint16_t dircount; uint64_t nextnextdir; + /* Update IDF loop list and check for IFD loop. */ + if (!_TIFFCheckDirNumberAndOffset(tif, ndir - 1, nextdir)) + { + TIFFErrorExtR(tif, module, "Error IFD loop detected"); + return 0; /* bad offset (IFD looping or more than + TIFF_MAX_DIR_COUNT IFDs) */ + } if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount64, 8)) { TIFFErrorExtR(tif, module, "Error fetching directory count"); @@ -3323,8 +3441,7 @@ static int TIFFLinkDirectory(TIFF *tif) "likely corrupt TIFF"); return (0); } - dircount = (uint16_t)dircount64; - (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET); + (void)TIFFSeekFile(tif, nextdir + 8 + dircount64 * 20, SEEK_SET); if (!ReadOK(tif, &nextnextdir, 8)) { TIFFErrorExtR(tif, module, "Error fetching directory link"); @@ -3334,7 +3451,8 @@ static int TIFFLinkDirectory(TIFF *tif) TIFFSwabLong8(&nextnextdir); if (nextnextdir == 0) { - (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET); + (void)TIFFSeekFile(tif, nextdir + 8 + dircount64 * 20, + SEEK_SET); if (!WriteOK(tif, &m, 8)) { TIFFErrorExtR(tif, module, "Error writing directory link"); @@ -3475,7 +3593,7 @@ int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype, if (entry_tag == tag) break; - read_offset += dirsize; + read_offset += (uint64_t)dirsize; } if (entry_tag != tag) @@ -3584,13 +3702,13 @@ int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype, if (in_datatype == TIFF_LONG8 && (entry_type == TIFF_SHORT || entry_type == TIFF_LONG || entry_type == TIFF_LONG8)) - datatype = entry_type; + datatype = (TIFFDataType)entry_type; else if (in_datatype == TIFF_SLONG8 && (entry_type == TIFF_SLONG || entry_type == TIFF_SLONG8)) - datatype = entry_type; + datatype = (TIFFDataType)entry_type; else if (in_datatype == TIFF_IFD8 && (entry_type == TIFF_IFD || entry_type == TIFF_IFD8)) - datatype = entry_type; + datatype = (TIFFDataType)entry_type; else datatype = in_datatype; } @@ -3605,7 +3723,8 @@ int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype, return 0; if (datatype == in_datatype) - memcpy(buf_to_write, data, count * TIFFDataWidth(datatype)); + memcpy(buf_to_write, data, + (size_t)count * (size_t)TIFFDataWidth(datatype)); else if (datatype == TIFF_SLONG && in_datatype == TIFF_SLONG8) { tmsize_t i; @@ -3698,8 +3817,8 @@ int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype, 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; + tif->tif_dir.td_stripoffset_entry.tdir_type = (uint16_t)datatype; + tif->tif_dir.td_stripoffset_entry.tdir_count = (uint64_t)count; } else if ((tag == TIFFTAG_TILEBYTECOUNTS || tag == TIFFTAG_STRIPBYTECOUNTS) && @@ -3707,8 +3826,8 @@ int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype, 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; + tif->tif_dir.td_stripbytecount_entry.tdir_type = (uint16_t)datatype; + tif->tif_dir.td_stripbytecount_entry.tdir_count = (uint64_t)count; } /* -------------------------------------------------------------------- */ @@ -3756,13 +3875,14 @@ int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype, if (count * TIFFDataWidth(datatype) == 4) { uint32_t value; - memcpy(&value, buf_to_write, count * TIFFDataWidth(datatype)); + memcpy(&value, buf_to_write, + (size_t)count * (size_t)TIFFDataWidth(datatype)); entry_offset = value; } else { memcpy(&entry_offset, buf_to_write, - count * TIFFDataWidth(datatype)); + (size_t)count * (size_t)TIFFDataWidth(datatype)); } } @@ -3772,7 +3892,7 @@ int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype, /* -------------------------------------------------------------------- */ /* Adjust the directory entry. */ /* -------------------------------------------------------------------- */ - entry_type = datatype; + entry_type = (uint16_t)datatype; entry_count = (uint64_t)count; memcpy(direntry_raw + 2, &entry_type, sizeof(uint16_t)); if (tif->tif_flags & TIFF_SWAB) diff --git a/3rdparty/libtiff/tif_dumpmode.c b/3rdparty/libtiff/tif_dumpmode.c index 267d5d2d7a..4e3133f419 100644 --- a/3rdparty/libtiff/tif_dumpmode.c +++ b/3rdparty/libtiff/tif_dumpmode.c @@ -80,7 +80,7 @@ static int DumpModeDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) "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); + tif->tif_dir.td_row, tif->tif_rawcc, cc); return (0); } /* @@ -99,8 +99,23 @@ static int DumpModeDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) */ static int DumpModeSeek(TIFF *tif, uint32_t nrows) { - tif->tif_rawcp += nrows * tif->tif_scanlinesize; - tif->tif_rawcc -= nrows * tif->tif_scanlinesize; + tmsize_t seek_size; + if (nrows > 0 && + tif->tif_dir.td_scanlinesize > (tmsize_t)(TIFF_TMSIZE_T_MAX / nrows)) + { + TIFFErrorExtR(tif, "DumpModeSeek", + "Integer overflow computing seek size"); + return (0); + } + seek_size = (tmsize_t)nrows * tif->tif_dir.td_scanlinesize; + if (seek_size > tif->tif_rawcc) + { + TIFFErrorExtR(tif, "DumpModeSeek", + "Seek beyond end of raw data buffer"); + return (0); + } + tif->tif_rawcp += seek_size; + tif->tif_rawcc -= seek_size; return (1); } diff --git a/3rdparty/libtiff/tif_fax3.c b/3rdparty/libtiff/tif_fax3.c index 34e1c7882f..06b9508df5 100644 --- a/3rdparty/libtiff/tif_fax3.c +++ b/3rdparty/libtiff/tif_fax3.c @@ -123,7 +123,7 @@ typedef struct static const char module[] = mod; \ Fax3CodecState *sp = DecoderState(tif); \ int a0; /* reference element */ \ - int lastx = sp->b.rowpixels; /* last element in row */ \ + int lastx = (int)sp->b.rowpixels; /* last element in row */ \ uint32_t BitAcc; /* bit accumulator */ \ int BitsAvail; /* # valid bits in BitAcc */ \ int RunLength; /* length of current run */ \ @@ -209,61 +209,68 @@ static int Fax3PreDecode(TIFF *tif, uint16_t s) 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); + TIFFErrorExtR( + tif, module, + "Bad code word at line %" PRIu32 " of %s %" PRIu32 " (x %" PRIu32 ")", + line, isTiled(tif) ? "tile" : "strip", + (isTiled(tif) ? tif->tif_dir.td_curtile : tif->tif_dir.td_curstrip), + a0); } #define unexpected(table, a0) \ do \ { \ - Fax3Unexpected(module, tif, sp->line, a0); \ + Fax3Unexpected(module, tif, (uint32_t)sp->line, (uint32_t)(a0)); \ ++sp->unexpectedReachedCount; \ } while (0) 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); + TIFFErrorExtR( + tif, module, + "Uncompressed data (not supported) at line %" PRIu32 " of %s %" PRIu32 + " (x %" PRIu32 ")", + line, isTiled(tif) ? "tile" : "strip", + (isTiled(tif) ? tif->tif_dir.td_curtile : tif->tif_dir.td_curstrip), + a0); } -#define extension(a0) Fax3Extension(module, tif, sp->line, a0) +#define extension(a0) \ + Fax3Extension(module, tif, (uint32_t)sp->line, (uint32_t)(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); + 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_dir.td_curtile : tif->tif_dir.td_curstrip), a0, + lastx); } #define badlength(a0, lastx) \ do \ { \ - Fax3BadLength(module, tif, sp->line, a0, lastx); \ + Fax3BadLength(module, tif, (uint32_t)sp->line, (uint32_t)(a0), \ + (uint32_t)(lastx)); \ ++sp->eolReachedCount; \ } while (0) 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); + TIFFWarningExtR( + tif, module, + "Premature EOF at line %" PRIu32 " of %s %" PRIu32 " (x %" PRIu32 ")", + line, isTiled(tif) ? "tile" : "strip", + (isTiled(tif) ? tif->tif_dir.td_curtile : tif->tif_dir.td_curstrip), + a0); } #define prematureEOF(a0) \ do \ { \ - Fax3PrematureEOF(module, tif, sp->line, a0); \ + Fax3PrematureEOF(module, tif, (uint32_t)sp->line, (uint32_t)(a0)); \ ++sp->eofReachedCount; \ } while (0) @@ -275,16 +282,15 @@ static void Fax3TryG3WithoutEOL(const char *module, TIFF *tif, uint32_t line, "Try to decode (read) fax Group 3 data without EOL at line %" PRIu32 " of %s %" PRIu32 " (x %" PRIu32 "). Please check result", line, isTiled(tif) ? "tile" : "strip", - (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0); + (isTiled(tif) ? tif->tif_dir.td_curtile : tif->tif_dir.td_curstrip), + a0); } #define tryG3WithoutEOL(a0) \ do \ { \ - Fax3TryG3WithoutEOL(module, tif, sp->line, a0); \ + Fax3TryG3WithoutEOL(module, tif, (uint32_t)sp->line, (uint32_t)(a0)); \ } while (0) -#define Nop - static int CheckReachedCounters(TIFF *tif, const char *module, Fax3CodecState *sp) { @@ -344,12 +350,12 @@ RETRY_WITHOUT_EOL_1D: pa = thisrun; #ifdef FAX3_DEBUG printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d\n", BitAcc, BitsAvail); - printf("-------------------- %" PRIu32 "\n", tif->tif_row); + printf("-------------------- %" PRIu32 "\n", tif->tif_dir.td_row); fflush(stdout); #endif SYNC_EOL(EOF1D, RETRY_WITHOUT_EOL_1D); EXPAND1D(EOF1Da); - (*sp->fill)(buf, thisrun, pa, lastx); + (*sp->fill)(buf, thisrun, pa, (uint32_t)lastx); buf += sp->b.rowbytes; occ -= sp->b.rowbytes; sp->line++; @@ -357,7 +363,7 @@ RETRY_WITHOUT_EOL_1D: EOF1D: /* premature EOF */ CLEANUP_RUNS(); EOF1Da: /* premature EOF */ - (*sp->fill)(buf, thisrun, pa, lastx); + (*sp->fill)(buf, thisrun, pa, (uint32_t)lastx); UNCACHE_STATE(tif, sp); return (-1); } @@ -404,16 +410,16 @@ RETRY_WITHOUT_EOL_2D: ClrBits(1); #ifdef FAX3_DEBUG printf(" %s\n-------------------- %" PRIu32 "\n", is1D ? "1D" : "2D", - tif->tif_row); + tif->tif_dir.td_row); fflush(stdout); #endif pb = sp->refruns; - b1 = *pb++; + b1 = (int)*pb++; if (is1D) EXPAND1D(EOF2Da); else EXPAND2D(EOF2Da); - (*sp->fill)(buf, thisrun, pa, lastx); + (*sp->fill)(buf, thisrun, pa, (uint32_t)lastx); if (pa < thisrun + sp->nruns) { SETVALUE(0); /* imaginary change for reference */ @@ -426,7 +432,7 @@ RETRY_WITHOUT_EOL_2D: EOF2D: /* premature EOF */ CLEANUP_RUNS(); EOF2Da: /* premature EOF */ - (*sp->fill)(buf, thisrun, pa, lastx); + (*sp->fill)(buf, thisrun, pa, (uint32_t)lastx); UNCACHE_STATE(tif, sp); return (-1); } @@ -479,12 +485,12 @@ void _TIFFFax3fillruns(unsigned char *buf, uint32_t *runs, uint32_t *erun, { if (bx) { /* align to byte boundary */ - *cp++ &= 0xff << (8 - bx); + *cp++ &= (unsigned char)(0xff << (8 - bx)); run -= 8 - bx; } - if ((n = run >> 3) != 0) + if ((n = (int32_t)(run >> 3)) != 0) { /* multiple bytes to fill */ - if ((n / sizeof(int64_t)) > 1) + if (((size_t)n / sizeof(int64_t)) > 1) { /* * Align to int64_tword boundary and fill. @@ -492,8 +498,8 @@ void _TIFFFax3fillruns(unsigned char *buf, uint32_t *runs, uint32_t *erun, 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); + nw = (int32_t)((size_t)n / sizeof(int64_t)); + n -= (int32_t)((size_t)nw * sizeof(int64_t)); do { *lp++ = 0L; @@ -504,10 +510,10 @@ void _TIFFFax3fillruns(unsigned char *buf, uint32_t *runs, uint32_t *erun, run &= 7; } if (run) - cp[0] &= 0xff >> run; + cp[0] &= (unsigned char)(0xff >> run); } else - cp[0] &= ~(_fillmasks[run] >> bx); + cp[0] &= (unsigned char)~(_fillmasks[run] >> bx); x += runs[0]; } run = runs[1]; @@ -521,12 +527,12 @@ void _TIFFFax3fillruns(unsigned char *buf, uint32_t *runs, uint32_t *erun, { if (bx) { /* align to byte boundary */ - *cp++ |= 0xff >> bx; + *cp++ |= (unsigned char)(0xff >> bx); run -= 8 - bx; } - if ((n = run >> 3) != 0) + if ((n = (int32_t)(run >> 3)) != 0) { /* multiple bytes to fill */ - if ((n / sizeof(int64_t)) > 1) + if (((size_t)n / sizeof(int64_t)) > 1) { /* * Align to int64_t boundary and fill. @@ -534,8 +540,8 @@ void _TIFFFax3fillruns(unsigned char *buf, uint32_t *runs, uint32_t *erun, 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); + nw = (int32_t)((size_t)n / sizeof(int64_t)); + n -= (int32_t)((size_t)nw * sizeof(int64_t)); do { *lp++ = -1L; @@ -550,7 +556,7 @@ void _TIFFFax3fillruns(unsigned char *buf, uint32_t *runs, uint32_t *erun, cp[0] = (unsigned char)((cp[0] | (0xff00 >> run)) & 0xff); } else - cp[0] |= _fillmasks[run] >> bx; + cp[0] |= (unsigned char)(_fillmasks[run] >> bx); x += runs[1]; } } @@ -726,12 +732,13 @@ static const int _msbmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, { \ while (length > bit) \ { \ - data |= bits >> (length - bit); \ + data |= (int)((unsigned int)bits >> (length - bit)); \ length -= bit; \ _FlushBits(tif); \ } \ assert(length < 9); \ - data |= (bits & _msbmask[length]) << (bit - length); \ + data |= (int)(((unsigned int)bits & (unsigned int)_msbmask[length]) \ + << (unsigned int)(bit - length)); \ bit -= length; \ if (bit == 0) \ _FlushBits(tif); \ @@ -745,13 +752,13 @@ static const int _msbmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, static int Fax3PutBits(TIFF *tif, unsigned int bits, unsigned int length) { Fax3CodecState *sp = EncoderState(tif); - unsigned int bit = sp->bit; - int data = sp->data; + unsigned int bit = (unsigned int)sp->bit; + int data = (int)sp->data; _PutBits(tif, bits, length); - sp->data = data; - sp->bit = bit; + sp->data = (uint32_t)data; + sp->bit = (int)bit; return 1; } @@ -782,8 +789,8 @@ static int Fax3PutBits(TIFF *tif, unsigned int bits, unsigned int length) 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 bit = (unsigned int)sp->bit; + int data = (int)sp->data; unsigned int code, length; while (span >= 2624) @@ -816,8 +823,8 @@ static int putspan(TIFF *tif, int32_t span, const tableentry *tab) #endif _PutBits(tif, code, length); - sp->data = data; - sp->bit = bit; + sp->data = (uint32_t)data; + sp->bit = (int)bit; return 1; } @@ -831,8 +838,8 @@ static int putspan(TIFF *tif, int32_t span, const tableentry *tab) static int Fax3PutEOL(TIFF *tif) { Fax3CodecState *sp = EncoderState(tif); - unsigned int bit = sp->bit; - int data = sp->data; + unsigned int bit = (unsigned int)sp->bit; + int data = (int)sp->data; unsigned int code, length, tparm; if (sp->b.groupoptions & GROUP3OPT_FILLBITS) @@ -849,7 +856,7 @@ static int Fax3PutEOL(TIFF *tif) align = sp->bit + (8 - align); else align = sp->bit - align; - tparm = align; + tparm = (unsigned int)align; _PutBits(tif, 0, tparm); } } @@ -862,8 +869,8 @@ static int Fax3PutEOL(TIFF *tif) } _PutBits(tif, code, length); - sp->data = data; - sp->bit = bit; + sp->data = (uint32_t)data; + sp->bit = (int)bit; return 1; } @@ -991,10 +998,10 @@ static inline int32_t find0span(unsigned char *bp, int32_t bs, int32_t be) bp++; } lp = (int64_t *)bp; - while ((bits >= (int32_t)(8 * sizeof(int64_t))) && (0 == *lp)) + while ((bits >= (int32_t)(size_t)(8 * sizeof(int64_t))) && (0 == *lp)) { - span += 8 * sizeof(int64_t); - bits -= 8 * sizeof(int64_t); + span += (int32_t)(size_t)(8 * sizeof(int64_t)); + bits -= (int32_t)(size_t)(8 * sizeof(int64_t)); lp++; } bp = (unsigned char *)lp; @@ -1059,11 +1066,11 @@ static inline int32_t find1span(unsigned char *bp, int32_t bs, int32_t be) bp++; } lp = (int64_t *)bp; - while ((bits >= (int32_t)(8 * sizeof(int64_t))) && + while ((bits >= (int32_t)(size_t)(8 * sizeof(int64_t))) && (~((uint64_t)0) == (uint64_t)*lp)) { - span += 8 * sizeof(int64_t); - bits -= 8 * sizeof(int64_t); + span += (int32_t)(size_t)(8 * sizeof(int64_t)); + bits -= (int32_t)(size_t)(8 * sizeof(int64_t)); lp++; } bp = (unsigned char *)lp; @@ -1118,16 +1125,16 @@ static int Fax3Encode1DRow(TIFF *tif, unsigned char *bp, uint32_t bits) for (;;) { - span = find0span(bp, bs, bits); /* white span */ + span = find0span(bp, (int32_t)bs, (int32_t)bits); /* white span */ if (!putspan(tif, span, TIFFFaxWhiteCodes)) return 0; - bs += span; + bs += (uint32_t)span; if (bs >= bits) break; - span = find1span(bp, bs, bits); /* black span */ + span = find1span(bp, (int32_t)bs, (int32_t)bits); /* black span */ if (!putspan(tif, span, TIFFFaxBlackCodes)) return 0; - bs += span; + bs += (uint32_t)span; if (bs >= bits) break; } @@ -1161,15 +1168,20 @@ static const tableentry vcodes[7] = { 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) +#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 a1 = (PIXEL(bp, 0) != 0 + ? 0 + : (uint32_t)finddiff(bp, (int32_t)0, (int32_t)bits, 0)); + uint32_t b1 = (PIXEL(rp, 0) != 0 + ? 0 + : (uint32_t)finddiff(rp, (int32_t)0, (int32_t)bits, 0)); uint32_t a2, b2; for (;;) { - b2 = finddiff2(rp, b1, bits, PIXEL(rp, b1)); + b2 = (uint32_t)finddiff2(rp, (int32_t)b1, (int32_t)bits, + (int32_t)PIXEL(rp, b1)); if (b2 >= a1) { /* Naive computation triggers @@ -1182,21 +1194,22 @@ static int Fax3Encode2DRow(TIFF *tif, unsigned char *bp, unsigned char *rp, : 0x7FFFFFFF; if (!(-3 <= d && d <= 3)) { /* horizontal mode */ - a2 = finddiff2(bp, a1, bits, PIXEL(bp, a1)); + a2 = (uint32_t)finddiff2(bp, (int32_t)a1, (int32_t)bits, + (int32_t)PIXEL(bp, a1)); if (!putcode(tif, &horizcode)) return 0; if (a0 + a1 == 0 || PIXEL(bp, a0) == 0) { - if (!putspan(tif, a1 - a0, TIFFFaxWhiteCodes)) + if (!putspan(tif, (int32_t)(a1 - a0), TIFFFaxWhiteCodes)) return 0; - if (!putspan(tif, a2 - a1, TIFFFaxBlackCodes)) + if (!putspan(tif, (int32_t)(a2 - a1), TIFFFaxBlackCodes)) return 0; } else { - if (!putspan(tif, a1 - a0, TIFFFaxBlackCodes)) + if (!putspan(tif, (int32_t)(a1 - a0), TIFFFaxBlackCodes)) return 0; - if (!putspan(tif, a2 - a1, TIFFFaxWhiteCodes)) + if (!putspan(tif, (int32_t)(a2 - a1), TIFFFaxWhiteCodes)) return 0; } a0 = a2; @@ -1216,9 +1229,12 @@ static int Fax3Encode2DRow(TIFF *tif, unsigned char *bp, unsigned char *rp, } 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)); + a1 = (uint32_t)finddiff(bp, (int32_t)a0, (int32_t)bits, + (int32_t)PIXEL(bp, a0)); + b1 = (uint32_t)finddiff(rp, (int32_t)a0, (int32_t)bits, + (int32_t)!PIXEL(bp, a0)); + b1 = (uint32_t)finddiff(rp, (int32_t)b1, (int32_t)bits, + (int32_t)PIXEL(bp, a0)); } return (1); #undef PIXEL @@ -1487,6 +1503,8 @@ static void Fax3PrintDir(TIFF *tif, FILE *fd, long flags) case CLEANFAXDATA_UNCLEAN: fprintf(fd, " uncorrected errors"); break; + default: + break; } fprintf(fd, " (%" PRIu16 " = 0x%" PRIx16 ")\n", sp->cleanfaxdata, sp->cleanfaxdata); @@ -1500,6 +1518,22 @@ static void Fax3PrintDir(TIFF *tif, FILE *fd, long flags) (*sp->printdir)(tif, fd, flags); } +static uint64_t Fax3GetMaxCompressionRatio(TIFF *tif) +{ + (void)tif; + + /* See README_for_libtiff_developpers.md for raw data used to estimate + * the maximum compression rate. */ + + /* 1024x1024: 36 */ + /* 4096x4096: 100 */ + /* 16383x16383: 163 */ + /* 65536x65536: 200 */ + /* 200000x200000: 208 */ + + return 250; +} + static int InitCCITTFax3(TIFF *tif) { static const char module[] = "InitCCITTFax3"; @@ -1564,6 +1598,7 @@ static int InitCCITTFax3(TIFF *tif) tif->tif_encodetile = Fax3Encode; tif->tif_close = Fax3Close; tif->tif_cleanup = Fax3Cleanup; + tif->tif_getmaxcompressionratio = Fax3GetMaxCompressionRatio; return (1); } @@ -1626,10 +1661,10 @@ static int Fax4Decode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) RunLength = 0; pa = thisrun = sp->curruns; pb = sp->refruns; - b1 = *pb++; + b1 = (int)*pb++; #ifdef FAX3_DEBUG printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d\n", BitAcc, BitsAvail); - printf("-------------------- %d\n", tif->tif_row); + printf("-------------------- %d\n", tif->tif_dir.td_row); fflush(stdout); #endif EXPAND2D(EOFG4); @@ -1643,7 +1678,7 @@ static int Fax4Decode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) occ, lastx); return -1; } - (*sp->fill)(buf, thisrun, pa, lastx); + (*sp->fill)(buf, thisrun, pa, (uint32_t)lastx); SETVALUE(0); /* imaginary change for reference */ SWAP(uint32_t *, sp->curruns, sp->refruns); buf += sp->b.rowbytes; @@ -1666,7 +1701,7 @@ static int Fax4Decode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) occ, lastx); return -1; } - (*sp->fill)(buf, thisrun, pa, lastx); + (*sp->fill)(buf, thisrun, pa, (uint32_t)lastx); UNCACHE_STATE(tif, sp); return (sp->line != start ? 1 @@ -1713,6 +1748,16 @@ static int Fax4PostEncode(TIFF *tif) return (1); } +static uint64_t Fax4GetMaxCompressionRatio(TIFF *tif) +{ + /* FAX4 can compress up to almost one byte per line, so the compression + * ratio can be up to the tile/strip width. + * See README_for_libtiff_developpers.md for raw data + */ + return isTiled(tif) ? tif->tif_dir.td_tilewidth + : tif->tif_dir.td_imagewidth; +} + int TIFFInitCCITTFax4(TIFF *tif, int scheme) { (void)scheme; @@ -1735,6 +1780,7 @@ int TIFFInitCCITTFax4(TIFF *tif, int scheme) tif->tif_encodestrip = Fax4Encode; tif->tif_encodetile = Fax4Encode; tif->tif_postencode = Fax4PostEncode; + tif->tif_getmaxcompressionratio = Fax4GetMaxCompressionRatio; /* * Suppress RTC at the end of each strip. */ @@ -1773,11 +1819,11 @@ static int Fax3DecodeRLE(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) pa = thisrun; #ifdef FAX3_DEBUG printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d\n", BitAcc, BitsAvail); - printf("-------------------- %" PRIu32 "\n", tif->tif_row); + printf("-------------------- %" PRIu32 "\n", tif->tif_dir.td_row); fflush(stdout); #endif EXPAND1D(EOFRLE); - (*sp->fill)(buf, thisrun, pa, lastx); + (*sp->fill)(buf, thisrun, pa, (uint32_t)lastx); /* * Cleanup at the end of the row. */ @@ -1798,7 +1844,7 @@ static int Fax3DecodeRLE(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) sp->line++; continue; EOFRLE: /* premature EOF */ - (*sp->fill)(buf, thisrun, pa, lastx); + (*sp->fill)(buf, thisrun, pa, (uint32_t)lastx); UNCACHE_STATE(tif, sp); return (-1); } @@ -1806,6 +1852,21 @@ static int Fax3DecodeRLE(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) return (1); } +static uint64_t Fax3RLEGetMaxCompressionRatio(TIFF *tif) +{ + (void)tif; + /* See README_for_libtiff_developpers.md for raw data used to estimate + * the maximum compression rate. */ + + /* 1024x1024: 43 */ + /* 4096x4096: 128 */ + /* 16383x16383: 171 */ + /* 65536x65536: 205 */ + /* 200000x200000: 211 */ + + return 250; +} + int TIFFInitCCITTRLE(TIFF *tif, int scheme) { (void)scheme; @@ -1814,6 +1875,7 @@ int TIFFInitCCITTRLE(TIFF *tif, int scheme) tif->tif_decoderow = Fax3DecodeRLE; tif->tif_decodestrip = Fax3DecodeRLE; tif->tif_decodetile = Fax3DecodeRLE; + tif->tif_getmaxcompressionratio = Fax3RLEGetMaxCompressionRatio; /* * Suppress RTC+EOLs when encoding and byte-align data. */ @@ -1832,6 +1894,7 @@ int TIFFInitCCITTRLEW(TIFF *tif, int scheme) tif->tif_decoderow = Fax3DecodeRLE; tif->tif_decodestrip = Fax3DecodeRLE; tif->tif_decodetile = Fax3DecodeRLE; + tif->tif_getmaxcompressionratio = Fax3RLEGetMaxCompressionRatio; /* * Suppress RTC+EOLs when encoding and word-align data. */ diff --git a/3rdparty/libtiff/tif_fax3.h b/3rdparty/libtiff/tif_fax3.h index c3100ce2c6..60d709c7e5 100644 --- a/3rdparty/libtiff/tif_fax3.h +++ b/3rdparty/libtiff/tif_fax3.h @@ -267,14 +267,14 @@ static const char *StateNames[] = { { \ if (pa >= thisrun + sp->nruns) \ { \ - TIFFErrorExtR(tif, module, "Buffer overflow at line %u of %s %u", \ + TIFFErrorExtR(tif, module, "Buffer overflow at line %d of %s %u", \ sp->line, isTiled(tif) ? "tile" : "strip", \ - isTiled(tif) ? tif->tif_curtile \ - : tif->tif_curstrip); \ + isTiled(tif) ? tif->tif_dir.td_curtile \ + : tif->tif_dir.td_curstrip); \ return (-1); \ } \ - *pa++ = RunLength + (x); \ - a0 += (x); \ + *pa++ = (uint32_t)((uint32_t)RunLength + (uint32_t)(x)); \ + a0 += (int)(uint32_t)(x); \ RunLength = 0; \ } while (0) #endif @@ -334,20 +334,20 @@ static const char *StateNames[] = { { \ if (RunLength) \ SETVALUE(0); \ - if (a0 != lastx) \ + if (a0 != (int)lastx) \ { \ badlength(a0, lastx); \ - while (a0 > lastx && pa > thisrun) \ - a0 -= *--pa; \ - if (a0 < lastx) \ + while (a0 > (int)lastx && pa > thisrun) \ + a0 -= (int)*--pa; \ + if (a0 < (int)lastx) \ { \ if (a0 < 0) \ a0 = 0; \ if ((pa - thisrun) & 1) \ SETVALUE(0); \ - SETVALUE(lastx - a0); \ + SETVALUE((uint32_t)((int)lastx - a0)); \ } \ - else if (a0 > lastx) \ + else if (a0 > (int)lastx) \ { \ SETVALUE(lastx); \ SETVALUE(0); \ @@ -385,8 +385,9 @@ static const char *StateNames[] = { goto doneWhite1d; \ case S_MakeUpW: \ case S_MakeUp: \ - a0 += TabEnt->Param; \ - RunLength += TabEnt->Param; \ + a0 = (int)((uint32_t)a0 + TabEnt->Param); \ + RunLength = \ + (int)((uint32_t)RunLength + TabEnt->Param); \ break; \ default: \ unexpected("WhiteTable", a0); \ @@ -394,7 +395,7 @@ static const char *StateNames[] = { } \ } \ doneWhite1d: \ - if (a0 >= lastx) \ + if (a0 >= (int)lastx) \ goto done1d; \ for (;;) \ { \ @@ -409,8 +410,8 @@ static const char *StateNames[] = { goto doneBlack1d; \ case S_MakeUpB: \ case S_MakeUp: \ - a0 += TabEnt->Param; \ - RunLength += TabEnt->Param; \ + a0 += (int)TabEnt->Param; \ + RunLength += (int)TabEnt->Param; \ break; \ default: \ unexpected("BlackTable", a0); \ @@ -418,7 +419,7 @@ static const char *StateNames[] = { } \ } \ doneBlack1d: \ - if (a0 >= lastx) \ + if (a0 >= (int)lastx) \ goto done1d; \ if (*(pa - 1) == 0 && *(pa - 2) == 0) \ pa -= 2; \ @@ -439,17 +440,18 @@ static const char *StateNames[] = { do \ { \ if (pa != thisrun) \ - while (b1 <= a0 && b1 < lastx) \ + while (b1 <= a0 && b1 < (int)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); \ + TIFFErrorExtR(tif, module, \ + "Buffer overflow at line %d of %s %u", \ + sp->line, isTiled(tif) ? "tile" : "strip", \ + isTiled(tif) ? tif->tif_dir.td_curtile \ + : tif->tif_dir.td_curstrip); \ return (-1); \ } \ - b1 += pb[0] + pb[1]; \ + b1 += (int)(pb[0] + pb[1]); \ pb += 2; \ } \ } while (0) @@ -460,14 +462,15 @@ static const char *StateNames[] = { #define EXPAND2D(eoflab) \ do \ { \ - while (a0 < lastx) \ + while (a0 < (int)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); \ + TIFFErrorExtR(tif, module, \ + "Buffer overflow at line %d of %s %u", sp->line, \ + isTiled(tif) ? "tile" : "strip", \ + isTiled(tif) ? tif->tif_dir.td_curtile \ + : tif->tif_dir.td_curstrip); \ return (-1); \ } \ LOOKUP8(7, TIFFFaxMainTable, eof2d); \ @@ -477,18 +480,19 @@ static const char *StateNames[] = { 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); \ + TIFFErrorExtR( \ + tif, module, \ + "Buffer overflow at line %d of %s %u", sp->line, \ + isTiled(tif) ? "tile" : "strip", \ + isTiled(tif) ? tif->tif_dir.td_curtile \ + : tif->tif_dir.td_curstrip); \ return (-1); \ } \ - b1 += *pb++; \ - RunLength += b1 - a0; \ + b1 = b1 + (int)*pb++; \ + RunLength = \ + (int)((uint32_t)RunLength + (uint32_t)(b1 - a0)); \ a0 = b1; \ - b1 += *pb++; \ + b1 = b1 + (int)*pb++; \ break; \ case S_Horiz: \ if ((pa - thisrun) & 1) \ @@ -503,8 +507,9 @@ static const char *StateNames[] = { goto doneWhite2da; \ case S_MakeUpB: \ case S_MakeUp: \ - a0 += TabEnt->Param; \ - RunLength += TabEnt->Param; \ + a0 = (int)((uint32_t)a0 + TabEnt->Param); \ + RunLength = (int)((uint32_t)RunLength + \ + TabEnt->Param); \ break; \ default: \ goto badBlack2d; \ @@ -521,8 +526,9 @@ static const char *StateNames[] = { goto doneBlack2da; \ case S_MakeUpW: \ case S_MakeUp: \ - a0 += TabEnt->Param; \ - RunLength += TabEnt->Param; \ + a0 = (int)((uint32_t)a0 + TabEnt->Param); \ + RunLength = (int)((uint32_t)RunLength + \ + TabEnt->Param); \ break; \ default: \ goto badWhite2d; \ @@ -542,8 +548,9 @@ static const char *StateNames[] = { goto doneWhite2db; \ case S_MakeUpW: \ case S_MakeUp: \ - a0 += TabEnt->Param; \ - RunLength += TabEnt->Param; \ + a0 = (int)((uint32_t)a0 + TabEnt->Param); \ + RunLength = (int)((uint32_t)RunLength + \ + TabEnt->Param); \ break; \ default: \ goto badWhite2d; \ @@ -560,8 +567,9 @@ static const char *StateNames[] = { goto doneBlack2db; \ case S_MakeUpB: \ case S_MakeUp: \ - a0 += TabEnt->Param; \ - RunLength += TabEnt->Param; \ + a0 = (int)((uint32_t)a0 + TabEnt->Param); \ + RunLength = (int)((uint32_t)RunLength + \ + TabEnt->Param); \ break; \ default: \ goto badBlack2d; \ @@ -576,47 +584,47 @@ static const char *StateNames[] = { 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); \ + TIFFErrorExtR( \ + tif, module, \ + "Buffer overflow at line %d of %s %u", sp->line, \ + isTiled(tif) ? "tile" : "strip", \ + isTiled(tif) ? tif->tif_dir.td_curtile \ + : tif->tif_dir.td_curstrip); \ return (-1); \ } \ - b1 += *pb++; \ + b1 = b1 + (int)*pb++; \ break; \ case S_VR: \ CHECK_b1; \ - SETVALUE(b1 - a0 + TabEnt->Param); \ + SETVALUE((int)((uint32_t)(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); \ + TIFFErrorExtR( \ + tif, module, \ + "Buffer overflow at line %d of %s %u", sp->line, \ + isTiled(tif) ? "tile" : "strip", \ + isTiled(tif) ? tif->tif_dir.td_curtile \ + : tif->tif_dir.td_curstrip); \ return (-1); \ } \ - b1 += *pb++; \ + b1 = b1 + (int)*pb++; \ break; \ case S_VL: \ CHECK_b1; \ - if (b1 < (int)(a0 + TabEnt->Param)) \ + if (b1 < (int)((uint32_t)a0 + TabEnt->Param)) \ { \ unexpected("VL", a0); \ goto eol2d; \ } \ - SETVALUE(b1 - a0 - TabEnt->Param); \ - b1 -= *--pb; \ + SETVALUE((int)((uint32_t)(b1 - a0) - TabEnt->Param)); \ + b1 = b1 - (int)*--pb; \ break; \ case S_Ext: \ - *pa++ = lastx - a0; \ + *pa++ = (uint32_t)((int)lastx - a0); \ extension(a0); \ goto eol2d; \ case S_EOL: \ - *pa++ = lastx - a0; \ + *pa++ = (uint32_t)((int)lastx - a0); \ NeedBits8(4, eof2d); \ if (GetBits(4)) \ unexpected("EOL", a0); \ diff --git a/3rdparty/libtiff/tif_getimage.c b/3rdparty/libtiff/tif_getimage.c index 9d4259ef83..4a759a6548 100644 --- a/3rdparty/libtiff/tif_getimage.c +++ b/3rdparty/libtiff/tif_getimage.c @@ -29,6 +29,7 @@ */ #include "tiffiop.h" #include +#include #include static int gtTileContig(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t); @@ -57,21 +58,21 @@ static const char photoTag[] = "PhotometricInterpretation"; 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 */ + {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 */ + 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 */ }; /* @@ -316,7 +317,7 @@ int TIFFRGBAImageBegin(TIFFRGBAImage *img, TIFF *tif, int stop, uint16_t compress; int colorchannels; uint16_t *red_orig, *green_orig, *blue_orig; - int n_color; + uint32_t n_color; if (!TIFFRGBAImageOK(tif, emsg)) return 0; @@ -372,6 +373,8 @@ int TIFFRGBAImageBegin(TIFFRGBAImage *img, TIFF *tif, int stop, case EXTRASAMPLE_UNASSALPHA: /* data is not pre-multiplied */ img->alpha = sampleinfo[0]; break; + default: + break; } } @@ -421,13 +424,13 @@ int TIFFRGBAImageBegin(TIFFRGBAImage *img, TIFF *tif, int stop, } /* 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); + n_color = (uint32_t)(1U << img->bitspersample); + img->redcmap = (uint16_t *)_TIFFmallocExt( + tif, (tmsize_t)(sizeof(uint16_t) * (size_t)n_color)); + img->greencmap = (uint16_t *)_TIFFmallocExt( + tif, (tmsize_t)(sizeof(uint16_t) * (size_t)n_color)); + img->bluecmap = (uint16_t *)_TIFFmallocExt( + tif, (tmsize_t)(sizeof(uint16_t) * (size_t)n_color)); if (!img->redcmap || !img->greencmap || !img->bluecmap) { snprintf(emsg, EMSG_BUF_SIZE, @@ -604,7 +607,7 @@ int TIFFRGBAImageGet(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, * Width is checked in img->get() function individually. */ if (0 <= img->row_offset && (uint32_t)img->row_offset < img->height) { - uint32_t hx = img->height - img->row_offset; + uint32_t hx = img->height - (uint32_t)img->row_offset; if (h > hx) { /* Adapt parameters to read only available lines and put image @@ -617,7 +620,7 @@ int TIFFRGBAImageGet(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, { TIFFErrorExtR(img->tif, TIFFFileName(img->tif), "Error in TIFFRGBAImageGet: row offset %d exceeds " - "image height %d", + "image height %u", img->row_offset, img->height); return 0; } @@ -751,13 +754,13 @@ static int gtTileContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, if (0 <= img->col_offset && (uint32_t)img->col_offset < img->width) { - wmin = TIFFmin(w, img->width - img->col_offset); + wmin = TIFFmin(w, img->width - (uint32_t)img->col_offset); } else { TIFFErrorExtR(tif, TIFFFileName(tif), "Error in gtTileContig: column offset %d exceeds " - "image width %d", + "image width %u", img->col_offset, img->width); return 0; } @@ -785,7 +788,7 @@ static int gtTileContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, } else { - if (tw > ((int64_t)INT_MAX + w)) + if (tw > ((int64_t)INT_MAX + w) || w > ((int64_t)INT_MAX + tw)) { TIFFErrorExtR(tif, TIFFFileName(tif), "%s", "unsupported tile size (too wide)"); @@ -804,9 +807,9 @@ static int gtTileContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, /* * Leftmost tile is clipped on left side if col_offset > 0. */ - leftmost_fromskew = img->col_offset % tw; - leftmost_tw = tw - leftmost_fromskew; - int64_t skew_i64 = (int64_t)toskew + leftmost_fromskew; + leftmost_fromskew = (int32_t)((uint32_t)img->col_offset % tw); + leftmost_tw = (uint32_t)((int32_t)tw - leftmost_fromskew); + int64_t skew_i64 = (int64_t)toskew + (int64_t)(int32_t)leftmost_fromskew; if (skew_i64 > INT_MAX || skew_i64 < INT_MIN) { TIFFErrorExtR(tif, TIFFFileName(tif), "%s %" PRId64, "Invalid skew", @@ -816,34 +819,36 @@ static int gtTileContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, leftmost_toskew = (int32_t)skew_i64; for (row = 0; ret != 0 && row < h; row += nrow) { - rowstoread = th - (row + img->row_offset) % th; + rowstoread = th - ((uint32_t)row + (uint32_t)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; + col = (uint32_t)img->col_offset; /* wmin: only write imagewidth if raster is bigger. */ while (tocol < wmin) { if (_TIFFReadTileAndAllocBuffer(tif, (void **)&buf, bufsize, col, - row + img->row_offset, 0, - 0) == (tmsize_t)(-1) && + (uint32_t)row + + (uint32_t)img->row_offset, + 0, 0) == (tmsize_t)(-1) && (buf == NULL || img->stoponerr)) { ret = 0; break; } - pos = ((row + img->row_offset) % th) * TIFFTileRowSize(tif) + + pos = (((uint32_t)row + (uint32_t)img->row_offset) % th) * + TIFFTileRowSize(tif) + ((tmsize_t)fromskew * img->samplesperpixel); if (tocol + this_tw > wmin) { /* * Rightmost tile is clipped on right side. */ - fromskew = tw - (wmin - tocol); - this_tw = tw - fromskew; - this_toskew = toskew + fromskew; + fromskew = (int32_t)(tw - (wmin - tocol)); + this_tw = (uint32_t)((int32_t)tw - fromskew); + this_toskew = (int32_t)(toskew + (int32_t)(uint32_t)fromskew); } tmsize_t roffset = (tmsize_t)y * w + tocol; (*put)(img, raster + roffset, tocol, y, this_tw, nrow, fromskew, @@ -859,7 +864,8 @@ static int gtTileContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, this_toskew = toskew; } - y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow); + y += (uint32_t)((flip & FLIP_VERTICALLY) ? -(int32_t)nrow + : (int32_t)nrow); } _TIFFfreeExt(img->tif, buf); @@ -869,7 +875,7 @@ static int gtTileContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, for (line = 0; line < h; line++) { - uint32_t *left = raster + (line * w); + uint32_t *left = raster + (size_t)line * w; /* Use wmin to only flip horizontally data in place and not complete * raster-row. */ uint32_t *right = left + wmin - 1; @@ -924,13 +930,13 @@ static int gtTileSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, uint32_t wmin; if (0 <= img->col_offset && (uint32_t)img->col_offset < img->width) { - wmin = TIFFmin(w, img->width - img->col_offset); + wmin = TIFFmin(w, img->width - (uint32_t)img->col_offset); } else { TIFFErrorExtR(tif, TIFFFileName(tif), "Error in gtTileSeparate: column offset %d exceeds " - "image width %d", + "image width %u", img->col_offset, img->width); return 0; } @@ -960,7 +966,7 @@ static int gtTileSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, } else { - if (tw > ((int64_t)INT_MAX + w)) + if (tw > ((int64_t)INT_MAX + w) || w > ((int64_t)INT_MAX + tw)) { TIFFErrorExtR(tif, TIFFFileName(tif), "%s", "unsupported tile size (too wide)"); @@ -992,9 +998,9 @@ static int gtTileSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, /* * Leftmost tile is clipped on left side if col_offset > 0. */ - leftmost_fromskew = img->col_offset % tw; - leftmost_tw = tw - leftmost_fromskew; - int64_t skew_i64 = (int64_t)toskew + leftmost_fromskew; + leftmost_fromskew = (int32_t)((uint32_t)img->col_offset % tw); + leftmost_tw = (uint32_t)((int32_t)tw - leftmost_fromskew); + int64_t skew_i64 = (int64_t)toskew + (int64_t)(int32_t)leftmost_fromskew; if (skew_i64 > INT_MAX || skew_i64 < INT_MIN) { TIFFErrorExtR(tif, TIFFFileName(tif), "%s %" PRId64, "Invalid skew", @@ -1004,21 +1010,22 @@ static int gtTileSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, leftmost_toskew = (int32_t)skew_i64; for (row = 0; ret != 0 && row < h; row += nrow) { - rowstoread = th - (row + img->row_offset) % th; + rowstoread = th - ((uint32_t)row + (uint32_t)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; + col = (uint32_t)img->col_offset; /* wmin: only write imagewidth if raster is bigger. */ while (tocol < wmin) { if (buf == NULL) { - if (_TIFFReadTileAndAllocBuffer(tif, (void **)&buf, bufsize, - col, row + img->row_offset, 0, - 0) == (tmsize_t)(-1) && + if (_TIFFReadTileAndAllocBuffer( + tif, (void **)&buf, bufsize, col, + (uint32_t)((int32_t)row + img->row_offset), 0, + 0) == (tmsize_t)(-1) && (buf == NULL || img->stoponerr)) { ret = 0; @@ -1037,32 +1044,36 @@ static int gtTileSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, pa = (alpha ? (p2 + tilesize) : NULL); } } - else if (TIFFReadTile(tif, p0, col, row + img->row_offset, 0, 0) == - (tmsize_t)(-1) && + else if (TIFFReadTile(tif, p0, col, + (uint32_t)((int32_t)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) && + TIFFReadTile(tif, p1, col, + (uint32_t)((int32_t)row + img->row_offset), 0, + (uint16_t)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) && + TIFFReadTile(tif, p2, col, + (uint32_t)((int32_t)row + img->row_offset), 0, + (uint16_t)2) == (tmsize_t)(-1) && img->stoponerr) { ret = 0; break; } if (alpha && - TIFFReadTile(tif, pa, col, row + img->row_offset, 0, - colorchannels) == (tmsize_t)(-1) && + TIFFReadTile(tif, pa, col, + (uint32_t)((int32_t)row + img->row_offset), 0, + (uint16_t)colorchannels) == (tmsize_t)(-1) && img->stoponerr) { ret = 0; @@ -1071,16 +1082,17 @@ static int gtTileSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, /* For SEPARATE the pos-offset is per sample and should not be * multiplied by img->samplesperpixel. */ - pos = ((row + img->row_offset) % th) * TIFFTileRowSize(tif) + + pos = (tmsize_t)((uint32_t)((int32_t)row + img->row_offset) % th) * + TIFFTileRowSize(tif) + (tmsize_t)fromskew; if (tocol + this_tw > wmin) { /* * Rightmost tile is clipped on right side. */ - fromskew = tw - (wmin - tocol); - this_tw = tw - fromskew; - this_toskew = toskew + fromskew; + fromskew = (int32_t)(tw - (wmin - tocol)); + this_tw = (uint32_t)((int32_t)tw - fromskew); + this_toskew = (int32_t)(toskew + (int32_t)(uint32_t)fromskew); } tmsize_t roffset = (tmsize_t)y * w + tocol; (*put)(img, raster + roffset, tocol, y, this_tw, nrow, fromskew, @@ -1097,7 +1109,8 @@ static int gtTileSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, this_toskew = toskew; } - y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow); + y += (uint32_t)((flip & FLIP_VERTICALLY) ? -(int32_t)nrow + : (int32_t)nrow); } if (flip & FLIP_HORIZONTALLY) @@ -1106,7 +1119,7 @@ static int gtTileSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, for (line = 0; line < h; line++) { - uint32_t *left = raster + (line * w); + uint32_t *left = raster + (size_t)line * w; /* Use wmin to only flip horizontally data in place and not complete * raster-row. */ uint32_t *right = left + wmin - 1; @@ -1155,13 +1168,13 @@ static int gtStripContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, uint32_t wmin; if (0 <= img->col_offset && (uint32_t)img->col_offset < imagewidth) { - wmin = TIFFmin(w, imagewidth - img->col_offset); + wmin = TIFFmin(w, imagewidth - (uint32_t)img->col_offset); } else { TIFFErrorExtR(tif, TIFFFileName(tif), "Error in gtStripContig: column offset %d exceeds " - "image width %d", + "image width %u", img->col_offset, imagewidth); return 0; } @@ -1195,7 +1208,7 @@ static int gtStripContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, y = 0; /* Skew forward to the end of the raster width of the row currently * copied. */ - toskew = w - wmin; + toskew = (int32_t)(w - wmin); } TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); @@ -1206,16 +1219,18 @@ static int gtStripContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, } scanline = TIFFScanlineSize(tif); - fromskew = (w < imagewidth ? imagewidth - w : 0); + fromskew = (int32_t)(w < imagewidth ? imagewidth - w : 0); for (row = 0; row < h; row += nrow) { uint32_t temp; - rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip; + rowstoread = rowsperstrip - + (uint32_t)((int32_t)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; + temp = + (uint32_t)((int32_t)row + img->row_offset) % rowsperstrip + nrowsub; if (scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline)) { TIFFErrorExtR(tif, TIFFFileName(tif), @@ -1223,21 +1238,27 @@ static int gtStripContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, return 0; } if (_TIFFReadEncodedStripAndAllocBuffer( - tif, TIFFComputeStrip(tif, row + img->row_offset, 0), + tif, + TIFFComputeStrip(tif, + (uint32_t)((int32_t)row + img->row_offset), 0), (void **)(&buf), maxstripsize, - temp * scanline) == (tmsize_t)(-1) && + (tmsize_t)((size_t)temp * (size_t)scanline)) == + (tmsize_t)(-1) && (buf == NULL || img->stoponerr)) { ret = 0; break; } - pos = ((row + img->row_offset) % rowsperstrip) * scanline + + pos = (tmsize_t)((uint32_t)((int32_t)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, wmin, nrow, fromskew, toskew, buf + pos); - y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow); + y += (uint32_t)((flip & FLIP_VERTICALLY) ? -(int32_t)nrow + : (int32_t)nrow); } if (flip & FLIP_HORIZONTALLY) @@ -1250,7 +1271,7 @@ static int gtStripContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, for (line = 0; line < h; line++) { - uint32_t *left = raster + (line * w); + uint32_t *left = raster + (size_t)line * w; /* Use wmin to only flip horizontally data in place and not complete * raster-row. */ uint32_t *right = left + wmin - 1; @@ -1300,13 +1321,13 @@ static int gtStripSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, uint32_t wmin; if (0 <= img->col_offset && (uint32_t)img->col_offset < imagewidth) { - wmin = TIFFmin(w, imagewidth - img->col_offset); + wmin = TIFFmin(w, imagewidth - (uint32_t)img->col_offset); } else { TIFFErrorExtR(tif, TIFFFileName(tif), "Error in gtStripSeparate: column offset %d exceeds " - "image width %d", + "image width %u", img->col_offset, imagewidth); return 0; } @@ -1337,7 +1358,7 @@ static int gtStripSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, y = 0; /* Skew forward to the end of the raster width of the row currently * written. */ - toskew = w - wmin; + toskew = (int32_t)(w - wmin); } switch (img->photometric) @@ -1361,14 +1382,16 @@ static int gtStripSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, } scanline = TIFFScanlineSize(tif); - fromskew = (w < imagewidth ? imagewidth - w : 0); + fromskew = (int32_t)(w < imagewidth ? imagewidth - w : 0); for (row = 0; row < h; row += nrow) { uint32_t temp; - rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip; + rowstoread = + rowsperstrip - + ((uint32_t)((int32_t)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; + offset_row = (uint32_t)((int32_t)row + img->row_offset); + temp = (uint32_t)((int32_t)row + img->row_offset) % rowsperstrip + nrow; if (scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline)) { TIFFErrorExtR(tif, TIFFFileName(tif), @@ -1435,12 +1458,15 @@ static int gtStripSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, /* For SEPARATE the pos-offset is per sample and should not be * multiplied by img->samplesperpixel. */ - pos = ((row + img->row_offset) % rowsperstrip) * scanline + + pos = (tmsize_t)((uint32_t)((int32_t)row + img->row_offset) % + rowsperstrip) * + scanline + (tmsize_t)img->col_offset; tmsize_t roffset = (tmsize_t)y * w; (*put)(img, raster + roffset, 0, y, wmin, nrow, fromskew, toskew, p0 + pos, p1 + pos, p2 + pos, (alpha ? (pa + pos) : NULL)); - y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow); + y += (uint32_t)((flip & FLIP_VERTICALLY) ? -(int32_t)nrow + : (int32_t)nrow); } if (flip & FLIP_HORIZONTALLY) @@ -1449,7 +1475,7 @@ static int gtStripSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, for (line = 0; line < h; line++) { - uint32_t *left = raster + (line * w); + uint32_t *left = raster + (size_t)line * w; /* Use wmin to only flip horizontally data in place and not complete * raster-row. */ uint32_t *right = left + wmin - 1; @@ -1505,6 +1531,9 @@ static int gtStripSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, op; /*-fallthrough*/ \ case 1: \ op; \ + break; \ + default: \ + break; \ } #define CASE4(x, op) \ switch (x) \ @@ -1515,6 +1544,9 @@ static int gtStripSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, op; /*-fallthrough*/ \ case 1: \ op; \ + break; \ + default: \ + break; \ } #define NOP @@ -1581,13 +1613,6 @@ static int gtStripSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, #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, \ @@ -1706,7 +1731,7 @@ DECLAREContigPutFunc(putagreytile) { for (x = w; x > 0; --x) { - *cp++ = BWmap[*pp][0] & ((uint32_t) * (pp + 1) << 24 | ~A1); + *cp++ = BWmap[*pp][0] & ((uint32_t)*(pp + 1) << 24 | ~A1); pp += samplesperpixel; } cp += toskew; @@ -1721,6 +1746,9 @@ DECLAREContigPutFunc(put16bitbwtile) { int samplesperpixel = img->samplesperpixel; uint32_t **BWmap = img->BWmap; + /* Convert pixel skew to byte skew (16-bit samples) */ + const tmsize_t fromskewLocal = + (tmsize_t)fromskew * (tmsize_t)(2 * samplesperpixel); (void)y; for (; h > 0; --h) @@ -1736,7 +1764,7 @@ DECLAREContigPutFunc(put16bitbwtile) wp += samplesperpixel; } cp += toskew; - pp += fromskew; + pp += fromskewLocal; } } @@ -1806,13 +1834,14 @@ DECLAREContigPutFunc(putRGBcontig8bittile) (void)x; (void)y; - fromskew *= samplesperpixel; + const tmsize_t fromskewLocal = + (tmsize_t)fromskew * (tmsize_t)samplesperpixel; for (; h > 0; --h) { UNROLL8(w, NOP, *cp++ = PACK(pp[0], pp[1], pp[2]); pp += samplesperpixel); cp += toskew; - pp += fromskew; + pp += fromskewLocal; } } @@ -1826,13 +1855,14 @@ DECLAREContigPutFunc(putRGBAAcontig8bittile) (void)x; (void)y; - fromskew *= samplesperpixel; + const tmsize_t fromskewLocal = + (tmsize_t)fromskew * (tmsize_t)samplesperpixel; for (; h > 0; --h) { UNROLL8(w, NOP, *cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]); pp += samplesperpixel); cp += toskew; - pp += fromskew; + pp += fromskewLocal; } } @@ -1844,7 +1874,8 @@ DECLAREContigPutFunc(putRGBUAcontig8bittile) { int samplesperpixel = img->samplesperpixel; (void)y; - fromskew *= samplesperpixel; + const tmsize_t fromskewLocal = + (tmsize_t)fromskew * (tmsize_t)samplesperpixel; for (; h > 0; --h) { uint32_t r, g, b, a; @@ -1860,7 +1891,7 @@ DECLAREContigPutFunc(putRGBUAcontig8bittile) pp += samplesperpixel; } cp += toskew; - pp += fromskew; + pp += fromskewLocal; } } @@ -1872,7 +1903,8 @@ DECLAREContigPutFunc(putRGBcontig16bittile) int samplesperpixel = img->samplesperpixel; uint16_t *wp = (uint16_t *)pp; (void)y; - fromskew *= samplesperpixel; + const tmsize_t fromskewLocal = + (tmsize_t)fromskew * (tmsize_t)samplesperpixel; for (; h > 0; --h) { for (x = w; x > 0; --x) @@ -1882,7 +1914,7 @@ DECLAREContigPutFunc(putRGBcontig16bittile) wp += samplesperpixel; } cp += toskew; - wp += fromskew; + wp += fromskewLocal; } } @@ -1895,7 +1927,8 @@ DECLAREContigPutFunc(putRGBAAcontig16bittile) int samplesperpixel = img->samplesperpixel; uint16_t *wp = (uint16_t *)pp; (void)y; - fromskew *= samplesperpixel; + const tmsize_t fromskewLocal = + (tmsize_t)fromskew * (tmsize_t)samplesperpixel; for (; h > 0; --h) { for (x = w; x > 0; --x) @@ -1905,7 +1938,7 @@ DECLAREContigPutFunc(putRGBAAcontig16bittile) wp += samplesperpixel; } cp += toskew; - wp += fromskew; + wp += fromskewLocal; } } @@ -1918,7 +1951,8 @@ DECLAREContigPutFunc(putRGBUAcontig16bittile) int samplesperpixel = img->samplesperpixel; uint16_t *wp = (uint16_t *)pp; (void)y; - fromskew *= samplesperpixel; + const tmsize_t fromskewLocal = + (tmsize_t)fromskew * (tmsize_t)samplesperpixel; for (; h > 0; --h) { uint32_t r, g, b, a; @@ -1934,7 +1968,7 @@ DECLAREContigPutFunc(putRGBUAcontig16bittile) wp += samplesperpixel; } cp += toskew; - wp += fromskew; + wp += fromskewLocal; } } @@ -1950,14 +1984,17 @@ DECLAREContigPutFunc(putRGBcontig8bitCMYKtile) (void)x; (void)y; - fromskew *= samplesperpixel; + const tmsize_t fromskewLocal = + (tmsize_t)fromskew * (tmsize_t)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; + UNROLL8(w, NOP, k = (uint16_t)(255 - pp[3]); + r = (uint16_t)((k * (uint16_t)(255 - pp[0])) / 255); + g = (uint16_t)((k * (uint16_t)(255 - pp[1])) / 255); + b = (uint16_t)((k * (uint16_t)(255 - pp[2])) / 255); *cp++ = PACK(r, g, b); pp += samplesperpixel); cp += toskew; - pp += fromskew; + pp += fromskewLocal; } } @@ -1970,22 +2007,23 @@ DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile) { int samplesperpixel = img->samplesperpixel; TIFFRGBValue *Map = img->Map; - uint16_t r, g, b, k; + unsigned int r, g, b, k; (void)y; - fromskew *= samplesperpixel; + const tmsize_t fromskewLocal = + (tmsize_t)fromskew * (tmsize_t)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; + k = 255U - pp[3]; + r = (k * (255U - pp[0])) / 255U; + g = (k * (255U - pp[1])) / 255U; + b = (k * (255U - pp[2])) / 255U; *cp++ = PACK(Map[r], Map[g], Map[b]); pp += samplesperpixel; } - pp += fromskew; + pp += fromskewLocal; cp += toskew; } } @@ -2038,13 +2076,13 @@ DECLARESepPutFunc(putCMYKseparate8bittile) (void)y; for (; h > 0; --h) { - uint32_t rv, gv, bv, kv; + unsigned int 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; + kv = 255U - *a++; + rv = (kv * (255U - *r++)) / 255U; + gv = (kv * (255U - *g++)) / 255U; + bv = (kv * (255U - *b++)) / 255U; *cp++ = PACK4(rv, gv, bv, 255); } SKEW4(r, g, b, a, fromskew); @@ -2156,7 +2194,7 @@ DECLAREContigPutFunc(putcontig8bitCIELab8) float X, Y, Z; uint32_t r, g, b; (void)y; - fromskew *= 3; + const tmsize_t fromskewLocal = (tmsize_t)fromskew * (tmsize_t)3; for (; h > 0; --h) { for (x = w; x > 0; --x) @@ -2168,7 +2206,7 @@ DECLAREContigPutFunc(putcontig8bitCIELab8) pp += 3; } cp += toskew; - pp += fromskew; + pp += fromskewLocal; } } @@ -2181,7 +2219,7 @@ DECLAREContigPutFunc(putcontig8bitCIELab16) uint32_t r, g, b; uint16_t *wp = (uint16_t *)pp; (void)y; - fromskew *= 3; + const tmsize_t fromskewLocal = (tmsize_t)fromskew * (tmsize_t)3; for (; h > 0; --h) { for (x = w; x > 0; --x) @@ -2193,7 +2231,7 @@ DECLAREContigPutFunc(putcontig8bitCIELab16) wp += 3; } cp += toskew; - wp += fromskew; + wp += fromskewLocal; } } @@ -2204,7 +2242,7 @@ DECLAREContigPutFunc(putcontig8bitCIELab16) #define YCbCrtoRGB(dst, Y) \ { \ uint32_t r, g, b; \ - TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b); \ + TIFFYCbCrtoRGB(img->ycbcr, (Y), (int32_t)Cb, (int32_t)Cr, &r, &g, &b); \ dst = PACK(r, g, b); \ } @@ -2216,11 +2254,12 @@ 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; + const tmsize_t incr = 3 * (tmsize_t)w + 4 * (tmsize_t)toskew; (void)y; /* adjust fromskew */ - fromskew = (fromskew / 4) * (4 * 2 + 2); + const tmsize_t fromskewLocal = + (tmsize_t)(fromskew / 4) * (tmsize_t)(4 * 4 + 2); if ((h & 3) == 0 && (w & 3) == 0) { for (; h >= 4; h -= 4) @@ -2258,7 +2297,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr44tile) cp1 += incr; cp2 += incr; cp3 += incr; - pp += fromskew; + pp += fromskewLocal; } } else @@ -2282,7 +2321,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr44tile) YCbCrtoRGB(cp1[3], pp[7]); /* FALLTHROUGH */ case 1: YCbCrtoRGB(cp[3], pp[3]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ + } /* FALLTHROUGH */ case 3: switch (h) { @@ -2294,7 +2333,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr44tile) YCbCrtoRGB(cp1[2], pp[6]); /* FALLTHROUGH */ case 1: YCbCrtoRGB(cp[2], pp[2]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ + } /* FALLTHROUGH */ case 2: switch (h) { @@ -2306,7 +2345,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr44tile) YCbCrtoRGB(cp1[1], pp[5]); /* FALLTHROUGH */ case 1: YCbCrtoRGB(cp[1], pp[1]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ + } /* FALLTHROUGH */ case 1: switch (h) { @@ -2318,7 +2357,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr44tile) YCbCrtoRGB(cp1[0], pp[4]); /* FALLTHROUGH */ case 1: YCbCrtoRGB(cp[0], pp[0]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ + } /* FALLTHROUGH */ } if (x < 4) { @@ -2345,7 +2384,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr44tile) cp1 += incr; cp2 += incr; cp3 += incr; - pp += fromskew; + pp += fromskewLocal; } } } @@ -2356,10 +2395,11 @@ DECLAREContigPutFunc(putcontig8bitYCbCr44tile) DECLAREContigPutFunc(putcontig8bitYCbCr42tile) { uint32_t *cp1 = cp + w + toskew; - int32_t incr = 2 * toskew + w; + const tmsize_t incr = 2 * (tmsize_t)toskew + (tmsize_t)w; (void)y; - fromskew = (fromskew / 4) * (4 * 2 + 2); + const tmsize_t fromskewLocal = + (tmsize_t)(fromskew / 4) * (tmsize_t)(4 * 2 + 2); if ((w & 3) == 0 && (h & 1) == 0) { for (; h >= 2; h -= 2) @@ -2385,7 +2425,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr42tile) } while (--x); cp += incr; cp1 += incr; - pp += fromskew; + pp += fromskewLocal; } } else @@ -2405,7 +2445,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr42tile) YCbCrtoRGB(cp1[3], pp[7]); /* FALLTHROUGH */ case 1: YCbCrtoRGB(cp[3], pp[3]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ + } /* FALLTHROUGH */ case 3: switch (h) { @@ -2413,7 +2453,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr42tile) YCbCrtoRGB(cp1[2], pp[6]); /* FALLTHROUGH */ case 1: YCbCrtoRGB(cp[2], pp[2]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ + } /* FALLTHROUGH */ case 2: switch (h) { @@ -2421,7 +2461,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr42tile) YCbCrtoRGB(cp1[1], pp[5]); /* FALLTHROUGH */ case 1: YCbCrtoRGB(cp[1], pp[1]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ + } /* FALLTHROUGH */ case 1: switch (h) { @@ -2429,7 +2469,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr42tile) YCbCrtoRGB(cp1[0], pp[4]); /* FALLTHROUGH */ case 1: YCbCrtoRGB(cp[0], pp[0]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ + } /* FALLTHROUGH */ } if (x < 4) { @@ -2450,7 +2490,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr42tile) h -= 2; cp += incr; cp1 += incr; - pp += fromskew; + pp += fromskewLocal; } } } @@ -2461,7 +2501,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr42tile) DECLAREContigPutFunc(putcontig8bitYCbCr41tile) { (void)y; - fromskew = (fromskew / 4) * (4 * 1 + 2); + const tmsize_t fromskewLocal = + (tmsize_t)(fromskew / 4) * (tmsize_t)(4 * 1 + 2); do { x = w >> 2; @@ -2495,6 +2536,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr41tile) YCbCrtoRGB(cp[0], pp[0]); /*-fallthrough*/ case 0: break; + default: + break; } cp += (w & 3); @@ -2502,7 +2545,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr41tile) } cp += toskew; - pp += fromskew; + pp += fromskewLocal; } while (--h); } @@ -2512,9 +2555,10 @@ DECLAREContigPutFunc(putcontig8bitYCbCr41tile) DECLAREContigPutFunc(putcontig8bitYCbCr22tile) { uint32_t *cp2; - int32_t incr = 2 * toskew + w; + const tmsize_t incr = 2 * (tmsize_t)toskew + (tmsize_t)w; (void)y; - fromskew = (fromskew / 2) * (2 * 2 + 2); + const tmsize_t fromskewLocal = + (tmsize_t)(fromskew / 2) * (tmsize_t)(2 * 2 + 2); cp2 = cp + w + toskew; while (h >= 2) { @@ -2544,7 +2588,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr22tile) } cp += incr; cp2 += incr; - pp += fromskew; + pp += fromskewLocal; h -= 2; } if (h == 1) @@ -2576,7 +2620,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr22tile) DECLAREContigPutFunc(putcontig8bitYCbCr21tile) { (void)y; - fromskew = (fromskew / 2) * (2 * 1 + 2); + const tmsize_t fromskewLocal = + (tmsize_t)(fromskew / 2) * (tmsize_t)(2 * 1 + 2); do { x = w >> 1; @@ -2605,7 +2650,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr21tile) } cp += toskew; - pp += fromskew; + pp += fromskewLocal; } while (--h); } @@ -2615,9 +2660,10 @@ DECLAREContigPutFunc(putcontig8bitYCbCr21tile) DECLAREContigPutFunc(putcontig8bitYCbCr12tile) { uint32_t *cp2; - int32_t incr = 2 * toskew + w; + const tmsize_t incr = 2 * (tmsize_t)toskew + (tmsize_t)w; (void)y; - fromskew = (fromskew / 1) * (1 * 2 + 2); + const tmsize_t fromskewLocal = + (tmsize_t)(fromskew / 1) * (tmsize_t)(1 * 2 + 2); cp2 = cp + w + toskew; while (h >= 2) { @@ -2634,7 +2680,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr12tile) } while (--x); cp += incr; cp2 += incr; - pp += fromskew; + pp += fromskewLocal; h -= 2; } if (h == 1) @@ -2657,7 +2703,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr12tile) DECLAREContigPutFunc(putcontig8bitYCbCr11tile) { (void)y; - fromskew = (fromskew / 1) * (1 * 1 + 2); + const tmsize_t fromskewLocal = + (tmsize_t)(fromskew / 1) * (tmsize_t)(1 * 1 + 2); do { x = w; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */ @@ -2671,7 +2718,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr11tile) pp += 3; } while (--x); cp += toskew; - pp += fromskew; + pp += fromskewLocal; } while (--h); } @@ -2730,8 +2777,8 @@ static int initYCbCrConversion(TIFFRGBAImage *img) /* 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]) + if (isnan(luma[0]) || isnan(luma[1]) || TIFF_FLOAT_EQ(luma[1], 0.0f) || + isnan(luma[2])) { TIFFErrorExtR(img->tif, module, "Invalid values for YCbCrCoefficients tag"); @@ -2763,7 +2810,7 @@ static tileContigRoutine initCIELabConversion(TIFFRGBAImage *img) float refWhite[3]; TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint); - if (whitePoint[1] == 0.0f) + if (TIFF_FLOAT_EQ(whitePoint[1], 0.0f)) { TIFFErrorExtR(img->tif, module, "Invalid value for WhitePoint tag."); return NULL; @@ -2781,10 +2828,10 @@ static tileContigRoutine initCIELabConversion(TIFFRGBAImage *img) } } - refWhite[1] = 100.0F; + refWhite[1] = 100.0f; refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1]; refWhite[2] = - (1.0F - whitePoint[0] - whitePoint[1]) / whitePoint[1] * refWhite[1]; + (1.0f - whitePoint[0] - whitePoint[1]) / whitePoint[1] * refWhite[1]; if (TIFFCIELabToRGBInit(img->cielab, &display_sRGB, refWhite) < 0) { TIFFErrorExtR(img->tif, module, @@ -2820,7 +2867,8 @@ static int makebwmap(TIFFRGBAImage *img) img->BWmap = (uint32_t **)_TIFFmallocExt( img->tif, - 256 * sizeof(uint32_t *) + (256 * nsamples * sizeof(uint32_t))); + (tmsize_t)((size_t)256 * sizeof(uint32_t *) + + ((size_t)256 * (size_t)nsamples * sizeof(uint32_t)))); if (img->BWmap == NULL) { TIFFErrorExtR(img->tif, TIFFFileName(img->tif), @@ -2861,6 +2909,8 @@ static int makebwmap(TIFFRGBAImage *img) case 16: GREY(i); break; + default: + break; } #undef GREY } @@ -2876,14 +2926,14 @@ static int setupMap(TIFFRGBAImage *img) { int32_t x, range; - range = (int32_t)((1L << img->bitspersample) - 1); + range = (int32_t)((1U << img->bitspersample) - 1U); /* treat 16 bit the same as eight bit */ if (img->bitspersample == 16) - range = (int32_t)255; + range = 255; img->Map = (TIFFRGBValue *)_TIFFmallocExt( - img->tif, (range + 1) * sizeof(TIFFRGBValue)); + img->tif, (tmsize_t)((size_t)(range + 1) * sizeof(TIFFRGBValue))); if (img->Map == NULL) { TIFFErrorExtR(img->tif, TIFFFileName(img->tif), @@ -2966,7 +3016,8 @@ static int makecmap(TIFFRGBAImage *img) img->PALmap = (uint32_t **)_TIFFmallocExt( img->tif, - 256 * sizeof(uint32_t *) + (256 * nsamples * sizeof(uint32_t))); + (tmsize_t)((size_t)256 * sizeof(uint32_t *) + + ((size_t)256 * (size_t)nsamples * sizeof(uint32_t)))); if (img->PALmap == NULL) { TIFFErrorExtR(img->tif, TIFFFileName(img->tif), @@ -3006,6 +3057,8 @@ static int makecmap(TIFFRGBAImage *img) case 8: CMAP(i); break; + default: + break; } #undef CMAP } @@ -3048,6 +3101,8 @@ static int buildMap(TIFFRGBAImage *img) if (img->bitspersample <= 8 && !makecmap(img)) return (0); break; + default: + break; } return (1); } @@ -3096,6 +3151,8 @@ static int PickContigCase(TIFFRGBAImage *img) img->put.contig = putRGBcontig16bittile; } break; + default: + break; } break; case PHOTOMETRIC_SEPARATED: @@ -3127,6 +3184,8 @@ static int PickContigCase(TIFFRGBAImage *img) case 1: img->put.contig = put1bitcmaptile; break; + default: + break; } } break; @@ -3154,6 +3213,8 @@ static int PickContigCase(TIFFRGBAImage *img) case 1: img->put.contig = put1bitbwtile; break; + default: + break; } } break; @@ -3175,6 +3236,19 @@ static int PickContigCase(TIFFRGBAImage *img) uint16_t SubsamplingVer; TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &SubsamplingHor, &SubsamplingVer); + /* Validate that the image dimensions are compatible with + the subsampling block. All putcontig8bitYCbCrXYtile routines + assume width >= X and height >= Y. */ + if (img->width < SubsamplingHor || + img->height < SubsamplingVer) + { + TIFFErrorExtR(img->tif, TIFFFileName(img->tif), + "YCbCr subsampling (%u,%u) incompatible " + "with image size %ux%u", + SubsamplingHor, SubsamplingVer, + img->width, img->height); + return (0); + } switch ((SubsamplingHor << 4) | SubsamplingVer) { case 0x44: @@ -3198,6 +3272,8 @@ static int PickContigCase(TIFFRGBAImage *img) case 0x11: img->put.contig = putcontig8bitYCbCr11tile; break; + default: + break; } } } @@ -3209,6 +3285,9 @@ static int PickContigCase(TIFFRGBAImage *img) img->put.contig = initCIELabConversion(img); break; } + break; + default: + break; } return ((img->get != NULL) && (img->put.contig != NULL)); } @@ -3260,6 +3339,8 @@ static int PickSeparateCase(TIFFRGBAImage *img) img->put.separate = putRGBseparate16bittile; } break; + default: + break; } break; case PHOTOMETRIC_SEPARATED: @@ -3284,10 +3365,14 @@ static int PickSeparateCase(TIFFRGBAImage *img) img->put.separate = putseparate8bitYCbCr11tile; break; /* TODO: add other cases here */ + default: + break; } } } break; + default: + break; } return ((img->get != NULL) && (img->put.separate != NULL)); } @@ -3298,7 +3383,7 @@ static int BuildMapUaToAa(TIFFRGBAImage *img) uint8_t *m; uint16_t na, nv; assert(img->UaToAa == NULL); - img->UaToAa = _TIFFmallocExt(img->tif, 65536); + img->UaToAa = (uint8_t *)_TIFFmallocExt(img->tif, 65536); if (img->UaToAa == NULL) { TIFFErrorExtR(img->tif, module, "Out of memory"); @@ -3319,7 +3404,7 @@ static int BuildMapBitdepth16To8(TIFFRGBAImage *img) uint8_t *m; uint32_t n; assert(img->Bitdepth16To8 == NULL); - img->Bitdepth16To8 = _TIFFmallocExt(img->tif, 65536); + img->Bitdepth16To8 = (uint8_t *)_TIFFmallocExt(img->tif, 65536); if (img->Bitdepth16To8 == NULL) { TIFFErrorExtR(img->tif, module, "Out of memory"); @@ -3386,7 +3471,7 @@ int TIFFReadRGBAStripExt(TIFF *tif, uint32_t row, uint32_t *raster, return (0); } - img.row_offset = row; + img.row_offset = (int)row; img.col_offset = 0; if (row + rowsperstrip > img.height) @@ -3497,8 +3582,8 @@ int TIFFReadRGBATileExt(TIFF *tif, uint32_t col, uint32_t row, uint32_t *raster, * Read the chunk of imagery. */ - img.row_offset = row; - img.col_offset = col; + img.row_offset = (int)row; + img.col_offset = (int)col; ok = TIFFRGBAImageGet(&img, raster, read_xsize, read_ysize); @@ -3520,15 +3605,16 @@ int TIFFReadRGBATileExt(TIFF *tif, uint32_t col, uint32_t row, uint32_t *raster, 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)); + _TIFFmemset( + raster + (size_t)(tile_ysize - i_row - 1) * tile_xsize + read_xsize, + 0, + (tmsize_t)(sizeof(uint32_t) * (size_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); + (tmsize_t)(sizeof(uint32_t) * (size_t)tile_xsize)); } return (ok); diff --git a/3rdparty/libtiff/tif_hash_set.c b/3rdparty/libtiff/tif_hash_set.c index 81dea3fcf2..7c27191ceb 100644 --- a/3rdparty/libtiff/tif_hash_set.c +++ b/3rdparty/libtiff/tif_hash_set.c @@ -76,7 +76,7 @@ static const int anPrimes[] = { 100663319, 201326611, 402653189, 805306457, 1610612741}; /************************************************************************/ -/* TIFFHashSetHashPointer() */ +/* TIFFHashSetHashPointer() */ /************************************************************************/ /** @@ -93,7 +93,7 @@ static unsigned long TIFFHashSetHashPointer(const void *elt) } /************************************************************************/ -/* TIFFHashSetEqualPointer() */ +/* TIFFHashSetEqualPointer() */ /************************************************************************/ /** @@ -111,7 +111,7 @@ static bool TIFFHashSetEqualPointer(const void *elt1, const void *elt2) } /************************************************************************/ -/* TIFFHashSetNew() */ +/* TIFFHashSetNew() */ /************************************************************************/ /** @@ -164,7 +164,7 @@ TIFFHashSet *TIFFHashSetNew(TIFFHashSetHashFunc fnHashFunc, } /************************************************************************/ -/* TIFFHashSetSize() */ +/* TIFFHashSetSize() */ /************************************************************************/ /** @@ -184,7 +184,7 @@ int TIFFHashSetSize(const TIFFHashSet *set) } /************************************************************************/ -/* TIFFHashSetGetNewListElt() */ +/* TIFFHashSetGetNewListElt() */ /************************************************************************/ static TIFFList *TIFFHashSetGetNewListElt(TIFFHashSet *set) @@ -202,7 +202,7 @@ static TIFFList *TIFFHashSetGetNewListElt(TIFFHashSet *set) } /************************************************************************/ -/* TIFFHashSetReturnListElt() */ +/* TIFFHashSetReturnListElt() */ /************************************************************************/ static void TIFFHashSetReturnListElt(TIFFHashSet *set, TIFFList *psList) @@ -220,7 +220,7 @@ static void TIFFHashSetReturnListElt(TIFFHashSet *set, TIFFList *psList) } /************************************************************************/ -/* TIFFHashSetClearInternal() */ +/* TIFFHashSetClearInternal() */ /************************************************************************/ static void TIFFHashSetClearInternal(TIFFHashSet *set, bool bFinalize) @@ -246,7 +246,7 @@ static void TIFFHashSetClearInternal(TIFFHashSet *set, bool bFinalize) } /************************************************************************/ -/* TIFFListDestroy() */ +/* TIFFListDestroy() */ /************************************************************************/ /** @@ -270,7 +270,7 @@ static void TIFFListDestroy(TIFFList *psList) } /************************************************************************/ -/* TIFFHashSetDestroy() */ +/* TIFFHashSetDestroy() */ /************************************************************************/ /** @@ -295,7 +295,7 @@ void TIFFHashSetDestroy(TIFFHashSet *set) #ifdef notused /************************************************************************/ -/* TIFFHashSetClear() */ +/* TIFFHashSetClear() */ /************************************************************************/ /** @@ -319,7 +319,7 @@ void TIFFHashSetClear(TIFFHashSet *set) } /************************************************************************/ -/* TIFFHashSetForeach() */ +/* TIFFHashSetForeach() */ /************************************************************************/ /** @@ -360,14 +360,14 @@ void TIFFHashSetForeach(TIFFHashSet *set, TIFFHashSetIterEltFunc fnIterFunc, #endif /************************************************************************/ -/* TIFFHashSetRehash() */ +/* TIFFHashSetRehash() */ /************************************************************************/ static bool TIFFHashSetRehash(TIFFHashSet *set) { int nNewAllocatedSize = anPrimes[set->nIndiceAllocatedSize]; TIFFList **newTabList = - (TIFFList **)(calloc(nNewAllocatedSize, sizeof(TIFFList *))); + (TIFFList **)(calloc((size_t)nNewAllocatedSize, sizeof(TIFFList *))); if (newTabList == NULL) return false; #ifdef HASH_DEBUG @@ -384,7 +384,7 @@ static bool TIFFHashSetRehash(TIFFHashSet *set) while (cur) { const unsigned long nNewHashVal = - set->fnHashFunc(cur->pData) % nNewAllocatedSize; + set->fnHashFunc(cur->pData) % (unsigned long)nNewAllocatedSize; #ifdef HASH_DEBUG if (newTabList[nNewHashVal]) set->nCollisions++; @@ -403,12 +403,13 @@ static bool TIFFHashSetRehash(TIFFHashSet *set) } /************************************************************************/ -/* TIFFHashSetFindPtr() */ +/* TIFFHashSetFindPtr() */ /************************************************************************/ static void **TIFFHashSetFindPtr(TIFFHashSet *set, const void *elt) { - const unsigned long nHashVal = set->fnHashFunc(elt) % set->nAllocatedSize; + const unsigned long nHashVal = + set->fnHashFunc(elt) % (unsigned long)set->nAllocatedSize; TIFFList *cur = set->tabList[nHashVal]; while (cur) { @@ -464,7 +465,8 @@ bool TIFFHashSetInsert(TIFFHashSet *set, void *elt) } } - const unsigned long nHashVal = set->fnHashFunc(elt) % set->nAllocatedSize; + const unsigned long nHashVal = + set->fnHashFunc(elt) % (unsigned long)set->nAllocatedSize; #ifdef HASH_DEBUG if (set->tabList[nHashVal]) set->nCollisions++; @@ -486,7 +488,7 @@ bool TIFFHashSetInsert(TIFFHashSet *set, void *elt) } /************************************************************************/ -/* TIFFHashSetLookup() */ +/* TIFFHashSetLookup() */ /************************************************************************/ /** @@ -532,7 +534,8 @@ static bool TIFFHashSetRemoveInternal(TIFFHashSet *set, const void *elt, } } - int nHashVal = (int)(set->fnHashFunc(elt) % set->nAllocatedSize); + int nHashVal = + (int)(set->fnHashFunc(elt) % (unsigned long)set->nAllocatedSize); TIFFList *cur = set->tabList[nHashVal]; TIFFList *prev = NULL; while (cur) @@ -581,7 +584,7 @@ bool TIFFHashSetRemove(TIFFHashSet *set, const void *elt) #ifdef notused /************************************************************************/ -/* TIFFHashSetRemoveDeferRehash() */ +/* TIFFHashSetRemoveDeferRehash() */ /************************************************************************/ /** diff --git a/3rdparty/libtiff/tif_jbig.c b/3rdparty/libtiff/tif_jbig.c index bb0de9e6e1..745956387b 100644 --- a/3rdparty/libtiff/tif_jbig.c +++ b/3rdparty/libtiff/tif_jbig.c @@ -33,7 +33,14 @@ #include "tiffiop.h" #ifdef JBIG_SUPPORT +#ifdef __cplusplus +extern "C" +{ +#endif #include "jbig.h" +#ifdef __cplusplus +} +#endif static int JBIGSetupDecode(TIFF *tif) { @@ -100,7 +107,7 @@ static int JBIGDecode(TIFF *tif, uint8_t *buffer, tmsize_t size, uint16_t s) decodedSize = jbg_dec_getsize(&decoder); if ((tmsize_t)decodedSize < size) { - memset(buffer + decodedSize, 0, (size_t)(size - decodedSize)); + memset(buffer + decodedSize, 0, (size_t)(size - (tmsize_t)decodedSize)); TIFFWarningExtR(tif, "JBIG", "Only decoded %lu bytes, whereas %" TIFF_SSIZE_FORMAT " requested", @@ -116,7 +123,7 @@ static int JBIGDecode(TIFF *tif, uint8_t *buffer, tmsize_t size, uint16_t s) return 0; } pImage = jbg_dec_getimage(&decoder, 0); - _TIFFmemcpy(buffer, pImage, decodedSize); + _TIFFmemcpy(buffer, pImage, (tmsize_t)decodedSize); jbg_dec_free(&decoder); tif->tif_rawcp += tif->tif_rawcc; diff --git a/3rdparty/libtiff/tif_jpeg.c b/3rdparty/libtiff/tif_jpeg.c index aba5f99b7c..b9a85cb18d 100644 --- a/3rdparty/libtiff/tif_jpeg.c +++ b/3rdparty/libtiff/tif_jpeg.c @@ -22,9 +22,6 @@ * OF THIS SOFTWARE. */ -#define WIN32_LEAN_AND_MEAN -#define VC_EXTRALEAN - #include "tiffiop.h" #include @@ -146,20 +143,9 @@ int TIFFJPEGIsFullStripRequired_12(TIFF *tif); #define LONGJMP(jbuf, code) longjmp(jbuf, code) #define JMP_BUF jmp_buf -#ifndef TIFF_jpeg_destination_mgr_defined -#define TIFF_jpeg_destination_mgr_defined -typedef struct jpeg_destination_mgr jpeg_destination_mgr; -#endif - -#ifndef TIFF_jpeg_source_mgr_defined -#define TIFF_jpeg_source_mgr_defined -typedef struct jpeg_source_mgr jpeg_source_mgr; -#endif - -#ifndef TIFF_jpeg_error_mgr_defined -#define TIFF_jpeg_error_mgr_defined -typedef struct jpeg_error_mgr jpeg_error_mgr; -#endif +typedef struct jpeg_destination_mgr tiff_jpeg_destination_mgr; +typedef struct jpeg_source_mgr tiff_jpeg_source_mgr; +typedef struct jpeg_error_mgr tiff_jpeg_error_mgr; /* * State block for each open TIFF file using @@ -174,6 +160,10 @@ typedef struct jpeg_error_mgr jpeg_error_mgr; * so we can safely cast JPEGState* -> jpeg_xxx_struct* * and vice versa! */ +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4324) /* structure padding due to alignment */ +#endif typedef struct { union @@ -184,22 +174,24 @@ typedef struct } cinfo; /* NB: must be first */ int cinfo_initialized; - jpeg_error_mgr err; /* libjpeg error manager */ - JMP_BUF exit_jmpbuf; /* for catching libjpeg failures */ + tiff_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 */ + tiff_jpeg_destination_mgr dest; /* data dest for compression */ + tiff_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 */ + uint32_t strile_width; + uint32_t strile_height; /* pointers to intermediate buffers when processing downsampled data */ TIFF_JSAMPARRAY ds_buffer[MAX_COMPONENTS]; int scancount; /* number of "scanlines" accumulated */ @@ -209,6 +201,9 @@ typedef struct int encode_raw_error; } JPEGState; +#ifdef _MSC_VER +#pragma warning(pop) +#endif #define JState(tif) ((JPEGState *)(tif)->tif_data) @@ -559,7 +554,7 @@ static boolean tables_empty_output_buffer(j_compress_ptr cinfo) /* 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)); + (tmsize_t)sp->otherSettings.jpegtables_length + 1000); if (newbuf == NULL) ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 100); sp->dest.next_output_byte = @@ -912,7 +907,7 @@ JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData *data) return (0); if (n < 2) return (0); - n -= 2; + n = (uint16_t)(n - 2); if (n > 0) JPEGFixupTagsSubsamplingSkip(data, n); } @@ -1016,7 +1011,7 @@ JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData *data, assert(m < 0x80000000UL); if (TIFFReadFile(data->tif, data->buffer, (tmsize_t)m) != (tmsize_t)m) return (0); - data->buffercurrentbyte = data->buffer; + data->buffercurrentbyte = (uint8_t *)data->buffer; data->bufferbytesleft = m; data->fileoffset += m; data->filebytesleft -= m; @@ -1037,7 +1032,7 @@ JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData *data, return (0); if (!JPEGFixupTagsSubsamplingReadByte(data, &mb)) return (0); - *result = (ma << 8) | mb; + *result = (uint16_t)((ma << 8) | mb); return (1); } @@ -1159,6 +1154,47 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif) return ret; } +static int JPEGComputeStrileWidthHeightBytesPerLine(TIFF *tif, uint16_t s) +{ + JPEGState *sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; + + /* + * Check image parameters and set decompression parameters. + */ + if (isTiled(tif)) + { + sp->strile_width = td->td_tilewidth; + sp->strile_height = td->td_tilelength; + sp->bytesperline = TIFFTileRowSize(tif); + } + else + { + sp->strile_width = td->td_imagewidth; + sp->strile_height = td->td_imagelength - tif->tif_dir.td_row; + if (sp->strile_height > td->td_rowsperstrip) + sp->strile_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 + */ + if (sp->h_sampling == 0 || sp->v_sampling == 0) + { + TIFFErrorExtR(tif, "JPEGComputeStrileWidthHeightBytesPerLine", + "JPEG horizontal or vertical sampling is zero"); + return (0); + } + sp->strile_width = TIFFhowmany_32(sp->strile_width, sp->h_sampling); + sp->strile_height = TIFFhowmany_32(sp->strile_height, sp->v_sampling); + } + + return 1; +} + /* * Set up for decoding a strip or tile. */ @@ -1167,7 +1203,6 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif) 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; @@ -1193,52 +1228,24 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif) return (0); tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte; - tif->tif_rawcc = sp->src.bytes_in_buffer; + tif->tif_rawcc = (tmsize_t)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 - */ - if (sp->h_sampling == 0 || sp->v_sampling == 0) - { - TIFFErrorExtR(tif, module, - "JPEG horizontal or vertical sampling is zero"); - return (0); - } - 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) + if (!JPEGComputeStrileWidthHeightBytesPerLine(tif, s)) + return 0; + + if (sp->cinfo.d.image_width < sp->strile_width || + sp->cinfo.d.image_height < sp->strile_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); + sp->strile_width, sp->strile_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)) + if (sp->cinfo.d.image_width == sp->strile_width && + sp->cinfo.d.image_height > sp->strile_height && + tif->tif_dir.td_row + sp->strile_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 */ @@ -1247,11 +1254,11 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif) 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); + sp->strile_width, sp->strile_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) + else if (sp->cinfo.d.image_width > sp->strile_width || + sp->cinfo.d.image_height > sp->strile_height) { /* * This case could be dangerous, if the strip or tile size has @@ -1262,8 +1269,8 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif) 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); + sp->strile_width, sp->strile_height, + sp->cinfo.d.image_width, sp->cinfo.d.image_height); return (0); } if (sp->cinfo.d.num_components != @@ -1282,7 +1289,8 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif) 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) + if (td->td_bitspersample != BITS_IN_JSAMPLE || + sp->cinfo.d.data_precision != td->td_bitspersample) { TIFFErrorExtR(tif, module, "Improper JPEG data precision"); return (0); @@ -1319,11 +1327,12 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif) 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) * + (toff_t)((JDIMENSION)(((int)compptr->width_in_blocks + + compptr->h_samp_factor - 1) / + compptr->h_samp_factor)) * + (JDIMENSION)(((int)compptr->height_in_blocks + + compptr->v_samp_factor - 1) / + compptr->v_samp_factor) * sizeof(JBLOCK); } } @@ -1439,7 +1448,7 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif) * Decode a chunk of pixels. * "Standard" case: returned data is not downsampled. */ -#if !JPEG_LIB_MK1_OR_12BIT +#if !defined(JPEG_LIB_MK1_OR_12BIT) static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) { JPEGState *sp = JState(tif); @@ -1464,7 +1473,18 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) TIFFWarningExtR(tif, tif->tif_name, "fractional scanline not read"); if (nrows > (tmsize_t)sp->cinfo.d.image_height) + { + /* Initialize the output buffer if the JPEG image is smaller than the + * strile height. */ + memset(buf, 0, (size_t)cc); nrows = sp->cinfo.d.image_height; + } + else if (sp->strile_width > sp->cinfo.d.image_width) + { + /* Initialize the output buffer if the JPEG image is smaller than the + * strile width. */ + memset(buf, 0, (size_t)cc); + } /* data is expected to be read in multiples of a scanline */ if (nrows) @@ -1483,7 +1503,7 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) return (0); } - ++tif->tif_row; + ++tif->tif_dir.td_row; buf += sp->bytesperline; cc -= sp->bytesperline; } while (--nrows > 0); @@ -1491,15 +1511,15 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) /* Update information on consumed data */ tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte; - tif->tif_rawcc = sp->src.bytes_in_buffer; + tif->tif_rawcc = (tmsize_t)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 */ +#endif /* !defined(JPEG_LIB_MK1_OR_12BIT) */ -#if JPEG_LIB_MK1_OR_12BIT +#if defined(JPEG_LIB_MK1_OR_12BIT) /*ARGSUSED*/ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) { @@ -1525,7 +1545,18 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) TIFFWarningExtR(tif, tif->tif_name, "fractional scanline not read"); if (nrows > (tmsize_t)sp->cinfo.d.image_height) + { + /* Initialize the output buffer if the JPEG image is smaller than the + * strile height. */ + memset(buf, 0, (size_t)cc); nrows = sp->cinfo.d.image_height; + } + else if (sp->strile_width > sp->cinfo.d.image_width) + { + /* Initialize the output buffer if the JPEG image is smaller than the + * strile width. */ + memset(buf, 0, (size_t)cc); + } /* data is expected to be read in multiples of a scanline */ if (nrows) @@ -1539,8 +1570,9 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) 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); + tif, (tmsize_t)((size_t)sizeof(short) * + (size_t)sp->cinfo.d.output_width * + (size_t)sp->cinfo.d.num_components)); } do @@ -1556,14 +1588,16 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) if (TIFFjpeg_read_scanlines(sp, &line_work_buf, 1) != 1) { memset(buf, 0, (size_t)cc); + _TIFFfreeExt(tif, line_work_buf); return (0); } if (sp->cinfo.d.data_precision == 12) { - int value_pairs = (sp->cinfo.d.output_width * - sp->cinfo.d.num_components) / - 2; + int value_pairs = + (int)((JDIMENSION)sp->cinfo.d.output_width * + (JDIMENSION)sp->cinfo.d.num_components) / + 2; int iPair; for (iPair = 0; iPair < value_pairs; iPair++) @@ -1582,18 +1616,19 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) else if (sp->cinfo.d.data_precision == 8) { int value_count = - (sp->cinfo.d.output_width * sp->cinfo.d.num_components); + (int)((JDIMENSION)sp->cinfo.d.output_width * + (JDIMENSION)sp->cinfo.d.num_components); int iValue; for (iValue = 0; iValue < value_count; iValue++) { ((unsigned char *)buf)[iValue] = - line_work_buf[iValue] & 0xff; + (unsigned char)(line_work_buf[iValue] & 0xff); } } } - ++tif->tif_row; + ++tif->tif_dir.td_row; buf += sp->bytesperline; cc -= sp->bytesperline; } while (--nrows > 0); @@ -1604,13 +1639,13 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) /* Update information on consumed data */ tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte; - tif->tif_rawcc = sp->src.bytes_in_buffer; + tif->tif_rawcc = (tmsize_t)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 */ +#endif /* defined(JPEG_LIB_MK1_OR_12BIT) */ /*ARGSUSED*/ static int DecodeRowError(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) @@ -1644,8 +1679,16 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) /* 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 ((uint32_t)nrows > td->td_imagelength - tif->tif_dir.td_row && + !isTiled(tif)) + nrows = td->td_imagelength - tif->tif_dir.td_row; + + /* The downsampled-data decode loop below only writes up to the JPEG + * codestream dimensions (and, due to the clump stride, may not cover the + * full caller buffer even for compliant files). Zero the whole buffer so + * no uninitialised heap is ever returned, mirroring the guard JPEGDecode + * received in 65759931ab6e (#826). */ + memset(buf, 0, (size_t)cc); #if defined(JPEG_LIB_MK1_OR_12BIT) unsigned short *tmpbuf = NULL; @@ -1660,9 +1703,10 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) 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); + tmpbuf = (unsigned short *)_TIFFmallocExt( + tif, (tmsize_t)((size_t)sizeof(unsigned short) * + (size_t)sp->cinfo.d.output_width * + (size_t)sp->cinfo.d.num_components)); if (tmpbuf == NULL) { TIFFErrorExtR(tif, "JPEGDecodeRaw", "Out of memory"); @@ -1755,18 +1799,20 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) if (sp->cinfo.d.data_precision == 8) { int i = 0; - int len = - sp->cinfo.d.output_width * sp->cinfo.d.num_components; + int len = (int)((JDIMENSION)sp->cinfo.d.output_width * + (JDIMENSION)sp->cinfo.d.num_components); for (i = 0; i < len; i++) { - ((unsigned char *)buf)[i] = tmpbuf[i] & 0xff; + ((unsigned char *)buf)[i] = + (unsigned char)(tmpbuf[i] & 0xff); } } else { /* 12-bit */ - int value_pairs = (sp->cinfo.d.output_width * - sp->cinfo.d.num_components) / - 2; + int value_pairs = + (int)((JDIMENSION)sp->cinfo.d.output_width * + (JDIMENSION)sp->cinfo.d.num_components) / + 2; int iPair; for (iPair = 0; iPair < value_pairs; iPair++) { @@ -1785,7 +1831,7 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) #endif sp->scancount++; - tif->tif_row += sp->v_sampling; + tif->tif_dir.td_row += sp->v_sampling; buf += sp->bytesperline; cc -= sp->bytesperline; @@ -2024,9 +2070,9 @@ static int JPEGSetupEncode(TIFF *tif) if (!TIFFGetField(tif, TIFFTAG_REFERENCEBLACKWHITE, &ref)) { float refbw[6]; - long top = 1L << td->td_bitspersample; + uint32_t top = 1U << td->td_bitspersample; refbw[0] = 0; - refbw[1] = (float)(top - 1L); + refbw[1] = (float)(top - 1); refbw[2] = (float)(top >> 1); refbw[3] = refbw[1]; refbw[4] = refbw[2]; @@ -2074,30 +2120,30 @@ static int JPEGSetupEncode(TIFF *tif) #endif if (isTiled(tif)) { - if ((td->td_tilelength % (sp->v_sampling * DCTSIZE)) != 0) + if ((td->td_tilelength % ((uint32_t)sp->v_sampling * DCTSIZE)) != 0) { TIFFErrorExtR(tif, module, "JPEG tile height must be multiple of %" PRIu32, - (uint32_t)(sp->v_sampling * DCTSIZE)); + (uint32_t)sp->v_sampling * DCTSIZE); return (0); } - if ((td->td_tilewidth % (sp->h_sampling * DCTSIZE)) != 0) + if ((td->td_tilewidth % ((uint32_t)sp->h_sampling * DCTSIZE)) != 0) { TIFFErrorExtR(tif, module, "JPEG tile width must be multiple of %" PRIu32, - (uint32_t)(sp->h_sampling * DCTSIZE)); + (uint32_t)sp->h_sampling * DCTSIZE); return (0); } } else { if (td->td_rowsperstrip < td->td_imagelength && - (td->td_rowsperstrip % (sp->v_sampling * DCTSIZE)) != 0) + (td->td_rowsperstrip % ((uint32_t)sp->v_sampling * DCTSIZE)) != 0) { TIFFErrorExtR(tif, module, "RowsPerStrip must be multiple of %" PRIu32 " for JPEG", - (uint32_t)(sp->v_sampling * DCTSIZE)); + (uint32_t)sp->v_sampling * DCTSIZE); return (0); } } @@ -2153,7 +2199,6 @@ 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); @@ -2164,47 +2209,20 @@ static int JPEGPreEncode(TIFF *tif, uint16_t s) } 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 - */ - if (sp->h_sampling == 0 || sp->v_sampling == 0) - { - TIFFErrorExtR(tif, module, - "JPEG horizontal or vertical sampling is zero"); - return (0); - } - segment_width = TIFFhowmany_32(segment_width, sp->h_sampling); - segment_height = TIFFhowmany_32(segment_height, sp->v_sampling); - } - if (segment_width > (uint32_t)JPEG_MAX_DIMENSION || - segment_height > (uint32_t)JPEG_MAX_DIMENSION) + + if (!JPEGComputeStrileWidthHeightBytesPerLine(tif, s)) + return 0; + + if (sp->strile_width > (uint32_t)JPEG_MAX_DIMENSION || + sp->strile_height > (uint32_t)JPEG_MAX_DIMENSION) { TIFFErrorExtR(tif, module, "Strip/tile too large for JPEG. Maximum dimension is %d", (int)JPEG_MAX_DIMENSION); return (0); } - sp->cinfo.c.image_width = segment_width; - sp->cinfo.c.image_height = segment_height; + sp->cinfo.c.image_width = sp->strile_width; + sp->cinfo.c.image_height = sp->strile_height; downsampled_input = FALSE; if (td->td_planarconfig == PLANARCONFIG_CONTIG) { @@ -2276,7 +2294,13 @@ static int JPEGPreEncode(TIFF *tif, uint16_t s) /* an existing file */ suppress_huff_table(sp, 0); suppress_huff_table(sp, 1); - sp->cinfo.c.optimize_coding = FALSE; + + /* We want to keep optimize_coding = TRUE for 12-bit JPEG */ + /* See lengthy explanation at + * https://gitlab.com/libtiff/libtiff/-/work_items/773#note_3009836854 + */ + if (sp->cinfo.c.data_precision == 8) + sp->cinfo.c.optimize_coding = FALSE; } else sp->cinfo.c.optimize_coding = TRUE; @@ -2332,13 +2356,15 @@ static int JPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) 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 (!isTiled(tif) && + tif->tif_dir.td_row + nrows > tif->tif_dir.td_imagelength) + nrows = tif->tif_dir.td_imagelength - tif->tif_dir.td_row; if (sp->cinfo.c.data_precision == 12) { line16_count = (int)((sp->bytesperline * 2) / 3); - line16 = (short *)_TIFFmallocExt(tif, sizeof(short) * line16_count); + line16 = (short *)_TIFFmallocExt( + tif, (tmsize_t)(sizeof(short) * (size_t)line16_count)); if (!line16) { TIFFErrorExtR(tif, "JPEGEncode", "Failed to allocate memory"); @@ -2363,8 +2389,10 @@ static int JPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) 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]; + out_ptr[0] = (TIFF_JSAMPLE)((in_ptr[0] << 4) | + ((in_ptr[1] & 0xf0) >> 4)); + out_ptr[1] = + (TIFF_JSAMPLE)(((in_ptr[1] & 0x0f) << 8) | in_ptr[2]); } } else @@ -2374,7 +2402,7 @@ static int JPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1) return (0); if (nrows > 0) - tif->tif_row++; + tif->tif_dir.td_row++; buf += sp->bytesperline; } @@ -2443,8 +2471,9 @@ static int JPEGEncodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) { int hsamp = compptr->h_samp_factor; int vsamp = compptr->v_samp_factor; - int padding = (int)(compptr->width_in_blocks * DCTSIZE - - clumps_per_line * hsamp); + int padding = + (int)(compptr->width_in_blocks * DCTSIZE - + (JDIMENSION)clumps_per_line * (JDIMENSION)hsamp); for (ypos = 0; ypos < vsamp; ypos++) { inptr = ((TIFF_JSAMPLE *)buf) + clumpoffset; @@ -2488,7 +2517,7 @@ static int JPEGEncodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) } sp->scancount = 0; } - tif->tif_row += sp->v_sampling; + tif->tif_dir.td_row += sp->v_sampling; buf += bytesperclumpline; nrows -= sp->v_sampling; } @@ -2582,10 +2611,11 @@ static void JPEGResetUpsampled(TIFF *tif) * 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); + if (tif->tif_dir.td_tilesize > 0) + tif->tif_dir.td_tilesize = + isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1); + if (tif->tif_dir.td_scanlinesize > 0) + tif->tif_dir.td_scanlinesize = TIFFScanlineSize(tif); } static int JPEGVSetField(TIFF *tif, uint32_t tag, va_list ap) @@ -2793,6 +2823,33 @@ static int JPEGInitializeLibJPEG(TIFF *tif, int decompress) return 1; } +static uint64_t JPEGGetMaxCompressionRatio(TIFF *tif) +{ + /* See README_for_libtiff_developpers.md for raw data used to estimate + * the maximum compression rate. */ + + const 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)) + { + if (sp->h_sampling == 2 && sp->v_sampling == 2) + { + if (tif->tif_dir.td_bitspersample == 12) + return 768; + else + return 512; + } + + return 0; /* unknown */ + } + + if (tif->tif_dir.td_bitspersample == 12) + return 384; + else + return 256; +} + /* Common to tif_jpeg.c and tif_jpeg_12.c */ static void TIFFInitJPEGCommon(TIFF *tif) { @@ -2829,6 +2886,7 @@ static void TIFFInitJPEGCommon(TIFF *tif) tif->tif_encoderow = JPEGEncode; tif->tif_encodestrip = JPEGEncode; tif->tif_encodetile = JPEGEncode; + tif->tif_getmaxcompressionratio = JPEGGetMaxCompressionRatio; tif->tif_cleanup = JPEGCleanup; tif->tif_defstripsize = JPEGDefaultStripSize; diff --git a/3rdparty/libtiff/tif_lerc.c b/3rdparty/libtiff/tif_lerc.c index 76d1a7b440..0466cab7f4 100644 --- a/3rdparty/libtiff/tif_lerc.c +++ b/3rdparty/libtiff/tif_lerc.c @@ -33,6 +33,7 @@ #include "Lerc_c_api.h" #include "zlib.h" +#include #ifdef ZSTD_SUPPORT #include "zstd.h" #endif @@ -188,7 +189,7 @@ static int SetupBuffers(TIFF *tif, LERCState *sp, const char *module) else { sp->segment_width = td->td_imagewidth; - sp->segment_height = td->td_imagelength - tif->tif_row; + sp->segment_height = td->td_imagelength - tif->tif_dir.td_row; if (sp->segment_height > td->td_rowsperstrip) sp->segment_height = td->td_rowsperstrip; } @@ -242,7 +243,7 @@ static int SetupBuffers(TIFF *tif, LERCState *sp, const char *module) } if ((td->td_planarconfig == PLANARCONFIG_CONTIG && - td->td_extrasamples > 0 && + td->td_extrasamples > 0 && td->td_sampleinfo && td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA && GetLercDataType(tif) == 1) || (td->td_sampleformat == SAMPLEFORMAT_IEEEFP && @@ -343,7 +344,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s) if (res != LIBDEFLATE_SUCCESS) { TIFFErrorExtR(tif, module, "Decoding error at scanline %lu", - (unsigned long)tif->tif_row); + (unsigned long)tif->tif_dir.td_row); return 0; } assert(lerc_data_sizet == (unsigned int)lerc_data_sizet); @@ -387,7 +388,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s) size_t zstd_ret; zstd_ret = ZSTD_decompress(sp->compressed_buffer, sp->compressed_size, - tif->tif_rawcp, tif->tif_rawcc); + tif->tif_rawcp, (size_t)tif->tif_rawcc); if (ZSTD_isError(zstd_ret)) { TIFFErrorExtR(tif, module, "Error in ZSTD_decompress(): %s", @@ -420,6 +421,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s) /* 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_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA && GetLercDataType(tif) == 1 && infoArray[2] == td->td_samplesperpixel - 1U) @@ -432,7 +434,8 @@ static int LERCPreDecode(TIFF *tif, uint16_t s) use_mask = 1; } - ndims = td->td_planarconfig == PLANARCONFIG_CONTIG ? nomask_bands : 1; + ndims = + (int)(td->td_planarconfig == PLANARCONFIG_CONTIG ? nomask_bands : 1); /* Info returned in infoArray is { version, dataType, nDim/nDepth, nCols, nRows, nBands, nValidPixels, blobSize, @@ -440,12 +443,12 @@ static int LERCPreDecode(TIFF *tif, uint16_t s) if (infoArray[0] != (unsigned)sp->lerc_version) { TIFFWarningExtR(tif, module, - "Unexpected version number: %d. Expected: %d", + "Unexpected version number: %u. Expected: %d", infoArray[0], sp->lerc_version); } if (infoArray[1] != (unsigned)lerc_data_type) { - TIFFErrorExtR(tif, module, "Unexpected dataType: %d. Expected: %d", + TIFFErrorExtR(tif, module, "Unexpected dataType: %u. Expected: %d", infoArray[1], lerc_data_type); return 0; } @@ -458,7 +461,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s) { if (nFoundDims != 1 && nFoundDims != (unsigned)ndims) { - TIFFErrorExtR(tif, module, "Unexpected nDim: %d. Expected: 1 or %d", + TIFFErrorExtR(tif, module, "Unexpected nDim: %u. Expected: 1 or %d", nFoundDims, ndims); return 0; } @@ -467,20 +470,20 @@ static int LERCPreDecode(TIFF *tif, uint16_t s) #endif if (nFoundDims != (unsigned)ndims) { - TIFFErrorExtR(tif, module, "Unexpected nDim: %d. Expected: %d", + TIFFErrorExtR(tif, module, "Unexpected nDim: %u. Expected: %d", nFoundDims, ndims); return 0; } if (infoArray[3] != sp->segment_width) { - TIFFErrorExtR(tif, module, "Unexpected nCols: %d. Expected: %du", + TIFFErrorExtR(tif, module, "Unexpected nCols: %u. Expected: %u", infoArray[3], sp->segment_width); return 0; } if (infoArray[4] != sp->segment_height) { - TIFFErrorExtR(tif, module, "Unexpected nRows: %d. Expected: %u", + TIFFErrorExtR(tif, module, "Unexpected nRows: %u. Expected: %u", infoArray[4], sp->segment_height); return 0; } @@ -504,28 +507,28 @@ static int LERCPreDecode(TIFF *tif, uint16_t s) #endif if (nFoundBands != td->td_samplesperpixel) { - TIFFErrorExtR(tif, module, "Unexpected nBands: %d. Expected: %d", + TIFFErrorExtR(tif, module, "Unexpected nBands: %u. Expected: %d", nFoundBands, td->td_samplesperpixel); return 0; } } else if (nFoundBands != 1) { - TIFFErrorExtR(tif, module, "Unexpected nBands: %d. Expected: %d", + TIFFErrorExtR(tif, module, "Unexpected nBands: %u. Expected: %d", nFoundBands, 1); return 0; } if (infoArray[7] != lerc_data_size) { - TIFFErrorExtR(tif, module, "Unexpected blobSize: %d. Expected: %u", + TIFFErrorExtR(tif, module, "Unexpected blobSize: %u. Expected: %u", infoArray[7], lerc_data_size); return 0; } int nRequestedMasks = use_mask ? 1 : 0; #if LERC_AT_LEAST_VERSION(3, 0, 0) - const int nFoundMasks = infoArray[8]; + const int nFoundMasks = (int)infoArray[8]; if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP && td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_samplesperpixel > 1 && nFoundDims == 1) @@ -576,21 +579,22 @@ static int LERCPreDecode(TIFF *tif, uint16_t s) sp->uncompressed_buffer_multiband_alloc = num_bytes_needed; } lerc_ret = lerc_decode(lerc_data, lerc_data_size, nRequestedMasks, - sp->mask_buffer, nFoundDims, sp->segment_width, - sp->segment_height, nFoundBands, lerc_data_type, + sp->mask_buffer, (int)nFoundDims, + (int)sp->segment_width, (int)sp->segment_height, + (int)nFoundBands, (unsigned int)lerc_data_type, sp->uncompressed_buffer_multiband); } else #endif { - lerc_ret = - lerc_decode(lerc_data, lerc_data_size, + lerc_ret = lerc_decode( + lerc_data, lerc_data_size, #if LERC_AT_LEAST_VERSION(3, 0, 0) - nRequestedMasks, + nRequestedMasks, #endif - use_mask ? sp->mask_buffer : NULL, nFoundDims, - sp->segment_width, sp->segment_height, nFoundBands, - lerc_data_type, sp->uncompressed_buffer); + use_mask ? sp->mask_buffer : NULL, (int)nFoundDims, + (int)sp->segment_width, (int)sp->segment_height, (int)nFoundBands, + (unsigned int)lerc_data_type, sp->uncompressed_buffer); } if (lerc_ret != 0) { @@ -601,17 +605,17 @@ static int LERCPreDecode(TIFF *tif, uint16_t s) /* Interleave alpha mask with other samples. */ if (use_mask && GetLercDataType(tif) == 1) { - unsigned src_stride = - (td->td_samplesperpixel - 1) * (td->td_bitspersample / 8); + unsigned src_stride = (unsigned int)((td->td_samplesperpixel - 1) * + (td->td_bitspersample / 8)); unsigned dst_stride = - td->td_samplesperpixel * (td->td_bitspersample / 8); + (unsigned int)(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]; + 1] = (uint8_t)(255 * sp->mask_buffer[i]); memcpy(sp->uncompressed_buffer + i * dst_stride, sp->uncompressed_buffer + i * src_stride, src_stride); } @@ -620,7 +624,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s) { i--; sp->uncompressed_buffer[i * dst_stride + td->td_samplesperpixel - - 1] = 255 * sp->mask_buffer[i]; + 1] = (uint8_t)(255 * sp->mask_buffer[i]); memmove(sp->uncompressed_buffer + i * dst_stride, sp->uncompressed_buffer + i * src_stride, src_stride); } @@ -649,7 +653,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s) } else { - const double nan_float64 = nan_float32; + const double nan_float64 = (double)nan_float32; for (i = 0; i < nb_pixels; i++) { if (sp->mask_buffer[i] == 0) @@ -677,7 +681,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s) } else { - const double nan_float64 = nan_float32; + const double nan_float64 = (double)nan_float32; for (i = 0; i < nb_pixels; i++) { for (int j = 0; j < td->td_samplesperpixel; j++) @@ -704,30 +708,32 @@ static int LERCPreDecode(TIFF *tif, uint16_t s) { for (int j = 0; j < td->td_samplesperpixel; j++) { - if (sp->mask_buffer[i + j * nb_pixels] == 0) + if (sp->mask_buffer[i + (unsigned int)j * nb_pixels] == + 0) ((float *)sp->uncompressed_buffer)[k] = nan_float32; else ((float *)sp->uncompressed_buffer)[k] = ((float *)sp->uncompressed_buffer_multiband) - [i + j * nb_pixels]; + [i + (unsigned int)j * nb_pixels]; ++k; } } } else { - const double nan_float64 = nan_float32; + const double nan_float64 = (double)nan_float32; for (i = 0; i < nb_pixels; i++) { for (int j = 0; j < td->td_samplesperpixel; j++) { - if (sp->mask_buffer[i + j * nb_pixels] == 0) + if (sp->mask_buffer[i + (unsigned int)j * nb_pixels] == + 0) ((double *)sp->uncompressed_buffer)[k] = nan_float64; else ((double *)sp->uncompressed_buffer)[k] = ((double *)sp->uncompressed_buffer_multiband) - [i + j * nb_pixels]; + [i + (unsigned int)j * nb_pixels]; ++k; } } @@ -766,8 +772,8 @@ static int LERCDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) return 0; } - memcpy(op, sp->uncompressed_buffer + sp->uncompressed_offset, occ); - sp->uncompressed_offset += (unsigned)occ; + memcpy(op, sp->uncompressed_buffer + sp->uncompressed_offset, (size_t)occ); + sp->uncompressed_offset += (unsigned int)occ; return 1; } @@ -832,8 +838,8 @@ static int LERCEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) return 0; } - memcpy(sp->uncompressed_buffer + sp->uncompressed_offset, bp, cc); - sp->uncompressed_offset += (unsigned)cc; + memcpy(sp->uncompressed_buffer + sp->uncompressed_offset, bp, (size_t)cc); + sp->uncompressed_offset += (unsigned int)cc; return 1; } @@ -863,13 +869,15 @@ static int LERCPostEncode(TIFF *tif) /* 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_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA && GetLercDataType(tif) == 1) { const unsigned dst_stride = - (td->td_samplesperpixel - 1) * (td->td_bitspersample / 8); + (unsigned int)((td->td_samplesperpixel - 1) * + (td->td_bitspersample / 8)); const unsigned src_stride = - td->td_samplesperpixel * (td->td_bitspersample / 8); + (unsigned int)(td->td_samplesperpixel * (td->td_bitspersample / 8)); unsigned i = 0; use_mask = 1; @@ -923,7 +931,7 @@ static int LERCPostEncode(TIFF *tif) { const float val = ((float *)sp->uncompressed_buffer)[k]; ++k; - if (val != val) + if (isnan(val)) { ++count_nan; } @@ -944,7 +952,7 @@ static int LERCPostEncode(TIFF *tif) for (i = 0; i < nb_pixels; i++) { const float val = ((float *)sp->uncompressed_buffer)[i]; - if (val != val) + if (isnan(val)) { use_mask = 1; break; @@ -965,7 +973,7 @@ static int LERCPostEncode(TIFF *tif) const double val = ((double *)sp->uncompressed_buffer)[k]; ++k; - if (val != val) + if (isnan(val)) { ++count_nan; } @@ -986,7 +994,7 @@ static int LERCPostEncode(TIFF *tif) for (i = 0; i < nb_pixels; i++) { const double val = ((double *)sp->uncompressed_buffer)[i]; - if (val != val) + if (isnan(val)) { use_mask = 1; break; @@ -1025,10 +1033,10 @@ static int LERCPostEncode(TIFF *tif) const float val = ((float *)sp->uncompressed_buffer)[k]; ((float *)sp->uncompressed_buffer_multiband) - [i + j * nb_pixels] = val; + [i + (unsigned int)j * nb_pixels] = val; ++k; - sp->mask_buffer[i + j * nb_pixels] = - (val == val) ? 255 : 0; + sp->mask_buffer[i + (unsigned int)j * nb_pixels] = + !isnan(val) ? 255 : 0; } } } @@ -1041,10 +1049,10 @@ static int LERCPostEncode(TIFF *tif) const double val = ((double *)sp->uncompressed_buffer)[k]; ((double *)sp->uncompressed_buffer_multiband) - [i + j * nb_pixels] = val; + [i + (unsigned int)j * nb_pixels] = val; ++k; - sp->mask_buffer[i + j * nb_pixels] = - (val == val) ? 255 : 0; + sp->mask_buffer[i + (unsigned int)j * nb_pixels] = + !isnan(val) ? 255 : 0; } } } @@ -1064,7 +1072,7 @@ static int LERCPostEncode(TIFF *tif) { const float val = ((float *)sp->uncompressed_buffer)[i * dst_nbands]; - sp->mask_buffer[i] = (val == val) ? 255 : 0; + sp->mask_buffer[i] = !isnan(val) ? 255 : 0; } } else @@ -1073,7 +1081,7 @@ static int LERCPostEncode(TIFF *tif) { const double val = ((double *)sp->uncompressed_buffer)[i * dst_nbands]; - sp->mask_buffer[i] = (val == val) ? 255 : 0; + sp->mask_buffer[i] = !isnan(val) ? 255 : 0; } } } @@ -1084,7 +1092,7 @@ static int LERCPostEncode(TIFF *tif) for (i = 0; i < nb_pixels; i++) { const float val = ((float *)sp->uncompressed_buffer)[i]; - sp->mask_buffer[i] = (val == val) ? 255 : 0; + sp->mask_buffer[i] = !isnan(val) ? 255 : 0; } } else @@ -1093,7 +1101,7 @@ static int LERCPostEncode(TIFF *tif) { const double val = ((double *)sp->uncompressed_buffer)[i]; - sp->mask_buffer[i] = (val == val) ? 255 : 0; + sp->mask_buffer[i] = !isnan(val) ? 255 : 0; } } } @@ -1104,7 +1112,8 @@ static int LERCPostEncode(TIFF *tif) #if LERC_AT_LEAST_VERSION(3, 0, 0) if (mask_count > 1) { - estimated_compressed_size += nb_pixels * mask_count / 8; + estimated_compressed_size += + (unsigned int)(nb_pixels * (unsigned int)mask_count / 8); } #endif @@ -1125,8 +1134,9 @@ static int LERCPostEncode(TIFF *tif) { lerc_ret = lerc_encodeForVersion( sp->uncompressed_buffer_multiband, sp->lerc_version, - GetLercDataType(tif), 1, sp->segment_width, sp->segment_height, - dst_nbands, dst_nbands, sp->mask_buffer, sp->maxzerror, + (unsigned int)GetLercDataType(tif), 1, (int)sp->segment_width, + (int)sp->segment_height, (int)dst_nbands, (int)dst_nbands, + sp->mask_buffer, sp->maxzerror, (unsigned char *)sp->compressed_buffer, sp->compressed_size, &numBytesWritten); } @@ -1134,9 +1144,10 @@ static int LERCPostEncode(TIFF *tif) #endif { 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, + sp->uncompressed_buffer, sp->lerc_version, + (unsigned int)GetLercDataType(tif), + (int)(td->td_planarconfig == PLANARCONFIG_CONTIG ? dst_nbands : 1), + (int)sp->segment_width, (int)sp->segment_height, 1, #if LERC_AT_LEAST_VERSION(3, 0, 0) use_mask ? 1 : 0, #endif @@ -1179,14 +1190,14 @@ static int LERCPostEncode(TIFF *tif) return 0; } - tif->tif_rawcc = libdeflate_zlib_compress( + tif->tif_rawcc = (tmsize_t)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); + (unsigned long)tif->tif_dir.td_row); return 0; } #else @@ -1252,7 +1263,7 @@ static int LERCPostEncode(TIFF *tif) int ret; uint8_t *tif_rawdata_backup = tif->tif_rawdata; tif->tif_rawdata = sp->uncompressed_buffer; - tif->tif_rawcc = zstd_ret; + tif->tif_rawcc = (tmsize_t)zstd_ret; ret = TIFFFlushData1(tif); tif->tif_rawdata = tif_rawdata_backup; if (!ret) @@ -1350,7 +1361,7 @@ static int LERCVSetField(TIFF *tif, uint32_t tag, va_list ap) { case TIFFTAG_LERC_PARAMETERS: { - uint32_t count = va_arg(ap, int); + uint32_t count = (uint32_t)va_arg(ap, int); int *params = va_arg(ap, int *); if (count < 2) { @@ -1529,6 +1540,13 @@ int TIFFInitLERC(TIFF *tif, int scheme) #endif tif->tif_cleanup = LERCCleanup; + /* LERC compression ratio can grow to several millions */ + /* eg. 5703725 for Lerc deflate on 16383x16383 array */ + /* or 3829644 for regular Lerc */ + /* See README_for_libtiff_developpers.md for raw data used to estimate + * the maximum compression rate. */ + /* so we don't define tif->tif_getmaxcompressionratio */ + /* 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); diff --git a/3rdparty/libtiff/tif_luv.c b/3rdparty/libtiff/tif_luv.c index ecc3225265..d9bc8fe310 100644 --- a/3rdparty/libtiff/tif_luv.c +++ b/3rdparty/libtiff/tif_luv.c @@ -212,7 +212,7 @@ static int LogL16Decode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) } tp = (int16_t *)sp->tbuf; } - _TIFFmemset((void *)tp, 0, npixels * sizeof(tp[0])); + _TIFFmemset((void *)tp, 0, (tmsize_t)((size_t)npixels * sizeof(tp[0]))); bp = (unsigned char *)tif->tif_rawcp; cc = tif->tif_rawcc; @@ -235,7 +235,7 @@ static int LogL16Decode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) { /* non-run */ rc = *bp++; /* nul is noop */ while (--cc && rc-- && i < npixels) - tp[i++] |= (int16_t)*bp++ << shft; + tp[i++] |= (int16_t)(*bp++ << shft); } } if (i != npixels) @@ -243,7 +243,7 @@ static int LogL16Decode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) TIFFErrorExtR(tif, module, "Not enough data at row %" PRIu32 " (short %" TIFF_SSIZE_FORMAT " pixels)", - tif->tif_row, npixels - i); + tif->tif_dir.td_row, npixels - i); tif->tif_rawcp = (uint8_t *)bp; tif->tif_rawcc = cc; return (0); @@ -290,7 +290,7 @@ static int LogLuvDecode24(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) cc = tif->tif_rawcc; for (i = 0; i < npixels && cc >= 3; i++) { - tp[i] = bp[0] << 16 | bp[1] << 8 | bp[2]; + tp[i] = (uint32_t)bp[0] << 16 | (uint32_t)bp[1] << 8 | bp[2]; bp += 3; cc -= 3; } @@ -301,7 +301,7 @@ static int LogLuvDecode24(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) TIFFErrorExtR(tif, module, "Not enough data at row %" PRIu32 " (short %" TIFF_SSIZE_FORMAT " pixels)", - tif->tif_row, npixels - i); + tif->tif_dir.td_row, npixels - i); return (0); } (*sp->tfunc)(sp, op, npixels); @@ -342,7 +342,7 @@ static int LogLuvDecode32(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) } tp = (uint32_t *)sp->tbuf; } - _TIFFmemset((void *)tp, 0, npixels * sizeof(tp[0])); + _TIFFmemset((void *)tp, 0, (tmsize_t)((size_t)npixels * sizeof(tp[0]))); bp = (unsigned char *)tif->tif_rawcp; cc = tif->tif_rawcc; @@ -373,7 +373,7 @@ static int LogLuvDecode32(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) TIFFErrorExtR(tif, module, "Not enough data at row %" PRIu32 " (short %" TIFF_SSIZE_FORMAT " pixels)", - tif->tif_row, npixels - i); + tif->tif_dir.td_row, npixels - i); tif->tif_rawcp = (uint8_t *)bp; tif->tif_rawcc = cc; return (0); @@ -767,25 +767,21 @@ static int LogLuvEncodeTile(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) #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)) #define TIFF_RAND_MAX 32767 // From POSIX.1-2001 as an example of an implementation of rand() -static uint32_t _TIFFRand() +static uint32_t _TIFFRand(void) { static uint32_t nCounter = 0; if (!nCounter) nCounter = (uint32_t)(time(NULL) & UINT32_MAX); ++nCounter; uint32_t nCounterLocal = - (uint32_t)(((uint64_t)(nCounter)*1103515245U + 12345U) & UINT32_MAX); + (uint32_t)(((uint64_t)(nCounter) * 1103515245U + 12345U) & UINT32_MAX); nCounter = nCounterLocal; return (nCounterLocal / 65536U) % (TIFF_RAND_MAX + 1); -}; +} static int tiff_itrunc(double x, int m) { @@ -797,8 +793,7 @@ static int tiff_itrunc(double x, int m) #if !LOGLUV_PUBLIC static #endif - double - LogL16toY(int p16) /* compute luminance from 16-bit LogL */ + double LogL16toY(int p16) /* compute luminance from 16-bit LogL */ { int Le = p16 & 0x7fff; double Y; @@ -812,8 +807,7 @@ static #if !LOGLUV_PUBLIC static #endif - int - LogL16fromY(double Y, int em) /* get 16-bit LogL from Y */ + int LogL16fromY(double Y, int em) /* get 16-bit LogL from Y */ { if (Y >= 1.8371976e19) return (0x7fff); @@ -855,20 +849,22 @@ static void L16fromY(LogLuvState *sp, uint8_t *op, tmsize_t n) float *yp = (float *)op; while (n-- > 0) - *l16++ = (int16_t)(LogL16fromY(*yp++, sp->encode_meth)); + *l16++ = (int16_t)(LogL16fromY((double)*yp++, sp->encode_meth)); } #if !LOGLUV_PUBLIC static #endif - void - XYZtoRGB24(float *xyz, uint8_t *rgb) + 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]; + r = 2.690 * (double)xyz[0] + -1.276 * (double)xyz[1] + + -0.414 * (double)xyz[2]; + g = -1.022 * (double)xyz[0] + 1.978 * (double)xyz[1] + + 0.044 * (double)xyz[2]; + b = 0.061 * (double)xyz[0] + -0.224 * (double)xyz[1] + + 1.163 * (double)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))); @@ -879,8 +875,7 @@ static #if !LOGLUV_PUBLIC static #endif - double - LogL10toY(int p10) /* compute luminance from 10-bit LogL */ + double LogL10toY(int p10) /* compute luminance from 10-bit LogL */ { if (p10 == 0) return (0.); @@ -890,8 +885,7 @@ static #if !LOGLUV_PUBLIC static #endif - int - LogL10fromY(double Y, int em) /* get 10-bit LogL from Y */ + int LogL10fromY(double Y, int em) /* get 10-bit LogL from Y */ { if (Y >= 15.742) return (0x3ff); @@ -903,13 +897,14 @@ static #define NANGLES 100 #define uv2ang(u, v) \ - ((NANGLES * .499999999 / M_PI) * atan2((v)-V_NEU, (u)-U_NEU) + .5 * NANGLES) + ((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; + int i; if (!initialized) { /* set up perimeter table */ @@ -919,13 +914,14 @@ static int oog_encode(double u, double v) /* encode out-of-gamut chroma */ eps[i] = 2.; for (vi = UV_NVS; vi--;) { - va = UV_VSTART + (vi + .5) * UV_SQSIZ; + va = (double)UV_VSTART + ((double)vi + .5) * (double)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; + ua = (double)uv_row[vi].ustart + + ((double)ui + .5) * (double)UV_SQSIZ; ang = uv2ang(ua, va); i = (int)ang; epsa = fabs(ang - (i + .5)); @@ -963,27 +959,28 @@ static int oog_encode(double u, double v) /* encode out-of-gamut chroma */ #if !LOGLUV_PUBLIC static #endif - int - uv_encode(double u, double v, int em) /* encode (u',v') coordinates */ + int uv_encode(double u, double v, int em) /* encode (u',v') coordinates */ { unsigned int vi; int ui; /* check for NaN */ - if (u != u || v != v) + if (isnan(u) || isnan(v)) { u = U_NEU; v = V_NEU; } - if (v < UV_VSTART) + if ((double)v < (double)UV_VSTART) return oog_encode(u, v); - vi = tiff_itrunc((v - UV_VSTART) * (1. / UV_SQSIZ), em); + vi = (unsigned int)tiff_itrunc( + ((double)v - (double)UV_VSTART) * (1. / (double)UV_SQSIZ), em); if (vi >= UV_NVS) return oog_encode(u, v); - if (u < uv_row[vi].ustart) + if ((double)u < (double)uv_row[vi].ustart) return oog_encode(u, v); - ui = tiff_itrunc((u - uv_row[vi].ustart) * (1. / UV_SQSIZ), em); + ui = tiff_itrunc( + ((double)u - (double)uv_row[vi].ustart) * (1. / (double)UV_SQSIZ), em); if (ui >= uv_row[vi].nus) return oog_encode(u, v); @@ -993,8 +990,7 @@ static #if !LOGLUV_PUBLIC static #endif - int - uv_decode(double *up, double *vp, int c) /* decode (u',v') index */ + int uv_decode(double *up, double *vp, int c) /* decode (u',v') index */ { unsigned int upper, lower; int ui; @@ -1020,16 +1016,15 @@ static } vi = lower; ui = c - uv_row[vi].ncum; - *up = uv_row[vi].ustart + (ui + .5) * UV_SQSIZ; - *vp = UV_VSTART + (vi + .5) * UV_SQSIZ; + *up = (double)uv_row[vi].ustart + ((double)ui + .5) * (double)UV_SQSIZ; + *vp = (double)UV_VSTART + ((double)vi + .5) * (double)UV_SQSIZ; return (0); } #if !LOGLUV_PUBLIC static #endif - void - LogLuv24toXYZ(uint32_t p, float *XYZ) + void LogLuv24toXYZ(uint32_t p, float *XYZ) { int Ce; double L, u, v, s, x, y; @@ -1059,15 +1054,14 @@ static #if !LOGLUV_PUBLIC static #endif - uint32_t - LogLuv24fromXYZ(float *XYZ, int em) + uint32_t LogLuv24fromXYZ(float *XYZ, int em) { int Le, Ce; double u, v, s; /* encode luminance */ - Le = LogL10fromY(XYZ[1], em); + Le = LogL10fromY((double)XYZ[1], em); /* encode color */ - s = XYZ[0] + 15. * XYZ[1] + 3. * XYZ[2]; + s = (double)XYZ[0] + 15. * (double)XYZ[1] + 3. * (double)XYZ[2]; if (!Le || s <= 0.) { u = U_NEU; @@ -1075,14 +1069,14 @@ static } else { - u = 4. * XYZ[0] / s; - v = 9. * XYZ[1] / s; + u = 4. * (double)XYZ[0] / s; + v = 9. * (double)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); + return (uint32_t)Le << 14 | (uint32_t)Ce; } static void Luv24toXYZ(LogLuvState *sp, uint8_t *op, tmsize_t n) @@ -1113,8 +1107,8 @@ static void Luv24toLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n) u = U_NEU; v = V_NEU; } - *luv3++ = (int16_t)(u * (1L << 15)); - *luv3++ = (int16_t)(v * (1L << 15)); + *luv3++ = (int16_t)(u * (1 << 15)); + *luv3++ = (int16_t)(v * (1 << 15)); luv++; } } @@ -1168,7 +1162,7 @@ static void Luv24fromLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n) sp->encode_meth); if (Ce < 0) /* never happens */ Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER); - *luv++ = (uint32_t)Le << 14 | Ce; + *luv++ = (uint32_t)Le << 14 | (uint32_t)Ce; luv3 += 3; } } @@ -1176,8 +1170,7 @@ static void Luv24fromLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n) #if !LOGLUV_PUBLIC static #endif - void - LogLuv32toXYZ(uint32_t p, float *XYZ) + void LogLuv32toXYZ(uint32_t p, float *XYZ) { double L, u, v, s, x, y; /* decode luminance */ @@ -1202,15 +1195,14 @@ static #if !LOGLUV_PUBLIC static #endif - uint32_t - LogLuv32fromXYZ(float *XYZ, int em) + 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); + Le = (unsigned int)LogL16fromY((double)XYZ[1], em); /* encode color */ - s = XYZ[0] + 15. * XYZ[1] + 3. * XYZ[2]; + s = (double)XYZ[0] + 15. * (double)XYZ[1] + 3. * (double)XYZ[2]; if (!Le || s <= 0.) { u = U_NEU; @@ -1218,19 +1210,19 @@ static } else { - u = 4. * XYZ[0] / s; - v = 9. * XYZ[1] / s; + u = 4. * (double)XYZ[0] / s; + v = 9. * (double)XYZ[1] / s; } if (u <= 0.) ue = 0; else - ue = tiff_itrunc(UVSCALE * u, em); + ue = (unsigned int)tiff_itrunc(UVSCALE * u, em); if (ue > 255) ue = 255; if (v <= 0.) ve = 0; else - ve = tiff_itrunc(UVSCALE * v, em); + ve = (unsigned int)tiff_itrunc(UVSCALE * v, em); if (ve > 255) ve = 255; /* combine encodings */ @@ -1261,8 +1253,8 @@ static void Luv32toLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n) *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)); + *luv3++ = (int16_t)(u * (1 << 15)); + *luv3++ = (int16_t)(v * (1 << 15)); luv++; } } @@ -1303,22 +1295,24 @@ static void Luv32fromLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n) { 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); + *luv++ = + (uint32_t)luv3[0] << 16 | + ((uint32_t)luv3[1] * (uint32_t)(UVSCALE + .5) >> 7 & 0xff00) | + ((uint32_t)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); + *luv++ = (uint32_t)luv3[0] << 16 | + ((uint32_t)tiff_itrunc(luv3[1] * (UVSCALE / (1 << 15)), + sp->encode_meth) + << 8 & + 0xff00) | + ((uint32_t)tiff_itrunc(luv3[2] * (UVSCALE / (1 << 15)), + sp->encode_meth) & + 0xff); luv3 += 3; } } @@ -1345,6 +1339,8 @@ static int LogL16GuessDataFmt(TIFFDirectory *td) case PACK(1, 8, SAMPLEFORMAT_VOID): case PACK(1, 8, SAMPLEFORMAT_UINT): return (SGILOGDATAFMT_8BIT); + default: + break; } #undef PACK return (SGILOGDATAFMT_UNKNOWN); @@ -1399,7 +1395,7 @@ static int LogL16InitState(TIFF *tif) 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) + tif, (tmsize_t)((size_t)sp->tbuflen * sizeof(int16_t)))) == NULL) { TIFFErrorExtR(tif, module, "No space for SGILog translation buffer"); return (0); @@ -1506,7 +1502,7 @@ static int LogLuvInitState(TIFF *tif) 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) + tif, (tmsize_t)((size_t)sp->tbuflen * sizeof(uint32_t)))) == NULL) { TIFFErrorExtR(tif, module, "No space for SGILog translation buffer"); return (0); @@ -1546,6 +1542,8 @@ static int LogLuvSetupDecode(TIFF *tif) case SGILOGDATAFMT_8BIT: sp->tfunc = Luv24toRGB; break; + default: + break; } } else @@ -1562,6 +1560,8 @@ static int LogLuvSetupDecode(TIFF *tif) case SGILOGDATAFMT_8BIT: sp->tfunc = Luv32toRGB; break; + default: + break; } } return (1); @@ -1577,6 +1577,8 @@ static int LogLuvSetupDecode(TIFF *tif) case SGILOGDATAFMT_8BIT: sp->tfunc = L16toGry; break; + default: + break; } return (1); default: @@ -1755,8 +1757,9 @@ static int LogLuvVSetField(TIFF *tif, uint32_t tag, va_list ap) /* * Must recalculate sizes should bits/sample change. */ - tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)-1; - tif->tif_scanlinesize = TIFFScanlineSize(tif); + tif->tif_dir.td_tilesize = + isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)-1; + tif->tif_dir.td_scanlinesize = TIFFScanlineSize(tif); return (1); case TIFFTAG_SGILOGENCODE: sp->encode_meth = (int)va_arg(ap, int); diff --git a/3rdparty/libtiff/tif_lzma.c b/3rdparty/libtiff/tif_lzma.c index 9834ae2c2c..7763f61acd 100644 --- a/3rdparty/libtiff/tif_lzma.c +++ b/3rdparty/libtiff/tif_lzma.c @@ -95,6 +95,17 @@ static const char *LZMAStrerror(lzma_ret ret) return "no progress is possible (stream is truncated or corrupt)"; case LZMA_PROG_ERROR: return "programming error"; +#if LZMA_VERSION >= 50040000 /* 5.4.0 */ + case LZMA_SEEK_NEEDED: + case LZMA_RET_INTERNAL1: + case LZMA_RET_INTERNAL2: + case LZMA_RET_INTERNAL3: + case LZMA_RET_INTERNAL4: + case LZMA_RET_INTERNAL5: + case LZMA_RET_INTERNAL6: + case LZMA_RET_INTERNAL7: + case LZMA_RET_INTERNAL8: +#endif default: return "unidentified liblzma error"; } @@ -179,7 +190,7 @@ static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) TIFFErrorExtR(tif, module, "LZMADecode: Scanline %" PRIu32 " cannot be read due to " "previous error", - tif->tif_row); + tif->tif_dir.td_row); return 0; } @@ -231,7 +242,7 @@ static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) { TIFFErrorExtR(tif, module, "Decoding error at scanline %" PRIu32 ", %s", - tif->tif_row, LZMAStrerror(ret)); + tif->tif_dir.td_row, LZMAStrerror(ret)); break; } } while (sp->stream.avail_out > 0); @@ -242,12 +253,12 @@ static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) TIFFErrorExtR(tif, module, "Not enough data at scanline %" PRIu32 " (short %" TIFF_SIZE_FORMAT " bytes)", - tif->tif_row, sp->stream.avail_out); + tif->tif_dir.td_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; + tif->tif_rawcc = (tmsize_t)sp->stream.avail_in; return 1; } @@ -326,7 +337,7 @@ static int LZMAEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { TIFFErrorExtR(tif, module, "Encoding error at scanline %" PRIu32 ", %s", - tif->tif_row, LZMAStrerror(ret)); + tif->tif_dir.td_row, LZMAStrerror(ret)); return 0; } if (sp->stream.avail_out == 0) @@ -365,7 +376,7 @@ static int LZMAPostEncode(TIFF *tif) if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) { tif->tif_rawcc = - tif->tif_rawdatasize - sp->stream.avail_out; + tif->tif_rawdatasize - (tmsize_t)sp->stream.avail_out; if (!TIFFFlushData1(tif)) return 0; sp->stream.next_out = tif->tif_rawdata; @@ -376,6 +387,27 @@ static int LZMAPostEncode(TIFF *tif) ZIPPreEncode */ } break; + case LZMA_NO_CHECK: + case LZMA_UNSUPPORTED_CHECK: + case LZMA_GET_CHECK: + case LZMA_MEM_ERROR: + case LZMA_MEMLIMIT_ERROR: + case LZMA_FORMAT_ERROR: + case LZMA_OPTIONS_ERROR: + case LZMA_DATA_ERROR: + case LZMA_BUF_ERROR: + case LZMA_PROG_ERROR: +#if LZMA_VERSION >= 50040000 /* 5.4.0 */ + case LZMA_SEEK_NEEDED: + case LZMA_RET_INTERNAL1: + case LZMA_RET_INTERNAL2: + case LZMA_RET_INTERNAL3: + case LZMA_RET_INTERNAL4: + case LZMA_RET_INTERNAL5: + case LZMA_RET_INTERNAL6: + case LZMA_RET_INTERNAL7: + case LZMA_RET_INTERNAL8: +#endif default: TIFFErrorExtR(tif, module, "Liblzma error: %s", LZMAStrerror(ret)); @@ -416,7 +448,7 @@ static int LZMAVSetField(TIFF *tif, uint32_t tag, va_list ap) { case TIFFTAG_LZMAPRESET: sp->preset = (int)va_arg(ap, int); - lzma_lzma_preset(&sp->opt_lzma, sp->preset); + lzma_lzma_preset(&sp->opt_lzma, (uint32_t)sp->preset); if (sp->state & LSTATE_INIT_ENCODE) { lzma_ret ret = @@ -454,6 +486,21 @@ static const TIFFField lzmaFields[] = { FALSE, "LZMA2 Compression Preset", NULL}, }; +static uint64_t LZMAGetMaxCompressionRatio(TIFF *tif) +{ + (void)tif; + + /* See README_for_libtiff_developpers.md for raw data used to estimate + * the maximum compression rate. */ + + /* 1024x1024: 3800 */ + /* 4096x4096: 6534 */ + /* 16383x16383: 6846 */ + /* 65536x65536: 6874 */ + + return 7000; +} + int TIFFInitLZMA(TIFF *tif, int scheme) { static const char module[] = "TIFFInitLZMA"; @@ -506,7 +553,7 @@ int TIFFInitLZMA(TIFF *tif, int scheme) sp->filters[0].id = LZMA_FILTER_DELTA; sp->filters[0].options = &sp->opt_delta; - lzma_lzma_preset(&sp->opt_lzma, sp->preset); + lzma_lzma_preset(&sp->opt_lzma, (uint32_t)sp->preset); sp->filters[1].id = LZMA_FILTER_LZMA2; sp->filters[1].options = &sp->opt_lzma; @@ -529,6 +576,8 @@ int TIFFInitLZMA(TIFF *tif, int scheme) tif->tif_encodestrip = LZMAEncode; tif->tif_encodetile = LZMAEncode; tif->tif_cleanup = LZMACleanup; + tif->tif_getmaxcompressionratio = LZMAGetMaxCompressionRatio; + /* * Setup predictor setup. */ diff --git a/3rdparty/libtiff/tif_lzw.c b/3rdparty/libtiff/tif_lzw.c index 4bf845b393..d9f56a427b 100644 --- a/3rdparty/libtiff/tif_lzw.c +++ b/3rdparty/libtiff/tif_lzw.c @@ -60,7 +60,7 @@ typedef size_t WordType; */ #define LZW_COMPAT /* include backwards compatibility code */ -#define MAXCODE(n) ((1L << (n)) - 1) +#define MAXCODE(n) ((1 << (n)) - 1) /* * The TIFF spec specifies that encoded bit * strings range from 9 to 12 bits. @@ -72,7 +72,7 @@ typedef size_t WordType; #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 HSIZE 9001 /* 91% occupancy */ #define HSHIFT (13 - 8) #ifdef LZW_COMPAT /* NB: +1024 is for compatibility with old files */ @@ -325,7 +325,7 @@ static int LZWPreDecode(TIFF *tif, uint16_t s) */ /* Get the next 32 or 64-bit from the input data */ -#ifdef WORDS_BIGENDIAN +#if WORDS_BIGENDIAN #define GetNextData(nextdata, bp) memcpy(&nextdata, bp, sizeof(nextdata)) #elif SIZEOF_WORDTYPE == 8 #if defined(_M_X64) @@ -372,7 +372,7 @@ static int LZWPreDecode(TIFF *tif, uint16_t s) nextbits += 8 * SIZEOF_WORDTYPE; \ dec_bitsleft -= 8 * SIZEOF_WORDTYPE; \ code = (WordType)((codetmp | (nextdata >> nextbits)) & \ - nbitsmask); \ + (WordType)nbitsmask); \ break; \ } \ else \ @@ -396,7 +396,7 @@ static int LZWPreDecode(TIFF *tif, uint16_t s) } \ } \ } \ - code = (WordType)((nextdata >> nextbits) & nbitsmask); \ + code = (WordType)((nextdata >> nextbits) & (WordType)nbitsmask); \ } while (0) static int LZWDecode(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s) @@ -420,7 +420,7 @@ static int LZWDecode(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s) TIFFErrorExtR(tif, module, "LZWDecode: Scanline %" PRIu32 " cannot be read due to " "previous error", - tif->tif_row); + tif->tif_dir.td_row); return 0; } @@ -472,7 +472,8 @@ static int LZWDecode(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s) } bp = (uint8_t *)tif->tif_rawcp; - sp->dec_bitsleft += (((uint64_t)tif->tif_rawcc - sp->old_tif_rawcc) << 3); + sp->dec_bitsleft += + (((uint64_t)tif->tif_rawcc - (uint64_t)sp->old_tif_rawcc) << 3); uint64_t dec_bitsleft = sp->dec_bitsleft; nbits = sp->lzw_nbits; nextdata = sp->lzw_nextdata; @@ -493,7 +494,7 @@ begin: { WordType code; GetNextCodeLZW(); - codep = dec_codetab + code; + codep = dec_codetab + (unsigned long)code; if (code >= CODE_FIRST) goto code_above_or_equal_to_258; if (code < 256) @@ -508,7 +509,7 @@ code_below_256: goto error_code; free_entp->next = oldcodep; free_entp->firstchar = oldcodep->firstchar; - free_entp->length = oldcodep->length + 1; + free_entp->length = (uint16_t)(oldcodep->length + 1); free_entp->value = (uint8_t)code; free_entp->repeated = (bool)(oldcodep->repeated & (oldcodep->value == code)); @@ -556,7 +557,7 @@ code_above_or_equal_to_258: free_entp->next = oldcodep; free_entp->firstchar = oldcodep->firstchar; - free_entp->length = oldcodep->length + 1; + free_entp->length = (uint16_t)(oldcodep->length + 1); if (++free_entp > maxcodep) { if (++nbits > BITS_MAX) /* should not happen for a conformant encoder */ @@ -673,7 +674,7 @@ code_clear: free_entp = dec_codetab + CODE_FIRST; nbits = BITS_MIN; nbitsmask = MAXCODE(BITS_MIN); - maxcodep = dec_codetab + nbitsmask - 1; + maxcodep = dec_codetab + (unsigned long)nbitsmask - 1; do { GetNextCodeLZW(); @@ -736,7 +737,7 @@ after_loop: TIFFErrorExtR(tif, module, "Not enough data at scanline %" PRIu32 " (short %" PRIu64 " bytes)", - tif->tif_row, (uint64_t)occ); + tif->tif_dir.td_row, (uint64_t)occ); return (0); } return (1); @@ -746,7 +747,7 @@ no_eoi: sp->read_error = 1; TIFFErrorExtR(tif, module, "LZWDecode: Strip %" PRIu32 " not terminated with EOI code", - tif->tif_curstrip); + tif->tif_dir.td_curstrip); return 0; error_code: memset(op, 0, (size_t)occ); @@ -768,13 +769,13 @@ error_code: TIFFWarningExtR(_tif, module, \ "LZWDecode: Strip %" PRIu32 \ " not terminated with EOI code", \ - _tif->tif_curstrip); \ + _tif->tif_dir.td_curstrip); \ _code = CODE_EOI; \ } \ else \ { \ _get(_sp, _bp, _code); \ - dec_bitsleft -= nbits; \ + dec_bitsleft -= (uint64_t)nbits; \ } \ } @@ -790,7 +791,7 @@ error_code: nextdata |= (unsigned long)*(bp)++ << nextbits; \ nextbits += 8; \ } \ - code = (hcode_t)(nextdata & nbitsmask); \ + code = (hcode_t)(nextdata & (unsigned long)nbitsmask); \ nextdata >>= nbits; \ nextbits -= nbits; \ } @@ -858,7 +859,8 @@ static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s) bp = (uint8_t *)tif->tif_rawcp; - sp->dec_bitsleft += (((uint64_t)tif->tif_rawcc - sp->old_tif_rawcc) << 3); + sp->dec_bitsleft += + (((uint64_t)tif->tif_rawcc - (uint64_t)sp->old_tif_rawcc) << 3); uint64_t dec_bitsleft = sp->dec_bitsleft; nbits = sp->lzw_nbits; @@ -893,7 +895,7 @@ static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s) TIFFErrorExtR( tif, tif->tif_name, "LZWDecode: Corrupted LZW table at scanline %" PRIu32, - tif->tif_row); + tif->tif_dir.td_row); return (0); } *op++ = (uint8_t)code; @@ -911,7 +913,7 @@ static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s) { TIFFErrorExtR(tif, module, "Corrupted LZW table at scanline %" PRIu32, - tif->tif_row); + tif->tif_dir.td_row); return (0); } @@ -921,11 +923,11 @@ static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s) { TIFFErrorExtR(tif, module, "Corrupted LZW table at scanline %" PRIu32, - tif->tif_row); + tif->tif_dir.td_row); return (0); } free_entp->firstchar = free_entp->next->firstchar; - free_entp->length = free_entp->next->length + 1; + free_entp->length = (uint16_t)(free_entp->next->length + 1); free_entp->value = (codep < free_entp) ? codep->firstchar : free_entp->firstchar; if (++free_entp > maxcodep) @@ -948,7 +950,7 @@ static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s) tif, module, "Wrong length of decoded " "string: data probably corrupted at scanline %" PRIu32, - tif->tif_row); + tif->tif_dir.td_row); return (0); } if (codep->length > occ) @@ -1010,7 +1012,7 @@ static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s) TIFFErrorExtR(tif, module, "Not enough data at scanline %" PRIu32 " (short %" PRIu64 " bytes)", - tif->tif_row, (uint64_t)occ); + tif->tif_dir.td_row, (uint64_t)occ); return (0); } return (1); @@ -1116,10 +1118,10 @@ static int LZWPreEncode(TIFF *tif, uint16_t s) */ static int LZWEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - register LZWCodecState *sp = LZWEncoderState(tif); - register long fcode; - register hash_t *hp; - register int h, c; + LZWCodecState *sp = LZWEncoderState(tif); + long fcode; + hash_t *hp; + int h, c; hcode_t ent; long disp; tmsize_t incount, outcount, checkpoint; @@ -1196,7 +1198,7 @@ static int LZWEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) * Avoid pointer arithmetic because of * wraparound problems with segments. */ - if ((h -= disp) < 0) + if ((h -= (int)disp) < 0) h += HSIZE; hp = &sp->enc_hashtab[h]; if (hp->hash == fcode) @@ -1301,7 +1303,7 @@ static int LZWEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) */ static int LZWPostEncode(TIFF *tif) { - register LZWCodecState *sp = LZWEncoderState(tif); + LZWCodecState *sp = LZWEncoderState(tif); uint8_t *op = tif->tif_rawcp; long nextbits = sp->lzw_nextbits; WordType nextdata = sp->lzw_nextdata; @@ -1319,7 +1321,7 @@ static int LZWPostEncode(TIFF *tif) { int free_ent = sp->lzw_free_ent; - PutNextCode(op, sp->enc_oldcode); + PutNextCode(op, (WordType)sp->enc_oldcode); sp->enc_oldcode = (hcode_t)-1; free_ent++; @@ -1357,8 +1359,8 @@ static int LZWPostEncode(TIFF *tif) */ static void cl_hash(LZWCodecState *sp) { - register hash_t *hp = &sp->enc_hashtab[HSIZE - 1]; - register long i = HSIZE - 8; + hash_t *hp = &sp->enc_hashtab[HSIZE - 1]; + long i = HSIZE - 8; do { @@ -1397,6 +1399,21 @@ static void LZWCleanup(TIFF *tif) _TIFFSetDefaultCompressionState(tif); } +static uint64_t LZWGetMaxCompressionRatio(TIFF *tif) +{ + (void)tif; + + /* See README_for_libtiff_developpers.md for raw data used to estimate + * the maximum compression rate. */ + + /* 1024x1024: 562 */ + /* 4096x4096: 1243 */ + /* 16383x16383: 1353 */ + /* 65536x65536: 1362 */ + + return 1400; +} + int TIFFInitLZW(TIFF *tif, int scheme) { static const char module[] = "TIFFInitLZW"; @@ -1430,6 +1447,7 @@ int TIFFInitLZW(TIFF *tif, int scheme) tif->tif_encodestrip = LZWEncode; tif->tif_encodetile = LZWEncode; #endif + tif->tif_getmaxcompressionratio = LZWGetMaxCompressionRatio; tif->tif_cleanup = LZWCleanup; /* * Setup predictor setup. diff --git a/3rdparty/libtiff/tif_next.c b/3rdparty/libtiff/tif_next.c index f000574ee7..04ae474b95 100644 --- a/3rdparty/libtiff/tif_next.c +++ b/3rdparty/libtiff/tif_next.c @@ -38,21 +38,22 @@ op[0] = (unsigned char)((v) << 6); \ break; \ case 1: \ - op[0] |= (v) << 4; \ + op[0] |= (unsigned char)((v) << 4); \ break; \ case 2: \ - op[0] |= (v) << 2; \ + op[0] |= (unsigned char)((v) << 2); \ break; \ case 3: \ - *op++ |= (v); \ + *op++ |= (unsigned char)(v); \ op_offset++; \ break; \ + default: \ + 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) { @@ -73,7 +74,7 @@ static int NeXTDecode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) bp = (unsigned char *)tif->tif_rawcp; cc = tif->tif_rawcc; - scanline = tif->tif_scanlinesize; + scanline = tif->tif_dir.td_scanlinesize; if (occ % scanline) { TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); @@ -146,7 +147,7 @@ static int NeXTDecode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) { TIFFErrorExtR(tif, module, "Invalid data for scanline %" PRIu32, - tif->tif_row); + tif->tif_dir.td_row); return (0); } if (cc == 0) @@ -163,7 +164,7 @@ static int NeXTDecode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) return (1); bad: TIFFErrorExtR(tif, module, "Not enough data for scanline %" PRIu32, - tif->tif_row); + tif->tif_dir.td_row); return (0); } diff --git a/3rdparty/libtiff/tif_ojpeg.c b/3rdparty/libtiff/tif_ojpeg.c index 5ef7a6af6f..e62ec9ea72 100644 --- a/3rdparty/libtiff/tif_ojpeg.c +++ b/3rdparty/libtiff/tif_ojpeg.c @@ -122,9 +122,6 @@ restarting of LibJpeg decoding session. */ -#define WIN32_LEAN_AND_MEAN -#define VC_EXTRALEAN - #include "tiffiop.h" #ifdef OJPEG_SUPPORT @@ -209,18 +206,12 @@ static const TIFFField ojpegFields[] = { #include "jerror.h" #include "jpeglib.h" -#ifndef TIFF_jpeg_source_mgr_defined -#define TIFF_jpeg_source_mgr_defined -typedef struct jpeg_source_mgr jpeg_source_mgr; -#endif +typedef struct jpeg_source_mgr tiff_ojpeg_source_mgr; -#ifndef TIFF_jpeg_error_mgr_defined -#define TIFF_jpeg_error_mgr_defined -typedef struct jpeg_error_mgr jpeg_error_mgr; -#endif +typedef struct jpeg_error_mgr tiff_ojpeg_error_mgr; -typedef struct jpeg_common_struct jpeg_common_struct; -typedef struct jpeg_decompress_struct jpeg_decompress_struct; +typedef struct jpeg_common_struct tiff_ojpeg_common_struct; +typedef struct jpeg_decompress_struct tiff_ojpeg_decompress_struct; typedef enum { @@ -316,9 +307,9 @@ typedef struct 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; + tiff_ojpeg_error_mgr libjpeg_jpeg_error_mgr; + tiff_ojpeg_decompress_struct libjpeg_jpeg_decompress_struct; + tiff_ojpeg_source_mgr libjpeg_jpeg_source_mgr; uint8_t subsampling_convert_log; uint32_t subsampling_convert_ylinelen; uint32_t subsampling_convert_ylines; @@ -413,46 +404,51 @@ 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, + tiff_ojpeg_decompress_struct *cinfo); +extern int jpeg_read_header_encap(OJPEGState *sp, + tiff_ojpeg_decompress_struct *cinfo, uint8_t require_image); extern int jpeg_start_decompress_encap(OJPEGState *sp, - jpeg_decompress_struct *cinfo); + tiff_ojpeg_decompress_struct *cinfo); extern int jpeg_read_scanlines_encap(OJPEGState *sp, - jpeg_decompress_struct *cinfo, + tiff_ojpeg_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); + tiff_ojpeg_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, + tiff_ojpeg_decompress_struct *j); +static int jpeg_read_header_encap(OJPEGState *sp, + tiff_ojpeg_decompress_struct *cinfo, uint8_t require_image); static int jpeg_start_decompress_encap(OJPEGState *sp, - jpeg_decompress_struct *cinfo); + tiff_ojpeg_decompress_struct *cinfo); static int jpeg_read_scanlines_encap(OJPEGState *sp, - jpeg_decompress_struct *cinfo, + tiff_ojpeg_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); + tiff_ojpeg_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, +OJPEGLibjpegJpegErrorMgrOutputMessage(tiff_ojpeg_common_struct *cinfo); +static void OJPEGLibjpegJpegErrorMgrErrorExit(tiff_ojpeg_common_struct *cinfo); +static void +OJPEGLibjpegJpegSourceMgrInitSource(tiff_ojpeg_decompress_struct *cinfo); +static boolean +OJPEGLibjpegJpegSourceMgrFillInputBuffer(tiff_ojpeg_decompress_struct *cinfo); +static void +OJPEGLibjpegJpegSourceMgrSkipInputData(tiff_ojpeg_decompress_struct *cinfo, long num_bytes); static boolean -OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct *cinfo, +OJPEGLibjpegJpegSourceMgrResyncToRestart(tiff_ojpeg_decompress_struct *cinfo, int desired); -static void OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct *cinfo); +static void +OJPEGLibjpegJpegSourceMgrTermSource(tiff_ojpeg_decompress_struct *cinfo); int TIFFInitOJPEG(TIFF *tif, int scheme) { @@ -473,7 +469,7 @@ int TIFFInitOJPEG(TIFF *tif, int scheme) } /* state block */ - sp = _TIFFmallocExt(tif, sizeof(OJPEGState)); + sp = (OJPEGState *)_TIFFmallocExt(tif, sizeof(OJPEGState)); if (sp == NULL) { TIFFErrorExtR(tif, module, "No space for OJPEG state block"); @@ -724,9 +720,9 @@ static int OJPEGPreDecode(TIFF *tif, uint16_t s) return (0); } if (isTiled(tif)) - m = tif->tif_curtile; + m = tif->tif_dir.td_curtile; else - m = tif->tif_curstrip; + m = tif->tif_dir.td_curstrip; if ((sp->writeheader_done != 0) && ((sp->write_cursample != s) || (sp->write_curstrile > m))) { @@ -797,7 +793,7 @@ static int OJPEGPreDecodeSkipRaw(TIFF *tif) { if (jpeg_read_raw_data_encap(sp, &(sp->libjpeg_jpeg_decompress_struct), sp->subsampling_convert_ycbcrimage, - sp->subsampling_ver * 8) == 0) + (uint32_t)sp->subsampling_ver * 8) == 0) return (0); m -= sp->subsampling_convert_clines; } @@ -805,7 +801,7 @@ static int OJPEGPreDecodeSkipRaw(TIFF *tif) { if (jpeg_read_raw_data_encap(sp, &(sp->libjpeg_jpeg_decompress_struct), sp->subsampling_convert_ycbcrimage, - sp->subsampling_ver * 8) == 0) + (uint32_t)sp->subsampling_ver * 8) == 0) return (0); sp->subsampling_convert_state = m; } @@ -819,7 +815,7 @@ static int OJPEGPreDecodeSkipScanlines(TIFF *tif) uint32_t m; if (sp->skip_buffer == NULL) { - sp->skip_buffer = _TIFFmallocExt(tif, sp->bytes_per_line); + sp->skip_buffer = (uint8_t *)_TIFFmallocExt(tif, sp->bytes_per_line); if (sp->skip_buffer == NULL) { TIFFErrorExtR(tif, module, "Out of memory"); @@ -910,10 +906,10 @@ static int OJPEGDecodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc) { 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) + if (jpeg_read_raw_data_encap( + sp, &(sp->libjpeg_jpeg_decompress_struct), + sp->subsampling_convert_ycbcrimage, + (uint32_t)sp->subsampling_ver * 8) == 0) { sp->error_in_raw_data_decoding = 1; return (0); @@ -1225,7 +1221,7 @@ static int OJPEGReadHeaderInfo(TIFF *tif) TIFFErrorExtR(tif, module, "Invalid subsampling values"); return (0); } - if (sp->strile_length % (sp->subsampling_ver * 8) != 0) + if (sp->strile_length % ((uint32_t)sp->subsampling_ver * 8) != 0) { TIFFErrorExtR(tif, module, "Incompatible vertical subsampling and image " @@ -1233,9 +1229,11 @@ static int OJPEGReadHeaderInfo(TIFF *tif) 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))); + (uint16_t)(((sp->strile_width + (uint32_t)sp->subsampling_hor * 8 - + 1) / + ((uint32_t)sp->subsampling_hor * 8)) * + (sp->strile_length / + ((uint32_t)sp->subsampling_ver * 8))); } if (OJPEGReadHeaderInfoSec(tif) == 0) return (0); @@ -1358,20 +1356,43 @@ static int OJPEGWriteHeaderInfo(TIFF *tif) /* Check for division by zero. */ if (sp->subsampling_hor == 0 || sp->subsampling_ver == 0) return (0); + /* Check for potential overflow in subsampling_convert_ylinelen + * computation. + */ + if (sp->strile_width > + UINT32_MAX - ((uint32_t)sp->subsampling_hor * 8 - 1)) + 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->strile_width + (uint32_t)sp->subsampling_hor * 8 - 1) / + ((uint32_t)sp->subsampling_hor * 8) * + ((uint32_t)sp->subsampling_hor * 8)); + sp->subsampling_convert_ylines = (uint32_t)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; + /* Check for potential overflow in buffer length computations. + * Use 64-bit intermediates to detect uint32_t overflow in + * ylinelen * ylines, clinelen * clines, and their sum. + */ + { + uint64_t ybuflen64 = + (uint64_t)sp->subsampling_convert_ylinelen * + sp->subsampling_convert_ylines; + uint64_t cbuflen64 = + (uint64_t)sp->subsampling_convert_clinelen * + sp->subsampling_convert_clines; + uint64_t ycbcrbuflen64 = ybuflen64 + 2 * cbuflen64; + if (ybuflen64 > UINT32_MAX || cbuflen64 > UINT32_MAX || + ycbcrbuflen64 > UINT32_MAX) + { + TIFFErrorExtR(tif, module, + "Integer overflow in OJPEG buffer size"); + return (0); + } + sp->subsampling_convert_ybuflen = (uint32_t)ybuflen64; + sp->subsampling_convert_cbuflen = (uint32_t)cbuflen64; + sp->subsampling_convert_ycbcrbuflen = (uint32_t)ycbcrbuflen64; + } /* 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 @@ -1383,8 +1404,8 @@ static int OJPEGWriteHeaderInfo(TIFF *tif) /* 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); + sp->subsampling_convert_ycbcrbuf = (uint8_t *)_TIFFcallocExt( + tif, 1, sp->subsampling_convert_ycbcrbuflen); if (sp->subsampling_convert_ycbcrbuf == 0) { TIFFErrorExtR(tif, module, "Out of memory"); @@ -1398,8 +1419,9 @@ static int OJPEGWriteHeaderInfo(TIFF *tif) 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 *)); + sp->subsampling_convert_ycbcrimage = (uint8_t **)_TIFFmallocExt( + tif, (tmsize_t)((size_t)sp->subsampling_convert_ycbcrimagelen * + sizeof(uint8_t *))); if (sp->subsampling_convert_ycbcrimage == 0) { TIFFErrorExtR(tif, module, "Out of memory"); @@ -1426,9 +1448,14 @@ static int OJPEGWriteHeaderInfo(TIFF *tif) ((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); + + const uint64_t bpl = + (uint64_t)sp->subsampling_convert_clinelenout * + ((uint64_t)sp->subsampling_ver * sp->subsampling_hor + 2); + if (bpl > UINT32_MAX) + return (0); + sp->bytes_per_line = (uint32_t)bpl; + sp->lines_per_strile = sp->strile_length / sp->subsampling_ver + ((sp->strile_length % sp->subsampling_ver) != 0 ? 1 : 0); @@ -1478,7 +1505,8 @@ 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))); + jpeg_destroy( + (tiff_ojpeg_common_struct *)(&(sp->libjpeg_jpeg_decompress_struct))); sp->libjpeg_session_active = 0; } @@ -1560,7 +1588,7 @@ static int OJPEGReadHeaderInfoSec(TIFF *tif) return (0); } if (n > 2) - OJPEGReadSkip(sp, n - 2); + OJPEGReadSkip(sp, (uint16_t)(n - 2)); break; case JPEG_MARKER_DRI: if (OJPEGReadHeaderInfoSecStreamDri(tif) == 0) @@ -1603,8 +1631,9 @@ static int OJPEGReadHeaderInfoSec(TIFF *tif) 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); + sp->sof_c[o] = (uint8_t)o; + sp->sof_hv[0] = + (uint8_t)((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; @@ -1659,10 +1688,10 @@ static int OJPEGReadHeaderInfoSecStreamDqt(TIFF *tif) return (0); } if (sp->subsamplingcorrect != 0) - OJPEGReadSkip(sp, m - 2); + OJPEGReadSkip(sp, (uint16_t)(m - 2)); else { - m -= 2; + m = (uint16_t)(m - 2); do { if (m < 65) @@ -1671,7 +1700,7 @@ static int OJPEGReadHeaderInfoSecStreamDqt(TIFF *tif) return (0); } na = sizeof(uint32_t) + 69; - nb = _TIFFmallocExt(tif, na); + nb = (uint8_t *)_TIFFmallocExt(tif, na); if (nb == 0) { TIFFErrorExtR(tif, module, "Out of memory"); @@ -1697,7 +1726,7 @@ static int OJPEGReadHeaderInfoSecStreamDqt(TIFF *tif) if (sp->qtable[o] != 0) _TIFFfreeExt(tif, sp->qtable[o]); sp->qtable[o] = nb; - m -= 65; + m = (uint16_t)(m - 65); } while (m > 0); } return (1); @@ -1725,12 +1754,12 @@ static int OJPEGReadHeaderInfoSecStreamDht(TIFF *tif) } if (sp->subsamplingcorrect != 0) { - OJPEGReadSkip(sp, m - 2); + OJPEGReadSkip(sp, (uint16_t)(m - 2)); } else { - na = sizeof(uint32_t) + 2 + m; - nb = _TIFFmallocExt(tif, na); + na = (uint32_t)(sizeof(uint32_t) + 2 + m); + nb = (uint8_t *)_TIFFmallocExt(tif, na); if (nb == 0) { TIFFErrorExtR(tif, module, "Out of memory"); @@ -1739,9 +1768,10 @@ static int OJPEGReadHeaderInfoSecStreamDht(TIFF *tif) *(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) + nb[sizeof(uint32_t) + 2] = (uint8_t)(m >> 8); + nb[sizeof(uint32_t) + 3] = (uint8_t)(m & 255); + if (OJPEGReadBlock(sp, (uint16_t)(m - 2), &nb[sizeof(uint32_t) + 4]) == + 0) { _TIFFfreeExt(tif, nb); return (0); @@ -1809,7 +1839,7 @@ static int OJPEGReadHeaderInfoSecStreamSof(TIFF *tif, uint8_t marker_id) TIFFErrorExtR(tif, module, "Corrupt SOF marker in JPEG data"); return (0); } - m -= 8; + m = (uint16_t)(m - 8); if (m % 3 != 0) { if (sp->subsamplingcorrect == 0) @@ -2030,7 +2060,7 @@ static int OJPEGReadHeaderInfoSecTablesQTable(TIFF *tif) } } oa = sizeof(uint32_t) + 69; - ob = _TIFFmallocExt(tif, oa); + ob = (uint8_t *)_TIFFmallocExt(tif, oa); if (ob == 0) { TIFFErrorExtR(tif, module, "Out of memory"); @@ -2098,8 +2128,8 @@ static int OJPEGReadHeaderInfoSecTablesDcTable(TIFF *tif) q = 0; for (n = 0; n < 16; n++) q += o[n]; - ra = sizeof(uint32_t) + 21 + q; - rb = _TIFFmallocExt(tif, ra); + ra = (uint32_t)(sizeof(uint32_t) + 21 + q); + rb = (uint8_t *)_TIFFmallocExt(tif, ra); if (rb == 0) { TIFFErrorExtR(tif, module, "Out of memory"); @@ -2122,7 +2152,7 @@ static int OJPEGReadHeaderInfoSecTablesDcTable(TIFF *tif) if (sp->dctable[m] != 0) _TIFFfreeExt(tif, sp->dctable[m]); sp->dctable[m] = rb; - sp->sos_tda[m] = (m << 4); + sp->sos_tda[m] = (uint8_t)(m << 4); } else sp->sos_tda[m] = sp->sos_tda[m - 1]; @@ -2168,8 +2198,8 @@ static int OJPEGReadHeaderInfoSecTablesAcTable(TIFF *tif) q = 0; for (n = 0; n < 16; n++) q += o[n]; - ra = sizeof(uint32_t) + 21 + q; - rb = _TIFFmallocExt(tif, ra); + ra = (uint32_t)(sizeof(uint32_t) + 21 + q); + rb = (uint8_t *)_TIFFmallocExt(tif, ra); if (rb == 0) { TIFFErrorExtR(tif, module, "Out of memory"); @@ -2220,7 +2250,7 @@ static int OJPEGReadBufferFill(OJPEGState *sp) 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) + if (n <= 0) return (0); assert(n > 0); assert(n <= OJPEG_BUFFER); @@ -2286,6 +2316,7 @@ static int OJPEGReadBufferFill(OJPEGState *sp) sp->in_buffer_next_strile++; } break; + case osibsEof: default: return (0); } @@ -2331,7 +2362,7 @@ static int OJPEGReadWord(OJPEGState *sp, uint16_t *word) uint8_t m; if (OJPEGReadByte(sp, &m) == 0) return (0); - *word = (m << 8); + *word = (uint16_t)(m << 8); if (OJPEGReadByte(sp, &m) == 0) return (0); *word |= m; @@ -2345,7 +2376,7 @@ static int OJPEGReadBlock(OJPEGState *sp, uint16_t len, void *mem) uint16_t n; assert(len > 0); mlen = len; - mmem = mem; + mmem = (uint8_t *)mem; do { if (sp->in_buffer_togo == 0) @@ -2359,8 +2390,8 @@ static int OJPEGReadBlock(OJPEGState *sp, uint16_t len, void *mem) n = sp->in_buffer_togo; _TIFFmemcpy(mmem, sp->in_buffer_cur, n); sp->in_buffer_cur += n; - sp->in_buffer_togo -= n; - mlen -= n; + sp->in_buffer_togo = (uint16_t)(sp->in_buffer_togo - n); + mlen = (uint16_t)(mlen - n); mmem += n; } while (mlen > 0); return (1); @@ -2375,8 +2406,8 @@ static void OJPEGReadSkip(OJPEGState *sp, uint16_t len) if (n > sp->in_buffer_togo) n = sp->in_buffer_togo; sp->in_buffer_cur += n; - sp->in_buffer_togo -= n; - m -= n; + sp->in_buffer_togo = (uint16_t)(sp->in_buffer_togo - n); + m = (uint16_t)(m - n); if (m > 0) { assert(sp->in_buffer_togo == 0); @@ -2462,6 +2493,8 @@ static int OJPEGWriteStream(TIFF *tif, void **mem, uint32_t *len) case ososEoi: OJPEGWriteStreamEoi(tif, mem, len); break; + default: + break; } } while (*len == 0); return (1); @@ -2475,7 +2508,7 @@ static void OJPEGWriteStreamSoi(TIFF *tif, void **mem, uint32_t *len) sp->out_buffer[1] = JPEG_MARKER_SOI; *len = 2; *mem = (void *)sp->out_buffer; - sp->out_state++; + sp->out_state = (OJPEGStateOutState)(sp->out_state + 1); } static void OJPEGWriteStreamQTable(TIFF *tif, uint8_t table_index, void **mem, @@ -2485,9 +2518,10 @@ static void OJPEGWriteStreamQTable(TIFF *tif, uint8_t table_index, void **mem, 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); + *len = (uint32_t)(*((uint32_t *)sp->qtable[table_index]) - + sizeof(uint32_t)); } - sp->out_state++; + sp->out_state = (OJPEGStateOutState)(sp->out_state + 1); } static void OJPEGWriteStreamDcTable(TIFF *tif, uint8_t table_index, void **mem, @@ -2497,9 +2531,10 @@ static void OJPEGWriteStreamDcTable(TIFF *tif, uint8_t table_index, void **mem, 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); + *len = (uint32_t)(*((uint32_t *)sp->dctable[table_index]) - + sizeof(uint32_t)); } - sp->out_state++; + sp->out_state = (OJPEGStateOutState)(sp->out_state + 1); } static void OJPEGWriteStreamAcTable(TIFF *tif, uint8_t table_index, void **mem, @@ -2509,9 +2544,10 @@ static void OJPEGWriteStreamAcTable(TIFF *tif, uint8_t table_index, void **mem, 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); + *len = (uint32_t)(*((uint32_t *)sp->actable[table_index]) - + sizeof(uint32_t)); } - sp->out_state++; + sp->out_state = (OJPEGStateOutState)(sp->out_state + 1); } static void OJPEGWriteStreamDri(TIFF *tif, void **mem, uint32_t *len) @@ -2524,12 +2560,12 @@ static void OJPEGWriteStreamDri(TIFF *tif, void **mem, uint32_t *len) 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); + sp->out_buffer[4] = (uint8_t)(sp->restart_interval >> 8); + sp->out_buffer[5] = (uint8_t)(sp->restart_interval & 255); *len = 6; *mem = (void *)sp->out_buffer; } - sp->out_state++; + sp->out_state = (OJPEGStateOutState)(sp->out_state + 1); } static void OJPEGWriteStreamSof(TIFF *tif, void **mem, uint32_t *len) @@ -2542,15 +2578,15 @@ static void OJPEGWriteStreamSof(TIFF *tif, void **mem, uint32_t *len) 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; + sp->out_buffer[3] = (uint8_t)(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); + sp->out_buffer[6] = (uint8_t)(sp->sof_y & 255); /* X */ sp->out_buffer[7] = (uint8_t)(sp->sof_x >> 8); - sp->out_buffer[8] = (sp->sof_x & 255); + sp->out_buffer[8] = (uint8_t)(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++) @@ -2564,9 +2600,9 @@ static void OJPEGWriteStreamSof(TIFF *tif, void **mem, uint32_t *len) sp->out_buffer[10 + m * 3 + 2] = sp->sof_tq[sp->plane_sample_offset + m]; } - *len = 10 + sp->samples_per_pixel_per_plane * 3; + *len = 10 + (uint32_t)sp->samples_per_pixel_per_plane * 3; *mem = (void *)sp->out_buffer; - sp->out_state++; + sp->out_state = (OJPEGStateOutState)(sp->out_state + 1); } static void OJPEGWriteStreamSos(TIFF *tif, void **mem, uint32_t *len) @@ -2579,7 +2615,7 @@ static void OJPEGWriteStreamSos(TIFF *tif, void **mem, uint32_t *len) 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; + sp->out_buffer[3] = (uint8_t)(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++) @@ -2596,9 +2632,9 @@ static void OJPEGWriteStreamSos(TIFF *tif, void **mem, uint32_t *len) 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; + *len = 8 + (uint32_t)sp->samples_per_pixel_per_plane * 2; *mem = (void *)sp->out_buffer; - sp->out_state++; + sp->out_state = (OJPEGStateOutState)(sp->out_state + 1); } static int OJPEGWriteStreamCompressed(TIFF *tif, void **mem, uint32_t *len) @@ -2626,6 +2662,8 @@ static int OJPEGWriteStreamCompressed(TIFF *tif, void **mem, uint32_t *len) case osibsEof: sp->out_state = ososEoi; break; + case osibsNotSetYet: + case osibsJpegInterchangeFormat: default: break; } @@ -2638,7 +2676,7 @@ 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->out_buffer[1] = (uint8_t)(JPEG_MARKER_RST0 + sp->restart_index); sp->restart_index++; if (sp->restart_index == 8) sp->restart_index = 0; @@ -2659,7 +2697,7 @@ static void OJPEGWriteStreamEoi(TIFF *tif, void **mem, uint32_t *len) #ifndef LIBJPEG_ENCAP_EXTERNAL static int jpeg_create_decompress_encap(OJPEGState *sp, - jpeg_decompress_struct *cinfo) + tiff_ojpeg_decompress_struct *cinfo) { if (SETJMP(sp->exit_jmpbuf)) return 0; @@ -2672,7 +2710,8 @@ static int jpeg_create_decompress_encap(OJPEGState *sp, #endif #ifndef LIBJPEG_ENCAP_EXTERNAL -static int jpeg_read_header_encap(OJPEGState *sp, jpeg_decompress_struct *cinfo, +static int jpeg_read_header_encap(OJPEGState *sp, + tiff_ojpeg_decompress_struct *cinfo, uint8_t require_image) { if (SETJMP(sp->exit_jmpbuf)) @@ -2687,7 +2726,7 @@ static int jpeg_read_header_encap(OJPEGState *sp, jpeg_decompress_struct *cinfo, #ifndef LIBJPEG_ENCAP_EXTERNAL static int jpeg_start_decompress_encap(OJPEGState *sp, - jpeg_decompress_struct *cinfo) + tiff_ojpeg_decompress_struct *cinfo) { if (SETJMP(sp->exit_jmpbuf)) return 0; @@ -2701,14 +2740,14 @@ static int jpeg_start_decompress_encap(OJPEGState *sp, #ifndef LIBJPEG_ENCAP_EXTERNAL static int jpeg_read_scanlines_encap(OJPEGState *sp, - jpeg_decompress_struct *cinfo, + tiff_ojpeg_decompress_struct *cinfo, void *scanlines, uint32_t max_lines) { if (SETJMP(sp->exit_jmpbuf)) return 0; else { - jpeg_read_scanlines(cinfo, scanlines, max_lines); + jpeg_read_scanlines(cinfo, (JSAMPARRAY)scanlines, max_lines); return 1; } } @@ -2716,14 +2755,14 @@ static int jpeg_read_scanlines_encap(OJPEGState *sp, #ifndef LIBJPEG_ENCAP_EXTERNAL static int jpeg_read_raw_data_encap(OJPEGState *sp, - jpeg_decompress_struct *cinfo, void *data, - uint32_t max_lines) + tiff_ojpeg_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); + jpeg_read_raw_data(cinfo, (JSAMPIMAGE)data, max_lines); return 1; } } @@ -2737,14 +2776,15 @@ static void jpeg_encap_unwind(TIFF *tif) } #endif -static void OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct *cinfo) +static void +OJPEGLibjpegJpegErrorMgrOutputMessage(tiff_ojpeg_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) +static void OJPEGLibjpegJpegErrorMgrErrorExit(tiff_ojpeg_common_struct *cinfo) { char buffer[JMSG_LENGTH_MAX]; (*cinfo->err->format_message)(cinfo, buffer); @@ -2752,13 +2792,14 @@ static void OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct *cinfo) jpeg_encap_unwind((TIFF *)(cinfo->client_data)); } -static void OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct *cinfo) +static void +OJPEGLibjpegJpegSourceMgrInitSource(tiff_ojpeg_decompress_struct *cinfo) { (void)cinfo; } static boolean -OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct *cinfo) +OJPEGLibjpegJpegSourceMgrFillInputBuffer(tiff_ojpeg_decompress_struct *cinfo) { TIFF *tif = (TIFF *)cinfo->client_data; OJPEGState *sp = (OJPEGState *)tif->tif_data; @@ -2770,12 +2811,12 @@ OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct *cinfo) jpeg_encap_unwind(tif); } sp->libjpeg_jpeg_source_mgr.bytes_in_buffer = len; - sp->libjpeg_jpeg_source_mgr.next_input_byte = mem; + sp->libjpeg_jpeg_source_mgr.next_input_byte = (const JOCTET *)mem; return (1); } static void -OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct *cinfo, +OJPEGLibjpegJpegSourceMgrSkipInputData(tiff_ojpeg_decompress_struct *cinfo, long num_bytes) { TIFF *tif = (TIFF *)cinfo->client_data; @@ -2789,7 +2830,7 @@ OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct *cinfo, #pragma warning(disable : 4702) /* unreachable code */ #endif static boolean -OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct *cinfo, +OJPEGLibjpegJpegSourceMgrResyncToRestart(tiff_ojpeg_decompress_struct *cinfo, int desired) { TIFF *tif = (TIFF *)cinfo->client_data; @@ -2802,7 +2843,8 @@ OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct *cinfo, #pragma warning(pop) #endif -static void OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct *cinfo) +static void +OJPEGLibjpegJpegSourceMgrTermSource(tiff_ojpeg_decompress_struct *cinfo) { (void)cinfo; } diff --git a/3rdparty/libtiff/tif_open.c b/3rdparty/libtiff/tif_open.c index 565d13cf69..43cb170286 100644 --- a/3rdparty/libtiff/tif_open.c +++ b/3rdparty/libtiff/tif_open.c @@ -77,7 +77,7 @@ int _TIFFgetMode(TIFFOpenOptions *opts, thandle_t clientdata, const char *mode, return (m); } -TIFFOpenOptions *TIFFOpenOptionsAlloc() +TIFFOpenOptions *TIFFOpenOptionsAlloc(void) { TIFFOpenOptions *opts = (TIFFOpenOptions *)_TIFFcalloc(1, sizeof(TIFFOpenOptions)); @@ -308,6 +308,7 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode, TIFF *tif; int m; const char *cp; + tmsize_t size_to_alloc; /* The following are configuration checks. They should be redundant, but * should not compile to any actual code in an optimised release build @@ -330,7 +331,7 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode, n.a8[0] = 1; n.a8[1] = 0; (void)n; -#ifdef WORDS_BIGENDIAN +#if WORDS_BIGENDIAN assert(n.a16 == 256); #else assert(n.a16 == 1); @@ -340,7 +341,7 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode, m = _TIFFgetMode(opts, clientdata, mode, module); if (m == -1) goto bad2; - tmsize_t size_to_alloc = (tmsize_t)(sizeof(TIFF) + strlen(name) + 1); + 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) { @@ -377,8 +378,6 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode, tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER; /* non-existent directory */ tif->tif_curdircount = TIFF_NON_EXISTENT_DIR_NUMBER; 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; @@ -398,6 +397,10 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode, tif->tif_warn_about_unknown_tags = opts->warn_about_unknown_tags; } + /* Reset tif->tif_dir structure to zero and + * initialize some IFD strile counter and index parameters. */ + _TIFFResetTifDirAndInitStrileCounters(&tif->tif_dir); + if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc) { TIFFErrorExtR(tif, module, @@ -480,13 +483,13 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode, switch (*cp) { case 'b': -#ifndef WORDS_BIGENDIAN +#if !WORDS_BIGENDIAN if (m & O_CREAT) tif->tif_flags |= TIFF_SWAB; #endif break; case 'l': -#ifdef WORDS_BIGENDIAN +#if WORDS_BIGENDIAN if ((m & O_CREAT)) tif->tif_flags |= TIFF_SWAB; #endif @@ -536,7 +539,9 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode, case 'O': if (m == O_RDONLY) tif->tif_flags |= - (TIFF_LAZYSTRILELOAD | TIFF_DEFERSTRILELOAD); + (TIFF_LAZYSTRILELOAD_ASKED | TIFF_DEFERSTRILELOAD); + break; + default: break; } @@ -561,7 +566,7 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode, /* * Setup header and write. */ -#ifdef WORDS_BIGENDIAN +#if WORDS_BIGENDIAN tif->tif_header.common.tiff_magic = (tif->tif_flags & TIFF_SWAB) ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN; #else @@ -654,13 +659,13 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode, } if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) { -#ifndef WORDS_BIGENDIAN +#if !WORDS_BIGENDIAN tif->tif_flags |= TIFF_SWAB; #endif } else { -#ifdef WORDS_BIGENDIAN +#if WORDS_BIGENDIAN tif->tif_flags |= TIFF_SWAB; #endif } @@ -780,6 +785,8 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode, if (!TIFFDefaultDirectory(tif)) goto bad; return (tif); + default: + break; } bad: tif->tif_mode = O_RDONLY; /* XXX avoid flush */ @@ -861,7 +868,7 @@ int TIFFIsTiled(TIFF *tif) { return (isTiled(tif)); } /* * Return current row being read/written. */ -uint32_t TIFFCurrentRow(TIFF *tif) { return (tif->tif_row); } +uint32_t TIFFCurrentRow(TIFF *tif) { return (tif->tif_dir.td_row); } /* * Return index of the current directory. @@ -871,12 +878,12 @@ tdir_t TIFFCurrentDirectory(TIFF *tif) { return (tif->tif_curdir); } /* * Return current strip. */ -uint32_t TIFFCurrentStrip(TIFF *tif) { return (tif->tif_curstrip); } +uint32_t TIFFCurrentStrip(TIFF *tif) { return (tif->tif_dir.td_curstrip); } /* * Return current tile. */ -uint32_t TIFFCurrentTile(TIFF *tif) { return (tif->tif_curtile); } +uint32_t TIFFCurrentTile(TIFF *tif) { return (tif->tif_dir.td_curtile); } /* * Return nonzero if the file has byte-swapped data. diff --git a/3rdparty/libtiff/tif_packbits.c b/3rdparty/libtiff/tif_packbits.c index d7db9b64ea..13d0f1d390 100644 --- a/3rdparty/libtiff/tif_packbits.c +++ b/3rdparty/libtiff/tif_packbits.c @@ -194,12 +194,17 @@ static int PackBitsEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) */ if (n == 1 && op[-2] == (uint8_t)-1 && *lastliteral < 126) { - state = (((*lastliteral) += 2) == 127 ? BASE : LITERAL); + state = + (((*lastliteral) = (uint8_t)(*lastliteral + 2)) == 127 + ? BASE + : LITERAL); op[-2] = op[-1]; /* replicate */ } else state = RUN; goto again; + default: + break; } } tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp); @@ -306,12 +311,22 @@ static int PackBitsDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) { memset(op, 0, (size_t)occ); TIFFErrorExtR(tif, module, "Not enough data for scanline %" PRIu32, - tif->tif_row); + tif->tif_dir.td_row); return (0); } return (1); } +static uint64_t PackBitsGetMaxCompressionRatio(TIFF *tif) +{ + (void)tif; + + /* See README_for_libtiff_developpers.md for raw data used to estimate + * the maximum compression rate. */ + + return 64; +} + int TIFFInitPackBits(TIFF *tif, int scheme) { (void)scheme; @@ -325,6 +340,8 @@ int TIFFInitPackBits(TIFF *tif, int scheme) tif->tif_encodestrip = PackBitsEncodeChunk; tif->tif_encodetile = PackBitsEncodeChunk; #endif + tif->tif_getmaxcompressionratio = PackBitsGetMaxCompressionRatio; + return (1); } #endif /* PACKBITS_SUPPORT */ diff --git a/3rdparty/libtiff/tif_pixarlog.c b/3rdparty/libtiff/tif_pixarlog.c index 309054804d..fa267dfbff 100644 --- a/3rdparty/libtiff/tif_pixarlog.c +++ b/3rdparty/libtiff/tif_pixarlog.c @@ -117,11 +117,11 @@ static float LogK1, LogK2; } while (i > 0); \ } -static void horizontalAccumulateF(uint16_t *wp, int n, int stride, float *op, - float *ToLinearF) +static void horizontalAccumulateF(uint16_t *wp, tmsize_t n, int stride, + float *op, float *ToLinearF) { - register unsigned int cr, cg, cb, ca, mask; - register float t0, t1, t2, t3; + unsigned int cr, cg, cb, ca, mask; + float t0, t1, t2, t3; if (n >= stride) { @@ -180,22 +180,22 @@ static void horizontalAccumulateF(uint16_t *wp, int n, int stride, float *op, n -= stride; while (n > 0) { - REPEAT(stride, wp[stride] += *wp; *op = ToLinearF[*wp & mask]; - wp++; op++) + REPEAT(stride, *wp = (uint16_t)(*wp + wp[-stride]); + *op = ToLinearF[*wp & mask]; wp++; op++) n -= stride; } } } } -static void horizontalAccumulate12(uint16_t *wp, int n, int stride, int16_t *op, - float *ToLinearF) +static void horizontalAccumulate12(uint16_t *wp, tmsize_t n, int stride, + int16_t *op, float *ToLinearF) { - register unsigned int cr, cg, cb, ca, mask; - register float t0, t1, t2, t3; + unsigned int cr, cg, cb, ca, mask; + float t0, t1, t2, t3; -#define SCALE12 2048.0F -#define CLAMP12(t) (((t) < 3071) ? (uint16_t)(t) : 3071) +#define SCALE12 2048.0f +#define CLAMP12(t) (((t) < 3071) ? (int16_t)(uint16_t)(t) : (int16_t)3071) if (n >= stride) { @@ -255,19 +255,19 @@ static void horizontalAccumulate12(uint16_t *wp, int n, int stride, int16_t *op, n -= stride; while (n > 0) { - REPEAT(stride, wp[stride] += *wp; - t0 = ToLinearF[wp[stride] & mask] * SCALE12; - *op = CLAMP12(t0); wp++; op++) + REPEAT(stride, *wp = (uint16_t)(*wp + wp[-stride]); + t0 = ToLinearF[*wp & mask] * SCALE12; *op = CLAMP12(t0); + wp++; op++) n -= stride; } } } } -static void horizontalAccumulate16(uint16_t *wp, int n, int stride, +static void horizontalAccumulate16(uint16_t *wp, tmsize_t n, int stride, uint16_t *op, uint16_t *ToLinear16) { - register unsigned int cr, cg, cb, ca, mask; + unsigned int cr, cg, cb, ca, mask; if (n >= stride) { @@ -312,8 +312,8 @@ static void horizontalAccumulate16(uint16_t *wp, int n, int stride, n -= stride; while (n > 0) { - REPEAT(stride, wp[stride] += *wp; *op = ToLinear16[*wp & mask]; - wp++; op++) + REPEAT(stride, *wp = (uint16_t)(*wp + wp[-stride]); + *op = ToLinear16[*wp & mask]; wp++; op++) n -= stride; } } @@ -324,10 +324,10 @@ static void horizontalAccumulate16(uint16_t *wp, int n, int stride, * Returns the log encoded 11-bit values with the horizontal * differencing undone. */ -static void horizontalAccumulate11(uint16_t *wp, int n, int stride, +static void horizontalAccumulate11(uint16_t *wp, tmsize_t n, int stride, uint16_t *op) { - register unsigned int cr, cg, cb, ca, mask; + unsigned int cr, cg, cb, ca, mask; if (n >= stride) { @@ -375,21 +375,22 @@ static void horizontalAccumulate11(uint16_t *wp, int n, int stride, } else { - REPEAT(stride, *op = *wp & mask; wp++; op++) + REPEAT(stride, *op = (uint16_t)(*wp & mask); wp++; op++) n -= stride; while (n > 0) { - REPEAT(stride, wp[stride] += *wp; *op = *wp & mask; wp++; op++) + REPEAT(stride, *wp = (uint16_t)(*wp + wp[-stride]); + *op = (uint16_t)(*wp & mask); wp++; op++) n -= stride; } } } } -static void horizontalAccumulate8(uint16_t *wp, int n, int stride, +static void horizontalAccumulate8(uint16_t *wp, tmsize_t n, int stride, unsigned char *op, unsigned char *ToLinear8) { - register unsigned int cr, cg, cb, ca, mask; + unsigned int cr, cg, cb, ca, mask; if (n >= stride) { @@ -434,20 +435,20 @@ static void horizontalAccumulate8(uint16_t *wp, int n, int stride, n -= stride; while (n > 0) { - REPEAT(stride, wp[stride] += *wp; *op = ToLinear8[*wp & mask]; - wp++; op++) + REPEAT(stride, *wp = (uint16_t)(*wp + wp[-stride]); + *op = ToLinear8[*wp & mask]; wp++; op++) n -= stride; } } } } -static void horizontalAccumulate8abgr(uint16_t *wp, int n, int stride, +static void horizontalAccumulate8abgr(uint16_t *wp, tmsize_t n, int stride, unsigned char *op, unsigned char *ToLinear8) { - register unsigned int cr, cg, cb, ca, mask; - register unsigned char t0, t1, t2, t3; + unsigned int cr, cg, cb, ca, mask; + unsigned char t0, t1, t2, t3; if (n >= stride) { @@ -508,8 +509,8 @@ static void horizontalAccumulate8abgr(uint16_t *wp, int n, int stride, n -= stride; while (n > 0) { - REPEAT(stride, wp[stride] += *wp; *op = ToLinear8[*wp & mask]; - wp++; op++) + REPEAT(stride, *wp = (uint16_t)(*wp + wp[-stride]); + *op = ToLinear8[*wp & mask]; wp++; op++) n -= stride; } } @@ -577,7 +578,8 @@ static int PixarLogMakeTables(TIFF *tif, PixarLogState *sp) 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)); + FromLT2 = (uint16_t *)_TIFFmallocExt( + tif, (tmsize_t)((size_t)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)); @@ -623,16 +625,17 @@ static int PixarLogMakeTables(TIFF *tif, PixarLogState *sp) for (i = 0; i < TSIZEP1; i++) { - v = ToLinearF[i] * 65535.0 + 0.5; + v = (double)ToLinearF[i] * 65535.0 + 0.5; ToLinear16[i] = (v > 65535.0) ? 65535 : (uint16_t)v; - v = ToLinearF[i] * 255.0 + 0.5; + v = (double)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]) + if ((i * linstep) * (i * linstep) > + (double)ToLinearF[j] * (double)ToLinearF[j + 1]) j++; FromLT2[i] = (uint16_t)j; } @@ -645,7 +648,8 @@ static int PixarLogMakeTables(TIFF *tif, PixarLogState *sp) j = 0; for (i = 0; i < 16384; i++) { - while ((i / 16383.) * (i / 16383.) > ToLinearF[j] * ToLinearF[j + 1]) + while ((i / 16383.) * (i / 16383.) > + (double)ToLinearF[j] * (double)ToLinearF[j + 1]) j++; From14[i] = (uint16_t)j; } @@ -653,7 +657,8 @@ static int PixarLogMakeTables(TIFF *tif, PixarLogState *sp) j = 0; for (i = 0; i < 256; i++) { - while ((i / 255.) * (i / 255.) > ToLinearF[j] * ToLinearF[j + 1]) + while ((i / 255.) * (i / 255.) > + (double)ToLinearF[j] * (double)ToLinearF[j + 1]) j++; From8[i] = (uint16_t)j; } @@ -708,6 +713,8 @@ static int PixarLogGuessDataFmt(TIFFDirectory *td) if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) guess = PIXARLOGDATAFMT_8BIT; break; + default: + break; } return guess; @@ -769,7 +776,8 @@ static int PixarLogSetupDecode(TIFF *tif) 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); + tbuf_size = + add_ms(tbuf_size, (tmsize_t)(sizeof(uint16_t) * (size_t)sp->stride)); if (tbuf_size == 0) return (0); /* TODO: this is an error return without error report through TIFFErrorExt */ @@ -838,18 +846,21 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) PixarLogState *sp = PixarLogDecoderState(tif); tmsize_t i; tmsize_t nsamples; - int llen; + tmsize_t llen; uint16_t *up; switch (sp->user_datafmt) { case PIXARLOGDATAFMT_FLOAT: - nsamples = occ / sizeof(float); /* XXX float == 32 bits */ + nsamples = (tmsize_t)((uint64_t)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 */ + nsamples = + (tmsize_t)((uint64_t)occ / + sizeof(uint16_t)); /* XXX uint16_t == 16 bits */ break; case PIXARLOGDATAFMT_8BIT: case PIXARLOGDATAFMT_8BITABGR: @@ -863,7 +874,55 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) return 0; } - llen = sp->stride * td->td_imagewidth; + llen = (tmsize_t)sp->stride * td->td_imagewidth; + + /* Fix: ABGR with stride=3 expands 3 samples to 4 output bytes per pixel */ + if (sp->user_datafmt == PIXARLOGDATAFMT_8BITABGR && sp->stride == 3) + { + tmsize_t required = (tmsize_t)td->td_imagewidth * 4; + tmsize_t max_rows; + tmsize_t max_nsamples; + + /* + * Ensure at least one expanded output row fits. + */ + if (occ < required) + { + TIFFErrorExtR(tif, module, + "Output buffer too small for PixarLog ABGR data"); + memset(op, 0, (size_t)occ); + return (0); + } + + /* + * The caller-provided output buffer size must represent a whole + * number of expanded ABGR scanlines. + */ + if (occ % required) + { + TIFFErrorExtR( + tif, module, + "Fractional scanline not supported for PixarLog ABGR data"); + memset(op, 0, (size_t)occ); + return (0); + } + + /* + * PixarLogDecode() may process multiple rows per call + * (e.g. strip decoding). Limit nsamples so the total + * output written by the loop below never exceeds occ. + */ + max_rows = occ / required; + max_nsamples = max_rows * llen; + + if (nsamples > max_nsamples) + { + TIFFErrorExtR(tif, module, + "Output buffer too small for PixarLog ABGR data"); + memset(op, 0, (size_t)occ); + return (0); + } + } (void)s; assert(sp != NULL); @@ -876,8 +935,8 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) we need to simplify this code to reflect a ZLib that is likely updated to deal with 8byte memory sizes, though this code will respond appropriately even before we simplify it */ - sp->stream.avail_out = (uInt)(nsamples * sizeof(uint16_t)); - if (sp->stream.avail_out != nsamples * sizeof(uint16_t)) + sp->stream.avail_out = (uInt)((unsigned long)nsamples * sizeof(uint16_t)); + if (sp->stream.avail_out != (unsigned long)nsamples * sizeof(uint16_t)) { TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size"); memset(op, 0, (size_t)occ); @@ -899,9 +958,10 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) } if (state == Z_DATA_ERROR) { - TIFFErrorExtR( - tif, module, "Decoding error at scanline %" PRIu32 ", %s", - tif->tif_row, sp->stream.msg ? sp->stream.msg : "(null)"); + TIFFErrorExtR(tif, module, + "Decoding error at scanline %" PRIu32 ", %s", + tif->tif_dir.td_row, + sp->stream.msg ? sp->stream.msg : "(null)"); memset(op, 0, (size_t)occ); return (0); } @@ -920,7 +980,7 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) TIFFErrorExtR(tif, module, "Not enough data at scanline %" PRIu32 " (short %u bytes)", - tif->tif_row, sp->stream.avail_out); + tif->tif_dir.td_row, sp->stream.avail_out); memset(op, 0, (size_t)occ); return (0); } @@ -941,7 +1001,8 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) if (nsamples % llen) { TIFFWarningExtR(tif, module, - "stride %d is not a multiple of sample count, " + "stride %" TIFF_SSIZE_FORMAT + " is not a multiple of sample count, " "%" TIFF_SSIZE_FORMAT ", data truncated.", llen, nsamples); nsamples -= nsamples % llen; @@ -954,31 +1015,37 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) case PIXARLOGDATAFMT_FLOAT: horizontalAccumulateF(up, llen, sp->stride, (float *)op, sp->ToLinearF); - op += llen * sizeof(float); + op += (unsigned long)llen * sizeof(float); break; case PIXARLOGDATAFMT_16BIT: horizontalAccumulate16(up, llen, sp->stride, (uint16_t *)op, sp->ToLinear16); - op += llen * sizeof(uint16_t); + op += (unsigned long)llen * sizeof(uint16_t); break; case PIXARLOGDATAFMT_12BITPICIO: horizontalAccumulate12(up, llen, sp->stride, (int16_t *)op, sp->ToLinearF); - op += llen * sizeof(int16_t); + op += (unsigned long)llen * sizeof(int16_t); break; case PIXARLOGDATAFMT_11BITLOG: horizontalAccumulate11(up, llen, sp->stride, (uint16_t *)op); - op += llen * sizeof(uint16_t); + op += (unsigned long)llen * sizeof(uint16_t); break; case PIXARLOGDATAFMT_8BIT: horizontalAccumulate8(up, llen, sp->stride, (unsigned char *)op, sp->ToLinear8); - op += llen * sizeof(unsigned char); + op += (unsigned long)llen * sizeof(unsigned char); break; case PIXARLOGDATAFMT_8BITABGR: horizontalAccumulate8abgr(up, llen, sp->stride, (unsigned char *)op, sp->ToLinear8); - op += llen * sizeof(unsigned char); + + /* For stride == 3 (RGB), horizontalAccumulate8abgr expands to 4 + * bytes/pixel (ABGR) */ + if (sp->stride == 3) + op += (unsigned long)td->td_imagewidth * 4; + else + op += (unsigned long)llen * sizeof(unsigned char); break; default: TIFFErrorExtR(tif, module, "Unsupported bits/sample: %" PRIu16, @@ -1063,17 +1130,18 @@ static int PixarLogPreEncode(TIFF *tif, uint16_t s) return (deflateReset(&sp->stream) == Z_OK); } -static void horizontalDifferenceF(float *ip, int n, int stride, uint16_t *wp, - uint16_t *FromLT2) +static void horizontalDifferenceF(float *ip, tmsize_t 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) + ((v < (float)0.) ? 0 \ + : (v < (float)2.) ? FromLT2[(int)(v * fltsize)] \ + : (v > (float)24.2) \ + ? 2047 \ + : (double)LogK1 * log((double)v * (double)LogK2) + 0.5) mask = CODE_MASK; if (n >= stride) @@ -1143,10 +1211,10 @@ static void horizontalDifferenceF(float *ip, int n, int stride, uint16_t *wp, } } -static void horizontalDifference16(unsigned short *ip, int n, int stride, +static void horizontalDifference16(unsigned short *ip, tmsize_t n, int stride, unsigned short *wp, uint16_t *From14) { - register int r1, g1, b1, a1, r2, g2, b2, a2, mask; + int r1, g1, b1, a1, r2, g2, b2, a2, mask; /* assumption is unsigned pixel values */ #undef CLAMP @@ -1219,10 +1287,10 @@ static void horizontalDifference16(unsigned short *ip, int n, int stride, } } -static void horizontalDifference8(unsigned char *ip, int n, int stride, +static void horizontalDifference8(unsigned char *ip, tmsize_t n, int stride, unsigned short *wp, uint16_t *From8) { - register int r1, g1, b1, a1, r2, g2, b2, a2, mask; + int r1, g1, b1, a1, r2, g2, b2, a2, mask; #undef CLAMP #define CLAMP(v) (From8[(v)]) @@ -1304,7 +1372,7 @@ static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) PixarLogState *sp = PixarLogEncoderState(tif); tmsize_t i; tmsize_t n; - int llen; + tmsize_t llen; unsigned short *up; (void)s; @@ -1312,12 +1380,14 @@ static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) switch (sp->user_datafmt) { case PIXARLOGDATAFMT_FLOAT: - n = cc / sizeof(float); /* XXX float == 32 bits */ + n = (tmsize_t)((unsigned long)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 */ + n = (tmsize_t)((unsigned long)cc / + sizeof(uint16_t)); /* XXX uint16_t == 16 bits */ break; case PIXARLOGDATAFMT_8BIT: case PIXARLOGDATAFMT_8BITABGR: @@ -1330,7 +1400,7 @@ static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) return 0; } - llen = sp->stride * td->td_imagewidth; + llen = (tmsize_t)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)) { @@ -1345,17 +1415,17 @@ static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) case PIXARLOGDATAFMT_FLOAT: horizontalDifferenceF((float *)bp, llen, sp->stride, up, sp->FromLT2); - bp += llen * sizeof(float); + bp += (unsigned long)llen * sizeof(float); break; case PIXARLOGDATAFMT_16BIT: horizontalDifference16((uint16_t *)bp, llen, sp->stride, up, sp->From14); - bp += llen * sizeof(uint16_t); + bp += (unsigned long)llen * sizeof(uint16_t); break; case PIXARLOGDATAFMT_8BIT: horizontalDifference8((unsigned char *)bp, llen, sp->stride, up, sp->From8); - bp += llen * sizeof(unsigned char); + bp += (unsigned long)llen * sizeof(unsigned char); break; default: TIFFErrorExtR(tif, module, @@ -1370,8 +1440,8 @@ static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) we need to simplify this code to reflect a ZLib that is likely updated to deal with 8byte memory sizes, though this code will respond appropriately even before we simplify it */ - sp->stream.avail_in = (uInt)(n * sizeof(uint16_t)); - if ((sp->stream.avail_in / sizeof(uint16_t)) != (uInt)n) + sp->stream.avail_in = (uInt)((unsigned long)n * sizeof(uint16_t)); + if ((sp->stream.avail_in / sizeof(uint16_t)) != (unsigned long)n) { TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size"); return (0); @@ -1562,13 +1632,15 @@ static int PixarLogVSetField(TIFF *tif, uint32_t tag, va_list ap) TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP); break; + default: + break; } /* * Must recalculate sizes should bits/sample change. */ - tif->tif_tilesize = + tif->tif_dir.td_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1); - tif->tif_scanlinesize = TIFFScanlineSize(tif); + tif->tif_dir.td_scanlinesize = TIFFScanlineSize(tif); result = 1; /* NB: pseudo tag */ break; default: @@ -1601,6 +1673,16 @@ static const TIFFField pixarlogFields[] = { {TIFFTAG_PIXARLOGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO, FALSE, FALSE, "", NULL}}; +static uint64_t PixarLogGetMaxCompressionRatio(TIFF *tif) +{ + (void)tif; + /* cf https://zlib.net/zlib_tech.html */ + const uint64_t MAX_DEFLATE_RATIO = 1032; + + /* security margin as I don't understand what this codec does */ + return MAX_DEFLATE_RATIO * (uint64_t)4; +} + int TIFFInitPixarLog(TIFF *tif, int scheme) { static const char module[] = "TIFFInitPixarLog"; @@ -1648,6 +1730,7 @@ int TIFFInitPixarLog(TIFF *tif, int scheme) tif->tif_encodetile = PixarLogEncode; tif->tif_close = PixarLogClose; tif->tif_cleanup = PixarLogCleanup; + tif->tif_getmaxcompressionratio = PixarLogGetMaxCompressionRatio; /* Override SetField so we can handle our private pseudo-tag */ sp->vgetparent = tif->tif_tagmethods.vgetfield; diff --git a/3rdparty/libtiff/tif_predict.c b/3rdparty/libtiff/tif_predict.c index 7a6fc4af8b..18b90c211e 100644 --- a/3rdparty/libtiff/tif_predict.c +++ b/3rdparty/libtiff/tif_predict.c @@ -30,7 +30,7 @@ #include "tif_predict.h" #include "tiffiop.h" -#if defined(__x86_64__) || defined(_M_X64) +#if defined(__x86_64__) || (defined(_M_X64) && !defined(_M_ARM64EC)) #include #endif @@ -151,6 +151,8 @@ static int PredictorSetupDecode(TIFF *tif) case 64: sp->decodepfunc = horAcc64; break; + default: + break; } /* * Override default decoding method with one that does the @@ -247,6 +249,8 @@ static int PredictorSetupEncode(TIFF *tif) case 64: sp->encodepfunc = horDiff64; break; + default: + break; } /* * Override default encoding method with one that does the @@ -590,7 +594,7 @@ static int fpAcc(TIFF *tif, uint8_t *cp0, tmsize_t cc) cp = (uint8_t *)cp0; count = 0; -#if defined(__x86_64__) || defined(_M_X64) +#if defined(__x86_64__) || (defined(_M_X64) && !defined(_M_ARM64EC)) if (bps == 4) { /* Optimization of general case */ @@ -972,7 +976,7 @@ static int PredictorEncodeRow(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) (int64_t)cc); return 0; } - memcpy(working_copy, bp, cc); + memcpy(working_copy, bp, (size_t)cc); if (!(*sp->encodepfunc)(tif, working_copy, cc)) { @@ -1010,7 +1014,7 @@ static int PredictorEncodeTile(TIFF *tif, uint8_t *bp0, tmsize_t cc0, (int64_t)cc0); return 0; } - memcpy(working_copy, bp0, cc0); + memcpy(working_copy, bp0, (size_t)cc0); bp = working_copy; rowsize = sp->rowsize; @@ -1098,8 +1102,10 @@ static void PredictorPrintDir(TIFF *tif, FILE *fd, long flags) case 3: fprintf(fd, "floating point predictor "); break; + default: + break; } - fprintf(fd, "%d (0x%x)\n", sp->predictor, sp->predictor); + fprintf(fd, "%d (0x%x)\n", sp->predictor, (unsigned)sp->predictor); } if (sp->printdir) (*sp->printdir)(tif, fd, flags); diff --git a/3rdparty/libtiff/tif_print.c b/3rdparty/libtiff/tif_print.c index addc03ab07..1ea450db95 100644 --- a/3rdparty/libtiff/tif_print.c +++ b/3rdparty/libtiff/tif_print.c @@ -118,10 +118,10 @@ static void _TIFFPrintField(FILE *fd, const TIFFField *fip, if (tv_size == 8) fprintf(fd, "%lf", ((double *)raw_data)[j]); else - fprintf(fd, "%f", ((float *)raw_data)[j]); + fprintf(fd, "%f", (double)((float *)raw_data)[j]); } else if (fip->field_type == TIFF_FLOAT) - fprintf(fd, "%f", ((float *)raw_data)[j]); + fprintf(fd, "%f", (double)((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) @@ -193,8 +193,9 @@ static int _TIFFPrettyPrintField(TIFF *tif, const TIFFField *fip, FILE *fd, 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]); + fprintf(fd, " White Point: %g-%g\n", + (double)((float *)raw_data)[0], + (double)((float *)raw_data)[1]); return 1; } return 0; @@ -232,6 +233,9 @@ static int _TIFFPrettyPrintField(TIFF *tif, const TIFFField *fip, FILE *fd, return 1; } return 0; + + default: + break; } return 0; @@ -244,8 +248,7 @@ static int _TIFFPrettyPrintField(TIFF *tif, const TIFFField *fip, FILE *fd, void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags) { TIFFDirectory *td = &tif->tif_dir; - char *sep; - long l, n; + const char *sep; fprintf(fd, "TIFF Directory at offset 0x%" PRIx64 " (%" PRIu64 ")\n", tif->tif_diroff, tif->tif_diroff); @@ -286,8 +289,8 @@ void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags) } if (TIFFFieldSet(tif, FIELD_RESOLUTION)) { - fprintf(fd, " Resolution: %g, %g", td->td_xresolution, - td->td_yresolution); + fprintf(fd, " Resolution: %g, %g", (double)td->td_xresolution, + (double)td->td_yresolution); if (TIFFFieldSet(tif, FIELD_RESOLUTIONUNIT)) { switch (td->td_resolutionunit) @@ -310,7 +313,8 @@ void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags) fprintf(fd, "\n"); } if (TIFFFieldSet(tif, FIELD_POSITION)) - fprintf(fd, " Position: %g, %g\n", td->td_xposition, td->td_yposition); + fprintf(fd, " Position: %g, %g\n", (double)td->td_xposition, + (double)td->td_yposition); if (TIFFFieldSet(tif, FIELD_BITSPERSAMPLE)) fprintf(fd, " Bits/Sample: %" PRIu16 "\n", td->td_bitspersample); if (TIFFFieldSet(tif, FIELD_SAMPLEFORMAT)) @@ -374,7 +378,8 @@ void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags) } } } - if (TIFFFieldSet(tif, FIELD_EXTRASAMPLES) && td->td_extrasamples) + if (TIFFFieldSet(tif, FIELD_EXTRASAMPLES) && td->td_extrasamples && + td->td_sampleinfo) { uint16_t i; fprintf(fd, " Extra Samples: %" PRIu16 "<", td->td_extrasamples); @@ -412,7 +417,8 @@ void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags) 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); + size_t max_chars = + (size_t)(td->td_inknameslen - (cp - td->td_inknames)); fputs(sep, fd); _TIFFprintAsciiBounded(fd, cp, max_chars); sep = ", "; @@ -548,17 +554,25 @@ void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags) 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)) + if (TIFFFieldSet(tif, FIELD_COLORMAP) && td->td_colormap[0] && + td->td_colormap[1] && td->td_colormap[2]) { 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]); + if (td->td_bitspersample >= 64) + fprintf(fd, " (BitsPerSample too large to print safely)\n"); + else + { + uint64_t n = 1ULL << td->td_bitspersample; + for (uint64_t l = 0u; l < n; l++) + fprintf(fd, + " %5" PRIu64 ": %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"); @@ -569,26 +583,37 @@ void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags) 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]); + (double)td->td_refblackwhite[2 * i + 0], + (double)td->td_refblackwhite[2 * i + 1]); } - if (TIFFFieldSet(tif, FIELD_TRANSFERFUNCTION)) + if (TIFFFieldSet(tif, FIELD_TRANSFERFUNCTION) && + td->td_transferfunction[0] && + ((td->td_samplesperpixel - td->td_extrasamples > 1 && + td->td_transferfunction[1] && td->td_transferfunction[2]) || + td->td_samplesperpixel - td->td_extrasamples <= 1)) { fprintf(fd, " Transfer Function: "); if (flags & TIFFPRINT_CURVES) { fprintf(fd, "\n"); - n = 1L << td->td_bitspersample; - for (l = 0; l < n; l++) + if (td->td_bitspersample >= 64) + fprintf(fd, " (BitsPerSample too large to print safely)\n"); + else { - 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); + uint64_t n = 1ULL << td->td_bitspersample; + for (uint64_t l = 0; l < n; l++) + { + uint16_t i; + fprintf(fd, " %2" PRIu64 ": %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 @@ -655,7 +680,7 @@ void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags) else if (fip->field_readcount == TIFF_SPP) value_count = td->td_samplesperpixel; else - value_count = fip->field_readcount; + value_count = (uint32_t)fip->field_readcount; if (fip->field_tag == TIFFTAG_DOTRANGE && strcmp(fip->field_name, "DotRange") == 0) { @@ -680,7 +705,8 @@ void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags) * "set_get_field_type" to determine internal storage size. */ int tv_size = TIFFFieldSetGetSize(fip); - raw_data = _TIFFmallocExt(tif, tv_size * value_count); + raw_data = _TIFFCheckMalloc(tif, value_count, tv_size, + "for tag data"); mem_alloc = 1; if (TIFFGetField(tif, tag, raw_data) != 1) { @@ -744,7 +770,7 @@ static void _TIFFprintAsciiBounded(FILE *fd, const char *cp, size_t max_chars) if (*tp) fprintf(fd, "\\%c", *tp); else - fprintf(fd, "\\%03o", *cp & 0xff); + fprintf(fd, "\\%03o", (unsigned int)(*cp & 0xff)); } } diff --git a/3rdparty/libtiff/tif_read.c b/3rdparty/libtiff/tif_read.c index a2bb304623..d1a4e89216 100644 --- a/3rdparty/libtiff/tif_read.c +++ b/3rdparty/libtiff/tif_read.c @@ -27,6 +27,7 @@ * Scanline-oriented Read Support */ #include "tiffiop.h" +#include #include int TIFFFillStrip(TIFF *tif, uint32_t strip); @@ -39,9 +40,6 @@ static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf, 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 \ @@ -99,7 +97,9 @@ static int TIFFReadAndRealloc(TIFF *tif, tmsize_t size, tmsize_t rawdata_offset, 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); + (uint64_t)already_read + (uint64_t)to_read + + (uint64_t)rawdata_offset, + 1024); if (tif->tif_rawdatasize == 0) { TIFFErrorExtR(tif, module, "Invalid buffer size"); @@ -111,7 +111,7 @@ static int TIFFReadAndRealloc(TIFF *tif, tmsize_t size, tmsize_t rawdata_offset, { TIFFErrorExtR(tif, module, "No space for data buffer at scanline %" PRIu32, - tif->tif_row); + tif->tif_dir.td_row); _TIFFfreeExt(tif, tif->tif_rawdata); tif->tif_rawdata = 0; tif->tif_rawdatasize = 0; @@ -127,18 +127,22 @@ static int TIFFReadAndRealloc(TIFF *tif, tmsize_t size, tmsize_t rawdata_offset, bytes_read = TIFFReadFile( tif, tif->tif_rawdata + rawdata_offset + already_read, to_read); + if (bytes_read < 0) + /* Treat read errors as short reads before updating offsets. */ + bytes_read = 0; 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); + memset( + tif->tif_rawdata + rawdata_offset + already_read, 0, + (size_t)(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); + tif->tif_dir.td_row, already_read, size); } else { @@ -147,8 +151,8 @@ static int TIFFReadAndRealloc(TIFF *tif, tmsize_t size, tmsize_t rawdata_offset, ", tile %" PRIu32 "; " "got %" TIFF_SSIZE_FORMAT " bytes, expected %" TIFF_SSIZE_FORMAT "", - tif->tif_row, tif->tif_col, strip_or_tile, - already_read, size); + tif->tif_dir.td_row, tif->tif_dir.td_col, + strip_or_tile, already_read, size); } return 0; } @@ -160,7 +164,7 @@ static int TIFFFillStripPartial(TIFF *tif, int strip, tmsize_t read_ahead, int restart) { static const char module[] = "TIFFFillStripPartial"; - register TIFFDirectory *td = &tif->tif_dir; + TIFFDirectory *td = &tif->tif_dir; tmsize_t unused_data; uint64_t read_offset; tmsize_t to_read; @@ -185,7 +189,7 @@ static int TIFFFillStripPartial(TIFF *tif, int strip, tmsize_t read_ahead, { assert(restart); - tif->tif_curstrip = NOSTRIP; + tif->tif_dir.td_curstrip = NOSTRIP; if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { TIFFErrorExtR(tif, module, @@ -214,20 +218,30 @@ static int TIFFFillStripPartial(TIFF *tif, int strip, tmsize_t read_ahead, if (unused_data > 0) { assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0); - memmove(tif->tif_rawdata, tif->tif_rawcp, unused_data); + memmove(tif->tif_rawdata, tif->tif_rawcp, (size_t)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; + read_offset = TIFFGetStrileOffset(tif, (uint32_t)strip); + if (read_offset > UINT64_MAX - (uint64_t)tif->tif_rawdataoff || + read_offset + (uint64_t)tif->tif_rawdataoff > + UINT64_MAX - (uint64_t)tif->tif_rawdataloaded) + { + TIFFErrorExtR(tif, module, + "Seek error at scanline %" PRIu32 ", strip %d", + tif->tif_dir.td_row, strip); + return 0; + } + read_offset += + (uint64_t)tif->tif_rawdataoff + (uint64_t)tif->tif_rawdataloaded; if (!SeekOK(tif, read_offset)) { TIFFErrorExtR(tif, module, "Seek error at scanline %" PRIu32 ", strip %d", - tif->tif_row, strip); + tif->tif_dir.td_row, strip); return 0; } @@ -238,11 +252,13 @@ static int TIFFFillStripPartial(TIFF *tif, int strip, tmsize_t read_ahead, 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) + if ((uint64_t)to_read > TIFFGetStrileByteCount(tif, (uint32_t)strip) - + (uint64_t)tif->tif_rawdataoff - + (uint64_t)tif->tif_rawdataloaded) { - to_read = (tmsize_t)TIFFGetStrileByteCount(tif, strip) - - tif->tif_rawdataoff - tif->tif_rawdataloaded; + to_read = (tmsize_t)(TIFFGetStrileByteCount(tif, (uint32_t)strip) - + (uint64_t)tif->tif_rawdataoff - + (uint64_t)tif->tif_rawdataloaded); } assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0); @@ -281,16 +297,17 @@ static int TIFFFillStripPartial(TIFF *tif, int strip, tmsize_t read_ahead, /* 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)) + (uint64_t)tif->tif_rawcc < + TIFFGetStrileByteCount(tif, (uint32_t)strip)) { if (TIFFJPEGIsFullStripRequired(tif)) { - return TIFFFillStrip(tif, strip); + return TIFFFillStrip(tif, (uint32_t)strip); } } #endif - return TIFFStartStrip(tif, strip); + return TIFFStartStrip(tif, (uint32_t)strip); } else { @@ -308,7 +325,7 @@ static int TIFFFillStripPartial(TIFF *tif, int strip, tmsize_t read_ahead, */ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample) { - register TIFFDirectory *td = &tif->tif_dir; + TIFFDirectory *td = &tif->tif_dir; uint32_t strip; int whole_strip; tmsize_t read_ahead = 0; @@ -323,8 +340,16 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample) td->td_imagelength); return (0); } + if (td->td_rowsperstrip == 0) + { + TIFFErrorExtR(tif, tif->tif_name, + "Cannot compute strip: RowsPerStrip is zero"); + return (0); + } if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { + uint64_t sample_offset; + uint64_t strip64; if (sample >= td->td_samplesperpixel) { TIFFErrorExtR(tif, tif->tif_name, @@ -332,16 +357,26 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample) sample, td->td_samplesperpixel); return (0); } - strip = (uint32_t)sample * td->td_stripsperimage + - row / td->td_rowsperstrip; + sample_offset = + _TIFFMultiply64(tif, sample, td->td_stripsperimage, "TIFFSeek"); + if (sample_offset == 0 && sample != 0 && td->td_stripsperimage != 0) + return (0); + strip64 = _TIFFAdd64(tif, sample_offset, row / td->td_rowsperstrip, + "TIFFSeek"); + if (strip64 == 0 && + (sample_offset != 0 || (row / td->td_rowsperstrip) != 0)) + return (0); + strip = _TIFFCastUInt64ToUInt32(tif, strip64, "TIFFSeek"); + if (strip == 0 && strip64 != 0) + return (0); } 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? - */ + /* + * 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 || @@ -359,14 +394,14 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample) /* is some constant value, for example for JPEG tables */ /* coverity[dead_error_line:SUPPRESS] */ - if (tif->tif_scanlinesize < TIFF_TMSIZE_T_MAX / 16 && - tif->tif_scanlinesize * 16 < TIFF_TMSIZE_T_MAX - 5000) + if (tif->tif_dir.td_scanlinesize < TIFF_TMSIZE_T_MAX / 16 && + tif->tif_dir.td_scanlinesize * 16 < TIFF_TMSIZE_T_MAX - 5000) { - read_ahead = tif->tif_scanlinesize * 16 + 5000; + read_ahead = tif->tif_dir.td_scanlinesize * 16 + 5000; } else { - read_ahead = tif->tif_scanlinesize; + read_ahead = tif->tif_dir.td_scanlinesize; } } #else @@ -377,7 +412,7 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample) * If we haven't loaded this strip, do so now, possibly * only reading the first part. */ - if (strip != tif->tif_curstrip) + if (strip != tif->tif_dir.td_curstrip) { /* different strip, refill */ if (whole_strip) @@ -412,7 +447,7 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample) } #endif - if (row < tif->tif_row) + if (row < tif->tif_dir.td_row) { /* * Moving backwards within the same strip: backup @@ -425,7 +460,7 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample) if (tif->tif_rawdataoff != 0) { - if (!TIFFFillStripPartial(tif, strip, read_ahead, 1)) + if (!TIFFFillStripPartial(tif, (int)strip, read_ahead, 1)) return 0; } else @@ -435,7 +470,7 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample) } } - if (row != tif->tif_row) + if (row != tif->tif_dir.td_row) { /* * Seek forward to the desired row. @@ -443,9 +478,9 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample) /* TODO: Will this really work with partial buffers? */ - if (!(*tif->tif_seek)(tif, row - tif->tif_row)) + if (!(*tif->tif_seek)(tif, row - tif->tif_dir.td_row)) return (0); - tif->tif_row = row; + tif->tif_dir.td_row = row; } return (1); @@ -462,20 +497,21 @@ int TIFFReadScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample) /* * Decompress desired row into user buffer. */ - e = (*tif->tif_decoderow)(tif, (uint8_t *)buf, tif->tif_scanlinesize, - sample); + e = (*tif->tif_decoderow)(tif, (uint8_t *)buf, + tif->tif_dir.td_scanlinesize, sample); /* we are now poised at the beginning of the next row */ - tif->tif_row = row + 1; + tif->tif_dir.td_row = row + 1; if (e) - (*tif->tif_postdecode)(tif, (uint8_t *)buf, tif->tif_scanlinesize); + (*tif->tif_postdecode)(tif, (uint8_t *)buf, + tif->tif_dir.td_scanlinesize); } else { /* See TIFFReadEncodedStrip comment regarding TIFFTAG_FAXFILLFUNC. */ if (buf) - memset(buf, 0, (size_t)tif->tif_scanlinesize); + memset(buf, 0, (size_t)tif->tif_dir.td_scanlinesize); } return (e > 0 ? 1 : -1); } @@ -553,9 +589,9 @@ tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32_t strip, void *buf, if (!isFillOrder(tif, td->td_fillorder) && (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits(buf, stripsize); + TIFFReverseBits((uint8_t *)buf, stripsize); - (*tif->tif_postdecode)(tif, buf, stripsize); + (*tif->tif_postdecode)(tif, (uint8_t *)buf, stripsize); return (stripsize); } @@ -569,9 +605,9 @@ tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32_t strip, void *buf, memset(buf, 0, (size_t)stripsize); return ((tmsize_t)(-1)); } - if ((*tif->tif_decodestrip)(tif, buf, stripsize, plane) <= 0) + if ((*tif->tif_decodestrip)(tif, (uint8_t *)buf, stripsize, plane) <= 0) return ((tmsize_t)(-1)); - (*tif->tif_postdecode)(tif, buf, stripsize); + (*tif->tif_postdecode)(tif, (uint8_t *)buf, stripsize); return (stripsize); } @@ -603,17 +639,39 @@ tmsize_t _TIFFReadEncodedStripAndAllocBuffer(TIFF *tif, uint32_t strip, if (!TIFFFillStrip(tif, strip)) return ((tmsize_t)(-1)); - *buf = _TIFFmallocExt(tif, bufsizetoalloc); + /* Sanity checks to avoid excessive memory allocation */ + /* 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. + */ + if (bufsizetoalloc > 100 * 1024 * 1024) + { + const uint64_t maxCompressionRatio = TIFFGetMaxCompressionRatio(tif); + if (maxCompressionRatio > 0 && + (uint64_t)tif->tif_rawdatasize < + (uint64_t)this_stripsize / maxCompressionRatio) + { + TIFFErrorExtR(tif, TIFFFileName(tif), + "Likely invalid strip byte count for strip %u. " + "Uncompressed strip size is %" PRIu64 ", " + "compressed one is %" PRIu64, + strip, (uint64_t)this_stripsize, + (uint64_t)tif->tif_rawdatasize); + return ((tmsize_t)(-1)); + } + } + + *buf = _TIFFcallocExt(tif, 1, 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) + if ((*tif->tif_decodestrip)(tif, (uint8_t *)*buf, this_stripsize, plane) <= + 0) return ((tmsize_t)(-1)); - (*tif->tif_postdecode)(tif, *buf, this_stripsize); + (*tif->tif_postdecode)(tif, (uint8_t *)*buf, this_stripsize); return (this_stripsize); } @@ -629,7 +687,7 @@ static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf, { TIFFErrorExtR(tif, module, "Seek error at scanline %" PRIu32 ", strip %" PRIu32, - tif->tif_row, strip); + tif->tif_dir.td_row, strip); return ((tmsize_t)(-1)); } cc = TIFFReadFile(tif, buf, size); @@ -639,7 +697,7 @@ static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf, "Read error at scanline %" PRIu32 "; got %" TIFF_SSIZE_FORMAT " bytes, expected %" TIFF_SSIZE_FORMAT, - tif->tif_row, cc, size); + tif->tif_dir.td_row, cc, size); return ((tmsize_t)(-1)); } } @@ -670,7 +728,7 @@ static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf, "Read error at scanline %" PRIu32 ", strip %" PRIu32 "; got %" TIFF_SSIZE_FORMAT " bytes, expected %" TIFF_SSIZE_FORMAT, - tif->tif_row, strip, n, size); + tif->tif_dir.td_row, strip, n, size); return ((tmsize_t)(-1)); } _TIFFmemcpy(buf, tif->tif_base + ma, size); @@ -691,14 +749,14 @@ static tmsize_t TIFFReadRawStripOrTile2(TIFF *tif, uint32_t strip_or_tile, { TIFFErrorExtR(tif, module, "Seek error at scanline %" PRIu32 ", strip %" PRIu32, - tif->tif_row, strip_or_tile); + tif->tif_dir.td_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); + TIFFErrorExtR( + tif, module, + "Seek error at row %" PRIu32 ", col %" PRIu32 ", tile %" PRIu32, + tif->tif_dir.td_row, tif->tif_dir.td_col, strip_or_tile); } return ((tmsize_t)(-1)); } @@ -774,22 +832,50 @@ int TIFFFillStrip(TIFF *tif, uint32_t strip) } /* 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) + const tmsize_t stripsize = TIFFStripSize(tif); + if (stripsize > 0) { - /* 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) + if (bytecount > 1024 * 1024 && + (bytecount - 4096) / 10 > (uint64_t)stripsize) { + /* Byte count should normally not be larger than a number of */ + /* times the uncompressed size plus some margin */ + /* 10 and 4096 are just values that could be adjusted. */ + /* Hopefully they are safe enough for all codecs */ + /* What happens next will depend on whether only the bytecount + */ + /* was corrupted to a large value but the strip/tile data is */ + /* fine. In that situation most codecs should work fine and */ + /* only used part of the tile/strip data. If the strip/tile */ + /* data is corrupted too, then codecs will later error out. */ 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); + TIFFWarningExtR(tif, module, + "Too large strip byte count %" PRIu64 + ", strip %" PRIu32 ". Limiting to %" PRIu64, + bytecount, strip, newbytecount); bytecount = newbytecount; } + else if (stripsize > 100 * 1024 * 1024) + { + /* 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 uint64_t maxCompressionRatio = + TIFFGetMaxCompressionRatio(tif); + if (maxCompressionRatio > 0 && + bytecount < (uint64_t)stripsize / maxCompressionRatio) + { + TIFFErrorExtR( + tif, module, + "Likely invalid strip byte count for strip %u. " + "Uncompressed strip size is %" PRIu64 ", " + "compressed one is %" PRIu64, + strip, (uint64_t)stripsize, bytecount); + return 0; + } + } } if (isMapped(tif)) @@ -818,10 +904,10 @@ int TIFFFillStrip(TIFF *tif, uint32_t strip) "Read error on strip %" PRIu32 "; " "got %" PRIu64 " bytes, expected %" PRIu64, strip, - NoSanitizeSubUInt64(tif->tif_size, + NoSanitizeSubUInt64((uint64_t)tif->tif_size, TIFFGetStrileOffset(tif, strip)), bytecount); - tif->tif_curstrip = NOSTRIP; + tif->tif_dir.td_curstrip = NOSTRIP; return (0); } } @@ -878,7 +964,7 @@ int TIFFFillStrip(TIFF *tif, uint32_t strip) } if (bytecountm > tif->tif_rawdatasize) { - tif->tif_curstrip = NOSTRIP; + tif->tif_dir.td_curstrip = NOSTRIP; if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { TIFFErrorExtR( @@ -889,7 +975,7 @@ int TIFFFillStrip(TIFF *tif, uint32_t strip) } if (tif->tif_flags & TIFF_BUFFERMMAP) { - tif->tif_curstrip = NOSTRIP; + tif->tif_dir.td_curstrip = NOSTRIP; tif->tif_rawdata = NULL; tif->tif_rawdatasize = 0; tif->tif_flags &= ~TIFF_BUFFERMMAP; @@ -954,7 +1040,7 @@ 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; + tmsize_t tilesize = tif->tif_dir.td_tilesize; if (!TIFFCheckRead(tif, 1)) return ((tmsize_t)(-1)); @@ -976,9 +1062,9 @@ tmsize_t TIFFReadEncodedTile(TIFF *tif, uint32_t tile, void *buf, tmsize_t size) if (!isFillOrder(tif, td->td_fillorder) && (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits(buf, tilesize); + TIFFReverseBits((uint8_t *)buf, tilesize); - (*tif->tif_postdecode)(tif, buf, tilesize); + (*tif->tif_postdecode)(tif, (uint8_t *)buf, tilesize); return (tilesize); } @@ -1032,7 +1118,7 @@ tmsize_t _TIFFReadEncodedTileAndAllocBuffer(TIFF *tif, uint32_t tile, { static const char module[] = "_TIFFReadEncodedTileAndAllocBuffer"; TIFFDirectory *td = &tif->tif_dir; - tmsize_t tilesize = tif->tif_tilesize; + tmsize_t tilesize = tif->tif_dir.td_tilesize; if (*buf != NULL) { @@ -1072,25 +1158,22 @@ tmsize_t _TIFFReadEncodedTileAndAllocBuffer(TIFF *tif, uint32_t tile, * 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) + if (bufsizetoalloc > 100 * 1024 * 1024) { - 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)); + const uint64_t maxCompressionRatio = + TIFFGetMaxCompressionRatio(tif); + if (maxCompressionRatio > 0 && + (uint64_t)tif->tif_rawdatasize < + (uint64_t)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)); + } } } @@ -1129,7 +1212,7 @@ static tmsize_t TIFFReadRawTile1(TIFF *tif, uint32_t tile, void *buf, TIFFErrorExtR(tif, module, "Seek error at row %" PRIu32 ", col %" PRIu32 ", tile %" PRIu32, - tif->tif_row, tif->tif_col, tile); + tif->tif_dir.td_row, tif->tif_dir.td_col, tile); return ((tmsize_t)(-1)); } cc = TIFFReadFile(tif, buf, size); @@ -1139,7 +1222,7 @@ static tmsize_t TIFFReadRawTile1(TIFF *tif, uint32_t tile, void *buf, "Read error at row %" PRIu32 ", col %" PRIu32 "; got %" TIFF_SSIZE_FORMAT " bytes, expected %" TIFF_SSIZE_FORMAT, - tif->tif_row, tif->tif_col, cc, size); + tif->tif_dir.td_row, tif->tif_dir.td_col, cc, size); return ((tmsize_t)(-1)); } } @@ -1162,7 +1245,8 @@ static tmsize_t TIFFReadRawTile1(TIFF *tif, uint32_t tile, void *buf, "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); + tif->tif_dir.td_row, tif->tif_dir.td_col, tile, n, + size); return ((tmsize_t)(-1)); } _TIFFmemcpy(buf, tif->tif_base + ma, size); @@ -1229,22 +1313,49 @@ int TIFFFillTile(TIFF *tif, uint32_t tile) } /* 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) + const tmsize_t tilesize = TIFFTileSize(tif); + if (tilesize > 0) { - /* 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) + if (bytecount > 1024 * 1024 && + (bytecount - 4096) / 10 > (uint64_t)tilesize) { - 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); + /* Byte count should normally not be larger than a number of */ + /* times the uncompressed size plus some margin */ + /* 10 and 4096 are just values that could be adjusted. */ + /* Hopefully they are safe enough for all codecs */ + /* What happens next will depend on whether only the bytecount + */ + /* was corrupted to a large value but the strip/tile data is */ + /* fine. In that situation most codecs should work fine and */ + /* only used part of the tile/strip data. If the strip/tile */ + /* data is corrupted too, then codecs will later error out. */ + uint64_t newbytecount = (uint64_t)tilesize * 10 + 4096; + TIFFWarningExtR(tif, module, + "Too large tile byte count %" PRIu64 + ", tile %" PRIu32 ". Limiting to %" PRIu64, + bytecount, tile, newbytecount); bytecount = newbytecount; } + else if (tilesize > 100 * 1024 * 1024) + { + /* 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 uint64_t maxCompressionRatio = + TIFFGetMaxCompressionRatio(tif); + if (maxCompressionRatio > 0 && + bytecount < (uint64_t)tilesize / maxCompressionRatio) + { + TIFFErrorExtR(tif, module, + "Likely invalid tile byte count for tile %u. " + "Uncompressed tile size is %" PRIu64 ", " + "compressed one is %" PRIu64, + tile, (uint64_t)tilesize, bytecount); + return 0; + } + } } if (isMapped(tif)) @@ -1262,7 +1373,7 @@ int TIFFFillTile(TIFF *tif, uint32_t tile) TIFFGetStrileOffset(tif, tile) > (uint64_t)tif->tif_size - bytecount) { - tif->tif_curtile = NOTILE; + tif->tif_dir.td_curtile = NOTILE; return (0); } } @@ -1312,7 +1423,7 @@ int TIFFFillTile(TIFF *tif, uint32_t tile) } if (bytecountm > tif->tif_rawdatasize) { - tif->tif_curtile = NOTILE; + tif->tif_dir.td_curtile = NOTILE; if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { TIFFErrorExtR(tif, module, @@ -1323,7 +1434,7 @@ int TIFFFillTile(TIFF *tif, uint32_t tile) } if (tif->tif_flags & TIFF_BUFFERMMAP) { - tif->tif_curtile = NOTILE; + tif->tif_dir.td_curtile = NOTILE; tif->tif_rawdata = NULL; tif->tif_rawdatasize = 0; tif->tif_flags &= ~TIFF_BUFFERMMAP; @@ -1410,7 +1521,7 @@ int TIFFReadBufferSetup(TIFF *tif, void *bp, tmsize_t size) { TIFFErrorExtR(tif, module, "No space for data buffer at scanline %" PRIu32, - tif->tif_row); + tif->tif_dir.td_row); tif->tif_rawdatasize = 0; return (0); } @@ -1431,8 +1542,13 @@ static int TIFFStartStrip(TIFF *tif, uint32_t strip) return (0); tif->tif_flags |= TIFF_CODERSETUP; } - tif->tif_curstrip = strip; - tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; + if (td->td_stripsperimage == 0) + { + TIFFErrorExtR(tif, "TIFFStartStrip", "Zero strips per image"); + return 0; + } + tif->tif_dir.td_curstrip = strip; + tif->tif_dir.td_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; tif->tif_flags &= ~TIFF_BUF4WRITE; if (tif->tif_flags & TIFF_NOREADRAW) @@ -1456,7 +1572,7 @@ static int TIFFStartStrip(TIFF *tif, uint32_t strip) */ /* tif_curstrip, we'd call tif_decoderow() on a possibly invalid */ /* codec state. */ - tif->tif_curstrip = NOSTRIP; + tif->tif_dir.td_curstrip = NOSTRIP; return 0; } return 1; @@ -1478,7 +1594,7 @@ static int TIFFStartTile(TIFF *tif, uint32_t tile) return (0); tif->tif_flags |= TIFF_CODERSETUP; } - tif->tif_curtile = tile; + tif->tif_dir.td_curtile = tile; if (td->td_tilewidth == 0) { TIFFErrorExtR(tif, module, "Zero tilewidth"); @@ -1490,14 +1606,14 @@ static int TIFFStartTile(TIFF *tif, uint32_t tile) TIFFErrorExtR(tif, module, "Zero tiles"); return 0; } - tif->tif_row = (tile % howmany32) * td->td_tilelength; + tif->tif_dir.td_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_dir.td_col = (tile % howmany32) * td->td_tilewidth; tif->tif_flags &= ~TIFF_BUF4WRITE; if (tif->tif_flags & TIFF_NOREADRAW) { @@ -1568,14 +1684,14 @@ int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf, tif->tif_flags &= ~TIFF_MYBUFFER; tif->tif_flags |= TIFF_BUFFERMMAP; tif->tif_rawdatasize = insize; - tif->tif_rawdata = inbuf; + tif->tif_rawdata = (uint8_t *)inbuf; tif->tif_rawdataoff = 0; tif->tif_rawdataloaded = insize; if (!isFillOrder(tif, td->td_fillorder) && (tif->tif_flags & TIFF_NOBITREV) == 0) { - TIFFReverseBits(inbuf, insize); + TIFFReverseBits((uint8_t *)inbuf, insize); } if (TIFFIsTiled(tif)) @@ -1632,13 +1748,13 @@ int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf, if (!isFillOrder(tif, td->td_fillorder) && (tif->tif_flags & TIFF_NOBITREV) == 0) { - TIFFReverseBits(inbuf, insize); + TIFFReverseBits((uint8_t *)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_rawdata = (uint8_t *)old_rawdata; tif->tif_rawdataoff = 0; tif->tif_rawdataloaded = 0; diff --git a/3rdparty/libtiff/tif_strip.c b/3rdparty/libtiff/tif_strip.c index c9ba393669..b07bf9ff21 100644 --- a/3rdparty/libtiff/tif_strip.c +++ b/3rdparty/libtiff/tif_strip.c @@ -47,6 +47,8 @@ uint32_t TIFFComputeStrip(TIFF *tif, uint32_t row, uint16_t sample) strip = row / td->td_rowsperstrip; if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { + uint64_t sample_offset; + uint64_t strip64; if (sample >= td->td_samplesperpixel) { TIFFErrorExtR(tif, module, "%lu: Sample out of range, max %lu", @@ -54,7 +56,16 @@ uint32_t TIFFComputeStrip(TIFF *tif, uint32_t row, uint16_t sample) (unsigned long)td->td_samplesperpixel); return (0); } - strip += (uint32_t)sample * td->td_stripsperimage; + sample_offset = _TIFFMultiply64(tif, sample, td->td_stripsperimage, + "TIFFComputeStrip"); + if (sample_offset == 0 && sample != 0 && td->td_stripsperimage != 0) + return (0); + strip64 = _TIFFAdd64(tif, sample_offset, strip, "TIFFComputeStrip"); + if (strip64 == 0 && (sample_offset != 0 || strip != 0)) + return (0); + strip = _TIFFCastUInt64ToUInt32(tif, strip64, "TIFFComputeStrip"); + if (strip == 0 && strip64 != 0) + return (0); } return (strip); } @@ -83,14 +94,24 @@ uint32_t TIFFNumberOfStrips(TIFF *tif) } /* - * Compute the # bytes in a variable height, row-aligned strip. + * Compute the # bytes in a variable height, row-aligned strip if isStrip is + * TRUE, or in a tile if isStrip is FALSE */ -uint64_t TIFFVStripSize64(TIFF *tif, uint32_t nrows) +uint64_t _TIFFStrileSize64(TIFF *tif, uint32_t nrows, int isStrip) { - static const char module[] = "TIFFVStripSize64"; + static const char module[] = "_TIFFStrileSize64"; TIFFDirectory *td = &tif->tif_dir; - if (nrows == (uint32_t)(-1)) - nrows = td->td_imagelength; + if (isStrip) + { + if (nrows == (uint32_t)(-1)) + nrows = td->td_imagelength; + } + else + { + 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) && (!isUpSampled(tif))) { @@ -125,9 +146,10 @@ uint64_t TIFFVStripSize64(TIFF *tif, uint32_t nrows) ycbcrsubsampling[0], ycbcrsubsampling[1]); return 0; } - samplingblock_samples = ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2; - samplingblocks_hor = - TIFFhowmany_32(td->td_imagewidth, ycbcrsubsampling[0]); + samplingblock_samples = + (uint16_t)(ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2); + const uint32_t width = isStrip ? td->td_imagewidth : td->td_tilewidth; + samplingblocks_hor = TIFFhowmany_32(width, ycbcrsubsampling[0]); samplingblocks_ver = TIFFhowmany_32(nrows, ycbcrsubsampling[1]); samplingrow_samples = _TIFFMultiply64(tif, samplingblocks_hor, samplingblock_samples, module); @@ -137,8 +159,20 @@ uint64_t TIFFVStripSize64(TIFF *tif, uint32_t nrows) _TIFFMultiply64(tif, samplingrow_size, samplingblocks_ver, module)); } else - return (_TIFFMultiply64(tif, nrows, TIFFScanlineSize64(tif), module)); + return (_TIFFMultiply64(tif, nrows, + isStrip ? TIFFScanlineSize64(tif) + : TIFFTileRowSize64(tif), + module)); } + +/* + * Compute the # bytes in a variable height, row-aligned strip. + */ +uint64_t TIFFVStripSize64(TIFF *tif, uint32_t nrows) +{ + return _TIFFStrileSize64(tif, nrows, /* isStrip = */ TRUE); +} + tmsize_t TIFFVStripSize(TIFF *tif, uint32_t nrows) { static const char module[] = "TIFFVStripSize"; @@ -286,7 +320,7 @@ uint64_t TIFFScanlineSize64(TIFF *tif) return 0; } samplingblock_samples = - ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2; + (uint16_t)(ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2); samplingblocks_hor = TIFFhowmany_32(td->td_imagewidth, ycbcrsubsampling[0]); samplingrow_samples = _TIFFMultiply64( diff --git a/3rdparty/libtiff/tif_swab.c b/3rdparty/libtiff/tif_swab.c index 827b025ce7..50fe635fbc 100644 --- a/3rdparty/libtiff/tif_swab.c +++ b/3rdparty/libtiff/tif_swab.c @@ -32,7 +32,7 @@ #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabShort) void TIFFSwabShort(uint16_t *wp) { - register unsigned char *cp = (unsigned char *)wp; + unsigned char *cp = (unsigned char *)wp; unsigned char t; assert(sizeof(uint16_t) == 2); t = cp[1]; @@ -44,7 +44,7 @@ void TIFFSwabShort(uint16_t *wp) #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabLong) void TIFFSwabLong(uint32_t *lp) { - register unsigned char *cp = (unsigned char *)lp; + unsigned char *cp = (unsigned char *)lp; unsigned char t; assert(sizeof(uint32_t) == 4); t = cp[3]; @@ -59,7 +59,7 @@ void TIFFSwabLong(uint32_t *lp) #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabLong8) void TIFFSwabLong8(uint64_t *lp) { - register unsigned char *cp = (unsigned char *)lp; + unsigned char *cp = (unsigned char *)lp; unsigned char t; assert(sizeof(uint64_t) == 8); t = cp[7]; @@ -78,10 +78,10 @@ void TIFFSwabLong8(uint64_t *lp) #endif #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfShort) -void TIFFSwabArrayOfShort(register uint16_t *wp, tmsize_t n) +void TIFFSwabArrayOfShort(uint16_t *wp, tmsize_t n) { - register unsigned char *cp; - register unsigned char t; + unsigned char *cp; + unsigned char t; assert(sizeof(uint16_t) == 2); /* XXX unroll loop some */ while (n-- > 0) @@ -96,7 +96,7 @@ void TIFFSwabArrayOfShort(register uint16_t *wp, tmsize_t n) #endif #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfTriples) -void TIFFSwabArrayOfTriples(register uint8_t *tp, tmsize_t n) +void TIFFSwabArrayOfTriples(uint8_t *tp, tmsize_t n) { unsigned char *cp; unsigned char t; @@ -114,10 +114,10 @@ void TIFFSwabArrayOfTriples(register uint8_t *tp, tmsize_t n) #endif #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfLong) -void TIFFSwabArrayOfLong(register uint32_t *lp, tmsize_t n) +void TIFFSwabArrayOfLong(uint32_t *lp, tmsize_t n) { - register unsigned char *cp; - register unsigned char t; + unsigned char *cp; + unsigned char t; assert(sizeof(uint32_t) == 4); /* XXX unroll loop some */ while (n-- > 0) @@ -135,10 +135,10 @@ void TIFFSwabArrayOfLong(register uint32_t *lp, tmsize_t n) #endif #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfLong8) -void TIFFSwabArrayOfLong8(register uint64_t *lp, tmsize_t n) +void TIFFSwabArrayOfLong8(uint64_t *lp, tmsize_t n) { - register unsigned char *cp; - register unsigned char t; + unsigned char *cp; + unsigned char t; assert(sizeof(uint64_t) == 8); /* XXX unroll loop some */ while (n-- > 0) @@ -164,7 +164,7 @@ void TIFFSwabArrayOfLong8(register uint64_t *lp, tmsize_t n) #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabFloat) void TIFFSwabFloat(float *fp) { - register unsigned char *cp = (unsigned char *)fp; + unsigned char *cp = (unsigned char *)fp; unsigned char t; assert(sizeof(float) == 4); t = cp[3]; @@ -177,10 +177,10 @@ void TIFFSwabFloat(float *fp) #endif #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfFloat) -void TIFFSwabArrayOfFloat(register float *fp, tmsize_t n) +void TIFFSwabArrayOfFloat(float *fp, tmsize_t n) { - register unsigned char *cp; - register unsigned char t; + unsigned char *cp; + unsigned char t; assert(sizeof(float) == 4); /* XXX unroll loop some */ while (n-- > 0) @@ -200,7 +200,7 @@ void TIFFSwabArrayOfFloat(register float *fp, tmsize_t n) #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabDouble) void TIFFSwabDouble(double *dp) { - register unsigned char *cp = (unsigned char *)dp; + unsigned char *cp = (unsigned char *)dp; unsigned char t; assert(sizeof(double) == 8); t = cp[7]; @@ -221,8 +221,8 @@ void TIFFSwabDouble(double *dp) #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfDouble) void TIFFSwabArrayOfDouble(double *dp, tmsize_t n) { - register unsigned char *cp; - register unsigned char t; + unsigned char *cp; + unsigned char t; assert(sizeof(double) == 8); /* XXX unroll loop some */ while (n-- > 0) diff --git a/3rdparty/libtiff/tif_thunder.c b/3rdparty/libtiff/tif_thunder.c index bac0607dbe..0c688db1ee 100644 --- a/3rdparty/libtiff/tif_thunder.c +++ b/3rdparty/libtiff/tif_thunder.c @@ -41,7 +41,7 @@ * 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_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 */ @@ -56,11 +56,11 @@ static const int threebitdeltas[8] = {0, 1, 2, 3, 0, -3, -2, -1}; #define SETPIXEL(op, v) \ { \ - lastpixel = (v)&0xf; \ + lastpixel = (v) & 0xf; \ if (npixels < maxpixels) \ { \ if (npixels++ & 1) \ - *op++ |= lastpixel; \ + *op++ |= (uint8_t)lastpixel; \ else \ op[0] = (uint8_t)(lastpixel << 4); \ } \ @@ -85,8 +85,8 @@ static int ThunderSetupDecode(TIFF *tif) static int ThunderDecode(TIFF *tif, uint8_t *op0, tmsize_t maxpixels) { static const char module[] = "ThunderDecode"; - register unsigned char *bp; - register tmsize_t cc; + unsigned char *bp; + tmsize_t cc; unsigned int lastpixel; tmsize_t npixels; uint8_t *op = op0; @@ -112,7 +112,7 @@ static int ThunderDecode(TIFF *tif, uint8_t *op0, tmsize_t maxpixels) break; if (npixels & 1) { - op[0] |= lastpixel; + op[0] |= (uint8_t)lastpixel; lastpixel = *op++; npixels++; n--; @@ -150,6 +150,8 @@ static int ThunderDecode(TIFF *tif, uint8_t *op0, tmsize_t maxpixels) case THUNDER_RAW: /* raw data */ SETPIXEL(op, n); break; + default: + break; } } tif->tif_rawcp = (uint8_t *)bp; @@ -161,7 +163,7 @@ static int ThunderDecode(TIFF *tif, uint8_t *op0, tmsize_t 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, + (unsigned long)tif->tif_dir.td_row, (uint64_t)npixels, (uint64_t)maxpixels); return (0); } @@ -175,7 +177,7 @@ static int ThunderDecodeRow(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) uint8_t *row = buf; (void)s; - if (occ % tif->tif_scanlinesize) + if (occ % tif->tif_dir.td_scanlinesize) { TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); return (0); @@ -184,8 +186,8 @@ static int ThunderDecodeRow(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) { if (!ThunderDecode(tif, row, tif->tif_dir.td_imagewidth)) return (0); - occ -= tif->tif_scanlinesize; - row += tif->tif_scanlinesize; + occ -= tif->tif_dir.td_scanlinesize; + row += tif->tif_dir.td_scanlinesize; } return (1); } diff --git a/3rdparty/libtiff/tif_tile.c b/3rdparty/libtiff/tif_tile.c index f07032f731..f907609400 100644 --- a/3rdparty/libtiff/tif_tile.c +++ b/3rdparty/libtiff/tif_tile.c @@ -54,12 +54,50 @@ uint32_t TIFFComputeTile(TIFF *tif, uint32_t x, uint32_t y, uint32_t z, 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); + uint32_t xpt_ypt = _TIFFMultiply32(tif, xpt, ypt, "TIFFComputeTile"); + uint32_t xpt_ypt_zpt = + _TIFFMultiply32(tif, xpt_ypt, zpt, "TIFFComputeTile"); + uint64_t z_offset; + uint64_t y_offset; + uint64_t tile64; + if ((xpt_ypt == 0 && xpt != 0 && ypt != 0) || + (xpt_ypt_zpt == 0 && xpt_ypt != 0 && zpt != 0)) + return (0); + + z_offset = _TIFFMultiply64(tif, xpt_ypt, z / dz, "TIFFComputeTile"); + y_offset = _TIFFMultiply64(tif, xpt, y / dy, "TIFFComputeTile"); + if ((z_offset == 0 && xpt_ypt != 0 && (z / dz) != 0) || + (y_offset == 0 && xpt != 0 && (y / dy) != 0)) + return (0); + tile64 = _TIFFAdd64(tif, z_offset, y_offset, "TIFFComputeTile"); + if (tile64 == 0 && (z_offset != 0 || y_offset != 0)) + return (0); + tile64 = _TIFFAdd64(tif, tile64, x / dx, "TIFFComputeTile"); + if (tile64 == 0 && (z_offset != 0 || y_offset != 0 || (x / dx) != 0)) + return (0); 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; + { + uint64_t sample_offset; + if (s >= td->td_samplesperpixel) + { + TIFFErrorExtR( + tif, "TIFFComputeTile", "%lu: Sample out of range, max %lu", + (unsigned long)s, (unsigned long)td->td_samplesperpixel); + return (0); + } + sample_offset = + _TIFFMultiply64(tif, xpt_ypt_zpt, s, "TIFFComputeTile"); + if (sample_offset == 0 && xpt_ypt_zpt != 0 && s != 0) + return (0); + tile64 = _TIFFAdd64(tif, sample_offset, tile64, "TIFFComputeTile"); + if (tile64 == 0 && (sample_offset != 0 || z_offset != 0 || + y_offset != 0 || (x / dx) != 0)) + return (0); + } + tile = _TIFFCastUInt64ToUInt32(tif, tile64, "TIFFComputeTile"); + if (tile == 0 && tile64 != 0) + return (0); } return (tile); } @@ -187,54 +225,9 @@ tmsize_t TIFFTileRowSize(TIFF *tif) */ 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)); + return _TIFFStrileSize64(tif, nrows, /* isStrip = */ FALSE); } + tmsize_t TIFFVTileSize(TIFF *tif, uint32_t nrows) { static const char module[] = "TIFFVTileSize"; diff --git a/3rdparty/libtiff/tif_unix.c b/3rdparty/libtiff/tif_unix.c index 9e6fc75b08..b02fe294eb 100644 --- a/3rdparty/libtiff/tif_unix.c +++ b/3rdparty/libtiff/tif_unix.c @@ -77,10 +77,10 @@ static tmsize_t _tiffReadProc(thandle_t fd, void *buf, tmsize_t size) return (tmsize_t)-1; } fdh.h = fd; - for (bytes_read = 0; bytes_read < bytes_total; bytes_read += count) + for (bytes_read = 0; bytes_read < bytes_total; bytes_read += (size_t)count) { char *buf_offset = (char *)buf + bytes_read; - size_t io_size = bytes_total - bytes_read; + size_t io_size = (size_t)(bytes_total - bytes_read); if (io_size > TIFF_IO_MAX) io_size = TIFF_IO_MAX; /* Below is an obvious false positive of Coverity Scan */ @@ -108,10 +108,11 @@ static tmsize_t _tiffWriteProc(thandle_t fd, void *buf, tmsize_t size) return (tmsize_t)-1; } fdh.h = fd; - for (bytes_written = 0; bytes_written < bytes_total; bytes_written += count) + for (bytes_written = 0; bytes_written < bytes_total; + bytes_written += (size_t)count) { const char *buf_offset = (char *)buf + bytes_written; - size_t io_size = bytes_total - bytes_written; + size_t io_size = (size_t)(bytes_total - bytes_written); if (io_size > TIFF_IO_MAX) io_size = TIFF_IO_MAX; /* Below is an obvious false positive of Coverity Scan */ @@ -174,7 +175,7 @@ static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize) (void *)mmap(0, (size_t)sizem, PROT_READ, MAP_SHARED, fdh.fd, 0); if (*pbase != (void *)-1) { - *psize = (tmsize_t)sizem; + *psize = (toff_t)sizem; return (1); } } @@ -184,7 +185,7 @@ static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize) static void _tiffUnmapProc(thandle_t fd, void *base, toff_t size) { (void)fd; - (void)munmap(base, (off_t)size); + (void)munmap(base, (size_t)size); } #else /* !HAVE_MMAP */ static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize) @@ -362,7 +363,8 @@ 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) +static void TIFF_ATTRIBUTE((__format__(__printf__, 2, 0))) + unixWarningHandler(const char *module, const char *fmt, va_list ap) { if (module != NULL) fprintf(stderr, "%s: ", module); @@ -372,7 +374,8 @@ static void unixWarningHandler(const char *module, const char *fmt, va_list ap) } TIFFErrorHandler _TIFFwarningHandler = unixWarningHandler; -static void unixErrorHandler(const char *module, const char *fmt, va_list ap) +static void TIFF_ATTRIBUTE((__format__(__printf__, 2, 0))) + unixErrorHandler(const char *module, const char *fmt, va_list ap) { if (module != NULL) fprintf(stderr, "%s: ", module); diff --git a/3rdparty/libtiff/tif_webp.c b/3rdparty/libtiff/tif_webp.c index c06ce163b7..cc8b680c52 100644 --- a/3rdparty/libtiff/tif_webp.c +++ b/3rdparty/libtiff/tif_webp.c @@ -84,15 +84,16 @@ static int TWebPDatasetWriter(const uint8_t *data, size_t data_size, 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)); + TIFFErrorExtR(tif, module, + "Buffer too small by %" TIFF_SIZE_FORMAT " bytes.", + (size_t)((uint64_t)tif->tif_rawcc + (uint64_t)data_size - + (uint64_t)tif->tif_rawdatasize)); return 0; } else { - _TIFFmemcpy(tif->tif_rawcp, data, data_size); - tif->tif_rawcc += data_size; + _TIFFmemcpy(tif->tif_rawcp, data, (tmsize_t)data_size); + tif->tif_rawcc += (tmsize_t)data_size; tif->tif_rawcp += data_size; return 1; } @@ -116,7 +117,7 @@ static int TWebPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) return 0; } - memcpy(sp->pBuffer + sp->buffer_offset, bp, cc); + memcpy(sp->pBuffer + sp->buffer_offset, bp, (size_t)cc); sp->buffer_offset += (unsigned)cc; return 1; @@ -141,7 +142,7 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) TIFFErrorExtR(tif, module, "ZIPDecode: Scanline %" PRIu32 " cannot be read due to " "previous error", - tif->tif_row); + tif->tif_dir.td_row); return 0; } @@ -158,7 +159,7 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) else { segment_width = td->td_imagewidth; - segment_height = td->td_imagelength - tif->tif_row; + segment_height = td->td_imagelength - tif->tif_dir.td_row; if (segment_height > td->td_rowsperstrip) segment_height = td->td_rowsperstrip; } @@ -246,7 +247,7 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) sp->pBuffer = NULL; } - sp->pBuffer = _TIFFmallocExt(tif, buffer_size); + sp->pBuffer = (uint8_t *)_TIFFmallocExt(tif, buffer_size); if (!sp->pBuffer) { TIFFErrorExtR(tif, module, "Cannot allocate buffer"); @@ -262,10 +263,10 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) WebPInitDecBuffer(&sp->sDecBuffer); sp->sDecBuffer.is_external_memory = 1; - sp->sDecBuffer.width = segment_width; - sp->sDecBuffer.height = segment_height; + sp->sDecBuffer.width = (int)segment_width; + sp->sDecBuffer.height = (int)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.stride = (int)(segment_width * sp->nSamples); sp->sDecBuffer.u.RGBA.size = buffer_size; if (sp->nSamples > 3) @@ -298,7 +299,7 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) return 0; } - status = WebPIAppend(sp->psDecoder, tif->tif_rawcp, tif->tif_rawcc); + status = WebPIAppend(sp->psDecoder, tif->tif_rawcp, (size_t)tif->tif_rawcc); if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED) { @@ -345,7 +346,7 @@ static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) } else { - memcpy(op, buf + (sp->last_y * stride), occ); + memcpy(op, buf + (sp->last_y * stride), (size_t)occ); } tif->tif_rawcp += tif->tif_rawcc; @@ -465,7 +466,7 @@ static int TWebPPreDecode(TIFF *tif, uint16_t s) else { segment_width = td->td_imagewidth; - segment_height = td->td_imagelength - tif->tif_row; + segment_height = td->td_imagelength - tif->tif_dir.td_row; if (segment_height > td->td_rowsperstrip) segment_height = td->td_rowsperstrip; } @@ -601,7 +602,7 @@ static int TWebPPreEncode(TIFF *tif, uint16_t s) else { segment_width = td->td_imagewidth; - segment_height = td->td_imagelength - tif->tif_row; + segment_height = td->td_imagelength - tif->tif_dir.td_row; if (segment_height > td->td_rowsperstrip) segment_height = td->td_rowsperstrip; } @@ -623,7 +624,7 @@ static int TWebPPreEncode(TIFF *tif, uint16_t s) sp->pBuffer = NULL; } - sp->pBuffer = _TIFFmallocExt(tif, sp->buffer_size); + sp->pBuffer = (uint8_t *)_TIFFmallocExt(tif, sp->buffer_size); if (!sp->pBuffer) { TIFFErrorExtR(tif, module, "Cannot allocate buffer"); @@ -631,8 +632,8 @@ static int TWebPPreEncode(TIFF *tif, uint16_t s) } sp->buffer_offset = 0; - sp->sPicture.width = segment_width; - sp->sPicture.height = segment_height; + sp->sPicture.width = (int)segment_width; + sp->sPicture.height = (int)segment_height; sp->sPicture.writer = TWebPDatasetWriter; sp->sPicture.custom_ptr = tif; @@ -708,9 +709,11 @@ static int TWebPPostEncode(TIFF *tif) case VP8_ENC_ERROR_USER_ABORT: pszErrorMsg = "User interrupted"; break; + case VP8_ENC_OK: + case VP8_ENC_ERROR_LAST: default: TIFFErrorExtR(tif, module, - "WebPEncode returned an unknown error code: %d", + "WebPEncode returned an unknown error code: %u", sp->sPicture.error_code); pszErrorMsg = "Unknown WebP error type."; break; @@ -776,7 +779,7 @@ static int TWebPVSetField(TIFF *tif, uint32_t tag, va_list ap) { case TIFFTAG_WEBP_LEVEL: sp->quality_level = (int)va_arg(ap, int); - if (sp->quality_level <= 0 || sp->quality_level > 100.0f) + if (sp->quality_level <= 0 || sp->quality_level > 100) { TIFFWarningExtR(tif, module, "WEBP_LEVEL should be between 1 and 100"); @@ -844,6 +847,17 @@ static const TIFFField TWebPFields[] = { FIELD_PSEUDO, TRUE, FALSE, "WEBP exact lossless", NULL}, }; +static uint64_t TWebPGetMaxCompressionRatio(TIFF *tif) +{ + /* See README_for_libtiff_developpers.md for raw data used to estimate + * the maximum compression rate. */ + + /* lossy compression: */ + /* return (tif->tif_dir.td_samplesperpixel == 4) ? 2199 : 1685; */ + /* lossless compression: */ + return (tif->tif_dir.td_samplesperpixel == 4) ? 104194 : 78146; +} + int TIFFInitWebP(TIFF *tif, int scheme) { static const char module[] = "TIFFInitWebP"; @@ -907,6 +921,7 @@ int TIFFInitWebP(TIFF *tif, int scheme) tif->tif_encodestrip = TWebPEncode; tif->tif_encodetile = TWebPEncode; tif->tif_cleanup = TWebPCleanup; + tif->tif_getmaxcompressionratio = TWebPGetMaxCompressionRatio; return 1; bad: diff --git a/3rdparty/libtiff/tif_win32.c b/3rdparty/libtiff/tif_win32.c index 525cebec76..4b21ab7d48 100644 --- a/3rdparty/libtiff/tif_win32.c +++ b/3rdparty/libtiff/tif_win32.c @@ -5,6 +5,7 @@ * 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 + * 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 @@ -72,7 +73,7 @@ static tmsize_t _tiffReadProc(thandle_t fd, void *buf, tmsize_t size) DWORD o; tmsize_t p; ma = (uint8_t *)buf; - mb = size; + mb = (uint64_t)size; p = 0; while (mb > 0) { @@ -101,7 +102,7 @@ static tmsize_t _tiffWriteProc(thandle_t fd, void *buf, tmsize_t size) DWORD o; tmsize_t p; ma = (uint8_t *)buf; - mb = size; + mb = (uint64_t)size; p = 0; while (mb > 0) { @@ -123,7 +124,7 @@ static uint64_t _tiffSeekProc(thandle_t fd, uint64_t off, int whence) { LARGE_INTEGER offli; DWORD dwMoveMethod; - offli.QuadPart = off; + offli.QuadPart = (LONGLONG)off; switch (whence) { case SEEK_SET: @@ -140,11 +141,11 @@ static uint64_t _tiffSeekProc(thandle_t fd, uint64_t off, int whence) break; } offli.LowPart = - SetFilePointer(fd, offli.LowPart, &offli.HighPart, dwMoveMethod); + SetFilePointer(fd, (LONG)offli.LowPart, &offli.HighPart, dwMoveMethod); if ((offli.LowPart == INVALID_SET_FILE_POINTER) && (GetLastError() != NO_ERROR)) offli.QuadPart = 0; - return (offli.QuadPart); + return ((uint64_t)offli.QuadPart); } static int _tiffCloseProc(thandle_t fd) { return (CloseHandle(fd) ? 0 : -1); } @@ -153,7 +154,7 @@ static uint64_t _tiffSizeProc(thandle_t fd) { LARGE_INTEGER m; if (GetFileSizeEx(fd, &m)) - return (m.QuadPart); + return ((uint64_t)m.QuadPart); else return (0); } @@ -343,7 +344,7 @@ TIFF *TIFFOpenWExt(const wchar_t *name, const char *mode, TIFFOpenOptions *opts) NULL); if (fd == INVALID_HANDLE_VALUE) { - _TIFFErrorEarly(opts, NULL, module, "%S: Cannot open", name); + _TIFFErrorEarly(opts, NULL, module, "%ls: Cannot open", name); return ((TIFF *)0); } diff --git a/3rdparty/libtiff/tif_write.c b/3rdparty/libtiff/tif_write.c index 3263853cc0..614a8ea85a 100644 --- a/3rdparty/libtiff/tif_write.c +++ b/3rdparty/libtiff/tif_write.c @@ -30,7 +30,7 @@ #include "tiffiop.h" #include -#define STRIPINCR 20 /* expansion factor on strip array */ +#define NOSTRIP ((uint32_t)(-1)) /* undefined state */ #define WRITECHECKSTRIPS(tif, module) \ (((tif)->tif_flags & TIFF_BEENWRITING) || TIFFWriteCheck((tif), 0, module)) @@ -38,7 +38,7 @@ (((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)) + 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, @@ -47,7 +47,7 @@ static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data, int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample) { static const char module[] = "TIFFWriteScanline"; - register TIFFDirectory *td; + TIFFDirectory *td; int status, imagegrew = 0; uint32_t strip; @@ -82,8 +82,16 @@ int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample) /* * Calculate strip and check for crossings. */ + if (td->td_rowsperstrip == 0) + { + TIFFErrorExtR(tif, module, + "Cannot compute strip: RowsPerStrip is zero"); + return (-1); + } if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { + uint64_t sample_offset; + uint64_t strip64; if (sample >= td->td_samplesperpixel) { TIFFErrorExtR(tif, module, "%lu: Sample out of range, max %lu", @@ -91,7 +99,18 @@ int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample) (unsigned long)td->td_samplesperpixel); return (-1); } - strip = sample * td->td_stripsperimage + row / td->td_rowsperstrip; + sample_offset = + _TIFFMultiply64(tif, sample, td->td_stripsperimage, module); + if (sample_offset == 0 && sample != 0 && td->td_stripsperimage != 0) + return (-1); + strip64 = + _TIFFAdd64(tif, sample_offset, row / td->td_rowsperstrip, module); + if (strip64 == 0 && + (sample_offset != 0 || (row / td->td_rowsperstrip) != 0)) + return (-1); + strip = _TIFFCastUInt64ToUInt32(tif, strip64, module); + if (strip == 0 && strip64 != 0) + return (-1); } else strip = row / td->td_rowsperstrip; @@ -104,14 +123,14 @@ int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample) */ if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module)) return (-1); - if (strip != tif->tif_curstrip) + if (strip != tif->tif_dir.td_curstrip) { /* * Changing strips -- flush any data present. */ if (!TIFFFlushData(tif)) return (-1); - tif->tif_curstrip = strip; + tif->tif_dir.td_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 @@ -125,7 +144,8 @@ int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample) TIFFErrorExtR(tif, module, "Zero strips per image"); return (-1); } - tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; + tif->tif_dir.td_row = + (strip % td->td_stripsperimage) * td->td_rowsperstrip; if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { if (!(*tif->tif_setupencode)(tif)) @@ -148,35 +168,35 @@ int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample) * 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_dir.td_row) { - if (row < tif->tif_row) + if (row < tif->tif_dir.td_row) { /* * Moving backwards within the same strip: * backup to the start and then decode * forward (below). */ - tif->tif_row = + tif->tif_dir.td_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)) + if (!(*tif->tif_seek)(tif, row - tif->tif_dir.td_row)) return (-1); - tif->tif_row = row; + tif->tif_dir.td_row = row; } /* swab if needed - note that source buffer will be altered */ - tif->tif_postdecode(tif, (uint8_t *)buf, tif->tif_scanlinesize); + tif->tif_postdecode(tif, (uint8_t *)buf, tif->tif_dir.td_scanlinesize); - status = (*tif->tif_encoderow)(tif, (uint8_t *)buf, tif->tif_scanlinesize, - sample); + status = (*tif->tif_encoderow)(tif, (uint8_t *)buf, + tif->tif_dir.td_scanlinesize, sample); /* we are now poised at the beginning of the next row */ - tif->tif_row = row + 1; + tif->tif_dir.td_row = row + 1; return (status); } @@ -188,7 +208,21 @@ int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample) /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */ static int _TIFFReserveLargeEnoughWriteBuffer(TIFF *tif, uint32_t strip_or_tile) { + static const char module[] = "_TIFFReserveLargeEnoughWriteBuffer"; TIFFDirectory *td = &tif->tif_dir; + + if (td->td_stripbytecount_p == NULL) + { + TIFFErrorExtR(tif, module, "Strip bytecount array pointer is NULL"); + return 0; + } + + if (strip_or_tile == NOSTRIP || strip_or_tile >= td->td_nstrips) + { + TIFFErrorExtR(tif, module, "Strip/tile number not valid"); + return 0; + } + if (td->td_stripbytecount_p[strip_or_tile] > 0) { /* The +1 is to ensure at least one extra bytes */ @@ -254,7 +288,7 @@ tmsize_t TIFFWriteEncodedStrip(TIFF *tif, uint32_t strip, void *data, tif->tif_flags |= TIFF_BUF4WRITE; - tif->tif_curstrip = strip; + tif->tif_dir.td_curstrip = strip; /* this informs TIFFAppendToStrip() we have changed or reset strip */ tif->tif_curoff = 0; @@ -273,7 +307,7 @@ tmsize_t TIFFWriteEncodedStrip(TIFF *tif, uint32_t strip, void *data, return ((tmsize_t)-1); } - tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; + tif->tif_dir.td_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { if (!(*tif->tif_setupencode)(tif)) @@ -362,9 +396,9 @@ tmsize_t TIFFWriteRawStrip(TIFF *tif, uint32_t strip, void *data, tmsize_t cc) return ((tmsize_t)-1); } - if (tif->tif_curstrip != strip) + if (tif->tif_dir.td_curstrip != strip) { - tif->tif_curstrip = strip; + tif->tif_dir.td_curstrip = strip; /* this informs TIFFAppendToStrip() we have changed or reset strip */ tif->tif_curoff = 0; @@ -375,7 +409,7 @@ tmsize_t TIFFWriteRawStrip(TIFF *tif, uint32_t strip, void *data, tmsize_t cc) TIFFErrorExtR(tif, module, "Zero strips per image"); return ((tmsize_t)-1); } - tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; + tif->tif_dir.td_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; return (TIFFAppendToStrip(tif, strip, (uint8_t *)data, cc) ? cc : (tmsize_t)-1); } @@ -437,7 +471,7 @@ tmsize_t TIFFWriteEncodedTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc) tif->tif_flags |= TIFF_BUF4WRITE; - tif->tif_curtile = tile; + tif->tif_dir.td_curtile = tile; /* this informs TIFFAppendToStrip() we have changed or reset tile */ tif->tif_curoff = 0; @@ -460,14 +494,14 @@ tmsize_t TIFFWriteEncodedTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc) TIFFErrorExtR(tif, module, "Zero tiles"); return ((tmsize_t)(-1)); } - tif->tif_row = (tile % howmany32) * td->td_tilelength; + tif->tif_dir.td_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; + tif->tif_dir.td_col = (tile % howmany32) * td->td_tilewidth; if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { @@ -482,8 +516,8 @@ tmsize_t TIFFWriteEncodedTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc) * 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; + if (cc < 1 || cc > tif->tif_dir.td_tilesize) + cc = tif->tif_dir.td_tilesize; /* shortcut to avoid an extra memcpy() */ if (td->td_compression == COMPRESSION_NONE) @@ -588,8 +622,10 @@ int TIFFSetupStrips(TIFF *tif) * 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)); + _TIFFmemset(td->td_stripoffset_p, 0, + (tmsize_t)((size_t)td->td_nstrips * sizeof(uint64_t))); + _TIFFmemset(td->td_stripbytecount_p, 0, + (tmsize_t)((size_t)td->td_nstrips * sizeof(uint64_t))); TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS); TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS); return (1); @@ -644,14 +680,14 @@ int TIFFWriteCheck(TIFF *tif, int tiles, const char *module) } if (isTiled(tif)) { - tif->tif_tilesize = TIFFTileSize(tif); - if (tif->tif_tilesize == 0) + tif->tif_dir.td_tilesize = TIFFTileSize(tif); + if (tif->tif_dir.td_tilesize == 0) return (0); } else - tif->tif_tilesize = (tmsize_t)(-1); - tif->tif_scanlinesize = TIFFScanlineSize(tif); - if (tif->tif_scanlinesize == 0) + tif->tif_dir.td_tilesize = (tmsize_t)(-1); + tif->tif_dir.td_scanlinesize = TIFFScanlineSize(tif); + if (tif->tif_dir.td_scanlinesize == 0) return (0); tif->tif_flags |= TIFF_BEENWRITING; @@ -689,7 +725,7 @@ int TIFFWriteBufferSetup(TIFF *tif, void *bp, tmsize_t size) } if (size == (tmsize_t)(-1)) { - size = (isTiled(tif) ? tif->tif_tilesize : TIFFStripSize(tif)); + size = (isTiled(tif) ? tif->tif_dir.td_tilesize : TIFFStripSize(tif)); /* Adds 10% margin for cases where compression would expand a bit */ if (size < TIFF_TMSIZE_T_MAX - size / 10) @@ -732,26 +768,31 @@ static int TIFFGrowStrips(TIFF *tif, uint32_t delta, const char *module) assert(td->td_planarconfig == PLANARCONFIG_CONTIG); new_stripoffset = (uint64_t *)_TIFFreallocExt( - tif, td->td_stripoffset_p, (td->td_nstrips + delta) * sizeof(uint64_t)); + tif, td->td_stripoffset_p, + (tmsize_t)(((size_t)td->td_nstrips + (size_t)delta) * + sizeof(uint64_t))); + /* + * Update td_stripoffset_p immediately so the old pointer is not left + * dangling if the second realloc fails. + */ + if (new_stripoffset) + td->td_stripoffset_p = new_stripoffset; new_stripbytecount = (uint64_t *)_TIFFreallocExt( tif, td->td_stripbytecount_p, - (td->td_nstrips + delta) * sizeof(uint64_t)); + (tmsize_t)(((size_t)td->td_nstrips + (size_t)delta) * + sizeof(uint64_t))); + if (new_stripbytecount) + td->td_stripbytecount_p = new_stripbytecount; 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)); + (tmsize_t)((size_t)delta * sizeof(uint64_t))); _TIFFmemset(td->td_stripbytecount_p + td->td_nstrips, 0, - delta * sizeof(uint64_t)); + (tmsize_t)((size_t)delta * sizeof(uint64_t))); td->td_nstrips += delta; tif->tif_flags |= TIFF_DIRTYDIRECT; @@ -769,6 +810,23 @@ static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data, uint64_t m; int64_t old_byte_count = -1; + /* Some security checks */ + if (td->td_stripoffset_p == NULL) + { + TIFFErrorExtR(tif, module, "Strip offset array pointer is NULL"); + return (0); + } + if (td->td_stripbytecount_p == NULL) + { + TIFFErrorExtR(tif, module, "Strip bytecount array pointer is NULL"); + return (0); + } + if (strip == NOSTRIP) + { + TIFFErrorExtR(tif, module, "Strip number not valid (NOSTRIP)"); + return (0); + } + if (tif->tif_curoff == 0) tif->tif_lastvalidoff = 0; @@ -790,7 +848,7 @@ static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data, if (!SeekOK(tif, td->td_stripoffset_p[strip])) { TIFFErrorExtR(tif, module, "Seek error at scanline %lu", - (unsigned long)tif->tif_row); + (unsigned long)tif->tif_dir.td_row); return (0); } @@ -812,11 +870,11 @@ static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data, /* * We are starting a fresh strip/tile, so set the size to zero. */ - old_byte_count = td->td_stripbytecount_p[strip]; + old_byte_count = (int64_t)td->td_stripbytecount_p[strip]; td->td_stripbytecount_p[strip] = 0; } - m = tif->tif_curoff + cc; + m = tif->tif_curoff + (uint64_t)cc; if (!(tif->tif_flags & TIFF_BIGTIFF)) m = (uint32_t)m; if ((m < tif->tif_curoff) || (m < (uint64_t)cc)) @@ -850,7 +908,7 @@ static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data, offsetRead = td->td_stripoffset_p[strip]; offsetWrite = TIFFSeekFile(tif, 0, SEEK_END); - m = offsetWrite + toCopy + cc; + m = offsetWrite + (uint64_t)toCopy + (uint64_t)cc; if (!(tif->tif_flags & TIFF_BIGTIFF) && m != (uint32_t)m) { TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded"); @@ -872,13 +930,15 @@ static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data, /* Move data written by previous calls to us at end of file */ while (toCopy > 0) { + tmsize_t chunkSize = + toCopy < (uint64_t)tempSize ? (tmsize_t)toCopy : tempSize; if (!SeekOK(tif, offsetRead)) { TIFFErrorExtR(tif, module, "Seek error"); _TIFFfreeExt(tif, temp); return (0); } - if (!ReadOK(tif, temp, tempSize)) + if (!ReadOK(tif, temp, chunkSize)) { TIFFErrorExtR(tif, module, "Cannot read"); _TIFFfreeExt(tif, temp); @@ -890,32 +950,32 @@ static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data, _TIFFfreeExt(tif, temp); return (0); } - if (!WriteOK(tif, temp, tempSize)) + if (!WriteOK(tif, temp, chunkSize)) { TIFFErrorExtR(tif, module, "Cannot write"); _TIFFfreeExt(tif, temp); return (0); } - offsetRead += tempSize; - offsetWrite += tempSize; - td->td_stripbytecount_p[strip] += tempSize; - toCopy -= tempSize; + offsetRead += (uint64_t)chunkSize; + offsetWrite += (uint64_t)chunkSize; + td->td_stripbytecount_p[strip] += (uint64_t)chunkSize; + toCopy -= (uint64_t)chunkSize; } _TIFFfreeExt(tif, temp); /* Append the data of this call */ - offsetWrite += cc; + offsetWrite += (uint64_t)cc; m = offsetWrite; } if (!WriteOK(tif, data, cc)) { TIFFErrorExtR(tif, module, "Write error at scanline %lu", - (unsigned long)tif->tif_row); + (unsigned long)tif->tif_dir.td_row); return (0); } tif->tif_curoff = m; - td->td_stripbytecount_p[strip] += cc; + td->td_stripbytecount_p[strip] += (uint64_t)cc; if ((int64_t)td->td_stripbytecount_p[strip] != old_byte_count) tif->tif_flags |= TIFF_DIRTYSTRIP; @@ -935,9 +995,10 @@ int TIFFFlushData1(TIFF *tif) 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)) + if (!TIFFAppendToStrip(tif, + isTiled(tif) ? tif->tif_dir.td_curtile + : tif->tif_dir.td_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 */ diff --git a/3rdparty/libtiff/tif_zip.c b/3rdparty/libtiff/tif_zip.c index 8abf88ae76..4081e7f159 100644 --- a/3rdparty/libtiff/tif_zip.c +++ b/3rdparty/libtiff/tif_zip.c @@ -159,7 +159,8 @@ static int ZIPPreDecode(TIFF *tif, uint16_t s) we need to simplify this code to reflect a ZLib that is likely updated to deal with 8byte memory sizes, though this code will respond appropriately even before we simplify it */ - sp->stream.avail_in = TIFF_CLAMP_UINT64_TO_INT32_MAX(tif->tif_rawcc); + sp->stream.avail_in = + TIFF_CLAMP_UINT64_TO_INT32_MAX((uint64_t)tif->tif_rawcc); if (inflateReset(&sp->stream) == Z_OK) { sp->read_error = 0; @@ -183,7 +184,7 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) TIFFErrorExtR(tif, module, "ZIPDecode: Scanline %" PRIu32 " cannot be read due to " "previous error", - tif->tif_row); + tif->tif_dir.td_row); return 0; } @@ -210,7 +211,7 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) } else { - uint32_t strip_height = td->td_imagelength - tif->tif_row; + uint32_t strip_height = td->td_imagelength - tif->tif_dir.td_row; if (strip_height > td->td_rowsperstrip) strip_height = td->td_rowsperstrip; if (TIFFVStripSize64(tif, strip_height) != (uint64_t)occ) @@ -254,7 +255,7 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) { memset(op, 0, (size_t)occ); TIFFErrorExtR(tif, module, "Decoding error at scanline %lu", - (unsigned long)tif->tif_row); + (unsigned long)tif->tif_dir.td_row); sp->read_error = 1; return 0; } @@ -275,8 +276,9 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) do { int state; - uInt avail_in_before = TIFF_CLAMP_UINT64_TO_INT32_MAX(tif->tif_rawcc); - uInt avail_out_before = TIFF_CLAMP_UINT64_TO_INT32_MAX(occ); + uInt avail_in_before = + TIFF_CLAMP_UINT64_TO_INT32_MAX((uint64_t)tif->tif_rawcc); + uInt avail_out_before = TIFF_CLAMP_UINT64_TO_INT32_MAX((uint64_t)occ); sp->stream.avail_in = avail_in_before; sp->stream.avail_out = avail_out_before; state = inflate(&sp->stream, Z_PARTIAL_FLUSH); @@ -288,7 +290,7 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) { memset(sp->stream.next_out, 0, (size_t)occ); TIFFErrorExtR(tif, module, "Decoding error at scanline %lu, %s", - (unsigned long)tif->tif_row, SAFE_MSG(sp)); + (unsigned long)tif->tif_dir.td_row, SAFE_MSG(sp)); sp->read_error = 1; return (0); } @@ -305,7 +307,7 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) TIFFErrorExtR(tif, module, "Not enough data at scanline %lu (short %" PRIu64 " bytes)", - (unsigned long)tif->tif_row, (uint64_t)occ); + (unsigned long)tif->tif_dir.td_row, (uint64_t)occ); memset(sp->stream.next_out, 0, (size_t)occ); sp->read_error = 1; return (0); @@ -411,7 +413,7 @@ static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) } else { - uint32_t strip_height = td->td_imagelength - tif->tif_row; + uint32_t strip_height = td->td_imagelength - tif->tif_dir.td_row; if (strip_height > td->td_rowsperstrip) strip_height = td->td_rowsperstrip; if (TIFFVStripSize64(tif, strip_height) != (uint64_t)cc) @@ -463,11 +465,11 @@ static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) if (nCompressedBytes == 0) { TIFFErrorExtR(tif, module, "Encoder error at scanline %lu", - (unsigned long)tif->tif_row); + (unsigned long)tif->tif_dir.td_row); return 0; } - tif->tif_rawcc = nCompressedBytes; + tif->tif_rawcc = (tmsize_t)nCompressedBytes; if (!TIFFFlushData1(tif)) return 0; @@ -485,7 +487,7 @@ static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) appropriately even before we simplify it */ do { - uInt avail_in_before = TIFF_CLAMP_UINT64_TO_INT32_MAX(cc); + uInt avail_in_before = TIFF_CLAMP_UINT64_TO_INT32_MAX((uint64_t)cc); sp->stream.avail_in = avail_in_before; if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) { @@ -499,7 +501,7 @@ static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) return 0; sp->stream.next_out = tif->tif_rawdata; sp->stream.avail_out = - TIFF_CLAMP_UINT64_TO_INT32_MAX(tif->tif_rawdatasize); + TIFF_CLAMP_UINT64_TO_INT32_MAX((uint64_t)tif->tif_rawdatasize); } cc -= (avail_in_before - sp->stream.avail_in); } while (cc > 0); @@ -682,7 +684,7 @@ static const TIFFField zipFields[] = { static void *TIFF_zalloc(void *opaque, unsigned int items, unsigned int size) { static const char module[] = "TIFF_zalloc"; - TIFF *tif = opaque; + TIFF *tif = (TIFF *)opaque; if (items > ~(size_t)0 / size) { @@ -698,6 +700,13 @@ static void TIFF_zfree(void *opaque, void *ptr) _TIFFfreeExt((TIFF *)opaque, ptr); } +static uint64_t ZIPGetMaxCompressionRatio(TIFF *tif) +{ + (void)tif; + /* cf https://zlib.net/zlib_tech.html */ + return 1032; +} + int TIFFInitZIP(TIFF *tif, int scheme) { static const char module[] = "TIFFInitZIP"; @@ -764,6 +773,7 @@ int TIFFInitZIP(TIFF *tif, int scheme) tif->tif_encodestrip = ZIPEncode; tif->tif_encodetile = ZIPEncode; tif->tif_cleanup = ZIPCleanup; + tif->tif_getmaxcompressionratio = ZIPGetMaxCompressionRatio; /* * Setup predictor setup. */ diff --git a/3rdparty/libtiff/tif_zstd.c b/3rdparty/libtiff/tif_zstd.c index c828dbf743..9a0b969e31 100644 --- a/3rdparty/libtiff/tif_zstd.c +++ b/3rdparty/libtiff/tif_zstd.c @@ -159,13 +159,13 @@ static int ZSTDDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) memset(op + out_buffer.pos, 0, out_buffer.size - out_buffer.pos); TIFFErrorExtR(tif, module, "Not enough data at scanline %lu (short %lu bytes)", - (unsigned long)tif->tif_row, + (unsigned long)tif->tif_dir.td_row, (unsigned long)((size_t)occ - out_buffer.pos)); return 0; } tif->tif_rawcp += in_buffer.pos; - tif->tif_rawcc -= in_buffer.pos; + tif->tif_rawcc -= (tmsize_t)in_buffer.pos; return 1; } @@ -287,7 +287,7 @@ static int ZSTDPostEncode(TIFF *tif) } if (sp->out_buffer.pos > 0) { - tif->tif_rawcc = sp->out_buffer.pos; + tif->tif_rawcc = (tmsize_t)sp->out_buffer.pos; if (!TIFFFlushData1(tif)) return 0; sp->out_buffer.dst = tif->tif_rawcp; diff --git a/3rdparty/libtiff/tiffio.h b/3rdparty/libtiff/tiffio.h index f9c206e32a..bb8fbde248 100644 --- a/3rdparty/libtiff/tiffio.h +++ b/3rdparty/libtiff/tiffio.h @@ -125,13 +125,13 @@ typedef void *thandle_t; /* client data handle */ */ /* reference white */ -#define D65_X0 (95.0470F) -#define D65_Y0 (100.0F) -#define D65_Z0 (108.8827F) +#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) +#define D50_X0 (96.4250f) +#define D50_Y0 (100.0f) +#define D50_Z0 (82.4680f) /* Structure for holding information about a display device. */ @@ -254,7 +254,7 @@ struct _TIFFRGBAImage * Macros for extracting components from the * packed ABGR form returned by TIFFReadRGBAImage. */ -#define TIFFGetR(abgr) ((abgr)&0xff) +#define TIFFGetR(abgr) ((abgr) & 0xff) #define TIFFGetG(abgr) (((abgr) >> 8) & 0xff) #define TIFFGetB(abgr) (((abgr) >> 16) & 0xff) #define TIFFGetA(abgr) (((abgr) >> 24) & 0xff) @@ -269,7 +269,7 @@ struct _TIFFRGBAImage typedef int (*TIFFInitMethod)(TIFF *, int); typedef struct { - char *name; + const char *name; uint16_t scheme; TIFFInitMethod init; } TIFFCodec; @@ -584,6 +584,7 @@ extern int TIFFReadRGBAImageOriented(TIFF *, uint32_t, uint32_t, uint32_t *, tmsize_t cc); extern tmsize_t TIFFWriteRawTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc); + extern uint64_t TIFFGetMaxCompressionRatio(TIFF *tif); extern int TIFFDataWidth( TIFFDataType); /* table of tag datatype widths within TIFF file. */ extern void TIFFSetWriteOffset(TIFF *tif, toff_t off); @@ -659,7 +660,7 @@ extern int TIFFReadRGBAImageOriented(TIFF *, uint32_t, uint32_t, uint32_t *, 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 */ + const char *field_name; /* ASCII name */ } TIFFFieldInfo; extern int TIFFMergeFieldInfo(TIFF *, const TIFFFieldInfo[], uint32_t); diff --git a/3rdparty/libtiff/tiffiop.h b/3rdparty/libtiff/tiffiop.h index 80c04c279b..4f4a29cfa5 100644 --- a/3rdparty/libtiff/tiffiop.h +++ b/3rdparty/libtiff/tiffiop.h @@ -38,6 +38,7 @@ #include #endif +#include #include #ifdef HAVE_ASSERT_H @@ -94,6 +95,7 @@ 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 *); +typedef uint64_t (*TIFFGetMaxCompressionRatioMethod)(TIFF *); struct TIFFOffsetAndDirNumber { @@ -143,13 +145,18 @@ struct tiff 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_LAZYSTRILELOAD_DONE \ + 0x2000000U /* set when lazy/ondemand loading of strip/tile \ + offset/bytecount values has been done. Only used if \ + TIFF_DEFERSTRILELOAD is set and in read-only mode */ #define TIFF_CHOPPEDUPARRAYS \ 0x4000000U /* set when allocChoppedUpStripArrays() has modified strip \ array */ +#define TIFF_LAZYSTRILELOAD_ASKED \ + 0x8000000U /* set when lazy/ondemand loading of strip/tile \ + offset/bytecount values has been requested on opening ('O' \ + flag) */ + 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 */ @@ -162,7 +169,6 @@ struct tiff tif_customdir; /* custom IFDs are separated from the main ones */ TIFFHeaderUnion tif_header; /* file's header block Classic/BigTIFF union */ uint16_t tif_header_size; /* file's header block and its length */ - uint32_t tif_row; /* current scanline */ /* There are IFDs in the file and an "active" IFD in memory, * from which fields are "set" and "get". @@ -184,7 +190,6 @@ struct tiff * - TIFF_NON_EXISTENT_DIR_NUMBER means 'dont know number of IFDs'. * - 0 means 'empty file opened for writing, but no IFD written yet' */ tdir_t tif_curdircount; - 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() */ @@ -192,10 +197,6 @@ struct tiff /* 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 */ @@ -216,10 +217,10 @@ struct tiff 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 */ + /* returns maximum compression ratio for current compression method */ + TIFFGetMaxCompressionRatioMethod tif_getmaxcompressionratio; + 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 */ @@ -295,13 +296,15 @@ struct TIFFOpenOptions * Default Read/Seek/Write definitions. */ #ifndef ReadOK -#define ReadOK(tif, buf, size) (TIFFReadFile((tif), (buf), (size)) == (size)) +#define ReadOK(tif, buf, size) \ + (TIFFReadFile((tif), (buf), (size)) == (tmsize_t)(size)) #endif #ifndef SeekOK #define SeekOK(tif, off) _TIFFSeekOK(tif, off) #endif #ifndef WriteOK -#define WriteOK(tif, buf, size) (TIFFWriteFile((tif), (buf), (size)) == (size)) +#define WriteOK(tif, buf, size) \ + (TIFFWriteFile((tif), (buf), (size)) == (tmsize_t)(size)) #endif /* NB: the uint32_t casts are to silence certain ANSI-C compilers */ @@ -315,19 +318,19 @@ struct TIFFOpenOptions (((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)) + (((x) & 0x07) ? ((uint32_t)(x) >> 3) + 1 : (uint32_t)(x) >> 3) +#define TIFFroundup_32(x, y) ((uint32_t)(TIFFhowmany_32(x, y) * (uint32_t)(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)) + (((x) & 0x07) ? ((uint64_t)(x) >> 3) + 1 : (uint64_t)(x) >> 3) +#define TIFFroundup_64(x, y) ((uint64_t)(TIFFhowmany_64(x, y) * (uint64_t)(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)(m) != (t)0) && (((t)((((t)(v)) * ((t)(m))) / ((t)(m)))) == (t)(v))) \ + ? (t)(((t)(v)) * ((t)(m))) \ : (t)0) #define TIFFmax(A, B) ((A) > (B) ? (A) : (B)) @@ -335,6 +338,10 @@ struct TIFFOpenOptions #define TIFFArrayCount(a) (sizeof(a) / sizeof((a)[0])) +/* Float/double equality macros that suppress -Wfloat-equal warnings */ +#define TIFF_FLOAT_EQ(x, y) (!(fabsf((x) - (y)) > 0.0f)) +#define TIFF_DOUBLE_EQ(x, y) (!(fabs((x) - (y)) > 0.0)) + /* Support for large files. @@ -355,7 +362,7 @@ struct TIFFOpenOptions */ #if defined(HAVE_FSEEKO) #define fseek(stream, offset, whence) fseeko(stream, offset, whence) -#define ftell(stream, offset, whence) ftello(stream, offset, whence) +#define ftell(stream) ftello(stream) #endif #endif #if defined(_WIN32) && \ @@ -459,9 +466,18 @@ extern "C" extern uint32_t _TIFFMultiply32(TIFF *, uint32_t, uint32_t, const char *); extern uint64_t _TIFFMultiply64(TIFF *, uint64_t, uint64_t, const char *); + extern uint64_t _TIFFAdd64(TIFF *, uint64_t, uint64_t, const char *); extern tmsize_t _TIFFMultiplySSize(TIFF *, tmsize_t, tmsize_t, const char *); + extern tmsize_t _TIFFAddSSize(TIFF *, tmsize_t, tmsize_t, const char *); extern tmsize_t _TIFFCastUInt64ToSSize(TIFF *, uint64_t, const char *); + extern uint32_t _TIFFCastUInt64ToUInt32(TIFF *, uint64_t, const char *); + extern uint64_t _TIFFComputeRowSize64(TIFF *, uint32_t, uint16_t, uint16_t, + const char *); + extern tmsize_t _TIFFComputeRowOffset(TIFF *, tmsize_t rowstride, uint32_t, + const char *); + extern uint64_t _TIFFComputeBitOffset(TIFF *, uint32_t, uint16_t, uint16_t, + const char *); extern void *_TIFFCheckMalloc(TIFF *, tmsize_t, tmsize_t, const char *); extern void *_TIFFCheckRealloc(TIFF *, void *, tmsize_t, tmsize_t, const char *); @@ -471,6 +487,8 @@ extern "C" extern void _TIFFCleanupIFDOffsetAndNumberMaps(TIFF *tif); + extern uint64_t _TIFFStrileSize64(TIFF *tif, uint32_t nrows, int isStrip); + extern tmsize_t _TIFFReadEncodedStripAndAllocBuffer(TIFF *tif, uint32_t strip, void **buf,