[trunk] Update libtiff to 4.0.1 to support BigTIFF. openjpeg/tiff 4.0.1 currently...
authorMathieu Malaterre <mathieu.malaterre@gmail.com>
Mon, 12 Mar 2012 11:35:35 +0000 (11:35 +0000)
committerMathieu Malaterre <mathieu.malaterre@gmail.com>
Mon, 12 Mar 2012 11:35:35 +0000 (11:35 +0000)
59 files changed:
thirdparty/CMakeLists.txt
thirdparty/libtiff/CMakeLists.txt
thirdparty/libtiff/libtiff.def [new file with mode: 0644]
thirdparty/libtiff/t4.h
thirdparty/libtiff/tif_apple.c [deleted file]
thirdparty/libtiff/tif_aux.c
thirdparty/libtiff/tif_close.c
thirdparty/libtiff/tif_codec.c
thirdparty/libtiff/tif_color.c
thirdparty/libtiff/tif_compress.c
thirdparty/libtiff/tif_config.h [deleted file]
thirdparty/libtiff/tif_config.h.cmake.in [new file with mode: 0644]
thirdparty/libtiff/tif_config.h.in [new file with mode: 0644]
thirdparty/libtiff/tif_dir.c
thirdparty/libtiff/tif_dir.h
thirdparty/libtiff/tif_dirinfo.c
thirdparty/libtiff/tif_dirread.c
thirdparty/libtiff/tif_dirwrite.c
thirdparty/libtiff/tif_dumpmode.c
thirdparty/libtiff/tif_error.c
thirdparty/libtiff/tif_extension.c
thirdparty/libtiff/tif_fax3.c
thirdparty/libtiff/tif_fax3.h
thirdparty/libtiff/tif_flush.c
thirdparty/libtiff/tif_getimage.c
thirdparty/libtiff/tif_jbig.c
thirdparty/libtiff/tif_jpeg.c
thirdparty/libtiff/tif_jpeg_12.c [new file with mode: 0644]
thirdparty/libtiff/tif_luv.c
thirdparty/libtiff/tif_lzma.c [new file with mode: 0644]
thirdparty/libtiff/tif_lzw.c
thirdparty/libtiff/tif_next.c
thirdparty/libtiff/tif_ojpeg.c
thirdparty/libtiff/tif_open.c
thirdparty/libtiff/tif_packbits.c
thirdparty/libtiff/tif_pixarlog.c
thirdparty/libtiff/tif_predict.c
thirdparty/libtiff/tif_predict.h
thirdparty/libtiff/tif_print.c
thirdparty/libtiff/tif_read.c
thirdparty/libtiff/tif_stream.cxx
thirdparty/libtiff/tif_strip.c
thirdparty/libtiff/tif_swab.c
thirdparty/libtiff/tif_thunder.c
thirdparty/libtiff/tif_tile.c
thirdparty/libtiff/tif_unix.c
thirdparty/libtiff/tif_version.c
thirdparty/libtiff/tif_warning.c
thirdparty/libtiff/tif_win32.c
thirdparty/libtiff/tif_write.c
thirdparty/libtiff/tif_zip.c
thirdparty/libtiff/tiff.h
thirdparty/libtiff/tiffconf.h [deleted file]
thirdparty/libtiff/tiffconf.h.cmake.in [new file with mode: 0644]
thirdparty/libtiff/tiffconf.h.in [new file with mode: 0644]
thirdparty/libtiff/tiffio.h
thirdparty/libtiff/tiffio.hxx
thirdparty/libtiff/tiffiop.h
thirdparty/libtiff/tiffvers.h

index 7ab24ba3ec10ce293daacfe4fa51c67f778588be..4213cb59feb448031a3b6bce53e339856875b626 100644 (file)
@@ -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)
index 14601f0b7e258980ae1bc0dcc51bdc8ab248717d..24332458b07a7dd16671ad9247483e364e75fe91 100644 (file)
 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)
+
+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)
+  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)
+
+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)
+  set(TIFF_SSIZE_T   ssize_t)
+  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()
+
+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)
 
-#IF(APPLE)
-#    SET(TARGET_FILES ${TARGET_FILES} tif_apple.c)
-#ENDIF(APPLE)
+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)
+
+#
+set(VERSION "\"4.0.1\"")
+set(PACKAGE_VERSION ${VERSION})
+set(PACKAGE "\"tiff\"")
+
+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)
+
+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 (file)
index 0000000..ce36cfd
--- /dev/null
@@ -0,0 +1,151 @@
+EXPORTS TIFFOpen
+       TIFFOpenW
+       TIFFGetVersion
+       TIFFCleanup
+       TIFFClose
+       TIFFFlush
+       TIFFFlushData
+       TIFFGetField
+       TIFFVGetField
+       TIFFGetFieldDefaulted
+       TIFFVGetFieldDefaulted
+       TIFFGetTagListEntry
+       TIFFGetTagListCount
+       TIFFReadDirectory
+       TIFFScanlineSize64
+       TIFFScanlineSize
+       TIFFStripSize64
+       TIFFStripSize
+       TIFFVStripSize64
+       TIFFVStripSize
+       TIFFRawStripSize64
+       TIFFRawStripSize
+       TIFFTileRowSize64
+       TIFFTileRowSize
+       TIFFTileSize64
+       TIFFTileSize
+       TIFFVTileSize64
+       TIFFVTileSize
+       TIFFFileno
+       TIFFSetFileno
+       TIFFGetMode
+       TIFFIsTiled
+       TIFFIsByteSwapped
+       TIFFIsBigEndian
+       TIFFIsMSB2LSB
+       TIFFIsUpSampled
+       TIFFCIELabToRGBInit
+       TIFFCIELabToXYZ
+       TIFFXYZToRGB
+       TIFFYCbCrToRGBInit
+       TIFFYCbCrtoRGB
+       TIFFCurrentRow
+       TIFFCurrentDirectory
+       TIFFCurrentStrip
+       TIFFCurrentTile
+       TIFFDataWidth
+       TIFFReadBufferSetup
+       TIFFWriteBufferSetup
+       TIFFSetupStrips
+       TIFFLastDirectory
+       TIFFSetDirectory
+       TIFFSetSubDirectory
+       TIFFUnlinkDirectory
+       TIFFSetField
+       TIFFVSetField
+       TIFFCheckpointDirectory
+       TIFFWriteDirectory
+       TIFFRewriteDirectory
+       TIFFPrintDirectory
+       TIFFReadScanline
+       TIFFWriteScanline
+       TIFFReadRGBAImage
+       TIFFReadRGBAImageOriented
+       TIFFFdOpen
+       TIFFClientOpen
+       TIFFFileName
+       TIFFError
+       TIFFErrorExt
+       TIFFWarning
+       TIFFWarningExt
+       TIFFSetErrorHandler
+       TIFFSetErrorHandlerExt
+       TIFFSetWarningHandler
+       TIFFSetWarningHandlerExt
+       TIFFComputeTile
+       TIFFCheckTile
+       TIFFNumberOfTiles
+       TIFFReadTile
+       TIFFWriteTile
+       TIFFComputeStrip
+       TIFFNumberOfStrips
+       TIFFRGBAImageBegin
+       TIFFRGBAImageGet
+       TIFFRGBAImageEnd
+       TIFFReadEncodedStrip
+       TIFFReadRawStrip
+       TIFFReadEncodedTile
+       TIFFReadRawTile
+       TIFFReadRGBATile
+       TIFFReadRGBAStrip
+       TIFFWriteEncodedStrip
+       TIFFWriteRawStrip
+       TIFFWriteEncodedTile
+       TIFFWriteRawTile
+       TIFFSetWriteOffset
+       TIFFSwabFloat
+       TIFFSwabDouble
+       TIFFSwabShort
+       TIFFSwabLong
+       TIFFSwabArrayOfShort
+       TIFFSwabArrayOfLong
+       TIFFSwabArrayOfFloat
+       TIFFSwabArrayOfDouble
+       TIFFSwabArrayOfTriples
+       TIFFReverseBits
+       TIFFGetBitRevTable
+       TIFFDefaultStripSize
+       TIFFDefaultTileSize
+       TIFFRasterScanlineSize64
+       TIFFRasterScanlineSize
+       _TIFFmalloc
+       _TIFFrealloc
+       _TIFFfree
+       _TIFFmemset
+       _TIFFmemcpy
+       _TIFFmemcmp
+       TIFFCreateDirectory
+       TIFFSetTagExtender
+       TIFFFieldWithName
+       TIFFFieldWithTag
+       TIFFCurrentDirOffset
+       TIFFWriteCheck
+       TIFFRGBAImageOK
+       TIFFNumberOfDirectories
+       TIFFSetFileName
+       TIFFSetClientdata
+       TIFFSetMode
+       TIFFClientdata
+       TIFFGetReadProc
+       TIFFGetWriteProc
+       TIFFGetSeekProc
+       TIFFGetCloseProc
+       TIFFGetSizeProc
+       TIFFGetMapFileProc
+       TIFFGetUnmapFileProc
+       TIFFIsCODECConfigured
+       TIFFGetConfiguredCODECs
+       TIFFFindCODEC
+       TIFFRegisterCODEC
+       TIFFUnRegisterCODEC
+       TIFFFreeDirectory
+       TIFFReadCustomDirectory
+       TIFFReadEXIFDirectory
+       TIFFAccessTagMethods
+       TIFFGetClientInfo
+       TIFFSetClientInfo
+       TIFFSwabLong8
+       TIFFSwabArrayOfLong8
+       TIFFFindField
+       TIFFUnsetField
+       TIFFMergeFieldInfo
index 870704ffe8aec4ecb342ccf2bb8dc8e62df13d85..b908f54f094846743f97ec908021121f44af8caa 100644 (file)
@@ -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.
  */
 
  * 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/tif_apple.c b/thirdparty/libtiff/tif_apple.c
deleted file mode 100644 (file)
index 8c48228..0000000
+++ /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 <Errors.h>
-#include <Files.h>
-#include <Memory.h>
-#include <Script.h>
-
-#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:
- */
index 272f0d9b68214e5810c41f0f193e78cd8380bc50..927150a49352deaf881631a3abd6e00e09887993 100644 (file)
@@ -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
 #include "tif_predict.h"
 #include <math.h>
 
-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->td_bitspersample;
+       n = ((tmsize_t)1)<<td->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:
index 02591ba978f5ba37bd7be286fccb63d6c5a975af..13d2bab5ce956e85c0154bda4fcdecd79e8ebd53 100644 (file)
@@ -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 <string.h>
 
 /************************************************************************/
 /*                            TIFFCleanup()                             */
 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);
-
-       /* Clean up custom fields */
-       if (tif->tif_nfields > 0)
-       {
-               size_t  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);
+               TIFFUnmapFileContents(tif, tif->tif_base, (toff_t)tif->tif_size);
+
+       /*
+         * Clean up custom fields.
+         */
+       if (tif->tif_fields && tif->tif_nfields > 0) {
+               uint32 i;
+
+               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
index d5c6fd1149dcf091e75ca1961be76c673c77cc35..e20166737a2bd3492ea9716d18aa5e3e40c80cec 100644 (file)
@@ -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.15 2010-12-14 12:53:00 dron Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
  */
 #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 }
 };
 
@@ -114,13 +118,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 +134,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 +145,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;
 }
 
index 02eb346b06bafad6d1b05d4326205cae8b74e4f8..be4850ce6b106a03171f629cd85600a2c05a1c84 100644 (file)
@@ -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++)
index 0ce509b0bd82b67ca89718ab066c30cc4b98dca4..20e72fd0731f5664e734de168d06819950407fb2 100644 (file)
@@ -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 (file)
index 08d1f0d..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Define to 1 if you have the <assert.h> header file. */
-#define HAVE_ASSERT_H 1
-
-/* Define to 1 if you have the <fcntl.h> 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 <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <io.h> header file. */
-#define HAVE_IO_H 1
-
-/* Define to 1 if you have the <search.h> 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 (file)
index 0000000..d3711a7
--- /dev/null
@@ -0,0 +1,393 @@
+/* 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 <assert.h> header file. */
+#cmakedefine HAVE_ASSERT_H @HAVE_ASSERT_H@
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#cmakedefine HAVE_DLFCN_H @HAVE_DLFCN_H@
+
+/* Define to 1 if you have the <fcntl.h> 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 <GLUT/glut.h> header file. */
+#cmakedefine HAVE_GLUT_GLUT_H @HAVE_GLUT_GLUT_H@
+
+/* Define to 1 if you have the <GL/glut.h> header file. */
+#cmakedefine HAVE_GL_GLUT_H @HAVE_GL_GLUT_H@
+
+/* Define to 1 if you have the <GL/glu.h> header file. */
+#cmakedefine HAVE_GL_GLU_H @HAVE_GL_GLU_H@
+
+/* Define to 1 if you have the <GL/gl.h> 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 <inttypes.h> header file. */
+#cmakedefine HAVE_INTTYPES_H @HAVE_INTTYPES_H@
+
+/* Define to 1 if you have the <io.h> 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 <limits.h> header file. */
+#cmakedefine HAVE_LIMITS_H @HAVE_LIMITS_H@
+
+/* Define to 1 if you have the <malloc.h> 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 <memory.h> 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 <OpenGL/glu.h> header file. */
+#cmakedefine HAVE_OPENGL_GLU_H @HAVE_OPENGL_GLU_H@
+
+/* Define to 1 if you have the <OpenGL/gl.h> 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 <search.h> 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 <stdint.h> header file. */
+#cmakedefine HAVE_STDINT_H @HAVE_STDINT_H@
+
+/* Define to 1 if you have the <stdlib.h> 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 <strings.h> header file. */
+#cmakedefine HAVE_STRINGS_H @HAVE_STRINGS_H@
+
+/* Define to 1 if you have the <string.h> 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 <sys/stat.h> header file. */
+#cmakedefine HAVE_SYS_STAT_H @HAVE_SYS_STAT_H@
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#cmakedefine HAVE_SYS_TIME_H @HAVE_SYS_TIME_H@
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#cmakedefine HAVE_SYS_TYPES_H @HAVE_SYS_TYPES_H@
+
+/* Define to 1 if you have the <unistd.h> 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 <windows.h> 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
+
+/* 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 <sys/time.h> and <time.h>. */
+#cmakedefine TIME_WITH_SYS_TIME @TIME_WITH_SYS_TIME@
+
+/* Define to 1 if your <sys/time.h> 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
+# 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
+
+/* Define for large files, on AIX-style hosts. */
+#cmakedefine _LARGE_FILES
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#cmakedefine 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
+#cmakedefine inline
+#endif
+
+/* Define to `long int' if <sys/types.h> does not define. */
+#cmakedefine off_t
+
+/* Define to `unsigned int' if <sys/types.h> 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 (file)
index 0000000..dfd6e38
--- /dev/null
@@ -0,0 +1,393 @@
+/* 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 <assert.h> header file. */
+#undef HAVE_ASSERT_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <fcntl.h> 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 <GLUT/glut.h> header file. */
+#undef HAVE_GLUT_GLUT_H
+
+/* Define to 1 if you have the <GL/glut.h> header file. */
+#undef HAVE_GL_GLUT_H
+
+/* Define to 1 if you have the <GL/glu.h> header file. */
+#undef HAVE_GL_GLU_H
+
+/* Define to 1 if you have the <GL/gl.h> 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 <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <io.h> 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 `c' library (-lc). */
+#undef HAVE_LIBC
+
+/* Define to 1 if you have the `m' library (-lm). */
+#undef HAVE_LIBM
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define to 1 if you have the <malloc.h> 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 <memory.h> 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 <OpenGL/glu.h> header file. */
+#undef HAVE_OPENGL_GLU_H
+
+/* Define to 1 if you have the <OpenGL/gl.h> 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 <search.h> 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 <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> 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 <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> 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 <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> 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 <windows.h> 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 in which 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
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+#undef NO_MINUS_C_MINUS_O
+
+/* 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 `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
+
+/* 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 <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define to 1 if your <sys/time.h> 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
+
+/* 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 <sys/types.h> does not define. */
+#undef off_t
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
index ac44b381f8b3f526a87dc054fbeb989c98d3eb35..401a080e39602b997abdd79d7576be2b3cdacd74 100644 (file)
@@ -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.108 2012-02-01 01:51:00 fwarmerdam 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*);
@@ -122,7 +137,7 @@ checkInkNamesString(TIFF* tif, uint32 slen, const char* s)
                                        goto bad;
                        cp++;                           /* skip \0 */
                }
-               return (cp-s);
+               return ((uint32)(cp-s));
        }
 bad:
        TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
@@ -134,7 +149,7 @@ 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";
 
@@ -145,16 +160,16 @@ _TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
 
        switch (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 +178,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 +193,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 +209,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,16 +249,22 @@ _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);
@@ -251,7 +273,7 @@ _TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
                td->td_yresolution = (float) va_arg(ap, double);
                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 +285,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->td_bitspersample);
@@ -287,14 +309,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 +327,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 +338,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 +355,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 +387,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 +404,257 @@ _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;
+               const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
 
-            /*
-             * 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 == NULL || 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 ? fip->field_name : "Unknown");
                        status = 0;
-                       goto end;
+                       break;
                }
 
-               td->td_customValues = new_customValues;
+               /*
+                * 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;
+                       }
+               }
 
-                tv = td->td_customValues + (td->td_customValueCount - 1);
-                tv->info = fip;
-                tv->value = NULL;
-                tv->count = 0;
-            }
+               /*
+                * Grow the custom list if the entry was not found.
+                */
+               if(tv == NULL) {
+                       TIFFTagValue *new_customValues;
 
-            /*
-             * 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;
+                       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;
                }
 
-               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;
-
-                   for (i = 0; i < tv->count; i++, val += tv_size) {
-                           switch (fip->field_type) {
-                               case TIFF_BYTE:
-                               case TIFF_UNDEFINED:
-                                   {
-                                       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;
-                               case TIFF_SHORT:
-                                   {
-                                       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;
-                               case TIFF_LONG:
-                               case TIFF_IFD:
-                                   {
-                                       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;
-                               case TIFF_RATIONAL:
-                               case TIFF_SRATIONAL:
-                               case TIFF_FLOAT:
-                                   {
-                                       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;
-                               default:
-                                   _TIFFmemset(val, 0, tv_size);
-                                   status = 0;
-                                   break;
-                           }
-                   }
+               /*
+                * 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_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 (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;
+                       }
+
+                       tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size,
+                           "custom tag binary object");
+                       if (!tv->value) {
+                               status = 0;
+                               goto end;
+                       }
+
+                       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;
+
+                               for (i = 0; i < tv->count; i++, val += tv_size) {
+                                       switch (fip->field_type) {
+                                               case TIFF_BYTE:
+                                               case TIFF_UNDEFINED:
+                                                       {
+                                                               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;
+                                               case TIFF_SHORT:
+                                                       {
+                                                               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;
+                                               case TIFF_LONG:
+                                               case TIFF_IFD:
+                                                       {
+                                                               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;
+                                               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;
+                                               case TIFF_DOUBLE:
+                                                       {
+                                                               double v = va_arg(ap, double);
+                                                               _TIFFmemcpy(val, &v, tv_size);
+                                                       }
+                                                       break;
+                                               default:
+                                                       _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,18 +662,24 @@ 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);
 }
 
@@ -614,9 +693,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 +725,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 +736,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 +784,321 @@ 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;
 
-    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;
-            }
+       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:
+                       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;
+               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:
+                       {
+                               const TIFFField* fip =
+                                       TIFFFindField(tif, tag, TIFF_ANY);
+                               int i;
 
-            /*
-            * Do we have a custom value?
-            */
-            ret_val = 0;
-            for (i = 0; i < td->td_customValueCount; i++) {
-               TIFFTagValue *tv = td->td_customValues + 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;
+                               }
 
-               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;
+                               /*
+                                * 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;
-                                               break;
-                                       default:
-                                               ret_val = 0;
-                                               break;
+                                       } 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_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;
                                }
-                           }
                        }
-                }
-               break;
-            }
-        }
-    }
-    return(ret_val);
+       }
+       return(ret_val);
 }
 
 /*
@@ -948,7 +1106,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 +1124,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 +1148,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 +1173,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 +1204,14 @@ 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;
-
-    return 0;
+       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;
 }
 
 /*
@@ -1056,11 +1221,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,16 +1236,16 @@ 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;
        /*
@@ -1107,69 +1271,143 @@ 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)||(poffb<poffa)||(poffb<(tmsize_t)sizeof(uint16))||(poffb>tif->tif_size))
+                       {
+                               TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count");
+                               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 ((poffc<poffb)||(poffc<dircount*12)||(poffd<poffc)||(poffd<(tmsize_t)sizeof(uint32))||(poffd>tif->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)||(poffb<poffa)||(poffb<(tmsize_t)sizeof(uint64))||(poffb>tif->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 ((poffc<poffb)||(poffc<dircount16*20)||(poffd<poffc)||(poffd<(tmsize_t)sizeof(uint64))||(poffd>tif->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 +1415,19 @@ 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);
+       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))
+               n++;
+       return (n);
 }
 
 /*
@@ -1193,12 +1435,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 +1469,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 +1483,7 @@ TIFFSetSubDirectory(TIFF* tif, uint32 diroff)
 /*
  * Return file offset of the current directory.
  */
-uint32
+uint64
 TIFFCurrentDirOffset(TIFF* tif)
 {
        return (tif->tif_diroff);
@@ -1258,12 +1503,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 +1520,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 +1550,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 +1583,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 <cameron@petris.com>
- *
- * 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:
index 515af19942cd8465340849ca8906bc566fa8bb1f..6af5f3dc37e4dc11e99f122770b47b45cb09352d 100644 (file)
@@ -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
  * ``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_LAST                      (32*FIELD_SETLONGS-1)
+#define FIELD_PSEUDO                   0
 
-#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 FIELD_LAST                     (32*FIELD_SETLONGS-1)
 
-
-#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
index 57c29d55c2d508c33ebd331eb54baa09edac146b..06b5a5a00f00f1ee7c32c4e22da676adab9e06cc 100644 (file)
@@ -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.114 2011-05-17 00:21:17 fwarmerdam 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.
  */
 
  */
 #include "tiffiop.h"
 #include <stdlib.h>
-#include <string.h>
 
 /*
- * 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 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
  *       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_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 },
+       /* end DNG tags */
+       /* begin pseudo tags */
+       { TIFFTAG_PERSAMPLE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "PerSample", NULL},
 };
 
-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 +319,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 +332,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 +343,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 +391,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 +417,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 +453,8 @@ TIFFDataWidth(TIFFDataType type)
 int
 _TIFFDataSize(TIFFDataType type)
 {
-       switch (type) {
+       switch (type)
+       {
                case TIFF_BYTE:
                case TIFF_SBYTE:
                case TIFF_ASCII:
@@ -713,169 +471,182 @@ _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;
+       key.field_type = dt;
 
-       ret = (const TIFFFieldInfo **) bsearch(&pkey,
-                                              tif->tif_fieldinfo, 
-                                              tif->tif_nfields,
-                                              sizeof(TIFFFieldInfo *), 
-                                              tagCompare);
+       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 *))
-{
-       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)
+const TIFFField*
+_TIFFFindFieldByName(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;
-
-        ret = (const TIFFFieldInfo **) lfind(&pkey,
-                                            tif->tif_fieldinfo, 
-                                            &tif->tif_nfields,
-                                            sizeof(TIFFFieldInfo *),
-                                            tagNameCompare);
+       /* 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);
+
        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 )
+const TIFFField*
+_TIFFFindOrRegisterField(TIFF *tif, uint32 tag, TIFFDataType dt)
 
 {
-    const TIFFFieldInfo *fld;
+       const TIFFField *fld;
 
-    fld = _TIFFFindFieldInfo( tif, tag, dt );
-    if( fld == NULL )
-    {
-        fld = _TIFFCreateAnonFieldInfo( tif, tag, dt );
-        if (!_TIFFMergeFieldInfo(tif, fld, 1))
-               return NULL;
-    }
+       fld = TIFFFindField(tif, tag, dt);
+       if (fld == NULL) {
+               fld = _TIFFCreateAnonField(tif, tag, dt);
+               if (!_TIFFMergeFields(tif, fld, 1))
+                       return NULL;
+       }
 
-    return fld;
+       return fld;
 }
 
-TIFFFieldInfo*
-_TIFFCreateAnonFieldInfo(TIFF *tif, ttag_t tag, TIFFDataType field_type)
+TIFFField*
+_TIFFCreateAnonField(TIFF *tif, uint32 tag, TIFFDataType field_type)
 {
-       TIFFFieldInfo *fld;
+       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 +655,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);
 
        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
index 907b53188c81c053565fd38cca40aab01aaca2cc..c242d8fa548abf6ee0d1d070327dda12f32bda6c 100644 (file)
@@ -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.174 2012-02-01 02:24:47 fwarmerdam 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.
  */
 
  *
  * 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
+
+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  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*);
+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;
 
 /*
- * Read the next TIFF directory from a file and convert it to the internal
- * format. We read directories sequentially.
- */
-int
-TIFFReadDirectory(TIFF* tif)
+  Unaligned safe copy of a uint64 value from an octet array.
+*/
+static uint64 TIFFReadUInt64(const uint8 *value)
 {
-       static const char module[] = "TIFFReadDirectory";
+       UInt64Aligned_t result;
 
-       int n;
-       TIFFDirectory* td;
-       TIFFDirEntry *dp, *dir = NULL;
-       uint16 iv;
-       uint32 v;
-       const TIFFFieldInfo* fip;
-       size_t fix;
-       uint16 dircount;
-       int diroutoforderwarning = 0, compressionknown = 0;
-       int haveunknowntags = 0;
+       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];
 
-       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);
+       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)<direntry->tdir_count)
+               return(TIFFReadDirEntryErrSizesan);
+       if ((uint64)(2147483647/desttypesize)<direntry->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; n<count; n++)
+                               {
+                                       err=TIFFReadDirEntryCheckRangeByteSbyte(*m);
+                                       if (err!=TIFFReadDirEntryErrOk)
+                                       {
+                                               _TIFFfree(origdata);
+                                               return(err);
+                                       }
+                                       m++;
+                               }
+                               *value=(uint8*)origdata;
+                               return(TIFFReadDirEntryErrOk);
+                       }
+       }
+       data=(uint8*)_TIFFmalloc(count);
+       if (data==0)
+       {
+               _TIFFfree(origdata);
+               return(TIFFReadDirEntryErrAlloc);
+       }
+       switch (direntry->tdir_type)
+       {
+               case TIFF_SHORT:
+                       {
+                               uint16* ma;
+                               uint8* mb;
+                               uint32 n;
+                               ma=(uint16*)origdata;
+                               mb=data;
+                               for (n=0; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       err=TIFFReadDirEntryCheckRangeSbyteByte(*m);
+                                       if (err!=TIFFReadDirEntryErrOk)
+                                       {
+                                               _TIFFfree(origdata);
+                                               return(err);
+                                       }
+                                       m++;
+                               }
+                               *value=(int8*)origdata;
+                               return(TIFFReadDirEntryErrOk);
+                       }
+               case TIFF_SBYTE:
+                       *value=(int8*)origdata;
+                       return(TIFFReadDirEntryErrOk);
+       }
+       data=(int8*)_TIFFmalloc(count);
+       if (data==0)
+       {
+               _TIFFfree(origdata);
+               return(TIFFReadDirEntryErrAlloc);
+       }
+       switch (direntry->tdir_type)
+       {
+               case TIFF_SHORT:
+                       {
+                               uint16* ma;
+                               int8* mb;
+                               uint32 n;
+                               ma=(uint16*)origdata;
+                               mb=data;
+                               for (n=0; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                                       *mb++=(uint16)(*ma++);
+                       }
+                       break;
+               case TIFF_SBYTE:
+                       {
+                               int8* ma;
+                               uint16* mb;
+                               uint32 n;
+                               ma=(int8*)origdata;
+                               mb=data;
+                               for (n=0; n<count; n++)
+                               {
+                                       err=TIFFReadDirEntryCheckRangeShortSbyte(*ma);
+                                       if (err!=TIFFReadDirEntryErrOk)
+                                               break;
+                                       *mb++=(uint16)(*ma++);
+                               }
+                       }
+                       break;
+               case TIFF_LONG:
+                       {
+                               uint32* ma;
+                               uint16* mb;
+                               uint32 n;
+                               ma=(uint32*)origdata;
+                               mb=data;
+                               for (n=0; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                                       *mb++=(int16)(*ma++);
+                       }
+                       break;
+               case TIFF_SBYTE:
+                       {
+                               int8* ma;
+                               int16* mb;
+                               uint32 n;
+                               ma=(int8*)origdata;
+                               mb=data;
+                               for (n=0; n<count; n++)
+                                       *mb++=(int16)(*ma++);
+                       }
+                       break;
+               case TIFF_LONG:
+                       {
+                               uint32* ma;
+                               int16* mb;
+                               uint32 n;
+                               ma=(uint32*)origdata;
+                               mb=data;
+                               for (n=0; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                                       *mb++=(uint32)(*ma++);
+                       }
+                       break;
+               case TIFF_SBYTE:
+                       {
+                               int8* ma;
+                               uint32* mb;
+                               uint32 n;
+                               ma=(int8*)origdata;
+                               mb=data;
+                               for (n=0; n<count; n++)
+                               {
+                                       err=TIFFReadDirEntryCheckRangeLongSbyte(*ma);
+                                       if (err!=TIFFReadDirEntryErrOk)
+                                               break;
+                                       *mb++=(uint32)(*ma++);
+                               }
+                       }
+                       break;
+               case TIFF_SHORT:
+                       {
+                               uint16* ma;
+                               uint32* mb;
+                               uint32 n;
+                               ma=(uint16*)origdata;
+                               mb=data;
+                               for (n=0; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                                       *mb++=(int32)(*ma++);
+                       }
+                       break;
+               case TIFF_SBYTE:
+                       {
+                               int8* ma;
+                               int32* mb;
+                               uint32 n;
+                               ma=(int8*)origdata;
+                               mb=data;
+                               for (n=0; n<count; n++)
+                                       *mb++=(int32)(*ma++);
+                       }
+                       break;
+               case TIFF_SHORT:
+                       {
+                               uint16* ma;
+                               int32* mb;
+                               uint32 n;
+                               ma=(uint16*)origdata;
+                               mb=data;
+                               for (n=0; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                                       *mb++=(uint64)(*ma++);
+                       }
+                       break;
+               case TIFF_SBYTE:
+                       {
+                               int8* ma;
+                               uint64* mb;
+                               uint32 n;
+                               ma=(int8*)origdata;
+                               mb=data;
+                               for (n=0; n<count; n++)
+                               {
+                                       err=TIFFReadDirEntryCheckRangeLong8Sbyte(*ma);
+                                       if (err!=TIFFReadDirEntryErrOk)
+                                               break;
+                                       *mb++=(uint64)(*ma++);
+                               }
+                       }
+                       break;
+               case TIFF_SHORT:
+                       {
+                               uint16* ma;
+                               uint64* mb;
+                               uint32 n;
+                               ma=(uint16*)origdata;
+                               mb=data;
+                               for (n=0; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                                       *mb++=(int64)(*ma++);
+                       }
+                       break;
+               case TIFF_SBYTE:
+                       {
+                               int8* ma;
+                               int64* mb;
+                               uint32 n;
+                               ma=(int8*)origdata;
+                               mb=data;
+                               for (n=0; n<count; n++)
+                                       *mb++=(int64)(*ma++);
+                       }
+                       break;
+               case TIFF_SHORT:
+                       {
+                               uint16* ma;
+                               int64* mb;
+                               uint32 n;
+                               ma=(uint16*)origdata;
+                               mb=data;
+                               for (n=0; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_flags&TIFF_SWAB)
+                                               TIFFSwabLong((uint32*)ma);
+                                       *mb++=(int64)(*ma++);
+                               }
+                       }
+                       break;
+       }
+       _TIFFfree(origdata);
+       if (err!=TIFFReadDirEntryErrOk)
+       {
+               _TIFFfree(data);
+               return(err);
+       }
+       *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; n<count; n++)
+                                       *mb++=(float)(*ma++);
+                       }
+                       break;
+               case TIFF_SBYTE:
+                       {
+                               int8* ma;
+                               float* mb;
+                               uint32 n;
+                               ma=(int8*)origdata;
+                               mb=data;
+                               for (n=0; n<count; n++)
+                                       *mb++=(float)(*ma++);
+                       }
+                       break;
+               case TIFF_SHORT:
+                       {
+                               uint16* ma;
+                               float* mb;
+                               uint32 n;
+                               ma=(uint16*)origdata;
+                               mb=data;
+                               for (n=0; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                                       *mb++=(float)(*ma++);
+                       }
+                       break;
+       }
+       _TIFFfree(origdata);
+       if (err!=TIFFReadDirEntryErrOk)
+       {
+               _TIFFfree(data);
+               return(err);
+       }
+       *value=data;
+       return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryDoubleArray(TIFF* tif, TIFFDirEntry* direntry, double** value)
+{
+       enum TIFFReadDirEntryErr err;
+       uint32 count;
+       void* origdata;
+       double* 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,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; n<count; n++)
+                                       *mb++=(double)(*ma++);
+                       }
+                       break;
+               case TIFF_SBYTE:
+                       {
+                               int8* ma;
+                               double* mb;
+                               uint32 n;
+                               ma=(int8*)origdata;
+                               mb=data;
+                               for (n=0; n<count; n++)
+                                       *mb++=(double)(*ma++);
+                       }
+                       break;
+               case TIFF_SHORT:
+                       {
+                               uint16* ma;
+                               double* mb;
+                               uint32 n;
+                               ma=(uint16*)origdata;
+                               mb=data;
+                               for (n=0; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                               {
+                                       if (tif->tif_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; n<count; n++)
+                                       *mb++=(double)(*ma++);
+                       }
+                       break;
+       }
+       _TIFFfree(origdata);
+       if (err!=TIFFReadDirEntryErrOk)
+       {
+               _TIFFfree(data);
+               return(err);
+       }
+       *value=data;
+       return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value)
+{
+       enum TIFFReadDirEntryErr err;
+       uint32 count;
+       void* origdata;
+       uint64* data;
+       switch (direntry->tdir_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; n<count; n++)
+                               {
+                                       if (tif->tif_flags&TIFF_SWAB)
+                                               TIFFSwabLong(ma);
+                                       *mb++=(uint64)(*ma++);
+                               }
+                       }
+                       break;
+       }
+       _TIFFfree(origdata);
+       if (err!=TIFFReadDirEntryErrOk)
+       {
+               _TIFFfree(data);
+               return(err);
+       }
+       *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 {
+               tmsize_t ma,mb;
+               ma=(tmsize_t)offset;
+               mb=ma+size;
+               if (((uint64)ma!=offset)||(mb<ma)||(mb<size)||(mb>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:
+                               TIFFErrorExt(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
+ * format. We read directories sequentially.
+ */
+int
+TIFFReadDirectory(TIFF* tif)
+{
+       static const char module[] = "TIFFReadDirectory";
+       TIFFDirEntry* dir;
+       uint16 dircount;
+       TIFFDirEntry* dp;
+       uint16 di;
+       const TIFFField* fip;
+       uint32 fii=FAILED_FII;
+        toff_t nextdiroff;
+       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; mb<dircount; ma++, mb++)
+               {
+                       TIFFDirEntry* na;
+                       uint16 nb;
+                       for (na=ma+1, nb=mb+1; nb<dircount; na++, nb++)
+                       {
+                               if (ma->tdir_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 +3470,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 +3487,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;
        }
-       /*
-        * 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) {
-                               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;
-                       }
-               }
+       dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_COMPRESSION);
+       if (dp)
+       {
                /*
-                * Check count if known in advance.
+                * 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.
                 */
-               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;
+               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;
        }
-
        /*
-        * 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.
+        * First real pass over the directory.
         */
-       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,
+       for (di=0, dp=dir; di<dircount; di++, dp++)
+       {
+               if (dp->tdir_tag!=IGNORE)
+               {
+                       TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
+                       if (fii == FAILED_FII)
+                       {
+                               TIFFWarningExt(tif->tif_clientdata, module,
+                                   "Unknown field with tag %d (0x%x) encountered",
+                                   dp->tdir_tag,dp->tdir_tag);
+                                /* the following knowingly leaks the 
+                                   anonymous field structure */
+                               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++;
+                                           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);
+                               }
+                       }
                }
-               /*
-                * 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;
+               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 +3595,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 +3663,150 @@ 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; di<dircount; di++, dp++)
+       {
+               switch (dp->tdir_tag)
+               {
+                       case IGNORE:
+                               break;
+                       case TIFFTAG_MINSAMPLEVALUE:
+                       case TIFFTAG_MAXSAMPLEVALUE:
+                       case TIFFTAG_BITSPERSAMPLE:
+                       case TIFFTAG_DATATYPE:
+                       case TIFFTAG_SAMPLEFORMAT:
                                /*
-                                * 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->td_bitspersample;
-                               if (dp->tdir_tag == TIFFTAG_COLORMAP ||
-                                   dp->tdir_count != v) {
-                                       if (!CheckDirCount(tif, dp, 3 * v))
-                                               break;
+                               {
+                                       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;
                                }
-                               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);
+                               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;
                                        }
-                                       _TIFFfree(cp);
+                                       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_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_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 OFILETYPE_PAGE:
-                               v = FILETYPE_PAGE;
+                       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;
+                                       countpersample=(1L<<tif->tif_dir.td_bitspersample);
+                                       if ((dp->tdir_tag==TIFFTAG_TRANSFERFUNCTION)&&(dp->tdir_count==(uint64)countpersample))
+                                       {
+                                               countrequired=countpersample;
+                                               incrementpersample=0;
+                                       }
+                                       else
+                                       {
+                                               countrequired=3*countpersample;
+                                               incrementpersample=countpersample;
+                                       }
+                                       if (dp->tdir_count!=(uint64)countrequired)
+                                               err=TIFFReadDirEntryErrCount;
+                                       else
+                                               err=TIFFReadDirEntryShortArray(tif,dp,&value);
+                                       if (err!=TIFFReadDirEntryErrOk)
+                    {
+                                               fip = TIFFFieldWithTag(tif,dp->tdir_tag);
+                                               TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",1);
+                    }
+                                       else
+                                       {
+                                               TIFFSetField(tif,dp->tdir_tag,value,value+incrementpersample,value+2*incrementpersample);
+                                               _TIFFfree(value);
+                                       }
+                               }
+                               break;
+/* BEGIN REV 4.0 COMPATIBILITY */
+                       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;
-                       }
-                       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 +3825,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,module,
+                                   "SamplesPerPixel tag is missing, "
+                                   "assuming correct SamplesPerPixel value is 3");
+                               if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,3))
+                                       goto bad;
+                       }
+                       if (tif->tif_dir.td_photometric==PHOTOMETRIC_YCBCR)
                        {
-                               TIFFWarningExt(tif->tif_clientdata,
-                                              "TIFFReadDirectory",
-                               "SamplesPerPixel tag is missing, "
-                               "assuming correct SamplesPerPixel value is 3");
+                               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 ((td->td_photometric==PHOTOMETRIC_MINISWHITE)
-                                || (td->td_photometric==PHOTOMETRIC_MINISBLACK))
+                       else if ((tif->tif_dir.td_photometric==PHOTOMETRIC_MINISWHITE)
+                                || (tif->tif_dir.td_photometric==PHOTOMETRIC_MINISBLACK))
                        {
-                               TIFFWarningExt(tif->tif_clientdata,
-                                              "TIFFReadDirectory",
-                               "SamplesPerPixel tag is missing, "
-                               "assuming correct SamplesPerPixel value is 1");
+                               /*
+                                * 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 +3881,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 +3908,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 +3934,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 +3952,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->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->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;
-
-               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;
+#if !defined(DEFER_STRILE_LOAD)        
+       if (tif->tif_dir.td_nstrips > 1) {
+               uint32 strip;
+
+               tif->tif_dir.td_stripbytecountsorted = 1;
+               for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) {
+                       if (tif->tif_dir.td_stripoffset[strip - 1] >
+                           tif->tif_dir.td_stripoffset[strip]) {
+                               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 +4026,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 +4062,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 +4079,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; n<dircount; n++, o++)
+       {
+               if (o->tdir_tag<m)
+               {
+                       TIFFWarningExt(tif->tif_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; n<dircount; m++, n++)
        {
                if (m->tdir_tag==tagid)
@@ -805,123 +4113,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; di<dircount; di++, dp++)
+       {
+               TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_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))
-                       {
-                               TIFFWarningExt(tif->tif_clientdata, module,
-                       "Registering anonymous field with tag %d (0x%x) failed",
-                                               dp->tdir_tag, dp->tdir_tag);
-                               goto 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) {
+                           "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,
-                       "%s: wrong data type %d for \"%s\"; tag ignored",
-                                           tif->tif_name, dp->tdir_type,
-                                           tif->tif_fieldinfo[fix-1]->field_name);
-                               goto ignore;
+                                   "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 );
                        }
                }
-               /*
-                * 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 (dp->tdir_tag!=IGNORE)
+               {
+                       fip=tif->tif_fields[fii];
+                       if (fip->field_bit==FIELD_IGNORE)
+                               dp->tdir_tag=IGNORE;
+                       else
+                       {
+                               /* 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;
+                                       }
+                               }
+                       }
+                       switch (dp->tdir_tag)
+                       {
+                               case IGNORE:
+                                       break;
+                               case EXIFTAG_SUBJECTDISTANCE:
+                                       (void) TIFFFetchSubjectDistance(tif,dp);
+                                       break;
+                               default:
+                                       (void) TIFFFetchNormalTag(tif, dp, TRUE);
+                                       break;
+                       }
                }
        }
-       
        if (dir)
                _TIFFfree(dir);
        return 1;
@@ -934,11 +4259,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 +4273,49 @@ EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
        TIFFDirectory *td = &tif->tif_dir;
        uint32 strip;
 
+    _TIFFFillStriles( tif );
+
        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 +4328,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 +4355,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,7 +4366,7 @@ 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;
 
@@ -1046,17 +4381,14 @@ 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;
@@ -1075,17 +4407,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 +4432,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 +4457,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 +4509,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 +4543,848 @@ TIFFFetchDirectory(TIFF* tif, toff_t diroff, TIFFDirEntry **pdir,
                 *
                 * to avoid overflow.
                 */
-               if (tif->tif_size < sizeof (uint16) ||
-                   off > tif->tif_size - sizeof(uint16)) {
+               if (!(tif->tif_flags&TIFF_BIGTIFF))
+               {
+                       m=off+sizeof(uint16);
+                       if ((m<off)||(m<(tmsize_t)sizeof(uint16))||(m>tif->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;
+               }
+               else
+               {
+                       tmsize_t m;
+                       uint64 dircount64;
+                       m=off+sizeof(uint64);
+                       if ((m<off)||(m<(tmsize_t)sizeof(uint64))||(m>tif->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 count",
-                               tif->tif_name);
+                                    "Sanity check on directory count failed, zero tag directories not supported");
                        return 0;
-               } else {
-                       _TIFFmemcpy(&dircount, tif->tif_base + off,
-                                   sizeof(uint16));
                }
-               off += sizeof (uint16);
-               if (tif->tif_flags & TIFF_SWAB)
-                       TIFFSwabShort(&dircount);
-               dir = (TIFFDirEntry *)_TIFFCheckMalloc(tif, dircount,
-                                               sizeof(TIFFDirEntry),
+               origdir = _TIFFCheckMalloc(tif, dircount16,
+                                               dirsize,
                                                "to read TIFF directory");
-               if (dir == NULL)
+               if (origdir == NULL)
                        return 0;
-               if (off + dircount * sizeof (TIFFDirEntry) > tif->tif_size) {
+               m=off+dircount16*dirsize;
+               if ((m<off)||(m<(tmsize_t)(dircount16*dirsize))||(m>tif->tif_size)) {
                        TIFFErrorExt(tif->tif_clientdata, module,
-                                    "%s: Can not read TIFF directory",
-                                    tif->tif_name);
-                       _TIFFfree(dir);
+                                    "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 ((m<off)||(m<(tmsize_t)sizeof(uint32))||(m>tif->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 ((m<off)||(m<(tmsize_t)sizeof(uint64))||(m>tif->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);
+       dir = (TIFFDirEntry*)_TIFFCheckMalloc(tif, dircount16,
+                                               sizeof(TIFFDirEntry),
+                                               "to read TIFF directory");
+       if (dir==0)
+       {
+               _TIFFfree(origdir);
+               return 0;
        }
-       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;
+       ma=(uint8*)origdir;
+       mb=dir;
+       for (n=0; n<dircount16; n++)
+       {
+               if (tif->tif_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))
+               {
+                       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);
                }
-       }
-       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;
+               {
+                       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);
                }
+               mb++;
        }
-        return (1);
-    } else
-        return (TIFFFetchData(tif, dir, (char*) v) != 0);      /* XXX */
+       _TIFFfree(origdir);
+       *pdir = dir;
+       return dircount16;
 }
 
 /*
- * Fetch an array of SHORT or SSHORT values.
+ * Fetch a tag that is not handled by special case code.
  */
 static int
-TIFFFetchShortArray(TIFF* tif, TIFFDirEntry* dir, uint16* v)
+TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
 {
-       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);
+       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->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_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);
+                               }
                        }
-               } else {
-                       switch (dir->tdir_count) {
-                       case 2: v[1] = (uint16) (dir->tdir_offset >> 16);
-                       case 1: v[0] = (uint16) (dir->tdir_offset & 0xffff);
+                       break;
+               case TIFF_SETGET_UINT8:
+                       {
+                               uint8 data;
+                               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);
+                               }
                        }
-               }
-               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);
-               return 0;
-       }
-
-       switch (dir->tdir_type) {
-               case TIFF_BYTE:
-               case TIFF_SBYTE:
+                       break;
+               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_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)
+                                       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)
+                                    /* corrupt file */;
+                               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:
                        {
-                       uint8 v[4];
-                       return TIFFFetchByteArray(tif, dir, v)
-                               && TIFFSetField(tif, dir->tdir_tag, v[0], v[1]);
+                               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);
+                                       }
+                               }
                        }
-               case TIFF_SHORT:
-               case TIFF_SSHORT:
+                       break;
+               case TIFF_SETGET_C16_DOUBLE:
                        {
-                       uint16 v[2];
-                       return TIFFFetchShortArray(tif, dir, v)
-                               && TIFFSetField(tif, dir->tdir_tag, v[0], v[1]);
+                               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);
+                                       }
+                               }
                        }
-               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;
+                       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);
+                                       }
+                               }
                        }
-               }
-               _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
-               {
-                 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];
-               }
-               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];
-               }
-               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);
-       }
-       return (1);
-}
-
-/*
- * Fetch a tag that is not handled by special case code.
- */
-static int
-TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp)
-{
-       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);
                        break;
-               case TIFF_SHORT:
-               case TIFF_SSHORT:
-                       cp = (char *)_TIFFCheckMalloc(tif,
-                           dp->tdir_count, sizeof (uint16), mesg);
-                       ok = cp && TIFFFetchShortArray(tif, dp, (uint16*) cp);
+               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_LONG:
-               case TIFF_SLONG:
-                       cp = (char *)_TIFFCheckMalloc(tif,
-                           dp->tdir_count, sizeof (uint32), mesg);
-                       ok = cp && TIFFFetchLongArray(tif, dp, (uint32*) cp);
+               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_RATIONAL:
-               case TIFF_SRATIONAL:
-                       cp = (char *)_TIFFCheckMalloc(tif,
-                           dp->tdir_count, sizeof (float), mesg);
-                       ok = cp && TIFFFetchRationalArray(tif, dp, (float*) cp);
+               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_FLOAT:
-                       cp = (char *)_TIFFCheckMalloc(tif,
-                           dp->tdir_count, sizeof (float), mesg);
-                       ok = cp && TIFFFetchFloatArray(tif, dp, (float*) cp);
+               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_DOUBLE:
-                       cp = (char *)_TIFFCheckMalloc(tif,
-                           dp->tdir_count, sizeof (double), mesg);
-                       ok = cp && TIFFFetchDoubleArray(tif, dp, (double*) cp);
+               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_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 */
+               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;
-               }
-               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;
-                         }
+               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);
+                               }
                        }
-                       /* 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));
+                       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_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_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_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_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_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_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);
-}
-
-#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);
+       if (err!=TIFFReadDirEntryErrOk)
+       {
+               TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",recover);
+               return(0);
+       }
+       return(1);
 }
-#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];
-                    }
+       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 (dir->tdir_count!=(uint64)nstrips)
+       {
+               uint64* resizeddata;
+               resizeddata=(uint64*)_TIFFCheckMalloc(tif,nstrips,sizeof(uint64),"for strip array");
+               if (resizeddata==0) {
+                       _TIFFfree(data);
+                       return(0);
                }
-               _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);
+               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;
        }
-       if (cp)
-               _TIFFfree(cp);
-       return (ok);
+       *lpp=data;
+       return(1);
 }
 
 /*
@@ -1966,29 +5393,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 +5455,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 +5521,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 +5532,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 +5542,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:
index 8d308c42926ea1c8785a3f8ced17440b3e8a5dd6..11738cfe754daa7e786fe2bd5706120a7bab7118 100644 (file)
@@ -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.76 2011-02-18 20:53:04 fwarmerdam 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.
  */
 
 #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*);
-
-#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 TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff);
+
+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 <n> 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,981 +196,2710 @@ 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;
-
-       if (tif->tif_mode == O_RDONLY)
-               return (1);
-
-       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);
-       }
-       /*
-        * 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 )
-               {
-                       int ci, is_set = FALSE;
+       return TIFFWriteDirectorySec(tif,FALSE,FALSE,pdiroff);
+}
 
-                       for( ci = 0; ci < td->td_customValueCount; ci++ )
-                               is_set |= (td->td_customValues[ci].info == fip);
+/*
+ * 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";
 
-                       if( !is_set )
-                               continue;
-               }
-               else if (!FieldSet(fields, fip->field_bit))
-                       continue;
-                
-               if( fip->field_bit != FIELD_CUSTOM )
-                       ResetFieldBit(fields, fip->field_bit);
-       }
+       /* We don't need to do anything special if it hasn't been written. */
+       if( tif->tif_diroff == 0 )
+               return TIFFWriteDirectory( tif );
 
        /*
-        * Write directory.
+        * Find and zero the pointer to this directory, so that TIFFLinkDirectory
+        * will cause it to be added after this directories current pre-link.
         */
-       dircount = (uint16) nfields;
-       *pdiroff = (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(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;
+       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);
                        }
                }
-               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;
+               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;
                        }
                }
-               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;
+       }
+       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);
                        }
                }
-               break;
-       case TIFF_ASCII:
-               { 
-                    char* cp;
-                    if (fip->field_passcount)
-                    {
-                        if( wc == (uint16) TIFF_VARIABLE2 )
-                            TIFFGetField(tif, fip->field_tag, &wc2, &cp);
-                        else
-                            TIFFGetField(tif, fip->field_tag, &wc, &cp);
-                    }
-                    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 (!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;
+               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;
                        }
                }
-                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);
-               }
-               break;
-
-        case TIFF_NOTYPE:
-                break;
        }
-       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);
-       }
-}
+       /*
+        * Now use TIFFWriteDirectory() normally.
+        */
 
-/*
- * 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);
+       return TIFFWriteDirectory( tif );
 }
-#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)
+TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff)
 {
-       uint16 buf[10], v;
-       uint16* w = buf;
-       uint16 i, samples = tif->tif_dir.td_samplesperpixel;
-       int status;
+       static const char module[] = "TIFFWriteDirectorySec";
+       uint32 ndir;
+       TIFFDirEntry* dir;
+       uint32 dirsize;
+       void* dirmem;
+       uint32 m;
+       if (tif->tif_mode == O_RDONLY)
+               return (1);
 
-       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);
+        _TIFFFillStriles( tif );
+        
+       /*
+        * Clear write state so that subsequent images with
+        * different characteristics get the right buffers
+        * setup for them.
+        */
+       if (imagedone)
+       {
+               if (tif->tif_flags & TIFF_POSTENCODE)
+               {
+                       tif->tif_flags &= ~TIFF_POSTENCODE;
+                       if (!(*tif->tif_postencode)(tif))
+                       {
+                               TIFFErrorExt(tif->tif_clientdata,module,
+                                   "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.  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.
+                */
+               if (tif->tif_rawcc > 0 
+                   && (tif->tif_flags & TIFF_BEENWRITING) != 0 )
+               {
+                   if( !TIFFFlushData1(tif) )
+                    {
+                       TIFFErrorExt(tif->tif_clientdata, module,
+                           "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_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 (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; n<tif->tif_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;
+                                               }
+                                       }
+                               }
+                       }
+               }
+               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;
+                       }
+               }
+               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_dataoff<tif->tif_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++;
+       }
+       if (isimage)
+       {
+               if (TIFFFieldSet(tif,FIELD_SUBIFD)&&(tif->tif_subifdoff==0))
+               {
+                       uint32 na;
+                       TIFFDirEntry* nb;
+                       for (na=0, nb=dir; ; na++, nb++)
+                       {
+                               assert(na<ndir);
+                               if (nb->tdir_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;
+               }
+       }
+       dirmem=_TIFFmalloc(dirsize);
+       if (dirmem==NULL)
+       {
+               TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+               goto bad;
+       }
+       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; m<ndir; m++)
+               {
+                       *(uint16*)n=o->tdir_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++;
+               }
+               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; m<ndir; m++)
+               {
+                       *(uint16*)n=o->tdir_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++;
+               }
+               _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);
+}
+
+static int
+TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
+{
+       static const char module[] = "TIFFWriteDirectoryTagSampleformatArray";
+       void* conv;
+       uint32 i;
+       int ok;
+       conv = _TIFFmalloc(count*sizeof(double));
+       if (conv == NULL)
+       {
+               TIFFErrorExt(tif->tif_clientdata, module, "Out of memory");
+               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;
+       }
+
+       _TIFFfree(conv);
+       return (ok);
+}
+
+#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);
+       }
+}
+#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
+TIFFWriteDirectoryTagUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
+{
+       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; nb<tif->tif_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; nb<tif->tif_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; nb<tif->tif_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; nb<tif->tif_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; nb<tif->tif_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; nb<tif->tif_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; nb<tif->tif_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);
        }
-       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);
+       return(TIFFWriteDirectoryTagCheckedDoubleArray(tif,ndir,dir,tag,count,value));
 }
 
-/*
- * 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.
- */
+#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; nb<tif->tif_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
-TIFFWritePerSampleAnys(TIFF* tif,
-    TIFFDataType type, ttag_t tag, TIFFDirEntry* dir)
+TIFFWriteDirectoryTagIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
 {
-       double buf[10], v;
-       double* w = buf;
-       uint16 i, samples = tif->tif_dir.td_samplesperpixel;
-       int status;
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       return(TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,tag,count,value));
+}
 
-       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);
+#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; mb<count; ma++, mb++, q++)
+    {
+        if (*ma>0xFFFFFFFF)
+        {
+            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; mb<count; ma++, mb++, q++)
+    {
+        if (*ma>0xFFFFFFFF)
+        {
+            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; mb<count; ma++, mb++)
+       {
+               if ((n==0)&&(*ma>0xFFFF))
+                       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; mb<count; ma++, mb++, q++)
+                       *q=(uint16)(*ma);
+               o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,count,p);
+               _TIFFfree(p);
+       }
+       else if (n==1)
+       {
+               uint32* p;
+               uint32* q;
+               p=_TIFFmalloc(count*sizeof(uint32));
+               if (p==NULL)
+               {
+                       TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+                       return(0);
+               }
+               for (ma=value, mb=0, q=p; mb<count; ma++, mb++, q++)
+                       *q=(uint32)(*ma);
+               o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,p);
+               _TIFFfree(p);
+       }
+       else
+       {
+               assert(n==2);
+               o=TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,tag,count,value);
+       }
+       return(o);
+}
+#endif
+static int
+TIFFWriteDirectoryTagColormap(TIFF* tif, uint32* ndir, TIFFDirEntry* dir)
+{
+       static const char module[] = "TIFFWriteDirectoryTagColormap";
+       uint32 m;
+       uint16* n;
+       int o;
+       if (dir==NULL)
+       {
+               (*ndir)++;
+               return(1);
+       }
+       m=(1<<tif->tif_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->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.
+        */
+       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;
+       }
+       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
+TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32* ndir, TIFFDirEntry* dir)
+{
+       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 <n> 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);
+}
+
+static int
+TIFFWriteDirectoryTagCheckedAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value)
+{
+       assert(sizeof(char)==1);
+       return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_ASCII,count,count,value));
+}
+
+static int
+TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
+{
+       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; nc<count; na++, nb+=2, nc++)
+       {
+               if (*na<=0.0)
+               {
+                       nb[0]=0;
+                       nb[1]=1;
+               }
+               else if (*na==(float)(uint32)(*na))
+               {
+                       nb[0]=(uint32)(*na);
+                       nb[1]=1;
+               }
+               else if (*na<1.0)
+               {
+                       nb[0]=(uint32)((*na)*0xFFFFFFFF);
+                       nb[1]=0xFFFFFFFF;
+               }
+               else
+               {
+                       nb[0]=0xFFFFFFFF;
+                       nb[1]=(uint32)(0xFFFFFFFF/(*na));
+               }
+       }
+       if (tif->tif_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<count; na++, nb+=2, nc++)
+       {
+               if (*na<0.0)
+               {
+                       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));
+                       }
+               }
+               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));
+                       }
                }
        }
-       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);
+       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);
 }
-#undef NITEMS
 
-/*
- * Setup a pair of shorts that are returned by
- * value, rather than as a reference to an array.
- */
+#ifdef notdef
 static int
-TIFFSetupShortPair(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
+TIFFWriteDirectoryTagCheckedFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value)
 {
-       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));
+       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
 
-/*
- * 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)
+TIFFWriteDirectoryTagCheckedFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
 {
-       uint32 i, off;
-
-       dir->tdir_tag = (uint16) tag;
-       dir->tdir_type = (short) TIFF_SHORT;
-       /* XXX -- yech, fool TIFFWriteData */
-       dir->tdir_count = (uint32) (1L<<tif->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;
-               }
-               return 1;
-       } else
-               return TIFFWriteData(tif, dir, cp);
+       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));
 }
 
-/*
- * 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;
-               }
-               return (1);
-       } else
-               return (TIFFWriteData(tif, dir, (char*) v));
-}
-
-/*
- * Setup a directory entry of an array of LONG
- * or SLONG and write the associated indirect values.
- */
+#ifdef notdef
 static int
-TIFFWriteLongArray(TIFF* tif, TIFFDirEntry* dir, uint32* v)
+TIFFWriteDirectoryTagCheckedDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
 {
-       if (dir->tdir_count == 1) {
-               dir->tdir_offset = v[0];
-               return (1);
-       } else
-               return (TIFFWriteData(tif, dir, (char*) v));
+       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
 
-/*
- * 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)
+TIFFWriteDirectoryTagCheckedDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
 {
-       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");
-               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);
+       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
-TIFFWriteFloatArray(TIFF* tif, TIFFDirEntry* dir, float* v)
+TIFFWriteDirectoryTagCheckedIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
 {
-       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));
+       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
-TIFFWriteDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v)
+TIFFWriteDirectoryTagCheckedIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
 {
-       TIFFCvtNativeToIEEEDouble(tif, dir->tdir_count, v);
-       return (TIFFWriteData(tif, dir, (char*) v));
+       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));
 }
 
-/*
- * 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)
+TIFFWriteDirectoryTagData(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 datatype, uint32 count, uint32 datalength, void* data)
 {
-       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);
-               }
+       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++;
        }
-
-       dir->tdir_tag = (uint16) tag;
-       dir->tdir_type = (uint16) type;
-       dir->tdir_count = n;
-
-       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:
+       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 ((nb<na)||(nb<datalength))
                {
-                       uint16* bp = (uint16*) w;
-                       for (i = 0; i < (int) n; i++)
-                               bp[i] = (uint16) v[i];
-                       if (!TIFFWriteShortArray(tif, dir, (uint16*)bp))
-                               goto out;
+                       TIFFErrorExt(tif->tif_clientdata,module,"Maximum TIFF file size exceeded");
+                       return(0);
                }
-               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;
+               if (!SeekOK(tif,na))
+               {
+                       TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data");
+                       return(0);
                }
-               break;
-       case TIFF_LONG:
+               assert(datalength<0x80000000UL);
+               if (!WriteOK(tif,data,(tmsize_t)datalength))
                {
-                       uint32* bp = (uint32*) w;
-                       for (i = 0; i < (int) n; i++)
-                               bp[i] = (uint32) v[i];
-                       if (!TIFFWriteLongArray(tif, dir, bp))
-                               goto out;
+                       TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data");
+                       return(0);
                }
-               break;
-       case TIFF_SLONG:
+               tif->tif_dataoff=nb;
+               if (tif->tif_dataoff&1)
+                       tif->tif_dataoff++;
+               if (!(tif->tif_flags&TIFF_BIGTIFF))
                {
-                       int32* bp = (int32*) w;
-                       for (i = 0; i < (int) n; i++)
-                               bp[i] = (int32) v[i];
-                       if (!TIFFWriteLongArray(tif, dir, (uint32*) bp))
-                               goto out;
+                       uint32 o;
+                       o=(uint32)na;
+                       if (tif->tif_flags&TIFF_SWAB)
+                               TIFFSwabLong(&o);
+                       _TIFFmemcpy(&dir[m].tdir_offset,&o,4);
                }
-               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;
+               else
+               {
+                       dir[m].tdir_offset.toff_long8 = na;
+                       if (tif->tif_flags&TIFF_SWAB)
+                               TIFFSwabLong8(&dir[m].tdir_offset.toff_long8);
                }
-               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;
-       }
-       status = 1;
- out:
-       if (w != buf)
-               _TIFFfree(w);
-       return (status);
-}
-
-static int
-TIFFWriteTransferFunction(TIFF* tif, TIFFDirEntry* dir)
-{
-       TIFFDirectory* td = &tif->tif_dir;
-       tsize_t n = (1L<<td->td_bitspersample) * sizeof (uint16);
-       uint16** tf = td->td_transferfunction;
-       int ncols;
-
-       /*
-        * 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;
        }
-       return (TIFFWriteShortTable(tif,
-           TIFFTAG_TRANSFERFUNCTION, dir, ncols, tf));
-}
-
-static int
-TIFFWriteInkNames(TIFF* tif, 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));
+       (*ndir)++;
+       return(1);
 }
 
 /*
- * Write a contiguous directory item.
+ * Link the current directory into the directory chain for the file.
  */
 static int
-TIFFWriteData(TIFF* tif, TIFFDirEntry* dir, char* cp)
+TIFFLinkDirectory(TIFF* tif)
 {
-       tsize_t cc;
+       static const char module[] = "TIFFLinkDirectory";
 
-       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;
+       tif->tif_diroff = (TIFFSeekFile(tif,0,SEEK_END)+1) &~ 1;
+
+       /*
+        * Handle SubIFDs
+        */
+       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);
+               }
+               else
+               {
+                       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);
                }
        }
-       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);
+
+       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);
+               }
+               /*
+                * Not the first directory, search to the last and append.
+                */
+               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==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)
+                       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;
+               }
        }
-       TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-                    "Error writing data for field \"%s\"",
-       _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
-       return (0);
+       return (1);
 }
 
-/*
- * 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. 
- */ 
+/************************************************************************/
+/*                          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 
-TIFFRewriteDirectory( TIFF *tif )
+int
+_TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype, 
+                  tmsize_t count, void* data)
 {
-    static const char module[] = "TIFFRewriteDirectory";
+    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;
+    }
 
-    /* We don't need to do anything special if it hasn't been written. */
     if( tif->tif_diroff == 0 )
-        return TIFFWriteDirectory( tif );
+    {
+        TIFFErrorExt( tif->tif_clientdata, module, 
+                      "Attempt to reset field on directory not already on disk." );
+        return 0;
+    }
 
-    /*
-    ** 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) 
+/* -------------------------------------------------------------------- */
+/*      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 )
     {
-        tif->tif_header.tiff_diroff = 0;
-        tif->tif_diroff = 0;
+       tmsize_t i;
 
-        TIFFSeekFile(tif, (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE),
-                    SEEK_SET);
-        if (!WriteOK(tif, &(tif->tif_header.tiff_diroff), 
-                     sizeof (tif->tif_diroff))) 
+        for( i = 0; i < count; i++ )
         {
-                       TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
-                                    "Error updating TIFF header");
-            return (0);
+            ((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
     {
-        toff_t  nextdir, off;
+        if( TIFFDataWidth(datatype) * count <= 8 )
+        {
+            entry_offset = read_offset + 12;
+            value_in_entry = 1;
+        }
+    }
 
-       nextdir = tif->tif_header.tiff_diroff;
-       do {
-               uint16 dircount;
+/* -------------------------------------------------------------------- */
+/*      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);
+        }
 
-               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);
-       }
+        _TIFFfree( buf_to_write );
+        return 1;
     }
 
-    /*
-    ** Now use TIFFWriteDirectory() normally.
-    */
+/* -------------------------------------------------------------------- */
+/*      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);
+        }
+        
+        _TIFFfree( buf_to_write );
+    }
+    else
+    {
+        memcpy( &entry_offset, buf_to_write, count*TIFFDataWidth(datatype));
+    }
 
-    return TIFFWriteDirectory( tif );
-}
+/* -------------------------------------------------------------------- */
+/*      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;
 
-/*
- * Link the current directory into the directory chain for the file.
- */
-static int
-TIFFLinkDirectory(TIFF* tif)
-{
-       static const char module[] = "TIFFLinkDirectory";
-       toff_t nextdir;
-       toff_t diroff, off;
+        value = (uint32) entry_count;
+        memcpy( direntry_raw + 4, &value, sizeof(uint32) );
+        if (tif->tif_flags&TIFF_SWAB)
+            TIFFSwabLong( (uint32 *) (direntry_raw + 4) );
 
-       tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1;
-       diroff = tif->tif_diroff;
-       if (tif->tif_flags & TIFF_SWAB)
-               TIFFSwabLong(&diroff);
+        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) );
 
-       /*
-        * 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);
-               }
-               /*
-                * 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);
-       }
+        memcpy( direntry_raw + 12, &entry_offset, sizeof(uint64) );
+        if (tif->tif_flags&TIFF_SWAB)
+            TIFFSwabLong8( (uint64 *) (direntry_raw + 12) );
+    }
 
-       if (tif->tif_header.tiff_diroff == 0) {
-               /*
-                * First directory, overwrite offset in header.
-                */
-               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;
+/* -------------------------------------------------------------------- */
+/*      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 (!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 != 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);
+    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:
index da861503d80f061425e2e01f49efdae036f81607..a94cf0b34a92c41378bc5916e7d3fc84813f1ea9 100644 (file)
@@ -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
  */
 #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);
 }
index 2377abda8775a51a6413c1bbe52021ae967398b2..0bc8b878bd053aa9e50cb51e80ef3425dcd70d9e 100644 (file)
@@ -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
index b67c0f00be36577bde4583c84781fa142c44a461..10afd4162c157271ca9d08de73795a1155a27775 100644 (file)
@@ -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;
index 9eec4ab7b7ac9339c0bf66ea01121a26a7c7a99b..52c16b40359a036483472358ffa9210637972e68 100644 (file)
@@ -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.72 2010-06-09 17:17:13 bfriesen Exp $ */
 
 /*
  * Copyright (c) 1990-1997 Sam Leffler
  * 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 */
-
-       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 */
+       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 */
+
+       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);
        }
@@ -538,9 +549,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 +566,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 +585,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 +713,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 +803,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 +862,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 +1034,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 +1054,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 +1116,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 +1125,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 +1160,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 +1190,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 +1216,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 +1272,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 +1294,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 +1316,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 +1326,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 +1352,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 +1372,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 +1429,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 +1470,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 +1501,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 +1573,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.
                 */
index 40718bcfa71c3a3dc1ceae62f74f208b97f48210..b0f46c9a43f065ae346f6ba8622777e96f28b780 100644 (file)
@@ -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;                                                      \
index 7ecc4d8345d4a64051a89c0f9c977da84ad7e48a..fd14e4cdae11b1889c61e5a21136f43b636a55fa 100644 (file)
@@ -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
 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
index 38455fbc074a7426a12b57d7334d3eb0c6303b21..6a09b4d254f9c1a3301d6cf1a468d8e753e9de37 100644 (file)
@@ -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.78 2011-02-23 21:46:09 fwarmerdam 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 },
@@ -202,10 +206,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 +262,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 +311,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 +319,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 +329,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 +348,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 +381,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 +391,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 +404,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 +414,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 +430,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,7 +591,7 @@ 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;
@@ -581,7 +600,7 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
 
     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));
@@ -604,14 +623,14 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
        nrow = (row + rowstoread > h ? h - row : rowstoread);
        for (col = 0; col < w; col += tw) 
         {
-            if (TIFFReadTile(tif, buf, col+img->col_offset,
-                             row+img->row_offset, 0, 0) < 0 && img->stoponerr)
+           if (TIFFReadTile(tif, buf, col+img->col_offset,  
+                            row+img->row_offset, 0, 0)==(tmsize_t)(-1) && img->stoponerr)
             {
                 ret = 0;
                 break;
             }
            
-            pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif);
+           pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif);  
 
            if (col + tw > w) 
             {
@@ -665,23 +684,24 @@ 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;
        int32 fromskew, toskew;
        int alpha = img->alpha;
        uint32 nrow;
        int ret = 1, flip;
+        int colorchannels;
 
-       tilesize = TIFFTileSize(tif);
+       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");
+               TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer");
                return (0);
        }
        _TIFFmemset(buf, 0, (alpha?4:3)*tilesize);
@@ -702,41 +722,58 @@ 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;
+        }
+
        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)
                {
-                       if (TIFFReadTile(tif, p0, col+img->col_offset,
-                           row+img->row_offset,0,0) < 0 && img->stoponerr)
+                       if (TIFFReadTile(tif, p0, col+img->col_offset,  
+                           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+img->col_offset,  
+                                            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+img->col_offset,  
+                                            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+img->col_offset,  
+                                            row+img->row_offset,0,colorchannels) == (tmsize_t)(-1) 
+                            && img->stoponerr)
+                        {
+                            ret = 0;
+                            break;
                        }
 
-                       pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif);
+                       pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif);  
 
                        if (col + tw > w)
                        {
@@ -790,12 +827,12 @@ 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;
 
@@ -817,7 +854,7 @@ 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,7 +866,7 @@ 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;
@@ -875,16 +912,16 @@ 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;
        int32 fromskew, toskew;
        int alpha = img->alpha;
-       int ret = 1, flip;
+       int ret = 1, flip, colorchannels;
 
-       stripsize = TIFFStripSize(tif);
+       stripsize = TIFFStripSize(tif);  
        p0 = buf = (unsigned char *)_TIFFmalloc((alpha?4:3)*stripsize);
        if (buf == 0) {
                TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer");
@@ -905,8 +942,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 +965,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 +989,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;
@@ -1036,6 +1089,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) \
@@ -1266,11 +1320,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 +1346,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 +1368,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 +1391,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 +1486,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);
@@ -1439,11 +1502,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 +1527,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 +1547,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 +1568,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;
@@ -1846,6 +1918,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr41tile)
 DECLAREContigPutFunc(putcontig8bitYCbCr22tile)
 {
        uint32* cp2;
+       int32 incr = 2*toskew+w;
        (void) y;
        fromskew = (fromskew / 2) * 6;
        cp2 = cp+w+toskew;
@@ -1872,8 +1945,8 @@ DECLAREContigPutFunc(putcontig8bitYCbCr22tile)
                        cp2 ++ ;
                        pp += 6;
                }
-               cp += toskew*2+w;
-               cp2 += toskew*2+w;
+               cp += incr;
+               cp2 += incr;
                pp += fromskew;
                h-=2;
        }
@@ -1939,6 +2012,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr21tile)
 DECLAREContigPutFunc(putcontig8bitYCbCr12tile)
 {
        uint32* cp2;
+       int32 incr = 2*toskew+w;
        (void) y;
        fromskew = (fromskew / 2) * 4;
        cp2 = cp+w+toskew;
@@ -1953,8 +2027,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 +2090,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 +2119,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 +2399,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;
                        }
@@ -2397,7 +2476,7 @@ PickContigCase(TIFFRGBAImage* img)
                        }
                        break;
                case PHOTOMETRIC_YCBCR:
-                       if (img->bitspersample == 8)
+                       if ((img->bitspersample==8) && (img->samplesperpixel==3))
                        {
                                if (initYCbCrConversion(img)!=0)
                                {
@@ -2461,6 +2540,9 @@ PickSeparateCase(TIFFRGBAImage* img)
        img->get = TIFFIsTiled(img->tif) ? gtTileSeparate : gtStripSeparate;
        img->put.separate = NULL;
        switch (img->photometric) {
+               case PHOTOMETRIC_MINISWHITE:
+               case PHOTOMETRIC_MINISBLACK:
+                  /* greyscale images processed pretty much as RGB by gtTileSeparate */
                case PHOTOMETRIC_RGB:
                        switch (img->bitspersample) {
                                case 8:
@@ -2468,7 +2550,8 @@ PickSeparateCase(TIFFRGBAImage* img)
                                                img->put.separate = putRGBAAseparate8bittile;
                                        else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
                                        {
-                                            img->put.separate = putRGBUAseparate8bittile;
+                                               if (BuildMapUaToAa(img))
+                                                       img->put.separate = putRGBUAseparate8bittile;
                                        }
                                        else
                                                img->put.separate = putRGBseparate8bittile;
@@ -2476,15 +2559,19 @@ PickSeparateCase(TIFFRGBAImage* img)
                                case 16:
                                        if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
                                        {
-                                            img->put.separate = putRGBAAseparate16bittile;
+                                               if (BuildMapBitdepth16To8(img))
+                                                       img->put.separate = putRGBAAseparate16bittile;
                                        }
                                        else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
                                        {
-                                            img->put.separate = putRGBUAseparate16bittile;
+                                               if (BuildMapBitdepth16To8(img) &&
+                                                   BuildMapUaToAa(img))
+                                                       img->put.separate = putRGBUAseparate16bittile;
                                        }
                                        else
                                        {
-                                            img->put.separate = putRGBseparate16bittile;
+                                               if (BuildMapBitdepth16To8(img))
+                                                       img->put.separate = putRGBseparate16bittile;
                                        }
                                        break;
                        }
@@ -2509,6 +2596,48 @@ PickSeparateCase(TIFFRGBAImage* img)
        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
index c92ee3de6c869f2a52b71b77c99fad3a4e8c16e1..37878f6e702cfb275be1fbfe1a06f4cd5f8e589e 100644 (file)
@@ -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 <faxguy@deanox.com>
- * 
+ *
  */
 
 #include "tiffiop.h"
 #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;
-}
-
-static int JBIGSetupEncode(TIFF* tif)
-{
-        if (TIFFNumberOfStrips(tif) != 1)
-        {
-                TIFFError("JBIG", "Multistrip images not supported in encoder");
-                return 0;
-        }
-
-        return 1;
-}
+                            );
+               return 0;
+       }
 
-static int JBIGCopyEncodedData(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s)
-{
-        (void) s;
-        while (cc > 0) 
-        {
-                tsize_t n = cc;
-
-                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);
-                }
-        }
-
-        return (1);
+       pImage = jbg_dec_getimage(&decoder, 0);
+       _TIFFmemcpy(buffer, pImage, jbg_dec_getsize(&decoder));
+       jbg_dec_free(&decoder);
+       return 1;
 }
 
-static void JBIGOutputBie(unsigned char* buffer, size_t len, void *userData)
+static int JBIGSetupEncode(TIFF* tif)
 {
-        TIFF* tif = (TIFF*)userData;
-
-        if (isFillOrder(tif, tif->tif_dir.td_fillorder))
-        {
-                TIFFReverseBits(buffer, len);
-        }
+       if (TIFFNumberOfStrips(tif) != 1)
+       {
+               TIFFErrorExt(tif->tif_clientdata, "JBIG", "Multistrip images not supported in encoder");
+               return 0;
+       }
 
-        JBIGCopyEncodedData(tif, buffer, len, 0);
+       return 1;
 }
 
-static int JBIGEncode(TIFF* tif, tidata_t buffer, tsize_t size, tsample_t s)
+static int JBIGCopyEncodedData(TIFF* tif, unsigned char* pp, size_t cc, uint16 s)
 {
-        TIFFDirectory* dir = &tif->tif_dir;
-        struct jbg_enc_state encoder;
-
-       (void) size, (void) s;
+       (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;
+               }
+
+               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);
+               }
+       }
 
-        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;
+       return (1);
 }
 
-static void JBIGCleanup(TIFF* tif)
+static void JBIGOutputBie(unsigned char* buffer, size_t len, void* userData)
 {
-        JBIGState *sp = GetJBIGState(tif);
-
-        assert(sp != 0);
-
-        tif->tif_tagmethods.vgetfield = sp->vgetparent;
-        tif->tif_tagmethods.vsetfield = sp->vsetparent;
+       TIFF* tif = (TIFF*)userData;
 
-       _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);
-        }
-}
+       if (isFillOrder(tif, tif->tif_dir.td_fillorder))
+       {
+               TIFFReverseBits(buffer, (tmsize_t)len);
+       }
 
-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;
+       JBIGCopyEncodedData(tif, buffer, len, 0);
 }
 
-static int JBIGVSetField(TIFF* tif, ttag_t tag, va_list ap)
+static int JBIGEncode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s)
 {
-        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;
+       TIFFDirectory* dir = &tif->tif_dir;
+       struct jbg_enc_state encoder;
 
-                case TIFFTAG_FAXDCS:
-                        _TIFFsetString(&codec->faxdcs, va_arg(ap, char*));
-                        break;
+       (void) size, (void) s;
 
-                default:
-                        return (*codec->vsetparent)(tif, tag, ap);
-        }
+       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);
 
-        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);
-
-        /* Initialize codec private fields */
-        codec->recvparams = 0;
-        codec->subaddress = NULL;
-        codec->faxdcs = NULL;
-        codec->recvtime = 0;
-
-       /* 
-        * 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;
+       /* 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;
+
+       return 1;
 }
 
 #endif /* JBIG_SUPPORT */
index a967827e749166d5fceea881e439d3341385bc5d..f0e0aab8e4e2339bb64c6c44eefee01f72f4074b 100644 (file)
@@ -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.105 2012-02-01 01:51:00 fwarmerdam Exp $ */
 
 /*
  * Copyright (c) 1994-1997 Sam Leffler
@@ -44,8 +44,9 @@
  */
 #include <setjmp.h>
 
-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,308 @@ 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_SOF3 0xC3
+#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_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:
+                       case JPEG_MARKER_SOF1:
+                               /* 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; o<data->tif->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);
@@ -679,7 +993,7 @@ JPEGSetupDecode(TIFF* tif)
  * Set up for decoding a strip or tile.
  */
 static int
-JPEGPreDecode(TIFF* tif, tsample_t s)
+JPEGPreDecode(TIFF* tif, uint16 s)
 {
        JPEGState *sp = JState(tif);
        TIFFDirectory *td = &tif->tif_dir;
@@ -689,6 +1003,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 +1019,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 +1038,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,15 +1080,15 @@ 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) {
@@ -771,11 +1096,11 @@ JPEGPreDecode(TIFF* tif, tsample_t s)
                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);
+                                   "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
@@ -802,7 +1127,7 @@ JPEGPreDecode(TIFF* tif, tsample_t s)
                             * try to deduce Intergraph files by the presense
                             * of the tag 33918.
                             */
-                           if (!_TIFFFindFieldInfo(tif, 33918, TIFF_ANY)) {
+                           if (!TIFFFindField(tif, 33918, TIFF_ANY)) {
                                        TIFFWarningExt(tif->tif_clientdata, module,
                                        "Decompressor will try reading with "
                                        "sampling %d,%d.",
@@ -850,7 +1175,7 @@ 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;
+               tif->tif_decoderow = DecodeRowError;
                tif->tif_decodestrip = JPEGDecodeRaw;
                tif->tif_decodetile = JPEGDecodeRaw;
        } else {
@@ -858,7 +1183,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))
@@ -878,103 +1203,130 @@ JPEGPreDecode(TIFF* tif, tsample_t s)
  * "Standard" case: returned data is not downsampled.
  */
 /*ARGSUSED*/ static int
-JPEGDecode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s)
+JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
 {
-    JPEGState *sp = JState(tif);
-    tsize_t nrows;
-    (void) 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;
 
-    nrows = cc / sp->bytesperline;
-    if (cc % sp->bytesperline)
+        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 > (int) sp->cinfo.d.image_height )
-        nrows = sp->cinfo.d.image_height;
+       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;
+       /* 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 !defined(JPEG_LIB_MK1)        
-        if( sp->cinfo.d.data_precision == 12 )
+               /*
+                * For 6B, only use temporary buffer for 12 bit imagery.
+                * For Mk1 always use it.
+                */
+#if !defined(JPEG_LIB_MK1)
+               if( sp->cinfo.d.data_precision == 12 )
 #endif
-        {
-            line_work_buf = (JSAMPROW) 
-                _TIFFmalloc(sizeof(short) * sp->cinfo.d.output_width 
-                            * sp->cinfo.d.num_components );
-        }
+               {
+                       line_work_buf = (JSAMPROW)
+                           _TIFFmalloc(sizeof(short) * sp->cinfo.d.output_width
+                           * sp->cinfo.d.num_components );
+               }
 
-        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);
-
-                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);
-                    }
-                }
-                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;
+
+                                               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;
+                                       }
+                               }
+                       }
+                       else
+                       {
+                               /*
+                                * In the libjpeg6b 8bit case.  We read directly into the
+                                * TIFF buffer.
+                               */
+                               JSAMPROW bufptr = (JSAMPROW)buf;
+
+                               if (TIFFjpeg_read_scanlines(sp, &bufptr, 1) != 1)
+                                       return (0);
+                       }
+
+                       ++tif->tif_row;
+                       buf += sp->bytesperline;
+                       cc -= sp->bytesperline;
+               } while (--nrows > 0);
+
+               if( line_work_buf != NULL )
+                       _TIFFfree( line_work_buf );
+       }
 
-    /* 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);
+        /* 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);
+}
+
+/*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 +1334,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);
+               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 * sp->v_sampling ) {
+                            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;
@@ -1025,7 +1389,7 @@ JPEGDecodeRaw(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s)
 
                                for (ypos = 0; ypos < vsamp; ypos++) {
                                        JSAMPLE *inptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos];
-#ifdef JPEG_LIB_MK1
+#if defined(JPEG_LIB_MK1_OR_12BIT)
                                        JSAMPLE *outptr = (JSAMPLE*)tmpbuf + clumpoffset;
 #else
                                        JSAMPLE *outptr = (JSAMPLE*)buf + clumpoffset;
@@ -1052,7 +1416,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,14 +1428,14 @@ 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;
                                        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);
@@ -1083,14 +1447,17 @@ 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;
+/*
+                       buf += clumps_per_line*samples_per_clump;
+                       cc -= clumps_per_line*samples_per_clump;
+*/
+                       buf += sp->bytesperline * sp->v_sampling;
+                       cc -= sp->bytesperline * sp->v_sampling;
+
                        nrows -= sp->v_sampling;
                } while (nrows > 0);
 
-#ifdef JPEG_LIB_MK1
+#if defined(JPEG_LIB_MK1_OR_12BIT)
                _TIFFfree(tmpbuf);
 #endif
 
@@ -1131,8 +1498,6 @@ 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,7 +1532,12 @@ 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);
@@ -1295,7 +1665,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 +1674,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 +1693,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");
@@ -1352,8 +1728,15 @@ 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 ((td->td_photometric == PHOTOMETRIC_MINISWHITE || td->td_photometric == PHOTOMETRIC_MINISBLACK) && td->td_samplesperpixel == 1)
+                               sp->cinfo.c.in_color_space = JCS_GRAYSCALE;
+                       else if (td->td_photometric == PHOTOMETRIC_RGB)
+                               sp->cinfo.c.in_color_space = JCS_RGB;
+                       else if (td->td_photometric == PHOTOMETRIC_SEPARATED && td->td_samplesperpixel == 4)
+                               sp->cinfo.c.in_color_space = JCS_CMYK;
+                       else
+                               sp->cinfo.c.in_color_space = JCS_UNKNOWN;
+                       if (!TIFFjpeg_set_colorspace(sp, sp->cinfo.c.in_color_space))
                                return (0);
                        /* jpeg_set_colorspace set all sampling factors to 1 */
                }
@@ -1375,7 +1758,7 @@ JPEGPreEncode(TIFF* tif, tsample_t s)
        sp->cinfo.c.write_Adobe_marker = FALSE;
        /* set up table handling correctly */
         if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE))
-                return (0);
+               return (0);
        if (! (sp->jpegtablesmode & JPEGTABLESMODE_QUANT)) {
                unsuppress_quant_table(sp, 0);
                unsuppress_quant_table(sp, 1);
@@ -1416,31 +1799,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 +1870,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 +1944,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 +1970,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);
 
                        }
@@ -1578,10 +1999,12 @@ JPEGCleanup(TIFF* tif)
        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 != NULL ) {
+               if( sp->cinfo_initialized )
+                   TIFFjpeg_destroy(sp);       /* release libjpeg resources */
+               if (sp->jpegtables)             /* tag value */
+                       _TIFFfree(sp->jpegtables);
+       }
        _TIFFfree(tif->tif_data);       /* release local state */
        tif->tif_data = NULL;
 
@@ -1618,24 +2041,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 +2068,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 +2102,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 +2123,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 +2135,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 +2154,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 +2165,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 +2191,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 +2207,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 +2233,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 +2243,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 +2271,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 +2287,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 +2316,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 (file)
index 0000000..87aaa19
--- /dev/null
@@ -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:
+ */
index eb622b9b0bf0effdd7ce8bf67033fc125e75b893..eba6c08ebd9f8311e2860e2de38381ba5f360369 100644 (file)
@@ -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.35 2011-04-02 20:54:09 bfriesen Exp $ */
 
 /*
  * Copyright (c) 1997 Greg Ward Larson
  * 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,9 @@ 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);
 
        assert(cc%rowlen == 0);
        while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s))
@@ -356,9 +391,9 @@ 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);
 
        assert(cc%rowlen == 0);
        while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s))
@@ -370,14 +405,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 +430,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 +448,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 +457,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 +498,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 +518,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 +530,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 +545,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 +571,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 +599,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 +616,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 +640,9 @@ 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);
 
        assert(cc%rowlen == 0);
        while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1)
@@ -608,9 +655,9 @@ 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);
 
        assert(cc%rowlen == 0);
        while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1)
@@ -676,7 +723,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 +733,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 +745,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 +807,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 +821,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 +963,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 +976,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 +996,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 +1011,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 +1023,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 +1104,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 +1116,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 +1134,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 +1149,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 +1161,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 +1184,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 +1208,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 +1222,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 +1243,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 +1314,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 +1343,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 +1382,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 +1420,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 +1431,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 +1446,7 @@ LogLuvSetupEncode(TIFF* tif)
                                sp->tfunc = Luv24fromXYZ;
                                break;
                        case SGILOGDATAFMT_16BIT:
-                               sp->tfunc = Luv24fromLuv48;
+                               sp->tfunc = Luv24fromLuv48;  
                                break;
                        case SGILOGDATAFMT_RAW:
                                break;
@@ -1400,13 +1454,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 +1472,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 +1484,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 +1534,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 +1574,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 +1593,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 +1606,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 +1622,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 +1647,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 (file)
index 0000000..dedf1d9
--- /dev/null
@@ -0,0 +1,495 @@
+/* $Id: tif_lzma.c,v 1.4 2011-12-22 00:29:29 bfriesen Exp $ */
+
+/*
+ * Copyright (c) 2010, Andrey Kiselev <dron@ak4719.spb.edu>
+ *
+ * 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 <stdio.h>
+
+/*
+ * 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: */
index d423866359ec66186435a94548232d568d8e6c7f..fd9c7a0a74ba55c2dd0c8e976c86929cdb7f2649 100644 (file)
@@ -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.45 2011-04-02 20:54:09 bfriesen 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
  *
  * 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
 
 /*
  * 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);
-            }
-
-            DecoderState(tif)->dec_codetab = NULL;
-            DecoderState(tif)->dec_decode = NULL;
-            
-            /*
-             * Setup predictor setup.
-             */
-            (void) TIFFPredictorInit(tif);
-
-            sp = DecoderState(tif);
-        }
-            
+       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);
+
+               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,13 +258,14 @@ 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 );
         }
@@ -268,7 +276,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 +299,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 +316,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 +347,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 +371,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.
         */
@@ -428,7 +443,7 @@ LZWDecode(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s)
                        NextCode(tif, sp, bp, code, GetNextCode);
                        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 +456,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 +487,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 +509,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 +530,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 +549,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 +580,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 +594,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.
         */
@@ -632,7 +662,7 @@ LZWDecodeCompat(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s)
                        NextCode(tif, sp, bp, code, GetNextCodeCompat);
                        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 +675,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 +703,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 +733,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 +753,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 +775,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 +792,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 +857,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 +868,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 +948,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 +1026,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 +1044,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 +1057,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 +1069,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 +1095,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 +1111,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 +1130,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);
 }
index d7652bb4c132d7e6b2cf569dbb2a82db0fae3aae..524e127c13dcbb17b149f5a77b1532959e9ba9c0 100644 (file)
@@ -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.13 2010-03-10 18:56:48 bfriesen Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
 #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,12 +60,17 @@ 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;
+       if (occ % scanline)
+       {
+               TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
+               return (0);
+       }
        for (row = buf; occ > 0; occ -= scanline, row += scanline) {
                n = *bp++, cc--;
                switch (n) {
@@ -79,7 +85,7 @@ 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.
@@ -105,7 +111,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,11 +130,11 @@ 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);
 }
@@ -137,8 +143,8 @@ int
 TIFFInitNeXT(TIFF* tif, int scheme)
 {
        (void) scheme;
-       tif->tif_decoderow = NeXTDecode;
-       tif->tif_decodestrip = NeXTDecode;
+       tif->tif_decoderow = NeXTDecode;  
+       tif->tif_decodestrip = NeXTDecode;  
        tif->tif_decodetile = NeXTDecode;
        return (1);
 }
index 9ae856cfdef922fa5577eff0ce6bfa2eb290df6e..0c9301d99c5a7dbfb6ed4df2824b2443cc3b747e 100644 (file)
@@ -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.54 2011-05-31 17:05:07 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
    session.
 */
 
+#define WIN32_LEAN_AND_MEAN
+#define VC_EXTRALEAN
 
 #include "tiffiop.h"
 #ifdef OJPEG_SUPPORT
  *     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
 #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 <setjmp.h>
 #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,30 @@ 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;
        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 +553,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; n<ma; n++)
-                                       sp->qtable_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 +568,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; n<ma; n++)
-                                       sp->dctable_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 +583,21 @@ 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; n<ma; n++)
-                                       sp->actable_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);
+       TIFFSetFieldBit(tif,TIFFFieldWithTag(tif,tag)->field_bit);
        tif->tif_flags|=TIFF_DIRTYDIRECT;
        return(1);
 }
@@ -581,34 +610,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; m<sp->qtable_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; m<sp->dctable_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; m<sp->actable_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 +658,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 +675,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 +686,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 +777,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 +795,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 +850,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 +875,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 +898,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 +907,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 +933,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 +979,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 +1047,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 +1057,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 +1084,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 +1103,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;
@@ -1223,7 +1265,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 +1433,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 (3<o)
                        {
                                TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data");
+                               _TIFFfree(nb);
                                return(0);
                        }
                        if (sp->qtable[o]!=0)
@@ -1537,11 +1582,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 ((p<sp->image_length) && (p<sp->strile_length_total))
+               if (((uint32)p<sp->image_length) && ((uint32)p<sp->strile_length_total))
                {
                        TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected height");
                        return(0);
@@ -1550,11 +1594,16 @@ OJPEGReadHeaderInfoSecStreamSof(TIFF* tif, uint8 marker_id)
                /* X: Number of samples per line */
                if (OJPEGReadWord(sp,&p)==0)
                        return(0);
-               if ((p<sp->image_width) && (p<sp->strile_width))
+               if (((uint32)p<sp->image_width) && ((uint32)p<sp->strile_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 +1766,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 +1873,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 +1911,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 +1924,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;
@@ -1905,22 +1954,24 @@ OJPEGReadBufferFill(OJPEGState* sp)
                        case osibsJpegInterchangeFormat:
                                sp->in_buffer_source=osibsStrile;
                        case osibsStrile:
-                               if (sp->in_buffer_next_strile==sp->in_buffer_strile_count)  
+                               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 +2082,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 +2322,7 @@ OJPEGWriteStreamCompressed(TIFF* tif, void** mem, uint32* len)
                switch(sp->in_buffer_source)
                {
                        case osibsStrile:
-                               if (sp->in_buffer_next_strile<sp->in_buffer_strile_count)  
+                               if (sp->in_buffer_next_strile<sp->in_buffer_strile_count)
                                        sp->out_state=ososRst;
                                else
                                        sp->out_state=ososEoi;
@@ -2366,7 +2417,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 +2425,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 +2441,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");
index 3b3b2ce67ba5e7ace3edafa4132d922eab4e1be3..8c88328cf28d995d568c497b4cfb35f5ccb1c73c 100644 (file)
@@ -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
  */
 #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);
-       }
-       /*
-        * 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.common.tiff_magic == TIFF_BIGENDIAN) {
+               #ifndef WORDS_BIGENDIAN
+               tif->tif_flags |= TIFF_SWAB;
+               #endif
+       } else {
+               #ifdef WORDS_BIGENDIAN
+               tif->tif_flags |= TIFF_SWAB;
+               #endif
        }
-       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);
 }
 
 /*
index ee095f568e8a3dd610010446e3299d06e910594f..a79abe860f460094f205830ec60b37908850e1a5 100644 (file)
@@ -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.20 2010-03-10 18:56:49 bfriesen Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
 #include <stdio.h>
 
 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,37 @@ 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--;
+                       b = *bp++, cc--;      /* TODO: may be reading past input buffer here when input data is corrupt or ends prematurely */
                        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;
+                       }
+                       _TIFFmemcpy(op, bp, ++n);  /* TODO: may be reading past input buffer here when input data is corrupt or ends prematurely */
                        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 +276,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;
index ed8eb4026fff3fb91dcc6f2cdb7e4ff3c7c8257e..d8123e8db0eceada346dfc4d0d10c26067398454 100644 (file)
@@ -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.35 2011-01-06 16:00:23 fwarmerdam Exp $ */
 
 /*
  * Copyright (c) 1996-1997 Sam Leffler
  * 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;
@@ -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,35 @@ multiply(size_t m1, size_t m2)
        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));
        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 +686,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 +698,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 +744,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 +755,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 +772,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 +788,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 +798,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 +843,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 +856,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 +867,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 +882,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 +894,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 +1082,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 +1108,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 +1134,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 +1142,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 +1178,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 +1189,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 +1211,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 +1256,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 +1307,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 +1318,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 +1335,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 +1352,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 +1362,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 +1373,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;
 
index bbc221f27f915bfd7cb5e4d968521d2cdb5eca6d..f93c6645f0f87d4a5be28d2f1a15d685c0fee713 100644 (file)
@@ -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
 
 #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 */
index da0ad9892b0f48a771d49293b0eb1b1733499d66..dc7144c69e6b3bac385d188bdcc7c0c6c3c2cafe 100644 (file)
@@ -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.
  */
 
  * 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  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  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 */
+       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
index d9e4435c50be115b2febd0283126d28ec4d24791..9481eb62c83abc8da711943666c7a2b588815de0 100644 (file)
@@ -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.54 2011-04-02 20:54:09 bfriesen Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -31,7 +31,7 @@
  */
 #include "tiffiop.h"
 #include <stdio.h>
-#include <string.h>
+
 #include <ctype.h>
 
 static const char *photoNames[] = {
@@ -61,7 +61,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 +73,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 +82,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, "<unsupported data type in TIFFPrint>");
                        break;
@@ -112,11 +135,11 @@ _TIFFPrintField(FILE* fd, const TIFFFieldInfo *fip,
 }
 
 static int
-_TIFFPrettyPrintField(TIFF* tif, FILE* fd, ttag_t tag,
+_TIFFPrettyPrintField(TIFF* tif, FILE* fd, uint32 tag,
                      uint32 value_count, void *raw_data)
 {
-       //TIFFDirectory *td = &tif->tif_dir;
-
+        (void) tif;
+        
        switch (tag)
        {
                case TIFFTAG_INKSET:
@@ -127,33 +150,23 @@ _TIFFPrettyPrintField(TIFF* tif, FILE* fd, ttag_t tag,
                                        break;
                                default:
                                        fprintf(fd, "%u (0x%x)\n",
-                                               *((uint16*)raw_data),
-                                               *((uint16*)raw_data));
+                                           *((uint16*)raw_data),
+                                           *((uint16*)raw_data));
                                        break;
                        }
                        return 1;
                case TIFFTAG_DOTRANGE:
                        fprintf(fd, "  Dot Range: %u-%u\n",
-                               ((uint16*)raw_data)[0], ((uint16*)raw_data)[1]);
+                           ((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;
-
-                       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]);
+                           ((float *)raw_data)[0], ((float *)raw_data)[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 +179,23 @@ _TIFFPrettyPrintField(TIFF* tif, FILE* fd, ttag_t tag,
                         * defined as array of LONG values.
                         */
                        fprintf(fd,
-                               "  RichTIFFIPTC Data: <present>, %lu bytes\n",
-                               (unsigned long) value_count * 4);
+                           "  RichTIFFIPTC Data: <present>, %lu bytes\n",
+                           (unsigned long) value_count * 4);
                        return 1;
                case TIFFTAG_PHOTOSHOP:
                        fprintf(fd, "  Photoshop Data: <present>, %lu bytes\n",
-                               (unsigned long) value_count);
+                           (unsigned long) value_count);
                        return 1;
                case TIFFTAG_ICCPROFILE:
                        fprintf(fd, "  ICC Profile: <present>, %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));
+                           "  Sample to Nits conversion factor: %.4e\n",
+                           *((double*)raw_data));
                        return 1;
-        }
+       }
 
        return 0;
 }
@@ -199,8 +212,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 = " ";
@@ -386,18 +406,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 +448,18 @@ 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)) {
+               fprintf(fd, "  SMin Sample Value:");
+               for (i = 0; i < td->td_samplesperpixel; ++i)
+                       fprintf(fd, " %g", td->td_sminsamplevalue[i]);
+               fprintf(fd, "\n");
+       }
+       if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE)) {
+               fprintf(fd, "  SMax Sample Value:");
+               for (i = 0; i < td->td_samplesperpixel; ++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 +492,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,117 +518,130 @@ 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;
-
-            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;
+       /*
+       ** Custom tag support.
+       */
+       {
+               int  i;
+               short count;
 
-                fip = TIFFFieldWithTag(tif, tag);
-                if(fip == NULL)
-                       continue;
+               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;
 
-               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)
-                                       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);
+
+                       if(fip->field_passcount) {
+                               if(TIFFGetField(tif, tag, &value_count, &raw_data) != 1)
                                        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_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)
+                                               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;
+                                       }
                                }
                        }
-               }
 
-               /*
-                * 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, 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 __int64) td->td_stripoffset[s],
+                           (unsigned __int64) td->td_stripbytecount[s]);
+#else
+                       fprintf(fd, "    %3lu: [%8llu, %8llu]\n",
                            (unsigned long) s,
-                           (unsigned long) td->td_stripoffset[s],
-                           (unsigned long) td->td_stripbytecount[s]);
+                           (unsigned long long) td->td_stripoffset[s],
+                           (unsigned long long) td->td_stripbytecount[s]);
+#endif
        }
 }
 
index 8ac0ae66cb99b93aaa9a6ea896d453fd878368ca..594733f871224b9bbc44b7f598b733a3192bcbe2 100644 (file)
@@ -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.38 2011-12-09 03:29:10 fwarmerdam Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
 #include "tiffiop.h"
 #include <stdio.h>
 
-       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;
+        uint64 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 )
+        {
+                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 = td->td_stripbytecount[strip]
+                        - tif->tif_rawdataoff - tif->tif_rawdataloaded;
+        }
+
+        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)
+                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 +191,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 +253,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 +293,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 +309,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))&&(size<stripsize))
+               stripsize=size;
+       if (!TIFFFillStrip(tif,strip))
+               return((tmsize_t)(-1));
+       if ((*tif->tif_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 ((mb<ma)||(mb<size)||(mb>tif->tif_size))
+                       n=tif->tif_size-ma;
+               else
+                       n=size;
+               if (n!=size) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
                        TIFFErrorExt(tif->tif_clientdata, module,
-    "%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 +430,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 defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+               TIFFErrorExt(tif->tif_clientdata, module,
+                            "%I64u: Invalid strip byte count, strip %lu",
+                            (unsigned __int64) bytecount,
+                            (unsigned long) strip);
+#else
+               TIFFErrorExt(tif->tif_clientdata, module,
+                            "%llu: Invalid strip byte count, strip %lu",
+                            (unsigned long long) bytecount,
+                            (unsigned long) strip);
+#endif
+               return ((tmsize_t)(-1));
+       }
+       bytecountm = (tmsize_t)bytecount;
+       if ((uint64)bytecountm!=bytecount) {
+               TIFFErrorExt(tif->tif_clientdata, module, "Integer overflow");
+               return ((tmsize_t)(-1));
        }
-       if (size != (tsize_t)-1 && (uint32)size < bytecount)
-               bytecount = size;
-       return (TIFFReadRawStrip1(tif, strip, buf, bytecount, module));
+       if (size != (tmsize_t)(-1) && size < bytecountm)
+               bytecountm = size;
+       return (TIFFReadRawStrip1(tif, strip, buf, bytecountm, module));
 }
 
 /*
@@ -259,25 +483,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];
+               uint64 bytecount = td->td_stripbytecount[strip];
                if (bytecount <= 0) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+                       TIFFErrorExt(tif->tif_clientdata, module,
+                               "Invalid strip byte count %I64u, strip %lu",
+                                    (unsigned __int64) bytecount,
+                                    (unsigned long) strip);
+#else
                        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 %llu, strip %lu",
+                                    (unsigned long long) bytecount,
+                                    (unsigned long) strip);
+#endif
                        return (0);
                }
                if (isMapped(tif) &&
@@ -306,53 +534,72 @@ 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;
                } 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 (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 +613,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 ((mb<ma)||(mb<size)||(mb>tif->tif_size))
+                       n=tif->tif_size-ma;
+               else
+                       n=size;
+               if (n!=size) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+                       TIFFErrorExt(tif->tif_clientdata, module,
+"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,
-    "%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 %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 +731,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 +770,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];
+               uint64 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);
+#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) &&
@@ -540,41 +821,51 @@ 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;
                } 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 (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,7 +881,7 @@ 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";
 
@@ -600,21 +891,21 @@ TIFFReadBufferSetup(TIFF* tif, tdata_t bp, tsize_t size)
                        _TIFFfree(tif->tif_rawdata);
                tif->tif_rawdata = NULL;
        }
-
        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)
+                       tif->tif_rawdatasize=(tmsize_t)(-1);
+               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 +917,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 +931,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,10 +952,13 @@ 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)
 {
        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);
@@ -667,11 +966,12 @@ TIFFStartTile(TIFF* tif, ttile_t tile)
        }
        tif->tif_curtile = tile;
        tif->tif_row =
-           (tile % TIFFhowmany(td->td_imagewidth, td->td_tilewidth)) *
+           (tile % TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth)) *
                td->td_tilelength;
        tif->tif_col =
-           (tile % TIFFhowmany(td->td_imagelength, td->td_tilelength)) *
+           (tile % TIFFhowmany_32(td->td_imagelength, td->td_tilelength)) *
                td->td_tilewidth;
+        tif->tif_flags &= ~TIFF_BUF4WRITE;
        if (tif->tif_flags&TIFF_NOREADRAW)
        {
                tif->tif_rawcp = NULL;
@@ -680,10 +980,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 +1003,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 +1017,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 +1025,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 +1033,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);
index 2a2351b2ba99871bad601219aac6193394253bfc..163447ebd013b66d2a661d05649946f6c4f5cd8b 100644 (file)
@@ -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.11 2010-12-11 23:12:29 faxguy Exp $ */
 
 /*
  * Copyright (c) 1988-1996 Sam Leffler
 using namespace std;
 #endif
 
-class tiffis_data
+/*
+  ISO C++ uses a 'std::streamsize' type to define counts.  This makes
+  it similar to, (but perhaps not the same as) size_t.
+
+  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
 {
-  public:
-
-       istream *myIS;
-        long   myStreamStartPos;
+       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<tiffis_data *>(fd);
 
-        data->myIS->read((char *)buf, (int)size);
+        // Verify that type does not overflow.
+        streamsize request_size = size;
+        if (static_cast<tmsize_t>(request_size) != size)
+          return static_cast<tmsize_t>(-1);
 
-        return data->myIS->gcount();
+        data->stream->read((char *) buf, request_size);
+
+        return static_cast<tmsize_t>(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<tiffos_data *>(fd);
+       ostream         *os = data->stream;
+       ios::pos_type   pos = os->tellp();
+
+        // Verify that type does not overflow.
+        streamsize request_size = size;
+        if (static_cast<tmsize_t>(request_size) != size)
+          return static_cast<tmsize_t>(-1);
 
-       os->write((const char *)buf, size);
+       os->write(reinterpret_cast<const char *>(buf), request_size);
 
-       return ((int)os->tellp()) - pos;
+       return static_cast<tmsize_t>(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<tiffos_data *>(fd);
+       ostream         *os = data->stream;
 
        // if the stream has already failed, don't do anything
        if( os->fail() )
-               return os->tellp();
+               return static_cast<uint64>(-1);
 
        switch(whence) {
        case SEEK_SET:
-           os->seekp(data->myStreamStartPos + off, ios::beg);
+               {
+                       // Compute 64-bit offset
+                       uint64 new_offset = static_cast<uint64>(data->start_pos) + off;
+
+                       // Verify that value does not overflow
+                       ios::off_type offset = static_cast<ios::off_type>(new_offset);
+                       if (static_cast<uint64>(offset) != new_offset)
+                               return static_cast<uint64>(-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<ios::off_type>(off);
+                       if (static_cast<uint64>(offset) != off)
+                               return static_cast<uint64>(-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<ios::off_type>(off);
+                       if (static_cast<uint64>(offset) != off)
+                               return static_cast<uint64>(-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<uint64>(origin) + off) > static_cast<uint64>(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<uint64>(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<ios::off_type>(static_cast<uint64>(origin) + off), ios::beg);
                }
        }
 
-       return os->tellp();
+       return static_cast<uint64>(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<tiffis_data *>(fd);
 
        switch(whence) {
        case SEEK_SET:
-               data->myIS->seekg(data->myStreamStartPos + off, ios::beg);
-               break;
+               {
+                       // Compute 64-bit offset
+                       uint64 new_offset = static_cast<uint64>(data->start_pos) + off;
+                       
+                       // Verify that value does not overflow
+                       ios::off_type offset = static_cast<ios::off_type>(new_offset);
+                       if (static_cast<uint64>(offset) != new_offset)
+                               return static_cast<uint64>(-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<ios::off_type>(off);
+                       if (static_cast<uint64>(offset) != off)
+                               return static_cast<uint64>(-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<ios::off_type>(off);
+                       if (static_cast<uint64>(offset) != off)
+                               return static_cast<uint64>(-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<tiffos_data *>(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<tiffis_data *>(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<tiffos_data *>(fd);
        return 0;
 }
 
@@ -218,18 +333,18 @@ 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<tiffis_data *>(fd);
        return 0;
 }
 
 static int
-_tiffDummyMapProc(thandle_t , tdata_t* , toff_t* )
+_tiffDummyMapProc(thandle_t , void** base, toff_t* size )
 {
        return (0);
 }
 
 static void
-_tiffDummyUnmapProc(thandle_t , tdata_t , toff_t )
+_tiffDummyUnmapProc(thandle_t , void* base, toff_t size )
 {
 }
 
@@ -243,32 +358,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<ostream *>(fd);
+               data->start_pos = data->stream->tellp();
 
                // Open for writing.
                tif = TIFFClientOpen(name, mode,
-                               (thandle_t) data,
-                               _tiffosReadProc, _tiffosWriteProc,
-                               _tiffosSeekProc, _tiffosCloseProc,
+                               reinterpret_cast<thandle_t>(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<istream *>(fd);
+               data->start_pos = data->stream->tellg();
                // Open for reading.
                tif = TIFFClientOpen(name, mode,
-                               (thandle_t) data,
-                               _tiffisReadProc, _tiffisWriteProc,
-                               _tiffisSeekProc, _tiffisCloseProc,
+                               reinterpret_cast<thandle_t>(data),
+                               _tiffisReadProc,
+                                _tiffisWriteProc,
+                               _tiffisSeekProc,
+                                _tiffisCloseProc,
                                _tiffisSizeProc,
-                               _tiffDummyMapProc, _tiffDummyUnmapProc);
+                               _tiffDummyMapProc,
+                                _tiffDummyUnmapProc);
        }
 
        return (tif);
 }
 
+} /* extern "C" */
+
 TIFF*
 TIFFStreamOpen(const char* name, ostream *os)
 {
@@ -276,7 +399,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<int>(os->tellp()) < 0 ) {
                *os << '\0';
                os->seekp(0);
        }
@@ -293,3 +416,10 @@ TIFFStreamOpen(const char* name, istream *is)
 }
 
 /* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+  Local Variables:
+  mode: c
+  indent-tabs-mode: true
+  c-basic-offset: 8
+  End:
+*/
index 63dec6bdace463541796884709b9da3ce210ca0c..3ced5a8d546168de1b54312fcddfee835d21c447 100644 (file)
@@ -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.34 2011-04-02 20:54:09 bfriesen Exp $ */
 
 /*
  * Copyright (c) 1991-1997 Sam Leffler
  */
 #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,100 @@ 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");
+                       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];
-
-       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;
+       uint64 bytecount = td->td_stripbytecount[strip];
+
+       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 +197,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 +243,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 +267,71 @@ 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);
+       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 +340,35 @@ TIFFNewScanlineSize(TIFF* tif)
  * I/O size returned by TIFFScanlineSize which may be less
  * if data is store as separate planes).
  */
-tsize_t
-TIFFRasterScanlineSize(TIFF* tif)
+uint64
+TIFFRasterScanlineSize64(TIFF* tif)
 {
+       static const char module[] = "TIFFRasterScanlineSize64";
        TIFFDirectory *td = &tif->tif_dir;
-       tsize_t scanline;
-       
-       scanline = multiply (tif, td->td_bitspersample, td->td_imagewidth,
-                            "TIFFRasterScanlineSize");
+       uint64 scanline;
+
+       scanline = _TIFFMultiply64(tif, td->td_bitspersample, td->td_imagewidth, module);
        if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
-               scanline = multiply (tif, scanline, td->td_samplesperpixel,
-                                    "TIFFRasterScanlineSize");
-               return ((tsize_t) TIFFhowmany8(scanline));
+               scanline = _TIFFMultiply64(tif, scanline, td->td_samplesperpixel, module);
+               return (TIFFhowmany8_64(scanline));
        } else
-               return ((tsize_t) multiply (tif, TIFFhowmany8(scanline),
-                                           td->td_samplesperpixel,
-                                           "TIFFRasterScanlineSize"));
+               return (_TIFFMultiply64(tif, TIFFhowmany8_64(scanline),
+                   td->td_samplesperpixel, module));
+}
+tmsize_t
+TIFFRasterScanlineSize(TIFF* tif)
+{
+       static const char module[] = "TIFFRasterScanlineSize";
+       uint64 m;
+       tmsize_t n;
+       m=TIFFRasterScanlineSize64(tif);
+       n=(tmsize_t)m;
+       if ((uint64)n!=m)
+       {
+               TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow");
+               n=0;
+       }
+       return(n);
 }
 
 /* vim: set ts=8 sts=8 sw=8 noet: */
index e4f1a6d1e234da13200c13bbdc57f8a4dcf4bf4e..f37e33f1c9925113b9a9cc1b87feba6d07bca064 100644 (file)
@@ -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]];
index 8e7a1258415c4b3dafd3ef9b8c0d994165eca486..390891c98bde1a07c593e6560f754826f656f11a 100644 (file)
@@ -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 <assert.h>
 #ifdef THUNDER_SUPPORT
 /*
  * TIFF Library.
 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 */
index d8379e61b307a3b071b04b42b8c51048ae53229e..062d943f6710d1b377c472bc3680f5f22642097d 100644 (file)
@@ -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.22 2010-07-01 15:33:28 dron Exp $ */
 
 /*
  * Copyright (c) 1991-1997 Sam Leffler
  */
 #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,66 @@ 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
-TIFFTileRowSize(TIFF* tif)
+uint64
+TIFFTileRowSize64(TIFF* tif)
 {
        TIFFDirectory *td = &tif->tif_dir;
-       tsize_t rowsize;
-       
+       uint64 rowsize;
+
        if (td->td_tilelength == 0 || td->td_tilewidth == 0)
-               return ((tsize_t) 0);
-       rowsize = multiply(tif, td->td_bitspersample, td->td_tilewidth,
-                          "TIFFTileRowSize");
+               return (0);
+       rowsize = _TIFFMultiply64(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));
+               rowsize = _TIFFMultiply64(tif, rowsize, td->td_samplesperpixel,
+                   "TIFFTileRowSize");
+       return (TIFFhowmany8_64(rowsize));
+}
+tmsize_t
+TIFFTileRowSize(TIFF* tif)
+{
+       static const char module[] = "TIFFTileRowSize";
+       uint64 m;
+       tmsize_t n;
+       m=TIFFTileRowSize64(tif);
+       n=(tmsize_t)m;
+       if ((uint64)n!=m)
+       {
+               TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
+               n=0;
+       }
+       return(n);
 }
 
 /*
  * 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 +195,70 @@ 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);
+               assert((ycbcrsubsampling[0]==1)||(ycbcrsubsampling[0]==2)||(ycbcrsubsampling[0]==4));
+               assert((ycbcrsubsampling[1]==1)||(ycbcrsubsampling[1]==2)||(ycbcrsubsampling[1]==4));
+               if (ycbcrsubsampling[0]*ycbcrsubsampling[1]==0)
+               {
+                       TIFFErrorExt(tif->tif_clientdata,module,
+                           "Invalid YCbCr subsampling");
                        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 +283,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: */
index e0f1a8ddf221e745ead9b58c13732005157af140..7c5cc50f80379d72e4eb3437dd2539276d14f28b 100644 (file)
@@ -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.22 2010-03-10 18:56:49 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.
  */
 
  * 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 <sys/types.h>
 #endif
 
+#include <errno.h>
+
 #include <stdarg.h>
 #include <stdlib.h>
 #include <sys/stat.h>
 # include <fcntl.h>
 #endif
 
+#ifdef HAVE_IO_H
+# include <io.h>
+#endif
+
 #include "tiffiop.h"
 
-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)
 {
-       return ((tsize_t) read((int) fd, buf, (size_t) size));
+       size_t size_io = (size_t) size;
+       if ((tmsize_t) size_io != size)
+       {
+               errno=EINVAL;
+               return (tmsize_t) -1;
+       }
+       return ((tmsize_t) read((int) 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));
+       size_t size_io = (size_t) size;
+       if ((tmsize_t) size_io != size)
+       {
+               errno=EINVAL;
+               return (tmsize_t) -1;
+       }
+       return ((tmsize_t) write((int) 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));
+       off_t off_io = (off_t) off;
+       if ((uint64) off_io != off)
+       {
+               errno=EINVAL;
+               return (uint64) -1; /* this is really gross */
+       }
+       return((uint64)lseek((int)fd,off_io,whence));
 }
 
 static int
 _tiffCloseProc(thandle_t fd)
 {
-       return (close((int) fd));
+       return(close((int)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
+       if (fstat((int)fd,&sb)<0)
+               return(0);
+       else
+               return((uint64)sb.st_size);
 }
 
 #ifdef HAVE_MMAP
 #include <sys/mman.h>
 
 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) {
+               *pbase = (void*)
+                   mmap(0, (size_t)sizem, PROT_READ, MAP_SHARED, (int) fd, 0);
+               if (*pbase != (void*) -1) {
+                       *psize = (tmsize_t)sizem;
                        return (1);
                }
        }
@@ -104,21 +127,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;
 }
@@ -150,22 +173,18 @@ 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);
                return ((TIFF *)0);
@@ -195,11 +214,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 +251,37 @@ TIFFOpenW(const wchar_t* name, const char* mode)
 #endif
 
 void*
-_TIFFmalloc(tsize_t s)
+_TIFFmalloc(tmsize_t s)
 {
        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 +306,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
index 218dab566e79a75a6a4ccf2610cfd90ace408fda..f92c843d88d0545c30cab02aa73e04872e3c9e43 100644 (file)
@@ -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.
index fe974d909ff5cbfdd78a857c0875bf84a67c2ac7..423b636e6e34ccb4ff94c536e7a225557fd9a588 100644 (file)
@@ -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
index 2ab944b12cf9099e2837ceba8e0ed5d17c114bfd..2cf1de93f2bfd128efd6d267fc1075c31e544b9b 100644 (file)
@@ -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.39 2011-12-22 17:07:57 bfriesen Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
 
 #include <windows.h>
 
-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,48 @@ 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));
+       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 +377,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 +408,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;
index bd084181d0a6cd78668eb2a78dcc5c8cb981be8c..eaa1f8143c20dc3b3a2230a5ea5c870bd47fece9 100644 (file)
@@ -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.36 2011-02-18 20:53:04 fwarmerdam 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.
  */
 
 #include "tiffiop.h"
 #include <stdio.h>
 
-#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,7 @@ 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);
                tif->tif_row =
                    (strip % td->td_stripsperimage) * td->td_rowsperstrip;
                if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
@@ -161,10 +163,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 +180,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 +200,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,19 +215,22 @@ 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;
+
        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;
+       tif->tif_rawcp = tif->tif_rawdata;  
 
-        if( td->td_stripbytecount[strip] > 0 )
+       if( td->td_stripbytecount[strip] > 0 )
         {
            /* Force TIFFAppendToStrip() to consider placing data at end
                of file. */
@@ -233,23 +238,23 @@ TIFFWriteEncodedStrip(TIFF* tif, tstrip_t strip, tdata_t data, tsize_t cc)
         }
         
        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 +265,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 +284,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 +295,25 @@ 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;
        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 +321,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 +336,20 @@ 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;
 
        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,13 +357,15 @@ 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 )
         {
            /* Force TIFFAppendToStrip() to consider placing data at end
                of file. */
@@ -370,20 +376,20 @@ TIFFWriteEncodedTile(TIFF* tif, ttile_t tile, tdata_t data, tsize_t cc)
         * Compute tiles per row & per column to compute
         * current row and column
         */
-       tif->tif_row = (tile % TIFFhowmany(td->td_imagelength, td->td_tilelength))
+       tif->tif_row = (tile % TIFFhowmany_32(td->td_imagelength, td->td_tilelength))
                * td->td_tilelength;
-       tif->tif_col = (tile % TIFFhowmany(td->td_imagewidth, td->td_tilewidth))
+       tif->tif_col = (tile % TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth))
                * 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 +399,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 +425,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 +461,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 +489,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 +513,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 +528,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 +557,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 +568,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 +581,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 +599,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 +635,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 +670,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 +678,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 ((m<tif->tif_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 +712,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,
index 15091f8daafca6ec20ac4da8127dc24e6a2b7f4f..f5aa2a9647a229264cb035b86457977fdb7e0549 100644 (file)
@@ -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.31 2011-01-06 16:00:23 fwarmerdam Exp $ */
 
 /*
  * Copyright (c) 1995-1997 Sam Leffler
  * 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", sp->stream.msg);
                return (0);
        } else {
                sp->state |= ZSTATE_INIT_DECODE;
@@ -111,74 +118,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, 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);
        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", sp->stream.msg);
                return (0);
        } else {
                sp->state |= ZSTATE_INIT_ENCODE;
@@ -190,17 +223,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 +251,37 @@ 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",
+                           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 ZIPPreEncode */
                }
        } while (sp->stream.avail_in > 0);
        return (1);
@@ -242,8 +294,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 +304,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",
+                           sp->stream.msg);
+                       return (0);
                }
        } while (state != Z_STREAM_END);
        return (1);
@@ -283,11 +334,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 +347,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",
+                                   sp->stream.msg);
                                return (0);
                        }
                }
@@ -320,7 +371,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 +385,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 +401,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 +410,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 +434,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;
index 0d4ab9f819f489bcc3ba880a3751c491719dd99d..5c32d3ae98db7cdc6528de6b77f7876c446eeef0 100644 (file)
@@ -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.67 2011-01-24 21:06:32 olivier Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
  *    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;
+
+typedef TIFF_INT16_T  int16;
+typedef TIFF_UINT16_T uint16;
+
+typedef TIFF_INT32_T  int32;
+typedef TIFF_UINT32_T uint32;
 
-/* For TIFFReassignTagToIgnore */
-enum TIFFIgnoreSense /* IGNORE tag table */
-{
-       TIS_STORE,
-       TIS_EXTRACT,
-       TIS_EMPTY
-};
+typedef TIFF_INT64_T  int64;
+typedef TIFF_UINT64_T uint64;
 
 /*
- * TIFF header.
+ * 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        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 int uint16_vap;
 
 /*
- * 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.
+ * TIFF header.
  */
-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;
+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;
+
 
 /*
  * NB: In the comments below,
@@ -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;
 
 /*
@@ -196,6 +187,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 */
@@ -576,6 +568,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 b/thirdparty/libtiff/tiffconf.h
deleted file mode 100644 (file)
index 68dfcf0..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
-  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_
-
-/* Define to 1 if the system has the type `int16'. */
-/* #undef HAVE_INT16 */
-
-/* Define to 1 if the system has the type `int32'. */
-/* #undef HAVE_INT32 */
-
-/* Define to 1 if the system has the type `int8'. */
-/* #undef HAVE_INT8 */
-
-/* The size of a `int', as computed by sizeof. */
-#define SIZEOF_INT 4
-
-/* The size of a `long', as computed by sizeof. */
-#define SIZEOF_LONG 4
-
-/* Signed 64-bit type formatter */
-#define TIFF_INT64_FORMAT "%I64d"
-
-/* Signed 64-bit type */
-#ifdef _MSC_VER
-#define TIFF_INT64_T signed __int64
-#else
-#define TIFF_INT64_T long long
-#endif
-
-/* Unsigned 64-bit type formatter */
-#define TIFF_UINT64_FORMAT "%I64u"
-
-/* Unsigned 64-bit type */
-#ifdef _MSC_VER
-#define TIFF_UINT64_T unsigned __int64
-#else
-#define TIFF_UINT64_T unsigned long long
-#endif
-
-/* Compatibility stuff. */
-
-/* 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 JPEG compression (requires IJG JPEG library) */
-/* #undef JPEG_SUPPORT */
-
-/* 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 Pixar log-format algorithm (requires Zlib) */
-/* #undef PIXARLOG_SUPPORT */
-
-/* Support ThunderScan 4-bit RLE algorithm */
-#define THUNDER_SUPPORT 1
-
-/* Support Deflate compression */
-/* #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
-
-/* 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
-
-/*
- * 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_ */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
diff --git a/thirdparty/libtiff/tiffconf.h.cmake.in b/thirdparty/libtiff/tiffconf.h.cmake.in
new file mode 100644 (file)
index 0000000..53a66d4
--- /dev/null
@@ -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 <stdint.h>
+#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.in b/thirdparty/libtiff/tiffconf.h.in
new file mode 100644 (file)
index 0000000..6da9c5a
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+  Configuration defines for installed libtiff.
+  This file maintained for backward compatibility. Do not use definitions
+  from this file in your programs.
+*/
+
+#ifndef _TIFFCONF_
+#define _TIFFCONF_
+
+/* Signed 16-bit type */
+#undef TIFF_INT16_T
+
+/* Signed 32-bit type */
+#undef TIFF_INT32_T
+
+/* Signed 64-bit type */
+#undef TIFF_INT64_T
+
+/* 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 */
+#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 */
+#undef HAVE_IEEEFP
+
+/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
+#undef HOST_FILLORDER
+
+/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian
+   (Intel) */
+#undef HOST_BIGENDIAN
+
+/* Support CCITT Group 3 & 4 algorithms */
+#undef CCITT_SUPPORT
+
+/* Support JPEG compression (requires IJG JPEG library) */
+#undef JPEG_SUPPORT
+
+/* Support JBIG compression (requires JBIG-KIT library) */
+#undef JBIG_SUPPORT
+
+/* Support LogLuv high dynamic range encoding */
+#undef LOGLUV_SUPPORT
+
+/* Support LZW algorithm */
+#undef LZW_SUPPORT
+
+/* Support NeXT 2-bit RLE algorithm */
+#undef NEXT_SUPPORT
+
+/* Support Old JPEG compresson (read contrib/ojpeg/README first! Compilation
+   fails with unpatched IJG JPEG library) */
+#undef OJPEG_SUPPORT
+
+/* Support Macintosh PackBits algorithm */
+#undef PACKBITS_SUPPORT
+
+/* Support Pixar log-format algorithm (requires Zlib) */
+#undef PIXARLOG_SUPPORT
+
+/* Support ThunderScan 4-bit RLE algorithm */
+#undef THUNDER_SUPPORT
+
+/* Support Deflate compression */
+#undef ZIP_SUPPORT
+
+/* Support strip chopping (whether or not to convert single-strip uncompressed
+   images to mutiple strips of ~8Kb to reduce memory usage) */
+#undef STRIPCHOP_DEFAULT
+
+/* Enable SubIFD tag (330) support */
+#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. */
+#undef DEFAULT_EXTRASAMPLE_AS_ALPHA
+
+/* Pick up YCbCr subsampling info from the JPEG data stream to support files
+   lacking the tag (default enabled). */
+#undef CHECK_JPEG_YCBCR_SUBSAMPLING
+
+/* Support MS MDI magic number files as TIFF */
+#undef MDI_SUPPORT
+
+/*
+ * 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_ */
index 36e4997a914ab9e2545e7d33f658b3632bc91509..6ca7434311683b9db5fc409df39f35495f60582f 100644 (file)
@@ -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.89 2012-02-18 16:20:26 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,
@@ -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 <windows.h>
 # 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 <stdio.h>
@@ -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,258 +270,267 @@ 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*); 
-
-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);
+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 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 {
-       ttag_t  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 */
-        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 */
-} TIFFFieldInfo;
+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 *);
+
+typedef int (*TIFFVSetMethod)(TIFF*, uint32, va_list);
+typedef int (*TIFFVGetMethod)(TIFF*, uint32, va_list);
+typedef void (*TIFFPrintMethod)(TIFF*, FILE*, long);
 
-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 */
+    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*);
-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);
+
+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 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 TIFFCheckpointDirectory(TIFF *);
+extern int TIFFRewriteDirectory(TIFF *);
 
 #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);
+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*, 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);
+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*, 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*);
+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*);
+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*,
+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);
+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*);
+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);
+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);
+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 int TIFFCIELabToRGBInit(TIFFCIELabToRGB*, const TIFFDisplay *, float*);
 extern void TIFFCIELabToXYZ(TIFFCIELabToRGB *, uint32, int32, int32,
-                           float *, float *, float *);
+    float *, float *, float *);
 extern void TIFFXYZToRGB(TIFFCIELabToRGB *, float, float, float,
-                        uint32 *, uint32 *, uint32 *);
+    uint32 *, uint32 *, uint32 *);
 
 extern int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB*, float*, float*);
 extern void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *, uint32, int32, int32,
-                          uint32 *, uint32 *, uint32 *);
+    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 */
+       short   field_writecount;       /* write count/TIFF_VARIABLE */
+       TIFFDataType field_type;        /* type of associated data */
+        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 */
+} TIFFFieldInfo;
+
+extern int TIFFMergeFieldInfo(TIFF*, const TIFFFieldInfo[], uint32);
+        
 #if defined(c_plusplus) || defined(__cplusplus)
 }
 #endif
index ee3fd32c7429b3d67e1369981615d79bbf443db3..ed994f115653ce73ee9437743d4295df9604749e 100644 (file)
@@ -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 <iostream>
 #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_ */
 
index a064039f6b880b60abf3f269eb5b963b811f1ace..7bed4abdabf03ca59108a8facfa6c0ceab5d7ecf 100644 (file)
@@ -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.82 2011-02-18 20:53:05 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,167 +74,180 @@ 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        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 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*, 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 */
+       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        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 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,(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)
@@ -253,86 +260,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 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 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 int TIFFInitDumpMode(TIFF*, int);
+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 _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 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 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)
index 314a22a0ae912de55d71e39f7af278b6f595a813..fbdc5a10e73fa9061bd8052443c83651f79deeb4 100644 (file)
@@ -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.1\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 20120218