diff --git a/.appveyor.yml b/.appveyor.yml index f469afe4..bcc0d1a0 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -32,6 +32,10 @@ environment: shared: OFF - compiler: vc14-nmake configuration: Release + - compiler: vc9-cmake + configuration: Debug + generator: Visual Studio 9 2008 + shared: ON cache: - 'c:\projects\download -> appveyor.yml' @@ -68,6 +72,7 @@ before_build: - 'if %compiler%==cygwin-cmake bash -c "cmake -G \"%generator%\" -DCMAKE_INSTALL_PREFIX:PATH=%AV_TIFF_CMAKE_INSTALL% -DCMAKE_BUILD_TYPE=%configuration% %AV_CMAKE_ARGS% %AV_TIFF_CMAKE_SOURCE%"' - 'if %compiler%==mingw64-cmake cmake -G "%generator%" -DCMAKE_INSTALL_PREFIX:PATH=%AV_TIFF_CMAKE_INSTALL% -DCMAKE_BUILD_TYPE=%configuration% %AV_CMAKE_ARGS% %AV_TIFF_CMAKE_SOURCE%' - 'if %compiler%==vc14-cmake cmake -G "%generator%" -DCMAKE_INSTALL_PREFIX:PATH=%AV_TIFF_CMAKE_INSTALL% -DCMAKE_BUILD_TYPE=%configuration% %AV_CMAKE_ARGS% %AV_TIFF_CMAKE_SOURCE%' + - 'if %compiler%==vc9-cmake cmake -G "%generator%" -DCMAKE_INSTALL_PREFIX:PATH=%AV_TIFF_CMAKE_INSTALL% -DCMAKE_BUILD_TYPE=%configuration% %AV_CMAKE_ARGS% %AV_TIFF_CMAKE_SOURCE%' build_script: - if NOT %compiler%==vc14-nmake cd %AV_TIFF_BUILD% @@ -75,6 +80,7 @@ build_script: - 'if %compiler%==cygwin-cmake bash -c "cmake --build . --config %configuration% --target install"' - 'if %compiler%==mingw64-cmake cmake --build . --config %configuration% --target install' - 'if %compiler%==vc14-cmake cmake --build . --config %configuration% --target install' + - 'if %compiler%==vc9-cmake cmake --build . --config %configuration% --target install' - 'if %compiler%==vc14-nmake nmake /f Makefile.vc EXTRAFLAGS=/DHAVE_SNPRINTF=1' - 'if %compiler%==vc14-nmake mkdir %AV_TIFF_INSTALL%' - 'if %compiler%==vc14-nmake mkdir %AV_TIFF_INSTALL%\bin' @@ -100,6 +106,7 @@ before_test: - 'if %compiler%==cygwin-cmake bash -c "ctest -V -C %configuration%"' - 'if %compiler%==mingw64-cmake ctest -V -C %configuration%' - 'if %compiler%==vc14-cmake ctest -V -C %configuration%' + - 'if %compiler%==vc9-cmake ctest -V -C %configuration%' # vc14-nmake does not support unit tests # AppVeyor don't yet have a configurable retention policy, so this will diff --git a/.gitignore b/.gitignore index 1c8b7c97..b45ca248 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +aclocal.m4 autom4te.cache **/Makefile *.o @@ -18,8 +19,14 @@ libtiff/mkg3states libtiff/stamp-h1 libtiff/stamp-h2 libtiff/tif_config.h +libtiff/tif_config.h.in libtiff/tiffconf.h libtool +m4/libtool.m4 +m4/ltoptions.m4 +m4/ltsugar.m4 +m4/ltversion.m4 +m4/lt~obsolete.m4 tools/fax2ps tools/fax2tiff tools/pal2rgb diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 606948e4..b80f8bed 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,6 @@ image: ubuntu:16.04 before_script: - - apt-get update -qq && apt-get install -y -qq autoconf automake build-essential cmake libtool libjpeg8-dev libjbig-dev liblzma-dev ninja-build zlib1g-dev zip + - apt-get update -qq && apt-get install -y -qq autoconf automake build-essential cmake libtool libjpeg8-dev libjbig-dev liblzma-dev ninja-build zlib1g-dev zip wget stages: - build diff --git a/CMakeLists.txt b/CMakeLists.txt index 52b5ae99..845ddf0e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,7 @@ # LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE # OF THIS SOFTWARE. -cmake_minimum_required(VERSION 2.8.9) +cmake_minimum_required(VERSION 2.8.11) # b/c of use of BUILD_INTERFACE generator expression # Default policy is from 2.8.9 cmake_policy(VERSION 2.8.9) @@ -92,8 +92,9 @@ include(GNUInstallDirs) include(CheckCCompilerFlag) include(CheckCSourceCompiles) include(CheckIncludeFile) +include(CheckLibraryExists) include(CheckTypeSize) -include(CheckFunctionExists) +include(CheckSymbolExists) enable_testing() macro(current_date var) @@ -213,9 +214,6 @@ check_include_file(dlfcn.h HAVE_DLFCN_H) check_include_file(fcntl.h HAVE_FCNTL_H) check_include_file(inttypes.h HAVE_INTTYPES_H) check_include_file(io.h HAVE_IO_H) -check_include_file(limits.h HAVE_LIMITS_H) -check_include_file(malloc.h HAVE_MALLOC_H) -check_include_file(memory.h HAVE_MEMORY_H) check_include_file(search.h HAVE_SEARCH_H) check_include_file(stdint.h HAVE_STDINT_H) check_include_file(string.h HAVE_STRING_H) @@ -271,8 +269,6 @@ int main(void){ # Check type sizes # NOTE: Could be replaced with C99 -check_type_size("signed short" SIZEOF_SIGNED_SHORT) -check_type_size("unsigned short" SIZEOF_UNSIGNED_SHORT) check_type_size("signed int" SIZEOF_SIGNED_INT) check_type_size("unsigned int" SIZEOF_UNSIGNED_INT) check_type_size("signed long" SIZEOF_SIGNED_LONG) @@ -388,80 +384,35 @@ endif() # TIFF_SSIZE_T TIFF_SSIZE_FORMAT # TIFF_PTRDIFF_T TIFF_PTRDIFF_FORMAT) -# Nonstandard int types -check_type_size(INT8 int8) -set(HAVE_INT8 ${INT8}) -check_type_size(INT16 int16) -set(HAVE_INT16 ${INT16}) -check_type_size(INT32 int32) -set(HAVE_INT32 ${INT32}) - -# Check functions -set(CMAKE_REQUIRED_LIBRARIES_SAVE ${CMAKE_REQUIRED_LIBRARIES}) -set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${M_LIBRARY}) -check_function_exists(floor HAVE_FLOOR) -check_function_exists(pow HAVE_POW) -check_function_exists(sqrt HAVE_SQRT) -set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES_SAVE}) - -check_function_exists(isascii HAVE_ISASCII) -check_function_exists(memmove HAVE_MEMMOVE) -check_function_exists(memset HAVE_MEMSET) -check_function_exists(mmap HAVE_MMAP) -check_function_exists(setmode HAVE_SETMODE) -check_function_exists(strcasecmp HAVE_STRCASECMP) -check_function_exists(strchr HAVE_STRCHR) -check_function_exists(strrchr HAVE_STRRCHR) -check_function_exists(strstr HAVE_STRSTR) -check_function_exists(strtol HAVE_STRTOL) -check_function_exists(strtol HAVE_STRTOUL) -check_function_exists(strtoull HAVE_STRTOULL) -check_function_exists(getopt HAVE_GETOPT) -check_function_exists(lfind HAVE_LFIND) - -# May be inlined, so check it compiles: -check_c_source_compiles(" -#include -int main(void) { - char buf[10]; - snprintf(buf, 10, \"Test %d\", 1); - return 0; -}" - HAVE_SNPRINTF) +check_symbol_exists(mmap "sys/mman.h" HAVE_MMAP) +check_symbol_exists(setmode "unistd.h" HAVE_SETMODE) +check_symbol_exists(snprintf "stdio.h" HAVE_SNPRINTF) +check_symbol_exists(strcasecmp "strings.h" HAVE_STRCASECMP) +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(lfind "search.h" HAVE_LFIND) if(NOT HAVE_SNPRINTF) add_definitions(-DNEED_LIBPORT) endif() # CPU bit order -set(fillorder FILLORDER_MSB2LSB) +set(HOST_FILLORDER FILLORDER_MSB2LSB) if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "i.*86.*" OR CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "amd64.*" OR CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86_64.*") - set(fillorder FILLORDER_LSB2MSB) + set(HOST_FILLORDER FILLORDER_LSB2MSB) endif() -set(HOST_FILLORDER ${fillorder} CACHE STRING "Native CPU bit order") -mark_as_advanced(HOST_FILLORDER) # CPU endianness include(TestBigEndian) -test_big_endian(bigendian) -if (bigendian) - set(bigendian ON) -else() - set(bigendian OFF) -endif() -set(HOST_BIG_ENDIAN ${bigendian} CACHE STRING "Native CPU bit order") -mark_as_advanced(HOST_BIG_ENDIAN) -if (HOST_BIG_ENDIAN) - set(HOST_BIG_ENDIAN 1) -else() - set(HOST_BIG_ENDIAN 0) -endif() +test_big_endian(HOST_BIG_ENDIAN) # IEEE floating point -set(HAVE_IEEEFP 1 CACHE STRING "IEEE floating point is available") -mark_as_advanced(HAVE_IEEEFP) +set(HAVE_IEEEFP 1) report_values(CMAKE_HOST_SYSTEM_PROCESSOR HOST_FILLORDER HOST_BIG_ENDIAN HAVE_IEEEFP) @@ -560,12 +511,9 @@ else() set(JBIG_FOUND FALSE) endif() -set(CMAKE_REQUIRED_LIBRARIES_SAVE ${CMAKE_REQUIRED_LIBRARIES}) set(CMAKE_REQUIRED_INCLUDES_SAVE ${CMAKE_REQUIRED_INCLUDES}) set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${JBIG_INCLUDE_DIR}) -set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${JBIG_LIBRARY}) -check_function_exists(jbg_newlen HAVE_JBG_NEWLEN) -set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES_SAVE}) +check_symbol_exists(jbg_newlen "jbig.h" HAVE_JBG_NEWLEN) set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES_SAVE}) # liblzma2 @@ -578,6 +526,42 @@ if(LIBLZMA_FOUND) set(LZMA_SUPPORT 1) endif() +# libzstd +option(zstd "use libzstd (required for ZSTD compression)" ON) +if (zstd) + find_path(ZSTD_INCLUDE_DIR zstd.h) + find_library(ZSTD_LIBRARY NAMES zstd) + if (ZSTD_INCLUDE_DIR AND ZSTD_LIBRARY) + check_library_exists ("${ZSTD_LIBRARY}" ZSTD_decompressStream "" ZSTD_RECENT_ENOUGH) + if (ZSTD_RECENT_ENOUGH) + set(ZSTD_FOUND TRUE) + set(ZSTD_LIBRARIES ${ZSTD_LIBRARY}) + message(STATUS "Found ZSTD library: ${ZSTD_LIBRARY}") + else () + message(WARNING "Found ZSTD library, but not recent enough. Use zstd >= 1.0") + endif () + endif () +endif() +set(ZSTD_SUPPORT 0) +if(ZSTD_FOUND) + set(ZSTD_SUPPORT 1) +endif() + +# libwebp +option(webp "use libwebp (required for WEBP compression)" ON) +if (webp) + find_path(WEBP_INCLUDE_DIR /webp/decode.h) + find_library(WEBP_LIBRARY NAMES webp) +endif() +set(WEBP_SUPPORT 0) +set(WEBP_FOUND FALSE) +if (WEBP_INCLUDE_DIR AND WEBP_LIBRARY) + set(WEBP_SUPPORT 1) + set(WEBP_FOUND TRUE) + set(WEBP_LIBRARIES ${WEBP_LIBRARY}) + message(STATUS "Found WEBP library: ${WEBP_LIBRARY}") +endif() + # 8/12-bit jpeg mode option(jpeg12 "enable libjpeg 8/12-bit dual mode (requires separate 12-bit libjpeg build)" ON) @@ -621,12 +605,8 @@ set(win32_io FALSE) if(WIN32) set(win32_io TRUE) endif() -set(USE_WIN32_FILEIO ${win32_io} CACHE BOOL "Use win32 IO system (Microsoft Windows only)") -if (USE_WIN32_FILEIO) - set(USE_WIN32_FILEIO TRUE) -else() - set(USE_WIN32_FILEIO FALSE) -endif() + +set(USE_WIN32_FILEIO ${win32_io}) # Orthogonal features @@ -692,6 +672,12 @@ endif() if(LIBLZMA_INCLUDE_DIRS) list(APPEND TIFF_INCLUDES ${LIBLZMA_INCLUDE_DIRS}) endif() +if(ZSTD_INCLUDE_DIR) + list(APPEND TIFF_INCLUDES ${ZSTD_INCLUDE_DIR}) +endif() +if(WEBP_INCLUDE_DIR) + list(APPEND TIFF_INCLUDES ${WEBP_INCLUDE_DIR}) +endif() # Libraries required by libtiff set(TIFF_LIBRARY_DEPS) @@ -713,6 +699,12 @@ endif() if(LIBLZMA_LIBRARIES) list(APPEND TIFF_LIBRARY_DEPS ${LIBLZMA_LIBRARIES}) endif() +if(ZSTD_LIBRARIES) + list(APPEND TIFF_LIBRARY_DEPS ${ZSTD_LIBRARIES}) +endif() +if(WEBP_LIBRARIES) + list(APPEND TIFF_LIBRARY_DEPS ${WEBP_LIBRARIES}) +endif() #report_values(TIFF_INCLUDES TIFF_LIBRARY_DEPS) @@ -756,6 +748,8 @@ message(STATUS " Old JPEG support: ${old-jpeg} (requested) ${ message(STATUS " JPEG 8/12 bit dual mode: ${jpeg12} (requested) ${JPEG12_FOUND} (availability)") message(STATUS " ISO JBIG support: ${jbig} (requested) ${JBIG_FOUND} (availability)") message(STATUS " LZMA2 support: ${lzma} (requested) ${LIBLZMA_FOUND} (availability)") +message(STATUS " ZSTD support: ${zstd} (requested) ${ZSTD_FOUND} (availability)") +message(STATUS " WEBP support: ${webp} (requested) ${WEBP_FOUND} (availability)") message(STATUS "") message(STATUS " C++ support: ${cxx} (requested) ${CXX_SUPPORT} (availability)") message(STATUS "") diff --git a/ChangeLog b/ChangeLog index ea8622b8..1f50e201 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,698 @@ +2018-11-10 Bob Friesenhahn + + * configure.ac: libtiff 4.0.10 released. + + Change COMPRESSION_ZSTD to 50000 and COMPRESSION_WEBP to 50001. + +2018-11-04 Bob Friesenhahn + + Added preliminary release notes for release 4.0.10. + +2018-11-03 Bob Friesenhahn + + tiff2pdf: Eliminate compiler warning about snprintf output truncation when formatting pdf_datetime. + +2018-11-03 Olivier Paquet + + Merge branch 'no_tif_platform_console' into 'master' + Remove builtin support for GUI warning and error message boxes + + See merge request libtiff/libtiff!24 + +2018-11-03 Bob Friesenhahn + + tiffcrop.c: Eliminate compiler warning about snprintf output truncation when formatting filenum. + + TWebPVGetField(): Add apparently missing break statement impacting TIFFTAG_WEBP_LOSSLESS. + + Eliminate compiler warnings about duplicate definitions of streq/strneq macros. + + Ignore generated files. + + Remove and ignore files which are a product of autogen.sh. + +2018-11-02 Bob Friesenhahn + + Fix TIFFErrorExt() formatting of size_t type for 32-bit compiles. + +2018-10-30 Even Rouault + + tiff2bw: avoid null pointer dereference in case of out of memory situation. Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2819 / CVE-2018-18661 + + tiffio.h: fix comment. + +2018-10-26 Even Rouault + + Merge branch 'header2' into 'master' + Fix 725279bd: Standalone tif_predict.h: tiff.h should be tiffiop.h + + See merge request libtiff/libtiff!41 + +2018-10-26 Kurt Schwehr + + Fix 725279bd: Standalone tif_predict.h: tiff.h should be tiffiop.h. + +2018-10-25 Even Rouault + + Merge branch 'headers' into 'master' + Add includes to headers to allow them to stand alone. + + See merge request libtiff/libtiff!40 + +2018-10-24 Kurt Schwehr + + Add includes to headers to allow them to stand alone. + This allows compilers that can do header stand alone header parsing + to process libtiff. + +2018-10-18 Even Rouault + + LZMAPreEncode: emit verbose error if lzma_stream_encoder() fails (typically because not enough memory available) + +2018-10-17 Even Rouault + + tif_webp.c: fix previous commit that broke scanline decoding. + + tif_webp.c: fix potential read outside libwebp buffer on corrupted images + +2018-10-14 Even Rouault + + Merge branch 'jbig_decode_overflow' into 'master' + JBIG: fix potential out-of-bounds write in JBIGDecode() + + See merge request libtiff/libtiff!38 + +2018-10-14 Even Rouault + + JBIG: fix potential out-of-bounds write in JBIGDecode() + JBIGDecode doesn't check if the user provided buffer is large enough + to store the JBIG decoded image, which can potentially cause out-of-bounds + write in the buffer. + This issue was reported and analyzed by Thomas Dullien. + + Also fixes a (harmless) potential use of uninitialized memory when + tif->tif_rawsize > tif->tif_rawcc + + And in case libtiff is compiled with CHUNKY_STRIP_READ_SUPPORT, make sure + that whole strip data is provided to JBIGDecode() + +2018-10-05 Even Rouault + + tif_webp.c: fix scanline reading/writing. + + WEBP codec: initialize nSamples in TWebPSetupDecode() and TWebPSetupEncode() + +2018-10-05 Even Rouault + + Merge branch 'tif_webp' into 'master' + webp support + + See merge request libtiff/libtiff!32 + +2018-10-05 Norman Barker + + webp in tiff. + +2018-09-17 Even Rouault + + Merge branch 'master' into 'master' + fix three potential vulnerabilities. + + See merge request libtiff/libtiff!33 + +2018-09-08 Young_X + + fix out-of-bound read on some tiled images. + + avoid potential int32 overflows in multiply_ms() + + only read/write TIFFTAG_GROUP3OPTIONS or TIFFTAG_GROUP4OPTIONS if compression is COMPRESSION_CCITTFAX3 or COMPRESSION_CCITTFAX4 + +2018-08-15 Even Rouault + + TIFFSetupStrips(): avoid potential uint32 overflow on 32-bit systems with large number of strips. Probably relates to http://bugzilla.maptools.org/show_bug.cgi?id=2788 / CVE-2018-10779 + +2018-08-07 Even Rouault + + ZSTD: fix flush issue that can cause endless loop in ZSTDEncode() + Fixes https://github.com/OSGeo/gdal/issues/833 + +2018-08-07 Even Rouault + + Merge branch 'fix_bug_2800' into 'master' + Fix libtiff 4.0.8 regression when reading LZW-compressed strips with scanline API + + See merge request libtiff/libtiff!31 + +2018-08-07 Even Rouault + + Fix libtiff 4.0.8 regression when reading LZW-compressed strips with scanline API + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2800 + +2018-07-05 Even Rouault + + Add tag and pseudo-tag definitions for ESRI LERC codec (out of tree codec whose source is at https://github.com/OSGeo/gdal/blob/master/gdal/frmts/gtiff/tif_lerc.c) + +2018-07-02 Even Rouault + + Fix TIFFTAG_ZSTD_LEVEL pseudo tag value to be > 65536, and the next one in the series + +2018-05-25 Stefan Weil + + Remove builtin support for GUI warning and error message boxes. + Now warnings always go to the console by default unless applications + define their own warning and error handlers. + + GUI applications (and Windows CE) are required to define such handlers. + +2018-05-12 Even Rouault + + LZWDecodeCompat(): fix potential index-out-of-bounds write. Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2780 / CVE-2018-8905 + The fix consists in using the similar code LZWDecode() to validate we + don't write outside of the output buffer. + + TIFFFetchNormalTag(): avoid (probably false positive) clang-tidy clang-analyzer-core.NullDereference warnings + + TIFFWriteDirectorySec: avoid assertion. Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2795. CVE-2018-10963 + +2018-05-04 Even Rouault + + tif_color.c: fix code comment. + +2018-04-17 Even Rouault + + Merge branch 'fuzzer-fix' into 'master' + remove a pointless multiplication and a variable that's not necessary + + See merge request libtiff/libtiff!29 + +2018-04-17 Paul Kehrer + + remove a pointless multiplication and a variable that's not necessary. + +2018-04-17 Even Rouault + + Merge branch 'ossfuzz' into 'master' + move oss-fuzz build script and fuzzer into libtiff tree + + See merge request libtiff/libtiff!28 + +2018-04-17 Paul Kehrer + + move oss-fuzz build script and fuzzer into libtiff tree. + +2018-04-14 Even Rouault + + _TIFFGetMaxColorChannels: update for LOGLUV, ITULAB and ICCLAB that have 3 color channels + +2018-04-12 Even Rouault + + Fix MSVC warning. + +2018-04-12 Even Rouault + + Merge branch 'master' into 'master' + Fix NULL pointer dereference in TIFFPrintDirectory (bugzilla 2778/CVE-2018-7456) + + See merge request libtiff/libtiff!27 + +2018-04-11 Hugo Lefeuvre + + Fix NULL pointer dereference in TIFFPrintDirectory. + The TIFFPrintDirectory function relies on the following assumptions, + supposed to be guaranteed by the specification: + + (a) A Transfer Function field is only present if the TIFF file has + photometric type < 3. + + (b) If SamplesPerPixel > Color Channels, then the ExtraSamples field + has count SamplesPerPixel - (Color Channels) and contains + information about supplementary channels. + + While respect of (a) and (b) are essential for the well functioning of + TIFFPrintDirectory, no checks are realized neither by the callee nor + by TIFFPrintDirectory itself. Hence, following scenarios might happen + and trigger the NULL pointer dereference: + + (1) TIFF File of photometric type 4 or more has illegal Transfer + Function field. + + (2) TIFF File has photometric type 3 or less and defines a + SamplesPerPixel field such that SamplesPerPixel > Color Channels + without defining all extra samples in the ExtraSamples fields. + + In this patch, we address both issues with respect of the following + principles: + + (A) In the case of (1), the defined transfer table should be printed + safely even if it isn't 'legal'. This allows us to avoid expensive + checks in TIFFPrintDirectory. Also, it is quite possible that + an alternative photometric type would be developed (not part of the + standard) and would allow definition of Transfer Table. We want + libtiff to be able to handle this scenario out of the box. + + (B) In the case of (2), the transfer table should be printed at its + right size, that is if TIFF file has photometric type Palette + then the transfer table should have one row and not three, even + if two extra samples are declared. + + In order to fulfill (A) we simply add a new 'i < 3' end condition to + the broken TIFFPrintDirectory loop. This makes sure that in any case + where (b) would be respected but not (a), everything stays fine. + + (B) is fulfilled by the loop condition + 'i < td->td_samplesperpixel - td->td_extrasamples'. This is enough as + long as (b) is respected. + + Naturally, we also make sure (b) is respected. This is done in the + TIFFReadDirectory function by making sure any non-color channel is + counted in ExtraSamples. + + This commit addresses CVE-2018-7456. + +2018-03-27 Even Rouault + + Merge branch 'tiffset-long8' into 'master' + tiffset: Add support for LONG8, SLONG8 and IFD8 field types + + See merge request libtiff/libtiff!25 + +2018-03-26 Roger Leigh + + port: Clean up NetBSD sources and headers to build standalone. + +2018-03-23 Roger Leigh + + port: Add strtol, strtoll and strtoull. + Also update strtoul. All use the same implementation from NetBSD libc. + + tiffset: Add support for LONG8, SLONG8 and IFD8 field types. + +2018-03-17 Even Rouault + + ChopUpSingleUncompressedStrip: avoid memory exhaustion (CVE-2017-11613) + Rework fix done in 3719385a3fac5cfb20b487619a5f08abbf967cf8 to work in more + cases like https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=6979. + Credit to OSS Fuzz + + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2724 + +2018-03-13 Even Rouault + + libtiff/tif_luv.c: rewrite loops in a more readable way (to avoid false positive reports like http://bugzilla.maptools.org/show_bug.cgi?id=2779) + +2018-03-13 Even Rouault + + Merge branch 'avoid_memory_exhaustion_in_ChopUpSingleUncompressedStrip' into 'master' + ChopUpSingleUncompressedStrip: avoid memory exhaustion (CVE-2017-11613) + + See merge request libtiff/libtiff!26 + +2018-03-11 Even Rouault + + ChopUpSingleUncompressedStrip: avoid memory exhaustion (CVE-2017-11613) + In ChopUpSingleUncompressedStrip(), if the computed number of strips is big + enough and we are in read only mode, validate that the file size is consistent + with that number of strips to avoid useless attempts at allocating a lot of + memory for the td_stripbytecount and td_stripoffset arrays. + + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2724 + +2018-03-10 Even Rouault + + Typo fix in comment. + +2018-03-03 Even Rouault + + Avoid warning with gcc 8 (partially revert 647b0e8c11ee11896f319b92cf110775f538d75c) + +2018-02-25 Even Rouault + + Merge branch 'typos' into 'master' + Fix some typos + + See merge request libtiff/libtiff!23 + +2018-02-24 Stefan Weil + + Fix some typos. + Most of them were found by codespell. + +2018-02-14 Even Rouault + + Typo fix in comment. + + Merge branch 'zstd' + + Add warning about COMPRESSION_ZSTD not being officialy registered. + +2018-02-14 Even Rouault + + Merge branch 'bug2772' into 'master' + Fix for bug 2772 + + See merge request libtiff/libtiff!20 + +2018-02-12 Nathan Baker + + Fix for bug 2772. + It is possible to craft a TIFF document where the IFD list is circular, + leading to an infinite loop while traversing the chain. The libtiff + directory reader has a failsafe that will break out of this loop after + reading 65535 directory entries, but it will continue processing, + consuming time and resources to process what is essentially a bogus TIFF + document. + + This change fixes the above behavior by breaking out of processing when + a TIFF document has >= 65535 directories and terminating with an error. + +2018-02-09 Even Rouault + + Merge branch 'libtiff-as-subdirectory-fixes' into 'master' + Prefer target_include_directories + + See merge request libtiff/libtiff!12 + +2018-02-06 Even Rouault + + Merge branch 'cmake-cleanups' into 'master' + Cmake cleanups + + See merge request libtiff/libtiff!11 + +2018-02-06 Even Rouault + + Merge branch 'check-right-cxx-variable' into 'master' + Check right cxx variable + + See merge request libtiff/libtiff!19 + +2018-02-06 Even Rouault + + Merge branch 'dont-leak-stream-open' into 'master' + Fix a memory leak in TIFFStreamOpen + + See merge request libtiff/libtiff!17 + +2018-02-06 Ben Boeckel + + cmake: check CXX_SUPPORT. + This variable is set in response to the `cxx` cache variable; use it + instead. + +2018-02-04 Olivier Paquet + + Merge branch 'warnings' into 'master' + Fix all compiler warnings for default build + + See merge request libtiff/libtiff!16 + +2018-02-04 Nathan Baker + + Fix all compiler warnings for default build. + +2018-01-30 Paul Kehrer + + tabs are hard. + +2018-01-29 Paul Kehrer + + use hard tabs like the rest of the project. + + Fix a memory leak in TIFFStreamOpen. + TIFFStreamOpen allocates a new tiff{o,i}s_data, but if TIFFClientOpen + fails then that struct is leaked. Delete it if the returned TIFF * is + null. + +2018-01-29 Kevin Funk + + Bump minimum required CMake version to v2.8.11. + Because we use the BUILD_INTERFACE generator expression + +2018-01-27 Even Rouault + + Merge branch 'patch-1' into 'master' + Update CMakeLists.txt for build fix on Windows + + See merge request libtiff/libtiff!14 + +2018-01-27 Even Rouault + + Merge branch 'patch-2' into 'master' + Update tiffgt.c for build fix on Windows + + See merge request libtiff/libtiff!13 + +2018-01-25 Olivier Paquet + + Merge branch 'bug2750' into 'master' + Add workaround to pal2rgb buffer overflow. + + See merge request libtiff/libtiff!15 + +2018-01-25 Nathan Baker + + Add workaround to pal2rgb buffer overflow. + +2018-01-23 Andrea + + Update tiffgt.c for build fix on Windows. + + Update CMakeLists.txt for build fix on Windows. + +2018-01-15 Even Rouault + + Merge branch 'has-attribute-check' into 'master' + tiffiop: use __has_attribute to detect the no_sanitize attribute + + See merge request libtiff/libtiff!10 + +2018-01-15 Ben Boeckel + + cmake: avoid setting hard-coded variables in the cache. + + cmake: avoid an unnecessary intermediate variable. + + cmake: avoid an unnecessary intermediate variable. + + cmake: avoid tautological logic. + + cmake: use check_symbol_exists. + This accounts for symbols being provided by macros. + + cmake: remove unused configure checks. + +2018-01-12 Kevin Funk + + Prefer target_include_directories. + When libtiff is included in a super project via a simple + `add_subdirectory(libtiff)`, this way the `tiff` library target has all + the necessary information to build against it. + + Note: The BUILD_INTERFACE generator expression feature requires at least + CMake v2.8.11 if I'm correct. + +2018-01-09 Ben Boeckel + + tiffiop: use __has_attribute to detect the no_sanitize attribute. + +2017-12-31 Even Rouault + + man/TIFFquery.3tiff: remove reference to non-existing TIFFReadStrip() function in TIFFIsByteSwapped() documentation. Patch by Eric Piel. Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2763 + + libtiff/tif_dir.c: _TIFFVGetField(): fix heap out-of-bounds access when requesting TIFFTAG_NUMBEROFINKS on a EXIF directory. Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2765. Reported by Google Autofuzz project + + libtiff/tif_print.c: TIFFPrintDirectory(): fix null pointer dereference on corrupted file. Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2770 + +2017-12-21 Even Rouault + + Add libzstd to gitlab-ci. + +2017-12-21 Even Rouault + + Add ZSTD compression codec. + From https://github.com/facebook/zstd + "Zstandard, or zstd as short version, is a fast lossless compression + algorithm, targeting real-time compression scenarios at zlib-level + and better compression ratios. It's backed by a very fast entropy stage, + provided by Huff0 and FSE library." + + We require libzstd >= 1.0.0 so as to be able to use streaming compression + and decompression methods. + + The default compression level we have selected is 9 (range goes from 1 to 22), + which experimentally offers equivalent or better compression ratio than + the default deflate/ZIP level of 6, and much faster compression. + + For example on a 6600x4400 16bit image, tiffcp -c zip runs in 10.7 seconds, + while tiffcp -c zstd runs in 5.3 seconds. Decompression time for zip is + 840 ms, and for zstd 650 ms. File size is 42735936 for zip, and + 42586822 for zstd. Similar findings on other images. + + On a 25894x16701 16bit image, + + Compression time Decompression time File size + + ZSTD 35 s 3.2 s 399 700 498 + ZIP/Deflate 1m 20 s 4.9 s 419 622 336 + +2017-12-10 Even Rouault + + Merge branch 'fix_cve-2017-9935' into 'master' + Fix CVE-2017-9935 + + See merge request libtiff/libtiff!7 + +2017-12-10 Brian May + + tiff2pdf: Fix apparent incorrect type for transfer table. + The standard says the transfer table contains unsigned 16 bit values, + I have no idea why we refer to them as floats. + +2017-12-10 Brian May + + tiff2pdf: Fix CVE-2017-9935. + Fix for http://bugzilla.maptools.org/show_bug.cgi?id=2704 + + This vulnerability - at least for the supplied test case - is because we + assume that a tiff will only have one transfer function that is the same + for all pages. This is not required by the TIFF standards. + + We than read the transfer function for every page. Depending on the + transfer function, we allocate either 2 or 4 bytes to the XREF buffer. + We allocate this memory after we read in the transfer function for the + page. + + For the first exploit - POC1, this file has 3 pages. For the first page + we allocate 2 extra extra XREF entries. Then for the next page 2 more + entries. Then for the last page the transfer function changes and we + allocate 4 more entries. + + When we read the file into memory, we assume we have 4 bytes extra for + each and every page (as per the last transfer function we read). Which + is not correct, we only have 2 bytes extra for the first 2 pages. As a + result, we end up writing past the end of the buffer. + + There are also some related issues that this also fixes. For example, + TIFFGetField can return uninitalized pointer values, and the logic to + detect a N=3 vs N=1 transfer function seemed rather strange. + + It is also strange that we declare the transfer functions to be of type + float, when the standard says they are unsigned 16 bit values. This is + fixed in another patch. + + This patch will check to ensure that the N value for every transfer + function is the same for every page. If this changes, we abort with an + error. In theory, we should perhaps check that the transfer function + itself is identical for every page, however we don't do that due to the + confusion of the type of the data in the transfer function. + +2017-12-10 Even Rouault + + Merge branch 'undef-warn-fixes' into 'master' + Fix a couple of harmless but annoying -Wundef warnings + + See merge request libtiff/libtiff!8 + +2017-12-07 Vadim Zeitlin + + Remove tests for undefined SIZEOF_VOIDP. + As configure never uses AC_CHECK_SIZEOF(void*), this symbol is never + defined and so it doesn't make sense to test it in the code, this just + results in -Wundef warnings if they're enabled. + + Avoid harmless -Wundef warnings for __clang_major__ + Check that we're using Clang before checking its version. + +2017-12-02 Even Rouault + + Merge branch 'remove_autogenerated_files' into 'master' + Remove autogenerated files + + See merge request libtiff/libtiff!5 + +2017-12-02 Bob Friesenhahn + + Merge branch 'tif_config_h_includes' into 'master' + 'tif_config.h' or 'tiffiop.h' must be included before any system header. + + See merge request libtiff/libtiff!6 + +2017-12-02 Bob Friesenhahn + + 'tif_config.h' or 'tiffio.h' must be included before any system header. + +2017-12-01 Even Rouault + + .gitignore: add patterns for build from root. + + Remove remaining .cvsignore files. + + Remove autoconf/automake generated files, and add them to .gitignore. + +2017-12-01 Olivier Paquet + + Merge branch 'makedistcheck' into 'master' + build/gitlab-ci and build/travis-ci: add a 'make dist' step in autoconf_build()… + + See merge request libtiff/libtiff!4 + +2017-12-01 Even Rouault + + build/gitlab-ci and build/travis-ci: add a 'make dist' step in autoconf_build() target, to check we are release-ready + +2017-12-01 Even Rouault + + Merge branch 'git_updates' into 'master' + CVS to Git updates + + See merge request libtiff/libtiff!2 + +2017-12-01 Even Rouault + + HOWTO-RELEASE: update to use signed tags. + + README.md: use markdown syntax for hyperlinks. + +2017-11-30 Even Rouault + + Add .gitignore. + + Regenerate autoconf files. + + Makefile.am: update to reflect removal of README.vms and README -> README.md + + Remove all $Id and $Headers comments with CVS versions. + + HOWTO-RELEASE: update for git. + + Remove outdated .cvsignore. + + Remove outdated commit script. + + Remove README.vms. + + Rename README as README.md, and update content. + + html/index.html: reflect change from CVS to gitlab. + +2017-11-30 Olivier Paquet + + Merge branch 'test-ci' into 'master' + Update CI configuration + + See merge request libtiff/libtiff!1 + +2017-11-23 Roger Leigh + + appveyor: Correct path for git clone and skip artefact archival. + +2017-11-22 Roger Leigh + + travis-ci: Remove unused matrix exclusion. + + Add gitlab-ci build support. + 2017-11-18 Bob Friesenhahn * configure.ac: libtiff 4.0.9 released. @@ -1849,7 +2544,7 @@ * libtiff/tif_jpeg.c: in JPEGFixupTags(), recognize SOF2, SOF9 and SOF10 markers to avoid emitting a warning (even if, according to the TechNote, - there are admitedly unusual/not recommended or even forbidden variants, but + there are admittedly unusual/not recommended or even forbidden variants, but they do work well with libjpeg for SOF2, and with libjpeg-turbo for SOF2, SOF9 and SOF10). Define in_color_space and input_components to the right values in @@ -2432,7 +3127,7 @@ 2012-05-19 Bob Friesenhahn * man/TIFFGetField.3tiff: Correct the 'count' field type in the - example for how to retreive the value of unsupported tags. + example for how to retrieve the value of unsupported tags. 2012-03-30 Frank Warmerdam @@ -3039,7 +3734,7 @@ 2010-04-21 Frank Warmerdam - * libtiff/tif_jpeg.c: avoid preparing jpeg tables everytime + * libtiff/tif_jpeg.c: avoid preparing jpeg tables every time JPEGSetupEncode() is called if the tables already seem to be established. This prevents spurious updates and rewriting of directories with jpegtables when doing updates to existing images. @@ -3371,7 +4066,7 @@ * test/common.sh - start verbose mode after common settings. - * libtiff/tif_dirinfo.c: Replace lfind() with local equivelent to + * libtiff/tif_dirinfo.c: Replace lfind() with local equivalent to avoid type mismatches on different platforms. http://bugzilla.maptools.org/show_bug.cgi?id=1889 @@ -3518,7 +4213,7 @@ * tools/tiffdump.c: When compiling for Microsoft Windows, apply consistent (__int64) casting when testing if _lseeki64 has - successfully seeked as requested. This is necessary for large + successfully sought as requested. This is necessary for large file support to work since off_t is only 32-bit. 2008-07-29 Frank Warmerdam @@ -4316,7 +5011,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic * libtiff/tif_getimage.c: replaced usage of TIFFScanlineSize in gtStripContig with TIFFNewScanlineSize so as to fix buggy behaviour on subsampled images - this ought to get sorted when we feel brave - enough to replace TIFFScanlineSize alltogether + enough to replace TIFFScanlineSize altogether * libtiff/tif_ojpeg.c: fixed bug in OJPEGReadSkip @@ -4974,7 +5669,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic 2005-06-03 Andrey Kiselev - * libtiff/tif_open.c: Replace runtime endianess check with the compile + * libtiff/tif_open.c: Replace runtime endianness check with the compile time one. * libtiff/tif_predict.c: Floating point predictor now works on @@ -6316,7 +7011,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic 2003-11-16 Andrey Kiselev * libtiff/{tiff.h, tif_dirinfo.c}: Added support for IFD (13) - datatype, intruduced in "Adobe PageMaker TIFF Tech. Notes". + datatype, introduced in "Adobe PageMaker TIFF Tech. Notes". 2003-11-15 Frank Warmerdam @@ -6627,7 +7322,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic * contrib/ojpeg/{Makefile.in, jdhuff.h, jinclude.h, ojpeg.c, README}, configure, Makefile.in: Improved libtiff compilation with OJPEG - support. Now no need for patching IJG JPEG library, hack requred by + support. Now no need for patching IJG JPEG library, hack required by libtiff will be compiled and used in-place. Implemented with suggestion and help from Bill Allombert, Debian's libjpeg maintainer. @@ -7485,7 +8180,7 @@ btiff/tif_win32.c: Replace custom Win32 memory api with generic sizes. It fixes two problems: Without scaling (-S) the fax is now centered on the page size specified - with -H and/or -W. Before, fax2ps was using an obscure and practially + with -H and/or -W. Before, fax2ps was using an obscure and practically useless algorithm to allocate the image relative to Letter sized paper which sometime sled to useless whitespace on the paper, while at the same time cutting of the faxes printable area at the opposite border. diff --git a/RELEASE-DATE b/RELEASE-DATE index f5a5ad72..94d1f0c1 100644 --- a/RELEASE-DATE +++ b/RELEASE-DATE @@ -1 +1 @@ -20171118 +20181110 diff --git a/VERSION b/VERSION index 7919852f..2d2d6810 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.0.9 +4.0.10 diff --git a/build/gitlab-ci b/build/gitlab-ci index 1370caec..1612cf5f 100644 --- a/build/gitlab-ci +++ b/build/gitlab-ci @@ -13,7 +13,7 @@ autoconf_build() mkdir autoconf-build cd autoconf-build echo "Running ../configure --prefix=$(pwd)/../autoconf-install) ${opts}" - ../configure --prefix=$(pwd)/../autoconf-install ${opts} + ../configure --prefix=$(pwd)/../autoconf-install --with-zstd-include-dir=/tmp/include --with-zstd-lib-dir=/tmp/lib --with-webp-include-dir=/tmp/include --with-webp-lib-dir=/tmp/lib ${opts} make make install make check @@ -29,8 +29,8 @@ cmake_build() fi mkdir cmake-build cd cmake-build - echo "Running cmake -G "$1" -DCMAKE_BUILD_TYPE="$2" -DCMAKE_INSTALL_PREFIX=../autoconf-install ${opts} .." - cmake -G "$1" -DCMAKE_BUILD_TYPE="$2" -DCMAKE_INSTALL_PREFIX=../autoconf-install ${opts} .. + echo "Running cmake -G "$1" -DCMAKE_BUILD_TYPE="$2" -DCMAKE_INSTALL_PREFIX=../autoconf-install -DZSTD_INCLUDE_DIR=/tmp/include -DZSTD_LIBRARY=/tmp/lib/libzstd.so -DWEBP_INCLUDE_DIR=/tmp/include -DZWEBP_LIBRARY=/tmp/lib/libwebp.so ${opts} .." + cmake -G "$1" -DCMAKE_BUILD_TYPE="$2" -DCMAKE_INSTALL_PREFIX=../autoconf-install -DZSTD_INCLUDE_DIR=/tmp/include -DZSTD_LIBRARY=/tmp/lib/libzstd.so -DWEBP_INCLUDE_DIR=/tmp/include -DWEBP_LIBRARY=/tmp/lib/libwebp.so ${opts} .. cmake --build . cmake --build . --target install ctest -V @@ -39,6 +39,27 @@ cmake_build() build=$1 shift +# Build zstd +wget https://github.com/facebook/zstd/archive/v1.3.3.tar.gz +tar xvzf v1.3.3.tar.gz +cd zstd-1.3.3/lib +# Faster build +make -j3 PREFIX=/tmp ZSTD_LEGACY_SUPPORT=0 CFLAGS=-O1 +make install PREFIX=/tmp ZSTD_LEGACY_SUPPORT=0 CFLAGS=-O1 +cd ../.. +rm -rf zstd-1.3.3 + +# Build webp +wget https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.0.0.tar.gz +tar xvzf libwebp-1.0.0.tar.gz +cd libwebp-1.0.0 +./configure --prefix=/tmp +make && make install +cd .. +rm -rf libwebp-1.0.0 + +export LD_LIBRARY_PATH=/tmp/lib + case $build in autoconf) echo "Testing Autoconf build" diff --git a/configure.ac b/configure.ac index 0dd32b75..c7b02e25 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.9],[tiff@lists.maptools.org],[tiff]) +AC_INIT([LibTIFF Software],[4.0.10],[tiff@lists.maptools.org],[tiff]) AC_CONFIG_AUX_DIR(config) AC_CONFIG_MACRO_DIR(m4) AC_LANG(C) @@ -41,7 +41,7 @@ dnl Versioning. dnl Don't fill the ALPHA_VERSION field, if not applicable. LIBTIFF_MAJOR_VERSION=4 LIBTIFF_MINOR_VERSION=0 -LIBTIFF_MICRO_VERSION=9 +LIBTIFF_MICRO_VERSION=10 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=8 +LIBTIFF_CURRENT=9 LIBTIFF_REVISION=0 -LIBTIFF_AGE=3 +LIBTIFF_AGE=4 LIBTIFF_VERSION_INFO=$LIBTIFF_CURRENT:$LIBTIFF_REVISION:$LIBTIFF_AGE # This is a special hack for OpenBSD and MirOS systems. The dynamic linker @@ -174,7 +174,7 @@ case "${host_os}" in esac dnl Checks for header files. -AC_CHECK_HEADERS([assert.h fcntl.h io.h limits.h malloc.h search.h sys/time.h unistd.h]) +AC_CHECK_HEADERS([assert.h fcntl.h io.h search.h unistd.h]) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST @@ -196,12 +196,6 @@ dnl --------------------------------------------------------------------------- dnl Compute sized types for current CPU and compiler options dnl --------------------------------------------------------------------------- -# Obtain size of an 'signed short' and define as SIZEOF_SIGNED_SHORT -AC_CHECK_SIZEOF(signed short) - -# Obtain size of an 'unsigned short' and define as SIZEOF_UNSIGNED_SHORT -AC_CHECK_SIZEOF(unsigned short) - # Obtain size of an 'signed int' and define as SIZEOF_SIGNED_INT AC_CHECK_SIZEOF(signed int) @@ -412,22 +406,15 @@ AC_MSG_RESULT($PTRDIFF_T) AC_DEFINE_UNQUOTED(TIFF_PTRDIFF_T,$PTRDIFF_T,[Pointer difference type]) AC_DEFINE_UNQUOTED(TIFF_PTRDIFF_FORMAT,$PTRDIFF_FORMAT,[Pointer difference type formatter]) -dnl Some compilers (IBM VisualAge) has these types defined, so check it here: -AC_CHECK_TYPES([int8, int16, int32],,, -[ -#if HAVE_INTTYPES_H -# include -#endif -]) - dnl Checks for library functions. -AC_CHECK_FUNCS([floor isascii memmove memset mmap pow setmode snprintf sqrt \ -strchr strrchr strstr strtol strtoul strtoull]) +AC_CHECK_FUNCS([mmap setmode snprintf]) dnl Will use local replacements for unavailable functions AC_REPLACE_FUNCS(getopt) AC_REPLACE_FUNCS(snprintf) AC_REPLACE_FUNCS(strcasecmp) +AC_REPLACE_FUNCS(strtol) +AC_REPLACE_FUNCS(strtoll) AC_REPLACE_FUNCS(strtoul) AC_REPLACE_FUNCS(strtoull) AC_REPLACE_FUNCS(lfind) @@ -826,6 +813,114 @@ fi AM_CONDITIONAL(HAVE_LZMA, test "$HAVE_LZMA" = 'yes') +dnl --------------------------------------------------------------------------- +dnl Check for libzstd. +dnl --------------------------------------------------------------------------- + +HAVE_ZSTD=no + +AC_ARG_ENABLE(zstd, + AS_HELP_STRING([--disable-zstd], + [disable libzstd usage (required for zstd compression, enabled by default)]),,) +AC_ARG_WITH(zstd-include-dir, + AS_HELP_STRING([--with-zstd-include-dir=DIR], + [location of libzstd headers]),,) +AC_ARG_WITH(zstd-lib-dir, + AS_HELP_STRING([--with-zstd-lib-dir=DIR], + [location of libzstd library binary]),,) + +if test "x$enable_zstd" != "xno" ; then + + if test "x$with_zstd_lib_dir" != "x" ; then + LDFLAGS="-L$with_zstd_lib_dir $LDFLAGS" + fi + + AC_CHECK_LIB(zstd, ZSTD_decompressStream, [zstd_lib=yes], [zstd_lib=no],) + if test "$zstd_lib" = "no" -a "x$with_zstd_lib_dir" != "x"; then + AC_MSG_ERROR([zstd library not found at $with_zstd_lib_dir]) + fi + + if test "x$with_zstd_include_dir" != "x" ; then + CPPFLAGS="-I$with_zstd_include_dir $CPPFLAGS" + fi + AC_CHECK_HEADER(zstd.h, [zstd_h=yes], [zstd_h=no]) + if test "$zstd_h" = "no" -a "x$with_zstd_include_dir" != "x" ; then + AC_MSG_ERROR([Libzstd headers not found at $with_zstd_include_dir]) + fi + + if test "$zstd_lib" = "yes" -a "$zstd_h" = "yes" ; then + HAVE_ZSTD=yes + fi + +fi + +if test "$HAVE_ZSTD" = "yes" ; then + AC_DEFINE(ZSTD_SUPPORT,1,[Support zstd compression]) + LIBS="-lzstd $LIBS" + tiff_libs_private="-lzstd ${tiff_libs_private}" + + if test "$HAVE_RPATH" = "yes" -a "x$with_zstd_lib_dir" != "x" ; then + LIBDIR="-R $with_zstd_lib_dir $LIBDIR" + fi + +fi + +AM_CONDITIONAL(HAVE_ZSTD, test "$HAVE_ZSTD" = 'yes') + +dnl --------------------------------------------------------------------------- +dnl Check for libwebp. +dnl --------------------------------------------------------------------------- + +HAVE_WEBP=no + +AC_ARG_ENABLE(webp, + AS_HELP_STRING([--disable-webp], + [disable libwebp usage (required for webp compression, enabled by default)]),,) +AC_ARG_WITH(webp-include-dir, + AS_HELP_STRING([--with-webp-include-dir=DIR], + [location of libwebp headers]),,) +AC_ARG_WITH(webp-lib-dir, + AS_HELP_STRING([--with-webp-lib-dir=DIR], + [location of libwebp library binary]),,) + +if test "x$enable_webp" != "xno" ; then + + if test "x$with_webp_lib_dir" != "x" ; then + LDFLAGS="-L$with_webp_lib_dir $LDFLAGS" + fi + + AC_CHECK_LIB(webp, WebPDecode, [webp_lib=yes], [webp_lib=no],) + if test "$webp_lib" = "no" -a "x$with_webp_lib_dir" != "x"; then + AC_MSG_ERROR([webp library not found at $with_webp_lib_dir]) + fi + + if test "x$with_webp_include_dir" != "x" ; then + CPPFLAGS="-I$with_webp_include_dir $CPPFLAGS" + fi + AC_CHECK_HEADER(webp/decode.h, [webp_h=yes], [webp_h=no]) + if test "$webp_h" = "no" -a "x$with_webp_include_dir" != "x" ; then + AC_MSG_ERROR([Libwebp headers not found at $with_webp_include_dir]) + fi + + if test "$webp_lib" = "yes" -a "$webp_h" = "yes" ; then + HAVE_WEBP=yes + fi + +fi + +if test "$HAVE_WEBP" = "yes" ; then + AC_DEFINE(WEBP_SUPPORT,1,[Support webp compression]) + LIBS="-lwebp $LIBS" + tiff_libs_private="-lwebp ${tiff_libs_private}" + + if test "$HAVE_RPATH" = "yes" -a "x$with_webp_lib_dir" != "x" ; then + LIBDIR="-R $with_webp_lib_dir $LIBDIR" + fi + +fi + +AM_CONDITIONAL(HAVE_WEBP, test "$HAVE_WEBP" = 'yes') + dnl --------------------------------------------------------------------------- dnl Should 8/12 bit jpeg mode be enabled? dnl --------------------------------------------------------------------------- @@ -1103,6 +1198,8 @@ LOC_MSG([ Old JPEG support: ${HAVE_OJPEG}]) LOC_MSG([ JPEG 8/12 bit dual mode: ${HAVE_JPEG12}]) LOC_MSG([ ISO JBIG support: ${HAVE_JBIG}]) LOC_MSG([ LZMA2 support: ${HAVE_LZMA}]) +LOC_MSG([ ZSTD support: ${HAVE_ZSTD}]) +LOC_MSG([ WEBP support: ${HAVE_WEBP}]) LOC_MSG() LOC_MSG([ C++ support: ${HAVE_CXX}]) LOC_MSG() diff --git a/contrib/addtiffo/tif_overview.c b/contrib/addtiffo/tif_overview.c index c61ffbb8..03b35733 100644 --- a/contrib/addtiffo/tif_overview.c +++ b/contrib/addtiffo/tif_overview.c @@ -65,6 +65,8 @@ # define MAX(a,b) ((a>b) ? a : b) #endif +#define TIFF_DIR_MAX 65534 + void TIFFBuildOverviews( TIFF *, int, int *, int, const char *, int (*)(double,void*), void * ); @@ -91,6 +93,7 @@ uint32 TIFF_WriteOverview( TIFF *hTIFF, uint32 nXSize, uint32 nYSize, { toff_t nBaseDirOffset; toff_t nOffset; + tdir_t iNumDir; (void) bUseSubIFDs; @@ -147,7 +150,16 @@ uint32 TIFF_WriteOverview( TIFF *hTIFF, uint32 nXSize, uint32 nYSize, return 0; TIFFWriteDirectory( hTIFF ); - TIFFSetDirectory( hTIFF, (tdir_t) (TIFFNumberOfDirectories(hTIFF)-1) ); + iNumDir = TIFFNumberOfDirectories(hTIFF); + if( iNumDir > TIFF_DIR_MAX ) + { + TIFFErrorExt( TIFFClientdata(hTIFF), + "TIFF_WriteOverview", + "File `%s' has too many directories.\n", + TIFFFileName(hTIFF) ); + exit(-1); + } + TIFFSetDirectory( hTIFF, (tdir_t) (iNumDir - 1) ); nOffset = TIFFCurrentDirOffset( hTIFF ); diff --git a/contrib/iptcutil/iptcutil.c b/contrib/iptcutil/iptcutil.c index b5b774ff..621716df 100644 --- a/contrib/iptcutil/iptcutil.c +++ b/contrib/iptcutil/iptcutil.c @@ -782,7 +782,7 @@ int sindex(char ch,char *string) char *cp; for(cp=string;*cp;++cp) if(ch==*cp) - return (int)(cp-string); /* return postion of character */ + return (int)(cp-string); /* return position of character */ return -1; /* eol ... no match found */ } @@ -926,6 +926,7 @@ int tokenizer(unsigned inflag,char *token,int tokmax,char *line, { case IN_WHITE: _p_state=IN_TOKEN; /* switch states */ + /* Fall through */ case IN_TOKEN: /* these 2 are */ case IN_QUOTE: /* identical here */ diff --git a/contrib/oss-fuzz/build.sh b/contrib/oss-fuzz/build.sh new file mode 100755 index 00000000..c3ac121f --- /dev/null +++ b/contrib/oss-fuzz/build.sh @@ -0,0 +1,52 @@ +#!/bin/bash -eu +# Copyright (c) 1988-1997 Sam Leffler +# Copyright (c) 1991-1997 Silicon Graphics, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Sam Leffler and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. + +# build zlib +pushd "$SRC/zlib" +./configure --static --prefix="$WORK" +make -j$(nproc) CFLAGS="$CFLAGS -fPIC" +make install +popd + +# Build libjpeg-turbo +pushd "$SRC/libjpeg-turbo" +cmake . -DCMAKE_INSTALL_PREFIX=$WORK -DENABLE_STATIC=on -DENABLE_SHARED=off +make -j$(nproc) +make install +popd + +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 + +mkdir afl_testcases +(cd afl_testcases; tar xf "$SRC/afl_testcases.tgz") +mkdir tif +find afl_testcases -type f -name '*.tif' -exec mv -n {} tif/ \; +zip -rj tif.zip tif/ +cp tif.zip "$OUT/tiff_read_rgba_fuzzer_seed_corpus.zip" +cp "$SRC/tiff.dict" "$OUT/tiff_read_rgba_fuzzer.dict" diff --git a/contrib/oss-fuzz/tiff_read_rgba_fuzzer.cc b/contrib/oss-fuzz/tiff_read_rgba_fuzzer.cc new file mode 100644 index 00000000..b1b189f8 --- /dev/null +++ b/contrib/oss-fuzz/tiff_read_rgba_fuzzer.cc @@ -0,0 +1,88 @@ +/* Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + + +/* stolen from tiffiop.h, which is a private header so we can't just include it */ +/* safe multiply returns either the multiplied value or 0 if it overflowed */ +#define __TIFFSafeMultiply(t,v,m) ((((t)(m) != (t)0) && (((t)(((v)*(m))/(m))) == (t)(v))) ? (t)((v)*(m)) : (t)0) + +const uint64 MAX_SIZE = 500000000; + +extern "C" void handle_error(const char *unused, const char *unused2, va_list unused3) { + return; +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + TIFFSetErrorHandler(handle_error); + TIFFSetWarningHandler(handle_error); + std::istringstream s(std::string(Data,Data+Size)); + TIFF* tif = TIFFStreamOpen("MemTIFF", &s); + if (!tif) { + return 0; + } + uint32 w, h; + uint32* raster; + + TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); + /* don't continue if file size is ludicrous */ + if (TIFFTileSize64(tif) > MAX_SIZE) { + TIFFClose(tif); + return 0; + } + uint64 bufsize = TIFFTileSize64(tif); + /* don't continue if the buffer size greater than the max allowed by the fuzzer */ + if (bufsize > MAX_SIZE || bufsize == 0) { + TIFFClose(tif); + return 0; + } + /* another hack to work around an OOM in tif_fax3.c */ + uint32 tilewidth = 0; + uint32 imagewidth = 0; + TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tilewidth); + TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imagewidth); + tilewidth = __TIFFSafeMultiply(uint32, tilewidth, 2); + imagewidth = __TIFFSafeMultiply(uint32, imagewidth, 2); + if (tilewidth * 2 > MAX_SIZE || imagewidth * 2 > MAX_SIZE || tilewidth == 0 || imagewidth == 0) { + TIFFClose(tif); + return 0; + } + uint32 size = __TIFFSafeMultiply(uint32, w, h); + if (size > MAX_SIZE || size == 0) { + TIFFClose(tif); + return 0; + } + raster = (uint32*) _TIFFmalloc(size * sizeof (uint32)); + if (raster != NULL) { + TIFFReadRGBAImage(tif, w, h, raster, 0); + _TIFFfree(raster); + } + TIFFClose(tif); + + return 0; +} diff --git a/contrib/pds/README b/contrib/pds/README index b9abc6b3..a36b0549 100644 --- a/contrib/pds/README +++ b/contrib/pds/README @@ -30,7 +30,7 @@ Your ReadRGBA() routine works well for reading many different formats (TILED, STIP, compressed or not, etc.) of the most basic types of data (RGB, 8-bit greyscale, 8-bit colormapped) into an SGI-style data array, and serves as a good template for users with other needs. I used it as -an exmaple of how to make an iterator which, rather than fill a data +an example of how to make an iterator which, rather than fill a data array, calls an arbitrary user-supplied callback function for each "chunk" of data - that "chunk" might be a strip or a tile, and might have one sample-per-pixel or two, and might be 8-bit data or 16-bit or diff --git a/contrib/pds/tif_imageiter.c b/contrib/pds/tif_imageiter.c index 9e7bd44a..243cfd65 100644 --- a/contrib/pds/tif_imageiter.c +++ b/contrib/pds/tif_imageiter.c @@ -114,7 +114,7 @@ TIFFImageIterBegin(TIFFImageIter* img, TIFF* tif, int stop, char emsg[1024]) TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Missing required \"Colormap\" tag"); return (0); } - /* fall thru... */ + /* fall through... */ case PHOTOMETRIC_MINISWHITE: case PHOTOMETRIC_MINISBLACK: /* This should work now so skip the check - BSR @@ -181,7 +181,7 @@ TIFFImageIterBegin(TIFFImageIter* img, TIFF* tif, int stop, char emsg[1024]) case ORIENTATION_LEFTBOT: /* XXX */ TIFFWarning(TIFFFileName(tif), "using bottom-left orientation"); img->orientation = ORIENTATION_BOTLEFT; - /* fall thru... */ + /* fall through... */ case ORIENTATION_BOTLEFT: break; case ORIENTATION_TOPRIGHT: @@ -190,7 +190,7 @@ TIFFImageIterBegin(TIFFImageIter* img, TIFF* tif, int stop, char emsg[1024]) default: TIFFWarning(TIFFFileName(tif), "using top-left orientation"); img->orientation = ORIENTATION_TOPLEFT; - /* fall thru... */ + /* fall through... */ case ORIENTATION_TOPLEFT: break; } diff --git a/contrib/pds/tif_imageiter.h b/contrib/pds/tif_imageiter.h index e7dbe46c..4f4fd279 100644 --- a/contrib/pds/tif_imageiter.h +++ b/contrib/pds/tif_imageiter.h @@ -44,7 +44,7 @@ struct _TIFFImageIter { uint16 samplesperpixel; /* image samples/pixel */ uint16 orientation; /* image orientation */ uint16 photometric; /* image photometric interp */ - uint16* redcmap; /* colormap pallete */ + uint16* redcmap; /* colormap palette */ uint16* greencmap; uint16* bluecmap; /* get image data routine */ diff --git a/contrib/pds/tif_pdsdirread.c b/contrib/pds/tif_pdsdirread.c index 567600c5..cc6231da 100644 --- a/contrib/pds/tif_pdsdirread.c +++ b/contrib/pds/tif_pdsdirread.c @@ -192,7 +192,7 @@ TIFFReadPrivateDataSubDirectory(TIFF* tif, toff_t pdir_offset, * the fields to check type and tag information, * and to extract info required to size data * structures. A second pass is made afterwards - * to read in everthing not taken in the first pass. + * to read in everything not taken in the first pass. */ td = &tif->tif_dir; @@ -825,7 +825,7 @@ TIFFFetchNormalSubTag(TIFF* tif, TIFFDirEntry* dp, const TIFFFieldInfo* fip, break; } } - /* fall thru... */ + /* fall through... */ case TIFF_LONG: case TIFF_SLONG: { uint32 v32 = diff --git a/contrib/tags/README b/contrib/tags/README index 73c6c213..3220b7b1 100644 --- a/contrib/tags/README +++ b/contrib/tags/README @@ -2,7 +2,7 @@ NOTE: Sept/2004 The following described approach to managing tag extensions has been -mostly superceeded since libtiff 3.6.0. The described approach requires +mostly superseded since libtiff 3.6.0. The described approach requires internal knowledge of the libtiff API and tends to be very fragile in the face of libtiff upgrades. diff --git a/contrib/tags/xtif_dir.c b/contrib/tags/xtif_dir.c index e67a6abf..35295526 100644 --- a/contrib/tags/xtif_dir.c +++ b/contrib/tags/xtif_dir.c @@ -269,7 +269,7 @@ _XTIFFDefaultDirectory(TIFF *tif) * Install into TIFF structure. */ TIFFMEMBER(tif,clientdir) = (tidata_t)xt; - tif->tif_flags |= XTIFF_INITIALIZED; /* dont do this again! */ + tif->tif_flags |= XTIFF_INITIALIZED; /* don't do this again! */ } /* set up our own defaults */ diff --git a/contrib/win_dib/README.tiff2dib b/contrib/win_dib/README.tiff2dib index 3e6075fb..ff70ca1a 100644 --- a/contrib/win_dib/README.tiff2dib +++ b/contrib/win_dib/README.tiff2dib @@ -40,7 +40,7 @@ it contain the function LoadTIFFinDIB that load a TIFF file and build a memory DIB with it and return the HANDLE (HDIB) of the memory bloc containing this DIB. Since DIB is the "natural" bitmap format for Windows 3.1, 95 and NT, -this function sould be usefull for some Windows 95 (or NT) developer. +this function should be useful for some Windows 95 (or NT) developer. Sorry for my approximate english ... diff --git a/contrib/win_dib/Tiffile.cpp b/contrib/win_dib/Tiffile.cpp index 9d958b1c..2f7965d6 100644 --- a/contrib/win_dib/Tiffile.cpp +++ b/contrib/win_dib/Tiffile.cpp @@ -360,7 +360,7 @@ setorientation(TIFFRGBAImage* img, uint32 h) case ORIENTATION_LEFTBOT: /* XXX */ TIFFWarning(TIFFFileName(tif), "using bottom-left orientation"); img->orientation = ORIENTATION_BOTLEFT; - /* fall thru... */ + /* fall through... */ case ORIENTATION_BOTLEFT: y = 0; break; @@ -370,7 +370,7 @@ setorientation(TIFFRGBAImage* img, uint32 h) default: TIFFWarning(TIFFFileName(tif), "using top-left orientation"); img->orientation = ORIENTATION_TOPLEFT; - /* fall thru... */ + /* fall through... */ case ORIENTATION_TOPLEFT: y = h-1; break; diff --git a/html/Makefile.am b/html/Makefile.am index 12193df7..c3ef8456 100644 --- a/html/Makefile.am +++ b/html/Makefile.am @@ -86,7 +86,8 @@ docfiles = \ v4.0.6.html \ v4.0.7.html \ v4.0.8.html \ - v4.0.9.html + v4.0.9.html \ + v4.0.10.html dist_doc_DATA = $(docfiles) diff --git a/html/addingtags.html b/html/addingtags.html index 4e89205b..c61a2623 100644 --- a/html/addingtags.html +++ b/html/addingtags.html @@ -12,7 +12,7 @@ Defining New TIFF Tags Libtiff has built-in knowledge of all the standard TIFF tags, as -well as extentions. The following describes how to add knowledge of +well as extensions. The following describes how to add knowledge of new tags as builtins to libtiff, or how to application specific tags can be used by applications without modifying libtiff.

@@ -113,7 +113,7 @@ their own tags to store information outside the core TIFF specification. This is done by calling TIFFMergeFieldInfo() with one or more TIFFFieldInfos.

-The libgeotiff library provides geospatial information extentions within +The libgeotiff library provides geospatial information extensions within a TIFF file. First, a set of TIFFFieldInfo's is prepared with information on the new tags:

diff --git a/html/bugs.html b/html/bugs.html index 07fc78b8..643c3c6e 100644 --- a/html/bugs.html +++ b/html/bugs.html @@ -22,7 +22,7 @@ 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 http://bugzilla.maptools.org/buglist.cgi?product=libtiff. Also verify that -the problem is still reproducable with the current development software +the problem is still reproducible with the current development software from CVS.

If you'd like to enter a new bug, you can do so at diff --git a/html/build.html b/html/build.html index f52b0966..77fbc40b 100644 --- a/html/build.html +++ b/html/build.html @@ -689,7 +689,7 @@ libtiff/uvcode.h LogL/LogLuv codec-specific definitions libtiff/version.h version string (generated by Makefile) libtiff/tif_apple.c Apple-related OS support libtiff/tif_atari.c Atari-related OS support -libtiff/tif_aux.c auxilary directory-related functions +libtiff/tif_aux.c auxiliary directory-related functions libtiff/tif_close.c close an open TIFF file libtiff/tif_codec.c configuration table of builtin codecs libtiff/tif_compress.c compression scheme support diff --git a/html/index.html b/html/index.html index a670d4ee..aadadae8 100644 --- a/html/index.html +++ b/html/index.html @@ -24,7 +24,7 @@ Latest Stable Release - v4.0.9 + v4.0.10 Master Download Site diff --git a/html/libtiff.html b/html/libtiff.html index b1de7a27..9da85e3d 100644 --- a/html/libtiff.html +++ b/html/libtiff.html @@ -97,7 +97,7 @@ information. The library include file <tiffio.h> contains a C pre-processor define TIFFLIB_VERSION that can be used to check library - version compatiblity at compile time. + version compatibility at compile time.


Library Datatypes

diff --git a/html/man/TIFFReadDirectory.3tiff.html b/html/man/TIFFReadDirectory.3tiff.html index 1e32f7cd..5e4004db 100644 --- a/html/man/TIFFReadDirectory.3tiff.html +++ b/html/man/TIFFReadDirectory.3tiff.html @@ -151,23 +151,23 @@ specification. This error is not fatal.

unknown tag was encountered in the directory; the library ignores all such tags.

-

TIFF directory is missing requred +

TIFF directory is missing required "ImageLength" field. The image violates the specification by not having a necessary field. There is no way for the library to recover from this error.

-

TIFF directory is missing requred +

TIFF directory is missing required "PlanarConfig" field. The image violates the specification by not having a necessary field. There is no way for the library to recover from this error.

-

TIFF directory is missing requred +

TIFF directory is missing required "StripOffsets" field. The image has multiple strips, but is missing the tag that specifies the file offset to each strip of data. There is no way for the library to recover from this error.

-

TIFF directory is missing requred +

TIFF directory is missing required "TileOffsets" field. The image has multiple tiles, but is missing the tag that specifies the file offset to each tile of data. There is no way for the library to diff --git a/html/man/TIFFWriteDirectory.3tiff.html b/html/man/TIFFWriteDirectory.3tiff.html index 9aff8c4c..6483aa6a 100644 --- a/html/man/TIFFWriteDirectory.3tiff.html +++ b/html/man/TIFFWriteDirectory.3tiff.html @@ -69,7 +69,7 @@ have an established location in the file. It will rewrite the directory, but instead of place it at it’s old location (as TIFFWriteDirectory would) it will place them at the end of the file, correcting the pointer from the -preceeding directory or file header to point to it’s +preceding directory or file header to point to it’s new location. This is particularly important in cases where the size of the directory and pointed to data has grown, so it won’t fit in the space available at the old diff --git a/html/man/TIFFmemory.3tiff.html b/html/man/TIFFmemory.3tiff.html index 39fa7894..283be9bd 100644 --- a/html/man/TIFFmemory.3tiff.html +++ b/html/man/TIFFmemory.3tiff.html @@ -76,7 +76,7 @@ another memory location using _TIFFmemcpy, or compared for equality using _TIFFmemcmp. These routines conform to the equivalent ANSI C routines: memset, memcpy, and memcmp, -repsectively.

+respectively.

diff --git a/html/v3.5.3.html b/html/v3.5.3.html index 78f46983..67da683e 100644 --- a/html/v3.5.3.html +++ b/html/v3.5.3.html @@ -49,7 +49,7 @@ From Burn All GIF's Day: Unisys license to use LZW in free software that complies with the Open Source Definition

-Unfortunatly, the removal of LZW compression means that saved image size has +Unfortunately, the removal of LZW compression means that saved image size has grown dramatically. Without a change in the TIFF spec to support another lossless compression format, this is unavoidable.

diff --git a/html/v3.5.7.html b/html/v3.5.7.html index 96f47916..d4285a8b 100644 --- a/html/v3.5.7.html +++ b/html/v3.5.7.html @@ -200,7 +200,7 @@ that corrects behaviour for non-Letter paper sizes. (Bug 35) It fixes two problems:
Without scaling (-S) the fax is now centered on the page size specified - with -H and/or -W. Before, fax2ps was using an obscure and practially + with -H and/or -W. Before, fax2ps was using an obscure and practically useless algorithm to allocate the image relative to Letter sized paper which sometime sled to useless whitespace on the paper, while at the same time cutting of the faxes printable area at the opposite border. diff --git a/html/v3.6.0.html b/html/v3.6.0.html index c53cd155..affbe09a 100644 --- a/html/v3.6.0.html +++ b/html/v3.6.0.html @@ -64,12 +64,12 @@ TIFFDirectory structure would changing, breaking any dynamically linked software that used the private data structures.

Also, any tag not recognised -by libtiff would not be read and accessable to applications without some +by libtiff would not be read and accessible to applications without some fairly complicated work on the applications part to pre-register the tags as exemplified by the support for "Geo"TIFF tags by libgeotiff layered on libtiff.

-Amoung other things this approach required the extension code +Among other things this approach required the extension code to access the private libtiff structures ... which made the higher level non-libtiff code be locked into a specific version of libtiff at compile time. This caused no end of bug reports!

diff --git a/html/v3.6.1.html b/html/v3.6.1.html index 3d6d838d..3e4e3fbc 100644 --- a/html/v3.6.1.html +++ b/html/v3.6.1.html @@ -116,7 +116,7 @@ Patch supplied by Ross Finlayson. it was done in 3.6.0).

  • libtiff/{tiff.h, tif_dirinfo.c}: Added support for IFD (13) datatype, -intruduced in "Adobe PageMaker TIFF Technical Notes". +introduced in "Adobe PageMaker TIFF Technical Notes".
  • libtiff/{tif_color.c, tif_getimage.c, tiffio.h}: New color space conversion code: CIE L*a*b* 1976 images now supported by the TIFFRGBAImage diff --git a/html/v3.7.2.html b/html/v3.7.2.html index 45347b72..1fa4cc8e 100644 --- a/html/v3.7.2.html +++ b/html/v3.7.2.html @@ -46,7 +46,7 @@ The following information is located here:
      -
    • Maintainance release. Many bugfixes in the build environment +
    • Maintenance release. Many bugfixes in the build environment and compatibility improvements.
    diff --git a/html/v3.7.3.html b/html/v3.7.3.html index 28981aef..771e1906 100644 --- a/html/v3.7.3.html +++ b/html/v3.7.3.html @@ -45,7 +45,7 @@ The following information is located here: MAJOR CHANGES:
      -
    • Replace runtime endianess check with the compile time one. +
    • Replace runtime endianness check with the compile time one.
    • Added support for the new predictor type (floating point predictor), defined at the TIFF Technical Note 3. diff --git a/html/v3.9.0.html b/html/v3.9.0.html index 1c8bf969..0e9ff9ae 100644 --- a/html/v3.9.0.html +++ b/html/v3.9.0.html @@ -154,7 +154,7 @@ information is located here:
    • libtiff/tif_getimage.c,tiffio.h: removed all use of UaToAa and Bitmap16to8 arrays in TIFFRGBAImage structure to - restore ABI compatability. These were just an attempt to + restore ABI compatibility. These were just an attempt to speed up processing with precalculated tables. http://bugzilla.maptools.org/show_bug.cgi?id=1979 diff --git a/html/v4.0.10.html b/html/v4.0.10.html new file mode 100644 index 00000000..f1b6b008 --- /dev/null +++ b/html/v4.0.10.html @@ -0,0 +1,326 @@ + + + + Changes in TIFF v4.0.10 + + + + + + + + +TIFF CHANGE INFORMATION + + + + +

      +This document describes the changes made to the software between the +previous and current 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: +

      +

      +


      + + + +MAJOR CHANGES: + +
        + +
      • The libtiff source repository is changed from CVS to Git and the master libtiff source repository is now at Gitlab. This is the first release to be made from the new Git repository.
      • + +
      + + +


      + + +CHANGES IN THE SOFTWARE CONFIGURATION: + +
        + +
      • Minimum CMake version is now v2.8.11 for the CMake-based build.
      • + +
      • Libwebp will be automatically detected and used by configure/cmake if present. + +
      • Libzstd will be automatically detected and used by configure/cmake if present. + + +
      + +


      + + + +CHANGES IN LIBTIFF: + + + +


      + + + +CHANGES IN THE TOOLS: + + + +


      + + + +CHANGES IN THE CONTRIB AREA: + +
        + +
      • None
      • + +
      + + + diff --git a/libtiff/CMakeLists.txt b/libtiff/CMakeLists.txt index 087dfa9e..1cf1b759 100644 --- a/libtiff/CMakeLists.txt +++ b/libtiff/CMakeLists.txt @@ -93,8 +93,10 @@ set(tiff_SOURCES tif_tile.c tif_version.c tif_warning.c + tif_webp.c tif_write.c - tif_zip.c) + tif_zip.c + tif_zstd.c) set(tiffxx_HEADERS tiffio.hxx) @@ -110,12 +112,14 @@ else() list(APPEND tiff_SOURCES tif_unix.c) endif() -include_directories(${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_BINARY_DIR} - ${TIFF_INCLUDES}) - add_library(tiff ${tiff_SOURCES} ${tiff_HEADERS} ${nodist_tiff_HEADERS} ${tiff_port_SOURCES} libtiff.def) +target_include_directories(tiff + PUBLIC + $ + $ + ${TIFF_INCLUDES} +) target_link_libraries(tiff ${TIFF_LIBRARY_DEPS}) set_target_properties(tiff PROPERTIES SOVERSION ${SO_COMPATVERSION}) if(NOT CYGWIN) @@ -138,7 +142,7 @@ install(TARGETS tiff install(FILES ${tiff_HEADERS} ${nodist_tiff_HEADERS} DESTINATION "${CMAKE_INSTALL_FULL_INCLUDEDIR}") -if(cxx) +if(CXX_SUPPORT) add_library(tiffxx ${tiffxx_SOURCES} ${tiffxx_HEADERS}) target_link_libraries(tiffxx tiff) set_target_properties(tiffxx PROPERTIES SOVERSION ${SO_COMPATVERSION}) diff --git a/libtiff/Makefile.am b/libtiff/Makefile.am index 9cbc5b1d..14a250a5 100644 --- a/libtiff/Makefile.am +++ b/libtiff/Makefile.am @@ -98,8 +98,10 @@ libtiff_la_SOURCES = \ tif_tile.c \ tif_version.c \ tif_warning.c \ + tif_webp.c \ tif_write.c \ - tif_zip.c + tif_zip.c \ + tif_zstd.c libtiffxx_la_SOURCES = \ tif_stream.cxx diff --git a/libtiff/tif_codec.c b/libtiff/tif_codec.c index e0aaacff..b6c04f01 100644 --- a/libtiff/tif_codec.c +++ b/libtiff/tif_codec.c @@ -70,6 +70,12 @@ static int NotConfigured(TIFF*, int); #ifndef LZMA_SUPPORT #define TIFFInitLZMA NotConfigured #endif +#ifndef ZSTD_SUPPORT +#define TIFFInitZSTD NotConfigured +#endif +#ifndef WEBP_SUPPORT +#define TIFFInitWebP NotConfigured +#endif /* * Compression schemes statically built into the library. @@ -97,6 +103,8 @@ TIFFCodec _TIFFBuiltinCODECS[] = { { "SGILog", COMPRESSION_SGILOG, TIFFInitSGILog }, { "SGILog24", COMPRESSION_SGILOG24, TIFFInitSGILog }, { "LZMA", COMPRESSION_LZMA, TIFFInitLZMA }, + { "ZSTD", COMPRESSION_ZSTD, TIFFInitZSTD }, + { "WEBP", COMPRESSION_WEBP, TIFFInitWebP }, { NULL, 0, NULL } }; diff --git a/libtiff/tif_color.c b/libtiff/tif_color.c index 40ca36f6..8fae40ea 100644 --- a/libtiff/tif_color.c +++ b/libtiff/tif_color.c @@ -166,7 +166,7 @@ TIFFCIELabToRGBInit(TIFFCIELabToRGB* cielab, } /* - * Convert color value from the YCbCr space to CIE XYZ. + * Convert color value from the YCbCr space to RGB. * The colorspace conversion algorithm comes from the IJG v5a code; * see below for more information on how it works. */ diff --git a/libtiff/tif_config.h.cmake.in b/libtiff/tif_config.h.cmake.in index de0f3a3c..24144603 100644 --- a/libtiff/tif_config.h.cmake.in +++ b/libtiff/tif_config.h.cmake.in @@ -26,9 +26,6 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_FCNTL_H 1 -/* Define to 1 if you have the `floor' function. */ -#cmakedefine HAVE_FLOOR 1 - /* Define to 1 if you have the `getopt' function. */ #cmakedefine HAVE_GETOPT 1 @@ -50,30 +47,12 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_IO_H 1 -/* Define to 1 if you have the `isascii' function. */ -#cmakedefine HAVE_ISASCII 1 - /* Define to 1 if you have the `jbg_newlen' function. */ #cmakedefine HAVE_JBG_NEWLEN 1 /* Define to 1 if you have the `lfind' function. */ #cmakedefine HAVE_LFIND 1 -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LIMITS_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_MALLOC_H 1 - -/* Define to 1 if you have the `memmove' function. */ -#cmakedefine HAVE_MEMMOVE 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_MEMORY_H 1 - -/* Define to 1 if you have the `memset' function. */ -#cmakedefine HAVE_MEMSET 1 - /* Define to 1 if you have the `mmap' function. */ #cmakedefine HAVE_MMAP 1 @@ -83,9 +62,6 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_OPENGL_GL_H 1 -/* Define to 1 if you have the `pow' function. */ -#cmakedefine HAVE_POW 1 - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SEARCH_H 1 @@ -95,33 +71,24 @@ /* Define to 1 if you have the `snprintf' function. */ #cmakedefine HAVE_SNPRINTF 1 -/* Define to 1 if you have the `sqrt' function. */ -#cmakedefine HAVE_SQRT 1 - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STDINT_H 1 /* Define to 1 if you have the `strcasecmp' function. */ #cmakedefine HAVE_STRCASECMP 1 -/* Define to 1 if you have the `strchr' function. */ -#cmakedefine HAVE_STRCHR 1 - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STRING_H 1 -/* Define to 1 if you have the `strrchr' function. */ -#cmakedefine HAVE_STRRCHR 1 - -/* Define to 1 if you have the `strstr' function. */ -#cmakedefine HAVE_STRSTR 1 - /* Define to 1 if you have the `strtol' function. */ #cmakedefine HAVE_STRTOL 1 +/* Define to 1 if you have the `strtoll' function. */ +#cmakedefine HAVE_STRTOLL 1 + /* Define to 1 if you have the `strtoul' function. */ #cmakedefine HAVE_STRTOUL 1 @@ -146,6 +113,12 @@ /* Support LZMA2 compression */ #cmakedefine LZMA_SUPPORT 1 +/* Support ZSTD compression */ +#cmakedefine ZSTD_SUPPORT 1 + +/* Support WEBP compression */ +#cmakedefine WEBP_SUPPORT 1 + /* Name of package */ #define PACKAGE "@PACKAGE_NAME@" @@ -176,9 +149,6 @@ /* The size of `signed long long', as computed by sizeof. */ #define SIZEOF_SIGNED_LONG_LONG @SIZEOF_SIGNED_LONG_LONG@ -/* The size of `signed short', as computed by sizeof. */ -#define SIZEOF_SIGNED_SHORT @SIZEOF_SIGNED_SHORT@ - /* The size of `unsigned char *', as computed by sizeof. */ #define SIZEOF_UNSIGNED_CHAR_P @SIZEOF_UNSIGNED_CHAR_P@ diff --git a/libtiff/tif_dir.h b/libtiff/tif_dir.h index bb508add..b2f5e694 100644 --- a/libtiff/tif_dir.h +++ b/libtiff/tif_dir.h @@ -24,6 +24,10 @@ #ifndef _TIFFDIR_ #define _TIFFDIR_ + +#include "tiff.h" +#include "tiffio.h" + /* * ``Library-private'' Directory-related Definitions. */ diff --git a/libtiff/tif_dirinfo.c b/libtiff/tif_dirinfo.c index d26fd120..e1f6b23e 100644 --- a/libtiff/tif_dirinfo.c +++ b/libtiff/tif_dirinfo.c @@ -977,6 +977,8 @@ _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag) case TIFFTAG_CONSECUTIVEBADFAXLINES: case TIFFTAG_GROUP3OPTIONS: case TIFFTAG_GROUP4OPTIONS: + /* LERC */ + case TIFFTAG_LERC_PARAMETERS: break; default: return 1; @@ -1052,7 +1054,18 @@ _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag) if (tag == TIFFTAG_PREDICTOR) return 1; break; - + case COMPRESSION_ZSTD: + if (tag == TIFFTAG_PREDICTOR) + return 1; + break; + case COMPRESSION_LERC: + if (tag == TIFFTAG_LERC_PARAMETERS) + return 1; + break; + case COMPRESSION_WEBP: + if (tag == TIFFTAG_PREDICTOR) + return 1; + break; } return 0; } diff --git a/libtiff/tif_dirread.c b/libtiff/tif_dirread.c index 14920ea3..50881ff9 100644 --- a/libtiff/tif_dirread.c +++ b/libtiff/tif_dirread.c @@ -165,6 +165,7 @@ static int TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uin static int TIFFFetchSubjectDistance(TIFF*, TIFFDirEntry*); static void ChopUpSingleUncompressedStrip(TIFF*); static uint64 TIFFReadUInt64(const uint8 *value); +static int _TIFFGetMaxColorChannels(uint16 photometric); static int _TIFFFillStrilesInternal( TIFF *tif, int loadStripByteCount ); @@ -3504,6 +3505,35 @@ static void TIFFReadDirEntryOutputErr(TIFF* tif, enum TIFFReadDirEntryErr err, c } } +/* + * Return the maximum number of color channels specified for a given photometric + * type. 0 is returned if photometric type isn't supported or no default value + * is defined by the specification. + */ +static int _TIFFGetMaxColorChannels( uint16 photometric ) +{ + switch (photometric) { + case PHOTOMETRIC_PALETTE: + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + return 1; + case PHOTOMETRIC_YCBCR: + case PHOTOMETRIC_RGB: + case PHOTOMETRIC_CIELAB: + case PHOTOMETRIC_LOGLUV: + case PHOTOMETRIC_ITULAB: + case PHOTOMETRIC_ICCLAB: + return 3; + case PHOTOMETRIC_SEPARATED: + case PHOTOMETRIC_MASK: + return 4; + case PHOTOMETRIC_LOGL: + case PHOTOMETRIC_CFA: + default: + return 0; + } +} + /* * Read the next TIFF directory from a file and convert it to the internal * format. We read directories sequentially. @@ -3520,6 +3550,7 @@ TIFFReadDirectory(TIFF* tif) uint32 fii=FAILED_FII; toff_t nextdiroff; int bitspersample_read = FALSE; + int color_channels; tif->tif_diroff=tif->tif_nextdiroff; if (!TIFFCheckDirOffset(tif,tif->tif_nextdiroff)) @@ -4024,6 +4055,37 @@ TIFFReadDirectory(TIFF* tif) } } } + + /* + * Make sure all non-color channels are extrasamples. + * If it's not the case, define them as such. + */ + color_channels = _TIFFGetMaxColorChannels(tif->tif_dir.td_photometric); + if (color_channels && tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples > color_channels) { + uint16 old_extrasamples; + uint16 *new_sampleinfo; + + TIFFWarningExt(tif->tif_clientdata,module, "Sum of Photometric type-related " + "color channels and ExtraSamples doesn't match SamplesPerPixel. " + "Defining non-color channels as ExtraSamples."); + + old_extrasamples = tif->tif_dir.td_extrasamples; + tif->tif_dir.td_extrasamples = (uint16) (tif->tif_dir.td_samplesperpixel - color_channels); + + // sampleinfo should contain information relative to these new extra samples + new_sampleinfo = (uint16*) _TIFFcalloc(tif->tif_dir.td_extrasamples, sizeof(uint16)); + if (!new_sampleinfo) { + TIFFErrorExt(tif->tif_clientdata, module, "Failed to allocate memory for " + "temporary new sampleinfo array (%d 16 bit elements)", + tif->tif_dir.td_extrasamples); + goto bad; + } + + memcpy(new_sampleinfo, tif->tif_dir.td_sampleinfo, old_extrasamples * sizeof(uint16)); + _TIFFsetShortArray(&tif->tif_dir.td_sampleinfo, new_sampleinfo, tif->tif_dir.td_extrasamples); + _TIFFfree(new_sampleinfo); + } + /* * Verify Palette image has a Colormap. */ @@ -4879,17 +4941,18 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) err=TIFFReadDirEntryByteArray(tif,dp,&data); if (err==TIFFReadDirEntryErrOk) { - uint8* ma; - uint32 mb; + uint32 mb = 0; int n; - ma=data; - mb=0; - while (mb<(uint32)dp->tdir_count) + if (data != NULL) { - if (*ma==0) - break; - ma++; - mb++; + uint8* ma = data; + while (mb<(uint32)dp->tdir_count) + { + if (*ma==0) + break; + ma++; + mb++; + } } if (mb+1<(uint32)dp->tdir_count) TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" contains null byte in value; value incorrectly truncated during reading due to implementation limitations",fip->field_name); @@ -5139,11 +5202,11 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) if (err==TIFFReadDirEntryErrOk) { int m; - if( dp->tdir_count > 0 && data[dp->tdir_count-1] != '\0' ) - { - TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte. Forcing it to be null",fip->field_name); - data[dp->tdir_count-1] = '\0'; - } + if( data != 0 && dp->tdir_count > 0 && data[dp->tdir_count-1] != '\0' ) + { + TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte. Forcing it to be null",fip->field_name); + data[dp->tdir_count-1] = '\0'; + } m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); if (data!=0) _TIFFfree(data); @@ -5316,11 +5379,11 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) if (err==TIFFReadDirEntryErrOk) { int m; - if( dp->tdir_count > 0 && data[dp->tdir_count-1] != '\0' ) - { - TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte. Forcing it to be null",fip->field_name); - data[dp->tdir_count-1] = '\0'; - } + if( data != 0 && dp->tdir_count > 0 && data[dp->tdir_count-1] != '\0' ) + { + TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte. Forcing it to be null",fip->field_name); + data[dp->tdir_count-1] = '\0'; + } m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); if (data!=0) _TIFFfree(data); @@ -5696,6 +5759,16 @@ ChopUpSingleUncompressedStrip(TIFF* tif) if( nstrips == 0 ) return; + /* If we are going to allocate a lot of memory, make sure that the */ + /* file is as big as needed */ + if( tif->tif_mode == O_RDONLY && + nstrips > 1000000 && + (offset >= TIFFGetFileSize(tif) || + stripbytes > (TIFFGetFileSize(tif) - offset) / (nstrips - 1)) ) + { + return; + } + newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64), "for chopped \"StripByteCounts\" array"); newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64), diff --git a/libtiff/tif_dirwrite.c b/libtiff/tif_dirwrite.c index 2430de6d..c15a28db 100644 --- a/libtiff/tif_dirwrite.c +++ b/libtiff/tif_dirwrite.c @@ -695,8 +695,11 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff) } break; default: - assert(0); /* we should never get here */ - break; + TIFFErrorExt(tif->tif_clientdata,module, + "Cannot write tag %d (%s)", + TIFFFieldTag(o), + o->field_name ? o->field_name : "unknown"); + goto bad; } } } diff --git a/libtiff/tif_jbig.c b/libtiff/tif_jbig.c index 0befdf32..7ffe8851 100644 --- a/libtiff/tif_jbig.c +++ b/libtiff/tif_jbig.c @@ -51,17 +51,18 @@ static int JBIGDecode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s) struct jbg_dec_state decoder; int decodeStatus = 0; unsigned char* pImage = NULL; - (void) size, (void) s; + unsigned long decodedSize; + (void) s; if (isFillOrder(tif, tif->tif_dir.td_fillorder)) { - TIFFReverseBits(tif->tif_rawdata, tif->tif_rawdatasize); + TIFFReverseBits(tif->tif_rawcp, tif->tif_rawcc); } jbg_dec_init(&decoder); #if defined(HAVE_JBG_NEWLEN) - jbg_newlen(tif->tif_rawdata, (size_t)tif->tif_rawdatasize); + jbg_newlen(tif->tif_rawcp, (size_t)tif->tif_rawcc); /* * I do not check the return status of jbg_newlen because even if this * function fails it does not necessarily mean that decoding the image @@ -74,8 +75,8 @@ static int JBIGDecode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s) */ #endif /* HAVE_JBG_NEWLEN */ - decodeStatus = jbg_dec_in(&decoder, (unsigned char*)tif->tif_rawdata, - (size_t)tif->tif_rawdatasize, NULL); + decodeStatus = jbg_dec_in(&decoder, (unsigned char*)tif->tif_rawcp, + (size_t)tif->tif_rawcc, NULL); if (JBG_EOK != decodeStatus) { /* @@ -96,9 +97,28 @@ static int JBIGDecode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s) return 0; } + decodedSize = jbg_dec_getsize(&decoder); + if( (tmsize_t)decodedSize < size ) + { + TIFFWarningExt(tif->tif_clientdata, "JBIG", + "Only decoded %lu bytes, whereas %lu requested", + decodedSize, (unsigned long)size); + } + else if( (tmsize_t)decodedSize > size ) + { + TIFFErrorExt(tif->tif_clientdata, "JBIG", + "Decoded %lu bytes, whereas %lu were requested", + decodedSize, (unsigned long)size); + jbg_dec_free(&decoder); + return 0; + } pImage = jbg_dec_getimage(&decoder, 0); - _TIFFmemcpy(buffer, pImage, jbg_dec_getsize(&decoder)); + _TIFFmemcpy(buffer, pImage, decodedSize); jbg_dec_free(&decoder); + + tif->tif_rawcp += tif->tif_rawcc; + tif->tif_rawcc = 0; + return 1; } diff --git a/libtiff/tif_jpeg.c b/libtiff/tif_jpeg.c index 10d4eba5..aae0dde6 100644 --- a/libtiff/tif_jpeg.c +++ b/libtiff/tif_jpeg.c @@ -74,7 +74,7 @@ int TIFFJPEGIsFullStripRequired_12(TIFF* tif); "JPEGLib: JPEG parameter struct mismatch: library thinks size is 432, caller expects 464" - For such users we wil fix the problem here. See install.doc file from + For such users we will fix the problem here. See install.doc file from the JPEG library distribution for details. */ diff --git a/libtiff/tif_luv.c b/libtiff/tif_luv.c index 266bb399..aa35ea07 100644 --- a/libtiff/tif_luv.c +++ b/libtiff/tif_luv.c @@ -213,7 +213,7 @@ LogL16Decode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) bp = (unsigned char*) tif->tif_rawcp; cc = tif->tif_rawcc; /* get each byte string */ - for (shft = 2*8; (shft -= 8) >= 0; ) { + for (shft = 8; shft >= 0; shft -=8) { for (i = 0; i < npixels && cc > 0; ) { if (*bp >= 128) { /* run */ if( cc < 2 ) @@ -347,7 +347,7 @@ LogLuvDecode32(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) bp = (unsigned char*) tif->tif_rawcp; cc = tif->tif_rawcc; /* get each byte string */ - for (shft = 4*8; (shft -= 8) >= 0; ) { + for (shft = 24; shft >= 0; shft -=8) { for (i = 0; i < npixels && cc > 0; ) { if (*bp >= 128) { /* run */ if( cc < 2 ) @@ -465,7 +465,7 @@ LogL16Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) /* compress each byte string */ op = tif->tif_rawcp; occ = tif->tif_rawdatasize - tif->tif_rawcc; - for (shft = 2*8; (shft -= 8) >= 0; ) + for (shft = 8; shft >= 0; shft -=8) { for (i = 0; i < npixels; i += rc) { if (occ < 4) { tif->tif_rawcp = op; @@ -520,6 +520,7 @@ LogL16Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) } else rc = 0; } + } tif->tif_rawcp = op; tif->tif_rawcc = tif->tif_rawdatasize - occ; @@ -616,7 +617,7 @@ LogLuvEncode32(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) /* compress each byte string */ op = tif->tif_rawcp; occ = tif->tif_rawdatasize - tif->tif_rawcc; - for (shft = 4*8; (shft -= 8) >= 0; ) + for (shft = 24; shft >= 0; shft -=8) { for (i = 0; i < npixels; i += rc) { if (occ < 4) { tif->tif_rawcp = op; @@ -671,6 +672,7 @@ LogLuvEncode32(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) } else rc = 0; } + } tif->tif_rawcp = op; tif->tif_rawcc = tif->tif_rawdatasize - occ; diff --git a/libtiff/tif_lzma.c b/libtiff/tif_lzma.c index b395de07..3f6096b6 100644 --- a/libtiff/tif_lzma.c +++ b/libtiff/tif_lzma.c @@ -247,6 +247,7 @@ LZMAPreEncode(TIFF* tif, uint16 s) { static const char module[] = "LZMAPreEncode"; LZMAState *sp = EncoderState(tif); + lzma_ret ret; (void) s; assert(sp != NULL); @@ -260,7 +261,13 @@ LZMAPreEncode(TIFF* tif, uint16 s) "Liblzma cannot deal with buffers this size"); return 0; } - return (lzma_stream_encoder(&sp->stream, sp->filters, sp->check) == LZMA_OK); + ret = lzma_stream_encoder(&sp->stream, sp->filters, sp->check); + if (ret != LZMA_OK) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error in lzma_stream_encoder(): %s", LZMAStrerror(ret)); + return 0; + } + return 1; } /* diff --git a/libtiff/tif_lzw.c b/libtiff/tif_lzw.c index 4ccb443c..ac685dd7 100644 --- a/libtiff/tif_lzw.c +++ b/libtiff/tif_lzw.c @@ -133,6 +133,7 @@ typedef struct { long dec_restart; /* restart count */ #ifdef LZW_CHECKEOS uint64 dec_bitsleft; /* available bits in raw data */ + tmsize_t old_tif_rawcc; /* value of tif_rawcc at the end of the previous TIFLZWDecode() call */ #endif decodeFunc dec_decode; /* regular or backwards compatible */ code_t* dec_codep; /* current recognized code */ @@ -318,6 +319,7 @@ LZWPreDecode(TIFF* tif, uint16 s) sp->dec_nbitsmask = MAXCODE(BITS_MIN); #ifdef LZW_CHECKEOS sp->dec_bitsleft = 0; + sp->old_tif_rawcc = 0; #endif sp->dec_free_entp = sp->dec_codetab + CODE_FIRST; /* @@ -425,7 +427,7 @@ LZWDecode(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) bp = (unsigned char *)tif->tif_rawcp; #ifdef LZW_CHECKEOS - sp->dec_bitsleft = (((uint64)tif->tif_rawcc) << 3); + sp->dec_bitsleft += (((uint64)tif->tif_rawcc - sp->old_tif_rawcc) << 3); #endif nbits = sp->lzw_nbits; nextdata = sp->lzw_nextdata; @@ -553,6 +555,9 @@ LZWDecode(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) tif->tif_rawcc -= (tmsize_t)( (uint8*) bp - tif->tif_rawcp ); tif->tif_rawcp = (uint8*) bp; +#ifdef LZW_CHECKEOS + sp->old_tif_rawcc = tif->tif_rawcc; +#endif sp->lzw_nbits = (unsigned short) nbits; sp->lzw_nextdata = nextdata; sp->lzw_nextbits = nextbits; @@ -602,6 +607,7 @@ LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) char *tp; unsigned char *bp; int code, nbits; + int len; long nextbits, nextdata, nbitsmask; code_t *codep, *free_entp, *maxcodep, *oldcodep; @@ -655,7 +661,7 @@ LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) bp = (unsigned char *)tif->tif_rawcp; #ifdef LZW_CHECKEOS - sp->dec_bitsleft = (((uint64)tif->tif_rawcc) << 3); + sp->dec_bitsleft += (((uint64)tif->tif_rawcc - sp->old_tif_rawcc) << 3); #endif nbits = sp->lzw_nbits; nextdata = sp->lzw_nextdata; @@ -753,13 +759,18 @@ LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) } while (--occ); break; } - assert(occ >= codep->length); - op += codep->length; - occ -= codep->length; - tp = op; + len = codep->length; + tp = op + len; do { - *--tp = codep->value; - } while( (codep = codep->next) != NULL ); + int t; + --tp; + t = codep->value; + codep = codep->next; + *tp = (char)t; + } while (codep && tp > op); + assert(occ >= len); + op += len; + occ -= len; } else { *op++ = (char)code; occ--; @@ -768,6 +779,9 @@ LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) tif->tif_rawcc -= (tmsize_t)( (uint8*) bp - tif->tif_rawcp ); tif->tif_rawcp = (uint8*) bp; +#ifdef LZW_CHECKEOS + sp->old_tif_rawcc = tif->tif_rawcc; +#endif sp->lzw_nbits = (unsigned short)nbits; sp->lzw_nextdata = nextdata; sp->lzw_nextbits = nextbits; diff --git a/libtiff/tif_predict.h b/libtiff/tif_predict.h index ee64d80c..a326b9b8 100644 --- a/libtiff/tif_predict.h +++ b/libtiff/tif_predict.h @@ -24,6 +24,10 @@ #ifndef _TIFFPREDICT_ #define _TIFFPREDICT_ + +#include "tiffio.h" +#include "tiffiop.h" + /* * ``Library-private'' Support for the Predictor Tag */ diff --git a/libtiff/tif_print.c b/libtiff/tif_print.c index 8deceb2b..1d86adbf 100644 --- a/libtiff/tif_print.c +++ b/libtiff/tif_print.c @@ -544,7 +544,7 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags) uint16 i; fprintf(fd, " %2ld: %5u", l, td->td_transferfunction[0][l]); - for (i = 1; i < td->td_samplesperpixel; i++) + for (i = 1; i < td->td_samplesperpixel - td->td_extrasamples && i < 3; i++) fprintf(fd, " %5u", td->td_transferfunction[i][l]); fputc('\n', fd); diff --git a/libtiff/tif_read.c b/libtiff/tif_read.c index d1cfe469..e63810cc 100644 --- a/libtiff/tif_read.c +++ b/libtiff/tif_read.c @@ -346,6 +346,13 @@ TIFFSeek(TIFF* tif, uint32 row, uint16 sample ) return 0; whole_strip = tif->tif_dir.td_stripbytecount[strip] < 10 || isMapped(tif); + if( td->td_compression == COMPRESSION_LERC || + td->td_compression == COMPRESSION_JBIG ) + { + /* Ideally plugins should have a way to declare they don't support + * chunk strip */ + whole_strip = 1; + } #else whole_strip = 1; #endif diff --git a/libtiff/tif_stream.cxx b/libtiff/tif_stream.cxx index 83c6bb05..7f640a9c 100644 --- a/libtiff/tif_stream.cxx +++ b/libtiff/tif_stream.cxx @@ -373,6 +373,9 @@ _tiffStreamOpen(const char* name, const char* mode, void *fd) _tiffosSizeProc, _tiffDummyMapProc, _tiffDummyUnmapProc); + if (!tif) { + delete data; + } } else { tiffis_data *data = new tiffis_data; data->stream = reinterpret_cast(fd); @@ -387,6 +390,9 @@ _tiffStreamOpen(const char* name, const char* mode, void *fd) _tiffisSizeProc, _tiffDummyMapProc, _tiffDummyUnmapProc); + if (!tif) { + delete data; + } } return (tif); diff --git a/libtiff/tif_webp.c b/libtiff/tif_webp.c new file mode 100644 index 00000000..a002f481 --- /dev/null +++ b/libtiff/tif_webp.c @@ -0,0 +1,684 @@ +/* +* Copyright (c) 2018, Mapbox +* Author: +* +* Permission to use, copy, modify, distribute, and sell this software and +* its documentation for any purpose is hereby granted without fee, provided +* that (i) the above copyright notices and this permission notice appear in +* all copies of the software and related documentation, and (ii) the names of +* Sam Leffler and Silicon Graphics may not be used in any advertising or +* publicity relating to the software without the specific, prior written +* permission of Sam Leffler and Silicon Graphics. +* +* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +* +* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +* OF THIS SOFTWARE. +*/ + +#include "tiffiop.h" +#ifdef WEBP_SUPPORT +/* + * TIFF Library. + * + * WEBP Compression Support + * + */ + +#include "webp/decode.h" +#include "webp/encode.h" + +#include + +#define LSTATE_INIT_DECODE 0x01 +#define LSTATE_INIT_ENCODE 0x02 +/* + * State block for each open TIFF + * file using WEBP compression/decompression. + */ +typedef struct { + uint16 nSamples; /* number of samples per pixel */ + + int lossless; /* lossy/lossless compression */ + int quality_level; /* compression level */ + WebPPicture sPicture; /* WebP Picture */ + WebPConfig sEncoderConfig; /* WebP encoder config */ + uint8* pBuffer; /* buffer to hold raw data on encoding */ + unsigned int buffer_offset; /* current offset into the buffer */ + unsigned int buffer_size; + + WebPIDecoder* psDecoder; /* WebPIDecoder */ + WebPDecBuffer sDecBuffer; /* Decoder buffer */ + int last_y; /* Last row decoded */ + + int state; /* state flags */ + + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ +} WebPState; + +#define LState(tif) ((WebPState*) (tif)->tif_data) +#define DecoderState(tif) LState(tif) +#define EncoderState(tif) LState(tif) + +static int TWebPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s); +static int TWebPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s); + +static +int TWebPDatasetWriter(const uint8_t* data, size_t data_size, + const WebPPicture* const picture) +{ + static const char module[] = "TWebPDatasetWriter"; + TIFF* tif = (TIFF*)(picture->custom_ptr); + + if ( (tif->tif_rawcc + (tmsize_t)data_size) > tif->tif_rawdatasize ) { + TIFFErrorExt(tif->tif_clientdata, module, + "Buffer too small by " TIFF_SIZE_FORMAT " bytes.", + (size_t) (tif->tif_rawcc + data_size - tif->tif_rawdatasize)); + return 0; + } else { + _TIFFmemcpy(tif->tif_rawcp, data, data_size); + tif->tif_rawcc += data_size; + tif->tif_rawcp += data_size; + return 1; + } +} + +/* + * Encode a chunk of pixels. + */ +static int +TWebPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +{ + static const char module[] = "TWebPEncode"; + WebPState *sp = EncoderState(tif); + (void) s; + + assert(sp != NULL); + assert(sp->state == LSTATE_INIT_ENCODE); + + if( (uint64)sp->buffer_offset + + (uint64)cc > sp->buffer_size ) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Too many bytes to be written"); + return 0; + } + + memcpy(sp->pBuffer + sp->buffer_offset, + bp, cc); + sp->buffer_offset += (unsigned)cc; + + return 1; + +} + +static int +TWebPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) +{ + static const char module[] = "WebPDecode"; + VP8StatusCode status = VP8_STATUS_OK; + WebPState *sp = DecoderState(tif); + (void) s; + + assert(sp != NULL); + assert(sp->state == LSTATE_INIT_DECODE); + + if (occ % sp->sDecBuffer.u.RGBA.stride) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Fractional scanlines cannot be read"); + return 0; + } + + status = WebPIAppend(sp->psDecoder, tif->tif_rawcp, tif->tif_rawcc); + + if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED) { + if (status == VP8_STATUS_INVALID_PARAM) { + TIFFErrorExt(tif->tif_clientdata, module, + "Invalid parameter used."); + } else if (status == VP8_STATUS_OUT_OF_MEMORY) { + TIFFErrorExt(tif->tif_clientdata, module, + "Out of memory."); + } else { + TIFFErrorExt(tif->tif_clientdata, module, + "Unrecognized error."); + } + return 0; + } else { + int current_y, stride; + uint8_t* buf; + + /* Returns the RGB/A image decoded so far */ + buf = WebPIDecGetRGB(sp->psDecoder, ¤t_y, NULL, NULL, &stride); + + if ((buf != NULL) && + (occ <= stride * (current_y - sp->last_y))) { + memcpy(op, + buf + (sp->last_y * stride), + occ); + + tif->tif_rawcp += tif->tif_rawcc; + tif->tif_rawcc = 0; + sp->last_y += occ / sp->sDecBuffer.u.RGBA.stride; + return 1; + } else { + TIFFErrorExt(tif->tif_clientdata, module, "Unable to decode WebP data."); + return 0; + } + } +} + +static int +TWebPFixupTags(TIFF* tif) +{ + (void) tif; + if (tif->tif_dir.td_planarconfig != PLANARCONFIG_CONTIG) { + static const char module[] = "TWebPFixupTags"; + TIFFErrorExt(tif->tif_clientdata, module, + "TIFF WEBP requires data to be stored contiguously in RGB e.g. RGBRGBRGB " +#if WEBP_ENCODER_ABI_VERSION >= 0x0100 + "or RGBARGBARGBA" +#endif + ); + return 0; + } + return 1; +} + +static int +TWebPSetupDecode(TIFF* tif) +{ + static const char module[] = "WebPSetupDecode"; + uint16 nBitsPerSample = tif->tif_dir.td_bitspersample; + uint16 sampleFormat = tif->tif_dir.td_sampleformat; + + WebPState* sp = DecoderState(tif); + assert(sp != NULL); + + sp->nSamples = tif->tif_dir.td_samplesperpixel; + + /* check band count */ + if ( sp->nSamples != 3 +#if WEBP_ENCODER_ABI_VERSION >= 0x0100 + && sp->nSamples != 4 +#endif + ) + { + TIFFErrorExt(tif->tif_clientdata, module, + "WEBP driver doesn't support %d bands. Must be 3 (RGB) " + #if WEBP_ENCODER_ABI_VERSION >= 0x0100 + "or 4 (RGBA) " + #endif + "bands.", + sp->nSamples ); + return 0; + } + + /* check bits per sample and data type */ + if ((nBitsPerSample != 8) && (sampleFormat != 1)) { + TIFFErrorExt(tif->tif_clientdata, module, + "WEBP driver requires 8 bit unsigned data"); + return 0; + } + + /* if we were last encoding, terminate this mode */ + if (sp->state & LSTATE_INIT_ENCODE) { + WebPPictureFree(&sp->sPicture); + if (sp->pBuffer != NULL) { + _TIFFfree(sp->pBuffer); + sp->pBuffer = NULL; + } + sp->buffer_offset = 0; + sp->state = 0; + } + + sp->state |= LSTATE_INIT_DECODE; + + return 1; +} + +/* +* Setup state for decoding a strip. +*/ +static int +TWebPPreDecode(TIFF* tif, uint16 s) +{ + static const char module[] = "TWebPPreDecode"; + uint32 segment_width, segment_height; + WebPState* sp = DecoderState(tif); + TIFFDirectory* td = &tif->tif_dir; + (void) s; + assert(sp != NULL); + + if (isTiled(tif)) { + segment_width = td->td_tilewidth; + segment_height = td->td_tilelength; + } else { + segment_width = td->td_imagewidth; + segment_height = td->td_imagelength - tif->tif_row; + if (segment_height > td->td_rowsperstrip) + segment_height = td->td_rowsperstrip; + } + + if( (sp->state & LSTATE_INIT_DECODE) == 0 ) + tif->tif_setupdecode(tif); + + if (sp->psDecoder != NULL) { + WebPIDelete(sp->psDecoder); + WebPFreeDecBuffer(&sp->sDecBuffer); + sp->psDecoder = NULL; + } + + sp->last_y = 0; + + WebPInitDecBuffer(&sp->sDecBuffer); + + sp->sDecBuffer.is_external_memory = 0; + sp->sDecBuffer.width = segment_width; + sp->sDecBuffer.height = segment_height; + sp->sDecBuffer.u.RGBA.stride = segment_width * sp->nSamples; + sp->sDecBuffer.u.RGBA.size = segment_width * sp->nSamples * segment_height; + + if (sp->nSamples > 3) { + sp->sDecBuffer.colorspace = MODE_RGBA; + } else { + sp->sDecBuffer.colorspace = MODE_RGB; + } + + sp->psDecoder = WebPINewDecoder(&sp->sDecBuffer); + + if (sp->psDecoder == NULL) { + TIFFErrorExt(tif->tif_clientdata, module, + "Unable to allocate WebP decoder."); + return 0; + } + + return 1; +} + +static int +TWebPSetupEncode(TIFF* tif) +{ + static const char module[] = "WebPSetupEncode"; + uint16 nBitsPerSample = tif->tif_dir.td_bitspersample; + uint16 sampleFormat = tif->tif_dir.td_sampleformat; + + WebPState* sp = EncoderState(tif); + assert(sp != NULL); + + sp->nSamples = tif->tif_dir.td_samplesperpixel; + + /* check band count */ + if ( sp->nSamples != 3 +#if WEBP_ENCODER_ABI_VERSION >= 0x0100 + && sp->nSamples != 4 +#endif + ) + { + TIFFErrorExt(tif->tif_clientdata, module, + "WEBP driver doesn't support %d bands. Must be 3 (RGB) " +#if WEBP_ENCODER_ABI_VERSION >= 0x0100 + "or 4 (RGBA) " +#endif + "bands.", + sp->nSamples ); + return 0; + } + + /* check bits per sample and data type */ + if ((nBitsPerSample != 8) && (sampleFormat != 1)) { + TIFFErrorExt(tif->tif_clientdata, module, + "WEBP driver requires 8 bit unsigned data"); + return 0; + } + + if (sp->state & LSTATE_INIT_DECODE) { + WebPIDelete(sp->psDecoder); + WebPFreeDecBuffer(&sp->sDecBuffer); + sp->psDecoder = NULL; + sp->last_y = 0; + sp->state = 0; + } + + sp->state |= LSTATE_INIT_ENCODE; + + if (!WebPConfigInitInternal(&sp->sEncoderConfig, WEBP_PRESET_DEFAULT, + sp->quality_level, + WEBP_ENCODER_ABI_VERSION)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error creating WebP encoder configuration."); + return 0; + } + +#if WEBP_ENCODER_ABI_VERSION >= 0x0100 + sp->sEncoderConfig.lossless = sp->lossless; +#endif + + if (!WebPValidateConfig(&sp->sEncoderConfig)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error with WebP encoder configuration."); + return 0; + } + + if (!WebPPictureInit(&sp->sPicture)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error initializing WebP picture."); + return 0; + } + + return 1; +} + +/* +* Reset encoding state at the start of a strip. +*/ +static int +TWebPPreEncode(TIFF* tif, uint16 s) +{ + static const char module[] = "TWebPPreEncode"; + uint32 segment_width, segment_height; + WebPState *sp = EncoderState(tif); + TIFFDirectory* td = &tif->tif_dir; + + (void) s; + + assert(sp != NULL); + if( sp->state != LSTATE_INIT_ENCODE ) + tif->tif_setupencode(tif); + + /* + * Set encoding parameters for this strip/tile. + */ + if (isTiled(tif)) { + segment_width = td->td_tilewidth; + segment_height = td->td_tilelength; + } else { + segment_width = td->td_imagewidth; + segment_height = td->td_imagelength - tif->tif_row; + if (segment_height > td->td_rowsperstrip) + segment_height = td->td_rowsperstrip; + } + + if( segment_width > 16383 || segment_height > 16383 ) { + TIFFErrorExt(tif->tif_clientdata, module, + "WEBP maximum image dimensions are 16383 x 16383."); + return 0; + } + + /* set up buffer for raw data */ + /* given above check and that nSamples <= 4, buffer_size is <= 1 GB */ + sp->buffer_size = segment_width * segment_height * sp->nSamples; + sp->pBuffer = _TIFFmalloc(sp->buffer_size); + if( !sp->pBuffer) { + TIFFErrorExt(tif->tif_clientdata, module, "Cannot allocate buffer"); + return 0; + } + sp->buffer_offset = 0; + + sp->sPicture.width = segment_width; + sp->sPicture.height = segment_height; + sp->sPicture.writer = TWebPDatasetWriter; + sp->sPicture.custom_ptr = tif; + + return 1; +} + +/* +* Finish off an encoded strip by flushing it. +*/ +static int +TWebPPostEncode(TIFF* tif) +{ + static const char module[] = "WebPPostEncode"; + int64_t stride; + WebPState *sp = EncoderState(tif); + assert(sp != NULL); + + assert(sp->state == LSTATE_INIT_ENCODE); + + stride = (int64_t)sp->sPicture.width * sp->nSamples; + +#if WEBP_ENCODER_ABI_VERSION >= 0x0100 + if (sp->nSamples == 4) { + if (!WebPPictureImportRGBA(&sp->sPicture, sp->pBuffer, (int)stride)) { + TIFFErrorExt(tif->tif_clientdata, module, + "WebPPictureImportRGBA() failed" ); + return 0; + } + } + else +#endif + if (!WebPPictureImportRGB(&sp->sPicture, sp->pBuffer, (int)stride)) { + TIFFErrorExt(tif->tif_clientdata, module, + "WebPPictureImportRGB() failed"); + return 0; + } + + if (!WebPEncode(&sp->sEncoderConfig, &sp->sPicture)) { + +#if WEBP_ENCODER_ABI_VERSION >= 0x0100 + const char* pszErrorMsg = NULL; + switch(sp->sPicture.error_code) { + case VP8_ENC_ERROR_OUT_OF_MEMORY: + pszErrorMsg = "Out of memory"; break; + case VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY: + pszErrorMsg = "Out of memory while flushing bits"; break; + case VP8_ENC_ERROR_NULL_PARAMETER: + pszErrorMsg = "A pointer parameter is NULL"; break; + case VP8_ENC_ERROR_INVALID_CONFIGURATION: + pszErrorMsg = "Configuration is invalid"; break; + case VP8_ENC_ERROR_BAD_DIMENSION: + pszErrorMsg = "Picture has invalid width/height"; break; + case VP8_ENC_ERROR_PARTITION0_OVERFLOW: + pszErrorMsg = "Partition is bigger than 512k. Try using less " + "SEGMENTS, or increase PARTITION_LIMIT value"; + break; + case VP8_ENC_ERROR_PARTITION_OVERFLOW: + pszErrorMsg = "Partition is bigger than 16M"; + break; + case VP8_ENC_ERROR_BAD_WRITE: + pszErrorMsg = "Error while fludshing bytes"; break; + case VP8_ENC_ERROR_FILE_TOO_BIG: + pszErrorMsg = "File is bigger than 4G"; break; + case VP8_ENC_ERROR_USER_ABORT: + pszErrorMsg = "User interrupted"; + break; + default: + TIFFErrorExt(tif->tif_clientdata, module, + "WebPEncode returned an unknown error code: %d", + sp->sPicture.error_code); + pszErrorMsg = "Unknown WebP error type."; + break; + } + TIFFErrorExt(tif->tif_clientdata, module, + "WebPEncode() failed : %s", pszErrorMsg); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "Error in WebPEncode()"); +#endif + return 0; + } + + sp->sPicture.custom_ptr = NULL; + + if (!TIFFFlushData1(tif)) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Error flushing TIFF WebP encoder."); + return 0; + } + + return 1; +} + +static void +TWebPCleanup(TIFF* tif) +{ + WebPState* sp = LState(tif); + + assert(sp != 0); + + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; + + if (sp->state & LSTATE_INIT_ENCODE) { + WebPPictureFree(&sp->sPicture); + } + + if (sp->psDecoder != NULL) { + WebPIDelete(sp->psDecoder); + WebPFreeDecBuffer(&sp->sDecBuffer); + sp->psDecoder = NULL; + sp->last_y = 0; + } + + if (sp->pBuffer != NULL) { + _TIFFfree(sp->pBuffer); + sp->pBuffer = NULL; + } + + if (tif->tif_data) { + _TIFFfree(tif->tif_data); + tif->tif_data = NULL; + } + + _TIFFSetDefaultCompressionState(tif); +} + +static int +TWebPVSetField(TIFF* tif, uint32 tag, va_list ap) +{ + static const char module[] = "WebPVSetField"; + WebPState* sp = LState(tif); + + switch (tag) { + case TIFFTAG_WEBP_LEVEL: + sp->quality_level = (int) va_arg(ap, int); + if( sp->quality_level <= 0 || + sp->quality_level > 100.0f ) { + TIFFWarningExt(tif->tif_clientdata, module, + "WEBP_LEVEL should be between 1 and 100"); + } + return 1; + case TIFFTAG_WEBP_LOSSLESS: + #if WEBP_ENCODER_ABI_VERSION >= 0x0100 + sp->lossless = va_arg(ap, int); + return 1; + #else + TIFFErrorExt(tif->tif_clientdata, module, + "Need to upgrade WEBP driver, this version doesn't support " + "lossless compression."); + return 0; + #endif + default: + return (*sp->vsetparent)(tif, tag, ap); + } + /*NOTREACHED*/ +} + +static int +TWebPVGetField(TIFF* tif, uint32 tag, va_list ap) +{ + WebPState* sp = LState(tif); + + switch (tag) { + case TIFFTAG_WEBP_LEVEL: + *va_arg(ap, int*) = sp->quality_level; + break; + case TIFFTAG_WEBP_LOSSLESS: + *va_arg(ap, int*) = sp->lossless; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); + } + return 1; +} + +static const TIFFField TWebPFields[] = { + { TIFFTAG_WEBP_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, + FIELD_PSEUDO, TRUE, FALSE, "WEBP quality", NULL }, + { TIFFTAG_WEBP_LOSSLESS, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, + FIELD_PSEUDO, TRUE, FALSE, "WEBP lossless/lossy", NULL + }, +}; + +int +TIFFInitWebP(TIFF* tif, int scheme) +{ + static const char module[] = "TIFFInitWebP"; + WebPState* sp; + + assert( scheme == COMPRESSION_WEBP ); + + /* + * Merge codec-specific tag information. + */ + if ( !_TIFFMergeFields(tif, TWebPFields, TIFFArrayCount(TWebPFields)) ) { + TIFFErrorExt(tif->tif_clientdata, module, + "Merging WebP codec-specific tags failed"); + return 0; + } + + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8*) _TIFFmalloc(sizeof(WebPState)); + if (tif->tif_data == NULL) + goto bad; + sp = LState(tif); + + /* + * Override parent get/set field methods. + */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = TWebPVGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = TWebPVSetField; /* hook for codec tags */ + + /* Default values for codec-specific fields */ + sp->quality_level = 75.0f; /* default comp. level */ + sp->lossless = 0; /* default to false */ + sp->state = 0; + sp->nSamples = 0; + sp->psDecoder = NULL; + sp->last_y = 0; + + sp->buffer_offset = 0; + sp->pBuffer = NULL; + + /* + * Install codec methods. + * Notes: + * encoderow is not supported + */ + tif->tif_fixuptags = TWebPFixupTags; + tif->tif_setupdecode = TWebPSetupDecode; + tif->tif_predecode = TWebPPreDecode; + tif->tif_decoderow = TWebPDecode; + tif->tif_decodestrip = TWebPDecode; + tif->tif_decodetile = TWebPDecode; + tif->tif_setupencode = TWebPSetupEncode; + tif->tif_preencode = TWebPPreEncode; + tif->tif_postencode = TWebPPostEncode; + tif->tif_encoderow = TWebPEncode; + tif->tif_encodestrip = TWebPEncode; + tif->tif_encodetile = TWebPEncode; + tif->tif_cleanup = TWebPCleanup; + + return 1; +bad: + TIFFErrorExt(tif->tif_clientdata, module, + "No space for WebP state block"); + return 0; +} + +#endif /* WEBP_SUPPORT */ diff --git a/libtiff/tif_wince.c b/libtiff/tif_wince.c index 5bd7daf5..b3b168f1 100644 --- a/libtiff/tif_wince.c +++ b/libtiff/tif_wince.c @@ -34,9 +34,6 @@ #include "tiffiop.h" #include -/* Turn off console support on Windows CE. */ -#undef TIF_PLATFORM_CONSOLE - COMPILATION SHOULD FAIL This file is not yet updated to reflect changes in LibTiff 4.0. If you have the opportunity to update and test this file, please contact LibTiff folks diff --git a/libtiff/tif_write.c b/libtiff/tif_write.c index 586f6fdf..a31ecd12 100644 --- a/libtiff/tif_write.c +++ b/libtiff/tif_write.c @@ -538,9 +538,11 @@ TIFFSetupStrips(TIFF* tif) if (td->td_planarconfig == PLANARCONFIG_SEPARATE) td->td_stripsperimage /= td->td_samplesperpixel; td->td_stripoffset = (uint64 *) - _TIFFmalloc(td->td_nstrips * sizeof (uint64)); + _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64), + "for \"StripOffsets\" array"); td->td_stripbytecount = (uint64 *) - _TIFFmalloc(td->td_nstrips * sizeof (uint64)); + _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64), + "for \"StripByteCounts\" array"); if (td->td_stripoffset == NULL || td->td_stripbytecount == NULL) return (0); /* diff --git a/libtiff/tif_zstd.c b/libtiff/tif_zstd.c new file mode 100644 index 00000000..21c935e2 --- /dev/null +++ b/libtiff/tif_zstd.c @@ -0,0 +1,440 @@ +/* +* Copyright (c) 2017, Planet Labs +* Author: +* +* Permission to use, copy, modify, distribute, and sell this software and +* its documentation for any purpose is hereby granted without fee, provided +* that (i) the above copyright notices and this permission notice appear in +* all copies of the software and related documentation, and (ii) the names of +* Sam Leffler and Silicon Graphics may not be used in any advertising or +* publicity relating to the software without the specific, prior written +* permission of Sam Leffler and Silicon Graphics. +* +* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +* +* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +* OF THIS SOFTWARE. +*/ + +#include "tiffiop.h" +#ifdef ZSTD_SUPPORT +/* +* TIFF Library. +* +* ZSTD Compression Support +* +*/ + +#include "tif_predict.h" +#include "zstd.h" + +#include + +/* +* State block for each open TIFF file using ZSTD compression/decompression. +*/ +typedef struct { + TIFFPredictorState predict; + ZSTD_DStream* dstream; + ZSTD_CStream* cstream; + int compression_level; /* compression level */ + ZSTD_outBuffer out_buffer; + int state; /* state flags */ +#define LSTATE_INIT_DECODE 0x01 +#define LSTATE_INIT_ENCODE 0x02 + + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ +} ZSTDState; + +#define LState(tif) ((ZSTDState*) (tif)->tif_data) +#define DecoderState(tif) LState(tif) +#define EncoderState(tif) LState(tif) + +static int ZSTDEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s); +static int ZSTDDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s); + +static int +ZSTDFixupTags(TIFF* tif) +{ + (void) tif; + return 1; +} + +static int +ZSTDSetupDecode(TIFF* tif) +{ + ZSTDState* sp = DecoderState(tif); + + assert(sp != NULL); + + /* if we were last encoding, terminate this mode */ + if (sp->state & LSTATE_INIT_ENCODE) { + ZSTD_freeCStream(sp->cstream); + sp->cstream = NULL; + sp->state = 0; + } + + sp->state |= LSTATE_INIT_DECODE; + return 1; +} + +/* +* Setup state for decoding a strip. +*/ +static int +ZSTDPreDecode(TIFF* tif, uint16 s) +{ + static const char module[] = "ZSTDPreDecode"; + ZSTDState* sp = DecoderState(tif); + size_t zstd_ret; + + (void) s; + assert(sp != NULL); + + if( (sp->state & LSTATE_INIT_DECODE) == 0 ) + tif->tif_setupdecode(tif); + + if( sp->dstream ) + { + ZSTD_freeDStream(sp->dstream); + sp->dstream = NULL; + } + + sp->dstream = ZSTD_createDStream(); + if( sp->dstream == NULL ) { + TIFFErrorExt(tif->tif_clientdata, module, + "Cannot allocate decompression stream"); + return 0; + } + zstd_ret = ZSTD_initDStream(sp->dstream); + if( ZSTD_isError(zstd_ret) ) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error in ZSTD_initDStream(): %s", + ZSTD_getErrorName(zstd_ret)); + return 0; + } + + return 1; +} + +static int +ZSTDDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) +{ + static const char module[] = "ZSTDDecode"; + ZSTDState* sp = DecoderState(tif); + ZSTD_inBuffer in_buffer; + ZSTD_outBuffer out_buffer; + size_t zstd_ret; + + (void) s; + assert(sp != NULL); + assert(sp->state == LSTATE_INIT_DECODE); + + in_buffer.src = tif->tif_rawcp; + in_buffer.size = (size_t) tif->tif_rawcc; + in_buffer.pos = 0; + + out_buffer.dst = op; + out_buffer.size = (size_t) occ; + out_buffer.pos = 0; + + do { + zstd_ret = ZSTD_decompressStream(sp->dstream, &out_buffer, + &in_buffer); + if( ZSTD_isError(zstd_ret) ) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error in ZSTD_decompressStream(): %s", + ZSTD_getErrorName(zstd_ret)); + return 0; + } + } while( zstd_ret != 0 && + in_buffer.pos < in_buffer.size && + out_buffer.pos < out_buffer.size ); + + if (out_buffer.pos < (size_t)occ) { + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data at scanline %lu (short %lu bytes)", + (unsigned long) tif->tif_row, + (unsigned long) (size_t)occ - out_buffer.pos); + return 0; + } + + tif->tif_rawcp += in_buffer.pos; + tif->tif_rawcc -= in_buffer.pos; + + return 1; +} + +static int +ZSTDSetupEncode(TIFF* tif) +{ + ZSTDState* sp = EncoderState(tif); + + assert(sp != NULL); + if (sp->state & LSTATE_INIT_DECODE) { + ZSTD_freeDStream(sp->dstream); + sp->dstream = NULL; + sp->state = 0; + } + + sp->state |= LSTATE_INIT_ENCODE; + return 1; +} + +/* +* Reset encoding state at the start of a strip. +*/ +static int +ZSTDPreEncode(TIFF* tif, uint16 s) +{ + static const char module[] = "ZSTDPreEncode"; + ZSTDState *sp = EncoderState(tif); + size_t zstd_ret; + + (void) s; + assert(sp != NULL); + if( sp->state != LSTATE_INIT_ENCODE ) + tif->tif_setupencode(tif); + + if (sp->cstream) { + ZSTD_freeCStream(sp->cstream); + sp->cstream = NULL; + } + sp->cstream = ZSTD_createCStream(); + if( sp->cstream == NULL ) { + TIFFErrorExt(tif->tif_clientdata, module, + "Cannot allocate compression stream"); + return 0; + } + + zstd_ret = ZSTD_initCStream(sp->cstream, sp->compression_level); + if( ZSTD_isError(zstd_ret) ) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error in ZSTD_initCStream(): %s", + ZSTD_getErrorName(zstd_ret)); + return 0; + } + + sp->out_buffer.dst = tif->tif_rawdata; + sp->out_buffer.size = (size_t)tif->tif_rawdatasize; + sp->out_buffer.pos = 0; + + return 1; +} + +/* +* Encode a chunk of pixels. +*/ +static int +ZSTDEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +{ + static const char module[] = "ZSTDEncode"; + ZSTDState *sp = EncoderState(tif); + ZSTD_inBuffer in_buffer; + size_t zstd_ret; + + assert(sp != NULL); + assert(sp->state == LSTATE_INIT_ENCODE); + + (void) s; + + in_buffer.src = bp; + in_buffer.size = (size_t)cc; + in_buffer.pos = 0; + + do { + zstd_ret = ZSTD_compressStream(sp->cstream, &sp->out_buffer, + &in_buffer); + if( ZSTD_isError(zstd_ret) ) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error in ZSTD_compressStream(): %s", + ZSTD_getErrorName(zstd_ret)); + return 0; + } + if( sp->out_buffer.pos == sp->out_buffer.size ) { + tif->tif_rawcc = tif->tif_rawdatasize; + TIFFFlushData1(tif); + sp->out_buffer.dst = tif->tif_rawcp; + sp->out_buffer.pos = 0; + } + } while( in_buffer.pos < in_buffer.size ); + + return 1; +} + +/* +* Finish off an encoded strip by flushing it. +*/ +static int +ZSTDPostEncode(TIFF* tif) +{ + static const char module[] = "ZSTDPostEncode"; + ZSTDState *sp = EncoderState(tif); + size_t zstd_ret; + + do { + zstd_ret = ZSTD_endStream(sp->cstream, &sp->out_buffer); + if( ZSTD_isError(zstd_ret) ) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error in ZSTD_endStream(): %s", + ZSTD_getErrorName(zstd_ret)); + return 0; + } + if( sp->out_buffer.pos > 0 ) { + tif->tif_rawcc = sp->out_buffer.pos; + TIFFFlushData1(tif); + sp->out_buffer.dst = tif->tif_rawcp; + sp->out_buffer.pos = 0; + } + } while (zstd_ret != 0); + return 1; +} + +static void +ZSTDCleanup(TIFF* tif) +{ + ZSTDState* sp = LState(tif); + + assert(sp != 0); + + (void)TIFFPredictorCleanup(tif); + + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; + + if (sp->dstream) { + ZSTD_freeDStream(sp->dstream); + sp->dstream = NULL; + } + if (sp->cstream) { + ZSTD_freeCStream(sp->cstream); + sp->cstream = NULL; + } + _TIFFfree(sp); + tif->tif_data = NULL; + + _TIFFSetDefaultCompressionState(tif); +} + +static int +ZSTDVSetField(TIFF* tif, uint32 tag, va_list ap) +{ + static const char module[] = "ZSTDVSetField"; + ZSTDState* sp = LState(tif); + + switch (tag) { + case TIFFTAG_ZSTD_LEVEL: + sp->compression_level = (int) va_arg(ap, int); + if( sp->compression_level <= 0 || + sp->compression_level > ZSTD_maxCLevel() ) + { + TIFFWarningExt(tif->tif_clientdata, module, + "ZSTD_LEVEL should be between 1 and %d", + ZSTD_maxCLevel()); + } + return 1; + default: + return (*sp->vsetparent)(tif, tag, ap); + } + /*NOTREACHED*/ +} + +static int +ZSTDVGetField(TIFF* tif, uint32 tag, va_list ap) +{ + ZSTDState* sp = LState(tif); + + switch (tag) { + case TIFFTAG_ZSTD_LEVEL: + *va_arg(ap, int*) = sp->compression_level; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); + } + return 1; +} + +static const TIFFField ZSTDFields[] = { + { TIFFTAG_ZSTD_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, + FIELD_PSEUDO, TRUE, FALSE, "ZSTD compression_level", NULL }, +}; + +int +TIFFInitZSTD(TIFF* tif, int scheme) +{ + static const char module[] = "TIFFInitZSTD"; + ZSTDState* sp; + + assert( scheme == COMPRESSION_ZSTD ); + + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, ZSTDFields, TIFFArrayCount(ZSTDFields))) { + TIFFErrorExt(tif->tif_clientdata, module, + "Merging ZSTD codec-specific tags failed"); + return 0; + } + + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8*) _TIFFmalloc(sizeof(ZSTDState)); + if (tif->tif_data == NULL) + goto bad; + sp = LState(tif); + + /* + * Override parent get/set field methods. + */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = ZSTDVGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = ZSTDVSetField; /* hook for codec tags */ + + /* Default values for codec-specific fields */ + sp->compression_level = 9; /* default comp. level */ + sp->state = 0; + sp->dstream = 0; + sp->cstream = 0; + sp->out_buffer.dst = NULL; + sp->out_buffer.size = 0; + sp->out_buffer.pos = 0; + + /* + * Install codec methods. + */ + tif->tif_fixuptags = ZSTDFixupTags; + tif->tif_setupdecode = ZSTDSetupDecode; + tif->tif_predecode = ZSTDPreDecode; + tif->tif_decoderow = ZSTDDecode; + tif->tif_decodestrip = ZSTDDecode; + tif->tif_decodetile = ZSTDDecode; + tif->tif_setupencode = ZSTDSetupEncode; + tif->tif_preencode = ZSTDPreEncode; + tif->tif_postencode = ZSTDPostEncode; + tif->tif_encoderow = ZSTDEncode; + tif->tif_encodestrip = ZSTDEncode; + tif->tif_encodetile = ZSTDEncode; + tif->tif_cleanup = ZSTDCleanup; + /* + * Setup predictor setup. + */ + (void) TIFFPredictorInit(tif); + return 1; +bad: + TIFFErrorExt(tif->tif_clientdata, module, + "No space for ZSTD state block"); + return 0; +} +#endif /* ZSTD_SUPPORT */ + +/* vim: set ts=8 sts=8 sw=8 noet: */ diff --git a/libtiff/tiff.h b/libtiff/tiff.h index 4f1eefb8..b05f0e0a 100644 --- a/libtiff/tiff.h +++ b/libtiff/tiff.h @@ -187,7 +187,11 @@ typedef enum { #define COMPRESSION_SGILOG 34676 /* SGI Log Luminance RLE */ #define COMPRESSION_SGILOG24 34677 /* SGI Log 24-bit packed */ #define COMPRESSION_JP2000 34712 /* Leadtools JPEG2000 */ +#define COMPRESSION_LERC 34887 /* ESRI Lerc codec: https://github.com/Esri/lerc */ +/* compression codes 34887-34889 are reserved for ESRI */ #define COMPRESSION_LZMA 34925 /* LZMA2 */ +#define COMPRESSION_ZSTD 50000 /* ZSTD: WARNING not registered in Adobe-maintained registry */ +#define COMPRESSION_WEBP 50001 /* WEBP: WARNING not registered in Adobe-maintained registry */ #define TIFFTAG_PHOTOMETRIC 262 /* photometric interpretation */ #define PHOTOMETRIC_MINISWHITE 0 /* min value is white */ #define PHOTOMETRIC_MINISBLACK 1 /* min value is black */ @@ -448,6 +452,8 @@ typedef enum { /* tag 34929 is a private tag registered to FedEx */ #define TIFFTAG_FEDEX_EDR 34929 /* unknown use */ #define TIFFTAG_INTEROPERABILITYIFD 40965 /* Pointer to Interoperability private directory */ +/* tags 50674 to 50677 are reserved for ESRI */ +#define TIFFTAG_LERC_PARAMETERS 50674 /* Stores LERC version and additional compression method */ /* Adobe Digital Negative (DNG) format tags */ #define TIFFTAG_DNGVERSION 50706 /* &DNG version number */ #define TIFFTAG_DNGBACKWARDVERSION 50707 /* &DNG compatibility version */ @@ -601,6 +607,16 @@ typedef enum { #define TIFFTAG_PERSAMPLE 65563 /* interface for per sample tags */ #define PERSAMPLE_MERGED 0 /* present as a single value */ #define PERSAMPLE_MULTI 1 /* present as multiple values */ +#define TIFFTAG_ZSTD_LEVEL 65564 /* ZSTD compression level */ +#define TIFFTAG_LERC_VERSION 65565 /* LERC version */ +#define LERC_VERSION_2_4 4 +#define TIFFTAG_LERC_ADD_COMPRESSION 65566 /* LERC additional compression */ +#define LERC_ADD_COMPRESSION_NONE 0 +#define LERC_ADD_COMPRESSION_DEFLATE 1 +#define LERC_ADD_COMPRESSION_ZSTD 2 +#define TIFFTAG_LERC_MAXZERROR 65567 /* LERC maximum error */ +#define TIFFTAG_WEBP_LEVEL 65568 /* WebP compression level: WARNING not registered in Adobe-maintained registry */ +#define TIFFTAG_WEBP_LOSSLESS 65569 /* WebP lossless/lossy : WARNING not registered in Adobe-maintained registry */ /* * EXIF tags diff --git a/libtiff/tiffconf.h-vms b/libtiff/tiffconf.h-vms index 8d52893e..72b03390 100644 --- a/libtiff/tiffconf.h-vms +++ b/libtiff/tiffconf.h-vms @@ -7,15 +7,6 @@ #ifndef _TIFFCONF_ #define _TIFFCONF_ -/* Define to 1 if the system has the type `int16'. */ -//#define HAVE_INT16 - -/* Define to 1 if the system has the type `int32'. */ -//#define HAVE_INT32 - -/* Define to 1 if the system has the type `int8'. */ -//#define HAVE_INT8 - /* The size of a `int', as computed by sizeof. */ #define SIZEOF_INT 4 diff --git a/libtiff/tiffconf.h.cmake.in b/libtiff/tiffconf.h.cmake.in index de8a807e..59542f1e 100644 --- a/libtiff/tiffconf.h.cmake.in +++ b/libtiff/tiffconf.h.cmake.in @@ -40,15 +40,6 @@ /* Pointer difference type */ #define TIFF_PTRDIFF_T @TIFF_PTRDIFF_T@ -/* Define to 1 if the system has the type `int16'. */ -#cmakedefine HAVE_INT16 1 - -/* Define to 1 if the system has the type `int32'. */ -#cmakedefine HAVE_INT32 1 - -/* Define to 1 if the system has the type `int8'. */ -#cmakedefine HAVE_INT8 1 - /* Compatibility stuff. */ /* Define as 0 or 1 according to the floating point format suported by the diff --git a/libtiff/tiffconf.h.in b/libtiff/tiffconf.h.in index 6da9c5a6..5de30c9b 100644 --- a/libtiff/tiffconf.h.in +++ b/libtiff/tiffconf.h.in @@ -37,15 +37,6 @@ /* Pointer difference type */ #undef TIFF_PTRDIFF_T -/* Define to 1 if the system has the type `int16'. */ -#undef HAVE_INT16 - -/* Define to 1 if the system has the type `int32'. */ -#undef HAVE_INT32 - -/* Define to 1 if the system has the type `int8'. */ -#undef HAVE_INT8 - /* Compatibility stuff. */ /* Define as 0 or 1 according to the floating point format suported by the diff --git a/libtiff/tiffconf.vc.h b/libtiff/tiffconf.vc.h index c8c6c656..fb37a755 100644 --- a/libtiff/tiffconf.vc.h +++ b/libtiff/tiffconf.vc.h @@ -7,15 +7,6 @@ #ifndef _TIFFCONF_ #define _TIFFCONF_ -/* Define to 1 if the system has the type `int16'. */ -/* #undef HAVE_INT16 */ - -/* Define to 1 if the system has the type `int32'. */ -/* #undef HAVE_INT32 */ - -/* Define to 1 if the system has the type `int8'. */ -/* #undef HAVE_INT8 */ - /* The size of a `int', as computed by sizeof. */ #define SIZEOF_INT 4 diff --git a/libtiff/tiffconf.wince.h b/libtiff/tiffconf.wince.h index 30ff2d7a..013b0960 100644 --- a/libtiff/tiffconf.wince.h +++ b/libtiff/tiffconf.wince.h @@ -25,15 +25,6 @@ #ifndef _TIFFCONF_ #define _TIFFCONF_ -/* Define to 1 if the system has the type `int16'. */ -/* #undef HAVE_INT16 */ - -/* Define to 1 if the system has the type `int32'. */ -/* #undef HAVE_INT32 */ - -/* Define to 1 if the system has the type `int8'. */ -/* #undef HAVE_INT8 */ - /* The size of a `int', as computed by sizeof. */ #define SIZEOF_INT 4 diff --git a/libtiff/tiffio.h b/libtiff/tiffio.h index 670cd426..31c2e676 100644 --- a/libtiff/tiffio.h +++ b/libtiff/tiffio.h @@ -50,7 +50,7 @@ typedef struct tiff TIFF; * promoted type (i.e. one of int, unsigned int, pointer, * or double) and because we defined pseudo-tags that are * outside the range of legal Aldus-assigned tags. - * NB: tsize_t is int32 and not uint32 because some functions + * NB: tsize_t is signed and not unsigned because some functions * return -1. * NB: toff_t is not off_t for many reasons; TIFFs max out at * 32-bit file offsets, and BigTIFF maxes out at 64-bit diff --git a/libtiff/tiffio.hxx b/libtiff/tiffio.hxx index 6cd72730..df2cbbce 100644 --- a/libtiff/tiffio.hxx +++ b/libtiff/tiffio.hxx @@ -31,6 +31,7 @@ #include #include "tiff.h" +#include "tiffio.h" extern TIFF* TIFFStreamOpen(const char*, std::ostream *); extern TIFF* TIFFStreamOpen(const char*, std::istream *); diff --git a/libtiff/tiffiop.h b/libtiff/tiffiop.h index 93d0143d..5a2662c2 100644 --- a/libtiff/tiffiop.h +++ b/libtiff/tiffiop.h @@ -70,6 +70,7 @@ extern int snprintf(char* str, size_t size, const char* format, ...); #endif #define streq(a,b) (strcmp(a,b) == 0) +#define strneq(a,b,n) (strncmp(a,b,n) == 0) #ifndef TRUE #define TRUE 1 @@ -312,7 +313,7 @@ typedef size_t TIFFIOSize_t; #define _TIFF_off_t off_t #endif -#if defined(__has_attribute) +#if defined(__has_attribute) && defined(__clang__) #if __has_attribute(no_sanitize) #define TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW __attribute__((no_sanitize("unsigned-integer-overflow"))) #else @@ -426,6 +427,12 @@ extern int TIFFInitSGILog(TIFF*, int); #ifdef LZMA_SUPPORT extern int TIFFInitLZMA(TIFF*, int); #endif +#ifdef ZSTD_SUPPORT +extern int TIFFInitZSTD(TIFF*, int); +#endif +#ifdef WEBP_SUPPORT +extern int TIFFInitWebP(TIFF*, int); +#endif #ifdef VMS extern const TIFFCodec _TIFFBuiltinCODECS[]; #else diff --git a/libtiff/tiffvers.h b/libtiff/tiffvers.h index 7c415740..403d61be 100644 --- a/libtiff/tiffvers.h +++ b/libtiff/tiffvers.h @@ -1,4 +1,4 @@ -#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.0.9\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc." +#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.0.10\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 20171118 +#define TIFFLIB_VERSION 20181110 diff --git a/man/TIFFmemory.3tiff b/man/TIFFmemory.3tiff index 3947c86e..70a82123 100644 --- a/man/TIFFmemory.3tiff +++ b/man/TIFFmemory.3tiff @@ -77,7 +77,7 @@ C routines: .IR memcpy , and .IR memcmp , -repsectively. +respectively. .SH DIAGNOSTICS None. .SH "SEE ALSO" diff --git a/nmake.opt b/nmake.opt index c354bdfc..ae544670 100644 --- a/nmake.opt +++ b/nmake.opt @@ -34,13 +34,6 @@ ###### Edit the following lines to choose a feature set you need. ####### # -# -# Select WINMODE_CONSOLE to build a library which reports errors to stderr, or -# WINMODE_WINDOWED to build such that errors are reported via MessageBox(). -# -WINMODE_CONSOLE = 1 -#WINMODE_WINDOWED = 1 - # # Comment out the following lines to disable internal codecs. # @@ -159,13 +152,6 @@ DLLNAME = libtiff.dll # Set the native cpu bit order EXTRAFLAGS = -DFILLODER_LSB2MSB $(EXTRAFLAGS) -!IFDEF WINMODE_WINDOWED -EXTRAFLAGS = -DTIF_PLATFORM_WINDOWED $(EXTRAFLAGS) -LIBS = user32.lib $(LIBS) -!ELSE -EXTRAFLAGS = -DTIF_PLATFORM_CONSOLE $(EXTRAFLAGS) -!ENDIF - # Codec stuff !IFDEF CCITT_SUPPORT EXTRAFLAGS = -DCCITT_SUPPORT $(EXTRAFLAGS) diff --git a/port/CMakeLists.txt b/port/CMakeLists.txt index 8b221d1d..b7eb3a29 100644 --- a/port/CMakeLists.txt +++ b/port/CMakeLists.txt @@ -28,6 +28,8 @@ set(port_optional_SOURCES getopt.c lfind.c strcasecmp.c + strtol.c + strtoll.c strtoul.c strtoull.c) @@ -45,6 +47,12 @@ endif() if(NOT HAVE_STRCASECMP) list(APPEND port_USED_FILES strcasecmp.c) endif() +if(NOT HAVE_STRTOL) + list(APPEND port_USED_FILES strtol.c) +endif() +if(NOT HAVE_STRTOLL) + list(APPEND port_USED_FILES strtoll.c) +endif() if(NOT HAVE_STRTOUL) list(APPEND port_USED_FILES strtoul.c) endif() diff --git a/port/Makefile.am b/port/Makefile.am index 4d6e11d0..250479fe 100644 --- a/port/Makefile.am +++ b/port/Makefile.am @@ -27,7 +27,9 @@ EXTRA_DIST = \ CMakeLists.txt \ Makefile.vc \ libport.h \ - snprintf.c + snprintf.c \ + _strtol.h \ + _strtoul.h noinst_LTLIBRARIES = libport.la libport_la_SOURCES = dummy.c libport.h diff --git a/port/_strtol.h b/port/_strtol.h new file mode 100644 index 00000000..73a10063 --- /dev/null +++ b/port/_strtol.h @@ -0,0 +1,160 @@ +/* $NetBSD: _strtol.h,v 1.11 2017/07/06 21:08:44 joerg Exp $ */ + +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Original version ID: + * NetBSD: src/lib/libc/locale/_wcstol.h,v 1.2 2003/08/07 16:43:03 agc Exp + */ + +#include + +/* + * function template for strtol, strtoll and strtoimax. + * + * parameters: + * _FUNCNAME : function name + * __INT : return type + * __INT_MIN : lower limit of the return type + * __INT_MAX : upper limit of the return type + */ +__INT +_FUNCNAME(const char *nptr, char **endptr, int base) +{ + const char *s; + __INT acc, cutoff; + unsigned char c; + int i, neg, any, cutlim; + + assert(nptr != NULL); + /* endptr may be NULL */ + + /* check base value */ + if (base && (base < 2 || base > 36)) { + errno = EINVAL; + if (endptr != NULL) + /* LINTED interface specification */ + *endptr = (char *)(nptr); + return 0; + } + + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + s = nptr; + do { + c = *s++; + } while (isspace(c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X') && + ((s[1] >= '0' && s[1] <= '9') || + (s[1] >= 'a' && s[1] <= 'f') || + (s[1] >= 'A' && s[1] <= 'F'))) { + c = s[1]; + s += 2; + base = 16; + } else if (base == 0) + base = (c == '0' ? 8 : 10); + + /* + * Compute the cutoff value between legal numbers and illegal + * numbers. That is the largest legal value, divided by the + * base. An input number that is greater than this value, if + * followed by a legal input character, is too big. One that + * is equal to this value may be valid or not; the limit + * between valid and invalid numbers is then based on the last + * digit. For instance, if the range for longs is + * [-2147483648..2147483647] and the input base is 10, + * cutoff will be set to 214748364 and cutlim to either + * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated + * a value > 214748364, or equal but the next digit is > 7 (or 8), + * the number is too big, and we will return a range error. + * + * Set any if any `digits' consumed; make it negative to indicate + * overflow. + */ + cutoff = (__INT)(neg ? __INT_MIN : __INT_MAX); + cutlim = (int)(cutoff % base); + cutoff /= base; + if (neg) { + if (cutlim > 0) { + cutlim -= base; + cutoff += 1; + } + cutlim = -cutlim; + } + for (acc = 0, any = 0;; c = *s++) { + if (c >= '0' && c <= '9') + i = c - '0'; + else if (c >= 'a' && c <= 'z') + i = (c - 'a') + 10; + else if (c >= 'A' && c <= 'Z') + i = (c - 'A') + 10; + else + break; + if (i >= base) + break; + if (any < 0) + continue; + if (neg) { + if (acc < cutoff || (acc == cutoff && i > cutlim)) { + acc = __INT_MIN; + any = -1; + errno = ERANGE; + } else { + any = 1; + acc *= base; + acc -= i; + } + } else { + if (acc > cutoff || (acc == cutoff && i > cutlim)) { + acc = __INT_MAX; + any = -1; + errno = ERANGE; + } else { + any = 1; + acc *= base; + acc += i; + } + } + } + if (endptr != NULL) + /* LINTED interface specification */ + *endptr = (char *)(any ? s - 1 : nptr); + return(acc); +} diff --git a/port/_strtoul.h b/port/_strtoul.h new file mode 100644 index 00000000..5cb62168 --- /dev/null +++ b/port/_strtoul.h @@ -0,0 +1,127 @@ +/* $NetBSD: _strtoul.h,v 1.11 2017/07/06 21:08:44 joerg Exp $ */ + +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Original version ID: + * NetBSD: src/lib/libc/locale/_wcstoul.h,v 1.2 2003/08/07 16:43:03 agc Exp + */ + +#include + +/* + * function template for strtoul, strtoull and strtoumax. + * + * parameters: + * _FUNCNAME : function name + * __UINT : return type + * __UINT_MAX : upper limit of the return type + */ +__UINT +_FUNCNAME(const char *nptr, char **endptr, int base) +{ + const char *s; + __UINT acc, cutoff; + unsigned char c; + int i, neg, any, cutlim; + + assert(nptr != NULL); + /* endptr may be NULL */ + + /* check base value */ + if (base && (base < 2 || base > 36)) { + errno = EINVAL; + if (endptr != NULL) + /* LINTED interface specification */ + *endptr = (char *)(nptr); + return 0; + } + + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + s = nptr; + do { + c = *s++; + } while (isspace(c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X') && + ((s[1] >= '0' && s[1] <= '9') || + (s[1] >= 'a' && s[1] <= 'f') || + (s[1] >= 'A' && s[1] <= 'F'))) { + c = s[1]; + s += 2; + base = 16; + } else if (base == 0) + base = (c == '0' ? 8 : 10); + + /* + * See strtol for comments as to the logic used. + */ + cutoff = ((__UINT)__UINT_MAX / (__UINT)base); + cutlim = (int)((__UINT)__UINT_MAX % (__UINT)base); + for (acc = 0, any = 0;; c = *s++) { + if (c >= '0' && c <= '9') + i = c - '0'; + else if (c >= 'a' && c <= 'z') + i = (c - 'a') + 10; + else if (c >= 'A' && c <= 'Z') + i = (c - 'A') + 10; + else + break; + if (i >= base) + break; + if (any < 0) + continue; + if (acc > cutoff || (acc == cutoff && i > cutlim)) { + acc = __UINT_MAX; + any = -1; + errno = ERANGE; + } else { + any = 1; + acc *= (__UINT)base; + acc += i; + } + } + if (neg && any > 0) + acc = -acc; + if (endptr != NULL) + /* LINTED interface specification */ + *endptr = (char *)(any ? s - 1 : nptr); + return(acc); +} diff --git a/port/libport.h b/port/libport.h index 53ea3418..ff262638 100644 --- a/port/libport.h +++ b/port/libport.h @@ -36,9 +36,18 @@ int strcasecmp(const char *s1, const char *s2); # define HAVE_GETOPT 1 #endif -#if 0 +#if HAVE_STRTOL +long strtol(const char *nptr, char **endptr, int base); +#endif +#if HAVE_STRTOLL +long long strtoll(const char *nptr, char **endptr, int base); +#endif +#if HAVE_STRTOUL unsigned long strtoul(const char *nptr, char **endptr, int base); #endif +#if HAVE_STRTOULL +unsigned long long strtoull(const char *nptr, char **endptr, int base); +#endif #if 0 void * diff --git a/port/strtol.c b/port/strtol.c new file mode 100644 index 00000000..a355dde9 --- /dev/null +++ b/port/strtol.c @@ -0,0 +1,45 @@ +/* $NetBSD: strtol.c,v 1.18 2008/08/20 12:42:26 joerg Exp $ */ + +/*- + * Copyright (c) 2005 The DragonFly Project. All rights reserved. + * Copyright (c) 2003 Citrus Project, + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if 0 +__RCSID("$NetBSD: strtol.c,v 1.18 2008/08/20 12:42:26 joerg Exp $"); +#endif + +#include +#include +#include +#include +#include + +#define _FUNCNAME strtol +#define __INT long +#define __INT_MIN LONG_MIN +#define __INT_MAX LONG_MAX + +#include "_strtol.h" diff --git a/port/strtoll.c b/port/strtoll.c new file mode 100644 index 00000000..4784b098 --- /dev/null +++ b/port/strtoll.c @@ -0,0 +1,44 @@ +/* $NetBSD: strtol.c,v 1.18 2008/08/20 12:42:26 joerg Exp $ */ + +/*- + * Copyright (c) 2005 The DragonFly Project. All rights reserved. + * Copyright (c) 2003 Citrus Project, + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if 0 +__RCSID("$NetBSD: strtol.c,v 1.18 2008/08/20 12:42:26 joerg Exp $"); +#endif + +#include +#include +#include +#include + +#define _FUNCNAME strtoll +#define __INT long long +#define __INT_MIN LLONG_MIN +#define __INT_MAX LLONG_MAX + +#include "_strtol.h" diff --git a/port/strtoul.c b/port/strtoul.c index 4439de78..dbd44f16 100644 --- a/port/strtoul.c +++ b/port/strtoul.c @@ -1,6 +1,9 @@ -/* - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. +/* $NetBSD: strtoul.c,v 1.3 2008/08/20 19:58:34 oster Exp $ */ + +/*- + * Copyright (c) 2005 The DragonFly Project. All rights reserved. + * Copyright (c) 2003 Citrus Project, + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,14 +13,11 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) @@ -28,80 +28,17 @@ */ #if 0 -static char sccsid[] = "@(#)strtoul.c 8.1 (Berkeley) 6/4/93"; -__RCSID("$NetBSD: strtoul.c,v 1.16 2003/08/07 16:43:45 agc Exp $"); +__RCSID("$NetBSD: strtoul.c,v 1.3 2008/08/20 19:58:34 oster Exp $"); #endif +#include #include #include #include #include -/* - * Convert a string to an unsigned long integer. - * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -unsigned long -strtoul(const char *nptr, char **endptr, int base) -{ - const char *s; - unsigned long acc, cutoff; - int c; - int neg, any, cutlim; +#define _FUNCNAME strtoul +#define __UINT unsigned long int +#define __UINT_MAX ULONG_MAX - /* - * See strtol for comments as to the logic used. - */ - s = nptr; - do { - c = (unsigned char) *s++; - } while (isspace(c)); - if (c == '-') { - neg = 1; - c = *s++; - } else { - neg = 0; - if (c == '+') - c = *s++; - } - if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X')) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - - cutoff = ULONG_MAX / (unsigned long)base; - cutlim = (int)(ULONG_MAX % (unsigned long)base); - for (acc = 0, any = 0;; c = (unsigned char) *s++) { - if (isdigit(c)) - c -= '0'; - else if (isalpha(c)) - c -= isupper(c) ? 'A' - 10 : 'a' - 10; - else - break; - if (c >= base) - break; - if (any < 0) - continue; - if (acc > cutoff || (acc == cutoff && c > cutlim)) { - any = -1; - acc = ULONG_MAX; - errno = ERANGE; - } else { - any = 1; - acc *= (unsigned long)base; - acc += c; - } - } - if (neg && any > 0) - acc = -acc; - if (endptr != 0) - /* LINTED interface specification */ - *endptr = (char *)(any ? s - 1 : nptr); - return (acc); -} +#include "_strtoul.h" diff --git a/port/strtoull.c b/port/strtoull.c index fb7739cc..91e4ddfb 100644 --- a/port/strtoull.c +++ b/port/strtoull.c @@ -1,6 +1,9 @@ +/* $NetBSD: strtoul.c,v 1.3 2008/08/20 19:58:34 oster Exp $ */ + /*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. + * Copyright (c) 2005 The DragonFly Project. All rights reserved. + * Copyright (c) 2003 Citrus Project, + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,18 +13,11 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) @@ -31,86 +27,18 @@ * SUCH DAMAGE. */ -#include -#include +#if 0 +__RCSID("$NetBSD: strtoul.c,v 1.3 2008/08/20 19:58:34 oster Exp $"); +#endif + +#include #include +#include +#include #include -/* - * Convert a string to an unsigned long long integer. - * - * Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -unsigned long long -strtoull(const char *nptr, char **endptr, int base) -{ - const char *s; - unsigned long long acc; - char c; - unsigned long long cutoff; - int neg, any, cutlim; +#define _FUNCNAME strtoull +#define __UINT unsigned long long int +#define __UINT_MAX ULLONG_MAX - /* - * See strtoq for comments as to the logic used. - */ - s = nptr; - do { - c = *s++; - } while (isspace((unsigned char)c)); - if (c == '-') { - neg = 1; - c = *s++; - } else { - neg = 0; - if (c == '+') - c = *s++; - } - if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X') && - ((s[1] >= '0' && s[1] <= '9') || - (s[1] >= 'A' && s[1] <= 'F') || - (s[1] >= 'a' && s[1] <= 'f'))) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - acc = any = 0; - if (base < 2 || base > 36) - goto noconv; - - cutoff = ULLONG_MAX / base; - cutlim = ULLONG_MAX % base; - for ( ; ; c = *s++) { - if (c >= '0' && c <= '9') - c -= '0'; - else if (c >= 'A' && c <= 'Z') - c -= 'A' - 10; - else if (c >= 'a' && c <= 'z') - c -= 'a' - 10; - else - break; - if (c >= base) - break; - if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) - any = -1; - else { - any = 1; - acc *= base; - acc += c; - } - } - if (any < 0) { - acc = ULLONG_MAX; - errno = ERANGE; - } else if (!any) { -noconv: - errno = EINVAL; - } else if (neg) - acc = -acc; - if (endptr != NULL) - *endptr = (char *)(any ? s - 1 : nptr); - return (acc); -} +#include "_strtoul.h" diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 912be19c..266e3fcf 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -44,6 +44,7 @@ set(TESTSCRIPTS tiffcp-logluv.sh tiffcp-thumbnail.sh tiffcp-lzw-compat.sh + tiffcp-lzw-scanline-decode.sh tiffdump.sh tiffinfo.sh tiffcp-split.sh @@ -120,7 +121,8 @@ set(TIFFIMAGES images/rgb-3c-16b.tiff images/rgb-3c-8b.tiff images/quad-tile.jpg.tiff - images/quad-lzw-compat.tiff) + images/quad-lzw-compat.tiff + images/lzw-single-strip.tiff) set(BMPIMAGES images/palette-1c-8b.bmp @@ -335,6 +337,7 @@ add_convert_test(tiffcp g32d "-c g3:2d" "images/miniswhite-1c-1b.ti add_convert_test(tiffcp g32dfill "-c g3:2d:fill" "images/miniswhite-1c-1b.tiff" FALSE) add_convert_test(tiffcp g4 "-c g4" "images/miniswhite-1c-1b.tiff" FALSE) add_convert_test(tiffcp none "-c none" "images/quad-lzw-compat.tiff" FALSE) +add_convert_test(tiffcp noner1 "-c none -r 1" "images/lzw-single-strip.tiff" FALSE) add_convert_test_multi(tiffcp tiffcp "" logluv "-c none" "-c sgilog" "" "images/logluv-3c-16b.tiff" FALSE) add_convert_test_multi(tiffcp thumbnail "" thumbnail "g3:1d" "" "" diff --git a/test/Makefile.am b/test/Makefile.am index 2052487c..52a3fa4b 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -79,6 +79,7 @@ TESTSCRIPTS = \ tiffcp-logluv.sh \ tiffcp-thumbnail.sh \ tiffcp-lzw-compat.sh \ + tiffcp-lzw-scanline-decode.sh \ tiffdump.sh \ tiffinfo.sh \ tiffcp-split.sh \ @@ -158,7 +159,8 @@ TIFFIMAGES = \ images/rgb-3c-16b.tiff \ images/rgb-3c-8b.tiff \ images/quad-tile.jpg.tiff \ - images/quad-lzw-compat.tiff + images/quad-lzw-compat.tiff \ + images/lzw-single-strip.tiff PNMIMAGES = \ images/minisblack-1c-8b.pgm \ diff --git a/test/common.sh b/test/common.sh index 6b1380dd..42c38737 100644 --- a/test/common.sh +++ b/test/common.sh @@ -41,6 +41,7 @@ IMG_RGB_3C_16B=${IMAGES}/rgb-3c-16b.tiff IMG_RGB_3C_8B=${IMAGES}/rgb-3c-8b.tiff IMG_MINISBLACK_2C_8B_ALPHA=${IMAGES}/minisblack-2c-8b-alpha.tiff IMG_QUAD_LZW_COMPAT=${IMAGES}/quad-lzw-compat.tiff +IMG_LZW_SINGLE_STROP=${IMAGES}/lzw-single-strip.tiff IMG_MINISWHITE_1C_1B_PBM=${IMAGES}/miniswhite-1c-1b.pbm IMG_MINISBLACK_1C_8B_PGM=${IMAGES}/minisblack-1c-8b.pgm diff --git a/test/images/lzw-single-strip.tiff b/test/images/lzw-single-strip.tiff new file mode 100644 index 00000000..0ac27c6d Binary files /dev/null and b/test/images/lzw-single-strip.tiff differ diff --git a/test/tiffcp-lzw-scanline-decode.sh b/test/tiffcp-lzw-scanline-decode.sh new file mode 100755 index 00000000..11654d19 --- /dev/null +++ b/test/tiffcp-lzw-scanline-decode.sh @@ -0,0 +1,6 @@ +#!/bin/sh +# +# Basic sanity check for tiffcp with LZW decompression +# +. ${srcdir:-.}/common.sh +f_test_convert "${TIFFCP} -c none -r 1" "${IMG_LZW_SINGLE_STROP}" "o-tiffcp-lzw-scanline-decode.tiff" \ No newline at end of file diff --git a/tiff.spec b/tiff.spec index 58ee3094..a94ec9f5 100644 --- a/tiff.spec +++ b/tiff.spec @@ -43,7 +43,7 @@ product tiff exp "tiff.sw.tools" endsubsys subsys dev - id "${TIFF_NAME} Developement Software" + id "${TIFF_NAME} Development Software" exp "tiff.sw.dev" endsubsys endimage diff --git a/tools/pal2rgb.c b/tools/pal2rgb.c index 01fcf941..01d8502e 100644 --- a/tools/pal2rgb.c +++ b/tools/pal2rgb.c @@ -402,7 +402,23 @@ cpTags(TIFF* in, TIFF* out) { struct cpTag *p; for (p = tags; p < &tags[NTAGS]; p++) - cpTag(in, out, p->tag, p->count, p->type); + { + if( p->tag == TIFFTAG_GROUP3OPTIONS ) + { + uint16 compression; + if( !TIFFGetField(in, TIFFTAG_COMPRESSION, &compression) || + compression != COMPRESSION_CCITTFAX3 ) + continue; + } + if( p->tag == TIFFTAG_GROUP4OPTIONS ) + { + uint16 compression; + if( !TIFFGetField(in, TIFFTAG_COMPRESSION, &compression) || + compression != COMPRESSION_CCITTFAX4 ) + continue; + } + cpTag(in, out, p->tag, p->count, p->type); + } } #undef NTAGS diff --git a/tools/ppm2tiff.c b/tools/ppm2tiff.c index af6e4124..c2d59257 100644 --- a/tools/ppm2tiff.c +++ b/tools/ppm2tiff.c @@ -70,15 +70,16 @@ BadPPM(char* file) exit(-2); } + +#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) { - tmsize_t bytes = m1 * m2; - - if (m1 && bytes / m1 != m2) - bytes = 0; - - return bytes; + if( m1 == 0 || m2 > TIFF_TMSIZE_T_MAX / m1 ) + return 0; + return m1 * m2; } int diff --git a/tools/thumbnail.c b/tools/thumbnail.c index db9c0c08..3d1adc78 100644 --- a/tools/thumbnail.c +++ b/tools/thumbnail.c @@ -525,15 +525,15 @@ setrow(uint8* row, uint32 nrows, const uint8* rows[]) default: for (i = fw; i > 8; i--) acc += bits[*src++]; - /* fall thru... */ - case 8: acc += bits[*src++]; - case 7: acc += bits[*src++]; - case 6: acc += bits[*src++]; - case 5: acc += bits[*src++]; - case 4: acc += bits[*src++]; - case 3: acc += bits[*src++]; - case 2: acc += bits[*src++]; - case 1: acc += bits[*src++]; + /* fall through... */ + case 8: acc += bits[*src++]; /* fall through */ + case 7: acc += bits[*src++]; /* fall through */ + case 6: acc += bits[*src++]; /* fall through */ + case 5: acc += bits[*src++]; /* fall through */ + case 4: acc += bits[*src++]; /* fall through */ + case 3: acc += bits[*src++]; /* fall through */ + case 2: acc += bits[*src++]; /* fall through */ + case 1: acc += bits[*src++]; /* fall through */ case 0: break; } acc += bits[*src & mask1]; diff --git a/tools/tiff2bw.c b/tools/tiff2bw.c index 05faba87..dbc697b0 100644 --- a/tools/tiff2bw.c +++ b/tools/tiff2bw.c @@ -38,9 +38,7 @@ #endif #include "tiffio.h" - -#define streq(a,b) (strcmp((a),(b)) == 0) -#define strneq(a,b,n) (strncmp(a,b,n) == 0) +#include "tiffiop.h" /* x% weighting -> fraction of full color */ #define PCT(x) (((x)*256+50)/100) @@ -221,6 +219,11 @@ main(int argc, char* argv[]) TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, thing); TIFFSetField(out, TIFFTAG_SOFTWARE, "tiff2bw"); outbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(out)); + if( !outbuf ) + { + fprintf(stderr, "Out of memory\n"); + goto tiff2bw_error; + } TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(out, rowsperstrip)); @@ -244,6 +247,11 @@ main(int argc, char* argv[]) #undef CVT } inbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in)); + if( !inbuf ) + { + fprintf(stderr, "Out of memory\n"); + goto tiff2bw_error; + } for (row = 0; row < h; row++) { if (TIFFReadScanline(in, inbuf, row, 0) < 0) break; @@ -254,6 +262,11 @@ main(int argc, char* argv[]) break; case pack(PHOTOMETRIC_RGB, PLANARCONFIG_CONTIG): inbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in)); + if( !inbuf ) + { + fprintf(stderr, "Out of memory\n"); + goto tiff2bw_error; + } for (row = 0; row < h; row++) { if (TIFFReadScanline(in, inbuf, row, 0) < 0) break; @@ -263,8 +276,16 @@ main(int argc, char* argv[]) } break; case pack(PHOTOMETRIC_RGB, PLANARCONFIG_SEPARATE): + { + tmsize_t inbufsize; rowsize = TIFFScanlineSize(in); - inbuf = (unsigned char *)_TIFFmalloc(3*rowsize); + inbufsize = TIFFSafeMultiply(tmsize_t, 3, rowsize); + inbuf = (unsigned char *)_TIFFmalloc(inbufsize); + if( !inbuf ) + { + fprintf(stderr, "Out of memory\n"); + goto tiff2bw_error; + } for (row = 0; row < h; row++) { for (s = 0; s < 3; s++) if (TIFFReadScanline(in, @@ -276,6 +297,7 @@ main(int argc, char* argv[]) break; } break; + } } #undef pack if (inbuf) @@ -450,7 +472,23 @@ cpTags(TIFF* in, TIFF* out) { struct cpTag *p; for (p = tags; p < &tags[NTAGS]; p++) - cpTag(in, out, p->tag, p->count, p->type); + { + if( p->tag == TIFFTAG_GROUP3OPTIONS ) + { + uint16 compression; + if( !TIFFGetField(in, TIFFTAG_COMPRESSION, &compression) || + compression != COMPRESSION_CCITTFAX3 ) + continue; + } + if( p->tag == TIFFTAG_GROUP4OPTIONS ) + { + uint16 compression; + if( !TIFFGetField(in, TIFFTAG_COMPRESSION, &compression) || + compression != COMPRESSION_CCITTFAX4 ) + continue; + } + cpTag(in, out, p->tag, p->count, p->type); + } } #undef NTAGS diff --git a/tools/tiff2pdf.c b/tools/tiff2pdf.c index 484776c1..13f693dc 100644 --- a/tools/tiff2pdf.c +++ b/tools/tiff2pdf.c @@ -68,6 +68,8 @@ extern int getopt(int, char**, char*); #define PS_UNIT_SIZE 72.0F +#define TIFF_DIR_MAX 65534 + /* This type is of PDF color spaces. */ typedef enum { T2P_CS_BILEVEL = 0x01, /* Bilevel, black and white */ @@ -1051,6 +1053,14 @@ void t2p_read_tiff_init(T2P* t2p, TIFF* input){ uint16* tiff_transferfunction[3]; directorycount=TIFFNumberOfDirectories(input); + if(directorycount > TIFF_DIR_MAX) { + TIFFError( + TIFF2PDF_MODULE, + "TIFF contains too many directories, %s", + TIFFFileName(input)); + t2p->t2p_error = T2P_ERR_ERROR; + return; + } t2p->tiff_pages = (T2P_PAGE*) _TIFFmalloc(TIFFSafeMultiply(tmsize_t,directorycount,sizeof(T2P_PAGE))); if(t2p->tiff_pages==NULL){ TIFFError( @@ -3736,12 +3746,13 @@ tsize_t t2p_sample_rgbaa_to_rgb(tdata_t data, uint32 samplecount) { uint32 i; - - /* For the 3 first samples, there is overlapping between souce and - destination, so use memmove(). - See http://bugzilla.maptools.org/show_bug.cgi?id=2577 */ - for(i = 0; i < 3 && i < samplecount; i++) - memmove((uint8*)data + i * 3, (uint8*)data + i * 4, 3); + + /* For the 3 first samples, there is overlap between source and + * destination, so use memmove(). + * See http://bugzilla.maptools.org/show_bug.cgi?id=2577 + */ + for(i = 0; i < 3 && i < samplecount; i++) + memmove((uint8*)data + i * 3, (uint8*)data + i * 4, 3); for(; i < samplecount; i++) memcpy((uint8*)data + i * 3, (uint8*)data + i * 4, 3); @@ -4240,13 +4251,13 @@ void t2p_pdf_currenttime(T2P* t2p) currenttime = localtime(&timenow); snprintf(t2p->pdf_datetime, sizeof(t2p->pdf_datetime), - "D:%.4d%.2d%.2d%.2d%.2d%.2d", - (currenttime->tm_year + 1900) % 65536, - (currenttime->tm_mon + 1) % 256, - (currenttime->tm_mday) % 256, - (currenttime->tm_hour) % 256, - (currenttime->tm_min) % 256, - (currenttime->tm_sec) % 256); + "D:%.4u%.2u%.2u%.2u%.2u%.2u", + TIFFmin((unsigned) currenttime->tm_year + 1900U,9999U), + TIFFmin((unsigned) currenttime->tm_mon + 1U,12U), /* 0-11 + 1 */ + TIFFmin((unsigned) currenttime->tm_mday,31U), /* 1-31 */ + TIFFmin((unsigned) currenttime->tm_hour,23U), /* 0-23 */ + TIFFmin((unsigned) currenttime->tm_min,59U), /* 0-59 */ + TIFFmin((unsigned) (currenttime->tm_sec),60U)); /* 0-60 */ return; } diff --git a/tools/tiff2ps.c b/tools/tiff2ps.c index af62e4cc..d8d3da3a 100644 --- a/tools/tiff2ps.c +++ b/tools/tiff2ps.c @@ -61,7 +61,7 @@ * if not specified on the command line. * Add new command line option to specify document creator * as an alterntive to the string "tiff2ps" following model - * of patch submitted by Thomas Jarosch for specifiying a + * of patch submitted by Thomas Jarosch for specifying a * document title which is also supported now. * * 2009-Feb-11 @@ -71,7 +71,7 @@ * or landscape) if -h or -w is specified. Rotation is in * degrees counterclockwise since that is how Postscript does * it. The auto opption rotates the image 90 degrees ccw to - * produce landscape if that is a better fit than portait. + * produce landscape if that is a better fit than portrait. * * Cleaned up code in TIFF2PS and broke into smaller functions * to simplify rotations. @@ -518,7 +518,7 @@ checkImage(TIFF* tif) "PhotometricInterpretation=YCbCr"); return (0); } - /* fall thru... */ + /* fall through... */ case PHOTOMETRIC_RGB: if (alpha && bitspersample != 8) { TIFFError(filename, @@ -526,7 +526,7 @@ checkImage(TIFF* tif) bitspersample); return (0); } - /* fall thru... */ + /* fall through... */ case PHOTOMETRIC_SEPARATED: case PHOTOMETRIC_PALETTE: case PHOTOMETRIC_MINISBLACK: @@ -550,7 +550,7 @@ checkImage(TIFF* tif) bitspersample = 8; break; case PHOTOMETRIC_CIELAB: - /* fall thru... */ + /* fall through... */ default: TIFFError(filename, "Can not handle image with PhotometricInterpretation=%d", diff --git a/tools/tiffcmp.c b/tools/tiffcmp.c index 02a5e342..299847df 100644 --- a/tools/tiffcmp.c +++ b/tools/tiffcmp.c @@ -436,7 +436,8 @@ PrintIntDiff(uint32 row, int sample, uint32 pix, uint32 w1, uint32 w2) { int32 mask1, mask2, s; - mask1 = ~((-1) << bitspersample); + /* mask1 should have the n lowest bits set, where n == bitspersample */ + mask1 = ((int32)1 << bitspersample) - 1; s = (8 - bitspersample); mask2 = mask1 << s; for (; mask2 && pix < imagewidth; diff --git a/tools/tiffcp.c b/tools/tiffcp.c index 08df56d5..2f406e2d 100644 --- a/tools/tiffcp.c +++ b/tools/tiffcp.c @@ -389,6 +389,12 @@ processCompressOptions(char* opt) } else if (strneq(opt, "lzma", 4)) { processZIPOptions(opt); defcompression = COMPRESSION_LZMA; + } else if (strneq(opt, "zstd", 4)) { + processZIPOptions(opt); + defcompression = COMPRESSION_ZSTD; + } else if (strneq(opt, "webp", 4)) { + processZIPOptions(opt); + defcompression = COMPRESSION_WEBP; } else if (strneq(opt, "jbig", 4)) { defcompression = COMPRESSION_JBIG; } else if (strneq(opt, "sgilog", 6)) { @@ -427,6 +433,8 @@ char* stuff[] = { " -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding", " -c zip[:opts] compress output with deflate encoding", " -c lzma[:opts] compress output with LZMA2 encoding", +" -c zstd[:opts] compress output with ZSTD encoding", +" -c webp[:opts] compress output with WEBP encoding", " -c jpeg[:opts] compress output with JPEG encoding", " -c jbig compress output with ISO JBIG encoding", " -c packbits compress output with packbits encoding", @@ -446,7 +454,7 @@ char* stuff[] = { " r output color image as RGB rather than YCbCr", "For example, -c jpeg:r:50 to get JPEG-encoded RGB data with 50% comp. quality", "", -"LZW, Deflate (ZIP) and LZMA2 options:", +"LZW, Deflate (ZIP), LZMA2, ZSTD and WEBP options:", " # set predictor value", " p# set compression level (preset)", "For example, -c lzw:2 to get LZW-encoded data with horizontal differencing,", @@ -653,7 +661,7 @@ tiffcp(TIFF* in, TIFF* out) case ORIENTATION_RIGHTBOT: /* XXX */ TIFFWarning(TIFFFileName(in), "using bottom-left orientation"); orientation = ORIENTATION_BOTLEFT; - /* fall thru... */ + /* fall through... */ case ORIENTATION_LEFTBOT: /* XXX */ case ORIENTATION_BOTLEFT: break; @@ -662,7 +670,7 @@ tiffcp(TIFF* in, TIFF* out) default: TIFFWarning(TIFFFileName(in), "using top-left orientation"); orientation = ORIENTATION_TOPLEFT; - /* fall thru... */ + /* fall through... */ case ORIENTATION_LEFTTOP: /* XXX */ case ORIENTATION_TOPLEFT: break; @@ -731,6 +739,8 @@ tiffcp(TIFF* in, TIFF* out) case COMPRESSION_ADOBE_DEFLATE: case COMPRESSION_DEFLATE: case COMPRESSION_LZMA: + case COMPRESSION_ZSTD: + case COMPRESSION_WEBP: if (predictor != (uint16)-1) TIFFSetField(out, TIFFTAG_PREDICTOR, predictor); else @@ -741,6 +751,15 @@ tiffcp(TIFF* in, TIFF* out) TIFFSetField(out, TIFFTAG_ZIPQUALITY, preset); else if (compression == COMPRESSION_LZMA) TIFFSetField(out, TIFFTAG_LZMAPRESET, preset); + else if (compression == COMPRESSION_ZSTD) + TIFFSetField(out, TIFFTAG_ZSTD_LEVEL, preset); + else if (compression == COMPRESSION_WEBP) { + if (preset == 100) { + TIFFSetField(out, TIFFTAG_WEBP_LOSSLESS, TRUE); + } else { + TIFFSetField(out, TIFFTAG_WEBP_LEVEL, preset); + } + } } break; case COMPRESSION_CCITTFAX3: diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c index d82a94c8..ac38ec37 100644 --- a/tools/tiffcrop.c +++ b/tools/tiffcrop.c @@ -25,7 +25,7 @@ * ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE * OR PERFORMANCE OF THIS SOFTWARE. * - * Some portions of the current code are derived from tiffcp, primarly in + * Some portions of the current code are derived from tiffcp, primarily in * the areas of lowlevel reading and writing of TAGS, scanlines and tiles though * some of the original functions have been extended to support arbitrary bit * depths. These functions are presented at the top of this file. @@ -148,11 +148,6 @@ extern int getopt(int argc, char * const argv[], const char *optstring); #define TIFF_UINT32_MAX 0xFFFFFFFFU -#ifndef streq -#define streq(a,b) (strcmp((a),(b)) == 0) -#endif -#define strneq(a,b,n) (strncmp((a),(b),(n)) == 0) - #define TRUE 1 #define FALSE 0 @@ -215,6 +210,8 @@ extern int getopt(int argc, char * const argv[], const char *optstring); #define DUMP_TEXT 1 #define DUMP_RAW 2 +#define TIFF_DIR_MAX 65534 + /* Offsets into buffer for margins and fixed width and length segments */ struct offset { uint32 tmargin; @@ -1683,7 +1680,7 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 *defconfig = PLANARCONFIG_CONTIG; else { - TIFFError ("Unkown planar configuration", "%s", optarg); + TIFFError ("Unknown planar configuration", "%s", optarg); TIFFError ("For valid options type", "tiffcrop -h"); exit (-1); } @@ -2112,7 +2109,7 @@ update_output_file (TIFF **tiffout, char *mode, int autoindex, { static int findex = 0; /* file sequence indicator */ char *sep; - char filenum[16]; + char filenum[18]; char export_ext[16]; char exportname[PATH_MAX]; @@ -2127,7 +2124,7 @@ update_output_file (TIFF **tiffout, char *mode, int autoindex, memset (exportname, '\0', PATH_MAX); /* Leave room for page number portion of the new filename */ - strncpy (exportname, outname, PATH_MAX - 16); + strncpy (exportname, outname, PATH_MAX - sizeof(filenum)); if (*tiffout == NULL) /* This is a new export file */ { if (autoindex) @@ -2149,9 +2146,9 @@ update_output_file (TIFF **tiffout, char *mode, int autoindex, return 1; } - snprintf(filenum, sizeof(filenum), "-%03d%s", findex, export_ext); - filenum[14] = '\0'; - strncat (exportname, filenum, 15); + snprintf(filenum, sizeof(filenum), "-%03d%.5s", findex, export_ext); + filenum[sizeof(filenum)-1] = '\0'; + strncat (exportname, filenum, sizeof(filenum)-1); } exportname[PATH_MAX - 1] = '\0'; @@ -2210,8 +2207,9 @@ main(int argc, char* argv[]) unsigned int total_pages = 0; unsigned int total_images = 0; unsigned int end_of_input = FALSE; - int seg, length; - char temp_filename[PATH_MAX + 1]; + int seg; + size_t length; + char temp_filename[PATH_MAX + 16]; /* Extra space keeps the compiler from complaining */ little_endian = *((unsigned char *)&little_endian) & '1'; @@ -2231,7 +2229,7 @@ main(int argc, char* argv[]) pageNum = -1; else total_images = 0; - /* read multiple input files and write to output file(s) */ + /* Read multiple input files and write to output file(s) */ while (optind < argc - 1) { in = TIFFOpen (argv[optind], "r"); @@ -2239,7 +2237,14 @@ main(int argc, char* argv[]) return (-3); /* If only one input file is specified, we can use directory count */ - total_images = TIFFNumberOfDirectories(in); + total_images = TIFFNumberOfDirectories(in); + if (total_images > TIFF_DIR_MAX) + { + TIFFError (TIFFFileName(in), "File contains too many directories"); + if (out != NULL) + (void) TIFFClose(out); + return (1); + } if (image_count == 0) { dirnum = 0; @@ -2303,8 +2308,8 @@ main(int argc, char* argv[]) if (dump.infile != NULL) fclose (dump.infile); - /* dump.infilename is guaranteed to be NUL termimated and have 20 bytes - fewer than PATH_MAX */ + /* dump.infilename is guaranteed to be NUL terminated and have 20 bytes + fewer than PATH_MAX */ snprintf(temp_filename, sizeof(temp_filename), "%s-read-%03d.%s", dump.infilename, dump_images, (dump.format == DUMP_TEXT) ? "txt" : "raw"); @@ -2322,7 +2327,7 @@ main(int argc, char* argv[]) if (dump.outfile != NULL) fclose (dump.outfile); - /* dump.outfilename is guaranteed to be NUL termimated and have 20 bytes + /* dump.outfilename is guaranteed to be NUL terminated and have 20 bytes fewer than PATH_MAX */ snprintf(temp_filename, sizeof(temp_filename), "%s-write-%03d.%s", dump.outfilename, dump_images, @@ -6772,12 +6777,12 @@ extractImageSection(struct image_data *image, struct pageseg *section, #endif bytebuff1 = bytebuff2 = 0; - if (shift1 == 0) /* the region is byte and sample alligned */ + if (shift1 == 0) /* the region is byte and sample aligned */ { _TIFFmemcpy (sect_buff + dst_offset, src_buff + offset1, full_bytes); #ifdef DEVELMODE - TIFFError ("", " Alligned data src offset1: %8d, Dst offset: %8d\n", offset1, dst_offset); + TIFFError ("", " Aligned data src offset1: %8d, Dst offset: %8d\n", offset1, dst_offset); sprintf(&bitarray[18], "\n"); sprintf(&bitarray[19], "\t"); for (j = 20, k = 7; j < 28; j++, k--) @@ -7720,7 +7725,7 @@ createCroppedImage(struct image_data *image, struct crop_mask *crop, * original code assumes we are always copying all samples. * Use of global variables for config, compression and others * should be replaced by addition to the crop_mask struct (which - * will be renamed to proc_opts indicating that is controlls + * will be renamed to proc_opts indicating that is controls * user supplied processing options, not just cropping) and * then passed in as an argument. */ @@ -8415,7 +8420,7 @@ rotateImage(uint16 rotation, struct image_data *image, uint32 *img_width, ibuff = *ibuff_ptr; switch (rotation) { - case 180: if ((bps % 8) == 0) /* byte alligned data */ + case 180: if ((bps % 8) == 0) /* byte aligned data */ { src = ibuff; pix_offset = (spp * bps) / 8; @@ -9055,8 +9060,9 @@ mirrorImage(uint16 spp, uint16 bps, uint16 mirror, uint32 width, uint32 length, _TIFFfree(line_buff); if (mirror == MIRROR_VERT) break; + /* Fall through */ case MIRROR_HORIZ : - if ((bps % 8) == 0) /* byte alligned data */ + if ((bps % 8) == 0) /* byte aligned data */ { for (row = 0; row < length; row++) { @@ -9201,7 +9207,7 @@ invertImage(uint16 photometric, uint16 spp, uint16 bps, uint32 width, uint32 len 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 = (bytebuff1 << 6) | (bytebuff2 << 4) | (bytebuff3 << 2) | bytebuff4; src++; } break; diff --git a/tools/tiffinfo.c b/tools/tiffinfo.c index aecbb91a..049e3a34 100644 --- a/tools/tiffinfo.c +++ b/tools/tiffinfo.c @@ -84,7 +84,7 @@ main(int argc, char* argv[]) break; case 'd': showdata++; - /* fall thru... */ + /* fall through... */ case 'D': readdata++; break; diff --git a/tools/tiffinfoce.c b/tools/tiffinfoce.c index 82ab330b..b90f0382 100644 --- a/tools/tiffinfoce.c +++ b/tools/tiffinfoce.c @@ -73,7 +73,7 @@ main(int argc, char* argv[]) break; case 'd': showdata++; - /* fall thru... */ + /* fall through... */ case 'D': readdata++; break; @@ -290,17 +290,24 @@ void TIFFReadContigTileData(TIFF* tif) { unsigned char *buf; - tsize_t rowsize = TIFFTileRowSize(tif); + tmsize_t rowsize = TIFFTileRowSize(tif); + tmsize_t tilesize = TIFFTileSize(tif); - buf = (unsigned char *)_TIFFmalloc(TIFFTileSize(tif)); + buf = (unsigned char *)_TIFFmalloc(tilesize); if (buf) { - uint32 tw, th, w, h; + uint32 tw=0, th=0, w=0, h=0; uint32 row, col; TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw); TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); + if( rowsize == 0 || th > tilesize / rowsize ) + { + fprintf(stderr, "Cannot display data: th * rowsize > tilesize\n"); + _TIFFfree(buf); + return; + } for (row = 0; row < h; row += th) { for (col = 0; col < w; col += tw) { if (TIFFReadTile(tif, buf, col, row, 0, 0) < 0) { @@ -318,11 +325,12 @@ void TIFFReadSeparateTileData(TIFF* tif) { unsigned char *buf; - tsize_t rowsize = TIFFTileRowSize(tif); + tmsize_t rowsize = TIFFTileRowSize(tif); + tmsize_t tilesize = TIFFTileSize(tif); - buf = (unsigned char *)_TIFFmalloc(TIFFTileSize(tif)); + buf = (unsigned char *)_TIFFmalloc(tilesize); if (buf) { - uint32 tw, th, w, h; + uint32 tw=0, th=0, w=0, h=0; uint32 row, col; tsample_t s, samplesperpixel; @@ -331,6 +339,12 @@ TIFFReadSeparateTileData(TIFF* tif) TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw); TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel); + if( rowsize == 0 || th > tilesize / rowsize ) + { + fprintf(stderr, "Cannot display data: th * rowsize > tilesize\n"); + _TIFFfree(buf); + return; + } for (row = 0; row < h; row += th) { for (col = 0; col < w; col += tw) { for (s = 0; s < samplesperpixel; s++) { diff --git a/tools/tiffset.c b/tools/tiffset.c index 9a75d910..7ecc401b 100644 --- a/tools/tiffset.c +++ b/tools/tiffset.c @@ -188,6 +188,9 @@ main(int argc, char* argv[]) size = 4; break; + case TIFF_LONG8: + case TIFF_SLONG8: + case TIFF_IFD8: case TIFF_DOUBLE: size = 8; break; @@ -224,7 +227,16 @@ main(int argc, char* argv[]) case TIFF_SLONG: case TIFF_IFD: for (i = 0; i < wc; i++) - ((uint32 *)array)[i] = atol(argv[arg_index+i]); + ((int32 *)array)[i] = atol(argv[arg_index+i]); + break; + case TIFF_LONG8: + for (i = 0; i < wc; i++) + ((uint64 *)array)[i] = strtoll(argv[arg_index+i], (char **)NULL, 10); + break; + case TIFF_SLONG8: + case TIFF_IFD8: + for (i = 0; i < wc; i++) + ((int64 *)array)[i] = strtoll(argv[arg_index+i], (char **)NULL, 10); break; case TIFF_DOUBLE: for (i = 0; i < wc; i++) @@ -275,6 +287,12 @@ main(int argc, char* argv[]) ret = TIFFSetField(tiff, TIFFFieldTag(fip), atol(argv[arg_index++])); break; + case TIFF_LONG8: + case TIFF_SLONG8: + case TIFF_IFD8: + ret = TIFFSetField(tiff, TIFFFieldTag(fip), + strtoll(argv[arg_index++], (char **)NULL, 10)); + break; case TIFF_DOUBLE: ret = TIFFSetField(tiff, TIFFFieldTag(fip), atof(argv[arg_index++]));