3rdparty: update libtiff 4.0.9

pull/10274/head
Alexander Alekhin 7 years ago
parent ae5e1f8ece
commit 5c709f4aaa
  1. 358
      3rdparty/libtiff/CMakeLists.txt
  2. 30
      3rdparty/libtiff/tif_aux.c
  3. 12
      3rdparty/libtiff/tif_close.c
  4. 2
      3rdparty/libtiff/tif_codec.c
  5. 60
      3rdparty/libtiff/tif_color.c
  6. 8
      3rdparty/libtiff/tif_compress.c
  7. 261
      3rdparty/libtiff/tif_config.h.cmake.in
  8. 162
      3rdparty/libtiff/tif_config.h.cmakein
  9. 216
      3rdparty/libtiff/tif_dir.c
  10. 3
      3rdparty/libtiff/tif_dir.h
  11. 203
      3rdparty/libtiff/tif_dirinfo.c
  12. 375
      3rdparty/libtiff/tif_dirread.c
  13. 220
      3rdparty/libtiff/tif_dirwrite.c
  14. 4
      3rdparty/libtiff/tif_dumpmode.c
  15. 18
      3rdparty/libtiff/tif_error.c
  16. 38
      3rdparty/libtiff/tif_extension.c
  17. 147
      3rdparty/libtiff/tif_fax3.c
  18. 8
      3rdparty/libtiff/tif_fax3.h
  19. 607
      3rdparty/libtiff/tif_getimage.c
  20. 3
      3rdparty/libtiff/tif_jbig.c
  21. 440
      3rdparty/libtiff/tif_jpeg.c
  22. 4
      3rdparty/libtiff/tif_jpeg_12.c
  23. 156
      3rdparty/libtiff/tif_luv.c
  24. 6
      3rdparty/libtiff/tif_lzma.c
  25. 123
      3rdparty/libtiff/tif_lzw.c
  26. 41
      3rdparty/libtiff/tif_next.c
  27. 121
      3rdparty/libtiff/tif_ojpeg.c
  28. 10
      3rdparty/libtiff/tif_open.c
  29. 33
      3rdparty/libtiff/tif_packbits.c
  30. 215
      3rdparty/libtiff/tif_pixarlog.c
  31. 317
      3rdparty/libtiff/tif_predict.c
  32. 8
      3rdparty/libtiff/tif_predict.h
  33. 32
      3rdparty/libtiff/tif_print.c
  34. 679
      3rdparty/libtiff/tif_read.c
  35. 12
      3rdparty/libtiff/tif_strip.c
  36. 30
      3rdparty/libtiff/tif_swab.c
  37. 5
      3rdparty/libtiff/tif_thunder.c
  38. 29
      3rdparty/libtiff/tif_tile.c
  39. 94
      3rdparty/libtiff/tif_unix.c
  40. 18
      3rdparty/libtiff/tif_warning.c
  41. 44
      3rdparty/libtiff/tif_win32.c
  42. 117
      3rdparty/libtiff/tif_write.c
  43. 45
      3rdparty/libtiff/tif_zip.c
  44. 39
      3rdparty/libtiff/tiff.h
  45. 130
      3rdparty/libtiff/tiffconf.h.cmake.in
  46. 16
      3rdparty/libtiff/tiffio.h
  47. 134
      3rdparty/libtiff/tiffiop.h
  48. 4
      3rdparty/libtiff/tiffvers.h
  49. 2
      3rdparty/libtiff/uvcode.h
  50. 44
      cmake/OpenCVFindLibsGrfmt.cmake

@ -4,27 +4,372 @@
# ----------------------------------------------------------------------------
project(${TIFF_LIBRARY})
include(CheckCSourceCompiles)
include(CheckFunctionExists)
include(CheckIncludeFile)
# Find libm, if available
find_library(M_LIBRARY m)
check_include_file(assert.h HAVE_ASSERT_H)
if(NOT MSVC)
check_include_file(dlfcn.h HAVE_DLFCN_H)
endif()
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_function_exists(jbg_newlen HAVE_JBG_NEWLEN)
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)
if(NOT MSVC)
check_include_file(strings.h HAVE_STRINGS_H)
check_include_file(sys/time.h HAVE_SYS_TIME_H)
endif()
check_include_file(sys/types.h HAVE_SYS_TYPES_H)
if(NOT MSVC)
check_include_file(unistd.h HAVE_UNISTD_H)
endif()
if(MSVC)
set(INLINE_KEYWORD "inline")
else()
# Inspired from /usr/share/autoconf/autoconf/c.m4
foreach(inline_keyword "inline" "__inline__" "__inline")
if(NOT DEFINED C_INLINE)
set(CMAKE_REQUIRED_DEFINITIONS_SAVE ${CMAKE_REQUIRED_DEFINITIONS})
set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
"-Dinline=${inline_keyword}")
check_c_source_compiles("
typedef int foo_t;
static inline foo_t static_foo() {return 0;}
foo_t foo(){return 0;}
int main(int argc, char *argv[]) {return 0;}"
C_HAS_${inline_keyword})
set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS_SAVE})
if(C_HAS_${inline_keyword})
set(C_INLINE TRUE)
set(INLINE_KEYWORD "${inline_keyword}")
endif()
endif()
endforeach()
if(NOT DEFINED C_INLINE)
set(INLINE_KEYWORD)
endif()
endif()
# Check type sizes
# NOTE: Could be replaced with C99 <stdint.h>
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)
check_type_size("unsigned long" SIZEOF_UNSIGNED_LONG)
check_type_size("signed long long" SIZEOF_SIGNED_LONG_LONG)
check_type_size("unsigned long long" SIZEOF_UNSIGNED_LONG_LONG)
check_type_size("unsigned char *" SIZEOF_UNSIGNED_CHAR_P)
set(CMAKE_EXTRA_INCLUDE_FILES_SAVE ${CMAKE_EXTRA_INCLUDE_FILES})
set(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES} "stddef.h")
check_type_size("size_t" SIZEOF_SIZE_T)
check_type_size("ptrdiff_t" SIZEOF_PTRDIFF_T)
set(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES_SAVE})
set(TIFF_INT8_T "signed char")
set(TIFF_UINT8_T "unsigned char")
set(TIFF_INT16_T "signed short")
set(TIFF_UINT16_T "unsigned short")
if(SIZEOF_SIGNED_INT EQUAL 4)
set(TIFF_INT32_T "signed int")
set(TIFF_INT32_FORMAT "%d")
elseif(SIZEOF_SIGNED_LONG EQUAL 4)
set(TIFF_INT32_T "signed long")
set(TIFF_INT32_FORMAT "%ld")
endif()
if(SIZEOF_UNSIGNED_INT EQUAL 4)
set(TIFF_UINT32_T "unsigned int")
set(TIFF_UINT32_FORMAT "%u")
elseif(SIZEOF_UNSIGNED_LONG EQUAL 4)
set(TIFF_UINT32_T "unsigned long")
set(TIFF_UINT32_FORMAT "%lu")
endif()
if(SIZEOF_SIGNED_LONG EQUAL 8)
set(TIFF_INT64_T "signed long")
set(TIFF_INT64_FORMAT "%ld")
elseif(SIZEOF_SIGNED_LONG_LONG EQUAL 8)
set(TIFF_INT64_T "signed long long")
if(MINGW)
set(TIFF_INT64_FORMAT "%I64d")
else()
set(TIFF_INT64_FORMAT "%lld")
endif()
endif()
if(SIZEOF_UNSIGNED_LONG EQUAL 8)
set(TIFF_UINT64_T "unsigned long")
set(TIFF_UINT64_FORMAT "%lu")
elseif(SIZEOF_UNSIGNED_LONG_LONG EQUAL 8)
set(TIFF_UINT64_T "unsigned long long")
if(MINGW)
set(TIFF_UINT64_FORMAT "%I64u")
else()
set(TIFF_UINT64_FORMAT "%llu")
endif()
endif()
if(SIZEOF_UNSIGNED_INT EQUAL SIZEOF_SIZE_T)
set(TIFF_SIZE_T "unsigned int")
set(TIFF_SIZE_FORMAT "%u")
elseif(SIZEOF_UNSIGNED_LONG EQUAL SIZEOF_SIZE_T)
set(TIFF_SIZE_T "unsigned long")
set(TIFF_SIZE_FORMAT "%lu")
elseif(SIZEOF_UNSIGNED_LONG_LONG EQUAL SIZEOF_SIZE_T)
set(TIFF_SIZE_T "unsigned long")
if(MINGW)
set(TIFF_SIZE_FORMAT "%I64u")
else()
set(TIFF_SIZE_FORMAT "%llu")
endif()
endif()
if(SIZEOF_SIGNED_INT EQUAL SIZEOF_UNSIGNED_CHAR_P)
set(TIFF_SSIZE_T "signed int")
set(TIFF_SSIZE_FORMAT "%d")
elseif(SIZEOF_SIGNED_LONG EQUAL SIZEOF_UNSIGNED_CHAR_P)
set(TIFF_SSIZE_T "signed long")
set(TIFF_SSIZE_FORMAT "%ld")
elseif(SIZEOF_SIGNED_LONG_LONG EQUAL SIZEOF_UNSIGNED_CHAR_P)
set(TIFF_SSIZE_T "signed long long")
if(MINGW)
set(TIFF_SSIZE_FORMAT "%I64d")
else()
set(TIFF_SSIZE_FORMAT "%lld")
endif()
endif()
if(NOT SIZEOF_PTRDIFF_T)
set(TIFF_PTRDIFF_T "${TIFF_SSIZE_T}")
set(TIFF_PTRDIFF_FORMAT "${SSIZE_FORMAT}")
else()
set(TIFF_PTRDIFF_T "ptrdiff_t")
set(TIFF_PTRDIFF_FORMAT "%ld")
endif()
# Nonstandard int types
if(NOT MSVC)
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})
endif()
# Check functions
if(NOT MSVC)
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})
endif()
if(NOT MSVC)
check_function_exists(isascii HAVE_ISASCII)
check_function_exists(memset HAVE_MEMSET)
check_function_exists(mmap HAVE_MMAP)
check_function_exists(getopt HAVE_GETOPT)
endif()
check_function_exists(memmove HAVE_MEMMOVE)
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(lfind HAVE_LFIND)
# May be inlined, so check it compiles:
check_c_source_compiles("
#include <stdio.h>
int main(void) {
char buf[10];
snprintf(buf, 10, \"Test %d\", 1);
return 0;
}"
HAVE_SNPRINTF)
if(NOT HAVE_SNPRINTF)
add_definitions(-DNEED_LIBPORT)
endif()
# CPU bit order
set(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)
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()
# IEEE floating point
set(HAVE_IEEEFP 1 CACHE STRING "IEEE floating point is available")
mark_as_advanced(HAVE_IEEEFP)
# Large file support
if(UNIX OR MINGW)
# This might not catch every possibility catered for by
# AC_SYS_LARGEFILE.
add_definitions(-D_FILE_OFFSET_BITS=64)
set(FILE_OFFSET_BITS 64)
endif()
# Documentation install directory (default to cmake project docdir)
set(LIBTIFF_DOCDIR "${CMAKE_INSTALL_FULL_DOCDIR}")
# Options to enable and disable internal codecs
option(ccitt "support for CCITT Group 3 & 4 algorithms" ON)
set(CCITT_SUPPORT ${ccitt})
option(packbits "support for Macintosh PackBits algorithm" ON)
set(PACKBITS_SUPPORT ${packbits})
option(lzw "support for LZW algorithm" ON)
set(LZW_SUPPORT ${lzw})
option(thunder "support for ThunderScan 4-bit RLE algorithm" ON)
set(THUNDER_SUPPORT ${thunder})
option(next "support for NeXT 2-bit RLE algorithm" ON)
set(NEXT_SUPPORT ${next})
option(logluv "support for LogLuv high dynamic range algorithm" ON)
set(LOGLUV_SUPPORT ${logluv})
# Option for Microsoft Document Imaging
option(mdi "support for Microsoft Document Imaging" ON)
set(MDI_SUPPORT ${mdi})
# ZLIB
set(ZLIB_SUPPORT 0)
if(ZLIB_LIBRARY)
set(ZLIB_SUPPORT 1)
endif()
set(ZIP_SUPPORT ${ZLIB_SUPPORT})
set(PIXARLOG_SUPPORT FALSE)
# JPEG
set(JPEG_SUPPORT FALSE)
if(HAVE_JPEG)
set(JPEG_SUPPORT TRUE)
include_directories(${JPEG_INCLUDE_DIR})
endif()
option(old-jpeg "support for Old JPEG compression (read-only)" OFF) # OpenCV: changed to OFF
set(OJPEG_SUPPORT FALSE)
if(JPEG_SUPPORT AND old-jpeg)
set(OJPEG_SUPPORT TRUE)
endif()
# OpenCV: turned off
set(JBIG_SUPPORT 0)
set(LZMA_SUPPORT 0) # OpenCV: turned off
set(JPEG12_FOUND FALSE) # OpenCV: turned off
set(STRIPCHOP_DEFAULT)
set(STRIP_SIZE_DEFAULT 8192)
# Win32 IO
set(win32_io FALSE)
if(WIN32 AND NOT WINRT)
set(USE_WIN32_FILEIO 1)
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()
# Orthogonal features
# OpenCV: turned ON
set(SUBIFD_SUPPORT 1)
set(DEFAULT_EXTRASAMPLE_AS_ALPHA 1)
set(CHECK_JPEG_YCBCR_SUBSAMPLING 1)
if(JPEG_INCLUDE_DIR)
list(APPEND TIFF_INCLUDES ${JPEG_INCLUDE_DIR})
endif()
if(JPEG12_INCLUDE_DIR)
list(APPEND TIFF_INCLUDES ${JPEG12_INCLUDE_DIR})
endif()
if(JBIG_INCLUDE_DIR)
list(APPEND TIFF_INCLUDES ${JBIG_INCLUDE_DIR})
endif()
if(LIBLZMA_INCLUDE_DIRS)
list(APPEND TIFF_INCLUDES ${LIBLZMA_INCLUDE_DIRS})
endif()
# Libraries required by libtiff
set(TIFF_LIBRARY_DEPS)
if(M_LIBRARY)
list(APPEND TIFF_LIBRARY_DEPS ${M_LIBRARY})
endif()
if(ZLIB_LIBRARIES)
list(APPEND TIFF_LIBRARY_DEPS ${ZLIB_LIBRARIES})
endif()
if(JPEG_LIBRARIES)
list(APPEND TIFF_LIBRARY_DEPS ${JPEG_LIBRARIES})
endif()
if(JPEG12_LIBRARIES)
list(APPEND TIFF_LIBRARY_DEPS ${JPEG12_LIBRARIES})
endif()
if(JBIG_LIBRARIES)
list(APPEND TIFF_LIBRARY_DEPS ${JBIG_LIBRARIES})
endif()
if(LIBLZMA_LIBRARIES)
list(APPEND TIFF_LIBRARY_DEPS ${LIBLZMA_LIBRARIES})
endif()
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tif_config.h.cmakein"
"${CMAKE_CURRENT_BINARY_DIR}/tif_config.h" @ONLY)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tif_config.h.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/tif_config.h"
@ONLY)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tiffconf.h.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/tiffconf.h"
@ONLY)
ocv_include_directories("${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}" ${ZLIB_INCLUDE_DIRS})
@ -79,6 +424,7 @@ set(lib_srcs
uvcode.h
tiffio.hxx
"${CMAKE_CURRENT_BINARY_DIR}/tif_config.h"
"${CMAKE_CURRENT_BINARY_DIR}/tiffconf.h"
)
if(WIN32 AND NOT WINRT)
@ -92,7 +438,9 @@ ocv_warnings_disable(CMAKE_C_FLAGS -Wno-unused-but-set-variable -Wmissing-protot
-Wmisleading-indentation
)
ocv_warnings_disable(CMAKE_C_FLAGS -Wunused-parameter) # clang
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wmissing-declarations -Wunused-parameter)
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wmissing-declarations -Wunused-parameter
-Wundef # tiffiop.h: #if __clang_major__ >= 4
)
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4018 /wd4100 /wd4127 /wd4311 /wd4701 /wd4706) # vs2005
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4244) # vs2008
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4267 /wd4305 /wd4306) # vs2008 Win64

@ -1,4 +1,4 @@
/* $Id: tif_aux.c,v 1.26 2010-07-01 15:33:28 dron Exp $ */
/* $Id: tif_aux.c,v 1.31 2017-11-17 20:21:00 erouault Exp $ */
/*
* Copyright (c) 1991-1997 Sam Leffler
@ -100,7 +100,8 @@ TIFFDefaultTransferFunction(TIFFDirectory* td)
n = ((tmsize_t)1)<<td->td_bitspersample;
nbytes = n * sizeof (uint16);
if (!(tf[0] = (uint16 *)_TIFFmalloc(nbytes)))
tf[0] = (uint16 *)_TIFFmalloc(nbytes);
if (tf[0] == NULL)
return 0;
tf[0][0] = 0;
for (i = 1; i < n; i++) {
@ -109,10 +110,12 @@ TIFFDefaultTransferFunction(TIFFDirectory* td)
}
if (td->td_samplesperpixel - td->td_extrasamples > 1) {
if (!(tf[1] = (uint16 *)_TIFFmalloc(nbytes)))
tf[1] = (uint16 *)_TIFFmalloc(nbytes);
if(tf[1] == NULL)
goto bad;
_TIFFmemcpy(tf[1], tf[0], nbytes);
if (!(tf[2] = (uint16 *)_TIFFmalloc(nbytes)))
tf[2] = (uint16 *)_TIFFmalloc(nbytes);
if (tf[2] == NULL)
goto bad;
_TIFFmemcpy(tf[2], tf[0], nbytes);
}
@ -134,7 +137,8 @@ TIFFDefaultRefBlackWhite(TIFFDirectory* td)
{
int i;
if (!(td->td_refblackwhite = (float *)_TIFFmalloc(6*sizeof (float))))
td->td_refblackwhite = (float *)_TIFFmalloc(6*sizeof (float));
if (td->td_refblackwhite == NULL)
return 0;
if (td->td_photometric == PHOTOMETRIC_YCBCR) {
/*
@ -163,7 +167,7 @@ TIFFDefaultRefBlackWhite(TIFFDirectory* td)
* value if the tag is not present in the directory.
*
* NB: We use the value in the directory, rather than
* explcit values so that defaults exist only one
* explicit values so that defaults exist only one
* place in the library -- in TIFFDefaultDirectory.
*/
int
@ -210,6 +214,13 @@ TIFFVGetFieldDefaulted(TIFF* tif, uint32 tag, va_list ap)
case TIFFTAG_PREDICTOR:
{
TIFFPredictorState* sp = (TIFFPredictorState*) tif->tif_data;
if( sp == NULL )
{
TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
"Cannot get \"Predictor\" tag as plugin is not configured");
*va_arg(ap, uint16*) = 0;
return 0;
}
*va_arg(ap, uint16*) = (uint16) sp->predictor;
return 1;
}
@ -348,6 +359,13 @@ _TIFFUInt64ToDouble(uint64 ui64)
}
}
int _TIFFSeekOK(TIFF* tif, toff_t off)
{
/* Huge offsets, especially -1 / UINT64_MAX, can cause issues */
/* See http://bugzilla.maptools.org/show_bug.cgi?id=2726 */
return off <= (~(uint64)0)/2 && TIFFSeekFile(tif,off,SEEK_SET)==off;
}
/* vim: set ts=8 sts=8 sw=8 noet: */
/*
* Local Variables:

@ -1,4 +1,4 @@
/* $Id: tif_close.c,v 1.19 2010-03-10 18:56:48 bfriesen Exp $ */
/* $Id: tif_close.c,v 1.21 2016-01-23 21:20:34 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -36,7 +36,7 @@
/**
* Auxiliary function to free the TIFF structure. Given structure will be
* completetly freed, so you should save opened file handle and pointer
* completely freed, so you should save opened file handle and pointer
* to the close procedure in external variables before calling
* _TIFFCleanup(), if you will need these ones to close the file.
*
@ -62,11 +62,11 @@ TIFFCleanup(TIFF* tif)
*/
while( tif->tif_clientinfo )
{
TIFFClientInfoLink *link = tif->tif_clientinfo;
TIFFClientInfoLink *psLink = tif->tif_clientinfo;
tif->tif_clientinfo = link->next;
_TIFFfree( link->name );
_TIFFfree( link );
tif->tif_clientinfo = psLink->next;
_TIFFfree( psLink->name );
_TIFFfree( psLink );
}
if (tif->tif_rawdata && (tif->tif_flags&TIFF_MYBUFFER))

@ -1,4 +1,4 @@
/* $Id: tif_codec.c,v 1.15 2010-12-14 12:53:00 dron Exp $ */
/* $Id: tif_codec.c,v 1.17 2015-08-19 02:31:04 bfriesen Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler

@ -1,4 +1,4 @@
/* $Id: tif_color.c,v 1.19 2010-12-14 02:22:42 faxguy Exp $ */
/* $Id: tif_color.c,v 1.24 2017-05-29 10:12:54 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -126,37 +126,37 @@ TIFFCIELabToRGBInit(TIFFCIELabToRGB* cielab,
const TIFFDisplay *display, float *refWhite)
{
int i;
double gamma;
double dfGamma;
cielab->range = CIELABTORGB_TABLE_RANGE;
_TIFFmemcpy(&cielab->display, display, sizeof(TIFFDisplay));
/* Red */
gamma = 1.0 / cielab->display.d_gammaR ;
dfGamma = 1.0 / cielab->display.d_gammaR ;
cielab->rstep =
(cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
for(i = 0; i <= cielab->range; i++) {
cielab->Yr2r[i] = cielab->display.d_Vrwr
* ((float)pow((double)i / cielab->range, gamma));
* ((float)pow((double)i / cielab->range, dfGamma));
}
/* Green */
gamma = 1.0 / cielab->display.d_gammaG ;
dfGamma = 1.0 / cielab->display.d_gammaG ;
cielab->gstep =
(cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
for(i = 0; i <= cielab->range; i++) {
cielab->Yg2g[i] = cielab->display.d_Vrwg
* ((float)pow((double)i / cielab->range, gamma));
* ((float)pow((double)i / cielab->range, dfGamma));
}
/* Blue */
gamma = 1.0 / cielab->display.d_gammaB ;
dfGamma = 1.0 / cielab->display.d_gammaB ;
cielab->bstep =
(cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
for(i = 0; i <= cielab->range; i++) {
cielab->Yb2b[i] = cielab->display.d_Vrwb
* ((float)pow((double)i / cielab->range, gamma));
* ((float)pow((double)i / cielab->range, dfGamma));
}
/* Init reference white point */
@ -175,7 +175,7 @@ TIFFCIELabToRGBInit(TIFFCIELabToRGB* cielab,
#define SHIFT 16
#define FIX(x) ((int32)((x) * (1L<<SHIFT) + 0.5))
#define ONE_HALF ((int32)(1<<(SHIFT-1)))
#define Code2V(c, RB, RW, CR) ((((c)-(int32)(RB))*(float)(CR))/(float)(((RW)-(RB)) ? ((RW)-(RB)) : 1))
#define Code2V(c, RB, RW, CR) ((((c)-(int32)(RB))*(float)(CR))/(float)(((RW)-(RB)!=0) ? ((RW)-(RB)) : 1))
#define CLAMP(f,min,max) ((f)<(min)?(min):(f)>(max)?(max):(f))
#define HICLAMP(f,max) ((f)>(max)?(max):(f))
@ -186,7 +186,9 @@ TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32 Y, int32 Cb, int32 Cr,
int32 i;
/* XXX: Only 8-bit YCbCr input supported for now */
Y = HICLAMP(Y, 255), Cb = CLAMP(Cb, 0, 255), Cr = CLAMP(Cr, 0, 255);
Y = HICLAMP(Y, 255);
Cb = CLAMP(Cb, 0, 255);
Cr = CLAMP(Cr, 0, 255);
i = ycbcr->Y_tab[Y] + ycbcr->Cr_r_tab[Cr];
*r = CLAMP(i, 0, 255);
@ -197,6 +199,23 @@ TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32 Y, int32 Cb, int32 Cr,
*b = CLAMP(i, 0, 255);
}
/* Clamp function for sanitization purposes. Normally clamping should not */
/* occur for well behaved chroma and refBlackWhite coefficients */
static float CLAMPw(float v, float vmin, float vmax)
{
if( v < vmin )
{
/* printf("%f clamped to %f\n", v, vmin); */
return vmin;
}
if( v > vmax )
{
/* printf("%f clamped to %f\n", v, vmax); */
return vmax;
}
return v;
}
/*
* Initialize the YCbCr->RGB conversion tables. The conversion
* is done according to the 6.0 spec:
@ -236,10 +255,10 @@ TIFFYCbCrToRGBInit(TIFFYCbCrToRGB* ycbcr, float *luma, float *refBlackWhite)
ycbcr->Cb_g_tab = ycbcr->Cr_g_tab + 256;
ycbcr->Y_tab = ycbcr->Cb_g_tab + 256;
{ float f1 = 2-2*LumaRed; int32 D1 = FIX(f1);
float f2 = LumaRed*f1/LumaGreen; int32 D2 = -FIX(f2);
float f3 = 2-2*LumaBlue; int32 D3 = FIX(f3);
float f4 = LumaBlue*f3/LumaGreen; int32 D4 = -FIX(f4);
{ float f1 = 2-2*LumaRed; int32 D1 = FIX(CLAMP(f1,0.0F,2.0F));
float f2 = LumaRed*f1/LumaGreen; int32 D2 = -FIX(CLAMP(f2,0.0F,2.0F));
float f3 = 2-2*LumaBlue; int32 D3 = FIX(CLAMP(f3,0.0F,2.0F));
float f4 = LumaBlue*f3/LumaGreen; int32 D4 = -FIX(CLAMP(f4,0.0F,2.0F));
int x;
#undef LumaBlue
@ -254,17 +273,20 @@ TIFFYCbCrToRGBInit(TIFFYCbCrToRGB* ycbcr, float *luma, float *refBlackWhite)
* constructing tables indexed by the raw pixel data.
*/
for (i = 0, x = -128; i < 256; i++, x++) {
int32 Cr = (int32)Code2V(x, refBlackWhite[4] - 128.0F,
refBlackWhite[5] - 128.0F, 127);
int32 Cb = (int32)Code2V(x, refBlackWhite[2] - 128.0F,
refBlackWhite[3] - 128.0F, 127);
int32 Cr = (int32)CLAMPw(Code2V(x, refBlackWhite[4] - 128.0F,
refBlackWhite[5] - 128.0F, 127),
-128.0F * 32, 128.0F * 32);
int32 Cb = (int32)CLAMPw(Code2V(x, refBlackWhite[2] - 128.0F,
refBlackWhite[3] - 128.0F, 127),
-128.0F * 32, 128.0F * 32);
ycbcr->Cr_r_tab[i] = (int32)((D1*Cr + ONE_HALF)>>SHIFT);
ycbcr->Cb_b_tab[i] = (int32)((D3*Cb + ONE_HALF)>>SHIFT);
ycbcr->Cr_g_tab[i] = D2*Cr;
ycbcr->Cb_g_tab[i] = D4*Cb + ONE_HALF;
ycbcr->Y_tab[i] =
(int32)Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255);
(int32)CLAMPw(Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255),
-128.0F * 32, 128.0F * 32);
}
}

@ -1,4 +1,4 @@
/* $Id: tif_compress.c,v 1.22 2010-03-10 18:56:48 bfriesen Exp $ */
/* $Id: tif_compress.c,v 1.25 2016-10-25 20:04:22 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -82,10 +82,10 @@ TIFFNoDecode(TIFF* tif, const char* method)
TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
"Compression scheme %u %s decoding is not implemented",
tif->tif_dir.td_compression, method);
return (-1);
return (0);
}
int
static int
_TIFFNoFixupTags(TIFF* tif)
{
(void) tif;
@ -227,7 +227,7 @@ TIFFUnRegisterCODEC(TIFFCodec* c)
codec_t* cd;
codec_t** pcd;
for (pcd = &registeredCODECS; (cd = *pcd); pcd = &cd->next)
for (pcd = &registeredCODECS; (cd = *pcd) != NULL; pcd = &cd->next)
if (cd->info == c) {
*pcd = cd->next;
_TIFFfree(cd);

@ -0,0 +1,261 @@
/* libtiff/tif_config.h.cmake.in. Not generated, but originated from autoheader. */
/* This file must be kept up-to-date with needed substitutions from libtiff/tif_config.h.in. */
/* Support CCITT Group 3 & 4 algorithms */
#cmakedefine CCITT_SUPPORT 1
/* Pick up YCbCr subsampling info from the JPEG data stream to support files
lacking the tag (default enabled). */
#cmakedefine CHECK_JPEG_YCBCR_SUBSAMPLING 1
/* enable partial strip reading for large strips (experimental) */
#cmakedefine CHUNKY_STRIP_READ_SUPPORT 1
/* Support C++ stream API (requires C++ compiler) */
#cmakedefine CXX_SUPPORT 1
/* enable deferred strip/tile offset/size loading (experimental) */
#cmakedefine DEFER_STRILE_LOAD 1
/* Define to 1 if you have the <assert.h> header file. */
#cmakedefine HAVE_ASSERT_H 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#cmakedefine HAVE_DLFCN_H 1
/* Define to 1 if you have the <fcntl.h> 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
/* Define to 1 if you have the <GLUT/glut.h> header file. */
#cmakedefine HAVE_GLUT_GLUT_H 1
/* Define to 1 if you have the <GL/glut.h> header file. */
#cmakedefine HAVE_GL_GLUT_H 1
/* Define to 1 if you have the <GL/glu.h> header file. */
#cmakedefine HAVE_GL_GLU_H 1
/* Define to 1 if you have the <GL/gl.h> header file. */
#cmakedefine HAVE_GL_GL_H 1
/* Define to 1 if you have the <inttypes.h> header file. */
#cmakedefine HAVE_INTTYPES_H 1
/* Define to 1 if you have the <io.h> 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 <limits.h> header file. */
#cmakedefine HAVE_LIMITS_H 1
/* Define to 1 if you have the <malloc.h> 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 <memory.h> 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
/* Define to 1 if you have the <OpenGL/glu.h> header file. */
#cmakedefine HAVE_OPENGL_GLU_H 1
/* Define to 1 if you have the <OpenGL/gl.h> 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 <search.h> header file. */
#cmakedefine HAVE_SEARCH_H 1
/* Define to 1 if you have the `setmode' function. */
#cmakedefine HAVE_SETMODE 1
/* 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 <stdint.h> 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 <strings.h> header file. */
#cmakedefine HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> 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 `strtoul' function. */
#cmakedefine HAVE_STRTOUL 1
/* Define to 1 if you have the `strtoull' function. */
#cmakedefine HAVE_STRTOULL 1
/* Define to 1 if you have the <sys/time.h> header file. */
#cmakedefine HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#cmakedefine HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#cmakedefine HAVE_UNISTD_H 1
/* 8/12 bit libjpeg dual mode enabled */
#cmakedefine JPEG_DUAL_MODE_8_12 1
/* 12bit libjpeg primary include file with path */
#define LIBJPEG_12_PATH @LIBJPEG_12_PATH@
/* Support LZMA2 compression */
#cmakedefine LZMA_SUPPORT 1
/* Name of package */
#define PACKAGE "@PACKAGE_NAME@"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@"
/* Define to the full name of this package. */
#define PACKAGE_NAME "@PACKAGE_NAME@"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "@PACKAGE_STRING@"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "@PACKAGE_TARNAME@"
/* Define to the home page for this package. */
#define PACKAGE_URL "@PACKAGE_URL@"
/* Define to the version of this package. */
#define PACKAGE_VERSION "@PACKAGE_VERSION@"
/* The size of `signed int', as computed by sizeof. */
#define SIZEOF_SIGNED_INT @SIZEOF_SIGNED_INT@
/* The size of `signed long', as computed by sizeof. */
#define SIZEOF_SIGNED_LONG @SIZEOF_SIGNED_LONG@
/* 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@
/* The size of `unsigned int', as computed by sizeof. */
#define SIZEOF_UNSIGNED_INT @SIZEOF_UNSIGNED_INT@
/* The size of `unsigned long', as computed by sizeof. */
#define SIZEOF_UNSIGNED_LONG @SIZEOF_UNSIGNED_LONG@
/* The size of `unsigned long long', as computed by sizeof. */
#define SIZEOF_UNSIGNED_LONG_LONG @SIZEOF_UNSIGNED_LONG_LONG@
/* The size of `unsigned short', as computed by sizeof. */
#define SIZEOF_UNSIGNED_SHORT @SIZEOF_UNSIGNED_SHORT@
/* Default size of the strip in bytes (when strip chopping enabled) */
#define STRIP_SIZE_DEFAULT @STRIP_SIZE_DEFAULT@
/* Signed 32-bit type formatter */
#define TIFF_INT32_FORMAT "@TIFF_INT32_FORMAT@"
/* Signed 64-bit type formatter */
#define TIFF_INT64_FORMAT "@TIFF_INT64_FORMAT@"
/* Pointer difference type formatter */
#define TIFF_PTRDIFF_FORMAT "@TIFF_PTRDIFF_FORMAT@"
/* Unsigned size type formatter */
#define TIFF_SIZE_FORMAT "@TIFF_SIZE_FORMAT@"
/* Signed size type formatter */
#define TIFF_SSIZE_FORMAT "@TIFF_SSIZE_FORMAT@"
/* Unsigned 32-bit type formatter */
#define TIFF_UINT32_FORMAT "@TIFF_UINT32_FORMAT@"
/* Unsigned 64-bit type formatter */
#define TIFF_UINT64_FORMAT "@TIFF_UINT64_FORMAT@"
/* Unsigned 8-bit type */
#define TIFF_UINT8_T @TIFF_UINT8_T@
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
#cmakedefine TM_IN_SYS_TIME 1
/* define to use win32 IO system */
#cmakedefine USE_WIN32_FILEIO 1
/* Version number of package */
#define VERSION "@PACKAGE_VERSION@"
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
# undef WORDS_BIGENDIAN
# endif
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
#define _FILE_OFFSET_BITS @FILE_OFFSET_BITS@
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#define inline @INLINE_KEYWORD@
#endif
/* Define to `long int' if <sys/types.h> does not define. */
#undef off_t
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t

@ -1,162 +0,0 @@
/* libtiff/tif_config.h. Generated from tif_config.h.in by configure. */
/* libtiff/tif_config.h.in. Generated from configure.ac by autoheader. */
/* Support CCITT Group 3 & 4 algorithms */
#define CCITT_SUPPORT 1
/* Pick up YCbCr subsampling info from the JPEG data stream to support files
lacking the tag (default enabled). */
#define CHECK_JPEG_YCBCR_SUBSAMPLING 1
/* enable partial strip reading for large strips (experimental) */
#undef CHUNKY_STRIP_READ_SUPPORT
/* Treat extra sample as alpha (default enabled). The RGBA interface will
treat a fourth sample with no EXTRASAMPLE_ value as being ASSOCALPHA. Many
packages produce RGBA files but don't mark the alpha properly. */
#define DEFAULT_EXTRASAMPLE_AS_ALPHA 1
/* enable deferred strip/tile offset/size loading (experimental) */
#undef DEFER_STRILE_LOAD
/* Define to 1 if you have the <assert.h> header file. */
#cmakedefine HAVE_ASSERT_H
/* Define to 1 if you have the <fcntl.h> header file. */
#cmakedefine HAVE_FCNTL_H
/* Define as 0 or 1 according to the floating point format suported by the
machine */
#define HAVE_IEEEFP 1
/* Define to 1 if you have the <io.h> header file. */
#cmakedefine HAVE_IO_H
/* Define to 1 if you have the `jbg_newlen' function. */
#cmakedefine HAVE_JBG_NEWLEN
/* Define to 1 if you have the `mmap' function. */
#cmakedefine HAVE_MMAP
/* Define to 1 if you have the <search.h> header file. */
#cmakedefine HAVE_SEARCH_H
/* Define to 1 if you have the <string.h> header file. */
#cmakedefine HAVE_STRING_H
/* Define to 1 if you have the <sys/types.h> header file. */
#cmakedefine HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#ifndef HAVE_UNISTD_H
#cmakedefine HAVE_UNISTD_H
#endif
/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian
(Intel) */
#define HOST_BIGENDIAN @WORDS_BIGENDIAN@
/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
#define HOST_FILLORDER FILLORDER_LSB2MSB
/* Support ISO JBIG compression (requires JBIG-KIT library) */
#undef JBIG_SUPPORT
/* 8/12 bit libjpeg dual mode enabled */
/* #undef JPEG_DUAL_MODE_8_12 */
/* Support JPEG compression (requires IJG JPEG library) */
#undef JPEG_SUPPORT
/* 12bit libjpeg primary include file with path */
/* #undef LIBJPEG_12_PATH */
/* Support LogLuv high dynamic range encoding */
#define LOGLUV_SUPPORT 1
/* Support LZMA2 compression */
/* #undef LZMA_SUPPORT */
/* Support LZW algorithm */
#define LZW_SUPPORT 1
/* Support Microsoft Document Imaging format */
#define MDI_SUPPORT 1
/* Support NeXT 2-bit RLE algorithm */
#define NEXT_SUPPORT 1
/* Support Old JPEG compresson (read-only) */
#undef OJPEG_SUPPORT
/* Support Macintosh PackBits algorithm */
#define PACKBITS_SUPPORT 1
/* Support Pixar log-format algorithm (requires Zlib) */
#define PIXARLOG_SUPPORT 1
/* The size of `unsigned long', as computed by sizeof. */
#define SIZEOF_UNSIGNED_LONG 8
/* Support strip chopping (whether or not to convert single-strip uncompressed
images to mutiple strips of specified size to reduce memory usage) */
#define STRIPCHOP_DEFAULT TIFF_STRIPCHOP
/* Default size of the strip in bytes (when strip chopping enabled) */
//#define STRIP_SIZE_DEFAULT 8192
/* Support ThunderScan 4-bit RLE algorithm */
#define THUNDER_SUPPORT 1
/* Signed 8-bit type */
#define TIFF_INT8_T signed char
/* Signed 16-bit type */
#define TIFF_INT16_T signed short
/* Signed 32-bit type */
#define TIFF_INT32_T signed int
/* Signed size type */
#define TIFF_SSIZE_T size_t
/* Unsigned 8-bit type */
#define TIFF_UINT8_T unsigned char
/* Unsigned 16-bit type */
#define TIFF_UINT16_T unsigned short
/* Unsigned 32-bit type */
#define TIFF_UINT32_T unsigned int
#ifdef _MSC_VER
/* Signed 64-bit type */
# define TIFF_INT64_T signed __int64
/* Unsigned 64-bit type */
# define TIFF_UINT64_T unsigned __int64
#else
/* Signed 64-bit type */
# define TIFF_INT64_T long long
/* Signed 64-bit type */
# define TIFF_UINT64_T unsigned long long
#endif
/* Signed 64-bit type formatter */
/* Unsigned 64-bit type formatter */
#if defined _MSC_VER || defined __MINGW__ || defined __MINGW32__
# define TIFF_UINT64_FORMAT "%I64u"
# define TIFF_SSIZE_FORMAT "%Iu"
#else
# define TIFF_UINT64_FORMAT "%llu"
# define TIFF_SSIZE_FORMAT "%zd"
#endif
/* define to use win32 IO system */
#cmakedefine USE_WIN32_FILEIO
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#cmakedefine WORDS_BIGENDIAN 1
/* Support Deflate compression */
#define ZIP_SUPPORT 1

@ -1,4 +1,4 @@
/* $Id: tif_dir.c,v 1.113 2012-06-14 20:32:53 fwarmerdam Exp $ */
/* $Id: tif_dir.c,v 1.131 2017-07-11 21:38:04 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -31,6 +31,7 @@
* (and also some miscellaneous stuff)
*/
#include "tiffiop.h"
#include <float.h>
/*
* These are used in the backwards compatibility code...
@ -43,8 +44,10 @@
static void
setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size)
{
if (*vpp)
_TIFFfree(*vpp), *vpp = 0;
if (*vpp) {
_TIFFfree(*vpp);
*vpp = 0;
}
if (vp) {
tmsize_t bytes = (tmsize_t)(nmemb * elem_size);
if (elem_size && bytes / elem_size == nmemb)
@ -57,13 +60,13 @@ void _TIFFsetByteArray(void** vpp, void* vp, uint32 n)
{ setByteArray(vpp, vp, n, 1); }
void _TIFFsetString(char** cpp, char* cp)
{ setByteArray((void**) cpp, (void*) cp, strlen(cp)+1, 1); }
void _TIFFsetNString(char** cpp, char* cp, uint32 n)
static void _TIFFsetNString(char** cpp, char* cp, uint32 n)
{ setByteArray((void**) cpp, (void*) cp, n, 1); }
void _TIFFsetShortArray(uint16** wpp, uint16* wp, uint32 n)
{ setByteArray((void**) wpp, (void*) wp, n, sizeof (uint16)); }
void _TIFFsetLongArray(uint32** lpp, uint32* lp, uint32 n)
{ setByteArray((void**) lpp, (void*) lp, n, sizeof (uint32)); }
void _TIFFsetLong8Array(uint64** lpp, uint64* lp, uint32 n)
static void _TIFFsetLong8Array(uint64** lpp, uint64* lp, uint32 n)
{ setByteArray((void**) lpp, (void*) lp, n, sizeof (uint64)); }
void _TIFFsetFloatArray(float** fpp, float* fp, uint32 n)
{ setByteArray((void**) fpp, (void*) fp, n, sizeof (float)); }
@ -152,6 +155,15 @@ bad:
return (0);
}
static float TIFFClampDoubleToFloat( double val )
{
if( val > FLT_MAX )
return FLT_MAX;
if( val < -FLT_MAX )
return -FLT_MAX;
return (float)val;
}
static int
_TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
{
@ -160,15 +172,17 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
TIFFDirectory* td = &tif->tif_dir;
int status = 1;
uint32 v32, i, v;
double dblval;
char* s;
const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
uint32 standard_tag = tag;
if( fip == NULL ) /* cannot happen since OkToChangeTag() already checks it */
return 0;
/*
* We want to force the custom code to be used for custom
* fields even if the tag happens to match a well known
* one - important for reinterpreted handling of standard
* tag values in custom directories (ie. EXIF)
* tag values in custom directories (i.e. EXIF)
*/
if (fip->field_bit == FIELD_CUSTOM) {
standard_tag = 0;
@ -252,6 +266,28 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
v = (uint16) va_arg(ap, uint16_vap);
if (v == 0)
goto badvalue;
if( v != td->td_samplesperpixel )
{
/* See http://bugzilla.maptools.org/show_bug.cgi?id=2500 */
if( td->td_sminsamplevalue != NULL )
{
TIFFWarningExt(tif->tif_clientdata,module,
"SamplesPerPixel tag value is changing, "
"but SMinSampleValue tag was read with a different value. Cancelling it");
TIFFClrFieldBit(tif,FIELD_SMINSAMPLEVALUE);
_TIFFfree(td->td_sminsamplevalue);
td->td_sminsamplevalue = NULL;
}
if( td->td_smaxsamplevalue != NULL )
{
TIFFWarningExt(tif->tif_clientdata,module,
"SamplesPerPixel tag value is changing, "
"but SMaxSampleValue tag was read with a different value. Cancelling it");
TIFFClrFieldBit(tif,FIELD_SMAXSAMPLEVALUE);
_TIFFfree(td->td_smaxsamplevalue);
td->td_smaxsamplevalue = NULL;
}
}
td->td_samplesperpixel = (uint16) v;
break;
case TIFFTAG_ROWSPERSTRIP:
@ -283,10 +319,16 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
setDoubleArrayOneValue(&td->td_smaxsamplevalue, va_arg(ap, double), td->td_samplesperpixel);
break;
case TIFFTAG_XRESOLUTION:
td->td_xresolution = (float) va_arg(ap, double);
dblval = va_arg(ap, double);
if( dblval < 0 )
goto badvaluedouble;
td->td_xresolution = TIFFClampDoubleToFloat( dblval );
break;
case TIFFTAG_YRESOLUTION:
td->td_yresolution = (float) va_arg(ap, double);
dblval = va_arg(ap, double);
if( dblval < 0 )
goto badvaluedouble;
td->td_yresolution = TIFFClampDoubleToFloat( dblval );
break;
case TIFFTAG_PLANARCONFIG:
v = (uint16) va_arg(ap, uint16_vap);
@ -295,10 +337,10 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
td->td_planarconfig = (uint16) v;
break;
case TIFFTAG_XPOSITION:
td->td_xposition = (float) va_arg(ap, double);
td->td_xposition = TIFFClampDoubleToFloat( va_arg(ap, double) );
break;
case TIFFTAG_YPOSITION:
td->td_yposition = (float) va_arg(ap, double);
td->td_yposition = TIFFClampDoubleToFloat( va_arg(ap, double) );
break;
case TIFFTAG_RESOLUTIONUNIT:
v = (uint16) va_arg(ap, uint16_vap);
@ -394,7 +436,7 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
if ((tif->tif_flags & TIFF_INSUBIFD) == 0) {
td->td_nsubifd = (uint16) va_arg(ap, uint16_vap);
_TIFFsetLong8Array(&td->td_subifd, (uint64*) va_arg(ap, uint64*),
(long) td->td_nsubifd);
(uint32) td->td_nsubifd);
} else {
TIFFErrorExt(tif->tif_clientdata, module,
"%s: Sorry, cannot nest SubIFDs",
@ -413,7 +455,7 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
for (i = 0; i < v; i++)
_TIFFsetShortArray(&td->td_transferfunction[i],
va_arg(ap, uint16*), 1L<<td->td_bitspersample);
va_arg(ap, uint16*), 1U<<td->td_bitspersample);
break;
case TIFFTAG_REFERENCEBLACKWHITE:
/* XXX should check for null range */
@ -449,11 +491,11 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
* happens, for example, when tiffcp is used to convert between
* compression schemes and codec-specific tags are blindly copied.
*/
if(fip == NULL || fip->field_bit != FIELD_CUSTOM) {
if(fip->field_bit != FIELD_CUSTOM) {
TIFFErrorExt(tif->tif_clientdata, module,
"%s: Invalid %stag \"%s\" (not supported by codec)",
tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
fip ? fip->field_name : "Unknown");
fip->field_name);
status = 0;
break;
}
@ -571,10 +613,10 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
handled this way ... likely best if we move it into
the directory structure with an explicit field in
libtiff 4.1 and assign it a FIELD_ value */
uint16 v[2];
v[0] = (uint16)va_arg(ap, int);
v[1] = (uint16)va_arg(ap, int);
_TIFFmemcpy(tv->value, &v, 4);
uint16 v2[2];
v2[0] = (uint16)va_arg(ap, int);
v2[1] = (uint16)va_arg(ap, int);
_TIFFmemcpy(tv->value, &v2, 4);
}
else if (fip->field_passcount
@ -592,66 +634,66 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
case TIFF_BYTE:
case TIFF_UNDEFINED:
{
uint8 v = (uint8)va_arg(ap, int);
_TIFFmemcpy(val, &v, tv_size);
uint8 v2 = (uint8)va_arg(ap, int);
_TIFFmemcpy(val, &v2, tv_size);
}
break;
case TIFF_SBYTE:
{
int8 v = (int8)va_arg(ap, int);
_TIFFmemcpy(val, &v, tv_size);
int8 v2 = (int8)va_arg(ap, int);
_TIFFmemcpy(val, &v2, tv_size);
}
break;
case TIFF_SHORT:
{
uint16 v = (uint16)va_arg(ap, int);
_TIFFmemcpy(val, &v, tv_size);
uint16 v2 = (uint16)va_arg(ap, int);
_TIFFmemcpy(val, &v2, tv_size);
}
break;
case TIFF_SSHORT:
{
int16 v = (int16)va_arg(ap, int);
_TIFFmemcpy(val, &v, tv_size);
int16 v2 = (int16)va_arg(ap, int);
_TIFFmemcpy(val, &v2, tv_size);
}
break;
case TIFF_LONG:
case TIFF_IFD:
{
uint32 v = va_arg(ap, uint32);
_TIFFmemcpy(val, &v, tv_size);
uint32 v2 = va_arg(ap, uint32);
_TIFFmemcpy(val, &v2, tv_size);
}
break;
case TIFF_SLONG:
{
int32 v = va_arg(ap, int32);
_TIFFmemcpy(val, &v, tv_size);
int32 v2 = va_arg(ap, int32);
_TIFFmemcpy(val, &v2, tv_size);
}
break;
case TIFF_LONG8:
case TIFF_IFD8:
{
uint64 v = va_arg(ap, uint64);
_TIFFmemcpy(val, &v, tv_size);
uint64 v2 = va_arg(ap, uint64);
_TIFFmemcpy(val, &v2, tv_size);
}
break;
case TIFF_SLONG8:
{
int64 v = va_arg(ap, int64);
_TIFFmemcpy(val, &v, tv_size);
int64 v2 = va_arg(ap, int64);
_TIFFmemcpy(val, &v2, tv_size);
}
break;
case TIFF_RATIONAL:
case TIFF_SRATIONAL:
case TIFF_FLOAT:
{
float v = (float)va_arg(ap, double);
_TIFFmemcpy(val, &v, tv_size);
float v2 = TIFFClampDoubleToFloat(va_arg(ap, double));
_TIFFmemcpy(val, &v2, tv_size);
}
break;
case TIFF_DOUBLE:
{
double v = va_arg(ap, double);
_TIFFmemcpy(val, &v, tv_size);
double v2 = va_arg(ap, double);
_TIFFmemcpy(val, &v2, tv_size);
}
break;
default:
@ -664,9 +706,9 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
}
}
if (status) {
const TIFFField* fip=TIFFFieldWithTag(tif,tag);
if (fip)
TIFFSetFieldBit(tif, fip->field_bit);
const TIFFField* fip2=TIFFFieldWithTag(tif,tag);
if (fip2)
TIFFSetFieldBit(tif, fip2->field_bit);
tif->tif_flags |= TIFF_DIRTYDIRECT;
}
@ -675,21 +717,31 @@ end:
return (status);
badvalue:
{
const TIFFField* fip=TIFFFieldWithTag(tif,tag);
const TIFFField* fip2=TIFFFieldWithTag(tif,tag);
TIFFErrorExt(tif->tif_clientdata, module,
"%s: Bad value %u for \"%s\" tag",
tif->tif_name, v,
fip ? fip->field_name : "Unknown");
fip2 ? fip2->field_name : "Unknown");
va_end(ap);
}
return (0);
badvalue32:
{
const TIFFField* fip=TIFFFieldWithTag(tif,tag);
const TIFFField* fip2=TIFFFieldWithTag(tif,tag);
TIFFErrorExt(tif->tif_clientdata, module,
"%s: Bad value %u for \"%s\" tag",
tif->tif_name, v32,
fip ? fip->field_name : "Unknown");
fip2 ? fip2->field_name : "Unknown");
va_end(ap);
}
return (0);
badvaluedouble:
{
const TIFFField* fip2=TIFFFieldWithTag(tif,tag);
TIFFErrorExt(tif->tif_clientdata, module,
"%s: Bad value %f for \"%s\" tag",
tif->tif_name, dblval,
fip2 ? fip2->field_name : "Unknown");
va_end(ap);
}
return (0);
@ -809,12 +861,42 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
int ret_val = 1;
uint32 standard_tag = tag;
const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY);
if( fip == NULL ) /* cannot happen since TIFFGetField() already checks it */
return 0;
if( tag == TIFFTAG_NUMBEROFINKS )
{
int i;
for (i = 0; i < td->td_customValueCount; i++) {
uint16 val;
TIFFTagValue *tv = td->td_customValues + i;
if (tv->info->field_tag != tag)
continue;
if( tv->value == NULL )
return 0;
val = *(uint16 *)tv->value;
/* Truncate to SamplesPerPixel, since the */
/* setting code for INKNAMES assume that there are SamplesPerPixel */
/* inknames. */
/* Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2599 */
if( val > td->td_samplesperpixel )
{
TIFFWarningExt(tif->tif_clientdata,"_TIFFVGetField",
"Truncating NumberOfInks from %u to %u",
val, td->td_samplesperpixel);
val = td->td_samplesperpixel;
}
*va_arg(ap, uint16*) = val;
return 1;
}
return 0;
}
/*
* We want to force the custom code to be used for custom
* fields even if the tag happens to match a well known
* one - important for reinterpreted handling of standard
* tag values in custom directories (ie. EXIF)
* tag values in custom directories (i.e. EXIF)
*/
if (fip->field_bit == FIELD_CUSTOM) {
standard_tag = 0;
@ -865,7 +947,7 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
*va_arg(ap, double**) = td->td_sminsamplevalue;
else
{
/* libtiff historially treats this as a single value. */
/* libtiff historically treats this as a single value. */
uint16 i;
double v = td->td_sminsamplevalue[0];
for (i=1; i < td->td_samplesperpixel; ++i)
@ -879,7 +961,7 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
*va_arg(ap, double**) = td->td_smaxsamplevalue;
else
{
/* libtiff historially treats this as a single value. */
/* libtiff historically treats this as a single value. */
uint16 i;
double v = td->td_smaxsamplevalue[0];
for (i=1; i < td->td_samplesperpixel; ++i)
@ -1006,14 +1088,14 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
* get a tag that is not valid for the image's
* codec then we'll arrive here.
*/
if( fip == NULL || fip->field_bit != FIELD_CUSTOM )
if( fip->field_bit != FIELD_CUSTOM )
{
TIFFErrorExt(tif->tif_clientdata, "_TIFFVGetField",
"%s: Invalid %stag \"%s\" "
"(not supported by codec)",
tif->tif_name,
isPseudoTag(tag) ? "pseudo-" : "",
fip ? fip->field_name : "Unknown");
fip->field_name);
ret_val = 0;
break;
}
@ -1302,8 +1384,20 @@ TIFFDefaultDirectory(TIFF* tif)
tif->tif_tagmethods.printdir = NULL;
/*
* Give client code a chance to install their own
* tag extensions & methods, prior to compression overloads.
* tag extensions & methods, prior to compression overloads,
* but do some prior cleanup first. (http://trac.osgeo.org/gdal/ticket/5054)
*/
if (tif->tif_nfieldscompat > 0) {
uint32 i;
for (i = 0; i < tif->tif_nfieldscompat; i++) {
if (tif->tif_fieldscompat[i].allocated_size)
_TIFFfree(tif->tif_fieldscompat[i].fields);
}
_TIFFfree(tif->tif_fieldscompat);
tif->tif_nfieldscompat = 0;
tif->tif_fieldscompat = NULL;
}
if (_TIFFextender)
(*_TIFFextender)(tif);
(void) TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
@ -1344,6 +1438,7 @@ TIFFAdvanceDirectory(TIFF* tif, uint64* nextdir, uint64* off)
if (((uint64)poffa!=poff)||(poffb<poffa)||(poffb<(tmsize_t)sizeof(uint16))||(poffb>tif->tif_size))
{
TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count");
*nextdir=0;
return(0);
}
_TIFFmemcpy(&dircount,tif->tif_base+poffa,sizeof(uint16));
@ -1453,7 +1548,8 @@ TIFFAdvanceDirectory(TIFF* tif, uint64* nextdir, uint64* off)
(void) TIFFSeekFile(tif,
dircount16*20, SEEK_CUR);
if (!ReadOK(tif, nextdir, sizeof (uint64))) {
TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
TIFFErrorExt(tif->tif_clientdata, module,
"%s: Error fetching directory link",
tif->tif_name);
return (0);
}
@ -1470,6 +1566,7 @@ TIFFAdvanceDirectory(TIFF* tif, uint64* nextdir, uint64* off)
uint16
TIFFNumberOfDirectories(TIFF* tif)
{
static const char module[] = "TIFFNumberOfDirectories";
uint64 nextdir;
uint16 n;
if (!(tif->tif_flags&TIFF_BIGTIFF))
@ -1478,7 +1575,18 @@ TIFFNumberOfDirectories(TIFF* tif)
nextdir = tif->tif_header.big.tiff_diroff;
n = 0;
while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL))
n++;
{
if (n != 65535) {
++n;
}
else
{
TIFFErrorExt(tif->tif_clientdata, module,
"Directory count exceeded 65535 limit,"
" giving up on counting.");
return (65535);
}
}
return (n);
}

@ -1,4 +1,4 @@
/* $Id: tif_dir.h,v 1.54 2011-02-18 20:53:05 fwarmerdam Exp $ */
/* $Id: tif_dir.h,v 1.55 2017-06-01 12:44:04 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -291,6 +291,7 @@ struct _TIFFField {
extern int _TIFFMergeFields(TIFF*, const TIFFField[], uint32);
extern const TIFFField* _TIFFFindOrRegisterField(TIFF *, uint32, TIFFDataType);
extern TIFFField* _TIFFCreateAnonField(TIFF *, uint32, TIFFDataType);
extern int _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag);
#if defined(__cplusplus)
}

@ -1,4 +1,4 @@
/* $Id: tif_dirinfo.c,v 1.114 2011-05-17 00:21:17 fwarmerdam Exp $ */
/* $Id: tif_dirinfo.c,v 1.127 2017-06-01 12:44:04 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -37,15 +37,23 @@
*
* NOTE: The second field (field_readcount) and third field (field_writecount)
* sometimes use the values TIFF_VARIABLE (-1), TIFF_VARIABLE2 (-3)
* and TIFFTAG_SPP (-2). The macros should be used but would throw off
* the formatting of the code, so please interprete the -1, -2 and -3
* and TIFF_SPP (-2). The macros should be used but would throw off
* the formatting of the code, so please interpret the -1, -2 and -3
* values accordingly.
*/
static TIFFFieldArray tiffFieldArray;
static TIFFFieldArray exifFieldArray;
static TIFFField
/* const object should be initialized */
#ifdef _MSC_VER
#pragma warning( push )
#pragma warning( disable : 4132 )
#endif
static const TIFFFieldArray tiffFieldArray;
static const TIFFFieldArray exifFieldArray;
#ifdef _MSC_VER
#pragma warning( pop )
#endif
static const TIFFField
tiffFields[] = {
{ TIFFTAG_SUBFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_SUBFILETYPE, 1, 0, "SubfileType", NULL },
{ TIFFTAG_OSUBFILETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_SUBFILETYPE, 1, 0, "OldSubfileType", NULL },
@ -95,7 +103,7 @@ tiffFields[] = {
{ TIFFTAG_TILELENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDIMENSIONS, 0, 0, "TileLength", NULL },
{ TIFFTAG_TILEOFFSETS, -1, 1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPOFFSETS, 0, 0, "TileOffsets", NULL },
{ TIFFTAG_TILEBYTECOUNTS, -1, 1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "TileByteCounts", NULL },
{ TIFFTAG_SUBIFD, -1, -1, TIFF_IFD8, 0, TIFF_SETGET_C16_IFD8, TIFF_SETGET_UNDEFINED, FIELD_SUBIFD, 1, 1, "SubIFD", &tiffFieldArray },
{ TIFFTAG_SUBIFD, -1, -1, TIFF_IFD8, 0, TIFF_SETGET_C16_IFD8, TIFF_SETGET_UNDEFINED, FIELD_SUBIFD, 1, 1, "SubIFD", (TIFFFieldArray*) &tiffFieldArray },
{ TIFFTAG_INKSET, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InkSet", NULL },
{ TIFFTAG_INKNAMES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_C16_ASCII, TIFF_SETGET_UNDEFINED, FIELD_INKNAMES, 1, 1, "InkNames", NULL },
{ TIFFTAG_NUMBEROFINKS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "NumberOfInks", NULL },
@ -128,11 +136,13 @@ tiffFields[] = {
{ TIFFTAG_PIXAR_FOVCOT, 1, 1, TIFF_FLOAT, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FieldOfViewCotangent", NULL },
{ TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToScreen", NULL },
{ TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToCamera", NULL },
{ TIFFTAG_CFAREPEATPATTERNDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CFARepeatPatternDim", NULL },
{ TIFFTAG_CFAPATTERN, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CFAPattern" , NULL},
{ TIFFTAG_COPYRIGHT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Copyright", NULL },
/* end Pixar tags */
{ TIFFTAG_RICHTIFFIPTC, -3, -3, TIFF_LONG, 0, TIFF_SETGET_C32_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "RichTIFFIPTC", NULL },
{ TIFFTAG_PHOTOSHOP, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "Photoshop", NULL },
{ TIFFTAG_EXIFIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "EXIFIFDOffset", &exifFieldArray },
{ TIFFTAG_EXIFIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "EXIFIFDOffset", (TIFFFieldArray*) &exifFieldArray },
{ TIFFTAG_ICCPROFILE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ICC Profile", NULL },
{ TIFFTAG_GPSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "GPSIFDOffset", NULL },
{ TIFFTAG_FAXRECVPARAMS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvParams", NULL },
@ -190,12 +200,26 @@ tiffFields[] = {
{ TIFFTAG_ASSHOTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotPreProfileMatrix", NULL },
{ TIFFTAG_CURRENTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CurrentICCProfile", NULL },
{ TIFFTAG_CURRENTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CurrentPreProfileMatrix", NULL },
{ TIFFTAG_PERSAMPLE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "PerSample", NULL},
/* end DNG tags */
/* begin TIFF/FX tags */
{ TIFFTAG_INDEXED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "Indexed", NULL },
{ TIFFTAG_GLOBALPARAMETERSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "GlobalParametersIFD", NULL },
{ TIFFTAG_PROFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ProfileType", NULL },
{ TIFFTAG_FAXPROFILE, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "FaxProfile", NULL },
{ TIFFTAG_CODINGMETHODS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CodingMethods", NULL },
{ TIFFTAG_VERSIONYEAR, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "VersionYear", NULL },
{ TIFFTAG_MODENUMBER, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ModeNumber", NULL },
{ TIFFTAG_DECODE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "Decode", NULL },
{ TIFFTAG_IMAGEBASECOLOR, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ImageBaseColor", NULL },
{ TIFFTAG_T82OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "T82Options", NULL },
{ TIFFTAG_STRIPROWCOUNTS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "StripRowCounts", NULL },
{ TIFFTAG_IMAGELAYER, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ImageLayer", NULL },
/* end TIFF/FX tags */
/* begin pseudo tags */
{ TIFFTAG_PERSAMPLE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "PerSample", NULL},
};
static TIFFField
static const TIFFField
exifFields[] = {
{ EXIFTAG_EXPOSURETIME, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureTime", NULL },
{ EXIFTAG_FNUMBER, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FNumber", NULL },
@ -255,13 +279,13 @@ exifFields[] = {
{ EXIFTAG_IMAGEUNIQUEID, 33, 33, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageUniqueID", NULL }
};
static TIFFFieldArray
tiffFieldArray = { tfiatImage, 0, TIFFArrayCount(tiffFields), tiffFields };
static TIFFFieldArray
exifFieldArray = { tfiatExif, 0, TIFFArrayCount(exifFields), exifFields };
static const TIFFFieldArray
tiffFieldArray = { tfiatImage, 0, TIFFArrayCount(tiffFields), (TIFFField*) tiffFields };
static const TIFFFieldArray
exifFieldArray = { tfiatExif, 0, TIFFArrayCount(exifFields), (TIFFField*) exifFields };
/*
* We have our own local lfind() equivelent to avoid subtle differences
* We have our own local lfind() equivalent to avoid subtle differences
* in types passed to lfind() on different systems.
*/
@ -348,7 +372,7 @@ _TIFFMergeFields(TIFF* tif, const TIFFField info[], uint32 n)
{
static const char module[] = "_TIFFMergeFields";
static const char reason[] = "for fields array";
TIFFField** tp;
/* TIFFField** tp; */
uint32 i;
tif->tif_foundfield = NULL;
@ -369,7 +393,7 @@ _TIFFMergeFields(TIFF* tif, const TIFFField info[], uint32 n)
return 0;
}
tp = tif->tif_fields + tif->tif_nfields;
/* tp = tif->tif_fields + tif->tif_nfields; */
for (i = 0; i < n; i++) {
const TIFFField *fip =
TIFFFindField(tif, info[i].field_tag, TIFF_ANY);
@ -505,7 +529,7 @@ TIFFFindField(TIFF* tif, uint32 tag, TIFFDataType dt)
return tif->tif_foundfield = (ret ? *ret : NULL);
}
const TIFFField*
static const TIFFField*
_TIFFFindFieldByName(TIFF* tif, const char *field_name, TIFFDataType dt)
{
TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, 0, NULL, NULL};
@ -556,6 +580,42 @@ TIFFFieldWithName(TIFF* tif, const char *field_name)
return (fip);
}
uint32
TIFFFieldTag(const TIFFField* fip)
{
return fip->field_tag;
}
const char *
TIFFFieldName(const TIFFField* fip)
{
return fip->field_name;
}
TIFFDataType
TIFFFieldDataType(const TIFFField* fip)
{
return fip->field_type;
}
int
TIFFFieldPassCount(const TIFFField* fip)
{
return fip->field_passcount;
}
int
TIFFFieldReadCount(const TIFFField* fip)
{
return fip->field_readcount;
}
int
TIFFFieldWriteCount(const TIFFField* fip)
{
return fip->field_writecount;
}
const TIFFField*
_TIFFFindOrRegisterField(TIFF *tif, uint32 tag, TIFFDataType dt)
@ -661,7 +721,7 @@ _TIFFCreateAnonField(TIFF *tif, uint32 tag, TIFFDataType field_type)
* note that this name is a special sign to TIFFClose() and
* _TIFFSetupFields() to free the field
*/
sprintf(fld->field_name, "Tag %d", (int) tag);
(void) snprintf(fld->field_name, 32, "Tag %d", (int) tag);
return fld;
}
@ -896,6 +956,109 @@ TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], uint32 n)
return 0;
}
int
_TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag)
{
/* Filter out non-codec specific tags */
switch (tag) {
/* Shared tags */
case TIFFTAG_PREDICTOR:
/* JPEG tags */
case TIFFTAG_JPEGTABLES:
/* OJPEG tags */
case TIFFTAG_JPEGIFOFFSET:
case TIFFTAG_JPEGIFBYTECOUNT:
case TIFFTAG_JPEGQTABLES:
case TIFFTAG_JPEGDCTABLES:
case TIFFTAG_JPEGACTABLES:
case TIFFTAG_JPEGPROC:
case TIFFTAG_JPEGRESTARTINTERVAL:
/* CCITT* */
case TIFFTAG_BADFAXLINES:
case TIFFTAG_CLEANFAXDATA:
case TIFFTAG_CONSECUTIVEBADFAXLINES:
case TIFFTAG_GROUP3OPTIONS:
case TIFFTAG_GROUP4OPTIONS:
break;
default:
return 1;
}
/* Check if codec specific tags are allowed for the current
* compression scheme (codec) */
switch (tif->tif_dir.td_compression) {
case COMPRESSION_LZW:
if (tag == TIFFTAG_PREDICTOR)
return 1;
break;
case COMPRESSION_PACKBITS:
/* No codec-specific tags */
break;
case COMPRESSION_THUNDERSCAN:
/* No codec-specific tags */
break;
case COMPRESSION_NEXT:
/* No codec-specific tags */
break;
case COMPRESSION_JPEG:
if (tag == TIFFTAG_JPEGTABLES)
return 1;
break;
case COMPRESSION_OJPEG:
switch (tag) {
case TIFFTAG_JPEGIFOFFSET:
case TIFFTAG_JPEGIFBYTECOUNT:
case TIFFTAG_JPEGQTABLES:
case TIFFTAG_JPEGDCTABLES:
case TIFFTAG_JPEGACTABLES:
case TIFFTAG_JPEGPROC:
case TIFFTAG_JPEGRESTARTINTERVAL:
return 1;
}
break;
case COMPRESSION_CCITTRLE:
case COMPRESSION_CCITTRLEW:
case COMPRESSION_CCITTFAX3:
case COMPRESSION_CCITTFAX4:
switch (tag) {
case TIFFTAG_BADFAXLINES:
case TIFFTAG_CLEANFAXDATA:
case TIFFTAG_CONSECUTIVEBADFAXLINES:
return 1;
case TIFFTAG_GROUP3OPTIONS:
if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX3)
return 1;
break;
case TIFFTAG_GROUP4OPTIONS:
if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4)
return 1;
break;
}
break;
case COMPRESSION_JBIG:
/* No codec-specific tags */
break;
case COMPRESSION_DEFLATE:
case COMPRESSION_ADOBE_DEFLATE:
if (tag == TIFFTAG_PREDICTOR)
return 1;
break;
case COMPRESSION_PIXARLOG:
if (tag == TIFFTAG_PREDICTOR)
return 1;
break;
case COMPRESSION_SGILOG:
case COMPRESSION_SGILOG24:
/* No codec-specific tags */
break;
case COMPRESSION_LZMA:
if (tag == TIFFTAG_PREDICTOR)
return 1;
break;
}
return 0;
}
/* vim: set ts=8 sts=8 sw=8 noet: */
/*

@ -1,4 +1,4 @@
/* $Id: tif_dirread.c,v 1.174 2012-02-01 02:24:47 fwarmerdam Exp $ */
/* $Id: tif_dirread.c,v 1.218 2017-09-09 21:44:42 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -40,6 +40,8 @@
*/
#include "tiffiop.h"
#include <float.h>
#include <stdlib.h>
#define IGNORE 0 /* tag placeholder used below */
#define FAILED_FII ((uint32) -1)
@ -166,6 +168,8 @@ static int TIFFFetchSubjectDistance(TIFF*, TIFFDirEntry*);
static void ChopUpSingleUncompressedStrip(TIFF*);
static uint64 TIFFReadUInt64(const uint8 *value);
static int _TIFFFillStrilesInternal( TIFF *tif, int loadStripByteCount );
typedef union _UInt64Aligned_t
{
double d;
@ -633,6 +637,8 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryFloat(TIFF* tif, TIFFDirEntry* d
err=TIFFReadDirEntryCheckedDouble(tif,direntry,&m);
if (err!=TIFFReadDirEntryErrOk)
return(err);
if ((m > FLT_MAX) || (m < FLT_MIN))
return(TIFFReadDirEntryErrRange);
*value=(float)m;
return(TIFFReadDirEntryErrOk);
}
@ -762,13 +768,80 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8(TIFF* tif, TIFFDirEntry* di
}
}
static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value)
#define INITIAL_THRESHOLD (1024 * 1024)
#define THRESHOLD_MULTIPLIER 10
#define MAX_THRESHOLD (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * INITIAL_THRESHOLD)
static enum TIFFReadDirEntryErr TIFFReadDirEntryDataAndRealloc(
TIFF* tif, uint64 offset, tmsize_t size, void** pdest)
{
#if SIZEOF_VOIDP == 8 || SIZEOF_SIZE_T == 8
tmsize_t threshold = INITIAL_THRESHOLD;
#endif
tmsize_t already_read = 0;
assert( !isMapped(tif) );
if (!SeekOK(tif,offset))
return(TIFFReadDirEntryErrIo);
/* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */
/* so as to avoid allocating too much memory in case the file is too */
/* short. We could ask for the file size, but this might be */
/* expensive with some I/O layers (think of reading a gzipped file) */
/* Restrict to 64 bit processes, so as to avoid reallocs() */
/* on 32 bit processes where virtual memory is scarce. */
while( already_read < size )
{
void* new_dest;
tmsize_t bytes_read;
tmsize_t to_read = size - already_read;
#if SIZEOF_VOIDP == 8 || SIZEOF_SIZE_T == 8
if( to_read >= threshold && threshold < MAX_THRESHOLD )
{
to_read = threshold;
threshold *= THRESHOLD_MULTIPLIER;
}
#endif
new_dest = (uint8*) _TIFFrealloc(
*pdest, already_read + to_read);
if( new_dest == NULL )
{
TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
"Failed to allocate memory for %s "
"(%ld elements of %ld bytes each)",
"TIFFReadDirEntryArray",
(long) 1, (long) (already_read + to_read));
return TIFFReadDirEntryErrAlloc;
}
*pdest = new_dest;
bytes_read = TIFFReadFile(tif,
(char*)*pdest + already_read, to_read);
already_read += bytes_read;
if (bytes_read != to_read) {
return TIFFReadDirEntryErrIo;
}
}
return TIFFReadDirEntryErrOk;
}
static enum TIFFReadDirEntryErr TIFFReadDirEntryArrayWithLimit(
TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize,
void** value, uint64 maxcount)
{
int typesize;
uint32 datasize;
void* data;
uint64 target_count64;
typesize=TIFFDataWidth(direntry->tdir_type);
if ((direntry->tdir_count==0)||(typesize==0))
target_count64 = (direntry->tdir_count > maxcount) ?
maxcount : direntry->tdir_count;
if ((target_count64==0)||(typesize==0))
{
*value=0;
return(TIFFReadDirEntryErrOk);
@ -780,17 +853,30 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* d
* in either the current data type or the dest data type. This also
* avoids problems with overflow of tmsize_t on 32bit systems.
*/
if ((uint64)(2147483647/typesize)<direntry->tdir_count)
if ((uint64)(2147483647/typesize)<target_count64)
return(TIFFReadDirEntryErrSizesan);
if ((uint64)(2147483647/desttypesize)<direntry->tdir_count)
if ((uint64)(2147483647/desttypesize)<target_count64)
return(TIFFReadDirEntryErrSizesan);
*count=(uint32)direntry->tdir_count;
*count=(uint32)target_count64;
datasize=(*count)*typesize;
assert((tmsize_t)datasize>0);
if( isMapped(tif) && datasize > (uint32)tif->tif_size )
return TIFFReadDirEntryErrIo;
if( !isMapped(tif) &&
(((tif->tif_flags&TIFF_BIGTIFF) && datasize > 8) ||
(!(tif->tif_flags&TIFF_BIGTIFF) && datasize > 4)) )
{
data = NULL;
}
else
{
data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray");
if (data==0)
return(TIFFReadDirEntryErrAlloc);
}
if (!(tif->tif_flags&TIFF_BIGTIFF))
{
if (datasize<=4)
@ -801,7 +887,10 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* d
uint32 offset = direntry->tdir_offset.toff_long;
if (tif->tif_flags&TIFF_SWAB)
TIFFSwabLong(&offset);
if( isMapped(tif) )
err=TIFFReadDirEntryData(tif,(uint64)offset,(tmsize_t)datasize,data);
else
err=TIFFReadDirEntryDataAndRealloc(tif,(uint64)offset,(tmsize_t)datasize,&data);
if (err!=TIFFReadDirEntryErrOk)
{
_TIFFfree(data);
@ -819,7 +908,10 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* d
uint64 offset = direntry->tdir_offset.toff_long8;
if (tif->tif_flags&TIFF_SWAB)
TIFFSwabLong8(&offset);
err=TIFFReadDirEntryData(tif,offset,(tmsize_t)datasize,data);
if( isMapped(tif) )
err=TIFFReadDirEntryData(tif,(uint64)offset,(tmsize_t)datasize,data);
else
err=TIFFReadDirEntryDataAndRealloc(tif,(uint64)offset,(tmsize_t)datasize,&data);
if (err!=TIFFReadDirEntryErrOk)
{
_TIFFfree(data);
@ -831,6 +923,12 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* d
return(TIFFReadDirEntryErrOk);
}
static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value)
{
return TIFFReadDirEntryArrayWithLimit(tif, direntry, count,
desttypesize, value, ~((uint64)0));
}
static enum TIFFReadDirEntryErr TIFFReadDirEntryByteArray(TIFF* tif, TIFFDirEntry* direntry, uint8** value)
{
enum TIFFReadDirEntryErr err;
@ -1860,7 +1958,8 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntrySlongArray(TIFF* tif, TIFFDirEnt
return(TIFFReadDirEntryErrOk);
}
static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value)
static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8ArrayWithLimit(
TIFF* tif, TIFFDirEntry* direntry, uint64** value, uint64 maxcount)
{
enum TIFFReadDirEntryErr err;
uint32 count;
@ -1880,7 +1979,7 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEnt
default:
return(TIFFReadDirEntryErrType);
}
err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata);
err=TIFFReadDirEntryArrayWithLimit(tif,direntry,&count,8,&origdata,maxcount);
if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
{
*value=0;
@ -2026,6 +2125,11 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEnt
return(TIFFReadDirEntryErrOk);
}
static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value)
{
return TIFFReadDirEntryLong8ArrayWithLimit(tif, direntry, value, ~((uint64)0));
}
static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8Array(TIFF* tif, TIFFDirEntry* direntry, int64** value)
{
enum TIFFReadDirEntryErr err;
@ -2172,11 +2276,6 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8Array(TIFF* tif, TIFFDirEn
break;
}
_TIFFfree(origdata);
if (err!=TIFFReadDirEntryErrOk)
{
_TIFFfree(data);
return(err);
}
*value=data;
return(TIFFReadDirEntryErrOk);
}
@ -2409,16 +2508,18 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryFloatArray(TIFF* tif, TIFFDirEnt
ma=(double*)origdata;
mb=data;
for (n=0; n<count; n++)
*mb++=(float)(*ma++);
{
double val = *ma++;
if( val > FLT_MAX )
val = FLT_MAX;
else if( val < -FLT_MAX )
val = -FLT_MAX;
*mb++=(float)val;
}
}
break;
}
_TIFFfree(origdata);
if (err!=TIFFReadDirEntryErrOk)
{
_TIFFfree(data);
return(err);
}
*value=data;
return(TIFFReadDirEntryErrOk);
}
@ -2657,11 +2758,6 @@ TIFFReadDirEntryDoubleArray(TIFF* tif, TIFFDirEntry* direntry, double** value)
break;
}
_TIFFfree(origdata);
if (err!=TIFFReadDirEntryErrOk)
{
_TIFFfree(data);
return(err);
}
*value=data;
return(TIFFReadDirEntryErrOk);
}
@ -2723,11 +2819,6 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8Array(TIFF* tif, TIFFDirEntr
break;
}
_TIFFfree(origdata);
if (err!=TIFFReadDirEntryErrOk)
{
_TIFFfree(data);
return(err);
}
*value=data;
return(TIFFReadDirEntryErrOk);
}
@ -2741,7 +2832,7 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleShort(TIFF* tif, TIFFDi
if (direntry->tdir_count<(uint64)tif->tif_dir.td_samplesperpixel)
return(TIFFReadDirEntryErrCount);
err=TIFFReadDirEntryShortArray(tif,direntry,&m);
if (err!=TIFFReadDirEntryErrOk)
if (err!=TIFFReadDirEntryErrOk || m == NULL)
return(err);
na=m;
nb=tif->tif_dir.td_samplesperpixel;
@ -2890,7 +2981,10 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedRational(TIFF* tif, TIFFD
m.l = direntry->tdir_offset.toff_long8;
if (tif->tif_flags&TIFF_SWAB)
TIFFSwabArrayOfLong(m.i,2);
if (m.i[0]==0)
/* Not completely sure what we should do when m.i[1]==0, but some */
/* sanitizers do not like division by 0.0: */
/* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */
if (m.i[0]==0 || m.i[1]==0)
*value=0.0;
else
*value=(double)m.i[0]/(double)m.i[1];
@ -2918,7 +3012,10 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSrational(TIFF* tif, TIFF
m.l=direntry->tdir_offset.toff_long8;
if (tif->tif_flags&TIFF_SWAB)
TIFFSwabArrayOfLong(m.i,2);
if ((int32)m.i[0]==0)
/* Not completely sure what we should do when m.i[1]==0, but some */
/* sanitizers do not like division by 0.0: */
/* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */
if ((int32)m.i[0]==0 || m.i[1]==0)
*value=0.0;
else
*value=(double)((int32)m.i[0])/(double)m.i[1];
@ -3194,11 +3291,7 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong(int32 value)
/*
* Largest 32-bit unsigned integer value.
*/
#if defined(__WIN32__) && defined(_MSC_VER)
# define TIFF_UINT32_MAX 0xFFFFFFFFI64
#else
# define TIFF_UINT32_MAX 0xFFFFFFFFLL
#endif
#define TIFF_UINT32_MAX 0xFFFFFFFFU
static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeLongLong8(uint64 value)
@ -3212,7 +3305,7 @@ TIFFReadDirEntryCheckRangeLongLong8(uint64 value)
static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeLongSlong8(int64 value)
{
if ((value<0) || (value > TIFF_UINT32_MAX))
if ((value < 0) || (value > (int64) TIFF_UINT32_MAX))
return(TIFFReadDirEntryErrRange);
else
return(TIFFReadDirEntryErrOk);
@ -3229,19 +3322,21 @@ TIFFReadDirEntryCheckRangeSlongLong(uint32 value)
return(TIFFReadDirEntryErrOk);
}
/* Check that the 8-byte unsigned value can fit in a 4-byte unsigned range */
static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSlongLong8(uint64 value)
{
if (value > 0x7FFFFFFFUL)
if (value > 0x7FFFFFFF)
return(TIFFReadDirEntryErrRange);
else
return(TIFFReadDirEntryErrOk);
}
/* Check that the 8-byte signed value can fit in a 4-byte signed range */
static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSlongSlong8(int64 value)
{
if ((value < 0L-0x80000000L) || (value > 0x7FFFFFFFL))
if ((value < 0-((int64) 0x7FFFFFFF+1)) || (value > 0x7FFFFFFF))
return(TIFFReadDirEntryErrRange);
else
return(TIFFReadDirEntryErrOk);
@ -3286,11 +3381,7 @@ TIFFReadDirEntryCheckRangeLong8Slong8(int64 value)
/*
* Largest 64-bit signed integer value.
*/
#if defined(__WIN32__) && defined(_MSC_VER)
# define TIFF_INT64_MAX 0x7FFFFFFFFFFFFFFFI64
#else
# define TIFF_INT64_MAX 0x7FFFFFFFFFFFFFFFLL
#endif
#define TIFF_INT64_MAX ((int64)(((uint64) ~0) >> 1))
static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSlong8Long8(uint64 value)
@ -3313,10 +3404,15 @@ TIFFReadDirEntryData(TIFF* tif, uint64 offset, tmsize_t size, void* dest)
if (!ReadOK(tif,dest,size))
return(TIFFReadDirEntryErrIo);
} else {
tmsize_t ma,mb;
ma=(tmsize_t)offset;
size_t ma,mb;
ma=(size_t)offset;
mb=ma+size;
if (((uint64)ma!=offset)||(mb<ma)||(mb<size)||(mb>tif->tif_size))
if (((uint64)ma!=offset)
|| (mb < ma)
|| (mb - ma != (size_t) size)
|| (mb < (size_t)size)
|| (mb > (size_t)tif->tif_size)
)
return(TIFFReadDirEntryErrIo);
_TIFFmemcpy(dest,tif->tif_base+ma,size);
}
@ -3369,7 +3465,7 @@ static void TIFFReadDirEntryOutputErr(TIFF* tif, enum TIFFReadDirEntryErr err, c
} else {
switch (err) {
case TIFFReadDirEntryErrCount:
TIFFErrorExt(tif->tif_clientdata, module,
TIFFWarningExt(tif->tif_clientdata, module,
"Incorrect count for \"%s\"; tag ignored",
tagname);
break;
@ -3425,6 +3521,8 @@ TIFFReadDirectory(TIFF* tif)
const TIFFField* fip;
uint32 fii=FAILED_FII;
toff_t nextdiroff;
int bitspersample_read = FALSE;
tif->tif_diroff=tif->tif_nextdiroff;
if (!TIFFCheckDirOffset(tif,tif->tif_nextdiroff))
return 0; /* last offset or bad offset (IFD looping) */
@ -3476,12 +3574,12 @@ TIFFReadDirectory(TIFF* tif)
* 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.
* But we must process the Compression tag first
* in order to merge in codec-private tag definitions (otherwise
* we may get complaints about unknown tags). However, the
* Compression tag may be dependent on the SamplesPerPixel
* tag value because older TIFF specs permited Compression
* tag value because older TIFF specs permitted Compression
* to be written as a SamplesPerPixel-count tag entry.
* Thus if we don't first figure out the correct SamplesPerPixel
* tag value then we may end up ignoring the Compression tag
@ -3583,6 +3681,10 @@ TIFFReadDirectory(TIFF* tif)
goto bad;
dp->tdir_tag=IGNORE;
break;
default:
if( !_TIFFCheckFieldIsValidForCodec(tif, dp->tdir_tag) )
dp->tdir_tag=IGNORE;
break;
}
}
}
@ -3645,6 +3747,7 @@ TIFFReadDirectory(TIFF* tif)
if (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE)
tif->tif_dir.td_stripsperimage /= tif->tif_dir.td_samplesperpixel;
if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) {
#ifdef OJPEG_SUPPORT
if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG) &&
(isTiled(tif)==0) &&
(tif->tif_dir.td_nstrips==1)) {
@ -3657,7 +3760,9 @@ TIFFReadDirectory(TIFF* tif)
* JpegInterchangeFormat stream.
*/
TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
} else {
} else
#endif
{
MissingRequired(tif,
isTiled(tif) ? "TileOffsets" : "StripOffsets");
goto bad;
@ -3682,7 +3787,7 @@ TIFFReadDirectory(TIFF* tif)
* DataType and SampleFormat tags are supposed to be
* written as one value/sample, but some vendors
* incorrectly write one value only -- so we accept
* that as well (yech). Other vendors write correct
* that as well (yuck). Other vendors write correct
* value for NumberOfSamples, but incorrect one for
* BitsPerSample and friends, and we will read this
* too.
@ -3701,13 +3806,15 @@ TIFFReadDirectory(TIFF* tif)
}
if (!TIFFSetField(tif,dp->tdir_tag,value))
goto bad;
if( dp->tdir_tag == TIFFTAG_BITSPERSAMPLE )
bitspersample_read = TRUE;
}
break;
case TIFFTAG_SMINSAMPLEVALUE:
case TIFFTAG_SMAXSAMPLEVALUE:
{
double *data = 0;
double *data = NULL;
enum TIFFReadDirEntryErr err;
uint32 saved_flags;
int m;
@ -3736,6 +3843,14 @@ TIFFReadDirectory(TIFF* tif)
_TIFFmemcpy( &(tif->tif_dir.td_stripoffset_entry),
dp, sizeof(TIFFDirEntry) );
#else
if( tif->tif_dir.td_stripoffset != NULL )
{
TIFFErrorExt(tif->tif_clientdata, module,
"tif->tif_dir.td_stripoffset is "
"already allocated. Likely duplicated "
"StripOffsets/TileOffsets tag");
goto bad;
}
if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripoffset))
goto bad;
#endif
@ -3746,6 +3861,14 @@ TIFFReadDirectory(TIFF* tif)
_TIFFmemcpy( &(tif->tif_dir.td_stripbytecount_entry),
dp, sizeof(TIFFDirEntry) );
#else
if( tif->tif_dir.td_stripbytecount != NULL )
{
TIFFErrorExt(tif->tif_clientdata, module,
"tif->tif_dir.td_stripbytecount is "
"already allocated. Likely duplicated "
"StripByteCounts/TileByteCounts tag");
goto bad;
}
if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripbytecount))
goto bad;
#endif
@ -3758,7 +3881,32 @@ TIFFReadDirectory(TIFF* tif)
uint32 countrequired;
uint32 incrementpersample;
uint16* value=NULL;
countpersample=(1L<<tif->tif_dir.td_bitspersample);
/* It would be dangerous to instantiate those tag values */
/* since if td_bitspersample has not yet been read (due to */
/* unordered tags), it could be read afterwards with a */
/* values greater than the default one (1), which may cause */
/* crashes in user code */
if( !bitspersample_read )
{
fip = TIFFFieldWithTag(tif,dp->tdir_tag);
TIFFWarningExt(tif->tif_clientdata,module,
"Ignoring %s since BitsPerSample tag not found",
fip ? fip->field_name : "unknown tagname");
continue;
}
/* ColorMap or TransferFunction for high bit */
/* depths do not make much sense and could be */
/* used as a denial of service vector */
if (tif->tif_dir.td_bitspersample > 24)
{
fip = TIFFFieldWithTag(tif,dp->tdir_tag);
TIFFWarningExt(tif->tif_clientdata,module,
"Ignoring %s because BitsPerSample=%d>24",
fip ? fip->field_name : "unknown tagname",
tif->tif_dir.td_bitspersample);
continue;
}
countpersample=(1U<<tif->tif_dir.td_bitspersample);
if ((dp->tdir_tag==TIFFTAG_TRANSFERFUNCTION)&&(dp->tdir_count==(uint64)countpersample))
{
countrequired=countpersample;
@ -3936,12 +4084,14 @@ TIFFReadDirectory(TIFF* tif)
#define BYTECOUNTLOOKSBAD \
( (tif->tif_dir.td_stripbytecount[0] == 0 && tif->tif_dir.td_stripoffset[0] != 0) || \
(tif->tif_dir.td_compression == COMPRESSION_NONE && \
tif->tif_dir.td_stripbytecount[0] > TIFFGetFileSize(tif) - tif->tif_dir.td_stripoffset[0]) || \
(tif->tif_dir.td_stripoffset[0] <= TIFFGetFileSize(tif) && \
tif->tif_dir.td_stripbytecount[0] > TIFFGetFileSize(tif) - tif->tif_dir.td_stripoffset[0])) || \
(tif->tif_mode == O_RDONLY && \
tif->tif_dir.td_compression == COMPRESSION_NONE && \
tif->tif_dir.td_stripbytecount[0] < TIFFScanlineSize64(tif) * tif->tif_dir.td_imagelength) )
} else if (tif->tif_dir.td_nstrips == 1
&& !(tif->tif_flags&TIFF_ISTILED)
&& _TIFFFillStriles(tif)
&& tif->tif_dir.td_stripoffset[0] != 0
&& BYTECOUNTLOOKSBAD) {
@ -4146,7 +4296,7 @@ TIFFReadDirectoryFindFieldInfo(TIFF* tif, uint16 tagid, uint32* fii)
}
/*
* Read custom directory from the arbitarry offset.
* Read custom directory from the arbitrary offset.
* The code is very similar to TIFFReadDirectory().
*/
int
@ -4273,7 +4423,9 @@ EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
TIFFDirectory *td = &tif->tif_dir;
uint32 strip;
_TIFFFillStriles( tif );
/* Do not try to load stripbytecount as we will compute it */
if( !_TIFFFillStrilesInternal( tif, 0 ) )
return -1;
if (td->td_stripbytecount)
_TIFFfree(td->td_stripbytecount);
@ -4295,7 +4447,7 @@ EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
/* calculate amount of space used by indirect values */
for (dp = dir, n = dircount; n > 0; n--, dp++)
{
uint32 typewidth = TIFFDataWidth((TIFFDataType) dp->tdir_type);
uint32 typewidth;
uint64 datasize;
typewidth = TIFFDataWidth((TIFFDataType) dp->tdir_type);
if (typewidth == 0) {
@ -4317,6 +4469,10 @@ EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
}
space+=datasize;
}
if( filesize < space )
/* we should perhaps return in error ? */
space = filesize;
else
space = filesize - space;
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
space /= td->td_samplesperpixel;
@ -4372,6 +4528,11 @@ TIFFCheckDirOffset(TIFF* tif, uint64 diroff)
if (diroff == 0) /* no more directories */
return 0;
if (tif->tif_dirnumber == 65535) {
TIFFErrorExt(tif->tif_clientdata, "TIFFCheckDirOffset",
"Cannot handle more than 65535 TIFF directories");
return 0;
}
for (n = 0; n < tif->tif_dirnumber && tif->tif_dirlist; n++) {
if (tif->tif_dirlist[n] == diroff)
@ -4380,7 +4541,7 @@ TIFFCheckDirOffset(TIFF* tif, uint64 diroff)
tif->tif_dirnumber++;
if (tif->tif_dirnumber > tif->tif_dirlistsize) {
if (tif->tif_dirlist == NULL || tif->tif_dirnumber > tif->tif_dirlistsize) {
uint64* new_dirlist;
/*
@ -4391,6 +4552,9 @@ TIFFCheckDirOffset(TIFF* tif, uint64 diroff)
tif->tif_dirnumber, 2 * sizeof(uint64), "for IFD list");
if (!new_dirlist)
return 0;
if( tif->tif_dirnumber >= 32768 )
tif->tif_dirlistsize = 65535;
else
tif->tif_dirlistsize = 2 * tif->tif_dirnumber;
tif->tif_dirlist = new_dirlist;
}
@ -4567,7 +4731,6 @@ TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntry** pdir,
}
else
{
tmsize_t m;
uint64 dircount64;
m=off+sizeof(uint64);
if ((m<off)||(m<(tmsize_t)sizeof(uint64))||(m>tif->tif_size)) {
@ -4703,6 +4866,7 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
return 0;
}
fip=tif->tif_fields[fii];
assert(fip != NULL); /* should not happen */
assert(fip->set_field_type!=TIFF_SETGET_OTHER); /* if so, we shouldn't arrive here but deal with this in specialized code */
assert(fip->set_field_type!=TIFF_SETGET_INT); /* if so, we shouldn't arrive here as this is only the case for pseudo-tags */
err=TIFFReadDirEntryErrOk;
@ -4761,7 +4925,7 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
break;
case TIFF_SETGET_UINT8:
{
uint8 data;
uint8 data=0;
assert(fip->field_readcount==1);
assert(fip->field_passcount==0);
err=TIFFReadDirEntryByte(tif,dp,&data);
@ -4855,8 +5019,12 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
uint16* data;
assert(fip->field_readcount==2);
assert(fip->field_passcount==0);
if (dp->tdir_count!=2)
if (dp->tdir_count!=2) {
TIFFWarningExt(tif->tif_clientdata,module,
"incorrect count for field \"%s\", expected 2, got %d",
fip->field_name,(int)dp->tdir_count);
return(0);
}
err=TIFFReadDirEntryShortArray(tif,dp,&data);
if (err==TIFFReadDirEntryErrOk)
{
@ -4873,8 +5041,12 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
uint8* data;
assert(fip->field_readcount>=1);
assert(fip->field_passcount==0);
if (dp->tdir_count!=(uint64)fip->field_readcount)
/* corrupt file */;
if (dp->tdir_count!=(uint64)fip->field_readcount) {
TIFFWarningExt(tif->tif_clientdata,module,
"incorrect count for field \"%s\", expected %d, got %d",
fip->field_name,(int) fip->field_readcount, (int)dp->tdir_count);
return 0;
}
else
{
err=TIFFReadDirEntryByteArray(tif,dp,&data);
@ -4969,6 +5141,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';
}
m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
if (data!=0)
_TIFFfree(data);
@ -5141,6 +5318,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';
}
m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
if (data!=0)
_TIFFfree(data);
@ -5342,7 +5524,7 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
}
if (err!=TIFFReadDirEntryErrOk)
{
TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",recover);
TIFFReadDirEntryOutputErr(tif,err,module,fip->field_name,recover);
return(0);
}
return(1);
@ -5358,28 +5540,39 @@ TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uint64** lpp)
static const char module[] = "TIFFFetchStripThing";
enum TIFFReadDirEntryErr err;
uint64* data;
err=TIFFReadDirEntryLong8Array(tif,dir,&data);
err=TIFFReadDirEntryLong8ArrayWithLimit(tif,dir,&data,nstrips);
if (err!=TIFFReadDirEntryErrOk)
{
const TIFFField* fip = TIFFFieldWithTag(tif,dir->tdir_tag);
TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0);
return(0);
}
if (dir->tdir_count!=(uint64)nstrips)
if (dir->tdir_count<(uint64)nstrips)
{
uint64* resizeddata;
const TIFFField* fip = TIFFFieldWithTag(tif,dir->tdir_tag);
const char* pszMax = getenv("LIBTIFF_STRILE_ARRAY_MAX_RESIZE_COUNT");
uint32 max_nstrips = 1000000;
if( pszMax )
max_nstrips = (uint32) atoi(pszMax);
TIFFReadDirEntryOutputErr(tif,TIFFReadDirEntryErrCount,
module,
fip ? fip->field_name : "unknown tagname",
( nstrips <= max_nstrips ) );
if( nstrips > max_nstrips )
{
_TIFFfree(data);
return(0);
}
resizeddata=(uint64*)_TIFFCheckMalloc(tif,nstrips,sizeof(uint64),"for strip array");
if (resizeddata==0) {
_TIFFfree(data);
return(0);
}
if (dir->tdir_count<(uint64)nstrips)
{
_TIFFmemcpy(resizeddata,data,(uint32)dir->tdir_count*sizeof(uint64));
_TIFFmemset(resizeddata+(uint32)dir->tdir_count,0,(nstrips-(uint32)dir->tdir_count)*sizeof(uint64));
}
else
_TIFFmemcpy(resizeddata,data,nstrips*sizeof(uint64));
_TIFFfree(data);
data=resizeddata;
}
@ -5461,13 +5654,17 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
uint64 rowblockbytes;
uint64 stripbytes;
uint32 strip;
uint64 nstrips64;
uint32 nstrips32;
uint32 nstrips;
uint32 rowsperstrip;
uint64* newcounts;
uint64* newoffsets;
bytecount = td->td_stripbytecount[0];
/* On a newly created file, just re-opened to be filled, we */
/* don't want strip chop to trigger as it is going to cause issues */
/* later ( StripOffsets and StripByteCounts improperly filled) . */
if( bytecount == 0 && tif->tif_mode != O_RDONLY )
return;
offset = td->td_stripoffset[0];
assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
if ((td->td_photometric == PHOTOMETRIC_YCBCR)&&
@ -5493,18 +5690,17 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
return;
/*
* never increase the number of strips in an image
* never increase the number of rows per strip
*/
if (rowsperstrip >= td->td_rowsperstrip)
return;
nstrips64 = TIFFhowmany_64(bytecount, stripbytes);
if ((nstrips64==0)||(nstrips64>0xFFFFFFFF)) /* something is wonky, do nothing. */
nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip);
if( nstrips == 0 )
return;
nstrips32 = (uint32)nstrips64;
newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64),
newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
"for chopped \"StripByteCounts\" array");
newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64),
newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
"for chopped \"StripOffsets\" array");
if (newcounts == NULL || newoffsets == NULL) {
/*
@ -5521,18 +5717,18 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
* Fill the strip information arrays with new bytecounts and offsets
* that reflect the broken-up format.
*/
for (strip = 0; strip < nstrips32; strip++) {
for (strip = 0; strip < nstrips; strip++) {
if (stripbytes > bytecount)
stripbytes = bytecount;
newcounts[strip] = stripbytes;
newoffsets[strip] = offset;
newoffsets[strip] = stripbytes ? offset : 0;
offset += stripbytes;
bytecount -= stripbytes;
}
/*
* Replace old single strip info with multi-strip info.
*/
td->td_stripsperimage = td->td_nstrips = nstrips32;
td->td_stripsperimage = td->td_nstrips = nstrips;
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
_TIFFfree(td->td_stripbytecount);
@ -5543,6 +5739,11 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
}
int _TIFFFillStriles( TIFF *tif )
{
return _TIFFFillStrilesInternal( tif, 1 );
}
static int _TIFFFillStrilesInternal( TIFF *tif, int loadStripByteCount )
{
#if defined(DEFER_STRILE_LOAD)
register TIFFDirectory *td = &tif->tif_dir;
@ -5560,7 +5761,8 @@ int _TIFFFillStriles( TIFF *tif )
return_value = 0;
}
if (!TIFFFetchStripThing(tif,&(td->td_stripbytecount_entry),
if (loadStripByteCount &&
!TIFFFetchStripThing(tif,&(td->td_stripbytecount_entry),
td->td_nstrips,&td->td_stripbytecount))
{
return_value = 0;
@ -5585,6 +5787,7 @@ int _TIFFFillStriles( TIFF *tif )
return return_value;
#else /* !defined(DEFER_STRILE_LOAD) */
(void) tif;
(void) loadStripByteCount;
return 1;
#endif
}

@ -1,4 +1,4 @@
/* $Id: tif_dirwrite.c,v 1.76 2011-02-18 20:53:04 fwarmerdam Exp $ */
/* $Id: tif_dirwrite.c,v 1.89 2017-08-23 13:33:42 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -30,6 +30,7 @@
* Directory Write Support Routines.
*/
#include "tiffiop.h"
#include <float.h>
#ifdef HAVE_IEEEFP
#define TIFFCvtNativeToIEEEFloat(tif, n, fp)
@ -542,7 +543,19 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff)
{
if (!isTiled(tif))
{
if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset))
/* td_stripoffset might be NULL in an odd OJPEG case. See
* tif_dirread.c around line 3634.
* XXX: OJPEG hack.
* If a) compression is OJPEG, b) it's not a tiled TIFF,
* and c) the number of strips is 1,
* then we tolerate the absence of stripoffsets tag,
* because, presumably, all required data is in the
* JpegInterchangeFormat stream.
* We can get here when using tiffset on such a file.
* See http://bugzilla.maptools.org/show_bug.cgi?id=2500
*/
if (tif->tif_dir.td_stripoffset != NULL &&
!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset))
goto bad;
}
else
@ -645,7 +658,7 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff)
assert(o->field_passcount==0);
TIFFGetField(tif,o->field_tag,&pb);
pa=(uint32)(strlen(pb));
if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,o->field_tag,pa,pb))
if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,(uint16)o->field_tag,pa,pb))
goto bad;
}
break;
@ -656,7 +669,7 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff)
assert(o->field_readcount==1);
assert(o->field_passcount==0);
TIFFGetField(tif,o->field_tag,&p);
if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,o->field_tag,p))
if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,(uint16)o->field_tag,p))
goto bad;
}
break;
@ -667,7 +680,7 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff)
assert(o->field_readcount==1);
assert(o->field_passcount==0);
TIFFGetField(tif,o->field_tag,&p);
if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,o->field_tag,p))
if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,(uint16)o->field_tag,p))
goto bad;
}
break;
@ -679,7 +692,7 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff)
assert(o->field_readcount==TIFF_VARIABLE2);
assert(o->field_passcount==1);
TIFFGetField(tif,o->field_tag,&pa,&pb);
if (!TIFFWriteDirectoryTagUndefinedArray(tif,&ndir,dir,o->field_tag,pa,pb))
if (!TIFFWriteDirectoryTagUndefinedArray(tif,&ndir,dir,(uint16)o->field_tag,pa,pb))
goto bad;
}
break;
@ -693,70 +706,72 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff)
}
for (m=0; m<(uint32)(tif->tif_dir.td_customValueCount); m++)
{
uint16 tag = (uint16)tif->tif_dir.td_customValues[m].info->field_tag;
uint32 count = tif->tif_dir.td_customValues[m].count;
switch (tif->tif_dir.td_customValues[m].info->field_type)
{
case TIFF_ASCII:
if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_UNDEFINED:
if (!TIFFWriteDirectoryTagUndefinedArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
if (!TIFFWriteDirectoryTagUndefinedArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_BYTE:
if (!TIFFWriteDirectoryTagByteArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
if (!TIFFWriteDirectoryTagByteArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_SBYTE:
if (!TIFFWriteDirectoryTagSbyteArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
if (!TIFFWriteDirectoryTagSbyteArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_SHORT:
if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_SSHORT:
if (!TIFFWriteDirectoryTagSshortArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
if (!TIFFWriteDirectoryTagSshortArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_LONG:
if (!TIFFWriteDirectoryTagLongArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
if (!TIFFWriteDirectoryTagLongArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_SLONG:
if (!TIFFWriteDirectoryTagSlongArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
if (!TIFFWriteDirectoryTagSlongArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_LONG8:
if (!TIFFWriteDirectoryTagLong8Array(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
if (!TIFFWriteDirectoryTagLong8Array(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_SLONG8:
if (!TIFFWriteDirectoryTagSlong8Array(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
if (!TIFFWriteDirectoryTagSlong8Array(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_RATIONAL:
if (!TIFFWriteDirectoryTagRationalArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
if (!TIFFWriteDirectoryTagRationalArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_SRATIONAL:
if (!TIFFWriteDirectoryTagSrationalArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
if (!TIFFWriteDirectoryTagSrationalArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_FLOAT:
if (!TIFFWriteDirectoryTagFloatArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
if (!TIFFWriteDirectoryTagFloatArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_DOUBLE:
if (!TIFFWriteDirectoryTagDoubleArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
if (!TIFFWriteDirectoryTagDoubleArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_IFD:
if (!TIFFWriteDirectoryTagIfdArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
if (!TIFFWriteDirectoryTagIfdArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
goto bad;
break;
case TIFF_IFD8:
if (!TIFFWriteDirectoryTagIfdIfd8Array(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
if (!TIFFWriteDirectoryTagIfdIfd8Array(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
goto bad;
break;
default:
@ -778,7 +793,7 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff)
goto bad;
}
else
tif->tif_diroff=(TIFFSeekFile(tif,0,SEEK_END)+1)&(~1);
tif->tif_diroff=(TIFFSeekFile(tif,0,SEEK_END)+1)&(~((toff_t)1));
if (pdiroff!=NULL)
*pdiroff=tif->tif_diroff;
if (!(tif->tif_flags&TIFF_BIGTIFF))
@ -806,7 +821,12 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff)
TIFFDirEntry* nb;
for (na=0, nb=dir; ; na++, nb++)
{
assert(na<ndir);
if( na == ndir )
{
TIFFErrorExt(tif->tif_clientdata,module,
"Cannot find SubIFD tag");
goto bad;
}
if (nb->tdir_tag==TIFFTAG_SUBIFD)
break;
}
@ -828,7 +848,7 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff)
uint32 nTmp;
TIFFDirEntry* o;
n=dirmem;
*(uint16*)n=ndir;
*(uint16*)n=(uint16)ndir;
if (tif->tif_flags&TIFF_SWAB)
TIFFSwabShort((uint16*)n);
n+=2;
@ -925,6 +945,69 @@ bad:
return(0);
}
static float TIFFClampDoubleToFloat( double val )
{
if( val > FLT_MAX )
return FLT_MAX;
if( val < -FLT_MAX )
return -FLT_MAX;
return (float)val;
}
static int8 TIFFClampDoubleToInt8( double val )
{
if( val > 127 )
return 127;
if( val < -128 || val != val )
return -128;
return (int8)val;
}
static int16 TIFFClampDoubleToInt16( double val )
{
if( val > 32767 )
return 32767;
if( val < -32768 || val != val )
return -32768;
return (int16)val;
}
static int32 TIFFClampDoubleToInt32( double val )
{
if( val > 0x7FFFFFFF )
return 0x7FFFFFFF;
if( val < -0x7FFFFFFF-1 || val != val )
return -0x7FFFFFFF-1;
return (int32)val;
}
static uint8 TIFFClampDoubleToUInt8( double val )
{
if( val < 0 )
return 0;
if( val > 255 || val != val )
return 255;
return (uint8)val;
}
static uint16 TIFFClampDoubleToUInt16( double val )
{
if( val < 0 )
return 0;
if( val > 65535 || val != val )
return 65535;
return (uint16)val;
}
static uint32 TIFFClampDoubleToUInt32( double val )
{
if( val < 0 )
return 0;
if( val > 0xFFFFFFFFU || val != val )
return 0xFFFFFFFFU;
return (uint32)val;
}
static int
TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
{
@ -945,7 +1028,7 @@ TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* di
if (tif->tif_dir.td_bitspersample<=32)
{
for (i = 0; i < count; ++i)
((float*)conv)[i] = (float)value[i];
((float*)conv)[i] = TIFFClampDoubleToFloat(value[i]);
ok = TIFFWriteDirectoryTagFloatArray(tif,ndir,dir,tag,count,(float*)conv);
}
else
@ -957,19 +1040,19 @@ TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* di
if (tif->tif_dir.td_bitspersample<=8)
{
for (i = 0; i < count; ++i)
((int8*)conv)[i] = (int8)value[i];
((int8*)conv)[i] = TIFFClampDoubleToInt8(value[i]);
ok = TIFFWriteDirectoryTagSbyteArray(tif,ndir,dir,tag,count,(int8*)conv);
}
else if (tif->tif_dir.td_bitspersample<=16)
{
for (i = 0; i < count; ++i)
((int16*)conv)[i] = (int16)value[i];
((int16*)conv)[i] = TIFFClampDoubleToInt16(value[i]);
ok = TIFFWriteDirectoryTagSshortArray(tif,ndir,dir,tag,count,(int16*)conv);
}
else
{
for (i = 0; i < count; ++i)
((int32*)conv)[i] = (int32)value[i];
((int32*)conv)[i] = TIFFClampDoubleToInt32(value[i]);
ok = TIFFWriteDirectoryTagSlongArray(tif,ndir,dir,tag,count,(int32*)conv);
}
break;
@ -977,19 +1060,19 @@ TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* di
if (tif->tif_dir.td_bitspersample<=8)
{
for (i = 0; i < count; ++i)
((uint8*)conv)[i] = (uint8)value[i];
((uint8*)conv)[i] = TIFFClampDoubleToUInt8(value[i]);
ok = TIFFWriteDirectoryTagByteArray(tif,ndir,dir,tag,count,(uint8*)conv);
}
else if (tif->tif_dir.td_bitspersample<=16)
{
for (i = 0; i < count; ++i)
((uint16*)conv)[i] = (uint16)value[i];
((uint16*)conv)[i] = TIFFClampDoubleToUInt16(value[i]);
ok = TIFFWriteDirectoryTagShortArray(tif,ndir,dir,tag,count,(uint16*)conv);
}
else
{
for (i = 0; i < count; ++i)
((uint32*)conv)[i] = (uint32)value[i];
((uint32*)conv)[i] = TIFFClampDoubleToUInt32(value[i]);
ok = TIFFWriteDirectoryTagLongArray(tif,ndir,dir,tag,count,(uint32*)conv);
}
break;
@ -1866,7 +1949,14 @@ TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32* ndir, TIFFDirEntry* dir)
for (p=0; p < tif->tif_dir.td_nsubifd; p++)
{
assert(pa != 0);
assert(*pa <= 0xFFFFFFFFUL);
/* Could happen if an classicTIFF has a SubIFD of type LONG8 (which is illegal) */
if( *pa > 0xFFFFFFFFUL)
{
TIFFErrorExt(tif->tif_clientdata,module,"Illegal value for SubIFD tag");
_TIFFfree(o);
return(0);
}
*pb++=(uint32)(*pa++);
}
n=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,o);
@ -2033,7 +2123,10 @@ TIFFWriteDirectoryTagCheckedLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, ui
{
uint64 m;
assert(sizeof(uint64)==8);
assert(tif->tif_flags&TIFF_BIGTIFF);
if( !(tif->tif_flags&TIFF_BIGTIFF) ) {
TIFFErrorExt(tif->tif_clientdata,"TIFFWriteDirectoryTagCheckedLong8","LONG8 not allowed for ClassicTIFF");
return(0);
}
m=value;
if (tif->tif_flags&TIFF_SWAB)
TIFFSwabLong8(&m);
@ -2046,7 +2139,10 @@ TIFFWriteDirectoryTagCheckedLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* di
{
assert(count<0x20000000);
assert(sizeof(uint64)==8);
assert(tif->tif_flags&TIFF_BIGTIFF);
if( !(tif->tif_flags&TIFF_BIGTIFF) ) {
TIFFErrorExt(tif->tif_clientdata,"TIFFWriteDirectoryTagCheckedLong8Array","LONG8 not allowed for ClassicTIFF");
return(0);
}
if (tif->tif_flags&TIFF_SWAB)
TIFFSwabArrayOfLong8(value,count);
return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG8,count,count*8,value));
@ -2058,7 +2154,10 @@ TIFFWriteDirectoryTagCheckedSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, u
{
int64 m;
assert(sizeof(int64)==8);
assert(tif->tif_flags&TIFF_BIGTIFF);
if( !(tif->tif_flags&TIFF_BIGTIFF) ) {
TIFFErrorExt(tif->tif_clientdata,"TIFFWriteDirectoryTagCheckedSlong8","SLONG8 not allowed for ClassicTIFF");
return(0);
}
m=value;
if (tif->tif_flags&TIFF_SWAB)
TIFFSwabLong8((uint64*)(&m));
@ -2071,7 +2170,10 @@ TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* d
{
assert(count<0x20000000);
assert(sizeof(int64)==8);
assert(tif->tif_flags&TIFF_BIGTIFF);
if( !(tif->tif_flags&TIFF_BIGTIFF) ) {
TIFFErrorExt(tif->tif_clientdata,"TIFFWriteDirectoryTagCheckedSlong8Array","SLONG8 not allowed for ClassicTIFF");
return(0);
}
if (tif->tif_flags&TIFF_SWAB)
TIFFSwabArrayOfLong8((uint64*)value,count);
return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG8,count,count*8,value));
@ -2080,15 +2182,25 @@ TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* d
static int
TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
{
static const char module[] = "TIFFWriteDirectoryTagCheckedRational";
uint32 m[2];
assert(value>=0.0);
assert(sizeof(uint32)==4);
if (value<=0.0)
if( value < 0 )
{
TIFFErrorExt(tif->tif_clientdata,module,"Negative value is illegal");
return 0;
}
else if( value != value )
{
TIFFErrorExt(tif->tif_clientdata,module,"Not-a-number value is illegal");
return 0;
}
else if (value==0.0)
{
m[0]=0;
m[1]=1;
}
else if (value==(double)(uint32)value)
else if (value <= 0xFFFFFFFFU && value==(double)(uint32)value)
{
m[0]=(uint32)value;
m[1]=1;
@ -2129,25 +2241,26 @@ TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry*
}
for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++)
{
if (*na<=0.0)
if (*na<=0.0 || *na != *na)
{
nb[0]=0;
nb[1]=1;
}
else if (*na==(float)(uint32)(*na))
else if (*na >= 0 && *na <= (float)0xFFFFFFFFU &&
*na==(float)(uint32)(*na))
{
nb[0]=(uint32)(*na);
nb[1]=1;
}
else if (*na<1.0)
{
nb[0]=(uint32)((*na)*0xFFFFFFFF);
nb[0]=(uint32)((double)(*na)*0xFFFFFFFF);
nb[1]=0xFFFFFFFF;
}
else
{
nb[0]=0xFFFFFFFF;
nb[1]=(uint32)(0xFFFFFFFF/(*na));
nb[1]=(uint32)((double)0xFFFFFFFF/(*na));
}
}
if (tif->tif_flags&TIFF_SWAB)
@ -2184,13 +2297,13 @@ TIFFWriteDirectoryTagCheckedSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry
}
else if (*na>-1.0)
{
nb[0]=-(int32)((-*na)*0x7FFFFFFF);
nb[0]=-(int32)((double)(-*na)*0x7FFFFFFF);
nb[1]=0x7FFFFFFF;
}
else
{
nb[0]=-0x7FFFFFFF;
nb[1]=(int32)(0x7FFFFFFF/(-*na));
nb[1]=(int32)((double)0x7FFFFFFF/(-*na));
}
}
else
@ -2202,13 +2315,13 @@ TIFFWriteDirectoryTagCheckedSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry
}
else if (*na<1.0)
{
nb[0]=(int32)((*na)*0x7FFFFFFF);
nb[0]=(int32)((double)(*na)*0x7FFFFFFF);
nb[1]=0x7FFFFFFF;
}
else
{
nb[0]=0x7FFFFFFF;
nb[1]=(int32)(0x7FFFFFFF/(*na));
nb[1]=(int32)((double)0x7FFFFFFF/(*na));
}
}
}
@ -2368,7 +2481,7 @@ TIFFLinkDirectory(TIFF* tif)
{
static const char module[] = "TIFFLinkDirectory";
tif->tif_diroff = (TIFFSeekFile(tif,0,SEEK_END)+1) &~ 1;
tif->tif_diroff = (TIFFSeekFile(tif,0,SEEK_END)+1) & (~((toff_t)1));
/*
* Handle SubIFDs
@ -2570,7 +2683,7 @@ _TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype,
tmsize_t count, void* data)
{
static const char module[] = "TIFFResetField";
const TIFFField* fip = NULL;
/* const TIFFField* fip = NULL; */
uint16 dircount;
tmsize_t dirsize;
uint8 direntry_raw[20];
@ -2586,7 +2699,7 @@ _TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype,
/* -------------------------------------------------------------------- */
/* Find field definition. */
/* -------------------------------------------------------------------- */
fip = TIFFFindField(tif, tag, TIFF_ANY);
/*fip =*/ TIFFFindField(tif, tag, TIFF_ANY);
/* -------------------------------------------------------------------- */
/* Do some checking this is a straight forward case. */
@ -2839,14 +2952,15 @@ _TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype,
"Error writing directory link");
return (0);
}
_TIFFfree( buf_to_write );
}
else
{
memcpy( &entry_offset, buf_to_write, count*TIFFDataWidth(datatype));
}
_TIFFfree( buf_to_write );
buf_to_write = 0;
/* -------------------------------------------------------------------- */
/* Adjust the directory entry. */
/* -------------------------------------------------------------------- */

@ -1,4 +1,4 @@
/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_dumpmode.c,v 1.14 2011-04-02 20:54:09 bfriesen Exp $ */
/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_dumpmode.c,v 1.15 2015-12-12 18:04:26 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -66,7 +66,7 @@ DumpModeEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s)
cc -= n;
if (tif->tif_rawcc >= tif->tif_rawdatasize &&
!TIFFFlushData1(tif))
return (-1);
return (0);
}
return (1);
}

@ -1,4 +1,4 @@
/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_error.c,v 1.5 2010-03-10 18:56:48 bfriesen Exp $ */
/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_error.c,v 1.6 2017-07-04 12:54:42 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -51,25 +51,33 @@ void
TIFFError(const char* module, const char* fmt, ...)
{
va_list ap;
if (_TIFFerrorHandler) {
va_start(ap, fmt);
if (_TIFFerrorHandler)
(*_TIFFerrorHandler)(module, fmt, ap);
if (_TIFFerrorHandlerExt)
va_end(ap);
}
if (_TIFFerrorHandlerExt) {
va_start(ap, fmt);
(*_TIFFerrorHandlerExt)(0, module, fmt, ap);
va_end(ap);
}
}
void
TIFFErrorExt(thandle_t fd, const char* module, const char* fmt, ...)
{
va_list ap;
if (_TIFFerrorHandler) {
va_start(ap, fmt);
if (_TIFFerrorHandler)
(*_TIFFerrorHandler)(module, fmt, ap);
if (_TIFFerrorHandlerExt)
va_end(ap);
}
if (_TIFFerrorHandlerExt) {
va_start(ap, fmt);
(*_TIFFerrorHandlerExt)(fd, module, fmt, ap);
va_end(ap);
}
}
/*
* Local Variables:

@ -1,4 +1,4 @@
/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_extension.c,v 1.7 2010-03-10 18:56:48 bfriesen Exp $ */
/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_extension.c,v 1.8 2015-12-06 11:13:43 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -66,13 +66,13 @@ TIFFTagMethods *TIFFAccessTagMethods( TIFF *tif )
void *TIFFGetClientInfo( TIFF *tif, const char *name )
{
TIFFClientInfoLink *link = tif->tif_clientinfo;
TIFFClientInfoLink *psLink = tif->tif_clientinfo;
while( link != NULL && strcmp(link->name,name) != 0 )
link = link->next;
while( psLink != NULL && strcmp(psLink->name,name) != 0 )
psLink = psLink->next;
if( link != NULL )
return link->data;
if( psLink != NULL )
return psLink->data;
else
return NULL;
}
@ -80,18 +80,18 @@ void *TIFFGetClientInfo( TIFF *tif, const char *name )
void TIFFSetClientInfo( TIFF *tif, void *data, const char *name )
{
TIFFClientInfoLink *link = tif->tif_clientinfo;
TIFFClientInfoLink *psLink = tif->tif_clientinfo;
/*
** Do we have an existing link with this name? If so, just
** set it.
*/
while( link != NULL && strcmp(link->name,name) != 0 )
link = link->next;
while( psLink != NULL && strcmp(psLink->name,name) != 0 )
psLink = psLink->next;
if( link != NULL )
if( psLink != NULL )
{
link->data = data;
psLink->data = data;
return;
}
@ -99,15 +99,15 @@ void TIFFSetClientInfo( TIFF *tif, void *data, const char *name )
** Create a new link.
*/
link = (TIFFClientInfoLink *) _TIFFmalloc(sizeof(TIFFClientInfoLink));
assert (link != NULL);
link->next = tif->tif_clientinfo;
link->name = (char *) _TIFFmalloc((tmsize_t)(strlen(name)+1));
assert (link->name != NULL);
strcpy(link->name, name);
link->data = data;
psLink = (TIFFClientInfoLink *) _TIFFmalloc(sizeof(TIFFClientInfoLink));
assert (psLink != NULL);
psLink->next = tif->tif_clientinfo;
psLink->name = (char *) _TIFFmalloc((tmsize_t)(strlen(name)+1));
assert (psLink->name != NULL);
strcpy(psLink->name, name);
psLink->data = data;
tif->tif_clientinfo = link;
tif->tif_clientinfo = psLink;
}
/*
* Local Variables:

@ -1,4 +1,4 @@
/* $Id: tif_fax3.c,v 1.73 2012-06-13 00:27:20 fwarmerdam Exp $ */
/* $Id: tif_fax3.c,v 1.81 2017-06-18 10:31:50 erouault Exp $ */
/*
* Copyright (c) 1990-1997 Sam Leffler
@ -329,34 +329,64 @@ Fax3Decode2D(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
#if SIZEOF_UNSIGNED_LONG == 8
# define FILL(n, cp) \
switch (n) { \
case 15:(cp)[14] = 0xff; case 14:(cp)[13] = 0xff; case 13: (cp)[12] = 0xff;\
case 12:(cp)[11] = 0xff; case 11:(cp)[10] = 0xff; case 10: (cp)[9] = 0xff;\
case 9: (cp)[8] = 0xff; case 8: (cp)[7] = 0xff; case 7: (cp)[6] = 0xff;\
case 6: (cp)[5] = 0xff; case 5: (cp)[4] = 0xff; case 4: (cp)[3] = 0xff;\
case 3: (cp)[2] = 0xff; case 2: (cp)[1] = 0xff; \
case 1: (cp)[0] = 0xff; (cp) += (n); case 0: ; \
case 15:(cp)[14] = 0xff; /*-fallthrough*/ \
case 14:(cp)[13] = 0xff; /*-fallthrough*/ \
case 13:(cp)[12] = 0xff; /*-fallthrough*/ \
case 12:(cp)[11] = 0xff; /*-fallthrough*/ \
case 11:(cp)[10] = 0xff; /*-fallthrough*/ \
case 10: (cp)[9] = 0xff; /*-fallthrough*/ \
case 9: (cp)[8] = 0xff; /*-fallthrough*/ \
case 8: (cp)[7] = 0xff; /*-fallthrough*/ \
case 7: (cp)[6] = 0xff; /*-fallthrough*/ \
case 6: (cp)[5] = 0xff; /*-fallthrough*/ \
case 5: (cp)[4] = 0xff; /*-fallthrough*/ \
case 4: (cp)[3] = 0xff; /*-fallthrough*/ \
case 3: (cp)[2] = 0xff; /*-fallthrough*/ \
case 2: (cp)[1] = 0xff; /*-fallthrough*/ \
case 1: (cp)[0] = 0xff; (cp) += (n); /*-fallthrough*/ \
case 0: ; \
}
# define ZERO(n, cp) \
switch (n) { \
case 15:(cp)[14] = 0; case 14:(cp)[13] = 0; case 13: (cp)[12] = 0; \
case 12:(cp)[11] = 0; case 11:(cp)[10] = 0; case 10: (cp)[9] = 0; \
case 9: (cp)[8] = 0; case 8: (cp)[7] = 0; case 7: (cp)[6] = 0; \
case 6: (cp)[5] = 0; case 5: (cp)[4] = 0; case 4: (cp)[3] = 0; \
case 3: (cp)[2] = 0; case 2: (cp)[1] = 0; \
case 1: (cp)[0] = 0; (cp) += (n); case 0: ; \
case 15:(cp)[14] = 0; /*-fallthrough*/ \
case 14:(cp)[13] = 0; /*-fallthrough*/ \
case 13:(cp)[12] = 0; /*-fallthrough*/ \
case 12:(cp)[11] = 0; /*-fallthrough*/ \
case 11:(cp)[10] = 0; /*-fallthrough*/ \
case 10: (cp)[9] = 0; /*-fallthrough*/ \
case 9: (cp)[8] = 0; /*-fallthrough*/ \
case 8: (cp)[7] = 0; /*-fallthrough*/ \
case 7: (cp)[6] = 0; /*-fallthrough*/ \
case 6: (cp)[5] = 0; /*-fallthrough*/ \
case 5: (cp)[4] = 0; /*-fallthrough*/ \
case 4: (cp)[3] = 0; /*-fallthrough*/ \
case 3: (cp)[2] = 0; /*-fallthrough*/ \
case 2: (cp)[1] = 0; /*-fallthrough*/ \
case 1: (cp)[0] = 0; (cp) += (n); /*-fallthrough*/ \
case 0: ; \
}
#else
# define FILL(n, cp) \
switch (n) { \
case 7: (cp)[6] = 0xff; case 6: (cp)[5] = 0xff; case 5: (cp)[4] = 0xff; \
case 4: (cp)[3] = 0xff; case 3: (cp)[2] = 0xff; case 2: (cp)[1] = 0xff; \
case 1: (cp)[0] = 0xff; (cp) += (n); case 0: ; \
case 7: (cp)[6] = 0xff; /*-fallthrough*/ \
case 6: (cp)[5] = 0xff; /*-fallthrough*/ \
case 5: (cp)[4] = 0xff; /*-fallthrough*/ \
case 4: (cp)[3] = 0xff; /*-fallthrough*/ \
case 3: (cp)[2] = 0xff; /*-fallthrough*/ \
case 2: (cp)[1] = 0xff; /*-fallthrough*/ \
case 1: (cp)[0] = 0xff; (cp) += (n); /*-fallthrough*/ \
case 0: ; \
}
# define ZERO(n, cp) \
switch (n) { \
case 7: (cp)[6] = 0; case 6: (cp)[5] = 0; case 5: (cp)[4] = 0; \
case 4: (cp)[3] = 0; case 3: (cp)[2] = 0; case 2: (cp)[1] = 0; \
case 1: (cp)[0] = 0; (cp) += (n); case 0: ; \
case 7: (cp)[6] = 0; /*-fallthrough*/ \
case 6: (cp)[5] = 0; /*-fallthrough*/ \
case 5: (cp)[4] = 0; /*-fallthrough*/ \
case 4: (cp)[3] = 0; /*-fallthrough*/ \
case 3: (cp)[2] = 0; /*-fallthrough*/ \
case 2: (cp)[1] = 0; /*-fallthrough*/ \
case 1: (cp)[0] = 0; (cp) += (n); /*-fallthrough*/ \
case 0: ; \
}
#endif
@ -442,8 +472,9 @@ _TIFFFax3fillruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 lastx)
FILL(n, cp);
run &= 7;
}
/* Explicit 0xff masking to make icc -check=conversions happy */
if (run)
cp[0] |= 0xff00 >> run;
cp[0] = (unsigned char)((cp[0] | (0xff00 >> run))&0xff);
} else
cp[0] |= _fillmasks[run]>>bx;
x += runs[1];
@ -526,7 +557,7 @@ Fax3SetupState(TIFF* tif)
"for Group 3/4 run arrays");
if (dsp->runs == NULL)
return (0);
memset( dsp->runs, 0, TIFFSafeMultiply(uint32,nruns,2));
memset( dsp->runs, 0, TIFFSafeMultiply(uint32,nruns,2)*sizeof(uint32));
dsp->curruns = dsp->runs;
if (needsRefLine)
dsp->refruns = dsp->runs + nruns;
@ -643,7 +674,8 @@ putspan(TIFF* tif, int32 span, const tableentry* tab)
while (span >= 2624) {
const tableentry* te = &tab[63 + (2560>>6)];
code = te->code, length = te->length;
code = te->code;
length = te->length;
#ifdef FAX3_DEBUG
DEBUG_PRINT("MakeUp", te->runlen);
#endif
@ -653,14 +685,16 @@ putspan(TIFF* tif, int32 span, const tableentry* tab)
if (span >= 64) {
const tableentry* te = &tab[63 + (span>>6)];
assert(te->runlen == 64*(span>>6));
code = te->code, length = te->length;
code = te->code;
length = te->length;
#ifdef FAX3_DEBUG
DEBUG_PRINT("MakeUp", te->runlen);
#endif
_PutBits(tif, code, length);
span -= te->runlen;
}
code = tab[span].code, length = tab[span].length;
code = tab[span].code;
length = tab[span].length;
#ifdef FAX3_DEBUG
DEBUG_PRINT(" Term", tab[span].runlen);
#endif
@ -696,14 +730,16 @@ Fax3PutEOL(TIFF* tif)
align = sp->bit + (8 - align);
else
align = sp->bit - align;
code = 0;
tparm=align;
_PutBits(tif, 0, tparm);
}
}
code = EOL, length = 12;
if (is2DEncoding(sp))
code = (code<<1) | (sp->tag == G3_1D), length++;
code = EOL;
length = 12;
if (is2DEncoding(sp)) {
code = (code<<1) | (sp->tag == G3_1D);
length++;
}
_PutBits(tif, code, length);
sp->data = data;
@ -804,7 +840,7 @@ static int32 find1span(unsigned char*, int32, int32);
* table. The ``base'' of the bit string is supplied
* along with the start+end bit indices.
*/
static int32
inline static int32
find0span(unsigned char* bp, int32 bs, int32 be)
{
int32 bits = be - bs;
@ -814,7 +850,7 @@ find0span(unsigned char* bp, int32 bs, int32 be)
/*
* Check partial byte on lhs.
*/
if (bits > 0 && (n = (bs & 7))) {
if (bits > 0 && (n = (bs & 7)) != 0) {
span = zeroruns[(*bp << n) & 0xff];
if (span > 8-n) /* table value too generous */
span = 8-n;
@ -834,12 +870,14 @@ find0span(unsigned char* bp, int32 bs, int32 be)
while (!isAligned(bp, long)) {
if (*bp != 0x00)
return (span + zeroruns[*bp]);
span += 8, bits -= 8;
span += 8;
bits -= 8;
bp++;
}
lp = (long*) bp;
while ((bits >= (int32)(8 * sizeof(long))) && (0 == *lp)) {
span += 8*sizeof (long), bits -= 8*sizeof (long);
span += 8*sizeof (long);
bits -= 8*sizeof (long);
lp++;
}
bp = (unsigned char*) lp;
@ -850,7 +888,8 @@ find0span(unsigned char* bp, int32 bs, int32 be)
while (bits >= 8) {
if (*bp != 0x00) /* end of run */
return (span + zeroruns[*bp]);
span += 8, bits -= 8;
span += 8;
bits -= 8;
bp++;
}
/*
@ -863,7 +902,7 @@ find0span(unsigned char* bp, int32 bs, int32 be)
return (span);
}
static int32
inline static int32
find1span(unsigned char* bp, int32 bs, int32 be)
{
int32 bits = be - bs;
@ -873,7 +912,7 @@ find1span(unsigned char* bp, int32 bs, int32 be)
/*
* Check partial byte on lhs.
*/
if (bits > 0 && (n = (bs & 7))) {
if (bits > 0 && (n = (bs & 7)) != 0) {
span = oneruns[(*bp << n) & 0xff];
if (span > 8-n) /* table value too generous */
span = 8-n;
@ -893,12 +932,14 @@ find1span(unsigned char* bp, int32 bs, int32 be)
while (!isAligned(bp, long)) {
if (*bp != 0xff)
return (span + oneruns[*bp]);
span += 8, bits -= 8;
span += 8;
bits -= 8;
bp++;
}
lp = (long*) bp;
while ((bits >= (int32)(8 * sizeof(long))) && (~0 == *lp)) {
span += 8*sizeof (long), bits -= 8*sizeof (long);
span += 8*sizeof (long);
bits -= 8*sizeof (long);
lp++;
}
bp = (unsigned char*) lp;
@ -909,7 +950,8 @@ find1span(unsigned char* bp, int32 bs, int32 be)
while (bits >= 8) {
if (*bp != 0xff) /* end of run */
return (span + oneruns[*bp]);
span += 8, bits -= 8;
span += 8;
bits -= 8;
bp++;
}
/*
@ -1001,7 +1043,11 @@ Fax3Encode2DRow(TIFF* tif, unsigned char* bp, unsigned char* rp, uint32 bits)
for (;;) {
b2 = finddiff2(rp, b1, bits, PIXEL(rp,b1));
if (b2 >= a1) {
int32 d = b1 - a1;
/* Naive computation triggers -fsanitize=undefined,unsigned-integer-overflow */
/* although it is correct unless the difference between both is < 31 bit */
/* int32 d = b1 - a1; */
int32 d = (b1 >= a1 && b1 - a1 <= 3U) ? (int32)(b1 - a1):
(b1 < a1 && a1 - b1 <= 3U) ? -(int32)(a1 - b1) : 0x7FFFFFFF;
if (!(-3 <= d && d <= 3)) { /* horizontal mode */
a2 = finddiff2(bp, a1, bits, PIXEL(bp,a1));
putcode(tif, &horizcode);
@ -1087,14 +1133,16 @@ Fax3PostEncode(TIFF* tif)
static void
Fax3Close(TIFF* tif)
{
if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0) {
if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0 && tif->tif_rawcp) {
Fax3CodecState* sp = EncoderState(tif);
unsigned int code = EOL;
unsigned int length = 12;
int i;
if (is2DEncoding(sp))
code = (code<<1) | (sp->tag == G3_1D), length++;
if (is2DEncoding(sp)) {
code = (code<<1) | (sp->tag == G3_1D);
length++;
}
for (i = 0; i < 6; i++)
Fax3PutBits(tif, code, length);
Fax3FlushBits(tif, sp);
@ -1181,7 +1229,7 @@ Fax3VSetField(TIFF* tif, uint32 tag, va_list ap)
return (*sp->vsetparent)(tif, tag, ap);
}
if ((fip = TIFFFieldWithTag(tif, tag)))
if ((fip = TIFFFieldWithTag(tif, tag)) != NULL)
TIFFSetFieldBit(tif, fip->field_bit);
else
return 0;
@ -1240,10 +1288,14 @@ Fax3PrintDir(TIFF* tif, FILE* fd, long flags)
} else {
fprintf(fd, " Group 3 Options:");
if (sp->groupoptions & GROUP3OPT_2DENCODING)
fprintf(fd, "%s2-d encoding", sep), sep = "+";
if (sp->groupoptions & GROUP3OPT_FILLBITS)
fprintf(fd, "%sEOL padding", sep), sep = "+";
if (sp->groupoptions & GROUP3OPT_2DENCODING) {
fprintf(fd, "%s2-d encoding", sep);
sep = "+";
}
if (sp->groupoptions & GROUP3OPT_FILLBITS) {
fprintf(fd, "%sEOL padding", sep);
sep = "+";
}
if (sp->groupoptions & GROUP3OPT_UNCOMPRESSED)
fprintf(fd, "%suncompressed data", sep);
}
@ -1303,6 +1355,7 @@ InitCCITTFax3(TIFF* tif)
"No space for state block");
return (0);
}
_TIFFmemset(tif->tif_data, 0, sizeof (Fax3CodecState));
sp = Fax3State(tif);
sp->rw_mode = tif->tif_mode;

@ -1,4 +1,4 @@
/* $Id: tif_fax3.h,v 1.9 2011-03-10 20:23:07 fwarmerdam Exp $ */
/* $Id: tif_fax3.h,v 1.13 2016-12-14 18:36:27 faxguy Exp $ */
/*
* Copyright (c) 1990-1997 Sam Leffler
@ -39,7 +39,7 @@
/*
* To override the default routine used to image decoded
* spans one can use the pseduo tag TIFFTAG_FAXFILLFUNC.
* spans one can use the pseudo tag TIFFTAG_FAXFILLFUNC.
* The routine must have the type signature given below;
* for example:
*
@ -81,10 +81,12 @@ extern void _TIFFFax3fillruns(unsigned char*, uint32*, uint32*, uint32);
#define S_MakeUp 11
#define S_EOL 12
/* WARNING: do not change the layout of this structure as the HylaFAX software */
/* really depends on it. See http://bugzilla.maptools.org/show_bug.cgi?id=2636 */
typedef struct { /* state table entry */
unsigned char State; /* see above */
unsigned char Width; /* width of code in bits */
uint32 Param; /* unsigned 32-bit run length in bits */
uint32 Param; /* unsigned 32-bit run length in bits (holds on 16 bit actually, but cannot be changed. See above warning) */
} TIFFFaxTabEnt;
extern const TIFFFaxTabEnt TIFFFaxMainTable[];

File diff suppressed because it is too large Load Diff

@ -1,4 +1,4 @@
/* $Id: tif_jbig.c,v 1.15 2010-03-10 18:56:48 bfriesen Exp $ */
/* $Id: tif_jbig.c,v 1.16 2017-06-26 15:20:00 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -94,6 +94,7 @@ static int JBIGDecode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s)
jbg_strerror(decodeStatus)
#endif
);
jbg_dec_free(&decoder);
return 0;
}

@ -1,4 +1,4 @@
/* $Id: tif_jpeg.c,v 1.108 2012-06-05 03:24:30 fwarmerdam Exp $ */
/* $Id: tif_jpeg.c,v 1.134 2017-10-17 19:04:47 erouault Exp $ */
/*
* Copyright (c) 1994-1997 Sam Leffler
@ -27,6 +27,8 @@
#define WIN32_LEAN_AND_MEAN
#define VC_EXTRALEAN
#include <stdlib.h>
#include "tiffiop.h"
#ifdef JPEG_SUPPORT
@ -47,6 +49,7 @@
int TIFFFillStrip(TIFF* tif, uint32 strip);
int TIFFFillTile(TIFF* tif, uint32 tile);
int TIFFReInitJPEG_12( TIFF *tif, int scheme, int is_encode );
int TIFFJPEGIsFullStripRequired_12(TIFF* tif);
/* We undefine FAR to avoid conflict with JPEG definition */
@ -58,7 +61,7 @@ int TIFFReInitJPEG_12( TIFF *tif, int scheme, int is_encode );
Libjpeg's jmorecfg.h defines INT16 and INT32, but only if XMD_H is
not defined. Unfortunately, the MinGW and Borland compilers include
a typedef for INT32, which causes a conflict. MSVC does not include
a conficting typedef given the headers which are included.
a conflicting typedef given the headers which are included.
*/
#if defined(__BORLANDC__) || defined(__MINGW32__)
# define XMD_H 1
@ -145,6 +148,8 @@ typedef struct {
jpeg_error_mgr err; /* libjpeg error manager */
JMP_BUF exit_jmpbuf; /* for catching libjpeg failures */
struct jpeg_progress_mgr progress;
/*
* The following two members could be a union, but
* they're small enough that it's not worth the effort.
@ -175,6 +180,7 @@ typedef struct {
int jpegtablesmode; /* What to put in JPEGTables */
int ycbcrsampling_fetched;
int max_allowed_scan_number;
} JPEGState;
#define JState(tif) ((JPEGState*)(tif)->tif_data)
@ -235,6 +241,33 @@ TIFFjpeg_output_message(j_common_ptr cinfo)
TIFFWarningExt(((JPEGState *) cinfo)->tif->tif_clientdata, "JPEGLib", "%s", buffer);
}
/* Avoid the risk of denial-of-service on crafted JPEGs with an insane */
/* number of scans. */
/* See http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf */
static void
TIFFjpeg_progress_monitor(j_common_ptr cinfo)
{
JPEGState *sp = (JPEGState *) cinfo; /* NB: cinfo assumed first */
if (cinfo->is_decompressor)
{
const int scan_no =
((j_decompress_ptr)cinfo)->input_scan_number;
if (scan_no >= sp->max_allowed_scan_number)
{
TIFFErrorExt(((JPEGState *) cinfo)->tif->tif_clientdata,
"TIFFjpeg_progress_monitor",
"Scan number %d exceeds maximum scans (%d). This limit "
"can be raised through the LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER "
"environment variable.",
scan_no, sp->max_allowed_scan_number);
jpeg_abort(cinfo); /* clean up libjpeg state */
LONGJMP(sp->exit_jmpbuf, 1); /* return to libtiff caller */
}
}
}
/*
* Interface routines. This layer of routines exists
* primarily to limit side-effects from using setjmp.
@ -252,6 +285,9 @@ TIFFjpeg_create_compress(JPEGState* sp)
sp->err.error_exit = TIFFjpeg_error_exit;
sp->err.output_message = TIFFjpeg_output_message;
/* set client_data to avoid UMR warning from tools like Purify */
sp->cinfo.c.client_data = NULL;
return CALLVJPEG(sp, jpeg_create_compress(&sp->cinfo.c));
}
@ -263,6 +299,9 @@ TIFFjpeg_create_decompress(JPEGState* sp)
sp->err.error_exit = TIFFjpeg_error_exit;
sp->err.output_message = TIFFjpeg_output_message;
/* set client_data to avoid UMR warning from tools like Purify */
sp->cinfo.d.client_data = NULL;
return CALLVJPEG(sp, jpeg_create_decompress(&sp->cinfo.d));
}
@ -330,9 +369,24 @@ TIFFjpeg_read_header(JPEGState* sp, boolean require_image)
return CALLJPEG(sp, -1, jpeg_read_header(&sp->cinfo.d, require_image));
}
static int
TIFFjpeg_has_multiple_scans(JPEGState* sp)
{
return CALLJPEG(sp, 0, jpeg_has_multiple_scans(&sp->cinfo.d));
}
static int
TIFFjpeg_start_decompress(JPEGState* sp)
{
const char* sz_max_allowed_scan_number;
/* progress monitor */
sp->cinfo.d.progress = &sp->progress;
sp->progress.progress_monitor = TIFFjpeg_progress_monitor;
sp->max_allowed_scan_number = 100;
sz_max_allowed_scan_number = getenv("LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER");
if( sz_max_allowed_scan_number )
sp->max_allowed_scan_number = atoi(sz_max_allowed_scan_number);
return CALLVJPEG(sp, jpeg_start_decompress(&sp->cinfo.d));
}
@ -583,9 +637,8 @@ std_term_source(j_decompress_ptr cinfo)
}
static void
TIFFjpeg_data_src(JPEGState* sp, TIFF* tif)
TIFFjpeg_data_src(JPEGState* sp)
{
(void) tif;
sp->cinfo.d.src = &sp->src;
sp->src.init_source = std_init_source;
sp->src.fill_input_buffer = std_fill_input_buffer;
@ -611,9 +664,9 @@ tables_init_source(j_decompress_ptr cinfo)
}
static void
TIFFjpeg_tables_src(JPEGState* sp, TIFF* tif)
TIFFjpeg_tables_src(JPEGState* sp)
{
TIFFjpeg_data_src(sp, tif);
TIFFjpeg_data_src(sp);
sp->src.init_source = tables_init_source;
}
@ -658,7 +711,9 @@ alloc_downsampled_buffers(TIFF* tif, jpeg_component_info* comp_info,
#define JPEG_MARKER_SOF0 0xC0
#define JPEG_MARKER_SOF1 0xC1
#define JPEG_MARKER_SOF3 0xC3
#define JPEG_MARKER_SOF2 0xC2
#define JPEG_MARKER_SOF9 0xC9
#define JPEG_MARKER_SOF10 0xCA
#define JPEG_MARKER_DHT 0xC4
#define JPEG_MARKER_SOI 0xD8
#define JPEG_MARKER_SOS 0xDA
@ -689,9 +744,11 @@ static int
JPEGFixupTags(TIFF* tif)
{
#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING
JPEGState* sp = JState(tif);
if ((tif->tif_dir.td_photometric==PHOTOMETRIC_YCBCR)&&
(tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)&&
(tif->tif_dir.td_samplesperpixel==3))
(tif->tif_dir.td_samplesperpixel==3) &&
!sp->ycbcrsampling_fetched)
JPEGFixupTagsSubsampling(tif);
#endif
@ -729,6 +786,7 @@ JPEGFixupTagsSubsampling(TIFF* tif)
_TIFFFillStriles( tif );
if( tif->tif_dir.td_stripbytecount == NULL
|| tif->tif_dir.td_stripoffset == NULL
|| tif->tif_dir.td_stripbytecount[0] == 0 )
{
/* Do not even try to check if the first strip/tile does not
@ -816,8 +874,11 @@ JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData* data)
JPEGFixupTagsSubsamplingSkip(data,n);
}
break;
case JPEG_MARKER_SOF0:
case JPEG_MARKER_SOF1:
case JPEG_MARKER_SOF0: /* Baseline sequential Huffman */
case JPEG_MARKER_SOF1: /* Extended sequential Huffman */
case JPEG_MARKER_SOF2: /* Progressive Huffman: normally not allowed by TechNote, but that doesn't hurt supporting it */
case JPEG_MARKER_SOF9: /* Extended sequential arithmetic */
case JPEG_MARKER_SOF10: /* Progressive arithmetic: normally not allowed by TechNote, but that doesn't hurt supporting it */
/* this marker contains the subsampling factors we're scanning for */
{
uint16 n;
@ -925,7 +986,7 @@ JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData* data, uint16 s
else
{
uint16 m;
m=skiplength-data->bufferbytesleft;
m=(uint16)(skiplength-data->bufferbytesleft);
if (m<=data->filebytesleft)
{
data->bufferbytesleft=0;
@ -962,7 +1023,7 @@ JPEGSetupDecode(TIFF* tif)
/* Read JPEGTables if it is present */
if (TIFFFieldSet(tif,FIELD_JPEGTABLES)) {
TIFFjpeg_tables_src(sp, tif);
TIFFjpeg_tables_src(sp);
if(TIFFjpeg_read_header(sp,FALSE) != JPEG_HEADER_TABLES_ONLY) {
TIFFErrorExt(tif->tif_clientdata, "JPEGSetupDecode", "Bogus JPEGTables field");
return (0);
@ -984,15 +1045,51 @@ JPEGSetupDecode(TIFF* tif)
}
/* Set up for reading normal data */
TIFFjpeg_data_src(sp, tif);
TIFFjpeg_data_src(sp);
tif->tif_postdecode = _TIFFNoPostDecode; /* override byte swapping */
return (1);
}
/* Returns 1 if the full strip should be read, even when doing scanline per */
/* scanline decoding. This happens when the JPEG stream uses multiple scans. */
/* Currently only called in CHUNKY_STRIP_READ_SUPPORT mode through */
/* scanline interface. */
/* Only reads tif->tif_dir.td_bitspersample, tif->tif_rawdata and */
/* tif->tif_rawcc members. */
/* Can be called independently of the usual setup/predecode/decode states */
int TIFFJPEGIsFullStripRequired(TIFF* tif)
{
int ret;
JPEGState state;
#if defined(JPEG_DUAL_MODE_8_12) && !defined(TIFFJPEGIsFullStripRequired)
if( tif->tif_dir.td_bitspersample == 12 )
return TIFFJPEGIsFullStripRequired_12( tif );
#endif
memset(&state, 0, sizeof(JPEGState));
state.tif = tif;
TIFFjpeg_create_decompress(&state);
TIFFjpeg_data_src(&state);
if (TIFFjpeg_read_header(&state, TRUE) != JPEG_HEADER_OK)
{
TIFFjpeg_destroy(&state);
return (0);
}
ret = TIFFjpeg_has_multiple_scans(&state);
TIFFjpeg_destroy(&state);
return ret;
}
/*
* Set up for decoding a strip or tile.
*/
static int
/*ARGSUSED*/ static int
JPEGPreDecode(TIFF* tif, uint16 s)
{
JPEGState *sp = JState(tif);
@ -1029,13 +1126,13 @@ JPEGPreDecode(TIFF* tif, uint16 s)
/*
* Check image parameters and set decompression parameters.
*/
segment_width = td->td_imagewidth;
segment_height = td->td_imagelength - tif->tif_row;
if (isTiled(tif)) {
segment_width = td->td_tilewidth;
segment_height = td->td_tilelength;
sp->bytesperline = TIFFTileRowSize(tif);
} else {
segment_width = td->td_imagewidth;
segment_height = td->td_imagelength - tif->tif_row;
if (segment_height > td->td_rowsperstrip)
segment_height = td->td_rowsperstrip;
sp->bytesperline = TIFFScanlineSize(tif);
@ -1057,7 +1154,21 @@ JPEGPreDecode(TIFF* tif, uint16 s)
sp->cinfo.d.image_width,
sp->cinfo.d.image_height);
}
if (sp->cinfo.d.image_width > segment_width ||
if( sp->cinfo.d.image_width == segment_width &&
sp->cinfo.d.image_height > segment_height &&
tif->tif_row + segment_height == td->td_imagelength &&
!isTiled(tif) ) {
/* Some files have a last strip, that should be truncated, */
/* but their JPEG codestream has still the maximum strip */
/* height. Warn about this as this is non compliant, but */
/* we can safely recover from that. */
TIFFWarningExt(tif->tif_clientdata, module,
"JPEG strip size exceeds expected dimensions,"
" expected %dx%d, got %dx%d",
segment_width, segment_height,
sp->cinfo.d.image_width, sp->cinfo.d.image_height);
}
else if (sp->cinfo.d.image_width > segment_width ||
sp->cinfo.d.image_height > segment_height) {
/*
* This case could be dangerous, if the strip or tile size has
@ -1091,6 +1202,47 @@ JPEGPreDecode(TIFF* tif, uint16 s)
return (0);
}
#endif
/* In some cases, libjpeg needs to allocate a lot of memory */
/* http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf */
if( TIFFjpeg_has_multiple_scans(sp) )
{
/* In this case libjpeg will need to allocate memory or backing */
/* store for all coefficients */
/* See call to jinit_d_coef_controller() from master_selection() */
/* in libjpeg */
toff_t nRequiredMemory = (toff_t)sp->cinfo.d.image_width *
sp->cinfo.d.image_height *
sp->cinfo.d.num_components *
((td->td_bitspersample+7)/8);
/* BLOCK_SMOOTHING_SUPPORTED is generally defined, so we need */
/* to replicate the logic of jinit_d_coef_controller() */
if( sp->cinfo.d.progressive_mode )
nRequiredMemory *= 3;
#ifndef TIFF_LIBJPEG_LARGEST_MEM_ALLOC
#define TIFF_LIBJPEG_LARGEST_MEM_ALLOC (100 * 1024 * 1024)
#endif
if( nRequiredMemory > TIFF_LIBJPEG_LARGEST_MEM_ALLOC &&
getenv("LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC") == NULL )
{
TIFFErrorExt(tif->tif_clientdata, module,
"Reading this strip would require libjpeg to allocate "
"at least %u bytes. "
"This is disabled since above the %u threshold. "
"You may override this restriction by defining the "
"LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC environment variable, "
"or recompile libtiff by defining the "
"TIFF_LIBJPEG_LARGEST_MEM_ALLOC macro to a value greater "
"than %u",
(unsigned)nRequiredMemory,
(unsigned)TIFF_LIBJPEG_LARGEST_MEM_ALLOC,
(unsigned)TIFF_LIBJPEG_LARGEST_MEM_ALLOC);
return (0);
}
}
if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
/* Component 0 should have expected sampling factors */
if (sp->cinfo.d.comp_info[0].h_samp_factor != sp->h_sampling ||
@ -1138,6 +1290,9 @@ JPEGPreDecode(TIFF* tif, uint16 s)
if (downsampled_output) {
/* Need to use raw-data interface to libjpeg */
sp->cinfo.d.raw_data_out = TRUE;
#if JPEG_LIB_VERSION >= 70
sp->cinfo.d.do_fancy_upsampling = FALSE;
#endif /* JPEG_LIB_VERSION >= 70 */
tif->tif_decoderow = DecodeRowError;
tif->tif_decodestrip = JPEGDecodeRaw;
tif->tif_decodetile = JPEGDecodeRaw;
@ -1165,6 +1320,63 @@ JPEGPreDecode(TIFF* tif, uint16 s)
* Decode a chunk of pixels.
* "Standard" case: returned data is not downsampled.
*/
#if !JPEG_LIB_MK1_OR_12BIT
static int
JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
{
JPEGState *sp = JState(tif);
tmsize_t nrows;
(void) s;
/*
** Update available information, buffer may have been refilled
** between decode requests
*/
sp->src.next_input_byte = (const JOCTET*) tif->tif_rawcp;
sp->src.bytes_in_buffer = (size_t) tif->tif_rawcc;
if( sp->bytesperline == 0 )
return 0;
nrows = cc / sp->bytesperline;
if (cc % sp->bytesperline)
TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
"fractional scanline not read");
if( nrows > (tmsize_t) sp->cinfo.d.image_height )
nrows = sp->cinfo.d.image_height;
/* data is expected to be read in multiples of a scanline */
if (nrows)
{
do
{
/*
* In the libjpeg6b-9a 8bit case. We read directly into
* the TIFF buffer.
*/
JSAMPROW bufptr = (JSAMPROW)buf;
if (TIFFjpeg_read_scanlines(sp, &bufptr, 1) != 1)
return (0);
++tif->tif_row;
buf += sp->bytesperline;
cc -= sp->bytesperline;
} while (--nrows > 0);
}
/* Update information on consumed data */
tif->tif_rawcp = (uint8*) sp->src.next_input_byte;
tif->tif_rawcc = sp->src.bytes_in_buffer;
/* Close down the decompressor if we've finished the strip or tile. */
return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height
|| TIFFjpeg_finish_decompress(sp);
}
#endif /* !JPEG_LIB_MK1_OR_12BIT */
#if JPEG_LIB_MK1_OR_12BIT
/*ARGSUSED*/ static int
JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
{
@ -1184,7 +1396,8 @@ JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
nrows = cc / sp->bytesperline;
if (cc % sp->bytesperline)
TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "fractional scanline not read");
TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
"fractional scanline not read");
if( nrows > (tmsize_t) sp->cinfo.d.image_height )
nrows = sp->cinfo.d.image_height;
@ -1198,22 +1411,22 @@ JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
* For 6B, only use temporary buffer for 12 bit imagery.
* For Mk1 always use it.
*/
#if !defined(JPEG_LIB_MK1)
if( sp->cinfo.d.data_precision == 12 )
#endif
{
line_work_buf = (JSAMPROW)
_TIFFmalloc(sizeof(short) * sp->cinfo.d.output_width
* sp->cinfo.d.num_components );
}
do {
do
{
if( line_work_buf != NULL )
{
/*
* In the MK1 case, we aways read into a 16bit buffer, and then
* pack down to 12bit or 8bit. In 6B case we only read into 16
* bit buffer for 12bit data, which we need to repack.
* In the MK1 case, we always read into a 16bit
* buffer, and then pack down to 12bit or 8bit.
* In 6B case we only read into 16 bit buffer
* for 12bit data, which we need to repack.
*/
if (TIFFjpeg_read_scanlines(sp, &line_work_buf, 1) != 1)
return (0);
@ -1230,10 +1443,10 @@ JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
((unsigned char *) buf) + iPair * 3;
JSAMPLE *in_ptr = line_work_buf + iPair * 2;
out_ptr[0] = (in_ptr[0] & 0xff0) >> 4;
out_ptr[1] = ((in_ptr[0] & 0xf) << 4)
| ((in_ptr[1] & 0xf00) >> 8);
out_ptr[2] = ((in_ptr[1] & 0xff) >> 0);
out_ptr[0] = (unsigned char)((in_ptr[0] & 0xff0) >> 4);
out_ptr[1] = (unsigned char)(((in_ptr[0] & 0xf) << 4)
| ((in_ptr[1] & 0xf00) >> 8));
out_ptr[2] = (unsigned char)(((in_ptr[1] & 0xff) >> 0));
}
}
else if( sp->cinfo.d.data_precision == 8 )
@ -1249,17 +1462,6 @@ JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
}
}
}
else
{
/*
* In the libjpeg6b 8bit case. We read directly into the
* TIFF buffer.
*/
JSAMPROW bufptr = (JSAMPROW)buf;
if (TIFFjpeg_read_scanlines(sp, &bufptr, 1) != 1)
return (0);
}
++tif->tif_row;
buf += sp->bytesperline;
@ -1278,6 +1480,7 @@ JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height
|| TIFFjpeg_finish_decompress(sp);
}
#endif /* JPEG_LIB_MK1_OR_12BIT */
/*ARGSUSED*/ static int
DecodeRowError(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
@ -1301,10 +1504,18 @@ JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
{
JPEGState *sp = JState(tif);
tmsize_t nrows;
TIFFDirectory *td = &tif->tif_dir;
(void) s;
nrows = sp->cinfo.d.image_height;
/* For last strip, limit number of rows to its truncated height */
/* even if the codestream height is larger (which is not compliant, */
/* but that we tolerate) */
if( (uint32)nrows > td->td_imagelength - tif->tif_row && !isTiled(tif) )
nrows = td->td_imagelength - tif->tif_row;
/* data is expected to be read in multiples of a scanline */
if ( (nrows = sp->cinfo.d.image_height) ) {
if ( nrows != 0 ) {
/* Cb,Cr both have sampling factors 1, so this is correct */
JDIMENSION clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width;
@ -1357,7 +1568,7 @@ JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
JSAMPLE *outptr = (JSAMPLE*)tmpbuf + clumpoffset;
#else
JSAMPLE *outptr = (JSAMPLE*)buf + clumpoffset;
if (cc < clumpoffset + samples_per_clump*(clumps_per_line-1) + hsamp) {
if (cc < (tmsize_t) (clumpoffset + samples_per_clump*(clumps_per_line-1) + hsamp)) {
TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw",
"application buffer not large enough for all data, possible subsampling issue");
return 0;
@ -1404,10 +1615,10 @@ JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
{
unsigned char *out_ptr = ((unsigned char *) buf) + iPair * 3;
JSAMPLE *in_ptr = (JSAMPLE *) (tmpbuf + iPair * 2);
out_ptr[0] = (in_ptr[0] & 0xff0) >> 4;
out_ptr[1] = ((in_ptr[0] & 0xf) << 4)
| ((in_ptr[1] & 0xf00) >> 8);
out_ptr[2] = ((in_ptr[1] & 0xff) >> 0);
out_ptr[0] = (unsigned char)((in_ptr[0] & 0xff0) >> 4);
out_ptr[1] = (unsigned char)(((in_ptr[0] & 0xf) << 4)
| ((in_ptr[1] & 0xf00) >> 8));
out_ptr[2] = (unsigned char)(((in_ptr[1] & 0xff) >> 0));
}
}
}
@ -1447,6 +1658,15 @@ unsuppress_quant_table (JPEGState* sp, int tblno)
qtbl->sent_table = FALSE;
}
static void
suppress_quant_table (JPEGState* sp, int tblno)
{
JQUANT_TBL* qtbl;
if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL)
qtbl->sent_table = TRUE;
}
static void
unsuppress_huff_table (JPEGState* sp, int tblno)
{
@ -1458,6 +1678,17 @@ unsuppress_huff_table (JPEGState* sp, int tblno)
htbl->sent_table = FALSE;
}
static void
suppress_huff_table (JPEGState* sp, int tblno)
{
JHUFF_TBL* htbl;
if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL)
htbl->sent_table = TRUE;
if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL)
htbl->sent_table = TRUE;
}
static int
prepare_JPEGTables(TIFF* tif)
{
@ -1507,21 +1738,56 @@ JPEGSetupEncode(TIFF* tif)
assert(sp != NULL);
assert(!sp->cinfo.comm.is_decompressor);
sp->photometric = td->td_photometric;
/*
* Initialize all JPEG parameters to default values.
* Note that jpeg_set_defaults needs legal values for
* in_color_space and input_components.
*/
if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
sp->cinfo.c.input_components = td->td_samplesperpixel;
if (sp->photometric == PHOTOMETRIC_YCBCR) {
if (sp->jpegcolormode == JPEGCOLORMODE_RGB) {
sp->cinfo.c.in_color_space = JCS_RGB;
} else {
sp->cinfo.c.in_color_space = JCS_YCbCr;
}
} else {
if ((td->td_photometric == PHOTOMETRIC_MINISWHITE || td->td_photometric == PHOTOMETRIC_MINISBLACK) && td->td_samplesperpixel == 1)
sp->cinfo.c.in_color_space = JCS_GRAYSCALE;
else if (td->td_photometric == PHOTOMETRIC_RGB && td->td_samplesperpixel == 3)
sp->cinfo.c.in_color_space = JCS_RGB;
else if (td->td_photometric == PHOTOMETRIC_SEPARATED && td->td_samplesperpixel == 4)
sp->cinfo.c.in_color_space = JCS_CMYK;
else
sp->cinfo.c.in_color_space = JCS_UNKNOWN;
}
} else {
sp->cinfo.c.input_components = 1;
sp->cinfo.c.in_color_space = JCS_UNKNOWN;
}
if (!TIFFjpeg_set_defaults(sp))
return (0);
/* Set per-file parameters */
sp->photometric = td->td_photometric;
switch (sp->photometric) {
case PHOTOMETRIC_YCBCR:
sp->h_sampling = td->td_ycbcrsubsampling[0];
sp->v_sampling = td->td_ycbcrsubsampling[1];
if( sp->h_sampling == 0 || sp->v_sampling == 0 )
{
TIFFErrorExt(tif->tif_clientdata, module,
"Invalig horizontal/vertical sampling value");
return (0);
}
if( td->td_bitspersample > 16 )
{
TIFFErrorExt(tif->tif_clientdata, module,
"BitsPerSample %d not allowed for JPEG",
td->td_bitspersample);
return (0);
}
/*
* A ReferenceBlackWhite field *must* be present since the
* default value is inappropriate for YCbCr. Fill in the
@ -1677,10 +1943,7 @@ JPEGPreEncode(TIFF* tif, uint16 s)
if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
sp->cinfo.c.input_components = td->td_samplesperpixel;
if (sp->photometric == PHOTOMETRIC_YCBCR) {
if (sp->jpegcolormode == JPEGCOLORMODE_RGB) {
sp->cinfo.c.in_color_space = JCS_RGB;
} else {
sp->cinfo.c.in_color_space = JCS_YCbCr;
if (sp->jpegcolormode != JPEGCOLORMODE_RGB) {
if (sp->h_sampling != 1 || sp->v_sampling != 1)
downsampled_input = TRUE;
}
@ -1693,21 +1956,11 @@ JPEGPreEncode(TIFF* tif, uint16 s)
sp->cinfo.c.comp_info[0].h_samp_factor = sp->h_sampling;
sp->cinfo.c.comp_info[0].v_samp_factor = sp->v_sampling;
} else {
if ((td->td_photometric == PHOTOMETRIC_MINISWHITE || td->td_photometric == PHOTOMETRIC_MINISBLACK) && td->td_samplesperpixel == 1)
sp->cinfo.c.in_color_space = JCS_GRAYSCALE;
else if (td->td_photometric == PHOTOMETRIC_RGB)
sp->cinfo.c.in_color_space = JCS_RGB;
else if (td->td_photometric == PHOTOMETRIC_SEPARATED && td->td_samplesperpixel == 4)
sp->cinfo.c.in_color_space = JCS_CMYK;
else
sp->cinfo.c.in_color_space = JCS_UNKNOWN;
if (!TIFFjpeg_set_colorspace(sp, sp->cinfo.c.in_color_space))
return (0);
/* jpeg_set_colorspace set all sampling factors to 1 */
}
} else {
sp->cinfo.c.input_components = 1;
sp->cinfo.c.in_color_space = JCS_UNKNOWN;
if (!TIFFjpeg_set_colorspace(sp, JCS_UNKNOWN))
return (0);
sp->cinfo.c.comp_info[0].component_id = s;
@ -1722,14 +1975,30 @@ JPEGPreEncode(TIFF* tif, uint16 s)
sp->cinfo.c.write_JFIF_header = FALSE;
sp->cinfo.c.write_Adobe_marker = FALSE;
/* set up table handling correctly */
/* calling TIFFjpeg_set_quality() causes quantization tables to be flagged */
/* as being to be emitted, which we don't want in the JPEGTABLESMODE_QUANT */
/* mode, so we must manually suppress them. However TIFFjpeg_set_quality() */
/* should really be called when dealing with files with directories with */
/* mixed qualities. see http://trac.osgeo.org/gdal/ticket/3539 */
if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE))
return (0);
if (! (sp->jpegtablesmode & JPEGTABLESMODE_QUANT)) {
if (sp->jpegtablesmode & JPEGTABLESMODE_QUANT) {
suppress_quant_table(sp, 0);
suppress_quant_table(sp, 1);
}
else {
unsuppress_quant_table(sp, 0);
unsuppress_quant_table(sp, 1);
}
if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF)
{
/* Explicit suppression is only needed if we did not go through the */
/* prepare_JPEGTables() code path, which may be the case if updating */
/* an existing file */
suppress_huff_table(sp, 0);
suppress_huff_table(sp, 1);
sp->cinfo.c.optimize_coding = FALSE;
}
else
sp->cinfo.c.optimize_coding = TRUE;
if (downsampled_input) {
@ -1786,9 +2055,16 @@ JPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
if( sp->cinfo.c.data_precision == 12 )
{
line16_count = (sp->bytesperline * 2) / 3;
line16_count = (int)((sp->bytesperline * 2) / 3);
line16 = (short *) _TIFFmalloc(sizeof(short) * line16_count);
// FIXME: undiagnosed malloc failure
if (!line16)
{
TIFFErrorExt(tif->tif_clientdata,
"JPEGEncode",
"Failed to allocate memory");
return 0;
}
}
while (nrows-- > 0) {
@ -1963,13 +2239,10 @@ JPEGCleanup(TIFF* tif)
tif->tif_tagmethods.vgetfield = sp->vgetparent;
tif->tif_tagmethods.vsetfield = sp->vsetparent;
tif->tif_tagmethods.printdir = sp->printdir;
if( sp != NULL ) {
if( sp->cinfo_initialized )
TIFFjpeg_destroy(sp); /* release libjpeg resources */
if (sp->jpegtables) /* tag value */
_TIFFfree(sp->jpegtables);
}
_TIFFfree(tif->tif_data); /* release local state */
tif->tif_data = NULL;
@ -2027,8 +2300,7 @@ JPEGVSetField(TIFF* tif, uint32 tag, va_list ap)
/* XXX */
return (0);
}
_TIFFsetByteArray(&sp->jpegtables, va_arg(ap, void*),
(long) v32);
_TIFFsetByteArray(&sp->jpegtables, va_arg(ap, void*), v32);
sp->jpegtables_length = v32;
TIFFSetFieldBit(tif, FIELD_JPEGTABLES);
break;
@ -2057,7 +2329,7 @@ JPEGVSetField(TIFF* tif, uint32 tag, va_list ap)
return (*sp->vsetparent)(tif, tag, ap);
}
if ((fip = TIFFFieldWithTag(tif, tag))) {
if ((fip = TIFFFieldWithTag(tif, tag)) != NULL) {
TIFFSetFieldBit(tif, fip->field_bit);
} else {
return (0);
@ -2181,6 +2453,25 @@ static int JPEGInitializeLibJPEG( TIFF * tif, int decompress )
} else {
if (!TIFFjpeg_create_compress(sp))
return (0);
#ifndef TIFF_JPEG_MAX_MEMORY_TO_USE
#define TIFF_JPEG_MAX_MEMORY_TO_USE (10 * 1024 * 1024)
#endif
/* libjpeg turbo 1.5.2 honours max_memory_to_use, but has no backing */
/* store implementation, so better not set max_memory_to_use ourselves. */
/* See https://github.com/libjpeg-turbo/libjpeg-turbo/issues/162 */
if( sp->cinfo.c.mem->max_memory_to_use > 0 )
{
/* This is to address bug related in ticket GDAL #1795. */
if (getenv("JPEGMEM") == NULL)
{
/* Increase the max memory usable. This helps when creating files */
/* with "big" tile, without using libjpeg temporary files. */
/* For example a 512x512 tile with 3 bands */
/* requires 1.5 MB which is above libjpeg 1MB default */
if( sp->cinfo.c.mem->max_memory_to_use < TIFF_JPEG_MAX_MEMORY_TO_USE )
sp->cinfo.c.mem->max_memory_to_use = TIFF_JPEG_MAX_MEMORY_TO_USE;
}
}
}
sp->cinfo_initialized = TRUE;
@ -2281,8 +2572,17 @@ here hopefully is harmless.
*/
sp->jpegtables_length = SIZE_OF_JPEGTABLES;
sp->jpegtables = (void *) _TIFFmalloc(sp->jpegtables_length);
// FIXME: NULL-deref after malloc failure
if (sp->jpegtables)
{
_TIFFmemset(sp->jpegtables, 0, SIZE_OF_JPEGTABLES);
}
else
{
TIFFErrorExt(tif->tif_clientdata,
"TIFFInitJPEG",
"Failed to allocate memory for JPEG tables");
return 0;
}
#undef SIZE_OF_JPEGTABLES
}

@ -4,6 +4,10 @@
#if defined(JPEG_DUAL_MODE_8_12)
# define TIFFInitJPEG TIFFInitJPEG_12
# define TIFFJPEGIsFullStripRequired TIFFJPEGIsFullStripRequired_12
int
TIFFInitJPEG_12(TIFF* tif, int scheme);
# include LIBJPEG_12_PATH

@ -1,4 +1,4 @@
/* $Id: tif_luv.c,v 1.35 2011-04-02 20:54:09 bfriesen Exp $ */
/* $Id: tif_luv.c,v 1.49 2017-07-24 12:47:30 erouault Exp $ */
/*
* Copyright (c) 1997 Greg Ward Larson
@ -158,6 +158,7 @@
typedef struct logLuvState LogLuvState;
struct logLuvState {
int encoder_state; /* 1 if encoder correctly initialized */
int user_datafmt; /* user data format */
int encode_meth; /* encoding method */
int pixel_size; /* bytes per pixel */
@ -202,7 +203,11 @@ LogL16Decode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
if (sp->user_datafmt == SGILOGDATAFMT_16BIT)
tp = (int16*) op;
else {
assert(sp->tbuflen >= npixels);
if(sp->tbuflen < npixels) {
TIFFErrorExt(tif->tif_clientdata, module,
"Translation buffer too short");
return (0);
}
tp = (int16*) sp->tbuf;
}
_TIFFmemset((void*) tp, 0, npixels*sizeof (tp[0]));
@ -211,9 +216,11 @@ LogL16Decode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
cc = tif->tif_rawcc;
/* get each byte string */
for (shft = 2*8; (shft -= 8) >= 0; ) {
for (i = 0; i < npixels && cc > 0; )
for (i = 0; i < npixels && cc > 0; ) {
if (*bp >= 128) { /* run */
rc = *bp++ + (2-128); /* TODO: potential input buffer overrun when decoding corrupt or truncated data */
if( cc < 2 )
break;
rc = *bp++ + (2-128);
b = (int16)(*bp++ << shft);
cc -= 2;
while (rc-- && i < npixels)
@ -223,6 +230,7 @@ LogL16Decode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
while (--cc && rc-- && i < npixels)
tp[i++] |= (int16)*bp++ << shft;
}
}
if (i != npixels) {
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFErrorExt(tif->tif_clientdata, module,
@ -268,13 +276,17 @@ LogLuvDecode24(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
if (sp->user_datafmt == SGILOGDATAFMT_RAW)
tp = (uint32 *)op;
else {
assert(sp->tbuflen >= npixels);
if(sp->tbuflen < npixels) {
TIFFErrorExt(tif->tif_clientdata, module,
"Translation buffer too short");
return (0);
}
tp = (uint32 *) sp->tbuf;
}
/* copy to array of uint32 */
bp = (unsigned char*) tif->tif_rawcp;
cc = tif->tif_rawcc;
for (i = 0; i < npixels && cc > 0; i++) {
for (i = 0; i < npixels && cc >= 3; i++) {
tp[i] = bp[0] << 16 | bp[1] << 8 | bp[2];
bp += 3;
cc -= 3;
@ -325,7 +337,11 @@ LogLuvDecode32(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
if (sp->user_datafmt == SGILOGDATAFMT_RAW)
tp = (uint32*) op;
else {
assert(sp->tbuflen >= npixels);
if(sp->tbuflen < npixels) {
TIFFErrorExt(tif->tif_clientdata, module,
"Translation buffer too short");
return (0);
}
tp = (uint32*) sp->tbuf;
}
_TIFFmemset((void*) tp, 0, npixels*sizeof (tp[0]));
@ -334,11 +350,13 @@ LogLuvDecode32(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
cc = tif->tif_rawcc;
/* get each byte string */
for (shft = 4*8; (shft -= 8) >= 0; ) {
for (i = 0; i < npixels && cc > 0; )
for (i = 0; i < npixels && cc > 0; ) {
if (*bp >= 128) { /* run */
if( cc < 2 )
break;
rc = *bp++ + (2-128);
b = (uint32)*bp++ << shft;
cc -= 2; /* TODO: potential input buffer overrun when decoding corrupt or truncated data */
cc -= 2;
while (rc-- && i < npixels)
tp[i++] |= b;
} else { /* non-run */
@ -346,6 +364,7 @@ LogLuvDecode32(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
while (--cc && rc-- && i < npixels)
tp[i++] |= (uint32)*bp++ << shft;
}
}
if (i != npixels) {
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFErrorExt(tif->tif_clientdata, module,
@ -379,9 +398,14 @@ LogLuvDecodeStrip(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
{
tmsize_t rowlen = TIFFScanlineSize(tif);
if (rowlen == 0)
return 0;
assert(cc%rowlen == 0);
while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s))
bp += rowlen, cc -= rowlen;
while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s)) {
bp += rowlen;
cc -= rowlen;
}
return (cc == 0);
}
@ -395,9 +419,14 @@ LogLuvDecodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
{
tmsize_t rowlen = TIFFTileRowSize(tif);
if (rowlen == 0)
return 0;
assert(cc%rowlen == 0);
while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s))
bp += rowlen, cc -= rowlen;
while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s)) {
bp += rowlen;
cc -= rowlen;
}
return (cc == 0);
}
@ -407,6 +436,7 @@ LogLuvDecodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
static int
LogL16Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
{
static const char module[] = "LogL16Encode";
LogLuvState* sp = EncoderState(tif);
int shft;
tmsize_t i;
@ -427,7 +457,11 @@ LogL16Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
tp = (int16*) bp;
else {
tp = (int16*) sp->tbuf;
assert(sp->tbuflen >= npixels);
if(sp->tbuflen < npixels) {
TIFFErrorExt(tif->tif_clientdata, module,
"Translation buffer too short");
return (0);
}
(*sp->tfunc)(sp, bp, npixels);
}
/* compress each byte string */
@ -439,7 +473,7 @@ LogL16Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
tif->tif_rawcp = op;
tif->tif_rawcc = tif->tif_rawdatasize - occ;
if (!TIFFFlushData1(tif))
return (-1);
return (0);
op = tif->tif_rawcp;
occ = tif->tif_rawdatasize - tif->tif_rawcc;
}
@ -471,7 +505,7 @@ LogL16Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
tif->tif_rawcp = op;
tif->tif_rawcc = tif->tif_rawdatasize - occ;
if (!TIFFFlushData1(tif))
return (-1);
return (0);
op = tif->tif_rawcp;
occ = tif->tif_rawdatasize - tif->tif_rawcc;
}
@ -500,6 +534,7 @@ LogL16Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
static int
LogLuvEncode24(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
{
static const char module[] = "LogLuvEncode24";
LogLuvState* sp = EncoderState(tif);
tmsize_t i;
tmsize_t npixels;
@ -515,7 +550,11 @@ LogLuvEncode24(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
tp = (uint32*) bp;
else {
tp = (uint32*) sp->tbuf;
assert(sp->tbuflen >= npixels);
if(sp->tbuflen < npixels) {
TIFFErrorExt(tif->tif_clientdata, module,
"Translation buffer too short");
return (0);
}
(*sp->tfunc)(sp, bp, npixels);
}
/* write out encoded pixels */
@ -526,7 +565,7 @@ LogLuvEncode24(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
tif->tif_rawcp = op;
tif->tif_rawcc = tif->tif_rawdatasize - occ;
if (!TIFFFlushData1(tif))
return (-1);
return (0);
op = tif->tif_rawcp;
occ = tif->tif_rawdatasize - tif->tif_rawcc;
}
@ -547,6 +586,7 @@ LogLuvEncode24(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
static int
LogLuvEncode32(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
{
static const char module[] = "LogLuvEncode32";
LogLuvState* sp = EncoderState(tif);
int shft;
tmsize_t i;
@ -568,7 +608,11 @@ LogLuvEncode32(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
tp = (uint32*) bp;
else {
tp = (uint32*) sp->tbuf;
assert(sp->tbuflen >= npixels);
if(sp->tbuflen < npixels) {
TIFFErrorExt(tif->tif_clientdata, module,
"Translation buffer too short");
return (0);
}
(*sp->tfunc)(sp, bp, npixels);
}
/* compress each byte string */
@ -580,7 +624,7 @@ LogLuvEncode32(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
tif->tif_rawcp = op;
tif->tif_rawcc = tif->tif_rawdatasize - occ;
if (!TIFFFlushData1(tif))
return (-1);
return (0);
op = tif->tif_rawcp;
occ = tif->tif_rawdatasize - tif->tif_rawcc;
}
@ -612,7 +656,7 @@ LogLuvEncode32(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
tif->tif_rawcp = op;
tif->tif_rawcc = tif->tif_rawdatasize - occ;
if (!TIFFFlushData1(tif))
return (-1);
return (0);
op = tif->tif_rawcp;
occ = tif->tif_rawdatasize - tif->tif_rawcc;
}
@ -644,9 +688,14 @@ LogLuvEncodeStrip(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
{
tmsize_t rowlen = TIFFScanlineSize(tif);
if (rowlen == 0)
return 0;
assert(cc%rowlen == 0);
while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1)
bp += rowlen, cc -= rowlen;
while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1) {
bp += rowlen;
cc -= rowlen;
}
return (cc == 0);
}
@ -659,9 +708,14 @@ LogLuvEncodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
{
tmsize_t rowlen = TIFFTileRowSize(tif);
if (rowlen == 0)
return 0;
assert(cc%rowlen == 0);
while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1)
bp += rowlen, cc -= rowlen;
while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1) {
bp += rowlen;
cc -= rowlen;
}
return (cc == 0);
}
@ -683,7 +737,9 @@ LogLuvEncodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#undef log2 /* Conflict with C'99 function */
#define log2(x) ((1./M_LN2)*log(x))
#undef exp2 /* Conflict with C'99 function */
#define exp2(x) exp(M_LN2*(x))
#define itrunc(x,m) ((m)==SGILOGENCODE_NODITHER ? \
@ -1208,15 +1264,16 @@ LogL16GuessDataFmt(TIFFDirectory *td)
return (SGILOGDATAFMT_UNKNOWN);
}
#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0))
#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1)
static tmsize_t
multiply_ms(tmsize_t m1, tmsize_t m2)
{
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;
}
static int
@ -1229,6 +1286,14 @@ LogL16InitState(TIFF* tif)
assert(sp != NULL);
assert(td->td_photometric == PHOTOMETRIC_LOGL);
if( td->td_samplesperpixel != 1 )
{
TIFFErrorExt(tif->tif_clientdata, module,
"Sorry, can not handle LogL image with %s=%d",
"Samples/pixel", td->td_samplesperpixel);
return 0;
}
/* for some reason, we can't do this in TIFFInitLogL16 */
if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN)
sp->user_datafmt = LogL16GuessDataFmt(td);
@ -1249,8 +1314,10 @@ LogL16InitState(TIFF* tif)
}
if( isTiled(tif) )
sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength);
else
else if( td->td_rowsperstrip < td->td_imagelength )
sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip);
else
sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_imagelength);
if (multiply_ms(sp->tbuflen, sizeof (int16)) == 0 ||
(sp->tbuf = (uint8*) _TIFFmalloc(sp->tbuflen * sizeof (int16))) == NULL) {
TIFFErrorExt(tif->tif_clientdata, module, "No space for SGILog translation buffer");
@ -1349,8 +1416,10 @@ LogLuvInitState(TIFF* tif)
}
if( isTiled(tif) )
sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength);
else
else if( td->td_rowsperstrip < td->td_imagelength )
sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip);
else
sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_imagelength);
if (multiply_ms(sp->tbuflen, sizeof (uint32)) == 0 ||
(sp->tbuf = (uint8*) _TIFFmalloc(sp->tbuflen * sizeof (uint32))) == NULL) {
TIFFErrorExt(tif->tif_clientdata, module, "No space for SGILog translation buffer");
@ -1489,6 +1558,7 @@ LogLuvSetupEncode(TIFF* tif)
td->td_photometric, "must be either LogLUV or LogL");
break;
}
sp->encoder_state = 1;
return (1);
notsupported:
TIFFErrorExt(tif->tif_clientdata, module,
@ -1500,20 +1570,28 @@ notsupported:
static void
LogLuvClose(TIFF* tif)
{
LogLuvState* sp = (LogLuvState*) tif->tif_data;
TIFFDirectory *td = &tif->tif_dir;
assert(sp != 0);
/*
* For consistency, we always want to write out the same
* bitspersample and sampleformat for our TIFF file,
* regardless of the data format being used by the application.
* Since this routine is called after tags have been set but
* before they have been recorded in the file, we reset them here.
* Note: this is really a nasty approach. See PixarLogClose
*/
if( sp->encoder_state )
{
/* See PixarLogClose. Might avoid issues with tags whose size depends
* on those below, but not completely sure this is enough. */
td->td_samplesperpixel =
(td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3;
td->td_bitspersample = 16;
td->td_sampleformat = SAMPLEFORMAT_INT;
}
}
static void
LogLuvCleanup(TIFF* tif)
@ -1551,17 +1629,21 @@ LogLuvVSetField(TIFF* tif, uint32 tag, va_list ap)
*/
switch (sp->user_datafmt) {
case SGILOGDATAFMT_FLOAT:
bps = 32, fmt = SAMPLEFORMAT_IEEEFP;
bps = 32;
fmt = SAMPLEFORMAT_IEEEFP;
break;
case SGILOGDATAFMT_16BIT:
bps = 16, fmt = SAMPLEFORMAT_INT;
bps = 16;
fmt = SAMPLEFORMAT_INT;
break;
case SGILOGDATAFMT_RAW:
bps = 32, fmt = SAMPLEFORMAT_UINT;
bps = 32;
fmt = SAMPLEFORMAT_UINT;
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
break;
case SGILOGDATAFMT_8BIT:
bps = 8, fmt = SAMPLEFORMAT_UINT;
bps = 8;
fmt = SAMPLEFORMAT_UINT;
break;
default:
TIFFErrorExt(tif->tif_clientdata, tif->tif_name,

@ -1,4 +1,4 @@
/* $Id: tif_lzma.c,v 1.4 2011-12-22 00:29:29 bfriesen Exp $ */
/* $Id: tif_lzma.c,v 1.6 2016-09-17 09:18:59 erouault Exp $ */
/*
* Copyright (c) 2010, Andrey Kiselev <dron@ak4719.spb.edu>
@ -95,7 +95,7 @@ LZMAStrerror(lzma_ret ret)
case LZMA_PROG_ERROR:
return "programming error";
default:
return "unindentified liblzma error";
return "unidentified liblzma error";
}
}
@ -490,6 +490,6 @@ bad:
"No space for LZMA2 state block");
return 0;
}
#endif /* LZMA_SUPORT */
#endif /* LZMA_SUPPORT */
/* vim: set ts=8 sts=8 sw=8 noet: */

@ -1,4 +1,4 @@
/* $Id: tif_lzw.c,v 1.45 2011-04-02 20:54:09 bfriesen Exp $ */
/* $Id: tif_lzw.c,v 1.57 2017-07-11 10:54:29 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -94,7 +94,7 @@ typedef struct {
unsigned short nbits; /* # of bits/code */
unsigned short maxcode; /* maximum code for lzw_nbits */
unsigned short free_ent; /* next free entry in hash table */
long nextdata; /* next bits of i/o */
unsigned long nextdata; /* next bits of i/o */
long nextbits; /* # of valid bits in lzw_nextdata */
int rw_mode; /* preserve rw_mode from init */
@ -240,8 +240,8 @@ LZWSetupDecode(TIFF* tif)
*/
code = 255;
do {
sp->dec_codetab[code].value = code;
sp->dec_codetab[code].firstchar = code;
sp->dec_codetab[code].value = (unsigned char)code;
sp->dec_codetab[code].firstchar = (unsigned char)code;
sp->dec_codetab[code].length = 1;
sp->dec_codetab[code].next = NULL;
} while (code--);
@ -268,12 +268,15 @@ LZWPreDecode(TIFF* tif, uint16 s)
if( sp->dec_codetab == NULL )
{
tif->tif_setupdecode( tif );
if( sp->dec_codetab == NULL )
return (0);
}
/*
* Check for old bit-reversed codes.
*/
if (tif->tif_rawdata[0] == 0 && (tif->tif_rawdata[1] & 0x1)) {
if (tif->tif_rawcc >= 2 &&
tif->tif_rawdata[0] == 0 && (tif->tif_rawdata[1] & 0x1)) {
#ifdef LZW_COMPAT
if (!sp->dec_decode) {
TIFFWarningExt(tif->tif_clientdata, module,
@ -316,7 +319,7 @@ LZWPreDecode(TIFF* tif, uint16 s)
sp->dec_restart = 0;
sp->dec_nbitsmask = MAXCODE(BITS_MIN);
#ifdef LZW_CHECKEOS
sp->dec_bitsleft = ((uint64)tif->tif_rawcc) << 3;
sp->dec_bitsleft = 0;
#endif
sp->dec_free_entp = sp->dec_codetab + CODE_FIRST;
/*
@ -365,7 +368,8 @@ LZWDecode(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
unsigned char *bp;
hcode_t code;
int len;
long nbits, nextbits, nextdata, nbitsmask;
long nbits, nextbits, nbitsmask;
unsigned long nextdata;
code_t *codep, *free_entp, *maxcodep, *oldcodep;
(void) s;
@ -408,19 +412,23 @@ LZWDecode(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
/*
* Residue satisfies only part of the decode request.
*/
op += residue, occ -= residue;
op += residue;
occ -= residue;
tp = op;
do {
int t;
--tp;
t = codep->value;
codep = codep->next;
*tp = t;
*tp = (char)t;
} while (--residue && codep);
sp->dec_restart = 0;
}
bp = (unsigned char *)tif->tif_rawcp;
#ifdef LZW_CHECKEOS
sp->dec_bitsleft = (((uint64)tif->tif_rawcc) << 3);
#endif
nbits = sp->lzw_nbits;
nextdata = sp->lzw_nextdata;
nextbits = sp->lzw_nextbits;
@ -434,6 +442,7 @@ LZWDecode(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
if (code == CODE_EOI)
break;
if (code == CODE_CLEAR) {
do {
free_entp = sp->dec_codetab + CODE_FIRST;
_TIFFmemset(free_entp, 0,
(CSIZE - CODE_FIRST) * sizeof (code_t));
@ -441,15 +450,17 @@ LZWDecode(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
nbitsmask = MAXCODE(BITS_MIN);
maxcodep = sp->dec_codetab + nbitsmask-1;
NextCode(tif, sp, bp, code, GetNextCode);
} while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */
if (code == CODE_EOI)
break;
if (code >= CODE_CLEAR) {
if (code > CODE_CLEAR) {
TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
"LZWDecode: Corrupted LZW table at scanline %d",
tif->tif_row);
return (0);
}
*op++ = (char)code, occ--;
*op++ = (char)code;
occ--;
oldcodep = sp->dec_codetab + code;
continue;
}
@ -527,18 +538,22 @@ LZWDecode(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
--tp;
t = codep->value;
codep = codep->next;
*tp = t;
*tp = (char)t;
} while (codep && tp > op);
if (codep) {
codeLoop(tif, module);
break;
}
assert(occ >= len);
op += len, occ -= len;
} else
*op++ = (char)code, occ--;
op += len;
occ -= len;
} else {
*op++ = (char)code;
occ--;
}
}
tif->tif_rawcc -= (tmsize_t)( (uint8*) bp - tif->tif_rawcp );
tif->tif_rawcp = (uint8*) bp;
sp->lzw_nbits = (unsigned short) nbits;
sp->lzw_nextdata = nextdata;
@ -630,7 +645,8 @@ LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
/*
* Residue satisfies only part of the decode request.
*/
op += residue, occ -= residue;
op += residue;
occ -= residue;
tp = op;
do {
*--tp = codep->value;
@ -640,6 +656,9 @@ 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);
#endif
nbits = sp->lzw_nbits;
nextdata = sp->lzw_nextdata;
nextbits = sp->lzw_nextbits;
@ -653,6 +672,7 @@ LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
if (code == CODE_EOI)
break;
if (code == CODE_CLEAR) {
do {
free_entp = sp->dec_codetab + CODE_FIRST;
_TIFFmemset(free_entp, 0,
(CSIZE - CODE_FIRST) * sizeof (code_t));
@ -660,15 +680,17 @@ LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
nbitsmask = MAXCODE(BITS_MIN);
maxcodep = sp->dec_codetab + nbitsmask;
NextCode(tif, sp, bp, code, GetNextCodeCompat);
} while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */
if (code == CODE_EOI)
break;
if (code >= CODE_CLEAR) {
if (code > CODE_CLEAR) {
TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
"LZWDecode: Corrupted LZW table at scanline %d",
tif->tif_row);
return (0);
}
*op++ = code, occ--;
*op++ = (char)code;
occ--;
oldcodep = sp->dec_codetab + code;
continue;
}
@ -734,17 +756,21 @@ LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
break;
}
assert(occ >= codep->length);
op += codep->length, occ -= codep->length;
op += codep->length;
occ -= codep->length;
tp = op;
do {
*--tp = codep->value;
} while( (codep = codep->next) != NULL );
} else
*op++ = code, occ--;
} else {
*op++ = (char)code;
occ--;
}
}
tif->tif_rawcc -= (tmsize_t)( (uint8*) bp - tif->tif_rawcp );
tif->tif_rawcp = (uint8*) bp;
sp->lzw_nbits = nbits;
sp->lzw_nbits = (unsigned short)nbits;
sp->lzw_nextdata = nextdata;
sp->lzw_nextbits = nextbits;
sp->dec_nbitsmask = nbitsmask;
@ -830,13 +856,15 @@ LZWPreEncode(TIFF* tif, uint16 s)
} else \
rat = (incount<<8) / outcount; \
}
/* Explicit 0xff masking to make icc -check=conversions happy */
#define PutNextCode(op, c) { \
nextdata = (nextdata << nbits) | c; \
nextbits += nbits; \
*op++ = (unsigned char)(nextdata >> (nextbits-8)); \
*op++ = (unsigned char)((nextdata >> (nextbits-8))&0xff); \
nextbits -= 8; \
if (nextbits >= 8) { \
*op++ = (unsigned char)(nextdata >> (nextbits-8)); \
*op++ = (unsigned char)((nextdata >> (nextbits-8))&0xff); \
nextbits -= 8; \
} \
outcount += nbits; \
@ -866,7 +894,8 @@ LZWEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
hcode_t ent;
long disp;
long incount, outcount, checkpoint;
long nextdata, nextbits;
unsigned long nextdata;
long nextbits;
int free_ent, maxcode, nbits;
uint8* op;
uint8* limit;
@ -890,7 +919,7 @@ LZWEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
nbits = sp->lzw_nbits;
op = tif->tif_rawcp;
limit = sp->enc_rawlimit;
ent = sp->enc_oldcode;
ent = (hcode_t)sp->enc_oldcode;
if (ent == (hcode_t) -1 && cc > 0) {
/*
@ -926,7 +955,7 @@ LZWEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
disp = 1;
do {
/*
* Avoid pointer arithmetic 'cuz of
* Avoid pointer arithmetic because of
* wraparound problems with segments.
*/
if ((h -= disp) < 0)
@ -949,12 +978,13 @@ LZWEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
*/
if (op > limit) {
tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata);
TIFFFlushData1(tif);
if( !TIFFFlushData1(tif) )
return 0;
op = tif->tif_rawdata;
}
PutNextCode(op, ent);
ent = c;
hp->code = free_ent++;
ent = (hcode_t)c;
hp->code = (hcode_t)(free_ent++);
hp->hash = fcode;
if (free_ent == CODE_MAX-1) {
/* table is full, emit clear code and reset */
@ -1011,9 +1041,9 @@ LZWEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
sp->enc_oldcode = ent;
sp->lzw_nextdata = nextdata;
sp->lzw_nextbits = nextbits;
sp->lzw_free_ent = free_ent;
sp->lzw_maxcode = maxcode;
sp->lzw_nbits = nbits;
sp->lzw_free_ent = (unsigned short)free_ent;
sp->lzw_maxcode = (unsigned short)maxcode;
sp->lzw_nbits = (unsigned short)nbits;
tif->tif_rawcp = op;
return (1);
}
@ -1028,22 +1058,43 @@ LZWPostEncode(TIFF* tif)
register LZWCodecState *sp = EncoderState(tif);
uint8* op = tif->tif_rawcp;
long nextbits = sp->lzw_nextbits;
long nextdata = sp->lzw_nextdata;
unsigned long nextdata = sp->lzw_nextdata;
long outcount = sp->enc_outcount;
int nbits = sp->lzw_nbits;
if (op > sp->enc_rawlimit) {
tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata);
TIFFFlushData1(tif);
if( !TIFFFlushData1(tif) )
return 0;
op = tif->tif_rawdata;
}
if (sp->enc_oldcode != (hcode_t) -1) {
int free_ent = sp->lzw_free_ent;
PutNextCode(op, sp->enc_oldcode);
sp->enc_oldcode = (hcode_t) -1;
free_ent ++;
if (free_ent == CODE_MAX-1) {
/* table is full, emit clear code and reset */
outcount = 0;
PutNextCode(op, CODE_CLEAR);
nbits = BITS_MIN;
} else {
/*
* If the next entry is going to be too big for
* the code size, then increase it, if possible.
*/
if (free_ent > sp->lzw_maxcode) {
nbits++;
assert(nbits <= BITS_MAX);
}
}
}
PutNextCode(op, CODE_EOI);
/* Explicit 0xff masking to make icc -check=conversions happy */
if (nextbits > 0)
*op++ = (unsigned char)(nextdata << (8-nextbits));
*op++ = (unsigned char)((nextdata << (8-nextbits))&0xff);
tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata);
return (1);
}

@ -1,4 +1,4 @@
/* $Id: tif_next.c,v 1.13 2010-03-10 18:56:48 bfriesen Exp $ */
/* $Id: tif_next.c,v 1.19 2016-09-04 21:32:56 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -37,7 +37,7 @@
case 0: op[0] = (unsigned char) ((v) << 6); break; \
case 1: op[0] |= (v) << 4; break; \
case 2: op[0] |= (v) << 2; break; \
case 3: *op++ |= (v); break; \
case 3: *op++ |= (v); op_offset++; break; \
} \
}
@ -71,8 +71,9 @@ NeXTDecode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
return (0);
}
for (row = buf; occ > 0; occ -= scanline, row += scanline) {
n = *bp++, cc--;
for (row = buf; cc > 0 && occ > 0; occ -= scanline, row += scanline) {
n = *bp++;
cc--;
switch (n) {
case LITERALROW:
/*
@ -90,6 +91,8 @@ NeXTDecode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
* The scanline has a literal span that begins at some
* offset.
*/
if( cc < 4 )
goto bad;
off = (bp[0] * 256) + bp[1];
n = (bp[2] * 256) + bp[3];
if (cc < 4+n || off+n > scanline)
@ -101,7 +104,10 @@ NeXTDecode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
}
default: {
uint32 npixels = 0, grey;
tmsize_t op_offset = 0;
uint32 imagewidth = tif->tif_dir.td_imagewidth;
if( isTiled(tif) )
imagewidth = tif->tif_dir.td_tilewidth;
/*
* The scanline is composed of a sequence of constant
@ -118,13 +124,19 @@ NeXTDecode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
* bounds, potentially resulting in a security
* issue.
*/
while (n-- > 0 && npixels < imagewidth)
while (n-- > 0 && npixels < imagewidth && op_offset < scanline)
SETPIXEL(op, grey);
if (npixels >= imagewidth)
break;
if (op_offset >= scanline ) {
TIFFErrorExt(tif->tif_clientdata, module, "Invalid data for scanline %ld",
(long) tif->tif_row);
return (0);
}
if (cc == 0)
goto bad;
n = *bp++, cc--;
n = *bp++;
cc--;
}
break;
}
@ -139,10 +151,27 @@ bad:
return (0);
}
static int
NeXTPreDecode(TIFF* tif, uint16 s)
{
static const char module[] = "NeXTPreDecode";
TIFFDirectory *td = &tif->tif_dir;
(void)s;
if( td->td_bitspersample != 2 )
{
TIFFErrorExt(tif->tif_clientdata, module, "Unsupported BitsPerSample = %d",
td->td_bitspersample);
return (0);
}
return (1);
}
int
TIFFInitNeXT(TIFF* tif, int scheme)
{
(void) scheme;
tif->tif_predecode = NeXTPreDecode;
tif->tif_decoderow = NeXTDecode;
tif->tif_decodestrip = NeXTDecode;
tif->tif_decodetile = NeXTDecode;

@ -1,4 +1,4 @@
/* $Id: tif_ojpeg.c,v 1.56 2012-05-24 03:15:18 fwarmerdam Exp $ */
/* $Id: tif_ojpeg.c,v 1.69 2017-04-27 17:29:26 erouault Exp $ */
/* WARNING: The type of JPEG encapsulation defined by the TIFF Version 6.0
specification is now totally obsolete and deprecated for new applications and
@ -39,7 +39,7 @@
OF THIS SOFTWARE.
Joris Van Damme and/or AWare Systems may be available for custom
developement. If you like what you see, and need anything similar or related,
development. If you like what you see, and need anything similar or related,
contact <info@awaresystems.be>.
*/
@ -75,7 +75,7 @@
OJPEGSubsamplingCorrect, making no note of any other data, reporting no warnings
or errors, up to the point where either these values are read, or it's clear they
aren't there. This means that some of the data is read twice, but we feel speed
in correcting these values is important enough to warrant this sacrifice. Allthough
in correcting these values is important enough to warrant this sacrifice. Although
there is currently no define or other configuration mechanism to disable this behaviour,
the actual header scanning is build to robustly respond with error report if it
should encounter an uncorrected mismatch of subsampling values. See
@ -84,7 +84,7 @@
The restart interval and restart markers are the most tricky part... The restart
interval can be specified in a tag. It can also be set inside the input JPEG stream.
It can be used inside the input JPEG stream. If reading from strile data, we've
consistenly discovered the need to insert restart markers in between the different
consistently discovered the need to insert restart markers in between the different
striles, as is also probably the most likely interpretation of the original TIFF 6.0
specification. With all this setting of interval, and actual use of markers that is not
predictable at the time of valid JPEG header assembly, the restart thing may turn
@ -113,7 +113,7 @@
planarconfig is not separate (vast majority). We may one day use that to build
converters to JPEG, and/or to new-style JPEG compression inside TIFF.
A dissadvantage is the lack of random access to the individual striles. This is the
A disadvantage is the lack of random access to the individual striles. This is the
reason for much of the complicated restart-and-position stuff inside OJPEGPreDecode.
Applications would do well accessing all striles in order, as this will result in
a single sequential scan of the input stream, and no restarting of LibJpeg decoding
@ -135,13 +135,13 @@
* The default mode, without JPEG_ENCAP_EXTERNAL, implements the call encapsulators
* here, internally, with normal longjump.
* SETJMP, LONGJMP, JMP_BUF: On some machines/environments a longjump equivalent is
* conviniently available, but still it may be worthwhile to use _setjmp or sigsetjmp
* conveniently available, but still it may be worthwhile to use _setjmp or sigsetjmp
* in place of plain setjmp. These macros will make it easier. It is useless
* to fiddle with these if you define JPEG_ENCAP_EXTERNAL.
* OJPEG_BUFFER: Define the size of the desired buffer here. Should be small enough so as to guarantee
* instant processing, optimal streaming and optimal use of processor cache, but also big
* enough so as to not result in significant call overhead. It should be at least a few
* bytes to accomodate some structures (this is verified in asserts), but it would not be
* bytes to accommodate some structures (this is verified in asserts), but it would not be
* sensible to make it this small anyway, and it should be at most 64K since it is indexed
* with uint16. We recommend 2K.
* EGYPTIANWALK: You could also define EGYPTIANWALK here, but it is not used anywhere and has
@ -200,7 +200,7 @@ static const TIFFField ojpegFields[] = {
Libjpeg's jmorecfg.h defines INT16 and INT32, but only if XMD_H is
not defined. Unfortunately, the MinGW and Borland compilers include
a typedef for INT32, which causes a conflict. MSVC does not include
a conficting typedef given the headers which are included.
a conflicting typedef given the headers which are included.
*/
#if defined(__BORLANDC__) || defined(__MINGW32__)
# define XMD_H 1
@ -244,6 +244,7 @@ typedef enum {
typedef struct {
TIFF* tif;
int decoder_ok;
#ifndef LIBJPEG_ENCAP_EXTERNAL
JMP_BUF exit_jmpbuf;
#endif
@ -528,6 +529,8 @@ OJPEGVSetField(TIFF* tif, uint32 tag, va_list ap)
uint32 ma;
uint64* mb;
uint32 n;
const TIFFField* fip;
switch(tag)
{
case TIFFTAG_JPEGIFOFFSET:
@ -597,7 +600,10 @@ OJPEGVSetField(TIFF* tif, uint32 tag, va_list ap)
default:
return (*sp->vsetparent)(tif,tag,ap);
}
TIFFSetFieldBit(tif,TIFFFieldWithTag(tif,tag)->field_bit);
fip = TIFFFieldWithTag(tif,tag);
if( fip == NULL ) /* shouldn't happen */
return(0);
TIFFSetFieldBit(tif,fip->field_bit);
tif->tif_flags|=TIFF_DIRTYDIRECT;
return(1);
}
@ -717,6 +723,7 @@ OJPEGPreDecode(TIFF* tif, uint16 s)
}
sp->write_curstrile++;
}
sp->decoder_ok = 1;
return(1);
}
@ -779,8 +786,14 @@ OJPEGPreDecodeSkipScanlines(TIFF* tif)
static int
OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
{
static const char module[]="OJPEGDecode";
OJPEGState* sp=(OJPEGState*)tif->tif_data;
(void)s;
if( !sp->decoder_ok )
{
TIFFErrorExt(tif->tif_clientdata,module,"Cannot decode: decoder not correctly initialized");
return 0;
}
if (sp->libjpeg_jpeg_query_style==0)
{
if (OJPEGDecodeRaw(tif,buf,cc)==0)
@ -1076,7 +1089,7 @@ OJPEGReadHeaderInfo(TIFF* tif)
TIFFErrorExt(tif->tif_clientdata,module,"Incompatible vertical subsampling and image strip/tile length");
return(0);
}
sp->restart_interval=((sp->strile_width+sp->subsampling_hor*8-1)/(sp->subsampling_hor*8))*(sp->strile_length/(sp->subsampling_ver*8));
sp->restart_interval=(uint16)(((sp->strile_width+sp->subsampling_hor*8-1)/(sp->subsampling_hor*8))*(sp->strile_length/(sp->subsampling_ver*8)));
}
if (OJPEGReadHeaderInfoSec(tif)==0)
return(0);
@ -1098,7 +1111,7 @@ OJPEGReadSecondarySos(TIFF* tif, uint16 s)
assert(s<3);
assert(sp->sos_end[0].log!=0);
assert(sp->sos_end[s].log==0);
sp->plane_sample_offset=s-1;
sp->plane_sample_offset=(uint8)(s-1);
while(sp->sos_end[sp->plane_sample_offset].log==0)
sp->plane_sample_offset--;
sp->in_buffer_source=sp->sos_end[sp->plane_sample_offset].in_buffer_source;
@ -1376,7 +1389,8 @@ OJPEGReadHeaderInfoSec(TIFF* tif)
static int
OJPEGReadHeaderInfoSecStreamDri(TIFF* tif)
{
/* this could easilly cause trouble in some cases... but no such cases have occured sofar */
/* This could easily cause trouble in some cases... but no such cases have
occurred so far */
static const char module[]="OJPEGReadHeaderInfoSecStreamDri";
OJPEGState* sp=(OJPEGState*)tif->tif_data;
uint16 m;
@ -1492,14 +1506,17 @@ OJPEGReadHeaderInfoSecStreamDht(TIFF* tif)
nb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
nb[sizeof(uint32)+2]=(m>>8);
nb[sizeof(uint32)+3]=(m&255);
if (OJPEGReadBlock(sp,m-2,&nb[sizeof(uint32)+4])==0)
if (OJPEGReadBlock(sp,m-2,&nb[sizeof(uint32)+4])==0) {
_TIFFfree(nb);
return(0);
}
o=nb[sizeof(uint32)+4];
if ((o&240)==0)
{
if (3<o)
{
TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
_TIFFfree(nb);
return(0);
}
if (sp->dctable[o]!=0)
@ -1511,12 +1528,14 @@ OJPEGReadHeaderInfoSecStreamDht(TIFF* tif)
if ((o&240)!=16)
{
TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
_TIFFfree(nb);
return(0);
}
o&=15;
if (3<o)
{
TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
_TIFFfree(nb);
return(0);
}
if (sp->actable[o]!=0)
@ -1769,9 +1788,14 @@ OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif)
ob[sizeof(uint32)+3]=67;
ob[sizeof(uint32)+4]=m;
TIFFSeekFile(tif,sp->qtable_offset[m],SEEK_SET);
p=TIFFReadFile(tif,&ob[sizeof(uint32)+5],64);
p=(uint32)TIFFReadFile(tif,&ob[sizeof(uint32)+5],64);
if (p!=64)
{
_TIFFfree(ob);
return(0);
}
if (sp->qtable[m]!=0)
_TIFFfree(sp->qtable[m]);
sp->qtable[m]=ob;
sp->sof_tq[m]=m;
}
@ -1812,7 +1836,7 @@ OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif)
}
}
TIFFSeekFile(tif,sp->dctable_offset[m],SEEK_SET);
p=TIFFReadFile(tif,o,16);
p=(uint32)TIFFReadFile(tif,o,16);
if (p!=16)
return(0);
q=0;
@ -1828,14 +1852,19 @@ OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif)
*(uint32*)rb=ra;
rb[sizeof(uint32)]=255;
rb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
rb[sizeof(uint32)+2]=((19+q)>>8);
rb[sizeof(uint32)+2]=(uint8)((19+q)>>8);
rb[sizeof(uint32)+3]=((19+q)&255);
rb[sizeof(uint32)+4]=m;
for (n=0; n<16; n++)
rb[sizeof(uint32)+5+n]=o[n];
p=TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q);
p=(uint32)TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q);
if (p!=q)
{
_TIFFfree(rb);
return(0);
}
if (sp->dctable[m]!=0)
_TIFFfree(sp->dctable[m]);
sp->dctable[m]=rb;
sp->sos_tda[m]=(m<<4);
}
@ -1876,7 +1905,7 @@ OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif)
}
}
TIFFSeekFile(tif,sp->actable_offset[m],SEEK_SET);
p=TIFFReadFile(tif,o,16);
p=(uint32)TIFFReadFile(tif,o,16);
if (p!=16)
return(0);
q=0;
@ -1892,14 +1921,19 @@ OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif)
*(uint32*)rb=ra;
rb[sizeof(uint32)]=255;
rb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
rb[sizeof(uint32)+2]=((19+q)>>8);
rb[sizeof(uint32)+2]=(uint8)((19+q)>>8);
rb[sizeof(uint32)+3]=((19+q)&255);
rb[sizeof(uint32)+4]=(16|m);
for (n=0; n<16; n++)
rb[sizeof(uint32)+5+n]=o[n];
p=TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q);
p=(uint32)TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q);
if (p!=q)
{
_TIFFfree(rb);
return(0);
}
if (sp->actable[m]!=0)
_TIFFfree(sp->actable[m]);
sp->actable[m]=rb;
sp->sos_tda[m]=(sp->sos_tda[m]|m);
}
@ -1955,6 +1989,7 @@ OJPEGReadBufferFill(OJPEGState* sp)
break;
case osibsJpegInterchangeFormat:
sp->in_buffer_source=osibsStrile;
break;
case osibsStrile:
if (!_TIFFFillStriles( sp->tif )
|| sp->tif->tif_dir.td_stripoffset == NULL
@ -2258,10 +2293,10 @@ OJPEGWriteStreamSof(TIFF* tif, void** mem, uint32* len)
/* P */
sp->out_buffer[4]=8;
/* Y */
sp->out_buffer[5]=(sp->sof_y>>8);
sp->out_buffer[5]=(uint8)(sp->sof_y>>8);
sp->out_buffer[6]=(sp->sof_y&255);
/* X */
sp->out_buffer[7]=(sp->sof_x>>8);
sp->out_buffer[7]=(uint8)(sp->sof_x>>8);
sp->out_buffer[8]=(sp->sof_x&255);
/* Nf */
sp->out_buffer[9]=sp->samples_per_pixel_per_plane;
@ -2374,7 +2409,12 @@ OJPEGWriteStreamEoi(TIFF* tif, void** mem, uint32* len)
static int
jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo)
{
return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_create_decompress(cinfo),1));
if( SETJMP(sp->exit_jmpbuf) )
return 0;
else {
jpeg_create_decompress(cinfo);
return 1;
}
}
#endif
@ -2382,7 +2422,12 @@ jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo)
static int
jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image)
{
return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_header(cinfo,require_image),1));
if( SETJMP(sp->exit_jmpbuf) )
return 0;
else {
jpeg_read_header(cinfo,require_image);
return 1;
}
}
#endif
@ -2390,7 +2435,12 @@ jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 requ
static int
jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo)
{
return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_start_decompress(cinfo),1));
if( SETJMP(sp->exit_jmpbuf) )
return 0;
else {
jpeg_start_decompress(cinfo);
return 1;
}
}
#endif
@ -2398,7 +2448,12 @@ jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo)
static int
jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines)
{
return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_scanlines(cinfo,scanlines,max_lines),1));
if( SETJMP(sp->exit_jmpbuf) )
return 0;
else {
jpeg_read_scanlines(cinfo,scanlines,max_lines);
return 1;
}
}
#endif
@ -2406,7 +2461,12 @@ jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* s
static int
jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines)
{
return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_raw_data(cinfo,data,max_lines),1));
if( SETJMP(sp->exit_jmpbuf) )
return 0;
else {
jpeg_read_raw_data(cinfo,data,max_lines);
return 1;
}
}
#endif
@ -2468,6 +2528,10 @@ OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct* cinfo, long num_b
jpeg_encap_unwind(tif);
}
#ifdef _MSC_VER
#pragma warning( push )
#pragma warning( disable : 4702 ) /* unreachable code */
#endif
static boolean
OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct* cinfo, int desired)
{
@ -2477,6 +2541,9 @@ OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct* cinfo, int desi
jpeg_encap_unwind(tif);
return(0);
}
#ifdef _MSC_VER
#pragma warning( pop )
#endif
static void
OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct* cinfo)

@ -1,4 +1,4 @@
/* $Id: tif_open.c,v 1.46 2010-12-06 16:54:54 faxguy Exp $ */
/* $Id: tif_open.c,v 1.48 2016-11-20 22:29:47 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -198,8 +198,8 @@ TIFFClientOpen(
* The 'L', 'B', and 'H' flags are intended for applications
* that can optimize operations on data by using a particular
* bit order. By default the library returns data in MSB2LSB
* bit order for compatibiltiy with older versions of this
* library. Returning data in the bit order of the native cpu
* bit order for compatibility with older versions of this
* library. Returning data in the bit order of the native CPU
* makes the most sense but also requires applications to check
* the value of the FillOrder tag; something they probably do
* not do right now.
@ -279,10 +279,10 @@ TIFFClientOpen(
* Setup header and write.
*/
#ifdef WORDS_BIGENDIAN
tif->tif_header.common.tiff_magic = tif->tif_flags & TIFF_SWAB
tif->tif_header.common.tiff_magic = (tif->tif_flags & TIFF_SWAB)
? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN;
#else
tif->tif_header.common.tiff_magic = tif->tif_flags & TIFF_SWAB
tif->tif_header.common.tiff_magic = (tif->tif_flags & TIFF_SWAB)
? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN;
#endif
if (!(tif->tif_flags&TIFF_BIGTIFF))

@ -1,4 +1,4 @@
/* $Id: tif_packbits.c,v 1.20 2010-03-10 18:56:49 bfriesen Exp $ */
/* $Id: tif_packbits.c,v 1.26 2017-05-14 02:26:07 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -38,7 +38,8 @@ PackBitsPreEncode(TIFF* tif, uint16 s)
{
(void) s;
if (!(tif->tif_data = (uint8*)_TIFFmalloc(sizeof(tmsize_t))))
tif->tif_data = (uint8*)_TIFFmalloc(sizeof(tmsize_t));
if (tif->tif_data == NULL)
return (0);
/*
* Calculate the scanline/tile-width size in bytes.
@ -81,7 +82,9 @@ PackBitsEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
/*
* Find the longest string of identical bytes.
*/
b = *bp++, cc--, n = 1;
b = *bp++;
cc--;
n = 1;
for (; cc > 0 && b == *bp; cc--, bp++)
n++;
again:
@ -96,7 +99,7 @@ PackBitsEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
slop = (long)(op - lastliteral);
tif->tif_rawcc += (tmsize_t)(lastliteral - tif->tif_rawcp);
if (!TIFFFlushData1(tif))
return (-1);
return (0);
op = tif->tif_rawcp;
while (slop-- > 0)
*op++ = *lastliteral++;
@ -104,7 +107,7 @@ PackBitsEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
} else {
tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp);
if (!TIFFFlushData1(tif))
return (-1);
return (0);
op = tif->tif_rawcp;
}
}
@ -222,7 +225,8 @@ PackBitsDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
bp = (char*) tif->tif_rawcp;
cc = tif->tif_rawcc;
while (cc > 0 && occ > 0) {
n = (long) *bp++, cc--;
n = (long) *bp++;
cc--;
/*
* Watch out for compilers that
* don't sign extend chars...
@ -240,8 +244,15 @@ PackBitsDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
(unsigned long) ((tmsize_t)n - occ));
n = (long)occ;
}
if( cc == 0 )
{
TIFFWarningExt(tif->tif_clientdata, module,
"Terminating PackBitsDecode due to lack of data.");
break;
}
occ -= n;
b = *bp++, cc--; /* TODO: may be reading past input buffer here when input data is corrupt or ends prematurely */
b = *bp++;
cc--;
while (n-- > 0)
*op++ = (uint8) b;
} else { /* copy next n+1 bytes literally */
@ -252,7 +263,13 @@ PackBitsDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
(unsigned long) ((tmsize_t)n - occ + 1));
n = (long)occ - 1;
}
_TIFFmemcpy(op, bp, ++n); /* TODO: may be reading past input buffer here when input data is corrupt or ends prematurely */
if (cc < (tmsize_t) (n+1))
{
TIFFWarningExt(tif->tif_clientdata, module,
"Terminating PackBitsDecode due to lack of data.");
break;
}
_TIFFmemcpy(op, bp, ++n);
op += n; occ -= n;
bp += n; cc -= n;
}

@ -1,4 +1,4 @@
/* $Id: tif_pixarlog.c,v 1.37 2012-05-24 23:21:45 fwarmerdam Exp $ */
/* $Id: tif_pixarlog.c,v 1.54 2017-07-10 10:40:28 erouault Exp $ */
/*
* Copyright (c) 1996-1997 Sam Leffler
@ -45,15 +45,15 @@
* input is assumed to be unsigned linear color values that represent
* the range 0-1. In the case of IEEE values, the 0-1 range is assumed to
* be the normal linear color range, in addition over 1 values are
* accepted up to a value of about 25.0 to encode "hot" hightlights and such.
* accepted up to a value of about 25.0 to encode "hot" highlights and such.
* The encoding is lossless for 8-bit values, slightly lossy for the
* other bit depths. The actual color precision should be better
* than the human eye can perceive with extra room to allow for
* error introduced by further image computation. As with any quantized
* color format, it is possible to perform image calculations which
* expose the quantization error. This format should certainly be less
* susceptable to such errors than standard 8-bit encodings, but more
* susceptable than straight 16-bit or 32-bit encodings.
* susceptible to such errors than standard 8-bit encodings, but more
* susceptible than straight 16-bit or 32-bit encodings.
*
* On reading the internal format is converted to the desired output format.
* The program can request which format it desires by setting the internal
@ -301,28 +301,30 @@ horizontalAccumulate11(uint16 *wp, int n, int stride, uint16 *op)
if (n >= stride) {
mask = CODE_MASK;
if (stride == 3) {
op[0] = cr = wp[0]; op[1] = cg = wp[1]; op[2] = cb = wp[2];
op[0] = wp[0]; op[1] = wp[1]; op[2] = wp[2];
cr = wp[0]; cg = wp[1]; cb = wp[2];
n -= 3;
while (n > 0) {
wp += 3;
op += 3;
n -= 3;
op[0] = (cr += wp[0]) & mask;
op[1] = (cg += wp[1]) & mask;
op[2] = (cb += wp[2]) & mask;
op[0] = (uint16)((cr += wp[0]) & mask);
op[1] = (uint16)((cg += wp[1]) & mask);
op[2] = (uint16)((cb += wp[2]) & mask);
}
} else if (stride == 4) {
op[0] = cr = wp[0]; op[1] = cg = wp[1];
op[2] = cb = wp[2]; op[3] = ca = wp[3];
op[0] = wp[0]; op[1] = wp[1];
op[2] = wp[2]; op[3] = wp[3];
cr = wp[0]; cg = wp[1]; cb = wp[2]; ca = wp[3];
n -= 4;
while (n > 0) {
wp += 4;
op += 4;
n -= 4;
op[0] = (cr += wp[0]) & mask;
op[1] = (cg += wp[1]) & mask;
op[2] = (cb += wp[2]) & mask;
op[3] = (ca += wp[3]) & mask;
op[0] = (uint16)((cr += wp[0]) & mask);
op[1] = (uint16)((cg += wp[1]) & mask);
op[2] = (uint16)((cb += wp[2]) & mask);
op[3] = (uint16)((ca += wp[3]) & mask);
}
} else {
REPEAT(stride, *op = *wp&mask; wp++; op++)
@ -457,6 +459,7 @@ horizontalAccumulate8abgr(uint16 *wp, int n, int stride, unsigned char *op,
typedef struct {
TIFFPredictorState predict;
z_stream stream;
tmsize_t tbuf_size; /* only set/used on reading for now */
uint16 *tbuf;
uint16 stride;
int state;
@ -556,7 +559,7 @@ PixarLogMakeTables(PixarLogState *sp)
for (i = 0; i < lt2size; i++) {
if ((i*linstep)*(i*linstep) > ToLinearF[j]*ToLinearF[j+1])
j++;
FromLT2[i] = j;
FromLT2[i] = (uint16)j;
}
/*
@ -568,14 +571,14 @@ PixarLogMakeTables(PixarLogState *sp)
for (i = 0; i < 16384; i++) {
while ((i/16383.)*(i/16383.) > ToLinearF[j]*ToLinearF[j+1])
j++;
From14[i] = j;
From14[i] = (uint16)j;
}
j = 0;
for (i = 0; i < 256; i++) {
while ((i/255.)*(i/255.) > ToLinearF[j]*ToLinearF[j+1])
j++;
From8[i] = j;
From8[i] = (uint16)j;
}
Fltsize = (float)(lt2size/2);
@ -633,15 +636,27 @@ PixarLogGuessDataFmt(TIFFDirectory *td)
return guess;
}
#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0))
#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1)
static tmsize_t
multiply_ms(tmsize_t m1, tmsize_t m2)
{
tmsize_t bytes = m1 * m2;
if( m1 == 0 || m2 > TIFF_TMSIZE_T_MAX / m1 )
return 0;
return m1 * m2;
}
if (m1 && bytes / m1 != m2)
bytes = 0;
static tmsize_t
add_ms(tmsize_t m1, tmsize_t m2)
{
/* if either input is zero, assume overflow already occurred */
if (m1 == 0 || m2 == 0)
return 0;
else if (m1 > TIFF_TMSIZE_T_MAX - m2)
return 0;
return bytes;
return m1 + m2;
}
static int
@ -658,9 +673,20 @@ PixarLogSetupDecode(TIFF* tif)
TIFFDirectory *td = &tif->tif_dir;
PixarLogState* sp = DecoderState(tif);
tmsize_t tbuf_size;
uint32 strip_height;
assert(sp != NULL);
/* This function can possibly be called several times by */
/* PredictorSetupDecode() if this function succeeds but */
/* PredictorSetup() fails */
if( (sp->state & PLSTATE_INIT) != 0 )
return 1;
strip_height = td->td_rowsperstrip;
if( strip_height > td->td_imagelength )
strip_height = td->td_imagelength;
/* Make sure no byte swapping happens on the data
* after decompression. */
tif->tif_postdecode = _TIFFNoPostDecode;
@ -670,15 +696,21 @@ PixarLogSetupDecode(TIFF* tif)
sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
td->td_samplesperpixel : 1);
tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth),
td->td_rowsperstrip), sizeof(uint16));
strip_height), sizeof(uint16));
/* add one more stride in case input ends mid-stride */
tbuf_size = add_ms(tbuf_size, sizeof(uint16) * sp->stride);
if (tbuf_size == 0)
return (0); /* TODO: this is an error return without error report through TIFFErrorExt */
sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size+sizeof(uint16));
sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size);
if (sp->tbuf == NULL)
return (0);
sp->tbuf_size = tbuf_size;
if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
sp->user_datafmt = PixarLogGuessDataFmt(td);
if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) {
_TIFFfree(sp->tbuf);
sp->tbuf = NULL;
sp->tbuf_size = 0;
TIFFErrorExt(tif->tif_clientdata, module,
"PixarLog compression can't handle bits depth/data format combination (depth: %d)",
td->td_bitspersample);
@ -686,7 +718,10 @@ PixarLogSetupDecode(TIFF* tif)
}
if (inflateInit(&sp->stream) != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg);
_TIFFfree(sp->tbuf);
sp->tbuf = NULL;
sp->tbuf_size = 0;
TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg ? sp->stream.msg : "(null)");
return (0);
} else {
sp->state |= PLSTATE_INIT;
@ -709,7 +744,7 @@ PixarLogPreDecode(TIFF* tif, uint16 s)
assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised,
we need to simplify this code to reflect a ZLib that is likely updated
to deal with 8byte memory sizes, though this code will respond
apropriately even before we simplify it */
appropriately even before we simplify it */
sp->stream.avail_in = (uInt) tif->tif_rawcc;
if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc)
{
@ -754,17 +789,27 @@ PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
(void) s;
assert(sp != NULL);
sp->stream.next_in = tif->tif_rawcp;
sp->stream.avail_in = (uInt) tif->tif_rawcc;
sp->stream.next_out = (unsigned char *) sp->tbuf;
assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised,
we need to simplify this code to reflect a ZLib that is likely updated
to deal with 8byte memory sizes, though this code will respond
apropriately even before we simplify it */
appropriately even before we simplify it */
sp->stream.avail_out = (uInt) (nsamples * sizeof(uint16));
if (sp->stream.avail_out != nsamples * sizeof(uint16))
{
TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
return (0);
}
/* Check that we will not fill more than what was allocated */
if ((tmsize_t)sp->stream.avail_out > sp->tbuf_size)
{
TIFFErrorExt(tif->tif_clientdata, module, "sp->stream.avail_out > sp->tbuf_size");
return (0);
}
do {
int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
if (state == Z_STREAM_END) {
@ -773,14 +818,14 @@ PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
if (state == Z_DATA_ERROR) {
TIFFErrorExt(tif->tif_clientdata, module,
"Decoding error at scanline %lu, %s",
(unsigned long) tif->tif_row, sp->stream.msg);
(unsigned long) tif->tif_row, sp->stream.msg ? sp->stream.msg : "(null)");
if (inflateSync(&sp->stream) != Z_OK)
return (0);
continue;
}
if (state != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
sp->stream.msg);
sp->stream.msg ? sp->stream.msg : "(null)");
return (0);
}
} while (sp->stream.avail_out > 0);
@ -793,6 +838,9 @@ PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
return (0);
}
tif->tif_rawcp = sp->stream.next_in;
tif->tif_rawcc = sp->stream.avail_in;
up = sp->tbuf;
/* Swap bytes in the data if from a different endian machine. */
if (tif->tif_flags & TIFF_SWAB)
@ -882,7 +930,7 @@ PixarLogSetupEncode(TIFF* tif)
}
if (deflateInit(&sp->stream, sp->quality) != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg);
TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg ? sp->stream.msg : "(null)");
return (0);
} else {
sp->state |= PLSTATE_INIT;
@ -905,8 +953,8 @@ PixarLogPreEncode(TIFF* tif, uint16 s)
assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised,
we need to simplify this code to reflect a ZLib that is likely updated
to deal with 8byte memory sizes, though this code will respond
apropriately even before we simplify it */
sp->stream.avail_out = tif->tif_rawdatasize;
appropriately even before we simplify it */
sp->stream.avail_out = (uInt)tif->tif_rawdatasize;
if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
{
TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
@ -937,9 +985,9 @@ horizontalDifferenceF(float *ip, int n, int stride, uint16 *wp, uint16 *FromLT2)
n -= 3;
wp += 3;
ip += 3;
r1 = (int32) CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
g1 = (int32) CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
b1 = (int32) CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
r1 = (int32) CLAMP(ip[0]); wp[0] = (uint16)((r1-r2) & mask); r2 = r1;
g1 = (int32) CLAMP(ip[1]); wp[1] = (uint16)((g1-g2) & mask); g2 = g1;
b1 = (int32) CLAMP(ip[2]); wp[2] = (uint16)((b1-b2) & mask); b2 = b1;
}
} else if (stride == 4) {
r2 = wp[0] = (uint16) CLAMP(ip[0]);
@ -951,23 +999,20 @@ horizontalDifferenceF(float *ip, int n, int stride, uint16 *wp, uint16 *FromLT2)
n -= 4;
wp += 4;
ip += 4;
r1 = (int32) CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
g1 = (int32) CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
b1 = (int32) CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
a1 = (int32) CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1;
r1 = (int32) CLAMP(ip[0]); wp[0] = (uint16)((r1-r2) & mask); r2 = r1;
g1 = (int32) CLAMP(ip[1]); wp[1] = (uint16)((g1-g2) & mask); g2 = g1;
b1 = (int32) CLAMP(ip[2]); wp[2] = (uint16)((b1-b2) & mask); b2 = b1;
a1 = (int32) CLAMP(ip[3]); wp[3] = (uint16)((a1-a2) & mask); a2 = a1;
}
} else {
ip += n - 1; /* point to last one */
wp += n - 1; /* point to last one */
REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]); wp++; ip++)
n -= stride;
while (n > 0) {
REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]);
wp[stride] -= wp[0];
wp[stride] &= mask;
wp--; ip--)
REPEAT(stride,
wp[0] = (uint16)(((int32)CLAMP(ip[0])-(int32)CLAMP(ip[-stride])) & mask);
wp++; ip++)
n -= stride;
}
REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]); wp--; ip--)
}
}
}
@ -992,9 +1037,9 @@ horizontalDifference16(unsigned short *ip, int n, int stride,
n -= 3;
wp += 3;
ip += 3;
r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
r1 = CLAMP(ip[0]); wp[0] = (uint16)((r1-r2) & mask); r2 = r1;
g1 = CLAMP(ip[1]); wp[1] = (uint16)((g1-g2) & mask); g2 = g1;
b1 = CLAMP(ip[2]); wp[2] = (uint16)((b1-b2) & mask); b2 = b1;
}
} else if (stride == 4) {
r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]);
@ -1004,23 +1049,20 @@ horizontalDifference16(unsigned short *ip, int n, int stride,
n -= 4;
wp += 4;
ip += 4;
r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
a1 = CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1;
r1 = CLAMP(ip[0]); wp[0] = (uint16)((r1-r2) & mask); r2 = r1;
g1 = CLAMP(ip[1]); wp[1] = (uint16)((g1-g2) & mask); g2 = g1;
b1 = CLAMP(ip[2]); wp[2] = (uint16)((b1-b2) & mask); b2 = b1;
a1 = CLAMP(ip[3]); wp[3] = (uint16)((a1-a2) & mask); a2 = a1;
}
} else {
ip += n - 1; /* point to last one */
wp += n - 1; /* point to last one */
REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++)
n -= stride;
while (n > 0) {
REPEAT(stride, wp[0] = CLAMP(ip[0]);
wp[stride] -= wp[0];
wp[stride] &= mask;
wp--; ip--)
REPEAT(stride,
wp[0] = (uint16)((CLAMP(ip[0])-CLAMP(ip[-stride])) & mask);
wp++; ip++)
n -= stride;
}
REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--)
}
}
}
@ -1043,9 +1085,9 @@ horizontalDifference8(unsigned char *ip, int n, int stride,
n -= 3;
while (n > 0) {
n -= 3;
r1 = CLAMP(ip[3]); wp[3] = (r1-r2) & mask; r2 = r1;
g1 = CLAMP(ip[4]); wp[4] = (g1-g2) & mask; g2 = g1;
b1 = CLAMP(ip[5]); wp[5] = (b1-b2) & mask; b2 = b1;
r1 = CLAMP(ip[3]); wp[3] = (uint16)((r1-r2) & mask); r2 = r1;
g1 = CLAMP(ip[4]); wp[4] = (uint16)((g1-g2) & mask); g2 = g1;
b1 = CLAMP(ip[5]); wp[5] = (uint16)((b1-b2) & mask); b2 = b1;
wp += 3;
ip += 3;
}
@ -1055,25 +1097,22 @@ horizontalDifference8(unsigned char *ip, int n, int stride,
n -= 4;
while (n > 0) {
n -= 4;
r1 = CLAMP(ip[4]); wp[4] = (r1-r2) & mask; r2 = r1;
g1 = CLAMP(ip[5]); wp[5] = (g1-g2) & mask; g2 = g1;
b1 = CLAMP(ip[6]); wp[6] = (b1-b2) & mask; b2 = b1;
a1 = CLAMP(ip[7]); wp[7] = (a1-a2) & mask; a2 = a1;
r1 = CLAMP(ip[4]); wp[4] = (uint16)((r1-r2) & mask); r2 = r1;
g1 = CLAMP(ip[5]); wp[5] = (uint16)((g1-g2) & mask); g2 = g1;
b1 = CLAMP(ip[6]); wp[6] = (uint16)((b1-b2) & mask); b2 = b1;
a1 = CLAMP(ip[7]); wp[7] = (uint16)((a1-a2) & mask); a2 = a1;
wp += 4;
ip += 4;
}
} else {
wp += n + stride - 1; /* point to last one */
ip += n + stride - 1; /* point to last one */
REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++)
n -= stride;
while (n > 0) {
REPEAT(stride, wp[0] = CLAMP(ip[0]);
wp[stride] -= wp[0];
wp[stride] &= mask;
wp--; ip--)
REPEAT(stride,
wp[0] = (uint16)((CLAMP(ip[0])-CLAMP(ip[-stride])) & mask);
wp++; ip++)
n -= stride;
}
REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--)
}
}
}
@ -1115,6 +1154,13 @@ PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
}
llen = sp->stride * td->td_imagewidth;
/* Check against the number of elements (of size uint16) of sp->tbuf */
if( n > (tmsize_t)(td->td_rowsperstrip * llen) )
{
TIFFErrorExt(tif->tif_clientdata, module,
"Too many input bytes provided");
return 0;
}
for (i = 0, up = sp->tbuf; i < n; i += llen, up += llen) {
switch (sp->user_datafmt) {
@ -1145,7 +1191,7 @@ PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised,
we need to simplify this code to reflect a ZLib that is likely updated
to deal with 8byte memory sizes, though this code will respond
apropriately even before we simplify it */
appropriately even before we simplify it */
sp->stream.avail_in = (uInt) (n * sizeof(uint16));
if ((sp->stream.avail_in / sizeof(uint16)) != (uInt) n)
{
@ -1157,7 +1203,7 @@ PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
do {
if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module, "Encoder error: %s",
sp->stream.msg);
sp->stream.msg ? sp->stream.msg : "(null)");
return (0);
}
if (sp->stream.avail_out == 0) {
@ -1199,7 +1245,7 @@ PixarLogPostEncode(TIFF* tif)
break;
default:
TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
sp->stream.msg);
sp->stream.msg ? sp->stream.msg : "(null)");
return (0);
}
} while (state != Z_STREAM_END);
@ -1209,9 +1255,11 @@ PixarLogPostEncode(TIFF* tif)
static void
PixarLogClose(TIFF* tif)
{
PixarLogState* sp = (PixarLogState*) tif->tif_data;
TIFFDirectory *td = &tif->tif_dir;
/* In a really sneaky (and really incorrect, and untruthfull, and
assert(sp != 0);
/* In a really sneaky (and really incorrect, and untruthful, and
* troublesome, and error-prone) maneuver that completely goes against
* the spirit of TIFF, and breaks TIFF, on close, we covertly
* modify both bitspersample and sampleformat in the directory to
@ -1219,9 +1267,20 @@ PixarLogClose(TIFF* tif)
* readers that don't know about PixarLog, or how to set
* the PIXARLOGDATFMT pseudo-tag.
*/
if (sp->state&PLSTATE_INIT) {
/* We test the state to avoid an issue such as in
* http://bugzilla.maptools.org/show_bug.cgi?id=2604
* What appends in that case is that the bitspersample is 1 and
* a TransferFunction is set. The size of the TransferFunction
* depends on 1<<bitspersample. So if we increase it, an access
* out of the buffer will happen at directory flushing.
* Another option would be to clear those targs.
*/
td->td_bitspersample = 8;
td->td_sampleformat = SAMPLEFORMAT_UINT;
}
}
static void
PixarLogCleanup(TIFF* tif)
@ -1269,7 +1328,7 @@ PixarLogVSetField(TIFF* tif, uint32 tag, va_list ap)
if (deflateParams(&sp->stream,
sp->quality, Z_DEFAULT_STRATEGY) != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
sp->stream.msg);
sp->stream.msg ? sp->stream.msg : "(null)");
return (0);
}
}

@ -1,4 +1,4 @@
/* $Id: tif_predict.c,v 1.32 2010-03-10 18:56:49 bfriesen Exp $ */
/* $Id: tif_predict.c,v 1.44 2017-06-18 10:31:50 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -34,16 +34,18 @@
#define PredictorState(tif) ((TIFFPredictorState*) (tif)->tif_data)
static void horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc);
static void horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc);
static void horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc);
static void swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc);
static void swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc);
static void horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc);
static void horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc);
static void horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc);
static void fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc);
static void fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc);
static int horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc);
static int horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc);
static int horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc);
static int swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc);
static int swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc);
static int horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc);
static int horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc);
static int horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc);
static int swabHorDiff16(TIFF* tif, uint8* cp0, tmsize_t cc);
static int swabHorDiff32(TIFF* tif, uint8* cp0, tmsize_t cc);
static int fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc);
static int fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc);
static int PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s);
static int PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s);
static int PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s);
@ -78,6 +80,15 @@ PredictorSetup(TIFF* tif)
td->td_sampleformat);
return 0;
}
if (td->td_bitspersample != 16
&& td->td_bitspersample != 24
&& td->td_bitspersample != 32
&& td->td_bitspersample != 64) { /* Should 64 be allowed? */
TIFFErrorExt(tif->tif_clientdata, module,
"Floating point \"Predictor\" not supported with %d-bit samples",
td->td_bitspersample);
return 0;
}
break;
default:
TIFFErrorExt(tif->tif_clientdata, module,
@ -106,6 +117,9 @@ PredictorSetupDecode(TIFF* tif)
TIFFPredictorState* sp = PredictorState(tif);
TIFFDirectory* td = &tif->tif_dir;
/* Note: when PredictorSetup() fails, the effets of setupdecode() */
/* will not be "cancelled" so setupdecode() might be robust to */
/* be called several times. */
if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
return 0;
@ -172,7 +186,7 @@ PredictorSetupDecode(TIFF* tif)
}
/*
* Allocate buffer to keep the decoded bytes before
* rearranging in the ight order
* rearranging in the right order
*/
}
@ -207,6 +221,23 @@ PredictorSetupEncode(TIFF* tif)
sp->encodetile = tif->tif_encodetile;
tif->tif_encodetile = PredictorEncodeTile;
}
/*
* If the data is horizontally differenced 16-bit data that
* requires byte-swapping, then it must be byte swapped after
* the differentiation step. We do this with a special-purpose
* routine and override the normal post decoding logic that
* the library setup when the directory was read.
*/
if (tif->tif_flags & TIFF_SWAB) {
if (sp->encodepfunc == horDiff16) {
sp->encodepfunc = swabHorDiff16;
tif->tif_postdecode = _TIFFNoPostDecode;
} else if (sp->encodepfunc == horDiff32) {
sp->encodepfunc = swabHorDiff32;
tif->tif_postdecode = _TIFFNoPostDecode;
}
}
}
else if (sp->predictor == 3) {
@ -231,21 +262,35 @@ PredictorSetupEncode(TIFF* tif)
#define REPEAT4(n, op) \
switch (n) { \
default: { tmsize_t i; for (i = n-4; i > 0; i--) { op; } } \
case 4: op; \
case 3: op; \
case 2: op; \
case 1: op; \
default: { \
tmsize_t i; for (i = n-4; i > 0; i--) { op; } } /*-fallthrough*/ \
case 4: op; /*-fallthrough*/ \
case 3: op; /*-fallthrough*/ \
case 2: op; /*-fallthrough*/ \
case 1: op; /*-fallthrough*/ \
case 0: ; \
}
static void
/* Remarks related to C standard compliance in all below functions : */
/* - to avoid any undefined behaviour, we only operate on unsigned types */
/* since the behaviour of "overflows" is defined (wrap over) */
/* - when storing into the byte stream, we explicitly mask with 0xff so */
/* as to make icc -check=conversions happy (not necessary by the standard) */
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
static int
horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc)
{
tmsize_t stride = PredictorState(tif)->stride;
char* cp = (char*) cp0;
assert((cc%stride)==0);
unsigned char* cp = (unsigned char*) cp0;
if((cc%stride)!=0)
{
TIFFErrorExt(tif->tif_clientdata, "horAcc8",
"%s", "(cc%stride)!=0");
return 0;
}
if (cc > stride) {
/*
* Pipeline the most common cases.
@ -257,9 +302,9 @@ horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc)
cc -= 3;
cp += 3;
while (cc>0) {
cp[0] = (char) (cr += cp[0]);
cp[1] = (char) (cg += cp[1]);
cp[2] = (char) (cb += cp[2]);
cp[0] = (unsigned char) ((cr += cp[0]) & 0xff);
cp[1] = (unsigned char) ((cg += cp[1]) & 0xff);
cp[2] = (unsigned char) ((cb += cp[2]) & 0xff);
cc -= 3;
cp += 3;
}
@ -271,10 +316,10 @@ horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc)
cc -= 4;
cp += 4;
while (cc>0) {
cp[0] = (char) (cr += cp[0]);
cp[1] = (char) (cg += cp[1]);
cp[2] = (char) (cb += cp[2]);
cp[3] = (char) (ca += cp[3]);
cp[0] = (unsigned char) ((cr += cp[0]) & 0xff);
cp[1] = (unsigned char) ((cg += cp[1]) & 0xff);
cp[2] = (unsigned char) ((cb += cp[2]) & 0xff);
cp[3] = (unsigned char) ((ca += cp[3]) & 0xff);
cc -= 4;
cp += 4;
}
@ -282,77 +327,73 @@ horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc)
cc -= stride;
do {
REPEAT4(stride, cp[stride] =
(char) (cp[stride] + *cp); cp++)
(unsigned char) ((cp[stride] + *cp) & 0xff); cp++)
cc -= stride;
} while (cc>0);
}
}
return 1;
}
static void
static int
swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc)
{
tmsize_t stride = PredictorState(tif)->stride;
uint16* wp = (uint16*) cp0;
tmsize_t wc = cc / 2;
assert((cc%(2*stride))==0);
if (wc > stride) {
TIFFSwabArrayOfShort(wp, wc);
wc -= stride;
do {
REPEAT4(stride, wp[stride] += wp[0]; wp++)
wc -= stride;
} while (wc > 0);
}
return horAcc16(tif, cp0, cc);
}
static void
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
static int
horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc)
{
tmsize_t stride = PredictorState(tif)->stride;
uint16* wp = (uint16*) cp0;
tmsize_t wc = cc / 2;
assert((cc%(2*stride))==0);
if((cc%(2*stride))!=0)
{
TIFFErrorExt(tif->tif_clientdata, "horAcc16",
"%s", "cc%(2*stride))!=0");
return 0;
}
if (wc > stride) {
wc -= stride;
do {
REPEAT4(stride, wp[stride] += wp[0]; wp++)
REPEAT4(stride, wp[stride] = (uint16)(((unsigned int)wp[stride] + (unsigned int)wp[0]) & 0xffff); wp++)
wc -= stride;
} while (wc > 0);
}
return 1;
}
static void
static int
swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc)
{
tmsize_t stride = PredictorState(tif)->stride;
uint32* wp = (uint32*) cp0;
tmsize_t wc = cc / 4;
assert((cc%(4*stride))==0);
if (wc > stride) {
TIFFSwabArrayOfLong(wp, wc);
wc -= stride;
do {
REPEAT4(stride, wp[stride] += wp[0]; wp++)
wc -= stride;
} while (wc > 0);
}
return horAcc32(tif, cp0, cc);
}
static void
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
static int
horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc)
{
tmsize_t stride = PredictorState(tif)->stride;
uint32* wp = (uint32*) cp0;
tmsize_t wc = cc / 4;
assert((cc%(4*stride))==0);
if((cc%(4*stride))!=0)
{
TIFFErrorExt(tif->tif_clientdata, "horAcc32",
"%s", "cc%(4*stride))!=0");
return 0;
}
if (wc > stride) {
wc -= stride;
@ -361,12 +402,13 @@ horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc)
wc -= stride;
} while (wc > 0);
}
return 1;
}
/*
* Floating point predictor accumulation routine.
*/
static void
static int
fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc)
{
tmsize_t stride = PredictorState(tif)->stride;
@ -374,15 +416,22 @@ fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc)
tmsize_t wc = cc / bps;
tmsize_t count = cc;
uint8 *cp = (uint8 *) cp0;
uint8 *tmp = (uint8 *)_TIFFmalloc(cc);
uint8 *tmp;
assert((cc%(bps*stride))==0);
if(cc%(bps*stride)!=0)
{
TIFFErrorExt(tif->tif_clientdata, "fpAcc",
"%s", "cc%(bps*stride))!=0");
return 0;
}
tmp = (uint8 *)_TIFFmalloc(cc);
if (!tmp)
return;
return 0;
while (count > stride) {
REPEAT4(stride, cp[stride] += cp[0]; cp++)
REPEAT4(stride, cp[stride] =
(unsigned char) ((cp[stride] + cp[0]) & 0xff); cp++)
count -= stride;
}
@ -400,6 +449,7 @@ fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc)
}
}
_TIFFfree(tmp);
return 1;
}
/*
@ -415,8 +465,7 @@ PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
assert(sp->decodepfunc != NULL);
if ((*sp->decoderow)(tif, op0, occ0, s)) {
(*sp->decodepfunc)(tif, op0, occ0);
return 1;
return (*sp->decodepfunc)(tif, op0, occ0);
} else
return 0;
}
@ -439,10 +488,16 @@ PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
if ((*sp->decodetile)(tif, op0, occ0, s)) {
tmsize_t rowsize = sp->rowsize;
assert(rowsize > 0);
assert((occ0%rowsize)==0);
if((occ0%rowsize) !=0)
{
TIFFErrorExt(tif->tif_clientdata, "PredictorDecodeTile",
"%s", "occ0%rowsize != 0");
return 0;
}
assert(sp->decodepfunc != NULL);
while (occ0 > 0) {
(*sp->decodepfunc)(tif, op0, rowsize);
if( !(*sp->decodepfunc)(tif, op0, rowsize) )
return 0;
occ0 -= rowsize;
op0 += rowsize;
}
@ -451,14 +506,20 @@ PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
return 0;
}
static void
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
static int
horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc)
{
TIFFPredictorState* sp = PredictorState(tif);
tmsize_t stride = sp->stride;
char* cp = (char*) cp0;
unsigned char* cp = (unsigned char*) cp0;
assert((cc%stride)==0);
if((cc%stride)!=0)
{
TIFFErrorExt(tif->tif_clientdata, "horDiff8",
"%s", "(cc%stride)!=0");
return 0;
}
if (cc > stride) {
cc -= stride;
@ -466,67 +527,94 @@ horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc)
* Pipeline the most common cases.
*/
if (stride == 3) {
int r1, g1, b1;
int r2 = cp[0];
int g2 = cp[1];
int b2 = cp[2];
unsigned int r1, g1, b1;
unsigned int r2 = cp[0];
unsigned int g2 = cp[1];
unsigned int b2 = cp[2];
do {
r1 = cp[3]; cp[3] = r1-r2; r2 = r1;
g1 = cp[4]; cp[4] = g1-g2; g2 = g1;
b1 = cp[5]; cp[5] = b1-b2; b2 = b1;
r1 = cp[3]; cp[3] = (unsigned char)((r1-r2)&0xff); r2 = r1;
g1 = cp[4]; cp[4] = (unsigned char)((g1-g2)&0xff); g2 = g1;
b1 = cp[5]; cp[5] = (unsigned char)((b1-b2)&0xff); b2 = b1;
cp += 3;
} while ((cc -= 3) > 0);
} else if (stride == 4) {
int r1, g1, b1, a1;
int r2 = cp[0];
int g2 = cp[1];
int b2 = cp[2];
int a2 = cp[3];
unsigned int r1, g1, b1, a1;
unsigned int r2 = cp[0];
unsigned int g2 = cp[1];
unsigned int b2 = cp[2];
unsigned int a2 = cp[3];
do {
r1 = cp[4]; cp[4] = r1-r2; r2 = r1;
g1 = cp[5]; cp[5] = g1-g2; g2 = g1;
b1 = cp[6]; cp[6] = b1-b2; b2 = b1;
a1 = cp[7]; cp[7] = a1-a2; a2 = a1;
r1 = cp[4]; cp[4] = (unsigned char)((r1-r2)&0xff); r2 = r1;
g1 = cp[5]; cp[5] = (unsigned char)((g1-g2)&0xff); g2 = g1;
b1 = cp[6]; cp[6] = (unsigned char)((b1-b2)&0xff); b2 = b1;
a1 = cp[7]; cp[7] = (unsigned char)((a1-a2)&0xff); a2 = a1;
cp += 4;
} while ((cc -= 4) > 0);
} else {
cp += cc - 1;
do {
REPEAT4(stride, cp[stride] -= cp[0]; cp--)
REPEAT4(stride, cp[stride] = (unsigned char)((cp[stride] - cp[0])&0xff); cp--)
} while ((cc -= stride) > 0);
}
}
return 1;
}
static void
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
static int
horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc)
{
TIFFPredictorState* sp = PredictorState(tif);
tmsize_t stride = sp->stride;
int16 *wp = (int16*) cp0;
uint16 *wp = (uint16*) cp0;
tmsize_t wc = cc/2;
assert((cc%(2*stride))==0);
if((cc%(2*stride))!=0)
{
TIFFErrorExt(tif->tif_clientdata, "horDiff8",
"%s", "(cc%(2*stride))!=0");
return 0;
}
if (wc > stride) {
wc -= stride;
wp += wc - 1;
do {
REPEAT4(stride, wp[stride] -= wp[0]; wp--)
REPEAT4(stride, wp[stride] = (uint16)(((unsigned int)wp[stride] - (unsigned int)wp[0]) & 0xffff); wp--)
wc -= stride;
} while (wc > 0);
}
return 1;
}
static void
static int
swabHorDiff16(TIFF* tif, uint8* cp0, tmsize_t cc)
{
uint16* wp = (uint16*) cp0;
tmsize_t wc = cc / 2;
if( !horDiff16(tif, cp0, cc) )
return 0;
TIFFSwabArrayOfShort(wp, wc);
return 1;
}
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
static int
horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc)
{
TIFFPredictorState* sp = PredictorState(tif);
tmsize_t stride = sp->stride;
int32 *wp = (int32*) cp0;
uint32 *wp = (uint32*) cp0;
tmsize_t wc = cc/4;
assert((cc%(4*stride))==0);
if((cc%(4*stride))!=0)
{
TIFFErrorExt(tif->tif_clientdata, "horDiff32",
"%s", "(cc%(4*stride))!=0");
return 0;
}
if (wc > stride) {
wc -= stride;
@ -536,12 +624,27 @@ horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc)
wc -= stride;
} while (wc > 0);
}
return 1;
}
static int
swabHorDiff32(TIFF* tif, uint8* cp0, tmsize_t cc)
{
uint32* wp = (uint32*) cp0;
tmsize_t wc = cc / 4;
if( !horDiff32(tif, cp0, cc) )
return 0;
TIFFSwabArrayOfLong(wp, wc);
return 1;
}
/*
* Floating point predictor differencing routine.
*/
static void
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
static int
fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc)
{
tmsize_t stride = PredictorState(tif)->stride;
@ -549,12 +652,18 @@ fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc)
tmsize_t wc = cc / bps;
tmsize_t count;
uint8 *cp = (uint8 *) cp0;
uint8 *tmp = (uint8 *)_TIFFmalloc(cc);
uint8 *tmp;
assert((cc%(bps*stride))==0);
if((cc%(bps*stride))!=0)
{
TIFFErrorExt(tif->tif_clientdata, "fpDiff",
"%s", "(cc%(bps*stride))!=0");
return 0;
}
tmp = (uint8 *)_TIFFmalloc(cc);
if (!tmp)
return;
return 0;
_TIFFmemcpy(tmp, cp0, cc);
for (count = 0; count < wc; count++) {
@ -573,7 +682,8 @@ fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc)
cp = (uint8 *) cp0;
cp += cc - stride - 1;
for (count = cc; count > stride; count -= stride)
REPEAT4(stride, cp[stride] -= cp[0]; cp--)
REPEAT4(stride, cp[stride] = (unsigned char)((cp[stride] - cp[0])&0xff); cp--)
return 1;
}
static int
@ -586,7 +696,8 @@ PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
assert(sp->encoderow != NULL);
/* XXX horizontal differencing alters user's data XXX */
(*sp->encodepfunc)(tif, bp, cc);
if( !(*sp->encodepfunc)(tif, bp, cc) )
return 0;
return (*sp->encoderow)(tif, bp, cc, s);
}
@ -621,7 +732,13 @@ PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s)
rowsize = sp->rowsize;
assert(rowsize > 0);
assert((cc0%rowsize)==0);
if((cc0%rowsize)!=0)
{
TIFFErrorExt(tif->tif_clientdata, "PredictorEncodeTile",
"%s", "(cc0%rowsize)!=0");
_TIFFfree( working_copy );
return 0;
}
while (cc > 0) {
(*sp->encodepfunc)(tif, bp, rowsize);
cc -= rowsize;
@ -670,7 +787,7 @@ PredictorVGetField(TIFF* tif, uint32 tag, va_list ap)
switch (tag) {
case TIFFTAG_PREDICTOR:
*va_arg(ap, uint16*) = sp->predictor;
*va_arg(ap, uint16*) = (uint16)sp->predictor;
break;
default:
return (*sp->vgetparent)(tif, tag, ap);
@ -691,7 +808,7 @@ PredictorPrintDir(TIFF* tif, FILE* fd, long flags)
case 2: fprintf(fd, "horizontal differencing "); break;
case 3: fprintf(fd, "floating point predictor "); break;
}
fprintf(fd, "%u (0x%x)\n", sp->predictor, sp->predictor);
fprintf(fd, "%d (0x%x)\n", sp->predictor, sp->predictor);
}
if (sp->printdir)
(*sp->printdir)(tif, fd, flags);

@ -1,4 +1,4 @@
/* $Id: tif_predict.h,v 1.8 2010-03-10 18:56:49 bfriesen Exp $ */
/* $Id: tif_predict.h,v 1.9 2016-10-31 17:24:26 erouault Exp $ */
/*
* Copyright (c) 1995-1997 Sam Leffler
@ -30,6 +30,8 @@
* ``Library-private'' Support for the Predictor Tag
*/
typedef int (*TIFFEncodeDecodeMethod)(TIFF* tif, uint8* buf, tmsize_t size);
/*
* Codecs that want to support the Predictor tag must place
* this structure first in their private state block so that
@ -43,12 +45,12 @@ typedef struct {
TIFFCodeMethod encoderow; /* parent codec encode/decode row */
TIFFCodeMethod encodestrip; /* parent codec encode/decode strip */
TIFFCodeMethod encodetile; /* parent codec encode/decode tile */
TIFFPostMethod encodepfunc; /* horizontal differencer */
TIFFEncodeDecodeMethod encodepfunc; /* horizontal differencer */
TIFFCodeMethod decoderow; /* parent codec encode/decode row */
TIFFCodeMethod decodestrip; /* parent codec encode/decode strip */
TIFFCodeMethod decodetile; /* parent codec encode/decode tile */
TIFFPostMethod decodepfunc; /* horizontal accumulator */
TIFFEncodeDecodeMethod decodepfunc; /* horizontal accumulator */
TIFFVGetMethod vgetparent; /* super-class method */
TIFFVSetMethod vsetparent; /* super-class method */

@ -1,4 +1,4 @@
/* $Id: tif_print.c,v 1.59 2012-06-13 01:08:51 fwarmerdam Exp $ */
/* $Id: tif_print.c,v 1.65 2016-11-20 22:31:22 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -35,9 +35,9 @@
#include <ctype.h>
static void
_TIFFprintAsciiBounded(FILE* fd, const char* cp, int max_chars);
_TIFFprintAsciiBounded(FILE* fd, const char* cp, size_t max_chars);
static const char *photoNames[] = {
static const char * const photoNames[] = {
"min-is-white", /* PHOTOMETRIC_MINISWHITE */
"min-is-black", /* PHOTOMETRIC_MINISBLACK */
"RGB color", /* PHOTOMETRIC_RGB */
@ -47,10 +47,12 @@ static const char *photoNames[] = {
"YCbCr", /* PHOTOMETRIC_YCBCR */
"7 (0x7)",
"CIE L*a*b*", /* PHOTOMETRIC_CIELAB */
"ICC L*a*b*", /* PHOTOMETRIC_ICCLAB */
"ITU L*a*b*" /* PHOTOMETRIC_ITULAB */
};
#define NPHOTONAMES (sizeof (photoNames) / sizeof (photoNames[0]))
static const char *orientNames[] = {
static const char * const orientNames[] = {
"0 (0x0)",
"row 0 top, col 0 lhs", /* ORIENTATION_TOPLEFT */
"row 0 top, col 0 rhs", /* ORIENTATION_TOPRIGHT */
@ -235,7 +237,6 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
{
TIFFDirectory *td = &tif->tif_dir;
char *sep;
uint16 i;
long l, n;
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
@ -261,7 +262,7 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
if (td->td_subfiletype & FILETYPE_MASK)
fprintf(fd, "%stransparency mask", sep);
fprintf(fd, " (%lu = 0x%lx)\n",
(long) td->td_subfiletype, (long) td->td_subfiletype);
(unsigned long) td->td_subfiletype, (long) td->td_subfiletype);
}
if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS)) {
fprintf(fd, " Image Width: %lu Image Length: %lu",
@ -363,6 +364,7 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
}
}
if (TIFFFieldSet(tif,FIELD_EXTRASAMPLES) && td->td_extrasamples) {
uint16 i;
fprintf(fd, " Extra Samples: %u<", td->td_extrasamples);
sep = "";
for (i = 0; i < td->td_extrasamples; i++) {
@ -387,13 +389,14 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
}
if (TIFFFieldSet(tif,FIELD_INKNAMES)) {
char* cp;
uint16 i;
fprintf(fd, " Ink Names: ");
i = td->td_samplesperpixel;
sep = "";
for (cp = td->td_inknames;
i > 0 && cp < td->td_inknames + td->td_inknameslen;
cp = strchr(cp,'\0')+1, i--) {
int max_chars =
size_t max_chars =
td->td_inknameslen - (cp - td->td_inknames);
fputs(sep, fd);
_TIFFprintAsciiBounded(fd, cp, max_chars);
@ -479,6 +482,7 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE))
fprintf(fd, " Max Sample Value: %u\n", td->td_maxsamplevalue);
if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE)) {
int i;
int count = (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1;
fprintf(fd, " SMin Sample Value:");
for (i = 0; i < count; ++i)
@ -486,6 +490,7 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
fprintf(fd, "\n");
}
if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE)) {
int i;
int count = (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1;
fprintf(fd, " SMax Sample Value:");
for (i = 0; i < count; ++i)
@ -516,7 +521,7 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
fprintf(fd, "\n");
n = 1L<<td->td_bitspersample;
for (l = 0; l < n; l++)
fprintf(fd, " %5lu: %5u %5u %5u\n",
fprintf(fd, " %5ld: %5u %5u %5u\n",
l,
td->td_colormap[0][l],
td->td_colormap[1][l],
@ -525,6 +530,7 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
fprintf(fd, "(present)\n");
}
if (TIFFFieldSet(tif,FIELD_REFBLACKWHITE)) {
int i;
fprintf(fd, " Reference Black/White:\n");
for (i = 0; i < 3; i++)
fprintf(fd, " %2d: %5g %5g\n", i,
@ -537,7 +543,8 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
fprintf(fd, "\n");
n = 1L<<td->td_bitspersample;
for (l = 0; l < n; l++) {
fprintf(fd, " %2lu: %5u",
uint16 i;
fprintf(fd, " %2ld: %5u",
l, td->td_transferfunction[0][l]);
for (i = 1; i < td->td_samplesperpixel; i++)
fprintf(fd, " %5u",
@ -548,6 +555,7 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
fprintf(fd, "(present)\n");
}
if (TIFFFieldSet(tif, FIELD_SUBIFD) && (td->td_subifd)) {
uint16 i;
fprintf(fd, " SubIFD Offsets:");
for (i = 0; i < td->td_nsubifd; i++)
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
@ -583,7 +591,7 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
if (fip->field_readcount == TIFF_VARIABLE2 ) {
if(TIFFGetField(tif, tag, &value_count, &raw_data) != 1)
continue;
} else if (fip->field_readcount == TIFF_VARIABLE2 ) {
} else if (fip->field_readcount == TIFF_VARIABLE ) {
uint16 small_value_count;
if(TIFFGetField(tif, tag, &small_value_count, &raw_data) != 1)
continue;
@ -653,7 +661,7 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
uint32 s;
fprintf(fd, " %lu %s:\n",
(long) td->td_nstrips,
(unsigned long) td->td_nstrips,
isTiled(tif) ? "Tiles" : "Strips");
for (s = 0; s < td->td_nstrips; s++)
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
@ -677,7 +685,7 @@ _TIFFprintAscii(FILE* fd, const char* cp)
}
static void
_TIFFprintAsciiBounded(FILE* fd, const char* cp, int max_chars)
_TIFFprintAsciiBounded(FILE* fd, const char* cp, size_t max_chars)
{
for (; max_chars > 0 && *cp != '\0'; cp++, max_chars--) {
const char* tp;

@ -1,4 +1,4 @@
/* $Id: tif_read.c,v 1.40 2012-06-01 00:55:09 fwarmerdam Exp $ */
/* $Id: tif_read.c,v 1.66 2017-11-17 20:21:00 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -31,6 +31,9 @@
#include "tiffiop.h"
#include <stdio.h>
#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0))
#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1)
int TIFFFillStrip(TIFF* tif, uint32 strip);
int TIFFFillTile(TIFF* tif, uint32 tile);
static int TIFFStartStrip(TIFF* tif, uint32 strip);
@ -38,19 +41,137 @@ static int TIFFStartTile(TIFF* tif, uint32 tile);
static int TIFFCheckRead(TIFF*, int);
static tmsize_t
TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,const char* module);
static tmsize_t
TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* module);
#define NOSTRIP ((uint32)(-1)) /* undefined state */
#define NOTILE ((uint32)(-1)) /* undefined state */
#define INITIAL_THRESHOLD (1024 * 1024)
#define THRESHOLD_MULTIPLIER 10
#define MAX_THRESHOLD (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * INITIAL_THRESHOLD)
/* Read 'size' bytes in tif_rawdata buffer starting at offset 'rawdata_offset'
* Returns 1 in case of success, 0 otherwise. */
static int TIFFReadAndRealloc( TIFF* tif, tmsize_t size,
tmsize_t rawdata_offset,
int is_strip, uint32 strip_or_tile,
const char* module )
{
#if SIZEOF_VOIDP == 8 || SIZEOF_SIZE_T == 8
tmsize_t threshold = INITIAL_THRESHOLD;
#endif
tmsize_t already_read = 0;
/* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */
/* so as to avoid allocating too much memory in case the file is too */
/* short. We could ask for the file size, but this might be */
/* expensive with some I/O layers (think of reading a gzipped file) */
/* Restrict to 64 bit processes, so as to avoid reallocs() */
/* on 32 bit processes where virtual memory is scarce. */
while( already_read < size )
{
tmsize_t bytes_read;
tmsize_t to_read = size - already_read;
#if SIZEOF_VOIDP == 8 || SIZEOF_SIZE_T == 8
if( to_read >= threshold && threshold < MAX_THRESHOLD &&
already_read + to_read + rawdata_offset > tif->tif_rawdatasize )
{
to_read = threshold;
threshold *= THRESHOLD_MULTIPLIER;
}
#endif
if (already_read + to_read + rawdata_offset > tif->tif_rawdatasize) {
uint8* new_rawdata;
assert((tif->tif_flags & TIFF_MYBUFFER) != 0);
tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64(
(uint64)already_read + to_read + rawdata_offset, 1024);
if (tif->tif_rawdatasize==0) {
TIFFErrorExt(tif->tif_clientdata, module,
"Invalid buffer size");
return 0;
}
new_rawdata = (uint8*) _TIFFrealloc(
tif->tif_rawdata, tif->tif_rawdatasize);
if( new_rawdata == 0 )
{
TIFFErrorExt(tif->tif_clientdata, module,
"No space for data buffer at scanline %lu",
(unsigned long) tif->tif_row);
_TIFFfree(tif->tif_rawdata);
tif->tif_rawdata = 0;
tif->tif_rawdatasize = 0;
return 0;
}
tif->tif_rawdata = new_rawdata;
}
bytes_read = TIFFReadFile(tif,
tif->tif_rawdata + rawdata_offset + already_read, to_read);
already_read += bytes_read;
if (bytes_read != to_read) {
memset( tif->tif_rawdata + rawdata_offset + already_read, 0,
tif->tif_rawdatasize - rawdata_offset - already_read );
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
if( is_strip )
{
TIFFErrorExt(tif->tif_clientdata, module,
"Read error at scanline %lu; got %I64u bytes, "
"expected %I64u",
(unsigned long) tif->tif_row,
(unsigned __int64) already_read,
(unsigned __int64) size);
}
else
{
TIFFErrorExt(tif->tif_clientdata, module,
"Read error at row %lu, col %lu, tile %lu; "
"got %I64u bytes, expected %I64u",
(unsigned long) tif->tif_row,
(unsigned long) tif->tif_col,
(unsigned long) strip_or_tile,
(unsigned __int64) already_read,
(unsigned __int64) size);
}
#else
if( is_strip )
{
TIFFErrorExt(tif->tif_clientdata, module,
"Read error at scanline %lu; got %llu bytes, "
"expected %llu",
(unsigned long) tif->tif_row,
(unsigned long long) already_read,
(unsigned long long) size);
}
else
{
TIFFErrorExt(tif->tif_clientdata, module,
"Read error at row %lu, col %lu, tile %lu; "
"got %llu bytes, expected %llu",
(unsigned long) tif->tif_row,
(unsigned long) tif->tif_col,
(unsigned long) strip_or_tile,
(unsigned long long) already_read,
(unsigned long long) size);
}
#endif
return 0;
}
}
return 1;
}
static int
TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
{
static const char module[] = "TIFFFillStripPartial";
register TIFFDirectory *td = &tif->tif_dir;
uint64 unused_data;
tmsize_t unused_data;
uint64 read_offset;
tmsize_t cc, to_read;
tmsize_t bytecountm;
tmsize_t to_read;
tmsize_t read_ahead_mod;
/* tmsize_t bytecountm; */
if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
return 0;
@ -61,8 +182,15 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
* bound on the size of a buffer we'll use?).
*/
bytecountm=(tmsize_t) td->td_stripbytecount[strip];
if (read_ahead*2 > tif->tif_rawdatasize) {
/* bytecountm=(tmsize_t) td->td_stripbytecount[strip]; */
/* Not completely sure where the * 2 comes from, but probably for */
/* an exponentional growth strategy of tif_rawdatasize */
if( read_ahead < TIFF_TMSIZE_T_MAX / 2 )
read_ahead_mod = read_ahead * 2;
else
read_ahead_mod = read_ahead;
if (read_ahead_mod > tif->tif_rawdatasize) {
assert( restart );
tif->tif_curstrip = NOSTRIP;
@ -72,8 +200,6 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
(unsigned long) strip);
return (0);
}
if (!TIFFReadBufferSetup(tif, 0, read_ahead*2))
return (0);
}
if( restart )
@ -113,37 +239,30 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
/*
** How much do we want to read?
*/
if( read_ahead_mod > tif->tif_rawdatasize )
to_read = read_ahead_mod - unused_data;
else
to_read = tif->tif_rawdatasize - unused_data;
if( (uint64) to_read > td->td_stripbytecount[strip]
- tif->tif_rawdataoff - tif->tif_rawdataloaded )
{
to_read = td->td_stripbytecount[strip]
to_read = (tmsize_t) td->td_stripbytecount[strip]
- tif->tif_rawdataoff - tif->tif_rawdataloaded;
}
assert((tif->tif_flags&TIFF_BUFFERMMAP)==0);
cc = TIFFReadFile(tif, tif->tif_rawdata + unused_data, to_read);
if (cc != to_read) {
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFErrorExt(tif->tif_clientdata, module,
"Read error at scanline %lu; got %I64u bytes, expected %I64u",
(unsigned long) tif->tif_row,
(unsigned __int64) cc,
(unsigned __int64) to_read);
#else
TIFFErrorExt(tif->tif_clientdata, module,
"Read error at scanline %lu; got %llu bytes, expected %llu",
(unsigned long) tif->tif_row,
(unsigned long long) cc,
(unsigned long long) to_read);
#endif
if( !TIFFReadAndRealloc( tif, to_read, unused_data,
1, /* is_strip */
0, /* strip_or_tile */
module) )
{
return 0;
}
tif->tif_rawdataoff = tif->tif_rawdataoff + tif->tif_rawdataloaded - unused_data ;
tif->tif_rawdataloaded = unused_data + to_read;
tif->tif_rawcc = tif->tif_rawdataloaded;
tif->tif_rawcp = tif->tif_rawdata;
if (!isFillOrder(tif, td->td_fillorder) &&
@ -157,10 +276,31 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
** restart the decoder.
*/
if( restart )
{
#ifdef JPEG_SUPPORT
/* A bit messy since breaks the codec abstraction. Ultimately */
/* there should be a function pointer for that, but it seems */
/* only JPEG is affected. */
/* For JPEG, if there are multiple scans (can generally be known */
/* with the read_ahead used), we need to read the whole strip */
if( tif->tif_dir.td_compression==COMPRESSION_JPEG &&
(uint64)tif->tif_rawcc < td->td_stripbytecount[strip] )
{
if( TIFFJPEGIsFullStripRequired(tif) )
{
return TIFFFillStrip(tif, strip);
}
}
#endif
return TIFFStartStrip(tif, strip);
}
else
{
return 1;
}
}
/*
* Seek to a random row+sample in a file.
@ -213,9 +353,20 @@ TIFFSeek(TIFF* tif, uint32 row, uint16 sample )
#endif
if( !whole_strip )
{
/* 16 is for YCbCr mode where we may need to read 16 */
/* lines at a time to get a decompressed line, and 5000 */
/* is some constant value, for example for JPEG tables */
if( tif->tif_scanlinesize < TIFF_TMSIZE_T_MAX / 16 &&
tif->tif_scanlinesize * 16 < TIFF_TMSIZE_T_MAX - 5000 )
{
read_ahead = tif->tif_scanlinesize * 16 + 5000;
}
else
{
read_ahead = tif->tif_scanlinesize;
}
}
/*
* If we haven't loaded this strip, do so now, possibly
@ -310,18 +461,17 @@ TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
}
/*
* Read a strip of data and decompress the specified
* amount into the user-supplied buffer.
* Calculate the strip size according to the number of
* rows in the strip (check for truncated last strip on any
* of the separations).
*/
tmsize_t
TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
static tmsize_t TIFFReadEncodedStripGetStripSize(TIFF* tif, uint32 strip, uint16* pplane)
{
static const char module[] = "TIFFReadEncodedStrip";
TIFFDirectory *td = &tif->tif_dir;
uint32 rowsperstrip;
uint32 stripsperplane;
uint32 stripinplane;
uint16 plane;
uint32 rows;
tmsize_t stripsize;
if (!TIFFCheckRead(tif,0))
@ -333,23 +483,55 @@ TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
(unsigned long)td->td_nstrips);
return((tmsize_t)(-1));
}
/*
* Calculate the strip size according to the number of
* rows in the strip (check for truncated last strip on any
* of the separations).
*/
rowsperstrip=td->td_rowsperstrip;
if (rowsperstrip>td->td_imagelength)
rowsperstrip=td->td_imagelength;
stripsperplane=((td->td_imagelength+rowsperstrip-1)/rowsperstrip);
stripsperplane= TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip);
stripinplane=(strip%stripsperplane);
plane=(strip/stripsperplane);
if( pplane ) *pplane=(uint16)(strip/stripsperplane);
rows=td->td_imagelength-stripinplane*rowsperstrip;
if (rows>rowsperstrip)
rows=rowsperstrip;
stripsize=TIFFVStripSize(tif,rows);
if (stripsize==0)
return((tmsize_t)(-1));
return stripsize;
}
/*
* Read a strip of data and decompress the specified
* amount into the user-supplied buffer.
*/
tmsize_t
TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
{
static const char module[] = "TIFFReadEncodedStrip";
TIFFDirectory *td = &tif->tif_dir;
tmsize_t stripsize;
uint16 plane;
stripsize=TIFFReadEncodedStripGetStripSize(tif, strip, &plane);
if (stripsize==((tmsize_t)(-1)))
return((tmsize_t)(-1));
/* shortcut to avoid an extra memcpy() */
if( td->td_compression == COMPRESSION_NONE &&
size!=(tmsize_t)(-1) && size >= stripsize &&
!isMapped(tif) &&
((tif->tif_flags&TIFF_NOREADRAW)==0) )
{
if (TIFFReadRawStrip1(tif, strip, buf, stripsize, module) != stripsize)
return ((tmsize_t)(-1));
if (!isFillOrder(tif, td->td_fillorder) &&
(tif->tif_flags & TIFF_NOBITREV) == 0)
TIFFReverseBits(buf,stripsize);
(*tif->tif_postdecode)(tif,buf,stripsize);
return (stripsize);
}
if ((size!=(tmsize_t)(-1))&&(size<stripsize))
stripsize=size;
if (!TIFFFillStrip(tif,strip))
@ -360,6 +542,49 @@ TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
return(stripsize);
}
/* Variant of TIFFReadEncodedStrip() that does
* * if *buf == NULL, *buf = _TIFFmalloc(bufsizetoalloc) only after TIFFFillStrip() has
* succeeded. This avoid excessive memory allocation in case of truncated
* file.
* * calls regular TIFFReadEncodedStrip() if *buf != NULL
*/
tmsize_t
_TIFFReadEncodedStripAndAllocBuffer(TIFF* tif, uint32 strip,
void **buf, tmsize_t bufsizetoalloc,
tmsize_t size_to_read)
{
tmsize_t this_stripsize;
uint16 plane;
if( *buf != NULL )
{
return TIFFReadEncodedStrip(tif, strip, *buf, size_to_read);
}
this_stripsize=TIFFReadEncodedStripGetStripSize(tif, strip, &plane);
if (this_stripsize==((tmsize_t)(-1)))
return((tmsize_t)(-1));
if ((size_to_read!=(tmsize_t)(-1))&&(size_to_read<this_stripsize))
this_stripsize=size_to_read;
if (!TIFFFillStrip(tif,strip))
return((tmsize_t)(-1));
*buf = _TIFFmalloc(bufsizetoalloc);
if (*buf == NULL) {
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for strip buffer");
return((tmsize_t)(-1));
}
_TIFFmemset(*buf, 0, bufsizetoalloc);
if ((*tif->tif_decodestrip)(tif,*buf,this_stripsize,plane)<=0)
return((tmsize_t)(-1));
(*tif->tif_postdecode)(tif,*buf,this_stripsize);
return(this_stripsize);
}
static tmsize_t
TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,
const char* module)
@ -397,16 +622,25 @@ TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,
return ((tmsize_t)(-1));
}
} else {
tmsize_t ma,mb;
tmsize_t ma = 0;
tmsize_t n;
ma=(tmsize_t)td->td_stripoffset[strip];
mb=ma+size;
if (((uint64)ma!=td->td_stripoffset[strip])||(ma>tif->tif_size))
if ((td->td_stripoffset[strip] > (uint64)TIFF_TMSIZE_T_MAX)||
((ma=(tmsize_t)td->td_stripoffset[strip])>tif->tif_size))
{
n=0;
else if ((mb<ma)||(mb<size)||(mb>tif->tif_size))
}
else if( ma > TIFF_TMSIZE_T_MAX - size )
{
n=0;
}
else
{
tmsize_t mb=ma+size;
if (mb>tif->tif_size)
n=tif->tif_size-ma;
else
n=size;
}
if (n!=size) {
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFErrorExt(tif->tif_clientdata, module,
@ -431,6 +665,43 @@ TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,
return (size);
}
static tmsize_t
TIFFReadRawStripOrTile2(TIFF* tif, uint32 strip_or_tile, int is_strip,
tmsize_t size, const char* module)
{
TIFFDirectory *td = &tif->tif_dir;
assert( !isMapped(tif) );
assert((tif->tif_flags&TIFF_NOREADRAW)==0);
if (!SeekOK(tif, td->td_stripoffset[strip_or_tile])) {
if( is_strip )
{
TIFFErrorExt(tif->tif_clientdata, module,
"Seek error at scanline %lu, strip %lu",
(unsigned long) tif->tif_row,
(unsigned long) strip_or_tile);
}
else
{
TIFFErrorExt(tif->tif_clientdata, module,
"Seek error at row %lu, col %lu, tile %lu",
(unsigned long) tif->tif_row,
(unsigned long) tif->tif_col,
(unsigned long) strip_or_tile);
}
return ((tmsize_t)(-1));
}
if( !TIFFReadAndRealloc( tif, size, 0, is_strip,
strip_or_tile, module ) )
{
return ((tmsize_t)(-1));
}
return (size);
}
/*
* Read a strip of data from the file.
*/
@ -458,7 +729,7 @@ TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
return ((tmsize_t)(-1));
}
bytecount = td->td_stripbytecount[strip];
if (bytecount <= 0) {
if ((int64)bytecount <= 0) {
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFErrorExt(tif->tif_clientdata, module,
"%I64u: Invalid strip byte count, strip %lu",
@ -498,7 +769,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
if ((tif->tif_flags&TIFF_NOREADRAW)==0)
{
uint64 bytecount = td->td_stripbytecount[strip];
if (bytecount <= 0) {
if ((int64)bytecount <= 0) {
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFErrorExt(tif->tif_clientdata, module,
"Invalid strip byte count %I64u, strip %lu",
@ -512,26 +783,40 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
#endif
return (0);
}
if (isMapped(tif) &&
(isFillOrder(tif, td->td_fillorder)
|| (tif->tif_flags & TIFF_NOBITREV))) {
/*
* The image is mapped into memory and we either don't
* need to flip bits or the compression routine is
* going to handle this operation itself. In this
* case, avoid copying the raw data and instead just
* reference the data from the memory mapped file
* image. This assumes that the decompression
* routines do not modify the contents of the raw data
* buffer (if they try to, the application will get a
* fault since the file is mapped read-only).
*/
if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
_TIFFfree(tif->tif_rawdata);
tif->tif_rawdata = NULL;
tif->tif_rawdatasize = 0;
/* To avoid excessive memory allocations: */
/* Byte count should normally not be larger than a number of */
/* times the uncompressed size plus some margin */
if( bytecount > 1024 * 1024 )
{
/* 10 and 4096 are just values that could be adjusted. */
/* Hopefully they are safe enough for all codecs */
tmsize_t stripsize = TIFFStripSize(tif);
if( stripsize != 0 &&
(bytecount - 4096) / 10 > (uint64)stripsize )
{
uint64 newbytecount = (uint64)stripsize * 10 + 4096;
if( (int64)newbytecount >= 0 )
{
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFWarningExt(tif->tif_clientdata, module,
"Too large strip byte count %I64u, strip %lu. Limiting to %I64u",
(unsigned __int64) bytecount,
(unsigned long) strip,
(unsigned __int64) newbytecount);
#else
TIFFErrorExt(tif->tif_clientdata, module,
"Too large strip byte count %llu, strip %lu. Limiting to %llu",
(unsigned long long) bytecount,
(unsigned long) strip,
(unsigned long long) newbytecount);
#endif
bytecount = newbytecount;
}
tif->tif_flags &= ~TIFF_MYBUFFER;
}
}
if (isMapped(tif)) {
/*
* We must check for overflow, potentially causing
* an OOB read. Instead of simple
@ -568,6 +853,28 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
tif->tif_curstrip = NOSTRIP;
return (0);
}
}
if (isMapped(tif) &&
(isFillOrder(tif, td->td_fillorder)
|| (tif->tif_flags & TIFF_NOBITREV))) {
/*
* The image is mapped into memory and we either don't
* need to flip bits or the compression routine is
* going to handle this operation itself. In this
* case, avoid copying the raw data and instead just
* reference the data from the memory mapped file
* image. This assumes that the decompression
* routines do not modify the contents of the raw data
* buffer (if they try to, the application will get a
* fault since the file is mapped read-only).
*/
if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
_TIFFfree(tif->tif_rawdata);
tif->tif_rawdata = NULL;
tif->tif_rawdatasize = 0;
}
tif->tif_flags &= ~TIFF_MYBUFFER;
tif->tif_rawdatasize = (tmsize_t)bytecount;
tif->tif_rawdata = tif->tif_base + (tmsize_t)td->td_stripoffset[strip];
tif->tif_rawdataoff = 0;
@ -601,17 +908,36 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
(unsigned long) strip);
return (0);
}
if (!TIFFReadBufferSetup(tif, 0, bytecountm))
return (0);
}
if (tif->tif_flags&TIFF_BUFFERMMAP) {
tif->tif_curstrip = NOSTRIP;
if (!TIFFReadBufferSetup(tif, 0, bytecountm))
tif->tif_rawdata = NULL;
tif->tif_rawdatasize = 0;
tif->tif_flags &= ~TIFF_BUFFERMMAP;
}
if( isMapped(tif) )
{
if (bytecountm > tif->tif_rawdatasize &&
!TIFFReadBufferSetup(tif, 0, bytecountm))
{
return (0);
}
if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata,
bytecountm, module) != bytecountm)
{
return (0);
}
}
else
{
if (TIFFReadRawStripOrTile2(tif, strip, 1,
bytecountm, module) != bytecountm)
{
return (0);
}
}
tif->tif_rawdataoff = 0;
tif->tif_rawdataloaded = bytecountm;
@ -661,6 +987,24 @@ TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size)
(unsigned long) tile, (unsigned long) td->td_nstrips);
return ((tmsize_t)(-1));
}
/* shortcut to avoid an extra memcpy() */
if( td->td_compression == COMPRESSION_NONE &&
size!=(tmsize_t)(-1) && size >= tilesize &&
!isMapped(tif) &&
((tif->tif_flags&TIFF_NOREADRAW)==0) )
{
if (TIFFReadRawTile1(tif, tile, buf, tilesize, module) != tilesize)
return ((tmsize_t)(-1));
if (!isFillOrder(tif, td->td_fillorder) &&
(tif->tif_flags & TIFF_NOBITREV) == 0)
TIFFReverseBits(buf,tilesize);
(*tif->tif_postdecode)(tif,buf,tilesize);
return (tilesize);
}
if (size == (tmsize_t)(-1))
size = tilesize;
else if (size > tilesize)
@ -673,6 +1017,77 @@ TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size)
return ((tmsize_t)(-1));
}
/* Variant of TIFFReadTile() that does
* * if *buf == NULL, *buf = _TIFFmalloc(bufsizetoalloc) only after TIFFFillTile() has
* succeeded. This avoid excessive memory allocation in case of truncated
* file.
* * calls regular TIFFReadEncodedTile() if *buf != NULL
*/
tmsize_t
_TIFFReadTileAndAllocBuffer(TIFF* tif,
void **buf, tmsize_t bufsizetoalloc,
uint32 x, uint32 y, uint32 z, uint16 s)
{
if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s))
return ((tmsize_t)(-1));
return (_TIFFReadEncodedTileAndAllocBuffer(tif,
TIFFComputeTile(tif, x, y, z, s),
buf, bufsizetoalloc,
(tmsize_t)(-1)));
}
/* Variant of TIFFReadEncodedTile() that does
* * if *buf == NULL, *buf = _TIFFmalloc(bufsizetoalloc) only after TIFFFillTile() has
* succeeded. This avoid excessive memory allocation in case of truncated
* file.
* * calls regular TIFFReadEncodedTile() if *buf != NULL
*/
tmsize_t
_TIFFReadEncodedTileAndAllocBuffer(TIFF* tif, uint32 tile,
void **buf, tmsize_t bufsizetoalloc,
tmsize_t size_to_read)
{
static const char module[] = "_TIFFReadEncodedTileAndAllocBuffer";
TIFFDirectory *td = &tif->tif_dir;
tmsize_t tilesize = tif->tif_tilesize;
if( *buf != NULL )
{
return TIFFReadEncodedTile(tif, tile, *buf, size_to_read);
}
if (!TIFFCheckRead(tif, 1))
return ((tmsize_t)(-1));
if (tile >= td->td_nstrips) {
TIFFErrorExt(tif->tif_clientdata, module,
"%lu: Tile out of range, max %lu",
(unsigned long) tile, (unsigned long) td->td_nstrips);
return ((tmsize_t)(-1));
}
if (!TIFFFillTile(tif,tile))
return((tmsize_t)(-1));
*buf = _TIFFmalloc(bufsizetoalloc);
if (*buf == NULL) {
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
"No space for tile buffer");
return((tmsize_t)(-1));
}
_TIFFmemset(*buf, 0, bufsizetoalloc);
if (size_to_read == (tmsize_t)(-1))
size_to_read = tilesize;
else if (size_to_read > tilesize)
size_to_read = tilesize;
if( (*tif->tif_decodetile)(tif,
(uint8*) *buf, size_to_read, (uint16)(tile/td->td_stripsperimage))) {
(*tif->tif_postdecode)(tif, (uint8*) *buf, size_to_read);
return (size_to_read);
} else
return ((tmsize_t)(-1));
}
static tmsize_t
TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* module)
{
@ -717,7 +1132,7 @@ TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* m
tmsize_t n;
ma=(tmsize_t)td->td_stripoffset[tile];
mb=ma+size;
if (((uint64)ma!=td->td_stripoffset[tile])||(ma>tif->tif_size))
if ((td->td_stripoffset[tile] > (uint64)TIFF_TMSIZE_T_MAX)||(ma>tif->tif_size))
n=0;
else if ((mb<ma)||(mb<size)||(mb>tif->tif_size))
n=tif->tif_size-ma;
@ -801,7 +1216,7 @@ TIFFFillTile(TIFF* tif, uint32 tile)
if ((tif->tif_flags&TIFF_NOREADRAW)==0)
{
uint64 bytecount = td->td_stripbytecount[tile];
if (bytecount <= 0) {
if ((int64)bytecount <= 0) {
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFErrorExt(tif->tif_clientdata, module,
"%I64u: Invalid tile byte count, tile %lu",
@ -815,6 +1230,56 @@ TIFFFillTile(TIFF* tif, uint32 tile)
#endif
return (0);
}
/* To avoid excessive memory allocations: */
/* Byte count should normally not be larger than a number of */
/* times the uncompressed size plus some margin */
if( bytecount > 1024 * 1024 )
{
/* 10 and 4096 are just values that could be adjusted. */
/* Hopefully they are safe enough for all codecs */
tmsize_t stripsize = TIFFTileSize(tif);
if( stripsize != 0 &&
(bytecount - 4096) / 10 > (uint64)stripsize )
{
uint64 newbytecount = (uint64)stripsize * 10 + 4096;
if( (int64)newbytecount >= 0 )
{
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
TIFFWarningExt(tif->tif_clientdata, module,
"Too large tile byte count %I64u, tile %lu. Limiting to %I64u",
(unsigned __int64) bytecount,
(unsigned long) tile,
(unsigned __int64) newbytecount);
#else
TIFFErrorExt(tif->tif_clientdata, module,
"Too large tile byte count %llu, tile %lu. Limiting to %llu",
(unsigned long long) bytecount,
(unsigned long) tile,
(unsigned long long) newbytecount);
#endif
bytecount = newbytecount;
}
}
}
if (isMapped(tif)) {
/*
* We must check for overflow, potentially causing
* an OOB read. Instead of simple
*
* td->td_stripoffset[tile]+bytecount > tif->tif_size
*
* comparison (which can overflow) we do the following
* two comparisons:
*/
if (bytecount > (uint64)tif->tif_size ||
td->td_stripoffset[tile] > (uint64)tif->tif_size - bytecount) {
tif->tif_curtile = NOTILE;
return (0);
}
}
if (isMapped(tif) &&
(isFillOrder(tif, td->td_fillorder)
|| (tif->tif_flags & TIFF_NOBITREV))) {
@ -835,20 +1300,7 @@ TIFFFillTile(TIFF* tif, uint32 tile)
tif->tif_rawdatasize = 0;
}
tif->tif_flags &= ~TIFF_MYBUFFER;
/*
* We must check for overflow, potentially causing
* an OOB read. Instead of simple
*
* td->td_stripoffset[tile]+bytecount > tif->tif_size
*
* comparison (which can overflow) we do the following
* two comparisons:
*/
if (bytecount > (uint64)tif->tif_size ||
td->td_stripoffset[tile] > (uint64)tif->tif_size - bytecount) {
tif->tif_curtile = NOTILE;
return (0);
}
tif->tif_rawdatasize = (tmsize_t)bytecount;
tif->tif_rawdata =
tif->tif_base + (tmsize_t)td->td_stripoffset[tile];
@ -876,18 +1328,36 @@ TIFFFillTile(TIFF* tif, uint32 tile)
(unsigned long) tile);
return (0);
}
if (!TIFFReadBufferSetup(tif, 0, bytecountm))
return (0);
}
if (tif->tif_flags&TIFF_BUFFERMMAP) {
tif->tif_curtile = NOTILE;
if (!TIFFReadBufferSetup(tif, 0, bytecountm))
return (0);
tif->tif_rawdata = NULL;
tif->tif_rawdatasize = 0;
tif->tif_flags &= ~TIFF_BUFFERMMAP;
}
if( isMapped(tif) )
{
if (bytecountm > tif->tif_rawdatasize &&
!TIFFReadBufferSetup(tif, 0, bytecountm))
{
return (0);
}
if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata,
bytecountm, module) != bytecountm)
{
return (0);
}
}
else
{
if (TIFFReadRawStripOrTile2(tif, tile, 0,
bytecountm, module) != bytecountm)
{
return (0);
}
}
tif->tif_rawdataoff = 0;
tif->tif_rawdataloaded = bytecountm;
@ -930,9 +1400,14 @@ TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size)
tif->tif_flags &= ~TIFF_MYBUFFER;
} else {
tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64((uint64)size, 1024);
if (tif->tif_rawdatasize==0)
tif->tif_rawdatasize=(tmsize_t)(-1);
tif->tif_rawdata = (uint8*) _TIFFmalloc(tif->tif_rawdatasize);
if (tif->tif_rawdatasize==0) {
TIFFErrorExt(tif->tif_clientdata, module,
"Invalid buffer size");
return (0);
}
/* Initialize to zero to avoid uninitialized buffers in case of */
/* short reads (http://bugzilla.maptools.org/show_bug.cgi?id=2651) */
tif->tif_rawdata = (uint8*) _TIFFcalloc(1, tif->tif_rawdatasize);
tif->tif_flags |= TIFF_MYBUFFER;
}
if (tif->tif_rawdata == NULL) {
@ -974,6 +1449,9 @@ TIFFStartStrip(TIFF* tif, uint32 strip)
else
{
tif->tif_rawcp = tif->tif_rawdata;
if( tif->tif_rawdataloaded > 0 )
tif->tif_rawcc = tif->tif_rawdataloaded;
else
tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[strip];
}
return ((*tif->tif_predecode)(tif,
@ -987,7 +1465,9 @@ TIFFStartStrip(TIFF* tif, uint32 strip)
static int
TIFFStartTile(TIFF* tif, uint32 tile)
{
static const char module[] = "TIFFStartTile";
TIFFDirectory *td = &tif->tif_dir;
uint32 howmany32;
if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
return 0;
@ -998,12 +1478,18 @@ TIFFStartTile(TIFF* tif, uint32 tile)
tif->tif_flags |= TIFF_CODERSETUP;
}
tif->tif_curtile = tile;
tif->tif_row =
(tile % TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth)) *
td->td_tilelength;
tif->tif_col =
(tile % TIFFhowmany_32(td->td_imagelength, td->td_tilelength)) *
td->td_tilewidth;
howmany32=TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth);
if (howmany32 == 0) {
TIFFErrorExt(tif->tif_clientdata,module,"Zero tiles");
return 0;
}
tif->tif_row = (tile % howmany32) * td->td_tilelength;
howmany32=TIFFhowmany_32(td->td_imagelength, td->td_tilelength);
if (howmany32 == 0) {
TIFFErrorExt(tif->tif_clientdata,module,"Zero tiles");
return 0;
}
tif->tif_col = (tile % howmany32) * td->td_tilewidth;
tif->tif_flags &= ~TIFF_BUF4WRITE;
if (tif->tif_flags&TIFF_NOREADRAW)
{
@ -1013,6 +1499,9 @@ TIFFStartTile(TIFF* tif, uint32 tile)
else
{
tif->tif_rawcp = tif->tif_rawdata;
if( tif->tif_rawdataloaded > 0 )
tif->tif_rawcc = tif->tif_rawdataloaded;
else
tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[tile];
}
return ((*tif->tif_predecode)(tif,

@ -1,4 +1,4 @@
/* $Id: tif_strip.c,v 1.35 2012-06-06 05:33:55 fwarmerdam Exp $ */
/* $Id: tif_strip.c,v 1.38 2016-12-03 11:02:15 erouault Exp $ */
/*
* Copyright (c) 1991-1997 Sam Leffler
@ -317,7 +317,14 @@ TIFFScanlineSize64(TIFF* tif)
}
}
else
{
scanline_size=TIFFhowmany_64(_TIFFMultiply64(tif,td->td_imagewidth,td->td_bitspersample,module),8);
}
if (scanline_size == 0)
{
TIFFErrorExt(tif->tif_clientdata,module,"Computed scanline size is zero");
return 0;
}
return(scanline_size);
}
tmsize_t
@ -328,8 +335,7 @@ TIFFScanlineSize(TIFF* tif)
tmsize_t n;
m=TIFFScanlineSize64(tif);
n=(tmsize_t)m;
if ((uint64)n!=m)
{
if ((uint64)n!=m) {
TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow");
n=0;
}

@ -1,4 +1,4 @@
/* $Id: tif_swab.c,v 1.13 2010-03-10 18:56:49 bfriesen Exp $ */
/* $Id: tif_swab.c,v 1.15 2017-06-08 16:39:50 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -31,7 +31,7 @@
*/
#include "tiffiop.h"
#ifndef TIFFSwabShort
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabShort)
void
TIFFSwabShort(uint16* wp)
{
@ -42,7 +42,7 @@ TIFFSwabShort(uint16* wp)
}
#endif
#ifndef TIFFSwabLong
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabLong)
void
TIFFSwabLong(uint32* lp)
{
@ -54,7 +54,7 @@ TIFFSwabLong(uint32* lp)
}
#endif
#ifndef TIFFSwabLong8
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabLong8)
void
TIFFSwabLong8(uint64* lp)
{
@ -68,7 +68,7 @@ TIFFSwabLong8(uint64* lp)
}
#endif
#ifndef TIFFSwabArrayOfShort
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfShort)
void
TIFFSwabArrayOfShort(register uint16* wp, tmsize_t n)
{
@ -84,7 +84,7 @@ TIFFSwabArrayOfShort(register uint16* wp, tmsize_t n)
}
#endif
#ifndef TIFFSwabArrayOfTriples
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfTriples)
void
TIFFSwabArrayOfTriples(register uint8* tp, tmsize_t n)
{
@ -100,7 +100,7 @@ TIFFSwabArrayOfTriples(register uint8* tp, tmsize_t n)
}
#endif
#ifndef TIFFSwabArrayOfLong
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfLong)
void
TIFFSwabArrayOfLong(register uint32* lp, tmsize_t n)
{
@ -117,7 +117,7 @@ TIFFSwabArrayOfLong(register uint32* lp, tmsize_t n)
}
#endif
#ifndef TIFFSwabArrayOfLong8
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfLong8)
void
TIFFSwabArrayOfLong8(register uint64* lp, tmsize_t n)
{
@ -136,7 +136,7 @@ TIFFSwabArrayOfLong8(register uint64* lp, tmsize_t n)
}
#endif
#ifndef TIFFSwabFloat
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabFloat)
void
TIFFSwabFloat(float* fp)
{
@ -148,7 +148,7 @@ TIFFSwabFloat(float* fp)
}
#endif
#ifndef TIFFSwabArrayOfFloat
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfFloat)
void
TIFFSwabArrayOfFloat(register float* fp, tmsize_t n)
{
@ -165,7 +165,7 @@ TIFFSwabArrayOfFloat(register float* fp, tmsize_t n)
}
#endif
#ifndef TIFFSwabDouble
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabDouble)
void
TIFFSwabDouble(double *dp)
{
@ -179,7 +179,7 @@ TIFFSwabDouble(double *dp)
}
#endif
#ifndef TIFFSwabArrayOfDouble
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfDouble)
void
TIFFSwabArrayOfDouble(double* dp, tmsize_t n)
{
@ -296,8 +296,10 @@ TIFFReverseBits(uint8* cp, tmsize_t n)
cp[7] = TIFFBitRevTable[cp[7]];
cp += 8;
}
while (n-- > 0)
*cp = TIFFBitRevTable[*cp], cp++;
while (n-- > 0) {
*cp = TIFFBitRevTable[*cp];
cp++;
}
}
/* vim: set ts=8 sts=8 sw=8 noet: */

@ -1,4 +1,4 @@
/* $Id: tif_thunder.c,v 1.12 2011-04-02 20:54:09 bfriesen Exp $ */
/* $Id: tif_thunder.c,v 1.13 2016-09-04 21:32:56 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -100,7 +100,8 @@ ThunderDecode(TIFF* tif, uint8* op, tmsize_t maxpixels)
while (cc > 0 && npixels < maxpixels) {
int n, delta;
n = *bp++, cc--;
n = *bp++;
cc--;
switch (n & THUNDER_CODE) {
case THUNDER_RUN: /* pixel run */
/*

@ -1,4 +1,4 @@
/* $Id: tif_tile.c,v 1.23 2012-06-06 05:33:55 fwarmerdam Exp $ */
/* $Id: tif_tile.c,v 1.24 2015-06-07 22:35:40 bfriesen Exp $ */
/*
* Copyright (c) 1991-1997 Sam Leffler
@ -143,17 +143,40 @@ TIFFNumberOfTiles(TIFF* tif)
uint64
TIFFTileRowSize64(TIFF* tif)
{
static const char module[] = "TIFFTileRowSize64";
TIFFDirectory *td = &tif->tif_dir;
uint64 rowsize;
uint64 tilerowsize;
if (td->td_tilelength == 0 || td->td_tilewidth == 0)
if (td->td_tilelength == 0)
{
TIFFErrorExt(tif->tif_clientdata,module,"Tile length is zero");
return 0;
}
if (td->td_tilewidth == 0)
{
TIFFErrorExt(tif->tif_clientdata,module,"Tile width is zero");
return (0);
}
rowsize = _TIFFMultiply64(tif, td->td_bitspersample, td->td_tilewidth,
"TIFFTileRowSize");
if (td->td_planarconfig == PLANARCONFIG_CONTIG)
{
if (td->td_samplesperpixel == 0)
{
TIFFErrorExt(tif->tif_clientdata,module,"Samples per pixel is zero");
return 0;
}
rowsize = _TIFFMultiply64(tif, rowsize, td->td_samplesperpixel,
"TIFFTileRowSize");
return (TIFFhowmany8_64(rowsize));
}
tilerowsize=TIFFhowmany8_64(rowsize);
if (tilerowsize == 0)
{
TIFFErrorExt(tif->tif_clientdata,module,"Computed tile row size is zero");
return 0;
}
return (tilerowsize);
}
tmsize_t
TIFFTileRowSize(TIFF* tif)

@ -1,4 +1,4 @@
/* $Id: tif_unix.c,v 1.23 2012-06-01 21:40:59 fwarmerdam Exp $ */
/* $Id: tif_unix.c,v 1.28 2017-01-11 19:02:49 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -55,53 +55,102 @@
#include "tiffiop.h"
#define TIFF_IO_MAX 2147483647U
typedef union fd_as_handle_union
{
int fd;
thandle_t h;
} fd_as_handle_union_t;
static tmsize_t
_tiffReadProc(thandle_t fd, void* buf, tmsize_t size)
{
size_t size_io = (size_t) size;
if ((tmsize_t) size_io != size)
fd_as_handle_union_t fdh;
const size_t bytes_total = (size_t) size;
size_t bytes_read;
tmsize_t count = -1;
if ((tmsize_t) bytes_total != size)
{
errno=EINVAL;
return (tmsize_t) -1;
}
return ((tmsize_t) read((int) fd, buf, size_io));
fdh.h = fd;
for (bytes_read=0; bytes_read < bytes_total; bytes_read+=count)
{
char *buf_offset = (char *) buf+bytes_read;
size_t io_size = bytes_total-bytes_read;
if (io_size > TIFF_IO_MAX)
io_size = TIFF_IO_MAX;
count=read(fdh.fd, buf_offset, (TIFFIOSize_t) io_size);
if (count <= 0)
break;
}
if (count < 0)
return (tmsize_t)-1;
return (tmsize_t) bytes_read;
}
static tmsize_t
_tiffWriteProc(thandle_t fd, void* buf, tmsize_t size)
{
size_t size_io = (size_t) size;
if ((tmsize_t) size_io != size)
fd_as_handle_union_t fdh;
const size_t bytes_total = (size_t) size;
size_t bytes_written;
tmsize_t count = -1;
if ((tmsize_t) bytes_total != size)
{
errno=EINVAL;
return (tmsize_t) -1;
}
return ((tmsize_t) write((int) fd, buf, size_io));
fdh.h = fd;
for (bytes_written=0; bytes_written < bytes_total; bytes_written+=count)
{
const char *buf_offset = (char *) buf+bytes_written;
size_t io_size = bytes_total-bytes_written;
if (io_size > TIFF_IO_MAX)
io_size = TIFF_IO_MAX;
count=write(fdh.fd, buf_offset, (TIFFIOSize_t) io_size);
if (count <= 0)
break;
}
if (count < 0)
return (tmsize_t)-1;
return (tmsize_t) bytes_written;
/* return ((tmsize_t) write(fdh.fd, buf, bytes_total)); */
}
static uint64
_tiffSeekProc(thandle_t fd, uint64 off, int whence)
{
off_t off_io = (off_t) off;
fd_as_handle_union_t fdh;
_TIFF_off_t off_io = (_TIFF_off_t) off;
if ((uint64) off_io != off)
{
errno=EINVAL;
return (uint64) -1; /* this is really gross */
}
return((uint64)lseek((int)fd,off_io,whence));
fdh.h = fd;
return((uint64)_TIFF_lseek_f(fdh.fd,off_io,whence));
}
static int
_tiffCloseProc(thandle_t fd)
{
return(close((int)fd));
fd_as_handle_union_t fdh;
fdh.h = fd;
return(close(fdh.fd));
}
static uint64
_tiffSizeProc(thandle_t fd)
{
struct stat sb;
if (fstat((int)fd,&sb)<0)
_TIFF_stat_s sb;
fd_as_handle_union_t fdh;
fdh.h = fd;
if (_TIFF_fstat_f(fdh.fd,&sb)<0)
return(0);
else
return((uint64)sb.st_size);
@ -116,8 +165,10 @@ _tiffMapProc(thandle_t fd, void** pbase, toff_t* psize)
uint64 size64 = _tiffSizeProc(fd);
tmsize_t sizem = (tmsize_t)size64;
if ((uint64)sizem==size64) {
fd_as_handle_union_t fdh;
fdh.h = fd;
*pbase = (void*)
mmap(0, (size_t)sizem, PROT_READ, MAP_SHARED, (int) fd, 0);
mmap(0, (size_t)sizem, PROT_READ, MAP_SHARED, fdh.fd, 0);
if (*pbase != (void*) -1) {
*psize = (tmsize_t)sizem;
return (1);
@ -155,8 +206,10 @@ TIFFFdOpen(int fd, const char* name, const char* mode)
{
TIFF* tif;
fd_as_handle_union_t fdh;
fdh.fd = fd;
tif = TIFFClientOpen(name, mode,
(thandle_t) fd,
fdh.h,
_tiffReadProc, _tiffWriteProc,
_tiffSeekProc, _tiffCloseProc, _tiffSizeProc,
_tiffMapProc, _tiffUnmapProc);
@ -225,7 +278,7 @@ TIFFOpenW(const wchar_t* name, const char* mode)
fd = _wopen(name, m, 0666);
if (fd < 0) {
TIFFErrorExt(0, module, "%s: Cannot open", name);
TIFFErrorExt(0, module, "%ls: Cannot open", name);
return ((TIFF *)0);
}
@ -257,9 +310,20 @@ TIFFOpenW(const wchar_t* name, const char* mode)
void*
_TIFFmalloc(tmsize_t s)
{
if (s == 0)
return ((void *) NULL);
return (malloc((size_t) s));
}
void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz)
{
if( nmemb == 0 || siz == 0 )
return ((void *) NULL);
return calloc((size_t) nmemb, (size_t)siz);
}
void
_TIFFfree(void* p)
{

@ -1,4 +1,4 @@
/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_warning.c,v 1.3 2010-03-10 18:56:49 bfriesen Exp $ */
/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_warning.c,v 1.4 2017-07-04 12:54:42 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -51,25 +51,33 @@ void
TIFFWarning(const char* module, const char* fmt, ...)
{
va_list ap;
if (_TIFFwarningHandler) {
va_start(ap, fmt);
if (_TIFFwarningHandler)
(*_TIFFwarningHandler)(module, fmt, ap);
if (_TIFFwarningHandlerExt)
va_end(ap);
}
if (_TIFFwarningHandlerExt) {
va_start(ap, fmt);
(*_TIFFwarningHandlerExt)(0, module, fmt, ap);
va_end(ap);
}
}
void
TIFFWarningExt(thandle_t fd, const char* module, const char* fmt, ...)
{
va_list ap;
if (_TIFFwarningHandler) {
va_start(ap, fmt);
if (_TIFFwarningHandler)
(*_TIFFwarningHandler)(module, fmt, ap);
if (_TIFFwarningHandlerExt)
va_end(ap);
}
if (_TIFFwarningHandlerExt) {
va_start(ap, fmt);
(*_TIFFwarningHandlerExt)(fd, module, fmt, ap);
va_end(ap);
}
}
/*

@ -1,4 +1,4 @@
/* $Id: tif_win32.c,v 1.39 2011-12-22 17:07:57 bfriesen Exp $ */
/* $Id: tif_win32.c,v 1.42 2017-01-11 19:02:49 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -28,6 +28,31 @@
* TIFF Library Win32-specific Routines. Adapted from tif_unix.c 4/5/95 by
* Scott Wagner (wagner@itek.com), Itek Graphix, Rochester, NY USA
*/
/*
CreateFileA/CreateFileW return type 'HANDLE'.
thandle_t is declared like
DECLARE_HANDLE(thandle_t);
in tiffio.h.
Windows (from winnt.h) DECLARE_HANDLE logic looks like
#ifdef STRICT
typedef void *HANDLE;
#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
#else
typedef PVOID HANDLE;
#define DECLARE_HANDLE(name) typedef HANDLE name
#endif
See http://bugzilla.maptools.org/show_bug.cgi?id=1941 for problems in WIN64
builds resulting from this. Unfortunately, the proposed patch was lost.
*/
#include "tiffiop.h"
#include <windows.h>
@ -214,7 +239,7 @@ TIFFFdOpen(int ifd, const char* name, const char* mode)
break;
}
}
tif = TIFFClientOpen(name, mode, (thandle_t)ifd,
tif = TIFFClientOpen(name, mode, (thandle_t)ifd, /* FIXME: WIN64 cast to pointer warning */
_tiffReadProc, _tiffWriteProc,
_tiffSeekProc, _tiffCloseProc, _tiffSizeProc,
fSuppressMap ? _tiffDummyMapProc : _tiffMapProc,
@ -259,7 +284,7 @@ TIFFOpen(const char* name, const char* mode)
return ((TIFF *)0);
}
tif = TIFFFdOpen((int)fd, name, mode);
tif = TIFFFdOpen((int)fd, name, mode); /* FIXME: WIN64 cast from pointer to int warning */
if(!tif)
CloseHandle(fd);
return tif;
@ -314,7 +339,7 @@ TIFFOpenW(const wchar_t* name, const char* mode)
NULL, NULL);
}
tif = TIFFFdOpen((int)fd,
tif = TIFFFdOpen((int)fd, /* FIXME: WIN64 cast from pointer to int warning */
(mbname != NULL) ? mbname : "<unknown>", mode);
if(!tif)
CloseHandle(fd);
@ -329,9 +354,20 @@ TIFFOpenW(const wchar_t* name, const char* mode)
void*
_TIFFmalloc(tmsize_t s)
{
if (s == 0)
return ((void *) NULL);
return (malloc((size_t) s));
}
void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz)
{
if( nmemb == 0 || siz == 0 )
return ((void *) NULL);
return calloc((size_t) nmemb, (size_t)siz);
}
void
_TIFFfree(void* p)
{

@ -1,4 +1,4 @@
/* $Id: tif_write.c,v 1.36 2011-02-18 20:53:04 fwarmerdam Exp $ */
/* $Id: tif_write.c,v 1.46 2016-12-03 21:57:44 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -115,6 +115,10 @@ TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
if (strip >= td->td_stripsperimage && imagegrew)
td->td_stripsperimage =
TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip);
if (td->td_stripsperimage == 0) {
TIFFErrorExt(tif->tif_clientdata, module, "Zero strips per image");
return (-1);
}
tif->tif_row =
(strip % td->td_stripsperimage) * td->td_rowsperstrip;
if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
@ -220,6 +224,11 @@ TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc)
tif->tif_flags |= TIFF_BUF4WRITE;
tif->tif_curstrip = strip;
if (td->td_stripsperimage == 0) {
TIFFErrorExt(tif->tif_clientdata, module, "Zero strips per image");
return ((tmsize_t) -1);
}
tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
if (!(*tif->tif_setupencode)(tif))
@ -227,17 +236,45 @@ TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc)
tif->tif_flags |= TIFF_CODERSETUP;
}
tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata;
if( td->td_stripbytecount[strip] > 0 )
{
/* Make sure that at the first attempt of rewriting the tile, we will have */
/* more bytes available in the output buffer than the previous byte count, */
/* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
/* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
if( tif->tif_rawdatasize <= (tmsize_t)td->td_stripbytecount[strip] )
{
if( !(TIFFWriteBufferSetup(tif, NULL,
(tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[strip] + 1), 1024))) )
return ((tmsize_t)(-1));
}
/* Force TIFFAppendToStrip() to consider placing data at end
of file. */
tif->tif_curoff = 0;
}
tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata;
tif->tif_flags &= ~TIFF_POSTENCODE;
/* shortcut to avoid an extra memcpy() */
if( td->td_compression == COMPRESSION_NONE )
{
/* swab if needed - note that source buffer will be altered */
tif->tif_postdecode( tif, (uint8*) data, cc );
if (!isFillOrder(tif, td->td_fillorder) &&
(tif->tif_flags & TIFF_NOBITREV) == 0)
TIFFReverseBits((uint8*) data, cc);
if (cc > 0 &&
!TIFFAppendToStrip(tif, strip, (uint8*) data, cc))
return ((tmsize_t) -1);
return (cc);
}
sample = (uint16)(strip / td->td_stripsperimage);
if (!(*tif->tif_preencode)(tif, sample))
return ((tmsize_t) -1);
@ -246,7 +283,7 @@ TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc)
tif->tif_postdecode( tif, (uint8*) data, cc );
if (!(*tif->tif_encodestrip)(tif, (uint8*) data, cc, sample))
return (0);
return ((tmsize_t) -1);
if (!(*tif->tif_postencode)(tif))
return ((tmsize_t) -1);
if (!isFillOrder(tif, td->td_fillorder) &&
@ -300,6 +337,10 @@ TIFFWriteRawStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc)
return ((tmsize_t) -1);
}
tif->tif_curstrip = strip;
if (td->td_stripsperimage == 0) {
TIFFErrorExt(tif->tif_clientdata, module,"Zero strips per image");
return ((tmsize_t) -1);
}
tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
return (TIFFAppendToStrip(tif, strip, (uint8*) data, cc) ?
cc : (tmsize_t) -1);
@ -342,6 +383,7 @@ TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc)
static const char module[] = "TIFFWriteEncodedTile";
TIFFDirectory *td;
uint16 sample;
uint32 howmany32;
if (!WRITECHECKTILES(tif, module))
return ((tmsize_t)(-1));
@ -362,24 +404,43 @@ TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc)
tif->tif_flags |= TIFF_BUF4WRITE;
tif->tif_curtile = tile;
tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata;
if( td->td_stripbytecount[tile] > 0 )
{
/* Make sure that at the first attempt of rewriting the tile, we will have */
/* more bytes available in the output buffer than the previous byte count, */
/* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
/* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
if( tif->tif_rawdatasize <= (tmsize_t) td->td_stripbytecount[tile] )
{
if( !(TIFFWriteBufferSetup(tif, NULL,
(tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[tile] + 1), 1024))) )
return ((tmsize_t)(-1));
}
/* Force TIFFAppendToStrip() to consider placing data at end
of file. */
tif->tif_curoff = 0;
}
tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata;
/*
* Compute tiles per row & per column to compute
* current row and column
*/
tif->tif_row = (tile % TIFFhowmany_32(td->td_imagelength, td->td_tilelength))
* td->td_tilelength;
tif->tif_col = (tile % TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth))
* td->td_tilewidth;
howmany32=TIFFhowmany_32(td->td_imagelength, td->td_tilelength);
if (howmany32 == 0) {
TIFFErrorExt(tif->tif_clientdata,module,"Zero tiles");
return ((tmsize_t)(-1));
}
tif->tif_row = (tile % howmany32) * td->td_tilelength;
howmany32=TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth);
if (howmany32 == 0) {
TIFFErrorExt(tif->tif_clientdata,module,"Zero tiles");
return ((tmsize_t)(-1));
}
tif->tif_col = (tile % howmany32) * td->td_tilewidth;
if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
if (!(*tif->tif_setupencode)(tif))
@ -387,9 +448,7 @@ TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc)
tif->tif_flags |= TIFF_CODERSETUP;
}
tif->tif_flags &= ~TIFF_POSTENCODE;
sample = (uint16)(tile/td->td_stripsperimage);
if (!(*tif->tif_preencode)(tif, sample))
return ((tmsize_t)(-1));
/*
* Clamp write amount to the tile size. This is mostly
* done so that callers can pass in some large number
@ -398,11 +457,30 @@ TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc)
if ( cc < 1 || cc > tif->tif_tilesize)
cc = tif->tif_tilesize;
/* shortcut to avoid an extra memcpy() */
if( td->td_compression == COMPRESSION_NONE )
{
/* swab if needed - note that source buffer will be altered */
tif->tif_postdecode( tif, (uint8*) data, cc );
if (!isFillOrder(tif, td->td_fillorder) &&
(tif->tif_flags & TIFF_NOBITREV) == 0)
TIFFReverseBits((uint8*) data, cc);
if (cc > 0 &&
!TIFFAppendToStrip(tif, tile, (uint8*) data, cc))
return ((tmsize_t) -1);
return (cc);
}
sample = (uint16)(tile/td->td_stripsperimage);
if (!(*tif->tif_preencode)(tif, sample))
return ((tmsize_t)(-1));
/* swab if needed - note that source buffer will be altered */
tif->tif_postdecode( tif, (uint8*) data, cc );
if (!(*tif->tif_encodetile)(tif, (uint8*) data, cc, sample))
return (0);
return ((tmsize_t) -1);
if (!(*tif->tif_postencode)(tif))
return ((tmsize_t)(-1));
if (!isFillOrder(tif, td->td_fillorder) &&
@ -720,7 +798,14 @@ TIFFFlushData1(TIFF* tif)
if (!TIFFAppendToStrip(tif,
isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip,
tif->tif_rawdata, tif->tif_rawcc))
{
/* We update those variables even in case of error since there's */
/* code that doesn't really check the return code of this */
/* function */
tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata;
return (0);
}
tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata;
}

@ -1,4 +1,4 @@
/* $Id: tif_zip.c,v 1.31 2011-01-06 16:00:23 fwarmerdam Exp $ */
/* $Id: tif_zip.c,v 1.37 2017-05-10 15:21:16 erouault Exp $ */
/*
* Copyright (c) 1995-1997 Sam Leffler
@ -36,7 +36,7 @@
* of the library: this code assumes the 1.0 API and also depends on
* the ability to write the zlib header multiple times (one per strip)
* which was not possible with versions prior to 0.95. Note also that
* older versions of this codec avoided this bug by supressing the header
* older versions of this codec avoided this bug by suppressing the header
* entirely. This means that files written with the old library cannot
* be read; they should be converted to a different compression scheme
* and then reconverted.
@ -61,6 +61,8 @@
#error "Antiquated ZLIB software; you must use version 1.0 or later"
#endif
#define SAFE_MSG(sp) ((sp)->stream.msg == NULL ? "" : (sp)->stream.msg)
/*
* State block for each open TIFF
* file using ZIP compression/decompression.
@ -105,8 +107,12 @@ ZIPSetupDecode(TIFF* tif)
sp->state = 0;
}
if (inflateInit(&sp->stream) != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg);
/* This function can possibly be called several times by */
/* PredictorSetupDecode() if this function succeeds but */
/* PredictorSetup() fails */
if ((sp->state & ZSTATE_INIT_DECODE) == 0 &&
inflateInit(&sp->stream) != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module, "%s", SAFE_MSG(sp));
return (0);
} else {
sp->state |= ZSTATE_INIT_DECODE;
@ -133,7 +139,7 @@ ZIPPreDecode(TIFF* tif, uint16 s)
assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised,
we need to simplify this code to reflect a ZLib that is likely updated
to deal with 8byte memory sizes, though this code will respond
apropriately even before we simplify it */
appropriately even before we simplify it */
sp->stream.avail_in = (uInt) tif->tif_rawcc;
if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc)
{
@ -160,7 +166,7 @@ ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised,
we need to simplify this code to reflect a ZLib that is likely updated
to deal with 8byte memory sizes, though this code will respond
apropriately even before we simplify it */
appropriately even before we simplify it */
sp->stream.avail_out = (uInt) occ;
if ((tmsize_t)sp->stream.avail_out != occ)
{
@ -174,14 +180,14 @@ ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
if (state == Z_DATA_ERROR) {
TIFFErrorExt(tif->tif_clientdata, module,
"Decoding error at scanline %lu, %s",
(unsigned long) tif->tif_row, sp->stream.msg);
(unsigned long) tif->tif_row, SAFE_MSG(sp));
if (inflateSync(&sp->stream) != Z_OK)
return (0);
continue;
}
if (state != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
sp->stream.msg);
TIFFErrorExt(tif->tif_clientdata, module,
"ZLib error: %s", SAFE_MSG(sp));
return (0);
}
} while (sp->stream.avail_out > 0);
@ -211,7 +217,7 @@ ZIPSetupEncode(TIFF* tif)
}
if (deflateInit(&sp->stream, sp->zipquality) != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg);
TIFFErrorExt(tif->tif_clientdata, module, "%s", SAFE_MSG(sp));
return (0);
} else {
sp->state |= ZSTATE_INIT_ENCODE;
@ -237,8 +243,8 @@ ZIPPreEncode(TIFF* tif, uint16 s)
assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised,
we need to simplify this code to reflect a ZLib that is likely updated
to deal with 8byte memory sizes, though this code will respond
apropriately even before we simplify it */
sp->stream.avail_out = tif->tif_rawdatasize;
appropriately even before we simplify it */
sp->stream.avail_out = (uInt)tif->tif_rawdatasize;
if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
{
TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
@ -264,7 +270,7 @@ ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised,
we need to simplify this code to reflect a ZLib that is likely updated
to deal with 8byte memory sizes, though this code will respond
apropriately even before we simplify it */
appropriately even before we simplify it */
sp->stream.avail_in = (uInt) cc;
if ((tmsize_t)sp->stream.avail_in != cc)
{
@ -273,8 +279,9 @@ ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
}
do {
if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module, "Encoder error: %s",
sp->stream.msg);
TIFFErrorExt(tif->tif_clientdata, module,
"Encoder error: %s",
SAFE_MSG(sp));
return (0);
}
if (sp->stream.avail_out == 0) {
@ -313,8 +320,8 @@ ZIPPostEncode(TIFF* tif)
}
break;
default:
TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
sp->stream.msg);
TIFFErrorExt(tif->tif_clientdata, module,
"ZLib error: %s", SAFE_MSG(sp));
return (0);
}
} while (state != Z_STREAM_END);
@ -359,7 +366,7 @@ ZIPVSetField(TIFF* tif, uint32 tag, va_list ap)
if (deflateParams(&sp->stream,
sp->zipquality, Z_DEFAULT_STRATEGY) != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
sp->stream.msg);
SAFE_MSG(sp));
return (0);
}
}
@ -457,7 +464,7 @@ bad:
"No space for ZIP state block");
return (0);
}
#endif /* ZIP_SUPORT */
#endif /* ZIP_SUPPORT */
/* vim: set ts=8 sts=8 sw=8 noet: */
/*

@ -1,4 +1,4 @@
/* $Id: tiff.h,v 1.67 2011-01-24 21:06:32 olivier Exp $ */
/* $Id: tiff.h,v 1.70 2016-01-23 21:20:34 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -27,7 +27,7 @@
#ifndef _TIFF_
#define _TIFF_
#include "tif_config.h"
#include "tiffconf.h"
/*
* Tag Image File Format (TIFF)
@ -166,6 +166,8 @@ typedef enum {
#define COMPRESSION_LZW 5 /* Lempel-Ziv & Welch */
#define COMPRESSION_OJPEG 6 /* !6.0 JPEG */
#define COMPRESSION_JPEG 7 /* %JPEG DCT compression */
#define COMPRESSION_T85 9 /* !TIFF/FX T.85 JBIG compression */
#define COMPRESSION_T43 10 /* !TIFF/FX T.43 colour by layered JBIG compression */
#define COMPRESSION_NEXT 32766 /* NeXT 2-bit RLE */
#define COMPRESSION_CCITTRLEW 32771 /* #1 w/ word alignment */
#define COMPRESSION_PACKBITS 32773 /* Macintosh RLE */
@ -199,6 +201,7 @@ typedef enum {
#define PHOTOMETRIC_CIELAB 8 /* !1976 CIE L*a*b* */
#define PHOTOMETRIC_ICCLAB 9 /* ICC L*a*b* [Adobe TIFF Technote 4] */
#define PHOTOMETRIC_ITULAB 10 /* ITU L*a*b* */
#define PHOTOMETRIC_CFA 32803 /* color filter array */
#define PHOTOMETRIC_LOGL 32844 /* CIE Log2(L) */
#define PHOTOMETRIC_LOGLUV 32845 /* CIE Log2(L) (u',v') */
#define TIFFTAG_THRESHHOLDING 263 /* +thresholding used on data */
@ -276,7 +279,7 @@ typedef enum {
#define PREDICTOR_FLOATINGPOINT 3 /* floating point predictor */
#define TIFFTAG_WHITEPOINT 318 /* image white point */
#define TIFFTAG_PRIMARYCHROMATICITIES 319 /* !primary chromaticities */
#define TIFFTAG_COLORMAP 320 /* RGB map for pallette image */
#define TIFFTAG_COLORMAP 320 /* RGB map for palette image */
#define TIFFTAG_HALFTONEHINTS 321 /* !highlight+shadow info */
#define TIFFTAG_TILEWIDTH 322 /* !tile width in pixels */
#define TIFFTAG_TILELENGTH 323 /* !tile height in pixels */
@ -319,6 +322,30 @@ typedef enum {
[Adobe TIFF Technote 3] */
#define TIFFTAG_JPEGTABLES 347 /* %JPEG table stream */
#define TIFFTAG_OPIPROXY 351 /* %OPI Proxy [Adobe TIFF technote] */
/* Tags 400-435 are from the TIFF/FX spec */
#define TIFFTAG_GLOBALPARAMETERSIFD 400 /* ! */
#define TIFFTAG_PROFILETYPE 401 /* ! */
#define PROFILETYPE_UNSPECIFIED 0 /* ! */
#define PROFILETYPE_G3_FAX 1 /* ! */
#define TIFFTAG_FAXPROFILE 402 /* ! */
#define FAXPROFILE_S 1 /* !TIFF/FX FAX profile S */
#define FAXPROFILE_F 2 /* !TIFF/FX FAX profile F */
#define FAXPROFILE_J 3 /* !TIFF/FX FAX profile J */
#define FAXPROFILE_C 4 /* !TIFF/FX FAX profile C */
#define FAXPROFILE_L 5 /* !TIFF/FX FAX profile L */
#define FAXPROFILE_M 6 /* !TIFF/FX FAX profile LM */
#define TIFFTAG_CODINGMETHODS 403 /* !TIFF/FX coding methods */
#define CODINGMETHODS_T4_1D (1 << 1) /* !T.4 1D */
#define CODINGMETHODS_T4_2D (1 << 2) /* !T.4 2D */
#define CODINGMETHODS_T6 (1 << 3) /* !T.6 */
#define CODINGMETHODS_T85 (1 << 4) /* !T.85 JBIG */
#define CODINGMETHODS_T42 (1 << 5) /* !T.42 JPEG */
#define CODINGMETHODS_T43 (1 << 6) /* !T.43 colour by layered JBIG */
#define TIFFTAG_VERSIONYEAR 404 /* !TIFF/FX version year */
#define TIFFTAG_MODENUMBER 405 /* !TIFF/FX mode number */
#define TIFFTAG_DECODE 433 /* !TIFF/FX decode */
#define TIFFTAG_IMAGEBASECOLOR 434 /* !TIFF/FX image base colour */
#define TIFFTAG_T82OPTIONS 435 /* !TIFF/FX T.82 options */
/*
* Tags 512-521 are obsoleted by Technical Note #2 which specifies a
* revised JPEG-in-TIFF scheme.
@ -331,7 +358,7 @@ typedef enum {
#define TIFFTAG_JPEGRESTARTINTERVAL 515 /* !restart interval length */
#define TIFFTAG_JPEGLOSSLESSPREDICTORS 517 /* !lossless proc predictor */
#define TIFFTAG_JPEGPOINTTRANSFORM 518 /* !lossless point transform */
#define TIFFTAG_JPEGQTABLES 519 /* !Q matrice offsets */
#define TIFFTAG_JPEGQTABLES 519 /* !Q matrix offsets */
#define TIFFTAG_JPEGDCTABLES 520 /* !DCT table offsets */
#define TIFFTAG_JPEGACTABLES 521 /* !AC coefficient offsets */
#define TIFFTAG_YCBCRCOEFFICIENTS 529 /* !RGB -> YCbCr transform */
@ -340,6 +367,7 @@ typedef enum {
#define YCBCRPOSITION_CENTERED 1 /* !as in PostScript Level 2 */
#define YCBCRPOSITION_COSITED 2 /* !as in CCIR 601-1 */
#define TIFFTAG_REFERENCEBLACKWHITE 532 /* !colorimetry info */
#define TIFFTAG_STRIPROWCOUNTS 559 /* !TIFF/FX strip row counts */
#define TIFFTAG_XMLPACKET 700 /* %XML packet
[Adobe XMP Specification,
January 2004 */
@ -375,6 +403,8 @@ typedef enum {
#define TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA 33306
/* tag 33405 is a private tag registered to Eastman Kodak */
#define TIFFTAG_WRITERSERIALNUMBER 33405 /* device serial number */
#define TIFFTAG_CFAREPEATPATTERNDIM 33421 /* dimensions of CFA pattern */
#define TIFFTAG_CFAPATTERN 33422 /* color filter array pattern */
/* tag 33432 is listed in the 6.0 spec w/ unknown ownership */
#define TIFFTAG_COPYRIGHT 33432 /* copyright string */
/* IPTC TAG from RichTIFF specifications */
@ -406,6 +436,7 @@ typedef enum {
#define TIFFTAG_EXIFIFD 34665 /* Pointer to EXIF private directory */
/* tag 34750 is a private tag registered to Adobe? */
#define TIFFTAG_ICCPROFILE 34675 /* ICC profile data */
#define TIFFTAG_IMAGELAYER 34732 /* !TIFF/FX image layer information */
/* tag 34750 is a private tag registered to Pixel Magic */
#define TIFFTAG_JBIGOPTIONS 34750 /* JBIG options */
#define TIFFTAG_GPSIFD 34853 /* Pointer to GPS private directory */

@ -0,0 +1,130 @@
/*
Configuration defines for installed libtiff.
This file maintained for backward compatibility. Do not use definitions
from this file in your programs.
*/
#ifndef _TIFFCONF_
#define _TIFFCONF_
/* Signed 16-bit type */
#define TIFF_INT16_T @TIFF_INT16_T@
/* Signed 32-bit type */
#define TIFF_INT32_T @TIFF_INT32_T@
/* Signed 64-bit type */
#define TIFF_INT64_T @TIFF_INT64_T@
/* Signed 8-bit type */
#define TIFF_INT8_T @TIFF_INT8_T@
/* Unsigned 16-bit type */
#define TIFF_UINT16_T @TIFF_UINT16_T@
/* Unsigned 32-bit type */
#define TIFF_UINT32_T @TIFF_UINT32_T@
/* Unsigned 64-bit type */
#define TIFF_UINT64_T @TIFF_UINT64_T@
/* Unsigned 8-bit type */
#define TIFF_UINT8_T @TIFF_UINT8_T@
/* Unsigned size type */
#define TIFF_SIZE_T @TIFF_SIZE_T@
/* Signed size type */
#define TIFF_SSIZE_T @TIFF_SSIZE_T@
/* 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
machine */
#cmakedefine HAVE_IEEEFP 1
/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
#define HOST_FILLORDER @HOST_FILLORDER@
/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian
(Intel) */
#define HOST_BIGENDIAN @HOST_BIG_ENDIAN@
/* Support CCITT Group 3 & 4 algorithms */
#cmakedefine CCITT_SUPPORT 1
/* Support JPEG compression (requires IJG JPEG library) */
#cmakedefine JPEG_SUPPORT 1
/* Support JBIG compression (requires JBIG-KIT library) */
#cmakedefine JBIG_SUPPORT
/* Support LogLuv high dynamic range encoding */
#cmakedefine LOGLUV_SUPPORT 1
/* Support LZW algorithm */
#cmakedefine LZW_SUPPORT 1
/* Support NeXT 2-bit RLE algorithm */
#cmakedefine NEXT_SUPPORT 1
/* Support Old JPEG compresson (read contrib/ojpeg/README first! Compilation
fails with unpatched IJG JPEG library) */
#cmakedefine OJPEG_SUPPORT 1
/* Support Macintosh PackBits algorithm */
#cmakedefine PACKBITS_SUPPORT 1
/* Support Pixar log-format algorithm (requires Zlib) */
#cmakedefine PIXARLOG_SUPPORT 1
/* Support ThunderScan 4-bit RLE algorithm */
#cmakedefine THUNDER_SUPPORT 1
/* Support Deflate compression */
#cmakedefine ZIP_SUPPORT 1
/* Support strip chopping (whether or not to convert single-strip uncompressed
images to mutiple strips of ~8Kb to reduce memory usage) */
#cmakedefine STRIPCHOP_DEFAULT 1
/* Enable SubIFD tag (330) support */
#cmakedefine SUBIFD_SUPPORT 1
/* Treat extra sample as alpha (default enabled). The RGBA interface will
treat a fourth sample with no EXTRASAMPLE_ value as being ASSOCALPHA. Many
packages produce RGBA files but don't mark the alpha properly. */
#cmakedefine DEFAULT_EXTRASAMPLE_AS_ALPHA 1
/* Pick up YCbCr subsampling info from the JPEG data stream to support files
lacking the tag (default enabled). */
#cmakedefine CHECK_JPEG_YCBCR_SUBSAMPLING 1
/* Support MS MDI magic number files as TIFF */
#cmakedefine MDI_SUPPORT 1
/*
* Feature support definitions.
* XXX: These macros are obsoleted. Don't use them in your apps!
* Macros stays here for backward compatibility and should be always defined.
*/
#define COLORIMETRY_SUPPORT
#define YCBCR_SUPPORT
#define CMYK_SUPPORT
#define ICC_SUPPORT
#define PHOTOSHOP_SUPPORT
#define IPTC_SUPPORT
#endif /* _TIFFCONF_ */

@ -1,4 +1,4 @@
/* $Id: tiffio.h,v 1.90 2012-06-06 04:58:00 fwarmerdam Exp $ */
/* $Id: tiffio.h,v 1.94 2017-01-11 19:02:49 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -208,7 +208,7 @@ struct _TIFFRGBAImage {
uint16 orientation; /* image orientation */
uint16 req_orientation; /* requested orientation */
uint16 photometric; /* image photometric interp */
uint16* redcmap; /* colormap pallete */
uint16* redcmap; /* colormap palette */
uint16* greencmap;
uint16* bluecmap;
/* get image data routine */
@ -225,7 +225,7 @@ struct _TIFFRGBAImage {
TIFFYCbCrToRGB* ycbcr; /* YCbCr conversion state */
TIFFCIELabToRGB* cielab; /* CIE L*a*b conversion state */
uint8* UaToAa; /* Unassociated alpha to associated alpha convertion LUT */
uint8* UaToAa; /* Unassociated alpha to associated alpha conversion LUT */
uint8* Bitdepth16To8; /* LUT for conversion from 16bit to 8bit values */
int row_offset;
@ -293,6 +293,7 @@ extern TIFFCodec* TIFFGetConfiguredCODECs(void);
*/
extern void* _TIFFmalloc(tmsize_t s);
extern void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz);
extern void* _TIFFrealloc(void* p, tmsize_t s);
extern void _TIFFmemset(void* p, int v, tmsize_t c);
extern void _TIFFmemcpy(void* d, const void* s, tmsize_t c);
@ -319,6 +320,13 @@ extern const TIFFField* TIFFFindField(TIFF *, uint32, TIFFDataType);
extern const TIFFField* TIFFFieldWithTag(TIFF*, uint32);
extern const TIFFField* TIFFFieldWithName(TIFF*, const char *);
extern uint32 TIFFFieldTag(const TIFFField*);
extern const char* TIFFFieldName(const TIFFField*);
extern TIFFDataType TIFFFieldDataType(const TIFFField*);
extern int TIFFFieldPassCount(const TIFFField*);
extern int TIFFFieldReadCount(const TIFFField*);
extern int TIFFFieldWriteCount(const TIFFField*);
typedef int (*TIFFVSetMethod)(TIFF*, uint32, va_list);
typedef int (*TIFFVGetMethod)(TIFF*, uint32, va_list);
typedef void (*TIFFPrintMethod)(TIFF*, FILE*, long);
@ -423,6 +431,8 @@ extern int TIFFReadRGBAImageOriented(TIFF*, uint32, uint32, uint32*, int, int);
extern int TIFFReadRGBAStrip(TIFF*, uint32, uint32 * );
extern int TIFFReadRGBATile(TIFF*, uint32, uint32, uint32 * );
extern int TIFFReadRGBAStripExt(TIFF*, uint32, uint32 *, int stop_on_error );
extern int TIFFReadRGBATileExt(TIFF*, uint32, uint32, uint32 *, int stop_on_error );
extern int TIFFRGBAImageOK(TIFF*, char [1024]);
extern int TIFFRGBAImageBegin(TIFFRGBAImage*, TIFF*, int, char [1024]);
extern int TIFFRGBAImageGet(TIFFRGBAImage*, uint32*, uint32, uint32);

@ -1,4 +1,4 @@
/* $Id: tiffiop.h,v 1.84 2012-05-30 01:50:17 fwarmerdam Exp $ */
/* $Id: tiffiop.h,v 1.95 2017-09-07 14:02:52 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@ -57,6 +57,12 @@ extern void *lfind(const void *, const void *, size_t *, size_t,
int (*)(const void *, const void *));
#endif
#if !defined(HAVE_SNPRINTF) && !defined(HAVE__SNPRINTF)
#undef snprintf
#define snprintf _TIFF_snprintf_f
extern int snprintf(char* str, size_t size, const char* format, ...);
#endif
#include "tiffio.h"
#include "tif_dir.h"
@ -80,7 +86,7 @@ typedef struct client_info {
/*
* Typedefs for ``method pointers'' used internally.
* these are depriciated and provided only for backwards compatibility
* these are deprecated and provided only for backwards compatibility.
*/
typedef unsigned char tidataval_t; /* internal image data value type */
typedef tidataval_t* tidata_t; /* reference to internal image data */
@ -99,33 +105,33 @@ struct tiff {
int tif_fd; /* open file descriptor */
int tif_mode; /* open mode (O_*) */
uint32 tif_flags;
#define TIFF_FILLORDER 0x00003 /* natural bit fill order for machine */
#define TIFF_DIRTYHEADER 0x00004 /* header must be written on close */
#define TIFF_DIRTYDIRECT 0x00008 /* current directory must be written */
#define TIFF_BUFFERSETUP 0x00010 /* data buffers setup */
#define TIFF_CODERSETUP 0x00020 /* encoder/decoder setup done */
#define TIFF_BEENWRITING 0x00040 /* written 1+ scanlines to file */
#define TIFF_SWAB 0x00080 /* byte swap file information */
#define TIFF_NOBITREV 0x00100 /* inhibit bit reversal logic */
#define TIFF_MYBUFFER 0x00200 /* my raw data buffer; free on close */
#define TIFF_ISTILED 0x00400 /* file is tile, not strip- based */
#define TIFF_MAPPED 0x00800 /* file is mapped into memory */
#define TIFF_POSTENCODE 0x01000 /* need call to postencode routine */
#define TIFF_INSUBIFD 0x02000 /* currently writing a subifd */
#define TIFF_UPSAMPLED 0x04000 /* library is doing data up-sampling */
#define TIFF_STRIPCHOP 0x08000 /* enable strip chopping support */
#define TIFF_HEADERONLY 0x10000 /* read header only, do not process the first directory */
#define TIFF_NOREADRAW 0x20000 /* skip reading of raw uncompressed image data */
#define TIFF_INCUSTOMIFD 0x40000 /* currently writing a custom IFD */
#define TIFF_BIGTIFF 0x80000 /* read/write bigtiff */
#define TIFF_BUF4WRITE 0x100000 /* rawcc bytes are for writing */
#define TIFF_DIRTYSTRIP 0x200000 /* stripoffsets/stripbytecount dirty*/
#define TIFF_PERSAMPLE 0x400000 /* get/set per sample tags as arrays */
#define TIFF_BUFFERMMAP 0x800000 /* read buffer (tif_rawdata) points into mmap() memory */
#define TIFF_FILLORDER 0x00003U /* natural bit fill order for machine */
#define TIFF_DIRTYHEADER 0x00004U /* header must be written on close */
#define TIFF_DIRTYDIRECT 0x00008U /* current directory must be written */
#define TIFF_BUFFERSETUP 0x00010U /* data buffers setup */
#define TIFF_CODERSETUP 0x00020U /* encoder/decoder setup done */
#define TIFF_BEENWRITING 0x00040U /* written 1+ scanlines to file */
#define TIFF_SWAB 0x00080U /* byte swap file information */
#define TIFF_NOBITREV 0x00100U /* inhibit bit reversal logic */
#define TIFF_MYBUFFER 0x00200U /* my raw data buffer; free on close */
#define TIFF_ISTILED 0x00400U /* file is tile, not strip- based */
#define TIFF_MAPPED 0x00800U /* file is mapped into memory */
#define TIFF_POSTENCODE 0x01000U /* need call to postencode routine */
#define TIFF_INSUBIFD 0x02000U /* currently writing a subifd */
#define TIFF_UPSAMPLED 0x04000U /* library is doing data up-sampling */
#define TIFF_STRIPCHOP 0x08000U /* enable strip chopping support */
#define TIFF_HEADERONLY 0x10000U /* read header only, do not process the first directory */
#define TIFF_NOREADRAW 0x20000U /* skip reading of raw uncompressed image data */
#define TIFF_INCUSTOMIFD 0x40000U /* currently writing a custom IFD */
#define TIFF_BIGTIFF 0x80000U /* read/write bigtiff */
#define TIFF_BUF4WRITE 0x100000U /* rawcc bytes are for writing */
#define TIFF_DIRTYSTRIP 0x200000U /* stripoffsets/stripbytecount dirty*/
#define TIFF_PERSAMPLE 0x400000U /* get/set per sample tags as arrays */
#define TIFF_BUFFERMMAP 0x800000U /* read buffer (tif_rawdata) points into mmap() memory */
uint64 tif_diroff; /* file offset of current directory */
uint64 tif_nextdiroff; /* file offset of following directory */
uint64* tif_dirlist; /* list of offsets to already seen directories to prevent IFD looping */
uint16 tif_dirlistsize; /* number of entires in offset list */
uint16 tif_dirlistsize; /* number of entries in offset list */
uint16 tif_dirnumber; /* number of already seen directories */
TIFFDirectory tif_dir; /* internal rep of current directory */
TIFFDirectory tif_customdir; /* custom IFDs are separated from the main ones */
@ -232,8 +238,7 @@ struct tiff {
(TIFFReadFile((tif),(buf),(size))==(size))
#endif
#ifndef SeekOK
#define SeekOK(tif, off) \
(TIFFSeekFile((tif),(off),SEEK_SET)==(off))
#define SeekOK(tif, off) _TIFFSeekOK(tif, off)
#endif
#ifndef WriteOK
#define WriteOK(tif, buf, size) \
@ -244,6 +249,10 @@ struct tiff {
#define TIFFhowmany_32(x, y) (((uint32)x < (0xffffffff - (uint32)(y-1))) ? \
((((uint32)(x))+(((uint32)(y))-1))/((uint32)(y))) : \
0U)
/* Variant of TIFFhowmany_32() that doesn't return 0 if x close to MAXUINT. */
/* Caution: TIFFhowmany_32_maxuint_compat(x,y)*y might overflow */
#define TIFFhowmany_32_maxuint_compat(x, y) \
(((uint32)(x) / (uint32)(y)) + ((((uint32)(x) % (uint32)(y)) != 0) ? 1 : 0))
#define TIFFhowmany8_32(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3)
#define TIFFroundup_32(x, y) (TIFFhowmany_32(x,y)*(y))
#define TIFFhowmany_64(x, y) ((((uint64)(x))+(((uint64)(y))-1))/((uint64)(y)))
@ -258,6 +267,60 @@ struct tiff {
#define TIFFArrayCount(a) (sizeof (a) / sizeof ((a)[0]))
/*
Support for large files.
Windows read/write APIs support only 'unsigned int' rather than 'size_t'.
Windows off_t is only 32-bit, even in 64-bit builds.
*/
#if defined(HAVE_FSEEKO)
/*
Use fseeko() and ftello() if they are available since they use
'off_t' rather than 'long'. It is wrong to use fseeko() and
ftello() only on systems with special LFS support since some systems
(e.g. FreeBSD) support a 64-bit off_t by default.
For MinGW, __MSVCRT_VERSION__ must be at least 0x800 to expose these
interfaces. The MinGW compiler must support the requested version. MinGW
does not distribute the CRT (it is supplied by Microsoft) so the correct CRT
must be available on the target computer in order for the program to run.
*/
#if defined(HAVE_FSEEKO)
# define fseek(stream,offset,whence) fseeko(stream,offset,whence)
# define ftell(stream,offset,whence) ftello(stream,offset,whence)
#endif
#endif
#if defined(__WIN32__) && \
!(defined(_MSC_VER) && _MSC_VER < 1400) && \
!(defined(__MSVCRT_VERSION__) && __MSVCRT_VERSION__ < 0x800)
typedef unsigned int TIFFIOSize_t;
#define _TIFF_lseek_f(fildes,offset,whence) _lseeki64(fildes,/* __int64 */ offset,whence)
/* #define _TIFF_tell_f(fildes) /\* __int64 *\/ _telli64(fildes) */
#define _TIFF_fseek_f(stream,offset,whence) _fseeki64(stream,/* __int64 */ offset,whence)
#define _TIFF_fstat_f(fildes,stat_buff) _fstati64(fildes,/* struct _stati64 */ stat_buff)
/* #define _TIFF_ftell_f(stream) /\* __int64 *\/ _ftelli64(stream) */
/* #define _TIFF_stat_f(path,stat_buff) _stati64(path,/\* struct _stati64 *\/ stat_buff) */
#define _TIFF_stat_s struct _stati64
#define _TIFF_off_t __int64
#else
typedef size_t TIFFIOSize_t;
#define _TIFF_lseek_f(fildes,offset,whence) lseek(fildes,offset,whence)
/* #define _TIFF_tell_f(fildes) (_TIFF_lseek_f(fildes,0,SEEK_CUR)) */
#define _TIFF_fseek_f(stream,offset,whence) fseek(stream,offset,whence)
#define _TIFF_fstat_f(fildes,stat_buff) fstat(fildes,stat_buff)
/* #define _TIFF_ftell_f(stream) ftell(stream) */
/* #define _TIFF_stat_f(path,stat_buff) stat(path,stat_buff) */
#define _TIFF_stat_s struct stat
#define _TIFF_off_t off_t
#endif
#if __clang_major__ >= 4 || (__clang_major__ == 3 && __clang_minor__ >= 8)
#define TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW __attribute__((no_sanitize("unsigned-integer-overflow")))
#else
#define TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
#endif
#if defined(__cplusplus)
extern "C" {
#endif
@ -308,6 +371,20 @@ extern void* _TIFFCheckRealloc(TIFF*, void*, tmsize_t, tmsize_t, const char*);
extern double _TIFFUInt64ToDouble(uint64);
extern float _TIFFUInt64ToFloat(uint64);
extern tmsize_t
_TIFFReadEncodedStripAndAllocBuffer(TIFF* tif, uint32 strip,
void **buf, tmsize_t bufsizetoalloc,
tmsize_t size_to_read);
extern tmsize_t
_TIFFReadEncodedTileAndAllocBuffer(TIFF* tif, uint32 tile,
void **buf, tmsize_t bufsizetoalloc,
tmsize_t size_to_read);
extern tmsize_t
_TIFFReadTileAndAllocBuffer(TIFF* tif,
void **buf, tmsize_t bufsizetoalloc,
uint32 x, uint32 y, uint32 z, uint16 s);
extern int _TIFFSeekOK(TIFF* tif, toff_t off);
extern int TIFFInitDumpMode(TIFF*, int);
#ifdef PACKBITS_SUPPORT
extern int TIFFInitPackBits(TIFF*, int);
@ -330,6 +407,7 @@ extern int TIFFInitOJPEG(TIFF*, int);
#endif
#ifdef JPEG_SUPPORT
extern int TIFFInitJPEG(TIFF*, int);
extern int TIFFJPEGIsFullStripRequired(TIFF*);
#endif
#ifdef JBIG_SUPPORT
extern int TIFFInitJBIG(TIFF*, int);

@ -1,4 +1,4 @@
#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.0.2\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc."
#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.0.9\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 20120615
#define TIFFLIB_VERSION 20171118

@ -3,7 +3,7 @@
#define UV_NDIVS 16289
#define UV_VSTART (float)0.016940
#define UV_NVS 163
static struct {
static const struct {
float ustart;
short nus, ncum;
} uv_row[UV_NVS] = {

@ -26,7 +26,28 @@ if(NOT ZLIB_FOUND)
ocv_parse_header2(ZLIB "${${ZLIB_LIBRARY}_SOURCE_DIR}/zlib.h" ZLIB_VERSION)
endif()
# --- libtiff (optional, should be searched after zlib) ---
# --- libjpeg (optional) ---
if(WITH_JPEG)
if(BUILD_JPEG)
ocv_clear_vars(JPEG_FOUND)
else()
include(FindJPEG)
endif()
if(NOT JPEG_FOUND)
ocv_clear_vars(JPEG_LIBRARY JPEG_LIBRARIES JPEG_INCLUDE_DIR)
set(JPEG_LIBRARY libjpeg)
set(JPEG_LIBRARIES ${JPEG_LIBRARY})
add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libjpeg")
set(JPEG_INCLUDE_DIR "${${JPEG_LIBRARY}_SOURCE_DIR}")
endif()
ocv_parse_header("${JPEG_INCLUDE_DIR}/jpeglib.h" JPEG_VERSION_LINES JPEG_LIB_VERSION)
set(HAVE_JPEG YES)
endif()
# --- libtiff (optional, should be searched after zlib and libjpeg) ---
if(WITH_TIFF)
if(BUILD_TIFF)
ocv_clear_vars(TIFF_FOUND)
@ -68,27 +89,6 @@ if(WITH_TIFF)
set(HAVE_TIFF YES)
endif()
# --- libjpeg (optional) ---
if(WITH_JPEG)
if(BUILD_JPEG)
ocv_clear_vars(JPEG_FOUND)
else()
include(FindJPEG)
endif()
if(NOT JPEG_FOUND)
ocv_clear_vars(JPEG_LIBRARY JPEG_LIBRARIES JPEG_INCLUDE_DIR)
set(JPEG_LIBRARY libjpeg)
set(JPEG_LIBRARIES ${JPEG_LIBRARY})
add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libjpeg")
set(JPEG_INCLUDE_DIR "${${JPEG_LIBRARY}_SOURCE_DIR}")
endif()
ocv_parse_header("${JPEG_INCLUDE_DIR}/jpeglib.h" JPEG_VERSION_LINES JPEG_LIB_VERSION)
set(HAVE_JPEG YES)
endif()
# --- libwebp (optional) ---
if(WITH_WEBP)

Loading…
Cancel
Save