diff --git a/thirdparty/CMakeLists.txt b/thirdparty/CMakeLists.txt index 7ab24ba3..955ee179 100644 --- a/thirdparty/CMakeLists.txt +++ b/thirdparty/CMakeLists.txt @@ -57,7 +57,10 @@ IF(BUILD_THIRDPARTY) message(STATUS "We will build TIFF lib from thirdparty") ADD_SUBDIRECTORY(libtiff) SET(TIFF_LIBNAME tiff PARENT_SCOPE) - SET(TIFF_INCLUDE_DIRNAME ${OPENJPEG_SOURCE_DIR}/thirdparty/libtiff PARENT_SCOPE) + SET(TIFF_INCLUDE_DIRNAME + ${OPENJPEG_SOURCE_DIR}/thirdparty/libtiff + ${OPENJPEG_BINARY_DIR}/thirdparty/libtiff + PARENT_SCOPE) SET(HAVE_TIFF_H 1 PARENT_SCOPE) SET(HAVE_LIBTIFF 1 PARENT_SCOPE) ELSE (BUILD_THIRDPARTY) diff --git a/thirdparty/libtiff/CMakeLists.txt b/thirdparty/libtiff/CMakeLists.txt index 14601f0b..efc86141 100644 --- a/thirdparty/libtiff/CMakeLists.txt +++ b/thirdparty/libtiff/CMakeLists.txt @@ -1,78 +1,253 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) project(libtiff C) +# This convenient copy of libtiff does not support encapsulated zlib or jpeg +# stream. see ZIP_SUPPORT and JPEG_SUPPORT values -INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}") -# -ADD_DEFINITIONS(-DHAVE_STRING_H=1) +INCLUDE_DIRECTORIES(BEFORE "${CMAKE_CURRENT_SOURCE_DIR}") +INCLUDE_DIRECTORIES(BEFORE "${CMAKE_CURRENT_BINARY_DIR}") SET(TARGET_FILES - t4.h - tiffiop.h - tif_aux.c - tif_close.c - tif_codec.c - tif_color.c - tif_compress.c - tif_dir.c - tif_dir.h - tif_dirinfo.c - tif_dirread.c - tif_dirwrite.c - tif_dumpmode.c - tif_error.c - tif_extension.c - tif_fax3.c - tif_fax3.h - tif_fax3sm.c - tif_flush.c - tif_getimage.c - tif_jbig.c - tif_jpeg.c - tif_luv.c - tif_lzw.c - tif_next.c - tif_ojpeg.c - tif_open.c - tif_packbits.c - tif_pixarlog.c - tif_predict.c - tif_predict.h - tif_print.c - tif_read.c - tif_strip.c - tif_swab.c - tif_thunder.c - tif_tile.c - tif_version.c - tif_warning.c - tif_write.c - tif_zip.c - uvcode.h - ) + t4.h + tiffiop.h + tif_aux.c + tif_close.c + tif_codec.c + tif_color.c + tif_compress.c + tif_dir.c + tif_dir.h + tif_dirinfo.c + tif_dirread.c + tif_dirwrite.c + tif_dumpmode.c + tif_error.c + tif_extension.c + tif_fax3.c + tif_fax3.h + tif_fax3sm.c + tif_flush.c + tif_getimage.c + tif_jbig.c + tif_jpeg.c + tif_luv.c + tif_lzw.c + tif_next.c + tif_ojpeg.c + tif_open.c + tif_packbits.c + tif_pixarlog.c + tif_predict.c + tif_predict.h + tif_print.c + tif_read.c + tif_strip.c + tif_swab.c + tif_thunder.c + tif_tile.c + tif_version.c + tif_warning.c + tif_write.c + tif_zip.c + tif_jpeg_12.c + tif_lzma.c + uvcode.h + ) IF(UNIX) - SET(TARGET_FILES ${TARGET_FILES} tif_unix.c) + SET(TARGET_FILES ${TARGET_FILES} tif_unix.c) +ELSE() + SET(TARGET_FILES ${TARGET_FILES} tif_win32.c) ENDIF() -IF(WIN32) - SET(TARGET_FILES ${TARGET_FILES} tif_win32.c) -ENDIF(WIN32) +include(${CMAKE_ROOT}/Modules/TestBigEndian.cmake) +TEST_BIG_ENDIAN(WORDS_BIGENDIAN) +set(HOST_BIGENDIAN ${WORDS_BIGENDIAN}) +if(HOST_BIGENDIAN) +set(HOST_FILLORDER "FILLORDER_MSB2LSB") +else() +set(HOST_FILLORDER "FILLORDER_LSB2MSB") +endif() +include(CheckIncludeFiles) +include(CheckSymbolExists) +include(CheckFunctionExists) -#IF(APPLE) -# SET(TARGET_FILES ${TARGET_FILES} tif_apple.c) -#ENDIF(APPLE) +CHECK_INCLUDE_FILES("zlib.h" HAVE_ZLIB_H) +CHECK_INCLUDE_FILES("jpeglib.h" HAVE_JPEGLIB_H) +if(HAVE_JPEGLIB_H) + set(JPEG_SUPPORT 1) +endif() +if(HAVE_ZLIB_H) + include_directories( + ${ZLIB_INCLUDE_DIR} + ) + set(ZIP_SUPPORT 1) + set(PIXARLOG_SUPPORT 1) # require zlib +endif() +CHECK_INCLUDE_FILES("assert.h" HAVE_ASSERT_H) +CHECK_INCLUDE_FILES("dlfcn.h" HAVE_DLFCN_H) +CHECK_INCLUDE_FILES("fcntl.h" HAVE_FCNTL_H) +CHECK_INCLUDE_FILES("inttypes.h" HAVE_INTTYPES_H) +CHECK_INCLUDE_FILES("io.h" HAVE_IO_H) +CHECK_INCLUDE_FILES("limits.h" HAVE_LIMITS_H) +CHECK_INCLUDE_FILES("malloc.h" HAVE_MALLOC_H) +CHECK_INCLUDE_FILES("memory.h" HAVE_MEMORY_H) +CHECK_INCLUDE_FILES("search.h" HAVE_SEARCH_H) +CHECK_INCLUDE_FILES("stdint.h" HAVE_STDINT_H) +CHECK_INCLUDE_FILES("stdlib.h" HAVE_STDLIB_H) +CHECK_INCLUDE_FILES("string.h" HAVE_STRING_H) +CHECK_INCLUDE_FILES("strings.h" HAVE_STRINGS_H) +CHECK_INCLUDE_FILES("sys/stat.h" HAVE_SYS_STAT_H) +CHECK_INCLUDE_FILES("sys/time.h" HAVE_SYS_TIME_H) +CHECK_INCLUDE_FILES("time.h" HAVE_TIME_H) +CHECK_INCLUDE_FILES("sys/types.h" HAVE_SYS_TYPES_H) +CHECK_INCLUDE_FILES("unistd.h" HAVE_UNISTD_H) +CHECK_INCLUDE_FILES("windows.h" HAVE_WINDOWS_H) +CHECK_INCLUDE_FILES("strings.h" HAVE_STRINGS_H) +CHECK_INCLUDE_FILES("ieeefp.h" HAVE_IEEEFP_H) + +# wotsit ? +if( HAVE_TIME_H AND HAVE_SYS_TIME_H ) + set(TIME_WITH_SYS_TIME 1) +endif() +set(LZMA_SUPPORT 0) # ? +set(MDI_SUPPORT 1) # ? +set(STDC_HEADERS 1) # why not ? +set(DEFAULT_EXTRASAMPLE_AS_ALPHA 1) +set(CHECK_JPEG_YCBCR_SUBSAMPLING 1) +set(CCITT_SUPPORT 1) +set(DEFER_STRILE_LOAD 0) +set(HAVE_JBG_NEWLEN 0) # FIXME: jbigkit stuff +set(STRIPCHOP_DEFAULT "TIFF_STRIPCHOP") +set(STRIP_SIZE_DEFAULT 8192) +set(SUBIFD_SUPPORT 1) +set(THUNDER_SUPPORT 1) + +CHECK_FUNCTION_EXISTS(getopt HAVE_GETOPT) +CHECK_FUNCTION_EXISTS(isascii HAVE_ISASCII) +CHECK_FUNCTION_EXISTS(memmove HAVE_MEMMOVE) +CHECK_FUNCTION_EXISTS(memset HAVE_MEMSET) +CHECK_FUNCTION_EXISTS(mmap HAVE_MMAP) +CHECK_FUNCTION_EXISTS(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(strtoul HAVE_STRTOUL) +CHECK_FUNCTION_EXISTS(strtoull HAVE_STRTOULL) + +include(CheckTypeSize) + +CHECK_TYPE_SIZE("signed int" SIZEOF_SIGNED_INT) +CHECK_TYPE_SIZE("signed long" SIZEOF_SIGNED_LONG) +CHECK_TYPE_SIZE("signed long long" SIZEOF_SIGNED_LONG_LONG) +CHECK_TYPE_SIZE("signed short" SIZEOF_SIGNED_SHORT) +CHECK_TYPE_SIZE("unsigned int" SIZEOF_UNSIGNED_INT) +CHECK_TYPE_SIZE("unsigned long" SIZEOF_UNSIGNED_LONG) +CHECK_TYPE_SIZE("unsigned long long" SIZEOF_UNSIGNED_LONG_LONG) +CHECK_TYPE_SIZE("unsigned short" SIZEOF_UNSIGNED_SHORT) +CHECK_TYPE_SIZE("unsigned char*" SIZEOF_UNSIGNED_CHAR_P) +# check platform has ssize_t: +CHECK_TYPE_SIZE(ssize_t SSIZE_T) + +if(HAVE_STDINT_H) + set(TIFF_INT8_T int8_t) + set(TIFF_INT16_T int16_t) + set(TIFF_INT32_T int32_t) + set(TIFF_INT64_T int64_t) + set(TIFF_UINT8_T uint8_t) + set(TIFF_UINT16_T uint16_t) + set(TIFF_UINT32_T uint32_t) + set(TIFF_UINT64_T uint64_t) + set(TIFF_PTRDIFF_T ptrdiff_t) + if(NOT HAVE_SSIZE_T) + if("${CMAKE_SIZEOF_VOID_P}" EQUAL 8) + set(TIFF_SSIZE_T int64_t) + elseif("${CMAKE_SIZEOF_VOID_P}" EQUAL 4) + set(TIFF_SSIZE_T int32_t) + else() + message(FATAL_ERROR "unknown ssize_t") + endif() + else() + set(TIFF_SSIZE_T ssize_t) + endif() + set(TIFF_INT32_FORMAT "\"%d\"") + set(TIFF_UINT32_FORMAT "\"%u\"") + set(TIFF_INT64_FORMAT "\"%ld\"") + set(TIFF_UINT64_FORMAT "\"%lu\"") + set(TIFF_PTRDIFF_FORMAT "\"%ld\"") + set(TIFF_SSIZE_FORMAT "\"%ld\"") +else() + set(TIFF_INT8_T "signed __int8") + set(TIFF_INT16_T "signed __int16") + set(TIFF_INT32_T "signed __int32") + set(TIFF_INT64_T "signed __int64") + set(TIFF_UINT8_T "unsigned __int8") + set(TIFF_UINT16_T "unsigned __int16") + set(TIFF_UINT32_T "unsigned __int32") + set(TIFF_UINT64_T "unsigned __int64") + set(TIFF_PTRDIFF_T ptrdiff_t) + if(NOT HAVE_SSIZE_T) + if("${CMAKE_SIZEOF_VOID_P}" EQUAL 8) + set(TIFF_SSIZE_T "signed __int64") + elseif("${CMAKE_SIZEOF_VOID_P}" EQUAL 4) + set(TIFF_SSIZE_T "signed __int32") + else() + message(FATAL_ERROR "unknown ssize_t") + endif() + else() + set(TIFF_SSIZE_T ssize_t) + endif() + set(TIFF_INT32_FORMAT "\"%d\"") + set(TIFF_UINT32_FORMAT "\"%u\"") + set(TIFF_INT64_FORMAT "\"%ld\"") + set(TIFF_UINT64_FORMAT "\"%lu\"") + set(TIFF_PTRDIFF_FORMAT "\"%ld\"") + set(TIFF_SSIZE_FORMAT "\"%ld\"") +endif() + +# +set(VERSION "\"4.0.1\"") +set(PACKAGE_VERSION ${VERSION}) +set(PACKAGE "\"tiff\"") + +# universal build ? +if(APPLE) + set(AC_APPLE_UNIVERSAL_BUILD 1) +endif() +if(UNIX) + set(CMAKE_REQUIRED_LIBRARIES m) + set(HAVE_LIBM 1) +endif() +CHECK_SYMBOL_EXISTS(floor "math.h" HAVE_FLOOR) +CHECK_SYMBOL_EXISTS(sqrt "math.h" HAVE_SQRT) +CHECK_SYMBOL_EXISTS(pow "math.h" HAVE_POW) +CHECK_SYMBOL_EXISTS(lfind "search.h" HAVE_LFIND) +CHECK_SYMBOL_EXISTS(setmod "io.h" HAVE_SETMODE) + +# http://www.cmake.org/pipermail/cmake/2007-September/016285.html +FOREACH(KEYWORD "inline" "__inline__" "__inline") + IF(NOT DEFINED C_INLINE) + TRY_COMPILE(C_HAS_${KEYWORD} "${CMAKE_CURRENT_BINARY_DIR}" + "${CMAKE_CURRENT_SOURCE_DIR}/test_inline.c" + COMPILE_DEFINITIONS "-Dinline=${KEYWORD}") + IF(C_HAS_${KEYWORD}) + SET(C_INLINE TRUE) + SET(INLINE "${KEYWORD}") + ENDIF(C_HAS_${KEYWORD}) + ENDIF(NOT DEFINED C_INLINE) +ENDFOREACH(KEYWORD) + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tiffconf.h.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/tiffconf.h @ONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tif_config.h.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/tif_config.h @ONLY) SET(LIBTARGET "tiff") # ADD_LIBRARY(${LIBTARGET} STATIC ${TARGET_FILES}) # -IF(MSVC) - SET_TARGET_PROPERTIES(${LIBTARGET} PROPERTIES PREFIX "lib") -ENDIF(MSVC) -# SET_TARGET_PROPERTIES(${LIBTARGET} PROPERTIES OUTPUT_NAME "${LIBTARGET}" ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/thirdparty/lib ) -# diff --git a/thirdparty/libtiff/libtiff.def b/thirdparty/libtiff/libtiff.def new file mode 100644 index 00000000..98228f1b --- /dev/null +++ b/thirdparty/libtiff/libtiff.def @@ -0,0 +1,164 @@ +EXPORTS TIFFAccessTagMethods + TIFFCIELabToRGBInit + TIFFCIELabToXYZ + TIFFCheckTile + TIFFCheckpointDirectory + TIFFCleanup + TIFFClientOpen + TIFFClientdata + TIFFClose + TIFFComputeStrip + TIFFComputeTile + TIFFCreateCustomDirectory + TIFFCreateDirectory + TIFFCreateEXIFDirectory + TIFFCurrentDirOffset + TIFFCurrentDirectory + TIFFCurrentRow + TIFFCurrentStrip + TIFFCurrentTile + TIFFDataWidth + TIFFDefaultStripSize + TIFFDefaultTileSize + TIFFError + TIFFErrorExt + TIFFFdOpen + TIFFFieldDataType + TIFFFieldName + TIFFFieldPassCount + TIFFFieldReadCount + TIFFFieldTag + TIFFFieldWithName + TIFFFieldWithTag + TIFFFieldWriteCount + TIFFFileName + TIFFFileno + TIFFFindCODEC + TIFFFindField + TIFFFlush + TIFFFlushData + TIFFFreeDirectory + TIFFGetBitRevTable + TIFFGetClientInfo + TIFFGetCloseProc + TIFFGetConfiguredCODECs + TIFFGetField + TIFFGetFieldDefaulted + TIFFGetMapFileProc + TIFFGetMode + TIFFGetReadProc + TIFFGetSeekProc + TIFFGetSizeProc + TIFFGetTagListCount + TIFFGetTagListEntry + TIFFGetUnmapFileProc + TIFFGetVersion + TIFFGetWriteProc + TIFFIsBigEndian + TIFFIsByteSwapped + TIFFIsCODECConfigured + TIFFIsMSB2LSB + TIFFIsTiled + TIFFIsUpSampled + TIFFLastDirectory + TIFFMergeFieldInfo + TIFFNumberOfDirectories + TIFFNumberOfStrips + TIFFNumberOfTiles + TIFFOpen + TIFFOpenW + TIFFPrintDirectory + TIFFRGBAImageBegin + TIFFRGBAImageEnd + TIFFRGBAImageGet + TIFFRGBAImageOK + TIFFRasterScanlineSize + TIFFRasterScanlineSize64 + TIFFRawStripSize + TIFFRawStripSize64 + TIFFReadBufferSetup + TIFFReadCustomDirectory + TIFFReadDirectory + TIFFReadEXIFDirectory + TIFFReadEncodedStrip + TIFFReadEncodedTile + TIFFReadRGBAImage + TIFFReadRGBAImageOriented + TIFFReadRGBAStrip + TIFFReadRGBATile + TIFFReadRawStrip + TIFFReadRawTile + TIFFReadScanline + TIFFReadTile + TIFFRegisterCODEC + TIFFReverseBits + TIFFRewriteDirectory + TIFFScanlineSize + TIFFScanlineSize64 + TIFFSetClientInfo + TIFFSetClientdata + TIFFSetCompressionScheme + TIFFSetDirectory + TIFFSetErrorHandler + TIFFSetErrorHandlerExt + TIFFSetField + TIFFSetFileName + TIFFSetFileno + TIFFSetMode + TIFFSetSubDirectory + TIFFSetTagExtender + TIFFSetWarningHandler + TIFFSetWarningHandlerExt + TIFFSetWriteOffset + TIFFSetupStrips + TIFFStripSize + TIFFStripSize64 + TIFFSwabArrayOfDouble + TIFFSwabArrayOfFloat + TIFFSwabArrayOfLong + TIFFSwabArrayOfLong8 + TIFFSwabArrayOfShort + TIFFSwabArrayOfTriples + TIFFSwabDouble + TIFFSwabFloat + TIFFSwabLong + TIFFSwabLong8 + TIFFSwabShort + TIFFTileRowSize + TIFFTileRowSize64 + TIFFTileSize + TIFFTileSize64 + TIFFUnRegisterCODEC + TIFFUnlinkDirectory + TIFFUnsetField + TIFFVGetField + TIFFVGetFieldDefaulted + TIFFVSetField + TIFFVStripSize + TIFFVStripSize64 + TIFFVTileSize + TIFFVTileSize64 + TIFFWarning + TIFFWarningExt + TIFFWriteBufferSetup + TIFFWriteCheck + TIFFWriteCustomDirectory + TIFFWriteDirectory + TIFFWriteEncodedStrip + TIFFWriteEncodedTile + TIFFWriteRawStrip + TIFFWriteRawTile + TIFFWriteScanline + TIFFWriteTile + TIFFXYZToRGB + TIFFYCbCrToRGBInit + TIFFYCbCrtoRGB + _TIFFCheckMalloc + _TIFFCheckRealloc + _TIFFRewriteField + _TIFFfree + _TIFFmalloc + _TIFFmemcmp + _TIFFmemcpy + _TIFFmemset + _TIFFrealloc diff --git a/thirdparty/libtiff/t4.h b/thirdparty/libtiff/t4.h index 870704ff..b908f54f 100644 --- a/thirdparty/libtiff/t4.h +++ b/thirdparty/libtiff/t4.h @@ -1,26 +1,26 @@ -/* $Id: t4.h,v 1.1.1.1.2.1 2010-06-08 18:50:41 bfriesen Exp $ */ +/* $Id: t4.h,v 1.3 2010-03-10 18:56:48 bfriesen Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -33,18 +33,18 @@ * worthwhile to make code & length 8 bits. */ typedef struct tableentry { - unsigned short length; /* bit length of g3 code */ - unsigned short code; /* g3 code */ - short runlen; /* run length in bits */ + unsigned short length; /* bit length of g3 code */ + unsigned short code; /* g3 code */ + short runlen; /* run length in bits */ } tableentry; -#define EOL 0x001 /* EOL code value - 0000 0000 0000 1 */ +#define EOL 0x001 /* EOL code value - 0000 0000 0000 1 */ /* status values returned instead of a run length */ -#define G3CODE_EOL -1 /* NB: ACT_EOL - ACT_WRUNT */ -#define G3CODE_INVALID -2 /* NB: ACT_INVALID - ACT_WRUNT */ -#define G3CODE_EOF -3 /* end of input data */ -#define G3CODE_INCOMP -4 /* incomplete run code */ +#define G3CODE_EOL -1 /* NB: ACT_EOL - ACT_WRUNT */ +#define G3CODE_INVALID -2 /* NB: ACT_INVALID - ACT_WRUNT */ +#define G3CODE_EOF -3 /* end of input data */ +#define G3CODE_INCOMP -4 /* incomplete run code */ /* * Note that these tables are ordered such that the @@ -279,8 +279,8 @@ const tableentry TIFFFaxBlackCodes[] = { { 12, 0x0, G3CODE_INVALID }, /* 0000 0000 0000 */ }; #else -extern const tableentry TIFFFaxWhiteCodes[]; -extern const tableentry TIFFFaxBlackCodes[]; +extern const tableentry TIFFFaxWhiteCodes[]; +extern const tableentry TIFFFaxBlackCodes[]; #endif #endif /* _T4_ */ /* diff --git a/thirdparty/libtiff/test_inline.c b/thirdparty/libtiff/test_inline.c new file mode 100644 index 00000000..db0d056c --- /dev/null +++ b/thirdparty/libtiff/test_inline.c @@ -0,0 +1,5 @@ +/* Test source lifted from /usr/share/autoconf/autoconf/c.m4 */ +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;} diff --git a/thirdparty/libtiff/tif_apple.c b/thirdparty/libtiff/tif_apple.c deleted file mode 100644 index 8c482288..00000000 --- a/thirdparty/libtiff/tif_apple.c +++ /dev/null @@ -1,281 +0,0 @@ -/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/Attic/tif_apple.c,v 1.3.2.1 2010-06-08 18:50:41 bfriesen Exp $ */ - -/* - * Copyright (c) 1988-1997 Sam Leffler - * Copyright (c) 1991-1997 Silicon Graphics, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that (i) the above copyright notices and this permission notice appear in - * all copies of the software and related documentation, and (ii) the names of - * Sam Leffler and Silicon Graphics may not be used in any advertising or - * publicity relating to the software without the specific, prior written - * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR - * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, - * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* - * TIFF Library Macintosh-specific routines. - * - * These routines use only Toolbox and high-level File Manager traps. - * They make no calls to the THINK C "unix" compatibility library. Also, - * malloc is not used directly but it is still referenced internally by - * the ANSI library in rare cases. Heap fragmentation by the malloc ring - * buffer is therefore minimized. - * - * O_RDONLY and O_RDWR are treated identically here. The tif_mode flag is - * checked in TIFFWriteCheck(). - * - * Create below fills in a blank creator signature and sets the file type - * to 'TIFF'. It is much better for the application to do this by Create'ing - * the file first and TIFFOpen'ing it later. - * --------- - * This code has been "Carbonized", and may not work with older MacOS versions. - * If so, grab the tif_apple.c out of an older libtiff distribution, like - * 3.5.5 from www.libtiff.org. - */ - -#include "tiffiop.h" -#include -#include -#include -#include - -#if defined(__PPCC__) || defined(__SC__) || defined(__MRC__) || defined(applec) -#define CtoPstr c2pstr -#endif - -static tsize_t -_tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size) -{ - return (FSRead((short) fd, (long*) &size, (char*) buf) == noErr ? - size : (tsize_t) -1); -} - -static tsize_t -_tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size) -{ - return (FSWrite((short) fd, (long*) &size, (char*) buf) == noErr ? - size : (tsize_t) -1); -} - -static toff_t -_tiffSeekProc(thandle_t fd, toff_t off, int whence) -{ - long fpos, size; - - if (GetEOF((short) fd, &size) != noErr) - return EOF; - (void) GetFPos((short) fd, &fpos); - - switch (whence) { - case SEEK_CUR: - if (off + fpos > size) - SetEOF((short) fd, off + fpos); - if (SetFPos((short) fd, fsFromMark, off) != noErr) - return EOF; - break; - case SEEK_END: - if (off > 0) - SetEOF((short) fd, off + size); - if (SetFPos((short) fd, fsFromStart, off + size) != noErr) - return EOF; - break; - case SEEK_SET: - if (off > size) - SetEOF((short) fd, off); - if (SetFPos((short) fd, fsFromStart, off) != noErr) - return EOF; - break; - } - - return (toff_t)(GetFPos((short) fd, &fpos) == noErr ? fpos : EOF); -} - -static int -_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) -{ - return (0); -} - -static void -_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size) -{ -} - -static int -_tiffCloseProc(thandle_t fd) -{ - return (FSClose((short) fd)); -} - -static toff_t -_tiffSizeProc(thandle_t fd) -{ - long size; - - if (GetEOF((short) fd, &size) != noErr) { - TIFFErrorExt(fd, "_tiffSizeProc", "%s: Cannot get file size"); - return (-1L); - } - return ((toff_t) size); -} - -/* - * Open a TIFF file descriptor for read/writing. - */ -TIFF* -TIFFFdOpen(int fd, const char* name, const char* mode) -{ - TIFF* tif; - - tif = TIFFClientOpen(name, mode, (thandle_t) fd, - _tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc, - _tiffSizeProc, _tiffMapProc, _tiffUnmapProc); - if (tif) - tif->tif_fd = fd; - return (tif); -} - -static void ourc2pstr( char* inString ) -{ - int sLen = strlen( inString ); - BlockMoveData( inString, &inString[1], sLen ); - inString[0] = sLen; -} - -/* - * Open a TIFF file for read/writing. - */ -TIFF* -TIFFOpen(const char* name, const char* mode) -{ - static const char module[] = "TIFFOpen"; - Str255 pname; - FInfo finfo; - short fref; - OSErr err; - FSSpec fSpec; - - strcpy((char*) pname, name); - ourc2pstr((char*) pname); - - err = FSMakeFSSpec( 0, 0, pname, &fSpec ); - - switch (_TIFFgetMode(mode, module)) { - default: - return ((TIFF*) 0); - case O_RDWR | O_CREAT | O_TRUNC: - if (FSpGetFInfo(&fSpec, &finfo) == noErr) - FSpDelete(&fSpec); - /* fall through */ - case O_RDWR | O_CREAT: - if ((err = FSpGetFInfo(&fSpec, &finfo)) == fnfErr) { - if (FSpCreate(&fSpec, ' ', 'TIFF', smSystemScript) != noErr) - goto badCreate; - if (FSpOpenDF(&fSpec, fsRdWrPerm, &fref) != noErr) - goto badOpen; - } else if (err == noErr) { - if (FSpOpenDF(&fSpec, fsRdWrPerm, &fref) != noErr) - goto badOpen; - } else - goto badOpen; - break; - case O_RDONLY: - if (FSpOpenDF(&fSpec, fsRdPerm, &fref) != noErr) - goto badOpen; - break; - case O_RDWR: - if (FSpOpenDF(&fSpec, fsRdWrPerm, &fref) != noErr) - goto badOpen; - break; - } - return (TIFFFdOpen((int) fref, name, mode)); -badCreate: - TIFFErrorExt(0, module, "%s: Cannot create", name); - return ((TIFF*) 0); -badOpen: - TIFFErrorExt(0, module, "%s: Cannot open", name); - return ((TIFF*) 0); -} - -void -_TIFFmemset(tdata_t p, int v, tsize_t c) -{ - memset(p, v, (size_t) c); -} - -void -_TIFFmemcpy(tdata_t d, const tdata_t s, tsize_t c) -{ - memcpy(d, s, (size_t) c); -} - -int -_TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c) -{ - return (memcmp(p1, p2, (size_t) c)); -} - -tdata_t -_TIFFmalloc(tsize_t s) -{ - return (NewPtr((size_t) s)); -} - -void -_TIFFfree(tdata_t p) -{ - DisposePtr(p); -} - -tdata_t -_TIFFrealloc(tdata_t p, tsize_t s) -{ - Ptr n = p; - - SetPtrSize(p, (size_t) s); - if (MemError() && (n = NewPtr((size_t) s)) != NULL) { - BlockMove(p, n, GetPtrSize(p)); - DisposePtr(p); - } - return ((tdata_t) n); -} - -static void -appleWarningHandler(const char* module, const char* fmt, va_list ap) -{ - if (module != NULL) - fprintf(stderr, "%s: ", module); - fprintf(stderr, "Warning, "); - vfprintf(stderr, fmt, ap); - fprintf(stderr, ".\n"); -} -TIFFErrorHandler _TIFFwarningHandler = appleWarningHandler; - -static void -appleErrorHandler(const char* module, const char* fmt, va_list ap) -{ - if (module != NULL) - fprintf(stderr, "%s: ", module); - vfprintf(stderr, fmt, ap); - fprintf(stderr, ".\n"); -} -TIFFErrorHandler _TIFFerrorHandler = appleErrorHandler; -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/thirdparty/libtiff/tif_aux.c b/thirdparty/libtiff/tif_aux.c index 272f0d9b..927150a4 100644 --- a/thirdparty/libtiff/tif_aux.c +++ b/thirdparty/libtiff/tif_aux.c @@ -1,4 +1,4 @@ -/* $Id: tif_aux.c,v 1.20.2.3 2010-06-09 21:15:27 bfriesen Exp $ */ +/* $Id: tif_aux.c,v 1.26 2010-07-01 15:33:28 dron Exp $ */ /* * Copyright (c) 1991-1997 Sam Leffler @@ -33,12 +33,38 @@ #include "tif_predict.h" #include -tdata_t -_TIFFCheckRealloc(TIFF* tif, tdata_t buffer, - size_t nmemb, size_t elem_size, const char* what) +uint32 +_TIFFMultiply32(TIFF* tif, uint32 first, uint32 second, const char* where) { - tdata_t cp = NULL; - tsize_t bytes = nmemb * elem_size; + uint32 bytes = first * second; + + if (second && bytes / second != first) { + TIFFErrorExt(tif->tif_clientdata, where, "Integer overflow in %s", where); + bytes = 0; + } + + return bytes; +} + +uint64 +_TIFFMultiply64(TIFF* tif, uint64 first, uint64 second, const char* where) +{ + uint64 bytes = first * second; + + if (second && bytes / second != first) { + TIFFErrorExt(tif->tif_clientdata, where, "Integer overflow in %s", where); + bytes = 0; + } + + return bytes; +} + +void* +_TIFFCheckRealloc(TIFF* tif, void* buffer, + tmsize_t nmemb, tmsize_t elem_size, const char* what) +{ + void* cp = NULL; + tmsize_t bytes = nmemb * elem_size; /* * XXX: Check for integer overflow. @@ -46,32 +72,33 @@ _TIFFCheckRealloc(TIFF* tif, tdata_t buffer, if (nmemb && elem_size && bytes / elem_size == nmemb) cp = _TIFFrealloc(buffer, bytes); - if (cp == NULL) + if (cp == NULL) { TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Failed to allocate memory for %s " "(%ld elements of %ld bytes each)", what,(long) nmemb, (long) elem_size); + } return cp; } -tdata_t -_TIFFCheckMalloc(TIFF* tif, size_t nmemb, size_t elem_size, const char* what) +void* +_TIFFCheckMalloc(TIFF* tif, tmsize_t nmemb, tmsize_t elem_size, const char* what) { - return _TIFFCheckRealloc(tif, NULL, nmemb, elem_size, what); + return _TIFFCheckRealloc(tif, NULL, nmemb, elem_size, what); } static int TIFFDefaultTransferFunction(TIFFDirectory* td) { uint16 **tf = td->td_transferfunction; - tsize_t i, n, nbytes; + tmsize_t i, n, nbytes; tf[0] = tf[1] = tf[2] = 0; - if (td->td_bitspersample >= sizeof(tsize_t) * 8 - 2) + if (td->td_bitspersample >= sizeof(tmsize_t) * 8 - 2) return 0; - n = 1<td_bitspersample; + n = ((tmsize_t)1)<td_bitspersample; nbytes = n * sizeof (uint16); if (!(tf[0] = (uint16 *)_TIFFmalloc(nbytes))) return 0; @@ -140,7 +167,7 @@ TIFFDefaultRefBlackWhite(TIFFDirectory* td) * place in the library -- in TIFFDefaultDirectory. */ int -TIFFVGetFieldDefaulted(TIFF* tif, ttag_t tag, va_list ap) +TIFFVGetFieldDefaulted(TIFF* tif, uint32 tag, va_list ap) { TIFFDirectory *td = &tif->tif_dir; @@ -269,7 +296,7 @@ TIFFVGetFieldDefaulted(TIFF* tif, ttag_t tag, va_list ap) * value if the tag is not present in the directory. */ int -TIFFGetFieldDefaulted(TIFF* tif, ttag_t tag, ...) +TIFFGetFieldDefaulted(TIFF* tif, uint32 tag, ...) { int ok; va_list ap; @@ -280,6 +307,47 @@ TIFFGetFieldDefaulted(TIFF* tif, ttag_t tag, ...) return (ok); } +struct _Int64Parts { + int32 low, high; +}; + +typedef union { + struct _Int64Parts part; + int64 value; +} _Int64; + +float +_TIFFUInt64ToFloat(uint64 ui64) +{ + _Int64 i; + + i.value = ui64; + if (i.part.high >= 0) { + return (float)i.value; + } else { + long double df; + df = (long double)i.value; + df += 18446744073709551616.0; /* adding 2**64 */ + return (float)df; + } +} + +double +_TIFFUInt64ToDouble(uint64 ui64) +{ + _Int64 i; + + i.value = ui64; + if (i.part.high >= 0) { + return (double)i.value; + } else { + long double df; + df = (long double)i.value; + df += 18446744073709551616.0; /* adding 2**64 */ + return (double)df; + } +} + /* vim: set ts=8 sts=8 sw=8 noet: */ /* * Local Variables: diff --git a/thirdparty/libtiff/tif_close.c b/thirdparty/libtiff/tif_close.c index 02591ba9..13d2bab5 100644 --- a/thirdparty/libtiff/tif_close.c +++ b/thirdparty/libtiff/tif_close.c @@ -1,4 +1,4 @@ -/* $Id: tif_close.c,v 1.10.2.1 2010-06-08 18:50:41 bfriesen Exp $ */ +/* $Id: tif_close.c,v 1.19 2010-03-10 18:56:48 bfriesen Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -28,6 +28,7 @@ * TIFF Library. */ #include "tiffiop.h" +#include /************************************************************************/ /* TIFFCleanup() */ @@ -45,18 +46,20 @@ void TIFFCleanup(TIFF* tif) { + /* + * Flush buffered data and directory (if dirty). + */ if (tif->tif_mode != O_RDONLY) - /* - * Flush buffered data and directory (if dirty). - */ - TIFFFlush(tif); + TIFFFlush(tif); (*tif->tif_cleanup)(tif); TIFFFreeDirectory(tif); if (tif->tif_dirlist) _TIFFfree(tif->tif_dirlist); - /* Clean up client info links */ + /* + * Clean up client info links. + */ while( tif->tif_clientinfo ) { TIFFClientInfoLink *link = tif->tif_clientinfo; @@ -69,27 +72,36 @@ TIFFCleanup(TIFF* tif) if (tif->tif_rawdata && (tif->tif_flags&TIFF_MYBUFFER)) _TIFFfree(tif->tif_rawdata); if (isMapped(tif)) - TIFFUnmapFileContents(tif, tif->tif_base, tif->tif_size); + TIFFUnmapFileContents(tif, tif->tif_base, (toff_t)tif->tif_size); - /* Clean up custom fields */ - if (tif->tif_nfields > 0) - { - size_t i; + /* + * Clean up custom fields. + */ + if (tif->tif_fields && tif->tif_nfields > 0) { + uint32 i; - for (i = 0; i < tif->tif_nfields; i++) - { - TIFFFieldInfo *fld = tif->tif_fieldinfo[i]; - if (fld->field_bit == FIELD_CUSTOM && - strncmp("Tag ", fld->field_name, 4) == 0) - { - _TIFFfree(fld->field_name); - _TIFFfree(fld); + for (i = 0; i < tif->tif_nfields; i++) { + TIFFField *fld = tif->tif_fields[i]; + if (fld->field_bit == FIELD_CUSTOM && + strncmp("Tag ", fld->field_name, 4) == 0) { + _TIFFfree(fld->field_name); + _TIFFfree(fld); + } } - } - - _TIFFfree(tif->tif_fieldinfo); + + _TIFFfree(tif->tif_fields); } + 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); + } + _TIFFfree(tif); } @@ -117,6 +129,8 @@ TIFFClose(TIFF* tif) (void) (*closeproc)(fd); } +/* vim: set ts=8 sts=8 sw=8 noet: */ + /* * Local Variables: * mode: c diff --git a/thirdparty/libtiff/tif_codec.c b/thirdparty/libtiff/tif_codec.c index d5c6fd11..703e87d5 100644 --- a/thirdparty/libtiff/tif_codec.c +++ b/thirdparty/libtiff/tif_codec.c @@ -1,4 +1,4 @@ -/* $Id: tif_codec.c,v 1.10.2.2 2010-06-08 18:50:41 bfriesen Exp $ */ +/* $Id: tif_codec.c,v 1.16 2013-05-02 14:44:29 tgl Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -31,43 +31,46 @@ */ #include "tiffiop.h" -static int NotConfigured(TIFF*, int); +static int NotConfigured(TIFF*, int); -#ifndef LZW_SUPPORT -#define TIFFInitLZW NotConfigured +#ifndef LZW_SUPPORT +#define TIFFInitLZW NotConfigured #endif -#ifndef PACKBITS_SUPPORT -#define TIFFInitPackBits NotConfigured +#ifndef PACKBITS_SUPPORT +#define TIFFInitPackBits NotConfigured #endif -#ifndef THUNDER_SUPPORT -#define TIFFInitThunderScan NotConfigured +#ifndef THUNDER_SUPPORT +#define TIFFInitThunderScan NotConfigured #endif -#ifndef NEXT_SUPPORT -#define TIFFInitNeXT NotConfigured +#ifndef NEXT_SUPPORT +#define TIFFInitNeXT NotConfigured #endif -#ifndef JPEG_SUPPORT -#define TIFFInitJPEG NotConfigured +#ifndef JPEG_SUPPORT +#define TIFFInitJPEG NotConfigured #endif -#ifndef OJPEG_SUPPORT -#define TIFFInitOJPEG NotConfigured +#ifndef OJPEG_SUPPORT +#define TIFFInitOJPEG NotConfigured #endif -#ifndef CCITT_SUPPORT -#define TIFFInitCCITTRLE NotConfigured -#define TIFFInitCCITTRLEW NotConfigured -#define TIFFInitCCITTFax3 NotConfigured -#define TIFFInitCCITTFax4 NotConfigured +#ifndef CCITT_SUPPORT +#define TIFFInitCCITTRLE NotConfigured +#define TIFFInitCCITTRLEW NotConfigured +#define TIFFInitCCITTFax3 NotConfigured +#define TIFFInitCCITTFax4 NotConfigured #endif #ifndef JBIG_SUPPORT -#define TIFFInitJBIG NotConfigured +#define TIFFInitJBIG NotConfigured #endif -#ifndef ZIP_SUPPORT -#define TIFFInitZIP NotConfigured +#ifndef ZIP_SUPPORT +#define TIFFInitZIP NotConfigured #endif -#ifndef PIXARLOG_SUPPORT -#define TIFFInitPixarLog NotConfigured +#ifndef PIXARLOG_SUPPORT +#define TIFFInitPixarLog NotConfigured #endif #ifndef LOGLUV_SUPPORT -#define TIFFInitSGILog NotConfigured +#define TIFFInitSGILog NotConfigured +#endif +#ifndef LZMA_SUPPORT +#define TIFFInitLZMA NotConfigured #endif /* @@ -95,6 +98,7 @@ TIFFCodec _TIFFBuiltinCODECS[] = { { "PixarLog", COMPRESSION_PIXARLOG, TIFFInitPixarLog }, { "SGILog", COMPRESSION_SGILOG, TIFFInitSGILog }, { "SGILog24", COMPRESSION_SGILOG24, TIFFInitSGILog }, + { "LZMA", COMPRESSION_LZMA, TIFFInitLZMA }, { NULL, 0, NULL } }; @@ -104,7 +108,8 @@ _notConfigured(TIFF* tif) const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression); char compression_code[20]; - sprintf( compression_code, "%d", tif->tif_dir.td_compression ); + snprintf(compression_code, sizeof(compression_code), "%d", + tif->tif_dir.td_compression ); TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "%s compression support is not configured", c ? c->name : compression_code ); @@ -114,13 +119,14 @@ _notConfigured(TIFF* tif) static int NotConfigured(TIFF* tif, int scheme) { - (void) scheme; - - tif->tif_decodestatus = FALSE; - tif->tif_setupdecode = _notConfigured; - tif->tif_encodestatus = FALSE; - tif->tif_setupencode = _notConfigured; - return (1); + (void) scheme; + + tif->tif_fixuptags = _notConfigured; + tif->tif_decodestatus = FALSE; + tif->tif_setupdecode = _notConfigured; + tif->tif_encodestatus = FALSE; + tif->tif_setupencode = _notConfigured; + return (1); } /************************************************************************/ @@ -129,7 +135,7 @@ NotConfigured(TIFF* tif, int scheme) /** * Check whether we have working codec for the specific coding scheme. - * + * * @return returns 1 if the codec is configured and working. Otherwise * 0 will be returned. */ @@ -140,14 +146,14 @@ TIFFIsCODECConfigured(uint16 scheme) const TIFFCodec* codec = TIFFFindCODEC(scheme); if(codec == NULL) { - return 0; - } - if(codec->init == NULL) { - return 0; - } + return 0; + } + if(codec->init == NULL) { + return 0; + } if(codec->init != NotConfigured){ - return 1; - } + return 1; + } return 0; } diff --git a/thirdparty/libtiff/tif_color.c b/thirdparty/libtiff/tif_color.c index 02eb346b..be4850ce 100644 --- a/thirdparty/libtiff/tif_color.c +++ b/thirdparty/libtiff/tif_color.c @@ -1,4 +1,4 @@ -/* $Id: tif_color.c,v 1.12.2.1 2010-06-08 18:50:41 bfriesen Exp $ */ +/* $Id: tif_color.c,v 1.19 2010-12-14 02:22:42 faxguy Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -123,7 +123,7 @@ TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z, */ int TIFFCIELabToRGBInit(TIFFCIELabToRGB* cielab, - TIFFDisplay *display, float *refWhite) + const TIFFDisplay *display, float *refWhite) { int i; double gamma; @@ -183,13 +183,18 @@ void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32 Y, int32 Cb, int32 Cr, uint32 *r, uint32 *g, uint32 *b) { + 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); - *r = ycbcr->clamptab[ycbcr->Y_tab[Y] + ycbcr->Cr_r_tab[Cr]]; - *g = ycbcr->clamptab[ycbcr->Y_tab[Y] - + (int)((ycbcr->Cb_g_tab[Cb] + ycbcr->Cr_g_tab[Cr]) >> SHIFT)]; - *b = ycbcr->clamptab[ycbcr->Y_tab[Y] + ycbcr->Cb_b_tab[Cb]]; + i = ycbcr->Y_tab[Y] + ycbcr->Cr_r_tab[Cr]; + *r = CLAMP(i, 0, 255); + i = ycbcr->Y_tab[Y] + + (int)((ycbcr->Cb_g_tab[Cb] + ycbcr->Cr_g_tab[Cr]) >> SHIFT); + *g = CLAMP(i, 0, 255); + i = ycbcr->Y_tab[Y] + ycbcr->Cb_b_tab[Cb]; + *b = CLAMP(i, 0, 255); } /* @@ -219,7 +224,7 @@ TIFFYCbCrToRGBInit(TIFFYCbCrToRGB* ycbcr, float *luma, float *refBlackWhite) #define LumaBlue luma[2] clamptab = (TIFFRGBValue*)( - (tidata_t) ycbcr+TIFFroundup(sizeof (TIFFYCbCrToRGB), sizeof (long))); + (uint8*) ycbcr+TIFFroundup_32(sizeof (TIFFYCbCrToRGB), sizeof (long))); _TIFFmemset(clamptab, 0, 256); /* v < 0 => 0 */ ycbcr->clamptab = (clamptab += 256); for (i = 0; i < 256; i++) diff --git a/thirdparty/libtiff/tif_compress.c b/thirdparty/libtiff/tif_compress.c index 0ce509b0..20e72fd0 100644 --- a/thirdparty/libtiff/tif_compress.c +++ b/thirdparty/libtiff/tif_compress.c @@ -1,4 +1,4 @@ -/* $Id: tif_compress.c,v 1.13.2.1 2010-06-08 18:50:41 bfriesen Exp $ */ +/* $Id: tif_compress.c,v 1.22 2010-03-10 18:56:48 bfriesen Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -36,11 +36,11 @@ TIFFNoEncode(TIFF* tif, const char* method) { const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression); - if (c) { + if (c) { TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "%s %s encoding is not implemented", c->name, method); - } else { + } else { TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Compression scheme %u %s encoding is not implemented", tif->tif_dir.td_compression, method); @@ -49,21 +49,21 @@ TIFFNoEncode(TIFF* tif, const char* method) } int -_TIFFNoRowEncode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s) +_TIFFNoRowEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) { (void) pp; (void) cc; (void) s; return (TIFFNoEncode(tif, "scanline")); } int -_TIFFNoStripEncode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s) +_TIFFNoStripEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) { (void) pp; (void) cc; (void) s; return (TIFFNoEncode(tif, "strip")); } int -_TIFFNoTileEncode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s) +_TIFFNoTileEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) { (void) pp; (void) cc; (void) s; return (TIFFNoEncode(tif, "tile")); @@ -86,21 +86,28 @@ TIFFNoDecode(TIFF* tif, const char* method) } int -_TIFFNoRowDecode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s) +_TIFFNoFixupTags(TIFF* tif) +{ + (void) tif; + return (1); +} + +int +_TIFFNoRowDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) { (void) pp; (void) cc; (void) s; return (TIFFNoDecode(tif, "scanline")); } int -_TIFFNoStripDecode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s) +_TIFFNoStripDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) { (void) pp; (void) cc; (void) s; return (TIFFNoDecode(tif, "strip")); } int -_TIFFNoTileDecode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s) +_TIFFNoTileDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) { (void) pp; (void) cc; (void) s; return (TIFFNoDecode(tif, "tile")); @@ -116,7 +123,7 @@ _TIFFNoSeek(TIFF* tif, uint32 off) } int -_TIFFNoPreCode(TIFF* tif, tsample_t s) +_TIFFNoPreCode(TIFF* tif, uint16 s) { (void) tif; (void) s; return (1); @@ -128,19 +135,20 @@ static void _TIFFvoid(TIFF* tif) { (void) tif; } void _TIFFSetDefaultCompressionState(TIFF* tif) { + tif->tif_fixuptags = _TIFFNoFixupTags; tif->tif_decodestatus = TRUE; tif->tif_setupdecode = _TIFFtrue; tif->tif_predecode = _TIFFNoPreCode; - tif->tif_decoderow = _TIFFNoRowDecode; + tif->tif_decoderow = _TIFFNoRowDecode; tif->tif_decodestrip = _TIFFNoStripDecode; - tif->tif_decodetile = _TIFFNoTileDecode; + tif->tif_decodetile = _TIFFNoTileDecode; tif->tif_encodestatus = TRUE; tif->tif_setupencode = _TIFFtrue; tif->tif_preencode = _TIFFNoPreCode; tif->tif_postencode = _TIFFtrue; tif->tif_encoderow = _TIFFNoRowEncode; - tif->tif_encodestrip = _TIFFNoStripEncode; - tif->tif_encodetile = _TIFFNoTileEncode; + tif->tif_encodestrip = _TIFFNoStripEncode; + tif->tif_encodetile = _TIFFNoTileEncode; tif->tif_close = _TIFFvoid; tif->tif_seek = _TIFFNoSeek; tif->tif_cleanup = _TIFFvoid; @@ -170,10 +178,10 @@ TIFFSetCompressionScheme(TIFF* tif, int scheme) * by this library. */ typedef struct _codec { - struct _codec* next; - TIFFCodec* info; + struct _codec* next; + TIFFCodec* info; } codec_t; -static codec_t* registeredCODECS = NULL; +static codec_t* registeredCODECS = NULL; const TIFFCodec* TIFFFindCODEC(uint16 scheme) @@ -194,12 +202,12 @@ TIFFCodec* TIFFRegisterCODEC(uint16 scheme, const char* name, TIFFInitMethod init) { codec_t* cd = (codec_t*) - _TIFFmalloc(sizeof (codec_t) + sizeof (TIFFCodec) + strlen(name)+1); + _TIFFmalloc((tmsize_t)(sizeof (codec_t) + sizeof (TIFFCodec) + strlen(name)+1)); if (cd != NULL) { - cd->info = (TIFFCodec*) ((tidata_t) cd + sizeof (codec_t)); + cd->info = (TIFFCodec*) ((uint8*) cd + sizeof (codec_t)); cd->info->name = (char*) - ((tidata_t) cd->info + sizeof (TIFFCodec)); + ((uint8*) cd->info + sizeof (TIFFCodec)); strcpy(cd->info->name, name); cd->info->scheme = scheme; cd->info->init = init; @@ -244,13 +252,14 @@ TIFFUnRegisterCODEC(TIFFCodec* c) TIFFCodec* TIFFGetConfiguredCODECs() { - int i = 1; - codec_t *cd; - const TIFFCodec *c; - TIFFCodec *codecs = NULL, *new_codecs; + int i = 1; + codec_t *cd; + const TIFFCodec* c; + TIFFCodec* codecs = NULL; + TIFFCodec* new_codecs; - for (cd = registeredCODECS; cd; cd = cd->next) { - new_codecs = (TIFFCodec *) + for (cd = registeredCODECS; cd; cd = cd->next) { + new_codecs = (TIFFCodec *) _TIFFrealloc(codecs, i * sizeof(TIFFCodec)); if (!new_codecs) { _TIFFfree (codecs); @@ -260,16 +269,16 @@ TIFFGetConfiguredCODECs() _TIFFmemcpy(codecs + i - 1, cd, sizeof(TIFFCodec)); i++; } - for (c = _TIFFBuiltinCODECS; c->name; c++) { - if (TIFFIsCODECConfigured(c->scheme)) { - new_codecs = (TIFFCodec *) + for (c = _TIFFBuiltinCODECS; c->name; c++) { + if (TIFFIsCODECConfigured(c->scheme)) { + new_codecs = (TIFFCodec *) _TIFFrealloc(codecs, i * sizeof(TIFFCodec)); if (!new_codecs) { _TIFFfree (codecs); return NULL; } codecs = new_codecs; - _TIFFmemcpy(codecs + i - 1, (const tdata_t)c, sizeof(TIFFCodec)); + _TIFFmemcpy(codecs + i - 1, (const void*)c, sizeof(TIFFCodec)); i++; } } @@ -282,7 +291,7 @@ TIFFGetConfiguredCODECs() codecs = new_codecs; _TIFFmemset(codecs + i - 1, 0, sizeof(TIFFCodec)); - return codecs; + return codecs; } /* vim: set ts=8 sts=8 sw=8 noet: */ diff --git a/thirdparty/libtiff/tif_config.h b/thirdparty/libtiff/tif_config.h deleted file mode 100644 index 08d1f0d0..00000000 --- a/thirdparty/libtiff/tif_config.h +++ /dev/null @@ -1,70 +0,0 @@ -/* Define to 1 if you have the header file. */ -#define HAVE_ASSERT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_FCNTL_H 1 - -/* 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 `jbg_newlen' function. */ -#define HAVE_JBG_NEWLEN 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_IO_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SEARCH_H 1 - -/* Define to 1 if you have the `setmode' function. */ -#define HAVE_SETMODE 1 - -/* The size of a `int', as computed by sizeof. */ -#define SIZEOF_INT 4 - -/* The size of a `long', as computed by sizeof. */ -#define SIZEOF_LONG 4 - - -#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 - -/* Set the native cpu bit order */ -#define HOST_FILLORDER FILLORDER_LSB2MSB - -/* Define to 1 if your processor stores words with the most significant byte - first (like Motorola and SPARC, unlike Intel and VAX). */ -/* #undef WORDS_BIGENDIAN */ - -/* 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 -# ifndef inline -# define inline __inline -# endif -#endif - -#define lfind _lfind -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/thirdparty/libtiff/tif_config.h.cmake.in b/thirdparty/libtiff/tif_config.h.cmake.in new file mode 100644 index 00000000..a556f3c4 --- /dev/null +++ b/thirdparty/libtiff/tif_config.h.cmake.in @@ -0,0 +1,398 @@ +/* libtiff/tif_config.h.in. Generated from configure.ac by autoheader. */ + +/* Define if building universal (internal helper macro) */ +#cmakedefine AC_APPLE_UNIVERSAL_BUILD + +/* Support CCITT Group 3 & 4 algorithms */ +#cmakedefine CCITT_SUPPORT @CCITT_SUPPORT@ + +/* Pick up YCbCr subsampling info from the JPEG data stream to support files + lacking the tag (default enabled). */ +#cmakedefine CHECK_JPEG_YCBCR_SUBSAMPLING @CHECK_JPEG_YCBCR_SUBSAMPLING@ + +/* enable partial strip reading for large strips (experimental) */ +#cmakedefine CHUNKY_STRIP_READ_SUPPORT + +/* Support C++ stream API (requires C++ compiler) */ +#cmakedefine CXX_SUPPORT @CXX_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. */ +#cmakedefine DEFAULT_EXTRASAMPLE_AS_ALPHA @DEFAULT_EXTRASAMPLE_AS_ALPHA@ + +/* enable deferred strip/tile offset/size loading (experimental) */ +#cmakedefine DEFER_STRILE_LOAD @DEFER_STRILE_LOAD@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ASSERT_H @HAVE_ASSERT_H@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_DLFCN_H @HAVE_DLFCN_H@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_FCNTL_H @HAVE_FCNTL_H@ + +/* Define to 1 if you have the `floor' function. */ +#cmakedefine HAVE_FLOOR @HAVE_FLOOR@ + +/* Define to 1 if you have the `getopt' function. */ +#cmakedefine HAVE_GETOPT @HAVE_GETOPT@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_GLUT_GLUT_H @HAVE_GLUT_GLUT_H@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_GL_GLUT_H @HAVE_GL_GLUT_H@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_GL_GLU_H @HAVE_GL_GLU_H@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_GL_GL_H @HAVE_GL_GL_H@ + +/* Define as 0 or 1 according to the floating point format suported by the + machine */ +#define HAVE_IEEEFP 1 + +/* Define to 1 if the system has the type `int16'. */ +#cmakedefine HAVE_INT16 + +/* Define to 1 if the system has the type `int32'. */ +#cmakedefine HAVE_INT32 + +/* Define to 1 if the system has the type `int8'. */ +#cmakedefine HAVE_INT8 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_INTTYPES_H @HAVE_INTTYPES_H@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_IO_H @HAVE_IO_H@ + +/* Define to 1 if you have the `isascii' function. */ +#cmakedefine HAVE_ISASCII @HAVE_ISASCII@ + +/* Define to 1 if you have the `jbg_newlen' function. */ +#cmakedefine HAVE_JBG_NEWLEN @HAVE_JBG_NEWLEN@ + +/* Define to 1 if you have the `lfind' function. */ +#cmakedefine HAVE_LFIND @HAVE_LFIND@ + +/* Define to 1 if you have the `c' library (-lc). */ +#cmakedefine HAVE_LIBC @HAVE_LIBC@ + +/* Define to 1 if you have the `m' library (-lm). */ +#cmakedefine HAVE_LIBM @HAVE_LIBM@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_LIMITS_H @HAVE_LIMITS_H@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_MALLOC_H @HAVE_MALLOC_H@ + +/* Define to 1 if you have the `memmove' function. */ +#cmakedefine HAVE_MEMMOVE @HAVE_MEMMOVE@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_MEMORY_H @HAVE_MEMORY_H@ + +/* Define to 1 if you have the `memset' function. */ +#cmakedefine HAVE_MEMSET @HAVE_MEMSET@ + +/* Define to 1 if you have the `mmap' function. */ +#cmakedefine HAVE_MMAP @HAVE_MMAP@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_OPENGL_GLU_H @HAVE_OPENGL_GLU_H@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_OPENGL_GL_H @HAVE_OPENGL_GL_H@ + +/* Define to 1 if you have the `pow' function. */ +#cmakedefine HAVE_POW @HAVE_POW@ + +/* Define if you have POSIX threads libraries and header files. */ +#cmakedefine HAVE_PTHREAD + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SEARCH_H @HAVE_SEARCH_H@ + +/* Define to 1 if you have the `setmode' function. */ +#cmakedefine HAVE_SETMODE @HAVE_SETMODE@ + +/* Define to 1 if you have the `sqrt' function. */ +#cmakedefine HAVE_SQRT @HAVE_SQRT@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDINT_H @HAVE_STDINT_H@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDLIB_H @HAVE_STDLIB_H@ + +/* Define to 1 if you have the `strcasecmp' function. */ +#cmakedefine HAVE_STRCASECMP @HAVE_STRCASECMP@ + +/* Define to 1 if you have the `strchr' function. */ +#cmakedefine HAVE_STRCHR @HAVE_STRCHR@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRINGS_H @HAVE_STRINGS_H@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRING_H @HAVE_STRING_H@ + +/* Define to 1 if you have the `strrchr' function. */ +#cmakedefine HAVE_STRRCHR @HAVE_STRRCHR@ + +/* Define to 1 if you have the `strstr' function. */ +#cmakedefine HAVE_STRSTR @HAVE_STRSTR@ + +/* Define to 1 if you have the `strtol' function. */ +#cmakedefine HAVE_STRTOL @HAVE_STRTOL@ + +/* Define to 1 if you have the `strtoul' function. */ +#cmakedefine HAVE_STRTOUL @HAVE_STRTOUL@ + +/* Define to 1 if you have the `strtoull' function. */ +#cmakedefine HAVE_STRTOULL @HAVE_STRTOULL@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_STAT_H @HAVE_SYS_STAT_H@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_TIME_H @HAVE_SYS_TIME_H@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_TYPES_H @HAVE_SYS_TYPES_H@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_UNISTD_H @HAVE_UNISTD_H@ + +/* Use nonstandard varargs form for the GLU tesselator callback */ +#cmakedefine HAVE_VARARGS_GLU_TESSCB + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_WINDOWS_H @HAVE_WINDOWS_H@ + +/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian + (Intel) */ +#define HOST_BIGENDIAN @HOST_BIGENDIAN@ + +/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */ +#cmakedefine HOST_FILLORDER @HOST_FILLORDER@ + +/* Support ISO JBIG compression (requires JBIG-KIT library) */ +#cmakedefine JBIG_SUPPORT + +/* 8/12 bit libjpeg dual mode enabled */ +#cmakedefine JPEG_DUAL_MODE_8_12 + +/* Support JPEG compression (requires IJG JPEG library) */ +#cmakedefine JPEG_SUPPORT @JPEG_SUPPORT@ + +/* 12bit libjpeg primary include file with path */ +#cmakedefine LIBJPEG_12_PATH + +/* Support LogLuv high dynamic range encoding */ +#define LOGLUV_SUPPORT 1 + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* Support LZMA2 compression */ +#cmakedefine LZMA_SUPPORT @LZMA_SUPPORT@ + +/* Support LZW algorithm */ +#define LZW_SUPPORT 1 + +/* Support Microsoft Document Imaging format */ +#cmakedefine MDI_SUPPORT @MDI_SUPPORT@ + +/* Support NeXT 2-bit RLE algorithm */ +#define NEXT_SUPPORT 1 + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +#cmakedefine NO_MINUS_C_MINUS_O @NO_MINUS_C_MINUS_O@ + +/* Support Old JPEG compresson (read-only) */ +#cmakedefine OJPEG_SUPPORT + +/* Name of package */ +#cmakedefine PACKAGE @PACKAGE@ + +/* Define to the address where bug reports for this package should be sent. */ +#cmakedefine PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#cmakedefine PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#cmakedefine PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#cmakedefine PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#cmakedefine PACKAGE_VERSION @PACKAGE_VERSION@ + +/* Support Macintosh PackBits algorithm */ +#define PACKBITS_SUPPORT 1 + +/* Support Pixar log-format algorithm (requires Zlib) */ +#cmakedefine PIXARLOG_SUPPORT @PIXARLOG_SUPPORT@ + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +#cmakedefine PTHREAD_CREATE_JOINABLE + +/* The size of `signed int', as computed by sizeof. */ +#cmakedefine SIZEOF_SIGNED_INT @SIZEOF_SIGNED_INT@ + +/* The size of `signed long', as computed by sizeof. */ +#cmakedefine SIZEOF_SIGNED_LONG @SIZEOF_SIGNED_LONG@ + +/* The size of `signed long long', as computed by sizeof. */ +#cmakedefine SIZEOF_SIGNED_LONG_LONG @SIZEOF_SIGNED_LONG_LONG@ + +/* The size of `signed short', as computed by sizeof. */ +#cmakedefine SIZEOF_SIGNED_SHORT @SIZEOF_SIGNED_SHORT@ + +/* The size of `unsigned char *', as computed by sizeof. */ +#cmakedefine SIZEOF_UNSIGNED_CHAR_P @SIZEOF_UNSIGNED_CHAR_P@ + +/* The size of `unsigned int', as computed by sizeof. */ +#cmakedefine SIZEOF_UNSIGNED_INT @SIZEOF_UNSIGNED_INT@ + +/* The size of `unsigned long', as computed by sizeof. */ +#cmakedefine SIZEOF_UNSIGNED_LONG @SIZEOF_UNSIGNED_LONG@ + +/* The size of `unsigned long long', as computed by sizeof. */ +#cmakedefine SIZEOF_UNSIGNED_LONG_LONG @SIZEOF_UNSIGNED_LONG_LONG@ + +/* The size of `unsigned short', as computed by sizeof. */ +#cmakedefine SIZEOF_UNSIGNED_SHORT @SIZEOF_UNSIGNED_SHORT@ + +/* Define to 1 if you have the ANSI C header files. */ +#cmakedefine STDC_HEADERS @STDC_HEADERS@ + +/* Support strip chopping (whether or not to convert single-strip uncompressed + images to mutiple strips of specified size to reduce memory usage) */ +#cmakedefine STRIPCHOP_DEFAULT @STRIPCHOP_DEFAULT@ + +/* Default size of the strip in bytes (when strip chopping enabled) */ +#cmakedefine STRIP_SIZE_DEFAULT @STRIP_SIZE_DEFAULT@ + +/* Enable SubIFD tag (330) support */ +#cmakedefine SUBIFD_SUPPORT @SUBIFD_SUPPORT@ + +/* Support ThunderScan 4-bit RLE algorithm */ +#cmakedefine THUNDER_SUPPORT @THUNDER_SUPPORT@ + +/* Signed 16-bit type */ +#cmakedefine TIFF_INT16_T @TIFF_INT16_T@ + +/* Signed 32-bit type formatter */ +#cmakedefine TIFF_INT32_FORMAT @TIFF_INT32_FORMAT@ + +/* Signed 32-bit type */ +#cmakedefine TIFF_INT32_T @TIFF_INT32_T@ + +/* Signed 64-bit type formatter */ +#cmakedefine TIFF_INT64_FORMAT @TIFF_INT64_FORMAT@ + +/* Signed 64-bit type */ +#cmakedefine TIFF_INT64_T @TIFF_INT64_T@ + +/* Signed 8-bit type */ +#cmakedefine TIFF_INT8_T @TIFF_INT8_T@ + +/* Pointer difference type formatter */ +#cmakedefine TIFF_PTRDIFF_FORMAT @TIFF_PTRDIFF_FORMAT@ + +/* Pointer difference type */ +#cmakedefine TIFF_PTRDIFF_T @TIFF_PTRDIFF_T@ + +/* Signed size type formatter */ +#cmakedefine TIFF_SSIZE_FORMAT @TIFF_SSIZE_FORMAT@ + +/* Signed size type */ +#cmakedefine TIFF_SSIZE_T @TIFF_SSIZE_T@ + +/* Unsigned 16-bit type */ +#cmakedefine TIFF_UINT16_T @TIFF_UINT16_T@ + +/* Unsigned 32-bit type formatter */ +#cmakedefine TIFF_UINT32_FORMAT @TIFF_UINT32_FORMAT@ + +/* Unsigned 32-bit type */ +#cmakedefine TIFF_UINT32_T @TIFF_UINT32_T@ + +/* Unsigned 64-bit type formatter */ +#cmakedefine TIFF_UINT64_FORMAT @TIFF_UINT64_FORMAT@ + +/* Unsigned 64-bit type */ +#cmakedefine TIFF_UINT64_T @TIFF_UINT64_T@ + +/* Unsigned 8-bit type */ +#cmakedefine TIFF_UINT8_T @TIFF_UINT8_T@ + +/* Define to 1 if you can safely include both and . */ +#cmakedefine TIME_WITH_SYS_TIME @TIME_WITH_SYS_TIME@ + +/* Define to 1 if your declares `struct tm'. */ +#cmakedefine TM_IN_SYS_TIME + +/* define to use win32 IO system */ +#cmakedefine USE_WIN32_FILEIO + +/* Version number of package */ +#cmakedefine VERSION @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 +#cmakedefine WORDS_BIGENDIAN @WORDS_BIGENDIAN@ +# endif +#endif + +/* Define to 1 if the X Window System is missing or not being used. */ +#cmakedefine X_DISPLAY_MISSING + +/* Support Deflate compression */ +#cmakedefine ZIP_SUPPORT @ZIP_SUPPORT@ + +/* Number of bits in a file offset, on hosts where this is settable. */ +#cmakedefine _FILE_OFFSET_BITS @_FILE_OFFSET_BITS@ + +/* Define for large files, on AIX-style hosts. */ +#cmakedefine _LARGE_FILES + +/* Define to empty if `const' does not conform to ANSI C. */ +#cmakedefine const + +/* Visual Studio 2015 / VC 14 / MSVC 19.00 finally has snprintf() */ +#if defined(_MSC_VER) && _MSC_VER < 1900 +#define snprintf _snprintf +#endif + +/* 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@ +#endif + +/* Define to `long int' if does not define. */ +#cmakedefine off_t + +/* Define to `unsigned int' if does not define. */ +#cmakedefine size_t diff --git a/thirdparty/libtiff/tif_config.h.in b/thirdparty/libtiff/tif_config.h.in new file mode 100644 index 00000000..468ddbd3 --- /dev/null +++ b/thirdparty/libtiff/tif_config.h.in @@ -0,0 +1,401 @@ +/* libtiff/tif_config.h.in. Generated from configure.ac by autoheader. */ + +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + +/* Support CCITT Group 3 & 4 algorithms */ +#undef CCITT_SUPPORT + +/* Pick up YCbCr subsampling info from the JPEG data stream to support files + lacking the tag (default enabled). */ +#undef CHECK_JPEG_YCBCR_SUBSAMPLING + +/* enable partial strip reading for large strips (experimental) */ +#undef CHUNKY_STRIP_READ_SUPPORT + +/* Support C++ stream API (requires C++ compiler) */ +#undef CXX_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. */ +#undef DEFAULT_EXTRASAMPLE_AS_ALPHA + +/* enable deferred strip/tile offset/size loading (experimental) */ +#undef DEFER_STRILE_LOAD + +/* Define to 1 if you have the header file. */ +#undef HAVE_ASSERT_H + +/* Define to 1 if you have the declaration of `optarg', and to 0 if you don't. + */ +#undef HAVE_DECL_OPTARG + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the `floor' function. */ +#undef HAVE_FLOOR + +/* Define to 1 if you have the `getopt' function. */ +#undef HAVE_GETOPT + +/* Define to 1 if you have the header file. */ +#undef HAVE_GLUT_GLUT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_GL_GLUT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_GL_GLU_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_GL_GL_H + +/* Define as 0 or 1 according to the floating point format suported by the + machine */ +#undef HAVE_IEEEFP + +/* Define to 1 if the system has the type `int16'. */ +#undef HAVE_INT16 + +/* Define to 1 if the system has the type `int32'. */ +#undef HAVE_INT32 + +/* Define to 1 if the system has the type `int8'. */ +#undef HAVE_INT8 + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_IO_H + +/* Define to 1 if you have the `isascii' function. */ +#undef HAVE_ISASCII + +/* Define to 1 if you have the `jbg_newlen' function. */ +#undef HAVE_JBG_NEWLEN + +/* Define to 1 if you have the `lfind' function. */ +#undef HAVE_LFIND + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define to 1 if you have the `memmove' function. */ +#undef HAVE_MEMMOVE + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `memset' function. */ +#undef HAVE_MEMSET + +/* Define to 1 if you have the `mmap' function. */ +#undef HAVE_MMAP + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENGL_GLU_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENGL_GL_H + +/* Define to 1 if you have the `pow' function. */ +#undef HAVE_POW + +/* Define if you have POSIX threads libraries and header files. */ +#undef HAVE_PTHREAD + +/* Define to 1 if you have the header file. */ +#undef HAVE_SEARCH_H + +/* Define to 1 if you have the `setmode' function. */ +#undef HAVE_SETMODE + +/* Define to 1 if you have the `sqrt' function. */ +#undef HAVE_SQRT + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strcasecmp' function. */ +#undef HAVE_STRCASECMP + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strrchr' function. */ +#undef HAVE_STRRCHR + +/* Define to 1 if you have the `strstr' function. */ +#undef HAVE_STRSTR + +/* Define to 1 if you have the `strtol' function. */ +#undef HAVE_STRTOL + +/* Define to 1 if you have the `strtoul' function. */ +#undef HAVE_STRTOUL + +/* Define to 1 if you have the `strtoull' function. */ +#undef HAVE_STRTOULL + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Use nonstandard varargs form for the GLU tesselator callback */ +#undef HAVE_VARARGS_GLU_TESSCB + +/* Define to 1 if you have the header file. */ +#undef HAVE_WINDOWS_H + +/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian + (Intel) */ +#undef HOST_BIGENDIAN + +/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */ +#undef HOST_FILLORDER + +/* 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 */ +#undef LOGLUV_SUPPORT + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#undef LT_OBJDIR + +/* Support LZMA2 compression */ +#undef LZMA_SUPPORT + +/* Support LZW algorithm */ +#undef LZW_SUPPORT + +/* Support Microsoft Document Imaging format */ +#undef MDI_SUPPORT + +/* Support NeXT 2-bit RLE algorithm */ +#undef NEXT_SUPPORT + +/* Support Old JPEG compresson (read-only) */ +#undef OJPEG_SUPPORT + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Support Macintosh PackBits algorithm */ +#undef PACKBITS_SUPPORT + +/* Support Pixar log-format algorithm (requires Zlib) */ +#undef PIXARLOG_SUPPORT + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +#undef PTHREAD_CREATE_JOINABLE + +/* The size of `signed int', as computed by sizeof. */ +#undef SIZEOF_SIGNED_INT + +/* The size of `signed long', as computed by sizeof. */ +#undef SIZEOF_SIGNED_LONG + +/* The size of `signed long long', as computed by sizeof. */ +#undef SIZEOF_SIGNED_LONG_LONG + +/* The size of `signed short', as computed by sizeof. */ +#undef SIZEOF_SIGNED_SHORT + +/* The size of `size_t', as computed by sizeof. */ +#undef SIZEOF_SIZE_T + +/* The size of `unsigned char *', as computed by sizeof. */ +#undef SIZEOF_UNSIGNED_CHAR_P + +/* The size of `unsigned int', as computed by sizeof. */ +#undef SIZEOF_UNSIGNED_INT + +/* The size of `unsigned long', as computed by sizeof. */ +#undef SIZEOF_UNSIGNED_LONG + +/* The size of `unsigned long long', as computed by sizeof. */ +#undef SIZEOF_UNSIGNED_LONG_LONG + +/* The size of `unsigned short', as computed by sizeof. */ +#undef SIZEOF_UNSIGNED_SHORT + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Support strip chopping (whether or not to convert single-strip uncompressed + images to mutiple strips of specified size to reduce memory usage) */ +#undef STRIPCHOP_DEFAULT + +/* Default size of the strip in bytes (when strip chopping enabled) */ +#undef STRIP_SIZE_DEFAULT + +/* Enable SubIFD tag (330) support */ +#undef SUBIFD_SUPPORT + +/* Support ThunderScan 4-bit RLE algorithm */ +#undef THUNDER_SUPPORT + +/* Signed 16-bit type */ +#undef TIFF_INT16_T + +/* Signed 32-bit type formatter */ +#undef TIFF_INT32_FORMAT + +/* Signed 32-bit type */ +#undef TIFF_INT32_T + +/* Signed 64-bit type formatter */ +#undef TIFF_INT64_FORMAT + +/* Signed 64-bit type */ +#undef TIFF_INT64_T + +/* Signed 8-bit type */ +#undef TIFF_INT8_T + +/* Pointer difference type formatter */ +#undef TIFF_PTRDIFF_FORMAT + +/* Pointer difference type */ +#undef TIFF_PTRDIFF_T + +/* Size type formatter */ +#undef TIFF_SIZE_FORMAT + +/* Unsigned size type */ +#undef TIFF_SIZE_T + +/* Signed size type formatter */ +#undef TIFF_SSIZE_FORMAT + +/* Signed size type */ +#undef TIFF_SSIZE_T + +/* Unsigned 16-bit type */ +#undef TIFF_UINT16_T + +/* Unsigned 32-bit type formatter */ +#undef TIFF_UINT32_FORMAT + +/* Unsigned 32-bit type */ +#undef TIFF_UINT32_T + +/* Unsigned 64-bit type formatter */ +#undef TIFF_UINT64_FORMAT + +/* Unsigned 64-bit type */ +#undef TIFF_UINT64_T + +/* Unsigned 8-bit type */ +#undef TIFF_UINT8_T + +/* Define to 1 if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Define to 1 if your declares `struct tm'. */ +#undef TM_IN_SYS_TIME + +/* define to use win32 IO system */ +#undef USE_WIN32_FILEIO + +/* Version number of package */ +#undef 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 + +/* Define to 1 if the X Window System is missing or not being used. */ +#undef X_DISPLAY_MISSING + +/* Support Deflate compression */ +#undef ZIP_SUPPORT + +/* Enable large inode numbers on Mac OS X 10.5. */ +#ifndef _DARWIN_USE_64_BIT_INODE +# define _DARWIN_USE_64_BIT_INODE 1 +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* 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 +#undef inline +#endif + +/* Define to `long int' if does not define. */ +#undef off_t + +/* Define to `unsigned int' if does not define. */ +#undef size_t diff --git a/thirdparty/libtiff/tif_dir.c b/thirdparty/libtiff/tif_dir.c index ac44b381..73212c02 100644 --- a/thirdparty/libtiff/tif_dir.c +++ b/thirdparty/libtiff/tif_dir.c @@ -1,4 +1,4 @@ -/* $Id: tif_dir.c,v 1.75.2.5 2010-06-09 21:15:27 bfriesen Exp $ */ +/* $Id: tif_dir.c,v 1.121 2015-05-31 23:11:43 bfriesen Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -46,7 +46,7 @@ setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size) if (*vpp) _TIFFfree(*vpp), *vpp = 0; if (vp) { - tsize_t bytes = nmemb * elem_size; + tmsize_t bytes = (tmsize_t)(nmemb * elem_size); if (elem_size && bytes / elem_size == nmemb) *vpp = (void*) _TIFFmalloc(bytes); if (*vpp) @@ -63,11 +63,26 @@ 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) + { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint64)); } void _TIFFsetFloatArray(float** fpp, float* fp, uint32 n) { setByteArray((void**) fpp, (void*) fp, n, sizeof (float)); } void _TIFFsetDoubleArray(double** dpp, double* dp, uint32 n) { setByteArray((void**) dpp, (void*) dp, n, sizeof (double)); } +static void +setDoubleArrayOneValue(double** vpp, double value, size_t nmemb) +{ + if (*vpp) + _TIFFfree(*vpp); + *vpp = _TIFFmalloc(nmemb*sizeof(double)); + if (*vpp) + { + while (nmemb--) + ((double*)*vpp)[nmemb] = value; + } +} + /* * Install extra samples information. */ @@ -80,7 +95,7 @@ setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v) uint16* va; uint32 i; - *v = va_arg(ap, uint32); + *v = (uint16) va_arg(ap, uint16_vap); if ((uint16) *v > td->td_samplesperpixel) return 0; va = va_arg(ap, uint16*); @@ -107,6 +122,10 @@ setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v) #undef EXTRASAMPLE_COREL_UNASSALPHA } +/* + * Confirm we have "samplesperpixel" ink names separated by \0. Returns + * zero if the ink names are not as expected. + */ static uint32 checkInkNamesString(TIFF* tif, uint32 slen, const char* s) { @@ -117,12 +136,12 @@ checkInkNamesString(TIFF* tif, uint32 slen, const char* s) const char* ep = s+slen; const char* cp = s; for (; i > 0; i--) { - for (; *cp != '\0'; cp++) - if (cp >= ep) - goto bad; + for (; cp < ep && *cp != '\0'; cp++) {} + if (cp >= ep) + goto bad; cp++; /* skip \0 */ } - return (cp-s); + return ((uint32)(cp-s)); } bad: TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", @@ -134,27 +153,41 @@ bad: } static int -_TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap) +_TIFFVSetField(TIFF* tif, uint32 tag, va_list ap) { static const char module[] = "_TIFFVSetField"; 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) + */ + if (fip->field_bit == FIELD_CUSTOM) { + standard_tag = 0; + } - switch (tag) { + switch (standard_tag) { case TIFFTAG_SUBFILETYPE: - td->td_subfiletype = va_arg(ap, uint32); + td->td_subfiletype = (uint32) va_arg(ap, uint32); break; case TIFFTAG_IMAGEWIDTH: - td->td_imagewidth = va_arg(ap, uint32); + td->td_imagewidth = (uint32) va_arg(ap, uint32); break; case TIFFTAG_IMAGELENGTH: - td->td_imagelength = va_arg(ap, uint32); + td->td_imagelength = (uint32) va_arg(ap, uint32); break; case TIFFTAG_BITSPERSAMPLE: - td->td_bitspersample = (uint16) va_arg(ap, int); + td->td_bitspersample = (uint16) va_arg(ap, uint16_vap); /* * If the data require post-decoding processing to byte-swap * samples, set it up here. Note that since tags are required @@ -163,7 +196,9 @@ _TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap) * work in with its normal work. */ if (tif->tif_flags & TIFF_SWAB) { - if (td->td_bitspersample == 16) + if (td->td_bitspersample == 8) + tif->tif_postdecode = _TIFFNoPostDecode; + else if (td->td_bitspersample == 16) tif->tif_postdecode = _TIFFSwab16BitData; else if (td->td_bitspersample == 24) tif->tif_postdecode = _TIFFSwab24BitData; @@ -176,14 +211,14 @@ _TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap) } break; case TIFFTAG_COMPRESSION: - v = va_arg(ap, uint32) & 0xffff; + v = (uint16) va_arg(ap, uint16_vap); /* * If we're changing the compression scheme, the notify the * previous module so that it can cleanup any state it's * setup. */ if (TIFFFieldSet(tif, FIELD_COMPRESSION)) { - if (td->td_compression == v) + if ((uint32)td->td_compression == v) break; (*tif->tif_cleanup)(tif); tif->tif_flags &= ~TIFF_CODERSETUP; @@ -192,38 +227,37 @@ _TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap) * Setup new compression routine state. */ if( (status = TIFFSetCompressionScheme(tif, v)) != 0 ) - td->td_compression = (uint16) v; - else - status = 0; + td->td_compression = (uint16) v; + else + status = 0; break; case TIFFTAG_PHOTOMETRIC: - td->td_photometric = (uint16) va_arg(ap, int); + td->td_photometric = (uint16) va_arg(ap, uint16_vap); break; case TIFFTAG_THRESHHOLDING: - td->td_threshholding = (uint16) va_arg(ap, int); + td->td_threshholding = (uint16) va_arg(ap, uint16_vap); break; case TIFFTAG_FILLORDER: - v = va_arg(ap, uint32); + v = (uint16) va_arg(ap, uint16_vap); if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB) goto badvalue; td->td_fillorder = (uint16) v; break; case TIFFTAG_ORIENTATION: - v = va_arg(ap, uint32); + v = (uint16) va_arg(ap, uint16_vap); if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v) goto badvalue; else td->td_orientation = (uint16) v; break; case TIFFTAG_SAMPLESPERPIXEL: - /* XXX should cross check -- e.g. if pallette, then 1 */ - v = va_arg(ap, uint32); + v = (uint16) va_arg(ap, uint16_vap); if (v == 0) goto badvalue; td->td_samplesperpixel = (uint16) v; break; case TIFFTAG_ROWSPERSTRIP: - v32 = va_arg(ap, uint32); + v32 = (uint32) va_arg(ap, uint32); if (v32 == 0) goto badvalue32; td->td_rowsperstrip = v32; @@ -233,25 +267,37 @@ _TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap) } break; case TIFFTAG_MINSAMPLEVALUE: - td->td_minsamplevalue = (uint16) va_arg(ap, int); + td->td_minsamplevalue = (uint16) va_arg(ap, uint16_vap); break; case TIFFTAG_MAXSAMPLEVALUE: - td->td_maxsamplevalue = (uint16) va_arg(ap, int); + td->td_maxsamplevalue = (uint16) va_arg(ap, uint16_vap); break; case TIFFTAG_SMINSAMPLEVALUE: - td->td_sminsamplevalue = va_arg(ap, double); + if (tif->tif_flags & TIFF_PERSAMPLE) + _TIFFsetDoubleArray(&td->td_sminsamplevalue, va_arg(ap, double*), td->td_samplesperpixel); + else + setDoubleArrayOneValue(&td->td_sminsamplevalue, va_arg(ap, double), td->td_samplesperpixel); break; case TIFFTAG_SMAXSAMPLEVALUE: - td->td_smaxsamplevalue = va_arg(ap, double); + if (tif->tif_flags & TIFF_PERSAMPLE) + _TIFFsetDoubleArray(&td->td_smaxsamplevalue, va_arg(ap, double*), td->td_samplesperpixel); + else + 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 = (float) 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 = (float) dblval; break; case TIFFTAG_PLANARCONFIG: - v = va_arg(ap, uint32); + v = (uint16) va_arg(ap, uint16_vap); if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE) goto badvalue; td->td_planarconfig = (uint16) v; @@ -263,18 +309,18 @@ _TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap) td->td_yposition = (float) va_arg(ap, double); break; case TIFFTAG_RESOLUTIONUNIT: - v = va_arg(ap, uint32); + v = (uint16) va_arg(ap, uint16_vap); if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v) goto badvalue; td->td_resolutionunit = (uint16) v; break; case TIFFTAG_PAGENUMBER: - td->td_pagenumber[0] = (uint16) va_arg(ap, int); - td->td_pagenumber[1] = (uint16) va_arg(ap, int); + td->td_pagenumber[0] = (uint16) va_arg(ap, uint16_vap); + td->td_pagenumber[1] = (uint16) va_arg(ap, uint16_vap); break; case TIFFTAG_HALFTONEHINTS: - td->td_halftonehints[0] = (uint16) va_arg(ap, int); - td->td_halftonehints[1] = (uint16) va_arg(ap, int); + td->td_halftonehints[0] = (uint16) va_arg(ap, uint16_vap); + td->td_halftonehints[1] = (uint16) va_arg(ap, uint16_vap); break; case TIFFTAG_COLORMAP: v32 = (uint32)(1L<td_bitspersample); @@ -287,14 +333,14 @@ _TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap) goto badvalue; break; case TIFFTAG_MATTEING: - td->td_extrasamples = (uint16) (va_arg(ap, int) != 0); + td->td_extrasamples = (((uint16) va_arg(ap, uint16_vap)) != 0); if (td->td_extrasamples) { uint16 sv = EXTRASAMPLE_ASSOCALPHA; _TIFFsetShortArray(&td->td_sampleinfo, &sv, 1); } break; case TIFFTAG_TILEWIDTH: - v32 = va_arg(ap, uint32); + v32 = (uint32) va_arg(ap, uint32); if (v32 % 16) { if (tif->tif_mode != O_RDONLY) goto badvalue32; @@ -305,7 +351,7 @@ _TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap) tif->tif_flags |= TIFF_ISTILED; break; case TIFFTAG_TILELENGTH: - v32 = va_arg(ap, uint32); + v32 = (uint32) va_arg(ap, uint32); if (v32 % 16) { if (tif->tif_mode != O_RDONLY) goto badvalue32; @@ -316,13 +362,13 @@ _TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap) tif->tif_flags |= TIFF_ISTILED; break; case TIFFTAG_TILEDEPTH: - v32 = va_arg(ap, uint32); + v32 = (uint32) va_arg(ap, uint32); if (v32 == 0) goto badvalue32; td->td_tiledepth = v32; break; case TIFFTAG_DATATYPE: - v = va_arg(ap, uint32); + v = (uint16) va_arg(ap, uint16_vap); switch (v) { case DATATYPE_VOID: v = SAMPLEFORMAT_VOID; break; case DATATYPE_INT: v = SAMPLEFORMAT_INT; break; @@ -333,29 +379,29 @@ _TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap) td->td_sampleformat = (uint16) v; break; case TIFFTAG_SAMPLEFORMAT: - v = va_arg(ap, uint32); + v = (uint16) va_arg(ap, uint16_vap); if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v) goto badvalue; td->td_sampleformat = (uint16) v; - /* Try to fix up the SWAB function for complex data. */ - if( td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT - && td->td_bitspersample == 32 - && tif->tif_postdecode == _TIFFSwab32BitData ) - tif->tif_postdecode = _TIFFSwab16BitData; - else if( (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT - || td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP) - && td->td_bitspersample == 64 - && tif->tif_postdecode == _TIFFSwab64BitData ) - tif->tif_postdecode = _TIFFSwab32BitData; + /* Try to fix up the SWAB function for complex data. */ + if( td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT + && td->td_bitspersample == 32 + && tif->tif_postdecode == _TIFFSwab32BitData ) + tif->tif_postdecode = _TIFFSwab16BitData; + else if( (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT + || td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP) + && td->td_bitspersample == 64 + && tif->tif_postdecode == _TIFFSwab64BitData ) + tif->tif_postdecode = _TIFFSwab32BitData; break; case TIFFTAG_IMAGEDEPTH: - td->td_imagedepth = va_arg(ap, uint32); + td->td_imagedepth = (uint32) va_arg(ap, uint32); break; case TIFFTAG_SUBIFD: if ((tif->tif_flags & TIFF_INSUBIFD) == 0) { - td->td_nsubifd = (uint16) va_arg(ap, int); - _TIFFsetLongArray(&td->td_subifd, va_arg(ap, uint32*), + td->td_nsubifd = (uint16) va_arg(ap, uint16_vap); + _TIFFsetLong8Array(&td->td_subifd, (uint64*) va_arg(ap, uint64*), (long) td->td_nsubifd); } else { TIFFErrorExt(tif->tif_clientdata, module, @@ -365,11 +411,11 @@ _TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap) } break; case TIFFTAG_YCBCRPOSITIONING: - td->td_ycbcrpositioning = (uint16) va_arg(ap, int); + td->td_ycbcrpositioning = (uint16) va_arg(ap, uint16_vap); break; case TIFFTAG_YCBCRSUBSAMPLING: - td->td_ycbcrsubsampling[0] = (uint16) va_arg(ap, int); - td->td_ycbcrsubsampling[1] = (uint16) va_arg(ap, int); + td->td_ycbcrsubsampling[0] = (uint16) va_arg(ap, uint16_vap); + td->td_ycbcrsubsampling[1] = (uint16) va_arg(ap, uint16_vap); break; case TIFFTAG_TRANSFERFUNCTION: v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1; @@ -382,206 +428,253 @@ _TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap) _TIFFsetFloatArray(&td->td_refblackwhite, va_arg(ap, float*), 6); break; case TIFFTAG_INKNAMES: - v = va_arg(ap, uint32); + v = (uint16) va_arg(ap, uint16_vap); s = va_arg(ap, char*); v = checkInkNamesString(tif, v, s); - status = v > 0; + status = v > 0; if( v > 0 ) { _TIFFsetNString(&td->td_inknames, s, v); td->td_inknameslen = v; } break; - default: { - TIFFTagValue *tv; - int tv_size, iCustom; - const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY); - - /* - * This can happen if multiple images are open with different - * codecs which have private tags. The global tag information - * table may then have tags that are valid for one file but not - * the other. If the client tries to set a tag that is not valid - * for the image's codec then we'll arrive here. This - * 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) { - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Invalid %stag \"%s\" (not supported by codec)", - tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", - fip ? fip->field_name : "Unknown"); - status = 0; + case TIFFTAG_PERSAMPLE: + v = (uint16) va_arg(ap, uint16_vap); + if( v == PERSAMPLE_MULTI ) + tif->tif_flags |= TIFF_PERSAMPLE; + else + tif->tif_flags &= ~TIFF_PERSAMPLE; break; - } + default: { + TIFFTagValue *tv; + int tv_size, iCustom; - /* - * Find the existing entry for this custom value. - */ - tv = NULL; - for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++) { - if (td->td_customValues[iCustom].info->field_tag == tag) { - tv = td->td_customValues + iCustom; - if (tv->value != NULL) { - _TIFFfree(tv->value); - tv->value = NULL; - } - break; - } - } - - /* - * Grow the custom list if the entry was not found. - */ - if(tv == NULL) { - TIFFTagValue *new_customValues; - - td->td_customValueCount++; - new_customValues = (TIFFTagValue *) - _TIFFrealloc(td->td_customValues, - sizeof(TIFFTagValue) * td->td_customValueCount); - if (!new_customValues) { + /* + * This can happen if multiple images are open with different + * codecs which have private tags. The global tag information + * table may then have tags that are valid for one file but not + * the other. If the client tries to set a tag that is not valid + * for the image's codec then we'll arrive here. This + * happens, for example, when tiffcp is used to convert between + * compression schemes and codec-specific tags are blindly copied. + */ + if(fip->field_bit != FIELD_CUSTOM) { TIFFErrorExt(tif->tif_clientdata, module, - "%s: Failed to allocate space for list of custom values", - tif->tif_name); + "%s: Invalid %stag \"%s\" (not supported by codec)", + tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", + fip->field_name); status = 0; + break; + } + + /* + * Find the existing entry for this custom value. + */ + tv = NULL; + for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++) { + if (td->td_customValues[iCustom].info->field_tag == tag) { + tv = td->td_customValues + iCustom; + if (tv->value != NULL) { + _TIFFfree(tv->value); + tv->value = NULL; + } + break; + } + } + + /* + * Grow the custom list if the entry was not found. + */ + if(tv == NULL) { + TIFFTagValue *new_customValues; + + td->td_customValueCount++; + new_customValues = (TIFFTagValue *) + _TIFFrealloc(td->td_customValues, + sizeof(TIFFTagValue) * td->td_customValueCount); + if (!new_customValues) { + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Failed to allocate space for list of custom values", + tif->tif_name); + status = 0; + goto end; + } + + td->td_customValues = new_customValues; + + tv = td->td_customValues + (td->td_customValueCount - 1); + tv->info = fip; + tv->value = NULL; + tv->count = 0; + } + + /* + * Set custom value ... save a copy of the custom tag value. + */ + tv_size = _TIFFDataSize(fip->field_type); + if (tv_size == 0) { + status = 0; + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Bad field type %d for \"%s\"", + tif->tif_name, fip->field_type, + fip->field_name); goto end; } - td->td_customValues = new_customValues; - - tv = td->td_customValues + (td->td_customValueCount - 1); - tv->info = fip; - tv->value = NULL; - tv->count = 0; - } - - /* - * Set custom value ... save a copy of the custom tag value. - */ - tv_size = _TIFFDataSize(fip->field_type); - if (tv_size == 0) { - status = 0; - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Bad field type %d for \"%s\"", - tif->tif_name, fip->field_type, - fip->field_name); - goto end; - } - - if(fip->field_passcount) { - if (fip->field_writecount == TIFF_VARIABLE2) - tv->count = (uint32) va_arg(ap, uint32); - else - tv->count = (int) va_arg(ap, int); - } else if (fip->field_writecount == TIFF_VARIABLE - || fip->field_writecount == TIFF_VARIABLE2) - tv->count = 1; - else if (fip->field_writecount == TIFF_SPP) - tv->count = td->td_samplesperpixel; - else - tv->count = fip->field_writecount; - - - if (fip->field_type == TIFF_ASCII) - _TIFFsetString((char **)&tv->value, va_arg(ap, char *)); - else { - tv->value = _TIFFCheckMalloc(tif, tv_size, tv->count, - "Tag Value"); - if (!tv->value) { - status = 0; - goto end; + if (fip->field_type == TIFF_ASCII) + { + uint32 ma; + char* mb; + if (fip->field_passcount) + { + assert(fip->field_writecount==TIFF_VARIABLE2); + ma=(uint32)va_arg(ap,uint32); + mb=(char*)va_arg(ap,char*); + } + else + { + mb=(char*)va_arg(ap,char*); + ma=(uint32)(strlen(mb)+1); + } + tv->count=ma; + setByteArray(&tv->value,mb,ma,1); } + else + { + if (fip->field_passcount) { + if (fip->field_writecount == TIFF_VARIABLE2) + tv->count = (uint32) va_arg(ap, uint32); + else + tv->count = (int) va_arg(ap, int); + } else if (fip->field_writecount == TIFF_VARIABLE + || fip->field_writecount == TIFF_VARIABLE2) + tv->count = 1; + else if (fip->field_writecount == TIFF_SPP) + tv->count = td->td_samplesperpixel; + else + tv->count = fip->field_writecount; - if ((fip->field_passcount - || fip->field_writecount == TIFF_VARIABLE - || fip->field_writecount == TIFF_VARIABLE2 - || fip->field_writecount == TIFF_SPP - || tv->count > 1) - && fip->field_tag != TIFFTAG_PAGENUMBER - && fip->field_tag != TIFFTAG_HALFTONEHINTS - && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING - && fip->field_tag != TIFFTAG_DOTRANGE) { - _TIFFmemcpy(tv->value, va_arg(ap, void *), - tv->count * tv_size); - } else { - /* - * XXX: The following loop required to handle - * TIFFTAG_PAGENUMBER, TIFFTAG_HALFTONEHINTS, - * TIFFTAG_YCBCRSUBSAMPLING and TIFFTAG_DOTRANGE tags. - * These tags are actually arrays and should be passed as - * array pointers to TIFFSetField() function, but actually - * passed as a list of separate values. This behaviour - * must be changed in the future! - */ - int i; - char *val = (char *)tv->value; + if (tv->count == 0) { + status = 0; + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Null count for \"%s\" (type " + "%d, writecount %d, passcount %d)", + tif->tif_name, + fip->field_name, + fip->field_type, + fip->field_writecount, + fip->field_passcount); + goto end; + } - for (i = 0; i < tv->count; i++, val += tv_size) { - switch (fip->field_type) { + tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size, + "custom tag binary object"); + if (!tv->value) { + status = 0; + goto end; + } + + if (fip->field_tag == TIFFTAG_DOTRANGE + && strcmp(fip->field_name,"DotRange") == 0) { + /* TODO: This is an evil exception and should not have been + 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); + } + + else if (fip->field_passcount + || fip->field_writecount == TIFF_VARIABLE + || fip->field_writecount == TIFF_VARIABLE2 + || fip->field_writecount == TIFF_SPP + || tv->count > 1) { + _TIFFmemcpy(tv->value, va_arg(ap, void *), + tv->count * tv_size); + } else { + char *val = (char *)tv->value; + assert( tv->count == 1 ); + + switch (fip->field_type) { case TIFF_BYTE: case TIFF_UNDEFINED: - { - uint8 v = (uint8)va_arg(ap, int); - _TIFFmemcpy(val, &v, tv_size); - } - break; + { + uint8 v = (uint8)va_arg(ap, int); + _TIFFmemcpy(val, &v, tv_size); + } + break; case TIFF_SBYTE: - { - int8 v = (int8)va_arg(ap, int); - _TIFFmemcpy(val, &v, tv_size); - } - break; + { + int8 v = (int8)va_arg(ap, int); + _TIFFmemcpy(val, &v, tv_size); + } + break; case TIFF_SHORT: - { - uint16 v = (uint16)va_arg(ap, int); - _TIFFmemcpy(val, &v, tv_size); - } - break; + { + uint16 v = (uint16)va_arg(ap, int); + _TIFFmemcpy(val, &v, tv_size); + } + break; case TIFF_SSHORT: - { - int16 v = (int16)va_arg(ap, int); - _TIFFmemcpy(val, &v, tv_size); - } - break; + { + int16 v = (int16)va_arg(ap, int); + _TIFFmemcpy(val, &v, tv_size); + } + break; case TIFF_LONG: case TIFF_IFD: - { - uint32 v = va_arg(ap, uint32); - _TIFFmemcpy(val, &v, tv_size); - } - break; + { + uint32 v = va_arg(ap, uint32); + _TIFFmemcpy(val, &v, tv_size); + } + break; case TIFF_SLONG: - { - int32 v = va_arg(ap, int32); - _TIFFmemcpy(val, &v, tv_size); - } - break; + { + int32 v = va_arg(ap, int32); + _TIFFmemcpy(val, &v, tv_size); + } + break; + case TIFF_LONG8: + case TIFF_IFD8: + { + uint64 v = va_arg(ap, uint64); + _TIFFmemcpy(val, &v, tv_size); + } + break; + case TIFF_SLONG8: + { + int64 v = va_arg(ap, int64); + _TIFFmemcpy(val, &v, tv_size); + } + break; case TIFF_RATIONAL: case TIFF_SRATIONAL: case TIFF_FLOAT: - { - float v = (float)va_arg(ap, double); - _TIFFmemcpy(val, &v, tv_size); - } - break; + { + float v = (float)va_arg(ap, double); + _TIFFmemcpy(val, &v, tv_size); + } + break; case TIFF_DOUBLE: - { - double v = va_arg(ap, double); - _TIFFmemcpy(val, &v, tv_size); - } - break; + { + double v = va_arg(ap, double); + _TIFFmemcpy(val, &v, tv_size); + } + break; default: - _TIFFmemset(val, 0, tv_size); - status = 0; - break; - } - } + _TIFFmemset(val, 0, tv_size); + status = 0; + break; + } + } } - } - } + } } if (status) { - TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit); + const TIFFField* fip=TIFFFieldWithTag(tif,tag); + if (fip) + TIFFSetFieldBit(tif, fip->field_bit); tif->tif_flags |= TIFF_DIRTYDIRECT; } @@ -589,19 +682,35 @@ end: va_end(ap); return (status); badvalue: - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Bad value %d for \"%s\" tag", + { + const TIFFField* fip=TIFFFieldWithTag(tif,tag); + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Bad value %u for \"%s\" tag", tif->tif_name, v, - _TIFFFieldWithTag(tif, tag)->field_name); - va_end(ap); + fip ? fip->field_name : "Unknown"); + va_end(ap); + } return (0); badvalue32: - TIFFErrorExt(tif->tif_clientdata, module, + { + const TIFFField* fip=TIFFFieldWithTag(tif,tag); + TIFFErrorExt(tif->tif_clientdata, module, "%s: Bad value %u for \"%s\" tag", tif->tif_name, v32, - _TIFFFieldWithTag(tif, tag)->field_name); - va_end(ap); + fip ? fip->field_name : "Unknown"); + va_end(ap); + } return (0); +badvaluedouble: + { + const TIFFField* fip=TIFFFieldWithTag(tif,tag); + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Bad value %f for \"%s\" tag", + tif->tif_name, dblval, + fip ? fip->field_name : "Unknown"); + va_end(ap); + } + return (0); } /* @@ -614,9 +723,9 @@ badvalue32: * on the format of the data that is written. */ static int -OkToChangeTag(TIFF* tif, ttag_t tag) +OkToChangeTag(TIFF* tif, uint32 tag) { - const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY); + const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY); if (!fip) { /* unknown tag */ TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", "%s: Unknown %stag %u", tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag); @@ -646,7 +755,7 @@ OkToChangeTag(TIFF* tif, ttag_t tag) * updated. */ int -TIFFSetField(TIFF* tif, ttag_t tag, ...) +TIFFSetField(TIFF* tif, uint32 tag, ...) { va_list ap; int status; @@ -657,6 +766,47 @@ TIFFSetField(TIFF* tif, ttag_t tag, ...) return (status); } +/* + * Clear the contents of the field in the internal structure. + */ +int +TIFFUnsetField(TIFF* tif, uint32 tag) +{ + const TIFFField *fip = TIFFFieldWithTag(tif, tag); + TIFFDirectory* td = &tif->tif_dir; + + if( !fip ) + return 0; + + if( fip->field_bit != FIELD_CUSTOM ) + TIFFClrFieldBit(tif, fip->field_bit); + else + { + TIFFTagValue *tv = NULL; + int i; + + for (i = 0; i < td->td_customValueCount; i++) { + + tv = td->td_customValues + i; + if( tv->info->field_tag == tag ) + break; + } + + if( i < td->td_customValueCount ) + { + _TIFFfree(tv->value); + for( ; i < td->td_customValueCount-1; i++) { + td->td_customValues[i] = td->td_customValues[i+1]; + } + td->td_customValueCount--; + } + } + + tif->tif_flags |= TIFF_DIRTYDIRECT; + + return (1); +} + /* * Like TIFFSetField, but taking a varargs * parameter list. This routine is useful @@ -664,283 +814,334 @@ TIFFSetField(TIFF* tif, ttag_t tag, ...) * top of the library. */ int -TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap) +TIFFVSetField(TIFF* tif, uint32 tag, va_list ap) { return OkToChangeTag(tif, tag) ? (*tif->tif_tagmethods.vsetfield)(tif, tag, ap) : 0; } static int -_TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap) +_TIFFVGetField(TIFF* tif, uint32 tag, va_list ap) { - TIFFDirectory* td = &tif->tif_dir; - int ret_val = 1; + TIFFDirectory* td = &tif->tif_dir; + 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; + + /* + * 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) + */ + if (fip->field_bit == FIELD_CUSTOM) { + standard_tag = 0; + } - switch (tag) { - case TIFFTAG_SUBFILETYPE: - *va_arg(ap, uint32*) = td->td_subfiletype; - break; - case TIFFTAG_IMAGEWIDTH: - *va_arg(ap, uint32*) = td->td_imagewidth; - break; - case TIFFTAG_IMAGELENGTH: - *va_arg(ap, uint32*) = td->td_imagelength; - break; - case TIFFTAG_BITSPERSAMPLE: - *va_arg(ap, uint16*) = td->td_bitspersample; - break; - case TIFFTAG_COMPRESSION: - *va_arg(ap, uint16*) = td->td_compression; - break; - case TIFFTAG_PHOTOMETRIC: - *va_arg(ap, uint16*) = td->td_photometric; - break; - case TIFFTAG_THRESHHOLDING: - *va_arg(ap, uint16*) = td->td_threshholding; - break; - case TIFFTAG_FILLORDER: - *va_arg(ap, uint16*) = td->td_fillorder; - break; - case TIFFTAG_ORIENTATION: - *va_arg(ap, uint16*) = td->td_orientation; - break; - case TIFFTAG_SAMPLESPERPIXEL: - *va_arg(ap, uint16*) = td->td_samplesperpixel; - break; - case TIFFTAG_ROWSPERSTRIP: - *va_arg(ap, uint32*) = td->td_rowsperstrip; - break; - case TIFFTAG_MINSAMPLEVALUE: - *va_arg(ap, uint16*) = td->td_minsamplevalue; - break; - case TIFFTAG_MAXSAMPLEVALUE: - *va_arg(ap, uint16*) = td->td_maxsamplevalue; - break; - case TIFFTAG_SMINSAMPLEVALUE: - *va_arg(ap, double*) = td->td_sminsamplevalue; - break; - case TIFFTAG_SMAXSAMPLEVALUE: - *va_arg(ap, double*) = td->td_smaxsamplevalue; - break; - case TIFFTAG_XRESOLUTION: - *va_arg(ap, float*) = td->td_xresolution; - break; - case TIFFTAG_YRESOLUTION: - *va_arg(ap, float*) = td->td_yresolution; - break; - case TIFFTAG_PLANARCONFIG: - *va_arg(ap, uint16*) = td->td_planarconfig; - break; - case TIFFTAG_XPOSITION: - *va_arg(ap, float*) = td->td_xposition; - break; - case TIFFTAG_YPOSITION: - *va_arg(ap, float*) = td->td_yposition; - break; - case TIFFTAG_RESOLUTIONUNIT: - *va_arg(ap, uint16*) = td->td_resolutionunit; - break; - case TIFFTAG_PAGENUMBER: - *va_arg(ap, uint16*) = td->td_pagenumber[0]; - *va_arg(ap, uint16*) = td->td_pagenumber[1]; - break; - case TIFFTAG_HALFTONEHINTS: - *va_arg(ap, uint16*) = td->td_halftonehints[0]; - *va_arg(ap, uint16*) = td->td_halftonehints[1]; - break; - case TIFFTAG_COLORMAP: - *va_arg(ap, uint16**) = td->td_colormap[0]; - *va_arg(ap, uint16**) = td->td_colormap[1]; - *va_arg(ap, uint16**) = td->td_colormap[2]; - break; - case TIFFTAG_STRIPOFFSETS: - case TIFFTAG_TILEOFFSETS: - *va_arg(ap, uint32**) = td->td_stripoffset; - break; - case TIFFTAG_STRIPBYTECOUNTS: - case TIFFTAG_TILEBYTECOUNTS: - *va_arg(ap, uint32**) = td->td_stripbytecount; - break; - case TIFFTAG_MATTEING: - *va_arg(ap, uint16*) = - (td->td_extrasamples == 1 && - td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA); - break; - case TIFFTAG_EXTRASAMPLES: - *va_arg(ap, uint16*) = td->td_extrasamples; - *va_arg(ap, uint16**) = td->td_sampleinfo; - break; - case TIFFTAG_TILEWIDTH: - *va_arg(ap, uint32*) = td->td_tilewidth; - break; - case TIFFTAG_TILELENGTH: - *va_arg(ap, uint32*) = td->td_tilelength; - break; - case TIFFTAG_TILEDEPTH: - *va_arg(ap, uint32*) = td->td_tiledepth; - break; - case TIFFTAG_DATATYPE: - switch (td->td_sampleformat) { - case SAMPLEFORMAT_UINT: - *va_arg(ap, uint16*) = DATATYPE_UINT; - break; - case SAMPLEFORMAT_INT: - *va_arg(ap, uint16*) = DATATYPE_INT; - break; - case SAMPLEFORMAT_IEEEFP: - *va_arg(ap, uint16*) = DATATYPE_IEEEFP; - break; - case SAMPLEFORMAT_VOID: - *va_arg(ap, uint16*) = DATATYPE_VOID; - break; - } - break; - case TIFFTAG_SAMPLEFORMAT: - *va_arg(ap, uint16*) = td->td_sampleformat; - break; - case TIFFTAG_IMAGEDEPTH: - *va_arg(ap, uint32*) = td->td_imagedepth; - break; - case TIFFTAG_SUBIFD: - *va_arg(ap, uint16*) = td->td_nsubifd; - *va_arg(ap, uint32**) = td->td_subifd; - break; - case TIFFTAG_YCBCRPOSITIONING: - *va_arg(ap, uint16*) = td->td_ycbcrpositioning; - break; - case TIFFTAG_YCBCRSUBSAMPLING: - *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[0]; - *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1]; - break; - case TIFFTAG_TRANSFERFUNCTION: - *va_arg(ap, uint16**) = td->td_transferfunction[0]; - if (td->td_samplesperpixel - td->td_extrasamples > 1) { - *va_arg(ap, uint16**) = td->td_transferfunction[1]; - *va_arg(ap, uint16**) = td->td_transferfunction[2]; - } - break; - case TIFFTAG_REFERENCEBLACKWHITE: - *va_arg(ap, float**) = td->td_refblackwhite; - break; - case TIFFTAG_INKNAMES: - *va_arg(ap, char**) = td->td_inknames; - break; - default: - { - const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY); - int i; - - /* - * This can happen if multiple images are open with different - * codecs which have private tags. The global tag information - * table may then have tags that are valid for one file but not - * the other. If the client tries to 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 ) - { - TIFFErrorExt(tif->tif_clientdata, "_TIFFVGetField", - "%s: Invalid %stag \"%s\" " - "(not supported by codec)", - tif->tif_name, - isPseudoTag(tag) ? "pseudo-" : "", - fip ? fip->field_name : "Unknown"); - ret_val = 0; - break; - } - - /* - * Do we have a custom value? - */ - ret_val = 0; - for (i = 0; i < td->td_customValueCount; i++) { - TIFFTagValue *tv = td->td_customValues + i; - - if (tv->info->field_tag != tag) - continue; - - if (fip->field_passcount) { - if (fip->field_readcount == TIFF_VARIABLE2) - *va_arg(ap, uint32*) = (uint32)tv->count; - else /* Assume TIFF_VARIABLE */ - *va_arg(ap, uint16*) = (uint16)tv->count; - *va_arg(ap, void **) = tv->value; - ret_val = 1; - } else { - if ((fip->field_type == TIFF_ASCII - || fip->field_readcount == TIFF_VARIABLE - || fip->field_readcount == TIFF_VARIABLE2 - || fip->field_readcount == TIFF_SPP - || tv->count > 1) - && fip->field_tag != TIFFTAG_PAGENUMBER - && fip->field_tag != TIFFTAG_HALFTONEHINTS - && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING - && fip->field_tag != TIFFTAG_DOTRANGE) { - *va_arg(ap, void **) = tv->value; - ret_val = 1; - } else { - int j; - char *val = (char *)tv->value; - - for (j = 0; j < tv->count; - j++, val += _TIFFDataSize(tv->info->field_type)) { - switch (fip->field_type) { - case TIFF_BYTE: - case TIFF_UNDEFINED: - *va_arg(ap, uint8*) = - *(uint8 *)val; - ret_val = 1; - break; - case TIFF_SBYTE: - *va_arg(ap, int8*) = - *(int8 *)val; - ret_val = 1; - break; - case TIFF_SHORT: - *va_arg(ap, uint16*) = - *(uint16 *)val; - ret_val = 1; - break; - case TIFF_SSHORT: - *va_arg(ap, int16*) = - *(int16 *)val; - ret_val = 1; - break; - case TIFF_LONG: - case TIFF_IFD: - *va_arg(ap, uint32*) = - *(uint32 *)val; - ret_val = 1; - break; - case TIFF_SLONG: - *va_arg(ap, int32*) = - *(int32 *)val; - ret_val = 1; - break; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - case TIFF_FLOAT: - *va_arg(ap, float*) = - *(float *)val; - ret_val = 1; - break; - case TIFF_DOUBLE: - *va_arg(ap, double*) = - *(double *)val; - ret_val = 1; - break; - default: - ret_val = 0; - break; - } - } + switch (standard_tag) { + case TIFFTAG_SUBFILETYPE: + *va_arg(ap, uint32*) = td->td_subfiletype; + break; + case TIFFTAG_IMAGEWIDTH: + *va_arg(ap, uint32*) = td->td_imagewidth; + break; + case TIFFTAG_IMAGELENGTH: + *va_arg(ap, uint32*) = td->td_imagelength; + break; + case TIFFTAG_BITSPERSAMPLE: + *va_arg(ap, uint16*) = td->td_bitspersample; + break; + case TIFFTAG_COMPRESSION: + *va_arg(ap, uint16*) = td->td_compression; + break; + case TIFFTAG_PHOTOMETRIC: + *va_arg(ap, uint16*) = td->td_photometric; + break; + case TIFFTAG_THRESHHOLDING: + *va_arg(ap, uint16*) = td->td_threshholding; + break; + case TIFFTAG_FILLORDER: + *va_arg(ap, uint16*) = td->td_fillorder; + break; + case TIFFTAG_ORIENTATION: + *va_arg(ap, uint16*) = td->td_orientation; + break; + case TIFFTAG_SAMPLESPERPIXEL: + *va_arg(ap, uint16*) = td->td_samplesperpixel; + break; + case TIFFTAG_ROWSPERSTRIP: + *va_arg(ap, uint32*) = td->td_rowsperstrip; + break; + case TIFFTAG_MINSAMPLEVALUE: + *va_arg(ap, uint16*) = td->td_minsamplevalue; + break; + case TIFFTAG_MAXSAMPLEVALUE: + *va_arg(ap, uint16*) = td->td_maxsamplevalue; + break; + case TIFFTAG_SMINSAMPLEVALUE: + if (tif->tif_flags & TIFF_PERSAMPLE) + *va_arg(ap, double**) = td->td_sminsamplevalue; + else + { + /* libtiff historially treats this as a single value. */ + uint16 i; + double v = td->td_sminsamplevalue[0]; + for (i=1; i < td->td_samplesperpixel; ++i) + if( td->td_sminsamplevalue[i] < v ) + v = td->td_sminsamplevalue[i]; + *va_arg(ap, double*) = v; } - } - break; - } - } - } - return(ret_val); + break; + case TIFFTAG_SMAXSAMPLEVALUE: + if (tif->tif_flags & TIFF_PERSAMPLE) + *va_arg(ap, double**) = td->td_smaxsamplevalue; + else + { + /* libtiff historially treats this as a single value. */ + uint16 i; + double v = td->td_smaxsamplevalue[0]; + for (i=1; i < td->td_samplesperpixel; ++i) + if( td->td_smaxsamplevalue[i] > v ) + v = td->td_smaxsamplevalue[i]; + *va_arg(ap, double*) = v; + } + break; + case TIFFTAG_XRESOLUTION: + *va_arg(ap, float*) = td->td_xresolution; + break; + case TIFFTAG_YRESOLUTION: + *va_arg(ap, float*) = td->td_yresolution; + break; + case TIFFTAG_PLANARCONFIG: + *va_arg(ap, uint16*) = td->td_planarconfig; + break; + case TIFFTAG_XPOSITION: + *va_arg(ap, float*) = td->td_xposition; + break; + case TIFFTAG_YPOSITION: + *va_arg(ap, float*) = td->td_yposition; + break; + case TIFFTAG_RESOLUTIONUNIT: + *va_arg(ap, uint16*) = td->td_resolutionunit; + break; + case TIFFTAG_PAGENUMBER: + *va_arg(ap, uint16*) = td->td_pagenumber[0]; + *va_arg(ap, uint16*) = td->td_pagenumber[1]; + break; + case TIFFTAG_HALFTONEHINTS: + *va_arg(ap, uint16*) = td->td_halftonehints[0]; + *va_arg(ap, uint16*) = td->td_halftonehints[1]; + break; + case TIFFTAG_COLORMAP: + *va_arg(ap, uint16**) = td->td_colormap[0]; + *va_arg(ap, uint16**) = td->td_colormap[1]; + *va_arg(ap, uint16**) = td->td_colormap[2]; + break; + case TIFFTAG_STRIPOFFSETS: + case TIFFTAG_TILEOFFSETS: + _TIFFFillStriles( tif ); + *va_arg(ap, uint64**) = td->td_stripoffset; + break; + case TIFFTAG_STRIPBYTECOUNTS: + case TIFFTAG_TILEBYTECOUNTS: + _TIFFFillStriles( tif ); + *va_arg(ap, uint64**) = td->td_stripbytecount; + break; + case TIFFTAG_MATTEING: + *va_arg(ap, uint16*) = + (td->td_extrasamples == 1 && + td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA); + break; + case TIFFTAG_EXTRASAMPLES: + *va_arg(ap, uint16*) = td->td_extrasamples; + *va_arg(ap, uint16**) = td->td_sampleinfo; + break; + case TIFFTAG_TILEWIDTH: + *va_arg(ap, uint32*) = td->td_tilewidth; + break; + case TIFFTAG_TILELENGTH: + *va_arg(ap, uint32*) = td->td_tilelength; + break; + case TIFFTAG_TILEDEPTH: + *va_arg(ap, uint32*) = td->td_tiledepth; + break; + case TIFFTAG_DATATYPE: + switch (td->td_sampleformat) { + case SAMPLEFORMAT_UINT: + *va_arg(ap, uint16*) = DATATYPE_UINT; + break; + case SAMPLEFORMAT_INT: + *va_arg(ap, uint16*) = DATATYPE_INT; + break; + case SAMPLEFORMAT_IEEEFP: + *va_arg(ap, uint16*) = DATATYPE_IEEEFP; + break; + case SAMPLEFORMAT_VOID: + *va_arg(ap, uint16*) = DATATYPE_VOID; + break; + } + break; + case TIFFTAG_SAMPLEFORMAT: + *va_arg(ap, uint16*) = td->td_sampleformat; + break; + case TIFFTAG_IMAGEDEPTH: + *va_arg(ap, uint32*) = td->td_imagedepth; + break; + case TIFFTAG_SUBIFD: + *va_arg(ap, uint16*) = td->td_nsubifd; + *va_arg(ap, uint64**) = td->td_subifd; + break; + case TIFFTAG_YCBCRPOSITIONING: + *va_arg(ap, uint16*) = td->td_ycbcrpositioning; + break; + case TIFFTAG_YCBCRSUBSAMPLING: + *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[0]; + *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1]; + break; + case TIFFTAG_TRANSFERFUNCTION: + *va_arg(ap, uint16**) = td->td_transferfunction[0]; + if (td->td_samplesperpixel - td->td_extrasamples > 1) { + *va_arg(ap, uint16**) = td->td_transferfunction[1]; + *va_arg(ap, uint16**) = td->td_transferfunction[2]; + } + break; + case TIFFTAG_REFERENCEBLACKWHITE: + *va_arg(ap, float**) = td->td_refblackwhite; + break; + case TIFFTAG_INKNAMES: + *va_arg(ap, char**) = td->td_inknames; + break; + default: + { + int i; + + /* + * This can happen if multiple images are open + * with different codecs which have private + * tags. The global tag information table may + * then have tags that are valid for one file + * but not the other. If the client tries to + * get a tag that is not valid for the image's + * codec then we'll arrive here. + */ + 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->field_name); + ret_val = 0; + break; + } + + /* + * Do we have a custom value? + */ + ret_val = 0; + for (i = 0; i < td->td_customValueCount; i++) { + TIFFTagValue *tv = td->td_customValues + i; + + if (tv->info->field_tag != tag) + continue; + + if (fip->field_passcount) { + if (fip->field_readcount == TIFF_VARIABLE2) + *va_arg(ap, uint32*) = (uint32)tv->count; + else /* Assume TIFF_VARIABLE */ + *va_arg(ap, uint16*) = (uint16)tv->count; + *va_arg(ap, void **) = tv->value; + ret_val = 1; + } else if (fip->field_tag == TIFFTAG_DOTRANGE + && strcmp(fip->field_name,"DotRange") == 0) { + /* TODO: This is an evil exception and should not have been + 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 */ + *va_arg(ap, uint16*) = ((uint16 *)tv->value)[0]; + *va_arg(ap, uint16*) = ((uint16 *)tv->value)[1]; + ret_val = 1; + } else { + if (fip->field_type == TIFF_ASCII + || fip->field_readcount == TIFF_VARIABLE + || fip->field_readcount == TIFF_VARIABLE2 + || fip->field_readcount == TIFF_SPP + || tv->count > 1) { + *va_arg(ap, void **) = tv->value; + ret_val = 1; + } else { + char *val = (char *)tv->value; + assert( tv->count == 1 ); + switch (fip->field_type) { + case TIFF_BYTE: + case TIFF_UNDEFINED: + *va_arg(ap, uint8*) = + *(uint8 *)val; + ret_val = 1; + break; + case TIFF_SBYTE: + *va_arg(ap, int8*) = + *(int8 *)val; + ret_val = 1; + break; + case TIFF_SHORT: + *va_arg(ap, uint16*) = + *(uint16 *)val; + ret_val = 1; + break; + case TIFF_SSHORT: + *va_arg(ap, int16*) = + *(int16 *)val; + ret_val = 1; + break; + case TIFF_LONG: + case TIFF_IFD: + *va_arg(ap, uint32*) = + *(uint32 *)val; + ret_val = 1; + break; + case TIFF_SLONG: + *va_arg(ap, int32*) = + *(int32 *)val; + ret_val = 1; + break; + case TIFF_LONG8: + case TIFF_IFD8: + *va_arg(ap, uint64*) = + *(uint64 *)val; + ret_val = 1; + break; + case TIFF_SLONG8: + *va_arg(ap, int64*) = + *(int64 *)val; + ret_val = 1; + break; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + *va_arg(ap, float*) = + *(float *)val; + ret_val = 1; + break; + case TIFF_DOUBLE: + *va_arg(ap, double*) = + *(double *)val; + ret_val = 1; + break; + default: + ret_val = 0; + break; + } + } + } + break; + } + } + } + return(ret_val); } /* @@ -948,7 +1149,7 @@ _TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap) * internal directory structure. */ int -TIFFGetField(TIFF* tif, ttag_t tag, ...) +TIFFGetField(TIFF* tif, uint32 tag, ...) { int status; va_list ap; @@ -966,9 +1167,9 @@ TIFFGetField(TIFF* tif, ttag_t tag, ...) * top of the library. */ int -TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap) +TIFFVGetField(TIFF* tif, uint32 tag, va_list ap) { - const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY); + const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY); return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) ? (*tif->tif_tagmethods.vgetfield)(tif, tag, ap) : 0); } @@ -990,6 +1191,8 @@ TIFFFreeDirectory(TIFF* tif) int i; _TIFFmemset(td->td_fieldsset, 0, FIELD_SETLONGS); + CleanupField(td_sminsamplevalue); + CleanupField(td_smaxsamplevalue); CleanupField(td_colormap[0]); CleanupField(td_colormap[1]); CleanupField(td_colormap[2]); @@ -1013,6 +1216,11 @@ TIFFFreeDirectory(TIFF* tif) td->td_customValueCount = 0; CleanupField(td_customValues); + +#if defined(DEFER_STRILE_LOAD) + _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry)); + _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry)); +#endif } #undef CleanupField @@ -1039,14 +1247,43 @@ TIFFSetTagExtender(TIFFExtendProc extender) int TIFFCreateDirectory(TIFF* tif) { - TIFFDefaultDirectory(tif); - tif->tif_diroff = 0; - tif->tif_nextdiroff = 0; - tif->tif_curoff = 0; - tif->tif_row = (uint32) -1; - tif->tif_curstrip = (tstrip_t) -1; + TIFFDefaultDirectory(tif); + tif->tif_diroff = 0; + tif->tif_nextdiroff = 0; + tif->tif_curoff = 0; + tif->tif_row = (uint32) -1; + tif->tif_curstrip = (uint32) -1; - return 0; + return 0; +} + +int +TIFFCreateCustomDirectory(TIFF* tif, const TIFFFieldArray* infoarray) +{ + TIFFDefaultDirectory(tif); + + /* + * Reset the field definitions to match the application provided list. + * Hopefully TIFFDefaultDirectory() won't have done anything irreversable + * based on it's assumption this is an image directory. + */ + _TIFFSetupFields(tif, infoarray); + + tif->tif_diroff = 0; + tif->tif_nextdiroff = 0; + tif->tif_curoff = 0; + tif->tif_row = (uint32) -1; + tif->tif_curstrip = (uint32) -1; + + return 0; +} + +int +TIFFCreateEXIFDirectory(TIFF* tif) +{ + const TIFFFieldArray* exifFieldArray; + exifFieldArray = _TIFFGetExifFields(); + return TIFFCreateCustomDirectory(tif, exifFieldArray); } /* @@ -1056,11 +1293,10 @@ int TIFFDefaultDirectory(TIFF* tif) { register TIFFDirectory* td = &tif->tif_dir; + const TIFFFieldArray* tiffFieldArray; - size_t tiffFieldInfoCount; - const TIFFFieldInfo *tiffFieldInfo = - _TIFFGetFieldInfo(&tiffFieldInfoCount); - _TIFFSetupFieldInfo(tif, tiffFieldInfo, tiffFieldInfoCount); + tiffFieldArray = _TIFFGetFields(); + _TIFFSetupFields(tif, tiffFieldArray); _TIFFmemset(td, 0, sizeof (*td)); td->td_fillorder = FILLORDER_MSB2LSB; @@ -1072,22 +1308,34 @@ TIFFDefaultDirectory(TIFF* tif) td->td_tilewidth = 0; td->td_tilelength = 0; td->td_tiledepth = 1; - td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */ + td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */ td->td_resolutionunit = RESUNIT_INCH; td->td_sampleformat = SAMPLEFORMAT_UINT; td->td_imagedepth = 1; td->td_ycbcrsubsampling[0] = 2; td->td_ycbcrsubsampling[1] = 2; td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED; - tif->tif_postdecode = _TIFFNoPostDecode; + tif->tif_postdecode = _TIFFNoPostDecode; tif->tif_foundfield = NULL; - tif->tif_tagmethods.vsetfield = _TIFFVSetField; + tif->tif_tagmethods.vsetfield = _TIFFVSetField; tif->tif_tagmethods.vgetfield = _TIFFVGetField; 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); @@ -1107,69 +1355,145 @@ TIFFDefaultDirectory(TIFF* tif) * Should we also be clearing stuff like INSUBIFD? */ tif->tif_flags &= ~TIFF_ISTILED; - /* - * Clear other directory-specific fields. - */ - tif->tif_tilesize = -1; - tif->tif_scanlinesize = -1; return (1); } static int -TIFFAdvanceDirectory(TIFF* tif, uint32* nextdir, toff_t* off) +TIFFAdvanceDirectory(TIFF* tif, uint64* nextdir, uint64* off) { static const char module[] = "TIFFAdvanceDirectory"; - uint16 dircount; if (isMapped(tif)) { - toff_t poff=*nextdir; - if (poff+sizeof(uint16) > tif->tif_size) + uint64 poff=*nextdir; + if (!(tif->tif_flags&TIFF_BIGTIFF)) { - TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count", - tif->tif_name); - return (0); + tmsize_t poffa,poffb,poffc,poffd; + uint16 dircount; + uint32 nextdir32; + poffa=(tmsize_t)poff; + poffb=poffa+sizeof(uint16); + if (((uint64)poffa!=poff)||(poffbtif->tif_size)) + { + TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count"); + *nextdir=0; + return(0); + } + _TIFFmemcpy(&dircount,tif->tif_base+poffa,sizeof(uint16)); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort(&dircount); + poffc=poffb+dircount*12; + poffd=poffc+sizeof(uint32); + if ((poffctif->tif_size)) + { + TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory link"); + return(0); + } + if (off!=NULL) + *off=(uint64)poffc; + _TIFFmemcpy(&nextdir32,tif->tif_base+poffc,sizeof(uint32)); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(&nextdir32); + *nextdir=nextdir32; } - _TIFFmemcpy(&dircount, tif->tif_base+poff, sizeof (uint16)); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&dircount); - poff+=sizeof (uint16)+dircount*sizeof (TIFFDirEntry); - if (off != NULL) - *off = poff; - if (((toff_t) (poff+sizeof (uint32))) > tif->tif_size) + else { - TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link", - tif->tif_name); - return (0); + tmsize_t poffa,poffb,poffc,poffd; + uint64 dircount64; + uint16 dircount16; + poffa=(tmsize_t)poff; + poffb=poffa+sizeof(uint64); + if (((uint64)poffa!=poff)||(poffbtif->tif_size)) + { + TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count"); + return(0); + } + _TIFFmemcpy(&dircount64,tif->tif_base+poffa,sizeof(uint64)); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8(&dircount64); + if (dircount64>0xFFFF) + { + TIFFErrorExt(tif->tif_clientdata,module,"Sanity check on directory count failed"); + return(0); + } + dircount16=(uint16)dircount64; + poffc=poffb+dircount16*20; + poffd=poffc+sizeof(uint64); + if ((poffctif->tif_size)) + { + TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory link"); + return(0); + } + if (off!=NULL) + *off=(uint64)poffc; + _TIFFmemcpy(nextdir,tif->tif_base+poffc,sizeof(uint64)); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8(nextdir); } - _TIFFmemcpy(nextdir, tif->tif_base+poff, sizeof (uint32)); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(nextdir); - return (1); + return(1); } else { - if (!SeekOK(tif, *nextdir) || - !ReadOK(tif, &dircount, sizeof (uint16))) { - TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count", - tif->tif_name); - return (0); + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + uint16 dircount; + uint32 nextdir32; + if (!SeekOK(tif, *nextdir) || + !ReadOK(tif, &dircount, sizeof (uint16))) { + TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count", + tif->tif_name); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount); + if (off != NULL) + *off = TIFFSeekFile(tif, + dircount*12, SEEK_CUR); + else + (void) TIFFSeekFile(tif, + dircount*12, SEEK_CUR); + if (!ReadOK(tif, &nextdir32, sizeof (uint32))) { + TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link", + tif->tif_name); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextdir32); + *nextdir=nextdir32; } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&dircount); - if (off != NULL) - *off = TIFFSeekFile(tif, - dircount*sizeof (TIFFDirEntry), SEEK_CUR); else - (void) TIFFSeekFile(tif, - dircount*sizeof (TIFFDirEntry), SEEK_CUR); - if (!ReadOK(tif, nextdir, sizeof (uint32))) { - TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link", - tif->tif_name); - return (0); + { + uint64 dircount64; + uint16 dircount16; + if (!SeekOK(tif, *nextdir) || + !ReadOK(tif, &dircount64, sizeof (uint64))) { + TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count", + tif->tif_name); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&dircount64); + if (dircount64>0xFFFF) + { + TIFFErrorExt(tif->tif_clientdata, module, "Error fetching directory count"); + return(0); + } + dircount16 = (uint16)dircount64; + if (off != NULL) + *off = TIFFSeekFile(tif, + dircount16*20, SEEK_CUR); + else + (void) TIFFSeekFile(tif, + dircount16*20, SEEK_CUR); + if (!ReadOK(tif, nextdir, sizeof (uint64))) { + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Error fetching directory link", + tif->tif_name); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(nextdir); } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(nextdir); return (1); } } @@ -1177,15 +1501,31 @@ TIFFAdvanceDirectory(TIFF* tif, uint32* nextdir, toff_t* off) /* * Count the number of directories in a file. */ -tdir_t +uint16 TIFFNumberOfDirectories(TIFF* tif) { - toff_t nextdir = tif->tif_header.tiff_diroff; - tdir_t n = 0; - - while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL)) - n++; - return (n); + static const char module[] = "TIFFNumberOfDirectories"; + uint64 nextdir; + uint16 n; + if (!(tif->tif_flags&TIFF_BIGTIFF)) + nextdir = tif->tif_header.classic.tiff_diroff; + else + nextdir = tif->tif_header.big.tiff_diroff; + n = 0; + while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL)) + { + if (n != 65535) { + ++n; + } + else + { + TIFFErrorExt(tif->tif_clientdata, module, + "Directory count exceeded 65535 limit," + " giving up on counting."); + return (65535); + } + } + return (n); } /* @@ -1193,12 +1533,15 @@ TIFFNumberOfDirectories(TIFF* tif) * NB: Directories are numbered starting at 0. */ int -TIFFSetDirectory(TIFF* tif, tdir_t dirn) +TIFFSetDirectory(TIFF* tif, uint16 dirn) { - toff_t nextdir; - tdir_t n; + uint64 nextdir; + uint16 n; - nextdir = tif->tif_header.tiff_diroff; + if (!(tif->tif_flags&TIFF_BIGTIFF)) + nextdir = tif->tif_header.classic.tiff_diroff; + else + nextdir = tif->tif_header.big.tiff_diroff; for (n = dirn; n > 0 && nextdir != 0; n--) if (!TIFFAdvanceDirectory(tif, &nextdir, NULL)) return (0); @@ -1224,7 +1567,7 @@ TIFFSetDirectory(TIFF* tif, tdir_t dirn) * the SubIFD tag (e.g. thumbnail images). */ int -TIFFSetSubDirectory(TIFF* tif, uint32 diroff) +TIFFSetSubDirectory(TIFF* tif, uint64 diroff) { tif->tif_nextdiroff = diroff; /* @@ -1238,7 +1581,7 @@ TIFFSetSubDirectory(TIFF* tif, uint32 diroff) /* * Return file offset of the current directory. */ -uint32 +uint64 TIFFCurrentDirOffset(TIFF* tif) { return (tif->tif_diroff); @@ -1258,12 +1601,12 @@ TIFFLastDirectory(TIFF* tif) * Unlink the specified directory from the directory chain. */ int -TIFFUnlinkDirectory(TIFF* tif, tdir_t dirn) +TIFFUnlinkDirectory(TIFF* tif, uint16 dirn) { static const char module[] = "TIFFUnlinkDirectory"; - toff_t nextdir; - toff_t off; - tdir_t n; + uint64 nextdir; + uint64 off; + uint16 n; if (tif->tif_mode == O_RDONLY) { TIFFErrorExt(tif->tif_clientdata, module, @@ -1275,8 +1618,16 @@ TIFFUnlinkDirectory(TIFF* tif, tdir_t dirn) * to unlink and nab the offset of the link * field we'll need to patch. */ - nextdir = tif->tif_header.tiff_diroff; - off = sizeof (uint16) + sizeof (uint16); + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + nextdir = tif->tif_header.classic.tiff_diroff; + off = 4; + } + else + { + nextdir = tif->tif_header.big.tiff_diroff; + off = 8; + } for (n = dirn-1; n > 0; n--) { if (nextdir == 0) { TIFFErrorExt(tif->tif_clientdata, module, "Directory %d does not exist", dirn); @@ -1297,11 +1648,26 @@ TIFFUnlinkDirectory(TIFF* tif, tdir_t dirn) * that follows. */ (void) TIFFSeekFile(tif, off, SEEK_SET); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&nextdir); - if (!WriteOK(tif, &nextdir, sizeof (uint32))) { - TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link"); - return (0); + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + uint32 nextdir32; + nextdir32=(uint32)nextdir; + assert((uint64)nextdir32==nextdir); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextdir32); + if (!WriteOK(tif, &nextdir32, sizeof (uint32))) { + TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link"); + return (0); + } + } + else + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&nextdir); + if (!WriteOK(tif, &nextdir, sizeof (uint64))) { + TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link"); + return (0); + } } /* * Leave directory state setup safely. We don't have @@ -1315,70 +1681,20 @@ TIFFUnlinkDirectory(TIFF* tif, tdir_t dirn) _TIFFfree(tif->tif_rawdata); tif->tif_rawdata = NULL; tif->tif_rawcc = 0; + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = 0; } - tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP|TIFF_POSTENCODE); + tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP|TIFF_POSTENCODE|TIFF_BUF4WRITE); TIFFFreeDirectory(tif); TIFFDefaultDirectory(tif); tif->tif_diroff = 0; /* force link on next write */ tif->tif_nextdiroff = 0; /* next write must be at end */ tif->tif_curoff = 0; tif->tif_row = (uint32) -1; - tif->tif_curstrip = (tstrip_t) -1; + tif->tif_curstrip = (uint32) -1; return (1); } -/* [BFC] - * - * Author: Bruce Cameron - * - * Set a table of tags that are to be replaced during directory process by the - * 'IGNORE' state - or return TRUE/FALSE for the requested tag such that - * 'ReadDirectory' can use the stored information. - * - * FIXME: this is never used properly. Should be removed in the future. - */ -int -TIFFReassignTagToIgnore (enum TIFFIgnoreSense task, int TIFFtagID) -{ - static int TIFFignoretags [FIELD_LAST]; - static int tagcount = 0 ; - int i; /* Loop index */ - int j; /* Loop index */ - - switch (task) - { - case TIS_STORE: - if ( tagcount < (FIELD_LAST - 1) ) - { - for ( j = 0 ; j < tagcount ; ++j ) - { /* Do not add duplicate tag */ - if ( TIFFignoretags [j] == TIFFtagID ) - return (TRUE) ; - } - TIFFignoretags [tagcount++] = TIFFtagID ; - return (TRUE) ; - } - break ; - - case TIS_EXTRACT: - for ( i = 0 ; i < tagcount ; ++i ) - { - if ( TIFFignoretags [i] == TIFFtagID ) - return (TRUE) ; - } - break; - - case TIS_EMPTY: - tagcount = 0 ; /* Clear the list */ - return (TRUE) ; - - default: - break; - } - - return (FALSE); -} - /* vim: set ts=8 sts=8 sw=8 noet: */ /* * Local Variables: diff --git a/thirdparty/libtiff/tif_dir.h b/thirdparty/libtiff/tif_dir.h index 515af199..6af5f3dc 100644 --- a/thirdparty/libtiff/tif_dir.h +++ b/thirdparty/libtiff/tif_dir.h @@ -1,4 +1,4 @@ -/* $Id: tif_dir.h,v 1.30.2.3 2010-06-09 21:15:27 bfriesen Exp $ */ +/* $Id: tif_dir.h,v 1.54 2011-02-18 20:53:05 fwarmerdam Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -30,13 +30,41 @@ * ``Library-private'' Directory-related Definitions. */ +typedef struct { + const TIFFField *info; + int count; + void *value; +} TIFFTagValue; + +/* + * TIFF Image File Directories are comprised of a table of field + * descriptors of the form shown below. The table is sorted in + * ascending order by tag. The values associated with each entry are + * disjoint and may appear anywhere in the file (so long as they are + * placed on a word boundary). + * + * If the value is 4 bytes or less, in ClassicTIFF, or 8 bytes or less in + * BigTIFF, then it is placed in the offset field to save space. If so, + * it is left-justified in the offset field. + */ +typedef struct { + uint16 tdir_tag; /* see below */ + uint16 tdir_type; /* data type; see below */ + uint64 tdir_count; /* number of items; length in spec */ + union { + uint16 toff_short; + uint32 toff_long; + uint64 toff_long8; + } tdir_offset; /* either offset or the data itself if fits */ +} TIFFDirEntry; + /* * Internal format of a TIFF directory entry. */ -typedef struct { -#define FIELD_SETLONGS 4 +typedef struct { +#define FIELD_SETLONGS 4 /* bit vector of fields that are set */ - unsigned long td_fieldsset[FIELD_SETLONGS]; + unsigned long td_fieldsset[FIELD_SETLONGS]; uint32 td_imagewidth, td_imagelength, td_imagedepth; uint32 td_tilewidth, td_tilelength, td_tiledepth; @@ -51,7 +79,8 @@ typedef struct { uint16 td_samplesperpixel; uint32 td_rowsperstrip; uint16 td_minsamplevalue, td_maxsamplevalue; - double td_sminsamplevalue, td_smaxsamplevalue; + double* td_sminsamplevalue; + double* td_smaxsamplevalue; float td_xresolution, td_yresolution; uint16 td_resolutionunit; uint16 td_planarconfig; @@ -64,19 +93,23 @@ typedef struct { /* even though the name is misleading, td_stripsperimage is the number * of striles (=strips or tiles) per plane, and td_nstrips the total * number of striles */ - tstrile_t td_stripsperimage; - tstrile_t td_nstrips; /* size of offset & bytecount arrays */ - toff_t* td_stripoffset; - toff_t* td_stripbytecount; /* FIXME: it should be tsize_t array */ + uint32 td_stripsperimage; + uint32 td_nstrips; /* size of offset & bytecount arrays */ + uint64* td_stripoffset; + uint64* td_stripbytecount; int td_stripbytecountsorted; /* is the bytecount array sorted ascending? */ +#if defined(DEFER_STRILE_LOAD) + TIFFDirEntry td_stripoffset_entry; /* for deferred loading */ + TIFFDirEntry td_stripbytecount_entry; /* for deferred loading */ +#endif uint16 td_nsubifd; - uint32* td_subifd; + uint64* td_subifd; /* YCbCr parameters */ uint16 td_ycbcrsubsampling[2]; uint16 td_ycbcrpositioning; /* Colorimetry parameters */ - float* td_refblackwhite; uint16* td_transferfunction[3]; + float* td_refblackwhite; /* CMYK parameters */ int td_inknameslen; char* td_inknames; @@ -86,115 +119,178 @@ typedef struct { } TIFFDirectory; /* - * Field flags used to indicate fields that have - * been set in a directory, and to reference fields - * when manipulating a directory. + * Field flags used to indicate fields that have been set in a directory, and + * to reference fields when manipulating a directory. */ /* - * FIELD_IGNORE is used to signify tags that are to - * be processed but otherwise ignored. This permits - * antiquated tags to be quietly read and discarded. - * Note that a bit *is* allocated for ignored tags; - * this is understood by the directory reading logic - * which uses this fact to avoid special-case handling - */ -#define FIELD_IGNORE 0 + * FIELD_IGNORE is used to signify tags that are to be processed but otherwise + * ignored. This permits antiquated tags to be quietly read and discarded. + * Note that a bit *is* allocated for ignored tags; this is understood by the + * directory reading logic which uses this fact to avoid special-case handling + */ +#define FIELD_IGNORE 0 /* multi-item fields */ -#define FIELD_IMAGEDIMENSIONS 1 -#define FIELD_TILEDIMENSIONS 2 -#define FIELD_RESOLUTION 3 -#define FIELD_POSITION 4 +#define FIELD_IMAGEDIMENSIONS 1 +#define FIELD_TILEDIMENSIONS 2 +#define FIELD_RESOLUTION 3 +#define FIELD_POSITION 4 /* single-item fields */ -#define FIELD_SUBFILETYPE 5 -#define FIELD_BITSPERSAMPLE 6 -#define FIELD_COMPRESSION 7 -#define FIELD_PHOTOMETRIC 8 -#define FIELD_THRESHHOLDING 9 -#define FIELD_FILLORDER 10 -#define FIELD_ORIENTATION 15 -#define FIELD_SAMPLESPERPIXEL 16 -#define FIELD_ROWSPERSTRIP 17 -#define FIELD_MINSAMPLEVALUE 18 -#define FIELD_MAXSAMPLEVALUE 19 -#define FIELD_PLANARCONFIG 20 -#define FIELD_RESOLUTIONUNIT 22 -#define FIELD_PAGENUMBER 23 -#define FIELD_STRIPBYTECOUNTS 24 -#define FIELD_STRIPOFFSETS 25 -#define FIELD_COLORMAP 26 -#define FIELD_EXTRASAMPLES 31 -#define FIELD_SAMPLEFORMAT 32 -#define FIELD_SMINSAMPLEVALUE 33 -#define FIELD_SMAXSAMPLEVALUE 34 -#define FIELD_IMAGEDEPTH 35 -#define FIELD_TILEDEPTH 36 -#define FIELD_HALFTONEHINTS 37 -#define FIELD_YCBCRSUBSAMPLING 39 -#define FIELD_YCBCRPOSITIONING 40 -#define FIELD_REFBLACKWHITE 41 -#define FIELD_TRANSFERFUNCTION 44 -#define FIELD_INKNAMES 46 -#define FIELD_SUBIFD 49 -/* FIELD_CUSTOM (see tiffio.h) 65 */ +#define FIELD_SUBFILETYPE 5 +#define FIELD_BITSPERSAMPLE 6 +#define FIELD_COMPRESSION 7 +#define FIELD_PHOTOMETRIC 8 +#define FIELD_THRESHHOLDING 9 +#define FIELD_FILLORDER 10 +#define FIELD_ORIENTATION 15 +#define FIELD_SAMPLESPERPIXEL 16 +#define FIELD_ROWSPERSTRIP 17 +#define FIELD_MINSAMPLEVALUE 18 +#define FIELD_MAXSAMPLEVALUE 19 +#define FIELD_PLANARCONFIG 20 +#define FIELD_RESOLUTIONUNIT 22 +#define FIELD_PAGENUMBER 23 +#define FIELD_STRIPBYTECOUNTS 24 +#define FIELD_STRIPOFFSETS 25 +#define FIELD_COLORMAP 26 +#define FIELD_EXTRASAMPLES 31 +#define FIELD_SAMPLEFORMAT 32 +#define FIELD_SMINSAMPLEVALUE 33 +#define FIELD_SMAXSAMPLEVALUE 34 +#define FIELD_IMAGEDEPTH 35 +#define FIELD_TILEDEPTH 36 +#define FIELD_HALFTONEHINTS 37 +#define FIELD_YCBCRSUBSAMPLING 39 +#define FIELD_YCBCRPOSITIONING 40 +#define FIELD_REFBLACKWHITE 41 +#define FIELD_TRANSFERFUNCTION 44 +#define FIELD_INKNAMES 46 +#define FIELD_SUBIFD 49 +/* FIELD_CUSTOM (see tiffio.h) 65 */ /* end of support for well-known tags; codec-private tags follow */ -#define FIELD_CODEC 66 /* base of codec-private tags */ +#define FIELD_CODEC 66 /* base of codec-private tags */ /* - * Pseudo-tags don't normally need field bits since they - * are not written to an output file (by definition). - * The library also has express logic to always query a - * codec for a pseudo-tag so allocating a field bit for - * one is a waste. If codec wants to promote the notion - * of a pseudo-tag being ``set'' or ``unset'' then it can - * do using internal state flags without polluting the - * field bit space defined for real tags. + * Pseudo-tags don't normally need field bits since they are not written to an + * output file (by definition). The library also has express logic to always + * query a codec for a pseudo-tag so allocating a field bit for one is a + * waste. If codec wants to promote the notion of a pseudo-tag being ``set'' + * or ``unset'' then it can do using internal state flags without polluting + * the field bit space defined for real tags. */ -#define FIELD_PSEUDO 0 +#define FIELD_PSEUDO 0 -#define FIELD_LAST (32*FIELD_SETLONGS-1) +#define FIELD_LAST (32*FIELD_SETLONGS-1) -#define TIFFExtractData(tif, type, v) \ - ((uint32) ((tif)->tif_header.tiff_magic == TIFF_BIGENDIAN ? \ - ((v) >> (tif)->tif_typeshift[type]) & (tif)->tif_typemask[type] : \ - (v) & (tif)->tif_typemask[type])) -#define TIFFInsertData(tif, type, v) \ - ((uint32) ((tif)->tif_header.tiff_magic == TIFF_BIGENDIAN ? \ - ((v) & (tif)->tif_typemask[type]) << (tif)->tif_typeshift[type] : \ - (v) & (tif)->tif_typemask[type])) - - -#define BITn(n) (((unsigned long)1L)<<((n)&0x1f)) -#define BITFIELDn(tif, n) ((tif)->tif_dir.td_fieldsset[(n)/32]) -#define TIFFFieldSet(tif, field) (BITFIELDn(tif, field) & BITn(field)) +#define BITn(n) (((unsigned long)1L)<<((n)&0x1f)) +#define BITFIELDn(tif, n) ((tif)->tif_dir.td_fieldsset[(n)/32]) +#define TIFFFieldSet(tif, field) (BITFIELDn(tif, field) & BITn(field)) #define TIFFSetFieldBit(tif, field) (BITFIELDn(tif, field) |= BITn(field)) #define TIFFClrFieldBit(tif, field) (BITFIELDn(tif, field) &= ~BITn(field)) -#define FieldSet(fields, f) (fields[(f)/32] & BITn(f)) -#define ResetFieldBit(fields, f) (fields[(f)/32] &= ~BITn(f)) +#define FieldSet(fields, f) (fields[(f)/32] & BITn(f)) +#define ResetFieldBit(fields, f) (fields[(f)/32] &= ~BITn(f)) + +typedef enum { + TIFF_SETGET_UNDEFINED = 0, + TIFF_SETGET_ASCII = 1, + TIFF_SETGET_UINT8 = 2, + TIFF_SETGET_SINT8 = 3, + TIFF_SETGET_UINT16 = 4, + TIFF_SETGET_SINT16 = 5, + TIFF_SETGET_UINT32 = 6, + TIFF_SETGET_SINT32 = 7, + TIFF_SETGET_UINT64 = 8, + TIFF_SETGET_SINT64 = 9, + TIFF_SETGET_FLOAT = 10, + TIFF_SETGET_DOUBLE = 11, + TIFF_SETGET_IFD8 = 12, + TIFF_SETGET_INT = 13, + TIFF_SETGET_UINT16_PAIR = 14, + TIFF_SETGET_C0_ASCII = 15, + TIFF_SETGET_C0_UINT8 = 16, + TIFF_SETGET_C0_SINT8 = 17, + TIFF_SETGET_C0_UINT16 = 18, + TIFF_SETGET_C0_SINT16 = 19, + TIFF_SETGET_C0_UINT32 = 20, + TIFF_SETGET_C0_SINT32 = 21, + TIFF_SETGET_C0_UINT64 = 22, + TIFF_SETGET_C0_SINT64 = 23, + TIFF_SETGET_C0_FLOAT = 24, + TIFF_SETGET_C0_DOUBLE = 25, + TIFF_SETGET_C0_IFD8 = 26, + TIFF_SETGET_C16_ASCII = 27, + TIFF_SETGET_C16_UINT8 = 28, + TIFF_SETGET_C16_SINT8 = 29, + TIFF_SETGET_C16_UINT16 = 30, + TIFF_SETGET_C16_SINT16 = 31, + TIFF_SETGET_C16_UINT32 = 32, + TIFF_SETGET_C16_SINT32 = 33, + TIFF_SETGET_C16_UINT64 = 34, + TIFF_SETGET_C16_SINT64 = 35, + TIFF_SETGET_C16_FLOAT = 36, + TIFF_SETGET_C16_DOUBLE = 37, + TIFF_SETGET_C16_IFD8 = 38, + TIFF_SETGET_C32_ASCII = 39, + TIFF_SETGET_C32_UINT8 = 40, + TIFF_SETGET_C32_SINT8 = 41, + TIFF_SETGET_C32_UINT16 = 42, + TIFF_SETGET_C32_SINT16 = 43, + TIFF_SETGET_C32_UINT32 = 44, + TIFF_SETGET_C32_SINT32 = 45, + TIFF_SETGET_C32_UINT64 = 46, + TIFF_SETGET_C32_SINT64 = 47, + TIFF_SETGET_C32_FLOAT = 48, + TIFF_SETGET_C32_DOUBLE = 49, + TIFF_SETGET_C32_IFD8 = 50, + TIFF_SETGET_OTHER = 51 +} TIFFSetGetFieldType; #if defined(__cplusplus) extern "C" { #endif -extern const TIFFFieldInfo *_TIFFGetFieldInfo(size_t *); -extern const TIFFFieldInfo *_TIFFGetExifFieldInfo(size_t *); -extern void _TIFFSetupFieldInfo(TIFF*, const TIFFFieldInfo[], size_t); -extern int _TIFFMergeFieldInfo(TIFF*, const TIFFFieldInfo[], int); -extern void _TIFFPrintFieldInfo(TIFF*, FILE*); -extern TIFFDataType _TIFFSampleToTagType(TIFF*); -extern const TIFFFieldInfo* _TIFFFindOrRegisterFieldInfo( TIFF *tif, - ttag_t tag, - TIFFDataType dt ); -extern TIFFFieldInfo* _TIFFCreateAnonFieldInfo( TIFF *tif, ttag_t tag, - TIFFDataType dt ); -#define _TIFFFindFieldInfo TIFFFindFieldInfo -#define _TIFFFindFieldInfoByName TIFFFindFieldInfoByName -#define _TIFFFieldWithTag TIFFFieldWithTag -#define _TIFFFieldWithName TIFFFieldWithName +extern const TIFFFieldArray* _TIFFGetFields(void); +extern const TIFFFieldArray* _TIFFGetExifFields(void); +extern void _TIFFSetupFields(TIFF* tif, const TIFFFieldArray* infoarray); +extern void _TIFFPrintFieldInfo(TIFF*, FILE*); + +extern int _TIFFFillStriles(TIFF*); + +typedef enum { + tfiatImage, + tfiatExif, + tfiatOther +} TIFFFieldArrayType; + +struct _TIFFFieldArray { + TIFFFieldArrayType type; /* array type, will be used to determine if IFD is image and such */ + uint32 allocated_size; /* 0 if array is constant, other if modified by future definition extension support */ + uint32 count; /* number of elements in fields array */ + TIFFField* fields; /* actual field info */ +}; + +struct _TIFFField { + uint32 field_tag; /* field's tag */ + short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */ + short field_writecount; /* write count/TIFF_VARIABLE */ + TIFFDataType field_type; /* type of associated data */ + uint32 reserved; /* reserved for future extension */ + TIFFSetGetFieldType set_field_type; /* type to be passed to TIFFSetField */ + TIFFSetGetFieldType get_field_type; /* type to be passed to TIFFGetField */ + unsigned short field_bit; /* bit in fieldsset bit vector */ + unsigned char field_oktochange; /* if true, can change while writing */ + unsigned char field_passcount; /* if true, pass dir count on set */ + char* field_name; /* ASCII name */ + TIFFFieldArray* field_subfields; /* if field points to child ifds, child ifd field definition array */ +}; + +extern int _TIFFMergeFields(TIFF*, const TIFFField[], uint32); +extern const TIFFField* _TIFFFindOrRegisterField(TIFF *, uint32, TIFFDataType); +extern TIFFField* _TIFFCreateAnonField(TIFF *, uint32, TIFFDataType); #if defined(__cplusplus) } @@ -202,6 +298,7 @@ extern TIFFFieldInfo* _TIFFCreateAnonFieldInfo( TIFF *tif, ttag_t tag, #endif /* _TIFFDIR_ */ /* vim: set ts=8 sts=8 sw=8 noet: */ + /* * Local Variables: * mode: c diff --git a/thirdparty/libtiff/tif_dirinfo.c b/thirdparty/libtiff/tif_dirinfo.c index 57c29d55..7db4bdb9 100644 --- a/thirdparty/libtiff/tif_dirinfo.c +++ b/thirdparty/libtiff/tif_dirinfo.c @@ -1,26 +1,26 @@ -/* $Id: tif_dirinfo.c,v 1.65.2.9 2010-06-09 21:15:27 bfriesen Exp $ */ +/* $Id: tif_dirinfo.c,v 1.121 2014-05-07 01:58:46 bfriesen Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -31,523 +31,303 @@ */ #include "tiffiop.h" #include -#include /* - * NB: NB: THIS ARRAY IS ASSUMED TO BE SORTED BY TAG. - * If a tag can have both LONG and SHORT types then the LONG must be - * placed before the SHORT for writing to work properly. + * NOTE: THIS ARRAY IS ASSUMED TO BE SORTED BY TAG. * * 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 interprete the -1, -2 and -3 * values accordingly. */ -static const TIFFFieldInfo -tiffFieldInfo[] = { - { TIFFTAG_SUBFILETYPE, 1, 1, TIFF_LONG, FIELD_SUBFILETYPE, - 1, 0, "SubfileType" }, -/* XXX SHORT for compatibility w/ old versions of the library */ - { TIFFTAG_SUBFILETYPE, 1, 1, TIFF_SHORT, FIELD_SUBFILETYPE, - 1, 0, "SubfileType" }, - { TIFFTAG_OSUBFILETYPE, 1, 1, TIFF_SHORT, FIELD_SUBFILETYPE, - 1, 0, "OldSubfileType" }, - { TIFFTAG_IMAGEWIDTH, 1, 1, TIFF_LONG, FIELD_IMAGEDIMENSIONS, - 0, 0, "ImageWidth" }, - { TIFFTAG_IMAGEWIDTH, 1, 1, TIFF_SHORT, FIELD_IMAGEDIMENSIONS, - 0, 0, "ImageWidth" }, - { TIFFTAG_IMAGELENGTH, 1, 1, TIFF_LONG, FIELD_IMAGEDIMENSIONS, - 1, 0, "ImageLength" }, - { TIFFTAG_IMAGELENGTH, 1, 1, TIFF_SHORT, FIELD_IMAGEDIMENSIONS, - 1, 0, "ImageLength" }, - { TIFFTAG_BITSPERSAMPLE, -1,-1, TIFF_SHORT, FIELD_BITSPERSAMPLE, - 0, 0, "BitsPerSample" }, -/* XXX LONG for compatibility with some broken TIFF writers */ - { TIFFTAG_BITSPERSAMPLE, -1,-1, TIFF_LONG, FIELD_BITSPERSAMPLE, - 0, 0, "BitsPerSample" }, - { TIFFTAG_COMPRESSION, -1, 1, TIFF_SHORT, FIELD_COMPRESSION, - 0, 0, "Compression" }, -/* XXX LONG for compatibility with some broken TIFF writers */ - { TIFFTAG_COMPRESSION, -1, 1, TIFF_LONG, FIELD_COMPRESSION, - 0, 0, "Compression" }, - { TIFFTAG_PHOTOMETRIC, 1, 1, TIFF_SHORT, FIELD_PHOTOMETRIC, - 0, 0, "PhotometricInterpretation" }, -/* XXX LONG for compatibility with some broken TIFF writers */ - { TIFFTAG_PHOTOMETRIC, 1, 1, TIFF_LONG, FIELD_PHOTOMETRIC, - 0, 0, "PhotometricInterpretation" }, - { TIFFTAG_THRESHHOLDING, 1, 1, TIFF_SHORT, FIELD_THRESHHOLDING, - 1, 0, "Threshholding" }, - { TIFFTAG_CELLWIDTH, 1, 1, TIFF_SHORT, FIELD_IGNORE, - 1, 0, "CellWidth" }, - { TIFFTAG_CELLLENGTH, 1, 1, TIFF_SHORT, FIELD_IGNORE, - 1, 0, "CellLength" }, - { TIFFTAG_FILLORDER, 1, 1, TIFF_SHORT, FIELD_FILLORDER, - 0, 0, "FillOrder" }, - { TIFFTAG_DOCUMENTNAME, -1,-1, TIFF_ASCII, FIELD_CUSTOM, - 1, 0, "DocumentName" }, - { TIFFTAG_IMAGEDESCRIPTION, -1,-1, TIFF_ASCII, FIELD_CUSTOM, - 1, 0, "ImageDescription" }, - { TIFFTAG_MAKE, -1,-1, TIFF_ASCII, FIELD_CUSTOM, - 1, 0, "Make" }, - { TIFFTAG_MODEL, -1,-1, TIFF_ASCII, FIELD_CUSTOM, - 1, 0, "Model" }, - { TIFFTAG_STRIPOFFSETS, -1,-1, TIFF_LONG, FIELD_STRIPOFFSETS, - 0, 0, "StripOffsets" }, - { TIFFTAG_STRIPOFFSETS, -1,-1, TIFF_SHORT, FIELD_STRIPOFFSETS, - 0, 0, "StripOffsets" }, - { TIFFTAG_ORIENTATION, 1, 1, TIFF_SHORT, FIELD_ORIENTATION, - 0, 0, "Orientation" }, - { TIFFTAG_SAMPLESPERPIXEL, 1, 1, TIFF_SHORT, FIELD_SAMPLESPERPIXEL, - 0, 0, "SamplesPerPixel" }, - { TIFFTAG_ROWSPERSTRIP, 1, 1, TIFF_LONG, FIELD_ROWSPERSTRIP, - 0, 0, "RowsPerStrip" }, - { TIFFTAG_ROWSPERSTRIP, 1, 1, TIFF_SHORT, FIELD_ROWSPERSTRIP, - 0, 0, "RowsPerStrip" }, - { TIFFTAG_STRIPBYTECOUNTS, -1,-1, TIFF_LONG, FIELD_STRIPBYTECOUNTS, - 0, 0, "StripByteCounts" }, - { TIFFTAG_STRIPBYTECOUNTS, -1,-1, TIFF_SHORT, FIELD_STRIPBYTECOUNTS, - 0, 0, "StripByteCounts" }, - { TIFFTAG_MINSAMPLEVALUE, -2,-1, TIFF_SHORT, FIELD_MINSAMPLEVALUE, - 1, 0, "MinSampleValue" }, - { TIFFTAG_MAXSAMPLEVALUE, -2,-1, TIFF_SHORT, FIELD_MAXSAMPLEVALUE, - 1, 0, "MaxSampleValue" }, - { TIFFTAG_XRESOLUTION, 1, 1, TIFF_RATIONAL, FIELD_RESOLUTION, - 1, 0, "XResolution" }, - { TIFFTAG_YRESOLUTION, 1, 1, TIFF_RATIONAL, FIELD_RESOLUTION, - 1, 0, "YResolution" }, - { TIFFTAG_PLANARCONFIG, 1, 1, TIFF_SHORT, FIELD_PLANARCONFIG, - 0, 0, "PlanarConfiguration" }, - { TIFFTAG_PAGENAME, -1,-1, TIFF_ASCII, FIELD_CUSTOM, - 1, 0, "PageName" }, - { TIFFTAG_XPOSITION, 1, 1, TIFF_RATIONAL, FIELD_POSITION, - 1, 0, "XPosition" }, - { TIFFTAG_YPOSITION, 1, 1, TIFF_RATIONAL, FIELD_POSITION, - 1, 0, "YPosition" }, - { TIFFTAG_FREEOFFSETS, -1,-1, TIFF_LONG, FIELD_IGNORE, - 0, 0, "FreeOffsets" }, - { TIFFTAG_FREEBYTECOUNTS, -1,-1, TIFF_LONG, FIELD_IGNORE, - 0, 0, "FreeByteCounts" }, - { TIFFTAG_GRAYRESPONSEUNIT, 1, 1, TIFF_SHORT, FIELD_IGNORE, - 1, 0, "GrayResponseUnit" }, - { TIFFTAG_GRAYRESPONSECURVE,-1,-1, TIFF_SHORT, FIELD_IGNORE, - 1, 0, "GrayResponseCurve" }, - { TIFFTAG_RESOLUTIONUNIT, 1, 1, TIFF_SHORT, FIELD_RESOLUTIONUNIT, - 1, 0, "ResolutionUnit" }, - { TIFFTAG_PAGENUMBER, 2, 2, TIFF_SHORT, FIELD_PAGENUMBER, - 1, 0, "PageNumber" }, - { TIFFTAG_COLORRESPONSEUNIT, 1, 1, TIFF_SHORT, FIELD_IGNORE, - 1, 0, "ColorResponseUnit" }, - { TIFFTAG_TRANSFERFUNCTION, -1,-1, TIFF_SHORT, FIELD_TRANSFERFUNCTION, - 1, 0, "TransferFunction" }, - { TIFFTAG_SOFTWARE, -1,-1, TIFF_ASCII, FIELD_CUSTOM, - 1, 0, "Software" }, - { TIFFTAG_DATETIME, 20,20, TIFF_ASCII, FIELD_CUSTOM, - 1, 0, "DateTime" }, - { TIFFTAG_ARTIST, -1,-1, TIFF_ASCII, FIELD_CUSTOM, - 1, 0, "Artist" }, - { TIFFTAG_HOSTCOMPUTER, -1,-1, TIFF_ASCII, FIELD_CUSTOM, - 1, 0, "HostComputer" }, - { TIFFTAG_WHITEPOINT, 2, 2, TIFF_RATIONAL, FIELD_CUSTOM, - 1, 0, "WhitePoint" }, - { TIFFTAG_PRIMARYCHROMATICITIES,6,6,TIFF_RATIONAL, FIELD_CUSTOM, - 1, 0, "PrimaryChromaticities" }, - { TIFFTAG_COLORMAP, -1,-1, TIFF_SHORT, FIELD_COLORMAP, - 1, 0, "ColorMap" }, - { TIFFTAG_HALFTONEHINTS, 2, 2, TIFF_SHORT, FIELD_HALFTONEHINTS, - 1, 0, "HalftoneHints" }, - { TIFFTAG_TILEWIDTH, 1, 1, TIFF_LONG, FIELD_TILEDIMENSIONS, - 0, 0, "TileWidth" }, - { TIFFTAG_TILEWIDTH, 1, 1, TIFF_SHORT, FIELD_TILEDIMENSIONS, - 0, 0, "TileWidth" }, - { TIFFTAG_TILELENGTH, 1, 1, TIFF_LONG, FIELD_TILEDIMENSIONS, - 0, 0, "TileLength" }, - { TIFFTAG_TILELENGTH, 1, 1, TIFF_SHORT, FIELD_TILEDIMENSIONS, - 0, 0, "TileLength" }, - { TIFFTAG_TILEOFFSETS, -1, 1, TIFF_LONG, FIELD_STRIPOFFSETS, - 0, 0, "TileOffsets" }, - { TIFFTAG_TILEBYTECOUNTS, -1, 1, TIFF_LONG, FIELD_STRIPBYTECOUNTS, - 0, 0, "TileByteCounts" }, - { TIFFTAG_TILEBYTECOUNTS, -1, 1, TIFF_SHORT, FIELD_STRIPBYTECOUNTS, - 0, 0, "TileByteCounts" }, - { TIFFTAG_SUBIFD, -1,-1, TIFF_IFD, FIELD_SUBIFD, - 1, 1, "SubIFD" }, - { TIFFTAG_SUBIFD, -1,-1, TIFF_LONG, FIELD_SUBIFD, - 1, 1, "SubIFD" }, - { TIFFTAG_INKSET, 1, 1, TIFF_SHORT, FIELD_CUSTOM, - 0, 0, "InkSet" }, - { TIFFTAG_INKNAMES, -1,-1, TIFF_ASCII, FIELD_INKNAMES, - 1, 1, "InkNames" }, - { TIFFTAG_NUMBEROFINKS, 1, 1, TIFF_SHORT, FIELD_CUSTOM, - 1, 0, "NumberOfInks" }, - { TIFFTAG_DOTRANGE, 2, 2, TIFF_SHORT, FIELD_CUSTOM, - 0, 0, "DotRange" }, - { TIFFTAG_DOTRANGE, 2, 2, TIFF_BYTE, FIELD_CUSTOM, - 0, 0, "DotRange" }, - { TIFFTAG_TARGETPRINTER, -1,-1, TIFF_ASCII, FIELD_CUSTOM, - 1, 0, "TargetPrinter" }, - { TIFFTAG_EXTRASAMPLES, -1,-1, TIFF_SHORT, FIELD_EXTRASAMPLES, - 0, 1, "ExtraSamples" }, -/* XXX for bogus Adobe Photoshop v2.5 files */ - { TIFFTAG_EXTRASAMPLES, -1,-1, TIFF_BYTE, FIELD_EXTRASAMPLES, - 0, 1, "ExtraSamples" }, - { TIFFTAG_SAMPLEFORMAT, -1,-1, TIFF_SHORT, FIELD_SAMPLEFORMAT, - 0, 0, "SampleFormat" }, - { TIFFTAG_SMINSAMPLEVALUE, -2,-1, TIFF_ANY, FIELD_SMINSAMPLEVALUE, - 1, 0, "SMinSampleValue" }, - { TIFFTAG_SMAXSAMPLEVALUE, -2,-1, TIFF_ANY, FIELD_SMAXSAMPLEVALUE, - 1, 0, "SMaxSampleValue" }, - { TIFFTAG_CLIPPATH, -1, -3, TIFF_BYTE, FIELD_CUSTOM, - 0, 1, "ClipPath" }, - { TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_SLONG, FIELD_CUSTOM, - 0, 0, "XClipPathUnits" }, - { TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_SSHORT, FIELD_CUSTOM, - 0, 0, "XClipPathUnits" }, - { TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_SBYTE, FIELD_CUSTOM, - 0, 0, "XClipPathUnits" }, - { TIFFTAG_YCLIPPATHUNITS, 1, 1, TIFF_SLONG, FIELD_CUSTOM, - 0, 0, "YClipPathUnits" }, - { TIFFTAG_YCLIPPATHUNITS, 1, 1, TIFF_SSHORT, FIELD_CUSTOM, - 0, 0, "YClipPathUnits" }, - { TIFFTAG_YCLIPPATHUNITS, 1, 1, TIFF_SBYTE, FIELD_CUSTOM, - 0, 0, "YClipPathUnits" }, - { TIFFTAG_YCBCRCOEFFICIENTS, 3, 3, TIFF_RATIONAL, FIELD_CUSTOM, - 0, 0, "YCbCrCoefficients" }, - { TIFFTAG_YCBCRSUBSAMPLING, 2, 2, TIFF_SHORT, FIELD_YCBCRSUBSAMPLING, - 0, 0, "YCbCrSubsampling" }, - { TIFFTAG_YCBCRPOSITIONING, 1, 1, TIFF_SHORT, FIELD_YCBCRPOSITIONING, - 0, 0, "YCbCrPositioning" }, - { TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_RATIONAL, FIELD_REFBLACKWHITE, - 1, 0, "ReferenceBlackWhite" }, -/* XXX temporarily accept LONG for backwards compatibility */ - { TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_LONG, FIELD_REFBLACKWHITE, - 1, 0, "ReferenceBlackWhite" }, - { TIFFTAG_XMLPACKET, -3,-3, TIFF_BYTE, FIELD_CUSTOM, - 0, 1, "XMLPacket" }, -/* begin SGI tags */ - { TIFFTAG_MATTEING, 1, 1, TIFF_SHORT, FIELD_EXTRASAMPLES, - 0, 0, "Matteing" }, - { TIFFTAG_DATATYPE, -2,-1, TIFF_SHORT, FIELD_SAMPLEFORMAT, - 0, 0, "DataType" }, - { TIFFTAG_IMAGEDEPTH, 1, 1, TIFF_LONG, FIELD_IMAGEDEPTH, - 0, 0, "ImageDepth" }, - { TIFFTAG_IMAGEDEPTH, 1, 1, TIFF_SHORT, FIELD_IMAGEDEPTH, - 0, 0, "ImageDepth" }, - { TIFFTAG_TILEDEPTH, 1, 1, TIFF_LONG, FIELD_TILEDEPTH, - 0, 0, "TileDepth" }, - { TIFFTAG_TILEDEPTH, 1, 1, TIFF_SHORT, FIELD_TILEDEPTH, - 0, 0, "TileDepth" }, -/* end SGI tags */ -/* begin Pixar tags */ - { TIFFTAG_PIXAR_IMAGEFULLWIDTH, 1, 1, TIFF_LONG, FIELD_CUSTOM, - 1, 0, "ImageFullWidth" }, - { TIFFTAG_PIXAR_IMAGEFULLLENGTH, 1, 1, TIFF_LONG, FIELD_CUSTOM, - 1, 0, "ImageFullLength" }, - { TIFFTAG_PIXAR_TEXTUREFORMAT, -1, -1, TIFF_ASCII, FIELD_CUSTOM, - 1, 0, "TextureFormat" }, - { TIFFTAG_PIXAR_WRAPMODES, -1, -1, TIFF_ASCII, FIELD_CUSTOM, - 1, 0, "TextureWrapModes" }, - { TIFFTAG_PIXAR_FOVCOT, 1, 1, TIFF_FLOAT, FIELD_CUSTOM, - 1, 0, "FieldOfViewCotangent" }, - { TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN, 16,16, TIFF_FLOAT, - FIELD_CUSTOM, 1, 0, "MatrixWorldToScreen" }, - { TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA, 16,16, TIFF_FLOAT, - FIELD_CUSTOM, 1, 0, "MatrixWorldToCamera" }, - { TIFFTAG_COPYRIGHT, -1, -1, TIFF_ASCII, FIELD_CUSTOM, - 1, 0, "Copyright" }, -/* end Pixar tags */ - { TIFFTAG_RICHTIFFIPTC, -3, -3, TIFF_LONG, FIELD_CUSTOM, - 0, 1, "RichTIFFIPTC" }, - { TIFFTAG_PHOTOSHOP, -3, -3, TIFF_BYTE, FIELD_CUSTOM, - 0, 1, "Photoshop" }, - { TIFFTAG_EXIFIFD, 1, 1, TIFF_LONG, FIELD_CUSTOM, - 0, 0, "EXIFIFDOffset" }, - { TIFFTAG_ICCPROFILE, -3, -3, TIFF_UNDEFINED, FIELD_CUSTOM, - 0, 1, "ICC Profile" }, - { TIFFTAG_GPSIFD, 1, 1, TIFF_LONG, FIELD_CUSTOM, - 0, 0, "GPSIFDOffset" }, - { TIFFTAG_STONITS, 1, 1, TIFF_DOUBLE, FIELD_CUSTOM, - 0, 0, "StoNits" }, - { TIFFTAG_INTEROPERABILITYIFD, 1, 1, TIFF_LONG, FIELD_CUSTOM, - 0, 0, "InteroperabilityIFDOffset" }, -/* begin DNG tags */ - { TIFFTAG_DNGVERSION, 4, 4, TIFF_BYTE, FIELD_CUSTOM, - 0, 0, "DNGVersion" }, - { TIFFTAG_DNGBACKWARDVERSION, 4, 4, TIFF_BYTE, FIELD_CUSTOM, - 0, 0, "DNGBackwardVersion" }, - { TIFFTAG_UNIQUECAMERAMODEL, -1, -1, TIFF_ASCII, FIELD_CUSTOM, - 1, 0, "UniqueCameraModel" }, - { TIFFTAG_LOCALIZEDCAMERAMODEL, -1, -1, TIFF_ASCII, FIELD_CUSTOM, - 1, 0, "LocalizedCameraModel" }, - { TIFFTAG_LOCALIZEDCAMERAMODEL, -1, -1, TIFF_BYTE, FIELD_CUSTOM, - 1, 1, "LocalizedCameraModel" }, - { TIFFTAG_CFAPLANECOLOR, -1, -1, TIFF_BYTE, FIELD_CUSTOM, - 0, 1, "CFAPlaneColor" }, - { TIFFTAG_CFALAYOUT, 1, 1, TIFF_SHORT, FIELD_CUSTOM, - 0, 0, "CFALayout" }, - { TIFFTAG_LINEARIZATIONTABLE, -1, -1, TIFF_SHORT, FIELD_CUSTOM, - 0, 1, "LinearizationTable" }, - { TIFFTAG_BLACKLEVELREPEATDIM, 2, 2, TIFF_SHORT, FIELD_CUSTOM, - 0, 0, "BlackLevelRepeatDim" }, - { TIFFTAG_BLACKLEVEL, -1, -1, TIFF_LONG, FIELD_CUSTOM, - 0, 1, "BlackLevel" }, - { TIFFTAG_BLACKLEVEL, -1, -1, TIFF_SHORT, FIELD_CUSTOM, - 0, 1, "BlackLevel" }, - { TIFFTAG_BLACKLEVEL, -1, -1, TIFF_RATIONAL, FIELD_CUSTOM, - 0, 1, "BlackLevel" }, - { TIFFTAG_BLACKLEVELDELTAH, -1, -1, TIFF_SRATIONAL, FIELD_CUSTOM, - 0, 1, "BlackLevelDeltaH" }, - { TIFFTAG_BLACKLEVELDELTAV, -1, -1, TIFF_SRATIONAL, FIELD_CUSTOM, - 0, 1, "BlackLevelDeltaV" }, - { TIFFTAG_WHITELEVEL, -2, -2, TIFF_LONG, FIELD_CUSTOM, - 0, 0, "WhiteLevel" }, - { TIFFTAG_WHITELEVEL, -2, -2, TIFF_SHORT, FIELD_CUSTOM, - 0, 0, "WhiteLevel" }, - { TIFFTAG_DEFAULTSCALE, 2, 2, TIFF_RATIONAL, FIELD_CUSTOM, - 0, 0, "DefaultScale" }, - { TIFFTAG_BESTQUALITYSCALE, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM, - 0, 0, "BestQualityScale" }, - { TIFFTAG_DEFAULTCROPORIGIN, 2, 2, TIFF_LONG, FIELD_CUSTOM, - 0, 0, "DefaultCropOrigin" }, - { TIFFTAG_DEFAULTCROPORIGIN, 2, 2, TIFF_SHORT, FIELD_CUSTOM, - 0, 0, "DefaultCropOrigin" }, - { TIFFTAG_DEFAULTCROPORIGIN, 2, 2, TIFF_RATIONAL, FIELD_CUSTOM, - 0, 0, "DefaultCropOrigin" }, - { TIFFTAG_DEFAULTCROPSIZE, 2, 2, TIFF_LONG, FIELD_CUSTOM, - 0, 0, "DefaultCropSize" }, - { TIFFTAG_DEFAULTCROPSIZE, 2, 2, TIFF_SHORT, FIELD_CUSTOM, - 0, 0, "DefaultCropSize" }, - { TIFFTAG_DEFAULTCROPSIZE, 2, 2, TIFF_RATIONAL, FIELD_CUSTOM, - 0, 0, "DefaultCropSize" }, - { TIFFTAG_COLORMATRIX1, -1, -1, TIFF_SRATIONAL, FIELD_CUSTOM, - 0, 1, "ColorMatrix1" }, - { TIFFTAG_COLORMATRIX2, -1, -1, TIFF_SRATIONAL, FIELD_CUSTOM, - 0, 1, "ColorMatrix2" }, - { TIFFTAG_CAMERACALIBRATION1, -1, -1, TIFF_SRATIONAL, FIELD_CUSTOM, - 0, 1, "CameraCalibration1" }, - { TIFFTAG_CAMERACALIBRATION2, -1, -1, TIFF_SRATIONAL, FIELD_CUSTOM, - 0, 1, "CameraCalibration2" }, - { TIFFTAG_REDUCTIONMATRIX1, -1, -1, TIFF_SRATIONAL, FIELD_CUSTOM, - 0, 1, "ReductionMatrix1" }, - { TIFFTAG_REDUCTIONMATRIX2, -1, -1, TIFF_SRATIONAL, FIELD_CUSTOM, - 0, 1, "ReductionMatrix2" }, - { TIFFTAG_ANALOGBALANCE, -1, -1, TIFF_RATIONAL, FIELD_CUSTOM, - 0, 1, "AnalogBalance" }, - { TIFFTAG_ASSHOTNEUTRAL, -1, -1, TIFF_SHORT, FIELD_CUSTOM, - 0, 1, "AsShotNeutral" }, - { TIFFTAG_ASSHOTNEUTRAL, -1, -1, TIFF_RATIONAL, FIELD_CUSTOM, - 0, 1, "AsShotNeutral" }, - { TIFFTAG_ASSHOTWHITEXY, 2, 2, TIFF_RATIONAL, FIELD_CUSTOM, - 0, 0, "AsShotWhiteXY" }, - { TIFFTAG_BASELINEEXPOSURE, 1, 1, TIFF_SRATIONAL, FIELD_CUSTOM, - 0, 0, "BaselineExposure" }, - { TIFFTAG_BASELINENOISE, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM, - 0, 0, "BaselineNoise" }, - { TIFFTAG_BASELINESHARPNESS, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM, - 0, 0, "BaselineSharpness" }, - { TIFFTAG_BAYERGREENSPLIT, 1, 1, TIFF_LONG, FIELD_CUSTOM, - 0, 0, "BayerGreenSplit" }, - { TIFFTAG_LINEARRESPONSELIMIT, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM, - 0, 0, "LinearResponseLimit" }, - { TIFFTAG_CAMERASERIALNUMBER, -1, -1, TIFF_ASCII, FIELD_CUSTOM, - 1, 0, "CameraSerialNumber" }, - { TIFFTAG_LENSINFO, 4, 4, TIFF_RATIONAL, FIELD_CUSTOM, - 0, 0, "LensInfo" }, - { TIFFTAG_CHROMABLURRADIUS, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM, - 0, 0, "ChromaBlurRadius" }, - { TIFFTAG_ANTIALIASSTRENGTH, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM, - 0, 0, "AntiAliasStrength" }, - { TIFFTAG_SHADOWSCALE, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM, - 0, 0, "ShadowScale" }, - { TIFFTAG_DNGPRIVATEDATA, -1, -1, TIFF_BYTE, FIELD_CUSTOM, - 0, 1, "DNGPrivateData" }, - { TIFFTAG_MAKERNOTESAFETY, 1, 1, TIFF_SHORT, FIELD_CUSTOM, - 0, 0, "MakerNoteSafety" }, - { TIFFTAG_CALIBRATIONILLUMINANT1, 1, 1, TIFF_SHORT, FIELD_CUSTOM, - 0, 0, "CalibrationIlluminant1" }, - { TIFFTAG_CALIBRATIONILLUMINANT2, 1, 1, TIFF_SHORT, FIELD_CUSTOM, - 0, 0, "CalibrationIlluminant2" }, - { TIFFTAG_RAWDATAUNIQUEID, 16, 16, TIFF_BYTE, FIELD_CUSTOM, - 0, 0, "RawDataUniqueID" }, - { TIFFTAG_ORIGINALRAWFILENAME, -1, -1, TIFF_ASCII, FIELD_CUSTOM, - 1, 0, "OriginalRawFileName" }, - { TIFFTAG_ORIGINALRAWFILENAME, -1, -1, TIFF_BYTE, FIELD_CUSTOM, - 1, 1, "OriginalRawFileName" }, - { TIFFTAG_ORIGINALRAWFILEDATA, -1, -1, TIFF_UNDEFINED, FIELD_CUSTOM, - 0, 1, "OriginalRawFileData" }, - { TIFFTAG_ACTIVEAREA, 4, 4, TIFF_LONG, FIELD_CUSTOM, - 0, 0, "ActiveArea" }, - { TIFFTAG_ACTIVEAREA, 4, 4, TIFF_SHORT, FIELD_CUSTOM, - 0, 0, "ActiveArea" }, - { TIFFTAG_MASKEDAREAS, -1, -1, TIFF_LONG, FIELD_CUSTOM, - 0, 1, "MaskedAreas" }, - { TIFFTAG_ASSHOTICCPROFILE, -1, -1, TIFF_UNDEFINED, FIELD_CUSTOM, - 0, 1, "AsShotICCProfile" }, - { TIFFTAG_ASSHOTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, FIELD_CUSTOM, - 0, 1, "AsShotPreProfileMatrix" }, - { TIFFTAG_CURRENTICCPROFILE, -1, -1, TIFF_UNDEFINED, FIELD_CUSTOM, - 0, 1, "CurrentICCProfile" }, - { TIFFTAG_CURRENTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, FIELD_CUSTOM, - 0, 1, "CurrentPreProfileMatrix" }, -/* end DNG tags */ + +static TIFFFieldArray tiffFieldArray; +static TIFFFieldArray exifFieldArray; + +static 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 }, + { TIFFTAG_IMAGEWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDIMENSIONS, 0, 0, "ImageWidth", NULL }, + { TIFFTAG_IMAGELENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDIMENSIONS, 1, 0, "ImageLength", NULL }, + { TIFFTAG_BITSPERSAMPLE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_BITSPERSAMPLE, 0, 0, "BitsPerSample", NULL }, + { TIFFTAG_COMPRESSION, -1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_COMPRESSION, 0, 0, "Compression", NULL }, + { TIFFTAG_PHOTOMETRIC, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_PHOTOMETRIC, 0, 0, "PhotometricInterpretation", NULL }, + { TIFFTAG_THRESHHOLDING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_THRESHHOLDING, 1, 0, "Threshholding", NULL }, + { TIFFTAG_CELLWIDTH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "CellWidth", NULL }, + { TIFFTAG_CELLLENGTH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "CellLength", NULL }, + { TIFFTAG_FILLORDER, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_FILLORDER, 0, 0, "FillOrder", NULL }, + { TIFFTAG_DOCUMENTNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DocumentName", NULL }, + { TIFFTAG_IMAGEDESCRIPTION, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageDescription", NULL }, + { TIFFTAG_MAKE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Make", NULL }, + { TIFFTAG_MODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Model", NULL }, + { TIFFTAG_STRIPOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPOFFSETS, 0, 0, "StripOffsets", NULL }, + { TIFFTAG_ORIENTATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_ORIENTATION, 0, 0, "Orientation", NULL }, + { TIFFTAG_SAMPLESPERPIXEL, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLESPERPIXEL, 0, 0, "SamplesPerPixel", NULL }, + { TIFFTAG_ROWSPERSTRIP, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_ROWSPERSTRIP, 0, 0, "RowsPerStrip", NULL }, + { TIFFTAG_STRIPBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "StripByteCounts", NULL }, + { TIFFTAG_MINSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_MINSAMPLEVALUE, 1, 0, "MinSampleValue", NULL }, + { TIFFTAG_MAXSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_MAXSAMPLEVALUE, 1, 0, "MaxSampleValue", NULL }, + { TIFFTAG_XRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "XResolution", NULL }, + { TIFFTAG_YRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "YResolution", NULL }, + { TIFFTAG_PLANARCONFIG, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_PLANARCONFIG, 0, 0, "PlanarConfiguration", NULL }, + { TIFFTAG_PAGENAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PageName", NULL }, + { TIFFTAG_XPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "XPosition", NULL }, + { TIFFTAG_YPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "YPosition", NULL }, + { TIFFTAG_FREEOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeOffsets", NULL }, + { TIFFTAG_FREEBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeByteCounts", NULL }, + { TIFFTAG_GRAYRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseUnit", NULL }, + { TIFFTAG_GRAYRESPONSECURVE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseCurve", NULL }, + { TIFFTAG_RESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTIONUNIT, 1, 0, "ResolutionUnit", NULL }, + { TIFFTAG_PAGENUMBER, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_PAGENUMBER, 1, 0, "PageNumber", NULL }, + { TIFFTAG_COLORRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "ColorResponseUnit", NULL }, + { TIFFTAG_TRANSFERFUNCTION, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_TRANSFERFUNCTION, 1, 0, "TransferFunction", NULL }, + { TIFFTAG_SOFTWARE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Software", NULL }, + { TIFFTAG_DATETIME, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTime", NULL }, + { TIFFTAG_ARTIST, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Artist", NULL }, + { TIFFTAG_HOSTCOMPUTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "HostComputer", NULL }, + { TIFFTAG_WHITEPOINT, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhitePoint", NULL }, + { TIFFTAG_PRIMARYCHROMATICITIES, 6, 6, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PrimaryChromaticities", NULL }, + { TIFFTAG_COLORMAP, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_COLORMAP, 1, 0, "ColorMap", NULL }, + { TIFFTAG_HALFTONEHINTS, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_HALFTONEHINTS, 1, 0, "HalftoneHints", NULL }, + { TIFFTAG_TILEWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDIMENSIONS, 0, 0, "TileWidth", NULL }, + { 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_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 }, + { TIFFTAG_DOTRANGE, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DotRange", NULL }, + { TIFFTAG_TARGETPRINTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TargetPrinter", NULL }, + { TIFFTAG_EXTRASAMPLES, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 1, "ExtraSamples", NULL }, + { TIFFTAG_SAMPLEFORMAT, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLEFORMAT, 0, 0, "SampleFormat", NULL }, + { TIFFTAG_SMINSAMPLEVALUE, -2, -1, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_SMINSAMPLEVALUE, 1, 0, "SMinSampleValue", NULL }, + { TIFFTAG_SMAXSAMPLEVALUE, -2, -1, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_SMAXSAMPLEVALUE, 1, 0, "SMaxSampleValue", NULL }, + { TIFFTAG_CLIPPATH, -1, -3, TIFF_BYTE, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ClipPath", NULL }, + { TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_SLONG, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL }, + { TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_SBYTE, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL }, + { TIFFTAG_YCLIPPATHUNITS, 1, 1, TIFF_SLONG, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YClipPathUnits", NULL }, + { TIFFTAG_YCBCRCOEFFICIENTS, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YCbCrCoefficients", NULL }, + { TIFFTAG_YCBCRSUBSAMPLING, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_YCBCRSUBSAMPLING, 0, 0, "YCbCrSubsampling", NULL }, + { TIFFTAG_YCBCRPOSITIONING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_YCBCRPOSITIONING, 0, 0, "YCbCrPositioning", NULL }, + { TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_REFBLACKWHITE, 1, 0, "ReferenceBlackWhite", NULL }, + { TIFFTAG_XMLPACKET, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "XMLPacket", NULL }, + /* begin SGI tags */ + { TIFFTAG_MATTEING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 0, "Matteing", NULL }, + { TIFFTAG_DATATYPE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLEFORMAT, 0, 0, "DataType", NULL }, + { TIFFTAG_IMAGEDEPTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDEPTH, 0, 0, "ImageDepth", NULL }, + { TIFFTAG_TILEDEPTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDEPTH, 0, 0, "TileDepth", NULL }, + /* end SGI tags */ + /* begin Pixar tags */ + { TIFFTAG_PIXAR_IMAGEFULLWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageFullWidth", NULL }, + { TIFFTAG_PIXAR_IMAGEFULLLENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageFullLength", NULL }, + { TIFFTAG_PIXAR_TEXTUREFORMAT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TextureFormat", NULL }, + { TIFFTAG_PIXAR_WRAPMODES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TextureWrapModes", NULL }, + { 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_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 }, + { TIFFTAG_FAXSUBADDRESS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxSubAddress", NULL }, + { TIFFTAG_FAXRECVTIME, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvTime", NULL }, + { TIFFTAG_FAXDCS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxDcs", NULL }, + { TIFFTAG_STONITS, 1, 1, TIFF_DOUBLE, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "StoNits", NULL }, + { TIFFTAG_INTEROPERABILITYIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InteroperabilityIFDOffset", NULL }, + /* begin DNG tags */ + { TIFFTAG_DNGVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DNGVersion", NULL }, + { TIFFTAG_DNGBACKWARDVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DNGBackwardVersion", NULL }, + { TIFFTAG_UNIQUECAMERAMODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "UniqueCameraModel", NULL }, + { TIFFTAG_LOCALIZEDCAMERAMODEL, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "LocalizedCameraModel", NULL }, + { TIFFTAG_CFAPLANECOLOR, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CFAPlaneColor", NULL }, + { TIFFTAG_CFALAYOUT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CFALayout", NULL }, + { TIFFTAG_LINEARIZATIONTABLE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "LinearizationTable", NULL }, + { TIFFTAG_BLACKLEVELREPEATDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BlackLevelRepeatDim", NULL }, + { TIFFTAG_BLACKLEVEL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "BlackLevel", NULL }, + { TIFFTAG_BLACKLEVELDELTAH, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "BlackLevelDeltaH", NULL }, + { TIFFTAG_BLACKLEVELDELTAV, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "BlackLevelDeltaV", NULL }, + { TIFFTAG_WHITELEVEL, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "WhiteLevel", NULL }, + { TIFFTAG_DEFAULTSCALE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultScale", NULL }, + { TIFFTAG_BESTQUALITYSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BestQualityScale", NULL }, + { TIFFTAG_DEFAULTCROPORIGIN, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultCropOrigin", NULL }, + { TIFFTAG_DEFAULTCROPSIZE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultCropSize", NULL }, + { TIFFTAG_COLORMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ColorMatrix1", NULL }, + { TIFFTAG_COLORMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ColorMatrix2", NULL }, + { TIFFTAG_CAMERACALIBRATION1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CameraCalibration1", NULL }, + { TIFFTAG_CAMERACALIBRATION2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CameraCalibration2", NULL }, + { TIFFTAG_REDUCTIONMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ReductionMatrix1", NULL }, + { TIFFTAG_REDUCTIONMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ReductionMatrix2", NULL }, + { TIFFTAG_ANALOGBALANCE, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AnalogBalance", NULL }, + { TIFFTAG_ASSHOTNEUTRAL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotNeutral", NULL }, + { TIFFTAG_ASSHOTWHITEXY, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "AsShotWhiteXY", NULL }, + { TIFFTAG_BASELINEEXPOSURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineExposure", NULL }, + { TIFFTAG_BASELINENOISE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineNoise", NULL }, + { TIFFTAG_BASELINESHARPNESS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineSharpness", NULL }, + { TIFFTAG_BAYERGREENSPLIT, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BayerGreenSplit", NULL }, + { TIFFTAG_LINEARRESPONSELIMIT, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "LinearResponseLimit", NULL }, + { TIFFTAG_CAMERASERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraSerialNumber", NULL }, + { TIFFTAG_LENSINFO, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "LensInfo", NULL }, + { TIFFTAG_CHROMABLURRADIUS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ChromaBlurRadius", NULL }, + { TIFFTAG_ANTIALIASSTRENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "AntiAliasStrength", NULL }, + { TIFFTAG_SHADOWSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ShadowScale", NULL }, + { TIFFTAG_DNGPRIVATEDATA, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "DNGPrivateData", NULL }, + { TIFFTAG_MAKERNOTESAFETY, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "MakerNoteSafety", NULL }, + { TIFFTAG_CALIBRATIONILLUMINANT1, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CalibrationIlluminant1", NULL }, + { TIFFTAG_CALIBRATIONILLUMINANT2, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CalibrationIlluminant2", NULL }, + { TIFFTAG_RAWDATAUNIQUEID, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "RawDataUniqueID", NULL }, + { TIFFTAG_ORIGINALRAWFILENAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OriginalRawFileName", NULL }, + { TIFFTAG_ORIGINALRAWFILEDATA, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "OriginalRawFileData", NULL }, + { TIFFTAG_ACTIVEAREA, 4, 4, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ActiveArea", NULL }, + { TIFFTAG_MASKEDAREAS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "MaskedAreas", NULL }, + { TIFFTAG_ASSHOTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotICCProfile", NULL }, + { 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 */ }; -static const TIFFFieldInfo -exifFieldInfo[] = { - { EXIFTAG_EXPOSURETIME, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM, - 1, 0, "ExposureTime" }, - { EXIFTAG_FNUMBER, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM, - 1, 0, "FNumber" }, - { EXIFTAG_EXPOSUREPROGRAM, 1, 1, TIFF_SHORT, FIELD_CUSTOM, - 1, 0, "ExposureProgram" }, - { EXIFTAG_SPECTRALSENSITIVITY, -1, -1, TIFF_ASCII, FIELD_CUSTOM, - 1, 0, "SpectralSensitivity" }, - { EXIFTAG_ISOSPEEDRATINGS, -1, -1, TIFF_SHORT, FIELD_CUSTOM, - 1, 1, "ISOSpeedRatings" }, - { EXIFTAG_OECF, -1, -1, TIFF_UNDEFINED, FIELD_CUSTOM, - 1, 1, "OptoelectricConversionFactor" }, - { EXIFTAG_EXIFVERSION, 4, 4, TIFF_UNDEFINED, FIELD_CUSTOM, - 1, 0, "ExifVersion" }, - { EXIFTAG_DATETIMEORIGINAL, 20, 20, TIFF_ASCII, FIELD_CUSTOM, - 1, 0, "DateTimeOriginal" }, - { EXIFTAG_DATETIMEDIGITIZED, 20, 20, TIFF_ASCII, FIELD_CUSTOM, - 1, 0, "DateTimeDigitized" }, - { EXIFTAG_COMPONENTSCONFIGURATION, 4, 4, TIFF_UNDEFINED, FIELD_CUSTOM, - 1, 0, "ComponentsConfiguration" }, - { EXIFTAG_COMPRESSEDBITSPERPIXEL, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM, - 1, 0, "CompressedBitsPerPixel" }, - { EXIFTAG_SHUTTERSPEEDVALUE, 1, 1, TIFF_SRATIONAL, FIELD_CUSTOM, - 1, 0, "ShutterSpeedValue" }, - { EXIFTAG_APERTUREVALUE, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM, - 1, 0, "ApertureValue" }, - { EXIFTAG_BRIGHTNESSVALUE, 1, 1, TIFF_SRATIONAL, FIELD_CUSTOM, - 1, 0, "BrightnessValue" }, - { EXIFTAG_EXPOSUREBIASVALUE, 1, 1, TIFF_SRATIONAL, FIELD_CUSTOM, - 1, 0, "ExposureBiasValue" }, - { EXIFTAG_MAXAPERTUREVALUE, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM, - 1, 0, "MaxApertureValue" }, - { EXIFTAG_SUBJECTDISTANCE, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM, - 1, 0, "SubjectDistance" }, - { EXIFTAG_METERINGMODE, 1, 1, TIFF_SHORT, FIELD_CUSTOM, - 1, 0, "MeteringMode" }, - { EXIFTAG_LIGHTSOURCE, 1, 1, TIFF_SHORT, FIELD_CUSTOM, - 1, 0, "LightSource" }, - { EXIFTAG_FLASH, 1, 1, TIFF_SHORT, FIELD_CUSTOM, - 1, 0, "Flash" }, - { EXIFTAG_FOCALLENGTH, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM, - 1, 0, "FocalLength" }, - { EXIFTAG_SUBJECTAREA, -1, -1, TIFF_SHORT, FIELD_CUSTOM, - 1, 1, "SubjectArea" }, - { EXIFTAG_MAKERNOTE, -1, -1, TIFF_UNDEFINED, FIELD_CUSTOM, - 1, 1, "MakerNote" }, - { EXIFTAG_USERCOMMENT, -1, -1, TIFF_UNDEFINED, FIELD_CUSTOM, - 1, 1, "UserComment" }, - { EXIFTAG_SUBSECTIME, -1, -1, TIFF_ASCII, FIELD_CUSTOM, - 1, 0, "SubSecTime" }, - { EXIFTAG_SUBSECTIMEORIGINAL, -1, -1, TIFF_ASCII, FIELD_CUSTOM, - 1, 0, "SubSecTimeOriginal" }, - { EXIFTAG_SUBSECTIMEDIGITIZED,-1, -1, TIFF_ASCII, FIELD_CUSTOM, - 1, 0, "SubSecTimeDigitized" }, - { EXIFTAG_FLASHPIXVERSION, 4, 4, TIFF_UNDEFINED, FIELD_CUSTOM, - 1, 0, "FlashpixVersion" }, - { EXIFTAG_COLORSPACE, 1, 1, TIFF_SHORT, FIELD_CUSTOM, - 1, 0, "ColorSpace" }, - { EXIFTAG_PIXELXDIMENSION, 1, 1, TIFF_LONG, FIELD_CUSTOM, - 1, 0, "PixelXDimension" }, - { EXIFTAG_PIXELXDIMENSION, 1, 1, TIFF_SHORT, FIELD_CUSTOM, - 1, 0, "PixelXDimension" }, - { EXIFTAG_PIXELYDIMENSION, 1, 1, TIFF_LONG, FIELD_CUSTOM, - 1, 0, "PixelYDimension" }, - { EXIFTAG_PIXELYDIMENSION, 1, 1, TIFF_SHORT, FIELD_CUSTOM, - 1, 0, "PixelYDimension" }, - { EXIFTAG_RELATEDSOUNDFILE, 13, 13, TIFF_ASCII, FIELD_CUSTOM, - 1, 0, "RelatedSoundFile" }, - { EXIFTAG_FLASHENERGY, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM, - 1, 0, "FlashEnergy" }, - { EXIFTAG_SPATIALFREQUENCYRESPONSE, -1, -1, TIFF_UNDEFINED, FIELD_CUSTOM, - 1, 1, "SpatialFrequencyResponse" }, - { EXIFTAG_FOCALPLANEXRESOLUTION, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM, - 1, 0, "FocalPlaneXResolution" }, - { EXIFTAG_FOCALPLANEYRESOLUTION, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM, - 1, 0, "FocalPlaneYResolution" }, - { EXIFTAG_FOCALPLANERESOLUTIONUNIT, 1, 1, TIFF_SHORT, FIELD_CUSTOM, - 1, 0, "FocalPlaneResolutionUnit" }, - { EXIFTAG_SUBJECTLOCATION, 2, 2, TIFF_SHORT, FIELD_CUSTOM, - 1, 0, "SubjectLocation" }, - { EXIFTAG_EXPOSUREINDEX, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM, - 1, 0, "ExposureIndex" }, - { EXIFTAG_SENSINGMETHOD, 1, 1, TIFF_SHORT, FIELD_CUSTOM, - 1, 0, "SensingMethod" }, - { EXIFTAG_FILESOURCE, 1, 1, TIFF_UNDEFINED, FIELD_CUSTOM, - 1, 0, "FileSource" }, - { EXIFTAG_SCENETYPE, 1, 1, TIFF_UNDEFINED, FIELD_CUSTOM, - 1, 0, "SceneType" }, - { EXIFTAG_CFAPATTERN, -1, -1, TIFF_UNDEFINED, FIELD_CUSTOM, - 1, 1, "CFAPattern" }, - { EXIFTAG_CUSTOMRENDERED, 1, 1, TIFF_SHORT, FIELD_CUSTOM, - 1, 0, "CustomRendered" }, - { EXIFTAG_EXPOSUREMODE, 1, 1, TIFF_SHORT, FIELD_CUSTOM, - 1, 0, "ExposureMode" }, - { EXIFTAG_WHITEBALANCE, 1, 1, TIFF_SHORT, FIELD_CUSTOM, - 1, 0, "WhiteBalance" }, - { EXIFTAG_DIGITALZOOMRATIO, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM, - 1, 0, "DigitalZoomRatio" }, - { EXIFTAG_FOCALLENGTHIN35MMFILM, 1, 1, TIFF_SHORT, FIELD_CUSTOM, - 1, 0, "FocalLengthIn35mmFilm" }, - { EXIFTAG_SCENECAPTURETYPE, 1, 1, TIFF_SHORT, FIELD_CUSTOM, - 1, 0, "SceneCaptureType" }, - { EXIFTAG_GAINCONTROL, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM, - 1, 0, "GainControl" }, - { EXIFTAG_CONTRAST, 1, 1, TIFF_SHORT, FIELD_CUSTOM, - 1, 0, "Contrast" }, - { EXIFTAG_SATURATION, 1, 1, TIFF_SHORT, FIELD_CUSTOM, - 1, 0, "Saturation" }, - { EXIFTAG_SHARPNESS, 1, 1, TIFF_SHORT, FIELD_CUSTOM, - 1, 0, "Sharpness" }, - { EXIFTAG_DEVICESETTINGDESCRIPTION, -1, -1, TIFF_UNDEFINED, FIELD_CUSTOM, - 1, 1, "DeviceSettingDescription" }, - { EXIFTAG_SUBJECTDISTANCERANGE, 1, 1, TIFF_SHORT, FIELD_CUSTOM, - 1, 0, "SubjectDistanceRange" }, - { EXIFTAG_IMAGEUNIQUEID, 33, 33, TIFF_ASCII, FIELD_CUSTOM, - 1, 0, "ImageUniqueID" } +static 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 }, + { EXIFTAG_EXPOSUREPROGRAM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureProgram", NULL }, + { EXIFTAG_SPECTRALSENSITIVITY, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SpectralSensitivity", NULL }, + { EXIFTAG_ISOSPEEDRATINGS, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ISOSpeedRatings", NULL }, + { EXIFTAG_OECF, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OptoelectricConversionFactor", NULL }, + { EXIFTAG_EXIFVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExifVersion", NULL }, + { EXIFTAG_DATETIMEORIGINAL, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeOriginal", NULL }, + { EXIFTAG_DATETIMEDIGITIZED, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeDigitized", NULL }, + { EXIFTAG_COMPONENTSCONFIGURATION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ComponentsConfiguration", NULL }, + { EXIFTAG_COMPRESSEDBITSPERPIXEL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CompressedBitsPerPixel", NULL }, + { EXIFTAG_SHUTTERSPEEDVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ShutterSpeedValue", NULL }, + { EXIFTAG_APERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ApertureValue", NULL }, + { EXIFTAG_BRIGHTNESSVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BrightnessValue", NULL }, + { EXIFTAG_EXPOSUREBIASVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureBiasValue", NULL }, + { EXIFTAG_MAXAPERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MaxApertureValue", NULL }, + { EXIFTAG_SUBJECTDISTANCE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistance", NULL }, + { EXIFTAG_METERINGMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MeteringMode", NULL }, + { EXIFTAG_LIGHTSOURCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LightSource", NULL }, + { EXIFTAG_FLASH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Flash", NULL }, + { EXIFTAG_FOCALLENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLength", NULL }, + { EXIFTAG_SUBJECTAREA, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SubjectArea", NULL }, + { EXIFTAG_MAKERNOTE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "MakerNote", NULL }, + { EXIFTAG_USERCOMMENT, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "UserComment", NULL }, + { EXIFTAG_SUBSECTIME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTime", NULL }, + { EXIFTAG_SUBSECTIMEORIGINAL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeOriginal", NULL }, + { EXIFTAG_SUBSECTIMEDIGITIZED, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeDigitized", NULL }, + { EXIFTAG_FLASHPIXVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashpixVersion", NULL }, + { EXIFTAG_COLORSPACE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ColorSpace", NULL }, + { EXIFTAG_PIXELXDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelXDimension", NULL }, + { EXIFTAG_PIXELYDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelYDimension", NULL }, + { EXIFTAG_RELATEDSOUNDFILE, 13, 13, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RelatedSoundFile", NULL }, + { EXIFTAG_FLASHENERGY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashEnergy", NULL }, + { EXIFTAG_SPATIALFREQUENCYRESPONSE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SpatialFrequencyResponse", NULL }, + { EXIFTAG_FOCALPLANEXRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneXResolution", NULL }, + { EXIFTAG_FOCALPLANEYRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneYResolution", NULL }, + { EXIFTAG_FOCALPLANERESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneResolutionUnit", NULL }, + { EXIFTAG_SUBJECTLOCATION, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectLocation", NULL }, + { EXIFTAG_EXPOSUREINDEX, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureIndex", NULL }, + { EXIFTAG_SENSINGMETHOD, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SensingMethod", NULL }, + { EXIFTAG_FILESOURCE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FileSource", NULL }, + { EXIFTAG_SCENETYPE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneType", NULL }, + { EXIFTAG_CFAPATTERN, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CFAPattern", NULL }, + { EXIFTAG_CUSTOMRENDERED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CustomRendered", NULL }, + { EXIFTAG_EXPOSUREMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureMode", NULL }, + { EXIFTAG_WHITEBALANCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhiteBalance", NULL }, + { EXIFTAG_DIGITALZOOMRATIO, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DigitalZoomRatio", NULL }, + { EXIFTAG_FOCALLENGTHIN35MMFILM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLengthIn35mmFilm", NULL }, + { EXIFTAG_SCENECAPTURETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneCaptureType", NULL }, + { EXIFTAG_GAINCONTROL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GainControl", NULL }, + { EXIFTAG_CONTRAST, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Contrast", NULL }, + { EXIFTAG_SATURATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Saturation", NULL }, + { EXIFTAG_SHARPNESS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Sharpness", NULL }, + { EXIFTAG_DEVICESETTINGDESCRIPTION, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "DeviceSettingDescription", NULL }, + { EXIFTAG_SUBJECTDISTANCERANGE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistanceRange", NULL }, + { EXIFTAG_IMAGEUNIQUEID, 33, 33, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageUniqueID", NULL } }; -const TIFFFieldInfo * -_TIFFGetFieldInfo(size_t *size) +static TIFFFieldArray +tiffFieldArray = { tfiatImage, 0, TIFFArrayCount(tiffFields), tiffFields }; +static TIFFFieldArray +exifFieldArray = { tfiatExif, 0, TIFFArrayCount(exifFields), exifFields }; + +/* + * We have our own local lfind() equivelent to avoid subtle differences + * in types passed to lfind() on different systems. + */ + +static void * +td_lfind(const void *key, const void *base, size_t *nmemb, size_t size, + int(*compar)(const void *, const void *)) { - *size = TIFFArrayCount(tiffFieldInfo); - return tiffFieldInfo; + char *element, *end; + + end = (char *)base + *nmemb * size; + for (element = (char *)base; element < end; element += size) + if (!compar(key, element)) /* key found */ + return element; + + return NULL; } -const TIFFFieldInfo * -_TIFFGetExifFieldInfo(size_t *size) +const TIFFFieldArray* +_TIFFGetFields(void) { - *size = TIFFArrayCount(exifFieldInfo); - return exifFieldInfo; + return(&tiffFieldArray); +} + +const TIFFFieldArray* +_TIFFGetExifFields(void) +{ + return(&exifFieldArray); } void -_TIFFSetupFieldInfo(TIFF* tif, const TIFFFieldInfo info[], size_t n) +_TIFFSetupFields(TIFF* tif, const TIFFFieldArray* fieldarray) { - if (tif->tif_fieldinfo) { - size_t i; + if (tif->tif_fields && tif->tif_nfields > 0) { + uint32 i; - for (i = 0; i < tif->tif_nfields; i++) - { - TIFFFieldInfo *fld = tif->tif_fieldinfo[i]; - if (fld->field_bit == FIELD_CUSTOM && + for (i = 0; i < tif->tif_nfields; i++) { + TIFFField *fld = tif->tif_fields[i]; + if (fld->field_bit == FIELD_CUSTOM && strncmp("Tag ", fld->field_name, 4) == 0) { _TIFFfree(fld->field_name); _TIFFfree(fld); } - } - - _TIFFfree(tif->tif_fieldinfo); + } + + _TIFFfree(tif->tif_fields); + tif->tif_fields = NULL; tif->tif_nfields = 0; } - if (!_TIFFMergeFieldInfo(tif, info, n)) - { - TIFFErrorExt(tif->tif_clientdata, "_TIFFSetupFieldInfo", + if (!_TIFFMergeFields(tif, fieldarray->fields, fieldarray->count)) { + TIFFErrorExt(tif->tif_clientdata, "_TIFFSetupFields", "Setting up field info failed"); } } @@ -555,8 +335,8 @@ _TIFFSetupFieldInfo(TIFF* tif, const TIFFFieldInfo info[], size_t n) static int tagCompare(const void* a, const void* b) { - const TIFFFieldInfo* ta = *(const TIFFFieldInfo**) a; - const TIFFFieldInfo* tb = *(const TIFFFieldInfo**) b; + const TIFFField* ta = *(const TIFFField**) a; + const TIFFField* tb = *(const TIFFField**) b; /* NB: be careful of return values for 16-bit platforms */ if (ta->field_tag != tb->field_tag) return (int)ta->field_tag - (int)tb->field_tag; @@ -568,8 +348,8 @@ tagCompare(const void* a, const void* b) static int tagNameCompare(const void* a, const void* b) { - const TIFFFieldInfo* ta = *(const TIFFFieldInfo**) a; - const TIFFFieldInfo* tb = *(const TIFFFieldInfo**) b; + const TIFFField* ta = *(const TIFFField**) a; + const TIFFField* tb = *(const TIFFField**) b; int ret = strcmp(ta->field_name, tb->field_name); if (ret) @@ -579,57 +359,47 @@ tagNameCompare(const void* a, const void* b) 0 : ((int)tb->field_type - (int)ta->field_type); } -void -TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], int n) -{ - if (_TIFFMergeFieldInfo(tif, info, n) < 0) - { - TIFFErrorExt(tif->tif_clientdata, "TIFFMergeFieldInfo", - "Merging block of %d fields failed", n); - } -} - int -_TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], int n) +_TIFFMergeFields(TIFF* tif, const TIFFField info[], uint32 n) { - static const char module[] = "_TIFFMergeFieldInfo"; - static const char reason[] = "for field info array"; - TIFFFieldInfo** tp; - int i; + static const char module[] = "_TIFFMergeFields"; + static const char reason[] = "for fields array"; + /* TIFFField** tp; */ + uint32 i; tif->tif_foundfield = NULL; - if (tif->tif_nfields > 0) { - tif->tif_fieldinfo = (TIFFFieldInfo**) - _TIFFCheckRealloc(tif, tif->tif_fieldinfo, + if (tif->tif_fields && tif->tif_nfields > 0) { + tif->tif_fields = (TIFFField**) + _TIFFCheckRealloc(tif, tif->tif_fields, (tif->tif_nfields + n), - sizeof (TIFFFieldInfo*), reason); + sizeof(TIFFField *), reason); } else { - tif->tif_fieldinfo = (TIFFFieldInfo**) - _TIFFCheckMalloc(tif, n, sizeof (TIFFFieldInfo*), + tif->tif_fields = (TIFFField **) + _TIFFCheckMalloc(tif, n, sizeof(TIFFField *), reason); } - if (!tif->tif_fieldinfo) { + if (!tif->tif_fields) { TIFFErrorExt(tif->tif_clientdata, module, - "Failed to allocate field info array"); + "Failed to allocate fields array"); return 0; } - tp = tif->tif_fieldinfo + tif->tif_nfields; - for (i = 0; i < n; i++) - { - const TIFFFieldInfo *fip = - _TIFFFindFieldInfo(tif, info[i].field_tag, info[i].field_type); - /* only add definitions that aren't already present */ - if (!fip) { - *tp++ = (TIFFFieldInfo*) (info + i); - 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); + + /* only add definitions that aren't already present */ + if (!fip) { + tif->tif_fields[tif->tif_nfields] = (TIFFField *) (info+i); + tif->tif_nfields++; + } + } /* Sort the field info by tag number */ - qsort(tif->tif_fieldinfo, tif->tif_nfields, - sizeof (TIFFFieldInfo*), tagCompare); + qsort(tif->tif_fields, tif->tif_nfields, + sizeof(TIFFField *), tagCompare); return n; } @@ -637,11 +407,11 @@ _TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], int n) void _TIFFPrintFieldInfo(TIFF* tif, FILE* fd) { - size_t i; + uint32 i; fprintf(fd, "%s: \n", tif->tif_name); for (i = 0; i < tif->tif_nfields; i++) { - const TIFFFieldInfo* fip = tif->tif_fieldinfo[i]; + const TIFFField* fip = tif->tif_fields[i]; fprintf(fd, "field[%2d] %5lu, %2d, %2d, %d, %2d, %5s, %5s, %s\n" , (int)i , (unsigned long) fip->field_tag @@ -663,26 +433,29 @@ TIFFDataWidth(TIFFDataType type) { switch(type) { - case 0: /* nothing */ - case 1: /* TIFF_BYTE */ - case 2: /* TIFF_ASCII */ - case 6: /* TIFF_SBYTE */ - case 7: /* TIFF_UNDEFINED */ - return 1; - case 3: /* TIFF_SHORT */ - case 8: /* TIFF_SSHORT */ - return 2; - case 4: /* TIFF_LONG */ - case 9: /* TIFF_SLONG */ - case 11: /* TIFF_FLOAT */ - case 13: /* TIFF_IFD */ - return 4; - case 5: /* TIFF_RATIONAL */ - case 10: /* TIFF_SRATIONAL */ - case 12: /* TIFF_DOUBLE */ - return 8; - default: - return 0; /* will return 0 for unknown types */ + case 0: /* nothing */ + case TIFF_BYTE: + case TIFF_ASCII: + case TIFF_SBYTE: + case TIFF_UNDEFINED: + return 1; + case TIFF_SHORT: + case TIFF_SSHORT: + return 2; + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_FLOAT: + case TIFF_IFD: + return 4; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_DOUBLE: + case TIFF_LONG8: + case TIFF_SLONG8: + case TIFF_IFD8: + return 8; + default: + return 0; /* will return 0 for unknown types */ } } @@ -696,7 +469,8 @@ TIFFDataWidth(TIFFDataType type) int _TIFFDataSize(TIFFDataType type) { - switch (type) { + switch (type) + { case TIFF_BYTE: case TIFF_SBYTE: case TIFF_ASCII: @@ -713,169 +487,218 @@ _TIFFDataSize(TIFFDataType type) case TIFF_SRATIONAL: return 4; case TIFF_DOUBLE: + case TIFF_LONG8: + case TIFF_SLONG8: + case TIFF_IFD8: return 8; default: return 0; } } -/* - * Return nearest TIFFDataType to the sample type of an image. - */ -TIFFDataType -_TIFFSampleToTagType(TIFF* tif) +const TIFFField* +TIFFFindField(TIFF* tif, uint32 tag, TIFFDataType dt) { - uint32 bps = TIFFhowmany8(tif->tif_dir.td_bitspersample); - - switch (tif->tif_dir.td_sampleformat) { - case SAMPLEFORMAT_IEEEFP: - return (bps == 4 ? TIFF_FLOAT : TIFF_DOUBLE); - case SAMPLEFORMAT_INT: - return (bps <= 1 ? TIFF_SBYTE : - bps <= 2 ? TIFF_SSHORT : TIFF_SLONG); - case SAMPLEFORMAT_UINT: - return (bps <= 1 ? TIFF_BYTE : - bps <= 2 ? TIFF_SHORT : TIFF_LONG); - case SAMPLEFORMAT_VOID: - return (TIFF_UNDEFINED); - } - /*NOTREACHED*/ - return (TIFF_UNDEFINED); -} - -const TIFFFieldInfo* -_TIFFFindFieldInfo(TIFF* tif, ttag_t tag, TIFFDataType dt) -{ - TIFFFieldInfo key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0}; - TIFFFieldInfo* pkey = &key; - const TIFFFieldInfo **ret; - + TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, 0, NULL, NULL}; + TIFFField* pkey = &key; + const TIFFField **ret; if (tif->tif_foundfield && tif->tif_foundfield->field_tag == tag && (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type)) return tif->tif_foundfield; /* If we are invoked with no field information, then just return. */ - if ( !tif->tif_fieldinfo ) { + if (!tif->tif_fields) return NULL; - } /* NB: use sorted search (e.g. binary search) */ - key.field_tag = tag; - key.field_type = dt; - ret = (const TIFFFieldInfo **) bsearch(&pkey, - tif->tif_fieldinfo, - tif->tif_nfields, - sizeof(TIFFFieldInfo *), - tagCompare); + key.field_tag = tag; + key.field_type = dt; + + ret = (const TIFFField **) bsearch(&pkey, tif->tif_fields, + tif->tif_nfields, + sizeof(TIFFField *), tagCompare); return tif->tif_foundfield = (ret ? *ret : NULL); } -#undef lfind -static void * -lfind(const void *key, const void *base, size_t *nmemb, size_t size, - int(*compar)(const void *, const void *)) +const TIFFField* +_TIFFFindFieldByName(TIFF* tif, const char *field_name, TIFFDataType dt) { - char *element, *end; - - end = (char *)base + *nmemb * size; - for (element = (char *)base; element < end; element += size) - if (!compar(element, key)) /* key found */ - return element; - - return NULL; -} - - -const TIFFFieldInfo* -_TIFFFindFieldInfoByName(TIFF* tif, const char *field_name, TIFFDataType dt) -{ - TIFFFieldInfo key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0}; - TIFFFieldInfo* pkey = &key; - const TIFFFieldInfo **ret; - + TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, 0, NULL, NULL}; + TIFFField* pkey = &key; + const TIFFField **ret; if (tif->tif_foundfield && streq(tif->tif_foundfield->field_name, field_name) && (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type)) return (tif->tif_foundfield); /* If we are invoked with no field information, then just return. */ - if ( !tif->tif_fieldinfo ) { + if (!tif->tif_fields) return NULL; - } - /* NB: use sorted search (e.g. binary search) */ - key.field_name = (char *)field_name; - key.field_type = dt; + /* NB: use linear search since list is sorted by key#, not name */ + + key.field_name = (char *)field_name; + key.field_type = dt; + + ret = (const TIFFField **) + td_lfind(&pkey, tif->tif_fields, &tif->tif_nfields, + sizeof(TIFFField *), tagNameCompare); - ret = (const TIFFFieldInfo **) lfind(&pkey, - tif->tif_fieldinfo, - &tif->tif_nfields, - sizeof(TIFFFieldInfo *), - tagNameCompare); return tif->tif_foundfield = (ret ? *ret : NULL); } -const TIFFFieldInfo* -_TIFFFieldWithTag(TIFF* tif, ttag_t tag) +const TIFFField* +TIFFFieldWithTag(TIFF* tif, uint32 tag) { - const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY); + const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY); if (!fip) { TIFFErrorExt(tif->tif_clientdata, "TIFFFieldWithTag", "Internal error, unknown tag 0x%x", (unsigned int) tag); - assert(fip != NULL); - /*NOTREACHED*/ } return (fip); } -const TIFFFieldInfo* -_TIFFFieldWithName(TIFF* tif, const char *field_name) +const TIFFField* +TIFFFieldWithName(TIFF* tif, const char *field_name) { - const TIFFFieldInfo* fip = - _TIFFFindFieldInfoByName(tif, field_name, TIFF_ANY); + const TIFFField* fip = + _TIFFFindFieldByName(tif, field_name, TIFF_ANY); if (!fip) { TIFFErrorExt(tif->tif_clientdata, "TIFFFieldWithName", "Internal error, unknown tag %s", field_name); - assert(fip != NULL); - /*NOTREACHED*/ } return (fip); } -const TIFFFieldInfo* -_TIFFFindOrRegisterFieldInfo( TIFF *tif, ttag_t tag, TIFFDataType dt ) - +uint32 +TIFFFieldTag(const TIFFField* fip) { - const TIFFFieldInfo *fld; - - fld = _TIFFFindFieldInfo( tif, tag, dt ); - if( fld == NULL ) - { - fld = _TIFFCreateAnonFieldInfo( tif, tag, dt ); - if (!_TIFFMergeFieldInfo(tif, fld, 1)) - return NULL; - } - - return fld; + return fip->field_tag; } -TIFFFieldInfo* -_TIFFCreateAnonFieldInfo(TIFF *tif, ttag_t tag, TIFFDataType field_type) +const char * +TIFFFieldName(const TIFFField* fip) { - TIFFFieldInfo *fld; + 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) + +{ + const TIFFField *fld; + + fld = TIFFFindField(tif, tag, dt); + if (fld == NULL) { + fld = _TIFFCreateAnonField(tif, tag, dt); + if (!_TIFFMergeFields(tif, fld, 1)) + return NULL; + } + + return fld; +} + +TIFFField* +_TIFFCreateAnonField(TIFF *tif, uint32 tag, TIFFDataType field_type) +{ + TIFFField *fld; (void) tif; - fld = (TIFFFieldInfo *) _TIFFmalloc(sizeof (TIFFFieldInfo)); + fld = (TIFFField *) _TIFFmalloc(sizeof (TIFFField)); if (fld == NULL) return NULL; - _TIFFmemset( fld, 0, sizeof(TIFFFieldInfo) ); + _TIFFmemset(fld, 0, sizeof(TIFFField)); fld->field_tag = tag; fld->field_readcount = TIFF_VARIABLE2; fld->field_writecount = TIFF_VARIABLE2; fld->field_type = field_type; + fld->reserved = 0; + switch (field_type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: + fld->set_field_type = TIFF_SETGET_C32_UINT8; + fld->get_field_type = TIFF_SETGET_C32_UINT8; + break; + case TIFF_ASCII: + fld->set_field_type = TIFF_SETGET_C32_ASCII; + fld->get_field_type = TIFF_SETGET_C32_ASCII; + break; + case TIFF_SHORT: + fld->set_field_type = TIFF_SETGET_C32_UINT16; + fld->get_field_type = TIFF_SETGET_C32_UINT16; + break; + case TIFF_LONG: + fld->set_field_type = TIFF_SETGET_C32_UINT32; + fld->get_field_type = TIFF_SETGET_C32_UINT32; + break; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + fld->set_field_type = TIFF_SETGET_C32_FLOAT; + fld->get_field_type = TIFF_SETGET_C32_FLOAT; + break; + case TIFF_SBYTE: + fld->set_field_type = TIFF_SETGET_C32_SINT8; + fld->get_field_type = TIFF_SETGET_C32_SINT8; + break; + case TIFF_SSHORT: + fld->set_field_type = TIFF_SETGET_C32_SINT16; + fld->get_field_type = TIFF_SETGET_C32_SINT16; + break; + case TIFF_SLONG: + fld->set_field_type = TIFF_SETGET_C32_SINT32; + fld->get_field_type = TIFF_SETGET_C32_SINT32; + break; + case TIFF_DOUBLE: + fld->set_field_type = TIFF_SETGET_C32_DOUBLE; + fld->get_field_type = TIFF_SETGET_C32_DOUBLE; + break; + case TIFF_IFD: + case TIFF_IFD8: + fld->set_field_type = TIFF_SETGET_C32_IFD8; + fld->get_field_type = TIFF_SETGET_C32_IFD8; + break; + case TIFF_LONG8: + fld->set_field_type = TIFF_SETGET_C32_UINT64; + fld->get_field_type = TIFF_SETGET_C32_UINT64; + break; + case TIFF_SLONG8: + fld->set_field_type = TIFF_SETGET_C32_SINT64; + fld->get_field_type = TIFF_SETGET_C32_SINT64; + break; + default: + fld->set_field_type = TIFF_SETGET_UNDEFINED; + fld->get_field_type = TIFF_SETGET_UNDEFINED; + break; + } fld->field_bit = FIELD_CUSTOM; fld->field_oktochange = TRUE; fld->field_passcount = TRUE; @@ -884,17 +707,249 @@ _TIFFCreateAnonFieldInfo(TIFF *tif, ttag_t tag, TIFFDataType field_type) _TIFFfree(fld); return NULL; } + fld->field_subfields = NULL; /* * note that this name is a special sign to TIFFClose() and - * _TIFFSetupFieldInfo() to free the field + * _TIFFSetupFields() to free the field */ - sprintf(fld->field_name, "Tag %d", (int) tag); + snprintf(fld->field_name, 32, "Tag %d", (int) tag); return fld; } +/**************************************************************************** + * O B S O L E T E D I N T E R F A C E S + * + * Don't use this stuff in your applications, it may be removed in the future + * libtiff versions. + ****************************************************************************/ + +static TIFFSetGetFieldType +_TIFFSetGetType(TIFFDataType type, short count, unsigned char passcount) +{ + if (type == TIFF_ASCII && count == TIFF_VARIABLE && passcount == 0) + return TIFF_SETGET_ASCII; + + else if (count == 1 && passcount == 0) { + switch (type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: + return TIFF_SETGET_UINT8; + case TIFF_ASCII: + return TIFF_SETGET_ASCII; + case TIFF_SHORT: + return TIFF_SETGET_UINT16; + case TIFF_LONG: + return TIFF_SETGET_UINT32; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + return TIFF_SETGET_FLOAT; + case TIFF_SBYTE: + return TIFF_SETGET_SINT8; + case TIFF_SSHORT: + return TIFF_SETGET_SINT16; + case TIFF_SLONG: + return TIFF_SETGET_SINT32; + case TIFF_DOUBLE: + return TIFF_SETGET_DOUBLE; + case TIFF_IFD: + case TIFF_IFD8: + return TIFF_SETGET_IFD8; + case TIFF_LONG8: + return TIFF_SETGET_UINT64; + case TIFF_SLONG8: + return TIFF_SETGET_SINT64; + default: + return TIFF_SETGET_UNDEFINED; + } + } + + else if (count >= 1 && passcount == 0) { + switch (type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: + return TIFF_SETGET_C0_UINT8; + case TIFF_ASCII: + return TIFF_SETGET_C0_ASCII; + case TIFF_SHORT: + return TIFF_SETGET_C0_UINT16; + case TIFF_LONG: + return TIFF_SETGET_C0_UINT32; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + return TIFF_SETGET_C0_FLOAT; + case TIFF_SBYTE: + return TIFF_SETGET_C0_SINT8; + case TIFF_SSHORT: + return TIFF_SETGET_C0_SINT16; + case TIFF_SLONG: + return TIFF_SETGET_C0_SINT32; + case TIFF_DOUBLE: + return TIFF_SETGET_C0_DOUBLE; + case TIFF_IFD: + case TIFF_IFD8: + return TIFF_SETGET_C0_IFD8; + case TIFF_LONG8: + return TIFF_SETGET_C0_UINT64; + case TIFF_SLONG8: + return TIFF_SETGET_C0_SINT64; + default: + return TIFF_SETGET_UNDEFINED; + } + } + + else if (count == TIFF_VARIABLE && passcount == 1) { + switch (type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: + return TIFF_SETGET_C16_UINT8; + case TIFF_ASCII: + return TIFF_SETGET_C16_ASCII; + case TIFF_SHORT: + return TIFF_SETGET_C16_UINT16; + case TIFF_LONG: + return TIFF_SETGET_C16_UINT32; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + return TIFF_SETGET_C16_FLOAT; + case TIFF_SBYTE: + return TIFF_SETGET_C16_SINT8; + case TIFF_SSHORT: + return TIFF_SETGET_C16_SINT16; + case TIFF_SLONG: + return TIFF_SETGET_C16_SINT32; + case TIFF_DOUBLE: + return TIFF_SETGET_C16_DOUBLE; + case TIFF_IFD: + case TIFF_IFD8: + return TIFF_SETGET_C16_IFD8; + case TIFF_LONG8: + return TIFF_SETGET_C16_UINT64; + case TIFF_SLONG8: + return TIFF_SETGET_C16_SINT64; + default: + return TIFF_SETGET_UNDEFINED; + } + } + + else if (count == TIFF_VARIABLE2 && passcount == 1) { + switch (type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: + return TIFF_SETGET_C32_UINT8; + case TIFF_ASCII: + return TIFF_SETGET_C32_ASCII; + case TIFF_SHORT: + return TIFF_SETGET_C32_UINT16; + case TIFF_LONG: + return TIFF_SETGET_C32_UINT32; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + return TIFF_SETGET_C32_FLOAT; + case TIFF_SBYTE: + return TIFF_SETGET_C32_SINT8; + case TIFF_SSHORT: + return TIFF_SETGET_C32_SINT16; + case TIFF_SLONG: + return TIFF_SETGET_C32_SINT32; + case TIFF_DOUBLE: + return TIFF_SETGET_C32_DOUBLE; + case TIFF_IFD: + case TIFF_IFD8: + return TIFF_SETGET_C32_IFD8; + case TIFF_LONG8: + return TIFF_SETGET_C32_UINT64; + case TIFF_SLONG8: + return TIFF_SETGET_C32_SINT64; + default: + return TIFF_SETGET_UNDEFINED; + } + } + + return TIFF_SETGET_UNDEFINED; +} + +int +TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], uint32 n) +{ + static const char module[] = "TIFFMergeFieldInfo"; + static const char reason[] = "for fields array"; + TIFFField *tp; + size_t nfields; + uint32 i; + + if (tif->tif_nfieldscompat > 0) { + tif->tif_fieldscompat = (TIFFFieldArray *) + _TIFFCheckRealloc(tif, tif->tif_fieldscompat, + tif->tif_nfieldscompat + 1, + sizeof(TIFFFieldArray), reason); + } else { + tif->tif_fieldscompat = (TIFFFieldArray *) + _TIFFCheckMalloc(tif, 1, sizeof(TIFFFieldArray), + reason); + } + if (!tif->tif_fieldscompat) { + TIFFErrorExt(tif->tif_clientdata, module, + "Failed to allocate fields array"); + return -1; + } + nfields = tif->tif_nfieldscompat++; + + tif->tif_fieldscompat[nfields].type = tfiatOther; + tif->tif_fieldscompat[nfields].allocated_size = n; + tif->tif_fieldscompat[nfields].count = n; + tif->tif_fieldscompat[nfields].fields = + (TIFFField *)_TIFFCheckMalloc(tif, n, sizeof(TIFFField), + reason); + if (!tif->tif_fieldscompat[nfields].fields) { + TIFFErrorExt(tif->tif_clientdata, module, + "Failed to allocate fields array"); + return -1; + } + + tp = tif->tif_fieldscompat[nfields].fields; + for (i = 0; i < n; i++) { + tp->field_tag = info[i].field_tag; + tp->field_readcount = info[i].field_readcount; + tp->field_writecount = info[i].field_writecount; + tp->field_type = info[i].field_type; + tp->reserved = 0; + tp->set_field_type = + _TIFFSetGetType(info[i].field_type, + info[i].field_readcount, + info[i].field_passcount); + tp->get_field_type = + _TIFFSetGetType(info[i].field_type, + info[i].field_readcount, + info[i].field_passcount); + tp->field_bit = info[i].field_bit; + tp->field_oktochange = info[i].field_oktochange; + tp->field_passcount = info[i].field_passcount; + tp->field_name = info[i].field_name; + tp->field_subfields = NULL; + tp++; + } + + if (!_TIFFMergeFields(tif, tif->tif_fieldscompat[nfields].fields, n)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Setting up field info failed"); + return -1; + } + + return 0; +} + /* vim: set ts=8 sts=8 sw=8 noet: */ + /* * Local Variables: * mode: c diff --git a/thirdparty/libtiff/tif_dirread.c b/thirdparty/libtiff/tif_dirread.c index 907b5318..606366c8 100644 --- a/thirdparty/libtiff/tif_dirread.c +++ b/thirdparty/libtiff/tif_dirread.c @@ -1,26 +1,26 @@ -/* $Id: tif_dirread.c,v 1.92.2.9 2010-06-14 00:21:46 fwarmerdam Exp $ */ +/* $Id: tif_dirread.c,v 1.187 2015-05-31 21:09:33 bfriesen Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -29,42 +29,3371 @@ * * Directory Read Support Routines. */ + +/* Suggested pending improvements: + * - add a field 'ignore' to the TIFFDirEntry structure, to flag status, + * eliminating current use of the IGNORE value, and therefore eliminating + * current irrational behaviour on tags with tag id code 0 + * - add a field 'field_info' to the TIFFDirEntry structure, and set that with + * the pointer to the appropriate TIFFField structure early on in + * TIFFReadDirectory, so as to eliminate current possibly repetitive lookup. + */ + #include "tiffiop.h" -#define IGNORE 0 /* tag placeholder used below */ +#define IGNORE 0 /* tag placeholder used below */ +#define FAILED_FII ((uint32) -1) #ifdef HAVE_IEEEFP -# define TIFFCvtIEEEFloatToNative(tif, n, fp) -# define TIFFCvtIEEEDoubleToNative(tif, n, dp) +# define TIFFCvtIEEEFloatToNative(tif, n, fp) +# define TIFFCvtIEEEDoubleToNative(tif, n, dp) #else -extern void TIFFCvtIEEEFloatToNative(TIFF*, uint32, float*); -extern void TIFFCvtIEEEDoubleToNative(TIFF*, uint32, double*); +extern void TIFFCvtIEEEFloatToNative(TIFF*, uint32, float*); +extern void TIFFCvtIEEEDoubleToNative(TIFF*, uint32, double*); #endif -static TIFFDirEntry* TIFFReadDirectoryFind(TIFFDirEntry* dir, - uint16 dircount, uint16 tagid); -static int EstimateStripByteCounts(TIFF*, TIFFDirEntry*, uint16); -static void MissingRequired(TIFF*, const char*); -static int TIFFCheckDirOffset(TIFF*, toff_t); -static int CheckDirCount(TIFF*, TIFFDirEntry*, uint32); -static uint16 TIFFFetchDirectory(TIFF*, toff_t, TIFFDirEntry**, toff_t *); -static tsize_t TIFFFetchData(TIFF*, TIFFDirEntry*, char*); -static tsize_t TIFFFetchString(TIFF*, TIFFDirEntry*, char*); -static float TIFFFetchRational(TIFF*, TIFFDirEntry*); -static int TIFFFetchNormalTag(TIFF*, TIFFDirEntry*); -static int TIFFFetchPerSampleShorts(TIFF*, TIFFDirEntry*, uint16*); -static int TIFFFetchPerSampleLongs(TIFF*, TIFFDirEntry*, uint32*); -static int TIFFFetchPerSampleAnys(TIFF*, TIFFDirEntry*, double*); -static int TIFFFetchShortArray(TIFF*, TIFFDirEntry*, uint16*); -static int TIFFFetchStripThing(TIFF*, TIFFDirEntry*, long, uint32**); -static int TIFFFetchRefBlackWhite(TIFF*, TIFFDirEntry*); -static int TIFFFetchSubjectDistance(TIFF*, TIFFDirEntry*); -static float TIFFFetchFloat(TIFF*, TIFFDirEntry*); -static int TIFFFetchFloatArray(TIFF*, TIFFDirEntry*, float*); -static int TIFFFetchDoubleArray(TIFF*, TIFFDirEntry*, double*); -static int TIFFFetchAnyArray(TIFF*, TIFFDirEntry*, double*); -static int TIFFFetchShortPair(TIFF*, TIFFDirEntry*); -static void ChopUpSingleUncompressedStrip(TIFF*); +enum TIFFReadDirEntryErr { + TIFFReadDirEntryErrOk = 0, + TIFFReadDirEntryErrCount = 1, + TIFFReadDirEntryErrType = 2, + TIFFReadDirEntryErrIo = 3, + TIFFReadDirEntryErrRange = 4, + TIFFReadDirEntryErrPsdif = 5, + TIFFReadDirEntryErrSizesan = 6, + TIFFReadDirEntryErrAlloc = 7, +}; + +static enum TIFFReadDirEntryErr TIFFReadDirEntryByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryFloat(TIFF* tif, TIFFDirEntry* direntry, float* value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryDouble(TIFF* tif, TIFFDirEntry* direntry, double* value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8(TIFF* tif, TIFFDirEntry* direntry, uint64* value); + +static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryByteArray(TIFF* tif, TIFFDirEntry* direntry, uint8** value); +static enum TIFFReadDirEntryErr TIFFReadDirEntrySbyteArray(TIFF* tif, TIFFDirEntry* direntry, int8** value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryShortArray(TIFF* tif, TIFFDirEntry* direntry, uint16** value); +static enum TIFFReadDirEntryErr TIFFReadDirEntrySshortArray(TIFF* tif, TIFFDirEntry* direntry, int16** value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryLongArray(TIFF* tif, TIFFDirEntry* direntry, uint32** value); +static enum TIFFReadDirEntryErr TIFFReadDirEntrySlongArray(TIFF* tif, TIFFDirEntry* direntry, int32** value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value); +static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8Array(TIFF* tif, TIFFDirEntry* direntry, int64** value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryFloatArray(TIFF* tif, TIFFDirEntry* direntry, float** value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryDoubleArray(TIFF* tif, TIFFDirEntry* direntry, double** value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value); + +static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value); +#if 0 +static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleDouble(TIFF* tif, TIFFDirEntry* direntry, double* value); +#endif + +static void TIFFReadDirEntryCheckedByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value); +static void TIFFReadDirEntryCheckedSbyte(TIFF* tif, TIFFDirEntry* direntry, int8* value); +static void TIFFReadDirEntryCheckedShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value); +static void TIFFReadDirEntryCheckedSshort(TIFF* tif, TIFFDirEntry* direntry, int16* value); +static void TIFFReadDirEntryCheckedLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value); +static void TIFFReadDirEntryCheckedSlong(TIFF* tif, TIFFDirEntry* direntry, int32* value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSlong8(TIFF* tif, TIFFDirEntry* direntry, int64* value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedRational(TIFF* tif, TIFFDirEntry* direntry, double* value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSrational(TIFF* tif, TIFFDirEntry* direntry, double* value); +static void TIFFReadDirEntryCheckedFloat(TIFF* tif, TIFFDirEntry* direntry, float* value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedDouble(TIFF* tif, TIFFDirEntry* direntry, double* value); + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSbyte(int8 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteShort(uint16 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSshort(int16 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong(uint32 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong(int32 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong8(uint64 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong8(int64 value); + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteByte(uint8 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteShort(uint16 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSshort(int16 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong(uint32 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong(int32 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong8(uint64 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong8(int64 value); + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSbyte(int8 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSshort(int16 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong(uint32 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong(int32 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong8(uint64 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong8(int64 value); + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortShort(uint16 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong(uint32 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong(int32 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong8(uint64 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong8(int64 value); + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSbyte(int8 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSshort(int16 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong(int32 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongLong8(uint64 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong8(int64 value); + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongLong(uint32 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongLong8(uint64 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongSlong8(int64 value); + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Sbyte(int8 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Sshort(int16 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Slong(int32 value); +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Slong8(int64 value); + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlong8Long8(uint64 value); + +static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF* tif, uint64 offset, tmsize_t size, void* dest); +static void TIFFReadDirEntryOutputErr(TIFF* tif, enum TIFFReadDirEntryErr err, const char* module, const char* tagname, int recover); + +static void TIFFReadDirectoryCheckOrder(TIFF* tif, TIFFDirEntry* dir, uint16 dircount); +static TIFFDirEntry* TIFFReadDirectoryFindEntry(TIFF* tif, TIFFDirEntry* dir, uint16 dircount, uint16 tagid); +static void TIFFReadDirectoryFindFieldInfo(TIFF* tif, uint16 tagid, uint32* fii); + +static int EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount); +static void MissingRequired(TIFF*, const char*); +static int TIFFCheckDirOffset(TIFF* tif, uint64 diroff); +static int CheckDirCount(TIFF*, TIFFDirEntry*, uint32); +static uint16 TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntry** pdir, uint64* nextdiroff); +static int TIFFFetchNormalTag(TIFF*, TIFFDirEntry*, int recover); +static int TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uint64** lpp); +static int TIFFFetchSubjectDistance(TIFF*, TIFFDirEntry*); +static void ChopUpSingleUncompressedStrip(TIFF*); +static uint64 TIFFReadUInt64(const uint8 *value); + +typedef union _UInt64Aligned_t +{ + double d; + uint64 l; + uint32 i[2]; + uint16 s[4]; + uint8 c[8]; +} UInt64Aligned_t; + +/* + Unaligned safe copy of a uint64 value from an octet array. +*/ +static uint64 TIFFReadUInt64(const uint8 *value) +{ + UInt64Aligned_t result; + + result.c[0]=value[0]; + result.c[1]=value[1]; + result.c[2]=value[2]; + result.c[3]=value[3]; + result.c[4]=value[4]; + result.c[5]=value[5]; + result.c[6]=value[6]; + result.c[7]=value[7]; + + return result.l; +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value) +{ + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count!=1) + return(TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + TIFFReadDirEntryCheckedByte(tif,direntry,value); + return(TIFFReadDirEntryErrOk); + case TIFF_SBYTE: + { + int8 m; + TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeByteSbyte(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint8)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16 m; + TIFFReadDirEntryCheckedShort(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeByteShort(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint8)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16 m; + TIFFReadDirEntryCheckedSshort(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeByteSshort(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint8)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32 m; + TIFFReadDirEntryCheckedLong(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeByteLong(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint8)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32 m; + TIFFReadDirEntryCheckedSlong(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeByteSlong(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint8)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64 m; + err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + err=TIFFReadDirEntryCheckRangeByteLong8(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint8)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64 m; + err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + err=TIFFReadDirEntryCheckRangeByteSlong8(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint8)m; + return(TIFFReadDirEntryErrOk); + } + default: + return(TIFFReadDirEntryErrType); + } +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value) +{ + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count!=1) + return(TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8 m; + TIFFReadDirEntryCheckedByte(tif,direntry,&m); + *value=(uint16)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8 m; + TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeShortSbyte(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint16)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + TIFFReadDirEntryCheckedShort(tif,direntry,value); + return(TIFFReadDirEntryErrOk); + case TIFF_SSHORT: + { + int16 m; + TIFFReadDirEntryCheckedSshort(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeShortSshort(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint16)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32 m; + TIFFReadDirEntryCheckedLong(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeShortLong(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint16)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32 m; + TIFFReadDirEntryCheckedSlong(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeShortSlong(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint16)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64 m; + err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + err=TIFFReadDirEntryCheckRangeShortLong8(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint16)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64 m; + err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + err=TIFFReadDirEntryCheckRangeShortSlong8(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint16)m; + return(TIFFReadDirEntryErrOk); + } + default: + return(TIFFReadDirEntryErrType); + } +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value) +{ + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count!=1) + return(TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8 m; + TIFFReadDirEntryCheckedByte(tif,direntry,&m); + *value=(uint32)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8 m; + TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeLongSbyte(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint32)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16 m; + TIFFReadDirEntryCheckedShort(tif,direntry,&m); + *value=(uint32)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16 m; + TIFFReadDirEntryCheckedSshort(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeLongSshort(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint32)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + TIFFReadDirEntryCheckedLong(tif,direntry,value); + return(TIFFReadDirEntryErrOk); + case TIFF_SLONG: + { + int32 m; + TIFFReadDirEntryCheckedSlong(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeLongSlong(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint32)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64 m; + err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + err=TIFFReadDirEntryCheckRangeLongLong8(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint32)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64 m; + err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + err=TIFFReadDirEntryCheckRangeLongSlong8(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint32)m; + return(TIFFReadDirEntryErrOk); + } + default: + return(TIFFReadDirEntryErrType); + } +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value) +{ + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count!=1) + return(TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8 m; + TIFFReadDirEntryCheckedByte(tif,direntry,&m); + *value=(uint64)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8 m; + TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeLong8Sbyte(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint64)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16 m; + TIFFReadDirEntryCheckedShort(tif,direntry,&m); + *value=(uint64)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16 m; + TIFFReadDirEntryCheckedSshort(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeLong8Sshort(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint64)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32 m; + TIFFReadDirEntryCheckedLong(tif,direntry,&m); + *value=(uint64)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32 m; + TIFFReadDirEntryCheckedSlong(tif,direntry,&m); + err=TIFFReadDirEntryCheckRangeLong8Slong(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint64)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + err=TIFFReadDirEntryCheckedLong8(tif,direntry,value); + return(err); + case TIFF_SLONG8: + { + int64 m; + err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + err=TIFFReadDirEntryCheckRangeLong8Slong8(m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(uint64)m; + return(TIFFReadDirEntryErrOk); + } + default: + return(TIFFReadDirEntryErrType); + } +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryFloat(TIFF* tif, TIFFDirEntry* direntry, float* value) +{ + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count!=1) + return(TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8 m; + TIFFReadDirEntryCheckedByte(tif,direntry,&m); + *value=(float)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8 m; + TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); + *value=(float)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16 m; + TIFFReadDirEntryCheckedShort(tif,direntry,&m); + *value=(float)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16 m; + TIFFReadDirEntryCheckedSshort(tif,direntry,&m); + *value=(float)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32 m; + TIFFReadDirEntryCheckedLong(tif,direntry,&m); + *value=(float)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32 m; + TIFFReadDirEntryCheckedSlong(tif,direntry,&m); + *value=(float)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64 m; + err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); +#if defined(__WIN32__) && (_MSC_VER < 1500) + /* + * XXX: MSVC 6.0 does not support conversion + * of 64-bit integers into floating point + * values. + */ + *value = _TIFFUInt64ToFloat(m); +#else + *value=(float)m; +#endif + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64 m; + err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(float)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_RATIONAL: + { + double m; + err=TIFFReadDirEntryCheckedRational(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(float)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SRATIONAL: + { + double m; + err=TIFFReadDirEntryCheckedSrational(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(float)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_FLOAT: + TIFFReadDirEntryCheckedFloat(tif,direntry,value); + return(TIFFReadDirEntryErrOk); + case TIFF_DOUBLE: + { + double m; + err=TIFFReadDirEntryCheckedDouble(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(float)m; + return(TIFFReadDirEntryErrOk); + } + default: + return(TIFFReadDirEntryErrType); + } +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryDouble(TIFF* tif, TIFFDirEntry* direntry, double* value) +{ + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count!=1) + return(TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8 m; + TIFFReadDirEntryCheckedByte(tif,direntry,&m); + *value=(double)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8 m; + TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); + *value=(double)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16 m; + TIFFReadDirEntryCheckedShort(tif,direntry,&m); + *value=(double)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16 m; + TIFFReadDirEntryCheckedSshort(tif,direntry,&m); + *value=(double)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32 m; + TIFFReadDirEntryCheckedLong(tif,direntry,&m); + *value=(double)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32 m; + TIFFReadDirEntryCheckedSlong(tif,direntry,&m); + *value=(double)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64 m; + err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); +#if defined(__WIN32__) && (_MSC_VER < 1500) + /* + * XXX: MSVC 6.0 does not support conversion + * of 64-bit integers into floating point + * values. + */ + *value = _TIFFUInt64ToDouble(m); +#else + *value = (double)m; +#endif + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64 m; + err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + *value=(double)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_RATIONAL: + err=TIFFReadDirEntryCheckedRational(tif,direntry,value); + return(err); + case TIFF_SRATIONAL: + err=TIFFReadDirEntryCheckedSrational(tif,direntry,value); + return(err); + case TIFF_FLOAT: + { + float m; + TIFFReadDirEntryCheckedFloat(tif,direntry,&m); + *value=(double)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_DOUBLE: + err=TIFFReadDirEntryCheckedDouble(tif,direntry,value); + return(err); + default: + return(TIFFReadDirEntryErrType); + } +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8(TIFF* tif, TIFFDirEntry* direntry, uint64* value) +{ + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count!=1) + return(TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_LONG: + case TIFF_IFD: + { + uint32 m; + TIFFReadDirEntryCheckedLong(tif,direntry,&m); + *value=(uint64)m; + return(TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + case TIFF_IFD8: + err=TIFFReadDirEntryCheckedLong8(tif,direntry,value); + return(err); + default: + return(TIFFReadDirEntryErrType); + } +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value) +{ + int typesize; + uint32 datasize; + void* data; + typesize=TIFFDataWidth(direntry->tdir_type); + if ((direntry->tdir_count==0)||(typesize==0)) + { + *value=0; + return(TIFFReadDirEntryErrOk); + } + (void) desttypesize; + + /* + * As a sanity check, make sure we have no more than a 2GB tag array + * 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)tdir_count) + return(TIFFReadDirEntryErrSizesan); + if ((uint64)(2147483647/desttypesize)tdir_count) + return(TIFFReadDirEntryErrSizesan); + + *count=(uint32)direntry->tdir_count; + datasize=(*count)*typesize; + assert((tmsize_t)datasize>0); + data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray"); + if (data==0) + return(TIFFReadDirEntryErrAlloc); + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + if (datasize<=4) + _TIFFmemcpy(data,&direntry->tdir_offset,datasize); + else + { + enum TIFFReadDirEntryErr err; + uint32 offset = direntry->tdir_offset.toff_long; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(&offset); + err=TIFFReadDirEntryData(tif,(uint64)offset,(tmsize_t)datasize,data); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(data); + return(err); + } + } + } + else + { + if (datasize<=8) + _TIFFmemcpy(data,&direntry->tdir_offset,datasize); + else + { + enum TIFFReadDirEntryErr err; + uint64 offset = direntry->tdir_offset.toff_long8; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8(&offset); + err=TIFFReadDirEntryData(tif,offset,(tmsize_t)datasize,data); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(data); + return(err); + } + } + } + *value=data; + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryByteArray(TIFF* tif, TIFFDirEntry* direntry, uint8** value) +{ + enum TIFFReadDirEntryErr err; + uint32 count; + void* origdata; + uint8* data; + switch (direntry->tdir_type) + { + case TIFF_ASCII: + case TIFF_UNDEFINED: + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return(TIFFReadDirEntryErrType); + } + err=TIFFReadDirEntryArray(tif,direntry,&count,1,&origdata); + if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) + { + *value=0; + return(err); + } + switch (direntry->tdir_type) + { + case TIFF_ASCII: + case TIFF_UNDEFINED: + case TIFF_BYTE: + *value=(uint8*)origdata; + return(TIFFReadDirEntryErrOk); + case TIFF_SBYTE: + { + int8* m; + uint32 n; + m=(int8*)origdata; + for (n=0; ntdir_type) + { + case TIFF_SHORT: + { + uint16* ma; + uint8* mb; + uint32 n; + ma=(uint16*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort(ma); + err=TIFFReadDirEntryCheckRangeByteShort(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint8)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16* ma; + uint8* mb; + uint32 n; + ma=(int16*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)ma); + err=TIFFReadDirEntryCheckRangeByteSshort(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint8)(*ma++); + } + } + break; + case TIFF_LONG: + { + uint32* ma; + uint8* mb; + uint32 n; + ma=(uint32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + err=TIFFReadDirEntryCheckRangeByteLong(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint8)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32* ma; + uint8* mb; + uint32 n; + ma=(int32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)ma); + err=TIFFReadDirEntryCheckRangeByteSlong(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint8)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64* ma; + uint8* mb; + uint32 n; + ma=(uint64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8(ma); + err=TIFFReadDirEntryCheckRangeByteLong8(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint8)(*ma++); + } + } + break; + case TIFF_SLONG8: + { + int64* ma; + uint8* mb; + uint32 n; + ma=(int64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)ma); + err=TIFFReadDirEntryCheckRangeByteSlong8(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint8)(*ma++); + } + } + break; + } + _TIFFfree(origdata); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(data); + return(err); + } + *value=data; + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntrySbyteArray(TIFF* tif, TIFFDirEntry* direntry, int8** value) +{ + enum TIFFReadDirEntryErr err; + uint32 count; + void* origdata; + int8* data; + switch (direntry->tdir_type) + { + case TIFF_UNDEFINED: + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return(TIFFReadDirEntryErrType); + } + err=TIFFReadDirEntryArray(tif,direntry,&count,1,&origdata); + if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) + { + *value=0; + return(err); + } + switch (direntry->tdir_type) + { + case TIFF_UNDEFINED: + case TIFF_BYTE: + { + uint8* m; + uint32 n; + m=(uint8*)origdata; + for (n=0; ntdir_type) + { + case TIFF_SHORT: + { + uint16* ma; + int8* mb; + uint32 n; + ma=(uint16*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort(ma); + err=TIFFReadDirEntryCheckRangeSbyteShort(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(int8)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16* ma; + int8* mb; + uint32 n; + ma=(int16*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)ma); + err=TIFFReadDirEntryCheckRangeSbyteSshort(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(int8)(*ma++); + } + } + break; + case TIFF_LONG: + { + uint32* ma; + int8* mb; + uint32 n; + ma=(uint32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + err=TIFFReadDirEntryCheckRangeSbyteLong(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(int8)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32* ma; + int8* mb; + uint32 n; + ma=(int32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)ma); + err=TIFFReadDirEntryCheckRangeSbyteSlong(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(int8)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64* ma; + int8* mb; + uint32 n; + ma=(uint64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8(ma); + err=TIFFReadDirEntryCheckRangeSbyteLong8(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(int8)(*ma++); + } + } + break; + case TIFF_SLONG8: + { + int64* ma; + int8* mb; + uint32 n; + ma=(int64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)ma); + err=TIFFReadDirEntryCheckRangeSbyteSlong8(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(int8)(*ma++); + } + } + break; + } + _TIFFfree(origdata); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(data); + return(err); + } + *value=data; + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryShortArray(TIFF* tif, TIFFDirEntry* direntry, uint16** value) +{ + enum TIFFReadDirEntryErr err; + uint32 count; + void* origdata; + uint16* data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return(TIFFReadDirEntryErrType); + } + err=TIFFReadDirEntryArray(tif,direntry,&count,2,&origdata); + if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) + { + *value=0; + return(err); + } + switch (direntry->tdir_type) + { + case TIFF_SHORT: + *value=(uint16*)origdata; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfShort(*value,count); + return(TIFFReadDirEntryErrOk); + case TIFF_SSHORT: + { + int16* m; + uint32 n; + m=(int16*)origdata; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)m); + err=TIFFReadDirEntryCheckRangeShortSshort(*m); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(origdata); + return(err); + } + m++; + } + *value=(uint16*)origdata; + return(TIFFReadDirEntryErrOk); + } + } + data=(uint16*)_TIFFmalloc(count*2); + if (data==0) + { + _TIFFfree(origdata); + return(TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8* ma; + uint16* mb; + uint32 n; + ma=(uint8*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + err=TIFFReadDirEntryCheckRangeShortLong(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint16)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32* ma; + uint16* mb; + uint32 n; + ma=(int32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)ma); + err=TIFFReadDirEntryCheckRangeShortSlong(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint16)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64* ma; + uint16* mb; + uint32 n; + ma=(uint64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8(ma); + err=TIFFReadDirEntryCheckRangeShortLong8(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint16)(*ma++); + } + } + break; + case TIFF_SLONG8: + { + int64* ma; + uint16* mb; + uint32 n; + ma=(int64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)ma); + err=TIFFReadDirEntryCheckRangeShortSlong8(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint16)(*ma++); + } + } + break; + } + _TIFFfree(origdata); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(data); + return(err); + } + *value=data; + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntrySshortArray(TIFF* tif, TIFFDirEntry* direntry, int16** value) +{ + enum TIFFReadDirEntryErr err; + uint32 count; + void* origdata; + int16* data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return(TIFFReadDirEntryErrType); + } + err=TIFFReadDirEntryArray(tif,direntry,&count,2,&origdata); + if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) + { + *value=0; + return(err); + } + switch (direntry->tdir_type) + { + case TIFF_SHORT: + { + uint16* m; + uint32 n; + m=(uint16*)origdata; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort(m); + err=TIFFReadDirEntryCheckRangeSshortShort(*m); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(origdata); + return(err); + } + m++; + } + *value=(int16*)origdata; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + *value=(int16*)origdata; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfShort((uint16*)(*value),count); + return(TIFFReadDirEntryErrOk); + } + data=(int16*)_TIFFmalloc(count*2); + if (data==0) + { + _TIFFfree(origdata); + return(TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8* ma; + int16* mb; + uint32 n; + ma=(uint8*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + err=TIFFReadDirEntryCheckRangeSshortLong(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(int16)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32* ma; + int16* mb; + uint32 n; + ma=(int32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)ma); + err=TIFFReadDirEntryCheckRangeSshortSlong(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(int16)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64* ma; + int16* mb; + uint32 n; + ma=(uint64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8(ma); + err=TIFFReadDirEntryCheckRangeSshortLong8(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(int16)(*ma++); + } + } + break; + case TIFF_SLONG8: + { + int64* ma; + int16* mb; + uint32 n; + ma=(int64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)ma); + err=TIFFReadDirEntryCheckRangeSshortSlong8(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(int16)(*ma++); + } + } + break; + } + _TIFFfree(origdata); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(data); + return(err); + } + *value=data; + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryLongArray(TIFF* tif, TIFFDirEntry* direntry, uint32** value) +{ + enum TIFFReadDirEntryErr err; + uint32 count; + void* origdata; + uint32* data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return(TIFFReadDirEntryErrType); + } + err=TIFFReadDirEntryArray(tif,direntry,&count,4,&origdata); + if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) + { + *value=0; + return(err); + } + switch (direntry->tdir_type) + { + case TIFF_LONG: + *value=(uint32*)origdata; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong(*value,count); + return(TIFFReadDirEntryErrOk); + case TIFF_SLONG: + { + int32* m; + uint32 n; + m=(int32*)origdata; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)m); + err=TIFFReadDirEntryCheckRangeLongSlong(*m); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(origdata); + return(err); + } + m++; + } + *value=(uint32*)origdata; + return(TIFFReadDirEntryErrOk); + } + } + data=(uint32*)_TIFFmalloc(count*4); + if (data==0) + { + _TIFFfree(origdata); + return(TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8* ma; + uint32* mb; + uint32 n; + ma=(uint8*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort(ma); + *mb++=(uint32)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16* ma; + uint32* mb; + uint32 n; + ma=(int16*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)ma); + err=TIFFReadDirEntryCheckRangeLongSshort(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint32)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64* ma; + uint32* mb; + uint32 n; + ma=(uint64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8(ma); + err=TIFFReadDirEntryCheckRangeLongLong8(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint32)(*ma++); + } + } + break; + case TIFF_SLONG8: + { + int64* ma; + uint32* mb; + uint32 n; + ma=(int64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)ma); + err=TIFFReadDirEntryCheckRangeLongSlong8(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint32)(*ma++); + } + } + break; + } + _TIFFfree(origdata); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(data); + return(err); + } + *value=data; + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntrySlongArray(TIFF* tif, TIFFDirEntry* direntry, int32** value) +{ + enum TIFFReadDirEntryErr err; + uint32 count; + void* origdata; + int32* data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return(TIFFReadDirEntryErrType); + } + err=TIFFReadDirEntryArray(tif,direntry,&count,4,&origdata); + if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) + { + *value=0; + return(err); + } + switch (direntry->tdir_type) + { + case TIFF_LONG: + { + uint32* m; + uint32 n; + m=(uint32*)origdata; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)m); + err=TIFFReadDirEntryCheckRangeSlongLong(*m); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(origdata); + return(err); + } + m++; + } + *value=(int32*)origdata; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + *value=(int32*)origdata; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong((uint32*)(*value),count); + return(TIFFReadDirEntryErrOk); + } + data=(int32*)_TIFFmalloc(count*4); + if (data==0) + { + _TIFFfree(origdata); + return(TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8* ma; + int32* mb; + uint32 n; + ma=(uint8*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort(ma); + *mb++=(int32)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16* ma; + int32* mb; + uint32 n; + ma=(int16*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)ma); + *mb++=(int32)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64* ma; + int32* mb; + uint32 n; + ma=(uint64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8(ma); + err=TIFFReadDirEntryCheckRangeSlongLong8(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(int32)(*ma++); + } + } + break; + case TIFF_SLONG8: + { + int64* ma; + int32* mb; + uint32 n; + ma=(int64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)ma); + err=TIFFReadDirEntryCheckRangeSlongSlong8(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(int32)(*ma++); + } + } + break; + } + _TIFFfree(origdata); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(data); + return(err); + } + *value=data; + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value) +{ + enum TIFFReadDirEntryErr err; + uint32 count; + void* origdata; + uint64* data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return(TIFFReadDirEntryErrType); + } + err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata); + if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) + { + *value=0; + return(err); + } + switch (direntry->tdir_type) + { + case TIFF_LONG8: + *value=(uint64*)origdata; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong8(*value,count); + return(TIFFReadDirEntryErrOk); + case TIFF_SLONG8: + { + int64* m; + uint32 n; + m=(int64*)origdata; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)m); + err=TIFFReadDirEntryCheckRangeLong8Slong8(*m); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(origdata); + return(err); + } + m++; + } + *value=(uint64*)origdata; + return(TIFFReadDirEntryErrOk); + } + } + data=(uint64*)_TIFFmalloc(count*8); + if (data==0) + { + _TIFFfree(origdata); + return(TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8* ma; + uint64* mb; + uint32 n; + ma=(uint8*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort(ma); + *mb++=(uint64)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16* ma; + uint64* mb; + uint32 n; + ma=(int16*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)ma); + err=TIFFReadDirEntryCheckRangeLong8Sshort(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint64)(*ma++); + } + } + break; + case TIFF_LONG: + { + uint32* ma; + uint64* mb; + uint32 n; + ma=(uint32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + *mb++=(uint64)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32* ma; + uint64* mb; + uint32 n; + ma=(int32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)ma); + err=TIFFReadDirEntryCheckRangeLong8Slong(*ma); + if (err!=TIFFReadDirEntryErrOk) + break; + *mb++=(uint64)(*ma++); + } + } + break; + } + _TIFFfree(origdata); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(data); + return(err); + } + *value=data; + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8Array(TIFF* tif, TIFFDirEntry* direntry, int64** value) +{ + enum TIFFReadDirEntryErr err; + uint32 count; + void* origdata; + int64* data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return(TIFFReadDirEntryErrType); + } + err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata); + if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) + { + *value=0; + return(err); + } + switch (direntry->tdir_type) + { + case TIFF_LONG8: + { + uint64* m; + uint32 n; + m=(uint64*)origdata; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8(m); + err=TIFFReadDirEntryCheckRangeSlong8Long8(*m); + if (err!=TIFFReadDirEntryErrOk) + { + _TIFFfree(origdata); + return(err); + } + m++; + } + *value=(int64*)origdata; + return(TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + *value=(int64*)origdata; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong8((uint64*)(*value),count); + return(TIFFReadDirEntryErrOk); + } + data=(int64*)_TIFFmalloc(count*8); + if (data==0) + { + _TIFFfree(origdata); + return(TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8* ma; + int64* mb; + uint32 n; + ma=(uint8*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort(ma); + *mb++=(int64)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16* ma; + int64* mb; + uint32 n; + ma=(int16*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)ma); + *mb++=(int64)(*ma++); + } + } + break; + case TIFF_LONG: + { + uint32* ma; + int64* mb; + uint32 n; + ma=(uint32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + *mb++=(int64)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32* ma; + int64* mb; + uint32 n; + ma=(int32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)ma); + *mb++=(int64)(*ma++); + } + } + break; + } + _TIFFfree(origdata); + *value=data; + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryFloatArray(TIFF* tif, TIFFDirEntry* direntry, float** value) +{ + enum TIFFReadDirEntryErr err; + uint32 count; + void* origdata; + float* data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + case TIFF_DOUBLE: + break; + default: + return(TIFFReadDirEntryErrType); + } + err=TIFFReadDirEntryArray(tif,direntry,&count,4,&origdata); + if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) + { + *value=0; + return(err); + } + switch (direntry->tdir_type) + { + case TIFF_FLOAT: + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong((uint32*)origdata,count); + TIFFCvtIEEEDoubleToNative(tif,count,(float*)origdata); + *value=(float*)origdata; + return(TIFFReadDirEntryErrOk); + } + data=(float*)_TIFFmalloc(count*sizeof(float)); + if (data==0) + { + _TIFFfree(origdata); + return(TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8* ma; + float* mb; + uint32 n; + ma=(uint8*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort(ma); + *mb++=(float)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16* ma; + float* mb; + uint32 n; + ma=(int16*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)ma); + *mb++=(float)(*ma++); + } + } + break; + case TIFF_LONG: + { + uint32* ma; + float* mb; + uint32 n; + ma=(uint32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + *mb++=(float)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32* ma; + float* mb; + uint32 n; + ma=(int32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)ma); + *mb++=(float)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64* ma; + float* mb; + uint32 n; + ma=(uint64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8(ma); +#if defined(__WIN32__) && (_MSC_VER < 1500) + /* + * XXX: MSVC 6.0 does not support + * conversion of 64-bit integers into + * floating point values. + */ + *mb++ = _TIFFUInt64ToFloat(*ma++); +#else + *mb++ = (float)(*ma++); +#endif + } + } + break; + case TIFF_SLONG8: + { + int64* ma; + float* mb; + uint32 n; + ma=(int64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)ma); + *mb++=(float)(*ma++); + } + } + break; + case TIFF_RATIONAL: + { + uint32* ma; + uint32 maa; + uint32 mab; + float* mb; + uint32 n; + ma=(uint32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + maa=*ma++; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + mab=*ma++; + if (mab==0) + *mb++=0.0; + else + *mb++=(float)maa/(float)mab; + } + } + break; + case TIFF_SRATIONAL: + { + uint32* ma; + int32 maa; + uint32 mab; + float* mb; + uint32 n; + ma=(uint32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + maa=*(int32*)ma; + ma++; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + mab=*ma++; + if (mab==0) + *mb++=0.0; + else + *mb++=(float)maa/(float)mab; + } + } + break; + case TIFF_DOUBLE: + { + double* ma; + float* mb; + uint32 n; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong8((uint64*)origdata,count); + TIFFCvtIEEEDoubleToNative(tif,count,(double*)origdata); + ma=(double*)origdata; + mb=data; + for (n=0; ntdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + case TIFF_DOUBLE: + break; + default: + return(TIFFReadDirEntryErrType); + } + err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata); + if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) + { + *value=0; + return(err); + } + switch (direntry->tdir_type) + { + case TIFF_DOUBLE: + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong8((uint64*)origdata,count); + TIFFCvtIEEEDoubleToNative(tif,count,(double*)origdata); + *value=(double*)origdata; + return(TIFFReadDirEntryErrOk); + } + data=(double*)_TIFFmalloc(count*sizeof(double)); + if (data==0) + { + _TIFFfree(origdata); + return(TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8* ma; + double* mb; + uint32 n; + ma=(uint8*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort(ma); + *mb++=(double)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16* ma; + double* mb; + uint32 n; + ma=(int16*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)ma); + *mb++=(double)(*ma++); + } + } + break; + case TIFF_LONG: + { + uint32* ma; + double* mb; + uint32 n; + ma=(uint32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + *mb++=(double)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32* ma; + double* mb; + uint32 n; + ma=(int32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)ma); + *mb++=(double)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64* ma; + double* mb; + uint32 n; + ma=(uint64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8(ma); +#if defined(__WIN32__) && (_MSC_VER < 1500) + /* + * XXX: MSVC 6.0 does not support + * conversion of 64-bit integers into + * floating point values. + */ + *mb++ = _TIFFUInt64ToDouble(*ma++); +#else + *mb++ = (double)(*ma++); +#endif + } + } + break; + case TIFF_SLONG8: + { + int64* ma; + double* mb; + uint32 n; + ma=(int64*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)ma); + *mb++=(double)(*ma++); + } + } + break; + case TIFF_RATIONAL: + { + uint32* ma; + uint32 maa; + uint32 mab; + double* mb; + uint32 n; + ma=(uint32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + maa=*ma++; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + mab=*ma++; + if (mab==0) + *mb++=0.0; + else + *mb++=(double)maa/(double)mab; + } + } + break; + case TIFF_SRATIONAL: + { + uint32* ma; + int32 maa; + uint32 mab; + double* mb; + uint32 n; + ma=(uint32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + maa=*(int32*)ma; + ma++; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + mab=*ma++; + if (mab==0) + *mb++=0.0; + else + *mb++=(double)maa/(double)mab; + } + } + break; + case TIFF_FLOAT: + { + float* ma; + double* mb; + uint32 n; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong((uint32*)origdata,count); + TIFFCvtIEEEFloatToNative(tif,count,(float*)origdata); + ma=(float*)origdata; + mb=data; + for (n=0; ntdir_type) + { + case TIFF_LONG: + case TIFF_LONG8: + case TIFF_IFD: + case TIFF_IFD8: + break; + default: + return(TIFFReadDirEntryErrType); + } + err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata); + if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) + { + *value=0; + return(err); + } + switch (direntry->tdir_type) + { + case TIFF_LONG8: + case TIFF_IFD8: + *value=(uint64*)origdata; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong8(*value,count); + return(TIFFReadDirEntryErrOk); + } + data=(uint64*)_TIFFmalloc(count*8); + if (data==0) + { + _TIFFfree(origdata); + return(TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_LONG: + case TIFF_IFD: + { + uint32* ma; + uint64* mb; + uint32 n; + ma=(uint32*)origdata; + mb=data; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabLong(ma); + *mb++=(uint64)(*ma++); + } + } + break; + } + _TIFFfree(origdata); + *value=data; + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value) +{ + enum TIFFReadDirEntryErr err; + uint16* m; + uint16* na; + uint16 nb; + if (direntry->tdir_count<(uint64)tif->tif_dir.td_samplesperpixel) + return(TIFFReadDirEntryErrCount); + err=TIFFReadDirEntryShortArray(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + na=m; + nb=tif->tif_dir.td_samplesperpixel; + *value=*na++; + nb--; + while (nb>0) + { + if (*na++!=*value) + { + err=TIFFReadDirEntryErrPsdif; + break; + } + nb--; + } + _TIFFfree(m); + return(err); +} + +#if 0 +static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleDouble(TIFF* tif, TIFFDirEntry* direntry, double* value) +{ + enum TIFFReadDirEntryErr err; + double* m; + double* na; + uint16 nb; + if (direntry->tdir_count<(uint64)tif->tif_dir.td_samplesperpixel) + return(TIFFReadDirEntryErrCount); + err=TIFFReadDirEntryDoubleArray(tif,direntry,&m); + if (err!=TIFFReadDirEntryErrOk) + return(err); + na=m; + nb=tif->tif_dir.td_samplesperpixel; + *value=*na++; + nb--; + while (nb>0) + { + if (*na++!=*value) + { + err=TIFFReadDirEntryErrPsdif; + break; + } + nb--; + } + _TIFFfree(m); + return(err); +} +#endif + +static void TIFFReadDirEntryCheckedByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value) +{ + (void) tif; + *value=*(uint8*)(&direntry->tdir_offset); +} + +static void TIFFReadDirEntryCheckedSbyte(TIFF* tif, TIFFDirEntry* direntry, int8* value) +{ + (void) tif; + *value=*(int8*)(&direntry->tdir_offset); +} + +static void TIFFReadDirEntryCheckedShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value) +{ + *value = direntry->tdir_offset.toff_short; + /* *value=*(uint16*)(&direntry->tdir_offset); */ + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort(value); +} + +static void TIFFReadDirEntryCheckedSshort(TIFF* tif, TIFFDirEntry* direntry, int16* value) +{ + *value=*(int16*)(&direntry->tdir_offset); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)value); +} + +static void TIFFReadDirEntryCheckedLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value) +{ + *value=*(uint32*)(&direntry->tdir_offset); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(value); +} + +static void TIFFReadDirEntryCheckedSlong(TIFF* tif, TIFFDirEntry* direntry, int32* value) +{ + *value=*(int32*)(&direntry->tdir_offset); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)value); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value) +{ + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + enum TIFFReadDirEntryErr err; + uint32 offset = direntry->tdir_offset.toff_long; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(&offset); + err=TIFFReadDirEntryData(tif,offset,8,value); + if (err!=TIFFReadDirEntryErrOk) + return(err); + } + else + *value = direntry->tdir_offset.toff_long8; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8(value); + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSlong8(TIFF* tif, TIFFDirEntry* direntry, int64* value) +{ + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + enum TIFFReadDirEntryErr err; + uint32 offset = direntry->tdir_offset.toff_long; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(&offset); + err=TIFFReadDirEntryData(tif,offset,8,value); + if (err!=TIFFReadDirEntryErrOk) + return(err); + } + else + *value=*(int64*)(&direntry->tdir_offset); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)value); + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedRational(TIFF* tif, TIFFDirEntry* direntry, double* value) +{ + UInt64Aligned_t m; + + assert(sizeof(double)==8); + assert(sizeof(uint64)==8); + assert(sizeof(uint32)==4); + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + enum TIFFReadDirEntryErr err; + uint32 offset = direntry->tdir_offset.toff_long; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(&offset); + err=TIFFReadDirEntryData(tif,offset,8,m.i); + if (err!=TIFFReadDirEntryErrOk) + return(err); + } + else + m.l = direntry->tdir_offset.toff_long8; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong(m.i,2); + if (m.i[0]==0) + *value=0.0; + else + *value=(double)m.i[0]/(double)m.i[1]; + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSrational(TIFF* tif, TIFFDirEntry* direntry, double* value) +{ + UInt64Aligned_t m; + assert(sizeof(double)==8); + assert(sizeof(uint64)==8); + assert(sizeof(int32)==4); + assert(sizeof(uint32)==4); + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + enum TIFFReadDirEntryErr err; + uint32 offset = direntry->tdir_offset.toff_long; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(&offset); + err=TIFFReadDirEntryData(tif,offset,8,m.i); + if (err!=TIFFReadDirEntryErrOk) + return(err); + } + else + m.l=direntry->tdir_offset.toff_long8; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong(m.i,2); + if ((int32)m.i[0]==0) + *value=0.0; + else + *value=(double)((int32)m.i[0])/(double)m.i[1]; + return(TIFFReadDirEntryErrOk); +} + +static void TIFFReadDirEntryCheckedFloat(TIFF* tif, TIFFDirEntry* direntry, float* value) +{ + union + { + float f; + uint32 i; + } float_union; + assert(sizeof(float)==4); + assert(sizeof(uint32)==4); + assert(sizeof(float_union)==4); + float_union.i=*(uint32*)(&direntry->tdir_offset); + *value=float_union.f; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)value); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedDouble(TIFF* tif, TIFFDirEntry* direntry, double* value) +{ + assert(sizeof(double)==8); + assert(sizeof(uint64)==8); + assert(sizeof(UInt64Aligned_t)==8); + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + enum TIFFReadDirEntryErr err; + uint32 offset = direntry->tdir_offset.toff_long; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(&offset); + err=TIFFReadDirEntryData(tif,offset,8,value); + if (err!=TIFFReadDirEntryErrOk) + return(err); + } + else + { + UInt64Aligned_t uint64_union; + uint64_union.l=direntry->tdir_offset.toff_long8; + *value=uint64_union.d; + } + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)value); + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSbyte(int8 value) +{ + if (value<0) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteShort(uint16 value) +{ + if (value>0xFF) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSshort(int16 value) +{ + if ((value<0)||(value>0xFF)) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong(uint32 value) +{ + if (value>0xFF) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong(int32 value) +{ + if ((value<0)||(value>0xFF)) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong8(uint64 value) +{ + if (value>0xFF) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong8(int64 value) +{ + if ((value<0)||(value>0xFF)) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteByte(uint8 value) +{ + if (value>0x7F) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteShort(uint16 value) +{ + if (value>0x7F) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSshort(int16 value) +{ + if ((value<-0x80)||(value>0x7F)) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong(uint32 value) +{ + if (value>0x7F) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong(int32 value) +{ + if ((value<-0x80)||(value>0x7F)) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong8(uint64 value) +{ + if (value>0x7F) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong8(int64 value) +{ + if ((value<-0x80)||(value>0x7F)) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSbyte(int8 value) +{ + if (value<0) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSshort(int16 value) +{ + if (value<0) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong(uint32 value) +{ + if (value>0xFFFF) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong(int32 value) +{ + if ((value<0)||(value>0xFFFF)) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong8(uint64 value) +{ + if (value>0xFFFF) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong8(int64 value) +{ + if ((value<0)||(value>0xFFFF)) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortShort(uint16 value) +{ + if (value>0x7FFF) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong(uint32 value) +{ + if (value>0x7FFF) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong(int32 value) +{ + if ((value<-0x8000)||(value>0x7FFF)) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong8(uint64 value) +{ + if (value>0x7FFF) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong8(int64 value) +{ + if ((value<-0x8000)||(value>0x7FFF)) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSbyte(int8 value) +{ + if (value<0) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSshort(int16 value) +{ + if (value<0) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong(int32 value) +{ + if (value<0) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +/* + * Largest 32-bit unsigned integer value. + */ +#if defined(__WIN32__) && defined(_MSC_VER) +# define TIFF_UINT32_MAX 0xFFFFFFFFI64 +#else +# define TIFF_UINT32_MAX 0xFFFFFFFFLL +#endif + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLongLong8(uint64 value) +{ + if (value > TIFF_UINT32_MAX) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLongSlong8(int64 value) +{ + if ((value<0) || (value > TIFF_UINT32_MAX)) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +#undef TIFF_UINT32_MAX + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSlongLong(uint32 value) +{ + if (value > 0x7FFFFFFFUL) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSlongLong8(uint64 value) +{ + if (value > 0x7FFFFFFFUL) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSlongSlong8(int64 value) +{ + if ((value < 0L-0x80000000L) || (value > 0x7FFFFFFFL)) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLong8Sbyte(int8 value) +{ + if (value < 0) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLong8Sshort(int16 value) +{ + if (value < 0) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLong8Slong(int32 value) +{ + if (value < 0) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLong8Slong8(int64 value) +{ + if (value < 0) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +/* + * Largest 64-bit signed integer value. + */ +#if defined(__WIN32__) && defined(_MSC_VER) +# define TIFF_INT64_MAX 0x7FFFFFFFFFFFFFFFI64 +#else +# define TIFF_INT64_MAX 0x7FFFFFFFFFFFFFFFLL +#endif + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSlong8Long8(uint64 value) +{ + if (value > TIFF_INT64_MAX) + return(TIFFReadDirEntryErrRange); + else + return(TIFFReadDirEntryErrOk); +} + +#undef TIFF_INT64_MAX + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryData(TIFF* tif, uint64 offset, tmsize_t size, void* dest) +{ + assert(size>0); + if (!isMapped(tif)) { + if (!SeekOK(tif,offset)) + return(TIFFReadDirEntryErrIo); + if (!ReadOK(tif,dest,size)) + return(TIFFReadDirEntryErrIo); + } else { + size_t ma,mb; + ma=(size_t)offset; + mb=ma+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); + } + return(TIFFReadDirEntryErrOk); +} + +static void TIFFReadDirEntryOutputErr(TIFF* tif, enum TIFFReadDirEntryErr err, const char* module, const char* tagname, int recover) +{ + if (!recover) { + switch (err) { + case TIFFReadDirEntryErrCount: + TIFFErrorExt(tif->tif_clientdata, module, + "Incorrect count for \"%s\"", + tagname); + break; + case TIFFReadDirEntryErrType: + TIFFErrorExt(tif->tif_clientdata, module, + "Incompatible type for \"%s\"", + tagname); + break; + case TIFFReadDirEntryErrIo: + TIFFErrorExt(tif->tif_clientdata, module, + "IO error during reading of \"%s\"", + tagname); + break; + case TIFFReadDirEntryErrRange: + TIFFErrorExt(tif->tif_clientdata, module, + "Incorrect value for \"%s\"", + tagname); + break; + case TIFFReadDirEntryErrPsdif: + TIFFErrorExt(tif->tif_clientdata, module, + "Cannot handle different values per sample for \"%s\"", + tagname); + break; + case TIFFReadDirEntryErrSizesan: + TIFFErrorExt(tif->tif_clientdata, module, + "Sanity check on size of \"%s\" value failed", + tagname); + break; + case TIFFReadDirEntryErrAlloc: + TIFFErrorExt(tif->tif_clientdata, module, + "Out of memory reading of \"%s\"", + tagname); + break; + default: + assert(0); /* we should never get here */ + break; + } + } else { + switch (err) { + case TIFFReadDirEntryErrCount: + TIFFWarningExt(tif->tif_clientdata, module, + "Incorrect count for \"%s\"; tag ignored", + tagname); + break; + case TIFFReadDirEntryErrType: + TIFFWarningExt(tif->tif_clientdata, module, + "Incompatible type for \"%s\"; tag ignored", + tagname); + break; + case TIFFReadDirEntryErrIo: + TIFFWarningExt(tif->tif_clientdata, module, + "IO error during reading of \"%s\"; tag ignored", + tagname); + break; + case TIFFReadDirEntryErrRange: + TIFFWarningExt(tif->tif_clientdata, module, + "Incorrect value for \"%s\"; tag ignored", + tagname); + break; + case TIFFReadDirEntryErrPsdif: + TIFFWarningExt(tif->tif_clientdata, module, + "Cannot handle different values per sample for \"%s\"; tag ignored", + tagname); + break; + case TIFFReadDirEntryErrSizesan: + TIFFWarningExt(tif->tif_clientdata, module, + "Sanity check on size of \"%s\" value failed; tag ignored", + tagname); + break; + case TIFFReadDirEntryErrAlloc: + TIFFWarningExt(tif->tif_clientdata, module, + "Out of memory reading of \"%s\"; tag ignored", + tagname); + break; + default: + assert(0); /* we should never get here */ + break; + } + } +} /* * Read the next TIFF directory from a file and convert it to the internal @@ -74,47 +3403,51 @@ int TIFFReadDirectory(TIFF* tif) { static const char module[] = "TIFFReadDirectory"; - - int n; - TIFFDirectory* td; - TIFFDirEntry *dp, *dir = NULL; - uint16 iv; - uint32 v; - const TIFFFieldInfo* fip; - size_t fix; + TIFFDirEntry* dir; uint16 dircount; - int diroutoforderwarning = 0, compressionknown = 0; - int haveunknowntags = 0; + TIFFDirEntry* dp; + uint16 di; + const TIFFField* fip; + uint32 fii=FAILED_FII; + toff_t nextdiroff; + int bitspersample_read = FALSE; - tif->tif_diroff = tif->tif_nextdiroff; - /* - * Check whether we have the last offset or bad offset (IFD looping). - */ - if (!TIFFCheckDirOffset(tif, tif->tif_nextdiroff)) - return 0; - /* - * Cleanup any previous compression state. - */ - (*tif->tif_cleanup)(tif); + tif->tif_diroff=tif->tif_nextdiroff; + if (!TIFFCheckDirOffset(tif,tif->tif_nextdiroff)) + return 0; /* last offset or bad offset (IFD looping) */ + (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */ tif->tif_curdir++; - dircount = TIFFFetchDirectory(tif, tif->tif_nextdiroff, - &dir, &tif->tif_nextdiroff); - if (!dircount) { - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Failed to read directory at offset %u", - tif->tif_name, tif->tif_nextdiroff); + nextdiroff = tif->tif_nextdiroff; + dircount=TIFFFetchDirectory(tif,nextdiroff,&dir,&tif->tif_nextdiroff); + if (!dircount) + { + TIFFErrorExt(tif->tif_clientdata,module, + "Failed to read directory at offset " TIFF_UINT64_FORMAT,nextdiroff); return 0; } + TIFFReadDirectoryCheckOrder(tif,dir,dircount); - tif->tif_flags &= ~TIFF_BEENWRITING; /* reset before new dir */ - /* - * Setup default value and then make a pass over - * 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. - */ - td = &tif->tif_dir; + /* + * Mark duplicates of any tag to be ignored (bugzilla 1994) + * to avoid certain pathological problems. + */ + { + TIFFDirEntry* ma; + uint16 mb; + for (ma=dir, mb=0; mbtdir_tag==na->tdir_tag) + na->tdir_tag=IGNORE; + } + } + } + + tif->tif_flags &= ~TIFF_BEENWRITING; /* reset before new dir */ + tif->tif_flags &= ~TIFF_BUF4WRITE; /* reset before new dir */ /* free any old stuff and reinit */ TIFFFreeDirectory(tif); TIFFDefaultDirectory(tif); @@ -124,13 +3457,14 @@ TIFFReadDirectory(TIFF* tif) * Thus we setup a default value here, even though * the TIFF spec says there is no default value. */ - TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); - + TIFFSetField(tif,TIFFTAG_PLANARCONFIG,PLANARCONFIG_CONTIG); /* - * Sigh, we must make a separate pass through the - * directory for the following reason: - * - * We must process the Compression tag in the first pass + * Setup default value and then make a pass over + * 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. + * 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 @@ -140,213 +3474,106 @@ TIFFReadDirectory(TIFF* tif) * tag value then we may end up ignoring the Compression tag * value because it has an incorrect count value (if the * true value of SamplesPerPixel is not 1). - * - * It sure would have been nice if Aldus had really thought - * this stuff through carefully. */ - for (dp = dir, n = dircount; n > 0; n--, dp++) { - if (tif->tif_flags & TIFF_SWAB) { - TIFFSwabArrayOfShort(&dp->tdir_tag, 2); - TIFFSwabArrayOfLong(&dp->tdir_count, 2); - } - if (dp->tdir_tag == TIFFTAG_SAMPLESPERPIXEL) { - if (!TIFFFetchNormalTag(tif, dp)) - goto bad; - dp->tdir_tag = IGNORE; + dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_SAMPLESPERPIXEL); + if (dp) + { + if (!TIFFFetchNormalTag(tif,dp,0)) + goto bad; + dp->tdir_tag=IGNORE; + } + dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_COMPRESSION); + if (dp) + { + /* + * The 5.0 spec says the Compression tag has one value, while + * earlier specs say it has one value per sample. Because of + * this, we accept the tag if one value is supplied with either + * count. + */ + uint16 value; + enum TIFFReadDirEntryErr err; + err=TIFFReadDirEntryShort(tif,dp,&value); + if (err==TIFFReadDirEntryErrCount) + err=TIFFReadDirEntryPersampleShort(tif,dp,&value); + if (err!=TIFFReadDirEntryErrOk) + { + TIFFReadDirEntryOutputErr(tif,err,module,"Compression",0); + goto bad; } + if (!TIFFSetField(tif,TIFFTAG_COMPRESSION,value)) + goto bad; + dp->tdir_tag=IGNORE; + } + else + { + if (!TIFFSetField(tif,TIFFTAG_COMPRESSION,COMPRESSION_NONE)) + goto bad; } /* * First real pass over the directory. */ - fix = 0; - for (dp = dir, n = dircount; n > 0; n--, dp++) { - - if (dp->tdir_tag == IGNORE) - continue; - if (fix >= tif->tif_nfields) - fix = 0; - - /* - * Silicon Beach (at least) writes unordered - * directory tags (violating the spec). Handle - * it here, but be obnoxious (maybe they'll fix it?). - */ - if (dp->tdir_tag < tif->tif_fieldinfo[fix]->field_tag) { - if (!diroutoforderwarning) { + for (di=0, dp=dir; ditdir_tag!=IGNORE) + { + TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii); + if (fii == FAILED_FII) + { TIFFWarningExt(tif->tif_clientdata, module, - "%s: invalid TIFF directory; tags are not sorted in ascending order", - tif->tif_name); - diroutoforderwarning = 1; - } - fix = 0; /* O(n^2) */ - } - while (fix < tif->tif_nfields && - tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag) - fix++; - if (fix >= tif->tif_nfields || - tif->tif_fieldinfo[fix]->field_tag != dp->tdir_tag) { - /* Unknown tag ... we'll deal with it below */ - haveunknowntags = 1; - continue; - } - /* - * Null out old tags that we ignore. - */ - if (tif->tif_fieldinfo[fix]->field_bit == FIELD_IGNORE) { - ignore: - dp->tdir_tag = IGNORE; - continue; - } - /* - * Check data type. - */ - fip = tif->tif_fieldinfo[fix]; - while (dp->tdir_type != (unsigned short) fip->field_type - && fix < tif->tif_nfields) { - if (fip->field_type == TIFF_ANY) /* wildcard */ - break; - fip = tif->tif_fieldinfo[++fix]; - if (fix >= tif->tif_nfields || - fip->field_tag != dp->tdir_tag) { - TIFFWarningExt(tif->tif_clientdata, module, - "%s: wrong data type %d for \"%s\"; tag ignored", - tif->tif_name, dp->tdir_type, - tif->tif_fieldinfo[fix-1]->field_name); - goto ignore; - } - } - /* - * Check count if known in advance. - */ - if (fip->field_readcount != TIFF_VARIABLE - && fip->field_readcount != TIFF_VARIABLE2) { - uint32 expected = (fip->field_readcount == TIFF_SPP) ? - (uint32) td->td_samplesperpixel : - (uint32) fip->field_readcount; - if (!CheckDirCount(tif, dp, expected)) - goto ignore; - } - - switch (dp->tdir_tag) { - case TIFFTAG_COMPRESSION: - /* - * The 5.0 spec says the Compression tag has - * one value, while earlier specs say it has - * one value per sample. Because of this, we - * accept the tag if one value is supplied. - */ - if (dp->tdir_count == 1) { - v = TIFFExtractData(tif, - dp->tdir_type, dp->tdir_offset); - if (!TIFFSetField(tif, dp->tdir_tag, (uint16)v)) - goto bad; - else - compressionknown = 1; - break; - /* XXX: workaround for broken TIFFs */ - } else if (dp->tdir_type == TIFF_LONG) { - if (!TIFFFetchPerSampleLongs(tif, dp, &v) || - !TIFFSetField(tif, dp->tdir_tag, (uint16)v)) - goto bad; - } else { - if (!TIFFFetchPerSampleShorts(tif, dp, &iv) - || !TIFFSetField(tif, dp->tdir_tag, iv)) - goto bad; - } - dp->tdir_tag = IGNORE; - break; - case TIFFTAG_STRIPOFFSETS: - case TIFFTAG_STRIPBYTECOUNTS: - case TIFFTAG_TILEOFFSETS: - case TIFFTAG_TILEBYTECOUNTS: - TIFFSetFieldBit(tif, fip->field_bit); - break; - case TIFFTAG_IMAGEWIDTH: - case TIFFTAG_IMAGELENGTH: - case TIFFTAG_IMAGEDEPTH: - case TIFFTAG_TILELENGTH: - case TIFFTAG_TILEWIDTH: - case TIFFTAG_TILEDEPTH: - case TIFFTAG_PLANARCONFIG: - case TIFFTAG_ROWSPERSTRIP: - case TIFFTAG_EXTRASAMPLES: - if (!TIFFFetchNormalTag(tif, dp)) - goto bad; - dp->tdir_tag = IGNORE; - break; - } - } - - /* - * If we saw any unknown tags, make an extra pass over the directory - * to deal with them. This must be done separately because the tags - * could have become known when we registered a codec after finding - * the Compression tag. In a correctly-sorted directory there's - * no problem because Compression will come before any codec-private - * tags, but if the sorting is wrong that might not hold. - */ - if (haveunknowntags) { - fix = 0; - for (dp = dir, n = dircount; n > 0; n--, dp++) { - if (dp->tdir_tag == IGNORE) - continue; - if (fix >= tif->tif_nfields || - dp->tdir_tag < tif->tif_fieldinfo[fix]->field_tag) - fix = 0; /* O(n^2) */ - while (fix < tif->tif_nfields && - tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag) - fix++; - if (fix >= tif->tif_nfields || - tif->tif_fieldinfo[fix]->field_tag != dp->tdir_tag) { - - TIFFWarningExt(tif->tif_clientdata, - module, - "%s: unknown field with tag %d (0x%x) encountered", - tif->tif_name, - dp->tdir_tag, - dp->tdir_tag); - - if (!_TIFFMergeFieldInfo(tif, - _TIFFCreateAnonFieldInfo(tif, + "Unknown field with tag %d (0x%x) encountered", + dp->tdir_tag,dp->tdir_tag); + /* the following knowingly leaks the + anonymous field structure */ + if (!_TIFFMergeFields(tif, + _TIFFCreateAnonField(tif, dp->tdir_tag, (TIFFDataType) dp->tdir_type), - 1)) - { + 1)) { TIFFWarningExt(tif->tif_clientdata, - module, - "Registering anonymous field with tag %d (0x%x) failed", - dp->tdir_tag, - dp->tdir_tag); - dp->tdir_tag = IGNORE; - continue; - } - fix = 0; - while (fix < tif->tif_nfields && - tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag) - fix++; - } - /* - * Check data type. - */ - fip = tif->tif_fieldinfo[fix]; - while (dp->tdir_type != (unsigned short) fip->field_type - && fix < tif->tif_nfields) { - if (fip->field_type == TIFF_ANY) /* wildcard */ - break; - fip = tif->tif_fieldinfo[++fix]; - if (fix >= tif->tif_nfields || - fip->field_tag != dp->tdir_tag) { - TIFFWarningExt(tif->tif_clientdata, module, - "%s: wrong data type %d for \"%s\"; tag ignored", - tif->tif_name, dp->tdir_type, - tif->tif_fieldinfo[fix-1]->field_name); - dp->tdir_tag = IGNORE; - break; + module, + "Registering anonymous field with tag %d (0x%x) failed", + dp->tdir_tag, + dp->tdir_tag); + dp->tdir_tag=IGNORE; + } else { + TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii); + assert(fii != FAILED_FII); + } + } + } + if (dp->tdir_tag!=IGNORE) + { + fip=tif->tif_fields[fii]; + if (fip->field_bit==FIELD_IGNORE) + dp->tdir_tag=IGNORE; + else + { + switch (dp->tdir_tag) + { + case TIFFTAG_STRIPOFFSETS: + case TIFFTAG_STRIPBYTECOUNTS: + case TIFFTAG_TILEOFFSETS: + case TIFFTAG_TILEBYTECOUNTS: + TIFFSetFieldBit(tif,fip->field_bit); + break; + case TIFFTAG_IMAGEWIDTH: + case TIFFTAG_IMAGELENGTH: + case TIFFTAG_IMAGEDEPTH: + case TIFFTAG_TILELENGTH: + case TIFFTAG_TILEWIDTH: + case TIFFTAG_TILEDEPTH: + case TIFFTAG_PLANARCONFIG: + case TIFFTAG_ROWSPERSTRIP: + case TIFFTAG_EXTRASAMPLES: + if (!TIFFFetchNormalTag(tif,dp,0)) + goto bad; + dp->tdir_tag=IGNORE; + break; + } } } - } } - /* * XXX: OJPEG hack. * If a) compression is OJPEG, b) planarconfig tag says it's separate, @@ -355,55 +3582,59 @@ TIFFReadDirectory(TIFF* tif) * that the buggy implementation of the buggy compression scheme * matches contig planarconfig best. So we 'fix-up' the tag here */ - if ((td->td_compression==COMPRESSION_OJPEG) && - (td->td_planarconfig==PLANARCONFIG_SEPARATE)) { - dp = TIFFReadDirectoryFind(dir,dircount,TIFFTAG_STRIPOFFSETS); - if ((dp!=0) && (dp->tdir_count==1)) { - dp = TIFFReadDirectoryFind(dir, dircount, - TIFFTAG_STRIPBYTECOUNTS); - if ((dp!=0) && (dp->tdir_count==1)) { - td->td_planarconfig=PLANARCONFIG_CONTIG; - TIFFWarningExt(tif->tif_clientdata, - "TIFFReadDirectory", - "Planarconfig tag value assumed incorrect, " - "assuming data is contig instead of chunky"); + if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG)&& + (tif->tif_dir.td_planarconfig==PLANARCONFIG_SEPARATE)) + { + if (!_TIFFFillStriles(tif)) + goto bad; + dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_STRIPOFFSETS); + if ((dp!=0)&&(dp->tdir_count==1)) + { + dp=TIFFReadDirectoryFindEntry(tif,dir,dircount, + TIFFTAG_STRIPBYTECOUNTS); + if ((dp!=0)&&(dp->tdir_count==1)) + { + tif->tif_dir.td_planarconfig=PLANARCONFIG_CONTIG; + TIFFWarningExt(tif->tif_clientdata,module, + "Planarconfig tag value assumed incorrect, " + "assuming data is contig instead of chunky"); } } } - /* * Allocate directory structure and setup defaults. */ - if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) { - MissingRequired(tif, "ImageLength"); + if (!TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS)) + { + MissingRequired(tif,"ImageLength"); goto bad; } - /* + /* * Setup appropriate structures (by strip or by tile) */ if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) { - td->td_nstrips = TIFFNumberOfStrips(tif); - td->td_tilewidth = td->td_imagewidth; - td->td_tilelength = td->td_rowsperstrip; - td->td_tiledepth = td->td_imagedepth; + tif->tif_dir.td_nstrips = TIFFNumberOfStrips(tif); + tif->tif_dir.td_tilewidth = tif->tif_dir.td_imagewidth; + tif->tif_dir.td_tilelength = tif->tif_dir.td_rowsperstrip; + tif->tif_dir.td_tiledepth = tif->tif_dir.td_imagedepth; tif->tif_flags &= ~TIFF_ISTILED; } else { - td->td_nstrips = TIFFNumberOfTiles(tif); + tif->tif_dir.td_nstrips = TIFFNumberOfTiles(tif); tif->tif_flags |= TIFF_ISTILED; } - if (!td->td_nstrips) { + if (!tif->tif_dir.td_nstrips) { TIFFErrorExt(tif->tif_clientdata, module, - "%s: cannot handle zero number of %s", - tif->tif_name, isTiled(tif) ? "tiles" : "strips"); + "Cannot handle zero number of %s", + isTiled(tif) ? "tiles" : "strips"); goto bad; } - td->td_stripsperimage = td->td_nstrips; - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) - td->td_stripsperimage /= td->td_samplesperpixel; + tif->tif_dir.td_stripsperimage = tif->tif_dir.td_nstrips; + if (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE) + tif->tif_dir.td_stripsperimage /= tif->tif_dir.td_samplesperpixel; if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) { - if ((td->td_compression==COMPRESSION_OJPEG) && + if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG) && (isTiled(tif)==0) && - (td->td_nstrips==1)) { + (tif->tif_dir.td_nstrips==1)) { /* * XXX: OJPEG hack. * If a) compression is OJPEG, b) it's not a tiled TIFF, @@ -419,137 +3650,165 @@ TIFFReadDirectory(TIFF* tif) goto bad; } } - /* * Second pass: extract other information. */ - for (dp = dir, n = dircount; n > 0; n--, dp++) { - if (dp->tdir_tag == IGNORE) - continue; - switch (dp->tdir_tag) { - case TIFFTAG_MINSAMPLEVALUE: - case TIFFTAG_MAXSAMPLEVALUE: - case TIFFTAG_BITSPERSAMPLE: - case TIFFTAG_DATATYPE: - case TIFFTAG_SAMPLEFORMAT: - /* - * The 5.0 spec says the Compression tag has - * one value, while earlier specs say it has - * one value per sample. Because of this, we - * accept the tag if one value is supplied. - * - * The MinSampleValue, MaxSampleValue, BitsPerSample - * DataType and SampleFormat tags are supposed to be - * written as one value/sample, but some vendors - * incorrectly write one value only -- so we accept - * that as well (yech). Other vendors write correct - * value for NumberOfSamples, but incorrect one for - * BitsPerSample and friends, and we will read this - * too. - */ - if (dp->tdir_count == 1) { - v = TIFFExtractData(tif, - dp->tdir_type, dp->tdir_offset); - if (!TIFFSetField(tif, dp->tdir_tag, (uint16)v)) - goto bad; - /* XXX: workaround for broken TIFFs */ - } else if (dp->tdir_tag == TIFFTAG_BITSPERSAMPLE - && dp->tdir_type == TIFF_LONG) { - if (!TIFFFetchPerSampleLongs(tif, dp, &v) || - !TIFFSetField(tif, dp->tdir_tag, (uint16)v)) - goto bad; - } else { - if (!TIFFFetchPerSampleShorts(tif, dp, &iv) || - !TIFFSetField(tif, dp->tdir_tag, iv)) - goto bad; - } - break; - case TIFFTAG_SMINSAMPLEVALUE: - case TIFFTAG_SMAXSAMPLEVALUE: - { - double dv = 0.0; - if (!TIFFFetchPerSampleAnys(tif, dp, &dv) || - !TIFFSetField(tif, dp->tdir_tag, dv)) - goto bad; - } - break; - case TIFFTAG_STRIPOFFSETS: - case TIFFTAG_TILEOFFSETS: - if (!TIFFFetchStripThing(tif, dp, - td->td_nstrips, &td->td_stripoffset)) - goto bad; - break; - case TIFFTAG_STRIPBYTECOUNTS: - case TIFFTAG_TILEBYTECOUNTS: - if (!TIFFFetchStripThing(tif, dp, - td->td_nstrips, &td->td_stripbytecount)) - goto bad; - break; - case TIFFTAG_COLORMAP: - case TIFFTAG_TRANSFERFUNCTION: - { - char* cp; + for (di=0, dp=dir; ditdir_tag) + { + case IGNORE: + break; + case TIFFTAG_MINSAMPLEVALUE: + case TIFFTAG_MAXSAMPLEVALUE: + case TIFFTAG_BITSPERSAMPLE: + case TIFFTAG_DATATYPE: + case TIFFTAG_SAMPLEFORMAT: /* - * TransferFunction can have either 1x or 3x - * data values; Colormap can have only 3x - * items. + * The MinSampleValue, MaxSampleValue, BitsPerSample + * DataType and SampleFormat tags are supposed to be + * written as one value/sample, but some vendors + * incorrectly write one value only -- so we accept + * that as well (yech). Other vendors write correct + * value for NumberOfSamples, but incorrect one for + * BitsPerSample and friends, and we will read this + * too. */ - v = 1L<td_bitspersample; - if (dp->tdir_tag == TIFFTAG_COLORMAP || - dp->tdir_count != v) { - if (!CheckDirCount(tif, dp, 3 * v)) - break; - } - v *= sizeof(uint16); - cp = (char *)_TIFFCheckMalloc(tif, - dp->tdir_count, - sizeof (uint16), - "to read \"TransferFunction\" tag"); - if (cp != NULL) { - if (TIFFFetchData(tif, dp, cp)) { - /* - * This deals with there being - * only one array to apply to - * all samples. - */ - uint32 c = 1L << td->td_bitspersample; - if (dp->tdir_count == c) - v = 0L; - TIFFSetField(tif, dp->tdir_tag, - cp, cp+v, cp+2*v); + { + uint16 value; + enum TIFFReadDirEntryErr err; + err=TIFFReadDirEntryShort(tif,dp,&value); + if (err==TIFFReadDirEntryErrCount) + err=TIFFReadDirEntryPersampleShort(tif,dp,&value); + if (err!=TIFFReadDirEntryErrOk) + { + fip = TIFFFieldWithTag(tif,dp->tdir_tag); + TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0); + goto bad; + } + if (!TIFFSetField(tif,dp->tdir_tag,value)) + goto bad; + if( dp->tdir_tag == TIFFTAG_BITSPERSAMPLE ) + bitspersample_read = TRUE; + } + break; + case TIFFTAG_SMINSAMPLEVALUE: + case TIFFTAG_SMAXSAMPLEVALUE: + { + + double *data; + enum TIFFReadDirEntryErr err; + uint32 saved_flags; + int m; + if (dp->tdir_count != (uint64)tif->tif_dir.td_samplesperpixel) + err = TIFFReadDirEntryErrCount; + else + err = TIFFReadDirEntryDoubleArray(tif, dp, &data); + if (err!=TIFFReadDirEntryErrOk) + { + fip = TIFFFieldWithTag(tif,dp->tdir_tag); + TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0); + goto bad; + } + saved_flags = tif->tif_flags; + tif->tif_flags |= TIFF_PERSAMPLE; + m = TIFFSetField(tif,dp->tdir_tag,data); + tif->tif_flags = saved_flags; + _TIFFfree(data); + if (!m) + goto bad; + } + break; + case TIFFTAG_STRIPOFFSETS: + case TIFFTAG_TILEOFFSETS: +#if defined(DEFER_STRILE_LOAD) + _TIFFmemcpy( &(tif->tif_dir.td_stripoffset_entry), + dp, sizeof(TIFFDirEntry) ); +#else + if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripoffset)) + goto bad; +#endif + break; + case TIFFTAG_STRIPBYTECOUNTS: + case TIFFTAG_TILEBYTECOUNTS: +#if defined(DEFER_STRILE_LOAD) + _TIFFmemcpy( &(tif->tif_dir.td_stripbytecount_entry), + dp, sizeof(TIFFDirEntry) ); +#else + if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripbytecount)) + goto bad; +#endif + break; + case TIFFTAG_COLORMAP: + case TIFFTAG_TRANSFERFUNCTION: + { + enum TIFFReadDirEntryErr err; + uint32 countpersample; + uint32 countrequired; + uint32 incrementpersample; + uint16* value=NULL; + /* It would be dangerous to instanciate 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; + } + countpersample=(1L<tif_dir.td_bitspersample); + if ((dp->tdir_tag==TIFFTAG_TRANSFERFUNCTION)&&(dp->tdir_count==(uint64)countpersample)) + { + countrequired=countpersample; + incrementpersample=0; + } + else + { + countrequired=3*countpersample; + incrementpersample=countpersample; + } + if (dp->tdir_count!=(uint64)countrequired) + err=TIFFReadDirEntryErrCount; + else + err=TIFFReadDirEntryShortArray(tif,dp,&value); + if (err!=TIFFReadDirEntryErrOk) + { + fip = TIFFFieldWithTag(tif,dp->tdir_tag); + TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",1); + } + else + { + TIFFSetField(tif,dp->tdir_tag,value,value+incrementpersample,value+2*incrementpersample); + _TIFFfree(value); } - _TIFFfree(cp); } break; - } - case TIFFTAG_PAGENUMBER: - case TIFFTAG_HALFTONEHINTS: - case TIFFTAG_YCBCRSUBSAMPLING: - case TIFFTAG_DOTRANGE: - (void) TIFFFetchShortPair(tif, dp); - break; - case TIFFTAG_REFERENCEBLACKWHITE: - (void) TIFFFetchRefBlackWhite(tif, dp); - break; /* BEGIN REV 4.0 COMPATIBILITY */ - case TIFFTAG_OSUBFILETYPE: - v = 0L; - switch (TIFFExtractData(tif, dp->tdir_type, - dp->tdir_offset)) { - case OFILETYPE_REDUCEDIMAGE: - v = FILETYPE_REDUCEDIMAGE; + case TIFFTAG_OSUBFILETYPE: + { + uint16 valueo; + uint32 value; + if (TIFFReadDirEntryShort(tif,dp,&valueo)==TIFFReadDirEntryErrOk) + { + switch (valueo) + { + case OFILETYPE_REDUCEDIMAGE: value=FILETYPE_REDUCEDIMAGE; break; + case OFILETYPE_PAGE: value=FILETYPE_PAGE; break; + default: value=0; break; + } + if (value!=0) + TIFFSetField(tif,TIFFTAG_SUBFILETYPE,value); + } + } break; - case OFILETYPE_PAGE: - v = FILETYPE_PAGE; - break; - } - if (v) - TIFFSetField(tif, TIFFTAG_SUBFILETYPE, v); - break; /* END REV 4.0 COMPATIBILITY */ - default: - (void) TIFFFetchNormalTag(tif, dp); - break; + default: + (void) TIFFFetchNormalTag(tif, dp, TRUE); + break; } } /* @@ -568,48 +3827,54 @@ TIFFReadDirectory(TIFF* tif) * and c) photometric is MINISWHITE or MINISBLACK, then we consistently * find samplesperpixel should be 3 */ - if (td->td_compression==COMPRESSION_OJPEG) + if (tif->tif_dir.td_compression==COMPRESSION_OJPEG) { if (!TIFFFieldSet(tif,FIELD_PHOTOMETRIC)) { - TIFFWarningExt(tif->tif_clientdata, "TIFFReadDirectory", - "Photometric tag is missing, assuming data is YCbCr"); + TIFFWarningExt(tif->tif_clientdata, module, + "Photometric tag is missing, assuming data is YCbCr"); if (!TIFFSetField(tif,TIFFTAG_PHOTOMETRIC,PHOTOMETRIC_YCBCR)) goto bad; } - else if (td->td_photometric==PHOTOMETRIC_RGB) + else if (tif->tif_dir.td_photometric==PHOTOMETRIC_RGB) { - td->td_photometric=PHOTOMETRIC_YCBCR; - TIFFWarningExt(tif->tif_clientdata, "TIFFReadDirectory", - "Photometric tag value assumed incorrect, " - "assuming data is YCbCr instead of RGB"); + tif->tif_dir.td_photometric=PHOTOMETRIC_YCBCR; + TIFFWarningExt(tif->tif_clientdata, module, + "Photometric tag value assumed incorrect, " + "assuming data is YCbCr instead of RGB"); } if (!TIFFFieldSet(tif,FIELD_BITSPERSAMPLE)) { - TIFFWarningExt(tif->tif_clientdata,"TIFFReadDirectory", - "BitsPerSample tag is missing, assuming 8 bits per sample"); + TIFFWarningExt(tif->tif_clientdata,module, + "BitsPerSample tag is missing, assuming 8 bits per sample"); if (!TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE,8)) goto bad; } if (!TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL)) { - if ((td->td_photometric==PHOTOMETRIC_RGB) - || (td->td_photometric==PHOTOMETRIC_YCBCR)) + if (tif->tif_dir.td_photometric==PHOTOMETRIC_RGB) { - TIFFWarningExt(tif->tif_clientdata, - "TIFFReadDirectory", - "SamplesPerPixel tag is missing, " - "assuming correct SamplesPerPixel value is 3"); + TIFFWarningExt(tif->tif_clientdata,module, + "SamplesPerPixel tag is missing, " + "assuming correct SamplesPerPixel value is 3"); if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,3)) goto bad; } - else if ((td->td_photometric==PHOTOMETRIC_MINISWHITE) - || (td->td_photometric==PHOTOMETRIC_MINISBLACK)) + if (tif->tif_dir.td_photometric==PHOTOMETRIC_YCBCR) { - TIFFWarningExt(tif->tif_clientdata, - "TIFFReadDirectory", - "SamplesPerPixel tag is missing, " - "assuming correct SamplesPerPixel value is 1"); + TIFFWarningExt(tif->tif_clientdata,module, + "SamplesPerPixel tag is missing, " + "applying correct SamplesPerPixel value of 3"); + if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,3)) + goto bad; + } + else if ((tif->tif_dir.td_photometric==PHOTOMETRIC_MINISWHITE) + || (tif->tif_dir.td_photometric==PHOTOMETRIC_MINISBLACK)) + { + /* + * SamplesPerPixel tag is missing, but is not required + * by spec. Assume correct SamplesPerPixel value of 1. + */ if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,1)) goto bad; } @@ -618,17 +3883,23 @@ TIFFReadDirectory(TIFF* tif) /* * Verify Palette image has a Colormap. */ - if (td->td_photometric == PHOTOMETRIC_PALETTE && + if (tif->tif_dir.td_photometric == PHOTOMETRIC_PALETTE && !TIFFFieldSet(tif, FIELD_COLORMAP)) { - MissingRequired(tif, "Colormap"); - goto bad; + if ( tif->tif_dir.td_bitspersample>=8 && tif->tif_dir.td_samplesperpixel==3) + tif->tif_dir.td_photometric = PHOTOMETRIC_RGB; + else if (tif->tif_dir.td_bitspersample>=8) + tif->tif_dir.td_photometric = PHOTOMETRIC_MINISBLACK; + else { + MissingRequired(tif, "Colormap"); + goto bad; + } } /* * OJPEG hack: * We do no further messing with strip/tile offsets/bytecounts in OJPEG * TIFFs */ - if (td->td_compression!=COMPRESSION_OJPEG) + if (tif->tif_dir.td_compression!=COMPRESSION_OJPEG) { /* * Attempt to deal with a missing StripByteCounts tag. @@ -639,18 +3910,16 @@ TIFFReadDirectory(TIFF* tif) * the size of the strips. In this case, assume there * is one uncompressed strip of data. */ - if ((td->td_planarconfig == PLANARCONFIG_CONTIG && - td->td_nstrips > 1) || - (td->td_planarconfig == PLANARCONFIG_SEPARATE && - td->td_nstrips != td->td_samplesperpixel)) { + if ((tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG && + tif->tif_dir.td_nstrips > 1) || + (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE && + tif->tif_dir.td_nstrips != (uint32)tif->tif_dir.td_samplesperpixel)) { MissingRequired(tif, "StripByteCounts"); goto bad; } TIFFWarningExt(tif->tif_clientdata, module, - "%s: TIFF directory is missing required " - "\"%s\" field, calculating from imagelength", - tif->tif_name, - _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name); + "TIFF directory is missing required " + "\"StripByteCounts\" field, calculating from imagelength"); if (EstimateStripByteCounts(tif, dir, dircount) < 0) goto bad; /* @@ -667,15 +3936,16 @@ TIFFReadDirectory(TIFF* tif) * dumped out. */ #define BYTECOUNTLOOKSBAD \ - ( (td->td_stripbytecount[0] == 0 && td->td_stripoffset[0] != 0) || \ - (td->td_compression == COMPRESSION_NONE && \ - td->td_stripbytecount[0] > TIFFGetFileSize(tif) - td->td_stripoffset[0]) || \ + ( (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_mode == O_RDONLY && \ - td->td_compression == COMPRESSION_NONE && \ - td->td_stripbytecount[0] < TIFFScanlineSize(tif) * td->td_imagelength) ) + tif->tif_dir.td_compression == COMPRESSION_NONE && \ + tif->tif_dir.td_stripbytecount[0] < TIFFScanlineSize64(tif) * tif->tif_dir.td_imagelength) ) - } else if (td->td_nstrips == 1 - && td->td_stripoffset[0] != 0 + } else if (tif->tif_dir.td_nstrips == 1 + && _TIFFFillStriles(tif) + && tif->tif_dir.td_stripoffset[0] != 0 && BYTECOUNTLOOKSBAD) { /* * XXX: Plexus (and others) sometimes give a value of @@ -684,61 +3954,71 @@ TIFFReadDirectory(TIFF* tif) * of estimating the size of a one strip image. */ TIFFWarningExt(tif->tif_clientdata, module, - "%s: Bogus \"%s\" field, ignoring and calculating from imagelength", - tif->tif_name, - _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name); + "Bogus \"StripByteCounts\" field, ignoring and calculating from imagelength"); if(EstimateStripByteCounts(tif, dir, dircount) < 0) goto bad; - } else if (td->td_planarconfig == PLANARCONFIG_CONTIG - && td->td_nstrips > 2 - && td->td_compression == COMPRESSION_NONE - && td->td_stripbytecount[0] != td->td_stripbytecount[1] - && td->td_stripbytecount[0] != 0 - && td->td_stripbytecount[1] != 0 ) { + +#if !defined(DEFER_STRILE_LOAD) + } else if (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG + && tif->tif_dir.td_nstrips > 2 + && tif->tif_dir.td_compression == COMPRESSION_NONE + && tif->tif_dir.td_stripbytecount[0] != tif->tif_dir.td_stripbytecount[1] + && tif->tif_dir.td_stripbytecount[0] != 0 + && tif->tif_dir.td_stripbytecount[1] != 0 ) { /* - * XXX: Some vendors fill StripByteCount array with - * absolutely wrong values (it can be equal to - * StripOffset array, for example). Catch this case - * here. + * XXX: Some vendors fill StripByteCount array with + * absolutely wrong values (it can be equal to + * StripOffset array, for example). Catch this case + * here. + * + * We avoid this check if deferring strile loading + * as it would always force us to load the strip/tile + * information. */ TIFFWarningExt(tif->tif_clientdata, module, - "%s: Wrong \"%s\" field, ignoring and calculating from imagelength", - tif->tif_name, - _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name); + "Wrong \"StripByteCounts\" field, ignoring and calculating from imagelength"); if (EstimateStripByteCounts(tif, dir, dircount) < 0) goto bad; +#endif /* !defined(DEFER_STRILE_LOAD) */ } } - if (dir) { - _TIFFfree((char *)dir); - dir = NULL; + if (dir) + { + _TIFFfree(dir); + dir=NULL; } if (!TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE)) - td->td_maxsamplevalue = (uint16)((1L<td_bitspersample)-1); - /* - * Setup default compression scheme. - */ - + { + if (tif->tif_dir.td_bitspersample>=16) + tif->tif_dir.td_maxsamplevalue=0xFFFF; + else + tif->tif_dir.td_maxsamplevalue = (uint16)((1L<tif_dir.td_bitspersample)-1); + } /* * XXX: We can optimize checking for the strip bounds using the sorted * bytecounts array. See also comments for TIFFAppendToStrip() * function in tif_write.c. */ - if (td->td_nstrips > 1) { - tstrip_t strip; +#if !defined(DEFER_STRILE_LOAD) + if (tif->tif_dir.td_nstrips > 1) { + uint32 strip; - td->td_stripbytecountsorted = 1; - for (strip = 1; strip < td->td_nstrips; strip++) { - if (td->td_stripoffset[strip - 1] > - td->td_stripoffset[strip]) { - td->td_stripbytecountsorted = 0; + tif->tif_dir.td_stripbytecountsorted = 1; + for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) { + if (tif->tif_dir.td_stripoffset[strip - 1] > + tif->tif_dir.td_stripoffset[strip]) { + tif->tif_dir.td_stripbytecountsorted = 0; break; } } } +#endif /* !defined(DEFER_STRILE_LOAD) */ + + /* + * An opportunity for compression mode dependent tag fixup + */ + (*tif->tif_fixuptags)(tif); - if (!TIFFFieldSet(tif, FIELD_COMPRESSION)) - TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE); /* * Some manufacturers make life difficult by writing * large amounts of uncompressed data as a single strip. @@ -748,24 +4028,35 @@ TIFFReadDirectory(TIFF* tif) * side effect, however, is that the RowsPerStrip tag * value may be changed. */ - if (td->td_nstrips == 1 && td->td_compression == COMPRESSION_NONE && - (tif->tif_flags & (TIFF_STRIPCHOP|TIFF_ISTILED)) == TIFF_STRIPCHOP) + if ((tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)&& + (tif->tif_dir.td_nstrips==1)&& + (tif->tif_dir.td_compression==COMPRESSION_NONE)&& + ((tif->tif_flags&(TIFF_STRIPCHOP|TIFF_ISTILED))==TIFF_STRIPCHOP)) + { + if ( !_TIFFFillStriles(tif) || !tif->tif_dir.td_stripbytecount ) + return 0; ChopUpSingleUncompressedStrip(tif); + } + + /* + * Clear the dirty directory flag. + */ + tif->tif_flags &= ~TIFF_DIRTYDIRECT; + tif->tif_flags &= ~TIFF_DIRTYSTRIP; /* * Reinitialize i/o since we are starting on a new directory. */ tif->tif_row = (uint32) -1; - tif->tif_curstrip = (tstrip_t) -1; + tif->tif_curstrip = (uint32) -1; tif->tif_col = (uint32) -1; - tif->tif_curtile = (ttile_t) -1; - tif->tif_tilesize = (tsize_t) -1; + tif->tif_curtile = (uint32) -1; + tif->tif_tilesize = (tmsize_t) -1; tif->tif_scanlinesize = TIFFScanlineSize(tif); if (!tif->tif_scanlinesize) { TIFFErrorExt(tif->tif_clientdata, module, - "%s: cannot handle zero scanline size", - tif->tif_name); + "Cannot handle zero scanline size"); return (0); } @@ -773,15 +4064,13 @@ TIFFReadDirectory(TIFF* tif) tif->tif_tilesize = TIFFTileSize(tif); if (!tif->tif_tilesize) { TIFFErrorExt(tif->tif_clientdata, module, - "%s: cannot handle zero tile size", - tif->tif_name); + "Cannot handle zero tile size"); return (0); } } else { if (!TIFFStripSize(tif)) { TIFFErrorExt(tif->tif_clientdata, module, - "%s: cannot handle zero strip size", - tif->tif_name); + "Cannot handle zero strip size"); return (0); } } @@ -792,11 +4081,32 @@ bad: return (0); } +static void +TIFFReadDirectoryCheckOrder(TIFF* tif, TIFFDirEntry* dir, uint16 dircount) +{ + static const char module[] = "TIFFReadDirectoryCheckOrder"; + uint16 m; + uint16 n; + TIFFDirEntry* o; + m=0; + for (n=0, o=dir; ntdir_tagtif_clientdata,module, + "Invalid TIFF directory; tags are not sorted in ascending order"); + break; + } + m=o->tdir_tag+1; + } +} + static TIFFDirEntry* -TIFFReadDirectoryFind(TIFFDirEntry* dir, uint16 dircount, uint16 tagid) +TIFFReadDirectoryFindEntry(TIFF* tif, TIFFDirEntry* dir, uint16 dircount, uint16 tagid) { TIFFDirEntry* m; uint16 n; + (void) tif; for (m=dir, n=0; ntdir_tag==tagid) @@ -805,123 +4115,140 @@ TIFFReadDirectoryFind(TIFFDirEntry* dir, uint16 dircount, uint16 tagid) return(0); } +static void +TIFFReadDirectoryFindFieldInfo(TIFF* tif, uint16 tagid, uint32* fii) +{ + int32 ma,mb,mc; + ma=-1; + mc=(int32)tif->tif_nfields; + while (1) + { + if (ma+1==mc) + { + *fii = FAILED_FII; + return; + } + mb=(ma+mc)/2; + if (tif->tif_fields[mb]->field_tag==(uint32)tagid) + break; + if (tif->tif_fields[mb]->field_tag<(uint32)tagid) + ma=mb; + else + mc=mb; + } + while (1) + { + if (mb==0) + break; + if (tif->tif_fields[mb-1]->field_tag!=(uint32)tagid) + break; + mb--; + } + *fii=mb; +} + /* * Read custom directory from the arbitarry offset. * The code is very similar to TIFFReadDirectory(). */ int TIFFReadCustomDirectory(TIFF* tif, toff_t diroff, - const TIFFFieldInfo info[], size_t n) + const TIFFFieldArray* infoarray) { static const char module[] = "TIFFReadCustomDirectory"; - - TIFFDirectory* td = &tif->tif_dir; - TIFFDirEntry *dp, *dir = NULL; - const TIFFFieldInfo* fip; - size_t fix; - uint16 i, dircount; - - _TIFFSetupFieldInfo(tif, info, n); - - dircount = TIFFFetchDirectory(tif, diroff, &dir, NULL); - if (!dircount) { - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Failed to read custom directory at offset %u", - tif->tif_name, diroff); + TIFFDirEntry* dir; + uint16 dircount; + TIFFDirEntry* dp; + uint16 di; + const TIFFField* fip; + uint32 fii; + _TIFFSetupFields(tif, infoarray); + dircount=TIFFFetchDirectory(tif,diroff,&dir,NULL); + if (!dircount) + { + TIFFErrorExt(tif->tif_clientdata,module, + "Failed to read custom directory at offset " TIFF_UINT64_FORMAT,diroff); return 0; } - TIFFFreeDirectory(tif); - _TIFFmemset(&tif->tif_dir, 0, sizeof(TIFFDirectory)); - - fix = 0; - for (dp = dir, i = dircount; i > 0; i--, dp++) { - if (tif->tif_flags & TIFF_SWAB) { - TIFFSwabArrayOfShort(&dp->tdir_tag, 2); - TIFFSwabArrayOfLong(&dp->tdir_count, 2); - } - - if (fix >= tif->tif_nfields || dp->tdir_tag == IGNORE) - continue; - - while (fix < tif->tif_nfields && - tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag) - fix++; - - if (fix >= tif->tif_nfields || - tif->tif_fieldinfo[fix]->field_tag != dp->tdir_tag) { - + _TIFFmemset(&tif->tif_dir, 0, sizeof(TIFFDirectory)); + TIFFReadDirectoryCheckOrder(tif,dir,dircount); + for (di=0, dp=dir; ditdir_tag,&fii); + if (fii == FAILED_FII) + { TIFFWarningExt(tif->tif_clientdata, module, - "%s: unknown field with tag %d (0x%x) encountered", - tif->tif_name, dp->tdir_tag, dp->tdir_tag); - if (!_TIFFMergeFieldInfo(tif, - _TIFFCreateAnonFieldInfo(tif, - dp->tdir_tag, - (TIFFDataType) dp->tdir_type), - 1)) + "Unknown field with tag %d (0x%x) encountered", + dp->tdir_tag, dp->tdir_tag); + if (!_TIFFMergeFields(tif, _TIFFCreateAnonField(tif, + dp->tdir_tag, + (TIFFDataType) dp->tdir_type), + 1)) { + TIFFWarningExt(tif->tif_clientdata, module, + "Registering anonymous field with tag %d (0x%x) failed", + dp->tdir_tag, dp->tdir_tag); + dp->tdir_tag=IGNORE; + } else { + TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii); + assert( fii != FAILED_FII ); + } + } + if (dp->tdir_tag!=IGNORE) + { + fip=tif->tif_fields[fii]; + if (fip->field_bit==FIELD_IGNORE) + dp->tdir_tag=IGNORE; + else { - TIFFWarningExt(tif->tif_clientdata, module, - "Registering anonymous field with tag %d (0x%x) failed", - dp->tdir_tag, dp->tdir_tag); - goto ignore; + /* check data type */ + while ((fip->field_type!=TIFF_ANY)&&(fip->field_type!=dp->tdir_type)) + { + fii++; + if ((fii==tif->tif_nfields)|| + (tif->tif_fields[fii]->field_tag!=(uint32)dp->tdir_tag)) + { + fii=0xFFFF; + break; + } + fip=tif->tif_fields[fii]; + } + if (fii==0xFFFF) + { + TIFFWarningExt(tif->tif_clientdata, module, + "Wrong data type %d for \"%s\"; tag ignored", + dp->tdir_type,fip->field_name); + dp->tdir_tag=IGNORE; + } + else + { + /* check count if known in advance */ + if ((fip->field_readcount!=TIFF_VARIABLE)&& + (fip->field_readcount!=TIFF_VARIABLE2)) + { + uint32 expected; + if (fip->field_readcount==TIFF_SPP) + expected=(uint32)tif->tif_dir.td_samplesperpixel; + else + expected=(uint32)fip->field_readcount; + if (!CheckDirCount(tif,dp,expected)) + dp->tdir_tag=IGNORE; + } + } } - - fix = 0; - while (fix < tif->tif_nfields && - tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag) - fix++; - } - /* - * Null out old tags that we ignore. - */ - if (tif->tif_fieldinfo[fix]->field_bit == FIELD_IGNORE) { - ignore: - dp->tdir_tag = IGNORE; - continue; - } - /* - * Check data type. - */ - fip = tif->tif_fieldinfo[fix]; - while (dp->tdir_type != (unsigned short) fip->field_type - && fix < tif->tif_nfields) { - if (fip->field_type == TIFF_ANY) /* wildcard */ - break; - fip = tif->tif_fieldinfo[++fix]; - if (fix >= tif->tif_nfields || - fip->field_tag != dp->tdir_tag) { - TIFFWarningExt(tif->tif_clientdata, module, - "%s: wrong data type %d for \"%s\"; tag ignored", - tif->tif_name, dp->tdir_type, - tif->tif_fieldinfo[fix-1]->field_name); - goto ignore; + switch (dp->tdir_tag) + { + case IGNORE: + break; + case EXIFTAG_SUBJECTDISTANCE: + (void) TIFFFetchSubjectDistance(tif,dp); + break; + default: + (void) TIFFFetchNormalTag(tif, dp, TRUE); + break; } } - /* - * Check count if known in advance. - */ - if (fip->field_readcount != TIFF_VARIABLE - && fip->field_readcount != TIFF_VARIABLE2) { - uint32 expected = (fip->field_readcount == TIFF_SPP) ? - (uint32) td->td_samplesperpixel : - (uint32) fip->field_readcount; - if (!CheckDirCount(tif, dp, expected)) - goto ignore; - } - - /* - * EXIF tags which need to be specifically processed. - */ - switch (dp->tdir_tag) { - case EXIFTAG_SUBJECTDISTANCE: - (void) TIFFFetchSubjectDistance(tif, dp); - break; - default: - (void) TIFFFetchNormalTag(tif, dp); - break; - } } - if (dir) _TIFFfree(dir); return 1; @@ -934,11 +4261,9 @@ TIFFReadCustomDirectory(TIFF* tif, toff_t diroff, int TIFFReadEXIFDirectory(TIFF* tif, toff_t diroff) { - size_t exifFieldInfoCount; - const TIFFFieldInfo *exifFieldInfo = - _TIFFGetExifFieldInfo(&exifFieldInfoCount); - return TIFFReadCustomDirectory(tif, diroff, exifFieldInfo, - exifFieldInfoCount); + const TIFFFieldArray* exifFieldArray; + exifFieldArray = _TIFFGetExifFields(); + return TIFFReadCustomDirectory(tif, diroff, exifFieldArray); } static int @@ -950,35 +4275,50 @@ EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount) TIFFDirectory *td = &tif->tif_dir; uint32 strip; + if( !_TIFFFillStriles( tif ) ) + return -1; + if (td->td_stripbytecount) _TIFFfree(td->td_stripbytecount); - td->td_stripbytecount = (uint32*) - _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint32), + td->td_stripbytecount = (uint64*) + _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64), "for \"StripByteCounts\" array"); if( td->td_stripbytecount == NULL ) return -1; if (td->td_compression != COMPRESSION_NONE) { - uint32 space = (uint32)(sizeof (TIFFHeader) - + sizeof (uint16) - + (dircount * sizeof (TIFFDirEntry)) - + sizeof (uint32)); - toff_t filesize = TIFFGetFileSize(tif); + uint64 space; + uint64 filesize; uint16 n; - + filesize = TIFFGetFileSize(tif); + if (!(tif->tif_flags&TIFF_BIGTIFF)) + space=sizeof(TIFFHeaderClassic)+2+dircount*12+4; + else + space=sizeof(TIFFHeaderBig)+8+dircount*20+8; /* calculate amount of space used by indirect values */ for (dp = dir, n = dircount; n > 0; n--, dp++) { - uint32 cc = TIFFDataWidth((TIFFDataType) dp->tdir_type); - if (cc == 0) { + uint32 typewidth = TIFFDataWidth((TIFFDataType) dp->tdir_type); + uint64 datasize; + typewidth = TIFFDataWidth((TIFFDataType) dp->tdir_type); + if (typewidth == 0) { TIFFErrorExt(tif->tif_clientdata, module, - "%s: Cannot determine size of unknown tag type %d", - tif->tif_name, dp->tdir_type); + "Cannot determine size of unknown tag type %d", + dp->tdir_type); return -1; } - cc = cc * dp->tdir_count; - if (cc > sizeof (uint32)) - space += cc; + datasize=(uint64)typewidth*dp->tdir_count; + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + if (datasize<=4) + datasize=0; + } + else + { + if (datasize<=8) + datasize=0; + } + space+=datasize; } space = filesize - space; if (td->td_planarconfig == PLANARCONFIG_SEPARATE) @@ -991,19 +4331,17 @@ EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount) * should begin. Since a strip of data must be contiguous, * it's safe to assume that we've overestimated the amount * of data in the strip and trim this number back accordingly. - */ + */ strip--; - if (((toff_t)(td->td_stripoffset[strip]+ - td->td_stripbytecount[strip])) > filesize) - td->td_stripbytecount[strip] = - filesize - td->td_stripoffset[strip]; + if (td->td_stripoffset[strip]+td->td_stripbytecount[strip] > filesize) + td->td_stripbytecount[strip] = filesize - td->td_stripoffset[strip]; } else if (isTiled(tif)) { - uint32 bytespertile = TIFFTileSize(tif); + uint64 bytespertile = TIFFTileSize64(tif); for (strip = 0; strip < td->td_nstrips; strip++) - td->td_stripbytecount[strip] = bytespertile; + td->td_stripbytecount[strip] = bytespertile; } else { - uint32 rowbytes = TIFFScanlineSize(tif); + uint64 rowbytes = TIFFScanlineSize64(tif); uint32 rowsperstrip = td->td_imagelength/td->td_stripsperimage; for (strip = 0; strip < td->td_nstrips; strip++) td->td_stripbytecount[strip] = rowbytes * rowsperstrip; @@ -1020,8 +4358,8 @@ MissingRequired(TIFF* tif, const char* tagname) static const char module[] = "MissingRequired"; TIFFErrorExt(tif->tif_clientdata, module, - "%s: TIFF directory is missing required \"%s\" field", - tif->tif_name, tagname); + "TIFF directory is missing required \"%s\" field", + tagname); } /* @@ -1031,12 +4369,17 @@ MissingRequired(TIFF* tif, const char* tagname) * seen directories and check every IFD offset against that list. */ static int -TIFFCheckDirOffset(TIFF* tif, toff_t diroff) +TIFFCheckDirOffset(TIFF* tif, uint64 diroff) { uint16 n; 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) @@ -1046,20 +4389,20 @@ TIFFCheckDirOffset(TIFF* tif, toff_t diroff) tif->tif_dirnumber++; if (tif->tif_dirnumber > tif->tif_dirlistsize) { - toff_t* new_dirlist; + uint64* new_dirlist; /* * XXX: Reduce memory allocation granularity of the dirlist * array. */ - new_dirlist = (toff_t *)_TIFFCheckRealloc(tif, - tif->tif_dirlist, - tif->tif_dirnumber, - 2 * sizeof(toff_t), - "for IFD list"); + new_dirlist = (uint64*)_TIFFCheckRealloc(tif, tif->tif_dirlist, + tif->tif_dirnumber, 2 * sizeof(uint64), "for IFD list"); if (!new_dirlist) return 0; - tif->tif_dirlistsize = 2 * tif->tif_dirnumber; + if( tif->tif_dirnumber >= 32768 ) + tif->tif_dirlistsize = 65535; + else + tif->tif_dirlistsize = 2 * tif->tif_dirnumber; tif->tif_dirlist = new_dirlist; } @@ -1075,17 +4418,20 @@ TIFFCheckDirOffset(TIFF* tif, toff_t diroff) static int CheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32 count) { - if (count > dir->tdir_count) { + if ((uint64)count > dir->tdir_count) { + const TIFFField* fip = TIFFFieldWithTag(tif, dir->tdir_tag); TIFFWarningExt(tif->tif_clientdata, tif->tif_name, - "incorrect count for field \"%s\" (%u, expecting %u); tag ignored", - _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name, + "incorrect count for field \"%s\" (" TIFF_UINT64_FORMAT ", expecting %u); tag ignored", + fip ? fip->field_name : "unknown tagname", dir->tdir_count, count); return (0); - } else if (count < dir->tdir_count) { + } else if ((uint64)count < dir->tdir_count) { + const TIFFField* fip = TIFFFieldWithTag(tif, dir->tdir_tag); TIFFWarningExt(tif->tif_clientdata, tif->tif_name, - "incorrect count for field \"%s\" (%u, expecting %u); tag trimmed", - _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name, + "incorrect count for field \"%s\" (" TIFF_UINT64_FORMAT ", expecting %u); tag trimmed", + fip ? fip->field_name : "unknown tagname", dir->tdir_count, count); + dir->tdir_count = count; return (1); } return (1); @@ -1097,13 +4443,18 @@ CheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32 count) * number of fields in the directory or 0 if failed. */ static uint16 -TIFFFetchDirectory(TIFF* tif, toff_t diroff, TIFFDirEntry **pdir, - toff_t *nextdiroff) +TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntry** pdir, + uint64 *nextdiroff) { static const char module[] = "TIFFFetchDirectory"; - TIFFDirEntry *dir; - uint16 dircount; + void* origdir; + uint16 dircount16; + uint32 dirsize; + TIFFDirEntry* dir; + uint8* ma; + TIFFDirEntry* mb; + uint16 n; assert(pdir); @@ -1117,24 +4468,51 @@ TIFFFetchDirectory(TIFF* tif, toff_t diroff, TIFFDirEntry **pdir, tif->tif_name); return 0; } - if (!ReadOK(tif, &dircount, sizeof (uint16))) { - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Can not read TIFF directory count", - tif->tif_name); - return 0; + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + if (!ReadOK(tif, &dircount16, sizeof (uint16))) { + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Can not read TIFF directory count", + tif->tif_name); + return 0; + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount16); + if (dircount16>4096) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Sanity check on directory count failed, this is probably not a valid IFD offset"); + return 0; + } + dirsize = 12; + } else { + uint64 dircount64; + if (!ReadOK(tif, &dircount64, sizeof (uint64))) { + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Can not read TIFF directory count", + tif->tif_name); + return 0; + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&dircount64); + if (dircount64>4096) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Sanity check on directory count failed, this is probably not a valid IFD offset"); + return 0; + } + dircount16 = (uint16)dircount64; + dirsize = 20; } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&dircount); - dir = (TIFFDirEntry *)_TIFFCheckMalloc(tif, dircount, - sizeof (TIFFDirEntry), - "to read TIFF directory"); - if (dir == NULL) + origdir = _TIFFCheckMalloc(tif, dircount16, + dirsize, "to read TIFF directory"); + if (origdir == NULL) return 0; - if (!ReadOK(tif, dir, dircount*sizeof (TIFFDirEntry))) { + if (!ReadOK(tif, origdir, (tmsize_t)(dircount16*dirsize))) { TIFFErrorExt(tif->tif_clientdata, module, "%.100s: Can not read TIFF directory", tif->tif_name); - _TIFFfree(dir); + _TIFFfree(origdir); return 0; } /* @@ -1142,9 +4520,30 @@ TIFFFetchDirectory(TIFF* tif, toff_t diroff, TIFFDirEntry **pdir, * needed. */ if (nextdiroff) - (void) ReadOK(tif, nextdiroff, sizeof(uint32)); + { + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + uint32 nextdiroff32; + if (!ReadOK(tif, &nextdiroff32, sizeof(uint32))) + nextdiroff32 = 0; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(&nextdiroff32); + *nextdiroff=nextdiroff32; + } else { + if (!ReadOK(tif, nextdiroff, sizeof(uint64))) + *nextdiroff = 0; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8(nextdiroff); + } + } } else { - toff_t off = tif->tif_diroff; + tmsize_t m; + tmsize_t off = (tmsize_t) tif->tif_diroff; + if ((uint64)off!=tif->tif_diroff) + { + TIFFErrorExt(tif->tif_clientdata,module,"Can not read TIFF directory count"); + return(0); + } /* * Check for integer overflow when validating the dir_off, @@ -1155,809 +4554,857 @@ TIFFFetchDirectory(TIFF* tif, toff_t diroff, TIFFDirEntry **pdir, * * to avoid overflow. */ - if (tif->tif_size < sizeof (uint16) || - off > tif->tif_size - sizeof(uint16)) { - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Can not read TIFF directory count", - tif->tif_name); - return 0; - } else { - _TIFFmemcpy(&dircount, tif->tif_base + off, - sizeof(uint16)); + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + m=off+sizeof(uint16); + if ((mtif->tif_size)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Can not read TIFF directory count"); + return 0; + } else { + _TIFFmemcpy(&dircount16, tif->tif_base + off, + sizeof(uint16)); + } + off += sizeof (uint16); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount16); + if (dircount16>4096) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Sanity check on directory count failed, this is probably not a valid IFD offset"); + return 0; + } + dirsize = 12; } - off += sizeof (uint16); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&dircount); - dir = (TIFFDirEntry *)_TIFFCheckMalloc(tif, dircount, - sizeof(TIFFDirEntry), - "to read TIFF directory"); - if (dir == NULL) - return 0; - if (off + dircount * sizeof (TIFFDirEntry) > tif->tif_size) { + else + { + tmsize_t m; + uint64 dircount64; + m=off+sizeof(uint64); + if ((mtif->tif_size)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Can not read TIFF directory count"); + return 0; + } else { + _TIFFmemcpy(&dircount64, tif->tif_base + off, + sizeof(uint64)); + } + off += sizeof (uint64); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&dircount64); + if (dircount64>4096) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Sanity check on directory count failed, this is probably not a valid IFD offset"); + return 0; + } + dircount16 = (uint16)dircount64; + dirsize = 20; + } + if (dircount16 == 0 ) + { TIFFErrorExt(tif->tif_clientdata, module, - "%s: Can not read TIFF directory", - tif->tif_name); - _TIFFfree(dir); + "Sanity check on directory count failed, zero tag directories not supported"); + return 0; + } + origdir = _TIFFCheckMalloc(tif, dircount16, + dirsize, + "to read TIFF directory"); + if (origdir == NULL) + return 0; + m=off+dircount16*dirsize; + if ((mtif->tif_size)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Can not read TIFF directory"); + _TIFFfree(origdir); return 0; } else { - _TIFFmemcpy(dir, tif->tif_base + off, - dircount * sizeof(TIFFDirEntry)); + _TIFFmemcpy(origdir, tif->tif_base + off, + dircount16 * dirsize); } if (nextdiroff) { - off += dircount * sizeof (TIFFDirEntry); - if (off + sizeof (uint32) <= tif->tif_size) { - _TIFFmemcpy(nextdiroff, tif->tif_base + off, - sizeof (uint32)); + off += dircount16 * dirsize; + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + uint32 nextdiroff32; + m=off+sizeof(uint32); + if ((mtif->tif_size)) + nextdiroff32 = 0; + else + _TIFFmemcpy(&nextdiroff32, tif->tif_base + off, + sizeof (uint32)); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(&nextdiroff32); + *nextdiroff = nextdiroff32; + } + else + { + m=off+sizeof(uint64); + if ((mtif->tif_size)) + *nextdiroff = 0; + else + _TIFFmemcpy(nextdiroff, tif->tif_base + off, + sizeof (uint64)); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8(nextdiroff); } } } - if (nextdiroff && tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(nextdiroff); - *pdir = dir; - return dircount; -} - -/* - * Fetch a contiguous directory item. - */ -static tsize_t -TIFFFetchData(TIFF* tif, TIFFDirEntry* dir, char* cp) -{ - uint32 w = TIFFDataWidth((TIFFDataType) dir->tdir_type); - /* - * FIXME: butecount should have tsize_t type, but for now libtiff - * defines tsize_t as a signed 32-bit integer and we are losing - * ability to read arrays larger than 2^31 bytes. So we are using - * uint32 instead of tsize_t here. - */ - uint32 cc = dir->tdir_count * w; - - /* Check for overflow. */ - if (!dir->tdir_count || !w || cc / w != dir->tdir_count) - goto bad; - - if (!isMapped(tif)) { - if (!SeekOK(tif, dir->tdir_offset)) - goto bad; - if (!ReadOK(tif, cp, cc)) - goto bad; - } else { - /* Check for overflow. */ - if (dir->tdir_offset + cc < dir->tdir_offset - || dir->tdir_offset + cc < cc - || dir->tdir_offset + cc > tif->tif_size) - goto bad; - _TIFFmemcpy(cp, tif->tif_base + dir->tdir_offset, cc); - } - if (tif->tif_flags & TIFF_SWAB) { - switch (dir->tdir_type) { - case TIFF_SHORT: - case TIFF_SSHORT: - TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count); - break; - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_FLOAT: - TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count); - break; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count); - break; - case TIFF_DOUBLE: - TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count); - break; - } - } - return (cc); -bad: - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Error fetching data for field \"%s\"", - _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); - return (tsize_t) 0; -} - -/* - * Fetch an ASCII item from the file. - */ -static tsize_t -TIFFFetchString(TIFF* tif, TIFFDirEntry* dir, char* cp) -{ - if (dir->tdir_count <= 4) { - uint32 l = dir->tdir_offset; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&l); - _TIFFmemcpy(cp, &l, dir->tdir_count); - return (1); - } - return (TIFFFetchData(tif, dir, cp)); -} - -/* - * Convert numerator+denominator to float. - */ -static int -cvtRational(TIFF* tif, TIFFDirEntry* dir, uint32 num, uint32 denom, float* rv) -{ - if (denom == 0) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "%s: Rational with zero denominator (num = %u)", - _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name, num); - return (0); - } else { - if (dir->tdir_type == TIFF_RATIONAL) - *rv = ((float)num / (float)denom); - else - *rv = ((float)(int32)num / (float)(int32)denom); - return (1); - } -} - -/* - * Fetch a rational item from the file at offset off and return the value as a - * floating point number. - */ -static float -TIFFFetchRational(TIFF* tif, TIFFDirEntry* dir) -{ - uint32 l[2]; - float v; - - return (!TIFFFetchData(tif, dir, (char *)l) || - !cvtRational(tif, dir, l[0], l[1], &v) ? 1.0f : v); -} - -/* - * Fetch a single floating point value from the offset field and return it as - * a native float. - */ -static float -TIFFFetchFloat(TIFF* tif, TIFFDirEntry* dir) -{ - float v; - int32 l = TIFFExtractData(tif, dir->tdir_type, dir->tdir_offset); - _TIFFmemcpy(&v, &l, sizeof(float)); - TIFFCvtIEEEFloatToNative(tif, 1, &v); - return (v); -} - -/* - * Fetch an array of BYTE or SBYTE values. - */ -static int -TIFFFetchByteArray(TIFF* tif, TIFFDirEntry* dir, uint8* v) -{ - if (dir->tdir_count <= 4) { - /* - * Extract data from offset field. - */ - if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) { - if (dir->tdir_type == TIFF_SBYTE) - switch (dir->tdir_count) { - case 4: v[3] = dir->tdir_offset & 0xff; - case 3: v[2] = (dir->tdir_offset >> 8) & 0xff; - case 2: v[1] = (dir->tdir_offset >> 16) & 0xff; - case 1: v[0] = dir->tdir_offset >> 24; - } - else - switch (dir->tdir_count) { - case 4: v[3] = dir->tdir_offset & 0xff; - case 3: v[2] = (dir->tdir_offset >> 8) & 0xff; - case 2: v[1] = (dir->tdir_offset >> 16) & 0xff; - case 1: v[0] = dir->tdir_offset >> 24; - } - } else { - if (dir->tdir_type == TIFF_SBYTE) - switch (dir->tdir_count) { - case 4: v[3] = dir->tdir_offset >> 24; - case 3: v[2] = (dir->tdir_offset >> 16) & 0xff; - case 2: v[1] = (dir->tdir_offset >> 8) & 0xff; - case 1: v[0] = dir->tdir_offset & 0xff; - } - else - switch (dir->tdir_count) { - case 4: v[3] = dir->tdir_offset >> 24; - case 3: v[2] = (dir->tdir_offset >> 16) & 0xff; - case 2: v[1] = (dir->tdir_offset >> 8) & 0xff; - case 1: v[0] = dir->tdir_offset & 0xff; - } - } - return (1); - } else - return (TIFFFetchData(tif, dir, (char*) v) != 0); /* XXX */ -} - -/* - * Fetch an array of SHORT or SSHORT values. - */ -static int -TIFFFetchShortArray(TIFF* tif, TIFFDirEntry* dir, uint16* v) -{ - if (dir->tdir_count <= 2) { - if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) { - switch (dir->tdir_count) { - case 2: v[1] = (uint16) (dir->tdir_offset & 0xffff); - case 1: v[0] = (uint16) (dir->tdir_offset >> 16); - } - } else { - switch (dir->tdir_count) { - case 2: v[1] = (uint16) (dir->tdir_offset >> 16); - case 1: v[0] = (uint16) (dir->tdir_offset & 0xffff); - } - } - return (1); - } else - return (TIFFFetchData(tif, dir, (char *)v) != 0); -} - -/* - * Fetch a pair of SHORT or BYTE values. Some tags may have either BYTE - * or SHORT type and this function works with both ones. - */ -static int -TIFFFetchShortPair(TIFF* tif, TIFFDirEntry* dir) -{ - /* - * Prevent overflowing the v stack arrays below by performing a sanity - * check on tdir_count, this should never be greater than two. - */ - if (dir->tdir_count > 2) { - TIFFWarningExt(tif->tif_clientdata, tif->tif_name, - "unexpected count for field \"%s\", %u, expected 2; ignored", - _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name, - dir->tdir_count); + dir = (TIFFDirEntry*)_TIFFCheckMalloc(tif, dircount16, + sizeof(TIFFDirEntry), + "to read TIFF directory"); + if (dir==0) + { + _TIFFfree(origdir); return 0; } - - switch (dir->tdir_type) { - case TIFF_BYTE: - case TIFF_SBYTE: - { - uint8 v[4]; - return TIFFFetchByteArray(tif, dir, v) - && TIFFSetField(tif, dir->tdir_tag, v[0], v[1]); - } - case TIFF_SHORT: - case TIFF_SSHORT: - { - uint16 v[2]; - return TIFFFetchShortArray(tif, dir, v) - && TIFFSetField(tif, dir->tdir_tag, v[0], v[1]); - } - default: - return 0; - } -} - -/* - * Fetch an array of LONG or SLONG values. - */ -static int -TIFFFetchLongArray(TIFF* tif, TIFFDirEntry* dir, uint32* v) -{ - if (dir->tdir_count == 1) { - v[0] = dir->tdir_offset; - return (1); - } else - return (TIFFFetchData(tif, dir, (char*) v) != 0); -} - -/* - * Fetch an array of RATIONAL or SRATIONAL values. - */ -static int -TIFFFetchRationalArray(TIFF* tif, TIFFDirEntry* dir, float* v) -{ - int ok = 0; - uint32* l; - - l = (uint32*)_TIFFCheckMalloc(tif, - dir->tdir_count, TIFFDataWidth((TIFFDataType) dir->tdir_type), - "to fetch array of rationals"); - if (l) { - if (TIFFFetchData(tif, dir, (char *)l)) { - uint32 i; - for (i = 0; i < dir->tdir_count; i++) { - ok = cvtRational(tif, dir, - l[2*i+0], l[2*i+1], &v[i]); - if (!ok) - break; - } - } - _TIFFfree((char *)l); - } - return (ok); -} - -/* - * Fetch an array of FLOAT values. - */ -static int -TIFFFetchFloatArray(TIFF* tif, TIFFDirEntry* dir, float* v) -{ - - if (dir->tdir_count == 1) { - union + ma=(uint8*)origdir; + mb=dir; + for (n=0; ntif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)ma); + mb->tdir_tag=*(uint16*)ma; + ma+=sizeof(uint16); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)ma); + mb->tdir_type=*(uint16*)ma; + ma+=sizeof(uint16); + if (!(tif->tif_flags&TIFF_BIGTIFF)) { - float f; - uint32 i; - } float_union; - - float_union.i=dir->tdir_offset; - v[0]=float_union.f; - TIFFCvtIEEEFloatToNative(tif, dir->tdir_count, v); - return (1); - } else if (TIFFFetchData(tif, dir, (char*) v)) { - TIFFCvtIEEEFloatToNative(tif, dir->tdir_count, v); - return (1); - } else - return (0); -} - -/* - * Fetch an array of DOUBLE values. - */ -static int -TIFFFetchDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v) -{ - if (TIFFFetchData(tif, dir, (char*) v)) { - TIFFCvtIEEEDoubleToNative(tif, dir->tdir_count, v); - return (1); - } else - return (0); -} - -/* - * Fetch an array of ANY values. The actual values are returned as doubles - * which should be able hold all the types. Yes, there really should be an - * tany_t to avoid this potential non-portability ... Note in particular that - * we assume that the double return value vector is large enough to read in - * any fundamental type. We use that vector as a buffer to read in the base - * type vector and then convert it in place to double (from end to front of - * course). - */ -static int -TIFFFetchAnyArray(TIFF* tif, TIFFDirEntry* dir, double* v) -{ - int i; - - switch (dir->tdir_type) { - case TIFF_BYTE: - case TIFF_SBYTE: - if (!TIFFFetchByteArray(tif, dir, (uint8*) v)) - return (0); - if (dir->tdir_type == TIFF_BYTE) { - uint8* vp = (uint8*) v; - for (i = dir->tdir_count-1; i >= 0; i--) - v[i] = vp[i]; - } else { - int8* vp = (int8*) v; - for (i = dir->tdir_count-1; i >= 0; i--) - v[i] = vp[i]; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)ma); + mb->tdir_count=(uint64)(*(uint32*)ma); + ma+=sizeof(uint32); + *(uint32*)(&mb->tdir_offset)=*(uint32*)ma; + ma+=sizeof(uint32); } - break; - case TIFF_SHORT: - case TIFF_SSHORT: - if (!TIFFFetchShortArray(tif, dir, (uint16*) v)) - return (0); - if (dir->tdir_type == TIFF_SHORT) { - uint16* vp = (uint16*) v; - for (i = dir->tdir_count-1; i >= 0; i--) - v[i] = vp[i]; - } else { - int16* vp = (int16*) v; - for (i = dir->tdir_count-1; i >= 0; i--) - v[i] = vp[i]; + else + { + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)ma); + mb->tdir_count=TIFFReadUInt64(ma); + ma+=sizeof(uint64); + mb->tdir_offset.toff_long8=TIFFReadUInt64(ma); + ma+=sizeof(uint64); } - break; - case TIFF_LONG: - case TIFF_SLONG: - if (!TIFFFetchLongArray(tif, dir, (uint32*) v)) - return (0); - if (dir->tdir_type == TIFF_LONG) { - uint32* vp = (uint32*) v; - for (i = dir->tdir_count-1; i >= 0; i--) - v[i] = vp[i]; - } else { - int32* vp = (int32*) v; - for (i = dir->tdir_count-1; i >= 0; i--) - v[i] = vp[i]; - } - break; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - if (!TIFFFetchRationalArray(tif, dir, (float*) v)) - return (0); - { float* vp = (float*) v; - for (i = dir->tdir_count-1; i >= 0; i--) - v[i] = vp[i]; - } - break; - case TIFF_FLOAT: - if (!TIFFFetchFloatArray(tif, dir, (float*) v)) - return (0); - { float* vp = (float*) v; - for (i = dir->tdir_count-1; i >= 0; i--) - v[i] = vp[i]; - } - break; - case TIFF_DOUBLE: - return (TIFFFetchDoubleArray(tif, dir, (double*) v)); - default: - /* TIFF_NOTYPE */ - /* TIFF_ASCII */ - /* TIFF_UNDEFINED */ - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "cannot read TIFF_ANY type %d for field \"%s\"", - dir->tdir_type, - _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); - return (0); + mb++; } - return (1); + _TIFFfree(origdir); + *pdir = dir; + return dircount16; } /* * Fetch a tag that is not handled by special case code. */ static int -TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp) +TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) { - static const char mesg[] = "to fetch tag value"; - int ok = 0; - const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, dp->tdir_tag); - - if (dp->tdir_count > 1) { /* array of values */ - char* cp = NULL; - - switch (dp->tdir_type) { - case TIFF_BYTE: - case TIFF_SBYTE: - cp = (char *)_TIFFCheckMalloc(tif, - dp->tdir_count, sizeof (uint8), mesg); - ok = cp && TIFFFetchByteArray(tif, dp, (uint8*) cp); + static const char module[] = "TIFFFetchNormalTag"; + enum TIFFReadDirEntryErr err; + uint32 fii; + const TIFFField* fip = NULL; + TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii); + if( fii == FAILED_FII ) + { + TIFFErrorExt(tif->tif_clientdata, "TIFFFetchNormalTag", + "No definition found for tag %d", + dp->tdir_tag); + 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; + switch (fip->set_field_type) + { + case TIFF_SETGET_UNDEFINED: break; - case TIFF_SHORT: - case TIFF_SSHORT: - cp = (char *)_TIFFCheckMalloc(tif, - dp->tdir_count, sizeof (uint16), mesg); - ok = cp && TIFFFetchShortArray(tif, dp, (uint16*) cp); - break; - case TIFF_LONG: - case TIFF_SLONG: - cp = (char *)_TIFFCheckMalloc(tif, - dp->tdir_count, sizeof (uint32), mesg); - ok = cp && TIFFFetchLongArray(tif, dp, (uint32*) cp); - break; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - cp = (char *)_TIFFCheckMalloc(tif, - dp->tdir_count, sizeof (float), mesg); - ok = cp && TIFFFetchRationalArray(tif, dp, (float*) cp); - break; - case TIFF_FLOAT: - cp = (char *)_TIFFCheckMalloc(tif, - dp->tdir_count, sizeof (float), mesg); - ok = cp && TIFFFetchFloatArray(tif, dp, (float*) cp); - break; - case TIFF_DOUBLE: - cp = (char *)_TIFFCheckMalloc(tif, - dp->tdir_count, sizeof (double), mesg); - ok = cp && TIFFFetchDoubleArray(tif, dp, (double*) cp); - break; - case TIFF_ASCII: - case TIFF_UNDEFINED: /* bit of a cheat... */ - /* - * Some vendors write strings w/o the trailing - * NULL byte, so always append one just in case. - */ - cp = (char *)_TIFFCheckMalloc(tif, dp->tdir_count + 1, - 1, mesg); - if( (ok = (cp && TIFFFetchString(tif, dp, cp))) != 0 ) - cp[dp->tdir_count] = '\0'; /* XXX */ - break; - } - if (ok) { - ok = (fip->field_passcount ? - TIFFSetField(tif, dp->tdir_tag, dp->tdir_count, cp) - : TIFFSetField(tif, dp->tdir_tag, cp)); - } - if (cp != NULL) - _TIFFfree(cp); - } else if (CheckDirCount(tif, dp, 1)) { /* singleton value */ - switch (dp->tdir_type) { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - /* - * If the tag is also acceptable as a LONG or SLONG - * then TIFFSetField will expect an uint32 parameter - * passed to it (through varargs). Thus, for machines - * where sizeof (int) != sizeof (uint32) we must do - * a careful check here. It's hard to say if this - * is worth optimizing. - * - * NB: We use TIFFFieldWithTag here knowing that - * it returns us the first entry in the table - * for the tag and that that entry is for the - * widest potential data type the tag may have. - */ - { TIFFDataType type = fip->field_type; - if (type != TIFF_LONG && type != TIFF_SLONG) { - uint16 v = (uint16) - TIFFExtractData(tif, dp->tdir_type, dp->tdir_offset); - ok = (fip->field_passcount ? - TIFFSetField(tif, dp->tdir_tag, 1, &v) - : TIFFSetField(tif, dp->tdir_tag, v)); - break; - } - } - /* fall thru... */ - case TIFF_LONG: - case TIFF_SLONG: - { uint32 v32 = - TIFFExtractData(tif, dp->tdir_type, dp->tdir_offset); - ok = (fip->field_passcount ? - TIFFSetField(tif, dp->tdir_tag, 1, &v32) - : TIFFSetField(tif, dp->tdir_tag, v32)); + case TIFF_SETGET_ASCII: + { + uint8* data; + assert(fip->field_passcount==0); + err=TIFFReadDirEntryByteArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + uint8* ma; + uint32 mb; + int n; + ma=data; + mb=0; + while (mb<(uint32)dp->tdir_count) + { + if (*ma==0) + break; + ma++; + mb++; + } + if (mb+1<(uint32)dp->tdir_count) + TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" contains null byte in value; value incorrectly truncated during reading due to implementation limitations",fip->field_name); + else if (mb+1>(uint32)dp->tdir_count) + { + uint8* o; + TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte",fip->field_name); + if ((uint32)dp->tdir_count+1!=dp->tdir_count+1) + o=NULL; + else + o=_TIFFmalloc((uint32)dp->tdir_count+1); + if (o==NULL) + { + if (data!=NULL) + _TIFFfree(data); + return(0); + } + _TIFFmemcpy(o,data,(uint32)dp->tdir_count); + o[(uint32)dp->tdir_count]=0; + if (data!=0) + _TIFFfree(data); + data=o; + } + n=TIFFSetField(tif,dp->tdir_tag,data); + if (data!=0) + _TIFFfree(data); + if (!n) + return(0); + } } break; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - case TIFF_FLOAT: - { float v = (dp->tdir_type == TIFF_FLOAT ? - TIFFFetchFloat(tif, dp) - : TIFFFetchRational(tif, dp)); - ok = (fip->field_passcount ? - TIFFSetField(tif, dp->tdir_tag, 1, &v) - : TIFFSetField(tif, dp->tdir_tag, v)); + case TIFF_SETGET_UINT8: + { + uint8 data=0; + assert(fip->field_readcount==1); + assert(fip->field_passcount==0); + err=TIFFReadDirEntryByte(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif,dp->tdir_tag,data)) + return(0); + } } break; - case TIFF_DOUBLE: - { double v; - ok = (TIFFFetchDoubleArray(tif, dp, &v) && - (fip->field_passcount ? - TIFFSetField(tif, dp->tdir_tag, 1, &v) - : TIFFSetField(tif, dp->tdir_tag, v)) - ); + case TIFF_SETGET_UINT16: + { + uint16 data; + assert(fip->field_readcount==1); + assert(fip->field_passcount==0); + err=TIFFReadDirEntryShort(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif,dp->tdir_tag,data)) + return(0); + } } break; - case TIFF_ASCII: - case TIFF_UNDEFINED: /* bit of a cheat... */ - { char c[2]; - if( (ok = (TIFFFetchString(tif, dp, c) != 0)) != 0 ) { - c[1] = '\0'; /* XXX paranoid */ - ok = (fip->field_passcount ? - TIFFSetField(tif, dp->tdir_tag, 1, c) - : TIFFSetField(tif, dp->tdir_tag, c)); - } + case TIFF_SETGET_UINT32: + { + uint32 data; + assert(fip->field_readcount==1); + assert(fip->field_passcount==0); + err=TIFFReadDirEntryLong(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif,dp->tdir_tag,data)) + return(0); + } } break; - } + case TIFF_SETGET_UINT64: + { + uint64 data; + assert(fip->field_readcount==1); + assert(fip->field_passcount==0); + err=TIFFReadDirEntryLong8(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif,dp->tdir_tag,data)) + return(0); + } + } + break; + case TIFF_SETGET_FLOAT: + { + float data; + assert(fip->field_readcount==1); + assert(fip->field_passcount==0); + err=TIFFReadDirEntryFloat(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif,dp->tdir_tag,data)) + return(0); + } + } + break; + case TIFF_SETGET_DOUBLE: + { + double data; + assert(fip->field_readcount==1); + assert(fip->field_passcount==0); + err=TIFFReadDirEntryDouble(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif,dp->tdir_tag,data)) + return(0); + } + } + break; + case TIFF_SETGET_IFD8: + { + uint64 data; + assert(fip->field_readcount==1); + assert(fip->field_passcount==0); + err=TIFFReadDirEntryIfd8(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif,dp->tdir_tag,data)) + return(0); + } + } + break; + case TIFF_SETGET_UINT16_PAIR: + { + uint16* data; + assert(fip->field_readcount==2); + assert(fip->field_passcount==0); + 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) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,data[0],data[1]); + _TIFFfree(data); + if (!m) + return(0); + } + } + break; + case TIFF_SETGET_C0_UINT8: + { + uint8* data; + assert(fip->field_readcount>=1); + assert(fip->field_passcount==0); + 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); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; + case TIFF_SETGET_C0_UINT16: + { + uint16* data; + assert(fip->field_readcount>=1); + assert(fip->field_passcount==0); + if (dp->tdir_count!=(uint64)fip->field_readcount) + /* corrupt file */; + else + { + err=TIFFReadDirEntryShortArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; + case TIFF_SETGET_C0_UINT32: + { + uint32* data; + assert(fip->field_readcount>=1); + assert(fip->field_passcount==0); + if (dp->tdir_count!=(uint64)fip->field_readcount) + /* corrupt file */; + else + { + err=TIFFReadDirEntryLongArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; + case TIFF_SETGET_C0_FLOAT: + { + float* data; + assert(fip->field_readcount>=1); + assert(fip->field_passcount==0); + if (dp->tdir_count!=(uint64)fip->field_readcount) + /* corrupt file */; + else + { + err=TIFFReadDirEntryFloatArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; + case TIFF_SETGET_C16_ASCII: + { + uint8* data; + assert(fip->field_readcount==TIFF_VARIABLE); + assert(fip->field_passcount==1); + if (dp->tdir_count>0xFFFF) + err=TIFFReadDirEntryErrCount; + else + { + err=TIFFReadDirEntryByteArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; + case TIFF_SETGET_C16_UINT8: + { + uint8* data; + assert(fip->field_readcount==TIFF_VARIABLE); + assert(fip->field_passcount==1); + if (dp->tdir_count>0xFFFF) + err=TIFFReadDirEntryErrCount; + else + { + err=TIFFReadDirEntryByteArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; + case TIFF_SETGET_C16_UINT16: + { + uint16* data; + assert(fip->field_readcount==TIFF_VARIABLE); + assert(fip->field_passcount==1); + if (dp->tdir_count>0xFFFF) + err=TIFFReadDirEntryErrCount; + else + { + err=TIFFReadDirEntryShortArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; + case TIFF_SETGET_C16_UINT32: + { + uint32* data; + assert(fip->field_readcount==TIFF_VARIABLE); + assert(fip->field_passcount==1); + if (dp->tdir_count>0xFFFF) + err=TIFFReadDirEntryErrCount; + else + { + err=TIFFReadDirEntryLongArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; + case TIFF_SETGET_C16_UINT64: + { + uint64* data; + assert(fip->field_readcount==TIFF_VARIABLE); + assert(fip->field_passcount==1); + if (dp->tdir_count>0xFFFF) + err=TIFFReadDirEntryErrCount; + else + { + err=TIFFReadDirEntryLong8Array(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; + case TIFF_SETGET_C16_FLOAT: + { + float* data; + assert(fip->field_readcount==TIFF_VARIABLE); + assert(fip->field_passcount==1); + if (dp->tdir_count>0xFFFF) + err=TIFFReadDirEntryErrCount; + else + { + err=TIFFReadDirEntryFloatArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; + case TIFF_SETGET_C16_DOUBLE: + { + double* data; + assert(fip->field_readcount==TIFF_VARIABLE); + assert(fip->field_passcount==1); + if (dp->tdir_count>0xFFFF) + err=TIFFReadDirEntryErrCount; + else + { + err=TIFFReadDirEntryDoubleArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; + case TIFF_SETGET_C16_IFD8: + { + uint64* data; + assert(fip->field_readcount==TIFF_VARIABLE); + assert(fip->field_passcount==1); + if (dp->tdir_count>0xFFFF) + err=TIFFReadDirEntryErrCount; + else + { + err=TIFFReadDirEntryIfd8Array(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + } + break; + case TIFF_SETGET_C32_ASCII: + { + uint8* data; + assert(fip->field_readcount==TIFF_VARIABLE2); + assert(fip->field_passcount==1); + err=TIFFReadDirEntryByteArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + break; + case TIFF_SETGET_C32_UINT8: + { + uint8* data; + assert(fip->field_readcount==TIFF_VARIABLE2); + assert(fip->field_passcount==1); + err=TIFFReadDirEntryByteArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + break; + case TIFF_SETGET_C32_SINT8: + { + int8* data = NULL; + assert(fip->field_readcount==TIFF_VARIABLE2); + assert(fip->field_passcount==1); + err=TIFFReadDirEntrySbyteArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + break; + case TIFF_SETGET_C32_UINT16: + { + uint16* data; + assert(fip->field_readcount==TIFF_VARIABLE2); + assert(fip->field_passcount==1); + err=TIFFReadDirEntryShortArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + break; + case TIFF_SETGET_C32_SINT16: + { + int16* data = NULL; + assert(fip->field_readcount==TIFF_VARIABLE2); + assert(fip->field_passcount==1); + err=TIFFReadDirEntrySshortArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + break; + case TIFF_SETGET_C32_UINT32: + { + uint32* data; + assert(fip->field_readcount==TIFF_VARIABLE2); + assert(fip->field_passcount==1); + err=TIFFReadDirEntryLongArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + break; + case TIFF_SETGET_C32_SINT32: + { + int32* data = NULL; + assert(fip->field_readcount==TIFF_VARIABLE2); + assert(fip->field_passcount==1); + err=TIFFReadDirEntrySlongArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + break; + case TIFF_SETGET_C32_UINT64: + { + uint64* data; + assert(fip->field_readcount==TIFF_VARIABLE2); + assert(fip->field_passcount==1); + err=TIFFReadDirEntryLong8Array(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + break; + case TIFF_SETGET_C32_SINT64: + { + int64* data = NULL; + assert(fip->field_readcount==TIFF_VARIABLE2); + assert(fip->field_passcount==1); + err=TIFFReadDirEntrySlong8Array(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + break; + case TIFF_SETGET_C32_FLOAT: + { + float* data; + assert(fip->field_readcount==TIFF_VARIABLE2); + assert(fip->field_passcount==1); + err=TIFFReadDirEntryFloatArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + break; + case TIFF_SETGET_C32_DOUBLE: + { + double* data; + assert(fip->field_readcount==TIFF_VARIABLE2); + assert(fip->field_passcount==1); + err=TIFFReadDirEntryDoubleArray(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + break; + case TIFF_SETGET_C32_IFD8: + { + uint64* data; + assert(fip->field_readcount==TIFF_VARIABLE2); + assert(fip->field_passcount==1); + err=TIFFReadDirEntryIfd8Array(tif,dp,&data); + if (err==TIFFReadDirEntryErrOk) + { + int m; + m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); + if (!m) + return(0); + } + } + break; + default: + assert(0); /* we should never get here */ + break; } - return (ok); + if (err!=TIFFReadDirEntryErrOk) + { + TIFFReadDirEntryOutputErr(tif,err,module,fip->field_name,recover); + return(0); + } + return(1); } -#define NITEMS(x) (sizeof (x) / sizeof (x[0])) -/* - * Fetch samples/pixel short values for - * the specified tag and verify that - * all values are the same. - */ -static int -TIFFFetchPerSampleShorts(TIFF* tif, TIFFDirEntry* dir, uint16* pl) -{ - uint16 samples = tif->tif_dir.td_samplesperpixel; - int status = 0; - - if (CheckDirCount(tif, dir, (uint32) samples)) { - uint16 buf[10]; - uint16* v = buf; - - if (dir->tdir_count > NITEMS(buf)) - v = (uint16*) _TIFFCheckMalloc(tif, dir->tdir_count, sizeof(uint16), - "to fetch per-sample values"); - if (v && TIFFFetchShortArray(tif, dir, v)) { - uint16 i; - int check_count = dir->tdir_count; - if( samples < check_count ) - check_count = samples; - - for (i = 1; i < check_count; i++) - if (v[i] != v[0]) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Cannot handle different per-sample values for field \"%s\"", - _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); - goto bad; - } - *pl = v[0]; - status = 1; - } - bad: - if (v && v != buf) - _TIFFfree(v); - } - return (status); -} - -/* - * Fetch samples/pixel long values for - * the specified tag and verify that - * all values are the same. - */ -static int -TIFFFetchPerSampleLongs(TIFF* tif, TIFFDirEntry* dir, uint32* pl) -{ - uint16 samples = tif->tif_dir.td_samplesperpixel; - int status = 0; - - if (CheckDirCount(tif, dir, (uint32) samples)) { - uint32 buf[10]; - uint32* v = buf; - - if (dir->tdir_count > NITEMS(buf)) - v = (uint32*) _TIFFCheckMalloc(tif, dir->tdir_count, sizeof(uint32), - "to fetch per-sample values"); - if (v && TIFFFetchLongArray(tif, dir, v)) { - uint16 i; - int check_count = dir->tdir_count; - - if( samples < check_count ) - check_count = samples; - for (i = 1; i < check_count; i++) - if (v[i] != v[0]) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Cannot handle different per-sample values for field \"%s\"", - _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); - goto bad; - } - *pl = v[0]; - status = 1; - } - bad: - if (v && v != buf) - _TIFFfree(v); - } - return (status); -} - -/* - * Fetch samples/pixel ANY values for the specified tag and verify that all - * values are the same. - */ -static int -TIFFFetchPerSampleAnys(TIFF* tif, TIFFDirEntry* dir, double* pl) -{ - uint16 samples = tif->tif_dir.td_samplesperpixel; - int status = 0; - - if (CheckDirCount(tif, dir, (uint32) samples)) { - double buf[10]; - double* v = buf; - - if (dir->tdir_count > NITEMS(buf)) - v = (double*) _TIFFCheckMalloc(tif, dir->tdir_count, sizeof (double), - "to fetch per-sample values"); - if (v && TIFFFetchAnyArray(tif, dir, v)) { - uint16 i; - int check_count = dir->tdir_count; - if( samples < check_count ) - check_count = samples; - - for (i = 1; i < check_count; i++) - if (v[i] != v[0]) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Cannot handle different per-sample values for field \"%s\"", - _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); - goto bad; - } - *pl = v[0]; - status = 1; - } - bad: - if (v && v != buf) - _TIFFfree(v); - } - return (status); -} -#undef NITEMS - /* * Fetch a set of offsets or lengths. * While this routine says "strips", in fact it's also used for tiles. */ static int -TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, long nstrips, uint32** lpp) +TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uint64** lpp) { - register uint32* lp; - int status; - - CheckDirCount(tif, dir, (uint32) nstrips); - - /* - * Allocate space for strip information. - */ - if (*lpp == NULL && - (*lpp = (uint32 *)_TIFFCheckMalloc(tif, - nstrips, sizeof (uint32), "for strip array")) == NULL) - return (0); - lp = *lpp; - _TIFFmemset( lp, 0, sizeof(uint32) * nstrips ); - - if (dir->tdir_type == (int)TIFF_SHORT) { - /* - * Handle uint16->uint32 expansion. - */ - uint16* dp = (uint16*) _TIFFCheckMalloc(tif, - dir->tdir_count, sizeof (uint16), "to fetch strip tag"); - if (dp == NULL) - return (0); - if( (status = TIFFFetchShortArray(tif, dir, dp)) != 0 ) { - int i; - - for( i = 0; i < nstrips && i < (int) dir->tdir_count; i++ ) - { - lp[i] = dp[i]; - } - } - _TIFFfree((char*) dp); - - } else if( nstrips != (int) dir->tdir_count ) { - /* Special case to correct length */ - - uint32* dp = (uint32*) _TIFFCheckMalloc(tif, - dir->tdir_count, sizeof (uint32), "to fetch strip tag"); - if (dp == NULL) - return (0); - - status = TIFFFetchLongArray(tif, dir, dp); - if( status != 0 ) { - int i; - - for( i = 0; i < nstrips && i < (int) dir->tdir_count; i++ ) - { - lp[i] = dp[i]; - } - } - - _TIFFfree( (char *) dp ); - } else - status = TIFFFetchLongArray(tif, dir, lp); - - return (status); -} - -/* - * Fetch and set the RefBlackWhite tag. - */ -static int -TIFFFetchRefBlackWhite(TIFF* tif, TIFFDirEntry* dir) -{ - static const char mesg[] = "for \"ReferenceBlackWhite\" array"; - char* cp; - int ok; - - if (dir->tdir_type == TIFF_RATIONAL) - return (TIFFFetchNormalTag(tif, dir)); - /* - * Handle LONG's for backward compatibility. - */ - cp = (char *)_TIFFCheckMalloc(tif, dir->tdir_count, - sizeof (uint32), mesg); - if( (ok = (cp && TIFFFetchLongArray(tif, dir, (uint32*) cp))) != 0) { - float* fp = (float*) - _TIFFCheckMalloc(tif, dir->tdir_count, sizeof (float), mesg); - if( (ok = (fp != NULL)) != 0 ) { - uint32 i; - for (i = 0; i < dir->tdir_count; i++) - fp[i] = (float)((uint32*) cp)[i]; - ok = TIFFSetField(tif, dir->tdir_tag, fp); - _TIFFfree((char*) fp); - } + static const char module[] = "TIFFFetchStripThing"; + enum TIFFReadDirEntryErr err; + uint64* data; + err=TIFFReadDirEntryLong8Array(tif,dir,&data); + 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 (cp) - _TIFFfree(cp); - return (ok); + if (dir->tdir_count!=(uint64)nstrips) + { + uint64* resizeddata; + 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; + } + *lpp=data; + return(1); } /* @@ -1966,29 +5413,56 @@ TIFFFetchRefBlackWhite(TIFF* tif, TIFFDirEntry* dir) static int TIFFFetchSubjectDistance(TIFF* tif, TIFFDirEntry* dir) { - uint32 l[2]; - float v; - int ok = 0; - - if( dir->tdir_count != 1 || dir->tdir_type != TIFF_RATIONAL ) - { - TIFFWarningExt(tif->tif_clientdata, tif->tif_name, - "incorrect count or type for SubjectDistance, tag ignored" ); - return (0); - } - - if (TIFFFetchData(tif, dir, (char *)l) - && cvtRational(tif, dir, l[0], l[1], &v)) { - /* - * XXX: Numerator 0xFFFFFFFF means that we have infinite - * distance. Indicate that with a negative floating point - * SubjectDistance value. - */ - ok = TIFFSetField(tif, dir->tdir_tag, - (l[0] != 0xFFFFFFFF) ? v : -v); + static const char module[] = "TIFFFetchSubjectDistance"; + enum TIFFReadDirEntryErr err; + UInt64Aligned_t m; + m.l=0; + assert(sizeof(double)==8); + assert(sizeof(uint64)==8); + assert(sizeof(uint32)==4); + if (dir->tdir_count!=1) + err=TIFFReadDirEntryErrCount; + else if (dir->tdir_type!=TIFF_RATIONAL) + err=TIFFReadDirEntryErrType; + else + { + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + uint32 offset; + offset=*(uint32*)(&dir->tdir_offset); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(&offset); + err=TIFFReadDirEntryData(tif,offset,8,m.i); + } + else + { + m.l=dir->tdir_offset.toff_long8; + err=TIFFReadDirEntryErrOk; + } + } + if (err==TIFFReadDirEntryErrOk) + { + double n; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong(m.i,2); + if (m.i[0]==0) + n=0.0; + else if (m.i[0]==0xFFFFFFFF) + /* + * XXX: Numerator 0xFFFFFFFF means that we have infinite + * distance. Indicate that with a negative floating point + * SubjectDistance value. + */ + n=-1.0; + else + n=(double)m.i[0]/(double)m.i[1]; + return(TIFFSetField(tif,dir->tdir_tag,n)); + } + else + { + TIFFReadDirEntryOutputErr(tif,err,module,"SubjectDistance",TRUE); + return(0); } - - return ok; } /* @@ -2001,42 +5475,59 @@ static void ChopUpSingleUncompressedStrip(TIFF* tif) { register TIFFDirectory *td = &tif->tif_dir; - uint32 bytecount = td->td_stripbytecount[0]; - uint32 offset = td->td_stripoffset[0]; - tsize_t rowbytes = TIFFVTileSize(tif, 1), stripbytes; - tstrip_t strip, nstrips, rowsperstrip; - uint32* newcounts; - uint32* newoffsets; + uint64 bytecount; + uint64 offset; + uint32 rowblock; + uint64 rowblockbytes; + uint64 stripbytes; + uint32 strip; + uint64 nstrips64; + uint32 nstrips32; + uint32 rowsperstrip; + uint64* newcounts; + uint64* newoffsets; + bytecount = td->td_stripbytecount[0]; + offset = td->td_stripoffset[0]; + assert(td->td_planarconfig == PLANARCONFIG_CONTIG); + if ((td->td_photometric == PHOTOMETRIC_YCBCR)&& + (!isUpSampled(tif))) + rowblock = td->td_ycbcrsubsampling[1]; + else + rowblock = 1; + rowblockbytes = TIFFVTileSize64(tif, rowblock); /* * Make the rows hold at least one scanline, but fill specified amount * of data if possible. */ - if (rowbytes > STRIP_SIZE_DEFAULT) { - stripbytes = rowbytes; - rowsperstrip = 1; - } else if (rowbytes > 0 ) { - rowsperstrip = STRIP_SIZE_DEFAULT / rowbytes; - stripbytes = rowbytes * rowsperstrip; + if (rowblockbytes > STRIP_SIZE_DEFAULT) { + stripbytes = rowblockbytes; + rowsperstrip = rowblock; + } else if (rowblockbytes > 0 ) { + uint32 rowblocksperstrip; + rowblocksperstrip = (uint32) (STRIP_SIZE_DEFAULT / rowblockbytes); + rowsperstrip = rowblocksperstrip * rowblock; + stripbytes = rowblocksperstrip * rowblockbytes; } - else - return; + else + return; - /* + /* * never increase the number of strips in an image */ if (rowsperstrip >= td->td_rowsperstrip) return; - nstrips = (tstrip_t) TIFFhowmany(bytecount, stripbytes); - if( nstrips == 0 ) /* something is wonky, do nothing. */ - return; + nstrips64 = TIFFhowmany_64(bytecount, stripbytes); + if ((nstrips64==0)||(nstrips64>0xFFFFFFFF)) /* something is wonky, do nothing. */ + return; + nstrips32 = (uint32)nstrips64; - newcounts = (uint32*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint32), + newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64), "for chopped \"StripByteCounts\" array"); - newoffsets = (uint32*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint32), + newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64), "for chopped \"StripOffsets\" array"); if (newcounts == NULL || newoffsets == NULL) { - /* + /* * Unable to allocate new strip information, give up and use * the original one strip information. */ @@ -2050,8 +5541,8 @@ ChopUpSingleUncompressedStrip(TIFF* tif) * Fill the strip information arrays with new bytecounts and offsets * that reflect the broken-up format. */ - for (strip = 0; strip < nstrips; strip++) { - if ((uint32)stripbytes > bytecount) + for (strip = 0; strip < nstrips32; strip++) { + if (stripbytes > bytecount) stripbytes = bytecount; newcounts[strip] = stripbytes; newoffsets[strip] = offset; @@ -2061,7 +5552,7 @@ ChopUpSingleUncompressedStrip(TIFF* tif) /* * Replace old single strip info with multi-strip info. */ - td->td_stripsperimage = td->td_nstrips = nstrips; + td->td_stripsperimage = td->td_nstrips = nstrips32; TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip); _TIFFfree(td->td_stripbytecount); @@ -2071,6 +5562,54 @@ ChopUpSingleUncompressedStrip(TIFF* tif) td->td_stripbytecountsorted = 1; } +int _TIFFFillStriles( TIFF *tif ) +{ +#if defined(DEFER_STRILE_LOAD) + register TIFFDirectory *td = &tif->tif_dir; + int return_value = 1; + + if( td->td_stripoffset != NULL ) + return 1; + + if( td->td_stripoffset_entry.tdir_count == 0 ) + return 0; + + if (!TIFFFetchStripThing(tif,&(td->td_stripoffset_entry), + td->td_nstrips,&td->td_stripoffset)) + { + return_value = 0; + } + + if (!TIFFFetchStripThing(tif,&(td->td_stripbytecount_entry), + td->td_nstrips,&td->td_stripbytecount)) + { + return_value = 0; + } + + _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry)); + _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry)); + + if (tif->tif_dir.td_nstrips > 1 && return_value == 1 ) { + uint32 strip; + + tif->tif_dir.td_stripbytecountsorted = 1; + for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) { + if (tif->tif_dir.td_stripoffset[strip - 1] > + tif->tif_dir.td_stripoffset[strip]) { + tif->tif_dir.td_stripbytecountsorted = 0; + break; + } + } + } + + return return_value; +#else /* !defined(DEFER_STRILE_LOAD) */ + (void) tif; + return 1; +#endif +} + + /* vim: set ts=8 sts=8 sw=8 noet: */ /* * Local Variables: diff --git a/thirdparty/libtiff/tif_dirwrite.c b/thirdparty/libtiff/tif_dirwrite.c index 8d308c42..a0fd8dc2 100644 --- a/thirdparty/libtiff/tif_dirwrite.c +++ b/thirdparty/libtiff/tif_dirwrite.c @@ -1,26 +1,26 @@ -/* $Id: tif_dirwrite.c,v 1.37.2.7 2010-06-08 18:50:42 bfriesen Exp $ */ +/* $Id: tif_dirwrite.c,v 1.78 2015-05-31 00:38:46 bfriesen Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -32,44 +32,144 @@ #include "tiffiop.h" #ifdef HAVE_IEEEFP -# define TIFFCvtNativeToIEEEFloat(tif, n, fp) -# define TIFFCvtNativeToIEEEDouble(tif, n, dp) +#define TIFFCvtNativeToIEEEFloat(tif, n, fp) +#define TIFFCvtNativeToIEEEDouble(tif, n, dp) #else -extern void TIFFCvtNativeToIEEEFloat(TIFF*, uint32, float*); -extern void TIFFCvtNativeToIEEEDouble(TIFF*, uint32, double*); +extern void TIFFCvtNativeToIEEEFloat(TIFF* tif, uint32 n, float* fp); +extern void TIFFCvtNativeToIEEEDouble(TIFF* tif, uint32 n, double* dp); #endif -static int TIFFWriteNormalTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*); -static void TIFFSetupShortLong(TIFF*, ttag_t, TIFFDirEntry*, uint32); -static void TIFFSetupShort(TIFF*, ttag_t, TIFFDirEntry*, uint16); -static int TIFFSetupShortPair(TIFF*, ttag_t, TIFFDirEntry*); -static int TIFFWritePerSampleShorts(TIFF*, ttag_t, TIFFDirEntry*); -static int TIFFWritePerSampleAnys(TIFF*, TIFFDataType, ttag_t, TIFFDirEntry*); -static int TIFFWriteShortTable(TIFF*, ttag_t, TIFFDirEntry*, uint32, uint16**); -static int TIFFWriteShortArray(TIFF*, TIFFDirEntry*, uint16*); -static int TIFFWriteLongArray(TIFF *, TIFFDirEntry*, uint32*); -static int TIFFWriteRationalArray(TIFF *, TIFFDirEntry*, float*); -static int TIFFWriteFloatArray(TIFF *, TIFFDirEntry*, float*); -static int TIFFWriteDoubleArray(TIFF *, TIFFDirEntry*, double*); -static int TIFFWriteByteArray(TIFF*, TIFFDirEntry*, char*); -static int TIFFWriteAnyArray(TIFF*, - TIFFDataType, ttag_t, TIFFDirEntry*, uint32, double*); -static int TIFFWriteTransferFunction(TIFF*, TIFFDirEntry*); -static int TIFFWriteInkNames(TIFF*, TIFFDirEntry*); -static int TIFFWriteData(TIFF*, TIFFDirEntry*, char*); -static int TIFFLinkDirectory(TIFF*); +static int TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff); -#define WriteRationalPair(type, tag1, v1, tag2, v2) { \ - TIFFWriteRational((tif), (type), (tag1), (dir), (v1)) \ - TIFFWriteRational((tif), (type), (tag2), (dir)+1, (v2)) \ - (dir)++; \ -} -#define TIFFWriteRational(tif, type, tag, dir, v) \ - (dir)->tdir_tag = (tag); \ - (dir)->tdir_type = (type); \ - (dir)->tdir_count = 1; \ - if (!TIFFWriteRationalArray((tif), (dir), &(v))) \ - goto bad; +static int TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value); +#if 0 +static int TIFFWriteDirectoryTagSampleformatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value); +#endif + +static int TIFFWriteDirectoryTagAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value); +static int TIFFWriteDirectoryTagUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value); +#ifdef notdef +static int TIFFWriteDirectoryTagByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value); +#endif +static int TIFFWriteDirectoryTagByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value); +#if 0 +static int TIFFWriteDirectoryTagBytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value); +#endif +#ifdef notdef +static int TIFFWriteDirectoryTagSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value); +#endif +static int TIFFWriteDirectoryTagSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value); +#if 0 +static int TIFFWriteDirectoryTagSbytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value); +#endif +static int TIFFWriteDirectoryTagShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value); +static int TIFFWriteDirectoryTagShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value); +static int TIFFWriteDirectoryTagShortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value); +#ifdef notdef +static int TIFFWriteDirectoryTagSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value); +#endif +static int TIFFWriteDirectoryTagSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value); +#if 0 +static int TIFFWriteDirectoryTagSshortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value); +#endif +static int TIFFWriteDirectoryTagLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value); +static int TIFFWriteDirectoryTagLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value); +#if 0 +static int TIFFWriteDirectoryTagLongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value); +#endif +#ifdef notdef +static int TIFFWriteDirectoryTagSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value); +#endif +static int TIFFWriteDirectoryTagSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value); +#if 0 +static int TIFFWriteDirectoryTagSlongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value); +#endif +#ifdef notdef +static int TIFFWriteDirectoryTagLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value); +#endif +static int TIFFWriteDirectoryTagLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value); +#ifdef notdef +static int TIFFWriteDirectoryTagSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value); +#endif +static int TIFFWriteDirectoryTagSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value); +static int TIFFWriteDirectoryTagRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value); +static int TIFFWriteDirectoryTagRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value); +static int TIFFWriteDirectoryTagSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value); +#ifdef notdef +static int TIFFWriteDirectoryTagFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value); +#endif +static int TIFFWriteDirectoryTagFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value); +#if 0 +static int TIFFWriteDirectoryTagFloatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value); +#endif +#ifdef notdef +static int TIFFWriteDirectoryTagDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value); +#endif +static int TIFFWriteDirectoryTagDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value); +#if 0 +static int TIFFWriteDirectoryTagDoublePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value); +#endif +static int TIFFWriteDirectoryTagIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value); +#ifdef notdef +static int TIFFWriteDirectoryTagIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value); +#endif +static int TIFFWriteDirectoryTagShortLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value); +static int TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value); +static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value); +#ifdef notdef +static int TIFFWriteDirectoryTagShortLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value); +#endif +static int TIFFWriteDirectoryTagColormap(TIFF* tif, uint32* ndir, TIFFDirEntry* dir); +static int TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32* ndir, TIFFDirEntry* dir); +static int TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32* ndir, TIFFDirEntry* dir); + +static int TIFFWriteDirectoryTagCheckedAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value); +static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value); +#ifdef notdef +static int TIFFWriteDirectoryTagCheckedByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value); +#endif +static int TIFFWriteDirectoryTagCheckedByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value); +#ifdef notdef +static int TIFFWriteDirectoryTagCheckedSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value); +#endif +static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value); +static int TIFFWriteDirectoryTagCheckedShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value); +static int TIFFWriteDirectoryTagCheckedShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value); +#ifdef notdef +static int TIFFWriteDirectoryTagCheckedSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value); +#endif +static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value); +static int TIFFWriteDirectoryTagCheckedLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value); +static int TIFFWriteDirectoryTagCheckedLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value); +#ifdef notdef +static int TIFFWriteDirectoryTagCheckedSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value); +#endif +static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value); +#ifdef notdef +static int TIFFWriteDirectoryTagCheckedLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value); +#endif +static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value); +#ifdef notdef +static int TIFFWriteDirectoryTagCheckedSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value); +#endif +static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value); +static int TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value); +static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value); +static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value); +#ifdef notdef +static int TIFFWriteDirectoryTagCheckedFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value); +#endif +static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value); +#ifdef notdef +static int TIFFWriteDirectoryTagCheckedDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value); +#endif +static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value); +static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value); +static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value); + +static int TIFFWriteDirectoryTagData(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 datatype, uint32 count, uint32 datalength, void* data); + +static int TIFFLinkDirectory(TIFF*); /* * Write the contents of the current directory @@ -77,343 +177,10 @@ static int TIFFLinkDirectory(TIFF*); * handle overwriting a directory with auxiliary * storage that's been changed. */ -static int -_TIFFWriteDirectory(TIFF* tif, int done) -{ - uint16 dircount; - toff_t diroff; - ttag_t tag; - uint32 nfields; - tsize_t dirsize; - char* data; - TIFFDirEntry* dir; - TIFFDirectory* td; - unsigned long b, fields[FIELD_SETLONGS]; - int fi, nfi; - - if (tif->tif_mode == O_RDONLY) - return (1); - /* - * Clear write state so that subsequent images with - * different characteristics get the right buffers - * setup for them. - */ - if (done) - { - if (tif->tif_flags & TIFF_POSTENCODE) { - tif->tif_flags &= ~TIFF_POSTENCODE; - if (!(*tif->tif_postencode)(tif)) { - TIFFErrorExt(tif->tif_clientdata, - tif->tif_name, - "Error post-encoding before directory write"); - return (0); - } - } - (*tif->tif_close)(tif); /* shutdown encoder */ - /* - * Flush any data that might have been written - * by the compression close+cleanup routines. - */ - if (tif->tif_rawcc > 0 - && (tif->tif_flags & TIFF_BEENWRITING) != 0 - && !TIFFFlushData1(tif)) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Error flushing data before directory write"); - return (0); - } - if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) { - _TIFFfree(tif->tif_rawdata); - tif->tif_rawdata = NULL; - tif->tif_rawcc = 0; - tif->tif_rawdatasize = 0; - } - tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP); - } - - td = &tif->tif_dir; - /* - * Size the directory so that we can calculate - * offsets for the data items that aren't kept - * in-place in each field. - */ - nfields = 0; - for (b = 0; b <= FIELD_LAST; b++) - if (TIFFFieldSet(tif, b) && b != FIELD_CUSTOM) - nfields += (b < FIELD_SUBFILETYPE ? 2 : 1); - nfields += td->td_customValueCount; - dirsize = nfields * sizeof (TIFFDirEntry); - data = (char*) _TIFFmalloc(dirsize); - if (data == NULL) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Cannot write directory, out of space"); - return (0); - } - /* - * Directory hasn't been placed yet, put - * it at the end of the file and link it - * into the existing directory structure. - */ - if (tif->tif_diroff == 0 && !TIFFLinkDirectory(tif)) - goto bad; - tif->tif_dataoff = (toff_t)( - tif->tif_diroff + sizeof (uint16) + dirsize + sizeof (toff_t)); - if (tif->tif_dataoff & 1) - tif->tif_dataoff++; - (void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET); - tif->tif_curdir++; - dir = (TIFFDirEntry*) data; - /* - * Setup external form of directory - * entries and write data items. - */ - _TIFFmemcpy(fields, td->td_fieldsset, sizeof (fields)); - /* - * Write out ExtraSamples tag only if - * extra samples are present in the data. - */ - if (FieldSet(fields, FIELD_EXTRASAMPLES) && !td->td_extrasamples) { - ResetFieldBit(fields, FIELD_EXTRASAMPLES); - nfields--; - dirsize -= sizeof (TIFFDirEntry); - } /*XXX*/ - for (fi = 0, nfi = tif->tif_nfields; nfi > 0; nfi--, fi++) { - const TIFFFieldInfo* fip = tif->tif_fieldinfo[fi]; - - /* - * For custom fields, we test to see if the custom field - * is set or not. For normal fields, we just use the - * FieldSet test. - */ - if( fip->field_bit == FIELD_CUSTOM ) - { - int ci, is_set = FALSE; - - for( ci = 0; ci < td->td_customValueCount; ci++ ) - is_set |= (td->td_customValues[ci].info == fip); - - if( !is_set ) - continue; - } - else if (!FieldSet(fields, fip->field_bit)) - continue; - - /* - * Handle other fields. - */ - switch (fip->field_bit) - { - case FIELD_STRIPOFFSETS: - /* - * We use one field bit for both strip and tile - - * offsets, and so must be careful in selecting - * the appropriate field descriptor (so that tags - * are written in sorted order). - */ - tag = isTiled(tif) ? - TIFFTAG_TILEOFFSETS : TIFFTAG_STRIPOFFSETS; - if (tag != fip->field_tag) - continue; - - dir->tdir_tag = (uint16) tag; - dir->tdir_type = (uint16) TIFF_LONG; - dir->tdir_count = (uint32) td->td_nstrips; - if (!TIFFWriteLongArray(tif, dir, td->td_stripoffset)) - goto bad; - break; - case FIELD_STRIPBYTECOUNTS: - /* - * We use one field bit for both strip and tile - * byte counts, and so must be careful in selecting - * the appropriate field descriptor (so that tags - * are written in sorted order). - */ - tag = isTiled(tif) ? - TIFFTAG_TILEBYTECOUNTS : TIFFTAG_STRIPBYTECOUNTS; - if (tag != fip->field_tag) - continue; - - dir->tdir_tag = (uint16) tag; - dir->tdir_type = (uint16) TIFF_LONG; - dir->tdir_count = (uint32) td->td_nstrips; - if (!TIFFWriteLongArray(tif, dir, td->td_stripbytecount)) - goto bad; - break; - case FIELD_ROWSPERSTRIP: - TIFFSetupShortLong(tif, TIFFTAG_ROWSPERSTRIP, - dir, td->td_rowsperstrip); - break; - case FIELD_COLORMAP: - if (!TIFFWriteShortTable(tif, TIFFTAG_COLORMAP, dir, - 3, td->td_colormap)) - goto bad; - break; - case FIELD_IMAGEDIMENSIONS: - TIFFSetupShortLong(tif, TIFFTAG_IMAGEWIDTH, - dir++, td->td_imagewidth); - TIFFSetupShortLong(tif, TIFFTAG_IMAGELENGTH, - dir, td->td_imagelength); - break; - case FIELD_TILEDIMENSIONS: - TIFFSetupShortLong(tif, TIFFTAG_TILEWIDTH, - dir++, td->td_tilewidth); - TIFFSetupShortLong(tif, TIFFTAG_TILELENGTH, - dir, td->td_tilelength); - break; - case FIELD_COMPRESSION: - TIFFSetupShort(tif, TIFFTAG_COMPRESSION, - dir, td->td_compression); - break; - case FIELD_PHOTOMETRIC: - TIFFSetupShort(tif, TIFFTAG_PHOTOMETRIC, - dir, td->td_photometric); - break; - case FIELD_POSITION: - WriteRationalPair(TIFF_RATIONAL, - TIFFTAG_XPOSITION, td->td_xposition, - TIFFTAG_YPOSITION, td->td_yposition); - break; - case FIELD_RESOLUTION: - WriteRationalPair(TIFF_RATIONAL, - TIFFTAG_XRESOLUTION, td->td_xresolution, - TIFFTAG_YRESOLUTION, td->td_yresolution); - break; - case FIELD_BITSPERSAMPLE: - case FIELD_MINSAMPLEVALUE: - case FIELD_MAXSAMPLEVALUE: - case FIELD_SAMPLEFORMAT: - if (!TIFFWritePerSampleShorts(tif, fip->field_tag, dir)) - goto bad; - break; - case FIELD_SMINSAMPLEVALUE: - case FIELD_SMAXSAMPLEVALUE: - if (!TIFFWritePerSampleAnys(tif, - _TIFFSampleToTagType(tif), fip->field_tag, dir)) - goto bad; - break; - case FIELD_PAGENUMBER: - case FIELD_HALFTONEHINTS: - case FIELD_YCBCRSUBSAMPLING: - if (!TIFFSetupShortPair(tif, fip->field_tag, dir)) - goto bad; - break; - case FIELD_INKNAMES: - if (!TIFFWriteInkNames(tif, dir)) - goto bad; - break; - case FIELD_TRANSFERFUNCTION: - if (!TIFFWriteTransferFunction(tif, dir)) - goto bad; - break; - case FIELD_SUBIFD: - /* - * XXX: Always write this field using LONG type - * for backward compatibility. - */ - dir->tdir_tag = (uint16) fip->field_tag; - dir->tdir_type = (uint16) TIFF_LONG; - dir->tdir_count = (uint32) td->td_nsubifd; - if (!TIFFWriteLongArray(tif, dir, td->td_subifd)) - goto bad; - /* - * Total hack: if this directory includes a SubIFD - * tag then force the next directories to be - * written as ``sub directories'' of this one. This - * is used to write things like thumbnails and - * image masks that one wants to keep out of the - * normal directory linkage access mechanism. - */ - if (dir->tdir_count > 0) { - tif->tif_flags |= TIFF_INSUBIFD; - tif->tif_nsubifd = (uint16) dir->tdir_count; - if (dir->tdir_count > 1) - tif->tif_subifdoff = dir->tdir_offset; - else - tif->tif_subifdoff = (uint32)( - tif->tif_diroff - + sizeof (uint16) - + ((char*)&dir->tdir_offset-data)); - } - break; - default: - /* XXX: Should be fixed and removed. */ - if (fip->field_tag == TIFFTAG_DOTRANGE) { - if (!TIFFSetupShortPair(tif, fip->field_tag, dir)) - goto bad; - } - else if (!TIFFWriteNormalTag(tif, dir, fip)) - goto bad; - break; - } - dir++; - - if( fip->field_bit != FIELD_CUSTOM ) - ResetFieldBit(fields, fip->field_bit); - } - - /* - * Write directory. - */ - dircount = (uint16) nfields; - diroff = (uint32) tif->tif_nextdiroff; - if (tif->tif_flags & TIFF_SWAB) { - /* - * The file's byte order is opposite to the - * native machine architecture. We overwrite - * the directory information with impunity - * because it'll be released below after we - * write it to the file. Note that all the - * other tag construction routines assume that - * we do this byte-swapping; i.e. they only - * byte-swap indirect data. - */ - for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) { - TIFFSwabArrayOfShort(&dir->tdir_tag, 2); - TIFFSwabArrayOfLong(&dir->tdir_count, 2); - } - dircount = (uint16) nfields; - TIFFSwabShort(&dircount); - TIFFSwabLong(&diroff); - } - (void) TIFFSeekFile(tif, tif->tif_diroff, SEEK_SET); - if (!WriteOK(tif, &dircount, sizeof (dircount))) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Error writing directory count"); - goto bad; - } - if (!WriteOK(tif, data, dirsize)) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Error writing directory contents"); - goto bad; - } - if (!WriteOK(tif, &diroff, sizeof (uint32))) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Error writing directory link"); - goto bad; - } - if (done) { - TIFFFreeDirectory(tif); - tif->tif_flags &= ~TIFF_DIRTYDIRECT; - (*tif->tif_cleanup)(tif); - - /* - * Reset directory-related state for subsequent - * directories. - */ - TIFFCreateDirectory(tif); - } - _TIFFfree(data); - return (1); -bad: - _TIFFfree(data); - return (0); -} -#undef WriteRationalPair - int TIFFWriteDirectory(TIFF* tif) { - return _TIFFWriteDirectory(tif, TRUE); + return TIFFWriteDirectorySec(tif,TRUE,TRUE,NULL); } /* @@ -421,7 +188,7 @@ TIFFWriteDirectory(TIFF* tif) * but leaves all data structures in memory so that it can be * written again. This will make a partially written TIFF file * readable before it is successfully completed/closed. - */ + */ int TIFFCheckpointDirectory(TIFF* tif) { @@ -429,892 +196,2169 @@ TIFFCheckpointDirectory(TIFF* tif) /* Setup the strips arrays, if they haven't already been. */ if (tif->tif_dir.td_stripoffset == NULL) (void) TIFFSetupStrips(tif); - rc = _TIFFWriteDirectory(tif, FALSE); + rc = TIFFWriteDirectorySec(tif,TRUE,FALSE,NULL); (void) TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END)); return rc; } -static int -_TIFFWriteCustomDirectory(TIFF* tif, toff_t *pdiroff) +int +TIFFWriteCustomDirectory(TIFF* tif, uint64* pdiroff) { - uint16 dircount; - uint32 nfields; - tsize_t dirsize; - char* data; - TIFFDirEntry* dir; - TIFFDirectory* td; - unsigned long b, fields[FIELD_SETLONGS]; - int fi, nfi; + return TIFFWriteDirectorySec(tif,FALSE,FALSE,pdiroff); +} +/* + * Similar to TIFFWriteDirectory(), but if the directory has already + * been written once, it is relocated to the end of the file, in case it + * has changed in size. Note that this will result in the loss of the + * previously used directory space. + */ +int +TIFFRewriteDirectory( TIFF *tif ) +{ + static const char module[] = "TIFFRewriteDirectory"; + + /* We don't need to do anything special if it hasn't been written. */ + if( tif->tif_diroff == 0 ) + return TIFFWriteDirectory( tif ); + + /* + * Find and zero the pointer to this directory, so that TIFFLinkDirectory + * will cause it to be added after this directories current pre-link. + */ + + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + if (tif->tif_header.classic.tiff_diroff == tif->tif_diroff) + { + tif->tif_header.classic.tiff_diroff = 0; + tif->tif_diroff = 0; + + TIFFSeekFile(tif,4,SEEK_SET); + if (!WriteOK(tif, &(tif->tif_header.classic.tiff_diroff),4)) + { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "Error updating TIFF header"); + return (0); + } + } + else + { + uint32 nextdir; + nextdir = tif->tif_header.classic.tiff_diroff; + while(1) { + uint16 dircount; + uint32 nextnextdir; + + if (!SeekOK(tif, nextdir) || + !ReadOK(tif, &dircount, 2)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error fetching directory count"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount); + (void) TIFFSeekFile(tif, + nextdir+2+dircount*12, SEEK_SET); + if (!ReadOK(tif, &nextnextdir, 4)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error fetching directory link"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextnextdir); + if (nextnextdir==tif->tif_diroff) + { + uint32 m; + m=0; + (void) TIFFSeekFile(tif, + nextdir+2+dircount*12, SEEK_SET); + if (!WriteOK(tif, &m, 4)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error writing directory link"); + return (0); + } + tif->tif_diroff=0; + break; + } + nextdir=nextnextdir; + } + } + } + else + { + if (tif->tif_header.big.tiff_diroff == tif->tif_diroff) + { + tif->tif_header.big.tiff_diroff = 0; + tif->tif_diroff = 0; + + TIFFSeekFile(tif,8,SEEK_SET); + if (!WriteOK(tif, &(tif->tif_header.big.tiff_diroff),8)) + { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "Error updating TIFF header"); + return (0); + } + } + else + { + uint64 nextdir; + nextdir = tif->tif_header.big.tiff_diroff; + while(1) { + uint64 dircount64; + uint16 dircount; + uint64 nextnextdir; + + if (!SeekOK(tif, nextdir) || + !ReadOK(tif, &dircount64, 8)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error fetching directory count"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&dircount64); + if (dircount64>0xFFFF) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Sanity check on tag count failed, likely corrupt TIFF"); + return (0); + } + dircount=(uint16)dircount64; + (void) TIFFSeekFile(tif, + nextdir+8+dircount*20, SEEK_SET); + if (!ReadOK(tif, &nextnextdir, 8)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error fetching directory link"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&nextnextdir); + if (nextnextdir==tif->tif_diroff) + { + uint64 m; + m=0; + (void) TIFFSeekFile(tif, + nextdir+8+dircount*20, SEEK_SET); + if (!WriteOK(tif, &m, 8)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error writing directory link"); + return (0); + } + tif->tif_diroff=0; + break; + } + nextdir=nextnextdir; + } + } + } + + /* + * Now use TIFFWriteDirectory() normally. + */ + + return TIFFWriteDirectory( tif ); +} + +static int +TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff) +{ + static const char module[] = "TIFFWriteDirectorySec"; + uint32 ndir; + TIFFDirEntry* dir; + uint32 dirsize; + void* dirmem; + uint32 m; if (tif->tif_mode == O_RDONLY) return (1); - td = &tif->tif_dir; + _TIFFFillStriles( tif ); + /* - * Size the directory so that we can calculate - * offsets for the data items that aren't kept - * in-place in each field. + * Clear write state so that subsequent images with + * different characteristics get the right buffers + * setup for them. */ - nfields = 0; - for (b = 0; b <= FIELD_LAST; b++) - if (TIFFFieldSet(tif, b) && b != FIELD_CUSTOM) - nfields += (b < FIELD_SUBFILETYPE ? 2 : 1); - nfields += td->td_customValueCount; - dirsize = nfields * sizeof (TIFFDirEntry); - data = (char*) _TIFFmalloc(dirsize); - if (data == NULL) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Cannot write directory, out of space"); - return (0); - } - /* - * Put the directory at the end of the file. - */ - tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1; - tif->tif_dataoff = (toff_t)( - tif->tif_diroff + sizeof (uint16) + dirsize + sizeof (toff_t)); - if (tif->tif_dataoff & 1) - tif->tif_dataoff++; - (void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET); - dir = (TIFFDirEntry*) data; - /* - * Setup external form of directory - * entries and write data items. - */ - _TIFFmemcpy(fields, td->td_fieldsset, sizeof (fields)); - - for (fi = 0, nfi = tif->tif_nfields; nfi > 0; nfi--, fi++) { - const TIFFFieldInfo* fip = tif->tif_fieldinfo[fi]; - - /* - * For custom fields, we test to see if the custom field - * is set or not. For normal fields, we just use the - * FieldSet test. - */ - if( fip->field_bit == FIELD_CUSTOM ) + if (imagedone) + { + if (tif->tif_flags & TIFF_POSTENCODE) { - int ci, is_set = FALSE; - - for( ci = 0; ci < td->td_customValueCount; ci++ ) - is_set |= (td->td_customValues[ci].info == fip); - - if( !is_set ) - continue; + tif->tif_flags &= ~TIFF_POSTENCODE; + if (!(*tif->tif_postencode)(tif)) + { + TIFFErrorExt(tif->tif_clientdata,module, + "Error post-encoding before directory write"); + return (0); + } } - else if (!FieldSet(fields, fip->field_bit)) - continue; - - if( fip->field_bit != FIELD_CUSTOM ) - ResetFieldBit(fields, fip->field_bit); - } - - /* - * Write directory. - */ - dircount = (uint16) nfields; - *pdiroff = (uint32) tif->tif_nextdiroff; - if (tif->tif_flags & TIFF_SWAB) { + (*tif->tif_close)(tif); /* shutdown encoder */ /* - * The file's byte order is opposite to the - * native machine architecture. We overwrite - * the directory information with impunity - * because it'll be released below after we - * write it to the file. Note that all the - * other tag construction routines assume that - * we do this byte-swapping; i.e. they only - * byte-swap indirect data. + * Flush any data that might have been written + * by the compression close+cleanup routines. But + * be careful not to write stuff if we didn't add data + * in the previous steps as the "rawcc" data may well be + * a previously read tile/strip in mixed read/write mode. */ - for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) { - TIFFSwabArrayOfShort(&dir->tdir_tag, 2); - TIFFSwabArrayOfLong(&dir->tdir_count, 2); - } - dircount = (uint16) nfields; - TIFFSwabShort(&dircount); - TIFFSwabLong(pdiroff); - } - (void) TIFFSeekFile(tif, tif->tif_diroff, SEEK_SET); - if (!WriteOK(tif, &dircount, sizeof (dircount))) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Error writing directory count"); - goto bad; - } - if (!WriteOK(tif, data, dirsize)) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Error writing directory contents"); - goto bad; - } - if (!WriteOK(tif, pdiroff, sizeof (uint32))) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Error writing directory link"); - goto bad; - } - _TIFFfree(data); - return (1); -bad: - _TIFFfree(data); - return (0); -} - -int -TIFFWriteCustomDirectory(TIFF* tif, toff_t *pdiroff) -{ - return _TIFFWriteCustomDirectory(tif, pdiroff); -} - -/* - * Process tags that are not special cased. - */ -static int -TIFFWriteNormalTag(TIFF* tif, TIFFDirEntry* dir, const TIFFFieldInfo* fip) -{ - uint16 wc = (uint16) fip->field_writecount; - uint32 wc2; - - dir->tdir_tag = (uint16) fip->field_tag; - dir->tdir_type = (uint16) fip->field_type; - dir->tdir_count = wc; - - switch (fip->field_type) { - case TIFF_SHORT: - case TIFF_SSHORT: - if (fip->field_passcount) { - uint16* wp; - if (wc == (uint16) TIFF_VARIABLE2) { - TIFFGetField(tif, fip->field_tag, &wc2, &wp); - dir->tdir_count = wc2; - } else { /* Assume TIFF_VARIABLE */ - TIFFGetField(tif, fip->field_tag, &wc, &wp); - dir->tdir_count = wc; - } - if (!TIFFWriteShortArray(tif, dir, wp)) - return 0; - } else { - if (wc == 1) { - uint16 sv; - TIFFGetField(tif, fip->field_tag, &sv); - dir->tdir_offset = - TIFFInsertData(tif, dir->tdir_type, sv); - } else { - uint16* wp; - TIFFGetField(tif, fip->field_tag, &wp); - if (!TIFFWriteShortArray(tif, dir, wp)) - return 0; - } - } - break; - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_IFD: - if (fip->field_passcount) { - uint32* lp; - if (wc == (uint16) TIFF_VARIABLE2) { - TIFFGetField(tif, fip->field_tag, &wc2, &lp); - dir->tdir_count = wc2; - } else { /* Assume TIFF_VARIABLE */ - TIFFGetField(tif, fip->field_tag, &wc, &lp); - dir->tdir_count = wc; - } - if (!TIFFWriteLongArray(tif, dir, lp)) - return 0; - } else { - if (wc == 1) { - /* XXX handle LONG->SHORT conversion */ - TIFFGetField(tif, fip->field_tag, - &dir->tdir_offset); - } else { - uint32* lp; - TIFFGetField(tif, fip->field_tag, &lp); - if (!TIFFWriteLongArray(tif, dir, lp)) - return 0; - } - } - break; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - if (fip->field_passcount) { - float* fp; - if (wc == (uint16) TIFF_VARIABLE2) { - TIFFGetField(tif, fip->field_tag, &wc2, &fp); - dir->tdir_count = wc2; - } else { /* Assume TIFF_VARIABLE */ - TIFFGetField(tif, fip->field_tag, &wc, &fp); - dir->tdir_count = wc; - } - if (!TIFFWriteRationalArray(tif, dir, fp)) - return 0; - } else { - if (wc == 1) { - float fv; - TIFFGetField(tif, fip->field_tag, &fv); - if (!TIFFWriteRationalArray(tif, dir, &fv)) - return 0; - } else { - float* fp; - TIFFGetField(tif, fip->field_tag, &fp); - if (!TIFFWriteRationalArray(tif, dir, fp)) - return 0; - } - } - break; - case TIFF_FLOAT: - if (fip->field_passcount) { - float* fp; - if (wc == (uint16) TIFF_VARIABLE2) { - TIFFGetField(tif, fip->field_tag, &wc2, &fp); - dir->tdir_count = wc2; - } else { /* Assume TIFF_VARIABLE */ - TIFFGetField(tif, fip->field_tag, &wc, &fp); - dir->tdir_count = wc; - } - if (!TIFFWriteFloatArray(tif, dir, fp)) - return 0; - } else { - if (wc == 1) { - float fv; - TIFFGetField(tif, fip->field_tag, &fv); - if (!TIFFWriteFloatArray(tif, dir, &fv)) - return 0; - } else { - float* fp; - TIFFGetField(tif, fip->field_tag, &fp); - if (!TIFFWriteFloatArray(tif, dir, fp)) - return 0; - } - } - break; - case TIFF_DOUBLE: - if (fip->field_passcount) { - double* dp; - if (wc == (uint16) TIFF_VARIABLE2) { - TIFFGetField(tif, fip->field_tag, &wc2, &dp); - dir->tdir_count = wc2; - } else { /* Assume TIFF_VARIABLE */ - TIFFGetField(tif, fip->field_tag, &wc, &dp); - dir->tdir_count = wc; - } - if (!TIFFWriteDoubleArray(tif, dir, dp)) - return 0; - } else { - if (wc == 1) { - double dv; - TIFFGetField(tif, fip->field_tag, &dv); - if (!TIFFWriteDoubleArray(tif, dir, &dv)) - return 0; - } else { - double* dp; - TIFFGetField(tif, fip->field_tag, &dp); - if (!TIFFWriteDoubleArray(tif, dir, dp)) - return 0; - } - } - break; - case TIFF_ASCII: - { - char* cp; - if (fip->field_passcount) + if (tif->tif_rawcc > 0 + && (tif->tif_flags & TIFF_BEENWRITING) != 0 ) + { + if( !TIFFFlushData1(tif) ) { - if( wc == (uint16) TIFF_VARIABLE2 ) - TIFFGetField(tif, fip->field_tag, &wc2, &cp); - else - TIFFGetField(tif, fip->field_tag, &wc, &cp); + TIFFErrorExt(tif->tif_clientdata, module, + "Error flushing data before directory write"); + return (0); } - else - TIFFGetField(tif, fip->field_tag, &cp); - - dir->tdir_count = (uint32) (strlen(cp) + 1); - if (!TIFFWriteByteArray(tif, dir, cp)) - return (0); } - break; - - case TIFF_BYTE: - case TIFF_SBYTE: - if (fip->field_passcount) { - char* cp; - if (wc == (uint16) TIFF_VARIABLE2) { - TIFFGetField(tif, fip->field_tag, &wc2, &cp); - dir->tdir_count = wc2; - } else { /* Assume TIFF_VARIABLE */ - TIFFGetField(tif, fip->field_tag, &wc, &cp); - dir->tdir_count = wc; + if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) + { + _TIFFfree(tif->tif_rawdata); + tif->tif_rawdata = NULL; + tif->tif_rawcc = 0; + tif->tif_rawdatasize = 0; + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = 0; + } + tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP); + } + dir=NULL; + dirmem=NULL; + dirsize=0; + while (1) + { + ndir=0; + if (isimage) + { + if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS)) + { + if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_IMAGEWIDTH,tif->tif_dir.td_imagewidth)) + goto bad; + if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_IMAGELENGTH,tif->tif_dir.td_imagelength)) + goto bad; } - if (!TIFFWriteByteArray(tif, dir, cp)) - return 0; - } else { - if (wc == 1) { - char cv; - TIFFGetField(tif, fip->field_tag, &cv); - if (!TIFFWriteByteArray(tif, dir, &cv)) - return 0; - } else { - char* cp; - TIFFGetField(tif, fip->field_tag, &cp); - if (!TIFFWriteByteArray(tif, dir, cp)) - return 0; + if (TIFFFieldSet(tif,FIELD_TILEDIMENSIONS)) + { + if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_TILEWIDTH,tif->tif_dir.td_tilewidth)) + goto bad; + if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_TILELENGTH,tif->tif_dir.td_tilelength)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_RESOLUTION)) + { + if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_XRESOLUTION,tif->tif_dir.td_xresolution)) + goto bad; + if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_YRESOLUTION,tif->tif_dir.td_yresolution)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_POSITION)) + { + if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_XPOSITION,tif->tif_dir.td_xposition)) + goto bad; + if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_YPOSITION,tif->tif_dir.td_yposition)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_SUBFILETYPE)) + { + if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_SUBFILETYPE,tif->tif_dir.td_subfiletype)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_BITSPERSAMPLE)) + { + if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_BITSPERSAMPLE,tif->tif_dir.td_bitspersample)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_COMPRESSION)) + { + if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_COMPRESSION,tif->tif_dir.td_compression)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_PHOTOMETRIC)) + { + if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_PHOTOMETRIC,tif->tif_dir.td_photometric)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_THRESHHOLDING)) + { + if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_THRESHHOLDING,tif->tif_dir.td_threshholding)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_FILLORDER)) + { + if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_FILLORDER,tif->tif_dir.td_fillorder)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_ORIENTATION)) + { + if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_ORIENTATION,tif->tif_dir.td_orientation)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL)) + { + if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_SAMPLESPERPIXEL,tif->tif_dir.td_samplesperpixel)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_ROWSPERSTRIP)) + { + if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_ROWSPERSTRIP,tif->tif_dir.td_rowsperstrip)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_MINSAMPLEVALUE)) + { + if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_MINSAMPLEVALUE,tif->tif_dir.td_minsamplevalue)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE)) + { + if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_MAXSAMPLEVALUE,tif->tif_dir.td_maxsamplevalue)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_PLANARCONFIG)) + { + if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_PLANARCONFIG,tif->tif_dir.td_planarconfig)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_RESOLUTIONUNIT)) + { + if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_RESOLUTIONUNIT,tif->tif_dir.td_resolutionunit)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_PAGENUMBER)) + { + if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_PAGENUMBER,2,&tif->tif_dir.td_pagenumber[0])) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_STRIPBYTECOUNTS)) + { + if (!isTiled(tif)) + { + if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount)) + goto bad; + } + else + { + if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount)) + goto bad; + } + } + if (TIFFFieldSet(tif,FIELD_STRIPOFFSETS)) + { + if (!isTiled(tif)) + { + if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset)) + goto bad; + } + else + { + if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset)) + goto bad; + } + } + if (TIFFFieldSet(tif,FIELD_COLORMAP)) + { + if (!TIFFWriteDirectoryTagColormap(tif,&ndir,dir)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_EXTRASAMPLES)) + { + if (tif->tif_dir.td_extrasamples) + { + uint16 na; + uint16* nb; + TIFFGetFieldDefaulted(tif,TIFFTAG_EXTRASAMPLES,&na,&nb); + if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_EXTRASAMPLES,na,nb)) + goto bad; + } + } + if (TIFFFieldSet(tif,FIELD_SAMPLEFORMAT)) + { + if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_SAMPLEFORMAT,tif->tif_dir.td_sampleformat)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE)) + { + if (!TIFFWriteDirectoryTagSampleformatArray(tif,&ndir,dir,TIFFTAG_SMINSAMPLEVALUE,tif->tif_dir.td_samplesperpixel,tif->tif_dir.td_sminsamplevalue)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE)) + { + if (!TIFFWriteDirectoryTagSampleformatArray(tif,&ndir,dir,TIFFTAG_SMAXSAMPLEVALUE,tif->tif_dir.td_samplesperpixel,tif->tif_dir.td_smaxsamplevalue)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_IMAGEDEPTH)) + { + if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_IMAGEDEPTH,tif->tif_dir.td_imagedepth)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_TILEDEPTH)) + { + if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_TILEDEPTH,tif->tif_dir.td_tiledepth)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_HALFTONEHINTS)) + { + if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_HALFTONEHINTS,2,&tif->tif_dir.td_halftonehints[0])) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING)) + { + if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_YCBCRSUBSAMPLING,2,&tif->tif_dir.td_ycbcrsubsampling[0])) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING)) + { + if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_YCBCRPOSITIONING,tif->tif_dir.td_ycbcrpositioning)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_REFBLACKWHITE)) + { + if (!TIFFWriteDirectoryTagRationalArray(tif,&ndir,dir,TIFFTAG_REFERENCEBLACKWHITE,6,tif->tif_dir.td_refblackwhite)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION)) + { + if (!TIFFWriteDirectoryTagTransferfunction(tif,&ndir,dir)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_INKNAMES)) + { + if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,TIFFTAG_INKNAMES,tif->tif_dir.td_inknameslen,tif->tif_dir.td_inknames)) + goto bad; + } + if (TIFFFieldSet(tif,FIELD_SUBIFD)) + { + if (!TIFFWriteDirectoryTagSubifd(tif,&ndir,dir)) + goto bad; + } + { + uint32 n; + for (n=0; ntif_nfields; n++) { + const TIFFField* o; + o = tif->tif_fields[n]; + if ((o->field_bit>=FIELD_CODEC)&&(TIFFFieldSet(tif,o->field_bit))) + { + switch (o->get_field_type) + { + case TIFF_SETGET_ASCII: + { + uint32 pa; + char* pb; + assert(o->field_type==TIFF_ASCII); + assert(o->field_readcount==TIFF_VARIABLE); + 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)) + goto bad; + } + break; + case TIFF_SETGET_UINT16: + { + uint16 p; + assert(o->field_type==TIFF_SHORT); + 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)) + goto bad; + } + break; + case TIFF_SETGET_UINT32: + { + uint32 p; + assert(o->field_type==TIFF_LONG); + 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)) + goto bad; + } + break; + case TIFF_SETGET_C32_UINT8: + { + uint32 pa; + void* pb; + assert(o->field_type==TIFF_UNDEFINED); + 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)) + goto bad; + } + break; + default: + assert(0); /* we should never get here */ + break; + } + } + } } } - break; - - case TIFF_UNDEFINED: - { char* cp; - if (wc == (unsigned short) TIFF_VARIABLE) { - TIFFGetField(tif, fip->field_tag, &wc, &cp); - dir->tdir_count = wc; - } else if (wc == (unsigned short) TIFF_VARIABLE2) { - TIFFGetField(tif, fip->field_tag, &wc2, &cp); - dir->tdir_count = wc2; - } else - TIFFGetField(tif, fip->field_tag, &cp); - if (!TIFFWriteByteArray(tif, dir, cp)) - return (0); + for (m=0; m<(uint32)(tif->tif_dir.td_customValueCount); m++) + { + 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)) + 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)) + 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)) + 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)) + 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)) + 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)) + 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)) + 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)) + 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)) + 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)) + 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)) + 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)) + 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)) + 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)) + 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)) + 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)) + goto bad; + break; + default: + assert(0); /* we should never get here */ + break; + } } - break; - - case TIFF_NOTYPE: - break; + if (dir!=NULL) + break; + dir=_TIFFmalloc(ndir*sizeof(TIFFDirEntry)); + if (dir==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + goto bad; + } + if (isimage) + { + if ((tif->tif_diroff==0)&&(!TIFFLinkDirectory(tif))) + goto bad; + } + else + tif->tif_diroff=(TIFFSeekFile(tif,0,SEEK_END)+1)&(~1); + if (pdiroff!=NULL) + *pdiroff=tif->tif_diroff; + if (!(tif->tif_flags&TIFF_BIGTIFF)) + dirsize=2+ndir*12+4; + else + dirsize=8+ndir*20+8; + tif->tif_dataoff=tif->tif_diroff+dirsize; + if (!(tif->tif_flags&TIFF_BIGTIFF)) + tif->tif_dataoff=(uint32)tif->tif_dataoff; + if ((tif->tif_dataofftif_diroff)||(tif->tif_dataoff<(uint64)dirsize)) + { + TIFFErrorExt(tif->tif_clientdata,module,"Maximum TIFF file size exceeded"); + goto bad; + } + if (tif->tif_dataoff&1) + tif->tif_dataoff++; + if (isimage) + tif->tif_curdir++; } - return (1); -} - -/* - * Setup a directory entry with either a SHORT - * or LONG type according to the value. - */ -static void -TIFFSetupShortLong(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint32 v) -{ - dir->tdir_tag = (uint16) tag; - dir->tdir_count = 1; - if (v > 0xffffL) { - dir->tdir_type = (short) TIFF_LONG; - dir->tdir_offset = v; - } else { - dir->tdir_type = (short) TIFF_SHORT; - dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v); - } -} - -/* - * Setup a SHORT directory entry - */ -static void -TIFFSetupShort(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint16 v) -{ - dir->tdir_tag = (uint16) tag; - dir->tdir_count = 1; - dir->tdir_type = (short) TIFF_SHORT; - dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v); -} -#undef MakeShortDirent - -#define NITEMS(x) (sizeof (x) / sizeof (x[0])) -/* - * Setup a directory entry that references a - * samples/pixel array of SHORT values and - * (potentially) write the associated indirect - * values. - */ -static int -TIFFWritePerSampleShorts(TIFF* tif, ttag_t tag, TIFFDirEntry* dir) -{ - uint16 buf[10], v; - uint16* w = buf; - uint16 i, samples = tif->tif_dir.td_samplesperpixel; - int status; - - if (samples > NITEMS(buf)) { - w = (uint16*) _TIFFmalloc(samples * sizeof (uint16)); - if (w == NULL) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "No space to write per-sample shorts"); - return (0); + if (isimage) + { + if (TIFFFieldSet(tif,FIELD_SUBIFD)&&(tif->tif_subifdoff==0)) + { + uint32 na; + TIFFDirEntry* nb; + for (na=0, nb=dir; ; na++, nb++) + { + assert(natdir_tag==TIFFTAG_SUBIFD) + break; + } + if (!(tif->tif_flags&TIFF_BIGTIFF)) + tif->tif_subifdoff=tif->tif_diroff+2+na*12+8; + else + tif->tif_subifdoff=tif->tif_diroff+8+na*20+12; } } - TIFFGetField(tif, tag, &v); - for (i = 0; i < samples; i++) - w[i] = v; - - dir->tdir_tag = (uint16) tag; - dir->tdir_type = (uint16) TIFF_SHORT; - dir->tdir_count = samples; - status = TIFFWriteShortArray(tif, dir, w); - if (w != buf) - _TIFFfree((char*) w); - return (status); -} - -/* - * Setup a directory entry that references a samples/pixel array of ``type'' - * values and (potentially) write the associated indirect values. The source - * data from TIFFGetField() for the specified tag must be returned as double. - */ -static int -TIFFWritePerSampleAnys(TIFF* tif, - TIFFDataType type, ttag_t tag, TIFFDirEntry* dir) -{ - double buf[10], v; - double* w = buf; - uint16 i, samples = tif->tif_dir.td_samplesperpixel; - int status; - - if (samples > NITEMS(buf)) { - w = (double*) _TIFFmalloc(samples * sizeof (double)); - if (w == NULL) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "No space to write per-sample values"); - return (0); - } + dirmem=_TIFFmalloc(dirsize); + if (dirmem==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + goto bad; } - TIFFGetField(tif, tag, &v); - for (i = 0; i < samples; i++) - w[i] = v; - status = TIFFWriteAnyArray(tif, type, tag, dir, samples, w); - if (w != buf) - _TIFFfree(w); - return (status); -} -#undef NITEMS - -/* - * Setup a pair of shorts that are returned by - * value, rather than as a reference to an array. - */ -static int -TIFFSetupShortPair(TIFF* tif, ttag_t tag, TIFFDirEntry* dir) -{ - uint16 v[2]; - - TIFFGetField(tif, tag, &v[0], &v[1]); - - dir->tdir_tag = (uint16) tag; - dir->tdir_type = (uint16) TIFF_SHORT; - dir->tdir_count = 2; - return (TIFFWriteShortArray(tif, dir, v)); -} - -/* - * Setup a directory entry for an NxM table of shorts, - * where M is known to be 2**bitspersample, and write - * the associated indirect data. - */ -static int -TIFFWriteShortTable(TIFF* tif, - ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16** table) -{ - uint32 i, off; - - dir->tdir_tag = (uint16) tag; - dir->tdir_type = (short) TIFF_SHORT; - /* XXX -- yech, fool TIFFWriteData */ - dir->tdir_count = (uint32) (1L<tif_dir.td_bitspersample); - off = tif->tif_dataoff; - for (i = 0; i < n; i++) - if (!TIFFWriteData(tif, dir, (char *)table[i])) - return (0); - dir->tdir_count *= n; - dir->tdir_offset = off; - return (1); -} - -/* - * Write/copy data associated with an ASCII or opaque tag value. - */ -static int -TIFFWriteByteArray(TIFF* tif, TIFFDirEntry* dir, char* cp) -{ - if (dir->tdir_count <= 4) { - if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) { - dir->tdir_offset = (uint32)cp[0] << 24; - if (dir->tdir_count >= 2) - dir->tdir_offset |= (uint32)cp[1] << 16; - if (dir->tdir_count >= 3) - dir->tdir_offset |= (uint32)cp[2] << 8; - if (dir->tdir_count == 4) - dir->tdir_offset |= cp[3]; - } else { - dir->tdir_offset = cp[0]; - if (dir->tdir_count >= 2) - dir->tdir_offset |= (uint32) cp[1] << 8; - if (dir->tdir_count >= 3) - dir->tdir_offset |= (uint32) cp[2] << 16; - if (dir->tdir_count == 4) - dir->tdir_offset |= (uint32) cp[3] << 24; + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + uint8* n; + uint32 nTmp; + TIFFDirEntry* o; + n=dirmem; + *(uint16*)n=ndir; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)n); + n+=2; + o=dir; + for (m=0; mtdir_tag; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)n); + n+=2; + *(uint16*)n=o->tdir_type; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)n); + n+=2; + nTmp = (uint32)o->tdir_count; + _TIFFmemcpy(n,&nTmp,4); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)n); + n+=4; + /* This is correct. The data has been */ + /* swabbed previously in TIFFWriteDirectoryTagData */ + _TIFFmemcpy(n,&o->tdir_offset,4); + n+=4; + o++; } - return 1; - } else - return TIFFWriteData(tif, dir, cp); -} - -/* - * Setup a directory entry of an array of SHORT - * or SSHORT and write the associated indirect values. - */ -static int -TIFFWriteShortArray(TIFF* tif, TIFFDirEntry* dir, uint16* v) -{ - if (dir->tdir_count <= 2) { - if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) { - dir->tdir_offset = (uint32) v[0] << 16; - if (dir->tdir_count == 2) - dir->tdir_offset |= v[1] & 0xffff; - } else { - dir->tdir_offset = v[0] & 0xffff; - if (dir->tdir_count == 2) - dir->tdir_offset |= (uint32) v[1] << 16; + nTmp = (uint32)tif->tif_nextdiroff; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(&nTmp); + _TIFFmemcpy(n,&nTmp,4); + } + else + { + uint8* n; + TIFFDirEntry* o; + n=dirmem; + *(uint64*)n=ndir; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)n); + n+=8; + o=dir; + for (m=0; mtdir_tag; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)n); + n+=2; + *(uint16*)n=o->tdir_type; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)n); + n+=2; + _TIFFmemcpy(n,&o->tdir_count,8); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)n); + n+=8; + _TIFFmemcpy(n,&o->tdir_offset,8); + n+=8; + o++; } - return (1); - } else - return (TIFFWriteData(tif, dir, (char*) v)); + _TIFFmemcpy(n,&tif->tif_nextdiroff,8); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)n); + } + _TIFFfree(dir); + dir=NULL; + if (!SeekOK(tif,tif->tif_diroff)) + { + TIFFErrorExt(tif->tif_clientdata,module,"IO error writing directory"); + goto bad; + } + if (!WriteOK(tif,dirmem,(tmsize_t)dirsize)) + { + TIFFErrorExt(tif->tif_clientdata,module,"IO error writing directory"); + goto bad; + } + _TIFFfree(dirmem); + if (imagedone) + { + TIFFFreeDirectory(tif); + tif->tif_flags &= ~TIFF_DIRTYDIRECT; + tif->tif_flags &= ~TIFF_DIRTYSTRIP; + (*tif->tif_cleanup)(tif); + /* + * Reset directory-related state for subsequent + * directories. + */ + TIFFCreateDirectory(tif); + } + return(1); +bad: + if (dir!=NULL) + _TIFFfree(dir); + if (dirmem!=NULL) + _TIFFfree(dirmem); + return(0); } -/* - * Setup a directory entry of an array of LONG - * or SLONG and write the associated indirect values. - */ static int -TIFFWriteLongArray(TIFF* tif, TIFFDirEntry* dir, uint32* v) -{ - if (dir->tdir_count == 1) { - dir->tdir_offset = v[0]; - return (1); - } else - return (TIFFWriteData(tif, dir, (char*) v)); -} - -/* - * Setup a directory entry of an array of RATIONAL - * or SRATIONAL and write the associated indirect values. - */ -static int -TIFFWriteRationalArray(TIFF* tif, TIFFDirEntry* dir, float* v) +TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value) { + static const char module[] = "TIFFWriteDirectoryTagSampleformatArray"; + void* conv; uint32 i; - uint32* t; - int status; - - t = (uint32*) _TIFFmalloc(2 * dir->tdir_count * sizeof (uint32)); - if (t == NULL) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "No space to write RATIONAL array"); + int ok; + conv = _TIFFmalloc(count*sizeof(double)); + if (conv == NULL) + { + TIFFErrorExt(tif->tif_clientdata, module, "Out of memory"); return (0); } - for (i = 0; i < dir->tdir_count; i++) { - float fv = v[i]; - int sign = 1; - uint32 den; - if (fv < 0) { - if (dir->tdir_type == TIFF_RATIONAL) { - TIFFWarningExt(tif->tif_clientdata, - tif->tif_name, - "\"%s\": Information lost writing value (%g) as (unsigned) RATIONAL", - _TIFFFieldWithTag(tif,dir->tdir_tag)->field_name, - fv); - fv = 0; - } else - fv = -fv, sign = -1; - } - den = 1L; - if (fv > 0) { - while (fv < 1L<<(31-3) && den < 1L<<(31-3)) - fv *= 1<<3, den *= 1L<<3; - } - t[2*i+0] = (uint32) (sign * (fv + 0.5)); - t[2*i+1] = den; - } - status = TIFFWriteData(tif, dir, (char *)t); - _TIFFfree((char*) t); - return (status); -} - -static int -TIFFWriteFloatArray(TIFF* tif, TIFFDirEntry* dir, float* v) -{ - TIFFCvtNativeToIEEEFloat(tif, dir->tdir_count, v); - if (dir->tdir_count == 1) { - dir->tdir_offset = *(uint32*) &v[0]; - return (1); - } else - return (TIFFWriteData(tif, dir, (char*) v)); -} - -static int -TIFFWriteDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v) -{ - TIFFCvtNativeToIEEEDouble(tif, dir->tdir_count, v); - return (TIFFWriteData(tif, dir, (char*) v)); -} - -/* - * Write an array of ``type'' values for a specified tag (i.e. this is a tag - * which is allowed to have different types, e.g. SMaxSampleType). - * Internally the data values are represented as double since a double can - * hold any of the TIFF tag types (yes, this should really be an abstract - * type tany_t for portability). The data is converted into the specified - * type in a temporary buffer and then handed off to the appropriate array - * writer. - */ -static int -TIFFWriteAnyArray(TIFF* tif, - TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v) -{ - char buf[10 * sizeof(double)]; - char* w = buf; - int i, status = 0; - - if (n * TIFFDataWidth(type) > sizeof buf) { - w = (char*) _TIFFmalloc(n * TIFFDataWidth(type)); - if (w == NULL) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "No space to write array"); - return (0); - } + switch (tif->tif_dir.td_sampleformat) + { + case SAMPLEFORMAT_IEEEFP: + if (tif->tif_dir.td_bitspersample<=32) + { + for (i = 0; i < count; ++i) + ((float*)conv)[i] = (float)value[i]; + ok = TIFFWriteDirectoryTagFloatArray(tif,ndir,dir,tag,count,(float*)conv); + } + else + { + ok = TIFFWriteDirectoryTagDoubleArray(tif,ndir,dir,tag,count,value); + } + break; + case SAMPLEFORMAT_INT: + if (tif->tif_dir.td_bitspersample<=8) + { + for (i = 0; i < count; ++i) + ((int8*)conv)[i] = (int8)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]; + ok = TIFFWriteDirectoryTagSshortArray(tif,ndir,dir,tag,count,(int16*)conv); + } + else + { + for (i = 0; i < count; ++i) + ((int32*)conv)[i] = (int32)value[i]; + ok = TIFFWriteDirectoryTagSlongArray(tif,ndir,dir,tag,count,(int32*)conv); + } + break; + case SAMPLEFORMAT_UINT: + if (tif->tif_dir.td_bitspersample<=8) + { + for (i = 0; i < count; ++i) + ((uint8*)conv)[i] = (uint8)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]; + ok = TIFFWriteDirectoryTagShortArray(tif,ndir,dir,tag,count,(uint16*)conv); + } + else + { + for (i = 0; i < count; ++i) + ((uint32*)conv)[i] = (uint32)value[i]; + ok = TIFFWriteDirectoryTagLongArray(tif,ndir,dir,tag,count,(uint32*)conv); + } + break; + default: + ok = 0; } - dir->tdir_tag = (uint16) tag; - dir->tdir_type = (uint16) type; - dir->tdir_count = n; + _TIFFfree(conv); + return (ok); +} - switch (type) { - case TIFF_BYTE: - { - uint8* bp = (uint8*) w; - for (i = 0; i < (int) n; i++) - bp[i] = (uint8) v[i]; - if (!TIFFWriteByteArray(tif, dir, (char*) bp)) - goto out; - } - break; - case TIFF_SBYTE: - { - int8* bp = (int8*) w; - for (i = 0; i < (int) n; i++) - bp[i] = (int8) v[i]; - if (!TIFFWriteByteArray(tif, dir, (char*) bp)) - goto out; - } - break; - case TIFF_SHORT: - { - uint16* bp = (uint16*) w; - for (i = 0; i < (int) n; i++) - bp[i] = (uint16) v[i]; - if (!TIFFWriteShortArray(tif, dir, (uint16*)bp)) - goto out; - } - break; - case TIFF_SSHORT: - { - int16* bp = (int16*) w; - for (i = 0; i < (int) n; i++) - bp[i] = (int16) v[i]; - if (!TIFFWriteShortArray(tif, dir, (uint16*)bp)) - goto out; - } - break; - case TIFF_LONG: - { - uint32* bp = (uint32*) w; - for (i = 0; i < (int) n; i++) - bp[i] = (uint32) v[i]; - if (!TIFFWriteLongArray(tif, dir, bp)) - goto out; - } - break; - case TIFF_SLONG: - { - int32* bp = (int32*) w; - for (i = 0; i < (int) n; i++) - bp[i] = (int32) v[i]; - if (!TIFFWriteLongArray(tif, dir, (uint32*) bp)) - goto out; - } - break; - case TIFF_FLOAT: - { - float* bp = (float*) w; - for (i = 0; i < (int) n; i++) - bp[i] = (float) v[i]; - if (!TIFFWriteFloatArray(tif, dir, bp)) - goto out; - } - break; - case TIFF_DOUBLE: - { - if( !TIFFWriteDoubleArray(tif, dir, v)) - goto out; - } - break; - default: - /* TIFF_NOTYPE */ - /* TIFF_ASCII */ - /* TIFF_UNDEFINED */ - /* TIFF_RATIONAL */ - /* TIFF_SRATIONAL */ - goto out; +#if 0 +static int +TIFFWriteDirectoryTagSampleformatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value) +{ + switch (tif->tif_dir.td_sampleformat) + { + case SAMPLEFORMAT_IEEEFP: + if (tif->tif_dir.td_bitspersample<=32) + return(TIFFWriteDirectoryTagFloatPerSample(tif,ndir,dir,tag,(float)value)); + else + return(TIFFWriteDirectoryTagDoublePerSample(tif,ndir,dir,tag,value)); + case SAMPLEFORMAT_INT: + if (tif->tif_dir.td_bitspersample<=8) + return(TIFFWriteDirectoryTagSbytePerSample(tif,ndir,dir,tag,(int8)value)); + else if (tif->tif_dir.td_bitspersample<=16) + return(TIFFWriteDirectoryTagSshortPerSample(tif,ndir,dir,tag,(int16)value)); + else + return(TIFFWriteDirectoryTagSlongPerSample(tif,ndir,dir,tag,(int32)value)); + case SAMPLEFORMAT_UINT: + if (tif->tif_dir.td_bitspersample<=8) + return(TIFFWriteDirectoryTagBytePerSample(tif,ndir,dir,tag,(uint8)value)); + else if (tif->tif_dir.td_bitspersample<=16) + return(TIFFWriteDirectoryTagShortPerSample(tif,ndir,dir,tag,(uint16)value)); + else + return(TIFFWriteDirectoryTagLongPerSample(tif,ndir,dir,tag,(uint32)value)); + default: + return(1); } - status = 1; - out: - if (w != buf) - _TIFFfree(w); - return (status); +} +#endif + +static int +TIFFWriteDirectoryTagAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedAscii(tif,ndir,dir,tag,count,value)); } static int -TIFFWriteTransferFunction(TIFF* tif, TIFFDirEntry* dir) +TIFFWriteDirectoryTagUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value) { - TIFFDirectory* td = &tif->tif_dir; - tsize_t n = (1L<td_bitspersample) * sizeof (uint16); - uint16** tf = td->td_transferfunction; - int ncols; + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedUndefinedArray(tif,ndir,dir,tag,count,value)); +} +#ifdef notdef +static int +TIFFWriteDirectoryTagByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedByte(tif,ndir,dir,tag,value)); +} +#endif + +static int +TIFFWriteDirectoryTagByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedByteArray(tif,ndir,dir,tag,count,value)); +} + +#if 0 +static int +TIFFWriteDirectoryTagBytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value) +{ + static const char module[] = "TIFFWriteDirectoryTagBytePerSample"; + uint8* m; + uint8* na; + uint16 nb; + int o; + if (dir==NULL) + { + (*ndir)++; + return(1); + } + m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint8)); + if (m==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + for (na=m, nb=0; nbtif_dir.td_samplesperpixel; na++, nb++) + *na=value; + o=TIFFWriteDirectoryTagCheckedByteArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m); + _TIFFfree(m); + return(o); +} +#endif + +#ifdef notdef +static int +TIFFWriteDirectoryTagSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedSbyte(tif,ndir,dir,tag,value)); +} +#endif + +static int +TIFFWriteDirectoryTagSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedSbyteArray(tif,ndir,dir,tag,count,value)); +} + +#if 0 +static int +TIFFWriteDirectoryTagSbytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value) +{ + static const char module[] = "TIFFWriteDirectoryTagSbytePerSample"; + int8* m; + int8* na; + uint16 nb; + int o; + if (dir==NULL) + { + (*ndir)++; + return(1); + } + m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int8)); + if (m==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + for (na=m, nb=0; nbtif_dir.td_samplesperpixel; na++, nb++) + *na=value; + o=TIFFWriteDirectoryTagCheckedSbyteArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m); + _TIFFfree(m); + return(o); +} +#endif + +static int +TIFFWriteDirectoryTagShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedShort(tif,ndir,dir,tag,value)); +} + +static int +TIFFWriteDirectoryTagShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,count,value)); +} + +static int +TIFFWriteDirectoryTagShortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value) +{ + static const char module[] = "TIFFWriteDirectoryTagShortPerSample"; + uint16* m; + uint16* na; + uint16 nb; + int o; + if (dir==NULL) + { + (*ndir)++; + return(1); + } + m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint16)); + if (m==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + for (na=m, nb=0; nbtif_dir.td_samplesperpixel; na++, nb++) + *na=value; + o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m); + _TIFFfree(m); + return(o); +} + +#ifdef notdef +static int +TIFFWriteDirectoryTagSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedSshort(tif,ndir,dir,tag,value)); +} +#endif + +static int +TIFFWriteDirectoryTagSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedSshortArray(tif,ndir,dir,tag,count,value)); +} + +#if 0 +static int +TIFFWriteDirectoryTagSshortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value) +{ + static const char module[] = "TIFFWriteDirectoryTagSshortPerSample"; + int16* m; + int16* na; + uint16 nb; + int o; + if (dir==NULL) + { + (*ndir)++; + return(1); + } + m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int16)); + if (m==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + for (na=m, nb=0; nbtif_dir.td_samplesperpixel; na++, nb++) + *na=value; + o=TIFFWriteDirectoryTagCheckedSshortArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m); + _TIFFfree(m); + return(o); +} +#endif + +static int +TIFFWriteDirectoryTagLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedLong(tif,ndir,dir,tag,value)); +} + +static int +TIFFWriteDirectoryTagLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,value)); +} + +#if 0 +static int +TIFFWriteDirectoryTagLongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value) +{ + static const char module[] = "TIFFWriteDirectoryTagLongPerSample"; + uint32* m; + uint32* na; + uint16 nb; + int o; + if (dir==NULL) + { + (*ndir)++; + return(1); + } + m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint32)); + if (m==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + for (na=m, nb=0; nbtif_dir.td_samplesperpixel; na++, nb++) + *na=value; + o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m); + _TIFFfree(m); + return(o); +} +#endif + +#ifdef notdef +static int +TIFFWriteDirectoryTagSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedSlong(tif,ndir,dir,tag,value)); +} +#endif + +static int +TIFFWriteDirectoryTagSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedSlongArray(tif,ndir,dir,tag,count,value)); +} + +#if 0 +static int +TIFFWriteDirectoryTagSlongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value) +{ + static const char module[] = "TIFFWriteDirectoryTagSlongPerSample"; + int32* m; + int32* na; + uint16 nb; + int o; + if (dir==NULL) + { + (*ndir)++; + return(1); + } + m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int32)); + if (m==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + for (na=m, nb=0; nbtif_dir.td_samplesperpixel; na++, nb++) + *na=value; + o=TIFFWriteDirectoryTagCheckedSlongArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m); + _TIFFfree(m); + return(o); +} +#endif + +#ifdef notdef +static int +TIFFWriteDirectoryTagLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedLong8(tif,ndir,dir,tag,value)); +} +#endif + +static int +TIFFWriteDirectoryTagLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,tag,count,value)); +} + +#ifdef notdef +static int +TIFFWriteDirectoryTagSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedSlong8(tif,ndir,dir,tag,value)); +} +#endif + +static int +TIFFWriteDirectoryTagSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedSlong8Array(tif,ndir,dir,tag,count,value)); +} + +static int +TIFFWriteDirectoryTagRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedRational(tif,ndir,dir,tag,value)); +} + +static int +TIFFWriteDirectoryTagRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedRationalArray(tif,ndir,dir,tag,count,value)); +} + +static int +TIFFWriteDirectoryTagSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedSrationalArray(tif,ndir,dir,tag,count,value)); +} + +#ifdef notdef +static int TIFFWriteDirectoryTagFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedFloat(tif,ndir,dir,tag,value)); +} +#endif + +static int TIFFWriteDirectoryTagFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedFloatArray(tif,ndir,dir,tag,count,value)); +} + +#if 0 +static int TIFFWriteDirectoryTagFloatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value) +{ + static const char module[] = "TIFFWriteDirectoryTagFloatPerSample"; + float* m; + float* na; + uint16 nb; + int o; + if (dir==NULL) + { + (*ndir)++; + return(1); + } + m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(float)); + if (m==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + for (na=m, nb=0; nbtif_dir.td_samplesperpixel; na++, nb++) + *na=value; + o=TIFFWriteDirectoryTagCheckedFloatArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m); + _TIFFfree(m); + return(o); +} +#endif + +#ifdef notdef +static int TIFFWriteDirectoryTagDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedDouble(tif,ndir,dir,tag,value)); +} +#endif + +static int TIFFWriteDirectoryTagDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedDoubleArray(tif,ndir,dir,tag,count,value)); +} + +#if 0 +static int TIFFWriteDirectoryTagDoublePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value) +{ + static const char module[] = "TIFFWriteDirectoryTagDoublePerSample"; + double* m; + double* na; + uint16 nb; + int o; + if (dir==NULL) + { + (*ndir)++; + return(1); + } + m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(double)); + if (m==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + for (na=m, nb=0; nbtif_dir.td_samplesperpixel; na++, nb++) + *na=value; + o=TIFFWriteDirectoryTagCheckedDoubleArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m); + _TIFFfree(m); + return(o); +} +#endif + +static int +TIFFWriteDirectoryTagIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,tag,count,value)); +} + +#ifdef notdef +static int +TIFFWriteDirectoryTagIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + return(TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,tag,count,value)); +} +#endif + +static int +TIFFWriteDirectoryTagShortLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value) +{ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + if (value<=0xFFFF) + return(TIFFWriteDirectoryTagCheckedShort(tif,ndir,dir,tag,(uint16)value)); + else + return(TIFFWriteDirectoryTagCheckedLong(tif,ndir,dir,tag,value)); +} + +/************************************************************************/ +/* TIFFWriteDirectoryTagLongLong8Array() */ +/* */ +/* Write out LONG8 array as LONG8 for BigTIFF or LONG for */ +/* Classic TIFF with some checking. */ +/************************************************************************/ + +static int +TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value) +{ + static const char module[] = "TIFFWriteDirectoryTagLongLong8Array"; + uint64* ma; + uint32 mb; + uint32* p; + uint32* q; + int o; + + /* is this just a counting pass? */ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + + /* We always write LONG8 for BigTIFF, no checking needed. */ + if( tif->tif_flags&TIFF_BIGTIFF ) + return TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir, + tag,count,value); + + /* + ** For classic tiff we want to verify everything is in range for LONG + ** and convert to long format. + */ + + p = _TIFFmalloc(count*sizeof(uint32)); + if (p==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + + for (q=p, ma=value, mb=0; mb0xFFFFFFFF) + { + TIFFErrorExt(tif->tif_clientdata,module, + "Attempt to write value larger than 0xFFFFFFFF in Classic TIFF file."); + _TIFFfree(p); + return(0); + } + *q= (uint32)(*ma); + } + + o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,p); + _TIFFfree(p); + + return(o); +} + +/************************************************************************/ +/* TIFFWriteDirectoryTagIfdIfd8Array() */ +/* */ +/* Write either IFD8 or IFD array depending on file type. */ +/************************************************************************/ + +static int +TIFFWriteDirectoryTagIfdIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value) +{ + static const char module[] = "TIFFWriteDirectoryTagIfdIfd8Array"; + uint64* ma; + uint32 mb; + uint32* p; + uint32* q; + int o; + + /* is this just a counting pass? */ + if (dir==NULL) + { + (*ndir)++; + return(1); + } + + /* We always write IFD8 for BigTIFF, no checking needed. */ + if( tif->tif_flags&TIFF_BIGTIFF ) + return TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir, + tag,count,value); + + /* + ** For classic tiff we want to verify everything is in range for IFD + ** and convert to long format. + */ + + p = _TIFFmalloc(count*sizeof(uint32)); + if (p==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + + for (q=p, ma=value, mb=0; mb0xFFFFFFFF) + { + TIFFErrorExt(tif->tif_clientdata,module, + "Attempt to write value larger than 0xFFFFFFFF in Classic TIFF file."); + _TIFFfree(p); + return(0); + } + *q= (uint32)(*ma); + } + + o=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,tag,count,p); + _TIFFfree(p); + + return(o); +} + +#ifdef notdef +static int +TIFFWriteDirectoryTagShortLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value) +{ + static const char module[] = "TIFFWriteDirectoryTagShortLongLong8Array"; + uint64* ma; + uint32 mb; + uint8 n; + int o; + if (dir==NULL) + { + (*ndir)++; + return(1); + } + n=0; + for (ma=value, mb=0; mb0xFFFF)) + n=1; + if ((n==1)&&(*ma>0xFFFFFFFF)) + { + n=2; + break; + } + } + if (n==0) + { + uint16* p; + uint16* q; + p=_TIFFmalloc(count*sizeof(uint16)); + if (p==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + for (ma=value, mb=0, q=p; mbtif_clientdata,module,"Out of memory"); + return(0); + } + for (ma=value, mb=0, q=p; mbtif_dir.td_bitspersample); + n=_TIFFmalloc(3*m*sizeof(uint16)); + if (n==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + _TIFFmemcpy(&n[0],tif->tif_dir.td_colormap[0],m*sizeof(uint16)); + _TIFFmemcpy(&n[m],tif->tif_dir.td_colormap[1],m*sizeof(uint16)); + _TIFFmemcpy(&n[2*m],tif->tif_dir.td_colormap[2],m*sizeof(uint16)); + o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,TIFFTAG_COLORMAP,3*m,n); + _TIFFfree(n); + return(o); +} + +static int +TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32* ndir, TIFFDirEntry* dir) +{ + static const char module[] = "TIFFWriteDirectoryTagTransferfunction"; + uint32 m; + uint16 n; + uint16* o; + int p; + if (dir==NULL) + { + (*ndir)++; + return(1); + } + m=(1<tif_dir.td_bitspersample); + n=tif->tif_dir.td_samplesperpixel-tif->tif_dir.td_extrasamples; /* * Check if the table can be written as a single column, * or if it must be written as 3 columns. Note that we * write a 3-column tag if there are 2 samples/pixel and * a single column of data won't suffice--hmm. */ - switch (td->td_samplesperpixel - td->td_extrasamples) { - default: if (_TIFFmemcmp(tf[0], tf[2], n)) { ncols = 3; break; } - case 2: if (_TIFFmemcmp(tf[0], tf[1], n)) { ncols = 3; break; } - case 1: case 0: ncols = 1; + if (n>3) + n=3; + if (n==3) + { + if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16))) + n=2; } - return (TIFFWriteShortTable(tif, - TIFFTAG_TRANSFERFUNCTION, dir, ncols, tf)); + if (n==2) + { + if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16))) + n=1; + } + if (n==0) + n=1; + o=_TIFFmalloc(n*m*sizeof(uint16)); + if (o==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + _TIFFmemcpy(&o[0],tif->tif_dir.td_transferfunction[0],m*sizeof(uint16)); + if (n>1) + _TIFFmemcpy(&o[m],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16)); + if (n>2) + _TIFFmemcpy(&o[2*m],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16)); + p=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,TIFFTAG_TRANSFERFUNCTION,n*m,o); + _TIFFfree(o); + return(p); } static int -TIFFWriteInkNames(TIFF* tif, TIFFDirEntry* dir) +TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32* ndir, TIFFDirEntry* dir) { - TIFFDirectory* td = &tif->tif_dir; - - dir->tdir_tag = TIFFTAG_INKNAMES; - dir->tdir_type = (short) TIFF_ASCII; - dir->tdir_count = td->td_inknameslen; - return (TIFFWriteByteArray(tif, dir, td->td_inknames)); + static const char module[] = "TIFFWriteDirectoryTagSubifd"; + uint64 m; + int n; + if (tif->tif_dir.td_nsubifd==0) + return(1); + if (dir==NULL) + { + (*ndir)++; + return(1); + } + m=tif->tif_dataoff; + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + uint32* o; + uint64* pa; + uint32* pb; + uint16 p; + o=_TIFFmalloc(tif->tif_dir.td_nsubifd*sizeof(uint32)); + if (o==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + pa=tif->tif_dir.td_subifd; + pb=o; + for (p=0; p < tif->tif_dir.td_nsubifd; p++) + { + assert(pa != 0); + assert(*pa <= 0xFFFFFFFFUL); + *pb++=(uint32)(*pa++); + } + n=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,o); + _TIFFfree(o); + } + else + n=TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,tif->tif_dir.td_subifd); + if (!n) + return(0); + /* + * Total hack: if this directory includes a SubIFD + * tag then force the next directories to be + * written as ``sub directories'' of this one. This + * is used to write things like thumbnails and + * image masks that one wants to keep out of the + * normal directory linkage access mechanism. + */ + tif->tif_flags|=TIFF_INSUBIFD; + tif->tif_nsubifd=tif->tif_dir.td_nsubifd; + if (tif->tif_dir.td_nsubifd==1) + tif->tif_subifdoff=0; + else + tif->tif_subifdoff=m; + return(1); } -/* - * Write a contiguous directory item. - */ static int -TIFFWriteData(TIFF* tif, TIFFDirEntry* dir, char* cp) +TIFFWriteDirectoryTagCheckedAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value) { - tsize_t cc; - - if (tif->tif_flags & TIFF_SWAB) { - switch (dir->tdir_type) { - case TIFF_SHORT: - case TIFF_SSHORT: - TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count); - break; - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_FLOAT: - TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count); - break; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count); - break; - case TIFF_DOUBLE: - TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count); - break; - } - } - dir->tdir_offset = tif->tif_dataoff; - cc = dir->tdir_count * TIFFDataWidth((TIFFDataType) dir->tdir_type); - if (SeekOK(tif, dir->tdir_offset) && - WriteOK(tif, cp, cc)) { - tif->tif_dataoff += (cc + 1) & ~1; - return (1); - } - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Error writing data for field \"%s\"", - _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); - return (0); + assert(sizeof(char)==1); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_ASCII,count,count,value)); } -/* - * Similar to TIFFWriteDirectory(), but if the directory has already - * been written once, it is relocated to the end of the file, in case it - * has changed in size. Note that this will result in the loss of the - * previously used directory space. - */ - -int -TIFFRewriteDirectory( TIFF *tif ) +static int +TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value) { - static const char module[] = "TIFFRewriteDirectory"; - - /* We don't need to do anything special if it hasn't been written. */ - if( tif->tif_diroff == 0 ) - return TIFFWriteDirectory( tif ); - - /* - ** Find and zero the pointer to this directory, so that TIFFLinkDirectory - ** will cause it to be added after this directories current pre-link. - */ - - /* Is it the first directory in the file? */ - if (tif->tif_header.tiff_diroff == tif->tif_diroff) - { - tif->tif_header.tiff_diroff = 0; - tif->tif_diroff = 0; - - TIFFSeekFile(tif, (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE), - SEEK_SET); - if (!WriteOK(tif, &(tif->tif_header.tiff_diroff), - sizeof (tif->tif_diroff))) - { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Error updating TIFF header"); - return (0); - } - } - else - { - toff_t nextdir, off; - - nextdir = tif->tif_header.tiff_diroff; - do { - uint16 dircount; - - if (!SeekOK(tif, nextdir) || - !ReadOK(tif, &dircount, sizeof (dircount))) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error fetching directory count"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&dircount); - (void) TIFFSeekFile(tif, - dircount * sizeof (TIFFDirEntry), SEEK_CUR); - if (!ReadOK(tif, &nextdir, sizeof (nextdir))) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error fetching directory link"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&nextdir); - } while (nextdir != tif->tif_diroff && nextdir != 0); - off = TIFFSeekFile(tif, 0, SEEK_CUR); /* get current offset */ - (void) TIFFSeekFile(tif, off - (toff_t)sizeof(nextdir), SEEK_SET); - tif->tif_diroff = 0; - if (!WriteOK(tif, &(tif->tif_diroff), sizeof (nextdir))) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error writing directory link"); - return (0); - } - } - - /* - ** Now use TIFFWriteDirectory() normally. - */ - - return TIFFWriteDirectory( tif ); + assert(sizeof(uint8)==1); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_UNDEFINED,count,count,value)); } +#ifdef notdef +static int +TIFFWriteDirectoryTagCheckedByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value) +{ + assert(sizeof(uint8)==1); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_BYTE,1,1,&value)); +} +#endif + +static int +TIFFWriteDirectoryTagCheckedByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value) +{ + assert(sizeof(uint8)==1); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_BYTE,count,count,value)); +} + +#ifdef notdef +static int +TIFFWriteDirectoryTagCheckedSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value) +{ + assert(sizeof(int8)==1); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SBYTE,1,1,&value)); +} +#endif + +static int +TIFFWriteDirectoryTagCheckedSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value) +{ + assert(sizeof(int8)==1); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SBYTE,count,count,value)); +} + +static int +TIFFWriteDirectoryTagCheckedShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value) +{ + uint16 m; + assert(sizeof(uint16)==2); + m=value; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort(&m); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SHORT,1,2,&m)); +} + +static int +TIFFWriteDirectoryTagCheckedShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value) +{ + assert(count<0x80000000); + assert(sizeof(uint16)==2); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfShort(value,count); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SHORT,count,count*2,value)); +} + +#ifdef notdef +static int +TIFFWriteDirectoryTagCheckedSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value) +{ + int16 m; + assert(sizeof(int16)==2); + m=value; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort((uint16*)(&m)); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SSHORT,1,2,&m)); +} +#endif + +static int +TIFFWriteDirectoryTagCheckedSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value) +{ + assert(count<0x80000000); + assert(sizeof(int16)==2); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfShort((uint16*)value,count); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SSHORT,count,count*2,value)); +} + +static int +TIFFWriteDirectoryTagCheckedLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value) +{ + uint32 m; + assert(sizeof(uint32)==4); + m=value; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(&m); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG,1,4,&m)); +} + +static int +TIFFWriteDirectoryTagCheckedLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value) +{ + assert(count<0x40000000); + assert(sizeof(uint32)==4); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong(value,count); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG,count,count*4,value)); +} + +#ifdef notdef +static int +TIFFWriteDirectoryTagCheckedSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value) +{ + int32 m; + assert(sizeof(int32)==4); + m=value; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong((uint32*)(&m)); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG,1,4,&m)); +} +#endif + +static int +TIFFWriteDirectoryTagCheckedSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value) +{ + assert(count<0x40000000); + assert(sizeof(int32)==4); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong((uint32*)value,count); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG,count,count*4,value)); +} + +#ifdef notdef +static int +TIFFWriteDirectoryTagCheckedLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value) +{ + uint64 m; + assert(sizeof(uint64)==8); + assert(tif->tif_flags&TIFF_BIGTIFF); + m=value; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8(&m); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG8,1,8,&m)); +} +#endif + +static int +TIFFWriteDirectoryTagCheckedLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value) +{ + assert(count<0x20000000); + assert(sizeof(uint64)==8); + assert(tif->tif_flags&TIFF_BIGTIFF); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong8(value,count); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG8,count,count*8,value)); +} + +#ifdef notdef +static int +TIFFWriteDirectoryTagCheckedSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value) +{ + int64 m; + assert(sizeof(int64)==8); + assert(tif->tif_flags&TIFF_BIGTIFF); + m=value; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8((uint64*)(&m)); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG8,1,8,&m)); +} +#endif + +static int +TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value) +{ + assert(count<0x20000000); + assert(sizeof(int64)==8); + assert(tif->tif_flags&TIFF_BIGTIFF); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong8((uint64*)value,count); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG8,count,count*8,value)); +} + +static int +TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value) +{ + uint32 m[2]; + assert(value>=0.0); + assert(sizeof(uint32)==4); + if (value<=0.0) + { + m[0]=0; + m[1]=1; + } + else if (value==(double)(uint32)value) + { + m[0]=(uint32)value; + m[1]=1; + } + else if (value<1.0) + { + m[0]=(uint32)(value*0xFFFFFFFF); + m[1]=0xFFFFFFFF; + } + else + { + m[0]=0xFFFFFFFF; + m[1]=(uint32)(0xFFFFFFFF/value); + } + if (tif->tif_flags&TIFF_SWAB) + { + TIFFSwabLong(&m[0]); + TIFFSwabLong(&m[1]); + } + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,1,8,&m[0])); +} + +static int +TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value) +{ + static const char module[] = "TIFFWriteDirectoryTagCheckedRationalArray"; + uint32* m; + float* na; + uint32* nb; + uint32 nc; + int o; + assert(sizeof(uint32)==4); + m=_TIFFmalloc(count*2*sizeof(uint32)); + if (m==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + for (na=value, nb=m, nc=0; nctif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong(m,count*2); + o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,count,count*8,&m[0]); + _TIFFfree(m); + return(o); +} + +static int +TIFFWriteDirectoryTagCheckedSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value) +{ + static const char module[] = "TIFFWriteDirectoryTagCheckedSrationalArray"; + int32* m; + float* na; + int32* nb; + uint32 nc; + int o; + assert(sizeof(int32)==4); + m=_TIFFmalloc(count*2*sizeof(int32)); + if (m==NULL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); + return(0); + } + for (na=value, nb=m, nc=0; nc-1.0) + { + nb[0]=-(int32)((-*na)*0x7FFFFFFF); + nb[1]=0x7FFFFFFF; + } + else + { + nb[0]=-0x7FFFFFFF; + nb[1]=(int32)(0x7FFFFFFF/(-*na)); + } + } + else + { + if (*na==(int32)(*na)) + { + nb[0]=(int32)(*na); + nb[1]=1; + } + else if (*na<1.0) + { + nb[0]=(int32)((*na)*0x7FFFFFFF); + nb[1]=0x7FFFFFFF; + } + else + { + nb[0]=0x7FFFFFFF; + nb[1]=(int32)(0x7FFFFFFF/(*na)); + } + } + } + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong((uint32*)m,count*2); + o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SRATIONAL,count,count*8,&m[0]); + _TIFFfree(m); + return(o); +} + +#ifdef notdef +static int +TIFFWriteDirectoryTagCheckedFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value) +{ + float m; + assert(sizeof(float)==4); + m=value; + TIFFCvtNativeToIEEEFloat(tif,1,&m); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabFloat(&m); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_FLOAT,1,4,&m)); +} +#endif + +static int +TIFFWriteDirectoryTagCheckedFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value) +{ + assert(count<0x40000000); + assert(sizeof(float)==4); + TIFFCvtNativeToIEEEFloat(tif,count,&value); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfFloat(value,count); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_FLOAT,count,count*4,value)); +} + +#ifdef notdef +static int +TIFFWriteDirectoryTagCheckedDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value) +{ + double m; + assert(sizeof(double)==8); + m=value; + TIFFCvtNativeToIEEEDouble(tif,1,&m); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabDouble(&m); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_DOUBLE,1,8,&m)); +} +#endif + +static int +TIFFWriteDirectoryTagCheckedDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value) +{ + assert(count<0x20000000); + assert(sizeof(double)==8); + TIFFCvtNativeToIEEEDouble(tif,count,&value); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfDouble(value,count); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_DOUBLE,count,count*8,value)); +} + +static int +TIFFWriteDirectoryTagCheckedIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value) +{ + assert(count<0x40000000); + assert(sizeof(uint32)==4); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong(value,count); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_IFD,count,count*4,value)); +} + +static int +TIFFWriteDirectoryTagCheckedIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value) +{ + assert(count<0x20000000); + assert(sizeof(uint64)==8); + assert(tif->tif_flags&TIFF_BIGTIFF); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabArrayOfLong8(value,count); + return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_IFD8,count,count*8,value)); +} + +static int +TIFFWriteDirectoryTagData(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 datatype, uint32 count, uint32 datalength, void* data) +{ + static const char module[] = "TIFFWriteDirectoryTagData"; + uint32 m; + m=0; + while (m<(*ndir)) + { + assert(dir[m].tdir_tag!=tag); + if (dir[m].tdir_tag>tag) + break; + m++; + } + if (m<(*ndir)) + { + uint32 n; + for (n=*ndir; n>m; n--) + dir[n]=dir[n-1]; + } + dir[m].tdir_tag=tag; + dir[m].tdir_type=datatype; + dir[m].tdir_count=count; + dir[m].tdir_offset.toff_long8 = 0; + if (datalength<=((tif->tif_flags&TIFF_BIGTIFF)?0x8U:0x4U)) + _TIFFmemcpy(&dir[m].tdir_offset,data,datalength); + else + { + uint64 na,nb; + na=tif->tif_dataoff; + nb=na+datalength; + if (!(tif->tif_flags&TIFF_BIGTIFF)) + nb=(uint32)nb; + if ((nbtif_clientdata,module,"Maximum TIFF file size exceeded"); + return(0); + } + if (!SeekOK(tif,na)) + { + TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data"); + return(0); + } + assert(datalength<0x80000000UL); + if (!WriteOK(tif,data,(tmsize_t)datalength)) + { + TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data"); + return(0); + } + tif->tif_dataoff=nb; + if (tif->tif_dataoff&1) + tif->tif_dataoff++; + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + uint32 o; + o=(uint32)na; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong(&o); + _TIFFmemcpy(&dir[m].tdir_offset,&o,4); + } + else + { + dir[m].tdir_offset.toff_long8 = na; + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8(&dir[m].tdir_offset.toff_long8); + } + } + (*ndir)++; + return(1); +} /* * Link the current directory into the directory chain for the file. @@ -1323,87 +2367,540 @@ static int TIFFLinkDirectory(TIFF* tif) { static const char module[] = "TIFFLinkDirectory"; - toff_t nextdir; - toff_t diroff, off; - tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1; - diroff = tif->tif_diroff; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&diroff); + tif->tif_diroff = (TIFFSeekFile(tif,0,SEEK_END)+1) &~ 1; /* * Handle SubIFDs */ - if (tif->tif_flags & TIFF_INSUBIFD) { - (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET); - if (!WriteOK(tif, &diroff, sizeof (diroff))) { - TIFFErrorExt(tif->tif_clientdata, module, - "%s: Error writing SubIFD directory link", - tif->tif_name); - return (0); + if (tif->tif_flags & TIFF_INSUBIFD) + { + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + uint32 m; + m = (uint32)tif->tif_diroff; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&m); + (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET); + if (!WriteOK(tif, &m, 4)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error writing SubIFD directory link"); + return (0); + } + /* + * Advance to the next SubIFD or, if this is + * the last one configured, revert back to the + * normal directory linkage. + */ + if (--tif->tif_nsubifd) + tif->tif_subifdoff += 4; + else + tif->tif_flags &= ~TIFF_INSUBIFD; + return (1); } - /* - * Advance to the next SubIFD or, if this is - * the last one configured, revert back to the - * normal directory linkage. - */ - if (--tif->tif_nsubifd) - tif->tif_subifdoff += sizeof (diroff); else - tif->tif_flags &= ~TIFF_INSUBIFD; - return (1); + { + uint64 m; + m = tif->tif_diroff; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&m); + (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET); + if (!WriteOK(tif, &m, 8)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error writing SubIFD directory link"); + return (0); + } + /* + * Advance to the next SubIFD or, if this is + * the last one configured, revert back to the + * normal directory linkage. + */ + if (--tif->tif_nsubifd) + tif->tif_subifdoff += 8; + else + tif->tif_flags &= ~TIFF_INSUBIFD; + return (1); + } } - if (tif->tif_header.tiff_diroff == 0) { + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + uint32 m; + uint32 nextdir; + m = (uint32)(tif->tif_diroff); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&m); + if (tif->tif_header.classic.tiff_diroff == 0) { + /* + * First directory, overwrite offset in header. + */ + tif->tif_header.classic.tiff_diroff = (uint32) tif->tif_diroff; + (void) TIFFSeekFile(tif,4, SEEK_SET); + if (!WriteOK(tif, &m, 4)) { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "Error writing TIFF header"); + return (0); + } + return (1); + } /* - * First directory, overwrite offset in header. + * Not the first directory, search to the last and append. */ - tif->tif_header.tiff_diroff = tif->tif_diroff; - (void) TIFFSeekFile(tif, - (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE), - SEEK_SET); - if (!WriteOK(tif, &diroff, sizeof (diroff))) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Error writing TIFF header"); - return (0); - } - return (1); - } - /* - * Not the first directory, search to the last and append. - */ - nextdir = tif->tif_header.tiff_diroff; - do { - uint16 dircount; + nextdir = tif->tif_header.classic.tiff_diroff; + while(1) { + uint16 dircount; + uint32 nextnextdir; - if (!SeekOK(tif, nextdir) || - !ReadOK(tif, &dircount, sizeof (dircount))) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error fetching directory count"); - return (0); + if (!SeekOK(tif, nextdir) || + !ReadOK(tif, &dircount, 2)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error fetching directory count"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount); + (void) TIFFSeekFile(tif, + nextdir+2+dircount*12, SEEK_SET); + if (!ReadOK(tif, &nextnextdir, 4)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error fetching directory link"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextnextdir); + if (nextnextdir==0) + { + (void) TIFFSeekFile(tif, + nextdir+2+dircount*12, SEEK_SET); + if (!WriteOK(tif, &m, 4)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error writing directory link"); + return (0); + } + break; + } + nextdir=nextnextdir; } + } + else + { + uint64 m; + uint64 nextdir; + m = tif->tif_diroff; if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&dircount); - (void) TIFFSeekFile(tif, - dircount * sizeof (TIFFDirEntry), SEEK_CUR); - if (!ReadOK(tif, &nextdir, sizeof (nextdir))) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error fetching directory link"); - return (0); + TIFFSwabLong8(&m); + if (tif->tif_header.big.tiff_diroff == 0) { + /* + * First directory, overwrite offset in header. + */ + tif->tif_header.big.tiff_diroff = tif->tif_diroff; + (void) TIFFSeekFile(tif,8, SEEK_SET); + if (!WriteOK(tif, &m, 8)) { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "Error writing TIFF header"); + return (0); + } + return (1); + } + /* + * Not the first directory, search to the last and append. + */ + nextdir = tif->tif_header.big.tiff_diroff; + while(1) { + uint64 dircount64; + uint16 dircount; + uint64 nextnextdir; + + if (!SeekOK(tif, nextdir) || + !ReadOK(tif, &dircount64, 8)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error fetching directory count"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&dircount64); + if (dircount64>0xFFFF) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Sanity check on tag count failed, likely corrupt TIFF"); + return (0); + } + dircount=(uint16)dircount64; + (void) TIFFSeekFile(tif, + nextdir+8+dircount*20, SEEK_SET); + if (!ReadOK(tif, &nextnextdir, 8)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error fetching directory link"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&nextnextdir); + if (nextnextdir==0) + { + (void) TIFFSeekFile(tif, + nextdir+8+dircount*20, SEEK_SET); + if (!WriteOK(tif, &m, 8)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error writing directory link"); + return (0); + } + break; + } + nextdir=nextnextdir; } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&nextdir); - } while (nextdir != 0); - off = TIFFSeekFile(tif, 0, SEEK_CUR); /* get current offset */ - (void) TIFFSeekFile(tif, off - (toff_t)sizeof(nextdir), SEEK_SET); - if (!WriteOK(tif, &diroff, sizeof (diroff))) { - TIFFErrorExt(tif->tif_clientdata, module, - "Error writing directory link"); - return (0); } return (1); } +/************************************************************************/ +/* TIFFRewriteField() */ +/* */ +/* Rewrite a field in the directory on disk without regard to */ +/* updating the TIFF directory structure in memory. Currently */ +/* only supported for field that already exist in the on-disk */ +/* directory. Mainly used for updating stripoffset / */ +/* stripbytecount values after the directory is already on */ +/* disk. */ +/* */ +/* Returns zero on failure, and one on success. */ +/************************************************************************/ + +int +_TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype, + tmsize_t count, void* data) +{ + static const char module[] = "TIFFResetField"; + /* const TIFFField* fip = NULL; */ + uint16 dircount; + tmsize_t dirsize; + uint8 direntry_raw[20]; + uint16 entry_tag = 0; + uint16 entry_type = 0; + uint64 entry_count = 0; + uint64 entry_offset = 0; + int value_in_entry = 0; + uint64 read_offset; + uint8 *buf_to_write = NULL; + TIFFDataType datatype; + +/* -------------------------------------------------------------------- */ +/* Find field definition. */ +/* -------------------------------------------------------------------- */ + /*fip =*/ TIFFFindField(tif, tag, TIFF_ANY); + +/* -------------------------------------------------------------------- */ +/* Do some checking this is a straight forward case. */ +/* -------------------------------------------------------------------- */ + if( isMapped(tif) ) + { + TIFFErrorExt( tif->tif_clientdata, module, + "Memory mapped files not currently supported for this operation." ); + return 0; + } + + if( tif->tif_diroff == 0 ) + { + TIFFErrorExt( tif->tif_clientdata, module, + "Attempt to reset field on directory not already on disk." ); + return 0; + } + +/* -------------------------------------------------------------------- */ +/* Read the directory entry count. */ +/* -------------------------------------------------------------------- */ + if (!SeekOK(tif, tif->tif_diroff)) { + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Seek error accessing TIFF directory", + tif->tif_name); + return 0; + } + + read_offset = tif->tif_diroff; + + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + if (!ReadOK(tif, &dircount, sizeof (uint16))) { + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Can not read TIFF directory count", + tif->tif_name); + return 0; + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount); + dirsize = 12; + read_offset += 2; + } else { + uint64 dircount64; + if (!ReadOK(tif, &dircount64, sizeof (uint64))) { + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Can not read TIFF directory count", + tif->tif_name); + return 0; + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&dircount64); + dircount = (uint16)dircount64; + dirsize = 20; + read_offset += 8; + } + +/* -------------------------------------------------------------------- */ +/* Read through directory to find target tag. */ +/* -------------------------------------------------------------------- */ + while( dircount > 0 ) + { + if (!ReadOK(tif, direntry_raw, dirsize)) { + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Can not read TIFF directory entry.", + tif->tif_name); + return 0; + } + + memcpy( &entry_tag, direntry_raw + 0, sizeof(uint16) ); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort( &entry_tag ); + + if( entry_tag == tag ) + break; + + read_offset += dirsize; + } + + if( entry_tag != tag ) + { + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Could not find tag %d.", + tif->tif_name, tag ); + return 0; + } + +/* -------------------------------------------------------------------- */ +/* Extract the type, count and offset for this entry. */ +/* -------------------------------------------------------------------- */ + memcpy( &entry_type, direntry_raw + 2, sizeof(uint16) ); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort( &entry_type ); + + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + uint32 value; + + memcpy( &value, direntry_raw + 4, sizeof(uint32) ); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong( &value ); + entry_count = value; + + memcpy( &value, direntry_raw + 8, sizeof(uint32) ); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong( &value ); + entry_offset = value; + } + else + { + memcpy( &entry_count, direntry_raw + 4, sizeof(uint64) ); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8( &entry_count ); + + memcpy( &entry_offset, direntry_raw + 12, sizeof(uint64) ); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8( &entry_offset ); + } + +/* -------------------------------------------------------------------- */ +/* What data type do we want to write this as? */ +/* -------------------------------------------------------------------- */ + if( TIFFDataWidth(in_datatype) == 8 && !(tif->tif_flags&TIFF_BIGTIFF) ) + { + if( in_datatype == TIFF_LONG8 ) + datatype = TIFF_LONG; + else if( in_datatype == TIFF_SLONG8 ) + datatype = TIFF_SLONG; + else if( in_datatype == TIFF_IFD8 ) + datatype = TIFF_IFD; + else + datatype = in_datatype; + } + else + datatype = in_datatype; + +/* -------------------------------------------------------------------- */ +/* Prepare buffer of actual data to write. This includes */ +/* swabbing as needed. */ +/* -------------------------------------------------------------------- */ + buf_to_write = + (uint8 *)_TIFFCheckMalloc(tif, count, TIFFDataWidth(datatype), + "for field buffer."); + if (!buf_to_write) + return 0; + + if( datatype == in_datatype ) + memcpy( buf_to_write, data, count * TIFFDataWidth(datatype) ); + else if( datatype == TIFF_SLONG && in_datatype == TIFF_SLONG8 ) + { + tmsize_t i; + + for( i = 0; i < count; i++ ) + { + ((int32 *) buf_to_write)[i] = + (int32) ((int64 *) data)[i]; + if( (int64) ((int32 *) buf_to_write)[i] != ((int64 *) data)[i] ) + { + _TIFFfree( buf_to_write ); + TIFFErrorExt( tif->tif_clientdata, module, + "Value exceeds 32bit range of output type." ); + return 0; + } + } + } + else if( (datatype == TIFF_LONG && in_datatype == TIFF_LONG8) + || (datatype == TIFF_IFD && in_datatype == TIFF_IFD8) ) + { + tmsize_t i; + + for( i = 0; i < count; i++ ) + { + ((uint32 *) buf_to_write)[i] = + (uint32) ((uint64 *) data)[i]; + if( (uint64) ((uint32 *) buf_to_write)[i] != ((uint64 *) data)[i] ) + { + _TIFFfree( buf_to_write ); + TIFFErrorExt( tif->tif_clientdata, module, + "Value exceeds 32bit range of output type." ); + return 0; + } + } + } + + if( TIFFDataWidth(datatype) > 1 && (tif->tif_flags&TIFF_SWAB) ) + { + if( TIFFDataWidth(datatype) == 2 ) + TIFFSwabArrayOfShort( (uint16 *) buf_to_write, count ); + else if( TIFFDataWidth(datatype) == 4 ) + TIFFSwabArrayOfLong( (uint32 *) buf_to_write, count ); + else if( TIFFDataWidth(datatype) == 8 ) + TIFFSwabArrayOfLong8( (uint64 *) buf_to_write, count ); + } + +/* -------------------------------------------------------------------- */ +/* Is this a value that fits into the directory entry? */ +/* -------------------------------------------------------------------- */ + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + if( TIFFDataWidth(datatype) * count <= 4 ) + { + entry_offset = read_offset + 8; + value_in_entry = 1; + } + } + else + { + if( TIFFDataWidth(datatype) * count <= 8 ) + { + entry_offset = read_offset + 12; + value_in_entry = 1; + } + } + +/* -------------------------------------------------------------------- */ +/* If the tag type, and count match, then we just write it out */ +/* over the old values without altering the directory entry at */ +/* all. */ +/* -------------------------------------------------------------------- */ + if( entry_count == (uint64)count && entry_type == (uint16) datatype ) + { + if (!SeekOK(tif, entry_offset)) { + _TIFFfree( buf_to_write ); + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Seek error accessing TIFF directory", + tif->tif_name); + return 0; + } + if (!WriteOK(tif, buf_to_write, count*TIFFDataWidth(datatype))) { + _TIFFfree( buf_to_write ); + TIFFErrorExt(tif->tif_clientdata, module, + "Error writing directory link"); + return (0); + } + + _TIFFfree( buf_to_write ); + return 1; + } + +/* -------------------------------------------------------------------- */ +/* Otherwise, we write the new tag data at the end of the file. */ +/* -------------------------------------------------------------------- */ + if( !value_in_entry ) + { + entry_offset = TIFFSeekFile(tif,0,SEEK_END); + + if (!WriteOK(tif, buf_to_write, count*TIFFDataWidth(datatype))) { + _TIFFfree( buf_to_write ); + TIFFErrorExt(tif->tif_clientdata, module, + "Error writing directory link"); + return (0); + } + } + else + { + memcpy( &entry_offset, buf_to_write, count*TIFFDataWidth(datatype)); + } + + _TIFFfree( buf_to_write ); + buf_to_write = 0; + +/* -------------------------------------------------------------------- */ +/* Adjust the directory entry. */ +/* -------------------------------------------------------------------- */ + entry_type = datatype; + memcpy( direntry_raw + 2, &entry_type, sizeof(uint16) ); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabShort( (uint16 *) (direntry_raw + 2) ); + + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + uint32 value; + + value = (uint32) entry_count; + memcpy( direntry_raw + 4, &value, sizeof(uint32) ); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong( (uint32 *) (direntry_raw + 4) ); + + value = (uint32) entry_offset; + memcpy( direntry_raw + 8, &value, sizeof(uint32) ); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong( (uint32 *) (direntry_raw + 8) ); + } + else + { + memcpy( direntry_raw + 4, &entry_count, sizeof(uint64) ); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8( (uint64 *) (direntry_raw + 4) ); + + memcpy( direntry_raw + 12, &entry_offset, sizeof(uint64) ); + if (tif->tif_flags&TIFF_SWAB) + TIFFSwabLong8( (uint64 *) (direntry_raw + 12) ); + } + +/* -------------------------------------------------------------------- */ +/* Write the directory entry out to disk. */ +/* -------------------------------------------------------------------- */ + if (!SeekOK(tif, read_offset )) { + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Seek error accessing TIFF directory", + tif->tif_name); + return 0; + } + + if (!WriteOK(tif, direntry_raw,dirsize)) + { + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Can not write TIFF directory entry.", + tif->tif_name); + return 0; + } + + return 1; +} /* vim: set ts=8 sts=8 sw=8 noet: */ /* * Local Variables: diff --git a/thirdparty/libtiff/tif_dumpmode.c b/thirdparty/libtiff/tif_dumpmode.c index da861503..a94cf0b3 100644 --- a/thirdparty/libtiff/tif_dumpmode.c +++ b/thirdparty/libtiff/tif_dumpmode.c @@ -1,4 +1,4 @@ -/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_dumpmode.c,v 1.5.2.2 2010-06-08 18:50:42 bfriesen Exp $ */ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_dumpmode.c,v 1.14 2011-04-02 20:54:09 bfriesen Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -31,22 +31,29 @@ */ #include "tiffiop.h" +static int +DumpFixupTags(TIFF* tif) +{ + (void) tif; + return (1); +} + /* * Encode a hunk of pixels. */ static int -DumpModeEncode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s) +DumpModeEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) { (void) s; while (cc > 0) { - tsize_t n; + tmsize_t n; n = cc; if (tif->tif_rawcc + n > tif->tif_rawdatasize) n = tif->tif_rawdatasize - tif->tif_rawcc; assert( n > 0 ); - + /* * Avoid copy if client has setup raw * data buffer to avoid extra copy. @@ -68,15 +75,24 @@ DumpModeEncode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s) * Decode a hunk of pixels. */ static int -DumpModeDecode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) +DumpModeDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) { + static const char module[] = "DumpModeDecode"; (void) s; -/* fprintf(stderr,"DumpModeDecode: scanline %ld, expected %ld bytes, got %ld bytes\n", */ -/* (long) tif->tif_row, (long) tif->tif_rawcc, (long) cc); */ if (tif->tif_rawcc < cc) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "DumpModeDecode: Not enough data for scanline %d", - tif->tif_row); +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, +"Not enough data for scanline %lu, expected a request for at most %I64d bytes, got a request for %I64d bytes", + (unsigned long) tif->tif_row, + (signed __int64) tif->tif_rawcc, + (signed __int64) cc); +#else + TIFFErrorExt(tif->tif_clientdata, module, +"Not enough data for scanline %lu, expected a request for at most %lld bytes, got a request for %lld bytes", + (unsigned long) tif->tif_row, + (signed long long) tif->tif_rawcc, + (signed long long) cc); +#endif return (0); } /* @@ -86,7 +102,7 @@ DumpModeDecode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) if (tif->tif_rawcp != buf) _TIFFmemcpy(buf, tif->tif_rawcp, cc); tif->tif_rawcp += cc; - tif->tif_rawcc -= cc; + tif->tif_rawcc -= cc; return (1); } @@ -108,12 +124,13 @@ int TIFFInitDumpMode(TIFF* tif, int scheme) { (void) scheme; + tif->tif_fixuptags = DumpFixupTags; tif->tif_decoderow = DumpModeDecode; tif->tif_decodestrip = DumpModeDecode; tif->tif_decodetile = DumpModeDecode; tif->tif_encoderow = DumpModeEncode; tif->tif_encodestrip = DumpModeEncode; - tif->tif_encodetile = DumpModeEncode; + tif->tif_encodetile = DumpModeEncode; tif->tif_seek = DumpModeSeek; return (1); } diff --git a/thirdparty/libtiff/tif_error.c b/thirdparty/libtiff/tif_error.c index 2377abda..0bc8b878 100644 --- a/thirdparty/libtiff/tif_error.c +++ b/thirdparty/libtiff/tif_error.c @@ -1,4 +1,4 @@ -/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_error.c,v 1.4.2.1 2010-06-08 18:50:42 bfriesen Exp $ */ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_error.c,v 1.5 2010-03-10 18:56:48 bfriesen Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler diff --git a/thirdparty/libtiff/tif_extension.c b/thirdparty/libtiff/tif_extension.c index b67c0f00..10afd416 100644 --- a/thirdparty/libtiff/tif_extension.c +++ b/thirdparty/libtiff/tif_extension.c @@ -1,4 +1,4 @@ -/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_extension.c,v 1.4.2.1 2010-06-08 18:50:42 bfriesen Exp $ */ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_extension.c,v 1.7 2010-03-10 18:56:48 bfriesen Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -41,13 +41,13 @@ int TIFFGetTagListCount( TIFF *tif ) return td->td_customValueCount; } -ttag_t TIFFGetTagListEntry( TIFF *tif, int tag_index ) +uint32 TIFFGetTagListEntry( TIFF *tif, int tag_index ) { TIFFDirectory* td = &tif->tif_dir; if( tag_index < 0 || tag_index >= td->td_customValueCount ) - return (ttag_t) -1; + return (uint32)(-1); else return td->td_customValues[tag_index].info->field_tag; } @@ -102,7 +102,7 @@ void TIFFSetClientInfo( TIFF *tif, void *data, const char *name ) link = (TIFFClientInfoLink *) _TIFFmalloc(sizeof(TIFFClientInfoLink)); assert (link != NULL); link->next = tif->tif_clientinfo; - link->name = (char *) _TIFFmalloc(strlen(name)+1); + link->name = (char *) _TIFFmalloc((tmsize_t)(strlen(name)+1)); assert (link->name != NULL); strcpy(link->name, name); link->data = data; diff --git a/thirdparty/libtiff/tif_fax3.c b/thirdparty/libtiff/tif_fax3.c index 9eec4ab7..2b2dccd0 100644 --- a/thirdparty/libtiff/tif_fax3.c +++ b/thirdparty/libtiff/tif_fax3.c @@ -1,4 +1,4 @@ -/* $Id: tif_fax3.c,v 1.43.2.10 2010-06-09 17:16:58 bfriesen Exp $ */ +/* $Id: tif_fax3.c,v 1.74 2012-06-21 02:01:31 fwarmerdam Exp $ */ /* * Copyright (c) 1990-1997 Sam Leffler @@ -48,22 +48,19 @@ * derived from this ``base state'' block. */ typedef struct { - int rw_mode; /* O_RDONLY for decode, else encode */ - int mode; /* operating mode */ - uint32 rowbytes; /* bytes in a decoded scanline */ - uint32 rowpixels; /* pixels in a scanline */ + int rw_mode; /* O_RDONLY for decode, else encode */ + int mode; /* operating mode */ + tmsize_t rowbytes; /* bytes in a decoded scanline */ + uint32 rowpixels; /* pixels in a scanline */ - uint16 cleanfaxdata; /* CleanFaxData tag */ - uint32 badfaxrun; /* BadFaxRun tag */ - uint32 badfaxlines; /* BadFaxLines tag */ - uint32 groupoptions; /* Group 3/4 options tag */ - uint32 recvparams; /* encoded Class 2 session params */ - char* subaddress; /* subaddress string */ - uint32 recvtime; /* time spent receiving (secs) */ - char* faxdcs; /* Table 2/T.30 encoded session params */ - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ - TIFFPrintMethod printdir; /* super-class method */ + uint16 cleanfaxdata; /* CleanFaxData tag */ + uint32 badfaxrun; /* BadFaxRun tag */ + uint32 badfaxlines; /* BadFaxLines tag */ + uint32 groupoptions; /* Group 3/4 options tag */ + + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ + TIFFPrintMethod printdir; /* super-class method */ } Fax3BaseState; #define Fax3State(tif) ((Fax3BaseState*) (tif)->tif_data) @@ -89,12 +86,11 @@ typedef struct { int line; } Fax3CodecState; -#define DecoderState(tif) ((Fax3CodecState*) Fax3State(tif)) -#define EncoderState(tif) ((Fax3CodecState*) Fax3State(tif)) +#define DecoderState(tif) ((Fax3CodecState*) Fax3State(tif)) +#define EncoderState(tif) ((Fax3CodecState*) Fax3State(tif)) -#define is2DEncoding(sp) \ - (sp->b.groupoptions & GROUP3OPT_2DENCODING) -#define isAligned(p,t) ((((unsigned long)(p)) & (sizeof (t)-1)) == 0) +#define is2DEncoding(sp) (sp->b.groupoptions & GROUP3OPT_2DENCODING) +#define isAligned(p,t) ((((size_t)(p)) & (sizeof (t)-1)) == 0) /* * Group 3 and Group 4 Decoding. @@ -140,15 +136,15 @@ typedef struct { sp->bit = BitsAvail; \ sp->data = BitAcc; \ sp->EOLcnt = EOLcnt; \ - tif->tif_rawcc -= (tidata_t) cp - tif->tif_rawcp; \ - tif->tif_rawcp = (tidata_t) cp; \ + tif->tif_rawcc -= (tmsize_t)((uint8*) cp - tif->tif_rawcp); \ + tif->tif_rawcp = (uint8*) cp; \ } while (0) /* * Setup state for decoding a strip. */ static int -Fax3PreDecode(TIFF* tif, tsample_t s) +Fax3PreDecode(TIFF* tif, uint16 s) { Fax3CodecState* sp = DecoderState(tif); @@ -183,10 +179,10 @@ Fax3PreDecode(TIFF* tif, tsample_t s) static void Fax3Unexpected(const char* module, TIFF* tif, uint32 line, uint32 a0) { - TIFFErrorExt(tif->tif_clientdata, module, "%s: Bad code word at line %u of %s %u (x %u)", - tif->tif_name, line, isTiled(tif) ? "tile" : "strip", - (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), - a0); + TIFFErrorExt(tif->tif_clientdata, module, "Bad code word at line %u of %s %u (x %u)", + line, isTiled(tif) ? "tile" : "strip", + (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), + a0); } #define unexpected(table, a0) Fax3Unexpected(module, tif, sp->line, a0) @@ -194,33 +190,31 @@ static void Fax3Extension(const char* module, TIFF* tif, uint32 line, uint32 a0) { TIFFErrorExt(tif->tif_clientdata, module, - "%s: Uncompressed data (not supported) at line %u of %s %u (x %u)", - tif->tif_name, line, isTiled(tif) ? "tile" : "strip", - (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), - a0); + "Uncompressed data (not supported) at line %u of %s %u (x %u)", + line, isTiled(tif) ? "tile" : "strip", + (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), + a0); } #define extension(a0) Fax3Extension(module, tif, sp->line, a0) static void Fax3BadLength(const char* module, TIFF* tif, uint32 line, uint32 a0, uint32 lastx) { - TIFFWarningExt(tif->tif_clientdata, module, "%s: %s at line %u of %s %u (got %u, expected %u)", - tif->tif_name, - a0 < lastx ? "Premature EOL" : "Line length mismatch", - line, isTiled(tif) ? "tile" : "strip", - (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), - a0, lastx); + TIFFWarningExt(tif->tif_clientdata, module, "%s at line %u of %s %u (got %u, expected %u)", + a0 < lastx ? "Premature EOL" : "Line length mismatch", + line, isTiled(tif) ? "tile" : "strip", + (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), + a0, lastx); } #define badlength(a0,lastx) Fax3BadLength(module, tif, sp->line, a0, lastx) static void Fax3PrematureEOF(const char* module, TIFF* tif, uint32 line, uint32 a0) { - TIFFWarningExt(tif->tif_clientdata, module, "%s: Premature EOF at line %u of %s %u (x %u)", - tif->tif_name, - line, isTiled(tif) ? "tile" : "strip", - (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), - a0); + TIFFWarningExt(tif->tif_clientdata, module, "Premature EOF at line %u of %s %u (x %u)", + line, isTiled(tif) ? "tile" : "strip", + (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), + a0); } #define prematureEOF(a0) Fax3PrematureEOF(module, tif, sp->line, a0) @@ -230,14 +224,18 @@ Fax3PrematureEOF(const char* module, TIFF* tif, uint32 line, uint32 a0) * Decode the requested amount of G3 1D-encoded data. */ static int -Fax3Decode1D(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) +Fax3Decode1D(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) { DECLARE_STATE(tif, sp, "Fax3Decode1D"); - (void) s; + if (occ % sp->b.rowbytes) + { + TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read"); + return (-1); + } CACHE_STATE(tif, sp); thisrun = sp->curruns; - while ((long)occ > 0) { + while (occ > 0) { a0 = 0; RunLength = 0; pa = thisrun; @@ -269,14 +267,18 @@ Fax3Decode1D(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) * Decode the requested amount of G3 2D-encoded data. */ static int -Fax3Decode2D(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) +Fax3Decode2D(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) { DECLARE_STATE_2D(tif, sp, "Fax3Decode2D"); int is1D; /* current line is 1d/2d-encoded */ - (void) s; + if (occ % sp->b.rowbytes) + { + TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read"); + return (-1); + } CACHE_STATE(tif, sp); - while ((long)occ > 0) { + while (occ > 0) { a0 = 0; RunLength = 0; pa = thisrun = sp->curruns; @@ -324,7 +326,7 @@ Fax3Decode2D(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) * this is <8 bytes. We optimize the code here to reflect the * machine characteristics. */ -#if SIZEOF_LONG == 8 +#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;\ @@ -452,6 +454,13 @@ _TIFFFax3fillruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 lastx) #undef ZERO #undef FILL +static int +Fax3FixupTags(TIFF* tif) +{ + (void) tif; + return (1); +} + /* * Setup G3/G4-related compression/decompression state * before data is processed. This routine is called once @@ -462,14 +471,16 @@ _TIFFFax3fillruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 lastx) static int Fax3SetupState(TIFF* tif) { + static const char module[] = "Fax3SetupState"; TIFFDirectory* td = &tif->tif_dir; Fax3BaseState* sp = Fax3State(tif); int needsRefLine; Fax3CodecState* dsp = (Fax3CodecState*) Fax3State(tif); - uint32 rowbytes, rowpixels, nruns; + tmsize_t rowbytes; + uint32 rowpixels, nruns; if (td->td_bitspersample != 1) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + TIFFErrorExt(tif->tif_clientdata, module, "Bits/sample must be 1 for Group 3/4 encoding/decoding"); return (0); } @@ -483,8 +494,8 @@ Fax3SetupState(TIFF* tif) rowbytes = TIFFScanlineSize(tif); rowpixels = td->td_imagewidth; } - sp->rowbytes = (uint32) rowbytes; - sp->rowpixels = (uint32) rowpixels; + sp->rowbytes = rowbytes; + sp->rowpixels = rowpixels; /* * Allocate any additional space required for decoding/encoding. */ @@ -495,11 +506,11 @@ Fax3SetupState(TIFF* tif) /* Assure that allocation computations do not overflow. - + TIFFroundup and TIFFSafeMultiply return zero on integer overflow */ dsp->runs=(uint32*) NULL; - nruns = TIFFroundup(rowpixels,32); + nruns = TIFFroundup_32(rowpixels,32); if (needsRefLine) { nruns = TIFFSafeMultiply(uint32,nruns,2); } @@ -515,6 +526,7 @@ Fax3SetupState(TIFF* tif) "for Group 3/4 run arrays"); if (dsp->runs == NULL) return (0); + memset( dsp->runs, 0, TIFFSafeMultiply(uint32,nruns,2)*sizeof(uint32)); dsp->curruns = dsp->runs; if (needsRefLine) dsp->refruns = dsp->runs + nruns; @@ -538,9 +550,8 @@ Fax3SetupState(TIFF* tif) */ esp->refline = (unsigned char*) _TIFFmalloc(rowbytes); if (esp->refline == NULL) { - TIFFErrorExt(tif->tif_clientdata, "Fax3SetupState", - "%s: No space for Group 3/4 reference line", - tif->tif_name); + TIFFErrorExt(tif->tif_clientdata, module, + "No space for Group 3/4 reference line"); return (0); } } else /* 1d encoding */ @@ -556,14 +567,14 @@ Fax3SetupState(TIFF* tif) #define Fax3FlushBits(tif, sp) { \ if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) \ (void) TIFFFlushData1(tif); \ - *(tif)->tif_rawcp++ = (tidataval_t) (sp)->data; \ + *(tif)->tif_rawcp++ = (uint8) (sp)->data; \ (tif)->tif_rawcc++; \ (sp)->data = 0, (sp)->bit = 8; \ } #define _FlushBits(tif) { \ if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) \ (void) TIFFFlushData1(tif); \ - *(tif)->tif_rawcp++ = (tidataval_t) data; \ + *(tif)->tif_rawcp++ = (uint8) data; \ (tif)->tif_rawcc++; \ data = 0, bit = 8; \ } @@ -575,6 +586,7 @@ static const int _msbmask[9] = length -= bit; \ _FlushBits(tif); \ } \ + assert( length < 9 ); \ data |= (bits & _msbmask[length]) << (bit - length); \ bit -= length; \ if (bit == 0) \ @@ -702,7 +714,7 @@ Fax3PutEOL(TIFF* tif) * Reset encoding state at the start of a strip. */ static int -Fax3PreEncode(TIFF* tif, tsample_t s) +Fax3PreEncode(TIFF* tif, uint16 s) { Fax3CodecState* sp = EncoderState(tif); @@ -792,7 +804,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; @@ -851,7 +863,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; @@ -1023,12 +1035,17 @@ Fax3Encode2DRow(TIFF* tif, unsigned char* bp, unsigned char* rp, uint32 bits) * Encode a buffer of pixels. */ static int -Fax3Encode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +Fax3Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) { + static const char module[] = "Fax3Encode"; Fax3CodecState* sp = EncoderState(tif); - (void) s; - while ((long)cc > 0) { + if (cc % sp->b.rowbytes) + { + TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be written"); + return (0); + } + while (cc > 0) { if ((sp->b.mode & FAXMODE_NOEOL) == 0) Fax3PutEOL(tif); if (is2DEncoding(sp)) { @@ -1038,7 +1055,7 @@ Fax3Encode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) sp->tag = G3_2D; } else { if (!Fax3Encode2DRow(tif, bp, sp->refline, - sp->b.rowpixels)) + sp->b.rowpixels)) return (0); sp->k--; } @@ -1100,11 +1117,6 @@ Fax3Cleanup(TIFF* tif) if (sp->refline) _TIFFfree(sp->refline); - if (Fax3State(tif)->subaddress) - _TIFFfree(Fax3State(tif)->subaddress); - if (Fax3State(tif)->faxdcs) - _TIFFfree(Fax3State(tif)->faxdcs); - _TIFFfree(tif->tif_data); tif->tif_data = NULL; @@ -1114,59 +1126,34 @@ Fax3Cleanup(TIFF* tif) #define FIELD_BADFAXLINES (FIELD_CODEC+0) #define FIELD_CLEANFAXDATA (FIELD_CODEC+1) #define FIELD_BADFAXRUN (FIELD_CODEC+2) -#define FIELD_RECVPARAMS (FIELD_CODEC+3) -#define FIELD_SUBADDRESS (FIELD_CODEC+4) -#define FIELD_RECVTIME (FIELD_CODEC+5) -#define FIELD_FAXDCS (FIELD_CODEC+6) #define FIELD_OPTIONS (FIELD_CODEC+7) -static const TIFFFieldInfo faxFieldInfo[] = { - { TIFFTAG_FAXMODE, 0, 0, TIFF_ANY, FIELD_PSEUDO, - FALSE, FALSE, "FaxMode" }, - { TIFFTAG_FAXFILLFUNC, 0, 0, TIFF_ANY, FIELD_PSEUDO, - FALSE, FALSE, "FaxFillFunc" }, - { TIFFTAG_BADFAXLINES, 1, 1, TIFF_LONG, FIELD_BADFAXLINES, - TRUE, FALSE, "BadFaxLines" }, - { TIFFTAG_BADFAXLINES, 1, 1, TIFF_SHORT, FIELD_BADFAXLINES, - TRUE, FALSE, "BadFaxLines" }, - { TIFFTAG_CLEANFAXDATA, 1, 1, TIFF_SHORT, FIELD_CLEANFAXDATA, - TRUE, FALSE, "CleanFaxData" }, - { TIFFTAG_CONSECUTIVEBADFAXLINES,1,1, TIFF_LONG, FIELD_BADFAXRUN, - TRUE, FALSE, "ConsecutiveBadFaxLines" }, - { TIFFTAG_CONSECUTIVEBADFAXLINES,1,1, TIFF_SHORT, FIELD_BADFAXRUN, - TRUE, FALSE, "ConsecutiveBadFaxLines" }, - { TIFFTAG_FAXRECVPARAMS, 1, 1, TIFF_LONG, FIELD_RECVPARAMS, - TRUE, FALSE, "FaxRecvParams" }, - { TIFFTAG_FAXSUBADDRESS, -1,-1, TIFF_ASCII, FIELD_SUBADDRESS, - TRUE, FALSE, "FaxSubAddress" }, - { TIFFTAG_FAXRECVTIME, 1, 1, TIFF_LONG, FIELD_RECVTIME, - TRUE, FALSE, "FaxRecvTime" }, - { TIFFTAG_FAXDCS, -1,-1, TIFF_ASCII, FIELD_FAXDCS, - TRUE, FALSE, "FaxDcs" }, +static const TIFFField faxFields[] = { + { TIFFTAG_FAXMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "FaxMode", NULL }, + { TIFFTAG_FAXFILLFUNC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "FaxFillFunc", NULL }, + { TIFFTAG_BADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_BADFAXLINES, TRUE, FALSE, "BadFaxLines", NULL }, + { TIFFTAG_CLEANFAXDATA, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UINT16, FIELD_CLEANFAXDATA, TRUE, FALSE, "CleanFaxData", NULL }, + { TIFFTAG_CONSECUTIVEBADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_BADFAXRUN, TRUE, FALSE, "ConsecutiveBadFaxLines", NULL }}; +static const TIFFField fax3Fields[] = { + { TIFFTAG_GROUP3OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group3Options", NULL }, }; -static const TIFFFieldInfo fax3FieldInfo[] = { - { TIFFTAG_GROUP3OPTIONS, 1, 1, TIFF_LONG, FIELD_OPTIONS, - FALSE, FALSE, "Group3Options" }, +static const TIFFField fax4Fields[] = { + { TIFFTAG_GROUP4OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group4Options", NULL }, }; -static const TIFFFieldInfo fax4FieldInfo[] = { - { TIFFTAG_GROUP4OPTIONS, 1, 1, TIFF_LONG, FIELD_OPTIONS, - FALSE, FALSE, "Group4Options" }, -}; -#define N(a) (sizeof (a) / sizeof (a[0])) static int -Fax3VSetField(TIFF* tif, ttag_t tag, va_list ap) +Fax3VSetField(TIFF* tif, uint32 tag, va_list ap) { Fax3BaseState* sp = Fax3State(tif); - const TIFFFieldInfo* fip; + const TIFFField* fip; assert(sp != 0); assert(sp->vsetparent != 0); switch (tag) { case TIFFTAG_FAXMODE: - sp->mode = va_arg(ap, int); + sp->mode = (int) va_arg(ap, int); return 1; /* NB: pseudo tag */ case TIFFTAG_FAXFILLFUNC: DecoderState(tif)->fill = va_arg(ap, TIFFFaxFillFunc); @@ -1174,39 +1161,27 @@ Fax3VSetField(TIFF* tif, ttag_t tag, va_list ap) case TIFFTAG_GROUP3OPTIONS: /* XXX: avoid reading options if compression mismatches. */ if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX3) - sp->groupoptions = va_arg(ap, uint32); + sp->groupoptions = (uint32) va_arg(ap, uint32); break; case TIFFTAG_GROUP4OPTIONS: /* XXX: avoid reading options if compression mismatches. */ if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) - sp->groupoptions = va_arg(ap, uint32); + sp->groupoptions = (uint32) va_arg(ap, uint32); break; case TIFFTAG_BADFAXLINES: - sp->badfaxlines = va_arg(ap, uint32); + sp->badfaxlines = (uint32) va_arg(ap, uint32); break; case TIFFTAG_CLEANFAXDATA: - sp->cleanfaxdata = (uint16) va_arg(ap, int); + sp->cleanfaxdata = (uint16) va_arg(ap, uint16_vap); break; case TIFFTAG_CONSECUTIVEBADFAXLINES: - sp->badfaxrun = va_arg(ap, uint32); - break; - case TIFFTAG_FAXRECVPARAMS: - sp->recvparams = va_arg(ap, uint32); - break; - case TIFFTAG_FAXSUBADDRESS: - _TIFFsetString(&sp->subaddress, va_arg(ap, char*)); - break; - case TIFFTAG_FAXRECVTIME: - sp->recvtime = va_arg(ap, uint32); - break; - case TIFFTAG_FAXDCS: - _TIFFsetString(&sp->faxdcs, va_arg(ap, char*)); + sp->badfaxrun = (uint32) va_arg(ap, uint32); break; default: return (*sp->vsetparent)(tif, tag, ap); } - if ((fip = _TIFFFieldWithTag(tif, tag))) + if ((fip = TIFFFieldWithTag(tif, tag))) TIFFSetFieldBit(tif, fip->field_bit); else return 0; @@ -1216,7 +1191,7 @@ Fax3VSetField(TIFF* tif, ttag_t tag, va_list ap) } static int -Fax3VGetField(TIFF* tif, ttag_t tag, va_list ap) +Fax3VGetField(TIFF* tif, uint32 tag, va_list ap) { Fax3BaseState* sp = Fax3State(tif); @@ -1242,18 +1217,6 @@ Fax3VGetField(TIFF* tif, ttag_t tag, va_list ap) case TIFFTAG_CONSECUTIVEBADFAXLINES: *va_arg(ap, uint32*) = sp->badfaxrun; break; - case TIFFTAG_FAXRECVPARAMS: - *va_arg(ap, uint32*) = sp->recvparams; - break; - case TIFFTAG_FAXSUBADDRESS: - *va_arg(ap, char**) = sp->subaddress; - break; - case TIFFTAG_FAXRECVTIME: - *va_arg(ap, uint32*) = sp->recvtime; - break; - case TIFFTAG_FAXDCS: - *va_arg(ap, char**) = sp->faxdcs; - break; default: return (*sp->vgetparent)(tif, tag, ap); } @@ -1310,27 +1273,20 @@ Fax3PrintDir(TIFF* tif, FILE* fd, long flags) if (TIFFFieldSet(tif,FIELD_BADFAXRUN)) fprintf(fd, " Consecutive Bad Fax Lines: %lu\n", (unsigned long) sp->badfaxrun); - if (TIFFFieldSet(tif,FIELD_RECVPARAMS)) - fprintf(fd, " Fax Receive Parameters: %08lx\n", - (unsigned long) sp->recvparams); - if (TIFFFieldSet(tif,FIELD_SUBADDRESS)) - fprintf(fd, " Fax SubAddress: %s\n", sp->subaddress); - if (TIFFFieldSet(tif,FIELD_RECVTIME)) - fprintf(fd, " Fax Receive Time: %lu secs\n", - (unsigned long) sp->recvtime); - if (TIFFFieldSet(tif,FIELD_FAXDCS)) - fprintf(fd, " Fax DCS: %s\n", sp->faxdcs); + if (sp->printdir) + (*sp->printdir)(tif, fd, flags); } static int InitCCITTFax3(TIFF* tif) { + static const char module[] = "InitCCITTFax3"; Fax3BaseState* sp; /* * Merge codec-specific tag information. */ - if (!_TIFFMergeFieldInfo(tif, faxFieldInfo, N(faxFieldInfo))) { + if (!_TIFFMergeFields(tif, faxFields, TIFFArrayCount(faxFields))) { TIFFErrorExt(tif->tif_clientdata, "InitCCITTFax3", "Merging common CCITT Fax codec-specific tags failed"); return 0; @@ -1339,12 +1295,12 @@ InitCCITTFax3(TIFF* tif) /* * Allocate state block so tag methods have storage to record values. */ - tif->tif_data = (tidata_t) + tif->tif_data = (uint8*) _TIFFmalloc(sizeof (Fax3CodecState)); if (tif->tif_data == NULL) { - TIFFErrorExt(tif->tif_clientdata, "TIFFInitCCITTFax3", - "%s: No space for state block", tif->tif_name); + TIFFErrorExt(tif->tif_clientdata, module, + "No space for state block"); return (0); } @@ -1361,9 +1317,6 @@ InitCCITTFax3(TIFF* tif) sp->printdir = tif->tif_tagmethods.printdir; tif->tif_tagmethods.printdir = Fax3PrintDir; /* hook for codec tags */ sp->groupoptions = 0; - sp->recvparams = 0; - sp->subaddress = NULL; - sp->faxdcs = NULL; if (sp->rw_mode == O_RDONLY) /* FIXME: improve for in place update */ tif->tif_flags |= TIFF_NOBITREV; /* decoder does bit reversal */ @@ -1374,6 +1327,7 @@ InitCCITTFax3(TIFF* tif) /* * Install codec methods. */ + tif->tif_fixuptags = Fax3FixupTags; tif->tif_setupdecode = Fax3SetupState; tif->tif_predecode = Fax3PreDecode; tif->tif_decoderow = Fax3Decode1D; @@ -1399,7 +1353,8 @@ TIFFInitCCITTFax3(TIFF* tif, int scheme) /* * Merge codec-specific tag information. */ - if (!_TIFFMergeFieldInfo(tif, fax3FieldInfo, N(fax3FieldInfo))) { + if (!_TIFFMergeFields(tif, fax3Fields, + TIFFArrayCount(fax3Fields))) { TIFFErrorExt(tif->tif_clientdata, "TIFFInitCCITTFax3", "Merging CCITT Fax 3 codec-specific tags failed"); return 0; @@ -1418,18 +1373,22 @@ TIFFInitCCITTFax3(TIFF* tif, int scheme) * Compression Scheme Support. */ -#define SWAP(t,a,b) { t x; x = (a); (a) = (b); (b) = x; } +#define SWAP(t,a,b) { t x; x = (a); (a) = (b); (b) = x; } /* * Decode the requested amount of G4-encoded data. */ static int -Fax4Decode(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) +Fax4Decode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) { DECLARE_STATE_2D(tif, sp, "Fax4Decode"); - (void) s; + if (occ % sp->b.rowbytes) + { + TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read"); + return (-1); + } CACHE_STATE(tif, sp); - while ((long)occ > 0) { + while (occ > 0) { a0 = 0; RunLength = 0; pa = thisrun = sp->curruns; @@ -1471,12 +1430,17 @@ Fax4Decode(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) * Encode the requested amount of data. */ static int -Fax4Encode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +Fax4Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) { + static const char module[] = "Fax4Encode"; Fax3CodecState *sp = EncoderState(tif); - (void) s; - while ((long)cc > 0) { + if (cc % sp->b.rowbytes) + { + TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be written"); + return (0); + } + while (cc > 0) { if (!Fax3Encode2DRow(tif, bp, sp->refline, sp->b.rowpixels)) return (0); _TIFFmemcpy(sp->refline, bp, sp->b.rowbytes); @@ -1507,7 +1471,8 @@ TIFFInitCCITTFax4(TIFF* tif, int scheme) /* * Merge codec-specific tag information. */ - if (!_TIFFMergeFieldInfo(tif, fax4FieldInfo, N(fax4FieldInfo))) { + if (!_TIFFMergeFields(tif, fax4Fields, + TIFFArrayCount(fax4Fields))) { TIFFErrorExt(tif->tif_clientdata, "TIFFInitCCITTFax4", "Merging CCITT Fax 4 codec-specific tags failed"); return 0; @@ -1537,15 +1502,19 @@ TIFFInitCCITTFax4(TIFF* tif, int scheme) * Decode the requested amount of RLE-encoded data. */ static int -Fax3DecodeRLE(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) +Fax3DecodeRLE(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) { DECLARE_STATE(tif, sp, "Fax3DecodeRLE"); int mode = sp->b.mode; - (void) s; + if (occ % sp->b.rowbytes) + { + TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read"); + return (-1); + } CACHE_STATE(tif, sp); thisrun = sp->curruns; - while ((long)occ > 0) { + while (occ > 0) { a0 = 0; RunLength = 0; pa = thisrun; @@ -1605,7 +1574,7 @@ TIFFInitCCITTRLEW(TIFF* tif, int scheme) if (InitCCITTFax3(tif)) { /* reuse G3 support */ tif->tif_decoderow = Fax3DecodeRLE; tif->tif_decodestrip = Fax3DecodeRLE; - tif->tif_decodetile = Fax3DecodeRLE; + tif->tif_decodetile = Fax3DecodeRLE; /* * Suppress RTC+EOLs when encoding and word-align data. */ diff --git a/thirdparty/libtiff/tif_fax3.h b/thirdparty/libtiff/tif_fax3.h index 40718bcf..b0f46c9a 100644 --- a/thirdparty/libtiff/tif_fax3.h +++ b/thirdparty/libtiff/tif_fax3.h @@ -1,4 +1,4 @@ -/* $Id: tif_fax3.h,v 1.5.2.1 2010-06-08 18:50:42 bfriesen Exp $ */ +/* $Id: tif_fax3.h,v 1.9 2011-03-10 20:23:07 fwarmerdam Exp $ */ /* * Copyright (c) 1990-1997 Sam Leffler @@ -52,7 +52,7 @@ * data in the run array as needed (e.g. to append zero runs to bring * the count up to a nice multiple). */ -typedef void (*TIFFFaxFillFunc)(unsigned char*, uint32*, uint32*, uint32); +typedef void (*TIFFFaxFillFunc)(unsigned char*, uint32*, uint32*, uint32); /* * The default run filler; made external for other decoders. @@ -60,36 +60,36 @@ typedef void (*TIFFFaxFillFunc)(unsigned char*, uint32*, uint32*, uint32); #if defined(__cplusplus) extern "C" { #endif -extern void _TIFFFax3fillruns(unsigned char*, uint32*, uint32*, uint32); +extern void _TIFFFax3fillruns(unsigned char*, uint32*, uint32*, uint32); #if defined(__cplusplus) } #endif /* finite state machine codes */ -#define S_Null 0 -#define S_Pass 1 -#define S_Horiz 2 -#define S_V0 3 -#define S_VR 4 -#define S_VL 5 -#define S_Ext 6 -#define S_TermW 7 -#define S_TermB 8 -#define S_MakeUpW 9 -#define S_MakeUpB 10 -#define S_MakeUp 11 -#define S_EOL 12 +#define S_Null 0 +#define S_Pass 1 +#define S_Horiz 2 +#define S_V0 3 +#define S_VR 4 +#define S_VL 5 +#define S_Ext 6 +#define S_TermW 7 +#define S_TermB 8 +#define S_MakeUpW 9 +#define S_MakeUpB 10 +#define S_MakeUp 11 +#define S_EOL 12 -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 */ +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 */ } TIFFFaxTabEnt; -extern const TIFFFaxTabEnt TIFFFaxMainTable[]; -extern const TIFFFaxTabEnt TIFFFaxWhiteTable[]; -extern const TIFFFaxTabEnt TIFFFaxBlackTable[]; +extern const TIFFFaxTabEnt TIFFFaxMainTable[]; +extern const TIFFFaxTabEnt TIFFFaxWhiteTable[]; +extern const TIFFFaxTabEnt TIFFFaxBlackTable[]; /* * The following macros define the majority of the G3/G4 decoder @@ -478,6 +478,12 @@ done1d: \ break; \ case S_VL: \ CHECK_b1; \ + if (b1 <= (int) (a0 + TabEnt->Param)) { \ + if (b1 < (int) (a0 + TabEnt->Param) || pa != thisrun) { \ + unexpected("VL", a0); \ + goto eol2d; \ + } \ + } \ SETVALUE(b1 - a0 - TabEnt->Param); \ b1 -= *--pb; \ break; \ diff --git a/thirdparty/libtiff/tif_flush.c b/thirdparty/libtiff/tif_flush.c index 7ecc4d83..fd14e4cd 100644 --- a/thirdparty/libtiff/tif_flush.c +++ b/thirdparty/libtiff/tif_flush.c @@ -1,4 +1,4 @@ -/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_flush.c,v 1.3.2.1 2010-06-08 18:50:42 bfriesen Exp $ */ +/* $Id: tif_flush.c,v 1.9 2010-03-31 06:40:10 fwarmerdam Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -32,15 +32,58 @@ int TIFFFlush(TIFF* tif) { + if( tif->tif_mode == O_RDONLY ) + return 1; - if (tif->tif_mode != O_RDONLY) { - if (!TIFFFlushData(tif)) - return (0); - if ((tif->tif_flags & TIFF_DIRTYDIRECT) && - !TIFFWriteDirectory(tif)) - return (0); - } - return (1); + if (!TIFFFlushData(tif)) + return (0); + + /* In update (r+) mode we try to detect the case where + only the strip/tile map has been altered, and we try to + rewrite only that portion of the directory without + making any other changes */ + + if( (tif->tif_flags & TIFF_DIRTYSTRIP) + && !(tif->tif_flags & TIFF_DIRTYDIRECT) + && tif->tif_mode == O_RDWR ) + { + uint64 *offsets=NULL, *sizes=NULL; + + if( TIFFIsTiled(tif) ) + { + if( TIFFGetField( tif, TIFFTAG_TILEOFFSETS, &offsets ) + && TIFFGetField( tif, TIFFTAG_TILEBYTECOUNTS, &sizes ) + && _TIFFRewriteField( tif, TIFFTAG_TILEOFFSETS, TIFF_LONG8, + tif->tif_dir.td_nstrips, offsets ) + && _TIFFRewriteField( tif, TIFFTAG_TILEBYTECOUNTS, TIFF_LONG8, + tif->tif_dir.td_nstrips, sizes ) ) + { + tif->tif_flags &= ~TIFF_DIRTYSTRIP; + tif->tif_flags &= ~TIFF_BEENWRITING; + return 1; + } + } + else + { + if( TIFFGetField( tif, TIFFTAG_STRIPOFFSETS, &offsets ) + && TIFFGetField( tif, TIFFTAG_STRIPBYTECOUNTS, &sizes ) + && _TIFFRewriteField( tif, TIFFTAG_STRIPOFFSETS, TIFF_LONG8, + tif->tif_dir.td_nstrips, offsets ) + && _TIFFRewriteField( tif, TIFFTAG_STRIPBYTECOUNTS, TIFF_LONG8, + tif->tif_dir.td_nstrips, sizes ) ) + { + tif->tif_flags &= ~TIFF_DIRTYSTRIP; + tif->tif_flags &= ~TIFF_BEENWRITING; + return 1; + } + } + } + + if ((tif->tif_flags & (TIFF_DIRTYDIRECT|TIFF_DIRTYSTRIP)) + && !TIFFRewriteDirectory(tif)) + return (0); + + return (1); } /* @@ -56,7 +99,7 @@ int TIFFFlushData(TIFF* tif) { if ((tif->tif_flags & TIFF_BEENWRITING) == 0) - return (0); + return (1); if (tif->tif_flags & TIFF_POSTENCODE) { tif->tif_flags &= ~TIFF_POSTENCODE; if (!(*tif->tif_postencode)(tif)) @@ -65,6 +108,7 @@ TIFFFlushData(TIFF* tif) return (TIFFFlushData1(tif)); } +/* vim: set ts=8 sts=8 sw=8 noet: */ /* * Local Variables: * mode: c diff --git a/thirdparty/libtiff/tif_getimage.c b/thirdparty/libtiff/tif_getimage.c index 38455fbc..f49b73fd 100644 --- a/thirdparty/libtiff/tif_getimage.c +++ b/thirdparty/libtiff/tif_getimage.c @@ -1,4 +1,4 @@ -/* $Id: tif_getimage.c,v 1.63.2.4 2010-06-08 18:50:42 bfriesen Exp $ */ +/* $Id: tif_getimage.c,v 1.90 2015-06-17 01:34:08 bfriesen Exp $ */ /* * Copyright (c) 1991-1997 Sam Leffler @@ -38,6 +38,10 @@ static int gtStripContig(TIFFRGBAImage*, uint32*, uint32, uint32); static int gtStripSeparate(TIFFRGBAImage*, uint32*, uint32, uint32); static int PickContigCase(TIFFRGBAImage*); static int PickSeparateCase(TIFFRGBAImage*); + +static int BuildMapUaToAa(TIFFRGBAImage* img); +static int BuildMapBitdepth16To8(TIFFRGBAImage* img); + static const char photoTag[] = "PhotometricInterpretation"; /* @@ -50,7 +54,7 @@ static const char photoTag[] = "PhotometricInterpretation"; * Color conversion constants. We will define display types here. */ -TIFFDisplay display_sRGB = { +static const TIFFDisplay display_sRGB = { { /* XYZ -> luminance matrix */ { 3.2410F, -1.5374F, -0.4986F }, { -0.9692F, 1.8760F, 0.0416F }, @@ -178,8 +182,23 @@ TIFFRGBAImageOK(TIFF* tif, char emsg[1024]) "Planarconfiguration", td->td_planarconfig); return (0); } + if( td->td_samplesperpixel != 3 ) + { + sprintf(emsg, + "Sorry, can not handle image with %s=%d", + "Samples/pixel", td->td_samplesperpixel); + return 0; + } break; case PHOTOMETRIC_CIELAB: + if( td->td_samplesperpixel != 3 || td->td_bitspersample != 8 ) + { + sprintf(emsg, + "Sorry, can not handle image with %s=%d and %s=%d", + "Samples/pixel", td->td_samplesperpixel, + "Bits/sample", td->td_bitspersample); + return 0; + } break; default: sprintf(emsg, "Sorry, can not handle image with %s=%d", @@ -202,10 +221,16 @@ TIFFRGBAImageEnd(TIFFRGBAImage* img) _TIFFfree(img->ycbcr), img->ycbcr = NULL; if (img->cielab) _TIFFfree(img->cielab), img->cielab = NULL; + if (img->UaToAa) + _TIFFfree(img->UaToAa), img->UaToAa = NULL; + if (img->Bitdepth16To8) + _TIFFfree(img->Bitdepth16To8), img->Bitdepth16To8 = NULL; + if( img->redcmap ) { _TIFFfree( img->redcmap ); _TIFFfree( img->greencmap ); _TIFFfree( img->bluecmap ); + img->redcmap = img->greencmap = img->bluecmap = NULL; } } @@ -252,7 +277,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024]) default: sprintf(emsg, "Sorry, can not handle images with %d-bit samples", img->bitspersample); - return (0); + goto fail_return; } img->alpha = 0; TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel); @@ -301,7 +326,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024]) break; default: sprintf(emsg, "Missing needed %s tag", photoTag); - return (0); + goto fail_return; } } switch (img->photometric) { @@ -309,7 +334,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024]) if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &red_orig, &green_orig, &blue_orig)) { sprintf(emsg, "Missing required \"Colormap\" tag"); - return (0); + goto fail_return; } /* copy the colormaps so we can modify them */ @@ -319,7 +344,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024]) img->bluecmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color); if( !img->redcmap || !img->greencmap || !img->bluecmap ) { sprintf(emsg, "Out of memory for colormap copy"); - return (0); + goto fail_return; } _TIFFmemcpy( img->redcmap, red_orig, n_color * 2 ); @@ -338,7 +363,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024]) photoTag, img->photometric, "Samples/pixel", img->samplesperpixel, img->bitspersample); - return (0); + goto fail_return; } break; case PHOTOMETRIC_YCBCR: @@ -371,7 +396,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024]) if (colorchannels < 3) { sprintf(emsg, "Sorry, can not handle RGB image with %s=%d", "Color channels", colorchannels); - return (0); + goto fail_return; } break; case PHOTOMETRIC_SEPARATED: @@ -381,12 +406,12 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024]) if (inkset != INKSET_CMYK) { sprintf(emsg, "Sorry, can not handle separated image with %s=%d", "InkSet", inkset); - return (0); + goto fail_return; } if (img->samplesperpixel < 4) { sprintf(emsg, "Sorry, can not handle separated image with %s=%d", "Samples/pixel", img->samplesperpixel); - return (0); + goto fail_return; } } break; @@ -394,7 +419,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024]) if (compress != COMPRESSION_SGILOG) { sprintf(emsg, "Sorry, LogL data must have %s=%d", "Compression", COMPRESSION_SGILOG); - return (0); + goto fail_return; } TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT); img->photometric = PHOTOMETRIC_MINISBLACK; /* little white lie */ @@ -404,7 +429,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024]) if (compress != COMPRESSION_SGILOG && compress != COMPRESSION_SGILOG24) { sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d", "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24); - return (0); + goto fail_return; } if (planarconfig != PLANARCONFIG_CONTIG) { sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d", @@ -420,30 +445,39 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024]) default: sprintf(emsg, "Sorry, can not handle image with %s=%d", photoTag, img->photometric); - return (0); + goto fail_return; } img->Map = NULL; img->BWmap = NULL; img->PALmap = NULL; img->ycbcr = NULL; img->cielab = NULL; + img->UaToAa = NULL; + img->Bitdepth16To8 = NULL; TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height); TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation); img->isContig = - !(planarconfig == PLANARCONFIG_SEPARATE && colorchannels > 1); + !(planarconfig == PLANARCONFIG_SEPARATE && img->samplesperpixel > 1); if (img->isContig) { if (!PickContigCase(img)) { sprintf(emsg, "Sorry, can not handle image"); - return 0; + goto fail_return; } } else { if (!PickSeparateCase(img)) { sprintf(emsg, "Sorry, can not handle image"); - return 0; + goto fail_return; } } return 1; + + fail_return: + _TIFFfree( img->redcmap ); + _TIFFfree( img->greencmap ); + _TIFFfree( img->bluecmap ); + img->redcmap = img->greencmap = img->bluecmap = NULL; + return 0; } int @@ -572,16 +606,20 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) TIFF* tif = img->tif; tileContigRoutine put = img->put.contig; uint32 col, row, y, rowstoread; - uint32 pos; + tmsize_t pos; uint32 tw, th; unsigned char* buf; int32 fromskew, toskew; uint32 nrow; int ret = 1, flip; + uint32 this_tw, tocol; + int32 this_toskew, leftmost_toskew; + int32 leftmost_fromskew; + uint32 leftmost_tw; buf = (unsigned char*) _TIFFmalloc(TIFFTileSize(tif)); if (buf == 0) { - TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer"); + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer"); return (0); } _TIFFmemset(buf, 0, TIFFTileSize(tif)); @@ -598,37 +636,50 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) toskew = -(int32)(tw - w); } + /* + * Leftmost tile is clipped on left side if col_offset > 0. + */ + leftmost_fromskew = img->col_offset % tw; + leftmost_tw = tw - leftmost_fromskew; + leftmost_toskew = toskew + leftmost_fromskew; for (row = 0; row < h; row += nrow) { rowstoread = th - (row + img->row_offset) % th; nrow = (row + rowstoread > h ? h - row : rowstoread); - for (col = 0; col < w; col += tw) + fromskew = leftmost_fromskew; + this_tw = leftmost_tw; + this_toskew = leftmost_toskew; + tocol = 0; + col = img->col_offset; + while (tocol < w) { - if (TIFFReadTile(tif, buf, col+img->col_offset, - row+img->row_offset, 0, 0) < 0 && img->stoponerr) + if (TIFFReadTile(tif, buf, col, + row+img->row_offset, 0, 0)==(tmsize_t)(-1) && img->stoponerr) { ret = 0; break; } - - pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif); - - if (col + tw > w) - { - /* - * Tile is clipped horizontally. Calculate - * visible portion and skewing factors. - */ - uint32 npix = w - col; - fromskew = tw - npix; - (*put)(img, raster+y*w+col, col, y, - npix, nrow, fromskew, toskew + fromskew, buf + pos); - } - else - { - (*put)(img, raster+y*w+col, col, y, tw, nrow, 0, toskew, buf + pos); - } - } + pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif) + \ + ((tmsize_t) fromskew * img->samplesperpixel); + if (tocol + this_tw > w) + { + /* + * Rightmost tile is clipped on right side. + */ + fromskew = tw - (w - tocol); + this_tw = tw - fromskew; + this_toskew = toskew + fromskew; + } + (*put)(img, raster+y*w+tocol, tocol, y, this_tw, nrow, fromskew, this_toskew, buf + pos); + tocol += this_tw; + col += this_tw; + /* + * After the leftmost tile, tiles are no longer clipped on left side. + */ + fromskew = 0; + this_tw = tw; + this_toskew = toskew; + } y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow); } @@ -665,26 +716,37 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) TIFF* tif = img->tif; tileSeparateRoutine put = img->put.separate; uint32 col, row, y, rowstoread; - uint32 pos; + tmsize_t pos; uint32 tw, th; unsigned char* buf; unsigned char* p0; unsigned char* p1; unsigned char* p2; unsigned char* pa; - tsize_t tilesize; + tmsize_t tilesize; + tmsize_t bufsize; int32 fromskew, toskew; int alpha = img->alpha; uint32 nrow; int ret = 1, flip; + int colorchannels; + uint32 this_tw, tocol; + int32 this_toskew, leftmost_toskew; + int32 leftmost_fromskew; + uint32 leftmost_tw; - tilesize = TIFFTileSize(tif); - buf = (unsigned char*) _TIFFmalloc((alpha?4:3)*tilesize); - if (buf == 0) { - TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer"); + tilesize = TIFFTileSize(tif); + bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,tilesize); + if (bufsize == 0) { + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtTileSeparate"); return (0); } - _TIFFmemset(buf, 0, (alpha?4:3)*tilesize); + buf = (unsigned char*) _TIFFmalloc(bufsize); + if (buf == 0) { + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer"); + return (0); + } + _TIFFmemset(buf, 0, bufsize); p0 = buf; p1 = p0 + tilesize; p2 = p1 + tilesize; @@ -702,57 +764,89 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) toskew = -(int32)(tw - w); } + switch( img->photometric ) + { + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + case PHOTOMETRIC_PALETTE: + colorchannels = 1; + p2 = p1 = p0; + break; + + default: + colorchannels = 3; + break; + } + + /* + * Leftmost tile is clipped on left side if col_offset > 0. + */ + leftmost_fromskew = img->col_offset % tw; + leftmost_tw = tw - leftmost_fromskew; + leftmost_toskew = toskew + leftmost_fromskew; for (row = 0; row < h; row += nrow) { rowstoread = th - (row + img->row_offset) % th; nrow = (row + rowstoread > h ? h - row : rowstoread); - for (col = 0; col < w; col += tw) + fromskew = leftmost_fromskew; + this_tw = leftmost_tw; + this_toskew = leftmost_toskew; + tocol = 0; + col = img->col_offset; + while (tocol < w) { - if (TIFFReadTile(tif, p0, col+img->col_offset, - row+img->row_offset,0,0) < 0 && img->stoponerr) + if (TIFFReadTile(tif, p0, col, + row+img->row_offset,0,0)==(tmsize_t)(-1) && img->stoponerr) { ret = 0; break; } - if (TIFFReadTile(tif, p1, col+img->col_offset, - row+img->row_offset,0,1) < 0 && img->stoponerr) + if (colorchannels > 1 + && TIFFReadTile(tif, p1, col, + row+img->row_offset,0,1) == (tmsize_t)(-1) + && img->stoponerr) { ret = 0; break; } - if (TIFFReadTile(tif, p2, col+img->col_offset, - row+img->row_offset,0,2) < 0 && img->stoponerr) + if (colorchannels > 1 + && TIFFReadTile(tif, p2, col, + row+img->row_offset,0,2) == (tmsize_t)(-1) + && img->stoponerr) { ret = 0; break; } - if (alpha) - { - if (TIFFReadTile(tif,pa,col+img->col_offset, - row+img->row_offset,0,3) < 0 && img->stoponerr) - { - ret = 0; - break; - } + if (alpha + && TIFFReadTile(tif,pa,col, + row+img->row_offset,0,colorchannels) == (tmsize_t)(-1) + && img->stoponerr) + { + ret = 0; + break; } - pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif); - - if (col + tw > w) + pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif) + \ + ((tmsize_t) fromskew * img->samplesperpixel); + if (tocol + this_tw > w) { /* - * Tile is clipped horizontally. Calculate - * visible portion and skewing factors. + * Rightmost tile is clipped on right side. */ - uint32 npix = w - col; - fromskew = tw - npix; - (*put)(img, raster+y*w+col, col, y, - npix, nrow, fromskew, toskew + fromskew, - p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL)); - } else { - (*put)(img, raster+y*w+col, col, y, - tw, nrow, 0, toskew, p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL)); + fromskew = tw - (w - tocol); + this_tw = tw - fromskew; + this_toskew = toskew + fromskew; } + (*put)(img, raster+y*w+tocol, tocol, y, this_tw, nrow, fromskew, this_toskew, \ + p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL)); + tocol += this_tw; + col += this_tw; + /* + * After the leftmost tile, tiles are no longer clipped on left side. + */ + fromskew = 0; + this_tw = tw; + this_toskew = toskew; } y += (flip & FLIP_VERTICALLY ?-(int32) nrow : (int32) nrow); @@ -790,15 +884,21 @@ gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) TIFF* tif = img->tif; tileContigRoutine put = img->put.contig; uint32 row, y, nrow, nrowsub, rowstoread; - uint32 pos; + tmsize_t pos; unsigned char* buf; uint32 rowsperstrip; uint16 subsamplinghor,subsamplingver; uint32 imagewidth = img->width; - tsize_t scanline; + tmsize_t scanline; int32 fromskew, toskew; int ret = 1, flip; + TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, &subsamplinghor, &subsamplingver); + if( subsamplingver == 0 ) { + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Invalid vertical YCbCr subsampling"); + return (0); + } + buf = (unsigned char*) _TIFFmalloc(TIFFStripSize(tif)); if (buf == 0) { TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for strip buffer"); @@ -816,8 +916,8 @@ gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) } TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); - TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, &subsamplinghor, &subsamplingver); - scanline = TIFFNewScanlineSize(tif); + + scanline = TIFFScanlineSize(tif); fromskew = (w < imagewidth ? imagewidth - w : 0); for (row = 0; row < h; row += nrow) { @@ -829,14 +929,15 @@ gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif,row+img->row_offset, 0), buf, - ((row + img->row_offset)%rowsperstrip + nrowsub) * scanline) < 0 + ((row + img->row_offset)%rowsperstrip + nrowsub) * scanline)==(tmsize_t)(-1) && img->stoponerr) { ret = 0; break; } - pos = ((row + img->row_offset) % rowsperstrip) * scanline; + pos = ((row + img->row_offset) % rowsperstrip) * scanline + \ + ((tmsize_t) img->col_offset * img->samplesperpixel); (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, buf + pos); y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow); } @@ -875,22 +976,28 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) unsigned char *buf; unsigned char *p0, *p1, *p2, *pa; uint32 row, y, nrow, rowstoread; - uint32 pos; - tsize_t scanline; + tmsize_t pos; + tmsize_t scanline; uint32 rowsperstrip, offset_row; uint32 imagewidth = img->width; - tsize_t stripsize; + tmsize_t stripsize; + tmsize_t bufsize; int32 fromskew, toskew; int alpha = img->alpha; - int ret = 1, flip; + int ret = 1, flip, colorchannels; - stripsize = TIFFStripSize(tif); - p0 = buf = (unsigned char *)_TIFFmalloc((alpha?4:3)*stripsize); + stripsize = TIFFStripSize(tif); + bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,stripsize); + if (bufsize == 0) { + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtStripSeparate"); + return (0); + } + p0 = buf = (unsigned char *)_TIFFmalloc(bufsize); if (buf == 0) { TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer"); return (0); } - _TIFFmemset(buf, 0, (alpha?4:3)*stripsize); + _TIFFmemset(buf, 0, bufsize); p1 = p0 + stripsize; p2 = p1 + stripsize; pa = (alpha?(p2+stripsize):NULL); @@ -905,8 +1012,22 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) toskew = -(int32)(w - w); } + switch( img->photometric ) + { + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + case PHOTOMETRIC_PALETTE: + colorchannels = 1; + p2 = p1 = p0; + break; + + default: + colorchannels = 3; + break; + } + TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); - scanline = TIFFScanlineSize(tif); + scanline = TIFFScanlineSize(tif); fromskew = (w < imagewidth ? imagewidth - w : 0); for (row = 0; row < h; row += nrow) { @@ -914,21 +1035,23 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) nrow = (row + rowstoread > h ? h - row : rowstoread); offset_row = row + img->row_offset; if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0), - p0, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0 + p0, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1) && img->stoponerr) { ret = 0; break; } - if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1), - p1, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0 + if (colorchannels > 1 + && TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1), + p1, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) == (tmsize_t)(-1) && img->stoponerr) { ret = 0; break; } - if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2), - p2, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0 + if (colorchannels > 1 + && TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2), + p2, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) == (tmsize_t)(-1) && img->stoponerr) { ret = 0; @@ -936,8 +1059,8 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) } if (alpha) { - if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 3), - pa, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0 + if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, colorchannels), + pa, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1) && img->stoponerr) { ret = 0; @@ -945,7 +1068,8 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) } } - pos = ((row + img->row_offset) % rowsperstrip) * scanline; + pos = ((row + img->row_offset) % rowsperstrip) * scanline + \ + ((tmsize_t) img->col_offset * img->samplesperpixel); (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL)); y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow); @@ -1036,6 +1160,7 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) #define PACK4(r,g,b,a) \ ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|((uint32)(a)<<24)) #define W2B(v) (((v)>>8)&0xff) +/* TODO: PACKW should have be made redundant in favor of Bitdepth16To8 LUT */ #define PACKW(r,g,b) \ ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|A1) #define PACKW4(r,g,b,a) \ @@ -1142,6 +1267,26 @@ DECLAREContigPutFunc(putgreytile) } } +/* + * 8-bit greyscale with associated alpha => colormap/RGBA + */ +DECLAREContigPutFunc(putagreytile) +{ + int samplesperpixel = img->samplesperpixel; + uint32** BWmap = img->BWmap; + + (void) y; + while (h-- > 0) { + for (x = w; x-- > 0;) + { + *cp++ = BWmap[*pp][0] & (*(pp+1) << 24 | ~A1); + pp += samplesperpixel; + } + cp += toskew; + pp += fromskew; + } +} + /* * 16-bit greyscale => colormap/RGB */ @@ -1266,11 +1411,13 @@ DECLAREContigPutFunc(putRGBUAcontig8bittile) fromskew *= samplesperpixel; while (h-- > 0) { uint32 r, g, b, a; + uint8* m; for (x = w; x-- > 0;) { a = pp[3]; - r = (a*pp[0] + 127) / 255; - g = (a*pp[1] + 127) / 255; - b = (a*pp[2] + 127) / 255; + m = img->UaToAa+(a<<8); + r = m[pp[0]]; + g = m[pp[1]]; + b = m[pp[2]]; *cp++ = PACK4(r,g,b,a); pp += samplesperpixel; } @@ -1290,8 +1437,10 @@ DECLAREContigPutFunc(putRGBcontig16bittile) fromskew *= samplesperpixel; while (h-- > 0) { for (x = w; x-- > 0;) { - *cp++ = PACKW(wp[0],wp[1],wp[2]); - wp += samplesperpixel; + *cp++ = PACK(img->Bitdepth16To8[wp[0]], + img->Bitdepth16To8[wp[1]], + img->Bitdepth16To8[wp[2]]); + wp += samplesperpixel; } cp += toskew; wp += fromskew; @@ -1310,8 +1459,11 @@ DECLAREContigPutFunc(putRGBAAcontig16bittile) fromskew *= samplesperpixel; while (h-- > 0) { for (x = w; x-- > 0;) { - *cp++ = PACKW4(wp[0],wp[1],wp[2],wp[3]); - wp += samplesperpixel; + *cp++ = PACK4(img->Bitdepth16To8[wp[0]], + img->Bitdepth16To8[wp[1]], + img->Bitdepth16To8[wp[2]], + img->Bitdepth16To8[wp[3]]); + wp += samplesperpixel; } cp += toskew; wp += fromskew; @@ -1330,13 +1482,15 @@ DECLAREContigPutFunc(putRGBUAcontig16bittile) fromskew *= samplesperpixel; while (h-- > 0) { uint32 r,g,b,a; + uint8* m; for (x = w; x-- > 0;) { - a = W2B(wp[3]); - r = (a*W2B(wp[0]) + 127) / 255; - g = (a*W2B(wp[1]) + 127) / 255; - b = (a*W2B(wp[2]) + 127) / 255; - *cp++ = PACK4(r,g,b,a); - wp += samplesperpixel; + a = img->Bitdepth16To8[wp[3]]; + m = img->UaToAa+(a<<8); + r = m[img->Bitdepth16To8[wp[0]]]; + g = m[img->Bitdepth16To8[wp[1]]]; + b = m[img->Bitdepth16To8[wp[2]]]; + *cp++ = PACK4(r,g,b,a); + wp += samplesperpixel; } cp += toskew; wp += fromskew; @@ -1423,7 +1577,7 @@ DECLARESepPutFunc(putRGBseparate8bittile) */ DECLARESepPutFunc(putRGBAAseparate8bittile) { - (void) img; (void) x; (void) y; + (void) img; (void) x; (void) y; while (h-- > 0) { UNROLL8(w, NOP, *cp++ = PACK4(*r++, *g++, *b++, *a++)); SKEW4(r, g, b, a, fromskew); @@ -1431,6 +1585,26 @@ DECLARESepPutFunc(putRGBAAseparate8bittile) } } +/* + * 8-bit unpacked CMYK samples => RGBA + */ +DECLARESepPutFunc(putCMYKseparate8bittile) +{ + (void) img; (void) y; + while (h-- > 0) { + uint32 rv, gv, bv, kv; + for (x = w; x-- > 0;) { + kv = 255 - *a++; + rv = (kv*(255-*r++))/255; + gv = (kv*(255-*g++))/255; + bv = (kv*(255-*b++))/255; + *cp++ = PACK4(rv,gv,bv,255); + } + SKEW4(r, g, b, a, fromskew); + cp += toskew; + } +} + /* * 8-bit unpacked samples => RGBA w/ unassociated alpha */ @@ -1439,11 +1613,13 @@ DECLARESepPutFunc(putRGBUAseparate8bittile) (void) img; (void) y; while (h-- > 0) { uint32 rv, gv, bv, av; + uint8* m; for (x = w; x-- > 0;) { av = *a++; - rv = (av* *r++ + 127) / 255; - gv = (av* *g++ + 127) / 255; - bv = (av* *b++ + 127) / 255; + m = img->UaToAa+(av<<8); + rv = m[*r++]; + gv = m[*g++]; + bv = m[*b++]; *cp++ = PACK4(rv,gv,bv,av); } SKEW4(r, g, b, a, fromskew); @@ -1462,7 +1638,9 @@ DECLARESepPutFunc(putRGBseparate16bittile) (void) img; (void) y; (void) a; while (h-- > 0) { for (x = 0; x < w; x++) - *cp++ = PACKW(*wr++,*wg++,*wb++); + *cp++ = PACK(img->Bitdepth16To8[*wr++], + img->Bitdepth16To8[*wg++], + img->Bitdepth16To8[*wb++]); SKEW(wr, wg, wb, fromskew); cp += toskew; } @@ -1480,7 +1658,10 @@ DECLARESepPutFunc(putRGBAAseparate16bittile) (void) img; (void) y; while (h-- > 0) { for (x = 0; x < w; x++) - *cp++ = PACKW4(*wr++,*wg++,*wb++,*wa++); + *cp++ = PACK4(img->Bitdepth16To8[*wr++], + img->Bitdepth16To8[*wg++], + img->Bitdepth16To8[*wb++], + img->Bitdepth16To8[*wa++]); SKEW4(wr, wg, wb, wa, fromskew); cp += toskew; } @@ -1498,12 +1679,14 @@ DECLARESepPutFunc(putRGBUAseparate16bittile) (void) img; (void) y; while (h-- > 0) { uint32 r,g,b,a; + uint8* m; for (x = w; x-- > 0;) { - a = W2B(*wa++); - r = (a*W2B(*wr++) + 127) / 255; - g = (a*W2B(*wg++) + 127) / 255; - b = (a*W2B(*wb++) + 127) / 255; - *cp++ = PACK4(r,g,b,a); + a = img->Bitdepth16To8[*wa++]; + m = img->UaToAa+(a<<8); + r = m[img->Bitdepth16To8[*wr++]]; + g = m[img->Bitdepth16To8[*wg++]]; + b = m[img->Bitdepth16To8[*wb++]]; + *cp++ = PACK4(r,g,b,a); } SKEW4(wr, wg, wb, wa, fromskew); cp += toskew; @@ -1728,7 +1911,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr42tile) (void) y; fromskew = (fromskew * 10) / 4; - if ((h & 3) == 0 && (w & 1) == 0) { + if ((w & 3) == 0 && (h & 1) == 0) { for (; h >= 2; h -= 2) { x = w>>2; do { @@ -1805,7 +1988,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr41tile) /* XXX adjust fromskew */ do { x = w>>2; - do { + while(x>0) { int32 Cb = pp[4]; int32 Cr = pp[5]; @@ -1816,7 +1999,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr41tile) cp += 4; pp += 6; - } while (--x); + x--; + } if( (w&3) != 0 ) { @@ -1846,6 +2030,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr41tile) DECLAREContigPutFunc(putcontig8bitYCbCr22tile) { uint32* cp2; + int32 incr = 2*toskew+w; (void) y; fromskew = (fromskew / 2) * 6; cp2 = cp+w+toskew; @@ -1872,8 +2057,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr22tile) cp2 ++ ; pp += 6; } - cp += toskew*2+w; - cp2 += toskew*2+w; + cp += incr; + cp2 += incr; pp += fromskew; h-=2; } @@ -1906,7 +2091,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr21tile) fromskew = (fromskew * 4) / 2; do { x = w>>1; - do { + while(x>0) { int32 Cb = pp[2]; int32 Cr = pp[3]; @@ -1915,7 +2100,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr21tile) cp += 2; pp += 4; - } while (--x); + x --; + } if( (w&1) != 0 ) { @@ -1939,6 +2125,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr21tile) DECLAREContigPutFunc(putcontig8bitYCbCr12tile) { uint32* cp2; + int32 incr = 2*toskew+w; (void) y; fromskew = (fromskew / 2) * 4; cp2 = cp+w+toskew; @@ -1953,8 +2140,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr12tile) cp2 ++; pp += 4; } while (--x); - cp += toskew*2+w; - cp2 += toskew*2+w; + cp += incr; + cp2 += incr; pp += fromskew; h-=2; } @@ -2016,13 +2203,13 @@ DECLARESepPutFunc(putseparate8bitYCbCr11tile) static int initYCbCrConversion(TIFFRGBAImage* img) { - static char module[] = "initYCbCrConversion"; + static const char module[] = "initYCbCrConversion"; float *luma, *refBlackWhite; if (img->ycbcr == NULL) { img->ycbcr = (TIFFYCbCrToRGB*) _TIFFmalloc( - TIFFroundup(sizeof (TIFFYCbCrToRGB), sizeof (long)) + TIFFroundup_32(sizeof (TIFFYCbCrToRGB), sizeof (long)) + 4*256*sizeof (TIFFRGBValue) + 2*256*sizeof (int) + 3*256*sizeof (int32) @@ -2045,7 +2232,7 @@ initYCbCrConversion(TIFFRGBAImage* img) static tileContigRoutine initCIELabConversion(TIFFRGBAImage* img) { - static char module[] = "initCIELabConversion"; + static const char module[] = "initCIELabConversion"; float *whitePoint; float refWhite[3]; @@ -2325,23 +2512,28 @@ PickContigCase(TIFFRGBAImage* img) img->put.contig = putRGBAAcontig8bittile; else if (img->alpha == EXTRASAMPLE_UNASSALPHA) { - img->put.contig = putRGBUAcontig8bittile; + if (BuildMapUaToAa(img)) + img->put.contig = putRGBUAcontig8bittile; } else - img->put.contig = putRGBcontig8bittile; + img->put.contig = putRGBcontig8bittile; break; case 16: if (img->alpha == EXTRASAMPLE_ASSOCALPHA) { - img->put.contig = putRGBAAcontig16bittile; + if (BuildMapBitdepth16To8(img)) + img->put.contig = putRGBAAcontig16bittile; } else if (img->alpha == EXTRASAMPLE_UNASSALPHA) { - img->put.contig = putRGBUAcontig16bittile; + if (BuildMapBitdepth16To8(img) && + BuildMapUaToAa(img)) + img->put.contig = putRGBUAcontig16bittile; } else { - img->put.contig = putRGBcontig16bittile; + if (BuildMapBitdepth16To8(img)) + img->put.contig = putRGBcontig16bittile; } break; } @@ -2382,7 +2574,10 @@ PickContigCase(TIFFRGBAImage* img) img->put.contig = put16bitbwtile; break; case 8: - img->put.contig = putgreytile; + if (img->alpha && img->samplesperpixel == 2) + img->put.contig = putagreytile; + else + img->put.contig = putgreytile; break; case 4: img->put.contig = put4bitbwtile; @@ -2397,7 +2592,7 @@ PickContigCase(TIFFRGBAImage* img) } break; case PHOTOMETRIC_YCBCR: - if (img->bitspersample == 8) + if ((img->bitspersample==8) && (img->samplesperpixel==3)) { if (initYCbCrConversion(img)!=0) { @@ -2407,7 +2602,7 @@ PickContigCase(TIFFRGBAImage* img) * must always be <= horizontal subsampling; so * there are only a few possibilities and we just * enumerate the cases. - * Joris: added support for the [1,2] case, nonetheless, to accomodate + * Joris: added support for the [1,2] case, nonetheless, to accommodate * some OJPEG files */ uint16 SubsamplingHor; @@ -2461,54 +2656,111 @@ PickSeparateCase(TIFFRGBAImage* img) img->get = TIFFIsTiled(img->tif) ? gtTileSeparate : gtStripSeparate; img->put.separate = NULL; switch (img->photometric) { - case PHOTOMETRIC_RGB: - switch (img->bitspersample) { - case 8: - if (img->alpha == EXTRASAMPLE_ASSOCALPHA) - img->put.separate = putRGBAAseparate8bittile; - else if (img->alpha == EXTRASAMPLE_UNASSALPHA) - { - img->put.separate = putRGBUAseparate8bittile; - } - else - img->put.separate = putRGBseparate8bittile; - break; - case 16: - if (img->alpha == EXTRASAMPLE_ASSOCALPHA) - { - img->put.separate = putRGBAAseparate16bittile; - } - else if (img->alpha == EXTRASAMPLE_UNASSALPHA) - { - img->put.separate = putRGBUAseparate16bittile; - } - else - { - img->put.separate = putRGBseparate16bittile; - } - break; + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + /* greyscale images processed pretty much as RGB by gtTileSeparate */ + case PHOTOMETRIC_RGB: + switch (img->bitspersample) { + case 8: + if (img->alpha == EXTRASAMPLE_ASSOCALPHA) + img->put.separate = putRGBAAseparate8bittile; + else if (img->alpha == EXTRASAMPLE_UNASSALPHA) + { + if (BuildMapUaToAa(img)) + img->put.separate = putRGBUAseparate8bittile; + } + else + img->put.separate = putRGBseparate8bittile; + break; + case 16: + if (img->alpha == EXTRASAMPLE_ASSOCALPHA) + { + if (BuildMapBitdepth16To8(img)) + img->put.separate = putRGBAAseparate16bittile; + } + else if (img->alpha == EXTRASAMPLE_UNASSALPHA) + { + if (BuildMapBitdepth16To8(img) && + BuildMapUaToAa(img)) + img->put.separate = putRGBUAseparate16bittile; + } + else + { + if (BuildMapBitdepth16To8(img)) + img->put.separate = putRGBseparate16bittile; } break; - case PHOTOMETRIC_YCBCR: - if ((img->bitspersample==8) && (img->samplesperpixel==3)) + } + break; + case PHOTOMETRIC_SEPARATED: + if (img->bitspersample == 8 && img->samplesperpixel == 4) + { + img->alpha = 1; // Not alpha, but seems like the only way to get 4th band + img->put.separate = putCMYKseparate8bittile; + } + break; + case PHOTOMETRIC_YCBCR: + if ((img->bitspersample==8) && (img->samplesperpixel==3)) + { + if (initYCbCrConversion(img)!=0) { - if (initYCbCrConversion(img)!=0) - { - uint16 hs, vs; - TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &hs, &vs); - switch ((hs<<4)|vs) { - case 0x11: - img->put.separate = putseparate8bitYCbCr11tile; - break; - /* TODO: add other cases here */ - } + uint16 hs, vs; + TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &hs, &vs); + switch ((hs<<4)|vs) { + case 0x11: + img->put.separate = putseparate8bitYCbCr11tile; + break; + /* TODO: add other cases here */ } } - break; + } + break; } return ((img->get!=NULL) && (img->put.separate!=NULL)); } +static int +BuildMapUaToAa(TIFFRGBAImage* img) +{ + static const char module[]="BuildMapUaToAa"; + uint8* m; + uint16 na,nv; + assert(img->UaToAa==NULL); + img->UaToAa=_TIFFmalloc(65536); + if (img->UaToAa==NULL) + { + TIFFErrorExt(img->tif->tif_clientdata,module,"Out of memory"); + return(0); + } + m=img->UaToAa; + for (na=0; na<256; na++) + { + for (nv=0; nv<256; nv++) + *m++=(nv*na+127)/255; + } + return(1); +} + +static int +BuildMapBitdepth16To8(TIFFRGBAImage* img) +{ + static const char module[]="BuildMapBitdepth16To8"; + uint8* m; + uint32 n; + assert(img->Bitdepth16To8==NULL); + img->Bitdepth16To8=_TIFFmalloc(65536); + if (img->Bitdepth16To8==NULL) + { + TIFFErrorExt(img->tif->tif_clientdata,module,"Out of memory"); + return(0); + } + m=img->Bitdepth16To8; + for (n=0; n<65536; n++) + *m++=(n+128)/257; + return(1); +} + + /* * Read a whole strip off data from the file, and convert to RGBA form. * If this is the last strip, then it will only contain the portion of diff --git a/thirdparty/libtiff/tif_jbig.c b/thirdparty/libtiff/tif_jbig.c index c92ee3de..37878f6e 100644 --- a/thirdparty/libtiff/tif_jbig.c +++ b/thirdparty/libtiff/tif_jbig.c @@ -1,26 +1,26 @@ -/* $Id: tif_jbig.c,v 1.2.2.3 2010-06-08 18:50:42 bfriesen Exp $ */ +/* $Id: tif_jbig.c,v 1.15 2010-03-10 18:56:48 bfriesen Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -29,7 +29,7 @@ * * JBIG Compression Algorithm Support. * Contributed by Lee Howard - * + * */ #include "tiffiop.h" @@ -37,339 +37,167 @@ #ifdef JBIG_SUPPORT #include "jbig.h" -typedef struct -{ - uint32 recvparams; /* encoded Class 2 session params */ - char* subaddress; /* subaddress string */ - uint32 recvtime; /* time spend receiving in seconds */ - char* faxdcs; /* encoded fax parameters (DCS, Table 2/T.30) */ - - TIFFVGetMethod vgetparent; - TIFFVSetMethod vsetparent; -} JBIGState; - -#define GetJBIGState(tif) ((JBIGState*)(tif)->tif_data) - -#define FIELD_RECVPARAMS (FIELD_CODEC+0) -#define FIELD_SUBADDRESS (FIELD_CODEC+1) -#define FIELD_RECVTIME (FIELD_CODEC+2) -#define FIELD_FAXDCS (FIELD_CODEC+3) - -static const TIFFFieldInfo jbigFieldInfo[] = -{ - {TIFFTAG_FAXRECVPARAMS, 1, 1, TIFF_LONG, FIELD_RECVPARAMS, TRUE, FALSE, "FaxRecvParams"}, - {TIFFTAG_FAXSUBADDRESS, -1, -1, TIFF_ASCII, FIELD_SUBADDRESS, TRUE, FALSE, "FaxSubAddress"}, - {TIFFTAG_FAXRECVTIME, 1, 1, TIFF_LONG, FIELD_RECVTIME, TRUE, FALSE, "FaxRecvTime"}, - {TIFFTAG_FAXDCS, -1, -1, TIFF_ASCII, FIELD_FAXDCS, TRUE, FALSE, "FaxDcs"}, -}; - static int JBIGSetupDecode(TIFF* tif) { - if (TIFFNumberOfStrips(tif) != 1) - { - TIFFError("JBIG", "Multistrip images not supported in decoder"); - return 0; - } + if (TIFFNumberOfStrips(tif) != 1) + { + TIFFErrorExt(tif->tif_clientdata, "JBIG", "Multistrip images not supported in decoder"); + return 0; + } - return 1; + return 1; } -static int JBIGDecode(TIFF* tif, tidata_t buffer, tsize_t size, tsample_t s) +static int JBIGDecode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s) { - struct jbg_dec_state decoder; - int decodeStatus = 0; - unsigned char* pImage = NULL; + struct jbg_dec_state decoder; + int decodeStatus = 0; + unsigned char* pImage = NULL; (void) size, (void) s; - if (isFillOrder(tif, tif->tif_dir.td_fillorder)) - { - TIFFReverseBits(tif->tif_rawdata, tif->tif_rawdatasize); - } + if (isFillOrder(tif, tif->tif_dir.td_fillorder)) + { + TIFFReverseBits(tif->tif_rawdata, tif->tif_rawdatasize); + } - jbg_dec_init(&decoder); + jbg_dec_init(&decoder); #if defined(HAVE_JBG_NEWLEN) - jbg_newlen(tif->tif_rawdata, tif->tif_rawdatasize); - /* - * I do not check the return status of jbg_newlen because even if this - * function fails it does not necessarily mean that decoding the image - * will fail. It is generally only needed for received fax images - * that do not contain the actual length of the image in the BIE - * header. I do not log when an error occurs because that will cause - * problems when converting JBIG encoded TIFF's to - * PostScript. As long as the actual image length is contained in the - * BIE header jbg_dec_in should succeed. - */ + jbg_newlen(tif->tif_rawdata, (size_t)tif->tif_rawdatasize); + /* + * I do not check the return status of jbg_newlen because even if this + * function fails it does not necessarily mean that decoding the image + * will fail. It is generally only needed for received fax images + * that do not contain the actual length of the image in the BIE + * header. I do not log when an error occurs because that will cause + * problems when converting JBIG encoded TIFF's to + * PostScript. As long as the actual image length is contained in the + * BIE header jbg_dec_in should succeed. + */ #endif /* HAVE_JBG_NEWLEN */ - decodeStatus = jbg_dec_in(&decoder, tif->tif_rawdata, - tif->tif_rawdatasize, NULL); - if (JBG_EOK != decodeStatus) - { + decodeStatus = jbg_dec_in(&decoder, (unsigned char*)tif->tif_rawdata, + (size_t)tif->tif_rawdatasize, NULL); + if (JBG_EOK != decodeStatus) + { /* * XXX: JBG_EN constant was defined in pre-2.0 releases of the * JBIG-KIT. Since the 2.0 the error reporting functions were * changed. We will handle both cases here. */ - TIFFError("JBIG", "Error (%d) decoding: %s", decodeStatus, + TIFFErrorExt(tif->tif_clientdata, + "JBIG", "Error (%d) decoding: %s", + decodeStatus, #if defined(JBG_EN) - jbg_strerror(decodeStatus, JBG_EN) + jbg_strerror(decodeStatus, JBG_EN) #else - jbg_strerror(decodeStatus) + jbg_strerror(decodeStatus) #endif - ); - return 0; - } - - pImage = jbg_dec_getimage(&decoder, 0); - _TIFFmemcpy(buffer, pImage, jbg_dec_getsize(&decoder)); - jbg_dec_free(&decoder); - return 1; + ); + return 0; + } + + pImage = jbg_dec_getimage(&decoder, 0); + _TIFFmemcpy(buffer, pImage, jbg_dec_getsize(&decoder)); + jbg_dec_free(&decoder); + return 1; } static int JBIGSetupEncode(TIFF* tif) { - if (TIFFNumberOfStrips(tif) != 1) - { - TIFFError("JBIG", "Multistrip images not supported in encoder"); - return 0; - } + if (TIFFNumberOfStrips(tif) != 1) + { + TIFFErrorExt(tif->tif_clientdata, "JBIG", "Multistrip images not supported in encoder"); + return 0; + } - return 1; + return 1; } -static int JBIGCopyEncodedData(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s) +static int JBIGCopyEncodedData(TIFF* tif, unsigned char* pp, size_t cc, uint16 s) { - (void) s; - while (cc > 0) - { - tsize_t n = cc; + (void) s; + while (cc > 0) + { + tmsize_t n = (tmsize_t)cc; - if (tif->tif_rawcc + n > tif->tif_rawdatasize) - { - n = tif->tif_rawdatasize - tif->tif_rawcc; - } + if (tif->tif_rawcc + n > tif->tif_rawdatasize) + { + n = tif->tif_rawdatasize - tif->tif_rawcc; + } - assert(n > 0); - _TIFFmemcpy(tif->tif_rawcp, pp, n); - tif->tif_rawcp += n; - tif->tif_rawcc += n; - pp += n; - cc -= n; - if (tif->tif_rawcc >= tif->tif_rawdatasize && - !TIFFFlushData1(tif)) - { - return (-1); - } - } + assert(n > 0); + _TIFFmemcpy(tif->tif_rawcp, pp, n); + tif->tif_rawcp += n; + tif->tif_rawcc += n; + pp += n; + cc -= (size_t)n; + if (tif->tif_rawcc >= tif->tif_rawdatasize && + !TIFFFlushData1(tif)) + { + return (-1); + } + } - return (1); + return (1); } -static void JBIGOutputBie(unsigned char* buffer, size_t len, void *userData) +static void JBIGOutputBie(unsigned char* buffer, size_t len, void* userData) { - TIFF* tif = (TIFF*)userData; + TIFF* tif = (TIFF*)userData; - if (isFillOrder(tif, tif->tif_dir.td_fillorder)) - { - TIFFReverseBits(buffer, len); - } + if (isFillOrder(tif, tif->tif_dir.td_fillorder)) + { + TIFFReverseBits(buffer, (tmsize_t)len); + } - JBIGCopyEncodedData(tif, buffer, len, 0); + JBIGCopyEncodedData(tif, buffer, len, 0); } -static int JBIGEncode(TIFF* tif, tidata_t buffer, tsize_t size, tsample_t s) +static int JBIGEncode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s) { - TIFFDirectory* dir = &tif->tif_dir; - struct jbg_enc_state encoder; + TIFFDirectory* dir = &tif->tif_dir; + struct jbg_enc_state encoder; (void) size, (void) s; - jbg_enc_init(&encoder, - dir->td_imagewidth, - dir->td_imagelength, - 1, - &buffer, - JBIGOutputBie, - tif); - /* - * jbg_enc_out does the "real" encoding. As data is encoded, - * JBIGOutputBie is called, which writes the data to the directory. - */ - jbg_enc_out(&encoder); - jbg_enc_free(&encoder); + jbg_enc_init(&encoder, + dir->td_imagewidth, + dir->td_imagelength, + 1, + &buffer, + JBIGOutputBie, + tif); + /* + * jbg_enc_out does the "real" encoding. As data is encoded, + * JBIGOutputBie is called, which writes the data to the directory. + */ + jbg_enc_out(&encoder); + jbg_enc_free(&encoder); - return 1; -} - -static void JBIGCleanup(TIFF* tif) -{ - JBIGState *sp = GetJBIGState(tif); - - assert(sp != 0); - - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; - - _TIFFfree(tif->tif_data); - tif->tif_data = NULL; - - _TIFFSetDefaultCompressionState(tif); -} - -static void JBIGPrintDir(TIFF* tif, FILE* fd, long flags) -{ - JBIGState* codec = GetJBIGState(tif); - (void)flags; - - if (TIFFFieldSet(tif, FIELD_RECVPARAMS)) - { - fprintf(fd, - " Fax Receive Parameters: %08lx\n", - (unsigned long)codec->recvparams); - } - - if (TIFFFieldSet(tif, FIELD_SUBADDRESS)) - { - fprintf(fd, - " Fax SubAddress: %s\n", - codec->subaddress); - } - - if (TIFFFieldSet(tif, FIELD_RECVTIME)) - { - fprintf(fd, - " Fax Receive Time: %lu secs\n", - (unsigned long)codec->recvtime); - } - - if (TIFFFieldSet(tif, FIELD_FAXDCS)) - { - fprintf(fd, - " Fax DCS: %s\n", - codec->faxdcs); - } -} - -static int JBIGVGetField(TIFF* tif, ttag_t tag, va_list ap) -{ - JBIGState* codec = GetJBIGState(tif); - - switch (tag) - { - case TIFFTAG_FAXRECVPARAMS: - *va_arg(ap, uint32*) = codec->recvparams; - break; - - case TIFFTAG_FAXSUBADDRESS: - *va_arg(ap, char**) = codec->subaddress; - break; - - case TIFFTAG_FAXRECVTIME: - *va_arg(ap, uint32*) = codec->recvtime; - break; - - case TIFFTAG_FAXDCS: - *va_arg(ap, char**) = codec->faxdcs; - break; - - default: - return (*codec->vgetparent)(tif, tag, ap); - } - - return 1; -} - -static int JBIGVSetField(TIFF* tif, ttag_t tag, va_list ap) -{ - JBIGState* codec = GetJBIGState(tif); - - switch (tag) - { - case TIFFTAG_FAXRECVPARAMS: - codec->recvparams = va_arg(ap, uint32); - break; - - case TIFFTAG_FAXSUBADDRESS: - _TIFFsetString(&codec->subaddress, va_arg(ap, char*)); - break; - - case TIFFTAG_FAXRECVTIME: - codec->recvtime = va_arg(ap, uint32); - break; - - case TIFFTAG_FAXDCS: - _TIFFsetString(&codec->faxdcs, va_arg(ap, char*)); - break; - - default: - return (*codec->vsetparent)(tif, tag, ap); - } - - TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit); - tif->tif_flags |= TIFF_DIRTYDIRECT; - return 1; + return 1; } int TIFFInitJBIG(TIFF* tif, int scheme) { - JBIGState* codec = NULL; - assert(scheme == COMPRESSION_JBIG); /* - * Merge codec-specific tag information. + * These flags are set so the JBIG Codec can control when to reverse + * bits and when not to and to allow the jbig decoder and bit reverser + * to write to memory when necessary. */ - if (!_TIFFMergeFieldInfo(tif, jbigFieldInfo, - TIFFArrayCount(jbigFieldInfo))) { - TIFFErrorExt(tif->tif_clientdata, "TIFFInitJBIG", - "Merging JBIG codec-specific tags failed"); - return 0; - } + tif->tif_flags |= TIFF_NOBITREV; + tif->tif_flags &= ~TIFF_MAPPED; - /* Allocate memory for the JBIGState structure.*/ - tif->tif_data = (tdata_t)_TIFFmalloc(sizeof(JBIGState)); - if (tif->tif_data == NULL) - { - TIFFError("TIFFInitJBIG", "Not enough memory for JBIGState"); - return 0; - } - _TIFFmemset(tif->tif_data, 0, sizeof(JBIGState)); - codec = GetJBIGState(tif); + /* Setup the function pointers for encode, decode, and cleanup. */ + tif->tif_setupdecode = JBIGSetupDecode; + tif->tif_decodestrip = JBIGDecode; - /* Initialize codec private fields */ - codec->recvparams = 0; - codec->subaddress = NULL; - codec->faxdcs = NULL; - codec->recvtime = 0; + tif->tif_setupencode = JBIGSetupEncode; + tif->tif_encodestrip = JBIGEncode; - /* - * Override parent get/set field methods. - */ - codec->vgetparent = tif->tif_tagmethods.vgetfield; - codec->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vgetfield = JBIGVGetField; - tif->tif_tagmethods.vsetfield = JBIGVSetField; - tif->tif_tagmethods.printdir = JBIGPrintDir; - - /* - * These flags are set so the JBIG Codec can control when to reverse - * bits and when not to and to allow the jbig decoder and bit reverser - * to write to memory when necessary. - */ - tif->tif_flags |= TIFF_NOBITREV; - tif->tif_flags &= ~TIFF_MAPPED; - - /* Setup the function pointers for encode, decode, and cleanup. */ - tif->tif_setupdecode = JBIGSetupDecode; - tif->tif_decodestrip = JBIGDecode; - - tif->tif_setupencode = JBIGSetupEncode; - tif->tif_encodestrip = JBIGEncode; - - tif->tif_cleanup = JBIGCleanup; - - return 1; + return 1; } #endif /* JBIG_SUPPORT */ diff --git a/thirdparty/libtiff/tif_jpeg.c b/thirdparty/libtiff/tif_jpeg.c index a967827e..d9276caf 100644 --- a/thirdparty/libtiff/tif_jpeg.c +++ b/thirdparty/libtiff/tif_jpeg.c @@ -1,4 +1,4 @@ -/* $Id: tif_jpeg.c,v 1.50.2.9 2010-06-14 02:47:16 fwarmerdam Exp $ */ +/* $Id: tif_jpeg.c,v 1.118 2015-06-10 13:17:41 bfriesen Exp $ */ /* * Copyright (c) 1994-1997 Sam Leffler @@ -44,8 +44,9 @@ */ #include -int TIFFFillStrip(TIFF*, tstrip_t); -int TIFFFillTile(TIFF*, ttile_t); +int TIFFFillStrip(TIFF* tif, uint32 strip); +int TIFFFillTile(TIFF* tif, uint32 tile); +int TIFFReInitJPEG_12( TIFF *tif, int scheme, int is_encode ); /* We undefine FAR to avoid conflict with JPEG definition */ @@ -77,7 +78,7 @@ int TIFFFillTile(TIFF*, ttile_t); */ /* Define "boolean" as unsigned char, not int, per Windows custom. */ -#if defined(WIN32) && !defined(__MINGW32__) +#if defined(__WIN32__) && !defined(__MINGW32__) # ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ typedef unsigned char boolean; # endif @@ -87,6 +88,17 @@ int TIFFFillTile(TIFF*, ttile_t); #include "jpeglib.h" #include "jerror.h" +/* + * Do we want to do special processing suitable for when JSAMPLE is a + * 16bit value? + */ + +#if defined(JPEG_LIB_MK1) +# define JPEG_LIB_MK1_OR_12BIT 1 +#elif BITS_IN_JSAMPLE == 12 +# define JPEG_LIB_MK1_OR_12BIT 1 +#endif + /* * We are using width_in_blocks which is supposed to be private to * libjpeg. Unfortunately, the libjpeg delivered with Cygwin has @@ -108,7 +120,7 @@ int TIFFFillTile(TIFF*, ttile_t); typedef struct jpeg_destination_mgr jpeg_destination_mgr; typedef struct jpeg_source_mgr jpeg_source_mgr; -typedef struct jpeg_error_mgr jpeg_error_mgr; +typedef struct jpeg_error_mgr jpeg_error_mgr; /* * State block for each open TIFF file using @@ -123,13 +135,13 @@ typedef struct jpeg_error_mgr jpeg_error_mgr; * so we can safely cast JPEGState* -> jpeg_xxx_struct* * and vice versa! */ -typedef struct { +typedef struct { union { struct jpeg_compress_struct c; struct jpeg_decompress_struct d; struct jpeg_common_struct comm; } cinfo; /* NB: must be first */ - int cinfo_initialized; + int cinfo_initialized; jpeg_error_mgr err; /* libjpeg error manager */ JMP_BUF exit_jmpbuf; /* for catching libjpeg failures */ @@ -144,7 +156,7 @@ typedef struct { uint16 photometric; /* copy of PhotometricInterpretation */ uint16 h_sampling; /* luminance sampling factors */ uint16 v_sampling; - tsize_t bytesperline; /* decompressed bytes per scanline */ + tmsize_t bytesperline; /* decompressed bytes per scanline */ /* pointers to intermediate buffers when processing downsampled data */ JSAMPARRAY ds_buffer[MAX_COMPONENTS]; int scancount; /* number of "scanlines" accumulated */ @@ -163,47 +175,25 @@ typedef struct { int jpegtablesmode; /* What to put in JPEGTables */ int ycbcrsampling_fetched; - uint32 recvparams; /* encoded Class 2 session params */ - char* subaddress; /* subaddress string */ - uint32 recvtime; /* time spent receiving (secs) */ - char* faxdcs; /* encoded fax parameters (DCS, Table 2/T.30) */ } JPEGState; #define JState(tif) ((JPEGState*)(tif)->tif_data) -static int JPEGDecode(TIFF*, tidata_t, tsize_t, tsample_t); -static int JPEGDecodeRaw(TIFF*, tidata_t, tsize_t, tsample_t); -static int JPEGEncode(TIFF*, tidata_t, tsize_t, tsample_t); -static int JPEGEncodeRaw(TIFF*, tidata_t, tsize_t, tsample_t); -static int JPEGInitializeLibJPEG( TIFF * tif, - int force_encode, int force_decode ); +static int JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s); +static int JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s); +static int JPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s); +static int JPEGEncodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s); +static int JPEGInitializeLibJPEG(TIFF * tif, int decode ); +static int DecodeRowError(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s); #define FIELD_JPEGTABLES (FIELD_CODEC+0) -#define FIELD_RECVPARAMS (FIELD_CODEC+1) -#define FIELD_SUBADDRESS (FIELD_CODEC+2) -#define FIELD_RECVTIME (FIELD_CODEC+3) -#define FIELD_FAXDCS (FIELD_CODEC+4) -static const TIFFFieldInfo jpegFieldInfo[] = { - { TIFFTAG_JPEGTABLES, -3,-3, TIFF_UNDEFINED, FIELD_JPEGTABLES, - FALSE, TRUE, "JPEGTables" }, - { TIFFTAG_JPEGQUALITY, 0, 0, TIFF_ANY, FIELD_PSEUDO, - TRUE, FALSE, "" }, - { TIFFTAG_JPEGCOLORMODE, 0, 0, TIFF_ANY, FIELD_PSEUDO, - FALSE, FALSE, "" }, - { TIFFTAG_JPEGTABLESMODE, 0, 0, TIFF_ANY, FIELD_PSEUDO, - FALSE, FALSE, "" }, - /* Specific for JPEG in faxes */ - { TIFFTAG_FAXRECVPARAMS, 1, 1, TIFF_LONG, FIELD_RECVPARAMS, - TRUE, FALSE, "FaxRecvParams" }, - { TIFFTAG_FAXSUBADDRESS, -1,-1, TIFF_ASCII, FIELD_SUBADDRESS, - TRUE, FALSE, "FaxSubAddress" }, - { TIFFTAG_FAXRECVTIME, 1, 1, TIFF_LONG, FIELD_RECVTIME, - TRUE, FALSE, "FaxRecvTime" }, - { TIFFTAG_FAXDCS, -1, -1, TIFF_ASCII, FIELD_FAXDCS, - TRUE, FALSE, "FaxDcs" }, +static const TIFFField jpegFields[] = { + { TIFFTAG_JPEGTABLES, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_C32_UINT8, FIELD_JPEGTABLES, FALSE, TRUE, "JPEGTables", NULL }, + { TIFFTAG_JPEGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL }, + { TIFFTAG_JPEGCOLORMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL }, + { TIFFTAG_JPEGTABLESMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL } }; -#define N(a) (sizeof (a) / sizeof (a[0])) /* * libjpeg interface layer. @@ -411,6 +401,19 @@ std_empty_output_buffer(j_compress_ptr cinfo) /* the entire buffer has been filled */ tif->tif_rawcc = tif->tif_rawdatasize; + +#ifdef IPPJ_HUFF + /* + * The Intel IPP performance library does not necessarily fill up + * the whole output buffer on each pass, so only dump out the parts + * that have been filled. + * http://trac.osgeo.org/gdal/wiki/JpegIPP + */ + if ( sp->dest.free_in_buffer >= 0 ) { + tif->tif_rawcc = tif->tif_rawdatasize - sp->dest.free_in_buffer; + } +#endif + TIFFFlushData1(tif); sp->dest.next_output_byte = (JOCTET*) tif->tif_rawdata; sp->dest.free_in_buffer = (size_t) tif->tif_rawdatasize; @@ -424,9 +427,9 @@ std_term_destination(j_compress_ptr cinfo) JPEGState* sp = (JPEGState*) cinfo; TIFF* tif = sp->tif; - tif->tif_rawcp = (tidata_t) sp->dest.next_output_byte; + tif->tif_rawcp = (uint8*) sp->dest.next_output_byte; tif->tif_rawcc = - tif->tif_rawdatasize - (tsize_t) sp->dest.free_in_buffer; + tif->tif_rawdatasize - (tmsize_t) sp->dest.free_in_buffer; /* NB: libtiff does the final buffer flush */ } @@ -461,8 +464,8 @@ tables_empty_output_buffer(j_compress_ptr cinfo) void* newbuf; /* the entire buffer has been filled; enlarge it by 1000 bytes */ - newbuf = _TIFFrealloc((tdata_t) sp->jpegtables, - (tsize_t) (sp->jpegtables_length + 1000)); + newbuf = _TIFFrealloc((void*) sp->jpegtables, + (tmsize_t) (sp->jpegtables_length + 1000)); if (newbuf == NULL) ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 100); sp->dest.next_output_byte = (JOCTET*) newbuf + sp->jpegtables_length; @@ -478,7 +481,7 @@ tables_term_destination(j_compress_ptr cinfo) JPEGState* sp = (JPEGState*) cinfo; /* set tables length to number of bytes actually emitted */ - sp->jpegtables_length -= sp->dest.free_in_buffer; + sp->jpegtables_length -= (uint32) sp->dest.free_in_buffer; } static int @@ -492,7 +495,7 @@ TIFFjpeg_tables_dest(JPEGState* sp, TIFF* tif) if (sp->jpegtables) _TIFFfree(sp->jpegtables); sp->jpegtables_length = 1000; - sp->jpegtables = (void*) _TIFFmalloc((tsize_t) sp->jpegtables_length); + sp->jpegtables = (void*) _TIFFmalloc((tmsize_t) sp->jpegtables_length); if (sp->jpegtables == NULL) { sp->jpegtables_length = 0; TIFFErrorExt(sp->tif->tif_clientdata, "TIFFjpeg_tables_dest", "No space for JPEGTables"); @@ -526,11 +529,29 @@ std_fill_input_buffer(j_decompress_ptr cinfo) JPEGState* sp = (JPEGState* ) cinfo; static const JOCTET dummy_EOI[2] = { 0xFF, JPEG_EOI }; +#ifdef IPPJ_HUFF + /* + * The Intel IPP performance library does not necessarily read the whole + * input buffer in one pass, so it is possible to get here with data + * yet to read. + * + * We just return without doing anything, until the entire buffer has + * been read. + * http://trac.osgeo.org/gdal/wiki/JpegIPP + */ + if( sp->src.bytes_in_buffer > 0 ) { + return (TRUE); + } +#endif + /* - * Should never get here since entire strip/tile is - * read into memory before the decompressor is called, - * and thus was supplied by init_source. + * Normally the whole strip/tile is read and so we don't need to do + * a fill. In the case of CHUNKY_STRIP_READ_SUPPORT we might not have + * all the data, but the rawdata is refreshed between scanlines and + * we push this into the io machinery in JPEGDecode(). + * http://trac.osgeo.org/gdal/ticket/3894 */ + WARNMS(cinfo, JWRN_JPEG_EOF); /* insert a fake EOI marker */ sp->src.next_input_byte = dummy_EOI; @@ -544,7 +565,7 @@ std_skip_input_data(j_decompress_ptr cinfo, long num_bytes) JPEGState* sp = (JPEGState*) cinfo; if (num_bytes > 0) { - if (num_bytes > (long) sp->src.bytes_in_buffer) { + if ((size_t)num_bytes > sp->src.bytes_in_buffer) { /* oops, buffer overrun */ (void) std_fill_input_buffer(cinfo); } else { @@ -558,8 +579,6 @@ static void std_term_source(j_decompress_ptr cinfo) { /* No work necessary here */ - /* Or must we update tif->tif_rawcp, tif->tif_rawcc ??? */ - /* (if so, need empty tables_term_source!) */ (void) cinfo; } @@ -635,13 +654,314 @@ alloc_downsampled_buffers(TIFF* tif, jpeg_component_info* comp_info, * JPEG Decoding. */ +#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING + +#define JPEG_MARKER_SOF0 0xC0 +#define JPEG_MARKER_SOF1 0xC1 +#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 +#define JPEG_MARKER_DQT 0xDB +#define JPEG_MARKER_DRI 0xDD +#define JPEG_MARKER_APP0 0xE0 +#define JPEG_MARKER_COM 0xFE +struct JPEGFixupTagsSubsamplingData +{ + TIFF* tif; + void* buffer; + uint32 buffersize; + uint8* buffercurrentbyte; + uint32 bufferbytesleft; + uint64 fileoffset; + uint64 filebytesleft; + uint8 filepositioned; +}; +static void JPEGFixupTagsSubsampling(TIFF* tif); +static int JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData* data); +static int JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData* data, uint8* result); +static int JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData* data, uint16* result); +static void JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData* data, uint16 skiplength); + +#endif + +static int +JPEGFixupTags(TIFF* tif) +{ +#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING + if ((tif->tif_dir.td_photometric==PHOTOMETRIC_YCBCR)&& + (tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)&& + (tif->tif_dir.td_samplesperpixel==3)) + JPEGFixupTagsSubsampling(tif); +#endif + + return(1); +} + +#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING + +static void +JPEGFixupTagsSubsampling(TIFF* tif) +{ + /* + * Some JPEG-in-TIFF produces do not emit the YCBCRSUBSAMPLING values in + * the TIFF tags, but still use non-default (2,2) values within the jpeg + * data stream itself. In order for TIFF applications to work properly + * - for instance to get the strip buffer size right - it is imperative + * that the subsampling be available before we start reading the image + * data normally. This function will attempt to analyze the first strip in + * order to get the sampling values from the jpeg data stream. + * + * Note that JPEGPreDeocode() will produce a fairly loud warning when the + * discovered sampling does not match the default sampling (2,2) or whatever + * was actually in the tiff tags. + * + * See the bug in bugzilla for details: + * + * http://bugzilla.remotesensing.org/show_bug.cgi?id=168 + * + * Frank Warmerdam, July 2002 + * Joris Van Damme, May 2007 + */ + static const char module[] = "JPEGFixupTagsSubsampling"; + struct JPEGFixupTagsSubsamplingData m; + + _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 + yet exist, as occurs when GDAL has created a new NULL file + for instance. */ + return; + } + + m.tif=tif; + m.buffersize=2048; + m.buffer=_TIFFmalloc(m.buffersize); + if (m.buffer==NULL) + { + TIFFWarningExt(tif->tif_clientdata,module, + "Unable to allocate memory for auto-correcting of subsampling values; auto-correcting skipped"); + return; + } + m.buffercurrentbyte=NULL; + m.bufferbytesleft=0; + m.fileoffset=tif->tif_dir.td_stripoffset[0]; + m.filepositioned=0; + m.filebytesleft=tif->tif_dir.td_stripbytecount[0]; + if (!JPEGFixupTagsSubsamplingSec(&m)) + TIFFWarningExt(tif->tif_clientdata,module, + "Unable to auto-correct subsampling values, likely corrupt JPEG compressed data in first strip/tile; auto-correcting skipped"); + _TIFFfree(m.buffer); +} + +static int +JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData* data) +{ + static const char module[] = "JPEGFixupTagsSubsamplingSec"; + uint8 m; + while (1) + { + while (1) + { + if (!JPEGFixupTagsSubsamplingReadByte(data,&m)) + return(0); + if (m==255) + break; + } + while (1) + { + if (!JPEGFixupTagsSubsamplingReadByte(data,&m)) + return(0); + if (m!=255) + break; + } + switch (m) + { + case JPEG_MARKER_SOI: + /* this type of marker has no data and should be skipped */ + break; + case JPEG_MARKER_COM: + case JPEG_MARKER_APP0: + case JPEG_MARKER_APP0+1: + case JPEG_MARKER_APP0+2: + case JPEG_MARKER_APP0+3: + case JPEG_MARKER_APP0+4: + case JPEG_MARKER_APP0+5: + case JPEG_MARKER_APP0+6: + case JPEG_MARKER_APP0+7: + case JPEG_MARKER_APP0+8: + case JPEG_MARKER_APP0+9: + case JPEG_MARKER_APP0+10: + case JPEG_MARKER_APP0+11: + case JPEG_MARKER_APP0+12: + case JPEG_MARKER_APP0+13: + case JPEG_MARKER_APP0+14: + case JPEG_MARKER_APP0+15: + case JPEG_MARKER_DQT: + case JPEG_MARKER_SOS: + case JPEG_MARKER_DHT: + case JPEG_MARKER_DRI: + /* this type of marker has data, but it has no use to us and should be skipped */ + { + uint16 n; + if (!JPEGFixupTagsSubsamplingReadWord(data,&n)) + return(0); + if (n<2) + return(0); + n-=2; + if (n>0) + JPEGFixupTagsSubsamplingSkip(data,n); + } + break; + 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; + uint16 o; + uint8 p; + uint8 ph,pv; + if (!JPEGFixupTagsSubsamplingReadWord(data,&n)) + return(0); + if (n!=8+data->tif->tif_dir.td_samplesperpixel*3) + return(0); + JPEGFixupTagsSubsamplingSkip(data,7); + if (!JPEGFixupTagsSubsamplingReadByte(data,&p)) + return(0); + ph=(p>>4); + pv=(p&15); + JPEGFixupTagsSubsamplingSkip(data,1); + for (o=1; otif->tif_dir.td_samplesperpixel; o++) + { + JPEGFixupTagsSubsamplingSkip(data,1); + if (!JPEGFixupTagsSubsamplingReadByte(data,&p)) + return(0); + if (p!=0x11) + { + TIFFWarningExt(data->tif->tif_clientdata,module, + "Subsampling values inside JPEG compressed data have no TIFF equivalent, auto-correction of TIFF subsampling values failed"); + return(1); + } + JPEGFixupTagsSubsamplingSkip(data,1); + } + if (((ph!=1)&&(ph!=2)&&(ph!=4))||((pv!=1)&&(pv!=2)&&(pv!=4))) + { + TIFFWarningExt(data->tif->tif_clientdata,module, + "Subsampling values inside JPEG compressed data have no TIFF equivalent, auto-correction of TIFF subsampling values failed"); + return(1); + } + if ((ph!=data->tif->tif_dir.td_ycbcrsubsampling[0])||(pv!=data->tif->tif_dir.td_ycbcrsubsampling[1])) + { + TIFFWarningExt(data->tif->tif_clientdata,module, + "Auto-corrected former TIFF subsampling values [%d,%d] to match subsampling values inside JPEG compressed data [%d,%d]", + (int)data->tif->tif_dir.td_ycbcrsubsampling[0], + (int)data->tif->tif_dir.td_ycbcrsubsampling[1], + (int)ph,(int)pv); + data->tif->tif_dir.td_ycbcrsubsampling[0]=ph; + data->tif->tif_dir.td_ycbcrsubsampling[1]=pv; + } + } + return(1); + default: + return(0); + } + } +} + +static int +JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData* data, uint8* result) +{ + if (data->bufferbytesleft==0) + { + uint32 m; + if (data->filebytesleft==0) + return(0); + if (!data->filepositioned) + { + TIFFSeekFile(data->tif,data->fileoffset,SEEK_SET); + data->filepositioned=1; + } + m=data->buffersize; + if ((uint64)m>data->filebytesleft) + m=(uint32)data->filebytesleft; + assert(m<0x80000000UL); + if (TIFFReadFile(data->tif,data->buffer,(tmsize_t)m)!=(tmsize_t)m) + return(0); + data->buffercurrentbyte=data->buffer; + data->bufferbytesleft=m; + data->fileoffset+=m; + data->filebytesleft-=m; + } + *result=*data->buffercurrentbyte; + data->buffercurrentbyte++; + data->bufferbytesleft--; + return(1); +} + +static int +JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData* data, uint16* result) +{ + uint8 ma; + uint8 mb; + if (!JPEGFixupTagsSubsamplingReadByte(data,&ma)) + return(0); + if (!JPEGFixupTagsSubsamplingReadByte(data,&mb)) + return(0); + *result=(ma<<8)|mb; + return(1); +} + +static void +JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData* data, uint16 skiplength) +{ + if ((uint32)skiplength<=data->bufferbytesleft) + { + data->buffercurrentbyte+=skiplength; + data->bufferbytesleft-=skiplength; + } + else + { + uint16 m; + m=skiplength-data->bufferbytesleft; + if (m<=data->filebytesleft) + { + data->bufferbytesleft=0; + data->fileoffset+=m; + data->filebytesleft-=m; + data->filepositioned=0; + } + else + { + data->bufferbytesleft=0; + data->filebytesleft=0; + } + } +} + +#endif + + static int JPEGSetupDecode(TIFF* tif) { JPEGState* sp = JState(tif); TIFFDirectory *td = &tif->tif_dir; - JPEGInitializeLibJPEG( tif, 0, 1 ); +#if defined(JPEG_DUAL_MODE_8_12) && !defined(TIFFInitJPEG) + if( tif->tif_dir.td_bitspersample == 12 ) + return TIFFReInitJPEG_12( tif, COMPRESSION_JPEG, 0 ); +#endif + + JPEGInitializeLibJPEG( tif, TRUE ); assert(sp != NULL); assert(sp->cinfo.comm.is_decompressor); @@ -678,8 +998,8 @@ JPEGSetupDecode(TIFF* tif) /* * Set up for decoding a strip or tile. */ -static int -JPEGPreDecode(TIFF* tif, tsample_t s) +/*ARGSUSED*/ static int +JPEGPreDecode(TIFF* tif, uint16 s) { JPEGState *sp = JState(tif); TIFFDirectory *td = &tif->tif_dir; @@ -689,6 +1009,12 @@ JPEGPreDecode(TIFF* tif, tsample_t s) int ci; assert(sp != NULL); + + if (sp->cinfo.comm.is_decompressor == 0) + { + tif->tif_setupdecode( tif ); + } + assert(sp->cinfo.comm.is_decompressor); /* * Reset decoder state from any previous strip/tile, @@ -699,8 +1025,13 @@ JPEGPreDecode(TIFF* tif, tsample_t s) /* * Read the header for this strip/tile. */ + if (TIFFjpeg_read_header(sp, TRUE) != JPEG_HEADER_OK) return (0); + + tif->tif_rawcp = (uint8*) sp->src.next_input_byte; + tif->tif_rawcc = sp->src.bytes_in_buffer; + /* * Check image parameters and set decompression parameters. */ @@ -713,15 +1044,15 @@ JPEGPreDecode(TIFF* tif, tsample_t s) } else { if (segment_height > td->td_rowsperstrip) segment_height = td->td_rowsperstrip; - sp->bytesperline = TIFFOldScanlineSize(tif); + sp->bytesperline = TIFFScanlineSize(tif); } if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) { /* * For PC 2, scale down the expected strip/tile size * to match a downsampled component */ - segment_width = TIFFhowmany(segment_width, sp->h_sampling); - segment_height = TIFFhowmany(segment_height, sp->v_sampling); + segment_width = TIFFhowmany_32(segment_width, sp->h_sampling); + segment_height = TIFFhowmany_32(segment_height, sp->v_sampling); } if (sp->cinfo.d.image_width < segment_width || sp->cinfo.d.image_height < segment_height) { @@ -755,65 +1086,28 @@ JPEGPreDecode(TIFF* tif, tsample_t s) } #ifdef JPEG_LIB_MK1 if (12 != td->td_bitspersample && 8 != td->td_bitspersample) { - TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG data precision"); - return (0); + TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG data precision"); + return (0); } - sp->cinfo.d.data_precision = td->td_bitspersample; - sp->cinfo.d.bits_in_jsample = td->td_bitspersample; + sp->cinfo.d.data_precision = td->td_bitspersample; + sp->cinfo.d.bits_in_jsample = td->td_bitspersample; #else if (sp->cinfo.d.data_precision != td->td_bitspersample) { - TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG data precision"); - return (0); + TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG data precision"); + return (0); } #endif 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 || sp->cinfo.d.comp_info[0].v_samp_factor != sp->v_sampling) { - TIFFWarningExt(tif->tif_clientdata, module, - "Improper JPEG sampling factors %d,%d\n" - "Apparently should be %d,%d.", - sp->cinfo.d.comp_info[0].h_samp_factor, - sp->cinfo.d.comp_info[0].v_samp_factor, - sp->h_sampling, sp->v_sampling); - - /* - * There are potential security issues here - * for decoders that have already allocated - * buffers based on the expected sampling - * factors. Lets check the sampling factors - * dont exceed what we were expecting. - */ - if (sp->cinfo.d.comp_info[0].h_samp_factor - > sp->h_sampling - || sp->cinfo.d.comp_info[0].v_samp_factor - > sp->v_sampling) { - TIFFErrorExt(tif->tif_clientdata, - module, - "Cannot honour JPEG sampling factors" - " that exceed those specified."); - return (0); - } - - /* - * XXX: Files written by the Intergraph software - * has different sampling factors stored in the - * TIFF tags and in the JPEG structures. We will - * try to deduce Intergraph files by the presense - * of the tag 33918. - */ - if (!_TIFFFindFieldInfo(tif, 33918, TIFF_ANY)) { - TIFFWarningExt(tif->tif_clientdata, module, - "Decompressor will try reading with " - "sampling %d,%d.", - sp->cinfo.d.comp_info[0].h_samp_factor, - sp->cinfo.d.comp_info[0].v_samp_factor); - - sp->h_sampling = (uint16) - sp->cinfo.d.comp_info[0].h_samp_factor; - sp->v_sampling = (uint16) - sp->cinfo.d.comp_info[0].v_samp_factor; - } + TIFFErrorExt(tif->tif_clientdata, module, + "Improper JPEG sampling factors %d,%d\n" + "Apparently should be %d,%d.", + sp->cinfo.d.comp_info[0].h_samp_factor, + sp->cinfo.d.comp_info[0].v_samp_factor, + sp->h_sampling, sp->v_sampling); + return (0); } /* Rest should have sampling factors 1,1 */ for (ci = 1; ci < sp->cinfo.d.num_components; ci++) { @@ -835,11 +1129,11 @@ JPEGPreDecode(TIFF* tif, tsample_t s) if (td->td_planarconfig == PLANARCONFIG_CONTIG && sp->photometric == PHOTOMETRIC_YCBCR && sp->jpegcolormode == JPEGCOLORMODE_RGB) { - /* Convert YCbCr to RGB */ + /* Convert YCbCr to RGB */ sp->cinfo.d.jpeg_color_space = JCS_YCbCr; sp->cinfo.d.out_color_space = JCS_RGB; } else { - /* Suppress colorspace handling */ + /* Suppress colorspace handling */ sp->cinfo.d.jpeg_color_space = JCS_UNKNOWN; sp->cinfo.d.out_color_space = JCS_UNKNOWN; if (td->td_planarconfig == PLANARCONFIG_CONTIG && @@ -850,7 +1144,10 @@ JPEGPreDecode(TIFF* tif, tsample_t s) if (downsampled_output) { /* Need to use raw-data interface to libjpeg */ sp->cinfo.d.raw_data_out = TRUE; - tif->tif_decoderow = JPEGDecodeRaw; +#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; } else { @@ -858,7 +1155,7 @@ JPEGPreDecode(TIFF* tif, tsample_t s) sp->cinfo.d.raw_data_out = FALSE; tif->tif_decoderow = JPEGDecode; tif->tif_decodestrip = JPEGDecode; - tif->tif_decodetile = JPEGDecode; + tif->tif_decodetile = JPEGDecode; } /* Start JPEG decompressor */ if (!TIFFjpeg_start_decompress(sp)) @@ -877,104 +1174,179 @@ JPEGPreDecode(TIFF* tif, tsample_t s) * Decode a chunk of pixels. * "Standard" case: returned data is not downsampled. */ -/*ARGSUSED*/ static int -JPEGDecode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) +#if !JPEG_LIB_MK1_OR_12BIT +static int +JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) { - JPEGState *sp = JState(tif); - tsize_t nrows; - (void) s; - - nrows = cc / sp->bytesperline; - if (cc % sp->bytesperline) - TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "fractional scanline not read"); - - if( nrows > (int) sp->cinfo.d.image_height ) - nrows = sp->cinfo.d.image_height; - - /* data is expected to be read in multiples of a scanline */ - if (nrows) - { - JSAMPROW line_work_buf = NULL; + JPEGState *sp = JState(tif); + tmsize_t nrows; + (void) s; /* - ** For 6B, only use temporary buffer for 12 bit imagery. - ** For Mk1 always use it. + ** Update available information, buffer may have been refilled + ** between decode requests */ -#if !defined(JPEG_LIB_MK1) - if( sp->cinfo.d.data_precision == 12 ) -#endif + 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) { - line_work_buf = (JSAMPROW) - _TIFFmalloc(sizeof(short) * sp->cinfo.d.output_width - * sp->cinfo.d.num_components ); + 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); } - 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. - */ - if (TIFFjpeg_read_scanlines(sp, &line_work_buf, 1) != 1) - return (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) +{ + 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) + { + JSAMPROW line_work_buf = NULL; + + /* + * For 6B, only use temporary buffer for 12 bit imagery. + * For Mk1 always use it. + */ if( sp->cinfo.d.data_precision == 12 ) { - int value_pairs = (sp->cinfo.d.output_width - * sp->cinfo.d.num_components) / 2; - int iPair; - - for( iPair = 0; iPair < value_pairs; iPair++ ) - { - unsigned char *out_ptr = - ((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); - } + line_work_buf = (JSAMPROW) + _TIFFmalloc(sizeof(short) * sp->cinfo.d.output_width + * sp->cinfo.d.num_components ); } - else if( sp->cinfo.d.data_precision == 8 ) - { - int value_count = (sp->cinfo.d.output_width - * sp->cinfo.d.num_components); - int iValue; - for( iValue = 0; iValue < value_count; iValue++ ) - { - ((unsigned char *) buf)[iValue] = - line_work_buf[iValue] & 0xff; - } - } - } - 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); - } + 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. + */ + if (TIFFjpeg_read_scanlines(sp, &line_work_buf, 1) != 1) + return (0); - ++tif->tif_row; - buf += sp->bytesperline; - cc -= sp->bytesperline; - } while (--nrows > 0); + if( sp->cinfo.d.data_precision == 12 ) + { + int value_pairs = (sp->cinfo.d.output_width + * sp->cinfo.d.num_components) / 2; + int iPair; - if( line_work_buf != NULL ) - _TIFFfree( line_work_buf ); - } + for( iPair = 0; iPair < value_pairs; iPair++ ) + { + unsigned char *out_ptr = + ((unsigned char *) buf) + iPair * 3; + JSAMPLE *in_ptr = line_work_buf + iPair * 2; - /* 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); + 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); + } + } + else if( sp->cinfo.d.data_precision == 8 ) + { + int value_count = (sp->cinfo.d.output_width + * sp->cinfo.d.num_components); + int iValue; + + for( iValue = 0; iValue < value_count; iValue++ ) + { + ((unsigned char *) buf)[iValue] = + line_work_buf[iValue] & 0xff; + } + } + } + + ++tif->tif_row; + buf += sp->bytesperline; + cc -= sp->bytesperline; + } while (--nrows > 0); + + if( line_work_buf != NULL ) + _TIFFfree( line_work_buf ); + } + + /* 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 */ + +/*ARGSUSED*/ static int +DecodeRowError(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) + +{ + (void) buf; + (void) cc; + (void) s; + + TIFFErrorExt(tif->tif_clientdata, "TIFFReadScanline", + "scanline oriented access is not supported for downsampled JPEG compressed images, consider enabling TIFF_JPEGCOLORMODE as JPEGCOLORMODE_RGB." ); + return 0; } /* @@ -982,28 +1354,40 @@ JPEGDecode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) * Returned data is downsampled per sampling factors. */ /*ARGSUSED*/ static int -JPEGDecodeRaw(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) +JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) { JPEGState *sp = JState(tif); - tsize_t nrows; + tmsize_t nrows; (void) s; /* data is expected to be read in multiples of a scanline */ if ( (nrows = sp->cinfo.d.image_height) ) { + /* Cb,Cr both have sampling factors 1, so this is correct */ JDIMENSION clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width; int samples_per_clump = sp->samplesperclump; -#ifdef JPEG_LIB_MK1 +#if defined(JPEG_LIB_MK1_OR_12BIT) unsigned short* tmpbuf = _TIFFmalloc(sizeof(unsigned short) * - sp->cinfo.d.output_width * - sp->cinfo.d.num_components); + sp->cinfo.d.output_width * + sp->cinfo.d.num_components); + if(tmpbuf==NULL) { + TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw", + "Out of memory"); + return 0; + } #endif do { jpeg_component_info *compptr; int ci, clumpoffset; + if( cc < sp->bytesperline ) { + TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw", + "application buffer not large enough for all data."); + return 0; + } + /* Reload downsampled-data buffer if needed */ if (sp->scancount >= DCTSIZE) { int n = sp->cinfo.d.max_v_samp_factor * DCTSIZE; @@ -1017,20 +1401,25 @@ JPEGDecodeRaw(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) */ clumpoffset = 0; /* first sample in clump */ for (ci = 0, compptr = sp->cinfo.d.comp_info; - ci < sp->cinfo.d.num_components; - ci++, compptr++) { + ci < sp->cinfo.d.num_components; + ci++, compptr++) { int hsamp = compptr->h_samp_factor; int vsamp = compptr->v_samp_factor; int ypos; for (ypos = 0; ypos < vsamp; ypos++) { JSAMPLE *inptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos]; -#ifdef JPEG_LIB_MK1 + JDIMENSION nclump; +#if defined(JPEG_LIB_MK1_OR_12BIT) JSAMPLE *outptr = (JSAMPLE*)tmpbuf + clumpoffset; #else JSAMPLE *outptr = (JSAMPLE*)buf + clumpoffset; + 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; + } #endif - JDIMENSION nclump; if (hsamp == 1) { /* fast path for at least Cb and Cr */ @@ -1041,7 +1430,7 @@ JPEGDecodeRaw(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) } else { int xpos; - /* general case */ + /* general case */ for (nclump = clumps_per_line; nclump-- > 0; ) { for (xpos = 0; xpos < hsamp; xpos++) outptr[xpos] = *inptr++; @@ -1052,7 +1441,7 @@ JPEGDecodeRaw(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) } } -#ifdef JPEG_LIB_MK1 +#if defined(JPEG_LIB_MK1_OR_12BIT) { if (sp->cinfo.d.data_precision == 8) { @@ -1064,17 +1453,17 @@ JPEGDecodeRaw(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) } } else - { // 12-bit + { /* 12-bit */ int value_pairs = (sp->cinfo.d.output_width - * sp->cinfo.d.num_components) / 2; + * sp->cinfo.d.num_components) / 2; int iPair; for( iPair = 0; iPair < value_pairs; iPair++ ) { unsigned char *out_ptr = ((unsigned char *) buf) + iPair * 3; - JSAMPLE *in_ptr = tmpbuf + iPair * 2; + 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); + | ((in_ptr[1] & 0xf00) >> 8); out_ptr[2] = ((in_ptr[1] & 0xff) >> 0); } } @@ -1083,14 +1472,14 @@ JPEGDecodeRaw(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) sp->scancount ++; tif->tif_row += sp->v_sampling; - /* increment/decrement of buf and cc is still incorrect, but should not matter - * TODO: resolve this */ + buf += sp->bytesperline; cc -= sp->bytesperline; + nrows -= sp->v_sampling; } while (nrows > 0); -#ifdef JPEG_LIB_MK1 +#if defined(JPEG_LIB_MK1_OR_12BIT) _TIFFfree(tmpbuf); #endif @@ -1098,7 +1487,7 @@ JPEGDecodeRaw(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) /* Close down the decompressor if done. */ return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height - || TIFFjpeg_finish_decompress(sp); + || TIFFjpeg_finish_decompress(sp); } @@ -1115,6 +1504,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) { @@ -1126,13 +1524,22 @@ 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) { JPEGState* sp = JState(tif); - JPEGInitializeLibJPEG( tif, 0, 0 ); - /* Initialize quant tables for current quality setting */ if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE)) return (0); @@ -1167,22 +1574,48 @@ JPEGSetupEncode(TIFF* tif) TIFFDirectory *td = &tif->tif_dir; static const char module[] = "JPEGSetupEncode"; - JPEGInitializeLibJPEG( tif, 1, 0 ); +#if defined(JPEG_DUAL_MODE_8_12) && !defined(TIFFInitJPEG) + if( tif->tif_dir.td_bitspersample == 12 ) + return TIFFReInitJPEG_12( tif, COMPRESSION_JPEG, 1 ); +#endif + + JPEGInitializeLibJPEG( tif, FALSE ); 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. */ - sp->cinfo.c.in_color_space = JCS_UNKNOWN; - sp->cinfo.c.input_components = 1; + 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]; @@ -1295,7 +1728,7 @@ JPEGSetupEncode(TIFF* tif) * Set encoding state at the start of a strip or tile. */ static int -JPEGPreEncode(TIFF* tif, tsample_t s) +JPEGPreEncode(TIFF* tif, uint16 s) { JPEGState *sp = JState(tif); TIFFDirectory *td = &tif->tif_dir; @@ -1304,6 +1737,12 @@ JPEGPreEncode(TIFF* tif, tsample_t s) int downsampled_input; assert(sp != NULL); + + if (sp->cinfo.comm.is_decompressor == 1) + { + tif->tif_setupencode( tif ); + } + assert(!sp->cinfo.comm.is_decompressor); /* * Set encoding parameters for this strip/tile. @@ -1317,14 +1756,14 @@ JPEGPreEncode(TIFF* tif, tsample_t s) segment_height = td->td_imagelength - tif->tif_row; if (segment_height > td->td_rowsperstrip) segment_height = td->td_rowsperstrip; - sp->bytesperline = TIFFOldScanlineSize(tif); + sp->bytesperline = TIFFScanlineSize(tif); } if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) { /* for PC 2, scale down the strip/tile size * to match a downsampled component */ - segment_width = TIFFhowmany(segment_width, sp->h_sampling); - segment_height = TIFFhowmany(segment_height, sp->v_sampling); + segment_width = TIFFhowmany_32(segment_width, sp->h_sampling); + segment_height = TIFFhowmany_32(segment_height, sp->v_sampling); } if (segment_width > 65535 || segment_height > 65535) { TIFFErrorExt(tif->tif_clientdata, module, "Strip/tile too large for JPEG"); @@ -1336,10 +1775,7 @@ JPEGPreEncode(TIFF* tif, tsample_t 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; } @@ -1352,14 +1788,11 @@ JPEGPreEncode(TIFF* tif, tsample_t 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 { - sp->cinfo.c.in_color_space = JCS_UNKNOWN; - if (!TIFFjpeg_set_colorspace(sp, 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; @@ -1374,14 +1807,30 @@ JPEGPreEncode(TIFF* tif, tsample_t s) sp->cinfo.c.write_JFIF_header = FALSE; sp->cinfo.c.write_Adobe_marker = FALSE; /* set up table handling correctly */ - if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE)) - return (0); - if (! (sp->jpegtablesmode & JPEGTABLESMODE_QUANT)) { + /* 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) { + 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) { @@ -1416,31 +1865,69 @@ JPEGPreEncode(TIFF* tif, tsample_t s) * "Standard" case: incoming data is not downsampled. */ static int -JPEGEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) +JPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) { JPEGState *sp = JState(tif); - tsize_t nrows; + tmsize_t nrows; JSAMPROW bufptr[1]; + short *line16 = NULL; + int line16_count = 0; (void) s; assert(sp != NULL); /* data is expected to be supplied in multiples of a scanline */ nrows = cc / sp->bytesperline; if (cc % sp->bytesperline) - TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "fractional scanline discarded"); + TIFFWarningExt(tif->tif_clientdata, tif->tif_name, + "fractional scanline discarded"); /* The last strip will be limited to image size */ if( !isTiled(tif) && tif->tif_row+nrows > tif->tif_dir.td_imagelength ) nrows = tif->tif_dir.td_imagelength - tif->tif_row; + if( sp->cinfo.c.data_precision == 12 ) + { + line16_count = (sp->bytesperline * 2) / 3; + line16 = (short *) _TIFFmalloc(sizeof(short) * line16_count); + // FIXME: undiagnosed malloc failure + } + while (nrows-- > 0) { + + if( sp->cinfo.c.data_precision == 12 ) + { + + int value_pairs = line16_count / 2; + int iPair; + + bufptr[0] = (JSAMPROW) line16; + + for( iPair = 0; iPair < value_pairs; iPair++ ) + { + unsigned char *in_ptr = + ((unsigned char *) buf) + iPair * 3; + JSAMPLE *out_ptr = (JSAMPLE *) (line16 + iPair * 2); + + out_ptr[0] = (in_ptr[0] << 4) | ((in_ptr[1] & 0xf0) >> 4); + out_ptr[1] = ((in_ptr[1] & 0x0f) << 8) | in_ptr[2]; + } + } + else + { bufptr[0] = (JSAMPROW) buf; - if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1) - return (0); - if (nrows > 0) - tif->tif_row++; - buf += sp->bytesperline; + } + if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1) + return (0); + if (nrows > 0) + tif->tif_row++; + buf += sp->bytesperline; } + + if( sp->cinfo.c.data_precision == 12 ) + { + _TIFFfree( line16 ); + } + return (1); } @@ -1449,17 +1936,17 @@ JPEGEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) * Incoming data is expected to be downsampled per sampling factors. */ static int -JPEGEncodeRaw(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) +JPEGEncodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) { JPEGState *sp = JState(tif); JSAMPLE* inptr; JSAMPLE* outptr; - tsize_t nrows; + tmsize_t nrows; JDIMENSION clumps_per_line, nclump; int clumpoffset, ci, xpos, ypos; jpeg_component_info* compptr; int samples_per_clump = sp->samplesperclump; - tsize_t bytesperclumpline; + tmsize_t bytesperclumpline; (void) s; assert(sp != NULL); @@ -1523,7 +2010,7 @@ JPEGEncodeRaw(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) sp->scancount = 0; } tif->tif_row += sp->v_sampling; - buf += sp->bytesperline; + buf += bytesperclumpline; nrows -= sp->v_sampling; } return (1); @@ -1549,12 +2036,12 @@ JPEGPostEncode(TIFF* tif) ci < sp->cinfo.c.num_components; ci++, compptr++) { int vsamp = compptr->v_samp_factor; - tsize_t row_width = compptr->width_in_blocks * DCTSIZE + tmsize_t row_width = compptr->width_in_blocks * DCTSIZE * sizeof(JSAMPLE); for (ypos = sp->scancount * vsamp; ypos < DCTSIZE * vsamp; ypos++) { - _TIFFmemcpy((tdata_t)sp->ds_buffer[ci][ypos], - (tdata_t)sp->ds_buffer[ci][ypos-1], + _TIFFmemcpy((void*)sp->ds_buffer[ci][ypos], + (void*)sp->ds_buffer[ci][ypos-1], row_width); } @@ -1577,11 +2064,10 @@ JPEGCleanup(TIFF* tif) tif->tif_tagmethods.vgetfield = sp->vgetparent; tif->tif_tagmethods.vsetfield = sp->vsetparent; tif->tif_tagmethods.printdir = sp->printdir; - - if( sp->cinfo_initialized ) - TIFFjpeg_destroy(sp); /* release libjpeg resources */ - if (sp->jpegtables) /* tag value */ - _TIFFfree(sp->jpegtables); + 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; @@ -1618,24 +2104,23 @@ JPEGResetUpsampled( TIFF* tif ) * Should we really be doing this now if image size isn't set? */ if( tif->tif_tilesize > 0 ) - tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tsize_t) -1; - - if(tif->tif_scanlinesize > 0 ) + tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1); + if( tif->tif_scanlinesize > 0 ) tif->tif_scanlinesize = TIFFScanlineSize(tif); } static int -JPEGVSetField(TIFF* tif, ttag_t tag, va_list ap) +JPEGVSetField(TIFF* tif, uint32 tag, va_list ap) { JPEGState* sp = JState(tif); - const TIFFFieldInfo* fip; + const TIFFField* fip; uint32 v32; assert(sp != NULL); switch (tag) { case TIFFTAG_JPEGTABLES: - v32 = va_arg(ap, uint32); + v32 = (uint32) va_arg(ap, uint32); if (v32 == 0) { /* XXX */ return (0); @@ -1646,43 +2131,31 @@ JPEGVSetField(TIFF* tif, ttag_t tag, va_list ap) TIFFSetFieldBit(tif, FIELD_JPEGTABLES); break; case TIFFTAG_JPEGQUALITY: - sp->jpegquality = va_arg(ap, int); + sp->jpegquality = (int) va_arg(ap, int); return (1); /* pseudo tag */ case TIFFTAG_JPEGCOLORMODE: - sp->jpegcolormode = va_arg(ap, int); - JPEGResetUpsampled( tif ); + sp->jpegcolormode = (int) va_arg(ap, int); + JPEGResetUpsampled( tif ); return (1); /* pseudo tag */ case TIFFTAG_PHOTOMETRIC: - { - int ret_value = (*sp->vsetparent)(tif, tag, ap); - JPEGResetUpsampled( tif ); - return ret_value; - } + { + int ret_value = (*sp->vsetparent)(tif, tag, ap); + JPEGResetUpsampled( tif ); + return ret_value; + } case TIFFTAG_JPEGTABLESMODE: - sp->jpegtablesmode = va_arg(ap, int); + sp->jpegtablesmode = (int) va_arg(ap, int); return (1); /* pseudo tag */ case TIFFTAG_YCBCRSUBSAMPLING: - /* mark the fact that we have a real ycbcrsubsampling! */ + /* mark the fact that we have a real ycbcrsubsampling! */ sp->ycbcrsampling_fetched = 1; - /* should we be recomputing upsampling info here? */ + /* should we be recomputing upsampling info here? */ return (*sp->vsetparent)(tif, tag, ap); - case TIFFTAG_FAXRECVPARAMS: - sp->recvparams = va_arg(ap, uint32); - break; - case TIFFTAG_FAXSUBADDRESS: - _TIFFsetString(&sp->subaddress, va_arg(ap, char*)); - break; - case TIFFTAG_FAXRECVTIME: - sp->recvtime = va_arg(ap, uint32); - break; - case TIFFTAG_FAXDCS: - _TIFFsetString(&sp->faxdcs, va_arg(ap, char*)); - break; default: return (*sp->vsetparent)(tif, tag, ap); } - if ((fip = _TIFFFieldWithTag(tif, tag))) { + if ((fip = TIFFFieldWithTag(tif, tag))) { TIFFSetFieldBit(tif, fip->field_bit); } else { return (0); @@ -1692,83 +2165,8 @@ JPEGVSetField(TIFF* tif, ttag_t tag, va_list ap) return (1); } -/* - * Some JPEG-in-TIFF produces do not emit the YCBCRSUBSAMPLING values in - * the TIFF tags, but still use non-default (2,2) values within the jpeg - * data stream itself. In order for TIFF applications to work properly - * - for instance to get the strip buffer size right - it is imperative - * that the subsampling be available before we start reading the image - * data normally. This function will attempt to load the first strip in - * order to get the sampling values from the jpeg data stream. Various - * hacks are various places are done to ensure this function gets called - * before the td_ycbcrsubsampling values are used from the directory structure, - * including calling TIFFGetField() for the YCBCRSUBSAMPLING field from - * TIFFStripSize(), and the printing code in tif_print.c. - * - * Note that JPEGPreDeocode() will produce a fairly loud warning when the - * discovered sampling does not match the default sampling (2,2) or whatever - * was actually in the tiff tags. - * - * Problems: - * o This code will cause one whole strip/tile of compressed data to be - * loaded just to get the tags right, even if the imagery is never read. - * It would be more efficient to just load a bit of the header, and - * initialize things from that. - * - * See the bug in bugzilla for details: - * - * http://bugzilla.remotesensing.org/show_bug.cgi?id=168 - * - * Frank Warmerdam, July 2002 - */ - -static void -JPEGFixupTestSubsampling( TIFF * tif ) -{ -#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING - JPEGState *sp = JState(tif); - TIFFDirectory *td = &tif->tif_dir; - - JPEGInitializeLibJPEG( tif, 0, 0 ); - - /* - * Some JPEG-in-TIFF files don't provide the ycbcrsampling tags, - * and use a sampling schema other than the default 2,2. To handle - * this we actually have to scan the header of a strip or tile of - * jpeg data to get the sampling. - */ - if( !sp->cinfo.comm.is_decompressor - || sp->ycbcrsampling_fetched - || td->td_photometric != PHOTOMETRIC_YCBCR ) - return; - - sp->ycbcrsampling_fetched = 1; - if( TIFFIsTiled( tif ) ) - { - if( !TIFFFillTile( tif, 0 ) ) - return; - } - else - { - if( !TIFFFillStrip( tif, 0 ) ) - return; - } - - TIFFSetField( tif, TIFFTAG_YCBCRSUBSAMPLING, - (uint16) sp->h_sampling, (uint16) sp->v_sampling ); - - /* - ** We want to clear the loaded strip so the application has time - ** to set JPEGCOLORMODE or other behavior modifiers. This essentially - ** undoes the JPEGPreDecode triggers by TIFFFileStrip(). (#1936) - */ - tif->tif_curstrip = -1; - -#endif /* CHECK_JPEG_YCBCR_SUBSAMPLING */ -} - static int -JPEGVGetField(TIFF* tif, ttag_t tag, va_list ap) +JPEGVGetField(TIFF* tif, uint32 tag, va_list ap) { JPEGState* sp = JState(tif); @@ -1788,21 +2186,6 @@ JPEGVGetField(TIFF* tif, ttag_t tag, va_list ap) case TIFFTAG_JPEGTABLESMODE: *va_arg(ap, int*) = sp->jpegtablesmode; break; - case TIFFTAG_YCBCRSUBSAMPLING: - JPEGFixupTestSubsampling( tif ); - return (*sp->vgetparent)(tif, tag, ap); - case TIFFTAG_FAXRECVPARAMS: - *va_arg(ap, uint32*) = sp->recvparams; - break; - case TIFFTAG_FAXSUBADDRESS: - *va_arg(ap, char**) = sp->subaddress; - break; - case TIFFTAG_FAXRECVTIME: - *va_arg(ap, uint32*) = sp->recvtime; - break; - case TIFFTAG_FAXDCS: - *va_arg(ap, char**) = sp->faxdcs; - break; default: return (*sp->vgetparent)(tif, tag, ap); } @@ -1815,21 +2198,15 @@ JPEGPrintDir(TIFF* tif, FILE* fd, long flags) JPEGState* sp = JState(tif); assert(sp != NULL); - (void) flags; - if (TIFFFieldSet(tif,FIELD_JPEGTABLES)) - fprintf(fd, " JPEG Tables: (%lu bytes)\n", - (unsigned long) sp->jpegtables_length); - if (TIFFFieldSet(tif,FIELD_RECVPARAMS)) - fprintf(fd, " Fax Receive Parameters: %08lx\n", - (unsigned long) sp->recvparams); - if (TIFFFieldSet(tif,FIELD_SUBADDRESS)) - fprintf(fd, " Fax SubAddress: %s\n", sp->subaddress); - if (TIFFFieldSet(tif,FIELD_RECVTIME)) - fprintf(fd, " Fax Receive Time: %lu secs\n", - (unsigned long) sp->recvtime); - if (TIFFFieldSet(tif,FIELD_FAXDCS)) - fprintf(fd, " Fax DCS: %s\n", sp->faxdcs); + + if( sp != NULL ) { + if (TIFFFieldSet(tif,FIELD_JPEGTABLES)) + fprintf(fd, " JPEG Tables: (%lu bytes)\n", + (unsigned long) sp->jpegtables_length); + if (sp->printdir) + (*sp->printdir)(tif, fd, flags); + } } static uint32 @@ -1840,7 +2217,7 @@ JPEGDefaultStripSize(TIFF* tif, uint32 s) s = (*sp->defsparent)(tif, s); if (s < td->td_imagelength) - s = TIFFroundup(s, td->td_ycbcrsubsampling[1] * DCTSIZE); + s = TIFFroundup_32(s, td->td_ycbcrsubsampling[1] * DCTSIZE); return (s); } @@ -1851,8 +2228,8 @@ JPEGDefaultTileSize(TIFF* tif, uint32* tw, uint32* th) TIFFDirectory *td = &tif->tif_dir; (*sp->deftparent)(tif, tw, th); - *tw = TIFFroundup(*tw, td->td_ycbcrsubsampling[0] * DCTSIZE); - *th = TIFFroundup(*th, td->td_ycbcrsubsampling[1] * DCTSIZE); + *tw = TIFFroundup_32(*tw, td->td_ycbcrsubsampling[0] * DCTSIZE); + *th = TIFFroundup_32(*th, td->td_ycbcrsubsampling[1] * DCTSIZE); } /* @@ -1877,19 +2254,15 @@ JPEGDefaultTileSize(TIFF* tif, uint32* tw, uint32* th) * NFW, Feb 3rd, 2003. */ -static int JPEGInitializeLibJPEG( TIFF * tif, int force_encode, int force_decode ) +static int JPEGInitializeLibJPEG( TIFF * tif, int decompress ) { JPEGState* sp = JState(tif); - uint32 *byte_counts = NULL; - int data_is_empty = TRUE; - int decompress; - if(sp->cinfo_initialized) { - if( force_encode && sp->cinfo.comm.is_decompressor ) + if( !decompress && sp->cinfo.comm.is_decompressor ) TIFFjpeg_destroy( sp ); - else if( force_decode && !sp->cinfo.comm.is_decompressor ) + else if( decompress && !sp->cinfo.comm.is_decompressor ) TIFFjpeg_destroy( sp ); else return 1; @@ -1897,42 +2270,12 @@ static int JPEGInitializeLibJPEG( TIFF * tif, int force_encode, int force_decode sp->cinfo_initialized = 0; } - /* - * Do we have tile data already? Make sure we initialize the - * the state in decompressor mode if we have tile data, even if we - * are not in read-only file access mode. - */ - if( TIFFIsTiled( tif ) - && TIFFGetField( tif, TIFFTAG_TILEBYTECOUNTS, &byte_counts ) - && byte_counts != NULL ) - { - data_is_empty = byte_counts[0] == 0; - } - if( !TIFFIsTiled( tif ) - && TIFFGetField( tif, TIFFTAG_STRIPBYTECOUNTS, &byte_counts) - && byte_counts != NULL ) - { - data_is_empty = byte_counts[0] == 0; - } - - if( force_decode ) - decompress = 1; - else if( force_encode ) - decompress = 0; - else if( tif->tif_mode == O_RDONLY ) - decompress = 1; - else if( data_is_empty ) - decompress = 0; - else - decompress = 1; - /* * Initialize libjpeg. */ if ( decompress ) { if (!TIFFjpeg_create_decompress(sp)) return (0); - } else { if (!TIFFjpeg_create_compress(sp)) return (0); @@ -1953,7 +2296,7 @@ TIFFInitJPEG(TIFF* tif, int scheme) /* * Merge codec-specific tag information. */ - if (!_TIFFMergeFieldInfo(tif, jpegFieldInfo, N(jpegFieldInfo))) { + if (!_TIFFMergeFields(tif, jpegFields, TIFFArrayCount(jpegFields))) { TIFFErrorExt(tif->tif_clientdata, "TIFFInitJPEG", "Merging JPEG codec-specific tags failed"); @@ -1963,7 +2306,7 @@ TIFFInitJPEG(TIFF* tif, int scheme) /* * Allocate state block so tag methods have storage to record values. */ - tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (JPEGState)); + tif->tif_data = (uint8*) _TIFFmalloc(sizeof (JPEGState)); if (tif->tif_data == NULL) { TIFFErrorExt(tif->tif_clientdata, @@ -1991,16 +2334,12 @@ TIFFInitJPEG(TIFF* tif, int scheme) sp->jpegquality = 75; /* Default IJG quality */ sp->jpegcolormode = JPEGCOLORMODE_RAW; sp->jpegtablesmode = JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF; - - sp->recvparams = 0; - sp->subaddress = NULL; - sp->faxdcs = NULL; - sp->ycbcrsampling_fetched = 0; /* * Install codec methods. */ + tif->tif_fixuptags = JPEGFixupTags; tif->tif_setupdecode = JPEGSetupDecode; tif->tif_predecode = JPEGPreDecode; tif->tif_decoderow = JPEGDecode; @@ -2011,7 +2350,7 @@ TIFFInitJPEG(TIFF* tif, int scheme) tif->tif_postencode = JPEGPostEncode; tif->tif_encoderow = JPEGEncode; tif->tif_encodestrip = JPEGEncode; - tif->tif_encodetile = JPEGEncode; + tif->tif_encodetile = JPEGEncode; tif->tif_cleanup = JPEGCleanup; sp->defsparent = tif->tif_defstripsize; tif->tif_defstripsize = JPEGDefaultStripSize; @@ -2040,16 +2379,11 @@ here hopefully is harmless. */ sp->jpegtables_length = SIZE_OF_JPEGTABLES; sp->jpegtables = (void *) _TIFFmalloc(sp->jpegtables_length); + // FIXME: NULL-deref after malloc failure _TIFFmemset(sp->jpegtables, 0, SIZE_OF_JPEGTABLES); #undef SIZE_OF_JPEGTABLES } - /* - * Mark the TIFFTAG_YCBCRSAMPLES as present even if it is not - * see: JPEGFixupTestSubsampling(). - */ - TIFFSetFieldBit( tif, FIELD_YCBCRSUBSAMPLING ); - return 1; } #endif /* JPEG_SUPPORT */ diff --git a/thirdparty/libtiff/tif_jpeg_12.c b/thirdparty/libtiff/tif_jpeg_12.c new file mode 100644 index 00000000..87aaa19e --- /dev/null +++ b/thirdparty/libtiff/tif_jpeg_12.c @@ -0,0 +1,65 @@ + +#include "tiffiop.h" + +#if defined(JPEG_DUAL_MODE_8_12) + +# define TIFFInitJPEG TIFFInitJPEG_12 + +# include LIBJPEG_12_PATH + +# include "tif_jpeg.c" + +int TIFFReInitJPEG_12( TIFF *tif, int scheme, int is_encode ) + +{ + JPEGState* sp; + + assert(scheme == COMPRESSION_JPEG); + + sp = JState(tif); + sp->tif = tif; /* back link */ + + /* + * Override parent get/set field methods. + */ + tif->tif_tagmethods.vgetfield = JPEGVGetField; /* hook for codec tags */ + tif->tif_tagmethods.vsetfield = JPEGVSetField; /* hook for codec tags */ + tif->tif_tagmethods.printdir = JPEGPrintDir; /* hook for codec tags */ + + /* + * Install codec methods. + */ + tif->tif_fixuptags = JPEGFixupTags; + tif->tif_setupdecode = JPEGSetupDecode; + tif->tif_predecode = JPEGPreDecode; + tif->tif_decoderow = JPEGDecode; + tif->tif_decodestrip = JPEGDecode; + tif->tif_decodetile = JPEGDecode; + tif->tif_setupencode = JPEGSetupEncode; + tif->tif_preencode = JPEGPreEncode; + tif->tif_postencode = JPEGPostEncode; + tif->tif_encoderow = JPEGEncode; + tif->tif_encodestrip = JPEGEncode; + tif->tif_encodetile = JPEGEncode; + tif->tif_cleanup = JPEGCleanup; + tif->tif_defstripsize = JPEGDefaultStripSize; + tif->tif_deftilesize = JPEGDefaultTileSize; + tif->tif_flags |= TIFF_NOBITREV; /* no bit reversal, please */ + + sp->cinfo_initialized = FALSE; + + if( is_encode ) + return JPEGSetupEncode(tif); + else + return JPEGSetupDecode(tif); +} + +#endif /* defined(JPEG_DUAL_MODE_8_12) */ + +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ diff --git a/thirdparty/libtiff/tif_luv.c b/thirdparty/libtiff/tif_luv.c index eb622b9b..4e328bad 100644 --- a/thirdparty/libtiff/tif_luv.c +++ b/thirdparty/libtiff/tif_luv.c @@ -1,4 +1,4 @@ -/* $Id: tif_luv.c,v 1.17.2.4 2010-06-08 18:50:42 bfriesen Exp $ */ +/* $Id: tif_luv.c,v 1.40 2015-06-21 01:09:09 bfriesen Exp $ */ /* * Copyright (c) 1997 Greg Ward Larson @@ -155,40 +155,44 @@ * State block for each open TIFF * file using LogLuv compression/decompression. */ -typedef struct logLuvState LogLuvState; +typedef struct logLuvState LogLuvState; struct logLuvState { - int user_datafmt; /* user data format */ - int encode_meth; /* encoding method */ - int pixel_size; /* bytes per pixel */ + int user_datafmt; /* user data format */ + int encode_meth; /* encoding method */ + int pixel_size; /* bytes per pixel */ - tidata_t* tbuf; /* translation buffer */ - int tbuflen; /* buffer length */ - void (*tfunc)(LogLuvState*, tidata_t, int); + uint8* tbuf; /* translation buffer */ + tmsize_t tbuflen; /* buffer length */ + void (*tfunc)(LogLuvState*, uint8*, tmsize_t); - TIFFVSetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ + TIFFVSetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ }; -#define DecoderState(tif) ((LogLuvState*) (tif)->tif_data) -#define EncoderState(tif) ((LogLuvState*) (tif)->tif_data) +#define DecoderState(tif) ((LogLuvState*) (tif)->tif_data) +#define EncoderState(tif) ((LogLuvState*) (tif)->tif_data) -#define SGILOGDATAFMT_UNKNOWN -1 +#define SGILOGDATAFMT_UNKNOWN -1 -#define MINRUN 4 /* minimum run length */ +#define MINRUN 4 /* minimum run length */ /* * Decode a string of 16-bit gray pixels. */ static int -LogL16Decode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) +LogL16Decode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) { + static const char module[] = "LogL16Decode"; LogLuvState* sp = DecoderState(tif); - int shft, i, npixels; + int shft; + tmsize_t i; + tmsize_t npixels; unsigned char* bp; int16* tp; int16 b; - int cc, rc; + tmsize_t cc; + int rc; assert(s == 0); assert(sp != NULL); @@ -201,15 +205,15 @@ LogL16Decode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) assert(sp->tbuflen >= npixels); tp = (int16*) sp->tbuf; } - _TIFFmemset((tdata_t) tp, 0, npixels*sizeof (tp[0])); + _TIFFmemset((void*) tp, 0, npixels*sizeof (tp[0])); bp = (unsigned char*) tif->tif_rawcp; cc = tif->tif_rawcc; - /* get each byte string */ + /* get each byte string */ for (shft = 2*8; (shft -= 8) >= 0; ) { for (i = 0; i < npixels && cc > 0; ) if (*bp >= 128) { /* run */ - rc = *bp++ + (2-128); + rc = *bp++ + (2-128); /* TODO: potential input buffer overrun when decoding corrupt or truncated data */ b = (int16)(*bp++ << shft); cc -= 2; while (rc-- && i < npixels) @@ -220,16 +224,24 @@ LogL16Decode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) tp[i++] |= (int16)*bp++ << shft; } if (i != npixels) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "LogL16Decode: Not enough data at row %d (short %d pixels)", - tif->tif_row, npixels - i); - tif->tif_rawcp = (tidata_t) bp; +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data at row %lu (short %I64d pixels)", + (unsigned long) tif->tif_row, + (unsigned __int64) (npixels - i)); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data at row %lu (short %llu pixels)", + (unsigned long) tif->tif_row, + (unsigned long long) (npixels - i)); +#endif + tif->tif_rawcp = (uint8*) bp; tif->tif_rawcc = cc; return (0); } } (*sp->tfunc)(sp, op, npixels); - tif->tif_rawcp = (tidata_t) bp; + tif->tif_rawcp = (uint8*) bp; tif->tif_rawcc = cc; return (1); } @@ -238,10 +250,13 @@ LogL16Decode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) * Decode a string of 24-bit pixels. */ static int -LogLuvDecode24(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) +LogLuvDecode24(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) { + static const char module[] = "LogLuvDecode24"; LogLuvState* sp = DecoderState(tif); - int cc, i, npixels; + tmsize_t cc; + tmsize_t i; + tmsize_t npixels; unsigned char* bp; uint32* tp; @@ -256,7 +271,7 @@ LogLuvDecode24(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) assert(sp->tbuflen >= npixels); tp = (uint32 *) sp->tbuf; } - /* copy to array of uint32 */ + /* copy to array of uint32 */ bp = (unsigned char*) tif->tif_rawcp; cc = tif->tif_rawcc; for (i = 0; i < npixels && cc > 0; i++) { @@ -264,12 +279,20 @@ LogLuvDecode24(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) bp += 3; cc -= 3; } - tif->tif_rawcp = (tidata_t) bp; + tif->tif_rawcp = (uint8*) bp; tif->tif_rawcc = cc; if (i != npixels) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "LogLuvDecode24: Not enough data at row %d (short %d pixels)", - tif->tif_row, npixels - i); +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data at row %lu (short %I64d pixels)", + (unsigned long) tif->tif_row, + (unsigned __int64) (npixels - i)); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data at row %lu (short %llu pixels)", + (unsigned long) tif->tif_row, + (unsigned long long) (npixels - i)); +#endif return (0); } (*sp->tfunc)(sp, op, npixels); @@ -280,14 +303,18 @@ LogLuvDecode24(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) * Decode a string of 32-bit pixels. */ static int -LogLuvDecode32(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) +LogLuvDecode32(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) { + static const char module[] = "LogLuvDecode32"; LogLuvState* sp; - int shft, i, npixels; + int shft; + tmsize_t i; + tmsize_t npixels; unsigned char* bp; uint32* tp; uint32 b; - int cc, rc; + tmsize_t cc; + int rc; assert(s == 0); sp = DecoderState(tif); @@ -301,17 +328,17 @@ LogLuvDecode32(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) assert(sp->tbuflen >= npixels); tp = (uint32*) sp->tbuf; } - _TIFFmemset((tdata_t) tp, 0, npixels*sizeof (tp[0])); + _TIFFmemset((void*) tp, 0, npixels*sizeof (tp[0])); bp = (unsigned char*) tif->tif_rawcp; cc = tif->tif_rawcc; - /* get each byte string */ + /* get each byte string */ for (shft = 4*8; (shft -= 8) >= 0; ) { for (i = 0; i < npixels && cc > 0; ) if (*bp >= 128) { /* run */ rc = *bp++ + (2-128); b = (uint32)*bp++ << shft; - cc -= 2; + cc -= 2; /* TODO: potential input buffer overrun when decoding corrupt or truncated data */ while (rc-- && i < npixels) tp[i++] |= b; } else { /* non-run */ @@ -320,16 +347,24 @@ LogLuvDecode32(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) tp[i++] |= (uint32)*bp++ << shft; } if (i != npixels) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "LogLuvDecode32: Not enough data at row %d (short %d pixels)", - tif->tif_row, npixels - i); - tif->tif_rawcp = (tidata_t) bp; +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data at row %lu (short %I64d pixels)", + (unsigned long) tif->tif_row, + (unsigned __int64) (npixels - i)); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data at row %lu (short %llu pixels)", + (unsigned long) tif->tif_row, + (unsigned long long) (npixels - i)); +#endif + tif->tif_rawcp = (uint8*) bp; tif->tif_rawcc = cc; return (0); } } (*sp->tfunc)(sp, op, npixels); - tif->tif_rawcp = (tidata_t) bp; + tif->tif_rawcp = (uint8*) bp; tif->tif_rawcc = cc; return (1); } @@ -340,9 +375,12 @@ LogLuvDecode32(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) * is row by row. */ static int -LogLuvDecodeStrip(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +LogLuvDecodeStrip(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) { - tsize_t rowlen = TIFFScanlineSize(tif); + tmsize_t rowlen = TIFFScanlineSize(tif); + + if (rowlen == 0) + return 0; assert(cc%rowlen == 0); while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s)) @@ -356,9 +394,12 @@ LogLuvDecodeStrip(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) * is row by row. */ static int -LogLuvDecodeTile(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +LogLuvDecodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) { - tsize_t rowlen = TIFFTileRowSize(tif); + tmsize_t rowlen = TIFFTileRowSize(tif); + + if (rowlen == 0) + return 0; assert(cc%rowlen == 0); while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s)) @@ -370,14 +411,19 @@ LogLuvDecodeTile(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) * Encode a row of 16-bit pixels. */ static int -LogL16Encode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +LogL16Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) { LogLuvState* sp = EncoderState(tif); - int shft, i, j, npixels; - tidata_t op; + int shft; + tmsize_t i; + tmsize_t j; + tmsize_t npixels; + uint8* op; int16* tp; int16 b; - int occ, rc=0, mask, beg; + tmsize_t occ; + int rc=0, mask; + tmsize_t beg; assert(s == 0); assert(sp != NULL); @@ -390,7 +436,7 @@ LogL16Encode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) assert(sp->tbuflen >= npixels); (*sp->tfunc)(sp, bp, npixels); } - /* compress each byte string */ + /* compress each byte string */ op = tif->tif_rawcp; occ = tif->tif_rawdatasize - tif->tif_rawcc; for (shft = 2*8; (shft -= 8) >= 0; ) @@ -408,7 +454,7 @@ LogL16Encode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) b = (int16) (tp[beg] & mask); rc = 1; while (rc < 127+2 && beg+rc < npixels && - (tp[beg+rc] & mask) == b) + (tp[beg+rc] & mask) == b) rc++; if (rc >= MINRUN) break; /* long enough */ @@ -417,33 +463,33 @@ LogL16Encode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) b = (int16) (tp[i] & mask);/*check short run */ j = i+1; while ((tp[j++] & mask) == b) - if (j == beg) { - *op++ = (tidataval_t)(128-2+j-i); - *op++ = (tidataval_t) (b >> shft); - occ -= 2; - i = beg; - break; - } + if (j == beg) { + *op++ = (uint8)(128-2+j-i); + *op++ = (uint8)(b >> shft); + occ -= 2; + i = beg; + break; + } } while (i < beg) { /* write out non-run */ if ((j = beg-i) > 127) j = 127; if (occ < j+3) { - tif->tif_rawcp = op; - tif->tif_rawcc = tif->tif_rawdatasize - occ; - if (!TIFFFlushData1(tif)) - return (-1); - op = tif->tif_rawcp; - occ = tif->tif_rawdatasize - tif->tif_rawcc; + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + if (!TIFFFlushData1(tif)) + return (-1); + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; } - *op++ = (tidataval_t) j; occ--; + *op++ = (uint8) j; occ--; while (j--) { - *op++ = (tidataval_t) (tp[i++] >> shft & 0xff); + *op++ = (uint8) (tp[i++] >> shft & 0xff); occ--; } } if (rc >= MINRUN) { /* write out run */ - *op++ = (tidataval_t) (128-2+rc); - *op++ = (tidataval_t) (tp[beg] >> shft & 0xff); + *op++ = (uint8) (128-2+rc); + *op++ = (uint8) (tp[beg] >> shft & 0xff); occ -= 2; } else rc = 0; @@ -458,11 +504,13 @@ LogL16Encode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) * Encode a row of 24-bit pixels. */ static int -LogLuvEncode24(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +LogLuvEncode24(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) { LogLuvState* sp = EncoderState(tif); - int i, npixels, occ; - tidata_t op; + tmsize_t i; + tmsize_t npixels; + tmsize_t occ; + uint8* op; uint32* tp; assert(s == 0); @@ -476,7 +524,7 @@ LogLuvEncode24(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) assert(sp->tbuflen >= npixels); (*sp->tfunc)(sp, bp, npixels); } - /* write out encoded pixels */ + /* write out encoded pixels */ op = tif->tif_rawcp; occ = tif->tif_rawdatasize - tif->tif_rawcc; for (i = npixels; i--; ) { @@ -488,9 +536,9 @@ LogLuvEncode24(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) op = tif->tif_rawcp; occ = tif->tif_rawdatasize - tif->tif_rawcc; } - *op++ = (tidataval_t)(*tp >> 16); - *op++ = (tidataval_t)(*tp >> 8 & 0xff); - *op++ = (tidataval_t)(*tp++ & 0xff); + *op++ = (uint8)(*tp >> 16); + *op++ = (uint8)(*tp >> 8 & 0xff); + *op++ = (uint8)(*tp++ & 0xff); occ -= 3; } tif->tif_rawcp = op; @@ -503,14 +551,19 @@ LogLuvEncode24(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) * Encode a row of 32-bit pixels. */ static int -LogLuvEncode32(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +LogLuvEncode32(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) { LogLuvState* sp = EncoderState(tif); - int shft, i, j, npixels; - tidata_t op; + int shft; + tmsize_t i; + tmsize_t j; + tmsize_t npixels; + uint8* op; uint32* tp; uint32 b; - int occ, rc=0, mask, beg; + tmsize_t occ; + int rc=0, mask; + tmsize_t beg; assert(s == 0); assert(sp != NULL); @@ -524,7 +577,7 @@ LogLuvEncode32(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) assert(sp->tbuflen >= npixels); (*sp->tfunc)(sp, bp, npixels); } - /* compress each byte string */ + /* compress each byte string */ op = tif->tif_rawcp; occ = tif->tif_rawdatasize - tif->tif_rawcc; for (shft = 4*8; (shft -= 8) >= 0; ) @@ -552,8 +605,8 @@ LogLuvEncode32(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) j = i+1; while ((tp[j++] & mask) == b) if (j == beg) { - *op++ = (tidataval_t)(128-2+j-i); - *op++ = (tidataval_t)(b >> shft); + *op++ = (uint8)(128-2+j-i); + *op++ = (uint8)(b >> shft); occ -= 2; i = beg; break; @@ -569,15 +622,15 @@ LogLuvEncode32(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) op = tif->tif_rawcp; occ = tif->tif_rawdatasize - tif->tif_rawcc; } - *op++ = (tidataval_t) j; occ--; + *op++ = (uint8) j; occ--; while (j--) { - *op++ = (tidataval_t)(tp[i++] >> shft & 0xff); + *op++ = (uint8)(tp[i++] >> shft & 0xff); occ--; } } if (rc >= MINRUN) { /* write out run */ - *op++ = (tidataval_t) (128-2+rc); - *op++ = (tidataval_t)(tp[beg] >> shft & 0xff); + *op++ = (uint8) (128-2+rc); + *op++ = (uint8)(tp[beg] >> shft & 0xff); occ -= 2; } else rc = 0; @@ -593,9 +646,12 @@ LogLuvEncode32(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) * avoid encoding runs across row boundaries. */ static int -LogLuvEncodeStrip(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +LogLuvEncodeStrip(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) { - tsize_t rowlen = TIFFScanlineSize(tif); + tmsize_t rowlen = TIFFScanlineSize(tif); + + if (rowlen == 0) + return 0; assert(cc%rowlen == 0); while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1) @@ -608,9 +664,12 @@ LogLuvEncodeStrip(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) * avoid encoding runs across row boundaries. */ static int -LogLuvEncodeTile(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +LogLuvEncodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) { - tsize_t rowlen = TIFFTileRowSize(tif); + tmsize_t rowlen = TIFFTileRowSize(tif); + + if (rowlen == 0) + return 0; assert(cc%rowlen == 0); while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1) @@ -636,7 +695,9 @@ LogLuvEncodeTile(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) #ifndef M_PI #define M_PI 3.14159265358979323846 #endif +#undef log2 /* Conflict with C'99 function */ #define log2(x) ((1./M_LN2)*log(x)) +#undef exp2 /* Conflict with C'99 function */ #define exp2(x) exp(M_LN2*(x)) #define itrunc(x,m) ((m)==SGILOGENCODE_NODITHER ? \ @@ -676,7 +737,7 @@ LogL16fromY(double Y, int em) /* get 16-bit LogL from Y */ } static void -L16toY(LogLuvState* sp, tidata_t op, int n) +L16toY(LogLuvState* sp, uint8* op, tmsize_t n) { int16* l16 = (int16*) sp->tbuf; float* yp = (float*) op; @@ -686,7 +747,7 @@ L16toY(LogLuvState* sp, tidata_t op, int n) } static void -L16toGry(LogLuvState* sp, tidata_t op, int n) +L16toGry(LogLuvState* sp, uint8* op, tmsize_t n) { int16* l16 = (int16*) sp->tbuf; uint8* gp = (uint8*) op; @@ -698,7 +759,7 @@ L16toGry(LogLuvState* sp, tidata_t op, int n) } static void -L16fromY(LogLuvState* sp, tidata_t op, int n) +L16fromY(LogLuvState* sp, uint8* op, tmsize_t n) { int16* l16 = (int16*) sp->tbuf; float* yp = (float*) op; @@ -760,7 +821,7 @@ oog_encode(double u, double v) /* encode out-of-gamut chroma */ static int oog_table[NANGLES]; static int initialized = 0; register int i; - + if (!initialized) { /* set up perimeter table */ double eps[NANGLES], ua, va, ang, epsa; int ui, vi, ustep; @@ -774,7 +835,7 @@ oog_encode(double u, double v) /* encode out-of-gamut chroma */ for (ui = uv_row[vi].nus-1; ui >= 0; ui -= ustep) { ua = uv_row[vi].ustart + (ui+.5)*UV_SQSIZ; ang = uv2ang(ua, va); - i = (int) ang; + i = (int) ang; epsa = fabs(ang - (i+.5)); if (epsa < eps[i]) { oog_table[i] = uv_row[vi].ncum + ui; @@ -916,9 +977,9 @@ LogLuv24fromXYZ(float XYZ[3], int em) } static void -Luv24toXYZ(LogLuvState* sp, tidata_t op, int n) +Luv24toXYZ(LogLuvState* sp, uint8* op, tmsize_t n) { - uint32* luv = (uint32*) sp->tbuf; + uint32* luv = (uint32*) sp->tbuf; float* xyz = (float*) op; while (n-- > 0) { @@ -929,9 +990,9 @@ Luv24toXYZ(LogLuvState* sp, tidata_t op, int n) } static void -Luv24toLuv48(LogLuvState* sp, tidata_t op, int n) +Luv24toLuv48(LogLuvState* sp, uint8* op, tmsize_t n) { - uint32* luv = (uint32*) sp->tbuf; + uint32* luv = (uint32*) sp->tbuf; int16* luv3 = (int16*) op; while (n-- > 0) { @@ -949,9 +1010,9 @@ Luv24toLuv48(LogLuvState* sp, tidata_t op, int n) } static void -Luv24toRGB(LogLuvState* sp, tidata_t op, int n) +Luv24toRGB(LogLuvState* sp, uint8* op, tmsize_t n) { - uint32* luv = (uint32*) sp->tbuf; + uint32* luv = (uint32*) sp->tbuf; uint8* rgb = (uint8*) op; while (n-- > 0) { @@ -964,9 +1025,9 @@ Luv24toRGB(LogLuvState* sp, tidata_t op, int n) } static void -Luv24fromXYZ(LogLuvState* sp, tidata_t op, int n) +Luv24fromXYZ(LogLuvState* sp, uint8* op, tmsize_t n) { - uint32* luv = (uint32*) sp->tbuf; + uint32* luv = (uint32*) sp->tbuf; float* xyz = (float*) op; while (n-- > 0) { @@ -976,9 +1037,9 @@ Luv24fromXYZ(LogLuvState* sp, tidata_t op, int n) } static void -Luv24fromLuv48(LogLuvState* sp, tidata_t op, int n) +Luv24fromLuv48(LogLuvState* sp, uint8* op, tmsize_t n) { - uint32* luv = (uint32*) sp->tbuf; + uint32* luv = (uint32*) sp->tbuf; int16* luv3 = (int16*) op; while (n-- > 0) { @@ -1057,9 +1118,9 @@ LogLuv32fromXYZ(float XYZ[3], int em) } static void -Luv32toXYZ(LogLuvState* sp, tidata_t op, int n) +Luv32toXYZ(LogLuvState* sp, uint8* op, tmsize_t n) { - uint32* luv = (uint32*) sp->tbuf; + uint32* luv = (uint32*) sp->tbuf; float* xyz = (float*) op; while (n-- > 0) { @@ -1069,9 +1130,9 @@ Luv32toXYZ(LogLuvState* sp, tidata_t op, int n) } static void -Luv32toLuv48(LogLuvState* sp, tidata_t op, int n) +Luv32toLuv48(LogLuvState* sp, uint8* op, tmsize_t n) { - uint32* luv = (uint32*) sp->tbuf; + uint32* luv = (uint32*) sp->tbuf; int16* luv3 = (int16*) op; while (n-- > 0) { @@ -1087,9 +1148,9 @@ Luv32toLuv48(LogLuvState* sp, tidata_t op, int n) } static void -Luv32toRGB(LogLuvState* sp, tidata_t op, int n) +Luv32toRGB(LogLuvState* sp, uint8* op, tmsize_t n) { - uint32* luv = (uint32*) sp->tbuf; + uint32* luv = (uint32*) sp->tbuf; uint8* rgb = (uint8*) op; while (n-- > 0) { @@ -1102,9 +1163,9 @@ Luv32toRGB(LogLuvState* sp, tidata_t op, int n) } static void -Luv32fromXYZ(LogLuvState* sp, tidata_t op, int n) +Luv32fromXYZ(LogLuvState* sp, uint8* op, tmsize_t n) { - uint32* luv = (uint32*) sp->tbuf; + uint32* luv = (uint32*) sp->tbuf; float* xyz = (float*) op; while (n-- > 0) { @@ -1114,7 +1175,7 @@ Luv32fromXYZ(LogLuvState* sp, tidata_t op, int n) } static void -Luv32fromLuv48(LogLuvState* sp, tidata_t op, int n) +Luv32fromLuv48(LogLuvState* sp, uint8* op, tmsize_t n) { uint32* luv = (uint32*) sp->tbuf; int16* luv3 = (int16*) op; @@ -1137,7 +1198,7 @@ Luv32fromLuv48(LogLuvState* sp, tidata_t op, int n) } static void -_logLuvNop(LogLuvState* sp, tidata_t op, int n) +_logLuvNop(LogLuvState* sp, uint8* op, tmsize_t n) { (void) sp; (void) op; (void) n; } @@ -1161,10 +1222,10 @@ LogL16GuessDataFmt(TIFFDirectory *td) return (SGILOGDATAFMT_UNKNOWN); } -static uint32 -multiply(size_t m1, size_t m2) +static tmsize_t +multiply_ms(tmsize_t m1, tmsize_t m2) { - uint32 bytes = m1 * m2; + tmsize_t bytes = m1 * m2; if (m1 && bytes / m1 != m2) bytes = 0; @@ -1175,9 +1236,9 @@ multiply(size_t m1, size_t m2) static int LogL16InitState(TIFF* tif) { + static const char module[] = "LogL16InitState"; TIFFDirectory *td = &tif->tif_dir; LogLuvState* sp = DecoderState(tif); - static const char module[] = "LogL16InitState"; assert(sp != NULL); assert(td->td_photometric == PHOTOMETRIC_LOGL); @@ -1196,18 +1257,17 @@ LogL16InitState(TIFF* tif) sp->pixel_size = sizeof (uint8); break; default: - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + TIFFErrorExt(tif->tif_clientdata, module, "No support for converting user data format to LogL"); return (0); } if( isTiled(tif) ) - sp->tbuflen = multiply(td->td_tilewidth, td->td_tilelength); + sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength); else - sp->tbuflen = multiply(td->td_imagewidth, td->td_rowsperstrip); - if (multiply(sp->tbuflen, sizeof (int16)) == 0 || - (sp->tbuf = (tidata_t*) _TIFFmalloc(sp->tbuflen * sizeof (int16))) == NULL) { - TIFFErrorExt(tif->tif_clientdata, module, "%s: No space for SGILog translation buffer", - tif->tif_name); + sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip); + 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"); return (0); } return (1); @@ -1268,9 +1328,9 @@ LogLuvGuessDataFmt(TIFFDirectory *td) static int LogLuvInitState(TIFF* tif) { + static const char module[] = "LogLuvInitState"; TIFFDirectory* td = &tif->tif_dir; LogLuvState* sp = DecoderState(tif); - static const char module[] = "LogLuvInitState"; assert(sp != NULL); assert(td->td_photometric == PHOTOMETRIC_LOGLUV); @@ -1297,26 +1357,33 @@ LogLuvInitState(TIFF* tif) sp->pixel_size = 3*sizeof (uint8); break; default: - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + TIFFErrorExt(tif->tif_clientdata, module, "No support for converting user data format to LogLuv"); return (0); } if( isTiled(tif) ) - sp->tbuflen = multiply(td->td_tilewidth, td->td_tilelength); + sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength); else - sp->tbuflen = multiply(td->td_imagewidth, td->td_rowsperstrip); - if (multiply(sp->tbuflen, sizeof (uint32)) == 0 || - (sp->tbuf = (tidata_t*) _TIFFmalloc(sp->tbuflen * sizeof (uint32))) == NULL) { - TIFFErrorExt(tif->tif_clientdata, module, "%s: No space for SGILog translation buffer", - tif->tif_name); + sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip); + 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"); return (0); } return (1); } +static int +LogLuvFixupTags(TIFF* tif) +{ + (void) tif; + return (1); +} + static int LogLuvSetupDecode(TIFF* tif) { + static const char module[] = "LogLuvSetupDecode"; LogLuvState* sp = DecoderState(tif); TIFFDirectory* td = &tif->tif_dir; @@ -1329,10 +1396,10 @@ LogLuvSetupDecode(TIFF* tif) tif->tif_decoderow = LogLuvDecode24; switch (sp->user_datafmt) { case SGILOGDATAFMT_FLOAT: - sp->tfunc = Luv24toXYZ; + sp->tfunc = Luv24toXYZ; break; case SGILOGDATAFMT_16BIT: - sp->tfunc = Luv24toLuv48; + sp->tfunc = Luv24toLuv48; break; case SGILOGDATAFMT_8BIT: sp->tfunc = Luv24toRGB; @@ -1367,8 +1434,8 @@ LogLuvSetupDecode(TIFF* tif) } return (1); default: - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Inappropriate photometric interpretation %d for SGILog compression; %s", + TIFFErrorExt(tif->tif_clientdata, module, + "Inappropriate photometric interpretation %d for SGILog compression; %s", td->td_photometric, "must be either LogLUV or LogL"); break; } @@ -1378,6 +1445,7 @@ LogLuvSetupDecode(TIFF* tif) static int LogLuvSetupEncode(TIFF* tif) { + static const char module[] = "LogLuvSetupEncode"; LogLuvState* sp = EncoderState(tif); TIFFDirectory* td = &tif->tif_dir; @@ -1392,7 +1460,7 @@ LogLuvSetupEncode(TIFF* tif) sp->tfunc = Luv24fromXYZ; break; case SGILOGDATAFMT_16BIT: - sp->tfunc = Luv24fromLuv48; + sp->tfunc = Luv24fromLuv48; break; case SGILOGDATAFMT_RAW: break; @@ -1400,13 +1468,13 @@ LogLuvSetupEncode(TIFF* tif) goto notsupported; } } else { - tif->tif_encoderow = LogLuvEncode32; + tif->tif_encoderow = LogLuvEncode32; switch (sp->user_datafmt) { case SGILOGDATAFMT_FLOAT: - sp->tfunc = Luv32fromXYZ; + sp->tfunc = Luv32fromXYZ; break; case SGILOGDATAFMT_16BIT: - sp->tfunc = Luv32fromLuv48; + sp->tfunc = Luv32fromLuv48; break; case SGILOGDATAFMT_RAW: break; @@ -1418,7 +1486,7 @@ LogLuvSetupEncode(TIFF* tif) case PHOTOMETRIC_LOGL: if (!LogL16InitState(tif)) break; - tif->tif_encoderow = LogL16Encode; + tif->tif_encoderow = LogL16Encode; switch (sp->user_datafmt) { case SGILOGDATAFMT_FLOAT: sp->tfunc = L16fromY; @@ -1430,14 +1498,14 @@ LogLuvSetupEncode(TIFF* tif) } break; default: - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Inappropriate photometric interpretation %d for SGILog compression; %s", - td->td_photometric, "must be either LogLUV or LogL"); + TIFFErrorExt(tif->tif_clientdata, module, + "Inappropriate photometric interpretation %d for SGILog compression; %s", + td->td_photometric, "must be either LogLUV or LogL"); break; } return (1); notsupported: - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + TIFFErrorExt(tif->tif_clientdata, module, "SGILog compression supported only for %s, or raw data", td->td_photometric == PHOTOMETRIC_LOGL ? "Y, L" : "XYZ, Luv"); return (0); @@ -1480,14 +1548,15 @@ LogLuvCleanup(TIFF* tif) } static int -LogLuvVSetField(TIFF* tif, ttag_t tag, va_list ap) +LogLuvVSetField(TIFF* tif, uint32 tag, va_list ap) { + static const char module[] = "LogLuvVSetField"; LogLuvState* sp = DecoderState(tif); int bps, fmt; switch (tag) { case TIFFTAG_SGILOGDATAFMT: - sp->user_datafmt = va_arg(ap, int); + sp->user_datafmt = (int) va_arg(ap, int); /* * Tweak the TIFF header so that the rest of libtiff knows what * size of data will be passed between app and library, and @@ -1519,16 +1588,16 @@ LogLuvVSetField(TIFF* tif, ttag_t tag, va_list ap) /* * Must recalculate sizes should bits/sample change. */ - tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tsize_t) -1; + tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t) -1; tif->tif_scanlinesize = TIFFScanlineSize(tif); return (1); case TIFFTAG_SGILOGENCODE: - sp->encode_meth = va_arg(ap, int); + sp->encode_meth = (int) va_arg(ap, int); if (sp->encode_meth != SGILOGENCODE_NODITHER && - sp->encode_meth != SGILOGENCODE_RANDITHER) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Unknown encoding %d for LogLuv compression", - sp->encode_meth); + sp->encode_meth != SGILOGENCODE_RANDITHER) { + TIFFErrorExt(tif->tif_clientdata, module, + "Unknown encoding %d for LogLuv compression", + sp->encode_meth); return (0); } return (1); @@ -1538,7 +1607,7 @@ LogLuvVSetField(TIFF* tif, ttag_t tag, va_list ap) } static int -LogLuvVGetField(TIFF* tif, ttag_t tag, va_list ap) +LogLuvVGetField(TIFF* tif, uint32 tag, va_list ap) { LogLuvState *sp = (LogLuvState *)tif->tif_data; @@ -1551,11 +1620,9 @@ LogLuvVGetField(TIFF* tif, ttag_t tag, va_list ap) } } -static const TIFFFieldInfo LogLuvFieldInfo[] = { - { TIFFTAG_SGILOGDATAFMT, 0, 0, TIFF_SHORT, FIELD_PSEUDO, - TRUE, FALSE, "SGILogDataFmt"}, - { TIFFTAG_SGILOGENCODE, 0, 0, TIFF_SHORT, FIELD_PSEUDO, - TRUE, FALSE, "SGILogEncode"} +static const TIFFField LogLuvFields[] = { + { TIFFTAG_SGILOGDATAFMT, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "SGILogDataFmt", NULL}, + { TIFFTAG_SGILOGENCODE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "SGILogEncode", NULL} }; int @@ -1569,24 +1636,24 @@ TIFFInitSGILog(TIFF* tif, int scheme) /* * Merge codec-specific tag information. */ - if (!_TIFFMergeFieldInfo(tif, LogLuvFieldInfo, - TIFFArrayCount(LogLuvFieldInfo))) { + if (!_TIFFMergeFields(tif, LogLuvFields, + TIFFArrayCount(LogLuvFields))) { TIFFErrorExt(tif->tif_clientdata, module, - "Merging SGILog codec-specific tags failed"); + "Merging SGILog codec-specific tags failed"); return 0; } /* * Allocate state block so tag methods have storage to record values. */ - tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (LogLuvState)); + tif->tif_data = (uint8*) _TIFFmalloc(sizeof (LogLuvState)); if (tif->tif_data == NULL) goto bad; sp = (LogLuvState*) tif->tif_data; - _TIFFmemset((tdata_t)sp, 0, sizeof (*sp)); + _TIFFmemset((void*)sp, 0, sizeof (*sp)); sp->user_datafmt = SGILOGDATAFMT_UNKNOWN; sp->encode_meth = (scheme == COMPRESSION_SGILOG24) ? - SGILOGENCODE_RANDITHER : SGILOGENCODE_NODITHER; + SGILOGENCODE_RANDITHER : SGILOGENCODE_NODITHER; sp->tfunc = _logLuvNop; /* @@ -1594,16 +1661,17 @@ TIFFInitSGILog(TIFF* tif, int scheme) * NB: tif_decoderow & tif_encoderow are filled * in at setup time. */ + tif->tif_fixuptags = LogLuvFixupTags; tif->tif_setupdecode = LogLuvSetupDecode; tif->tif_decodestrip = LogLuvDecodeStrip; tif->tif_decodetile = LogLuvDecodeTile; tif->tif_setupencode = LogLuvSetupEncode; - tif->tif_encodestrip = LogLuvEncodeStrip; + tif->tif_encodestrip = LogLuvEncodeStrip; tif->tif_encodetile = LogLuvEncodeTile; tif->tif_close = LogLuvClose; tif->tif_cleanup = LogLuvCleanup; - /* + /* * Override parent get/set field methods. */ sp->vgetparent = tif->tif_tagmethods.vgetfield; diff --git a/thirdparty/libtiff/tif_lzma.c b/thirdparty/libtiff/tif_lzma.c new file mode 100644 index 00000000..dedf1d94 --- /dev/null +++ b/thirdparty/libtiff/tif_lzma.c @@ -0,0 +1,495 @@ +/* $Id: tif_lzma.c,v 1.4 2011-12-22 00:29:29 bfriesen Exp $ */ + +/* + * Copyright (c) 2010, Andrey Kiselev + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "tiffiop.h" +#ifdef LZMA_SUPPORT +/* + * TIFF Library. + * + * LZMA2 Compression Support + * + * You need an LZMA2 SDK to link with. See http://tukaani.org/xz/ for details. + * + * The codec is derived from ZLIB codec (tif_zip.c). + */ + +#include "tif_predict.h" +#include "lzma.h" + +#include + +/* + * State block for each open TIFF file using LZMA2 compression/decompression. + */ +typedef struct { + TIFFPredictorState predict; + lzma_stream stream; + lzma_filter filters[LZMA_FILTERS_MAX + 1]; + lzma_options_delta opt_delta; /* delta filter options */ + lzma_options_lzma opt_lzma; /* LZMA2 filter options */ + int preset; /* compression level */ + lzma_check check; /* type of the integrity check */ + int state; /* state flags */ +#define LSTATE_INIT_DECODE 0x01 +#define LSTATE_INIT_ENCODE 0x02 + + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ +} LZMAState; + +#define LState(tif) ((LZMAState*) (tif)->tif_data) +#define DecoderState(tif) LState(tif) +#define EncoderState(tif) LState(tif) + +static int LZMAEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s); +static int LZMADecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s); + +static const char * +LZMAStrerror(lzma_ret ret) +{ + switch (ret) { + case LZMA_OK: + return "operation completed successfully"; + case LZMA_STREAM_END: + return "end of stream was reached"; + case LZMA_NO_CHECK: + return "input stream has no integrity check"; + case LZMA_UNSUPPORTED_CHECK: + return "cannot calculate the integrity check"; + case LZMA_GET_CHECK: + return "integrity check type is now available"; + case LZMA_MEM_ERROR: + return "cannot allocate memory"; + case LZMA_MEMLIMIT_ERROR: + return "memory usage limit was reached"; + case LZMA_FORMAT_ERROR: + return "file format not recognized"; + case LZMA_OPTIONS_ERROR: + return "invalid or unsupported options"; + case LZMA_DATA_ERROR: + return "data is corrupt"; + case LZMA_BUF_ERROR: + return "no progress is possible (stream is truncated or corrupt)"; + case LZMA_PROG_ERROR: + return "programming error"; + default: + return "unindentified liblzma error"; + } +} + +static int +LZMAFixupTags(TIFF* tif) +{ + (void) tif; + return 1; +} + +static int +LZMASetupDecode(TIFF* tif) +{ + LZMAState* sp = DecoderState(tif); + + assert(sp != NULL); + + /* if we were last encoding, terminate this mode */ + if (sp->state & LSTATE_INIT_ENCODE) { + lzma_end(&sp->stream); + sp->state = 0; + } + + sp->state |= LSTATE_INIT_DECODE; + return 1; +} + +/* + * Setup state for decoding a strip. + */ +static int +LZMAPreDecode(TIFF* tif, uint16 s) +{ + static const char module[] = "LZMAPreDecode"; + LZMAState* sp = DecoderState(tif); + lzma_ret ret; + + (void) s; + assert(sp != NULL); + + if( (sp->state & LSTATE_INIT_DECODE) == 0 ) + tif->tif_setupdecode(tif); + + sp->stream.next_in = tif->tif_rawdata; + sp->stream.avail_in = (size_t) tif->tif_rawcc; + if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc) { + TIFFErrorExt(tif->tif_clientdata, module, + "Liblzma cannot deal with buffers this size"); + return 0; + } + + /* + * Disable memory limit when decoding. UINT64_MAX is a flag to disable + * the limit, we are passing (uint64_t)-1 which should be the same. + */ + ret = lzma_stream_decoder(&sp->stream, (uint64_t)-1, 0); + if (ret != LZMA_OK) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error initializing the stream decoder, %s", + LZMAStrerror(ret)); + return 0; + } + return 1; +} + +static int +LZMADecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) +{ + static const char module[] = "LZMADecode"; + LZMAState* sp = DecoderState(tif); + + (void) s; + assert(sp != NULL); + assert(sp->state == LSTATE_INIT_DECODE); + + sp->stream.next_in = tif->tif_rawcp; + sp->stream.avail_in = (size_t) tif->tif_rawcc; + + sp->stream.next_out = op; + sp->stream.avail_out = (size_t) occ; + if ((tmsize_t)sp->stream.avail_out != occ) { + TIFFErrorExt(tif->tif_clientdata, module, + "Liblzma cannot deal with buffers this size"); + return 0; + } + + do { + /* + * Save the current stream state to properly recover from the + * decoding errors later. + */ + const uint8_t *next_in = sp->stream.next_in; + size_t avail_in = sp->stream.avail_in; + + lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN); + if (ret == LZMA_STREAM_END) + break; + if (ret == LZMA_MEMLIMIT_ERROR) { + lzma_ret r = lzma_stream_decoder(&sp->stream, + lzma_memusage(&sp->stream), 0); + if (r != LZMA_OK) { + TIFFErrorExt(tif->tif_clientdata, module, + "Error initializing the stream decoder, %s", + LZMAStrerror(r)); + break; + } + sp->stream.next_in = next_in; + sp->stream.avail_in = avail_in; + continue; + } + if (ret != LZMA_OK) { + TIFFErrorExt(tif->tif_clientdata, module, + "Decoding error at scanline %lu, %s", + (unsigned long) tif->tif_row, LZMAStrerror(ret)); + break; + } + } while (sp->stream.avail_out > 0); + if (sp->stream.avail_out != 0) { + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data at scanline %lu (short %lu bytes)", + (unsigned long) tif->tif_row, (unsigned long) sp->stream.avail_out); + return 0; + } + + tif->tif_rawcp = (uint8 *)sp->stream.next_in; /* cast away const */ + tif->tif_rawcc = sp->stream.avail_in; + + return 1; +} + +static int +LZMASetupEncode(TIFF* tif) +{ + LZMAState* sp = EncoderState(tif); + + assert(sp != NULL); + if (sp->state & LSTATE_INIT_DECODE) { + lzma_end(&sp->stream); + sp->state = 0; + } + + sp->state |= LSTATE_INIT_ENCODE; + return 1; +} + +/* + * Reset encoding state at the start of a strip. + */ +static int +LZMAPreEncode(TIFF* tif, uint16 s) +{ + static const char module[] = "LZMAPreEncode"; + LZMAState *sp = EncoderState(tif); + + (void) s; + assert(sp != NULL); + if( sp->state != LSTATE_INIT_ENCODE ) + tif->tif_setupencode(tif); + + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = (size_t)tif->tif_rawdatasize; + if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) { + TIFFErrorExt(tif->tif_clientdata, module, + "Liblzma cannot deal with buffers this size"); + return 0; + } + return (lzma_stream_encoder(&sp->stream, sp->filters, sp->check) == LZMA_OK); +} + +/* + * Encode a chunk of pixels. + */ +static int +LZMAEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) +{ + static const char module[] = "LZMAEncode"; + LZMAState *sp = EncoderState(tif); + + assert(sp != NULL); + assert(sp->state == LSTATE_INIT_ENCODE); + + (void) s; + sp->stream.next_in = bp; + sp->stream.avail_in = (size_t) cc; + if ((tmsize_t)sp->stream.avail_in != cc) { + TIFFErrorExt(tif->tif_clientdata, module, + "Liblzma cannot deal with buffers this size"); + return 0; + } + do { + lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN); + if (ret != LZMA_OK) { + TIFFErrorExt(tif->tif_clientdata, module, + "Encoding error at scanline %lu, %s", + (unsigned long) tif->tif_row, LZMAStrerror(ret)); + return 0; + } + if (sp->stream.avail_out == 0) { + tif->tif_rawcc = tif->tif_rawdatasize; + TIFFFlushData1(tif); + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = (size_t)tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in LZMAPreEncode */ + } + } while (sp->stream.avail_in > 0); + return 1; +} + +/* + * Finish off an encoded strip by flushing the last + * string and tacking on an End Of Information code. + */ +static int +LZMAPostEncode(TIFF* tif) +{ + static const char module[] = "LZMAPostEncode"; + LZMAState *sp = EncoderState(tif); + lzma_ret ret; + + sp->stream.avail_in = 0; + do { + ret = lzma_code(&sp->stream, LZMA_FINISH); + switch (ret) { + case LZMA_STREAM_END: + case LZMA_OK: + if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) { + tif->tif_rawcc = + tif->tif_rawdatasize - sp->stream.avail_out; + TIFFFlushData1(tif); + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = (size_t)tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in ZIPPreEncode */ + } + break; + default: + TIFFErrorExt(tif->tif_clientdata, module, "Liblzma error: %s", + LZMAStrerror(ret)); + return 0; + } + } while (ret != LZMA_STREAM_END); + return 1; +} + +static void +LZMACleanup(TIFF* tif) +{ + LZMAState* sp = LState(tif); + + assert(sp != 0); + + (void)TIFFPredictorCleanup(tif); + + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; + + if (sp->state) { + lzma_end(&sp->stream); + sp->state = 0; + } + _TIFFfree(sp); + tif->tif_data = NULL; + + _TIFFSetDefaultCompressionState(tif); +} + +static int +LZMAVSetField(TIFF* tif, uint32 tag, va_list ap) +{ + static const char module[] = "LZMAVSetField"; + LZMAState* sp = LState(tif); + + switch (tag) { + case TIFFTAG_LZMAPRESET: + sp->preset = (int) va_arg(ap, int); + lzma_lzma_preset(&sp->opt_lzma, sp->preset); + if (sp->state & LSTATE_INIT_ENCODE) { + lzma_ret ret = lzma_stream_encoder(&sp->stream, + sp->filters, + sp->check); + if (ret != LZMA_OK) { + TIFFErrorExt(tif->tif_clientdata, module, + "Liblzma error: %s", + LZMAStrerror(ret)); + } + } + return 1; + default: + return (*sp->vsetparent)(tif, tag, ap); + } + /*NOTREACHED*/ +} + +static int +LZMAVGetField(TIFF* tif, uint32 tag, va_list ap) +{ + LZMAState* sp = LState(tif); + + switch (tag) { + case TIFFTAG_LZMAPRESET: + *va_arg(ap, int*) = sp->preset; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); + } + return 1; +} + +static const TIFFField lzmaFields[] = { + { TIFFTAG_LZMAPRESET, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, + FIELD_PSEUDO, TRUE, FALSE, "LZMA2 Compression Preset", NULL }, +}; + +int +TIFFInitLZMA(TIFF* tif, int scheme) +{ + static const char module[] = "TIFFInitLZMA"; + LZMAState* sp; + lzma_stream tmp_stream = LZMA_STREAM_INIT; + + assert( scheme == COMPRESSION_LZMA ); + + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, lzmaFields, TIFFArrayCount(lzmaFields))) { + TIFFErrorExt(tif->tif_clientdata, module, + "Merging LZMA2 codec-specific tags failed"); + return 0; + } + + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8*) _TIFFmalloc(sizeof(LZMAState)); + if (tif->tif_data == NULL) + goto bad; + sp = LState(tif); + memcpy(&sp->stream, &tmp_stream, sizeof(lzma_stream)); + + /* + * Override parent get/set field methods. + */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = LZMAVGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = LZMAVSetField; /* hook for codec tags */ + + /* Default values for codec-specific fields */ + sp->preset = LZMA_PRESET_DEFAULT; /* default comp. level */ + sp->check = LZMA_CHECK_NONE; + sp->state = 0; + + /* Data filters. So far we are using delta and LZMA2 filters only. */ + sp->opt_delta.type = LZMA_DELTA_TYPE_BYTE; + /* + * The sample size in bytes seems to be reasonable distance for delta + * filter. + */ + sp->opt_delta.dist = (tif->tif_dir.td_bitspersample % 8) ? + 1 : tif->tif_dir.td_bitspersample / 8; + sp->filters[0].id = LZMA_FILTER_DELTA; + sp->filters[0].options = &sp->opt_delta; + + lzma_lzma_preset(&sp->opt_lzma, sp->preset); + sp->filters[1].id = LZMA_FILTER_LZMA2; + sp->filters[1].options = &sp->opt_lzma; + + sp->filters[2].id = LZMA_VLI_UNKNOWN; + sp->filters[2].options = NULL; + + /* + * Install codec methods. + */ + tif->tif_fixuptags = LZMAFixupTags; + tif->tif_setupdecode = LZMASetupDecode; + tif->tif_predecode = LZMAPreDecode; + tif->tif_decoderow = LZMADecode; + tif->tif_decodestrip = LZMADecode; + tif->tif_decodetile = LZMADecode; + tif->tif_setupencode = LZMASetupEncode; + tif->tif_preencode = LZMAPreEncode; + tif->tif_postencode = LZMAPostEncode; + tif->tif_encoderow = LZMAEncode; + tif->tif_encodestrip = LZMAEncode; + tif->tif_encodetile = LZMAEncode; + tif->tif_cleanup = LZMACleanup; + /* + * Setup predictor setup. + */ + (void) TIFFPredictorInit(tif); + return 1; +bad: + TIFFErrorExt(tif->tif_clientdata, module, + "No space for LZMA2 state block"); + return 0; +} +#endif /* LZMA_SUPORT */ + +/* vim: set ts=8 sts=8 sw=8 noet: */ diff --git a/thirdparty/libtiff/tif_lzw.c b/thirdparty/libtiff/tif_lzw.c index d4238663..58345f0a 100644 --- a/thirdparty/libtiff/tif_lzw.c +++ b/thirdparty/libtiff/tif_lzw.c @@ -1,4 +1,4 @@ -/* $Id: tif_lzw.c,v 1.29.2.6 2010-06-08 18:50:42 bfriesen Exp $ */ +/* $Id: tif_lzw.c,v 1.47 2015-06-13 05:03:50 faxguy Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -27,7 +27,7 @@ #include "tiffiop.h" #ifdef LZW_SUPPORT /* - * TIFF Library. + * TIFF Library. * Rev 5.0 Lempel-Ziv & Welch Compression Support * * This code is derived from the compress program whose code is @@ -53,34 +53,34 @@ * * Future revisions to the TIFF spec are expected to "clarify this issue". */ -#define LZW_COMPAT /* include backwards compatibility code */ +#define LZW_COMPAT /* include backwards compatibility code */ /* * Each strip of data is supposed to be terminated by a CODE_EOI. * If the following #define is included, the decoder will also * check for end-of-strip w/o seeing this code. This makes the * library more robust, but also slower. */ -#define LZW_CHECKEOS /* include checks for strips w/o EOI code */ +#define LZW_CHECKEOS /* include checks for strips w/o EOI code */ #define MAXCODE(n) ((1L<<(n))-1) /* * The TIFF spec specifies that encoded bit * strings range from 9 to 12 bits. */ -#define BITS_MIN 9 /* start with 9 bits */ -#define BITS_MAX 12 /* max of 12 bit strings */ +#define BITS_MIN 9 /* start with 9 bits */ +#define BITS_MAX 12 /* max of 12 bit strings */ /* predefined codes */ -#define CODE_CLEAR 256 /* code to clear string table */ -#define CODE_EOI 257 /* end-of-information code */ -#define CODE_FIRST 258 /* first free code entry */ -#define CODE_MAX MAXCODE(BITS_MAX) -#define HSIZE 9001L /* 91% occupancy */ -#define HSHIFT (13-8) +#define CODE_CLEAR 256 /* code to clear string table */ +#define CODE_EOI 257 /* end-of-information code */ +#define CODE_FIRST 258 /* first free code entry */ +#define CODE_MAX MAXCODE(BITS_MAX) +#define HSIZE 9001L /* 91% occupancy */ +#define HSHIFT (13-8) #ifdef LZW_COMPAT /* NB: +1024 is for compatibility with old files */ -#define CSIZE (MAXCODE(BITS_MAX)+1024L) +#define CSIZE (MAXCODE(BITS_MAX)+1024L) #else -#define CSIZE (MAXCODE(BITS_MAX)+1L) +#define CSIZE (MAXCODE(BITS_MAX)+1L) #endif /* @@ -88,23 +88,23 @@ * compression/decompression. Note that the predictor * state block must be first in this data structure. */ -typedef struct { - TIFFPredictorState predict; /* predictor super class */ +typedef struct { + TIFFPredictorState predict; /* predictor super class */ - 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 */ - long nextbits; /* # of valid bits in lzw_nextdata */ + 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 */ + long nextbits; /* # of valid bits in lzw_nextdata */ - int rw_mode; /* preserve rw_mode from init */ + int rw_mode; /* preserve rw_mode from init */ } LZWBaseState; -#define lzw_nbits base.nbits -#define lzw_maxcode base.maxcode -#define lzw_free_ent base.free_ent -#define lzw_nextdata base.nextdata -#define lzw_nextbits base.nextbits +#define lzw_nbits base.nbits +#define lzw_maxcode base.maxcode +#define lzw_free_ent base.free_ent +#define lzw_nextdata base.nextdata +#define lzw_nextbits base.nextbits /* * Encoding-specific state. @@ -125,44 +125,44 @@ typedef struct code_ent { unsigned char firstchar; /* first token of string */ } code_t; -typedef int (*decodeFunc)(TIFF*, tidata_t, tsize_t, tsample_t); +typedef int (*decodeFunc)(TIFF*, uint8*, tmsize_t, uint16); typedef struct { LZWBaseState base; /* Decoding specific data */ - long dec_nbitsmask; /* lzw_nbits 1 bits, right adjusted */ - long dec_restart; /* restart count */ + long dec_nbitsmask; /* lzw_nbits 1 bits, right adjusted */ + long dec_restart; /* restart count */ #ifdef LZW_CHECKEOS - long dec_bitsleft; /* available bits in raw data */ + uint64 dec_bitsleft; /* available bits in raw data */ #endif decodeFunc dec_decode; /* regular or backwards compatible */ - code_t* dec_codep; /* current recognized code */ - code_t* dec_oldcodep; /* previously recognized code */ - code_t* dec_free_entp; /* next free entry */ - code_t* dec_maxcodep; /* max available entry */ - code_t* dec_codetab; /* kept separate for small machines */ + code_t* dec_codep; /* current recognized code */ + code_t* dec_oldcodep; /* previously recognized code */ + code_t* dec_free_entp; /* next free entry */ + code_t* dec_maxcodep; /* max available entry */ + code_t* dec_codetab; /* kept separate for small machines */ /* Encoding specific data */ - int enc_oldcode; /* last code encountered */ - long enc_checkpoint; /* point at which to clear table */ + int enc_oldcode; /* last code encountered */ + long enc_checkpoint; /* point at which to clear table */ #define CHECK_GAP 10000 /* enc_ratio check interval */ - long enc_ratio; /* current compression ratio */ - long enc_incount; /* (input) data bytes encoded */ - long enc_outcount; /* encoded (output) bytes */ - tidata_t enc_rawlimit; /* bound on tif_rawdata buffer */ - hash_t* enc_hashtab; /* kept separate for small machines */ + long enc_ratio; /* current compression ratio */ + long enc_incount; /* (input) data bytes encoded */ + long enc_outcount; /* encoded (output) bytes */ + uint8* enc_rawlimit; /* bound on tif_rawdata buffer */ + hash_t* enc_hashtab; /* kept separate for small machines */ } LZWCodecState; -#define LZWState(tif) ((LZWBaseState*) (tif)->tif_data) -#define DecoderState(tif) ((LZWCodecState*) LZWState(tif)) -#define EncoderState(tif) ((LZWCodecState*) LZWState(tif)) +#define LZWState(tif) ((LZWBaseState*) (tif)->tif_data) +#define DecoderState(tif) ((LZWCodecState*) LZWState(tif)) +#define EncoderState(tif) ((LZWCodecState*) LZWState(tif)) -static int LZWDecode(TIFF*, tidata_t, tsize_t, tsample_t); +static int LZWDecode(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s); #ifdef LZW_COMPAT -static int LZWDecodeCompat(TIFF*, tidata_t, tsize_t, tsample_t); +static int LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s); #endif -static void cl_hash(LZWCodecState*); +static void cl_hash(LZWCodecState*); /* * LZW Decoder. @@ -174,8 +174,8 @@ static void cl_hash(LZWCodecState*); * strip is suppose to be terminated with CODE_EOI. */ #define NextCode(_tif, _sp, _bp, _code, _get) { \ - if ((_sp)->dec_bitsleft < nbits) { \ - TIFFWarningExt(_tif->tif_clientdata, _tif->tif_name, \ + if ((_sp)->dec_bitsleft < (uint64)nbits) { \ + TIFFWarningExt(_tif->tif_clientdata, module, \ "LZWDecode: Strip %d not terminated with EOI code", \ _tif->tif_curstrip); \ _code = CODE_EOI; \ @@ -188,37 +188,44 @@ static void cl_hash(LZWCodecState*); #define NextCode(tif, sp, bp, code, get) get(sp, bp, code) #endif +static int +LZWFixupTags(TIFF* tif) +{ + (void) tif; + return (1); +} + static int LZWSetupDecode(TIFF* tif) { + static const char module[] = "LZWSetupDecode"; LZWCodecState* sp = DecoderState(tif); - static const char module[] = " LZWSetupDecode"; int code; - if( sp == NULL ) - { - /* - * Allocate state block so tag methods have storage to record - * values. - */ - tif->tif_data = (tidata_t) _TIFFmalloc(sizeof(LZWCodecState)); - if (tif->tif_data == NULL) - { - TIFFErrorExt(tif->tif_clientdata, "LZWPreDecode", "No space for LZW state block"); - return (0); - } + if( sp == NULL ) + { + /* + * Allocate state block so tag methods have storage to record + * values. + */ + tif->tif_data = (uint8*) _TIFFmalloc(sizeof(LZWCodecState)); + if (tif->tif_data == NULL) + { + TIFFErrorExt(tif->tif_clientdata, module, "No space for LZW state block"); + return (0); + } - DecoderState(tif)->dec_codetab = NULL; - DecoderState(tif)->dec_decode = NULL; - - /* - * Setup predictor setup. - */ - (void) TIFFPredictorInit(tif); + DecoderState(tif)->dec_codetab = NULL; + DecoderState(tif)->dec_decode = NULL; + + /* + * Setup predictor setup. + */ + (void) TIFFPredictorInit(tif); + + sp = DecoderState(tif); + } - sp = DecoderState(tif); - } - assert(sp != NULL); if (sp->dec_codetab == NULL) { @@ -231,13 +238,13 @@ LZWSetupDecode(TIFF* tif) /* * Pre-load the table. */ - code = 255; - do { - sp->dec_codetab[code].value = code; - sp->dec_codetab[code].firstchar = code; - sp->dec_codetab[code].length = 1; - sp->dec_codetab[code].next = NULL; - } while (code--); + code = 255; + do { + sp->dec_codetab[code].value = code; + sp->dec_codetab[code].firstchar = code; + sp->dec_codetab[code].length = 1; + sp->dec_codetab[code].next = NULL; + } while (code--); /* * Zero-out the unused entries */ @@ -251,15 +258,18 @@ LZWSetupDecode(TIFF* tif) * Setup state for decoding a strip. */ static int -LZWPreDecode(TIFF* tif, tsample_t s) +LZWPreDecode(TIFF* tif, uint16 s) { + static const char module[] = "LZWPreDecode"; LZWCodecState *sp = DecoderState(tif); (void) s; assert(sp != NULL); - if( sp->dec_codetab == NULL ) + if( sp->dec_codetab == NULL ) { tif->tif_setupdecode( tif ); + if( sp->dec_codetab == NULL ) + return (0); } /* @@ -268,7 +278,7 @@ LZWPreDecode(TIFF* tif, tsample_t s) if (tif->tif_rawdata[0] == 0 && (tif->tif_rawdata[1] & 0x1)) { #ifdef LZW_COMPAT if (!sp->dec_decode) { - TIFFWarningExt(tif->tif_clientdata, tif->tif_name, + TIFFWarningExt(tif->tif_clientdata, module, "Old-style LZW codes, convert file"); /* * Override default decoding methods with @@ -291,7 +301,7 @@ LZWPreDecode(TIFF* tif, tsample_t s) sp->lzw_maxcode = MAXCODE(BITS_MIN); #else /* !LZW_COMPAT */ if (!sp->dec_decode) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + TIFFErrorExt(tif->tif_clientdata, module, "Old-style LZW codes not supported"); sp->dec_decode = LZWDecode; } @@ -308,7 +318,7 @@ LZWPreDecode(TIFF* tif, tsample_t s) sp->dec_restart = 0; sp->dec_nbitsmask = MAXCODE(BITS_MIN); #ifdef LZW_CHECKEOS - sp->dec_bitsleft = tif->tif_rawcc << 3; + sp->dec_bitsleft = ((uint64)tif->tif_rawcc) << 3; #endif sp->dec_free_entp = sp->dec_codetab + CODE_FIRST; /* @@ -339,16 +349,17 @@ LZWPreDecode(TIFF* tif, tsample_t s) } static void -codeLoop(TIFF* tif) +codeLoop(TIFF* tif, const char* module) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "LZWDecode: Bogus encoding, loop in the code table; scanline %d", + TIFFErrorExt(tif->tif_clientdata, module, + "Bogus encoding, loop in the code table; scanline %d", tif->tif_row); } static int -LZWDecode(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) +LZWDecode(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) { + static const char module[] = "LZWDecode"; LZWCodecState *sp = DecoderState(tif); char *op = (char*) op0; long occ = (long) occ0; @@ -362,6 +373,12 @@ LZWDecode(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) (void) s; assert(sp != NULL); assert(sp->dec_codetab != NULL); + + /* + Fail if value does not fit in long. + */ + if ((tmsize_t) occ != occ0) + return (0); /* * Restart interrupted output operation. */ @@ -419,16 +436,18 @@ LZWDecode(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) if (code == CODE_EOI) break; if (code == CODE_CLEAR) { - free_entp = sp->dec_codetab + CODE_FIRST; - _TIFFmemset(free_entp, 0, - (CSIZE - CODE_FIRST) * sizeof (code_t)); - nbits = BITS_MIN; - nbitsmask = MAXCODE(BITS_MIN); - maxcodep = sp->dec_codetab + nbitsmask-1; - NextCode(tif, sp, bp, code, GetNextCode); + do { + free_entp = sp->dec_codetab + CODE_FIRST; + _TIFFmemset(free_entp, 0, + (CSIZE - CODE_FIRST) * sizeof (code_t)); + nbits = BITS_MIN; + 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); @@ -441,22 +460,22 @@ LZWDecode(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) codep = sp->dec_codetab + code; /* - * Add the new entry to the code table. - */ + * Add the new entry to the code table. + */ if (free_entp < &sp->dec_codetab[0] || - free_entp >= &sp->dec_codetab[CSIZE]) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "LZWDecode: Corrupted LZW table at scanline %d", - tif->tif_row); + free_entp >= &sp->dec_codetab[CSIZE]) { + TIFFErrorExt(tif->tif_clientdata, module, + "Corrupted LZW table at scanline %d", + tif->tif_row); return (0); } free_entp->next = oldcodep; if (free_entp->next < &sp->dec_codetab[0] || - free_entp->next >= &sp->dec_codetab[CSIZE]) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "LZWDecode: Corrupted LZW table at scanline %d", - tif->tif_row); + free_entp->next >= &sp->dec_codetab[CSIZE]) { + TIFFErrorExt(tif->tif_clientdata, module, + "Corrupted LZW table at scanline %d", + tif->tif_row); return (0); } free_entp->firstchar = free_entp->next->firstchar; @@ -472,15 +491,15 @@ LZWDecode(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) oldcodep = codep; if (code >= 256) { /* - * Code maps to a string, copy string + * Code maps to a string, copy string * value to output (written in reverse). - */ + */ if(codep->length == 0) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "LZWDecode: Wrong length of decoded string: " - "data probably corrupted at scanline %d", - tif->tif_row); - return (0); + TIFFErrorExt(tif->tif_clientdata, module, + "Wrong length of decoded string: " + "data probably corrupted at scanline %d", + tif->tif_row); + return (0); } if (codep->length > occ) { /* @@ -494,14 +513,14 @@ LZWDecode(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) codep = codep->next; } while (codep && codep->length > occ); if (codep) { - sp->dec_restart = occ; + sp->dec_restart = (long)occ; tp = op + occ; do { *--tp = codep->value; codep = codep->next; } while (--occ && codep); if (codep) - codeLoop(tif); + codeLoop(tif, module); } break; } @@ -515,15 +534,16 @@ LZWDecode(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) *tp = t; } while (codep && tp > op); if (codep) { - codeLoop(tif); + codeLoop(tif, module); break; } + assert(occ >= len); op += len, occ -= len; } else *op++ = (char)code, occ--; } - tif->tif_rawcp = (tidata_t) bp; + tif->tif_rawcp = (uint8*) bp; sp->lzw_nbits = (unsigned short) nbits; sp->lzw_nextdata = nextdata; sp->lzw_nextbits = nextbits; @@ -533,9 +553,15 @@ LZWDecode(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) sp->dec_maxcodep = maxcodep; if (occ > 0) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "LZWDecode: Not enough data at scanline %d (short %ld bytes)", - tif->tif_row, occ); +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data at scanline %d (short %I64d bytes)", + tif->tif_row, (unsigned __int64) occ); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data at scanline %d (short %llu bytes)", + tif->tif_row, (unsigned long long) occ); +#endif return (0); } return (1); @@ -558,8 +584,9 @@ LZWDecode(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) } static int -LZWDecodeCompat(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) +LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) { + static const char module[] = "LZWDecodeCompat"; LZWCodecState *sp = DecoderState(tif); char *op = (char*) op0; long occ = (long) occ0; @@ -571,6 +598,13 @@ LZWDecodeCompat(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) (void) s; assert(sp != NULL); + + /* + Fail if value does not fit in long. + */ + if ((tmsize_t) occ != occ0) + return (0); + /* * Restart interrupted output operation. */ @@ -623,16 +657,18 @@ LZWDecodeCompat(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) if (code == CODE_EOI) break; if (code == CODE_CLEAR) { - free_entp = sp->dec_codetab + CODE_FIRST; - _TIFFmemset(free_entp, 0, - (CSIZE - CODE_FIRST) * sizeof (code_t)); - nbits = BITS_MIN; - nbitsmask = MAXCODE(BITS_MIN); - maxcodep = sp->dec_codetab + nbitsmask; - NextCode(tif, sp, bp, code, GetNextCodeCompat); + do { + free_entp = sp->dec_codetab + CODE_FIRST; + _TIFFmemset(free_entp, 0, + (CSIZE - CODE_FIRST) * sizeof (code_t)); + nbits = BITS_MIN; + 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); @@ -645,22 +681,20 @@ LZWDecodeCompat(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) codep = sp->dec_codetab + code; /* - * Add the new entry to the code table. - */ + * Add the new entry to the code table. + */ if (free_entp < &sp->dec_codetab[0] || - free_entp >= &sp->dec_codetab[CSIZE]) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "LZWDecodeCompat: Corrupted LZW table at scanline %d", - tif->tif_row); + free_entp >= &sp->dec_codetab[CSIZE]) { + TIFFErrorExt(tif->tif_clientdata, module, + "Corrupted LZW table at scanline %d", tif->tif_row); return (0); } free_entp->next = oldcodep; if (free_entp->next < &sp->dec_codetab[0] || - free_entp->next >= &sp->dec_codetab[CSIZE]) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "LZWDecodeCompat: Corrupted LZW table at scanline %d", - tif->tif_row); + free_entp->next >= &sp->dec_codetab[CSIZE]) { + TIFFErrorExt(tif->tif_clientdata, module, + "Corrupted LZW table at scanline %d", tif->tif_row); return (0); } free_entp->firstchar = free_entp->next->firstchar; @@ -675,17 +709,16 @@ LZWDecodeCompat(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) } oldcodep = codep; if (code >= 256) { - char *op_orig = op; /* - * Code maps to a string, copy string + * Code maps to a string, copy string * value to output (written in reverse). - */ + */ if(codep->length == 0) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "LZWDecodeCompat: Wrong length of decoded " - "string: data probably corrupted at scanline %d", - tif->tif_row); - return (0); + TIFFErrorExt(tif->tif_clientdata, module, + "Wrong length of decoded " + "string: data probably corrupted at scanline %d", + tif->tif_row); + return (0); } if (codep->length > occ) { /* @@ -706,16 +739,17 @@ LZWDecodeCompat(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) } while (--occ); break; } + assert(occ >= codep->length); op += codep->length, occ -= codep->length; tp = op; do { *--tp = codep->value; - } while( (codep = codep->next) != NULL && tp > op_orig); + } while( (codep = codep->next) != NULL ); } else *op++ = code, occ--; } - tif->tif_rawcp = (tidata_t) bp; + tif->tif_rawcp = (uint8*) bp; sp->lzw_nbits = nbits; sp->lzw_nextdata = nextdata; sp->lzw_nextbits = nextbits; @@ -725,9 +759,15 @@ LZWDecodeCompat(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) sp->dec_maxcodep = maxcodep; if (occ > 0) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "LZWDecodeCompat: Not enough data at scanline %d (short %ld bytes)", - tif->tif_row, occ); +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data at scanline %d (short %I64d bytes)", + tif->tif_row, (unsigned __int64) occ); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data at scanline %d (short %llu bytes)", + tif->tif_row, (unsigned long long) occ); +#endif return (0); } return (1); @@ -741,13 +781,14 @@ LZWDecodeCompat(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) static int LZWSetupEncode(TIFF* tif) { - LZWCodecState* sp = EncoderState(tif); static const char module[] = "LZWSetupEncode"; + LZWCodecState* sp = EncoderState(tif); assert(sp != NULL); sp->enc_hashtab = (hash_t*) _TIFFmalloc(HSIZE*sizeof (hash_t)); if (sp->enc_hashtab == NULL) { - TIFFErrorExt(tif->tif_clientdata, module, "No space for LZW hash table"); + TIFFErrorExt(tif->tif_clientdata, module, + "No space for LZW hash table"); return (0); } return (1); @@ -757,14 +798,14 @@ LZWSetupEncode(TIFF* tif) * Reset encoding state at the start of a strip. */ static int -LZWPreEncode(TIFF* tif, tsample_t s) +LZWPreEncode(TIFF* tif, uint16 s) { LZWCodecState *sp = EncoderState(tif); (void) s; assert(sp != NULL); - - if( sp->enc_hashtab == NULL ) + + if( sp->enc_hashtab == NULL ) { tif->tif_setupencode( tif ); } @@ -822,7 +863,7 @@ LZWPreEncode(TIFF* tif, tsample_t s) * for the decoder. */ static int -LZWEncode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +LZWEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) { register LZWCodecState *sp = EncoderState(tif); register long fcode; @@ -833,7 +874,8 @@ LZWEncode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) long incount, outcount, checkpoint; long nextdata, nextbits; int free_ent, maxcode, nbits; - tidata_t op, limit; + uint8* op; + uint8* limit; (void) s; if (sp == NULL) @@ -912,7 +954,7 @@ LZWEncode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) * are at least 4 bytes free--room for 2 codes. */ if (op > limit) { - tif->tif_rawcc = (tsize_t)(op - tif->tif_rawdata); + tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); TIFFFlushData1(tif); op = tif->tif_rawdata; } @@ -990,14 +1032,14 @@ static int LZWPostEncode(TIFF* tif) { register LZWCodecState *sp = EncoderState(tif); - tidata_t op = tif->tif_rawcp; + uint8* op = tif->tif_rawcp; long nextbits = sp->lzw_nextbits; long nextdata = sp->lzw_nextdata; long outcount = sp->enc_outcount; int nbits = sp->lzw_nbits; if (op > sp->enc_rawlimit) { - tif->tif_rawcc = (tsize_t)(op - tif->tif_rawdata); + tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); TIFFFlushData1(tif); op = tif->tif_rawdata; } @@ -1008,7 +1050,7 @@ LZWPostEncode(TIFF* tif) PutNextCode(op, CODE_EOI); if (nextbits > 0) *op++ = (unsigned char)(nextdata << (8-nextbits)); - tif->tif_rawcc = (tsize_t)(op - tif->tif_rawdata); + tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); return (1); } @@ -1021,7 +1063,7 @@ cl_hash(LZWCodecState* sp) register hash_t *hp = &sp->enc_hashtab[HSIZE-1]; register long i = HSIZE-8; - do { + do { i -= 8; hp[-7].hash = -1; hp[-6].hash = -1; @@ -1033,7 +1075,7 @@ cl_hash(LZWCodecState* sp) hp[ 0].hash = -1; hp -= 8; } while (i >= 0); - for (i += 8; i > 0; i--, hp--) + for (i += 8; i > 0; i--, hp--) hp->hash = -1; } @@ -1059,11 +1101,12 @@ LZWCleanup(TIFF* tif) int TIFFInitLZW(TIFF* tif, int scheme) { + static const char module[] = "TIFFInitLZW"; assert(scheme == COMPRESSION_LZW); /* * Allocate state block so tag methods have storage to record values. */ - tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (LZWCodecState)); + tif->tif_data = (uint8*) _TIFFmalloc(sizeof (LZWCodecState)); if (tif->tif_data == NULL) goto bad; DecoderState(tif)->dec_codetab = NULL; @@ -1074,6 +1117,7 @@ TIFFInitLZW(TIFF* tif, int scheme) /* * Install codec methods. */ + tif->tif_fixuptags = LZWFixupTags; tif->tif_setupdecode = LZWSetupDecode; tif->tif_predecode = LZWPreDecode; tif->tif_decoderow = LZWDecode; @@ -1092,7 +1136,7 @@ TIFFInitLZW(TIFF* tif, int scheme) (void) TIFFPredictorInit(tif); return (1); bad: - TIFFErrorExt(tif->tif_clientdata, "TIFFInitLZW", + TIFFErrorExt(tif->tif_clientdata, module, "No space for LZW state block"); return (0); } diff --git a/thirdparty/libtiff/tif_next.c b/thirdparty/libtiff/tif_next.c index d7652bb4..17e03111 100644 --- a/thirdparty/libtiff/tif_next.c +++ b/thirdparty/libtiff/tif_next.c @@ -1,4 +1,4 @@ -/* $Id: tif_next.c,v 1.8.2.1 2010-06-08 18:50:42 bfriesen Exp $ */ +/* $Id: tif_next.c,v 1.16 2014-12-29 12:09:11 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -46,12 +46,13 @@ #define WHITE ((1<<2)-1) static int -NeXTDecode(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) +NeXTDecode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) { + static const char module[] = "NeXTDecode"; unsigned char *bp, *op; - tsize_t cc; - tidata_t row; - tsize_t scanline, n; + tmsize_t cc; + uint8* row; + tmsize_t scanline, n; (void) s; /* @@ -59,13 +60,18 @@ NeXTDecode(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) * white (we assume a PhotometricInterpretation * of ``min-is-black''). */ - for (op = buf, cc = occ; cc-- > 0;) + for (op = (unsigned char*) buf, cc = occ; cc-- > 0;) *op++ = 0xff; bp = (unsigned char *)tif->tif_rawcp; cc = tif->tif_rawcc; scanline = tif->tif_scanlinesize; - for (row = buf; occ > 0; occ -= scanline, row += scanline) { + if (occ % scanline) + { + TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read"); + return (0); + } + for (row = buf; cc > 0 && occ > 0; occ -= scanline, row += scanline) { n = *bp++, cc--; switch (n) { case LITERALROW: @@ -79,11 +85,13 @@ NeXTDecode(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) cc -= scanline; break; case LITERALSPAN: { - tsize_t off; + tmsize_t off; /* * 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) @@ -96,6 +104,8 @@ NeXTDecode(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) default: { uint32 npixels = 0, grey; 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 @@ -105,7 +115,7 @@ NeXTDecode(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) */ op = row; for (;;) { - grey = (n>>6) & 0x3; + grey = (uint32)((n>>6) & 0x3); n &= 0x3f; /* * Ensure the run does not exceed the scanline @@ -124,21 +134,38 @@ NeXTDecode(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) } } } - tif->tif_rawcp = (tidata_t) bp; + tif->tif_rawcp = (uint8*) bp; tif->tif_rawcc = cc; return (1); bad: - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "NeXTDecode: Not enough data for scanline %ld", + TIFFErrorExt(tif->tif_clientdata, module, "Not enough data for scanline %ld", (long) tif->tif_row); 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_decoderow = NeXTDecode; - tif->tif_decodestrip = NeXTDecode; + tif->tif_predecode = NeXTPreDecode; + tif->tif_decoderow = NeXTDecode; + tif->tif_decodestrip = NeXTDecode; tif->tif_decodetile = NeXTDecode; return (1); } diff --git a/thirdparty/libtiff/tif_ojpeg.c b/thirdparty/libtiff/tif_ojpeg.c index 9ae856cf..23d40622 100644 --- a/thirdparty/libtiff/tif_ojpeg.c +++ b/thirdparty/libtiff/tif_ojpeg.c @@ -1,4 +1,4 @@ -/* $Id: tif_ojpeg.c,v 1.24.2.6 2010-06-08 23:29:51 bfriesen Exp $ */ +/* $Id: tif_ojpeg.c,v 1.60 2015-05-31 00:38:46 bfriesen 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 . */ @@ -120,6 +120,8 @@ session. */ +#define WIN32_LEAN_AND_MEAN +#define VC_EXTRALEAN #include "tiffiop.h" #ifdef OJPEG_SUPPORT @@ -139,14 +141,14 @@ * 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 * absolutely no effect. That is why most people insist the EGYPTIANWALK is a bit silly. */ -/* #define LIBJPEG_ENCAP_EXTERNAL */ +/* define LIBJPEG_ENCAP_EXTERNAL */ #define SETJMP(jbuf) setjmp(jbuf) #define LONGJMP(jbuf,code) longjmp(jbuf,code) #define JMP_BUF jmp_buf @@ -173,22 +175,45 @@ #define FIELD_OJPEG_JPEGACTABLES (FIELD_CODEC+4) #define FIELD_OJPEG_JPEGPROC (FIELD_CODEC+5) #define FIELD_OJPEG_JPEGRESTARTINTERVAL (FIELD_CODEC+6) -#define FIELD_OJPEG_COUNT 7 -static const TIFFFieldInfo ojpeg_field_info[] = { - {TIFFTAG_JPEGIFOFFSET,1,1,TIFF_LONG,FIELD_OJPEG_JPEGINTERCHANGEFORMAT,TRUE,FALSE,"JpegInterchangeFormat"}, - {TIFFTAG_JPEGIFBYTECOUNT,1,1,TIFF_LONG,FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH,TRUE,FALSE,"JpegInterchangeFormatLength"}, - {TIFFTAG_JPEGQTABLES,TIFF_VARIABLE,TIFF_VARIABLE,TIFF_LONG,FIELD_OJPEG_JPEGQTABLES,FALSE,TRUE,"JpegQTables"}, - {TIFFTAG_JPEGDCTABLES,TIFF_VARIABLE,TIFF_VARIABLE,TIFF_LONG,FIELD_OJPEG_JPEGDCTABLES,FALSE,TRUE,"JpegDcTables"}, - {TIFFTAG_JPEGACTABLES,TIFF_VARIABLE,TIFF_VARIABLE,TIFF_LONG,FIELD_OJPEG_JPEGACTABLES,FALSE,TRUE,"JpegAcTables"}, - {TIFFTAG_JPEGPROC,1,1,TIFF_SHORT,FIELD_OJPEG_JPEGPROC,FALSE,FALSE,"JpegProc"}, - {TIFFTAG_JPEGRESTARTINTERVAL,1,1,TIFF_SHORT,FIELD_OJPEG_JPEGRESTARTINTERVAL,FALSE,FALSE,"JpegRestartInterval"}, +static const TIFFField ojpegFields[] = { + {TIFFTAG_JPEGIFOFFSET,1,1,TIFF_LONG8,0,TIFF_SETGET_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGINTERCHANGEFORMAT,TRUE,FALSE,"JpegInterchangeFormat",NULL}, + {TIFFTAG_JPEGIFBYTECOUNT,1,1,TIFF_LONG8,0,TIFF_SETGET_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH,TRUE,FALSE,"JpegInterchangeFormatLength",NULL}, + {TIFFTAG_JPEGQTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGQTABLES,FALSE,TRUE,"JpegQTables",NULL}, + {TIFFTAG_JPEGDCTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGDCTABLES,FALSE,TRUE,"JpegDcTables",NULL}, + {TIFFTAG_JPEGACTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGACTABLES,FALSE,TRUE,"JpegAcTables",NULL}, + {TIFFTAG_JPEGPROC,1,1,TIFF_SHORT,0,TIFF_SETGET_UINT16,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGPROC,FALSE,FALSE,"JpegProc",NULL}, + {TIFFTAG_JPEGRESTARTINTERVAL,1,1,TIFF_SHORT,0,TIFF_SETGET_UINT16,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGRESTARTINTERVAL,FALSE,FALSE,"JpegRestartInterval",NULL}, }; #ifndef LIBJPEG_ENCAP_EXTERNAL #include #endif +/* We undefine FAR to avoid conflict with JPEG definition */ + +#ifdef FAR +#undef FAR +#endif + +/* + 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. +*/ +#if defined(__BORLANDC__) || defined(__MINGW32__) +# define XMD_H 1 +#endif + +/* Define "boolean" as unsigned char, not int, per Windows custom. */ +#if defined(__WIN32__) && !defined(__MINGW32__) +# ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ + typedef unsigned char boolean; +# endif +# define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ +#endif + #include "jpeglib.h" #include "jerror.h" @@ -224,7 +249,8 @@ typedef struct { #endif TIFFVGetMethod vgetparent; TIFFVSetMethod vsetparent; - toff_t file_size; + TIFFPrintMethod printdir; + uint64 file_size; uint32 image_width; uint32 image_length; uint32 strile_width; @@ -233,8 +259,8 @@ typedef struct { uint8 samples_per_pixel; uint8 plane_sample_offset; uint8 samples_per_pixel_per_plane; - toff_t jpeg_interchange_format; - toff_t jpeg_interchange_format_length; + uint64 jpeg_interchange_format; + uint64 jpeg_interchange_format_length; uint8 jpeg_proc; uint8 subsamplingcorrect; uint8 subsamplingcorrect_done; @@ -245,9 +271,9 @@ typedef struct { uint8 qtable_offset_count; uint8 dctable_offset_count; uint8 actable_offset_count; - toff_t qtable_offset[3]; - toff_t dctable_offset[3]; - toff_t actable_offset[3]; + uint64 qtable_offset[3]; + uint64 dctable_offset[3]; + uint64 actable_offset[3]; uint8* qtable[4]; uint8* dctable[4]; uint8* actable[4]; @@ -265,14 +291,14 @@ typedef struct { struct { uint8 log; OJPEGStateInBufferSource in_buffer_source; - tstrile_t in_buffer_next_strile; - toff_t in_buffer_file_pos; - toff_t in_buffer_file_togo; + uint32 in_buffer_next_strile; + uint64 in_buffer_file_pos; + uint64 in_buffer_file_togo; } sos_end[3]; uint8 readheader_done; uint8 writeheader_done; - tsample_t write_cursample; - tstrile_t write_curstrile; + uint16 write_cursample; + uint32 write_curstrile; uint8 libjpeg_session_active; uint8 libjpeg_jpeg_query_style; jpeg_error_mgr libjpeg_jpeg_error_mgr; @@ -297,11 +323,11 @@ typedef struct { uint32 bytes_per_line; /* if the codec outputs subsampled data, a 'line' in bytes_per_line */ uint32 lines_per_strile; /* and lines_per_strile means subsampling_ver desubsampled rows */ OJPEGStateInBufferSource in_buffer_source; - tstrile_t in_buffer_next_strile; - tstrile_t in_buffer_strile_count; - toff_t in_buffer_file_pos; + uint32 in_buffer_next_strile; + uint32 in_buffer_strile_count; + uint64 in_buffer_file_pos; uint8 in_buffer_file_pos_log; - toff_t in_buffer_file_togo; + uint64 in_buffer_file_togo; uint16 in_buffer_togo; uint8* in_buffer_cur; uint8 in_buffer[OJPEG_BUFFER]; @@ -310,27 +336,28 @@ typedef struct { uint8* skip_buffer; } OJPEGState; -static int OJPEGVGetField(TIFF* tif, ttag_t tag, va_list ap); -static int OJPEGVSetField(TIFF* tif, ttag_t tag, va_list ap); +static int OJPEGVGetField(TIFF* tif, uint32 tag, va_list ap); +static int OJPEGVSetField(TIFF* tif, uint32 tag, va_list ap); static void OJPEGPrintDir(TIFF* tif, FILE* fd, long flags); +static int OJPEGFixupTags(TIFF* tif); static int OJPEGSetupDecode(TIFF* tif); -static int OJPEGPreDecode(TIFF* tif, tsample_t s); +static int OJPEGPreDecode(TIFF* tif, uint16 s); static int OJPEGPreDecodeSkipRaw(TIFF* tif); static int OJPEGPreDecodeSkipScanlines(TIFF* tif); -static int OJPEGDecode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s); -static int OJPEGDecodeRaw(TIFF* tif, tidata_t buf, tsize_t cc); -static int OJPEGDecodeScanlines(TIFF* tif, tidata_t buf, tsize_t cc); -static void OJPEGPostDecode(TIFF* tif, tidata_t buf, tsize_t cc); +static int OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s); +static int OJPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc); +static int OJPEGDecodeScanlines(TIFF* tif, uint8* buf, tmsize_t cc); +static void OJPEGPostDecode(TIFF* tif, uint8* buf, tmsize_t cc); static int OJPEGSetupEncode(TIFF* tif); -static int OJPEGPreEncode(TIFF* tif, tsample_t s); -static int OJPEGEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s); +static int OJPEGPreEncode(TIFF* tif, uint16 s); +static int OJPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s); static int OJPEGPostEncode(TIFF* tif); static void OJPEGCleanup(TIFF* tif); static void OJPEGSubsamplingCorrect(TIFF* tif); static int OJPEGReadHeaderInfo(TIFF* tif); -static int OJPEGReadSecondarySos(TIFF* tif, tsample_t s); +static int OJPEGReadSecondarySos(TIFF* tif, uint16 s); static int OJPEGWriteHeaderInfo(TIFF* tif); static void OJPEGLibjpegSessionAbort(TIFF* tif); @@ -399,9 +426,9 @@ TIFFInitOJPEG(TIFF* tif, int scheme) /* * Merge codec-specific tag information. */ - if (!_TIFFMergeFieldInfo(tif,ojpeg_field_info,FIELD_OJPEG_COUNT)) { + if (!_TIFFMergeFields(tif, ojpegFields, TIFFArrayCount(ojpegFields))) { TIFFErrorExt(tif->tif_clientdata, module, - "Merging Old JPEG codec-specific tags failed"); + "Merging Old JPEG codec-specific tags failed"); return 0; } @@ -419,25 +446,27 @@ TIFFInitOJPEG(TIFF* tif, int scheme) sp->subsampling_ver=2; TIFFSetField(tif,TIFFTAG_YCBCRSUBSAMPLING,2,2); /* tif codec methods */ + tif->tif_fixuptags=OJPEGFixupTags; tif->tif_setupdecode=OJPEGSetupDecode; tif->tif_predecode=OJPEGPreDecode; - tif->tif_postdecode=OJPEGPostDecode; - tif->tif_decoderow=OJPEGDecode; - tif->tif_decodestrip=OJPEGDecode; - tif->tif_decodetile=OJPEGDecode; + tif->tif_postdecode=OJPEGPostDecode; + tif->tif_decoderow=OJPEGDecode; + tif->tif_decodestrip=OJPEGDecode; + tif->tif_decodetile=OJPEGDecode; tif->tif_setupencode=OJPEGSetupEncode; tif->tif_preencode=OJPEGPreEncode; tif->tif_postencode=OJPEGPostEncode; - tif->tif_encoderow=OJPEGEncode; - tif->tif_encodestrip=OJPEGEncode; - tif->tif_encodetile=OJPEGEncode; + tif->tif_encoderow=OJPEGEncode; + tif->tif_encodestrip=OJPEGEncode; + tif->tif_encodetile=OJPEGEncode; tif->tif_cleanup=OJPEGCleanup; - tif->tif_data=(tidata_t)sp; + tif->tif_data=(uint8*)sp; /* tif tag methods */ sp->vgetparent=tif->tif_tagmethods.vgetfield; tif->tif_tagmethods.vgetfield=OJPEGVGetField; sp->vsetparent=tif->tif_tagmethods.vsetfield; tif->tif_tagmethods.vsetfield=OJPEGVSetField; + sp->printdir=tif->tif_tagmethods.printdir; tif->tif_tagmethods.printdir=OJPEGPrintDir; /* Some OJPEG files don't have strip or tile offsets or bytecounts tags. Some others do, but have totally meaningless or corrupt values @@ -450,16 +479,16 @@ TIFFInitOJPEG(TIFF* tif, int scheme) } static int -OJPEGVGetField(TIFF* tif, ttag_t tag, va_list ap) +OJPEGVGetField(TIFF* tif, uint32 tag, va_list ap) { OJPEGState* sp=(OJPEGState*)tif->tif_data; switch(tag) { case TIFFTAG_JPEGIFOFFSET: - *va_arg(ap,uint32*)=(uint32)sp->jpeg_interchange_format; + *va_arg(ap,uint64*)=(uint64)sp->jpeg_interchange_format; break; case TIFFTAG_JPEGIFBYTECOUNT: - *va_arg(ap,uint32*)=(uint32)sp->jpeg_interchange_format_length; + *va_arg(ap,uint64*)=(uint64)sp->jpeg_interchange_format_length; break; case TIFFTAG_YCBCRSUBSAMPLING: if (sp->subsamplingcorrect_done==0) @@ -469,11 +498,11 @@ OJPEGVGetField(TIFF* tif, ttag_t tag, va_list ap) break; case TIFFTAG_JPEGQTABLES: *va_arg(ap,uint32*)=(uint32)sp->qtable_offset_count; - *va_arg(ap,void**)=(void*)sp->qtable_offset; + *va_arg(ap,void**)=(void*)sp->qtable_offset; break; case TIFFTAG_JPEGDCTABLES: *va_arg(ap,uint32*)=(uint32)sp->dctable_offset_count; - *va_arg(ap,void**)=(void*)sp->dctable_offset; + *va_arg(ap,void**)=(void*)sp->dctable_offset; break; case TIFFTAG_JPEGACTABLES: *va_arg(ap,uint32*)=(uint32)sp->actable_offset_count; @@ -492,30 +521,32 @@ OJPEGVGetField(TIFF* tif, ttag_t tag, va_list ap) } static int -OJPEGVSetField(TIFF* tif, ttag_t tag, va_list ap) +OJPEGVSetField(TIFF* tif, uint32 tag, va_list ap) { static const char module[]="OJPEGVSetField"; OJPEGState* sp=(OJPEGState*)tif->tif_data; uint32 ma; - uint32* mb; + uint64* mb; uint32 n; + const TIFFField* fip; + switch(tag) { case TIFFTAG_JPEGIFOFFSET: - sp->jpeg_interchange_format=(toff_t)va_arg(ap,uint32); + sp->jpeg_interchange_format=(uint64)va_arg(ap,uint64); break; case TIFFTAG_JPEGIFBYTECOUNT: - sp->jpeg_interchange_format_length=(toff_t)va_arg(ap,uint32); + sp->jpeg_interchange_format_length=(uint64)va_arg(ap,uint64); break; case TIFFTAG_YCBCRSUBSAMPLING: sp->subsampling_tag=1; - sp->subsampling_hor=(uint8)va_arg(ap,int); - sp->subsampling_ver=(uint8)va_arg(ap,int); + sp->subsampling_hor=(uint8)va_arg(ap,uint16_vap); + sp->subsampling_ver=(uint8)va_arg(ap,uint16_vap); tif->tif_dir.td_ycbcrsubsampling[0]=sp->subsampling_hor; tif->tif_dir.td_ycbcrsubsampling[1]=sp->subsampling_ver; break; case TIFFTAG_JPEGQTABLES: - ma=va_arg(ap,uint32); + ma=(uint32)va_arg(ap,uint32); if (ma!=0) { if (ma>3) @@ -524,13 +555,13 @@ OJPEGVSetField(TIFF* tif, ttag_t tag, va_list ap) return(0); } sp->qtable_offset_count=(uint8)ma; - mb=va_arg(ap,uint32*); + mb=(uint64*)va_arg(ap,uint64*); for (n=0; nqtable_offset[n]=(toff_t)mb[n]; + sp->qtable_offset[n]=mb[n]; } break; case TIFFTAG_JPEGDCTABLES: - ma=va_arg(ap,uint32); + ma=(uint32)va_arg(ap,uint32); if (ma!=0) { if (ma>3) @@ -539,13 +570,13 @@ OJPEGVSetField(TIFF* tif, ttag_t tag, va_list ap) return(0); } sp->dctable_offset_count=(uint8)ma; - mb=va_arg(ap,uint32*); + mb=(uint64*)va_arg(ap,uint64*); for (n=0; ndctable_offset[n]=(toff_t)mb[n]; + sp->dctable_offset[n]=mb[n]; } break; case TIFFTAG_JPEGACTABLES: - ma=va_arg(ap,uint32); + ma=(uint32)va_arg(ap,uint32); if (ma!=0) { if (ma>3) @@ -554,21 +585,24 @@ OJPEGVSetField(TIFF* tif, ttag_t tag, va_list ap) return(0); } sp->actable_offset_count=(uint8)ma; - mb=va_arg(ap,uint32*); + mb=(uint64*)va_arg(ap,uint64*); for (n=0; nactable_offset[n]=(toff_t)mb[n]; + sp->actable_offset[n]=mb[n]; } break; case TIFFTAG_JPEGPROC: - sp->jpeg_proc=(uint8)va_arg(ap,uint32); + sp->jpeg_proc=(uint8)va_arg(ap,uint16_vap); break; case TIFFTAG_JPEGRESTARTINTERVAL: - sp->restart_interval=(uint16)va_arg(ap,uint32); + sp->restart_interval=(uint16)va_arg(ap,uint16_vap); break; 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); } @@ -581,34 +615,43 @@ OJPEGPrintDir(TIFF* tif, FILE* fd, long flags) (void)flags; assert(sp!=NULL); if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGINTERCHANGEFORMAT)) - fprintf(fd," JpegInterchangeFormat: %lu\n",(unsigned long)sp->jpeg_interchange_format); + fprintf(fd," JpegInterchangeFormat: " TIFF_UINT64_FORMAT "\n",(TIFF_UINT64_T)sp->jpeg_interchange_format); if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH)) - fprintf(fd," JpegInterchangeFormatLength: %lu\n",(unsigned long)sp->jpeg_interchange_format_length); + fprintf(fd," JpegInterchangeFormatLength: " TIFF_UINT64_FORMAT "\n",(TIFF_UINT64_T)sp->jpeg_interchange_format_length); if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGQTABLES)) { fprintf(fd," JpegQTables:"); for (m=0; mqtable_offset_count; m++) - fprintf(fd," %lu",(unsigned long)sp->qtable_offset[m]); + fprintf(fd," " TIFF_UINT64_FORMAT,(TIFF_UINT64_T)sp->qtable_offset[m]); fprintf(fd,"\n"); } if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGDCTABLES)) { fprintf(fd," JpegDcTables:"); for (m=0; mdctable_offset_count; m++) - fprintf(fd," %lu",(unsigned long)sp->dctable_offset[m]); + fprintf(fd," " TIFF_UINT64_FORMAT,(TIFF_UINT64_T)sp->dctable_offset[m]); fprintf(fd,"\n"); } if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGACTABLES)) { fprintf(fd," JpegAcTables:"); for (m=0; mactable_offset_count; m++) - fprintf(fd," %lu",(unsigned long)sp->actable_offset[m]); + fprintf(fd," " TIFF_UINT64_FORMAT,(TIFF_UINT64_T)sp->actable_offset[m]); fprintf(fd,"\n"); } if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGPROC)) fprintf(fd," JpegProc: %u\n",(unsigned int)sp->jpeg_proc); if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGRESTARTINTERVAL)) fprintf(fd," JpegRestartInterval: %u\n",(unsigned int)sp->restart_interval); + if (sp->printdir) + (*sp->printdir)(tif, fd, flags); +} + +static int +OJPEGFixupTags(TIFF* tif) +{ + (void) tif; + return(1); } static int @@ -620,10 +663,10 @@ OJPEGSetupDecode(TIFF* tif) } static int -OJPEGPreDecode(TIFF* tif, tsample_t s) +OJPEGPreDecode(TIFF* tif, uint16 s) { OJPEGState* sp=(OJPEGState*)tif->tif_data; - tstrile_t m; + uint32 m; if (sp->subsamplingcorrect_done==0) OJPEGSubsamplingCorrect(tif); if (sp->readheader_done==0) @@ -637,9 +680,9 @@ OJPEGPreDecode(TIFF* tif, tsample_t s) return(0); } if isTiled(tif) - m=(tstrile_t)tif->tif_curtile; + m=tif->tif_curtile; else - m=(tstrile_t)tif->tif_curstrip; + m=tif->tif_curstrip; if ((sp->writeheader_done!=0) && ((sp->write_cursample!=s) || (sp->write_curstrile>m))) { if (sp->libjpeg_session_active!=0) @@ -648,7 +691,7 @@ OJPEGPreDecode(TIFF* tif, tsample_t s) } if (sp->writeheader_done==0) { - sp->plane_sample_offset=s; + sp->plane_sample_offset=(uint8)s; sp->write_cursample=s; sp->write_curstrile=s*tif->tif_dir.td_stripsperimage; if ((sp->in_buffer_file_pos_log==0) || @@ -739,7 +782,7 @@ OJPEGPreDecodeSkipScanlines(TIFF* tif) } static int -OJPEGDecode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) +OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) { OJPEGState* sp=(OJPEGState*)tif->tif_data; (void)s; @@ -757,12 +800,12 @@ OJPEGDecode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) } static int -OJPEGDecodeRaw(TIFF* tif, tidata_t buf, tsize_t cc) +OJPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc) { static const char module[]="OJPEGDecodeRaw"; OJPEGState* sp=(OJPEGState*)tif->tif_data; uint8* m; - uint32 n; + tmsize_t n; uint8* oy; uint8* ocb; uint8* ocr; @@ -812,12 +855,12 @@ OJPEGDecodeRaw(TIFF* tif, tidata_t buf, tsize_t cc) } static int -OJPEGDecodeScanlines(TIFF* tif, tidata_t buf, tsize_t cc) +OJPEGDecodeScanlines(TIFF* tif, uint8* buf, tmsize_t cc) { static const char module[]="OJPEGDecodeScanlines"; OJPEGState* sp=(OJPEGState*)tif->tif_data; uint8* m; - uint32 n; + tmsize_t n; if (cc%sp->bytes_per_line!=0) { TIFFErrorExt(tif->tif_clientdata,module,"Fractional scanline not read"); @@ -837,13 +880,13 @@ OJPEGDecodeScanlines(TIFF* tif, tidata_t buf, tsize_t cc) } static void -OJPEGPostDecode(TIFF* tif, tidata_t buf, tsize_t cc) +OJPEGPostDecode(TIFF* tif, uint8* buf, tmsize_t cc) { OJPEGState* sp=(OJPEGState*)tif->tif_data; (void)buf; (void)cc; sp->write_curstrile++; - if (sp->write_curstrile%tif->tif_dir.td_stripsperimage==0) + if (sp->write_curstrile%tif->tif_dir.td_stripsperimage==0) { assert(sp->libjpeg_session_active!=0); OJPEGLibjpegSessionAbort(tif); @@ -860,7 +903,7 @@ OJPEGSetupEncode(TIFF* tif) } static int -OJPEGPreEncode(TIFF* tif, tsample_t s) +OJPEGPreEncode(TIFF* tif, uint16 s) { static const char module[]="OJPEGPreEncode"; (void)s; @@ -869,7 +912,7 @@ OJPEGPreEncode(TIFF* tif, tsample_t s) } static int -OJPEGEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) +OJPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) { static const char module[]="OJPEGEncode"; (void)buf; @@ -895,6 +938,7 @@ OJPEGCleanup(TIFF* tif) { tif->tif_tagmethods.vgetfield=sp->vgetparent; tif->tif_tagmethods.vsetfield=sp->vsetparent; + tif->tif_tagmethods.printdir=sp->printdir; if (sp->qtable[0]!=0) _TIFFfree(sp->qtable[0]); if (sp->qtable[1]!=0) @@ -940,6 +984,8 @@ OJPEGSubsamplingCorrect(TIFF* tif) OJPEGState* sp=(OJPEGState*)tif->tif_data; uint8 mh; uint8 mv; + _TIFFFillStriles( tif ); + assert(sp->subsamplingcorrect_done==0); if ((tif->tif_dir.td_samplesperpixel!=3) || ((tif->tif_dir.td_photometric!=PHOTOMETRIC_YCBCR) && (tif->tif_dir.td_photometric!=PHOTOMETRIC_ITULAB))) @@ -1006,9 +1052,9 @@ OJPEGReadHeaderInfo(TIFF* tif) sp->strile_length=tif->tif_dir.td_rowsperstrip; sp->strile_length_total=sp->image_length; } - sp->samples_per_pixel=tif->tif_dir.td_samplesperpixel; - if (sp->samples_per_pixel==1) + if (tif->tif_dir.td_samplesperpixel==1) { + sp->samples_per_pixel=1; sp->plane_sample_offset=0; sp->samples_per_pixel_per_plane=sp->samples_per_pixel; sp->subsampling_hor=1; @@ -1016,11 +1062,12 @@ OJPEGReadHeaderInfo(TIFF* tif) } else { - if (sp->samples_per_pixel!=3) + if (tif->tif_dir.td_samplesperpixel!=3) { TIFFErrorExt(tif->tif_clientdata,module,"SamplesPerPixel %d not supported for this compression scheme",sp->samples_per_pixel); return(0); } + sp->samples_per_pixel=3; sp->plane_sample_offset=0; if (tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG) sp->samples_per_pixel_per_plane=3; @@ -1042,13 +1089,13 @@ OJPEGReadHeaderInfo(TIFF* tif) sp->sos_end[0].in_buffer_source=sp->in_buffer_source; sp->sos_end[0].in_buffer_next_strile=sp->in_buffer_next_strile; sp->sos_end[0].in_buffer_file_pos=sp->in_buffer_file_pos-sp->in_buffer_togo; - sp->sos_end[0].in_buffer_file_togo=sp->in_buffer_file_togo+sp->in_buffer_togo; + sp->sos_end[0].in_buffer_file_togo=sp->in_buffer_file_togo+sp->in_buffer_togo; sp->readheader_done=1; return(1); } static int -OJPEGReadSecondarySos(TIFF* tif, tsample_t s) +OJPEGReadSecondarySos(TIFF* tif, uint16 s) { OJPEGState* sp=(OJPEGState*)tif->tif_data; uint8 m; @@ -1061,7 +1108,7 @@ OJPEGReadSecondarySos(TIFF* tif, tsample_t s) sp->plane_sample_offset--; sp->in_buffer_source=sp->sos_end[sp->plane_sample_offset].in_buffer_source; sp->in_buffer_next_strile=sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile; - sp->in_buffer_file_pos=sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos; + sp->in_buffer_file_pos=sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos; sp->in_buffer_file_pos_log=0; sp->in_buffer_file_togo=sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo; sp->in_buffer_togo=0; @@ -1104,7 +1151,9 @@ OJPEGWriteHeaderInfo(TIFF* tif) OJPEGState* sp=(OJPEGState*)tif->tif_data; uint8** m; uint32 n; - assert(sp->libjpeg_session_active==0); + /* if a previous attempt failed, don't try again */ + if (sp->libjpeg_session_active != 0) + return 0; sp->out_state=ososSoi; sp->restart_index=0; jpeg_std_error(&(sp->libjpeg_jpeg_error_mgr)); @@ -1223,7 +1272,7 @@ OJPEGReadHeaderInfoSec(TIFF* tif) } sp->in_buffer_source=osibsNotSetYet; sp->in_buffer_next_strile=0; - sp->in_buffer_strile_count=tif->tif_dir.td_nstrips; + sp->in_buffer_strile_count=tif->tif_dir.td_nstrips; sp->in_buffer_file_togo=0; sp->in_buffer_togo=0; do @@ -1391,12 +1440,15 @@ OJPEGReadHeaderInfoSecStreamDqt(TIFF* tif) nb[sizeof(uint32)+1]=JPEG_MARKER_DQT; nb[sizeof(uint32)+2]=0; nb[sizeof(uint32)+3]=67; - if (OJPEGReadBlock(sp,65,&nb[sizeof(uint32)+4])==0) + if (OJPEGReadBlock(sp,65,&nb[sizeof(uint32)+4])==0) { + _TIFFfree(nb); return(0); + } o=nb[sizeof(uint32)+4]&15; if (3tif_clientdata,module,"Corrupt DQT marker in JPEG data"); + _TIFFfree(nb); return(0); } if (sp->qtable[o]!=0) @@ -1445,14 +1497,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 (3tif_clientdata,module,"Corrupt DHT marker in JPEG data"); + _TIFFfree(nb); return(0); } if (sp->dctable[o]!=0) @@ -1464,12 +1519,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 (3tif_clientdata,module,"Corrupt DHT marker in JPEG data"); + _TIFFfree(nb); return(0); } if (sp->actable[o]!=0) @@ -1537,11 +1594,10 @@ OJPEGReadHeaderInfoSecStreamSof(TIFF* tif, uint8 marker_id) OJPEGReadSkip(sp,4); else { - /* TODO: probably best to also add check on allowed upper bound, especially x, may cause buffer overflow otherwise i think */ /* Y: Number of lines */ if (OJPEGReadWord(sp,&p)==0) return(0); - if ((pimage_length) && (pstrile_length_total)) + if (((uint32)pimage_length) && ((uint32)pstrile_length_total)) { TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected height"); return(0); @@ -1550,11 +1606,16 @@ OJPEGReadHeaderInfoSecStreamSof(TIFF* tif, uint8 marker_id) /* X: Number of samples per line */ if (OJPEGReadWord(sp,&p)==0) return(0); - if ((pimage_width) && (pstrile_width)) + if (((uint32)pimage_width) && ((uint32)pstrile_width)) { TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected width"); return(0); } + if ((uint32)p>sp->strile_width) + { + TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data image width exceeds expected image width"); + return(0); + } sp->sof_x=p; } /* Nf: Number of image components in frame */ @@ -1717,7 +1778,7 @@ OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif) ob[sizeof(uint32)+2]=0; ob[sizeof(uint32)+3]=67; ob[sizeof(uint32)+4]=m; - TIFFSeekFile(tif,sp->qtable_offset[m],SEEK_SET); + TIFFSeekFile(tif,sp->qtable_offset[m],SEEK_SET); p=TIFFReadFile(tif,&ob[sizeof(uint32)+5],64); if (p!=64) return(0); @@ -1824,7 +1885,7 @@ OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif) return(0); } } - TIFFSeekFile(tif,sp->actable_offset[m],SEEK_SET); + TIFFSeekFile(tif,sp->actable_offset[m],SEEK_SET); p=TIFFReadFile(tif,o,16); if (p!=16) return(0); @@ -1862,7 +1923,7 @@ static int OJPEGReadBufferFill(OJPEGState* sp) { uint16 m; - tsize_t n; + tmsize_t n; /* TODO: double-check: when subsamplingcorrect is set, no call to TIFFErrorExt or TIFFWarningExt should be made * in any other case, seek or read errors should be passed through */ do @@ -1875,15 +1936,15 @@ OJPEGReadBufferFill(OJPEGState* sp) sp->in_buffer_file_pos_log=1; } m=OJPEG_BUFFER; - if (m>sp->in_buffer_file_togo) + if ((uint64)m>sp->in_buffer_file_togo) m=(uint16)sp->in_buffer_file_togo; - n=TIFFReadFile(sp->tif,sp->in_buffer,(tsize_t)m); + n=TIFFReadFile(sp->tif,sp->in_buffer,(tmsize_t)m); if (n==0) return(0); assert(n>0); assert(n<=OJPEG_BUFFER); assert(n<65536); - assert((uint16)n<=sp->in_buffer_file_togo); + assert((uint64)n<=sp->in_buffer_file_togo); m=(uint16)n; sp->in_buffer_togo=m; sp->in_buffer_cur=sp->in_buffer; @@ -1904,23 +1965,31 @@ OJPEGReadBufferFill(OJPEGState* sp) break; case osibsJpegInterchangeFormat: sp->in_buffer_source=osibsStrile; + break; case osibsStrile: - if (sp->in_buffer_next_strile==sp->in_buffer_strile_count) + if (!_TIFFFillStriles( sp->tif ) + || sp->tif->tif_dir.td_stripoffset == NULL + || sp->tif->tif_dir.td_stripbytecount == NULL) + return 0; + + if (sp->in_buffer_next_strile==sp->in_buffer_strile_count) sp->in_buffer_source=osibsEof; else { - if (sp->tif->tif_dir.td_stripoffset == 0) { - TIFFErrorExt(sp->tif->tif_clientdata,sp->tif->tif_name,"Strip offsets are missing"); - return(0); - } - sp->in_buffer_file_pos=sp->tif->tif_dir.td_stripoffset[sp->in_buffer_next_strile]; + sp->in_buffer_file_pos=sp->tif->tif_dir.td_stripoffset[sp->in_buffer_next_strile]; if (sp->in_buffer_file_pos!=0) { if (sp->in_buffer_file_pos>=sp->file_size) sp->in_buffer_file_pos=0; + else if (sp->tif->tif_dir.td_stripbytecount==NULL) + sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos; else { - sp->in_buffer_file_togo=sp->tif->tif_dir.td_stripbytecount[sp->in_buffer_next_strile]; + if (sp->tif->tif_dir.td_stripbytecount == 0) { + TIFFErrorExt(sp->tif->tif_clientdata,sp->tif->tif_name,"Strip byte counts are missing"); + return(0); + } + sp->in_buffer_file_togo=sp->tif->tif_dir.td_stripbytecount[sp->in_buffer_next_strile]; if (sp->in_buffer_file_togo==0) sp->in_buffer_file_pos=0; else if (sp->in_buffer_file_pos+sp->in_buffer_file_togo>sp->file_size) @@ -2031,8 +2100,8 @@ OJPEGReadSkip(OJPEGState* sp, uint16 len) { assert(sp->in_buffer_togo==0); n=m; - if (n>sp->in_buffer_file_togo) - n=sp->in_buffer_file_togo; + if ((uint64)n>sp->in_buffer_file_togo) + n=(uint16)sp->in_buffer_file_togo; sp->in_buffer_file_pos+=n; sp->in_buffer_file_togo-=n; sp->in_buffer_file_pos_log=0; @@ -2271,7 +2340,7 @@ OJPEGWriteStreamCompressed(TIFF* tif, void** mem, uint32* len) switch(sp->in_buffer_source) { case osibsStrile: - if (sp->in_buffer_next_strilein_buffer_strile_count) + if (sp->in_buffer_next_strilein_buffer_strile_count) sp->out_state=ososRst; else sp->out_state=ososEoi; @@ -2366,7 +2435,7 @@ OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct* cinfo) { char buffer[JMSG_LENGTH_MAX]; (*cinfo->err->format_message)(cinfo,buffer); - TIFFWarningExt(((TIFF*)(cinfo->client_data))->tif_clientdata,"LibJpeg", "%s", buffer); + TIFFWarningExt(((TIFF*)(cinfo->client_data))->tif_clientdata,"LibJpeg","%s",buffer); } static void @@ -2374,7 +2443,7 @@ OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct* cinfo) { char buffer[JMSG_LENGTH_MAX]; (*cinfo->err->format_message)(cinfo,buffer); - TIFFErrorExt(((TIFF*)(cinfo->client_data))->tif_clientdata,"LibJpeg", "%s", buffer); + TIFFErrorExt(((TIFF*)(cinfo->client_data))->tif_clientdata,"LibJpeg","%s",buffer); jpeg_encap_unwind((TIFF*)(cinfo->client_data)); } @@ -2390,7 +2459,7 @@ OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct* cinfo) TIFF* tif=(TIFF*)cinfo->client_data; OJPEGState* sp=(OJPEGState*)tif->tif_data; void* mem=0; - uint32 len=0; + uint32 len=0U; if (OJPEGWriteStream(tif,&mem,&len)==0) { TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Premature end of JPEG data"); diff --git a/thirdparty/libtiff/tif_open.c b/thirdparty/libtiff/tif_open.c index 3b3b2ce6..8c88328c 100644 --- a/thirdparty/libtiff/tif_open.c +++ b/thirdparty/libtiff/tif_open.c @@ -1,4 +1,4 @@ -/* $Id: tif_open.c,v 1.33.2.1 2010-06-08 18:50:42 bfriesen Exp $ */ +/* $Id: tif_open.c,v 1.46 2010-12-06 16:54:54 faxguy Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -29,90 +29,22 @@ */ #include "tiffiop.h" -static const long typemask[13] = { - (long)0L, /* TIFF_NOTYPE */ - (long)0x000000ffL, /* TIFF_BYTE */ - (long)0xffffffffL, /* TIFF_ASCII */ - (long)0x0000ffffL, /* TIFF_SHORT */ - (long)0xffffffffL, /* TIFF_LONG */ - (long)0xffffffffL, /* TIFF_RATIONAL */ - (long)0x000000ffL, /* TIFF_SBYTE */ - (long)0x000000ffL, /* TIFF_UNDEFINED */ - (long)0x0000ffffL, /* TIFF_SSHORT */ - (long)0xffffffffL, /* TIFF_SLONG */ - (long)0xffffffffL, /* TIFF_SRATIONAL */ - (long)0xffffffffL, /* TIFF_FLOAT */ - (long)0xffffffffL, /* TIFF_DOUBLE */ -}; -static const int bigTypeshift[13] = { - 0, /* TIFF_NOTYPE */ - 24, /* TIFF_BYTE */ - 0, /* TIFF_ASCII */ - 16, /* TIFF_SHORT */ - 0, /* TIFF_LONG */ - 0, /* TIFF_RATIONAL */ - 24, /* TIFF_SBYTE */ - 24, /* TIFF_UNDEFINED */ - 16, /* TIFF_SSHORT */ - 0, /* TIFF_SLONG */ - 0, /* TIFF_SRATIONAL */ - 0, /* TIFF_FLOAT */ - 0, /* TIFF_DOUBLE */ -}; -static const int litTypeshift[13] = { - 0, /* TIFF_NOTYPE */ - 0, /* TIFF_BYTE */ - 0, /* TIFF_ASCII */ - 0, /* TIFF_SHORT */ - 0, /* TIFF_LONG */ - 0, /* TIFF_RATIONAL */ - 0, /* TIFF_SBYTE */ - 0, /* TIFF_UNDEFINED */ - 0, /* TIFF_SSHORT */ - 0, /* TIFF_SLONG */ - 0, /* TIFF_SRATIONAL */ - 0, /* TIFF_FLOAT */ - 0, /* TIFF_DOUBLE */ -}; - /* * Dummy functions to fill the omitted client procedures. */ static int -_tiffDummyMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) +_tiffDummyMapProc(thandle_t fd, void** pbase, toff_t* psize) { (void) fd; (void) pbase; (void) psize; return (0); } static void -_tiffDummyUnmapProc(thandle_t fd, tdata_t base, toff_t size) +_tiffDummyUnmapProc(thandle_t fd, void* base, toff_t size) { (void) fd; (void) base; (void) size; } -/* - * Initialize the shift & mask tables, and the - * byte swapping state according to the file - * contents and the machine architecture. - */ -static void -TIFFInitOrder(TIFF* tif, int magic) -{ - tif->tif_typemask = typemask; - if (magic == TIFF_BIGENDIAN) { - tif->tif_typeshift = bigTypeshift; -#ifndef WORDS_BIGENDIAN - tif->tif_flags |= TIFF_SWAB; -#endif - } else { - tif->tif_typeshift = litTypeshift; -#ifdef WORDS_BIGENDIAN - tif->tif_flags |= TIFF_SWAB; -#endif - } -} - int _TIFFgetMode(const char* mode, const char* module) { @@ -155,10 +87,36 @@ TIFFClientOpen( int m; const char* cp; + /* The following are configuration checks. They should be redundant, but should not + * compile to any actual code in an optimised release build anyway. If any of them + * fail, (makefile-based or other) configuration is not correct */ + assert(sizeof(uint8)==1); + assert(sizeof(int8)==1); + assert(sizeof(uint16)==2); + assert(sizeof(int16)==2); + assert(sizeof(uint32)==4); + assert(sizeof(int32)==4); + assert(sizeof(uint64)==8); + assert(sizeof(int64)==8); + assert(sizeof(tmsize_t)==sizeof(void*)); + { + union{ + uint8 a8[2]; + uint16 a16; + } n; + n.a8[0]=1; + n.a8[1]=0; + #ifdef WORDS_BIGENDIAN + assert(n.a16==256); + #else + assert(n.a16==1); + #endif + } + m = _TIFFgetMode(mode, module); if (m == -1) goto bad2; - tif = (TIFF *)_TIFFmalloc(sizeof (TIFF) + strlen(name) + 1); + tif = (TIFF *)_TIFFmalloc((tmsize_t)(sizeof (TIFF) + strlen(name) + 1)); if (tif == NULL) { TIFFErrorExt(clientdata, module, "%s: Out of memory (TIFF structure)", name); goto bad2; @@ -167,14 +125,14 @@ TIFFClientOpen( tif->tif_name = (char *)tif + sizeof (TIFF); strcpy(tif->tif_name, name); tif->tif_mode = m &~ (O_CREAT|O_TRUNC); - tif->tif_curdir = (tdir_t) -1; /* non-existent directory */ + tif->tif_curdir = (uint16) -1; /* non-existent directory */ tif->tif_curoff = 0; - tif->tif_curstrip = (tstrip_t) -1; /* invalid strip */ + tif->tif_curstrip = (uint32) -1; /* invalid strip */ tif->tif_row = (uint32) -1; /* read/write pre-increment */ tif->tif_clientdata = clientdata; if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc) { TIFFErrorExt(clientdata, module, - "One of the client procedures is NULL pointer."); + "One of the client procedures is NULL pointer."); goto bad2; } tif->tif_readproc = readproc; @@ -182,7 +140,7 @@ TIFFClientOpen( tif->tif_seekproc = seekproc; tif->tif_closeproc = closeproc; tif->tif_sizeproc = sizeproc; - if (mapproc) + if (mapproc) tif->tif_mapproc = mapproc; else tif->tif_mapproc = _tiffDummyMapProc; @@ -190,7 +148,7 @@ TIFFClientOpen( tif->tif_unmapproc = unmapproc; else tif->tif_unmapproc = _tiffDummyUnmapProc; - _TIFFSetDefaultCompressionState(tif); /* setup default state */ + _TIFFSetDefaultCompressionState(tif); /* setup default state */ /* * Default is to return data MSB2LSB and enable the * use of memory-mapped files and strip chopping when @@ -200,10 +158,10 @@ TIFFClientOpen( if (m == O_RDONLY ) tif->tif_flags |= TIFF_MAPPED; -#ifdef STRIPCHOP_DEFAULT + #ifdef STRIPCHOP_DEFAULT if (m == O_RDONLY || m == O_RDWR) tif->tif_flags |= STRIPCHOP_DEFAULT; -#endif + #endif /* * Process library-specific flags in the open mode string. @@ -213,16 +171,18 @@ TIFFClientOpen( * TIFF but only supports some braindead idea of what the * vendor thinks TIFF is): * - * 'l' use little-endian byte order for creating a file - * 'b' use big-endian byte order for creating a file - * 'L' read/write information using LSB2MSB bit order - * 'B' read/write information using MSB2LSB bit order - * 'H' read/write information using host bit order - * 'M' enable use of memory-mapped files when supported - * 'm' disable use of memory-mapped files - * 'C' enable strip chopping support when reading - * 'c' disable strip chopping support - * 'h' read TIFF header only, do not load the first IFD + * 'l' use little-endian byte order for creating a file + * 'b' use big-endian byte order for creating a file + * 'L' read/write information using LSB2MSB bit order + * 'B' read/write information using MSB2LSB bit order + * 'H' read/write information using host bit order + * 'M' enable use of memory-mapped files when supported + * 'm' disable use of memory-mapped files + * 'C' enable strip chopping support when reading + * 'c' disable strip chopping support + * 'h' read TIFF header only, do not load the first IFD + * '4' ClassicTIFF for creating a file (default) + * '8' BigTIFF for creating a file * * The use of the 'l' and 'b' flags is strongly discouraged. * These flags are provided solely because numerous vendors, @@ -257,94 +217,120 @@ TIFFClientOpen( */ for (cp = mode; *cp; cp++) switch (*cp) { - case 'b': -#ifndef WORDS_BIGENDIAN - if (m&O_CREAT) - tif->tif_flags |= TIFF_SWAB; -#endif - break; - case 'l': -#ifdef WORDS_BIGENDIAN - if ((m&O_CREAT)) - tif->tif_flags |= TIFF_SWAB; -#endif - break; - case 'B': - tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | - FILLORDER_MSB2LSB; - break; - case 'L': - tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | - FILLORDER_LSB2MSB; - break; - case 'H': - tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | - HOST_FILLORDER; - break; - case 'M': - if (m == O_RDONLY) - tif->tif_flags |= TIFF_MAPPED; - break; - case 'm': - if (m == O_RDONLY) - tif->tif_flags &= ~TIFF_MAPPED; - break; - case 'C': - if (m == O_RDONLY) - tif->tif_flags |= TIFF_STRIPCHOP; - break; - case 'c': - if (m == O_RDONLY) - tif->tif_flags &= ~TIFF_STRIPCHOP; - break; - case 'h': - tif->tif_flags |= TIFF_HEADERONLY; - break; + case 'b': + #ifndef WORDS_BIGENDIAN + if (m&O_CREAT) + tif->tif_flags |= TIFF_SWAB; + #endif + break; + case 'l': + #ifdef WORDS_BIGENDIAN + if ((m&O_CREAT)) + tif->tif_flags |= TIFF_SWAB; + #endif + break; + case 'B': + tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | + FILLORDER_MSB2LSB; + break; + case 'L': + tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | + FILLORDER_LSB2MSB; + break; + case 'H': + tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | + HOST_FILLORDER; + break; + case 'M': + if (m == O_RDONLY) + tif->tif_flags |= TIFF_MAPPED; + break; + case 'm': + if (m == O_RDONLY) + tif->tif_flags &= ~TIFF_MAPPED; + break; + case 'C': + if (m == O_RDONLY) + tif->tif_flags |= TIFF_STRIPCHOP; + break; + case 'c': + if (m == O_RDONLY) + tif->tif_flags &= ~TIFF_STRIPCHOP; + break; + case 'h': + tif->tif_flags |= TIFF_HEADERONLY; + break; + case '8': + if (m&O_CREAT) + tif->tif_flags |= TIFF_BIGTIFF; + break; } /* * Read in TIFF header. */ - if (tif->tif_mode & O_TRUNC || - !ReadOK(tif, &tif->tif_header, sizeof (TIFFHeader))) { + if ((m & O_TRUNC) || + !ReadOK(tif, &tif->tif_header, sizeof (TIFFHeaderClassic))) { if (tif->tif_mode == O_RDONLY) { TIFFErrorExt(tif->tif_clientdata, name, - "Cannot read TIFF header"); + "Cannot read TIFF header"); goto bad; } /* * Setup header and write. */ -#ifdef WORDS_BIGENDIAN - tif->tif_header.tiff_magic = tif->tif_flags & TIFF_SWAB + #ifdef WORDS_BIGENDIAN + tif->tif_header.common.tiff_magic = tif->tif_flags & TIFF_SWAB ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN; -#else - tif->tif_header.tiff_magic = tif->tif_flags & TIFF_SWAB + #else + tif->tif_header.common.tiff_magic = tif->tif_flags & TIFF_SWAB ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN; -#endif - tif->tif_header.tiff_version = TIFF_VERSION; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&tif->tif_header.tiff_version); - tif->tif_header.tiff_diroff = 0; /* filled in later */ - - - /* - * The doc for "fopen" for some STD_C_LIBs says that if you - * open a file for modify ("+"), then you must fseek (or - * fflush?) between any freads and fwrites. This is not - * necessary on most systems, but has been shown to be needed - * on Solaris. - */ - TIFFSeekFile( tif, 0, SEEK_SET ); - - if (!WriteOK(tif, &tif->tif_header, sizeof (TIFFHeader))) { + #endif + if (!(tif->tif_flags&TIFF_BIGTIFF)) + { + tif->tif_header.common.tiff_version = TIFF_VERSION_CLASSIC; + tif->tif_header.classic.tiff_diroff = 0; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&tif->tif_header.common.tiff_version); + tif->tif_header_size = sizeof(TIFFHeaderClassic); + } + else + { + tif->tif_header.common.tiff_version = TIFF_VERSION_BIG; + tif->tif_header.big.tiff_offsetsize = 8; + tif->tif_header.big.tiff_unused = 0; + tif->tif_header.big.tiff_diroff = 0; + if (tif->tif_flags & TIFF_SWAB) + { + TIFFSwabShort(&tif->tif_header.common.tiff_version); + TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize); + } + tif->tif_header_size = sizeof (TIFFHeaderBig); + } + /* + * The doc for "fopen" for some STD_C_LIBs says that if you + * open a file for modify ("+"), then you must fseek (or + * fflush?) between any freads and fwrites. This is not + * necessary on most systems, but has been shown to be needed + * on Solaris. + */ + TIFFSeekFile( tif, 0, SEEK_SET ); + if (!WriteOK(tif, &tif->tif_header, (tmsize_t)(tif->tif_header_size))) { TIFFErrorExt(tif->tif_clientdata, name, - "Error writing TIFF header"); + "Error writing TIFF header"); goto bad; } /* * Setup the byte order handling. */ - TIFFInitOrder(tif, tif->tif_header.tiff_magic); + if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) { + #ifndef WORDS_BIGENDIAN + tif->tif_flags |= TIFF_SWAB; + #endif + } else { + #ifdef WORDS_BIGENDIAN + tif->tif_flags |= TIFF_SWAB; + #endif + } /* * Setup default directory. */ @@ -359,95 +345,139 @@ TIFFClientOpen( /* * Setup the byte order handling. */ - if (tif->tif_header.tiff_magic != TIFF_BIGENDIAN && - tif->tif_header.tiff_magic != TIFF_LITTLEENDIAN -#if MDI_SUPPORT + if (tif->tif_header.common.tiff_magic != TIFF_BIGENDIAN && + tif->tif_header.common.tiff_magic != TIFF_LITTLEENDIAN + #if MDI_SUPPORT && -#if HOST_BIGENDIAN - tif->tif_header.tiff_magic != MDI_BIGENDIAN -#else - tif->tif_header.tiff_magic != MDI_LITTLEENDIAN -#endif + #if HOST_BIGENDIAN + tif->tif_header.common.tiff_magic != MDI_BIGENDIAN + #else + tif->tif_header.common.tiff_magic != MDI_LITTLEENDIAN + #endif ) { TIFFErrorExt(tif->tif_clientdata, name, - "Not a TIFF or MDI file, bad magic number %d (0x%x)", -#else + "Not a TIFF or MDI file, bad magic number %d (0x%x)", + #else ) { TIFFErrorExt(tif->tif_clientdata, name, - "Not a TIFF file, bad magic number %d (0x%x)", -#endif - tif->tif_header.tiff_magic, - tif->tif_header.tiff_magic); + "Not a TIFF file, bad magic number %d (0x%x)", + #endif + tif->tif_header.common.tiff_magic, + tif->tif_header.common.tiff_magic); goto bad; } - TIFFInitOrder(tif, tif->tif_header.tiff_magic); - /* - * Swap header if required. - */ - if (tif->tif_flags & TIFF_SWAB) { - TIFFSwabShort(&tif->tif_header.tiff_version); - TIFFSwabLong(&tif->tif_header.tiff_diroff); + if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) { + #ifndef WORDS_BIGENDIAN + tif->tif_flags |= TIFF_SWAB; + #endif + } else { + #ifdef WORDS_BIGENDIAN + tif->tif_flags |= TIFF_SWAB; + #endif } - /* - * Now check version (if needed, it's been byte-swapped). - * Note that this isn't actually a version number, it's a - * magic number that doesn't change (stupid). - */ - if (tif->tif_header.tiff_version == TIFF_BIGTIFF_VERSION) { - TIFFErrorExt(tif->tif_clientdata, name, - "This is a BigTIFF file. This format not supported\n" - "by this version of libtiff." ); - goto bad; - } - if (tif->tif_header.tiff_version != TIFF_VERSION) { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&tif->tif_header.common.tiff_version); + if ((tif->tif_header.common.tiff_version != TIFF_VERSION_CLASSIC)&& + (tif->tif_header.common.tiff_version != TIFF_VERSION_BIG)) { TIFFErrorExt(tif->tif_clientdata, name, "Not a TIFF file, bad version number %d (0x%x)", - tif->tif_header.tiff_version, - tif->tif_header.tiff_version); + tif->tif_header.common.tiff_version, + tif->tif_header.common.tiff_version); goto bad; } + if (tif->tif_header.common.tiff_version == TIFF_VERSION_CLASSIC) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&tif->tif_header.classic.tiff_diroff); + tif->tif_header_size = sizeof(TIFFHeaderClassic); + } + else + { + if (!ReadOK(tif, ((uint8*)(&tif->tif_header) + sizeof(TIFFHeaderClassic)), (sizeof(TIFFHeaderBig)-sizeof(TIFFHeaderClassic)))) + { + TIFFErrorExt(tif->tif_clientdata, name, + "Cannot read TIFF header"); + goto bad; + } + if (tif->tif_flags & TIFF_SWAB) + { + TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize); + TIFFSwabLong8(&tif->tif_header.big.tiff_diroff); + } + if (tif->tif_header.big.tiff_offsetsize != 8) + { + TIFFErrorExt(tif->tif_clientdata, name, + "Not a TIFF file, bad BigTIFF offsetsize %d (0x%x)", + tif->tif_header.big.tiff_offsetsize, + tif->tif_header.big.tiff_offsetsize); + goto bad; + } + if (tif->tif_header.big.tiff_unused != 0) + { + TIFFErrorExt(tif->tif_clientdata, name, + "Not a TIFF file, bad BigTIFF unused %d (0x%x)", + tif->tif_header.big.tiff_unused, + tif->tif_header.big.tiff_unused); + goto bad; + } + tif->tif_header_size = sizeof(TIFFHeaderBig); + tif->tif_flags |= TIFF_BIGTIFF; + } tif->tif_flags |= TIFF_MYBUFFER; tif->tif_rawcp = tif->tif_rawdata = 0; tif->tif_rawdatasize = 0; + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = 0; - /* - * Sometimes we do not want to read the first directory (for example, - * it may be broken) and want to proceed to other directories. I this - * case we use the TIFF_HEADERONLY flag to open file and return - * immediately after reading TIFF header. - */ - if (tif->tif_flags & TIFF_HEADERONLY) - return (tif); - - /* - * Setup initial directory. - */ switch (mode[0]) { - case 'r': - tif->tif_nextdiroff = tif->tif_header.tiff_diroff; - /* - * Try to use a memory-mapped file if the client - * has not explicitly suppressed usage with the - * 'm' flag in the open mode (see above). - */ - if ((tif->tif_flags & TIFF_MAPPED) && - !TIFFMapFileContents(tif, (tdata_t*) &tif->tif_base, &tif->tif_size)) - tif->tif_flags &= ~TIFF_MAPPED; - if (TIFFReadDirectory(tif)) { - tif->tif_rawcc = -1; - tif->tif_flags |= TIFF_BUFFERSETUP; + case 'r': + if (!(tif->tif_flags&TIFF_BIGTIFF)) + tif->tif_nextdiroff = tif->tif_header.classic.tiff_diroff; + else + tif->tif_nextdiroff = tif->tif_header.big.tiff_diroff; + /* + * Try to use a memory-mapped file if the client + * has not explicitly suppressed usage with the + * 'm' flag in the open mode (see above). + */ + if (tif->tif_flags & TIFF_MAPPED) + { + toff_t n; + if (TIFFMapFileContents(tif,(void**)(&tif->tif_base),&n)) + { + tif->tif_size=(tmsize_t)n; + assert((toff_t)tif->tif_size==n); + } + else + tif->tif_flags &= ~TIFF_MAPPED; + } + /* + * Sometimes we do not want to read the first directory (for example, + * it may be broken) and want to proceed to other directories. I this + * case we use the TIFF_HEADERONLY flag to open file and return + * immediately after reading TIFF header. + */ + if (tif->tif_flags & TIFF_HEADERONLY) + return (tif); + + /* + * Setup initial directory. + */ + if (TIFFReadDirectory(tif)) { + tif->tif_rawcc = (tmsize_t)-1; + tif->tif_flags |= TIFF_BUFFERSETUP; + return (tif); + } + break; + case 'a': + /* + * New directories are automatically append + * to the end of the directory chain when they + * are written out (see TIFFWriteDirectory). + */ + if (!TIFFDefaultDirectory(tif)) + goto bad; return (tif); - } - break; - case 'a': - /* - * New directories are automatically append - * to the end of the directory chain when they - * are written out (see TIFFWriteDirectory). - */ - if (!TIFFDefaultDirectory(tif)) - goto bad; - return (tif); } bad: tif->tif_mode = O_RDONLY; /* XXX avoid flush */ @@ -562,7 +592,7 @@ TIFFCurrentRow(TIFF* tif) /* * Return index of the current directory. */ -tdir_t +uint16 TIFFCurrentDirectory(TIFF* tif) { return (tif->tif_curdir); @@ -571,7 +601,7 @@ TIFFCurrentDirectory(TIFF* tif) /* * Return current strip. */ -tstrip_t +uint32 TIFFCurrentStrip(TIFF* tif) { return (tif->tif_curstrip); @@ -580,7 +610,7 @@ TIFFCurrentStrip(TIFF* tif) /* * Return current tile. */ -ttile_t +uint32 TIFFCurrentTile(TIFF* tif) { return (tif->tif_curtile); @@ -619,7 +649,7 @@ TIFFIsMSB2LSB(TIFF* tif) int TIFFIsBigEndian(TIFF* tif) { - return (tif->tif_header.tiff_magic == TIFF_BIGENDIAN); + return (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN); } /* diff --git a/thirdparty/libtiff/tif_packbits.c b/thirdparty/libtiff/tif_packbits.c index ee095f56..9e771901 100644 --- a/thirdparty/libtiff/tif_packbits.c +++ b/thirdparty/libtiff/tif_packbits.c @@ -1,4 +1,4 @@ -/* $Id: tif_packbits.c,v 1.13.2.2 2010-06-08 18:50:42 bfriesen Exp $ */ +/* $Id: tif_packbits.c,v 1.22 2012-06-20 05:25:33 fwarmerdam Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -34,19 +34,19 @@ #include static int -PackBitsPreEncode(TIFF* tif, tsample_t s) +PackBitsPreEncode(TIFF* tif, uint16 s) { (void) s; - if (!(tif->tif_data = (tidata_t)_TIFFmalloc(sizeof(tsize_t)))) + if (!(tif->tif_data = (uint8*)_TIFFmalloc(sizeof(tmsize_t)))) return (0); /* * Calculate the scanline/tile-width size in bytes. */ if (isTiled(tif)) - *(tsize_t*)tif->tif_data = TIFFTileRowSize(tif); + *(tmsize_t*)tif->tif_data = TIFFTileRowSize(tif); else - *(tsize_t*)tif->tif_data = TIFFScanlineSize(tif); + *(tmsize_t*)tif->tif_data = TIFFScanlineSize(tif); return (1); } @@ -58,21 +58,16 @@ PackBitsPostEncode(TIFF* tif) return (1); } -/* - * NB: tidata is the type representing *(tidata_t); - * if tidata_t is made signed then this type must - * be adjusted accordingly. - */ -typedef unsigned char tidata; - /* * Encode a run of pixels. */ static int -PackBitsEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) +PackBitsEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) { unsigned char* bp = (unsigned char*) buf; - tidata_t op, ep, lastliteral; + uint8* op; + uint8* ep; + uint8* lastliteral; long n, slop; int b; enum { BASE, LITERAL, RUN, LITERAL_RUN } state; @@ -98,8 +93,8 @@ PackBitsEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) * front of the buffer. */ if (state == LITERAL || state == LITERAL_RUN) { - slop = op - lastliteral; - tif->tif_rawcc += lastliteral - tif->tif_rawcp; + slop = (long)(op - lastliteral); + tif->tif_rawcc += (tmsize_t)(lastliteral - tif->tif_rawcp); if (!TIFFFlushData1(tif)) return (-1); op = tif->tif_rawcp; @@ -107,7 +102,7 @@ PackBitsEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) *op++ = *lastliteral++; lastliteral = tif->tif_rawcp; } else { - tif->tif_rawcc += op - tif->tif_rawcp; + tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp); if (!TIFFFlushData1(tif)) return (-1); op = tif->tif_rawcp; @@ -118,17 +113,17 @@ PackBitsEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) if (n > 1) { state = RUN; if (n > 128) { - *op++ = (tidata) -127; - *op++ = (tidataval_t) b; + *op++ = (uint8) -127; + *op++ = (uint8) b; n -= 128; goto again; } - *op++ = (tidataval_t)(-(n-1)); - *op++ = (tidataval_t) b; + *op++ = (uint8)(-(n-1)); + *op++ = (uint8) b; } else { lastliteral = op; *op++ = 0; - *op++ = (tidataval_t) b; + *op++ = (uint8) b; state = LITERAL; } break; @@ -136,33 +131,33 @@ PackBitsEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) if (n > 1) { state = LITERAL_RUN; if (n > 128) { - *op++ = (tidata) -127; - *op++ = (tidataval_t) b; + *op++ = (uint8) -127; + *op++ = (uint8) b; n -= 128; goto again; } - *op++ = (tidataval_t)(-(n-1)); /* encode run */ - *op++ = (tidataval_t) b; + *op++ = (uint8)(-(n-1)); /* encode run */ + *op++ = (uint8) b; } else { /* extend literal */ if (++(*lastliteral) == 127) state = BASE; - *op++ = (tidataval_t) b; + *op++ = (uint8) b; } break; case RUN: /* last object was run */ if (n > 1) { if (n > 128) { - *op++ = (tidata) -127; - *op++ = (tidataval_t) b; + *op++ = (uint8) -127; + *op++ = (uint8) b; n -= 128; goto again; } - *op++ = (tidataval_t)(-(n-1)); - *op++ = (tidataval_t) b; + *op++ = (uint8)(-(n-1)); + *op++ = (uint8) b; } else { lastliteral = op; *op++ = 0; - *op++ = (tidataval_t) b; + *op++ = (uint8) b; state = LITERAL; } break; @@ -173,7 +168,7 @@ PackBitsEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) * case we convert literal-run-literal * to a single literal. */ - if (n == 1 && op[-2] == (tidata) -1 && + if (n == 1 && op[-2] == (uint8) -1 && *lastliteral < 126) { state = (((*lastliteral) += 2) == 127 ? BASE : LITERAL); @@ -183,7 +178,7 @@ PackBitsEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) goto again; } } - tif->tif_rawcc += op - tif->tif_rawcp; + tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp); tif->tif_rawcp = op; return (1); } @@ -196,12 +191,12 @@ PackBitsEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) * when it was encoded by strips. */ static int -PackBitsEncodeChunk(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +PackBitsEncodeChunk(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) { - tsize_t rowsize = *(tsize_t*)tif->tif_data; + tmsize_t rowsize = *(tmsize_t*)tif->tif_data; - while ((long)cc > 0) { - int chunk = rowsize; + while (cc > 0) { + tmsize_t chunk = rowsize; if( cc < chunk ) chunk = cc; @@ -215,17 +210,18 @@ PackBitsEncodeChunk(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) } static int -PackBitsDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) +PackBitsDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) { + static const char module[] = "PackBitsDecode"; char *bp; - tsize_t cc; + tmsize_t cc; long n; int b; (void) s; bp = (char*) tif->tif_rawcp; cc = tif->tif_rawcc; - while (cc > 0 && (long)occ > 0) { + while (cc > 0 && occ > 0) { n = (long) *bp++, cc--; /* * Watch out for compilers that @@ -236,39 +232,43 @@ PackBitsDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) if (n < 0) { /* replicate next byte -n+1 times */ if (n == -128) /* nop */ continue; - n = -n + 1; - if( occ < n ) - { - TIFFWarningExt(tif->tif_clientdata, tif->tif_name, - "PackBitsDecode: discarding %ld bytes " - "to avoid buffer overrun", - n - occ); - n = occ; - } + n = -n + 1; + if( occ < (tmsize_t)n ) + { + TIFFWarningExt(tif->tif_clientdata, module, + "Discarding %lu bytes to avoid buffer overrun", + (unsigned long) ((tmsize_t)n - occ)); + n = (long)occ; + } occ -= n; b = *bp++, cc--; while (n-- > 0) - *op++ = (tidataval_t) b; + *op++ = (uint8) b; } else { /* copy next n+1 bytes literally */ - if (occ < n + 1) - { - TIFFWarningExt(tif->tif_clientdata, tif->tif_name, - "PackBitsDecode: discarding %ld bytes " - "to avoid buffer overrun", - n - occ + 1); - n = occ - 1; - } - _TIFFmemcpy(op, bp, ++n); + if (occ < (tmsize_t)(n + 1)) + { + TIFFWarningExt(tif->tif_clientdata, module, + "Discarding %lu bytes to avoid buffer overrun", + (unsigned long) ((tmsize_t)n - occ + 1)); + n = (long)occ - 1; + } + 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; } } - tif->tif_rawcp = (tidata_t) bp; + tif->tif_rawcp = (uint8*) bp; tif->tif_rawcc = cc; if (occ > 0) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "PackBitsDecode: Not enough data for scanline %ld", - (long) tif->tif_row); + TIFFErrorExt(tif->tif_clientdata, module, + "Not enough data for scanline %lu", + (unsigned long) tif->tif_row); return (0); } return (1); @@ -282,7 +282,7 @@ TIFFInitPackBits(TIFF* tif, int scheme) tif->tif_decodestrip = PackBitsDecode; tif->tif_decodetile = PackBitsDecode; tif->tif_preencode = PackBitsPreEncode; - tif->tif_postencode = PackBitsPostEncode; + tif->tif_postencode = PackBitsPostEncode; tif->tif_encoderow = PackBitsEncode; tif->tif_encodestrip = PackBitsEncodeChunk; tif->tif_encodetile = PackBitsEncodeChunk; diff --git a/thirdparty/libtiff/tif_pixarlog.c b/thirdparty/libtiff/tif_pixarlog.c index ed8eb402..044c4115 100644 --- a/thirdparty/libtiff/tif_pixarlog.c +++ b/thirdparty/libtiff/tif_pixarlog.c @@ -1,4 +1,4 @@ -/* $Id: tif_pixarlog.c,v 1.15.2.4 2010-06-08 18:50:42 bfriesen Exp $ */ +/* $Id: tif_pixarlog.c,v 1.39 2012-12-10 17:27:13 tgl Exp $ */ /* * Copyright (c) 1996-1997 Sam Leffler @@ -83,7 +83,10 @@ * The codec also handle byte swapping the encoded values as necessary * since the library does not have the information necessary * to know the bit depth of the raw unencoded buffer. - * + * + * NOTE: This decoder does not appear to update tif_rawcp, and tif_rawcc. + * This can cause problems with the implementation of CHUNKY_STRIP_READ_SUPPORT + * as noted in http://trac.osgeo.org/gdal/ticket/3894. FrankW - Jan'11 */ #include "tif_predict.h" @@ -108,7 +111,7 @@ static float LogK1, LogK2; #define REPEAT(n, op) { int i; i=n; do { i--; op; } while (i>0); } static void -horizontalAccumulateF(uint16 *wp, int n, int stride, float *op, +horizontalAccumulateF(uint16 *wp, int n, int stride, float *op, float *ToLinearF) { register unsigned int cr, cg, cb, ca, mask; @@ -117,9 +120,9 @@ horizontalAccumulateF(uint16 *wp, int n, int stride, float *op, if (n >= stride) { mask = CODE_MASK; if (stride == 3) { - t0 = ToLinearF[cr = wp[0]]; - t1 = ToLinearF[cg = wp[1]]; - t2 = ToLinearF[cb = wp[2]]; + t0 = ToLinearF[cr = (wp[0] & mask)]; + t1 = ToLinearF[cg = (wp[1] & mask)]; + t2 = ToLinearF[cb = (wp[2] & mask)]; op[0] = t0; op[1] = t1; op[2] = t2; @@ -136,10 +139,10 @@ horizontalAccumulateF(uint16 *wp, int n, int stride, float *op, op[2] = t2; } } else if (stride == 4) { - t0 = ToLinearF[cr = wp[0]]; - t1 = ToLinearF[cg = wp[1]]; - t2 = ToLinearF[cb = wp[2]]; - t3 = ToLinearF[ca = wp[3]]; + t0 = ToLinearF[cr = (wp[0] & mask)]; + t1 = ToLinearF[cg = (wp[1] & mask)]; + t2 = ToLinearF[cb = (wp[2] & mask)]; + t3 = ToLinearF[ca = (wp[3] & mask)]; op[0] = t0; op[1] = t1; op[2] = t2; @@ -183,9 +186,9 @@ horizontalAccumulate12(uint16 *wp, int n, int stride, int16 *op, if (n >= stride) { mask = CODE_MASK; if (stride == 3) { - t0 = ToLinearF[cr = wp[0]] * SCALE12; - t1 = ToLinearF[cg = wp[1]] * SCALE12; - t2 = ToLinearF[cb = wp[2]] * SCALE12; + t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12; + t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12; + t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12; op[0] = CLAMP12(t0); op[1] = CLAMP12(t1); op[2] = CLAMP12(t2); @@ -202,10 +205,10 @@ horizontalAccumulate12(uint16 *wp, int n, int stride, int16 *op, op[2] = CLAMP12(t2); } } else if (stride == 4) { - t0 = ToLinearF[cr = wp[0]] * SCALE12; - t1 = ToLinearF[cg = wp[1]] * SCALE12; - t2 = ToLinearF[cb = wp[2]] * SCALE12; - t3 = ToLinearF[ca = wp[3]] * SCALE12; + t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12; + t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12; + t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12; + t3 = ToLinearF[ca = (wp[3] & mask)] * SCALE12; op[0] = CLAMP12(t0); op[1] = CLAMP12(t1); op[2] = CLAMP12(t2); @@ -247,9 +250,9 @@ horizontalAccumulate16(uint16 *wp, int n, int stride, uint16 *op, if (n >= stride) { mask = CODE_MASK; if (stride == 3) { - op[0] = ToLinear16[cr = wp[0]]; - op[1] = ToLinear16[cg = wp[1]]; - op[2] = ToLinear16[cb = wp[2]]; + op[0] = ToLinear16[cr = (wp[0] & mask)]; + op[1] = ToLinear16[cg = (wp[1] & mask)]; + op[2] = ToLinear16[cb = (wp[2] & mask)]; n -= 3; while (n > 0) { wp += 3; @@ -260,10 +263,10 @@ horizontalAccumulate16(uint16 *wp, int n, int stride, uint16 *op, op[2] = ToLinear16[(cb += wp[2]) & mask]; } } else if (stride == 4) { - op[0] = ToLinear16[cr = wp[0]]; - op[1] = ToLinear16[cg = wp[1]]; - op[2] = ToLinear16[cb = wp[2]]; - op[3] = ToLinear16[ca = wp[3]]; + op[0] = ToLinear16[cr = (wp[0] & mask)]; + op[1] = ToLinear16[cg = (wp[1] & mask)]; + op[2] = ToLinear16[cb = (wp[2] & mask)]; + op[3] = ToLinear16[ca = (wp[3] & mask)]; n -= 4; while (n > 0) { wp += 4; @@ -342,9 +345,9 @@ horizontalAccumulate8(uint16 *wp, int n, int stride, unsigned char *op, if (n >= stride) { mask = CODE_MASK; if (stride == 3) { - op[0] = ToLinear8[cr = wp[0]]; - op[1] = ToLinear8[cg = wp[1]]; - op[2] = ToLinear8[cb = wp[2]]; + op[0] = ToLinear8[cr = (wp[0] & mask)]; + op[1] = ToLinear8[cg = (wp[1] & mask)]; + op[2] = ToLinear8[cb = (wp[2] & mask)]; n -= 3; while (n > 0) { n -= 3; @@ -355,10 +358,10 @@ horizontalAccumulate8(uint16 *wp, int n, int stride, unsigned char *op, op[2] = ToLinear8[(cb += wp[2]) & mask]; } } else if (stride == 4) { - op[0] = ToLinear8[cr = wp[0]]; - op[1] = ToLinear8[cg = wp[1]]; - op[2] = ToLinear8[cb = wp[2]]; - op[3] = ToLinear8[ca = wp[3]]; + op[0] = ToLinear8[cr = (wp[0] & mask)]; + op[1] = ToLinear8[cg = (wp[1] & mask)]; + op[2] = ToLinear8[cb = (wp[2] & mask)]; + op[3] = ToLinear8[ca = (wp[3] & mask)]; n -= 4; while (n > 0) { n -= 4; @@ -393,9 +396,9 @@ horizontalAccumulate8abgr(uint16 *wp, int n, int stride, unsigned char *op, mask = CODE_MASK; if (stride == 3) { op[0] = 0; - t1 = ToLinear8[cb = wp[2]]; - t2 = ToLinear8[cg = wp[1]]; - t3 = ToLinear8[cr = wp[0]]; + t1 = ToLinear8[cb = (wp[2] & mask)]; + t2 = ToLinear8[cg = (wp[1] & mask)]; + t3 = ToLinear8[cr = (wp[0] & mask)]; op[1] = t1; op[2] = t2; op[3] = t3; @@ -413,10 +416,10 @@ horizontalAccumulate8abgr(uint16 *wp, int n, int stride, unsigned char *op, op[3] = t3; } } else if (stride == 4) { - t0 = ToLinear8[ca = wp[3]]; - t1 = ToLinear8[cb = wp[2]]; - t2 = ToLinear8[cg = wp[1]]; - t3 = ToLinear8[cr = wp[0]]; + t0 = ToLinear8[ca = (wp[3] & mask)]; + t1 = ToLinear8[cb = (wp[2] & mask)]; + t2 = ToLinear8[cg = (wp[1] & mask)]; + t3 = ToLinear8[cr = (wp[0] & mask)]; op[0] = t0; op[1] = t1; op[2] = t2; @@ -587,11 +590,11 @@ PixarLogMakeTables(PixarLogState *sp) return 1; } -#define DecoderState(tif) ((PixarLogState*) (tif)->tif_data) -#define EncoderState(tif) ((PixarLogState*) (tif)->tif_data) +#define DecoderState(tif) ((PixarLogState*) (tif)->tif_data) +#define EncoderState(tif) ((PixarLogState*) (tif)->tif_data) -static int PixarLogEncode(TIFF*, tidata_t, tsize_t, tsample_t); -static int PixarLogDecode(TIFF*, tidata_t, tsize_t, tsample_t); +static int PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s); +static int PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s); #define PIXARLOGDATAFMT_UNKNOWN -1 @@ -630,10 +633,10 @@ PixarLogGuessDataFmt(TIFFDirectory *td) return guess; } -static uint32 -multiply(size_t m1, size_t m2) +static tmsize_t +multiply_ms(tmsize_t m1, tmsize_t m2) { - uint32 bytes = m1 * m2; + tmsize_t bytes = m1 * m2; if (m1 && bytes / m1 != m2) bytes = 0; @@ -641,28 +644,51 @@ multiply(size_t m1, size_t m2) return bytes; } +static tmsize_t +add_ms(tmsize_t m1, tmsize_t m2) +{ + tmsize_t bytes = m1 + m2; + + /* if either input is zero, assume overflow already occurred */ + if (m1 == 0 || m2 == 0) + bytes = 0; + else if (bytes <= m1 || bytes <= m2) + bytes = 0; + + return bytes; +} + +static int +PixarLogFixupTags(TIFF* tif) +{ + (void) tif; + return (1); +} + static int PixarLogSetupDecode(TIFF* tif) { + static const char module[] = "PixarLogSetupDecode"; TIFFDirectory *td = &tif->tif_dir; PixarLogState* sp = DecoderState(tif); - tsize_t tbuf_size; - static const char module[] = "PixarLogSetupDecode"; + tmsize_t tbuf_size; assert(sp != NULL); /* Make sure no byte swapping happens on the data * after decompression. */ - tif->tif_postdecode = _TIFFNoPostDecode; + tif->tif_postdecode = _TIFFNoPostDecode; /* for some reason, we can't do this in TIFFInitPixarLog */ sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel : 1); - tbuf_size = multiply(multiply(multiply(sp->stride, td->td_imagewidth), + tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth), td->td_rowsperstrip), 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); + return (0); /* TODO: this is an error return without error report through TIFFErrorExt */ sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size); if (sp->tbuf == NULL) return (0); @@ -676,7 +702,7 @@ PixarLogSetupDecode(TIFF* tif) } if (inflateInit(&sp->stream) != Z_OK) { - TIFFErrorExt(tif->tif_clientdata, module, "%s: %s", tif->tif_name, sp->stream.msg); + TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg); return (0); } else { sp->state |= PLSTATE_INIT; @@ -688,24 +714,36 @@ PixarLogSetupDecode(TIFF* tif) * Setup state for decoding a strip. */ static int -PixarLogPreDecode(TIFF* tif, tsample_t s) +PixarLogPreDecode(TIFF* tif, uint16 s) { + static const char module[] = "PixarLogPreDecode"; PixarLogState* sp = DecoderState(tif); (void) s; assert(sp != NULL); sp->stream.next_in = tif->tif_rawdata; - sp->stream.avail_in = tif->tif_rawcc; + 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 */ + sp->stream.avail_in = (uInt) tif->tif_rawcc; + if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc) + { + TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size"); + return (0); + } return (inflateReset(&sp->stream) == Z_OK); } static int -PixarLogDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) +PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) { + static const char module[] = "PixarLogDecode"; TIFFDirectory *td = &tif->tif_dir; PixarLogState* sp = DecoderState(tif); - static const char module[] = "PixarLogDecode"; - int i, nsamples, llen; + tmsize_t i; + tmsize_t nsamples; + int llen; uint16 *up; switch (sp->user_datafmt) { @@ -722,7 +760,7 @@ PixarLogDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) nsamples = occ; break; default: - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + TIFFErrorExt(tif->tif_clientdata, module, "%d bit input not supported in PixarLog", td->td_bitspersample); return 0; @@ -733,7 +771,16 @@ PixarLogDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) (void) s; assert(sp != NULL); sp->stream.next_out = (unsigned char *) sp->tbuf; - sp->stream.avail_out = nsamples * sizeof(uint16); + 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 = (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); + } do { int state = inflate(&sp->stream, Z_PARTIAL_FLUSH); if (state == Z_STREAM_END) { @@ -741,15 +788,15 @@ PixarLogDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) } if (state == Z_DATA_ERROR) { TIFFErrorExt(tif->tif_clientdata, module, - "%s: Decoding error at scanline %d, %s", - tif->tif_name, tif->tif_row, sp->stream.msg); + "Decoding error at scanline %lu, %s", + (unsigned long) tif->tif_row, sp->stream.msg); if (inflateSync(&sp->stream) != Z_OK) return (0); continue; } if (state != Z_OK) { - TIFFErrorExt(tif->tif_clientdata, module, "%s: zlib error: %s", - tif->tif_name, sp->stream.msg); + TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", + sp->stream.msg); return (0); } } while (sp->stream.avail_out > 0); @@ -757,8 +804,8 @@ PixarLogDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) /* hopefully, we got all the bytes we needed */ if (sp->stream.avail_out != 0) { TIFFErrorExt(tif->tif_clientdata, module, - "%s: Not enough data at scanline %d (short %d bytes)", - tif->tif_name, tif->tif_row, sp->stream.avail_out); + "Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT " bytes)", + (unsigned long) tif->tif_row, (TIFF_UINT64_T) sp->stream.avail_out); return (0); } @@ -767,15 +814,15 @@ PixarLogDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) if (tif->tif_flags & TIFF_SWAB) TIFFSwabArrayOfShort(up, nsamples); - /* + /* * if llen is not an exact multiple of nsamples, the decode operation * may overflow the output buffer, so truncate it enough to prevent * that but still salvage as much data as possible. */ if (nsamples % llen) { TIFFWarningExt(tif->tif_clientdata, module, - "%s: stride %d is not a multiple of sample count, " - "%d, data truncated.", tif->tif_name, llen, nsamples); + "stride %lu is not a multiple of sample count, " + "%lu, data truncated.", (unsigned long) llen, (unsigned long) nsamples); nsamples -= nsamples % llen; } @@ -812,8 +859,8 @@ PixarLogDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) op += llen * sizeof(unsigned char); break; default: - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "PixarLogDecode: unsupported bits/sample: %d", + TIFFErrorExt(tif->tif_clientdata, module, + "Unsupported bits/sample: %d", td->td_bitspersample); return (0); } @@ -825,10 +872,10 @@ PixarLogDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) static int PixarLogSetupEncode(TIFF* tif) { + static const char module[] = "PixarLogSetupEncode"; TIFFDirectory *td = &tif->tif_dir; PixarLogState* sp = EncoderState(tif); - tsize_t tbuf_size; - static const char module[] = "PixarLogSetupEncode"; + tmsize_t tbuf_size; assert(sp != NULL); @@ -836,10 +883,10 @@ PixarLogSetupEncode(TIFF* tif) sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel : 1); - tbuf_size = multiply(multiply(multiply(sp->stride, td->td_imagewidth), + tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth), td->td_rowsperstrip), sizeof(uint16)); if (tbuf_size == 0) - return (0); + return (0); /* TODO: this is an error return without error report through TIFFErrorExt */ sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size); if (sp->tbuf == NULL) return (0); @@ -851,7 +898,7 @@ PixarLogSetupEncode(TIFF* tif) } if (deflateInit(&sp->stream, sp->quality) != Z_OK) { - TIFFErrorExt(tif->tif_clientdata, module, "%s: %s", tif->tif_name, sp->stream.msg); + TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg); return (0); } else { sp->state |= PLSTATE_INIT; @@ -863,21 +910,30 @@ PixarLogSetupEncode(TIFF* tif) * Reset encoding state at the start of a strip. */ static int -PixarLogPreEncode(TIFF* tif, tsample_t s) +PixarLogPreEncode(TIFF* tif, uint16 s) { + static const char module[] = "PixarLogPreEncode"; PixarLogState *sp = EncoderState(tif); (void) s; assert(sp != NULL); sp->stream.next_out = tif->tif_rawdata; + 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; + if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) + { + TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size"); + return (0); + } return (deflateReset(&sp->stream) == Z_OK); } static void horizontalDifferenceF(float *ip, int n, int stride, uint16 *wp, uint16 *FromLT2) { - int32 r1, g1, b1, a1, r2, g2, b2, a2, mask; float fltsize = Fltsize; @@ -1042,12 +1098,14 @@ horizontalDifference8(unsigned char *ip, int n, int stride, * Encode a chunk of pixels. */ static int -PixarLogEncode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) { + static const char module[] = "PixarLogEncode"; TIFFDirectory *td = &tif->tif_dir; PixarLogState *sp = EncoderState(tif); - static const char module[] = "PixarLogEncode"; - int i, n, llen; + tmsize_t i; + tmsize_t n; + int llen; unsigned short * up; (void) s; @@ -1066,7 +1124,7 @@ PixarLogEncode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) n = cc; break; default: - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + TIFFErrorExt(tif->tif_clientdata, module, "%d bit input not supported in PixarLog", td->td_bitspersample); return 0; @@ -1092,7 +1150,7 @@ PixarLogEncode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) bp += llen * sizeof(unsigned char); break; default: - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + TIFFErrorExt(tif->tif_clientdata, module, "%d bit input not supported in PixarLog", td->td_bitspersample); return 0; @@ -1100,19 +1158,29 @@ PixarLogEncode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) } sp->stream.next_in = (unsigned char *) sp->tbuf; - sp->stream.avail_in = n * sizeof(uint16); + 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 */ + sp->stream.avail_in = (uInt) (n * sizeof(uint16)); + if ((sp->stream.avail_in / sizeof(uint16)) != (uInt) n) + { + TIFFErrorExt(tif->tif_clientdata, module, + "ZLib cannot deal with buffers this size"); + return (0); + } do { if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) { - TIFFErrorExt(tif->tif_clientdata, module, "%s: Encoder error: %s", - tif->tif_name, sp->stream.msg); + TIFFErrorExt(tif->tif_clientdata, module, "Encoder error: %s", + sp->stream.msg); return (0); } if (sp->stream.avail_out == 0) { tif->tif_rawcc = tif->tif_rawdatasize; TIFFFlushData1(tif); sp->stream.next_out = tif->tif_rawdata; - sp->stream.avail_out = tif->tif_rawdatasize; + sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in PixarLogPreEncode */ } } while (sp->stream.avail_in > 0); return (1); @@ -1126,8 +1194,8 @@ PixarLogEncode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) static int PixarLogPostEncode(TIFF* tif) { - PixarLogState *sp = EncoderState(tif); static const char module[] = "PixarLogPostEncode"; + PixarLogState *sp = EncoderState(tif); int state; sp->stream.avail_in = 0; @@ -1137,17 +1205,17 @@ PixarLogPostEncode(TIFF* tif) switch (state) { case Z_STREAM_END: case Z_OK: - if (sp->stream.avail_out != (uint32)tif->tif_rawdatasize) { + if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) { tif->tif_rawcc = tif->tif_rawdatasize - sp->stream.avail_out; TIFFFlushData1(tif); sp->stream.next_out = tif->tif_rawdata; - sp->stream.avail_out = tif->tif_rawdatasize; + sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in PixarLogPreEncode */ } break; default: - TIFFErrorExt(tif->tif_clientdata, module, "%s: zlib error: %s", - tif->tif_name, sp->stream.msg); + TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", + sp->stream.msg); return (0); } } while (state != Z_STREAM_END); @@ -1159,9 +1227,11 @@ PixarLogClose(TIFF* tif) { TIFFDirectory *td = &tif->tif_dir; - /* In a really sneaky maneuver, on close, we covertly modify both - * bitspersample and sampleformat in the directory to indicate - * 8-bit linear. This way, the decode "just works" even for + /* In a really sneaky (and really incorrect, and untruthfull, 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 + * indicate 8-bit linear. This way, the decode "just works" even for * readers that don't know about PixarLog, or how to set * the PIXARLOGDATFMT pseudo-tag. */ @@ -1202,26 +1272,26 @@ PixarLogCleanup(TIFF* tif) } static int -PixarLogVSetField(TIFF* tif, ttag_t tag, va_list ap) +PixarLogVSetField(TIFF* tif, uint32 tag, va_list ap) { + static const char module[] = "PixarLogVSetField"; PixarLogState *sp = (PixarLogState *)tif->tif_data; int result; - static const char module[] = "PixarLogVSetField"; switch (tag) { case TIFFTAG_PIXARLOGQUALITY: - sp->quality = va_arg(ap, int); + sp->quality = (int) va_arg(ap, int); if (tif->tif_mode != O_RDONLY && (sp->state&PLSTATE_INIT)) { if (deflateParams(&sp->stream, sp->quality, Z_DEFAULT_STRATEGY) != Z_OK) { - TIFFErrorExt(tif->tif_clientdata, module, "%s: zlib error: %s", - tif->tif_name, sp->stream.msg); + TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", + sp->stream.msg); return (0); } } return (1); case TIFFTAG_PIXARLOGDATAFMT: - sp->user_datafmt = va_arg(ap, int); + sp->user_datafmt = (int) va_arg(ap, int); /* Tweak the TIFF header so that the rest of libtiff knows what * size of data will be passed between app and library, and * assume that the app knows what it is doing and is not @@ -1253,7 +1323,7 @@ PixarLogVSetField(TIFF* tif, ttag_t tag, va_list ap) /* * Must recalculate sizes should bits/sample change. */ - tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tsize_t) -1; + tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1); tif->tif_scanlinesize = TIFFScanlineSize(tif); result = 1; /* NB: pseudo tag */ break; @@ -1264,7 +1334,7 @@ PixarLogVSetField(TIFF* tif, ttag_t tag, va_list ap) } static int -PixarLogVGetField(TIFF* tif, ttag_t tag, va_list ap) +PixarLogVGetField(TIFF* tif, uint32 tag, va_list ap) { PixarLogState *sp = (PixarLogState *)tif->tif_data; @@ -1281,9 +1351,9 @@ PixarLogVGetField(TIFF* tif, ttag_t tag, va_list ap) return (1); } -static const TIFFFieldInfo pixarlogFieldInfo[] = { - {TIFFTAG_PIXARLOGDATAFMT,0,0,TIFF_ANY, FIELD_PSEUDO,FALSE,FALSE,""}, - {TIFFTAG_PIXARLOGQUALITY,0,0,TIFF_ANY, FIELD_PSEUDO,FALSE,FALSE,""} +static const TIFFField pixarlogFields[] = { + {TIFFTAG_PIXARLOGDATAFMT, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}, + {TIFFTAG_PIXARLOGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL} }; int @@ -1298,8 +1368,8 @@ TIFFInitPixarLog(TIFF* tif, int scheme) /* * Merge codec-specific tag information. */ - if (!_TIFFMergeFieldInfo(tif, pixarlogFieldInfo, - TIFFArrayCount(pixarlogFieldInfo))) { + if (!_TIFFMergeFields(tif, pixarlogFields, + TIFFArrayCount(pixarlogFields))) { TIFFErrorExt(tif->tif_clientdata, module, "Merging PixarLog codec-specific tags failed"); return 0; @@ -1308,7 +1378,7 @@ TIFFInitPixarLog(TIFF* tif, int scheme) /* * Allocate state block so tag methods have storage to record values. */ - tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (PixarLogState)); + tif->tif_data = (uint8*) _TIFFmalloc(sizeof (PixarLogState)); if (tif->tif_data == NULL) goto bad; sp = (PixarLogState*) tif->tif_data; @@ -1319,17 +1389,18 @@ TIFFInitPixarLog(TIFF* tif, int scheme) /* * Install codec methods. */ + tif->tif_fixuptags = PixarLogFixupTags; tif->tif_setupdecode = PixarLogSetupDecode; tif->tif_predecode = PixarLogPreDecode; tif->tif_decoderow = PixarLogDecode; - tif->tif_decodestrip = PixarLogDecode; + tif->tif_decodestrip = PixarLogDecode; tif->tif_decodetile = PixarLogDecode; tif->tif_setupencode = PixarLogSetupEncode; tif->tif_preencode = PixarLogPreEncode; tif->tif_postencode = PixarLogPostEncode; - tif->tif_encoderow = PixarLogEncode; + tif->tif_encoderow = PixarLogEncode; tif->tif_encodestrip = PixarLogEncode; - tif->tif_encodetile = PixarLogEncode; + tif->tif_encodetile = PixarLogEncode; tif->tif_close = PixarLogClose; tif->tif_cleanup = PixarLogCleanup; diff --git a/thirdparty/libtiff/tif_predict.c b/thirdparty/libtiff/tif_predict.c index bbc221f2..f93c6645 100644 --- a/thirdparty/libtiff/tif_predict.c +++ b/thirdparty/libtiff/tif_predict.c @@ -1,4 +1,4 @@ -/* $Id: tif_predict.c,v 1.11.2.4 2010-06-08 18:50:42 bfriesen Exp $ */ +/* $Id: tif_predict.c,v 1.32 2010-03-10 18:56:49 bfriesen Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -34,20 +34,20 @@ #define PredictorState(tif) ((TIFFPredictorState*) (tif)->tif_data) -static void horAcc8(TIFF*, tidata_t, tsize_t); -static void horAcc16(TIFF*, tidata_t, tsize_t); -static void horAcc32(TIFF*, tidata_t, tsize_t); -static void swabHorAcc16(TIFF*, tidata_t, tsize_t); -static void swabHorAcc32(TIFF*, tidata_t, tsize_t); -static void horDiff8(TIFF*, tidata_t, tsize_t); -static void horDiff16(TIFF*, tidata_t, tsize_t); -static void horDiff32(TIFF*, tidata_t, tsize_t); -static void fpAcc(TIFF*, tidata_t, tsize_t); -static void fpDiff(TIFF*, tidata_t, tsize_t); -static int PredictorDecodeRow(TIFF*, tidata_t, tsize_t, tsample_t); -static int PredictorDecodeTile(TIFF*, tidata_t, tsize_t, tsample_t); -static int PredictorEncodeRow(TIFF*, tidata_t, tsize_t, tsample_t); -static int PredictorEncodeTile(TIFF*, tidata_t, tsize_t, tsample_t); +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 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); +static int PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s); static int PredictorSetup(TIFF* tif) @@ -66,23 +66,23 @@ PredictorSetup(TIFF* tif) && td->td_bitspersample != 16 && td->td_bitspersample != 32) { TIFFErrorExt(tif->tif_clientdata, module, - "Horizontal differencing \"Predictor\" not supported with %d-bit samples", - td->td_bitspersample); + "Horizontal differencing \"Predictor\" not supported with %d-bit samples", + td->td_bitspersample); return 0; } break; case PREDICTOR_FLOATINGPOINT: if (td->td_sampleformat != SAMPLEFORMAT_IEEEFP) { TIFFErrorExt(tif->tif_clientdata, module, - "Floating point \"Predictor\" not supported with %d data format", - td->td_sampleformat); + "Floating point \"Predictor\" not supported with %d data format", + td->td_sampleformat); return 0; } break; default: TIFFErrorExt(tif->tif_clientdata, module, - "\"Predictor\" value %d not supported", - sp->predictor); + "\"Predictor\" value %d not supported", + sp->predictor); return 0; } sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? @@ -94,6 +94,8 @@ PredictorSetup(TIFF* tif) sp->rowsize = TIFFTileRowSize(tif); else sp->rowsize = TIFFScanlineSize(tif); + if (sp->rowsize == 0) + return 0; return 1; } @@ -126,6 +128,7 @@ PredictorSetupDecode(TIFF* tif) sp->decodetile = tif->tif_decodetile; tif->tif_decodetile = PredictorDecodeTile; } + /* * If the data is horizontally differenced 16-bit data that * requires byte-swapping, then it must be byte swapped before @@ -137,10 +140,10 @@ PredictorSetupDecode(TIFF* tif) if (sp->decodepfunc == horAcc16) { sp->decodepfunc = swabHorAcc16; tif->tif_postdecode = _TIFFNoPostDecode; - } else if (sp->decodepfunc == horAcc32) { + } else if (sp->decodepfunc == horAcc32) { sp->decodepfunc = swabHorAcc32; tif->tif_postdecode = _TIFFNoPostDecode; - } + } } } @@ -205,7 +208,7 @@ PredictorSetupEncode(TIFF* tif) tif->tif_encodetile = PredictorEncodeTile; } } - + else if (sp->predictor == 3) { sp->encodepfunc = fpDiff; /* @@ -228,7 +231,7 @@ PredictorSetupEncode(TIFF* tif) #define REPEAT4(n, op) \ switch (n) { \ - default: { int i; for (i = n-4; i > 0; i--) { op; } } \ + default: { tmsize_t i; for (i = n-4; i > 0; i--) { op; } } \ case 4: op; \ case 3: op; \ case 2: op; \ @@ -237,13 +240,13 @@ PredictorSetupEncode(TIFF* tif) } static void -horAcc8(TIFF* tif, tidata_t cp0, tsize_t cc) +horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc) { - tsize_t stride = PredictorState(tif)->stride; + tmsize_t stride = PredictorState(tif)->stride; char* cp = (char*) cp0; + assert((cc%stride)==0); if (cc > stride) { - cc -= stride; /* * Pipeline the most common cases. */ @@ -251,40 +254,49 @@ horAcc8(TIFF* tif, tidata_t cp0, tsize_t cc) unsigned int cr = cp[0]; unsigned int cg = cp[1]; unsigned int cb = cp[2]; - do { - cc -= 3, cp += 3; + 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]); - } while ((int32) cc > 0); + cc -= 3; + cp += 3; + } } else if (stride == 4) { unsigned int cr = cp[0]; unsigned int cg = cp[1]; unsigned int cb = cp[2]; unsigned int ca = cp[3]; - do { - cc -= 4, cp += 4; + 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]); - } while ((int32) cc > 0); + cc -= 4; + cp += 4; + } } else { + cc -= stride; do { REPEAT4(stride, cp[stride] = (char) (cp[stride] + *cp); cp++) cc -= stride; - } while ((int32) cc > 0); + } while (cc>0); } } } static void -swabHorAcc16(TIFF* tif, tidata_t cp0, tsize_t cc) +swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc) { - tsize_t stride = PredictorState(tif)->stride; + tmsize_t stride = PredictorState(tif)->stride; uint16* wp = (uint16*) cp0; - tsize_t wc = cc / 2; + tmsize_t wc = cc / 2; + + assert((cc%(2*stride))==0); if (wc > stride) { TIFFSwabArrayOfShort(wp, wc); @@ -292,32 +304,36 @@ swabHorAcc16(TIFF* tif, tidata_t cp0, tsize_t cc) do { REPEAT4(stride, wp[stride] += wp[0]; wp++) wc -= stride; - } while ((int32) wc > 0); + } while (wc > 0); } } static void -horAcc16(TIFF* tif, tidata_t cp0, tsize_t cc) +horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc) { - tsize_t stride = PredictorState(tif)->stride; + tmsize_t stride = PredictorState(tif)->stride; uint16* wp = (uint16*) cp0; - tsize_t wc = cc / 2; + tmsize_t wc = cc / 2; + + assert((cc%(2*stride))==0); if (wc > stride) { wc -= stride; do { REPEAT4(stride, wp[stride] += wp[0]; wp++) wc -= stride; - } while ((int32) wc > 0); + } while (wc > 0); } } static void -swabHorAcc32(TIFF* tif, tidata_t cp0, tsize_t cc) +swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc) { - tsize_t stride = PredictorState(tif)->stride; + tmsize_t stride = PredictorState(tif)->stride; uint32* wp = (uint32*) cp0; - tsize_t wc = cc / 4; + tmsize_t wc = cc / 4; + + assert((cc%(4*stride))==0); if (wc > stride) { TIFFSwabArrayOfLong(wp, wc); @@ -325,23 +341,25 @@ swabHorAcc32(TIFF* tif, tidata_t cp0, tsize_t cc) do { REPEAT4(stride, wp[stride] += wp[0]; wp++) wc -= stride; - } while ((int32) wc > 0); + } while (wc > 0); } } static void -horAcc32(TIFF* tif, tidata_t cp0, tsize_t cc) +horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc) { - tsize_t stride = PredictorState(tif)->stride; + tmsize_t stride = PredictorState(tif)->stride; uint32* wp = (uint32*) cp0; - tsize_t wc = cc / 4; + tmsize_t wc = cc / 4; + + assert((cc%(4*stride))==0); if (wc > stride) { wc -= stride; do { REPEAT4(stride, wp[stride] += wp[0]; wp++) wc -= stride; - } while ((int32) wc > 0); + } while (wc > 0); } } @@ -349,15 +367,17 @@ horAcc32(TIFF* tif, tidata_t cp0, tsize_t cc) * Floating point predictor accumulation routine. */ static void -fpAcc(TIFF* tif, tidata_t cp0, tsize_t cc) +fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc) { - tsize_t stride = PredictorState(tif)->stride; + tmsize_t stride = PredictorState(tif)->stride; uint32 bps = tif->tif_dir.td_bitspersample / 8; - tsize_t wc = cc / bps; - tsize_t count = cc; + tmsize_t wc = cc / bps; + tmsize_t count = cc; uint8 *cp = (uint8 *) cp0; uint8 *tmp = (uint8 *)_TIFFmalloc(cc); + assert((cc%(bps*stride))==0); + if (!tmp) return; @@ -371,12 +391,12 @@ fpAcc(TIFF* tif, tidata_t cp0, tsize_t cc) for (count = 0; count < wc; count++) { uint32 byte; for (byte = 0; byte < bps; byte++) { -#if WORDS_BIGENDIAN + #if WORDS_BIGENDIAN cp[bps * count + byte] = tmp[byte * wc + count]; -#else + #else cp[bps * count + byte] = tmp[(bps - byte - 1) * wc + count]; -#endif + #endif } } _TIFFfree(tmp); @@ -386,13 +406,13 @@ fpAcc(TIFF* tif, tidata_t cp0, tsize_t cc) * Decode a scanline and apply the predictor routine. */ static int -PredictorDecodeRow(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) +PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) { TIFFPredictorState *sp = PredictorState(tif); assert(sp != NULL); assert(sp->decoderow != NULL); - assert(sp->decodepfunc != NULL); + assert(sp->decodepfunc != NULL); if ((*sp->decoderow)(tif, op0, occ0, s)) { (*sp->decodepfunc)(tif, op0, occ0); @@ -409,7 +429,7 @@ PredictorDecodeRow(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) * strip/tile dimensions. */ static int -PredictorDecodeTile(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) +PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) { TIFFPredictorState *sp = PredictorState(tif); @@ -417,11 +437,12 @@ PredictorDecodeTile(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) assert(sp->decodetile != NULL); if ((*sp->decodetile)(tif, op0, occ0, s)) { - tsize_t rowsize = sp->rowsize; + tmsize_t rowsize = sp->rowsize; assert(rowsize > 0); + assert((occ0%rowsize)==0); assert(sp->decodepfunc != NULL); - while ((long)occ0 > 0) { - (*sp->decodepfunc)(tif, op0, (tsize_t) rowsize); + while (occ0 > 0) { + (*sp->decodepfunc)(tif, op0, rowsize); occ0 -= rowsize; op0 += rowsize; } @@ -431,12 +452,14 @@ PredictorDecodeTile(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) } static void -horDiff8(TIFF* tif, tidata_t cp0, tsize_t cc) +horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc) { TIFFPredictorState* sp = PredictorState(tif); - tsize_t stride = sp->stride; + tmsize_t stride = sp->stride; char* cp = (char*) cp0; + assert((cc%stride)==0); + if (cc > stride) { cc -= stride; /* @@ -452,7 +475,7 @@ horDiff8(TIFF* tif, tidata_t cp0, tsize_t cc) g1 = cp[4]; cp[4] = g1-g2; g2 = g1; b1 = cp[5]; cp[5] = b1-b2; b2 = b1; cp += 3; - } while ((int32)(cc -= 3) > 0); + } while ((cc -= 3) > 0); } else if (stride == 4) { int r1, g1, b1, a1; int r2 = cp[0]; @@ -465,23 +488,25 @@ horDiff8(TIFF* tif, tidata_t cp0, tsize_t cc) b1 = cp[6]; cp[6] = b1-b2; b2 = b1; a1 = cp[7]; cp[7] = a1-a2; a2 = a1; cp += 4; - } while ((int32)(cc -= 4) > 0); + } while ((cc -= 4) > 0); } else { cp += cc - 1; do { REPEAT4(stride, cp[stride] -= cp[0]; cp--) - } while ((int32)(cc -= stride) > 0); + } while ((cc -= stride) > 0); } } } static void -horDiff16(TIFF* tif, tidata_t cp0, tsize_t cc) +horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc) { TIFFPredictorState* sp = PredictorState(tif); - tsize_t stride = sp->stride; + tmsize_t stride = sp->stride; int16 *wp = (int16*) cp0; - tsize_t wc = cc/2; + tmsize_t wc = cc/2; + + assert((cc%(2*stride))==0); if (wc > stride) { wc -= stride; @@ -489,17 +514,19 @@ horDiff16(TIFF* tif, tidata_t cp0, tsize_t cc) do { REPEAT4(stride, wp[stride] -= wp[0]; wp--) wc -= stride; - } while ((int32) wc > 0); + } while (wc > 0); } } static void -horDiff32(TIFF* tif, tidata_t cp0, tsize_t cc) +horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc) { TIFFPredictorState* sp = PredictorState(tif); - tsize_t stride = sp->stride; + tmsize_t stride = sp->stride; int32 *wp = (int32*) cp0; - tsize_t wc = cc/4; + tmsize_t wc = cc/4; + + assert((cc%(4*stride))==0); if (wc > stride) { wc -= stride; @@ -507,7 +534,7 @@ horDiff32(TIFF* tif, tidata_t cp0, tsize_t cc) do { REPEAT4(stride, wp[stride] -= wp[0]; wp--) wc -= stride; - } while ((int32) wc > 0); + } while (wc > 0); } } @@ -515,15 +542,17 @@ horDiff32(TIFF* tif, tidata_t cp0, tsize_t cc) * Floating point predictor differencing routine. */ static void -fpDiff(TIFF* tif, tidata_t cp0, tsize_t cc) +fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc) { - tsize_t stride = PredictorState(tif)->stride; + tmsize_t stride = PredictorState(tif)->stride; uint32 bps = tif->tif_dir.td_bitspersample / 8; - tsize_t wc = cc / bps; - tsize_t count; + tmsize_t wc = cc / bps; + tmsize_t count; uint8 *cp = (uint8 *) cp0; uint8 *tmp = (uint8 *)_TIFFmalloc(cc); + assert((cc%(bps*stride))==0); + if (!tmp) return; @@ -531,12 +560,12 @@ fpDiff(TIFF* tif, tidata_t cp0, tsize_t cc) for (count = 0; count < wc; count++) { uint32 byte; for (byte = 0; byte < bps; byte++) { -#if WORDS_BIGENDIAN - cp[byte * wc + count] = tmp[bps * count + byte]; -#else + #if WORDS_BIGENDIAN + cp[byte * wc + count] = tmp[bps * count + byte]; + #else cp[(bps - byte - 1) * wc + count] = tmp[bps * count + byte]; -#endif + #endif } } _TIFFfree(tmp); @@ -548,7 +577,7 @@ fpDiff(TIFF* tif, tidata_t cp0, tsize_t cc) } static int -PredictorEncodeRow(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) { TIFFPredictorState *sp = PredictorState(tif); @@ -562,12 +591,12 @@ PredictorEncodeRow(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) } static int -PredictorEncodeTile(TIFF* tif, tidata_t bp0, tsize_t cc0, tsample_t s) +PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s) { static const char module[] = "PredictorEncodeTile"; TIFFPredictorState *sp = PredictorState(tif); uint8 *working_copy; - tsize_t cc = cc0, rowsize; + tmsize_t cc = cc0, rowsize; unsigned char* bp; int result_code; @@ -583,7 +612,7 @@ PredictorEncodeTile(TIFF* tif, tidata_t bp0, tsize_t cc0, tsample_t s) if( working_copy == NULL ) { TIFFErrorExt(tif->tif_clientdata, module, - "Out of memory allocating %d byte temp buffer.", + "Out of memory allocating " TIFF_SSIZE_FORMAT " byte temp buffer.", cc0 ); return 0; } @@ -607,13 +636,12 @@ PredictorEncodeTile(TIFF* tif, tidata_t bp0, tsize_t cc0, tsample_t s) #define FIELD_PREDICTOR (FIELD_CODEC+0) /* XXX */ -static const TIFFFieldInfo predictFieldInfo[] = { - { TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, FIELD_PREDICTOR, - FALSE, FALSE, "Predictor" }, +static const TIFFField predictFields[] = { + { TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UINT16, FIELD_PREDICTOR, FALSE, FALSE, "Predictor", NULL }, }; static int -PredictorVSetField(TIFF* tif, ttag_t tag, va_list ap) +PredictorVSetField(TIFF* tif, uint32 tag, va_list ap) { TIFFPredictorState *sp = PredictorState(tif); @@ -622,7 +650,7 @@ PredictorVSetField(TIFF* tif, ttag_t tag, va_list ap) switch (tag) { case TIFFTAG_PREDICTOR: - sp->predictor = (uint16) va_arg(ap, int); + sp->predictor = (uint16) va_arg(ap, uint16_vap); TIFFSetFieldBit(tif, FIELD_PREDICTOR); break; default: @@ -633,7 +661,7 @@ PredictorVSetField(TIFF* tif, ttag_t tag, va_list ap) } static int -PredictorVGetField(TIFF* tif, ttag_t tag, va_list ap) +PredictorVGetField(TIFF* tif, uint32 tag, va_list ap) { TIFFPredictorState *sp = PredictorState(tif); @@ -659,9 +687,9 @@ PredictorPrintDir(TIFF* tif, FILE* fd, long flags) if (TIFFFieldSet(tif,FIELD_PREDICTOR)) { fprintf(fd, " Predictor: "); switch (sp->predictor) { - case 1: fprintf(fd, "none "); break; - case 2: fprintf(fd, "horizontal differencing "); break; - case 3: fprintf(fd, "floating point predictor "); break; + case 1: fprintf(fd, "none "); break; + 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); } @@ -679,10 +707,10 @@ TIFFPredictorInit(TIFF* tif) /* * Merge codec-specific tag information. */ - if (!_TIFFMergeFieldInfo(tif, predictFieldInfo, - TIFFArrayCount(predictFieldInfo))) { + if (!_TIFFMergeFields(tif, predictFields, + TIFFArrayCount(predictFields))) { TIFFErrorExt(tif->tif_clientdata, "TIFFPredictorInit", - "Merging Predictor codec-specific tags failed"); + "Merging Predictor codec-specific tags failed"); return 0; } @@ -694,7 +722,7 @@ TIFFPredictorInit(TIFF* tif) PredictorVGetField;/* hook for predictor tag */ sp->vsetparent = tif->tif_tagmethods.vsetfield; tif->tif_tagmethods.vsetfield = - PredictorVSetField;/* hook for predictor tag */ + PredictorVSetField;/* hook for predictor tag */ sp->printdir = tif->tif_tagmethods.printdir; tif->tif_tagmethods.printdir = PredictorPrintDir; /* hook for predictor tag */ diff --git a/thirdparty/libtiff/tif_predict.h b/thirdparty/libtiff/tif_predict.h index da0ad989..dc7144c6 100644 --- a/thirdparty/libtiff/tif_predict.h +++ b/thirdparty/libtiff/tif_predict.h @@ -1,26 +1,26 @@ -/* $Id: tif_predict.h,v 1.3.2.2 2010-06-08 18:50:42 bfriesen Exp $ */ +/* $Id: tif_predict.h,v 1.8 2010-03-10 18:56:49 bfriesen Exp $ */ /* * Copyright (c) 1995-1997 Sam Leffler * Copyright (c) 1995-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -36,32 +36,32 @@ * the predictor code can cast tif_data to find its state. */ typedef struct { - int predictor; /* predictor tag value */ - int stride; /* sample stride over data */ - tsize_t rowsize; /* tile/strip row size */ + int predictor; /* predictor tag value */ + tmsize_t stride; /* sample stride over data */ + tmsize_t rowsize; /* tile/strip row size */ - 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 */ - - 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 */ + 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 */ - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ - TIFFPrintMethod printdir; /* super-class method */ - TIFFBoolMethod setupdecode; /* super-class method */ - TIFFBoolMethod setupencode; /* super-class method */ + 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 */ + + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ + TIFFPrintMethod printdir; /* super-class method */ + TIFFBoolMethod setupdecode; /* super-class method */ + TIFFBoolMethod setupencode; /* super-class method */ } TIFFPredictorState; #if defined(__cplusplus) extern "C" { #endif -extern int TIFFPredictorInit(TIFF*); -extern int TIFFPredictorCleanup(TIFF*); +extern int TIFFPredictorInit(TIFF*); +extern int TIFFPredictorCleanup(TIFF*); #if defined(__cplusplus) } #endif diff --git a/thirdparty/libtiff/tif_print.c b/thirdparty/libtiff/tif_print.c index d9e4435c..9e27ae25 100644 --- a/thirdparty/libtiff/tif_print.c +++ b/thirdparty/libtiff/tif_print.c @@ -1,4 +1,4 @@ -/* $Id: tif_print.c,v 1.36.2.4 2010-06-08 18:50:42 bfriesen Exp $ */ +/* $Id: tif_print.c,v 1.61 2012-12-12 22:50:18 tgl Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -31,9 +31,12 @@ */ #include "tiffiop.h" #include -#include + #include +static void +_TIFFprintAsciiBounded(FILE* fd, const char* cp, int max_chars); + static const char *photoNames[] = { "min-is-white", /* PHOTOMETRIC_MINISWHITE */ "min-is-black", /* PHOTOMETRIC_MINISBLACK */ @@ -44,6 +47,8 @@ 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])) @@ -61,7 +66,7 @@ static const char *orientNames[] = { #define NORIENTNAMES (sizeof (orientNames) / sizeof (orientNames[0])) static void -_TIFFPrintField(FILE* fd, const TIFFFieldInfo *fip, +_TIFFPrintField(FILE* fd, const TIFFField *fip, uint32 value_count, void *raw_data) { uint32 j; @@ -73,7 +78,7 @@ _TIFFPrintField(FILE* fd, const TIFFFieldInfo *fip, fprintf(fd, "%u", ((uint8 *) raw_data)[j]); else if(fip->field_type == TIFF_UNDEFINED) fprintf(fd, "0x%x", - (unsigned int) ((unsigned char *) raw_data)[j]); + (unsigned int) ((unsigned char *) raw_data)[j]); else if(fip->field_type == TIFF_SBYTE) fprintf(fd, "%d", ((int8 *) raw_data)[j]); else if(fip->field_type == TIFF_SHORT) @@ -82,23 +87,46 @@ _TIFFPrintField(FILE* fd, const TIFFFieldInfo *fip, fprintf(fd, "%d", ((int16 *) raw_data)[j]); else if(fip->field_type == TIFF_LONG) fprintf(fd, "%lu", - (unsigned long)((uint32 *) raw_data)[j]); + (unsigned long)((uint32 *) raw_data)[j]); else if(fip->field_type == TIFF_SLONG) fprintf(fd, "%ld", (long)((int32 *) raw_data)[j]); + else if(fip->field_type == TIFF_IFD) + fprintf(fd, "0x%lx", + (unsigned long)((uint32 *) raw_data)[j]); else if(fip->field_type == TIFF_RATIONAL || fip->field_type == TIFF_SRATIONAL || fip->field_type == TIFF_FLOAT) fprintf(fd, "%f", ((float *) raw_data)[j]); - else if(fip->field_type == TIFF_IFD) - fprintf(fd, "0x%ulx", ((uint32 *) raw_data)[j]); + else if(fip->field_type == TIFF_LONG8) +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + fprintf(fd, "%I64u", + (unsigned __int64)((uint64 *) raw_data)[j]); +#else + fprintf(fd, "%llu", + (unsigned long long)((uint64 *) raw_data)[j]); +#endif + else if(fip->field_type == TIFF_SLONG8) +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + fprintf(fd, "%I64d", (__int64)((int64 *) raw_data)[j]); +#else + fprintf(fd, "%lld", (long long)((int64 *) raw_data)[j]); +#endif + else if(fip->field_type == TIFF_IFD8) +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + fprintf(fd, "0x%I64x", + (unsigned __int64)((uint64 *) raw_data)[j]); +#else + fprintf(fd, "0x%llx", + (unsigned long long)((uint64 *) raw_data)[j]); +#endif + else if(fip->field_type == TIFF_FLOAT) + fprintf(fd, "%f", ((float *)raw_data)[j]); + else if(fip->field_type == TIFF_DOUBLE) + fprintf(fd, "%f", ((double *) raw_data)[j]); else if(fip->field_type == TIFF_ASCII) { fprintf(fd, "%s", (char *) raw_data); break; } - else if(fip->field_type == TIFF_DOUBLE) - fprintf(fd, "%f", ((double *) raw_data)[j]); - else if(fip->field_type == TIFF_FLOAT) - fprintf(fd, "%f", ((float *)raw_data)[j]); else { fprintf(fd, ""); break; @@ -112,16 +140,22 @@ _TIFFPrintField(FILE* fd, const TIFFFieldInfo *fip, } static int -_TIFFPrettyPrintField(TIFF* tif, FILE* fd, ttag_t tag, +_TIFFPrettyPrintField(TIFF* tif, const TIFFField *fip, FILE* fd, uint32 tag, uint32 value_count, void *raw_data) { - //TIFFDirectory *td = &tif->tif_dir; + (void) tif; + /* do not try to pretty print auto-defined fields */ + if (strncmp(fip->field_name,"Tag ", 4) == 0) { + return 0; + } + switch (tag) { case TIFFTAG_INKSET: - fprintf(fd, " Ink Set: "); - switch (*((uint16*)raw_data)) { + if (value_count == 2 && fip->field_type == TIFF_SHORT) { + fprintf(fd, " Ink Set: "); + switch (*((uint16*)raw_data)) { case INKSET_CMYK: fprintf(fd, "CMYK\n"); break; @@ -130,30 +164,31 @@ _TIFFPrettyPrintField(TIFF* tif, FILE* fd, ttag_t tag, *((uint16*)raw_data), *((uint16*)raw_data)); break; + } + return 1; } - return 1; - case TIFFTAG_DOTRANGE: - fprintf(fd, " Dot Range: %u-%u\n", - ((uint16*)raw_data)[0], ((uint16*)raw_data)[1]); - return 1; - case TIFFTAG_WHITEPOINT: - fprintf(fd, " White Point: %g-%g\n", - ((float *)raw_data)[0], ((float *)raw_data)[1]); return 1; - case TIFFTAG_REFERENCEBLACKWHITE: - { - uint16 i; + return 0; + + case TIFFTAG_DOTRANGE: + if (value_count == 2 && fip->field_type == TIFF_SHORT) { + fprintf(fd, " Dot Range: %u-%u\n", + ((uint16*)raw_data)[0], ((uint16*)raw_data)[1]); + return 1; + } + return 0; + + case TIFFTAG_WHITEPOINT: + if (value_count == 2 && fip->field_type == TIFF_RATIONAL) { + fprintf(fd, " White Point: %g-%g\n", + ((float *)raw_data)[0], ((float *)raw_data)[1]); + return 1; + } + return 0; - fprintf(fd, " Reference Black/White:\n"); - for (i = 0; i < 3; i++) - fprintf(fd, " %2d: %5g %5g\n", i, - ((float *)raw_data)[2*i+0], - ((float *)raw_data)[2*i+1]); - return 1; - } case TIFFTAG_XMLPACKET: { uint32 i; - + fprintf(fd, " XMLPacket (XMP Metadata):\n" ); for(i = 0; i < value_count; i++) fputc(((char *)raw_data)[i], fd); @@ -166,23 +201,29 @@ _TIFFPrettyPrintField(TIFF* tif, FILE* fd, ttag_t tag, * defined as array of LONG values. */ fprintf(fd, - " RichTIFFIPTC Data: , %lu bytes\n", - (unsigned long) value_count * 4); + " RichTIFFIPTC Data: , %lu bytes\n", + (unsigned long) value_count * 4); return 1; + case TIFFTAG_PHOTOSHOP: fprintf(fd, " Photoshop Data: , %lu bytes\n", - (unsigned long) value_count); + (unsigned long) value_count); return 1; + case TIFFTAG_ICCPROFILE: fprintf(fd, " ICC Profile: , %lu bytes\n", - (unsigned long) value_count); + (unsigned long) value_count); return 1; + case TIFFTAG_STONITS: - fprintf(fd, - " Sample to Nits conversion factor: %.4e\n", - *((double*)raw_data)); - return 1; - } + if (value_count == 1 && fip->field_type == TIFF_DOUBLE) { + fprintf(fd, + " Sample to Nits conversion factor: %.4e\n", + *((double*)raw_data)); + return 1; + } + return 0; + } return 0; } @@ -199,8 +240,15 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags) uint16 i; long l, n; - fprintf(fd, "TIFF Directory at offset 0x%lx (%lu)\n", - (unsigned long)tif->tif_diroff, (unsigned long)tif->tif_diroff); +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + fprintf(fd, "TIFF Directory at offset 0x%I64x (%I64u)\n", + (unsigned __int64) tif->tif_diroff, + (unsigned __int64) tif->tif_diroff); +#else + fprintf(fd, "TIFF Directory at offset 0x%llx (%llu)\n", + (unsigned long long) tif->tif_diroff, + (unsigned long long) tif->tif_diroff); +#endif if (TIFFFieldSet(tif,FIELD_SUBFILETYPE)) { fprintf(fd, " Subfile Type:"); sep = " "; @@ -344,9 +392,13 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags) fprintf(fd, " Ink Names: "); i = td->td_samplesperpixel; sep = ""; - for (cp = td->td_inknames; i > 0; cp = strchr(cp,'\0')+1, i--) { + for (cp = td->td_inknames; + i > 0 && cp < td->td_inknames + td->td_inknameslen; + cp = strchr(cp,'\0')+1, i--) { + int max_chars = + td->td_inknameslen - (cp - td->td_inknames); fputs(sep, fd); - _TIFFprintAscii(fd, cp); + _TIFFprintAsciiBounded(fd, cp, max_chars); sep = ", "; } fputs("\n", fd); @@ -386,18 +438,9 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags) } if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING)) { - /* - * For hacky reasons (see tif_jpeg.c - JPEGFixupTestSubsampling), - * we need to fetch this rather than trust what is in our - * structures. - */ - uint16 subsampling[2]; - - TIFFGetField( tif, TIFFTAG_YCBCRSUBSAMPLING, - subsampling + 0, subsampling + 1 ); fprintf(fd, " YCbCr Subsampling: %u, %u\n", - subsampling[0], subsampling[1] ); - } + td->td_ycbcrsubsampling[0], td->td_ycbcrsubsampling[1] ); + } if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING)) { fprintf(fd, " YCbCr Positioning: "); switch (td->td_ycbcrpositioning) { @@ -437,12 +480,20 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags) fprintf(fd, " Min Sample Value: %u\n", td->td_minsamplevalue); if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE)) fprintf(fd, " Max Sample Value: %u\n", td->td_maxsamplevalue); - if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE)) - fprintf(fd, " SMin Sample Value: %g\n", - td->td_sminsamplevalue); - if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE)) - fprintf(fd, " SMax Sample Value: %g\n", - td->td_smaxsamplevalue); + if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE)) { + int count = (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1; + fprintf(fd, " SMin Sample Value:"); + for (i = 0; i < count; ++i) + fprintf(fd, " %g", td->td_sminsamplevalue[i]); + fprintf(fd, "\n"); + } + if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE)) { + int count = (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1; + fprintf(fd, " SMax Sample Value:"); + for (i = 0; i < count; ++i) + fprintf(fd, " %g", td->td_smaxsamplevalue[i]); + fprintf(fd, "\n"); + } if (TIFFFieldSet(tif,FIELD_PLANARCONFIG)) { fprintf(fd, " Planar Configuration: "); switch (td->td_planarconfig) { @@ -475,6 +526,13 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags) } else fprintf(fd, "(present)\n"); } + if (TIFFFieldSet(tif,FIELD_REFBLACKWHITE)) { + fprintf(fd, " Reference Black/White:\n"); + for (i = 0; i < 3; i++) + fprintf(fd, " %2d: %5g %5g\n", i, + td->td_refblackwhite[2*i+0], + td->td_refblackwhite[2*i+1]); + } if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION)) { fprintf(fd, " Transfer Function: "); if (flags & TIFFPRINT_CURVES) { @@ -494,124 +552,136 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags) if (TIFFFieldSet(tif, FIELD_SUBIFD) && (td->td_subifd)) { fprintf(fd, " SubIFD Offsets:"); for (i = 0; i < td->td_nsubifd; i++) - fprintf(fd, " %5lu", (long) td->td_subifd[i]); +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + fprintf(fd, " %5I64u", + (unsigned __int64) td->td_subifd[i]); +#else + fprintf(fd, " %5llu", + (unsigned long long) td->td_subifd[i]); +#endif fputc('\n', fd); } - /* - ** Custom tag support. - */ - { - int i; - short count; + /* + ** Custom tag support. + */ + { + int i; + short count; - count = (short) TIFFGetTagListCount(tif); - for(i = 0; i < count; i++) { - ttag_t tag = TIFFGetTagListEntry(tif, i); - const TIFFFieldInfo *fip; - uint32 value_count; - int mem_alloc = 0; - void *raw_data; + count = (short) TIFFGetTagListCount(tif); + for(i = 0; i < count; i++) { + uint32 tag = TIFFGetTagListEntry(tif, i); + const TIFFField *fip; + uint32 value_count; + int mem_alloc = 0; + void *raw_data; - fip = TIFFFieldWithTag(tif, tag); - if(fip == NULL) - continue; - - if(fip->field_passcount) { - if(TIFFGetField(tif, tag, &value_count, &raw_data) != 1) + fip = TIFFFieldWithTag(tif, tag); + if(fip == NULL) continue; - } else { - if (fip->field_readcount == TIFF_VARIABLE - || fip->field_readcount == TIFF_VARIABLE2) - value_count = 1; - else if (fip->field_readcount == TIFF_SPP) - value_count = td->td_samplesperpixel; - else - value_count = fip->field_readcount; - if ((fip->field_type == TIFF_ASCII - || fip->field_readcount == TIFF_VARIABLE - || fip->field_readcount == TIFF_VARIABLE2 - || fip->field_readcount == TIFF_SPP - || value_count > 1) - && fip->field_tag != TIFFTAG_PAGENUMBER - && fip->field_tag != TIFFTAG_HALFTONEHINTS - && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING - && fip->field_tag != TIFFTAG_DOTRANGE) { - if(TIFFGetField(tif, tag, &raw_data) != 1) + + if(fip->field_passcount) { + if (fip->field_readcount == TIFF_VARIABLE2 ) { + if(TIFFGetField(tif, tag, &value_count, &raw_data) != 1) + continue; + } else if (fip->field_readcount == TIFF_VARIABLE ) { + uint16 small_value_count; + if(TIFFGetField(tif, tag, &small_value_count, &raw_data) != 1) + continue; + value_count = small_value_count; + } else { + assert (fip->field_readcount == TIFF_VARIABLE + || fip->field_readcount == TIFF_VARIABLE2); continue; - } else if (fip->field_tag != TIFFTAG_PAGENUMBER - && fip->field_tag != TIFFTAG_HALFTONEHINTS - && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING - && fip->field_tag != TIFFTAG_DOTRANGE) { - raw_data = _TIFFmalloc( - _TIFFDataSize(fip->field_type) - * value_count); - mem_alloc = 1; - if(TIFFGetField(tif, tag, raw_data) != 1) { - _TIFFfree(raw_data); - continue; - } + } } else { - /* - * XXX: Should be fixed and removed, see the - * notes related to TIFFTAG_PAGENUMBER, - * TIFFTAG_HALFTONEHINTS, - * TIFFTAG_YCBCRSUBSAMPLING and - * TIFFTAG_DOTRANGE tags in tif_dir.c. */ - char *tmp; - raw_data = _TIFFmalloc( - _TIFFDataSize(fip->field_type) - * value_count); - tmp = raw_data; - mem_alloc = 1; - if(TIFFGetField(tif, tag, tmp, - tmp + _TIFFDataSize(fip->field_type)) != 1) { - _TIFFfree(raw_data); - continue; + if (fip->field_readcount == TIFF_VARIABLE + || fip->field_readcount == TIFF_VARIABLE2) + value_count = 1; + else if (fip->field_readcount == TIFF_SPP) + value_count = td->td_samplesperpixel; + else + value_count = fip->field_readcount; + if (fip->field_tag == TIFFTAG_DOTRANGE + && strcmp(fip->field_name,"DotRange") == 0) { + /* TODO: This is an evil exception and should not have been + 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 */ + static uint16 dotrange[2]; + raw_data = dotrange; + TIFFGetField(tif, tag, dotrange+0, dotrange+1); + } else if (fip->field_type == TIFF_ASCII + || fip->field_readcount == TIFF_VARIABLE + || fip->field_readcount == TIFF_VARIABLE2 + || fip->field_readcount == TIFF_SPP + || value_count > 1) { + if(TIFFGetField(tif, tag, &raw_data) != 1) + continue; + } else { + raw_data = _TIFFmalloc( + _TIFFDataSize(fip->field_type) + * value_count); + mem_alloc = 1; + if(TIFFGetField(tif, tag, raw_data) != 1) { + _TIFFfree(raw_data); + continue; + } } } - } - /* - * Catch the tags which needs to be specially handled and - * pretty print them. If tag not handled in - * _TIFFPrettyPrintField() fall down and print it as any other - * tag. - */ - if (_TIFFPrettyPrintField(tif, fd, tag, value_count, raw_data)) { + /* + * Catch the tags which needs to be specially handled + * and pretty print them. If tag not handled in + * _TIFFPrettyPrintField() fall down and print it as + * any other tag. + */ + if (!_TIFFPrettyPrintField(tif, fip, fd, tag, value_count, raw_data)) + _TIFFPrintField(fd, fip, value_count, raw_data); + if(mem_alloc) _TIFFfree(raw_data); - continue; } - else - _TIFFPrintField(fd, fip, value_count, raw_data); - - if(mem_alloc) - _TIFFfree(raw_data); - } - } + } if (tif->tif_tagmethods.printdir) (*tif->tif_tagmethods.printdir)(tif, fd, flags); + + _TIFFFillStriles( tif ); + if ((flags & TIFFPRINT_STRIPS) && TIFFFieldSet(tif,FIELD_STRIPOFFSETS)) { - tstrip_t s; + uint32 s; fprintf(fd, " %lu %s:\n", (long) td->td_nstrips, isTiled(tif) ? "Tiles" : "Strips"); for (s = 0; s < td->td_nstrips; s++) - fprintf(fd, " %3lu: [%8lu, %8lu]\n", +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + fprintf(fd, " %3lu: [%8I64u, %8I64u]\n", (unsigned long) s, - (unsigned long) td->td_stripoffset[s], - (unsigned long) td->td_stripbytecount[s]); + (unsigned __int64) td->td_stripoffset[s], + (unsigned __int64) td->td_stripbytecount[s]); +#else + fprintf(fd, " %3lu: [%8llu, %8llu]\n", + (unsigned long) s, + (unsigned long long) td->td_stripoffset[s], + (unsigned long long) td->td_stripbytecount[s]); +#endif } } void _TIFFprintAscii(FILE* fd, const char* cp) { - for (; *cp != '\0'; cp++) { + _TIFFprintAsciiBounded( fd, cp, strlen(cp)); +} + +static void +_TIFFprintAsciiBounded(FILE* fd, const char* cp, int max_chars) +{ + for (; max_chars > 0 && *cp != '\0'; cp++, max_chars--) { const char* tp; if (isprint((int)*cp)) { diff --git a/thirdparty/libtiff/tif_read.c b/thirdparty/libtiff/tif_read.c index 8ac0ae66..5cb419bd 100644 --- a/thirdparty/libtiff/tif_read.c +++ b/thirdparty/libtiff/tif_read.c @@ -1,4 +1,4 @@ -/* $Id: tif_read.c,v 1.16.2.3 2010-06-09 14:32:47 bfriesen Exp $ */ +/* $Id: tif_read.c,v 1.45 2015-06-07 22:35:40 bfriesen Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -31,29 +31,161 @@ #include "tiffiop.h" #include - int TIFFFillStrip(TIFF*, tstrip_t); - int TIFFFillTile(TIFF*, ttile_t); -static int TIFFStartStrip(TIFF*, tstrip_t); -static int TIFFStartTile(TIFF*, ttile_t); -static int TIFFCheckRead(TIFF*, int); +int TIFFFillStrip(TIFF* tif, uint32 strip); +int TIFFFillTile(TIFF* tif, uint32 tile); +static int TIFFStartStrip(TIFF* tif, uint32 strip); +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); -#define NOSTRIP ((tstrip_t) -1) /* undefined state */ -#define NOTILE ((ttile_t) -1) /* undefined state */ +#define NOSTRIP ((uint32)(-1)) /* undefined state */ +#define NOTILE ((uint32)(-1)) /* undefined state */ + +static int +TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart ) +{ + static const char module[] = "TIFFFillStripPartial"; + register TIFFDirectory *td = &tif->tif_dir; + tmsize_t unused_data; + uint64 read_offset; + tmsize_t cc, to_read; + /* tmsize_t bytecountm; */ + + if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) + return 0; + + /* + * Expand raw data buffer, if needed, to hold data + * strip coming from file (perhaps should set upper + * bound on the size of a buffer we'll use?). + */ + + /* bytecountm=(tmsize_t) td->td_stripbytecount[strip]; */ + if (read_ahead*2 > tif->tif_rawdatasize) { + assert( restart ); + + tif->tif_curstrip = NOSTRIP; + if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { + TIFFErrorExt(tif->tif_clientdata, module, + "Data buffer too small to hold part of strip %lu", + (unsigned long) strip); + return (0); + } + if (!TIFFReadBufferSetup(tif, 0, read_ahead*2)) + return (0); + } + + if( restart ) + { + tif->tif_rawdataloaded = 0; + tif->tif_rawdataoff = 0; + } + + /* + ** If we are reading more data, move any unused data to the + ** start of the buffer. + */ + if( tif->tif_rawdataloaded > 0 ) + unused_data = tif->tif_rawdataloaded - (tif->tif_rawcp - tif->tif_rawdata); + else + unused_data = 0; + + if( unused_data > 0 ) + { + assert((tif->tif_flags&TIFF_BUFFERMMAP)==0); + memmove( tif->tif_rawdata, tif->tif_rawcp, unused_data ); + } + + /* + ** Seek to the point in the file where more data should be read. + */ + read_offset = td->td_stripoffset[strip] + + tif->tif_rawdataoff + tif->tif_rawdataloaded; + + if (!SeekOK(tif, read_offset)) { + TIFFErrorExt(tif->tif_clientdata, module, + "Seek error at scanline %lu, strip %lu", + (unsigned long) tif->tif_row, (unsigned long) strip); + return 0; + } + + /* + ** How much do we want to read? + */ + to_read = tif->tif_rawdatasize - unused_data; + if( (uint64) to_read > td->td_stripbytecount[strip] + - tif->tif_rawdataoff - tif->tif_rawdataloaded ) + { + 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 + return 0; + } + + tif->tif_rawdataoff = tif->tif_rawdataoff + tif->tif_rawdataloaded - unused_data ; + tif->tif_rawdataloaded = unused_data + to_read; + + tif->tif_rawcp = tif->tif_rawdata; + + if (!isFillOrder(tif, td->td_fillorder) && + (tif->tif_flags & TIFF_NOBITREV) == 0) { + assert((tif->tif_flags&TIFF_BUFFERMMAP)==0); + TIFFReverseBits(tif->tif_rawdata + unused_data, to_read ); + } + + /* + ** When starting a strip from the beginning we need to + ** restart the decoder. + */ + if( restart ) + return TIFFStartStrip(tif, strip); + else + return 1; +} /* * Seek to a random row+sample in a file. + * + * Only used by TIFFReadScanline, and is only used on + * strip organized files. We do some tricky stuff to try + * and avoid reading the whole compressed raw data for big + * strips. */ static int -TIFFSeek(TIFF* tif, uint32 row, tsample_t sample) +TIFFSeek(TIFF* tif, uint32 row, uint16 sample ) { register TIFFDirectory *td = &tif->tif_dir; - tstrip_t strip; + uint32 strip; + int whole_strip; + tmsize_t read_ahead = 0; + /* + ** Establish what strip we are working from. + */ if (row >= td->td_imagelength) { /* out of range */ TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "%lu: Row out of range, max %lu", - (unsigned long) row, - (unsigned long) td->td_imagelength); + "%lu: Row out of range, max %lu", + (unsigned long) row, + (unsigned long) td->td_imagelength); return (0); } if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { @@ -63,13 +195,60 @@ TIFFSeek(TIFF* tif, uint32 row, tsample_t sample) (unsigned long) sample, (unsigned long) td->td_samplesperpixel); return (0); } - strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip; + strip = (uint32)sample*td->td_stripsperimage + row/td->td_rowsperstrip; } else strip = row / td->td_rowsperstrip; + + /* + * Do we want to treat this strip as one whole chunk or + * read it a few lines at a time? + */ +#if defined(CHUNKY_STRIP_READ_SUPPORT) + if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) + return 0; + whole_strip = tif->tif_dir.td_stripbytecount[strip] < 10 + || isMapped(tif); +#else + whole_strip = 1; +#endif + + if( !whole_strip ) + { + read_ahead = tif->tif_scanlinesize * 16 + 5000; + } + + /* + * If we haven't loaded this strip, do so now, possibly + * only reading the first part. + */ if (strip != tif->tif_curstrip) { /* different strip, refill */ - if (!TIFFFillStrip(tif, strip)) - return (0); - } else if (row < tif->tif_row) { + + if( whole_strip ) + { + if (!TIFFFillStrip(tif, strip)) + return (0); + } + else + { + if( !TIFFFillStripPartial(tif,strip,read_ahead,1) ) + return 0; + } + } + + /* + ** If we already have some data loaded, do we need to read some more? + */ + else if( !whole_strip ) + { + if( ((tif->tif_rawdata + tif->tif_rawdataloaded) - tif->tif_rawcp) < read_ahead + && (uint64) tif->tif_rawdataoff+tif->tif_rawdataloaded < td->td_stripbytecount[strip] ) + { + if( !TIFFFillStripPartial(tif,strip,read_ahead,0) ) + return 0; + } + } + + if (row < tif->tif_row) { /* * Moving backwards within the same strip: backup * to the start and then decode forward (below). @@ -78,22 +257,36 @@ TIFFSeek(TIFF* tif, uint32 row, tsample_t sample) * strip, it's better to just read and decode the entire * strip, and then access the decoded data in a random fashion. */ - if (!TIFFStartStrip(tif, strip)) - return (0); + + if( tif->tif_rawdataoff != 0 ) + { + if( !TIFFFillStripPartial(tif,strip,read_ahead,1) ) + return 0; + } + else + { + if (!TIFFStartStrip(tif, strip)) + return (0); + } } + if (row != tif->tif_row) { /* * Seek forward to the desired row. */ + + /* TODO: Will this really work with partial buffers? */ + if (!(*tif->tif_seek)(tif, row - tif->tif_row)) return (0); tif->tif_row = row; } + return (1); } int -TIFFReadScanline(TIFF* tif, tdata_t buf, uint32 row, tsample_t sample) +TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample) { int e; @@ -104,14 +297,14 @@ TIFFReadScanline(TIFF* tif, tdata_t buf, uint32 row, tsample_t sample) * Decompress desired row into user buffer. */ e = (*tif->tif_decoderow) - (tif, (tidata_t) buf, tif->tif_scanlinesize, sample); + (tif, (uint8*) buf, tif->tif_scanlinesize, sample); /* we are now poised at the beginning of the next row */ tif->tif_row = row + 1; if (e) - (*tif->tif_postdecode)(tif, (tidata_t) buf, - tif->tif_scanlinesize); + (*tif->tif_postdecode)(tif, (uint8*) buf, + tif->tif_scanlinesize); } return (e > 0 ? 1 : -1); } @@ -120,93 +313,120 @@ TIFFReadScanline(TIFF* tif, tdata_t buf, uint32 row, tsample_t sample) * Read a strip of data and decompress the specified * amount into the user-supplied buffer. */ -tsize_t -TIFFReadEncodedStrip(TIFF* tif, tstrip_t strip, tdata_t buf, tsize_t size) +tmsize_t +TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size) { + static const char module[] = "TIFFReadEncodedStrip"; TIFFDirectory *td = &tif->tif_dir; - uint32 nrows; - tsize_t stripsize; - tstrip_t sep_strip, strips_per_sep; - - if (!TIFFCheckRead(tif, 0)) - return (-1); - if (strip >= td->td_nstrips) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "%ld: Strip out of range, max %ld", - (long) strip, (long) td->td_nstrips); - return (-1); + uint32 rowsperstrip; + uint32 stripsperplane; + uint32 stripinplane; + uint16 plane; + uint32 rows; + tmsize_t stripsize; + if (!TIFFCheckRead(tif,0)) + return((tmsize_t)(-1)); + if (strip>=td->td_nstrips) + { + TIFFErrorExt(tif->tif_clientdata,module, + "%lu: Strip out of range, max %lu",(unsigned long)strip, + (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). */ - if( td->td_rowsperstrip >= td->td_imagelength ) - strips_per_sep = 1; - else - strips_per_sep = (td->td_imagelength+td->td_rowsperstrip-1) - / td->td_rowsperstrip; - - sep_strip = strip % strips_per_sep; - - if (sep_strip != strips_per_sep-1 || - (nrows = td->td_imagelength % td->td_rowsperstrip) == 0) - nrows = td->td_rowsperstrip; - - stripsize = TIFFVStripSize(tif, nrows); - if (size == (tsize_t) -1) - size = stripsize; - else if (size > stripsize) - size = stripsize; - if (TIFFFillStrip(tif, strip) - && (*tif->tif_decodestrip)(tif, (tidata_t) buf, size, - (tsample_t)(strip / td->td_stripsperimage)) > 0 ) { - (*tif->tif_postdecode)(tif, (tidata_t) buf, size); - return (size); - } else - return ((tsize_t) -1); + rowsperstrip=td->td_rowsperstrip; + if (rowsperstrip>td->td_imagelength) + rowsperstrip=td->td_imagelength; + stripsperplane=((td->td_imagelength+rowsperstrip-1)/rowsperstrip); + stripinplane=(strip%stripsperplane); + plane=(strip/stripsperplane); + rows=td->td_imagelength-stripinplane*rowsperstrip; + if (rows>rowsperstrip) + rows=rowsperstrip; + stripsize=TIFFVStripSize(tif,rows); + if (stripsize==0) + return((tmsize_t)(-1)); + if ((size!=(tmsize_t)(-1))&&(sizetif_decodestrip)(tif,buf,stripsize,plane)<=0) + return((tmsize_t)(-1)); + (*tif->tif_postdecode)(tif,buf,stripsize); + return(stripsize); } -static tsize_t -TIFFReadRawStrip1(TIFF* tif, - tstrip_t strip, tdata_t buf, tsize_t size, const char* module) +static tmsize_t +TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size, + const char* module) { TIFFDirectory *td = &tif->tif_dir; + if (!_TIFFFillStriles( tif )) + return ((tmsize_t)(-1)); + assert((tif->tif_flags&TIFF_NOREADRAW)==0); if (!isMapped(tif)) { - tsize_t cc; + tmsize_t cc; if (!SeekOK(tif, td->td_stripoffset[strip])) { TIFFErrorExt(tif->tif_clientdata, module, - "%s: Seek error at scanline %lu, strip %lu", - tif->tif_name, + "Seek error at scanline %lu, strip %lu", (unsigned long) tif->tif_row, (unsigned long) strip); - return (-1); + return ((tmsize_t)(-1)); } cc = TIFFReadFile(tif, buf, size); if (cc != size) { +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) TIFFErrorExt(tif->tif_clientdata, module, - "%s: Read error at scanline %lu; got %lu bytes, expected %lu", - tif->tif_name, - (unsigned long) tif->tif_row, - (unsigned long) cc, - (unsigned long) size); - return (-1); + "Read error at scanline %lu; got %I64u bytes, expected %I64u", + (unsigned long) tif->tif_row, + (unsigned __int64) cc, + (unsigned __int64) size); +#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) size); +#endif + return ((tmsize_t)(-1)); } } else { - if (td->td_stripoffset[strip] + size > tif->tif_size) { + tmsize_t ma,mb; + tmsize_t n; + ma=(tmsize_t)td->td_stripoffset[strip]; + mb=ma+size; + if (((uint64)ma!=td->td_stripoffset[strip])||(ma>tif->tif_size)) + n=0; + else if ((mbtif->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, - "%s: Read error at scanline %lu, strip %lu; got %lu bytes, expected %lu", - tif->tif_name, - (unsigned long) tif->tif_row, - (unsigned long) strip, - (unsigned long) tif->tif_size - td->td_stripoffset[strip], - (unsigned long) size); - return (-1); + "Read error at scanline %lu, strip %lu; got %I64u bytes, expected %I64u", + (unsigned long) tif->tif_row, + (unsigned long) strip, + (unsigned __int64) n, + (unsigned __int64) size); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "Read error at scanline %lu, strip %lu; got %llu bytes, expected %llu", + (unsigned long) tif->tif_row, + (unsigned long) strip, + (unsigned long long) n, + (unsigned long long) size); +#endif + return ((tmsize_t)(-1)); } - _TIFFmemcpy(buf, tif->tif_base + td->td_stripoffset[strip], - size); + _TIFFmemcpy(buf, tif->tif_base + ma, + size); } return (size); } @@ -214,44 +434,52 @@ TIFFReadRawStrip1(TIFF* tif, /* * Read a strip of data from the file. */ -tsize_t -TIFFReadRawStrip(TIFF* tif, tstrip_t strip, tdata_t buf, tsize_t size) +tmsize_t +TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size) { static const char module[] = "TIFFReadRawStrip"; TIFFDirectory *td = &tif->tif_dir; - /* - * FIXME: butecount should have tsize_t type, but for now libtiff - * defines tsize_t as a signed 32-bit integer and we are losing - * ability to read arrays larger than 2^31 bytes. So we are using - * uint32 instead of tsize_t here. - */ - uint32 bytecount; + uint64 bytecount; + tmsize_t bytecountm; if (!TIFFCheckRead(tif, 0)) - return ((tsize_t) -1); + return ((tmsize_t)(-1)); if (strip >= td->td_nstrips) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "%lu: Strip out of range, max %lu", - (unsigned long) strip, - (unsigned long) td->td_nstrips); - return ((tsize_t) -1); + TIFFErrorExt(tif->tif_clientdata, module, + "%lu: Strip out of range, max %lu", + (unsigned long) strip, + (unsigned long) td->td_nstrips); + return ((tmsize_t)(-1)); } if (tif->tif_flags&TIFF_NOREADRAW) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Compression scheme does not support access to raw uncompressed data"); - return ((tsize_t) -1); + TIFFErrorExt(tif->tif_clientdata, module, + "Compression scheme does not support access to raw uncompressed data"); + return ((tmsize_t)(-1)); } bytecount = td->td_stripbytecount[strip]; - if (bytecount <= 0) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "%lu: Invalid strip byte count, strip %lu", - (unsigned long) bytecount, (unsigned long) strip); - return ((tsize_t) -1); + if ((int64)bytecount <= 0) { +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, + "%I64u: Invalid strip byte count, strip %lu", + (unsigned __int64) bytecount, + (unsigned long) strip); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "%llu: Invalid strip byte count, strip %lu", + (unsigned long long) bytecount, + (unsigned long) strip); +#endif + return ((tmsize_t)(-1)); } - if (size != (tsize_t)-1 && (uint32)size < bytecount) - bytecount = size; - return (TIFFReadRawStrip1(tif, strip, buf, bytecount, module)); + bytecountm = (tmsize_t)bytecount; + if ((uint64)bytecountm!=bytecount) { + TIFFErrorExt(tif->tif_clientdata, module, "Integer overflow"); + return ((tmsize_t)(-1)); + } + if (size != (tmsize_t)(-1) && size < bytecountm) + bytecountm = size; + return (TIFFReadRawStrip1(tif, strip, buf, bytecountm, module)); } /* @@ -259,25 +487,29 @@ TIFFReadRawStrip(TIFF* tif, tstrip_t strip, tdata_t buf, tsize_t size) * expanded, as necessary, to hold the strip's data. */ int -TIFFFillStrip(TIFF* tif, tstrip_t strip) +TIFFFillStrip(TIFF* tif, uint32 strip) { static const char module[] = "TIFFFillStrip"; TIFFDirectory *td = &tif->tif_dir; + if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) + return 0; + if ((tif->tif_flags&TIFF_NOREADRAW)==0) { - /* - * FIXME: butecount should have tsize_t type, but for now - * libtiff defines tsize_t as a signed 32-bit integer and we - * are losing ability to read arrays larger than 2^31 bytes. - * So we are using uint32 instead of tsize_t here. - */ - uint32 bytecount = td->td_stripbytecount[strip]; - if (bytecount <= 0) { + uint64 bytecount = td->td_stripbytecount[strip]; + if ((int64)bytecount <= 0) { +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) TIFFErrorExt(tif->tif_clientdata, module, - "%s: Invalid strip byte count %lu, strip %lu", - tif->tif_name, (unsigned long) bytecount, - (unsigned long) strip); + "Invalid strip byte count %I64u, strip %lu", + (unsigned __int64) bytecount, + (unsigned long) strip); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "Invalid strip byte count %llu, strip %lu", + (unsigned long long) bytecount, + (unsigned long) strip); +#endif return (0); } if (isMapped(tif) && @@ -294,8 +526,11 @@ TIFFFillStrip(TIFF* tif, tstrip_t strip) * 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) + 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; /* * We must check for overflow, potentially causing @@ -306,53 +541,85 @@ TIFFFillStrip(TIFF* tif, tstrip_t strip) * comparison (which can overflow) we do the following * two comparisons: */ - if (bytecount > tif->tif_size || - td->td_stripoffset[strip] > tif->tif_size - bytecount) { + if (bytecount > (uint64)tif->tif_size || + td->td_stripoffset[strip] > (uint64)tif->tif_size - bytecount) { /* * This error message might seem strange, but * it's what would happen if a read were done * instead. */ +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) TIFFErrorExt(tif->tif_clientdata, module, - "%s: Read error on strip %lu; " - "got %lu bytes, expected %lu", - tif->tif_name, (unsigned long) strip, - (unsigned long) tif->tif_size - td->td_stripoffset[strip], - (unsigned long) bytecount); + "Read error on strip %lu; " + "got %I64u bytes, expected %I64u", + (unsigned long) strip, + (unsigned __int64) tif->tif_size - td->td_stripoffset[strip], + (unsigned __int64) bytecount); +#else + TIFFErrorExt(tif->tif_clientdata, module, + + "Read error on strip %lu; " + "got %llu bytes, expected %llu", + (unsigned long) strip, + (unsigned long long) tif->tif_size - td->td_stripoffset[strip], + (unsigned long long) bytecount); +#endif tif->tif_curstrip = NOSTRIP; return (0); } - tif->tif_rawdatasize = bytecount; - tif->tif_rawdata = tif->tif_base + td->td_stripoffset[strip]; + tif->tif_rawdatasize = (tmsize_t)bytecount; + tif->tif_rawdata = tif->tif_base + (tmsize_t)td->td_stripoffset[strip]; + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = (tmsize_t) bytecount; + + /* + * When we have tif_rawdata reference directly into the memory mapped file + * we need to be pretty careful about how we use the rawdata. It is not + * a general purpose working buffer as it normally otherwise is. So we + * keep track of this fact to avoid using it improperly. + */ + tif->tif_flags |= TIFF_BUFFERMMAP; } else { /* * Expand raw data buffer, if needed, to hold data * strip coming from file (perhaps should set upper * bound on the size of a buffer we'll use?). */ - if (bytecount > (uint32)tif->tif_rawdatasize) { + tmsize_t bytecountm; + bytecountm=(tmsize_t)bytecount; + if ((uint64)bytecountm!=bytecount) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); + return(0); + } + if (bytecountm > tif->tif_rawdatasize) { tif->tif_curstrip = NOSTRIP; if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { - TIFFErrorExt(tif->tif_clientdata, - module, - "%s: Data buffer too small to hold strip %lu", - tif->tif_name, - (unsigned long) strip); + TIFFErrorExt(tif->tif_clientdata, module, + "Data buffer too small to hold strip %lu", + (unsigned long) strip); return (0); } - if (!TIFFReadBufferSetup(tif, 0, - TIFFroundup(bytecount, 1024))) + if (!TIFFReadBufferSetup(tif, 0, bytecountm)) return (0); } - if ((uint32)TIFFReadRawStrip1(tif, strip, - (unsigned char *)tif->tif_rawdata, - bytecount, module) != bytecount) + if (tif->tif_flags&TIFF_BUFFERMMAP) { + tif->tif_curstrip = NOSTRIP; + if (!TIFFReadBufferSetup(tif, 0, bytecountm)) + return (0); + } + if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata, + bytecountm, module) != bytecountm) return (0); + + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = bytecountm; + if (!isFillOrder(tif, td->td_fillorder) && (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits(tif->tif_rawdata, bytecount); - } + TIFFReverseBits(tif->tif_rawdata, bytecountm); + } } return (TIFFStartStrip(tif, strip)); } @@ -366,89 +633,117 @@ TIFFFillStrip(TIFF* tif, tstrip_t strip) * Read and decompress a tile of data. The * tile is selected by the (x,y,z,s) coordinates. */ -tsize_t -TIFFReadTile(TIFF* tif, - tdata_t buf, uint32 x, uint32 y, uint32 z, tsample_t s) +tmsize_t +TIFFReadTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s) { if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s)) - return (-1); + return ((tmsize_t)(-1)); return (TIFFReadEncodedTile(tif, - TIFFComputeTile(tif, x, y, z, s), buf, (tsize_t) -1)); + TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1))); } /* * Read a tile of data and decompress the specified * amount into the user-supplied buffer. */ -tsize_t -TIFFReadEncodedTile(TIFF* tif, ttile_t tile, tdata_t buf, tsize_t size) +tmsize_t +TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size) { + static const char module[] = "TIFFReadEncodedTile"; TIFFDirectory *td = &tif->tif_dir; - tsize_t tilesize = tif->tif_tilesize; + tmsize_t tilesize = tif->tif_tilesize; if (!TIFFCheckRead(tif, 1)) - return (-1); + return ((tmsize_t)(-1)); if (tile >= td->td_nstrips) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "%ld: Tile out of range, max %ld", - (long) tile, (unsigned long) td->td_nstrips); - return (-1); + 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 (size == (tsize_t) -1) + if (size == (tmsize_t)(-1)) size = tilesize; else if (size > tilesize) size = tilesize; if (TIFFFillTile(tif, tile) && (*tif->tif_decodetile)(tif, - (tidata_t) buf, size, (tsample_t)(tile/td->td_stripsperimage))) { - (*tif->tif_postdecode)(tif, (tidata_t) buf, size); + (uint8*) buf, size, (uint16)(tile/td->td_stripsperimage))) { + (*tif->tif_postdecode)(tif, (uint8*) buf, size); return (size); } else - return (-1); + return ((tmsize_t)(-1)); } -static tsize_t -TIFFReadRawTile1(TIFF* tif, - ttile_t tile, tdata_t buf, tsize_t size, const char* module) +static tmsize_t +TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* module) { TIFFDirectory *td = &tif->tif_dir; + if (!_TIFFFillStriles( tif )) + return ((tmsize_t)(-1)); + assert((tif->tif_flags&TIFF_NOREADRAW)==0); if (!isMapped(tif)) { - tsize_t cc; + tmsize_t cc; if (!SeekOK(tif, td->td_stripoffset[tile])) { TIFFErrorExt(tif->tif_clientdata, module, - "%s: Seek error at row %ld, col %ld, tile %ld", - tif->tif_name, - (long) tif->tif_row, - (long) tif->tif_col, - (long) tile); - return ((tsize_t) -1); + "Seek error at row %lu, col %lu, tile %lu", + (unsigned long) tif->tif_row, + (unsigned long) tif->tif_col, + (unsigned long) tile); + return ((tmsize_t)(-1)); } cc = TIFFReadFile(tif, buf, size); if (cc != size) { +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) TIFFErrorExt(tif->tif_clientdata, module, - "%s: Read error at row %ld, col %ld; got %lu bytes, expected %lu", - tif->tif_name, - (long) tif->tif_row, - (long) tif->tif_col, - (unsigned long) cc, - (unsigned long) size); - return ((tsize_t) -1); + "Read error at row %lu, col %lu; got %I64u bytes, expected %I64u", + (unsigned long) tif->tif_row, + (unsigned long) tif->tif_col, + (unsigned __int64) cc, + (unsigned __int64) size); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "Read error at row %lu, col %lu; got %llu bytes, expected %llu", + (unsigned long) tif->tif_row, + (unsigned long) tif->tif_col, + (unsigned long long) cc, + (unsigned long long) size); +#endif + return ((tmsize_t)(-1)); } } else { - if (td->td_stripoffset[tile] + size > tif->tif_size) { + tmsize_t ma,mb; + tmsize_t n; + ma=(tmsize_t)td->td_stripoffset[tile]; + mb=ma+size; + if (((uint64)ma!=td->td_stripoffset[tile])||(ma>tif->tif_size)) + n=0; + else if ((mbtif->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, - "%s: Read error at row %ld, col %ld, tile %ld; got %lu bytes, expected %lu", - tif->tif_name, - (long) tif->tif_row, - (long) tif->tif_col, - (long) tile, - (unsigned long) tif->tif_size - td->td_stripoffset[tile], - (unsigned long) size); - return ((tsize_t) -1); +"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) tile, + (unsigned __int64) n, + (unsigned __int64) 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) tile, + (unsigned long long) n, + (unsigned long long) size); +#endif + return ((tmsize_t)(-1)); } - _TIFFmemcpy(buf, tif->tif_base + td->td_stripoffset[tile], size); + _TIFFmemcpy(buf, tif->tif_base + ma, size); } return (size); } @@ -456,37 +751,38 @@ TIFFReadRawTile1(TIFF* tif, /* * Read a tile of data from the file. */ -tsize_t -TIFFReadRawTile(TIFF* tif, ttile_t tile, tdata_t buf, tsize_t size) +tmsize_t +TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size) { static const char module[] = "TIFFReadRawTile"; TIFFDirectory *td = &tif->tif_dir; - /* - * FIXME: butecount should have tsize_t type, but for now libtiff - * defines tsize_t as a signed 32-bit integer and we are losing - * ability to read arrays larger than 2^31 bytes. So we are using - * uint32 instead of tsize_t here. - */ - uint32 bytecount; + uint64 bytecount64; + tmsize_t bytecountm; if (!TIFFCheckRead(tif, 1)) - return ((tsize_t) -1); + return ((tmsize_t)(-1)); if (tile >= td->td_nstrips) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "%lu: Tile out of range, max %lu", + TIFFErrorExt(tif->tif_clientdata, module, + "%lu: Tile out of range, max %lu", (unsigned long) tile, (unsigned long) td->td_nstrips); - return ((tsize_t) -1); + return ((tmsize_t)(-1)); } if (tif->tif_flags&TIFF_NOREADRAW) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Compression scheme does not support access to raw uncompressed data"); - return ((tsize_t) -1); + TIFFErrorExt(tif->tif_clientdata, module, + "Compression scheme does not support access to raw uncompressed data"); + return ((tmsize_t)(-1)); } - bytecount = td->td_stripbytecount[tile]; - if (size != (tsize_t) -1 && (uint32)size < bytecount) - bytecount = size; - return (TIFFReadRawTile1(tif, tile, buf, bytecount, module)); + bytecount64 = td->td_stripbytecount[tile]; + if (size != (tmsize_t)(-1) && (uint64)size < bytecount64) + bytecount64 = (uint64)size; + bytecountm = (tmsize_t)bytecount64; + if ((uint64)bytecountm!=bytecount64) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); + return ((tmsize_t)(-1)); + } + return (TIFFReadRawTile1(tif, tile, buf, bytecountm, module)); } /* @@ -494,24 +790,29 @@ TIFFReadRawTile(TIFF* tif, ttile_t tile, tdata_t buf, tsize_t size) * expanded, as necessary, to hold the tile's data. */ int -TIFFFillTile(TIFF* tif, ttile_t tile) +TIFFFillTile(TIFF* tif, uint32 tile) { static const char module[] = "TIFFFillTile"; TIFFDirectory *td = &tif->tif_dir; + if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) + return 0; + if ((tif->tif_flags&TIFF_NOREADRAW)==0) { - /* - * FIXME: butecount should have tsize_t type, but for now - * libtiff defines tsize_t as a signed 32-bit integer and we - * are losing ability to read arrays larger than 2^31 bytes. - * So we are using uint32 instead of tsize_t here. - */ - uint32 bytecount = td->td_stripbytecount[tile]; - if (bytecount <= 0) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "%lu: Invalid tile byte count, tile %lu", - (unsigned long) bytecount, (unsigned long) tile); + uint64 bytecount = td->td_stripbytecount[tile]; + if ((int64)bytecount <= 0) { +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, + "%I64u: Invalid tile byte count, tile %lu", + (unsigned __int64) bytecount, + (unsigned long) tile); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "%llu: Invalid tile byte count, tile %lu", + (unsigned long long) bytecount, + (unsigned long) tile); +#endif return (0); } if (isMapped(tif) && @@ -528,8 +829,11 @@ TIFFFillTile(TIFF* tif, ttile_t tile) * 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) + 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; /* * We must check for overflow, potentially causing @@ -540,41 +844,58 @@ TIFFFillTile(TIFF* tif, ttile_t tile) * comparison (which can overflow) we do the following * two comparisons: */ - if (bytecount > tif->tif_size || - td->td_stripoffset[tile] > tif->tif_size - bytecount) { + if (bytecount > (uint64)tif->tif_size || + td->td_stripoffset[tile] > (uint64)tif->tif_size - bytecount) { tif->tif_curtile = NOTILE; return (0); } - tif->tif_rawdatasize = bytecount; + tif->tif_rawdatasize = (tmsize_t)bytecount; tif->tif_rawdata = - tif->tif_base + td->td_stripoffset[tile]; + tif->tif_base + (tmsize_t)td->td_stripoffset[tile]; + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = (tmsize_t) bytecount; + tif->tif_flags |= TIFF_BUFFERMMAP; } else { /* * Expand raw data buffer, if needed, to hold data * tile coming from file (perhaps should set upper * bound on the size of a buffer we'll use?). */ - if (bytecount > (uint32)tif->tif_rawdatasize) { + tmsize_t bytecountm; + bytecountm=(tmsize_t)bytecount; + if ((uint64)bytecountm!=bytecount) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); + return(0); + } + if (bytecountm > tif->tif_rawdatasize) { tif->tif_curtile = NOTILE; if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { - TIFFErrorExt(tif->tif_clientdata, - module, - "%s: Data buffer too small to hold tile %ld", - tif->tif_name, - (long) tile); + TIFFErrorExt(tif->tif_clientdata, module, + "Data buffer too small to hold tile %lu", + (unsigned long) tile); return (0); } - if (!TIFFReadBufferSetup(tif, 0, - TIFFroundup(bytecount, 1024))) + if (!TIFFReadBufferSetup(tif, 0, bytecountm)) return (0); } - if ((uint32)TIFFReadRawTile1(tif, tile, - (unsigned char *)tif->tif_rawdata, - bytecount, module) != bytecount) + if (tif->tif_flags&TIFF_BUFFERMMAP) { + tif->tif_curtile = NOTILE; + if (!TIFFReadBufferSetup(tif, 0, bytecountm)) + return (0); + } + + if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata, + bytecountm, module) != bytecountm) return (0); + + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = bytecountm; + if (!isFillOrder(tif, td->td_fillorder) && (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits(tif->tif_rawdata, bytecount); + TIFFReverseBits(tif->tif_rawdata, + tif->tif_rawdataloaded); } } return (TIFFStartTile(tif, tile)); @@ -590,31 +911,37 @@ TIFFFillTile(TIFF* tif, ttile_t tile) * raw data. */ int -TIFFReadBufferSetup(TIFF* tif, tdata_t bp, tsize_t size) +TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size) { static const char module[] = "TIFFReadBufferSetup"; assert((tif->tif_flags&TIFF_NOREADRAW)==0); + tif->tif_flags &= ~TIFF_BUFFERMMAP; + if (tif->tif_rawdata) { if (tif->tif_flags & TIFF_MYBUFFER) _TIFFfree(tif->tif_rawdata); tif->tif_rawdata = NULL; + tif->tif_rawdatasize = 0; } - if (bp) { tif->tif_rawdatasize = size; - tif->tif_rawdata = (tidata_t) bp; + tif->tif_rawdata = (uint8*) bp; tif->tif_flags &= ~TIFF_MYBUFFER; } else { - tif->tif_rawdatasize = TIFFroundup(size, 1024); - if (tif->tif_rawdatasize > 0) - tif->tif_rawdata = (tidata_t) _TIFFmalloc(tif->tif_rawdatasize); + tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64((uint64)size, 1024); + if (tif->tif_rawdatasize==0) { + TIFFErrorExt(tif->tif_clientdata, module, + "Invalid buffer size"); + return (0); + } + tif->tif_rawdata = (uint8*) _TIFFmalloc(tif->tif_rawdatasize); tif->tif_flags |= TIFF_MYBUFFER; } - if ((tif->tif_rawdata == NULL) || (tif->tif_rawdatasize == 0)) { + if (tif->tif_rawdata == NULL) { TIFFErrorExt(tif->tif_clientdata, module, - "%s: No space for data buffer at scanline %ld", - tif->tif_name, (long) tif->tif_row); + "No space for data buffer at scanline %lu", + (unsigned long) tif->tif_row); tif->tif_rawdatasize = 0; return (0); } @@ -626,10 +953,13 @@ TIFFReadBufferSetup(TIFF* tif, tdata_t bp, tsize_t size) * strip has just been read in. */ static int -TIFFStartStrip(TIFF* tif, tstrip_t strip) +TIFFStartStrip(TIFF* tif, uint32 strip) { TIFFDirectory *td = &tif->tif_dir; + if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) + return 0; + if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { if (!(*tif->tif_setupdecode)(tif)) return (0); @@ -637,18 +967,20 @@ TIFFStartStrip(TIFF* tif, tstrip_t strip) } tif->tif_curstrip = strip; tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; + tif->tif_flags &= ~TIFF_BUF4WRITE; + if (tif->tif_flags&TIFF_NOREADRAW) { tif->tif_rawcp = NULL; - tif->tif_rawcc = 0; + tif->tif_rawcc = 0; } else { tif->tif_rawcp = tif->tif_rawdata; - tif->tif_rawcc = td->td_stripbytecount[strip]; + tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[strip]; } return ((*tif->tif_predecode)(tif, - (tsample_t)(strip / td->td_stripsperimage))); + (uint16)(strip / td->td_stripsperimage))); } /* @@ -656,9 +988,14 @@ TIFFStartStrip(TIFF* tif, tstrip_t strip) * tile has just been read in. */ static int -TIFFStartTile(TIFF* tif, ttile_t tile) +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; if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { if (!(*tif->tif_setupdecode)(tif)) @@ -666,12 +1003,19 @@ TIFFStartTile(TIFF* tif, ttile_t tile) tif->tif_flags |= TIFF_CODERSETUP; } tif->tif_curtile = tile; - tif->tif_row = - (tile % TIFFhowmany(td->td_imagewidth, td->td_tilewidth)) * - td->td_tilelength; - tif->tif_col = - (tile % TIFFhowmany(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) { tif->tif_rawcp = NULL; @@ -680,10 +1024,10 @@ TIFFStartTile(TIFF* tif, ttile_t tile) else { tif->tif_rawcp = tif->tif_rawdata; - tif->tif_rawcc = td->td_stripbytecount[tile]; + tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[tile]; } return ((*tif->tif_predecode)(tif, - (tsample_t)(tile/td->td_stripsperimage))); + (uint16)(tile/td->td_stripsperimage))); } static int @@ -703,13 +1047,13 @@ TIFFCheckRead(TIFF* tif, int tiles) } void -_TIFFNoPostDecode(TIFF* tif, tidata_t buf, tsize_t cc) +_TIFFNoPostDecode(TIFF* tif, uint8* buf, tmsize_t cc) { (void) tif; (void) buf; (void) cc; } void -_TIFFSwab16BitData(TIFF* tif, tidata_t buf, tsize_t cc) +_TIFFSwab16BitData(TIFF* tif, uint8* buf, tmsize_t cc) { (void) tif; assert((cc & 1) == 0); @@ -717,7 +1061,7 @@ _TIFFSwab16BitData(TIFF* tif, tidata_t buf, tsize_t cc) } void -_TIFFSwab24BitData(TIFF* tif, tidata_t buf, tsize_t cc) +_TIFFSwab24BitData(TIFF* tif, uint8* buf, tmsize_t cc) { (void) tif; assert((cc % 3) == 0); @@ -725,7 +1069,7 @@ _TIFFSwab24BitData(TIFF* tif, tidata_t buf, tsize_t cc) } void -_TIFFSwab32BitData(TIFF* tif, tidata_t buf, tsize_t cc) +_TIFFSwab32BitData(TIFF* tif, uint8* buf, tmsize_t cc) { (void) tif; assert((cc & 3) == 0); @@ -733,7 +1077,7 @@ _TIFFSwab32BitData(TIFF* tif, tidata_t buf, tsize_t cc) } void -_TIFFSwab64BitData(TIFF* tif, tidata_t buf, tsize_t cc) +_TIFFSwab64BitData(TIFF* tif, uint8* buf, tmsize_t cc) { (void) tif; assert((cc & 7) == 0); diff --git a/thirdparty/libtiff/tif_stream.cxx b/thirdparty/libtiff/tif_stream.cxx index 2a2351b2..ecca1fd5 100644 --- a/thirdparty/libtiff/tif_stream.cxx +++ b/thirdparty/libtiff/tif_stream.cxx @@ -1,4 +1,4 @@ -/* $Id: tif_stream.cxx,v 1.6.2.1 2009-01-01 00:10:43 bfriesen Exp $ */ +/* $Id: tif_stream.cxx,v 1.13 2015-05-28 01:50:22 bfriesen Exp $ */ /* * Copyright (c) 1988-1996 Sam Leffler @@ -34,76 +34,166 @@ using namespace std; #endif -class tiffis_data -{ - public: +/* + ISO C++ uses a 'std::streamsize' type to define counts. This makes + it similar to, (but perhaps not the same as) size_t. - istream *myIS; - long myStreamStartPos; + The std::ios::pos_type is used to represent stream positions as used + by tellg(), tellp(), seekg(), and seekp(). This makes it similar to + (but perhaps not the same as) 'off_t'. The std::ios::streampos type + is used for character streams, but is documented to not be an + integral type anymore, so it should *not* be assigned to an integral + type. + + The std::ios::off_type is used to specify relative offsets needed by + the variants of seekg() and seekp() which accept a relative offset + argument. + + Useful prototype knowledge: + + Obtain read position + ios::pos_type basic_istream::tellg() + + Set read position + basic_istream& basic_istream::seekg(ios::pos_type) + basic_istream& basic_istream::seekg(ios::off_type, ios_base::seekdir) + + Read data + basic_istream& istream::read(char *str, streamsize count) + + Number of characters read in last unformatted read + streamsize istream::gcount(); + + Obtain write position + ios::pos_type basic_ostream::tellp() + + Set write position + basic_ostream& basic_ostream::seekp(ios::pos_type) + basic_ostream& basic_ostream::seekp(ios::off_type, ios_base::seekdir) + + Write data + basic_ostream& ostream::write(const char *str, streamsize count) +*/ + +struct tiffis_data; +struct tiffos_data; + +extern "C" { + + static tmsize_t _tiffosReadProc(thandle_t, void*, tmsize_t); + static tmsize_t _tiffisReadProc(thandle_t fd, void* buf, tmsize_t size); + static tmsize_t _tiffosWriteProc(thandle_t fd, void* buf, tmsize_t size); + static tmsize_t _tiffisWriteProc(thandle_t, void*, tmsize_t); + static uint64 _tiffosSeekProc(thandle_t fd, uint64 off, int whence); + static uint64 _tiffisSeekProc(thandle_t fd, uint64 off, int whence); + static uint64 _tiffosSizeProc(thandle_t fd); + static uint64 _tiffisSizeProc(thandle_t fd); + static int _tiffosCloseProc(thandle_t fd); + static int _tiffisCloseProc(thandle_t fd); + static int _tiffDummyMapProc(thandle_t , void** base, toff_t* size ); + static void _tiffDummyUnmapProc(thandle_t , void* base, toff_t size ); + static TIFF* _tiffStreamOpen(const char* name, const char* mode, void *fd); + +struct tiffis_data +{ + istream *stream; + ios::pos_type start_pos; }; -class tiffos_data +struct tiffos_data { - public: - - ostream *myOS; - long myStreamStartPos; + ostream *stream; + ios::pos_type start_pos; }; -static tsize_t -_tiffosReadProc(thandle_t, tdata_t, tsize_t) +static tmsize_t +_tiffosReadProc(thandle_t, void*, tmsize_t) { return 0; } -static tsize_t -_tiffisReadProc(thandle_t fd, tdata_t buf, tsize_t size) +static tmsize_t +_tiffisReadProc(thandle_t fd, void* buf, tmsize_t size) { - tiffis_data *data = (tiffis_data *)fd; + tiffis_data *data = reinterpret_cast(fd); - data->myIS->read((char *)buf, (int)size); + // Verify that type does not overflow. + streamsize request_size = size; + if (static_cast(request_size) != size) + return static_cast(-1); - return data->myIS->gcount(); + data->stream->read((char *) buf, request_size); + + return static_cast(data->stream->gcount()); } -static tsize_t -_tiffosWriteProc(thandle_t fd, tdata_t buf, tsize_t size) +static tmsize_t +_tiffosWriteProc(thandle_t fd, void* buf, tmsize_t size) { - tiffos_data *data = (tiffos_data *)fd; - ostream *os = data->myOS; - int pos = os->tellp(); + tiffos_data *data = reinterpret_cast(fd); + ostream *os = data->stream; + ios::pos_type pos = os->tellp(); - os->write((const char *)buf, size); + // Verify that type does not overflow. + streamsize request_size = size; + if (static_cast(request_size) != size) + return static_cast(-1); - return ((int)os->tellp()) - pos; + os->write(reinterpret_cast(buf), request_size); + + return static_cast(os->tellp() - pos); } -static tsize_t -_tiffisWriteProc(thandle_t, tdata_t, tsize_t) +static tmsize_t +_tiffisWriteProc(thandle_t, void*, tmsize_t) { return 0; } -static toff_t -_tiffosSeekProc(thandle_t fd, toff_t off, int whence) +static uint64 +_tiffosSeekProc(thandle_t fd, uint64 off, int whence) { - tiffos_data *data = (tiffos_data *)fd; - ostream *os = data->myOS; + tiffos_data *data = reinterpret_cast(fd); + ostream *os = data->stream; // if the stream has already failed, don't do anything if( os->fail() ) - return os->tellp(); + return static_cast(-1); switch(whence) { case SEEK_SET: - os->seekp(data->myStreamStartPos + off, ios::beg); + { + // Compute 64-bit offset + uint64 new_offset = static_cast(data->start_pos) + off; + + // Verify that value does not overflow + ios::off_type offset = static_cast(new_offset); + if (static_cast(offset) != new_offset) + return static_cast(-1); + + os->seekp(offset, ios::beg); break; + } case SEEK_CUR: - os->seekp(off, ios::cur); - break; + { + // Verify that value does not overflow + ios::off_type offset = static_cast(off); + if (static_cast(offset) != off) + return static_cast(-1); + + os->seekp(offset, ios::cur); + break; + } case SEEK_END: - os->seekp(off, ios::end); - break; + { + // Verify that value does not overflow + ios::off_type offset = static_cast(off); + if (static_cast(offset) != off) + return static_cast(-1); + + os->seekp(offset, ios::end); + break; + } } // Attempt to workaround problems with seeking past the end of the @@ -116,14 +206,15 @@ _tiffosSeekProc(thandle_t fd, toff_t off, int whence) #else ios::iostate old_state; #endif - toff_t origin=0; + ios::pos_type origin; old_state = os->rdstate(); // reset the fail bit or else tellp() won't work below os->clear(os->rdstate() & ~ios::failbit); switch( whence ) { case SEEK_SET: - origin = data->myStreamStartPos; + default: + origin = data->start_pos; break; case SEEK_CUR: origin = os->tellp(); @@ -137,80 +228,104 @@ _tiffosSeekProc(thandle_t fd, toff_t off, int whence) os->clear(old_state); // only do something if desired seek position is valid - if( origin + off > data->myStreamStartPos ) { - toff_t num_fill; + if( (static_cast(origin) + off) > static_cast(data->start_pos) ) { + uint64 num_fill; // clear the fail bit os->clear(os->rdstate() & ~ios::failbit); // extend the stream to the expected size os->seekp(0, ios::end); - num_fill = origin + off - (toff_t)os->tellp(); - for( toff_t i = 0; i < num_fill; i++ ) + num_fill = (static_cast(origin)) + off - os->tellp(); + for( uint64 i = 0; i < num_fill; i++ ) os->put('\0'); // retry the seek - os->seekp(origin + off, ios::beg); + os->seekp(static_cast(static_cast(origin) + off), ios::beg); } } - return os->tellp(); + return static_cast(os->tellp()); } -static toff_t -_tiffisSeekProc(thandle_t fd, toff_t off, int whence) +static uint64 +_tiffisSeekProc(thandle_t fd, uint64 off, int whence) { - tiffis_data *data = (tiffis_data *)fd; + tiffis_data *data = reinterpret_cast(fd); switch(whence) { case SEEK_SET: - data->myIS->seekg(data->myStreamStartPos + off, ios::beg); - break; + { + // Compute 64-bit offset + uint64 new_offset = static_cast(data->start_pos) + off; + + // Verify that value does not overflow + ios::off_type offset = static_cast(new_offset); + if (static_cast(offset) != new_offset) + return static_cast(-1); + + data->stream->seekg(offset, ios::beg); + break; + } case SEEK_CUR: - data->myIS->seekg(off, ios::cur); - break; + { + // Verify that value does not overflow + ios::off_type offset = static_cast(off); + if (static_cast(offset) != off) + return static_cast(-1); + + data->stream->seekg(offset, ios::cur); + break; + } case SEEK_END: - data->myIS->seekg(off, ios::end); - break; + { + // Verify that value does not overflow + ios::off_type offset = static_cast(off); + if (static_cast(offset) != off) + return static_cast(-1); + + data->stream->seekg(offset, ios::end); + break; + } } - return ((long)data->myIS->tellg()) - data->myStreamStartPos; + return (uint64) (data->stream->tellg() - data->start_pos); } -static toff_t +static uint64 _tiffosSizeProc(thandle_t fd) { - tiffos_data *data = (tiffos_data *)fd; - ostream *os = data->myOS; - toff_t pos = os->tellp(); - toff_t len; + tiffos_data *data = reinterpret_cast(fd); + ostream *os = data->stream; + ios::pos_type pos = os->tellp(); + ios::pos_type len; os->seekp(0, ios::end); len = os->tellp(); os->seekp(pos); - return len; + return (uint64) len; } -static toff_t +static uint64 _tiffisSizeProc(thandle_t fd) { - tiffis_data *data = (tiffis_data *)fd; - int pos = data->myIS->tellg(); - int len; + tiffis_data *data = reinterpret_cast(fd); + ios::pos_type pos = data->stream->tellg(); + ios::pos_type len; - data->myIS->seekg(0, ios::end); - len = data->myIS->tellg(); - data->myIS->seekg(pos); + data->stream->seekg(0, ios::end); + len = data->stream->tellg(); + data->stream->seekg(pos); - return len; + return (uint64) len; } static int _tiffosCloseProc(thandle_t fd) { // Our stream was not allocated by us, so it shouldn't be closed by us. - delete (tiffos_data *)fd; + delete reinterpret_cast(fd); return 0; } @@ -218,19 +333,23 @@ static int _tiffisCloseProc(thandle_t fd) { // Our stream was not allocated by us, so it shouldn't be closed by us. - delete (tiffis_data *)fd; + delete reinterpret_cast(fd); return 0; } static int -_tiffDummyMapProc(thandle_t , tdata_t* , toff_t* ) +_tiffDummyMapProc(thandle_t , void** base, toff_t* size ) { + (void) base; + (void) size; return (0); } static void -_tiffDummyUnmapProc(thandle_t , tdata_t , toff_t ) +_tiffDummyUnmapProc(thandle_t , void* base, toff_t size ) { + (void) base; + (void) size; } /* @@ -243,32 +362,40 @@ _tiffStreamOpen(const char* name, const char* mode, void *fd) if( strchr(mode, 'w') ) { tiffos_data *data = new tiffos_data; - data->myOS = (ostream *)fd; - data->myStreamStartPos = data->myOS->tellp(); + data->stream = reinterpret_cast(fd); + data->start_pos = data->stream->tellp(); // Open for writing. tif = TIFFClientOpen(name, mode, - (thandle_t) data, - _tiffosReadProc, _tiffosWriteProc, - _tiffosSeekProc, _tiffosCloseProc, + reinterpret_cast(data), + _tiffosReadProc, + _tiffosWriteProc, + _tiffosSeekProc, + _tiffosCloseProc, _tiffosSizeProc, - _tiffDummyMapProc, _tiffDummyUnmapProc); + _tiffDummyMapProc, + _tiffDummyUnmapProc); } else { tiffis_data *data = new tiffis_data; - data->myIS = (istream *)fd; - data->myStreamStartPos = data->myIS->tellg(); + data->stream = reinterpret_cast(fd); + data->start_pos = data->stream->tellg(); // Open for reading. tif = TIFFClientOpen(name, mode, - (thandle_t) data, - _tiffisReadProc, _tiffisWriteProc, - _tiffisSeekProc, _tiffisCloseProc, + reinterpret_cast(data), + _tiffisReadProc, + _tiffisWriteProc, + _tiffisSeekProc, + _tiffisCloseProc, _tiffisSizeProc, - _tiffDummyMapProc, _tiffDummyUnmapProc); + _tiffDummyMapProc, + _tiffDummyUnmapProc); } return (tif); } +} /* extern "C" */ + TIFF* TIFFStreamOpen(const char* name, ostream *os) { @@ -276,7 +403,7 @@ TIFFStreamOpen(const char* name, ostream *os) // written to it yet, then tellp() will return -1 which will break us. // We workaround this by writing out a dummy character and // then seek back to the beginning. - if( !os->fail() && (int)os->tellp() < 0 ) { + if( !os->fail() && static_cast(os->tellp()) < 0 ) { *os << '\0'; os->seekp(0); } @@ -293,3 +420,11 @@ TIFFStreamOpen(const char* name, istream *is) } /* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ + diff --git a/thirdparty/libtiff/tif_strip.c b/thirdparty/libtiff/tif_strip.c index 63dec6bd..6cac71dd 100644 --- a/thirdparty/libtiff/tif_strip.c +++ b/thirdparty/libtiff/tif_strip.c @@ -1,4 +1,4 @@ -/* $Id: tif_strip.c,v 1.19.2.1 2010-06-08 18:50:43 bfriesen Exp $ */ +/* $Id: tif_strip.c,v 1.36 2015-06-07 22:35:40 bfriesen Exp $ */ /* * Copyright (c) 1991-1997 Sam Leffler @@ -31,54 +31,25 @@ */ #include "tiffiop.h" -static uint32 -summarize(TIFF* tif, size_t summand1, size_t summand2, const char* where) -{ - /* - * XXX: We are using casting to uint32 here, bacause sizeof(size_t) - * may be larger than sizeof(uint32) on 64-bit architectures. - */ - uint32 bytes = summand1 + summand2; - - if (bytes - summand1 != summand2) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Integer overflow in %s", where); - bytes = 0; - } - - return (bytes); -} - -static uint32 -multiply(TIFF* tif, size_t nmemb, size_t elem_size, const char* where) -{ - uint32 bytes = nmemb * elem_size; - - if (elem_size && bytes / elem_size != nmemb) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Integer overflow in %s", where); - bytes = 0; - } - - return (bytes); -} - /* * Compute which strip a (row,sample) value is in. */ -tstrip_t -TIFFComputeStrip(TIFF* tif, uint32 row, tsample_t sample) +uint32 +TIFFComputeStrip(TIFF* tif, uint32 row, uint16 sample) { + static const char module[] = "TIFFComputeStrip"; TIFFDirectory *td = &tif->tif_dir; - tstrip_t strip; + uint32 strip; strip = row / td->td_rowsperstrip; if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { if (sample >= td->td_samplesperpixel) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + TIFFErrorExt(tif->tif_clientdata, module, "%lu: Sample out of range, max %lu", (unsigned long) sample, (unsigned long) td->td_samplesperpixel); - return ((tstrip_t) 0); + return (0); } - strip += sample*td->td_stripsperimage; + strip += (uint32)sample*td->td_stripsperimage; } return (strip); } @@ -86,33 +57,34 @@ TIFFComputeStrip(TIFF* tif, uint32 row, tsample_t sample) /* * Compute how many strips are in an image. */ -tstrip_t +uint32 TIFFNumberOfStrips(TIFF* tif) { TIFFDirectory *td = &tif->tif_dir; - tstrip_t nstrips; + uint32 nstrips; nstrips = (td->td_rowsperstrip == (uint32) -1 ? 1 : - TIFFhowmany(td->td_imagelength, td->td_rowsperstrip)); + TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip)); if (td->td_planarconfig == PLANARCONFIG_SEPARATE) - nstrips = multiply(tif, nstrips, td->td_samplesperpixel, - "TIFFNumberOfStrips"); + nstrips = _TIFFMultiply32(tif, nstrips, (uint32)td->td_samplesperpixel, + "TIFFNumberOfStrips"); return (nstrips); } /* * Compute the # bytes in a variable height, row-aligned strip. */ -tsize_t -TIFFVStripSize(TIFF* tif, uint32 nrows) +uint64 +TIFFVStripSize64(TIFF* tif, uint32 nrows) { + static const char module[] = "TIFFVStripSize64"; TIFFDirectory *td = &tif->tif_dir; - - if (nrows == (uint32) -1) - nrows = td->td_imagelength; - if (td->td_planarconfig == PLANARCONFIG_CONTIG && - td->td_photometric == PHOTOMETRIC_YCBCR && - !isUpSampled(tif)) { + if (nrows==(uint32)(-1)) + nrows=td->td_imagelength; + if ((td->td_planarconfig==PLANARCONFIG_CONTIG)&& + (td->td_photometric == PHOTOMETRIC_YCBCR)&& + (!isUpSampled(tif))) + { /* * Packed YCbCr data contain one Cb+Cr for every * HorizontalSampling*VerticalSampling Y values. @@ -122,53 +94,102 @@ TIFFVStripSize(TIFF* tif, uint32 nrows) * YCbCr data for the extended image. */ uint16 ycbcrsubsampling[2]; - tsize_t w, scanline, samplingarea; - - TIFFGetField( tif, TIFFTAG_YCBCRSUBSAMPLING, - ycbcrsubsampling + 0, - ycbcrsubsampling + 1 ); - - samplingarea = ycbcrsubsampling[0]*ycbcrsubsampling[1]; - if (samplingarea == 0) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Invalid YCbCr subsampling"); + uint16 samplingblock_samples; + uint32 samplingblocks_hor; + uint32 samplingblocks_ver; + uint64 samplingrow_samples; + uint64 samplingrow_size; + if(td->td_samplesperpixel!=3) + { + TIFFErrorExt(tif->tif_clientdata,module, + "Invalid td_samplesperpixel value"); return 0; } - - w = TIFFroundup(td->td_imagewidth, ycbcrsubsampling[0]); - scanline = TIFFhowmany8(multiply(tif, w, td->td_bitspersample, - "TIFFVStripSize")); - nrows = TIFFroundup(nrows, ycbcrsubsampling[1]); - /* NB: don't need TIFFhowmany here 'cuz everything is rounded */ - scanline = multiply(tif, nrows, scanline, "TIFFVStripSize"); - return ((tsize_t) - summarize(tif, scanline, - multiply(tif, 2, scanline / samplingarea, - "TIFFVStripSize"), "TIFFVStripSize")); - } else - return ((tsize_t) multiply(tif, nrows, TIFFScanlineSize(tif), - "TIFFVStripSize")); + TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0, + ycbcrsubsampling+1); + if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && ycbcrsubsampling[0] != 4) + ||(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && ycbcrsubsampling[1] != 4)) + { + TIFFErrorExt(tif->tif_clientdata,module, + "Invalid YCbCr subsampling (%dx%d)", + ycbcrsubsampling[0], + ycbcrsubsampling[1] ); + return 0; + } + samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2; + samplingblocks_hor=TIFFhowmany_32(td->td_imagewidth,ycbcrsubsampling[0]); + samplingblocks_ver=TIFFhowmany_32(nrows,ycbcrsubsampling[1]); + samplingrow_samples=_TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module); + samplingrow_size=TIFFhowmany8_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module)); + return(_TIFFMultiply64(tif,samplingrow_size,samplingblocks_ver,module)); + } + else + return(_TIFFMultiply64(tif,nrows,TIFFScanlineSize64(tif),module)); +} +tmsize_t +TIFFVStripSize(TIFF* tif, uint32 nrows) +{ + static const char module[] = "TIFFVStripSize"; + uint64 m; + tmsize_t n; + m=TIFFVStripSize64(tif,nrows); + n=(tmsize_t)m; + if ((uint64)n!=m) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); + n=0; + } + return(n); } - /* * Compute the # bytes in a raw strip. */ -tsize_t -TIFFRawStripSize(TIFF* tif, tstrip_t strip) +uint64 +TIFFRawStripSize64(TIFF* tif, uint32 strip) { + static const char module[] = "TIFFRawStripSize64"; TIFFDirectory* td = &tif->tif_dir; - tsize_t bytecount = td->td_stripbytecount[strip]; + uint64 bytecount = td->td_stripbytecount[strip]; - if (bytecount <= 0) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "%lu: Invalid strip byte count, strip %lu", - (unsigned long) bytecount, (unsigned long) strip); - bytecount = (tsize_t) -1; + if (bytecount == 0) + { +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, + "%I64u: Invalid strip byte count, strip %lu", + (unsigned __int64) bytecount, + (unsigned long) strip); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "%llu: Invalid strip byte count, strip %lu", + (unsigned long long) bytecount, + (unsigned long) strip); +#endif + bytecount = (uint64) -1; } return bytecount; } +tmsize_t +TIFFRawStripSize(TIFF* tif, uint32 strip) +{ + static const char module[] = "TIFFRawStripSize"; + uint64 m; + tmsize_t n; + m=TIFFRawStripSize64(tif,strip); + if (m==(uint64)(-1)) + n=(tmsize_t)(-1); + else + { + n=(tmsize_t)m; + if ((uint64)n!=m) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); + n=0; + } + } + return(n); +} /* * Compute the # bytes in a (row-aligned) strip. @@ -178,14 +199,29 @@ TIFFRawStripSize(TIFF* tif, tstrip_t strip) * truncated to reflect the actual space required * to hold the strip. */ -tsize_t -TIFFStripSize(TIFF* tif) +uint64 +TIFFStripSize64(TIFF* tif) { TIFFDirectory* td = &tif->tif_dir; uint32 rps = td->td_rowsperstrip; if (rps > td->td_imagelength) rps = td->td_imagelength; - return (TIFFVStripSize(tif, rps)); + return (TIFFVStripSize64(tif, rps)); +} +tmsize_t +TIFFStripSize(TIFF* tif) +{ + static const char module[] = "TIFFStripSize"; + uint64 m; + tmsize_t n; + m=TIFFStripSize64(tif); + n=(tmsize_t)m; + if ((uint64)n!=m) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); + n=0; + } + return(n); } /* @@ -209,82 +245,21 @@ _TIFFDefaultStripSize(TIFF* tif, uint32 s) * image up into strips that are approximately * STRIP_SIZE_DEFAULT bytes long. */ - tsize_t scanline = TIFFScanlineSize(tif); - s = (uint32)STRIP_SIZE_DEFAULT / (scanline == 0 ? 1 : scanline); - if (s == 0) /* very wide images */ - s = 1; + uint64 scanlinesize; + uint64 rows; + scanlinesize=TIFFScanlineSize64(tif); + if (scanlinesize==0) + scanlinesize=1; + rows=(uint64)STRIP_SIZE_DEFAULT/scanlinesize; + if (rows==0) + rows=1; + else if (rows>0xFFFFFFFF) + rows=0xFFFFFFFF; + s=(uint32)rows; } return (s); } -/* - * Return the number of bytes to read/write in a call to - * one of the scanline-oriented i/o routines. Note that - * this number may be 1/samples-per-pixel if data is - * stored as separate planes. - */ -tsize_t -TIFFScanlineSize(TIFF* tif) -{ - TIFFDirectory *td = &tif->tif_dir; - tsize_t scanline; - - if (td->td_planarconfig == PLANARCONFIG_CONTIG) { - if (td->td_photometric == PHOTOMETRIC_YCBCR - && !isUpSampled(tif)) { - uint16 ycbcrsubsampling[2]; - - TIFFGetField(tif, TIFFTAG_YCBCRSUBSAMPLING, - ycbcrsubsampling + 0, - ycbcrsubsampling + 1); - - if (ycbcrsubsampling[0] == 0) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Invalid YCbCr subsampling"); - return 0; - } - - scanline = TIFFroundup(td->td_imagewidth, - ycbcrsubsampling[0]); - scanline = TIFFhowmany8(multiply(tif, scanline, - td->td_bitspersample, - "TIFFScanlineSize")); - return ((tsize_t) - summarize(tif, scanline, - multiply(tif, 2, - scanline / ycbcrsubsampling[0], - "TIFFVStripSize"), - "TIFFVStripSize")); - } else { - scanline = multiply(tif, td->td_imagewidth, - td->td_samplesperpixel, - "TIFFScanlineSize"); - } - } else - scanline = td->td_imagewidth; - return ((tsize_t) TIFFhowmany8(multiply(tif, scanline, - td->td_bitspersample, - "TIFFScanlineSize"))); -} - -/* - * Some stuff depends on this older version of TIFFScanlineSize - * TODO: resolve this - */ -tsize_t -TIFFOldScanlineSize(TIFF* tif) -{ - TIFFDirectory *td = &tif->tif_dir; - tsize_t scanline; - - scanline = multiply (tif, td->td_bitspersample, td->td_imagewidth, - "TIFFScanlineSize"); - if (td->td_planarconfig == PLANARCONFIG_CONTIG) - scanline = multiply (tif, scanline, td->td_samplesperpixel, - "TIFFScanlineSize"); - return ((tsize_t) TIFFhowmany8(scanline)); -} - /* * Return the number of bytes to read/write in a call to * one of the scanline-oriented i/o routines. Note that @@ -294,46 +269,77 @@ TIFFOldScanlineSize(TIFF* tif) * strip size divided by the strip height, i.e. the size of a pack of vertical * subsampling lines divided by vertical subsampling. It should thus make * sense when multiplied by a multiple of vertical subsampling. - * Some stuff depends on this newer version of TIFFScanlineSize - * TODO: resolve this */ -tsize_t -TIFFNewScanlineSize(TIFF* tif) +uint64 +TIFFScanlineSize64(TIFF* tif) { + static const char module[] = "TIFFScanlineSize64"; TIFFDirectory *td = &tif->tif_dir; - tsize_t scanline; - - if (td->td_planarconfig == PLANARCONFIG_CONTIG) { - if (td->td_photometric == PHOTOMETRIC_YCBCR - && !isUpSampled(tif)) { + uint64 scanline_size; + if (td->td_planarconfig==PLANARCONFIG_CONTIG) + { + if ((td->td_photometric==PHOTOMETRIC_YCBCR)&& + (td->td_samplesperpixel==3)&& + (!isUpSampled(tif))) + { uint16 ycbcrsubsampling[2]; - - TIFFGetField(tif, TIFFTAG_YCBCRSUBSAMPLING, - ycbcrsubsampling + 0, - ycbcrsubsampling + 1); - - if (ycbcrsubsampling[0]*ycbcrsubsampling[1] == 0) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Invalid YCbCr subsampling"); - return 0; + uint16 samplingblock_samples; + uint32 samplingblocks_hor; + uint64 samplingrow_samples; + uint64 samplingrow_size; + if(td->td_samplesperpixel!=3) + { + TIFFErrorExt(tif->tif_clientdata,module, + "Invalid td_samplesperpixel value"); + return 0; } - - return((tsize_t) ((((td->td_imagewidth+ycbcrsubsampling[0]-1) - /ycbcrsubsampling[0]) - *(ycbcrsubsampling[0]*ycbcrsubsampling[1]+2) - *td->td_bitspersample+7) - /8)/ycbcrsubsampling[1]); - - } else { - scanline = multiply(tif, td->td_imagewidth, - td->td_samplesperpixel, - "TIFFScanlineSize"); + TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING, + ycbcrsubsampling+0, + ycbcrsubsampling+1); + if (((ycbcrsubsampling[0]!=1)&&(ycbcrsubsampling[0]!=2)&&(ycbcrsubsampling[0]!=4)) || + ((ycbcrsubsampling[1]!=1)&&(ycbcrsubsampling[1]!=2)&&(ycbcrsubsampling[1]!=4))) + { + TIFFErrorExt(tif->tif_clientdata,module, + "Invalid YCbCr subsampling"); + return 0; + } + samplingblock_samples = ycbcrsubsampling[0]*ycbcrsubsampling[1]+2; + samplingblocks_hor = TIFFhowmany_32(td->td_imagewidth,ycbcrsubsampling[0]); + samplingrow_samples = _TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module); + samplingrow_size = TIFFhowmany_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module),8); + scanline_size = (samplingrow_size/ycbcrsubsampling[1]); } - } else - scanline = td->td_imagewidth; - return ((tsize_t) TIFFhowmany8(multiply(tif, scanline, - td->td_bitspersample, - "TIFFScanlineSize"))); + else + { + uint64 scanline_samples; + scanline_samples=_TIFFMultiply64(tif,td->td_imagewidth,td->td_samplesperpixel,module); + scanline_size=TIFFhowmany_64(_TIFFMultiply64(tif,scanline_samples,td->td_bitspersample,module),8); + } + } + 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 +TIFFScanlineSize(TIFF* tif) +{ + static const char module[] = "TIFFScanlineSize"; + uint64 m; + tmsize_t n; + m=TIFFScanlineSize64(tif); + n=(tmsize_t)m; + if ((uint64)n!=m) { + TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow"); + n=0; + } + return(n); } /* @@ -342,22 +348,35 @@ TIFFNewScanlineSize(TIFF* tif) * I/O size returned by TIFFScanlineSize which may be less * if data is store as separate planes). */ -tsize_t +uint64 +TIFFRasterScanlineSize64(TIFF* tif) +{ + static const char module[] = "TIFFRasterScanlineSize64"; + TIFFDirectory *td = &tif->tif_dir; + uint64 scanline; + + scanline = _TIFFMultiply64(tif, td->td_bitspersample, td->td_imagewidth, module); + if (td->td_planarconfig == PLANARCONFIG_CONTIG) { + scanline = _TIFFMultiply64(tif, scanline, td->td_samplesperpixel, module); + return (TIFFhowmany8_64(scanline)); + } else + return (_TIFFMultiply64(tif, TIFFhowmany8_64(scanline), + td->td_samplesperpixel, module)); +} +tmsize_t TIFFRasterScanlineSize(TIFF* tif) { - TIFFDirectory *td = &tif->tif_dir; - tsize_t scanline; - - scanline = multiply (tif, td->td_bitspersample, td->td_imagewidth, - "TIFFRasterScanlineSize"); - if (td->td_planarconfig == PLANARCONFIG_CONTIG) { - scanline = multiply (tif, scanline, td->td_samplesperpixel, - "TIFFRasterScanlineSize"); - return ((tsize_t) TIFFhowmany8(scanline)); - } else - return ((tsize_t) multiply (tif, TIFFhowmany8(scanline), - td->td_samplesperpixel, - "TIFFRasterScanlineSize")); + static const char module[] = "TIFFRasterScanlineSize"; + uint64 m; + tmsize_t n; + m=TIFFRasterScanlineSize64(tif); + n=(tmsize_t)m; + if ((uint64)n!=m) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow"); + n=0; + } + return(n); } /* vim: set ts=8 sts=8 sw=8 noet: */ diff --git a/thirdparty/libtiff/tif_swab.c b/thirdparty/libtiff/tif_swab.c index e4f1a6d1..f37e33f1 100644 --- a/thirdparty/libtiff/tif_swab.c +++ b/thirdparty/libtiff/tif_swab.c @@ -1,4 +1,4 @@ -/* $Id: tif_swab.c,v 1.4.2.1 2010-06-08 18:50:43 bfriesen Exp $ */ +/* $Id: tif_swab.c,v 1.13 2010-03-10 18:56:49 bfriesen Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -37,7 +37,7 @@ TIFFSwabShort(uint16* wp) { register unsigned char* cp = (unsigned char*) wp; unsigned char t; - + assert(sizeof(uint16)==2); t = cp[1]; cp[1] = cp[0]; cp[0] = t; } #endif @@ -48,19 +48,33 @@ TIFFSwabLong(uint32* lp) { register unsigned char* cp = (unsigned char*) lp; unsigned char t; - + assert(sizeof(uint32)==4); t = cp[3]; cp[3] = cp[0]; cp[0] = t; t = cp[2]; cp[2] = cp[1]; cp[1] = t; } #endif +#ifndef TIFFSwabLong8 +void +TIFFSwabLong8(uint64* lp) +{ + register unsigned char* cp = (unsigned char*) lp; + unsigned char t; + assert(sizeof(uint64)==8); + t = cp[7]; cp[7] = cp[0]; cp[0] = t; + t = cp[6]; cp[6] = cp[1]; cp[1] = t; + t = cp[5]; cp[5] = cp[2]; cp[2] = t; + t = cp[4]; cp[4] = cp[3]; cp[3] = t; +} +#endif + #ifndef TIFFSwabArrayOfShort void -TIFFSwabArrayOfShort(uint16* wp, register unsigned long n) +TIFFSwabArrayOfShort(register uint16* wp, tmsize_t n) { register unsigned char* cp; register unsigned char t; - + assert(sizeof(uint16)==2); /* XXX unroll loop some */ while (n-- > 0) { cp = (unsigned char*) wp; @@ -72,7 +86,7 @@ TIFFSwabArrayOfShort(uint16* wp, register unsigned long n) #ifndef TIFFSwabArrayOfTriples void -TIFFSwabArrayOfTriples(uint8* tp, unsigned long n) +TIFFSwabArrayOfTriples(register uint8* tp, tmsize_t n) { unsigned char* cp; unsigned char t; @@ -88,11 +102,11 @@ TIFFSwabArrayOfTriples(uint8* tp, unsigned long n) #ifndef TIFFSwabArrayOfLong void -TIFFSwabArrayOfLong(register uint32* lp, register unsigned long n) +TIFFSwabArrayOfLong(register uint32* lp, tmsize_t n) { register unsigned char *cp; register unsigned char t; - + assert(sizeof(uint32)==4); /* XXX unroll loop some */ while (n-- > 0) { cp = (unsigned char *)lp; @@ -103,30 +117,84 @@ TIFFSwabArrayOfLong(register uint32* lp, register unsigned long n) } #endif +#ifndef TIFFSwabArrayOfLong8 +void +TIFFSwabArrayOfLong8(register uint64* lp, tmsize_t n) +{ + register unsigned char *cp; + register unsigned char t; + assert(sizeof(uint64)==8); + /* XXX unroll loop some */ + while (n-- > 0) { + cp = (unsigned char *)lp; + t = cp[7]; cp[7] = cp[0]; cp[0] = t; + t = cp[6]; cp[6] = cp[1]; cp[1] = t; + t = cp[5]; cp[5] = cp[2]; cp[2] = t; + t = cp[4]; cp[4] = cp[3]; cp[3] = t; + lp++; + } +} +#endif + +#ifndef TIFFSwabFloat +void +TIFFSwabFloat(float* fp) +{ + register unsigned char* cp = (unsigned char*) fp; + unsigned char t; + assert(sizeof(float)==4); + t = cp[3]; cp[3] = cp[0]; cp[0] = t; + t = cp[2]; cp[2] = cp[1]; cp[1] = t; +} +#endif + +#ifndef TIFFSwabArrayOfFloat +void +TIFFSwabArrayOfFloat(register float* fp, tmsize_t n) +{ + register unsigned char *cp; + register unsigned char t; + assert(sizeof(float)==4); + /* XXX unroll loop some */ + while (n-- > 0) { + cp = (unsigned char *)fp; + t = cp[3]; cp[3] = cp[0]; cp[0] = t; + t = cp[2]; cp[2] = cp[1]; cp[1] = t; + fp++; + } +} +#endif + #ifndef TIFFSwabDouble void TIFFSwabDouble(double *dp) { - register uint32* lp = (uint32*) dp; - uint32 t; - - TIFFSwabArrayOfLong(lp, 2); - t = lp[0]; lp[0] = lp[1]; lp[1] = t; + register unsigned char* cp = (unsigned char*) dp; + unsigned char t; + assert(sizeof(double)==8); + t = cp[7]; cp[7] = cp[0]; cp[0] = t; + t = cp[6]; cp[6] = cp[1]; cp[1] = t; + t = cp[5]; cp[5] = cp[2]; cp[2] = t; + t = cp[4]; cp[4] = cp[3]; cp[3] = t; } #endif #ifndef TIFFSwabArrayOfDouble void -TIFFSwabArrayOfDouble(double* dp, register unsigned long n) +TIFFSwabArrayOfDouble(double* dp, tmsize_t n) { - register uint32* lp = (uint32*) dp; - register uint32 t; - - TIFFSwabArrayOfLong(lp, n + n); - while (n-- > 0) { - t = lp[0]; lp[0] = lp[1]; lp[1] = t; - lp += 2; - } + register unsigned char *cp; + register unsigned char t; + assert(sizeof(double)==8); + /* XXX unroll loop some */ + while (n-- > 0) { + cp = (unsigned char *)dp; + t = cp[7]; cp[7] = cp[0]; cp[0] = t; + t = cp[6]; cp[6] = cp[1]; cp[1] = t; + t = cp[5]; cp[5] = cp[2]; cp[2] = t; + t = cp[4]; cp[4] = cp[3]; cp[3] = t; + dp++; + } } #endif @@ -215,7 +283,7 @@ TIFFGetBitRevTable(int reversed) } void -TIFFReverseBits(register unsigned char* cp, register unsigned long n) +TIFFReverseBits(uint8* cp, tmsize_t n) { for (; n > 8; n -= 8) { cp[0] = TIFFBitRevTable[cp[0]]; diff --git a/thirdparty/libtiff/tif_thunder.c b/thirdparty/libtiff/tif_thunder.c index 8e7a1258..390891c9 100644 --- a/thirdparty/libtiff/tif_thunder.c +++ b/thirdparty/libtiff/tif_thunder.c @@ -1,4 +1,4 @@ -/* $Id: tif_thunder.c,v 1.5.2.1 2010-06-08 18:50:43 bfriesen Exp $ */ +/* $Id: tif_thunder.c,v 1.12 2011-04-02 20:54:09 bfriesen Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -25,6 +25,7 @@ */ #include "tiffiop.h" +#include #ifdef THUNDER_SUPPORT /* * TIFF Library. @@ -55,21 +56,42 @@ static const int twobitdeltas[4] = { 0, 1, 0, -1 }; static const int threebitdeltas[8] = { 0, 1, 2, 3, 0, -3, -2, -1 }; -#define SETPIXEL(op, v) { \ - lastpixel = (v) & 0xf; \ - if (npixels++ & 1) \ - *op++ |= lastpixel; \ - else \ - op[0] = (tidataval_t) (lastpixel << 4); \ +#define SETPIXEL(op, v) { \ + lastpixel = (v) & 0xf; \ + if ( npixels < maxpixels ) \ + { \ + if (npixels++ & 1) \ + *op++ |= lastpixel; \ + else \ + op[0] = (uint8) (lastpixel << 4); \ + } \ } static int -ThunderDecode(TIFF* tif, tidata_t op, tsize_t maxpixels) +ThunderSetupDecode(TIFF* tif) { + static const char module[] = "ThunderSetupDecode"; + + if( tif->tif_dir.td_bitspersample != 4 ) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Wrong bitspersample value (%d), Thunder decoder only supports 4bits per sample.", + (int) tif->tif_dir.td_bitspersample ); + return 0; + } + + + return (1); +} + +static int +ThunderDecode(TIFF* tif, uint8* op, tmsize_t maxpixels) +{ + static const char module[] = "ThunderDecode"; register unsigned char *bp; - register tsize_t cc; + register tmsize_t cc; unsigned int lastpixel; - tsize_t npixels; + tmsize_t npixels; bp = (unsigned char *)tif->tif_rawcp; cc = tif->tif_rawcc; @@ -93,7 +115,7 @@ ThunderDecode(TIFF* tif, tidata_t op, tsize_t maxpixels) npixels += n; if (npixels < maxpixels) { for (; n > 0; n -= 2) - *op++ = (tidataval_t) lastpixel; + *op++ = (uint8) lastpixel; } if (n == -1) *--op &= 0xf0; @@ -118,25 +140,43 @@ ThunderDecode(TIFF* tif, tidata_t op, tsize_t maxpixels) break; } } - tif->tif_rawcp = (tidata_t) bp; + tif->tif_rawcp = (uint8*) bp; tif->tif_rawcc = cc; if (npixels != maxpixels) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "ThunderDecode: %s data at scanline %ld (%lu != %lu)", - npixels < maxpixels ? "Not enough" : "Too much", - (long) tif->tif_row, (long) npixels, (long) maxpixels); +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, + "%s data at scanline %lu (%I64u != %I64u)", + npixels < maxpixels ? "Not enough" : "Too much", + (unsigned long) tif->tif_row, + (unsigned __int64) npixels, + (unsigned __int64) maxpixels); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "%s data at scanline %lu (%llu != %llu)", + npixels < maxpixels ? "Not enough" : "Too much", + (unsigned long) tif->tif_row, + (unsigned long long) npixels, + (unsigned long long) maxpixels); +#endif return (0); } - return (1); + + return (1); } static int -ThunderDecodeRow(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) +ThunderDecodeRow(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) { - tidata_t row = buf; + static const char module[] = "ThunderDecodeRow"; + uint8* row = buf; (void) s; - while ((long)occ > 0) { + if (occ % tif->tif_scanlinesize) + { + TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read"); + return (0); + } + while (occ > 0) { if (!ThunderDecode(tif, row, tif->tif_dir.td_imagewidth)) return (0); occ -= tif->tif_scanlinesize; @@ -149,8 +189,10 @@ int TIFFInitThunderScan(TIFF* tif, int scheme) { (void) scheme; + + tif->tif_setupdecode = ThunderSetupDecode; tif->tif_decoderow = ThunderDecodeRow; - tif->tif_decodestrip = ThunderDecodeRow; + tif->tif_decodestrip = ThunderDecodeRow; return (1); } #endif /* THUNDER_SUPPORT */ diff --git a/thirdparty/libtiff/tif_tile.c b/thirdparty/libtiff/tif_tile.c index d8379e61..388e168a 100644 --- a/thirdparty/libtiff/tif_tile.c +++ b/thirdparty/libtiff/tif_tile.c @@ -1,4 +1,4 @@ -/* $Id: tif_tile.c,v 1.12.2.1 2010-06-08 18:50:43 bfriesen Exp $ */ +/* $Id: tif_tile.c,v 1.24 2015-06-07 22:35:40 bfriesen Exp $ */ /* * Copyright (c) 1991-1997 Sam Leffler @@ -31,47 +31,17 @@ */ #include "tiffiop.h" -static uint32 -summarize(TIFF* tif, size_t summand1, size_t summand2, const char* where) -{ - /* - * XXX: We are using casting to uint32 here, because sizeof(size_t) - * may be larger than sizeof(uint32) on 64-bit architectures. - */ - uint32 bytes = summand1 + summand2; - - if (bytes - summand1 != summand2) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Integer overflow in %s", where); - bytes = 0; - } - - return (bytes); -} - -static uint32 -multiply(TIFF* tif, size_t nmemb, size_t elem_size, const char* where) -{ - uint32 bytes = nmemb * elem_size; - - if (elem_size && bytes / elem_size != nmemb) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Integer overflow in %s", where); - bytes = 0; - } - - return (bytes); -} - /* * Compute which tile an (x,y,z,s) value is in. */ -ttile_t -TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, tsample_t s) +uint32 +TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s) { TIFFDirectory *td = &tif->tif_dir; uint32 dx = td->td_tilewidth; uint32 dy = td->td_tilelength; uint32 dz = td->td_tiledepth; - ttile_t tile = 1; + uint32 tile = 1; if (td->td_imagedepth == 1) z = 0; @@ -82,9 +52,9 @@ TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, tsample_t s) if (dz == (uint32) -1) dz = td->td_imagedepth; if (dx != 0 && dy != 0 && dz != 0) { - uint32 xpt = TIFFhowmany(td->td_imagewidth, dx); - uint32 ypt = TIFFhowmany(td->td_imagelength, dy); - uint32 zpt = TIFFhowmany(td->td_imagedepth, dz); + uint32 xpt = TIFFhowmany_32(td->td_imagewidth, dx); + uint32 ypt = TIFFhowmany_32(td->td_imagelength, dy); + uint32 zpt = TIFFhowmany_32(td->td_imagedepth, dz); if (td->td_planarconfig == PLANARCONFIG_SEPARATE) tile = (xpt*ypt*zpt)*s + @@ -102,7 +72,7 @@ TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, tsample_t s) * against the image bounds. */ int -TIFFCheckTile(TIFF* tif, uint32 x, uint32 y, uint32 z, tsample_t s) +TIFFCheckTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s) { TIFFDirectory *td = &tif->tif_dir; @@ -141,14 +111,14 @@ TIFFCheckTile(TIFF* tif, uint32 x, uint32 y, uint32 z, tsample_t s) /* * Compute how many tiles are in an image. */ -ttile_t +uint32 TIFFNumberOfTiles(TIFF* tif) { TIFFDirectory *td = &tif->tif_dir; uint32 dx = td->td_tilewidth; uint32 dy = td->td_tilelength; uint32 dz = td->td_tiledepth; - ttile_t ntiles; + uint32 ntiles; if (dx == (uint32) -1) dx = td->td_imagewidth; @@ -157,50 +127,89 @@ TIFFNumberOfTiles(TIFF* tif) if (dz == (uint32) -1) dz = td->td_imagedepth; ntiles = (dx == 0 || dy == 0 || dz == 0) ? 0 : - multiply(tif, multiply(tif, TIFFhowmany(td->td_imagewidth, dx), - TIFFhowmany(td->td_imagelength, dy), - "TIFFNumberOfTiles"), - TIFFhowmany(td->td_imagedepth, dz), "TIFFNumberOfTiles"); + _TIFFMultiply32(tif, _TIFFMultiply32(tif, TIFFhowmany_32(td->td_imagewidth, dx), + TIFFhowmany_32(td->td_imagelength, dy), + "TIFFNumberOfTiles"), + TIFFhowmany_32(td->td_imagedepth, dz), "TIFFNumberOfTiles"); if (td->td_planarconfig == PLANARCONFIG_SEPARATE) - ntiles = multiply(tif, ntiles, td->td_samplesperpixel, - "TIFFNumberOfTiles"); + ntiles = _TIFFMultiply32(tif, ntiles, td->td_samplesperpixel, + "TIFFNumberOfTiles"); return (ntiles); } /* * Compute the # bytes in each row of a tile. */ -tsize_t +uint64 +TIFFTileRowSize64(TIFF* tif) +{ + static const char module[] = "TIFFTileRowSize64"; + TIFFDirectory *td = &tif->tif_dir; + uint64 rowsize; + uint64 tilerowsize; + + 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"); + } + 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) { - TIFFDirectory *td = &tif->tif_dir; - tsize_t rowsize; - - if (td->td_tilelength == 0 || td->td_tilewidth == 0) - return ((tsize_t) 0); - rowsize = multiply(tif, td->td_bitspersample, td->td_tilewidth, - "TIFFTileRowSize"); - if (td->td_planarconfig == PLANARCONFIG_CONTIG) - rowsize = multiply(tif, rowsize, td->td_samplesperpixel, - "TIFFTileRowSize"); - return ((tsize_t) TIFFhowmany8(rowsize)); + static const char module[] = "TIFFTileRowSize"; + uint64 m; + tmsize_t n; + m=TIFFTileRowSize64(tif); + n=(tmsize_t)m; + if ((uint64)n!=m) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); + n=0; + } + return(n); } /* * Compute the # bytes in a variable length, row-aligned tile. */ -tsize_t -TIFFVTileSize(TIFF* tif, uint32 nrows) +uint64 +TIFFVTileSize64(TIFF* tif, uint32 nrows) { + static const char module[] = "TIFFVTileSize64"; TIFFDirectory *td = &tif->tif_dir; - tsize_t tilesize; - if (td->td_tilelength == 0 || td->td_tilewidth == 0 || td->td_tiledepth == 0) - return ((tsize_t) 0); - if (td->td_planarconfig == PLANARCONFIG_CONTIG && - td->td_photometric == PHOTOMETRIC_YCBCR && - !isUpSampled(tif)) { + return (0); + if ((td->td_planarconfig==PLANARCONFIG_CONTIG)&& + (td->td_photometric==PHOTOMETRIC_YCBCR)&& + (td->td_samplesperpixel==3)&& + (!isUpSampled(tif))) + { /* * Packed YCbCr data contain one Cb+Cr for every * HorizontalSampling*VerticalSampling Y values. @@ -209,38 +218,71 @@ TIFFVTileSize(TIFF* tif, uint32 nrows) * horizontal/vertical subsampling area include * YCbCr data for the extended image. */ - tsize_t w = - TIFFroundup(td->td_tilewidth, td->td_ycbcrsubsampling[0]); - tsize_t rowsize = - TIFFhowmany8(multiply(tif, w, td->td_bitspersample, - "TIFFVTileSize")); - tsize_t samplingarea = - td->td_ycbcrsubsampling[0]*td->td_ycbcrsubsampling[1]; - if (samplingarea == 0) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Invalid YCbCr subsampling"); + uint16 ycbcrsubsampling[2]; + uint16 samplingblock_samples; + uint32 samplingblocks_hor; + uint32 samplingblocks_ver; + uint64 samplingrow_samples; + uint64 samplingrow_size; + TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0, + ycbcrsubsampling+1); + if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && ycbcrsubsampling[0] != 4) + ||(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && ycbcrsubsampling[1] != 4)) + { + TIFFErrorExt(tif->tif_clientdata,module, + "Invalid YCbCr subsampling (%dx%d)", + ycbcrsubsampling[0], + ycbcrsubsampling[1] ); return 0; } - nrows = TIFFroundup(nrows, td->td_ycbcrsubsampling[1]); - /* NB: don't need TIFFhowmany here 'cuz everything is rounded */ - tilesize = multiply(tif, nrows, rowsize, "TIFFVTileSize"); - tilesize = summarize(tif, tilesize, - multiply(tif, 2, tilesize / samplingarea, - "TIFFVTileSize"), - "TIFFVTileSize"); - } else - tilesize = multiply(tif, nrows, TIFFTileRowSize(tif), - "TIFFVTileSize"); - return ((tsize_t) - multiply(tif, tilesize, td->td_tiledepth, "TIFFVTileSize")); + samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2; + samplingblocks_hor=TIFFhowmany_32(td->td_tilewidth,ycbcrsubsampling[0]); + samplingblocks_ver=TIFFhowmany_32(nrows,ycbcrsubsampling[1]); + samplingrow_samples=_TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module); + samplingrow_size=TIFFhowmany8_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module)); + return(_TIFFMultiply64(tif,samplingrow_size,samplingblocks_ver,module)); + } + else + return(_TIFFMultiply64(tif,nrows,TIFFTileRowSize64(tif),module)); +} +tmsize_t +TIFFVTileSize(TIFF* tif, uint32 nrows) +{ + static const char module[] = "TIFFVTileSize"; + uint64 m; + tmsize_t n; + m=TIFFVTileSize64(tif,nrows); + n=(tmsize_t)m; + if ((uint64)n!=m) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); + n=0; + } + return(n); } /* * Compute the # bytes in a row-aligned tile. */ -tsize_t +uint64 +TIFFTileSize64(TIFF* tif) +{ + return (TIFFVTileSize64(tif, tif->tif_dir.td_tilelength)); +} +tmsize_t TIFFTileSize(TIFF* tif) { - return (TIFFVTileSize(tif, tif->tif_dir.td_tilelength)); + static const char module[] = "TIFFTileSize"; + uint64 m; + tmsize_t n; + m=TIFFTileSize64(tif); + n=(tmsize_t)m; + if ((uint64)n!=m) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); + n=0; + } + return(n); } /* @@ -265,9 +307,9 @@ _TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th) *th = 256; /* roundup to a multiple of 16 per the spec */ if (*tw & 0xf) - *tw = TIFFroundup(*tw, 16); + *tw = TIFFroundup_32(*tw, 16); if (*th & 0xf) - *th = TIFFroundup(*th, 16); + *th = TIFFroundup_32(*th, 16); } /* vim: set ts=8 sts=8 sw=8 noet: */ diff --git a/thirdparty/libtiff/tif_unix.c b/thirdparty/libtiff/tif_unix.c index e0f1a8dd..e96841a4 100644 --- a/thirdparty/libtiff/tif_unix.c +++ b/thirdparty/libtiff/tif_unix.c @@ -1,26 +1,26 @@ -/* $Id: tif_unix.c,v 1.12.2.1 2010-06-08 18:50:43 bfriesen Exp $ */ +/* $Id: tif_unix.c,v 1.26 2015-06-16 15:33:17 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -28,12 +28,15 @@ * TIFF Library UNIX-specific Routines. These are should also work with the * Windows Common RunTime Library. */ + #include "tif_config.h" #ifdef HAVE_SYS_TYPES_H # include #endif +#include + #include #include #include @@ -46,57 +49,95 @@ # include #endif +#ifdef HAVE_IO_H +# include +#endif + #include "tiffiop.h" -static tsize_t -_tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size) +typedef union fd_as_handle_union { - return ((tsize_t) read((int) fd, buf, (size_t) size)); + int fd; + thandle_t h; +} fd_as_handle_union_t; + +static tmsize_t +_tiffReadProc(thandle_t fd, void* buf, tmsize_t size) +{ + fd_as_handle_union_t fdh; + size_t size_io = (size_t) size; + if ((tmsize_t) size_io != size) + { + errno=EINVAL; + return (tmsize_t) -1; + } + fdh.h = fd; + return ((tmsize_t) read(fdh.fd, buf, size_io)); } -static tsize_t -_tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size) +static tmsize_t +_tiffWriteProc(thandle_t fd, void* buf, tmsize_t size) { - return ((tsize_t) write((int) fd, buf, (size_t) size)); + fd_as_handle_union_t fdh; + size_t size_io = (size_t) size; + if ((tmsize_t) size_io != size) + { + errno=EINVAL; + return (tmsize_t) -1; + } + fdh.h = fd; + return ((tmsize_t) write(fdh.fd, buf, size_io)); } -static toff_t -_tiffSeekProc(thandle_t fd, toff_t off, int whence) +static uint64 +_tiffSeekProc(thandle_t fd, uint64 off, int whence) { - return ((toff_t) lseek((int) fd, (off_t) off, whence)); + fd_as_handle_union_t fdh; + off_t off_io = (off_t) off; + if ((uint64) off_io != off) + { + errno=EINVAL; + return (uint64) -1; /* this is really gross */ + } + fdh.h = fd; + return((uint64)lseek(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 toff_t +static uint64 _tiffSizeProc(thandle_t fd) { -#ifdef _AM29K - long fsize; - return ((fsize = lseek((int) fd, 0, SEEK_END)) < 0 ? 0 : fsize); -#else struct stat sb; - return (toff_t) (fstat((int) fd, &sb) < 0 ? 0 : sb.st_size); -#endif + fd_as_handle_union_t fdh; + fdh.h = fd; + if (fstat(fdh.fd,&sb)<0) + return(0); + else + return((uint64)sb.st_size); } #ifdef HAVE_MMAP #include static int -_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) +_tiffMapProc(thandle_t fd, void** pbase, toff_t* psize) { - toff_t size = _tiffSizeProc(fd); - if (size != (toff_t) -1) { - *pbase = (tdata_t) - mmap(0, size, PROT_READ, MAP_SHARED, (int) fd, 0); - if (*pbase != (tdata_t) -1) { - *psize = size; + 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, fdh.fd, 0); + if (*pbase != (void*) -1) { + *psize = (tmsize_t)sizem; return (1); } } @@ -104,21 +145,21 @@ _tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) } static void -_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size) +_tiffUnmapProc(thandle_t fd, void* base, toff_t size) { (void) fd; (void) munmap(base, (off_t) size); } #else /* !HAVE_MMAP */ static int -_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) +_tiffMapProc(thandle_t fd, void** pbase, toff_t* psize) { (void) fd; (void) pbase; (void) psize; return (0); } static void -_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size) +_tiffUnmapProc(thandle_t fd, void* base, toff_t size) { (void) fd; (void) base; (void) size; } @@ -132,8 +173,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); @@ -150,24 +193,24 @@ TIFFOpen(const char* name, const char* mode) { static const char module[] = "TIFFOpen"; int m, fd; - TIFF* tif; + TIFF* tif; m = _TIFFgetMode(mode, module); if (m == -1) return ((TIFF*)0); -/* for cygwin and mingw */ +/* for cygwin and mingw */ #ifdef O_BINARY - m |= O_BINARY; -#endif - -#ifdef _AM29K - fd = open(name, m); -#else - fd = open(name, m, 0666); + m |= O_BINARY; #endif + + fd = open(name, m, 0666); if (fd < 0) { - TIFFErrorExt(0, module, "%s: Cannot open", name); + if (errno > 0 && strerror(errno) != NULL ) { + TIFFErrorExt(0, module, "%s: %s", name, strerror(errno) ); + } else { + TIFFErrorExt(0, module, "%s: Cannot open", name); + } return ((TIFF *)0); } @@ -195,11 +238,11 @@ TIFFOpenW(const wchar_t* name, const char* mode) if (m == -1) return ((TIFF*)0); -/* for cygwin and mingw */ +/* for cygwin and mingw */ #ifdef O_BINARY - m |= O_BINARY; -#endif - + m |= O_BINARY; +#endif + fd = _wopen(name, m, 0666); if (fd < 0) { TIFFErrorExt(0, module, "%s: Cannot open", name); @@ -232,37 +275,40 @@ TIFFOpenW(const wchar_t* name, const char* mode) #endif void* -_TIFFmalloc(tsize_t s) +_TIFFmalloc(tmsize_t s) { + if (s == 0) + return ((void *) NULL); + return (malloc((size_t) s)); } void -_TIFFfree(tdata_t p) +_TIFFfree(void* p) { free(p); } void* -_TIFFrealloc(tdata_t p, tsize_t s) +_TIFFrealloc(void* p, tmsize_t s) { return (realloc(p, (size_t) s)); } void -_TIFFmemset(tdata_t p, int v, tsize_t c) +_TIFFmemset(void* p, int v, tmsize_t c) { memset(p, v, (size_t) c); } void -_TIFFmemcpy(tdata_t d, const tdata_t s, tsize_t c) +_TIFFmemcpy(void* d, const void* s, tmsize_t c) { memcpy(d, s, (size_t) c); } int -_TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c) +_TIFFmemcmp(const void* p1, const void* p2, tmsize_t c) { return (memcmp(p1, p2, (size_t) c)); } @@ -287,6 +333,9 @@ unixErrorHandler(const char* module, const char* fmt, va_list ap) fprintf(stderr, ".\n"); } TIFFErrorHandler _TIFFerrorHandler = unixErrorHandler; + +/* vim: set ts=8 sts=8 sw=8 noet: */ + /* * Local Variables: * mode: c diff --git a/thirdparty/libtiff/tif_version.c b/thirdparty/libtiff/tif_version.c index 218dab56..f92c843d 100644 --- a/thirdparty/libtiff/tif_version.c +++ b/thirdparty/libtiff/tif_version.c @@ -1,4 +1,4 @@ -/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_version.c,v 1.2.2.1 2010-06-08 18:50:43 bfriesen Exp $ */ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_version.c,v 1.3 2010-03-10 18:56:49 bfriesen Exp $ */ /* * Copyright (c) 1992-1997 Sam Leffler * Copyright (c) 1992-1997 Silicon Graphics, Inc. diff --git a/thirdparty/libtiff/tif_warning.c b/thirdparty/libtiff/tif_warning.c index fe974d90..423b636e 100644 --- a/thirdparty/libtiff/tif_warning.c +++ b/thirdparty/libtiff/tif_warning.c @@ -1,4 +1,4 @@ -/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_warning.c,v 1.2.2.1 2010-06-08 18:50:43 bfriesen Exp $ */ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_warning.c,v 1.3 2010-03-10 18:56:49 bfriesen Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler diff --git a/thirdparty/libtiff/tif_win32.c b/thirdparty/libtiff/tif_win32.c index 2ab944b1..5d294746 100644 --- a/thirdparty/libtiff/tif_win32.c +++ b/thirdparty/libtiff/tif_win32.c @@ -1,4 +1,4 @@ -/* $Id: tif_win32.c,v 1.21.2.1 2010-06-08 18:50:43 bfriesen Exp $ */ +/* $Id: tif_win32.c,v 1.40 2012-11-18 17:51:52 bfriesen Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -32,49 +32,91 @@ #include -static tsize_t -_tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size) +static tmsize_t +_tiffReadProc(thandle_t fd, void* buf, tmsize_t size) { - DWORD dwSizeRead; - if (!ReadFile(fd, buf, size, &dwSizeRead, NULL)) - return(0); - return ((tsize_t) dwSizeRead); + /* tmsize_t is 64bit on 64bit systems, but the WinAPI ReadFile takes + * 32bit sizes, so we loop through the data in suitable 32bit sized + * chunks */ + uint8* ma; + uint64 mb; + DWORD n; + DWORD o; + tmsize_t p; + ma=(uint8*)buf; + mb=size; + p=0; + while (mb>0) + { + n=0x80000000UL; + if ((uint64)n>mb) + n=(DWORD)mb; + if (!ReadFile(fd,(LPVOID)ma,n,&o,NULL)) + return(0); + ma+=o; + mb-=o; + p+=o; + if (o!=n) + break; + } + return(p); } -static tsize_t -_tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size) +static tmsize_t +_tiffWriteProc(thandle_t fd, void* buf, tmsize_t size) { - DWORD dwSizeWritten; - if (!WriteFile(fd, buf, size, &dwSizeWritten, NULL)) - return(0); - return ((tsize_t) dwSizeWritten); + /* tmsize_t is 64bit on 64bit systems, but the WinAPI WriteFile takes + * 32bit sizes, so we loop through the data in suitable 32bit sized + * chunks */ + uint8* ma; + uint64 mb; + DWORD n; + DWORD o; + tmsize_t p; + ma=(uint8*)buf; + mb=size; + p=0; + while (mb>0) + { + n=0x80000000UL; + if ((uint64)n>mb) + n=(DWORD)mb; + if (!WriteFile(fd,(LPVOID)ma,n,&o,NULL)) + return(0); + ma+=o; + mb-=o; + p+=o; + if (o!=n) + break; + } + return(p); } -static toff_t -_tiffSeekProc(thandle_t fd, toff_t off, int whence) +static uint64 +_tiffSeekProc(thandle_t fd, uint64 off, int whence) { - ULARGE_INTEGER li; + LARGE_INTEGER offli; DWORD dwMoveMethod; - - li.QuadPart = off; - + offli.QuadPart = off; switch(whence) { - case SEEK_SET: - dwMoveMethod = FILE_BEGIN; - break; - case SEEK_CUR: - dwMoveMethod = FILE_CURRENT; - break; - case SEEK_END: - dwMoveMethod = FILE_END; - break; - default: - dwMoveMethod = FILE_BEGIN; - break; + case SEEK_SET: + dwMoveMethod = FILE_BEGIN; + break; + case SEEK_CUR: + dwMoveMethod = FILE_CURRENT; + break; + case SEEK_END: + dwMoveMethod = FILE_END; + break; + default: + dwMoveMethod = FILE_BEGIN; + break; } - return ((toff_t)SetFilePointer(fd, (LONG) li.LowPart, - (PLONG)&li.HighPart, dwMoveMethod)); + offli.LowPart=SetFilePointer(fd,offli.LowPart,&offli.HighPart,dwMoveMethod); + if ((offli.LowPart==INVALID_SET_FILE_POINTER)&&(GetLastError()!=NO_ERROR)) + offli.QuadPart=0; + return(offli.QuadPart); } static int @@ -83,14 +125,16 @@ _tiffCloseProc(thandle_t fd) return (CloseHandle(fd) ? 0 : -1); } -static toff_t +static uint64 _tiffSizeProc(thandle_t fd) { - return ((toff_t)GetFileSize(fd, NULL)); + ULARGE_INTEGER m; + m.LowPart=GetFileSize(fd,&m.HighPart); + return(m.QuadPart); } static int -_tiffDummyMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) +_tiffDummyMapProc(thandle_t fd, void** pbase, toff_t* psize) { (void) fd; (void) pbase; @@ -110,14 +154,20 @@ _tiffDummyMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) * with Visual C++ 5.0 */ static int -_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) +_tiffMapProc(thandle_t fd, void** pbase, toff_t* psize) { - toff_t size; + uint64 size; + tmsize_t sizem; HANDLE hMapFile; - if ((size = _tiffSizeProc(fd)) == 0xFFFFFFFF) + size = _tiffSizeProc(fd); + sizem = (tmsize_t)size; + if ((uint64)sizem!=size) return (0); - hMapFile = CreateFileMapping(fd, NULL, PAGE_READONLY, 0, size, NULL); + + /* By passing in 0 for the maximum file size, it specifies that we + create a file mapping object for the full file size. */ + hMapFile = CreateFileMapping(fd, NULL, PAGE_READONLY, 0, 0, NULL); if (hMapFile == NULL) return (0); *pbase = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0); @@ -129,7 +179,7 @@ _tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) } static void -_tiffDummyUnmapProc(thandle_t fd, tdata_t base, toff_t size) +_tiffDummyUnmapProc(thandle_t fd, void* base, toff_t size) { (void) fd; (void) base; @@ -137,8 +187,10 @@ _tiffDummyUnmapProc(thandle_t fd, tdata_t base, toff_t size) } static void -_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size) +_tiffUnmapProc(thandle_t fd, void* base, toff_t size) { + (void) fd; + (void) size; UnmapViewOfFile(base); } @@ -151,8 +203,17 @@ TIFF* TIFFFdOpen(int ifd, const char* name, const char* mode) { TIFF* tif; - BOOL fSuppressMap = (mode[1] == 'u' || (mode[1]!=0 && mode[2] == 'u')); - + int fSuppressMap; + int m; + fSuppressMap=0; + for (m=0; mode[m]!=0; m++) + { + if (mode[m]=='u') + { + fSuppressMap=1; + break; + } + } tif = TIFFClientOpen(name, mode, (thandle_t)ifd, _tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, @@ -179,26 +240,15 @@ TIFFOpen(const char* name, const char* mode) m = _TIFFgetMode(mode, module); - switch(m) - { - case O_RDONLY: - dwMode = OPEN_EXISTING; - break; - case O_RDWR: - dwMode = OPEN_ALWAYS; - break; - case O_RDWR|O_CREAT: - dwMode = OPEN_ALWAYS; - break; - case O_RDWR|O_TRUNC: - dwMode = CREATE_ALWAYS; - break; - case O_RDWR|O_CREAT|O_TRUNC: - dwMode = CREATE_ALWAYS; - break; - default: - return ((TIFF*)0); + switch(m) { + case O_RDONLY: dwMode = OPEN_EXISTING; break; + case O_RDWR: dwMode = OPEN_ALWAYS; break; + case O_RDWR|O_CREAT: dwMode = OPEN_ALWAYS; break; + case O_RDWR|O_TRUNC: dwMode = CREATE_ALWAYS; break; + case O_RDWR|O_CREAT|O_TRUNC: dwMode = CREATE_ALWAYS; break; + default: return ((TIFF*)0); } + fd = (thandle_t)CreateFileA(name, (m == O_RDONLY)?GENERIC_READ:(GENERIC_READ | GENERIC_WRITE), FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode, @@ -242,7 +292,7 @@ TIFFOpenW(const wchar_t* name, const char* mode) fd = (thandle_t)CreateFileW(name, (m == O_RDONLY)?GENERIC_READ:(GENERIC_READ|GENERIC_WRITE), - FILE_SHARE_READ, NULL, dwMode, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode, (m == O_RDONLY)?FILE_ATTRIBUTE_READONLY:FILE_ATTRIBUTE_NORMAL, NULL); if (fd == INVALID_HANDLE_VALUE) { @@ -276,71 +326,51 @@ TIFFOpenW(const wchar_t* name, const char* mode) #endif /* ndef _WIN32_WCE */ - -tdata_t -_TIFFmalloc(tsize_t s) +void* +_TIFFmalloc(tmsize_t s) { - return ((tdata_t)GlobalAlloc(GMEM_FIXED, s)); + if (s == 0) + return ((void *) NULL); + + return (malloc((size_t) s)); } void -_TIFFfree(tdata_t p) +_TIFFfree(void* p) { - GlobalFree(p); - return; + free(p); } -tdata_t -_TIFFrealloc(tdata_t p, tsize_t s) +void* +_TIFFrealloc(void* p, tmsize_t s) { - void* pvTmp; - tsize_t old; - - if(p == NULL) - return ((tdata_t)GlobalAlloc(GMEM_FIXED, s)); - - old = GlobalSize(p); - - if (old>=s) { - if ((pvTmp = GlobalAlloc(GMEM_FIXED, s)) != NULL) { - CopyMemory(pvTmp, p, s); - GlobalFree(p); - } - } else { - if ((pvTmp = GlobalAlloc(GMEM_FIXED, s)) != NULL) { - CopyMemory(pvTmp, p, old); - GlobalFree(p); - } - } - return ((tdata_t)pvTmp); + return (realloc(p, (size_t) s)); } void -_TIFFmemset(void* p, int v, tsize_t c) +_TIFFmemset(void* p, int v, tmsize_t c) { - FillMemory(p, c, (BYTE)v); + memset(p, v, (size_t) c); } void -_TIFFmemcpy(void* d, const tdata_t s, tsize_t c) +_TIFFmemcpy(void* d, const void* s, tmsize_t c) { - CopyMemory(d, s, c); + memcpy(d, s, (size_t) c); } int -_TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c) +_TIFFmemcmp(const void* p1, const void* p2, tmsize_t c) { - register const BYTE *pb1 = (const BYTE *) p1; - register const BYTE *pb2 = (const BYTE *) p2; - register DWORD dwTmp = c; - register int iTmp; - for (iTmp = 0; dwTmp-- && !iTmp; iTmp = (int)*pb1++ - (int)*pb2++) - ; - return (iTmp); + return (memcmp(p1, p2, (size_t) c)); } #ifndef _WIN32_WCE +#if (_MSC_VER < 1500) +# define vsnprintf _vsnprintf +#endif + static void Win32WarningHandler(const char* module, const char* fmt, va_list ap) { @@ -350,14 +380,17 @@ Win32WarningHandler(const char* module, const char* fmt, va_list ap) LPCTSTR szTitleText = "%s Warning"; LPCTSTR szDefaultModule = "LIBTIFF"; LPCTSTR szTmpModule = (module == NULL) ? szDefaultModule : module; - if ((szTitle = (LPTSTR)LocalAlloc(LMEM_FIXED, (strlen(szTmpModule) + - strlen(szTitleText) + strlen(fmt) + 128)*sizeof(char))) == NULL) + SIZE_T nBufSize = (strlen(szTmpModule) + + strlen(szTitleText) + strlen(fmt) + 256)*sizeof(char); + + if ((szTitle = (LPTSTR)LocalAlloc(LMEM_FIXED, nBufSize)) == NULL) return; sprintf(szTitle, szTitleText, szTmpModule); szTmp = szTitle + (strlen(szTitle)+2)*sizeof(char); - vsprintf(szTmp, fmt, ap); + vsnprintf(szTmp, nBufSize-(strlen(szTitle)+2)*sizeof(char), fmt, ap); MessageBoxA(GetFocus(), szTmp, szTitle, MB_OK | MB_ICONINFORMATION); LocalFree(szTitle); + return; #else if (module != NULL) @@ -378,12 +411,14 @@ Win32ErrorHandler(const char* module, const char* fmt, va_list ap) LPCTSTR szTitleText = "%s Error"; LPCTSTR szDefaultModule = "LIBTIFF"; LPCTSTR szTmpModule = (module == NULL) ? szDefaultModule : module; - if ((szTitle = (LPTSTR)LocalAlloc(LMEM_FIXED, (strlen(szTmpModule) + - strlen(szTitleText) + strlen(fmt) + 128)*sizeof(char))) == NULL) + SIZE_T nBufSize = (strlen(szTmpModule) + + strlen(szTitleText) + strlen(fmt) + 256)*sizeof(char); + + if ((szTitle = (LPTSTR)LocalAlloc(LMEM_FIXED, nBufSize)) == NULL) return; sprintf(szTitle, szTitleText, szTmpModule); szTmp = szTitle + (strlen(szTitle)+2)*sizeof(char); - vsprintf(szTmp, fmt, ap); + vsnprintf(szTmp, nBufSize-(strlen(szTitle)+2)*sizeof(char), fmt, ap); MessageBoxA(GetFocus(), szTmp, szTitle, MB_OK | MB_ICONEXCLAMATION); LocalFree(szTitle); return; diff --git a/thirdparty/libtiff/tif_write.c b/thirdparty/libtiff/tif_write.c index bd084181..7996c31e 100644 --- a/thirdparty/libtiff/tif_write.c +++ b/thirdparty/libtiff/tif_write.c @@ -1,26 +1,26 @@ -/* $Id: tif_write.c,v 1.22.2.5 2010-06-08 18:50:43 bfriesen Exp $ */ +/* $Id: tif_write.c,v 1.42 2015-06-07 23:00:23 bfriesen Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -32,26 +32,26 @@ #include "tiffiop.h" #include -#define STRIPINCR 20 /* expansion factor on strip array */ +#define STRIPINCR 20 /* expansion factor on strip array */ -#define WRITECHECKSTRIPS(tif, module) \ +#define WRITECHECKSTRIPS(tif, module) \ (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),0,module)) -#define WRITECHECKTILES(tif, module) \ +#define WRITECHECKTILES(tif, module) \ (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),1,module)) -#define BUFFERCHECK(tif) \ +#define BUFFERCHECK(tif) \ ((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) || \ - TIFFWriteBufferSetup((tif), NULL, (tsize_t) -1)) + TIFFWriteBufferSetup((tif), NULL, (tmsize_t) -1)) -static int TIFFGrowStrips(TIFF*, int, const char*); -static int TIFFAppendToStrip(TIFF*, tstrip_t, tidata_t, tsize_t); +static int TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module); +static int TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc); int -TIFFWriteScanline(TIFF* tif, tdata_t buf, uint32 row, tsample_t sample) +TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample) { static const char module[] = "TIFFWriteScanline"; register TIFFDirectory *td; int status, imagegrew = 0; - tstrip_t strip; + uint32 strip; if (!WRITECHECKSTRIPS(tif, module)) return (-1); @@ -62,6 +62,8 @@ TIFFWriteScanline(TIFF* tif, tdata_t buf, uint32 row, tsample_t sample) */ if (!BUFFERCHECK(tif)) return (-1); + tif->tif_flags |= TIFF_BUF4WRITE; /* not strictly sure this is right*/ + td = &tif->tif_dir; /* * Extend image length if needed @@ -69,8 +71,8 @@ TIFFWriteScanline(TIFF* tif, tdata_t buf, uint32 row, tsample_t sample) */ if (row >= td->td_imagelength) { /* extend image */ if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Can not change \"ImageLength\" when using separate planes"); + TIFFErrorExt(tif->tif_clientdata, module, + "Can not change \"ImageLength\" when using separate planes"); return (-1); } td->td_imagelength = row+1; @@ -81,9 +83,9 @@ TIFFWriteScanline(TIFF* tif, tdata_t buf, uint32 row, tsample_t sample) */ if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { if (sample >= td->td_samplesperpixel) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "%d: Sample out of range, max %d", - sample, td->td_samplesperpixel); + TIFFErrorExt(tif->tif_clientdata, module, + "%lu: Sample out of range, max %lu", + (unsigned long) sample, (unsigned long) td->td_samplesperpixel); return (-1); } strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip; @@ -112,7 +114,11 @@ TIFFWriteScanline(TIFF* tif, tdata_t buf, uint32 row, tsample_t sample) */ if (strip >= td->td_stripsperimage && imagegrew) td->td_stripsperimage = - TIFFhowmany(td->td_imagelength,td->td_rowsperstrip); + 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) { @@ -161,10 +167,10 @@ TIFFWriteScanline(TIFF* tif, tdata_t buf, uint32 row, tsample_t sample) tif->tif_row = row; } - /* swab if needed - note that source buffer will be altered */ - tif->tif_postdecode( tif, (tidata_t) buf, tif->tif_scanlinesize ); + /* swab if needed - note that source buffer will be altered */ + tif->tif_postdecode( tif, (uint8*) buf, tif->tif_scanlinesize ); - status = (*tif->tif_encoderow)(tif, (tidata_t) buf, + status = (*tif->tif_encoderow)(tif, (uint8*) buf, tif->tif_scanlinesize, sample); /* we are now poised at the beginning of the next row */ @@ -178,15 +184,15 @@ TIFFWriteScanline(TIFF* tif, tdata_t buf, uint32 row, tsample_t sample) * * NB: Image length must be setup before writing. */ -tsize_t -TIFFWriteEncodedStrip(TIFF* tif, tstrip_t strip, tdata_t data, tsize_t cc) +tmsize_t +TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc) { static const char module[] = "TIFFWriteEncodedStrip"; TIFFDirectory *td = &tif->tif_dir; - tsample_t sample; + uint16 sample; if (!WRITECHECKSTRIPS(tif, module)) - return ((tsize_t) -1); + return ((tmsize_t) -1); /* * Check strip array to make sure there's space. * We don't support dynamically growing files that @@ -198,14 +204,14 @@ TIFFWriteEncodedStrip(TIFF* tif, tstrip_t strip, tdata_t data, tsize_t cc) */ if (strip >= td->td_nstrips) { if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Can not grow image by strips when using separate planes"); - return ((tsize_t) -1); + TIFFErrorExt(tif->tif_clientdata, module, + "Can not grow image by strips when using separate planes"); + return ((tmsize_t) -1); } if (!TIFFGrowStrips(tif, 1, module)) - return ((tsize_t) -1); + return ((tmsize_t) -1); td->td_stripsperimage = - TIFFhowmany(td->td_imagelength, td->td_rowsperstrip); + TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip); } /* * Handle delayed allocation of data buffer. This @@ -213,43 +219,62 @@ TIFFWriteEncodedStrip(TIFF* tif, tstrip_t strip, tdata_t data, tsize_t cc) * info. */ if (!BUFFERCHECK(tif)) - return ((tsize_t) -1); + return ((tmsize_t) -1); + + 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)) - return ((tsize_t) -1); + return ((tmsize_t) -1); tif->tif_flags |= TIFF_CODERSETUP; } - - tif->tif_rawcc = 0; - tif->tif_rawcp = tif->tif_rawdata; - if( td->td_stripbytecount[strip] > 0 ) + 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; - sample = (tsample_t)(strip / td->td_stripsperimage); + sample = (uint16)(strip / td->td_stripsperimage); if (!(*tif->tif_preencode)(tif, sample)) - return ((tsize_t) -1); + return ((tmsize_t) -1); /* swab if needed - note that source buffer will be altered */ - tif->tif_postdecode( tif, (tidata_t) data, cc ); + tif->tif_postdecode( tif, (uint8*) data, cc ); - if (!(*tif->tif_encodestrip)(tif, (tidata_t) data, cc, sample)) - return ((tsize_t) 0); + if (!(*tif->tif_encodestrip)(tif, (uint8*) data, cc, sample)) + return (0); if (!(*tif->tif_postencode)(tif)) - return ((tsize_t) -1); + return ((tmsize_t) -1); if (!isFillOrder(tif, td->td_fillorder) && (tif->tif_flags & TIFF_NOBITREV) == 0) TIFFReverseBits(tif->tif_rawdata, tif->tif_rawcc); if (tif->tif_rawcc > 0 && !TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc)) - return ((tsize_t) -1); + return ((tmsize_t) -1); tif->tif_rawcc = 0; tif->tif_rawcp = tif->tif_rawdata; return (cc); @@ -260,14 +285,14 @@ TIFFWriteEncodedStrip(TIFF* tif, tstrip_t strip, tdata_t data, tsize_t cc) * * NB: Image length must be setup before writing. */ -tsize_t -TIFFWriteRawStrip(TIFF* tif, tstrip_t strip, tdata_t data, tsize_t cc) +tmsize_t +TIFFWriteRawStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc) { static const char module[] = "TIFFWriteRawStrip"; TIFFDirectory *td = &tif->tif_dir; if (!WRITECHECKSTRIPS(tif, module)) - return ((tsize_t) -1); + return ((tmsize_t) -1); /* * Check strip array to make sure there's space. * We don't support dynamically growing files that @@ -279,9 +304,9 @@ TIFFWriteRawStrip(TIFF* tif, tstrip_t strip, tdata_t data, tsize_t cc) */ if (strip >= td->td_nstrips) { if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, - "Can not grow image by strips when using separate planes"); - return ((tsize_t) -1); + TIFFErrorExt(tif->tif_clientdata, module, + "Can not grow image by strips when using separate planes"); + return ((tmsize_t) -1); } /* * Watch out for a growing image. The value of @@ -290,26 +315,29 @@ TIFFWriteRawStrip(TIFF* tif, tstrip_t strip, tdata_t data, tsize_t cc) */ if (strip >= td->td_stripsperimage) td->td_stripsperimage = - TIFFhowmany(td->td_imagelength,td->td_rowsperstrip); + TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip); if (!TIFFGrowStrips(tif, 1, module)) - return ((tsize_t) -1); + 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, (tidata_t) data, cc) ? - cc : (tsize_t) -1); + return (TIFFAppendToStrip(tif, strip, (uint8*) data, cc) ? + cc : (tmsize_t) -1); } /* * Write and compress a tile of data. The * tile is selected by the (x,y,z,s) coordinates. */ -tsize_t -TIFFWriteTile(TIFF* tif, - tdata_t buf, uint32 x, uint32 y, uint32 z, tsample_t s) +tmsize_t +TIFFWriteTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s) { if (!TIFFCheckTile(tif, x, y, z, s)) - return (-1); + return ((tmsize_t)(-1)); /* * NB: A tile size of -1 is used instead of tif_tilesize knowing * that TIFFWriteEncodedTile will clamp this to the tile size. @@ -317,7 +345,7 @@ TIFFWriteTile(TIFF* tif, * after the output buffer is setup in TIFFWriteBufferSetup. */ return (TIFFWriteEncodedTile(tif, - TIFFComputeTile(tif, x, y, z, s), buf, (tsize_t) -1)); + TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1))); } /* @@ -332,20 +360,21 @@ TIFFWriteTile(TIFF* tif, * interface does not support automatically growing * the image on each write (as TIFFWriteScanline does). */ -tsize_t -TIFFWriteEncodedTile(TIFF* tif, ttile_t tile, tdata_t data, tsize_t cc) +tmsize_t +TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc) { static const char module[] = "TIFFWriteEncodedTile"; TIFFDirectory *td; - tsample_t sample; + uint16 sample; + uint32 howmany32; if (!WRITECHECKTILES(tif, module)) - return ((tsize_t) -1); + return ((tmsize_t)(-1)); td = &tif->tif_dir; if (tile >= td->td_nstrips) { - TIFFErrorExt(tif->tif_clientdata, module, "%s: Tile %lu out of range, max %lu", - tif->tif_name, (unsigned long) tile, (unsigned long) td->td_nstrips); - return ((tsize_t) -1); + TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu", + (unsigned long) tile, (unsigned long) td->td_nstrips); + return ((tmsize_t)(-1)); } /* * Handle delayed allocation of data buffer. This @@ -353,37 +382,58 @@ TIFFWriteEncodedTile(TIFF* tif, ttile_t tile, tdata_t data, tsize_t cc) * directory information). */ if (!BUFFERCHECK(tif)) - return ((tsize_t) -1); + return ((tmsize_t)(-1)); + + 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 ) + 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(td->td_imagelength, td->td_tilelength)) - * td->td_tilelength; - tif->tif_col = (tile % TIFFhowmany(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)) - return ((tsize_t) -1); + return ((tmsize_t)(-1)); tif->tif_flags |= TIFF_CODERSETUP; } tif->tif_flags &= ~TIFF_POSTENCODE; - sample = (tsample_t)(tile/td->td_stripsperimage); + sample = (uint16)(tile/td->td_stripsperimage); if (!(*tif->tif_preencode)(tif, sample)) - return ((tsize_t) -1); + return ((tmsize_t)(-1)); /* * Clamp write amount to the tile size. This is mostly * done so that callers can pass in some large number @@ -393,18 +443,18 @@ TIFFWriteEncodedTile(TIFF* tif, ttile_t tile, tdata_t data, tsize_t cc) cc = tif->tif_tilesize; /* swab if needed - note that source buffer will be altered */ - tif->tif_postdecode( tif, (tidata_t) data, cc ); + tif->tif_postdecode( tif, (uint8*) data, cc ); - if (!(*tif->tif_encodetile)(tif, (tidata_t) data, cc, sample)) - return ((tsize_t) 0); + if (!(*tif->tif_encodetile)(tif, (uint8*) data, cc, sample)) + return (0); if (!(*tif->tif_postencode)(tif)) - return ((tsize_t) -1); + return ((tmsize_t)(-1)); if (!isFillOrder(tif, td->td_fillorder) && (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits((unsigned char *)tif->tif_rawdata, tif->tif_rawcc); + TIFFReverseBits((uint8*)tif->tif_rawdata, tif->tif_rawcc); if (tif->tif_rawcc > 0 && !TIFFAppendToStrip(tif, tile, tif->tif_rawdata, tif->tif_rawcc)) - return ((tsize_t) -1); + return ((tmsize_t)(-1)); tif->tif_rawcc = 0; tif->tif_rawcp = tif->tif_rawdata; return (cc); @@ -419,21 +469,21 @@ TIFFWriteEncodedTile(TIFF* tif, ttile_t tile, tdata_t data, tsize_t cc) * interface does not support automatically growing * the image on each write (as TIFFWriteScanline does). */ -tsize_t -TIFFWriteRawTile(TIFF* tif, ttile_t tile, tdata_t data, tsize_t cc) +tmsize_t +TIFFWriteRawTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc) { static const char module[] = "TIFFWriteRawTile"; if (!WRITECHECKTILES(tif, module)) - return ((tsize_t) -1); + return ((tmsize_t)(-1)); if (tile >= tif->tif_dir.td_nstrips) { - TIFFErrorExt(tif->tif_clientdata, module, "%s: Tile %lu out of range, max %lu", - tif->tif_name, (unsigned long) tile, + TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu", + (unsigned long) tile, (unsigned long) tif->tif_dir.td_nstrips); - return ((tsize_t) -1); + return ((tmsize_t)(-1)); } - return (TIFFAppendToStrip(tif, tile, (tidata_t) data, cc) ? - cc : (tsize_t) -1); + return (TIFFAppendToStrip(tif, tile, (uint8*) data, cc) ? + cc : (tmsize_t)(-1)); } #define isUnspecified(tif, f) \ @@ -455,18 +505,18 @@ TIFFSetupStrips(TIFF* tif) td->td_nstrips = td->td_stripsperimage; if (td->td_planarconfig == PLANARCONFIG_SEPARATE) td->td_stripsperimage /= td->td_samplesperpixel; - td->td_stripoffset = (uint32 *) - _TIFFmalloc(td->td_nstrips * sizeof (uint32)); - td->td_stripbytecount = (uint32 *) - _TIFFmalloc(td->td_nstrips * sizeof (uint32)); + td->td_stripoffset = (uint64 *) + _TIFFmalloc(td->td_nstrips * sizeof (uint64)); + td->td_stripbytecount = (uint64 *) + _TIFFmalloc(td->td_nstrips * sizeof (uint64)); if (td->td_stripoffset == NULL || td->td_stripbytecount == NULL) return (0); /* * Place data at the end-of-file * (by setting offsets to zero). */ - _TIFFmemset(td->td_stripoffset, 0, td->td_nstrips*sizeof (uint32)); - _TIFFmemset(td->td_stripbytecount, 0, td->td_nstrips*sizeof (uint32)); + _TIFFmemset(td->td_stripoffset, 0, td->td_nstrips*sizeof (uint64)); + _TIFFmemset(td->td_stripbytecount, 0, td->td_nstrips*sizeof (uint64)); TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS); TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS); return (1); @@ -483,16 +533,17 @@ int TIFFWriteCheck(TIFF* tif, int tiles, const char* module) { if (tif->tif_mode == O_RDONLY) { - TIFFErrorExt(tif->tif_clientdata, module, "%s: File not open for writing", - tif->tif_name); + TIFFErrorExt(tif->tif_clientdata, module, "File not open for writing"); return (0); } if (tiles ^ isTiled(tif)) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, tiles ? + TIFFErrorExt(tif->tif_clientdata, module, tiles ? "Can not write tiles to a stripped image" : "Can not write scanlines to a tiled image"); return (0); } + + _TIFFFillStriles( tif ); /* * On the first write verify all the required information @@ -506,8 +557,7 @@ TIFFWriteCheck(TIFF* tif, int tiles, const char* module) */ if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) { TIFFErrorExt(tif->tif_clientdata, module, - "%s: Must set \"ImageWidth\" before writing data", - tif->tif_name); + "Must set \"ImageWidth\" before writing data"); return (0); } if (tif->tif_dir.td_samplesperpixel == 1) { @@ -522,19 +572,27 @@ TIFFWriteCheck(TIFF* tif, int tiles, const char* module) } else { if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG)) { TIFFErrorExt(tif->tif_clientdata, module, - "%s: Must set \"PlanarConfiguration\" before writing data", - tif->tif_name); + "Must set \"PlanarConfiguration\" before writing data"); return (0); } } if (tif->tif_dir.td_stripoffset == NULL && !TIFFSetupStrips(tif)) { tif->tif_dir.td_nstrips = 0; - TIFFErrorExt(tif->tif_clientdata, module, "%s: No space for %s arrays", - tif->tif_name, isTiled(tif) ? "tile" : "strip"); + TIFFErrorExt(tif->tif_clientdata, module, "No space for %s arrays", + isTiled(tif) ? "tile" : "strip"); return (0); } - tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tsize_t) -1; + if (isTiled(tif)) + { + tif->tif_tilesize = TIFFTileSize(tif); + if (tif->tif_tilesize == 0) + return (0); + } + else + tif->tif_tilesize = (tmsize_t)(-1); tif->tif_scanlinesize = TIFFScanlineSize(tif); + if (tif->tif_scanlinesize == 0) + return (0); tif->tif_flags |= TIFF_BEENWRITING; return (1); } @@ -543,7 +601,7 @@ TIFFWriteCheck(TIFF* tif, int tiles, const char* module) * Setup the raw data buffer used for encoding. */ int -TIFFWriteBufferSetup(TIFF* tif, tdata_t bp, tsize_t size) +TIFFWriteBufferSetup(TIFF* tif, void* bp, tmsize_t size) { static const char module[] = "TIFFWriteBufferSetup"; @@ -554,7 +612,7 @@ TIFFWriteBufferSetup(TIFF* tif, tdata_t bp, tsize_t size) } tif->tif_rawdata = NULL; } - if (size == (tsize_t) -1) { + if (size == (tmsize_t)(-1)) { size = (isTiled(tif) ? tif->tif_tilesize : TIFFStripSize(tif)); /* @@ -567,14 +625,13 @@ TIFFWriteBufferSetup(TIFF* tif, tdata_t bp, tsize_t size) if (bp == NULL) { bp = _TIFFmalloc(size); if (bp == NULL) { - TIFFErrorExt(tif->tif_clientdata, module, "%s: No space for output buffer", - tif->tif_name); + TIFFErrorExt(tif->tif_clientdata, module, "No space for output buffer"); return (0); } tif->tif_flags |= TIFF_MYBUFFER; } else tif->tif_flags &= ~TIFF_MYBUFFER; - tif->tif_rawdata = (tidata_t) bp; + tif->tif_rawdata = (uint8*) bp; tif->tif_rawdatasize = size; tif->tif_rawcc = 0; tif->tif_rawcp = tif->tif_rawdata; @@ -586,33 +643,35 @@ TIFFWriteBufferSetup(TIFF* tif, tdata_t bp, tsize_t size) * Grow the strip data structures by delta strips. */ static int -TIFFGrowStrips(TIFF* tif, int delta, const char* module) +TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module) { - TIFFDirectory *td = &tif->tif_dir; - uint32 *new_stripoffset, *new_stripbytecount; + TIFFDirectory *td = &tif->tif_dir; + uint64* new_stripoffset; + uint64* new_stripbytecount; assert(td->td_planarconfig == PLANARCONFIG_CONTIG); - new_stripoffset = (uint32*)_TIFFrealloc(td->td_stripoffset, - (td->td_nstrips + delta) * sizeof (uint32)); - new_stripbytecount = (uint32*)_TIFFrealloc(td->td_stripbytecount, - (td->td_nstrips + delta) * sizeof (uint32)); + new_stripoffset = (uint64*)_TIFFrealloc(td->td_stripoffset, + (td->td_nstrips + delta) * sizeof (uint64)); + new_stripbytecount = (uint64*)_TIFFrealloc(td->td_stripbytecount, + (td->td_nstrips + delta) * sizeof (uint64)); if (new_stripoffset == NULL || new_stripbytecount == NULL) { if (new_stripoffset) _TIFFfree(new_stripoffset); if (new_stripbytecount) _TIFFfree(new_stripbytecount); td->td_nstrips = 0; - TIFFErrorExt(tif->tif_clientdata, module, "%s: No space to expand strip arrays", - tif->tif_name); + TIFFErrorExt(tif->tif_clientdata, module, "No space to expand strip arrays"); return (0); } td->td_stripoffset = new_stripoffset; td->td_stripbytecount = new_stripbytecount; _TIFFmemset(td->td_stripoffset + td->td_nstrips, - 0, delta*sizeof (uint32)); + 0, delta*sizeof (uint64)); _TIFFmemset(td->td_stripbytecount + td->td_nstrips, - 0, delta*sizeof (uint32)); + 0, delta*sizeof (uint64)); td->td_nstrips += delta; + tif->tif_flags |= TIFF_DIRTYDIRECT; + return (1); } @@ -620,21 +679,23 @@ TIFFGrowStrips(TIFF* tif, int delta, const char* module) * Append the data to the specified strip. */ static int -TIFFAppendToStrip(TIFF* tif, tstrip_t strip, tidata_t data, tsize_t cc) +TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc) { static const char module[] = "TIFFAppendToStrip"; TIFFDirectory *td = &tif->tif_dir; + uint64 m; + int64 old_byte_count = -1; if (td->td_stripoffset[strip] == 0 || tif->tif_curoff == 0) { assert(td->td_nstrips > 0); if( td->td_stripbytecount[strip] != 0 && td->td_stripoffset[strip] != 0 - && td->td_stripbytecount[strip] >= cc ) + && td->td_stripbytecount[strip] >= (uint64) cc ) { /* * There is already tile data on disk, and the new tile - * data we have to will fit in the same space. The only + * data we have will fit in the same space. The only * aspect of this that is risky is that there could be * more data to append to this strip before we are done * depending on how we are getting called. @@ -653,6 +714,7 @@ TIFFAppendToStrip(TIFF* tif, tstrip_t strip, tidata_t data, tsize_t cc) * write this strip. */ td->td_stripoffset[strip] = TIFFSeekFile(tif, 0, SEEK_END); + tif->tif_flags |= TIFF_DIRTYSTRIP; } tif->tif_curoff = td->td_stripoffset[strip]; @@ -660,16 +722,29 @@ TIFFAppendToStrip(TIFF* tif, tstrip_t strip, tidata_t data, tsize_t cc) /* * We are starting a fresh strip/tile, so set the size to zero. */ + old_byte_count = td->td_stripbytecount[strip]; td->td_stripbytecount[strip] = 0; } + m = tif->tif_curoff+cc; + if (!(tif->tif_flags&TIFF_BIGTIFF)) + m = (uint32)m; + if ((mtif_curoff)||(m<(uint64)cc)) + { + TIFFErrorExt(tif->tif_clientdata, module, "Maximum TIFF file size exceeded"); + return (0); + } if (!WriteOK(tif, data, cc)) { TIFFErrorExt(tif->tif_clientdata, module, "Write error at scanline %lu", (unsigned long) tif->tif_row); return (0); } - tif->tif_curoff = tif->tif_curoff+cc; + tif->tif_curoff = m; td->td_stripbytecount[strip] += cc; + + if( (int64) td->td_stripbytecount[strip] != old_byte_count ) + tif->tif_flags |= TIFF_DIRTYSTRIP; + return (1); } @@ -681,10 +756,10 @@ TIFFAppendToStrip(TIFF* tif, tstrip_t strip, tidata_t data, tsize_t cc) int TIFFFlushData1(TIFF* tif) { - if (tif->tif_rawcc > 0) { + if (tif->tif_rawcc > 0 && tif->tif_flags & TIFF_BUF4WRITE ) { if (!isFillOrder(tif, tif->tif_dir.td_fillorder) && (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits((unsigned char *)tif->tif_rawdata, + TIFFReverseBits((uint8*)tif->tif_rawdata, tif->tif_rawcc); if (!TIFFAppendToStrip(tif, isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip, diff --git a/thirdparty/libtiff/tif_zip.c b/thirdparty/libtiff/tif_zip.c index 15091f8d..22e9f35b 100644 --- a/thirdparty/libtiff/tif_zip.c +++ b/thirdparty/libtiff/tif_zip.c @@ -1,4 +1,4 @@ -/* $Id: tif_zip.c,v 1.11.2.4 2010-06-08 18:50:43 bfriesen Exp $ */ +/* $Id: tif_zip.c,v 1.33 2014-12-25 18:29:11 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,45 +61,54 @@ #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. */ -typedef struct { +typedef struct { TIFFPredictorState predict; - z_stream stream; - int zipquality; /* compression level */ - int state; /* state flags */ + z_stream stream; + int zipquality; /* compression level */ + int state; /* state flags */ #define ZSTATE_INIT_DECODE 0x01 #define ZSTATE_INIT_ENCODE 0x02 - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ } ZIPState; -#define ZState(tif) ((ZIPState*) (tif)->tif_data) -#define DecoderState(tif) ZState(tif) -#define EncoderState(tif) ZState(tif) +#define ZState(tif) ((ZIPState*) (tif)->tif_data) +#define DecoderState(tif) ZState(tif) +#define EncoderState(tif) ZState(tif) -static int ZIPEncode(TIFF*, tidata_t, tsize_t, tsample_t); -static int ZIPDecode(TIFF*, tidata_t, tsize_t, tsample_t); +static int ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s); +static int ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s); + +static int +ZIPFixupTags(TIFF* tif) +{ + (void) tif; + return (1); +} static int ZIPSetupDecode(TIFF* tif) { - ZIPState* sp = DecoderState(tif); static const char module[] = "ZIPSetupDecode"; + ZIPState* sp = DecoderState(tif); assert(sp != NULL); /* if we were last encoding, terminate this mode */ if (sp->state & ZSTATE_INIT_ENCODE) { - deflateEnd(&sp->stream); - sp->state = 0; - } + deflateEnd(&sp->stream); + sp->state = 0; + } if (inflateInit(&sp->stream) != Z_OK) { - TIFFErrorExt(tif->tif_clientdata, module, "%s: %s", tif->tif_name, sp->stream.msg); + TIFFErrorExt(tif->tif_clientdata, module, "%s", SAFE_MSG(sp)); return (0); } else { sp->state |= ZSTATE_INIT_DECODE; @@ -111,74 +120,100 @@ ZIPSetupDecode(TIFF* tif) * Setup state for decoding a strip. */ static int -ZIPPreDecode(TIFF* tif, tsample_t s) +ZIPPreDecode(TIFF* tif, uint16 s) { + static const char module[] = "ZIPPreDecode"; ZIPState* sp = DecoderState(tif); (void) s; assert(sp != NULL); - if( (sp->state & ZSTATE_INIT_DECODE) == 0 ) + if( (sp->state & ZSTATE_INIT_DECODE) == 0 ) tif->tif_setupdecode( tif ); sp->stream.next_in = tif->tif_rawdata; - sp->stream.avail_in = tif->tif_rawcc; + 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 */ + sp->stream.avail_in = (uInt) tif->tif_rawcc; + if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc) + { + TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size"); + return (0); + } return (inflateReset(&sp->stream) == Z_OK); } static int -ZIPDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) +ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) { - ZIPState* sp = DecoderState(tif); static const char module[] = "ZIPDecode"; + ZIPState* sp = DecoderState(tif); (void) s; assert(sp != NULL); - assert(sp->state == ZSTATE_INIT_DECODE); + assert(sp->state == ZSTATE_INIT_DECODE); + sp->stream.next_in = tif->tif_rawcp; + sp->stream.avail_in = (uInt) tif->tif_rawcc; + sp->stream.next_out = op; - sp->stream.avail_out = occ; + 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 = (uInt) occ; + if ((tmsize_t)sp->stream.avail_out != occ) + { + TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size"); + return (0); + } do { int state = inflate(&sp->stream, Z_PARTIAL_FLUSH); if (state == Z_STREAM_END) break; if (state == Z_DATA_ERROR) { TIFFErrorExt(tif->tif_clientdata, module, - "%s: Decoding error at scanline %d, %s", - tif->tif_name, tif->tif_row, sp->stream.msg); + "Decoding error at scanline %lu, %s", + (unsigned long) tif->tif_row, SAFE_MSG(sp)); if (inflateSync(&sp->stream) != Z_OK) return (0); continue; } if (state != Z_OK) { - TIFFErrorExt(tif->tif_clientdata, module, "%s: zlib error: %s", - tif->tif_name, sp->stream.msg); + TIFFErrorExt(tif->tif_clientdata, module, + "ZLib error: %s", SAFE_MSG(sp)); return (0); } } while (sp->stream.avail_out > 0); if (sp->stream.avail_out != 0) { TIFFErrorExt(tif->tif_clientdata, module, - "%s: Not enough data at scanline %d (short %d bytes)", - tif->tif_name, tif->tif_row, sp->stream.avail_out); + "Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT " bytes)", + (unsigned long) tif->tif_row, (TIFF_UINT64_T) sp->stream.avail_out); return (0); } + + tif->tif_rawcp = sp->stream.next_in; + tif->tif_rawcc = sp->stream.avail_in; + return (1); } static int ZIPSetupEncode(TIFF* tif) { - ZIPState* sp = EncoderState(tif); static const char module[] = "ZIPSetupEncode"; + ZIPState* sp = EncoderState(tif); assert(sp != NULL); if (sp->state & ZSTATE_INIT_DECODE) { - inflateEnd(&sp->stream); - sp->state = 0; - } + inflateEnd(&sp->stream); + sp->state = 0; + } if (deflateInit(&sp->stream, sp->zipquality) != Z_OK) { - TIFFErrorExt(tif->tif_clientdata, module, "%s: %s", tif->tif_name, sp->stream.msg); + TIFFErrorExt(tif->tif_clientdata, module, "%s", SAFE_MSG(sp)); return (0); } else { sp->state |= ZSTATE_INIT_ENCODE; @@ -190,17 +225,27 @@ ZIPSetupEncode(TIFF* tif) * Reset encoding state at the start of a strip. */ static int -ZIPPreEncode(TIFF* tif, tsample_t s) +ZIPPreEncode(TIFF* tif, uint16 s) { + static const char module[] = "ZIPPreEncode"; ZIPState *sp = EncoderState(tif); (void) s; assert(sp != NULL); - if( sp->state != ZSTATE_INIT_ENCODE ) + if( sp->state != ZSTATE_INIT_ENCODE ) tif->tif_setupencode( tif ); sp->stream.next_out = tif->tif_rawdata; + 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; + if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) + { + TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size"); + return (0); + } return (deflateReset(&sp->stream) == Z_OK); } @@ -208,28 +253,38 @@ ZIPPreEncode(TIFF* tif, tsample_t s) * Encode a chunk of pixels. */ static int -ZIPEncode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) { - ZIPState *sp = EncoderState(tif); static const char module[] = "ZIPEncode"; + ZIPState *sp = EncoderState(tif); - assert(sp != NULL); - assert(sp->state == ZSTATE_INIT_ENCODE); + assert(sp != NULL); + assert(sp->state == ZSTATE_INIT_ENCODE); (void) s; sp->stream.next_in = bp; - sp->stream.avail_in = cc; + 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 */ + sp->stream.avail_in = (uInt) cc; + if ((tmsize_t)sp->stream.avail_in != cc) + { + TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size"); + return (0); + } do { if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) { - TIFFErrorExt(tif->tif_clientdata, module, "%s: Encoder error: %s", - tif->tif_name, sp->stream.msg); + TIFFErrorExt(tif->tif_clientdata, module, + "Encoder error: %s", + SAFE_MSG(sp)); return (0); } if (sp->stream.avail_out == 0) { tif->tif_rawcc = tif->tif_rawdatasize; TIFFFlushData1(tif); sp->stream.next_out = tif->tif_rawdata; - sp->stream.avail_out = tif->tif_rawdatasize; + sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in ZIPPreEncode */ } } while (sp->stream.avail_in > 0); return (1); @@ -242,8 +297,8 @@ ZIPEncode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) static int ZIPPostEncode(TIFF* tif) { - ZIPState *sp = EncoderState(tif); static const char module[] = "ZIPPostEncode"; + ZIPState *sp = EncoderState(tif); int state; sp->stream.avail_in = 0; @@ -252,19 +307,18 @@ ZIPPostEncode(TIFF* tif) switch (state) { case Z_STREAM_END: case Z_OK: - if ((int)sp->stream.avail_out != (int)tif->tif_rawdatasize) - { - tif->tif_rawcc = - tif->tif_rawdatasize - sp->stream.avail_out; - TIFFFlushData1(tif); - sp->stream.next_out = tif->tif_rawdata; - sp->stream.avail_out = tif->tif_rawdatasize; - } - break; + if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) + { + tif->tif_rawcc = tif->tif_rawdatasize - sp->stream.avail_out; + TIFFFlushData1(tif); + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in ZIPPreEncode */ + } + break; default: - TIFFErrorExt(tif->tif_clientdata, module, "%s: zlib error: %s", - tif->tif_name, sp->stream.msg); - return (0); + TIFFErrorExt(tif->tif_clientdata, module, + "ZLib error: %s", SAFE_MSG(sp)); + return (0); } } while (state != Z_STREAM_END); return (1); @@ -283,11 +337,11 @@ ZIPCleanup(TIFF* tif) tif->tif_tagmethods.vsetfield = sp->vsetparent; if (sp->state & ZSTATE_INIT_ENCODE) { - deflateEnd(&sp->stream); - sp->state = 0; - } else if( sp->state & ZSTATE_INIT_DECODE) { - inflateEnd(&sp->stream); - sp->state = 0; + deflateEnd(&sp->stream); + sp->state = 0; + } else if( sp->state & ZSTATE_INIT_DECODE) { + inflateEnd(&sp->stream); + sp->state = 0; } _TIFFfree(sp); tif->tif_data = NULL; @@ -296,19 +350,19 @@ ZIPCleanup(TIFF* tif) } static int -ZIPVSetField(TIFF* tif, ttag_t tag, va_list ap) +ZIPVSetField(TIFF* tif, uint32 tag, va_list ap) { - ZIPState* sp = ZState(tif); static const char module[] = "ZIPVSetField"; + ZIPState* sp = ZState(tif); switch (tag) { case TIFFTAG_ZIPQUALITY: - sp->zipquality = va_arg(ap, int); + sp->zipquality = (int) va_arg(ap, int); if ( sp->state&ZSTATE_INIT_ENCODE ) { if (deflateParams(&sp->stream, sp->zipquality, Z_DEFAULT_STRATEGY) != Z_OK) { - TIFFErrorExt(tif->tif_clientdata, module, "%s: zlib error: %s", - tif->tif_name, sp->stream.msg); + TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", + SAFE_MSG(sp)); return (0); } } @@ -320,7 +374,7 @@ ZIPVSetField(TIFF* tif, ttag_t tag, va_list ap) } static int -ZIPVGetField(TIFF* tif, ttag_t tag, va_list ap) +ZIPVGetField(TIFF* tif, uint32 tag, va_list ap) { ZIPState* sp = ZState(tif); @@ -334,9 +388,8 @@ ZIPVGetField(TIFF* tif, ttag_t tag, va_list ap) return (1); } -static const TIFFFieldInfo zipFieldInfo[] = { - { TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, FIELD_PSEUDO, - TRUE, FALSE, "" }, +static const TIFFField zipFields[] = { + { TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL }, }; int @@ -351,8 +404,7 @@ TIFFInitZIP(TIFF* tif, int scheme) /* * Merge codec-specific tag information. */ - if (!_TIFFMergeFieldInfo(tif, zipFieldInfo, - TIFFArrayCount(zipFieldInfo))) { + if (!_TIFFMergeFields(tif, zipFields, TIFFArrayCount(zipFields))) { TIFFErrorExt(tif->tif_clientdata, module, "Merging Deflate codec-specific tags failed"); return 0; @@ -361,7 +413,7 @@ TIFFInitZIP(TIFF* tif, int scheme) /* * Allocate state block so tag methods have storage to record values. */ - tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (ZIPState)); + tif->tif_data = (uint8*) _TIFFmalloc(sizeof (ZIPState)); if (tif->tif_data == NULL) goto bad; sp = ZState(tif); @@ -385,11 +437,12 @@ TIFFInitZIP(TIFF* tif, int scheme) /* * Install codec methods. */ + tif->tif_fixuptags = ZIPFixupTags; tif->tif_setupdecode = ZIPSetupDecode; tif->tif_predecode = ZIPPreDecode; tif->tif_decoderow = ZIPDecode; tif->tif_decodestrip = ZIPDecode; - tif->tif_decodetile = ZIPDecode; + tif->tif_decodetile = ZIPDecode; tif->tif_setupencode = ZIPSetupEncode; tif->tif_preencode = ZIPPreEncode; tif->tif_postencode = ZIPPostEncode; diff --git a/thirdparty/libtiff/tiff.h b/thirdparty/libtiff/tiff.h index 0d4ab9f8..bc46acd0 100644 --- a/thirdparty/libtiff/tiff.h +++ b/thirdparty/libtiff/tiff.h @@ -1,4 +1,4 @@ -/* $Id: tiff.h,v 1.43.2.1 2010-06-08 18:50:43 bfriesen Exp $ */ +/* $Id: tiff.h,v 1.69 2014-04-02 17:23:06 fwarmerdam Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -39,87 +39,75 @@ * Suite 200 * Seattle, WA 98104 * 206-622-5500 - * + * * (http://partners.adobe.com/asn/developer/PDFS/TN/TIFF6.pdf) * - * For Big TIFF design notes see the following link + * For BigTIFF design notes see the following links * http://www.remotesensing.org/libtiff/bigtiffdesign.html + * http://www.awaresystems.be/imaging/tiff/bigtiff.html */ -#define TIFF_VERSION 42 -#define TIFF_BIGTIFF_VERSION 43 -#define TIFF_BIGENDIAN 0x4d4d -#define TIFF_LITTLEENDIAN 0x4949 -#define MDI_LITTLEENDIAN 0x5045 -#define MDI_BIGENDIAN 0x4550 +#define TIFF_VERSION_CLASSIC 42 +#define TIFF_VERSION_BIG 43 + +#define TIFF_BIGENDIAN 0x4d4d +#define TIFF_LITTLEENDIAN 0x4949 +#define MDI_LITTLEENDIAN 0x5045 +#define MDI_BIGENDIAN 0x4550 + /* * Intrinsic data types required by the file format: * - * 8-bit quantities int8/uint8 - * 16-bit quantities int16/uint16 - * 32-bit quantities int32/uint32 - * strings unsigned char* + * 8-bit quantities int8/uint8 + * 16-bit quantities int16/uint16 + * 32-bit quantities int32/uint32 + * 64-bit quantities int64/uint64 + * strings unsigned char* */ -#ifndef HAVE_INT8 -typedef signed char int8; /* NB: non-ANSI compilers may not grok */ -#endif -typedef unsigned char uint8; -#ifndef HAVE_INT16 -typedef short int16; -#endif -typedef unsigned short uint16; /* sizeof (uint16) must == 2 */ -#if SIZEOF_INT == 4 -#ifndef HAVE_INT32 -typedef int int32; -#endif -typedef unsigned int uint32; /* sizeof (uint32) must == 4 */ -#elif SIZEOF_LONG == 4 -#ifndef HAVE_INT32 -typedef long int32; -#endif -typedef unsigned long uint32; /* sizeof (uint32) must == 4 */ -#endif +typedef TIFF_INT8_T int8; +typedef TIFF_UINT8_T uint8; -/* For TIFFReassignTagToIgnore */ -enum TIFFIgnoreSense /* IGNORE tag table */ -{ - TIS_STORE, - TIS_EXTRACT, - TIS_EMPTY -}; +typedef TIFF_INT16_T int16; +typedef TIFF_UINT16_T uint16; + +typedef TIFF_INT32_T int32; +typedef TIFF_UINT32_T uint32; + +typedef TIFF_INT64_T int64; +typedef TIFF_UINT64_T uint64; + +/* + * Some types as promoted in a variable argument list + * We use uint16_vap rather then directly using int, because this way + * we document the type we actually want to pass through, conceptually, + * rather then confusing the issue by merely stating the type it gets + * promoted to + */ + +typedef int uint16_vap; /* * TIFF header. */ -typedef struct { - uint16 tiff_magic; /* magic number (defines byte order) */ -#define TIFF_MAGIC_SIZE 2 - uint16 tiff_version; /* TIFF version number */ -#define TIFF_VERSION_SIZE 2 - uint32 tiff_diroff; /* byte offset to first directory */ -#define TIFF_DIROFFSET_SIZE 4 -} TIFFHeader; +typedef struct { + uint16 tiff_magic; /* magic number (defines byte order) */ + uint16 tiff_version; /* TIFF version number */ +} TIFFHeaderCommon; +typedef struct { + uint16 tiff_magic; /* magic number (defines byte order) */ + uint16 tiff_version; /* TIFF version number */ + uint32 tiff_diroff; /* byte offset to first directory */ +} TIFFHeaderClassic; +typedef struct { + uint16 tiff_magic; /* magic number (defines byte order) */ + uint16 tiff_version; /* TIFF version number */ + uint16 tiff_offsetsize; /* size of offsets, should be 8 */ + uint16 tiff_unused; /* unused word, should be 0 */ + uint64 tiff_diroff; /* byte offset to first directory */ +} TIFFHeaderBig; -/* - * TIFF Image File Directories are comprised of a table of field - * descriptors of the form shown below. The table is sorted in - * ascending order by tag. The values associated with each entry are - * disjoint and may appear anywhere in the file (so long as they are - * placed on a word boundary). - * - * If the value is 4 bytes or less, then it is placed in the offset - * field to save space. If the value is less than 4 bytes, it is - * left-justified in the offset field. - */ -typedef struct { - uint16 tdir_tag; /* see below */ - uint16 tdir_type; /* data type; see below */ - uint32 tdir_count; /* number of items; length in spec */ - uint32 tdir_offset; /* byte offset to field data */ -} TIFFDirEntry; - /* * NB: In the comments below, * - items marked with a + are obsoleted by revision 5.0, @@ -134,21 +122,24 @@ typedef struct { * * Note: RATIONALs are the ratio of two 32-bit integer values. */ -typedef enum { - TIFF_NOTYPE = 0, /* placeholder */ - TIFF_BYTE = 1, /* 8-bit unsigned integer */ - TIFF_ASCII = 2, /* 8-bit bytes w/ last byte null */ - TIFF_SHORT = 3, /* 16-bit unsigned integer */ - TIFF_LONG = 4, /* 32-bit unsigned integer */ - TIFF_RATIONAL = 5, /* 64-bit unsigned fraction */ - TIFF_SBYTE = 6, /* !8-bit signed integer */ - TIFF_UNDEFINED = 7, /* !8-bit untyped data */ - TIFF_SSHORT = 8, /* !16-bit signed integer */ - TIFF_SLONG = 9, /* !32-bit signed integer */ - TIFF_SRATIONAL = 10, /* !64-bit signed fraction */ - TIFF_FLOAT = 11, /* !32-bit IEEE floating point */ - TIFF_DOUBLE = 12, /* !64-bit IEEE floating point */ - TIFF_IFD = 13 /* %32-bit unsigned integer (offset) */ +typedef enum { + TIFF_NOTYPE = 0, /* placeholder */ + TIFF_BYTE = 1, /* 8-bit unsigned integer */ + TIFF_ASCII = 2, /* 8-bit bytes w/ last byte null */ + TIFF_SHORT = 3, /* 16-bit unsigned integer */ + TIFF_LONG = 4, /* 32-bit unsigned integer */ + TIFF_RATIONAL = 5, /* 64-bit unsigned fraction */ + TIFF_SBYTE = 6, /* !8-bit signed integer */ + TIFF_UNDEFINED = 7, /* !8-bit untyped data */ + TIFF_SSHORT = 8, /* !16-bit signed integer */ + TIFF_SLONG = 9, /* !32-bit signed integer */ + TIFF_SRATIONAL = 10, /* !64-bit signed fraction */ + TIFF_FLOAT = 11, /* !32-bit IEEE floating point */ + TIFF_DOUBLE = 12, /* !64-bit IEEE floating point */ + TIFF_IFD = 13, /* %32-bit unsigned integer (offset) */ + TIFF_LONG8 = 16, /* BigTIFF 64-bit unsigned integer */ + TIFF_SLONG8 = 17, /* BigTIFF 64-bit signed integer */ + TIFF_IFD8 = 18 /* BigTIFF 64-bit unsigned integer (offset) */ } TIFFDataType; /* @@ -175,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 */ @@ -196,6 +189,7 @@ typedef enum { #define COMPRESSION_SGILOG 34676 /* SGI Log Luminance RLE */ #define COMPRESSION_SGILOG24 34677 /* SGI Log 24-bit packed */ #define COMPRESSION_JP2000 34712 /* Leadtools JPEG2000 */ +#define COMPRESSION_LZMA 34925 /* LZMA2 */ #define TIFFTAG_PHOTOMETRIC 262 /* photometric interpretation */ #define PHOTOMETRIC_MINISWHITE 0 /* min value is white */ #define PHOTOMETRIC_MINISBLACK 1 /* min value is black */ @@ -207,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 */ @@ -327,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. @@ -348,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 */ @@ -383,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 */ @@ -414,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 */ @@ -576,6 +599,10 @@ typedef enum { #define TIFFTAG_SGILOGENCODE 65561 /* SGILog data encoding control*/ #define SGILOGENCODE_NODITHER 0 /* do not dither encoded values*/ #define SGILOGENCODE_RANDITHER 1 /* randomly dither encd values */ +#define TIFFTAG_LZMAPRESET 65562 /* LZMA2 preset (compression level) */ +#define TIFFTAG_PERSAMPLE 65563 /* interface for per sample tags */ +#define PERSAMPLE_MERGED 0 /* present as a single value */ +#define PERSAMPLE_MULTI 1 /* present as multiple values */ /* * EXIF tags diff --git a/thirdparty/libtiff/tiffconf.h.cmake.in b/thirdparty/libtiff/tiffconf.h.cmake.in new file mode 100644 index 00000000..53a66d41 --- /dev/null +++ b/thirdparty/libtiff/tiffconf.h.cmake.in @@ -0,0 +1,79 @@ +/* + 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_ + +#include "tif_config.h" +#if defined( HAVE_STDINT_H ) +#include +#endif + +/* Define as 0 or 1 according to the floating point format suported by the + machine */ +#define HAVE_IEEEFP 1 + +/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */ +#define HOST_FILLORDER FILLORDER_LSB2MSB + +/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian + (Intel) */ +#define HOST_BIGENDIAN 0 + +/* Support CCITT Group 3 & 4 algorithms */ +#define CCITT_SUPPORT 1 + +/* Support LogLuv high dynamic range encoding */ +#define LOGLUV_SUPPORT 1 + +/* Support LZW algorithm */ +#define LZW_SUPPORT 1 + +/* Support NeXT 2-bit RLE algorithm */ +#define NEXT_SUPPORT 1 + +/* Support Old JPEG compresson (read contrib/ojpeg/README first! Compilation + fails with unpatched IJG JPEG library) */ +/* #undef OJPEG_SUPPORT */ + +/* Support Macintosh PackBits algorithm */ +#define PACKBITS_SUPPORT 1 + +/* Support ThunderScan 4-bit RLE algorithm */ +#define THUNDER_SUPPORT 1 + +/* Support strip chopping (whether or not to convert single-strip uncompressed + images to mutiple strips of ~8Kb to reduce memory usage) */ +#define STRIPCHOP_DEFAULT TIFF_STRIPCHOP + +/* Enable SubIFD tag (330) support */ +#define 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. */ +/*#define DEFAULT_EXTRASAMPLE_AS_ALPHA 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 + +/* Support MS MDI magic number files as TIFF */ +#define 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_ */ diff --git a/thirdparty/libtiff/tiffconf.h b/thirdparty/libtiff/tiffconf.h.in similarity index 65% rename from thirdparty/libtiff/tiffconf.h rename to thirdparty/libtiff/tiffconf.h.in index 68dfcf01..6da9c5a6 100644 --- a/thirdparty/libtiff/tiffconf.h +++ b/thirdparty/libtiff/tiffconf.h.in @@ -7,100 +7,110 @@ #ifndef _TIFFCONF_ #define _TIFFCONF_ -/* Define to 1 if the system has the type `int16'. */ -/* #undef HAVE_INT16 */ +/* Signed 16-bit type */ +#undef TIFF_INT16_T -/* Define to 1 if the system has the type `int32'. */ -/* #undef HAVE_INT32 */ - -/* Define to 1 if the system has the type `int8'. */ -/* #undef HAVE_INT8 */ - -/* The size of a `int', as computed by sizeof. */ -#define SIZEOF_INT 4 - -/* The size of a `long', as computed by sizeof. */ -#define SIZEOF_LONG 4 - -/* Signed 64-bit type formatter */ -#define TIFF_INT64_FORMAT "%I64d" +/* Signed 32-bit type */ +#undef TIFF_INT32_T /* Signed 64-bit type */ -#ifdef _MSC_VER -#define TIFF_INT64_T signed __int64 -#else -#define TIFF_INT64_T long long -#endif +#undef TIFF_INT64_T -/* Unsigned 64-bit type formatter */ -#define TIFF_UINT64_FORMAT "%I64u" +/* Signed 8-bit type */ +#undef TIFF_INT8_T + +/* Unsigned 16-bit type */ +#undef TIFF_UINT16_T + +/* Unsigned 32-bit type */ +#undef TIFF_UINT32_T /* Unsigned 64-bit type */ -#ifdef _MSC_VER -#define TIFF_UINT64_T unsigned __int64 -#else -#define TIFF_UINT64_T unsigned long long -#endif +#undef TIFF_UINT64_T + +/* Unsigned 8-bit type */ +#undef TIFF_UINT8_T + +/* Signed size type */ +#undef TIFF_SSIZE_T + +/* Pointer difference type */ +#undef TIFF_PTRDIFF_T + +/* Define to 1 if the system has the type `int16'. */ +#undef HAVE_INT16 + +/* Define to 1 if the system has the type `int32'. */ +#undef HAVE_INT32 + +/* Define to 1 if the system has the type `int8'. */ +#undef HAVE_INT8 /* Compatibility stuff. */ /* Define as 0 or 1 according to the floating point format suported by the machine */ -#define HAVE_IEEEFP 1 +#undef HAVE_IEEEFP /* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */ -#define HOST_FILLORDER FILLORDER_LSB2MSB +#undef HOST_FILLORDER /* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian (Intel) */ -#define HOST_BIGENDIAN 0 +#undef HOST_BIGENDIAN /* Support CCITT Group 3 & 4 algorithms */ -#define CCITT_SUPPORT 1 +#undef CCITT_SUPPORT /* Support JPEG compression (requires IJG JPEG library) */ -/* #undef JPEG_SUPPORT */ +#undef JPEG_SUPPORT + +/* Support JBIG compression (requires JBIG-KIT library) */ +#undef JBIG_SUPPORT /* Support LogLuv high dynamic range encoding */ -#define LOGLUV_SUPPORT 1 +#undef LOGLUV_SUPPORT /* Support LZW algorithm */ -#define LZW_SUPPORT 1 +#undef LZW_SUPPORT /* Support NeXT 2-bit RLE algorithm */ -#define NEXT_SUPPORT 1 +#undef NEXT_SUPPORT /* Support Old JPEG compresson (read contrib/ojpeg/README first! Compilation fails with unpatched IJG JPEG library) */ -/* #undef OJPEG_SUPPORT */ +#undef OJPEG_SUPPORT /* Support Macintosh PackBits algorithm */ -#define PACKBITS_SUPPORT 1 +#undef PACKBITS_SUPPORT /* Support Pixar log-format algorithm (requires Zlib) */ -/* #undef PIXARLOG_SUPPORT */ +#undef PIXARLOG_SUPPORT /* Support ThunderScan 4-bit RLE algorithm */ -#define THUNDER_SUPPORT 1 +#undef THUNDER_SUPPORT /* Support Deflate compression */ -/* #undef ZIP_SUPPORT */ +#undef ZIP_SUPPORT /* Support strip chopping (whether or not to convert single-strip uncompressed images to mutiple strips of ~8Kb to reduce memory usage) */ -#define STRIPCHOP_DEFAULT TIFF_STRIPCHOP +#undef STRIPCHOP_DEFAULT /* Enable SubIFD tag (330) support */ -#define SUBIFD_SUPPORT 1 +#undef SUBIFD_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 +#undef DEFAULT_EXTRASAMPLE_AS_ALPHA /* Pick up YCbCr subsampling info from the JPEG data stream to support files lacking the tag (default enabled). */ -#define CHECK_JPEG_YCBCR_SUBSAMPLING 1 +#undef CHECK_JPEG_YCBCR_SUBSAMPLING + +/* Support MS MDI magic number files as TIFF */ +#undef MDI_SUPPORT /* * Feature support definitions. @@ -115,10 +125,3 @@ #define IPTC_SUPPORT #endif /* _TIFFCONF_ */ -/* - * Local Variables: - * mode: c - * c-basic-offset: 8 - * fill-column: 78 - * End: - */ diff --git a/thirdparty/libtiff/tiffio.h b/thirdparty/libtiff/tiffio.h index 36e4997a..038b6701 100644 --- a/thirdparty/libtiff/tiffio.h +++ b/thirdparty/libtiff/tiffio.h @@ -1,21 +1,21 @@ -/* $Id: tiffio.h,v 1.56.2.4 2010-06-08 18:50:43 bfriesen Exp $ */ +/* $Id: tiffio.h,v 1.91 2012-07-29 15:45:29 tgl Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, @@ -37,7 +37,7 @@ * TIFF is defined as an incomplete type to hide the * library's internal data structures from clients. */ -typedef struct tiff TIFF; +typedef struct tiff TIFF; /* * The following typedefs define the intrinsic size of @@ -55,18 +55,27 @@ typedef struct tiff TIFF; * NB: tsize_t is int32 and not uint32 because some functions * return -1. * NB: toff_t is not off_t for many reasons; TIFFs max out at - * 32-bit file offsets being the most important, and to ensure - * that it is unsigned, rather than signed. + * 32-bit file offsets, and BigTIFF maxes out at 64-bit + * offsets being the most important, and to ensure use of + * a consistently unsigned type across architectures. + * Prior to libtiff 4.0, this was an unsigned 32 bit type. */ +/* + * this is the machine addressing size type, only it's signed, so make it + * int32 on 32bit machines, int64 on 64bit machines + */ +typedef TIFF_SSIZE_T tmsize_t; +typedef uint64 toff_t; /* file offset */ +/* the following are deprecated and should be replaced by their defining + counterparts */ typedef uint32 ttag_t; /* directory tag */ typedef uint16 tdir_t; /* directory index */ typedef uint16 tsample_t; /* sample number */ typedef uint32 tstrile_t; /* strip or tile number */ typedef tstrile_t tstrip_t; /* strip number */ typedef tstrile_t ttile_t; /* tile number */ -typedef size_t tsize_t; /* i/o size in bytes */ +typedef tmsize_t tsize_t; /* i/o size in bytes */ typedef void* tdata_t; /* image data ref */ -typedef uint32 toff_t; /* file offset */ #if !defined(__WIN32__) && (defined(_WIN32) || defined(WIN32)) #define __WIN32__ @@ -89,12 +98,12 @@ typedef uint32 toff_t; /* file offset */ # define VC_EXTRALEAN # include # ifdef __WIN32__ -DECLARE_HANDLE(thandle_t); /* Win32 file handle */ +DECLARE_HANDLE(thandle_t); /* Win32 file handle */ # else -typedef HFILE thandle_t; /* client data handle */ +typedef HFILE thandle_t; /* client data handle */ # endif /* __WIN32__ */ #else -typedef void* thandle_t; /* client data handle */ +typedef void* thandle_t; /* client data handle */ #endif /* USE_WIN32_FILEIO */ /* @@ -103,13 +112,13 @@ typedef void* thandle_t; /* client data handle */ * very large. Bit-or these flags to enable printing * multiple items. */ -#define TIFFPRINT_NONE 0x0 /* no extra info */ -#define TIFFPRINT_STRIPS 0x1 /* strips/tiles info */ -#define TIFFPRINT_CURVES 0x2 /* color/gray response curves */ -#define TIFFPRINT_COLORMAP 0x4 /* colormap */ -#define TIFFPRINT_JPEGQTABLES 0x100 /* JPEG Q matrices */ -#define TIFFPRINT_JPEGACTABLES 0x200 /* JPEG AC tables */ -#define TIFFPRINT_JPEGDCTABLES 0x200 /* JPEG DC tables */ +#define TIFFPRINT_NONE 0x0 /* no extra info */ +#define TIFFPRINT_STRIPS 0x1 /* strips/tiles info */ +#define TIFFPRINT_CURVES 0x2 /* color/gray response curves */ +#define TIFFPRINT_COLORMAP 0x4 /* colormap */ +#define TIFFPRINT_JPEGQTABLES 0x100 /* JPEG Q matrices */ +#define TIFFPRINT_JPEGACTABLES 0x200 /* JPEG AC tables */ +#define TIFFPRINT_JPEGDCTABLES 0x200 /* JPEG DC tables */ /* * Colour conversion stuff @@ -126,42 +135,42 @@ typedef void* thandle_t; /* client data handle */ /* Structure for holding information about a display device. */ -typedef unsigned char TIFFRGBValue; /* 8-bit samples */ +typedef unsigned char TIFFRGBValue; /* 8-bit samples */ typedef struct { - float d_mat[3][3]; /* XYZ -> luminance matrix */ - float d_YCR; /* Light o/p for reference white */ + float d_mat[3][3]; /* XYZ -> luminance matrix */ + float d_YCR; /* Light o/p for reference white */ float d_YCG; float d_YCB; - uint32 d_Vrwr; /* Pixel values for ref. white */ + uint32 d_Vrwr; /* Pixel values for ref. white */ uint32 d_Vrwg; uint32 d_Vrwb; - float d_Y0R; /* Residual light for black pixel */ + float d_Y0R; /* Residual light for black pixel */ float d_Y0G; float d_Y0B; - float d_gammaR; /* Gamma values for the three guns */ + float d_gammaR; /* Gamma values for the three guns */ float d_gammaG; float d_gammaB; } TIFFDisplay; -typedef struct { /* YCbCr->RGB support */ - TIFFRGBValue* clamptab; /* range clamping table */ - int* Cr_r_tab; - int* Cb_b_tab; - int32* Cr_g_tab; - int32* Cb_g_tab; - int32* Y_tab; +typedef struct { /* YCbCr->RGB support */ + TIFFRGBValue* clamptab; /* range clamping table */ + int* Cr_r_tab; + int* Cb_b_tab; + int32* Cr_g_tab; + int32* Cb_g_tab; + int32* Y_tab; } TIFFYCbCrToRGB; -typedef struct { /* CIE Lab 1976->RGB support */ - int range; /* Size of conversion table */ +typedef struct { /* CIE Lab 1976->RGB support */ + int range; /* Size of conversion table */ #define CIELABTORGB_TABLE_RANGE 1500 - float rstep, gstep, bstep; - float X0, Y0, Z0; /* Reference white point */ + float rstep, gstep, bstep; + float X0, Y0, Z0; /* Reference white point */ TIFFDisplay display; - float Yr2r[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yr to r */ - float Yg2g[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yg to g */ - float Yb2b[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yb to b */ + float Yr2r[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yr to r */ + float Yg2g[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yg to g */ + float Yb2b[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yb to b */ } TIFFCIELabToRGB; /* @@ -216,6 +225,9 @@ 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* Bitdepth16To8; /* LUT for conversion from 16bit to 8bit values */ + int row_offset; int col_offset; }; @@ -224,10 +236,10 @@ struct _TIFFRGBAImage { * Macros for extracting components from the * packed ABGR form returned by TIFFReadRGBAImage. */ -#define TIFFGetR(abgr) ((abgr) & 0xff) -#define TIFFGetG(abgr) (((abgr) >> 8) & 0xff) -#define TIFFGetB(abgr) (((abgr) >> 16) & 0xff) -#define TIFFGetA(abgr) (((abgr) >> 24) & 0xff) +#define TIFFGetR(abgr) ((abgr) & 0xff) +#define TIFFGetG(abgr) (((abgr) >> 8) & 0xff) +#define TIFFGetB(abgr) (((abgr) >> 16) & 0xff) +#define TIFFGetA(abgr) (((abgr) >> 24) & 0xff) /* * A CODEC is a software package that implements decoding, @@ -236,11 +248,11 @@ struct _TIFFRGBAImage { * More codecs may be registered through calls to the library * and/or the builtin implementations may be overridden. */ -typedef int (*TIFFInitMethod)(TIFF*, int); +typedef int (*TIFFInitMethod)(TIFF*, int); typedef struct { - char* name; - uint16 scheme; - TIFFInitMethod init; + char* name; + uint16 scheme; + TIFFInitMethod init; } TIFFCodec; #include @@ -248,7 +260,7 @@ typedef struct { /* share internal LogLuv conversion routines? */ #ifndef LOGLUV_PUBLIC -#define LOGLUV_PUBLIC 1 +#define LOGLUV_PUBLIC 1 #endif #if !defined(__GNUC__) && !defined(__attribute__) @@ -258,48 +270,264 @@ typedef struct { #if defined(c_plusplus) || defined(__cplusplus) extern "C" { #endif -typedef void (*TIFFErrorHandler)(const char*, const char*, va_list); -typedef void (*TIFFErrorHandlerExt)(thandle_t, const char*, const char*, va_list); -typedef tsize_t (*TIFFReadWriteProc)(thandle_t, tdata_t, tsize_t); -typedef toff_t (*TIFFSeekProc)(thandle_t, toff_t, int); -typedef int (*TIFFCloseProc)(thandle_t); -typedef toff_t (*TIFFSizeProc)(thandle_t); -typedef int (*TIFFMapFileProc)(thandle_t, tdata_t*, toff_t*); -typedef void (*TIFFUnmapFileProc)(thandle_t, tdata_t, toff_t); -typedef void (*TIFFExtendProc)(TIFF*); +typedef void (*TIFFErrorHandler)(const char*, const char*, va_list); +typedef void (*TIFFErrorHandlerExt)(thandle_t, const char*, const char*, va_list); +typedef tmsize_t (*TIFFReadWriteProc)(thandle_t, void*, tmsize_t); +typedef toff_t (*TIFFSeekProc)(thandle_t, toff_t, int); +typedef int (*TIFFCloseProc)(thandle_t); +typedef toff_t (*TIFFSizeProc)(thandle_t); +typedef int (*TIFFMapFileProc)(thandle_t, void** base, toff_t* size); +typedef void (*TIFFUnmapFileProc)(thandle_t, void* base, toff_t size); +typedef void (*TIFFExtendProc)(TIFF*); -extern const char* TIFFGetVersion(void); +extern const char* TIFFGetVersion(void); -extern const TIFFCodec* TIFFFindCODEC(uint16); -extern TIFFCodec* TIFFRegisterCODEC(uint16, const char*, TIFFInitMethod); -extern void TIFFUnRegisterCODEC(TIFFCodec*); -extern int TIFFIsCODECConfigured(uint16); -extern TIFFCodec* TIFFGetConfiguredCODECs(void); +extern const TIFFCodec* TIFFFindCODEC(uint16); +extern TIFFCodec* TIFFRegisterCODEC(uint16, const char*, TIFFInitMethod); +extern void TIFFUnRegisterCODEC(TIFFCodec*); +extern int TIFFIsCODECConfigured(uint16); +extern TIFFCodec* TIFFGetConfiguredCODECs(void); /* * Auxiliary functions. */ -extern tdata_t _TIFFmalloc(tsize_t); -extern tdata_t _TIFFrealloc(tdata_t, tsize_t); -extern void _TIFFmemset(tdata_t, int, tsize_t); -extern void _TIFFmemcpy(tdata_t, const tdata_t, tsize_t); -extern int _TIFFmemcmp(const tdata_t, const tdata_t, tsize_t); -extern void _TIFFfree(tdata_t); +extern void* _TIFFmalloc(tmsize_t s); +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); +extern int _TIFFmemcmp(const void* p1, const void* p2, tmsize_t c); +extern void _TIFFfree(void* p); /* ** Stuff, related to tag handling and creating custom tags. */ -extern int TIFFGetTagListCount( TIFF * ); -extern ttag_t TIFFGetTagListEntry( TIFF *, int tag_index ); +extern int TIFFGetTagListCount( TIFF * ); +extern uint32 TIFFGetTagListEntry( TIFF *, int tag_index ); -#define TIFF_ANY TIFF_NOTYPE /* for field descriptor searching */ -#define TIFF_VARIABLE -1 /* marker for variable length tags */ -#define TIFF_SPP -2 /* marker for SamplesPerPixel tags */ -#define TIFF_VARIABLE2 -3 /* marker for uint32 var-length tags */ +#define TIFF_ANY TIFF_NOTYPE /* for field descriptor searching */ +#define TIFF_VARIABLE -1 /* marker for variable length tags */ +#define TIFF_SPP -2 /* marker for SamplesPerPixel tags */ +#define TIFF_VARIABLE2 -3 /* marker for uint32 var-length tags */ -#define FIELD_CUSTOM 65 +#define FIELD_CUSTOM 65 +typedef struct _TIFFField TIFFField; +typedef struct _TIFFFieldArray TIFFFieldArray; + +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); + +typedef struct { + TIFFVSetMethod vsetfield; /* tag set routine */ + TIFFVGetMethod vgetfield; /* tag get routine */ + TIFFPrintMethod printdir; /* directory print routine */ +} TIFFTagMethods; + +extern TIFFTagMethods *TIFFAccessTagMethods(TIFF *); +extern void *TIFFGetClientInfo(TIFF *, const char *); +extern void TIFFSetClientInfo(TIFF *, void *, const char *); + +extern void TIFFCleanup(TIFF* tif); +extern void TIFFClose(TIFF* tif); +extern int TIFFFlush(TIFF* tif); +extern int TIFFFlushData(TIFF* tif); +extern int TIFFGetField(TIFF* tif, uint32 tag, ...); +extern int TIFFVGetField(TIFF* tif, uint32 tag, va_list ap); +extern int TIFFGetFieldDefaulted(TIFF* tif, uint32 tag, ...); +extern int TIFFVGetFieldDefaulted(TIFF* tif, uint32 tag, va_list ap); +extern int TIFFReadDirectory(TIFF* tif); +extern int TIFFReadCustomDirectory(TIFF* tif, toff_t diroff, const TIFFFieldArray* infoarray); +extern int TIFFReadEXIFDirectory(TIFF* tif, toff_t diroff); +extern uint64 TIFFScanlineSize64(TIFF* tif); +extern tmsize_t TIFFScanlineSize(TIFF* tif); +extern uint64 TIFFRasterScanlineSize64(TIFF* tif); +extern tmsize_t TIFFRasterScanlineSize(TIFF* tif); +extern uint64 TIFFStripSize64(TIFF* tif); +extern tmsize_t TIFFStripSize(TIFF* tif); +extern uint64 TIFFRawStripSize64(TIFF* tif, uint32 strip); +extern tmsize_t TIFFRawStripSize(TIFF* tif, uint32 strip); +extern uint64 TIFFVStripSize64(TIFF* tif, uint32 nrows); +extern tmsize_t TIFFVStripSize(TIFF* tif, uint32 nrows); +extern uint64 TIFFTileRowSize64(TIFF* tif); +extern tmsize_t TIFFTileRowSize(TIFF* tif); +extern uint64 TIFFTileSize64(TIFF* tif); +extern tmsize_t TIFFTileSize(TIFF* tif); +extern uint64 TIFFVTileSize64(TIFF* tif, uint32 nrows); +extern tmsize_t TIFFVTileSize(TIFF* tif, uint32 nrows); +extern uint32 TIFFDefaultStripSize(TIFF* tif, uint32 request); +extern void TIFFDefaultTileSize(TIFF*, uint32*, uint32*); +extern int TIFFFileno(TIFF*); +extern int TIFFSetFileno(TIFF*, int); +extern thandle_t TIFFClientdata(TIFF*); +extern thandle_t TIFFSetClientdata(TIFF*, thandle_t); +extern int TIFFGetMode(TIFF*); +extern int TIFFSetMode(TIFF*, int); +extern int TIFFIsTiled(TIFF*); +extern int TIFFIsByteSwapped(TIFF*); +extern int TIFFIsUpSampled(TIFF*); +extern int TIFFIsMSB2LSB(TIFF*); +extern int TIFFIsBigEndian(TIFF*); +extern TIFFReadWriteProc TIFFGetReadProc(TIFF*); +extern TIFFReadWriteProc TIFFGetWriteProc(TIFF*); +extern TIFFSeekProc TIFFGetSeekProc(TIFF*); +extern TIFFCloseProc TIFFGetCloseProc(TIFF*); +extern TIFFSizeProc TIFFGetSizeProc(TIFF*); +extern TIFFMapFileProc TIFFGetMapFileProc(TIFF*); +extern TIFFUnmapFileProc TIFFGetUnmapFileProc(TIFF*); +extern uint32 TIFFCurrentRow(TIFF*); +extern uint16 TIFFCurrentDirectory(TIFF*); +extern uint16 TIFFNumberOfDirectories(TIFF*); +extern uint64 TIFFCurrentDirOffset(TIFF*); +extern uint32 TIFFCurrentStrip(TIFF*); +extern uint32 TIFFCurrentTile(TIFF* tif); +extern int TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size); +extern int TIFFWriteBufferSetup(TIFF* tif, void* bp, tmsize_t size); +extern int TIFFSetupStrips(TIFF *); +extern int TIFFWriteCheck(TIFF*, int, const char *); +extern void TIFFFreeDirectory(TIFF*); +extern int TIFFCreateDirectory(TIFF*); +extern int TIFFCreateCustomDirectory(TIFF*,const TIFFFieldArray*); +extern int TIFFCreateEXIFDirectory(TIFF*); +extern int TIFFLastDirectory(TIFF*); +extern int TIFFSetDirectory(TIFF*, uint16); +extern int TIFFSetSubDirectory(TIFF*, uint64); +extern int TIFFUnlinkDirectory(TIFF*, uint16); +extern int TIFFSetField(TIFF*, uint32, ...); +extern int TIFFVSetField(TIFF*, uint32, va_list); +extern int TIFFUnsetField(TIFF*, uint32); +extern int TIFFWriteDirectory(TIFF *); +extern int TIFFWriteCustomDirectory(TIFF *, uint64 *); +extern int TIFFCheckpointDirectory(TIFF *); +extern int TIFFRewriteDirectory(TIFF *); + +#if defined(c_plusplus) || defined(__cplusplus) +extern void TIFFPrintDirectory(TIFF*, FILE*, long = 0); +extern int TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample = 0); +extern int TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample = 0); +extern int TIFFReadRGBAImage(TIFF*, uint32, uint32, uint32*, int = 0); +extern int TIFFReadRGBAImageOriented(TIFF*, uint32, uint32, uint32*, + int = ORIENTATION_BOTLEFT, int = 0); +#else +extern void TIFFPrintDirectory(TIFF*, FILE*, long); +extern int TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample); +extern int TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample); +extern int TIFFReadRGBAImage(TIFF*, uint32, uint32, uint32*, int); +extern int TIFFReadRGBAImageOriented(TIFF*, uint32, uint32, uint32*, int, int); +#endif + +extern int TIFFReadRGBAStrip(TIFF*, uint32, uint32 * ); +extern int TIFFReadRGBATile(TIFF*, uint32, uint32, uint32 * ); +extern int TIFFRGBAImageOK(TIFF*, char [1024]); +extern int TIFFRGBAImageBegin(TIFFRGBAImage*, TIFF*, int, char [1024]); +extern int TIFFRGBAImageGet(TIFFRGBAImage*, uint32*, uint32, uint32); +extern void TIFFRGBAImageEnd(TIFFRGBAImage*); +extern TIFF* TIFFOpen(const char*, const char*); +# ifdef __WIN32__ +extern TIFF* TIFFOpenW(const wchar_t*, const char*); +# endif /* __WIN32__ */ +extern TIFF* TIFFFdOpen(int, const char*, const char*); +extern TIFF* TIFFClientOpen(const char*, const char*, + thandle_t, + TIFFReadWriteProc, TIFFReadWriteProc, + TIFFSeekProc, TIFFCloseProc, + TIFFSizeProc, + TIFFMapFileProc, TIFFUnmapFileProc); +extern const char* TIFFFileName(TIFF*); +extern const char* TIFFSetFileName(TIFF*, const char *); +extern void TIFFError(const char*, const char*, ...) __attribute__((__format__ (__printf__,2,3))); +extern void TIFFErrorExt(thandle_t, const char*, const char*, ...) __attribute__((__format__ (__printf__,3,4))); +extern void TIFFWarning(const char*, const char*, ...) __attribute__((__format__ (__printf__,2,3))); +extern void TIFFWarningExt(thandle_t, const char*, const char*, ...) __attribute__((__format__ (__printf__,3,4))); +extern TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler); +extern TIFFErrorHandlerExt TIFFSetErrorHandlerExt(TIFFErrorHandlerExt); +extern TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler); +extern TIFFErrorHandlerExt TIFFSetWarningHandlerExt(TIFFErrorHandlerExt); +extern TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc); +extern uint32 TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s); +extern int TIFFCheckTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s); +extern uint32 TIFFNumberOfTiles(TIFF*); +extern tmsize_t TIFFReadTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s); +extern tmsize_t TIFFWriteTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s); +extern uint32 TIFFComputeStrip(TIFF*, uint32, uint16); +extern uint32 TIFFNumberOfStrips(TIFF*); +extern tmsize_t TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size); +extern tmsize_t TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size); +extern tmsize_t TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size); +extern tmsize_t TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size); +extern tmsize_t TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc); +extern tmsize_t TIFFWriteRawStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc); +extern tmsize_t TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc); +extern tmsize_t TIFFWriteRawTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc); +extern int TIFFDataWidth(TIFFDataType); /* table of tag datatype widths */ +extern void TIFFSetWriteOffset(TIFF* tif, toff_t off); +extern void TIFFSwabShort(uint16*); +extern void TIFFSwabLong(uint32*); +extern void TIFFSwabLong8(uint64*); +extern void TIFFSwabFloat(float*); +extern void TIFFSwabDouble(double*); +extern void TIFFSwabArrayOfShort(uint16* wp, tmsize_t n); +extern void TIFFSwabArrayOfTriples(uint8* tp, tmsize_t n); +extern void TIFFSwabArrayOfLong(uint32* lp, tmsize_t n); +extern void TIFFSwabArrayOfLong8(uint64* lp, tmsize_t n); +extern void TIFFSwabArrayOfFloat(float* fp, tmsize_t n); +extern void TIFFSwabArrayOfDouble(double* dp, tmsize_t n); +extern void TIFFReverseBits(uint8* cp, tmsize_t n); +extern const unsigned char* TIFFGetBitRevTable(int); + +#ifdef LOGLUV_PUBLIC +#define U_NEU 0.210526316 +#define V_NEU 0.473684211 +#define UVSCALE 410. +extern double LogL16toY(int); +extern double LogL10toY(int); +extern void XYZtoRGB24(float*, uint8*); +extern int uv_decode(double*, double*, int); +extern void LogLuv24toXYZ(uint32, float*); +extern void LogLuv32toXYZ(uint32, float*); +#if defined(c_plusplus) || defined(__cplusplus) +extern int LogL16fromY(double, int = SGILOGENCODE_NODITHER); +extern int LogL10fromY(double, int = SGILOGENCODE_NODITHER); +extern int uv_encode(double, double, int = SGILOGENCODE_NODITHER); +extern uint32 LogLuv24fromXYZ(float*, int = SGILOGENCODE_NODITHER); +extern uint32 LogLuv32fromXYZ(float*, int = SGILOGENCODE_NODITHER); +#else +extern int LogL16fromY(double, int); +extern int LogL10fromY(double, int); +extern int uv_encode(double, double, int); +extern uint32 LogLuv24fromXYZ(float*, int); +extern uint32 LogLuv32fromXYZ(float*, int); +#endif +#endif /* LOGLUV_PUBLIC */ + +extern int TIFFCIELabToRGBInit(TIFFCIELabToRGB*, const TIFFDisplay *, float*); +extern void TIFFCIELabToXYZ(TIFFCIELabToRGB *, uint32, int32, int32, + float *, float *, float *); +extern void TIFFXYZToRGB(TIFFCIELabToRGB *, float, float, float, + uint32 *, uint32 *, uint32 *); + +extern int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB*, float*, float*); +extern void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *, uint32, int32, int32, + uint32 *, uint32 *, uint32 *); + +/**************************************************************************** + * O B S O L E T E D I N T E R F A C E S + * + * Don't use this stuff in your applications, it may be removed in the future + * libtiff versions. + ****************************************************************************/ typedef struct { ttag_t field_tag; /* field's tag */ short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */ @@ -311,205 +539,8 @@ typedef struct { char *field_name; /* ASCII name */ } TIFFFieldInfo; -typedef struct _TIFFTagValue { - const TIFFFieldInfo *info; - int count; - void *value; -} TIFFTagValue; - -extern void TIFFMergeFieldInfo(TIFF*, const TIFFFieldInfo[], int); -extern const TIFFFieldInfo* TIFFFindFieldInfo(TIFF*, ttag_t, TIFFDataType); -extern const TIFFFieldInfo* TIFFFindFieldInfoByName(TIFF* , const char *, - TIFFDataType); -extern const TIFFFieldInfo* TIFFFieldWithTag(TIFF*, ttag_t); -extern const TIFFFieldInfo* TIFFFieldWithName(TIFF*, const char *); - -typedef int (*TIFFVSetMethod)(TIFF*, ttag_t, va_list); -typedef int (*TIFFVGetMethod)(TIFF*, ttag_t, va_list); -typedef void (*TIFFPrintMethod)(TIFF*, FILE*, long); - -typedef struct { - TIFFVSetMethod vsetfield; /* tag set routine */ - TIFFVGetMethod vgetfield; /* tag get routine */ - TIFFPrintMethod printdir; /* directory print routine */ -} TIFFTagMethods; +extern int TIFFMergeFieldInfo(TIFF*, const TIFFFieldInfo[], uint32); -extern TIFFTagMethods *TIFFAccessTagMethods( TIFF * ); -extern void *TIFFGetClientInfo( TIFF *, const char * ); -extern void TIFFSetClientInfo( TIFF *, void *, const char * ); - -extern void TIFFCleanup(TIFF*); -extern void TIFFClose(TIFF*); -extern int TIFFFlush(TIFF*); -extern int TIFFFlushData(TIFF*); -extern int TIFFGetField(TIFF*, ttag_t, ...); -extern int TIFFVGetField(TIFF*, ttag_t, va_list); -extern int TIFFGetFieldDefaulted(TIFF*, ttag_t, ...); -extern int TIFFVGetFieldDefaulted(TIFF*, ttag_t, va_list); -extern int TIFFReadDirectory(TIFF*); -extern int TIFFReadCustomDirectory(TIFF*, toff_t, const TIFFFieldInfo[], - size_t); -extern int TIFFReadEXIFDirectory(TIFF*, toff_t); -extern tsize_t TIFFScanlineSize(TIFF*); -extern tsize_t TIFFOldScanlineSize(TIFF*); -extern tsize_t TIFFNewScanlineSize(TIFF*); -extern tsize_t TIFFRasterScanlineSize(TIFF*); -extern tsize_t TIFFStripSize(TIFF*); -extern tsize_t TIFFRawStripSize(TIFF*, tstrip_t); -extern tsize_t TIFFVStripSize(TIFF*, uint32); -extern tsize_t TIFFTileRowSize(TIFF*); -extern tsize_t TIFFTileSize(TIFF*); -extern tsize_t TIFFVTileSize(TIFF*, uint32); -extern uint32 TIFFDefaultStripSize(TIFF*, uint32); -extern void TIFFDefaultTileSize(TIFF*, uint32*, uint32*); -extern int TIFFFileno(TIFF*); -extern int TIFFSetFileno(TIFF*, int); -extern thandle_t TIFFClientdata(TIFF*); -extern thandle_t TIFFSetClientdata(TIFF*, thandle_t); -extern int TIFFGetMode(TIFF*); -extern int TIFFSetMode(TIFF*, int); -extern int TIFFIsTiled(TIFF*); -extern int TIFFIsByteSwapped(TIFF*); -extern int TIFFIsUpSampled(TIFF*); -extern int TIFFIsMSB2LSB(TIFF*); -extern int TIFFIsBigEndian(TIFF*); -extern TIFFReadWriteProc TIFFGetReadProc(TIFF*); -extern TIFFReadWriteProc TIFFGetWriteProc(TIFF*); -extern TIFFSeekProc TIFFGetSeekProc(TIFF*); -extern TIFFCloseProc TIFFGetCloseProc(TIFF*); -extern TIFFSizeProc TIFFGetSizeProc(TIFF*); -extern TIFFMapFileProc TIFFGetMapFileProc(TIFF*); -extern TIFFUnmapFileProc TIFFGetUnmapFileProc(TIFF*); -extern uint32 TIFFCurrentRow(TIFF*); -extern tdir_t TIFFCurrentDirectory(TIFF*); -extern tdir_t TIFFNumberOfDirectories(TIFF*); -extern uint32 TIFFCurrentDirOffset(TIFF*); -extern tstrip_t TIFFCurrentStrip(TIFF*); -extern ttile_t TIFFCurrentTile(TIFF*); -extern int TIFFReadBufferSetup(TIFF*, tdata_t, tsize_t); -extern int TIFFWriteBufferSetup(TIFF*, tdata_t, tsize_t); -extern int TIFFSetupStrips(TIFF *); -extern int TIFFWriteCheck(TIFF*, int, const char *); -extern void TIFFFreeDirectory(TIFF*); -extern int TIFFCreateDirectory(TIFF*); -extern int TIFFLastDirectory(TIFF*); -extern int TIFFSetDirectory(TIFF*, tdir_t); -extern int TIFFSetSubDirectory(TIFF*, uint32); -extern int TIFFUnlinkDirectory(TIFF*, tdir_t); -extern int TIFFSetField(TIFF*, ttag_t, ...); -extern int TIFFVSetField(TIFF*, ttag_t, va_list); -extern int TIFFWriteDirectory(TIFF *); -extern int TIFFCheckpointDirectory(TIFF *); -extern int TIFFRewriteDirectory(TIFF *); -extern int TIFFReassignTagToIgnore(enum TIFFIgnoreSense, int); - -#if defined(c_plusplus) || defined(__cplusplus) -extern void TIFFPrintDirectory(TIFF*, FILE*, long = 0); -extern int TIFFReadScanline(TIFF*, tdata_t, uint32, tsample_t = 0); -extern int TIFFWriteScanline(TIFF*, tdata_t, uint32, tsample_t = 0); -extern int TIFFReadRGBAImage(TIFF*, uint32, uint32, uint32*, int = 0); -extern int TIFFReadRGBAImageOriented(TIFF*, uint32, uint32, uint32*, - int = ORIENTATION_BOTLEFT, int = 0); -#else -extern void TIFFPrintDirectory(TIFF*, FILE*, long); -extern int TIFFReadScanline(TIFF*, tdata_t, uint32, tsample_t); -extern int TIFFWriteScanline(TIFF*, tdata_t, uint32, tsample_t); -extern int TIFFReadRGBAImage(TIFF*, uint32, uint32, uint32*, int); -extern int TIFFReadRGBAImageOriented(TIFF*, uint32, uint32, uint32*, int, int); -#endif - -extern int TIFFReadRGBAStrip(TIFF*, tstrip_t, uint32 * ); -extern int TIFFReadRGBATile(TIFF*, uint32, uint32, uint32 * ); -extern int TIFFRGBAImageOK(TIFF*, char [1024]); -extern int TIFFRGBAImageBegin(TIFFRGBAImage*, TIFF*, int, char [1024]); -extern int TIFFRGBAImageGet(TIFFRGBAImage*, uint32*, uint32, uint32); -extern void TIFFRGBAImageEnd(TIFFRGBAImage*); -extern TIFF* TIFFOpen(const char*, const char*); -# ifdef __WIN32__ -extern TIFF* TIFFOpenW(const wchar_t*, const char*); -# endif /* __WIN32__ */ -extern TIFF* TIFFFdOpen(int, const char*, const char*); -extern TIFF* TIFFClientOpen(const char*, const char*, - thandle_t, - TIFFReadWriteProc, TIFFReadWriteProc, - TIFFSeekProc, TIFFCloseProc, - TIFFSizeProc, - TIFFMapFileProc, TIFFUnmapFileProc); -extern const char* TIFFFileName(TIFF*); -extern const char* TIFFSetFileName(TIFF*, const char *); -extern void TIFFError(const char*, const char*, ...) __attribute__((format (printf,2,3))); -extern void TIFFErrorExt(thandle_t, const char*, const char*, ...) __attribute__((format (printf,3,4))); -extern void TIFFWarning(const char*, const char*, ...) __attribute__((format (printf,2,3))); -extern void TIFFWarningExt(thandle_t, const char*, const char*, ...) __attribute__((format (printf,3,4))); -extern TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler); -extern TIFFErrorHandlerExt TIFFSetErrorHandlerExt(TIFFErrorHandlerExt); -extern TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler); -extern TIFFErrorHandlerExt TIFFSetWarningHandlerExt(TIFFErrorHandlerExt); -extern TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc); -extern ttile_t TIFFComputeTile(TIFF*, uint32, uint32, uint32, tsample_t); -extern int TIFFCheckTile(TIFF*, uint32, uint32, uint32, tsample_t); -extern ttile_t TIFFNumberOfTiles(TIFF*); -extern tsize_t TIFFReadTile(TIFF*, - tdata_t, uint32, uint32, uint32, tsample_t); -extern tsize_t TIFFWriteTile(TIFF*, - tdata_t, uint32, uint32, uint32, tsample_t); -extern tstrip_t TIFFComputeStrip(TIFF*, uint32, tsample_t); -extern tstrip_t TIFFNumberOfStrips(TIFF*); -extern tsize_t TIFFReadEncodedStrip(TIFF*, tstrip_t, tdata_t, tsize_t); -extern tsize_t TIFFReadRawStrip(TIFF*, tstrip_t, tdata_t, tsize_t); -extern tsize_t TIFFReadEncodedTile(TIFF*, ttile_t, tdata_t, tsize_t); -extern tsize_t TIFFReadRawTile(TIFF*, ttile_t, tdata_t, tsize_t); -extern tsize_t TIFFWriteEncodedStrip(TIFF*, tstrip_t, tdata_t, tsize_t); -extern tsize_t TIFFWriteRawStrip(TIFF*, tstrip_t, tdata_t, tsize_t); -extern tsize_t TIFFWriteEncodedTile(TIFF*, ttile_t, tdata_t, tsize_t); -extern tsize_t TIFFWriteRawTile(TIFF*, ttile_t, tdata_t, tsize_t); -extern int TIFFDataWidth(TIFFDataType); /* table of tag datatype widths */ -extern void TIFFSetWriteOffset(TIFF*, toff_t); -extern void TIFFSwabShort(uint16*); -extern void TIFFSwabLong(uint32*); -extern void TIFFSwabDouble(double*); -extern void TIFFSwabArrayOfShort(uint16*, unsigned long); -extern void TIFFSwabArrayOfTriples(uint8*, unsigned long); -extern void TIFFSwabArrayOfLong(uint32*, unsigned long); -extern void TIFFSwabArrayOfDouble(double*, unsigned long); -extern void TIFFReverseBits(unsigned char *, unsigned long); -extern const unsigned char* TIFFGetBitRevTable(int); - -#ifdef LOGLUV_PUBLIC -#define U_NEU 0.210526316 -#define V_NEU 0.473684211 -#define UVSCALE 410. -extern double LogL16toY(int); -extern double LogL10toY(int); -extern void XYZtoRGB24(float*, uint8*); -extern int uv_decode(double*, double*, int); -extern void LogLuv24toXYZ(uint32, float*); -extern void LogLuv32toXYZ(uint32, float*); -#if defined(c_plusplus) || defined(__cplusplus) -extern int LogL16fromY(double, int = SGILOGENCODE_NODITHER); -extern int LogL10fromY(double, int = SGILOGENCODE_NODITHER); -extern int uv_encode(double, double, int = SGILOGENCODE_NODITHER); -extern uint32 LogLuv24fromXYZ(float*, int = SGILOGENCODE_NODITHER); -extern uint32 LogLuv32fromXYZ(float*, int = SGILOGENCODE_NODITHER); -#else -extern int LogL16fromY(double, int); -extern int LogL10fromY(double, int); -extern int uv_encode(double, double, int); -extern uint32 LogLuv24fromXYZ(float*, int); -extern uint32 LogLuv32fromXYZ(float*, int); -#endif -#endif /* LOGLUV_PUBLIC */ - -extern int TIFFCIELabToRGBInit(TIFFCIELabToRGB*, TIFFDisplay *, float*); -extern void TIFFCIELabToXYZ(TIFFCIELabToRGB *, uint32, int32, int32, - float *, float *, float *); -extern void TIFFXYZToRGB(TIFFCIELabToRGB *, float, float, float, - uint32 *, uint32 *, uint32 *); - -extern int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB*, float*, float*); -extern void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *, uint32, int32, int32, - uint32 *, uint32 *, uint32 *); - #if defined(c_plusplus) || defined(__cplusplus) } #endif diff --git a/thirdparty/libtiff/tiffio.hxx b/thirdparty/libtiff/tiffio.hxx index ee3fd32c..ed994f11 100644 --- a/thirdparty/libtiff/tiffio.hxx +++ b/thirdparty/libtiff/tiffio.hxx @@ -1,4 +1,4 @@ -/* $Id: tiffio.hxx,v 1.1.2.1 2010-06-08 18:50:43 bfriesen Exp $ */ +/* $Id: tiffio.hxx,v 1.3 2010-06-08 18:55:15 bfriesen Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -34,8 +34,8 @@ #include #include "tiff.h" -extern TIFF* TIFFStreamOpen(const char*, std::ostream *); -extern TIFF* TIFFStreamOpen(const char*, std::istream *); +extern TIFF* TIFFStreamOpen(const char*, std::ostream *); +extern TIFF* TIFFStreamOpen(const char*, std::istream *); #endif /* _TIFFIO_HXX_ */ diff --git a/thirdparty/libtiff/tiffiop.h b/thirdparty/libtiff/tiffiop.h index a064039f..53357d85 100644 --- a/thirdparty/libtiff/tiffiop.h +++ b/thirdparty/libtiff/tiffiop.h @@ -1,4 +1,4 @@ -/* $Id: tiffiop.h,v 1.51.2.6 2010-06-12 02:55:16 bfriesen Exp $ */ +/* $Id: tiffiop.h,v 1.84 2012-05-30 01:50:17 fwarmerdam Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -57,14 +57,8 @@ extern void *lfind(const void *, const void *, size_t *, size_t, int (*)(const void *, const void *)); #endif -/* - Libtiff itself does not require a 64-bit type, but bundled TIFF - utilities may use it. -*/ -typedef TIFF_INT64_T int64; -typedef TIFF_UINT64_T uint64; - #include "tiffio.h" + #include "tif_dir.h" #ifndef STRIP_SIZE_DEFAULT @@ -80,170 +74,184 @@ typedef TIFF_UINT64_T uint64; typedef struct client_info { struct client_info *next; - void *data; - char *name; + void *data; + char *name; } TIFFClientInfoLink; /* * Typedefs for ``method pointers'' used internally. + * these are depriciated 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 */ +typedef unsigned char tidataval_t; /* internal image data value type */ +typedef tidataval_t* tidata_t; /* reference to internal image data */ -typedef void (*TIFFVoidMethod)(TIFF*); -typedef int (*TIFFBoolMethod)(TIFF*); -typedef int (*TIFFPreMethod)(TIFF*, tsample_t); -typedef int (*TIFFCodeMethod)(TIFF*, tidata_t, tsize_t, tsample_t); -typedef int (*TIFFSeekMethod)(TIFF*, uint32); -typedef void (*TIFFPostMethod)(TIFF*, tidata_t, tsize_t); -typedef uint32 (*TIFFStripMethod)(TIFF*, uint32); -typedef void (*TIFFTileMethod)(TIFF*, uint32*, uint32*); +typedef void (*TIFFVoidMethod)(TIFF*); +typedef int (*TIFFBoolMethod)(TIFF*); +typedef int (*TIFFPreMethod)(TIFF*, uint16); +typedef int (*TIFFCodeMethod)(TIFF* tif, uint8* buf, tmsize_t size, uint16 sample); +typedef int (*TIFFSeekMethod)(TIFF*, uint32); +typedef void (*TIFFPostMethod)(TIFF* tif, uint8* buf, tmsize_t size); +typedef uint32 (*TIFFStripMethod)(TIFF*, uint32); +typedef void (*TIFFTileMethod)(TIFF*, uint32*, uint32*); struct tiff { - char* tif_name; /* name of open file */ - 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 */ - toff_t tif_diroff; /* file offset of current directory */ - toff_t tif_nextdiroff; /* file offset of following directory */ - toff_t* tif_dirlist; /* list of offsets to already seen */ - /* directories to prevent IFD looping */ - tsize_t tif_dirlistsize;/* number of entires 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 */ - TIFFHeader tif_header; /* file's header block */ - const int* tif_typeshift; /* data type shift counts */ - const long* tif_typemask; /* data type masks */ - uint32 tif_row; /* current scanline */ - tdir_t tif_curdir; /* current directory (index) */ - tstrip_t tif_curstrip; /* current strip for read/write */ - toff_t tif_curoff; /* current offset for read/write */ - toff_t tif_dataoff; /* current offset for writing dir */ -/* SubIFD support */ - uint16 tif_nsubifd; /* remaining subifds to write */ - toff_t tif_subifdoff; /* offset for patching SubIFD link */ -/* tiling support */ - uint32 tif_col; /* current column (offset by row too) */ - ttile_t tif_curtile; /* current tile for read/write */ - tsize_t tif_tilesize; /* # of bytes in a tile */ -/* compression scheme hooks */ - int tif_decodestatus; - TIFFBoolMethod tif_setupdecode;/* called once before predecode */ - TIFFPreMethod tif_predecode; /* pre- row/strip/tile decoding */ - TIFFBoolMethod tif_setupencode;/* called once before preencode */ - int tif_encodestatus; - TIFFPreMethod tif_preencode; /* pre- row/strip/tile encoding */ - TIFFBoolMethod tif_postencode; /* post- row/strip/tile encoding */ - TIFFCodeMethod tif_decoderow; /* scanline decoding routine */ - TIFFCodeMethod tif_encoderow; /* scanline encoding routine */ - TIFFCodeMethod tif_decodestrip;/* strip decoding routine */ - TIFFCodeMethod tif_encodestrip;/* strip encoding routine */ - TIFFCodeMethod tif_decodetile; /* tile decoding routine */ - TIFFCodeMethod tif_encodetile; /* tile encoding routine */ - TIFFVoidMethod tif_close; /* cleanup-on-close routine */ - TIFFSeekMethod tif_seek; /* position within a strip routine */ - TIFFVoidMethod tif_cleanup; /* cleanup state routine */ - TIFFStripMethod tif_defstripsize;/* calculate/constrain strip size */ - TIFFTileMethod tif_deftilesize;/* calculate/constrain tile size */ - tidata_t tif_data; /* compression scheme private data */ -/* input/output buffering */ - tsize_t tif_scanlinesize;/* # of bytes in a scanline */ - tsize_t tif_scanlineskew;/* scanline skew for reading strips */ - tidata_t tif_rawdata; /* raw data buffer */ - tsize_t tif_rawdatasize;/* # of bytes in raw data buffer */ - tidata_t tif_rawcp; /* current spot in raw buffer */ - tsize_t tif_rawcc; /* bytes unread from raw buffer */ -/* memory-mapped file support */ - tidata_t tif_base; /* base of mapped file */ - toff_t tif_size; /* size of mapped file region (bytes) - FIXME: it should be tsize_t */ - TIFFMapFileProc tif_mapproc; /* map file method */ - TIFFUnmapFileProc tif_unmapproc;/* unmap file method */ -/* input/output callback methods */ - thandle_t tif_clientdata; /* callback parameter */ - TIFFReadWriteProc tif_readproc; /* read method */ - TIFFReadWriteProc tif_writeproc;/* write method */ - TIFFSeekProc tif_seekproc; /* lseek method */ - TIFFCloseProc tif_closeproc; /* close method */ - TIFFSizeProc tif_sizeproc; /* filesize method */ -/* post-decoding support */ - TIFFPostMethod tif_postdecode; /* post decoding routine */ -/* tag support */ - TIFFFieldInfo** tif_fieldinfo; /* sorted table of registered tags */ - size_t tif_nfields; /* # entries in registered tag table */ - const TIFFFieldInfo *tif_foundfield;/* cached pointer to already found tag */ - TIFFTagMethods tif_tagmethods; /* tag get/set/print routines */ - TIFFClientInfoLink *tif_clientinfo; /* extra client information. */ + char* tif_name; /* name of open file */ + 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 */ + 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_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 */ + union { + TIFFHeaderCommon common; + TIFFHeaderClassic classic; + TIFFHeaderBig big; + } tif_header; + uint16 tif_header_size; /* file's header block and its length */ + uint32 tif_row; /* current scanline */ + uint16 tif_curdir; /* current directory (index) */ + uint32 tif_curstrip; /* current strip for read/write */ + uint64 tif_curoff; /* current offset for read/write */ + uint64 tif_dataoff; /* current offset for writing dir */ + /* SubIFD support */ + uint16 tif_nsubifd; /* remaining subifds to write */ + uint64 tif_subifdoff; /* offset for patching SubIFD link */ + /* tiling support */ + uint32 tif_col; /* current column (offset by row too) */ + uint32 tif_curtile; /* current tile for read/write */ + tmsize_t tif_tilesize; /* # of bytes in a tile */ + /* compression scheme hooks */ + int tif_decodestatus; + TIFFBoolMethod tif_fixuptags; /* called in TIFFReadDirectory */ + TIFFBoolMethod tif_setupdecode; /* called once before predecode */ + TIFFPreMethod tif_predecode; /* pre- row/strip/tile decoding */ + TIFFBoolMethod tif_setupencode; /* called once before preencode */ + int tif_encodestatus; + TIFFPreMethod tif_preencode; /* pre- row/strip/tile encoding */ + TIFFBoolMethod tif_postencode; /* post- row/strip/tile encoding */ + TIFFCodeMethod tif_decoderow; /* scanline decoding routine */ + TIFFCodeMethod tif_encoderow; /* scanline encoding routine */ + TIFFCodeMethod tif_decodestrip; /* strip decoding routine */ + TIFFCodeMethod tif_encodestrip; /* strip encoding routine */ + TIFFCodeMethod tif_decodetile; /* tile decoding routine */ + TIFFCodeMethod tif_encodetile; /* tile encoding routine */ + TIFFVoidMethod tif_close; /* cleanup-on-close routine */ + TIFFSeekMethod tif_seek; /* position within a strip routine */ + TIFFVoidMethod tif_cleanup; /* cleanup state routine */ + TIFFStripMethod tif_defstripsize; /* calculate/constrain strip size */ + TIFFTileMethod tif_deftilesize; /* calculate/constrain tile size */ + uint8* tif_data; /* compression scheme private data */ + /* input/output buffering */ + tmsize_t tif_scanlinesize; /* # of bytes in a scanline */ + tmsize_t tif_scanlineskew; /* scanline skew for reading strips */ + uint8* tif_rawdata; /* raw data buffer */ + tmsize_t tif_rawdatasize; /* # of bytes in raw data buffer */ + tmsize_t tif_rawdataoff; /* rawdata offset within strip */ + tmsize_t tif_rawdataloaded;/* amount of data in rawdata */ + uint8* tif_rawcp; /* current spot in raw buffer */ + tmsize_t tif_rawcc; /* bytes unread from raw buffer */ + /* memory-mapped file support */ + uint8* tif_base; /* base of mapped file */ + tmsize_t tif_size; /* size of mapped file region (bytes, thus tmsize_t) */ + TIFFMapFileProc tif_mapproc; /* map file method */ + TIFFUnmapFileProc tif_unmapproc; /* unmap file method */ + /* input/output callback methods */ + thandle_t tif_clientdata; /* callback parameter */ + TIFFReadWriteProc tif_readproc; /* read method */ + TIFFReadWriteProc tif_writeproc; /* write method */ + TIFFSeekProc tif_seekproc; /* lseek method */ + TIFFCloseProc tif_closeproc; /* close method */ + TIFFSizeProc tif_sizeproc; /* filesize method */ + /* post-decoding support */ + TIFFPostMethod tif_postdecode; /* post decoding routine */ + /* tag support */ + TIFFField** tif_fields; /* sorted table of registered tags */ + size_t tif_nfields; /* # entries in registered tag table */ + const TIFFField* tif_foundfield; /* cached pointer to already found tag */ + TIFFTagMethods tif_tagmethods; /* tag get/set/print routines */ + TIFFClientInfoLink* tif_clientinfo; /* extra client information. */ + /* Backward compatibility stuff. We need these two fields for + * setting up an old tag extension scheme. */ + TIFFFieldArray* tif_fieldscompat; + size_t tif_nfieldscompat; }; -#define isPseudoTag(t) (t > 0xffff) /* is tag value normal or pseudo */ +#define isPseudoTag(t) (t > 0xffff) /* is tag value normal or pseudo */ -#define isTiled(tif) (((tif)->tif_flags & TIFF_ISTILED) != 0) -#define isMapped(tif) (((tif)->tif_flags & TIFF_MAPPED) != 0) -#define isFillOrder(tif, o) (((tif)->tif_flags & (o)) != 0) -#define isUpSampled(tif) (((tif)->tif_flags & TIFF_UPSAMPLED) != 0) -#define TIFFReadFile(tif, buf, size) \ - ((*(tif)->tif_readproc)((tif)->tif_clientdata,buf,size)) -#define TIFFWriteFile(tif, buf, size) \ - ((*(tif)->tif_writeproc)((tif)->tif_clientdata,buf,size)) -#define TIFFSeekFile(tif, off, whence) \ - ((*(tif)->tif_seekproc)((tif)->tif_clientdata,(toff_t)(off),whence)) -#define TIFFCloseFile(tif) \ +#define isTiled(tif) (((tif)->tif_flags & TIFF_ISTILED) != 0) +#define isMapped(tif) (((tif)->tif_flags & TIFF_MAPPED) != 0) +#define isFillOrder(tif, o) (((tif)->tif_flags & (o)) != 0) +#define isUpSampled(tif) (((tif)->tif_flags & TIFF_UPSAMPLED) != 0) +#define TIFFReadFile(tif, buf, size) \ + ((*(tif)->tif_readproc)((tif)->tif_clientdata,(buf),(size))) +#define TIFFWriteFile(tif, buf, size) \ + ((*(tif)->tif_writeproc)((tif)->tif_clientdata,(buf),(size))) +#define TIFFSeekFile(tif, off, whence) \ + ((*(tif)->tif_seekproc)((tif)->tif_clientdata,(off),(whence))) +#define TIFFCloseFile(tif) \ ((*(tif)->tif_closeproc)((tif)->tif_clientdata)) -#define TIFFGetFileSize(tif) \ +#define TIFFGetFileSize(tif) \ ((*(tif)->tif_sizeproc)((tif)->tif_clientdata)) -#define TIFFMapFileContents(tif, paddr, psize) \ - ((*(tif)->tif_mapproc)((tif)->tif_clientdata,paddr,psize)) -#define TIFFUnmapFileContents(tif, addr, size) \ - ((*(tif)->tif_unmapproc)((tif)->tif_clientdata,addr,size)) +#define TIFFMapFileContents(tif, paddr, psize) \ + ((*(tif)->tif_mapproc)((tif)->tif_clientdata,(paddr),(psize))) +#define TIFFUnmapFileContents(tif, addr, size) \ + ((*(tif)->tif_unmapproc)((tif)->tif_clientdata,(addr),(size))) /* * Default Read/Seek/Write definitions. */ #ifndef ReadOK -#define ReadOK(tif, buf, size) \ - (TIFFReadFile(tif, (tdata_t) buf, (tsize_t)(size)) == (tsize_t)(size)) +#define ReadOK(tif, buf, size) \ + (TIFFReadFile((tif),(buf),(size))==(size)) #endif #ifndef SeekOK -#define SeekOK(tif, off) \ - (TIFFSeekFile(tif, (toff_t) off, SEEK_SET) == (toff_t) off) +#define SeekOK(tif, off) \ + (TIFFSeekFile((tif),(off),SEEK_SET)==(off)) #endif #ifndef WriteOK -#define WriteOK(tif, buf, size) \ - (TIFFWriteFile(tif, (tdata_t) buf, (tsize_t) size) == (tsize_t) size) +#define WriteOK(tif, buf, size) \ + (TIFFWriteFile((tif),(buf),(size))==(size)) #endif /* NB: the uint32 casts are to silence certain ANSI-C compilers */ -#define TIFFhowmany(x, y) (((uint32)x < (0xffffffff - (uint32)(y-1))) ? \ +#define TIFFhowmany_32(x, y) (((uint32)x < (0xffffffff - (uint32)(y-1))) ? \ ((((uint32)(x))+(((uint32)(y))-1))/((uint32)(y))) : \ 0U) -#define TIFFhowmany8(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3) -#define TIFFroundup(x, y) (TIFFhowmany(x,y)*(y)) +#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))) +#define TIFFhowmany8_64(x) (((x)&0x07)?((uint64)(x)>>3)+1:(uint64)(x)>>3) +#define TIFFroundup_64(x, y) (TIFFhowmany_64(x,y)*(y)) /* Safe multiply which returns zero if there is an integer overflow */ -#define TIFFSafeMultiply(t,v,m) ((((t)m != (t)0) && (((t)((v*m)/m)) == (t)v)) ? (t)(v*m) : (t)0) +#define TIFFSafeMultiply(t,v,m) ((((t)(m) != (t)0) && (((t)(((v)*(m))/(m))) == (t)(v))) ? (t)((v)*(m)) : (t)0) #define TIFFmax(A,B) ((A)>(B)?(A):(B)) #define TIFFmin(A,B) ((A)<(B)?(A):(B)) @@ -253,86 +261,95 @@ struct tiff { #if defined(__cplusplus) extern "C" { #endif -extern int _TIFFgetMode(const char*, const char*); -extern int _TIFFNoRowEncode(TIFF*, tidata_t, tsize_t, tsample_t); -extern int _TIFFNoStripEncode(TIFF*, tidata_t, tsize_t, tsample_t); -extern int _TIFFNoTileEncode(TIFF*, tidata_t, tsize_t, tsample_t); -extern int _TIFFNoRowDecode(TIFF*, tidata_t, tsize_t, tsample_t); -extern int _TIFFNoStripDecode(TIFF*, tidata_t, tsize_t, tsample_t); -extern int _TIFFNoTileDecode(TIFF*, tidata_t, tsize_t, tsample_t); -extern void _TIFFNoPostDecode(TIFF*, tidata_t, tsize_t); -extern int _TIFFNoPreCode (TIFF*, tsample_t); -extern int _TIFFNoSeek(TIFF*, uint32); -extern void _TIFFSwab16BitData(TIFF*, tidata_t, tsize_t); -extern void _TIFFSwab24BitData(TIFF*, tidata_t, tsize_t); -extern void _TIFFSwab32BitData(TIFF*, tidata_t, tsize_t); -extern void _TIFFSwab64BitData(TIFF*, tidata_t, tsize_t); -extern int TIFFFlushData1(TIFF*); -extern int TIFFDefaultDirectory(TIFF*); -extern void _TIFFSetDefaultCompressionState(TIFF*); -extern int TIFFSetCompressionScheme(TIFF*, int); -extern int TIFFSetDefaultCompressionState(TIFF*); -extern uint32 _TIFFDefaultStripSize(TIFF*, uint32); -extern void _TIFFDefaultTileSize(TIFF*, uint32*, uint32*); -extern int _TIFFDataSize(TIFFDataType); +extern int _TIFFgetMode(const char* mode, const char* module); +extern int _TIFFNoRowEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s); +extern int _TIFFNoStripEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s); +extern int _TIFFNoTileEncode(TIFF*, uint8* pp, tmsize_t cc, uint16 s); +extern int _TIFFNoRowDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s); +extern int _TIFFNoStripDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s); +extern int _TIFFNoTileDecode(TIFF*, uint8* pp, tmsize_t cc, uint16 s); +extern void _TIFFNoPostDecode(TIFF* tif, uint8* buf, tmsize_t cc); +extern int _TIFFNoPreCode(TIFF* tif, uint16 s); +extern int _TIFFNoSeek(TIFF* tif, uint32 off); +extern void _TIFFSwab16BitData(TIFF* tif, uint8* buf, tmsize_t cc); +extern void _TIFFSwab24BitData(TIFF* tif, uint8* buf, tmsize_t cc); +extern void _TIFFSwab32BitData(TIFF* tif, uint8* buf, tmsize_t cc); +extern void _TIFFSwab64BitData(TIFF* tif, uint8* buf, tmsize_t cc); +extern int TIFFFlushData1(TIFF* tif); +extern int TIFFDefaultDirectory(TIFF* tif); +extern void _TIFFSetDefaultCompressionState(TIFF* tif); +extern int _TIFFRewriteField(TIFF *, uint16, TIFFDataType, tmsize_t, void *); +extern int TIFFSetCompressionScheme(TIFF* tif, int scheme); +extern int TIFFSetDefaultCompressionState(TIFF* tif); +extern uint32 _TIFFDefaultStripSize(TIFF* tif, uint32 s); +extern void _TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th); +extern int _TIFFDataSize(TIFFDataType type); -extern void _TIFFsetByteArray(void**, void*, uint32); -extern void _TIFFsetString(char**, char*); -extern void _TIFFsetShortArray(uint16**, uint16*, uint32); -extern void _TIFFsetLongArray(uint32**, uint32*, uint32); -extern void _TIFFsetFloatArray(float**, float*, uint32); -extern void _TIFFsetDoubleArray(double**, double*, uint32); +extern void _TIFFsetByteArray(void**, void*, uint32); +extern void _TIFFsetString(char**, char*); +extern void _TIFFsetShortArray(uint16**, uint16*, uint32); +extern void _TIFFsetLongArray(uint32**, uint32*, uint32); +extern void _TIFFsetFloatArray(float**, float*, uint32); +extern void _TIFFsetDoubleArray(double**, double*, uint32); -extern void _TIFFprintAscii(FILE*, const char*); -extern void _TIFFprintAsciiTag(FILE*, const char*, const char*); +extern void _TIFFprintAscii(FILE*, const char*); +extern void _TIFFprintAsciiTag(FILE*, const char*, const char*); -extern TIFFErrorHandler _TIFFwarningHandler; -extern TIFFErrorHandler _TIFFerrorHandler; -extern TIFFErrorHandlerExt _TIFFwarningHandlerExt; -extern TIFFErrorHandlerExt _TIFFerrorHandlerExt; +extern TIFFErrorHandler _TIFFwarningHandler; +extern TIFFErrorHandler _TIFFerrorHandler; +extern TIFFErrorHandlerExt _TIFFwarningHandlerExt; +extern TIFFErrorHandlerExt _TIFFerrorHandlerExt; -extern tdata_t _TIFFCheckMalloc(TIFF*, size_t, size_t, const char*); -extern tdata_t _TIFFCheckRealloc(TIFF*, tdata_t, size_t, size_t, const char*); +extern uint32 _TIFFMultiply32(TIFF*, uint32, uint32, const char*); +extern uint64 _TIFFMultiply64(TIFF*, uint64, uint64, const char*); +extern void* _TIFFCheckMalloc(TIFF*, tmsize_t, tmsize_t, const char*); +extern void* _TIFFCheckRealloc(TIFF*, void*, tmsize_t, tmsize_t, const char*); -extern int TIFFInitDumpMode(TIFF*, int); +extern double _TIFFUInt64ToDouble(uint64); +extern float _TIFFUInt64ToFloat(uint64); + +extern int TIFFInitDumpMode(TIFF*, int); #ifdef PACKBITS_SUPPORT -extern int TIFFInitPackBits(TIFF*, int); +extern int TIFFInitPackBits(TIFF*, int); #endif #ifdef CCITT_SUPPORT -extern int TIFFInitCCITTRLE(TIFF*, int), TIFFInitCCITTRLEW(TIFF*, int); -extern int TIFFInitCCITTFax3(TIFF*, int), TIFFInitCCITTFax4(TIFF*, int); +extern int TIFFInitCCITTRLE(TIFF*, int), TIFFInitCCITTRLEW(TIFF*, int); +extern int TIFFInitCCITTFax3(TIFF*, int), TIFFInitCCITTFax4(TIFF*, int); #endif #ifdef THUNDER_SUPPORT -extern int TIFFInitThunderScan(TIFF*, int); +extern int TIFFInitThunderScan(TIFF*, int); #endif #ifdef NEXT_SUPPORT -extern int TIFFInitNeXT(TIFF*, int); +extern int TIFFInitNeXT(TIFF*, int); #endif #ifdef LZW_SUPPORT -extern int TIFFInitLZW(TIFF*, int); +extern int TIFFInitLZW(TIFF*, int); #endif #ifdef OJPEG_SUPPORT -extern int TIFFInitOJPEG(TIFF*, int); +extern int TIFFInitOJPEG(TIFF*, int); #endif #ifdef JPEG_SUPPORT -extern int TIFFInitJPEG(TIFF*, int); +extern int TIFFInitJPEG(TIFF*, int); #endif #ifdef JBIG_SUPPORT -extern int TIFFInitJBIG(TIFF*, int); +extern int TIFFInitJBIG(TIFF*, int); #endif #ifdef ZIP_SUPPORT -extern int TIFFInitZIP(TIFF*, int); +extern int TIFFInitZIP(TIFF*, int); #endif #ifdef PIXARLOG_SUPPORT -extern int TIFFInitPixarLog(TIFF*, int); +extern int TIFFInitPixarLog(TIFF*, int); #endif #ifdef LOGLUV_SUPPORT -extern int TIFFInitSGILog(TIFF*, int); +extern int TIFFInitSGILog(TIFF*, int); +#endif +#ifdef LZMA_SUPPORT +extern int TIFFInitLZMA(TIFF*, int); #endif #ifdef VMS -extern const TIFFCodec _TIFFBuiltinCODECS[]; +extern const TIFFCodec _TIFFBuiltinCODECS[]; #else -extern TIFFCodec _TIFFBuiltinCODECS[]; +extern TIFFCodec _TIFFBuiltinCODECS[]; #endif #if defined(__cplusplus) diff --git a/thirdparty/libtiff/tiffvers.h b/thirdparty/libtiff/tiffvers.h index 314a22a0..1ed5b8f3 100644 --- a/thirdparty/libtiff/tiffvers.h +++ b/thirdparty/libtiff/tiffvers.h @@ -1,4 +1,4 @@ -#define TIFFLIB_VERSION_STR "LIBTIFF, Version 3.9.4\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc." +#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.0.4\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 20100615 +#define TIFFLIB_VERSION 20150621