Merge pull request #29864 from Xingchen1224:libtiff-4.7.2-upgrade-5.x

Port of #29838 - 3rdparty/libtiff: upgrade libtiff to 4.7.2 - #29864

3rdparty/libtiff: Upgrade libtiff to 4.7.2 - port of #29838

[Feature Request] Upgrade libtiff to 4.7.2 (https://libtiff.gitlab.io/libtiff/releases/v4.7.2.html)

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

(cherry picked from commit 5b526645b6)

### 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
This commit is contained in:
Xingchen
2026-09-08 10:15:36 +03:00
committed by GitHub
parent 6a4ce74373
commit b2e8947065
43 changed files with 5352 additions and 1700 deletions
+1 -1
View File
@@ -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)
+2336
View File
@@ -1,3 +1,2339 @@
2026-06-27 Even Rouault <even.rouault@spatialys.com>
libtiff 4.7.2 release
2026-06-27 Even Rouault <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
Merge branch 'rst_formatting_fix' into 'master'
v4.7.2.rst: formatting fix
See merge request libtiff/libtiff!913
2026-06-27 Even Rouault <even.rouault@spatialys.com>
Revert "_TIFFSetDefaultCompressionState(): reset postdecode callback"
This reverts commit b7a73279cc83e39a2d3425d69185281009f7554a.
Fixes #860, but re-opens #795
2026-06-27 Even Rouault <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
v4.7.2.rst: formatting fix.
2026-06-25 Even Rouault <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <faxguy@howardsilvan.com>
tif_jbig.c don't discard validly decoded data if errors occur.
2026-06-25 Even Rouault <even.rouault@spatialys.com>
_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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <wangdw.augustus@qq.com>
Handle negative TIFFReadFile results before state updates (#854)
Harden integer size and offset calculations in libtiff, tools, and contrib
2026-06-12 waugustus <wangdw.augustus@qq.com>
Fix signed left-shift UB in LogLuv RANDITHER encoding (#850)
2026-06-10 Even Rouault <even.rouault@spatialys.com>
Merge branch 'patch-1' into 'master'
oss-fuzz: fix broken build
See merge request libtiff/libtiff!896
2026-06-10 david korczynski <david@adalogics.com>
oss-fuzz: fix broken build.
2026-06-08 Even Rouault <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
DumpModeSeek(): fix -Wsign-compare on 32 bit platforms.
2026-06-08 Even Rouault <even.rouault@spatialys.com>
Merge branch 'formatting_fixes' into 'master'
Formatting fixes (apply pre-commit run --all)
See merge request libtiff/libtiff!893
2026-06-08 Even Rouault <even.rouault@spatialys.com>
Formatting fixes (apply pre-commit run --all)
2026-06-08 Even Rouault <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <evil.gen.sec@gmail.com>
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 <amhurtado@protonmail.com>
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 <amhurtado@protonmail.com>
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 <amhurtado@protonmail.com>
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 <amhurtado@protonmail.com>
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 <amhurtado@protonmail.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <amhurtado@protonmail.com>
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 <amhurtado@protonmail.com>
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 <even.rouault@spatialys.com>
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 <amhurtado@protonmail.com>
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 <wangdw.augustus@qq.com>
Address review feedback for overflow guard fixes.
2026-05-14 Even Rouault <even.rouault@spatialys.com>
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 <wangdw.augustus@qq.com>
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 <even.rouault@spatialys.com>
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 <wangdw.augustus@qq.com>
tiffcrop: fix byte carry for left/right composite bit offsets.
tiffcrop: recompute composite crop dimensions before allocation.
2026-05-09 Even Rouault <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
TIFFFillStrip/Tile(): avoid excessive memory allocation.
Closes #831
2026-05-07 Even Rouault <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <sulau@freenet.de>
TIFFLinkDirectory() checks for IFD loops (fixes 788)
2026-05-07 waugustus <wangdw.augustus@qq.com>
pixarlog: error out on invalid ABGR output buffer sizes.
pixarlog: complete ABGR bounds check for multi-row strip decoding.
2026-05-05 Niels Provos <provos@gmail.com>
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 <even.rouault@spatialys.com>
Doc: TIFFFdOpen(): clarify role of filename parameter.
Fixes #823
TIFFRGBAImage: avoid int overflows in put functions.
Fixes #830
2026-05-04 Even Rouault <even.rouault@spatialys.com>
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 <provos@gmail.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <little-endian> Version: 0x2a <ClassicTIFF>
Directory 0: offset 8 (0x8) next 2147483647 (0x7fffffff)
[...]
```
2026-04-25 Roger Leigh <rleigh@codelibre.net>
Merge branch 'cmake-macos-framework' into 'master'
Build: Support for iOS-derived builds
See merge request libtiff/libtiff!780
2026-04-25 Roger Leigh <rleigh@codelibre.net>
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 <treata11@yahoo.com>
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 <rleigh@codelibre.net>
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 <treata11@yahoo.com>
Build: Support for iOS-derived builds.
2026-04-25 Roger Leigh <rleigh@codelibre.net>
Merge branch 'oss-fuzz' into 'master'
Add fuzzer for libtiff write logic
See merge request libtiff/libtiff!875
2026-04-25 Roger Leigh <rleigh@codelibre.net>
Remove unused __TIFFSafeMultiply macro and MAX_SIZE constant.
2026-04-25 Arthur Chan <arthur.chan@adalogics.com>
Fix formatting and build script.
Fix formatting accordingly.
Create new fuzzer and integrate to libtiff.
2026-04-25 Roger Leigh <rleigh@codelibre.net>
Merge branch 'fix-bufoverflow' into 'master'
tiffcrop: avoid buffer overflow in combineSeparateTileSamplesBytes()
See merge request libtiff/libtiff!848
2026-04-25 Roger Leigh <rleigh@codelibre.net>
Merge branch 'tiffsplit-kostasl' into 'master'
tiffsplit: use 7-digit numbered output names
See merge request libtiff/libtiff!874
2026-04-25 Kostas Lagogiannis <costaslag@gmail.com>
tiffsplit: use 7-digit numbered output names.
2026-04-25 Roger Leigh <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
Merge branch 'support_arm64_arm64ec' into 'master'
Enable support for arm64EC
See merge request libtiff/libtiff!830
2026-04-25 Roger Leigh <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
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 <wangdw.augustus@qq.com>
pixarlog: add comment explaining 4-byte advance in ABGR decode.
2026-04-23 waugustus <wangdw.augustus@qq.com>
pixarlog: fix heap-buffer-overflow in 8BITABGR decode with stride 3 (#824)
2026-04-22 Even Rouault <even.rouault@spatialys.com>
Add libtiff/README_for_libtiff_developpers.md and reference it in various GetMaxCompressionRatio() functions
2026-04-22 Even Rouault <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <wangdw.augustus@qq.com>
tiffcrop: size separated region buffers from actual dimensions.
2026-04-21 Even Rouault <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
Update pre-commit clang-format to v22.1.3 and apply 'pre-commit run --all'
2026-04-20 Even Rouault <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
tif_write: Make expression less ambiguous.
tif_config: Don't check if macro defined when undefined.
2026-04-18 Roger Leigh <rleigh@codelibre.net>
Run clang-format on all modified files.
Suggested-by: Timothy Lyanguzov <theta682@gitlab.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-18 Roger Leigh <rleigh@codelibre.net>
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 <theta682@gitlab.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-18 Roger Leigh <rleigh@codelibre.net>
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 <theta682@gitlab.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-18 Roger Leigh <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
Merge remote-tracking branch 'origin/master' into warning-additions4.
2026-04-12 Even Rouault <even.rouault@spatialys.com>
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 <mohammadmseet@gmail.com>
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 <even.rouault@spatialys.com>
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 <sulau@freenet.de>
Some editorials due to suggestions.
2026-04-09 Even Rouault <even.rouault@spatialys.com>
Merge branch 'master' into 'master'
Check result of _TIFFCheckRealloc
See merge request libtiff/libtiff!865
2026-04-08 Roger Leigh <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
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 <aymeric.esparre@gmail.com>
Check result of _TIFFCheckRealloc to prevent memory leaks and segmentation fault when reallocation fails.
2026-04-06 Su_Laus <sulau@freenet.de>
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 <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <rleigh@codelibre.net>
Merge branch 'warning-additions3' into 'master'
Add additional warnings: write-strings and conversion
See merge request libtiff/libtiff!802
2026-04-04 Roger Leigh <rleigh@codelibre.net>
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 <vseleznev@cloudlinux.com>
tiffcrop: Remove dead code in combineSeparateTileSamplesBytes()
2026-04-01 Even Rouault <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <wangdw.augustus@qq.com>
tif_getimage: reject tile widths that would overflow toskew (#808)
2026-03-29 Even Rouault <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <wangdw.augustus@qq.com>
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 <even.rouault@spatialys.com>
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 <wangdw.augustus@qq.com>
tiff2pdf: Fix integer overflow in RGBA raster allocation in tiff2pdf by validating size computation before _TIFFrealloc()
Fixes #804
2026-03-29 Even Rouault <even.rouault@spatialys.com>
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 <wangdw.augustus@qq.com>
tiffcmp: validate scanline buffer sizes in mixed planar comparison to prevent out-of-bounds reads (#802)
2026-03-23 Even Rouault <even.rouault@spatialys.com>
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 <kodareef5@gmail.com>
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 <dataisland@outlook.com>
thumbnail: improve integer overflow check for image memory allocation.
thumbnail: add integer overflow check for image memory allocation.
2026-03-22 Even Rouault <even.rouault@spatialys.com>
Merge branch '_TIFFPartialReadStripArray_overflow' into 'master'
_TIFFPartialReadStripArray(): avoid potential (unsigned) integer overflow in...
See merge request libtiff/libtiff!851
2026-03-22 Su_Laus <sulau@freenet.de>
TIFFAppendToStrip(): add some checks to avoid null-pointer-dereferencing (fixes #777 second issue).
2026-03-22 dataisland <dataisland@outlook.com>
thumbnail: prevent integer overflow by capping row count at 256.
2026-03-21 Even Rouault <even.rouault@spatialys.com>
_TIFFPartialReadStripArray(): avoid potential (unsigned) integer overflow in file offset computation, on 32 bit builds
2026-03-21 Even Rouault <even.rouault@spatialys.com>
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 <dataisland@outlook.com>
rgb2ycbcr: fix integer overflow check for pixel count calculation.
2026-03-18 Even Rouault <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <dataisland@outlook.com>
thumbnail.c: add error handling for missing strip and tile byte counts.
2026-03-16 Even Rouault <even.rouault@spatialys.com>
_TIFFSetDefaultPostDecode(): improve code comment for bitspersample == 128
2026-03-16 Even Rouault <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
PixarLog: fix undoing horizontal differencing when SamplesPerPixel != 3 and 4
Patch by Christoph Gohlke (@cgohlke)
Fixes #789
2026-03-16 Even Rouault <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
thumbnail.c: add missing include (master only)
2026-03-15 Even Rouault <even.rouault@spatialys.com>
Merge branch 'formatting_fixes' into 'master'
Formatting fixes
See merge request libtiff/libtiff!840
2026-03-15 Roger Leigh <rleigh@codelibre.net>
thumbnail: Include tiffiop.h for _TIFFMultiply32.
Merge remote-tracking branch 'origin/master' into warning-additions3.
2026-03-15 Even Rouault <even.rouault@spatialys.com>
Merge branch 'issue-790-median' into 'master'
fix UAF in tiffmedian (#790)
See merge request libtiff/libtiff!831
2026-03-15 Even Rouault <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
Merge branch 'issue-790-tiffcrop' into 'master'
fix undefined behaviour in tiffcrop (#790)
See merge request libtiff/libtiff!834
2026-03-15 Even Rouault <even.rouault@spatialys.com>
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 <rleigh@codelibre.net>
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 <even.rouault@spatialys.com>
Formatting fixes.
2026-03-15 Even Rouault <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
Merge branch 'fix_798' into 'master'
putcontig8bitYCbCr44tile: fix wrong fromskew computation
Closes #798
See merge request libtiff/libtiff!838
2026-03-13 waugustus <wangdw.augustus@qq.com>
tools: validate numeric command-line arguments (#799)
2026-03-13 Even Rouault <even.rouault@spatialys.com>
putcontig8bitYCbCr44tile: fix wrong fromskew computation.
Fix error introduced in 06155116f6ee7f910ac5a8a60e0852c621d72306
Fixes #798
2026-03-11 waugustus <wangdw.augustus@qq.com>
fix inconsistent fromskew handling in put16bitbwtile (#792)
2026-03-03 4ugustus <wangdw.augustus@qq.com>
Simplify cleanup by removing redundant NULL check.
2026-03-03 waugustus <wangdw.augustus@qq.com>
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 <amaldika@qti.qualcomm.com>
Enable support for arm64EC.
2026-02-24 Roger Leigh <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
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 <even.rouault@spatialys.com>
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 <rleigh@codelibre.net>
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 <even.rouault@spatialys.com>
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 <rleigh@codelibre.net>
test: Correct MSVC warnings.
Use Windows Containers for VS2022 and VS2026 builds.
2026-02-14 Even Rouault <even.rouault@spatialys.com>
Merge branch 'issue-784-tiffcrop' into 'master'
fix stack-overflow in #784
See merge request libtiff/libtiff!823
2026-02-14 Even Rouault <even.rouault@spatialys.com>
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 <wangdw.augustus@qq.com>
fix null pointer deference in #782.
2026-02-12 waugustus <wangdw.augustus@qq.com>
fix stack-overflow in #784.
2026-02-11 Even Rouault <even.rouault@spatialys.com>
Merge branch 'formatting_fixes' into 'master'
Formatting fixes
See merge request libtiff/libtiff!822
2026-02-10 Even Rouault <even.rouault@spatialys.com>
Formatting fixes.
2026-02-08 Even Rouault <even.rouault@spatialys.com>
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 <rleigh@codelibre.net>
CI: Switch MinGW builds to use Windows Docker image.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ci: Revert to use powershell.
2026-02-06 Roger Leigh <rleigh@codelibre.net>
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 <noreply@anthropic.com>
2026-02-06 Roger Leigh <rleigh@codelibre.net>
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 <noreply@anthropic.com>
2026-02-02 Even Rouault <even.rouault@spatialys.com>
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 <sulau@freenet.de>
tiffdump: Avoid unaligned memory access for tag field values.
2026-02-02 Even Rouault <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <sulau@freenet.de>
Amend test and tools for cxx compatibility - mainly "const char *". Some additional re-formating due to clang-format.
2026-01-30 Su_Laus <sulau@freenet.de>
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 <even.rouault@spatialys.com>
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 <github@lovell.info>
ojpeg: prevent EOF infinite loop (fixes commit 2a3d55b)
2026-01-22 Bob Friesenhahn <graphicsmagick.project@gmail.com>
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 <bobjfriesenhahn@gmail.com>
Eliminate duplicate case TIFF_SETGET_C0_IFD8.
2026-01-21 Even Rouault <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
Merge branch 'tiffsplit-769' into 'master'
tiffsplit: check filename length, #769
See merge request libtiff/libtiff!808
2026-01-19 Roger Leigh <rleigh@codelibre.net>
Merge branch 'warning-additions2' into 'master'
Add additional compiler warnings to extra-warnings
See merge request libtiff/libtiff!800
2026-01-09 Lee Howard <faxguy@howardsilvan.com>
tiffcp - avoid integer overflow in iskew and oskew, #770.
2025-12-31 Lee Howard <faxguy@howardsilvan.com>
tiffsplit: check filename length, #769.
fax2tiff: avoid endless loop on corrupt input, #759.
2025-12-29 Roger Leigh <rleigh@codelibre.net>
Merge remote-tracking branch 'origin/master' into warning-additions2.
2025-12-27 Roger Leigh <rleigh@codelibre.net>
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 <even.rouault@spatialys.com>
JPEGDecode(): fix memory leak in error code path.
Fixes https://issues.oss-fuzz.com/issues/471945501
2025-12-25 Even Rouault <even.rouault@spatialys.com>
Merge branch 'warning-additions' into 'master'
ci: Build CMake builds with extra-warnings
See merge request libtiff/libtiff!798
2025-12-25 Roger Leigh <rleigh@codelibre.net>
Merge branch 'ossfuzz_471472003' into 'master'
TIFFFillStrip(): prevent harmless unsigned integer overflow
See merge request libtiff/libtiff!801
2025-12-25 Roger Leigh <rleigh@codelibre.net>
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 <even.rouault@spatialys.com>
TIFFFillStrip(): prevent harmless unsigned integer overflow.
Fixes https://issues.oss-fuzz.com/issues/471472003
2025-12-24 Roger Leigh <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
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 <even.rouault@spatialys.com>
_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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
tif_dirread.c: fix typo in code comment (master only)
2025-12-22 Roger Leigh <rleigh@codelibre.net>
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 <even.rouault@spatialys.com>
Rework TIFF_LAZYSTRILELOAD flag.
2025-12-22 Even Rouault <even.rouault@spatialys.com>
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 <rleigh@codelibre.net>
Merge branch 'ci-vcpkg' into 'master'
ci: Use vcpkg installation specific to libtiff
See merge request libtiff/libtiff!792
2025-12-21 Roger Leigh <rleigh@codelibre.net>
ci: Use vcpkg installation specific to libtiff.
2025-12-21 Roger Leigh <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
ci: Test C++ compatibility mode.
2025-12-18 Roger Leigh <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
Merge branch 'ci-windows' into 'master'
ci: Add Windows builds
See merge request libtiff/libtiff!790
2025-12-17 Roger Leigh <rleigh@codelibre.net>
Add .gitattributes.
ci: Corrections for Cygwin and MinGW builds.
ci: Restrict most jobs to libtiff/libtiff.
2025-12-16 Roger Leigh <rleigh@codelibre.net>
ci: Add Windows builds.
ci: Drop AppVeyor use.
2025-12-16 Even Rouault <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <rleigh@codelibre.net>
Merge branch 'ci-linux' into 'master'
ci: Use Linux Docker runner
See merge request libtiff/libtiff!787
2025-12-15 Roger Leigh <rleigh@codelibre.net>
ci: Use Linux Docker runner.
2025-12-15 Roger Leigh <rleigh@codelibre.net>
Merge branch 'ci-macos' into 'master'
ci: Add MacOS and FreeBSD builds
See merge request libtiff/libtiff!786
2025-12-15 Roger Leigh <rleigh@codelibre.net>
ci: Add MacOS and FreeBSD builds.
2025-12-14 Roger Leigh <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
Merge branch 'fix-goto-variable-init' into 'master'
Fix goto bypassing variable initialisation
See merge request libtiff/libtiff!783
2025-12-14 Roger Leigh <rleigh@codelibre.net>
Merge remote-tracking branch 'origin/master' into fix-goto-variable-init
2025-12-14 Roger Leigh <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
Merge branch 'remove-register-keyword' into 'master'
Remove use of register keyword
See merge request libtiff/libtiff!779
2025-12-14 Roger Leigh <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
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 <bobjfriesenhahn@gmail.com>
configure.ac: Require bootstrap with at least Autoconf 2.71.
2025-12-13 Roger Leigh <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
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 <rleigh@codelibre.net>
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 <even.rouault@spatialys.com>
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 <sulau@freenet.de>
Checking the range of double values in tiff2ps before converting to int32_t. Closes #679
2025-12-07 Even Rouault <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <mkhachaiants@gmail.com>
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 <sulau@freenet.de>
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 <even.rouault@spatialys.com>
Su Laus <sulau@freenet.de>
Apply 2 suggestion(s) to 1 file(s)
2025-11-29 Su_Laus <sulau@freenet.de>
Align writing and reading of TIFF_LONG8 and TIFF_IFD8 tags.
2025-11-29 Even Rouault <even.rouault@spatialys.com>
Merge branch 'warning_fixes' into 'master'
Fix compiler warnings with clang 18
See merge request libtiff/libtiff!771
2025-11-29 Even Rouault <even.rouault@spatialys.com>
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 <sulau@freenet.de>
Fix bug introduced by MR libtiff/libtiff!769 (issue-753-putcontig8bitYCbCr42tile) and revealed by mingw build in AppVeyor.
2025-11-25 Even Rouault <even.rouault@spatialys.com>
Fix compiler warnings with clang 18.
2025-11-25 Even Rouault <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
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 <wangdw.augustus@qq.com>
Reject invalid YCbCr subsampling when image dimensions are smaller than the subsampling block to prevent out-of-bounds writes. (#753)
2025-11-11 waugustus <wangdw.augustus@qq.com>
tiffcrop: fix undefined behavior in reverseSamples32bits() (#752)
2025-11-10 waugustus <wangdw.augustus@qq.com>
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 <sulau@freenet.de>
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 <even.rouault@spatialys.com>
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 <sulau@freenet.de>
Check td_stripbytecount_p and td_stripoffset_p for NULL pointer before (re-)writing to file.
Closes #749
2025-09-17 Reinhold Gschweicher <pyro4hell@gmail.com>
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 <pyro4hell@gmail.com>
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 <rleigh@codelibre.net>
2025-09-15 Reinhold Gschweicher <pyro4hell@gmail.com>
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 <even.rouault@spatialys.com>
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 <even.rouault@spatialys.com>
Merge branch 'raw2tiff-742' into 'master'
+1 -1
View File
@@ -1 +1 @@
20250911
20260627
+112 -15
View File
@@ -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;
}
+3 -3
View File
@@ -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() */
/************************************************************************/
/**
+40 -41
View File
@@ -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);
}
}
+36 -12
View File
@@ -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);
+90 -55
View File
@@ -31,6 +31,7 @@
#include "tiffiop.h"
#include <float.h> /*--: for Rational2Double */
#include <limits.h>
#include <math.h>
/*
* 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--;
+14 -2
View File
@@ -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 */
};
+130 -24
View File
@@ -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;
}
+241 -82
View File
@@ -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 */
+242 -122
View File
@@ -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)
+18 -3
View File
@@ -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);
}
+158 -95
View File
@@ -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.
*/
+73 -65
View File
@@ -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); \
+259 -173
View File
@@ -29,6 +29,7 @@
*/
#include "tiffiop.h"
#include <limits.h>
#include <math.h>
#include <stdio.h>
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);
+23 -20
View File
@@ -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() */
/************************************************************************/
/**
+9 -2
View File
@@ -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;
+225 -167
View File
@@ -22,9 +22,6 @@
* OF THIS SOFTWARE.
*/
#define WIN32_LEAN_AND_MEAN
#define VC_EXTRALEAN
#include "tiffiop.h"
#include <stdlib.h>
@@ -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;
+83 -65
View File
@@ -33,6 +33,7 @@
#include "Lerc_c_api.h"
#include "zlib.h"
#include <math.h>
#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);
+84 -81
View File
@@ -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);
+57 -8
View File
@@ -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.
*/
+50 -32
View File
@@ -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.
+8 -7
View File
@@ -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);
}
+172 -130
View File
@@ -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;
}
+21 -14
View File
@@ -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.
+19 -2
View File
@@ -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 */
+160 -77
View File
@@ -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;
+11 -5
View File
@@ -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 <emmintrin.h>
#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);
+59 -33
View File
@@ -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));
}
}
+243 -127
View File
@@ -27,6 +27,7 @@
* Scanline-oriented Read Support
*/
#include "tiffiop.h"
#include <limits.h>
#include <stdio.h>
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;
+45 -11
View File
@@ -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(
+20 -20
View File
@@ -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)
+12 -10
View File
@@ -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);
}
+44 -51
View File
@@ -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";
+11 -8
View File
@@ -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);
+36 -21
View File
@@ -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:
+8 -7
View File
@@ -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);
}
+121 -60
View File
@@ -30,7 +30,7 @@
#include "tiffiop.h"
#include <stdio.h>
#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 */
+24 -14
View File
@@ -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.
*/
+3 -3
View File
@@ -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;
+10 -9
View File
@@ -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);
+40 -22
View File
@@ -38,6 +38,7 @@
#include <sys/types.h>
#endif
#include <math.h>
#include <string.h>
#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,