summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore17
-rw-r--r--.gitlab-ci.yml14
-rw-r--r--CMakeLists.txt38
-rw-r--r--ChangeLog884
-rw-r--r--HOWTO-RELEASE54
-rw-r--r--Makefile.vc3
-rw-r--r--README.md5
-rw-r--r--RELEASE-DATE2
-rw-r--r--VERSION2
-rw-r--r--build/gitlab-ci2
-rw-r--r--configure.ac23
-rwxr-xr-xcontrib/oss-fuzz/build.sh29
-rw-r--r--contrib/oss-fuzz/tiff_read_rgba_fuzzer.cc91
-rw-r--r--html/Makefile.am3
-rw-r--r--html/bigtiffpr.html6
-rw-r--r--html/bugs.html19
-rw-r--r--html/index.html18
-rw-r--r--html/libtiff.html32
-rw-r--r--html/v3.5.6-beta.html2
-rw-r--r--html/v4.1.0.html198
-rw-r--r--libtiff/CMakeLists.txt2
-rw-r--r--libtiff/libtiff.def7
-rw-r--r--libtiff/mkg3states.c2
-rw-r--r--libtiff/tif_aux.c75
-rw-r--r--libtiff/tif_config.vc.h21
-rw-r--r--libtiff/tif_dir.c67
-rw-r--r--libtiff/tif_dir.h12
-rw-r--r--libtiff/tif_dirinfo.c2
-rw-r--r--libtiff/tif_dirread.c1293
-rw-r--r--libtiff/tif_dirwrite.c343
-rw-r--r--libtiff/tif_flush.c118
-rw-r--r--libtiff/tif_getimage.c34
-rw-r--r--libtiff/tif_jpeg.c17
-rw-r--r--libtiff/tif_luv.c25
-rw-r--r--libtiff/tif_lzw.c2
-rw-r--r--libtiff/tif_ojpeg.c86
-rw-r--r--libtiff/tif_open.c18
-rw-r--r--libtiff/tif_pixarlog.c12
-rw-r--r--libtiff/tif_print.c10
-rw-r--r--libtiff/tif_read.c256
-rw-r--r--libtiff/tif_strip.c38
-rw-r--r--libtiff/tif_thunder.c10
-rw-r--r--libtiff/tif_tile.c27
-rw-r--r--libtiff/tif_webp.c10
-rw-r--r--libtiff/tif_win32.c50
-rw-r--r--libtiff/tif_write.c145
-rw-r--r--libtiff/tif_zip.c56
-rw-r--r--libtiff/tiffio.h10
-rw-r--r--libtiff/tiffiop.h22
-rw-r--r--libtiff/tiffvers.h4
-rw-r--r--man/TIFFOpen.3tiff15
-rw-r--r--man/libtiff.3tiff6
-rw-r--r--nmake.opt10
-rw-r--r--port/Makefile.vc44
-rw-r--r--port/libport.h12
-rw-r--r--test/CMakeLists.txt25
-rw-r--r--test/Makefile.am27
-rw-r--r--test/common.sh1
-rw-r--r--test/defer_strile_loading.c311
-rw-r--r--test/defer_strile_writing.c239
-rwxr-xr-xtest/fax2tiff.sh17
-rw-r--r--test/images/README.txt3
-rw-r--r--test/images/miniswhite-1c-1b.g3bin0 -> 9687 bytes
-rw-r--r--test/images/ojpeg_chewey_subsamp21_multi_strip.tiffbin0 -> 39752 bytes
-rw-r--r--test/images/ojpeg_single_strip_no_rowsperstrip.tiffbin0 -> 8258 bytes
-rw-r--r--test/images/ojpeg_zackthecat_subsamp22_single_strip.tiffbin0 -> 8258 bytes
-rwxr-xr-xtest/ppm2tiff_pbm.sh1
-rwxr-xr-xtest/ppm2tiff_pgm.sh1
-rwxr-xr-xtest/ppm2tiff_ppm.sh1
-rw-r--r--test/refs/o-tiff2ps-EPS1.ps112
-rw-r--r--test/refs/o-tiff2ps-PS1.ps115
-rw-r--r--test/refs/o-tiff2ps-PS2.ps104
-rw-r--r--test/refs/o-tiff2ps-PS3.ps104
-rw-r--r--test/rewrite_tag.c39
-rw-r--r--test/testtypes.c58
-rwxr-xr-xtest/tiff2bw-logluv-3c-16b.sh7
-rwxr-xr-xtest/tiff2bw-lzw-single-strip.sh7
-rwxr-xr-xtest/tiff2bw-minisblack-1c-16b.sh7
-rwxr-xr-xtest/tiff2bw-minisblack-1c-8b.sh7
-rwxr-xr-xtest/tiff2bw-minisblack-2c-8b-alpha.sh7
-rwxr-xr-xtest/tiff2bw-miniswhite-1c-1b.sh7
-rwxr-xr-xtest/tiff2bw-ojpeg_chewey_subsamp21_multi_strip.sh7
-rwxr-xr-xtest/tiff2bw-ojpeg_zackthecat_subsamp22_single_strip.sh7
-rwxr-xr-xtest/tiff2bw-palette-1c-1b.sh7
-rwxr-xr-xtest/tiff2bw-palette-1c-4b.sh7
-rwxr-xr-xtest/tiff2bw-quad-tile.jpg.sh7
-rwxr-xr-xtest/tiff2bw-quad-tile.jpg.t1iff.sh7
-rwxr-xr-xtest/tiff2bw-rgb-3c-16b.sh7
-rwxr-xr-xtest/tiff2ps-EPS1.sh4
-rwxr-xr-xtest/tiff2ps-PS1.sh4
-rwxr-xr-xtest/tiff2ps-PS2.sh4
-rwxr-xr-xtest/tiff2ps-PS3.sh4
-rwxr-xr-xtest/tiff2rgba-lzw-single-strip.sh7
-rwxr-xr-xtest/tiff2rgba-ojpeg_chewey_subsamp21_multi_strip.sh7
-rwxr-xr-xtest/tiff2rgba-ojpeg_single_strip_no_rowsperstrip.sh7
-rwxr-xr-xtest/tiff2rgba-ojpeg_zackthecat_subsamp22_single_strip.sh7
-rwxr-xr-xtest/tiff2rgba-quad-lzw-compat.sh7
-rwxr-xr-xtest/tiff2rgba-quad-tile.jpg.t1iff.sh7
-rwxr-xr-xtest/tiffcrop-R90-lzw-single-strip.sh7
-rwxr-xr-xtest/tiffcrop-R90-ojpeg_chewey_subsamp21_multi_strip.sh7
-rwxr-xr-xtest/tiffcrop-R90-ojpeg_zackthecat_subsamp22_single_strip.sh7
-rwxr-xr-xtest/tiffcrop-R90-quad-lzw-compat.sh7
-rwxr-xr-xtest/tiffcrop-R90-quad-tile.jpg.t1iff.sh7
-rwxr-xr-xtest/tiffcrop-doubleflip-lzw-single-strip.sh7
-rwxr-xr-xtest/tiffcrop-doubleflip-ojpeg_chewey_subsamp21_multi_strip.sh7
-rwxr-xr-xtest/tiffcrop-doubleflip-ojpeg_zackthecat_subsamp22_single_strip.sh7
-rwxr-xr-xtest/tiffcrop-doubleflip-quad-lzw-compat.sh7
-rwxr-xr-xtest/tiffcrop-doubleflip-quad-tile.jpg.t1iff.sh7
-rwxr-xr-xtest/tiffcrop-extract-lzw-single-strip.sh7
-rwxr-xr-xtest/tiffcrop-extract-ojpeg_chewey_subsamp21_multi_strip.sh7
-rwxr-xr-xtest/tiffcrop-extract-ojpeg_zackthecat_subsamp22_single_strip.sh7
-rwxr-xr-xtest/tiffcrop-extract-quad-lzw-compat.sh7
-rwxr-xr-xtest/tiffcrop-extract-quad-tile.jpg.t1iff.sh7
-rwxr-xr-xtest/tiffcrop-extractz14-lzw-single-strip.sh7
-rwxr-xr-xtest/tiffcrop-extractz14-ojpeg_chewey_subsamp21_multi_strip.sh7
-rwxr-xr-xtest/tiffcrop-extractz14-ojpeg_zackthecat_subsamp22_single_strip.sh7
-rwxr-xr-xtest/tiffcrop-extractz14-quad-lzw-compat.sh7
-rwxr-xr-xtest/tiffcrop-extractz14-quad-tile.jpg.t1iff.sh7
-rw-r--r--tools/fax2tiff.c18
-rw-r--r--tools/pal2rgb.c7
-rw-r--r--tools/ppm2tiff.c2
-rw-r--r--tools/raw2tiff.c27
-rw-r--r--tools/rgb2ycbcr.c1
-rw-r--r--tools/thumbnail.c2
-rw-r--r--tools/tiff2pdf.c62
-rw-r--r--tools/tiff2ps.c34
-rw-r--r--tools/tiffcmp.c2
-rw-r--r--tools/tiffcp.c11
-rw-r--r--tools/tiffcrop.c68
-rw-r--r--tools/tiffdump.c2
-rw-r--r--tools/tiffgt.c2
-rw-r--r--tools/tiffset.c4
-rw-r--r--tools/tiffsplit.c2
133 files changed, 4904 insertions, 1090 deletions
diff --git a/.gitignore b/.gitignore
index 64b08bde..bb20ea72 100644
--- a/.gitignore
+++ b/.gitignore
@@ -43,6 +43,8 @@ tools/fax2tiff
tools/pal2rgb
tools/ppm2tiff
tools/raw2tiff
+tools/rgb2ycbcr
+tools/thumbnail
tools/tiff2bw
tools/tiff2pdf
tools/tiff2ps
@@ -52,7 +54,22 @@ tools/tiffcp
tools/tiffcrop
tools/tiffdither
tools/tiffdump
+tools/tiffgt
tools/tiffinfo
tools/tiffmedian
tools/tiffset
tools/tiffsplit
+test/ascii_tag
+test/custom_dir
+test/long_tag
+test/raw_decode
+test/rewrite
+test/short_tag
+test/strip_rw
+test/defer_strile_loading
+test/defer_strile_writing
+test/testtypes
+test/*.log
+test/*.trs
+test/o-*
+*~
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index b80f8bed..c8a89403 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -4,11 +4,14 @@ before_script:
stages:
- build
+ - pages
autoconf:
stage: build
script:
- sh build/gitlab-ci autoconf
+ after_script:
+ - 'cat autoconf-build/test/test-suite.log'
cmake-makefiles:
stage: build
@@ -19,3 +22,14 @@ cmake-ninja:
stage: build
script:
- sh build/gitlab-ci cmake "Ninja" Debug
+
+pages:
+ stage: pages
+ script:
+ - cp -r html public
+ artifacts:
+ name: $CI_PROJECT_NAME-$CI_JOB_NAME
+ paths:
+ - public
+ only:
+ - master
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 845ddf0e..d0285be0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -43,17 +43,13 @@ if (POLICY CMP0054)
endif(POLICY CMP0054)
# Read version information from configure.ac.
-FILE(READ "${CMAKE_CURRENT_SOURCE_DIR}/configure.ac" configure)
-STRING(REGEX REPLACE ";" "\\\\;" configure "${configure}")
-STRING(REGEX REPLACE "\n" ";" configure "${configure}")
+FILE(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/configure.ac" configure REGEX "^LIBTIFF_.*=")
foreach(line ${configure})
foreach(var LIBTIFF_MAJOR_VERSION LIBTIFF_MINOR_VERSION LIBTIFF_MICRO_VERSION LIBTIFF_ALPHA_VERSION
LIBTIFF_CURRENT LIBTIFF_REVISION LIBTIFF_AGE)
- if(NOT ${var})
- string(REGEX MATCH "^${var}=(.*)" ${var}_MATCH "${line}")
- if(${var}_MATCH)
- string(REGEX REPLACE "^${var}=(.*)" "\\1" ${var} "${line}")
- endif()
+ if(NOT ${var} AND line MATCHES "^${var}=(.*)")
+ set(${var} "${CMAKE_MATCH_1}")
+ break()
endif()
endforeach()
endforeach()
@@ -338,29 +334,21 @@ endif()
if(SIZEOF_UNSIGNED_INT EQUAL SIZEOF_SIZE_T)
set(TIFF_SIZE_T "unsigned int")
set(TIFF_SIZE_FORMAT "%u")
+ set(TIFF_SSIZE_T "signed int")
+ set(TIFF_SSIZE_FORMAT "%d")
elseif(SIZEOF_UNSIGNED_LONG EQUAL SIZEOF_SIZE_T)
set(TIFF_SIZE_T "unsigned long")
set(TIFF_SIZE_FORMAT "%lu")
-elseif(SIZEOF_UNSIGNED_LONG_LONG EQUAL SIZEOF_SIZE_T)
- set(TIFF_SIZE_T "unsigned long")
- if (MINGW)
- set(TIFF_SIZE_FORMAT "%I64u")
- else()
- set(TIFF_SIZE_FORMAT "%llu")
- endif()
-endif()
-
-if(SIZEOF_SIGNED_INT EQUAL SIZEOF_UNSIGNED_CHAR_P)
- set(TIFF_SSIZE_T "signed int")
- set(TIFF_SSIZE_FORMAT "%d")
-elseif(SIZEOF_SIGNED_LONG EQUAL SIZEOF_UNSIGNED_CHAR_P)
set(TIFF_SSIZE_T "signed long")
set(TIFF_SSIZE_FORMAT "%ld")
-elseif(SIZEOF_SIGNED_LONG_LONG EQUAL SIZEOF_UNSIGNED_CHAR_P)
+elseif(SIZEOF_UNSIGNED_LONG_LONG EQUAL SIZEOF_SIZE_T)
+ set(TIFF_SIZE_T "unsigned long long")
set(TIFF_SSIZE_T "signed long long")
if (MINGW)
+ set(TIFF_SIZE_FORMAT "%I64u")
set(TIFF_SSIZE_FORMAT "%I64d")
else()
+ set(TIFF_SIZE_FORMAT "%llu")
set(TIFF_SSIZE_FORMAT "%lld")
endif()
endif()
@@ -392,7 +380,7 @@ check_symbol_exists(strtol "stdlib.h" HAVE_STRTOL)
check_symbol_exists(strtoll "stdlib.h" HAVE_STRTOLL)
check_symbol_exists(strtoul "stdlib.h" HAVE_STRTOUL)
check_symbol_exists(strtoull "stdlib.h" HAVE_STRTOULL)
-check_symbol_exists(getopt "unistd.h" HAVE_GETOPT)
+check_symbol_exists(getopt "unistd.h;stdio.h" HAVE_GETOPT)
check_symbol_exists(lfind "search.h" HAVE_LFIND)
if(NOT HAVE_SNPRINTF)
@@ -403,6 +391,8 @@ endif()
set(HOST_FILLORDER FILLORDER_MSB2LSB)
if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "i.*86.*" OR
CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "amd64.*" OR
+ # AMD64 on Windows
+ CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "AMD64" OR
CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86_64.*")
set(HOST_FILLORDER FILLORDER_LSB2MSB)
endif()
@@ -623,7 +613,7 @@ if(strip-chopping)
endif()
# Defer loading of strip/tile offsets
-option(defer-strile-load "enable deferred strip/tile offset/size loading (experimental)" OFF)
+option(defer-strile-load "enable deferred strip/tile offset/size loading (also available at runtime with the 'D' flag of TIFFOpen())" OFF)
set(DEFER_STRILE_LOAD ${defer-strile-load})
# CHUNKY_STRIP_READ_SUPPORT
diff --git a/ChangeLog b/ChangeLog
index 1f50e201..01e2182c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,887 @@
+2019-11-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ libtiff 4.1.0 released.
+
+ Added a step for updating the legacy ChangeLog file.
+
+ Ignore emacs temporary files (ending with tilde character).
+
+ Added release summary page for the 4.1.0 release.
+
+ Fix Cmake HAVE_GETOPT for systems which declare getopt in stdio.h. Fix utility baked-in getopt prototype which appears when HAVE_GETOPT is not defined.
+
+ Fax2tiff.sh needs to remove its output file in advance. Syntax changes so that bash is not required.
+
+2019-10-26 Even Rouault <even.rouault@spatialys.com>
+
+ tif_jpeg.c: extra cast to silence Coverity warning. GDAL CID 1406475.
+
+2019-10-23 Even Rouault <even.rouault@spatialys.com>
+
+ tif_jpeg.c: fix warning added by previous commit (on 32bit builds)
+
+2019-10-23 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'coverity-fixes' into 'master'
+ Coverity fixes
+
+ See merge request libtiff/libtiff!94
+
+2019-10-22 Timothy Lyanguzov <timothy.lyanguzov@sap.com>
+
+ Use 64-bit calculations correctly.
+
+ Fix size calculation to use 64-bit tmsize_t correctly.
+
+ Make bytesperclumpline calculations using tmsize_t type.
+
+2019-10-03 Even Rouault <even.rouault@spatialys.com>
+
+ tif_read: align code of TIFFReadRawStrip() and TIFFReadRawTile() that differed for non good reason. Non-functional change normally. (fixes GitLab #162)
+
+2019-10-01 Even Rouault <even.rouault@spatialys.com>
+
+ HTML: update for GitLab issues.
+
+2019-09-29 Even Rouault <even.rouault@spatialys.com>
+
+ html/v3.5.6-beta.html: redact URL of defunct web site.
+
+ Website: update links to mailing list.
+
+2019-09-17 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFReadAndRealloc(): avoid too large memory allocation attempts. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=17244
+
+2019-09-03 Even Rouault <even.rouault@spatialys.com>
+
+ ByteCountLooksBad and EstimateStripByteCounts: avoid unsigned integer overflows. Fixes https://oss-fuzz.com/testcase-detail/5686156066291712 and https://oss-fuzz.com/testcase-detail/6332499206078464
+
+2019-09-02 Even Rouault <even.rouault@spatialys.com>
+
+ tif_ojpeg.c: avoid relying on isTiled macro being wrapped in ()
+
+ tif_ojpeg.c: avoid use of uninitialized memory on edge/broken file. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16844
+
+ tiff_read_rgba_fuzzer.cc: add a -DSTANDALONE mode for easier reproduction of oss-fuzz reports
+
+2019-09-01 Even Rouault <even.rouault@spatialys.com>
+
+ tif_dirread.c: allocChoppedUpStripArrays(). avoid unsigned integer overflow. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16846
+
+2019-08-27 Even Rouault <even.rouault@spatialys.com>
+
+ tif_ojpeg.c: avoid unsigned integer overflow. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16793
+
+2019-08-26 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFReadDirEntryData(): rewrite to avoid unsigned integer overflow (not a bug). Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16792
+
+ TIFFFetchDirectory(): fix invalid cast from uint64 to tmsize_t. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16784
+
+2019-08-25 Even Rouault <even.rouault@spatialys.com>
+
+ JPEG: avoid use of unintialized memory on corrupted files.
+ Follow-up of cf3ce6fab894414a336546f62adc57f02590a22c
+ Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16602
+ Credit to OSS Fuzz
+
+2019-08-23 Even Rouault <even.rouault@spatialys.com>
+
+ _TIFFPartialReadStripArray(): avoid unsigned integer overflow. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16685
+
+ OJPEGWriteHeaderInfo(): avoid unsigned integer overflow on strile dimensions close to UINT32_MAX. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16683
+
+ TIFFFillStrip(): avoid harmless unsigned integer overflow. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16653
+
+ EstimateStripByteCounts(): avoid unsigned integer overflow. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16643&
+
+ tif_ojpeg: avoid unsigned integer overflow (probably not a bug). Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16635
+
+ tif_thunder: avoid unsigned integer overflow (not a bug). Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16632
+
+2019-08-22 Even Rouault <even.rouault@spatialys.com>
+
+ _TIFFMultiply32() / _TIFFMultiply64(): avoid relying on unsigned integer overflow (not a bug)
+
+ EstimateStripByteCounts(): avoid unsigned integer overflow.
+
+2019-08-21 Even Rouault <even.rouault@spatialys.com>
+
+ EstimateStripByteCounts(): avoid unsigned integer overflow.
+
+2019-08-20 Even Rouault <even.rouault@spatialys.com>
+
+ EstimateStripByteCounts(): avoid harmless unsigned integer overflow.
+
+ _TIFFPartialReadStripArray(): avoid triggering unsigned integer overflow with -fsanitize=unsigned-integer-overflow (not a bug, this is well defined by itself)
+
+2019-08-18 Even Rouault <even.rouault@spatialys.com>
+
+ tiff2ps: fix use of wrong data type that caused issues (/Height being written as 0) on 64-bit big endian platforms
+
+2019-08-16 Even Rouault <even.rouault@spatialys.com>
+
+ setByteArray(): fix previous commit.
+
+ setByteArray(): avoid potential signed integer overflow. Pointed by Hendra Gunadi. No actual problem known (which does not mean there wouldn't be any. Particularly on 32bit builds)
+
+2019-08-15 Even Rouault <even.rouault@spatialys.com>
+
+ RGBA interface: fix integer overflow potentially causing write heap buffer overflow, especially on 32 bit builds. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16443. Credit to OSS Fuzz
+
+2019-08-14 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_integer_overflow' into 'master'
+ Fix integer overflow in _TIFFCheckMalloc() and other implementation-defined behaviour (CVE-2019-14973)
+
+ See merge request libtiff/libtiff!90
+
+2019-08-13 Even Rouault <even.rouault@spatialys.com>
+
+ Fix integer overflow in _TIFFCheckMalloc() and other implementation-defined behaviour (CVE-2019-14973)
+ _TIFFCheckMalloc()/_TIFFCheckRealloc() used a unsafe way to detect overflow
+ in the multiplication of nmemb and elem_size (which are of type tmsize_t, thus
+ signed), which was especially easily triggered on 32-bit builds (with recent
+ enough compilers that assume that signed multiplication cannot overflow, since
+ this is undefined behaviour by the C standard). The original issue which lead to
+ this fix was trigged from tif_fax3.c
+
+ There were also unsafe (implementation defied), and broken in practice on 64bit
+ builds, ways of checking that a uint64 fits of a (signed) tmsize_t by doing
+ (uint64)(tmsize_t)uint64_var != uint64_var comparisons. Those have no known
+ at that time exploits, but are better to fix in a more bullet-proof way.
+ Or similarly use of (int64)uint64_var <= 0.
+
+2019-08-12 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFClientOpen(): fix memory leak if one of the required callbacks is not provided. Fixed Coverity GDAL CID 1404110
+
+ OJPEGReadBufferFill(): avoid very long processing time on corrupted files. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16400. master only
+
+2019-08-10 Even Rouault <even.rouault@spatialys.com>
+
+ oss-fuzz/tiff_read_rgba_fuzzer.cc: fix wrong env variable value in previous commit
+
+ oss-fuzz/tiff_read_rgba_fuzzer.cc: avoid issue with libjpeg-turbo and MSAN
+
+ OJPEG: fix integer division by zero on corrupted subsampling factors. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=15824. Credit to OSS Fuzz
+
+ Merge branch 'ossfuzz_i386'
+
+ contrib/oss-fuzz/build.sh: fix for i386 build of jbigkit, and use $LIB_FUZZING_ENGINE
+
+2019-08-10 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'patch-1' into 'master'
+ fix two tiny typos
+
+ See merge request libtiff/libtiff!89
+
+2019-08-10 Reto Kromer <rk@reto.ch>
+
+ fix two tiny typos.
+
+2019-08-09 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'patch-1' into 'master'
+ fix a typo in man page
+
+ See merge request libtiff/libtiff!88
+
+2019-08-09 Reto Kromer <rk@reto.ch>
+
+ fix typo.
+
+2019-08-04 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'TIFFTAGID_Zero_reading_IGNORE' into 'master'
+ Suppressed Reading of Tiff tags with ID = 0 (like GPSVERSIONID) corrected.
+
+ See merge request libtiff/libtiff!77
+
+2019-08-04 Su Laus <sulau@freenet.de>
+
+ Reading of Tiff tags with ID = 0 (like GPSVERSIONID) corrected.
+ IGNORE placeholder in tif_dirread.c is now replaced by a field dir_ignore in the TIFFDirEntry structure
+
+ Currently, in tif_dirread.c a special IGNORE value for the tif tags is defined
+ in order to flag status preventing already processed tags from further processing.
+ This irrational behaviour prevents reading of custom tags with id code 0 - like tag GPSVERSIONID from EXIF 2.31 definition.
+
+ An additional field 'tdir_ignore' is now added to the TIFFDirEntry structure and code is changed
+ to allow tags with id code 0 to be read correctly.
+
+ This change was already proposed as pending improvement in tif_dirread.c around line 32.
+
+ Reference is also made to:
+ - Discussion in https://gitlab.com/libtiff/libtiff/merge_requests/39
+ - http://bugzilla.maptools.org/show_bug.cgi?id=2540
+
+ Comments and indention adapted.
+
+ Preparation to rebase onto master
+
+2019-07-16 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'cmake_amd64' into 'master'
+ CMakeLists.txt: properly set value of HOST_FILLORDER to LSB2MSB for Windows CMake builds
+
+ See merge request libtiff/libtiff!87
+
+2019-07-15 Even Rouault <even.rouault@spatialys.com>
+
+ CMakeLists.txt: properly set value of HOST_FILLORDER to LSB2MSB for Windows CMake builds
+ As can be seen in https://ci.appveyor.com/project/rleigh-codelibre/libtiff-didfs/builds/25846668/job/ory5w098j8wcij9x
+ log, the HOST_FILLORDER is not properly set:
+
+ [00:02:58] -- CMAKE_HOST_SYSTEM_PROCESSOR set to AMD64
+ [00:02:58] -- HOST_FILLORDER set to FILLORDER_MSB2LSB
+
+ Ther reason is that we match the "amd64.*" lowercase string whereas
+ CMAKE_HOST_SYSTEM_PROCESSOR is set to AMD64 uppercase.
+
+2019-07-09 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFWriteCheck(): call TIFFForceStrileArrayWriting() when needed (should have gone with eaeca6274ae71cdfaeb9f673b6fb0f3cfc0e6ce5) (master only)
+
+2019-07-09 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_chromium_925269' into 'master'
+ OJPEG: avoid use of unintialized memory on corrupted files
+
+ See merge request libtiff/libtiff!86
+
+2019-07-05 Even Rouault <even.rouault@spatialys.com>
+
+ OJPEG: avoid use of unintialized memory on corrupted files.
+ Fixes https://bugs.chromium.org/p/chromium/issues/detail?id=925269
+ Patch from Lei Zhang with little adaptations.
+
+2019-06-29 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix-division-by-zero' into 'master'
+ Return infinite distance when denominator is zero.
+
+ See merge request libtiff/libtiff!85
+
+2019-06-29 Dirk Lemstra <dirk@lemstra.org>
+
+ Return infinite distance when denominator is zero.
+
+2019-06-29 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'typetests' into 'master'
+ Add test to check that libtiff types have the correct size
+
+ See merge request libtiff/libtiff!57
+
+2019-05-31 Thomas Bernard <miniupnp@free.fr>
+
+ make TIFF_SSIZE_T the same bitwidth as TIFF_SIZE_T.
+ it was previously the same bitwidth as unsigned char *
+ Pointers can be larger than size_t.
+
+2019-05-31 Thomas Bernard <miniupnp@free.fr>
+
+ Add test to check that libtiff types have the correct size.
+ in configure/CMakeList.txt :
+
+ - TIFF_INT8_T/TIFF_UINT8_T is signed/unsigned char
+ sizeof(char)==1 in C standard
+ - TIFF_INT16_T/TIFF_UINT16_T is signed/unsigned short
+ sizeof(short)>=2 in C standard
+ - TIFF_INT32_T/TIFF_UINT32_T is defined so its sizeof() is 4
+
+ - TIFF_INT64_T/TIFF_UINT64_T is defined so its sizeof() is 8
+
+ - TIFF_SIZE_T is defined so it has same sizeof() than size_t
+
+ - TIFF_SSIZE_T is defined so it has same sizeof() than unsigned char *
+
+2019-05-29 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'defer_strile_writing' into 'master'
+ Add TIFFDeferStrileArrayWriting() and TIFFForceStrileArrayWriting()
+
+ See merge request libtiff/libtiff!82
+
+2019-05-29 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'TIFFReadFromUserBuffer' into 'master'
+ Add TIFFReadFromUserBuffer()
+
+ See merge request libtiff/libtiff!81
+
+2019-05-26 Even Rouault <even.rouault@spatialys.com>
+
+ Fix vulnerability in 'D' (DeferStrileLoad) mode (master only) (fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14908)
+
+2019-05-25 Even Rouault <even.rouault@spatialys.com>
+
+ Replace 'stripped' by 'striped' in error messages.
+
+2019-05-25 Even Rouault <even.rouault@spatialys.com>
+
+ Add TIFFDeferStrileArrayWriting() and TIFFForceStrileArrayWriting()
+ Those advanced writing functions must be used in a particular sequence
+ to make their intended effect. Their aim is to control when/where
+ the [Strip/Tile][Offsets/ByteCounts] arrays are written into the file.
+
+ The purpose of this is to generate 'cloud-optimized geotiff' files where
+ the first KB of the file only contain the IFD entries without the potentially
+ large strile arrays. Those are written afterwards.
+
+ The typical sequence of calls is:
+ TIFFOpen()
+ [ TIFFCreateDirectory(tif) ]
+ Set fields with calls to TIFFSetField(tif, ...)
+ TIFFDeferStrileArrayWriting(tif)
+ TIFFWriteCheck(tif, ...)
+ TIFFWriteDirectory(tif)
+ ... potentially create other directories and come back to the above directory
+ TIFFForceStrileArrayWriting(tif): emit the arrays at the end of file
+
+ See test/defer_strile_writing.c for a practical example.
+
+2019-05-24 Even Rouault <even.rouault@spatialys.com>
+
+ Fix vulnerability introduced by defer strile loading (master only)
+ Found on GDAL with https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14894
+ Disabling the TIFF_DEFERSTRILELOAD bit in ChopupStripArray() was a
+ bad idea since when using TIFFReadDirectory() to reload the directory again
+ would lead to a different value of td_rowsperstrip, which could confuse
+ readers if they relied on the value found initially.
+
+ Fix typo in error message (master only)
+
+2019-05-22 Even Rouault <even.rouault@spatialys.com>
+
+ Add TIFFReadFromUserBuffer()
+ This function replaces the use of TIFFReadEncodedStrip()/TIFFReadEncodedTile()
+ when the user can provide the buffer for the input data, for example when
+ he wants to avoid libtiff to read the strile offset/count values from the
+ [Strip|Tile][Offsets/ByteCounts] array.
+
+ libtiff.def: add missing new symbols.
+
+ test/defer_strile_loading.c: fix warning with Visual C++
+
+ _TIFFRewriteField(): fix for bigtiff case (master only)
+ 116cf67f4c59196605abdb244657c3070c4310af made StripByteCount/TileByteCount to
+ always be rewritten as TIFF_LONG8.
+
+2019-05-21 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'ondemand_strile_offbytecount_loading' into 'master'
+ Make defer strile offset/bytecount loading available at runtime
+
+ See merge request libtiff/libtiff!79
+
+2019-05-21 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bigtiff_write_bytecount_on_long_when_possible' into 'master'
+ Create TileByteCounts/StripByteCounts tag with SHORT (ClassicTIFF/BigTIFF) or LONG (BigTIFF) type when possible
+
+ See merge request libtiff/libtiff!78
+
+2019-05-21 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'html_link' into 'master'
+ libtiff.html, bigtiffpr.html: absolute => relative link
+
+ See merge request libtiff/libtiff!80
+
+2019-05-14 Thomas Bernard <miniupnp@free.fr>
+
+ libtiff.html, bigtiffpr.html: absolute => relative link.
+
+2019-05-10 Even Rouault <even.rouault@spatialys.com>
+
+ Make defer strile offset/bytecount loading available at runtime.
+ ... and add per-strile offset/bytecount loading capabilities.
+
+ Part of this commit makes the behaviour that was previously met when
+ libtiff was compiled with -DDEFER_STRILE_LOAD available for default builds
+ when specifying the new 'D' (Deferred) TIFFOpen() flag. In that mode, the [Tile/Strip][ByteCounts/Offsets]
+ arrays are only loaded when first accessed. This can speed-up the opening
+ of files stored on the network when just metadata retrieval is needed.
+ This mode has been used for years by the GDAL library when compiled with
+ its embeded libtiff copy.
+
+ To avoid potential out-of-tree code (typically codecs) that would use
+ the td_stripbytecount and td_stripoffset array inconditionnaly assuming they
+ have been loaded, those have been suffixed with _p (for protected). The
+ use of the new functions mentionned below is then recommended.
+
+ Another addition of this commit is the capability of loading only the
+ values of the offset/bytecount of the strile of interest instead of the
+ whole array. This is enabled with the new 'O' (Ondemand) flag of TIFFOpen()
+ (which implies 'D'). That behaviour has also been used by GDAL, which hacked
+ into the td_stripoffset/td_stripbytecount arrays directly. The new code
+ added in the _TIFFFetchStrileValue() and _TIFFPartialReadStripArray() internal
+ functions is mostly a port of what was in GDAL GTiff driver previously.
+
+ Related to that, the public TIFFGetStrileOffset[WithErr]() and TIFFGetStrileByteCount[WithErr]()
+ functions have been added to API. They are of particular interest when
+ using sparse files (with offset == bytecount == 0) and you want to detect
+ if a strile is present or not without decompressing the data, or updating
+ an existing sparse file.
+ They will also be used to enable a future enhancement where client code can entirely
+ skip bytecount loading in some situtations
+
+ A new test/defer_strile_loading.c test has been added to test the above
+ capabilities.
+
+2019-05-10 Even Rouault <even.rouault@spatialys.com>
+
+ Creation: use SHORT type when possible for StripByteCounts/TileByteCounts
+ This follows the same logic as previous commit.
+
+2019-05-09 Even Rouault <even.rouault@spatialys.com>
+
+ BigTIFF creation: write TileByteCounts/StripByteCounts tag with LONG when possible
+ In most situations of BigTIFF file, the tile/strip sizes are of reasonable size,
+ that is they fit on a 4-byte LONG. So in that case, use LONG instead of LONG8
+ to save some space. For uncompressed file, it is easy to detect such situations
+ by checking at the TIFFTileSize64()/TIFFStripSize64() return. For compressed file,
+ we must take into account the fact that compression may sometimes result in
+ larger compressed data. So we allow this optimization only for a few select
+ compression times, and take a huge security margin (10x factor). We also only
+ apply this optimization on multi-strip files, so as to allow easy on-the-fly
+ growing of single-strip files whose strip size could grow above the 4GB threshold.
+
+ This change is compatible with the BigTIFF specification. According to
+ https://www.awaresystems.be/imaging/tiff/bigtiff.html:
+ "The StripOffsets, StripByteCounts, TileOffsets, and TileByteCounts tags are
+ allowed to have the datatype TIFF_LONG8 in BigTIFF. Old datatypes TIFF_LONG,
+ and TIFF_SHORT where allowed in the TIFF 6.0 specification, are still valid in BigTIFF, too. "
+ On a practical point of view, this is also compatible on reading/writing of
+ older libtiff 4.X versions.
+
+ The only glitch I found, which is rather minor, is when using such a BigTIFF
+ file with TileByteCounts/StripByteCounts written with TIFF_LONG, and updating
+ it with an older libtiff 4.X version with a change in the
+ [Tile/Strip][ByteCounts/Offsets] array. In that case the _TIFFRewriteField()
+ function will rewrite the directory and array with TIFF_LONG8, instead of updating
+ the existing array (this is an issue fixed by this commit). The file will
+ still be valid however, hence the minor severity of this.
+
+2019-05-08 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bug2799' into 'master'
+ fix fax2tiff
+
+ See merge request libtiff/libtiff!55
+
+2019-05-08 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bug_2829' into 'master'
+ WIN32: use tif_win32.c when building with CMake
+
+ See merge request libtiff/libtiff!75
+
+2019-05-06 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'FILESOURCE_SCENETYPE_reading' into 'master'
+ Reading error for FileSource and SceneType tags corrected.
+
+ See merge request libtiff/libtiff!76
+
+2019-05-06 Su Laus <sulau@freenet.de>
+
+ Reading error for FileSource and SceneType tags corrected.
+ EXIF tags FILESOURCE and SCENETYPE are defined as TIFF_UNDEFINED and field_readcount==1!
+ There is a bug in TIFFReadDirEntryByte() preventing to read correctly type TIFF_UNDEFINED fields with field_readcount==1
+ Upgrade of TIFFReadDirEntryByte() with added TIFF_UNDEFINED switch-entry allows libtiff to read those tags correctly.
+
+2019-04-25 Thomas Bernard <miniupnp@free.fr>
+
+ WIN32: use tif_win32.c when building with CMake.
+ see http://bugzilla.maptools.org/show_bug.cgi?id=2829
+
+ the top CMakeLists.txt defines
+ win32_io and USE_WIN32_FILEIO
+
+ WIN32_IO is defined nowhere in CMake (only in automake things)
+
+2019-04-25 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'gitlab_pages' into 'master'
+ Advertise https://libtiff.gitlab.io/libtiff/ as mirror
+
+ See merge request libtiff/libtiff!70
+
+2019-04-25 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bug_2844' into 'master'
+ tiff2ps.c: PSDataColorContig(): avoid heap buffer overrun
+
+ See merge request libtiff/libtiff!69
+
+2019-04-25 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue_2785' into 'master'
+ tiff2pdf.c: don't call t2p_tile_collapse_left() for Ycbcr
+
+ See merge request libtiff/libtiff!64
+
+2019-04-11 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_gdal_1439' into 'master'
+ TIFFWriteEncodedStrip/TIFFWriteEncodedTile: fix rewriting of LZW-compressed data
+
+ See merge request libtiff/libtiff!74
+
+2019-04-11 Even Rouault <even.rouault@spatialys.com>
+
+ TIFFWriteEncodedStrip/TIFFWriteEncodedTile: fix rewriting of LZW-compressed data
+ Fixes https://github.com/OSGeo/gdal/issues/1439
+
+ When rewriting a LZW tile/strip whose existing size is very close to a multiple of
+ 1024 bytes (and larger than 8192 bytes) with compressed data that is larger,
+ the new data was not placed at the end of the file, causing corruption.
+
+2019-04-08 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bug2848' into 'master'
+ tif_luv.c: LogLuvSetupEncode() error must return 0
+
+ See merge request libtiff/libtiff!72
+
+2019-04-03 Thomas Bernard <miniupnp@free.fr>
+
+ build/gitlab-ci: fix typo.
+
+ show test-suite.log in gitlab-ci.
+ useful when build fails
+
+ Add output check for tiff2ps.
+ note : the reference files have been generated in master branch
+
+2019-03-23 Even Rouault <even.rouault@spatialys.com>
+
+ tif_read.c: potentially fix false positive from Coverity Scan. CID 1400288
+
+ tif_read.c: potentially fix false positive from Coverity Scan. CID 1400271
+
+ tif_zip.c: remove dead code. CID 1400360.
+
+ tif_webp.c: remove false positive warning about dereference before null check. CID 1400255
+
+ tif_pixarlog.c: remove dead code. CID 1400342.
+
+ tif_pixarlog.c: avoid false positive Coverity Scan warnings about overflow. CID 1400300 and 1400367
+
+ tif_lzw.c: silence CoverityScan false positive. CID 1400355.
+
+ tif_luv.c: silence CoverityScan false positive. CID 1400231, 1400251, 1400254, 1400272, 1400318, 1400356
+
+ TryChopUpUncompressedBigTiff(): avoid potential division by zero. master only. GDAL Coverity CID 1400263
+
+2019-03-22 Thomas Bernard <miniupnp@free.fr>
+
+ tif_luv.c: LogLuvSetupEncode() error must return 0.
+ see http://bugzilla.maptools.org/show_bug.cgi?id=2848
+
+ if wrongly returning 1, the processing of incorrect file continues,
+ which causes problems.
+
+2019-03-22 Thomas Bernard <miniupnp@free.fr>
+
+ add a test for fax2tiff tool.
+
+2019-02-28 Thomas Bernard <miniupnp@free.fr>
+
+ tiff2pdf.c: don't call t2p_tile_collapse_left() when buffer size is wrong
+ see http://bugzilla.maptools.org/show_bug.cgi?id=2785
+
+ Advertise https://libtiff.gitlab.io/libtiff/ as mirror.
+ I'm put it above the maptools.org mirror because
+ Even Rouault believe at some point it will be completely removed
+
+2019-02-28 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bug_2826' into 'master'
+ tiff2pdf.c: check colormap pointers when loading CMYK with colormap
+
+ See merge request libtiff/libtiff!65
+
+2019-02-28 Thomas Bernard <miniupnp@free.fr>
+
+ tiff2pdf.c: check colormap pointers.
+ Avoid access to non initialized pointers
+ http://bugzilla.maptools.org/show_bug.cgi?id=2826
+
+2019-02-27 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'fix_warnings' into 'master'
+ tiff2ps.c: fix warning caused by integer promotion
+
+ See merge request libtiff/libtiff!68
+
+2019-02-23 Thomas Bernard <miniupnp@free.fr>
+
+ PSDataColorContig(): avoid heap buffer overrun.
+ fixes http://bugzilla.maptools.org/show_bug.cgi?id=2844
+ each iteration of the loop read nc bytes
+
+2019-02-22 Thomas Bernard <miniupnp@free.fr>
+
+ tiff2ps.c: fix warning caused by integer promotion.
+ uint8 value is promoted to int in (value << 24) so -fsanitize
+ yield runtime errors :
+ tiff2ps.c:2969:33: runtime error: left shift of 246 by 24 places cannot be represented in type 'int'
+
+2019-02-22 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'large_strile_improvements' into 'master'
+ Large strile support improvements
+
+ See merge request libtiff/libtiff!63
+
+2019-02-21 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'gitlab-pages' into 'master'
+ ci: Add pages job
+
+ See merge request libtiff/libtiff!45
+
+2019-02-19 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue_2833' into 'master'
+ tiffcp.c: check that (Tile Width)*(Samples/Pixel) do no overflow
+
+ See merge request libtiff/libtiff!60
+
+2019-02-19 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue_2831' into 'master'
+ tiffcrop.c: fix invertImage() for bps 2 and 4
+
+ See merge request libtiff/libtiff!61
+
+2019-02-19 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'issue_2842' into 'master'
+ move _TIFFClampDoubleToFloat() to tif_aux.c
+
+ See merge request libtiff/libtiff!62
+
+2019-02-19 Even Rouault <even.rouault@spatialys.com>
+
+ tif_zip.c: allow reading and writing strips/tiles with more than 4 GB of compressed or uncompressed data
+
+ tif_dirread.c: when strip chopping is enabled, extend this mechanism to multi-strip uncompressed files with strips larger than 2GB to expose them as strips of ~500 MB
+
+2019-02-19 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'size_t_typo' into 'master'
+ CMakeLists.txt: fix TIFF_SIZE_T
+
+ See merge request libtiff/libtiff!59
+
+2019-02-12 Thomas Bernard <miniupnp@free.fr>
+
+ move _TIFFClampDoubleToFloat() to tif_aux.c.
+ the same function was declared in tif_dir.c and tif_dirwrite.c
+
+ see http://bugzilla.maptools.org/show_bug.cgi?id=2842
+
+2019-02-11 Thomas Bernard <miniupnp@free.fr>
+
+ tiffcrop.c: fix invertImage() for bps 2 and 4.
+ too much bytes were processed, causing a heap buffer overrun
+ http://bugzilla.maptools.org/show_bug.cgi?id=2831
+ the loop counter must be
+ for (col = 0; col < width; col += 8 / bps)
+
+ Also the values were not properly calculated. It should be
+ 255-x, 15-x, 3-x for bps 8, 4, 2.
+
+ But anyway it is easyer to invert all bits as 255-x = ~x, etc.
+ (substracting from a binary number composed of all 1 is like inverting
+ the bits)
+
+2019-02-11 Thomas Bernard <miniupnp@free.fr>
+
+ tiffcp.c: use INT_MAX.
+
+ check that (Tile Width)*(Samples/Pixel) do no overflow.
+ fixes bug 2833
+
+2019-02-03 Thomas Bernard <miniupnp@free.fr>
+
+ CMakeLists.txt: fix TIFF_SIZE_T.
+
+2019-02-02 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'master' into 'master'
+ Fix for simple memory leak that was assigned CVE-2019-6128.
+
+ See merge request libtiff/libtiff!50
+
+2019-02-02 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bug2835' into 'master'
+ tiff2ps: fix heap-buffer-overflow
+
+ See merge request libtiff/libtiff!53
+
+2019-02-02 Even Rouault <even.rouault@spatialys.com>
+
+ Fix warning (use of uninitialized value) added per d0a842c5dbad2609aed43c701a12ed12461d3405 (fixes https://gitlab.com/libtiff/libtiff/merge_requests/54#note_137742985)
+
+2019-02-02 Yuri Aksenov <yuri.aksenov@gmail.com>
+
+ fix fax2tiff.
+ see http://bugzilla.maptools.org/show_bug.cgi?id=2799
+ fixes d9bc8472e72549f29c0062c1cbd3d56f279f3be2
+
+2019-02-02 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'tiffcrop' into 'master'
+ tiffcrop: shut up clang warnings
+
+ See merge request libtiff/libtiff!52
+
+2019-02-01 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'bug2833' into 'master'
+ TIFFWriteDirectoryTagTransferfunction() : fix NULL dereferencing
+
+ See merge request libtiff/libtiff!54
+
+2019-02-01 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'gitignore' into 'master'
+ add test/ files to .gitignore
+
+ See merge request libtiff/libtiff!56
+
+2019-02-01 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'master' into 'master'
+ tif_dir: unset transferfunction field if necessary (CVE-2018-19210)
+
+ See merge request libtiff/libtiff!47
+
+2019-01-29 Thomas Bernard <miniupnp@free.fr>
+
+ add test/ files to .gitignore.
+
+2019-01-29 Thomas Bernard <miniupnp@free.fr>
+
+ TIFFWriteDirectoryTagTransferfunction() : fix NULL dereferencing.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2833
+
+ we must check the pointer is not NULL before memcmp() the memory
+
+2019-01-29 Thomas Bernard <miniupnp@free.fr>
+
+ tiff2ps: fix heap-buffer-overflow.
+ http://bugzilla.maptools.org/show_bug.cgi?id=2834
+
+ usually the test (i < byte_count) is OK because the byte_count is divisible by samplesperpixel.
+ But if that is not the case, (i + ncomps) < byte_count should be used, or
+ maybe (i + samplesperpixel) <= byte_count
+
+2019-01-28 Thomas Bernard <miniupnp@free.fr>
+
+ tiffcrop: shut up clang warnings.
+ make the out filename building a bit more simple
+ and remove the use of strcat()
+
+2019-01-23 Scott Gayou <github.scott@gmail.com>
+
+ Fix for simple memory leak that was assigned CVE-2019-6128.
+ pal2rgb failed to free memory on a few errors. This was reported
+ here: http://bugzilla.maptools.org/show_bug.cgi?id=2836.
+
+2019-01-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ Fix tiff2ps error regarding "Inconsistent value of es" by allowing es to be zero. Problem was reported to the tiff mailing list by Julian H. Stacey on January 5, 2019.
+
+2018-12-13 Hugo Lefeuvre <hle@debian.org>
+
+ tif_dir: unset transferfunction field if necessary.
+ The number of entries in the transfer table is determined as following:
+
+ (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1
+
+ This means that whenever td->td_samplesperpixel or td->td_extrasamples are
+ modified we also need to make sure that the number of required entries in
+ the transfer table didn't change.
+
+ If it changed and the number of entries is higher than before we should
+ invalidate the transfer table field and free previously allocated values.
+ In the other case there's nothing to do, additional tf entries won't harm
+ and properly written code will just ignore them since spp - es < 1.
+
+ For instance this situation might happen when reading an OJPEG compressed
+ image with missing SamplesPerPixel tag. In this case the SamplesPerPixel
+ field might be updated after setting the transfer table.
+
+ see http://bugzilla.maptools.org/show_bug.cgi?id=2500
+
+ This commit addresses CVE-2018-19210.
+
+2018-12-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ Do not attempt to re-sync zip stream after reported data error from inflate().
+
+2018-12-07 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'resource-leaks' into 'master'
+ Fix two resource leaks
+
+ See merge request libtiff/libtiff!43
+
+2018-12-07 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'build-jbig' into 'master'
+ add jbig support to the fuzzer
+
+ See merge request libtiff/libtiff!42
+
+2018-12-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ tiffcrop.c: Avoid new clang warning about tools/tiffcrop.c "size argument in 'strncat' call appears to be size of the source".
+
+2018-11-28 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'webp_memleak' into 'master'
+ fixed mem leak in webp compression
+
+ See merge request libtiff/libtiff!48
+
+2018-11-28 Norman Barker <norman.barker@mapbox.com>
+
+ fixed mem leak in webp compression.
+
+2018-11-20 Even Rouault <even.rouault@spatialys.com>
+
+ Merge branch 'lossless_webp' into 'master'
+ fixed lossless webp compression config
+
+ See merge request libtiff/libtiff!46
+
+2018-11-20 Norman Barker <norman.barker@mapbox.com>
+
+ fixed lossless webp compression config.
+
+2018-11-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ snprintf porting fix for Visual Studio 2003.
+
+2018-11-18 Roger Leigh <rleigh@codelibre.net>
+
+ ci: Add pages job.
+
+2018-11-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ Change references from defunct ftp site to https site.
+
2018-11-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
* configure.ac: libtiff 4.0.10 released.
diff --git a/HOWTO-RELEASE b/HOWTO-RELEASE
index 81b4af7d..abcdc9ba 100644
--- a/HOWTO-RELEASE
+++ b/HOWTO-RELEASE
@@ -1,4 +1,4 @@
-HOWTO-RELEASE:
+HOWTO-RELEASE:
Notes on releasing.
@@ -22,17 +22,30 @@ Notes on releasing.
and correctly set system clock and on a filesystem which accurately
records file update times. Use of GNU make is recommended.
-1. Commit any unsaved changes.
+1. Commit any unsaved changes.
-2. Create html/vX.X.html and add it to git with 'git add html/vX.X.html'.
- Take ChangeLog entries and html-ify in there.
+2. Use gnulib's gitlog-to-changelog script to add new (since the last
+ release) entries to the traditional ChangeLog file. Take note of
+ the most recent change note time stamp and use that as the starting
+ point. Concatenate the old logs to the new logs. The added logs
+ may be used to help produce the release notes (in next step). For
+ example:
+
+ gitlog-to-changelog --since=`head -n 1 ChangeLog | sed -e 's/ .*//g'` --append-dot > ChangeLog.added
+ printf "\n" >> ChangeLog.added
+ cat ChangeLog.added ChangeLog > ChangeLog.new
+ mv ChangeLog.new ChangeLog
+ rm ChangeLog.added
+
+3. Create html/vX.X.html and add it to git with 'git add html/vX.X.html'.
+ Take ChangeLog entries and html-ify in there.
Easist thing to do is take html/vX.(X-1).html and use it as a template.
-3. Add vX.X.html file to the list of 'docfiles' files in the html/Makefile.am.
+4. Add vX.X.html file to the list of 'docfiles' files in the html/Makefile.am.
-4. Update html/index.html to refer to this new page as the current release.
+5. Update html/index.html to refer to this new page as the current release.
-5. Increment the release version in configure.ac. Put 'alpha' or
+6. Increment the release version in configure.ac. Put 'alpha' or
'beta' after the version, if applicable. For example:
4.0.0
@@ -42,7 +55,7 @@ Notes on releasing.
Version should be updated in two places: in the second argument of the
AC_INIT macro and in LIBTIFF_xxx_VERSION variables.
-6. Update library ELF versioning in configure.ac (LIBTIFF_CURRENT,
+7. Update library ELF versioning in configure.ac (LIBTIFF_CURRENT,
LIBTIFF_REVISION, and LIBTIFF_AGE). These numbers have nothing to
do with the libtiff release version numbers.
@@ -53,11 +66,11 @@ Notes on releasing.
have been added, removed, or interface structures have changed,
then more care is required.
-7. Add an entry to Changelog similar to:
+8. Add an entry to Changelog similar to:
* libtiff 4.0.0 released.
-8. In the source tree do
+9. In the source tree do
./autogen.sh
@@ -65,7 +78,7 @@ Notes on releasing.
maintainer build with current autoconf, automake, and libtool
packages. It is only needed when updating tool versions.
-9. It is recommended (but not required) to build outside of the source
+10. It is recommended (but not required) to build outside of the source
tree so that the source tree is kept in a pristine state. This
also allows sharing the source directory on several networked
systems. For example:
@@ -78,17 +91,17 @@ Notes on releasing.
./configure --enable-maintainer-mode
-10. In the build tree do
+11. In the build tree do
make release
This will update "RELEASE-DATE", "VERSION", and libtiff/tiffvers.h
in the source tree.
-11. In the source tree, verify that the version info in RELEASE-DATE,
+12. In the source tree, verify that the version info in RELEASE-DATE,
VERSION and libtiff/tiffvers.h is right.
-12. In the build tree do
+13. In the build tree do
make
make distcheck
@@ -99,11 +112,11 @@ Notes on releasing.
Two files with names tiff-version.tar.gz and tiff-version.zip will
be created in the top level build directory.
-13. In the source tree do
+14. In the source tree do
'git status', 'git add .', 'git commit' and 'git push'
-14. In the source tree, create a signed tag
+15. In the source tree, create a signed tag
git tag -s v4.0.0 -m "Create tag for v4.0.0"
@@ -113,7 +126,7 @@ Notes on releasing.
git push origin v4.0.0
-15. Sign the release files in the build tree using your private key
+16. Sign the release files in the build tree using your private key
export GPG_TTY=$(tty)
for file in tiff-*.tar.gz tiff-*.zip ; do \
@@ -124,11 +137,10 @@ Notes on releasing.
gpg2 --verify ${file}.sig $file ; \
done
-16. Copy release packages from the build tree to the
+17. Copy release packages from the build tree to the
ftp.remotesensing.org ftp site.
scp tiff-*.tar.gz tiff-*.zip \
- bfriesen@upload.osgeo.org:/osgeo/download/libtiff
-
-17. Announce to list, tiff@lists.maptools.org
+ bfriesen@upload.osgeo.org:/osgeo/download/libtiff
+18. Announce to list, tiff@lists.maptools.org
diff --git a/Makefile.vc b/Makefile.vc
index 6e66c730..eeb5d04d 100644
--- a/Makefile.vc
+++ b/Makefile.vc
@@ -31,6 +31,9 @@
all: port lib tools
port::
+ cd libtiff
+ $(MAKE) /f Makefile.vc tif_config.h
+ cd..
cd port
$(MAKE) /f Makefile.vc
cd..
diff --git a/README.md b/README.md
index 13dac751..2573dab1 100644
--- a/README.md
+++ b/README.md
@@ -32,8 +32,11 @@ Source code repository
Bug database
------------
-[Bugzilla](http://bugzilla.maptools.org/buglist.cgi?product=libtiff)
+[GitLab issues](https://gitlab.com/libtiff/libtiff/issues)
+Previously, the project used
+[Bugzilla](http://bugzilla.maptools.org/buglist.cgi?product=libtiff). This
+is no longer in use, and all remaining issues have been migrated to GitLab.
Use and Copyright
-----------------
diff --git a/RELEASE-DATE b/RELEASE-DATE
index 94d1f0c1..ad4fa62a 100644
--- a/RELEASE-DATE
+++ b/RELEASE-DATE
@@ -1 +1 @@
-20181110
+20191103
diff --git a/VERSION b/VERSION
index 2d2d6810..ee74734a 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-4.0.10
+4.1.0
diff --git a/build/gitlab-ci b/build/gitlab-ci
index 1612cf5f..e7306268 100644
--- a/build/gitlab-ci
+++ b/build/gitlab-ci
@@ -20,7 +20,7 @@ autoconf_build()
make distcheck
}
-# Test autoconf build
+# Test cmake build
cmake_build()
{
PATH="$(pwd)/tools/bin:$PATH"
diff --git a/configure.ac b/configure.ac
index c7b02e25..eecb8e99 100644
--- a/configure.ac
+++ b/configure.ac
@@ -25,7 +25,7 @@ dnl OF THIS SOFTWARE.
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.64)
-AC_INIT([LibTIFF Software],[4.0.10],[tiff@lists.maptools.org],[tiff])
+AC_INIT([LibTIFF Software],[4.1.0],[tiff@lists.maptools.org],[tiff])
AC_CONFIG_AUX_DIR(config)
AC_CONFIG_MACRO_DIR(m4)
AC_LANG(C)
@@ -40,8 +40,8 @@ AM_MAINTAINER_MODE
dnl Versioning.
dnl Don't fill the ALPHA_VERSION field, if not applicable.
LIBTIFF_MAJOR_VERSION=4
-LIBTIFF_MINOR_VERSION=0
-LIBTIFF_MICRO_VERSION=10
+LIBTIFF_MINOR_VERSION=1
+LIBTIFF_MICRO_VERSION=0
LIBTIFF_ALPHA_VERSION=
LIBTIFF_VERSION=$LIBTIFF_MAJOR_VERSION.$LIBTIFF_MINOR_VERSION.$LIBTIFF_MICRO_VERSION$LIBTIFF_ALPHA_VERSION
dnl This will be used with the 'make release' target
@@ -76,9 +76,9 @@ dnl 5. If any interfaces have been added since the last public release, then
dnl increment age.
dnl 6. If any interfaces have been removed since the last public release,
dnl then set age to 0.
-LIBTIFF_CURRENT=9
+LIBTIFF_CURRENT=10
LIBTIFF_REVISION=0
-LIBTIFF_AGE=4
+LIBTIFF_AGE=5
LIBTIFF_VERSION_INFO=$LIBTIFF_CURRENT:$LIBTIFF_REVISION:$LIBTIFF_AGE
# This is a special hack for OpenBSD and MirOS systems. The dynamic linker
@@ -365,15 +365,15 @@ AC_DEFINE_UNQUOTED([TIFF_SIZE_FORMAT],[$SIZE_FORMAT],[Size type formatter])
AC_MSG_CHECKING(for signed size type)
SSIZE_T='unknown'
SSIZE_FORMAT='unknown'
-if test $ac_cv_sizeof_signed_int -eq $ac_cv_sizeof_unsigned_char_p
+if test $ac_cv_sizeof_signed_int -eq $ac_cv_sizeof_size_t
then
SSIZE_T='signed int'
SSIZE_FORMAT='"%d"'
-elif test $ac_cv_sizeof_signed_long -eq $ac_cv_sizeof_unsigned_char_p
+elif test $ac_cv_sizeof_signed_long -eq $ac_cv_sizeof_size_t
then
SSIZE_T='signed long'
SSIZE_FORMAT='"%ld"'
-elif test $ac_cv_sizeof_signed_long_long -eq $ac_cv_sizeof_unsigned_char_p
+elif test $ac_cv_sizeof_signed_long_long -eq $ac_cv_sizeof_size_t
then
SSIZE_T='signed long long'
case "${host_os}" in
@@ -1070,17 +1070,16 @@ fi
dnl ---------------------------------------------------------------------------
dnl Should we try to defer loading of strip/tile offsets and sizes to
-dnl optimize directory scanning? These is an experimental feature for
-dnl libtiff 4.0.
+dnl optimize directory scanning?
dnl ---------------------------------------------------------------------------
AC_ARG_ENABLE(defer-strile-load,
AS_HELP_STRING([--enable-defer-strile-load],
- [enable deferred strip/tile offset/size loading (experimental)]),
+ [enable deferred strip/tile offset/size loading (also available at runtime with the 'D' flag of TIFFOpen()]),
[HAVE_DEFER_STRILE_LOAD=$enableval], [HAVE_DEFER_STRILE_LOAD=no])
if test "$HAVE_DEFER_STRILE_LOAD" = "yes" ; then
- AC_DEFINE(DEFER_STRILE_LOAD,1,[enable deferred strip/tile offset/size loading (experimental)])
+ AC_DEFINE(DEFER_STRILE_LOAD,1,[enable deferred strip/tile offset/size loading])
fi
diff --git a/contrib/oss-fuzz/build.sh b/contrib/oss-fuzz/build.sh
index ccac210c..ab824398 100755
--- a/contrib/oss-fuzz/build.sh
+++ b/contrib/oss-fuzz/build.sh
@@ -37,19 +37,38 @@ popd
# Build libjbig
pushd "$SRC/jbigkit"
-make lib
+if [ "$ARCHITECTURE" = "i386" ]; then
+ echo "#!/bin/bash" > gcc
+ echo "clang -m32 \$*" >> gcc
+ chmod +x gcc
+ PATH=$PWD:$PATH make lib
+else
+ make lib
+fi
+
mv "$SRC"/jbigkit/libjbig/*.a "$WORK/lib/"
mv "$SRC"/jbigkit/libjbig/*.h "$WORK/include/"
popd
+if [ "$ARCHITECTURE" != "i386" ]; then
+ apt-get install -y liblzma-dev
+fi
+
cmake . -DCMAKE_INSTALL_PREFIX=$WORK -DBUILD_SHARED_LIBS=off
make -j$(nproc)
make install
-$CXX $CXXFLAGS -std=c++11 -I$WORK/include \
- $SRC/libtiff/contrib/oss-fuzz/tiff_read_rgba_fuzzer.cc -o $OUT/tiff_read_rgba_fuzzer \
- -lFuzzingEngine $WORK/lib/libtiffxx.a $WORK/lib/libtiff.a $WORK/lib/libz.a $WORK/lib/libjpeg.a \
- $WORK/lib/libjbig.a $WORK/lib/libjbig85.a
+if [ "$ARCHITECTURE" = "i386" ]; then
+ $CXX $CXXFLAGS -std=c++11 -I$WORK/include \
+ $SRC/libtiff/contrib/oss-fuzz/tiff_read_rgba_fuzzer.cc -o $OUT/tiff_read_rgba_fuzzer \
+ $LIB_FUZZING_ENGINE $WORK/lib/libtiffxx.a $WORK/lib/libtiff.a $WORK/lib/libz.a $WORK/lib/libjpeg.a \
+ $WORK/lib/libjbig.a $WORK/lib/libjbig85.a
+else
+ $CXX $CXXFLAGS -std=c++11 -I$WORK/include \
+ $SRC/libtiff/contrib/oss-fuzz/tiff_read_rgba_fuzzer.cc -o $OUT/tiff_read_rgba_fuzzer \
+ $LIB_FUZZING_ENGINE $WORK/lib/libtiffxx.a $WORK/lib/libtiff.a $WORK/lib/libz.a $WORK/lib/libjpeg.a \
+ $WORK/lib/libjbig.a $WORK/lib/libjbig85.a -Wl,-Bstatic -llzma -Wl,-Bdynamic
+fi
mkdir afl_testcases
(cd afl_testcases; tar xf "$SRC/afl_testcases.tgz")
diff --git a/contrib/oss-fuzz/tiff_read_rgba_fuzzer.cc b/contrib/oss-fuzz/tiff_read_rgba_fuzzer.cc
index b1b189f8..dd17b5d8 100644
--- a/contrib/oss-fuzz/tiff_read_rgba_fuzzer.cc
+++ b/contrib/oss-fuzz/tiff_read_rgba_fuzzer.cc
@@ -22,6 +22,8 @@
*/
#include <cstdint>
+#include <cstdlib>
+#include <cstring>
#include <sstream>
#include <tiffio.h>
#include <tiffio.hxx>
@@ -38,8 +40,18 @@ extern "C" void handle_error(const char *unused, const char *unused2, va_list un
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+#ifndef STANDALONE
TIFFSetErrorHandler(handle_error);
TIFFSetWarningHandler(handle_error);
+#endif
+#if defined(__has_feature)
+# if __has_feature(memory_sanitizer)
+ // libjpeg-turbo has issues with MSAN and SIMD code
+ // See https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=7547
+ // and https://github.com/libjpeg-turbo/libjpeg-turbo/pull/365
+ setenv("JSIMD_FORCENONE" ,"1", 1);
+# endif
+#endif
std::istringstream s(std::string(Data,Data+Size));
TIFF* tif = TIFFStreamOpen("MemTIFF", &s);
if (!tif) {
@@ -86,3 +98,82 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
return 0;
}
+
+#ifdef STANDALONE
+
+template<class T> static void CPL_IGNORE_RET_VAL(T) {}
+
+static void Usage(int, char* argv[])
+{
+ fprintf(stderr, "%s [--help] [-repeat N] filename.\n", argv[0]);
+ exit(1);
+}
+
+int main(int argc, char* argv[])
+{
+ int nRet = 0;
+ void* buf = NULL;
+ int nLen = 0;
+ int nLoops = 1;
+ const char* pszFilename = NULL;
+
+ for(int i = 1; i < argc; i++ )
+ {
+ if( i + 1 < argc && strcmp(argv[i], "-repeat") == 0 )
+ {
+ nLoops = atoi(argv[i+1]);
+ i++;
+ }
+ else if( strcmp(argv[i], "-dummy") == 0 )
+ {
+ uint8_t dummy = ' ';
+ return LLVMFuzzerTestOneInput(&dummy, 1);
+ }
+ else if( strcmp(argv[i], "--help") == 0 )
+ {
+ Usage(argc, argv);
+ }
+ else if( argv[i][0] == '-' )
+ {
+ fprintf(stderr, "Unrecognized option: %s", argv[i]);
+ Usage(argc, argv);
+ }
+ else
+ {
+ pszFilename = argv[i];
+ }
+ }
+ if( pszFilename == nullptr )
+ {
+ fprintf(stderr, "No filename specified\n");
+ Usage(argc, argv);
+ }
+ FILE* f = fopen(pszFilename, "rb");
+ if( !f )
+ {
+ fprintf(stderr, "%s does not exist.\n", pszFilename);
+ exit(1);
+ }
+ fseek(f, 0, SEEK_END);
+ nLen = (int)ftell(f);
+ fseek(f, 0, SEEK_SET);
+ buf = malloc(nLen);
+ if( !buf )
+ {
+ fprintf(stderr, "malloc failed.\n");
+ fclose(f);
+ exit(1);
+ }
+ CPL_IGNORE_RET_VAL(fread(buf, nLen, 1, f));
+ fclose(f);
+ for( int i = 0; i < nLoops; i++ )
+ {
+ nRet = LLVMFuzzerTestOneInput(static_cast<const uint8_t*>(buf), nLen);
+ if( nRet != 0 )
+ break;
+ }
+ free(buf);
+ return nRet;
+}
+
+#endif
diff --git a/html/Makefile.am b/html/Makefile.am
index c3ef8456..10b419b2 100644
--- a/html/Makefile.am
+++ b/html/Makefile.am
@@ -87,7 +87,8 @@ docfiles = \
v4.0.7.html \
v4.0.8.html \
v4.0.9.html \
- v4.0.10.html
+ v4.0.10.html \
+ v4.1.0.html
dist_doc_DATA = $(docfiles)
diff --git a/html/bigtiffpr.html b/html/bigtiffpr.html
index c7d771b0..b7a36c6b 100644
--- a/html/bigtiffpr.html
+++ b/html/bigtiffpr.html
@@ -8,7 +8,7 @@
<body lang="en" text="#000000" bgcolor="#ffffff" link="#0000ff" alink="#0000ff" vlink="#0000ff">
<h1>Extending LibTiff library with support for the new BigTIFF format</h1>
<p>
- <a href="http://www.simplesystems.org/libtiff//">LibTiff</a> maintainers have started work on LibTiff 4.0,
+ <a href=".">LibTiff</a> maintainers have started work on LibTiff 4.0,
the next major upgrade of the time-proven <a href="http://www.awaresystems.be/imaging/tiff.html">TIFF</a>
codec. This upgrade will include support for the new BigTIFF file format. It is planned a preliminary
version (LibTiff 4.0alpha1) will be operational by June 15, 2007. Testing and final release improvements
@@ -32,7 +32,7 @@
The LibTiff BigTIFF upgrade is made possible by four sponsors funding the project. The programming work will
primarily be done by <a href="http://www.awaresystems.be/index.html">Joris Van Damme (AWare Systems)</a>.
LibTiff's licensing agreement will remain unchanged. More details on the project itself, are available from
- the <a href="http://www.simplesystems.org/libtiff//BigTIFFProposal.html">BigTIFF in LibTiff project page</a>.
+ the <a href="BigTIFFProposal.html">BigTIFF in LibTiff project page</a>.
</p>
<p>
The sponsors are, in alphabetical order:
@@ -74,4 +74,4 @@
</tbody>
</table>
</body>
-</html> \ No newline at end of file
+</html>
diff --git a/html/bugs.html b/html/bugs.html
index 643c3c6e..bc27955e 100644
--- a/html/bugs.html
+++ b/html/bugs.html
@@ -14,19 +14,20 @@ This software is free. Please let us know when you find a problem or
fix a bug.
<P>
-Thanks to <A HREF=http://www.maptools.org/>MapTools.org</a>, libtiff now uses
-bugzilla to track bugs. All bugs filed in the older bugzilla at
+The project is using <a href="https://gitlab.com/libtiff/libtiff/issues">
+GitLab issues</a> since October 2019.
+Previously, the project used MapTools.org
+bugzilla to track bugs: remaining tickets in that bugzilla instance have been
+migrated to GitLab issues. All bugs filed in a older bugzilla at
bugzilla.remotesensing.org (pre April 2008) have unfortunately been lost.
<P>
If you think you've discovered a bug, please first check to see if it is
-already known by looking at the list of already reported bugs. You can do so
-by visiting the buglist at
-<A HREF=http://bugzilla.maptools.org/buglist.cgi?product=libtiff>http://bugzilla.maptools.org/buglist.cgi?product=libtiff</A>. Also verify that
+already known by looking at the list of already reported bugs. Also verify that
the problem is still reproducible with the current development software
from CVS.
<P>
If you'd like to enter a new bug, you can do so at
-<A HREF=http://bugzilla.maptools.org/enter_bug.cgi?product=libtiff>http://bugzilla.maptools.org/enter_bug.cgi?product=libtiff</A>.
+<A HREF=https://gitlab.com/libtiff/libtiff/issues/new>https://gitlab.com/libtiff/libtiff/issues/new</A>.
<P>
If you'd like to inform us about some kind of security issue that should not
be disclosed for a period of time, then you can contact maintainers directly.
@@ -37,12 +38,12 @@ Bob Friesenhahn
<P>
Of course, reporting bugs is no substitute for discussion. The
-<a href="mailto:tiff@lists.maptools.org">tiff@lists.maptools.org</a> mailing
+<a href="mailto:tiff@lists.osgeo.org">tiff@lists.osgeo.org</a> mailing
list is for users of this software, and discussion TIFF issues in general.
It is managed with the Mailman software, and the web interface for subscribing
and managing your access to the list is at:<p>
- <a href="http://lists.maptools.org/mailman/listinfo/tiff">http://lists.maptools.org/mailman/listinfo/tiff</a><P>
+ <a href="http://lists.osgeo.org/mailman/listinfo/tiff">http://lists.osgeo.org/mailman/listinfo/tiff</a><P>
Posts to the list are only accepted from members of the list in order
to limit the amount of spam propagated.<p>
@@ -56,6 +57,6 @@ Systems</a>. <p>
<HR>
-Last updated: $Date: 2016-04-08 02:34:03 $
+Last updated: 2019-10-01
</BODY>
</HTML>
diff --git a/html/index.html b/html/index.html
index 8e12c2f1..dca511e7 100644
--- a/html/index.html
+++ b/html/index.html
@@ -20,11 +20,15 @@
</tr>
<tr>
<th>Home Page #2</th>
+ <td><a href="https://libtiff.gitlab.io/libtiff/" title="Mirror of the LibTIFF software">https://libtiff.gitlab.io/libtiff/</a></td>
+ </tr>
+ <tr>
+ <th>Home Page #3</th>
<td><a href="http://libtiff.maptools.org/" title="Mirror of the LibTIFF software">http://libtiff.maptools.org/</a></td>
</tr>
<tr>
<th>Latest Stable Release</th>
- <td><a href="v4.0.10.html">v4.0.10</a></td>
+ <td><a href="v4.1.0.html">v4.1.0</a></td>
</tr>
<tr>
<th>Master Download Site</th>
@@ -32,8 +36,8 @@
</tr>
<tr>
<th>Mailing List</th>
- <td><a href="mailto:tiff@lists.maptools.org">tiff@lists.maptools.org</a>,
- <a href="http://lists.maptools.org/mailman/listinfo/tiff/">Subscription</a>,
+ <td><a href="mailto:tiff@lists.osgeo.org">tiff@lists.osgeo.org</a>,
+ <a href="http://lists.osgeo.org/mailman/listinfo/tiff/">Subscription</a>,
<a href="http://www.awaresystems.be/imaging/tiff/tml.html">Archive</a>.
Please, read the <a href="http://www.awaresystems.be/imaging/tiff/faq.html">TIFF FAQ</a>
before asking questions.</td>
@@ -70,9 +74,9 @@
</p>
<p>
Questions should be sent to the TIFF mailing list:
- <a href="mailto:tiff@lists.maptools.org">tiff@lists.maptools.org</a>, with
+ <a href="mailto:tiff@lists.osgeo.org">tiff@lists.osgeo.org</a>, with
a subscription interface at
- <a href="http://lists.maptools.org/mailman/listinfo/tiff">http://lists.maptools.org/mailman/listinfo/tiff</a>.
+ <a href="http://lists.osgeo.org/mailman/listinfo/tiff">http://lists.osgeo.org/mailman/listinfo/tiff</a>.
</p>
<p>
The persons currently actively maintaining and releasing libtiff
@@ -96,7 +100,7 @@
<li><a href="contrib.html">Contributed software</a></li>
<li><a href="document.html">TIFF documentation</a></li>
<li><a href="build.html">Building the software distribution</a></li>
- <li><a href="bugs.html">Bugs, Bugzilla, and the TIFF mailing list</a></li>
+ <li><a href="bugs.html">Bugs, GitLab issues, and the TIFF mailing list</a></li>
<li><a href="images.html">Test images</a></li>
<li><a href="misc.html">Acknowledgements and copyright issues</a></li>
<li><a href="man/index.html">Man Pages</a></li>
@@ -110,7 +114,7 @@
</ul>
<hr>
<p>
- Last updated 2017-11-30
+ Last updated 2019-11-03
</p>
</body>
</html>
diff --git a/html/libtiff.html b/html/libtiff.html
index 9da85e3d..d6b5eab3 100644
--- a/html/libtiff.html
+++ b/html/libtiff.html
@@ -45,8 +45,8 @@
to the capabilities of the library; it is not an attempt to describe
everything a developer needs to know about the library or about TIFF.
Detailed information on the interfaces to the library are given in
- the <a href="http://www.simplesystems.org/libtiff/man/index.html">UNIX
- manual pages</a> that accompany this software.
+ the <a href="man/index.html">UNIX manual pages</a> that accompany
+ this software.
</p>
<p>
Michael Still has also written a useful introduction to libtiff for the
@@ -518,9 +518,9 @@
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &amp;imagelength);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf = _TIFFmalloc(TIFFScanlineSize(tif));<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (row = 0; row &lt; imagelength; row++)<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiffreadscanline(tif, buf, row);<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_tifffree(buf);<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiffclose(tif);<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFReadScanline(tif, buf, row, 0);<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_TIFFfree(buf);<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFClose(tif);<br>
&nbsp;&nbsp;&nbsp;&nbsp;}<br>
}</tt>
</p>
@@ -547,17 +547,17 @@
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf = _TIFFmalloc(TIFFScanlineSize(tif));<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (config == PLANARCONFIG_CONTIG) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (row = 0; row &lt; imagelength; row++)<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiffreadscanline(tif, buf, row);<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFReadScanline(tif, buf, row, 0);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else if (config == planarconfig_separate) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint16 s, nsamples;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiffgetfield(tif, tifftag_samplesperpixel, &amp;nsamples);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (s = 0; s &lt; nsamples; s++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (row = 0; row &lt; imagelength; row++)<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiffreadscanline(tif, buf, row, s);<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFReadScanline(tif, buf, row, s);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_tifffree(buf);<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiffclose(tif);<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_TIFFfree(buf);<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFClose(tif);<br>
&nbsp;&nbsp;&nbsp;&nbsp;}<br>
}</tt>
</p>
@@ -568,7 +568,7 @@
<p style="margin-left: 40px">
<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (row = 0; row &lt; imagelength; row++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (s = 0; s &lt; nsamples; s++)<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiffreadscanline(tif, buf, row, s);</tt>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFReadScanline(tif, buf, row, s);</tt>
</p>
<p>
...then problems would arise if <tt>RowsPerStrip</tt> was not one
@@ -601,8 +601,8 @@
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf = _TIFFmalloc(TIFFStripSize(tif));<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (strip = 0; strip &lt; tiffnumberofstrips(tif); strip++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiffreadencodedstrip(tif, strip, buf, (tsize_t) -1);<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_tifffree(buf);<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiffclose(tif);<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_TIFFfree(buf);<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFClose(tif);<br>
&nbsp;&nbsp;&nbsp;&nbsp;}<br>
}</tt>
</p>
@@ -702,8 +702,8 @@
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (y = 0; y &lt; imagelength; y += tilelength)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (x = 0; x &lt; imagewidth; x += tilewidth)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiffreadtile(tif, buf, x, y, 0);<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_tifffree(buf);<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiffclose(tif);<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_TIFFfree(buf);<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFClose(tif);<br>
&nbsp;&nbsp;&nbsp;&nbsp;}<br>
}</tt>
</p>
@@ -729,8 +729,8 @@
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf = _TIFFmalloc(TIFFTileSize(tif));<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (tile = 0; tile &lt; tiffnumberoftiles(tif); tile++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiffreadencodedtile(tif, tile, buf, (tsize_t) -1);<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_tifffree(buf);<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiffclose(tif);<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_TIFFfree(buf);<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFClose(tif);<br>
&nbsp;&nbsp;&nbsp;&nbsp;}<br>
}</tt>
</p>
diff --git a/html/v3.5.6-beta.html b/html/v3.5.6-beta.html
index 59198b4c..498cc439 100644
--- a/html/v3.5.6-beta.html
+++ b/html/v3.5.6-beta.html
@@ -112,7 +112,7 @@ The following information is located here:
<LI> Modified tiffio.h logic with regard to including windows.h. It
won't include it when building with __CYGWIN__.
- <LI> README: update to mention www.libtiff.org, don't list Sam's old
+ <LI> README: update to mention {REDACTED - defunct web site}, don't list Sam's old
email address.
<LI> libtiff/tif_dirread.c: Don't use estimate strip byte count for
diff --git a/html/v4.1.0.html b/html/v4.1.0.html
new file mode 100644
index 00000000..7c61fac7
--- /dev/null
+++ b/html/v4.1.0.html
@@ -0,0 +1,198 @@
+<HTML>
+<HEAD>
+<TITLE>
+ Changes in TIFF v4.1.0
+</TITLE>
+<STYLE>
+table, th, td {
+ border: 1px solid black;
+ border-collapse: collapse;
+}
+th, td {
+ padding: 8pt;
+ text-align: center;
+}
+th {
+ text-align: center;
+}
+td {
+ text-align: center;
+}
+
+ul li {
+ padding: 3pt;
+}
+
+ul.a {
+ list-style-type: circle;
+}
+
+ul.b {
+ list-style-type: square;
+}
+
+ol.c {
+ list-style-type: upper-roman;
+}
+
+ol.d {
+ list-style-type: lower-alpha;
+}
+
+</STYLE>
+</HEAD>
+
+<BODY BGCOLOR=white>
+<FONT FACE="Helvetica, Arial, Sans">
+
+<BASEFONT SIZE=4>
+<B><FONT SIZE=+3>T</FONT>IFF <FONT SIZE=+2>C</FONT>HANGE <FONT SIZE=+2>I</FONT>NFORMATION</B>
+<BASEFONT SIZE=3>
+
+<UL>
+<HR SIZE=4 WIDTH=65% ALIGN=left>
+<B>Current Version</B>: v4.1.0<BR>
+<B>Previous Version</B>: <A HREF=v4.0.10.html>v4.0.10</a><BR>
+<B>Master Download Site</B>: <A HREF="https://download.osgeo.org/libtiff">
+download.osgeo.org</a>, directory pub/libtiff</A><BR>
+<B>Master HTTP Site #1</B>: <A HREF="http://www.simplesystems.org/libtiff/">
+http://www.simplesystems.org/libtiff/</a><BR>
+<B>Master HTTP Site #2</B>: <A HREF="http://libtiff.maptools.org/">
+http://libtiff.maptools.org/</a>
+<HR SIZE=4 WIDTH=65% ALIGN=left>
+</UL>
+
+<P>
+This document describes the changes made to the software between the
+<I>previous</I> and <I>current</I> versions (see above). If you don't
+find something listed here, then it was not done in this timeframe, or
+it was not considered important enough to be mentioned. The following
+information is located here. A change summary is also provided by the
+ChangeLog file included in the release package and by the Git commit
+history:
+<UL>
+<LI><A HREF="#highlights">Major Changes</A>
+<LI><A HREF="#configure">Changes in the software configuration</A>
+<LI><A HREF="#libtiff">Changes in libtiff</A>
+<LI><A HREF="#tools">Changes in the tools</A>
+<LI><A HREF="#contrib">Changes in the contrib area</A>
+</UL>
+<p>
+<P><HR WIDTH=65% ALIGN=left>
+
+<!--------------------------------------------------------------------------->
+
+<A NAME="highlights"><B><FONT SIZE=+3>M</FONT>AJOR CHANGES:</B></A>
+
+<UL>
+
+ <LI>Make defer strile offset/bytecount loading available at runtime
+ and add per-strile offset/bytecount loading capabilities. Part of
+ this commit makes the behaviour that was previously met when libtiff
+ was compiled with -DDEFER_STRILE_LOAD available for default builds
+ when specifying the new 'D' (Deferred) TIFFOpen() flag. In that
+ mode, the [Tile/Strip][ByteCounts/Offsets] arrays are only loaded
+ when first accessed. This can speed-up the opening of files stored
+ on the network when just metadata retrieval is needed.
+
+ Another addition is the capability of loading only the values of
+ the offset/bytecount of the strile of interest instead of the
+ whole array. This is enabled with the new 'O' (Ondemand) flag of
+ TIFFOpen() (which implies 'D').
+
+ The public TIFFGetStrileOffset[WithErr]() and
+ TIFFGetStrileByteCount[WithErr]() functions have been added to
+ API. They are of particular interest when using sparse files (with
+ offset == bytecount == 0) and you want to detect if a strile is
+ present or not without decompressing the data, or updating an
+ existing sparse file.
+ </LI>
+
+ <LI>The BigTIFF writer now optimizes file size by using 32-bit LONG
+ values (rather than 64-bit) where it is reasonable and safe to do
+ so. Likewise, the 16-bit SHORT type is used when possible for
+ StripByteCounts/TileByteCounts.
+ </LI>
+
+</UL>
+
+
+<P><HR WIDTH=65% ALIGN=left>
+<!--------------------------------------------------------------------------->
+
+<A NAME="configure"><B><FONT SIZE=+3>C</FONT>HANGES IN THE SOFTWARE CONFIGURATION:</B></A>
+
+<UL>
+
+ <LI>The WIN32 build now uses tif_win32.c when building with CMake.</LI>
+
+ <LI>Properly set value of HOST_FILLORDER to LSB2MSB for Windows
+ CMake builds. It was not being properly set!</LI>
+
+</UL>
+
+<P><HR WIDTH=65% ALIGN=left>
+
+<!--------------------------------------------------------------------------->
+
+<A NAME="libtiff"><B><FONT SIZE=+3>C</FONT>HANGES IN LIBTIFF:</B></A>
+
+<UL>
+
+ <LI>
+ Changes in the libtiff library may be viewed on-line
+ at <A HREF="https://gitlab.com/libtiff/libtiff/commits/master/libtiff">Libtiff
+ Library Commits</A>.
+ </LI>
+
+ <LI>
+ New function TIFFReadFromUserBuffer() which replaces the use of
+ TIFFReadEncodedStrip()/TIFFReadEncodedTile() when the user can
+ provide the buffer for the input data, for example when he wants
+ to avoid libtiff to read the strile offset/count values from the
+ [Strip|Tile][Offsets/ByteCounts] array.
+ </LI>
+
+ <LI>
+ New functions TIFFDeferStrileArrayWriting() and TIFFForceStrileArrayWriting()
+ Those advanced writing functions must be used in a particular sequence
+ to make their intended effect. Their aim is to control when/where
+ the [Strip/Tile][Offsets/ByteCounts] arrays are written into the file.
+
+ The purpose of this is to generate 'cloud-optimized geotiff' files where
+ the first KB of the file only contain the IFD entries without the potentially
+ large strile arrays. Those are written afterwards.
+ </LI>
+
+</UL>
+
+<P><HR WIDTH=65% ALIGN=left>
+
+<!-------------------------------------------------------------------------->
+
+<A NAME="tools"><B><FONT SIZE=+3>C</FONT>HANGES IN THE TOOLS:</B></A>
+
+<UL>
+
+ <LI>Changes in the libtiff utilities may be viewed on-line
+ at <A HREF="https://gitlab.com/libtiff/libtiff/commits/master/tools">Libtiff
+ Tools Commits</A></LI>
+
+</UL>
+
+<P><HR WIDTH=65% ALIGN=left>
+
+<!--------------------------------------------------------------------------->
+
+<A NAME="contrib"><B><FONT SIZE=+3>C</FONT>HANGES IN THE CONTRIB AREA:</B></A>
+
+<UL>
+
+ <LI>Changes in the libtiff contrib area may be viewed on-line
+ at <A HREF="https://gitlab.com/libtiff/libtiff/commits/master/contrib">Libtiff
+ Contrib Commits</A></LI>
+
+</UL>
+
+</BODY>
+</HTML>
diff --git a/libtiff/CMakeLists.txt b/libtiff/CMakeLists.txt
index 1cf1b759..080685db 100644
--- a/libtiff/CMakeLists.txt
+++ b/libtiff/CMakeLists.txt
@@ -104,7 +104,7 @@ set(tiffxx_HEADERS
set(tiffxx_SOURCES
tif_stream.cxx)
-if(WIN32_IO)
+if(USE_WIN32_FILEIO)
extra_dist(tif_unix.c)
list(APPEND tiff_SOURCES tif_win32.c)
else()
diff --git a/libtiff/libtiff.def b/libtiff/libtiff.def
index 341c719d..e34fac58 100644
--- a/libtiff/libtiff.def
+++ b/libtiff/libtiff.def
@@ -20,6 +20,7 @@ EXPORTS TIFFAccessTagMethods
TIFFDataWidth
TIFFDefaultStripSize
TIFFDefaultTileSize
+ TIFFDeferStrileArrayWriting
TIFFError
TIFFErrorExt
TIFFFdOpen
@@ -37,6 +38,7 @@ EXPORTS TIFFAccessTagMethods
TIFFFindField
TIFFFlush
TIFFFlushData
+ TIFFForceStrileArrayWriting
TIFFFreeDirectory
TIFFGetBitRevTable
TIFFGetClientInfo
@@ -49,6 +51,10 @@ EXPORTS TIFFAccessTagMethods
TIFFGetReadProc
TIFFGetSeekProc
TIFFGetSizeProc
+ TIFFGetStrileByteCount
+ TIFFGetStrileByteCountWithErr
+ TIFFGetStrileOffset
+ TIFFGetStrileOffsetWithErr
TIFFGetTagListCount
TIFFGetTagListEntry
TIFFGetUnmapFileProc
@@ -82,6 +88,7 @@ EXPORTS TIFFAccessTagMethods
TIFFReadEXIFDirectory
TIFFReadEncodedStrip
TIFFReadEncodedTile
+ TIFFReadFromUserBuffer
TIFFReadRGBAImage
TIFFReadRGBAImageOriented
TIFFReadRGBAStrip
diff --git a/libtiff/mkg3states.c b/libtiff/mkg3states.c
index 54fc0599..2cb9174c 100644
--- a/libtiff/mkg3states.c
+++ b/libtiff/mkg3states.c
@@ -40,7 +40,7 @@
#include "tif_fax3.h"
#ifndef HAVE_GETOPT
-extern int getopt(int, char**, char*);
+extern int getopt(int argc, char * const argv[], const char *optstring);
#endif
#define streq(a,b) (strcmp(a,b) == 0)
diff --git a/libtiff/tif_aux.c b/libtiff/tif_aux.c
index 4ece162f..8188db53 100644
--- a/libtiff/tif_aux.c
+++ b/libtiff/tif_aux.c
@@ -30,31 +30,66 @@
#include "tiffiop.h"
#include "tif_predict.h"
#include <math.h>
+#include <float.h>
uint32
_TIFFMultiply32(TIFF* tif, uint32 first, uint32 second, const char* where)
{
- uint32 bytes = first * second;
-
- if (second && bytes / second != first) {
+ if (second && first > TIFF_UINT32_MAX / second) {
TIFFErrorExt(tif->tif_clientdata, where, "Integer overflow in %s", where);
- bytes = 0;
+ return 0;
}
- return bytes;
+ return first * second;
}
uint64
_TIFFMultiply64(TIFF* tif, uint64 first, uint64 second, const char* where)
{
- uint64 bytes = first * second;
-
- if (second && bytes / second != first) {
+ if (second && first > TIFF_UINT64_MAX / second) {
TIFFErrorExt(tif->tif_clientdata, where, "Integer overflow in %s", where);
- bytes = 0;
+ return 0;
}
- return bytes;
+ return first * second;
+}
+
+tmsize_t
+_TIFFMultiplySSize(TIFF* tif, tmsize_t first, tmsize_t second, const char* where)
+{
+ if( first <= 0 || second <= 0 )
+ {
+ if( tif != NULL && where != NULL )
+ {
+ TIFFErrorExt(tif->tif_clientdata, where,
+ "Invalid argument to _TIFFMultiplySSize() in %s", where);
+ }
+ return 0;
+ }
+
+ if( first > TIFF_TMSIZE_T_MAX / second )
+ {
+ if( tif != NULL && where != NULL )
+ {
+ TIFFErrorExt(tif->tif_clientdata, where,
+ "Integer overflow in %s", where);
+ }
+ return 0;
+ }
+ return first * second;
+}
+
+tmsize_t _TIFFCastUInt64ToSSize(TIFF* tif, uint64 val, const char* module)
+{
+ if( val > (uint64)TIFF_TMSIZE_T_MAX )
+ {
+ if( tif != NULL && module != NULL )
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
+ }
+ return 0;
+ }
+ return (tmsize_t)val;
}
void*
@@ -62,13 +97,14 @@ _TIFFCheckRealloc(TIFF* tif, void* buffer,
tmsize_t nmemb, tmsize_t elem_size, const char* what)
{
void* cp = NULL;
- tmsize_t bytes = nmemb * elem_size;
-
+ tmsize_t count = _TIFFMultiplySSize(tif, nmemb, elem_size, NULL);
/*
- * XXX: Check for integer overflow.
+ * Check for integer overflow.
*/
- if (nmemb && elem_size && bytes / elem_size == nmemb)
- cp = _TIFFrealloc(buffer, bytes);
+ if (count != 0)
+ {
+ cp = _TIFFrealloc(buffer, count);
+ }
if (cp == NULL) {
TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
@@ -357,6 +393,15 @@ _TIFFUInt64ToDouble(uint64 ui64)
}
}
+float _TIFFClampDoubleToFloat( double val )
+{
+ if( val > FLT_MAX )
+ return FLT_MAX;
+ if( val < -FLT_MAX )
+ return -FLT_MAX;
+ return (float)val;
+}
+
int _TIFFSeekOK(TIFF* tif, toff_t off)
{
/* Huge offsets, especially -1 / UINT64_MAX, can cause issues */
diff --git a/libtiff/tif_config.vc.h b/libtiff/tif_config.vc.h
index 5cebfa02..939594f8 100644
--- a/libtiff/tif_config.vc.h
+++ b/libtiff/tif_config.vc.h
@@ -104,11 +104,24 @@
/* Set the native cpu bit order */
#define HOST_FILLORDER FILLORDER_LSB2MSB
+/*
+ Please see associated settings in "nmake.opt" which configure porting
+ settings. It should not be necessary to edit the following pre-processor
+ logic.
+*/
+#if defined(_MSC_VER)
/* Visual Studio 2015 / VC 14 / MSVC 19.00 finally has snprintf() */
-#if defined(_MSC_VER) && _MSC_VER < 1900
-#define snprintf _snprintf
-#else
-#define HAVE_SNPRINTF 1
+# if _MSC_VER < 1900 /* Visual C++ 2015 */
+# define snprintf _snprintf
+# else
+# define HAVE_SNPRINTF 1
+# endif
+# define HAVE_STRTOL 1
+# define HAVE_STRTOUL 1
+# if _MSC_VER >= 1900 /* Visual Studio 2015 added strtoll/strtoull */
+# define HAVE_STRTOLL 1
+# define HAVE_STRTOULL 1
+# endif
#endif
/* Define to 1 if your processor stores words with the most significant byte
diff --git a/libtiff/tif_dir.c b/libtiff/tif_dir.c
index 6f0b4879..1e0a76c3 100644
--- a/libtiff/tif_dir.c
+++ b/libtiff/tif_dir.c
@@ -29,7 +29,6 @@
* (and also some miscellaneous stuff)
*/
#include "tiffiop.h"
-#include <float.h>
/*
* These are used in the backwards compatibility code...
@@ -47,8 +46,8 @@ setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size)
*vpp = 0;
}
if (vp) {
- tmsize_t bytes = (tmsize_t)(nmemb * elem_size);
- if (elem_size && bytes / elem_size == nmemb)
+ tmsize_t bytes = _TIFFMultiplySSize(NULL, nmemb, elem_size, NULL);
+ if (bytes)
*vpp = (void*) _TIFFmalloc(bytes);
if (*vpp)
_TIFFmemcpy(*vpp, vp, bytes);
@@ -88,13 +87,15 @@ setDoubleArrayOneValue(double** vpp, double value, size_t nmemb)
* Install extra samples information.
*/
static int
-setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v)
+setExtraSamples(TIFF* tif, va_list ap, uint32* v)
{
/* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */
#define EXTRASAMPLE_COREL_UNASSALPHA 999
uint16* va;
uint32 i;
+ TIFFDirectory* td = &tif->tif_dir;
+ static const char module[] = "setExtraSamples";
*v = (uint16) va_arg(ap, uint16_vap);
if ((uint16) *v > td->td_samplesperpixel)
@@ -116,6 +117,18 @@ setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v)
return 0;
}
}
+
+ if ( td->td_transferfunction[0] != NULL && (td->td_samplesperpixel - *v > 1) &&
+ !(td->td_samplesperpixel - td->td_extrasamples > 1))
+ {
+ TIFFWarningExt(tif->tif_clientdata,module,
+ "ExtraSamples tag value is changing, "
+ "but TransferFunction was read with a different value. Cancelling it");
+ TIFFClrFieldBit(tif,FIELD_TRANSFERFUNCTION);
+ _TIFFfree(td->td_transferfunction[0]);
+ td->td_transferfunction[0] = NULL;
+ }
+
td->td_extrasamples = (uint16) *v;
_TIFFsetShortArray(&td->td_sampleinfo, va, td->td_extrasamples);
return 1;
@@ -153,15 +166,6 @@ bad:
return (0);
}
-static float TIFFClampDoubleToFloat( double val )
-{
- if( val > FLT_MAX )
- return FLT_MAX;
- if( val < -FLT_MAX )
- return -FLT_MAX;
- return (float)val;
-}
-
static int
_TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
{
@@ -285,6 +289,18 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
_TIFFfree(td->td_smaxsamplevalue);
td->td_smaxsamplevalue = NULL;
}
+ /* Test if 3 transfer functions instead of just one are now needed
+ See http://bugzilla.maptools.org/show_bug.cgi?id=2820 */
+ if( td->td_transferfunction[0] != NULL && (v - td->td_extrasamples > 1) &&
+ !(td->td_samplesperpixel - td->td_extrasamples > 1))
+ {
+ TIFFWarningExt(tif->tif_clientdata,module,
+ "SamplesPerPixel tag value is changing, "
+ "but TransferFunction was read with a different value. Cancelling it");
+ TIFFClrFieldBit(tif,FIELD_TRANSFERFUNCTION);
+ _TIFFfree(td->td_transferfunction[0]);
+ td->td_transferfunction[0] = NULL;
+ }
}
td->td_samplesperpixel = (uint16) v;
break;
@@ -320,13 +336,13 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
dblval = va_arg(ap, double);
if( dblval < 0 )
goto badvaluedouble;
- td->td_xresolution = TIFFClampDoubleToFloat( dblval );
+ td->td_xresolution = _TIFFClampDoubleToFloat( dblval );
break;
case TIFFTAG_YRESOLUTION:
dblval = va_arg(ap, double);
if( dblval < 0 )
goto badvaluedouble;
- td->td_yresolution = TIFFClampDoubleToFloat( dblval );
+ td->td_yresolution = _TIFFClampDoubleToFloat( dblval );
break;
case TIFFTAG_PLANARCONFIG:
v = (uint16) va_arg(ap, uint16_vap);
@@ -335,10 +351,10 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
td->td_planarconfig = (uint16) v;
break;
case TIFFTAG_XPOSITION:
- td->td_xposition = TIFFClampDoubleToFloat( va_arg(ap, double) );
+ td->td_xposition = _TIFFClampDoubleToFloat( va_arg(ap, double) );
break;
case TIFFTAG_YPOSITION:
- td->td_yposition = TIFFClampDoubleToFloat( va_arg(ap, double) );
+ td->td_yposition = _TIFFClampDoubleToFloat( va_arg(ap, double) );
break;
case TIFFTAG_RESOLUTIONUNIT:
v = (uint16) va_arg(ap, uint16_vap);
@@ -361,7 +377,7 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
_TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32);
break;
case TIFFTAG_EXTRASAMPLES:
- if (!setExtraSamples(td, ap, &v))
+ if (!setExtraSamples(tif, ap, &v))
goto badvalue;
break;
case TIFFTAG_MATTEING:
@@ -684,7 +700,7 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
case TIFF_SRATIONAL:
case TIFF_FLOAT:
{
- float v2 = TIFFClampDoubleToFloat(va_arg(ap, double));
+ float v2 = _TIFFClampDoubleToFloat(va_arg(ap, double));
_TIFFmemcpy(val, &v2, tv_size);
}
break;
@@ -1002,12 +1018,12 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
case TIFFTAG_STRIPOFFSETS:
case TIFFTAG_TILEOFFSETS:
_TIFFFillStriles( tif );
- *va_arg(ap, uint64**) = td->td_stripoffset;
+ *va_arg(ap, uint64**) = td->td_stripoffset_p;
break;
case TIFFTAG_STRIPBYTECOUNTS:
case TIFFTAG_TILEBYTECOUNTS:
_TIFFFillStriles( tif );
- *va_arg(ap, uint64**) = td->td_stripbytecount;
+ *va_arg(ap, uint64**) = td->td_stripbytecount_p;
break;
case TIFFTAG_MATTEING:
*va_arg(ap, uint16*) =
@@ -1266,8 +1282,9 @@ TIFFFreeDirectory(TIFF* tif)
CleanupField(td_transferfunction[0]);
CleanupField(td_transferfunction[1]);
CleanupField(td_transferfunction[2]);
- CleanupField(td_stripoffset);
- CleanupField(td_stripbytecount);
+ CleanupField(td_stripoffset_p);
+ CleanupField(td_stripbytecount_p);
+ td->td_stripoffsetbyteallocsize = 0;
TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
@@ -1280,10 +1297,8 @@ TIFFFreeDirectory(TIFF* tif)
td->td_customValueCount = 0;
CleanupField(td_customValues);
-#if defined(DEFER_STRILE_LOAD)
_TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
_TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
-#endif
}
#undef CleanupField
@@ -1371,7 +1386,9 @@ TIFFDefaultDirectory(TIFF* tif)
td->td_tilewidth = 0;
td->td_tilelength = 0;
td->td_tiledepth = 1;
+#ifdef STRIPBYTECOUNTSORTED_UNUSED
td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */
+#endif
td->td_resolutionunit = RESUNIT_INCH;
td->td_sampleformat = SAMPLEFORMAT_UINT;
td->td_imagedepth = 1;
diff --git a/libtiff/tif_dir.h b/libtiff/tif_dir.h
index b2f5e694..e7f06673 100644
--- a/libtiff/tif_dir.h
+++ b/libtiff/tif_dir.h
@@ -58,6 +58,7 @@ typedef struct {
uint32 toff_long;
uint64 toff_long8;
} tdir_offset; /* either offset or the data itself if fits */
+ uint8 tdir_ignore; /* flag status to ignore tag when parsing tags in tif_dirread.c */
} TIFFDirEntry;
/*
@@ -97,13 +98,14 @@ typedef struct {
* number of striles */
uint32 td_stripsperimage;
uint32 td_nstrips; /* size of offset & bytecount arrays */
- uint64* td_stripoffset;
- uint64* td_stripbytecount;
+ uint64* td_stripoffset_p; /* should be accessed with TIFFGetStrileOffset */
+ uint64* td_stripbytecount_p; /* should be accessed with TIFFGetStrileByteCount */
+ uint32 td_stripoffsetbyteallocsize; /* number of elements currently allocated for td_stripoffset/td_stripbytecount. Only used if TIFF_LAZYSTRILELOAD is set */
+#ifdef STRIPBYTECOUNTSORTED_UNUSED
int td_stripbytecountsorted; /* is the bytecount array sorted ascending? */
-#if defined(DEFER_STRILE_LOAD)
+#endif
TIFFDirEntry td_stripoffset_entry; /* for deferred loading */
TIFFDirEntry td_stripbytecount_entry; /* for deferred loading */
-#endif
uint16 td_nsubifd;
uint64* td_subifd;
/* YCbCr parameters */
@@ -118,6 +120,8 @@ typedef struct {
int td_customValueCount;
TIFFTagValue *td_customValues;
+
+ unsigned char td_deferstrilearraywriting; /* see TIFFDeferStrileArrayWriting() */
} TIFFDirectory;
/*
diff --git a/libtiff/tif_dirinfo.c b/libtiff/tif_dirinfo.c
index e1f6b23e..b508040c 100644
--- a/libtiff/tif_dirinfo.c
+++ b/libtiff/tif_dirinfo.c
@@ -138,7 +138,7 @@ tiffFields[] = {
{ TIFFTAG_CFAPATTERN, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CFAPattern" , NULL},
{ TIFFTAG_COPYRIGHT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Copyright", NULL },
/* end Pixar tags */
- { TIFFTAG_RICHTIFFIPTC, -3, -3, TIFF_LONG, 0, TIFF_SETGET_C32_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "RichTIFFIPTC", NULL },
+ { TIFFTAG_RICHTIFFIPTC, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "RichTIFFIPTC", NULL },
{ TIFFTAG_PHOTOSHOP, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "Photoshop", NULL },
{ TIFFTAG_EXIFIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "EXIFIFDOffset", (TIFFFieldArray*) &exifFieldArray },
{ TIFFTAG_ICCPROFILE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ICC Profile", NULL },
diff --git a/libtiff/tif_dirread.c b/libtiff/tif_dirread.c
index e80a3b13..58f2eb53 100644
--- a/libtiff/tif_dirread.c
+++ b/libtiff/tif_dirread.c
@@ -29,9 +29,6 @@
*/
/* Suggested pending improvements:
- * - add a field 'ignore' to the TIFFDirEntry structure, to flag status,
- * eliminating current use of the IGNORE value, and therefore eliminating
- * current irrational behaviour on tags with tag id code 0
* - add a field 'field_info' to the TIFFDirEntry structure, and set that with
* the pointer to the appropriate TIFFField structure early on in
* TIFFReadDirectory, so as to eliminate current possibly repetitive lookup.
@@ -41,9 +38,13 @@
#include <float.h>
#include <stdlib.h>
-#define IGNORE 0 /* tag placeholder used below */
#define FAILED_FII ((uint32) -1)
+/*
+ * Largest 64-bit signed integer value.
+ */
+#define TIFF_INT64_MAX ((int64)(TIFF_UINT64_MAX >> 1))
+
#ifdef HAVE_IEEEFP
# define TIFFCvtIEEEFloatToNative(tif, n, fp)
# define TIFFCvtIEEEDoubleToNative(tif, n, dp)
@@ -164,6 +165,7 @@ static int TIFFFetchNormalTag(TIFF*, TIFFDirEntry*, int recover);
static int TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uint64** lpp);
static int TIFFFetchSubjectDistance(TIFF*, TIFFDirEntry*);
static void ChopUpSingleUncompressedStrip(TIFF*);
+static void TryChopUpUncompressedBigTiff(TIFF*);
static uint64 TIFFReadUInt64(const uint8 *value);
static int _TIFFGetMaxColorChannels(uint16 photometric);
@@ -205,6 +207,7 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryByte(TIFF* tif, TIFFDirEntry* di
switch (direntry->tdir_type)
{
case TIFF_BYTE:
+ case TIFF_UNDEFINED: /* Support to read TIFF_UNDEFINED with field_readcount==1 */
TIFFReadDirEntryCheckedByte(tif,direntry,value);
return(TIFFReadDirEntryErrOk);
case TIFF_SBYTE:
@@ -3287,11 +3290,6 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong(int32 value)
return(TIFFReadDirEntryErrOk);
}
-/*
- * Largest 32-bit unsigned integer value.
- */
-#define TIFF_UINT32_MAX 0xFFFFFFFFU
-
static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeLongLong8(uint64 value)
{
@@ -3310,8 +3308,6 @@ TIFFReadDirEntryCheckRangeLongSlong8(int64 value)
return(TIFFReadDirEntryErrOk);
}
-#undef TIFF_UINT32_MAX
-
static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSlongLong(uint32 value)
{
@@ -3377,11 +3373,6 @@ TIFFReadDirEntryCheckRangeLong8Slong8(int64 value)
return(TIFFReadDirEntryErrOk);
}
-/*
- * Largest 64-bit signed integer value.
- */
-#define TIFF_INT64_MAX ((int64)(((uint64) ~0) >> 1))
-
static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSlong8Long8(uint64 value)
{
@@ -3391,8 +3382,6 @@ TIFFReadDirEntryCheckRangeSlong8Long8(uint64 value)
return(TIFFReadDirEntryErrOk);
}
-#undef TIFF_INT64_MAX
-
static enum TIFFReadDirEntryErr
TIFFReadDirEntryData(TIFF* tif, uint64 offset, tmsize_t size, void* dest)
{
@@ -3405,13 +3394,13 @@ TIFFReadDirEntryData(TIFF* tif, uint64 offset, tmsize_t size, void* dest)
} else {
size_t ma,mb;
ma=(size_t)offset;
+ if( (uint64)ma!=offset ||
+ ma > (~(size_t)0) - (size_t)size )
+ {
+ return TIFFReadDirEntryErrIo;
+ }
mb=ma+size;
- if (((uint64)ma!=offset)
- || (mb < ma)
- || (mb - ma != (size_t) size)
- || (mb < (size_t)size)
- || (mb > (size_t)tif->tif_size)
- )
+ if (mb > (size_t)tif->tif_size)
return(TIFFReadDirEntryErrIo);
_TIFFmemcpy(dest,tif->tif_base+ma,size);
}
@@ -3534,6 +3523,49 @@ static int _TIFFGetMaxColorChannels( uint16 photometric )
}
}
+static int ByteCountLooksBad(TIFF* tif)
+{
+ /*
+ * Assume we have wrong StripByteCount value (in case
+ * of single strip) in following cases:
+ * - it is equal to zero along with StripOffset;
+ * - it is larger than file itself (in case of uncompressed
+ * image);
+ * - it is smaller than the size of the bytes per row
+ * multiplied on the number of rows. The last case should
+ * not be checked in the case of writing new image,
+ * because we may do not know the exact strip size
+ * until the whole image will be written and directory
+ * dumped out.
+ */
+ uint64 bytecount = TIFFGetStrileByteCount(tif, 0);
+ uint64 offset = TIFFGetStrileOffset(tif, 0);
+ uint64 filesize;
+
+ if( offset == 0 )
+ return 0;
+ if (bytecount == 0)
+ return 1;
+ if ( tif->tif_dir.td_compression != COMPRESSION_NONE )
+ return 0;
+ filesize = TIFFGetFileSize(tif);
+ if( offset <= filesize && bytecount > filesize - offset )
+ return 1;
+ if( tif->tif_mode == O_RDONLY )
+ {
+ uint64 scanlinesize = TIFFScanlineSize64(tif);
+ if( tif->tif_dir.td_imagelength > 0 &&
+ scanlinesize > TIFF_UINT64_MAX / tif->tif_dir.td_imagelength )
+ {
+ return 1;
+ }
+ if( bytecount < scanlinesize * tif->tif_dir.td_imagelength)
+ return 1;
+ }
+ return 0;
+}
+
+
/*
* Read the next TIFF directory from a file and convert it to the internal
* format. We read directories sequentially.
@@ -3580,14 +3612,17 @@ TIFFReadDirectory(TIFF* tif)
uint16 nb;
for (na=ma+1, nb=mb+1; nb<dircount; na++, nb++)
{
- if (ma->tdir_tag==na->tdir_tag)
- na->tdir_tag=IGNORE;
+ if (ma->tdir_tag == na->tdir_tag) {
+ na->tdir_ignore = TRUE;
+ }
}
}
}
tif->tif_flags &= ~TIFF_BEENWRITING; /* reset before new dir */
tif->tif_flags &= ~TIFF_BUF4WRITE; /* reset before new dir */
+ tif->tif_flags &= ~TIFF_CHOPPEDUPARRAYS;
+
/* free any old stuff and reinit */
TIFFFreeDirectory(tif);
TIFFDefaultDirectory(tif);
@@ -3620,7 +3655,7 @@ TIFFReadDirectory(TIFF* tif)
{
if (!TIFFFetchNormalTag(tif,dp,0))
goto bad;
- dp->tdir_tag=IGNORE;
+ dp->tdir_ignore = TRUE;
}
dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_COMPRESSION);
if (dp)
@@ -3643,7 +3678,7 @@ TIFFReadDirectory(TIFF* tif)
}
if (!TIFFSetField(tif,TIFFTAG_COMPRESSION,value))
goto bad;
- dp->tdir_tag=IGNORE;
+ dp->tdir_ignore = TRUE;
}
else
{
@@ -3655,7 +3690,7 @@ TIFFReadDirectory(TIFF* tif)
*/
for (di=0, dp=dir; di<dircount; di++, dp++)
{
- if (dp->tdir_tag!=IGNORE)
+ if (!dp->tdir_ignore)
{
TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
if (fii == FAILED_FII)
@@ -3663,8 +3698,8 @@ TIFFReadDirectory(TIFF* tif)
TIFFWarningExt(tif->tif_clientdata, module,
"Unknown field with tag %d (0x%x) encountered",
dp->tdir_tag,dp->tdir_tag);
- /* the following knowingly leaks the
- anonymous field structure */
+ /* the following knowingly leaks the
+ anonymous field structure */
if (!_TIFFMergeFields(tif,
_TIFFCreateAnonField(tif,
dp->tdir_tag,
@@ -3675,18 +3710,18 @@ TIFFReadDirectory(TIFF* tif)
"Registering anonymous field with tag %d (0x%x) failed",
dp->tdir_tag,
dp->tdir_tag);
- dp->tdir_tag=IGNORE;
+ dp->tdir_ignore = TRUE;
} else {
TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
assert(fii != FAILED_FII);
}
}
}
- if (dp->tdir_tag!=IGNORE)
+ if (!dp->tdir_ignore)
{
fip=tif->tif_fields[fii];
if (fip->field_bit==FIELD_IGNORE)
- dp->tdir_tag=IGNORE;
+ dp->tdir_ignore = TRUE;
else
{
switch (dp->tdir_tag)
@@ -3708,12 +3743,12 @@ TIFFReadDirectory(TIFF* tif)
case TIFFTAG_EXTRASAMPLES:
if (!TIFFFetchNormalTag(tif,dp,0))
goto bad;
- dp->tdir_tag=IGNORE;
+ dp->tdir_ignore = TRUE;
+ break;
+ default:
+ if( !_TIFFCheckFieldIsValidForCodec(tif, dp->tdir_tag) )
+ dp->tdir_ignore = TRUE;
break;
- default:
- if( !_TIFFCheckFieldIsValidForCodec(tif, dp->tdir_tag) )
- dp->tdir_tag=IGNORE;
- break;
}
}
}
@@ -3729,8 +3764,8 @@ TIFFReadDirectory(TIFF* tif)
if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG)&&
(tif->tif_dir.td_planarconfig==PLANARCONFIG_SEPARATE))
{
- if (!_TIFFFillStriles(tif))
- goto bad;
+ if (!_TIFFFillStriles(tif))
+ goto bad;
dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_STRIPOFFSETS);
if ((dp!=0)&&(dp->tdir_count==1))
{
@@ -3802,190 +3837,240 @@ TIFFReadDirectory(TIFF* tif)
*/
for (di=0, dp=dir; di<dircount; di++, dp++)
{
- switch (dp->tdir_tag)
- {
- case IGNORE:
- break;
- case TIFFTAG_MINSAMPLEVALUE:
- case TIFFTAG_MAXSAMPLEVALUE:
- case TIFFTAG_BITSPERSAMPLE:
- case TIFFTAG_DATATYPE:
- case TIFFTAG_SAMPLEFORMAT:
- /*
- * The MinSampleValue, MaxSampleValue, BitsPerSample
- * DataType and SampleFormat tags are supposed to be
- * written as one value/sample, but some vendors
- * incorrectly write one value only -- so we accept
- * that as well (yuck). Other vendors write correct
- * value for NumberOfSamples, but incorrect one for
- * BitsPerSample and friends, and we will read this
- * too.
- */
- {
- uint16 value;
- enum TIFFReadDirEntryErr err;
- err=TIFFReadDirEntryShort(tif,dp,&value);
- if (err==TIFFReadDirEntryErrCount)
- err=TIFFReadDirEntryPersampleShort(tif,dp,&value);
- if (err!=TIFFReadDirEntryErrOk)
- {
- fip = TIFFFieldWithTag(tif,dp->tdir_tag);
- TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0);
- goto bad;
- }
- if (!TIFFSetField(tif,dp->tdir_tag,value))
- goto bad;
- if( dp->tdir_tag == TIFFTAG_BITSPERSAMPLE )
- bitspersample_read = TRUE;
- }
- break;
- case TIFFTAG_SMINSAMPLEVALUE:
- case TIFFTAG_SMAXSAMPLEVALUE:
- {
-
- double *data = NULL;
- enum TIFFReadDirEntryErr err;
- uint32 saved_flags;
- int m;
- if (dp->tdir_count != (uint64)tif->tif_dir.td_samplesperpixel)
- err = TIFFReadDirEntryErrCount;
- else
- err = TIFFReadDirEntryDoubleArray(tif, dp, &data);
- if (err!=TIFFReadDirEntryErrOk)
+ if (!dp->tdir_ignore) {
+ switch (dp->tdir_tag)
+ {
+ case TIFFTAG_MINSAMPLEVALUE:
+ case TIFFTAG_MAXSAMPLEVALUE:
+ case TIFFTAG_BITSPERSAMPLE:
+ case TIFFTAG_DATATYPE:
+ case TIFFTAG_SAMPLEFORMAT:
+ /*
+ * The MinSampleValue, MaxSampleValue, BitsPerSample
+ * DataType and SampleFormat tags are supposed to be
+ * written as one value/sample, but some vendors
+ * incorrectly write one value only -- so we accept
+ * that as well (yuck). Other vendors write correct
+ * value for NumberOfSamples, but incorrect one for
+ * BitsPerSample and friends, and we will read this
+ * too.
+ */
{
- fip = TIFFFieldWithTag(tif,dp->tdir_tag);
- TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0);
- goto bad;
+ uint16 value;
+ enum TIFFReadDirEntryErr err;
+ err=TIFFReadDirEntryShort(tif,dp,&value);
+ if (err==TIFFReadDirEntryErrCount)
+ err=TIFFReadDirEntryPersampleShort(tif,dp,&value);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ fip = TIFFFieldWithTag(tif,dp->tdir_tag);
+ TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0);
+ goto bad;
+ }
+ if (!TIFFSetField(tif,dp->tdir_tag,value))
+ goto bad;
+ if( dp->tdir_tag == TIFFTAG_BITSPERSAMPLE )
+ bitspersample_read = TRUE;
}
- saved_flags = tif->tif_flags;
- tif->tif_flags |= TIFF_PERSAMPLE;
- m = TIFFSetField(tif,dp->tdir_tag,data);
- tif->tif_flags = saved_flags;
- _TIFFfree(data);
- if (!m)
- goto bad;
- }
- break;
- case TIFFTAG_STRIPOFFSETS:
- case TIFFTAG_TILEOFFSETS:
-#if defined(DEFER_STRILE_LOAD)
- _TIFFmemcpy( &(tif->tif_dir.td_stripoffset_entry),
- dp, sizeof(TIFFDirEntry) );
-#else
- if( tif->tif_dir.td_stripoffset != NULL )
- {
- TIFFErrorExt(tif->tif_clientdata, module,
- "tif->tif_dir.td_stripoffset is "
- "already allocated. Likely duplicated "
- "StripOffsets/TileOffsets tag");
- goto bad;
- }
- if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripoffset))
- goto bad;
-#endif
- break;
- case TIFFTAG_STRIPBYTECOUNTS:
- case TIFFTAG_TILEBYTECOUNTS:
-#if defined(DEFER_STRILE_LOAD)
- _TIFFmemcpy( &(tif->tif_dir.td_stripbytecount_entry),
- dp, sizeof(TIFFDirEntry) );
-#else
- if( tif->tif_dir.td_stripbytecount != NULL )
- {
- TIFFErrorExt(tif->tif_clientdata, module,
- "tif->tif_dir.td_stripbytecount is "
- "already allocated. Likely duplicated "
- "StripByteCounts/TileByteCounts tag");
- goto bad;
- }
- if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripbytecount))
- goto bad;
-#endif
- break;
- case TIFFTAG_COLORMAP:
- case TIFFTAG_TRANSFERFUNCTION:
- {
- enum TIFFReadDirEntryErr err;
- uint32 countpersample;
- uint32 countrequired;
- uint32 incrementpersample;
- uint16* value=NULL;
- /* It would be dangerous to instantiate those tag values */
- /* since if td_bitspersample has not yet been read (due to */
- /* unordered tags), it could be read afterwards with a */
- /* values greater than the default one (1), which may cause */
- /* crashes in user code */
- if( !bitspersample_read )
- {
- fip = TIFFFieldWithTag(tif,dp->tdir_tag);
- TIFFWarningExt(tif->tif_clientdata,module,
- "Ignoring %s since BitsPerSample tag not found",
- fip ? fip->field_name : "unknown tagname");
- continue;
- }
- /* ColorMap or TransferFunction for high bit */
- /* depths do not make much sense and could be */
- /* used as a denial of service vector */
- if (tif->tif_dir.td_bitspersample > 24)
+ break;
+ case TIFFTAG_SMINSAMPLEVALUE:
+ case TIFFTAG_SMAXSAMPLEVALUE:
{
- fip = TIFFFieldWithTag(tif,dp->tdir_tag);
- TIFFWarningExt(tif->tif_clientdata,module,
- "Ignoring %s because BitsPerSample=%d>24",
- fip ? fip->field_name : "unknown tagname",
- tif->tif_dir.td_bitspersample);
- continue;
+
+ double *data = NULL;
+ enum TIFFReadDirEntryErr err;
+ uint32 saved_flags;
+ int m;
+ if (dp->tdir_count != (uint64)tif->tif_dir.td_samplesperpixel)
+ err = TIFFReadDirEntryErrCount;
+ else
+ err = TIFFReadDirEntryDoubleArray(tif, dp, &data);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ fip = TIFFFieldWithTag(tif,dp->tdir_tag);
+ TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0);
+ goto bad;
+ }
+ saved_flags = tif->tif_flags;
+ tif->tif_flags |= TIFF_PERSAMPLE;
+ m = TIFFSetField(tif,dp->tdir_tag,data);
+ tif->tif_flags = saved_flags;
+ _TIFFfree(data);
+ if (!m)
+ goto bad;
}
- countpersample=(1U<<tif->tif_dir.td_bitspersample);
- if ((dp->tdir_tag==TIFFTAG_TRANSFERFUNCTION)&&(dp->tdir_count==(uint64)countpersample))
+ break;
+ case TIFFTAG_STRIPOFFSETS:
+ case TIFFTAG_TILEOFFSETS:
+ switch( dp->tdir_type )
{
- countrequired=countpersample;
- incrementpersample=0;
- }
- else
+ case TIFF_SHORT:
+ case TIFF_LONG:
+ case TIFF_LONG8:
+ break;
+ default:
+ /* Warn except if directory typically created with TIFFDeferStrileArrayWriting() */
+ if( !(tif->tif_mode == O_RDWR &&
+ dp->tdir_count == 0 &&
+ dp->tdir_type == 0 &&
+ dp->tdir_offset.toff_long8 == 0) )
+ {
+ fip = TIFFFieldWithTag(tif,dp->tdir_tag);
+ TIFFWarningExt(tif->tif_clientdata,module,
+ "Invalid data type for tag %s",
+ fip ? fip->field_name : "unknown tagname");
+ }
+ break;
+ }
+ _TIFFmemcpy( &(tif->tif_dir.td_stripoffset_entry),
+ dp, sizeof(TIFFDirEntry) );
+ break;
+ case TIFFTAG_STRIPBYTECOUNTS:
+ case TIFFTAG_TILEBYTECOUNTS:
+ switch( dp->tdir_type )
{
- countrequired=3*countpersample;
- incrementpersample=countpersample;
- }
- if (dp->tdir_count!=(uint64)countrequired)
- err=TIFFReadDirEntryErrCount;
- else
- err=TIFFReadDirEntryShortArray(tif,dp,&value);
- if (err!=TIFFReadDirEntryErrOk)
- {
- fip = TIFFFieldWithTag(tif,dp->tdir_tag);
- TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",1);
- }
- else
+ case TIFF_SHORT:
+ case TIFF_LONG:
+ case TIFF_LONG8:
+ break;
+ default:
+ /* Warn except if directory typically created with TIFFDeferStrileArrayWriting() */
+ if( !(tif->tif_mode == O_RDWR &&
+ dp->tdir_count == 0 &&
+ dp->tdir_type == 0 &&
+ dp->tdir_offset.toff_long8 == 0) )
+ {
+ fip = TIFFFieldWithTag(tif,dp->tdir_tag);
+ TIFFWarningExt(tif->tif_clientdata,module,
+ "Invalid data type for tag %s",
+ fip ? fip->field_name : "unknown tagname");
+ }
+ break;
+ }
+ _TIFFmemcpy( &(tif->tif_dir.td_stripbytecount_entry),
+ dp, sizeof(TIFFDirEntry) );
+ break;
+ case TIFFTAG_COLORMAP:
+ case TIFFTAG_TRANSFERFUNCTION:
{
- TIFFSetField(tif,dp->tdir_tag,value,value+incrementpersample,value+2*incrementpersample);
- _TIFFfree(value);
+ enum TIFFReadDirEntryErr err;
+ uint32 countpersample;
+ uint32 countrequired;
+ uint32 incrementpersample;
+ uint16* value=NULL;
+ /* It would be dangerous to instantiate those tag values */
+ /* since if td_bitspersample has not yet been read (due to */
+ /* unordered tags), it could be read afterwards with a */
+ /* values greater than the default one (1), which may cause */
+ /* crashes in user code */
+ if( !bitspersample_read )
+ {
+ fip = TIFFFieldWithTag(tif,dp->tdir_tag);
+ TIFFWarningExt(tif->tif_clientdata,module,
+ "Ignoring %s since BitsPerSample tag not found",
+ fip ? fip->field_name : "unknown tagname");
+ continue;
+ }
+ /* ColorMap or TransferFunction for high bit */
+ /* depths do not make much sense and could be */
+ /* used as a denial of service vector */
+ if (tif->tif_dir.td_bitspersample > 24)
+ {
+ fip = TIFFFieldWithTag(tif,dp->tdir_tag);
+ TIFFWarningExt(tif->tif_clientdata,module,
+ "Ignoring %s because BitsPerSample=%d>24",
+ fip ? fip->field_name : "unknown tagname",
+ tif->tif_dir.td_bitspersample);
+ continue;
+ }
+ countpersample=(1U<<tif->tif_dir.td_bitspersample);
+ if ((dp->tdir_tag==TIFFTAG_TRANSFERFUNCTION)&&(dp->tdir_count==(uint64)countpersample))
+ {
+ countrequired=countpersample;
+ incrementpersample=0;
+ }
+ else
+ {
+ countrequired=3*countpersample;
+ incrementpersample=countpersample;
+ }
+ if (dp->tdir_count!=(uint64)countrequired)
+ err=TIFFReadDirEntryErrCount;
+ else
+ err=TIFFReadDirEntryShortArray(tif,dp,&value);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ fip = TIFFFieldWithTag(tif,dp->tdir_tag);
+ TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",1);
+ }
+ else
+ {
+ TIFFSetField(tif,dp->tdir_tag,value,value+incrementpersample,value+2*incrementpersample);
+ _TIFFfree(value);
+ }
}
- }
- break;
+ break;
/* BEGIN REV 4.0 COMPATIBILITY */
- case TIFFTAG_OSUBFILETYPE:
- {
- uint16 valueo;
- uint32 value;
- if (TIFFReadDirEntryShort(tif,dp,&valueo)==TIFFReadDirEntryErrOk)
+ case TIFFTAG_OSUBFILETYPE:
{
- switch (valueo)
+ uint16 valueo;
+ uint32 value;
+ if (TIFFReadDirEntryShort(tif,dp,&valueo)==TIFFReadDirEntryErrOk)
{
- case OFILETYPE_REDUCEDIMAGE: value=FILETYPE_REDUCEDIMAGE; break;
- case OFILETYPE_PAGE: value=FILETYPE_PAGE; break;
- default: value=0; break;
+ switch (valueo)
+ {
+ case OFILETYPE_REDUCEDIMAGE: value=FILETYPE_REDUCEDIMAGE; break;
+ case OFILETYPE_PAGE: value=FILETYPE_PAGE; break;
+ default: value=0; break;
+ }
+ if (value!=0)
+ TIFFSetField(tif,TIFFTAG_SUBFILETYPE,value);
}
- if (value!=0)
- TIFFSetField(tif,TIFFTAG_SUBFILETYPE,value);
}
- }
- break;
+ break;
/* END REV 4.0 COMPATIBILITY */
- default:
- (void) TIFFFetchNormalTag(tif, dp, TRUE);
- break;
- }
- }
+ default:
+ (void) TIFFFetchNormalTag(tif, dp, TRUE);
+ break;
+ }
+ } /* -- if (!dp->tdir_ignore) */
+ } /* -- for-loop -- */
+
+ if( tif->tif_mode == O_RDWR &&
+ tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 )
+ {
+ /* Directory typically created with TIFFDeferStrileArrayWriting() */
+ TIFFSetupStrips(tif);
+ }
+ else if( !(tif->tif_flags&TIFF_DEFERSTRILELOAD) )
+ {
+ if( tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 )
+ {
+ if (!TIFFFetchStripThing(tif,&(tif->tif_dir.td_stripoffset_entry),
+ tif->tif_dir.td_nstrips,
+ &tif->tif_dir.td_stripoffset_p))
+ {
+ goto bad;
+ }
+ }
+ if( tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 )
+ {
+ if (!TIFFFetchStripThing(tif,&(tif->tif_dir.td_stripbytecount_entry),
+ tif->tif_dir.td_nstrips,
+ &tif->tif_dir.td_stripbytecount_p))
+ {
+ goto bad;
+ }
+ }
+ }
+
/*
* OJPEG hack:
* - If a) compression is OJPEG, and b) photometric tag is missing,
@@ -4128,33 +4213,10 @@ TIFFReadDirectory(TIFF* tif)
"\"StripByteCounts\" field, calculating from imagelength");
if (EstimateStripByteCounts(tif, dir, dircount) < 0)
goto bad;
- /*
- * Assume we have wrong StripByteCount value (in case
- * of single strip) in following cases:
- * - it is equal to zero along with StripOffset;
- * - it is larger than file itself (in case of uncompressed
- * image);
- * - it is smaller than the size of the bytes per row
- * multiplied on the number of rows. The last case should
- * not be checked in the case of writing new image,
- * because we may do not know the exact strip size
- * until the whole image will be written and directory
- * dumped out.
- */
- #define BYTECOUNTLOOKSBAD \
- ( (tif->tif_dir.td_stripbytecount[0] == 0 && tif->tif_dir.td_stripoffset[0] != 0) || \
- (tif->tif_dir.td_compression == COMPRESSION_NONE && \
- (tif->tif_dir.td_stripoffset[0] <= TIFFGetFileSize(tif) && \
- tif->tif_dir.td_stripbytecount[0] > TIFFGetFileSize(tif) - tif->tif_dir.td_stripoffset[0])) || \
- (tif->tif_mode == O_RDONLY && \
- tif->tif_dir.td_compression == COMPRESSION_NONE && \
- tif->tif_dir.td_stripbytecount[0] < TIFFScanlineSize64(tif) * tif->tif_dir.td_imagelength) )
} else if (tif->tif_dir.td_nstrips == 1
&& !(tif->tif_flags&TIFF_ISTILED)
- && _TIFFFillStriles(tif)
- && tif->tif_dir.td_stripoffset[0] != 0
- && BYTECOUNTLOOKSBAD) {
+ && ByteCountLooksBad(tif)) {
/*
* XXX: Plexus (and others) sometimes give a value of
* zero for a tag when they don't know what the
@@ -4166,13 +4228,13 @@ TIFFReadDirectory(TIFF* tif)
if(EstimateStripByteCounts(tif, dir, dircount) < 0)
goto bad;
-#if !defined(DEFER_STRILE_LOAD)
- } else if (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG
+ } else if (!(tif->tif_flags&TIFF_DEFERSTRILELOAD)
+ && tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG
&& tif->tif_dir.td_nstrips > 2
&& tif->tif_dir.td_compression == COMPRESSION_NONE
- && tif->tif_dir.td_stripbytecount[0] != tif->tif_dir.td_stripbytecount[1]
- && tif->tif_dir.td_stripbytecount[0] != 0
- && tif->tif_dir.td_stripbytecount[1] != 0 ) {
+ && TIFFGetStrileByteCount(tif, 0) != TIFFGetStrileByteCount(tif, 1)
+ && TIFFGetStrileByteCount(tif, 0) != 0
+ && TIFFGetStrileByteCount(tif, 1) != 0 ) {
/*
* XXX: Some vendors fill StripByteCount array with
* absolutely wrong values (it can be equal to
@@ -4187,7 +4249,6 @@ TIFFReadDirectory(TIFF* tif)
"Wrong \"StripByteCounts\" field, ignoring and calculating from imagelength");
if (EstimateStripByteCounts(tif, dir, dircount) < 0)
goto bad;
-#endif /* !defined(DEFER_STRILE_LOAD) */
}
}
if (dir)
@@ -4202,26 +4263,27 @@ TIFFReadDirectory(TIFF* tif)
else
tif->tif_dir.td_maxsamplevalue = (uint16)((1L<<tif->tif_dir.td_bitspersample)-1);
}
+
+#ifdef STRIPBYTECOUNTSORTED_UNUSED
/*
* XXX: We can optimize checking for the strip bounds using the sorted
* bytecounts array. See also comments for TIFFAppendToStrip()
* function in tif_write.c.
*/
-#if !defined(DEFER_STRILE_LOAD)
- if (tif->tif_dir.td_nstrips > 1) {
+ if (!(tif->tif_flags&TIFF_DEFERSTRILELOAD) && tif->tif_dir.td_nstrips > 1) {
uint32 strip;
tif->tif_dir.td_stripbytecountsorted = 1;
for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) {
- if (tif->tif_dir.td_stripoffset[strip - 1] >
- tif->tif_dir.td_stripoffset[strip]) {
+ if (TIFFGetStrileOffset(tif, strip - 1) >
+ TIFFGetStrileOffset(tif, strip)) {
tif->tif_dir.td_stripbytecountsorted = 0;
break;
}
}
}
-#endif /* !defined(DEFER_STRILE_LOAD) */
-
+#endif
+
/*
* An opportunity for compression mode dependent tag fixup
*/
@@ -4240,11 +4302,20 @@ TIFFReadDirectory(TIFF* tif)
(tif->tif_dir.td_nstrips==1)&&
(tif->tif_dir.td_compression==COMPRESSION_NONE)&&
((tif->tif_flags&(TIFF_STRIPCHOP|TIFF_ISTILED))==TIFF_STRIPCHOP))
- {
- if ( !_TIFFFillStriles(tif) || !tif->tif_dir.td_stripbytecount )
- return 0;
- ChopUpSingleUncompressedStrip(tif);
- }
+ {
+ ChopUpSingleUncompressedStrip(tif);
+ }
+
+ /* There are also uncompressed striped files with strips larger than */
+ /* 2 GB, which make them unfriendly with a lot of code. If possible, */
+ /* try to expose smaller "virtual" strips. */
+ if( tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG &&
+ tif->tif_dir.td_compression == COMPRESSION_NONE &&
+ (tif->tif_flags&(TIFF_STRIPCHOP|TIFF_ISTILED)) == TIFF_STRIPCHOP &&
+ TIFFStripSize64(tif) > 0x7FFFFFFFUL )
+ {
+ TryChopUpUncompressedBigTiff(tif);
+ }
/*
* Clear the dirty directory flag.
@@ -4396,17 +4467,17 @@ TIFFReadCustomDirectory(TIFF* tif, toff_t diroff,
TIFFWarningExt(tif->tif_clientdata, module,
"Registering anonymous field with tag %d (0x%x) failed",
dp->tdir_tag, dp->tdir_tag);
- dp->tdir_tag=IGNORE;
+ dp->tdir_ignore = TRUE;
} else {
TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
assert( fii != FAILED_FII );
}
}
- if (dp->tdir_tag!=IGNORE)
+ if (!dp->tdir_ignore)
{
fip=tif->tif_fields[fii];
if (fip->field_bit==FIELD_IGNORE)
- dp->tdir_tag=IGNORE;
+ dp->tdir_ignore = TRUE;
else
{
/* check data type */
@@ -4426,7 +4497,7 @@ TIFFReadCustomDirectory(TIFF* tif, toff_t diroff,
TIFFWarningExt(tif->tif_clientdata, module,
"Wrong data type %d for \"%s\"; tag ignored",
dp->tdir_type,fip->field_name);
- dp->tdir_tag=IGNORE;
+ dp->tdir_ignore = TRUE;
}
else
{
@@ -4440,21 +4511,21 @@ TIFFReadCustomDirectory(TIFF* tif, toff_t diroff,
else
expected=(uint32)fip->field_readcount;
if (!CheckDirCount(tif,dp,expected))
- dp->tdir_tag=IGNORE;
+ dp->tdir_ignore = TRUE;
}
}
}
- switch (dp->tdir_tag)
- {
- case IGNORE:
- break;
- case EXIFTAG_SUBJECTDISTANCE:
- (void) TIFFFetchSubjectDistance(tif,dp);
- break;
- default:
- (void) TIFFFetchNormalTag(tif, dp, TRUE);
- break;
- }
+ if (!dp->tdir_ignore) {
+ switch (dp->tdir_tag)
+ {
+ case EXIFTAG_SUBJECTDISTANCE:
+ (void)TIFFFetchSubjectDistance(tif, dp);
+ break;
+ default:
+ (void)TIFFFetchNormalTag(tif, dp, TRUE);
+ break;
+ }
+ } /*-- if (!dp->tdir_ignore) */
}
}
if (dir)
@@ -4487,12 +4558,12 @@ EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
if( !_TIFFFillStrilesInternal( tif, 0 ) )
return -1;
- if (td->td_stripbytecount)
- _TIFFfree(td->td_stripbytecount);
- td->td_stripbytecount = (uint64*)
+ if (td->td_stripbytecount_p)
+ _TIFFfree(td->td_stripbytecount_p);
+ td->td_stripbytecount_p = (uint64*)
_TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64),
"for \"StripByteCounts\" array");
- if( td->td_stripbytecount == NULL )
+ if( td->td_stripbytecount_p == NULL )
return -1;
if (td->td_compression != COMPRESSION_NONE) {
@@ -4516,6 +4587,8 @@ EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
dp->tdir_type);
return -1;
}
+ if( dp->tdir_count > TIFF_UINT64_MAX / typewidth )
+ return -1;
datasize=(uint64)typewidth*dp->tdir_count;
if (!(tif->tif_flags&TIFF_BIGTIFF))
{
@@ -4527,6 +4600,8 @@ EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
if (datasize<=8)
datasize=0;
}
+ if( space > TIFF_UINT64_MAX - datasize )
+ return -1;
space+=datasize;
}
if( filesize < space )
@@ -4537,7 +4612,7 @@ EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
space /= td->td_samplesperpixel;
for (strip = 0; strip < td->td_nstrips; strip++)
- td->td_stripbytecount[strip] = space;
+ td->td_stripbytecount_p[strip] = space;
/*
* This gross hack handles the case were the offset to
* the last strip is past the place where we think the strip
@@ -4546,18 +4621,30 @@ EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
* of data in the strip and trim this number back accordingly.
*/
strip--;
- if (td->td_stripoffset[strip]+td->td_stripbytecount[strip] > filesize)
- td->td_stripbytecount[strip] = filesize - td->td_stripoffset[strip];
+ if (td->td_stripoffset_p[strip] > TIFF_UINT64_MAX - td->td_stripbytecount_p[strip])
+ return -1;
+ if (td->td_stripoffset_p[strip]+td->td_stripbytecount_p[strip] > filesize) {
+ if( td->td_stripoffset_p[strip] >= filesize ) {
+ /* Not sure what we should in that case... */
+ td->td_stripbytecount_p[strip] = 0;
+ } else {
+ td->td_stripbytecount_p[strip] = filesize - td->td_stripoffset_p[strip];
+ }
+ }
} else if (isTiled(tif)) {
uint64 bytespertile = TIFFTileSize64(tif);
for (strip = 0; strip < td->td_nstrips; strip++)
- td->td_stripbytecount[strip] = bytespertile;
+ td->td_stripbytecount_p[strip] = bytespertile;
} else {
uint64 rowbytes = TIFFScanlineSize64(tif);
uint32 rowsperstrip = td->td_imagelength/td->td_stripsperimage;
for (strip = 0; strip < td->td_nstrips; strip++)
- td->td_stripbytecount[strip] = rowbytes * rowsperstrip;
+ {
+ if( rowbytes > 0 && rowsperstrip > TIFF_UINT64_MAX / rowbytes )
+ return -1;
+ td->td_stripbytecount_p[strip] = rowbytes * rowsperstrip;
+ }
}
TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
@@ -4751,12 +4838,13 @@ TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntry** pdir,
}
} else {
tmsize_t m;
- tmsize_t off = (tmsize_t) tif->tif_diroff;
- if ((uint64)off!=tif->tif_diroff)
+ tmsize_t off;
+ if (tif->tif_diroff > (uint64)TIFF_INT64_MAX)
{
TIFFErrorExt(tif->tif_clientdata,module,"Can not read TIFF directory count");
return(0);
}
+ off = (tmsize_t) tif->tif_diroff;
/*
* Check for integer overflow when validating the dir_off,
@@ -4874,6 +4962,7 @@ TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntry** pdir,
mb=dir;
for (n=0; n<dircount16; n++)
{
+ mb->tdir_ignore = FALSE;
if (tif->tif_flags&TIFF_SWAB)
TIFFSwabShort((uint16*)ma);
mb->tdir_tag=*(uint16*)ma;
@@ -4888,6 +4977,7 @@ TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntry** pdir,
TIFFSwabLong((uint32*)ma);
mb->tdir_count=(uint64)(*(uint32*)ma);
ma+=sizeof(uint32);
+ mb->tdir_offset.toff_long8=0;
*(uint32*)(&mb->tdir_offset)=*(uint32*)ma;
ma+=sizeof(uint32);
}
@@ -5090,6 +5180,7 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
if (err==TIFFReadDirEntryErrOk)
{
int m;
+ assert(data); /* avoid CLang static Analyzer false positive */
m=TIFFSetField(tif,dp->tdir_tag,data[0],data[1]);
_TIFFfree(data);
if (!m)
@@ -5681,7 +5772,7 @@ TIFFFetchSubjectDistance(TIFF* tif, TIFFDirEntry* dir)
TIFFSwabArrayOfLong(m.i,2);
if (m.i[0]==0)
n=0.0;
- else if (m.i[0]==0xFFFFFFFF)
+ else if (m.i[0]==0xFFFFFFFF || m.i[1]==0)
/*
* XXX: Numerator 0xFFFFFFFF means that we have infinite
* distance. Indicate that with a negative floating point
@@ -5699,6 +5790,75 @@ TIFFFetchSubjectDistance(TIFF* tif, TIFFDirEntry* dir)
}
}
+static void allocChoppedUpStripArrays(TIFF* tif, uint32 nstrips,
+ uint64 stripbytes, uint32 rowsperstrip)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ uint64 bytecount;
+ uint64 offset;
+ uint64 last_offset;
+ uint64 last_bytecount;
+ uint32 i;
+ uint64 *newcounts;
+ uint64 *newoffsets;
+
+ offset = TIFFGetStrileOffset(tif, 0);
+ last_offset = TIFFGetStrileOffset(tif, td->td_nstrips-1);
+ last_bytecount = TIFFGetStrileByteCount(tif, td->td_nstrips-1);
+ if( last_offset > TIFF_UINT64_MAX - last_bytecount ||
+ last_offset + last_bytecount < offset )
+ {
+ return;
+ }
+ bytecount = last_offset + last_bytecount - offset;
+
+ newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
+ "for chopped \"StripByteCounts\" array");
+ newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
+ "for chopped \"StripOffsets\" array");
+ if (newcounts == NULL || newoffsets == NULL) {
+ /*
+ * Unable to allocate new strip information, give up and use
+ * the original one strip information.
+ */
+ if (newcounts != NULL)
+ _TIFFfree(newcounts);
+ if (newoffsets != NULL)
+ _TIFFfree(newoffsets);
+ return;
+ }
+
+ /*
+ * Fill the strip information arrays with new bytecounts and offsets
+ * that reflect the broken-up format.
+ */
+ for (i = 0; i < nstrips; i++)
+ {
+ if (stripbytes > bytecount)
+ stripbytes = bytecount;
+ newcounts[i] = stripbytes;
+ newoffsets[i] = stripbytes ? offset : 0;
+ offset += stripbytes;
+ bytecount -= stripbytes;
+ }
+
+ /*
+ * Replace old single strip info with multi-strip info.
+ */
+ td->td_stripsperimage = td->td_nstrips = nstrips;
+ TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
+
+ _TIFFfree(td->td_stripbytecount_p);
+ _TIFFfree(td->td_stripoffset_p);
+ td->td_stripbytecount_p = newcounts;
+ td->td_stripoffset_p = newoffsets;
+#ifdef STRIPBYTECOUNTSORTED_UNUSED
+ td->td_stripbytecountsorted = 1;
+#endif
+ tif->tif_flags |= TIFF_CHOPPEDUPARRAYS;
+}
+
+
/*
* Replace a single strip (tile) of uncompressed data by multiple strips
* (tiles), each approximately STRIP_SIZE_DEFAULT bytes. This is useful for
@@ -5714,19 +5874,16 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
uint32 rowblock;
uint64 rowblockbytes;
uint64 stripbytes;
- uint32 strip;
uint32 nstrips;
uint32 rowsperstrip;
- uint64* newcounts;
- uint64* newoffsets;
- bytecount = td->td_stripbytecount[0];
+ bytecount = TIFFGetStrileByteCount(tif, 0);
/* On a newly created file, just re-opened to be filled, we */
/* don't want strip chop to trigger as it is going to cause issues */
/* later ( StripOffsets and StripByteCounts improperly filled) . */
if( bytecount == 0 && tif->tif_mode != O_RDONLY )
return;
- offset = td->td_stripoffset[0];
+ offset = TIFFGetStrileByteCount(tif, 0);
assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
if ((td->td_photometric == PHOTOMETRIC_YCBCR)&&
(!isUpSampled(tif)))
@@ -5769,98 +5926,520 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
return;
}
- newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
- "for chopped \"StripByteCounts\" array");
- newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
- "for chopped \"StripOffsets\" array");
- if (newcounts == NULL || newoffsets == NULL) {
- /*
- * Unable to allocate new strip information, give up and use
- * the original one strip information.
- */
- if (newcounts != NULL)
- _TIFFfree(newcounts);
- if (newoffsets != NULL)
- _TIFFfree(newoffsets);
- return;
- }
- /*
- * Fill the strip information arrays with new bytecounts and offsets
- * that reflect the broken-up format.
- */
- for (strip = 0; strip < nstrips; strip++) {
- if (stripbytes > bytecount)
- stripbytes = bytecount;
- newcounts[strip] = stripbytes;
- newoffsets[strip] = stripbytes ? offset : 0;
- offset += stripbytes;
- bytecount -= stripbytes;
- }
- /*
- * Replace old single strip info with multi-strip info.
- */
- td->td_stripsperimage = td->td_nstrips = nstrips;
- TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
-
- _TIFFfree(td->td_stripbytecount);
- _TIFFfree(td->td_stripoffset);
- td->td_stripbytecount = newcounts;
- td->td_stripoffset = newoffsets;
- td->td_stripbytecountsorted = 1;
+ allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip);
}
-int _TIFFFillStriles( TIFF *tif )
+
+/*
+ * Replace a file with contiguous strips > 2 GB of uncompressed data by
+ * multiple smaller strips. This is useful for
+ * dealing with large images or for dealing with machines with a limited
+ * amount memory.
+ */
+static void TryChopUpUncompressedBigTiff( TIFF* tif )
{
- return _TIFFFillStrilesInternal( tif, 1 );
+ TIFFDirectory *td = &tif->tif_dir;
+ uint32 rowblock;
+ uint64 rowblockbytes;
+ uint32 i;
+ uint64 stripsize;
+ uint32 rowblocksperstrip;
+ uint32 rowsperstrip;
+ uint64 stripbytes;
+ uint32 nstrips;
+
+ stripsize = TIFFStripSize64(tif);
+
+ assert( tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG );
+ assert( tif->tif_dir.td_compression == COMPRESSION_NONE );
+ assert( (tif->tif_flags&(TIFF_STRIPCHOP|TIFF_ISTILED)) == TIFF_STRIPCHOP );
+ assert( stripsize > 0x7FFFFFFFUL );
+
+ /* On a newly created file, just re-opened to be filled, we */
+ /* don't want strip chop to trigger as it is going to cause issues */
+ /* later ( StripOffsets and StripByteCounts improperly filled) . */
+ if( TIFFGetStrileByteCount(tif, 0) == 0 && tif->tif_mode != O_RDONLY )
+ return;
+
+ if ((td->td_photometric == PHOTOMETRIC_YCBCR)&&
+ (!isUpSampled(tif)))
+ rowblock = td->td_ycbcrsubsampling[1];
+ else
+ rowblock = 1;
+ rowblockbytes = TIFFVStripSize64(tif, rowblock);
+ if( rowblockbytes == 0 || rowblockbytes > 0x7FFFFFFFUL )
+ {
+ /* In case of file with gigantic width */
+ return;
+ }
+
+ /* Check that the strips are contiguous and of the expected size */
+ for( i = 0; i < td->td_nstrips; i++ )
+ {
+ if( i == td->td_nstrips - 1 )
+ {
+ if( TIFFGetStrileByteCount(tif, i) < TIFFVStripSize64(
+ tif, td->td_imagelength - i * td->td_rowsperstrip ) )
+ {
+ return;
+ }
+ }
+ else
+ {
+ if( TIFFGetStrileByteCount(tif, i) != stripsize )
+ {
+ return;
+ }
+ if( i > 0 && TIFFGetStrileOffset(tif, i) !=
+ TIFFGetStrileOffset(tif, i-1) + TIFFGetStrileByteCount(tif, i-1) )
+ {
+ return;
+ }
+ }
+ }
+
+ /* Aim for 512 MB strips (that will still be manageable by 32 bit builds */
+ rowblocksperstrip = (uint32) (512 * 1024 * 1024 / rowblockbytes);
+ if( rowblocksperstrip == 0 )
+ rowblocksperstrip = 1;
+ rowsperstrip = rowblocksperstrip * rowblock;
+ stripbytes = rowblocksperstrip * rowblockbytes;
+ assert( stripbytes <= 0x7FFFFFFFUL );
+
+ nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip);
+ if( nstrips == 0 )
+ return;
+
+ /* If we are going to allocate a lot of memory, make sure that the */
+ /* file is as big as needed */
+ if( tif->tif_mode == O_RDONLY &&
+ nstrips > 1000000 )
+ {
+ uint64 last_offset = TIFFGetStrileOffset(tif, td->td_nstrips-1);
+ uint64 filesize = TIFFGetFileSize(tif);
+ uint64 last_bytecount = TIFFGetStrileByteCount(tif, td->td_nstrips-1);
+ if( last_offset > filesize ||
+ last_bytecount > filesize - last_offset )
+ {
+ return;
+ }
+ }
+
+ allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip);
}
-static int _TIFFFillStrilesInternal( TIFF *tif, int loadStripByteCount )
+
+TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
+static uint64 _TIFFUnsanitizedAddUInt64AndInt(uint64 a, int b)
{
-#if defined(DEFER_STRILE_LOAD)
- register TIFFDirectory *td = &tif->tif_dir;
- int return_value = 1;
+ return a + b;
+}
- if( td->td_stripoffset != NULL )
- return 1;
+/* Read the value of [Strip|Tile]Offset or [Strip|Tile]ByteCount around
+ * strip/tile of number strile. Also fetch the neighbouring values using a
+ * 4096 byte page size.
+ */
+static
+int _TIFFPartialReadStripArray( TIFF* tif, TIFFDirEntry* dirent,
+ int strile, uint64* panVals )
+{
+ static const char module[] = "_TIFFPartialReadStripArray";
+#define IO_CACHE_PAGE_SIZE 4096
+
+ size_t sizeofval;
+ const int bSwab = (tif->tif_flags & TIFF_SWAB) != 0;
+ int sizeofvalint;
+ uint64 nBaseOffset;
+ uint64 nOffset;
+ uint64 nOffsetStartPage;
+ uint64 nOffsetEndPage;
+ tmsize_t nToRead;
+ tmsize_t nRead;
+ uint64 nLastStripOffset;
+ int iStartBefore;
+ int i;
+ const uint32 arraySize = tif->tif_dir.td_stripoffsetbyteallocsize;
+ unsigned char buffer[2 * IO_CACHE_PAGE_SIZE];
+
+ assert( dirent->tdir_count > 4 );
+
+ if( dirent->tdir_type == TIFF_SHORT )
+ {
+ sizeofval = sizeof(uint16);
+ }
+ else if( dirent->tdir_type == TIFF_LONG )
+ {
+ sizeofval = sizeof(uint32);
+ }
+ else if( dirent->tdir_type == TIFF_LONG8 )
+ {
+ sizeofval = sizeof(uint64);
+ }
+ else if( dirent->tdir_type == TIFF_SLONG8 )
+ {
+ /* Non conformant but used by some images as in */
+ /* https://github.com/OSGeo/gdal/issues/2165 */
+ sizeofval = sizeof(int64);
+ }
+ else
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Invalid type for [Strip|Tile][Offset/ByteCount] tag");
+ panVals[strile] = 0;
+ return 0;
+ }
+ sizeofvalint = (int)(sizeofval);
- if( td->td_stripoffset_entry.tdir_count == 0 )
+ if( tif->tif_flags&TIFF_BIGTIFF )
+ {
+ uint64 offset = dirent->tdir_offset.toff_long8;
+ if( bSwab )
+ TIFFSwabLong8(&offset);
+ nBaseOffset = offset;
+ }
+ else
+ {
+ uint32 offset = dirent->tdir_offset.toff_long;
+ if( bSwab )
+ TIFFSwabLong(&offset);
+ nBaseOffset = offset;
+ }
+ /* To avoid later unsigned integer overflows */
+ if( nBaseOffset > (uint64)TIFF_INT64_MAX )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Cannot read offset/size for strile %d", strile);
+ panVals[strile] = 0;
+ return 0;
+ }
+ nOffset = nBaseOffset + sizeofval * strile;
+ nOffsetStartPage =
+ (nOffset / IO_CACHE_PAGE_SIZE) * IO_CACHE_PAGE_SIZE;
+ nOffsetEndPage = nOffsetStartPage + IO_CACHE_PAGE_SIZE;
+
+ if( nOffset + sizeofval > nOffsetEndPage )
+ nOffsetEndPage += IO_CACHE_PAGE_SIZE;
+#undef IO_CACHE_PAGE_SIZE
+
+ nLastStripOffset = nBaseOffset + arraySize * sizeofval;
+ if( nLastStripOffset < nOffsetEndPage )
+ nOffsetEndPage = nLastStripOffset;
+ if( nOffsetStartPage >= nOffsetEndPage )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Cannot read offset/size for strile %d", strile);
+ panVals[strile] = 0;
+ return 0;
+ }
+ if (!SeekOK(tif,nOffsetStartPage))
+ {
+ panVals[strile] = 0;
+ return 0;
+ }
+
+ nToRead = (tmsize_t)(nOffsetEndPage - nOffsetStartPage);
+ nRead = TIFFReadFile(tif, buffer, nToRead);
+ if( nRead < nToRead )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Cannot read offset/size for strile around ~%d", strile);
+ return 0;
+ }
+ iStartBefore = -(int)((nOffset - nOffsetStartPage) / sizeofval);
+ if( strile + iStartBefore < 0 )
+ iStartBefore = -strile;
+ for( i = iStartBefore;
+ (uint32)(strile + i) < arraySize &&
+ _TIFFUnsanitizedAddUInt64AndInt(nOffset, (i + 1) * sizeofvalint) <= nOffsetEndPage;
+ ++i )
+ {
+ if( dirent->tdir_type == TIFF_SHORT )
+ {
+ uint16 val;
+ memcpy(&val,
+ buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
+ sizeof(val));
+ if( bSwab )
+ TIFFSwabShort(&val);
+ panVals[strile + i] = val;
+ }
+ else if( dirent->tdir_type == TIFF_LONG )
+ {
+ uint32 val;
+ memcpy(&val,
+ buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
+ sizeof(val));
+ if( bSwab )
+ TIFFSwabLong(&val);
+ panVals[strile + i] = val;
+ }
+ else if( dirent->tdir_type == TIFF_LONG8 )
+ {
+ uint64 val;
+ memcpy(&val,
+ buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
+ sizeof(val));
+ if( bSwab )
+ TIFFSwabLong8(&val);
+ panVals[strile + i] = val;
+ }
+ else /* if( dirent->tdir_type == TIFF_SLONG8 ) */
+ {
+ /* Non conformant data type */
+ int64 val;
+ memcpy(&val,
+ buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
+ sizeof(val));
+ if( bSwab )
+ TIFFSwabLong8((uint64*) &val);
+ panVals[strile + i] = (uint64) val;
+ }
+ }
+ return 1;
+}
+
+static int _TIFFFetchStrileValue(TIFF* tif,
+ uint32 strile,
+ TIFFDirEntry* dirent,
+ uint64** parray)
+{
+ static const char module[] = "_TIFFFetchStrileValue";
+ TIFFDirectory *td = &tif->tif_dir;
+ if( strile >= dirent->tdir_count )
+ {
+ return 0;
+ }
+ if( strile >= td->td_stripoffsetbyteallocsize )
+ {
+ uint32 nStripArrayAllocBefore = td->td_stripoffsetbyteallocsize;
+ uint32 nStripArrayAllocNew;
+ uint64 nArraySize64;
+ size_t nArraySize;
+ uint64* offsetArray;
+ uint64* bytecountArray;
+
+ if( strile > 1000000 )
+ {
+ uint64 filesize = TIFFGetFileSize(tif);
+ /* Avoid excessive memory allocation attempt */
+ /* For such a big blockid we need at least a TIFF_LONG per strile */
+ /* for the offset array. */
+ if( strile > filesize / sizeof(uint32) )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module, "File too short");
return 0;
+ }
+ }
- if (!TIFFFetchStripThing(tif,&(td->td_stripoffset_entry),
- td->td_nstrips,&td->td_stripoffset))
+ if( td->td_stripoffsetbyteallocsize == 0 &&
+ td->td_nstrips < 1024 * 1024 )
+ {
+ nStripArrayAllocNew = td->td_nstrips;
+ }
+ else
{
- return_value = 0;
+#define TIFF_MAX(a,b) (((a)>(b)) ? (a) : (b))
+#define TIFF_MIN(a,b) (((a)<(b)) ? (a) : (b))
+ nStripArrayAllocNew = TIFF_MAX(strile + 1, 1024U * 512U );
+ if( nStripArrayAllocNew < 0xFFFFFFFFU / 2 )
+ nStripArrayAllocNew *= 2;
+ nStripArrayAllocNew = TIFF_MIN(nStripArrayAllocNew, td->td_nstrips);
}
+ assert( strile < nStripArrayAllocNew );
+ nArraySize64 = (uint64)sizeof(uint64) * nStripArrayAllocNew;
+ nArraySize = (size_t)(nArraySize64);
+#if SIZEOF_SIZE_T == 4
+ if( nArraySize != nArraySize64 )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Cannot allocate strip offset and bytecount arrays");
+ return 0;
+ }
+#endif
+ offsetArray = (uint64*)(
+ _TIFFrealloc( td->td_stripoffset_p, nArraySize ) );
+ bytecountArray = (uint64*)(
+ _TIFFrealloc( td->td_stripbytecount_p, nArraySize ) );
+ if( offsetArray )
+ td->td_stripoffset_p = offsetArray;
+ if( bytecountArray )
+ td->td_stripbytecount_p = bytecountArray;
+ if( offsetArray && bytecountArray )
+ {
+ td->td_stripoffsetbyteallocsize = nStripArrayAllocNew;
+ /* Initialize new entries to ~0 / -1 */
+ memset(td->td_stripoffset_p + nStripArrayAllocBefore,
+ 0xFF,
+ (td->td_stripoffsetbyteallocsize - nStripArrayAllocBefore) * sizeof(uint64) );
+ memset(td->td_stripbytecount_p + nStripArrayAllocBefore,
+ 0xFF,
+ (td->td_stripoffsetbyteallocsize - nStripArrayAllocBefore) * sizeof(uint64) );
+ }
+ else
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Cannot allocate strip offset and bytecount arrays");
+ _TIFFfree(td->td_stripoffset_p);
+ td->td_stripoffset_p = NULL;
+ _TIFFfree(td->td_stripbytecount_p);
+ td->td_stripbytecount_p = NULL;
+ td->td_stripoffsetbyteallocsize = 0;
+ }
+ }
+ if( *parray == NULL || strile >= td->td_stripoffsetbyteallocsize )
+ return 0;
- if (loadStripByteCount &&
- !TIFFFetchStripThing(tif,&(td->td_stripbytecount_entry),
- td->td_nstrips,&td->td_stripbytecount))
+ if( ~((*parray)[strile]) == 0 )
+ {
+ if( !_TIFFPartialReadStripArray( tif, dirent, strile, *parray ) )
{
- return_value = 0;
+ (*parray)[strile] = 0;
+ return 0;
}
+ }
- _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
- _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
+ return 1;
+}
- if (tif->tif_dir.td_nstrips > 1 && return_value == 1 ) {
- uint32 strip;
+static uint64 _TIFFGetStrileOffsetOrByteCountValue(TIFF *tif, uint32 strile,
+ TIFFDirEntry* dirent,
+ uint64** parray,
+ int *pbErr)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ if( pbErr )
+ *pbErr = 0;
+ if( (tif->tif_flags&TIFF_DEFERSTRILELOAD) && !(tif->tif_flags&TIFF_CHOPPEDUPARRAYS) )
+ {
+ if( !(tif->tif_flags&TIFF_LAZYSTRILELOAD) ||
+ /* If the values may fit in the toff_long/toff_long8 member */
+ /* then use _TIFFFillStriles to simplify _TIFFFetchStrileValue */
+ dirent->tdir_count <= 4 )
+ {
+ if( !_TIFFFillStriles(tif) )
+ {
+ if( pbErr )
+ *pbErr = 1;
+ /* Do not return, as we want this function to always */
+ /* return the same value if called several times with */
+ /* the same arguments */
+ }
+ }
+ else
+ {
+ if( !_TIFFFetchStrileValue(tif, strile, dirent, parray) )
+ {
+ if( pbErr )
+ *pbErr = 1;
+ return 0;
+ }
+ }
+ }
+ if( *parray == NULL || strile >= td->td_nstrips )
+ {
+ if( pbErr )
+ *pbErr = 1;
+ return 0;
+ }
+ return (*parray)[strile];
+}
- tif->tif_dir.td_stripbytecountsorted = 1;
- for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) {
- if (tif->tif_dir.td_stripoffset[strip - 1] >
- tif->tif_dir.td_stripoffset[strip]) {
- tif->tif_dir.td_stripbytecountsorted = 0;
- break;
- }
- }
- }
+/* Return the value of the TileOffsets/StripOffsets array for the specified tile/strile */
+uint64 TIFFGetStrileOffset(TIFF *tif, uint32 strile)
+{
+ return TIFFGetStrileOffsetWithErr(tif, strile, NULL);
+}
+
+/* Return the value of the TileOffsets/StripOffsets array for the specified tile/strile */
+uint64 TIFFGetStrileOffsetWithErr(TIFF *tif, uint32 strile, int *pbErr)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ return _TIFFGetStrileOffsetOrByteCountValue(tif, strile,
+ &(td->td_stripoffset_entry),
+ &(td->td_stripoffset_p), pbErr);
+}
+
+/* Return the value of the TileByteCounts/StripByteCounts array for the specified tile/strile */
+uint64 TIFFGetStrileByteCount(TIFF *tif, uint32 strile)
+{
+ return TIFFGetStrileByteCountWithErr(tif, strile, NULL);
+}
+
+/* Return the value of the TileByteCounts/StripByteCounts array for the specified tile/strile */
+uint64 TIFFGetStrileByteCountWithErr(TIFF *tif, uint32 strile, int *pbErr)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ return _TIFFGetStrileOffsetOrByteCountValue(tif, strile,
+ &(td->td_stripbytecount_entry),
+ &(td->td_stripbytecount_p), pbErr);
+}
- return return_value;
-#else /* !defined(DEFER_STRILE_LOAD) */
- (void) tif;
- (void) loadStripByteCount;
+
+int _TIFFFillStriles( TIFF *tif )
+{
+ return _TIFFFillStrilesInternal( tif, 1 );
+}
+
+static int _TIFFFillStrilesInternal( TIFF *tif, int loadStripByteCount )
+{
+ register TIFFDirectory *td = &tif->tif_dir;
+ int return_value = 1;
+
+ /* Do not do anything if TIFF_DEFERSTRILELOAD is not set */
+ if( !(tif->tif_flags&TIFF_DEFERSTRILELOAD) || (tif->tif_flags&TIFF_CHOPPEDUPARRAYS) != 0 )
return 1;
-#endif
+
+ if( tif->tif_flags&TIFF_LAZYSTRILELOAD )
+ {
+ /* In case of lazy loading, reload completely the arrays */
+ _TIFFfree(td->td_stripoffset_p);
+ _TIFFfree(td->td_stripbytecount_p);
+ td->td_stripoffset_p = NULL;
+ td->td_stripbytecount_p = NULL;
+ td->td_stripoffsetbyteallocsize = 0;
+ tif->tif_flags &= ~TIFF_LAZYSTRILELOAD;
+ }
+
+ /* If stripoffset array is already loaded, exit with success */
+ if( td->td_stripoffset_p != NULL )
+ return 1;
+
+ /* If tdir_count was cancelled, then we already got there, but in error */
+ if( td->td_stripoffset_entry.tdir_count == 0 )
+ return 0;
+
+ if (!TIFFFetchStripThing(tif,&(td->td_stripoffset_entry),
+ td->td_nstrips,&td->td_stripoffset_p))
+ {
+ return_value = 0;
+ }
+
+ if (loadStripByteCount &&
+ !TIFFFetchStripThing(tif,&(td->td_stripbytecount_entry),
+ td->td_nstrips,&td->td_stripbytecount_p))
+ {
+ return_value = 0;
+ }
+
+ _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
+ _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
+
+#ifdef STRIPBYTECOUNTSORTED_UNUSED
+ if (tif->tif_dir.td_nstrips > 1 && return_value == 1 ) {
+ uint32 strip;
+
+ tif->tif_dir.td_stripbytecountsorted = 1;
+ for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) {
+ if (tif->tif_dir.td_stripoffset_p[strip - 1] >
+ tif->tif_dir.td_stripoffset_p[strip]) {
+ tif->tif_dir.td_stripbytecountsorted = 0;
+ break;
+ }
+ }
+ }
+#endif
+
+ return return_value;
}
diff --git a/libtiff/tif_dirwrite.c b/libtiff/tif_dirwrite.c
index c15a28db..9e4d3060 100644
--- a/libtiff/tif_dirwrite.c
+++ b/libtiff/tif_dirwrite.c
@@ -28,7 +28,6 @@
* Directory Write Support Routines.
*/
#include "tiffiop.h"
-#include <float.h>
#ifdef HAVE_IEEEFP
#define TIFFCvtNativeToIEEEFloat(tif, n, fp)
@@ -183,6 +182,51 @@ TIFFWriteDirectory(TIFF* tif)
}
/*
+ * This is an advanced writing function that must be used in a particular
+ * sequence, and generally together with TIFFForceStrileArrayWriting(),
+ * to make its intended effect. Its aim is to modify the location
+ * where the [Strip/Tile][Offsets/ByteCounts] arrays are located in the file.
+ * More precisely, when TIFFWriteCheck() will be called, the tag entries for
+ * those arrays will be written with type = count = offset = 0 as a temporary
+ * value.
+ *
+ * Its effect is only valid for the current directory, and before
+ * TIFFWriteDirectory() is first called, and will be reset when
+ * changing directory.
+ *
+ * The typical sequence of calls is:
+ * TIFFOpen()
+ * [ TIFFCreateDirectory(tif) ]
+ * Set fields with calls to TIFFSetField(tif, ...)
+ * TIFFDeferStrileArrayWriting(tif)
+ * TIFFWriteCheck(tif, ...)
+ * TIFFWriteDirectory(tif)
+ * ... potentially create other directories and come back to the above directory
+ * TIFFForceStrileArrayWriting(tif): emit the arrays at the end of file
+ *
+ * Returns 1 in case of success, 0 otherwise.
+ */
+int TIFFDeferStrileArrayWriting(TIFF* tif)
+{
+ static const char module[] = "TIFFDeferStrileArrayWriting";
+ if (tif->tif_mode == O_RDONLY)
+ {
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "File opened in read-only mode");
+ return 0;
+ }
+ if( tif->tif_diroff != 0 )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Directory has already been written");
+ return 0;
+ }
+
+ tif->tif_dir.td_deferstrilearraywriting = TRUE;
+ return 1;
+}
+
+/*
* Similar to TIFFWriteDirectory(), writes the directory out
* but leaves all data structures in memory so that it can be
* written again. This will make a partially written TIFF file
@@ -193,7 +237,7 @@ TIFFCheckpointDirectory(TIFF* tif)
{
int rc;
/* Setup the strips arrays, if they haven't already been. */
- if (tif->tif_dir.td_stripoffset == NULL)
+ if (tif->tif_dir.td_stripoffset_p == NULL)
(void) TIFFSetupStrips(tif);
rc = TIFFWriteDirectorySec(tif,TRUE,FALSE,NULL);
(void) TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END));
@@ -528,12 +572,12 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff)
{
if (!isTiled(tif))
{
- if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount))
+ if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount_p))
goto bad;
}
else
{
- if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount))
+ if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount_p))
goto bad;
}
}
@@ -541,7 +585,7 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff)
{
if (!isTiled(tif))
{
- /* td_stripoffset might be NULL in an odd OJPEG case. See
+ /* td_stripoffset_p might be NULL in an odd OJPEG case. See
* tif_dirread.c around line 3634.
* XXX: OJPEG hack.
* If a) compression is OJPEG, b) it's not a tiled TIFF,
@@ -552,13 +596,13 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff)
* We can get here when using tiffset on such a file.
* See http://bugzilla.maptools.org/show_bug.cgi?id=2500
*/
- if (tif->tif_dir.td_stripoffset != NULL &&
- !TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset))
+ if (tif->tif_dir.td_stripoffset_p != NULL &&
+ !TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset_p))
goto bad;
}
else
{
- if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset))
+ if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset_p))
goto bad;
}
}
@@ -946,15 +990,6 @@ bad:
return(0);
}
-static float TIFFClampDoubleToFloat( double val )
-{
- if( val > FLT_MAX )
- return FLT_MAX;
- if( val < -FLT_MAX )
- return -FLT_MAX;
- return (float)val;
-}
-
static int8 TIFFClampDoubleToInt8( double val )
{
if( val > 127 )
@@ -1029,7 +1064,7 @@ TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* di
if (tif->tif_dir.td_bitspersample<=32)
{
for (i = 0; i < count; ++i)
- ((float*)conv)[i] = TIFFClampDoubleToFloat(value[i]);
+ ((float*)conv)[i] = _TIFFClampDoubleToFloat(value[i]);
ok = TIFFWriteDirectoryTagFloatArray(tif,ndir,dir,tag,count,(float*)conv);
}
else
@@ -1661,22 +1696,52 @@ TIFFWriteDirectoryTagShortLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint1
return(TIFFWriteDirectoryTagCheckedLong(tif,ndir,dir,tag,value));
}
+static int _WriteAsType(TIFF* tif, uint64 strile_size, uint64 uncompressed_threshold)
+{
+ const uint16 compression = tif->tif_dir.td_compression;
+ if ( compression == COMPRESSION_NONE )
+ {
+ return strile_size > uncompressed_threshold;
+ }
+ else if ( compression == COMPRESSION_JPEG ||
+ compression == COMPRESSION_LZW ||
+ compression == COMPRESSION_ADOBE_DEFLATE ||
+ compression == COMPRESSION_LZMA ||
+ compression == COMPRESSION_LERC ||
+ compression == COMPRESSION_ZSTD ||
+ compression == COMPRESSION_WEBP )
+ {
+ /* For a few select compression types, we assume that in the worst */
+ /* case the compressed size will be 10 times the uncompressed size */
+ /* This is overly pessismistic ! */
+ return strile_size >= uncompressed_threshold / 10;
+ }
+ return 1;
+}
+
+static int WriteAsLong8(TIFF* tif, uint64 strile_size)
+{
+ return _WriteAsType(tif, strile_size, 0xFFFFFFFFU);
+}
+
+static int WriteAsLong4(TIFF* tif, uint64 strile_size)
+{
+ return _WriteAsType(tif, strile_size, 0xFFFFU);
+}
+
/************************************************************************/
/* TIFFWriteDirectoryTagLongLong8Array() */
/* */
-/* Write out LONG8 array as LONG8 for BigTIFF or LONG for */
-/* Classic TIFF with some checking. */
+/* Write out LONG8 array and write a SHORT/LONG/LONG8 depending */
+/* on strile size and Classic/BigTIFF mode. */
/************************************************************************/
static int
TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
{
static const char module[] = "TIFFWriteDirectoryTagLongLong8Array";
- uint64* ma;
- uint32 mb;
- uint32* p;
- uint32* q;
int o;
+ int write_aslong4;
/* is this just a counting pass? */
if (dir==NULL)
@@ -1685,37 +1750,105 @@ TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir,
return(1);
}
- /* We always write LONG8 for BigTIFF, no checking needed. */
- if( tif->tif_flags&TIFF_BIGTIFF )
- return TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,
- tag,count,value);
-
- /*
- ** For classic tiff we want to verify everything is in range for LONG
- ** and convert to long format.
- */
+ if( tif->tif_dir.td_deferstrilearraywriting )
+ {
+ return TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_NOTYPE, 0, 0, NULL);
+ }
- p = _TIFFmalloc(count*sizeof(uint32));
- if (p==NULL)
+ if( tif->tif_flags&TIFF_BIGTIFF )
{
- TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
- return(0);
+ int write_aslong8 = 1;
+ /* In the case of ByteCounts array, we may be able to write them on */
+ /* LONG if the strip/tilesize is not too big. */
+ /* Also do that for count > 1 in the case someone would want to create */
+ /* a single-strip file with a growing height, in which case using */
+ /* LONG8 will be safer. */
+ if( count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS )
+ {
+ write_aslong8 = WriteAsLong8(tif, TIFFStripSize64(tif));
+ }
+ else if( count > 1 && tag == TIFFTAG_TILEBYTECOUNTS )
+ {
+ write_aslong8 = WriteAsLong8(tif, TIFFTileSize64(tif));
+ }
+ if( write_aslong8 )
+ {
+ return TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,
+ tag,count,value);
+ }
}
- for (q=p, ma=value, mb=0; mb<count; ma++, mb++, q++)
+ write_aslong4 = 1;
+ if( count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS )
{
- if (*ma>0xFFFFFFFF)
+ write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif));
+ }
+ else if( count > 1 && tag == TIFFTAG_TILEBYTECOUNTS )
+ {
+ write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif));
+ }
+ if( write_aslong4 )
+ {
+ /*
+ ** For classic tiff we want to verify everything is in range for LONG
+ ** and convert to long format.
+ */
+
+ uint32* p = _TIFFmalloc(count*sizeof(uint32));
+ uint32* q;
+ uint64* ma;
+ uint32 mb;
+
+ if (p==NULL)
{
- TIFFErrorExt(tif->tif_clientdata,module,
- "Attempt to write value larger than 0xFFFFFFFF in Classic TIFF file.");
- _TIFFfree(p);
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
return(0);
}
- *q= (uint32)(*ma);
+
+ for (q=p, ma=value, mb=0; mb<count; ma++, mb++, q++)
+ {
+ if (*ma>0xFFFFFFFF)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,
+ "Attempt to write value larger than 0xFFFFFFFF in LONG array.");
+ _TIFFfree(p);
+ return(0);
+ }
+ *q= (uint32)(*ma);
+ }
+
+ o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,p);
+ _TIFFfree(p);
}
+ else
+ {
+ uint16* p = _TIFFmalloc(count*sizeof(uint16));
+ uint16* q;
+ uint64* ma;
+ uint32 mb;
- o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,p);
- _TIFFfree(p);
+ if (p==NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+
+ for (q=p, ma=value, mb=0; mb<count; ma++, mb++, q++)
+ {
+ if (*ma>0xFFFF)
+ {
+ /* Should not happen normally given the check we did before */
+ TIFFErrorExt(tif->tif_clientdata,module,
+ "Attempt to write value larger than 0xFFFF in SHORT array.");
+ _TIFFfree(p);
+ return(0);
+ }
+ *q= (uint16)(*ma);
+ }
+
+ o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,count,p);
+ _TIFFfree(p);
+ }
return(o);
}
@@ -1893,12 +2026,14 @@ TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32* ndir, TIFFDirEntry* dir
n=3;
if (n==3)
{
- if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16)))
+ if (tif->tif_dir.td_transferfunction[2] == NULL ||
+ !_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16)))
n=2;
}
if (n==2)
{
- if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16)))
+ if (tif->tif_dir.td_transferfunction[1] == NULL ||
+ !_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16)))
n=1;
}
if (n==0)
@@ -2428,7 +2563,12 @@ TIFFWriteDirectoryTagData(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag
dir[m].tdir_count=count;
dir[m].tdir_offset.toff_long8 = 0;
if (datalength<=((tif->tif_flags&TIFF_BIGTIFF)?0x8U:0x4U))
- _TIFFmemcpy(&dir[m].tdir_offset,data,datalength);
+ {
+ if( data && datalength )
+ {
+ _TIFFmemcpy(&dir[m].tdir_offset,data,datalength);
+ }
+ }
else
{
uint64 na,nb;
@@ -2821,12 +2961,59 @@ _TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype,
}
/* -------------------------------------------------------------------- */
+/* When a dummy tag was written due to TIFFDeferStrileArrayWriting() */
+/* -------------------------------------------------------------------- */
+ if( entry_offset == 0 && entry_count == 0 && entry_type == 0 )
+ {
+ if( tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS )
+ {
+ entry_type = (tif->tif_flags&TIFF_BIGTIFF) ? TIFF_LONG8 : TIFF_LONG;
+ }
+ else
+ {
+ int write_aslong8 = 1;
+ if( count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS )
+ {
+ write_aslong8 = WriteAsLong8(tif, TIFFStripSize64(tif));
+ }
+ else if( count > 1 && tag == TIFFTAG_TILEBYTECOUNTS )
+ {
+ write_aslong8 = WriteAsLong8(tif, TIFFTileSize64(tif));
+ }
+ if( write_aslong8 )
+ {
+ entry_type = TIFF_LONG8;
+ }
+ else
+ {
+ int write_aslong4 = 1;
+ if( count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS )
+ {
+ write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif));
+ }
+ else if( count > 1 && tag == TIFFTAG_TILEBYTECOUNTS )
+ {
+ write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif));
+ }
+ if( write_aslong4 )
+ {
+ entry_type = TIFF_LONG;
+ }
+ else
+ {
+ entry_type = TIFF_SHORT;
+ }
+ }
+ }
+ }
+
+/* -------------------------------------------------------------------- */
/* What data type do we want to write this as? */
/* -------------------------------------------------------------------- */
if( TIFFDataWidth(in_datatype) == 8 && !(tif->tif_flags&TIFF_BIGTIFF) )
{
if( in_datatype == TIFF_LONG8 )
- datatype = TIFF_LONG;
+ datatype = entry_type == TIFF_SHORT ? TIFF_SHORT : TIFF_LONG;
else if( in_datatype == TIFF_SLONG8 )
datatype = TIFF_SLONG;
else if( in_datatype == TIFF_IFD8 )
@@ -2834,8 +3021,21 @@ _TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype,
else
datatype = in_datatype;
}
- else
- datatype = in_datatype;
+ else
+ {
+ if( in_datatype == TIFF_LONG8 &&
+ (entry_type == TIFF_SHORT || entry_type == TIFF_LONG ||
+ entry_type == TIFF_LONG8 ) )
+ datatype = entry_type;
+ else if( in_datatype == TIFF_SLONG8 &&
+ (entry_type == TIFF_SLONG || entry_type == TIFF_SLONG8 ) )
+ datatype = entry_type;
+ else if( in_datatype == TIFF_IFD8 &&
+ (entry_type == TIFF_IFD || entry_type == TIFF_IFD8 ) )
+ datatype = entry_type;
+ else
+ datatype = in_datatype;
+ }
/* -------------------------------------------------------------------- */
/* Prepare buffer of actual data to write. This includes */
@@ -2884,6 +3084,29 @@ _TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype,
}
}
}
+ else if( datatype == TIFF_SHORT && in_datatype == TIFF_LONG8 )
+ {
+ tmsize_t i;
+
+ for( i = 0; i < count; i++ )
+ {
+ ((uint16 *) buf_to_write)[i] =
+ (uint16) ((uint64 *) data)[i];
+ if( (uint64) ((uint16 *) buf_to_write)[i] != ((uint64 *) data)[i] )
+ {
+ _TIFFfree( buf_to_write );
+ TIFFErrorExt( tif->tif_clientdata, module,
+ "Value exceeds 16bit range of output type." );
+ return 0;
+ }
+ }
+ }
+ else
+ {
+ TIFFErrorExt( tif->tif_clientdata, module,
+ "Unhandled type conversion." );
+ return 0;
+ }
if( TIFFDataWidth(datatype) > 1 && (tif->tif_flags&TIFF_SWAB) )
{
@@ -2915,6 +3138,23 @@ _TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype,
}
}
+ if( (tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS) &&
+ tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 )
+ {
+ tif->tif_dir.td_stripoffset_entry.tdir_type = datatype;
+ tif->tif_dir.td_stripoffset_entry.tdir_count = count;
+ }
+ else if( (tag == TIFFTAG_TILEBYTECOUNTS || tag == TIFFTAG_STRIPBYTECOUNTS) &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 )
+ {
+ tif->tif_dir.td_stripbytecount_entry.tdir_type = datatype;
+ tif->tif_dir.td_stripbytecount_entry.tdir_count = count;
+ }
+
/* -------------------------------------------------------------------- */
/* If the tag type, and count match, then we just write it out */
/* over the old values without altering the directory entry at */
@@ -2966,6 +3206,7 @@ _TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype,
/* Adjust the directory entry. */
/* -------------------------------------------------------------------- */
entry_type = datatype;
+ entry_count = (uint64)count;
memcpy( direntry_raw + 2, &entry_type, sizeof(uint16) );
if (tif->tif_flags&TIFF_SWAB)
TIFFSwabShort( (uint16 *) (direntry_raw + 2) );
diff --git a/libtiff/tif_flush.c b/libtiff/tif_flush.c
index 881fac51..f7fa2072 100644
--- a/libtiff/tif_flush.c
+++ b/libtiff/tif_flush.c
@@ -45,36 +45,8 @@ TIFFFlush(TIFF* tif)
&& !(tif->tif_flags & TIFF_DIRTYDIRECT)
&& tif->tif_mode == O_RDWR )
{
- uint64 *offsets=NULL, *sizes=NULL;
-
- if( TIFFIsTiled(tif) )
- {
- if( TIFFGetField( tif, TIFFTAG_TILEOFFSETS, &offsets )
- && TIFFGetField( tif, TIFFTAG_TILEBYTECOUNTS, &sizes )
- && _TIFFRewriteField( tif, TIFFTAG_TILEOFFSETS, TIFF_LONG8,
- tif->tif_dir.td_nstrips, offsets )
- && _TIFFRewriteField( tif, TIFFTAG_TILEBYTECOUNTS, TIFF_LONG8,
- tif->tif_dir.td_nstrips, sizes ) )
- {
- tif->tif_flags &= ~TIFF_DIRTYSTRIP;
- tif->tif_flags &= ~TIFF_BEENWRITING;
- return 1;
- }
- }
- else
- {
- if( TIFFGetField( tif, TIFFTAG_STRIPOFFSETS, &offsets )
- && TIFFGetField( tif, TIFFTAG_STRIPBYTECOUNTS, &sizes )
- && _TIFFRewriteField( tif, TIFFTAG_STRIPOFFSETS, TIFF_LONG8,
- tif->tif_dir.td_nstrips, offsets )
- && _TIFFRewriteField( tif, TIFFTAG_STRIPBYTECOUNTS, TIFF_LONG8,
- tif->tif_dir.td_nstrips, sizes ) )
- {
- tif->tif_flags &= ~TIFF_DIRTYSTRIP;
- tif->tif_flags &= ~TIFF_BEENWRITING;
- return 1;
- }
- }
+ if( TIFFForceStrileArrayWriting(tif) )
+ return 1;
}
if ((tif->tif_flags & (TIFF_DIRTYDIRECT|TIFF_DIRTYSTRIP))
@@ -85,6 +57,92 @@ TIFFFlush(TIFF* tif)
}
/*
+ * This is an advanced writing function that must be used in a particular
+ * sequence, and together with TIFFDeferStrileArrayWriting(),
+ * to make its intended effect. Its aim is to force the writing of
+ * the [Strip/Tile][Offsets/ByteCounts] arrays at the end of the file, when
+ * they have not yet been rewritten.
+ *
+ * The typical sequence of calls is:
+ * TIFFOpen()
+ * [ TIFFCreateDirectory(tif) ]
+ * Set fields with calls to TIFFSetField(tif, ...)
+ * TIFFDeferStrileArrayWriting(tif)
+ * TIFFWriteCheck(tif, ...)
+ * TIFFWriteDirectory(tif)
+ * ... potentially create other directories and come back to the above directory
+ * TIFFForceStrileArrayWriting(tif)
+ *
+ * Returns 1 in case of success, 0 otherwise.
+ */
+int TIFFForceStrileArrayWriting(TIFF* tif)
+{
+ static const char module[] = "TIFFForceStrileArrayWriting";
+ const int isTiled = TIFFIsTiled(tif);
+
+ if (tif->tif_mode == O_RDONLY)
+ {
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "File opened in read-only mode");
+ return 0;
+ }
+ if( tif->tif_diroff == 0 )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Directory has not yet been written");
+ return 0;
+ }
+ if( (tif->tif_flags & TIFF_DIRTYDIRECT) != 0 )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Directory has changes other than the strile arrays. "
+ "TIFFRewriteDirectory() should be called instead");
+ return 0;
+ }
+
+ if( !(tif->tif_flags & TIFF_DIRTYSTRIP) )
+ {
+ if( !(tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0) )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Function not called together with "
+ "TIFFDeferStrileArrayWriting()");
+ return 0;
+ }
+
+ if (tif->tif_dir.td_stripoffset_p == NULL && !TIFFSetupStrips(tif))
+ return 0;
+ }
+
+ if( _TIFFRewriteField( tif,
+ isTiled ? TIFFTAG_TILEOFFSETS :
+ TIFFTAG_STRIPOFFSETS,
+ TIFF_LONG8,
+ tif->tif_dir.td_nstrips,
+ tif->tif_dir.td_stripoffset_p )
+ && _TIFFRewriteField( tif,
+ isTiled ? TIFFTAG_TILEBYTECOUNTS :
+ TIFFTAG_STRIPBYTECOUNTS,
+ TIFF_LONG8,
+ tif->tif_dir.td_nstrips,
+ tif->tif_dir.td_stripbytecount_p ) )
+ {
+ tif->tif_flags &= ~TIFF_DIRTYSTRIP;
+ tif->tif_flags &= ~TIFF_BEENWRITING;
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
* Flush buffered data to the file.
*
* Frank Warmerdam'2000: I modified this to return 1 if TIFF_BEENWRITING
diff --git a/libtiff/tif_getimage.c b/libtiff/tif_getimage.c
index 6a9d5a7c..4da785d3 100644
--- a/libtiff/tif_getimage.c
+++ b/libtiff/tif_getimage.c
@@ -755,9 +755,8 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
uint32 leftmost_tw;
tilesize = TIFFTileSize(tif);
- bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,tilesize);
+ bufsize = _TIFFMultiplySSize(tif, alpha?4:3,tilesize, "gtTileSeparate");
if (bufsize == 0) {
- TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtTileSeparate");
return (0);
}
@@ -950,16 +949,23 @@ gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
fromskew = (w < imagewidth ? imagewidth - w : 0);
for (row = 0; row < h; row += nrow)
{
+ uint32 temp;
rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
nrow = (row + rowstoread > h ? h - row : rowstoread);
nrowsub = nrow;
if ((nrowsub%subsamplingver)!=0)
nrowsub+=subsamplingver-nrowsub%subsamplingver;
+ temp = (row + img->row_offset)%rowsperstrip + nrowsub;
+ if( scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline) )
+ {
+ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in gtStripContig");
+ return 0;
+ }
if (_TIFFReadEncodedStripAndAllocBuffer(tif,
TIFFComputeStrip(tif,row+img->row_offset, 0),
(void**)(&buf),
maxstripsize,
- ((row + img->row_offset)%rowsperstrip + nrowsub) * scanline)==(tmsize_t)(-1)
+ temp * scanline)==(tmsize_t)(-1)
&& (buf == NULL || img->stoponerr))
{
ret = 0;
@@ -1019,9 +1025,8 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
uint16 colorchannels;
stripsize = TIFFStripSize(tif);
- bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,stripsize);
+ bufsize = _TIFFMultiplySSize(tif,alpha?4:3,stripsize, "gtStripSeparate");
if (bufsize == 0) {
- TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtStripSeparate");
return (0);
}
@@ -1053,15 +1058,22 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
fromskew = (w < imagewidth ? imagewidth - w : 0);
for (row = 0; row < h; row += nrow)
{
+ uint32 temp;
rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
nrow = (row + rowstoread > h ? h - row : rowstoread);
offset_row = row + img->row_offset;
+ temp = (row + img->row_offset)%rowsperstrip + nrow;
+ if( scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline) )
+ {
+ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in gtStripSeparate");
+ return 0;
+ }
if( buf == NULL )
{
if (_TIFFReadEncodedStripAndAllocBuffer(
tif, TIFFComputeStrip(tif, offset_row, 0),
(void**) &buf, bufsize,
- ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
+ temp * scanline)==(tmsize_t)(-1)
&& (buf == NULL || img->stoponerr))
{
ret = 0;
@@ -1081,7 +1093,7 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
}
}
else if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0),
- p0, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
+ p0, temp * scanline)==(tmsize_t)(-1)
&& img->stoponerr)
{
ret = 0;
@@ -1089,7 +1101,7 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
}
if (colorchannels > 1
&& TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1),
- p1, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) == (tmsize_t)(-1)
+ p1, temp * scanline) == (tmsize_t)(-1)
&& img->stoponerr)
{
ret = 0;
@@ -1097,7 +1109,7 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
}
if (colorchannels > 1
&& TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2),
- p2, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) == (tmsize_t)(-1)
+ p2, temp * scanline) == (tmsize_t)(-1)
&& img->stoponerr)
{
ret = 0;
@@ -1106,7 +1118,7 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
if (alpha)
{
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, colorchannels),
- pa, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
+ pa, temp * scanline)==(tmsize_t)(-1)
&& img->stoponerr)
{
ret = 0;
@@ -2957,7 +2969,7 @@ TIFFReadRGBATileExt(TIFF* tif, uint32 col, uint32 row, uint32 * raster, int stop
if( !TIFFIsTiled( tif ) )
{
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
- "Can't use TIFFReadRGBATile() with stripped file.");
+ "Can't use TIFFReadRGBATile() with striped file.");
return (0);
}
diff --git a/libtiff/tif_jpeg.c b/libtiff/tif_jpeg.c
index f2ddc331..93ae2ead 100644
--- a/libtiff/tif_jpeg.c
+++ b/libtiff/tif_jpeg.c
@@ -780,12 +780,9 @@ JPEGFixupTagsSubsampling(TIFF* tif)
*/
static const char module[] = "JPEGFixupTagsSubsampling";
struct JPEGFixupTagsSubsamplingData m;
+ uint64 fileoffset = TIFFGetStrileOffset(tif, 0);
- _TIFFFillStriles( tif );
-
- if( tif->tif_dir.td_stripbytecount == NULL
- || tif->tif_dir.td_stripoffset == NULL
- || tif->tif_dir.td_stripbytecount[0] == 0 )
+ if( fileoffset == 0 )
{
/* Do not even try to check if the first strip/tile does not
yet exist, as occurs when GDAL has created a new NULL file
@@ -804,9 +801,9 @@ JPEGFixupTagsSubsampling(TIFF* tif)
}
m.buffercurrentbyte=NULL;
m.bufferbytesleft=0;
- m.fileoffset=tif->tif_dir.td_stripoffset[0];
+ m.fileoffset=fileoffset;
m.filepositioned=0;
- m.filebytesleft=tif->tif_dir.td_stripbytecount[0];
+ m.filebytesleft=TIFFGetStrileByteCount(tif, 0);
if (!JPEGFixupTagsSubsamplingSec(&m))
TIFFWarningExt(tif->tif_clientdata,module,
"Unable to auto-correct subsampling values, likely corrupt JPEG compressed data in first strip/tile; auto-correcting skipped");
@@ -1566,7 +1563,7 @@ JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
JSAMPLE *outptr = (JSAMPLE*)tmpbuf + clumpoffset;
#else
JSAMPLE *outptr = (JSAMPLE*)buf + clumpoffset;
- if (cc < (tmsize_t) (clumpoffset + samples_per_clump*(clumps_per_line-1) + hsamp)) {
+ if (cc < (tmsize_t)(clumpoffset + (tmsize_t)samples_per_clump*(clumps_per_line-1) + hsamp)) {
TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw",
"application buffer not large enough for all data, possible subsampling issue");
return 0;
@@ -2126,8 +2123,8 @@ JPEGEncodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
/* data is expected to be supplied in multiples of a clumpline */
/* a clumpline is equivalent to v_sampling desubsampled scanlines */
/* TODO: the following calculation of bytesperclumpline, should substitute calculation of sp->bytesperline, except that it is per v_sampling lines */
- bytesperclumpline = (((sp->cinfo.c.image_width+sp->h_sampling-1)/sp->h_sampling)
- *(sp->h_sampling*sp->v_sampling+2)*sp->cinfo.c.data_precision+7)
+ bytesperclumpline = ((((tmsize_t)sp->cinfo.c.image_width+sp->h_sampling-1)/sp->h_sampling)
+ *((tmsize_t)sp->h_sampling*sp->v_sampling+2)*sp->cinfo.c.data_precision+7)
/8;
nrows = ( cc / bytesperclumpline ) * sp->v_sampling;
diff --git a/libtiff/tif_luv.c b/libtiff/tif_luv.c
index aa35ea07..6fe48588 100644
--- a/libtiff/tif_luv.c
+++ b/libtiff/tif_luv.c
@@ -742,9 +742,14 @@ LogLuvEncodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
#undef exp2 /* Conflict with C'99 function */
#define exp2(x) exp(M_LN2*(x))
-#define itrunc(x,m) ((m)==SGILOGENCODE_NODITHER ? \
- (int)(x) : \
- (int)((x) + rand()*(1./RAND_MAX) - .5))
+static int itrunc(double x, int m)
+{
+ if( m == SGILOGENCODE_NODITHER )
+ return (int)x;
+ /* Silence CoverityScan warning about bad crypto function */
+ /* coverity[dont_call] */
+ return (int)(x + rand()*(1./RAND_MAX) - .5);
+}
#if !LOGLUV_PUBLIC
static
@@ -1264,16 +1269,10 @@ LogL16GuessDataFmt(TIFFDirectory *td)
return (SGILOGDATAFMT_UNKNOWN);
}
-
-#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0))
-#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1)
-
static tmsize_t
multiply_ms(tmsize_t m1, tmsize_t m2)
{
- if( m1 == 0 || m2 > TIFF_TMSIZE_T_MAX / m1 )
- return 0;
- return m1 * m2;
+ return _TIFFMultiplySSize(NULL, m1, m2, NULL);
}
static int
@@ -1507,7 +1506,7 @@ LogLuvSetupEncode(TIFF* tif)
switch (td->td_photometric) {
case PHOTOMETRIC_LOGLUV:
if (!LogLuvInitState(tif))
- break;
+ return (0);
if (td->td_compression == COMPRESSION_SGILOG24) {
tif->tif_encoderow = LogLuvEncode24;
switch (sp->user_datafmt) {
@@ -1540,7 +1539,7 @@ LogLuvSetupEncode(TIFF* tif)
break;
case PHOTOMETRIC_LOGL:
if (!LogL16InitState(tif))
- break;
+ return (0);
tif->tif_encoderow = LogL16Encode;
switch (sp->user_datafmt) {
case SGILOGDATAFMT_FLOAT:
@@ -1556,7 +1555,7 @@ LogLuvSetupEncode(TIFF* tif)
TIFFErrorExt(tif->tif_clientdata, module,
"Inappropriate photometric interpretation %d for SGILog compression; %s",
td->td_photometric, "must be either LogLUV or LogL");
- break;
+ return (0);
}
sp->encoder_state = 1;
return (1);
diff --git a/libtiff/tif_lzw.c b/libtiff/tif_lzw.c
index ac685dd7..21064f29 100644
--- a/libtiff/tif_lzw.c
+++ b/libtiff/tif_lzw.c
@@ -247,6 +247,8 @@ LZWSetupDecode(TIFF* tif)
/*
* Zero-out the unused entries
*/
+ /* Silence false positive */
+ /* coverity[overrun-buffer-arg] */
_TIFFmemset(&sp->dec_codetab[CODE_CLEAR], 0,
(CODE_FIRST - CODE_CLEAR) * sizeof (code_t));
}
diff --git a/libtiff/tif_ojpeg.c b/libtiff/tif_ojpeg.c
index 27385d8c..aa5ff5e2 100644
--- a/libtiff/tif_ojpeg.c
+++ b/libtiff/tif_ojpeg.c
@@ -243,6 +243,7 @@ typedef enum {
typedef struct {
TIFF* tif;
int decoder_ok;
+ int error_in_raw_data_decoding;
#ifndef LIBJPEG_ENCAP_EXTERNAL
JMP_BUF exit_jmpbuf;
#endif
@@ -678,7 +679,7 @@ OJPEGPreDecode(TIFF* tif, uint16 s)
if (OJPEGReadSecondarySos(tif,s)==0)
return(0);
}
- if isTiled(tif)
+ if (isTiled(tif))
m=tif->tif_curtile;
else
m=tif->tif_curstrip;
@@ -742,6 +743,7 @@ OJPEGPreDecodeSkipRaw(TIFF* tif)
}
m-=sp->subsampling_convert_clines-sp->subsampling_convert_state;
sp->subsampling_convert_state=0;
+ sp->error_in_raw_data_decoding=0;
}
while (m>=sp->subsampling_convert_clines)
{
@@ -792,6 +794,10 @@ OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
TIFFErrorExt(tif->tif_clientdata,module,"Cannot decode: decoder not correctly initialized");
return 0;
}
+ if( sp->error_in_raw_data_decoding )
+ {
+ return 0;
+ }
if (sp->libjpeg_jpeg_query_style==0)
{
if (OJPEGDecodeRaw(tif,buf,cc)==0)
@@ -832,7 +838,10 @@ OJPEGDecodeRaw(TIFF* tif, uint8* 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)
+ {
+ sp->error_in_raw_data_decoding = 1;
return(0);
+ }
}
oy=sp->subsampling_convert_ybuf+sp->subsampling_convert_state*sp->subsampling_ver*sp->subsampling_convert_ylinelen;
ocb=sp->subsampling_convert_cbbuf+sp->subsampling_convert_state*sp->subsampling_convert_clinelen;
@@ -990,7 +999,6 @@ OJPEGSubsamplingCorrect(TIFF* tif)
OJPEGState* sp=(OJPEGState*)tif->tif_data;
uint8 mh;
uint8 mv;
- _TIFFFillStriles( tif );
assert(sp->subsamplingcorrect_done==0);
if ((tif->tif_dir.td_samplesperpixel!=3) || ((tif->tif_dir.td_photometric!=PHOTOMETRIC_YCBCR) &&
@@ -1046,7 +1054,7 @@ OJPEGReadHeaderInfo(TIFF* tif)
assert(sp->readheader_done==0);
sp->image_width=tif->tif_dir.td_imagewidth;
sp->image_length=tif->tif_dir.td_imagelength;
- if isTiled(tif)
+ if (isTiled(tif))
{
sp->strile_width=tif->tif_dir.td_tilewidth;
sp->strile_length=tif->tif_dir.td_tilelength;
@@ -1056,6 +1064,8 @@ OJPEGReadHeaderInfo(TIFF* tif)
{
sp->strile_width=sp->image_width;
sp->strile_length=tif->tif_dir.td_rowsperstrip;
+ if( sp->strile_length == (uint32)-1 )
+ sp->strile_length = sp->image_length;
sp->strile_length_total=sp->image_length;
}
if (tif->tif_dir.td_samplesperpixel==1)
@@ -1082,6 +1092,12 @@ OJPEGReadHeaderInfo(TIFF* tif)
}
if (sp->strile_length<sp->image_length)
{
+ if (((sp->subsampling_hor!=1) && (sp->subsampling_hor!=2) && (sp->subsampling_hor!=4)) ||
+ ((sp->subsampling_ver!=1) && (sp->subsampling_ver!=2) && (sp->subsampling_ver!=4)))
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Invalid subsampling values");
+ return(0);
+ }
if (sp->strile_length%(sp->subsampling_ver*8)!=0)
{
TIFFErrorExt(tif->tif_clientdata,module,"Incompatible vertical subsampling and image strip/tile length");
@@ -1197,7 +1213,13 @@ OJPEGWriteHeaderInfo(TIFF* tif)
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;
- sp->subsampling_convert_ycbcrbuf=_TIFFmalloc(sp->subsampling_convert_ycbcrbuflen);
+ /* The calloc is not normally necessary, except in some edge/broken cases */
+ /* for example for a tiled image of height 1 with a tile height of 1 and subsampling_hor=subsampling_ver=2 */
+ /* In that case, libjpeg will only fill the 8 first lines of the 16 lines */
+ /* See https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16844 */
+ /* Even if this case is allowed (?), its handling is broken because OJPEGPreDecode() should also likely */
+ /* reset subsampling_convert_state to 0 when changing tile. */
+ sp->subsampling_convert_ycbcrbuf=_TIFFcalloc(1, sp->subsampling_convert_ycbcrbuflen);
if (sp->subsampling_convert_ycbcrbuf==0)
{
TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
@@ -1223,10 +1245,11 @@ OJPEGWriteHeaderInfo(TIFF* tif)
*m++=sp->subsampling_convert_cbbuf+n*sp->subsampling_convert_clinelen;
for (n=0; n<sp->subsampling_convert_clines; n++)
*m++=sp->subsampling_convert_crbuf+n*sp->subsampling_convert_clinelen;
- sp->subsampling_convert_clinelenout=((sp->strile_width+sp->subsampling_hor-1)/sp->subsampling_hor);
+ sp->subsampling_convert_clinelenout=sp->strile_width/sp->subsampling_hor + ((sp->strile_width % sp->subsampling_hor) != 0 ? 1 : 0);
sp->subsampling_convert_state=0;
+ sp->error_in_raw_data_decoding=0;
sp->bytes_per_line=sp->subsampling_convert_clinelenout*(sp->subsampling_ver*sp->subsampling_hor+2);
- sp->lines_per_strile=((sp->strile_length+sp->subsampling_ver-1)/sp->subsampling_ver);
+ sp->lines_per_strile=sp->strile_length/sp->subsampling_ver + ((sp->strile_length % sp->subsampling_ver) != 0 ? 1 : 0);
sp->subsampling_convert_log=1;
}
}
@@ -1240,6 +1263,29 @@ OJPEGWriteHeaderInfo(TIFF* tif)
}
if (jpeg_start_decompress_encap(sp,&(sp->libjpeg_jpeg_decompress_struct))==0)
return(0);
+ if(sp->libjpeg_jpeg_decompress_struct.image_width != sp->strile_width ||
+ sp->libjpeg_jpeg_decompress_struct.image_height < sp->strile_length) {
+ TIFFErrorExt(tif->tif_clientdata,module,
+ "jpeg_start_decompress() returned image_width = %d "
+ "and image_height = %d, expected %d and %d",
+ sp->libjpeg_jpeg_decompress_struct.image_width,
+ sp->libjpeg_jpeg_decompress_struct.image_height,
+ sp->strile_width,
+ sp->strile_length);
+ return 0;
+ }
+ if(sp->libjpeg_jpeg_decompress_struct.max_h_samp_factor != sp->subsampling_hor ||
+ sp->libjpeg_jpeg_decompress_struct.max_v_samp_factor != sp->subsampling_ver) {
+ TIFFErrorExt(tif->tif_clientdata,module,
+ "jpeg_start_decompress() returned max_h_samp_factor = %d "
+ "and max_v_samp_factor = %d, expected %d and %d",
+ sp->libjpeg_jpeg_decompress_struct.max_h_samp_factor,
+ sp->libjpeg_jpeg_decompress_struct.max_v_samp_factor,
+ sp->subsampling_hor,
+ sp->subsampling_ver);
+ return 0;
+ }
+
sp->writeheader_done=1;
return(1);
}
@@ -1272,7 +1318,9 @@ OJPEGReadHeaderInfoSec(TIFF* tif)
}
else
{
- if ((sp->jpeg_interchange_format_length==0) || (sp->jpeg_interchange_format+sp->jpeg_interchange_format_length>sp->file_size))
+ if ((sp->jpeg_interchange_format_length==0) ||
+ (sp->jpeg_interchange_format > TIFF_UINT64_MAX - sp->jpeg_interchange_format_length) ||
+ (sp->jpeg_interchange_format+sp->jpeg_interchange_format_length>sp->file_size))
sp->jpeg_interchange_format_length=sp->file_size-sp->jpeg_interchange_format;
}
}
@@ -1989,32 +2037,30 @@ OJPEGReadBufferFill(OJPEGState* sp)
sp->in_buffer_source=osibsStrile;
break;
case osibsStrile:
- if (!_TIFFFillStriles( sp->tif )
- || sp->tif->tif_dir.td_stripoffset == NULL
- || sp->tif->tif_dir.td_stripbytecount == NULL)
- return 0;
-
if (sp->in_buffer_next_strile==sp->in_buffer_strile_count)
sp->in_buffer_source=osibsEof;
else
{
- sp->in_buffer_file_pos=sp->tif->tif_dir.td_stripoffset[sp->in_buffer_next_strile];
+ int err = 0;
+ sp->in_buffer_file_pos=TIFFGetStrileOffsetWithErr(sp->tif, sp->in_buffer_next_strile, &err);
+ if( err )
+ return 0;
if (sp->in_buffer_file_pos!=0)
{
+ uint64 bytecount = TIFFGetStrileByteCountWithErr(sp->tif, sp->in_buffer_next_strile, &err);
+ if( err )
+ return 0;
if (sp->in_buffer_file_pos>=sp->file_size)
sp->in_buffer_file_pos=0;
- else if (sp->tif->tif_dir.td_stripbytecount==NULL)
+ else if (bytecount==0)
sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos;
else
{
- if (sp->tif->tif_dir.td_stripbytecount == 0) {
- TIFFErrorExt(sp->tif->tif_clientdata,sp->tif->tif_name,"Strip byte counts are missing");
- return(0);
- }
- sp->in_buffer_file_togo=sp->tif->tif_dir.td_stripbytecount[sp->in_buffer_next_strile];
+ sp->in_buffer_file_togo=bytecount;
if (sp->in_buffer_file_togo==0)
sp->in_buffer_file_pos=0;
- else if (sp->in_buffer_file_pos+sp->in_buffer_file_togo>sp->file_size)
+ else if (sp->in_buffer_file_pos > TIFF_UINT64_MAX - sp->in_buffer_file_togo ||
+ sp->in_buffer_file_pos+sp->in_buffer_file_togo>sp->file_size)
sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos;
}
}
diff --git a/libtiff/tif_open.c b/libtiff/tif_open.c
index c574c452..3cb53d4e 100644
--- a/libtiff/tif_open.c
+++ b/libtiff/tif_open.c
@@ -131,6 +131,7 @@ TIFFClientOpen(
if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc) {
TIFFErrorExt(clientdata, module,
"One of the client procedures is NULL pointer.");
+ _TIFFfree(tif);
goto bad2;
}
tif->tif_readproc = readproc;
@@ -181,6 +182,8 @@ TIFFClientOpen(
* 'h' read TIFF header only, do not load the first IFD
* '4' ClassicTIFF for creating a file (default)
* '8' BigTIFF for creating a file
+ * 'D' enable use of deferred strip/tile offset/bytecount array loading.
+ * 'O' on-demand loading of values instead of whole array loading (implies D)
*
* The use of the 'l' and 'b' flags is strongly discouraged.
* These flags are provided solely because numerous vendors,
@@ -262,7 +265,22 @@ TIFFClientOpen(
if (m&O_CREAT)
tif->tif_flags |= TIFF_BIGTIFF;
break;
+ case 'D':
+ tif->tif_flags |= TIFF_DEFERSTRILELOAD;
+ break;
+ case 'O':
+ if( m == O_RDONLY )
+ tif->tif_flags |= (TIFF_LAZYSTRILELOAD | TIFF_DEFERSTRILELOAD);
+ break;
}
+
+#ifdef DEFER_STRILE_LOAD
+ /* Compatibility with old DEFER_STRILE_LOAD compilation flag */
+ /* Probably unneeded, since to the best of my knowledge (E. Rouault) */
+ /* GDAL was the only user of this, and will now use the new 'D' flag */
+ tif->tif_flags |= TIFF_DEFERSTRILELOAD;
+#endif
+
/*
* Read in TIFF header.
*/
diff --git a/libtiff/tif_pixarlog.c b/libtiff/tif_pixarlog.c
index 77620e3d..62640905 100644
--- a/libtiff/tif_pixarlog.c
+++ b/libtiff/tif_pixarlog.c
@@ -634,20 +634,16 @@ PixarLogGuessDataFmt(TIFFDirectory *td)
return guess;
}
-#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0))
-#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1)
-
static tmsize_t
multiply_ms(tmsize_t m1, tmsize_t m2)
{
- if( m1 == 0 || m2 > TIFF_TMSIZE_T_MAX / m1 )
- return 0;
- return m1 * m2;
+ return _TIFFMultiplySSize(NULL, m1, m2, NULL);
}
static tmsize_t
add_ms(tmsize_t m1, tmsize_t m2)
{
+ assert(m1 >= 0 && m2 >= 0);
/* if either input is zero, assume overflow already occurred */
if (m1 == 0 || m2 == 0)
return 0;
@@ -817,9 +813,7 @@ PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
TIFFErrorExt(tif->tif_clientdata, module,
"Decoding error at scanline %lu, %s",
(unsigned long) tif->tif_row, sp->stream.msg ? sp->stream.msg : "(null)");
- /* if (inflateSync(&sp->stream) != Z_OK) */
return (0);
- continue;
}
if (state != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
@@ -1153,7 +1147,7 @@ PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
llen = sp->stride * td->td_imagewidth;
/* Check against the number of elements (of size uint16) of sp->tbuf */
- if( n > (tmsize_t)(td->td_rowsperstrip * llen) )
+ if( n > ((tmsize_t)td->td_rowsperstrip * llen) )
{
TIFFErrorExt(tif->tif_clientdata, module,
"Too many input bytes provided");
diff --git a/libtiff/tif_print.c b/libtiff/tif_print.c
index 1d86adbf..a0737941 100644
--- a/libtiff/tif_print.c
+++ b/libtiff/tif_print.c
@@ -652,8 +652,6 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
if (tif->tif_tagmethods.printdir)
(*tif->tif_tagmethods.printdir)(tif, fd, flags);
- _TIFFFillStriles( tif );
-
if ((flags & TIFFPRINT_STRIPS) &&
TIFFFieldSet(tif,FIELD_STRIPOFFSETS)) {
uint32 s;
@@ -665,13 +663,13 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
fprintf(fd, " %3lu: [%8I64u, %8I64u]\n",
(unsigned long) s,
- td->td_stripoffset ? (unsigned __int64) td->td_stripoffset[s] : 0,
- td->td_stripbytecount ? (unsigned __int64) td->td_stripbytecount[s] : 0);
+ (unsigned __int64) TIFFGetStrileOffset(tif, s),
+ (unsigned __int64) TIFFGetStrileByteCount(tif, s));
#else
fprintf(fd, " %3lu: [%8llu, %8llu]\n",
(unsigned long) s,
- td->td_stripoffset ? (unsigned long long) td->td_stripoffset[s] : 0,
- td->td_stripbytecount ? (unsigned long long) td->td_stripbytecount[s] : 0);
+ (unsigned long long) TIFFGetStrileOffset(tif, s),
+ (unsigned long long) TIFFGetStrileByteCount(tif, s));
#endif
}
}
diff --git a/libtiff/tif_read.c b/libtiff/tif_read.c
index e63810cc..527fadd6 100644
--- a/libtiff/tif_read.c
+++ b/libtiff/tif_read.c
@@ -29,9 +29,6 @@
#include "tiffiop.h"
#include <stdio.h>
-#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0))
-#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1)
-
int TIFFFillStrip(TIFF* tif, uint32 strip);
int TIFFFillTile(TIFF* tif, uint32 tile);
static int TIFFStartStrip(TIFF* tif, uint32 strip);
@@ -49,6 +46,8 @@ TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* m
#define THRESHOLD_MULTIPLIER 10
#define MAX_THRESHOLD (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * INITIAL_THRESHOLD)
+#define TIFF_INT64_MAX ((((int64)0x7FFFFFFF) << 32) | 0xFFFFFFFF)
+
/* Read 'size' bytes in tif_rawdata buffer starting at offset 'rawdata_offset'
* Returns 1 in case of success, 0 otherwise. */
static int TIFFReadAndRealloc( TIFF* tif, tmsize_t size,
@@ -61,6 +60,22 @@ static int TIFFReadAndRealloc( TIFF* tif, tmsize_t size,
#endif
tmsize_t already_read = 0;
+
+#if SIZEOF_SIZE_T != 8
+ /* On 32 bit processes, if the request is large enough, check against */
+ /* file size */
+ if( size > 1000 * 1000 * 1000 )
+ {
+ uint64 filesize = TIFFGetFileSize(tif);
+ if( (uint64)size >= filesize )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Chunk size requested is larger than file size.");
+ return 0;
+ }
+ }
+#endif
+
/* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */
/* so as to avoid allocating too much memory in case the file is too */
/* short. We could ask for the file size, but this might be */
@@ -103,6 +118,11 @@ static int TIFFReadAndRealloc( TIFF* tif, tmsize_t size,
}
tif->tif_rawdata = new_rawdata;
}
+ if( tif->tif_rawdata == NULL )
+ {
+ /* should not happen in practice but helps CoverityScan */
+ return 0;
+ }
bytes_read = TIFFReadFile(tif,
tif->tif_rawdata + rawdata_offset + already_read, to_read);
@@ -170,17 +190,14 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
tmsize_t to_read;
tmsize_t read_ahead_mod;
/* tmsize_t bytecountm; */
-
- if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
- return 0;
-
+
/*
* Expand raw data buffer, if needed, to hold data
* strip coming from file (perhaps should set upper
* bound on the size of a buffer we'll use?).
*/
- /* bytecountm=(tmsize_t) td->td_stripbytecount[strip]; */
+ /* bytecountm=(tmsize_t) TIFFGetStrileByteCount(tif, strip); */
/* Not completely sure where the * 2 comes from, but probably for */
/* an exponentional growth strategy of tif_rawdatasize */
@@ -224,7 +241,7 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
/*
** Seek to the point in the file where more data should be read.
*/
- read_offset = td->td_stripoffset[strip]
+ read_offset = TIFFGetStrileOffset(tif, strip)
+ tif->tif_rawdataoff + tif->tif_rawdataloaded;
if (!SeekOK(tif, read_offset)) {
@@ -241,10 +258,10 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
to_read = read_ahead_mod - unused_data;
else
to_read = tif->tif_rawdatasize - unused_data;
- if( (uint64) to_read > td->td_stripbytecount[strip]
+ if( (uint64) to_read > TIFFGetStrileByteCount(tif, strip)
- tif->tif_rawdataoff - tif->tif_rawdataloaded )
{
- to_read = (tmsize_t) td->td_stripbytecount[strip]
+ to_read = (tmsize_t) TIFFGetStrileByteCount(tif, strip)
- tif->tif_rawdataoff - tif->tif_rawdataloaded;
}
@@ -283,7 +300,7 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
/* 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)tif->tif_rawcc < td->td_stripbytecount[strip] )
+ (uint64)tif->tif_rawcc < TIFFGetStrileByteCount(tif, strip) )
{
if( TIFFJPEGIsFullStripRequired(tif) )
{
@@ -342,9 +359,7 @@ TIFFSeek(TIFF* tif, uint32 row, uint16 sample )
* read it a few lines at a time?
*/
#if defined(CHUNKY_STRIP_READ_SUPPORT)
- if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
- return 0;
- whole_strip = tif->tif_dir.td_stripbytecount[strip] < 10
+ whole_strip = TIFFGetStrileByteCount(tif, strip) < 10
|| isMapped(tif);
if( td->td_compression == COMPRESSION_LERC ||
td->td_compression == COMPRESSION_JBIG )
@@ -397,7 +412,7 @@ TIFFSeek(TIFF* tif, uint32 row, uint16 sample )
else if( !whole_strip )
{
if( ((tif->tif_rawdata + tif->tif_rawdataloaded) - tif->tif_rawcp) < read_ahead
- && (uint64) tif->tif_rawdataoff+tif->tif_rawdataloaded < td->td_stripbytecount[strip] )
+ && (uint64) tif->tif_rawdataoff+tif->tif_rawdataloaded < TIFFGetStrileByteCount(tif, strip) )
{
if( !TIFFFillStripPartial(tif,strip,read_ahead,0) )
return 0;
@@ -594,16 +609,11 @@ static tmsize_t
TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,
const char* module)
{
- TIFFDirectory *td = &tif->tif_dir;
-
- if (!_TIFFFillStriles( tif ))
- return ((tmsize_t)(-1));
-
assert((tif->tif_flags&TIFF_NOREADRAW)==0);
if (!isMapped(tif)) {
tmsize_t cc;
- if (!SeekOK(tif, td->td_stripoffset[strip])) {
+ if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip))) {
TIFFErrorExt(tif->tif_clientdata, module,
"Seek error at scanline %lu, strip %lu",
(unsigned long) tif->tif_row, (unsigned long) strip);
@@ -629,8 +639,8 @@ TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,
} else {
tmsize_t ma = 0;
tmsize_t n;
- if ((td->td_stripoffset[strip] > (uint64)TIFF_TMSIZE_T_MAX)||
- ((ma=(tmsize_t)td->td_stripoffset[strip])>tif->tif_size))
+ if ((TIFFGetStrileOffset(tif, strip) > (uint64)TIFF_TMSIZE_T_MAX)||
+ ((ma=(tmsize_t)TIFFGetStrileOffset(tif, strip))>tif->tif_size))
{
n=0;
}
@@ -674,12 +684,10 @@ static tmsize_t
TIFFReadRawStripOrTile2(TIFF* tif, uint32 strip_or_tile, int is_strip,
tmsize_t size, const char* module)
{
- TIFFDirectory *td = &tif->tif_dir;
-
assert( !isMapped(tif) );
assert((tif->tif_flags&TIFF_NOREADRAW)==0);
- if (!SeekOK(tif, td->td_stripoffset[strip_or_tile])) {
+ if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip_or_tile))) {
if( is_strip )
{
TIFFErrorExt(tif->tif_clientdata, module,
@@ -715,7 +723,7 @@ TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
{
static const char module[] = "TIFFReadRawStrip";
TIFFDirectory *td = &tif->tif_dir;
- uint64 bytecount;
+ uint64 bytecount64;
tmsize_t bytecountm;
if (!TIFFCheckRead(tif, 0))
@@ -733,31 +741,23 @@ TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
"Compression scheme does not support access to raw uncompressed data");
return ((tmsize_t)(-1));
}
- bytecount = td->td_stripbytecount[strip];
- if ((int64)bytecount <= 0) {
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
- TIFFErrorExt(tif->tif_clientdata, module,
- "%I64u: Invalid strip byte count, strip %lu",
- (unsigned __int64) bytecount,
- (unsigned long) strip);
-#else
- TIFFErrorExt(tif->tif_clientdata, module,
- "%llu: Invalid strip byte count, strip %lu",
- (unsigned long long) bytecount,
- (unsigned long) strip);
-#endif
- return ((tmsize_t)(-1));
- }
- bytecountm = (tmsize_t)bytecount;
- if ((uint64)bytecountm!=bytecount) {
- TIFFErrorExt(tif->tif_clientdata, module, "Integer overflow");
+ bytecount64 = TIFFGetStrileByteCount(tif, strip);
+ if (size != (tmsize_t)(-1) && (uint64)size <= bytecount64)
+ bytecountm = size;
+ else
+ bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module);
+ if( bytecountm == 0 ) {
return ((tmsize_t)(-1));
}
- if (size != (tmsize_t)(-1) && size < bytecountm)
- bytecountm = size;
return (TIFFReadRawStrip1(tif, strip, buf, bytecountm, module));
}
+TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
+static uint64 NoSantizeSubUInt64(uint64 a, uint64 b)
+{
+ return a - b;
+}
+
/*
* Read the specified strip and setup for decoding. The data buffer is
* expanded, as necessary, to hold the strip's data.
@@ -768,13 +768,10 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
static const char module[] = "TIFFFillStrip";
TIFFDirectory *td = &tif->tif_dir;
- if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
- return 0;
-
if ((tif->tif_flags&TIFF_NOREADRAW)==0)
{
- uint64 bytecount = td->td_stripbytecount[strip];
- if ((int64)bytecount <= 0) {
+ uint64 bytecount = TIFFGetStrileByteCount(tif, strip);
+ if( bytecount == 0 || bytecount > (uint64)TIFF_INT64_MAX ) {
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFErrorExt(tif->tif_clientdata, module,
"Invalid strip byte count %I64u, strip %lu",
@@ -801,7 +798,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
(bytecount - 4096) / 10 > (uint64)stripsize )
{
uint64 newbytecount = (uint64)stripsize * 10 + 4096;
- if( (int64)newbytecount >= 0 )
+ if( newbytecount == 0 || newbytecount > (uint64)TIFF_INT64_MAX )
{
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFWarningExt(tif->tif_clientdata, module,
@@ -826,13 +823,13 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
* We must check for overflow, potentially causing
* an OOB read. Instead of simple
*
- * td->td_stripoffset[strip]+bytecount > tif->tif_size
+ * TIFFGetStrileOffset(tif, strip)+bytecount > tif->tif_size
*
* comparison (which can overflow) we do the following
* two comparisons:
*/
if (bytecount > (uint64)tif->tif_size ||
- td->td_stripoffset[strip] > (uint64)tif->tif_size - bytecount) {
+ TIFFGetStrileOffset(tif, strip) > (uint64)tif->tif_size - bytecount) {
/*
* This error message might seem strange, but
* it's what would happen if a read were done
@@ -844,7 +841,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
"Read error on strip %lu; "
"got %I64u bytes, expected %I64u",
(unsigned long) strip,
- (unsigned __int64) tif->tif_size - td->td_stripoffset[strip],
+ (unsigned __int64) NoSantizeSubUInt64(tif->tif_size, TIFFGetStrileOffset(tif, strip)),
(unsigned __int64) bytecount);
#else
TIFFErrorExt(tif->tif_clientdata, module,
@@ -852,7 +849,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
"Read error on strip %lu; "
"got %llu bytes, expected %llu",
(unsigned long) strip,
- (unsigned long long) tif->tif_size - td->td_stripoffset[strip],
+ (unsigned long long) NoSantizeSubUInt64(tif->tif_size, TIFFGetStrileOffset(tif, strip)),
(unsigned long long) bytecount);
#endif
tif->tif_curstrip = NOSTRIP;
@@ -881,7 +878,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
}
tif->tif_flags &= ~TIFF_MYBUFFER;
tif->tif_rawdatasize = (tmsize_t)bytecount;
- tif->tif_rawdata = tif->tif_base + (tmsize_t)td->td_stripoffset[strip];
+ tif->tif_rawdata = tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, strip);
tif->tif_rawdataoff = 0;
tif->tif_rawdataloaded = (tmsize_t) bytecount;
@@ -1096,16 +1093,11 @@ _TIFFReadEncodedTileAndAllocBuffer(TIFF* tif, uint32 tile,
static tmsize_t
TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* module)
{
- TIFFDirectory *td = &tif->tif_dir;
-
- if (!_TIFFFillStriles( tif ))
- return ((tmsize_t)(-1));
-
assert((tif->tif_flags&TIFF_NOREADRAW)==0);
if (!isMapped(tif)) {
tmsize_t cc;
- if (!SeekOK(tif, td->td_stripoffset[tile])) {
+ if (!SeekOK(tif, TIFFGetStrileOffset(tif, tile))) {
TIFFErrorExt(tif->tif_clientdata, module,
"Seek error at row %lu, col %lu, tile %lu",
(unsigned long) tif->tif_row,
@@ -1135,9 +1127,9 @@ TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* m
} else {
tmsize_t ma,mb;
tmsize_t n;
- ma=(tmsize_t)td->td_stripoffset[tile];
+ ma=(tmsize_t)TIFFGetStrileOffset(tif, tile);
mb=ma+size;
- if ((td->td_stripoffset[tile] > (uint64)TIFF_TMSIZE_T_MAX)||(ma>tif->tif_size))
+ if ((TIFFGetStrileOffset(tif, tile) > (uint64)TIFF_TMSIZE_T_MAX)||(ma>tif->tif_size))
n=0;
else if ((mb<ma)||(mb<size)||(mb>tif->tif_size))
n=tif->tif_size-ma;
@@ -1193,13 +1185,12 @@ TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size)
"Compression scheme does not support access to raw uncompressed data");
return ((tmsize_t)(-1));
}
- bytecount64 = td->td_stripbytecount[tile];
- if (size != (tmsize_t)(-1) && (uint64)size < bytecount64)
- bytecount64 = (uint64)size;
- bytecountm = (tmsize_t)bytecount64;
- if ((uint64)bytecountm!=bytecount64)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
+ bytecount64 = TIFFGetStrileByteCount(tif, tile);
+ if (size != (tmsize_t)(-1) && (uint64)size <= bytecount64)
+ bytecountm = size;
+ else
+ bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module);
+ if( bytecountm == 0 ) {
return ((tmsize_t)(-1));
}
return (TIFFReadRawTile1(tif, tile, buf, bytecountm, module));
@@ -1215,13 +1206,10 @@ TIFFFillTile(TIFF* tif, uint32 tile)
static const char module[] = "TIFFFillTile";
TIFFDirectory *td = &tif->tif_dir;
- if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
- return 0;
-
if ((tif->tif_flags&TIFF_NOREADRAW)==0)
{
- uint64 bytecount = td->td_stripbytecount[tile];
- if ((int64)bytecount <= 0) {
+ uint64 bytecount = TIFFGetStrileByteCount(tif, tile);
+ if( bytecount == 0 || bytecount > (uint64)TIFF_INT64_MAX ) {
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFErrorExt(tif->tif_clientdata, module,
"%I64u: Invalid tile byte count, tile %lu",
@@ -1248,7 +1236,7 @@ TIFFFillTile(TIFF* tif, uint32 tile)
(bytecount - 4096) / 10 > (uint64)stripsize )
{
uint64 newbytecount = (uint64)stripsize * 10 + 4096;
- if( (int64)newbytecount >= 0 )
+ if( newbytecount == 0 || newbytecount > (uint64)TIFF_INT64_MAX )
{
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFWarningExt(tif->tif_clientdata, module,
@@ -1273,13 +1261,13 @@ TIFFFillTile(TIFF* tif, uint32 tile)
* We must check for overflow, potentially causing
* an OOB read. Instead of simple
*
- * td->td_stripoffset[tile]+bytecount > tif->tif_size
+ * TIFFGetStrileOffset(tif, tile)+bytecount > tif->tif_size
*
* comparison (which can overflow) we do the following
* two comparisons:
*/
if (bytecount > (uint64)tif->tif_size ||
- td->td_stripoffset[tile] > (uint64)tif->tif_size - bytecount) {
+ TIFFGetStrileOffset(tif, tile) > (uint64)tif->tif_size - bytecount) {
tif->tif_curtile = NOTILE;
return (0);
}
@@ -1308,7 +1296,7 @@ TIFFFillTile(TIFF* tif, uint32 tile)
tif->tif_rawdatasize = (tmsize_t)bytecount;
tif->tif_rawdata =
- tif->tif_base + (tmsize_t)td->td_stripoffset[tile];
+ tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, tile);
tif->tif_rawdataoff = 0;
tif->tif_rawdataloaded = (tmsize_t) bytecount;
tif->tif_flags |= TIFF_BUFFERMMAP;
@@ -1367,7 +1355,8 @@ TIFFFillTile(TIFF* tif, uint32 tile)
tif->tif_rawdataoff = 0;
tif->tif_rawdataloaded = bytecountm;
- if (!isFillOrder(tif, td->td_fillorder) &&
+ if (tif->tif_rawdata != NULL &&
+ !isFillOrder(tif, td->td_fillorder) &&
(tif->tif_flags & TIFF_NOBITREV) == 0)
TIFFReverseBits(tif->tif_rawdata,
tif->tif_rawdataloaded);
@@ -1434,9 +1423,6 @@ TIFFStartStrip(TIFF* tif, uint32 strip)
{
TIFFDirectory *td = &tif->tif_dir;
- if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
- return 0;
-
if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
if (!(*tif->tif_setupdecode)(tif))
return (0);
@@ -1457,7 +1443,7 @@ TIFFStartStrip(TIFF* tif, uint32 strip)
if( tif->tif_rawdataloaded > 0 )
tif->tif_rawcc = tif->tif_rawdataloaded;
else
- tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[strip];
+ tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, strip);
}
return ((*tif->tif_predecode)(tif,
(uint16)(strip / td->td_stripsperimage)));
@@ -1474,9 +1460,6 @@ TIFFStartTile(TIFF* tif, uint32 tile)
TIFFDirectory *td = &tif->tif_dir;
uint32 howmany32;
- if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
- return 0;
-
if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
if (!(*tif->tif_setupdecode)(tif))
return (0);
@@ -1507,7 +1490,7 @@ TIFFStartTile(TIFF* tif, uint32 tile)
if( tif->tif_rawdataloaded > 0 )
tif->tif_rawcc = tif->tif_rawdataloaded;
else
- tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[tile];
+ tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, tile);
}
return ((*tif->tif_predecode)(tif,
(uint16)(tile/td->td_stripsperimage)));
@@ -1522,13 +1505,100 @@ TIFFCheckRead(TIFF* tif, int tiles)
}
if (tiles ^ isTiled(tif)) {
TIFFErrorExt(tif->tif_clientdata, tif->tif_name, tiles ?
- "Can not read tiles from a stripped image" :
+ "Can not read tiles from a striped image" :
"Can not read scanlines from a tiled image");
return (0);
}
return (1);
}
+/* Use the provided input buffer (inbuf, insize) and decompress it into
+ * (outbuf, outsize).
+ * This function replaces the use of TIFFReadEncodedStrip()/TIFFReadEncodedTile()
+ * when the user can provide the buffer for the input data, for example when
+ * he wants to avoid libtiff to read the strile offset/count values from the
+ * [Strip|Tile][Offsets/ByteCounts] array.
+ * inbuf content must be writable (if bit reversal is needed)
+ * Returns 1 in case of success, 0 otherwise.
+ */
+int TIFFReadFromUserBuffer(TIFF* tif, uint32 strile,
+ void* inbuf, tmsize_t insize,
+ void* outbuf, tmsize_t outsize)
+{
+ static const char module[] = "TIFFReadFromUserBuffer";
+ TIFFDirectory *td = &tif->tif_dir;
+ int ret = 1;
+ uint32 old_tif_flags = tif->tif_flags;
+ tmsize_t old_rawdatasize = tif->tif_rawdatasize;
+ void* old_rawdata = tif->tif_rawdata;
+
+ if (tif->tif_mode == O_WRONLY) {
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "File not open for reading");
+ return 0;
+ }
+ if (tif->tif_flags&TIFF_NOREADRAW)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Compression scheme does not support access to raw uncompressed data");
+ return 0;
+ }
+
+ tif->tif_flags &= ~TIFF_MYBUFFER;
+ tif->tif_flags |= TIFF_BUFFERMMAP;
+ tif->tif_rawdatasize = insize;
+ tif->tif_rawdata = inbuf;
+ tif->tif_rawdataoff = 0;
+ tif->tif_rawdataloaded = insize;
+
+ if (!isFillOrder(tif, td->td_fillorder) &&
+ (tif->tif_flags & TIFF_NOBITREV) == 0)
+ {
+ TIFFReverseBits(inbuf, insize);
+ }
+
+ if( TIFFIsTiled(tif) )
+ {
+ if( !TIFFStartTile(tif, strile) ||
+ !(*tif->tif_decodetile)(tif, (uint8*) outbuf, outsize,
+ (uint16)(strile/td->td_stripsperimage)) )
+ {
+ ret = 0;
+ }
+ }
+ else
+ {
+ uint32 rowsperstrip=td->td_rowsperstrip;
+ uint32 stripsperplane;
+ if (rowsperstrip>td->td_imagelength)
+ rowsperstrip=td->td_imagelength;
+ stripsperplane= TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip);
+ if( !TIFFStartStrip(tif, strile) ||
+ !(*tif->tif_decodestrip)(tif, (uint8*) outbuf, outsize,
+ (uint16)(strile/stripsperplane)) )
+ {
+ ret = 0;
+ }
+ }
+ if( ret )
+ {
+ (*tif->tif_postdecode)(tif, (uint8*) outbuf, outsize);
+ }
+
+ if (!isFillOrder(tif, td->td_fillorder) &&
+ (tif->tif_flags & TIFF_NOBITREV) == 0)
+ {
+ TIFFReverseBits(inbuf, insize);
+ }
+
+ tif->tif_flags = old_tif_flags;
+ tif->tif_rawdatasize = old_rawdatasize;
+ tif->tif_rawdata = old_rawdata;
+ tif->tif_rawdataoff = 0;
+ tif->tif_rawdataloaded = 0;
+
+ return ret;
+}
+
void
_TIFFNoPostDecode(TIFF* tif, uint8* buf, tmsize_t cc)
{
diff --git a/libtiff/tif_strip.c b/libtiff/tif_strip.c
index 5b76fba5..c08c60a7 100644
--- a/libtiff/tif_strip.c
+++ b/libtiff/tif_strip.c
@@ -129,15 +129,8 @@ TIFFVStripSize(TIFF* tif, uint32 nrows)
{
static const char module[] = "TIFFVStripSize";
uint64 m;
- tmsize_t n;
m=TIFFVStripSize64(tif,nrows);
- n=(tmsize_t)m;
- if ((uint64)n!=m)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
- n=0;
- }
- return(n);
+ return _TIFFCastUInt64ToSSize(tif, m, module);
}
/*
@@ -147,8 +140,7 @@ uint64
TIFFRawStripSize64(TIFF* tif, uint32 strip)
{
static const char module[] = "TIFFRawStripSize64";
- TIFFDirectory* td = &tif->tif_dir;
- uint64 bytecount = td->td_stripbytecount[strip];
+ uint64 bytecount = TIFFGetStrileByteCount(tif, strip);
if (bytecount == 0)
{
@@ -211,15 +203,8 @@ TIFFStripSize(TIFF* tif)
{
static const char module[] = "TIFFStripSize";
uint64 m;
- tmsize_t n;
m=TIFFStripSize64(tif);
- n=(tmsize_t)m;
- if ((uint64)n!=m)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
- n=0;
- }
- return(n);
+ return _TIFFCastUInt64ToSSize(tif, m, module);
}
/*
@@ -330,14 +315,8 @@ TIFFScanlineSize(TIFF* tif)
{
static const char module[] = "TIFFScanlineSize";
uint64 m;
- tmsize_t n;
m=TIFFScanlineSize64(tif);
- n=(tmsize_t)m;
- if ((uint64)n!=m) {
- TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow");
- n=0;
- }
- return(n);
+ return _TIFFCastUInt64ToSSize(tif, m, module);
}
/*
@@ -366,15 +345,8 @@ TIFFRasterScanlineSize(TIFF* tif)
{
static const char module[] = "TIFFRasterScanlineSize";
uint64 m;
- tmsize_t n;
m=TIFFRasterScanlineSize64(tif);
- n=(tmsize_t)m;
- if ((uint64)n!=m)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow");
- n=0;
- }
- return(n);
+ return _TIFFCastUInt64ToSSize(tif, m, module);
}
/* vim: set ts=8 sts=8 sw=8 noet: */
diff --git a/libtiff/tif_thunder.c b/libtiff/tif_thunder.c
index 2388dbb6..db6383a8 100644
--- a/libtiff/tif_thunder.c
+++ b/libtiff/tif_thunder.c
@@ -122,17 +122,17 @@ ThunderDecode(TIFF* tif, uint8* op, tmsize_t maxpixels)
break;
case THUNDER_2BITDELTAS: /* 2-bit deltas */
if ((delta = ((n >> 4) & 3)) != DELTA2_SKIP)
- SETPIXEL(op, lastpixel + twobitdeltas[delta]);
+ SETPIXEL(op, (unsigned)((int)lastpixel + twobitdeltas[delta]));
if ((delta = ((n >> 2) & 3)) != DELTA2_SKIP)
- SETPIXEL(op, lastpixel + twobitdeltas[delta]);
+ SETPIXEL(op, (unsigned)((int)lastpixel + twobitdeltas[delta]));
if ((delta = (n & 3)) != DELTA2_SKIP)
- SETPIXEL(op, lastpixel + twobitdeltas[delta]);
+ SETPIXEL(op, (unsigned)((int)lastpixel + twobitdeltas[delta]));
break;
case THUNDER_3BITDELTAS: /* 3-bit deltas */
if ((delta = ((n >> 3) & 7)) != DELTA3_SKIP)
- SETPIXEL(op, lastpixel + threebitdeltas[delta]);
+ SETPIXEL(op, (unsigned)((int)lastpixel + threebitdeltas[delta]));
if ((delta = (n & 7)) != DELTA3_SKIP)
- SETPIXEL(op, lastpixel + threebitdeltas[delta]);
+ SETPIXEL(op, (unsigned)((int)lastpixel + threebitdeltas[delta]));
break;
case THUNDER_RAW: /* raw data */
SETPIXEL(op, n);
diff --git a/libtiff/tif_tile.c b/libtiff/tif_tile.c
index 58fe9354..661cc771 100644
--- a/libtiff/tif_tile.c
+++ b/libtiff/tif_tile.c
@@ -181,15 +181,8 @@ TIFFTileRowSize(TIFF* tif)
{
static const char module[] = "TIFFTileRowSize";
uint64 m;
- tmsize_t n;
m=TIFFTileRowSize64(tif);
- n=(tmsize_t)m;
- if ((uint64)n!=m)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
- n=0;
- }
- return(n);
+ return _TIFFCastUInt64ToSSize(tif, m, module);
}
/*
@@ -248,15 +241,8 @@ TIFFVTileSize(TIFF* tif, uint32 nrows)
{
static const char module[] = "TIFFVTileSize";
uint64 m;
- tmsize_t n;
m=TIFFVTileSize64(tif,nrows);
- n=(tmsize_t)m;
- if ((uint64)n!=m)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
- n=0;
- }
- return(n);
+ return _TIFFCastUInt64ToSSize(tif, m, module);
}
/*
@@ -272,15 +258,8 @@ TIFFTileSize(TIFF* tif)
{
static const char module[] = "TIFFTileSize";
uint64 m;
- tmsize_t n;
m=TIFFTileSize64(tif);
- n=(tmsize_t)m;
- if ((uint64)n!=m)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
- n=0;
- }
- return(n);
+ return _TIFFCastUInt64ToSSize(tif, m, module);
}
/*
diff --git a/libtiff/tif_webp.c b/libtiff/tif_webp.c
index 53c3b214..22665f2d 100644
--- a/libtiff/tif_webp.c
+++ b/libtiff/tif_webp.c
@@ -553,12 +553,10 @@ TWebPCleanup(TIFF* tif)
_TIFFfree(sp->pBuffer);
sp->pBuffer = NULL;
}
-
- if (tif->tif_data) {
- _TIFFfree(tif->tif_data);
- tif->tif_data = NULL;
- }
-
+
+ _TIFFfree(tif->tif_data);
+ tif->tif_data = NULL;
+
_TIFFSetDefaultCompressionState(tif);
}
diff --git a/libtiff/tif_win32.c b/libtiff/tif_win32.c
index 088880e7..bf5fbfb3 100644
--- a/libtiff/tif_win32.c
+++ b/libtiff/tif_win32.c
@@ -27,33 +27,37 @@
* Scott Wagner (wagner@itek.com), Itek Graphix, Rochester, NY USA
*/
-/*
- CreateFileA/CreateFileW return type 'HANDLE'.
-
- thandle_t is declared like
-
- DECLARE_HANDLE(thandle_t);
+#include "tiffiop.h"
- in tiffio.h.
+#include <windows.h>
- Windows (from winnt.h) DECLARE_HANDLE logic looks like
+/*
+ CreateFileA/CreateFileW return type 'HANDLE' while TIFFFdOpen() takes 'int',
+ which is formally incompatible and can even seemingly be of different size:
+ HANDLE is 64 bit under Win64, while int is still 32 bits there.
- #ifdef STRICT
- typedef void *HANDLE;
- #define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
- #else
- typedef PVOID HANDLE;
- #define DECLARE_HANDLE(name) typedef HANDLE name
- #endif
+ However, only the lower 32 bits of a HANDLE are significant under Win64 as,
+ for interoperability reasons, they must have the same values in 32- and
+ 64-bit programs running on the same system, see
- See http://bugzilla.maptools.org/show_bug.cgi?id=1941 for problems in WIN64
- builds resulting from this. Unfortunately, the proposed patch was lost.
+ https://docs.microsoft.com/en-us/windows/win32/winprog64/interprocess-communication
+ Because of this, it is safe to define the following trivial functions for
+ casting between ints and HANDLEs, which are only really needed to avoid
+ compiler warnings (and, perhaps, to make the code slightly more clear).
+ Note that using the intermediate cast to "intptr_t" is crucial for warning
+ avoidance, as this integer type has the same size as HANDLE in all builds.
*/
-
-#include "tiffiop.h"
-#include <windows.h>
+static inline thandle_t thandle_from_int(int ifd)
+{
+ return (thandle_t)(intptr_t)ifd;
+}
+
+static inline int thandle_to_int(thandle_t fd)
+{
+ return (int)(intptr_t)fd;
+}
static tmsize_t
_tiffReadProc(thandle_t fd, void* buf, tmsize_t size)
@@ -237,7 +241,7 @@ TIFFFdOpen(int ifd, const char* name, const char* mode)
break;
}
}
- tif = TIFFClientOpen(name, mode, (thandle_t)ifd, /* FIXME: WIN64 cast to pointer warning */
+ tif = TIFFClientOpen(name, mode, thandle_from_int(ifd),
_tiffReadProc, _tiffWriteProc,
_tiffSeekProc, _tiffCloseProc, _tiffSizeProc,
fSuppressMap ? _tiffDummyMapProc : _tiffMapProc,
@@ -282,7 +286,7 @@ TIFFOpen(const char* name, const char* mode)
return ((TIFF *)0);
}
- tif = TIFFFdOpen((int)fd, name, mode); /* FIXME: WIN64 cast from pointer to int warning */
+ tif = TIFFFdOpen(thandle_to_int(fd), name, mode);
if(!tif)
CloseHandle(fd);
return tif;
@@ -337,7 +341,7 @@ TIFFOpenW(const wchar_t* name, const char* mode)
NULL, NULL);
}
- tif = TIFFFdOpen((int)fd, /* FIXME: WIN64 cast from pointer to int warning */
+ tif = TIFFFdOpen(thandle_to_int(fd),
(mbname != NULL) ? mbname : "<unknown>", mode);
if(!tif)
CloseHandle(fd);
diff --git a/libtiff/tif_write.c b/libtiff/tif_write.c
index a31ecd12..f79330e9 100644
--- a/libtiff/tif_write.c
+++ b/libtiff/tif_write.c
@@ -128,10 +128,10 @@ TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata;
- if( td->td_stripbytecount[strip] > 0 )
+ if( td->td_stripbytecount_p[strip] > 0 )
{
/* if we are writing over existing tiles, zero length */
- td->td_stripbytecount[strip] = 0;
+ td->td_stripbytecount_p[strip] = 0;
/* this forces TIFFAppendToStrip() to do a seek */
tif->tif_curoff = 0;
@@ -176,6 +176,32 @@ TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
return (status);
}
+/* Make sure that at the first attempt of rewriting a tile/strip, we will have */
+/* more bytes available in the output buffer than the previous byte count, */
+/* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
+/* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
+static int _TIFFReserveLargeEnoughWriteBuffer(TIFF* tif, uint32 strip_or_tile)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ if( td->td_stripbytecount_p[strip_or_tile] > 0 )
+ {
+ /* The +1 is to ensure at least one extra bytes */
+ /* The +4 is because the LZW encoder flushes 4 bytes before the limit */
+ uint64 safe_buffer_size = (uint64)(td->td_stripbytecount_p[strip_or_tile] + 1 + 4);
+ if( tif->tif_rawdatasize <= (tmsize_t)safe_buffer_size )
+ {
+ if( !(TIFFWriteBufferSetup(tif, NULL,
+ (tmsize_t)TIFFroundup_64(safe_buffer_size, 1024))) )
+ return 0;
+ }
+
+ /* Force TIFFAppendToStrip() to consider placing data at end
+ of file. */
+ tif->tif_curoff = 0;
+ }
+ return 1;
+}
+
/*
* Encode the supplied data and write it to the
* specified strip.
@@ -222,6 +248,13 @@ TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc)
tif->tif_flags |= TIFF_BUF4WRITE;
tif->tif_curstrip = strip;
+ if( !_TIFFReserveLargeEnoughWriteBuffer(tif, strip) ) {
+ return ((tmsize_t)(-1));
+ }
+
+ tif->tif_rawcc = 0;
+ tif->tif_rawcp = tif->tif_rawdata;
+
if (td->td_stripsperimage == 0) {
TIFFErrorExt(tif->tif_clientdata, module, "Zero strips per image");
return ((tmsize_t) -1);
@@ -234,27 +267,6 @@ TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc)
tif->tif_flags |= TIFF_CODERSETUP;
}
- if( td->td_stripbytecount[strip] > 0 )
- {
- /* Make sure that at the first attempt of rewriting the tile, we will have */
- /* more bytes available in the output buffer than the previous byte count, */
- /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
- /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
- if( tif->tif_rawdatasize <= (tmsize_t)td->td_stripbytecount[strip] )
- {
- if( !(TIFFWriteBufferSetup(tif, NULL,
- (tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[strip] + 1), 1024))) )
- return ((tmsize_t)(-1));
- }
-
- /* Force TIFFAppendToStrip() to consider placing data at end
- of file. */
- tif->tif_curoff = 0;
- }
-
- tif->tif_rawcc = 0;
- tif->tif_rawcp = tif->tif_rawdata;
-
tif->tif_flags &= ~TIFF_POSTENCODE;
/* shortcut to avoid an extra memcpy() */
@@ -402,22 +414,8 @@ TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc)
tif->tif_flags |= TIFF_BUF4WRITE;
tif->tif_curtile = tile;
- if( td->td_stripbytecount[tile] > 0 )
- {
- /* Make sure that at the first attempt of rewriting the tile, we will have */
- /* more bytes available in the output buffer than the previous byte count, */
- /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
- /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
- if( tif->tif_rawdatasize <= (tmsize_t) td->td_stripbytecount[tile] )
- {
- if( !(TIFFWriteBufferSetup(tif, NULL,
- (tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[tile] + 1), 1024))) )
- return ((tmsize_t)(-1));
- }
-
- /* Force TIFFAppendToStrip() to consider placing data at end
- of file. */
- tif->tif_curoff = 0;
+ if( !_TIFFReserveLargeEnoughWriteBuffer(tif, tile) ) {
+ return ((tmsize_t)(-1));
}
tif->tif_rawcc = 0;
@@ -535,22 +533,29 @@ TIFFSetupStrips(TIFF* tif)
isUnspecified(tif, FIELD_ROWSPERSTRIP) ?
td->td_samplesperpixel : TIFFNumberOfStrips(tif);
td->td_nstrips = td->td_stripsperimage;
+ /* TIFFWriteDirectoryTagData has a limitation to 0x80000000U bytes */
+ if( td->td_nstrips >= 0x80000000U / ((tif->tif_flags&TIFF_BIGTIFF)?0x8U:0x4U) )
+ {
+ TIFFErrorExt(tif->tif_clientdata, "TIFFSetupStrips",
+ "Too large Strip/Tile Offsets/ByteCounts arrays");
+ return 0;
+ }
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
td->td_stripsperimage /= td->td_samplesperpixel;
- td->td_stripoffset = (uint64 *)
+ td->td_stripoffset_p = (uint64 *)
_TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64),
"for \"StripOffsets\" array");
- td->td_stripbytecount = (uint64 *)
+ td->td_stripbytecount_p = (uint64 *)
_TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64),
"for \"StripByteCounts\" array");
- if (td->td_stripoffset == NULL || td->td_stripbytecount == NULL)
+ if (td->td_stripoffset_p == NULL || td->td_stripbytecount_p == NULL)
return (0);
/*
* Place data at the end-of-file
* (by setting offsets to zero).
*/
- _TIFFmemset(td->td_stripoffset, 0, td->td_nstrips*sizeof (uint64));
- _TIFFmemset(td->td_stripbytecount, 0, td->td_nstrips*sizeof (uint64));
+ _TIFFmemset(td->td_stripoffset_p, 0, td->td_nstrips*sizeof (uint64));
+ _TIFFmemset(td->td_stripbytecount_p, 0, td->td_nstrips*sizeof (uint64));
TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
return (1);
@@ -572,7 +577,7 @@ TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
}
if (tiles ^ isTiled(tif)) {
TIFFErrorExt(tif->tif_clientdata, module, tiles ?
- "Can not write tiles to a stripped image" :
+ "Can not write tiles to a striped image" :
"Can not write scanlines to a tiled image");
return (0);
}
@@ -610,7 +615,7 @@ TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
return (0);
}
}
- if (tif->tif_dir.td_stripoffset == NULL && !TIFFSetupStrips(tif)) {
+ if (tif->tif_dir.td_stripoffset_p == NULL && !TIFFSetupStrips(tif)) {
tif->tif_dir.td_nstrips = 0;
TIFFErrorExt(tif->tif_clientdata, module, "No space for %s arrays",
isTiled(tif) ? "tile" : "strip");
@@ -628,6 +633,20 @@ TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
if (tif->tif_scanlinesize == 0)
return (0);
tif->tif_flags |= TIFF_BEENWRITING;
+
+ if( tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
+ tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
+ tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 &&
+ !(tif->tif_flags & TIFF_DIRTYDIRECT) )
+ {
+ TIFFForceStrileArrayWriting(tif);
+ }
+
return (1);
}
@@ -684,9 +703,9 @@ TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module)
uint64* new_stripbytecount;
assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
- new_stripoffset = (uint64*)_TIFFrealloc(td->td_stripoffset,
+ new_stripoffset = (uint64*)_TIFFrealloc(td->td_stripoffset_p,
(td->td_nstrips + delta) * sizeof (uint64));
- new_stripbytecount = (uint64*)_TIFFrealloc(td->td_stripbytecount,
+ new_stripbytecount = (uint64*)_TIFFrealloc(td->td_stripbytecount_p,
(td->td_nstrips + delta) * sizeof (uint64));
if (new_stripoffset == NULL || new_stripbytecount == NULL) {
if (new_stripoffset)
@@ -697,11 +716,11 @@ TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module)
TIFFErrorExt(tif->tif_clientdata, module, "No space to expand strip arrays");
return (0);
}
- td->td_stripoffset = new_stripoffset;
- td->td_stripbytecount = new_stripbytecount;
- _TIFFmemset(td->td_stripoffset + td->td_nstrips,
+ td->td_stripoffset_p = new_stripoffset;
+ td->td_stripbytecount_p = new_stripbytecount;
+ _TIFFmemset(td->td_stripoffset_p + td->td_nstrips,
0, delta*sizeof (uint64));
- _TIFFmemset(td->td_stripbytecount + td->td_nstrips,
+ _TIFFmemset(td->td_stripbytecount_p + td->td_nstrips,
0, delta*sizeof (uint64));
td->td_nstrips += delta;
tif->tif_flags |= TIFF_DIRTYDIRECT;
@@ -720,12 +739,12 @@ TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc)
uint64 m;
int64 old_byte_count = -1;
- if (td->td_stripoffset[strip] == 0 || tif->tif_curoff == 0) {
+ if (td->td_stripoffset_p[strip] == 0 || tif->tif_curoff == 0) {
assert(td->td_nstrips > 0);
- if( td->td_stripbytecount[strip] != 0
- && td->td_stripoffset[strip] != 0
- && td->td_stripbytecount[strip] >= (uint64) cc )
+ if( td->td_stripbytecount_p[strip] != 0
+ && td->td_stripoffset_p[strip] != 0
+ && td->td_stripbytecount_p[strip] >= (uint64) cc )
{
/*
* There is already tile data on disk, and the new tile
@@ -734,7 +753,7 @@ TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc)
* more data to append to this strip before we are done
* depending on how we are getting called.
*/
- if (!SeekOK(tif, td->td_stripoffset[strip])) {
+ if (!SeekOK(tif, td->td_stripoffset_p[strip])) {
TIFFErrorExt(tif->tif_clientdata, module,
"Seek error at scanline %lu",
(unsigned long)tif->tif_row);
@@ -747,17 +766,17 @@ TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc)
* Seek to end of file, and set that as our location to
* write this strip.
*/
- td->td_stripoffset[strip] = TIFFSeekFile(tif, 0, SEEK_END);
+ td->td_stripoffset_p[strip] = TIFFSeekFile(tif, 0, SEEK_END);
tif->tif_flags |= TIFF_DIRTYSTRIP;
}
- tif->tif_curoff = td->td_stripoffset[strip];
+ tif->tif_curoff = td->td_stripoffset_p[strip];
/*
* We are starting a fresh strip/tile, so set the size to zero.
*/
- old_byte_count = td->td_stripbytecount[strip];
- td->td_stripbytecount[strip] = 0;
+ old_byte_count = td->td_stripbytecount_p[strip];
+ td->td_stripbytecount_p[strip] = 0;
}
m = tif->tif_curoff+cc;
@@ -774,9 +793,9 @@ TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc)
return (0);
}
tif->tif_curoff = m;
- td->td_stripbytecount[strip] += cc;
+ td->td_stripbytecount_p[strip] += cc;
- if( (int64) td->td_stripbytecount[strip] != old_byte_count )
+ if( (int64) td->td_stripbytecount_p[strip] != old_byte_count )
tif->tif_flags |= TIFF_DIRTYSTRIP;
return (1);
diff --git a/libtiff/tif_zip.c b/libtiff/tif_zip.c
index 80f0dfe9..325222e5 100644
--- a/libtiff/tif_zip.c
+++ b/libtiff/tif_zip.c
@@ -124,7 +124,6 @@ ZIPSetupDecode(TIFF* tif)
static int
ZIPPreDecode(TIFF* tif, uint16 s)
{
- static const char module[] = "ZIPPreDecode";
ZIPState* sp = DecoderState(tif);
(void) s;
@@ -138,12 +137,7 @@ ZIPPreDecode(TIFF* tif, uint16 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) tif->tif_rawcc;
- if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc)
- {
- TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
- return (0);
- }
+ sp->stream.avail_in = (uint64)tif->tif_rawcc < 0xFFFFFFFFU ? (uInt) tif->tif_rawcc : 0xFFFFFFFFU;
return (inflateReset(&sp->stream) == Z_OK);
}
@@ -158,46 +152,43 @@ ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
assert(sp->state == ZSTATE_INIT_DECODE);
sp->stream.next_in = tif->tif_rawcp;
- sp->stream.avail_in = (uInt) tif->tif_rawcc;
sp->stream.next_out = op;
assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised,
we need to simplify this code to reflect a ZLib that is likely updated
to deal with 8byte memory sizes, though this code will respond
appropriately even before we simplify it */
- sp->stream.avail_out = (uInt) occ;
- if ((tmsize_t)sp->stream.avail_out != occ)
- {
- TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
- return (0);
- }
do {
- int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
+ int state;
+ uInt avail_in_before = (uint64)tif->tif_rawcc <= 0xFFFFFFFFU ? (uInt)tif->tif_rawcc : 0xFFFFFFFFU;
+ uInt avail_out_before = (uint64)occ < 0xFFFFFFFFU ? (uInt) occ : 0xFFFFFFFFU;
+ sp->stream.avail_in = avail_in_before;
+ sp->stream.avail_out = avail_out_before;
+ state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
+ tif->tif_rawcc -= (avail_in_before - sp->stream.avail_in);
+ occ -= (avail_out_before - sp->stream.avail_out);
if (state == Z_STREAM_END)
break;
if (state == Z_DATA_ERROR) {
TIFFErrorExt(tif->tif_clientdata, module,
"Decoding error at scanline %lu, %s",
(unsigned long) tif->tif_row, SAFE_MSG(sp));
- /* if (inflateSync(&sp->stream) != Z_OK) */
return (0);
- continue;
}
if (state != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module,
"ZLib error: %s", SAFE_MSG(sp));
return (0);
}
- } while (sp->stream.avail_out > 0);
- if (sp->stream.avail_out != 0) {
+ } while (occ > 0);
+ if (occ != 0) {
TIFFErrorExt(tif->tif_clientdata, module,
"Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT " bytes)",
- (unsigned long) tif->tif_row, (TIFF_UINT64_T) sp->stream.avail_out);
+ (unsigned long) tif->tif_row, (TIFF_UINT64_T) occ);
return (0);
}
tif->tif_rawcp = sp->stream.next_in;
- tif->tif_rawcc = sp->stream.avail_in;
return (1);
}
@@ -229,7 +220,6 @@ ZIPSetupEncode(TIFF* tif)
static int
ZIPPreEncode(TIFF* tif, uint16 s)
{
- static const char module[] = "ZIPPreEncode";
ZIPState *sp = EncoderState(tif);
(void) s;
@@ -242,12 +232,7 @@ ZIPPreEncode(TIFF* tif, uint16 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)tif->tif_rawdatasize;
- if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
- {
- TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
- return (0);
- }
+ sp->stream.avail_out = (uint64)tif->tif_rawdatasize <= 0xFFFFFFFFU ? (uInt)tif->tif_rawdatasize : 0xFFFFFFFFU;
return (deflateReset(&sp->stream) == Z_OK);
}
@@ -269,13 +254,9 @@ ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 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) cc;
- if ((tmsize_t)sp->stream.avail_in != cc)
- {
- TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
- return (0);
- }
do {
+ uInt avail_in_before = (uint64)cc <= 0xFFFFFFFFU ? (uInt)cc : 0xFFFFFFFFU;
+ sp->stream.avail_in = avail_in_before;
if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module,
"Encoder error: %s",
@@ -286,9 +267,10 @@ ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
tif->tif_rawcc = tif->tif_rawdatasize;
TIFFFlushData1(tif);
sp->stream.next_out = tif->tif_rawdata;
- sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in ZIPPreEncode */
+ sp->stream.avail_out = (uint64)tif->tif_rawdatasize <= 0xFFFFFFFFU ? (uInt)tif->tif_rawdatasize : 0xFFFFFFFFU;
}
- } while (sp->stream.avail_in > 0);
+ cc -= (avail_in_before - sp->stream.avail_in);
+ } while (cc > 0);
return (1);
}
@@ -314,7 +296,7 @@ ZIPPostEncode(TIFF* tif)
tif->tif_rawcc = tif->tif_rawdatasize - sp->stream.avail_out;
TIFFFlushData1(tif);
sp->stream.next_out = tif->tif_rawdata;
- sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in ZIPPreEncode */
+ sp->stream.avail_out = (uint64)tif->tif_rawdatasize <= 0xFFFFFFFFU ? (uInt)tif->tif_rawdatasize : 0xFFFFFFFFU;
}
break;
default:
diff --git a/libtiff/tiffio.h b/libtiff/tiffio.h
index 31c2e676..198481d5 100644
--- a/libtiff/tiffio.h
+++ b/libtiff/tiffio.h
@@ -411,6 +411,8 @@ extern int TIFFWriteDirectory(TIFF *);
extern int TIFFWriteCustomDirectory(TIFF *, uint64 *);
extern int TIFFCheckpointDirectory(TIFF *);
extern int TIFFRewriteDirectory(TIFF *);
+extern int TIFFDeferStrileArrayWriting(TIFF *);
+extern int TIFFForceStrileArrayWriting(TIFF* );
#if defined(c_plusplus) || defined(__cplusplus)
extern void TIFFPrintDirectory(TIFF*, FILE*, long = 0);
@@ -468,6 +470,9 @@ extern tmsize_t TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_
extern tmsize_t TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size);
extern tmsize_t TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size);
extern tmsize_t TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size);
+extern int TIFFReadFromUserBuffer(TIFF* tif, uint32 strile,
+ void* inbuf, tmsize_t insize,
+ void* outbuf, tmsize_t outsize);
extern tmsize_t TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc);
extern tmsize_t TIFFWriteRawStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc);
extern tmsize_t TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc);
@@ -488,6 +493,11 @@ extern void TIFFSwabArrayOfDouble(double* dp, tmsize_t n);
extern void TIFFReverseBits(uint8* cp, tmsize_t n);
extern const unsigned char* TIFFGetBitRevTable(int);
+extern uint64 TIFFGetStrileOffset(TIFF *tif, uint32 strile);
+extern uint64 TIFFGetStrileByteCount(TIFF *tif, uint32 strile);
+extern uint64 TIFFGetStrileOffsetWithErr(TIFF *tif, uint32 strile, int *pbErr);
+extern uint64 TIFFGetStrileByteCountWithErr(TIFF *tif, uint32 strile, int *pbErr);
+
#ifdef LOGLUV_PUBLIC
#define U_NEU 0.210526316
#define V_NEU 0.473684211
diff --git a/libtiff/tiffiop.h b/libtiff/tiffiop.h
index 186c291f..45a79323 100644
--- a/libtiff/tiffiop.h
+++ b/libtiff/tiffiop.h
@@ -77,6 +77,19 @@ extern int snprintf(char* str, size_t size, const char* format, ...);
#define FALSE 0
#endif
+#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0))
+#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1)
+
+/*
+ * Largest 32-bit unsigned integer value.
+ */
+#define TIFF_UINT32_MAX 0xFFFFFFFFU
+
+/*
+ * Largest 64-bit unsigned integer value.
+ */
+#define TIFF_UINT64_MAX (((uint64)(TIFF_UINT32_MAX)) << 32 | TIFF_UINT32_MAX)
+
typedef struct client_info {
struct client_info *next;
void *data;
@@ -127,6 +140,9 @@ struct tiff {
#define TIFF_DIRTYSTRIP 0x200000U /* stripoffsets/stripbytecount dirty*/
#define TIFF_PERSAMPLE 0x400000U /* get/set per sample tags as arrays */
#define TIFF_BUFFERMMAP 0x800000U /* read buffer (tif_rawdata) points into mmap() memory */
+ #define TIFF_DEFERSTRILELOAD 0x1000000U /* defer strip/tile offset/bytecount array loading. */
+ #define TIFF_LAZYSTRILELOAD 0x2000000U /* lazy/ondemand loading of strip/tile offset/bytecount values. Only used if TIFF_DEFERSTRILELOAD is set and in read-only mode */
+ #define TIFF_CHOPPEDUPARRAYS 0x4000000U /* set when allocChoppedUpStripArrays() has modified strip array */
uint64 tif_diroff; /* file offset of current directory */
uint64 tif_nextdiroff; /* file offset of following directory */
uint64* tif_dirlist; /* list of offsets to already seen directories to prevent IFD looping */
@@ -258,7 +274,7 @@ struct tiff {
#define TIFFhowmany8_64(x) (((x)&0x07)?((uint64)(x)>>3)+1:(uint64)(x)>>3)
#define TIFFroundup_64(x, y) (TIFFhowmany_64(x,y)*(y))
-/* Safe multiply which returns zero if there is an integer overflow */
+/* Safe multiply which returns zero if there is an *unsigned* integer overflow. This macro is not safe for *signed* integer types */
#define TIFFSafeMultiply(t,v,m) ((((t)(m) != (t)0) && (((t)(((v)*(m))/(m))) == (t)(v))) ? (t)((v)*(m)) : (t)0)
#define TIFFmax(A,B) ((A)>(B)?(A):(B))
@@ -368,12 +384,16 @@ extern TIFFErrorHandlerExt _TIFFerrorHandlerExt;
extern uint32 _TIFFMultiply32(TIFF*, uint32, uint32, const char*);
extern uint64 _TIFFMultiply64(TIFF*, uint64, uint64, const char*);
+extern tmsize_t _TIFFMultiplySSize(TIFF*, tmsize_t, tmsize_t, const char*);
+extern tmsize_t _TIFFCastUInt64ToSSize(TIFF*, uint64, const char*);
extern void* _TIFFCheckMalloc(TIFF*, tmsize_t, tmsize_t, const char*);
extern void* _TIFFCheckRealloc(TIFF*, void*, tmsize_t, tmsize_t, const char*);
extern double _TIFFUInt64ToDouble(uint64);
extern float _TIFFUInt64ToFloat(uint64);
+extern float _TIFFClampDoubleToFloat(double);
+
extern tmsize_t
_TIFFReadEncodedStripAndAllocBuffer(TIFF* tif, uint32 strip,
void **buf, tmsize_t bufsizetoalloc,
diff --git a/libtiff/tiffvers.h b/libtiff/tiffvers.h
index 403d61be..aa3f613e 100644
--- a/libtiff/tiffvers.h
+++ b/libtiff/tiffvers.h
@@ -1,4 +1,4 @@
-#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.0.10\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc."
+#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.1.0\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc."
/*
* This define can be used in code that requires
* compilation-related definitions specific to a
@@ -6,4 +6,4 @@
* version checking should be done based on the
* string returned by TIFFGetVersion.
*/
-#define TIFFLIB_VERSION 20181110
+#define TIFFLIB_VERSION 20191103
diff --git a/man/TIFFOpen.3tiff b/man/TIFFOpen.3tiff
index 5a6e96b8..c6ed28e6 100644
--- a/man/TIFFOpen.3tiff
+++ b/man/TIFFOpen.3tiff
@@ -207,6 +207,21 @@ Disable the use of strip chopping when reading images.
Read TIFF header only, do not load the first image directory. That could be
useful in case of the broken first directory. We can open the file and proceed
to the other directories.
+.TP
+.B 4
+ClassicTIFF for creating a file (default)
+.TP
+.B 8
+BigTIFF for creating a file.
+.TP
+.B D
+Enable use of deferred strip/tile offset/bytecount array loading. They will
+be loaded the first time they are accessed to. This loading will be done in
+its entirety unless the O flag is also specified.
+.TP
+.B O
+On-demand loading of values of the strip/tile offset/bytecount arrays, limited
+to the requested strip/tile, instead of whole array loading (implies D)
.SH "BYTE ORDER"
The
.SM TIFF
diff --git a/man/libtiff.3tiff b/man/libtiff.3tiff
index 3efe162e..8e9ff35b 100644
--- a/man/libtiff.3tiff
+++ b/man/libtiff.3tiff
@@ -342,7 +342,7 @@ WhitePoint 318 R/W
XPosition 286 R/W
XResolution 282 R/W
YCbCrCoefficients 529 R/W used by TIFFRGBAImage support
-YCbCrPositioning 531 R/W tile/strip size calulcations
+YCbCrPositioning 531 R/W tile/strip size calculations
YCbCrSubsampling 530 R/W
YPosition 286 R/W
YResolution 283 R/W used by Group 3 codec
@@ -354,7 +354,7 @@ tags whose values lie in a range outside the valid range of
.SM TIFF
tags.
These tags are termed
-.I pseud-tags
+.I pseudo-tags
and are used to control various codec-specific functions within the library.
The table below summarizes the defined pseudo-tags.
.sp
@@ -408,7 +408,7 @@ The default value is a pointer to a builtin function that images
packed bilevel data.
.TP
.B TIFFTAG_IPTCNEWSPHOTO
-Tag contaings image metadata per the IPTC newsphoto spec: Headline,
+Tag contains image metadata per the IPTC newsphoto spec: Headline,
captioning, credit, etc... Used by most wire services.
.TP
.B TIFFTAG_PHOTOSHOP
diff --git a/nmake.opt b/nmake.opt
index ae544670..d9bf15f1 100644
--- a/nmake.opt
+++ b/nmake.opt
@@ -29,6 +29,7 @@
# Usage examples (see details below):
# nmake -f makefile.vc
# nmake -f makefile.vc DEBUG=1
+# nmake -f makefile.vc clean
#
#
###### Edit the following lines to choose a feature set you need. #######
@@ -108,6 +109,11 @@ CHECK_JPEG_YCBCR_SUBSAMPLING = 1
####################### Compiler related options. #######################
#
+
+# Indicate if the compiler provides strtoll/strtoull (default 1)
+# Users of MSVC++ 14.0 ("Visual Studio 2015") and later should set this to 1
+HAVE_STRTOLL = 1
+
#
# Pick debug or optimized build flags. We default to an optimized build
# with no debugging information.
@@ -118,7 +124,7 @@ OPTFLAGS = /MDd /EHsc /W3 /D_CRT_SECURE_NO_DEPRECATE
!ELSE
OPTFLAGS = /Ox /MD /EHsc /W3 /D_CRT_SECURE_NO_DEPRECATE
!ENDIF
-#OPTFLAGS = /Zi
+#OPTFLAGS = /Zi
#
# Uncomment following line to enable using Windows Common RunTime Library
@@ -139,7 +145,7 @@ LD = link /nologo
CFLAGS = $(OPTFLAGS) $(INCL) $(EXTRAFLAGS)
CXXFLAGS = $(OPTFLAGS) $(INCL) $(EXTRAFLAGS)
-EXTRAFLAGS =
+EXTRAFLAGS = -DHAVE_CONFIG_H
LIBS =
# Name of the output shared library
diff --git a/port/Makefile.vc b/port/Makefile.vc
index 992d2696..e4471af5 100644
--- a/port/Makefile.vc
+++ b/port/Makefile.vc
@@ -23,13 +23,53 @@
# Makefile for MS Visual C and Watcom C compilers.
#
# To build:
-# C:\libtiff\port> nmake /f makefile.vc
+# C:\libtiff\port> nmake /f makefile.vc
!INCLUDE ..\nmake.opt
+HAVE_STRTOL = 1
+HAVE_STRTOUL = 1
+
+# strtoul()/strtoull() are provided together
+!IF $(HAVE_STRTOLL)
+HAVE_STRTOULL = 1
+!ELSE
+HAVE_STRTOULL = 0
+!endif
+
+!IF $(HAVE_STRTOL)
+STRTOL_OBJ =
+!ELSE
+STRTOL_OBJ = strtol.obj
+!ENDIF
+
+!IF $(HAVE_STRTOUL)
+STRTOUL_OBJ =
+!ELSE
+STRTOUL_OBJ = strtoul.obj
+!ENDIF
+
+!IF $(HAVE_STRTOLL)
+STRTOLL_OBJ =
+!ELSE
+STRTOLL_OBJ = strtoll.obj
+!ENDIF
+
+!IF $(HAVE_STRTOULL)
+STRTOULL_OBJ =
+!ELSE
+STRTOULL_OBJ = strtoull.obj
+!ENDIF
+
+INCL = -I..\libtiff
+
OBJ = \
- snprintf.obj \
+ snprintf.obj \
strcasecmp.obj \
+ $(STRTOL_OBJ) \
+ $(STRTOUL_OBJ) \
+ $(STRTOLL_OBJ) \
+ $(STRTOULL_OBJ) \
getopt.obj
all: libport.lib
diff --git a/port/libport.h b/port/libport.h
index ff262638..9f2dace1 100644
--- a/port/libport.h
+++ b/port/libport.h
@@ -24,6 +24,10 @@
#ifndef _LIBPORT_
#define _LIBPORT_
+#if defined(HAVE_CONFIG_H)
+# include <tif_config.h>
+#endif
+
int getopt(int argc, char * const argv[], const char *optstring);
extern char *optarg;
extern int opterr;
@@ -36,16 +40,16 @@ int strcasecmp(const char *s1, const char *s2);
# define HAVE_GETOPT 1
#endif
-#if HAVE_STRTOL
+#if !defined(HAVE_STRTOL)
long strtol(const char *nptr, char **endptr, int base);
#endif
-#if HAVE_STRTOLL
+#if !defined(HAVE_STRTOLL)
long long strtoll(const char *nptr, char **endptr, int base);
#endif
-#if HAVE_STRTOUL
+#if !defined(HAVE_STRTOUL)
unsigned long strtoul(const char *nptr, char **endptr, int base);
#endif
-#if HAVE_STRTOULL
+#if !defined(HAVE_STRTOULL)
unsigned long long strtoull(const char *nptr, char **endptr, int base);
#endif
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 266e3fcf..23b678cf 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -35,6 +35,7 @@ set(TESTSCRIPTS
ppm2tiff_pbm.sh
ppm2tiff_pgm.sh
ppm2tiff_ppm.sh
+ fax2tiff.sh
tiffcp-g3.sh
tiffcp-g3-1d.sh
tiffcp-g3-1d-fill.sh
@@ -104,7 +105,10 @@ set(TESTSCRIPTS
tiff2rgba-palette-1c-8b.sh
tiff2rgba-rgb-3c-16b.sh
tiff2rgba-rgb-3c-8b.sh
- tiff2rgba-quad-tile.jpg.sh)
+ tiff2rgba-quad-tile.jpg.sh
+ tiff2rgba-ojpeg_zackthecat_subsamp22_single_strip.sh
+ tiff2rgba-ojpeg_chewey_subsamp21_multi_strip.sh
+ tiff2rgba-ojpeg_single_strip_no_rowsperstrip.sh)
# This list should contain all of the TIFF files in the 'images'
# subdirectory which are intended to be used as input images for
@@ -122,7 +126,10 @@ set(TIFFIMAGES
images/rgb-3c-8b.tiff
images/quad-tile.jpg.tiff
images/quad-lzw-compat.tiff
- images/lzw-single-strip.tiff)
+ images/lzw-single-strip.tiff
+ images/ojpeg_zackthecat_subsamp22_single_strip.tiff
+ images/ojpeg_chewey_subsamp21_multi_strip.tiff
+ images/ojpeg_single_strip_no_rowsperstrip.tiff)
set(BMPIMAGES
images/palette-1c-8b.bmp
@@ -151,6 +158,7 @@ set(UNCOMPRESSEDIMAGES
# files which are not currently used by the tests.
set(IMAGES_EXTRA_DIST
images/README.txt
+ images/miniswhite-1c-1b.g3
${BMPIMAGES}
${GIFIMAGES}
${PNMIMAGES}
@@ -186,6 +194,15 @@ endif()
add_executable(custom_dir custom_dir.c)
target_link_libraries(custom_dir tiff port)
+add_executable(defer_strile_loading defer_strile_loading.c)
+target_link_libraries(defer_strile_loading tiff port)
+
+add_executable(defer_strile_writing defer_strile_writing.c)
+target_link_libraries(defer_strile_writing tiff port)
+
+add_executable(testtypes testtypes.c)
+target_link_libraries(testtypes tiff port)
+
set(TEST_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output")
file(MAKE_DIRECTORY "${TEST_OUTPUT}")
@@ -383,3 +400,7 @@ add_convert_tests(tiffcrop doubleflip "-F both" TIFFIMAGES TRU
add_convert_tests(tiffcrop extract "-U px -E top -X 60 -Y 60" TIFFIMAGES TRUE)
# Test extracting the first and fourth quarters from the left side.
add_convert_tests(tiffcrop extractz14 "-E left -Z1:4,2:4" TIFFIMAGES TRUE)
+
+# test types
+add_test(NAME "testtypes"
+ COMMAND "testtypes")
diff --git a/test/Makefile.am b/test/Makefile.am
index 52a3fa4b..e7d239bd 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -34,6 +34,7 @@ TESTS_ENVIRONMENT = \
MEMCHECK="$(MEMCHECK)"
EXTRA_DIST = \
+ $(REFFILES) \
$(TESTSCRIPTS) \
$(IMAGES_EXTRA_DIST) \
CMakeLists.txt \
@@ -54,7 +55,11 @@ CLEANFILES = test_packbits.tif o-*
if HAVE_JPEG
JPEG_DEPENDENT_CHECK_PROG=raw_decode
JPEG_DEPENDENT_TESTSCRIPTS=\
- tiff2rgba-quad-tile.jpg.sh
+ tiff2rgba-quad-tile.jpg.sh \
+ tiff2rgba-ojpeg_zackthecat_subsamp22_single_strip.sh \
+ tiff2rgba-ojpeg_chewey_subsamp21_multi_strip.sh \
+ tiff2rgba-ojpeg_single_strip_no_rowsperstrip.sh
+
else
JPEG_DEPENDENT_CHECK_PROG=
JPEG_DEPENDENT_TESTSCRIPTS=
@@ -63,6 +68,7 @@ endif
# Executable programs which need to be built in order to support tests
check_PROGRAMS = \
ascii_tag long_tag short_tag strip_rw rewrite custom_dir \
+ defer_strile_loading defer_strile_writing testtypes \
$(JPEG_DEPENDENT_CHECK_PROG)
# Test scripts to execute
@@ -70,6 +76,7 @@ TESTSCRIPTS = \
ppm2tiff_pbm.sh \
ppm2tiff_pgm.sh \
ppm2tiff_ppm.sh \
+ fax2tiff.sh \
tiffcp-g3.sh \
tiffcp-g3-1d.sh \
tiffcp-g3-1d-fill.sh \
@@ -144,6 +151,14 @@ TESTSCRIPTS = \
tiff2rgba-rgb-3c-8b.sh \
$(JPEG_DEPENDENT_TESTSCRIPTS)
+# This list should contain the references files
+# from the 'refs' subdirectory
+REFFILES = \
+ refs/o-tiff2ps-EPS1.ps \
+ refs/o-tiff2ps-PS1.ps \
+ refs/o-tiff2ps-PS2.ps \
+ refs/o-tiff2ps-PS3.ps
+
# This list should contain all of the TIFF files in the 'images'
# subdirectory which are intended to be used as input images for
# tests. All of these files should use the extension ".tiff".
@@ -160,7 +175,10 @@ TIFFIMAGES = \
images/rgb-3c-8b.tiff \
images/quad-tile.jpg.tiff \
images/quad-lzw-compat.tiff \
- images/lzw-single-strip.tiff
+ images/lzw-single-strip.tiff \
+ images/ojpeg_zackthecat_subsamp22_single_strip.tiff \
+ images/ojpeg_chewey_subsamp21_multi_strip.tiff \
+ images/ojpeg_single_strip_no_rowsperstrip.tiff
PNMIMAGES = \
images/minisblack-1c-8b.pgm \
@@ -172,6 +190,7 @@ PNMIMAGES = \
# files which are not currently used by the tests.
IMAGES_EXTRA_DIST = \
images/README.txt \
+ images/miniswhite-1c-1b.g3 \
$(PNMIMAGES) \
$(TIFFIMAGES)
@@ -191,6 +210,10 @@ raw_decode_SOURCES = raw_decode.c
raw_decode_LDADD = $(LIBTIFF)
custom_dir_SOURCES = custom_dir.c
custom_dir_LDADD = $(LIBTIFF)
+defer_strile_loading_SOURCES = defer_strile_loading.c
+defer_strile_loading_LDADD = $(LIBTIFF)
+defer_strile_writing_SOURCES = defer_strile_writing.c
+defer_strile_writing_LDADD = $(LIBTIFF)
AM_CPPFLAGS = -I$(top_srcdir)/libtiff
diff --git a/test/common.sh b/test/common.sh
index 42c38737..5bebcd37 100644
--- a/test/common.sh
+++ b/test/common.sh
@@ -7,6 +7,7 @@ SRCDIR=`cd $SRCDIR && pwd`
TOPSRCDIR=`cd $srcdir/.. && pwd`
TOOLS=`cd ../tools && pwd`
IMAGES="${SRCDIR}/images"
+REFS="${SRCDIR}/refs"
# Aliases for built tools
FAX2PS=${TOOLS}/fax2ps
diff --git a/test/defer_strile_loading.c b/test/defer_strile_loading.c
new file mode 100644
index 00000000..b444c01f
--- /dev/null
+++ b/test/defer_strile_loading.c
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 2019, Even Rouault <even.rouault at spatialys.com>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library
+ *
+ * Module to test 'D' and 'O' open flags
+ */
+
+#include "tif_config.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#include "tiffio.h"
+#include "tifftest.h"
+
+int test(int classictif, int height, int tiled)
+{
+ const char* filename = "defer_strile_loading.tif";
+ TIFF* tif;
+ int i;
+ int ret = 0;
+ FILE* f;
+
+ (void)ret;
+
+ tif = TIFFOpen(filename, classictif ? "wDO" : "w8DO"); /* O should be ignored in write mode */
+ if(!tif)
+ {
+ fprintf(stderr, "cannot create %s\n", filename);
+ return 1;
+ }
+ ret = TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
+ assert(ret);
+ ret = TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, 1);
+ assert(ret);
+ ret = TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
+ assert(ret);
+ ret = TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
+ assert(ret);
+ ret = TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
+ assert(ret);
+ ret = TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+ assert(ret);
+ if( tiled )
+ {
+ int j;
+ ret = TIFFSetField(tif, TIFFTAG_TILEWIDTH, 16);
+ assert( ret );
+ ret = TIFFSetField(tif, TIFFTAG_TILELENGTH, 16);
+ assert( ret );
+ for( j = 0; j < (height+15) / 16; j++ )
+ {
+ unsigned char tilebuffer[256];
+ memset(tilebuffer, (unsigned char)j, 256);
+ ret = TIFFWriteEncodedTile( tif, j, tilebuffer, 256 );
+ assert(ret == 256);
+ }
+ }
+ else
+ {
+ ret = TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
+ assert(ret);
+ for( i = 0; i < height; i++ )
+ {
+ unsigned char c = (unsigned char)i;
+ ret = TIFFWriteEncodedStrip( tif, i, &c, 1 );
+ assert(ret == 1);
+
+ if( i == 1 && height > 100000 )
+ i = height - 2;
+ }
+ }
+ TIFFClose(tif);
+
+ f = fopen(filename, "rb");
+ if( !f )
+ return 1;
+
+ for( i = 0; i < 2; i++ )
+ {
+ tif = TIFFOpen(filename, i == 0 ? "rD" : "rO");
+ if(!tif)
+ {
+ fprintf(stderr, "cannot open %s\n", filename);
+ fclose(f);
+ return 1;
+ }
+ if( tiled )
+ {
+ int j;
+ for( j = 0; j < (height+15) / 16; j++ )
+ {
+ int retry;
+ unsigned char expected_c = (unsigned char)j;
+
+ for( retry = 0; retry < 2; retry++ )
+ {
+ unsigned char tilebuffer[256];
+ memset(tilebuffer,0, 256);
+ ret = TIFFReadEncodedTile( tif, j, tilebuffer, 256 );
+ assert(ret == 256);
+ if( tilebuffer[0] != expected_c ||
+ tilebuffer[255] != expected_c )
+ {
+ fprintf(stderr, "unexpected value at tile %d: %d %d\n",
+ j, tilebuffer[0], tilebuffer[255]);
+ TIFFClose(tif);
+ fclose(f);
+ return 1;
+ }
+ }
+
+ {
+ int err = 0;
+ int offset, size;
+ unsigned char inputbuffer[256];
+ unsigned char tilebuffer[256];
+
+ offset = TIFFGetStrileOffsetWithErr(tif, j, &err);
+ assert(offset != 0);
+ assert(err == 0);
+
+ size = TIFFGetStrileByteCountWithErr(tif, j, &err);
+ assert(size == 256);
+ assert(err == 0);
+
+ fseek(f, offset, SEEK_SET);
+ fread(inputbuffer, 256, 1, f);
+
+ memset(tilebuffer,0, 256);
+ ret = TIFFReadFromUserBuffer(tif, j,
+ inputbuffer, 256,
+ tilebuffer, 256 );
+ assert(ret == 1);
+ if( tilebuffer[0] != expected_c ||
+ tilebuffer[255] != expected_c )
+ {
+ fprintf(stderr, "unexpected value at tile %d: %d %d\n",
+ j, tilebuffer[0], tilebuffer[255]);
+ TIFFClose(tif);
+ fclose(f);
+ return 1;
+ }
+ }
+ }
+ }
+ else
+ {
+ int j;
+ for( j = 0; j < height; j++ )
+ {
+ int retry;
+ unsigned char expected_c = (unsigned char)j;
+ for( retry = 0; retry < 2; retry++ )
+ {
+ unsigned char c = 0;
+ ret = TIFFReadEncodedStrip( tif, j, &c, 1 );
+ assert(ret == 1);
+ if( c != expected_c )
+ {
+ fprintf(stderr, "unexpected value at line %d: %d\n",
+ j, c);
+ TIFFClose(tif);
+ fclose(f);
+ return 1;
+ }
+ }
+
+ {
+ int err = 0;
+ int offset, size;
+ unsigned char inputbuffer[1];
+ unsigned char tilebuffer[1];
+
+ offset = TIFFGetStrileOffsetWithErr(tif, j, &err);
+ assert(offset != 0);
+ assert(err == 0);
+
+ size = TIFFGetStrileByteCountWithErr(tif, j, &err);
+ assert(size == 1);
+ assert(err == 0);
+
+ fseek(f, offset, SEEK_SET);
+ fread(inputbuffer, 1, 1, f);
+
+ memset(tilebuffer,0, 1);
+ ret = TIFFReadFromUserBuffer(tif, j,
+ inputbuffer, 1,
+ tilebuffer, 1 );
+ assert(ret == 1);
+ if( tilebuffer[0] != expected_c )
+ {
+ fprintf(stderr, "unexpected value at line %d: %d\n",
+ j, tilebuffer[0]);
+ TIFFClose(tif);
+ fclose(f);
+ return 1;
+ }
+ }
+
+ if( j == 1 && height > 100000 )
+ j = height - 2;
+ }
+
+ if( height > 100000 )
+ {
+ /* Missing strip */
+ int err = 0;
+ ret = TIFFGetStrileOffsetWithErr(tif, 2, &err);
+ assert(ret == 0);
+ assert(err == 0);
+
+ ret = TIFFGetStrileByteCountWithErr(tif, 2, &err);
+ assert(ret == 0);
+ assert(err == 0);
+
+ }
+ }
+
+ {
+ int err = 0;
+ ret = TIFFGetStrileOffsetWithErr(tif, 0xFFFFFFFFU, &err);
+ assert(ret == 0);
+ assert(err == 1);
+
+ ret = TIFFGetStrileByteCountWithErr(tif, 0xFFFFFFFFU, &err);
+ assert(ret == 0);
+ assert(err == 1);
+ }
+
+ {
+ toff_t* offsets = NULL;
+ toff_t* bytecounts = NULL;
+ ret = TIFFGetField( tif,
+ tiled ? TIFFTAG_TILEOFFSETS : TIFFTAG_STRIPOFFSETS, &offsets );
+ assert(ret);
+ assert(offsets);
+ ret = TIFFGetField( tif,
+ tiled ? TIFFTAG_TILEBYTECOUNTS : TIFFTAG_STRIPBYTECOUNTS, &bytecounts );
+ assert(ret);
+ assert(bytecounts);
+ if( tiled )
+ {
+ assert(bytecounts[0] == 256);
+ }
+ else
+ {
+ assert(bytecounts[0] == 1);
+ if( height > 1 && height <= 100000)
+ {
+ assert(offsets[1] == offsets[0] + 1);
+ assert(offsets[height - 1] == offsets[0] + height - 1);
+ }
+ assert(bytecounts[height - 1] == 1);
+ }
+ }
+
+ TIFFClose(tif);
+ }
+ fclose(f);
+
+ unlink(filename);
+ return 0;
+}
+
+int
+main()
+{
+ int is_classic;
+ for( is_classic = 1; is_classic >= 0; is_classic-- )
+ {
+ int tiled;
+ for( tiled = 0; tiled <= 1; tiled ++ )
+ {
+ if( test(is_classic, 1, tiled) )
+ return 1;
+ if( test(is_classic, 8192, tiled) )
+ return 1;
+ }
+ if( test(is_classic, 2000000, 0) )
+ return 1;
+ }
+ return 0;
+}
diff --git a/test/defer_strile_writing.c b/test/defer_strile_writing.c
new file mode 100644
index 00000000..4e358567
--- /dev/null
+++ b/test/defer_strile_writing.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2019, Even Rouault <even.rouault at spatialys.com>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library
+ *
+ * Module to test TIFFDeferStrileArrayWriting and TIFFForceStrileArrayWriting
+ */
+
+#include "tif_config.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#include "tiffio.h"
+
+int test(const char* mode, int tiled, int height)
+{
+ const char* filename = "defer_strile_writing.tif";
+ TIFF* tif;
+ int i;
+ int ret = 0;
+ (void)ret;
+
+ tif = TIFFOpen(filename, mode);
+ if(!tif)
+ {
+ fprintf(stderr, "cannot create %s\n", filename);
+ return 1;
+ }
+ ret = TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
+ assert(ret);
+ ret = TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, 1);
+ assert(ret);
+ ret = TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
+ assert(ret);
+ ret = TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
+ assert(ret);
+ ret = TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
+ assert(ret);
+ ret = TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+ assert(ret);
+
+ if( tiled )
+ {
+ ret = TIFFSetField(tif, TIFFTAG_TILEWIDTH, 16);
+ assert( ret );
+ ret = TIFFSetField(tif, TIFFTAG_TILELENGTH, 16);
+ assert( ret );
+ }
+ else
+ {
+ ret = TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
+ assert(ret);
+ }
+
+ ret = TIFFDeferStrileArrayWriting(tif);
+ assert(ret);
+
+ ret = TIFFWriteCheck( tif, tiled, "test" );
+ assert(ret);
+
+ ret = TIFFWriteDirectory( tif );
+ assert(ret);
+
+ /* Create other directory */
+ TIFFFreeDirectory( tif );
+ TIFFCreateDirectory( tif );
+
+ ret = TIFFSetField( tif, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE );
+ assert(ret);
+ ret = TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
+ assert(ret);
+ ret = TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, 1);
+ assert(ret);
+ ret = TIFFSetField(tif, TIFFTAG_IMAGELENGTH, 1);
+ assert(ret);
+ ret = TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
+ assert(ret);
+ ret = TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
+ assert(ret);
+ ret = TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+ assert(ret);
+ ret = TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
+ assert(ret);
+
+ ret = TIFFDeferStrileArrayWriting(tif);
+ assert(ret);
+
+ ret = TIFFWriteCheck( tif, 0, "test" );
+ assert(ret);
+
+ ret = TIFFWriteDirectory( tif );
+ assert(ret);
+
+ /* Force writing of strile arrays */
+ ret = TIFFSetDirectory( tif, 0 );
+ assert(ret);
+
+ ret = TIFFForceStrileArrayWriting(tif);
+ assert(ret);
+
+ ret = TIFFSetDirectory( tif, 1 );
+ assert(ret);
+
+ ret = TIFFForceStrileArrayWriting(tif);
+ assert(ret);
+
+ /* Now write data on frist directory */
+ ret = TIFFSetDirectory( tif, 0 );
+ assert(ret);
+
+ if( tiled )
+ {
+ int j;
+ for( j = 0; j < (height+15) / 16; j++ )
+ {
+ unsigned char tilebuffer[256];
+ memset(tilebuffer, (unsigned char)j, 256);
+ ret = TIFFWriteEncodedTile( tif, j, tilebuffer, 256 );
+ assert(ret == 256);
+ }
+ }
+ else
+ {
+ for( i = 0; i < height; i++ )
+ {
+ unsigned char c = (unsigned char)i;
+ ret = TIFFWriteEncodedStrip( tif, i, &c, 1 );
+ assert(ret == 1);
+
+ if( i == 1 && height > 100000 )
+ i = height - 2;
+ }
+ }
+
+ TIFFClose(tif);
+
+ tif = TIFFOpen(filename, "r");
+ if(!tif)
+ {
+ fprintf(stderr, "cannot open %s\n", filename);
+ return 1;
+ }
+ if( tiled )
+ {
+ int j;
+ for( j = 0; j < (height+15) / 16; j++ )
+ {
+ int retry;
+ for( retry = 0; retry < 2; retry++ )
+ {
+ unsigned char tilebuffer[256];
+ unsigned char expected_c = (unsigned char)j;
+ memset(tilebuffer,0, 256);
+ ret = TIFFReadEncodedTile( tif, j, tilebuffer, 256 );
+ assert(ret == 256);
+ if( tilebuffer[0] != expected_c ||
+ tilebuffer[255] != expected_c )
+ {
+ fprintf(stderr, "unexpected value at tile %d: %d %d\n",
+ j, tilebuffer[0], tilebuffer[255]);
+ TIFFClose(tif);
+ return 1;
+ }
+ }
+ }
+ }
+ else
+ {
+ int j;
+ for( j = 0; j < height; j++ )
+ {
+ int retry;
+ for( retry = 0; retry < 2; retry++ )
+ {
+ unsigned char c = 0;
+ unsigned char expected_c = (unsigned char)j;
+ ret = TIFFReadEncodedStrip( tif, j, &c, 1 );
+ assert(ret == 1);
+ if( c != expected_c )
+ {
+ fprintf(stderr, "unexpected value at line %d: %d\n",
+ j, c);
+ TIFFClose(tif);
+ return 1;
+ }
+ }
+ }
+ }
+
+ TIFFClose(tif);
+
+ unlink(filename);
+ return 0;
+}
+
+int
+main()
+{
+ int tiled;
+ for( tiled = 0; tiled <= 1; tiled ++ )
+ {
+ if( test("w", tiled, 1) )
+ return 1;
+ if( test("w", tiled, 10) )
+ return 1;
+ if( test("w8", tiled, 1) )
+ return 1;
+ if( test("wD", tiled, 1) )
+ return 1;
+ }
+ return 0;
+}
diff --git a/test/fax2tiff.sh b/test/fax2tiff.sh
new file mode 100755
index 00000000..8806a647
--- /dev/null
+++ b/test/fax2tiff.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+#
+# Basic sanity check for fax2tiff
+#
+. ${srcdir:-.}/common.sh
+infile="${IMAGES}/miniswhite-1c-1b.g3"
+outfile="o-fax2tiff.tiff"
+rm -f $outfile
+echo "$MEMCHECK ${FAX2TIFF} -M -o $outfile $infile"
+eval $MEMCHECK ${FAX2TIFF} -M -o $outfile $infile
+status=$?
+if [ $status != 0 ] ; then
+ echo "Returned failed status $status!"
+ echo "Output (if any) is in \"${outfile}\"."
+ exit $status
+fi
+f_tiffinfo_validate $outfile
diff --git a/test/images/README.txt b/test/images/README.txt
index 17f6292e..b6447d8e 100644
--- a/test/images/README.txt
+++ b/test/images/README.txt
@@ -27,3 +27,6 @@ PNM files:
minisblack-1c-8b.pgm
miniswhite-1c-1b.pbm
rgb-3c-8b.ppm
+
+G3 Fax files :
+ miniswhite-1c-1b.g3
diff --git a/test/images/miniswhite-1c-1b.g3 b/test/images/miniswhite-1c-1b.g3
new file mode 100644
index 00000000..9f00ce16
--- /dev/null
+++ b/test/images/miniswhite-1c-1b.g3
Binary files differ
diff --git a/test/images/ojpeg_chewey_subsamp21_multi_strip.tiff b/test/images/ojpeg_chewey_subsamp21_multi_strip.tiff
new file mode 100644
index 00000000..8b04d473
--- /dev/null
+++ b/test/images/ojpeg_chewey_subsamp21_multi_strip.tiff
Binary files differ
diff --git a/test/images/ojpeg_single_strip_no_rowsperstrip.tiff b/test/images/ojpeg_single_strip_no_rowsperstrip.tiff
new file mode 100644
index 00000000..61611b9d
--- /dev/null
+++ b/test/images/ojpeg_single_strip_no_rowsperstrip.tiff
Binary files differ
diff --git a/test/images/ojpeg_zackthecat_subsamp22_single_strip.tiff b/test/images/ojpeg_zackthecat_subsamp22_single_strip.tiff
new file mode 100644
index 00000000..15185b68
--- /dev/null
+++ b/test/images/ojpeg_zackthecat_subsamp22_single_strip.tiff
Binary files differ
diff --git a/test/ppm2tiff_pbm.sh b/test/ppm2tiff_pbm.sh
index 68d9e459..fb6c3cf7 100755
--- a/test/ppm2tiff_pbm.sh
+++ b/test/ppm2tiff_pbm.sh
@@ -1,5 +1,4 @@
#!/bin/sh
-# Generated file, master is Makefile.am
. ${srcdir:-.}/common.sh
infile="$IMG_MINISWHITE_1C_1B_PBM"
outfile="o-ppm2tiff_pbm.tiff"
diff --git a/test/ppm2tiff_pgm.sh b/test/ppm2tiff_pgm.sh
index 001ec706..60352348 100755
--- a/test/ppm2tiff_pgm.sh
+++ b/test/ppm2tiff_pgm.sh
@@ -1,5 +1,4 @@
#!/bin/sh
-# Generated file, master is Makefile.am
. ${srcdir:-.}/common.sh
infile="$IMG_MINISBLACK_1C_8B_PGM"
outfile="o-ppm2tiff_pgm.tiff"
diff --git a/test/ppm2tiff_ppm.sh b/test/ppm2tiff_ppm.sh
index 8a81527b..e213a71d 100755
--- a/test/ppm2tiff_ppm.sh
+++ b/test/ppm2tiff_ppm.sh
@@ -1,5 +1,4 @@
#!/bin/sh
-# Generated file, master is Makefile.am
. ${srcdir:-.}/common.sh
infile="$IMG_RGB_3C_8B_PPM"
outfile="o-ppm2tiff_ppm.tiff"
diff --git a/test/refs/o-tiff2ps-EPS1.ps b/test/refs/o-tiff2ps-EPS1.ps
new file mode 100644
index 00000000..9d9da8a2
--- /dev/null
+++ b/test/refs/o-tiff2ps-EPS1.ps
@@ -0,0 +1,112 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%Creator: tiff2ps
+%%Title: miniswhite-1c-1b.tiff
+%%CreationDate: Tue Apr 2 16:33:00 2019
+%%DocumentData: Clean7Bit
+%%Origin: 0 0
+%%BoundingBox: 0 0 157 151
+%%LanguageLevel: 1
+%%Pages: 1 1
+%%EndComments
+%%Page: 1 1
+gsave
+100 dict begin
+157.000000 151.000000 scale
+%ImageData: 157 151 1 1 0 1 2 "image"
+/scanLine 20 string def
+157 151 1
+[157 0 0 -151 0 151]
+{currentfile scanLine readhexstring pop} bind
+image
+0204153c0bfffffffff1ffffc7e01017ff8057ff5aa2803e1ffffffe0697ffffc7e485
+dfffd77fff48aca4dfd7fffff80003ffffcffe017fffe0c7ff1101250ffbfffff0241b
+ffffffff80fffff37fff29fa48abf7ffffe41221ffffafffe3fffff19fff7ff82200f7
+fdff0040803fff5ffff5ffffe17ffffffe00088bc0070008259fff7ffffdfffff0ffff
+7ffe040003c0001222001fff3ffffffffff15fdfffff084003004104809493fc1dffff
+ffffc1badfffff0fd000010020140009e337ffffffffc3efffffff1abc040400000502
+04c6bfffffefffc36b7ffffe1ffe0c808804009490061bffffffff82fafffffc3dff08
+080000020042a78fffffffff87f7fffffc1fff0c0010428049080c27ffffffff87feff
+fffc7ffd108000e0611090103ffffffffe077dfffffdbffc340003e808020203cfffff
+fffc0bd77fffe0fffc000003e10022008877fffffffc06fdff3fe35ffc780217c02808
+28000ffffffff80f5fff6bc27ff040000fc00100a20103ffffffc007f5ff5ec2ffe082
+200bc480420454a1ffffffe0065fff7fc5ff0010005f1000205a4929ffffffe003d7ff
+5fe7b80008202f029804000000ffffffc003efff37e5fe0010001e0401020240917fff
+ffc004effffffbf80022001f018888a429087fffff8007b7ff5ff3e00080009c002122
+2544015ffff9c01fb7ff7ef7c0100400fc8408000020981ffff0783fe97f77fbc00800
+017e009006560a4547ffd2bffbffff5fd780020000f801041000a00033fccdbb9ffeff
+1ba000500003fa1024a249125025f033effffeffffc000c00042f002860800880540d0
+47ffffffff574001c80003f9803e405054411400a9bfffffff7e0003804003f00a0302
+090114800005efffffff6f0003880007fc0203a040a3522a4017ffffffff5f00034000
+1af980a884120f1f8c000adffffffffff80fc0000ff82810420a27ffa800067fffffff
+fff80f400033fc010a44508fff8e000bfffffffffffc0fc0003ff9809842404fff9e20
+07ffffdff7fffe0d400003ff200220291fff9b401afffffffffffc1fe01359ff089620
+015fffaa001bffffff1ffffa3d703eeeff810b22480fff905006fffffd6ffff81fb078
+adffe40e00412fff85400d7ffff9fffff01d787fedffe08ba8185fff501007ffff925f
+fff03af8e7f7fff13f81401ffe054005ffffc1fffff03ffcf5effff00fa0094754d310
+05fffb07bfff803ffdddfffff00fe0145ea503d00fffff2f5fff003abfdffffff23fd2
+000151a7d81afffe3f7f7f803bbffffffff88fe081a02a23d006fffe7fbf39403ffebf
+fffff23fe408068007d00bfffeffff6bf83f7f7ffffffd1fe01004aa2ff005fffff55f
+46581afde7fffff087f00151008fd0027fffe2ff75f83fdc7bfffff05ff04004600fc0
+097fffc7ff79503677fffffff90ffa0495069f9002b7ffc9bf1e403edb7bfffff94ff0
+0420005f000127f7c3ff1e201764dffffff811440106963f80001ddffc5f0000296bbf
+fffff842920b0200fe0000007fffbf00003681ebfffff8096cffc094fc20001fffff5f
+000001015ffffff88064dfc001f980003ffffff700000200f9fffff0130a0fc29af400
+007fffffff00000003affffff8041403c2297d1800ffffffcf00000003fdfffff000a9
+87e402d01800fffffff720300002bfbffff8299407f005a09800fffffff764000003da
+fffff80001aff020040000ffffffef78c00001fbfffff0002107f020880000ffffffc7
+db000003dffffff0024c87f042100000ffffffd759000003f6fffff0100895f801400d
+00ffffffc7f3000007fffffff0024137f81e781fe0dfffff8f6c000007effffff00001
+fbfc29fc37b0ffffff8748000003feffffe000017efc11de5fe06fffff07d0000007df
+fffff000037bfc13ff9ff07fffff8700000007fffffff0000ffcfe227ffff837ffff1f
+2000000fbbfffff0003dfffe41fffffc1fffffe75000000fffffffe00205fdff647fff
+f816ffffc7a0000007dfffffe06f843dff635fffff03fdff074000000fffffffe1b3e0
+1affe9ff67ff0522ce074000000fffffffc0bfb003ffc9f27ffe0398290700000007f7
+ffff81fff00fffce4077ff04a020470000000fffffff86fff8057ffcc05fff0000000f
+0000000fffffff837ffa0ffff780ffff0000000700000017bfffff0fffff0ffff601ff
+ff000000470000000fffffff09dfc78bffffc22fff0000000700000007ffffff0d5bf0
+eeffff89ffff0000000f0000000fffffff0bfff87eff8f12bfff000000270000000fff
+ffff0feffc27fffd055fff000004070000001f7fffff3fb6d7ffff7907fffe0000000f
+0000001ffffffc3e5d476fc0dd7fffff0000200f0000000ffffffc1ffdbdf5f12bffff
+ff0000015f0000001ffffffc1f97edfff05fffefff0000003f0000000ffffff839febb
+5ffcabbffffe000008bf0000002ffffffc3d56bfb7ff5fffffff000084ff0000001fff
+fff85bdde5fffe29ffffff000000ff0000003fffffe066baaffffebbffffff000012ff
+0000001ffffff02aebf66ffe5dffffff000001ff0000001fffffd057757bffff257fff
+ff00000bff0000002fffffe0ad575f5fffd5ffffff000240ff0000003fffffc05bbcfe
+bfff0a7fffff000003f70000006fffffc02aeb95ffffa5ffffff000093f70000003bff
+ffc0aff99df77f0a7bfffe000423f70000003fffffb0112e733ffe95ddfefe000047c7
+0000007fffffe01bf7eeedff0ab3defe00000b970000005fffff804415a9b775a54fff
+ee000027c70000007fffff8036db4a3fb685ba7ffe00008787000050bffffff0080455
+e6dd5867df6c000015870000007fffff801051a06eba9abfdffe000003070000605fff
+ffc006082bb7ed954976f800000c07000000ffffffc004022a757a252bf7fc00002507
+0000a07effff700568591fe55ada2e9c00000007000000bffffe400a3a24a55a656fff
+bc00000587000000fffffbe000845a5df81ad59af8000020070000009fffffe0004c24
+93c85556edf400000007000000ffffbf8000b25b2dbd1aa57bbc00000007000001ffff
+ffa000491466e0035c5ffc00001407000001bfffffc000248b0bb86497db7000000007
+000000ffffff4000122a35390a26effc000000070000007fffff8000498782e454d579
+7c00000007000001bfffffc000210953ba89495ff400000007000001fbffffc0002892
+a968256ebde800000007000001ffffffc000858581f914dbfb7c00000007000003bfff
+ff00002142649887699dfc00000007000001bfffff00004a80a961296dffe802000007
+000002dfffff00001191489822b757f800000007400001bfffff00001004a9a85576fb
+d8000000077e2007ffffff0000038141500a97afb8000000077658077bffff00000611
+aca951ee79d000000007ffa207effffe0000008a51500c556ff000000007ffc907ffff
+fe0000028141c80467e77000000007ff74065ffffe00000126ac50005cbfe000000007
+ffe80dfffffc0000008155a00017efc000000007fffe075ffffc000002a4aa58012937
+4000000007fffc0efffffc00000003ad50002acd8500000007fffd19dffffc000000a0
+62a000077f8058000007fffa0dfffffc00000084d9a800157501f0000007fffe06bfff
+fc000000216450006dce023f000007fffc06bffff0000000601a400015d801ff500007
+fff009e7fff000000000418000057001ffb28007ffe0037fffe0000000c0a000000240
+07fffe8007fff0011bffe000000010010000007b21ffffe007ffffffffffe000000000
+000000007f82fffffc07ffffffffffc000000000000000007fc1ffffff07ffffffffff
+c900000000000000006c04fffffb07ffffffffffffa0000000000000000c027ffff847
+ffffffffffffffc00000000000000001affffa27fffffffffffffff000000000000000
+04005ffc07fffffffffffffffd0000000000000000000000075fffffffffffffffc000
+000000000000220180ef1ffffffffffffffffe00000000000002000883ff1fffffffff
+ffffffff00001800000000000009ff3fffffffffffffffff0000000001418000003bff
+2fffffffffffffffff00010000027000901207ff7fffffffffffffffff7e00010037f8
+0018000fff7fffffffffffffffffff00a44007fc0030423fff7fffffffffffffffffff
+c043002ffc003000afff
+end
+grestore
+showpage
+%%Trailer
+%%EOF
diff --git a/test/refs/o-tiff2ps-PS1.ps b/test/refs/o-tiff2ps-PS1.ps
new file mode 100644
index 00000000..62c3e4bb
--- /dev/null
+++ b/test/refs/o-tiff2ps-PS1.ps
@@ -0,0 +1,115 @@
+%!PS-Adobe-3.0
+%%Creator: tiff2ps
+%%Title: miniswhite-1c-1b.tiff
+%%CreationDate: Tue Apr 2 16:33:00 2019
+%%DocumentData: Clean7Bit
+%%Origin: 0 0
+%%BoundingBox: 0 0 157 151
+%%LanguageLevel: 1
+%%Pages: (atend)
+%%EndComments
+%%BeginSetup
+%%EndSetup
+%%Page: 1 1
+gsave
+100 dict begin
+157.000000 151.000000 scale
+%ImageData: 157 151 1 1 0 1 2 "image"
+/scanLine 20 string def
+157 151 1
+[157 0 0 -151 0 151]
+{currentfile scanLine readhexstring pop} bind
+image
+0204153c0bfffffffff1ffffc7e01017ff8057ff5aa2803e1ffffffe0697ffffc7e485
+dfffd77fff48aca4dfd7fffff80003ffffcffe017fffe0c7ff1101250ffbfffff0241b
+ffffffff80fffff37fff29fa48abf7ffffe41221ffffafffe3fffff19fff7ff82200f7
+fdff0040803fff5ffff5ffffe17ffffffe00088bc0070008259fff7ffffdfffff0ffff
+7ffe040003c0001222001fff3ffffffffff15fdfffff084003004104809493fc1dffff
+ffffc1badfffff0fd000010020140009e337ffffffffc3efffffff1abc040400000502
+04c6bfffffefffc36b7ffffe1ffe0c808804009490061bffffffff82fafffffc3dff08
+080000020042a78fffffffff87f7fffffc1fff0c0010428049080c27ffffffff87feff
+fffc7ffd108000e0611090103ffffffffe077dfffffdbffc340003e808020203cfffff
+fffc0bd77fffe0fffc000003e10022008877fffffffc06fdff3fe35ffc780217c02808
+28000ffffffff80f5fff6bc27ff040000fc00100a20103ffffffc007f5ff5ec2ffe082
+200bc480420454a1ffffffe0065fff7fc5ff0010005f1000205a4929ffffffe003d7ff
+5fe7b80008202f029804000000ffffffc003efff37e5fe0010001e0401020240917fff
+ffc004effffffbf80022001f018888a429087fffff8007b7ff5ff3e00080009c002122
+2544015ffff9c01fb7ff7ef7c0100400fc8408000020981ffff0783fe97f77fbc00800
+017e009006560a4547ffd2bffbffff5fd780020000f801041000a00033fccdbb9ffeff
+1ba000500003fa1024a249125025f033effffeffffc000c00042f002860800880540d0
+47ffffffff574001c80003f9803e405054411400a9bfffffff7e0003804003f00a0302
+090114800005efffffff6f0003880007fc0203a040a3522a4017ffffffff5f00034000
+1af980a884120f1f8c000adffffffffff80fc0000ff82810420a27ffa800067fffffff
+fff80f400033fc010a44508fff8e000bfffffffffffc0fc0003ff9809842404fff9e20
+07ffffdff7fffe0d400003ff200220291fff9b401afffffffffffc1fe01359ff089620
+015fffaa001bffffff1ffffa3d703eeeff810b22480fff905006fffffd6ffff81fb078
+adffe40e00412fff85400d7ffff9fffff01d787fedffe08ba8185fff501007ffff925f
+fff03af8e7f7fff13f81401ffe054005ffffc1fffff03ffcf5effff00fa0094754d310
+05fffb07bfff803ffdddfffff00fe0145ea503d00fffff2f5fff003abfdffffff23fd2
+000151a7d81afffe3f7f7f803bbffffffff88fe081a02a23d006fffe7fbf39403ffebf
+fffff23fe408068007d00bfffeffff6bf83f7f7ffffffd1fe01004aa2ff005fffff55f
+46581afde7fffff087f00151008fd0027fffe2ff75f83fdc7bfffff05ff04004600fc0
+097fffc7ff79503677fffffff90ffa0495069f9002b7ffc9bf1e403edb7bfffff94ff0
+0420005f000127f7c3ff1e201764dffffff811440106963f80001ddffc5f0000296bbf
+fffff842920b0200fe0000007fffbf00003681ebfffff8096cffc094fc20001fffff5f
+000001015ffffff88064dfc001f980003ffffff700000200f9fffff0130a0fc29af400
+007fffffff00000003affffff8041403c2297d1800ffffffcf00000003fdfffff000a9
+87e402d01800fffffff720300002bfbffff8299407f005a09800fffffff764000003da
+fffff80001aff020040000ffffffef78c00001fbfffff0002107f020880000ffffffc7
+db000003dffffff0024c87f042100000ffffffd759000003f6fffff0100895f801400d
+00ffffffc7f3000007fffffff0024137f81e781fe0dfffff8f6c000007effffff00001
+fbfc29fc37b0ffffff8748000003feffffe000017efc11de5fe06fffff07d0000007df
+fffff000037bfc13ff9ff07fffff8700000007fffffff0000ffcfe227ffff837ffff1f
+2000000fbbfffff0003dfffe41fffffc1fffffe75000000fffffffe00205fdff647fff
+f816ffffc7a0000007dfffffe06f843dff635fffff03fdff074000000fffffffe1b3e0
+1affe9ff67ff0522ce074000000fffffffc0bfb003ffc9f27ffe0398290700000007f7
+ffff81fff00fffce4077ff04a020470000000fffffff86fff8057ffcc05fff0000000f
+0000000fffffff837ffa0ffff780ffff0000000700000017bfffff0fffff0ffff601ff
+ff000000470000000fffffff09dfc78bffffc22fff0000000700000007ffffff0d5bf0
+eeffff89ffff0000000f0000000fffffff0bfff87eff8f12bfff000000270000000fff
+ffff0feffc27fffd055fff000004070000001f7fffff3fb6d7ffff7907fffe0000000f
+0000001ffffffc3e5d476fc0dd7fffff0000200f0000000ffffffc1ffdbdf5f12bffff
+ff0000015f0000001ffffffc1f97edfff05fffefff0000003f0000000ffffff839febb
+5ffcabbffffe000008bf0000002ffffffc3d56bfb7ff5fffffff000084ff0000001fff
+fff85bdde5fffe29ffffff000000ff0000003fffffe066baaffffebbffffff000012ff
+0000001ffffff02aebf66ffe5dffffff000001ff0000001fffffd057757bffff257fff
+ff00000bff0000002fffffe0ad575f5fffd5ffffff000240ff0000003fffffc05bbcfe
+bfff0a7fffff000003f70000006fffffc02aeb95ffffa5ffffff000093f70000003bff
+ffc0aff99df77f0a7bfffe000423f70000003fffffb0112e733ffe95ddfefe000047c7
+0000007fffffe01bf7eeedff0ab3defe00000b970000005fffff804415a9b775a54fff
+ee000027c70000007fffff8036db4a3fb685ba7ffe00008787000050bffffff0080455
+e6dd5867df6c000015870000007fffff801051a06eba9abfdffe000003070000605fff
+ffc006082bb7ed954976f800000c07000000ffffffc004022a757a252bf7fc00002507
+0000a07effff700568591fe55ada2e9c00000007000000bffffe400a3a24a55a656fff
+bc00000587000000fffffbe000845a5df81ad59af8000020070000009fffffe0004c24
+93c85556edf400000007000000ffffbf8000b25b2dbd1aa57bbc00000007000001ffff
+ffa000491466e0035c5ffc00001407000001bfffffc000248b0bb86497db7000000007
+000000ffffff4000122a35390a26effc000000070000007fffff8000498782e454d579
+7c00000007000001bfffffc000210953ba89495ff400000007000001fbffffc0002892
+a968256ebde800000007000001ffffffc000858581f914dbfb7c00000007000003bfff
+ff00002142649887699dfc00000007000001bfffff00004a80a961296dffe802000007
+000002dfffff00001191489822b757f800000007400001bfffff00001004a9a85576fb
+d8000000077e2007ffffff0000038141500a97afb8000000077658077bffff00000611
+aca951ee79d000000007ffa207effffe0000008a51500c556ff000000007ffc907ffff
+fe0000028141c80467e77000000007ff74065ffffe00000126ac50005cbfe000000007
+ffe80dfffffc0000008155a00017efc000000007fffe075ffffc000002a4aa58012937
+4000000007fffc0efffffc00000003ad50002acd8500000007fffd19dffffc000000a0
+62a000077f8058000007fffa0dfffffc00000084d9a800157501f0000007fffe06bfff
+fc000000216450006dce023f000007fffc06bffff0000000601a400015d801ff500007
+fff009e7fff000000000418000057001ffb28007ffe0037fffe0000000c0a000000240
+07fffe8007fff0011bffe000000010010000007b21ffffe007ffffffffffe000000000
+000000007f82fffffc07ffffffffffc000000000000000007fc1ffffff07ffffffffff
+c900000000000000006c04fffffb07ffffffffffffa0000000000000000c027ffff847
+ffffffffffffffc00000000000000001affffa27fffffffffffffff000000000000000
+04005ffc07fffffffffffffffd0000000000000000000000075fffffffffffffffc000
+000000000000220180ef1ffffffffffffffffe00000000000002000883ff1fffffffff
+ffffffff00001800000000000009ff3fffffffffffffffff0000000001418000003bff
+2fffffffffffffffff00010000027000901207ff7fffffffffffffffff7e00010037f8
+0018000fff7fffffffffffffffffff00a44007fc0030423fff7fffffffffffffffffff
+c043002ffc003000afff
+end
+grestore
+showpage
+%%Trailer
+%%Pages: 1
+%%EOF
diff --git a/test/refs/o-tiff2ps-PS2.ps b/test/refs/o-tiff2ps-PS2.ps
new file mode 100644
index 00000000..e7fe4339
--- /dev/null
+++ b/test/refs/o-tiff2ps-PS2.ps
@@ -0,0 +1,104 @@
+%!PS-Adobe-3.0
+%%Creator: tiff2ps
+%%Title: miniswhite-1c-1b.tiff
+%%CreationDate: Tue Apr 2 16:33:00 2019
+%%DocumentData: Clean7Bit
+%%Origin: 0 0
+%%BoundingBox: 0 0 157 151
+%%LanguageLevel: 2
+%%Pages: (atend)
+%%EndComments
+%%BeginSetup
+gsave newpath clippath pathbbox grestore
+ 4 2 roll 2 copy translate
+ exch 3 1 roll sub 3 1 roll sub exch
+ currentpagedevice /PageSize get aload pop
+ exch 3 1 roll div 3 1 roll div abs exch abs
+ 2 copy gt { exch } if pop
+ dup 1 lt { dup scale } { pop } ifelse
+%%EndSetup
+%%Page: 1 1
+%%PageOrientation: Landscape
+%%PageBoundingBox: 0 0 157 151
+1 dict begin /PageSize [ 157.000000 151.000000 ] def currentdict end setpagedevice
+<<
+ /Policies <<
+ /PageSize 3
+ >>
+>> setpagedevice
+gsave
+100 dict begin
+157.000000 151.000000 scale
+% PostScript Level 2 only.
+/DeviceGray setcolorspace
+{ % exec
+ /im_stream currentfile /ASCII85Decode filter def
+ <<
+ /ImageType 1
+ /Width 157
+ /Height 151
+ /ImageMatrix [ 157 0 0 -151 0 151 ]
+ /BitsPerComponent 1
+ /Interpolate true
+ /Decode [1 0]
+ /DataSource im_stream
+ >> image
+ im_stream status { im_stream flushfile } if
+}
+exec
+rVPltoDejk!"Ju/3$7VQ!.UpIV-SSehuE`Xq.Ka.3#d/d!%<?t[o6KR-ia5Ps82is0EM0'!$=0#
+mf(r0"98E4gZ/>7!!%KK!"=AXeciN^#QOiDmG7gC:]MI8!"NB:J-Xp1#Qb#+^OO$!TE#<!!$6Xj
+!!3,oF?fR#pY'!TJ,fWN!"T&0J-#QIr'15Kh>cC5^]4?7!"PYE!!)c.r;XM.Iqrj&iW&rY!'Wgo
+!!)LAs8N&Uli6Yua8c2?!'Cem!!)+JqtpEnqYg:O5QCcq!'HKr!!2!Yo7(u]s(cQKj8]/[!.>"N
+!!C(<p\4^frVsQ5Du]k<!-ebL!!D-ZoDe9mJ%#+CfDkmO!-eME!!@`Qmsk?ZT'pUd^]4?7!Vh6H
+!!5CfbQ%JVp\k'g0E;(Q"8"!l!$;1Cs8W!<s5!^!L]@DT"8Muu^`9!LL]-F$fD!nsn,NFg#OnAd
+PWaO-^]3dfrr6:'qu?]s5PPQcTfiAtIGaZYJ%b`[?2ss*+8MQ0J3!]1n,K'Ls50Z]ec5[M+8dMe
+TGU3!pYX?rBD_`/rr<$!5Pu&ma;P*Zn,MADrr)f1DL_]e5Pkul!!EQ,h>cF4GB[9BpOE5DJ+uP7
+TF;qBJ,a$YhVHntrh'5q5N#'4JI"L/qu6bFp](9NBA`b#LVO[UL]fs:s8ITLDu$C*]!q_l5Qh&e
+TI><gs8N?'qsXPls3(R#6sp#qjBqqjs83&hgKh8TYM'N2&-)_2!'gKJs1JsAH2%>_qS+\nzW5&<j
+s83(N_8!1S^?bf"5QCcaJcGXt^\eW8r;H?gl[Ss2&-)\1OT56&s7c]pr*R3DXjt2MzT`=r)s5aH7
+=*s?(i,eqk+92BA!!i!Xs6p9Fn%JDH!*B3rJ,fQL!!i#.s3(TEot.DH!-/&2z!!D^Ts1ehgB>)'a
+!+Fd[!!",I!!2Z*s82lSrSQ2a!+`k+z!!D.$m%sdWC#Ao_!*0'[!!!#W!!U6#_%?Zro\I"G!,o(:
+!!!(^!!hFXLJe*knc->M!.)ENJ,fcR!"\(EJ._i(FB@Xu!3bkd!!$l/!"[$R(^L*O^ja&V!W'S-
+!!#1_!"ZjI$4m1Jn6bn!X"<`9!!N'^!.Vcc+ohTRn/pti>5U&C!!(B=!<:#'+92BN^b,TcY#m(5
+!!0lcJ:GL&!!!!(E$'O9e_DhR!!.U8`kT:i5QCcn^`3%DJ+t\h!!*'"PR#!SJ,fQNi#hFb<R;9Q
+!!!A!\YnNj(]XOHGRseVs)9XiJ,gSiM?gpAKE(u_TF\g7TC>)=J,hP/L9J^T!!!!'n-/](q-\.>
+8,tP5iP32SKE(uVYRgWgs.KDkfEaS>iSWjg+92BHm^rJoBu#5uiZJ>rs8UZ75QCch]l!E?rrN0"
+s*t)7s8U2i'EA+<p6,J@CBNJohuEbMs8W)tTE"rsJ"%QFrW[lP^]4??s8W&t"onW6m.Kj2AIJP<
+J,fQLs8W,s:]LJ#qs4/Ceq3)b!!!!Qs8W,s!WW32s&O@`r@d@6!!!!)hp;?$5X5;Senb$kqHmn8
+!!!!)S,`Nd,ldoMs8Gh*hu!HR!!!!1LHkh<"98E4s5*M]hfo,#!!!!Y,ldoB+92BPrNg_Z^$l"$
+!!!!IVZ6\o#ljr9n+UQ%rkJ%(!!!!Y%0-A&!!!!0rP$>XiJ6>5+92C\PQ1[X&-)\@s8E-'ecWuh
+!!!"D\,ZL+!<<*As8IQOmNJ5FO8o:U0E;(I+92BPs87NPli:E(J,fRos8W,o!!!!0s6p*kh1,J1
+a8c4uhuE`G6i[2ts2"a:^&S-8huE`oYQ+Xl!!!!@rV?QqRt(JDkl:]C?iU0$+92B`OF+hES=fi^
+quQln^]4?'!!!!?9HW?r(''^%qV<n$^]4?'!!!!`5Yq:X2@Y0;r+FUUs8W,o#QOjR!"\Q!0u&ME
+qd86js8W,g!!!"E!!i@N"$`FYs8W,gs8W,g!!!"HJ-GEB#_)gSs8W,os8W,_5QCfR!!)Kg$2so)
+s8W,/s8W,g!!!#m+?4HC!'S[/s8W,os8W,o!!!#iU^n%;!-S>Bs8W,gs8W,g!!!#k!!e&TE:#mj
+s8W,Os8W,g!!!#g&-LPb!rAPis8Vuks8W,WJ,fSb8LOQ=LA1`Ls8W,gs8W,W!!!,;U:?:L,(KXn
+s8V!Gs8W,g!!!,Z!^[5(e,TIKs8W(ks8W,W!!!,ZBG(:UTE#N's8W,7s8W,g!!!8D!CWR_<'UEa
+s8VgYs8W,G!!!,<WB`uSTE"rls8REGs8W,W!!!8"+rUF^ec5[Ms8W*!s8W,7!!"+/78Nsb6i[2e
+s8VHds8W,W!!!P['FBj%U&Y/ns8W&us8W,W!!"[NMM(s0g40/'s8V]ks8W,G!!"*=W1]d`.KBGK
+s8B\4s8W,7!!#6Z6NKFPomd#Bs8W!&s8W+\!!#76'P[UJ=o\O&s8Qm@s8W,;!!#5[#%@jgon3;G
+s81RWs8W,7!!#g_d>YjAC*EZZs8TSgs8W+L!!",%#S@[Loh6M0s8V_)s8W+l!!%M\l;gH5>-Iu=
+s8U_2s8W+L!!%Mj,dkEZH:<>bs8R=gs8T8f!!!Q(ql1MXVjJTjs8VA/s8W+L!!%N;Y$[;[AO%@=
+s8W#ls8S^a!!#7ZpXD_HC:8s(s8V]cs8W*!!!#7\rRHdZg=-B1s8UgJs8QGW!!&)VQ_r[ZV'XN!
+s8W,os8W*a!!0k-`S4RmRZIM:s8Vq?s8W*!!!FDDH_mGAjXOgHs8V!Os8W+,!!",@ZeK:TWi6U=
+s8W,os8W*!!'l&69r-3(j][=)s8W,os8W&u!!$C+[d0>'r1fnes8VE[s8W'`!!#7`gN<'XRqO(.
+s8W,os8W*!!!'e6mFBA!p"9lYs8W,os8W+L!!%NK[Wm3>X"&jVs8W,os8W'`!!#7`hY+$>G.+%O
+s8W,os8W'$!!#7`f54QTg6"]<s8W,os8W&u!!#7`H?t#ElQcUcs8W,os8W!^!!*'!hS#CkGa;e@
+s8W,os8W'`!!*'![=;5Kerg"LrVuoms8W$?!!*'!mV]LHh+4ILs8W,o^]49u!!*'!n,$-eWegj+
+s8W,oJ`$5&!!*'!r-lA`ok7/ls8W,oM5U-%!!*'!q<h0^Xq?CAs8W,o!+#@2!!3-"s)kKJo;[l_
+s8W,o!&jTP!!3-"rI2I>qj84]s8W,o!/pZG!!3-"rn15Rs._h$s8W,o!#P2+!!E9$s*gtTs6("Y
+s8W,o!!2kf!!E9$rEE:"rmo0*s8W,o!!D`k!!E9$s85cus4&lNs8W,o!!;:*!!E9$s'M=(s7h+o
+VuQel!!Von!!E9$s*H(os6>L@&-)\)!!2m\!!E9$s5'6Ks,o,8_#OH0!!E$^!"],0s.ADfs6;!2
+!3cFt!"\c?!"],0s8Tf_s8%fU!)7t<!$D,h!$D7@s$'ljs8B_-!!.TE!"](i!$D7@s6oses8Rc/
+!!",9z!$D7@s8W-!s8RUt!!!,rz!'gM`s8W-!s8RU5!!!#oz!&jlWs8W-!s8S;[!!!/sz!!$C+
+s8W-!s8V]hJ,fhaz!!!!`s8W-!s8W,u:]L[Oz!!!!0s8W-!s8W,rs.BJhz!!!!#s8W-!s8W-!
+s8W,oTE"rlz5QCc`s8W-!h>Vm8huE`Wz!WW3"s8W,ts7^m@huE`Wz!<<)^s8W-!s8Vcm^]4?7
+z!<<*!s8K`^s8U";ci=%Gz!<<&us8A#YDsd<"J,fQLz!.k1Ls2YHFkPt#OJ,fQLz!!*%'^\@p2
+cb7*oJ,fQLz!!#6rs3LlJci6fA~>
+end
+grestore
+showpage
+%%Trailer
+%%Pages: 1
+%%EOF
diff --git a/test/refs/o-tiff2ps-PS3.ps b/test/refs/o-tiff2ps-PS3.ps
new file mode 100644
index 00000000..6ec22b9b
--- /dev/null
+++ b/test/refs/o-tiff2ps-PS3.ps
@@ -0,0 +1,104 @@
+%!PS-Adobe-3.0
+%%Creator: tiff2ps
+%%Title: miniswhite-1c-1b.tiff
+%%CreationDate: Tue Apr 2 16:33:00 2019
+%%DocumentData: Clean7Bit
+%%Origin: 0 0
+%%BoundingBox: 0 0 157 151
+%%LanguageLevel: 3
+%%Pages: (atend)
+%%EndComments
+%%BeginSetup
+gsave newpath clippath pathbbox grestore
+ 4 2 roll 2 copy translate
+ exch 3 1 roll sub 3 1 roll sub exch
+ currentpagedevice /PageSize get aload pop
+ exch 3 1 roll div 3 1 roll div abs exch abs
+ 2 copy gt { exch } if pop
+ dup 1 lt { dup scale } { pop } ifelse
+%%EndSetup
+%%Page: 1 1
+%%PageOrientation: Landscape
+%%PageBoundingBox: 0 0 157 151
+1 dict begin /PageSize [ 157.000000 151.000000 ] def currentdict end setpagedevice
+<<
+ /Policies <<
+ /PageSize 3
+ >>
+>> setpagedevice
+gsave
+100 dict begin
+157.000000 151.000000 scale
+% PostScript Level 2 only.
+/DeviceGray setcolorspace
+{ % exec
+ /im_stream currentfile /ASCII85Decode filter def
+ <<
+ /ImageType 1
+ /Width 157
+ /Height 151
+ /ImageMatrix [ 157 0 0 -151 0 151 ]
+ /BitsPerComponent 1
+ /Interpolate true
+ /Decode [1 0]
+ /DataSource im_stream
+ >> image
+ im_stream status { im_stream flushfile } if
+}
+exec
+rVPltoDejk!"Ju/3$7VQ!.UpIV-SSehuE`Xq.Ka.3#d/d!%<?t[o6KR-ia5Ps82is0EM0'!$=0#
+mf(r0"98E4gZ/>7!!%KK!"=AXeciN^#QOiDmG7gC:]MI8!"NB:J-Xp1#Qb#+^OO$!TE#<!!$6Xj
+!!3,oF?fR#pY'!TJ,fWN!"T&0J-#QIr'15Kh>cC5^]4?7!"PYE!!)c.r;XM.Iqrj&iW&rY!'Wgo
+!!)LAs8N&Uli6Yua8c2?!'Cem!!)+JqtpEnqYg:O5QCcq!'HKr!!2!Yo7(u]s(cQKj8]/[!.>"N
+!!C(<p\4^frVsQ5Du]k<!-ebL!!D-ZoDe9mJ%#+CfDkmO!-eME!!@`Qmsk?ZT'pUd^]4?7!Vh6H
+!!5CfbQ%JVp\k'g0E;(Q"8"!l!$;1Cs8W!<s5!^!L]@DT"8Muu^`9!LL]-F$fD!nsn,NFg#OnAd
+PWaO-^]3dfrr6:'qu?]s5PPQcTfiAtIGaZYJ%b`[?2ss*+8MQ0J3!]1n,K'Ls50Z]ec5[M+8dMe
+TGU3!pYX?rBD_`/rr<$!5Pu&ma;P*Zn,MADrr)f1DL_]e5Pkul!!EQ,h>cF4GB[9BpOE5DJ+uP7
+TF;qBJ,a$YhVHntrh'5q5N#'4JI"L/qu6bFp](9NBA`b#LVO[UL]fs:s8ITLDu$C*]!q_l5Qh&e
+TI><gs8N?'qsXPls3(R#6sp#qjBqqjs83&hgKh8TYM'N2&-)_2!'gKJs1JsAH2%>_qS+\nzW5&<j
+s83(N_8!1S^?bf"5QCcaJcGXt^\eW8r;H?gl[Ss2&-)\1OT56&s7c]pr*R3DXjt2MzT`=r)s5aH7
+=*s?(i,eqk+92BA!!i!Xs6p9Fn%JDH!*B3rJ,fQL!!i#.s3(TEot.DH!-/&2z!!D^Ts1ehgB>)'a
+!+Fd[!!",I!!2Z*s82lSrSQ2a!+`k+z!!D.$m%sdWC#Ao_!*0'[!!!#W!!U6#_%?Zro\I"G!,o(:
+!!!(^!!hFXLJe*knc->M!.)ENJ,fcR!"\(EJ._i(FB@Xu!3bkd!!$l/!"[$R(^L*O^ja&V!W'S-
+!!#1_!"ZjI$4m1Jn6bn!X"<`9!!N'^!.Vcc+ohTRn/pti>5U&C!!(B=!<:#'+92BN^b,TcY#m(5
+!!0lcJ:GL&!!!!(E$'O9e_DhR!!.U8`kT:i5QCcn^`3%DJ+t\h!!*'"PR#!SJ,fQNi#hFb<R;9Q
+!!!A!\YnNj(]XOHGRseVs)9XiJ,gSiM?gpAKE(u_TF\g7TC>)=J,hP/L9J^T!!!!'n-/](q-\.>
+8,tP5iP32SKE(uVYRgWgs.KDkfEaS>iSWjg+92BHm^rJoBu#5uiZJ>rs8UZ75QCch]l!E?rrN0"
+s*t)7s8U2i'EA+<p6,J@CBNJohuEbMs8W)tTE"rsJ"%QFrW[lP^]4??s8W&t"onW6m.Kj2AIJP<
+J,fQLs8W,s:]LJ#qs4/Ceq3)b!!!!Qs8W,s!WW32s&O@`r@d@6!!!!)hp;?$5X5;Senb$kqHmn8
+!!!!)S,`Nd,ldoMs8Gh*hu!HR!!!!1LHkh<"98E4s5*M]hfo,#!!!!Y,ldoB+92BPrNg_Z^$l"$
+!!!!IVZ6\o#ljr9n+UQ%rkJ%(!!!!Y%0-A&!!!!0rP$>XiJ6>5+92C\PQ1[X&-)\@s8E-'ecWuh
+!!!"D\,ZL+!<<*As8IQOmNJ5FO8o:U0E;(I+92BPs87NPli:E(J,fRos8W,o!!!!0s6p*kh1,J1
+a8c4uhuE`G6i[2ts2"a:^&S-8huE`oYQ+Xl!!!!@rV?QqRt(JDkl:]C?iU0$+92B`OF+hES=fi^
+quQln^]4?'!!!!?9HW?r(''^%qV<n$^]4?'!!!!`5Yq:X2@Y0;r+FUUs8W,o#QOjR!"\Q!0u&ME
+qd86js8W,g!!!"E!!i@N"$`FYs8W,gs8W,g!!!"HJ-GEB#_)gSs8W,os8W,_5QCfR!!)Kg$2so)
+s8W,/s8W,g!!!#m+?4HC!'S[/s8W,os8W,o!!!#iU^n%;!-S>Bs8W,gs8W,g!!!#k!!e&TE:#mj
+s8W,Os8W,g!!!#g&-LPb!rAPis8Vuks8W,WJ,fSb8LOQ=LA1`Ls8W,gs8W,W!!!,;U:?:L,(KXn
+s8V!Gs8W,g!!!,Z!^[5(e,TIKs8W(ks8W,W!!!,ZBG(:UTE#N's8W,7s8W,g!!!8D!CWR_<'UEa
+s8VgYs8W,G!!!,<WB`uSTE"rls8REGs8W,W!!!8"+rUF^ec5[Ms8W*!s8W,7!!"+/78Nsb6i[2e
+s8VHds8W,W!!!P['FBj%U&Y/ns8W&us8W,W!!"[NMM(s0g40/'s8V]ks8W,G!!"*=W1]d`.KBGK
+s8B\4s8W,7!!#6Z6NKFPomd#Bs8W!&s8W+\!!#76'P[UJ=o\O&s8Qm@s8W,;!!#5[#%@jgon3;G
+s81RWs8W,7!!#g_d>YjAC*EZZs8TSgs8W+L!!",%#S@[Loh6M0s8V_)s8W+l!!%M\l;gH5>-Iu=
+s8U_2s8W+L!!%Mj,dkEZH:<>bs8R=gs8T8f!!!Q(ql1MXVjJTjs8VA/s8W+L!!%N;Y$[;[AO%@=
+s8W#ls8S^a!!#7ZpXD_HC:8s(s8V]cs8W*!!!#7\rRHdZg=-B1s8UgJs8QGW!!&)VQ_r[ZV'XN!
+s8W,os8W*a!!0k-`S4RmRZIM:s8Vq?s8W*!!!FDDH_mGAjXOgHs8V!Os8W+,!!",@ZeK:TWi6U=
+s8W,os8W*!!'l&69r-3(j][=)s8W,os8W&u!!$C+[d0>'r1fnes8VE[s8W'`!!#7`gN<'XRqO(.
+s8W,os8W*!!!'e6mFBA!p"9lYs8W,os8W+L!!%NK[Wm3>X"&jVs8W,os8W'`!!#7`hY+$>G.+%O
+s8W,os8W'$!!#7`f54QTg6"]<s8W,os8W&u!!#7`H?t#ElQcUcs8W,os8W!^!!*'!hS#CkGa;e@
+s8W,os8W'`!!*'![=;5Kerg"LrVuoms8W$?!!*'!mV]LHh+4ILs8W,o^]49u!!*'!n,$-eWegj+
+s8W,oJ`$5&!!*'!r-lA`ok7/ls8W,oM5U-%!!*'!q<h0^Xq?CAs8W,o!+#@2!!3-"s)kKJo;[l_
+s8W,o!&jTP!!3-"rI2I>qj84]s8W,o!/pZG!!3-"rn15Rs._h$s8W,o!#P2+!!E9$s*gtTs6("Y
+s8W,o!!2kf!!E9$rEE:"rmo0*s8W,o!!D`k!!E9$s85cus4&lNs8W,o!!;:*!!E9$s'M=(s7h+o
+VuQel!!Von!!E9$s*H(os6>L@&-)\)!!2m\!!E9$s5'6Ks,o,8_#OH0!!E$^!"],0s.ADfs6;!2
+!3cFt!"\c?!"],0s8Tf_s8%fU!)7t<!$D,h!$D7@s$'ljs8B_-!!.TE!"](i!$D7@s6oses8Rc/
+!!",9z!$D7@s8W-!s8RUt!!!,rz!'gM`s8W-!s8RU5!!!#oz!&jlWs8W-!s8S;[!!!/sz!!$C+
+s8W-!s8V]hJ,fhaz!!!!`s8W-!s8W,u:]L[Oz!!!!0s8W-!s8W,rs.BJhz!!!!#s8W-!s8W-!
+s8W,oTE"rlz5QCc`s8W-!h>Vm8huE`Wz!WW3"s8W,ts7^m@huE`Wz!<<)^s8W-!s8Vcm^]4?7
+z!<<*!s8K`^s8U";ci=%Gz!<<&us8A#YDsd<"J,fQLz!.k1Ls2YHFkPt#OJ,fQLz!!*%'^\@p2
+cb7*oJ,fQLz!!#6rs3LlJci6fA~>
+end
+grestore
+showpage
+%%Trailer
+%%Pages: 1
+%%EOF
diff --git a/test/rewrite_tag.c b/test/rewrite_tag.c
index 2a366f78..1708b024 100644
--- a/test/rewrite_tag.c
+++ b/test/rewrite_tag.c
@@ -30,6 +30,7 @@
#include "tif_config.h"
#include <stdio.h>
+#include <stdlib.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
@@ -38,7 +39,6 @@
#include "tiffio.h"
#include "tiffiop.h"
-const uint32 width = 10;
const uint32 length = 40;
const uint32 rows_per_strip = 1;
@@ -49,6 +49,7 @@ int test_packbits()
int i;
unsigned char buf[10] = {0,0,0,0,0,0,0,0,0,0};
+ uint32 width = 10;
int length = 20;
const char *filename = "test_packbits.tif";
@@ -136,17 +137,20 @@ int test_packbits()
/************************************************************************/
/* rewrite_test() */
/************************************************************************/
-int rewrite_test( const char *filename, int length, int bigtiff,
+int rewrite_test( const char *filename, uint32 width, int length, int bigtiff,
uint64 base_value )
{
TIFF *tif;
int i;
- unsigned char buf[10] = {5,6,7,8,9,10,11,12,13,14};
+ unsigned char *buf;
uint64 *rowoffset, *rowbytes;
uint64 *upd_rowoffset;
uint64 *upd_bytecount;
+ buf = calloc(1, width);
+ assert(buf);
+
/* Test whether we can write tags. */
if( bigtiff )
tif = TIFFOpen(filename, "w8");
@@ -155,6 +159,7 @@ int rewrite_test( const char *filename, int length, int bigtiff,
if (!tif) {
fprintf (stderr, "Can't create test TIFF file %s.\n", filename);
+ free(buf);
return 1;
}
@@ -202,6 +207,7 @@ int rewrite_test( const char *filename, int length, int bigtiff,
tif = TIFFOpen(filename, "r+");
if (!tif) {
fprintf (stderr, "Can't open test TIFF file %s.\n", filename);
+ free(buf);
return 1;
}
@@ -219,7 +225,7 @@ int rewrite_test( const char *filename, int length, int bigtiff,
upd_rowoffset = (uint64 *) _TIFFmalloc(sizeof(uint64) * length);
for( i = 0; i < length; i++ )
- upd_rowoffset[i] = base_value + i*10;
+ upd_rowoffset[i] = base_value + i*width;
if( !_TIFFRewriteField( tif, TIFFTAG_STRIPOFFSETS, TIFF_LONG8,
length, upd_rowoffset ) )
@@ -232,7 +238,7 @@ int rewrite_test( const char *filename, int length, int bigtiff,
upd_bytecount = (uint64 *) _TIFFmalloc(sizeof(uint64) * length);
for( i = 0; i < length; i++ )
- upd_bytecount[i] = 100 + i*10;
+ upd_bytecount[i] = 100 + i*width;
if( !_TIFFRewriteField( tif, TIFFTAG_STRIPBYTECOUNTS, TIFF_LONG8,
length, upd_bytecount ) )
@@ -250,6 +256,7 @@ int rewrite_test( const char *filename, int length, int bigtiff,
tif = TIFFOpen(filename, "r");
if (!tif) {
fprintf (stderr, "Can't open test TIFF file %s.\n", filename);
+ free(buf);
return 1;
}
@@ -261,7 +268,7 @@ int rewrite_test( const char *filename, int length, int bigtiff,
for( i = 0; i < length; i++ )
{
- uint64 expect = base_value + i*10;
+ uint64 expect = base_value + i*width;
if( rowoffset[i] != expect )
{
@@ -284,7 +291,7 @@ int rewrite_test( const char *filename, int length, int bigtiff,
for( i = 0; i < length; i++ )
{
- uint64 expect = 100 + i*10;
+ uint64 expect = 100 + i*width;
if( rowbytes[i] != expect )
{
@@ -300,6 +307,7 @@ int rewrite_test( const char *filename, int length, int bigtiff,
}
TIFFClose( tif );
+ free(buf);
/* All tests passed; delete file and exit with success status. */
unlink(filename);
@@ -308,6 +316,7 @@ int rewrite_test( const char *filename, int length, int bigtiff,
failure:
/* Something goes wrong; close file and return unsuccessful status. */
TIFFClose(tif);
+ free(buf);
/* unlink(filename); */
return 1;
@@ -325,16 +334,20 @@ main(void)
failure |= test_packbits();
/* test fairly normal use */
- failure |= rewrite_test( "rewrite1.tif", 10, 0, 100 );
- failure |= rewrite_test( "rewrite2.tif", 10, 1, 100 );
+ failure |= rewrite_test( "rewrite1.tif", 10, 10, 0, 100 );
+ failure |= rewrite_test( "rewrite2.tif", 10, 10, 1, 100 );
/* test case of fitting all in directory entry */
- failure |= rewrite_test( "rewrite3.tif", 1, 0, 100 );
- failure |= rewrite_test( "rewrite4.tif", 1, 1, 100 );
+ failure |= rewrite_test( "rewrite3.tif", 10, 1, 0, 100 );
+ failure |= rewrite_test( "rewrite4.tif", 10, 1, 1, 100 );
/* test with very large values that don't fit in 4bytes (bigtiff only) */
- failure |= rewrite_test( "rewrite5.tif", 1000, 1, 0x6000000000ULL );
- failure |= rewrite_test( "rewrite6.tif", 1, 1, 0x6000000000ULL );
+ failure |= rewrite_test( "rewrite5.tif", 10, 1000, 1, 0x6000000000ULL );
+ failure |= rewrite_test( "rewrite6.tif", 10, 1, 1, 0x6000000000ULL );
+
+ /* StripByteCounts on LONG */
+ failure |= rewrite_test( "rewrite7.tif", 65536, 1, 0, 100 );
+ failure |= rewrite_test( "rewrite8.tif", 65536, 2, 0, 100 );
return failure;
}
diff --git a/test/testtypes.c b/test/testtypes.c
new file mode 100644
index 00000000..a36d21e5
--- /dev/null
+++ b/test/testtypes.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2019, Thomas Bernard <miniupnp@free.fr>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library
+ *
+ * Module to test ASCII tags read/write functions.
+ */
+
+#include "tif_config.h"
+
+#include <stdio.h>
+
+#include "tiffio.h"
+
+#define CHECK_TYPE(t, s) \
+ if (sizeof(t) != s) { \
+ fprintf(stderr, "sizeof(" # t ")=%d, it should be %d\n", (int)sizeof(t), (int)s); \
+ return 1; \
+ }
+
+int
+main()
+{
+ CHECK_TYPE(TIFF_INT8_T, 1)
+ CHECK_TYPE(TIFF_INT16_T, 2)
+ CHECK_TYPE(TIFF_INT32_T, 4)
+ CHECK_TYPE(TIFF_INT64_T, 8)
+ CHECK_TYPE(TIFF_UINT8_T, 1)
+ CHECK_TYPE(TIFF_UINT16_T, 2)
+ CHECK_TYPE(TIFF_UINT32_T, 4)
+ CHECK_TYPE(TIFF_UINT64_T, 8)
+ CHECK_TYPE(TIFF_SIZE_T, sizeof(size_t))
+ CHECK_TYPE(TIFF_SSIZE_T, sizeof(size_t))
+ return 0;
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
diff --git a/test/tiff2bw-logluv-3c-16b.sh b/test/tiff2bw-logluv-3c-16b.sh
new file mode 100755
index 00000000..9a64a1af
--- /dev/null
+++ b/test/tiff2bw-logluv-3c-16b.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/logluv-3c-16b.tiff"
+outfile="o-tiff2bw-logluv-3c-16b.tiff"
+f_test_convert "$TIFF2BW" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiff2bw-lzw-single-strip.sh b/test/tiff2bw-lzw-single-strip.sh
new file mode 100755
index 00000000..def92097
--- /dev/null
+++ b/test/tiff2bw-lzw-single-strip.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/lzw-single-strip.tiff"
+outfile="o-tiff2bw-lzw-single-strip.tiff"
+f_test_convert "$TIFF2BW" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiff2bw-minisblack-1c-16b.sh b/test/tiff2bw-minisblack-1c-16b.sh
new file mode 100755
index 00000000..d0dee2c8
--- /dev/null
+++ b/test/tiff2bw-minisblack-1c-16b.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/minisblack-1c-16b.tiff"
+outfile="o-tiff2bw-minisblack-1c-16b.tiff"
+f_test_convert "$TIFF2BW" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiff2bw-minisblack-1c-8b.sh b/test/tiff2bw-minisblack-1c-8b.sh
new file mode 100755
index 00000000..c3437b95
--- /dev/null
+++ b/test/tiff2bw-minisblack-1c-8b.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/minisblack-1c-8b.tiff"
+outfile="o-tiff2bw-minisblack-1c-8b.tiff"
+f_test_convert "$TIFF2BW" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiff2bw-minisblack-2c-8b-alpha.sh b/test/tiff2bw-minisblack-2c-8b-alpha.sh
new file mode 100755
index 00000000..81f7b6d6
--- /dev/null
+++ b/test/tiff2bw-minisblack-2c-8b-alpha.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/minisblack-2c-8b-alpha.tiff"
+outfile="o-tiff2bw-minisblack-2c-8b-alpha.tiff"
+f_test_convert "$TIFF2BW" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiff2bw-miniswhite-1c-1b.sh b/test/tiff2bw-miniswhite-1c-1b.sh
new file mode 100755
index 00000000..e3043c1f
--- /dev/null
+++ b/test/tiff2bw-miniswhite-1c-1b.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/miniswhite-1c-1b.tiff"
+outfile="o-tiff2bw-miniswhite-1c-1b.tiff"
+f_test_convert "$TIFF2BW" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiff2bw-ojpeg_chewey_subsamp21_multi_strip.sh b/test/tiff2bw-ojpeg_chewey_subsamp21_multi_strip.sh
new file mode 100755
index 00000000..61a2ccf5
--- /dev/null
+++ b/test/tiff2bw-ojpeg_chewey_subsamp21_multi_strip.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/ojpeg_chewey_subsamp21_multi_strip.tiff"
+outfile="o-tiff2bw-ojpeg_chewey_subsamp21_multi_strip.tiff"
+f_test_convert "$TIFF2BW" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiff2bw-ojpeg_zackthecat_subsamp22_single_strip.sh b/test/tiff2bw-ojpeg_zackthecat_subsamp22_single_strip.sh
new file mode 100755
index 00000000..7b09ded9
--- /dev/null
+++ b/test/tiff2bw-ojpeg_zackthecat_subsamp22_single_strip.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/ojpeg_zackthecat_subsamp22_single_strip.tiff"
+outfile="o-tiff2bw-ojpeg_zackthecat_subsamp22_single_strip.tiff"
+f_test_convert "$TIFF2BW" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiff2bw-palette-1c-1b.sh b/test/tiff2bw-palette-1c-1b.sh
new file mode 100755
index 00000000..3862614e
--- /dev/null
+++ b/test/tiff2bw-palette-1c-1b.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/palette-1c-1b.tiff"
+outfile="o-tiff2bw-palette-1c-1b.tiff"
+f_test_convert "$TIFF2BW" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiff2bw-palette-1c-4b.sh b/test/tiff2bw-palette-1c-4b.sh
new file mode 100755
index 00000000..21d8e90d
--- /dev/null
+++ b/test/tiff2bw-palette-1c-4b.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/palette-1c-4b.tiff"
+outfile="o-tiff2bw-palette-1c-4b.tiff"
+f_test_convert "$TIFF2BW" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiff2bw-quad-tile.jpg.sh b/test/tiff2bw-quad-tile.jpg.sh
new file mode 100755
index 00000000..29c2f40a
--- /dev/null
+++ b/test/tiff2bw-quad-tile.jpg.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/quad-tile.jpg.tiff"
+outfile="o-tiff2bw-quad-tile.jpg.tiff"
+f_test_convert "$TIFF2BW" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiff2bw-quad-tile.jpg.t1iff.sh b/test/tiff2bw-quad-tile.jpg.t1iff.sh
new file mode 100755
index 00000000..1c507b37
--- /dev/null
+++ b/test/tiff2bw-quad-tile.jpg.t1iff.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/quad-tile.jpg.t1iff"
+outfile="o-tiff2bw-quad-tile.jpg.t1iff.tiff"
+f_test_convert "$TIFF2BW" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiff2bw-rgb-3c-16b.sh b/test/tiff2bw-rgb-3c-16b.sh
new file mode 100755
index 00000000..0ba9efb1
--- /dev/null
+++ b/test/tiff2bw-rgb-3c-16b.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/rgb-3c-16b.tiff"
+outfile="o-tiff2bw-rgb-3c-16b.tiff"
+f_test_convert "$TIFF2BW" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiff2ps-EPS1.sh b/test/tiff2ps-EPS1.sh
index ebe6f04b..b1dc82e7 100755
--- a/test/tiff2ps-EPS1.sh
+++ b/test/tiff2ps-EPS1.sh
@@ -2,5 +2,7 @@
#
# Basic sanity check for tiffps with PostScript Level 1 encapsulated output
#
+PSFILE=o-tiff2ps-EPS1.ps
. ${srcdir:-.}/common.sh
-f_test_stdout "${TIFF2PS} -e -1" "${IMG_MINISWHITE_1C_1B}" "o-tiff2ps-EPS1.ps" \ No newline at end of file
+f_test_stdout "${TIFF2PS} -e -1" "${IMG_MINISWHITE_1C_1B}" "${PSFILE}"
+diff -I '%%\(CreationDate\|Title\):*' -u "${REFS}/${PSFILE}" "${PSFILE}" || exit 1
diff --git a/test/tiff2ps-PS1.sh b/test/tiff2ps-PS1.sh
index 65921597..73171b98 100755
--- a/test/tiff2ps-PS1.sh
+++ b/test/tiff2ps-PS1.sh
@@ -2,5 +2,7 @@
#
# Basic sanity check for tiffps with PostScript Level 1 output
#
+PSFILE="o-tiff2ps-PS1.ps"
. ${srcdir:-.}/common.sh
-f_test_stdout "${TIFF2PS} -a -p -1" "${IMG_MINISWHITE_1C_1B}" "o-tiff2ps-PS1.ps" \ No newline at end of file
+f_test_stdout "${TIFF2PS} -a -p -1" "${IMG_MINISWHITE_1C_1B}" "${PSFILE}"
+diff -I '%%\(CreationDate\|Title\):*' -u "${REFS}/${PSFILE}" "${PSFILE}" || exit 1
diff --git a/test/tiff2ps-PS2.sh b/test/tiff2ps-PS2.sh
index 2a216069..9d3a521d 100755
--- a/test/tiff2ps-PS2.sh
+++ b/test/tiff2ps-PS2.sh
@@ -2,5 +2,7 @@
#
# Basic sanity check for tiffps with PostScript Level 2 output
#
+PSFILE=o-tiff2ps-PS2.ps
. ${srcdir:-.}/common.sh
-f_test_stdout "${TIFF2PS} -a -p -2" "${IMG_MINISWHITE_1C_1B}" "o-tiff2ps-PS2.ps" \ No newline at end of file
+f_test_stdout "${TIFF2PS} -a -p -2" "${IMG_MINISWHITE_1C_1B}" "${PSFILE}"
+diff -I '%%\(CreationDate\|Title\):*' -u "${REFS}/${PSFILE}" "${PSFILE}" || exit 1
diff --git a/test/tiff2ps-PS3.sh b/test/tiff2ps-PS3.sh
index f9f34b66..eb55b9a0 100755
--- a/test/tiff2ps-PS3.sh
+++ b/test/tiff2ps-PS3.sh
@@ -2,5 +2,7 @@
#
# Basic sanity check for tiffps with PostScript Level 3 output
#
+PSFILE=o-tiff2ps-PS3.ps
. ${srcdir:-.}/common.sh
-f_test_stdout "${TIFF2PS} -a -p -3" "${IMG_MINISWHITE_1C_1B}" "o-tiff2ps-PS3.ps" \ No newline at end of file
+f_test_stdout "${TIFF2PS} -a -p -3" "${IMG_MINISWHITE_1C_1B}" "${PSFILE}"
+diff -I '%%\(CreationDate\|Title\):*' -u "${REFS}/${PSFILE}" "${PSFILE}" || exit 1
diff --git a/test/tiff2rgba-lzw-single-strip.sh b/test/tiff2rgba-lzw-single-strip.sh
new file mode 100755
index 00000000..184a28d5
--- /dev/null
+++ b/test/tiff2rgba-lzw-single-strip.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/lzw-single-strip.tiff"
+outfile="o-tiff2rgba-lzw-single-strip.tiff"
+f_test_convert "$TIFF2RGBA" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiff2rgba-ojpeg_chewey_subsamp21_multi_strip.sh b/test/tiff2rgba-ojpeg_chewey_subsamp21_multi_strip.sh
new file mode 100755
index 00000000..d1225c94
--- /dev/null
+++ b/test/tiff2rgba-ojpeg_chewey_subsamp21_multi_strip.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/ojpeg_chewey_subsamp21_multi_strip.tiff"
+outfile="o-tiff2rgba-ojpeg_chewey_subsamp21_multi_strip.tiff"
+f_test_convert "$TIFF2RGBA" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiff2rgba-ojpeg_single_strip_no_rowsperstrip.sh b/test/tiff2rgba-ojpeg_single_strip_no_rowsperstrip.sh
new file mode 100755
index 00000000..d69c99dc
--- /dev/null
+++ b/test/tiff2rgba-ojpeg_single_strip_no_rowsperstrip.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/ojpeg_single_strip_no_rowsperstrip.tiff"
+outfile="o-tiff2rgba-ojpeg_single_strip_no_rowsperstrip.tiff"
+f_test_convert "$TIFF2RGBA" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiff2rgba-ojpeg_zackthecat_subsamp22_single_strip.sh b/test/tiff2rgba-ojpeg_zackthecat_subsamp22_single_strip.sh
new file mode 100755
index 00000000..ca23a12d
--- /dev/null
+++ b/test/tiff2rgba-ojpeg_zackthecat_subsamp22_single_strip.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/ojpeg_zackthecat_subsamp22_single_strip.tiff"
+outfile="o-tiff2rgba-ojpeg_zackthecat_subsamp22_single_strip.tiff"
+f_test_convert "$TIFF2RGBA" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiff2rgba-quad-lzw-compat.sh b/test/tiff2rgba-quad-lzw-compat.sh
new file mode 100755
index 00000000..5ad808a5
--- /dev/null
+++ b/test/tiff2rgba-quad-lzw-compat.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/quad-lzw-compat.tiff"
+outfile="o-tiff2rgba-quad-lzw-compat.tiff"
+f_test_convert "$TIFF2RGBA" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiff2rgba-quad-tile.jpg.t1iff.sh b/test/tiff2rgba-quad-tile.jpg.t1iff.sh
new file mode 100755
index 00000000..9d553df6
--- /dev/null
+++ b/test/tiff2rgba-quad-tile.jpg.t1iff.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/quad-tile.jpg.t1iff"
+outfile="o-tiff2rgba-quad-tile.jpg.t1iff.tiff"
+f_test_convert "$TIFF2RGBA" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiffcrop-R90-lzw-single-strip.sh b/test/tiffcrop-R90-lzw-single-strip.sh
new file mode 100755
index 00000000..7b4fdbf9
--- /dev/null
+++ b/test/tiffcrop-R90-lzw-single-strip.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/lzw-single-strip.tiff"
+outfile="o-tiffcrop-R90-lzw-single-strip.tiff"
+f_test_convert "$TIFFCROP -R90" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiffcrop-R90-ojpeg_chewey_subsamp21_multi_strip.sh b/test/tiffcrop-R90-ojpeg_chewey_subsamp21_multi_strip.sh
new file mode 100755
index 00000000..41df587d
--- /dev/null
+++ b/test/tiffcrop-R90-ojpeg_chewey_subsamp21_multi_strip.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/ojpeg_chewey_subsamp21_multi_strip.tiff"
+outfile="o-tiffcrop-R90-ojpeg_chewey_subsamp21_multi_strip.tiff"
+f_test_convert "$TIFFCROP -R90" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiffcrop-R90-ojpeg_zackthecat_subsamp22_single_strip.sh b/test/tiffcrop-R90-ojpeg_zackthecat_subsamp22_single_strip.sh
new file mode 100755
index 00000000..61f8fc41
--- /dev/null
+++ b/test/tiffcrop-R90-ojpeg_zackthecat_subsamp22_single_strip.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/ojpeg_zackthecat_subsamp22_single_strip.tiff"
+outfile="o-tiffcrop-R90-ojpeg_zackthecat_subsamp22_single_strip.tiff"
+f_test_convert "$TIFFCROP -R90" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiffcrop-R90-quad-lzw-compat.sh b/test/tiffcrop-R90-quad-lzw-compat.sh
new file mode 100755
index 00000000..1a40412e
--- /dev/null
+++ b/test/tiffcrop-R90-quad-lzw-compat.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/quad-lzw-compat.tiff"
+outfile="o-tiffcrop-R90-quad-lzw-compat.tiff"
+f_test_convert "$TIFFCROP -R90" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiffcrop-R90-quad-tile.jpg.t1iff.sh b/test/tiffcrop-R90-quad-tile.jpg.t1iff.sh
new file mode 100755
index 00000000..0d2bf973
--- /dev/null
+++ b/test/tiffcrop-R90-quad-tile.jpg.t1iff.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/quad-tile.jpg.t1iff"
+outfile="o-tiffcrop-R90-quad-tile.jpg.t1iff.tiff"
+f_test_convert "$TIFFCROP -R90" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiffcrop-doubleflip-lzw-single-strip.sh b/test/tiffcrop-doubleflip-lzw-single-strip.sh
new file mode 100755
index 00000000..15351247
--- /dev/null
+++ b/test/tiffcrop-doubleflip-lzw-single-strip.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/lzw-single-strip.tiff"
+outfile="o-tiffcrop-doubleflip-lzw-single-strip.tiff"
+f_test_convert "$TIFFCROP -F both" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiffcrop-doubleflip-ojpeg_chewey_subsamp21_multi_strip.sh b/test/tiffcrop-doubleflip-ojpeg_chewey_subsamp21_multi_strip.sh
new file mode 100755
index 00000000..3196ae1d
--- /dev/null
+++ b/test/tiffcrop-doubleflip-ojpeg_chewey_subsamp21_multi_strip.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/ojpeg_chewey_subsamp21_multi_strip.tiff"
+outfile="o-tiffcrop-doubleflip-ojpeg_chewey_subsamp21_multi_strip.tiff"
+f_test_convert "$TIFFCROP -F both" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiffcrop-doubleflip-ojpeg_zackthecat_subsamp22_single_strip.sh b/test/tiffcrop-doubleflip-ojpeg_zackthecat_subsamp22_single_strip.sh
new file mode 100755
index 00000000..6ce71d4f
--- /dev/null
+++ b/test/tiffcrop-doubleflip-ojpeg_zackthecat_subsamp22_single_strip.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/ojpeg_zackthecat_subsamp22_single_strip.tiff"
+outfile="o-tiffcrop-doubleflip-ojpeg_zackthecat_subsamp22_single_strip.tiff"
+f_test_convert "$TIFFCROP -F both" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiffcrop-doubleflip-quad-lzw-compat.sh b/test/tiffcrop-doubleflip-quad-lzw-compat.sh
new file mode 100755
index 00000000..5c482a5d
--- /dev/null
+++ b/test/tiffcrop-doubleflip-quad-lzw-compat.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/quad-lzw-compat.tiff"
+outfile="o-tiffcrop-doubleflip-quad-lzw-compat.tiff"
+f_test_convert "$TIFFCROP -F both" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiffcrop-doubleflip-quad-tile.jpg.t1iff.sh b/test/tiffcrop-doubleflip-quad-tile.jpg.t1iff.sh
new file mode 100755
index 00000000..2e097126
--- /dev/null
+++ b/test/tiffcrop-doubleflip-quad-tile.jpg.t1iff.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/quad-tile.jpg.t1iff"
+outfile="o-tiffcrop-doubleflip-quad-tile.jpg.t1iff.tiff"
+f_test_convert "$TIFFCROP -F both" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiffcrop-extract-lzw-single-strip.sh b/test/tiffcrop-extract-lzw-single-strip.sh
new file mode 100755
index 00000000..58041a23
--- /dev/null
+++ b/test/tiffcrop-extract-lzw-single-strip.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/lzw-single-strip.tiff"
+outfile="o-tiffcrop-extract-lzw-single-strip.tiff"
+f_test_convert "$TIFFCROP -U px -E top -X 60 -Y 60" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiffcrop-extract-ojpeg_chewey_subsamp21_multi_strip.sh b/test/tiffcrop-extract-ojpeg_chewey_subsamp21_multi_strip.sh
new file mode 100755
index 00000000..bb30f9bd
--- /dev/null
+++ b/test/tiffcrop-extract-ojpeg_chewey_subsamp21_multi_strip.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/ojpeg_chewey_subsamp21_multi_strip.tiff"
+outfile="o-tiffcrop-extract-ojpeg_chewey_subsamp21_multi_strip.tiff"
+f_test_convert "$TIFFCROP -U px -E top -X 60 -Y 60" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiffcrop-extract-ojpeg_zackthecat_subsamp22_single_strip.sh b/test/tiffcrop-extract-ojpeg_zackthecat_subsamp22_single_strip.sh
new file mode 100755
index 00000000..ce06a261
--- /dev/null
+++ b/test/tiffcrop-extract-ojpeg_zackthecat_subsamp22_single_strip.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/ojpeg_zackthecat_subsamp22_single_strip.tiff"
+outfile="o-tiffcrop-extract-ojpeg_zackthecat_subsamp22_single_strip.tiff"
+f_test_convert "$TIFFCROP -U px -E top -X 60 -Y 60" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiffcrop-extract-quad-lzw-compat.sh b/test/tiffcrop-extract-quad-lzw-compat.sh
new file mode 100755
index 00000000..bade2456
--- /dev/null
+++ b/test/tiffcrop-extract-quad-lzw-compat.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/quad-lzw-compat.tiff"
+outfile="o-tiffcrop-extract-quad-lzw-compat.tiff"
+f_test_convert "$TIFFCROP -U px -E top -X 60 -Y 60" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiffcrop-extract-quad-tile.jpg.t1iff.sh b/test/tiffcrop-extract-quad-tile.jpg.t1iff.sh
new file mode 100755
index 00000000..11834416
--- /dev/null
+++ b/test/tiffcrop-extract-quad-tile.jpg.t1iff.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/quad-tile.jpg.t1iff"
+outfile="o-tiffcrop-extract-quad-tile.jpg.t1iff.tiff"
+f_test_convert "$TIFFCROP -U px -E top -X 60 -Y 60" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiffcrop-extractz14-lzw-single-strip.sh b/test/tiffcrop-extractz14-lzw-single-strip.sh
new file mode 100755
index 00000000..022ab76f
--- /dev/null
+++ b/test/tiffcrop-extractz14-lzw-single-strip.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/lzw-single-strip.tiff"
+outfile="o-tiffcrop-extractz14-lzw-single-strip.tiff"
+f_test_convert "$TIFFCROP -E left -Z1:4,2:4" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiffcrop-extractz14-ojpeg_chewey_subsamp21_multi_strip.sh b/test/tiffcrop-extractz14-ojpeg_chewey_subsamp21_multi_strip.sh
new file mode 100755
index 00000000..81d66249
--- /dev/null
+++ b/test/tiffcrop-extractz14-ojpeg_chewey_subsamp21_multi_strip.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/ojpeg_chewey_subsamp21_multi_strip.tiff"
+outfile="o-tiffcrop-extractz14-ojpeg_chewey_subsamp21_multi_strip.tiff"
+f_test_convert "$TIFFCROP -E left -Z1:4,2:4" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiffcrop-extractz14-ojpeg_zackthecat_subsamp22_single_strip.sh b/test/tiffcrop-extractz14-ojpeg_zackthecat_subsamp22_single_strip.sh
new file mode 100755
index 00000000..e6c3c5f3
--- /dev/null
+++ b/test/tiffcrop-extractz14-ojpeg_zackthecat_subsamp22_single_strip.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/ojpeg_zackthecat_subsamp22_single_strip.tiff"
+outfile="o-tiffcrop-extractz14-ojpeg_zackthecat_subsamp22_single_strip.tiff"
+f_test_convert "$TIFFCROP -E left -Z1:4,2:4" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiffcrop-extractz14-quad-lzw-compat.sh b/test/tiffcrop-extractz14-quad-lzw-compat.sh
new file mode 100755
index 00000000..3fe169c3
--- /dev/null
+++ b/test/tiffcrop-extractz14-quad-lzw-compat.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/quad-lzw-compat.tiff"
+outfile="o-tiffcrop-extractz14-quad-lzw-compat.tiff"
+f_test_convert "$TIFFCROP -E left -Z1:4,2:4" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/test/tiffcrop-extractz14-quad-tile.jpg.t1iff.sh b/test/tiffcrop-extractz14-quad-tile.jpg.t1iff.sh
new file mode 100755
index 00000000..5d36e7da
--- /dev/null
+++ b/test/tiffcrop-extractz14-quad-tile.jpg.t1iff.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Generated file, master is Makefile.am
+. ${srcdir:-.}/common.sh
+infile="$srcdir/images/quad-tile.jpg.t1iff"
+outfile="o-tiffcrop-extractz14-quad-tile.jpg.t1iff.tiff"
+f_test_convert "$TIFFCROP -E left -Z1:4,2:4" $infile $outfile
+f_tiffinfo_validate $outfile
diff --git a/tools/fax2tiff.c b/tools/fax2tiff.c
index 2098b2ab..21223131 100644
--- a/tools/fax2tiff.c
+++ b/tools/fax2tiff.c
@@ -74,14 +74,10 @@ static void usage(void);
Struct to carry client data. Note that it does not appear that the client
data is actually used in this program.
*/
-typedef struct _FAX_Client_Data
+typedef union _FAX_Client_Data
{
-#if defined(_WIN32) && defined(USE_WIN32_FILEIO)
- intptr_t fh; /* Operating system file handle */
-#else
- int fd; /* Integer file descriptor */
-#endif
-
+ thandle_t fh; /* Operating system file handle */
+ int fd; /* Integer file descriptor */
} FAX_Client_Data;
int
@@ -89,7 +85,7 @@ main(int argc, char* argv[])
{
FILE *in;
TIFF *out = NULL;
- FAX_Client_Data client_data;
+ FAX_Client_Data client_data;
TIFFErrorHandler whandler = NULL;
int compression_in = COMPRESSION_CCITTFAX3;
int compression_out = COMPRESSION_CCITTFAX3;
@@ -280,11 +276,11 @@ main(int argc, char* argv[])
continue;
}
#if defined(_WIN32) && defined(USE_WIN32_FILEIO)
- client_data.fh = _get_osfhandle(fileno(in));
+ client_data.fh = (thandle_t)_get_osfhandle(fileno(in));
#else
- client_data.fd = fileno(in);
+ client_data.fd = fileno(in);
#endif
- TIFFSetClientdata(faxTIFF, (thandle_t) &client_data);
+ TIFFSetClientdata(faxTIFF, client_data.fh);
TIFFSetFileName(faxTIFF, (const char*)argv[optind]);
TIFFSetField(out, TIFFTAG_IMAGEWIDTH, xsize);
TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 1);
diff --git a/tools/pal2rgb.c b/tools/pal2rgb.c
index 01d8502e..9492f1cf 100644
--- a/tools/pal2rgb.c
+++ b/tools/pal2rgb.c
@@ -118,12 +118,14 @@ main(int argc, char* argv[])
shortv != PHOTOMETRIC_PALETTE) {
fprintf(stderr, "%s: Expecting a palette image.\n",
argv[optind]);
+ (void) TIFFClose(in);
return (-1);
}
if (!TIFFGetField(in, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) {
fprintf(stderr,
"%s: No colormap (not a valid palette image).\n",
argv[optind]);
+ (void) TIFFClose(in);
return (-1);
}
bitspersample = 0;
@@ -131,11 +133,14 @@ main(int argc, char* argv[])
if (bitspersample != 8) {
fprintf(stderr, "%s: Sorry, can only handle 8-bit images.\n",
argv[optind]);
+ (void) TIFFClose(in);
return (-1);
}
out = TIFFOpen(argv[optind+1], "w");
- if (out == NULL)
+ if (out == NULL) {
+ (void) TIFFClose(in);
return (-2);
+ }
cpTags(in, out);
TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &imagewidth);
TIFFGetField(in, TIFFTAG_IMAGELENGTH, &imagelength);
diff --git a/tools/ppm2tiff.c b/tools/ppm2tiff.c
index d3ea6493..2b275618 100644
--- a/tools/ppm2tiff.c
+++ b/tools/ppm2tiff.c
@@ -48,7 +48,7 @@
#include "tiffio.h"
#ifndef HAVE_GETOPT
-extern int getopt(int, char**, char*);
+extern int getopt(int argc, char * const argv[], const char *optstring);
#endif
#define streq(a,b) (strcmp(a,b) == 0)
diff --git a/tools/raw2tiff.c b/tools/raw2tiff.c
index f502408e..f00142cf 100644
--- a/tools/raw2tiff.c
+++ b/tools/raw2tiff.c
@@ -60,7 +60,7 @@
#include "tiffio.h"
#ifndef HAVE_GETOPT
-extern int getopt(int, char**, char*);
+extern int getopt(int argc, char * const argv[], const char *optstring);
#endif
#ifndef O_BINARY
@@ -372,7 +372,7 @@ guessSize(int fd, TIFFDataType dtype, _TIFF_off_t hdr_size, uint32 nbands,
_TIFF_stat_s filestat;
uint32 w, h, scanlinesize, imagesize;
uint32 depth = TIFFDataWidth(dtype);
- float cor_coef = 0, tmp;
+ double cor_coef = 0, tmp;
if (_TIFF_fstat_f(fd, &filestat) == -1) {
fprintf(stderr, "Failed to obtain file size.\n");
@@ -419,22 +419,28 @@ guessSize(int fd, TIFFDataType dtype, _TIFF_off_t hdr_size, uint32 nbands,
w++) {
if (imagesize % w == 0) {
scanlinesize = w * depth;
+ h = imagesize / w;
+ if (h < 2)
+ continue;
+ /* reads 2 lines at the middle of the image and calculate their correlation.
+ * it works for h >= 2. (in this case it will compare line 0 and line 1 */
buf1 = _TIFFmalloc(scanlinesize);
buf2 = _TIFFmalloc(scanlinesize);
- h = imagesize / w;
do {
- if (_TIFF_lseek_f(fd, hdr_size + (int)(h/2)*scanlinesize,
+ if (_TIFF_lseek_f(fd, hdr_size + (int)((h - 1)/2)*scanlinesize,
SEEK_SET) == (_TIFF_off_t)-1) {
fprintf(stderr, "seek error.\n");
fail=1;
break;
}
+ /* read line (h-1)/2 */
if (read(fd, buf1, scanlinesize) !=
(long) scanlinesize) {
fprintf(stderr, "read error.\n");
fail=1;
break;
}
+ /* read line ((h-1)/2)+1 */
if (read(fd, buf2, scanlinesize) !=
(long) scanlinesize) {
fprintf(stderr, "read error.\n");
@@ -445,11 +451,15 @@ guessSize(int fd, TIFFDataType dtype, _TIFF_off_t hdr_size, uint32 nbands,
swapBytesInScanline(buf1, w, dtype);
swapBytesInScanline(buf2, w, dtype);
}
- tmp = (float) fabs(correlation(buf1, buf2,
- w, dtype));
- if (tmp > cor_coef) {
- cor_coef = tmp;
+ if (0 == memcmp(buf1, buf2, scanlinesize)) {
*width = w, *length = h;
+ } else {
+ tmp = fabs(correlation(buf1, buf2,
+ w, dtype));
+ if (tmp > cor_coef) {
+ cor_coef = tmp;
+ *width = w, *length = h;
+ }
}
} while (0);
@@ -564,6 +574,7 @@ correlation(void *buf1, void *buf2, uint32 n_elem, TIFFDataType dtype)
M2 /= n_elem;
D1 -= M1 * M1 * n_elem;
D2 -= M2 * M2 * n_elem;
+ if (D1 * D2 == 0.0) return 0.0; /* avoid divide by zero */
K = (K - M1 * M2 * n_elem) / sqrt(D1 * D2);
return K;
diff --git a/tools/rgb2ycbcr.c b/tools/rgb2ycbcr.c
index cf5f956f..cb94d458 100644
--- a/tools/rgb2ycbcr.c
+++ b/tools/rgb2ycbcr.c
@@ -129,6 +129,7 @@ main(int argc, char* argv[])
if (!tiffcvt(in, out) ||
!TIFFWriteDirectory(out)) {
(void) TIFFClose(out);
+ (void) TIFFClose(in);
return (1);
}
} while (TIFFReadDirectory(in));
diff --git a/tools/thumbnail.c b/tools/thumbnail.c
index 3d1adc78..169a6369 100644
--- a/tools/thumbnail.c
+++ b/tools/thumbnail.c
@@ -40,7 +40,7 @@
#include "tiffio.h"
#ifndef HAVE_GETOPT
-extern int getopt(int, char**, char*);
+extern int getopt(int argc, char * const argv[], const char *optstring);
#endif
#define streq(a,b) (strcmp(a,b) == 0)
diff --git a/tools/tiff2pdf.c b/tools/tiff2pdf.c
index 857c60fd..bca54d53 100644
--- a/tools/tiff2pdf.c
+++ b/tools/tiff2pdf.c
@@ -54,7 +54,7 @@
#include "tiffio.h"
#ifndef HAVE_GETOPT
-extern int getopt(int, char**, char*);
+extern int getopt(int argc, char * const argv[], const char *optstring);
#endif
#ifndef EXIT_SUCCESS
@@ -1292,10 +1292,10 @@ int t2p_cmp_t2p_page(const void* e1, const void* e2){
void t2p_read_tiff_data(T2P* t2p, TIFF* input){
int i=0;
- uint16* r;
- uint16* g;
- uint16* b;
- uint16* a;
+ uint16* r = NULL;
+ uint16* g = NULL;
+ uint16* b = NULL;
+ uint16* a = NULL;
uint16 xuint16;
uint16* xuint16p;
float* xfloatp;
@@ -1522,12 +1522,19 @@ void t2p_read_tiff_data(T2P* t2p, TIFF* input){
t2p->pdf_palettesize=0x0001<<t2p->tiff_bitspersample;
if(!TIFFGetField(input, TIFFTAG_COLORMAP, &r, &g, &b)){
TIFFError(
- TIFF2PDF_MODULE,
- "Palettized image %s has no color map",
+ TIFF2PDF_MODULE,
+ "Palettized image %s has no color map",
TIFFFileName(input));
t2p->t2p_error = T2P_ERR_ERROR;
return;
- }
+ }
+ if(r == NULL || g == NULL || b == NULL){
+ TIFFError(
+ TIFF2PDF_MODULE,
+ "Error getting 3 components from color map");
+ t2p->t2p_error = T2P_ERR_ERROR;
+ return;
+ }
if(t2p->pdf_palette != NULL){
_TIFFfree(t2p->pdf_palette);
t2p->pdf_palette=NULL;
@@ -1591,12 +1598,19 @@ void t2p_read_tiff_data(T2P* t2p, TIFF* input){
t2p->pdf_palettesize=0x0001<<t2p->tiff_bitspersample;
if(!TIFFGetField(input, TIFFTAG_COLORMAP, &r, &g, &b, &a)){
TIFFError(
- TIFF2PDF_MODULE,
- "Palettized image %s has no color map",
+ TIFF2PDF_MODULE,
+ "Palettized image %s has no color map",
TIFFFileName(input));
t2p->t2p_error = T2P_ERR_ERROR;
return;
- }
+ }
+ if(r == NULL || g == NULL || b == NULL || a == NULL){
+ TIFFError(
+ TIFF2PDF_MODULE,
+ "Error getting 4 components from color map");
+ t2p->t2p_error = T2P_ERR_ERROR;
+ return;
+ }
if(t2p->pdf_palette != NULL){
_TIFFfree(t2p->pdf_palette);
t2p->pdf_palette=NULL;
@@ -3104,19 +3118,26 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_
if(t2p->pdf_sample & T2P_SAMPLE_LAB_SIGNED_TO_UNSIGNED){
t2p->tiff_datasize=t2p_sample_lab_signed_to_unsigned(
- (tdata_t)buffer,
+ (tdata_t)buffer,
t2p->tiff_tiles[t2p->pdf_page].tiles_tilewidth
*t2p->tiff_tiles[t2p->pdf_page].tiles_tilelength);
}
}
if(t2p_tile_is_right_edge(t2p->tiff_tiles[t2p->pdf_page], tile) != 0){
- t2p_tile_collapse_left(
- buffer,
- TIFFTileRowSize(input),
- t2p->tiff_tiles[t2p->pdf_page].tiles_tilewidth,
- t2p->tiff_tiles[t2p->pdf_page].tiles_edgetilewidth,
- t2p->tiff_tiles[t2p->pdf_page].tiles_tilelength);
+ if ((uint64)t2p->tiff_datasize < (uint64)TIFFTileRowSize(input) * (uint64)t2p->tiff_tiles[t2p->pdf_page].tiles_tilelength) {
+ /* we don't know how to handle PLANARCONFIG_CONTIG, PHOTOMETRIC_YCBCR with 3 samples per pixel */
+ TIFFWarning(
+ TIFF2PDF_MODULE,
+ "Don't know how to collapse tile to the left");
+ } else {
+ t2p_tile_collapse_left(
+ buffer,
+ TIFFTileRowSize(input),
+ t2p->tiff_tiles[t2p->pdf_page].tiles_tilewidth,
+ t2p->tiff_tiles[t2p->pdf_page].tiles_edgetilewidth,
+ t2p->tiff_tiles[t2p->pdf_page].tiles_tilelength);
+ }
}
@@ -3710,6 +3731,11 @@ tsize_t t2p_sample_realize_palette(T2P* t2p, unsigned char* buffer){
for(i=sample_count;i>0;i--){
palette_offset=buffer[i-1] * component_count;
sample_offset= (i-1) * component_count;
+ if(palette_offset + component_count > t2p->pdf_palettesize){
+ TIFFError(TIFF2PDF_MODULE,
+ "Error: palette_offset + component_count > t2p->pdf_palettesize");
+ return 1;
+ }
for(j=0;j<component_count;j++){
buffer[sample_offset+j]=t2p->pdf_palette[palette_offset+j];
}
diff --git a/tools/tiff2ps.c b/tools/tiff2ps.c
index 5660a68b..31a318a8 100644
--- a/tools/tiff2ps.c
+++ b/tools/tiff2ps.c
@@ -682,8 +682,8 @@ isCCITTCompression(TIFF* tif)
static tsize_t tf_bytesperrow;
static tsize_t ps_bytesperrow;
-static tsize_t tf_rowsperstrip;
-static tsize_t tf_numberstrips;
+static uint32 tf_rowsperstrip;
+static uint32 tf_numberstrips;
static char *hex = "0123456789abcdef";
/*
@@ -1798,7 +1798,7 @@ PS_Lvl2ImageDict(FILE* fd, TIFF* tif, uint32 w, uint32 h)
int use_rawdata;
uint32 tile_width, tile_height;
uint16 predictor, minsamplevalue, maxsamplevalue;
- int repeat_count;
+ uint32 repeat_count;
char im_h[64], im_x[64], im_y[64];
char * imageOp = "image";
@@ -1850,7 +1850,7 @@ PS_Lvl2ImageDict(FILE* fd, TIFF* tif, uint32 w, uint32 h)
fputs("{ % exec\n", fd);
if (repeat_count > 1)
- fprintf(fd, "%d { %% repeat\n", repeat_count);
+ fprintf(fd, "%u { %% repeat\n", repeat_count);
/*
* Output filter options and image dictionary.
@@ -2264,7 +2264,7 @@ PS_Lvl2page(FILE* fd, TIFF* tif, uint32 w, uint32 h)
if (alpha) {
int adjust, i, j = 0;
int ncomps = samplesperpixel - extrasamples;
- for (i = 0; i < byte_count; i+=samplesperpixel) {
+ for (i = 0; (i + ncomps) < byte_count; i+=samplesperpixel) {
adjust = 255 - buf_data[i + ncomps];
switch (ncomps) {
case 1:
@@ -2467,8 +2467,10 @@ PSDataColorContig(FILE* fd, TIFF* tif, uint32 w, uint32 h, int nc)
}
if (alpha) {
int adjust;
- cc = 0;
- for (; cc < tf_bytesperrow; cc += samplesperpixel) {
+ /*
+ * the code inside this loop reads nc bytes + 1 extra byte (for adjust)
+ */
+ for (cc = 0; (cc + nc) < tf_bytesperrow; cc += samplesperpixel) {
DOBREAK(breaklen, nc, fd);
/*
* For images with alpha, matte against
@@ -2486,8 +2488,10 @@ PSDataColorContig(FILE* fd, TIFF* tif, uint32 w, uint32 h, int nc)
cp += es;
}
} else {
- cc = 0;
- for (; cc < tf_bytesperrow; cc += samplesperpixel) {
+ /*
+ * the code inside this loop reads nc bytes per iteration
+ */
+ for (cc = 0; (cc + nc) <= tf_bytesperrow; cc += samplesperpixel) {
DOBREAK(breaklen, nc, fd);
switch (nc) {
case 4: c = *cp++; PUTHEX(c,fd);
@@ -2766,7 +2770,7 @@ PSRawDataBW(FILE* fd, TIFF* tif, uint32 w, uint32 h)
bufsize = (uint32) bc[0];
- for ( s = 0; ++s < (tstrip_t)tf_numberstrips; ) {
+ for ( s = 0; ++s < tf_numberstrips; ) {
if ( bc[s] > bufsize )
bufsize = (uint32) bc[s];
}
@@ -2799,7 +2803,7 @@ PSRawDataBW(FILE* fd, TIFF* tif, uint32 w, uint32 h)
}
#endif
- for (s = 0; s < (tstrip_t) tf_numberstrips; s++) {
+ for (s = 0; s < tf_numberstrips; s++) {
cc = TIFFReadRawStrip(tif, s, tf_buf, (tmsize_t) bc[s]);
if (cc < 0) {
TIFFError(filename, "Can't read strip");
@@ -2966,10 +2970,10 @@ tsize_t Ascii85EncodeBlock( uint8 * ascii85_p, unsigned f_eod, const uint8 * raw
for ( ; raw_l > 3; raw_l -= 4 )
{
- val32 = *(++raw_p) << 24;
- val32 += *(++raw_p) << 16;
- val32 += *(++raw_p) << 8;
- val32 += *(++raw_p);
+ val32 = (uint32)*(++raw_p) << 24;
+ val32 += (uint32)*(++raw_p) << 16;
+ val32 += (uint32)*(++raw_p) << 8;
+ val32 += (uint32)*(++raw_p);
if ( val32 == 0 ) /* Special case */
{
diff --git a/tools/tiffcmp.c b/tools/tiffcmp.c
index 299847df..7b764883 100644
--- a/tools/tiffcmp.c
+++ b/tools/tiffcmp.c
@@ -40,7 +40,7 @@
#include "tiffio.h"
#ifndef HAVE_GETOPT
-extern int getopt(int, char**, char*);
+extern int getopt(int argc, char * const argv[], const char *optstring);
#endif
static int stopondiff = 1;
diff --git a/tools/tiffcp.c b/tools/tiffcp.c
index 2f406e2d..84d81488 100644
--- a/tools/tiffcp.c
+++ b/tools/tiffcp.c
@@ -41,6 +41,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <limits.h>
#include <ctype.h>
@@ -51,7 +52,7 @@
#include "tiffio.h"
#ifndef HAVE_GETOPT
-extern int getopt(int, char**, char*);
+extern int getopt(int argc, char * const argv[], const char *optstring);
#endif
#if defined(VMS)
@@ -1408,7 +1409,7 @@ DECLAREreadFunc(readSeparateTilesIntoBuffer)
int status = 1;
uint32 imagew = TIFFRasterScanlineSize(in);
uint32 tilew = TIFFTileRowSize(in);
- int iskew = imagew - tilew*spp;
+ int iskew;
tsize_t tilesize = TIFFTileSize(in);
tdata_t tilebuf;
uint8* bufp = (uint8*) buf;
@@ -1416,6 +1417,12 @@ DECLAREreadFunc(readSeparateTilesIntoBuffer)
uint32 row;
uint16 bps = 0, bytes_per_sample;
+ if (spp > (INT_MAX / tilew))
+ {
+ TIFFError(TIFFFileName(in), "Error, cannot handle that much samples per tile row (Tile Width * Samples/Pixel)");
+ return 0;
+ }
+ iskew = imagew - tilew*spp;
tilebuf = _TIFFmalloc(tilesize);
if (tilebuf == 0)
return 0;
diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c
index edb1addf..6cc5a2ce 100644
--- a/tools/tiffcrop.c
+++ b/tools/tiffcrop.c
@@ -1334,9 +1334,10 @@ static int writeBufferToSeparateTiles (TIFF* out, uint8* buf, uint32 imagelength
if (obuf == NULL)
return 1;
- TIFFGetField(out, TIFFTAG_TILELENGTH, &tl);
- TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw);
- TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps);
+ if( !TIFFGetField(out, TIFFTAG_TILELENGTH, &tl) ||
+ !TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw) ||
+ !TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps) )
+ return 1;
if( imagewidth == 0 ||
(uint32)bps * (uint32)spp > TIFF_UINT32_MAX / imagewidth ||
@@ -2108,8 +2109,8 @@ update_output_file (TIFF **tiffout, char *mode, int autoindex,
char *outname, unsigned int *page)
{
static int findex = 0; /* file sequence indicator */
+ size_t basename_len;
char *sep;
- char filenum[18];
char export_ext[16];
char exportname[PATH_MAX];
@@ -2120,12 +2121,13 @@ update_output_file (TIFF **tiffout, char *mode, int autoindex,
*tiffout = NULL;
}
- strcpy (export_ext, ".tiff");
- memset (filenum, '\0', sizeof(filenum));
+ memcpy (export_ext, ".tiff", 6);
memset (exportname, '\0', sizeof(exportname));
- /* Leave room for page number portion of the new filename */
- strncpy (exportname, outname, sizeof(exportname) - sizeof(filenum));
+ /* Leave room for page number portion of the new filename :
+ * hyphen + 6 digits + dot + 4 extension characters + null terminator */
+ #define FILENUM_MAX_LENGTH (1+6+1+4+1)
+ strncpy (exportname, outname, sizeof(exportname) - FILENUM_MAX_LENGTH);
if (*tiffout == NULL) /* This is a new export file */
{
if (autoindex)
@@ -2137,8 +2139,9 @@ update_output_file (TIFF **tiffout, char *mode, int autoindex,
*sep = '\0';
}
else
- strncpy (export_ext, ".tiff", 5);
+ memcpy (export_ext, ".tiff", 5);
export_ext[5] = '\0';
+ basename_len = strlen(exportname);
/* MAX_EXPORT_PAGES limited to 6 digits to prevent string overflow of pathname */
if (findex > MAX_EXPORT_PAGES)
@@ -2147,10 +2150,8 @@ update_output_file (TIFF **tiffout, char *mode, int autoindex,
return 1;
}
- snprintf(filenum, sizeof(filenum), "-%03d%.5s", findex, export_ext);
- filenum[sizeof(filenum)-1] = '\0';
- /* We previously assured that there will be space for 'filenum' */
- strcat (exportname, filenum);
+ /* We previously assured that there will be space left */
+ snprintf(exportname + basename_len, sizeof(exportname) - basename_len, "-%03d%.5s", findex, export_ext);
}
exportname[sizeof(exportname) - 1] = '\0';
@@ -4023,9 +4024,9 @@ combineSeparateSamples24bits (uint8 *in[], uint8 *out, uint32 cols,
{
src = in[s] + src_offset + src_byte;
if (little_endian)
- buff1 = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
+ buff1 = ((uint32)src[0] << 24) | ((uint32)src[1] << 16) | ((uint32)src[2] << 8) | (uint32)src[3];
else
- buff1 = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
+ buff1 = ((uint32)src[3] << 24) | ((uint32)src[2] << 16) | ((uint32)src[1] << 8) | (uint32)src[0];
buff1 = (buff1 & matchbits) << (src_bit);
/* If we have a full buffer's worth, write it out */
@@ -9144,7 +9145,6 @@ static int
invertImage(uint16 photometric, uint16 spp, uint16 bps, uint32 width, uint32 length, unsigned char *work_buff)
{
uint32 row, col;
- unsigned char bytebuff1, bytebuff2, bytebuff3, bytebuff4;
unsigned char *src;
uint16 *src_uint16;
uint32 *src_uint32;
@@ -9174,7 +9174,7 @@ invertImage(uint16 photometric, uint16 spp, uint16 bps, uint32 width, uint32 len
for (row = 0; row < length; row++)
for (col = 0; col < width; col++)
{
- *src_uint32 = (uint32)0xFFFFFFFF - *src_uint32;
+ *src_uint32 = ~(*src_uint32);
src_uint32++;
}
break;
@@ -9182,39 +9182,15 @@ invertImage(uint16 photometric, uint16 spp, uint16 bps, uint32 width, uint32 len
for (row = 0; row < length; row++)
for (col = 0; col < width; col++)
{
- *src_uint16 = (uint16)0xFFFF - *src_uint16;
+ *src_uint16 = ~(*src_uint16);
src_uint16++;
}
break;
- case 8: for (row = 0; row < length; row++)
- for (col = 0; col < width; col++)
- {
- *src = (uint8)255 - *src;
- src++;
- }
- break;
- case 4: for (row = 0; row < length; row++)
- for (col = 0; col < width; col++)
- {
- bytebuff1 = 16 - (uint8)(*src & 240 >> 4);
- bytebuff2 = 16 - (*src & 15);
- *src = bytebuff1 << 4 & bytebuff2;
- src++;
- }
- break;
- case 2: for (row = 0; row < length; row++)
- for (col = 0; col < width; col++)
- {
- bytebuff1 = 4 - (uint8)(*src & 192 >> 6);
- bytebuff2 = 4 - (uint8)(*src & 48 >> 4);
- bytebuff3 = 4 - (uint8)(*src & 12 >> 2);
- bytebuff4 = 4 - (uint8)(*src & 3);
- *src = (bytebuff1 << 6) | (bytebuff2 << 4) | (bytebuff3 << 2) | bytebuff4;
- src++;
- }
- break;
+ case 8:
+ case 4:
+ case 2:
case 1: for (row = 0; row < length; row++)
- for (col = 0; col < width; col += 8 /(spp * bps))
+ for (col = 0; col < width; col += 8 / bps)
{
*src = ~(*src);
src++;
diff --git a/tools/tiffdump.c b/tools/tiffdump.c
index ab48e52c..4cdcda0c 100644
--- a/tools/tiffdump.c
+++ b/tools/tiffdump.c
@@ -51,7 +51,7 @@
#endif
#ifndef HAVE_GETOPT
-extern int getopt(int, char**, char*);
+extern int getopt(int argc, char * const argv[], const char *optstring);
#endif
#include "tiffio.h"
diff --git a/tools/tiffgt.c b/tools/tiffgt.c
index 5991d309..2f11b0ca 100644
--- a/tools/tiffgt.c
+++ b/tools/tiffgt.c
@@ -49,7 +49,7 @@
#include "tiffiop.h"
#ifndef HAVE_GETOPT
-extern int getopt(int, char**, char*);
+extern int getopt(int argc, char * const argv[], const char *optstring);
#endif
static uint32 width = 0, height = 0; /* window width & height */
diff --git a/tools/tiffset.c b/tools/tiffset.c
index 7ecc401b..fdfdf3cc 100644
--- a/tools/tiffset.c
+++ b/tools/tiffset.c
@@ -35,6 +35,10 @@
#include "tiffio.h"
+#ifdef NEED_LIBPORT
+# include "libport.h"
+#endif
+
static char* usageMsg[] = {
"usage: tiffset [options] filename",
"where options are:",
diff --git a/tools/tiffsplit.c b/tools/tiffsplit.c
index c9e3a787..c8b7f2dd 100644
--- a/tools/tiffsplit.c
+++ b/tools/tiffsplit.c
@@ -31,7 +31,7 @@
#include "tiffio.h"
#ifndef HAVE_GETOPT
-extern int getopt(int, char**, char*);
+extern int getopt(int argc, char * const argv[], const char *optstring);
#endif
#define CopyField(tag, v) \