vendor: OpenCV 5.0.0 snapshot at 40738fb16ceddb5fb3fea747585f7ce6abb0605b

This commit is contained in:
Gitea Mirror Bot
2026-08-22 00:10:33 +08:00
commit f7f077da11
6933 changed files with 2335208 additions and 0 deletions
+483
View File
@@ -0,0 +1,483 @@
# ----------------------------------------------------------------------------
# CMake file for libtiff. See root CMakeLists.txt
#
# ----------------------------------------------------------------------------
project(${TIFF_LIBRARY})
include(CheckCSourceCompiles)
include(CheckFunctionExists)
include(CheckIncludeFile)
include(CheckTypeSize)
# Find libm, if available
find_library(M_LIBRARY m)
check_include_file(assert.h HAVE_ASSERT_H)
if(NOT MSVC)
check_include_file(dlfcn.h HAVE_DLFCN_H)
endif()
check_include_file(fcntl.h HAVE_FCNTL_H)
check_include_file(inttypes.h HAVE_INTTYPES_H)
check_include_file(io.h HAVE_IO_H)
check_include_file(limits.h HAVE_LIMITS_H)
check_include_file(malloc.h HAVE_MALLOC_H)
check_include_file(memory.h HAVE_MEMORY_H)
check_include_file(search.h HAVE_SEARCH_H)
check_include_file(stdint.h HAVE_STDINT_H)
check_include_file(string.h HAVE_STRING_H)
if(NOT MSVC)
check_include_file(strings.h HAVE_STRINGS_H)
check_include_file(sys/time.h HAVE_SYS_TIME_H)
endif()
check_include_file(sys/types.h HAVE_SYS_TYPES_H)
if(NOT MSVC)
check_include_file(unistd.h HAVE_UNISTD_H)
endif()
# Inspired from /usr/share/autoconf/autoconf/c.m4
foreach(inline_keyword "inline" "__inline__" "__inline")
if(NOT DEFINED C_INLINE)
set(CMAKE_REQUIRED_DEFINITIONS_SAVE ${CMAKE_REQUIRED_DEFINITIONS})
set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
"-Dinline=${inline_keyword}")
check_c_source_compiles("
typedef int foo_t;
static inline foo_t static_foo() {return 0;}
foo_t foo(){return 0;}
int main(int argc, char *argv[]) {return 0;}"
C_HAS_${inline_keyword})
set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS_SAVE})
if(C_HAS_${inline_keyword})
set(C_INLINE TRUE)
set(INLINE_KEYWORD "${inline_keyword}")
endif()
endif()
endforeach()
if(NOT DEFINED C_INLINE)
set(INLINE_KEYWORD)
endif()
# Check type sizes
# NOTE: Could be replaced with C99 <stdint.h>
check_type_size("signed short" SIZEOF_SIGNED_SHORT)
check_type_size("unsigned short" SIZEOF_UNSIGNED_SHORT)
check_type_size("signed int" SIZEOF_SIGNED_INT)
check_type_size("unsigned int" SIZEOF_UNSIGNED_INT)
check_type_size("signed long" SIZEOF_SIGNED_LONG)
check_type_size("unsigned long" SIZEOF_UNSIGNED_LONG)
check_type_size("signed long long" SIZEOF_SIGNED_LONG_LONG)
check_type_size("unsigned long long" SIZEOF_UNSIGNED_LONG_LONG)
check_type_size("unsigned char *" SIZEOF_UNSIGNED_CHAR_P)
set(CMAKE_EXTRA_INCLUDE_FILES_SAVE ${CMAKE_EXTRA_INCLUDE_FILES})
set(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES} "stddef.h")
check_type_size("size_t" SIZEOF_SIZE_T)
check_type_size("ptrdiff_t" SIZEOF_PTRDIFF_T)
set(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES_SAVE})
set(TIFF_INT8_T "signed char")
set(TIFF_UINT8_T "unsigned char")
set(TIFF_INT16_T "signed short")
set(TIFF_UINT16_T "unsigned short")
if(SIZEOF_SIGNED_INT EQUAL 4)
set(TIFF_INT32_T "signed int")
set(TIFF_INT32_FORMAT "%d")
elseif(SIZEOF_SIGNED_LONG EQUAL 4)
set(TIFF_INT32_T "signed long")
set(TIFF_INT32_FORMAT "%ld")
endif()
if(SIZEOF_UNSIGNED_INT EQUAL 4)
set(TIFF_UINT32_T "unsigned int")
set(TIFF_UINT32_FORMAT "%u")
elseif(SIZEOF_UNSIGNED_LONG EQUAL 4)
set(TIFF_UINT32_T "unsigned long")
set(TIFF_UINT32_FORMAT "%lu")
endif()
if(SIZEOF_SIGNED_LONG EQUAL 8)
set(TIFF_INT64_T "signed long")
set(TIFF_INT64_FORMAT "%ld")
elseif(SIZEOF_SIGNED_LONG_LONG EQUAL 8)
set(TIFF_INT64_T "signed long long")
if(MINGW)
set(TIFF_INT64_FORMAT "%I64d")
else()
set(TIFF_INT64_FORMAT "%lld")
endif()
endif()
if(SIZEOF_UNSIGNED_LONG EQUAL 8)
set(TIFF_UINT64_T "unsigned long")
set(TIFF_UINT64_FORMAT "%lu")
elseif(SIZEOF_UNSIGNED_LONG_LONG EQUAL 8)
set(TIFF_UINT64_T "unsigned long long")
if(MINGW)
set(TIFF_UINT64_FORMAT "%I64u")
else()
set(TIFF_UINT64_FORMAT "%llu")
endif()
endif()
if(SIZEOF_UNSIGNED_INT EQUAL SIZEOF_SIZE_T)
set(TIFF_SIZE_T "uint32_t")
set(TIFF_SIZE_FORMAT "%u")
set(TIFF_SSIZE_T "int32_t")
set(TIFF_SSIZE_FORMAT "%d")
elseif(SIZEOF_UNSIGNED_LONG EQUAL SIZEOF_SIZE_T)
set(TIFF_SIZE_T "uint64_t")
set(TIFF_SIZE_FORMAT "%lu")
set(TIFF_SSIZE_T "int64_t")
set(TIFF_SSIZE_FORMAT "%ld")
elseif(SIZEOF_UNSIGNED_LONG_LONG EQUAL SIZEOF_SIZE_T)
set(TIFF_SIZE_T "uint64_t")
if(MINGW)
set(TIFF_SIZE_FORMAT "%I64u")
set(TIFF_SSIZE_FORMAT "%I64d")
else()
set(TIFF_SIZE_FORMAT "%llu")
set(TIFF_SSIZE_FORMAT "%lld")
endif()
endif()
if(SIZEOF_SIGNED_INT EQUAL SIZEOF_UNSIGNED_CHAR_P)
elseif(SIZEOF_SIGNED_LONG EQUAL SIZEOF_UNSIGNED_CHAR_P)
elseif(SIZEOF_SIGNED_LONG_LONG EQUAL SIZEOF_UNSIGNED_CHAR_P)
set(TIFF_SSIZE_T "signed long long")
if(MINGW)
else()
endif()
endif()
if(NOT SIZEOF_PTRDIFF_T)
set(TIFF_PTRDIFF_T "${TIFF_SSIZE_T}")
set(TIFF_PTRDIFF_FORMAT "${SSIZE_FORMAT}")
else()
set(TIFF_PTRDIFF_T "ptrdiff_t")
set(TIFF_PTRDIFF_FORMAT "%ld")
endif()
# Nonstandard int types
if(NOT MSVC)
check_type_size(INT8 int8)
set(HAVE_INT8 ${INT8})
check_type_size(INT16 int16)
set(HAVE_INT16 ${INT16})
check_type_size(INT32 int32)
set(HAVE_INT32 ${INT32})
endif()
# Check functions
if(NOT MSVC)
set(CMAKE_REQUIRED_LIBRARIES_SAVE ${CMAKE_REQUIRED_LIBRARIES})
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${M_LIBRARY})
check_function_exists(floor HAVE_FLOOR)
check_function_exists(pow HAVE_POW)
check_function_exists(sqrt HAVE_SQRT)
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES_SAVE})
endif()
if(NOT MSVC)
check_function_exists(isascii HAVE_ISASCII)
check_function_exists(memset HAVE_MEMSET)
check_function_exists(mmap HAVE_MMAP)
check_function_exists(getopt HAVE_GETOPT)
endif()
check_function_exists(memmove HAVE_MEMMOVE)
check_function_exists(setmode HAVE_SETMODE)
check_function_exists(strcasecmp HAVE_STRCASECMP)
check_function_exists(strchr HAVE_STRCHR)
check_function_exists(strrchr HAVE_STRRCHR)
check_function_exists(strstr HAVE_STRSTR)
check_function_exists(strtol HAVE_STRTOL)
check_function_exists(strtol HAVE_STRTOUL)
check_function_exists(strtoull HAVE_STRTOULL)
check_function_exists(lfind HAVE_LFIND)
# CPU bit order
set(fillorder FILLORDER_MSB2LSB)
if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "i.*86.*" OR
CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "amd64.*" OR
# AMD64 on Windows
CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "AMD64" OR
CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86_64.*")
set(fillorder FILLORDER_LSB2MSB)
endif()
set(HOST_FILLORDER ${fillorder} CACHE STRING "Native CPU bit order")
mark_as_advanced(HOST_FILLORDER)
# CPU endianness
include(TestBigEndian)
test_big_endian(bigendian)
if(bigendian)
set(bigendian ON)
else()
set(bigendian OFF)
endif()
set(HOST_BIG_ENDIAN ${bigendian} CACHE STRING "Native CPU bit order")
mark_as_advanced(HOST_BIG_ENDIAN)
if(HOST_BIG_ENDIAN)
set(HOST_BIG_ENDIAN 1)
else()
set(HOST_BIG_ENDIAN 0)
endif()
if(HOST_BIG_ENDIAN)
add_definitions(-DWORDS_BIGENDIAN)
endif()
# IEEE floating point
set(HAVE_IEEEFP 1 CACHE STRING "IEEE floating point is available")
mark_as_advanced(HAVE_IEEEFP)
# Large file support
if(UNIX OR MINGW)
if(ANDROID AND (ANDROID_NATIVE_API_LEVEL LESS 21) AND CV_GCC)
# Android NDK build problem: 'mmap' issue with GCC and API<21
else()
# This might not catch every possibility catered for by
# AC_SYS_LARGEFILE.
add_definitions(-D_FILE_OFFSET_BITS=64)
set(FILE_OFFSET_BITS 64)
endif()
endif()
# Documentation install directory (default to cmake project docdir)
set(LIBTIFF_DOCDIR "${CMAKE_INSTALL_FULL_DOCDIR}")
# Options to enable and disable internal codecs
option(ccitt "support for CCITT Group 3 & 4 algorithms" ON)
set(CCITT_SUPPORT ${ccitt})
option(packbits "support for Macintosh PackBits algorithm" ON)
set(PACKBITS_SUPPORT ${packbits})
option(lzw "support for LZW algorithm" ON)
set(LZW_SUPPORT ${lzw})
option(thunder "support for ThunderScan 4-bit RLE algorithm" ON)
set(THUNDER_SUPPORT ${thunder})
option(next "support for NeXT 2-bit RLE algorithm" ON)
set(NEXT_SUPPORT ${next})
option(logluv "support for LogLuv high dynamic range algorithm" ON)
set(LOGLUV_SUPPORT ${logluv})
# Option for Microsoft Document Imaging
option(mdi "support for Microsoft Document Imaging" ON)
set(MDI_SUPPORT ${mdi})
# ZLIB
set(ZLIB_SUPPORT 0)
if(ZLIB_LIBRARY)
set(ZLIB_SUPPORT 1)
endif()
set(ZIP_SUPPORT ${ZLIB_SUPPORT})
set(PIXARLOG_SUPPORT FALSE)
# JPEG
set(JPEG_SUPPORT FALSE)
if(HAVE_JPEG)
set(JPEG_SUPPORT TRUE)
if(TARGET ${JPEG_LIBRARY} AND DEFINED ${JPEG_LIBRARY}_BINARY_DIR)
include_directories("${${JPEG_LIBRARY}_BINARY_DIR}")
endif()
include_directories(${JPEG_INCLUDE_DIR})
endif()
option(old-jpeg "support for Old JPEG compression (read-only)" OFF) # OpenCV: changed to OFF
set(OJPEG_SUPPORT FALSE)
if(JPEG_SUPPORT AND old-jpeg)
set(OJPEG_SUPPORT TRUE)
endif()
# OpenCV: turned off
set(JBIG_SUPPORT 0)
set(LZMA_SUPPORT 0) # OpenCV: turned off
set(JPEG12_FOUND FALSE) # OpenCV: turned off
set(STRIPCHOP_DEFAULT)
set(STRIP_SIZE_DEFAULT 8192)
# Win32 IO
set(win32_io FALSE)
if(WIN32 AND NOT WINRT)
set(win32_io TRUE)
endif()
set(USE_WIN32_FILEIO ${win32_io} CACHE BOOL "Use win32 IO system (Microsoft Windows only)")
if(USE_WIN32_FILEIO)
set(USE_WIN32_FILEIO TRUE)
else()
set(USE_WIN32_FILEIO FALSE)
endif()
# Orthogonal features
# OpenCV: turned ON
set(SUBIFD_SUPPORT 1)
set(DEFAULT_EXTRASAMPLE_AS_ALPHA 1)
set(CHECK_JPEG_YCBCR_SUBSAMPLING 1)
if(JPEG_INCLUDE_DIR)
list(APPEND TIFF_INCLUDES ${JPEG_INCLUDE_DIR})
endif()
if(JPEG12_INCLUDE_DIR)
list(APPEND TIFF_INCLUDES ${JPEG12_INCLUDE_DIR})
endif()
if(JBIG_INCLUDE_DIR)
list(APPEND TIFF_INCLUDES ${JBIG_INCLUDE_DIR})
endif()
if(LIBLZMA_INCLUDE_DIRS)
list(APPEND TIFF_INCLUDES ${LIBLZMA_INCLUDE_DIRS})
endif()
# Libraries required by libtiff
set(TIFF_LIBRARY_DEPS)
if(M_LIBRARY)
list(APPEND TIFF_LIBRARY_DEPS ${M_LIBRARY})
endif()
if(ZLIB_LIBRARIES)
list(APPEND TIFF_LIBRARY_DEPS ${ZLIB_LIBRARIES})
endif()
if(JPEG_LIBRARIES)
list(APPEND TIFF_LIBRARY_DEPS ${JPEG_LIBRARIES})
endif()
if(JPEG12_LIBRARIES)
list(APPEND TIFF_LIBRARY_DEPS ${JPEG12_LIBRARIES})
endif()
if(JBIG_LIBRARIES)
list(APPEND TIFF_LIBRARY_DEPS ${JBIG_LIBRARIES})
endif()
if(LIBLZMA_LIBRARIES)
list(APPEND TIFF_LIBRARY_DEPS ${LIBLZMA_LIBRARIES})
endif()
set(LIBTIFF_MAJOR_VERSION "4")
set(LIBTIFF_MINOR_VERSION "7")
set(LIBTIFF_MICRO_VERSION "1")
set(LIBTIFF_VERSION "${LIBTIFF_MAJOR_VERSION}.${LIBTIFF_MINOR_VERSION}.${LIBTIFF_MICRO_VERSION}")
file(READ "RELEASE-DATE" LIBTIFF_RELEASE_DATE content)
set(TIFF_MAX_DIR_COUNT "1048576")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tif_config.h.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/tif_config.h"
@ONLY)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tiffconf.h.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/tiffconf.h"
@ONLY)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tiffvers.h.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/tiffvers.h"
@ONLY)
ocv_include_directories("${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}" ${ZLIB_INCLUDE_DIRS})
set(lib_srcs
tif_aux.c
tif_close.c
tif_codec.c
tif_color.c
tif_compress.c
tif_dir.c
tif_dirinfo.c
tif_dirread.c
tif_dirwrite.c
tif_dumpmode.c
tif_error.c
tif_extension.c
tif_fax3.c
tif_fax3sm.c
tif_flush.c
tif_getimage.c
tif_hash_set.c
tif_jbig.c
tif_jpeg_12.c
tif_jpeg.c
tif_luv.c
tif_lzma.c
tif_lzw.c
tif_next.c
tif_ojpeg.c
tif_open.c
tif_packbits.c
tif_pixarlog.c
tif_predict.c
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_webp.c
tif_write.c
tif_zip.c
tif_zstd.c
tif_stream.cxx
t4.h
tif_dir.h
tif_fax3.h
tif_hash_set.h
tif_predict.h
tiff.h
tiffio.h
tiffiop.h
"${CMAKE_CURRENT_BINARY_DIR}/tiffvers.h"
uvcode.h
tiffio.hxx
"${CMAKE_CURRENT_BINARY_DIR}/tif_config.h"
"${CMAKE_CURRENT_BINARY_DIR}/tiffconf.h"
)
if(WIN32 AND NOT WINRT)
list(APPEND lib_srcs tif_win32.c)
else()
list(APPEND lib_srcs tif_unix.c)
endif()
ocv_warnings_disable(CMAKE_C_FLAGS -Wno-unused-but-set-variable -Wmissing-prototypes -Wmissing-declarations -Wundef -Wunused -Wsign-compare
-Wcast-align -Wshadow -Wno-maybe-uninitialized -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast
-Wmisleading-indentation
-Wimplicit-fallthrough
-Wunused-parameter # clang
-Warray-parameter
-Wstrict-prototypes # clang15
)
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wmissing-declarations -Wunused-parameter -Wmissing-prototypes
-Wundef # tiffiop.h: #if __clang_major__ >= 4
)
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4018 /wd4100 /wd4127 /wd4311 /wd4701 /wd4706) # vs2005
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4244) # vs2008
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4267 /wd4305 /wd4306) # vs2008 Win64
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4703) # vs2012
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4456 /wd4457 /wd4312) # vs2015
ocv_warnings_disable(CMAKE_C_FLAGS /wd4267 /wd4244 /wd4018 /wd4311 /wd4312)
add_library(${TIFF_LIBRARY} STATIC ${OPENCV_3RDPARTY_EXCLUDE_FROM_ALL} ${lib_srcs})
target_link_libraries(${TIFF_LIBRARY} ${ZLIB_LIBRARIES})
set_target_properties(${TIFF_LIBRARY}
PROPERTIES
OUTPUT_NAME "${TIFF_LIBRARY}"
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
COMPILE_PDB_NAME ${TIFF_LIBRARY}
COMPILE_PDB_NAME_DEBUG "${TIFF_LIBRARY}${OPENCV_DEBUG_POSTFIX}"
ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH}
)
if(ENABLE_SOLUTION_FOLDERS)
set_target_properties(${TIFF_LIBRARY} PROPERTIES FOLDER "3rdparty")
endif()
if(NOT BUILD_SHARED_LIBS)
ocv_install_target(${TIFF_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev OPTIONAL)
endif()
ocv_install_3rdparty_licenses(libtiff LICENSE.md)
+18685
View File
File diff suppressed because it is too large Load Diff
+49
View File
@@ -0,0 +1,49 @@
# LibTIFF license
Copyright © 1988-1997 Sam Leffler\
Copyright © 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.
# Lempel-Ziv & Welch Compression (tif_lzw.c) license
The code of tif_lzw.c is derived from the compress program whose code is
derived from software contributed to Berkeley by James A. Woods,
derived from original work by Spencer Thomas and Joseph Orost.
The original Berkeley copyright notice appears below in its entirety:
Copyright (c) 1985, 1986 The Regents of the University of California.
All rights reserved.
This code is derived from software contributed to Berkeley by
James A. Woods, derived from original work by Spencer Thomas
and Joseph Orost.
Redistribution and use in source and binary forms are permitted
provided that the above copyright notice and this paragraph are
duplicated in all such forms and that any documentation,
advertising materials, and other materials related to such
distribution and use acknowledge that the software was developed
by the University of California, Berkeley. The name of the
University may not be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+69
View File
@@ -0,0 +1,69 @@
TIFF Software Distribution
--------------------------
This file is just a placeholder; the entire documentation is now located
as reStructuredText in the doc directory. To view the documentation
as HTML, visit https://libtiff.gitlab.io/libtiff/ or
http://www.simplesystems.org/libtiff/ or within the release package
in the doc/html-prebuilt directory. The manual pages are
located at doc/man-prebuilt.
The release package can be downloaded at
http://download.osgeo.org/libtiff/
If you can't hack either of these options then basically what you
want to do is:
% ./configure
% make
% su
# make install
More information, email contacts, and mailing list information can be
found online at http://www.simplesystems.org/libtiff/
Source code repository
----------------------
[GitLab](https://gitlab.com/libtiff/libtiff)
Bug database
------------
[GitLab issues](https://gitlab.com/libtiff/libtiff/issues)
Previously, the project used
[Bugzilla](http://bugzilla.maptools.org/buglist.cgi?product=libtiff). This
is no longer in use, and all remaining issues have been migrated to GitLab.
Use and Copyright
-----------------
Silicon Graphics has seen fit to allow us to give this work away. It
is free. There is no support or guarantee of any sort as to its
operations, correctness, or whatever. If you do anything useful with
all or parts of it you need to honor the copyright notices. I would
also be interested in knowing about it and, hopefully, be acknowledged.
The legal way of saying that is:
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.
+1
View File
@@ -0,0 +1 @@
20250911
+284
View File
@@ -0,0 +1,284 @@
/*
* 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.
*/
#ifndef _T4_
#define _T4_
/*
* CCITT T.4 1D Huffman runlength codes and
* related definitions. Given the small sizes
* of these tables it does not seem
* 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 */
} tableentry;
#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 */
/*
* Note that these tables are ordered such that the
* index into the table is known to be either the
* run length, or (run length / 64) + a fixed offset.
*
* NB: The G3CODE_INVALID entries are only used
* during state generation (see mkg3states.c).
*/
#ifdef G3CODES
const tableentry TIFFFaxWhiteCodes[] = {
{8, 0x35, 0}, /* 0011 0101 */
{6, 0x7, 1}, /* 0001 11 */
{4, 0x7, 2}, /* 0111 */
{4, 0x8, 3}, /* 1000 */
{4, 0xB, 4}, /* 1011 */
{4, 0xC, 5}, /* 1100 */
{4, 0xE, 6}, /* 1110 */
{4, 0xF, 7}, /* 1111 */
{5, 0x13, 8}, /* 1001 1 */
{5, 0x14, 9}, /* 1010 0 */
{5, 0x7, 10}, /* 0011 1 */
{5, 0x8, 11}, /* 0100 0 */
{6, 0x8, 12}, /* 0010 00 */
{6, 0x3, 13}, /* 0000 11 */
{6, 0x34, 14}, /* 1101 00 */
{6, 0x35, 15}, /* 1101 01 */
{6, 0x2A, 16}, /* 1010 10 */
{6, 0x2B, 17}, /* 1010 11 */
{7, 0x27, 18}, /* 0100 111 */
{7, 0xC, 19}, /* 0001 100 */
{7, 0x8, 20}, /* 0001 000 */
{7, 0x17, 21}, /* 0010 111 */
{7, 0x3, 22}, /* 0000 011 */
{7, 0x4, 23}, /* 0000 100 */
{7, 0x28, 24}, /* 0101 000 */
{7, 0x2B, 25}, /* 0101 011 */
{7, 0x13, 26}, /* 0010 011 */
{7, 0x24, 27}, /* 0100 100 */
{7, 0x18, 28}, /* 0011 000 */
{8, 0x2, 29}, /* 0000 0010 */
{8, 0x3, 30}, /* 0000 0011 */
{8, 0x1A, 31}, /* 0001 1010 */
{8, 0x1B, 32}, /* 0001 1011 */
{8, 0x12, 33}, /* 0001 0010 */
{8, 0x13, 34}, /* 0001 0011 */
{8, 0x14, 35}, /* 0001 0100 */
{8, 0x15, 36}, /* 0001 0101 */
{8, 0x16, 37}, /* 0001 0110 */
{8, 0x17, 38}, /* 0001 0111 */
{8, 0x28, 39}, /* 0010 1000 */
{8, 0x29, 40}, /* 0010 1001 */
{8, 0x2A, 41}, /* 0010 1010 */
{8, 0x2B, 42}, /* 0010 1011 */
{8, 0x2C, 43}, /* 0010 1100 */
{8, 0x2D, 44}, /* 0010 1101 */
{8, 0x4, 45}, /* 0000 0100 */
{8, 0x5, 46}, /* 0000 0101 */
{8, 0xA, 47}, /* 0000 1010 */
{8, 0xB, 48}, /* 0000 1011 */
{8, 0x52, 49}, /* 0101 0010 */
{8, 0x53, 50}, /* 0101 0011 */
{8, 0x54, 51}, /* 0101 0100 */
{8, 0x55, 52}, /* 0101 0101 */
{8, 0x24, 53}, /* 0010 0100 */
{8, 0x25, 54}, /* 0010 0101 */
{8, 0x58, 55}, /* 0101 1000 */
{8, 0x59, 56}, /* 0101 1001 */
{8, 0x5A, 57}, /* 0101 1010 */
{8, 0x5B, 58}, /* 0101 1011 */
{8, 0x4A, 59}, /* 0100 1010 */
{8, 0x4B, 60}, /* 0100 1011 */
{8, 0x32, 61}, /* 0011 0010 */
{8, 0x33, 62}, /* 0011 0011 */
{8, 0x34, 63}, /* 0011 0100 */
{5, 0x1B, 64}, /* 1101 1 */
{5, 0x12, 128}, /* 1001 0 */
{6, 0x17, 192}, /* 0101 11 */
{7, 0x37, 256}, /* 0110 111 */
{8, 0x36, 320}, /* 0011 0110 */
{8, 0x37, 384}, /* 0011 0111 */
{8, 0x64, 448}, /* 0110 0100 */
{8, 0x65, 512}, /* 0110 0101 */
{8, 0x68, 576}, /* 0110 1000 */
{8, 0x67, 640}, /* 0110 0111 */
{9, 0xCC, 704}, /* 0110 0110 0 */
{9, 0xCD, 768}, /* 0110 0110 1 */
{9, 0xD2, 832}, /* 0110 1001 0 */
{9, 0xD3, 896}, /* 0110 1001 1 */
{9, 0xD4, 960}, /* 0110 1010 0 */
{9, 0xD5, 1024}, /* 0110 1010 1 */
{9, 0xD6, 1088}, /* 0110 1011 0 */
{9, 0xD7, 1152}, /* 0110 1011 1 */
{9, 0xD8, 1216}, /* 0110 1100 0 */
{9, 0xD9, 1280}, /* 0110 1100 1 */
{9, 0xDA, 1344}, /* 0110 1101 0 */
{9, 0xDB, 1408}, /* 0110 1101 1 */
{9, 0x98, 1472}, /* 0100 1100 0 */
{9, 0x99, 1536}, /* 0100 1100 1 */
{9, 0x9A, 1600}, /* 0100 1101 0 */
{6, 0x18, 1664}, /* 0110 00 */
{9, 0x9B, 1728}, /* 0100 1101 1 */
{11, 0x8, 1792}, /* 0000 0001 000 */
{11, 0xC, 1856}, /* 0000 0001 100 */
{11, 0xD, 1920}, /* 0000 0001 101 */
{12, 0x12, 1984}, /* 0000 0001 0010 */
{12, 0x13, 2048}, /* 0000 0001 0011 */
{12, 0x14, 2112}, /* 0000 0001 0100 */
{12, 0x15, 2176}, /* 0000 0001 0101 */
{12, 0x16, 2240}, /* 0000 0001 0110 */
{12, 0x17, 2304}, /* 0000 0001 0111 */
{12, 0x1C, 2368}, /* 0000 0001 1100 */
{12, 0x1D, 2432}, /* 0000 0001 1101 */
{12, 0x1E, 2496}, /* 0000 0001 1110 */
{12, 0x1F, 2560}, /* 0000 0001 1111 */
{12, 0x1, G3CODE_EOL}, /* 0000 0000 0001 */
{9, 0x1, G3CODE_INVALID}, /* 0000 0000 1 */
{10, 0x1, G3CODE_INVALID}, /* 0000 0000 01 */
{11, 0x1, G3CODE_INVALID}, /* 0000 0000 001 */
{12, 0x0, G3CODE_INVALID}, /* 0000 0000 0000 */
};
const tableentry TIFFFaxBlackCodes[] = {
{10, 0x37, 0}, /* 0000 1101 11 */
{3, 0x2, 1}, /* 010 */
{2, 0x3, 2}, /* 11 */
{2, 0x2, 3}, /* 10 */
{3, 0x3, 4}, /* 011 */
{4, 0x3, 5}, /* 0011 */
{4, 0x2, 6}, /* 0010 */
{5, 0x3, 7}, /* 0001 1 */
{6, 0x5, 8}, /* 0001 01 */
{6, 0x4, 9}, /* 0001 00 */
{7, 0x4, 10}, /* 0000 100 */
{7, 0x5, 11}, /* 0000 101 */
{7, 0x7, 12}, /* 0000 111 */
{8, 0x4, 13}, /* 0000 0100 */
{8, 0x7, 14}, /* 0000 0111 */
{9, 0x18, 15}, /* 0000 1100 0 */
{10, 0x17, 16}, /* 0000 0101 11 */
{10, 0x18, 17}, /* 0000 0110 00 */
{10, 0x8, 18}, /* 0000 0010 00 */
{11, 0x67, 19}, /* 0000 1100 111 */
{11, 0x68, 20}, /* 0000 1101 000 */
{11, 0x6C, 21}, /* 0000 1101 100 */
{11, 0x37, 22}, /* 0000 0110 111 */
{11, 0x28, 23}, /* 0000 0101 000 */
{11, 0x17, 24}, /* 0000 0010 111 */
{11, 0x18, 25}, /* 0000 0011 000 */
{12, 0xCA, 26}, /* 0000 1100 1010 */
{12, 0xCB, 27}, /* 0000 1100 1011 */
{12, 0xCC, 28}, /* 0000 1100 1100 */
{12, 0xCD, 29}, /* 0000 1100 1101 */
{12, 0x68, 30}, /* 0000 0110 1000 */
{12, 0x69, 31}, /* 0000 0110 1001 */
{12, 0x6A, 32}, /* 0000 0110 1010 */
{12, 0x6B, 33}, /* 0000 0110 1011 */
{12, 0xD2, 34}, /* 0000 1101 0010 */
{12, 0xD3, 35}, /* 0000 1101 0011 */
{12, 0xD4, 36}, /* 0000 1101 0100 */
{12, 0xD5, 37}, /* 0000 1101 0101 */
{12, 0xD6, 38}, /* 0000 1101 0110 */
{12, 0xD7, 39}, /* 0000 1101 0111 */
{12, 0x6C, 40}, /* 0000 0110 1100 */
{12, 0x6D, 41}, /* 0000 0110 1101 */
{12, 0xDA, 42}, /* 0000 1101 1010 */
{12, 0xDB, 43}, /* 0000 1101 1011 */
{12, 0x54, 44}, /* 0000 0101 0100 */
{12, 0x55, 45}, /* 0000 0101 0101 */
{12, 0x56, 46}, /* 0000 0101 0110 */
{12, 0x57, 47}, /* 0000 0101 0111 */
{12, 0x64, 48}, /* 0000 0110 0100 */
{12, 0x65, 49}, /* 0000 0110 0101 */
{12, 0x52, 50}, /* 0000 0101 0010 */
{12, 0x53, 51}, /* 0000 0101 0011 */
{12, 0x24, 52}, /* 0000 0010 0100 */
{12, 0x37, 53}, /* 0000 0011 0111 */
{12, 0x38, 54}, /* 0000 0011 1000 */
{12, 0x27, 55}, /* 0000 0010 0111 */
{12, 0x28, 56}, /* 0000 0010 1000 */
{12, 0x58, 57}, /* 0000 0101 1000 */
{12, 0x59, 58}, /* 0000 0101 1001 */
{12, 0x2B, 59}, /* 0000 0010 1011 */
{12, 0x2C, 60}, /* 0000 0010 1100 */
{12, 0x5A, 61}, /* 0000 0101 1010 */
{12, 0x66, 62}, /* 0000 0110 0110 */
{12, 0x67, 63}, /* 0000 0110 0111 */
{10, 0xF, 64}, /* 0000 0011 11 */
{12, 0xC8, 128}, /* 0000 1100 1000 */
{12, 0xC9, 192}, /* 0000 1100 1001 */
{12, 0x5B, 256}, /* 0000 0101 1011 */
{12, 0x33, 320}, /* 0000 0011 0011 */
{12, 0x34, 384}, /* 0000 0011 0100 */
{12, 0x35, 448}, /* 0000 0011 0101 */
{13, 0x6C, 512}, /* 0000 0011 0110 0 */
{13, 0x6D, 576}, /* 0000 0011 0110 1 */
{13, 0x4A, 640}, /* 0000 0010 0101 0 */
{13, 0x4B, 704}, /* 0000 0010 0101 1 */
{13, 0x4C, 768}, /* 0000 0010 0110 0 */
{13, 0x4D, 832}, /* 0000 0010 0110 1 */
{13, 0x72, 896}, /* 0000 0011 1001 0 */
{13, 0x73, 960}, /* 0000 0011 1001 1 */
{13, 0x74, 1024}, /* 0000 0011 1010 0 */
{13, 0x75, 1088}, /* 0000 0011 1010 1 */
{13, 0x76, 1152}, /* 0000 0011 1011 0 */
{13, 0x77, 1216}, /* 0000 0011 1011 1 */
{13, 0x52, 1280}, /* 0000 0010 1001 0 */
{13, 0x53, 1344}, /* 0000 0010 1001 1 */
{13, 0x54, 1408}, /* 0000 0010 1010 0 */
{13, 0x55, 1472}, /* 0000 0010 1010 1 */
{13, 0x5A, 1536}, /* 0000 0010 1101 0 */
{13, 0x5B, 1600}, /* 0000 0010 1101 1 */
{13, 0x64, 1664}, /* 0000 0011 0010 0 */
{13, 0x65, 1728}, /* 0000 0011 0010 1 */
{11, 0x8, 1792}, /* 0000 0001 000 */
{11, 0xC, 1856}, /* 0000 0001 100 */
{11, 0xD, 1920}, /* 0000 0001 101 */
{12, 0x12, 1984}, /* 0000 0001 0010 */
{12, 0x13, 2048}, /* 0000 0001 0011 */
{12, 0x14, 2112}, /* 0000 0001 0100 */
{12, 0x15, 2176}, /* 0000 0001 0101 */
{12, 0x16, 2240}, /* 0000 0001 0110 */
{12, 0x17, 2304}, /* 0000 0001 0111 */
{12, 0x1C, 2368}, /* 0000 0001 1100 */
{12, 0x1D, 2432}, /* 0000 0001 1101 */
{12, 0x1E, 2496}, /* 0000 0001 1110 */
{12, 0x1F, 2560}, /* 0000 0001 1111 */
{12, 0x1, G3CODE_EOL}, /* 0000 0000 0001 */
{9, 0x1, G3CODE_INVALID}, /* 0000 0000 1 */
{10, 0x1, G3CODE_INVALID}, /* 0000 0000 01 */
{11, 0x1, G3CODE_INVALID}, /* 0000 0000 001 */
{12, 0x0, G3CODE_INVALID}, /* 0000 0000 0000 */
};
#else
extern const tableentry TIFFFaxWhiteCodes[];
extern const tableentry TIFFFaxBlackCodes[];
#endif
#endif /* _T4_ */
+414
View File
@@ -0,0 +1,414 @@
/*
* Copyright (c) 1991-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.
*
* Auxiliary Support Routines.
*/
#include "tif_predict.h"
#include "tiffiop.h"
#include <float.h>
#include <math.h>
uint32_t _TIFFMultiply32(TIFF *tif, uint32_t first, uint32_t second,
const char *where)
{
if (second && first > UINT32_MAX / second)
{
TIFFErrorExtR(tif, where, "Integer overflow in %s", where);
return 0;
}
return first * second;
}
uint64_t _TIFFMultiply64(TIFF *tif, uint64_t first, uint64_t second,
const char *where)
{
if (second && first > UINT64_MAX / second)
{
TIFFErrorExtR(tif, where, "Integer overflow in %s", where);
return 0;
}
return first * second;
}
tmsize_t _TIFFMultiplySSize(TIFF *tif, tmsize_t first, tmsize_t second,
const char *where)
{
if (first <= 0 || second <= 0)
{
if (tif != NULL && where != NULL)
{
TIFFErrorExtR(tif, where,
"Invalid argument to _TIFFMultiplySSize() in %s",
where);
}
return 0;
}
if (first > TIFF_TMSIZE_T_MAX / second)
{
if (tif != NULL && where != NULL)
{
TIFFErrorExtR(tif, where, "Integer overflow in %s", where);
}
return 0;
}
return first * second;
}
tmsize_t _TIFFCastUInt64ToSSize(TIFF *tif, uint64_t val, const char *module)
{
if (val > (uint64_t)TIFF_TMSIZE_T_MAX)
{
if (tif != NULL && module != NULL)
{
TIFFErrorExtR(tif, module, "Integer overflow");
}
return 0;
}
return (tmsize_t)val;
}
void *_TIFFCheckRealloc(TIFF *tif, void *buffer, tmsize_t nmemb,
tmsize_t elem_size, const char *what)
{
void *cp = NULL;
tmsize_t count = _TIFFMultiplySSize(tif, nmemb, elem_size, NULL);
/*
* Check for integer overflow.
*/
if (count != 0)
{
cp = _TIFFreallocExt(tif, buffer, count);
}
if (cp == NULL)
{
TIFFErrorExtR(tif, tif->tif_name,
"Failed to allocate memory for %s "
"(%" TIFF_SSIZE_FORMAT " elements of %" TIFF_SSIZE_FORMAT
" bytes each)",
what, nmemb, elem_size);
}
return cp;
}
void *_TIFFCheckMalloc(TIFF *tif, tmsize_t nmemb, tmsize_t elem_size,
const char *what)
{
return _TIFFCheckRealloc(tif, NULL, nmemb, elem_size, what);
}
static int TIFFDefaultTransferFunction(TIFF *tif, TIFFDirectory *td)
{
uint16_t **tf = td->td_transferfunction;
tmsize_t i, n, nbytes;
tf[0] = tf[1] = tf[2] = 0;
// Do not try to generate a default TransferFunction beyond 24 bits.
// This otherwise leads to insane amounts, resulting in denial of service
// See https://github.com/OSGeo/gdal/issues/10875
if (td->td_bitspersample > 24)
return 0;
n = ((tmsize_t)1) << td->td_bitspersample;
nbytes = n * sizeof(uint16_t);
tf[0] = (uint16_t *)_TIFFmallocExt(tif, nbytes);
if (tf[0] == NULL)
return 0;
tf[0][0] = 0;
for (i = 1; i < n; i++)
{
double t = (double)i / ((double)n - 1.);
tf[0][i] = (uint16_t)floor(65535. * pow(t, 2.2) + .5);
}
if (td->td_samplesperpixel - td->td_extrasamples > 1)
{
tf[1] = (uint16_t *)_TIFFmallocExt(tif, nbytes);
if (tf[1] == NULL)
goto bad;
_TIFFmemcpy(tf[1], tf[0], nbytes);
tf[2] = (uint16_t *)_TIFFmallocExt(tif, nbytes);
if (tf[2] == NULL)
goto bad;
_TIFFmemcpy(tf[2], tf[0], nbytes);
}
return 1;
bad:
if (tf[0])
_TIFFfreeExt(tif, tf[0]);
if (tf[1])
_TIFFfreeExt(tif, tf[1]);
if (tf[2])
_TIFFfreeExt(tif, tf[2]);
tf[0] = tf[1] = tf[2] = 0;
return 0;
}
static int TIFFDefaultRefBlackWhite(TIFF *tif, TIFFDirectory *td)
{
int i;
td->td_refblackwhite = (float *)_TIFFmallocExt(tif, 6 * sizeof(float));
if (td->td_refblackwhite == NULL)
return 0;
if (td->td_photometric == PHOTOMETRIC_YCBCR)
{
/*
* YCbCr (Class Y) images must have the ReferenceBlackWhite
* tag set. Fix the broken images, which lacks that tag.
*/
td->td_refblackwhite[0] = 0.0F;
td->td_refblackwhite[1] = td->td_refblackwhite[3] =
td->td_refblackwhite[5] = 255.0F;
td->td_refblackwhite[2] = td->td_refblackwhite[4] = 128.0F;
}
else
{
/*
* Assume RGB (Class R)
*/
for (i = 0; i < 3; i++)
{
td->td_refblackwhite[2 * i + 0] = 0;
td->td_refblackwhite[2 * i + 1] =
(float)((1L << td->td_bitspersample) - 1L);
}
}
return 1;
}
/*
* Like TIFFGetField, but return any default
* value if the tag is not present in the directory.
*
* NB: We use the value in the directory, rather than
* explicit values so that defaults exist only one
* place in the library -- in TIFFDefaultDirectory.
*/
int TIFFVGetFieldDefaulted(TIFF *tif, uint32_t tag, va_list ap)
{
TIFFDirectory *td = &tif->tif_dir;
if (TIFFVGetField(tif, tag, ap))
return (1);
switch (tag)
{
case TIFFTAG_SUBFILETYPE:
*va_arg(ap, uint32_t *) = td->td_subfiletype;
return (1);
case TIFFTAG_BITSPERSAMPLE:
*va_arg(ap, uint16_t *) = td->td_bitspersample;
return (1);
case TIFFTAG_THRESHHOLDING:
*va_arg(ap, uint16_t *) = td->td_threshholding;
return (1);
case TIFFTAG_FILLORDER:
*va_arg(ap, uint16_t *) = td->td_fillorder;
return (1);
case TIFFTAG_ORIENTATION:
*va_arg(ap, uint16_t *) = td->td_orientation;
return (1);
case TIFFTAG_SAMPLESPERPIXEL:
*va_arg(ap, uint16_t *) = td->td_samplesperpixel;
return (1);
case TIFFTAG_ROWSPERSTRIP:
*va_arg(ap, uint32_t *) = td->td_rowsperstrip;
return (1);
case TIFFTAG_MINSAMPLEVALUE:
*va_arg(ap, uint16_t *) = td->td_minsamplevalue;
return (1);
case TIFFTAG_MAXSAMPLEVALUE:
{
uint16_t maxsamplevalue;
/* td_bitspersample=1 is always set in TIFFDefaultDirectory().
* Therefore, td_maxsamplevalue has to be re-calculated in
* TIFFGetFieldDefaulted(). */
if (td->td_bitspersample > 0)
{
/* This shift operation into a uint16_t limits the value to
* 65535 even if td_bitspersamle is > 16 */
if (td->td_bitspersample <= 16)
{
maxsamplevalue = (1 << td->td_bitspersample) -
1; /* 2**(BitsPerSample) - 1 */
}
else
{
maxsamplevalue = 65535;
}
}
else
{
maxsamplevalue = 0;
}
*va_arg(ap, uint16_t *) = maxsamplevalue;
return (1);
}
case TIFFTAG_PLANARCONFIG:
*va_arg(ap, uint16_t *) = td->td_planarconfig;
return (1);
case TIFFTAG_RESOLUTIONUNIT:
*va_arg(ap, uint16_t *) = td->td_resolutionunit;
return (1);
case TIFFTAG_PREDICTOR:
{
TIFFPredictorState *sp = (TIFFPredictorState *)tif->tif_data;
if (sp == NULL)
{
TIFFErrorExtR(
tif, tif->tif_name,
"Cannot get \"Predictor\" tag as plugin is not configured");
*va_arg(ap, uint16_t *) = 0;
return 0;
}
*va_arg(ap, uint16_t *) = (uint16_t)sp->predictor;
return 1;
}
case TIFFTAG_DOTRANGE:
*va_arg(ap, uint16_t *) = 0;
*va_arg(ap, uint16_t *) = (1 << td->td_bitspersample) - 1;
return (1);
case TIFFTAG_INKSET:
*va_arg(ap, uint16_t *) = INKSET_CMYK;
return 1;
case TIFFTAG_NUMBEROFINKS:
*va_arg(ap, uint16_t *) = 4;
return (1);
case TIFFTAG_EXTRASAMPLES:
*va_arg(ap, uint16_t *) = td->td_extrasamples;
*va_arg(ap, const uint16_t **) = td->td_sampleinfo;
return (1);
case TIFFTAG_MATTEING:
*va_arg(ap, uint16_t *) =
(td->td_extrasamples == 1 &&
td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
return (1);
case TIFFTAG_TILEDEPTH:
*va_arg(ap, uint32_t *) = td->td_tiledepth;
return (1);
case TIFFTAG_DATATYPE:
*va_arg(ap, uint16_t *) = td->td_sampleformat - 1;
return (1);
case TIFFTAG_SAMPLEFORMAT:
*va_arg(ap, uint16_t *) = td->td_sampleformat;
return (1);
case TIFFTAG_IMAGEDEPTH:
*va_arg(ap, uint32_t *) = td->td_imagedepth;
return (1);
case TIFFTAG_YCBCRCOEFFICIENTS:
{
/* defaults are from CCIR Recommendation 601-1 */
static const float ycbcrcoeffs[] = {0.299f, 0.587f, 0.114f};
*va_arg(ap, const float **) = ycbcrcoeffs;
return 1;
}
case TIFFTAG_YCBCRSUBSAMPLING:
*va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[0];
*va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[1];
return (1);
case TIFFTAG_YCBCRPOSITIONING:
*va_arg(ap, uint16_t *) = td->td_ycbcrpositioning;
return (1);
case TIFFTAG_WHITEPOINT:
{
/* TIFF 6.0 specification tells that it is no default
value for the WhitePoint, but AdobePhotoshop TIFF
Technical Note tells that it should be CIE D50. */
static const float whitepoint[] = {
D50_X0 / (D50_X0 + D50_Y0 + D50_Z0),
D50_Y0 / (D50_X0 + D50_Y0 + D50_Z0)};
*va_arg(ap, const float **) = whitepoint;
return 1;
}
case TIFFTAG_TRANSFERFUNCTION:
if (!td->td_transferfunction[0] &&
!TIFFDefaultTransferFunction(tif, td))
{
TIFFErrorExtR(tif, tif->tif_name,
"No space for \"TransferFunction\" tag");
return (0);
}
*va_arg(ap, const uint16_t **) = td->td_transferfunction[0];
if (td->td_samplesperpixel - td->td_extrasamples > 1)
{
*va_arg(ap, const uint16_t **) = td->td_transferfunction[1];
*va_arg(ap, const uint16_t **) = td->td_transferfunction[2];
}
return (1);
case TIFFTAG_REFERENCEBLACKWHITE:
if (!td->td_refblackwhite && !TIFFDefaultRefBlackWhite(tif, td))
return (0);
*va_arg(ap, const float **) = td->td_refblackwhite;
return (1);
}
return 0;
}
/*
* Like TIFFGetField, but return any default
* value if the tag is not present in the directory.
*/
int TIFFGetFieldDefaulted(TIFF *tif, uint32_t tag, ...)
{
int ok;
va_list ap;
va_start(ap, tag);
ok = TIFFVGetFieldDefaulted(tif, tag, ap);
va_end(ap);
return (ok);
}
float _TIFFClampDoubleToFloat(double val)
{
if (val > FLT_MAX)
return FLT_MAX;
if (val < -FLT_MAX)
return -FLT_MAX;
return (float)val;
}
uint32_t _TIFFClampDoubleToUInt32(double val)
{
if (val < 0)
return 0;
if (val > 0xFFFFFFFFU || val != val)
return 0xFFFFFFFFU;
return (uint32_t)val;
}
int _TIFFSeekOK(TIFF *tif, toff_t off)
{
/* Huge offsets, especially -1 / UINT64_MAX, can cause issues */
/* See http://bugzilla.maptools.org/show_bug.cgi?id=2726 */
return off <= (~(uint64_t)0) / 2 && TIFFSeekFile(tif, off, SEEK_SET) == off;
}
+165
View File
@@ -0,0 +1,165 @@
/*
* 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.
*/
#include "tiffiop.h"
#include <string.h>
/************************************************************************/
/* TIFFCleanup() */
/************************************************************************/
/**
* Auxiliary function to free the TIFF structure. Given structure will be
* completely freed, so you should save opened file handle and pointer
* to the close procedure in external variables before calling
* _TIFFCleanup(), if you will need these ones to close the file.
*
* @param tif A TIFF pointer.
*/
void TIFFCleanup(TIFF *tif)
{
/*
* Flush buffered data and directory (if dirty).
*/
if (tif->tif_mode != O_RDONLY)
TIFFFlush(tif);
TIFFFreeDirectory(tif);
_TIFFCleanupIFDOffsetAndNumberMaps(tif);
/*
* Clean up client info links.
*/
while (tif->tif_clientinfo)
{
TIFFClientInfoLink *psLink = tif->tif_clientinfo;
tif->tif_clientinfo = psLink->next;
_TIFFfreeExt(tif, psLink->name);
_TIFFfreeExt(tif, psLink);
}
if (tif->tif_rawdata && (tif->tif_flags & TIFF_MYBUFFER))
_TIFFfreeExt(tif, tif->tif_rawdata);
if (isMapped(tif))
TIFFUnmapFileContents(tif, tif->tif_base, (toff_t)tif->tif_size);
/*
* Clean up custom fields.
*/
if (tif->tif_fields && tif->tif_nfields > 0)
{
uint32_t i;
for (i = 0; i < tif->tif_nfields; i++)
{
TIFFField *fld = tif->tif_fields[i];
if (fld->field_name != NULL)
{
if (fld->field_bit == FIELD_CUSTOM &&
/* caution: tif_fields[i] must not be the beginning of a
* fields-array. Otherwise the following tags are also freed
* with the first free().
*/
TIFFFieldIsAnonymous(fld))
{
_TIFFfreeExt(tif, fld->field_name);
_TIFFfreeExt(tif, fld);
}
}
}
_TIFFfreeExt(tif, tif->tif_fields);
}
if (tif->tif_nfieldscompat > 0)
{
uint32_t i;
for (i = 0; i < tif->tif_nfieldscompat; i++)
{
if (tif->tif_fieldscompat[i].allocated_size)
_TIFFfreeExt(tif, tif->tif_fieldscompat[i].fields);
}
_TIFFfreeExt(tif, tif->tif_fieldscompat);
}
if (tif->tif_cur_cumulated_mem_alloc != 0)
{
TIFFErrorExtR(tif, "TIFFCleanup",
"tif_cur_cumulated_mem_alloc = %" PRIu64 " whereas it "
"should be 0",
(uint64_t)tif->tif_cur_cumulated_mem_alloc);
}
_TIFFfreeExt(NULL, tif);
}
/************************************************************************/
/* _TIFFCleanupIFDOffsetAndNumberMaps() */
/************************************************************************/
void _TIFFCleanupIFDOffsetAndNumberMaps(TIFF *tif)
{
if (tif->tif_map_dir_offset_to_number)
{
TIFFHashSetDestroy(tif->tif_map_dir_offset_to_number);
tif->tif_map_dir_offset_to_number = NULL;
}
if (tif->tif_map_dir_number_to_offset)
{
TIFFHashSetDestroy(tif->tif_map_dir_number_to_offset);
tif->tif_map_dir_number_to_offset = NULL;
}
}
/************************************************************************/
/* TIFFClose() */
/************************************************************************/
/**
* Close a previously opened TIFF file.
*
* TIFFClose closes a file that was previously opened with TIFFOpen().
* Any buffered data are flushed to the file, including the contents of
* the current directory (if modified); and all resources are reclaimed.
*
* @param tif A TIFF pointer.
*/
void TIFFClose(TIFF *tif)
{
if (tif != NULL)
{
TIFFCloseProc closeproc = tif->tif_closeproc;
thandle_t fd = tif->tif_clientdata;
TIFFCleanup(tif);
(void)(*closeproc)(fd);
}
}
+163
View File
@@ -0,0 +1,163 @@
/*
* 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
*
* Builtin Compression Scheme Configuration Support.
*/
#include "tiffiop.h"
static int NotConfigured(TIFF *, int);
#ifndef LZW_SUPPORT
#define TIFFInitLZW NotConfigured
#endif
#ifndef PACKBITS_SUPPORT
#define TIFFInitPackBits NotConfigured
#endif
#ifndef THUNDER_SUPPORT
#define TIFFInitThunderScan NotConfigured
#endif
#ifndef NEXT_SUPPORT
#define TIFFInitNeXT NotConfigured
#endif
#ifndef JPEG_SUPPORT
#define TIFFInitJPEG NotConfigured
#endif
#ifndef OJPEG_SUPPORT
#define TIFFInitOJPEG NotConfigured
#endif
#ifndef CCITT_SUPPORT
#define TIFFInitCCITTRLE NotConfigured
#define TIFFInitCCITTRLEW NotConfigured
#define TIFFInitCCITTFax3 NotConfigured
#define TIFFInitCCITTFax4 NotConfigured
#endif
#ifndef JBIG_SUPPORT
#define TIFFInitJBIG NotConfigured
#endif
#ifndef ZIP_SUPPORT
#define TIFFInitZIP NotConfigured
#endif
#ifndef PIXARLOG_SUPPORT
#define TIFFInitPixarLog NotConfigured
#endif
#ifndef LOGLUV_SUPPORT
#define TIFFInitSGILog NotConfigured
#endif
#ifndef LERC_SUPPORT
#define TIFFInitLERC NotConfigured
#endif
#ifndef LZMA_SUPPORT
#define TIFFInitLZMA NotConfigured
#endif
#ifndef ZSTD_SUPPORT
#define TIFFInitZSTD NotConfigured
#endif
#ifndef WEBP_SUPPORT
#define TIFFInitWebP NotConfigured
#endif
/*
* Compression schemes statically built into the library.
*/
const TIFFCodec _TIFFBuiltinCODECS[] = {
{"None", COMPRESSION_NONE, TIFFInitDumpMode},
{"LZW", COMPRESSION_LZW, TIFFInitLZW},
{"PackBits", COMPRESSION_PACKBITS, TIFFInitPackBits},
{"ThunderScan", COMPRESSION_THUNDERSCAN, TIFFInitThunderScan},
{"NeXT", COMPRESSION_NEXT, TIFFInitNeXT},
{"JPEG", COMPRESSION_JPEG, TIFFInitJPEG},
{"Old-style JPEG", COMPRESSION_OJPEG, TIFFInitOJPEG},
{"CCITT RLE", COMPRESSION_CCITTRLE, TIFFInitCCITTRLE},
{"CCITT RLE/W", COMPRESSION_CCITTRLEW, TIFFInitCCITTRLEW},
{"CCITT Group 3", COMPRESSION_CCITTFAX3, TIFFInitCCITTFax3},
{"CCITT Group 4", COMPRESSION_CCITTFAX4, TIFFInitCCITTFax4},
{"ISO JBIG", COMPRESSION_JBIG, TIFFInitJBIG},
{"Deflate", COMPRESSION_DEFLATE, TIFFInitZIP},
{"AdobeDeflate", COMPRESSION_ADOBE_DEFLATE, TIFFInitZIP},
{"PixarLog", COMPRESSION_PIXARLOG, TIFFInitPixarLog},
{"SGILog", COMPRESSION_SGILOG, TIFFInitSGILog},
{"SGILog24", COMPRESSION_SGILOG24, TIFFInitSGILog},
{"LZMA", COMPRESSION_LZMA, TIFFInitLZMA},
{"ZSTD", COMPRESSION_ZSTD, TIFFInitZSTD},
{"WEBP", COMPRESSION_WEBP, TIFFInitWebP},
{"LERC", COMPRESSION_LERC, TIFFInitLERC},
{NULL, 0, NULL}};
static int _notConfigured(TIFF *tif)
{
const TIFFCodec *c = TIFFFindCODEC(tif->tif_dir.td_compression);
char compression_code[20];
snprintf(compression_code, sizeof(compression_code), "%" PRIu16,
tif->tif_dir.td_compression);
TIFFErrorExtR(tif, tif->tif_name,
"%s compression support is not configured",
c ? c->name : compression_code);
return (0);
}
static int NotConfigured(TIFF *tif, int scheme)
{
(void)scheme;
tif->tif_fixuptags = _notConfigured;
tif->tif_decodestatus = FALSE;
tif->tif_setupdecode = _notConfigured;
tif->tif_encodestatus = FALSE;
tif->tif_setupencode = _notConfigured;
return (1);
}
/************************************************************************/
/* TIFFIsCODECConfigured() */
/************************************************************************/
/**
* 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.
*/
int TIFFIsCODECConfigured(uint16_t scheme)
{
const TIFFCodec *codec = TIFFFindCODEC(scheme);
if (codec == NULL)
{
return 0;
}
if (codec->init == NULL)
{
return 0;
}
if (codec->init != NotConfigured)
{
return 1;
}
return 0;
}
+322
View File
@@ -0,0 +1,322 @@
/*
* 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.
*/
/*
* CIE L*a*b* to CIE XYZ and CIE XYZ to RGB conversion routines are taken
* from the VIPS library (http://www.vips.ecs.soton.ac.uk) with
* the permission of John Cupitt, the VIPS author.
*/
/*
* TIFF Library.
*
* Color space conversion routines.
*/
#include "tiffiop.h"
#include <math.h>
/*
* Convert color value from the CIE L*a*b* 1976 space to CIE XYZ.
*/
void TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a, int32_t b,
float *X, float *Y, float *Z)
{
TIFFCIELab16ToXYZ(cielab, l * 257, a * 256, b * 256, X, Y, Z);
}
/*
* For CIELab encoded in 16 bits, L is an unsigned integer range [0,65535].
* The a* and b* components are signed integers range [-32768,32767]. The 16
* bit chrominance values are encoded as 256 times the 1976 CIE a* and b*
* values
*/
void TIFFCIELab16ToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a,
int32_t b, float *X, float *Y, float *Z)
{
float L = (float)l * 100.0F / 65535.0F;
float cby, tmp;
if (L < 8.856F)
{
*Y = (L * cielab->Y0) / 903.292F;
cby = 7.787F * (*Y / cielab->Y0) + 16.0F / 116.0F;
}
else
{
cby = (L + 16.0F) / 116.0F;
*Y = cielab->Y0 * cby * cby * cby;
}
tmp = (float)a / 256.0F / 500.0F + cby;
if (tmp < 0.2069F)
*X = cielab->X0 * (tmp - 0.13793F) / 7.787F;
else
*X = cielab->X0 * tmp * tmp * tmp;
tmp = cby - (float)b / 256.0F / 200.0F;
if (tmp < 0.2069F)
*Z = cielab->Z0 * (tmp - 0.13793F) / 7.787F;
else
*Z = cielab->Z0 * tmp * tmp * tmp;
}
#define RINT(R) ((uint32_t)((R) > 0 ? ((R) + 0.5) : ((R)-0.5)))
/*
* Convert color value from the XYZ space to RGB.
*/
void TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z,
uint32_t *r, uint32_t *g, uint32_t *b)
{
size_t i;
float Yr, Yg, Yb;
float *matrix = &cielab->display.d_mat[0][0];
/* Multiply through the matrix to get luminosity values. */
Yr = matrix[0] * X + matrix[1] * Y + matrix[2] * Z;
Yg = matrix[3] * X + matrix[4] * Y + matrix[5] * Z;
Yb = matrix[6] * X + matrix[7] * Y + matrix[8] * Z;
/* Clip input */
Yr = TIFFmax(Yr, cielab->display.d_Y0R);
Yg = TIFFmax(Yg, cielab->display.d_Y0G);
Yb = TIFFmax(Yb, cielab->display.d_Y0B);
/* Avoid overflow in case of wrong input values */
Yr = TIFFmin(Yr, cielab->display.d_YCR);
Yg = TIFFmin(Yg, cielab->display.d_YCG);
Yb = TIFFmin(Yb, cielab->display.d_YCB);
/* Turn luminosity to colour value. */
i = (size_t)((Yr - cielab->display.d_Y0R) / cielab->rstep);
i = TIFFmin((size_t)cielab->range, i);
*r = RINT(cielab->Yr2r[i]);
i = (size_t)((Yg - cielab->display.d_Y0G) / cielab->gstep);
i = TIFFmin((size_t)cielab->range, i);
*g = RINT(cielab->Yg2g[i]);
i = (size_t)((Yb - cielab->display.d_Y0B) / cielab->bstep);
i = TIFFmin((size_t)cielab->range, i);
*b = RINT(cielab->Yb2b[i]);
/* Clip output. */
*r = TIFFmin(*r, cielab->display.d_Vrwr);
*g = TIFFmin(*g, cielab->display.d_Vrwg);
*b = TIFFmin(*b, cielab->display.d_Vrwb);
}
#undef RINT
/*
* Allocate conversion state structures and make look_up tables for
* the Yr,Yb,Yg <=> r,g,b conversions.
*/
int TIFFCIELabToRGBInit(TIFFCIELabToRGB *cielab, const TIFFDisplay *display,
float *refWhite)
{
size_t i;
double dfGamma;
cielab->range = CIELABTORGB_TABLE_RANGE;
_TIFFmemcpy(&cielab->display, display, sizeof(TIFFDisplay));
/* Red */
dfGamma = 1.0 / cielab->display.d_gammaR;
cielab->rstep =
(cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
for (i = 0; i <= (size_t)cielab->range; i++)
{
cielab->Yr2r[i] = cielab->display.d_Vrwr *
((float)pow((double)i / cielab->range, dfGamma));
}
/* Green */
dfGamma = 1.0 / cielab->display.d_gammaG;
cielab->gstep =
(cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
for (i = 0; i <= (size_t)cielab->range; i++)
{
cielab->Yg2g[i] = cielab->display.d_Vrwg *
((float)pow((double)i / cielab->range, dfGamma));
}
/* Blue */
dfGamma = 1.0 / cielab->display.d_gammaB;
cielab->bstep =
(cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
for (i = 0; i <= (size_t)cielab->range; i++)
{
cielab->Yb2b[i] = cielab->display.d_Vrwb *
((float)pow((double)i / cielab->range, dfGamma));
}
/* Init reference white point */
cielab->X0 = refWhite[0];
cielab->Y0 = refWhite[1];
cielab->Z0 = refWhite[2];
return 0;
}
/*
* Convert color value from the YCbCr space to RGB.
* The colorspace conversion algorithm comes from the IJG v5a code;
* see below for more information on how it works.
*/
#define SHIFT 16
#define FIX(x) ((int32_t)((x) * (1L << SHIFT) + 0.5))
#define ONE_HALF ((int32_t)(1 << (SHIFT - 1)))
#define Code2V(c, RB, RW, CR) \
((((c) - (int32_t)(RB)) * (float)(CR)) / \
(float)(((RW) - (RB) != 0) ? ((RW) - (RB)) : 1))
/* !((f)>=(min)) written that way to deal with NaN */
#define CLAMP(f, min, max) \
((!((f) >= (min))) ? (min) : (f) > (max) ? (max) : (f))
#define HICLAMP(f, max) ((f) > (max) ? (max) : (f))
void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32_t Y, int32_t Cb, int32_t Cr,
uint32_t *r, uint32_t *g, uint32_t *b)
{
int32_t i;
/* XXX: Only 8-bit YCbCr input supported for now */
Y = HICLAMP(Y, 255);
Cb = CLAMP(Cb, 0, 255);
Cr = CLAMP(Cr, 0, 255);
i = ycbcr->Y_tab[Y] + ycbcr->Cr_r_tab[Cr];
*r = CLAMP(i, 0, 255);
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);
}
/* Clamp function for sanitization purposes. Normally clamping should not */
/* occur for well behaved chroma and refBlackWhite coefficients */
static float CLAMPw(float v, float vmin, float vmax)
{
if (v < vmin)
{
/* printf("%f clamped to %f\n", v, vmin); */
return vmin;
}
if (v > vmax)
{
/* printf("%f clamped to %f\n", v, vmax); */
return vmax;
}
return v;
}
/*
* Initialize the YCbCr->RGB conversion tables. The conversion
* is done according to the 6.0 spec:
*
* R = Y + Cr*(2 - 2*LumaRed)
* B = Y + Cb*(2 - 2*LumaBlue)
* G = Y
* - LumaBlue*Cb*(2-2*LumaBlue)/LumaGreen
* - LumaRed*Cr*(2-2*LumaRed)/LumaGreen
*
* To avoid floating point arithmetic the fractional constants that
* come out of the equations are represented as fixed point values
* in the range 0...2^16. We also eliminate multiplications by
* pre-calculating possible values indexed by Cb and Cr (this code
* assumes conversion is being done for 8-bit samples).
*/
int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *ycbcr, float *luma, float *refBlackWhite)
{
TIFFRGBValue *clamptab;
int i;
#define LumaRed luma[0]
#define LumaGreen luma[1]
#define LumaBlue luma[2]
clamptab =
(TIFFRGBValue *)((uint8_t *)ycbcr +
TIFFroundup_32(sizeof(TIFFYCbCrToRGB), sizeof(long)));
_TIFFmemset(clamptab, 0, 256); /* v < 0 => 0 */
ycbcr->clamptab = (clamptab += 256);
for (i = 0; i < 256; i++)
clamptab[i] = (TIFFRGBValue)i;
_TIFFmemset(clamptab + 256, 255, 2 * 256); /* v > 255 => 255 */
ycbcr->Cr_r_tab = (int *)(clamptab + 3 * 256);
ycbcr->Cb_b_tab = ycbcr->Cr_r_tab + 256;
ycbcr->Cr_g_tab = (int32_t *)(ycbcr->Cb_b_tab + 256);
ycbcr->Cb_g_tab = ycbcr->Cr_g_tab + 256;
ycbcr->Y_tab = ycbcr->Cb_g_tab + 256;
{
float f1 = 2 - 2 * LumaRed;
int32_t D1 = FIX(CLAMP(f1, 0.0F, 2.0F));
float f2 = LumaRed * f1 / LumaGreen;
int32_t D2 = -FIX(CLAMP(f2, 0.0F, 2.0F));
float f3 = 2 - 2 * LumaBlue;
int32_t D3 = FIX(CLAMP(f3, 0.0F, 2.0F));
float f4 = LumaBlue * f3 / LumaGreen;
int32_t D4 = -FIX(CLAMP(f4, 0.0F, 2.0F));
int x;
#undef LumaBlue
#undef LumaGreen
#undef LumaRed
/*
* i is the actual input pixel value in the range 0..255
* Cb and Cr values are in the range -128..127 (actually
* they are in a range defined by the ReferenceBlackWhite
* tag) so there is some range shifting to do here when
* constructing tables indexed by the raw pixel data.
*/
for (i = 0, x = -128; i < 256; i++, x++)
{
int32_t Cr = (int32_t)CLAMPw(Code2V(x, refBlackWhite[4] - 128.0F,
refBlackWhite[5] - 128.0F, 127),
-128.0F * 32, 128.0F * 32);
int32_t Cb = (int32_t)CLAMPw(Code2V(x, refBlackWhite[2] - 128.0F,
refBlackWhite[3] - 128.0F, 127),
-128.0F * 32, 128.0F * 32);
ycbcr->Cr_r_tab[i] = (int32_t)((D1 * Cr + ONE_HALF) >> SHIFT);
ycbcr->Cb_b_tab[i] = (int32_t)((D3 * Cb + ONE_HALF) >> SHIFT);
ycbcr->Cr_g_tab[i] = D2 * Cr;
ycbcr->Cb_g_tab[i] = D4 * Cb + ONE_HALF;
ycbcr->Y_tab[i] = (int32_t)CLAMPw(
Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255),
-128.0F * 32, 128.0F * 32);
}
}
return 0;
}
#undef HICLAMP
#undef CLAMP
#undef Code2V
#undef SHIFT
#undef ONE_HALF
#undef FIX
+310
View File
@@ -0,0 +1,310 @@
/*
* 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
*
* Compression Scheme Configuration Support.
*/
#include "tiffiop.h"
static int TIFFNoEncode(TIFF *tif, const char *method)
{
const TIFFCodec *c = TIFFFindCODEC(tif->tif_dir.td_compression);
if (c)
{
TIFFErrorExtR(tif, tif->tif_name, "%s %s encoding is not implemented",
c->name, method);
}
else
{
TIFFErrorExtR(tif, tif->tif_name,
"Compression scheme %" PRIu16
" %s encoding is not implemented",
tif->tif_dir.td_compression, method);
}
return (-1);
}
int _TIFFNoRowEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
{
(void)pp;
(void)cc;
(void)s;
return (TIFFNoEncode(tif, "scanline"));
}
int _TIFFNoStripEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
{
(void)pp;
(void)cc;
(void)s;
return (TIFFNoEncode(tif, "strip"));
}
int _TIFFNoTileEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
{
(void)pp;
(void)cc;
(void)s;
return (TIFFNoEncode(tif, "tile"));
}
static int TIFFNoDecode(TIFF *tif, const char *method)
{
const TIFFCodec *c = TIFFFindCODEC(tif->tif_dir.td_compression);
if (c)
TIFFErrorExtR(tif, tif->tif_name, "%s %s decoding is not implemented",
c->name, method);
else
TIFFErrorExtR(tif, tif->tif_name,
"Compression scheme %" PRIu16
" %s decoding is not implemented",
tif->tif_dir.td_compression, method);
return (0);
}
static int _TIFFNoFixupTags(TIFF *tif)
{
(void)tif;
return (1);
}
int _TIFFNoRowDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
{
(void)pp;
(void)cc;
(void)s;
return (TIFFNoDecode(tif, "scanline"));
}
int _TIFFNoStripDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
{
(void)pp;
(void)cc;
(void)s;
return (TIFFNoDecode(tif, "strip"));
}
int _TIFFNoTileDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
{
(void)pp;
(void)cc;
(void)s;
return (TIFFNoDecode(tif, "tile"));
}
int _TIFFNoSeek(TIFF *tif, uint32_t off)
{
(void)off;
TIFFErrorExtR(tif, tif->tif_name,
"Compression algorithm does not support random access");
return (0);
}
int _TIFFNoPreCode(TIFF *tif, uint16_t s)
{
(void)tif;
(void)s;
return (1);
}
static int _TIFFtrue(TIFF *tif)
{
(void)tif;
return (1);
}
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_decodestrip = _TIFFNoStripDecode;
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_close = _TIFFvoid;
tif->tif_seek = _TIFFNoSeek;
tif->tif_cleanup = _TIFFvoid;
tif->tif_defstripsize = _TIFFDefaultStripSize;
tif->tif_deftilesize = _TIFFDefaultTileSize;
tif->tif_flags &= ~(TIFF_NOBITREV | TIFF_NOREADRAW);
}
int TIFFSetCompressionScheme(TIFF *tif, int scheme)
{
const TIFFCodec *c = TIFFFindCODEC((uint16_t)scheme);
_TIFFSetDefaultCompressionState(tif);
/*
* Don't treat an unknown compression scheme as an error.
* This permits applications to open files with data that
* the library does not have builtin support for, but which
* may still be meaningful.
*/
return (c ? (*c->init)(tif, scheme) : 1);
}
/*
* Other compression schemes may be registered. Registered
* schemes can also override the builtin versions provided
* by this library.
*/
typedef struct _codec
{
struct _codec *next;
TIFFCodec *info;
} codec_t;
static codec_t *registeredCODECS = NULL;
const TIFFCodec *TIFFFindCODEC(uint16_t scheme)
{
const TIFFCodec *c;
codec_t *cd;
for (cd = registeredCODECS; cd; cd = cd->next)
if (cd->info->scheme == scheme)
return ((const TIFFCodec *)cd->info);
for (c = _TIFFBuiltinCODECS; c->name; c++)
if (c->scheme == scheme)
return (c);
return ((const TIFFCodec *)0);
}
TIFFCodec *TIFFRegisterCODEC(uint16_t scheme, const char *name,
TIFFInitMethod init)
{
codec_t *cd = (codec_t *)_TIFFmallocExt(
NULL,
(tmsize_t)(sizeof(codec_t) + sizeof(TIFFCodec) + strlen(name) + 1));
if (cd != NULL)
{
cd->info = (TIFFCodec *)((uint8_t *)cd + sizeof(codec_t));
cd->info->name = (char *)((uint8_t *)cd->info + sizeof(TIFFCodec));
strcpy(cd->info->name, name);
cd->info->scheme = scheme;
cd->info->init = init;
cd->next = registeredCODECS;
registeredCODECS = cd;
}
else
{
TIFFErrorExt(0, "TIFFRegisterCODEC",
"No space to register compression scheme %s", name);
return NULL;
}
return (cd->info);
}
void TIFFUnRegisterCODEC(TIFFCodec *c)
{
codec_t *cd;
codec_t **pcd;
for (pcd = &registeredCODECS; (cd = *pcd) != NULL; pcd = &cd->next)
if (cd->info == c)
{
*pcd = cd->next;
_TIFFfreeExt(NULL, cd);
return;
}
TIFFErrorExt(0, "TIFFUnRegisterCODEC",
"Cannot remove compression scheme %s; not registered",
c->name);
}
/************************************************************************/
/* TIFFGetConfisuredCODECs() */
/************************************************************************/
/**
* Get list of configured codecs, both built-in and registered by user.
* Caller is responsible to free this structure.
*
* @return returns array of TIFFCodec records (the last record should be NULL)
* or NULL if function failed.
*/
TIFFCodec *TIFFGetConfiguredCODECs()
{
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 *)_TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec));
if (!new_codecs)
{
_TIFFfreeExt(NULL, codecs);
return NULL;
}
codecs = new_codecs;
_TIFFmemcpy(codecs + i - 1, cd->info, sizeof(TIFFCodec));
i++;
}
for (c = _TIFFBuiltinCODECS; c->name; c++)
{
if (TIFFIsCODECConfigured(c->scheme))
{
new_codecs = (TIFFCodec *)_TIFFreallocExt(NULL, codecs,
i * sizeof(TIFFCodec));
if (!new_codecs)
{
_TIFFfreeExt(NULL, codecs);
return NULL;
}
codecs = new_codecs;
_TIFFmemcpy(codecs + i - 1, (const void *)c, sizeof(TIFFCodec));
i++;
}
}
new_codecs =
(TIFFCodec *)_TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec));
if (!new_codecs)
{
_TIFFfreeExt(NULL, codecs);
return NULL;
}
codecs = new_codecs;
_TIFFmemset(codecs + i - 1, 0, sizeof(TIFFCodec));
return codecs;
}
+163
View File
@@ -0,0 +1,163 @@
/* clang-format off */
/* clang-format disabled because CMake scripts are very sensitive to the
* formatting of this file. configure_file variables of type "@VAR@" are
* modified by clang-format and won't be substituted.
*/
/* libtiff/tif_config.h.cmake.in. Not generated, but originated from autoheader. */
/* This file must be kept up-to-date with needed substitutions from libtiff/tif_config.h.in. */
#include "tiffconf.h"
/* Support CCITT Group 3 & 4 algorithms */
#cmakedefine CCITT_SUPPORT 1
/* Pick up YCbCr subsampling info from the JPEG data stream to support files
lacking the tag (default enabled). */
#cmakedefine CHECK_JPEG_YCBCR_SUBSAMPLING 1
/* enable partial strip reading for large strips (experimental) */
#cmakedefine CHUNKY_STRIP_READ_SUPPORT 1
/* Support C++ stream API (requires C++ compiler) */
#cmakedefine CXX_SUPPORT 1
/* enable deferred strip/tile offset/size loading (experimental) */
#cmakedefine DEFER_STRILE_LOAD 1
/* Define to 1 if you have the <assert.h> header file. */
#cmakedefine HAVE_ASSERT_H 1
/* Define to 1 if you have the declaration of `optarg', and to 0 if you don't. */
#cmakedefine HAVE_DECL_OPTARG 1
/* Define to 1 if you have the <fcntl.h> header file. */
#cmakedefine HAVE_FCNTL_H 1
/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
#cmakedefine HAVE_FSEEKO 1
/* Define to 1 if you have the `getopt' function. */
#cmakedefine HAVE_GETOPT 1
/* Define to 1 if you have the <GLUT/glut.h> header file. */
#cmakedefine HAVE_GLUT_GLUT_H 1
/* Define to 1 if you have the <GL/glut.h> header file. */
#cmakedefine HAVE_GL_GLUT_H 1
/* Define to 1 if you have the <GL/glu.h> header file. */
#cmakedefine HAVE_GL_GLU_H 1
/* Define to 1 if you have the <GL/gl.h> header file. */
#cmakedefine HAVE_GL_GL_H 1
/* Define to 1 if you have the <io.h> header file. */
#cmakedefine HAVE_IO_H 1
/* Define to 1 if you have the `jbg_newlen' function. */
#cmakedefine HAVE_JBG_NEWLEN 1
/* Define to 1 if you have the `mmap' function. */
#cmakedefine HAVE_MMAP 1
/* Define to 1 if you have the <OpenGL/glu.h> header file. */
#cmakedefine HAVE_OPENGL_GLU_H 1
/* Define to 1 if you have the <OpenGL/gl.h> header file. */
#cmakedefine HAVE_OPENGL_GL_H 1
/* Define to 1 if you have the `setmode' function. */
#cmakedefine HAVE_SETMODE 1
/* Define to 1 if you have the <strings.h> header file. */
#cmakedefine HAVE_STRINGS_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#cmakedefine HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#cmakedefine HAVE_UNISTD_H 1
/* 8/12 bit libjpeg dual mode enabled */
#cmakedefine JPEG_DUAL_MODE_8_12 1
/* 8/12 bit dual mode JPEG built into libjpeg-turbo 3.0+ */
#cmakedefine HAVE_JPEGTURBO_DUAL_MODE_8_12 1
/* Support LERC compression */
#cmakedefine LERC_SUPPORT 1
/* Define to 1 when building a static libtiff with LERC enabled. */
#cmakedefine LERC_STATIC
/* 12bit libjpeg primary include file with path */
#define LIBJPEG_12_PATH "@LIBJPEG_12_PATH@"
/* Support LZMA2 compression */
#cmakedefine LZMA_SUPPORT 1
/* Name of package */
#define PACKAGE "@PACKAGE_NAME@"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@"
/* Define to the full name of this package. */
#define PACKAGE_NAME "@PACKAGE_NAME@"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "@PACKAGE_TARNAME@"
/* Define to the home page for this package. */
#define PACKAGE_URL "@PACKAGE_URL@"
/* Size of size_t */
#define SIZEOF_SIZE_T @SIZEOF_SIZE_T@
/* Default size of the strip in bytes (when strip chopping enabled) */
#cmakedefine STRIP_SIZE_DEFAULT @STRIP_SIZE_DEFAULT@
/** Maximum number of TIFF IFDs that libtiff can iterate through in a file. */
#define TIFF_MAX_DIR_COUNT @TIFF_MAX_DIR_COUNT@
/* define to use win32 IO system */
#cmakedefine USE_WIN32_FILEIO 1
/* Support WEBP compression */
#cmakedefine WEBP_SUPPORT 1
/* Support ZSTD compression */
#cmakedefine ZSTD_SUPPORT 1
/* 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 1
# endif
#endif
#if !defined(__MINGW32__)
# define TIFF_SIZE_FORMAT "zu"
#endif
#if SIZEOF_SIZE_T == 8
# define TIFF_SSIZE_FORMAT PRId64
# if defined(__MINGW32__)
# define TIFF_SIZE_FORMAT PRIu64
# endif
#elif SIZEOF_SIZE_T == 4
# define TIFF_SSIZE_FORMAT PRId32
# if defined(__MINGW32__)
# define TIFF_SIZE_FORMAT PRIu32
# endif
#else
# error "Unsupported size_t size; please submit a bug report"
#endif
/* clang-format on */
+2366
View File
File diff suppressed because it is too large Load Diff
+365
View File
@@ -0,0 +1,365 @@
/*
* 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.
*/
#ifndef _TIFFDIR_
#define _TIFFDIR_
#include "tiff.h"
#include "tiffio.h"
/*
* ``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_t tdir_tag; /* see below */
uint16_t tdir_type; /* data type; see below */
uint64_t tdir_count; /* number of items; length in spec */
union
{
uint16_t toff_short;
uint32_t toff_long;
uint64_t toff_long8;
} tdir_offset; /* either offset or the data itself if fits */
uint8_t tdir_ignore; /* flag status to ignore tag when parsing tags in
tif_dirread.c */
} TIFFDirEntry;
typedef struct
{
uint64_t offset;
uint64_t length;
} TIFFEntryOffsetAndLength; /* auxiliary for evaluating size of IFD data */
/*
* Internal format of a TIFF directory entry.
*/
typedef struct
{
#define FIELDSET_ITEMS 4
/* bit vector of fields that are set */
uint32_t td_fieldsset[FIELDSET_ITEMS];
uint32_t td_imagewidth, td_imagelength, td_imagedepth;
uint32_t td_tilewidth, td_tilelength, td_tiledepth;
uint32_t td_subfiletype;
uint16_t td_bitspersample;
uint16_t td_sampleformat;
uint16_t td_compression;
uint16_t td_photometric;
uint16_t td_threshholding;
uint16_t td_fillorder;
uint16_t td_orientation;
uint16_t td_samplesperpixel;
uint32_t td_rowsperstrip;
uint16_t td_minsamplevalue, td_maxsamplevalue;
double *td_sminsamplevalue;
double *td_smaxsamplevalue;
float td_xresolution, td_yresolution;
uint16_t td_resolutionunit;
uint16_t td_planarconfig;
float td_xposition, td_yposition;
uint16_t td_pagenumber[2];
uint16_t *td_colormap[3];
uint16_t td_halftonehints[2];
uint16_t td_extrasamples;
uint16_t *td_sampleinfo;
/* 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 */
uint32_t td_stripsperimage;
uint32_t td_nstrips; /* size of offset & bytecount arrays */
uint64_t
*td_stripoffset_p; /* should be accessed with TIFFGetStrileOffset */
uint64_t *td_stripbytecount_p; /* should be accessed with
TIFFGetStrileByteCount */
uint32_t
td_stripoffsetbyteallocsize; /* number of elements currently allocated
for td_stripoffset/td_stripbytecount.
Only used if TIFF_LAZYSTRILELOAD is set
*/
#ifdef STRIPBYTECOUNTSORTED_UNUSED
int td_stripbytecountsorted; /* is the bytecount array sorted ascending? */
#endif
/* Be aware that the parameters of td_stripoffset_entry and
* td_stripbytecount_entry are swapped but tdir_offset is not
* and has to be swapped when used. */
TIFFDirEntry td_stripoffset_entry; /* for deferred loading */
TIFFDirEntry td_stripbytecount_entry; /* for deferred loading */
uint16_t td_nsubifd;
uint64_t *td_subifd;
/* YCbCr parameters */
uint16_t td_ycbcrsubsampling[2];
uint16_t td_ycbcrpositioning;
/* Colorimetry parameters */
uint16_t *td_transferfunction[3];
float *td_refblackwhite;
/* CMYK parameters */
int td_inknameslen;
char *td_inknames;
uint16_t td_numberofinks; /* number of inks in InkNames string */
int td_customValueCount;
TIFFTagValue *td_customValues;
unsigned char
td_deferstrilearraywriting; /* see TIFFDeferStrileArrayWriting() */
unsigned char
td_iswrittentofile; /* indicates if current IFD is present on file */
/* LibTIFF writes all data that does not fit into the IFD entries directly
* after the IFD tag entry part. When reading, only the IFD data directly
* and continuously behind the IFD tags is taken into account for the IFD
* data size.*/
uint64_t td_dirdatasize_write; /* auxiliary for evaluating size of IFD data
to be written */
uint64_t td_dirdatasize_read; /* auxiliary for evaluating size of IFD data
read from file */
uint32_t td_dirdatasize_Noffsets; /* auxiliary counter for
tif_dir.td_dirdatasize_offsets array */
TIFFEntryOffsetAndLength
*td_dirdatasize_offsets; /* auxiliary array for all offsets of IFD tag
entries with data outside the IFD tag
entries. */
} TIFFDirectory;
/*
* 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
/* multi-item fields */
#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
#define FIELD_NUMBEROFINKS 50
/* 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 */
/*
* 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 * FIELDSET_ITEMS - 1)
#define BITn(n) (((uint32_t)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))
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 TIFFFieldArray *_TIFFGetFields(void);
extern const TIFFFieldArray *_TIFFGetExifFields(void);
extern const TIFFFieldArray *_TIFFGetGpsFields(void);
extern void _TIFFSetupFields(TIFF *tif, const TIFFFieldArray *infoarray);
extern void _TIFFPrintFieldInfo(TIFF *, FILE *);
extern int _TIFFFillStriles(TIFF *);
typedef enum
{
tfiatImage,
tfiatExif,
tfiatGps, /* EXIF-GPS fields array type */
tfiatOther
} TIFFFieldArrayType;
struct _TIFFFieldArray
{
TIFFFieldArrayType type; /* array type, will be used to determine if IFD
is image and such */
uint32_t allocated_size; /* 0 if array is constant, other if modified by
future definition extension support */
uint32_t count; /* number of elements in fields array */
TIFFField *fields; /* actual field info */
};
struct _TIFFField
{
uint32_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 */
uint32_t field_anonymous; /* if true, this is a unknown /
anonymous tag */
TIFFSetGetFieldType set_get_field_type; /* type to be passed to
TIFFSetField, 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_t);
extern const TIFFField *_TIFFFindOrRegisterField(TIFF *, uint32_t,
TIFFDataType);
extern TIFFField *_TIFFCreateAnonField(TIFF *, uint32_t, TIFFDataType);
extern int _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag);
extern int _TIFFCheckDirNumberAndOffset(TIFF *tif, tdir_t dirn,
uint64_t diroff);
extern int _TIFFGetDirNumberFromOffset(TIFF *tif, uint64_t diroff,
tdir_t *dirn);
extern int _TIFFGetOffsetFromDirNumber(TIFF *tif, tdir_t dirn,
uint64_t *diroff);
extern int _TIFFRemoveEntryFromDirectoryListByOffset(TIFF *tif,
uint64_t diroff);
#if defined(__cplusplus)
}
#endif
#endif /* _TIFFDIR_ */
+1364
View File
File diff suppressed because it is too large Load Diff
+8447
View File
File diff suppressed because it is too large Load Diff
+3824
View File
File diff suppressed because it is too large Load Diff
+122
View File
@@ -0,0 +1,122 @@
/*
* 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.
*
* "Null" Compression Algorithm Support.
*/
#include "tiffiop.h"
static int DumpFixupTags(TIFF *tif)
{
(void)tif;
return (1);
}
/*
* Encode a hunk of pixels.
*/
static int DumpModeEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
{
(void)s;
while (cc > 0)
{
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.
*/
if (tif->tif_rawcp != pp)
_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 (0);
}
return (1);
}
/*
* Decode a hunk of pixels.
*/
static int DumpModeDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
{
static const char module[] = "DumpModeDecode";
(void)s;
if (tif->tif_rawcc < cc)
{
TIFFErrorExtR(tif, module,
"Not enough data for scanline %" PRIu32
", expected a request for at most %" TIFF_SSIZE_FORMAT
" bytes, got a request for %" TIFF_SSIZE_FORMAT " bytes",
tif->tif_row, tif->tif_rawcc, cc);
return (0);
}
/*
* Avoid copy if client has setup raw
* data buffer to avoid extra copy.
*/
if (tif->tif_rawcp != buf)
_TIFFmemcpy(buf, tif->tif_rawcp, cc);
tif->tif_rawcp += cc;
tif->tif_rawcc -= cc;
return (1);
}
/*
* Seek forwards nrows in the current strip.
*/
static int DumpModeSeek(TIFF *tif, uint32_t nrows)
{
tif->tif_rawcp += nrows * tif->tif_scanlinesize;
tif->tif_rawcc -= nrows * tif->tif_scanlinesize;
return (1);
}
/*
* Initialize dump mode.
*/
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_seek = DumpModeSeek;
return (1);
}
+132
View File
@@ -0,0 +1,132 @@
/*
* 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.
*/
#include "tiffiop.h"
TIFFErrorHandlerExt _TIFFerrorHandlerExt = NULL;
TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler handler)
{
TIFFErrorHandler prev = _TIFFerrorHandler;
_TIFFerrorHandler = handler;
return (prev);
}
TIFFErrorHandlerExt TIFFSetErrorHandlerExt(TIFFErrorHandlerExt handler)
{
TIFFErrorHandlerExt prev = _TIFFerrorHandlerExt;
_TIFFerrorHandlerExt = handler;
return (prev);
}
void TIFFError(const char *module, const char *fmt, ...)
{
va_list ap;
if (_TIFFerrorHandler)
{
va_start(ap, fmt);
(*_TIFFerrorHandler)(module, fmt, ap);
va_end(ap);
}
if (_TIFFerrorHandlerExt)
{
va_start(ap, fmt);
(*_TIFFerrorHandlerExt)(0, module, fmt, ap);
va_end(ap);
}
}
void TIFFErrorExt(thandle_t fd, const char *module, const char *fmt, ...)
{
va_list ap;
if (_TIFFerrorHandler)
{
va_start(ap, fmt);
(*_TIFFerrorHandler)(module, fmt, ap);
va_end(ap);
}
if (_TIFFerrorHandlerExt)
{
va_start(ap, fmt);
(*_TIFFerrorHandlerExt)(fd, module, fmt, ap);
va_end(ap);
}
}
void _TIFFErrorEarly(TIFFOpenOptions *opts, thandle_t clientdata,
const char *module, const char *fmt, ...)
{
va_list ap;
if (opts && opts->errorhandler)
{
va_start(ap, fmt);
int stop = opts->errorhandler(NULL, opts->errorhandler_user_data,
module, fmt, ap);
va_end(ap);
if (stop)
return;
}
if (_TIFFerrorHandler)
{
va_start(ap, fmt);
(*_TIFFerrorHandler)(module, fmt, ap);
va_end(ap);
}
if (_TIFFerrorHandlerExt)
{
va_start(ap, fmt);
(*_TIFFerrorHandlerExt)(clientdata, module, fmt, ap);
va_end(ap);
}
}
void TIFFErrorExtR(TIFF *tif, const char *module, const char *fmt, ...)
{
va_list ap;
if (tif && tif->tif_errorhandler)
{
va_start(ap, fmt);
int stop = (*tif->tif_errorhandler)(
tif, tif->tif_errorhandler_user_data, module, fmt, ap);
va_end(ap);
if (stop)
return;
}
if (_TIFFerrorHandler)
{
va_start(ap, fmt);
(*_TIFFerrorHandler)(module, fmt, ap);
va_end(ap);
}
if (_TIFFerrorHandlerExt)
{
va_start(ap, fmt);
(*_TIFFerrorHandlerExt)(tif ? tif->tif_clientdata : NULL, module, fmt,
ap);
va_end(ap);
}
}
+110
View File
@@ -0,0 +1,110 @@
/*
* 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.
*
* Various routines support external extension of the tag set, and other
* application extension capabilities.
*/
#include "tiffiop.h"
int TIFFGetTagListCount(TIFF *tif)
{
TIFFDirectory *td = &tif->tif_dir;
return td->td_customValueCount;
}
uint32_t TIFFGetTagListEntry(TIFF *tif, int tag_index)
{
TIFFDirectory *td = &tif->tif_dir;
if (tag_index < 0 || tag_index >= td->td_customValueCount)
return (uint32_t)(-1);
else
return td->td_customValues[tag_index].info->field_tag;
}
/*
** This provides read/write access to the TIFFTagMethods within the TIFF
** structure to application code without giving access to the private
** TIFF structure.
*/
TIFFTagMethods *TIFFAccessTagMethods(TIFF *tif)
{
return &(tif->tif_tagmethods);
}
void *TIFFGetClientInfo(TIFF *tif, const char *name)
{
TIFFClientInfoLink *psLink = tif->tif_clientinfo;
while (psLink != NULL && strcmp(psLink->name, name) != 0)
psLink = psLink->next;
if (psLink != NULL)
return psLink->data;
else
return NULL;
}
void TIFFSetClientInfo(TIFF *tif, void *data, const char *name)
{
TIFFClientInfoLink *psLink = tif->tif_clientinfo;
/*
** Do we have an existing link with this name? If so, just
** set it.
*/
while (psLink != NULL && strcmp(psLink->name, name) != 0)
psLink = psLink->next;
if (psLink != NULL)
{
psLink->data = data;
return;
}
/*
** Create a new link.
*/
psLink =
(TIFFClientInfoLink *)_TIFFmallocExt(tif, sizeof(TIFFClientInfoLink));
assert(psLink != NULL);
psLink->next = tif->tif_clientinfo;
psLink->name = (char *)_TIFFmallocExt(tif, (tmsize_t)(strlen(name) + 1));
assert(psLink->name != NULL);
strcpy(psLink->name, name);
psLink->data = data;
tif->tif_clientinfo = psLink;
}
+1844
View File
File diff suppressed because it is too large Load Diff
+657
View File
@@ -0,0 +1,657 @@
/*
* Copyright (c) 1990-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.
*/
#ifndef _FAX3_
#define _FAX3_
/*
* TIFF Library.
*
* CCITT Group 3 (T.4) and Group 4 (T.6) Decompression Support.
*
* Decoder support is derived, with permission, from the code
* in Frank Cringle's viewfax program;
* Copyright (C) 1990, 1995 Frank D. Cringle.
*/
#include "tiff.h"
/*
* To override the default routine used to image decoded
* spans one can use the pseudo tag TIFFTAG_FAXFILLFUNC.
* The routine must have the type signature given below;
* for example:
*
* fillruns(unsigned char* buf, uint32_t* runs, uint32_t* erun, uint32_t lastx)
*
* where buf is place to set the bits, runs is the array of b&w run
* lengths (white then black), erun is the last run in the array, and
* lastx is the width of the row in pixels. Fill routines can assume
* the run array has room for at least lastx runs and can overwrite
* 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_t *, uint32_t *,
uint32_t);
/*
* The default run filler; made external for other decoders.
*/
#if defined(__cplusplus)
extern "C"
{
#endif
extern void _TIFFFax3fillruns(unsigned char *, uint32_t *, uint32_t *,
uint32_t);
#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
/* WARNING: do not change the layout of this structure as the HylaFAX software
*/
/* really depends on it. See http://bugzilla.maptools.org/show_bug.cgi?id=2636
*/
typedef struct
{ /* state table entry */
unsigned char State; /* see above */
unsigned char Width; /* width of code in bits */
uint32_t Param; /* unsigned 32-bit run length in bits (holds on 16 bit
actually, but cannot be changed. See above warning) */
} TIFFFaxTabEnt;
extern const TIFFFaxTabEnt TIFFFaxMainTable[];
extern const TIFFFaxTabEnt TIFFFaxWhiteTable[];
extern const TIFFFaxTabEnt TIFFFaxBlackTable[];
/*
* The following macros define the majority of the G3/G4 decoder
* algorithm using the state tables defined elsewhere. To build
* a decoder you need some setup code and some glue code. Note
* that you may also need/want to change the way the NeedBits*
* macros get input data if, for example, you know the data to be
* decoded is properly aligned and oriented (doing so before running
* the decoder can be a big performance win).
*
* Consult the decoder in the TIFF library for an idea of what you
* need to define and setup to make use of these definitions.
*
* NB: to enable a debugging version of these macros define FAX3_DEBUG
* before including this file. Trace output goes to stdout.
*/
#ifndef EndOfData
#define EndOfData() (cp >= ep)
#endif
/*
* Need <=8 or <=16 bits of input data. Unlike viewfax we
* cannot use/assume a word-aligned, properly bit swizzled
* input data set because data may come from an arbitrarily
* aligned, read-only source such as a memory-mapped file.
* Note also that the viewfax decoder does not check for
* running off the end of the input data buffer. This is
* possible for G3-encoded data because it prescans the input
* data to count EOL markers, but can cause problems for G4
* data. In any event, we don't prescan and must watch for
* running out of data since we can't permit the library to
* scan past the end of the input data buffer.
*
* Finally, note that we must handle remaindered data at the end
* of a strip specially. The coder asks for a fixed number of
* bits when scanning for the next code. This may be more bits
* than are actually present in the data stream. If we appear
* to run out of data but still have some number of valid bits
* remaining then we makeup the requested amount with zeros and
* return successfully. If the returned data is incorrect then
* we should be called again and get a premature EOF error;
* otherwise we should get the right answer.
*/
#ifndef NeedBits8
#define NeedBits8(n, eoflab) \
do \
{ \
if (BitsAvail < (n)) \
{ \
if (EndOfData()) \
{ \
if (BitsAvail == 0) /* no valid bits */ \
goto eoflab; \
BitsAvail = (n); /* pad with zeros */ \
} \
else \
{ \
BitAcc |= ((uint32_t)bitmap[*cp++]) << BitsAvail; \
BitsAvail += 8; \
} \
} \
} while (0)
#endif
#ifndef NeedBits16
#define NeedBits16(n, eoflab) \
do \
{ \
if (BitsAvail < (n)) \
{ \
if (EndOfData()) \
{ \
if (BitsAvail == 0) /* no valid bits */ \
goto eoflab; \
BitsAvail = (n); /* pad with zeros */ \
} \
else \
{ \
BitAcc |= ((uint32_t)bitmap[*cp++]) << BitsAvail; \
if ((BitsAvail += 8) < (n)) \
{ \
if (EndOfData()) \
{ \
/* NB: we know BitsAvail is non-zero here */ \
BitsAvail = (n); /* pad with zeros */ \
} \
else \
{ \
BitAcc |= ((uint32_t)bitmap[*cp++]) << BitsAvail; \
BitsAvail += 8; \
} \
} \
} \
} \
} while (0)
#endif
#define GetBits(n) (BitAcc & ((1 << (n)) - 1))
#define ClrBits(n) \
do \
{ \
BitsAvail -= (n); \
BitAcc >>= (n); \
} while (0)
#ifdef FAX3_DEBUG
static const char *StateNames[] = {
"Null ", "Pass ", "Horiz ", "V0 ", "VR ", "VL ", "Ext ",
"TermW ", "TermB ", "MakeUpW", "MakeUpB", "MakeUp ", "EOL ",
};
#define DEBUG_SHOW putchar(BitAcc & (1 << t) ? '1' : '0')
#define LOOKUP8(wid, tab, eoflab) \
do \
{ \
int t; \
NeedBits8(wid, eoflab); \
TabEnt = tab + GetBits(wid); \
printf("%08lX/%d: %s%5d\t", (long)BitAcc, BitsAvail, \
StateNames[TabEnt->State], TabEnt->Param); \
for (t = 0; t < TabEnt->Width; t++) \
DEBUG_SHOW; \
putchar('\n'); \
fflush(stdout); \
ClrBits(TabEnt->Width); \
} while (0)
#define LOOKUP16(wid, tab, eoflab) \
do \
{ \
int t; \
NeedBits16(wid, eoflab); \
TabEnt = tab + GetBits(wid); \
printf("%08lX/%d: %s%5d\t", (long)BitAcc, BitsAvail, \
StateNames[TabEnt->State], TabEnt->Param); \
for (t = 0; t < TabEnt->Width; t++) \
DEBUG_SHOW; \
putchar('\n'); \
fflush(stdout); \
ClrBits(TabEnt->Width); \
} while (0)
#define SETVALUE(x) \
do \
{ \
*pa++ = RunLength + (x); \
printf("SETVALUE: %d\t%d\n", RunLength + (x), a0); \
a0 += x; \
RunLength = 0; \
} while (0)
#else
#define LOOKUP8(wid, tab, eoflab) \
do \
{ \
NeedBits8(wid, eoflab); \
TabEnt = tab + GetBits(wid); \
ClrBits(TabEnt->Width); \
} while (0)
#define LOOKUP16(wid, tab, eoflab) \
do \
{ \
NeedBits16(wid, eoflab); \
TabEnt = tab + GetBits(wid); \
ClrBits(TabEnt->Width); \
} while (0)
/*
* Append a run to the run length array for the
* current row and reset decoding state.
*/
#define SETVALUE(x) \
do \
{ \
if (pa >= thisrun + sp->nruns) \
{ \
TIFFErrorExtR(tif, module, "Buffer overflow at line %u of %s %u", \
sp->line, isTiled(tif) ? "tile" : "strip", \
isTiled(tif) ? tif->tif_curtile \
: tif->tif_curstrip); \
return (-1); \
} \
*pa++ = RunLength + (x); \
a0 += (x); \
RunLength = 0; \
} while (0)
#endif
/*
* Synchronize input decoding at the start of each
* row by scanning for an EOL (if appropriate) and
* skipping any trash data that might be present
* after a decoding error. Note that the decoding
* done elsewhere that recognizes an EOL only consumes
* 11 consecutive zero bits. This means that if EOLcnt
* is non-zero then we still need to scan for the final flag
* bit that is part of the EOL code.
*/
#define SYNC_EOL(eoflab, retrywithouteol) \
do \
{ \
if (!(sp->b.mode & FAXMODE_NOEOL)) /* skip EOL, if not present */ \
{ \
if (EOLcnt == 0) \
{ \
for (;;) \
{ \
NeedBits16(11, eoflab); \
if (GetBits(11) == 0) \
break; /* EOL found */ \
ClrBits(1); \
} \
} \
/* Now move after EOL or detect missing EOL. */ \
for (;;) \
{ \
NeedBits8(8, noEOLFound); \
if (GetBits(8)) \
break; \
ClrBits(8); \
} \
while (GetBits(1) == 0) \
ClrBits(1); \
ClrBits(1); /* EOL bit */ \
EOLcnt = 0; /* reset EOL counter/flag */ \
break; /* existing EOL skipped, leave macro */ \
noEOLFound: \
sp->b.mode |= FAXMODE_NOEOL; \
tryG3WithoutEOL(a0); \
goto retrywithouteol; \
} \
} while (0)
/*
* Cleanup the array of runs after decoding a row.
* We adjust final runs to insure the user buffer is not
* overwritten and/or undecoded area is white filled.
*/
#define CLEANUP_RUNS() \
do \
{ \
if (RunLength) \
SETVALUE(0); \
if (a0 != lastx) \
{ \
badlength(a0, lastx); \
while (a0 > lastx && pa > thisrun) \
a0 -= *--pa; \
if (a0 < lastx) \
{ \
if (a0 < 0) \
a0 = 0; \
if ((pa - thisrun) & 1) \
SETVALUE(0); \
SETVALUE(lastx - a0); \
} \
else if (a0 > lastx) \
{ \
SETVALUE(lastx); \
SETVALUE(0); \
} \
} \
} while (0)
/*
* Decode a line of 1D-encoded data.
*
* The line expanders are written as macros so that they can be reused
* but still have direct access to the local variables of the "calling"
* function.
*
* Note that unlike the original version we have to explicitly test for
* a0 >= lastx after each black/white run is decoded. This is because
* the original code depended on the input data being zero-padded to
* insure the decoder recognized an EOL before running out of data.
*/
#define EXPAND1D(eoflab) \
do \
{ \
for (;;) \
{ \
for (;;) \
{ \
LOOKUP16(12, TIFFFaxWhiteTable, eof1d); \
switch (TabEnt->State) \
{ \
case S_EOL: \
EOLcnt = 1; \
goto done1d; \
case S_TermW: \
SETVALUE(TabEnt->Param); \
goto doneWhite1d; \
case S_MakeUpW: \
case S_MakeUp: \
a0 += TabEnt->Param; \
RunLength += TabEnt->Param; \
break; \
default: \
unexpected("WhiteTable", a0); \
goto done1d; \
} \
} \
doneWhite1d: \
if (a0 >= lastx) \
goto done1d; \
for (;;) \
{ \
LOOKUP16(13, TIFFFaxBlackTable, eof1d); \
switch (TabEnt->State) \
{ \
case S_EOL: \
EOLcnt = 1; \
goto done1d; \
case S_TermB: \
SETVALUE(TabEnt->Param); \
goto doneBlack1d; \
case S_MakeUpB: \
case S_MakeUp: \
a0 += TabEnt->Param; \
RunLength += TabEnt->Param; \
break; \
default: \
unexpected("BlackTable", a0); \
goto done1d; \
} \
} \
doneBlack1d: \
if (a0 >= lastx) \
goto done1d; \
if (*(pa - 1) == 0 && *(pa - 2) == 0) \
pa -= 2; \
} \
eof1d: \
prematureEOF(a0); \
CLEANUP_RUNS(); \
goto eoflab; \
done1d: \
CLEANUP_RUNS(); \
} while (0)
/*
* Update the value of b1 using the array
* of runs for the reference line.
*/
#define CHECK_b1 \
do \
{ \
if (pa != thisrun) \
while (b1 <= a0 && b1 < lastx) \
{ \
if (pb + 1 >= sp->refruns + sp->nruns) \
{ \
TIFFErrorExtR( \
tif, module, "Buffer overflow at line %u of %s %u", \
sp->line, isTiled(tif) ? "tile" : "strip", \
isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
return (-1); \
} \
b1 += pb[0] + pb[1]; \
pb += 2; \
} \
} while (0)
/*
* Expand a row of 2D-encoded data.
*/
#define EXPAND2D(eoflab) \
do \
{ \
while (a0 < lastx) \
{ \
if (pa >= thisrun + sp->nruns) \
{ \
TIFFErrorExtR( \
tif, module, "Buffer overflow at line %u of %s %u", \
sp->line, isTiled(tif) ? "tile" : "strip", \
isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
return (-1); \
} \
LOOKUP8(7, TIFFFaxMainTable, eof2d); \
switch (TabEnt->State) \
{ \
case S_Pass: \
CHECK_b1; \
if (pb + 1 >= sp->refruns + sp->nruns) \
{ \
TIFFErrorExtR(tif, module, \
"Buffer overflow at line %u of %s %u", \
sp->line, \
isTiled(tif) ? "tile" : "strip", \
isTiled(tif) ? tif->tif_curtile \
: tif->tif_curstrip); \
return (-1); \
} \
b1 += *pb++; \
RunLength += b1 - a0; \
a0 = b1; \
b1 += *pb++; \
break; \
case S_Horiz: \
if ((pa - thisrun) & 1) \
{ \
for (;;) \
{ /* black first */ \
LOOKUP16(13, TIFFFaxBlackTable, eof2d); \
switch (TabEnt->State) \
{ \
case S_TermB: \
SETVALUE(TabEnt->Param); \
goto doneWhite2da; \
case S_MakeUpB: \
case S_MakeUp: \
a0 += TabEnt->Param; \
RunLength += TabEnt->Param; \
break; \
default: \
goto badBlack2d; \
} \
} \
doneWhite2da:; \
for (;;) \
{ /* then white */ \
LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \
switch (TabEnt->State) \
{ \
case S_TermW: \
SETVALUE(TabEnt->Param); \
goto doneBlack2da; \
case S_MakeUpW: \
case S_MakeUp: \
a0 += TabEnt->Param; \
RunLength += TabEnt->Param; \
break; \
default: \
goto badWhite2d; \
} \
} \
doneBlack2da:; \
} \
else \
{ \
for (;;) \
{ /* white first */ \
LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \
switch (TabEnt->State) \
{ \
case S_TermW: \
SETVALUE(TabEnt->Param); \
goto doneWhite2db; \
case S_MakeUpW: \
case S_MakeUp: \
a0 += TabEnt->Param; \
RunLength += TabEnt->Param; \
break; \
default: \
goto badWhite2d; \
} \
} \
doneWhite2db:; \
for (;;) \
{ /* then black */ \
LOOKUP16(13, TIFFFaxBlackTable, eof2d); \
switch (TabEnt->State) \
{ \
case S_TermB: \
SETVALUE(TabEnt->Param); \
goto doneBlack2db; \
case S_MakeUpB: \
case S_MakeUp: \
a0 += TabEnt->Param; \
RunLength += TabEnt->Param; \
break; \
default: \
goto badBlack2d; \
} \
} \
doneBlack2db:; \
} \
CHECK_b1; \
break; \
case S_V0: \
CHECK_b1; \
SETVALUE(b1 - a0); \
if (pb >= sp->refruns + sp->nruns) \
{ \
TIFFErrorExtR(tif, module, \
"Buffer overflow at line %u of %s %u", \
sp->line, \
isTiled(tif) ? "tile" : "strip", \
isTiled(tif) ? tif->tif_curtile \
: tif->tif_curstrip); \
return (-1); \
} \
b1 += *pb++; \
break; \
case S_VR: \
CHECK_b1; \
SETVALUE(b1 - a0 + TabEnt->Param); \
if (pb >= sp->refruns + sp->nruns) \
{ \
TIFFErrorExtR(tif, module, \
"Buffer overflow at line %u of %s %u", \
sp->line, \
isTiled(tif) ? "tile" : "strip", \
isTiled(tif) ? tif->tif_curtile \
: tif->tif_curstrip); \
return (-1); \
} \
b1 += *pb++; \
break; \
case S_VL: \
CHECK_b1; \
if (b1 < (int)(a0 + TabEnt->Param)) \
{ \
unexpected("VL", a0); \
goto eol2d; \
} \
SETVALUE(b1 - a0 - TabEnt->Param); \
b1 -= *--pb; \
break; \
case S_Ext: \
*pa++ = lastx - a0; \
extension(a0); \
goto eol2d; \
case S_EOL: \
*pa++ = lastx - a0; \
NeedBits8(4, eof2d); \
if (GetBits(4)) \
unexpected("EOL", a0); \
ClrBits(4); \
EOLcnt = 1; \
goto eol2d; \
default: \
badMain2d: \
unexpected("MainTable", a0); \
goto eol2d; \
badBlack2d: \
unexpected("BlackTable", a0); \
goto eol2d; \
badWhite2d: \
unexpected("WhiteTable", a0); \
goto eol2d; \
eof2d: \
prematureEOF(a0); \
CLEANUP_RUNS(); \
goto eoflab; \
} \
} \
if (RunLength) \
{ \
if (RunLength + a0 < lastx) \
{ \
/* expect a final V0 */ \
NeedBits8(1, eof2d); \
if (!GetBits(1)) \
goto badMain2d; \
ClrBits(1); \
} \
SETVALUE(0); \
} \
eol2d: \
CLEANUP_RUNS(); \
} while (0)
#endif /* _FAX3_ */
+1261
View File
File diff suppressed because it is too large Load Diff
+157
View File
@@ -0,0 +1,157 @@
/*
* 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.
*/
#include "tiffiop.h"
int TIFFFlush(TIFF *tif)
{
if (tif->tif_mode == O_RDONLY)
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)
{
if (TIFFForceStrileArrayWriting(tif))
return 1;
}
if ((tif->tif_flags & (TIFF_DIRTYDIRECT | TIFF_DIRTYSTRIP)) &&
!TIFFRewriteDirectory(tif))
return (0);
return (1);
}
/*
* This is an advanced writing function that must be used in a particular
* sequence, and together with TIFFDeferStrileArrayWriting(),
* to make its intended effect. Its aim is to force the writing of
* the [Strip/Tile][Offsets/ByteCounts] arrays at the end of the file, when
* they have not yet been rewritten.
*
* The typical sequence of calls is:
* TIFFOpen()
* [ TIFFCreateDirectory(tif) ]
* Set fields with calls to TIFFSetField(tif, ...)
* TIFFDeferStrileArrayWriting(tif)
* TIFFWriteCheck(tif, ...)
* TIFFWriteDirectory(tif)
* ... potentially create other directories and come back to the above directory
* TIFFForceStrileArrayWriting(tif)
*
* Returns 1 in case of success, 0 otherwise.
*/
int TIFFForceStrileArrayWriting(TIFF *tif)
{
static const char module[] = "TIFFForceStrileArrayWriting";
const int isTiled = TIFFIsTiled(tif);
if (tif->tif_mode == O_RDONLY)
{
TIFFErrorExtR(tif, tif->tif_name, "File opened in read-only mode");
return 0;
}
if (tif->tif_diroff == 0)
{
TIFFErrorExtR(tif, module, "Directory has not yet been written");
return 0;
}
if ((tif->tif_flags & TIFF_DIRTYDIRECT) != 0)
{
TIFFErrorExtR(tif, module,
"Directory has changes other than the strile arrays. "
"TIFFRewriteDirectory() should be called instead");
return 0;
}
if (!(tif->tif_flags & TIFF_DIRTYSTRIP))
{
if (!(tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0))
{
TIFFErrorExtR(tif, module,
"Function not called together with "
"TIFFDeferStrileArrayWriting()");
return 0;
}
if (tif->tif_dir.td_stripoffset_p == NULL && !TIFFSetupStrips(tif))
return 0;
}
if (_TIFFRewriteField(tif,
isTiled ? TIFFTAG_TILEOFFSETS : TIFFTAG_STRIPOFFSETS,
TIFF_LONG8, tif->tif_dir.td_nstrips,
tif->tif_dir.td_stripoffset_p) &&
_TIFFRewriteField(
tif, isTiled ? TIFFTAG_TILEBYTECOUNTS : TIFFTAG_STRIPBYTECOUNTS,
TIFF_LONG8, tif->tif_dir.td_nstrips,
tif->tif_dir.td_stripbytecount_p))
{
tif->tif_flags &= ~TIFF_DIRTYSTRIP;
tif->tif_flags &= ~TIFF_BEENWRITING;
return 1;
}
return 0;
}
/*
* Flush buffered data to the file.
*
* Frank Warmerdam'2000: I modified this to return 1 if TIFF_BEENWRITING
* is not set, so that TIFFFlush() will proceed to write out the directory.
* The documentation says returning 1 is an error indicator, but not having
* been writing isn't exactly a an error. Hopefully this doesn't cause
* problems for other people.
*/
int TIFFFlushData(TIFF *tif)
{
if ((tif->tif_flags & TIFF_BEENWRITING) == 0)
return (1);
if (tif->tif_flags & TIFF_POSTENCODE)
{
tif->tif_flags &= ~TIFF_POSTENCODE;
if (!(*tif->tif_postencode)(tif))
return (0);
}
return (TIFFFlushData1(tif));
}
+3535
View File
File diff suppressed because it is too large Load Diff
+603
View File
@@ -0,0 +1,603 @@
/**********************************************************************
*
* Name: tif_hash_set.c
* Purpose: Hash set functions.
* Author: Even Rouault, <even dot rouault at spatialys.com>
*
**********************************************************************
* Copyright (c) 2008-2009, Even Rouault <even dot rouault at spatialys.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
****************************************************************************/
#include "tif_config.h"
#include "tif_hash_set.h"
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
/** List element structure. */
typedef struct _TIFFList TIFFList;
/** List element structure. */
struct _TIFFList
{
/*! Pointer to the data object. Should be allocated and freed by the
* caller.
* */
void *pData;
/*! Pointer to the next element in list. NULL, if current element is the
* last one.
*/
struct _TIFFList *psNext;
};
struct _TIFFHashSet
{
TIFFHashSetHashFunc fnHashFunc;
TIFFHashSetEqualFunc fnEqualFunc;
TIFFHashSetFreeEltFunc fnFreeEltFunc;
TIFFList **tabList;
int nSize;
int nIndiceAllocatedSize;
int nAllocatedSize;
TIFFList *psRecyclingList;
int nRecyclingListSize;
bool bRehash;
#ifdef HASH_DEBUG
int nCollisions;
#endif
};
static const int anPrimes[] = {
53, 97, 193, 389, 769, 1543, 3079,
6151, 12289, 24593, 49157, 98317, 196613, 393241,
786433, 1572869, 3145739, 6291469, 12582917, 25165843, 50331653,
100663319, 201326611, 402653189, 805306457, 1610612741};
/************************************************************************/
/* TIFFHashSetHashPointer() */
/************************************************************************/
/**
* Hash function for an arbitrary pointer
*
* @param elt the arbitrary pointer to hash
*
* @return the hash value of the pointer
*/
static unsigned long TIFFHashSetHashPointer(const void *elt)
{
return (unsigned long)(uintptr_t)((void *)(elt));
}
/************************************************************************/
/* TIFFHashSetEqualPointer() */
/************************************************************************/
/**
* Equality function for arbitrary pointers
*
* @param elt1 the first arbitrary pointer to compare
* @param elt2 the second arbitrary pointer to compare
*
* @return true if the pointers are equal
*/
static bool TIFFHashSetEqualPointer(const void *elt1, const void *elt2)
{
return elt1 == elt2;
}
/************************************************************************/
/* TIFFHashSetNew() */
/************************************************************************/
/**
* Creates a new hash set
*
* The hash function must return a hash value for the elements to insert.
* If fnHashFunc is NULL, TIFFHashSetHashPointer will be used.
*
* The equal function must return if two elements are equal.
* If fnEqualFunc is NULL, TIFFHashSetEqualPointer will be used.
*
* The free function is used to free elements inserted in the hash set,
* when the hash set is destroyed, when elements are removed or replaced.
* If fnFreeEltFunc is NULL, elements inserted into the hash set will not be
* freed.
*
* @param fnHashFunc hash function. May be NULL.
* @param fnEqualFunc equal function. May be NULL.
* @param fnFreeEltFunc element free function. May be NULL.
*
* @return a new hash set
*/
TIFFHashSet *TIFFHashSetNew(TIFFHashSetHashFunc fnHashFunc,
TIFFHashSetEqualFunc fnEqualFunc,
TIFFHashSetFreeEltFunc fnFreeEltFunc)
{
TIFFHashSet *set = (TIFFHashSet *)malloc(sizeof(TIFFHashSet));
if (set == NULL)
return NULL;
set->fnHashFunc = fnHashFunc ? fnHashFunc : TIFFHashSetHashPointer;
set->fnEqualFunc = fnEqualFunc ? fnEqualFunc : TIFFHashSetEqualPointer;
set->fnFreeEltFunc = fnFreeEltFunc;
set->nSize = 0;
set->tabList = (TIFFList **)(calloc(53, sizeof(TIFFList *)));
if (set->tabList == NULL)
{
free(set);
return NULL;
}
set->nIndiceAllocatedSize = 0;
set->nAllocatedSize = 53;
set->psRecyclingList = NULL;
set->nRecyclingListSize = 0;
set->bRehash = false;
#ifdef HASH_DEBUG
set->nCollisions = 0;
#endif
return set;
}
/************************************************************************/
/* TIFFHashSetSize() */
/************************************************************************/
/**
* Returns the number of elements inserted in the hash set
*
* Note: this is not the internal size of the hash set
*
* @param set the hash set
*
* @return the number of elements in the hash set
*/
int TIFFHashSetSize(const TIFFHashSet *set)
{
assert(set != NULL);
return set->nSize;
}
/************************************************************************/
/* TIFFHashSetGetNewListElt() */
/************************************************************************/
static TIFFList *TIFFHashSetGetNewListElt(TIFFHashSet *set)
{
if (set->psRecyclingList)
{
TIFFList *psRet = set->psRecyclingList;
psRet->pData = NULL;
set->nRecyclingListSize--;
set->psRecyclingList = psRet->psNext;
return psRet;
}
return (TIFFList *)malloc(sizeof(TIFFList));
}
/************************************************************************/
/* TIFFHashSetReturnListElt() */
/************************************************************************/
static void TIFFHashSetReturnListElt(TIFFHashSet *set, TIFFList *psList)
{
if (set->nRecyclingListSize < 128)
{
psList->psNext = set->psRecyclingList;
set->psRecyclingList = psList;
set->nRecyclingListSize++;
}
else
{
free(psList);
}
}
/************************************************************************/
/* TIFFHashSetClearInternal() */
/************************************************************************/
static void TIFFHashSetClearInternal(TIFFHashSet *set, bool bFinalize)
{
assert(set != NULL);
for (int i = 0; i < set->nAllocatedSize; i++)
{
TIFFList *cur = set->tabList[i];
while (cur)
{
if (set->fnFreeEltFunc)
set->fnFreeEltFunc(cur->pData);
TIFFList *psNext = cur->psNext;
if (bFinalize)
free(cur);
else
TIFFHashSetReturnListElt(set, cur);
cur = psNext;
}
set->tabList[i] = NULL;
}
set->bRehash = false;
}
/************************************************************************/
/* TIFFListDestroy() */
/************************************************************************/
/**
* Destroy a list. Caller responsible for freeing data objects contained in
* list elements.
*
* @param psList pointer to list head.
*
*/
static void TIFFListDestroy(TIFFList *psList)
{
TIFFList *psCurrent = psList;
while (psCurrent)
{
TIFFList *const psNext = psCurrent->psNext;
free(psCurrent);
psCurrent = psNext;
}
}
/************************************************************************/
/* TIFFHashSetDestroy() */
/************************************************************************/
/**
* Destroys an allocated hash set.
*
* This function also frees the elements if a free function was
* provided at the creation of the hash set.
*
* @param set the hash set
*/
void TIFFHashSetDestroy(TIFFHashSet *set)
{
if (set)
{
TIFFHashSetClearInternal(set, true);
free(set->tabList);
TIFFListDestroy(set->psRecyclingList);
free(set);
}
}
#ifdef notused
/************************************************************************/
/* TIFFHashSetClear() */
/************************************************************************/
/**
* Clear all elements from a hash set.
*
* This function also frees the elements if a free function was
* provided at the creation of the hash set.
*
* @param set the hash set
*/
void TIFFHashSetClear(TIFFHashSet *set)
{
TIFFHashSetClearInternal(set, false);
set->nIndiceAllocatedSize = 0;
set->nAllocatedSize = 53;
#ifdef HASH_DEBUG
set->nCollisions = 0;
#endif
set->nSize = 0;
}
/************************************************************************/
/* TIFFHashSetForeach() */
/************************************************************************/
/**
* Walk through the hash set and runs the provided function on all the
* elements
*
* This function is provided the user_data argument of TIFFHashSetForeach.
* It must return true to go on the walk through the hash set, or FALSE to
* make it stop.
*
* Note : the structure of the hash set must *NOT* be modified during the
* walk.
*
* @param set the hash set.
* @param fnIterFunc the function called on each element.
* @param user_data the user data provided to the function.
*/
void TIFFHashSetForeach(TIFFHashSet *set, TIFFHashSetIterEltFunc fnIterFunc,
void *user_data)
{
assert(set != NULL);
if (!fnIterFunc)
return;
for (int i = 0; i < set->nAllocatedSize; i++)
{
TIFFList *cur = set->tabList[i];
while (cur)
{
if (!fnIterFunc(cur->pData, user_data))
return;
cur = cur->psNext;
}
}
}
#endif
/************************************************************************/
/* TIFFHashSetRehash() */
/************************************************************************/
static bool TIFFHashSetRehash(TIFFHashSet *set)
{
int nNewAllocatedSize = anPrimes[set->nIndiceAllocatedSize];
TIFFList **newTabList =
(TIFFList **)(calloc(nNewAllocatedSize, sizeof(TIFFList *)));
if (newTabList == NULL)
return false;
#ifdef HASH_DEBUG
TIFFDebug("TIFFHASH",
"hashSet=%p, nSize=%d, nCollisions=%d, "
"fCollisionRate=%.02f",
set, set->nSize, set->nCollisions,
set->nCollisions * 100.0 / set->nSize);
set->nCollisions = 0;
#endif
for (int i = 0; i < set->nAllocatedSize; i++)
{
TIFFList *cur = set->tabList[i];
while (cur)
{
const unsigned long nNewHashVal =
set->fnHashFunc(cur->pData) % nNewAllocatedSize;
#ifdef HASH_DEBUG
if (newTabList[nNewHashVal])
set->nCollisions++;
#endif
TIFFList *psNext = cur->psNext;
cur->psNext = newTabList[nNewHashVal];
newTabList[nNewHashVal] = cur;
cur = psNext;
}
}
free(set->tabList);
set->tabList = newTabList;
set->nAllocatedSize = nNewAllocatedSize;
set->bRehash = false;
return true;
}
/************************************************************************/
/* TIFFHashSetFindPtr() */
/************************************************************************/
static void **TIFFHashSetFindPtr(TIFFHashSet *set, const void *elt)
{
const unsigned long nHashVal = set->fnHashFunc(elt) % set->nAllocatedSize;
TIFFList *cur = set->tabList[nHashVal];
while (cur)
{
if (set->fnEqualFunc(cur->pData, elt))
return &cur->pData;
cur = cur->psNext;
}
return NULL;
}
/************************************************************************/
/* TIFFHashSetInsert() */
/************************************************************************/
/**
* Inserts an element into a hash set.
*
* If the element was already inserted in the hash set, the previous
* element is replaced by the new element. If a free function was provided,
* it is used to free the previously inserted element
*
* @param set the hash set
* @param elt the new element to insert in the hash set
*
* @return true if success. If false is returned, elt has not been inserted,
* but TIFFHashSetInsert() will have run the free function if provided.
*/
bool TIFFHashSetInsert(TIFFHashSet *set, void *elt)
{
assert(set != NULL);
void **pElt = TIFFHashSetFindPtr(set, elt);
if (pElt)
{
if (set->fnFreeEltFunc)
set->fnFreeEltFunc(*pElt);
*pElt = elt;
return true;
}
if (set->nSize >= 2 * set->nAllocatedSize / 3 ||
(set->bRehash && set->nIndiceAllocatedSize > 0 &&
set->nSize <= set->nAllocatedSize / 2))
{
set->nIndiceAllocatedSize++;
if (!TIFFHashSetRehash(set))
{
set->nIndiceAllocatedSize--;
if (set->fnFreeEltFunc)
set->fnFreeEltFunc(elt);
return false;
}
}
const unsigned long nHashVal = set->fnHashFunc(elt) % set->nAllocatedSize;
#ifdef HASH_DEBUG
if (set->tabList[nHashVal])
set->nCollisions++;
#endif
TIFFList *new_elt = TIFFHashSetGetNewListElt(set);
if (new_elt == NULL)
{
if (set->fnFreeEltFunc)
set->fnFreeEltFunc(elt);
return false;
}
new_elt->pData = elt;
new_elt->psNext = set->tabList[nHashVal];
set->tabList[nHashVal] = new_elt;
set->nSize++;
return true;
}
/************************************************************************/
/* TIFFHashSetLookup() */
/************************************************************************/
/**
* Returns the element found in the hash set corresponding to the element to
* look up The element must not be modified.
*
* @param set the hash set
* @param elt the element to look up in the hash set
*
* @return the element found in the hash set or NULL
*/
void *TIFFHashSetLookup(TIFFHashSet *set, const void *elt)
{
assert(set != NULL);
void **pElt = TIFFHashSetFindPtr(set, elt);
if (pElt)
return *pElt;
return NULL;
}
/************************************************************************/
/* TIFFHashSetRemoveInternal() */
/************************************************************************/
static bool TIFFHashSetRemoveInternal(TIFFHashSet *set, const void *elt,
bool bDeferRehash)
{
assert(set != NULL);
if (set->nIndiceAllocatedSize > 0 && set->nSize <= set->nAllocatedSize / 2)
{
set->nIndiceAllocatedSize--;
if (bDeferRehash)
set->bRehash = true;
else
{
if (!TIFFHashSetRehash(set))
{
set->nIndiceAllocatedSize++;
return false;
}
}
}
int nHashVal = (int)(set->fnHashFunc(elt) % set->nAllocatedSize);
TIFFList *cur = set->tabList[nHashVal];
TIFFList *prev = NULL;
while (cur)
{
if (set->fnEqualFunc(cur->pData, elt))
{
if (prev)
prev->psNext = cur->psNext;
else
set->tabList[nHashVal] = cur->psNext;
if (set->fnFreeEltFunc)
set->fnFreeEltFunc(cur->pData);
TIFFHashSetReturnListElt(set, cur);
#ifdef HASH_DEBUG
if (set->tabList[nHashVal])
set->nCollisions--;
#endif
set->nSize--;
return true;
}
prev = cur;
cur = cur->psNext;
}
return false;
}
/************************************************************************/
/* TIFFHashSetRemove() */
/************************************************************************/
/**
* Removes an element from a hash set
*
* @param set the hash set
* @param elt the new element to remove from the hash set
*
* @return true if the element was in the hash set
*/
bool TIFFHashSetRemove(TIFFHashSet *set, const void *elt)
{
return TIFFHashSetRemoveInternal(set, elt, false);
}
#ifdef notused
/************************************************************************/
/* TIFFHashSetRemoveDeferRehash() */
/************************************************************************/
/**
* Removes an element from a hash set.
*
* This will defer potential rehashing of the set to later calls to
* TIFFHashSetInsert() or TIFFHashSetRemove().
*
* @param set the hash set
* @param elt the new element to remove from the hash set
*
* @return true if the element was in the hash set
*/
bool TIFFHashSetRemoveDeferRehash(TIFFHashSet *set, const void *elt)
{
return TIFFHashSetRemoveInternal(set, elt, true);
}
#endif
+100
View File
@@ -0,0 +1,100 @@
/**********************************************************************
* $Id$
*
* Name: tif_hash_set.h
* Project: TIFF - Common Portability Library
* Purpose: Hash set functions.
* Author: Even Rouault, <even dot rouault at spatialys.com>
*
**********************************************************************
* Copyright (c) 2008-2009, Even Rouault <even dot rouault at spatialys.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
****************************************************************************/
#ifndef TIFF_HASH_SET_H_INCLUDED
#define TIFF_HASH_SET_H_INCLUDED
#include <stdbool.h>
/**
* \file tif_hash_set.h
*
* Hash set implementation.
*
* An hash set is a data structure that holds elements that are unique
* according to a comparison function. Operations on the hash set, such as
* insertion, removal or lookup, are supposed to be fast if an efficient
* "hash" function is provided.
*/
#ifdef __cplusplus
extern "C"
{
#endif
/* Types */
/** Opaque type for a hash set */
typedef struct _TIFFHashSet TIFFHashSet;
/** TIFFHashSetHashFunc */
typedef unsigned long (*TIFFHashSetHashFunc)(const void *elt);
/** TIFFHashSetEqualFunc */
typedef bool (*TIFFHashSetEqualFunc)(const void *elt1, const void *elt2);
/** TIFFHashSetFreeEltFunc */
typedef void (*TIFFHashSetFreeEltFunc)(void *elt);
/* Functions */
TIFFHashSet *TIFFHashSetNew(TIFFHashSetHashFunc fnHashFunc,
TIFFHashSetEqualFunc fnEqualFunc,
TIFFHashSetFreeEltFunc fnFreeEltFunc);
void TIFFHashSetDestroy(TIFFHashSet *set);
int TIFFHashSetSize(const TIFFHashSet *set);
#ifdef notused
void TIFFHashSetClear(TIFFHashSet *set);
/** TIFFHashSetIterEltFunc */
typedef int (*TIFFHashSetIterEltFunc)(void *elt, void *user_data);
void TIFFHashSetForeach(TIFFHashSet *set, TIFFHashSetIterEltFunc fnIterFunc,
void *user_data);
#endif
bool TIFFHashSetInsert(TIFFHashSet *set, void *elt);
void *TIFFHashSetLookup(TIFFHashSet *set, const void *elt);
bool TIFFHashSetRemove(TIFFHashSet *set, const void *elt);
#ifdef notused
bool TIFFHashSetRemoveDeferRehash(TIFFHashSet *set, const void *elt);
#endif
#ifdef __cplusplus
}
#endif
#endif /* TIFF_HASH_SET_H_INCLUDED */
+233
View File
@@ -0,0 +1,233 @@
/*
* 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.
*
* JBIG Compression Algorithm Support.
* Contributed by Lee Howard <faxguy@deanox.com>
*
*/
#include "tiffiop.h"
#ifdef JBIG_SUPPORT
#include "jbig.h"
static int JBIGSetupDecode(TIFF *tif)
{
if (TIFFNumberOfStrips(tif) != 1)
{
TIFFErrorExtR(tif, "JBIG",
"Multistrip images not supported in decoder");
return 0;
}
return 1;
}
static int JBIGDecode(TIFF *tif, uint8_t *buffer, tmsize_t size, uint16_t s)
{
struct jbg_dec_state decoder;
int decodeStatus = 0;
unsigned char *pImage = NULL;
unsigned long decodedSize;
(void)s;
if (isFillOrder(tif, tif->tif_dir.td_fillorder))
{
TIFFReverseBits(tif->tif_rawcp, tif->tif_rawcc);
}
jbg_dec_init(&decoder);
#if defined(HAVE_JBG_NEWLEN)
jbg_newlen(tif->tif_rawcp, (size_t)tif->tif_rawcc);
/*
* I do not check the return status of jbg_newlen because even if this
* function fails it does not necessarily mean that decoding the image
* 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, (unsigned char *)tif->tif_rawcp,
(size_t)tif->tif_rawcc, 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.
*/
TIFFErrorExtR(tif, "JBIG", "Error (%d) decoding: %s", decodeStatus,
#if defined(JBG_EN)
jbg_strerror(decodeStatus, JBG_EN)
#else
jbg_strerror(decodeStatus)
#endif
);
memset(buffer, 0, (size_t)size);
jbg_dec_free(&decoder);
return 0;
}
decodedSize = jbg_dec_getsize(&decoder);
if ((tmsize_t)decodedSize < size)
{
memset(buffer + decodedSize, 0, (size_t)(size - decodedSize));
TIFFWarningExtR(tif, "JBIG",
"Only decoded %lu bytes, whereas %" TIFF_SSIZE_FORMAT
" requested",
decodedSize, size);
}
else if ((tmsize_t)decodedSize > size)
{
TIFFErrorExtR(tif, "JBIG",
"Decoded %lu bytes, whereas %" TIFF_SSIZE_FORMAT
" were requested",
decodedSize, size);
jbg_dec_free(&decoder);
return 0;
}
pImage = jbg_dec_getimage(&decoder, 0);
_TIFFmemcpy(buffer, pImage, decodedSize);
jbg_dec_free(&decoder);
tif->tif_rawcp += tif->tif_rawcc;
tif->tif_rawcc = 0;
return 1;
}
static int JBIGSetupEncode(TIFF *tif)
{
if (TIFFNumberOfStrips(tif) != 1)
{
TIFFErrorExtR(tif, "JBIG",
"Multistrip images not supported in encoder");
return 0;
}
return 1;
}
static int JBIGCopyEncodedData(TIFF *tif, unsigned char *pp, size_t cc,
uint16_t 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);
}
}
return (1);
}
static void JBIGOutputBie(unsigned char *buffer, size_t len, void *userData)
{
TIFF *tif = (TIFF *)userData;
if (isFillOrder(tif, tif->tif_dir.td_fillorder))
{
TIFFReverseBits(buffer, (tmsize_t)len);
}
JBIGCopyEncodedData(tif, buffer, len, 0);
}
static int JBIGEncode(TIFF *tif, uint8_t *buffer, tmsize_t size, uint16_t s)
{
TIFFDirectory *dir = &tif->tif_dir;
struct jbg_enc_state encoder;
(void)size, (void)s;
jbg_enc_init(&encoder, dir->td_imagewidth, dir->td_imagelength, 1, &buffer,
JBIGOutputBie, tif);
/*
* jbg_enc_out does the "real" encoding. As data is encoded,
* JBIGOutputBie is called, which writes the data to the directory.
*/
jbg_enc_out(&encoder);
jbg_enc_free(&encoder);
return 1;
}
int TIFFInitJBIG(TIFF *tif, int scheme)
{
(void)scheme;
assert(scheme == COMPRESSION_JBIG);
/*
* 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;
/* We may have read from a previous IFD and thus set TIFF_BUFFERMMAP and
* cleared TIFF_MYBUFFER. It is necessary to restore them to their initial
* value to be consistent with the state of a non-memory mapped file.
*/
if (tif->tif_flags & TIFF_BUFFERMMAP)
{
tif->tif_rawdata = NULL;
tif->tif_rawdatasize = 0;
tif->tif_flags &= ~TIFF_BUFFERMMAP;
tif->tif_flags |= TIFF_MYBUFFER;
}
/* 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 */
+2916
View File
File diff suppressed because it is too large Load Diff
+63
View File
@@ -0,0 +1,63 @@
#include "tiffiop.h"
#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12)
#define JPEG_DUAL_MODE_8_12
#endif
#if defined(JPEG_DUAL_MODE_8_12)
#define FROM_TIF_JPEG_12
#ifdef TIFFInitJPEG
#undef TIFFInitJPEG
#endif
#define TIFFInitJPEG TIFFInitJPEG_12
#ifdef TIFFJPEGIsFullStripRequired
#undef TIFFJPEGIsFullStripRequired
#endif
#define TIFFJPEGIsFullStripRequired TIFFJPEGIsFullStripRequired_12
int TIFFInitJPEG_12(TIFF *tif, int scheme);
#if !defined(HAVE_JPEGTURBO_DUAL_MODE_8_12)
#include LIBJPEG_12_PATH
#endif
#include "tif_jpeg.c"
int TIFFReInitJPEG_12(TIFF *tif, const JPEGOtherSettings *otherSettings,
int scheme, int is_encode)
{
JPEGState *sp;
uint8_t *new_tif_data;
(void)scheme;
assert(scheme == COMPRESSION_JPEG);
new_tif_data =
(uint8_t *)_TIFFreallocExt(tif, tif->tif_data, sizeof(JPEGState));
if (new_tif_data == NULL)
{
TIFFErrorExtR(tif, "TIFFReInitJPEG_12",
"No space for JPEG state block");
return 0;
}
tif->tif_data = new_tif_data;
_TIFFmemset(tif->tif_data, 0, sizeof(JPEGState));
TIFFInitJPEGCommon(tif);
sp = JState(tif);
sp->otherSettings = *otherSettings;
if (is_encode)
return JPEGSetupEncode(tif);
else
return JPEGSetupDecode(tif);
}
#endif /* defined(JPEG_DUAL_MODE_8_12) */
+1545
View File
File diff suppressed because it is too large Load Diff
+1855
View File
File diff suppressed because it is too large Load Diff
+541
View File
@@ -0,0 +1,541 @@
/*
* 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 "lzma.h"
#include "tif_predict.h"
#include <stdio.h>
/*
* State block for each open TIFF file using LZMA2 compression/decompression.
*/
typedef struct
{
TIFFPredictorState predict;
int read_error; /* whether a read error has occurred, and which should cause
further reads in the same strip/tile to be aborted */
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 GetLZMAState(tif) ((LZMAState *)(tif)->tif_data)
#define LZMADecoderState(tif) GetLZMAState(tif)
#define LZMAEncoderState(tif) GetLZMAState(tif)
static int LZMAEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t 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 "unidentified liblzma error";
}
}
static int LZMAFixupTags(TIFF *tif)
{
(void)tif;
return 1;
}
static int LZMASetupDecode(TIFF *tif)
{
LZMAState *sp = LZMADecoderState(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_t s)
{
static const char module[] = "LZMAPreDecode";
LZMAState *sp = LZMADecoderState(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)
{
TIFFErrorExtR(tif, 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)
{
TIFFErrorExtR(tif, module, "Error initializing the stream decoder, %s",
LZMAStrerror(ret));
return 0;
}
sp->read_error = 0;
return 1;
}
static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
{
static const char module[] = "LZMADecode";
LZMAState *sp = LZMADecoderState(tif);
(void)s;
assert(sp != NULL);
assert(sp->state == LSTATE_INIT_DECODE);
if (sp->read_error)
{
memset(op, 0, (size_t)occ);
TIFFErrorExtR(tif, module,
"LZMADecode: Scanline %" PRIu32 " cannot be read due to "
"previous error",
tif->tif_row);
return 0;
}
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)
{
// read_error not set here as this is a usage issue that can be
// recovered in a following call.
memset(op, 0, (size_t)occ);
TIFFErrorExtR(tif, 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)
{
sp->read_error = 1;
memset(op, 0, (size_t)occ);
TIFFErrorExtR(tif, 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)
{
TIFFErrorExtR(tif, module,
"Decoding error at scanline %" PRIu32 ", %s",
tif->tif_row, LZMAStrerror(ret));
break;
}
} while (sp->stream.avail_out > 0);
if (sp->stream.avail_out != 0)
{
sp->read_error = 1;
memset(sp->stream.next_out, 0, sp->stream.avail_out);
TIFFErrorExtR(tif, module,
"Not enough data at scanline %" PRIu32
" (short %" TIFF_SIZE_FORMAT " bytes)",
tif->tif_row, sp->stream.avail_out);
return 0;
}
tif->tif_rawcp = (uint8_t *)sp->stream.next_in; /* cast away const */
tif->tif_rawcc = sp->stream.avail_in;
return 1;
}
static int LZMASetupEncode(TIFF *tif)
{
LZMAState *sp = LZMAEncoderState(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_t s)
{
static const char module[] = "LZMAPreEncode";
LZMAState *sp = LZMAEncoderState(tif);
lzma_ret ret;
(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)
{
TIFFErrorExtR(tif, module,
"Liblzma cannot deal with buffers this size");
return 0;
}
ret = lzma_stream_encoder(&sp->stream, sp->filters, sp->check);
if (ret != LZMA_OK)
{
TIFFErrorExtR(tif, module, "Error in lzma_stream_encoder(): %s",
LZMAStrerror(ret));
return 0;
}
return 1;
}
/*
* Encode a chunk of pixels.
*/
static int LZMAEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
{
static const char module[] = "LZMAEncode";
LZMAState *sp = LZMAEncoderState(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)
{
TIFFErrorExtR(tif, module,
"Liblzma cannot deal with buffers this size");
return 0;
}
do
{
lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN);
if (ret != LZMA_OK)
{
TIFFErrorExtR(tif, module,
"Encoding error at scanline %" PRIu32 ", %s",
tif->tif_row, LZMAStrerror(ret));
return 0;
}
if (sp->stream.avail_out == 0)
{
tif->tif_rawcc = tif->tif_rawdatasize;
if (!TIFFFlushData1(tif))
return 0;
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 = LZMAEncoderState(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;
if (!TIFFFlushData1(tif))
return 0;
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:
TIFFErrorExtR(tif, module, "Liblzma error: %s",
LZMAStrerror(ret));
return 0;
}
} while (ret != LZMA_STREAM_END);
return 1;
}
static void LZMACleanup(TIFF *tif)
{
LZMAState *sp = GetLZMAState(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;
}
_TIFFfreeExt(tif, sp);
tif->tif_data = NULL;
_TIFFSetDefaultCompressionState(tif);
}
static int LZMAVSetField(TIFF *tif, uint32_t tag, va_list ap)
{
static const char module[] = "LZMAVSetField";
LZMAState *sp = GetLZMAState(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)
{
TIFFErrorExtR(tif, module, "Liblzma error: %s",
LZMAStrerror(ret));
}
}
return 1;
default:
return (*sp->vsetparent)(tif, tag, ap);
}
/*NOTREACHED*/
}
static int LZMAVGetField(TIFF *tif, uint32_t tag, va_list ap)
{
LZMAState *sp = GetLZMAState(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, 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;
(void)scheme;
assert(scheme == COMPRESSION_LZMA);
/*
* Merge codec-specific tag information.
*/
if (!_TIFFMergeFields(tif, lzmaFields, TIFFArrayCount(lzmaFields)))
{
TIFFErrorExtR(tif, module, "Merging LZMA2 codec-specific tags failed");
return 0;
}
/*
* Allocate state block so tag methods have storage to record values.
*/
tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(LZMAState));
if (tif->tif_data == NULL)
goto bad;
sp = GetLZMAState(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:
TIFFErrorExtR(tif, module, "No space for LZMA2 state block");
return 0;
}
#endif /* LZMA_SUPPORT */
+1464
View File
File diff suppressed because it is too large Load Diff
+194
View File
@@ -0,0 +1,194 @@
/*
* Copyright (c) 1988-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "tiffiop.h"
#ifdef NEXT_SUPPORT
/*
* TIFF Library.
*
* NeXT 2-bit Grey Scale Compression Algorithm Support
*/
#define SETPIXEL(op, v) \
{ \
switch (npixels++ & 3) \
{ \
case 0: \
op[0] = (unsigned char)((v) << 6); \
break; \
case 1: \
op[0] |= (v) << 4; \
break; \
case 2: \
op[0] |= (v) << 2; \
break; \
case 3: \
*op++ |= (v); \
op_offset++; \
break; \
} \
}
#define LITERALROW 0x00
#define LITERALSPAN 0x40
#define WHITE ((1 << 2) - 1)
static int NeXTDecode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
{
static const char module[] = "NeXTDecode";
unsigned char *bp, *op;
tmsize_t cc;
uint8_t *row;
tmsize_t scanline, n;
(void)s;
/*
* Each scanline is assumed to start off as all
* white (we assume a PhotometricInterpretation
* of ``min-is-black'').
*/
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)
{
TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
return (0);
}
for (row = buf; cc > 0 && occ > 0; occ -= scanline, row += scanline)
{
n = *bp++;
cc--;
switch (n)
{
case LITERALROW:
/*
* The entire scanline is given as literal values.
*/
if (cc < scanline)
goto bad;
_TIFFmemcpy(row, bp, scanline);
bp += scanline;
cc -= scanline;
break;
case LITERALSPAN:
{
tmsize_t off;
/*
* The scanline has a literal span that begins at some
* offset.
*/
if (cc < 4)
goto bad;
off = (bp[0] * 256) + bp[1];
n = (bp[2] * 256) + bp[3];
if (cc < 4 + n || off + n > scanline)
goto bad;
_TIFFmemcpy(row + off, bp + 4, n);
bp += 4 + n;
cc -= 4 + n;
break;
}
default:
{
uint32_t npixels = 0, grey;
tmsize_t op_offset = 0;
uint32_t imagewidth = tif->tif_dir.td_imagewidth;
if (isTiled(tif))
imagewidth = tif->tif_dir.td_tilewidth;
/*
* The scanline is composed of a sequence of constant
* color ``runs''. We shift into ``run mode'' and
* interpret bytes as codes of the form
* <color><npixels> until we've filled the scanline.
*/
op = row;
for (;;)
{
grey = (uint32_t)((n >> 6) & 0x3);
n &= 0x3f;
/*
* Ensure the run does not exceed the scanline
* bounds, potentially resulting in a security
* issue.
*/
while (n-- > 0 && npixels < imagewidth &&
op_offset < scanline)
SETPIXEL(op, grey);
if (npixels >= imagewidth)
break;
if (op_offset >= scanline)
{
TIFFErrorExtR(tif, module,
"Invalid data for scanline %" PRIu32,
tif->tif_row);
return (0);
}
if (cc == 0)
goto bad;
n = *bp++;
cc--;
}
break;
}
}
}
tif->tif_rawcp = (uint8_t *)bp;
tif->tif_rawcc = cc;
return (1);
bad:
TIFFErrorExtR(tif, module, "Not enough data for scanline %" PRIu32,
tif->tif_row);
return (0);
}
static int NeXTPreDecode(TIFF *tif, uint16_t s)
{
static const char module[] = "NeXTPreDecode";
TIFFDirectory *td = &tif->tif_dir;
(void)s;
if (td->td_bitspersample != 2)
{
TIFFErrorExtR(tif, module, "Unsupported BitsPerSample = %" PRIu16,
td->td_bitspersample);
return (0);
}
return (1);
}
int TIFFInitNeXT(TIFF *tif, int scheme)
{
(void)scheme;
tif->tif_predecode = NeXTPreDecode;
tif->tif_decoderow = NeXTDecode;
tif->tif_decodestrip = NeXTDecode;
tif->tif_decodetile = NeXTDecode;
return (1);
}
#endif /* NEXT_SUPPORT */
+2810
View File
File diff suppressed because it is too large Load Diff
+945
View File
@@ -0,0 +1,945 @@
/*
* 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.
*/
#ifdef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
#undef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
#endif
#include "tiffiop.h"
#include <assert.h>
#include <limits.h>
/*
* Dummy functions to fill the omitted client procedures.
*/
int _tiffDummyMapProc(thandle_t fd, void **pbase, toff_t *psize)
{
(void)fd;
(void)pbase;
(void)psize;
return (0);
}
void _tiffDummyUnmapProc(thandle_t fd, void *base, toff_t size)
{
(void)fd;
(void)base;
(void)size;
}
int _TIFFgetMode(TIFFOpenOptions *opts, thandle_t clientdata, const char *mode,
const char *module)
{
int m = -1;
switch (mode[0])
{
case 'r':
m = O_RDONLY;
if (mode[1] == '+')
m = O_RDWR;
break;
case 'w':
case 'a':
m = O_RDWR | O_CREAT;
if (mode[0] == 'w')
m |= O_TRUNC;
break;
default:
_TIFFErrorEarly(opts, clientdata, module, "\"%s\": Bad mode", mode);
break;
}
return (m);
}
TIFFOpenOptions *TIFFOpenOptionsAlloc()
{
TIFFOpenOptions *opts =
(TIFFOpenOptions *)_TIFFcalloc(1, sizeof(TIFFOpenOptions));
return opts;
}
void TIFFOpenOptionsFree(TIFFOpenOptions *opts) { _TIFFfree(opts); }
/** Define a limit in bytes for a single memory allocation done by libtiff.
* If max_single_mem_alloc is set to 0, which is the default, no other limit
* that the underlying _TIFFmalloc() or
* TIFFOpenOptionsSetMaxCumulatedMemAlloc() will be applied.
*/
void TIFFOpenOptionsSetMaxSingleMemAlloc(TIFFOpenOptions *opts,
tmsize_t max_single_mem_alloc)
{
opts->max_single_mem_alloc = max_single_mem_alloc;
}
/** Define a limit in bytes for the cumulated memory allocations done by libtiff
* on a given TIFF handle.
* If max_cumulated_mem_alloc is set to 0, which is the default, no other limit
* that the underlying _TIFFmalloc() or
* TIFFOpenOptionsSetMaxSingleMemAlloc() will be applied.
*/
void TIFFOpenOptionsSetMaxCumulatedMemAlloc(TIFFOpenOptions *opts,
tmsize_t max_cumulated_mem_alloc)
{
opts->max_cumulated_mem_alloc = max_cumulated_mem_alloc;
}
/** Whether a warning should be emitted when encountering a unknown tag.
* Default is FALSE since libtiff 4.7.1
*/
void TIFFOpenOptionsSetWarnAboutUnknownTags(TIFFOpenOptions *opts,
int warn_about_unknown_tags)
{
opts->warn_about_unknown_tags = warn_about_unknown_tags;
}
void TIFFOpenOptionsSetErrorHandlerExtR(TIFFOpenOptions *opts,
TIFFErrorHandlerExtR handler,
void *errorhandler_user_data)
{
opts->errorhandler = handler;
opts->errorhandler_user_data = errorhandler_user_data;
}
void TIFFOpenOptionsSetWarningHandlerExtR(TIFFOpenOptions *opts,
TIFFErrorHandlerExtR handler,
void *warnhandler_user_data)
{
opts->warnhandler = handler;
opts->warnhandler_user_data = warnhandler_user_data;
}
static void _TIFFEmitErrorAboveMaxSingleMemAlloc(TIFF *tif,
const char *pszFunction,
tmsize_t s)
{
TIFFErrorExtR(tif, pszFunction,
"Memory allocation of %" PRIu64
" bytes is beyond the %" PRIu64
" byte limit defined in open options",
(uint64_t)s, (uint64_t)tif->tif_max_single_mem_alloc);
}
static void _TIFFEmitErrorAboveMaxCumulatedMemAlloc(TIFF *tif,
const char *pszFunction,
tmsize_t s)
{
TIFFErrorExtR(tif, pszFunction,
"Cumulated memory allocation of %" PRIu64 " + %" PRIu64
" bytes is beyond the %" PRIu64
" cumulated byte limit defined in open options",
(uint64_t)tif->tif_cur_cumulated_mem_alloc, (uint64_t)s,
(uint64_t)tif->tif_max_cumulated_mem_alloc);
}
/* When allocating memory, we write at the beginning of the buffer it size.
* This allows us to keep track of the total memory allocated when we
* malloc/calloc/realloc and free. In theory we need just SIZEOF_SIZE_T bytes
* for that, but on x86_64, allocations of more than 16 bytes are aligned on
* 16 bytes. Hence using 2 * SIZEOF_SIZE_T.
* It is critical that _TIFFmallocExt/_TIFFcallocExt/_TIFFreallocExt are
* paired with _TIFFfreeExt.
* CMakeLists.txt defines TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS, which in
* turn disables the definition of the non Ext version in tiffio.h
*/
#define LEADING_AREA_TO_STORE_ALLOC_SIZE (2 * SIZEOF_SIZE_T)
/** malloc() version that takes into account memory-specific open options */
void *_TIFFmallocExt(TIFF *tif, tmsize_t s)
{
if (tif != NULL && tif->tif_max_single_mem_alloc > 0 &&
s > tif->tif_max_single_mem_alloc)
{
_TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFmallocExt", s);
return NULL;
}
if (tif != NULL && tif->tif_max_cumulated_mem_alloc > 0)
{
if (s > tif->tif_max_cumulated_mem_alloc -
tif->tif_cur_cumulated_mem_alloc ||
s > TIFF_TMSIZE_T_MAX - LEADING_AREA_TO_STORE_ALLOC_SIZE)
{
_TIFFEmitErrorAboveMaxCumulatedMemAlloc(tif, "_TIFFmallocExt", s);
return NULL;
}
void *ptr = _TIFFmalloc(LEADING_AREA_TO_STORE_ALLOC_SIZE + s);
if (!ptr)
return NULL;
tif->tif_cur_cumulated_mem_alloc += s;
memcpy(ptr, &s, sizeof(s));
return (char *)ptr + LEADING_AREA_TO_STORE_ALLOC_SIZE;
}
return _TIFFmalloc(s);
}
/** calloc() version that takes into account memory-specific open options */
void *_TIFFcallocExt(TIFF *tif, tmsize_t nmemb, tmsize_t siz)
{
if (nmemb <= 0 || siz <= 0 || nmemb > TIFF_TMSIZE_T_MAX / siz)
return NULL;
if (tif != NULL && tif->tif_max_single_mem_alloc > 0)
{
if (nmemb * siz > tif->tif_max_single_mem_alloc)
{
_TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFcallocExt",
nmemb * siz);
return NULL;
}
}
if (tif != NULL && tif->tif_max_cumulated_mem_alloc > 0)
{
const tmsize_t s = nmemb * siz;
if (s > tif->tif_max_cumulated_mem_alloc -
tif->tif_cur_cumulated_mem_alloc ||
s > TIFF_TMSIZE_T_MAX - LEADING_AREA_TO_STORE_ALLOC_SIZE)
{
_TIFFEmitErrorAboveMaxCumulatedMemAlloc(tif, "_TIFFcallocExt", s);
return NULL;
}
void *ptr = _TIFFcalloc(LEADING_AREA_TO_STORE_ALLOC_SIZE + s, 1);
if (!ptr)
return NULL;
tif->tif_cur_cumulated_mem_alloc += s;
memcpy(ptr, &s, sizeof(s));
return (char *)ptr + LEADING_AREA_TO_STORE_ALLOC_SIZE;
}
return _TIFFcalloc(nmemb, siz);
}
/** realloc() version that takes into account memory-specific open options */
void *_TIFFreallocExt(TIFF *tif, void *p, tmsize_t s)
{
if (tif != NULL && tif->tif_max_single_mem_alloc > 0 &&
s > tif->tif_max_single_mem_alloc)
{
_TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFreallocExt", s);
return NULL;
}
if (tif != NULL && tif->tif_max_cumulated_mem_alloc > 0)
{
void *oldPtr = p;
tmsize_t oldSize = 0;
if (p)
{
oldPtr = (char *)p - LEADING_AREA_TO_STORE_ALLOC_SIZE;
memcpy(&oldSize, oldPtr, sizeof(oldSize));
assert(oldSize <= tif->tif_cur_cumulated_mem_alloc);
}
if (s > oldSize &&
(s > tif->tif_max_cumulated_mem_alloc -
(tif->tif_cur_cumulated_mem_alloc - oldSize) ||
s > TIFF_TMSIZE_T_MAX - LEADING_AREA_TO_STORE_ALLOC_SIZE))
{
_TIFFEmitErrorAboveMaxCumulatedMemAlloc(tif, "_TIFFreallocExt",
s - oldSize);
return NULL;
}
void *newPtr =
_TIFFrealloc(oldPtr, LEADING_AREA_TO_STORE_ALLOC_SIZE + s);
if (newPtr == NULL)
return NULL;
tif->tif_cur_cumulated_mem_alloc -= oldSize;
tif->tif_cur_cumulated_mem_alloc += s;
memcpy(newPtr, &s, sizeof(s));
return (char *)newPtr + LEADING_AREA_TO_STORE_ALLOC_SIZE;
}
return _TIFFrealloc(p, s);
}
/** free() version that takes into account memory-specific open options */
void _TIFFfreeExt(TIFF *tif, void *p)
{
if (p != NULL && tif != NULL && tif->tif_max_cumulated_mem_alloc > 0)
{
void *oldPtr = (char *)p - LEADING_AREA_TO_STORE_ALLOC_SIZE;
tmsize_t oldSize;
memcpy(&oldSize, oldPtr, sizeof(oldSize));
assert(oldSize <= tif->tif_cur_cumulated_mem_alloc);
tif->tif_cur_cumulated_mem_alloc -= oldSize;
p = oldPtr;
}
_TIFFfree(p);
}
TIFF *TIFFClientOpen(const char *name, const char *mode, thandle_t clientdata,
TIFFReadWriteProc readproc, TIFFReadWriteProc writeproc,
TIFFSeekProc seekproc, TIFFCloseProc closeproc,
TIFFSizeProc sizeproc, TIFFMapFileProc mapproc,
TIFFUnmapFileProc unmapproc)
{
return TIFFClientOpenExt(name, mode, clientdata, readproc, writeproc,
seekproc, closeproc, sizeproc, mapproc, unmapproc,
NULL);
}
TIFF *TIFFClientOpenExt(const char *name, const char *mode,
thandle_t clientdata, TIFFReadWriteProc readproc,
TIFFReadWriteProc writeproc, TIFFSeekProc seekproc,
TIFFCloseProc closeproc, TIFFSizeProc sizeproc,
TIFFMapFileProc mapproc, TIFFUnmapFileProc unmapproc,
TIFFOpenOptions *opts)
{
static const char module[] = "TIFFClientOpenExt";
TIFF *tif;
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_t) == 1);
assert(sizeof(int8_t) == 1);
assert(sizeof(uint16_t) == 2);
assert(sizeof(int16_t) == 2);
assert(sizeof(uint32_t) == 4);
assert(sizeof(int32_t) == 4);
assert(sizeof(uint64_t) == 8);
assert(sizeof(int64_t) == 8);
{
union
{
uint8_t a8[2];
uint16_t a16;
} n;
n.a8[0] = 1;
n.a8[1] = 0;
(void)n;
#ifdef WORDS_BIGENDIAN
assert(n.a16 == 256);
#else
assert(n.a16 == 1);
#endif
}
m = _TIFFgetMode(opts, clientdata, mode, module);
if (m == -1)
goto bad2;
tmsize_t size_to_alloc = (tmsize_t)(sizeof(TIFF) + strlen(name) + 1);
if (opts && opts->max_single_mem_alloc > 0 &&
size_to_alloc > opts->max_single_mem_alloc)
{
_TIFFErrorEarly(opts, clientdata, module,
"%s: Memory allocation of %" PRIu64
" bytes is beyond the %" PRIu64
" byte limit defined in open options",
name, (uint64_t)size_to_alloc,
(uint64_t)opts->max_single_mem_alloc);
goto bad2;
}
if (opts && opts->max_cumulated_mem_alloc > 0 &&
size_to_alloc > opts->max_cumulated_mem_alloc)
{
_TIFFErrorEarly(opts, clientdata, module,
"%s: Memory allocation of %" PRIu64
" bytes is beyond the %" PRIu64
" cumulated byte limit defined in open options",
name, (uint64_t)size_to_alloc,
(uint64_t)opts->max_cumulated_mem_alloc);
goto bad2;
}
tif = (TIFF *)_TIFFmallocExt(NULL, size_to_alloc);
if (tif == NULL)
{
_TIFFErrorEarly(opts, clientdata, module,
"%s: Out of memory (TIFF structure)", name);
goto bad2;
}
_TIFFmemset(tif, 0, sizeof(*tif));
tif->tif_name = (char *)tif + sizeof(TIFF);
strcpy(tif->tif_name, name);
tif->tif_mode = m & ~(O_CREAT | O_TRUNC);
tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER; /* non-existent directory */
tif->tif_curdircount = TIFF_NON_EXISTENT_DIR_NUMBER;
tif->tif_curoff = 0;
tif->tif_curstrip = (uint32_t)-1; /* invalid strip */
tif->tif_row = (uint32_t)-1; /* read/write pre-increment */
tif->tif_clientdata = clientdata;
tif->tif_readproc = readproc;
tif->tif_writeproc = writeproc;
tif->tif_seekproc = seekproc;
tif->tif_closeproc = closeproc;
tif->tif_sizeproc = sizeproc;
tif->tif_mapproc = mapproc ? mapproc : _tiffDummyMapProc;
tif->tif_unmapproc = unmapproc ? unmapproc : _tiffDummyUnmapProc;
if (opts)
{
tif->tif_errorhandler = opts->errorhandler;
tif->tif_errorhandler_user_data = opts->errorhandler_user_data;
tif->tif_warnhandler = opts->warnhandler;
tif->tif_warnhandler_user_data = opts->warnhandler_user_data;
tif->tif_max_single_mem_alloc = opts->max_single_mem_alloc;
tif->tif_max_cumulated_mem_alloc = opts->max_cumulated_mem_alloc;
tif->tif_warn_about_unknown_tags = opts->warn_about_unknown_tags;
}
if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc)
{
TIFFErrorExtR(tif, module,
"One of the client procedures is NULL pointer.");
_TIFFfreeExt(NULL, tif);
goto bad2;
}
_TIFFSetDefaultCompressionState(tif); /* setup default state */
/*
* Default is to return data MSB2LSB and enable the
* use of memory-mapped files and strip chopping when
* a file is opened read-only.
*/
tif->tif_flags = FILLORDER_MSB2LSB;
if (m == O_RDONLY)
tif->tif_flags |= TIFF_MAPPED;
#ifdef STRIPCHOP_DEFAULT
if (m == O_RDONLY || m == O_RDWR)
tif->tif_flags |= STRIPCHOP_DEFAULT;
#endif
/*
* Process library-specific flags in the open mode string.
* The following flags may be used to control intrinsic library
* behavior that may or may not be desirable (usually for
* compatibility with some application that claims to support
* TIFF but only supports some brain dead 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
* '4' ClassicTIFF for creating a file (default)
* '8' BigTIFF for creating a file
* 'D' enable use of deferred strip/tile offset/bytecount array loading.
* 'O' on-demand loading of values instead of whole array loading (implies
* D)
*
* The use of the 'l' and 'b' flags is strongly discouraged.
* These flags are provided solely because numerous vendors,
* typically on the PC, do not correctly support TIFF; they
* only support the Intel little-endian byte order. This
* support is not configured by default because it supports
* the violation of the TIFF spec that says that readers *MUST*
* support both byte orders. It is strongly recommended that
* you not use this feature except to deal with busted apps
* that write invalid TIFF. And even in those cases you should
* bang on the vendors to fix their software.
*
* The 'L', 'B', and 'H' flags are intended for applications
* that can optimize operations on data by using a particular
* bit order. By default the library returns data in MSB2LSB
* bit order for compatibility with older versions of this
* library. Returning data in the bit order of the native CPU
* makes the most sense but also requires applications to check
* the value of the FillOrder tag; something they probably do
* not do right now.
*
* The 'M' and 'm' flags are provided because some virtual memory
* systems exhibit poor behavior when large images are mapped.
* These options permit clients to control the use of memory-mapped
* files on a per-file basis.
*
* The 'C' and 'c' flags are provided because the library support
* for chopping up large strips into multiple smaller strips is not
* application-transparent and as such can cause problems. The 'c'
* option permits applications that only want to look at the tags,
* for example, to get the unadulterated TIFF tag information.
*/
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':
TIFFWarningExtR(tif, name,
"H(ost) mode is deprecated. Since "
"libtiff 4.5.1, it is an alias of 'B' / "
"FILLORDER_MSB2LSB.");
tif->tif_flags =
(tif->tif_flags & ~TIFF_FILLORDER) | FILLORDER_MSB2LSB;
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;
case 'D':
tif->tif_flags |= TIFF_DEFERSTRILELOAD;
break;
case 'O':
if (m == O_RDONLY)
tif->tif_flags |=
(TIFF_LAZYSTRILELOAD | TIFF_DEFERSTRILELOAD);
break;
}
#ifdef DEFER_STRILE_LOAD
/* Compatibility with old DEFER_STRILE_LOAD compilation flag */
/* Probably unneeded, since to the best of my knowledge (E. Rouault) */
/* GDAL was the only user of this, and will now use the new 'D' flag */
tif->tif_flags |= TIFF_DEFERSTRILELOAD;
#endif
/*
* Read in TIFF header.
*/
if ((m & O_TRUNC) ||
!ReadOK(tif, &tif->tif_header, sizeof(TIFFHeaderClassic)))
{
if (tif->tif_mode == O_RDONLY)
{
TIFFErrorExtR(tif, name, "Cannot read TIFF header");
goto bad;
}
/*
* Setup header and write.
*/
#ifdef WORDS_BIGENDIAN
tif->tif_header.common.tiff_magic =
(tif->tif_flags & TIFF_SWAB) ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN;
#else
tif->tif_header.common.tiff_magic =
(tif->tif_flags & TIFF_SWAB) ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN;
#endif
TIFFHeaderUnion tif_header_swapped;
if (!(tif->tif_flags & TIFF_BIGTIFF))
{
tif->tif_header.common.tiff_version = TIFF_VERSION_CLASSIC;
tif->tif_header.classic.tiff_diroff = 0;
tif->tif_header_size = sizeof(TIFFHeaderClassic);
/* Swapped copy for writing */
_TIFFmemcpy(&tif_header_swapped, &tif->tif_header,
sizeof(TIFFHeaderUnion));
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabShort(&tif_header_swapped.common.tiff_version);
}
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;
tif->tif_header_size = sizeof(TIFFHeaderBig);
/* Swapped copy for writing */
_TIFFmemcpy(&tif_header_swapped, &tif->tif_header,
sizeof(TIFFHeaderUnion));
if (tif->tif_flags & TIFF_SWAB)
{
TIFFSwabShort(&tif_header_swapped.common.tiff_version);
TIFFSwabShort(&tif_header_swapped.big.tiff_offsetsize);
}
}
/*
* 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_header_swapped,
(tmsize_t)(tif->tif_header_size)))
{
TIFFErrorExtR(tif, name, "Error writing TIFF header");
goto bad;
}
/*
* Setup default directory.
*/
if (!TIFFDefaultDirectory(tif))
goto bad;
tif->tif_diroff = 0;
tif->tif_lastdiroff = 0;
tif->tif_setdirectory_force_absolute = FALSE;
/* tif_curdircount = 0 means 'empty file opened for writing, but no IFD
* written yet' */
tif->tif_curdircount = 0;
return (tif);
}
/*
* Setup the byte order handling according to the opened file for reading.
*/
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.common.tiff_magic != MDI_BIGENDIAN
#else
tif->tif_header.common.tiff_magic != MDI_LITTLEENDIAN
#endif
)
{
TIFFErrorExtR(tif, name,
"Not a TIFF or MDI file, bad magic number %" PRIu16
" (0x%" PRIx16 ")",
#else
)
{
TIFFErrorExtR(tif, name,
"Not a TIFF file, bad magic number %" PRIu16
" (0x%" PRIx16 ")",
#endif
tif->tif_header.common.tiff_magic,
tif->tif_header.common.tiff_magic);
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_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))
{
TIFFErrorExtR(tif, name,
"Not a TIFF file, bad version number %" PRIu16
" (0x%" PRIx16 ")",
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_t *)(&tif->tif_header) + sizeof(TIFFHeaderClassic)),
(sizeof(TIFFHeaderBig) - sizeof(TIFFHeaderClassic))))
{
TIFFErrorExtR(tif, 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)
{
TIFFErrorExtR(tif, name,
"Not a TIFF file, bad BigTIFF offsetsize %" PRIu16
" (0x%" PRIx16 ")",
tif->tif_header.big.tiff_offsetsize,
tif->tif_header.big.tiff_offsetsize);
goto bad;
}
if (tif->tif_header.big.tiff_unused != 0)
{
TIFFErrorExtR(tif, name,
"Not a TIFF file, bad BigTIFF unused %" PRIu16
" (0x%" PRIx16 ")",
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;
switch (mode[0])
{
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.
* However, the pointer to TIFFSetField() and TIFFGetField()
* (i.e. tif->tif_tagmethods.vsetfield and
* tif->tif_tagmethods.vgetfield) need to be initialized, which is
* done in TIFFDefaultDirectory().
*/
if (tif->tif_flags & TIFF_HEADERONLY)
{
if (!TIFFDefaultDirectory(tif))
goto bad;
return (tif);
}
/*
* Setup initial directory.
*/
if (TIFFReadDirectory(tif))
{
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 */
TIFFCleanup(tif);
bad2:
return ((TIFF *)0);
}
/*
* Query functions to access private data.
*/
/*
* Return open file's name.
*/
const char *TIFFFileName(TIFF *tif) { return (tif->tif_name); }
/*
* Set the file name.
*/
const char *TIFFSetFileName(TIFF *tif, const char *name)
{
const char *old_name = tif->tif_name;
tif->tif_name = (char *)name;
return (old_name);
}
/*
* Return open file's I/O descriptor.
*/
int TIFFFileno(TIFF *tif) { return (tif->tif_fd); }
/*
* Set open file's I/O descriptor, and return previous value.
*/
int TIFFSetFileno(TIFF *tif, int fd)
{
int old_fd = tif->tif_fd;
tif->tif_fd = fd;
return old_fd;
}
/*
* Return open file's clientdata.
*/
thandle_t TIFFClientdata(TIFF *tif) { return (tif->tif_clientdata); }
/*
* Set open file's clientdata, and return previous value.
*/
thandle_t TIFFSetClientdata(TIFF *tif, thandle_t newvalue)
{
thandle_t m = tif->tif_clientdata;
tif->tif_clientdata = newvalue;
return m;
}
/*
* Return read/write mode.
*/
int TIFFGetMode(TIFF *tif) { return (tif->tif_mode); }
/*
* Return read/write mode.
*/
int TIFFSetMode(TIFF *tif, int mode)
{
int old_mode = tif->tif_mode;
tif->tif_mode = mode;
return (old_mode);
}
/*
* Return nonzero if file is organized in
* tiles; zero if organized as strips.
*/
int TIFFIsTiled(TIFF *tif) { return (isTiled(tif)); }
/*
* Return current row being read/written.
*/
uint32_t TIFFCurrentRow(TIFF *tif) { return (tif->tif_row); }
/*
* Return index of the current directory.
*/
tdir_t TIFFCurrentDirectory(TIFF *tif) { return (tif->tif_curdir); }
/*
* Return current strip.
*/
uint32_t TIFFCurrentStrip(TIFF *tif) { return (tif->tif_curstrip); }
/*
* Return current tile.
*/
uint32_t TIFFCurrentTile(TIFF *tif) { return (tif->tif_curtile); }
/*
* Return nonzero if the file has byte-swapped data.
*/
int TIFFIsByteSwapped(TIFF *tif) { return ((tif->tif_flags & TIFF_SWAB) != 0); }
/*
* Return nonzero if the data is returned up-sampled.
*/
int TIFFIsUpSampled(TIFF *tif) { return (isUpSampled(tif)); }
/*
* Return nonzero if the data is returned in MSB-to-LSB bit order.
*/
int TIFFIsMSB2LSB(TIFF *tif) { return (isFillOrder(tif, FILLORDER_MSB2LSB)); }
/*
* Return nonzero if given file was written in big-endian order.
*/
int TIFFIsBigEndian(TIFF *tif)
{
return (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN);
}
/*
* Return nonzero if given file is BigTIFF style.
*/
int TIFFIsBigTIFF(TIFF *tif) { return ((tif->tif_flags & TIFF_BIGTIFF) != 0); }
/*
* Return pointer to file read method.
*/
TIFFReadWriteProc TIFFGetReadProc(TIFF *tif) { return (tif->tif_readproc); }
/*
* Return pointer to file write method.
*/
TIFFReadWriteProc TIFFGetWriteProc(TIFF *tif) { return (tif->tif_writeproc); }
/*
* Return pointer to file seek method.
*/
TIFFSeekProc TIFFGetSeekProc(TIFF *tif) { return (tif->tif_seekproc); }
/*
* Return pointer to file close method.
*/
TIFFCloseProc TIFFGetCloseProc(TIFF *tif) { return (tif->tif_closeproc); }
/*
* Return pointer to file size requesting method.
*/
TIFFSizeProc TIFFGetSizeProc(TIFF *tif) { return (tif->tif_sizeproc); }
/*
* Return pointer to memory mapping method.
*/
TIFFMapFileProc TIFFGetMapFileProc(TIFF *tif) { return (tif->tif_mapproc); }
/*
* Return pointer to memory unmapping method.
*/
TIFFUnmapFileProc TIFFGetUnmapFileProc(TIFF *tif)
{
return (tif->tif_unmapproc);
}
+330
View File
@@ -0,0 +1,330 @@
/*
* Copyright (c) 1988-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "tiffiop.h"
#ifdef PACKBITS_SUPPORT
/*
* TIFF Library.
*
* PackBits Compression Algorithm Support
*/
#include <stdio.h>
#ifndef PACKBITS_READ_ONLY
static int PackBitsPreEncode(TIFF *tif, uint16_t s)
{
(void)s;
tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(tmsize_t));
if (tif->tif_data == NULL)
return (0);
/*
* Calculate the scanline/tile-width size in bytes.
*/
if (isTiled(tif))
*(tmsize_t *)tif->tif_data = TIFFTileRowSize(tif);
else
*(tmsize_t *)tif->tif_data = TIFFScanlineSize(tif);
return (1);
}
static int PackBitsPostEncode(TIFF *tif)
{
if (tif->tif_data)
_TIFFfreeExt(tif, tif->tif_data);
return (1);
}
/*
* Encode a run of pixels.
*/
static int PackBitsEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
{
unsigned char *bp = (unsigned char *)buf;
uint8_t *op;
uint8_t *ep;
uint8_t *lastliteral;
long n, slop;
int b;
enum
{
BASE,
LITERAL,
RUN,
LITERAL_RUN
} state;
(void)s;
op = tif->tif_rawcp;
ep = tif->tif_rawdata + tif->tif_rawdatasize;
state = BASE;
lastliteral = NULL;
while (cc > 0)
{
/*
* Find the longest string of identical bytes.
*/
b = *bp++;
cc--;
n = 1;
for (; cc > 0 && b == *bp; cc--, bp++)
n++;
again:
if (op + 2 >= ep)
{ /* insure space for new data */
/*
* Be careful about writing the last
* literal. Must write up to that point
* and then copy the remainder to the
* front of the buffer.
*/
if (state == LITERAL || state == LITERAL_RUN)
{
slop = (long)(op - lastliteral);
tif->tif_rawcc += (tmsize_t)(lastliteral - tif->tif_rawcp);
if (!TIFFFlushData1(tif))
return (0);
op = tif->tif_rawcp;
while (slop-- > 0)
*op++ = *lastliteral++;
lastliteral = tif->tif_rawcp;
}
else
{
tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp);
if (!TIFFFlushData1(tif))
return (0);
op = tif->tif_rawcp;
}
}
switch (state)
{
case BASE: /* initial state, set run/literal */
if (n > 1)
{
state = RUN;
if (n > 128)
{
*op++ = (uint8_t)-127;
*op++ = (uint8_t)b;
n -= 128;
goto again;
}
*op++ = (uint8_t)(-(n - 1));
*op++ = (uint8_t)b;
}
else
{
lastliteral = op;
*op++ = 0;
*op++ = (uint8_t)b;
state = LITERAL;
}
break;
case LITERAL: /* last object was literal string */
if (n > 1)
{
state = LITERAL_RUN;
if (n > 128)
{
*op++ = (uint8_t)-127;
*op++ = (uint8_t)b;
n -= 128;
goto again;
}
*op++ = (uint8_t)(-(n - 1)); /* encode run */
*op++ = (uint8_t)b;
}
else
{ /* extend literal */
if (++(*lastliteral) == 127)
state = BASE;
*op++ = (uint8_t)b;
}
break;
case RUN: /* last object was run */
if (n > 1)
{
if (n > 128)
{
*op++ = (uint8_t)-127;
*op++ = (uint8_t)b;
n -= 128;
goto again;
}
*op++ = (uint8_t)(-(n - 1));
*op++ = (uint8_t)b;
}
else
{
lastliteral = op;
*op++ = 0;
*op++ = (uint8_t)b;
state = LITERAL;
}
break;
case LITERAL_RUN: /* literal followed by a run */
/*
* Check to see if previous run should
* be converted to a literal, in which
* case we convert literal-run-literal
* to a single literal.
*/
if (n == 1 && op[-2] == (uint8_t)-1 && *lastliteral < 126)
{
state = (((*lastliteral) += 2) == 127 ? BASE : LITERAL);
op[-2] = op[-1]; /* replicate */
}
else
state = RUN;
goto again;
}
}
tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp);
tif->tif_rawcp = op;
return (1);
}
/*
* Encode a rectangular chunk of pixels. We break it up
* into row-sized pieces to insure that encoded runs do
* not span rows. Otherwise, there can be problems with
* the decoder if data is read, for example, by scanlines
* when it was encoded by strips.
*/
static int PackBitsEncodeChunk(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
{
tmsize_t rowsize = *(tmsize_t *)tif->tif_data;
while (cc > 0)
{
tmsize_t chunk = rowsize;
if (cc < chunk)
chunk = cc;
if (PackBitsEncode(tif, bp, chunk, s) < 0)
return (-1);
bp += chunk;
cc -= chunk;
}
return (1);
}
#endif
static int PackBitsDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
{
static const char module[] = "PackBitsDecode";
int8_t *bp;
tmsize_t cc;
long n;
int b;
(void)s;
bp = (int8_t *)tif->tif_rawcp;
cc = tif->tif_rawcc;
while (cc > 0 && occ > 0)
{
n = (long)*bp++;
cc--;
if (n < 0)
{ /* replicate next byte -n+1 times */
if (n == -128) /* nop */
continue;
n = -n + 1;
if (occ < (tmsize_t)n)
{
TIFFWarningExtR(tif, module,
"Discarding %" TIFF_SSIZE_FORMAT
" bytes to avoid buffer overrun",
(tmsize_t)n - occ);
n = (long)occ;
}
if (cc == 0)
{
TIFFWarningExtR(
tif, module,
"Terminating PackBitsDecode due to lack of data.");
break;
}
occ -= n;
b = *bp++;
cc--;
while (n-- > 0)
*op++ = (uint8_t)b;
}
else
{ /* copy next n+1 bytes literally */
if (occ < (tmsize_t)(n + 1))
{
TIFFWarningExtR(tif, module,
"Discarding %" TIFF_SSIZE_FORMAT
" bytes to avoid buffer overrun",
(tmsize_t)n - occ + 1);
n = (long)occ - 1;
}
if (cc < (tmsize_t)(n + 1))
{
TIFFWarningExtR(
tif, module,
"Terminating PackBitsDecode due to lack of data.");
break;
}
_TIFFmemcpy(op, bp, ++n);
op += n;
occ -= n;
bp += n;
cc -= n;
}
}
tif->tif_rawcp = (uint8_t *)bp;
tif->tif_rawcc = cc;
if (occ > 0)
{
memset(op, 0, (size_t)occ);
TIFFErrorExtR(tif, module, "Not enough data for scanline %" PRIu32,
tif->tif_row);
return (0);
}
return (1);
}
int TIFFInitPackBits(TIFF *tif, int scheme)
{
(void)scheme;
tif->tif_decoderow = PackBitsDecode;
tif->tif_decodestrip = PackBitsDecode;
tif->tif_decodetile = PackBitsDecode;
#ifndef PACKBITS_READ_ONLY
tif->tif_preencode = PackBitsPreEncode;
tif->tif_postencode = PackBitsPostEncode;
tif->tif_encoderow = PackBitsEncode;
tif->tif_encodestrip = PackBitsEncodeChunk;
tif->tif_encodetile = PackBitsEncodeChunk;
#endif
return (1);
}
#endif /* PACKBITS_SUPPORT */
+1677
View File
File diff suppressed because it is too large Load Diff
+1161
View File
File diff suppressed because it is too large Load Diff
+74
View File
@@ -0,0 +1,74 @@
/*
* Copyright (c) 1995-1997 Sam Leffler
* Copyright (c) 1995-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.
*/
#ifndef _TIFFPREDICT_
#define _TIFFPREDICT_
#include "tiffio.h"
#include "tiffiop.h"
/*
* ``Library-private'' Support for the Predictor Tag
*/
typedef int (*TIFFEncodeDecodeMethod)(TIFF *tif, uint8_t *buf, tmsize_t size);
/*
* Codecs that want to support the Predictor tag must place
* this structure first in their private state block so that
* the predictor code can cast tif_data to find its state.
*/
typedef struct
{
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 */
TIFFEncodeDecodeMethod encodepfunc; /* horizontal differencer */
TIFFCodeMethod decoderow; /* parent codec encode/decode row */
TIFFCodeMethod decodestrip; /* parent codec encode/decode strip */
TIFFCodeMethod decodetile; /* parent codec encode/decode tile */
TIFFEncodeDecodeMethod decodepfunc; /* horizontal accumulator */
TIFFVGetMethod vgetparent; /* super-class method */
TIFFVSetMethod vsetparent; /* super-class method */
TIFFPrintMethod printdir; /* super-class method */
TIFFBoolMethod setupdecode; /* super-class method */
TIFFBoolMethod setupencode; /* super-class method */
} TIFFPredictorState;
#if defined(__cplusplus)
extern "C"
{
#endif
extern int TIFFPredictorInit(TIFF *);
extern int TIFFPredictorCleanup(TIFF *);
#if defined(__cplusplus)
}
#endif
#endif /* _TIFFPREDICT_ */
+756
View File
@@ -0,0 +1,756 @@
/*
* 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.
*
* Directory Printing Support
*/
#include "tiffiop.h"
#include <stdio.h>
#include <ctype.h>
static void _TIFFprintAsciiBounded(FILE *fd, const char *cp, size_t max_chars);
static const char *const photoNames[] = {
"min-is-white", /* PHOTOMETRIC_MINISWHITE */
"min-is-black", /* PHOTOMETRIC_MINISBLACK */
"RGB color", /* PHOTOMETRIC_RGB */
"palette color (RGB from colormap)", /* PHOTOMETRIC_PALETTE */
"transparency mask", /* PHOTOMETRIC_MASK */
"separated", /* PHOTOMETRIC_SEPARATED */
"YCbCr", /* PHOTOMETRIC_YCBCR */
"7 (0x7)",
"CIE L*a*b*", /* PHOTOMETRIC_CIELAB */
"ICC L*a*b*", /* PHOTOMETRIC_ICCLAB */
"ITU L*a*b*" /* PHOTOMETRIC_ITULAB */
};
#define NPHOTONAMES (sizeof(photoNames) / sizeof(photoNames[0]))
static const char *const orientNames[] = {
"0 (0x0)",
"row 0 top, col 0 lhs", /* ORIENTATION_TOPLEFT */
"row 0 top, col 0 rhs", /* ORIENTATION_TOPRIGHT */
"row 0 bottom, col 0 rhs", /* ORIENTATION_BOTRIGHT */
"row 0 bottom, col 0 lhs", /* ORIENTATION_BOTLEFT */
"row 0 lhs, col 0 top", /* ORIENTATION_LEFTTOP */
"row 0 rhs, col 0 top", /* ORIENTATION_RIGHTTOP */
"row 0 rhs, col 0 bottom", /* ORIENTATION_RIGHTBOT */
"row 0 lhs, col 0 bottom", /* ORIENTATION_LEFTBOT */
};
#define NORIENTNAMES (sizeof(orientNames) / sizeof(orientNames[0]))
static const struct tagname
{
uint16_t tag;
const char *name;
} tagnames[] = {
{TIFFTAG_GDAL_METADATA, "GDAL Metadata"},
{TIFFTAG_GDAL_NODATA, "GDAL NoDataValue"},
};
#define NTAGS (sizeof(tagnames) / sizeof(tagnames[0]))
static void _TIFFPrintField(FILE *fd, const TIFFField *fip,
uint32_t value_count, void *raw_data)
{
uint32_t j;
/* Print a user-friendly name for tags of relatively common use, but */
/* which aren't registered by libtiff itself. */
const char *field_name = fip->field_name;
if (TIFFFieldIsAnonymous(fip))
{
for (size_t i = 0; i < NTAGS; ++i)
{
if (fip->field_tag == tagnames[i].tag)
{
field_name = tagnames[i].name;
break;
}
}
}
fprintf(fd, " %s: ", field_name);
for (j = 0; j < value_count; j++)
{
if (fip->field_type == TIFF_BYTE)
fprintf(fd, "%" PRIu8, ((uint8_t *)raw_data)[j]);
else if (fip->field_type == TIFF_UNDEFINED)
fprintf(fd, "0x%" PRIx8, ((uint8_t *)raw_data)[j]);
else if (fip->field_type == TIFF_SBYTE)
fprintf(fd, "%" PRId8, ((int8_t *)raw_data)[j]);
else if (fip->field_type == TIFF_SHORT)
fprintf(fd, "%" PRIu16, ((uint16_t *)raw_data)[j]);
else if (fip->field_type == TIFF_SSHORT)
fprintf(fd, "%" PRId16, ((int16_t *)raw_data)[j]);
else if (fip->field_type == TIFF_LONG)
fprintf(fd, "%" PRIu32, ((uint32_t *)raw_data)[j]);
else if (fip->field_type == TIFF_SLONG)
fprintf(fd, "%" PRId32, ((int32_t *)raw_data)[j]);
else if (fip->field_type == TIFF_IFD)
fprintf(fd, "0x%" PRIx32, ((uint32_t *)raw_data)[j]);
else if (fip->field_type == TIFF_RATIONAL ||
fip->field_type == TIFF_SRATIONAL)
{
int tv_size = TIFFFieldSetGetSize(fip);
if (tv_size == 8)
fprintf(fd, "%lf", ((double *)raw_data)[j]);
else
fprintf(fd, "%f", ((float *)raw_data)[j]);
}
else if (fip->field_type == TIFF_FLOAT)
fprintf(fd, "%f", ((float *)raw_data)[j]);
else if (fip->field_type == TIFF_LONG8)
fprintf(fd, "%" PRIu64, ((uint64_t *)raw_data)[j]);
else if (fip->field_type == TIFF_SLONG8)
fprintf(fd, "%" PRId64, ((int64_t *)raw_data)[j]);
else if (fip->field_type == TIFF_IFD8)
fprintf(fd, "0x%" PRIx64, ((uint64_t *)raw_data)[j]);
else if (fip->field_type == TIFF_DOUBLE)
fprintf(fd, "%lf", ((double *)raw_data)[j]);
else if (fip->field_type == TIFF_ASCII)
{
fprintf(fd, "%s", (char *)raw_data);
break;
}
else
{
fprintf(fd, "<unsupported data type in TIFFPrint>");
break;
}
if (j < value_count - 1)
fprintf(fd, ",");
}
fprintf(fd, "\n");
}
static int _TIFFPrettyPrintField(TIFF *tif, const TIFFField *fip, FILE *fd,
uint32_t tag, uint32_t value_count,
void *raw_data)
{
(void)tif;
/* do not try to pretty print auto-defined fields */
if (TIFFFieldIsAnonymous(fip))
{
return 0;
}
switch (tag)
{
case TIFFTAG_INKSET:
if (value_count == 2 && fip->field_type == TIFF_SHORT)
{
fprintf(fd, " Ink Set: ");
switch (*((uint16_t *)raw_data))
{
case INKSET_CMYK:
fprintf(fd, "CMYK\n");
break;
default:
fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n",
*((uint16_t *)raw_data),
*((uint16_t *)raw_data));
break;
}
return 1;
}
return 0;
case TIFFTAG_DOTRANGE:
if (value_count == 2 && fip->field_type == TIFF_SHORT)
{
fprintf(fd, " Dot Range: %" PRIu16 "-%" PRIu16 "\n",
((uint16_t *)raw_data)[0], ((uint16_t *)raw_data)[1]);
return 1;
}
return 0;
case TIFFTAG_WHITEPOINT:
if (value_count == 2 && fip->field_type == TIFF_RATIONAL)
{
fprintf(fd, " White Point: %g-%g\n", ((float *)raw_data)[0],
((float *)raw_data)[1]);
return 1;
}
return 0;
case TIFFTAG_XMLPACKET:
{
uint32_t i;
fprintf(fd, " XMLPacket (XMP Metadata):\n");
for (i = 0; i < value_count; i++)
fputc(((char *)raw_data)[i], fd);
fprintf(fd, "\n");
return 1;
}
case TIFFTAG_RICHTIFFIPTC:
fprintf(fd, " RichTIFFIPTC Data: <present>, %" PRIu32 " bytes\n",
value_count);
return 1;
case TIFFTAG_PHOTOSHOP:
fprintf(fd, " Photoshop Data: <present>, %" PRIu32 " bytes\n",
value_count);
return 1;
case TIFFTAG_ICCPROFILE:
fprintf(fd, " ICC Profile: <present>, %" PRIu32 " bytes\n",
value_count);
return 1;
case TIFFTAG_STONITS:
if (value_count == 1 && fip->field_type == TIFF_DOUBLE)
{
fprintf(fd, " Sample to Nits conversion factor: %.4e\n",
*((double *)raw_data));
return 1;
}
return 0;
}
return 0;
}
/*
* Print the contents of the current directory
* to the specified stdio file stream.
*/
void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags)
{
TIFFDirectory *td = &tif->tif_dir;
char *sep;
long l, n;
fprintf(fd, "TIFF Directory at offset 0x%" PRIx64 " (%" PRIu64 ")\n",
tif->tif_diroff, tif->tif_diroff);
if (TIFFFieldSet(tif, FIELD_SUBFILETYPE))
{
fprintf(fd, " Subfile Type:");
sep = " ";
if (td->td_subfiletype & FILETYPE_REDUCEDIMAGE)
{
fprintf(fd, "%sreduced-resolution image", sep);
sep = "/";
}
if (td->td_subfiletype & FILETYPE_PAGE)
{
fprintf(fd, "%smulti-page document", sep);
sep = "/";
}
if (td->td_subfiletype & FILETYPE_MASK)
fprintf(fd, "%stransparency mask", sep);
fprintf(fd, " (%" PRIu32 " = 0x%" PRIx32 ")\n", td->td_subfiletype,
td->td_subfiletype);
}
if (TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS))
{
fprintf(fd, " Image Width: %" PRIu32 " Image Length: %" PRIu32,
td->td_imagewidth, td->td_imagelength);
if (TIFFFieldSet(tif, FIELD_IMAGEDEPTH))
fprintf(fd, " Image Depth: %" PRIu32, td->td_imagedepth);
fprintf(fd, "\n");
}
if (TIFFFieldSet(tif, FIELD_TILEDIMENSIONS))
{
fprintf(fd, " Tile Width: %" PRIu32 " Tile Length: %" PRIu32,
td->td_tilewidth, td->td_tilelength);
if (TIFFFieldSet(tif, FIELD_TILEDEPTH))
fprintf(fd, " Tile Depth: %" PRIu32, td->td_tiledepth);
fprintf(fd, "\n");
}
if (TIFFFieldSet(tif, FIELD_RESOLUTION))
{
fprintf(fd, " Resolution: %g, %g", td->td_xresolution,
td->td_yresolution);
if (TIFFFieldSet(tif, FIELD_RESOLUTIONUNIT))
{
switch (td->td_resolutionunit)
{
case RESUNIT_NONE:
fprintf(fd, " (unitless)");
break;
case RESUNIT_INCH:
fprintf(fd, " pixels/inch");
break;
case RESUNIT_CENTIMETER:
fprintf(fd, " pixels/cm");
break;
default:
fprintf(fd, " (unit %" PRIu16 " = 0x%" PRIx16 ")",
td->td_resolutionunit, td->td_resolutionunit);
break;
}
}
fprintf(fd, "\n");
}
if (TIFFFieldSet(tif, FIELD_POSITION))
fprintf(fd, " Position: %g, %g\n", td->td_xposition, td->td_yposition);
if (TIFFFieldSet(tif, FIELD_BITSPERSAMPLE))
fprintf(fd, " Bits/Sample: %" PRIu16 "\n", td->td_bitspersample);
if (TIFFFieldSet(tif, FIELD_SAMPLEFORMAT))
{
fprintf(fd, " Sample Format: ");
switch (td->td_sampleformat)
{
case SAMPLEFORMAT_VOID:
fprintf(fd, "void\n");
break;
case SAMPLEFORMAT_INT:
fprintf(fd, "signed integer\n");
break;
case SAMPLEFORMAT_UINT:
fprintf(fd, "unsigned integer\n");
break;
case SAMPLEFORMAT_IEEEFP:
fprintf(fd, "IEEE floating point\n");
break;
case SAMPLEFORMAT_COMPLEXINT:
fprintf(fd, "complex signed integer\n");
break;
case SAMPLEFORMAT_COMPLEXIEEEFP:
fprintf(fd, "complex IEEE floating point\n");
break;
default:
fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n",
td->td_sampleformat, td->td_sampleformat);
break;
}
}
if (TIFFFieldSet(tif, FIELD_COMPRESSION))
{
const TIFFCodec *c = TIFFFindCODEC(td->td_compression);
fprintf(fd, " Compression Scheme: ");
if (c)
fprintf(fd, "%s\n", c->name);
else
fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", td->td_compression,
td->td_compression);
}
if (TIFFFieldSet(tif, FIELD_PHOTOMETRIC))
{
fprintf(fd, " Photometric Interpretation: ");
if (td->td_photometric < NPHOTONAMES)
fprintf(fd, "%s\n", photoNames[td->td_photometric]);
else
{
switch (td->td_photometric)
{
case PHOTOMETRIC_LOGL:
fprintf(fd, "CIE Log2(L)\n");
break;
case PHOTOMETRIC_LOGLUV:
fprintf(fd, "CIE Log2(L) (u',v')\n");
break;
default:
fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n",
td->td_photometric, td->td_photometric);
break;
}
}
}
if (TIFFFieldSet(tif, FIELD_EXTRASAMPLES) && td->td_extrasamples)
{
uint16_t i;
fprintf(fd, " Extra Samples: %" PRIu16 "<", td->td_extrasamples);
sep = "";
for (i = 0; i < td->td_extrasamples; i++)
{
switch (td->td_sampleinfo[i])
{
case EXTRASAMPLE_UNSPECIFIED:
fprintf(fd, "%sunspecified", sep);
break;
case EXTRASAMPLE_ASSOCALPHA:
fprintf(fd, "%sassoc-alpha", sep);
break;
case EXTRASAMPLE_UNASSALPHA:
fprintf(fd, "%sunassoc-alpha", sep);
break;
default:
fprintf(fd, "%s%" PRIu16 " (0x%" PRIx16 ")", sep,
td->td_sampleinfo[i], td->td_sampleinfo[i]);
break;
}
sep = ", ";
}
fprintf(fd, ">\n");
}
if (TIFFFieldSet(tif, FIELD_INKNAMES))
{
char *cp;
uint16_t i;
fprintf(fd, " Ink Names: ");
i = td->td_samplesperpixel;
sep = "";
for (cp = td->td_inknames;
i > 0 && cp < td->td_inknames + td->td_inknameslen;
cp = strchr(cp, '\0') + 1, i--)
{
size_t max_chars = td->td_inknameslen - (cp - td->td_inknames);
fputs(sep, fd);
_TIFFprintAsciiBounded(fd, cp, max_chars);
sep = ", ";
}
fputs("\n", fd);
}
if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS))
{
fprintf(fd, " NumberOfInks: %d\n", td->td_numberofinks);
}
if (TIFFFieldSet(tif, FIELD_THRESHHOLDING))
{
fprintf(fd, " Thresholding: ");
switch (td->td_threshholding)
{
case THRESHHOLD_BILEVEL:
fprintf(fd, "bilevel art scan\n");
break;
case THRESHHOLD_HALFTONE:
fprintf(fd, "halftone or dithered scan\n");
break;
case THRESHHOLD_ERRORDIFFUSE:
fprintf(fd, "error diffused\n");
break;
default:
fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n",
td->td_threshholding, td->td_threshholding);
break;
}
}
if (TIFFFieldSet(tif, FIELD_FILLORDER))
{
fprintf(fd, " FillOrder: ");
switch (td->td_fillorder)
{
case FILLORDER_MSB2LSB:
fprintf(fd, "msb-to-lsb\n");
break;
case FILLORDER_LSB2MSB:
fprintf(fd, "lsb-to-msb\n");
break;
default:
fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", td->td_fillorder,
td->td_fillorder);
break;
}
}
if (TIFFFieldSet(tif, FIELD_YCBCRSUBSAMPLING))
{
fprintf(fd, " YCbCr Subsampling: %" PRIu16 ", %" PRIu16 "\n",
td->td_ycbcrsubsampling[0], td->td_ycbcrsubsampling[1]);
}
if (TIFFFieldSet(tif, FIELD_YCBCRPOSITIONING))
{
fprintf(fd, " YCbCr Positioning: ");
switch (td->td_ycbcrpositioning)
{
case YCBCRPOSITION_CENTERED:
fprintf(fd, "centered\n");
break;
case YCBCRPOSITION_COSITED:
fprintf(fd, "cosited\n");
break;
default:
fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n",
td->td_ycbcrpositioning, td->td_ycbcrpositioning);
break;
}
}
if (TIFFFieldSet(tif, FIELD_HALFTONEHINTS))
fprintf(fd, " Halftone Hints: light %" PRIu16 " dark %" PRIu16 "\n",
td->td_halftonehints[0], td->td_halftonehints[1]);
if (TIFFFieldSet(tif, FIELD_ORIENTATION))
{
fprintf(fd, " Orientation: ");
if (td->td_orientation < NORIENTNAMES)
fprintf(fd, "%s\n", orientNames[td->td_orientation]);
else
fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", td->td_orientation,
td->td_orientation);
}
if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
fprintf(fd, " Samples/Pixel: %" PRIx16 "\n", td->td_samplesperpixel);
if (TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
{
fprintf(fd, " Rows/Strip: ");
if (td->td_rowsperstrip == (uint32_t)-1)
fprintf(fd, "(infinite)\n");
else
fprintf(fd, "%" PRIu32 "\n", td->td_rowsperstrip);
}
if (TIFFFieldSet(tif, FIELD_MINSAMPLEVALUE))
fprintf(fd, " Min Sample Value: %" PRIu16 "\n", td->td_minsamplevalue);
if (TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE))
fprintf(fd, " Max Sample Value: %" PRIu16 "\n", td->td_maxsamplevalue);
if (TIFFFieldSet(tif, FIELD_SMINSAMPLEVALUE))
{
int i;
int count =
(tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1;
fprintf(fd, " SMin Sample Value:");
for (i = 0; i < count; ++i)
fprintf(fd, " %g", td->td_sminsamplevalue[i]);
fprintf(fd, "\n");
}
if (TIFFFieldSet(tif, FIELD_SMAXSAMPLEVALUE))
{
int i;
int count =
(tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1;
fprintf(fd, " SMax Sample Value:");
for (i = 0; i < count; ++i)
fprintf(fd, " %g", td->td_smaxsamplevalue[i]);
fprintf(fd, "\n");
}
if (TIFFFieldSet(tif, FIELD_PLANARCONFIG))
{
fprintf(fd, " Planar Configuration: ");
switch (td->td_planarconfig)
{
case PLANARCONFIG_CONTIG:
fprintf(fd, "single image plane\n");
break;
case PLANARCONFIG_SEPARATE:
fprintf(fd, "separate image planes\n");
break;
default:
fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n",
td->td_planarconfig, td->td_planarconfig);
break;
}
}
if (TIFFFieldSet(tif, FIELD_PAGENUMBER))
fprintf(fd, " Page Number: %" PRIu16 "-%" PRIu16 "\n",
td->td_pagenumber[0], td->td_pagenumber[1]);
if (TIFFFieldSet(tif, FIELD_COLORMAP))
{
fprintf(fd, " Color Map: ");
if (flags & TIFFPRINT_COLORMAP)
{
fprintf(fd, "\n");
n = 1L << td->td_bitspersample;
for (l = 0; l < n; l++)
fprintf(fd, " %5ld: %5" PRIu16 " %5" PRIu16 " %5" PRIu16 "\n",
l, td->td_colormap[0][l], td->td_colormap[1][l],
td->td_colormap[2][l]);
}
else
fprintf(fd, "(present)\n");
}
if (TIFFFieldSet(tif, FIELD_REFBLACKWHITE))
{
int i;
fprintf(fd, " Reference Black/White:\n");
for (i = 0; i < 3; i++)
fprintf(fd, " %2d: %5g %5g\n", i,
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)
{
fprintf(fd, "\n");
n = 1L << td->td_bitspersample;
for (l = 0; l < n; l++)
{
uint16_t i;
fprintf(fd, " %2ld: %5" PRIu16, l,
td->td_transferfunction[0][l]);
for (i = 1;
i < td->td_samplesperpixel - td->td_extrasamples && i < 3;
i++)
fprintf(fd, " %5" PRIu16, td->td_transferfunction[i][l]);
fputc('\n', fd);
}
}
else
fprintf(fd, "(present)\n");
}
if (TIFFFieldSet(tif, FIELD_SUBIFD) && (td->td_subifd))
{
uint16_t i;
fprintf(fd, " SubIFD Offsets:");
for (i = 0; i < td->td_nsubifd; i++)
fprintf(fd, " %5" PRIu64, td->td_subifd[i]);
fputc('\n', fd);
}
/*
** Custom tag support.
*/
{
int i;
short count;
count = (short)TIFFGetTagListCount(tif);
for (i = 0; i < count; i++)
{
uint32_t tag = TIFFGetTagListEntry(tif, i);
const TIFFField *fip;
uint32_t value_count;
int mem_alloc = 0;
void *raw_data = NULL;
uint16_t dotrange[2]; /* must be kept in that scope and not moved in
the below TIFFTAG_DOTRANGE specific case */
fip = TIFFFieldWithTag(tif, tag);
if (fip == NULL)
continue;
if (fip->field_passcount)
{
if (fip->field_readcount == TIFF_VARIABLE2)
{
if (TIFFGetField(tif, tag, &value_count, &raw_data) != 1)
continue;
}
else if (fip->field_readcount == TIFF_VARIABLE)
{
uint16_t small_value_count;
if (TIFFGetField(tif, tag, &small_value_count, &raw_data) !=
1)
continue;
value_count = small_value_count;
}
else
{
assert(fip->field_readcount == TIFF_VARIABLE ||
fip->field_readcount == TIFF_VARIABLE2);
continue;
}
}
else
{
if (fip->field_readcount == TIFF_VARIABLE ||
fip->field_readcount == TIFF_VARIABLE2)
value_count = 1;
else if (fip->field_readcount == TIFF_SPP)
value_count = td->td_samplesperpixel;
else
value_count = fip->field_readcount;
if (fip->field_tag == TIFFTAG_DOTRANGE &&
strcmp(fip->field_name, "DotRange") == 0)
{
/* TODO: This is an evil exception and should not have been
handled this way ... likely best if we move it into
the directory structure with an explicit field in
libtiff 4.1 and assign it a FIELD_ value */
raw_data = dotrange;
TIFFGetField(tif, tag, dotrange + 0, dotrange + 1);
}
else if (fip->field_type == TIFF_ASCII ||
fip->field_readcount == TIFF_VARIABLE ||
fip->field_readcount == TIFF_VARIABLE2 ||
fip->field_readcount == TIFF_SPP || value_count > 1)
{
if (TIFFGetField(tif, tag, &raw_data) != 1)
continue;
}
else
{
/*--: Rational2Double: For Rationals evaluate
* "set_get_field_type" to determine internal storage size.
*/
int tv_size = TIFFFieldSetGetSize(fip);
raw_data = _TIFFmallocExt(tif, tv_size * value_count);
mem_alloc = 1;
if (TIFFGetField(tif, tag, raw_data) != 1)
{
_TIFFfreeExt(tif, 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 (raw_data != NULL &&
!_TIFFPrettyPrintField(tif, fip, fd, tag, value_count,
raw_data))
_TIFFPrintField(fd, fip, value_count, raw_data);
if (mem_alloc)
_TIFFfreeExt(tif, raw_data);
}
}
if (tif->tif_tagmethods.printdir)
(*tif->tif_tagmethods.printdir)(tif, fd, flags);
if ((flags & TIFFPRINT_STRIPS) && TIFFFieldSet(tif, FIELD_STRIPOFFSETS))
{
uint32_t s;
fprintf(fd, " %" PRIu32 " %s:\n", td->td_nstrips,
isTiled(tif) ? "Tiles" : "Strips");
for (s = 0; s < td->td_nstrips; s++)
fprintf(fd, " %3" PRIu32 ": [%8" PRIu64 ", %8" PRIu64 "]\n", s,
TIFFGetStrileOffset(tif, s),
TIFFGetStrileByteCount(tif, s));
}
}
void _TIFFprintAscii(FILE *fd, const char *cp)
{
_TIFFprintAsciiBounded(fd, cp, strlen(cp));
}
static void _TIFFprintAsciiBounded(FILE *fd, const char *cp, size_t max_chars)
{
for (; max_chars > 0 && *cp != '\0'; cp++, max_chars--)
{
const char *tp;
if (isprint((int)*cp))
{
fputc(*cp, fd);
continue;
}
for (tp = "\tt\bb\rr\nn\vv"; *tp; tp++)
if (*tp++ == *cp)
break;
if (*tp)
fprintf(fd, "\\%c", *tp);
else
fprintf(fd, "\\%03o", *cp & 0xff);
}
}
void _TIFFprintAsciiTag(FILE *fd, const char *name, const char *value)
{
fprintf(fd, " %s: \"", name);
_TIFFprintAscii(fd, value);
fprintf(fd, "\"\n");
}
+1681
View File
File diff suppressed because it is too large Load Diff
+404
View File
@@ -0,0 +1,404 @@
/*
* Copyright (c) 1988-1996 Sam Leffler
* Copyright (c) 1991-1996 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 UNIX-specific Routines.
*/
#include "tiffiop.h"
#include <iostream>
using namespace std;
/*
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_t _tiffosSeekProc(thandle_t fd, uint64_t off, int whence);
static uint64_t _tiffisSeekProc(thandle_t fd, uint64_t off, int whence);
static uint64_t _tiffosSizeProc(thandle_t fd);
static uint64_t _tiffisSizeProc(thandle_t fd);
static int _tiffosCloseProc(thandle_t fd);
static int _tiffisCloseProc(thandle_t fd);
static int _tiffDummyMapProcCxx(thandle_t, void **base, toff_t *size);
static void _tiffDummyUnmapProcCxx(thandle_t, void *base, toff_t size);
static TIFF *_tiffStreamOpen(const char *name, const char *mode, void *fd);
struct tiffis_data
{
istream *stream;
ios::pos_type start_pos;
};
struct tiffos_data
{
ostream *stream;
ios::pos_type start_pos;
};
static tmsize_t _tiffosReadProc(thandle_t, void *, tmsize_t) { return 0; }
static tmsize_t _tiffisReadProc(thandle_t fd, void *buf, tmsize_t size)
{
tiffis_data *data = reinterpret_cast<tiffis_data *>(fd);
// Verify that type does not overflow.
streamsize request_size = size;
if (static_cast<tmsize_t>(request_size) != size)
return static_cast<tmsize_t>(-1);
data->stream->read((char *)buf, request_size);
return static_cast<tmsize_t>(data->stream->gcount());
}
static tmsize_t _tiffosWriteProc(thandle_t fd, void *buf, tmsize_t size)
{
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(reinterpret_cast<const char *>(buf), request_size);
return static_cast<tmsize_t>(os->tellp() - pos);
}
static tmsize_t _tiffisWriteProc(thandle_t, void *, tmsize_t) { return 0; }
static uint64_t _tiffosSeekProc(thandle_t fd, uint64_t off, int whence)
{
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 static_cast<uint64_t>(-1);
switch (whence)
{
case SEEK_SET:
{
// Compute 64-bit offset
uint64_t new_offset =
static_cast<uint64_t>(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_t>(offset) != new_offset)
return static_cast<uint64_t>(-1);
os->seekp(offset, ios::beg);
break;
}
case SEEK_CUR:
{
// Verify that value does not overflow
ios::off_type offset = static_cast<ios::off_type>(off);
if (static_cast<uint64_t>(offset) != off)
return static_cast<uint64_t>(-1);
os->seekp(offset, ios::cur);
break;
}
case SEEK_END:
{
// Verify that value does not overflow
ios::off_type offset = static_cast<ios::off_type>(off);
if (static_cast<uint64_t>(offset) != off)
return static_cast<uint64_t>(-1);
os->seekp(offset, ios::end);
break;
}
}
// Attempt to workaround problems with seeking past the end of the
// stream. ofstream doesn't have a problem with this but
// ostrstream/ostringstream does. In that situation, add intermediate
// '\0' characters.
if (os->fail())
{
ios::iostate old_state;
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:
default:
origin = data->start_pos;
break;
case SEEK_CUR:
origin = os->tellp();
break;
case SEEK_END:
os->seekp(0, ios::end);
origin = os->tellp();
break;
}
// restore original stream state
os->clear(old_state);
// only do something if desired seek position is valid
if ((static_cast<uint64_t>(origin) + off) >
static_cast<uint64_t>(data->start_pos))
{
uint64_t 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 = (static_cast<uint64_t>(origin)) + off - os->tellp();
for (uint64_t i = 0; i < num_fill; i++)
os->put('\0');
// retry the seek
os->seekp(static_cast<ios::off_type>(
static_cast<uint64_t>(origin) + off),
ios::beg);
}
}
return static_cast<uint64_t>(os->tellp());
}
static uint64_t _tiffisSeekProc(thandle_t fd, uint64_t off, int whence)
{
tiffis_data *data = reinterpret_cast<tiffis_data *>(fd);
switch (whence)
{
case SEEK_SET:
{
// Compute 64-bit offset
uint64_t new_offset =
static_cast<uint64_t>(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_t>(offset) != new_offset)
return static_cast<uint64_t>(-1);
data->stream->seekg(offset, ios::beg);
break;
}
case SEEK_CUR:
{
// Verify that value does not overflow
ios::off_type offset = static_cast<ios::off_type>(off);
if (static_cast<uint64_t>(offset) != off)
return static_cast<uint64_t>(-1);
data->stream->seekg(offset, ios::cur);
break;
}
case SEEK_END:
{
// Verify that value does not overflow
ios::off_type offset = static_cast<ios::off_type>(off);
if (static_cast<uint64_t>(offset) != off)
return static_cast<uint64_t>(-1);
data->stream->seekg(offset, ios::end);
break;
}
}
return (uint64_t)(data->stream->tellg() - data->start_pos);
}
static uint64_t _tiffosSizeProc(thandle_t fd)
{
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 (uint64_t)len;
}
static uint64_t _tiffisSizeProc(thandle_t fd)
{
tiffis_data *data = reinterpret_cast<tiffis_data *>(fd);
ios::pos_type pos = data->stream->tellg();
ios::pos_type len;
data->stream->seekg(0, ios::end);
len = data->stream->tellg();
data->stream->seekg(pos);
return (uint64_t)len;
}
static int _tiffosCloseProc(thandle_t fd)
{
// Our stream was not allocated by us, so it shouldn't be closed by us.
delete reinterpret_cast<tiffos_data *>(fd);
return 0;
}
static int _tiffisCloseProc(thandle_t fd)
{
// Our stream was not allocated by us, so it shouldn't be closed by us.
delete reinterpret_cast<tiffis_data *>(fd);
return 0;
}
static int _tiffDummyMapProcCxx(thandle_t, void **base, toff_t *size)
{
(void)base;
(void)size;
return (0);
}
static void _tiffDummyUnmapProcCxx(thandle_t, void *base, toff_t size)
{
(void)base;
(void)size;
}
/*
* Open a TIFF file descriptor for read/writing.
*/
static TIFF *_tiffStreamOpen(const char *name, const char *mode, void *fd)
{
TIFF *tif;
if (strchr(mode, 'w'))
{
tiffos_data *data = new tiffos_data;
data->stream = reinterpret_cast<ostream *>(fd);
data->start_pos = data->stream->tellp();
// Open for writing.
tif = TIFFClientOpen(
name, mode, reinterpret_cast<thandle_t>(data), _tiffosReadProc,
_tiffosWriteProc, _tiffosSeekProc, _tiffosCloseProc,
_tiffosSizeProc, _tiffDummyMapProcCxx, _tiffDummyUnmapProcCxx);
if (!tif)
{
delete data;
}
}
else
{
tiffis_data *data = new tiffis_data;
data->stream = reinterpret_cast<istream *>(fd);
data->start_pos = data->stream->tellg();
// Open for reading.
tif = TIFFClientOpen(
name, mode, reinterpret_cast<thandle_t>(data), _tiffisReadProc,
_tiffisWriteProc, _tiffisSeekProc, _tiffisCloseProc,
_tiffisSizeProc, _tiffDummyMapProcCxx, _tiffDummyUnmapProcCxx);
if (!tif)
{
delete data;
}
}
return (tif);
}
} /* extern "C" */
TIFF *TIFFStreamOpen(const char *name, ostream *os)
{
// If os is either a ostrstream or ostringstream, and has no data
// 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() && static_cast<int>(os->tellp()) < 0)
{
*os << '\0';
os->seekp(0);
}
// NB: We don't support mapped files with streams so add 'm'
return _tiffStreamOpen(name, "wm", os);
}
TIFF *TIFFStreamOpen(const char *name, istream *is)
{
// NB: We don't support mapped files with streams so add 'm'
return _tiffStreamOpen(name, "rm", is);
}
+381
View File
@@ -0,0 +1,381 @@
/*
* Copyright (c) 1991-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.
*
* Strip-organized Image Support Routines.
*/
#include "tiffiop.h"
/*
* Compute which strip a (row,sample) value is in.
*/
uint32_t TIFFComputeStrip(TIFF *tif, uint32_t row, uint16_t sample)
{
static const char module[] = "TIFFComputeStrip";
TIFFDirectory *td = &tif->tif_dir;
uint32_t strip;
if (td->td_rowsperstrip == 0)
{
TIFFErrorExtR(tif, module,
"Cannot compute strip: RowsPerStrip is zero");
return 0;
}
strip = row / td->td_rowsperstrip;
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
{
if (sample >= td->td_samplesperpixel)
{
TIFFErrorExtR(tif, module, "%lu: Sample out of range, max %lu",
(unsigned long)sample,
(unsigned long)td->td_samplesperpixel);
return (0);
}
strip += (uint32_t)sample * td->td_stripsperimage;
}
return (strip);
}
/*
* Compute how many strips are in an image.
*/
uint32_t TIFFNumberOfStrips(TIFF *tif)
{
TIFFDirectory *td = &tif->tif_dir;
uint32_t nstrips;
if (td->td_rowsperstrip == 0)
{
TIFFWarningExtR(tif, "TIFFNumberOfStrips", "RowsPerStrip is zero");
return 0;
}
nstrips = (td->td_rowsperstrip == (uint32_t)-1
? 1
: TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip));
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
nstrips =
_TIFFMultiply32(tif, nstrips, (uint32_t)td->td_samplesperpixel,
"TIFFNumberOfStrips");
return (nstrips);
}
/*
* Compute the # bytes in a variable height, row-aligned strip.
*/
uint64_t TIFFVStripSize64(TIFF *tif, uint32_t nrows)
{
static const char module[] = "TIFFVStripSize64";
TIFFDirectory *td = &tif->tif_dir;
if (nrows == (uint32_t)(-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.
* Must also roundup width and height when calculating
* since images that are not a multiple of the
* horizontal/vertical subsampling area include
* YCbCr data for the extended image.
*/
uint16_t ycbcrsubsampling[2];
uint16_t samplingblock_samples;
uint32_t samplingblocks_hor;
uint32_t samplingblocks_ver;
uint64_t samplingrow_samples;
uint64_t samplingrow_size;
if (td->td_samplesperpixel != 3)
{
TIFFErrorExtR(tif, module, "Invalid td_samplesperpixel value");
return 0;
}
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) ||
(ycbcrsubsampling[0] == 0 || ycbcrsubsampling[1] == 0))
{
TIFFErrorExtR(tif, module, "Invalid YCbCr subsampling (%dx%d)",
ycbcrsubsampling[0], ycbcrsubsampling[1]);
return 0;
}
samplingblock_samples = ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2;
samplingblocks_hor =
TIFFhowmany_32(td->td_imagewidth, ycbcrsubsampling[0]);
samplingblocks_ver = TIFFhowmany_32(nrows, ycbcrsubsampling[1]);
samplingrow_samples = _TIFFMultiply64(tif, samplingblocks_hor,
samplingblock_samples, module);
samplingrow_size = TIFFhowmany8_64(_TIFFMultiply64(
tif, samplingrow_samples, td->td_bitspersample, module));
return (
_TIFFMultiply64(tif, samplingrow_size, samplingblocks_ver, module));
}
else
return (_TIFFMultiply64(tif, nrows, TIFFScanlineSize64(tif), module));
}
tmsize_t TIFFVStripSize(TIFF *tif, uint32_t nrows)
{
static const char module[] = "TIFFVStripSize";
uint64_t m;
m = TIFFVStripSize64(tif, nrows);
return _TIFFCastUInt64ToSSize(tif, m, module);
}
/*
* Compute the # bytes in a raw strip.
*/
uint64_t TIFFRawStripSize64(TIFF *tif, uint32_t strip)
{
static const char module[] = "TIFFRawStripSize64";
uint64_t bytecount = TIFFGetStrileByteCount(tif, strip);
if (bytecount == 0)
{
TIFFErrorExtR(tif, module,
"%" PRIu64 ": Invalid strip byte count, strip %lu",
(uint64_t)bytecount, (unsigned long)strip);
bytecount = (uint64_t)-1;
}
return bytecount;
}
tmsize_t TIFFRawStripSize(TIFF *tif, uint32_t strip)
{
static const char module[] = "TIFFRawStripSize";
uint64_t m;
tmsize_t n;
m = TIFFRawStripSize64(tif, strip);
if (m == (uint64_t)(-1))
n = (tmsize_t)(-1);
else
{
n = (tmsize_t)m;
if ((uint64_t)n != m)
{
TIFFErrorExtR(tif, module, "Integer overflow");
n = 0;
}
}
return (n);
}
/*
* Compute the # bytes in a (row-aligned) strip.
*
* Note that if RowsPerStrip is larger than the
* recorded ImageLength, then the strip size is
* truncated to reflect the actual space required
* to hold the strip.
*/
uint64_t TIFFStripSize64(TIFF *tif)
{
TIFFDirectory *td = &tif->tif_dir;
uint32_t rps = td->td_rowsperstrip;
if (rps > td->td_imagelength)
rps = td->td_imagelength;
return (TIFFVStripSize64(tif, rps));
}
tmsize_t TIFFStripSize(TIFF *tif)
{
static const char module[] = "TIFFStripSize";
uint64_t m;
m = TIFFStripSize64(tif);
return _TIFFCastUInt64ToSSize(tif, m, module);
}
/*
* Compute a default strip size based on the image
* characteristics and a requested value. If the
* request is <1 then we choose a strip size according
* to certain heuristics.
*/
uint32_t TIFFDefaultStripSize(TIFF *tif, uint32_t request)
{
return (*tif->tif_defstripsize)(tif, request);
}
uint32_t _TIFFDefaultStripSize(TIFF *tif, uint32_t s)
{
if ((int32_t)s < 1)
{
/*
* If RowsPerStrip is unspecified, try to break the
* image up into strips that are approximately
* STRIP_SIZE_DEFAULT bytes long.
*/
uint64_t scanlinesize;
uint64_t rows;
scanlinesize = TIFFScanlineSize64(tif);
if (scanlinesize == 0)
scanlinesize = 1;
rows = (uint64_t)STRIP_SIZE_DEFAULT / scanlinesize;
if (rows == 0)
rows = 1;
else if (rows > 0xFFFFFFFF)
rows = 0xFFFFFFFF;
s = (uint32_t)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.
* The ScanlineSize in case of YCbCrSubsampling is defined as the
* 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.
*/
uint64_t TIFFScanlineSize64(TIFF *tif)
{
static const char module[] = "TIFFScanlineSize64";
TIFFDirectory *td = &tif->tif_dir;
uint64_t scanline_size;
if (td->td_planarconfig == PLANARCONFIG_CONTIG)
{
if ((td->td_photometric == PHOTOMETRIC_YCBCR) &&
(td->td_samplesperpixel == 3) && (!isUpSampled(tif)))
{
uint16_t ycbcrsubsampling[2];
uint16_t samplingblock_samples;
uint32_t samplingblocks_hor;
uint64_t samplingrow_samples;
uint64_t samplingrow_size;
if (td->td_samplesperpixel != 3)
{
TIFFErrorExtR(tif, module, "Invalid td_samplesperpixel value");
return 0;
}
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)) ||
((ycbcrsubsampling[0] == 0) || (ycbcrsubsampling[1] == 0)))
{
TIFFErrorExtR(tif, 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
{
uint64_t scanline_samples;
uint32_t scanline_width = td->td_imagewidth;
#if 0
// Tries to fix https://gitlab.com/libtiff/libtiff/-/merge_requests/564
// but causes regression when decoding legit files with tiffcp -c none
// Cf https://gitlab.com/libtiff/libtiff/-/merge_requests/644
if (td->td_photometric == PHOTOMETRIC_YCBCR)
{
uint16_t subsampling_hor;
uint16_t ignored;
TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
&subsampling_hor, &ignored);
if (subsampling_hor > 1) // roundup width for YCbCr
scanline_width =
TIFFroundup_32(scanline_width, subsampling_hor);
}
#endif
scanline_samples = _TIFFMultiply64(tif, scanline_width,
td->td_samplesperpixel, module);
scanline_size =
TIFFhowmany_64(_TIFFMultiply64(tif, scanline_samples,
td->td_bitspersample, module),
8);
}
}
else
{
scanline_size =
TIFFhowmany_64(_TIFFMultiply64(tif, td->td_imagewidth,
td->td_bitspersample, module),
8);
}
if (scanline_size == 0)
{
TIFFErrorExtR(tif, module, "Computed scanline size is zero");
return 0;
}
return (scanline_size);
}
tmsize_t TIFFScanlineSize(TIFF *tif)
{
static const char module[] = "TIFFScanlineSize";
uint64_t m;
m = TIFFScanlineSize64(tif);
return _TIFFCastUInt64ToSSize(tif, m, module);
}
/*
* Return the number of bytes required to store a complete
* decoded and packed raster scanline (as opposed to the
* I/O size returned by TIFFScanlineSize which may be less
* if data is store as separate planes).
*/
uint64_t TIFFRasterScanlineSize64(TIFF *tif)
{
static const char module[] = "TIFFRasterScanlineSize64";
TIFFDirectory *td = &tif->tif_dir;
uint64_t scanline;
scanline =
_TIFFMultiply64(tif, td->td_bitspersample, td->td_imagewidth, module);
if (td->td_planarconfig == PLANARCONFIG_CONTIG)
{
scanline =
_TIFFMultiply64(tif, scanline, td->td_samplesperpixel, module);
return (TIFFhowmany8_64(scanline));
}
else
return (_TIFFMultiply64(tif, TIFFhowmany8_64(scanline),
td->td_samplesperpixel, module));
}
tmsize_t TIFFRasterScanlineSize(TIFF *tif)
{
static const char module[] = "TIFFRasterScanlineSize";
uint64_t m;
m = TIFFRasterScanlineSize64(tif);
return _TIFFCastUInt64ToSSize(tif, m, module);
}
+329
View File
@@ -0,0 +1,329 @@
/*
* 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 Bit & Byte Swapping Support.
*
* XXX We assume short = 16-bits and long = 32-bits XXX
*/
#include "tiffiop.h"
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabShort)
void TIFFSwabShort(uint16_t *wp)
{
register unsigned char *cp = (unsigned char *)wp;
unsigned char t;
assert(sizeof(uint16_t) == 2);
t = cp[1];
cp[1] = cp[0];
cp[0] = t;
}
#endif
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabLong)
void TIFFSwabLong(uint32_t *lp)
{
register unsigned char *cp = (unsigned char *)lp;
unsigned char t;
assert(sizeof(uint32_t) == 4);
t = cp[3];
cp[3] = cp[0];
cp[0] = t;
t = cp[2];
cp[2] = cp[1];
cp[1] = t;
}
#endif
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabLong8)
void TIFFSwabLong8(uint64_t *lp)
{
register unsigned char *cp = (unsigned char *)lp;
unsigned char t;
assert(sizeof(uint64_t) == 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
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfShort)
void TIFFSwabArrayOfShort(register uint16_t *wp, tmsize_t n)
{
register unsigned char *cp;
register unsigned char t;
assert(sizeof(uint16_t) == 2);
/* XXX unroll loop some */
while (n-- > 0)
{
cp = (unsigned char *)wp;
t = cp[1];
cp[1] = cp[0];
cp[0] = t;
wp++;
}
}
#endif
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfTriples)
void TIFFSwabArrayOfTriples(register uint8_t *tp, tmsize_t n)
{
unsigned char *cp;
unsigned char t;
/* XXX unroll loop some */
while (n-- > 0)
{
cp = (unsigned char *)tp;
t = cp[2];
cp[2] = cp[0];
cp[0] = t;
tp += 3;
}
}
#endif
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfLong)
void TIFFSwabArrayOfLong(register uint32_t *lp, tmsize_t n)
{
register unsigned char *cp;
register unsigned char t;
assert(sizeof(uint32_t) == 4);
/* XXX unroll loop some */
while (n-- > 0)
{
cp = (unsigned char *)lp;
t = cp[3];
cp[3] = cp[0];
cp[0] = t;
t = cp[2];
cp[2] = cp[1];
cp[1] = t;
lp++;
}
}
#endif
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfLong8)
void TIFFSwabArrayOfLong8(register uint64_t *lp, tmsize_t n)
{
register unsigned char *cp;
register unsigned char t;
assert(sizeof(uint64_t) == 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
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(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
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(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
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabDouble)
void TIFFSwabDouble(double *dp)
{
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
#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfDouble)
void TIFFSwabArrayOfDouble(double *dp, tmsize_t n)
{
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
/*
* Bit reversal tables. TIFFBitRevTable[<byte>] gives
* the bit reversed value of <byte>. Used in various
* places in the library when the FillOrder requires
* bit reversal of byte values (e.g. CCITT Fax 3
* encoding/decoding). TIFFNoBitRevTable is provided
* for algorithms that want an equivalent table that
* do not reverse bit values.
*/
static const unsigned char TIFFBitRevTable[256] = {
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0,
0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4,
0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc,
0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca,
0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6,
0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1,
0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9,
0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd,
0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3,
0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7,
0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf,
0x3f, 0xbf, 0x7f, 0xff};
static const unsigned char TIFFNoBitRevTable[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53,
0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb,
0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
0xfc, 0xfd, 0xfe, 0xff,
};
const unsigned char *TIFFGetBitRevTable(int reversed)
{
return (reversed ? TIFFBitRevTable : TIFFNoBitRevTable);
}
void TIFFReverseBits(uint8_t *cp, tmsize_t n)
{
for (; n > 8; n -= 8)
{
cp[0] = TIFFBitRevTable[cp[0]];
cp[1] = TIFFBitRevTable[cp[1]];
cp[2] = TIFFBitRevTable[cp[2]];
cp[3] = TIFFBitRevTable[cp[3]];
cp[4] = TIFFBitRevTable[cp[4]];
cp[5] = TIFFBitRevTable[cp[5]];
cp[6] = TIFFBitRevTable[cp[6]];
cp[7] = TIFFBitRevTable[cp[7]];
cp += 8;
}
while (n-- > 0)
{
*cp = TIFFBitRevTable[*cp];
cp++;
}
}
+202
View File
@@ -0,0 +1,202 @@
/*
* Copyright (c) 1988-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "tiffiop.h"
#include <assert.h>
#ifdef THUNDER_SUPPORT
/*
* TIFF Library.
*
* ThunderScan 4-bit Compression Algorithm Support
*/
/*
* ThunderScan uses an encoding scheme designed for
* 4-bit pixel values. Data is encoded in bytes, with
* each byte split into a 2-bit code word and a 6-bit
* data value. The encoding gives raw data, runs of
* pixels, or pixel values encoded as a delta from the
* previous pixel value. For the latter, either 2-bit
* or 3-bit delta values are used, with the deltas packed
* into a single byte.
*/
#define THUNDER_DATA 0x3f /* mask for 6-bit data */
#define THUNDER_CODE 0xc0 /* mask for 2-bit code word */
/* code values */
#define THUNDER_RUN 0x00 /* run of pixels w/ encoded count */
#define THUNDER_2BITDELTAS 0x40 /* 3 pixels w/ encoded 2-bit deltas */
#define DELTA2_SKIP 2 /* skip code for 2-bit deltas */
#define THUNDER_3BITDELTAS 0x80 /* 2 pixels w/ encoded 3-bit deltas */
#define DELTA3_SKIP 4 /* skip code for 3-bit deltas */
#define THUNDER_RAW 0xc0 /* raw data encoded */
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 < maxpixels) \
{ \
if (npixels++ & 1) \
*op++ |= lastpixel; \
else \
op[0] = (uint8_t)(lastpixel << 4); \
} \
}
static int ThunderSetupDecode(TIFF *tif)
{
static const char module[] = "ThunderSetupDecode";
if (tif->tif_dir.td_bitspersample != 4)
{
TIFFErrorExtR(tif, 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_t *op0, tmsize_t maxpixels)
{
static const char module[] = "ThunderDecode";
register unsigned char *bp;
register tmsize_t cc;
unsigned int lastpixel;
tmsize_t npixels;
uint8_t *op = op0;
bp = (unsigned char *)tif->tif_rawcp;
cc = tif->tif_rawcc;
lastpixel = 0;
npixels = 0;
while (cc > 0 && npixels < maxpixels)
{
int n, delta;
n = *bp++;
cc--;
switch (n & THUNDER_CODE)
{
case THUNDER_RUN: /* pixel run */
/*
* Replicate the last pixel n times,
* where n is the lower-order 6 bits.
*/
if (n == 0)
break;
if (npixels & 1)
{
op[0] |= lastpixel;
lastpixel = *op++;
npixels++;
n--;
}
else
lastpixel |= lastpixel << 4;
npixels += n;
if (npixels > maxpixels)
break;
for (; n > 0; n -= 2)
*op++ = (uint8_t)lastpixel;
if (n == -1)
*--op &= 0xf0;
lastpixel &= 0xf;
break;
case THUNDER_2BITDELTAS: /* 2-bit deltas */
if ((delta = ((n >> 4) & 3)) != DELTA2_SKIP)
SETPIXEL(op,
(unsigned)((int)lastpixel + twobitdeltas[delta]));
if ((delta = ((n >> 2) & 3)) != DELTA2_SKIP)
SETPIXEL(op,
(unsigned)((int)lastpixel + twobitdeltas[delta]));
if ((delta = (n & 3)) != DELTA2_SKIP)
SETPIXEL(op,
(unsigned)((int)lastpixel + twobitdeltas[delta]));
break;
case THUNDER_3BITDELTAS: /* 3-bit deltas */
if ((delta = ((n >> 3) & 7)) != DELTA3_SKIP)
SETPIXEL(
op, (unsigned)((int)lastpixel + threebitdeltas[delta]));
if ((delta = (n & 7)) != DELTA3_SKIP)
SETPIXEL(
op, (unsigned)((int)lastpixel + threebitdeltas[delta]));
break;
case THUNDER_RAW: /* raw data */
SETPIXEL(op, n);
break;
}
}
tif->tif_rawcp = (uint8_t *)bp;
tif->tif_rawcc = cc;
if (npixels != maxpixels)
{
uint8_t *op_end = op0 + (maxpixels + 1) / 2;
memset(op, 0, (size_t)(op_end - op));
TIFFErrorExtR(tif, module,
"%s data at scanline %lu (%" PRIu64 " != %" PRIu64 ")",
npixels < maxpixels ? "Not enough" : "Too much",
(unsigned long)tif->tif_row, (uint64_t)npixels,
(uint64_t)maxpixels);
return (0);
}
return (1);
}
static int ThunderDecodeRow(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
{
static const char module[] = "ThunderDecodeRow";
uint8_t *row = buf;
(void)s;
if (occ % tif->tif_scanlinesize)
{
TIFFErrorExtR(tif, 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;
row += tif->tif_scanlinesize;
}
return (1);
}
int TIFFInitThunderScan(TIFF *tif, int scheme)
{
(void)scheme;
tif->tif_setupdecode = ThunderSetupDecode;
tif->tif_decoderow = ThunderDecodeRow;
tif->tif_decodestrip = ThunderDecodeRow;
return (1);
}
#endif /* THUNDER_SUPPORT */
+284
View File
@@ -0,0 +1,284 @@
/*
* Copyright (c) 1991-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.
*
* Tiled Image Support Routines.
*/
#include "tiffiop.h"
/*
* Compute which tile an (x,y,z,s) value is in.
*/
uint32_t TIFFComputeTile(TIFF *tif, uint32_t x, uint32_t y, uint32_t z,
uint16_t s)
{
TIFFDirectory *td = &tif->tif_dir;
uint32_t dx = td->td_tilewidth;
uint32_t dy = td->td_tilelength;
uint32_t dz = td->td_tiledepth;
uint32_t tile = 1;
if (td->td_imagedepth == 1)
z = 0;
if (dx == (uint32_t)-1)
dx = td->td_imagewidth;
if (dy == (uint32_t)-1)
dy = td->td_imagelength;
if (dz == (uint32_t)-1)
dz = td->td_imagedepth;
if (dx != 0 && dy != 0 && dz != 0)
{
uint32_t xpt = TIFFhowmany_32(td->td_imagewidth, dx);
uint32_t ypt = TIFFhowmany_32(td->td_imagelength, dy);
uint32_t zpt = TIFFhowmany_32(td->td_imagedepth, dz);
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
tile = (xpt * ypt * zpt) * s + (xpt * ypt) * (z / dz) +
xpt * (y / dy) + x / dx;
else
tile = (xpt * ypt) * (z / dz) + xpt * (y / dy) + x / dx;
}
return (tile);
}
/*
* Check an (x,y,z,s) coordinate
* against the image bounds.
*/
int TIFFCheckTile(TIFF *tif, uint32_t x, uint32_t y, uint32_t z, uint16_t s)
{
TIFFDirectory *td = &tif->tif_dir;
if (x >= td->td_imagewidth)
{
TIFFErrorExtR(tif, tif->tif_name, "%lu: Col out of range, max %lu",
(unsigned long)x, (unsigned long)(td->td_imagewidth - 1));
return (0);
}
if (y >= td->td_imagelength)
{
TIFFErrorExtR(tif, tif->tif_name, "%lu: Row out of range, max %lu",
(unsigned long)y,
(unsigned long)(td->td_imagelength - 1));
return (0);
}
if (z >= td->td_imagedepth)
{
TIFFErrorExtR(tif, tif->tif_name, "%lu: Depth out of range, max %lu",
(unsigned long)z, (unsigned long)(td->td_imagedepth - 1));
return (0);
}
if (td->td_planarconfig == PLANARCONFIG_SEPARATE &&
s >= td->td_samplesperpixel)
{
TIFFErrorExtR(tif, tif->tif_name, "%lu: Sample out of range, max %lu",
(unsigned long)s,
(unsigned long)(td->td_samplesperpixel - 1));
return (0);
}
return (1);
}
/*
* Compute how many tiles are in an image.
*/
uint32_t TIFFNumberOfTiles(TIFF *tif)
{
TIFFDirectory *td = &tif->tif_dir;
uint32_t dx = td->td_tilewidth;
uint32_t dy = td->td_tilelength;
uint32_t dz = td->td_tiledepth;
uint32_t ntiles;
if (dx == (uint32_t)-1)
dx = td->td_imagewidth;
if (dy == (uint32_t)-1)
dy = td->td_imagelength;
if (dz == (uint32_t)-1)
dz = td->td_imagedepth;
ntiles =
(dx == 0 || dy == 0 || dz == 0)
? 0
: _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 = _TIFFMultiply32(tif, ntiles, td->td_samplesperpixel,
"TIFFNumberOfTiles");
return (ntiles);
}
/*
* Compute the # bytes in each row of a tile.
*/
uint64_t TIFFTileRowSize64(TIFF *tif)
{
static const char module[] = "TIFFTileRowSize64";
TIFFDirectory *td = &tif->tif_dir;
uint64_t rowsize;
uint64_t tilerowsize;
if (td->td_tilelength == 0)
{
TIFFErrorExtR(tif, module, "Tile length is zero");
return 0;
}
if (td->td_tilewidth == 0)
{
TIFFErrorExtR(tif, module, "Tile width is zero");
return (0);
}
rowsize = _TIFFMultiply64(tif, td->td_bitspersample, td->td_tilewidth,
"TIFFTileRowSize");
if (td->td_planarconfig == PLANARCONFIG_CONTIG)
{
if (td->td_samplesperpixel == 0)
{
TIFFErrorExtR(tif, module, "Samples per pixel is zero");
return 0;
}
rowsize = _TIFFMultiply64(tif, rowsize, td->td_samplesperpixel,
"TIFFTileRowSize");
}
tilerowsize = TIFFhowmany8_64(rowsize);
if (tilerowsize == 0)
{
TIFFErrorExtR(tif, module, "Computed tile row size is zero");
return 0;
}
return (tilerowsize);
}
tmsize_t TIFFTileRowSize(TIFF *tif)
{
static const char module[] = "TIFFTileRowSize";
uint64_t m;
m = TIFFTileRowSize64(tif);
return _TIFFCastUInt64ToSSize(tif, m, module);
}
/*
* Compute the # bytes in a variable length, row-aligned tile.
*/
uint64_t TIFFVTileSize64(TIFF *tif, uint32_t nrows)
{
static const char module[] = "TIFFVTileSize64";
TIFFDirectory *td = &tif->tif_dir;
if (td->td_tilelength == 0 || td->td_tilewidth == 0 ||
td->td_tiledepth == 0)
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.
* Must also roundup width and height when calculating
* since images that are not a multiple of the
* horizontal/vertical subsampling area include
* YCbCr data for the extended image.
*/
uint16_t ycbcrsubsampling[2];
uint16_t samplingblock_samples;
uint32_t samplingblocks_hor;
uint32_t samplingblocks_ver;
uint64_t samplingrow_samples;
uint64_t samplingrow_size;
TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
ycbcrsubsampling + 0, ycbcrsubsampling + 1);
if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 &&
ycbcrsubsampling[0] != 4) ||
(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 &&
ycbcrsubsampling[1] != 4))
{
TIFFErrorExtR(tif, module, "Invalid YCbCr subsampling (%dx%d)",
ycbcrsubsampling[0], ycbcrsubsampling[1]);
return 0;
}
samplingblock_samples = ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2;
samplingblocks_hor =
TIFFhowmany_32(td->td_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_t nrows)
{
static const char module[] = "TIFFVTileSize";
uint64_t m;
m = TIFFVTileSize64(tif, nrows);
return _TIFFCastUInt64ToSSize(tif, m, module);
}
/*
* Compute the # bytes in a row-aligned tile.
*/
uint64_t TIFFTileSize64(TIFF *tif)
{
return (TIFFVTileSize64(tif, tif->tif_dir.td_tilelength));
}
tmsize_t TIFFTileSize(TIFF *tif)
{
static const char module[] = "TIFFTileSize";
uint64_t m;
m = TIFFTileSize64(tif);
return _TIFFCastUInt64ToSSize(tif, m, module);
}
/*
* Compute a default tile size based on the image
* characteristics and a requested value. If a
* request is <1 then we choose a size according
* to certain heuristics.
*/
void TIFFDefaultTileSize(TIFF *tif, uint32_t *tw, uint32_t *th)
{
(*tif->tif_deftilesize)(tif, tw, th);
}
void _TIFFDefaultTileSize(TIFF *tif, uint32_t *tw, uint32_t *th)
{
(void)tif;
if (*(int32_t *)tw < 1)
*tw = 256;
if (*(int32_t *)th < 1)
*th = 256;
/* roundup to a multiple of 16 per the spec */
if (*tw & 0xf)
*tw = TIFFroundup_32(*tw, 16);
if (*th & 0xf)
*th = TIFFroundup_32(*th, 16);
}
+382
View File
@@ -0,0 +1,382 @@
/*
* 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 UNIX-specific Routines. These are should also work with the
* Windows Common RunTime Library.
*/
#ifdef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
#undef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
#endif
#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>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_IO_H
#include <io.h>
#endif
#include "tiffiop.h"
#define TIFF_IO_MAX 2147483647U
typedef union fd_as_handle_union
{
int fd;
thandle_t h;
} fd_as_handle_union_t;
static tmsize_t _tiffReadProc(thandle_t fd, void *buf, tmsize_t size)
{
fd_as_handle_union_t fdh;
const size_t bytes_total = (size_t)size;
size_t bytes_read;
tmsize_t count = -1;
if ((tmsize_t)bytes_total != size)
{
errno = EINVAL;
return (tmsize_t)-1;
}
fdh.h = fd;
for (bytes_read = 0; bytes_read < bytes_total; bytes_read += count)
{
char *buf_offset = (char *)buf + bytes_read;
size_t io_size = bytes_total - bytes_read;
if (io_size > TIFF_IO_MAX)
io_size = TIFF_IO_MAX;
/* Below is an obvious false positive of Coverity Scan */
/* coverity[overflow_sink] */
count = read(fdh.fd, buf_offset, (TIFFIOSize_t)io_size);
if (count <= 0)
break;
}
if (count < 0)
return (tmsize_t)-1;
/* Silence Coverity Scan warning about unsigned to signed underflow. */
/* coverity[return_overflow:SUPPRESS] */
return (tmsize_t)bytes_read;
}
static tmsize_t _tiffWriteProc(thandle_t fd, void *buf, tmsize_t size)
{
fd_as_handle_union_t fdh;
const size_t bytes_total = (size_t)size;
size_t bytes_written;
tmsize_t count = -1;
if ((tmsize_t)bytes_total != size)
{
errno = EINVAL;
return (tmsize_t)-1;
}
fdh.h = fd;
for (bytes_written = 0; bytes_written < bytes_total; bytes_written += count)
{
const char *buf_offset = (char *)buf + bytes_written;
size_t io_size = bytes_total - bytes_written;
if (io_size > TIFF_IO_MAX)
io_size = TIFF_IO_MAX;
/* Below is an obvious false positive of Coverity Scan */
/* coverity[overflow_sink] */
count = write(fdh.fd, buf_offset, (TIFFIOSize_t)io_size);
if (count <= 0)
break;
}
if (count < 0)
return (tmsize_t)-1;
/* Silence Coverity Scan warning about unsigned to signed underflow. */
/* coverity[return_overflow:SUPPRESS] */
return (tmsize_t)bytes_written;
/* return ((tmsize_t) write(fdh.fd, buf, bytes_total)); */
}
static uint64_t _tiffSeekProc(thandle_t fd, uint64_t off, int whence)
{
fd_as_handle_union_t fdh;
_TIFF_off_t off_io = (_TIFF_off_t)off;
if ((uint64_t)off_io != off)
{
errno = EINVAL;
return (uint64_t)-1; /* this is really gross */
}
fdh.h = fd;
return ((uint64_t)_TIFF_lseek_f(fdh.fd, off_io, whence));
}
static int _tiffCloseProc(thandle_t fd)
{
fd_as_handle_union_t fdh;
fdh.h = fd;
return (close(fdh.fd));
}
static uint64_t _tiffSizeProc(thandle_t fd)
{
_TIFF_stat_s sb;
fd_as_handle_union_t fdh;
fdh.h = fd;
if (_TIFF_fstat_f(fdh.fd, &sb) < 0)
return (0);
else
return ((uint64_t)sb.st_size);
}
#ifdef HAVE_MMAP
#include <sys/mman.h>
static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize)
{
uint64_t size64 = _tiffSizeProc(fd);
tmsize_t sizem = (tmsize_t)size64;
if (size64 && (uint64_t)sizem == size64)
{
fd_as_handle_union_t fdh;
fdh.h = fd;
*pbase =
(void *)mmap(0, (size_t)sizem, PROT_READ, MAP_SHARED, fdh.fd, 0);
if (*pbase != (void *)-1)
{
*psize = (tmsize_t)sizem;
return (1);
}
}
return (0);
}
static void _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, void **pbase, toff_t *psize)
{
(void)fd;
(void)pbase;
(void)psize;
return (0);
}
static void _tiffUnmapProc(thandle_t fd, void *base, toff_t size)
{
(void)fd;
(void)base;
(void)size;
}
#endif /* !HAVE_MMAP */
/*
* Open a TIFF file descriptor for read/writing.
*/
TIFF *TIFFFdOpen(int fd, const char *name, const char *mode)
{
return TIFFFdOpenExt(fd, name, mode, NULL);
}
TIFF *TIFFFdOpenExt(int fd, const char *name, const char *mode,
TIFFOpenOptions *opts)
{
TIFF *tif;
fd_as_handle_union_t fdh;
fdh.fd = fd;
tif = TIFFClientOpenExt(name, mode, fdh.h, _tiffReadProc, _tiffWriteProc,
_tiffSeekProc, _tiffCloseProc, _tiffSizeProc,
_tiffMapProc, _tiffUnmapProc, opts);
if (tif)
tif->tif_fd = fd;
return (tif);
}
/*
* Open a TIFF file for read/writing.
*/
TIFF *TIFFOpen(const char *name, const char *mode)
{
return TIFFOpenExt(name, mode, NULL);
}
TIFF *TIFFOpenExt(const char *name, const char *mode, TIFFOpenOptions *opts)
{
static const char module[] = "TIFFOpen";
int m, fd;
TIFF *tif;
m = _TIFFgetMode(opts, NULL, mode, module);
if (m == -1)
return ((TIFF *)0);
/* for cygwin and mingw */
#ifdef O_BINARY
m |= O_BINARY;
#endif
fd = open(name, m, 0666);
if (fd < 0)
{
if (errno > 0 && strerror(errno) != NULL)
{
_TIFFErrorEarly(opts, NULL, module, "%s: %s", name,
strerror(errno));
}
else
{
_TIFFErrorEarly(opts, NULL, module, "%s: Cannot open", name);
}
return ((TIFF *)0);
}
tif = TIFFFdOpenExt((int)fd, name, mode, opts);
if (!tif)
close(fd);
return tif;
}
#ifdef _WIN32
#include <windows.h>
/*
* Open a TIFF file with a Unicode filename, for read/writing.
*/
TIFF *TIFFOpenW(const wchar_t *name, const char *mode)
{
return TIFFOpenWExt(name, mode, NULL);
}
TIFF *TIFFOpenWExt(const wchar_t *name, const char *mode, TIFFOpenOptions *opts)
{
static const char module[] = "TIFFOpenW";
int m, fd;
int mbsize;
char *mbname;
TIFF *tif;
m = _TIFFgetMode(opts, NULL, mode, module);
if (m == -1)
return ((TIFF *)0);
/* for cygwin and mingw */
#ifdef O_BINARY
m |= O_BINARY;
#endif
fd = _wopen(name, m, 0666);
if (fd < 0)
{
_TIFFErrorEarly(opts, NULL, module, "%ls: Cannot open", name);
return ((TIFF *)0);
}
mbname = NULL;
mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL);
if (mbsize > 0)
{
mbname = _TIFFmalloc(mbsize);
if (!mbname)
{
_TIFFErrorEarly(
opts, NULL, module,
"Can't allocate space for filename conversion buffer");
return ((TIFF *)0);
}
WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize, NULL, NULL);
}
tif = TIFFFdOpenExt((int)fd, (mbname != NULL) ? mbname : "<unknown>", mode,
opts);
_TIFFfree(mbname);
if (!tif)
close(fd);
return tif;
}
#endif
void *_TIFFmalloc(tmsize_t s)
{
if (s == 0)
return ((void *)NULL);
return (malloc((size_t)s));
}
void *_TIFFcalloc(tmsize_t nmemb, tmsize_t siz)
{
if (nmemb == 0 || siz == 0)
return ((void *)NULL);
return calloc((size_t)nmemb, (size_t)siz);
}
void _TIFFfree(void *p) { free(p); }
void *_TIFFrealloc(void *p, tmsize_t s) { return (realloc(p, (size_t)s)); }
void _TIFFmemset(void *p, int v, tmsize_t c) { memset(p, v, (size_t)c); }
void _TIFFmemcpy(void *d, const void *s, tmsize_t c)
{
memcpy(d, s, (size_t)c);
}
int _TIFFmemcmp(const void *p1, const void *p2, tmsize_t c)
{
return (memcmp(p1, p2, (size_t)c));
}
static void unixWarningHandler(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 = unixWarningHandler;
static void unixErrorHandler(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 = unixErrorHandler;
+28
View File
@@ -0,0 +1,28 @@
/*
* Copyright (c) 1992-1997 Sam Leffler
* Copyright (c) 1992-1997 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "tiffiop.h"
static const char TIFFVersion[] = TIFFLIB_VERSION_STR;
const char *TIFFGetVersion(void) { return (TIFFVersion); }
+105
View File
@@ -0,0 +1,105 @@
/*
* 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.
*/
#include "tiffiop.h"
TIFFErrorHandlerExt _TIFFwarningHandlerExt = NULL;
TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler handler)
{
TIFFErrorHandler prev = _TIFFwarningHandler;
_TIFFwarningHandler = handler;
return (prev);
}
TIFFErrorHandlerExt TIFFSetWarningHandlerExt(TIFFErrorHandlerExt handler)
{
TIFFErrorHandlerExt prev = _TIFFwarningHandlerExt;
_TIFFwarningHandlerExt = handler;
return (prev);
}
void TIFFWarning(const char *module, const char *fmt, ...)
{
va_list ap;
if (_TIFFwarningHandler)
{
va_start(ap, fmt);
(*_TIFFwarningHandler)(module, fmt, ap);
va_end(ap);
}
if (_TIFFwarningHandlerExt)
{
va_start(ap, fmt);
(*_TIFFwarningHandlerExt)(0, module, fmt, ap);
va_end(ap);
}
}
void TIFFWarningExt(thandle_t fd, const char *module, const char *fmt, ...)
{
va_list ap;
if (_TIFFwarningHandler)
{
va_start(ap, fmt);
(*_TIFFwarningHandler)(module, fmt, ap);
va_end(ap);
}
if (_TIFFwarningHandlerExt)
{
va_start(ap, fmt);
(*_TIFFwarningHandlerExt)(fd, module, fmt, ap);
va_end(ap);
}
}
void TIFFWarningExtR(TIFF *tif, const char *module, const char *fmt, ...)
{
va_list ap;
if (tif && tif->tif_warnhandler)
{
va_start(ap, fmt);
int stop = (*tif->tif_warnhandler)(tif, tif->tif_warnhandler_user_data,
module, fmt, ap);
va_end(ap);
if (stop)
return;
}
if (_TIFFwarningHandler)
{
va_start(ap, fmt);
(*_TIFFwarningHandler)(module, fmt, ap);
va_end(ap);
}
if (_TIFFwarningHandlerExt)
{
va_start(ap, fmt);
(*_TIFFwarningHandlerExt)(tif ? tif->tif_clientdata : 0, module, fmt,
ap);
va_end(ap);
}
}
+917
View File
@@ -0,0 +1,917 @@
/*
* Copyright (c) 2018, Mapbox
* Author: <norman.barker at mapbox.com>
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "tiffiop.h"
#ifdef WEBP_SUPPORT
/*
* TIFF Library.
*
* WEBP Compression Support
*
*/
#include "webp/decode.h"
#include "webp/encode.h"
#include <stdbool.h>
#include <stdio.h>
#define LSTATE_INIT_DECODE 0x01
#define LSTATE_INIT_ENCODE 0x02
/*
* State block for each open TIFF
* file using WEBP compression/decompression.
*/
typedef struct
{
uint16_t nSamples; /* number of samples per pixel */
int read_error; /* whether a read error has occurred, and which should cause
further reads in the same strip/tile to be aborted */
int lossless; /* lossy/lossless compression */
int lossless_exact; /* lossless exact mode. If TRUE, R,G,B values in areas
with alpha = 0 will be preserved */
int quality_level; /* compression level */
WebPPicture sPicture; /* WebP Picture */
WebPConfig sEncoderConfig; /* WebP encoder config */
uint8_t *pBuffer; /* buffer to hold raw data on encoding */
unsigned int buffer_offset; /* current offset into the buffer */
unsigned int buffer_size;
WebPIDecoder *psDecoder; /* WebPIDecoder */
WebPDecBuffer sDecBuffer; /* Decoder buffer */
int last_y; /* Last row decoded */
int state; /* state flags */
TIFFVGetMethod vgetparent; /* super-class method */
TIFFVSetMethod vsetparent; /* super-class method */
} WebPState;
#define LState(tif) ((WebPState *)(tif)->tif_data)
#define DecoderState(tif) LState(tif)
#define EncoderState(tif) LState(tif)
static int TWebPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s);
static int TWebPDatasetWriter(const uint8_t *data, size_t data_size,
const WebPPicture *const picture)
{
static const char module[] = "TWebPDatasetWriter";
TIFF *tif = (TIFF *)(picture->custom_ptr);
if ((tif->tif_rawcc + (tmsize_t)data_size) > tif->tif_rawdatasize)
{
TIFFErrorExtR(
tif, module, "Buffer too small by %" TIFF_SIZE_FORMAT " bytes.",
(size_t)(tif->tif_rawcc + data_size - tif->tif_rawdatasize));
return 0;
}
else
{
_TIFFmemcpy(tif->tif_rawcp, data, data_size);
tif->tif_rawcc += data_size;
tif->tif_rawcp += data_size;
return 1;
}
}
/*
* Encode a chunk of pixels.
*/
static int TWebPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
{
static const char module[] = "TWebPEncode";
WebPState *sp = EncoderState(tif);
(void)s;
assert(sp != NULL);
assert(sp->state == LSTATE_INIT_ENCODE);
if ((uint64_t)sp->buffer_offset + (uint64_t)cc > sp->buffer_size)
{
TIFFErrorExtR(tif, module, "Too many bytes to be written");
return 0;
}
memcpy(sp->pBuffer + sp->buffer_offset, bp, cc);
sp->buffer_offset += (unsigned)cc;
return 1;
}
static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
{
static const char module[] = "WebPDecode";
VP8StatusCode status = VP8_STATUS_OK;
WebPState *sp = DecoderState(tif);
uint32_t segment_width, segment_height;
bool decode_whole_strile = false;
(void)s;
assert(sp != NULL);
assert(sp->state == LSTATE_INIT_DECODE);
if (sp->read_error)
{
memset(op, 0, (size_t)occ);
TIFFErrorExtR(tif, module,
"ZIPDecode: Scanline %" PRIu32 " cannot be read due to "
"previous error",
tif->tif_row);
return 0;
}
if (sp->psDecoder == NULL)
{
TIFFDirectory *td = &tif->tif_dir;
uint32_t buffer_size;
if (isTiled(tif))
{
segment_width = td->td_tilewidth;
segment_height = td->td_tilelength;
}
else
{
segment_width = td->td_imagewidth;
segment_height = td->td_imagelength - tif->tif_row;
if (segment_height > td->td_rowsperstrip)
segment_height = td->td_rowsperstrip;
}
int webp_width, webp_height;
if (!WebPGetInfo(tif->tif_rawcp,
(uint64_t)tif->tif_rawcc > UINT32_MAX
? UINT32_MAX
: (uint32_t)tif->tif_rawcc,
&webp_width, &webp_height))
{
memset(op, 0, (size_t)occ);
sp->read_error = 1;
TIFFErrorExtR(tif, module, "WebPGetInfo() failed");
return 0;
}
if ((uint32_t)webp_width != segment_width ||
(uint32_t)webp_height != segment_height)
{
memset(op, 0, (size_t)occ);
sp->read_error = 1;
TIFFErrorExtR(
tif, module, "WebP blob dimension is %dx%d. Expected %ux%u",
webp_width, webp_height, segment_width, segment_height);
return 0;
}
#if WEBP_DECODER_ABI_VERSION >= 0x0002
WebPDecoderConfig config;
if (!WebPInitDecoderConfig(&config))
{
memset(op, 0, (size_t)occ);
sp->read_error = 1;
TIFFErrorExtR(tif, module, "WebPInitDecoderConfig() failed");
return 0;
}
const bool bWebPGetFeaturesOK =
WebPGetFeatures(tif->tif_rawcp,
(uint64_t)tif->tif_rawcc > UINT32_MAX
? UINT32_MAX
: (uint32_t)tif->tif_rawcc,
&config.input) == VP8_STATUS_OK;
WebPFreeDecBuffer(&config.output);
if (!bWebPGetFeaturesOK)
{
memset(op, 0, (size_t)occ);
sp->read_error = 1;
TIFFErrorExtR(tif, module, "WebPInitDecoderConfig() failed");
return 0;
}
const int webp_bands = config.input.has_alpha ? 4 : 3;
if (webp_bands != sp->nSamples &&
/* We accept the situation where the WebP blob has only 3 bands,
* whereas the raster is 4 bands. This can happen when the alpha
* channel is fully opaque, and WebP decoding works fine in that
* situation.
*/
!(webp_bands == 3 && sp->nSamples == 4))
{
memset(op, 0, (size_t)occ);
sp->read_error = 1;
TIFFErrorExtR(tif, module,
"WebP blob band count is %d. Expected %d", webp_bands,
sp->nSamples);
return 0;
}
#endif
buffer_size = segment_width * segment_height * sp->nSamples;
if (occ == (tmsize_t)buffer_size)
{
/* If decoding the whole strip/tile, we can directly use the */
/* output buffer */
decode_whole_strile = true;
}
else if (sp->pBuffer == NULL || buffer_size > sp->buffer_size)
{
if (sp->pBuffer != NULL)
{
_TIFFfreeExt(tif, sp->pBuffer);
sp->pBuffer = NULL;
}
sp->pBuffer = _TIFFmallocExt(tif, buffer_size);
if (!sp->pBuffer)
{
TIFFErrorExtR(tif, module, "Cannot allocate buffer");
memset(op, 0, (size_t)occ);
sp->read_error = 1;
return 0;
}
sp->buffer_size = buffer_size;
}
sp->last_y = 0;
WebPInitDecBuffer(&sp->sDecBuffer);
sp->sDecBuffer.is_external_memory = 1;
sp->sDecBuffer.width = segment_width;
sp->sDecBuffer.height = segment_height;
sp->sDecBuffer.u.RGBA.rgba = decode_whole_strile ? op : sp->pBuffer;
sp->sDecBuffer.u.RGBA.stride = segment_width * sp->nSamples;
sp->sDecBuffer.u.RGBA.size = buffer_size;
if (sp->nSamples > 3)
{
sp->sDecBuffer.colorspace = MODE_RGBA;
}
else
{
sp->sDecBuffer.colorspace = MODE_RGB;
}
sp->psDecoder = WebPINewDecoder(&sp->sDecBuffer);
if (sp->psDecoder == NULL)
{
memset(op, 0, (size_t)occ);
sp->read_error = 1;
TIFFErrorExtR(tif, module, "Unable to allocate WebP decoder.");
return 0;
}
}
if (occ % sp->sDecBuffer.u.RGBA.stride)
{
// read_error not set here as this is a usage issue that can be
// recovered in a following call.
memset(op, 0, (size_t)occ);
/* Do not set read_error as could potentially be recovered */
TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
return 0;
}
status = WebPIAppend(sp->psDecoder, tif->tif_rawcp, tif->tif_rawcc);
if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED)
{
if (status == VP8_STATUS_INVALID_PARAM)
{
TIFFErrorExtR(tif, module, "Invalid parameter used.");
}
else if (status == VP8_STATUS_OUT_OF_MEMORY)
{
TIFFErrorExtR(tif, module, "Out of memory.");
}
else
{
TIFFErrorExtR(tif, module, "Unrecognized error.");
}
memset(op, 0, (size_t)occ);
sp->read_error = 1;
return 0;
}
else
{
int current_y, stride;
uint8_t *buf;
/* Returns the RGB/A image decoded so far */
buf = WebPIDecGetRGB(sp->psDecoder, &current_y, NULL, NULL, &stride);
if ((buf != NULL) &&
(occ <= (tmsize_t)stride * (current_y - sp->last_y)))
{
const int numberOfExpectedLines =
(int)(occ / sp->sDecBuffer.u.RGBA.stride);
if (decode_whole_strile)
{
if (current_y != numberOfExpectedLines)
{
memset(op, 0, (size_t)occ);
sp->read_error = 1;
TIFFErrorExtR(tif, module,
"Unable to decode WebP data: less lines than "
"expected.");
return 0;
}
}
else
{
memcpy(op, buf + (sp->last_y * stride), occ);
}
tif->tif_rawcp += tif->tif_rawcc;
tif->tif_rawcc = 0;
sp->last_y += numberOfExpectedLines;
if (decode_whole_strile)
{
/* We can now free the decoder as we're completely done */
if (sp->psDecoder != NULL)
{
WebPIDelete(sp->psDecoder);
WebPFreeDecBuffer(&sp->sDecBuffer);
sp->psDecoder = NULL;
}
}
return 1;
}
else
{
memset(op, 0, (size_t)occ);
sp->read_error = 1;
TIFFErrorExtR(tif, module, "Unable to decode WebP data.");
return 0;
}
}
}
static int TWebPFixupTags(TIFF *tif)
{
(void)tif;
if (tif->tif_dir.td_planarconfig != PLANARCONFIG_CONTIG)
{
static const char module[] = "TWebPFixupTags";
TIFFErrorExtR(tif, module,
"TIFF WEBP requires data to be stored contiguously in "
"RGB e.g. RGBRGBRGB "
#if WEBP_ENCODER_ABI_VERSION >= 0x0100
"or RGBARGBARGBA"
#endif
);
return 0;
}
return 1;
}
static int TWebPSetupDecode(TIFF *tif)
{
static const char module[] = "WebPSetupDecode";
uint16_t nBitsPerSample = tif->tif_dir.td_bitspersample;
uint16_t sampleFormat = tif->tif_dir.td_sampleformat;
WebPState *sp = DecoderState(tif);
assert(sp != NULL);
sp->nSamples = tif->tif_dir.td_samplesperpixel;
/* check band count */
if (sp->nSamples != 3
#if WEBP_ENCODER_ABI_VERSION >= 0x0100
&& sp->nSamples != 4
#endif
)
{
TIFFErrorExtR(tif, module,
"WEBP driver doesn't support %d bands. Must be 3 (RGB) "
#if WEBP_ENCODER_ABI_VERSION >= 0x0100
"or 4 (RGBA) "
#endif
"bands.",
sp->nSamples);
return 0;
}
/* check bits per sample and data type */
if ((nBitsPerSample != 8) && (sampleFormat != 1))
{
TIFFErrorExtR(tif, module, "WEBP driver requires 8 bit unsigned data");
return 0;
}
/* if we were last encoding, terminate this mode */
if (sp->state & LSTATE_INIT_ENCODE)
{
WebPPictureFree(&sp->sPicture);
if (sp->pBuffer != NULL)
{
_TIFFfreeExt(tif, sp->pBuffer);
sp->pBuffer = NULL;
}
sp->buffer_offset = 0;
sp->state = 0;
}
sp->state |= LSTATE_INIT_DECODE;
return 1;
}
/*
* Setup state for decoding a strip.
*/
static int TWebPPreDecode(TIFF *tif, uint16_t s)
{
static const char module[] = "TWebPPreDecode";
uint32_t segment_width, segment_height;
WebPState *sp = DecoderState(tif);
TIFFDirectory *td = &tif->tif_dir;
(void)s;
assert(sp != NULL);
if (isTiled(tif))
{
segment_width = td->td_tilewidth;
segment_height = td->td_tilelength;
}
else
{
segment_width = td->td_imagewidth;
segment_height = td->td_imagelength - tif->tif_row;
if (segment_height > td->td_rowsperstrip)
segment_height = td->td_rowsperstrip;
}
if (segment_width > 16383 || segment_height > 16383)
{
TIFFErrorExtR(tif, module,
"WEBP maximum image dimensions are 16383 x 16383.");
return 0;
}
if ((sp->state & LSTATE_INIT_DECODE) == 0)
tif->tif_setupdecode(tif);
if (sp->psDecoder != NULL)
{
WebPIDelete(sp->psDecoder);
WebPFreeDecBuffer(&sp->sDecBuffer);
sp->psDecoder = NULL;
}
sp->read_error = 0;
return 1;
}
static int TWebPSetupEncode(TIFF *tif)
{
static const char module[] = "WebPSetupEncode";
uint16_t nBitsPerSample = tif->tif_dir.td_bitspersample;
uint16_t sampleFormat = tif->tif_dir.td_sampleformat;
WebPState *sp = EncoderState(tif);
assert(sp != NULL);
sp->nSamples = tif->tif_dir.td_samplesperpixel;
/* check band count */
if (sp->nSamples != 3
#if WEBP_ENCODER_ABI_VERSION >= 0x0100
&& sp->nSamples != 4
#endif
)
{
TIFFErrorExtR(tif, module,
"WEBP driver doesn't support %d bands. Must be 3 (RGB) "
#if WEBP_ENCODER_ABI_VERSION >= 0x0100
"or 4 (RGBA) "
#endif
"bands.",
sp->nSamples);
return 0;
}
/* check bits per sample and data type */
if ((nBitsPerSample != 8) || (sampleFormat != SAMPLEFORMAT_UINT))
{
TIFFErrorExtR(tif, module, "WEBP driver requires 8 bit unsigned data");
return 0;
}
if (sp->state & LSTATE_INIT_DECODE)
{
WebPIDelete(sp->psDecoder);
WebPFreeDecBuffer(&sp->sDecBuffer);
sp->psDecoder = NULL;
sp->last_y = 0;
sp->state = 0;
}
sp->state |= LSTATE_INIT_ENCODE;
if (!WebPPictureInit(&sp->sPicture))
{
TIFFErrorExtR(tif, module, "Error initializing WebP picture.");
return 0;
}
if (!WebPConfigInitInternal(&sp->sEncoderConfig, WEBP_PRESET_DEFAULT,
(float)sp->quality_level,
WEBP_ENCODER_ABI_VERSION))
{
TIFFErrorExtR(tif, module,
"Error creating WebP encoder configuration.");
return 0;
}
// WebPConfigInitInternal above sets lossless to false
#if WEBP_ENCODER_ABI_VERSION >= 0x0100
sp->sEncoderConfig.lossless = sp->lossless;
if (sp->lossless)
{
sp->sPicture.use_argb = 1;
#if WEBP_ENCODER_ABI_VERSION >= 0x0209
sp->sEncoderConfig.exact = sp->lossless_exact;
#endif
}
#endif
if (!WebPValidateConfig(&sp->sEncoderConfig))
{
TIFFErrorExtR(tif, module, "Error with WebP encoder configuration.");
return 0;
}
return 1;
}
/*
* Reset encoding state at the start of a strip.
*/
static int TWebPPreEncode(TIFF *tif, uint16_t s)
{
static const char module[] = "TWebPPreEncode";
uint32_t segment_width, segment_height;
WebPState *sp = EncoderState(tif);
TIFFDirectory *td = &tif->tif_dir;
(void)s;
assert(sp != NULL);
if (sp->state != LSTATE_INIT_ENCODE)
tif->tif_setupencode(tif);
/*
* Set encoding parameters for this strip/tile.
*/
if (isTiled(tif))
{
segment_width = td->td_tilewidth;
segment_height = td->td_tilelength;
}
else
{
segment_width = td->td_imagewidth;
segment_height = td->td_imagelength - tif->tif_row;
if (segment_height > td->td_rowsperstrip)
segment_height = td->td_rowsperstrip;
}
if (segment_width > 16383 || segment_height > 16383)
{
TIFFErrorExtR(tif, module,
"WEBP maximum image dimensions are 16383 x 16383.");
return 0;
}
/* set up buffer for raw data */
/* given above check and that nSamples <= 4, buffer_size is <= 1 GB */
sp->buffer_size = segment_width * segment_height * sp->nSamples;
if (sp->pBuffer != NULL)
{
_TIFFfreeExt(tif, sp->pBuffer);
sp->pBuffer = NULL;
}
sp->pBuffer = _TIFFmallocExt(tif, sp->buffer_size);
if (!sp->pBuffer)
{
TIFFErrorExtR(tif, module, "Cannot allocate buffer");
return 0;
}
sp->buffer_offset = 0;
sp->sPicture.width = segment_width;
sp->sPicture.height = segment_height;
sp->sPicture.writer = TWebPDatasetWriter;
sp->sPicture.custom_ptr = tif;
return 1;
}
/*
* Finish off an encoded strip by flushing it.
*/
static int TWebPPostEncode(TIFF *tif)
{
static const char module[] = "WebPPostEncode";
int64_t stride;
WebPState *sp = EncoderState(tif);
assert(sp != NULL);
assert(sp->state == LSTATE_INIT_ENCODE);
stride = (int64_t)sp->sPicture.width * sp->nSamples;
#if WEBP_ENCODER_ABI_VERSION >= 0x0100
if (sp->nSamples == 4)
{
if (!WebPPictureImportRGBA(&sp->sPicture, sp->pBuffer, (int)stride))
{
TIFFErrorExtR(tif, module, "WebPPictureImportRGBA() failed");
return 0;
}
}
else
#endif
if (!WebPPictureImportRGB(&sp->sPicture, sp->pBuffer, (int)stride))
{
TIFFErrorExtR(tif, module, "WebPPictureImportRGB() failed");
return 0;
}
if (!WebPEncode(&sp->sEncoderConfig, &sp->sPicture))
{
#if WEBP_ENCODER_ABI_VERSION >= 0x0100
const char *pszErrorMsg = NULL;
switch (sp->sPicture.error_code)
{
case VP8_ENC_ERROR_OUT_OF_MEMORY:
pszErrorMsg = "Out of memory";
break;
case VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY:
pszErrorMsg = "Out of memory while flushing bits";
break;
case VP8_ENC_ERROR_NULL_PARAMETER:
pszErrorMsg = "A pointer parameter is NULL";
break;
case VP8_ENC_ERROR_INVALID_CONFIGURATION:
pszErrorMsg = "Configuration is invalid";
break;
case VP8_ENC_ERROR_BAD_DIMENSION:
pszErrorMsg = "Picture has invalid width/height";
break;
case VP8_ENC_ERROR_PARTITION0_OVERFLOW:
pszErrorMsg = "Partition is bigger than 512k. Try using less "
"SEGMENTS, or increase PARTITION_LIMIT value";
break;
case VP8_ENC_ERROR_PARTITION_OVERFLOW:
pszErrorMsg = "Partition is bigger than 16M";
break;
case VP8_ENC_ERROR_BAD_WRITE:
pszErrorMsg = "Error while fludshing bytes";
break;
case VP8_ENC_ERROR_FILE_TOO_BIG:
pszErrorMsg = "File is bigger than 4G";
break;
case VP8_ENC_ERROR_USER_ABORT:
pszErrorMsg = "User interrupted";
break;
default:
TIFFErrorExtR(tif, module,
"WebPEncode returned an unknown error code: %d",
sp->sPicture.error_code);
pszErrorMsg = "Unknown WebP error type.";
break;
}
TIFFErrorExtR(tif, module, "WebPEncode() failed : %s", pszErrorMsg);
#else
TIFFErrorExtR(tif, module, "Error in WebPEncode()");
#endif
return 0;
}
sp->sPicture.custom_ptr = NULL;
if (!TIFFFlushData1(tif))
{
TIFFErrorExtR(tif, module, "Error flushing TIFF WebP encoder.");
return 0;
}
return 1;
}
static void TWebPCleanup(TIFF *tif)
{
WebPState *sp = LState(tif);
assert(sp != 0);
tif->tif_tagmethods.vgetfield = sp->vgetparent;
tif->tif_tagmethods.vsetfield = sp->vsetparent;
if (sp->state & LSTATE_INIT_ENCODE)
{
WebPPictureFree(&sp->sPicture);
}
if (sp->psDecoder != NULL)
{
WebPIDelete(sp->psDecoder);
WebPFreeDecBuffer(&sp->sDecBuffer);
sp->psDecoder = NULL;
sp->last_y = 0;
}
if (sp->pBuffer != NULL)
{
_TIFFfreeExt(tif, sp->pBuffer);
sp->pBuffer = NULL;
}
_TIFFfreeExt(tif, tif->tif_data);
tif->tif_data = NULL;
_TIFFSetDefaultCompressionState(tif);
}
static int TWebPVSetField(TIFF *tif, uint32_t tag, va_list ap)
{
static const char module[] = "WebPVSetField";
WebPState *sp = LState(tif);
switch (tag)
{
case TIFFTAG_WEBP_LEVEL:
sp->quality_level = (int)va_arg(ap, int);
if (sp->quality_level <= 0 || sp->quality_level > 100.0f)
{
TIFFWarningExtR(tif, module,
"WEBP_LEVEL should be between 1 and 100");
}
return 1;
case TIFFTAG_WEBP_LOSSLESS:
#if WEBP_ENCODER_ABI_VERSION >= 0x0100
sp->lossless = va_arg(ap, int);
if (sp->lossless)
{
sp->quality_level = 100;
}
return 1;
#else
TIFFErrorExtR(
tif, module,
"Need to upgrade WEBP driver, this version doesn't support "
"lossless compression.");
return 0;
#endif
case TIFFTAG_WEBP_LOSSLESS_EXACT:
#if WEBP_ENCODER_ABI_VERSION >= 0x0209
sp->lossless_exact = va_arg(ap, int);
return 1;
#else
TIFFErrorExtR(
tif, module,
"Need to upgrade WEBP driver, this version doesn't support "
"lossless compression.");
return 0;
#endif
default:
return (*sp->vsetparent)(tif, tag, ap);
}
/*NOTREACHED*/
}
static int TWebPVGetField(TIFF *tif, uint32_t tag, va_list ap)
{
WebPState *sp = LState(tif);
switch (tag)
{
case TIFFTAG_WEBP_LEVEL:
*va_arg(ap, int *) = sp->quality_level;
break;
case TIFFTAG_WEBP_LOSSLESS:
*va_arg(ap, int *) = sp->lossless;
break;
case TIFFTAG_WEBP_LOSSLESS_EXACT:
*va_arg(ap, int *) = sp->lossless_exact;
break;
default:
return (*sp->vgetparent)(tif, tag, ap);
}
return 1;
}
static const TIFFField TWebPFields[] = {
{TIFFTAG_WEBP_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO, TRUE,
FALSE, "WEBP quality", NULL},
{TIFFTAG_WEBP_LOSSLESS, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO,
TRUE, FALSE, "WEBP lossless/lossy", NULL},
{TIFFTAG_WEBP_LOSSLESS_EXACT, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
FIELD_PSEUDO, TRUE, FALSE, "WEBP exact lossless", NULL},
};
int TIFFInitWebP(TIFF *tif, int scheme)
{
static const char module[] = "TIFFInitWebP";
WebPState *sp;
(void)scheme;
assert(scheme == COMPRESSION_WEBP);
/*
* Merge codec-specific tag information.
*/
if (!_TIFFMergeFields(tif, TWebPFields, TIFFArrayCount(TWebPFields)))
{
TIFFErrorExtR(tif, module, "Merging WebP codec-specific tags failed");
return 0;
}
/*
* Allocate state block so tag methods have storage to record values.
*/
tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(WebPState));
if (tif->tif_data == NULL)
goto bad;
sp = LState(tif);
/*
* Override parent get/set field methods.
*/
sp->vgetparent = tif->tif_tagmethods.vgetfield;
tif->tif_tagmethods.vgetfield = TWebPVGetField; /* hook for codec tags */
sp->vsetparent = tif->tif_tagmethods.vsetfield;
tif->tif_tagmethods.vsetfield = TWebPVSetField; /* hook for codec tags */
/* Default values for codec-specific fields */
sp->quality_level = 75; /* default comp. level */
sp->lossless = 0; /* default to false */
sp->lossless_exact = 1; /* exact lossless mode (if lossless enabled) */
sp->state = 0;
sp->nSamples = 0;
sp->psDecoder = NULL;
sp->last_y = 0;
sp->buffer_offset = 0;
sp->pBuffer = NULL;
/*
* Install codec methods.
* Notes:
* encoderow is not supported
*/
tif->tif_fixuptags = TWebPFixupTags;
tif->tif_setupdecode = TWebPSetupDecode;
tif->tif_predecode = TWebPPreDecode;
tif->tif_decoderow = TWebPDecode;
tif->tif_decodestrip = TWebPDecode;
tif->tif_decodetile = TWebPDecode;
tif->tif_setupencode = TWebPSetupEncode;
tif->tif_preencode = TWebPPreEncode;
tif->tif_postencode = TWebPPostEncode;
tif->tif_encoderow = TWebPEncode;
tif->tif_encodestrip = TWebPEncode;
tif->tif_encodetile = TWebPEncode;
tif->tif_cleanup = TWebPCleanup;
return 1;
bad:
TIFFErrorExtR(tif, module, "No space for WebP state block");
return 0;
}
#endif /* WEBP_SUPPORT */
+431
View File
@@ -0,0 +1,431 @@
/*
* 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 Win32-specific Routines. Adapted from tif_unix.c 4/5/95 by
* Scott Wagner (wagner@itek.com), Itek Graphix, Rochester, NY USA
*/
#ifdef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
#undef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
#endif
#include "tiffiop.h"
#include <stdlib.h>
#include <windows.h>
/*
CreateFileA/CreateFileW return type 'HANDLE' while TIFFFdOpen() takes 'int',
which is formally incompatible and can even seemingly be of different size:
HANDLE is 64 bit under Win64, while int is still 32 bits there.
However, only the lower 32 bits of a HANDLE are significant under Win64 as,
for interoperability reasons, they must have the same values in 32- and
64-bit programs running on the same system, see
https://docs.microsoft.com/en-us/windows/win32/winprog64/interprocess-communication
Because of this, it is safe to define the following trivial functions for
casting between ints and HANDLEs, which are only really needed to avoid
compiler warnings (and, perhaps, to make the code slightly more clear).
Note that using the intermediate cast to "intptr_t" is crucial for warning
avoidance, as this integer type has the same size as HANDLE in all builds.
*/
static inline thandle_t thandle_from_int(int ifd)
{
return (thandle_t)(intptr_t)ifd;
}
static inline int thandle_to_int(thandle_t fd) { return (int)(intptr_t)fd; }
static tmsize_t _tiffReadProc(thandle_t fd, void *buf, tmsize_t size)
{
/* 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_t *ma;
uint64_t mb;
DWORD n;
DWORD o;
tmsize_t p;
ma = (uint8_t *)buf;
mb = size;
p = 0;
while (mb > 0)
{
n = 0x80000000UL;
if ((uint64_t)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 tmsize_t _tiffWriteProc(thandle_t fd, void *buf, tmsize_t size)
{
/* 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_t *ma;
uint64_t mb;
DWORD n;
DWORD o;
tmsize_t p;
ma = (uint8_t *)buf;
mb = size;
p = 0;
while (mb > 0)
{
n = 0x80000000UL;
if ((uint64_t)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 uint64_t _tiffSeekProc(thandle_t fd, uint64_t off, int whence)
{
LARGE_INTEGER offli;
DWORD dwMoveMethod;
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;
}
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 _tiffCloseProc(thandle_t fd) { return (CloseHandle(fd) ? 0 : -1); }
static uint64_t _tiffSizeProc(thandle_t fd)
{
LARGE_INTEGER m;
if (GetFileSizeEx(fd, &m))
return (m.QuadPart);
else
return (0);
}
/*
* From "Hermann Josef Hill" <lhill@rhein-zeitung.de>:
*
* Windows uses both a handle and a pointer for file mapping,
* but according to the SDK documentation and Richter's book
* "Advanced Windows Programming" it is safe to free the handle
* after obtaining the file mapping pointer
*
* This removes a nasty OS dependency and cures a problem
* with Visual C++ 5.0
*/
static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize)
{
uint64_t size;
tmsize_t sizem;
HANDLE hMapFile;
size = _tiffSizeProc(fd);
sizem = (tmsize_t)size;
if (!size || (uint64_t)sizem != size)
return (0);
/* 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);
CloseHandle(hMapFile);
if (*pbase == NULL)
return (0);
*psize = size;
return (1);
}
static void _tiffUnmapProc(thandle_t fd, void *base, toff_t size)
{
(void)fd;
(void)size;
UnmapViewOfFile(base);
}
/*
* Open a TIFF file descriptor for read/writing.
* Note that TIFFFdOpen and TIFFOpen recognise the character 'u' in the mode
* string, which forces the file to be opened unmapped.
*/
TIFF *TIFFFdOpen(int ifd, const char *name, const char *mode)
{
return TIFFFdOpenExt(ifd, name, mode, NULL);
}
TIFF *TIFFFdOpenExt(int ifd, const char *name, const char *mode,
TIFFOpenOptions *opts)
{
TIFF *tif;
int fSuppressMap;
int m;
fSuppressMap = 0;
for (m = 0; mode[m] != 0; m++)
{
if (mode[m] == 'u')
{
fSuppressMap = 1;
break;
}
}
tif = TIFFClientOpenExt(
name, mode, thandle_from_int(ifd), _tiffReadProc, _tiffWriteProc,
_tiffSeekProc, _tiffCloseProc, _tiffSizeProc,
fSuppressMap ? _tiffDummyMapProc : _tiffMapProc,
fSuppressMap ? _tiffDummyUnmapProc : _tiffUnmapProc, opts);
if (tif)
tif->tif_fd = ifd;
return (tif);
}
#ifndef _WIN32_WCE
/*
* Open a TIFF file for read/writing.
*/
TIFF *TIFFOpen(const char *name, const char *mode)
{
return TIFFOpenExt(name, mode, NULL);
}
TIFF *TIFFOpenExt(const char *name, const char *mode, TIFFOpenOptions *opts)
{
static const char module[] = "TIFFOpen";
thandle_t fd;
int m;
DWORD dwMode;
TIFF *tif;
m = _TIFFgetMode(opts, NULL, mode, module);
switch (m)
{
case O_RDONLY:
dwMode = OPEN_EXISTING;
break;
case O_RDWR:
dwMode = OPEN_EXISTING;
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,
(m == O_RDONLY) ? FILE_ATTRIBUTE_READONLY : FILE_ATTRIBUTE_NORMAL,
NULL);
if (fd == INVALID_HANDLE_VALUE)
{
_TIFFErrorEarly(opts, NULL, module, "%s: Cannot open", name);
return ((TIFF *)0);
}
tif = TIFFFdOpenExt(thandle_to_int(fd), name, mode, opts);
if (!tif)
CloseHandle(fd);
return tif;
}
/*
* Open a TIFF file with a Unicode filename, for read/writing.
*/
TIFF *TIFFOpenW(const wchar_t *name, const char *mode)
{
return TIFFOpenWExt(name, mode, NULL);
}
TIFF *TIFFOpenWExt(const wchar_t *name, const char *mode, TIFFOpenOptions *opts)
{
static const char module[] = "TIFFOpenW";
thandle_t fd;
int m;
DWORD dwMode;
int mbsize;
char *mbname;
TIFF *tif;
m = _TIFFgetMode(opts, NULL, mode, module);
switch (m)
{
case O_RDONLY:
dwMode = OPEN_EXISTING;
break;
case O_RDWR:
dwMode = OPEN_EXISTING;
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)CreateFileW(
name, (m == O_RDONLY) ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE),
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode,
(m == O_RDONLY) ? FILE_ATTRIBUTE_READONLY : FILE_ATTRIBUTE_NORMAL,
NULL);
if (fd == INVALID_HANDLE_VALUE)
{
_TIFFErrorEarly(opts, NULL, module, "%S: Cannot open", name);
return ((TIFF *)0);
}
mbname = NULL;
mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL);
if (mbsize > 0)
{
mbname = (char *)_TIFFmalloc(mbsize);
if (!mbname)
{
_TIFFErrorEarly(
opts, NULL, module,
"Can't allocate space for filename conversion buffer");
return ((TIFF *)0);
}
WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize, NULL, NULL);
}
tif = TIFFFdOpenExt(thandle_to_int(fd),
(mbname != NULL) ? mbname : "<unknown>", mode, opts);
if (!tif)
CloseHandle(fd);
_TIFFfree(mbname);
return tif;
}
#endif /* ndef _WIN32_WCE */
void *_TIFFmalloc(tmsize_t s)
{
if (s == 0)
return ((void *)NULL);
return (malloc((size_t)s));
}
void *_TIFFcalloc(tmsize_t nmemb, tmsize_t siz)
{
if (nmemb == 0 || siz == 0)
return ((void *)NULL);
return calloc((size_t)nmemb, (size_t)siz);
}
void _TIFFfree(void *p) { free(p); }
void *_TIFFrealloc(void *p, tmsize_t s) { return (realloc(p, (size_t)s)); }
void _TIFFmemset(void *p, int v, tmsize_t c) { memset(p, v, (size_t)c); }
void _TIFFmemcpy(void *d, const void *s, tmsize_t c)
{
memcpy(d, s, (size_t)c);
}
int _TIFFmemcmp(const void *p1, const void *p2, tmsize_t c)
{
return (memcmp(p1, p2, (size_t)c));
}
#ifndef _WIN32_WCE
static void Win32WarningHandler(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 = Win32WarningHandler;
static void Win32ErrorHandler(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 = Win32ErrorHandler;
#endif /* ndef _WIN32_WCE */
+965
View File
@@ -0,0 +1,965 @@
/*
* 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.
*
* Scanline-oriented Write Support
*/
#include "tiffiop.h"
#include <stdio.h>
#define STRIPINCR 20 /* expansion factor on strip array */
#define WRITECHECKSTRIPS(tif, module) \
(((tif)->tif_flags & TIFF_BEENWRITING) || TIFFWriteCheck((tif), 0, module))
#define WRITECHECKTILES(tif, module) \
(((tif)->tif_flags & TIFF_BEENWRITING) || TIFFWriteCheck((tif), 1, module))
#define BUFFERCHECK(tif) \
((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) || \
TIFFWriteBufferSetup((tif), NULL, (tmsize_t)-1))
static int TIFFGrowStrips(TIFF *tif, uint32_t delta, const char *module);
static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
tmsize_t cc);
int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
{
static const char module[] = "TIFFWriteScanline";
register TIFFDirectory *td;
int status, imagegrew = 0;
uint32_t strip;
if (!WRITECHECKSTRIPS(tif, module))
return (-1);
/*
* Handle delayed allocation of data buffer. This
* permits it to be sized more intelligently (using
* directory information).
*/
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
* (but only for PlanarConfig=1).
*/
if (row >= td->td_imagelength)
{ /* extend image */
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
{
TIFFErrorExtR(
tif, module,
"Can not change \"ImageLength\" when using separate planes");
return (-1);
}
td->td_imagelength = row + 1;
imagegrew = 1;
}
/*
* Calculate strip and check for crossings.
*/
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
{
if (sample >= td->td_samplesperpixel)
{
TIFFErrorExtR(tif, 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;
}
else
strip = row / td->td_rowsperstrip;
/*
* Check strip array to make sure there's space. We don't support
* dynamically growing files that have data organized in separate
* bitplanes because it's too painful. In that case we require that
* the imagelength be set properly before the first write (so that the
* strips array will be fully allocated above).
*/
if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module))
return (-1);
if (strip != tif->tif_curstrip)
{
/*
* Changing strips -- flush any data present.
*/
if (!TIFFFlushData(tif))
return (-1);
tif->tif_curstrip = strip;
/*
* Watch out for a growing image. The value of strips/image
* will initially be 1 (since it can't be deduced until the
* imagelength is known).
*/
if (strip >= td->td_stripsperimage && imagegrew)
td->td_stripsperimage =
TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);
if (td->td_stripsperimage == 0)
{
TIFFErrorExtR(tif, module, "Zero strips per image");
return (-1);
}
tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
{
if (!(*tif->tif_setupencode)(tif))
return (-1);
tif->tif_flags |= TIFF_CODERSETUP;
}
tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata;
/* this informs TIFFAppendToStrip() we have changed strip */
tif->tif_curoff = 0;
if (!(*tif->tif_preencode)(tif, sample))
return (-1);
tif->tif_flags |= TIFF_POSTENCODE;
}
/*
* Ensure the write is either sequential or at the
* beginning of a strip (or that we can randomly
* access the data -- i.e. no encoding).
*/
if (row != tif->tif_row)
{
if (row < tif->tif_row)
{
/*
* Moving backwards within the same strip:
* backup to the start and then decode
* forward (below).
*/
tif->tif_row =
(strip % td->td_stripsperimage) * td->td_rowsperstrip;
tif->tif_rawcp = tif->tif_rawdata;
}
/*
* Seek forward to the desired row.
*/
if (!(*tif->tif_seek)(tif, row - tif->tif_row))
return (-1);
tif->tif_row = row;
}
/* swab if needed - note that source buffer will be altered */
tif->tif_postdecode(tif, (uint8_t *)buf, tif->tif_scanlinesize);
status = (*tif->tif_encoderow)(tif, (uint8_t *)buf, tif->tif_scanlinesize,
sample);
/* we are now poised at the beginning of the next row */
tif->tif_row = row + 1;
return (status);
}
/* Make sure that at the first attempt of rewriting a tile/strip, we will have
*/
/* more bytes available in the output buffer than the previous byte count, */
/* so that TIFFAppendToStrip() will detect the overflow when it is called the
* first */
/* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
static int _TIFFReserveLargeEnoughWriteBuffer(TIFF *tif, uint32_t strip_or_tile)
{
TIFFDirectory *td = &tif->tif_dir;
if (td->td_stripbytecount_p[strip_or_tile] > 0)
{
/* The +1 is to ensure at least one extra bytes */
/* The +4 is because the LZW encoder flushes 4 bytes before the limit */
uint64_t safe_buffer_size =
(uint64_t)(td->td_stripbytecount_p[strip_or_tile] + 1 + 4);
if (tif->tif_rawdatasize <= (tmsize_t)safe_buffer_size)
{
if (!(TIFFWriteBufferSetup(
tif, NULL,
(tmsize_t)TIFFroundup_64(safe_buffer_size, 1024))))
return 0;
}
}
return 1;
}
/*
* Encode the supplied data and write it to the
* specified strip.
*
* NB: Image length must be setup before writing.
*/
tmsize_t TIFFWriteEncodedStrip(TIFF *tif, uint32_t strip, void *data,
tmsize_t cc)
{
static const char module[] = "TIFFWriteEncodedStrip";
TIFFDirectory *td = &tif->tif_dir;
uint16_t sample;
if (!WRITECHECKSTRIPS(tif, module))
return ((tmsize_t)-1);
/*
* Check strip array to make sure there's space.
* We don't support dynamically growing files that
* have data organized in separate bitplanes because
* it's too painful. In that case we require that
* the imagelength be set properly before the first
* write (so that the strips array will be fully
* allocated above).
*/
if (strip >= td->td_nstrips)
{
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
{
TIFFErrorExtR(
tif, module,
"Can not grow image by strips when using separate planes");
return ((tmsize_t)-1);
}
if (!TIFFGrowStrips(tif, 1, module))
return ((tmsize_t)-1);
td->td_stripsperimage =
TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);
}
/*
* Handle delayed allocation of data buffer. This
* permits it to be sized according to the directory
* info.
*/
if (!BUFFERCHECK(tif))
return ((tmsize_t)-1);
tif->tif_flags |= TIFF_BUF4WRITE;
tif->tif_curstrip = strip;
/* this informs TIFFAppendToStrip() we have changed or reset strip */
tif->tif_curoff = 0;
if (!_TIFFReserveLargeEnoughWriteBuffer(tif, strip))
{
return ((tmsize_t)(-1));
}
tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata;
if (td->td_stripsperimage == 0)
{
TIFFErrorExtR(tif, module, "Zero strips per image");
return ((tmsize_t)-1);
}
tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
{
if (!(*tif->tif_setupencode)(tif))
return ((tmsize_t)-1);
tif->tif_flags |= TIFF_CODERSETUP;
}
tif->tif_flags &= ~TIFF_POSTENCODE;
/* shortcut to avoid an extra memcpy() */
if (td->td_compression == COMPRESSION_NONE)
{
/* swab if needed - note that source buffer will be altered */
tif->tif_postdecode(tif, (uint8_t *)data, cc);
if (!isFillOrder(tif, td->td_fillorder) &&
(tif->tif_flags & TIFF_NOBITREV) == 0)
TIFFReverseBits((uint8_t *)data, cc);
if (cc > 0 && !TIFFAppendToStrip(tif, strip, (uint8_t *)data, cc))
return ((tmsize_t)-1);
return (cc);
}
sample = (uint16_t)(strip / td->td_stripsperimage);
if (!(*tif->tif_preencode)(tif, sample))
return ((tmsize_t)-1);
/* swab if needed - note that source buffer will be altered */
tif->tif_postdecode(tif, (uint8_t *)data, cc);
if (!(*tif->tif_encodestrip)(tif, (uint8_t *)data, cc, sample))
return ((tmsize_t)-1);
if (!(*tif->tif_postencode)(tif))
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 ((tmsize_t)-1);
tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata;
return (cc);
}
/*
* Write the supplied data to the specified strip.
*
* NB: Image length must be setup before writing.
*/
tmsize_t TIFFWriteRawStrip(TIFF *tif, uint32_t strip, void *data, tmsize_t cc)
{
static const char module[] = "TIFFWriteRawStrip";
TIFFDirectory *td = &tif->tif_dir;
if (!WRITECHECKSTRIPS(tif, module))
return ((tmsize_t)-1);
/*
* Check strip array to make sure there's space.
* We don't support dynamically growing files that
* have data organized in separate bitplanes because
* it's too painful. In that case we require that
* the imagelength be set properly before the first
* write (so that the strips array will be fully
* allocated above).
*/
if (strip >= td->td_nstrips)
{
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
{
TIFFErrorExtR(
tif, module,
"Can not grow image by strips when using separate planes");
return ((tmsize_t)-1);
}
/*
* Watch out for a growing image. The value of
* strips/image will initially be 1 (since it
* can't be deduced until the imagelength is known).
*/
if (strip >= td->td_stripsperimage)
td->td_stripsperimage =
TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);
if (!TIFFGrowStrips(tif, 1, module))
return ((tmsize_t)-1);
}
if (tif->tif_curstrip != strip)
{
tif->tif_curstrip = strip;
/* this informs TIFFAppendToStrip() we have changed or reset strip */
tif->tif_curoff = 0;
}
if (td->td_stripsperimage == 0)
{
TIFFErrorExtR(tif, module, "Zero strips per image");
return ((tmsize_t)-1);
}
tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
return (TIFFAppendToStrip(tif, strip, (uint8_t *)data, cc) ? cc
: (tmsize_t)-1);
}
/*
* Write and compress a tile of data. The
* tile is selected by the (x,y,z,s) coordinates.
*/
tmsize_t TIFFWriteTile(TIFF *tif, void *buf, uint32_t x, uint32_t y, uint32_t z,
uint16_t s)
{
if (!TIFFCheckTile(tif, x, y, z, s))
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.
* This is done because the tile size may not be defined until
* after the output buffer is setup in TIFFWriteBufferSetup.
*/
return (TIFFWriteEncodedTile(tif, TIFFComputeTile(tif, x, y, z, s), buf,
(tmsize_t)(-1)));
}
/*
* Encode the supplied data and write it to the
* specified tile. There must be space for the
* data. The function clamps individual writes
* to a tile to the tile size, but does not (and
* can not) check that multiple writes to the same
* tile do not write more than tile size data.
*
* NB: Image length must be setup before writing; this
* interface does not support automatically growing
* the image on each write (as TIFFWriteScanline does).
*/
tmsize_t TIFFWriteEncodedTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc)
{
static const char module[] = "TIFFWriteEncodedTile";
TIFFDirectory *td;
uint16_t sample;
uint32_t howmany32;
if (!WRITECHECKTILES(tif, module))
return ((tmsize_t)(-1));
td = &tif->tif_dir;
if (tile >= td->td_nstrips)
{
TIFFErrorExtR(tif, 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
* permits it to be sized more intelligently (using
* directory information).
*/
if (!BUFFERCHECK(tif))
return ((tmsize_t)(-1));
tif->tif_flags |= TIFF_BUF4WRITE;
tif->tif_curtile = tile;
/* this informs TIFFAppendToStrip() we have changed or reset tile */
tif->tif_curoff = 0;
if (!_TIFFReserveLargeEnoughWriteBuffer(tif, tile))
{
return ((tmsize_t)(-1));
}
tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata;
/*
* Compute tiles per row & per column to compute
* current row and column
*/
howmany32 = TIFFhowmany_32(td->td_imagelength, td->td_tilelength);
if (howmany32 == 0)
{
TIFFErrorExtR(tif, module, "Zero tiles");
return ((tmsize_t)(-1));
}
tif->tif_row = (tile % howmany32) * td->td_tilelength;
howmany32 = TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth);
if (howmany32 == 0)
{
TIFFErrorExtR(tif, module, "Zero tiles");
return ((tmsize_t)(-1));
}
tif->tif_col = (tile % howmany32) * td->td_tilewidth;
if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
{
if (!(*tif->tif_setupencode)(tif))
return ((tmsize_t)(-1));
tif->tif_flags |= TIFF_CODERSETUP;
}
tif->tif_flags &= ~TIFF_POSTENCODE;
/*
* Clamp write amount to the tile size. This is mostly
* done so that callers can pass in some large number
* (e.g. -1) and have the tile size used instead.
*/
if (cc < 1 || cc > tif->tif_tilesize)
cc = tif->tif_tilesize;
/* shortcut to avoid an extra memcpy() */
if (td->td_compression == COMPRESSION_NONE)
{
/* swab if needed - note that source buffer will be altered */
tif->tif_postdecode(tif, (uint8_t *)data, cc);
if (!isFillOrder(tif, td->td_fillorder) &&
(tif->tif_flags & TIFF_NOBITREV) == 0)
TIFFReverseBits((uint8_t *)data, cc);
if (cc > 0 && !TIFFAppendToStrip(tif, tile, (uint8_t *)data, cc))
return ((tmsize_t)-1);
return (cc);
}
sample = (uint16_t)(tile / td->td_stripsperimage);
if (!(*tif->tif_preencode)(tif, sample))
return ((tmsize_t)(-1));
/* swab if needed - note that source buffer will be altered */
tif->tif_postdecode(tif, (uint8_t *)data, cc);
if (!(*tif->tif_encodetile)(tif, (uint8_t *)data, cc, sample))
return ((tmsize_t)-1);
if (!(*tif->tif_postencode)(tif))
return ((tmsize_t)(-1));
if (!isFillOrder(tif, td->td_fillorder) &&
(tif->tif_flags & TIFF_NOBITREV) == 0)
TIFFReverseBits((uint8_t *)tif->tif_rawdata, tif->tif_rawcc);
if (tif->tif_rawcc > 0 &&
!TIFFAppendToStrip(tif, tile, tif->tif_rawdata, tif->tif_rawcc))
return ((tmsize_t)(-1));
tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata;
return (cc);
}
/*
* Write the supplied data to the specified strip.
* There must be space for the data; we don't check
* if strips overlap!
*
* NB: Image length must be setup before writing; this
* interface does not support automatically growing
* the image on each write (as TIFFWriteScanline does).
*/
tmsize_t TIFFWriteRawTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc)
{
static const char module[] = "TIFFWriteRawTile";
if (!WRITECHECKTILES(tif, module))
return ((tmsize_t)(-1));
if (tile >= tif->tif_dir.td_nstrips)
{
TIFFErrorExtR(tif, module, "Tile %lu out of range, max %lu",
(unsigned long)tile,
(unsigned long)tif->tif_dir.td_nstrips);
return ((tmsize_t)(-1));
}
return (TIFFAppendToStrip(tif, tile, (uint8_t *)data, cc) ? cc
: (tmsize_t)(-1));
}
#define isUnspecified(tif, f) \
(TIFFFieldSet(tif, f) && (tif)->tif_dir.td_imagelength == 0)
int TIFFSetupStrips(TIFF *tif)
{
TIFFDirectory *td = &tif->tif_dir;
if (isTiled(tif))
td->td_stripsperimage = isUnspecified(tif, FIELD_TILEDIMENSIONS)
? td->td_samplesperpixel
: TIFFNumberOfTiles(tif);
else
td->td_stripsperimage = isUnspecified(tif, FIELD_ROWSPERSTRIP)
? td->td_samplesperpixel
: TIFFNumberOfStrips(tif);
td->td_nstrips = td->td_stripsperimage;
/* TIFFWriteDirectoryTagData has a limitation to 0x80000000U bytes */
if (td->td_nstrips >=
0x80000000U / ((tif->tif_flags & TIFF_BIGTIFF) ? 0x8U : 0x4U))
{
TIFFErrorExtR(tif, "TIFFSetupStrips",
"Too large Strip/Tile Offsets/ByteCounts arrays");
return 0;
}
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
td->td_stripsperimage /= td->td_samplesperpixel;
if (td->td_stripoffset_p != NULL)
_TIFFfreeExt(tif, td->td_stripoffset_p);
td->td_stripoffset_p = (uint64_t *)_TIFFCheckMalloc(
tif, td->td_nstrips, sizeof(uint64_t), "for \"StripOffsets\" array");
if (td->td_stripbytecount_p != NULL)
_TIFFfreeExt(tif, td->td_stripbytecount_p);
td->td_stripbytecount_p = (uint64_t *)_TIFFCheckMalloc(
tif, td->td_nstrips, sizeof(uint64_t), "for \"StripByteCounts\" array");
if (td->td_stripoffset_p == NULL || td->td_stripbytecount_p == NULL)
return (0);
/*
* Place data at the end-of-file
* (by setting offsets to zero).
*/
_TIFFmemset(td->td_stripoffset_p, 0, td->td_nstrips * sizeof(uint64_t));
_TIFFmemset(td->td_stripbytecount_p, 0, td->td_nstrips * sizeof(uint64_t));
TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
return (1);
}
#undef isUnspecified
/*
* Verify file is writable and that the directory
* information is setup properly. In doing the latter
* we also "freeze" the state of the directory so
* that important information is not changed.
*/
int TIFFWriteCheck(TIFF *tif, int tiles, const char *module)
{
if (tif->tif_mode == O_RDONLY)
{
TIFFErrorExtR(tif, module, "File not open for writing");
return (0);
}
if (tiles ^ isTiled(tif))
{
TIFFErrorExtR(tif, module,
tiles ? "Can not write tiles to a striped image"
: "Can not write scanlines to a tiled image");
return (0);
}
_TIFFFillStriles(tif);
/*
* On the first write verify all the required information
* has been setup and initialize any data structures that
* had to wait until directory information was set.
* Note that a lot of our work is assumed to remain valid
* because we disallow any of the important parameters
* from changing after we start writing (i.e. once
* TIFF_BEENWRITING is set, TIFFSetField will only allow
* the image's length to be changed).
*/
if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS))
{
TIFFErrorExtR(tif, module,
"Must set \"ImageWidth\" before writing data");
return (0);
}
if (tif->tif_dir.td_stripoffset_p == NULL && !TIFFSetupStrips(tif))
{
tif->tif_dir.td_nstrips = 0;
TIFFErrorExtR(tif, module, "No space for %s arrays",
isTiled(tif) ? "tile" : "strip");
return (0);
}
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;
if (tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 &&
!(tif->tif_flags & TIFF_DIRTYDIRECT))
{
TIFFForceStrileArrayWriting(tif);
}
return (1);
}
/*
* Setup the raw data buffer used for encoding.
*/
int TIFFWriteBufferSetup(TIFF *tif, void *bp, tmsize_t size)
{
static const char module[] = "TIFFWriteBufferSetup";
if (tif->tif_rawdata)
{
if (tif->tif_flags & TIFF_MYBUFFER)
{
_TIFFfreeExt(tif, tif->tif_rawdata);
tif->tif_flags &= ~TIFF_MYBUFFER;
}
tif->tif_rawdata = NULL;
}
if (size == (tmsize_t)(-1))
{
size = (isTiled(tif) ? tif->tif_tilesize : TIFFStripSize(tif));
/* Adds 10% margin for cases where compression would expand a bit */
if (size < TIFF_TMSIZE_T_MAX - size / 10)
size += size / 10;
/*
* Make raw data buffer at least 8K
*/
if (size < 8 * 1024)
size = 8 * 1024;
bp = NULL; /* NB: force malloc */
}
if (bp == NULL)
{
bp = _TIFFmallocExt(tif, size);
if (bp == NULL)
{
TIFFErrorExtR(tif, module, "No space for output buffer");
return (0);
}
tif->tif_flags |= TIFF_MYBUFFER;
}
else
tif->tif_flags &= ~TIFF_MYBUFFER;
tif->tif_rawdata = (uint8_t *)bp;
tif->tif_rawdatasize = size;
tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata;
tif->tif_flags |= TIFF_BUFFERSETUP;
return (1);
}
/*
* Grow the strip data structures by delta strips.
*/
static int TIFFGrowStrips(TIFF *tif, uint32_t delta, const char *module)
{
TIFFDirectory *td = &tif->tif_dir;
uint64_t *new_stripoffset;
uint64_t *new_stripbytecount;
assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
new_stripoffset = (uint64_t *)_TIFFreallocExt(
tif, td->td_stripoffset_p, (td->td_nstrips + delta) * sizeof(uint64_t));
new_stripbytecount = (uint64_t *)_TIFFreallocExt(
tif, td->td_stripbytecount_p,
(td->td_nstrips + delta) * sizeof(uint64_t));
if (new_stripoffset == NULL || new_stripbytecount == NULL)
{
if (new_stripoffset)
_TIFFfreeExt(tif, new_stripoffset);
if (new_stripbytecount)
_TIFFfreeExt(tif, new_stripbytecount);
td->td_nstrips = 0;
TIFFErrorExtR(tif, module, "No space to expand strip arrays");
return (0);
}
td->td_stripoffset_p = new_stripoffset;
td->td_stripbytecount_p = new_stripbytecount;
_TIFFmemset(td->td_stripoffset_p + td->td_nstrips, 0,
delta * sizeof(uint64_t));
_TIFFmemset(td->td_stripbytecount_p + td->td_nstrips, 0,
delta * sizeof(uint64_t));
td->td_nstrips += delta;
tif->tif_flags |= TIFF_DIRTYDIRECT;
return (1);
}
/*
* Append the data to the specified strip.
*/
static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
tmsize_t cc)
{
static const char module[] = "TIFFAppendToStrip";
TIFFDirectory *td = &tif->tif_dir;
uint64_t m;
int64_t old_byte_count = -1;
if (tif->tif_curoff == 0)
tif->tif_lastvalidoff = 0;
if (td->td_stripoffset_p[strip] == 0 || tif->tif_curoff == 0)
{
assert(td->td_nstrips > 0);
if (td->td_stripbytecount_p[strip] != 0 &&
td->td_stripoffset_p[strip] != 0 &&
td->td_stripbytecount_p[strip] >= (uint64_t)cc)
{
/*
* There is already tile data on disk, and the new tile
* 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.
*/
if (!SeekOK(tif, td->td_stripoffset_p[strip]))
{
TIFFErrorExtR(tif, module, "Seek error at scanline %lu",
(unsigned long)tif->tif_row);
return (0);
}
tif->tif_lastvalidoff =
td->td_stripoffset_p[strip] + td->td_stripbytecount_p[strip];
}
else
{
/*
* Seek to end of file, and set that as our location to
* write this strip.
*/
td->td_stripoffset_p[strip] = TIFFSeekFile(tif, 0, SEEK_END);
tif->tif_flags |= TIFF_DIRTYSTRIP;
}
tif->tif_curoff = td->td_stripoffset_p[strip];
/*
* We are starting a fresh strip/tile, so set the size to zero.
*/
old_byte_count = td->td_stripbytecount_p[strip];
td->td_stripbytecount_p[strip] = 0;
}
m = tif->tif_curoff + cc;
if (!(tif->tif_flags & TIFF_BIGTIFF))
m = (uint32_t)m;
if ((m < tif->tif_curoff) || (m < (uint64_t)cc))
{
TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
return (0);
}
if (tif->tif_lastvalidoff != 0 && m > tif->tif_lastvalidoff &&
td->td_stripbytecount_p[strip] > 0)
{
/* Ouch: we have detected that we are rewriting in place a strip/tile */
/* with several calls to TIFFAppendToStrip(). The first call was with */
/* a size smaller than the previous size of the strip/tile, so we */
/* opted to rewrite in place, but a following call causes us to go */
/* outsize of the strip/tile area, so we have to finally go for a */
/* append-at-end-of-file strategy, and start by moving what we already
*/
/* wrote. */
tmsize_t tempSize;
void *temp;
uint64_t offsetRead;
uint64_t offsetWrite;
uint64_t toCopy = td->td_stripbytecount_p[strip];
if (toCopy < 1024 * 1024)
tempSize = (tmsize_t)toCopy;
else
tempSize = 1024 * 1024;
offsetRead = td->td_stripoffset_p[strip];
offsetWrite = TIFFSeekFile(tif, 0, SEEK_END);
m = offsetWrite + toCopy + cc;
if (!(tif->tif_flags & TIFF_BIGTIFF) && m != (uint32_t)m)
{
TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
return (0);
}
temp = _TIFFmallocExt(tif, tempSize);
if (temp == NULL)
{
TIFFErrorExtR(tif, module, "No space for output buffer");
return (0);
}
tif->tif_flags |= TIFF_DIRTYSTRIP;
td->td_stripoffset_p[strip] = offsetWrite;
td->td_stripbytecount_p[strip] = 0;
/* Move data written by previous calls to us at end of file */
while (toCopy > 0)
{
if (!SeekOK(tif, offsetRead))
{
TIFFErrorExtR(tif, module, "Seek error");
_TIFFfreeExt(tif, temp);
return (0);
}
if (!ReadOK(tif, temp, tempSize))
{
TIFFErrorExtR(tif, module, "Cannot read");
_TIFFfreeExt(tif, temp);
return (0);
}
if (!SeekOK(tif, offsetWrite))
{
TIFFErrorExtR(tif, module, "Seek error");
_TIFFfreeExt(tif, temp);
return (0);
}
if (!WriteOK(tif, temp, tempSize))
{
TIFFErrorExtR(tif, module, "Cannot write");
_TIFFfreeExt(tif, temp);
return (0);
}
offsetRead += tempSize;
offsetWrite += tempSize;
td->td_stripbytecount_p[strip] += tempSize;
toCopy -= tempSize;
}
_TIFFfreeExt(tif, temp);
/* Append the data of this call */
offsetWrite += cc;
m = offsetWrite;
}
if (!WriteOK(tif, data, cc))
{
TIFFErrorExtR(tif, module, "Write error at scanline %lu",
(unsigned long)tif->tif_row);
return (0);
}
tif->tif_curoff = m;
td->td_stripbytecount_p[strip] += cc;
if ((int64_t)td->td_stripbytecount_p[strip] != old_byte_count)
tif->tif_flags |= TIFF_DIRTYSTRIP;
return (1);
}
/*
* Internal version of TIFFFlushData that can be
* called by ``encodestrip routines'' w/o concern
* for infinite recursion.
*/
int TIFFFlushData1(TIFF *tif)
{
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((uint8_t *)tif->tif_rawdata, tif->tif_rawcc);
if (!TIFFAppendToStrip(
tif, isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip,
tif->tif_rawdata, tif->tif_rawcc))
{
/* We update those variables even in case of error since there's */
/* code that doesn't really check the return code of this */
/* function */
tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata;
return (0);
}
tif->tif_rawcc = 0;
tif->tif_rawcp = tif->tif_rawdata;
}
return (1);
}
/*
* Set the current write offset. This should only be
* used to set the offset to a known previous location
* (very carefully), or to 0 so that the next write gets
* appended to the end of the file.
*/
void TIFFSetWriteOffset(TIFF *tif, toff_t off)
{
tif->tif_curoff = off;
tif->tif_lastvalidoff = 0;
}
+776
View File
@@ -0,0 +1,776 @@
/*
* Copyright (c) 1995-1997 Sam Leffler
* Copyright (c) 1995-1997 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "tiffiop.h"
#ifdef ZIP_SUPPORT
/*
* TIFF Library.
*
* ZIP (aka Deflate) Compression Support
*
* This file is an interface to the zlib library written by
* Jean-loup Gailly and Mark Adler. You must use version 1.0 or later
* of the library.
*
* Optionally, libdeflate (https://github.com/ebiggers/libdeflate) may be used
* to do the compression and decompression, but only for whole strips and tiles.
* For scanline access, zlib will be sued as a fallback.
*/
#include "tif_predict.h"
#include "zlib.h"
#if LIBDEFLATE_SUPPORT
#include "libdeflate.h"
#endif
#define LIBDEFLATE_MAX_COMPRESSION_LEVEL 12
#include <stdio.h>
/*
* Sigh, ZLIB_VERSION is defined as a string so there's no
* way to do a proper check here. Instead we guess based
* on the presence of #defines that were added between the
* 0.95 and 1.0 distributions.
*/
#if !defined(Z_NO_COMPRESSION) || !defined(Z_DEFLATED)
#error "Antiquated ZLIB software; you must use version 1.0 or later"
#endif
#define SAFE_MSG(sp) ((sp)->stream.msg == NULL ? "" : (sp)->stream.msg)
/*
* State block for each open TIFF
* file using ZIP compression/decompression.
*/
typedef struct
{
TIFFPredictorState predict;
z_stream stream;
int read_error; /* whether a read error has occurred, and which should cause
further reads in the same strip/tile to be aborted */
int zipquality; /* compression level */
int state; /* state flags */
int subcodec; /* DEFLATE_SUBCODEC_ZLIB or DEFLATE_SUBCODEC_LIBDEFLATE */
#if LIBDEFLATE_SUPPORT
int libdeflate_state; /* -1 = until first time ZIPEncode() / ZIPDecode() is
called, 0 = use zlib, 1 = use libdeflate */
struct libdeflate_decompressor *libdeflate_dec;
struct libdeflate_compressor *libdeflate_enc;
#endif
#define ZSTATE_INIT_DECODE 0x01
#define ZSTATE_INIT_ENCODE 0x02
TIFFVGetMethod vgetparent; /* super-class method */
TIFFVSetMethod vsetparent; /* super-class method */
} ZIPState;
#define GetZIPState(tif) ((ZIPState *)(tif)->tif_data)
#define ZIPDecoderState(tif) GetZIPState(tif)
#define ZIPEncoderState(tif) GetZIPState(tif)
static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s);
static int ZIPFixupTags(TIFF *tif)
{
(void)tif;
return (1);
}
static int ZIPSetupDecode(TIFF *tif)
{
static const char module[] = "ZIPSetupDecode";
ZIPState *sp = ZIPDecoderState(tif);
assert(sp != NULL);
/* if we were last encoding, terminate this mode */
if (sp->state & ZSTATE_INIT_ENCODE)
{
deflateEnd(&sp->stream);
sp->state = 0;
}
/* This function can possibly be called several times by */
/* PredictorSetupDecode() if this function succeeds but */
/* PredictorSetup() fails */
if ((sp->state & ZSTATE_INIT_DECODE) == 0 &&
inflateInit(&sp->stream) != Z_OK)
{
TIFFErrorExtR(tif, module, "%s", SAFE_MSG(sp));
return (0);
}
else
{
sp->state |= ZSTATE_INIT_DECODE;
return (1);
}
}
static inline uint64_t TIFF_MIN_UINT64(uint64_t a, uint64_t b)
{
return a < b ? a : b;
}
static inline uInt TIFF_CLAMP_UINT64_TO_INT32_MAX(uint64_t v)
{
return (uInt)TIFF_MIN_UINT64(v, INT32_MAX);
}
/*
* Setup state for decoding a strip.
*/
static int ZIPPreDecode(TIFF *tif, uint16_t s)
{
ZIPState *sp = ZIPDecoderState(tif);
(void)s;
assert(sp != NULL);
if ((sp->state & ZSTATE_INIT_DECODE) == 0)
tif->tif_setupdecode(tif);
#if LIBDEFLATE_SUPPORT
sp->libdeflate_state = -1;
#endif
sp->stream.next_in = tif->tif_rawdata;
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
appropriately even before we simplify it */
sp->stream.avail_in = TIFF_CLAMP_UINT64_TO_INT32_MAX(tif->tif_rawcc);
if (inflateReset(&sp->stream) == Z_OK)
{
sp->read_error = 0;
return 1;
}
return 0;
}
static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
{
static const char module[] = "ZIPDecode";
ZIPState *sp = ZIPDecoderState(tif);
(void)s;
assert(sp != NULL);
assert(sp->state == ZSTATE_INIT_DECODE);
if (sp->read_error)
{
memset(op, 0, (size_t)occ);
TIFFErrorExtR(tif, module,
"ZIPDecode: Scanline %" PRIu32 " cannot be read due to "
"previous error",
tif->tif_row);
return 0;
}
#if LIBDEFLATE_SUPPORT
if (sp->libdeflate_state == 1)
return 0;
/* If we have libdeflate support and we are asked to read a whole */
/* strip/tile, then go for using it */
do
{
TIFFDirectory *td = &tif->tif_dir;
if (sp->libdeflate_state == 0)
break;
if (sp->subcodec == DEFLATE_SUBCODEC_ZLIB)
break;
/* Check if we are in the situation where we can use libdeflate */
if (isTiled(tif))
{
if (TIFFTileSize64(tif) != (uint64_t)occ)
break;
}
else
{
uint32_t strip_height = td->td_imagelength - tif->tif_row;
if (strip_height > td->td_rowsperstrip)
strip_height = td->td_rowsperstrip;
if (TIFFVStripSize64(tif, strip_height) != (uint64_t)occ)
break;
}
/* Check for overflow */
if ((size_t)tif->tif_rawcc != (uint64_t)tif->tif_rawcc)
break;
if ((size_t)occ != (uint64_t)occ)
break;
/* Go for decompression using libdeflate */
{
enum libdeflate_result res;
if (sp->libdeflate_dec == NULL)
{
sp->libdeflate_dec = libdeflate_alloc_decompressor();
if (sp->libdeflate_dec == NULL)
{
break;
}
}
sp->libdeflate_state = 1;
res = libdeflate_zlib_decompress(sp->libdeflate_dec, tif->tif_rawcp,
(size_t)tif->tif_rawcc, op,
(size_t)occ, NULL);
tif->tif_rawcp += tif->tif_rawcc;
tif->tif_rawcc = 0;
/* We accept LIBDEFLATE_INSUFFICIENT_SPACE has a return */
/* There are odd files in the wild where the last strip, when */
/* it is smaller in height than td_rowsperstrip, actually contains
*/
/* data for td_rowsperstrip lines. Just ignore that silently. */
if (res != LIBDEFLATE_SUCCESS &&
res != LIBDEFLATE_INSUFFICIENT_SPACE)
{
memset(op, 0, (size_t)occ);
TIFFErrorExtR(tif, module, "Decoding error at scanline %lu",
(unsigned long)tif->tif_row);
sp->read_error = 1;
return 0;
}
return 1;
}
} while (0);
sp->libdeflate_state = 0;
#endif /* LIBDEFLATE_SUPPORT */
sp->stream.next_in = tif->tif_rawcp;
sp->stream.next_out = op;
assert(sizeof(sp->stream.avail_out) == 4); /* if this assert gets raised,
we need to simplify this code to reflect a ZLib that is likely updated
to deal with 8byte memory sizes, though this code will respond
appropriately even before we simplify it */
do
{
int state;
uInt avail_in_before = TIFF_CLAMP_UINT64_TO_INT32_MAX(tif->tif_rawcc);
uInt avail_out_before = TIFF_CLAMP_UINT64_TO_INT32_MAX(occ);
sp->stream.avail_in = avail_in_before;
sp->stream.avail_out = avail_out_before;
state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
tif->tif_rawcc -= (avail_in_before - sp->stream.avail_in);
occ -= (avail_out_before - sp->stream.avail_out);
if (state == Z_STREAM_END)
break;
if (state == Z_DATA_ERROR)
{
memset(sp->stream.next_out, 0, (size_t)occ);
TIFFErrorExtR(tif, module, "Decoding error at scanline %lu, %s",
(unsigned long)tif->tif_row, SAFE_MSG(sp));
sp->read_error = 1;
return (0);
}
if (state != Z_OK)
{
memset(sp->stream.next_out, 0, (size_t)occ);
TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp));
sp->read_error = 1;
return (0);
}
} while (occ > 0);
if (occ != 0)
{
TIFFErrorExtR(tif, module,
"Not enough data at scanline %lu (short %" PRIu64
" bytes)",
(unsigned long)tif->tif_row, (uint64_t)occ);
memset(sp->stream.next_out, 0, (size_t)occ);
sp->read_error = 1;
return (0);
}
tif->tif_rawcp = sp->stream.next_in;
return (1);
}
static int ZIPSetupEncode(TIFF *tif)
{
static const char module[] = "ZIPSetupEncode";
ZIPState *sp = ZIPEncoderState(tif);
int cappedQuality;
assert(sp != NULL);
if (sp->state & ZSTATE_INIT_DECODE)
{
inflateEnd(&sp->stream);
sp->state = 0;
}
cappedQuality = sp->zipquality;
if (cappedQuality > Z_BEST_COMPRESSION)
cappedQuality = Z_BEST_COMPRESSION;
if (deflateInit(&sp->stream, cappedQuality) != Z_OK)
{
TIFFErrorExtR(tif, module, "%s", SAFE_MSG(sp));
return (0);
}
else
{
sp->state |= ZSTATE_INIT_ENCODE;
return (1);
}
}
/*
* Reset encoding state at the start of a strip.
*/
static int ZIPPreEncode(TIFF *tif, uint16_t s)
{
ZIPState *sp = ZIPEncoderState(tif);
(void)s;
assert(sp != NULL);
if (sp->state != ZSTATE_INIT_ENCODE)
tif->tif_setupencode(tif);
#if LIBDEFLATE_SUPPORT
sp->libdeflate_state = -1;
#endif
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
appropriately even before we simplify it */
sp->stream.avail_out = (uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU
? (uInt)tif->tif_rawdatasize
: 0xFFFFFFFFU;
return (deflateReset(&sp->stream) == Z_OK);
}
/*
* Encode a chunk of pixels.
*/
static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
{
static const char module[] = "ZIPEncode";
ZIPState *sp = ZIPEncoderState(tif);
assert(sp != NULL);
assert(sp->state == ZSTATE_INIT_ENCODE);
(void)s;
#if LIBDEFLATE_SUPPORT
if (sp->libdeflate_state == 1)
return 0;
/* If we have libdeflate support and we are asked to write a whole */
/* strip/tile, then go for using it */
do
{
TIFFDirectory *td = &tif->tif_dir;
if (sp->libdeflate_state == 0)
break;
if (sp->subcodec == DEFLATE_SUBCODEC_ZLIB)
break;
/* Libdeflate does not support the 0-compression level */
if (sp->zipquality == Z_NO_COMPRESSION)
break;
/* Check if we are in the situation where we can use libdeflate */
if (isTiled(tif))
{
if (TIFFTileSize64(tif) != (uint64_t)cc)
break;
}
else
{
uint32_t strip_height = td->td_imagelength - tif->tif_row;
if (strip_height > td->td_rowsperstrip)
strip_height = td->td_rowsperstrip;
if (TIFFVStripSize64(tif, strip_height) != (uint64_t)cc)
break;
}
/* Check for overflow */
if ((size_t)tif->tif_rawdatasize != (uint64_t)tif->tif_rawdatasize)
break;
if ((size_t)cc != (uint64_t)cc)
break;
/* Go for compression using libdeflate */
{
size_t nCompressedBytes;
if (sp->libdeflate_enc == NULL)
{
/* To get results as good as zlib, we asked for an extra */
/* level of compression */
sp->libdeflate_enc = libdeflate_alloc_compressor(
sp->zipquality == Z_DEFAULT_COMPRESSION ? 7
: sp->zipquality >= 6 && sp->zipquality <= 9
? sp->zipquality + 1
: sp->zipquality);
if (sp->libdeflate_enc == NULL)
{
TIFFErrorExtR(tif, module, "Cannot allocate compressor");
break;
}
}
/* Make sure the output buffer is large enough for the worse case.
*/
/* In TIFFWriteBufferSetup(), when libtiff allocates the buffer */
/* we've taken a 10% margin over the uncompressed size, which should
*/
/* be large enough even for the the worse case scenario. */
if (libdeflate_zlib_compress_bound(sp->libdeflate_enc, (size_t)cc) >
(size_t)tif->tif_rawdatasize)
{
break;
}
sp->libdeflate_state = 1;
nCompressedBytes = libdeflate_zlib_compress(
sp->libdeflate_enc, bp, (size_t)cc, tif->tif_rawdata,
(size_t)tif->tif_rawdatasize);
if (nCompressedBytes == 0)
{
TIFFErrorExtR(tif, module, "Encoder error at scanline %lu",
(unsigned long)tif->tif_row);
return 0;
}
tif->tif_rawcc = nCompressedBytes;
if (!TIFFFlushData1(tif))
return 0;
return 1;
}
} while (0);
sp->libdeflate_state = 0;
#endif /* LIBDEFLATE_SUPPORT */
sp->stream.next_in = bp;
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
appropriately even before we simplify it */
do
{
uInt avail_in_before = TIFF_CLAMP_UINT64_TO_INT32_MAX(cc);
sp->stream.avail_in = avail_in_before;
if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK)
{
TIFFErrorExtR(tif, module, "Encoder error: %s", SAFE_MSG(sp));
return (0);
}
if (sp->stream.avail_out == 0)
{
tif->tif_rawcc = tif->tif_rawdatasize;
if (!TIFFFlushData1(tif))
return 0;
sp->stream.next_out = tif->tif_rawdata;
sp->stream.avail_out =
TIFF_CLAMP_UINT64_TO_INT32_MAX(tif->tif_rawdatasize);
}
cc -= (avail_in_before - sp->stream.avail_in);
} while (cc > 0);
return (1);
}
/*
* Finish off an encoded strip by flushing the last
* string and tacking on an End Of Information code.
*/
static int ZIPPostEncode(TIFF *tif)
{
static const char module[] = "ZIPPostEncode";
ZIPState *sp = ZIPEncoderState(tif);
int state;
#if LIBDEFLATE_SUPPORT
if (sp->libdeflate_state == 1)
return 1;
#endif
sp->stream.avail_in = 0;
do
{
state = deflate(&sp->stream, Z_FINISH);
switch (state)
{
case Z_STREAM_END:
case Z_OK:
if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
{
tif->tif_rawcc =
tif->tif_rawdatasize - sp->stream.avail_out;
if (!TIFFFlushData1(tif))
return 0;
sp->stream.next_out = tif->tif_rawdata;
sp->stream.avail_out =
(uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU
? (uInt)tif->tif_rawdatasize
: 0xFFFFFFFFU;
}
break;
default:
TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp));
return (0);
}
} while (state != Z_STREAM_END);
return (1);
}
static void ZIPCleanup(TIFF *tif)
{
ZIPState *sp = GetZIPState(tif);
assert(sp != 0);
(void)TIFFPredictorCleanup(tif);
tif->tif_tagmethods.vgetfield = sp->vgetparent;
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;
}
#if LIBDEFLATE_SUPPORT
if (sp->libdeflate_dec)
libdeflate_free_decompressor(sp->libdeflate_dec);
if (sp->libdeflate_enc)
libdeflate_free_compressor(sp->libdeflate_enc);
#endif
_TIFFfreeExt(tif, sp);
tif->tif_data = NULL;
_TIFFSetDefaultCompressionState(tif);
}
static int ZIPVSetField(TIFF *tif, uint32_t tag, va_list ap)
{
static const char module[] = "ZIPVSetField";
ZIPState *sp = GetZIPState(tif);
switch (tag)
{
case TIFFTAG_ZIPQUALITY:
sp->zipquality = (int)va_arg(ap, int);
if (sp->zipquality < Z_DEFAULT_COMPRESSION ||
sp->zipquality > LIBDEFLATE_MAX_COMPRESSION_LEVEL)
{
TIFFErrorExtR(
tif, module,
"Invalid ZipQuality value. Should be in [-1,%d] range",
LIBDEFLATE_MAX_COMPRESSION_LEVEL);
return 0;
}
if (sp->state & ZSTATE_INIT_ENCODE)
{
int cappedQuality = sp->zipquality;
if (cappedQuality > Z_BEST_COMPRESSION)
cappedQuality = Z_BEST_COMPRESSION;
if (deflateParams(&sp->stream, cappedQuality,
Z_DEFAULT_STRATEGY) != Z_OK)
{
TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp));
return (0);
}
}
#if LIBDEFLATE_SUPPORT
if (sp->libdeflate_enc)
{
libdeflate_free_compressor(sp->libdeflate_enc);
sp->libdeflate_enc = NULL;
}
#endif
return (1);
case TIFFTAG_DEFLATE_SUBCODEC:
sp->subcodec = (int)va_arg(ap, int);
if (sp->subcodec != DEFLATE_SUBCODEC_ZLIB &&
sp->subcodec != DEFLATE_SUBCODEC_LIBDEFLATE)
{
TIFFErrorExtR(tif, module, "Invalid DeflateCodec value.");
return 0;
}
#if !LIBDEFLATE_SUPPORT
if (sp->subcodec == DEFLATE_SUBCODEC_LIBDEFLATE)
{
TIFFErrorExtR(tif, module,
"DeflateCodec = DEFLATE_SUBCODEC_LIBDEFLATE "
"unsupported in this build");
return 0;
}
#endif
return 1;
default:
return (*sp->vsetparent)(tif, tag, ap);
}
/*NOTREACHED*/
}
static int ZIPVGetField(TIFF *tif, uint32_t tag, va_list ap)
{
ZIPState *sp = GetZIPState(tif);
switch (tag)
{
case TIFFTAG_ZIPQUALITY:
*va_arg(ap, int *) = sp->zipquality;
break;
case TIFFTAG_DEFLATE_SUBCODEC:
*va_arg(ap, int *) = sp->subcodec;
break;
default:
return (*sp->vgetparent)(tif, tag, ap);
}
return (1);
}
static const TIFFField zipFields[] = {
{TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO, TRUE,
FALSE, "", NULL},
{TIFFTAG_DEFLATE_SUBCODEC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO,
TRUE, FALSE, "", NULL},
};
static void *TIFF_zalloc(void *opaque, unsigned int items, unsigned int size)
{
static const char module[] = "TIFF_zalloc";
TIFF *tif = opaque;
if (items > ~(size_t)0 / size)
{
TIFFErrorExtR(tif, module, "Overflow");
return NULL;
}
return _TIFFmallocExt(tif, items * size);
}
static void TIFF_zfree(void *opaque, void *ptr)
{
_TIFFfreeExt((TIFF *)opaque, ptr);
}
int TIFFInitZIP(TIFF *tif, int scheme)
{
static const char module[] = "TIFFInitZIP";
ZIPState *sp;
assert((scheme == COMPRESSION_DEFLATE) ||
(scheme == COMPRESSION_ADOBE_DEFLATE));
#ifdef NDEBUG
(void)scheme;
#endif
/*
* Merge codec-specific tag information.
*/
if (!_TIFFMergeFields(tif, zipFields, TIFFArrayCount(zipFields)))
{
TIFFErrorExtR(tif, module,
"Merging Deflate codec-specific tags failed");
return 0;
}
/*
* Allocate state block so tag methods have storage to record values.
*/
tif->tif_data = (uint8_t *)_TIFFcallocExt(tif, sizeof(ZIPState), 1);
if (tif->tif_data == NULL)
goto bad;
sp = GetZIPState(tif);
sp->stream.zalloc = TIFF_zalloc;
sp->stream.zfree = TIFF_zfree;
sp->stream.opaque = tif;
sp->stream.data_type = Z_BINARY;
/*
* Override parent get/set field methods.
*/
sp->vgetparent = tif->tif_tagmethods.vgetfield;
tif->tif_tagmethods.vgetfield = ZIPVGetField; /* hook for codec tags */
sp->vsetparent = tif->tif_tagmethods.vsetfield;
tif->tif_tagmethods.vsetfield = ZIPVSetField; /* hook for codec tags */
/* Default values for codec-specific fields */
sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */
sp->state = 0;
#if LIBDEFLATE_SUPPORT
sp->subcodec = DEFLATE_SUBCODEC_LIBDEFLATE;
#else
sp->subcodec = DEFLATE_SUBCODEC_ZLIB;
#endif
/*
* 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_setupencode = ZIPSetupEncode;
tif->tif_preencode = ZIPPreEncode;
tif->tif_postencode = ZIPPostEncode;
tif->tif_encoderow = ZIPEncode;
tif->tif_encodestrip = ZIPEncode;
tif->tif_encodetile = ZIPEncode;
tif->tif_cleanup = ZIPCleanup;
/*
* Setup predictor setup.
*/
(void)TIFFPredictorInit(tif);
return (1);
bad:
TIFFErrorExtR(tif, module, "No space for ZIP state block");
return (0);
}
#endif /* ZIP_SUPPORT */
+437
View File
@@ -0,0 +1,437 @@
/*
* Copyright (c) 2017, Planet Labs
* Author: <even.rouault at spatialys.com>
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "tiffiop.h"
#ifdef ZSTD_SUPPORT
/*
* TIFF Library.
*
* ZSTD Compression Support
*
*/
#include "tif_predict.h"
#include "zstd.h"
#include <stdio.h>
/*
* State block for each open TIFF file using ZSTD compression/decompression.
*/
typedef struct
{
TIFFPredictorState predict;
ZSTD_DStream *dstream;
ZSTD_CStream *cstream;
int compression_level; /* compression level */
ZSTD_outBuffer out_buffer;
int state; /* state flags */
#define LSTATE_INIT_DECODE 0x01
#define LSTATE_INIT_ENCODE 0x02
TIFFVGetMethod vgetparent; /* super-class method */
TIFFVSetMethod vsetparent; /* super-class method */
} ZSTDState;
#define GetZSTDState(tif) ((ZSTDState *)(tif)->tif_data)
#define ZSTDDecoderState(tif) GetZSTDState(tif)
#define ZSTDEncoderState(tif) GetZSTDState(tif)
static int ZSTDEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
static int ZSTDDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s);
static int ZSTDFixupTags(TIFF *tif)
{
(void)tif;
return 1;
}
static int ZSTDSetupDecode(TIFF *tif)
{
ZSTDState *sp = ZSTDDecoderState(tif);
assert(sp != NULL);
/* if we were last encoding, terminate this mode */
if (sp->state & LSTATE_INIT_ENCODE)
{
ZSTD_freeCStream(sp->cstream);
sp->cstream = NULL;
sp->state = 0;
}
sp->state |= LSTATE_INIT_DECODE;
return 1;
}
/*
* Setup state for decoding a strip.
*/
static int ZSTDPreDecode(TIFF *tif, uint16_t s)
{
static const char module[] = "ZSTDPreDecode";
ZSTDState *sp = ZSTDDecoderState(tif);
size_t zstd_ret;
(void)s;
assert(sp != NULL);
if ((sp->state & LSTATE_INIT_DECODE) == 0)
tif->tif_setupdecode(tif);
if (sp->dstream == NULL)
{
sp->dstream = ZSTD_createDStream();
if (sp->dstream == NULL)
{
TIFFErrorExtR(tif, module, "Cannot allocate decompression stream");
return 0;
}
}
zstd_ret = ZSTD_initDStream(sp->dstream);
if (ZSTD_isError(zstd_ret))
{
TIFFErrorExtR(tif, module, "Error in ZSTD_initDStream(): %s",
ZSTD_getErrorName(zstd_ret));
return 0;
}
return 1;
}
static int ZSTDDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
{
static const char module[] = "ZSTDDecode";
ZSTDState *sp = ZSTDDecoderState(tif);
ZSTD_inBuffer in_buffer;
ZSTD_outBuffer out_buffer;
size_t zstd_ret;
(void)s;
assert(sp != NULL);
assert(sp->state == LSTATE_INIT_DECODE);
in_buffer.src = tif->tif_rawcp;
in_buffer.size = (size_t)tif->tif_rawcc;
in_buffer.pos = 0;
out_buffer.dst = op;
out_buffer.size = (size_t)occ;
out_buffer.pos = 0;
do
{
zstd_ret = ZSTD_decompressStream(sp->dstream, &out_buffer, &in_buffer);
if (ZSTD_isError(zstd_ret))
{
memset(op + out_buffer.pos, 0, out_buffer.size - out_buffer.pos);
TIFFErrorExtR(tif, module, "Error in ZSTD_decompressStream(): %s",
ZSTD_getErrorName(zstd_ret));
return 0;
}
} while (zstd_ret != 0 && in_buffer.pos < in_buffer.size &&
out_buffer.pos < out_buffer.size);
if (out_buffer.pos < (size_t)occ)
{
memset(op + out_buffer.pos, 0, out_buffer.size - out_buffer.pos);
TIFFErrorExtR(tif, module,
"Not enough data at scanline %lu (short %lu bytes)",
(unsigned long)tif->tif_row,
(unsigned long)((size_t)occ - out_buffer.pos));
return 0;
}
tif->tif_rawcp += in_buffer.pos;
tif->tif_rawcc -= in_buffer.pos;
return 1;
}
static int ZSTDSetupEncode(TIFF *tif)
{
ZSTDState *sp = ZSTDEncoderState(tif);
assert(sp != NULL);
if (sp->state & LSTATE_INIT_DECODE)
{
ZSTD_freeDStream(sp->dstream);
sp->dstream = NULL;
sp->state = 0;
}
sp->state |= LSTATE_INIT_ENCODE;
return 1;
}
/*
* Reset encoding state at the start of a strip.
*/
static int ZSTDPreEncode(TIFF *tif, uint16_t s)
{
static const char module[] = "ZSTDPreEncode";
ZSTDState *sp = ZSTDEncoderState(tif);
size_t zstd_ret;
(void)s;
assert(sp != NULL);
if (sp->state != LSTATE_INIT_ENCODE)
tif->tif_setupencode(tif);
if (sp->cstream == NULL)
{
sp->cstream = ZSTD_createCStream();
if (sp->cstream == NULL)
{
TIFFErrorExtR(tif, module, "Cannot allocate compression stream");
return 0;
}
}
zstd_ret = ZSTD_initCStream(sp->cstream, sp->compression_level);
if (ZSTD_isError(zstd_ret))
{
TIFFErrorExtR(tif, module, "Error in ZSTD_initCStream(): %s",
ZSTD_getErrorName(zstd_ret));
return 0;
}
sp->out_buffer.dst = tif->tif_rawdata;
sp->out_buffer.size = (size_t)tif->tif_rawdatasize;
sp->out_buffer.pos = 0;
return 1;
}
/*
* Encode a chunk of pixels.
*/
static int ZSTDEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
{
static const char module[] = "ZSTDEncode";
ZSTDState *sp = ZSTDEncoderState(tif);
ZSTD_inBuffer in_buffer;
size_t zstd_ret;
assert(sp != NULL);
assert(sp->state == LSTATE_INIT_ENCODE);
(void)s;
in_buffer.src = bp;
in_buffer.size = (size_t)cc;
in_buffer.pos = 0;
do
{
zstd_ret =
ZSTD_compressStream(sp->cstream, &sp->out_buffer, &in_buffer);
if (ZSTD_isError(zstd_ret))
{
TIFFErrorExtR(tif, module, "Error in ZSTD_compressStream(): %s",
ZSTD_getErrorName(zstd_ret));
return 0;
}
if (sp->out_buffer.pos == sp->out_buffer.size)
{
tif->tif_rawcc = tif->tif_rawdatasize;
if (!TIFFFlushData1(tif))
return 0;
sp->out_buffer.dst = tif->tif_rawcp;
sp->out_buffer.pos = 0;
}
} while (in_buffer.pos < in_buffer.size);
return 1;
}
/*
* Finish off an encoded strip by flushing it.
*/
static int ZSTDPostEncode(TIFF *tif)
{
static const char module[] = "ZSTDPostEncode";
ZSTDState *sp = ZSTDEncoderState(tif);
size_t zstd_ret;
do
{
zstd_ret = ZSTD_endStream(sp->cstream, &sp->out_buffer);
if (ZSTD_isError(zstd_ret))
{
TIFFErrorExtR(tif, module, "Error in ZSTD_endStream(): %s",
ZSTD_getErrorName(zstd_ret));
return 0;
}
if (sp->out_buffer.pos > 0)
{
tif->tif_rawcc = sp->out_buffer.pos;
if (!TIFFFlushData1(tif))
return 0;
sp->out_buffer.dst = tif->tif_rawcp;
sp->out_buffer.pos = 0;
}
} while (zstd_ret != 0);
return 1;
}
static void ZSTDCleanup(TIFF *tif)
{
ZSTDState *sp = GetZSTDState(tif);
assert(sp != 0);
(void)TIFFPredictorCleanup(tif);
tif->tif_tagmethods.vgetfield = sp->vgetparent;
tif->tif_tagmethods.vsetfield = sp->vsetparent;
if (sp->dstream)
{
ZSTD_freeDStream(sp->dstream);
sp->dstream = NULL;
}
if (sp->cstream)
{
ZSTD_freeCStream(sp->cstream);
sp->cstream = NULL;
}
_TIFFfreeExt(tif, sp);
tif->tif_data = NULL;
_TIFFSetDefaultCompressionState(tif);
}
static int ZSTDVSetField(TIFF *tif, uint32_t tag, va_list ap)
{
static const char module[] = "ZSTDVSetField";
ZSTDState *sp = GetZSTDState(tif);
switch (tag)
{
case TIFFTAG_ZSTD_LEVEL:
sp->compression_level = (int)va_arg(ap, int);
if (sp->compression_level <= 0 ||
sp->compression_level > ZSTD_maxCLevel())
{
TIFFWarningExtR(tif, module,
"ZSTD_LEVEL should be between 1 and %d",
ZSTD_maxCLevel());
}
return 1;
default:
return (*sp->vsetparent)(tif, tag, ap);
}
/*NOTREACHED*/
}
static int ZSTDVGetField(TIFF *tif, uint32_t tag, va_list ap)
{
ZSTDState *sp = GetZSTDState(tif);
switch (tag)
{
case TIFFTAG_ZSTD_LEVEL:
*va_arg(ap, int *) = sp->compression_level;
break;
default:
return (*sp->vgetparent)(tif, tag, ap);
}
return 1;
}
static const TIFFField ZSTDFields[] = {
{TIFFTAG_ZSTD_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO, TRUE,
FALSE, "ZSTD compression_level", NULL},
};
int TIFFInitZSTD(TIFF *tif, int scheme)
{
static const char module[] = "TIFFInitZSTD";
ZSTDState *sp;
(void)scheme;
assert(scheme == COMPRESSION_ZSTD);
/*
* Merge codec-specific tag information.
*/
if (!_TIFFMergeFields(tif, ZSTDFields, TIFFArrayCount(ZSTDFields)))
{
TIFFErrorExtR(tif, module, "Merging ZSTD codec-specific tags failed");
return 0;
}
/*
* Allocate state block so tag methods have storage to record values.
*/
tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(ZSTDState));
if (tif->tif_data == NULL)
goto bad;
sp = GetZSTDState(tif);
/*
* Override parent get/set field methods.
*/
sp->vgetparent = tif->tif_tagmethods.vgetfield;
tif->tif_tagmethods.vgetfield = ZSTDVGetField; /* hook for codec tags */
sp->vsetparent = tif->tif_tagmethods.vsetfield;
tif->tif_tagmethods.vsetfield = ZSTDVSetField; /* hook for codec tags */
/* Default values for codec-specific fields */
sp->compression_level = 9; /* default comp. level */
sp->state = 0;
sp->dstream = 0;
sp->cstream = 0;
sp->out_buffer.dst = NULL;
sp->out_buffer.size = 0;
sp->out_buffer.pos = 0;
/*
* Install codec methods.
*/
tif->tif_fixuptags = ZSTDFixupTags;
tif->tif_setupdecode = ZSTDSetupDecode;
tif->tif_predecode = ZSTDPreDecode;
tif->tif_decoderow = ZSTDDecode;
tif->tif_decodestrip = ZSTDDecode;
tif->tif_decodetile = ZSTDDecode;
tif->tif_setupencode = ZSTDSetupEncode;
tif->tif_preencode = ZSTDPreEncode;
tif->tif_postencode = ZSTDPostEncode;
tif->tif_encoderow = ZSTDEncode;
tif->tif_encodestrip = ZSTDEncode;
tif->tif_encodetile = ZSTDEncode;
tif->tif_cleanup = ZSTDCleanup;
/*
* Setup predictor setup.
*/
(void)TIFFPredictorInit(tif);
return 1;
bad:
TIFFErrorExtR(tif, module, "No space for ZSTD state block");
return 0;
}
#endif /* ZSTD_SUPPORT */
+900
View File
@@ -0,0 +1,900 @@
/*
* 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.
*/
#ifndef _TIFF_
#define _TIFF_
#include "tiffconf.h"
/*
* Tag Image File Format (TIFF)
*
* Based on Rev 6.0 from:
* Developer's Desk
* Aldus Corporation
* 411 First Ave. South
* Suite 200
* Seattle, WA 98104
* 206-622-5500
*
* (http://partners.adobe.com/asn/developer/PDFS/TN/TIFF6.pdf)
*
* 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_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_t/uint_8_t
* 16-bit quantities int16_t/uint_16_t
* 32-bit quantities int32_t/uint_32_t
* 64-bit quantities int64_t/uint_64_t
* strings unsigned char*
*/
#ifdef __GNUC__
#define TIFF_GCC_DEPRECATED __attribute__((deprecated))
#else
#define TIFF_GCC_DEPRECATED
#endif
#ifdef _MSC_VER
#define TIFF_MSC_DEPRECATED \
__declspec(deprecated("libtiff type deprecated; please use corresponding " \
"C99 stdint.h type"))
#else
#define TIFF_MSC_DEPRECATED
#endif
#ifndef TIFF_DISABLE_DEPRECATED
typedef TIFF_MSC_DEPRECATED int8_t int8 TIFF_GCC_DEPRECATED;
typedef TIFF_MSC_DEPRECATED uint8_t uint8 TIFF_GCC_DEPRECATED;
typedef TIFF_MSC_DEPRECATED int16_t int16 TIFF_GCC_DEPRECATED;
typedef TIFF_MSC_DEPRECATED uint16_t uint16 TIFF_GCC_DEPRECATED;
typedef TIFF_MSC_DEPRECATED int32_t int32 TIFF_GCC_DEPRECATED;
typedef TIFF_MSC_DEPRECATED uint32_t uint32 TIFF_GCC_DEPRECATED;
typedef TIFF_MSC_DEPRECATED int64_t int64 TIFF_GCC_DEPRECATED;
typedef TIFF_MSC_DEPRECATED uint64_t uint64 TIFF_GCC_DEPRECATED;
#endif /* TIFF_DISABLE_DEPRECATED */
/*
* Some types as promoted in a variable argument list
* We use uint16_vap rather then directly using int, because this way
* we document the type we actually want to pass through, conceptually,
* rather then confusing the issue by merely stating the type it gets
* promoted to
*/
typedef int uint16_vap;
/*
* TIFF header.
*/
typedef struct
{
uint16_t tiff_magic; /* magic number (defines byte order) */
uint16_t tiff_version; /* TIFF version number */
} TIFFHeaderCommon;
typedef struct
{
uint16_t tiff_magic; /* magic number (defines byte order) */
uint16_t tiff_version; /* TIFF version number */
uint32_t tiff_diroff; /* byte offset to first directory */
} TIFFHeaderClassic;
typedef struct
{
uint16_t tiff_magic; /* magic number (defines byte order) */
uint16_t tiff_version; /* TIFF version number */
uint16_t tiff_offsetsize; /* size of offsets, should be 8 */
uint16_t tiff_unused; /* unused word, should be 0 */
uint64_t tiff_diroff; /* byte offset to first directory */
} TIFFHeaderBig;
/*
* NB: In the comments below,
* - items marked with a + are obsoleted by revision 5.0,
* - items marked with a ! are introduced in revision 6.0.
* - items marked with a % are introduced post revision 6.0.
* - items marked with a $ are obsoleted by revision 6.0.
* - items marked with a & are introduced by Adobe DNG specification.
*/
/*
* Tag data type information.
*
* Note: RATIONALs are the ratio of two 32-bit integer values.
*--:
* Note2: TIFF_IFD8 data type is used in tiffFields[]-tag definition in order to
distinguish the write-handling of those tags between ClassicTIFF and BigTiff:
For ClassicTIFF libtiff writes a 32-bit value and the TIFF_IFD
type-id into the file For BigTIFF libtiff writes a 64-bit value and the
TIFF_IFD8 type-id into the file
*/
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;
/*
* TIFF Tag Definitions.
*/
/* clang-format off */ /* for better readability of tag comments */
#define TIFFTAG_SUBFILETYPE 254 /* subfile data descriptor */
#define FILETYPE_REDUCEDIMAGE 0x1 /* reduced resolution version */
#define FILETYPE_PAGE 0x2 /* one page of many */
#define FILETYPE_MASK 0x4 /* transparency mask */
#define TIFFTAG_OSUBFILETYPE 255 /* +kind of data in subfile */
#define OFILETYPE_IMAGE 1 /* full resolution image data */
#define OFILETYPE_REDUCEDIMAGE 2 /* reduced size image data */
#define OFILETYPE_PAGE 3 /* one page of many */
#define TIFFTAG_IMAGEWIDTH 256 /* image width in pixels */
#define TIFFTAG_IMAGELENGTH 257 /* image height in pixels */
#define TIFFTAG_BITSPERSAMPLE 258 /* bits per channel (sample) */
#define TIFFTAG_COMPRESSION 259 /* data compression technique */
#define COMPRESSION_NONE 1 /* dump mode */
#define COMPRESSION_CCITTRLE 2 /* CCITT modified Huffman RLE */
#define COMPRESSION_CCITTFAX3 3 /* CCITT Group 3 fax encoding */
#define COMPRESSION_CCITT_T4 3 /* CCITT T.4 (TIFF 6 name) */
#define COMPRESSION_CCITTFAX4 4 /* CCITT Group 4 fax encoding */
#define COMPRESSION_CCITT_T6 4 /* CCITT T.6 (TIFF 6 name) */
#define COMPRESSION_LZW 5 /* Lempel-Ziv & Welch */
#define COMPRESSION_OJPEG 6 /* !6.0 JPEG */
#define COMPRESSION_JPEG 7 /* %JPEG DCT compression */
#define COMPRESSION_T85 9 /* !TIFF/FX T.85 JBIG compression */
#define COMPRESSION_T43 10 /* !TIFF/FX T.43 colour by layered JBIG compression */
#define COMPRESSION_NEXT 32766 /* NeXT 2-bit RLE */
#define COMPRESSION_CCITTRLEW 32771 /* #1 w/ word alignment */
#define COMPRESSION_PACKBITS 32773 /* Macintosh RLE */
#define COMPRESSION_THUNDERSCAN 32809 /* ThunderScan RLE */
/* codes 32895-32898 are reserved for ANSI IT8 TIFF/IT <dkelly@apago.com) */
#define COMPRESSION_IT8CTPAD 32895 /* IT8 CT w/padding */
#define COMPRESSION_IT8LW 32896 /* IT8 Linework RLE */
#define COMPRESSION_IT8MP 32897 /* IT8 Monochrome picture */
#define COMPRESSION_IT8BL 32898 /* IT8 Binary line art */
/* compression codes 32908-32911 are reserved for Pixar */
#define COMPRESSION_PIXARFILM 32908 /* Pixar companded 10bit LZW */
#define COMPRESSION_PIXARLOG 32909 /* Pixar companded 11bit ZIP */
#define COMPRESSION_DEFLATE 32946 /* Deflate compression, legacy tag */
#define COMPRESSION_ADOBE_DEFLATE 8 /* Deflate compression, as recognized by Adobe */
/* compression code 32947 is reserved for Oceana Matrix <dev@oceana.com> */
#define COMPRESSION_DCS 32947 /* Kodak DCS encoding */
#define COMPRESSION_JBIG 34661 /* ISO JBIG */
#define COMPRESSION_SGILOG 34676 /* SGI Log Luminance RLE */
#define COMPRESSION_SGILOG24 34677 /* SGI Log 24-bit packed */
#define COMPRESSION_JP2000 34712 /* Leadtools JPEG2000 */
#define COMPRESSION_LERC 34887 /* ESRI Lerc codec: https://github.com/Esri/lerc */
/* compression codes 34887-34889 are reserved for ESRI */
#define COMPRESSION_LZMA 34925 /* LZMA2 */
#define COMPRESSION_ZSTD 50000 /* ZSTD: WARNING not registered in Adobe-maintained registry */
#define COMPRESSION_WEBP 50001 /* WEBP: WARNING not registered in Adobe-maintained registry */
#define COMPRESSION_JXL 50002 /* JPEGXL: WARNING not registered in Adobe-maintained registry */
#define COMPRESSION_JXL_DNG_1_7 52546 /* JPEGXL from DNG 1.7 specification */
#define TIFFTAG_PHOTOMETRIC 262 /* photometric interpretation */
#define PHOTOMETRIC_MINISWHITE 0 /* min value is white */
#define PHOTOMETRIC_MINISBLACK 1 /* min value is black */
#define PHOTOMETRIC_RGB 2 /* RGB color model */
#define PHOTOMETRIC_PALETTE 3 /* color map indexed */
#define PHOTOMETRIC_MASK 4 /* $holdout mask */
#define PHOTOMETRIC_SEPARATED 5 /* !color separations */
#define PHOTOMETRIC_YCBCR 6 /* !CCIR 601 */
#define PHOTOMETRIC_CIELAB 8 /* !1976 CIE L*a*b* */
#define PHOTOMETRIC_ICCLAB 9 /* ICC L*a*b* [Adobe TIFF Technote 4] */
#define PHOTOMETRIC_ITULAB 10 /* ITU L*a*b* */
#define PHOTOMETRIC_CFA 32803 /* color filter array */
#define PHOTOMETRIC_LOGL 32844 /* CIE Log2(L) */
#define PHOTOMETRIC_LOGLUV 32845 /* CIE Log2(L) (u',v') */
#define TIFFTAG_THRESHHOLDING 263 /* +thresholding used on data */
#define THRESHHOLD_BILEVEL 1 /* b&w art scan */
#define THRESHHOLD_HALFTONE 2 /* or dithered scan */
#define THRESHHOLD_ERRORDIFFUSE 3 /* usually floyd-steinberg */
#define TIFFTAG_CELLWIDTH 264 /* +dithering matrix width */
#define TIFFTAG_CELLLENGTH 265 /* +dithering matrix height */
#define TIFFTAG_FILLORDER 266 /* data order within a byte */
#define FILLORDER_MSB2LSB 1 /* most significant -> least */
#define FILLORDER_LSB2MSB 2 /* least significant -> most */
#define TIFFTAG_DOCUMENTNAME 269 /* name of doc. image is from */
#define TIFFTAG_IMAGEDESCRIPTION 270 /* info about image */
#define TIFFTAG_MAKE 271 /* scanner manufacturer name */
#define TIFFTAG_MODEL 272 /* scanner model name/number */
#define TIFFTAG_STRIPOFFSETS 273 /* offsets to data strips */
#define TIFFTAG_ORIENTATION 274 /* +image orientation */
#define ORIENTATION_TOPLEFT 1 /* row 0 top, col 0 lhs */
#define ORIENTATION_TOPRIGHT 2 /* row 0 top, col 0 rhs */
#define ORIENTATION_BOTRIGHT 3 /* row 0 bottom, col 0 rhs */
#define ORIENTATION_BOTLEFT 4 /* row 0 bottom, col 0 lhs */
#define ORIENTATION_LEFTTOP 5 /* row 0 lhs, col 0 top */
#define ORIENTATION_RIGHTTOP 6 /* row 0 rhs, col 0 top */
#define ORIENTATION_RIGHTBOT 7 /* row 0 rhs, col 0 bottom */
#define ORIENTATION_LEFTBOT 8 /* row 0 lhs, col 0 bottom */
#define TIFFTAG_SAMPLESPERPIXEL 277 /* samples per pixel */
#define TIFFTAG_ROWSPERSTRIP 278 /* rows per strip of data */
#define TIFFTAG_STRIPBYTECOUNTS 279 /* bytes counts for strips */
#define TIFFTAG_MINSAMPLEVALUE 280 /* +minimum sample value */
#define TIFFTAG_MAXSAMPLEVALUE 281 /* +maximum sample value */
#define TIFFTAG_XRESOLUTION 282 /* pixels/resolution in x */
#define TIFFTAG_YRESOLUTION 283 /* pixels/resolution in y */
#define TIFFTAG_PLANARCONFIG 284 /* storage organization */
#define PLANARCONFIG_CONTIG 1 /* single image plane */
#define PLANARCONFIG_SEPARATE 2 /* separate planes of data */
#define TIFFTAG_PAGENAME 285 /* page name image is from */
#define TIFFTAG_XPOSITION 286 /* x page offset of image lhs */
#define TIFFTAG_YPOSITION 287 /* y page offset of image lhs */
#define TIFFTAG_FREEOFFSETS 288 /* +byte offset to free block */
#define TIFFTAG_FREEBYTECOUNTS 289 /* +sizes of free blocks */
#define TIFFTAG_GRAYRESPONSEUNIT 290 /* $gray scale curve accuracy */
#define GRAYRESPONSEUNIT_10S 1 /* tenths of a unit */
#define GRAYRESPONSEUNIT_100S 2 /* hundredths of a unit */
#define GRAYRESPONSEUNIT_1000S 3 /* thousandths of a unit */
#define GRAYRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */
#define GRAYRESPONSEUNIT_100000S 5 /* hundred-thousandths */
#define TIFFTAG_GRAYRESPONSECURVE 291 /* $gray scale response curve */
#define TIFFTAG_GROUP3OPTIONS 292 /* 32 flag bits */
#define TIFFTAG_T4OPTIONS 292 /* TIFF 6.0 proper name alias */
#define GROUP3OPT_2DENCODING 0x1 /* 2-dimensional coding */
#define GROUP3OPT_UNCOMPRESSED 0x2 /* data not compressed */
#define GROUP3OPT_FILLBITS 0x4 /* fill to byte boundary */
#define TIFFTAG_GROUP4OPTIONS 293 /* 32 flag bits */
#define TIFFTAG_T6OPTIONS 293 /* TIFF 6.0 proper name */
#define GROUP4OPT_UNCOMPRESSED 0x2 /* data not compressed */
#define TIFFTAG_RESOLUTIONUNIT 296 /* units of resolutions */
#define RESUNIT_NONE 1 /* no meaningful units */
#define RESUNIT_INCH 2 /* english */
#define RESUNIT_CENTIMETER 3 /* metric */
#define TIFFTAG_PAGENUMBER 297 /* page numbers of multi-page */
#define TIFFTAG_COLORRESPONSEUNIT 300 /* $color curve accuracy */
#define COLORRESPONSEUNIT_10S 1 /* tenths of a unit */
#define COLORRESPONSEUNIT_100S 2 /* hundredths of a unit */
#define COLORRESPONSEUNIT_1000S 3 /* thousandths of a unit */
#define COLORRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */
#define COLORRESPONSEUNIT_100000S 5 /* hundred-thousandths */
#define TIFFTAG_TRANSFERFUNCTION 301 /* !colorimetry info */
#define TIFFTAG_SOFTWARE 305 /* name & release */
#define TIFFTAG_DATETIME 306 /* creation date and time */
#define TIFFTAG_ARTIST 315 /* creator of image */
#define TIFFTAG_HOSTCOMPUTER 316 /* machine where created */
#define TIFFTAG_PREDICTOR 317 /* prediction scheme w/ LZW */
#define PREDICTOR_NONE 1 /* no prediction scheme used */
#define PREDICTOR_HORIZONTAL 2 /* horizontal differencing */
#define PREDICTOR_FLOATINGPOINT 3 /* floating point predictor */
#define TIFFTAG_WHITEPOINT 318 /* image white point */
#define TIFFTAG_PRIMARYCHROMATICITIES 319 /* !primary chromaticities */
#define TIFFTAG_COLORMAP 320 /* RGB map for palette image */
#define TIFFTAG_HALFTONEHINTS 321 /* !highlight+shadow info */
#define TIFFTAG_TILEWIDTH 322 /* !tile width in pixels */
#define TIFFTAG_TILELENGTH 323 /* !tile height in pixels */
#define TIFFTAG_TILEOFFSETS 324 /* !offsets to data tiles */
#define TIFFTAG_TILEBYTECOUNTS 325 /* !byte counts for tiles */
#define TIFFTAG_BADFAXLINES 326 /* lines w/ wrong pixel count */
#define TIFFTAG_CLEANFAXDATA 327 /* regenerated line info */
#define CLEANFAXDATA_CLEAN 0 /* no errors detected */
#define CLEANFAXDATA_REGENERATED 1 /* receiver regenerated lines */
#define CLEANFAXDATA_UNCLEAN 2 /* uncorrected errors exist */
#define TIFFTAG_CONSECUTIVEBADFAXLINES 328 /* max consecutive bad lines */
#define TIFFTAG_SUBIFD 330 /* subimage descriptors */
#define TIFFTAG_INKSET 332 /* !inks in separated image */
#define INKSET_CMYK 1 /* !cyan-magenta-yellow-black color */
#define INKSET_MULTIINK 2 /* !multi-ink or hi-fi color */
#define TIFFTAG_INKNAMES 333 /* !ascii names of inks */
#define TIFFTAG_NUMBEROFINKS 334 /* !number of inks */
#define TIFFTAG_DOTRANGE 336 /* !0% and 100% dot codes */
#define TIFFTAG_TARGETPRINTER 337 /* !separation target */
#define TIFFTAG_EXTRASAMPLES 338 /* !info about extra samples */
#define EXTRASAMPLE_UNSPECIFIED 0 /* !unspecified data */
#define EXTRASAMPLE_ASSOCALPHA 1 /* !associated alpha data */
#define EXTRASAMPLE_UNASSALPHA 2 /* !unassociated alpha data */
#define TIFFTAG_SAMPLEFORMAT 339 /* !data sample format */
#define SAMPLEFORMAT_UINT 1 /* !unsigned integer data */
#define SAMPLEFORMAT_INT 2 /* !signed integer data */
#define SAMPLEFORMAT_IEEEFP 3 /* !IEEE floating point data */
#define SAMPLEFORMAT_VOID 4 /* !untyped data */
#define SAMPLEFORMAT_COMPLEXINT 5 /* !complex signed int */
#define SAMPLEFORMAT_COMPLEXIEEEFP 6 /* !complex ieee floating */
#define TIFFTAG_SMINSAMPLEVALUE 340 /* !variable MinSampleValue */
#define TIFFTAG_SMAXSAMPLEVALUE 341 /* !variable MaxSampleValue */
#define TIFFTAG_CLIPPATH 343 /* %ClipPath [Adobe TIFF technote 2] */
#define TIFFTAG_XCLIPPATHUNITS 344 /* %XClipPathUnits [Adobe TIFF technote 2] */
#define TIFFTAG_YCLIPPATHUNITS 345 /* %YClipPathUnits [Adobe TIFF technote 2] */
#define TIFFTAG_INDEXED 346 /* %Indexed [Adobe TIFF Technote 3] */
#define TIFFTAG_JPEGTABLES 347 /* %JPEG table stream */
#define TIFFTAG_OPIPROXY 351 /* %OPI Proxy [Adobe TIFF technote] */
/* Tags 400-435 are from the TIFF/FX spec */
#define TIFFTAG_GLOBALPARAMETERSIFD 400 /* ! */
#define TIFFTAG_PROFILETYPE 401 /* ! */
#define PROFILETYPE_UNSPECIFIED 0 /* ! */
#define PROFILETYPE_G3_FAX 1 /* ! */
#define TIFFTAG_FAXPROFILE 402 /* ! */
#define FAXPROFILE_S 1 /* !TIFF/FX FAX profile S */
#define FAXPROFILE_F 2 /* !TIFF/FX FAX profile F */
#define FAXPROFILE_J 3 /* !TIFF/FX FAX profile J */
#define FAXPROFILE_C 4 /* !TIFF/FX FAX profile C */
#define FAXPROFILE_L 5 /* !TIFF/FX FAX profile L */
#define FAXPROFILE_M 6 /* !TIFF/FX FAX profile LM */
#define TIFFTAG_CODINGMETHODS 403 /* !TIFF/FX coding methods */
#define CODINGMETHODS_T4_1D (1 << 1) /* !T.4 1D */
#define CODINGMETHODS_T4_2D (1 << 2) /* !T.4 2D */
#define CODINGMETHODS_T6 (1 << 3) /* !T.6 */
#define CODINGMETHODS_T85 (1 << 4) /* !T.85 JBIG */
#define CODINGMETHODS_T42 (1 << 5) /* !T.42 JPEG */
#define CODINGMETHODS_T43 (1 << 6) /* !T.43 colour by layered JBIG */
#define TIFFTAG_VERSIONYEAR 404 /* !TIFF/FX version year */
#define TIFFTAG_MODENUMBER 405 /* !TIFF/FX mode number */
#define TIFFTAG_DECODE 433 /* !TIFF/FX decode */
#define TIFFTAG_IMAGEBASECOLOR 434 /* !TIFF/FX image base colour */
#define TIFFTAG_T82OPTIONS 435 /* !TIFF/FX T.82 options */
/*
* Tags 512-521 are obsoleted by Technical Note #2 which specifies a
* revised JPEG-in-TIFF scheme.
*/
#define TIFFTAG_JPEGPROC 512 /* !JPEG processing algorithm */
#define JPEGPROC_BASELINE 1 /* !baseline sequential */
#define JPEGPROC_LOSSLESS 14 /* !Huffman coded lossless */
#define TIFFTAG_JPEGIFOFFSET 513 /* !pointer to SOI marker */
#define TIFFTAG_JPEGIFBYTECOUNT 514 /* !JFIF stream length */
#define TIFFTAG_JPEGRESTARTINTERVAL 515 /* !restart interval length */
#define TIFFTAG_JPEGLOSSLESSPREDICTORS 517 /* !lossless proc predictor */
#define TIFFTAG_JPEGPOINTTRANSFORM 518 /* !lossless point transform */
#define TIFFTAG_JPEGQTABLES 519 /* !Q matrix offsets */
#define TIFFTAG_JPEGDCTABLES 520 /* !DCT table offsets */
#define TIFFTAG_JPEGACTABLES 521 /* !AC coefficient offsets */
#define TIFFTAG_YCBCRCOEFFICIENTS 529 /* !RGB -> YCbCr transform */
#define TIFFTAG_YCBCRSUBSAMPLING 530 /* !YCbCr subsampling factors */
#define TIFFTAG_YCBCRPOSITIONING 531 /* !subsample positioning */
#define YCBCRPOSITION_CENTERED 1 /* !as in PostScript Level 2 */
#define YCBCRPOSITION_COSITED 2 /* !as in CCIR 601-1 */
#define TIFFTAG_REFERENCEBLACKWHITE 532 /* !colorimetry info */
#define TIFFTAG_STRIPROWCOUNTS 559 /* !TIFF/FX strip row counts */
#define TIFFTAG_XMLPACKET 700 /* %XML packet [Adobe XMP Specification, January 2004 */
#define TIFFTAG_OPIIMAGEID 32781 /* %OPI ImageID [Adobe TIFF technote] */
/* For eiStream Annotation Specification, Version 1.00.06 see
* http://web.archive.org/web/20050309141348/http://www.kofile.com/support%20pro/faqs/annospec.htm */
#define TIFFTAG_TIFFANNOTATIONDATA 32932
/* tags 32952-32956 are private tags registered to Island Graphics */
#define TIFFTAG_REFPTS 32953 /* image reference points */
#define TIFFTAG_REGIONTACKPOINT 32954 /* region-xform tack point */
#define TIFFTAG_REGIONWARPCORNERS 32955 /* warp quadrilateral */
#define TIFFTAG_REGIONAFFINE 32956 /* affine transformation mat */
/* tags 32995-32999 are private tags registered to SGI */
#define TIFFTAG_MATTEING 32995 /* $use ExtraSamples */
#define TIFFTAG_DATATYPE 32996 /* $use SampleFormat */
#define TIFFTAG_IMAGEDEPTH 32997 /* z depth of image */
#define TIFFTAG_TILEDEPTH 32998 /* z depth/data tile */
/* tags 33300-33309 are private tags registered to Pixar */
/*
* TIFFTAG_PIXAR_IMAGEFULLWIDTH and TIFFTAG_PIXAR_IMAGEFULLLENGTH
* are set when an image has been cropped out of a larger image.
* They reflect the size of the original uncropped image.
* The TIFFTAG_XPOSITION and TIFFTAG_YPOSITION can be used
* to determine the position of the smaller image in the larger one.
*/
#define TIFFTAG_PIXAR_IMAGEFULLWIDTH 33300 /* full image size in x */
#define TIFFTAG_PIXAR_IMAGEFULLLENGTH 33301 /* full image size in y */
/* Tags 33302-33306 are used to identify special image modes and data
* used by Pixar's texture formats.
*/
#define TIFFTAG_PIXAR_TEXTUREFORMAT 33302 /* texture map format */
#define TIFFTAG_PIXAR_WRAPMODES 33303 /* s & t wrap modes */
#define TIFFTAG_PIXAR_FOVCOT 33304 /* cotan(fov) for env. maps */
#define TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN 33305
#define TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA 33306
/* tag 33405 is a private tag registered to Eastman Kodak */
#define TIFFTAG_WRITERSERIALNUMBER 33405 /* device serial number */
#define TIFFTAG_CFAREPEATPATTERNDIM 33421 /* (alias for TIFFTAG_EP_CFAREPEATPATTERNDIM)*/
#define TIFFTAG_CFAPATTERN 33422 /* (alias for TIFFTAG_EP_CFAPATTERN) */
#define TIFFTAG_BATTERYLEVEL 33423 /* (alias for TIFFTAG_EP_BATTERYLEVEL) */
/* tag 33432 is listed in the 6.0 spec w/ unknown ownership */
#define TIFFTAG_COPYRIGHT 33432 /* copyright string */
/* Tags 33445-33452 are used for Molecular Dynamics GEL fileformat,
* see http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf
* (2023: the above web site is unavailable but tags are explained briefly at
* https://www.awaresystems.be/imaging/tiff/tifftags/docs/gel.html
*/
#define TIFFTAG_MD_FILETAG 33445 /* Specifies the pixel data format encoding in the GEL file format. */
#define TIFFTAG_MD_SCALEPIXEL 33446 /* scale factor */
#define TIFFTAG_MD_COLORTABLE 33447 /* conversion from 16bit to 8bit */
#define TIFFTAG_MD_LABNAME 33448 /* name of the lab that scanned this file. */
#define TIFFTAG_MD_SAMPLEINFO 33449 /* information about the scanned GEL sample */
#define TIFFTAG_MD_PREPDATE 33450 /* information about the date the sample was prepared YY/MM/DD */
#define TIFFTAG_MD_PREPTIME 33451 /* information about the time the sample was prepared HH:MM*/
#define TIFFTAG_MD_FILEUNITS 33452 /* Units for data in this file, as used in the GEL file format. */
/* IPTC TAG from RichTIFF specifications */
#define TIFFTAG_RICHTIFFIPTC 33723
#define TIFFTAG_INGR_PACKET_DATA_TAG 33918 /* Intergraph Application specific storage. */
#define TIFFTAG_INGR_FLAG_REGISTERS 33919 /* Intergraph Application specific flags. */
#define TIFFTAG_IRASB_TRANSORMATION_MATRIX 33920 /* Originally part of Intergraph's GeoTIFF tags, but likely understood by IrasB only. */
#define TIFFTAG_MODELTIEPOINTTAG 33922 /* GeoTIFF */
/* 34016-34029 are reserved for ANSI IT8 TIFF/IT <dkelly@apago.com) */
#define TIFFTAG_IT8SITE 34016 /* site name */
#define TIFFTAG_IT8COLORSEQUENCE 34017 /* color seq. [RGB,CMYK,etc] */
#define TIFFTAG_IT8HEADER 34018 /* DDES Header */
#define TIFFTAG_IT8RASTERPADDING 34019 /* raster scanline padding */
#define TIFFTAG_IT8BITSPERRUNLENGTH 34020 /* # of bits in short run */
#define TIFFTAG_IT8BITSPEREXTENDEDRUNLENGTH 34021 /* # of bits in long run */
#define TIFFTAG_IT8COLORTABLE 34022 /* LW colortable */
#define TIFFTAG_IT8IMAGECOLORINDICATOR 34023 /* BP/BL image color switch */
#define TIFFTAG_IT8BKGCOLORINDICATOR 34024 /* BP/BL bg color switch */
#define TIFFTAG_IT8IMAGECOLORVALUE 34025 /* BP/BL image color value */
#define TIFFTAG_IT8BKGCOLORVALUE 34026 /* BP/BL bg color value */
#define TIFFTAG_IT8PIXELINTENSITYRANGE 34027 /* MP pixel intensity value */
#define TIFFTAG_IT8TRANSPARENCYINDICATOR 34028 /* HC transparency switch */
#define TIFFTAG_IT8COLORCHARACTERIZATION 34029 /* color character. table */
#define TIFFTAG_IT8HCUSAGE 34030 /* HC usage indicator */
#define TIFFTAG_IT8TRAPINDICATOR 34031 /* Trapping indicator (untrapped=0, trapped=1) */
#define TIFFTAG_IT8CMYKEQUIVALENT 34032 /* CMYK color equivalents */
/* tags 34232-34236 are private tags registered to Texas Instruments */
#define TIFFTAG_FRAMECOUNT 34232 /* Sequence Frame Count */
#define TIFFTAG_MODELTRANSFORMATIONTAG 34264 /* Used in interchangeable GeoTIFF files */
/* tag 34377 is private tag registered to Adobe for PhotoShop */
#define TIFFTAG_PHOTOSHOP 34377
/* tags 34665, 34853 and 40965 are documented in EXIF specification */
#define TIFFTAG_EXIFIFD 34665 /* Pointer to EXIF private directory */
/* tag 34750 is a private tag registered to Adobe? */
#define TIFFTAG_ICCPROFILE 34675 /* ICC profile data */
#define TIFFTAG_IMAGELAYER 34732 /* !TIFF/FX image layer information */
/* tag 34750 is a private tag registered to Pixel Magic */
#define TIFFTAG_JBIGOPTIONS 34750 /* JBIG options */
#define TIFFTAG_GPSIFD 34853 /* Pointer to EXIF GPS private directory */
/* tags 34908-34914 are private tags registered to SGI */
#define TIFFTAG_FAXRECVPARAMS 34908 /* encoded Class 2 ses. params */
#define TIFFTAG_FAXSUBADDRESS 34909 /* received SubAddr string */
#define TIFFTAG_FAXRECVTIME 34910 /* receive time (secs) */
#define TIFFTAG_FAXDCS 34911 /* encoded fax ses. params, Table 2/T.30 */
/* tags 37439-37443 are registered to SGI <gregl@sgi.com> */
#define TIFFTAG_STONITS 37439 /* Sample value to Nits */
/* tag 34929 is a private tag registered to FedEx */
#define TIFFTAG_FEDEX_EDR 34929 /* unknown use */
#define TIFFTAG_IMAGESOURCEDATA 37724 /* http://justsolve.archiveteam.org/wiki/PSD, http://www.adobe.com/devnet-apps/photoshop/fileformatashtml/ */
#define TIFFTAG_INTEROPERABILITYIFD 40965 /* Pointer to EXIF Interoperability private directory */
#define TIFFTAG_GDAL_METADATA 42112 /* Used by the GDAL library */
#define TIFFTAG_GDAL_NODATA 42113 /* Used by the GDAL library */
#define TIFFTAG_OCE_SCANJOB_DESCRIPTION 50215 /* Used in the Oce scanning process */
#define TIFFTAG_OCE_APPLICATION_SELECTOR 50216 /* Used in the Oce scanning process. */
#define TIFFTAG_OCE_IDENTIFICATION_NUMBER 50217
#define TIFFTAG_OCE_IMAGELOGIC_CHARACTERISTICS 50218
/* tags 50674 to 50677 are reserved for ESRI */
#define TIFFTAG_LERC_PARAMETERS 50674 /* Stores LERC version and additional compression method */
/* Adobe Digital Negative (DNG) format tags */
#define TIFFTAG_DNGVERSION 50706 /* &DNG version number */
#define TIFFTAG_DNGBACKWARDVERSION 50707 /* &DNG compatibility version */
#define TIFFTAG_UNIQUECAMERAMODEL 50708 /* &name for the camera model */
#define TIFFTAG_LOCALIZEDCAMERAMODEL 50709 /* &localized camera model name (UTF-8) */
#define TIFFTAG_CFAPLANECOLOR 50710 /* &CFAPattern->LinearRaw space mapping */
#define TIFFTAG_CFALAYOUT 50711 /* &spatial layout of the CFA */
#define TIFFTAG_LINEARIZATIONTABLE 50712 /* &lookup table description */
#define TIFFTAG_BLACKLEVELREPEATDIM 50713 /* &repeat pattern size for the BlackLevel tag */
#define TIFFTAG_BLACKLEVEL 50714 /* &zero light encoding level */
#define TIFFTAG_BLACKLEVELDELTAH 50715 /* &zero light encoding level differences (columns) */
#define TIFFTAG_BLACKLEVELDELTAV 50716 /* &zero light encoding level differences (rows) */
#define TIFFTAG_WHITELEVEL 50717 /* &fully saturated encoding level */
#define TIFFTAG_DEFAULTSCALE 50718 /* &default scale factors */
#define TIFFTAG_DEFAULTCROPORIGIN 50719 /* &origin of the final image area */
#define TIFFTAG_DEFAULTCROPSIZE 50720 /* &size of the final image area */
#define TIFFTAG_COLORMATRIX1 50721 /* &XYZ->reference color space transformation matrix 1 */
#define TIFFTAG_COLORMATRIX2 50722 /* &XYZ->reference color space transformation matrix 2 */
#define TIFFTAG_CAMERACALIBRATION1 50723 /* &calibration matrix 1 */
#define TIFFTAG_CAMERACALIBRATION2 50724 /* &calibration matrix 2 */
#define TIFFTAG_REDUCTIONMATRIX1 50725 /* &dimensionality reduction matrix 1 */
#define TIFFTAG_REDUCTIONMATRIX2 50726 /* &dimensionality reduction matrix 2 */
#define TIFFTAG_ANALOGBALANCE 50727 /* &gain applied the stored raw values*/
#define TIFFTAG_ASSHOTNEUTRAL 50728 /* &selected white balance in linear reference space */
#define TIFFTAG_ASSHOTWHITEXY 50729 /* &selected white balance in x-y chromaticity coordinates */
#define TIFFTAG_BASELINEEXPOSURE 50730 /* &how much to move the zero point */
#define TIFFTAG_BASELINENOISE 50731 /* &relative noise level */
#define TIFFTAG_BASELINESHARPNESS 50732 /* &relative amount of sharpening */
/* TIFFTAG_BAYERGREENSPLIT: &how closely the values of the green pixels in the blue/green rows
* track the values of the green pixels in the red/green rows */
#define TIFFTAG_BAYERGREENSPLIT 50733
#define TIFFTAG_LINEARRESPONSELIMIT 50734 /* &non-linear encoding range */
#define TIFFTAG_CAMERASERIALNUMBER 50735 /* &camera's serial number */
#define TIFFTAG_LENSINFO 50736 /* info about the lens */
#define TIFFTAG_CHROMABLURRADIUS 50737 /* &chroma blur radius */
#define TIFFTAG_ANTIALIASSTRENGTH 50738 /* &relative strength of the camera's anti-alias filter */
#define TIFFTAG_SHADOWSCALE 50739 /* &used by Adobe Camera Raw */
#define TIFFTAG_DNGPRIVATEDATA 50740 /* &manufacturer's private data */
#define TIFFTAG_MAKERNOTESAFETY 50741 /* &whether the EXIF MakerNote tag is safe to preserve along with the rest of the EXIF data */
#define TIFFTAG_CALIBRATIONILLUMINANT1 50778 /* &illuminant 1 */
#define TIFFTAG_CALIBRATIONILLUMINANT2 50779 /* &illuminant 2 */
#define TIFFTAG_BESTQUALITYSCALE 50780 /* &best quality multiplier */
#define TIFFTAG_RAWDATAUNIQUEID 50781 /* &unique identifier for the raw image data */
#define TIFFTAG_ORIGINALRAWFILENAME 50827 /* &file name of the original raw file (UTF-8) */
#define TIFFTAG_ORIGINALRAWFILEDATA 50828 /* &contents of the original raw file */
#define TIFFTAG_ACTIVEAREA 50829 /* &active (non-masked) pixels of the sensor */
#define TIFFTAG_MASKEDAREAS 50830 /* &list of coordinates of fully masked pixels */
#define TIFFTAG_ASSHOTICCPROFILE 50831 /* &these two tags used to */
#define TIFFTAG_ASSHOTPREPROFILEMATRIX 50832 /* map cameras's color space into ICC profile space */
#define TIFFTAG_CURRENTICCPROFILE 50833 /* & */
#define TIFFTAG_CURRENTPREPROFILEMATRIX 50834 /* & */
/* DNG 1.2.0.0 */
#define TIFFTAG_COLORIMETRICREFERENCE 50879 /* &colorimetric reference */
#define TIFFTAG_CAMERACALIBRATIONSIGNATURE 50931 /* &camera calibration signature (UTF-8) */
#define TIFFTAG_PROFILECALIBRATIONSIGNATURE 50932 /* &profile calibration signature (UTF-8) */
/* TIFFTAG_EXTRACAMERAPROFILES 50933 &extra camera profiles : is already defined for GeoTIFF DGIWG */
#define TIFFTAG_ASSHOTPROFILENAME 50934 /* &as shot profile name (UTF-8) */
#define TIFFTAG_NOISEREDUCTIONAPPLIED 50935 /* &amount of applied noise reduction */
#define TIFFTAG_PROFILENAME 50936 /* &camera profile name (UTF-8) */
#define TIFFTAG_PROFILEHUESATMAPDIMS 50937 /* &dimensions of HSV mapping */
#define TIFFTAG_PROFILEHUESATMAPDATA1 50938 /* &first HSV mapping table */
#define TIFFTAG_PROFILEHUESATMAPDATA2 50939 /* &second HSV mapping table */
#define TIFFTAG_PROFILETONECURVE 50940 /* &default tone curve */
#define TIFFTAG_PROFILEEMBEDPOLICY 50941 /* &profile embedding policy */
#define TIFFTAG_PROFILECOPYRIGHT 50942 /* &profile copyright information (UTF-8) */
#define TIFFTAG_FORWARDMATRIX1 50964 /* &matrix for mapping white balanced camera colors to XYZ D50 */
#define TIFFTAG_FORWARDMATRIX2 50965 /* &matrix for mapping white balanced camera colors to XYZ D50 */
#define TIFFTAG_PREVIEWAPPLICATIONNAME 50966 /* &name of application that created preview (UTF-8) */
#define TIFFTAG_PREVIEWAPPLICATIONVERSION 50967 /* &version of application that created preview (UTF-8) */
#define TIFFTAG_PREVIEWSETTINGSNAME 50968 /* &name of conversion settings (UTF-8) */
#define TIFFTAG_PREVIEWSETTINGSDIGEST 50969 /* &unique id of conversion settings */
#define TIFFTAG_PREVIEWCOLORSPACE 50970 /* &preview color space */
#define TIFFTAG_PREVIEWDATETIME 50971 /* &date/time preview was rendered */
#define TIFFTAG_RAWIMAGEDIGEST 50972 /* &md5 of raw image data */
#define TIFFTAG_ORIGINALRAWFILEDIGEST 50973 /* &md5 of the data stored in the OriginalRawFileData tag */
#define TIFFTAG_SUBTILEBLOCKSIZE 50974 /* &subtile block size */
#define TIFFTAG_ROWINTERLEAVEFACTOR 50975 /* &number of interleaved fields */
#define TIFFTAG_PROFILELOOKTABLEDIMS 50981 /* &num of input samples in each dim of default "look" table */
#define TIFFTAG_PROFILELOOKTABLEDATA 50982 /* &default "look" table for use as starting point */
/* DNG 1.3.0.0 */
#define TIFFTAG_OPCODELIST1 51008 /* &opcodes that should be applied to raw image after reading */
#define TIFFTAG_OPCODELIST2 51009 /* &opcodes that should be applied after mapping to linear reference */
#define TIFFTAG_OPCODELIST3 51022 /* &opcodes that should be applied after demosaicing */
#define TIFFTAG_NOISEPROFILE 51041 /* &noise profile */
/* DNG 1.4.0.0 */
#define TIFFTAG_DEFAULTUSERCROP 51125 /* &default user crop rectangle in relative coords */
#define TIFFTAG_DEFAULTBLACKRENDER 51110 /* &black rendering hint */
#define TIFFTAG_BASELINEEXPOSUREOFFSET 51109 /* &baseline exposure offset */
#define TIFFTAG_PROFILELOOKTABLEENCODING 51108 /* &3D LookTable indexing conversion */
#define TIFFTAG_PROFILEHUESATMAPENCODING 51107 /* &3D HueSatMap indexing conversion */
#define TIFFTAG_ORIGINALDEFAULTFINALSIZE 51089 /* &default final size of larger original file for this proxy */
#define TIFFTAG_ORIGINALBESTQUALITYFINALSIZE 51090 /* &best quality final size of larger original file for this proxy */
#define TIFFTAG_ORIGINALDEFAULTCROPSIZE 51091 /* &the default crop size of larger original file for this proxy */
#define TIFFTAG_NEWRAWIMAGEDIGEST 51111 /* &modified MD5 digest of the raw image data */
#define TIFFTAG_RAWTOPREVIEWGAIN 51112 /* &The gain between the main raw FD and the preview IFD containing this tag */
/* DNG 1.5.0.0 */
#define TIFFTAG_DEPTHFORMAT 51177 /* &encoding of the depth data in the file */
#define TIFFTAG_DEPTHNEAR 51178 /* &distance from the camera represented by value 0 in the depth map */
#define TIFFTAG_DEPTHFAR 51179 /* &distance from the camera represented by the maximum value in the depth map */
#define TIFFTAG_DEPTHUNITS 51180 /* &measurement units for DepthNear and DepthFar */
#define TIFFTAG_DEPTHMEASURETYPE 51181 /* &measurement geometry for the depth map */
#define TIFFTAG_ENHANCEPARAMS 51182 /* &a string that documents how the enhanced image data was processed. */
/* DNG 1.6.0.0 */
#define TIFFTAG_PROFILEGAINTABLEMAP 52525 /* &spatially varying gain tables that can be applied as starting point */
#define TIFFTAG_SEMANTICNAME 52526 /* &a string that identifies the semantic mask */
#define TIFFTAG_SEMANTICINSTANCEID 52528 /* &a string that identifies a specific instance in a semantic mask */
#define TIFFTAG_MASKSUBAREA 52536 /* &the crop rectangle of this IFD's mask, relative to the main image */
#define TIFFTAG_RGBTABLES 52543 /* &color transforms to apply to masked image regions */
#define TIFFTAG_CALIBRATIONILLUMINANT3 52529 /* &the illuminant used for the third set of color calibration tags */
#define TIFFTAG_COLORMATRIX3 52531 /* &matrix to convert XYZ values to reference camera native color space under CalibrationIlluminant3 */
#define TIFFTAG_CAMERACALIBRATION3 52530 /* &matrix to transform reference camera native space values to individual camera native space values under CalibrationIlluminant3 */
#define TIFFTAG_REDUCTIONMATRIX3 52538 /* &dimensionality reduction matrix for use in color conversion to XYZ under CalibrationIlluminant3 */
#define TIFFTAG_PROFILEHUESATMAPDATA3 52537 /* &the data for the third HSV table */
#define TIFFTAG_FORWARDMATRIX3 52532 /* &matrix to map white balanced camera colors to XYZ D50 */
#define TIFFTAG_ILLUMINANTDATA1 52533 /* &data for the first calibration illuminant */
#define TIFFTAG_ILLUMINANTDATA2 52534 /* &data for the second calibration illuminant */
#define TIFFTAG_ILLUMINANTDATA3 53535 /* &data for the third calibration illuminant */
/* TIFF/EP */
#define TIFFTAG_EP_CFAREPEATPATTERNDIM 33421 /* dimensions of CFA pattern */
#define TIFFTAG_EP_CFAPATTERN 33422 /* color filter array pattern */
#define TIFFTAG_EP_BATTERYLEVEL 33423 /* battery level (rational or ASCII) */
#define TIFFTAG_EP_INTERLACE 34857 /* Number of multi-field images */
/* TIFFTAG_EP_IPTC_NAA and TIFFTAG_RICHTIFFIPTC share the same tag number (33723)
* LibTIFF type is UNDEFINED or BYTE, but often times incorrectly specified as LONG,
* because TIFF/EP (ISO/DIS 12234-2) specifies type LONG or ASCII. */
#define TIFFTAG_EP_IPTC_NAA 33723 /* Alias IPTC/NAA Newspaper Association RichTIFF */
#define TIFFTAG_EP_TIMEZONEOFFSET 34858 /* Time zone offset relative to UTC */
#define TIFFTAG_EP_SELFTIMERMODE 34859 /* Number of seconds capture was delayed from button press */
#define TIFFTAG_EP_FLASHENERGY 37387 /* Flash energy, or range if there is uncertainty */
#define TIFFTAG_EP_SPATIALFREQUENCYRESPONSE 37388 /* Spatial frequency response */
#define TIFFTAG_EP_NOISE 37389 /* Camera noise measurement values */
#define TIFFTAG_EP_FOCALPLANEXRESOLUTION 37390 /* Focal plane X resolution */
#define TIFFTAG_EP_FOCALPLANEYRESOLUTION 37391 /* Focal plane Y resolution */
#define TIFFTAG_EP_FOCALPLANERESOLUTIONUNIT 37392 /* Focal plane resolution unit */
#define TIFFTAG_EP_IMAGENUMBER 37393 /* Number of image when several of burst shot stored in same TIFF/EP */
#define TIFFTAG_EP_SECURITYCLASSIFICATION 37394 /* Security classification */
#define TIFFTAG_EP_IMAGEHISTORY 37395 /* Record of what has been done to the image */
#define TIFFTAG_EP_EXPOSUREINDEX 37397 /* Exposure index */
#define TIFFTAG_EP_STANDARDID 37398 /* TIFF/EP standard version, n.n.n.n */
#define TIFFTAG_EP_SENSINGMETHOD 37399 /* Type of image sensor */
/*
* TIFF/EP tags equivalent to EXIF tags
* Note that TIFF-EP and EXIF use nearly the same metadata tag set, but TIFF-EP stores the tags in IFD 0,
* while EXIF store the tags in a separate IFD. Either location is allowed by DNG, but the EXIF location is preferred.
*/
#define TIFFTAG_EP_EXPOSURETIME 33434 /* Exposure time */
#define TIFFTAG_EP_FNUMBER 33437 /* F number */
#define TIFFTAG_EP_EXPOSUREPROGRAM 34850 /* Exposure program */
#define TIFFTAG_EP_SPECTRALSENSITIVITY 34852 /* Spectral sensitivity */
#define TIFFTAG_EP_ISOSPEEDRATINGS 34855 /* ISO speed rating */
#define TIFFTAG_EP_OECF 34856 /* Optoelectric conversion factor */
#define TIFFTAG_EP_DATETIMEORIGINAL 36867 /* Date and time of original data generation */
#define TIFFTAG_EP_COMPRESSEDBITSPERPIXEL 37122 /* Image compression mode */
#define TIFFTAG_EP_SHUTTERSPEEDVALUE 37377 /* Shutter speed */
#define TIFFTAG_EP_APERTUREVALUE 37378 /* Aperture */
#define TIFFTAG_EP_BRIGHTNESSVALUE 37379 /* Brightness */
#define TIFFTAG_EP_EXPOSUREBIASVALUE 37380 /* Exposure bias */
#define TIFFTAG_EP_MAXAPERTUREVALUE 37381 /* Maximum lens aperture */
#define TIFFTAG_EP_SUBJECTDISTANCE 37382 /* Subject distance */
#define TIFFTAG_EP_METERINGMODE 37383 /* Metering mode */
#define TIFFTAG_EP_LIGHTSOURCE 37384 /* Light source */
#define TIFFTAG_EP_FLASH 37385 /* Flash */
#define TIFFTAG_EP_FOCALLENGTH 37386 /* Lens focal length */
#define TIFFTAG_EP_SUBJECTLOCATION 37396 /* Subject location (area) */
#define TIFFTAG_RPCCOEFFICIENT 50844 /* Define by GDAL for geospatial georeferencing through RPC: http://geotiff.maptools.org/rpc_prop.html */
#define TIFFTAG_ALIAS_LAYER_METADATA 50784 /* Alias Sketchbook Pro layer usage description. */
/* GeoTIFF DGIWG */
#define TIFFTAG_TIFF_RSID 50908 /* https://www.awaresystems.be/imaging/tiff/tifftags/tiff_rsid.html */
#define TIFFTAG_GEO_METADATA 50909 /* https://www.awaresystems.be/imaging/tiff/tifftags/geo_metadata.html */
#define TIFFTAG_EXTRACAMERAPROFILES 50933 /* http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/products/photoshop/pdfs/dng_spec_1.4.0.0.pdf */
/* tag 65535 is an undefined tag used by Eastman Kodak */
#define TIFFTAG_DCSHUESHIFTVALUES 65535 /* hue shift correction data */
/*
* The following are ``pseudo tags'' that can be used to control
* codec-specific functionality. These tags are not written to file.
* Note that these values start at 0xffff+1 so that they'll never
* collide with Aldus-assigned tags.
*
* If you want your private pseudo tags ``registered'' (i.e. added to
* this file), please post a bug report via the tracking system at
* http://www.remotesensing.org/libtiff/bugs.html with the appropriate
* C definitions to add.
*/
#define TIFFTAG_FAXMODE 65536 /* Group 3/4 format control */
#define FAXMODE_CLASSIC 0x0000 /* default, include RTC */
#define FAXMODE_NORTC 0x0001 /* no RTC at end of data */
#define FAXMODE_NOEOL 0x0002 /* no EOL code at end of row */
#define FAXMODE_BYTEALIGN 0x0004 /* byte align row */
#define FAXMODE_WORDALIGN 0x0008 /* word align row */
#define FAXMODE_CLASSF FAXMODE_NORTC /* TIFF Class F */
#define TIFFTAG_JPEGQUALITY 65537 /* Compression quality level */
/* Note: quality level is on the IJG 0-100 scale. Default value is 75 */
#define TIFFTAG_JPEGCOLORMODE 65538 /* Auto RGB<=>YCbCr convert? */
#define JPEGCOLORMODE_RAW 0x0000 /* no conversion (default) */
#define JPEGCOLORMODE_RGB 0x0001 /* do auto conversion */
#define TIFFTAG_JPEGTABLESMODE 65539 /* What to put in JPEGTables */
#define JPEGTABLESMODE_QUANT 0x0001 /* include quantization tbls */
#define JPEGTABLESMODE_HUFF 0x0002 /* include Huffman tbls */
/* Note: default is JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF */
#define TIFFTAG_FAXFILLFUNC 65540 /* G3/G4 fill function */
#define TIFFTAG_PIXARLOGDATAFMT 65549 /* PixarLogCodec I/O data sz */
#define PIXARLOGDATAFMT_8BIT 0 /* regular u_char samples */
#define PIXARLOGDATAFMT_8BITABGR 1 /* ABGR-order u_chars */
#define PIXARLOGDATAFMT_11BITLOG 2 /* 11-bit log-encoded (raw) */
#define PIXARLOGDATAFMT_12BITPICIO 3 /* as per PICIO (1.0==2048) */
#define PIXARLOGDATAFMT_16BIT 4 /* signed short samples */
#define PIXARLOGDATAFMT_FLOAT 5 /* IEEE float samples */
/* 65550-65556 are allocated to Oceana Matrix <dev@oceana.com> */
#define TIFFTAG_DCSIMAGERTYPE 65550 /* imager model & filter */
#define DCSIMAGERMODEL_M3 0 /* M3 chip (1280 x 1024) */
#define DCSIMAGERMODEL_M5 1 /* M5 chip (1536 x 1024) */
#define DCSIMAGERMODEL_M6 2 /* M6 chip (3072 x 2048) */
#define DCSIMAGERFILTER_IR 0 /* infrared filter */
#define DCSIMAGERFILTER_MONO 1 /* monochrome filter */
#define DCSIMAGERFILTER_CFA 2 /* color filter array */
#define DCSIMAGERFILTER_OTHER 3 /* other filter */
#define TIFFTAG_DCSINTERPMODE 65551 /* interpolation mode */
#define DCSINTERPMODE_NORMAL 0x0 /* whole image, default */
#define DCSINTERPMODE_PREVIEW 0x1 /* preview of image (384x256) */
#define TIFFTAG_DCSBALANCEARRAY 65552 /* color balance values */
#define TIFFTAG_DCSCORRECTMATRIX 65553 /* color correction values */
#define TIFFTAG_DCSGAMMA 65554 /* gamma value */
#define TIFFTAG_DCSTOESHOULDERPTS 65555 /* toe & shoulder points */
#define TIFFTAG_DCSCALIBRATIONFD 65556 /* calibration file desc */
/* Note: quality level is on the ZLIB 1-9 scale. Default value is -1 */
#define TIFFTAG_ZIPQUALITY 65557 /* compression quality level */
#define TIFFTAG_PIXARLOGQUALITY 65558 /* PixarLog uses same scale */
/* 65559 is allocated to Oceana Matrix <dev@oceana.com> */
#define TIFFTAG_DCSCLIPRECTANGLE 65559 /* area of image to acquire */
#define TIFFTAG_SGILOGDATAFMT 65560 /* SGILog user data format */
#define SGILOGDATAFMT_FLOAT 0 /* IEEE float samples */
#define SGILOGDATAFMT_16BIT 1 /* 16-bit samples */
#define SGILOGDATAFMT_RAW 2 /* uninterpreted data */
#define SGILOGDATAFMT_8BIT 3 /* 8-bit RGB monitor values */
#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 */
#define TIFFTAG_ZSTD_LEVEL 65564 /* ZSTD compression level */
#define TIFFTAG_LERC_VERSION 65565 /* LERC version */
#define LERC_VERSION_2_4 4
#define TIFFTAG_LERC_ADD_COMPRESSION 65566 /* LERC additional compression */
#define LERC_ADD_COMPRESSION_NONE 0
#define LERC_ADD_COMPRESSION_DEFLATE 1
#define LERC_ADD_COMPRESSION_ZSTD 2
#define TIFFTAG_LERC_MAXZERROR 65567 /* LERC maximum error */
#define TIFFTAG_WEBP_LEVEL 65568 /* WebP compression level */
#define TIFFTAG_WEBP_LOSSLESS 65569 /* WebP lossless/lossy */
#define TIFFTAG_WEBP_LOSSLESS_EXACT 65571 /* WebP lossless exact mode. Set-only mode. Default is 1. Can be set to 0 to increase compression rate, but R,G,B in areas where alpha = 0 will not be preserved */
#define TIFFTAG_DEFLATE_SUBCODEC 65570 /* ZIP codec: to get/set the sub-codec to use. Will default to libdeflate when available */
#define DEFLATE_SUBCODEC_ZLIB 0
#define DEFLATE_SUBCODEC_LIBDEFLATE 1
/*
* EXIF tags
*/
#define EXIFTAG_EXPOSURETIME 33434 /* Exposure time */
#define EXIFTAG_FNUMBER 33437 /* F number */
#define EXIFTAG_EXPOSUREPROGRAM 34850 /* Exposure program */
#define EXIFTAG_SPECTRALSENSITIVITY 34852 /* Spectral sensitivity */
/* After EXIF 2.2.1 ISOSpeedRatings is named PhotographicSensitivity.
In addition, while "Count=Any", only 1 count should be used. */
#define EXIFTAG_ISOSPEEDRATINGS 34855 /* ISO speed rating */
#define EXIFTAG_PHOTOGRAPHICSENSITIVITY 34855 /* Photographic Sensitivity (new name for tag 34855) */
#define EXIFTAG_OECF 34856 /* Optoelectric conversion factor */
#define EXIFTAG_EXIFVERSION 36864 /* Exif version */
#define EXIFTAG_DATETIMEORIGINAL 36867 /* Date and time of original data generation */
#define EXIFTAG_DATETIMEDIGITIZED 36868 /* Date and time of digital data generation */
#define EXIFTAG_COMPONENTSCONFIGURATION 37121 /* Meaning of each component */
#define EXIFTAG_COMPRESSEDBITSPERPIXEL 37122 /* Image compression mode */
#define EXIFTAG_SHUTTERSPEEDVALUE 37377 /* Shutter speed */
#define EXIFTAG_APERTUREVALUE 37378 /* Aperture */
#define EXIFTAG_BRIGHTNESSVALUE 37379 /* Brightness */
#define EXIFTAG_EXPOSUREBIASVALUE 37380 /* Exposure bias */
#define EXIFTAG_MAXAPERTUREVALUE 37381 /* Maximum lens aperture */
#define EXIFTAG_SUBJECTDISTANCE 37382 /* Subject distance */
#define EXIFTAG_METERINGMODE 37383 /* Metering mode */
#define EXIFTAG_LIGHTSOURCE 37384 /* Light source */
#define EXIFTAG_FLASH 37385 /* Flash */
#define EXIFTAG_FOCALLENGTH 37386 /* Lens focal length */
#define EXIFTAG_SUBJECTAREA 37396 /* Subject area */
#define EXIFTAG_MAKERNOTE 37500 /* Manufacturer notes */
#define EXIFTAG_USERCOMMENT 37510 /* User comments */
#define EXIFTAG_SUBSECTIME 37520 /* DateTime subseconds */
#define EXIFTAG_SUBSECTIMEORIGINAL 37521 /* DateTimeOriginal subseconds */
#define EXIFTAG_SUBSECTIMEDIGITIZED 37522 /* DateTimeDigitized subseconds */
#define EXIFTAG_FLASHPIXVERSION 40960 /* Supported Flashpix version */
#define EXIFTAG_COLORSPACE 40961 /* Color space information */
#define EXIFTAG_PIXELXDIMENSION 40962 /* Valid image width */
#define EXIFTAG_PIXELYDIMENSION 40963 /* Valid image height */
#define EXIFTAG_RELATEDSOUNDFILE 40964 /* Related audio file */
#define EXIFTAG_FLASHENERGY 41483 /* Flash energy */
#define EXIFTAG_SPATIALFREQUENCYRESPONSE 41484 /* Spatial frequency response */
#define EXIFTAG_FOCALPLANEXRESOLUTION 41486 /* Focal plane X resolution */
#define EXIFTAG_FOCALPLANEYRESOLUTION 41487 /* Focal plane Y resolution */
#define EXIFTAG_FOCALPLANERESOLUTIONUNIT 41488 /* Focal plane resolution unit */
#define EXIFTAG_SUBJECTLOCATION 41492 /* Subject location */
#define EXIFTAG_EXPOSUREINDEX 41493 /* Exposure index */
#define EXIFTAG_SENSINGMETHOD 41495 /* Sensing method */
#define EXIFTAG_FILESOURCE 41728 /* File source */
#define EXIFTAG_SCENETYPE 41729 /* Scene type */
#define EXIFTAG_CFAPATTERN 41730 /* CFA pattern */
#define EXIFTAG_CUSTOMRENDERED 41985 /* Custom image processing */
#define EXIFTAG_EXPOSUREMODE 41986 /* Exposure mode */
#define EXIFTAG_WHITEBALANCE 41987 /* White balance */
#define EXIFTAG_DIGITALZOOMRATIO 41988 /* Digital zoom ratio */
#define EXIFTAG_FOCALLENGTHIN35MMFILM 41989 /* Focal length in 35 mm film */
#define EXIFTAG_SCENECAPTURETYPE 41990 /* Scene capture type */
#define EXIFTAG_GAINCONTROL 41991 /* Gain control */
#define EXIFTAG_CONTRAST 41992 /* Contrast */
#define EXIFTAG_SATURATION 41993 /* Saturation */
#define EXIFTAG_SHARPNESS 41994 /* Sharpness */
#define EXIFTAG_DEVICESETTINGDESCRIPTION 41995 /* Device settings description */
#define EXIFTAG_SUBJECTDISTANCERANGE 41996 /* Subject distance range */
#define EXIFTAG_IMAGEUNIQUEID 42016 /* Unique image ID */
/*--: New for EXIF-Version 2.32, May 2019 ... */
#define EXIFTAG_SENSITIVITYTYPE 34864 /* The SensitivityType tag indicates which one of the parameters of ISO12232 is the PhotographicSensitivity tag. */
#define EXIFTAG_STANDARDOUTPUTSENSITIVITY 34865 /* This tag indicates the standard output sensitivity value of a camera or input device defined in ISO 12232. */
#define EXIFTAG_RECOMMENDEDEXPOSUREINDEX 34866 /* recommended exposure index */
#define EXIFTAG_ISOSPEED 34867 /* ISO speed value */
#define EXIFTAG_ISOSPEEDLATITUDEYYY 34868 /* ISO speed latitude yyy */
#define EXIFTAG_ISOSPEEDLATITUDEZZZ 34869 /* ISO speed latitude zzz */
#define EXIFTAG_OFFSETTIME 36880 /* offset from UTC of the time of DateTime tag. */
#define EXIFTAG_OFFSETTIMEORIGINAL 36881 /* offset from UTC of the time of DateTimeOriginal tag. */
#define EXIFTAG_OFFSETTIMEDIGITIZED 36882 /* offset from UTC of the time of DateTimeDigitized tag. */
#define EXIFTAG_TEMPERATURE 37888 /* Temperature as the ambient situation at the shot in dergee Celsius */
#define EXIFTAG_HUMIDITY 37889 /* Humidity as the ambient situation at the shot in percent */
#define EXIFTAG_PRESSURE 37890 /* Pressure as the ambient situation at the shot hecto-Pascal (hPa) */
#define EXIFTAG_WATERDEPTH 37891 /* WaterDepth as the ambient situation at the shot in meter (m) */
#define EXIFTAG_ACCELERATION 37892 /* Acceleration (a scalar regardless of direction) as the ambientsituation at the shot in units of mGal (10-5 m/s^2) */
/* EXIFTAG_CAMERAELEVATIONANGLE: Elevation/depression. angle of the orientation of the camera(imaging optical axis)
* as the ambient situation at the shot in degree from -180deg to +180deg. */
#define EXIFTAG_CAMERAELEVATIONANGLE 37893
#define EXIFTAG_CAMERAOWNERNAME 42032 /* owner of a camera */
#define EXIFTAG_BODYSERIALNUMBER 42033 /* serial number of the body of the camera */
/* EXIFTAG_LENSSPECIFICATION: minimum focal length (in mm), maximum focal length (in mm),minimum F number in the minimum focal length,
* and minimum F number in the maximum focal length, */
#define EXIFTAG_LENSSPECIFICATION 42034
#define EXIFTAG_LENSMAKE 42035 /* the lens manufacturer */
#define EXIFTAG_LENSMODEL 42036 /* the lens model name and model number */
#define EXIFTAG_LENSSERIALNUMBER 42037 /* the serial number of the interchangeable lens */
#define EXIFTAG_GAMMA 42240 /* value of coefficient gamma */
#define EXIFTAG_COMPOSITEIMAGE 42080 /* composite image */
#define EXIFTAG_SOURCEIMAGENUMBEROFCOMPOSITEIMAGE 42081 /* source image number of composite image */
#define EXIFTAG_SOURCEEXPOSURETIMESOFCOMPOSITEIMAGE 42082 /* source exposure times of composite image */
/*
* EXIF-GPS tags (Version 2.31, July 2016)
*/
#define GPSTAG_VERSIONID 0 /* Indicates the version of GPSInfoIFD. */
#define GPSTAG_LATITUDEREF 1 /* Indicates whether the latitude is north or south latitude. */
#define GPSTAG_LATITUDE 2 /* Indicates the latitude. */
#define GPSTAG_LONGITUDEREF 3 /* Indicates whether the longitude is east or west longitude. */
#define GPSTAG_LONGITUDE 4 /* Indicates the longitude. */
#define GPSTAG_ALTITUDEREF 5 /* Indicates the altitude used as the reference altitude. */
#define GPSTAG_ALTITUDE 6 /* Indicates the altitude based on the reference in GPSAltitudeRef. */
#define GPSTAG_TIMESTAMP 7 /*Indicates the time as UTC (Coordinated Universal Time). */
#define GPSTAG_SATELLITES 8 /*Indicates the GPS satellites used for measurements. */
#define GPSTAG_STATUS 9 /* Indicates the status of the GPS receiver when the image is recorded. */
#define GPSTAG_MEASUREMODE 10 /* Indicates the GPS measurement mode. */
#define GPSTAG_DOP 11 /* Indicates the GPS DOP (data degree of precision). */
#define GPSTAG_SPEEDREF 12 /* Indicates the unit used to express the GPS receiver speed of movement. */
#define GPSTAG_SPEED 13 /* Indicates the speed of GPS receiver movement. */
#define GPSTAG_TRACKREF 14 /* Indicates the reference for giving the direction of GPS receiver movement. */
#define GPSTAG_TRACK 15 /* Indicates the direction of GPS receiver movement. */
#define GPSTAG_IMGDIRECTIONREF 16 /* Indicates the reference for giving the direction of the image when it is captured. */
#define GPSTAG_IMGDIRECTION 17 /* Indicates the direction of the image when it was captured. */
#define GPSTAG_MAPDATUM 18 /* Indicates the geodetic survey data used by the GPS receiver. (e.g. WGS-84) */
#define GPSTAG_DESTLATITUDEREF 19 /* Indicates whether the latitude of the destination point is north or south latitude. */
#define GPSTAG_DESTLATITUDE 20 /* Indicates the latitude of the destination point. */
#define GPSTAG_DESTLONGITUDEREF 21 /* Indicates whether the longitude of the destination point is east or west longitude. */
#define GPSTAG_DESTLONGITUDE 22 /* Indicates the longitude of the destination point. */
#define GPSTAG_DESTBEARINGREF 23 /* Indicates the reference used for giving the bearing to the destination point. */
#define GPSTAG_DESTBEARING 24 /* Indicates the bearing to the destination point. */
#define GPSTAG_DESTDISTANCEREF 25 /* Indicates the unit used to express the distance to the destination point. */
#define GPSTAG_DESTDISTANCE 26 /* Indicates the distance to the destination point. */
#define GPSTAG_PROCESSINGMETHOD 27 /* A character string recording the name of the method used for location finding. */
#define GPSTAG_AREAINFORMATION 28 /* A character string recording the name of the GPS area. */
#define GPSTAG_DATESTAMP 29 /* A character string recording date and time information relative to UTC (Coordinated Universal Time). */
#define GPSTAG_DIFFERENTIAL 30 /* Indicates whether differential correction is applied to the GPS receiver. */
#define GPSTAG_GPSHPOSITIONINGERROR 31 /* Indicates horizontal positioning errors in meters. */
#endif /* _TIFF_ */
+144
View File
@@ -0,0 +1,144 @@
/*
Configuration defines for installed libtiff.
This file maintained for backward compatibility. Do not use definitions
from this file in your programs.
*/
/* clang-format off */
/* clang-format disabled because CMake scripts are very sensitive to the
* formatting of this file. configure_file variables of type "@VAR@" are
* modified by clang-format and won't be substituted.
*/
#ifndef _TIFFCONF_
#define _TIFFCONF_
#include <stddef.h>
#include <stdint.h>
#include <inttypes.h>
/* Signed 16-bit type */
#define TIFF_INT16_T @TIFF_INT16_T@
/* Signed 32-bit type */
#define TIFF_INT32_T @TIFF_INT32_T@
/* Signed 64-bit type */
#define TIFF_INT64_T @TIFF_INT64_T@
/* Signed 8-bit type */
#define TIFF_INT8_T @TIFF_INT8_T@
/* Unsigned 16-bit type */
#define TIFF_UINT16_T @TIFF_UINT16_T@
/* Unsigned 32-bit type */
#define TIFF_UINT32_T @TIFF_UINT32_T@
/* Unsigned 64-bit type */
#define TIFF_UINT64_T @TIFF_UINT64_T@
/* Unsigned 8-bit type */
#define TIFF_UINT8_T @TIFF_UINT8_T@
/* Signed size type */
#define TIFF_SSIZE_T @TIFF_SSIZE_T@
/* Compatibility stuff. */
/* Define as 0 or 1 according to the floating point format supported by the
machine */
#cmakedefine HAVE_IEEEFP 1
/* The concept of HOST_FILLORDER is broken. Since libtiff 4.5.1
* this macro will always be hardcoded to FILLORDER_LSB2MSB on all
* architectures, to reflect past long behavior of doing so on x86 architecture.
* Note however that the default FillOrder used by libtiff is FILLORDER_MSB2LSB,
* as mandated per the TIFF specification.
* The influence of HOST_FILLORDER is only when passing the 'H' mode in
* TIFFOpen().
* You should NOT rely on this macro to decide the CPU endianness!
* This macro will be removed in libtiff 4.6
*/
#define HOST_FILLORDER FILLORDER_LSB2MSB
/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian
(Intel) */
#define HOST_BIGENDIAN @HOST_BIG_ENDIAN@
/* Support CCITT Group 3 & 4 algorithms */
#cmakedefine CCITT_SUPPORT 1
/* Support JPEG compression (requires IJG JPEG library) */
#cmakedefine JPEG_SUPPORT 1
/* Support JBIG compression (requires JBIG-KIT library) */
#cmakedefine JBIG_SUPPORT
/* Support LERC compression */
#cmakedefine LERC_SUPPORT 1
/* Support LogLuv high dynamic range encoding */
#cmakedefine LOGLUV_SUPPORT 1
/* Support LZW algorithm */
#cmakedefine LZW_SUPPORT 1
/* Support NeXT 2-bit RLE algorithm */
#cmakedefine NEXT_SUPPORT 1
/* Support Old JPEG compression (read contrib/ojpeg/README first! Compilation
fails with unpatched IJG JPEG library) */
#cmakedefine OJPEG_SUPPORT 1
/* Support Macintosh PackBits algorithm */
#cmakedefine PACKBITS_SUPPORT 1
/* Support Pixar log-format algorithm (requires Zlib) */
#cmakedefine PIXARLOG_SUPPORT 1
/* Support ThunderScan 4-bit RLE algorithm */
#cmakedefine THUNDER_SUPPORT 1
/* Support Deflate compression */
#cmakedefine ZIP_SUPPORT 1
/* Support libdeflate enhanced compression */
#cmakedefine LIBDEFLATE_SUPPORT 1
/* Support strip chopping (whether or not to convert single-strip uncompressed
images to multiple strips of ~8Kb to reduce memory usage) */
#cmakedefine STRIPCHOP_DEFAULT TIFF_STRIPCHOP
/* Enable SubIFD tag (330) support */
#cmakedefine SUBIFD_SUPPORT 1
/* Treat extra sample as alpha (default enabled). The RGBA interface will
treat a fourth sample with no EXTRASAMPLE_ value as being ASSOCALPHA. Many
packages produce RGBA files but don't mark the alpha properly. */
#cmakedefine DEFAULT_EXTRASAMPLE_AS_ALPHA 1
/* Pick up YCbCr subsampling info from the JPEG data stream to support files
lacking the tag (default enabled). */
#cmakedefine CHECK_JPEG_YCBCR_SUBSAMPLING 1
/* Support MS MDI magic number files as TIFF */
#cmakedefine MDI_SUPPORT 1
/*
* Feature support definitions.
* XXX: These macros are obsoleted. Don't use them in your apps!
* Macros stays here for backward compatibility and should be always defined.
*/
#define COLORIMETRY_SUPPORT
#define YCBCR_SUPPORT
#define CMYK_SUPPORT
#define ICC_SUPPORT
#define PHOTOSHOP_SUPPORT
#define IPTC_SUPPORT
#endif /* _TIFFCONF_ */
/* clang-format on */
+671
View File
@@ -0,0 +1,671 @@
/*
* 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.
*/
#ifndef _TIFFIO_
#define _TIFFIO_
/*
* TIFF I/O Library Definitions.
*/
#include "tiff.h"
#include "tiffvers.h"
/*
* TIFF is defined as an incomplete type to hide the
* library's internal data structures from clients.
*/
typedef struct tiff TIFF;
/*
* The following typedefs define the intrinsic size of
* data types used in the *exported* interfaces. These
* definitions depend on the proper definition of types
* in tiff.h. Note also that the varargs interface used
* to pass tag types and values uses the types defined in
* tiff.h directly.
*
* NB: ttag_t -> deprecated and replaced by uint32_t
* is unsigned int and not unsigned short because
* ANSI C requires that the type before the ellipsis be a
* promoted type (i.e. one of int, unsigned int, pointer,
* or double) and because we defined pseudo-tags that are
* outside the range of legal Aldus-assigned tags.
* NB: tsize_t -> deprecated and replaced by tmsize_t
* is signed and not unsigned because some functions
* return -1.
* NB: toff_t is not off_t for many reasons; TIFFs max out at
* 32-bit file offsets, and BigTIFF maxes out at 64-bit
* 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_t on 32bit machines, int64_t on 64bit machines
*/
typedef TIFF_SSIZE_T tmsize_t;
#define TIFF_TMSIZE_T_MAX (tmsize_t)(SIZE_MAX >> 1)
typedef uint64_t toff_t; /* file offset */
typedef uint32_t tdir_t; /* directory index */
/* the following are deprecated and should be replaced by their defining
counterparts */
typedef uint32_t ttag_t; /* directory tag */
typedef uint16_t tsample_t; /* sample number */
typedef uint32_t tstrile_t; /* strip or tile number */
typedef tstrile_t tstrip_t; /* strip number */
typedef tstrile_t ttile_t; /* tile number */
typedef tmsize_t tsize_t; /* i/o size in bytes */
typedef void *tdata_t; /* image data ref */
/*
* On windows you should define USE_WIN32_FILEIO if you are using tif_win32.c
* or AVOID_WIN32_FILEIO if you are using something else (like tif_unix.c).
*
* By default tif_unix.c is assumed.
*/
#if defined(_WIN32)
#if !defined(__CYGWIN) && !defined(AVOID_WIN32_FILEIO) && \
!defined(USE_WIN32_FILEIO)
#define AVOID_WIN32_FILEIO
#endif
#endif
#if defined(USE_WIN32_FILEIO)
#define VC_EXTRALEAN
#include <windows.h>
#ifdef _WIN32
DECLARE_HANDLE(thandle_t); /* Win32 file handle */
#else
typedef HFILE thandle_t; /* client data handle */
#endif /* _WIN32 */
#else
typedef void *thandle_t; /* client data handle */
#endif /* USE_WIN32_FILEIO */
/*
* Flags to pass to TIFFPrintDirectory to control
* printing of data structures that are potentially
* 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 */
/*
* Colour conversion stuff
*/
/* reference white */
#define D65_X0 (95.0470F)
#define D65_Y0 (100.0F)
#define D65_Z0 (108.8827F)
#define D50_X0 (96.4250F)
#define D50_Y0 (100.0F)
#define D50_Z0 (82.4680F)
/* Structure for holding information about a display device. */
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_YCG;
float d_YCB;
uint32_t d_Vrwr; /* Pixel values for ref. white */
uint32_t d_Vrwg;
uint32_t d_Vrwb;
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_gammaG;
float d_gammaB;
} TIFFDisplay;
/* YCbCr->RGB support for TIFFYCbCrToRGBInit() and TIFFYCbCrToRGB()
* Attention:
* Functions TIFFYCbCrToRGBInit() and TIFFYCbCrToRGB() require a user provided
* large memory buffer, where several tables can be setup.
* The pointers to these tables are stored in the structure TIFFYCbCrToRGB,
* which is located at the beginning of the buffer. Thus, this memory has to be
* allocated as follows:
* TIFFYCbCrToRGB *ycbcr = (TIFFYCbCrToRGB *)_TIFFmalloc(
* TIFFroundup_32(sizeof(TIFFYCbCrToRGB), sizeof(long)) +
* 4 * 256 * sizeof(TIFFRGBValue) + 2 * 256 * sizeof(int) +
* 3 * 256 * sizeof(int32_t));
*/
typedef struct
{ /* YCbCr->RGB support */
TIFFRGBValue *clamptab; /* range clamping table */
int *Cr_r_tab;
int *Cb_b_tab;
int32_t *Cr_g_tab;
int32_t *Cb_g_tab;
int32_t *Y_tab;
} TIFFYCbCrToRGB;
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 */
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 */
} TIFFCIELabToRGB;
/*
* RGBA-style image support.
*/
typedef struct _TIFFRGBAImage TIFFRGBAImage;
/*
* The image reading and conversion routines invoke
* ``put routines'' to copy/image/whatever tiles of
* raw image data. A default set of routines are
* provided to convert/copy raw image data to 8-bit
* packed ABGR format rasters. Applications can supply
* alternate routines that unpack the data into a
* different format or, for example, unpack the data
* and draw the unpacked raster on the display.
*/
typedef void (*tileContigRoutine)(TIFFRGBAImage *, uint32_t *, uint32_t,
uint32_t, uint32_t, uint32_t, int32_t,
int32_t, unsigned char *);
typedef void (*tileSeparateRoutine)(TIFFRGBAImage *, uint32_t *, uint32_t,
uint32_t, uint32_t, uint32_t, int32_t,
int32_t, unsigned char *, unsigned char *,
unsigned char *, unsigned char *);
/*
* RGBA-reader state.
*/
struct _TIFFRGBAImage
{
TIFF *tif; /* image handle */
int stoponerr; /* stop on read error */
int isContig; /* data is packed/separate */
int alpha; /* type of alpha data present */
uint32_t width; /* image width */
uint32_t height; /* image height */
uint16_t bitspersample; /* image bits/sample */
uint16_t samplesperpixel; /* image samples/pixel */
uint16_t orientation; /* image orientation */
uint16_t req_orientation; /* requested orientation */
uint16_t photometric; /* image photometric interp */
uint16_t *redcmap; /* colormap palette */
uint16_t *greencmap;
uint16_t *bluecmap;
/* get image data routine */
int (*get)(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t);
/* put decoded strip/tile */
union
{
void (*any)(TIFFRGBAImage *);
tileContigRoutine contig;
tileSeparateRoutine separate;
} put;
TIFFRGBValue *Map; /* sample mapping array */
uint32_t **BWmap; /* black&white map */
uint32_t **PALmap; /* palette image map */
TIFFYCbCrToRGB *ycbcr; /* YCbCr conversion state */
TIFFCIELabToRGB *cielab; /* CIE L*a*b conversion state */
uint8_t *UaToAa; /* Unassociated alpha to associated alpha conversion LUT */
uint8_t *Bitdepth16To8; /* LUT for conversion from 16bit to 8bit values */
int row_offset;
int col_offset;
};
/*
* 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)
/*
* A CODEC is a software package that implements decoding,
* encoding, or decoding+encoding of a compression algorithm.
* The library provides a collection of builtin codecs.
* More codecs may be registered through calls to the library
* and/or the builtin implementations may be overridden.
*/
typedef int (*TIFFInitMethod)(TIFF *, int);
typedef struct
{
char *name;
uint16_t scheme;
TIFFInitMethod init;
} TIFFCodec;
typedef struct
{
uint32_t uNum;
uint32_t uDenom;
} TIFFRational_t;
#include <stdarg.h>
#include <stdio.h>
/* share internal LogLuv conversion routines? */
#ifndef LOGLUV_PUBLIC
#define LOGLUV_PUBLIC 1
#endif
#if defined(__GNUC__) || defined(__clang__) || defined(__attribute__)
#define TIFF_ATTRIBUTE(x) __attribute__(x)
#else
#define TIFF_ATTRIBUTE(x) /*nothing*/
#endif
#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 int (*TIFFErrorHandlerExtR)(TIFF *, void *user_data, 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_t);
extern TIFFCodec *TIFFRegisterCODEC(uint16_t, const char *, TIFFInitMethod);
extern void TIFFUnRegisterCODEC(TIFFCodec *);
extern int TIFFIsCODECConfigured(uint16_t);
extern TIFFCodec *TIFFGetConfiguredCODECs(void);
/*
* Auxiliary functions.
*/
#ifndef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
extern void *_TIFFmalloc(tmsize_t s);
extern void *_TIFFcalloc(tmsize_t nmemb, tmsize_t siz);
extern void *_TIFFrealloc(void *p, tmsize_t s);
extern void _TIFFfree(void *p);
#endif
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);
/*
** Stuff, related to tag handling and creating custom tags.
*/
extern int TIFFGetTagListCount(TIFF *);
extern uint32_t 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_t var-length tags */
#define FIELD_CUSTOM 65
typedef struct _TIFFField TIFFField;
typedef struct _TIFFFieldArray TIFFFieldArray;
extern const TIFFField *TIFFFindField(TIFF *, uint32_t, TIFFDataType);
extern const TIFFField *TIFFFieldWithTag(TIFF *, uint32_t);
extern const TIFFField *TIFFFieldWithName(TIFF *, const char *);
extern uint32_t TIFFFieldTag(const TIFFField *);
extern const char *TIFFFieldName(const TIFFField *);
extern TIFFDataType TIFFFieldDataType(const TIFFField *);
extern int TIFFFieldPassCount(const TIFFField *);
extern int TIFFFieldReadCount(const TIFFField *);
extern int TIFFFieldWriteCount(const TIFFField *);
extern int
TIFFFieldSetGetSize(const TIFFField *); /* returns internal storage size of
TIFFSetGetFieldType in bytes. */
extern int TIFFFieldSetGetCountSize(
const TIFFField *); /* returns size of count parameter 0=none,
2=uint16_t, 4=uint32_t */
extern int TIFFFieldIsAnonymous(const TIFFField *);
typedef int (*TIFFVSetMethod)(TIFF *, uint32_t, va_list);
typedef int (*TIFFVGetMethod)(TIFF *, uint32_t, va_list);
typedef void (*TIFFPrintMethod)(TIFF *, FILE *, long);
typedef struct
{
TIFFVSetMethod vsetfield; /* tag set routine */
TIFFVGetMethod vgetfield; /* tag get routine */
TIFFPrintMethod printdir; /* directory print routine */
} TIFFTagMethods;
extern 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_t tag, ...);
extern int TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap);
extern int TIFFGetFieldDefaulted(TIFF *tif, uint32_t tag, ...);
extern int TIFFVGetFieldDefaulted(TIFF *tif, uint32_t 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 int TIFFReadGPSDirectory(TIFF *tif, toff_t diroff);
extern uint64_t TIFFScanlineSize64(TIFF *tif);
extern tmsize_t TIFFScanlineSize(TIFF *tif);
extern uint64_t TIFFRasterScanlineSize64(TIFF *tif);
extern tmsize_t TIFFRasterScanlineSize(TIFF *tif);
extern uint64_t TIFFStripSize64(TIFF *tif);
extern tmsize_t TIFFStripSize(TIFF *tif);
extern uint64_t TIFFRawStripSize64(TIFF *tif, uint32_t strip);
extern tmsize_t TIFFRawStripSize(TIFF *tif, uint32_t strip);
extern uint64_t TIFFVStripSize64(TIFF *tif, uint32_t nrows);
extern tmsize_t TIFFVStripSize(TIFF *tif, uint32_t nrows);
extern uint64_t TIFFTileRowSize64(TIFF *tif);
extern tmsize_t TIFFTileRowSize(TIFF *tif);
extern uint64_t TIFFTileSize64(TIFF *tif);
extern tmsize_t TIFFTileSize(TIFF *tif);
extern uint64_t TIFFVTileSize64(TIFF *tif, uint32_t nrows);
extern tmsize_t TIFFVTileSize(TIFF *tif, uint32_t nrows);
extern uint32_t TIFFDefaultStripSize(TIFF *tif, uint32_t request);
extern void TIFFDefaultTileSize(TIFF *, uint32_t *, uint32_t *);
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 int TIFFIsBigTIFF(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_t TIFFCurrentRow(TIFF *);
extern tdir_t TIFFCurrentDirectory(TIFF *);
extern tdir_t TIFFNumberOfDirectories(TIFF *);
extern uint64_t TIFFCurrentDirOffset(TIFF *);
extern uint32_t TIFFCurrentStrip(TIFF *);
extern uint32_t TIFFCurrentTile(TIFF *tif);
extern int TIFFReadBufferSetup(TIFF *tif, void *bp, tmsize_t size);
extern int TIFFWriteBufferSetup(TIFF *tif, void *bp, tmsize_t size);
extern int TIFFSetupStrips(TIFF *);
extern int TIFFWriteCheck(TIFF *, int, const char *);
extern void TIFFFreeDirectory(TIFF *);
extern int TIFFCreateDirectory(TIFF *);
extern int TIFFCreateCustomDirectory(TIFF *, const TIFFFieldArray *);
extern int TIFFCreateEXIFDirectory(TIFF *);
extern int TIFFCreateGPSDirectory(TIFF *);
extern int TIFFLastDirectory(TIFF *);
extern int TIFFSetDirectory(TIFF *, tdir_t);
extern int TIFFSetSubDirectory(TIFF *, uint64_t);
extern int TIFFUnlinkDirectory(TIFF *, tdir_t);
extern int TIFFSetField(TIFF *, uint32_t, ...);
extern int TIFFVSetField(TIFF *, uint32_t, va_list);
extern int TIFFUnsetField(TIFF *, uint32_t);
extern int TIFFWriteDirectory(TIFF *);
extern int TIFFWriteCustomDirectory(TIFF *, uint64_t *);
extern int TIFFCheckpointDirectory(TIFF *);
extern int TIFFRewriteDirectory(TIFF *);
extern int TIFFDeferStrileArrayWriting(TIFF *);
extern int TIFFForceStrileArrayWriting(TIFF *);
#if defined(c_plusplus) || defined(__cplusplus)
extern void TIFFPrintDirectory(TIFF *, FILE *, long = 0);
extern int TIFFReadScanline(TIFF *tif, void *buf, uint32_t row,
uint16_t sample = 0);
extern int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row,
uint16_t sample = 0);
extern int TIFFReadRGBAImage(TIFF *, uint32_t, uint32_t, uint32_t *,
int = 0);
extern int TIFFReadRGBAImageOriented(TIFF *, uint32_t, uint32_t, uint32_t *,
int = ORIENTATION_BOTLEFT, int = 0);
#else
extern void TIFFPrintDirectory(TIFF *, FILE *, long);
extern int TIFFReadScanline(TIFF *tif, void *buf, uint32_t row,
uint16_t sample);
extern int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row,
uint16_t sample);
extern int TIFFReadRGBAImage(TIFF *, uint32_t, uint32_t, uint32_t *, int);
extern int TIFFReadRGBAImageOriented(TIFF *, uint32_t, uint32_t, uint32_t *,
int, int);
#endif
extern int TIFFReadRGBAStrip(TIFF *, uint32_t, uint32_t *);
extern int TIFFReadRGBATile(TIFF *, uint32_t, uint32_t, uint32_t *);
extern int TIFFReadRGBAStripExt(TIFF *, uint32_t, uint32_t *,
int stop_on_error);
extern int TIFFReadRGBATileExt(TIFF *, uint32_t, uint32_t, uint32_t *,
int stop_on_error);
extern int TIFFRGBAImageOK(TIFF *, char[1024]);
extern int TIFFRGBAImageBegin(TIFFRGBAImage *, TIFF *, int, char[1024]);
extern int TIFFRGBAImageGet(TIFFRGBAImage *, uint32_t *, uint32_t,
uint32_t);
extern void TIFFRGBAImageEnd(TIFFRGBAImage *);
extern const char *TIFFFileName(TIFF *);
extern const char *TIFFSetFileName(TIFF *, const char *);
extern void TIFFError(const char *, const char *, ...)
TIFF_ATTRIBUTE((__format__(__printf__, 2, 3)));
extern void TIFFErrorExt(thandle_t, const char *, const char *, ...)
TIFF_ATTRIBUTE((__format__(__printf__, 3, 4)));
extern void TIFFWarning(const char *, const char *, ...)
TIFF_ATTRIBUTE((__format__(__printf__, 2, 3)));
extern void TIFFWarningExt(thandle_t, const char *, const char *, ...)
TIFF_ATTRIBUTE((__format__(__printf__, 3, 4)));
extern TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler);
extern TIFFErrorHandlerExt TIFFSetErrorHandlerExt(TIFFErrorHandlerExt);
extern TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler);
extern TIFFErrorHandlerExt TIFFSetWarningHandlerExt(TIFFErrorHandlerExt);
extern void TIFFWarningExtR(TIFF *, const char *, const char *, ...)
TIFF_ATTRIBUTE((__format__(__printf__, 3, 4)));
extern void TIFFErrorExtR(TIFF *, const char *, const char *, ...)
TIFF_ATTRIBUTE((__format__(__printf__, 3, 4)));
typedef struct TIFFOpenOptions TIFFOpenOptions;
extern TIFFOpenOptions *TIFFOpenOptionsAlloc(void);
extern void TIFFOpenOptionsFree(TIFFOpenOptions *);
extern void
TIFFOpenOptionsSetMaxSingleMemAlloc(TIFFOpenOptions *opts,
tmsize_t max_single_mem_alloc);
extern void
TIFFOpenOptionsSetMaxCumulatedMemAlloc(TIFFOpenOptions *opts,
tmsize_t max_cumulated_mem_alloc);
extern void
TIFFOpenOptionsSetWarnAboutUnknownTags(TIFFOpenOptions *opts,
int warn_about_unknown_tags);
extern void
TIFFOpenOptionsSetErrorHandlerExtR(TIFFOpenOptions *opts,
TIFFErrorHandlerExtR handler,
void *errorhandler_user_data);
extern void
TIFFOpenOptionsSetWarningHandlerExtR(TIFFOpenOptions *opts,
TIFFErrorHandlerExtR handler,
void *warnhandler_user_data);
extern TIFF *TIFFOpen(const char *, const char *);
extern TIFF *TIFFOpenExt(const char *, const char *, TIFFOpenOptions *opts);
#ifdef _WIN32
extern TIFF *TIFFOpenW(const wchar_t *, const char *);
extern TIFF *TIFFOpenWExt(const wchar_t *, const char *,
TIFFOpenOptions *opts);
#endif /* _WIN32 */
extern TIFF *TIFFFdOpen(int, const char *, const char *);
extern TIFF *TIFFFdOpenExt(int, const char *, const char *,
TIFFOpenOptions *opts);
extern TIFF *TIFFClientOpen(const char *, const char *, thandle_t,
TIFFReadWriteProc, TIFFReadWriteProc,
TIFFSeekProc, TIFFCloseProc, TIFFSizeProc,
TIFFMapFileProc, TIFFUnmapFileProc);
extern TIFF *TIFFClientOpenExt(const char *, const char *, thandle_t,
TIFFReadWriteProc, TIFFReadWriteProc,
TIFFSeekProc, TIFFCloseProc, TIFFSizeProc,
TIFFMapFileProc, TIFFUnmapFileProc,
TIFFOpenOptions *opts);
extern TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc);
extern uint32_t TIFFComputeTile(TIFF *tif, uint32_t x, uint32_t y,
uint32_t z, uint16_t s);
extern int TIFFCheckTile(TIFF *tif, uint32_t x, uint32_t y, uint32_t z,
uint16_t s);
extern uint32_t TIFFNumberOfTiles(TIFF *);
extern tmsize_t TIFFReadTile(TIFF *tif, void *buf, uint32_t x, uint32_t y,
uint32_t z, uint16_t s);
extern tmsize_t TIFFWriteTile(TIFF *tif, void *buf, uint32_t x, uint32_t y,
uint32_t z, uint16_t s);
extern uint32_t TIFFComputeStrip(TIFF *, uint32_t, uint16_t);
extern uint32_t TIFFNumberOfStrips(TIFF *);
extern tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32_t strip, void *buf,
tmsize_t size);
extern tmsize_t TIFFReadRawStrip(TIFF *tif, uint32_t strip, void *buf,
tmsize_t size);
extern tmsize_t TIFFReadEncodedTile(TIFF *tif, uint32_t tile, void *buf,
tmsize_t size);
extern tmsize_t TIFFReadRawTile(TIFF *tif, uint32_t tile, void *buf,
tmsize_t size);
extern int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf,
tmsize_t insize, void *outbuf,
tmsize_t outsize);
extern tmsize_t TIFFWriteEncodedStrip(TIFF *tif, uint32_t strip, void *data,
tmsize_t cc);
extern tmsize_t TIFFWriteRawStrip(TIFF *tif, uint32_t strip, void *data,
tmsize_t cc);
extern tmsize_t TIFFWriteEncodedTile(TIFF *tif, uint32_t tile, void *data,
tmsize_t cc);
extern tmsize_t TIFFWriteRawTile(TIFF *tif, uint32_t tile, void *data,
tmsize_t cc);
extern int TIFFDataWidth(
TIFFDataType); /* table of tag datatype widths within TIFF file. */
extern void TIFFSetWriteOffset(TIFF *tif, toff_t off);
extern void TIFFSwabShort(uint16_t *);
extern void TIFFSwabLong(uint32_t *);
extern void TIFFSwabLong8(uint64_t *);
extern void TIFFSwabFloat(float *);
extern void TIFFSwabDouble(double *);
extern void TIFFSwabArrayOfShort(uint16_t *wp, tmsize_t n);
extern void TIFFSwabArrayOfTriples(uint8_t *tp, tmsize_t n);
extern void TIFFSwabArrayOfLong(uint32_t *lp, tmsize_t n);
extern void TIFFSwabArrayOfLong8(uint64_t *lp, tmsize_t n);
extern void TIFFSwabArrayOfFloat(float *fp, tmsize_t n);
extern void TIFFSwabArrayOfDouble(double *dp, tmsize_t n);
extern void TIFFReverseBits(uint8_t *cp, tmsize_t n);
extern const unsigned char *TIFFGetBitRevTable(int);
extern uint64_t TIFFGetStrileOffset(TIFF *tif, uint32_t strile);
extern uint64_t TIFFGetStrileByteCount(TIFF *tif, uint32_t strile);
extern uint64_t TIFFGetStrileOffsetWithErr(TIFF *tif, uint32_t strile,
int *pbErr);
extern uint64_t TIFFGetStrileByteCountWithErr(TIFF *tif, uint32_t strile,
int *pbErr);
#if 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_t *);
extern int uv_decode(double *, double *, int);
extern void LogLuv24toXYZ(uint32_t, float *);
extern void LogLuv32toXYZ(uint32_t, 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_t LogLuv24fromXYZ(float *, int = SGILOGENCODE_NODITHER);
extern uint32_t 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_t LogLuv24fromXYZ(float *, int);
extern uint32_t LogLuv32fromXYZ(float *, int);
#endif
#endif /* LOGLUV_PUBLIC */
extern int TIFFCIELabToRGBInit(TIFFCIELabToRGB *, const TIFFDisplay *,
float *);
extern void TIFFCIELabToXYZ(TIFFCIELabToRGB *, uint32_t, int32_t, int32_t,
float *, float *, float *);
extern void TIFFXYZToRGB(TIFFCIELabToRGB *, float, float, float, uint32_t *,
uint32_t *, uint32_t *);
extern int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *, float *, float *);
extern void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *, uint32_t, int32_t, int32_t,
uint32_t *, uint32_t *, uint32_t *);
/****************************************************************************
* 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
{
uint32_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_t);
#if defined(c_plusplus) || defined(__cplusplus)
}
#endif
#endif /* _TIFFIO_ */
+39
View File
@@ -0,0 +1,39 @@
/*
* 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.
*/
#ifndef _TIFFIO_HXX_
#define _TIFFIO_HXX_
/*
* TIFF I/O library definitions which provide C++ streams API.
*/
#include "tiff.h"
#include "tiffio.h"
#include <iostream>
extern TIFF *TIFFStreamOpen(const char *, std::ostream *);
extern TIFF *TIFFStreamOpen(const char *, std::istream *);
#endif /* _TIFFIO_HXX_ */
+549
View File
@@ -0,0 +1,549 @@
/*
* 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.
*/
#ifndef _TIFFIOP_
#define _TIFFIOP_
/*
* ``Library-private'' definitions.
*/
#include "tif_config.h"
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <string.h>
#ifdef HAVE_ASSERT_H
#include <assert.h>
#else
#define assert(x)
#endif
#include "tif_hash_set.h"
#include "tiffio.h"
#include "tif_dir.h"
#include <limits.h>
#ifndef STRIP_SIZE_DEFAULT
#define STRIP_SIZE_DEFAULT 8192
#endif
#ifndef TIFF_MAX_DIR_COUNT
#define TIFF_MAX_DIR_COUNT 1048576
#endif
#define TIFF_NON_EXISTENT_DIR_NUMBER UINT_MAX
#define streq(a, b) (strcmp(a, b) == 0)
#define strneq(a, b, n) (strncmp(a, b, n) == 0)
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
typedef struct client_info
{
struct client_info *next;
void *data;
char *name;
} TIFFClientInfoLink;
/*
* Typedefs for ``method pointers'' used internally.
* these are deprecated and provided only for backwards compatibility.
*/
typedef unsigned char tidataval_t; /* internal image data value type */
typedef tidataval_t *tidata_t; /* reference to internal image data */
typedef void (*TIFFVoidMethod)(TIFF *);
typedef int (*TIFFBoolMethod)(TIFF *);
typedef int (*TIFFPreMethod)(TIFF *, uint16_t);
typedef int (*TIFFCodeMethod)(TIFF *tif, uint8_t *buf, tmsize_t size,
uint16_t sample);
typedef int (*TIFFSeekMethod)(TIFF *, uint32_t);
typedef void (*TIFFPostMethod)(TIFF *tif, uint8_t *buf, tmsize_t size);
typedef uint32_t (*TIFFStripMethod)(TIFF *, uint32_t);
typedef void (*TIFFTileMethod)(TIFF *, uint32_t *, uint32_t *);
struct TIFFOffsetAndDirNumber
{
uint64_t offset;
tdir_t dirNumber;
};
typedef struct TIFFOffsetAndDirNumber TIFFOffsetAndDirNumber;
typedef union
{
TIFFHeaderCommon common;
TIFFHeaderClassic classic;
TIFFHeaderBig big;
} TIFFHeaderUnion;
struct tiff
{
char *tif_name; /* name of open file */
int tif_fd; /* open file descriptor */
int tif_mode; /* open mode (O_*) */
uint32_t tif_flags;
#define TIFF_FILLORDER 0x00003U /* natural bit fill order for machine */
#define TIFF_DIRTYHEADER 0x00004U /* header must be written on close */
#define TIFF_DIRTYDIRECT 0x00008U /* current directory must be written */
#define TIFF_BUFFERSETUP 0x00010U /* data buffers setup */
#define TIFF_CODERSETUP 0x00020U /* encoder/decoder setup done */
#define TIFF_BEENWRITING 0x00040U /* written 1+ scanlines to file */
#define TIFF_SWAB 0x00080U /* byte swap file information */
#define TIFF_NOBITREV 0x00100U /* inhibit bit reversal logic */
#define TIFF_MYBUFFER 0x00200U /* my raw data buffer; free on close */
#define TIFF_ISTILED 0x00400U /* file is tile, not strip- based */
#define TIFF_MAPPED 0x00800U /* file is mapped into memory */
#define TIFF_POSTENCODE 0x01000U /* need call to postencode routine */
#define TIFF_INSUBIFD 0x02000U /* currently writing a subifd */
#define TIFF_UPSAMPLED 0x04000U /* library is doing data up-sampling */
#define TIFF_STRIPCHOP 0x08000U /* enable strip chopping support */
#define TIFF_HEADERONLY \
0x10000U /* read header only, do not process the first directory */
#define TIFF_NOREADRAW \
0x20000U /* skip reading of raw uncompressed image data */
#define TIFF_INCUSTOMIFD 0x40000U /* currently writing a custom IFD */
#define TIFF_BIGTIFF 0x80000U /* read/write bigtiff */
#define TIFF_BUF4WRITE 0x100000U /* rawcc bytes are for writing */
#define TIFF_DIRTYSTRIP 0x200000U /* stripoffsets/stripbytecount dirty*/
#define TIFF_PERSAMPLE 0x400000U /* get/set per sample tags as arrays */
#define TIFF_BUFFERMMAP \
0x800000U /* read buffer (tif_rawdata) points into mmap() memory */
#define TIFF_DEFERSTRILELOAD \
0x1000000U /* defer strip/tile offset/bytecount array loading. */
#define TIFF_LAZYSTRILELOAD \
0x2000000U /* lazy/ondemand loading of strip/tile offset/bytecount values. \
Only used if TIFF_DEFERSTRILELOAD is set and in read-only \
mode */
#define TIFF_CHOPPEDUPARRAYS \
0x4000000U /* set when allocChoppedUpStripArrays() has modified strip \
array */
uint64_t tif_diroff; /* file offset of current directory */
uint64_t tif_nextdiroff; /* file offset of following directory */
uint64_t tif_lastdiroff; /* file offset of last directory written so far */
TIFFHashSet *tif_map_dir_offset_to_number;
TIFFHashSet *tif_map_dir_number_to_offset;
int tif_setdirectory_force_absolute; /* switch between relative and absolute
stepping in TIFFSetDirectory() */
TIFFDirectory tif_dir; /* internal rep of current directory */
TIFFDirectory
tif_customdir; /* custom IFDs are separated from the main ones */
TIFFHeaderUnion tif_header; /* file's header block Classic/BigTIFF union */
uint16_t tif_header_size; /* file's header block and its length */
uint32_t tif_row; /* current scanline */
/* There are IFDs in the file and an "active" IFD in memory,
* from which fields are "set" and "get".
* tif_curdir is set to:
* a) TIFF_NON_EXISTENT_DIR_NUMBER if there is no IFD in the file
* or the state is unknown,
* or the last read (i.e. TIFFFetchDirectory()) failed,
* or a custom directory was written.
* b) IFD index of last IFD written in the file. In this case the
* active IFD is a new (empty) one and tif_diroff is zero.
* If writing fails, tif_curdir is not changed.
* c) IFD index of IFD read from file into memory (=active IFD),
* even if IFD is corrupt and TIFFReadDirectory() returns 0.
* Then tif_diroff contains the offset of the IFD in the file.
* d) IFD index 0, whenever a custom directory or an unchained SubIFD
* was read. */
tdir_t tif_curdir; /* current directory (index) */
/* tif_curdircount: number of directories (main-IFDs) in file:
* - TIFF_NON_EXISTENT_DIR_NUMBER means 'dont know number of IFDs'.
* - 0 means 'empty file opened for writing, but no IFD written yet' */
tdir_t tif_curdircount;
uint32_t tif_curstrip; /* current strip for read/write */
uint64_t tif_curoff; /* current offset for read/write */
uint64_t tif_lastvalidoff; /* last valid offset allowed for rewrite in
place. Used only by TIFFAppendToStrip() */
uint64_t tif_dataoff; /* current offset for writing dir (IFD) */
/* SubIFD support */
uint16_t tif_nsubifd; /* remaining subifds to write */
uint64_t tif_subifdoff; /* offset for patching SubIFD link */
/* tiling support */
uint32_t tif_col; /* current column (offset by row too) */
uint32_t 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_t *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_t *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_t *tif_rawcp; /* current spot in raw buffer */
tmsize_t tif_rawcc; /* bytes unread from raw buffer */
/* memory-mapped file support */
uint8_t *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;
/* Error handler support */
TIFFErrorHandlerExtR tif_errorhandler;
void *tif_errorhandler_user_data;
TIFFErrorHandlerExtR tif_warnhandler;
void *tif_warnhandler_user_data;
tmsize_t tif_max_single_mem_alloc; /* in bytes. 0 for unlimited */
tmsize_t tif_max_cumulated_mem_alloc; /* in bytes. 0 for unlimited */
tmsize_t tif_cur_cumulated_mem_alloc; /* in bytes */
int tif_warn_about_unknown_tags;
};
struct TIFFOpenOptions
{
TIFFErrorHandlerExtR errorhandler; /* may be NULL */
void *errorhandler_user_data; /* may be NULL */
TIFFErrorHandlerExtR warnhandler; /* may be NULL */
void *warnhandler_user_data; /* may be NULL */
tmsize_t max_single_mem_alloc; /* in bytes. 0 for unlimited */
tmsize_t max_cumulated_mem_alloc; /* in bytes. 0 for unlimited */
int warn_about_unknown_tags;
};
#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) ((*(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)))
/*
* Default Read/Seek/Write definitions.
*/
#ifndef ReadOK
#define ReadOK(tif, buf, size) (TIFFReadFile((tif), (buf), (size)) == (size))
#endif
#ifndef SeekOK
#define SeekOK(tif, off) _TIFFSeekOK(tif, off)
#endif
#ifndef WriteOK
#define WriteOK(tif, buf, size) (TIFFWriteFile((tif), (buf), (size)) == (size))
#endif
/* NB: the uint32_t casts are to silence certain ANSI-C compilers */
#define TIFFhowmany_32(x, y) \
(((uint32_t)x < (0xffffffff - (uint32_t)(y - 1))) \
? ((((uint32_t)(x)) + (((uint32_t)(y)) - 1)) / ((uint32_t)(y))) \
: 0U)
/* Variant of TIFFhowmany_32() that doesn't return 0 if x close to MAXUINT. */
/* Caution: TIFFhowmany_32_maxuint_compat(x,y)*y might overflow */
#define TIFFhowmany_32_maxuint_compat(x, y) \
(((uint32_t)(x) / (uint32_t)(y)) + \
((((uint32_t)(x) % (uint32_t)(y)) != 0) ? 1 : 0))
#define TIFFhowmany8_32(x) \
(((x)&0x07) ? ((uint32_t)(x) >> 3) + 1 : (uint32_t)(x) >> 3)
#define TIFFroundup_32(x, y) (TIFFhowmany_32(x, y) * (y))
#define TIFFhowmany_64(x, y) \
((((uint64_t)(x)) + (((uint64_t)(y)) - 1)) / ((uint64_t)(y)))
#define TIFFhowmany8_64(x) \
(((x)&0x07) ? ((uint64_t)(x) >> 3) + 1 : (uint64_t)(x) >> 3)
#define TIFFroundup_64(x, y) (TIFFhowmany_64(x, y) * (y))
/* Safe multiply which returns zero if there is an *unsigned* integer overflow.
* This macro is not safe for *signed* integer types */
#define TIFFSafeMultiply(t, v, m) \
((((t)(m) != (t)0) && (((t)(((v) * (m)) / (m))) == (t)(v))) \
? (t)((v) * (m)) \
: (t)0)
#define TIFFmax(A, B) ((A) > (B) ? (A) : (B))
#define TIFFmin(A, B) ((A) < (B) ? (A) : (B))
#define TIFFArrayCount(a) (sizeof(a) / sizeof((a)[0]))
/*
Support for large files.
Windows read/write APIs support only 'unsigned int' rather than 'size_t'.
Windows off_t is only 32-bit, even in 64-bit builds.
*/
#if defined(HAVE_FSEEKO)
/*
Use fseeko() and ftello() if they are available since they use
'off_t' rather than 'long'. It is wrong to use fseeko() and
ftello() only on systems with special LFS support since some systems
(e.g. FreeBSD) support a 64-bit off_t by default.
For MinGW, __MSVCRT_VERSION__ must be at least 0x800 to expose these
interfaces. The MinGW compiler must support the requested version. MinGW
does not distribute the CRT (it is supplied by Microsoft) so the correct CRT
must be available on the target computer in order for the program to run.
*/
#if defined(HAVE_FSEEKO)
#define fseek(stream, offset, whence) fseeko(stream, offset, whence)
#define ftell(stream, offset, whence) ftello(stream, offset, whence)
#endif
#endif
#if defined(_WIN32) && \
!(defined(__MSVCRT_VERSION__) && __MSVCRT_VERSION__ < 0x800)
typedef unsigned int TIFFIOSize_t;
#define _TIFF_lseek_f(fildes, offset, whence) \
_lseeki64(fildes, /* __int64 */ offset, whence)
/* #define _TIFF_tell_f(fildes) /\* __int64 *\/ _telli64(fildes) */
#define _TIFF_fseek_f(stream, offset, whence) \
_fseeki64(stream, /* __int64 */ offset, whence)
#define _TIFF_fstat_f(fildes, stat_buff) \
_fstati64(fildes, /* struct _stati64 */ stat_buff)
/* #define _TIFF_ftell_f(stream) /\* __int64 *\/ _ftelli64(stream) */
/* #define _TIFF_stat_f(path,stat_buff) _stati64(path,/\* struct _stati64 *\/
* stat_buff) */
#define _TIFF_stat_s struct _stati64
#define _TIFF_off_t __int64
#else
typedef size_t TIFFIOSize_t;
#define _TIFF_lseek_f(fildes, offset, whence) lseek(fildes, offset, whence)
/* #define _TIFF_tell_f(fildes) (_TIFF_lseek_f(fildes,0,SEEK_CUR)) */
#define _TIFF_fseek_f(stream, offset, whence) fseek(stream, offset, whence)
#define _TIFF_fstat_f(fildes, stat_buff) fstat(fildes, stat_buff)
/* #define _TIFF_ftell_f(stream) ftell(stream) */
/* #define _TIFF_stat_f(path,stat_buff) stat(path,stat_buff) */
#define _TIFF_stat_s struct stat
#define _TIFF_off_t off_t
#endif
#if defined(__has_attribute) && defined(__clang__)
#if __has_attribute(no_sanitize)
#define TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW \
__attribute__((no_sanitize("unsigned-integer-overflow")))
#else
#define TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
#endif
#else
#define TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
#endif
#if defined(__cplusplus)
extern "C"
{
#endif
extern int _tiffDummyMapProc(thandle_t fd, void **pbase, toff_t *psize);
extern void _tiffDummyUnmapProc(thandle_t fd, void *base, toff_t size);
extern int _TIFFgetMode(TIFFOpenOptions *opts, thandle_t clientdata,
const char *mode, const char *module);
extern int _TIFFNoRowEncode(TIFF *tif, uint8_t *pp, tmsize_t cc,
uint16_t s);
extern int _TIFFNoStripEncode(TIFF *tif, uint8_t *pp, tmsize_t cc,
uint16_t s);
extern int _TIFFNoTileEncode(TIFF *, uint8_t *pp, tmsize_t cc, uint16_t s);
extern int _TIFFNoRowDecode(TIFF *tif, uint8_t *pp, tmsize_t cc,
uint16_t s);
extern int _TIFFNoStripDecode(TIFF *tif, uint8_t *pp, tmsize_t cc,
uint16_t s);
extern int _TIFFNoTileDecode(TIFF *, uint8_t *pp, tmsize_t cc, uint16_t s);
extern void _TIFFNoPostDecode(TIFF *tif, uint8_t *buf, tmsize_t cc);
extern int _TIFFNoPreCode(TIFF *tif, uint16_t s);
extern int _TIFFNoSeek(TIFF *tif, uint32_t off);
extern void _TIFFSwab16BitData(TIFF *tif, uint8_t *buf, tmsize_t cc);
extern void _TIFFSwab24BitData(TIFF *tif, uint8_t *buf, tmsize_t cc);
extern void _TIFFSwab32BitData(TIFF *tif, uint8_t *buf, tmsize_t cc);
extern void _TIFFSwab64BitData(TIFF *tif, uint8_t *buf, tmsize_t cc);
extern int TIFFFlushData1(TIFF *tif);
extern int TIFFDefaultDirectory(TIFF *tif);
extern void _TIFFSetDefaultCompressionState(TIFF *tif);
extern int _TIFFRewriteField(TIFF *, uint16_t, TIFFDataType, tmsize_t,
void *);
extern int TIFFSetCompressionScheme(TIFF *tif, int scheme);
extern int TIFFSetDefaultCompressionState(TIFF *tif);
extern uint32_t _TIFFDefaultStripSize(TIFF *tif, uint32_t s);
extern void _TIFFDefaultTileSize(TIFF *tif, uint32_t *tw, uint32_t *th);
extern void _TIFFsetByteArray(void **, const void *, uint32_t);
extern void _TIFFsetByteArrayExt(TIFF *, void **, const void *, uint32_t);
extern void _TIFFsetShortArray(uint16_t **, const uint16_t *, uint32_t);
extern void _TIFFsetShortArrayExt(TIFF *, uint16_t **, const uint16_t *,
uint32_t);
extern void _TIFFsetLongArray(uint32_t **, const uint32_t *, uint32_t);
extern void _TIFFsetLongArrayExt(TIFF *, uint32_t **, const uint32_t *,
uint32_t);
extern void _TIFFsetFloatArray(float **, const float *, uint32_t);
extern void _TIFFsetFloatArrayExt(TIFF *, float **, const float *,
uint32_t);
extern void _TIFFsetDoubleArray(double **, const double *, uint32_t);
extern void _TIFFsetDoubleArrayExt(TIFF *, double **, const double *,
uint32_t);
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;
void _TIFFErrorEarly(TIFFOpenOptions *opts, thandle_t clientdata,
const char *module, const char *fmt, ...)
TIFF_ATTRIBUTE((__format__(__printf__, 4, 5)));
extern uint32_t _TIFFMultiply32(TIFF *, uint32_t, uint32_t, const char *);
extern uint64_t _TIFFMultiply64(TIFF *, uint64_t, uint64_t, const char *);
extern tmsize_t _TIFFMultiplySSize(TIFF *, tmsize_t, tmsize_t,
const char *);
extern tmsize_t _TIFFCastUInt64ToSSize(TIFF *, uint64_t, const char *);
extern void *_TIFFCheckMalloc(TIFF *, tmsize_t, tmsize_t, const char *);
extern void *_TIFFCheckRealloc(TIFF *, void *, tmsize_t, tmsize_t,
const char *);
extern float _TIFFClampDoubleToFloat(double);
extern uint32_t _TIFFClampDoubleToUInt32(double);
extern void _TIFFCleanupIFDOffsetAndNumberMaps(TIFF *tif);
extern tmsize_t _TIFFReadEncodedStripAndAllocBuffer(TIFF *tif,
uint32_t strip,
void **buf,
tmsize_t bufsizetoalloc,
tmsize_t size_to_read);
extern tmsize_t _TIFFReadEncodedTileAndAllocBuffer(TIFF *tif, uint32_t tile,
void **buf,
tmsize_t bufsizetoalloc,
tmsize_t size_to_read);
extern tmsize_t _TIFFReadTileAndAllocBuffer(TIFF *tif, void **buf,
tmsize_t bufsizetoalloc,
uint32_t x, uint32_t y,
uint32_t z, uint16_t s);
extern int _TIFFSeekOK(TIFF *tif, toff_t off);
extern int TIFFInitDumpMode(TIFF *, int);
#ifdef PACKBITS_SUPPORT
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);
#endif
#ifdef THUNDER_SUPPORT
extern int TIFFInitThunderScan(TIFF *, int);
#endif
#ifdef NEXT_SUPPORT
extern int TIFFInitNeXT(TIFF *, int);
#endif
#ifdef LZW_SUPPORT
extern int TIFFInitLZW(TIFF *, int);
#endif
#ifdef OJPEG_SUPPORT
extern int TIFFInitOJPEG(TIFF *, int);
#endif
#ifdef JPEG_SUPPORT
extern int TIFFInitJPEG(TIFF *, int);
extern int TIFFJPEGIsFullStripRequired(TIFF *);
#endif
#ifdef JBIG_SUPPORT
extern int TIFFInitJBIG(TIFF *, int);
#endif
#ifdef ZIP_SUPPORT
extern int TIFFInitZIP(TIFF *, int);
#endif
#ifdef PIXARLOG_SUPPORT
extern int TIFFInitPixarLog(TIFF *, int);
#endif
#ifdef LOGLUV_SUPPORT
extern int TIFFInitSGILog(TIFF *, int);
#endif
#ifdef LERC_SUPPORT
extern int TIFFInitLERC(TIFF *tif, int);
#endif
#ifdef LZMA_SUPPORT
extern int TIFFInitLZMA(TIFF *, int);
#endif
#ifdef ZSTD_SUPPORT
extern int TIFFInitZSTD(TIFF *, int);
#endif
#ifdef WEBP_SUPPORT
extern int TIFFInitWebP(TIFF *, int);
#endif
extern const TIFFCodec _TIFFBuiltinCODECS[];
extern void TIFFCIELab16ToXYZ(TIFFCIELabToRGB *, uint32_t l, int32_t a,
int32_t b, float *, float *, float *);
extern void *_TIFFmallocExt(TIFF *tif, tmsize_t s);
extern void *_TIFFcallocExt(TIFF *tif, tmsize_t nmemb, tmsize_t siz);
extern void *_TIFFreallocExt(TIFF *tif, void *p, tmsize_t s);
extern void _TIFFfreeExt(TIFF *tif, void *p);
#if defined(__cplusplus)
}
#endif
#endif /* _TIFFIOP_ */
+36
View File
@@ -0,0 +1,36 @@
/* tiffvers.h version information is updated according to version information
* in configure.ac */
/* clang-format off */
/* clang-format disabled because FindTIFF.cmake is very sensitive to the
* formatting of below line being a single line.
* Furthermore, configure_file variables of type "@VAR@" are
* modified by clang-format and won't be substituted by CMake.
*/
#define TIFFLIB_VERSION_STR "LIBTIFF, Version @LIBTIFF_VERSION@\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
* version or versions of the library. Runtime
* version checking should be done based on the
* string returned by TIFFGetVersion.
*/
#define TIFFLIB_VERSION @LIBTIFF_RELEASE_DATE@
/* The following defines have been added in 4.5.0 */
#define TIFFLIB_MAJOR_VERSION @LIBTIFF_MAJOR_VERSION@
#define TIFFLIB_MINOR_VERSION @LIBTIFF_MINOR_VERSION@
#define TIFFLIB_MICRO_VERSION @LIBTIFF_MICRO_VERSION@
#define TIFFLIB_VERSION_STR_MAJ_MIN_MIC "@LIBTIFF_VERSION@"
/* Macro added in 4.5.0. Returns TRUE if the current libtiff version is
* greater or equal to major.minor.micro
*/
#define TIFFLIB_AT_LEAST(major, minor, micro) \
(TIFFLIB_MAJOR_VERSION > (major) || \
(TIFFLIB_MAJOR_VERSION == (major) && TIFFLIB_MINOR_VERSION > (minor)) || \
(TIFFLIB_MAJOR_VERSION == (major) && TIFFLIB_MINOR_VERSION == (minor) && \
TIFFLIB_MICRO_VERSION >= (micro)))
/* clang-format on */
+93
View File
@@ -0,0 +1,93 @@
/* Version 1.0 generated April 7, 1997 by Greg Ward Larson, SGI */
#define UV_SQSIZ (float)0.003500
#define UV_NDIVS 16289
#define UV_VSTART (float)0.016940
#define UV_NVS 163
static const struct
{
float ustart;
short nus, ncum;
} uv_row[UV_NVS] = {
{(float)0.247663, 4, 0}, {(float)0.243779, 6, 4},
{(float)0.241684, 7, 10}, {(float)0.237874, 9, 17},
{(float)0.235906, 10, 26}, {(float)0.232153, 12, 36},
{(float)0.228352, 14, 48}, {(float)0.226259, 15, 62},
{(float)0.222371, 17, 77}, {(float)0.220410, 18, 94},
{(float)0.214710, 21, 112}, {(float)0.212714, 22, 133},
{(float)0.210721, 23, 155}, {(float)0.204976, 26, 178},
{(float)0.202986, 27, 204}, {(float)0.199245, 29, 231},
{(float)0.195525, 31, 260}, {(float)0.193560, 32, 291},
{(float)0.189878, 34, 323}, {(float)0.186216, 36, 357},
{(float)0.186216, 36, 393}, {(float)0.182592, 38, 429},
{(float)0.179003, 40, 467}, {(float)0.175466, 42, 507},
{(float)0.172001, 44, 549}, {(float)0.172001, 44, 593},
{(float)0.168612, 46, 637}, {(float)0.168612, 46, 683},
{(float)0.163575, 49, 729}, {(float)0.158642, 52, 778},
{(float)0.158642, 52, 830}, {(float)0.158642, 52, 882},
{(float)0.153815, 55, 934}, {(float)0.153815, 55, 989},
{(float)0.149097, 58, 1044}, {(float)0.149097, 58, 1102},
{(float)0.142746, 62, 1160}, {(float)0.142746, 62, 1222},
{(float)0.142746, 62, 1284}, {(float)0.138270, 65, 1346},
{(float)0.138270, 65, 1411}, {(float)0.138270, 65, 1476},
{(float)0.132166, 69, 1541}, {(float)0.132166, 69, 1610},
{(float)0.126204, 73, 1679}, {(float)0.126204, 73, 1752},
{(float)0.126204, 73, 1825}, {(float)0.120381, 77, 1898},
{(float)0.120381, 77, 1975}, {(float)0.120381, 77, 2052},
{(float)0.120381, 77, 2129}, {(float)0.112962, 82, 2206},
{(float)0.112962, 82, 2288}, {(float)0.112962, 82, 2370},
{(float)0.107450, 86, 2452}, {(float)0.107450, 86, 2538},
{(float)0.107450, 86, 2624}, {(float)0.107450, 86, 2710},
{(float)0.100343, 91, 2796}, {(float)0.100343, 91, 2887},
{(float)0.100343, 91, 2978}, {(float)0.095126, 95, 3069},
{(float)0.095126, 95, 3164}, {(float)0.095126, 95, 3259},
{(float)0.095126, 95, 3354}, {(float)0.088276, 100, 3449},
{(float)0.088276, 100, 3549}, {(float)0.088276, 100, 3649},
{(float)0.088276, 100, 3749}, {(float)0.081523, 105, 3849},
{(float)0.081523, 105, 3954}, {(float)0.081523, 105, 4059},
{(float)0.081523, 105, 4164}, {(float)0.074861, 110, 4269},
{(float)0.074861, 110, 4379}, {(float)0.074861, 110, 4489},
{(float)0.074861, 110, 4599}, {(float)0.068290, 115, 4709},
{(float)0.068290, 115, 4824}, {(float)0.068290, 115, 4939},
{(float)0.068290, 115, 5054}, {(float)0.063573, 119, 5169},
{(float)0.063573, 119, 5288}, {(float)0.063573, 119, 5407},
{(float)0.063573, 119, 5526}, {(float)0.057219, 124, 5645},
{(float)0.057219, 124, 5769}, {(float)0.057219, 124, 5893},
{(float)0.057219, 124, 6017}, {(float)0.050985, 129, 6141},
{(float)0.050985, 129, 6270}, {(float)0.050985, 129, 6399},
{(float)0.050985, 129, 6528}, {(float)0.050985, 129, 6657},
{(float)0.044859, 134, 6786}, {(float)0.044859, 134, 6920},
{(float)0.044859, 134, 7054}, {(float)0.044859, 134, 7188},
{(float)0.040571, 138, 7322}, {(float)0.040571, 138, 7460},
{(float)0.040571, 138, 7598}, {(float)0.040571, 138, 7736},
{(float)0.036339, 142, 7874}, {(float)0.036339, 142, 8016},
{(float)0.036339, 142, 8158}, {(float)0.036339, 142, 8300},
{(float)0.032139, 146, 8442}, {(float)0.032139, 146, 8588},
{(float)0.032139, 146, 8734}, {(float)0.032139, 146, 8880},
{(float)0.027947, 150, 9026}, {(float)0.027947, 150, 9176},
{(float)0.027947, 150, 9326}, {(float)0.023739, 154, 9476},
{(float)0.023739, 154, 9630}, {(float)0.023739, 154, 9784},
{(float)0.023739, 154, 9938}, {(float)0.019504, 158, 10092},
{(float)0.019504, 158, 10250}, {(float)0.019504, 158, 10408},
{(float)0.016976, 161, 10566}, {(float)0.016976, 161, 10727},
{(float)0.016976, 161, 10888}, {(float)0.016976, 161, 11049},
{(float)0.012639, 165, 11210}, {(float)0.012639, 165, 11375},
{(float)0.012639, 165, 11540}, {(float)0.009991, 168, 11705},
{(float)0.009991, 168, 11873}, {(float)0.009991, 168, 12041},
{(float)0.009016, 170, 12209}, {(float)0.009016, 170, 12379},
{(float)0.009016, 170, 12549}, {(float)0.006217, 173, 12719},
{(float)0.006217, 173, 12892}, {(float)0.005097, 175, 13065},
{(float)0.005097, 175, 13240}, {(float)0.005097, 175, 13415},
{(float)0.003909, 177, 13590}, {(float)0.003909, 177, 13767},
{(float)0.002340, 177, 13944}, {(float)0.002389, 170, 14121},
{(float)0.001068, 164, 14291}, {(float)0.001653, 157, 14455},
{(float)0.000717, 150, 14612}, {(float)0.001614, 143, 14762},
{(float)0.000270, 136, 14905}, {(float)0.000484, 129, 15041},
{(float)0.001103, 123, 15170}, {(float)0.001242, 115, 15293},
{(float)0.001188, 109, 15408}, {(float)0.001011, 103, 15517},
{(float)0.000709, 97, 15620}, {(float)0.000301, 89, 15717},
{(float)0.002416, 82, 15806}, {(float)0.003251, 76, 15888},
{(float)0.003246, 69, 15964}, {(float)0.004141, 62, 16033},
{(float)0.005963, 55, 16095}, {(float)0.008839, 47, 16150},
{(float)0.010490, 40, 16197}, {(float)0.016994, 31, 16237},
{(float)0.023659, 21, 16268},
};