Removed the libs directory containing win32 compiled versions of libpng, libtiff and liblcms. Added a thirdparty directory to include main source files of libtiff, libpng, libz and liblcms to enable support of these formats in the codec executables. CMake will try to statically build these libraries if they are not found on the system. Note that these third party libraries are not required to build libopenjpeg (which has no dependencies).
This commit is contained in:
parent
6bda73eeb2
commit
19f9147e10
4
CHANGES
4
CHANGES
@ -5,6 +5,10 @@ What's New for OpenJPEG
|
||||
! : changed
|
||||
+ : added
|
||||
|
||||
March 20, 2011
|
||||
+ [antonin] added a 'thirdparty' directory to include main source files of libtiff, libpng, libz and liblcms to enable support of these formats in the codec executables. CMake will try to statically build these libraries if they are not found on the system. Note that these third party libraries are not required to build libopenjpeg (which has no dependencies).
|
||||
- [antonin] removed the 'libs' directory containing win32 compiled versions of libpng, libtiff and liblcms.
|
||||
|
||||
March 10, 2011
|
||||
* [antonin] fixed lt_version in configure.ac
|
||||
|
||||
|
233
CMakeLists.txt
233
CMakeLists.txt
@ -156,44 +156,26 @@ SUBDIRS(libopenjpeg)
|
||||
#-----------------------------------------------------------------------------
|
||||
# Build CODEC executables ?
|
||||
OPTION(BUILD_CODEC "Build the CODEC executables" ON)
|
||||
IF(BUILD_CODEC)
|
||||
SUBDIRS(codec)
|
||||
ENDIF(BUILD_CODEC)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Build MJ2 executables ?
|
||||
OPTION(BUILD_MJ2 "Build the MJ2 executables." OFF)
|
||||
IF(BUILD_MJ2)
|
||||
SUBDIRS(mj2)
|
||||
ENDIF(BUILD_MJ2)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Build JPWL executables ?
|
||||
OPTION(BUILD_JPWL "Build the JPWL executables" OFF)
|
||||
IF(BUILD_JPWL)
|
||||
SUBDIRS(jpwl)
|
||||
ENDIF(BUILD_JPWL)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Build JP3D executables ?
|
||||
OPTION(BUILD_JP3D "Build the JP3D executables" OFF)
|
||||
IF(BUILD_JP3D)
|
||||
SUBDIRS(jp3d)
|
||||
ENDIF(BUILD_JP3D)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Build INDEXER_JPIP executables ?
|
||||
OPTION(BUILD_INDEXER_JPIP "Build the INDEXER_JPIP executables" OFF)
|
||||
IF(BUILD_INDEXER_JPIP)
|
||||
SUBDIRS(indexer_JPIP)
|
||||
ENDIF(BUILD_INDEXER_JPIP)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Build DOCUMENTATION ?
|
||||
OPTION(BUILD_DOC "Build the doxygen documentation" OFF)
|
||||
IF(BUILD_DOC)
|
||||
SUBDIRS(doc)
|
||||
ENDIF(BUILD_DOC)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# For openjpeg team if they ever want CDash+CMake
|
||||
@ -238,24 +220,6 @@ INSTALL(
|
||||
LICENSE
|
||||
DESTINATION ${OPENJPEG_INSTALL_DOC_DIR})
|
||||
#
|
||||
IF(UNIX OR CYGWIN)
|
||||
SET(CMAKE_INCLUDE_PATH /usr/include /usr/local/include /opt/include
|
||||
/opt/local/include /usr/include/libpng /usr/include/libpng14
|
||||
/usr/include/libpng12 /usr/local/include/libpng
|
||||
/usr/local/include/libpng14 /usr/local/include/libpng12
|
||||
/opt/include/libpng /opt/include/libpng14 /opt/include/libpng12
|
||||
/opt/local/include/libpng /opt/local/include/libpng14
|
||||
/opt/local/include/libpng12 )
|
||||
SET(CMAKE_LIBRARY_PATH /usr/lib /usr/local/lib /opt/lib /opt/local/lib)
|
||||
ELSEIF(WIN32)
|
||||
SET(CMAKE_INCLUDE_PATH ${OPENJPEG_SOURCE_DIR}/libs/libtiff
|
||||
${OPENJPEG_SOURCE_DIR}/libs/png ${OPENJPEG_SOURCE_DIR}/libs/lcms2
|
||||
C:/WINDOWS/system32/user )
|
||||
SET(CMAKE_LIBRARY_PATH ${OPENJPEG_SOURCE_DIR}/libs/libtiff
|
||||
${OPENJPEG_SOURCE_DIR}/libs/png ${OPENJPEG_SOURCE_DIR}/libs/lcms2
|
||||
C:/WINDOWS/system32/user )
|
||||
ENDIF()
|
||||
#
|
||||
FIND_FILE(HAVE_STRINGS_H_FOUND strings.h)
|
||||
IF(NOT HAVE_STRINGS_H_FOUND STREQUAL "HAVE_STRINGS_H_FOUND-NOTFOUND")
|
||||
FIND_FILE(HAVE_STRINGS_H strings.h)
|
||||
@ -302,71 +266,158 @@ IF(NOT HAVE_UNISTD_H_FOUND STREQUAL "HAVE_UNISTD_H_FOUND-NOTFOUND")
|
||||
SET(HAS_UNISTD_H 1)
|
||||
ENDIF()
|
||||
#
|
||||
# Does the system have png library installed ?
|
||||
IF(BUILD_CODEC OR BUILD_JPWL OR BUILD_MJ2)
|
||||
#
|
||||
FIND_PACKAGE(PNG)
|
||||
#
|
||||
IF(PNG_FOUND)
|
||||
SET(HAVE_PNG_H 1)
|
||||
SET(HAVE_LIBPNG 1)
|
||||
IF(UNIX OR CYGWIN)
|
||||
SET(CMAKE_INCLUDE_PATH /usr/include /usr/local/include /opt/include
|
||||
/opt/local/include /usr/include/libpng /usr/include/libpng14
|
||||
/usr/include/libpng12 /usr/local/include/libpng
|
||||
/usr/local/include/libpng14 /usr/local/include/libpng12
|
||||
/opt/include/libpng /opt/include/libpng14 /opt/include/libpng12
|
||||
/opt/local/include/libpng /opt/local/include/libpng14)
|
||||
SET(CMAKE_LIBRARY_PATH /usr/lib /usr/local/lib /opt/lib /opt/local/lib)
|
||||
ENDIF()
|
||||
#
|
||||
# Does the system have tiff library installed ?
|
||||
#
|
||||
FIND_PACKAGE(TIFF)
|
||||
FIND_PACKAGE(ZLIB QUIET)
|
||||
#
|
||||
IF(TIFF_FOUND)
|
||||
SET(HAVE_TIFF_H 1)
|
||||
SET(HAVE_LIBTIFF 1)
|
||||
ENDIF()
|
||||
IF(ZLIB_LIBRARY STREQUAL "ZLIB_LIBRARY-NOTFOUND")
|
||||
SET(ZLIB_FOUND 0)
|
||||
ENDIF(ZLIB_LIBRARY STREQUAL "ZLIB_LIBRARY-NOTFOUND")
|
||||
#
|
||||
IF(ZLIB_FOUND)
|
||||
SET(HAVE_ZLIB_H 1)
|
||||
SET(HABE_LIBZ 1)
|
||||
SET(Z_LIBNAME ${ZLIB_LIBRARIES})
|
||||
SET(Z_INCLUDE_DIRNAME ${ZLIB_INCLUDE_DIR})
|
||||
ENDIF(ZLIB_FOUND)
|
||||
#
|
||||
# Does the system have lcms library installed ?
|
||||
FIND_PACKAGE(PNG QUIET)
|
||||
#
|
||||
SET(LCMS_LIB "")
|
||||
FIND_FILE(LCMS2_HEADER_FOUND lcms2.h)
|
||||
IF(PNG_LIBRARY STREQUAL "PNG_LIBRARY-NOTFOUND")
|
||||
SET(PNG_FOUND 0)
|
||||
ENDIF(PNG_LIBRARY STREQUAL "PNG_LIBRARY-NOTFOUND")
|
||||
#
|
||||
IF(LCMS2_HEADER_FOUND STREQUAL "LCMS2_HEADER_FOUND-NOTFOUND")
|
||||
SET(LCMS2_HEADER_FOUND "")
|
||||
ENDIF()
|
||||
IF(LCMS2_HEADER_FOUND)
|
||||
FIND_PATH(LCMS_INCLUDE_DIR lcms2.h)
|
||||
IF(UNIX OR CYGWIN)
|
||||
FIND_LIBRARY(HAVE_LIBLCMS2 lcms2)
|
||||
ELSE()
|
||||
FIND_LIBRARY(HAVE_LIBLCMS2 lcms2_static.lib)
|
||||
ENDIF()
|
||||
IF(HAVE_LIBLCMS2 STREQUAL "HAVE_LIBLCMS2-NOTFOUND")
|
||||
SET(HAVE_LIBLCMS2 "")
|
||||
ENDIF()
|
||||
IF(HAVE_LIBLCMS2)
|
||||
SET(LCMS_LIB "${HAVE_LIBLCMS2}")
|
||||
SET(HAVE_LCMS2_LIB 1)
|
||||
SET(HAVE_LCMS2_H 1)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(NOT LCMS2_HEADER_FOUND)
|
||||
FIND_FILE(LCMS1_HEADER_FOUND lcms.h)
|
||||
IF(LCMS1_HEADER_FOUND STREQUAL "LCMS1_HEADER_FOUND-NOTFOUND")
|
||||
SET(LCMS1_HEADER_FOUND "")
|
||||
ENDIF()
|
||||
IF(LCMS1_HEADER_FOUND)
|
||||
FIND_PATH(LCMS_INCLUDE_DIR lcms.h)
|
||||
FIND_LIBRARY(HAVE_LIBLCMS1 lcms)
|
||||
IF(HAVE_LIBLCMS1 STREQUAL "HAVE_LIBLCMS1-NOTFOUND")
|
||||
SET(HAVE_LIBLCMS1 "")
|
||||
ENDIF()
|
||||
IF(HAVE_LIBLCMS1)
|
||||
SET(LCMS_LIB "${HAVE_LIBLCMS1}")
|
||||
SET(HAVE_LCMS1_LIB 1)
|
||||
SET(HAVE_LCMS1_H 1)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(PNG_FOUND)
|
||||
SET(HAVE_PNG_H 1)
|
||||
SET(HAVE_LIBPNG 1)
|
||||
SET(PNG_LIBNAME ${PNG_LIBRARIES})
|
||||
SET(PNG_INCLUDE_DIRNAME ${PNG_INCLUDE_DIR})
|
||||
ENDIF(PNG_FOUND)
|
||||
#
|
||||
FIND_PACKAGE(TIFF QUIET)
|
||||
#
|
||||
IF(TIFF_LIBRARY STREQUAL "TIFF_LIBRARY-NOTFOUND")
|
||||
SET(TIFF_FOUND 0)
|
||||
ENDIF(TIFF_LIBRARY STREQUAL "TIFF_LIBRARY-NOTFOUND")
|
||||
#
|
||||
IF(TIFF_FOUND)
|
||||
SET(HAVE_TIFF_H 1)
|
||||
SET(HAVE_LIBTIFF 1)
|
||||
SET(TIFF_LIBNAME ${TIFF_LIBRARIES})
|
||||
SET(TIFF_INCLUDE_DIRNAME ${TIFF_INCLUDE_DIR})
|
||||
ENDIF(TIFF_FOUND)
|
||||
#
|
||||
FIND_PACKAGE(LCMS QUIET)
|
||||
#
|
||||
IF(LCMS_LIBRARY STREQUAL "LCMS_LIBRARY-NOTFOUND")
|
||||
SET(LCMS_FOUND 0)
|
||||
ENDIF(LCMS_LIBRARY STREQUAL "LCMS_LIBRARY-NOTFOUND")
|
||||
#
|
||||
IF(LCMS_FOUND)
|
||||
SET(HAVE_LCMS1_H 1)
|
||||
SET(HAVE_LCMS1_LIB 1)
|
||||
SET(LCMS_LIBNAME ${LCMS_LIBRARIES})
|
||||
SET(LCMS_INCLUDE_DIRNAME ${LCMS_INCLUDE_DIR})
|
||||
ENDIF(LCMS_FOUND)
|
||||
#
|
||||
IF(NOT LCMS_FOUND)
|
||||
FIND_PACKAGE(LCMS2 QUIET)
|
||||
IF(LCMS2_LIBRARY STREQUAL "LCMS2_LIBRARY-NOTFOUND")
|
||||
SET(LCMS2_FOUND 0)
|
||||
ENDIF(LCMS2_LIBRARY STREQUAL "LCMS2_LIBRARY-NOTFOUND")
|
||||
#
|
||||
IF(LCMS2_FOUND)
|
||||
SET(HAVE_LCMS2_H 1)
|
||||
SET(HAVE_LCMS2_LIB 1)
|
||||
SET(LCMS_LIBNAME ${LCMS2_LIBRARIES})
|
||||
SET(LCMS_INCLUDE_DIRNAME ${LCMS2_INCLUDE_DIR})
|
||||
ENDIF(LCMS2_FOUND)
|
||||
ENDIF(NOT LCMS_FOUND)
|
||||
#-------------------------------------------------------------
|
||||
OPTION(BUILD_THIRDPARTY "Build the thirdparty executables" ON)
|
||||
#
|
||||
IF(NOT ZLIB_FOUND OR NOT PNG_FOUND OR NOT TIFF_FOUND OR NOT LCMS_FOUND OR NOT LCMS2_FOUND)
|
||||
IF(BUILD_THIRDPARTY)
|
||||
SET(HAVE_ZLIB_H 1)
|
||||
SET(HAVE_LIBZ 1)
|
||||
SET(HAVE_PNG_H 1)
|
||||
SET(HAVE_LIBPNG 1)
|
||||
SET(HAVE_TIFF_H 1)
|
||||
SET(HAVE_LIBTIFF 1)
|
||||
SET(HAVE_LCMS2_H 1)
|
||||
SET(HAVE_LIBLCMS2 1)
|
||||
#
|
||||
ADD_SUBDIRECTORY(${OPENJPEG_SOURCE_DIR}/thirdparty)
|
||||
#
|
||||
LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/thirdparty/lib)
|
||||
#
|
||||
IF(NOT ZLIB_FOUND)
|
||||
INCLUDE_DIRECTORIES(${OPENJPEG_SOURCE_DIR}/thirdparty/include)
|
||||
SET(ZLIB_INCLUDE_DIRNAME ${OPENJPEG_SOURCE_DIR}/thirdparty/include)
|
||||
SET(Z_LIBNAME z)
|
||||
SET(ZLIB_FOUND 1)
|
||||
ENDIF(NOT ZLIB_FOUND)
|
||||
#
|
||||
IF(NOT PNG_FOUND)
|
||||
SET(PNG_INCLUDE_DIRNAME ${OPENJPEG_SOURCE_DIR}/thirdparty/libpng)
|
||||
SET(PNG_LIBNAME png)
|
||||
SET(PNG_FOUND 1)
|
||||
ENDIF(NOT PNG_FOUND)
|
||||
#
|
||||
IF(NOT LCMS_FOUND AND NOT LCMS2_FOUND)
|
||||
SET(LCMS_INCLUDE_DIRNAME ${OPENJPEG_SOURCE_DIR}/thirdparty/liblcms2/include)
|
||||
SET(LCMS_LIBNAME lcms2)
|
||||
SET(LCMS2_FOUND 1)
|
||||
ENDIF(NOT LCMS_FOUND AND NOT LCMS2_FOUND)
|
||||
#
|
||||
IF(NOT TIFF_FOUND)
|
||||
SET(TIFF_INCLUDE_DIRNAME ${OPENJPEG_SOURCE_DIR}/thirdparty/libtiff)
|
||||
SET(TIFF_LIBNAME tiff)
|
||||
SET(TIFF_FOUND 1)
|
||||
ENDIF(NOT TIFF_FOUND)
|
||||
#
|
||||
ENDIF(BUILD_THIRDPARTY)
|
||||
ENDIF(NOT ZLIB_FOUND OR NOT PNG_FOUND OR NOT TIFF_FOUND OR NOT LCMS_FOUND OR NOT LCMS2_FOUND)
|
||||
#
|
||||
ENDIF(BUILD_CODEC OR BUILD_JPWL OR BUILD_MJ2)
|
||||
#
|
||||
IF(BUILD_CODEC)
|
||||
SUBDIRS(codec)
|
||||
ENDIF(BUILD_CODEC)
|
||||
#
|
||||
IF(BUILD_MJ2)
|
||||
SUBDIRS(mj2)
|
||||
ENDIF(BUILD_MJ2)
|
||||
#
|
||||
IF(BUILD_JPWL)
|
||||
SUBDIRS(jpwl)
|
||||
ENDIF(BUILD_JPWL)
|
||||
#
|
||||
IF(BUILD_JP3D)
|
||||
SUBDIRS(jp3d)
|
||||
ENDIF(BUILD_JP3D)
|
||||
#
|
||||
IF(BUILD_INDEXER_JPIP)
|
||||
SUBDIRS(indexer_JPIP)
|
||||
ENDIF(BUILD_INDEXER_JPIP)
|
||||
#
|
||||
IF(BUILD_DOC)
|
||||
SUBDIRS(doc)
|
||||
ENDIF(BUILD_DOC)
|
||||
#
|
||||
# generate opj_config.h
|
||||
CONFIGURE_FILE("${OPENJPEG_SOURCE_DIR}/opj_configh.cmake.in"
|
||||
"${OPENJPEG_BINARY_DIR}/opj_config.h"
|
||||
@ONLY
|
||||
"${OPENJPEG_BINARY_DIR}/opj_config.h"
|
||||
@ONLY
|
||||
)
|
||||
|
||||
|
@ -18,15 +18,12 @@ ENDIF(DONT_HAVE_GETOPT)
|
||||
# Headers file are located here:
|
||||
INCLUDE_DIRECTORIES(
|
||||
${OPENJPEG_SOURCE_DIR}/libopenjpeg
|
||||
${LCMS_INCLUDE_DIR}
|
||||
${LCMS_INCLUDE_DIRNAME}
|
||||
${OPENJPEG_SOURCE_DIR}/common
|
||||
${Z_INCLUDE_DIRNAME}
|
||||
${PNG_INCLUDE_DIRNAME}
|
||||
${TIFF_INCLUDE_DIRNAME}
|
||||
)
|
||||
IF(PNG_FOUND)
|
||||
INCLUDE_DIRECTORIES(${PNG_INCLUDE_DIR})
|
||||
ENDIF(PNG_FOUND)
|
||||
IF(TIFF_FOUND)
|
||||
INCLUDE_DIRECTORIES(${TIFF_INCLUDE_DIR})
|
||||
ENDIF(TIFF_FOUND)
|
||||
|
||||
IF(WIN32)
|
||||
IF(BUILD_SHARED_LIBS)
|
||||
@ -39,13 +36,9 @@ ENDIF(WIN32)
|
||||
# Loop over all executables:
|
||||
FOREACH(exe j2k_to_image image_to_j2k j2k_dump)
|
||||
ADD_EXECUTABLE(${exe} ${exe}.c ${common_SRCS})
|
||||
TARGET_LINK_LIBRARIES(${exe} ${OPENJPEG_LIBRARY_NAME} ${LCMS_LIB})
|
||||
IF(PNG_FOUND)
|
||||
TARGET_LINK_LIBRARIES(${exe} ${PNG_LIBRARIES})
|
||||
ENDIF(PNG_FOUND)
|
||||
IF(TIFF_FOUND)
|
||||
TARGET_LINK_LIBRARIES(${exe} ${TIFF_LIBRARIES})
|
||||
ENDIF(TIFF_FOUND)
|
||||
TARGET_LINK_LIBRARIES(${exe} ${OPENJPEG_LIBRARY_NAME}
|
||||
${LCMS_LIBNAME} ${Z_LIBNAME} ${PNG_LIBNAME} ${TIFF_LIBNAME})
|
||||
|
||||
ADD_TEST(${exe} ${EXECUTABLE_OUTPUT_PATH}/${exe})
|
||||
# calling those exe without option will make them fail always:
|
||||
SET_TESTS_PROPERTIES(${exe} PROPERTIES WILL_FAIL TRUE)
|
||||
|
@ -44,19 +44,12 @@
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBTIFF
|
||||
#ifdef _WIN32
|
||||
#include "../libs/libtiff/tiffio.h"
|
||||
#else
|
||||
#include <tiffio.h>
|
||||
#endif /* _WIN32 */
|
||||
#endif /* HAVE_LIBTIFF */
|
||||
|
||||
#ifdef HAVE_LIBPNG
|
||||
#ifdef _WIN32
|
||||
#include "../libs/png/png.h"
|
||||
#else
|
||||
#include <zlib.h>
|
||||
#include <png.h>
|
||||
#endif /* _WIN32 */
|
||||
#endif /* HAVE_LIBPNG */
|
||||
|
||||
#include "../libopenjpeg/openjpeg.h"
|
||||
@ -1515,7 +1508,7 @@ typedef struct tiff_infoheader{
|
||||
int imagetotif(opj_image_t * image, const char *outfile) {
|
||||
int width, height, imgsize;
|
||||
int bps,index,adjust = 0;
|
||||
int last_i=0;
|
||||
unsigned int last_i=0;
|
||||
TIFF *tif;
|
||||
tdata_t buf;
|
||||
tstrip_t strip;
|
||||
|
@ -39,7 +39,8 @@ IF(WIN32)
|
||||
ENDIF(BUILD_SHARED_LIBS)
|
||||
ENDIF(WIN32)
|
||||
ADD_LIBRARY(${OPENJPEG_LIBRARY_NAME}_JPWL ${JPWL_SRCS} ${OPJ_SRCS})
|
||||
SET_TARGET_PROPERTIES(${OPENJPEG_LIBRARY_NAME}_JPWL PROPERTIES ${OPENJPEG_LIBRARY_PROPERTIES})
|
||||
SET_TARGET_PROPERTIES(${OPENJPEG_LIBRARY_NAME}_JPWL
|
||||
PROPERTIES ${OPENJPEG_LIBRARY_PROPERTIES})
|
||||
|
||||
# Install library
|
||||
INSTALL(TARGETS ${OPENJPEG_LIBRARY_NAME}_JPWL
|
||||
@ -51,19 +52,12 @@ INSTALL(TARGETS ${OPENJPEG_LIBRARY_NAME}_JPWL
|
||||
INCLUDE_DIRECTORIES(
|
||||
${OPENJPEG_SOURCE_DIR}/libopenjpeg
|
||||
${OPENJPEG_SOURCE_DIR}/common
|
||||
${ZLIB_INCLUDE_DIRNAME}
|
||||
${LCMS_INCLUDE_DIRNAME}
|
||||
${PNG_INCLUDE_DIRNAME}
|
||||
${TIFF_INCLUDE_DIRNAME}
|
||||
)
|
||||
|
||||
IF(LCMS_INCLUDE_DIR)
|
||||
INCLUDE_DIRECTORIES( ${LCMS_INCLUDE_DIR} )
|
||||
ENDIF(LCMS_INCLUDE_DIR)
|
||||
IF(PNG_FOUND)
|
||||
INCLUDE_DIRECTORIES(${PNG_INCLUDE_DIR})
|
||||
ENDIF(PNG_FOUND)
|
||||
IF(TIFF_FOUND)
|
||||
INCLUDE_DIRECTORIES(${TIFF_INCLUDE_DIR})
|
||||
ENDIF(TIFF_FOUND)
|
||||
|
||||
|
||||
ADD_EXECUTABLE(JPWL_j2k_to_image
|
||||
../codec/j2k_to_image.c
|
||||
../codec/convert.c
|
||||
@ -72,13 +66,9 @@ ${OPENJPEG_SOURCE_DIR}/common/color.c
|
||||
${common_SRCS}
|
||||
)
|
||||
|
||||
TARGET_LINK_LIBRARIES(JPWL_j2k_to_image ${OPENJPEG_LIBRARY_NAME}_JPWL ${LCMS_LIB})
|
||||
IF(PNG_FOUND)
|
||||
TARGET_LINK_LIBRARIES(JPWL_j2k_to_image ${PNG_LIBRARIES})
|
||||
ENDIF(PNG_FOUND)
|
||||
IF(TIFF_FOUND)
|
||||
TARGET_LINK_LIBRARIES(JPWL_j2k_to_image ${TIFF_LIBRARIES})
|
||||
ENDIF(TIFF_FOUND)
|
||||
TARGET_LINK_LIBRARIES(JPWL_j2k_to_image ${OPENJPEG_LIBRARY_NAME}_JPWL
|
||||
${LCMS_LIBNAME} ${Z_LIBNAME} ${PNG_LIBNAME} ${TIFF_LIBNAME})
|
||||
#
|
||||
IF(UNIX)
|
||||
TARGET_LINK_LIBRARIES(JPWL_j2k_to_image m)
|
||||
ENDIF(UNIX)
|
||||
@ -91,13 +81,9 @@ ADD_EXECUTABLE(JPWL_image_to_j2k
|
||||
${common_SRCS}
|
||||
)
|
||||
|
||||
TARGET_LINK_LIBRARIES(JPWL_image_to_j2k ${OPENJPEG_LIBRARY_NAME}_JPWL ${LCMS_LIB})
|
||||
IF(PNG_FOUND)
|
||||
TARGET_LINK_LIBRARIES(JPWL_image_to_j2k ${PNG_LIBRARIES})
|
||||
ENDIF(PNG_FOUND)
|
||||
IF(TIFF_FOUND)
|
||||
TARGET_LINK_LIBRARIES(JPWL_image_to_j2k ${TIFF_LIBRARIES})
|
||||
ENDIF(TIFF_FOUND)
|
||||
TARGET_LINK_LIBRARIES(JPWL_image_to_j2k ${OPENJPEG_LIBRARY_NAME}_JPWL
|
||||
${LCMS_LIBNAME} ${Z_LIBNAME} ${PNG_LIBNAME} ${TIFF_LIBNAME})
|
||||
#
|
||||
IF(UNIX)
|
||||
TARGET_LINK_LIBRARIES(JPWL_image_to_j2k m)
|
||||
ENDIF(UNIX)
|
||||
|
Binary file not shown.
Binary file not shown.
@ -1,550 +0,0 @@
|
||||
/* $Id: tiffio.h,v 1.86 2010-03-10 18:56:49 bfriesen Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* 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 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 is int32 and not uint32 because some functions
|
||||
* return -1.
|
||||
* NB: toff_t is not off_t for many reasons; TIFFs max out at
|
||||
* 32-bit file offsets, and BigTIFF maxes out at 64-bit
|
||||
* offsets being the most important, and to ensure use of
|
||||
* a consistently unsigned type across architectures.
|
||||
* Prior to libtiff 4.0, this was an unsigned 32 bit type.
|
||||
*/
|
||||
/*
|
||||
* this is the machine addressing size type, only it's signed, so make it
|
||||
* int32 on 32bit machines, int64 on 64bit machines
|
||||
*/
|
||||
typedef TIFF_SSIZE_T tmsize_t;
|
||||
typedef uint64 toff_t; /* file offset */
|
||||
/* the following are deprecated and should be replaced by their defining
|
||||
counterparts */
|
||||
typedef uint32 ttag_t; /* directory tag */
|
||||
typedef uint16 tdir_t; /* directory index */
|
||||
typedef uint16 tsample_t; /* sample number */
|
||||
typedef uint32 tstrile_t; /* strip or tile number */
|
||||
typedef tstrile_t tstrip_t; /* strip number */
|
||||
typedef tstrile_t ttile_t; /* tile number */
|
||||
typedef tmsize_t tsize_t; /* i/o size in bytes */
|
||||
typedef void* tdata_t; /* image data ref */
|
||||
|
||||
#if !defined(__WIN32__) && (defined(_WIN32) || defined(WIN32))
|
||||
#define __WIN32__
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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(_WINDOWS) || defined(__WIN32__) || defined(_Windows)
|
||||
# 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 d_Vrwr; /* Pixel values for ref. white */
|
||||
uint32 d_Vrwg;
|
||||
uint32 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;
|
||||
|
||||
typedef struct { /* YCbCr->RGB support */
|
||||
TIFFRGBValue* clamptab; /* range clamping table */
|
||||
int* Cr_r_tab;
|
||||
int* Cb_b_tab;
|
||||
int32* Cr_g_tab;
|
||||
int32* Cb_g_tab;
|
||||
int32* Y_tab;
|
||||
} TIFFYCbCrToRGB;
|
||||
|
||||
typedef struct { /* CIE Lab 1976->RGB support */
|
||||
int range; /* Size of conversion table */
|
||||
#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*, uint32, uint32, uint32, uint32, int32, int32,
|
||||
unsigned char*);
|
||||
typedef void (*tileSeparateRoutine)
|
||||
(TIFFRGBAImage*, uint32*, uint32, uint32, uint32, uint32, int32, int32,
|
||||
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 width; /* image width */
|
||||
uint32 height; /* image height */
|
||||
uint16 bitspersample; /* image bits/sample */
|
||||
uint16 samplesperpixel; /* image samples/pixel */
|
||||
uint16 orientation; /* image orientation */
|
||||
uint16 req_orientation; /* requested orientation */
|
||||
uint16 photometric; /* image photometric interp */
|
||||
uint16* redcmap; /* colormap pallete */
|
||||
uint16* greencmap;
|
||||
uint16* bluecmap;
|
||||
/* get image data routine */
|
||||
int (*get)(TIFFRGBAImage*, uint32*, uint32, uint32);
|
||||
/* put decoded strip/tile */
|
||||
union {
|
||||
void (*any)(TIFFRGBAImage*);
|
||||
tileContigRoutine contig;
|
||||
tileSeparateRoutine separate;
|
||||
} put;
|
||||
TIFFRGBValue* Map; /* sample mapping array */
|
||||
uint32** BWmap; /* black&white map */
|
||||
uint32** PALmap; /* palette image map */
|
||||
TIFFYCbCrToRGB* ycbcr; /* YCbCr conversion state */
|
||||
TIFFCIELabToRGB* cielab; /* CIE L*a*b conversion state */
|
||||
|
||||
uint8* UaToAa; /* Unassociated alpha to associated alpha convertion LUT */
|
||||
uint8* Bitdepth16To8; /* LUT for conversion from 16bit to 8bit values */
|
||||
|
||||
int row_offset;
|
||||
int col_offset;
|
||||
};
|
||||
|
||||
/*
|
||||
* 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 scheme;
|
||||
TIFFInitMethod init;
|
||||
} TIFFCodec;
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/* share internal LogLuv conversion routines? */
|
||||
#ifndef LOGLUV_PUBLIC
|
||||
#define LOGLUV_PUBLIC 1
|
||||
#endif
|
||||
|
||||
#if !defined(__GNUC__) && !defined(__attribute__)
|
||||
# define __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 tmsize_t (*TIFFReadWriteProc)(thandle_t, void*, tmsize_t);
|
||||
typedef toff_t (*TIFFSeekProc)(thandle_t, toff_t, int);
|
||||
typedef int (*TIFFCloseProc)(thandle_t);
|
||||
typedef toff_t (*TIFFSizeProc)(thandle_t);
|
||||
typedef int (*TIFFMapFileProc)(thandle_t, void** base, toff_t* size);
|
||||
typedef void (*TIFFUnmapFileProc)(thandle_t, void* base, toff_t size);
|
||||
typedef void (*TIFFExtendProc)(TIFF*);
|
||||
|
||||
extern const char* TIFFGetVersion(void);
|
||||
|
||||
extern const TIFFCodec* TIFFFindCODEC(uint16);
|
||||
extern TIFFCodec* TIFFRegisterCODEC(uint16, const char*, TIFFInitMethod);
|
||||
extern void TIFFUnRegisterCODEC(TIFFCodec*);
|
||||
extern int TIFFIsCODECConfigured(uint16);
|
||||
extern TIFFCodec* TIFFGetConfiguredCODECs(void);
|
||||
|
||||
/*
|
||||
* Auxiliary functions.
|
||||
*/
|
||||
|
||||
extern void* _TIFFmalloc(tmsize_t s);
|
||||
extern void* _TIFFrealloc(void* p, tmsize_t s);
|
||||
extern void _TIFFmemset(void* p, int v, tmsize_t c);
|
||||
extern void _TIFFmemcpy(void* d, const void* s, tmsize_t c);
|
||||
extern int _TIFFmemcmp(const void* p1, const void* p2, tmsize_t c);
|
||||
extern void _TIFFfree(void* p);
|
||||
|
||||
/*
|
||||
** Stuff, related to tag handling and creating custom tags.
|
||||
*/
|
||||
extern int TIFFGetTagListCount( TIFF * );
|
||||
extern uint32 TIFFGetTagListEntry( TIFF *, int tag_index );
|
||||
|
||||
#define TIFF_ANY TIFF_NOTYPE /* for field descriptor searching */
|
||||
#define TIFF_VARIABLE -1 /* marker for variable length tags */
|
||||
#define TIFF_SPP -2 /* marker for SamplesPerPixel tags */
|
||||
#define TIFF_VARIABLE2 -3 /* marker for uint32 var-length tags */
|
||||
|
||||
#define FIELD_CUSTOM 65
|
||||
|
||||
typedef struct _TIFFField TIFFField;
|
||||
typedef struct _TIFFFieldArray TIFFFieldArray;
|
||||
|
||||
extern const TIFFField* TIFFFindField(TIFF *, uint32, TIFFDataType);
|
||||
extern const TIFFField* TIFFFieldWithTag(TIFF*, uint32);
|
||||
extern const TIFFField* TIFFFieldWithName(TIFF*, const char *);
|
||||
|
||||
typedef int (*TIFFVSetMethod)(TIFF*, uint32, va_list);
|
||||
typedef int (*TIFFVGetMethod)(TIFF*, uint32, va_list);
|
||||
typedef void (*TIFFPrintMethod)(TIFF*, FILE*, long);
|
||||
|
||||
typedef struct {
|
||||
TIFFVSetMethod vsetfield; /* tag set routine */
|
||||
TIFFVGetMethod vgetfield; /* tag get routine */
|
||||
TIFFPrintMethod printdir; /* directory print routine */
|
||||
} TIFFTagMethods;
|
||||
|
||||
extern TIFFTagMethods *TIFFAccessTagMethods(TIFF *);
|
||||
extern void *TIFFGetClientInfo(TIFF *, const char *);
|
||||
extern void TIFFSetClientInfo(TIFF *, void *, const char *);
|
||||
|
||||
extern void TIFFCleanup(TIFF* tif);
|
||||
extern void TIFFClose(TIFF* tif);
|
||||
extern int TIFFFlush(TIFF* tif);
|
||||
extern int TIFFFlushData(TIFF* tif);
|
||||
extern int TIFFGetField(TIFF* tif, uint32 tag, ...);
|
||||
extern int TIFFVGetField(TIFF* tif, uint32 tag, va_list ap);
|
||||
extern int TIFFGetFieldDefaulted(TIFF* tif, uint32 tag, ...);
|
||||
extern int TIFFVGetFieldDefaulted(TIFF* tif, uint32 tag, va_list ap);
|
||||
extern int TIFFReadDirectory(TIFF* tif);
|
||||
extern int TIFFReadCustomDirectory(TIFF* tif, toff_t diroff, const TIFFFieldArray* infoarray);
|
||||
extern int TIFFReadEXIFDirectory(TIFF* tif, toff_t diroff);
|
||||
extern uint64 TIFFScanlineSize64(TIFF* tif);
|
||||
extern tmsize_t TIFFScanlineSize(TIFF* tif);
|
||||
extern uint64 TIFFRasterScanlineSize64(TIFF* tif);
|
||||
extern tmsize_t TIFFRasterScanlineSize(TIFF* tif);
|
||||
extern uint64 TIFFStripSize64(TIFF* tif);
|
||||
extern tmsize_t TIFFStripSize(TIFF* tif);
|
||||
extern uint64 TIFFRawStripSize64(TIFF* tif, uint32 strip);
|
||||
extern tmsize_t TIFFRawStripSize(TIFF* tif, uint32 strip);
|
||||
extern uint64 TIFFVStripSize64(TIFF* tif, uint32 nrows);
|
||||
extern tmsize_t TIFFVStripSize(TIFF* tif, uint32 nrows);
|
||||
extern uint64 TIFFTileRowSize64(TIFF* tif);
|
||||
extern tmsize_t TIFFTileRowSize(TIFF* tif);
|
||||
extern uint64 TIFFTileSize64(TIFF* tif);
|
||||
extern tmsize_t TIFFTileSize(TIFF* tif);
|
||||
extern uint64 TIFFVTileSize64(TIFF* tif, uint32 nrows);
|
||||
extern tmsize_t TIFFVTileSize(TIFF* tif, uint32 nrows);
|
||||
extern uint32 TIFFDefaultStripSize(TIFF* tif, uint32 request);
|
||||
extern void TIFFDefaultTileSize(TIFF*, uint32*, uint32*);
|
||||
extern int TIFFFileno(TIFF*);
|
||||
extern int TIFFSetFileno(TIFF*, int);
|
||||
extern thandle_t TIFFClientdata(TIFF*);
|
||||
extern thandle_t TIFFSetClientdata(TIFF*, thandle_t);
|
||||
extern int TIFFGetMode(TIFF*);
|
||||
extern int TIFFSetMode(TIFF*, int);
|
||||
extern int TIFFIsTiled(TIFF*);
|
||||
extern int TIFFIsByteSwapped(TIFF*);
|
||||
extern int TIFFIsUpSampled(TIFF*);
|
||||
extern int TIFFIsMSB2LSB(TIFF*);
|
||||
extern int TIFFIsBigEndian(TIFF*);
|
||||
extern TIFFReadWriteProc TIFFGetReadProc(TIFF*);
|
||||
extern TIFFReadWriteProc TIFFGetWriteProc(TIFF*);
|
||||
extern TIFFSeekProc TIFFGetSeekProc(TIFF*);
|
||||
extern TIFFCloseProc TIFFGetCloseProc(TIFF*);
|
||||
extern TIFFSizeProc TIFFGetSizeProc(TIFF*);
|
||||
extern TIFFMapFileProc TIFFGetMapFileProc(TIFF*);
|
||||
extern TIFFUnmapFileProc TIFFGetUnmapFileProc(TIFF*);
|
||||
extern uint32 TIFFCurrentRow(TIFF*);
|
||||
extern uint16 TIFFCurrentDirectory(TIFF*);
|
||||
extern uint16 TIFFNumberOfDirectories(TIFF*);
|
||||
extern uint64 TIFFCurrentDirOffset(TIFF*);
|
||||
extern uint32 TIFFCurrentStrip(TIFF*);
|
||||
extern uint32 TIFFCurrentTile(TIFF* tif);
|
||||
extern int TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size);
|
||||
extern int TIFFWriteBufferSetup(TIFF* tif, void* bp, tmsize_t size);
|
||||
extern int TIFFSetupStrips(TIFF *);
|
||||
extern int TIFFWriteCheck(TIFF*, int, const char *);
|
||||
extern void TIFFFreeDirectory(TIFF*);
|
||||
extern int TIFFCreateDirectory(TIFF*);
|
||||
extern int TIFFLastDirectory(TIFF*);
|
||||
extern int TIFFSetDirectory(TIFF*, uint16);
|
||||
extern int TIFFSetSubDirectory(TIFF*, uint64);
|
||||
extern int TIFFUnlinkDirectory(TIFF*, uint16);
|
||||
extern int TIFFSetField(TIFF*, uint32, ...);
|
||||
extern int TIFFVSetField(TIFF*, uint32, va_list);
|
||||
extern int TIFFUnsetField(TIFF*, uint32);
|
||||
extern int TIFFWriteDirectory(TIFF *);
|
||||
extern int TIFFCheckpointDirectory(TIFF *);
|
||||
extern int TIFFRewriteDirectory(TIFF *);
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
extern void TIFFPrintDirectory(TIFF*, FILE*, long = 0);
|
||||
extern int TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample = 0);
|
||||
extern int TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample = 0);
|
||||
extern int TIFFReadRGBAImage(TIFF*, uint32, uint32, uint32*, int = 0);
|
||||
extern int TIFFReadRGBAImageOriented(TIFF*, uint32, uint32, uint32*,
|
||||
int = ORIENTATION_BOTLEFT, int = 0);
|
||||
#else
|
||||
extern void TIFFPrintDirectory(TIFF*, FILE*, long);
|
||||
extern int TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample);
|
||||
extern int TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample);
|
||||
extern int TIFFReadRGBAImage(TIFF*, uint32, uint32, uint32*, int);
|
||||
extern int TIFFReadRGBAImageOriented(TIFF*, uint32, uint32, uint32*, int, int);
|
||||
#endif
|
||||
|
||||
extern int TIFFReadRGBAStrip(TIFF*, uint32, uint32 * );
|
||||
extern int TIFFReadRGBATile(TIFF*, uint32, uint32, uint32 * );
|
||||
extern int TIFFRGBAImageOK(TIFF*, char [1024]);
|
||||
extern int TIFFRGBAImageBegin(TIFFRGBAImage*, TIFF*, int, char [1024]);
|
||||
extern int TIFFRGBAImageGet(TIFFRGBAImage*, uint32*, uint32, uint32);
|
||||
extern void TIFFRGBAImageEnd(TIFFRGBAImage*);
|
||||
extern TIFF* TIFFOpen(const char*, const char*);
|
||||
# ifdef __WIN32__
|
||||
extern TIFF* TIFFOpenW(const wchar_t*, const char*);
|
||||
# endif /* __WIN32__ */
|
||||
extern TIFF* TIFFFdOpen(int, const char*, const char*);
|
||||
extern TIFF* TIFFClientOpen(const char*, const char*,
|
||||
thandle_t,
|
||||
TIFFReadWriteProc, TIFFReadWriteProc,
|
||||
TIFFSeekProc, TIFFCloseProc,
|
||||
TIFFSizeProc,
|
||||
TIFFMapFileProc, TIFFUnmapFileProc);
|
||||
extern const char* TIFFFileName(TIFF*);
|
||||
extern const char* TIFFSetFileName(TIFF*, const char *);
|
||||
extern void TIFFError(const char*, const char*, ...) __attribute__((format (printf,2,3)));
|
||||
extern void TIFFErrorExt(thandle_t, const char*, const char*, ...) __attribute__((format (printf,3,4)));
|
||||
extern void TIFFWarning(const char*, const char*, ...) __attribute__((format (printf,2,3)));
|
||||
extern void TIFFWarningExt(thandle_t, const char*, const char*, ...) __attribute__((format (printf,3,4)));
|
||||
extern TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler);
|
||||
extern TIFFErrorHandlerExt TIFFSetErrorHandlerExt(TIFFErrorHandlerExt);
|
||||
extern TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler);
|
||||
extern TIFFErrorHandlerExt TIFFSetWarningHandlerExt(TIFFErrorHandlerExt);
|
||||
extern TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc);
|
||||
extern uint32 TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s);
|
||||
extern int TIFFCheckTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s);
|
||||
extern uint32 TIFFNumberOfTiles(TIFF*);
|
||||
extern tmsize_t TIFFReadTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s);
|
||||
extern tmsize_t TIFFWriteTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s);
|
||||
extern uint32 TIFFComputeStrip(TIFF*, uint32, uint16);
|
||||
extern uint32 TIFFNumberOfStrips(TIFF*);
|
||||
extern tmsize_t TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size);
|
||||
extern tmsize_t TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size);
|
||||
extern tmsize_t TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size);
|
||||
extern tmsize_t TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size);
|
||||
extern tmsize_t TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc);
|
||||
extern tmsize_t TIFFWriteRawStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc);
|
||||
extern tmsize_t TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc);
|
||||
extern tmsize_t TIFFWriteRawTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc);
|
||||
extern int TIFFDataWidth(TIFFDataType); /* table of tag datatype widths */
|
||||
extern void TIFFSetWriteOffset(TIFF* tif, toff_t off);
|
||||
extern void TIFFSwabShort(uint16*);
|
||||
extern void TIFFSwabLong(uint32*);
|
||||
extern void TIFFSwabLong8(uint64*);
|
||||
extern void TIFFSwabFloat(float*);
|
||||
extern void TIFFSwabDouble(double*);
|
||||
extern void TIFFSwabArrayOfShort(uint16* wp, tmsize_t n);
|
||||
extern void TIFFSwabArrayOfTriples(uint8* tp, tmsize_t n);
|
||||
extern void TIFFSwabArrayOfLong(uint32* lp, tmsize_t n);
|
||||
extern void TIFFSwabArrayOfLong8(uint64* lp, tmsize_t n);
|
||||
extern void TIFFSwabArrayOfFloat(float* fp, tmsize_t n);
|
||||
extern void TIFFSwabArrayOfDouble(double* dp, tmsize_t n);
|
||||
extern void TIFFReverseBits(uint8* cp, tmsize_t n);
|
||||
extern const unsigned char* TIFFGetBitRevTable(int);
|
||||
|
||||
#ifdef LOGLUV_PUBLIC
|
||||
#define U_NEU 0.210526316
|
||||
#define V_NEU 0.473684211
|
||||
#define UVSCALE 410.
|
||||
extern double LogL16toY(int);
|
||||
extern double LogL10toY(int);
|
||||
extern void XYZtoRGB24(float*, uint8*);
|
||||
extern int uv_decode(double*, double*, int);
|
||||
extern void LogLuv24toXYZ(uint32, float*);
|
||||
extern void LogLuv32toXYZ(uint32, float*);
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
extern int LogL16fromY(double, int = SGILOGENCODE_NODITHER);
|
||||
extern int LogL10fromY(double, int = SGILOGENCODE_NODITHER);
|
||||
extern int uv_encode(double, double, int = SGILOGENCODE_NODITHER);
|
||||
extern uint32 LogLuv24fromXYZ(float*, int = SGILOGENCODE_NODITHER);
|
||||
extern uint32 LogLuv32fromXYZ(float*, int = SGILOGENCODE_NODITHER);
|
||||
#else
|
||||
extern int LogL16fromY(double, int);
|
||||
extern int LogL10fromY(double, int);
|
||||
extern int uv_encode(double, double, int);
|
||||
extern uint32 LogLuv24fromXYZ(float*, int);
|
||||
extern uint32 LogLuv32fromXYZ(float*, int);
|
||||
#endif
|
||||
#endif /* LOGLUV_PUBLIC */
|
||||
|
||||
extern int TIFFCIELabToRGBInit(TIFFCIELabToRGB*, const TIFFDisplay *, float*);
|
||||
extern void TIFFCIELabToXYZ(TIFFCIELabToRGB *, uint32, int32, int32,
|
||||
float *, float *, float *);
|
||||
extern void TIFFXYZToRGB(TIFFCIELabToRGB *, float, float, float,
|
||||
uint32 *, uint32 *, uint32 *);
|
||||
|
||||
extern int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB*, float*, float*);
|
||||
extern void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *, uint32, int32, int32,
|
||||
uint32 *, uint32 *, uint32 *);
|
||||
|
||||
/****************************************************************************
|
||||
* O B S O L E T E D I N T E R F A C E S
|
||||
*
|
||||
* Don't use this stuff in your applications, it may be removed in the future
|
||||
* libtiff versions.
|
||||
****************************************************************************/
|
||||
typedef struct {
|
||||
ttag_t field_tag; /* field's tag */
|
||||
short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */
|
||||
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);
|
||||
extern const TIFFFieldInfo* TIFFFindFieldInfo(TIFF*, uint32, TIFFDataType);
|
||||
extern const TIFFFieldInfo* TIFFFindFieldInfoByName(TIFF* , const char *,
|
||||
TIFFDataType);
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TIFFIO_ */
|
||||
|
||||
/* vim: set ts=8 sts=8 sw=8 noet: */
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 8
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
Binary file not shown.
Binary file not shown.
@ -37,7 +37,7 @@ ENDIF(WIN32)
|
||||
INCLUDE_DIRECTORIES(
|
||||
${OPENJPEG_SOURCE_DIR}/libopenjpeg
|
||||
${OPENJPEG_SOURCE_DIR}/common
|
||||
${LCMS_INCLUDE_DIR}
|
||||
${LCMS_INCLUDE_DIRNAME}
|
||||
)
|
||||
|
||||
ADD_EXECUTABLE(frames_to_mj2
|
||||
@ -46,7 +46,9 @@ ADD_EXECUTABLE(frames_to_mj2
|
||||
${OPJ_SRCS}
|
||||
${MJ2_SRCS}
|
||||
)
|
||||
TARGET_LINK_LIBRARIES(frames_to_mj2 ${LCMS_LIB})
|
||||
IF(LCMS_FOUND OR LCMS2_FOUND)
|
||||
TARGET_LINK_LIBRARIES(frames_to_mj2 ${LCMS_LIBNAME})
|
||||
ENDIF(LCMS_FOUND OR LCMS2_FOUND)
|
||||
IF(UNIX)
|
||||
TARGET_LINK_LIBRARIES(frames_to_mj2 m)
|
||||
ENDIF(UNIX)
|
||||
@ -58,7 +60,9 @@ ADD_EXECUTABLE(mj2_to_frames
|
||||
${MJ2_SRCS}
|
||||
${OPENJPEG_SOURCE_DIR}/common/color.c
|
||||
)
|
||||
TARGET_LINK_LIBRARIES(mj2_to_frames ${LCMS_LIB})
|
||||
IF(LCMS_FOUND OR LCMS2_FOUND)
|
||||
TARGET_LINK_LIBRARIES(mj2_to_frames ${LCMS_LIBNAME})
|
||||
ENDIF(LCMS_FOUND OR LCMS2_FOUND)
|
||||
IF(UNIX)
|
||||
TARGET_LINK_LIBRARIES(mj2_to_frames m)
|
||||
ENDIF(UNIX)
|
||||
@ -68,7 +72,9 @@ ADD_EXECUTABLE(extract_j2k_from_mj2
|
||||
${OPJ_SRCS}
|
||||
${MJ2_SRCS}
|
||||
)
|
||||
TARGET_LINK_LIBRARIES(extract_j2k_from_mj2 ${LCMS_LIB})
|
||||
IF(LCMS_FOUND OR LCMS2_FOUND)
|
||||
TARGET_LINK_LIBRARIES(extract_j2k_from_mj2 ${LCMS_LIBNAME})
|
||||
ENDIF(LCMS_FOUND OR LCMS2_FOUND)
|
||||
IF(UNIX)
|
||||
TARGET_LINK_LIBRARIES(extract_j2k_from_mj2 m)
|
||||
ENDIF(UNIX)
|
||||
@ -78,7 +84,9 @@ ADD_EXECUTABLE(wrap_j2k_in_mj2
|
||||
${OPJ_SRCS}
|
||||
${MJ2_SRCS}
|
||||
)
|
||||
TARGET_LINK_LIBRARIES(wrap_j2k_in_mj2 ${LCMS_LIB})
|
||||
IF(LCMS_FOUND OR LCMS2_FOUND)
|
||||
TARGET_LINK_LIBRARIES(wrap_j2k_in_mj2 ${LCMS_LIBNAME})
|
||||
ENDIF(LCMS_FOUND OR LCMS2_FOUND)
|
||||
IF(UNIX)
|
||||
TARGET_LINK_LIBRARIES(wrap_j2k_in_mj2 m)
|
||||
ENDIF(UNIX)
|
||||
|
20
thirdparty/CMakeLists.txt
vendored
Normal file
20
thirdparty/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
|
||||
IF(BUILD_THIRDPARTY)
|
||||
#
|
||||
IF(NOT ZLIB_FOUND)
|
||||
ADD_SUBDIRECTORY(libz)
|
||||
ENDIF(NOT ZLIB_FOUND)
|
||||
#
|
||||
IF(NOT PNG_FOUND)
|
||||
ADD_SUBDIRECTORY(libpng)
|
||||
ENDIF(NOT PNG_FOUND)
|
||||
#
|
||||
IF(NOT LCMS2_FOUND)
|
||||
ADD_SUBDIRECTORY(liblcms2)
|
||||
ENDIF(NOT LCMS2_FOUND)
|
||||
#
|
||||
IF(NOT TIFF_FOUND)
|
||||
ADD_SUBDIRECTORY(libtiff)
|
||||
ENDIF(NOT TIFF_FOUND)
|
||||
#
|
||||
ENDIF(BUILD_THIRDPARTY)
|
760
libs/png/zconf.h → thirdparty/include/zconf.h
vendored
Executable file → Normal file
760
libs/png/zconf.h → thirdparty/include/zconf.h
vendored
Executable file → Normal file
@ -1,332 +1,428 @@
|
||||
/* zconf.h -- configuration of the zlib compression library
|
||||
* Copyright (C) 1995-2005 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#ifndef ZCONF_H
|
||||
#define ZCONF_H
|
||||
|
||||
/*
|
||||
* If you *really* need a unique prefix for all types and library functions,
|
||||
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
|
||||
*/
|
||||
#ifdef Z_PREFIX
|
||||
# define deflateInit_ z_deflateInit_
|
||||
# define deflate z_deflate
|
||||
# define deflateEnd z_deflateEnd
|
||||
# define inflateInit_ z_inflateInit_
|
||||
# define inflate z_inflate
|
||||
# define inflateEnd z_inflateEnd
|
||||
# define deflateInit2_ z_deflateInit2_
|
||||
# define deflateSetDictionary z_deflateSetDictionary
|
||||
# define deflateCopy z_deflateCopy
|
||||
# define deflateReset z_deflateReset
|
||||
# define deflateParams z_deflateParams
|
||||
# define deflateBound z_deflateBound
|
||||
# define deflatePrime z_deflatePrime
|
||||
# define inflateInit2_ z_inflateInit2_
|
||||
# define inflateSetDictionary z_inflateSetDictionary
|
||||
# define inflateSync z_inflateSync
|
||||
# define inflateSyncPoint z_inflateSyncPoint
|
||||
# define inflateCopy z_inflateCopy
|
||||
# define inflateReset z_inflateReset
|
||||
# define inflateBack z_inflateBack
|
||||
# define inflateBackEnd z_inflateBackEnd
|
||||
# define compress z_compress
|
||||
# define compress2 z_compress2
|
||||
# define compressBound z_compressBound
|
||||
# define uncompress z_uncompress
|
||||
# define adler32 z_adler32
|
||||
# define crc32 z_crc32
|
||||
# define get_crc_table z_get_crc_table
|
||||
# define zError z_zError
|
||||
|
||||
# define alloc_func z_alloc_func
|
||||
# define free_func z_free_func
|
||||
# define in_func z_in_func
|
||||
# define out_func z_out_func
|
||||
# define Byte z_Byte
|
||||
# define uInt z_uInt
|
||||
# define uLong z_uLong
|
||||
# define Bytef z_Bytef
|
||||
# define charf z_charf
|
||||
# define intf z_intf
|
||||
# define uIntf z_uIntf
|
||||
# define uLongf z_uLongf
|
||||
# define voidpf z_voidpf
|
||||
# define voidp z_voidp
|
||||
#endif
|
||||
|
||||
#if defined(__MSDOS__) && !defined(MSDOS)
|
||||
# define MSDOS
|
||||
#endif
|
||||
#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
|
||||
# define OS2
|
||||
#endif
|
||||
#if defined(_WINDOWS) && !defined(WINDOWS)
|
||||
# define WINDOWS
|
||||
#endif
|
||||
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
|
||||
# ifndef WIN32
|
||||
# define WIN32
|
||||
# endif
|
||||
#endif
|
||||
#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
|
||||
# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
|
||||
# ifndef SYS16BIT
|
||||
# define SYS16BIT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
|
||||
* than 64k bytes at a time (needed on systems with 16-bit int).
|
||||
*/
|
||||
#ifdef SYS16BIT
|
||||
# define MAXSEG_64K
|
||||
#endif
|
||||
#ifdef MSDOS
|
||||
# define UNALIGNED_OK
|
||||
#endif
|
||||
|
||||
#ifdef __STDC_VERSION__
|
||||
# ifndef STDC
|
||||
# define STDC
|
||||
# endif
|
||||
# if __STDC_VERSION__ >= 199901L
|
||||
# ifndef STDC99
|
||||
# define STDC99
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
|
||||
# define STDC
|
||||
#endif
|
||||
|
||||
#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
|
||||
# define STDC
|
||||
#endif
|
||||
|
||||
#ifndef STDC
|
||||
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
|
||||
# define const /* note: need a more gentle solution here */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Some Mac compilers merge all .h files incorrectly: */
|
||||
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
|
||||
# define NO_DUMMY_DECL
|
||||
#endif
|
||||
|
||||
/* Maximum value for memLevel in deflateInit2 */
|
||||
#ifndef MAX_MEM_LEVEL
|
||||
# ifdef MAXSEG_64K
|
||||
# define MAX_MEM_LEVEL 8
|
||||
# else
|
||||
# define MAX_MEM_LEVEL 9
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
|
||||
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
|
||||
* created by gzip. (Files created by minigzip can still be extracted by
|
||||
* gzip.)
|
||||
*/
|
||||
#ifndef MAX_WBITS
|
||||
# define MAX_WBITS 15 /* 32K LZ77 window */
|
||||
#endif
|
||||
|
||||
/* The memory requirements for deflate are (in bytes):
|
||||
(1 << (windowBits+2)) + (1 << (memLevel+9))
|
||||
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
|
||||
plus a few kilobytes for small objects. For example, if you want to reduce
|
||||
the default memory requirements from 256K to 128K, compile with
|
||||
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
|
||||
Of course this will generally degrade compression (there's no free lunch).
|
||||
|
||||
The memory requirements for inflate are (in bytes) 1 << windowBits
|
||||
that is, 32K for windowBits=15 (default value) plus a few kilobytes
|
||||
for small objects.
|
||||
*/
|
||||
|
||||
/* Type declarations */
|
||||
|
||||
#ifndef OF /* function prototypes */
|
||||
# ifdef STDC
|
||||
# define OF(args) args
|
||||
# else
|
||||
# define OF(args) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The following definitions for FAR are needed only for MSDOS mixed
|
||||
* model programming (small or medium model with some far allocations).
|
||||
* This was tested only with MSC; for other MSDOS compilers you may have
|
||||
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
|
||||
* just define FAR to be empty.
|
||||
*/
|
||||
#ifdef SYS16BIT
|
||||
# if defined(M_I86SM) || defined(M_I86MM)
|
||||
/* MSC small or medium model */
|
||||
# define SMALL_MEDIUM
|
||||
# ifdef _MSC_VER
|
||||
# define FAR _far
|
||||
# else
|
||||
# define FAR far
|
||||
# endif
|
||||
# endif
|
||||
# if (defined(__SMALL__) || defined(__MEDIUM__))
|
||||
/* Turbo C small or medium model */
|
||||
# define SMALL_MEDIUM
|
||||
# ifdef __BORLANDC__
|
||||
# define FAR _far
|
||||
# else
|
||||
# define FAR far
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(WINDOWS) || defined(WIN32)
|
||||
/* If building or using zlib as a DLL, define ZLIB_DLL.
|
||||
* This is not mandatory, but it offers a little performance increase.
|
||||
*/
|
||||
# ifdef ZLIB_DLL
|
||||
# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
|
||||
# ifdef ZLIB_INTERNAL
|
||||
# define ZEXTERN extern __declspec(dllexport)
|
||||
# else
|
||||
# define ZEXTERN extern __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
# endif /* ZLIB_DLL */
|
||||
/* If building or using zlib with the WINAPI/WINAPIV calling convention,
|
||||
* define ZLIB_WINAPI.
|
||||
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
|
||||
*/
|
||||
# ifdef ZLIB_WINAPI
|
||||
# ifdef FAR
|
||||
# undef FAR
|
||||
# endif
|
||||
# include <windows.h>
|
||||
/* No need for _export, use ZLIB.DEF instead. */
|
||||
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
|
||||
# define ZEXPORT WINAPI
|
||||
# ifdef WIN32
|
||||
# define ZEXPORTVA WINAPIV
|
||||
# else
|
||||
# define ZEXPORTVA FAR CDECL
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined (__BEOS__)
|
||||
# ifdef ZLIB_DLL
|
||||
# ifdef ZLIB_INTERNAL
|
||||
# define ZEXPORT __declspec(dllexport)
|
||||
# define ZEXPORTVA __declspec(dllexport)
|
||||
# else
|
||||
# define ZEXPORT __declspec(dllimport)
|
||||
# define ZEXPORTVA __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef ZEXTERN
|
||||
# define ZEXTERN extern
|
||||
#endif
|
||||
#ifndef ZEXPORT
|
||||
# define ZEXPORT
|
||||
#endif
|
||||
#ifndef ZEXPORTVA
|
||||
# define ZEXPORTVA
|
||||
#endif
|
||||
|
||||
#ifndef FAR
|
||||
# define FAR
|
||||
#endif
|
||||
|
||||
#if !defined(__MACTYPES__)
|
||||
typedef unsigned char Byte; /* 8 bits */
|
||||
#endif
|
||||
typedef unsigned int uInt; /* 16 bits or more */
|
||||
typedef unsigned long uLong; /* 32 bits or more */
|
||||
|
||||
#ifdef SMALL_MEDIUM
|
||||
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
|
||||
# define Bytef Byte FAR
|
||||
#else
|
||||
typedef Byte FAR Bytef;
|
||||
#endif
|
||||
typedef char FAR charf;
|
||||
typedef int FAR intf;
|
||||
typedef uInt FAR uIntf;
|
||||
typedef uLong FAR uLongf;
|
||||
|
||||
#ifdef STDC
|
||||
typedef void const *voidpc;
|
||||
typedef void FAR *voidpf;
|
||||
typedef void *voidp;
|
||||
#else
|
||||
typedef Byte const *voidpc;
|
||||
typedef Byte FAR *voidpf;
|
||||
typedef Byte *voidp;
|
||||
#endif
|
||||
|
||||
#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
|
||||
# include <sys/types.h> /* for off_t */
|
||||
# include <unistd.h> /* for SEEK_* and off_t */
|
||||
# ifdef VMS
|
||||
# include <unixio.h> /* for off_t */
|
||||
# endif
|
||||
# define z_off_t off_t
|
||||
#endif
|
||||
#ifndef SEEK_SET
|
||||
# define SEEK_SET 0 /* Seek from beginning of file. */
|
||||
# define SEEK_CUR 1 /* Seek from current position. */
|
||||
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
|
||||
#endif
|
||||
#ifndef z_off_t
|
||||
# define z_off_t long
|
||||
#endif
|
||||
|
||||
#if defined(__OS400__)
|
||||
# define NO_vsnprintf
|
||||
#endif
|
||||
|
||||
#if defined(__MVS__)
|
||||
# define NO_vsnprintf
|
||||
# ifdef FAR
|
||||
# undef FAR
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* MVS linker does not support external names larger than 8 bytes */
|
||||
#if defined(__MVS__)
|
||||
# pragma map(deflateInit_,"DEIN")
|
||||
# pragma map(deflateInit2_,"DEIN2")
|
||||
# pragma map(deflateEnd,"DEEND")
|
||||
# pragma map(deflateBound,"DEBND")
|
||||
# pragma map(inflateInit_,"ININ")
|
||||
# pragma map(inflateInit2_,"ININ2")
|
||||
# pragma map(inflateEnd,"INEND")
|
||||
# pragma map(inflateSync,"INSY")
|
||||
# pragma map(inflateSetDictionary,"INSEDI")
|
||||
# pragma map(compressBound,"CMBND")
|
||||
# pragma map(inflate_table,"INTABL")
|
||||
# pragma map(inflate_fast,"INFA")
|
||||
# pragma map(inflate_copyright,"INCOPY")
|
||||
#endif
|
||||
|
||||
#endif /* ZCONF_H */
|
||||
/* zconf.h -- configuration of the zlib compression library
|
||||
* Copyright (C) 1995-2010 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#ifndef ZCONF_H
|
||||
#define ZCONF_H
|
||||
|
||||
/*
|
||||
* If you *really* need a unique prefix for all types and library functions,
|
||||
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
|
||||
* Even better than compiling with -DZ_PREFIX would be to use configure to set
|
||||
* this permanently in zconf.h using "./configure --zprefix".
|
||||
*/
|
||||
#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
|
||||
|
||||
/* all linked symbols */
|
||||
# define _dist_code z__dist_code
|
||||
# define _length_code z__length_code
|
||||
# define _tr_align z__tr_align
|
||||
# define _tr_flush_block z__tr_flush_block
|
||||
# define _tr_init z__tr_init
|
||||
# define _tr_stored_block z__tr_stored_block
|
||||
# define _tr_tally z__tr_tally
|
||||
# define adler32 z_adler32
|
||||
# define adler32_combine z_adler32_combine
|
||||
# define adler32_combine64 z_adler32_combine64
|
||||
# define compress z_compress
|
||||
# define compress2 z_compress2
|
||||
# define compressBound z_compressBound
|
||||
# define crc32 z_crc32
|
||||
# define crc32_combine z_crc32_combine
|
||||
# define crc32_combine64 z_crc32_combine64
|
||||
# define deflate z_deflate
|
||||
# define deflateBound z_deflateBound
|
||||
# define deflateCopy z_deflateCopy
|
||||
# define deflateEnd z_deflateEnd
|
||||
# define deflateInit2_ z_deflateInit2_
|
||||
# define deflateInit_ z_deflateInit_
|
||||
# define deflateParams z_deflateParams
|
||||
# define deflatePrime z_deflatePrime
|
||||
# define deflateReset z_deflateReset
|
||||
# define deflateSetDictionary z_deflateSetDictionary
|
||||
# define deflateSetHeader z_deflateSetHeader
|
||||
# define deflateTune z_deflateTune
|
||||
# define deflate_copyright z_deflate_copyright
|
||||
# define get_crc_table z_get_crc_table
|
||||
# define gz_error z_gz_error
|
||||
# define gz_intmax z_gz_intmax
|
||||
# define gz_strwinerror z_gz_strwinerror
|
||||
# define gzbuffer z_gzbuffer
|
||||
# define gzclearerr z_gzclearerr
|
||||
# define gzclose z_gzclose
|
||||
# define gzclose_r z_gzclose_r
|
||||
# define gzclose_w z_gzclose_w
|
||||
# define gzdirect z_gzdirect
|
||||
# define gzdopen z_gzdopen
|
||||
# define gzeof z_gzeof
|
||||
# define gzerror z_gzerror
|
||||
# define gzflush z_gzflush
|
||||
# define gzgetc z_gzgetc
|
||||
# define gzgets z_gzgets
|
||||
# define gzoffset z_gzoffset
|
||||
# define gzoffset64 z_gzoffset64
|
||||
# define gzopen z_gzopen
|
||||
# define gzopen64 z_gzopen64
|
||||
# define gzprintf z_gzprintf
|
||||
# define gzputc z_gzputc
|
||||
# define gzputs z_gzputs
|
||||
# define gzread z_gzread
|
||||
# define gzrewind z_gzrewind
|
||||
# define gzseek z_gzseek
|
||||
# define gzseek64 z_gzseek64
|
||||
# define gzsetparams z_gzsetparams
|
||||
# define gztell z_gztell
|
||||
# define gztell64 z_gztell64
|
||||
# define gzungetc z_gzungetc
|
||||
# define gzwrite z_gzwrite
|
||||
# define inflate z_inflate
|
||||
# define inflateBack z_inflateBack
|
||||
# define inflateBackEnd z_inflateBackEnd
|
||||
# define inflateBackInit_ z_inflateBackInit_
|
||||
# define inflateCopy z_inflateCopy
|
||||
# define inflateEnd z_inflateEnd
|
||||
# define inflateGetHeader z_inflateGetHeader
|
||||
# define inflateInit2_ z_inflateInit2_
|
||||
# define inflateInit_ z_inflateInit_
|
||||
# define inflateMark z_inflateMark
|
||||
# define inflatePrime z_inflatePrime
|
||||
# define inflateReset z_inflateReset
|
||||
# define inflateReset2 z_inflateReset2
|
||||
# define inflateSetDictionary z_inflateSetDictionary
|
||||
# define inflateSync z_inflateSync
|
||||
# define inflateSyncPoint z_inflateSyncPoint
|
||||
# define inflateUndermine z_inflateUndermine
|
||||
# define inflate_copyright z_inflate_copyright
|
||||
# define inflate_fast z_inflate_fast
|
||||
# define inflate_table z_inflate_table
|
||||
# define uncompress z_uncompress
|
||||
# define zError z_zError
|
||||
# define zcalloc z_zcalloc
|
||||
# define zcfree z_zcfree
|
||||
# define zlibCompileFlags z_zlibCompileFlags
|
||||
# define zlibVersion z_zlibVersion
|
||||
|
||||
/* all zlib typedefs in zlib.h and zconf.h */
|
||||
# define Byte z_Byte
|
||||
# define Bytef z_Bytef
|
||||
# define alloc_func z_alloc_func
|
||||
# define charf z_charf
|
||||
# define free_func z_free_func
|
||||
# define gzFile z_gzFile
|
||||
# define gz_header z_gz_header
|
||||
# define gz_headerp z_gz_headerp
|
||||
# define in_func z_in_func
|
||||
# define intf z_intf
|
||||
# define out_func z_out_func
|
||||
# define uInt z_uInt
|
||||
# define uIntf z_uIntf
|
||||
# define uLong z_uLong
|
||||
# define uLongf z_uLongf
|
||||
# define voidp z_voidp
|
||||
# define voidpc z_voidpc
|
||||
# define voidpf z_voidpf
|
||||
|
||||
/* all zlib structs in zlib.h and zconf.h */
|
||||
# define gz_header_s z_gz_header_s
|
||||
# define internal_state z_internal_state
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__MSDOS__) && !defined(MSDOS)
|
||||
# define MSDOS
|
||||
#endif
|
||||
#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
|
||||
# define OS2
|
||||
#endif
|
||||
#if defined(_WINDOWS) && !defined(WINDOWS)
|
||||
# define WINDOWS
|
||||
#endif
|
||||
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
|
||||
# ifndef WIN32
|
||||
# define WIN32
|
||||
# endif
|
||||
#endif
|
||||
#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
|
||||
# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
|
||||
# ifndef SYS16BIT
|
||||
# define SYS16BIT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
|
||||
* than 64k bytes at a time (needed on systems with 16-bit int).
|
||||
*/
|
||||
#ifdef SYS16BIT
|
||||
# define MAXSEG_64K
|
||||
#endif
|
||||
#ifdef MSDOS
|
||||
# define UNALIGNED_OK
|
||||
#endif
|
||||
|
||||
#ifdef __STDC_VERSION__
|
||||
# ifndef STDC
|
||||
# define STDC
|
||||
# endif
|
||||
# if __STDC_VERSION__ >= 199901L
|
||||
# ifndef STDC99
|
||||
# define STDC99
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
|
||||
# define STDC
|
||||
#endif
|
||||
|
||||
#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
|
||||
# define STDC
|
||||
#endif
|
||||
|
||||
#ifndef STDC
|
||||
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
|
||||
# define const /* note: need a more gentle solution here */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Some Mac compilers merge all .h files incorrectly: */
|
||||
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
|
||||
# define NO_DUMMY_DECL
|
||||
#endif
|
||||
|
||||
/* Maximum value for memLevel in deflateInit2 */
|
||||
#ifndef MAX_MEM_LEVEL
|
||||
# ifdef MAXSEG_64K
|
||||
# define MAX_MEM_LEVEL 8
|
||||
# else
|
||||
# define MAX_MEM_LEVEL 9
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
|
||||
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
|
||||
* created by gzip. (Files created by minigzip can still be extracted by
|
||||
* gzip.)
|
||||
*/
|
||||
#ifndef MAX_WBITS
|
||||
# define MAX_WBITS 15 /* 32K LZ77 window */
|
||||
#endif
|
||||
|
||||
/* The memory requirements for deflate are (in bytes):
|
||||
(1 << (windowBits+2)) + (1 << (memLevel+9))
|
||||
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
|
||||
plus a few kilobytes for small objects. For example, if you want to reduce
|
||||
the default memory requirements from 256K to 128K, compile with
|
||||
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
|
||||
Of course this will generally degrade compression (there's no free lunch).
|
||||
|
||||
The memory requirements for inflate are (in bytes) 1 << windowBits
|
||||
that is, 32K for windowBits=15 (default value) plus a few kilobytes
|
||||
for small objects.
|
||||
*/
|
||||
|
||||
/* Type declarations */
|
||||
|
||||
#ifndef OF /* function prototypes */
|
||||
# ifdef STDC
|
||||
# define OF(args) args
|
||||
# else
|
||||
# define OF(args) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The following definitions for FAR are needed only for MSDOS mixed
|
||||
* model programming (small or medium model with some far allocations).
|
||||
* This was tested only with MSC; for other MSDOS compilers you may have
|
||||
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
|
||||
* just define FAR to be empty.
|
||||
*/
|
||||
#ifdef SYS16BIT
|
||||
# if defined(M_I86SM) || defined(M_I86MM)
|
||||
/* MSC small or medium model */
|
||||
# define SMALL_MEDIUM
|
||||
# ifdef _MSC_VER
|
||||
# define FAR _far
|
||||
# else
|
||||
# define FAR far
|
||||
# endif
|
||||
# endif
|
||||
# if (defined(__SMALL__) || defined(__MEDIUM__))
|
||||
/* Turbo C small or medium model */
|
||||
# define SMALL_MEDIUM
|
||||
# ifdef __BORLANDC__
|
||||
# define FAR _far
|
||||
# else
|
||||
# define FAR far
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(WINDOWS) || defined(WIN32)
|
||||
/* If building or using zlib as a DLL, define ZLIB_DLL.
|
||||
* This is not mandatory, but it offers a little performance increase.
|
||||
*/
|
||||
# ifdef ZLIB_DLL
|
||||
# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
|
||||
# ifdef ZLIB_INTERNAL
|
||||
# define ZEXTERN extern __declspec(dllexport)
|
||||
# else
|
||||
# define ZEXTERN extern __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
# endif /* ZLIB_DLL */
|
||||
/* If building or using zlib with the WINAPI/WINAPIV calling convention,
|
||||
* define ZLIB_WINAPI.
|
||||
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
|
||||
*/
|
||||
# ifdef ZLIB_WINAPI
|
||||
# ifdef FAR
|
||||
# undef FAR
|
||||
# endif
|
||||
# include <windows.h>
|
||||
/* No need for _export, use ZLIB.DEF instead. */
|
||||
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
|
||||
# define ZEXPORT WINAPI
|
||||
# ifdef WIN32
|
||||
# define ZEXPORTVA WINAPIV
|
||||
# else
|
||||
# define ZEXPORTVA FAR CDECL
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined (__BEOS__)
|
||||
# ifdef ZLIB_DLL
|
||||
# ifdef ZLIB_INTERNAL
|
||||
# define ZEXPORT __declspec(dllexport)
|
||||
# define ZEXPORTVA __declspec(dllexport)
|
||||
# else
|
||||
# define ZEXPORT __declspec(dllimport)
|
||||
# define ZEXPORTVA __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef ZEXTERN
|
||||
# define ZEXTERN extern
|
||||
#endif
|
||||
#ifndef ZEXPORT
|
||||
# define ZEXPORT
|
||||
#endif
|
||||
#ifndef ZEXPORTVA
|
||||
# define ZEXPORTVA
|
||||
#endif
|
||||
|
||||
#ifndef FAR
|
||||
# define FAR
|
||||
#endif
|
||||
|
||||
#if !defined(__MACTYPES__)
|
||||
typedef unsigned char Byte; /* 8 bits */
|
||||
#endif
|
||||
typedef unsigned int uInt; /* 16 bits or more */
|
||||
typedef unsigned long uLong; /* 32 bits or more */
|
||||
|
||||
#ifdef SMALL_MEDIUM
|
||||
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
|
||||
# define Bytef Byte FAR
|
||||
#else
|
||||
typedef Byte FAR Bytef;
|
||||
#endif
|
||||
typedef char FAR charf;
|
||||
typedef int FAR intf;
|
||||
typedef uInt FAR uIntf;
|
||||
typedef uLong FAR uLongf;
|
||||
|
||||
#ifdef STDC
|
||||
typedef void const *voidpc;
|
||||
typedef void FAR *voidpf;
|
||||
typedef void *voidp;
|
||||
#else
|
||||
typedef Byte const *voidpc;
|
||||
typedef Byte FAR *voidpf;
|
||||
typedef Byte *voidp;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
|
||||
# define Z_HAVE_UNISTD_H
|
||||
#endif
|
||||
|
||||
#ifdef STDC
|
||||
# include <sys/types.h> /* for off_t */
|
||||
#endif
|
||||
|
||||
/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
|
||||
* "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
|
||||
* though the former does not conform to the LFS document), but considering
|
||||
* both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
|
||||
* equivalently requesting no 64-bit operations
|
||||
*/
|
||||
#if -_LARGEFILE64_SOURCE - -1 == 1
|
||||
# undef _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
|
||||
#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
|
||||
# include <unistd.h> /* for SEEK_* and off_t */
|
||||
# ifdef VMS
|
||||
# include <unixio.h> /* for off_t */
|
||||
# endif
|
||||
# ifndef z_off_t
|
||||
# define z_off_t off_t
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef SEEK_SET
|
||||
# define SEEK_SET 0 /* Seek from beginning of file. */
|
||||
# define SEEK_CUR 1 /* Seek from current position. */
|
||||
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
|
||||
#endif
|
||||
|
||||
#ifndef z_off_t
|
||||
# define z_off_t long
|
||||
#endif
|
||||
|
||||
#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
|
||||
# define z_off64_t off64_t
|
||||
#else
|
||||
# define z_off64_t z_off_t
|
||||
#endif
|
||||
|
||||
#if defined(__OS400__)
|
||||
# define NO_vsnprintf
|
||||
#endif
|
||||
|
||||
#if defined(__MVS__)
|
||||
# define NO_vsnprintf
|
||||
#endif
|
||||
|
||||
/* MVS linker does not support external names larger than 8 bytes */
|
||||
#if defined(__MVS__)
|
||||
#pragma map(deflateInit_,"DEIN")
|
||||
#pragma map(deflateInit2_,"DEIN2")
|
||||
#pragma map(deflateEnd,"DEEND")
|
||||
#pragma map(deflateBound,"DEBND")
|
||||
#pragma map(inflateInit_,"ININ")
|
||||
#pragma map(inflateInit2_,"ININ2")
|
||||
#pragma map(inflateEnd,"INEND")
|
||||
#pragma map(inflateSync,"INSY")
|
||||
#pragma map(inflateSetDictionary,"INSEDI")
|
||||
#pragma map(compressBound,"CMBND")
|
||||
#pragma map(inflate_table,"INTABL")
|
||||
#pragma map(inflate_fast,"INFA")
|
||||
#pragma map(inflate_copyright,"INCOPY")
|
||||
#endif
|
||||
|
||||
#endif /* ZCONF_H */
|
430
thirdparty/include/zconf.h.cmake.msvc
vendored
Normal file
430
thirdparty/include/zconf.h.cmake.msvc
vendored
Normal file
@ -0,0 +1,430 @@
|
||||
/* zconf.h -- configuration of the zlib compression library
|
||||
* Copyright (C) 1995-2010 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#ifndef ZCONF_H
|
||||
#define ZCONF_H
|
||||
/* #undef Z_PREFIX */
|
||||
/* #undef Z_HAVE_UNISTD_H */
|
||||
|
||||
/*
|
||||
* If you *really* need a unique prefix for all types and library functions,
|
||||
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
|
||||
* Even better than compiling with -DZ_PREFIX would be to use configure to set
|
||||
* this permanently in zconf.h using "./configure --zprefix".
|
||||
*/
|
||||
#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
|
||||
|
||||
/* all linked symbols */
|
||||
# define _dist_code z__dist_code
|
||||
# define _length_code z__length_code
|
||||
# define _tr_align z__tr_align
|
||||
# define _tr_flush_block z__tr_flush_block
|
||||
# define _tr_init z__tr_init
|
||||
# define _tr_stored_block z__tr_stored_block
|
||||
# define _tr_tally z__tr_tally
|
||||
# define adler32 z_adler32
|
||||
# define adler32_combine z_adler32_combine
|
||||
# define adler32_combine64 z_adler32_combine64
|
||||
# define compress z_compress
|
||||
# define compress2 z_compress2
|
||||
# define compressBound z_compressBound
|
||||
# define crc32 z_crc32
|
||||
# define crc32_combine z_crc32_combine
|
||||
# define crc32_combine64 z_crc32_combine64
|
||||
# define deflate z_deflate
|
||||
# define deflateBound z_deflateBound
|
||||
# define deflateCopy z_deflateCopy
|
||||
# define deflateEnd z_deflateEnd
|
||||
# define deflateInit2_ z_deflateInit2_
|
||||
# define deflateInit_ z_deflateInit_
|
||||
# define deflateParams z_deflateParams
|
||||
# define deflatePrime z_deflatePrime
|
||||
# define deflateReset z_deflateReset
|
||||
# define deflateSetDictionary z_deflateSetDictionary
|
||||
# define deflateSetHeader z_deflateSetHeader
|
||||
# define deflateTune z_deflateTune
|
||||
# define deflate_copyright z_deflate_copyright
|
||||
# define get_crc_table z_get_crc_table
|
||||
# define gz_error z_gz_error
|
||||
# define gz_intmax z_gz_intmax
|
||||
# define gz_strwinerror z_gz_strwinerror
|
||||
# define gzbuffer z_gzbuffer
|
||||
# define gzclearerr z_gzclearerr
|
||||
# define gzclose z_gzclose
|
||||
# define gzclose_r z_gzclose_r
|
||||
# define gzclose_w z_gzclose_w
|
||||
# define gzdirect z_gzdirect
|
||||
# define gzdopen z_gzdopen
|
||||
# define gzeof z_gzeof
|
||||
# define gzerror z_gzerror
|
||||
# define gzflush z_gzflush
|
||||
# define gzgetc z_gzgetc
|
||||
# define gzgets z_gzgets
|
||||
# define gzoffset z_gzoffset
|
||||
# define gzoffset64 z_gzoffset64
|
||||
# define gzopen z_gzopen
|
||||
# define gzopen64 z_gzopen64
|
||||
# define gzprintf z_gzprintf
|
||||
# define gzputc z_gzputc
|
||||
# define gzputs z_gzputs
|
||||
# define gzread z_gzread
|
||||
# define gzrewind z_gzrewind
|
||||
# define gzseek z_gzseek
|
||||
# define gzseek64 z_gzseek64
|
||||
# define gzsetparams z_gzsetparams
|
||||
# define gztell z_gztell
|
||||
# define gztell64 z_gztell64
|
||||
# define gzungetc z_gzungetc
|
||||
# define gzwrite z_gzwrite
|
||||
# define inflate z_inflate
|
||||
# define inflateBack z_inflateBack
|
||||
# define inflateBackEnd z_inflateBackEnd
|
||||
# define inflateBackInit_ z_inflateBackInit_
|
||||
# define inflateCopy z_inflateCopy
|
||||
# define inflateEnd z_inflateEnd
|
||||
# define inflateGetHeader z_inflateGetHeader
|
||||
# define inflateInit2_ z_inflateInit2_
|
||||
# define inflateInit_ z_inflateInit_
|
||||
# define inflateMark z_inflateMark
|
||||
# define inflatePrime z_inflatePrime
|
||||
# define inflateReset z_inflateReset
|
||||
# define inflateReset2 z_inflateReset2
|
||||
# define inflateSetDictionary z_inflateSetDictionary
|
||||
# define inflateSync z_inflateSync
|
||||
# define inflateSyncPoint z_inflateSyncPoint
|
||||
# define inflateUndermine z_inflateUndermine
|
||||
# define inflate_copyright z_inflate_copyright
|
||||
# define inflate_fast z_inflate_fast
|
||||
# define inflate_table z_inflate_table
|
||||
# define uncompress z_uncompress
|
||||
# define zError z_zError
|
||||
# define zcalloc z_zcalloc
|
||||
# define zcfree z_zcfree
|
||||
# define zlibCompileFlags z_zlibCompileFlags
|
||||
# define zlibVersion z_zlibVersion
|
||||
|
||||
/* all zlib typedefs in zlib.h and zconf.h */
|
||||
# define Byte z_Byte
|
||||
# define Bytef z_Bytef
|
||||
# define alloc_func z_alloc_func
|
||||
# define charf z_charf
|
||||
# define free_func z_free_func
|
||||
# define gzFile z_gzFile
|
||||
# define gz_header z_gz_header
|
||||
# define gz_headerp z_gz_headerp
|
||||
# define in_func z_in_func
|
||||
# define intf z_intf
|
||||
# define out_func z_out_func
|
||||
# define uInt z_uInt
|
||||
# define uIntf z_uIntf
|
||||
# define uLong z_uLong
|
||||
# define uLongf z_uLongf
|
||||
# define voidp z_voidp
|
||||
# define voidpc z_voidpc
|
||||
# define voidpf z_voidpf
|
||||
|
||||
/* all zlib structs in zlib.h and zconf.h */
|
||||
# define gz_header_s z_gz_header_s
|
||||
# define internal_state z_internal_state
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__MSDOS__) && !defined(MSDOS)
|
||||
# define MSDOS
|
||||
#endif
|
||||
#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
|
||||
# define OS2
|
||||
#endif
|
||||
#if defined(_WINDOWS) && !defined(WINDOWS)
|
||||
# define WINDOWS
|
||||
#endif
|
||||
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
|
||||
# ifndef WIN32
|
||||
# define WIN32
|
||||
# endif
|
||||
#endif
|
||||
#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
|
||||
# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
|
||||
# ifndef SYS16BIT
|
||||
# define SYS16BIT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
|
||||
* than 64k bytes at a time (needed on systems with 16-bit int).
|
||||
*/
|
||||
#ifdef SYS16BIT
|
||||
# define MAXSEG_64K
|
||||
#endif
|
||||
#ifdef MSDOS
|
||||
# define UNALIGNED_OK
|
||||
#endif
|
||||
|
||||
#ifdef __STDC_VERSION__
|
||||
# ifndef STDC
|
||||
# define STDC
|
||||
# endif
|
||||
# if __STDC_VERSION__ >= 199901L
|
||||
# ifndef STDC99
|
||||
# define STDC99
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
|
||||
# define STDC
|
||||
#endif
|
||||
|
||||
#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
|
||||
# define STDC
|
||||
#endif
|
||||
|
||||
#ifndef STDC
|
||||
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
|
||||
# define const /* note: need a more gentle solution here */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Some Mac compilers merge all .h files incorrectly: */
|
||||
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
|
||||
# define NO_DUMMY_DECL
|
||||
#endif
|
||||
|
||||
/* Maximum value for memLevel in deflateInit2 */
|
||||
#ifndef MAX_MEM_LEVEL
|
||||
# ifdef MAXSEG_64K
|
||||
# define MAX_MEM_LEVEL 8
|
||||
# else
|
||||
# define MAX_MEM_LEVEL 9
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
|
||||
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
|
||||
* created by gzip. (Files created by minigzip can still be extracted by
|
||||
* gzip.)
|
||||
*/
|
||||
#ifndef MAX_WBITS
|
||||
# define MAX_WBITS 15 /* 32K LZ77 window */
|
||||
#endif
|
||||
|
||||
/* The memory requirements for deflate are (in bytes):
|
||||
(1 << (windowBits+2)) + (1 << (memLevel+9))
|
||||
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
|
||||
plus a few kilobytes for small objects. For example, if you want to reduce
|
||||
the default memory requirements from 256K to 128K, compile with
|
||||
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
|
||||
Of course this will generally degrade compression (there's no free lunch).
|
||||
|
||||
The memory requirements for inflate are (in bytes) 1 << windowBits
|
||||
that is, 32K for windowBits=15 (default value) plus a few kilobytes
|
||||
for small objects.
|
||||
*/
|
||||
|
||||
/* Type declarations */
|
||||
|
||||
#ifndef OF /* function prototypes */
|
||||
# ifdef STDC
|
||||
# define OF(args) args
|
||||
# else
|
||||
# define OF(args) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The following definitions for FAR are needed only for MSDOS mixed
|
||||
* model programming (small or medium model with some far allocations).
|
||||
* This was tested only with MSC; for other MSDOS compilers you may have
|
||||
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
|
||||
* just define FAR to be empty.
|
||||
*/
|
||||
#ifdef SYS16BIT
|
||||
# if defined(M_I86SM) || defined(M_I86MM)
|
||||
/* MSC small or medium model */
|
||||
# define SMALL_MEDIUM
|
||||
# ifdef _MSC_VER
|
||||
# define FAR _far
|
||||
# else
|
||||
# define FAR far
|
||||
# endif
|
||||
# endif
|
||||
# if (defined(__SMALL__) || defined(__MEDIUM__))
|
||||
/* Turbo C small or medium model */
|
||||
# define SMALL_MEDIUM
|
||||
# ifdef __BORLANDC__
|
||||
# define FAR _far
|
||||
# else
|
||||
# define FAR far
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(WINDOWS) || defined(WIN32)
|
||||
/* If building or using zlib as a DLL, define ZLIB_DLL.
|
||||
* This is not mandatory, but it offers a little performance increase.
|
||||
*/
|
||||
# ifdef ZLIB_DLL
|
||||
# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
|
||||
# ifdef ZLIB_INTERNAL
|
||||
# define ZEXTERN extern __declspec(dllexport)
|
||||
# else
|
||||
# define ZEXTERN extern __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
# endif /* ZLIB_DLL */
|
||||
/* If building or using zlib with the WINAPI/WINAPIV calling convention,
|
||||
* define ZLIB_WINAPI.
|
||||
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
|
||||
*/
|
||||
# ifdef ZLIB_WINAPI
|
||||
# ifdef FAR
|
||||
# undef FAR
|
||||
# endif
|
||||
# include <windows.h>
|
||||
/* No need for _export, use ZLIB.DEF instead. */
|
||||
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
|
||||
# define ZEXPORT WINAPI
|
||||
# ifdef WIN32
|
||||
# define ZEXPORTVA WINAPIV
|
||||
# else
|
||||
# define ZEXPORTVA FAR CDECL
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined (__BEOS__)
|
||||
# ifdef ZLIB_DLL
|
||||
# ifdef ZLIB_INTERNAL
|
||||
# define ZEXPORT __declspec(dllexport)
|
||||
# define ZEXPORTVA __declspec(dllexport)
|
||||
# else
|
||||
# define ZEXPORT __declspec(dllimport)
|
||||
# define ZEXPORTVA __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef ZEXTERN
|
||||
# define ZEXTERN extern
|
||||
#endif
|
||||
#ifndef ZEXPORT
|
||||
# define ZEXPORT
|
||||
#endif
|
||||
#ifndef ZEXPORTVA
|
||||
# define ZEXPORTVA
|
||||
#endif
|
||||
|
||||
#ifndef FAR
|
||||
# define FAR
|
||||
#endif
|
||||
|
||||
#if !defined(__MACTYPES__)
|
||||
typedef unsigned char Byte; /* 8 bits */
|
||||
#endif
|
||||
typedef unsigned int uInt; /* 16 bits or more */
|
||||
typedef unsigned long uLong; /* 32 bits or more */
|
||||
|
||||
#ifdef SMALL_MEDIUM
|
||||
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
|
||||
# define Bytef Byte FAR
|
||||
#else
|
||||
typedef Byte FAR Bytef;
|
||||
#endif
|
||||
typedef char FAR charf;
|
||||
typedef int FAR intf;
|
||||
typedef uInt FAR uIntf;
|
||||
typedef uLong FAR uLongf;
|
||||
|
||||
#ifdef STDC
|
||||
typedef void const *voidpc;
|
||||
typedef void FAR *voidpf;
|
||||
typedef void *voidp;
|
||||
#else
|
||||
typedef Byte const *voidpc;
|
||||
typedef Byte FAR *voidpf;
|
||||
typedef Byte *voidp;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
|
||||
# define Z_HAVE_UNISTD_H
|
||||
#endif
|
||||
|
||||
#ifdef STDC
|
||||
# include <sys/types.h> /* for off_t */
|
||||
#endif
|
||||
|
||||
/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
|
||||
* "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
|
||||
* though the former does not conform to the LFS document), but considering
|
||||
* both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
|
||||
* equivalently requesting no 64-bit operations
|
||||
*/
|
||||
#if -_LARGEFILE64_SOURCE - -1 == 1
|
||||
# undef _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
|
||||
#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
|
||||
# include <unistd.h> /* for SEEK_* and off_t */
|
||||
# ifdef VMS
|
||||
# include <unixio.h> /* for off_t */
|
||||
# endif
|
||||
# ifndef z_off_t
|
||||
# define z_off_t off_t
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef SEEK_SET
|
||||
# define SEEK_SET 0 /* Seek from beginning of file. */
|
||||
# define SEEK_CUR 1 /* Seek from current position. */
|
||||
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
|
||||
#endif
|
||||
|
||||
#ifndef z_off_t
|
||||
# define z_off_t long
|
||||
#endif
|
||||
|
||||
#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
|
||||
# define z_off64_t off64_t
|
||||
#else
|
||||
# define z_off64_t z_off_t
|
||||
#endif
|
||||
|
||||
#if defined(__OS400__)
|
||||
# define NO_vsnprintf
|
||||
#endif
|
||||
|
||||
#if defined(__MVS__)
|
||||
# define NO_vsnprintf
|
||||
#endif
|
||||
|
||||
/* MVS linker does not support external names larger than 8 bytes */
|
||||
#if defined(__MVS__)
|
||||
#pragma map(deflateInit_,"DEIN")
|
||||
#pragma map(deflateInit2_,"DEIN2")
|
||||
#pragma map(deflateEnd,"DEEND")
|
||||
#pragma map(deflateBound,"DEBND")
|
||||
#pragma map(inflateInit_,"ININ")
|
||||
#pragma map(inflateInit2_,"ININ2")
|
||||
#pragma map(inflateEnd,"INEND")
|
||||
#pragma map(inflateSync,"INSY")
|
||||
#pragma map(inflateSetDictionary,"INSEDI")
|
||||
#pragma map(compressBound,"CMBND")
|
||||
#pragma map(inflate_table,"INTABL")
|
||||
#pragma map(inflate_fast,"INFA")
|
||||
#pragma map(inflate_copyright,"INCOPY")
|
||||
#endif
|
||||
|
||||
#endif /* ZCONF_H */
|
2970
libs/png/zlib.h → thirdparty/include/zlib.h
vendored
Executable file → Normal file
2970
libs/png/zlib.h → thirdparty/include/zlib.h
vendored
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
20
thirdparty/liblcms2/CMakeLists.txt
vendored
Normal file
20
thirdparty/liblcms2/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
PROJECT(liblcms2 C)
|
||||
#
|
||||
INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
#
|
||||
FILE(GLOB SRCS src/*.c)
|
||||
FILE(GLOB HDRS include/*.h)
|
||||
#
|
||||
SET(LIBTARGET "lcms2")
|
||||
#
|
||||
ADD_LIBRARY(${LIBTARGET} STATIC ${SRCS} ${HDRS})
|
||||
#
|
||||
IF(MSVC)
|
||||
SET_TARGET_PROPERTIES(${LIBTARGET} PROPERTIES PREFIX "lib")
|
||||
ENDIF(MSVC)
|
||||
#
|
||||
SET_TARGET_PROPERTIES(${LIBTARGET}
|
||||
PROPERTIES
|
||||
OUTPUT_NAME "${LIBTARGET}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/thirdparty/lib)
|
||||
#
|
8
thirdparty/liblcms2/COPYING
vendored
Normal file
8
thirdparty/liblcms2/COPYING
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
Little CMS
|
||||
Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
|
||||
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.
|
33
libs/lcms2/lcms2.h → thirdparty/liblcms2/include/lcms2.h
vendored
Executable file → Normal file
33
libs/lcms2/lcms2.h → thirdparty/liblcms2/include/lcms2.h
vendored
Executable file → Normal file
@ -23,7 +23,7 @@
|
||||
//
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Version 2.0
|
||||
// Version 2.1
|
||||
//
|
||||
|
||||
#ifndef _lcms2_H
|
||||
@ -72,7 +72,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
// Version/release
|
||||
#define LCMS_VERSION 2000
|
||||
#define LCMS_VERSION 2010
|
||||
|
||||
// I will give the chance of redefining basic types for compilers that are not fully C99 compliant
|
||||
#ifndef CMS_BASIC_TYPES_ALREADY_DEFINED
|
||||
@ -181,12 +181,12 @@ typedef int cmsBool;
|
||||
# define CMS_USE_BIG_ENDIAN 1
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_CPU_PPC
|
||||
#if TARGET_CPU_PPC
|
||||
# define CMS_USE_BIG_ENDIAN 1
|
||||
#endif
|
||||
|
||||
#ifdef macintosh
|
||||
# ifndef __LITTLE_ENDIAN__
|
||||
# ifdef __BIG_ENDIAN__
|
||||
# define CMS_USE_BIG_ENDIAN 1
|
||||
# endif
|
||||
#endif
|
||||
@ -380,7 +380,7 @@ typedef enum {
|
||||
cmsSigMotionPictureFilmScanner = 0x6D706673, // 'mpfs'
|
||||
cmsSigMotionPictureFilmRecorder = 0x6D706672, // 'mpfr'
|
||||
cmsSigDigitalMotionPictureCamera = 0x646D7063, // 'dmpc'
|
||||
cmsSigDigitalCinemaProjector = 0x64636A70, // 'dcpj'
|
||||
cmsSigDigitalCinemaProjector = 0x64636A70 // 'dcpj'
|
||||
|
||||
} cmsTechnologySignature;
|
||||
|
||||
@ -441,7 +441,7 @@ typedef enum {
|
||||
cmsSigLinkClass = 0x6C696E6B, // 'link'
|
||||
cmsSigAbstractClass = 0x61627374, // 'abst'
|
||||
cmsSigColorSpaceClass = 0x73706163, // 'spac'
|
||||
cmsSigNamedColorClass = 0x6e6d636c, // 'nmcl'
|
||||
cmsSigNamedColorClass = 0x6e6d636c // 'nmcl'
|
||||
|
||||
} cmsProfileClassSignature;
|
||||
|
||||
@ -844,9 +844,12 @@ typedef void* cmsHTRANSFORM;
|
||||
|
||||
// Float formatters.
|
||||
#define TYPE_XYZ_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_XYZ)|CHANNELS_SH(3)|BYTES_SH(4))
|
||||
#define TYPE_XYZA_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_XYZ)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4))
|
||||
#define TYPE_Lab_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_Lab)|CHANNELS_SH(3)|BYTES_SH(4))
|
||||
#define TYPE_LabA_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_Lab)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4))
|
||||
#define TYPE_GRAY_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_GRAY)|CHANNELS_SH(1)|BYTES_SH(4))
|
||||
#define TYPE_RGB_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4))
|
||||
#define TYPE_RGBA_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4))
|
||||
#define TYPE_CMYK_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(4))
|
||||
|
||||
// Floating point formatters.
|
||||
@ -1307,12 +1310,18 @@ CMSAPI cmsBool CMSEXPORT cmsIsTag(cmsHPROFILE hProfile, cmsTagSignatur
|
||||
CMSAPI void* CMSEXPORT cmsReadTag(cmsHPROFILE hProfile, cmsTagSignature sig);
|
||||
CMSAPI cmsBool CMSEXPORT cmsWriteTag(cmsHPROFILE hProfile, cmsTagSignature sig, const void* data);
|
||||
CMSAPI cmsBool CMSEXPORT cmsLinkTag(cmsHPROFILE hProfile, cmsTagSignature sig, cmsTagSignature dest);
|
||||
CMSAPI cmsTagSignature CMSEXPORT cmsTagLinkedTo(cmsHPROFILE hProfile, cmsTagSignature sig);
|
||||
|
||||
// Read and write raw data
|
||||
CMSAPI cmsInt32Number CMSEXPORT cmsReadRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, void* Buffer, cmsUInt32Number BufferSize);
|
||||
CMSAPI cmsBool CMSEXPORT cmsWriteRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, const void* data, cmsUInt32Number Size);
|
||||
|
||||
// Access header data
|
||||
#define cmsEmbeddedProfileFalse 0x00000000
|
||||
#define cmsEmbeddedProfileTrue 0x00000001
|
||||
#define cmsUseAnywhere 0x00000000
|
||||
#define cmsUseWithEmbeddedDataOnly 0x00000002
|
||||
|
||||
CMSAPI cmsUInt32Number CMSEXPORT cmsGetHeaderFlags(cmsHPROFILE hProfile);
|
||||
CMSAPI void CMSEXPORT cmsGetHeaderAttributes(cmsHPROFILE hProfile, cmsUInt64Number* Flags);
|
||||
CMSAPI void CMSEXPORT cmsGetHeaderProfileID(cmsHPROFILE hProfile, cmsUInt8Number* ProfileID);
|
||||
@ -1348,9 +1357,9 @@ CMSAPI void CMSEXPORT cmsSetEncodedICCversion(cmsHPROFILE hProfile,
|
||||
#define LCMS_USED_AS_OUTPUT 1
|
||||
#define LCMS_USED_AS_PROOF 2
|
||||
|
||||
CMSAPI cmsBool CMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile, cmsUInt32Number Intent, int UsedDirection);
|
||||
CMSAPI cmsBool CMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number UsedDirection);
|
||||
CMSAPI cmsBool CMSEXPORT cmsIsMatrixShaper(cmsHPROFILE hProfile);
|
||||
CMSAPI cmsBool CMSEXPORT cmsIsCLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent, int UsedDirection);
|
||||
CMSAPI cmsBool CMSEXPORT cmsIsCLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number UsedDirection);
|
||||
|
||||
// Translate form/to our notation to ICC
|
||||
CMSAPI cmsColorSpaceSignature CMSEXPORT _cmsICCcolorSpace(int OurNotation);
|
||||
@ -1499,7 +1508,6 @@ CMSAPI cmsUInt32Number CMSEXPORT cmsGetSupportedIntents(cmsUInt32Number nMax, c
|
||||
#define cmsFLAGS_NOOPTIMIZE 0x0100 // Inhibit optimizations
|
||||
#define cmsFLAGS_NULLTRANSFORM 0x0200 // Don't transform anyway
|
||||
|
||||
|
||||
// Proofing flags
|
||||
#define cmsFLAGS_GAMUTCHECK 0x1000 // Out of Gamut alarm
|
||||
#define cmsFLAGS_SOFTPROOFING 0x4000 // Do softproofing
|
||||
@ -1603,8 +1611,15 @@ CMSAPI void CMSEXPORT cmsGetAlarmCodes(cmsUInt16Number NewAlarm[cmsM
|
||||
// Adaptation state for absolute colorimetric intent
|
||||
CMSAPI cmsFloat64Number CMSEXPORT cmsSetAdaptationState(cmsFloat64Number d);
|
||||
|
||||
// Grab the ContextID from an open transform. Returns NULL if a NULL transform is passed
|
||||
CMSAPI cmsContext CMSEXPORT cmsGetTransformContextID(cmsHTRANSFORM hTransform);
|
||||
|
||||
// For backwards compatibility
|
||||
CMSAPI cmsBool CMSEXPORT cmsChangeBuffersFormat(cmsHTRANSFORM hTransform,
|
||||
cmsUInt32Number InputFormat,
|
||||
cmsUInt32Number OutputFormat);
|
||||
|
||||
|
||||
|
||||
// PostScript ColorRenderingDictionary and ColorSpaceArray ----------------------------------------------------
|
||||
|
4
libs/lcms2/lcms2_plugin.h → thirdparty/liblcms2/include/lcms2_plugin.h
vendored
Executable file → Normal file
4
libs/lcms2/lcms2_plugin.h → thirdparty/liblcms2/include/lcms2_plugin.h
vendored
Executable file → Normal file
@ -115,6 +115,7 @@ struct _cms_io_handler {
|
||||
|
||||
cmsContext ContextID;
|
||||
cmsUInt32Number UsedSpace;
|
||||
cmsUInt32Number ReportedSize;
|
||||
char PhysicalFile[cmsMAX_PATH];
|
||||
|
||||
cmsUInt32Number (* Read)(struct _cms_io_handler* iohandler, void *Buffer,
|
||||
@ -385,8 +386,9 @@ typedef struct _cms_typehandler_struct {
|
||||
void (* FreePtr)(struct _cms_typehandler_struct* self,
|
||||
void *Ptr);
|
||||
|
||||
// The calling thread
|
||||
// Additional parameters used by the calling thread
|
||||
cmsContext ContextID;
|
||||
cmsUInt32Number ICCVersion;
|
||||
|
||||
} cmsTagTypeHandler;
|
||||
|
483
thirdparty/liblcms2/src/cmscam02.c
vendored
Normal file
483
thirdparty/liblcms2/src/cmscam02.c
vendored
Normal file
@ -0,0 +1,483 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
//
|
||||
// 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 "lcms2_internal.h"
|
||||
|
||||
// CIECAM 02 appearance model. Many thanks to Jordi Vilar for the debugging.
|
||||
|
||||
// ---------- Implementation --------------------------------------------
|
||||
|
||||
typedef struct {
|
||||
|
||||
cmsFloat64Number XYZ[3];
|
||||
cmsFloat64Number RGB[3];
|
||||
cmsFloat64Number RGBc[3];
|
||||
cmsFloat64Number RGBp[3];
|
||||
cmsFloat64Number RGBpa[3];
|
||||
cmsFloat64Number a, b, h, e, H, A, J, Q, s, t, C, M;
|
||||
cmsFloat64Number abC[2];
|
||||
cmsFloat64Number abs[2];
|
||||
cmsFloat64Number abM[2];
|
||||
|
||||
} CAM02COLOR;
|
||||
|
||||
typedef struct {
|
||||
|
||||
CAM02COLOR adoptedWhite;
|
||||
cmsFloat64Number LA, Yb;
|
||||
cmsFloat64Number F, c, Nc;
|
||||
cmsUInt32Number surround;
|
||||
cmsFloat64Number n, Nbb, Ncb, z, FL, D;
|
||||
|
||||
cmsContext ContextID;
|
||||
|
||||
} cmsCIECAM02;
|
||||
|
||||
|
||||
static
|
||||
cmsFloat64Number compute_n(cmsCIECAM02* pMod)
|
||||
{
|
||||
return (pMod -> Yb / pMod -> adoptedWhite.XYZ[1]);
|
||||
}
|
||||
|
||||
static
|
||||
cmsFloat64Number compute_z(cmsCIECAM02* pMod)
|
||||
{
|
||||
return (1.48 + pow(pMod -> n, 0.5));
|
||||
}
|
||||
|
||||
static
|
||||
cmsFloat64Number computeNbb(cmsCIECAM02* pMod)
|
||||
{
|
||||
return (0.725 * pow((1.0 / pMod -> n), 0.2));
|
||||
}
|
||||
|
||||
static
|
||||
cmsFloat64Number computeFL(cmsCIECAM02* pMod)
|
||||
{
|
||||
cmsFloat64Number k, FL;
|
||||
|
||||
k = 1.0 / ((5.0 * pMod->LA) + 1.0);
|
||||
FL = 0.2 * pow(k, 4.0) * (5.0 * pMod->LA) + 0.1 *
|
||||
(pow((1.0 - pow(k, 4.0)), 2.0)) *
|
||||
(pow((5.0 * pMod->LA), (1.0 / 3.0)));
|
||||
|
||||
return FL;
|
||||
}
|
||||
|
||||
static
|
||||
cmsFloat64Number computeD(cmsCIECAM02* pMod)
|
||||
{
|
||||
cmsFloat64Number D;
|
||||
|
||||
D = pMod->F - (1.0/3.6)*(exp(((-pMod ->LA-42) / 92.0)));
|
||||
|
||||
return D;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
CAM02COLOR XYZtoCAT02(CAM02COLOR clr)
|
||||
{
|
||||
clr.RGB[0] = (clr.XYZ[0] * 0.7328) + (clr.XYZ[1] * 0.4296) + (clr.XYZ[2] * -0.1624);
|
||||
clr.RGB[1] = (clr.XYZ[0] * -0.7036) + (clr.XYZ[1] * 1.6975) + (clr.XYZ[2] * 0.0061);
|
||||
clr.RGB[2] = (clr.XYZ[0] * 0.0030) + (clr.XYZ[1] * 0.0136) + (clr.XYZ[2] * 0.9834);
|
||||
|
||||
return clr;
|
||||
}
|
||||
|
||||
static
|
||||
CAM02COLOR ChromaticAdaptation(CAM02COLOR clr, cmsCIECAM02* pMod)
|
||||
{
|
||||
cmsUInt32Number i;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
clr.RGBc[i] = ((pMod -> adoptedWhite.XYZ[1] *
|
||||
(pMod->D / pMod -> adoptedWhite.RGB[i])) +
|
||||
(1.0 - pMod->D)) * clr.RGB[i];
|
||||
}
|
||||
|
||||
return clr;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
CAM02COLOR CAT02toHPE(CAM02COLOR clr)
|
||||
{
|
||||
cmsFloat64Number M[9];
|
||||
|
||||
M[0] =(( 0.38971 * 1.096124) + (0.68898 * 0.454369) + (-0.07868 * -0.009628));
|
||||
M[1] =(( 0.38971 * -0.278869) + (0.68898 * 0.473533) + (-0.07868 * -0.005698));
|
||||
M[2] =(( 0.38971 * 0.182745) + (0.68898 * 0.072098) + (-0.07868 * 1.015326));
|
||||
M[3] =((-0.22981 * 1.096124) + (1.18340 * 0.454369) + ( 0.04641 * -0.009628));
|
||||
M[4] =((-0.22981 * -0.278869) + (1.18340 * 0.473533) + ( 0.04641 * -0.005698));
|
||||
M[5] =((-0.22981 * 0.182745) + (1.18340 * 0.072098) + ( 0.04641 * 1.015326));
|
||||
M[6] =(-0.009628);
|
||||
M[7] =(-0.005698);
|
||||
M[8] =( 1.015326);
|
||||
|
||||
clr.RGBp[0] = (clr.RGBc[0] * M[0]) + (clr.RGBc[1] * M[1]) + (clr.RGBc[2] * M[2]);
|
||||
clr.RGBp[1] = (clr.RGBc[0] * M[3]) + (clr.RGBc[1] * M[4]) + (clr.RGBc[2] * M[5]);
|
||||
clr.RGBp[2] = (clr.RGBc[0] * M[6]) + (clr.RGBc[1] * M[7]) + (clr.RGBc[2] * M[8]);
|
||||
|
||||
return clr;
|
||||
}
|
||||
|
||||
static
|
||||
CAM02COLOR NonlinearCompression(CAM02COLOR clr, cmsCIECAM02* pMod)
|
||||
{
|
||||
cmsUInt32Number i;
|
||||
cmsFloat64Number temp;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (clr.RGBp[i] < 0) {
|
||||
|
||||
temp = pow((-1.0 * pMod->FL * clr.RGBp[i] / 100.0), 0.42);
|
||||
clr.RGBpa[i] = (-1.0 * 400.0 * temp) / (temp + 27.13) + 0.1;
|
||||
}
|
||||
else {
|
||||
temp = pow((pMod->FL * clr.RGBp[i] / 100.0), 0.42);
|
||||
clr.RGBpa[i] = (400.0 * temp) / (temp + 27.13) + 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
clr.A = (((2.0 * clr.RGBpa[0]) + clr.RGBpa[1] +
|
||||
(clr.RGBpa[2] / 20.0)) - 0.305) * pMod->Nbb;
|
||||
|
||||
return clr;
|
||||
}
|
||||
|
||||
static
|
||||
CAM02COLOR ComputeCorrelates(CAM02COLOR clr, cmsCIECAM02* pMod)
|
||||
{
|
||||
cmsFloat64Number a, b, temp, e, t, r2d, d2r;
|
||||
|
||||
a = clr.RGBpa[0] - (12.0 * clr.RGBpa[1] / 11.0) + (clr.RGBpa[2] / 11.0);
|
||||
b = (clr.RGBpa[0] + clr.RGBpa[1] - (2.0 * clr.RGBpa[2])) / 9.0;
|
||||
|
||||
r2d = (180.0 / 3.141592654);
|
||||
if (a == 0) {
|
||||
if (b == 0) clr.h = 0;
|
||||
else if (b > 0) clr.h = 90;
|
||||
else clr.h = 270;
|
||||
}
|
||||
else if (a > 0) {
|
||||
temp = b / a;
|
||||
if (b > 0) clr.h = (r2d * atan(temp));
|
||||
else if (b == 0) clr.h = 0;
|
||||
else clr.h = (r2d * atan(temp)) + 360;
|
||||
}
|
||||
else {
|
||||
temp = b / a;
|
||||
clr.h = (r2d * atan(temp)) + 180;
|
||||
}
|
||||
|
||||
d2r = (3.141592654 / 180.0);
|
||||
e = ((12500.0 / 13.0) * pMod->Nc * pMod->Ncb) *
|
||||
(cos((clr.h * d2r + 2.0)) + 3.8);
|
||||
|
||||
if (clr.h < 20.14) {
|
||||
temp = ((clr.h + 122.47)/1.2) + ((20.14 - clr.h)/0.8);
|
||||
clr.H = 300 + (100*((clr.h + 122.47)/1.2)) / temp;
|
||||
}
|
||||
else if (clr.h < 90.0) {
|
||||
temp = ((clr.h - 20.14)/0.8) + ((90.00 - clr.h)/0.7);
|
||||
clr.H = (100*((clr.h - 20.14)/0.8)) / temp;
|
||||
}
|
||||
else if (clr.h < 164.25) {
|
||||
temp = ((clr.h - 90.00)/0.7) + ((164.25 - clr.h)/1.0);
|
||||
clr.H = 100 + ((100*((clr.h - 90.00)/0.7)) / temp);
|
||||
}
|
||||
else if (clr.h < 237.53) {
|
||||
temp = ((clr.h - 164.25)/1.0) + ((237.53 - clr.h)/1.2);
|
||||
clr.H = 200 + ((100*((clr.h - 164.25)/1.0)) / temp);
|
||||
}
|
||||
else {
|
||||
temp = ((clr.h - 237.53)/1.2) + ((360 - clr.h + 20.14)/0.8);
|
||||
clr.H = 300 + ((100*((clr.h - 237.53)/1.2)) / temp);
|
||||
}
|
||||
|
||||
clr.J = 100.0 * pow((clr.A / pMod->adoptedWhite.A),
|
||||
(pMod->c * pMod->z));
|
||||
|
||||
clr.Q = (4.0 / pMod->c) * pow((clr.J / 100.0), 0.5) *
|
||||
(pMod->adoptedWhite.A + 4.0) * pow(pMod->FL, 0.25);
|
||||
|
||||
t = (e * pow(((a * a) + (b * b)), 0.5)) /
|
||||
(clr.RGBpa[0] + clr.RGBpa[1] +
|
||||
((21.0 / 20.0) * clr.RGBpa[2]));
|
||||
|
||||
clr.C = pow(t, 0.9) * pow((clr.J / 100.0), 0.5) *
|
||||
pow((1.64 - pow(0.29, pMod->n)), 0.73);
|
||||
|
||||
clr.M = clr.C * pow(pMod->FL, 0.25);
|
||||
clr.s = 100.0 * pow((clr.M / clr.Q), 0.5);
|
||||
|
||||
return clr;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
CAM02COLOR InverseCorrelates(CAM02COLOR clr, cmsCIECAM02* pMod)
|
||||
{
|
||||
|
||||
cmsFloat64Number t, e, p1, p2, p3, p4, p5, hr, d2r;
|
||||
d2r = 3.141592654 / 180.0;
|
||||
|
||||
t = pow( (clr.C / (pow((clr.J / 100.0), 0.5) *
|
||||
(pow((1.64 - pow(0.29, pMod->n)), 0.73)))),
|
||||
(1.0 / 0.9) );
|
||||
e = ((12500.0 / 13.0) * pMod->Nc * pMod->Ncb) *
|
||||
(cos((clr.h * d2r + 2.0)) + 3.8);
|
||||
|
||||
clr.A = pMod->adoptedWhite.A * pow(
|
||||
(clr.J / 100.0),
|
||||
(1.0 / (pMod->c * pMod->z)));
|
||||
|
||||
p1 = e / t;
|
||||
p2 = (clr.A / pMod->Nbb) + 0.305;
|
||||
p3 = 21.0 / 20.0;
|
||||
|
||||
hr = clr.h * d2r;
|
||||
|
||||
if (fabs(sin(hr)) >= fabs(cos(hr))) {
|
||||
p4 = p1 / sin(hr);
|
||||
clr.b = (p2 * (2.0 + p3) * (460.0 / 1403.0)) /
|
||||
(p4 + (2.0 + p3) * (220.0 / 1403.0) *
|
||||
(cos(hr) / sin(hr)) - (27.0 / 1403.0) +
|
||||
p3 * (6300.0 / 1403.0));
|
||||
clr.a = clr.b * (cos(hr) / sin(hr));
|
||||
}
|
||||
else {
|
||||
p5 = p1 / cos(hr);
|
||||
clr.a = (p2 * (2.0 + p3) * (460.0 / 1403.0)) /
|
||||
(p5 + (2.0 + p3) * (220.0 / 1403.0) -
|
||||
((27.0 / 1403.0) - p3 * (6300.0 / 1403.0)) *
|
||||
(sin(hr) / cos(hr)));
|
||||
clr.b = clr.a * (sin(hr) / cos(hr));
|
||||
}
|
||||
|
||||
clr.RGBpa[0] = ((460.0 / 1403.0) * p2) +
|
||||
((451.0 / 1403.0) * clr.a) +
|
||||
((288.0 / 1403.0) * clr.b);
|
||||
clr.RGBpa[1] = ((460.0 / 1403.0) * p2) -
|
||||
((891.0 / 1403.0) * clr.a) -
|
||||
((261.0 / 1403.0) * clr.b);
|
||||
clr.RGBpa[2] = ((460.0 / 1403.0) * p2) -
|
||||
((220.0 / 1403.0) * clr.a) -
|
||||
((6300.0 / 1403.0) * clr.b);
|
||||
|
||||
return clr;
|
||||
}
|
||||
|
||||
static
|
||||
CAM02COLOR InverseNonlinearity(CAM02COLOR clr, cmsCIECAM02* pMod)
|
||||
{
|
||||
cmsUInt32Number i;
|
||||
cmsFloat64Number c1;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if ((clr.RGBpa[i] - 0.1) < 0) c1 = -1;
|
||||
else c1 = 1;
|
||||
clr.RGBp[i] = c1 * (100.0 / pMod->FL) *
|
||||
pow(((27.13 * fabs(clr.RGBpa[i] - 0.1)) /
|
||||
(400.0 - fabs(clr.RGBpa[i] - 0.1))),
|
||||
(1.0 / 0.42));
|
||||
}
|
||||
|
||||
return clr;
|
||||
}
|
||||
|
||||
static
|
||||
CAM02COLOR HPEtoCAT02(CAM02COLOR clr)
|
||||
{
|
||||
cmsFloat64Number M[9];
|
||||
|
||||
M[0] = (( 0.7328 * 1.910197) + (0.4296 * 0.370950));
|
||||
M[1] = (( 0.7328 * -1.112124) + (0.4296 * 0.629054));
|
||||
M[2] = (( 0.7328 * 0.201908) + (0.4296 * 0.000008) - 0.1624);
|
||||
M[3] = ((-0.7036 * 1.910197) + (1.6975 * 0.370950));
|
||||
M[4] = ((-0.7036 * -1.112124) + (1.6975 * 0.629054));
|
||||
M[5] = ((-0.7036 * 0.201908) + (1.6975 * 0.000008) + 0.0061);
|
||||
M[6] = (( 0.0030 * 1.910197) + (0.0136 * 0.370950));
|
||||
M[7] = (( 0.0030 * -1.112124) + (0.0136 * 0.629054));
|
||||
M[8] = (( 0.0030 * 0.201908) + (0.0136 * 0.000008) + 0.9834);;
|
||||
|
||||
clr.RGBc[0] = (clr.RGBp[0] * M[0]) + (clr.RGBp[1] * M[1]) + (clr.RGBp[2] * M[2]);
|
||||
clr.RGBc[1] = (clr.RGBp[0] * M[3]) + (clr.RGBp[1] * M[4]) + (clr.RGBp[2] * M[5]);
|
||||
clr.RGBc[2] = (clr.RGBp[0] * M[6]) + (clr.RGBp[1] * M[7]) + (clr.RGBp[2] * M[8]);
|
||||
return clr;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
CAM02COLOR InverseChromaticAdaptation(CAM02COLOR clr, cmsCIECAM02* pMod)
|
||||
{
|
||||
cmsUInt32Number i;
|
||||
for (i = 0; i < 3; i++) {
|
||||
clr.RGB[i] = clr.RGBc[i] /
|
||||
((pMod->adoptedWhite.XYZ[1] * pMod->D / pMod->adoptedWhite.RGB[i]) + 1.0 - pMod->D);
|
||||
}
|
||||
return clr;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
CAM02COLOR CAT02toXYZ(CAM02COLOR clr)
|
||||
{
|
||||
clr.XYZ[0] = (clr.RGB[0] * 1.096124) + (clr.RGB[1] * -0.278869) + (clr.RGB[2] * 0.182745);
|
||||
clr.XYZ[1] = (clr.RGB[0] * 0.454369) + (clr.RGB[1] * 0.473533) + (clr.RGB[2] * 0.072098);
|
||||
clr.XYZ[2] = (clr.RGB[0] * -0.009628) + (clr.RGB[1] * -0.005698) + (clr.RGB[2] * 1.015326);
|
||||
|
||||
return clr;
|
||||
}
|
||||
|
||||
|
||||
cmsHANDLE CMSEXPORT cmsCIECAM02Init(cmsContext ContextID, const cmsViewingConditions* pVC)
|
||||
{
|
||||
cmsCIECAM02* lpMod;
|
||||
|
||||
_cmsAssert(pVC != NULL);
|
||||
|
||||
if((lpMod = (cmsCIECAM02*) _cmsMallocZero(ContextID, sizeof(cmsCIECAM02))) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lpMod ->ContextID = ContextID;
|
||||
|
||||
lpMod ->adoptedWhite.XYZ[0] = pVC ->whitePoint.X;
|
||||
lpMod ->adoptedWhite.XYZ[1] = pVC ->whitePoint.Y;
|
||||
lpMod ->adoptedWhite.XYZ[2] = pVC ->whitePoint.Z;
|
||||
|
||||
lpMod -> LA = pVC ->La;
|
||||
lpMod -> Yb = pVC ->Yb;
|
||||
lpMod -> D = pVC ->D_value;
|
||||
lpMod -> surround = pVC ->surround;
|
||||
|
||||
switch (lpMod -> surround) {
|
||||
|
||||
|
||||
case CUTSHEET_SURROUND:
|
||||
lpMod->F = 0.8;
|
||||
lpMod->c = 0.41;
|
||||
lpMod->Nc = 0.8;
|
||||
break;
|
||||
|
||||
case DARK_SURROUND:
|
||||
lpMod -> F = 0.8;
|
||||
lpMod -> c = 0.525;
|
||||
lpMod -> Nc = 0.8;
|
||||
break;
|
||||
|
||||
case DIM_SURROUND:
|
||||
lpMod -> F = 0.9;
|
||||
lpMod -> c = 0.59;
|
||||
lpMod -> Nc = 0.95;
|
||||
break;
|
||||
|
||||
default:
|
||||
// Average surround
|
||||
lpMod -> F = 1.0;
|
||||
lpMod -> c = 0.69;
|
||||
lpMod -> Nc = 1.0;
|
||||
}
|
||||
|
||||
lpMod -> n = compute_n(lpMod);
|
||||
lpMod -> z = compute_z(lpMod);
|
||||
lpMod -> Nbb = computeNbb(lpMod);
|
||||
lpMod -> FL = computeFL(lpMod);
|
||||
|
||||
if (lpMod -> D == D_CALCULATE) {
|
||||
lpMod -> D = computeD(lpMod);
|
||||
}
|
||||
|
||||
lpMod -> Ncb = lpMod -> Nbb;
|
||||
|
||||
lpMod -> adoptedWhite = XYZtoCAT02(lpMod -> adoptedWhite);
|
||||
lpMod -> adoptedWhite = ChromaticAdaptation(lpMod -> adoptedWhite, lpMod);
|
||||
lpMod -> adoptedWhite = CAT02toHPE(lpMod -> adoptedWhite);
|
||||
lpMod -> adoptedWhite = NonlinearCompression(lpMod -> adoptedWhite, lpMod);
|
||||
|
||||
return (cmsHANDLE) lpMod;
|
||||
|
||||
}
|
||||
|
||||
void CMSEXPORT cmsCIECAM02Done(cmsHANDLE hModel)
|
||||
{
|
||||
cmsCIECAM02* lpMod = (cmsCIECAM02*) hModel;
|
||||
|
||||
if (lpMod) _cmsFree(lpMod ->ContextID, lpMod);
|
||||
}
|
||||
|
||||
|
||||
void CMSEXPORT cmsCIECAM02Forward(cmsHANDLE hModel, const cmsCIEXYZ* pIn, cmsJCh* pOut)
|
||||
{
|
||||
CAM02COLOR clr;
|
||||
cmsCIECAM02* lpMod = (cmsCIECAM02*) hModel;
|
||||
|
||||
_cmsAssert(lpMod != NULL);
|
||||
_cmsAssert(pIn != NULL);
|
||||
_cmsAssert(pOut != NULL);
|
||||
|
||||
clr.XYZ[0] = pIn ->X;
|
||||
clr.XYZ[1] = pIn ->Y;
|
||||
clr.XYZ[2] = pIn ->Z;
|
||||
|
||||
clr = XYZtoCAT02(clr);
|
||||
clr = ChromaticAdaptation(clr, lpMod);
|
||||
clr = CAT02toHPE(clr);
|
||||
clr = NonlinearCompression(clr, lpMod);
|
||||
clr = ComputeCorrelates(clr, lpMod);
|
||||
|
||||
pOut ->J = clr.J;
|
||||
pOut ->C = clr.C;
|
||||
pOut ->h = clr.h;
|
||||
}
|
||||
|
||||
void CMSEXPORT cmsCIECAM02Reverse(cmsHANDLE hModel, const cmsJCh* pIn, cmsCIEXYZ* pOut)
|
||||
{
|
||||
CAM02COLOR clr;
|
||||
cmsCIECAM02* lpMod = (cmsCIECAM02*) hModel;
|
||||
|
||||
_cmsAssert(lpMod != NULL);
|
||||
_cmsAssert(pIn != NULL);
|
||||
_cmsAssert(pOut != NULL);
|
||||
|
||||
clr.J = pIn -> J;
|
||||
clr.C = pIn -> C;
|
||||
clr.h = pIn -> h;
|
||||
|
||||
clr = InverseCorrelates(clr, lpMod);
|
||||
clr = InverseNonlinearity(clr, lpMod);
|
||||
clr = HPEtoCAT02(clr);
|
||||
clr = InverseChromaticAdaptation(clr, lpMod);
|
||||
clr = CAT02toXYZ(clr);
|
||||
|
||||
pOut ->X = clr.XYZ[0];
|
||||
pOut ->Y = clr.XYZ[1];
|
||||
pOut ->Z = clr.XYZ[2];
|
||||
}
|
||||
|
2655
thirdparty/liblcms2/src/cmscgats.c
vendored
Normal file
2655
thirdparty/liblcms2/src/cmscgats.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1039
thirdparty/liblcms2/src/cmscnvrt.c
vendored
Normal file
1039
thirdparty/liblcms2/src/cmscnvrt.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
428
thirdparty/liblcms2/src/cmserr.c
vendored
Normal file
428
thirdparty/liblcms2/src/cmserr.c
vendored
Normal file
@ -0,0 +1,428 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
//
|
||||
// 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 "lcms2_internal.h"
|
||||
|
||||
// I am so tired about incompatibilities on those functions that here are some replacements
|
||||
// that hopefully would be fully portable.
|
||||
|
||||
// compare two strings ignoring case
|
||||
int CMSEXPORT cmsstrcasecmp(const char* s1, const char* s2)
|
||||
{
|
||||
register const unsigned char *us1 = (const unsigned char *)s1,
|
||||
*us2 = (const unsigned char *)s2;
|
||||
|
||||
while (toupper(*us1) == toupper(*us2++))
|
||||
if (*us1++ == '\0')
|
||||
return (0);
|
||||
return (toupper(*us1) - toupper(*--us2));
|
||||
}
|
||||
|
||||
// long int because C99 specifies ftell in such way (7.19.9.2)
|
||||
long int CMSEXPORT cmsfilelength(FILE* f)
|
||||
{
|
||||
long int p , n;
|
||||
|
||||
p = ftell(f); // register current file position
|
||||
|
||||
if (fseek(f, 0, SEEK_END) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
n = ftell(f);
|
||||
fseek(f, p, SEEK_SET); // file position restored
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
// Memory handling ------------------------------------------------------------------
|
||||
//
|
||||
// This is the interface to low-level memory management routines. By default a simple
|
||||
// wrapping to malloc/free/realloc is provided, although there is a limit on the max
|
||||
// amount of memoy that can be reclaimed. This is mostly as a safety feature to
|
||||
// prevent bogus or malintentionated code to allocate huge blocks that otherwise lcms
|
||||
// would never need.
|
||||
|
||||
#define MAX_MEMORY_FOR_ALLOC ((cmsUInt32Number)(1024U*1024U*512U))
|
||||
|
||||
// User may override this behaviour by using a memory plug-in, which basically replaces
|
||||
// the default memory management functions. In this case, no check is performed and it
|
||||
// is up to the plug-in writter to keep in the safe side. There are only three functions
|
||||
// required to be implemented: malloc, realloc and free, although the user may want to
|
||||
// replace the optional mallocZero, calloc and dup as well.
|
||||
|
||||
cmsBool _cmsRegisterMemHandlerPlugin(cmsPluginBase* Plugin);
|
||||
|
||||
// *********************************************************************************
|
||||
|
||||
// This is the default memory allocation function. It does a very coarse
|
||||
// check of amout of memory, just to prevent exploits
|
||||
static
|
||||
void* _cmsMallocDefaultFn(cmsContext ContextID, cmsUInt32Number size)
|
||||
{
|
||||
if (size > MAX_MEMORY_FOR_ALLOC) return NULL; // Never allow over maximum
|
||||
|
||||
return (void*) malloc(size);
|
||||
|
||||
cmsUNUSED_PARAMETER(ContextID);
|
||||
}
|
||||
|
||||
// Generic allocate & zero
|
||||
static
|
||||
void* _cmsMallocZeroDefaultFn(cmsContext ContextID, cmsUInt32Number size)
|
||||
{
|
||||
void *pt = _cmsMalloc(ContextID, size);
|
||||
if (pt == NULL) return NULL;
|
||||
|
||||
memset(pt, 0, size);
|
||||
return pt;
|
||||
}
|
||||
|
||||
|
||||
// The default free function. The only check proformed is against NULL pointers
|
||||
static
|
||||
void _cmsFreeDefaultFn(cmsContext ContextID, void *Ptr)
|
||||
{
|
||||
// free(NULL) is defined a no-op by C99, therefore it is safe to
|
||||
// avoid the check, but it is here just in case...
|
||||
|
||||
if (Ptr) free(Ptr);
|
||||
|
||||
cmsUNUSED_PARAMETER(ContextID);
|
||||
}
|
||||
|
||||
// The default realloc function. Again it check for exploits. If Ptr is NULL,
|
||||
// realloc behaves the same way as malloc and allocates a new block of size bytes.
|
||||
static
|
||||
void* _cmsReallocDefaultFn(cmsContext ContextID, void* Ptr, cmsUInt32Number size)
|
||||
{
|
||||
|
||||
if (size > MAX_MEMORY_FOR_ALLOC) return NULL; // Never realloc over 512Mb
|
||||
|
||||
return realloc(Ptr, size);
|
||||
|
||||
cmsUNUSED_PARAMETER(ContextID);
|
||||
}
|
||||
|
||||
|
||||
// The default calloc function. Allocates an array of num elements, each one of size bytes
|
||||
// all memory is initialized to zero.
|
||||
static
|
||||
void* _cmsCallocDefaultFn(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Number size)
|
||||
{
|
||||
cmsUInt32Number Total = num * size;
|
||||
|
||||
// Preserve calloc behaviour
|
||||
if (Total == 0) return NULL;
|
||||
|
||||
// Safe check for overflow.
|
||||
if (num >= UINT_MAX / size) return NULL;
|
||||
|
||||
// Check for overflow
|
||||
if (Total < num || Total < size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (Total > MAX_MEMORY_FOR_ALLOC) return NULL; // Never alloc over 512Mb
|
||||
|
||||
return _cmsMallocZero(ContextID, Total);
|
||||
}
|
||||
|
||||
// Generic block duplication
|
||||
static
|
||||
void* _cmsDupDefaultFn(cmsContext ContextID, const void* Org, cmsUInt32Number size)
|
||||
{
|
||||
void* mem;
|
||||
|
||||
if (size > MAX_MEMORY_FOR_ALLOC) return NULL; // Never dup over 512Mb
|
||||
|
||||
mem = _cmsMalloc(ContextID, size);
|
||||
|
||||
if (mem != NULL && Org != NULL)
|
||||
memmove(mem, Org, size);
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
// Pointers to malloc and _cmsFree functions in current environment
|
||||
static void * (* MallocPtr)(cmsContext ContextID, cmsUInt32Number size) = _cmsMallocDefaultFn;
|
||||
static void * (* MallocZeroPtr)(cmsContext ContextID, cmsUInt32Number size) = _cmsMallocZeroDefaultFn;
|
||||
static void (* FreePtr)(cmsContext ContextID, void *Ptr) = _cmsFreeDefaultFn;
|
||||
static void * (* ReallocPtr)(cmsContext ContextID, void *Ptr, cmsUInt32Number NewSize) = _cmsReallocDefaultFn;
|
||||
static void * (* CallocPtr)(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Number size)= _cmsCallocDefaultFn;
|
||||
static void * (* DupPtr)(cmsContext ContextID, const void* Org, cmsUInt32Number size) = _cmsDupDefaultFn;
|
||||
|
||||
// Plug-in replacement entry
|
||||
cmsBool _cmsRegisterMemHandlerPlugin(cmsPluginBase *Data)
|
||||
{
|
||||
cmsPluginMemHandler* Plugin = (cmsPluginMemHandler*) Data;
|
||||
|
||||
// NULL forces to reset to defaults
|
||||
if (Data == NULL) {
|
||||
|
||||
MallocPtr = _cmsMallocDefaultFn;
|
||||
MallocZeroPtr= _cmsMallocZeroDefaultFn;
|
||||
FreePtr = _cmsFreeDefaultFn;
|
||||
ReallocPtr = _cmsReallocDefaultFn;
|
||||
CallocPtr = _cmsCallocDefaultFn;
|
||||
DupPtr = _cmsDupDefaultFn;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Check for required callbacks
|
||||
if (Plugin -> MallocPtr == NULL ||
|
||||
Plugin -> FreePtr == NULL ||
|
||||
Plugin -> ReallocPtr == NULL) return FALSE;
|
||||
|
||||
// Set replacement functions
|
||||
MallocPtr = Plugin -> MallocPtr;
|
||||
FreePtr = Plugin -> FreePtr;
|
||||
ReallocPtr = Plugin -> ReallocPtr;
|
||||
|
||||
if (Plugin ->MallocZeroPtr != NULL) MallocZeroPtr = Plugin ->MallocZeroPtr;
|
||||
if (Plugin ->CallocPtr != NULL) CallocPtr = Plugin -> CallocPtr;
|
||||
if (Plugin ->DupPtr != NULL) DupPtr = Plugin -> DupPtr;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Generic allocate
|
||||
void* CMSEXPORT _cmsMalloc(cmsContext ContextID, cmsUInt32Number size)
|
||||
{
|
||||
return MallocPtr(ContextID, size);
|
||||
}
|
||||
|
||||
// Generic allocate & zero
|
||||
void* CMSEXPORT _cmsMallocZero(cmsContext ContextID, cmsUInt32Number size)
|
||||
{
|
||||
return MallocZeroPtr(ContextID, size);
|
||||
}
|
||||
|
||||
// Generic calloc
|
||||
void* CMSEXPORT _cmsCalloc(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Number size)
|
||||
{
|
||||
return CallocPtr(ContextID, num, size);
|
||||
}
|
||||
|
||||
// Generic reallocate
|
||||
void* CMSEXPORT _cmsRealloc(cmsContext ContextID, void* Ptr, cmsUInt32Number size)
|
||||
{
|
||||
return ReallocPtr(ContextID, Ptr, size);
|
||||
}
|
||||
|
||||
// Generic free memory
|
||||
void CMSEXPORT _cmsFree(cmsContext ContextID, void* Ptr)
|
||||
{
|
||||
if (Ptr != NULL) FreePtr(ContextID, Ptr);
|
||||
}
|
||||
|
||||
// Generic block duplication
|
||||
void* CMSEXPORT _cmsDupMem(cmsContext ContextID, const void* Org, cmsUInt32Number size)
|
||||
{
|
||||
return DupPtr(ContextID, Org, size);
|
||||
}
|
||||
|
||||
// ********************************************************************************************
|
||||
|
||||
// Sub allocation takes care of many pointers of small size. The memory allocated in
|
||||
// this way have be freed at once. Next function allocates a single chunk for linked list
|
||||
// I prefer this method over realloc due to the big inpact on xput realloc may have if
|
||||
// memory is being swapped to disk. This approach is safer (although thats not true on any platform)
|
||||
static
|
||||
_cmsSubAllocator_chunk* _cmsCreateSubAllocChunk(cmsContext ContextID, cmsUInt32Number Initial)
|
||||
{
|
||||
_cmsSubAllocator_chunk* chunk;
|
||||
|
||||
// Create the container
|
||||
chunk = (_cmsSubAllocator_chunk*) _cmsMallocZero(ContextID, sizeof(_cmsSubAllocator_chunk));
|
||||
if (chunk == NULL) return NULL;
|
||||
|
||||
// Initialize values
|
||||
chunk ->Block = (cmsUInt8Number*) _cmsMalloc(ContextID, Initial);
|
||||
if (chunk ->Block == NULL) {
|
||||
|
||||
// Something went wrong
|
||||
_cmsFree(ContextID, chunk);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 20K by default
|
||||
if (Initial == 0)
|
||||
Initial = 20*1024;
|
||||
|
||||
chunk ->BlockSize = Initial;
|
||||
chunk ->Used = 0;
|
||||
chunk ->next = NULL;
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
// The suballocated is nothing but a pointer to the first element in the list. We also keep
|
||||
// the thread ID in this structure.
|
||||
_cmsSubAllocator* _cmsCreateSubAlloc(cmsContext ContextID, cmsUInt32Number Initial)
|
||||
{
|
||||
_cmsSubAllocator* sub;
|
||||
|
||||
// Create the container
|
||||
sub = (_cmsSubAllocator*) _cmsMallocZero(ContextID, sizeof(_cmsSubAllocator));
|
||||
if (sub == NULL) return NULL;
|
||||
|
||||
sub ->ContextID = ContextID;
|
||||
|
||||
sub ->h = _cmsCreateSubAllocChunk(ContextID, Initial);
|
||||
if (sub ->h == NULL) {
|
||||
_cmsFree(ContextID, sub);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return sub;
|
||||
}
|
||||
|
||||
|
||||
// Get rid of whole linked list
|
||||
void _cmsSubAllocDestroy(_cmsSubAllocator* sub)
|
||||
{
|
||||
_cmsSubAllocator_chunk *chunk, *n;
|
||||
|
||||
for (chunk = sub ->h; chunk != NULL; chunk = n) {
|
||||
|
||||
n = chunk->next;
|
||||
if (chunk->Block != NULL) _cmsFree(sub ->ContextID, chunk->Block);
|
||||
_cmsFree(sub ->ContextID, chunk);
|
||||
}
|
||||
|
||||
// Free the header
|
||||
_cmsFree(sub ->ContextID, sub);
|
||||
}
|
||||
|
||||
|
||||
// Get a pointer to small memory block.
|
||||
void* _cmsSubAlloc(_cmsSubAllocator* sub, cmsUInt32Number size)
|
||||
{
|
||||
cmsUInt32Number Free = sub -> h ->BlockSize - sub -> h -> Used;
|
||||
cmsUInt8Number* ptr;
|
||||
|
||||
size = _cmsALIGNLONG(size);
|
||||
|
||||
// Check for memory. If there is no room, allocate a new chunk of double memory size.
|
||||
if (size > Free) {
|
||||
|
||||
_cmsSubAllocator_chunk* chunk;
|
||||
cmsUInt32Number newSize;
|
||||
|
||||
newSize = sub -> h ->BlockSize * 2;
|
||||
if (newSize < size) newSize = size;
|
||||
|
||||
chunk = _cmsCreateSubAllocChunk(sub -> ContextID, newSize);
|
||||
if (chunk == NULL) return NULL;
|
||||
|
||||
// Link list
|
||||
chunk ->next = sub ->h;
|
||||
sub ->h = chunk;
|
||||
|
||||
}
|
||||
|
||||
ptr = sub -> h ->Block + sub -> h ->Used;
|
||||
sub -> h -> Used += size;
|
||||
|
||||
return (void*) ptr;
|
||||
}
|
||||
|
||||
// Error logging ******************************************************************
|
||||
|
||||
// There is no error handling at all. When a funtion fails, it returns proper value.
|
||||
// For example, all create functions does return NULL on failure. Other return FALSE
|
||||
// It may be interesting, for the developer, to know why the function is failing.
|
||||
// for that reason, lcms2 does offer a logging function. This function does recive
|
||||
// a ENGLISH string with some clues on what is going wrong. You can show this
|
||||
// info to the end user, or just create some sort of log.
|
||||
// The logging function should NOT terminate the program, as this obviously can leave
|
||||
// resources. It is the programmer's responsability to check each function return code
|
||||
// to make sure it didn't fail.
|
||||
|
||||
// Error messages are limited to MAX_ERROR_MESSAGE_LEN
|
||||
|
||||
#define MAX_ERROR_MESSAGE_LEN 1024
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------
|
||||
|
||||
// This is our default log error
|
||||
static void DefaultLogErrorHandlerFunction(cmsContext ContextID, cmsUInt32Number ErrorCode, const char *Text);
|
||||
|
||||
// The current handler in actual environment
|
||||
static cmsLogErrorHandlerFunction LogErrorHandler = DefaultLogErrorHandlerFunction;
|
||||
|
||||
// The default error logger does nothing.
|
||||
static
|
||||
void DefaultLogErrorHandlerFunction(cmsContext ContextID, cmsUInt32Number ErrorCode, const char *Text)
|
||||
{
|
||||
// fprintf(stderr, "[lcms]: %s\n", Text);
|
||||
// fflush(stderr);
|
||||
|
||||
cmsUNUSED_PARAMETER(ContextID);
|
||||
cmsUNUSED_PARAMETER(ErrorCode);
|
||||
cmsUNUSED_PARAMETER(Text);
|
||||
}
|
||||
|
||||
// Change log error
|
||||
void CMSEXPORT cmsSetLogErrorHandler(cmsLogErrorHandlerFunction Fn)
|
||||
{
|
||||
if (Fn == NULL)
|
||||
LogErrorHandler = DefaultLogErrorHandlerFunction;
|
||||
else
|
||||
LogErrorHandler = Fn;
|
||||
}
|
||||
|
||||
// Log an error
|
||||
// ErrorText is a text holding an english description of error.
|
||||
void CMSEXPORT cmsSignalError(cmsContext ContextID, cmsUInt32Number ErrorCode, const char *ErrorText, ...)
|
||||
{
|
||||
va_list args;
|
||||
char Buffer[MAX_ERROR_MESSAGE_LEN];
|
||||
|
||||
va_start(args, ErrorText);
|
||||
vsnprintf(Buffer, MAX_ERROR_MESSAGE_LEN-1, ErrorText, args);
|
||||
va_end(args);
|
||||
|
||||
// Call handler
|
||||
LogErrorHandler(ContextID, ErrorCode, Buffer);
|
||||
}
|
||||
|
||||
// Utility function to print signatures
|
||||
void _cmsTagSignature2String(char String[5], cmsTagSignature sig)
|
||||
{
|
||||
cmsUInt32Number be;
|
||||
|
||||
// Convert to big endian
|
||||
be = _cmsAdjustEndianess32((cmsUInt32Number) sig);
|
||||
|
||||
// Move chars
|
||||
memmove(String, &be, 4);
|
||||
|
||||
// Make sure of terminator
|
||||
String[4] = 0;
|
||||
}
|
||||
|
1138
thirdparty/liblcms2/src/cmsgamma.c
vendored
Normal file
1138
thirdparty/liblcms2/src/cmsgamma.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
591
thirdparty/liblcms2/src/cmsgmt.c
vendored
Normal file
591
thirdparty/liblcms2/src/cmsgmt.c
vendored
Normal file
@ -0,0 +1,591 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
//
|
||||
// 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 "lcms2_internal.h"
|
||||
|
||||
|
||||
// Auxiliar: append a Lab identity after the given sequence of profiles
|
||||
// and return the transform. Lab profile is closed, rest of profiles are kept open.
|
||||
cmsHTRANSFORM _cmsChain2Lab(cmsContext ContextID,
|
||||
cmsUInt32Number nProfiles,
|
||||
cmsUInt32Number InputFormat,
|
||||
cmsUInt32Number OutputFormat,
|
||||
const cmsUInt32Number Intents[],
|
||||
const cmsHPROFILE hProfiles[],
|
||||
const cmsBool BPC[],
|
||||
const cmsFloat64Number AdaptationStates[],
|
||||
cmsUInt32Number dwFlags)
|
||||
{
|
||||
cmsHTRANSFORM xform;
|
||||
cmsHPROFILE hLab;
|
||||
cmsHPROFILE ProfileList[256];
|
||||
cmsBool BPCList[256];
|
||||
cmsFloat64Number AdaptationList[256];
|
||||
cmsUInt32Number IntentList[256];
|
||||
cmsUInt32Number i;
|
||||
|
||||
// This is a rather big number and there is no need of dynamic memory
|
||||
// since we are adding a profile, 254 + 1 = 255 and this is the limit
|
||||
if (nProfiles > 254) return NULL;
|
||||
|
||||
// The output space
|
||||
hLab = cmsCreateLab4ProfileTHR(ContextID, NULL);
|
||||
if (hLab == NULL) return NULL;
|
||||
|
||||
// Create a copy of parameters
|
||||
for (i=0; i < nProfiles; i++) {
|
||||
|
||||
ProfileList[i] = hProfiles[i];
|
||||
BPCList[i] = BPC[i];
|
||||
AdaptationList[i] = AdaptationStates[i];
|
||||
IntentList[i] = Intents[i];
|
||||
}
|
||||
|
||||
// Place Lab identity at chain's end.
|
||||
ProfileList[nProfiles] = hLab;
|
||||
BPCList[nProfiles] = 0;
|
||||
AdaptationList[nProfiles] = 1.0;
|
||||
IntentList[nProfiles] = INTENT_RELATIVE_COLORIMETRIC;
|
||||
|
||||
// Create the transform
|
||||
xform = cmsCreateExtendedTransform(ContextID, nProfiles + 1, ProfileList,
|
||||
BPCList,
|
||||
IntentList,
|
||||
AdaptationList,
|
||||
NULL, 0,
|
||||
InputFormat,
|
||||
OutputFormat,
|
||||
dwFlags);
|
||||
|
||||
cmsCloseProfile(hLab);
|
||||
|
||||
return xform;
|
||||
}
|
||||
|
||||
|
||||
// Compute K -> L* relationship. Flags may include black point compensation. In this case,
|
||||
// the relationship is assumed from the profile with BPC to a black point zero.
|
||||
static
|
||||
cmsToneCurve* ComputeKToLstar(cmsContext ContextID,
|
||||
cmsUInt32Number nPoints,
|
||||
cmsUInt32Number nProfiles,
|
||||
const cmsUInt32Number Intents[],
|
||||
const cmsHPROFILE hProfiles[],
|
||||
const cmsBool BPC[],
|
||||
const cmsFloat64Number AdaptationStates[],
|
||||
cmsUInt32Number dwFlags)
|
||||
{
|
||||
cmsToneCurve* out = NULL;
|
||||
cmsUInt32Number i;
|
||||
cmsHTRANSFORM xform;
|
||||
cmsCIELab Lab;
|
||||
cmsFloat32Number cmyk[4];
|
||||
cmsFloat32Number* SampledPoints;
|
||||
|
||||
xform = _cmsChain2Lab(ContextID, nProfiles, TYPE_CMYK_FLT, TYPE_Lab_DBL, Intents, hProfiles, BPC, AdaptationStates, dwFlags);
|
||||
if (xform == NULL) return NULL;
|
||||
|
||||
SampledPoints = (cmsFloat32Number*) _cmsCalloc(ContextID, nPoints, sizeof(cmsFloat32Number));
|
||||
if (SampledPoints == NULL) goto Error;
|
||||
|
||||
for (i=0; i < nPoints; i++) {
|
||||
|
||||
cmyk[0] = 0;
|
||||
cmyk[1] = 0;
|
||||
cmyk[2] = 0;
|
||||
cmyk[3] = (cmsFloat32Number) ((i * 100.0) / (nPoints-1));
|
||||
|
||||
cmsDoTransform(xform, cmyk, &Lab, 1);
|
||||
SampledPoints[i]= (cmsFloat32Number) (1.0 - Lab.L / 100.0); // Negate K for easier operation
|
||||
}
|
||||
|
||||
out = cmsBuildTabulatedToneCurveFloat(ContextID, nPoints, SampledPoints);
|
||||
|
||||
Error:
|
||||
|
||||
cmsDeleteTransform(xform);
|
||||
if (SampledPoints) _cmsFree(ContextID, SampledPoints);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
// Compute Black tone curve on a CMYK -> CMYK transform. This is done by
|
||||
// using the proof direction on both profiles to find K->L* relationship
|
||||
// then joining both curves. dwFlags may include black point compensation.
|
||||
cmsToneCurve* _cmsBuildKToneCurve(cmsContext ContextID,
|
||||
cmsUInt32Number nPoints,
|
||||
cmsUInt32Number nProfiles,
|
||||
const cmsUInt32Number Intents[],
|
||||
const cmsHPROFILE hProfiles[],
|
||||
const cmsBool BPC[],
|
||||
const cmsFloat64Number AdaptationStates[],
|
||||
cmsUInt32Number dwFlags)
|
||||
{
|
||||
cmsToneCurve *in, *out, *KTone;
|
||||
|
||||
// Make sure CMYK -> CMYK
|
||||
if (cmsGetColorSpace(hProfiles[0]) != cmsSigCmykData ||
|
||||
cmsGetColorSpace(hProfiles[nProfiles-1])!= cmsSigCmykData) return NULL;
|
||||
|
||||
|
||||
// Make sure last is an output profile
|
||||
if (cmsGetDeviceClass(hProfiles[nProfiles - 1]) != cmsSigOutputClass) return NULL;
|
||||
|
||||
// Create individual curves. BPC works also as each K to L* is
|
||||
// computed as a BPC to zero black point in case of L*
|
||||
in = ComputeKToLstar(ContextID, nPoints, nProfiles - 1, Intents, hProfiles, BPC, AdaptationStates, dwFlags);
|
||||
if (in == NULL) return NULL;
|
||||
|
||||
out = ComputeKToLstar(ContextID, nPoints, 1,
|
||||
Intents + (nProfiles - 1),
|
||||
hProfiles + (nProfiles - 1),
|
||||
BPC + (nProfiles - 1),
|
||||
AdaptationStates + (nProfiles - 1),
|
||||
dwFlags);
|
||||
if (out == NULL) {
|
||||
cmsFreeToneCurve(in);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Build the relationship. This effectively limits the maximum accuracy to 16 bits, but
|
||||
// since this is used on black-preserving LUTs, we are not loosing accuracy in any case
|
||||
KTone = cmsJoinToneCurve(ContextID, in, out, nPoints);
|
||||
|
||||
// Get rid of components
|
||||
cmsFreeToneCurve(in); cmsFreeToneCurve(out);
|
||||
|
||||
// Something went wrong...
|
||||
if (KTone == NULL) return NULL;
|
||||
|
||||
// Make sure it is monotonic
|
||||
if (!cmsIsToneCurveMonotonic(KTone)) {
|
||||
|
||||
cmsFreeToneCurve(KTone);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return KTone;
|
||||
}
|
||||
|
||||
|
||||
// Gamut LUT Creation -----------------------------------------------------------------------------------------
|
||||
|
||||
// Used by gamut & softproofing
|
||||
|
||||
typedef struct {
|
||||
|
||||
cmsHTRANSFORM hInput; // From whatever input color space. 16 bits to DBL
|
||||
cmsHTRANSFORM hForward, hReverse; // Transforms going from Lab to colorant and back
|
||||
cmsFloat64Number Thereshold; // The thereshold after which is considered out of gamut
|
||||
|
||||
} GAMUTCHAIN;
|
||||
|
||||
// This sampler does compute gamut boundaries by comparing original
|
||||
// values with a transform going back and forth. Values above ERR_THERESHOLD
|
||||
// of maximum are considered out of gamut.
|
||||
|
||||
#define ERR_THERESHOLD 5
|
||||
|
||||
|
||||
static
|
||||
int GamutSampler(register const cmsUInt16Number In[], register cmsUInt16Number Out[], register void* Cargo)
|
||||
{
|
||||
GAMUTCHAIN* t = (GAMUTCHAIN* ) Cargo;
|
||||
cmsCIELab LabIn1, LabOut1;
|
||||
cmsCIELab LabIn2, LabOut2;
|
||||
cmsUInt16Number Proof[cmsMAXCHANNELS], Proof2[cmsMAXCHANNELS];
|
||||
cmsFloat64Number dE1, dE2, ErrorRatio;
|
||||
|
||||
// Assume in-gamut by default.
|
||||
dE1 = 0.;
|
||||
dE2 = 0;
|
||||
ErrorRatio = 1.0;
|
||||
|
||||
// Convert input to Lab
|
||||
if (t -> hInput != NULL)
|
||||
cmsDoTransform(t -> hInput, In, &LabIn1, 1);
|
||||
|
||||
// converts from PCS to colorant. This always
|
||||
// does return in-gamut values,
|
||||
cmsDoTransform(t -> hForward, &LabIn1, Proof, 1);
|
||||
|
||||
// Now, do the inverse, from colorant to PCS.
|
||||
cmsDoTransform(t -> hReverse, Proof, &LabOut1, 1);
|
||||
|
||||
memmove(&LabIn2, &LabOut1, sizeof(cmsCIELab));
|
||||
|
||||
// Try again, but this time taking Check as input
|
||||
cmsDoTransform(t -> hForward, &LabOut1, Proof2, 1);
|
||||
cmsDoTransform(t -> hReverse, Proof2, &LabOut2, 1);
|
||||
|
||||
// Take difference of direct value
|
||||
dE1 = cmsDeltaE(&LabIn1, &LabOut1);
|
||||
|
||||
// Take difference of converted value
|
||||
dE2 = cmsDeltaE(&LabIn2, &LabOut2);
|
||||
|
||||
|
||||
// if dE1 is small and dE2 is small, value is likely to be in gamut
|
||||
if (dE1 < t->Thereshold && dE2 < t->Thereshold)
|
||||
Out[0] = 0;
|
||||
else {
|
||||
|
||||
// if dE1 is small and dE2 is big, undefined. Assume in gamut
|
||||
if (dE1 < t->Thereshold && dE2 > t->Thereshold)
|
||||
Out[0] = 0;
|
||||
else
|
||||
// dE1 is big and dE2 is small, clearly out of gamut
|
||||
if (dE1 > t->Thereshold && dE2 < t->Thereshold)
|
||||
Out[0] = (cmsUInt16Number) _cmsQuickFloor((dE1 - t->Thereshold) + .5);
|
||||
else {
|
||||
|
||||
// dE1 is big and dE2 is also big, could be due to perceptual mapping
|
||||
// so take error ratio
|
||||
if (dE2 == 0.0)
|
||||
ErrorRatio = dE1;
|
||||
else
|
||||
ErrorRatio = dE1 / dE2;
|
||||
|
||||
if (ErrorRatio > t->Thereshold)
|
||||
Out[0] = (cmsUInt16Number) _cmsQuickFloor((ErrorRatio - t->Thereshold) + .5);
|
||||
else
|
||||
Out[0] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Does compute a gamut LUT going back and forth across pcs -> relativ. colorimetric intent -> pcs
|
||||
// the dE obtained is then annotated on the LUT. Values truely out of gamut are clipped to dE = 0xFFFE
|
||||
// and values changed are supposed to be handled by any gamut remapping, so, are out of gamut as well.
|
||||
//
|
||||
// **WARNING: This algorithm does assume that gamut remapping algorithms does NOT move in-gamut colors,
|
||||
// of course, many perceptual and saturation intents does not work in such way, but relativ. ones should.
|
||||
|
||||
cmsPipeline* _cmsCreateGamutCheckPipeline(cmsContext ContextID,
|
||||
cmsHPROFILE hProfiles[],
|
||||
cmsBool BPC[],
|
||||
cmsUInt32Number Intents[],
|
||||
cmsFloat64Number AdaptationStates[],
|
||||
cmsUInt32Number nGamutPCSposition,
|
||||
cmsHPROFILE hGamut)
|
||||
{
|
||||
cmsHPROFILE hLab;
|
||||
cmsPipeline* Gamut;
|
||||
cmsStage* CLUT;
|
||||
cmsUInt32Number dwFormat;
|
||||
GAMUTCHAIN Chain;
|
||||
int nChannels, nGridpoints;
|
||||
cmsColorSpaceSignature ColorSpace;
|
||||
cmsUInt32Number i;
|
||||
cmsHPROFILE ProfileList[256];
|
||||
cmsBool BPCList[256];
|
||||
cmsFloat64Number AdaptationList[256];
|
||||
cmsUInt32Number IntentList[256];
|
||||
|
||||
memset(&Chain, 0, sizeof(GAMUTCHAIN));
|
||||
|
||||
|
||||
if (nGamutPCSposition <= 0 || nGamutPCSposition > 255) {
|
||||
cmsSignalError(ContextID, cmsERROR_RANGE, "Wrong position of PCS. 1..255 expected, %d found.", nGamutPCSposition);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hLab = cmsCreateLab4ProfileTHR(ContextID, NULL);
|
||||
if (hLab == NULL) return NULL;
|
||||
|
||||
|
||||
// The figure of merit. On matrix-shaper profiles, should be almost zero as
|
||||
// the conversion is pretty exact. On LUT based profiles, different resolutions
|
||||
// of input and output CLUT may result in differences.
|
||||
|
||||
if (cmsIsMatrixShaper(hGamut)) {
|
||||
|
||||
Chain.Thereshold = 1.0;
|
||||
}
|
||||
else {
|
||||
Chain.Thereshold = ERR_THERESHOLD;
|
||||
}
|
||||
|
||||
|
||||
// Create a copy of parameters
|
||||
for (i=0; i < nGamutPCSposition; i++) {
|
||||
ProfileList[i] = hProfiles[i];
|
||||
BPCList[i] = BPC[i];
|
||||
AdaptationList[i] = AdaptationStates[i];
|
||||
IntentList[i] = Intents[i];
|
||||
}
|
||||
|
||||
// Fill Lab identity
|
||||
ProfileList[nGamutPCSposition] = hLab;
|
||||
BPCList[nGamutPCSposition] = 0;
|
||||
AdaptationList[nGamutPCSposition] = 1.0;
|
||||
Intents[nGamutPCSposition] = INTENT_RELATIVE_COLORIMETRIC;
|
||||
|
||||
|
||||
ColorSpace = cmsGetColorSpace(hGamut);
|
||||
|
||||
nChannels = cmsChannelsOf(ColorSpace);
|
||||
nGridpoints = _cmsReasonableGridpointsByColorspace(ColorSpace, cmsFLAGS_HIGHRESPRECALC);
|
||||
dwFormat = (CHANNELS_SH(nChannels)|BYTES_SH(2));
|
||||
|
||||
// 16 bits to Lab double
|
||||
Chain.hInput = cmsCreateExtendedTransform(ContextID,
|
||||
nGamutPCSposition + 1,
|
||||
ProfileList,
|
||||
BPCList,
|
||||
Intents,
|
||||
AdaptationList,
|
||||
NULL, 0,
|
||||
dwFormat, TYPE_Lab_DBL,
|
||||
cmsFLAGS_NOCACHE);
|
||||
|
||||
|
||||
// Does create the forward step. Lab double to device
|
||||
dwFormat = (CHANNELS_SH(nChannels)|BYTES_SH(2));
|
||||
Chain.hForward = cmsCreateTransformTHR(ContextID,
|
||||
hLab, TYPE_Lab_DBL,
|
||||
hGamut, dwFormat,
|
||||
INTENT_RELATIVE_COLORIMETRIC,
|
||||
cmsFLAGS_NOCACHE);
|
||||
|
||||
// Does create the backwards step
|
||||
Chain.hReverse = cmsCreateTransformTHR(ContextID, hGamut, dwFormat,
|
||||
hLab, TYPE_Lab_DBL,
|
||||
INTENT_RELATIVE_COLORIMETRIC,
|
||||
cmsFLAGS_NOCACHE);
|
||||
|
||||
|
||||
// All ok?
|
||||
if (Chain.hForward && Chain.hReverse) {
|
||||
|
||||
// Go on, try to compute gamut LUT from PCS. This consist on a single channel containing
|
||||
// dE when doing a transform back and forth on the colorimetric intent.
|
||||
|
||||
Gamut = cmsPipelineAlloc(ContextID, 3, 1);
|
||||
|
||||
if (Gamut != NULL) {
|
||||
|
||||
CLUT = cmsStageAllocCLut16bit(ContextID, nGridpoints, nChannels, 1, NULL);
|
||||
cmsPipelineInsertStage(Gamut, cmsAT_BEGIN, CLUT);
|
||||
|
||||
cmsStageSampleCLut16bit(CLUT, GamutSampler, (void*) &Chain, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
Gamut = NULL; // Didn't work...
|
||||
|
||||
// Free all needed stuff.
|
||||
if (Chain.hInput) cmsDeleteTransform(Chain.hInput);
|
||||
if (Chain.hForward) cmsDeleteTransform(Chain.hForward);
|
||||
if (Chain.hReverse) cmsDeleteTransform(Chain.hReverse);
|
||||
if (hLab) cmsCloseProfile(hLab);
|
||||
|
||||
// And return computed hull
|
||||
return Gamut;
|
||||
}
|
||||
|
||||
// Total Area Coverage estimation ----------------------------------------------------------------
|
||||
|
||||
typedef struct {
|
||||
cmsUInt32Number nOutputChans;
|
||||
cmsHTRANSFORM hRoundTrip;
|
||||
cmsFloat32Number MaxTAC;
|
||||
cmsFloat32Number MaxInput[cmsMAXCHANNELS];
|
||||
|
||||
} cmsTACestimator;
|
||||
|
||||
|
||||
// This callback just accounts the maximum ink dropped in the given node. It does not populate any
|
||||
// memory, as the destination table is NULL. Its only purpose it to know the global maximum.
|
||||
static
|
||||
int EstimateTAC(register const cmsUInt16Number In[], register cmsUInt16Number Out[], register void * Cargo)
|
||||
{
|
||||
cmsTACestimator* bp = (cmsTACestimator*) Cargo;
|
||||
cmsFloat32Number RoundTrip[cmsMAXCHANNELS];
|
||||
cmsUInt32Number i;
|
||||
cmsFloat32Number Sum;
|
||||
|
||||
|
||||
// Evaluate the xform
|
||||
cmsDoTransform(bp->hRoundTrip, In, RoundTrip, 1);
|
||||
|
||||
// All all amounts of ink
|
||||
for (Sum=0, i=0; i < bp ->nOutputChans; i++)
|
||||
Sum += RoundTrip[i];
|
||||
|
||||
// If above maximum, keep track of input values
|
||||
if (Sum > bp ->MaxTAC) {
|
||||
|
||||
bp ->MaxTAC = Sum;
|
||||
|
||||
for (i=0; i < bp ->nOutputChans; i++) {
|
||||
bp ->MaxInput[i] = In[i];
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
cmsUNUSED_PARAMETER(Out);
|
||||
}
|
||||
|
||||
|
||||
// Detect Total area coverage of the profile
|
||||
cmsFloat64Number CMSEXPORT cmsDetectTAC(cmsHPROFILE hProfile)
|
||||
{
|
||||
cmsTACestimator bp;
|
||||
cmsUInt32Number dwFormatter;
|
||||
cmsUInt32Number GridPoints[MAX_INPUT_DIMENSIONS];
|
||||
cmsHPROFILE hLab;
|
||||
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
||||
|
||||
// TAC only works on output profiles
|
||||
if (cmsGetDeviceClass(hProfile) != cmsSigOutputClass) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Create a fake formatter for result
|
||||
dwFormatter = cmsFormatterForColorspaceOfProfile(hProfile, 4, TRUE);
|
||||
|
||||
bp.nOutputChans = T_CHANNELS(dwFormatter);
|
||||
bp.MaxTAC = 0; // Initial TAC is 0
|
||||
|
||||
// for safety
|
||||
if (bp.nOutputChans >= cmsMAXCHANNELS) return 0;
|
||||
|
||||
hLab = cmsCreateLab4ProfileTHR(ContextID, NULL);
|
||||
if (hLab == NULL) return 0;
|
||||
// Setup a roundtrip on perceptual intent in output profile for TAC estimation
|
||||
bp.hRoundTrip = cmsCreateTransformTHR(ContextID, hLab, TYPE_Lab_16,
|
||||
hProfile, dwFormatter, INTENT_PERCEPTUAL, cmsFLAGS_NOOPTIMIZE|cmsFLAGS_NOCACHE);
|
||||
|
||||
cmsCloseProfile(hLab);
|
||||
if (bp.hRoundTrip == NULL) return 0;
|
||||
|
||||
// For L* we only need black and white. For C* we need many points
|
||||
GridPoints[0] = 6;
|
||||
GridPoints[1] = 74;
|
||||
GridPoints[2] = 74;
|
||||
|
||||
|
||||
if (!cmsSliceSpace16(3, GridPoints, EstimateTAC, &bp)) {
|
||||
bp.MaxTAC = 0;
|
||||
}
|
||||
|
||||
cmsDeleteTransform(bp.hRoundTrip);
|
||||
|
||||
// Results in %
|
||||
return bp.MaxTAC;
|
||||
}
|
||||
|
||||
|
||||
// Carefully, clamp on CIELab space.
|
||||
|
||||
cmsBool CMSEXPORT cmsDesaturateLab(cmsCIELab* Lab,
|
||||
double amax, double amin,
|
||||
double bmax, double bmin)
|
||||
{
|
||||
|
||||
// Whole Luma surface to zero
|
||||
|
||||
if (Lab -> L < 0) {
|
||||
|
||||
Lab-> L = Lab->a = Lab-> b = 0.0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Clamp white, DISCARD HIGHLIGHTS. This is done
|
||||
// in such way because icc spec doesn't allow the
|
||||
// use of L>100 as a highlight means.
|
||||
|
||||
if (Lab->L > 100)
|
||||
Lab -> L = 100;
|
||||
|
||||
// Check out gamut prism, on a, b faces
|
||||
|
||||
if (Lab -> a < amin || Lab->a > amax||
|
||||
Lab -> b < bmin || Lab->b > bmax) {
|
||||
|
||||
cmsCIELCh LCh;
|
||||
double h, slope;
|
||||
|
||||
// Falls outside a, b limits. Transports to LCh space,
|
||||
// and then do the clipping
|
||||
|
||||
|
||||
if (Lab -> a == 0.0) { // Is hue exactly 90?
|
||||
|
||||
// atan will not work, so clamp here
|
||||
Lab -> b = Lab->b < 0 ? bmin : bmax;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
cmsLab2LCh(&LCh, Lab);
|
||||
|
||||
slope = Lab -> b / Lab -> a;
|
||||
h = LCh.h;
|
||||
|
||||
// There are 4 zones
|
||||
|
||||
if ((h >= 0. && h < 45.) ||
|
||||
(h >= 315 && h <= 360.)) {
|
||||
|
||||
// clip by amax
|
||||
Lab -> a = amax;
|
||||
Lab -> b = amax * slope;
|
||||
}
|
||||
else
|
||||
if (h >= 45. && h < 135.)
|
||||
{
|
||||
// clip by bmax
|
||||
Lab -> b = bmax;
|
||||
Lab -> a = bmax / slope;
|
||||
}
|
||||
else
|
||||
if (h >= 135. && h < 225.) {
|
||||
// clip by amin
|
||||
Lab -> a = amin;
|
||||
Lab -> b = amin * slope;
|
||||
|
||||
}
|
||||
else
|
||||
if (h >= 225. && h < 315.) {
|
||||
// clip by bmin
|
||||
Lab -> b = bmin;
|
||||
Lab -> a = bmin / slope;
|
||||
}
|
||||
else {
|
||||
cmsSignalError(0, cmsERROR_RANGE, "Invalid angle");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
1463
thirdparty/liblcms2/src/cmsintrp.c
vendored
Normal file
1463
thirdparty/liblcms2/src/cmsintrp.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1720
thirdparty/liblcms2/src/cmsio0.c
vendored
Normal file
1720
thirdparty/liblcms2/src/cmsio0.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
760
thirdparty/liblcms2/src/cmsio1.c
vendored
Normal file
760
thirdparty/liblcms2/src/cmsio1.c
vendored
Normal file
@ -0,0 +1,760 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
//
|
||||
// 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 "lcms2_internal.h"
|
||||
|
||||
// Read tags using low-level functions, provides necessary glue code to adapt versions, etc.
|
||||
|
||||
// LUT tags
|
||||
static const cmsTagSignature Device2PCS16[] = {cmsSigAToB0Tag, // Perceptual
|
||||
cmsSigAToB1Tag, // Relative colorimetric
|
||||
cmsSigAToB2Tag, // Saturation
|
||||
cmsSigAToB1Tag }; // Absolute colorimetric
|
||||
|
||||
static const cmsTagSignature Device2PCSFloat[] = {cmsSigDToB0Tag, // Perceptual
|
||||
cmsSigDToB1Tag, // Relative colorimetric
|
||||
cmsSigDToB2Tag, // Saturation
|
||||
cmsSigDToB3Tag }; // Absolute colorimetric
|
||||
|
||||
static const cmsTagSignature PCS2Device16[] = {cmsSigBToA0Tag, // Perceptual
|
||||
cmsSigBToA1Tag, // Relative colorimetric
|
||||
cmsSigBToA2Tag, // Saturation
|
||||
cmsSigBToA1Tag }; // Absolute colorimetric
|
||||
|
||||
static const cmsTagSignature PCS2DeviceFloat[] = {cmsSigBToD0Tag, // Perceptual
|
||||
cmsSigBToD1Tag, // Relative colorimetric
|
||||
cmsSigBToD2Tag, // Saturation
|
||||
cmsSigBToD3Tag }; // Absolute colorimetric
|
||||
|
||||
|
||||
// Factors to convert from 1.15 fixed point to 0..1.0 range and vice-versa
|
||||
#define InpAdj (1.0/MAX_ENCODEABLE_XYZ) // (65536.0/(65535.0*2.0))
|
||||
#define OutpAdj (MAX_ENCODEABLE_XYZ) // ((2.0*65535.0)/65536.0)
|
||||
|
||||
// Several resources for gray conversions.
|
||||
static const cmsFloat64Number GrayInputMatrix[] = { (InpAdj*cmsD50X), (InpAdj*cmsD50Y), (InpAdj*cmsD50Z) };
|
||||
static const cmsFloat64Number OneToThreeInputMatrix[] = { 1, 1, 1 };
|
||||
static const cmsFloat64Number PickYMatrix[] = { 0, (OutpAdj*cmsD50Y), 0 };
|
||||
static const cmsFloat64Number PickLstarMatrix[] = { 1, 0, 0 };
|
||||
|
||||
// Get a media white point fixing some issues found in certain old profiles
|
||||
cmsBool _cmsReadMediaWhitePoint(cmsCIEXYZ* Dest, cmsHPROFILE hProfile)
|
||||
{
|
||||
cmsCIEXYZ* Tag;
|
||||
|
||||
_cmsAssert(Dest != NULL);
|
||||
|
||||
Tag = (cmsCIEXYZ*) cmsReadTag(hProfile, cmsSigMediaWhitePointTag);
|
||||
|
||||
// If no wp, take D50
|
||||
if (Tag == NULL) {
|
||||
*Dest = *cmsD50_XYZ();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// V2 display profiles should give D50
|
||||
if (cmsGetEncodedICCversion(hProfile) < 0x4000000) {
|
||||
|
||||
if (cmsGetDeviceClass(hProfile) == cmsSigDisplayClass) {
|
||||
*Dest = *cmsD50_XYZ();
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// All seems ok
|
||||
*Dest = *Tag;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Chromatic adaptation matrix. Fix some issues as well
|
||||
cmsBool _cmsReadCHAD(cmsMAT3* Dest, cmsHPROFILE hProfile)
|
||||
{
|
||||
cmsMAT3* Tag;
|
||||
|
||||
_cmsAssert(Dest != NULL);
|
||||
|
||||
Tag = (cmsMAT3*) cmsReadTag(hProfile, cmsSigChromaticAdaptationTag);
|
||||
|
||||
if (Tag != NULL) {
|
||||
|
||||
*Dest = *Tag;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// No CHAD available, default it to identity
|
||||
_cmsMAT3identity(Dest);
|
||||
|
||||
// V2 display profiles should give D50
|
||||
if (cmsGetEncodedICCversion(hProfile) < 0x4000000) {
|
||||
|
||||
if (cmsGetDeviceClass(hProfile) == cmsSigDisplayClass) {
|
||||
|
||||
cmsCIEXYZ* White = (cmsCIEXYZ*) cmsReadTag(hProfile, cmsSigMediaWhitePointTag);
|
||||
|
||||
if (White == NULL) {
|
||||
|
||||
_cmsMAT3identity(Dest);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return _cmsAdaptationMatrix(Dest, NULL, cmsD50_XYZ(), White);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Auxiliar, read colorants as a MAT3 structure. Used by any function that needs a matrix-shaper
|
||||
static
|
||||
cmsBool ReadICCMatrixRGB2XYZ(cmsMAT3* r, cmsHPROFILE hProfile)
|
||||
{
|
||||
cmsCIEXYZ *PtrRed, *PtrGreen, *PtrBlue;
|
||||
|
||||
_cmsAssert(r != NULL);
|
||||
|
||||
PtrRed = (cmsCIEXYZ *) cmsReadTag(hProfile, cmsSigRedColorantTag);
|
||||
PtrGreen = (cmsCIEXYZ *) cmsReadTag(hProfile, cmsSigGreenColorantTag);
|
||||
PtrBlue = (cmsCIEXYZ *) cmsReadTag(hProfile, cmsSigBlueColorantTag);
|
||||
|
||||
if (PtrRed == NULL || PtrGreen == NULL || PtrBlue == NULL)
|
||||
return FALSE;
|
||||
|
||||
_cmsVEC3init(&r -> v[0], PtrRed -> X, PtrGreen -> X, PtrBlue -> X);
|
||||
_cmsVEC3init(&r -> v[1], PtrRed -> Y, PtrGreen -> Y, PtrBlue -> Y);
|
||||
_cmsVEC3init(&r -> v[2], PtrRed -> Z, PtrGreen -> Z, PtrBlue -> Z);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Gray input pipeline
|
||||
static
|
||||
cmsPipeline* BuildGrayInputMatrixPipeline(cmsHPROFILE hProfile)
|
||||
{
|
||||
cmsToneCurve *GrayTRC;
|
||||
cmsPipeline* Lut;
|
||||
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
||||
|
||||
GrayTRC = (cmsToneCurve *) cmsReadTag(hProfile, cmsSigGrayTRCTag);
|
||||
if (GrayTRC == NULL) return NULL;
|
||||
|
||||
Lut = cmsPipelineAlloc(ContextID, 1, 3);
|
||||
if (Lut == NULL) return NULL;
|
||||
|
||||
if (cmsGetPCS(hProfile) == cmsSigLabData) {
|
||||
|
||||
// In this case we implement the profile as an identity matrix plus 3 tone curves
|
||||
cmsUInt16Number Zero[2] = { 0x8080, 0x8080 };
|
||||
cmsToneCurve* EmptyTab;
|
||||
cmsToneCurve* LabCurves[3];
|
||||
|
||||
EmptyTab = cmsBuildTabulatedToneCurve16(ContextID, 2, Zero);
|
||||
|
||||
if (EmptyTab == NULL) {
|
||||
|
||||
cmsPipelineFree(Lut);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LabCurves[0] = GrayTRC;
|
||||
LabCurves[1] = EmptyTab;
|
||||
LabCurves[2] = EmptyTab;
|
||||
|
||||
cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 3, 1, OneToThreeInputMatrix, NULL));
|
||||
cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 3, LabCurves));
|
||||
|
||||
cmsFreeToneCurve(EmptyTab);
|
||||
|
||||
}
|
||||
else {
|
||||
cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 1, &GrayTRC));
|
||||
cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 3, 1, GrayInputMatrix, NULL));
|
||||
}
|
||||
|
||||
return Lut;
|
||||
}
|
||||
|
||||
// RGB Matrix shaper
|
||||
static
|
||||
cmsPipeline* BuildRGBInputMatrixShaper(cmsHPROFILE hProfile)
|
||||
{
|
||||
cmsPipeline* Lut;
|
||||
cmsMAT3 Mat;
|
||||
cmsToneCurve *Shapes[3];
|
||||
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
||||
int i, j;
|
||||
|
||||
if (!ReadICCMatrixRGB2XYZ(&Mat, hProfile)) return NULL;
|
||||
|
||||
// XYZ PCS in encoded in 1.15 format, and the matrix output comes in 0..0xffff range, so
|
||||
// we need to adjust the output by a factor of (0x10000/0xffff) to put data in
|
||||
// a 1.16 range, and then a >> 1 to obtain 1.15. The total factor is (65536.0)/(65535.0*2)
|
||||
|
||||
for (i=0; i < 3; i++)
|
||||
for (j=0; j < 3; j++)
|
||||
Mat.v[i].n[j] *= InpAdj;
|
||||
|
||||
|
||||
Shapes[0] = (cmsToneCurve *) cmsReadTag(hProfile, cmsSigRedTRCTag);
|
||||
Shapes[1] = (cmsToneCurve *) cmsReadTag(hProfile, cmsSigGreenTRCTag);
|
||||
Shapes[2] = (cmsToneCurve *) cmsReadTag(hProfile, cmsSigBlueTRCTag);
|
||||
|
||||
if (!Shapes[0] || !Shapes[1] || !Shapes[2])
|
||||
return NULL;
|
||||
|
||||
Lut = cmsPipelineAlloc(ContextID, 3, 3);
|
||||
if (Lut != NULL) {
|
||||
|
||||
cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 3, Shapes));
|
||||
cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 3, 3, (cmsFloat64Number*) &Mat, NULL));
|
||||
}
|
||||
|
||||
return Lut;
|
||||
}
|
||||
|
||||
// Read and create a BRAND NEW MPE LUT from a given profile. All stuff dependent of version, etc
|
||||
// is adjusted here in order to create a LUT that takes care of all those details
|
||||
cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent)
|
||||
{
|
||||
cmsTagTypeSignature OriginalType;
|
||||
cmsTagSignature tag16 = Device2PCS16[Intent];
|
||||
cmsTagSignature tagFloat = Device2PCSFloat[Intent];
|
||||
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
||||
|
||||
if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
|
||||
|
||||
// Floating point LUT are always V4, so no adjustment is required
|
||||
return cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat));
|
||||
}
|
||||
|
||||
// Revert to perceptual if no tag is found
|
||||
if (!cmsIsTag(hProfile, tag16)) {
|
||||
tag16 = Device2PCS16[0];
|
||||
}
|
||||
|
||||
if (cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table?
|
||||
|
||||
// Check profile version and LUT type. Do the necessary adjustments if needed
|
||||
|
||||
// First read the tag
|
||||
cmsPipeline* Lut = (cmsPipeline*) cmsReadTag(hProfile, tag16);
|
||||
if (Lut == NULL) return NULL;
|
||||
|
||||
// After reading it, we have now info about the original type
|
||||
OriginalType = _cmsGetTagTrueType(hProfile, tag16);
|
||||
|
||||
// The profile owns the Lut, so we need to copy it
|
||||
Lut = cmsPipelineDup(Lut);
|
||||
|
||||
// We need to adjust data only for Lab16 on output
|
||||
if (OriginalType != cmsSigLut16Type || cmsGetPCS(hProfile) != cmsSigLabData)
|
||||
return Lut;
|
||||
|
||||
// Add a matrix for conversion V2 to V4 Lab PCS
|
||||
cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID));
|
||||
return Lut;
|
||||
}
|
||||
|
||||
// Lut was not found, try to create a matrix-shaper
|
||||
|
||||
// Check if this is a grayscale profile.
|
||||
if (cmsGetColorSpace(hProfile) == cmsSigGrayData) {
|
||||
|
||||
// if so, build appropiate conversion tables.
|
||||
// The tables are the PCS iluminant, scaled across GrayTRC
|
||||
return BuildGrayInputMatrixPipeline(hProfile);
|
||||
}
|
||||
|
||||
// Not gray, create a normal matrix-shaper
|
||||
return BuildRGBInputMatrixShaper(hProfile);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Gray output pipeline.
|
||||
// XYZ -> Gray or Lab -> Gray. Since we only know the GrayTRC, we need to do some assumptions. Gray component will be
|
||||
// given by Y on XYZ PCS and by L* on Lab PCS, Both across inverse TRC curve.
|
||||
// The complete pipeline on XYZ is Matrix[3:1] -> Tone curve and in Lab Matrix[3:1] -> Tone Curve as well.
|
||||
|
||||
static
|
||||
cmsPipeline* BuildGrayOutputPipeline(cmsHPROFILE hProfile)
|
||||
{
|
||||
cmsToneCurve *GrayTRC, *RevGrayTRC;
|
||||
cmsPipeline* Lut;
|
||||
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
||||
|
||||
GrayTRC = (cmsToneCurve *) cmsReadTag(hProfile, cmsSigGrayTRCTag);
|
||||
if (GrayTRC == NULL) return NULL;
|
||||
|
||||
RevGrayTRC = cmsReverseToneCurve(GrayTRC);
|
||||
if (RevGrayTRC == NULL) return NULL;
|
||||
|
||||
Lut = cmsPipelineAlloc(ContextID, 3, 1);
|
||||
if (Lut == NULL) {
|
||||
cmsFreeToneCurve(RevGrayTRC);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (cmsGetPCS(hProfile) == cmsSigLabData) {
|
||||
|
||||
cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 1, 3, PickLstarMatrix, NULL));
|
||||
}
|
||||
else {
|
||||
cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 1, 3, PickYMatrix, NULL));
|
||||
}
|
||||
|
||||
cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 1, &RevGrayTRC));
|
||||
cmsFreeToneCurve(RevGrayTRC);
|
||||
|
||||
return Lut;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static
|
||||
cmsPipeline* BuildRGBOutputMatrixShaper(cmsHPROFILE hProfile)
|
||||
{
|
||||
cmsPipeline* Lut;
|
||||
cmsToneCurve *Shapes[3], *InvShapes[3];
|
||||
cmsMAT3 Mat, Inv;
|
||||
int i, j;
|
||||
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
||||
|
||||
if (!ReadICCMatrixRGB2XYZ(&Mat, hProfile))
|
||||
return NULL;
|
||||
|
||||
if (!_cmsMAT3inverse(&Mat, &Inv))
|
||||
return NULL;
|
||||
|
||||
// XYZ PCS in encoded in 1.15 format, and the matrix input should come in 0..0xffff range, so
|
||||
// we need to adjust the input by a << 1 to obtain a 1.16 fixed and then by a factor of
|
||||
// (0xffff/0x10000) to put data in 0..0xffff range. Total factor is (2.0*65535.0)/65536.0;
|
||||
|
||||
for (i=0; i < 3; i++)
|
||||
for (j=0; j < 3; j++)
|
||||
Inv.v[i].n[j] *= OutpAdj;
|
||||
|
||||
Shapes[0] = (cmsToneCurve *) cmsReadTag(hProfile, cmsSigRedTRCTag);
|
||||
Shapes[1] = (cmsToneCurve *) cmsReadTag(hProfile, cmsSigGreenTRCTag);
|
||||
Shapes[2] = (cmsToneCurve *) cmsReadTag(hProfile, cmsSigBlueTRCTag);
|
||||
|
||||
if (!Shapes[0] || !Shapes[1] || !Shapes[2])
|
||||
return NULL;
|
||||
|
||||
InvShapes[0] = cmsReverseToneCurve(Shapes[0]);
|
||||
InvShapes[1] = cmsReverseToneCurve(Shapes[1]);
|
||||
InvShapes[2] = cmsReverseToneCurve(Shapes[2]);
|
||||
|
||||
if (!InvShapes[0] || !InvShapes[1] || !InvShapes[2]) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Lut = cmsPipelineAlloc(ContextID, 3, 3);
|
||||
if (Lut != NULL) {
|
||||
|
||||
cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 3, 3, (cmsFloat64Number*) &Inv, NULL));
|
||||
cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 3, InvShapes));
|
||||
}
|
||||
|
||||
cmsFreeToneCurveTriple(InvShapes);
|
||||
return Lut;
|
||||
}
|
||||
|
||||
|
||||
// Change CLUT interpolation to trilinear
|
||||
static
|
||||
void ChangeInterpolationToTrilinear(cmsPipeline* Lut)
|
||||
{
|
||||
cmsStage* Stage;
|
||||
|
||||
for (Stage = cmsPipelineGetPtrToFirstStage(Lut);
|
||||
Stage != NULL;
|
||||
Stage = cmsStageNext(Stage)) {
|
||||
|
||||
if (cmsStageType(Stage) == cmsSigCLutElemType) {
|
||||
|
||||
_cmsStageCLutData* CLUT = (_cmsStageCLutData*) Stage ->Data;
|
||||
|
||||
CLUT ->Params->dwFlags |= CMS_LERP_FLAGS_TRILINEAR;
|
||||
_cmsSetInterpolationRoutine(CLUT ->Params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create an output MPE LUT from agiven profile. Version mismatches are handled here
|
||||
cmsPipeline* _cmsReadOutputLUT(cmsHPROFILE hProfile, int Intent)
|
||||
{
|
||||
cmsTagTypeSignature OriginalType;
|
||||
cmsTagSignature tag16 = PCS2Device16[Intent];
|
||||
cmsTagSignature tagFloat = PCS2DeviceFloat[Intent];
|
||||
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
||||
|
||||
if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
|
||||
|
||||
// Floating point LUT are always V4, so no adjustment is required
|
||||
return cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat));
|
||||
}
|
||||
|
||||
// Revert to perceptual if no tag is found
|
||||
if (!cmsIsTag(hProfile, tag16)) {
|
||||
tag16 = PCS2Device16[0];
|
||||
}
|
||||
|
||||
if (cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table?
|
||||
|
||||
// Check profile version and LUT type. Do the necessary adjustments if needed
|
||||
|
||||
// First read the tag
|
||||
cmsPipeline* Lut = (cmsPipeline*) cmsReadTag(hProfile, tag16);
|
||||
if (Lut == NULL) return NULL;
|
||||
|
||||
// After reading it, we have info about the original type
|
||||
OriginalType = _cmsGetTagTrueType(hProfile, tag16);
|
||||
|
||||
// The profile owns the Lut, so we need to copy it
|
||||
Lut = cmsPipelineDup(Lut);
|
||||
if (Lut == NULL) return NULL;
|
||||
|
||||
// Now it is time for a controversial stuff. I found that for 3D LUTS using
|
||||
// Lab used as indexer space, trilinear interpolation should be used
|
||||
if (cmsGetPCS(hProfile) == cmsSigLabData)
|
||||
ChangeInterpolationToTrilinear(Lut);
|
||||
|
||||
// We need to adjust data only for Lab and Lut16 type
|
||||
if (OriginalType != cmsSigLut16Type || cmsGetPCS(hProfile) != cmsSigLabData)
|
||||
return Lut;
|
||||
|
||||
// Add a matrix for conversion V4 to V2 Lab PCS
|
||||
cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID));
|
||||
return Lut;
|
||||
}
|
||||
|
||||
// Lut not found, try to create a matrix-shaper
|
||||
|
||||
// Check if this is a grayscale profile.
|
||||
if (cmsGetColorSpace(hProfile) == cmsSigGrayData) {
|
||||
|
||||
// if so, build appropiate conversion tables.
|
||||
// The tables are the PCS iluminant, scaled across GrayTRC
|
||||
return BuildGrayOutputPipeline(hProfile);
|
||||
}
|
||||
|
||||
// Not gray, create a normal matrix-shaper
|
||||
return BuildRGBOutputMatrixShaper(hProfile);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// This one includes abstract profiles as well. Matrix-shaper cannot be obtained on that device class. The
|
||||
// tag name here may default to AToB0
|
||||
cmsPipeline* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent)
|
||||
{
|
||||
cmsPipeline* Lut;
|
||||
cmsTagTypeSignature OriginalType;
|
||||
cmsTagSignature tag16 = Device2PCS16[Intent];
|
||||
cmsTagSignature tagFloat = Device2PCSFloat[Intent];
|
||||
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
||||
|
||||
if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
|
||||
|
||||
// Floating point LUT are always V4, no adjustment is required
|
||||
return cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat));
|
||||
}
|
||||
|
||||
tagFloat = Device2PCSFloat[0];
|
||||
if (cmsIsTag(hProfile, tagFloat)) {
|
||||
|
||||
return cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat));
|
||||
}
|
||||
|
||||
if (!cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table?
|
||||
|
||||
tag16 = Device2PCS16[0];
|
||||
if (!cmsIsTag(hProfile, tag16)) return NULL;
|
||||
}
|
||||
|
||||
// Check profile version and LUT type. Do the necessary adjustments if needed
|
||||
|
||||
// Read the tag
|
||||
Lut = (cmsPipeline*) cmsReadTag(hProfile, tag16);
|
||||
if (Lut == NULL) return NULL;
|
||||
|
||||
// The profile owns the Lut, so we need to copy it
|
||||
Lut = cmsPipelineDup(Lut);
|
||||
if (Lut == NULL) return NULL;
|
||||
|
||||
// Now it is time for a controversial stuff. I found that for 3D LUTS using
|
||||
// Lab used as indexer space, trilinear interpolation should be used
|
||||
if (cmsGetColorSpace(hProfile) == cmsSigLabData)
|
||||
ChangeInterpolationToTrilinear(Lut);
|
||||
|
||||
// After reading it, we have info about the original type
|
||||
OriginalType = _cmsGetTagTrueType(hProfile, tag16);
|
||||
|
||||
// We need to adjust data for Lab16 on output
|
||||
if (OriginalType != cmsSigLut16Type) return Lut;
|
||||
|
||||
// Here it is possible to get Lab on both sides
|
||||
|
||||
if (cmsGetPCS(hProfile) == cmsSigLabData) {
|
||||
cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID));
|
||||
}
|
||||
|
||||
if (cmsGetColorSpace(hProfile) == cmsSigLabData) {
|
||||
cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID));
|
||||
}
|
||||
|
||||
return Lut;
|
||||
|
||||
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Returns TRUE if the profile is implemented as matrix-shaper
|
||||
cmsBool CMSEXPORT cmsIsMatrixShaper(cmsHPROFILE hProfile)
|
||||
{
|
||||
switch (cmsGetColorSpace(hProfile)) {
|
||||
|
||||
case cmsSigGrayData:
|
||||
|
||||
return cmsIsTag(hProfile, cmsSigGrayTRCTag);
|
||||
|
||||
case cmsSigRgbData:
|
||||
|
||||
return (cmsIsTag(hProfile, cmsSigRedColorantTag) &&
|
||||
cmsIsTag(hProfile, cmsSigGreenColorantTag) &&
|
||||
cmsIsTag(hProfile, cmsSigBlueColorantTag) &&
|
||||
cmsIsTag(hProfile, cmsSigRedTRCTag) &&
|
||||
cmsIsTag(hProfile, cmsSigGreenTRCTag) &&
|
||||
cmsIsTag(hProfile, cmsSigBlueTRCTag));
|
||||
|
||||
default:
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns TRUE if the intent is implemented as CLUT
|
||||
cmsBool CMSEXPORT cmsIsCLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number UsedDirection)
|
||||
{
|
||||
const cmsTagSignature* TagTable;
|
||||
|
||||
// For devicelinks, the supported intent is that one stated in the header
|
||||
if (cmsGetDeviceClass(hProfile) == cmsSigLinkClass) {
|
||||
return (cmsGetHeaderRenderingIntent(hProfile) == Intent);
|
||||
}
|
||||
|
||||
switch (UsedDirection) {
|
||||
|
||||
case LCMS_USED_AS_INPUT: TagTable = Device2PCS16; break;
|
||||
case LCMS_USED_AS_OUTPUT:TagTable = PCS2Device16; break;
|
||||
|
||||
// For proofing, we need rel. colorimetric in output. Let's do some recursion
|
||||
case LCMS_USED_AS_PROOF:
|
||||
return cmsIsIntentSupported(hProfile, Intent, LCMS_USED_AS_INPUT) &&
|
||||
cmsIsIntentSupported(hProfile, INTENT_RELATIVE_COLORIMETRIC, LCMS_USED_AS_OUTPUT);
|
||||
|
||||
default:
|
||||
cmsSignalError(cmsGetProfileContextID(hProfile), cmsERROR_RANGE, "Unexpected direction (%d)", UsedDirection);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return cmsIsTag(hProfile, TagTable[Intent]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Return info about supported intents
|
||||
cmsBool CMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile,
|
||||
cmsUInt32Number Intent, cmsUInt32Number UsedDirection)
|
||||
{
|
||||
|
||||
if (cmsIsCLUT(hProfile, Intent, UsedDirection)) return TRUE;
|
||||
|
||||
// Is there any matrix-shaper? If so, the intent is supported. This is a bit odd, since V2 matrix shaper
|
||||
// does not fully support relative colorimetric because they cannot deal with non-zero black points, but
|
||||
// many profiles claims that, and this is certainly not true for V4 profiles. Lets answer "yes" no matter
|
||||
// the accuracy would be less than optimal in rel.col and v2 case.
|
||||
|
||||
return cmsIsMatrixShaper(hProfile);
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Read both, profile sequence description and profile sequence id if present. Then combine both to
|
||||
// create qa unique structure holding both. Shame on ICC to store things in such complicated way.
|
||||
|
||||
cmsSEQ* _cmsReadProfileSequence(cmsHPROFILE hProfile)
|
||||
{
|
||||
cmsSEQ* ProfileSeq;
|
||||
cmsSEQ* ProfileId;
|
||||
cmsSEQ* NewSeq;
|
||||
cmsUInt32Number i;
|
||||
|
||||
// Take profile sequence description first
|
||||
ProfileSeq = (cmsSEQ*) cmsReadTag(hProfile, cmsSigProfileSequenceDescTag);
|
||||
|
||||
// Take profile sequence ID
|
||||
ProfileId = (cmsSEQ*) cmsReadTag(hProfile, cmsSigProfileSequenceIdTag);
|
||||
|
||||
if (ProfileSeq == NULL && ProfileId == NULL) return NULL;
|
||||
|
||||
if (ProfileSeq == NULL) return cmsDupProfileSequenceDescription(ProfileId);
|
||||
if (ProfileId == NULL) return cmsDupProfileSequenceDescription(ProfileSeq);
|
||||
|
||||
// We have to mix both together. For that they must agree
|
||||
if (ProfileSeq ->n != ProfileId ->n) return cmsDupProfileSequenceDescription(ProfileSeq);
|
||||
|
||||
NewSeq = cmsDupProfileSequenceDescription(ProfileSeq);
|
||||
|
||||
// Ok, proceed to the mixing
|
||||
for (i=0; i < ProfileSeq ->n; i++) {
|
||||
|
||||
memmove(&NewSeq ->seq[i].ProfileID, &ProfileId ->seq[i].ProfileID, sizeof(cmsProfileID));
|
||||
NewSeq ->seq[i].Description = cmsMLUdup(ProfileId ->seq[i].Description);
|
||||
}
|
||||
|
||||
return NewSeq;
|
||||
}
|
||||
|
||||
// Dump the contents of profile sequence in both tags (if v4 available)
|
||||
cmsBool _cmsWriteProfileSequence(cmsHPROFILE hProfile, const cmsSEQ* seq)
|
||||
{
|
||||
if (!cmsWriteTag(hProfile, cmsSigProfileSequenceDescTag, seq)) return FALSE;
|
||||
|
||||
if (cmsGetProfileVersion(hProfile) >= 4.0) {
|
||||
|
||||
if (!cmsWriteTag(hProfile, cmsSigProfileSequenceIdTag, seq)) return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Auxiliar, read and duplicate a MLU if found.
|
||||
static
|
||||
cmsMLU* GetMLUFromProfile(cmsHPROFILE h, cmsTagSignature sig)
|
||||
{
|
||||
cmsMLU* mlu = (cmsMLU*) cmsReadTag(h, sig);
|
||||
if (mlu == NULL) return NULL;
|
||||
|
||||
return cmsMLUdup(mlu);
|
||||
}
|
||||
|
||||
// Create a sequence description out of an array of profiles
|
||||
cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[])
|
||||
{
|
||||
cmsUInt32Number i;
|
||||
cmsSEQ* seq = cmsAllocProfileSequenceDescription(ContextID, nProfiles);
|
||||
|
||||
if (seq == NULL) return NULL;
|
||||
|
||||
for (i=0; i < nProfiles; i++) {
|
||||
|
||||
cmsPSEQDESC* ps = &seq ->seq[i];
|
||||
cmsHPROFILE h = hProfiles[i];
|
||||
cmsTechnologySignature* techpt;
|
||||
|
||||
cmsGetHeaderAttributes(h, &ps ->attributes);
|
||||
cmsGetHeaderProfileID(h, ps ->ProfileID.ID8);
|
||||
ps ->deviceMfg = cmsGetHeaderManufacturer(h);
|
||||
ps ->deviceModel = cmsGetHeaderModel(h);
|
||||
|
||||
techpt = (cmsTechnologySignature*) cmsReadTag(h, cmsSigTechnologyTag);
|
||||
if (techpt == NULL)
|
||||
ps ->technology = (cmsTechnologySignature) 0;
|
||||
else
|
||||
ps ->technology = *techpt;
|
||||
|
||||
ps ->Manufacturer = GetMLUFromProfile(h, cmsSigDeviceMfgDescTag);
|
||||
ps ->Model = GetMLUFromProfile(h, cmsSigDeviceModelDescTag);
|
||||
ps ->Description = GetMLUFromProfile(h, cmsSigProfileDescriptionTag);
|
||||
|
||||
}
|
||||
|
||||
return seq;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
static
|
||||
const cmsMLU* GetInfo(cmsHPROFILE hProfile, cmsInfoType Info)
|
||||
{
|
||||
cmsTagSignature sig;
|
||||
|
||||
switch (Info) {
|
||||
|
||||
case cmsInfoDescription:
|
||||
sig = cmsSigProfileDescriptionTag;
|
||||
break;
|
||||
|
||||
case cmsInfoManufacturer:
|
||||
sig = cmsSigDeviceMfgDescTag;
|
||||
break;
|
||||
|
||||
case cmsInfoModel:
|
||||
sig = cmsSigDeviceModelDescTag;
|
||||
break;
|
||||
|
||||
case cmsInfoCopyright:
|
||||
sig = cmsSigCopyrightTag;
|
||||
break;
|
||||
|
||||
default: return NULL;
|
||||
}
|
||||
|
||||
|
||||
return (cmsMLU*) cmsReadTag(hProfile, sig);
|
||||
}
|
||||
|
||||
|
||||
|
||||
cmsUInt32Number CMSEXPORT cmsGetProfileInfo(cmsHPROFILE hProfile, cmsInfoType Info,
|
||||
const char LanguageCode[3], const char CountryCode[3],
|
||||
wchar_t* Buffer, cmsUInt32Number BufferSize)
|
||||
{
|
||||
const cmsMLU* mlu = GetInfo(hProfile, Info);
|
||||
if (mlu == NULL) return 0;
|
||||
|
||||
return cmsMLUgetWide(mlu, LanguageCode, CountryCode, Buffer, BufferSize);
|
||||
}
|
||||
|
||||
|
||||
cmsUInt32Number CMSEXPORT cmsGetProfileInfoASCII(cmsHPROFILE hProfile, cmsInfoType Info,
|
||||
const char LanguageCode[3], const char CountryCode[3],
|
||||
char* Buffer, cmsUInt32Number BufferSize)
|
||||
{
|
||||
const cmsMLU* mlu = GetInfo(hProfile, Info);
|
||||
if (mlu == NULL) return 0;
|
||||
|
||||
return cmsMLUgetASCII(mlu, LanguageCode, CountryCode, Buffer, BufferSize);
|
||||
}
|
1665
thirdparty/liblcms2/src/cmslut.c
vendored
Normal file
1665
thirdparty/liblcms2/src/cmslut.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
317
thirdparty/liblcms2/src/cmsmd5.c
vendored
Normal file
317
thirdparty/liblcms2/src/cmsmd5.c
vendored
Normal file
@ -0,0 +1,317 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
//
|
||||
// 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 "lcms2_internal.h"
|
||||
|
||||
#ifdef CMS_USE_BIG_ENDIAN
|
||||
|
||||
static
|
||||
void byteReverse(cmsUInt8Number * buf, cmsUInt32Number longs)
|
||||
{
|
||||
do {
|
||||
|
||||
cmsUInt32Number t = _cmsAdjustEndianess32(*(cmsUInt32Number *) buf);
|
||||
*(cmsUInt32Number *) buf = t;
|
||||
buf += sizeof(cmsUInt32Number);
|
||||
|
||||
} while (--longs);
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
#define byteReverse(buf, len)
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
cmsUInt32Number buf[4];
|
||||
cmsUInt32Number bits[2];
|
||||
cmsUInt8Number in[64];
|
||||
cmsContext ContextID;
|
||||
|
||||
} _cmsMD5;
|
||||
|
||||
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
||||
#define F2(x, y, z) F1(z, x, y)
|
||||
#define F3(x, y, z) (x ^ y ^ z)
|
||||
#define F4(x, y, z) (y ^ (x | ~z))
|
||||
|
||||
#define STEP(f, w, x, y, z, data, s) \
|
||||
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
|
||||
|
||||
|
||||
static
|
||||
void MD5_Transform(cmsUInt32Number buf[4], cmsUInt32Number in[16])
|
||||
|
||||
{
|
||||
register cmsUInt32Number a, b, c, d;
|
||||
|
||||
a = buf[0];
|
||||
b = buf[1];
|
||||
c = buf[2];
|
||||
d = buf[3];
|
||||
|
||||
STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
|
||||
STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
|
||||
STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
|
||||
STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
|
||||
STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
|
||||
STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
|
||||
STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
|
||||
STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
|
||||
STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
|
||||
STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
|
||||
STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
|
||||
STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
|
||||
STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
|
||||
STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
|
||||
STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
|
||||
STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
|
||||
|
||||
STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
|
||||
STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
|
||||
STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
|
||||
STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
|
||||
STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
|
||||
STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
|
||||
STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
|
||||
STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
|
||||
STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
|
||||
STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
|
||||
STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
|
||||
STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
|
||||
STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
|
||||
STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
|
||||
STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
|
||||
STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
|
||||
|
||||
STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
|
||||
STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
|
||||
STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
|
||||
STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
|
||||
STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
|
||||
STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
|
||||
STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
|
||||
STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
|
||||
STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
|
||||
STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
|
||||
STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
|
||||
STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
|
||||
STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
|
||||
STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
|
||||
STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
|
||||
STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
|
||||
|
||||
STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
|
||||
STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
|
||||
STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
|
||||
STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
|
||||
STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
|
||||
STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
|
||||
STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
|
||||
STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
|
||||
STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
|
||||
STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
|
||||
STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
|
||||
STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
|
||||
STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
|
||||
STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
|
||||
STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
|
||||
STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
|
||||
|
||||
buf[0] += a;
|
||||
buf[1] += b;
|
||||
buf[2] += c;
|
||||
buf[3] += d;
|
||||
}
|
||||
|
||||
|
||||
// Create a MD5 object
|
||||
static
|
||||
cmsHANDLE MD5alloc(cmsContext ContextID)
|
||||
{
|
||||
_cmsMD5* ctx = (_cmsMD5*) _cmsMallocZero(ContextID, sizeof(_cmsMD5));
|
||||
if (ctx == NULL) return NULL;
|
||||
|
||||
ctx ->ContextID = ContextID;
|
||||
|
||||
ctx->buf[0] = 0x67452301;
|
||||
ctx->buf[1] = 0xefcdab89;
|
||||
ctx->buf[2] = 0x98badcfe;
|
||||
ctx->buf[3] = 0x10325476;
|
||||
|
||||
ctx->bits[0] = 0;
|
||||
ctx->bits[1] = 0;
|
||||
|
||||
return (cmsHANDLE) ctx;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void MD5add(cmsHANDLE Handle, cmsUInt8Number* buf, cmsUInt32Number len)
|
||||
{
|
||||
_cmsMD5* ctx = (_cmsMD5*) Handle;
|
||||
cmsUInt32Number t;
|
||||
|
||||
t = ctx->bits[0];
|
||||
if ((ctx->bits[0] = t + (len << 3)) < t)
|
||||
ctx->bits[1]++;
|
||||
|
||||
ctx->bits[1] += len >> 29;
|
||||
|
||||
t = (t >> 3) & 0x3f;
|
||||
|
||||
if (t) {
|
||||
|
||||
cmsUInt8Number *p = (cmsUInt8Number *) ctx->in + t;
|
||||
|
||||
t = 64 - t;
|
||||
if (len < t) {
|
||||
memmove(p, buf, len);
|
||||
return;
|
||||
}
|
||||
|
||||
memmove(p, buf, t);
|
||||
byteReverse(ctx->in, 16);
|
||||
|
||||
MD5_Transform(ctx->buf, (cmsUInt32Number *) ctx->in);
|
||||
buf += t;
|
||||
len -= t;
|
||||
}
|
||||
|
||||
while (len >= 64) {
|
||||
memmove(ctx->in, buf, 64);
|
||||
byteReverse(ctx->in, 16);
|
||||
MD5_Transform(ctx->buf, (cmsUInt32Number *) ctx->in);
|
||||
buf += 64;
|
||||
len -= 64;
|
||||
}
|
||||
|
||||
memmove(ctx->in, buf, len);
|
||||
}
|
||||
|
||||
// Destroy the object and return the checksum
|
||||
static
|
||||
void MD5finish(cmsProfileID* ProfileID, cmsHANDLE Handle)
|
||||
{
|
||||
_cmsMD5* ctx = (_cmsMD5*) Handle;
|
||||
cmsUInt32Number count;
|
||||
cmsUInt8Number *p;
|
||||
|
||||
count = (ctx->bits[0] >> 3) & 0x3F;
|
||||
|
||||
p = ctx->in + count;
|
||||
*p++ = 0x80;
|
||||
|
||||
count = 64 - 1 - count;
|
||||
|
||||
if (count < 8) {
|
||||
|
||||
memset(p, 0, count);
|
||||
byteReverse(ctx->in, 16);
|
||||
MD5_Transform(ctx->buf, (cmsUInt32Number *) ctx->in);
|
||||
|
||||
memset(ctx->in, 0, 56);
|
||||
} else {
|
||||
memset(p, 0, count - 8);
|
||||
}
|
||||
byteReverse(ctx->in, 14);
|
||||
|
||||
((cmsUInt32Number *) ctx->in)[14] = ctx->bits[0];
|
||||
((cmsUInt32Number *) ctx->in)[15] = ctx->bits[1];
|
||||
|
||||
MD5_Transform(ctx->buf, (cmsUInt32Number *) ctx->in);
|
||||
|
||||
byteReverse((cmsUInt8Number *) ctx->buf, 4);
|
||||
memmove(ProfileID ->ID8, ctx->buf, 16);
|
||||
|
||||
_cmsFree(ctx ->ContextID, ctx);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Assuming io points to an ICC profile, compute and store MD5 checksum
|
||||
// In the header, rendering intentent, attributes and ID should be set to zero
|
||||
// before computing MD5 checksum (per 6.1.13 in ICC spec)
|
||||
|
||||
cmsBool CMSEXPORT cmsMD5computeID(cmsHPROFILE hProfile)
|
||||
{
|
||||
cmsContext ContextID;
|
||||
cmsUInt32Number BytesNeeded;
|
||||
cmsUInt8Number* Mem = NULL;
|
||||
cmsHANDLE MD5 = NULL;
|
||||
_cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile;
|
||||
_cmsICCPROFILE Keep;
|
||||
|
||||
_cmsAssert(hProfile != NULL);
|
||||
|
||||
ContextID = cmsGetProfileContextID(hProfile);
|
||||
|
||||
// Save a copy of the profile header
|
||||
memmove(&Keep, Icc, sizeof(_cmsICCPROFILE));
|
||||
|
||||
// Set RI, attributes and ID
|
||||
memset(&Icc ->attributes, 0, sizeof(Icc ->attributes));
|
||||
Icc ->RenderingIntent = 0;
|
||||
memset(&Icc ->ProfileID, 0, sizeof(Icc ->ProfileID));
|
||||
|
||||
// Compute needed storage
|
||||
if (!cmsSaveProfileToMem(hProfile, NULL, &BytesNeeded)) goto Error;
|
||||
|
||||
// Allocate memory
|
||||
Mem = (cmsUInt8Number*) _cmsMalloc(ContextID, BytesNeeded);
|
||||
if (Mem == NULL) goto Error;
|
||||
|
||||
// Save to temporary storage
|
||||
if (!cmsSaveProfileToMem(hProfile, Mem, &BytesNeeded)) goto Error;
|
||||
|
||||
// Create MD5 object
|
||||
MD5 = MD5alloc(ContextID);
|
||||
if (MD5 == NULL) goto Error;
|
||||
|
||||
// Add all bytes
|
||||
MD5add(MD5, Mem, BytesNeeded);
|
||||
|
||||
// Temp storage is no longer needed
|
||||
_cmsFree(ContextID, Mem);
|
||||
|
||||
// Restore header
|
||||
memmove(Icc, &Keep, sizeof(_cmsICCPROFILE));
|
||||
|
||||
// And store the ID
|
||||
MD5finish(&Icc ->ProfileID, MD5);
|
||||
return TRUE;
|
||||
|
||||
Error:
|
||||
|
||||
// Free resources as something went wrong
|
||||
if (MD5 != NULL) _cmsFree(ContextID, MD5);
|
||||
if (Mem != NULL) _cmsFree(ContextID, Mem);
|
||||
memmove(Icc, &Keep, sizeof(_cmsICCPROFILE));
|
||||
return FALSE;
|
||||
}
|
||||
|
176
thirdparty/liblcms2/src/cmsmtrx.c
vendored
Normal file
176
thirdparty/liblcms2/src/cmsmtrx.c
vendored
Normal file
@ -0,0 +1,176 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
//
|
||||
// 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 "lcms2_internal.h"
|
||||
|
||||
|
||||
#define DSWAP(x, y) {cmsFloat64Number tmp = (x); (x)=(y); (y)=tmp;}
|
||||
|
||||
|
||||
// Initiate a vector
|
||||
void CMSEXPORT _cmsVEC3init(cmsVEC3* r, cmsFloat64Number x, cmsFloat64Number y, cmsFloat64Number z)
|
||||
{
|
||||
r -> n[VX] = x;
|
||||
r -> n[VY] = y;
|
||||
r -> n[VZ] = z;
|
||||
}
|
||||
|
||||
// Vector substraction
|
||||
void CMSEXPORT _cmsVEC3minus(cmsVEC3* r, const cmsVEC3* a, const cmsVEC3* b)
|
||||
{
|
||||
r -> n[VX] = a -> n[VX] - b -> n[VX];
|
||||
r -> n[VY] = a -> n[VY] - b -> n[VY];
|
||||
r -> n[VZ] = a -> n[VZ] - b -> n[VZ];
|
||||
}
|
||||
|
||||
// Vector cross product
|
||||
void CMSEXPORT _cmsVEC3cross(cmsVEC3* r, const cmsVEC3* u, const cmsVEC3* v)
|
||||
{
|
||||
r ->n[VX] = u->n[VY] * v->n[VZ] - v->n[VY] * u->n[VZ];
|
||||
r ->n[VY] = u->n[VZ] * v->n[VX] - v->n[VZ] * u->n[VX];
|
||||
r ->n[VZ] = u->n[VX] * v->n[VY] - v->n[VX] * u->n[VY];
|
||||
}
|
||||
|
||||
// Vector dot product
|
||||
cmsFloat64Number CMSEXPORT _cmsVEC3dot(const cmsVEC3* u, const cmsVEC3* v)
|
||||
{
|
||||
return u->n[VX] * v->n[VX] + u->n[VY] * v->n[VY] + u->n[VZ] * v->n[VZ];
|
||||
}
|
||||
|
||||
// Euclidean length
|
||||
cmsFloat64Number CMSEXPORT _cmsVEC3length(const cmsVEC3* a)
|
||||
{
|
||||
return sqrt(a ->n[VX] * a ->n[VX] +
|
||||
a ->n[VY] * a ->n[VY] +
|
||||
a ->n[VZ] * a ->n[VZ]);
|
||||
}
|
||||
|
||||
// Euclidean distance
|
||||
cmsFloat64Number CMSEXPORT _cmsVEC3distance(const cmsVEC3* a, const cmsVEC3* b)
|
||||
{
|
||||
cmsFloat64Number d1 = a ->n[VX] - b ->n[VX];
|
||||
cmsFloat64Number d2 = a ->n[VY] - b ->n[VY];
|
||||
cmsFloat64Number d3 = a ->n[VZ] - b ->n[VZ];
|
||||
|
||||
return sqrt(d1*d1 + d2*d2 + d3*d3);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 3x3 Identity
|
||||
void CMSEXPORT _cmsMAT3identity(cmsMAT3* a)
|
||||
{
|
||||
_cmsVEC3init(&a-> v[0], 1.0, 0.0, 0.0);
|
||||
_cmsVEC3init(&a-> v[1], 0.0, 1.0, 0.0);
|
||||
_cmsVEC3init(&a-> v[2], 0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
static
|
||||
cmsBool CloseEnough(cmsFloat64Number a, cmsFloat64Number b)
|
||||
{
|
||||
return fabs(b - a) < (1.0 / 65535.0);
|
||||
}
|
||||
|
||||
|
||||
cmsBool CMSEXPORT _cmsMAT3isIdentity(const cmsMAT3* a)
|
||||
{
|
||||
cmsMAT3 Identity;
|
||||
int i, j;
|
||||
|
||||
_cmsMAT3identity(&Identity);
|
||||
|
||||
for (i=0; i < 3; i++)
|
||||
for (j=0; j < 3; j++)
|
||||
if (!CloseEnough(a ->v[i].n[j], Identity.v[i].n[j])) return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Multiply two matrices
|
||||
void CMSEXPORT _cmsMAT3per(cmsMAT3* r, const cmsMAT3* a, const cmsMAT3* b)
|
||||
{
|
||||
#define ROWCOL(i, j) \
|
||||
a->v[i].n[0]*b->v[0].n[j] + a->v[i].n[1]*b->v[1].n[j] + a->v[i].n[2]*b->v[2].n[j]
|
||||
|
||||
_cmsVEC3init(&r-> v[0], ROWCOL(0,0), ROWCOL(0,1), ROWCOL(0,2));
|
||||
_cmsVEC3init(&r-> v[1], ROWCOL(1,0), ROWCOL(1,1), ROWCOL(1,2));
|
||||
_cmsVEC3init(&r-> v[2], ROWCOL(2,0), ROWCOL(2,1), ROWCOL(2,2));
|
||||
|
||||
#undef ROWCOL //(i, j)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Inverse of a matrix b = a^(-1)
|
||||
cmsBool CMSEXPORT _cmsMAT3inverse(const cmsMAT3* a, cmsMAT3* b)
|
||||
{
|
||||
cmsFloat64Number det, c0, c1, c2;
|
||||
|
||||
c0 = a -> v[1].n[1]*a -> v[2].n[2] - a -> v[1].n[2]*a -> v[2].n[1];
|
||||
c1 = -a -> v[1].n[0]*a -> v[2].n[2] + a -> v[1].n[2]*a -> v[2].n[0];
|
||||
c2 = a -> v[1].n[0]*a -> v[2].n[1] - a -> v[1].n[1]*a -> v[2].n[0];
|
||||
|
||||
det = a -> v[0].n[0]*c0 + a -> v[0].n[1]*c1 + a -> v[0].n[2]*c2;
|
||||
|
||||
if (fabs(det) < MATRIX_DET_TOLERANCE) return FALSE; // singular matrix; can't invert
|
||||
|
||||
b -> v[0].n[0] = c0/det;
|
||||
b -> v[0].n[1] = (a -> v[0].n[2]*a -> v[2].n[1] - a -> v[0].n[1]*a -> v[2].n[2])/det;
|
||||
b -> v[0].n[2] = (a -> v[0].n[1]*a -> v[1].n[2] - a -> v[0].n[2]*a -> v[1].n[1])/det;
|
||||
b -> v[1].n[0] = c1/det;
|
||||
b -> v[1].n[1] = (a -> v[0].n[0]*a -> v[2].n[2] - a -> v[0].n[2]*a -> v[2].n[0])/det;
|
||||
b -> v[1].n[2] = (a -> v[0].n[2]*a -> v[1].n[0] - a -> v[0].n[0]*a -> v[1].n[2])/det;
|
||||
b -> v[2].n[0] = c2/det;
|
||||
b -> v[2].n[1] = (a -> v[0].n[1]*a -> v[2].n[0] - a -> v[0].n[0]*a -> v[2].n[1])/det;
|
||||
b -> v[2].n[2] = (a -> v[0].n[0]*a -> v[1].n[1] - a -> v[0].n[1]*a -> v[1].n[0])/det;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Solve a system in the form Ax = b
|
||||
cmsBool CMSEXPORT _cmsMAT3solve(cmsVEC3* x, cmsMAT3* a, cmsVEC3* b)
|
||||
{
|
||||
cmsMAT3 m, a_1;
|
||||
|
||||
memmove(&m, a, sizeof(cmsMAT3));
|
||||
|
||||
if (!_cmsMAT3inverse(&m, &a_1)) return FALSE; // Singular matrix
|
||||
|
||||
_cmsMAT3eval(x, &a_1, b);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Evaluate a vector across a matrix
|
||||
void CMSEXPORT _cmsMAT3eval(cmsVEC3* r, const cmsMAT3* a, const cmsVEC3* v)
|
||||
{
|
||||
r->n[VX] = a->v[0].n[VX]*v->n[VX] + a->v[0].n[VY]*v->n[VY] + a->v[0].n[VZ]*v->n[VZ];
|
||||
r->n[VY] = a->v[1].n[VX]*v->n[VX] + a->v[1].n[VY]*v->n[VY] + a->v[1].n[VZ]*v->n[VZ];
|
||||
r->n[VZ] = a->v[2].n[VX]*v->n[VX] + a->v[2].n[VY]*v->n[VY] + a->v[2].n[VZ]*v->n[VZ];
|
||||
}
|
||||
|
||||
|
750
thirdparty/liblcms2/src/cmsnamed.c
vendored
Normal file
750
thirdparty/liblcms2/src/cmsnamed.c
vendored
Normal file
@ -0,0 +1,750 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
//
|
||||
// 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 "lcms2_internal.h"
|
||||
|
||||
// Multilocalized unicode objects. That is an attempt to encapsulate i18n.
|
||||
|
||||
|
||||
// Allocates an empty multi localizad unicode object
|
||||
cmsMLU* CMSEXPORT cmsMLUalloc(cmsContext ContextID, cmsUInt32Number nItems)
|
||||
{
|
||||
cmsMLU* mlu;
|
||||
|
||||
// nItems should be positive if given
|
||||
if (nItems <= 0) nItems = 2;
|
||||
|
||||
// Create the container
|
||||
mlu = (cmsMLU*) _cmsMallocZero(ContextID, sizeof(cmsMLU));
|
||||
if (mlu == NULL) return NULL;
|
||||
|
||||
mlu ->ContextID = ContextID;
|
||||
|
||||
// Create entry array
|
||||
mlu ->Entries = (_cmsMLUentry*) _cmsCalloc(ContextID, nItems, sizeof(_cmsMLUentry));
|
||||
if (mlu ->Entries == NULL) {
|
||||
_cmsFree(ContextID, mlu);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Ok, keep indexes up to date
|
||||
mlu ->AllocatedEntries = nItems;
|
||||
mlu ->UsedEntries = 0;
|
||||
|
||||
return mlu;
|
||||
}
|
||||
|
||||
|
||||
// Grows a mempool table for a MLU. Each time this function is called, mempool size is multiplied times two.
|
||||
static
|
||||
cmsBool GrowMLUpool(cmsMLU* mlu)
|
||||
{
|
||||
cmsUInt32Number size;
|
||||
void *NewPtr;
|
||||
|
||||
// Sanity check
|
||||
if (mlu == NULL) return FALSE;
|
||||
|
||||
if (mlu ->PoolSize == 0)
|
||||
size = 256;
|
||||
else
|
||||
size = mlu ->PoolSize * 2;
|
||||
|
||||
// Check for overflow
|
||||
if (size < mlu ->PoolSize) return FALSE;
|
||||
|
||||
// Reallocate the pool
|
||||
NewPtr = _cmsRealloc(mlu ->ContextID, mlu ->MemPool, size);
|
||||
if (NewPtr == NULL) return FALSE;
|
||||
|
||||
|
||||
mlu ->MemPool = NewPtr;
|
||||
mlu ->PoolSize = size;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Grows a ntry table for a MLU. Each time this function is called, table size is multiplied times two.
|
||||
static
|
||||
cmsBool GrowMLUtable(cmsMLU* mlu)
|
||||
{
|
||||
int AllocatedEntries;
|
||||
_cmsMLUentry *NewPtr;
|
||||
|
||||
// Sanity check
|
||||
if (mlu == NULL) return FALSE;
|
||||
|
||||
AllocatedEntries = mlu ->AllocatedEntries * 2;
|
||||
|
||||
// Check for overflow
|
||||
if (AllocatedEntries / 2 != mlu ->AllocatedEntries) return FALSE;
|
||||
|
||||
// Reallocate the memory
|
||||
NewPtr = (_cmsMLUentry*)_cmsRealloc(mlu ->ContextID, mlu ->Entries, AllocatedEntries*sizeof(_cmsMLUentry));
|
||||
if (NewPtr == NULL) return FALSE;
|
||||
|
||||
mlu ->Entries = NewPtr;
|
||||
mlu ->AllocatedEntries = AllocatedEntries;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Search for a specific entry in the structure. Language and Country are used.
|
||||
static
|
||||
int SearchMLUEntry(cmsMLU* mlu, cmsUInt16Number LanguageCode, cmsUInt16Number CountryCode)
|
||||
{
|
||||
int i;
|
||||
|
||||
// Sanity check
|
||||
if (mlu == NULL) return -1;
|
||||
|
||||
// Iterate whole table
|
||||
for (i=0; i < mlu ->UsedEntries; i++) {
|
||||
|
||||
if (mlu ->Entries[i].Country == CountryCode &&
|
||||
mlu ->Entries[i].Language == LanguageCode) return i;
|
||||
}
|
||||
|
||||
// Not found
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Add a block of characters to the intended MLU. Language and country are specified.
|
||||
// Only one entry for Language/country pair is allowed.
|
||||
static
|
||||
cmsBool AddMLUBlock(cmsMLU* mlu, cmsUInt32Number size, const wchar_t *Block,
|
||||
cmsUInt16Number LanguageCode, cmsUInt16Number CountryCode)
|
||||
{
|
||||
cmsUInt32Number Offset;
|
||||
cmsUInt8Number* Ptr;
|
||||
|
||||
// Sanity check
|
||||
if (mlu == NULL) return FALSE;
|
||||
|
||||
// Is there any room available?
|
||||
if (mlu ->UsedEntries >= mlu ->AllocatedEntries) {
|
||||
if (!GrowMLUtable(mlu)) return FALSE;
|
||||
}
|
||||
|
||||
// Only one ASCII string
|
||||
if (SearchMLUEntry(mlu, LanguageCode, CountryCode) >= 0) return FALSE; // Only one is allowed!
|
||||
|
||||
// Check for size
|
||||
while ((mlu ->PoolSize - mlu ->PoolUsed) < size) {
|
||||
|
||||
if (!GrowMLUpool(mlu)) return FALSE;
|
||||
}
|
||||
|
||||
Offset = mlu ->PoolUsed;
|
||||
|
||||
Ptr = (cmsUInt8Number*) mlu ->MemPool;
|
||||
if (Ptr == NULL) return FALSE;
|
||||
|
||||
// Set the entry
|
||||
memmove(Ptr + Offset, Block, size);
|
||||
mlu ->PoolUsed += size;
|
||||
|
||||
mlu ->Entries[mlu ->UsedEntries].StrW = Offset;
|
||||
mlu ->Entries[mlu ->UsedEntries].Len = size;
|
||||
mlu ->Entries[mlu ->UsedEntries].Country = CountryCode;
|
||||
mlu ->Entries[mlu ->UsedEntries].Language = LanguageCode;
|
||||
mlu ->UsedEntries++;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Add an ASCII entry.
|
||||
cmsBool CMSEXPORT cmsMLUsetASCII(cmsMLU* mlu, const char LanguageCode[3], const char CountryCode[3], const char* ASCIIString)
|
||||
{
|
||||
cmsUInt32Number i, len = (cmsUInt32Number) strlen(ASCIIString)+1;
|
||||
wchar_t* WStr;
|
||||
cmsBool rc;
|
||||
cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode);
|
||||
cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode);
|
||||
|
||||
if (mlu == NULL) return FALSE;
|
||||
|
||||
WStr = (wchar_t*) _cmsCalloc(mlu ->ContextID, len, sizeof(wchar_t));
|
||||
if (WStr == NULL) return FALSE;
|
||||
|
||||
for (i=0; i < len; i++)
|
||||
WStr[i] = (wchar_t) ASCIIString[i];
|
||||
|
||||
rc = AddMLUBlock(mlu, len * sizeof(wchar_t), WStr, Lang, Cntry);
|
||||
|
||||
_cmsFree(mlu ->ContextID, WStr);
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
||||
// We don't need any wcs support library
|
||||
static
|
||||
cmsUInt32Number mywcslen(const wchar_t *s)
|
||||
{
|
||||
const wchar_t *p;
|
||||
|
||||
p = s;
|
||||
while (*p)
|
||||
p++;
|
||||
|
||||
return (cmsUInt32Number)(p - s);
|
||||
}
|
||||
|
||||
|
||||
// Add a wide entry
|
||||
cmsBool CMSEXPORT cmsMLUsetWide(cmsMLU* mlu, const char Language[3], const char Country[3], const wchar_t* WideString)
|
||||
{
|
||||
cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) Language);
|
||||
cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) Country);
|
||||
cmsUInt32Number len;
|
||||
|
||||
if (mlu == NULL) return FALSE;
|
||||
if (WideString == NULL) return FALSE;
|
||||
|
||||
len = (cmsUInt32Number) (mywcslen(WideString) + 1) * sizeof(wchar_t);
|
||||
return AddMLUBlock(mlu, len, WideString, Lang, Cntry);
|
||||
}
|
||||
|
||||
// Duplicating a MLU is as easy as copying all members
|
||||
cmsMLU* CMSEXPORT cmsMLUdup(const cmsMLU* mlu)
|
||||
{
|
||||
cmsMLU* NewMlu = NULL;
|
||||
|
||||
// Duplicating a NULL obtains a NULL
|
||||
if (mlu == NULL) return NULL;
|
||||
|
||||
NewMlu = cmsMLUalloc(mlu ->ContextID, mlu ->UsedEntries);
|
||||
if (NewMlu == NULL) return NULL;
|
||||
|
||||
// Should never happen
|
||||
if (NewMlu ->AllocatedEntries < mlu ->UsedEntries)
|
||||
goto Error;
|
||||
|
||||
// Sanitize...
|
||||
if (NewMlu ->Entries == NULL || mlu ->Entries == NULL) goto Error;
|
||||
|
||||
memmove(NewMlu ->Entries, mlu ->Entries, mlu ->UsedEntries * sizeof(_cmsMLUentry));
|
||||
NewMlu ->UsedEntries = mlu ->UsedEntries;
|
||||
|
||||
// The MLU may be empty
|
||||
if (mlu ->PoolUsed == 0) {
|
||||
NewMlu ->MemPool = NULL;
|
||||
}
|
||||
else {
|
||||
// It is not empty
|
||||
NewMlu ->MemPool = _cmsMalloc(mlu ->ContextID, mlu ->PoolUsed);
|
||||
if (NewMlu ->MemPool == NULL) goto Error;
|
||||
}
|
||||
|
||||
NewMlu ->PoolSize = mlu ->PoolUsed;
|
||||
|
||||
if (NewMlu ->MemPool == NULL || mlu ->MemPool == NULL) goto Error;
|
||||
|
||||
memmove(NewMlu ->MemPool, mlu->MemPool, mlu ->PoolUsed);
|
||||
NewMlu ->PoolUsed = mlu ->PoolUsed;
|
||||
|
||||
return NewMlu;
|
||||
|
||||
Error:
|
||||
|
||||
if (NewMlu != NULL) cmsMLUfree(NewMlu);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Free any used memory
|
||||
void CMSEXPORT cmsMLUfree(cmsMLU* mlu)
|
||||
{
|
||||
if (mlu) {
|
||||
|
||||
if (mlu -> Entries) _cmsFree(mlu ->ContextID, mlu->Entries);
|
||||
if (mlu -> MemPool) _cmsFree(mlu ->ContextID, mlu->MemPool);
|
||||
|
||||
_cmsFree(mlu ->ContextID, mlu);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// The algorithm first searches for an exact match of country and language, if not found it uses
|
||||
// the Language. If none is found, first entry is used instead.
|
||||
static
|
||||
const wchar_t* _cmsMLUgetWide(const cmsMLU* mlu,
|
||||
cmsUInt32Number *len,
|
||||
cmsUInt16Number LanguageCode, cmsUInt16Number CountryCode,
|
||||
cmsUInt16Number* UsedLanguageCode, cmsUInt16Number* UsedCountryCode)
|
||||
{
|
||||
int i;
|
||||
int Best = -1;
|
||||
_cmsMLUentry* v;
|
||||
|
||||
if (mlu == NULL) return NULL;
|
||||
|
||||
if (mlu -> AllocatedEntries <= 0) return NULL;
|
||||
|
||||
for (i=0; i < mlu ->UsedEntries; i++) {
|
||||
|
||||
v = mlu ->Entries + i;
|
||||
|
||||
if (v -> Language == LanguageCode) {
|
||||
|
||||
if (Best == -1) Best = i;
|
||||
|
||||
if (v -> Country == CountryCode) {
|
||||
|
||||
if (UsedLanguageCode != NULL) *UsedLanguageCode = v ->Language;
|
||||
if (UsedCountryCode != NULL) *UsedCountryCode = v ->Country;
|
||||
|
||||
if (len != NULL) *len = v ->Len;
|
||||
|
||||
return (wchar_t*) ((cmsUInt8Number*) mlu ->MemPool + v -> StrW); // Found exact match
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No string found. Return First one
|
||||
if (Best == -1)
|
||||
Best = 0;
|
||||
|
||||
v = mlu ->Entries + Best;
|
||||
|
||||
if (UsedLanguageCode != NULL) *UsedLanguageCode = v ->Language;
|
||||
if (UsedCountryCode != NULL) *UsedCountryCode = v ->Country;
|
||||
|
||||
if (len != NULL) *len = v ->Len;
|
||||
|
||||
return(wchar_t*) ((cmsUInt8Number*) mlu ->MemPool + v ->StrW);
|
||||
}
|
||||
|
||||
|
||||
// Obtain an ASCII representation of the wide string. Setting buffer to NULL returns the len
|
||||
cmsUInt32Number CMSEXPORT cmsMLUgetASCII(const cmsMLU* mlu,
|
||||
const char LanguageCode[3], const char CountryCode[3],
|
||||
char* Buffer, cmsUInt32Number BufferSize)
|
||||
{
|
||||
const wchar_t *Wide;
|
||||
cmsUInt32Number StrLen = 0;
|
||||
cmsUInt32Number ASCIIlen, i;
|
||||
|
||||
cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode);
|
||||
cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode);
|
||||
|
||||
// Sanitize
|
||||
if (mlu == NULL) return 0;
|
||||
|
||||
// Get WideChar
|
||||
Wide = _cmsMLUgetWide(mlu, &StrLen, Lang, Cntry, NULL, NULL);
|
||||
if (Wide == NULL) return 0;
|
||||
|
||||
ASCIIlen = StrLen / sizeof(wchar_t);
|
||||
|
||||
// Maybe we want only to know the len?
|
||||
if (Buffer == NULL) return ASCIIlen + 1; // Note the zero at the end
|
||||
|
||||
// No buffer size means no data
|
||||
if (BufferSize <= 0) return 0;
|
||||
|
||||
// Some clipping may be required
|
||||
if (BufferSize < ASCIIlen + 1)
|
||||
ASCIIlen = BufferSize - 1;
|
||||
|
||||
// Precess each character
|
||||
for (i=0; i < ASCIIlen; i++) {
|
||||
|
||||
if (Wide[i] == 0)
|
||||
Buffer[i] = 0;
|
||||
else
|
||||
Buffer[i] = (char) Wide[i];
|
||||
}
|
||||
|
||||
// We put a termination "\0"
|
||||
Buffer[ASCIIlen] = 0;
|
||||
return ASCIIlen + 1;
|
||||
}
|
||||
|
||||
// Obtain a wide representation of the MLU, on depending on current locale settings
|
||||
cmsUInt32Number CMSEXPORT cmsMLUgetWide(const cmsMLU* mlu,
|
||||
const char LanguageCode[3], const char CountryCode[3],
|
||||
wchar_t* Buffer, cmsUInt32Number BufferSize)
|
||||
{
|
||||
const wchar_t *Wide;
|
||||
cmsUInt32Number StrLen = 0;
|
||||
|
||||
cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode);
|
||||
cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode);
|
||||
|
||||
// Sanitize
|
||||
if (mlu == NULL) return 0;
|
||||
|
||||
Wide = _cmsMLUgetWide(mlu, &StrLen, Lang, Cntry, NULL, NULL);
|
||||
if (Wide == NULL) return 0;
|
||||
|
||||
// Maybe we want only to know the len?
|
||||
if (Buffer == NULL) return StrLen + sizeof(wchar_t);
|
||||
|
||||
// No buffer size means no data
|
||||
if (BufferSize <= 0) return 0;
|
||||
|
||||
// Some clipping may be required
|
||||
if (BufferSize < StrLen + sizeof(wchar_t))
|
||||
StrLen = BufferSize - + sizeof(wchar_t);
|
||||
|
||||
memmove(Buffer, Wide, StrLen);
|
||||
Buffer[StrLen / sizeof(wchar_t)] = 0;
|
||||
|
||||
return StrLen + sizeof(wchar_t);
|
||||
}
|
||||
|
||||
|
||||
// Get also the language and country
|
||||
CMSAPI cmsBool CMSEXPORT cmsMLUgetTranslation(const cmsMLU* mlu,
|
||||
const char LanguageCode[3], const char CountryCode[3],
|
||||
char ObtainedLanguage[3], char ObtainedCountry[3])
|
||||
{
|
||||
const wchar_t *Wide;
|
||||
|
||||
cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode);
|
||||
cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode);
|
||||
cmsUInt16Number ObtLang, ObtCode;
|
||||
|
||||
// Sanitize
|
||||
if (mlu == NULL) return FALSE;
|
||||
|
||||
Wide = _cmsMLUgetWide(mlu, NULL, Lang, Cntry, &ObtLang, &ObtCode);
|
||||
if (Wide == NULL) return FALSE;
|
||||
|
||||
// Get used language and code
|
||||
*(cmsUInt16Number *)ObtainedLanguage = _cmsAdjustEndianess16(ObtLang);
|
||||
*(cmsUInt16Number *)ObtainedCountry = _cmsAdjustEndianess16(ObtCode);
|
||||
|
||||
ObtainedLanguage[2] = ObtainedCountry[2] = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Named color lists --------------------------------------------------------------------------------------------
|
||||
|
||||
// Grow the list to keep at least NumElements
|
||||
static
|
||||
cmsBool GrowNamedColorList(cmsNAMEDCOLORLIST* v)
|
||||
{
|
||||
cmsUInt32Number size;
|
||||
_cmsNAMEDCOLOR * NewPtr;
|
||||
|
||||
if (v == NULL) return FALSE;
|
||||
|
||||
if (v ->Allocated == 0)
|
||||
size = 64; // Initial guess
|
||||
else
|
||||
size = v ->Allocated * 2;
|
||||
|
||||
// Keep a maximum color lists can grow, 100K entries seems reasonable
|
||||
if (size > 1024*100) return FALSE;
|
||||
|
||||
NewPtr = (_cmsNAMEDCOLOR*) _cmsRealloc(v ->ContextID, v ->List, size * sizeof(_cmsNAMEDCOLOR));
|
||||
if (NewPtr == NULL)
|
||||
return FALSE;
|
||||
|
||||
v ->List = NewPtr;
|
||||
v ->Allocated = size;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Allocate a list for n elements
|
||||
cmsNAMEDCOLORLIST* CMSEXPORT cmsAllocNamedColorList(cmsContext ContextID, cmsUInt32Number n, cmsUInt32Number ColorantCount, const char* Prefix, const char* Suffix)
|
||||
{
|
||||
cmsNAMEDCOLORLIST* v = (cmsNAMEDCOLORLIST*) _cmsMallocZero(ContextID, sizeof(cmsNAMEDCOLORLIST));
|
||||
|
||||
if (v == NULL) return NULL;
|
||||
|
||||
v ->List = NULL;
|
||||
v ->nColors = 0;
|
||||
v ->ContextID = ContextID;
|
||||
|
||||
while (v -> Allocated < n)
|
||||
GrowNamedColorList(v);
|
||||
|
||||
strncpy(v ->Prefix, Prefix, sizeof(v ->Prefix));
|
||||
strncpy(v ->Suffix, Suffix, sizeof(v ->Suffix));
|
||||
v -> ColorantCount = ColorantCount;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
// Free a list
|
||||
void CMSEXPORT cmsFreeNamedColorList(cmsNAMEDCOLORLIST* v)
|
||||
{
|
||||
if (v ->List) _cmsFree(v ->ContextID, v ->List);
|
||||
if (v) _cmsFree(v ->ContextID, v);
|
||||
}
|
||||
|
||||
cmsNAMEDCOLORLIST* CMSEXPORT cmsDupNamedColorList(const cmsNAMEDCOLORLIST* v)
|
||||
{
|
||||
cmsNAMEDCOLORLIST* NewNC;
|
||||
|
||||
if (v == NULL) return NULL;
|
||||
|
||||
NewNC= cmsAllocNamedColorList(v ->ContextID, v -> nColors, v ->ColorantCount, v ->Prefix, v ->Suffix);
|
||||
if (NewNC == NULL) return NULL;
|
||||
|
||||
// For really large tables we need this
|
||||
while (NewNC ->Allocated < v ->Allocated)
|
||||
GrowNamedColorList(NewNC);
|
||||
|
||||
memmove(NewNC ->Prefix, v ->Prefix, sizeof(v ->Prefix));
|
||||
memmove(NewNC ->Suffix, v ->Suffix, sizeof(v ->Suffix));
|
||||
NewNC ->ColorantCount = v ->ColorantCount;
|
||||
memmove(NewNC->List, v ->List, v->nColors * sizeof(_cmsNAMEDCOLOR));
|
||||
NewNC ->nColors = v ->nColors;
|
||||
return NewNC;
|
||||
}
|
||||
|
||||
|
||||
// Append a color to a list. List pointer may change if reallocated
|
||||
cmsBool CMSEXPORT cmsAppendNamedColor(cmsNAMEDCOLORLIST* NamedColorList,
|
||||
const char* Name,
|
||||
cmsUInt16Number PCS[3], cmsUInt16Number Colorant[cmsMAXCHANNELS])
|
||||
{
|
||||
cmsUInt32Number i;
|
||||
|
||||
if (NamedColorList == NULL) return FALSE;
|
||||
|
||||
if (NamedColorList ->nColors + 1 > NamedColorList ->Allocated) {
|
||||
if (!GrowNamedColorList(NamedColorList)) return FALSE;
|
||||
}
|
||||
|
||||
for (i=0; i < NamedColorList ->ColorantCount; i++)
|
||||
NamedColorList ->List[NamedColorList ->nColors].DeviceColorant[i] = Colorant == NULL? 0 : Colorant[i];
|
||||
|
||||
for (i=0; i < 3; i++)
|
||||
NamedColorList ->List[NamedColorList ->nColors].PCS[i] = PCS == NULL ? 0 : PCS[i];
|
||||
|
||||
if (Name != NULL)
|
||||
strncpy(NamedColorList ->List[NamedColorList ->nColors].Name, Name,
|
||||
sizeof(NamedColorList ->List[NamedColorList ->nColors].Name));
|
||||
else
|
||||
NamedColorList ->List[NamedColorList ->nColors].Name[0] = 0;
|
||||
|
||||
|
||||
NamedColorList ->nColors++;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Returns number of elements
|
||||
cmsUInt32Number CMSEXPORT cmsNamedColorCount(const cmsNAMEDCOLORLIST* NamedColorList)
|
||||
{
|
||||
if (NamedColorList == NULL) return 0;
|
||||
return NamedColorList ->nColors;
|
||||
}
|
||||
|
||||
// Info aboout a given color
|
||||
cmsBool CMSEXPORT cmsNamedColorInfo(const cmsNAMEDCOLORLIST* NamedColorList, cmsUInt32Number nColor,
|
||||
char* Name,
|
||||
char* Prefix,
|
||||
char* Suffix,
|
||||
cmsUInt16Number* PCS,
|
||||
cmsUInt16Number* Colorant)
|
||||
{
|
||||
if (NamedColorList == NULL) return FALSE;
|
||||
|
||||
if (nColor >= cmsNamedColorCount(NamedColorList)) return FALSE;
|
||||
|
||||
if (Name) strcpy(Name, NamedColorList->List[nColor].Name);
|
||||
if (Prefix) strcpy(Prefix, NamedColorList->Prefix);
|
||||
if (Suffix) strcpy(Suffix, NamedColorList->Suffix);
|
||||
if (PCS)
|
||||
memmove(PCS, NamedColorList ->List[nColor].PCS, 3*sizeof(cmsUInt16Number));
|
||||
|
||||
if (Colorant)
|
||||
memmove(Colorant, NamedColorList ->List[nColor].DeviceColorant,
|
||||
sizeof(cmsUInt16Number) * NamedColorList ->ColorantCount);
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Search for a given color name (no prefix or suffix)
|
||||
cmsInt32Number CMSEXPORT cmsNamedColorIndex(const cmsNAMEDCOLORLIST* NamedColorList, const char* Name)
|
||||
{
|
||||
int i, n;
|
||||
|
||||
if (NamedColorList == NULL) return -1;
|
||||
n = cmsNamedColorCount(NamedColorList);
|
||||
for (i=0; i < n; i++) {
|
||||
if (cmsstrcasecmp(Name, NamedColorList->List[i].Name) == 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// MPE support -----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
static
|
||||
void FreeNamedColorList(cmsStage* mpe)
|
||||
{
|
||||
cmsNAMEDCOLORLIST* List = (cmsNAMEDCOLORLIST*) mpe ->Data;
|
||||
cmsFreeNamedColorList(List);
|
||||
}
|
||||
|
||||
static
|
||||
void* DupNamedColorList(cmsStage* mpe)
|
||||
{
|
||||
cmsNAMEDCOLORLIST* List = (cmsNAMEDCOLORLIST*) mpe ->Data;
|
||||
return cmsDupNamedColorList(List);
|
||||
}
|
||||
|
||||
static
|
||||
void EvalNamedColor(const cmsFloat32Number In[], cmsFloat32Number Out[], const cmsStage *mpe)
|
||||
{
|
||||
cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) mpe ->Data;
|
||||
cmsUInt16Number index = (cmsUInt16Number) _cmsQuickSaturateWord(In[0] * 65535.0);
|
||||
cmsUInt32Number j;
|
||||
|
||||
if (index >= NamedColorList-> nColors) {
|
||||
cmsSignalError(NamedColorList ->ContextID, cmsERROR_RANGE, "Color %d out of range; ignored", index);
|
||||
}
|
||||
else {
|
||||
for (j=0; j < NamedColorList ->ColorantCount; j++)
|
||||
Out[j] = (cmsFloat32Number) (NamedColorList->List[index].DeviceColorant[j] / 65535.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Named color lookup element
|
||||
cmsStage* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList)
|
||||
{
|
||||
return _cmsStageAllocPlaceholder(NamedColorList ->ContextID,
|
||||
cmsSigNamedColorElemType,
|
||||
1, 3,
|
||||
EvalNamedColor,
|
||||
DupNamedColorList,
|
||||
FreeNamedColorList,
|
||||
cmsDupNamedColorList(NamedColorList));
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Retrieve the named color list from a transform. Should be first element in the LUT
|
||||
cmsNAMEDCOLORLIST* CMSEXPORT cmsGetNamedColorList(cmsHTRANSFORM xform)
|
||||
{
|
||||
_cmsTRANSFORM* v = (_cmsTRANSFORM*) xform;
|
||||
cmsStage* mpe = v ->Lut->Elements;
|
||||
|
||||
if (mpe ->Type != cmsSigNamedColorElemType) return NULL;
|
||||
return (cmsNAMEDCOLORLIST*) mpe ->Data;
|
||||
}
|
||||
|
||||
|
||||
// Profile sequence description routines -------------------------------------------------------------------------------------
|
||||
|
||||
cmsSEQ* CMSEXPORT cmsAllocProfileSequenceDescription(cmsContext ContextID, cmsUInt32Number n)
|
||||
{
|
||||
cmsSEQ* Seq;
|
||||
cmsUInt32Number i;
|
||||
|
||||
if (n == 0) return NULL;
|
||||
|
||||
// In a absolutely arbitrary way, I hereby decide to allow a maxim of 255 profiles linked
|
||||
// in a devicelink. It makes not sense anyway and may be used for exploits, so let's close the door!
|
||||
if (n > 255) return NULL;
|
||||
|
||||
Seq = (cmsSEQ*) _cmsMallocZero(ContextID, sizeof(cmsSEQ));
|
||||
if (Seq == NULL) return NULL;
|
||||
|
||||
Seq -> ContextID = ContextID;
|
||||
Seq -> seq = (cmsPSEQDESC*) _cmsCalloc(ContextID, n, sizeof(cmsPSEQDESC));
|
||||
Seq -> n = n;
|
||||
|
||||
|
||||
for (i=0; i < n; i++) {
|
||||
Seq -> seq[i].Manufacturer = NULL;
|
||||
Seq -> seq[i].Model = NULL;
|
||||
Seq -> seq[i].Description = NULL;
|
||||
}
|
||||
|
||||
return Seq;
|
||||
}
|
||||
|
||||
void CMSEXPORT cmsFreeProfileSequenceDescription(cmsSEQ* pseq)
|
||||
{
|
||||
cmsUInt32Number i;
|
||||
|
||||
for (i=0; i < pseq ->n; i++) {
|
||||
if (pseq ->seq[i].Manufacturer != NULL) cmsMLUfree(pseq ->seq[i].Manufacturer);
|
||||
if (pseq ->seq[i].Model != NULL) cmsMLUfree(pseq ->seq[i].Model);
|
||||
if (pseq ->seq[i].Description != NULL) cmsMLUfree(pseq ->seq[i].Description);
|
||||
}
|
||||
|
||||
if (pseq ->seq != NULL) _cmsFree(pseq ->ContextID, pseq ->seq);
|
||||
_cmsFree(pseq -> ContextID, pseq);
|
||||
}
|
||||
|
||||
cmsSEQ* CMSEXPORT cmsDupProfileSequenceDescription(const cmsSEQ* pseq)
|
||||
{
|
||||
cmsSEQ *NewSeq;
|
||||
cmsUInt32Number i;
|
||||
|
||||
if (pseq == NULL)
|
||||
return NULL;
|
||||
|
||||
NewSeq = (cmsSEQ*) _cmsMalloc(pseq -> ContextID, sizeof(cmsSEQ));
|
||||
if (NewSeq == NULL) return NULL;
|
||||
|
||||
|
||||
NewSeq -> seq = (cmsPSEQDESC*) _cmsCalloc(pseq ->ContextID, pseq ->n, sizeof(cmsPSEQDESC));
|
||||
if (NewSeq ->seq == NULL) goto Error;
|
||||
|
||||
NewSeq -> ContextID = pseq ->ContextID;
|
||||
NewSeq -> n = pseq ->n;
|
||||
|
||||
for (i=0; i < pseq->n; i++) {
|
||||
|
||||
memmove(&NewSeq ->seq[i].attributes, &pseq ->seq[i].attributes, sizeof(cmsUInt64Number));
|
||||
|
||||
NewSeq ->seq[i].deviceMfg = pseq ->seq[i].deviceMfg;
|
||||
NewSeq ->seq[i].deviceModel = pseq ->seq[i].deviceModel;
|
||||
memmove(&NewSeq ->seq[i].ProfileID, &pseq ->seq[i].ProfileID, sizeof(cmsProfileID));
|
||||
NewSeq ->seq[i].technology = pseq ->seq[i].technology;
|
||||
|
||||
NewSeq ->seq[i].Manufacturer = cmsMLUdup(pseq ->seq[i].Manufacturer);
|
||||
NewSeq ->seq[i].Model = cmsMLUdup(pseq ->seq[i].Model);
|
||||
NewSeq ->seq[i].Description = cmsMLUdup(pseq ->seq[i].Description);
|
||||
|
||||
}
|
||||
|
||||
return NewSeq;
|
||||
|
||||
Error:
|
||||
|
||||
cmsFreeProfileSequenceDescription(NewSeq);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
1631
thirdparty/liblcms2/src/cmsopt.c
vendored
Normal file
1631
thirdparty/liblcms2/src/cmsopt.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2558
thirdparty/liblcms2/src/cmspack.c
vendored
Normal file
2558
thirdparty/liblcms2/src/cmspack.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
926
thirdparty/liblcms2/src/cmspcs.c
vendored
Normal file
926
thirdparty/liblcms2/src/cmspcs.c
vendored
Normal file
@ -0,0 +1,926 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
//
|
||||
// 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 "lcms2_internal.h"
|
||||
|
||||
// inter PCS conversions XYZ <-> CIE L* a* b*
|
||||
/*
|
||||
|
||||
|
||||
CIE 15:2004 CIELab is defined as:
|
||||
|
||||
L* = 116*f(Y/Yn) - 16 0 <= L* <= 100
|
||||
a* = 500*[f(X/Xn) - f(Y/Yn)]
|
||||
b* = 200*[f(Y/Yn) - f(Z/Zn)]
|
||||
|
||||
and
|
||||
|
||||
f(t) = t^(1/3) 1 >= t > (24/116)^3
|
||||
(841/108)*t + (16/116) 0 <= t <= (24/116)^3
|
||||
|
||||
|
||||
Reverse transform is:
|
||||
|
||||
X = Xn*[a* / 500 + (L* + 16) / 116] ^ 3 if (X/Xn) > (24/116)
|
||||
= Xn*(a* / 500 + L* / 116) / 7.787 if (X/Xn) <= (24/116)
|
||||
|
||||
|
||||
|
||||
PCS in Lab2 is encoded as:
|
||||
|
||||
8 bit Lab PCS:
|
||||
|
||||
L* 0..100 into a 0..ff byte.
|
||||
a* t + 128 range is -128.0 +127.0
|
||||
b*
|
||||
|
||||
16 bit Lab PCS:
|
||||
|
||||
L* 0..100 into a 0..ff00 word.
|
||||
a* t + 128 range is -128.0 +127.9961
|
||||
b*
|
||||
|
||||
|
||||
|
||||
Interchange Space Component Actual Range Encoded Range
|
||||
CIE XYZ X 0 -> 1.99997 0x0000 -> 0xffff
|
||||
CIE XYZ Y 0 -> 1.99997 0x0000 -> 0xffff
|
||||
CIE XYZ Z 0 -> 1.99997 0x0000 -> 0xffff
|
||||
|
||||
Version 2,3
|
||||
-----------
|
||||
|
||||
CIELAB (16 bit) L* 0 -> 100.0 0x0000 -> 0xff00
|
||||
CIELAB (16 bit) a* -128.0 -> +127.996 0x0000 -> 0x8000 -> 0xffff
|
||||
CIELAB (16 bit) b* -128.0 -> +127.996 0x0000 -> 0x8000 -> 0xffff
|
||||
|
||||
|
||||
Version 4
|
||||
---------
|
||||
|
||||
CIELAB (16 bit) L* 0 -> 100.0 0x0000 -> 0xffff
|
||||
CIELAB (16 bit) a* -128.0 -> +127 0x0000 -> 0x8080 -> 0xffff
|
||||
CIELAB (16 bit) b* -128.0 -> +127 0x0000 -> 0x8080 -> 0xffff
|
||||
|
||||
*/
|
||||
|
||||
// Conversions
|
||||
void CMSEXPORT cmsXYZ2xyY(cmsCIExyY* Dest, const cmsCIEXYZ* Source)
|
||||
{
|
||||
cmsFloat64Number ISum;
|
||||
|
||||
ISum = 1./(Source -> X + Source -> Y + Source -> Z);
|
||||
|
||||
Dest -> x = (Source -> X) * ISum;
|
||||
Dest -> y = (Source -> Y) * ISum;
|
||||
Dest -> Y = Source -> Y;
|
||||
}
|
||||
|
||||
void CMSEXPORT cmsxyY2XYZ(cmsCIEXYZ* Dest, const cmsCIExyY* Source)
|
||||
{
|
||||
Dest -> X = (Source -> x / Source -> y) * Source -> Y;
|
||||
Dest -> Y = Source -> Y;
|
||||
Dest -> Z = ((1 - Source -> x - Source -> y) / Source -> y) * Source -> Y;
|
||||
}
|
||||
|
||||
static
|
||||
cmsFloat64Number f(cmsFloat64Number t)
|
||||
{
|
||||
const cmsFloat64Number Limit = (24.0/116.0) * (24.0/116.0) * (24.0/116.0);
|
||||
|
||||
if (t <= Limit)
|
||||
return (841.0/108.0) * t + (16.0/116.0);
|
||||
else
|
||||
return pow(t, 1.0/3.0);
|
||||
}
|
||||
|
||||
static
|
||||
cmsFloat64Number f_1(cmsFloat64Number t)
|
||||
{
|
||||
const cmsFloat64Number Limit = (24.0/116.0);
|
||||
|
||||
if (t <= Limit) {
|
||||
return (108.0/841.0) * (t - (16.0/116.0));
|
||||
}
|
||||
|
||||
return t * t * t;
|
||||
}
|
||||
|
||||
|
||||
// Standard XYZ to Lab. it can handle negative XZY numbers in some cases
|
||||
void CMSEXPORT cmsXYZ2Lab(const cmsCIEXYZ* WhitePoint, cmsCIELab* Lab, const cmsCIEXYZ* xyz)
|
||||
{
|
||||
cmsFloat64Number fx, fy, fz;
|
||||
|
||||
if (WhitePoint == NULL)
|
||||
WhitePoint = cmsD50_XYZ();
|
||||
|
||||
fx = f(xyz->X / WhitePoint->X);
|
||||
fy = f(xyz->Y / WhitePoint->Y);
|
||||
fz = f(xyz->Z / WhitePoint->Z);
|
||||
|
||||
Lab->L = 116.0*fy - 16.0;
|
||||
Lab->a = 500.0*(fx - fy);
|
||||
Lab->b = 200.0*(fy - fz);
|
||||
}
|
||||
|
||||
|
||||
// Standard XYZ to Lab. It can return negative XYZ in some cases
|
||||
void CMSEXPORT cmsLab2XYZ(const cmsCIEXYZ* WhitePoint, cmsCIEXYZ* xyz, const cmsCIELab* Lab)
|
||||
{
|
||||
cmsFloat64Number x, y, z;
|
||||
|
||||
if (WhitePoint == NULL)
|
||||
WhitePoint = cmsD50_XYZ();
|
||||
|
||||
y = (Lab-> L + 16.0) / 116.0;
|
||||
x = y + 0.002 * Lab -> a;
|
||||
z = y - 0.005 * Lab -> b;
|
||||
|
||||
xyz -> X = f_1(x) * WhitePoint -> X;
|
||||
xyz -> Y = f_1(y) * WhitePoint -> Y;
|
||||
xyz -> Z = f_1(z) * WhitePoint -> Z;
|
||||
|
||||
}
|
||||
|
||||
static
|
||||
cmsFloat64Number L2float2(cmsUInt16Number v)
|
||||
{
|
||||
return (cmsFloat64Number) v / 652.800;
|
||||
}
|
||||
|
||||
// the a/b part
|
||||
static
|
||||
cmsFloat64Number ab2float2(cmsUInt16Number v)
|
||||
{
|
||||
return ((cmsFloat64Number) v / 256.0) - 128.0;
|
||||
}
|
||||
|
||||
static
|
||||
cmsUInt16Number L2Fix2(cmsFloat64Number L)
|
||||
{
|
||||
return _cmsQuickSaturateWord(L * 652.8);
|
||||
}
|
||||
|
||||
static
|
||||
cmsUInt16Number ab2Fix2(cmsFloat64Number ab)
|
||||
{
|
||||
return _cmsQuickSaturateWord((ab + 128.0) * 256.0);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
cmsFloat64Number L2float4(cmsUInt16Number v)
|
||||
{
|
||||
return (cmsFloat64Number) v / 655.35;
|
||||
}
|
||||
|
||||
// the a/b part
|
||||
static
|
||||
cmsFloat64Number ab2float4(cmsUInt16Number v)
|
||||
{
|
||||
return ((cmsFloat64Number) v / 257.0) - 128.0;
|
||||
}
|
||||
|
||||
|
||||
void CMSEXPORT cmsLabEncoded2FloatV2(cmsCIELab* Lab, const cmsUInt16Number wLab[3])
|
||||
{
|
||||
Lab->L = L2float2(wLab[0]);
|
||||
Lab->a = ab2float2(wLab[1]);
|
||||
Lab->b = ab2float2(wLab[2]);
|
||||
}
|
||||
|
||||
|
||||
void CMSEXPORT cmsLabEncoded2Float(cmsCIELab* Lab, const cmsUInt16Number wLab[3])
|
||||
{
|
||||
Lab->L = L2float4(wLab[0]);
|
||||
Lab->a = ab2float4(wLab[1]);
|
||||
Lab->b = ab2float4(wLab[2]);
|
||||
}
|
||||
|
||||
static
|
||||
cmsFloat64Number Clamp_L_doubleV2(cmsFloat64Number L)
|
||||
{
|
||||
const cmsFloat64Number L_max = (cmsFloat64Number) (0xFFFF * 100.0) / 0xFF00;
|
||||
|
||||
if (L < 0) L = 0;
|
||||
if (L > L_max) L = L_max;
|
||||
|
||||
return L;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
cmsFloat64Number Clamp_ab_doubleV2(cmsFloat64Number ab)
|
||||
{
|
||||
if (ab < MIN_ENCODEABLE_ab2) ab = MIN_ENCODEABLE_ab2;
|
||||
if (ab > MAX_ENCODEABLE_ab2) ab = MAX_ENCODEABLE_ab2;
|
||||
|
||||
return ab;
|
||||
}
|
||||
|
||||
void CMSEXPORT cmsFloat2LabEncodedV2(cmsUInt16Number wLab[3], const cmsCIELab* fLab)
|
||||
{
|
||||
cmsCIELab Lab;
|
||||
|
||||
Lab.L = Clamp_L_doubleV2(fLab ->L);
|
||||
Lab.a = Clamp_ab_doubleV2(fLab ->a);
|
||||
Lab.b = Clamp_ab_doubleV2(fLab ->b);
|
||||
|
||||
wLab[0] = L2Fix2(Lab.L);
|
||||
wLab[1] = ab2Fix2(Lab.a);
|
||||
wLab[2] = ab2Fix2(Lab.b);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
cmsFloat64Number Clamp_L_doubleV4(cmsFloat64Number L)
|
||||
{
|
||||
if (L < 0) L = 0;
|
||||
if (L > 100.0) L = 100.0;
|
||||
|
||||
return L;
|
||||
}
|
||||
|
||||
static
|
||||
cmsFloat64Number Clamp_ab_doubleV4(cmsFloat64Number ab)
|
||||
{
|
||||
if (ab < MIN_ENCODEABLE_ab4) ab = MIN_ENCODEABLE_ab4;
|
||||
if (ab > MAX_ENCODEABLE_ab4) ab = MAX_ENCODEABLE_ab4;
|
||||
|
||||
return ab;
|
||||
}
|
||||
|
||||
static
|
||||
cmsUInt16Number L2Fix4(cmsFloat64Number L)
|
||||
{
|
||||
return _cmsQuickSaturateWord(L * 655.35);
|
||||
}
|
||||
|
||||
static
|
||||
cmsUInt16Number ab2Fix4(cmsFloat64Number ab)
|
||||
{
|
||||
return _cmsQuickSaturateWord((ab + 128.0) * 257.0);
|
||||
}
|
||||
|
||||
void CMSEXPORT cmsFloat2LabEncoded(cmsUInt16Number wLab[3], const cmsCIELab* fLab)
|
||||
{
|
||||
cmsCIELab Lab;
|
||||
|
||||
Lab.L = Clamp_L_doubleV4(fLab ->L);
|
||||
Lab.a = Clamp_ab_doubleV4(fLab ->a);
|
||||
Lab.b = Clamp_ab_doubleV4(fLab ->b);
|
||||
|
||||
wLab[0] = L2Fix4(Lab.L);
|
||||
wLab[1] = ab2Fix4(Lab.a);
|
||||
wLab[2] = ab2Fix4(Lab.b);
|
||||
}
|
||||
|
||||
// Auxiliar: convert to Radians
|
||||
static
|
||||
cmsFloat64Number RADIANS(cmsFloat64Number deg)
|
||||
{
|
||||
return (deg * M_PI) / 180.;
|
||||
}
|
||||
|
||||
|
||||
// Auxiliar: atan2 but operating in degrees and returning 0 if a==b==0
|
||||
static
|
||||
cmsFloat64Number atan2deg(cmsFloat64Number a, cmsFloat64Number b)
|
||||
{
|
||||
cmsFloat64Number h;
|
||||
|
||||
if (a == 0 && b == 0)
|
||||
h = 0;
|
||||
else
|
||||
h = atan2(a, b);
|
||||
|
||||
h *= (180. / M_PI);
|
||||
|
||||
while (h > 360.)
|
||||
h -= 360.;
|
||||
|
||||
while ( h < 0)
|
||||
h += 360.;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
|
||||
// Auxiliar: Square
|
||||
static
|
||||
cmsFloat64Number Sqr(cmsFloat64Number v)
|
||||
{
|
||||
return v * v;
|
||||
}
|
||||
// From cylindrical coordinates. No check is performed, then negative values are allowed
|
||||
void CMSEXPORT cmsLab2LCh(cmsCIELCh* LCh, const cmsCIELab* Lab)
|
||||
{
|
||||
LCh -> L = Lab -> L;
|
||||
LCh -> C = pow(Sqr(Lab ->a) + Sqr(Lab ->b), 0.5);
|
||||
LCh -> h = atan2deg(Lab ->b, Lab ->a);
|
||||
}
|
||||
|
||||
|
||||
// To cylindrical coordinates. No check is performed, then negative values are allowed
|
||||
void CMSEXPORT cmsLCh2Lab(cmsCIELab* Lab, const cmsCIELCh* LCh)
|
||||
{
|
||||
cmsFloat64Number h = (LCh -> h * M_PI) / 180.0;
|
||||
|
||||
Lab -> L = LCh -> L;
|
||||
Lab -> a = LCh -> C * cos(h);
|
||||
Lab -> b = LCh -> C * sin(h);
|
||||
}
|
||||
|
||||
// In XYZ All 3 components are encoded using 1.15 fixed point
|
||||
static
|
||||
cmsUInt16Number XYZ2Fix(cmsFloat64Number d)
|
||||
{
|
||||
return _cmsQuickSaturateWord(d * 32768.0);
|
||||
}
|
||||
|
||||
void CMSEXPORT cmsFloat2XYZEncoded(cmsUInt16Number XYZ[3], const cmsCIEXYZ* fXYZ)
|
||||
{
|
||||
cmsCIEXYZ xyz;
|
||||
|
||||
xyz.X = fXYZ -> X;
|
||||
xyz.Y = fXYZ -> Y;
|
||||
xyz.Z = fXYZ -> Z;
|
||||
|
||||
// Clamp to encodeable values.
|
||||
if (xyz.Y <= 0) {
|
||||
|
||||
xyz.X = 0;
|
||||
xyz.Y = 0;
|
||||
xyz.Z = 0;
|
||||
}
|
||||
|
||||
if (xyz.X > MAX_ENCODEABLE_XYZ)
|
||||
xyz.X = MAX_ENCODEABLE_XYZ;
|
||||
|
||||
if (xyz.X < 0)
|
||||
xyz.X = 0;
|
||||
|
||||
if (xyz.Y > MAX_ENCODEABLE_XYZ)
|
||||
xyz.Y = MAX_ENCODEABLE_XYZ;
|
||||
|
||||
if (xyz.Y < 0)
|
||||
xyz.Y = 0;
|
||||
|
||||
if (xyz.Z > MAX_ENCODEABLE_XYZ)
|
||||
xyz.Z = MAX_ENCODEABLE_XYZ;
|
||||
|
||||
if (xyz.Z < 0)
|
||||
xyz.Z = 0;
|
||||
|
||||
|
||||
XYZ[0] = XYZ2Fix(xyz.X);
|
||||
XYZ[1] = XYZ2Fix(xyz.Y);
|
||||
XYZ[2] = XYZ2Fix(xyz.Z);
|
||||
}
|
||||
|
||||
|
||||
// To convert from Fixed 1.15 point to cmsFloat64Number
|
||||
static
|
||||
cmsFloat64Number XYZ2float(cmsUInt16Number v)
|
||||
{
|
||||
cmsS15Fixed16Number fix32;
|
||||
|
||||
// From 1.15 to 15.16
|
||||
fix32 = v << 1;
|
||||
|
||||
// From fixed 15.16 to cmsFloat64Number
|
||||
return _cms15Fixed16toDouble(fix32);
|
||||
}
|
||||
|
||||
|
||||
void CMSEXPORT cmsXYZEncoded2Float(cmsCIEXYZ* fXYZ, const cmsUInt16Number XYZ[3])
|
||||
{
|
||||
fXYZ -> X = XYZ2float(XYZ[0]);
|
||||
fXYZ -> Y = XYZ2float(XYZ[1]);
|
||||
fXYZ -> Z = XYZ2float(XYZ[2]);
|
||||
}
|
||||
|
||||
|
||||
// Returns dE on two Lab values
|
||||
cmsFloat64Number CMSEXPORT cmsDeltaE(const cmsCIELab* Lab1, const cmsCIELab* Lab2)
|
||||
{
|
||||
cmsFloat64Number dL, da, db;
|
||||
|
||||
dL = fabs(Lab1 -> L - Lab2 -> L);
|
||||
da = fabs(Lab1 -> a - Lab2 -> a);
|
||||
db = fabs(Lab1 -> b - Lab2 -> b);
|
||||
|
||||
return pow(Sqr(dL) + Sqr(da) + Sqr(db), 0.5);
|
||||
}
|
||||
|
||||
|
||||
// Return the CIE94 Delta E
|
||||
cmsFloat64Number CMSEXPORT cmsCIE94DeltaE(const cmsCIELab* Lab1, const cmsCIELab* Lab2)
|
||||
{
|
||||
cmsCIELCh LCh1, LCh2;
|
||||
cmsFloat64Number dE, dL, dC, dh, dhsq;
|
||||
cmsFloat64Number c12, sc, sh;
|
||||
|
||||
dL = fabs(Lab1 ->L - Lab2 ->L);
|
||||
|
||||
cmsLab2LCh(&LCh1, Lab1);
|
||||
cmsLab2LCh(&LCh2, Lab2);
|
||||
|
||||
dC = fabs(LCh1.C - LCh2.C);
|
||||
dE = cmsDeltaE(Lab1, Lab2);
|
||||
|
||||
dhsq = Sqr(dE) - Sqr(dL) - Sqr(dC);
|
||||
if (dhsq < 0)
|
||||
dh = 0;
|
||||
else
|
||||
dh = pow(dhsq, 0.5);
|
||||
|
||||
c12 = sqrt(LCh1.C * LCh2.C);
|
||||
|
||||
sc = 1.0 + (0.048 * c12);
|
||||
sh = 1.0 + (0.014 * c12);
|
||||
|
||||
return sqrt(Sqr(dL) + Sqr(dC) / Sqr(sc) + Sqr(dh) / Sqr(sh));
|
||||
}
|
||||
|
||||
|
||||
// Auxiliary
|
||||
static
|
||||
cmsFloat64Number ComputeLBFD(const cmsCIELab* Lab)
|
||||
{
|
||||
cmsFloat64Number yt;
|
||||
|
||||
if (Lab->L > 7.996969)
|
||||
yt = (Sqr((Lab->L+16)/116)*((Lab->L+16)/116))*100;
|
||||
else
|
||||
yt = 100 * (Lab->L / 903.3);
|
||||
|
||||
return (54.6 * (M_LOG10E * (log(yt + 1.5))) - 9.6);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// bfd - gets BFD(1:1) difference between Lab1, Lab2
|
||||
cmsFloat64Number CMSEXPORT cmsBFDdeltaE(const cmsCIELab* Lab1, const cmsCIELab* Lab2)
|
||||
{
|
||||
cmsFloat64Number lbfd1,lbfd2,AveC,Aveh,dE,deltaL,
|
||||
deltaC,deltah,dc,t,g,dh,rh,rc,rt,bfd;
|
||||
cmsCIELCh LCh1, LCh2;
|
||||
|
||||
|
||||
lbfd1 = ComputeLBFD(Lab1);
|
||||
lbfd2 = ComputeLBFD(Lab2);
|
||||
deltaL = lbfd2 - lbfd1;
|
||||
|
||||
cmsLab2LCh(&LCh1, Lab1);
|
||||
cmsLab2LCh(&LCh2, Lab2);
|
||||
|
||||
deltaC = LCh2.C - LCh1.C;
|
||||
AveC = (LCh1.C+LCh2.C)/2;
|
||||
Aveh = (LCh1.h+LCh2.h)/2;
|
||||
|
||||
dE = cmsDeltaE(Lab1, Lab2);
|
||||
|
||||
if (Sqr(dE)>(Sqr(Lab2->L-Lab1->L)+Sqr(deltaC)))
|
||||
deltah = sqrt(Sqr(dE)-Sqr(Lab2->L-Lab1->L)-Sqr(deltaC));
|
||||
else
|
||||
deltah =0;
|
||||
|
||||
|
||||
dc = 0.035 * AveC / (1 + 0.00365 * AveC)+0.521;
|
||||
g = sqrt(Sqr(Sqr(AveC))/(Sqr(Sqr(AveC))+14000));
|
||||
t = 0.627+(0.055*cos((Aveh-254)/(180/M_PI))-
|
||||
0.040*cos((2*Aveh-136)/(180/M_PI))+
|
||||
0.070*cos((3*Aveh-31)/(180/M_PI))+
|
||||
0.049*cos((4*Aveh+114)/(180/M_PI))-
|
||||
0.015*cos((5*Aveh-103)/(180/M_PI)));
|
||||
|
||||
dh = dc*(g*t+1-g);
|
||||
rh = -0.260*cos((Aveh-308)/(180/M_PI))-
|
||||
0.379*cos((2*Aveh-160)/(180/M_PI))-
|
||||
0.636*cos((3*Aveh+254)/(180/M_PI))+
|
||||
0.226*cos((4*Aveh+140)/(180/M_PI))-
|
||||
0.194*cos((5*Aveh+280)/(180/M_PI));
|
||||
|
||||
rc = sqrt((AveC*AveC*AveC*AveC*AveC*AveC)/((AveC*AveC*AveC*AveC*AveC*AveC)+70000000));
|
||||
rt = rh*rc;
|
||||
|
||||
bfd = sqrt(Sqr(deltaL)+Sqr(deltaC/dc)+Sqr(deltah/dh)+(rt*(deltaC/dc)*(deltah/dh)));
|
||||
|
||||
return bfd;
|
||||
}
|
||||
|
||||
|
||||
// cmc - CMC(l:c) difference between Lab1, Lab2
|
||||
cmsFloat64Number CMSEXPORT cmsCMCdeltaE(const cmsCIELab* Lab1, const cmsCIELab* Lab2, cmsFloat64Number l, cmsFloat64Number c)
|
||||
{
|
||||
cmsFloat64Number dE,dL,dC,dh,sl,sc,sh,t,f,cmc;
|
||||
cmsCIELCh LCh1, LCh2;
|
||||
|
||||
if (Lab1 ->L == 0 && Lab2 ->L == 0) return 0;
|
||||
|
||||
cmsLab2LCh(&LCh1, Lab1);
|
||||
cmsLab2LCh(&LCh2, Lab2);
|
||||
|
||||
|
||||
dL = Lab2->L-Lab1->L;
|
||||
dC = LCh2.C-LCh1.C;
|
||||
|
||||
dE = cmsDeltaE(Lab1, Lab2);
|
||||
|
||||
if (Sqr(dE)>(Sqr(dL)+Sqr(dC)))
|
||||
dh = sqrt(Sqr(dE)-Sqr(dL)-Sqr(dC));
|
||||
else
|
||||
dh =0;
|
||||
|
||||
if ((LCh1.h > 164) && (LCh1.h < 345))
|
||||
t = 0.56 + fabs(0.2 * cos(((LCh1.h + 168)/(180/M_PI))));
|
||||
else
|
||||
t = 0.36 + fabs(0.4 * cos(((LCh1.h + 35 )/(180/M_PI))));
|
||||
|
||||
sc = 0.0638 * LCh1.C / (1 + 0.0131 * LCh1.C) + 0.638;
|
||||
sl = 0.040975 * Lab1->L /(1 + 0.01765 * Lab1->L);
|
||||
|
||||
if (Lab1->L<16)
|
||||
sl = 0.511;
|
||||
|
||||
f = sqrt((LCh1.C * LCh1.C * LCh1.C * LCh1.C)/((LCh1.C * LCh1.C * LCh1.C * LCh1.C)+1900));
|
||||
sh = sc*(t*f+1-f);
|
||||
cmc = sqrt(Sqr(dL/(l*sl))+Sqr(dC/(c*sc))+Sqr(dh/sh));
|
||||
|
||||
return cmc;
|
||||
}
|
||||
|
||||
// dE2000 The weightings KL, KC and KH can be modified to reflect the relative
|
||||
// importance of lightness, chroma and hue in different industrial applications
|
||||
cmsFloat64Number CMSEXPORT cmsCIE2000DeltaE(const cmsCIELab* Lab1, const cmsCIELab* Lab2,
|
||||
cmsFloat64Number Kl, cmsFloat64Number Kc, cmsFloat64Number Kh)
|
||||
{
|
||||
cmsFloat64Number L1 = Lab1->L;
|
||||
cmsFloat64Number a1 = Lab1->a;
|
||||
cmsFloat64Number b1 = Lab1->b;
|
||||
cmsFloat64Number C = sqrt( Sqr(a1) + Sqr(b1) );
|
||||
|
||||
cmsFloat64Number Ls = Lab2 ->L;
|
||||
cmsFloat64Number as = Lab2 ->a;
|
||||
cmsFloat64Number bs = Lab2 ->b;
|
||||
cmsFloat64Number Cs = sqrt( Sqr(as) + Sqr(bs) );
|
||||
|
||||
cmsFloat64Number G = 0.5 * ( 1 - sqrt(pow((C + Cs) / 2 , 7.0) / (pow((C + Cs) / 2, 7.0) + pow(25.0, 7.0) ) ));
|
||||
|
||||
cmsFloat64Number a_p = (1 + G ) * a1;
|
||||
cmsFloat64Number b_p = b1;
|
||||
cmsFloat64Number C_p = sqrt( Sqr(a_p) + Sqr(b_p));
|
||||
cmsFloat64Number h_p = atan2deg(b_p, a_p);
|
||||
|
||||
|
||||
cmsFloat64Number a_ps = (1 + G) * as;
|
||||
cmsFloat64Number b_ps = bs;
|
||||
cmsFloat64Number C_ps = sqrt(Sqr(a_ps) + Sqr(b_ps));
|
||||
cmsFloat64Number h_ps = atan2deg(b_ps, a_ps);
|
||||
|
||||
cmsFloat64Number meanC_p =(C_p + C_ps) / 2;
|
||||
|
||||
cmsFloat64Number hps_plus_hp = h_ps + h_p;
|
||||
cmsFloat64Number hps_minus_hp = h_ps - h_p;
|
||||
|
||||
cmsFloat64Number meanh_p = fabs(hps_minus_hp) <= 180.000001 ? (hps_plus_hp)/2 :
|
||||
(hps_plus_hp) < 360 ? (hps_plus_hp + 360)/2 :
|
||||
(hps_plus_hp - 360)/2;
|
||||
|
||||
cmsFloat64Number delta_h = (hps_minus_hp) <= -180.000001 ? (hps_minus_hp + 360) :
|
||||
(hps_minus_hp) > 180 ? (hps_minus_hp - 360) :
|
||||
(hps_minus_hp);
|
||||
cmsFloat64Number delta_L = (Ls - L1);
|
||||
cmsFloat64Number delta_C = (C_ps - C_p );
|
||||
|
||||
|
||||
cmsFloat64Number delta_H =2 * sqrt(C_ps*C_p) * sin(RADIANS(delta_h) / 2);
|
||||
|
||||
cmsFloat64Number T = 1 - 0.17 * cos(RADIANS(meanh_p-30))
|
||||
+ 0.24 * cos(RADIANS(2*meanh_p))
|
||||
+ 0.32 * cos(RADIANS(3*meanh_p + 6))
|
||||
- 0.2 * cos(RADIANS(4*meanh_p - 63));
|
||||
|
||||
cmsFloat64Number Sl = 1 + (0.015 * Sqr((Ls + L1) /2- 50) )/ sqrt(20 + Sqr( (Ls+L1)/2 - 50) );
|
||||
|
||||
cmsFloat64Number Sc = 1 + 0.045 * (C_p + C_ps)/2;
|
||||
cmsFloat64Number Sh = 1 + 0.015 * ((C_ps + C_p)/2) * T;
|
||||
|
||||
cmsFloat64Number delta_ro = 30 * exp( -Sqr(((meanh_p - 275 ) / 25)));
|
||||
|
||||
cmsFloat64Number Rc = 2 * sqrt(( pow(meanC_p, 7.0) )/( pow(meanC_p, 7.0) + pow(25.0, 7.0)));
|
||||
|
||||
cmsFloat64Number Rt = -sin(2 * RADIANS(delta_ro)) * Rc;
|
||||
|
||||
cmsFloat64Number deltaE00 = sqrt( Sqr(delta_L /(Sl * Kl)) +
|
||||
Sqr(delta_C/(Sc * Kc)) +
|
||||
Sqr(delta_H/(Sh * Kh)) +
|
||||
Rt*(delta_C/(Sc * Kc)) * (delta_H / (Sh * Kh)));
|
||||
|
||||
return deltaE00;
|
||||
}
|
||||
|
||||
// This function returns a number of gridpoints to be used as LUT table. It assumes same number
|
||||
// of gripdpoints in all dimensions. Flags may override the choice.
|
||||
int _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags)
|
||||
{
|
||||
int nChannels;
|
||||
|
||||
// Already specified?
|
||||
if (dwFlags & 0x00FF0000) {
|
||||
// Yes, grab'em
|
||||
return (dwFlags >> 16) & 0xFF;
|
||||
}
|
||||
|
||||
nChannels = cmsChannelsOf(Colorspace);
|
||||
|
||||
// HighResPrecalc is maximum resolution
|
||||
if (dwFlags & cmsFLAGS_HIGHRESPRECALC) {
|
||||
|
||||
if (nChannels > 4)
|
||||
return 7; // 7 for Hifi
|
||||
|
||||
if (nChannels == 4) // 23 for CMYK
|
||||
return 23;
|
||||
|
||||
return 49; // 49 for RGB and others
|
||||
}
|
||||
|
||||
|
||||
// LowResPrecal is lower resolution
|
||||
if (dwFlags & cmsFLAGS_LOWRESPRECALC) {
|
||||
|
||||
if (nChannels > 4)
|
||||
return 6; // 6 for more than 4 channels
|
||||
|
||||
if (nChannels == 1)
|
||||
return 33; // For monochrome
|
||||
|
||||
return 17; // 17 for remaining
|
||||
}
|
||||
|
||||
// Default values
|
||||
if (nChannels > 4)
|
||||
return 7; // 7 for Hifi
|
||||
|
||||
if (nChannels == 4)
|
||||
return 17; // 17 for CMYK
|
||||
|
||||
return 33; // 33 for RGB
|
||||
}
|
||||
|
||||
|
||||
cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
|
||||
cmsUInt16Number **White,
|
||||
cmsUInt16Number **Black,
|
||||
cmsUInt32Number *nOutputs)
|
||||
{
|
||||
// Only most common spaces
|
||||
|
||||
static cmsUInt16Number RGBblack[4] = { 0, 0, 0 };
|
||||
static cmsUInt16Number RGBwhite[4] = { 0xffff, 0xffff, 0xffff };
|
||||
static cmsUInt16Number CMYKblack[4] = { 0xffff, 0xffff, 0xffff, 0xffff }; // 400% of ink
|
||||
static cmsUInt16Number CMYKwhite[4] = { 0, 0, 0, 0 };
|
||||
static cmsUInt16Number LABblack[4] = { 0, 0x8080, 0x8080 }; // V4 Lab encoding
|
||||
static cmsUInt16Number LABwhite[4] = { 0xFFFF, 0x8080, 0x8080 };
|
||||
static cmsUInt16Number CMYblack[4] = { 0xffff, 0xffff, 0xffff };
|
||||
static cmsUInt16Number CMYwhite[4] = { 0, 0, 0 };
|
||||
static cmsUInt16Number Grayblack[4] = { 0 };
|
||||
static cmsUInt16Number GrayWhite[4] = { 0xffff };
|
||||
|
||||
switch (Space) {
|
||||
|
||||
case cmsSigGrayData: if (White) *White = GrayWhite;
|
||||
if (Black) *Black = Grayblack;
|
||||
if (nOutputs) *nOutputs = 1;
|
||||
return TRUE;
|
||||
|
||||
case cmsSigRgbData: if (White) *White = RGBwhite;
|
||||
if (Black) *Black = RGBblack;
|
||||
if (nOutputs) *nOutputs = 3;
|
||||
return TRUE;
|
||||
|
||||
case cmsSigLabData: if (White) *White = LABwhite;
|
||||
if (Black) *Black = LABblack;
|
||||
if (nOutputs) *nOutputs = 3;
|
||||
return TRUE;
|
||||
|
||||
case cmsSigCmykData: if (White) *White = CMYKwhite;
|
||||
if (Black) *Black = CMYKblack;
|
||||
if (nOutputs) *nOutputs = 4;
|
||||
return TRUE;
|
||||
|
||||
case cmsSigCmyData: if (White) *White = CMYwhite;
|
||||
if (Black) *Black = CMYblack;
|
||||
if (nOutputs) *nOutputs = 3;
|
||||
return TRUE;
|
||||
|
||||
default:;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Several utilities -------------------------------------------------------
|
||||
|
||||
// Translate from our colorspace to ICC representation
|
||||
|
||||
cmsColorSpaceSignature CMSEXPORT _cmsICCcolorSpace(int OurNotation)
|
||||
{
|
||||
switch (OurNotation) {
|
||||
|
||||
case 1:
|
||||
case PT_GRAY: return cmsSigGrayData;
|
||||
|
||||
case 2:
|
||||
case PT_RGB: return cmsSigRgbData;
|
||||
|
||||
case PT_CMY: return cmsSigCmyData;
|
||||
case PT_CMYK: return cmsSigCmykData;
|
||||
case PT_YCbCr:return cmsSigYCbCrData;
|
||||
case PT_YUV: return cmsSigLuvData;
|
||||
case PT_XYZ: return cmsSigXYZData;
|
||||
|
||||
case PT_LabV2:
|
||||
case PT_Lab: return cmsSigLabData;
|
||||
|
||||
case PT_YUVK: return cmsSigLuvKData;
|
||||
case PT_HSV: return cmsSigHsvData;
|
||||
case PT_HLS: return cmsSigHlsData;
|
||||
case PT_Yxy: return cmsSigYxyData;
|
||||
|
||||
case PT_MCH1: return cmsSigMCH1Data;
|
||||
case PT_MCH2: return cmsSigMCH2Data;
|
||||
case PT_MCH3: return cmsSigMCH3Data;
|
||||
case PT_MCH4: return cmsSigMCH4Data;
|
||||
case PT_MCH5: return cmsSigMCH5Data;
|
||||
case PT_MCH6: return cmsSigMCH6Data;
|
||||
case PT_MCH7: return cmsSigMCH7Data;
|
||||
case PT_MCH8: return cmsSigMCH8Data;
|
||||
|
||||
case PT_MCH9: return cmsSigMCH9Data;
|
||||
case PT_MCH10: return cmsSigMCHAData;
|
||||
case PT_MCH11: return cmsSigMCHBData;
|
||||
case PT_MCH12: return cmsSigMCHCData;
|
||||
case PT_MCH13: return cmsSigMCHDData;
|
||||
case PT_MCH14: return cmsSigMCHEData;
|
||||
case PT_MCH15: return cmsSigMCHFData;
|
||||
|
||||
default: return (cmsColorSpaceSignature) (-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int CMSEXPORT _cmsLCMScolorSpace(cmsColorSpaceSignature ProfileSpace)
|
||||
{
|
||||
switch (ProfileSpace) {
|
||||
|
||||
case cmsSigGrayData: return PT_GRAY;
|
||||
case cmsSigRgbData: return PT_RGB;
|
||||
case cmsSigCmyData: return PT_CMY;
|
||||
case cmsSigCmykData: return PT_CMYK;
|
||||
case cmsSigYCbCrData:return PT_YCbCr;
|
||||
case cmsSigLuvData: return PT_YUV;
|
||||
case cmsSigXYZData: return PT_XYZ;
|
||||
case cmsSigLabData: return PT_Lab;
|
||||
case cmsSigLuvKData: return PT_YUVK;
|
||||
case cmsSigHsvData: return PT_HSV;
|
||||
case cmsSigHlsData: return PT_HLS;
|
||||
case cmsSigYxyData: return PT_Yxy;
|
||||
|
||||
case cmsSig1colorData:
|
||||
case cmsSigMCH1Data: return PT_MCH1;
|
||||
|
||||
case cmsSig2colorData:
|
||||
case cmsSigMCH2Data: return PT_MCH2;
|
||||
|
||||
case cmsSig3colorData:
|
||||
case cmsSigMCH3Data: return PT_MCH3;
|
||||
|
||||
case cmsSig4colorData:
|
||||
case cmsSigMCH4Data: return PT_MCH4;
|
||||
|
||||
case cmsSig5colorData:
|
||||
case cmsSigMCH5Data: return PT_MCH5;
|
||||
|
||||
case cmsSig6colorData:
|
||||
case cmsSigMCH6Data: return PT_MCH6;
|
||||
|
||||
case cmsSigMCH7Data:
|
||||
case cmsSig7colorData:return PT_MCH7;
|
||||
|
||||
case cmsSigMCH8Data:
|
||||
case cmsSig8colorData:return PT_MCH8;
|
||||
|
||||
case cmsSigMCH9Data:
|
||||
case cmsSig9colorData:return PT_MCH9;
|
||||
|
||||
case cmsSigMCHAData:
|
||||
case cmsSig10colorData:return PT_MCH10;
|
||||
|
||||
case cmsSigMCHBData:
|
||||
case cmsSig11colorData:return PT_MCH11;
|
||||
|
||||
case cmsSigMCHCData:
|
||||
case cmsSig12colorData:return PT_MCH12;
|
||||
|
||||
case cmsSigMCHDData:
|
||||
case cmsSig13colorData:return PT_MCH13;
|
||||
|
||||
case cmsSigMCHEData:
|
||||
case cmsSig14colorData:return PT_MCH14;
|
||||
|
||||
case cmsSigMCHFData:
|
||||
case cmsSig15colorData:return PT_MCH15;
|
||||
|
||||
default: return (cmsColorSpaceSignature) (-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cmsUInt32Number CMSEXPORT cmsChannelsOf(cmsColorSpaceSignature ColorSpace)
|
||||
{
|
||||
switch (ColorSpace) {
|
||||
|
||||
case cmsSigGrayData: return 1;
|
||||
|
||||
case cmsSig2colorData: return 2;
|
||||
|
||||
case cmsSigXYZData:
|
||||
case cmsSigLabData:
|
||||
case cmsSigLuvData:
|
||||
case cmsSigYCbCrData:
|
||||
case cmsSigYxyData:
|
||||
case cmsSigRgbData:
|
||||
case cmsSigHsvData:
|
||||
case cmsSigHlsData:
|
||||
case cmsSigCmyData:
|
||||
case cmsSig3colorData: return 3;
|
||||
|
||||
case cmsSigLuvKData:
|
||||
case cmsSigCmykData:
|
||||
case cmsSig4colorData: return 4;
|
||||
|
||||
case cmsSigMCH5Data:
|
||||
case cmsSig5colorData: return 5;
|
||||
|
||||
case cmsSigMCH6Data:
|
||||
case cmsSig6colorData: return 6;
|
||||
|
||||
case cmsSigMCH7Data:
|
||||
case cmsSig7colorData: return 7;
|
||||
|
||||
case cmsSigMCH8Data:
|
||||
case cmsSig8colorData: return 8;
|
||||
|
||||
case cmsSigMCH9Data:
|
||||
case cmsSig9colorData: return 9;
|
||||
|
||||
case cmsSigMCHAData:
|
||||
case cmsSig10colorData: return 10;
|
||||
|
||||
case cmsSigMCHBData:
|
||||
case cmsSig11colorData: return 11;
|
||||
|
||||
case cmsSigMCHCData:
|
||||
case cmsSig12colorData: return 12;
|
||||
|
||||
case cmsSigMCHDData:
|
||||
case cmsSig13colorData: return 13;
|
||||
|
||||
case cmsSigMCHEData:
|
||||
case cmsSig14colorData: return 14;
|
||||
|
||||
case cmsSigMCHFData:
|
||||
case cmsSig15colorData: return 15;
|
||||
|
||||
default: return 3;
|
||||
}
|
||||
}
|
612
thirdparty/liblcms2/src/cmsplugin.c
vendored
Normal file
612
thirdparty/liblcms2/src/cmsplugin.c
vendored
Normal file
@ -0,0 +1,612 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
//
|
||||
// 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 "lcms2_internal.h"
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
// Encoding & Decoding support functions
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
||||
// Little-Endian to Big-Endian
|
||||
|
||||
// Adjust a word value after being readed/ before being written from/to an ICC profile
|
||||
cmsUInt16Number CMSEXPORT _cmsAdjustEndianess16(cmsUInt16Number Word)
|
||||
{
|
||||
#ifndef CMS_USE_BIG_ENDIAN
|
||||
|
||||
cmsUInt8Number* pByte = (cmsUInt8Number*) &Word;
|
||||
cmsUInt8Number tmp;
|
||||
|
||||
tmp = pByte[0];
|
||||
pByte[0] = pByte[1];
|
||||
pByte[1] = tmp;
|
||||
#endif
|
||||
|
||||
return Word;
|
||||
}
|
||||
|
||||
|
||||
// Transports to properly encoded values - note that icc profiles does use big endian notation.
|
||||
|
||||
// 1 2 3 4
|
||||
// 4 3 2 1
|
||||
|
||||
cmsUInt32Number CMSEXPORT _cmsAdjustEndianess32(cmsUInt32Number DWord)
|
||||
{
|
||||
#ifndef CMS_USE_BIG_ENDIAN
|
||||
|
||||
cmsUInt8Number* pByte = (cmsUInt8Number*) &DWord;
|
||||
cmsUInt8Number temp1;
|
||||
cmsUInt8Number temp2;
|
||||
|
||||
temp1 = *pByte++;
|
||||
temp2 = *pByte++;
|
||||
*(pByte-1) = *pByte;
|
||||
*pByte++ = temp2;
|
||||
*(pByte-3) = *pByte;
|
||||
*pByte = temp1;
|
||||
#endif
|
||||
return DWord;
|
||||
}
|
||||
|
||||
// 1 2 3 4 5 6 7 8
|
||||
// 8 7 6 5 4 3 2 1
|
||||
|
||||
void CMSEXPORT _cmsAdjustEndianess64(cmsUInt64Number* Result, cmsUInt64Number QWord)
|
||||
{
|
||||
|
||||
#ifndef CMS_USE_BIG_ENDIAN
|
||||
|
||||
cmsUInt8Number* pIn = (cmsUInt8Number*) &QWord;
|
||||
cmsUInt8Number* pOut = (cmsUInt8Number*) Result;
|
||||
|
||||
_cmsAssert(Result != NULL);
|
||||
|
||||
pOut[7] = pIn[0];
|
||||
pOut[6] = pIn[1];
|
||||
pOut[5] = pIn[2];
|
||||
pOut[4] = pIn[3];
|
||||
pOut[3] = pIn[4];
|
||||
pOut[2] = pIn[5];
|
||||
pOut[1] = pIn[6];
|
||||
pOut[0] = pIn[7];
|
||||
|
||||
#else
|
||||
|
||||
_cmsAssert(Result != NULL);
|
||||
|
||||
*Result = QWord;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Auxiliar -- read 8, 16 and 32-bit numbers
|
||||
cmsBool CMSEXPORT _cmsReadUInt8Number(cmsIOHANDLER* io, cmsUInt8Number* n)
|
||||
{
|
||||
cmsUInt8Number tmp;
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
if (io -> Read(io, &tmp, sizeof(cmsUInt8Number), 1) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (n != NULL) *n = tmp;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
cmsBool CMSEXPORT _cmsReadUInt16Number(cmsIOHANDLER* io, cmsUInt16Number* n)
|
||||
{
|
||||
cmsUInt16Number tmp;
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
if (io -> Read(io, &tmp, sizeof(cmsUInt16Number), 1) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (n != NULL) *n = _cmsAdjustEndianess16(tmp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
cmsBool CMSEXPORT _cmsReadUInt16Array(cmsIOHANDLER* io, cmsUInt32Number n, cmsUInt16Number* Array)
|
||||
{
|
||||
cmsUInt32Number i;
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
for (i=0; i < n; i++) {
|
||||
|
||||
if (Array != NULL) {
|
||||
if (!_cmsReadUInt16Number(io, Array + i)) return FALSE;
|
||||
}
|
||||
else {
|
||||
if (!_cmsReadUInt16Number(io, NULL)) return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
cmsBool CMSEXPORT _cmsReadUInt32Number(cmsIOHANDLER* io, cmsUInt32Number* n)
|
||||
{
|
||||
cmsUInt32Number tmp;
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
if (io -> Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (n != NULL) *n = _cmsAdjustEndianess32(tmp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
cmsBool CMSEXPORT _cmsReadFloat32Number(cmsIOHANDLER* io, cmsFloat32Number* n)
|
||||
{
|
||||
cmsUInt32Number tmp;
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
if (io -> Read(io, &tmp, sizeof(cmsFloat32Number), 1) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (n != NULL) {
|
||||
|
||||
tmp = _cmsAdjustEndianess32(tmp);
|
||||
*n = *(cmsFloat32Number*) &tmp;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
cmsBool CMSEXPORT _cmsReadUInt64Number(cmsIOHANDLER* io, cmsUInt64Number* n)
|
||||
{
|
||||
cmsUInt64Number tmp;
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
if (io -> Read(io, &tmp, sizeof(cmsUInt64Number), 1) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (n != NULL) _cmsAdjustEndianess64(n, tmp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
cmsBool CMSEXPORT _cmsRead15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number* n)
|
||||
{
|
||||
cmsUInt32Number tmp;
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
if (io -> Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (n != NULL) {
|
||||
*n = _cms15Fixed16toDouble(_cmsAdjustEndianess32(tmp));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Jun-21-2000: Some profiles (those that comes with W2K) comes
|
||||
// with the media white (media black?) x 100. Add a sanity check
|
||||
|
||||
static
|
||||
void NormalizeXYZ(cmsCIEXYZ* Dest)
|
||||
{
|
||||
while (Dest -> X > 2. &&
|
||||
Dest -> Y > 2. &&
|
||||
Dest -> Z > 2.) {
|
||||
|
||||
Dest -> X /= 10.;
|
||||
Dest -> Y /= 10.;
|
||||
Dest -> Z /= 10.;
|
||||
}
|
||||
}
|
||||
|
||||
cmsBool CMSEXPORT _cmsReadXYZNumber(cmsIOHANDLER* io, cmsCIEXYZ* XYZ)
|
||||
{
|
||||
cmsEncodedXYZNumber xyz;
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
if (io ->Read(io, &xyz, sizeof(cmsEncodedXYZNumber), 1) != 1) return FALSE;
|
||||
|
||||
if (XYZ != NULL) {
|
||||
|
||||
XYZ->X = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.X));
|
||||
XYZ->Y = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.Y));
|
||||
XYZ->Z = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.Z));
|
||||
|
||||
NormalizeXYZ(XYZ);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
cmsBool CMSEXPORT _cmsWriteUInt8Number(cmsIOHANDLER* io, cmsUInt8Number n)
|
||||
{
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
if (io -> Write(io, sizeof(cmsUInt8Number), &n) != 1)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
cmsBool CMSEXPORT _cmsWriteUInt16Number(cmsIOHANDLER* io, cmsUInt16Number n)
|
||||
{
|
||||
cmsUInt16Number tmp;
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
tmp = _cmsAdjustEndianess16(n);
|
||||
if (io -> Write(io, sizeof(cmsUInt16Number), &tmp) != 1)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
cmsBool CMSEXPORT _cmsWriteUInt16Array(cmsIOHANDLER* io, cmsUInt32Number n, const cmsUInt16Number* Array)
|
||||
{
|
||||
cmsUInt32Number i;
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
_cmsAssert(Array != NULL);
|
||||
|
||||
for (i=0; i < n; i++) {
|
||||
if (!_cmsWriteUInt16Number(io, Array[i])) return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
cmsBool CMSEXPORT _cmsWriteUInt32Number(cmsIOHANDLER* io, cmsUInt32Number n)
|
||||
{
|
||||
cmsUInt32Number tmp;
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
tmp = _cmsAdjustEndianess32(n);
|
||||
if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
cmsBool CMSEXPORT _cmsWriteFloat32Number(cmsIOHANDLER* io, cmsFloat32Number n)
|
||||
{
|
||||
cmsUInt32Number tmp;
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
tmp = *(cmsUInt32Number*) &n;
|
||||
tmp = _cmsAdjustEndianess32(tmp);
|
||||
if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
cmsBool CMSEXPORT _cmsWriteUInt64Number(cmsIOHANDLER* io, cmsUInt64Number n)
|
||||
{
|
||||
cmsUInt64Number tmp;
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
_cmsAdjustEndianess64(&tmp, n);
|
||||
if (io -> Write(io, sizeof(cmsUInt64Number), &tmp) != 1)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
cmsBool CMSEXPORT _cmsWrite15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number n)
|
||||
{
|
||||
cmsUInt32Number tmp;
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
tmp = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(n));
|
||||
if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
cmsBool CMSEXPORT _cmsWriteXYZNumber(cmsIOHANDLER* io, const cmsCIEXYZ* XYZ)
|
||||
{
|
||||
cmsEncodedXYZNumber xyz;
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
_cmsAssert(XYZ != NULL);
|
||||
|
||||
xyz.X = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(XYZ->X));
|
||||
xyz.Y = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(XYZ->Y));
|
||||
xyz.Z = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(XYZ->Z));
|
||||
|
||||
return io -> Write(io, sizeof(cmsEncodedXYZNumber), &xyz);
|
||||
}
|
||||
|
||||
// from Fixed point 8.8 to double
|
||||
cmsFloat64Number CMSEXPORT _cms8Fixed8toDouble(cmsUInt16Number fixed8)
|
||||
{
|
||||
cmsUInt8Number msb, lsb;
|
||||
|
||||
lsb = (cmsUInt8Number) (fixed8 & 0xff);
|
||||
msb = (cmsUInt8Number) (((cmsUInt16Number) fixed8 >> 8) & 0xff);
|
||||
|
||||
return (cmsFloat64Number) ((cmsFloat64Number) msb + ((cmsFloat64Number) lsb / 256.0));
|
||||
}
|
||||
|
||||
cmsUInt16Number CMSEXPORT _cmsDoubleTo8Fixed8(cmsFloat64Number val)
|
||||
{
|
||||
cmsS15Fixed16Number GammaFixed32 = _cmsDoubleTo15Fixed16(val);
|
||||
return (cmsUInt16Number) ((GammaFixed32 >> 8) & 0xFFFF);
|
||||
}
|
||||
|
||||
// from Fixed point 15.16 to double
|
||||
cmsFloat64Number CMSEXPORT _cms15Fixed16toDouble(cmsS15Fixed16Number fix32)
|
||||
{
|
||||
cmsFloat64Number floater, sign, mid;
|
||||
int Whole, FracPart;
|
||||
|
||||
sign = (fix32 < 0 ? -1 : 1);
|
||||
fix32 = abs(fix32);
|
||||
|
||||
Whole = (cmsUInt16Number)(fix32 >> 16) & 0xffff;
|
||||
FracPart = (cmsUInt16Number)(fix32 & 0xffff);
|
||||
|
||||
mid = (cmsFloat64Number) FracPart / 65536.0;
|
||||
floater = (cmsFloat64Number) Whole + mid;
|
||||
|
||||
return sign * floater;
|
||||
}
|
||||
|
||||
// from double to Fixed point 15.16
|
||||
cmsS15Fixed16Number CMSEXPORT _cmsDoubleTo15Fixed16(cmsFloat64Number v)
|
||||
{
|
||||
return ((cmsS15Fixed16Number) floor((v)*65536.0 + 0.5));
|
||||
}
|
||||
|
||||
// Date/Time functions
|
||||
|
||||
void CMSEXPORT _cmsDecodeDateTimeNumber(const cmsDateTimeNumber *Source, struct tm *Dest)
|
||||
{
|
||||
|
||||
_cmsAssert(Dest != NULL);
|
||||
_cmsAssert(Source != NULL);
|
||||
|
||||
Dest->tm_sec = _cmsAdjustEndianess16(Source->seconds);
|
||||
Dest->tm_min = _cmsAdjustEndianess16(Source->minutes);
|
||||
Dest->tm_hour = _cmsAdjustEndianess16(Source->hours);
|
||||
Dest->tm_mday = _cmsAdjustEndianess16(Source->day);
|
||||
Dest->tm_mon = _cmsAdjustEndianess16(Source->month) - 1;
|
||||
Dest->tm_year = _cmsAdjustEndianess16(Source->year) - 1900;
|
||||
Dest->tm_wday = -1;
|
||||
Dest->tm_yday = -1;
|
||||
Dest->tm_isdst = 0;
|
||||
}
|
||||
|
||||
void CMSEXPORT _cmsEncodeDateTimeNumber(cmsDateTimeNumber *Dest, const struct tm *Source)
|
||||
{
|
||||
_cmsAssert(Dest != NULL);
|
||||
_cmsAssert(Source != NULL);
|
||||
|
||||
Dest->seconds = _cmsAdjustEndianess16((cmsUInt16Number) Source->tm_sec);
|
||||
Dest->minutes = _cmsAdjustEndianess16((cmsUInt16Number) Source->tm_min);
|
||||
Dest->hours = _cmsAdjustEndianess16((cmsUInt16Number) Source->tm_hour);
|
||||
Dest->day = _cmsAdjustEndianess16((cmsUInt16Number) Source->tm_mday);
|
||||
Dest->month = _cmsAdjustEndianess16((cmsUInt16Number) (Source->tm_mon + 1));
|
||||
Dest->year = _cmsAdjustEndianess16((cmsUInt16Number) (Source->tm_year + 1900));
|
||||
}
|
||||
|
||||
// Read base and return type base
|
||||
cmsTagTypeSignature CMSEXPORT _cmsReadTypeBase(cmsIOHANDLER* io)
|
||||
{
|
||||
_cmsTagBase Base;
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
if (io -> Read(io, &Base, sizeof(_cmsTagBase), 1) != 1)
|
||||
return (cmsTagTypeSignature) 0;
|
||||
|
||||
return (cmsTagTypeSignature) _cmsAdjustEndianess32(Base.sig);
|
||||
}
|
||||
|
||||
// Setup base marker
|
||||
cmsBool CMSEXPORT _cmsWriteTypeBase(cmsIOHANDLER* io, cmsTagTypeSignature sig)
|
||||
{
|
||||
_cmsTagBase Base;
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
Base.sig = (cmsTagTypeSignature) _cmsAdjustEndianess32(sig);
|
||||
memset(&Base.reserved, 0, sizeof(Base.reserved));
|
||||
return io -> Write(io, sizeof(_cmsTagBase), &Base);
|
||||
}
|
||||
|
||||
cmsBool CMSEXPORT _cmsReadAlignment(cmsIOHANDLER* io)
|
||||
{
|
||||
cmsUInt8Number Buffer[4];
|
||||
cmsUInt32Number NextAligned, At;
|
||||
cmsUInt32Number BytesToNextAlignedPos;
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
At = io -> Tell(io);
|
||||
NextAligned = _cmsALIGNLONG(At);
|
||||
BytesToNextAlignedPos = NextAligned - At;
|
||||
if (BytesToNextAlignedPos == 0) return TRUE;
|
||||
if (BytesToNextAlignedPos > 4) return FALSE;
|
||||
|
||||
return (io ->Read(io, Buffer, BytesToNextAlignedPos, 1) == 1);
|
||||
}
|
||||
|
||||
cmsBool CMSEXPORT _cmsWriteAlignment(cmsIOHANDLER* io)
|
||||
{
|
||||
cmsUInt8Number Buffer[4];
|
||||
cmsUInt32Number NextAligned, At;
|
||||
cmsUInt32Number BytesToNextAlignedPos;
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
At = io -> Tell(io);
|
||||
NextAligned = _cmsALIGNLONG(At);
|
||||
BytesToNextAlignedPos = NextAligned - At;
|
||||
if (BytesToNextAlignedPos == 0) return TRUE;
|
||||
if (BytesToNextAlignedPos > 4) return FALSE;
|
||||
|
||||
memset(Buffer, 0, BytesToNextAlignedPos);
|
||||
return io -> Write(io, BytesToNextAlignedPos, Buffer);
|
||||
}
|
||||
|
||||
|
||||
// To deal with text streams. 2K at most
|
||||
cmsBool CMSEXPORT _cmsIOPrintf(cmsIOHANDLER* io, const char* frm, ...)
|
||||
{
|
||||
va_list args;
|
||||
int len;
|
||||
cmsUInt8Number Buffer[2048];
|
||||
cmsBool rc;
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
_cmsAssert(frm != NULL);
|
||||
|
||||
va_start(args, frm);
|
||||
|
||||
len = vsnprintf((char*) Buffer, 2047, frm, args);
|
||||
if (len < 0) return FALSE; // Truncated, which is a fatal error for us
|
||||
|
||||
rc = io ->Write(io, len, Buffer);
|
||||
|
||||
va_end(args);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
// Plugin memory management -------------------------------------------------------------------------------------------------
|
||||
|
||||
static _cmsSubAllocator* PluginPool = NULL;
|
||||
|
||||
// Specialized malloc for plug-ins, that is freed upon exit.
|
||||
void* _cmsPluginMalloc(cmsUInt32Number size)
|
||||
{
|
||||
if (PluginPool == NULL)
|
||||
PluginPool = _cmsCreateSubAlloc(0, 4*1024);
|
||||
|
||||
return _cmsSubAlloc(PluginPool, size);
|
||||
}
|
||||
|
||||
|
||||
// Main plug-in dispatcher
|
||||
cmsBool CMSEXPORT cmsPlugin(void* Plug_in)
|
||||
{
|
||||
cmsPluginBase* Plugin;
|
||||
|
||||
for (Plugin = (cmsPluginBase*) Plug_in;
|
||||
Plugin != NULL;
|
||||
Plugin = Plugin -> Next) {
|
||||
|
||||
if (Plugin -> Magic != cmsPluginMagicNumber) {
|
||||
cmsSignalError(0, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Plugin ->ExpectedVersion > LCMS_VERSION) {
|
||||
cmsSignalError(0, cmsERROR_UNKNOWN_EXTENSION, "plugin needs Little CMS %d, current version is %d",
|
||||
Plugin ->ExpectedVersion, LCMS_VERSION);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
switch (Plugin -> Type) {
|
||||
|
||||
case cmsPluginMemHandlerSig:
|
||||
if (!_cmsRegisterMemHandlerPlugin(Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
case cmsPluginInterpolationSig:
|
||||
if (!_cmsRegisterInterpPlugin(Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
case cmsPluginTagTypeSig:
|
||||
if (!_cmsRegisterTagTypePlugin(Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
case cmsPluginTagSig:
|
||||
if (!_cmsRegisterTagPlugin(Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
case cmsPluginFormattersSig:
|
||||
if (!_cmsRegisterFormattersPlugin(Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
case cmsPluginRenderingIntentSig:
|
||||
if (!_cmsRegisterRenderingIntentPlugin(Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
case cmsPluginParametricCurveSig:
|
||||
if (!_cmsRegisterParametricCurvesPlugin(Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
case cmsPluginMultiProcessElementSig:
|
||||
if (!_cmsRegisterMultiProcessElementPlugin(Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
case cmsPluginOptimizationSig:
|
||||
if (!_cmsRegisterOptimizationPlugin(Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
cmsSignalError(0, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin type '%X'", Plugin -> Type);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Keep a reference to the plug-in
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Revert all plug-ins to default
|
||||
void CMSEXPORT cmsUnregisterPlugins(void)
|
||||
{
|
||||
_cmsRegisterMemHandlerPlugin(NULL);
|
||||
_cmsRegisterInterpPlugin(NULL);
|
||||
_cmsRegisterTagTypePlugin(NULL);
|
||||
_cmsRegisterTagPlugin(NULL);
|
||||
_cmsRegisterFormattersPlugin(NULL);
|
||||
_cmsRegisterRenderingIntentPlugin(NULL);
|
||||
_cmsRegisterParametricCurvesPlugin(NULL);
|
||||
_cmsRegisterMultiProcessElementPlugin(NULL);
|
||||
_cmsRegisterOptimizationPlugin(NULL);
|
||||
|
||||
if (PluginPool != NULL)
|
||||
_cmsSubAllocDestroy(PluginPool);
|
||||
|
||||
PluginPool = NULL;
|
||||
}
|
1595
thirdparty/liblcms2/src/cmsps2.c
vendored
Normal file
1595
thirdparty/liblcms2/src/cmsps2.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
266
thirdparty/liblcms2/src/cmssamp.c
vendored
Normal file
266
thirdparty/liblcms2/src/cmssamp.c
vendored
Normal file
@ -0,0 +1,266 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
//
|
||||
// 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 "lcms2_internal.h"
|
||||
|
||||
|
||||
|
||||
// This file contains routines for resampling and LUT optimization, black point detection
|
||||
// and black preservation.
|
||||
|
||||
// Black point detection -------------------------------------------------------------------------
|
||||
|
||||
|
||||
// PCS -> PCS round trip transform, always uses relative intent on the device -> pcs
|
||||
static
|
||||
cmsHTRANSFORM CreateRoundtripXForm(cmsHPROFILE hProfile, cmsUInt32Number nIntent)
|
||||
{
|
||||
cmsHPROFILE hLab = cmsCreateLab4Profile(NULL);
|
||||
cmsHTRANSFORM xform;
|
||||
cmsBool BPC[4] = { FALSE, FALSE, FALSE, FALSE };
|
||||
cmsFloat64Number States[4] = { 1.0, 1.0, 1.0, 1.0 };
|
||||
cmsHPROFILE hProfiles[4];
|
||||
cmsUInt32Number Intents[4];
|
||||
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
||||
|
||||
hProfiles[0] = hLab; hProfiles[1] = hProfile; hProfiles[2] = hProfile; hProfiles[3] = hLab;
|
||||
Intents[0] = INTENT_RELATIVE_COLORIMETRIC; Intents[1] = nIntent; Intents[2] = INTENT_RELATIVE_COLORIMETRIC; Intents[3] = INTENT_RELATIVE_COLORIMETRIC;
|
||||
|
||||
xform = cmsCreateExtendedTransform(ContextID, 4, hProfiles, BPC, Intents,
|
||||
States, NULL, 0, TYPE_Lab_DBL, TYPE_Lab_DBL, cmsFLAGS_NOCACHE|cmsFLAGS_NOOPTIMIZE);
|
||||
|
||||
cmsCloseProfile(hLab);
|
||||
return xform;
|
||||
}
|
||||
|
||||
// Use darker colorants to obtain black point. This works in the relative colorimetric intent and
|
||||
// assumes more ink results in darker colors. No ink limit is assumed.
|
||||
static
|
||||
cmsBool BlackPointAsDarkerColorant(cmsHPROFILE hInput,
|
||||
cmsUInt32Number Intent,
|
||||
cmsCIEXYZ* BlackPoint,
|
||||
cmsUInt32Number dwFlags)
|
||||
{
|
||||
cmsUInt16Number *Black;
|
||||
cmsHTRANSFORM xform;
|
||||
cmsColorSpaceSignature Space;
|
||||
cmsUInt32Number nChannels;
|
||||
cmsUInt32Number dwFormat;
|
||||
cmsHPROFILE hLab;
|
||||
cmsCIELab Lab;
|
||||
cmsCIEXYZ BlackXYZ;
|
||||
cmsContext ContextID = cmsGetProfileContextID(hInput);
|
||||
|
||||
// If the profile does not support input direction, assume Black point 0
|
||||
if (!cmsIsIntentSupported(hInput, Intent, LCMS_USED_AS_INPUT)) {
|
||||
|
||||
BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Create a formatter which has n channels and floating point
|
||||
dwFormat = cmsFormatterForColorspaceOfProfile(hInput, 2, FALSE);
|
||||
|
||||
// Try to get black by using black colorant
|
||||
Space = cmsGetColorSpace(hInput);
|
||||
|
||||
// This function returns darker colorant in 16 bits for several spaces
|
||||
if (!_cmsEndPointsBySpace(Space, NULL, &Black, &nChannels)) {
|
||||
|
||||
BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (nChannels != T_CHANNELS(dwFormat)) {
|
||||
BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Lab will be used as the output space, but lab2 will avoid recursion
|
||||
hLab = cmsCreateLab2ProfileTHR(ContextID, NULL);
|
||||
if (hLab == NULL) {
|
||||
BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Create the transform
|
||||
xform = cmsCreateTransformTHR(ContextID, hInput, dwFormat,
|
||||
hLab, TYPE_Lab_DBL, Intent, cmsFLAGS_NOOPTIMIZE|cmsFLAGS_NOCACHE);
|
||||
cmsCloseProfile(hLab);
|
||||
|
||||
if (xform == NULL) {
|
||||
// Something went wrong. Get rid of open resources and return zero as black
|
||||
|
||||
BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Convert black to Lab
|
||||
cmsDoTransform(xform, Black, &Lab, 1);
|
||||
|
||||
// Force it to be neutral, clip to max. L* of 50
|
||||
Lab.a = Lab.b = 0;
|
||||
if (Lab.L > 50) Lab.L = 50;
|
||||
|
||||
// Free the resources
|
||||
cmsDeleteTransform(xform);
|
||||
|
||||
// Convert from Lab (which is now clipped) to XYZ.
|
||||
cmsLab2XYZ(NULL, &BlackXYZ, &Lab);
|
||||
|
||||
if (BlackPoint != NULL)
|
||||
*BlackPoint = BlackXYZ;
|
||||
|
||||
return TRUE;
|
||||
|
||||
cmsUNUSED_PARAMETER(dwFlags);
|
||||
}
|
||||
|
||||
// Get a black point of output CMYK profile, discounting any ink-limiting embedded
|
||||
// in the profile. For doing that, we use perceptual intent in input direction:
|
||||
// Lab (0, 0, 0) -> [Perceptual] Profile -> CMYK -> [Rel. colorimetric] Profile -> Lab
|
||||
static
|
||||
cmsBool BlackPointUsingPerceptualBlack(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfile)
|
||||
|
||||
{
|
||||
cmsHTRANSFORM hRoundTrip;
|
||||
cmsCIELab LabIn, LabOut;
|
||||
cmsCIEXYZ BlackXYZ;
|
||||
|
||||
// Is the intent supported by the profile?
|
||||
if (!cmsIsIntentSupported(hProfile, INTENT_PERCEPTUAL, LCMS_USED_AS_INPUT)) {
|
||||
|
||||
BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
hRoundTrip = CreateRoundtripXForm(hProfile, INTENT_PERCEPTUAL);
|
||||
if (hRoundTrip == NULL) {
|
||||
BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LabIn.L = LabIn.a = LabIn.b = 0;
|
||||
cmsDoTransform(hRoundTrip, &LabIn, &LabOut, 1);
|
||||
|
||||
// Clip Lab to reasonable limits
|
||||
if (LabOut.L > 50) LabOut.L = 50;
|
||||
LabOut.a = LabOut.b = 0;
|
||||
|
||||
cmsDeleteTransform(hRoundTrip);
|
||||
|
||||
// Convert it to XYZ
|
||||
cmsLab2XYZ(NULL, &BlackXYZ, &LabOut);
|
||||
|
||||
if (BlackPoint != NULL)
|
||||
*BlackPoint = BlackXYZ;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// This function shouldn't exist at all -- there is such quantity of broken
|
||||
// profiles on black point tag, that we must somehow fix chromaticity to
|
||||
// avoid huge tint when doing Black point compensation. This function does
|
||||
// just that. There is a special flag for using black point tag, but turned
|
||||
// off by default because it is bogus on most profiles. The detection algorithm
|
||||
// involves to turn BP to neutral and to use only L component.
|
||||
|
||||
cmsBool CMSEXPORT cmsDetectBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags)
|
||||
{
|
||||
|
||||
// Zero for black point
|
||||
if (cmsGetDeviceClass(hProfile) == cmsSigLinkClass) {
|
||||
|
||||
BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// v4 + perceptual & saturation intents does have its own black point, and it is
|
||||
// well specified enough to use it. Black point tag is deprecated in V4.
|
||||
|
||||
if ((cmsGetEncodedICCversion(hProfile) >= 0x4000000) &&
|
||||
(Intent == INTENT_PERCEPTUAL || Intent == INTENT_SATURATION)) {
|
||||
|
||||
// Matrix shaper share MRC & perceptual intents
|
||||
if (cmsIsMatrixShaper(hProfile))
|
||||
return BlackPointAsDarkerColorant(hProfile, INTENT_RELATIVE_COLORIMETRIC, BlackPoint, 0);
|
||||
|
||||
// Get Perceptual black out of v4 profiles. That is fixed for perceptual & saturation intents
|
||||
BlackPoint -> X = cmsPERCEPTUAL_BLACK_X;
|
||||
BlackPoint -> Y = cmsPERCEPTUAL_BLACK_Y;
|
||||
BlackPoint -> Z = cmsPERCEPTUAL_BLACK_Z;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CMS_USE_PROFILE_BLACK_POINT_TAG
|
||||
|
||||
// v2, v4 rel/abs colorimetric
|
||||
if (cmsIsTag(hProfile, cmsSigMediaBlackPointTag) &&
|
||||
Intent == INTENT_RELATIVE_COLORIMETRIC) {
|
||||
|
||||
cmsCIEXYZ *BlackPtr, BlackXYZ, UntrustedBlackPoint, TrustedBlackPoint, MediaWhite;
|
||||
cmsCIELab Lab;
|
||||
|
||||
// If black point is specified, then use it,
|
||||
|
||||
BlackPtr = cmsReadTag(hProfile, cmsSigMediaBlackPointTag);
|
||||
if (BlackPtr != NULL) {
|
||||
|
||||
BlackXYZ = *BlackPtr;
|
||||
_cmsReadMediaWhitePoint(&MediaWhite, hProfile);
|
||||
|
||||
// Black point is absolute XYZ, so adapt to D50 to get PCS value
|
||||
cmsAdaptToIlluminant(&UntrustedBlackPoint, &MediaWhite, cmsD50_XYZ(), &BlackXYZ);
|
||||
|
||||
// Force a=b=0 to get rid of any chroma
|
||||
cmsXYZ2Lab(NULL, &Lab, &UntrustedBlackPoint);
|
||||
Lab.a = Lab.b = 0;
|
||||
if (Lab.L > 50) Lab.L = 50; // Clip to L* <= 50
|
||||
cmsLab2XYZ(NULL, &TrustedBlackPoint, &Lab);
|
||||
|
||||
if (BlackPoint != NULL)
|
||||
*BlackPoint = TrustedBlackPoint;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// That is about v2 profiles.
|
||||
|
||||
// If output profile, discount ink-limiting and that's all
|
||||
if (Intent == INTENT_RELATIVE_COLORIMETRIC &&
|
||||
(cmsGetDeviceClass(hProfile) == cmsSigOutputClass) &&
|
||||
(cmsGetColorSpace(hProfile) == cmsSigCmykData))
|
||||
return BlackPointUsingPerceptualBlack(BlackPoint, hProfile);
|
||||
|
||||
// Nope, compute BP using current intent.
|
||||
return BlackPointAsDarkerColorant(hProfile, Intent, BlackPoint, dwFlags);
|
||||
}
|
||||
|
||||
|
734
thirdparty/liblcms2/src/cmssm.c
vendored
Normal file
734
thirdparty/liblcms2/src/cmssm.c
vendored
Normal file
@ -0,0 +1,734 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
//
|
||||
// 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 "lcms2_internal.h"
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
// Gamut boundary description by using Jan Morovic's Segment maxima method
|
||||
// Many thanks to Jan for allowing me to use his algorithm.
|
||||
|
||||
// r = C*
|
||||
// alpha = Hab
|
||||
// theta = L*
|
||||
|
||||
#define SECTORS 16 // number of divisions in alpha and theta
|
||||
|
||||
// Spherical coordinates
|
||||
typedef struct {
|
||||
|
||||
cmsFloat64Number r;
|
||||
cmsFloat64Number alpha;
|
||||
cmsFloat64Number theta;
|
||||
|
||||
} cmsSpherical;
|
||||
|
||||
typedef enum {
|
||||
GP_EMPTY,
|
||||
GP_SPECIFIED,
|
||||
GP_MODELED
|
||||
|
||||
} GDBPointType;
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
GDBPointType Type;
|
||||
cmsSpherical p; // Keep also alpha & theta of maximum
|
||||
|
||||
} cmsGDBPoint;
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
cmsContext ContextID;
|
||||
cmsGDBPoint Gamut[SECTORS][SECTORS];
|
||||
|
||||
} cmsGDB;
|
||||
|
||||
|
||||
// A line using the parametric form
|
||||
// P = a + t*u
|
||||
typedef struct {
|
||||
|
||||
cmsVEC3 a;
|
||||
cmsVEC3 u;
|
||||
|
||||
} cmsLine;
|
||||
|
||||
|
||||
// A plane using the parametric form
|
||||
// Q = b + r*v + s*w
|
||||
typedef struct {
|
||||
|
||||
cmsVEC3 b;
|
||||
cmsVEC3 v;
|
||||
cmsVEC3 w;
|
||||
|
||||
} cmsPlane;
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
// ATAN2() which always returns degree positive numbers
|
||||
|
||||
static
|
||||
cmsFloat64Number _cmsAtan2(cmsFloat64Number y, cmsFloat64Number x)
|
||||
{
|
||||
cmsFloat64Number a;
|
||||
|
||||
// Deal with undefined case
|
||||
if (x == 0.0 && y == 0.0) return 0;
|
||||
|
||||
a = (atan2(y, x) * 180.0) / M_PI;
|
||||
|
||||
while (a < 0) {
|
||||
a += 360;
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
// Convert to spherical coordinates
|
||||
static
|
||||
void ToSpherical(cmsSpherical* sp, const cmsVEC3* v)
|
||||
{
|
||||
|
||||
cmsFloat64Number L, a, b;
|
||||
|
||||
L = v ->n[VX];
|
||||
a = v ->n[VY];
|
||||
b = v ->n[VZ];
|
||||
|
||||
sp ->r = sqrt( L*L + a*a + b*b );
|
||||
|
||||
if (sp ->r == 0) {
|
||||
sp ->alpha = sp ->theta = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
sp ->alpha = _cmsAtan2(a, b);
|
||||
sp ->theta = _cmsAtan2(sqrt(a*a + b*b), L);
|
||||
}
|
||||
|
||||
|
||||
// Convert to cartesian from spherical
|
||||
static
|
||||
void ToCartesian(cmsVEC3* v, const cmsSpherical* sp)
|
||||
{
|
||||
cmsFloat64Number sin_alpha;
|
||||
cmsFloat64Number cos_alpha;
|
||||
cmsFloat64Number sin_theta;
|
||||
cmsFloat64Number cos_theta;
|
||||
cmsFloat64Number L, a, b;
|
||||
|
||||
sin_alpha = sin((M_PI * sp ->alpha) / 180.0);
|
||||
cos_alpha = cos((M_PI * sp ->alpha) / 180.0);
|
||||
sin_theta = sin((M_PI * sp ->theta) / 180.0);
|
||||
cos_theta = cos((M_PI * sp ->theta) / 180.0);
|
||||
|
||||
a = sp ->r * sin_theta * sin_alpha;
|
||||
b = sp ->r * sin_theta * cos_alpha;
|
||||
L = sp ->r * cos_theta;
|
||||
|
||||
v ->n[VX] = L;
|
||||
v ->n[VY] = a;
|
||||
v ->n[VZ] = b;
|
||||
}
|
||||
|
||||
|
||||
// Quantize sector of a spherical coordinate. Saturate 360, 180 to last sector
|
||||
// The limits are the centers of each sector, so
|
||||
static
|
||||
void QuantizeToSector(const cmsSpherical* sp, int* alpha, int* theta)
|
||||
{
|
||||
*alpha = (int) floor(((sp->alpha * (SECTORS)) / 360.0) );
|
||||
*theta = (int) floor(((sp->theta * (SECTORS)) / 180.0) );
|
||||
|
||||
if (*alpha >= SECTORS)
|
||||
*alpha = SECTORS-1;
|
||||
if (*theta >= SECTORS)
|
||||
*theta = SECTORS-1;
|
||||
}
|
||||
|
||||
|
||||
// Line determined by 2 points
|
||||
static
|
||||
void LineOf2Points(cmsLine* line, cmsVEC3* a, cmsVEC3* b)
|
||||
{
|
||||
|
||||
_cmsVEC3init(&line ->a, a ->n[VX], a ->n[VY], a ->n[VZ]);
|
||||
_cmsVEC3init(&line ->u, b ->n[VX] - a ->n[VX],
|
||||
b ->n[VY] - a ->n[VY],
|
||||
b ->n[VZ] - a ->n[VZ]);
|
||||
}
|
||||
|
||||
|
||||
// Evaluate parametric line
|
||||
static
|
||||
void GetPointOfLine(cmsVEC3* p, const cmsLine* line, cmsFloat64Number t)
|
||||
{
|
||||
p ->n[VX] = line ->a.n[VX] + t * line->u.n[VX];
|
||||
p ->n[VY] = line ->a.n[VY] + t * line->u.n[VY];
|
||||
p ->n[VZ] = line ->a.n[VZ] + t * line->u.n[VZ];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Closest point in sector line1 to sector line2 (both are defined as 0 <=t <= 1)
|
||||
http://softsurfer.com/Archive/algorithm_0106/algorithm_0106.htm
|
||||
|
||||
Copyright 2001, softSurfer (www.softsurfer.com)
|
||||
This code may be freely used and modified for any purpose
|
||||
providing that this copyright notice is included with it.
|
||||
SoftSurfer makes no warranty for this code, and cannot be held
|
||||
liable for any real or imagined damage resulting from its use.
|
||||
Users of this code must verify correctness for their application.
|
||||
|
||||
*/
|
||||
|
||||
static
|
||||
cmsBool ClosestLineToLine(cmsVEC3* r, const cmsLine* line1, const cmsLine* line2)
|
||||
{
|
||||
cmsFloat64Number a, b, c, d, e, D;
|
||||
cmsFloat64Number sc, sN, sD;
|
||||
cmsFloat64Number tc, tN, tD;
|
||||
cmsVEC3 w0;
|
||||
|
||||
_cmsVEC3minus(&w0, &line1 ->a, &line2 ->a);
|
||||
|
||||
a = _cmsVEC3dot(&line1 ->u, &line1 ->u);
|
||||
b = _cmsVEC3dot(&line1 ->u, &line2 ->u);
|
||||
c = _cmsVEC3dot(&line2 ->u, &line2 ->u);
|
||||
d = _cmsVEC3dot(&line1 ->u, &w0);
|
||||
e = _cmsVEC3dot(&line2 ->u, &w0);
|
||||
|
||||
D = a*c - b * b; // Denominator
|
||||
sD = tD = D; // default sD = D >= 0
|
||||
|
||||
if (D < MATRIX_DET_TOLERANCE) { // the lines are almost parallel
|
||||
|
||||
sN = 0.0; // force using point P0 on segment S1
|
||||
sD = 1.0; // to prevent possible division by 0.0 later
|
||||
tN = e;
|
||||
tD = c;
|
||||
}
|
||||
else { // get the closest points on the infinite lines
|
||||
|
||||
sN = (b*e - c*d);
|
||||
tN = (a*e - b*d);
|
||||
|
||||
if (sN < 0.0) { // sc < 0 => the s=0 edge is visible
|
||||
|
||||
sN = 0.0;
|
||||
tN = e;
|
||||
tD = c;
|
||||
}
|
||||
else if (sN > sD) { // sc > 1 => the s=1 edge is visible
|
||||
sN = sD;
|
||||
tN = e + b;
|
||||
tD = c;
|
||||
}
|
||||
}
|
||||
|
||||
if (tN < 0.0) { // tc < 0 => the t=0 edge is visible
|
||||
|
||||
tN = 0.0;
|
||||
// recompute sc for this edge
|
||||
if (-d < 0.0)
|
||||
sN = 0.0;
|
||||
else if (-d > a)
|
||||
sN = sD;
|
||||
else {
|
||||
sN = -d;
|
||||
sD = a;
|
||||
}
|
||||
}
|
||||
else if (tN > tD) { // tc > 1 => the t=1 edge is visible
|
||||
|
||||
tN = tD;
|
||||
|
||||
// recompute sc for this edge
|
||||
if ((-d + b) < 0.0)
|
||||
sN = 0;
|
||||
else if ((-d + b) > a)
|
||||
sN = sD;
|
||||
else {
|
||||
sN = (-d + b);
|
||||
sD = a;
|
||||
}
|
||||
}
|
||||
// finally do the division to get sc and tc
|
||||
sc = (fabs(sN) < MATRIX_DET_TOLERANCE ? 0.0 : sN / sD);
|
||||
tc = (fabs(tN) < MATRIX_DET_TOLERANCE ? 0.0 : tN / tD);
|
||||
|
||||
GetPointOfLine(r, line1, sc);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------ Wrapper
|
||||
|
||||
|
||||
// Allocate & free structure
|
||||
cmsHANDLE CMSEXPORT cmsGBDAlloc(cmsContext ContextID)
|
||||
{
|
||||
cmsGDB* gbd = (cmsGDB*) _cmsMallocZero(ContextID, sizeof(cmsGDB));
|
||||
if (gbd == NULL) return NULL;
|
||||
|
||||
gbd -> ContextID = ContextID;
|
||||
|
||||
return (cmsHANDLE) gbd;
|
||||
}
|
||||
|
||||
|
||||
void CMSEXPORT cmsGBDFree(cmsHANDLE hGBD)
|
||||
{
|
||||
cmsGDB* gbd = (cmsGDB*) hGBD;
|
||||
if (hGBD != NULL)
|
||||
_cmsFree(gbd->ContextID, (void*) gbd);
|
||||
}
|
||||
|
||||
|
||||
// Auxiliar to retrieve a pointer to the segmentr containing the Lab value
|
||||
static
|
||||
cmsGDBPoint* GetPoint(cmsGDB* gbd, const cmsCIELab* Lab, cmsSpherical* sp)
|
||||
{
|
||||
cmsVEC3 v;
|
||||
int alpha, theta;
|
||||
|
||||
// Housekeeping
|
||||
_cmsAssert(gbd != NULL);
|
||||
_cmsAssert(Lab != NULL);
|
||||
_cmsAssert(sp != NULL);
|
||||
|
||||
// Center L* by substracting half of its domain, that's 50
|
||||
_cmsVEC3init(&v, Lab ->L - 50.0, Lab ->a, Lab ->b);
|
||||
|
||||
// Convert to spherical coordinates
|
||||
ToSpherical(sp, &v);
|
||||
|
||||
if (sp ->r < 0 || sp ->alpha < 0 || sp->theta < 0) {
|
||||
cmsSignalError(gbd ->ContextID, cmsERROR_RANGE, "spherical value out of range");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// On which sector it falls?
|
||||
QuantizeToSector(sp, &alpha, &theta);
|
||||
|
||||
if (alpha < 0 || theta < 0 || alpha >= SECTORS || theta >= SECTORS) {
|
||||
cmsSignalError(gbd ->ContextID, cmsERROR_RANGE, " quadrant out of range");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get pointer to the sector
|
||||
return &gbd ->Gamut[theta][alpha];
|
||||
}
|
||||
|
||||
// Add a point to gamut descriptor. Point to add is in Lab color space.
|
||||
// GBD is centered on a=b=0 and L*=50
|
||||
cmsBool CMSEXPORT cmsGDBAddPoint(cmsHANDLE hGBD, const cmsCIELab* Lab)
|
||||
{
|
||||
cmsGDB* gbd = (cmsGDB*) hGBD;
|
||||
cmsGDBPoint* ptr;
|
||||
cmsSpherical sp;
|
||||
|
||||
|
||||
// Get pointer to the sector
|
||||
ptr = GetPoint(gbd, Lab, &sp);
|
||||
if (ptr == NULL) return FALSE;
|
||||
|
||||
// If no samples at this sector, add it
|
||||
if (ptr ->Type == GP_EMPTY) {
|
||||
|
||||
ptr -> Type = GP_SPECIFIED;
|
||||
ptr -> p = sp;
|
||||
}
|
||||
else {
|
||||
|
||||
|
||||
// Substitute only if radius is greater
|
||||
if (sp.r > ptr -> p.r) {
|
||||
|
||||
ptr -> Type = GP_SPECIFIED;
|
||||
ptr -> p = sp;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Check if a given point falls inside gamut
|
||||
cmsBool CMSEXPORT cmsGDBCheckPoint(cmsHANDLE hGBD, const cmsCIELab* Lab)
|
||||
{
|
||||
cmsGDB* gbd = (cmsGDB*) hGBD;
|
||||
cmsGDBPoint* ptr;
|
||||
cmsSpherical sp;
|
||||
|
||||
// Get pointer to the sector
|
||||
ptr = GetPoint(gbd, Lab, &sp);
|
||||
if (ptr == NULL) return FALSE;
|
||||
|
||||
// If no samples at this sector, return no data
|
||||
if (ptr ->Type == GP_EMPTY) return FALSE;
|
||||
|
||||
// In gamut only if radius is greater
|
||||
|
||||
return (sp.r <= ptr -> p.r);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Find near sectors. The list of sectors found is returned on Close[].
|
||||
// The function returns the number of sectors as well.
|
||||
|
||||
// 24 9 10 11 12
|
||||
// 23 8 1 2 13
|
||||
// 22 7 * 3 14
|
||||
// 21 6 5 4 15
|
||||
// 20 19 18 17 16
|
||||
//
|
||||
// Those are the relative movements
|
||||
// {-2,-2}, {-1, -2}, {0, -2}, {+1, -2}, {+2, -2},
|
||||
// {-2,-1}, {-1, -1}, {0, -1}, {+1, -1}, {+2, -1},
|
||||
// {-2, 0}, {-1, 0}, {0, 0}, {+1, 0}, {+2, 0},
|
||||
// {-2,+1}, {-1, +1}, {0, +1}, {+1, +1}, {+2, +1},
|
||||
// {-2,+2}, {-1, +2}, {0, +2}, {+1, +2}, {+2, +2}};
|
||||
|
||||
|
||||
static
|
||||
const struct _spiral {
|
||||
|
||||
int AdvX, AdvY;
|
||||
|
||||
} Spiral[] = { {0, -1}, {+1, -1}, {+1, 0}, {+1, +1}, {0, +1}, {-1, +1},
|
||||
{-1, 0}, {-1, -1}, {-1, -2}, {0, -2}, {+1, -2}, {+2, -2},
|
||||
{+2, -1}, {+2, 0}, {+2, +1}, {+2, +2}, {+1, +2}, {0, +2},
|
||||
{-1, +2}, {-2, +2}, {-2, +1}, {-2, 0}, {-2, -1}, {-2, -2} };
|
||||
|
||||
#define NSTEPS (sizeof(Spiral) / sizeof(struct _spiral))
|
||||
|
||||
static
|
||||
int FindNearSectors(cmsGDB* gbd, int alpha, int theta, cmsGDBPoint* Close[])
|
||||
{
|
||||
int nSectors = 0;
|
||||
int i, a, t;
|
||||
cmsGDBPoint* pt;
|
||||
|
||||
for (i=0; i < NSTEPS; i++) {
|
||||
|
||||
a = alpha + Spiral[i].AdvX;
|
||||
t = theta + Spiral[i].AdvY;
|
||||
|
||||
// Cycle at the end
|
||||
a %= SECTORS;
|
||||
t %= SECTORS;
|
||||
|
||||
// Cycle at the begin
|
||||
if (a < 0) a = SECTORS + a;
|
||||
if (t < 0) t = SECTORS + t;
|
||||
|
||||
pt = &gbd ->Gamut[t][a];
|
||||
|
||||
if (pt -> Type != GP_EMPTY) {
|
||||
|
||||
Close[nSectors++] = pt;
|
||||
}
|
||||
}
|
||||
|
||||
return nSectors;
|
||||
}
|
||||
|
||||
|
||||
// Interpolate a missing sector. Method identifies whatever this is top, bottom or mid
|
||||
static
|
||||
cmsBool InterpolateMissingSector(cmsGDB* gbd, int alpha, int theta)
|
||||
{
|
||||
cmsSpherical sp;
|
||||
cmsVEC3 Lab;
|
||||
cmsVEC3 Centre;
|
||||
cmsLine ray;
|
||||
int nCloseSectors;
|
||||
cmsGDBPoint* Close[NSTEPS];
|
||||
cmsSpherical closel, templ;
|
||||
cmsLine edge;
|
||||
int k, m;
|
||||
|
||||
// Is that point already specified?
|
||||
if (gbd ->Gamut[theta][alpha].Type != GP_EMPTY) return TRUE;
|
||||
|
||||
// Fill close points
|
||||
nCloseSectors = FindNearSectors(gbd, alpha, theta, Close);
|
||||
|
||||
|
||||
// Find a central point on the sector
|
||||
sp.alpha = (cmsFloat64Number) ((alpha + 0.5) * 360.0) / (SECTORS);
|
||||
sp.theta = (cmsFloat64Number) ((theta + 0.5) * 180.0) / (SECTORS);
|
||||
sp.r = 50.0;
|
||||
|
||||
// Convert to Cartesian
|
||||
ToCartesian(&Lab, &sp);
|
||||
|
||||
// Create a ray line from centre to this point
|
||||
_cmsVEC3init(&Centre, 50.0, 0, 0);
|
||||
LineOf2Points(&ray, &Lab, &Centre);
|
||||
|
||||
// For all close sectors
|
||||
closel.r = 0.0;
|
||||
closel.alpha = 0;
|
||||
closel.theta = 0;
|
||||
|
||||
for (k=0; k < nCloseSectors; k++) {
|
||||
|
||||
for(m = k+1; m < nCloseSectors; m++) {
|
||||
|
||||
cmsVEC3 temp, a1, a2;
|
||||
|
||||
// A line from sector to sector
|
||||
ToCartesian(&a1, &Close[k]->p);
|
||||
ToCartesian(&a2, &Close[m]->p);
|
||||
|
||||
LineOf2Points(&edge, &a1, &a2);
|
||||
|
||||
// Find a line
|
||||
ClosestLineToLine(&temp, &ray, &edge);
|
||||
|
||||
// Convert to spherical
|
||||
ToSpherical(&templ, &temp);
|
||||
|
||||
|
||||
if ( templ.r > closel.r &&
|
||||
templ.theta >= (theta*180.0/SECTORS) &&
|
||||
templ.theta <= ((theta+1)*180.0/SECTORS) &&
|
||||
templ.alpha >= (alpha*360.0/SECTORS) &&
|
||||
templ.alpha <= ((alpha+1)*360.0/SECTORS)) {
|
||||
|
||||
closel = templ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gbd ->Gamut[theta][alpha].p = closel;
|
||||
gbd ->Gamut[theta][alpha].Type = GP_MODELED;
|
||||
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Interpolate missing parts. The algorithm fist computes slices at
|
||||
// theta=0 and theta=Max.
|
||||
cmsBool CMSEXPORT cmsGDBCompute(cmsHANDLE hGBD, cmsUInt32Number dwFlags)
|
||||
{
|
||||
int alpha, theta;
|
||||
cmsGDB* gbd = (cmsGDB*) hGBD;
|
||||
|
||||
_cmsAssert(hGBD != NULL);
|
||||
|
||||
// Interpolate black
|
||||
for (alpha = 0; alpha <= SECTORS; alpha++) {
|
||||
|
||||
if (!InterpolateMissingSector(gbd, alpha, 0)) return FALSE;
|
||||
}
|
||||
|
||||
// Interpolate white
|
||||
for (alpha = 0; alpha <= SECTORS; alpha++) {
|
||||
|
||||
if (!InterpolateMissingSector(gbd, alpha, SECTORS-1)) return FALSE;
|
||||
}
|
||||
|
||||
|
||||
// Interpolate Mid
|
||||
for (theta = 1; theta < SECTORS; theta++) {
|
||||
for (alpha = 0; alpha <= SECTORS; alpha++) {
|
||||
|
||||
if (!InterpolateMissingSector(gbd, alpha, theta)) return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Done
|
||||
return TRUE;
|
||||
|
||||
cmsUNUSED_PARAMETER(dwFlags);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Great for debug, but not suitable for real use
|
||||
|
||||
#if 0
|
||||
cmsBool cmsGBDdumpVRML(cmsHANDLE hGBD, const char* fname)
|
||||
{
|
||||
FILE* fp;
|
||||
int i, j;
|
||||
cmsGDB* gbd = (cmsGDB*) hGBD;
|
||||
cmsGDBPoint* pt;
|
||||
|
||||
fp = fopen (fname, "wt");
|
||||
if (fp == NULL)
|
||||
return FALSE;
|
||||
|
||||
fprintf (fp, "#VRML V2.0 utf8\n");
|
||||
|
||||
// set the viewing orientation and distance
|
||||
fprintf (fp, "DEF CamTest Group {\n");
|
||||
fprintf (fp, "\tchildren [\n");
|
||||
fprintf (fp, "\t\tDEF Cameras Group {\n");
|
||||
fprintf (fp, "\t\t\tchildren [\n");
|
||||
fprintf (fp, "\t\t\t\tDEF DefaultView Viewpoint {\n");
|
||||
fprintf (fp, "\t\t\t\t\tposition 0 0 340\n");
|
||||
fprintf (fp, "\t\t\t\t\torientation 0 0 1 0\n");
|
||||
fprintf (fp, "\t\t\t\t\tdescription \"default view\"\n");
|
||||
fprintf (fp, "\t\t\t\t}\n");
|
||||
fprintf (fp, "\t\t\t]\n");
|
||||
fprintf (fp, "\t\t},\n");
|
||||
fprintf (fp, "\t]\n");
|
||||
fprintf (fp, "}\n");
|
||||
|
||||
// Output the background stuff
|
||||
fprintf (fp, "Background {\n");
|
||||
fprintf (fp, "\tskyColor [\n");
|
||||
fprintf (fp, "\t\t.5 .5 .5\n");
|
||||
fprintf (fp, "\t]\n");
|
||||
fprintf (fp, "}\n");
|
||||
|
||||
// Output the shape stuff
|
||||
fprintf (fp, "Transform {\n");
|
||||
fprintf (fp, "\tscale .3 .3 .3\n");
|
||||
fprintf (fp, "\tchildren [\n");
|
||||
|
||||
// Draw the axes as a shape:
|
||||
fprintf (fp, "\t\tShape {\n");
|
||||
fprintf (fp, "\t\t\tappearance Appearance {\n");
|
||||
fprintf (fp, "\t\t\t\tmaterial Material {\n");
|
||||
fprintf (fp, "\t\t\t\t\tdiffuseColor 0 0.8 0\n");
|
||||
fprintf (fp, "\t\t\t\t\temissiveColor 1.0 1.0 1.0\n");
|
||||
fprintf (fp, "\t\t\t\t\tshininess 0.8\n");
|
||||
fprintf (fp, "\t\t\t\t}\n");
|
||||
fprintf (fp, "\t\t\t}\n");
|
||||
fprintf (fp, "\t\t\tgeometry IndexedLineSet {\n");
|
||||
fprintf (fp, "\t\t\t\tcoord Coordinate {\n");
|
||||
fprintf (fp, "\t\t\t\t\tpoint [\n");
|
||||
fprintf (fp, "\t\t\t\t\t0.0 0.0 0.0,\n");
|
||||
fprintf (fp, "\t\t\t\t\t%f 0.0 0.0,\n", 255.0);
|
||||
fprintf (fp, "\t\t\t\t\t0.0 %f 0.0,\n", 255.0);
|
||||
fprintf (fp, "\t\t\t\t\t0.0 0.0 %f]\n", 255.0);
|
||||
fprintf (fp, "\t\t\t\t}\n");
|
||||
fprintf (fp, "\t\t\t\tcoordIndex [\n");
|
||||
fprintf (fp, "\t\t\t\t\t0, 1, -1\n");
|
||||
fprintf (fp, "\t\t\t\t\t0, 2, -1\n");
|
||||
fprintf (fp, "\t\t\t\t\t0, 3, -1]\n");
|
||||
fprintf (fp, "\t\t\t}\n");
|
||||
fprintf (fp, "\t\t}\n");
|
||||
|
||||
|
||||
fprintf (fp, "\t\tShape {\n");
|
||||
fprintf (fp, "\t\t\tappearance Appearance {\n");
|
||||
fprintf (fp, "\t\t\t\tmaterial Material {\n");
|
||||
fprintf (fp, "\t\t\t\t\tdiffuseColor 0 0.8 0\n");
|
||||
fprintf (fp, "\t\t\t\t\temissiveColor 1 1 1\n");
|
||||
fprintf (fp, "\t\t\t\t\tshininess 0.8\n");
|
||||
fprintf (fp, "\t\t\t\t}\n");
|
||||
fprintf (fp, "\t\t\t}\n");
|
||||
fprintf (fp, "\t\t\tgeometry PointSet {\n");
|
||||
|
||||
// fill in the points here
|
||||
fprintf (fp, "\t\t\t\tcoord Coordinate {\n");
|
||||
fprintf (fp, "\t\t\t\t\tpoint [\n");
|
||||
|
||||
// We need to transverse all gamut hull.
|
||||
for (i=0; i < SECTORS; i++)
|
||||
for (j=0; j < SECTORS; j++) {
|
||||
|
||||
cmsVEC3 v;
|
||||
|
||||
pt = &gbd ->Gamut[i][j];
|
||||
ToCartesian(&v, &pt ->p);
|
||||
|
||||
fprintf (fp, "\t\t\t\t\t%g %g %g", v.n[0]+50, v.n[1], v.n[2]);
|
||||
|
||||
if ((j == SECTORS - 1) && (i == SECTORS - 1))
|
||||
fprintf (fp, "]\n");
|
||||
else
|
||||
fprintf (fp, ",\n");
|
||||
|
||||
}
|
||||
|
||||
fprintf (fp, "\t\t\t\t}\n");
|
||||
|
||||
|
||||
|
||||
// fill in the face colors
|
||||
fprintf (fp, "\t\t\t\tcolor Color {\n");
|
||||
fprintf (fp, "\t\t\t\t\tcolor [\n");
|
||||
|
||||
for (i=0; i < SECTORS; i++)
|
||||
for (j=0; j < SECTORS; j++) {
|
||||
|
||||
cmsVEC3 v;
|
||||
|
||||
pt = &gbd ->Gamut[i][j];
|
||||
|
||||
|
||||
ToCartesian(&v, &pt ->p);
|
||||
|
||||
|
||||
if (pt ->Type == GP_EMPTY)
|
||||
fprintf (fp, "\t\t\t\t\t%g %g %g", 0.0, 0.0, 0.0);
|
||||
else
|
||||
if (pt ->Type == GP_MODELED)
|
||||
fprintf (fp, "\t\t\t\t\t%g %g %g", 1.0, .5, .5);
|
||||
else {
|
||||
fprintf (fp, "\t\t\t\t\t%g %g %g", 1.0, 1.0, 1.0);
|
||||
|
||||
}
|
||||
|
||||
if ((j == SECTORS - 1) && (i == SECTORS - 1))
|
||||
fprintf (fp, "]\n");
|
||||
else
|
||||
fprintf (fp, ",\n");
|
||||
}
|
||||
fprintf (fp, "\t\t\t}\n");
|
||||
|
||||
|
||||
fprintf (fp, "\t\t\t}\n");
|
||||
fprintf (fp, "\t\t}\n");
|
||||
fprintf (fp, "\t]\n");
|
||||
fprintf (fp, "}\n");
|
||||
|
||||
fclose (fp);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
4955
thirdparty/liblcms2/src/cmstypes.c
vendored
Normal file
4955
thirdparty/liblcms2/src/cmstypes.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1148
thirdparty/liblcms2/src/cmsvirt.c
vendored
Normal file
1148
thirdparty/liblcms2/src/cmsvirt.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
351
thirdparty/liblcms2/src/cmswtpnt.c
vendored
Normal file
351
thirdparty/liblcms2/src/cmswtpnt.c
vendored
Normal file
@ -0,0 +1,351 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
//
|
||||
// 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 "lcms2_internal.h"
|
||||
|
||||
|
||||
// D50 - Widely used
|
||||
const cmsCIEXYZ* CMSEXPORT cmsD50_XYZ(void)
|
||||
{
|
||||
static cmsCIEXYZ D50XYZ = {cmsD50X, cmsD50Y, cmsD50Z};
|
||||
|
||||
return &D50XYZ;
|
||||
}
|
||||
|
||||
const cmsCIExyY* CMSEXPORT cmsD50_xyY(void)
|
||||
{
|
||||
static cmsCIExyY D50xyY;
|
||||
|
||||
cmsXYZ2xyY(&D50xyY, cmsD50_XYZ());
|
||||
|
||||
return &D50xyY;
|
||||
}
|
||||
|
||||
// Obtains WhitePoint from Temperature
|
||||
cmsBool CMSEXPORT cmsWhitePointFromTemp(cmsCIExyY* WhitePoint, cmsFloat64Number TempK)
|
||||
{
|
||||
cmsFloat64Number x, y;
|
||||
cmsFloat64Number T, T2, T3;
|
||||
// cmsFloat64Number M1, M2;
|
||||
|
||||
_cmsAssert(WhitePoint != NULL);
|
||||
|
||||
T = TempK;
|
||||
T2 = T*T; // Square
|
||||
T3 = T2*T; // Cube
|
||||
|
||||
// For correlated color temperature (T) between 4000K and 7000K:
|
||||
|
||||
if (T >= 4000. && T <= 7000.)
|
||||
{
|
||||
x = -4.6070*(1E9/T3) + 2.9678*(1E6/T2) + 0.09911*(1E3/T) + 0.244063;
|
||||
}
|
||||
else
|
||||
// or for correlated color temperature (T) between 7000K and 25000K:
|
||||
|
||||
if (T > 7000.0 && T <= 25000.0)
|
||||
{
|
||||
x = -2.0064*(1E9/T3) + 1.9018*(1E6/T2) + 0.24748*(1E3/T) + 0.237040;
|
||||
}
|
||||
else {
|
||||
cmsSignalError(0, cmsERROR_RANGE, "cmsWhitePointFromTemp: invalid temp");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Obtain y(x)
|
||||
|
||||
y = -3.000*(x*x) + 2.870*x - 0.275;
|
||||
|
||||
// wave factors (not used, but here for futures extensions)
|
||||
|
||||
// M1 = (-1.3515 - 1.7703*x + 5.9114 *y)/(0.0241 + 0.2562*x - 0.7341*y);
|
||||
// M2 = (0.0300 - 31.4424*x + 30.0717*y)/(0.0241 + 0.2562*x - 0.7341*y);
|
||||
|
||||
WhitePoint -> x = x;
|
||||
WhitePoint -> y = y;
|
||||
WhitePoint -> Y = 1.0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
cmsFloat64Number mirek; // temp (in microreciprocal kelvin)
|
||||
cmsFloat64Number ut; // u coord of intersection w/ blackbody locus
|
||||
cmsFloat64Number vt; // v coord of intersection w/ blackbody locus
|
||||
cmsFloat64Number tt; // slope of ISOTEMPERATURE. line
|
||||
|
||||
} ISOTEMPERATURE;
|
||||
|
||||
static ISOTEMPERATURE isotempdata[] = {
|
||||
// {Mirek, Ut, Vt, Tt }
|
||||
{0, 0.18006, 0.26352, -0.24341},
|
||||
{10, 0.18066, 0.26589, -0.25479},
|
||||
{20, 0.18133, 0.26846, -0.26876},
|
||||
{30, 0.18208, 0.27119, -0.28539},
|
||||
{40, 0.18293, 0.27407, -0.30470},
|
||||
{50, 0.18388, 0.27709, -0.32675},
|
||||
{60, 0.18494, 0.28021, -0.35156},
|
||||
{70, 0.18611, 0.28342, -0.37915},
|
||||
{80, 0.18740, 0.28668, -0.40955},
|
||||
{90, 0.18880, 0.28997, -0.44278},
|
||||
{100, 0.19032, 0.29326, -0.47888},
|
||||
{125, 0.19462, 0.30141, -0.58204},
|
||||
{150, 0.19962, 0.30921, -0.70471},
|
||||
{175, 0.20525, 0.31647, -0.84901},
|
||||
{200, 0.21142, 0.32312, -1.0182 },
|
||||
{225, 0.21807, 0.32909, -1.2168 },
|
||||
{250, 0.22511, 0.33439, -1.4512 },
|
||||
{275, 0.23247, 0.33904, -1.7298 },
|
||||
{300, 0.24010, 0.34308, -2.0637 },
|
||||
{325, 0.24702, 0.34655, -2.4681 },
|
||||
{350, 0.25591, 0.34951, -2.9641 },
|
||||
{375, 0.26400, 0.35200, -3.5814 },
|
||||
{400, 0.27218, 0.35407, -4.3633 },
|
||||
{425, 0.28039, 0.35577, -5.3762 },
|
||||
{450, 0.28863, 0.35714, -6.7262 },
|
||||
{475, 0.29685, 0.35823, -8.5955 },
|
||||
{500, 0.30505, 0.35907, -11.324 },
|
||||
{525, 0.31320, 0.35968, -15.628 },
|
||||
{550, 0.32129, 0.36011, -23.325 },
|
||||
{575, 0.32931, 0.36038, -40.770 },
|
||||
{600, 0.33724, 0.36051, -116.45 }
|
||||
};
|
||||
|
||||
#define NISO sizeof(isotempdata)/sizeof(ISOTEMPERATURE)
|
||||
|
||||
|
||||
// Robertson's method
|
||||
cmsBool CMSEXPORT cmsTempFromWhitePoint(cmsFloat64Number* TempK, const cmsCIExyY* WhitePoint)
|
||||
{
|
||||
int j;
|
||||
cmsFloat64Number us,vs;
|
||||
cmsFloat64Number uj,vj,tj,di,dj,mi,mj;
|
||||
cmsFloat64Number xs, ys;
|
||||
|
||||
_cmsAssert(WhitePoint != NULL);
|
||||
_cmsAssert(TempK != NULL);
|
||||
|
||||
di = mi = 0;
|
||||
xs = WhitePoint -> x;
|
||||
ys = WhitePoint -> y;
|
||||
|
||||
// convert (x,y) to CIE 1960 (u,WhitePoint)
|
||||
|
||||
us = (2*xs) / (-xs + 6*ys + 1.5);
|
||||
vs = (3*ys) / (-xs + 6*ys + 1.5);
|
||||
|
||||
|
||||
for (j=0; j < NISO; j++) {
|
||||
|
||||
uj = isotempdata[j].ut;
|
||||
vj = isotempdata[j].vt;
|
||||
tj = isotempdata[j].tt;
|
||||
mj = isotempdata[j].mirek;
|
||||
|
||||
dj = ((vs - vj) - tj * (us - uj)) / sqrt(1.0 + tj * tj);
|
||||
|
||||
if ((j != 0) && (di/dj < 0.0)) {
|
||||
|
||||
// Found a match
|
||||
*TempK = 1000000.0 / (mi + (di / (di - dj)) * (mj - mi));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
di = dj;
|
||||
mi = mj;
|
||||
}
|
||||
|
||||
// Not found
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
// Compute chromatic adaptation matrix using Chad as cone matrix
|
||||
|
||||
static
|
||||
cmsBool ComputeChromaticAdaptation(cmsMAT3* Conversion,
|
||||
const cmsCIEXYZ* SourceWhitePoint,
|
||||
const cmsCIEXYZ* DestWhitePoint,
|
||||
const cmsMAT3* Chad)
|
||||
|
||||
{
|
||||
|
||||
cmsMAT3 Chad_Inv;
|
||||
cmsVEC3 ConeSourceXYZ, ConeSourceRGB;
|
||||
cmsVEC3 ConeDestXYZ, ConeDestRGB;
|
||||
cmsMAT3 Cone, Tmp;
|
||||
|
||||
|
||||
Tmp = *Chad;
|
||||
if (!_cmsMAT3inverse(&Tmp, &Chad_Inv)) return FALSE;
|
||||
|
||||
_cmsVEC3init(&ConeSourceXYZ, SourceWhitePoint -> X,
|
||||
SourceWhitePoint -> Y,
|
||||
SourceWhitePoint -> Z);
|
||||
|
||||
_cmsVEC3init(&ConeDestXYZ, DestWhitePoint -> X,
|
||||
DestWhitePoint -> Y,
|
||||
DestWhitePoint -> Z);
|
||||
|
||||
_cmsMAT3eval(&ConeSourceRGB, Chad, &ConeSourceXYZ);
|
||||
_cmsMAT3eval(&ConeDestRGB, Chad, &ConeDestXYZ);
|
||||
|
||||
// Build matrix
|
||||
_cmsVEC3init(&Cone.v[0], ConeDestRGB.n[0]/ConeSourceRGB.n[0], 0.0, 0.0);
|
||||
_cmsVEC3init(&Cone.v[1], 0.0, ConeDestRGB.n[1]/ConeSourceRGB.n[1], 0.0);
|
||||
_cmsVEC3init(&Cone.v[2], 0.0, 0.0, ConeDestRGB.n[2]/ConeSourceRGB.n[2]);
|
||||
|
||||
|
||||
// Normalize
|
||||
_cmsMAT3per(&Tmp, &Cone, Chad);
|
||||
_cmsMAT3per(Conversion, &Chad_Inv, &Tmp);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Returns the final chrmatic adaptation from illuminant FromIll to Illuminant ToIll
|
||||
// The cone matrix can be specified in ConeMatrix. If NULL, Bradford is assumed
|
||||
cmsBool _cmsAdaptationMatrix(cmsMAT3* r, const cmsMAT3* ConeMatrix, const cmsCIEXYZ* FromIll, const cmsCIEXYZ* ToIll)
|
||||
{
|
||||
cmsMAT3 LamRigg = {{ // Bradford matrix
|
||||
{{ 0.8951, 0.2664, -0.1614 }},
|
||||
{{ -0.7502, 1.7135, 0.0367 }},
|
||||
{{ 0.0389, -0.0685, 1.0296 }}
|
||||
}};
|
||||
|
||||
if (ConeMatrix == NULL)
|
||||
ConeMatrix = &LamRigg;
|
||||
|
||||
return ComputeChromaticAdaptation(r, FromIll, ToIll, ConeMatrix);
|
||||
}
|
||||
|
||||
// Same as anterior, but assuming D50 destination. White point is given in xyY
|
||||
static
|
||||
cmsBool _cmsAdaptMatrixToD50(cmsMAT3* r, const cmsCIExyY* SourceWhitePt)
|
||||
{
|
||||
cmsCIEXYZ Dn;
|
||||
cmsMAT3 Bradford;
|
||||
cmsMAT3 Tmp;
|
||||
|
||||
cmsxyY2XYZ(&Dn, SourceWhitePt);
|
||||
|
||||
if (!_cmsAdaptationMatrix(&Bradford, NULL, &Dn, cmsD50_XYZ())) return FALSE;
|
||||
|
||||
Tmp = *r;
|
||||
_cmsMAT3per(r, &Bradford, &Tmp);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Build a White point, primary chromas transfer matrix from RGB to CIE XYZ
|
||||
// This is just an approximation, I am not handling all the non-linear
|
||||
// aspects of the RGB to XYZ process, and assumming that the gamma correction
|
||||
// has transitive property in the tranformation chain.
|
||||
//
|
||||
// the alghoritm:
|
||||
//
|
||||
// - First I build the absolute conversion matrix using
|
||||
// primaries in XYZ. This matrix is next inverted
|
||||
// - Then I eval the source white point across this matrix
|
||||
// obtaining the coeficients of the transformation
|
||||
// - Then, I apply these coeficients to the original matrix
|
||||
//
|
||||
cmsBool _cmsBuildRGB2XYZtransferMatrix(cmsMAT3* r, const cmsCIExyY* WhitePt, const cmsCIExyYTRIPLE* Primrs)
|
||||
{
|
||||
cmsVEC3 WhitePoint, Coef;
|
||||
cmsMAT3 Result, Primaries;
|
||||
cmsFloat64Number xn, yn;
|
||||
cmsFloat64Number xr, yr;
|
||||
cmsFloat64Number xg, yg;
|
||||
cmsFloat64Number xb, yb;
|
||||
|
||||
xn = WhitePt -> x;
|
||||
yn = WhitePt -> y;
|
||||
xr = Primrs -> Red.x;
|
||||
yr = Primrs -> Red.y;
|
||||
xg = Primrs -> Green.x;
|
||||
yg = Primrs -> Green.y;
|
||||
xb = Primrs -> Blue.x;
|
||||
yb = Primrs -> Blue.y;
|
||||
|
||||
// Build Primaries matrix
|
||||
_cmsVEC3init(&Primaries.v[0], xr, xg, xb);
|
||||
_cmsVEC3init(&Primaries.v[1], yr, yg, yb);
|
||||
_cmsVEC3init(&Primaries.v[2], (1-xr-yr), (1-xg-yg), (1-xb-yb));
|
||||
|
||||
|
||||
// Result = Primaries ^ (-1) inverse matrix
|
||||
if (!_cmsMAT3inverse(&Primaries, &Result))
|
||||
return FALSE;
|
||||
|
||||
|
||||
_cmsVEC3init(&WhitePoint, xn/yn, 1.0, (1.0-xn-yn)/yn);
|
||||
|
||||
// Across inverse primaries ...
|
||||
_cmsMAT3eval(&Coef, &Result, &WhitePoint);
|
||||
|
||||
// Give us the Coefs, then I build transformation matrix
|
||||
_cmsVEC3init(&r -> v[0], Coef.n[VX]*xr, Coef.n[VY]*xg, Coef.n[VZ]*xb);
|
||||
_cmsVEC3init(&r -> v[1], Coef.n[VX]*yr, Coef.n[VY]*yg, Coef.n[VZ]*yb);
|
||||
_cmsVEC3init(&r -> v[2], Coef.n[VX]*(1.0-xr-yr), Coef.n[VY]*(1.0-xg-yg), Coef.n[VZ]*(1.0-xb-yb));
|
||||
|
||||
|
||||
return _cmsAdaptMatrixToD50(r, WhitePt);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Adapts a color to a given illuminant. Original color is expected to have
|
||||
// a SourceWhitePt white point.
|
||||
cmsBool CMSEXPORT cmsAdaptToIlluminant(cmsCIEXYZ* Result,
|
||||
const cmsCIEXYZ* SourceWhitePt,
|
||||
const cmsCIEXYZ* Illuminant,
|
||||
const cmsCIEXYZ* Value)
|
||||
{
|
||||
cmsMAT3 Bradford;
|
||||
cmsVEC3 In, Out;
|
||||
|
||||
_cmsAssert(Result != NULL);
|
||||
_cmsAssert(SourceWhitePt != NULL);
|
||||
_cmsAssert(Illuminant != NULL);
|
||||
_cmsAssert(Value != NULL);
|
||||
|
||||
if (!_cmsAdaptationMatrix(&Bradford, NULL, SourceWhitePt, Illuminant)) return FALSE;
|
||||
|
||||
_cmsVEC3init(&In, Value -> X, Value -> Y, Value -> Z);
|
||||
_cmsMAT3eval(&Out, &Bradford, &In);
|
||||
|
||||
Result -> X = Out.n[0];
|
||||
Result -> Y = Out.n[1];
|
||||
Result -> Z = Out.n[2];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
809
thirdparty/liblcms2/src/cmsxform.c
vendored
Normal file
809
thirdparty/liblcms2/src/cmsxform.c
vendored
Normal file
@ -0,0 +1,809 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
//
|
||||
// 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 "lcms2_internal.h"
|
||||
|
||||
// Transformations stuff
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
// Alarm codes for 16-bit transformations, because the fixed range of containers there are
|
||||
// no values left to mark out of gamut. volatile is C99 per 6.2.5
|
||||
static volatile cmsUInt16Number Alarm[cmsMAXCHANNELS];
|
||||
static volatile cmsFloat64Number GlobalAdaptationState = 0;
|
||||
|
||||
// The adaptation state may be defaulted by this function. If you don't like it, use the extended transform routine
|
||||
cmsFloat64Number CMSEXPORT cmsSetAdaptationState(cmsFloat64Number d)
|
||||
{
|
||||
cmsFloat64Number OldVal = GlobalAdaptationState;
|
||||
|
||||
if (d >= 0)
|
||||
GlobalAdaptationState = d;
|
||||
|
||||
return OldVal;
|
||||
}
|
||||
|
||||
// Alarm codes are always global
|
||||
void CMSEXPORT cmsSetAlarmCodes(cmsUInt16Number NewAlarm[cmsMAXCHANNELS])
|
||||
{
|
||||
int i;
|
||||
|
||||
_cmsAssert(NewAlarm != NULL);
|
||||
|
||||
for (i=0; i < cmsMAXCHANNELS; i++)
|
||||
Alarm[i] = NewAlarm[i];
|
||||
}
|
||||
|
||||
// You can get the codes cas well
|
||||
void CMSEXPORT cmsGetAlarmCodes(cmsUInt16Number OldAlarm[cmsMAXCHANNELS])
|
||||
{
|
||||
int i;
|
||||
|
||||
_cmsAssert(OldAlarm != NULL);
|
||||
|
||||
for (i=0; i < cmsMAXCHANNELS; i++)
|
||||
OldAlarm[i] = Alarm[i];
|
||||
}
|
||||
|
||||
// Get rid of transform resources
|
||||
void CMSEXPORT cmsDeleteTransform(cmsHTRANSFORM hTransform)
|
||||
{
|
||||
_cmsTRANSFORM* p = (_cmsTRANSFORM*) hTransform;
|
||||
|
||||
_cmsAssert(p != NULL);
|
||||
|
||||
if (p -> GamutCheck)
|
||||
cmsPipelineFree(p -> GamutCheck);
|
||||
|
||||
if (p -> Lut)
|
||||
cmsPipelineFree(p -> Lut);
|
||||
|
||||
if (p ->InputColorant)
|
||||
cmsFreeNamedColorList(p ->InputColorant);
|
||||
|
||||
if (p -> OutputColorant)
|
||||
cmsFreeNamedColorList(p ->OutputColorant);
|
||||
|
||||
if (p ->Sequence)
|
||||
cmsFreeProfileSequenceDescription(p ->Sequence);
|
||||
|
||||
LCMS_FREE_LOCK(&p->rwlock);
|
||||
_cmsFree(p ->ContextID, (void *) p);
|
||||
}
|
||||
|
||||
// Apply transform
|
||||
void CMSEXPORT cmsDoTransform(cmsHTRANSFORM Transform,
|
||||
const void* InputBuffer,
|
||||
void* OutputBuffer,
|
||||
cmsUInt32Number Size)
|
||||
|
||||
{
|
||||
_cmsTRANSFORM* p = (_cmsTRANSFORM*) Transform;
|
||||
|
||||
p -> xform(p, InputBuffer, OutputBuffer, Size);
|
||||
}
|
||||
|
||||
|
||||
// Transform routines ----------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Float xform converts floats. Since there are no performance issues, one routine does all job, including gamut check.
|
||||
// Note that because extended range, we can use a -1.0 value for out of gamut in this case.
|
||||
static
|
||||
void FloatXFORM(_cmsTRANSFORM* p,
|
||||
const void* in,
|
||||
void* out, cmsUInt32Number Size)
|
||||
{
|
||||
cmsUInt8Number* accum;
|
||||
cmsUInt8Number* output;
|
||||
cmsFloat32Number fIn[cmsMAXCHANNELS], fOut[cmsMAXCHANNELS];
|
||||
cmsFloat32Number OutOfGamut;
|
||||
cmsUInt32Number i, j;
|
||||
|
||||
accum = (cmsUInt8Number*) in;
|
||||
output = (cmsUInt8Number*) out;
|
||||
|
||||
for (i=0; i < Size; i++) {
|
||||
|
||||
accum = p -> FromInputFloat(p, fIn, accum, Size);
|
||||
|
||||
// Any gamut chack to do?
|
||||
if (p ->GamutCheck != NULL) {
|
||||
|
||||
// Evaluate gamut marker.
|
||||
cmsPipelineEvalFloat( fIn, &OutOfGamut, p ->GamutCheck);
|
||||
|
||||
// Is current color out of gamut?
|
||||
if (OutOfGamut > 0.0) {
|
||||
|
||||
// Certainly, out of gamut
|
||||
for (j=0; j < cmsMAXCHANNELS; j++)
|
||||
fOut[j] = -1.0;
|
||||
|
||||
}
|
||||
else {
|
||||
// No, proceed normally
|
||||
cmsPipelineEvalFloat(fIn, fOut, p -> Lut);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
// No gamut check at all
|
||||
cmsPipelineEvalFloat(fIn, fOut, p -> Lut);
|
||||
}
|
||||
|
||||
// Back to asked representation
|
||||
output = p -> ToOutputFloat(p, fOut, output, Size);
|
||||
}
|
||||
}
|
||||
|
||||
// 16 bit precision -----------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Null transformation, only applies formatters. No caché
|
||||
static
|
||||
void NullXFORM(_cmsTRANSFORM* p,
|
||||
const void* in,
|
||||
void* out, cmsUInt32Number Size)
|
||||
{
|
||||
cmsUInt8Number* accum;
|
||||
cmsUInt8Number* output;
|
||||
cmsUInt16Number wIn[cmsMAXCHANNELS];
|
||||
cmsUInt32Number i, n;
|
||||
|
||||
accum = (cmsUInt8Number*) in;
|
||||
output = (cmsUInt8Number*) out;
|
||||
n = Size; // Buffer len
|
||||
|
||||
for (i=0; i < n; i++) {
|
||||
|
||||
accum = p -> FromInput(p, wIn, accum, Size);
|
||||
output = p -> ToOutput(p, wIn, output, Size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// No gamut check, no cache, 16 bits
|
||||
static
|
||||
void PrecalculatedXFORM(_cmsTRANSFORM* p,
|
||||
const void* in,
|
||||
void* out, cmsUInt32Number Size)
|
||||
{
|
||||
register cmsUInt8Number* accum;
|
||||
register cmsUInt8Number* output;
|
||||
cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
|
||||
cmsUInt32Number i, n;
|
||||
|
||||
accum = (cmsUInt8Number*) in;
|
||||
output = (cmsUInt8Number*) out;
|
||||
n = Size;
|
||||
|
||||
for (i=0; i < n; i++) {
|
||||
|
||||
accum = p -> FromInput(p, wIn, accum, Size);
|
||||
p ->Lut ->Eval16Fn(wIn, wOut, p -> Lut->Data);
|
||||
output = p -> ToOutput(p, wOut, output, Size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Auxiliar: Handle precalculated gamut check
|
||||
static
|
||||
void TransformOnePixelWithGamutCheck(_cmsTRANSFORM* p,
|
||||
const cmsUInt16Number wIn[],
|
||||
cmsUInt16Number wOut[])
|
||||
{
|
||||
cmsUInt16Number wOutOfGamut;
|
||||
|
||||
p ->GamutCheck ->Eval16Fn(wIn, &wOutOfGamut, p ->GamutCheck ->Data);
|
||||
if (wOutOfGamut >= 1) {
|
||||
|
||||
cmsUInt16Number i;
|
||||
|
||||
for (i=0; i < p ->Lut->OutputChannels; i++)
|
||||
wOut[i] = Alarm[i];
|
||||
}
|
||||
else
|
||||
p ->Lut ->Eval16Fn(wIn, wOut, p -> Lut->Data);
|
||||
}
|
||||
|
||||
// Gamut check, No caché, 16 bits.
|
||||
static
|
||||
void PrecalculatedXFORMGamutCheck(_cmsTRANSFORM* p,
|
||||
const void* in,
|
||||
void* out, cmsUInt32Number Size)
|
||||
{
|
||||
cmsUInt8Number* accum;
|
||||
cmsUInt8Number* output;
|
||||
cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
|
||||
cmsUInt32Number i, n;
|
||||
|
||||
accum = (cmsUInt8Number*) in;
|
||||
output = (cmsUInt8Number*) out;
|
||||
n = Size; // Buffer len
|
||||
|
||||
for (i=0; i < n; i++) {
|
||||
|
||||
accum = p -> FromInput(p, wIn, accum, Size);
|
||||
TransformOnePixelWithGamutCheck(p, wIn, wOut);
|
||||
output = p -> ToOutput(p, wOut, output, Size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// No gamut check, Caché, 16 bits,
|
||||
static
|
||||
void CachedXFORM(_cmsTRANSFORM* p,
|
||||
const void* in,
|
||||
void* out, cmsUInt32Number Size)
|
||||
{
|
||||
cmsUInt8Number* accum;
|
||||
cmsUInt8Number* output;
|
||||
cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
|
||||
cmsUInt32Number i, n;
|
||||
cmsUInt16Number CacheIn[cmsMAXCHANNELS], CacheOut[cmsMAXCHANNELS];
|
||||
|
||||
accum = (cmsUInt8Number*) in;
|
||||
output = (cmsUInt8Number*) out;
|
||||
n = Size; // Buffer len
|
||||
|
||||
// Empty buffers for quick memcmp
|
||||
memset(wIn, 0, sizeof(wIn));
|
||||
memset(wOut, 0, sizeof(wOut));
|
||||
|
||||
|
||||
LCMS_READ_LOCK(&p ->rwlock);
|
||||
memmove(CacheIn, p ->CacheIn, sizeof(CacheIn));
|
||||
memmove(CacheOut, p ->CacheOut, sizeof(CacheOut));
|
||||
LCMS_UNLOCK(&p ->rwlock);
|
||||
|
||||
for (i=0; i < n; i++) {
|
||||
|
||||
accum = p -> FromInput(p, wIn, accum, Size);
|
||||
|
||||
if (memcmp(wIn, CacheIn, sizeof(CacheIn)) == 0) {
|
||||
|
||||
memmove(wOut, CacheOut, sizeof(CacheOut));
|
||||
}
|
||||
else {
|
||||
|
||||
p ->Lut ->Eval16Fn(wIn, wOut, p -> Lut->Data);
|
||||
|
||||
memmove(CacheIn, wIn, sizeof(CacheIn));
|
||||
memmove(CacheOut, wOut, sizeof(CacheOut));
|
||||
}
|
||||
|
||||
output = p -> ToOutput(p, wOut, output, Size);
|
||||
}
|
||||
|
||||
|
||||
LCMS_WRITE_LOCK(&p ->rwlock);
|
||||
memmove(p->CacheIn, CacheIn, sizeof(CacheIn));
|
||||
memmove(p->CacheOut, CacheOut, sizeof(CacheOut));
|
||||
LCMS_UNLOCK(&p ->rwlock);
|
||||
}
|
||||
|
||||
|
||||
// All those nice features together
|
||||
static
|
||||
void CachedXFORMGamutCheck(_cmsTRANSFORM* p,
|
||||
const void* in,
|
||||
void* out, cmsUInt32Number Size)
|
||||
{
|
||||
cmsUInt8Number* accum;
|
||||
cmsUInt8Number* output;
|
||||
cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
|
||||
cmsUInt32Number i, n;
|
||||
cmsUInt16Number CacheIn[cmsMAXCHANNELS], CacheOut[cmsMAXCHANNELS];
|
||||
|
||||
accum = (cmsUInt8Number*) in;
|
||||
output = (cmsUInt8Number*) out;
|
||||
n = Size; // Buffer len
|
||||
|
||||
// Empty buffers for quick memcmp
|
||||
memset(wIn, 0, sizeof(cmsUInt16Number) * cmsMAXCHANNELS);
|
||||
memset(wOut, 0, sizeof(cmsUInt16Number) * cmsMAXCHANNELS);
|
||||
|
||||
LCMS_READ_LOCK(&p ->rwlock);
|
||||
memmove(CacheIn, p ->CacheIn, sizeof(cmsUInt16Number) * cmsMAXCHANNELS);
|
||||
memmove(CacheOut, p ->CacheOut, sizeof(cmsUInt16Number) * cmsMAXCHANNELS);
|
||||
LCMS_UNLOCK(&p ->rwlock);
|
||||
|
||||
|
||||
for (i=0; i < n; i++) {
|
||||
|
||||
accum = p -> FromInput(p, wIn, accum, Size);
|
||||
|
||||
if (memcmp(wIn, CacheIn, sizeof(cmsUInt16Number) * cmsMAXCHANNELS) == 0) {
|
||||
memmove(wOut, CacheOut, sizeof(cmsUInt16Number) * cmsMAXCHANNELS);
|
||||
}
|
||||
else {
|
||||
TransformOnePixelWithGamutCheck(p, wIn, wOut);
|
||||
memmove(CacheIn, wIn, sizeof(cmsUInt16Number) * cmsMAXCHANNELS);
|
||||
memmove(CacheOut, wOut, sizeof(cmsUInt16Number) * cmsMAXCHANNELS);
|
||||
}
|
||||
|
||||
output = p -> ToOutput(p, wOut, output, Size);
|
||||
}
|
||||
|
||||
LCMS_WRITE_LOCK(&p ->rwlock);
|
||||
memmove(p->CacheIn, CacheIn, sizeof(cmsUInt16Number) * cmsMAXCHANNELS);
|
||||
memmove(p->CacheOut, CacheOut, sizeof(cmsUInt16Number) * cmsMAXCHANNELS);
|
||||
LCMS_UNLOCK(&p ->rwlock);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Allocate transform struct and set it to defaults
|
||||
static
|
||||
_cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsUInt32Number InputFormat, cmsUInt32Number OutputFormat, cmsUInt32Number dwFlags)
|
||||
{
|
||||
// Allocate needed memory
|
||||
_cmsTRANSFORM* p = (_cmsTRANSFORM*) _cmsMallocZero(ContextID, sizeof(_cmsTRANSFORM));
|
||||
if (!p) return NULL;
|
||||
|
||||
// Check whatever this is a true floating point transform
|
||||
if (_cmsFormatterIsFloat(InputFormat) && _cmsFormatterIsFloat(OutputFormat)) {
|
||||
|
||||
// Get formatter function always return a valid union, but the contents of this union may be NULL.
|
||||
p ->FromInputFloat = _cmsGetFormatter(InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
|
||||
p ->ToOutputFloat = _cmsGetFormatter(OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
|
||||
dwFlags |= cmsFLAGS_CAN_CHANGE_FORMATTER;
|
||||
|
||||
if (p ->FromInputFloat == NULL || p ->ToOutputFloat == NULL) {
|
||||
|
||||
cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported raster format");
|
||||
_cmsFree(ContextID, p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Float transforms don't use caché, always are non-NULL
|
||||
p ->xform = FloatXFORM;
|
||||
}
|
||||
else {
|
||||
|
||||
if (InputFormat == 0 && OutputFormat == 0) {
|
||||
p ->FromInput = p ->ToOutput = NULL;
|
||||
}
|
||||
else {
|
||||
|
||||
int BytesPerPixelInput;
|
||||
|
||||
p ->FromInput = _cmsGetFormatter(InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16;
|
||||
p ->ToOutput = _cmsGetFormatter(OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16;
|
||||
|
||||
|
||||
if (p ->FromInput == NULL || p ->ToOutput == NULL) {
|
||||
|
||||
cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported raster format");
|
||||
_cmsFree(ContextID, p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BytesPerPixelInput = T_BYTES(p ->InputFormat);
|
||||
if (BytesPerPixelInput == 0 || BytesPerPixelInput >= 2)
|
||||
dwFlags |= cmsFLAGS_CAN_CHANGE_FORMATTER;
|
||||
|
||||
}
|
||||
|
||||
if (dwFlags & cmsFLAGS_NULLTRANSFORM) {
|
||||
|
||||
p ->xform = NullXFORM;
|
||||
}
|
||||
else {
|
||||
if (dwFlags & cmsFLAGS_NOCACHE) {
|
||||
|
||||
if (dwFlags & cmsFLAGS_GAMUTCHECK)
|
||||
p ->xform = PrecalculatedXFORMGamutCheck; // Gamut check, no caché
|
||||
else
|
||||
p ->xform = PrecalculatedXFORM; // No caché, no gamut check
|
||||
}
|
||||
else {
|
||||
|
||||
if (dwFlags & cmsFLAGS_GAMUTCHECK)
|
||||
p ->xform = CachedXFORMGamutCheck; // Gamut check, caché
|
||||
else
|
||||
p ->xform = CachedXFORM; // No gamut check, caché
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Create a mutex for shared memory
|
||||
LCMS_CREATE_LOCK(&p->rwlock);
|
||||
|
||||
p ->InputFormat = InputFormat;
|
||||
p ->OutputFormat = OutputFormat;
|
||||
p ->dwOriginalFlags = dwFlags;
|
||||
p ->ContextID = ContextID;
|
||||
return p;
|
||||
}
|
||||
|
||||
static
|
||||
cmsBool GetXFormColorSpaces(int nProfiles, cmsHPROFILE hProfiles[], cmsColorSpaceSignature* Input, cmsColorSpaceSignature* Output)
|
||||
{
|
||||
cmsColorSpaceSignature ColorSpaceIn, ColorSpaceOut;
|
||||
cmsColorSpaceSignature PostColorSpace;
|
||||
int i;
|
||||
|
||||
if (hProfiles[0] == NULL) return FALSE;
|
||||
|
||||
*Input = PostColorSpace = cmsGetColorSpace(hProfiles[0]);
|
||||
|
||||
for (i=0; i < nProfiles; i++) {
|
||||
|
||||
cmsHPROFILE hProfile = hProfiles[i];
|
||||
|
||||
int lIsInput = (PostColorSpace != cmsSigXYZData) &&
|
||||
(PostColorSpace != cmsSigLabData);
|
||||
|
||||
if (hProfile == NULL) return FALSE;
|
||||
|
||||
if (lIsInput) {
|
||||
|
||||
ColorSpaceIn = cmsGetColorSpace(hProfile);
|
||||
ColorSpaceOut = cmsGetPCS(hProfile);
|
||||
}
|
||||
else {
|
||||
|
||||
ColorSpaceIn = cmsGetPCS(hProfile);
|
||||
ColorSpaceOut = cmsGetColorSpace(hProfile);
|
||||
}
|
||||
|
||||
PostColorSpace = ColorSpaceOut;
|
||||
}
|
||||
|
||||
*Output = PostColorSpace;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Check colorspace
|
||||
static
|
||||
cmsBool IsProperColorSpace(cmsColorSpaceSignature Check, cmsUInt32Number dwFormat)
|
||||
{
|
||||
int Space1 = T_COLORSPACE(dwFormat);
|
||||
int Space2 = _cmsLCMScolorSpace(Check);
|
||||
|
||||
if (Space1 == PT_ANY) return TRUE;
|
||||
if (Space1 == Space2) return TRUE;
|
||||
|
||||
if (Space1 == PT_LabV2 && Space2 == PT_Lab) return TRUE;
|
||||
if (Space1 == PT_Lab && Space2 == PT_LabV2) return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// New to lcms 2.0 -- have all parameters available.
|
||||
cmsHTRANSFORM CMSEXPORT cmsCreateExtendedTransform(cmsContext ContextID,
|
||||
cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[],
|
||||
cmsBool BPC[],
|
||||
cmsUInt32Number Intents[],
|
||||
cmsFloat64Number AdaptationStates[],
|
||||
cmsHPROFILE hGamutProfile,
|
||||
cmsUInt32Number nGamutPCSposition,
|
||||
cmsUInt32Number InputFormat,
|
||||
cmsUInt32Number OutputFormat,
|
||||
cmsUInt32Number dwFlags)
|
||||
{
|
||||
_cmsTRANSFORM* xform;
|
||||
cmsBool FloatTransform;
|
||||
cmsColorSpaceSignature EntryColorSpace;
|
||||
cmsColorSpaceSignature ExitColorSpace;
|
||||
cmsPipeline* Lut;
|
||||
cmsUInt32Number LastIntent = Intents[nProfiles-1];
|
||||
|
||||
// If gamut check is requested, make sure we have a gamut profile
|
||||
if (dwFlags & cmsFLAGS_GAMUTCHECK) {
|
||||
if (hGamutProfile == NULL) dwFlags &= ~cmsFLAGS_GAMUTCHECK;
|
||||
}
|
||||
|
||||
// On floating point transforms, inhibit optimizations
|
||||
FloatTransform = (_cmsFormatterIsFloat(InputFormat) && _cmsFormatterIsFloat(OutputFormat));
|
||||
|
||||
if (_cmsFormatterIsFloat(InputFormat) || _cmsFormatterIsFloat(OutputFormat))
|
||||
dwFlags |= cmsFLAGS_NOCACHE;
|
||||
|
||||
// Mark entry/exit spaces
|
||||
if (!GetXFormColorSpaces(nProfiles, hProfiles, &EntryColorSpace, &ExitColorSpace)) {
|
||||
cmsSignalError(ContextID, cmsERROR_NULL, "NULL input profiles on transform");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Check if proper colorspaces
|
||||
if (!IsProperColorSpace(EntryColorSpace, InputFormat)) {
|
||||
cmsSignalError(ContextID, cmsERROR_COLORSPACE_CHECK, "Wrong input color space on transform");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!IsProperColorSpace(ExitColorSpace, OutputFormat)) {
|
||||
cmsSignalError(ContextID, cmsERROR_COLORSPACE_CHECK, "Wrong output color space on transform");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Create a pipeline with all transformations
|
||||
Lut = _cmsLinkProfiles(ContextID, nProfiles, Intents, hProfiles, BPC, AdaptationStates, dwFlags);
|
||||
if (Lut == NULL) {
|
||||
cmsSignalError(ContextID, cmsERROR_NOT_SUITABLE, "Couldn't link the profiles");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Optimize the LUT if possible
|
||||
_cmsOptimizePipeline(&Lut, LastIntent, &InputFormat, &OutputFormat, &dwFlags);
|
||||
|
||||
|
||||
// All seems ok
|
||||
xform = AllocEmptyTransform(ContextID, InputFormat, OutputFormat, dwFlags);
|
||||
if (xform == NULL) {
|
||||
cmsPipelineFree(Lut);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Keep values
|
||||
xform ->EntryColorSpace = EntryColorSpace;
|
||||
xform ->ExitColorSpace = ExitColorSpace;
|
||||
xform ->Lut = Lut;
|
||||
|
||||
|
||||
// Create a gamut check LUT if requested
|
||||
if (hGamutProfile != NULL && (dwFlags & cmsFLAGS_GAMUTCHECK))
|
||||
xform ->GamutCheck = _cmsCreateGamutCheckPipeline(ContextID, hProfiles,
|
||||
BPC, Intents,
|
||||
AdaptationStates,
|
||||
nGamutPCSposition,
|
||||
hGamutProfile);
|
||||
|
||||
|
||||
// Try to read input and output colorant table
|
||||
if (cmsIsTag(hProfiles[0], cmsSigColorantTableTag)) {
|
||||
|
||||
// Input table can only come in this way.
|
||||
xform ->InputColorant = cmsDupNamedColorList((cmsNAMEDCOLORLIST*) cmsReadTag(hProfiles[0], cmsSigColorantTableTag));
|
||||
}
|
||||
|
||||
// Output is a little bit more complex.
|
||||
if (cmsGetDeviceClass(hProfiles[nProfiles-1]) == cmsSigLinkClass) {
|
||||
|
||||
// This tag may exist only on devicelink profiles.
|
||||
if (cmsIsTag(hProfiles[nProfiles-1], cmsSigColorantTableOutTag)) {
|
||||
|
||||
// It may be NULL if error
|
||||
xform ->OutputColorant = cmsDupNamedColorList((cmsNAMEDCOLORLIST*) cmsReadTag(hProfiles[nProfiles-1], cmsSigColorantTableOutTag));
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (cmsIsTag(hProfiles[nProfiles-1], cmsSigColorantTableTag)) {
|
||||
|
||||
xform -> OutputColorant = cmsDupNamedColorList((cmsNAMEDCOLORLIST*) cmsReadTag(hProfiles[nProfiles-1], cmsSigColorantTableTag));
|
||||
}
|
||||
}
|
||||
|
||||
// Store the sequence of profiles
|
||||
if (dwFlags & cmsFLAGS_KEEP_SEQUENCE) {
|
||||
xform ->Sequence = _cmsCompileProfileSequence(ContextID, nProfiles, hProfiles);
|
||||
}
|
||||
else
|
||||
xform ->Sequence = NULL;
|
||||
|
||||
// If this is a cached transform, init first value, which is zero (16 bits only)
|
||||
if (!(dwFlags & cmsFLAGS_NOCACHE)) {
|
||||
|
||||
memset(&xform ->CacheIn, 0, sizeof(xform ->CacheIn));
|
||||
|
||||
if (xform ->GamutCheck != NULL) {
|
||||
TransformOnePixelWithGamutCheck(xform, xform ->CacheIn, xform->CacheOut);
|
||||
}
|
||||
else {
|
||||
|
||||
xform ->Lut ->Eval16Fn(xform ->CacheIn, xform->CacheOut, xform -> Lut->Data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return (cmsHTRANSFORM) xform;
|
||||
}
|
||||
|
||||
// Multiprofile transforms: Gamut check is not available here, as it is unclear from which profile the gamut comes.
|
||||
|
||||
cmsHTRANSFORM CMSEXPORT cmsCreateMultiprofileTransformTHR(cmsContext ContextID,
|
||||
cmsHPROFILE hProfiles[],
|
||||
cmsUInt32Number nProfiles,
|
||||
cmsUInt32Number InputFormat,
|
||||
cmsUInt32Number OutputFormat,
|
||||
cmsUInt32Number Intent,
|
||||
cmsUInt32Number dwFlags)
|
||||
{
|
||||
cmsUInt32Number i;
|
||||
cmsBool BPC[256];
|
||||
cmsUInt32Number Intents[256];
|
||||
cmsFloat64Number AdaptationStates[256];
|
||||
|
||||
if (nProfiles <= 0 || nProfiles > 255) {
|
||||
cmsSignalError(ContextID, cmsERROR_RANGE, "Wrong number of profiles. 1..255 expected, %d found.", nProfiles);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i=0; i < nProfiles; i++) {
|
||||
BPC[i] = dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION ? TRUE : FALSE;
|
||||
Intents[i] = Intent;
|
||||
AdaptationStates[i] = GlobalAdaptationState;
|
||||
}
|
||||
|
||||
|
||||
return cmsCreateExtendedTransform(ContextID, nProfiles, hProfiles, BPC, Intents, AdaptationStates, NULL, 0, InputFormat, OutputFormat, dwFlags);
|
||||
}
|
||||
|
||||
|
||||
|
||||
cmsHTRANSFORM CMSEXPORT cmsCreateMultiprofileTransform(cmsHPROFILE hProfiles[],
|
||||
cmsUInt32Number nProfiles,
|
||||
cmsUInt32Number InputFormat,
|
||||
cmsUInt32Number OutputFormat,
|
||||
cmsUInt32Number Intent,
|
||||
cmsUInt32Number dwFlags)
|
||||
{
|
||||
|
||||
if (nProfiles <= 0 || nProfiles > 255) {
|
||||
cmsSignalError(NULL, cmsERROR_RANGE, "Wrong number of profiles. 1..255 expected, %d found.", nProfiles);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return cmsCreateMultiprofileTransformTHR(cmsGetProfileContextID(hProfiles[0]),
|
||||
hProfiles,
|
||||
nProfiles,
|
||||
InputFormat,
|
||||
OutputFormat,
|
||||
Intent,
|
||||
dwFlags);
|
||||
}
|
||||
|
||||
cmsHTRANSFORM CMSEXPORT cmsCreateTransformTHR(cmsContext ContextID,
|
||||
cmsHPROFILE Input,
|
||||
cmsUInt32Number InputFormat,
|
||||
cmsHPROFILE Output,
|
||||
cmsUInt32Number OutputFormat,
|
||||
cmsUInt32Number Intent,
|
||||
cmsUInt32Number dwFlags)
|
||||
{
|
||||
|
||||
cmsHPROFILE hArray[2];
|
||||
|
||||
hArray[0] = Input;
|
||||
hArray[1] = Output;
|
||||
|
||||
return cmsCreateMultiprofileTransformTHR(ContextID, hArray, Output == NULL ? 1 : 2, InputFormat, OutputFormat, Intent, dwFlags);
|
||||
}
|
||||
|
||||
CMSAPI cmsHTRANSFORM CMSEXPORT cmsCreateTransform(cmsHPROFILE Input,
|
||||
cmsUInt32Number InputFormat,
|
||||
cmsHPROFILE Output,
|
||||
cmsUInt32Number OutputFormat,
|
||||
cmsUInt32Number Intent,
|
||||
cmsUInt32Number dwFlags)
|
||||
{
|
||||
return cmsCreateTransformTHR(cmsGetProfileContextID(Input), Input, InputFormat, Output, OutputFormat, Intent, dwFlags);
|
||||
}
|
||||
|
||||
|
||||
cmsHTRANSFORM CMSEXPORT cmsCreateProofingTransformTHR(cmsContext ContextID,
|
||||
cmsHPROFILE InputProfile,
|
||||
cmsUInt32Number InputFormat,
|
||||
cmsHPROFILE OutputProfile,
|
||||
cmsUInt32Number OutputFormat,
|
||||
cmsHPROFILE ProofingProfile,
|
||||
cmsUInt32Number nIntent,
|
||||
cmsUInt32Number ProofingIntent,
|
||||
cmsUInt32Number dwFlags)
|
||||
{
|
||||
cmsHPROFILE hArray[4];
|
||||
cmsUInt32Number Intents[4];
|
||||
cmsBool BPC[4];
|
||||
cmsFloat64Number Adaptation[4];
|
||||
cmsBool DoBPC = (dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION) ? TRUE : FALSE;
|
||||
|
||||
|
||||
hArray[0] = InputProfile; hArray[1] = ProofingProfile; hArray[2] = ProofingProfile; hArray[3] = OutputProfile;
|
||||
Intents[0] = nIntent; Intents[1] = nIntent; Intents[2] = INTENT_RELATIVE_COLORIMETRIC; Intents[3] = ProofingIntent;
|
||||
BPC[0] = DoBPC; BPC[1] = DoBPC; BPC[2] = 0; BPC[3] = 0;
|
||||
|
||||
Adaptation[0] = Adaptation[1] = Adaptation[2] = Adaptation[3] = GlobalAdaptationState;
|
||||
|
||||
if (!(dwFlags & (cmsFLAGS_SOFTPROOFING|cmsFLAGS_GAMUTCHECK)))
|
||||
return cmsCreateTransformTHR(ContextID, InputProfile, InputFormat, OutputProfile, OutputFormat, nIntent, dwFlags);
|
||||
|
||||
return cmsCreateExtendedTransform(ContextID, 4, hArray, BPC, Intents, Adaptation,
|
||||
ProofingProfile, 1, InputFormat, OutputFormat, dwFlags);
|
||||
|
||||
}
|
||||
|
||||
|
||||
cmsHTRANSFORM CMSEXPORT cmsCreateProofingTransform(cmsHPROFILE InputProfile,
|
||||
cmsUInt32Number InputFormat,
|
||||
cmsHPROFILE OutputProfile,
|
||||
cmsUInt32Number OutputFormat,
|
||||
cmsHPROFILE ProofingProfile,
|
||||
cmsUInt32Number nIntent,
|
||||
cmsUInt32Number ProofingIntent,
|
||||
cmsUInt32Number dwFlags)
|
||||
{
|
||||
return cmsCreateProofingTransformTHR(cmsGetProfileContextID(InputProfile),
|
||||
InputProfile,
|
||||
InputFormat,
|
||||
OutputProfile,
|
||||
OutputFormat,
|
||||
ProofingProfile,
|
||||
nIntent,
|
||||
ProofingIntent,
|
||||
dwFlags);
|
||||
}
|
||||
|
||||
|
||||
// Grab the ContextID from an open transform. Returns NULL if a NULL transform is passed
|
||||
cmsContext CMSEXPORT cmsGetTransformContextID(cmsHTRANSFORM hTransform)
|
||||
{
|
||||
_cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform;
|
||||
|
||||
if (xform == NULL) return NULL;
|
||||
return xform -> ContextID;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// For backwards compatibility
|
||||
cmsBool CMSEXPORT cmsChangeBuffersFormat(cmsHTRANSFORM hTransform,
|
||||
cmsUInt32Number InputFormat,
|
||||
cmsUInt32Number OutputFormat)
|
||||
{
|
||||
|
||||
_cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform;
|
||||
cmsFormatter16 FromInput, ToOutput;
|
||||
cmsUInt32Number BytesPerPixelInput;
|
||||
|
||||
// We only can afford to change formatters if previous transform is at least 16 bits
|
||||
BytesPerPixelInput = T_BYTES(xform ->InputFormat);
|
||||
if (!(xform ->dwOriginalFlags & cmsFLAGS_CAN_CHANGE_FORMATTER)) {
|
||||
|
||||
cmsSignalError(xform ->ContextID, cmsERROR_NOT_SUITABLE, "cmsChangeBuffersFormat works only on transforms created originally with at least 16 bits of precision");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FromInput = _cmsGetFormatter(InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16;
|
||||
ToOutput = _cmsGetFormatter(OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16;
|
||||
|
||||
if (FromInput == NULL || ToOutput == NULL) {
|
||||
|
||||
cmsSignalError(xform -> ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported raster format");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
xform ->InputFormat = InputFormat;
|
||||
xform ->OutputFormat = OutputFormat;
|
||||
xform ->FromInput = FromInput;
|
||||
xform ->ToOutput = ToOutput;
|
||||
return TRUE;
|
||||
}
|
300
thirdparty/liblcms2/src/lcms2.def
vendored
Normal file
300
thirdparty/liblcms2/src/lcms2.def
vendored
Normal file
@ -0,0 +1,300 @@
|
||||
LIBRARY LCMS2.DLL
|
||||
|
||||
EXPORTS
|
||||
|
||||
_cms15Fixed16toDouble = _cms15Fixed16toDouble
|
||||
_cms8Fixed8toDouble = _cms8Fixed8toDouble
|
||||
cmsAdaptToIlluminant = cmsAdaptToIlluminant
|
||||
_cmsAdjustEndianess16 = _cmsAdjustEndianess16
|
||||
_cmsAdjustEndianess32 = _cmsAdjustEndianess32
|
||||
_cmsAdjustEndianess64 = _cmsAdjustEndianess64
|
||||
cmsAllocNamedColorList = cmsAllocNamedColorList
|
||||
cmsAllocProfileSequenceDescription = cmsAllocProfileSequenceDescription
|
||||
cmsAppendNamedColor = cmsAppendNamedColor
|
||||
cmsBFDdeltaE = cmsBFDdeltaE
|
||||
cmsBuildGamma = cmsBuildGamma
|
||||
cmsBuildParametricToneCurve = cmsBuildParametricToneCurve
|
||||
cmsBuildSegmentedToneCurve = cmsBuildSegmentedToneCurve
|
||||
cmsBuildTabulatedToneCurve16 = cmsBuildTabulatedToneCurve16
|
||||
cmsBuildTabulatedToneCurveFloat = cmsBuildTabulatedToneCurveFloat
|
||||
_cmsCalloc = _cmsCalloc
|
||||
cmsChannelsOf = cmsChannelsOf
|
||||
cmsCIE2000DeltaE = cmsCIE2000DeltaE
|
||||
cmsCIE94DeltaE = cmsCIE94DeltaE
|
||||
cmsCIECAM02Done = cmsCIECAM02Done
|
||||
cmsCIECAM02Forward = cmsCIECAM02Forward
|
||||
cmsCIECAM02Init = cmsCIECAM02Init
|
||||
cmsCIECAM02Reverse = cmsCIECAM02Reverse
|
||||
cmsCloseIOhandler = cmsCloseIOhandler
|
||||
cmsCloseProfile = cmsCloseProfile
|
||||
cmsCMCdeltaE = cmsCMCdeltaE
|
||||
cmsCreate_sRGBProfile = cmsCreate_sRGBProfile
|
||||
cmsCreate_sRGBProfileTHR = cmsCreate_sRGBProfileTHR
|
||||
cmsCreateBCHSWabstractProfile = cmsCreateBCHSWabstractProfile
|
||||
cmsCreateBCHSWabstractProfileTHR = cmsCreateBCHSWabstractProfileTHR
|
||||
cmsCreateExtendedTransform = cmsCreateExtendedTransform
|
||||
cmsCreateGrayProfile = cmsCreateGrayProfile
|
||||
cmsCreateGrayProfileTHR = cmsCreateGrayProfileTHR
|
||||
cmsCreateInkLimitingDeviceLink = cmsCreateInkLimitingDeviceLink
|
||||
cmsCreateInkLimitingDeviceLinkTHR = cmsCreateInkLimitingDeviceLinkTHR
|
||||
cmsCreateLab2Profile = cmsCreateLab2Profile
|
||||
cmsCreateLab2ProfileTHR = cmsCreateLab2ProfileTHR
|
||||
cmsCreateLab4Profile = cmsCreateLab4Profile
|
||||
cmsCreateLab4ProfileTHR = cmsCreateLab4ProfileTHR
|
||||
cmsCreateLinearizationDeviceLink = cmsCreateLinearizationDeviceLink
|
||||
cmsCreateLinearizationDeviceLinkTHR = cmsCreateLinearizationDeviceLinkTHR
|
||||
cmsCreateMultiprofileTransform = cmsCreateMultiprofileTransform
|
||||
cmsCreateMultiprofileTransformTHR = cmsCreateMultiprofileTransformTHR
|
||||
cmsCreateNULLProfile = cmsCreateNULLProfile
|
||||
cmsCreateNULLProfileTHR = cmsCreateNULLProfileTHR
|
||||
cmsCreateProfilePlaceholder = cmsCreateProfilePlaceholder
|
||||
cmsCreateProofingTransform = cmsCreateProofingTransform
|
||||
cmsCreateProofingTransformTHR = cmsCreateProofingTransformTHR
|
||||
cmsCreateRGBProfile = cmsCreateRGBProfile
|
||||
cmsCreateRGBProfileTHR = cmsCreateRGBProfileTHR
|
||||
cmsCreateTransform = cmsCreateTransform
|
||||
cmsCreateTransformTHR = cmsCreateTransformTHR
|
||||
cmsCreateXYZProfile = cmsCreateXYZProfile
|
||||
cmsCreateXYZProfileTHR = cmsCreateXYZProfileTHR
|
||||
cmsD50_xyY = cmsD50_xyY
|
||||
cmsD50_XYZ = cmsD50_XYZ
|
||||
_cmsDecodeDateTimeNumber = _cmsDecodeDateTimeNumber
|
||||
_cmsDefaultICCintents = _cmsDefaultICCintents
|
||||
cmsDeleteTransform = cmsDeleteTransform
|
||||
cmsDeltaE = cmsDeltaE
|
||||
cmsDetectBlackPoint = cmsDetectBlackPoint
|
||||
cmsDetectTAC = cmsDetectTAC
|
||||
cmsDesaturateLab = cmsDesaturateLab
|
||||
cmsDoTransform = cmsDoTransform
|
||||
_cmsDoubleTo15Fixed16 = _cmsDoubleTo15Fixed16
|
||||
_cmsDoubleTo8Fixed8 = _cmsDoubleTo8Fixed8
|
||||
_cmsDupMem = _cmsDupMem
|
||||
cmsDupNamedColorList = cmsDupNamedColorList
|
||||
cmsDupProfileSequenceDescription = cmsDupProfileSequenceDescription
|
||||
cmsDupToneCurve = cmsDupToneCurve
|
||||
_cmsEncodeDateTimeNumber = _cmsEncodeDateTimeNumber
|
||||
cmsEstimateGamma = cmsEstimateGamma
|
||||
cmsEvalToneCurve16 = cmsEvalToneCurve16
|
||||
cmsEvalToneCurveFloat = cmsEvalToneCurveFloat
|
||||
cmsfilelength = cmsfilelength
|
||||
cmsFloat2LabEncoded = cmsFloat2LabEncoded
|
||||
cmsFloat2LabEncodedV2 = cmsFloat2LabEncodedV2
|
||||
cmsFloat2XYZEncoded = cmsFloat2XYZEncoded
|
||||
cmsFormatterForColorspaceOfProfile = cmsFormatterForColorspaceOfProfile
|
||||
cmsFormatterForPCSOfProfile = cmsFormatterForPCSOfProfile
|
||||
_cmsFree = _cmsFree
|
||||
cmsFreeNamedColorList = cmsFreeNamedColorList
|
||||
cmsFreeProfileSequenceDescription = cmsFreeProfileSequenceDescription
|
||||
cmsFreeToneCurve = cmsFreeToneCurve
|
||||
cmsFreeToneCurveTriple = cmsFreeToneCurveTriple
|
||||
cmsGBDAlloc = cmsGBDAlloc
|
||||
cmsGBDFree = cmsGBDFree
|
||||
cmsGDBAddPoint = cmsGDBAddPoint
|
||||
cmsGDBCheckPoint = cmsGDBCheckPoint
|
||||
cmsGDBCompute = cmsGDBCompute
|
||||
cmsGetAlarmCodes = cmsGetAlarmCodes
|
||||
cmsGetColorSpace = cmsGetColorSpace
|
||||
cmsGetDeviceClass = cmsGetDeviceClass
|
||||
cmsGetEncodedICCversion = cmsGetEncodedICCversion
|
||||
cmsGetHeaderAttributes = cmsGetHeaderAttributes
|
||||
cmsGetHeaderCreationDateTime = cmsGetHeaderCreationDateTime
|
||||
cmsGetHeaderFlags = cmsGetHeaderFlags
|
||||
cmsGetHeaderManufacturer = cmsGetHeaderManufacturer
|
||||
cmsGetHeaderModel = cmsGetHeaderModel
|
||||
cmsGetHeaderProfileID = cmsGetHeaderProfileID
|
||||
cmsGetHeaderRenderingIntent = cmsGetHeaderRenderingIntent
|
||||
cmsGetNamedColorList = cmsGetNamedColorList
|
||||
cmsGetPCS = cmsGetPCS
|
||||
cmsGetPostScriptColorResource = cmsGetPostScriptColorResource
|
||||
cmsGetPostScriptCRD = cmsGetPostScriptCRD
|
||||
cmsGetPostScriptCSA = cmsGetPostScriptCSA
|
||||
cmsGetProfileInfo = cmsGetProfileInfo
|
||||
cmsGetProfileInfoASCII = cmsGetProfileInfoASCII
|
||||
cmsGetProfileContextID = cmsGetProfileContextID
|
||||
cmsGetProfileVersion = cmsGetProfileVersion
|
||||
cmsGetSupportedIntents = cmsGetSupportedIntents
|
||||
cmsGetTagCount = cmsGetTagCount
|
||||
cmsGetTagSignature = cmsGetTagSignature
|
||||
cmsGetTransformContextID = cmsGetTransformContextID
|
||||
_cmsICCcolorSpace = _cmsICCcolorSpace
|
||||
_cmsIOPrintf = _cmsIOPrintf
|
||||
cmsIsCLUT = cmsIsCLUT
|
||||
cmsIsIntentSupported = cmsIsIntentSupported
|
||||
cmsIsMatrixShaper = cmsIsMatrixShaper
|
||||
cmsIsTag = cmsIsTag
|
||||
cmsIsToneCurveDescending = cmsIsToneCurveDescending
|
||||
cmsIsToneCurveLinear = cmsIsToneCurveLinear
|
||||
cmsIsToneCurveMonotonic = cmsIsToneCurveMonotonic
|
||||
cmsIsToneCurveMultisegment = cmsIsToneCurveMultisegment
|
||||
cmsGetToneCurveParametricType = cmsGetToneCurveParametricType
|
||||
cmsIT8Alloc = cmsIT8Alloc
|
||||
cmsIT8DefineDblFormat = cmsIT8DefineDblFormat
|
||||
cmsIT8EnumDataFormat = cmsIT8EnumDataFormat
|
||||
cmsIT8EnumProperties = cmsIT8EnumProperties
|
||||
cmsIT8Free = cmsIT8Free
|
||||
cmsIT8GetData = cmsIT8GetData
|
||||
cmsIT8GetDataDbl = cmsIT8GetDataDbl
|
||||
cmsIT8FindDataFormat = cmsIT8FindDataFormat
|
||||
cmsIT8GetDataRowCol = cmsIT8GetDataRowCol
|
||||
cmsIT8GetDataRowColDbl = cmsIT8GetDataRowColDbl
|
||||
cmsIT8GetPatchName = cmsIT8GetPatchName
|
||||
cmsIT8GetProperty = cmsIT8GetProperty
|
||||
cmsIT8GetPropertyDbl = cmsIT8GetPropertyDbl
|
||||
cmsIT8GetSheetType = cmsIT8GetSheetType
|
||||
cmsIT8LoadFromFile = cmsIT8LoadFromFile
|
||||
cmsIT8LoadFromMem = cmsIT8LoadFromMem
|
||||
cmsIT8SaveToFile = cmsIT8SaveToFile
|
||||
cmsIT8SaveToMem = cmsIT8SaveToMem
|
||||
cmsIT8SetComment = cmsIT8SetComment
|
||||
cmsIT8SetData = cmsIT8SetData
|
||||
cmsIT8SetDataDbl = cmsIT8SetDataDbl
|
||||
cmsIT8SetDataFormat = cmsIT8SetDataFormat
|
||||
cmsIT8SetDataRowCol = cmsIT8SetDataRowCol
|
||||
cmsIT8SetDataRowColDbl = cmsIT8SetDataRowColDbl
|
||||
cmsIT8SetPropertyDbl = cmsIT8SetPropertyDbl
|
||||
cmsIT8SetPropertyHex = cmsIT8SetPropertyHex
|
||||
cmsIT8SetPropertyStr = cmsIT8SetPropertyStr
|
||||
cmsIT8SetPropertyUncooked = cmsIT8SetPropertyUncooked
|
||||
cmsIT8SetSheetType = cmsIT8SetSheetType
|
||||
cmsIT8SetTable = cmsIT8SetTable
|
||||
cmsIT8SetTableByLabel = cmsIT8SetTableByLabel
|
||||
cmsIT8TableCount = cmsIT8TableCount
|
||||
cmsJoinToneCurve = cmsJoinToneCurve
|
||||
cmsLab2LCh = cmsLab2LCh
|
||||
cmsLab2XYZ = cmsLab2XYZ
|
||||
cmsLabEncoded2Float = cmsLabEncoded2Float
|
||||
cmsLabEncoded2FloatV2 = cmsLabEncoded2FloatV2
|
||||
cmsLCh2Lab = cmsLCh2Lab
|
||||
_cmsLCMScolorSpace = _cmsLCMScolorSpace
|
||||
cmsLinkTag = cmsLinkTag
|
||||
cmsPipelineAlloc = cmsPipelineAlloc
|
||||
cmsPipelineCat = cmsPipelineCat
|
||||
cmsPipelineCheckAndRetreiveStages = cmsPipelineCheckAndRetreiveStages
|
||||
cmsPipelineDup = cmsPipelineDup
|
||||
cmsPipelineStageCount = cmsPipelineStageCount
|
||||
cmsPipelineEval16 = cmsPipelineEval16
|
||||
cmsPipelineEvalFloat = cmsPipelineEvalFloat
|
||||
cmsPipelineEvalReverseFloat = cmsPipelineEvalReverseFloat
|
||||
cmsPipelineFree = cmsPipelineFree
|
||||
cmsPipelineGetPtrToFirstStage = cmsPipelineGetPtrToFirstStage
|
||||
cmsPipelineGetPtrToLastStage = cmsPipelineGetPtrToLastStage
|
||||
cmsPipelineInputChannels = cmsPipelineInputChannels
|
||||
cmsPipelineInsertStage = cmsPipelineInsertStage
|
||||
cmsPipelineOutputChannels = cmsPipelineOutputChannels
|
||||
cmsPipelineSetSaveAs8bitsFlag = cmsPipelineSetSaveAs8bitsFlag
|
||||
_cmsPipelineSetOptimizationParameters = _cmsPipelineSetOptimizationParameters
|
||||
cmsPipelineUnlinkStage = cmsPipelineUnlinkStage
|
||||
_cmsMalloc = _cmsMalloc
|
||||
_cmsMallocZero = _cmsMallocZero
|
||||
_cmsMAT3eval = _cmsMAT3eval
|
||||
_cmsMAT3identity = _cmsMAT3identity
|
||||
_cmsMAT3inverse = _cmsMAT3inverse
|
||||
_cmsMAT3isIdentity = _cmsMAT3isIdentity
|
||||
_cmsMAT3per = _cmsMAT3per
|
||||
_cmsMAT3solve = _cmsMAT3solve
|
||||
cmsMD5computeID = cmsMD5computeID
|
||||
cmsMLUalloc = cmsMLUalloc
|
||||
cmsMLUdup = cmsMLUdup
|
||||
cmsMLUfree = cmsMLUfree
|
||||
cmsMLUgetASCII = cmsMLUgetASCII
|
||||
cmsMLUgetTranslation = cmsMLUgetTranslation
|
||||
cmsMLUgetWide = cmsMLUgetWide
|
||||
cmsMLUsetASCII = cmsMLUsetASCII
|
||||
cmsMLUsetWide = cmsMLUsetWide
|
||||
cmsStageAllocCLut16bit = cmsStageAllocCLut16bit
|
||||
cmsStageAllocCLut16bitGranular = cmsStageAllocCLut16bitGranular
|
||||
cmsStageAllocCLutFloat = cmsStageAllocCLutFloat
|
||||
cmsStageAllocCLutFloatGranular = cmsStageAllocCLutFloatGranular
|
||||
cmsStageAllocToneCurves = cmsStageAllocToneCurves
|
||||
cmsStageAllocIdentity = cmsStageAllocIdentity
|
||||
cmsStageAllocMatrix = cmsStageAllocMatrix
|
||||
_cmsStageAllocPlaceholder = _cmsStageAllocPlaceholder
|
||||
cmsStageDup = cmsStageDup
|
||||
cmsStageFree = cmsStageFree
|
||||
cmsStageNext = cmsStageNext
|
||||
cmsStageInputChannels = cmsStageInputChannels
|
||||
cmsStageOutputChannels = cmsStageOutputChannels
|
||||
cmsStageSampleCLut16bit = cmsStageSampleCLut16bit
|
||||
cmsStageSampleCLutFloat = cmsStageSampleCLutFloat
|
||||
cmsStageType = cmsStageType
|
||||
cmsStageData = cmsStageData
|
||||
cmsNamedColorCount = cmsNamedColorCount
|
||||
cmsNamedColorIndex = cmsNamedColorIndex
|
||||
cmsNamedColorInfo = cmsNamedColorInfo
|
||||
cmsOpenIOhandlerFromFile = cmsOpenIOhandlerFromFile
|
||||
cmsOpenIOhandlerFromMem = cmsOpenIOhandlerFromMem
|
||||
cmsOpenIOhandlerFromNULL = cmsOpenIOhandlerFromNULL
|
||||
cmsOpenIOhandlerFromStream = cmsOpenIOhandlerFromStream
|
||||
cmsOpenProfileFromFile = cmsOpenProfileFromFile
|
||||
cmsOpenProfileFromFileTHR = cmsOpenProfileFromFileTHR
|
||||
cmsOpenProfileFromIOhandlerTHR = cmsOpenProfileFromIOhandlerTHR
|
||||
cmsOpenProfileFromMem = cmsOpenProfileFromMem
|
||||
cmsOpenProfileFromMemTHR = cmsOpenProfileFromMemTHR
|
||||
cmsOpenProfileFromStream = cmsOpenProfileFromStream
|
||||
cmsOpenProfileFromStreamTHR = cmsOpenProfileFromStreamTHR
|
||||
cmsPlugin = cmsPlugin
|
||||
_cmsRead15Fixed16Number = _cmsRead15Fixed16Number
|
||||
_cmsReadAlignment = _cmsReadAlignment
|
||||
_cmsReadFloat32Number = _cmsReadFloat32Number
|
||||
cmsReadRawTag = cmsReadRawTag
|
||||
cmsReadTag = cmsReadTag
|
||||
_cmsReadTypeBase = _cmsReadTypeBase
|
||||
_cmsReadUInt16Array = _cmsReadUInt16Array
|
||||
_cmsReadUInt16Number = _cmsReadUInt16Number
|
||||
_cmsReadUInt32Number = _cmsReadUInt32Number
|
||||
_cmsReadUInt64Number = _cmsReadUInt64Number
|
||||
_cmsReadUInt8Number = _cmsReadUInt8Number
|
||||
_cmsReadXYZNumber = _cmsReadXYZNumber
|
||||
_cmsRealloc = _cmsRealloc
|
||||
cmsReverseToneCurve = cmsReverseToneCurve
|
||||
cmsReverseToneCurveEx = cmsReverseToneCurveEx
|
||||
cmsSaveProfileToFile = cmsSaveProfileToFile
|
||||
cmsSaveProfileToIOhandler = cmsSaveProfileToIOhandler
|
||||
cmsSaveProfileToMem = cmsSaveProfileToMem
|
||||
cmsSaveProfileToStream = cmsSaveProfileToStream
|
||||
cmsSetAdaptationState = cmsSetAdaptationState
|
||||
cmsSetAlarmCodes = cmsSetAlarmCodes
|
||||
cmsSetColorSpace = cmsSetColorSpace
|
||||
cmsSetDeviceClass = cmsSetDeviceClass
|
||||
cmsSetEncodedICCversion = cmsSetEncodedICCversion
|
||||
cmsSetHeaderAttributes = cmsSetHeaderAttributes
|
||||
cmsSetHeaderFlags = cmsSetHeaderFlags
|
||||
cmsSetHeaderManufacturer = cmsSetHeaderManufacturer
|
||||
cmsSetHeaderModel = cmsSetHeaderModel
|
||||
cmsSetHeaderProfileID = cmsSetHeaderProfileID
|
||||
cmsSetHeaderRenderingIntent = cmsSetHeaderRenderingIntent
|
||||
cmsSetLogErrorHandler = cmsSetLogErrorHandler
|
||||
cmsSetPCS = cmsSetPCS
|
||||
cmsSetProfileVersion = cmsSetProfileVersion
|
||||
cmsSignalError = cmsSignalError
|
||||
cmsSmoothToneCurve = cmsSmoothToneCurve
|
||||
cmsstrcasecmp = cmsstrcasecmp
|
||||
cmsTempFromWhitePoint = cmsTempFromWhitePoint
|
||||
cmsTransform2DeviceLink = cmsTransform2DeviceLink
|
||||
cmsUnregisterPlugins = cmsUnregisterPlugins
|
||||
_cmsVEC3cross = _cmsVEC3cross
|
||||
_cmsVEC3distance = _cmsVEC3distance
|
||||
_cmsVEC3dot = _cmsVEC3dot
|
||||
_cmsVEC3init = _cmsVEC3init
|
||||
_cmsVEC3length = _cmsVEC3length
|
||||
_cmsVEC3minus = _cmsVEC3minus
|
||||
cmsWhitePointFromTemp = cmsWhitePointFromTemp
|
||||
_cmsWrite15Fixed16Number = _cmsWrite15Fixed16Number
|
||||
_cmsWriteAlignment = _cmsWriteAlignment
|
||||
_cmsWriteFloat32Number = _cmsWriteFloat32Number
|
||||
cmsWriteRawTag = cmsWriteRawTag
|
||||
cmsWriteTag = cmsWriteTag
|
||||
_cmsWriteTypeBase = _cmsWriteTypeBase
|
||||
_cmsWriteUInt16Array = _cmsWriteUInt16Array
|
||||
_cmsWriteUInt16Number = _cmsWriteUInt16Number
|
||||
_cmsWriteUInt32Number = _cmsWriteUInt32Number
|
||||
_cmsWriteUInt64Number = _cmsWriteUInt64Number
|
||||
_cmsWriteUInt8Number = _cmsWriteUInt8Number
|
||||
_cmsWriteXYZNumber = _cmsWriteXYZNumber
|
||||
cmsxyY2XYZ = cmsxyY2XYZ
|
||||
cmsXYZ2Lab = cmsXYZ2Lab
|
||||
cmsXYZ2xyY = cmsXYZ2xyY
|
||||
cmsXYZEncoded2Float = cmsXYZEncoded2Float
|
||||
cmsSliceSpace16 = cmsSliceSpace16
|
||||
cmsSliceSpaceFloat = cmsSliceSpaceFloat
|
||||
cmsChangeBuffersFormat = cmsChangeBuffersFormat
|
652
thirdparty/liblcms2/src/lcms2_internal.h
vendored
Normal file
652
thirdparty/liblcms2/src/lcms2_internal.h
vendored
Normal file
@ -0,0 +1,652 @@
|
||||
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
//
|
||||
// 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 _lcms_internal_H
|
||||
|
||||
// Include plug-in foundation
|
||||
#ifndef _lcms_plugin_H
|
||||
# include "lcms2_plugin.h"
|
||||
#endif
|
||||
|
||||
// ctype is part of C99 as per 7.1.2
|
||||
#include <ctype.h>
|
||||
|
||||
// assert macro is part of C99 as per 7.2
|
||||
#include <assert.h>
|
||||
|
||||
// Some needed constants
|
||||
#ifndef M_PI
|
||||
# define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#ifndef M_LOG10E
|
||||
# define M_LOG10E 0.434294481903251827651
|
||||
#endif
|
||||
|
||||
// BorlandC 5.5 is broken on that
|
||||
#ifdef __BORLANDC__
|
||||
#define sinf(x) (float)sin((float)x)
|
||||
#define sqrtf(x) (float)sqrt((float)x)
|
||||
#endif
|
||||
|
||||
|
||||
// Alignment of ICC file format uses 4 bytes (cmsUInt32Number)
|
||||
#define _cmsSIZEOFLONGMINUS1 (sizeof(cmsUInt32Number)-1)
|
||||
#define _cmsALIGNLONG(x) (((x)+_cmsSIZEOFLONGMINUS1) & ~(_cmsSIZEOFLONGMINUS1))
|
||||
|
||||
// Maximum encodeable values in floating point
|
||||
#define MAX_ENCODEABLE_XYZ (1.0 + 32767.0/32768.0)
|
||||
#define MIN_ENCODEABLE_ab2 (-128.0)
|
||||
#define MAX_ENCODEABLE_ab2 ((65535.0/256.0) - 128.0)
|
||||
#define MIN_ENCODEABLE_ab4 (-128.0)
|
||||
#define MAX_ENCODEABLE_ab4 (127.0)
|
||||
|
||||
// Maximum of channels for internal pipeline evaluation
|
||||
#define MAX_STAGE_CHANNELS 128
|
||||
|
||||
// Unused parameter warning supression
|
||||
#define cmsUNUSED_PARAMETER(x) ((void)x)
|
||||
|
||||
// The specification for "inline" is section 6.7.4 of the C99 standard (ISO/IEC 9899:1999).
|
||||
// unfortunately VisualC++ does not conform that
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
# define cmsINLINE __inline
|
||||
#else
|
||||
# define cmsINLINE static inline
|
||||
#endif
|
||||
|
||||
// Other replacement functions
|
||||
#ifdef _MSC_VER
|
||||
# ifndef snprintf
|
||||
# define snprintf _snprintf
|
||||
# endif
|
||||
# ifndef vsnprintf
|
||||
# define vsnprintf _vsnprintf
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Pthreads. In windows we use the native WIN32 API instead
|
||||
#ifdef CMS_DONT_USE_PTHREADS
|
||||
typedef int LCMS_RWLOCK_T;
|
||||
# define LCMS_CREATE_LOCK(x)
|
||||
# define LCMS_FREE_LOCK(x)
|
||||
# define LCMS_READ_LOCK(x)
|
||||
# define LCMS_WRITE_LOCK(x)
|
||||
# define LCMS_UNLOCK(x)
|
||||
#else
|
||||
#ifdef CMS_IS_WINDOWS_
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <windows.h>
|
||||
typedef CRITICAL_SECTION LCMS_RWLOCK_T;
|
||||
# define LCMS_CREATE_LOCK(x) InitializeCriticalSection((x))
|
||||
# define LCMS_FREE_LOCK(x) DeleteCriticalSection((x))
|
||||
# define LCMS_READ_LOCK(x) EnterCriticalSection((x))
|
||||
# define LCMS_WRITE_LOCK(x) EnterCriticalSection((x))
|
||||
# define LCMS_UNLOCK(x) LeaveCriticalSection((x))
|
||||
#else
|
||||
# include <pthread.h>
|
||||
typedef pthread_rwlock_t LCMS_RWLOCK_T;
|
||||
# define LCMS_CREATE_LOCK(x) pthread_rwlock_init((x), NULL)
|
||||
# define LCMS_FREE_LOCK(x) pthread_rwlock_destroy((x))
|
||||
# define LCMS_READ_LOCK(x) pthread_rwlock_rdlock((x))
|
||||
# define LCMS_WRITE_LOCK(x) pthread_rwlock_wrlock((x))
|
||||
# define LCMS_UNLOCK(x) pthread_rwlock_unlock((x))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// A fast way to convert from/to 16 <-> 8 bits
|
||||
#define FROM_8_TO_16(rgb) (cmsUInt16Number) ((((cmsUInt16Number) (rgb)) << 8)|(rgb))
|
||||
#define FROM_16_TO_8(rgb) (cmsUInt8Number) ((((rgb) * 65281 + 8388608) >> 24) & 0xFF)
|
||||
|
||||
// Code analysis is broken on asserts
|
||||
#ifdef _MSC_VER
|
||||
# if (_MSC_VER >= 1500)
|
||||
# define _cmsAssert(a) { assert((a)); __analysis_assume((a)); }
|
||||
# else
|
||||
# define _cmsAssert(a) assert((a))
|
||||
# endif
|
||||
#else
|
||||
# define _cmsAssert(a) assert((a))
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
// Determinant lower than that are assumed zero (used on matrix invert)
|
||||
#define MATRIX_DET_TOLERANCE 0.0001
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
// Fixed point
|
||||
#define FIXED_TO_INT(x) ((x)>>16)
|
||||
#define FIXED_REST_TO_INT(x) ((x)&0xFFFFU)
|
||||
#define ROUND_FIXED_TO_INT(x) (((x)+0x8000)>>16)
|
||||
|
||||
cmsINLINE cmsS15Fixed16Number _cmsToFixedDomain(int a) { return a + ((a + 0x7fff) / 0xffff); }
|
||||
cmsINLINE int _cmsFromFixedDomain(cmsS15Fixed16Number a) { return a - ((a + 0x7fff) >> 16); }
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Fast floor conversion logic. Thanks to Sree Kotay and Stuart Nixon
|
||||
// note than this only works in the range ..-32767...+32767 because
|
||||
// mantissa is interpreted as 15.16 fixed point.
|
||||
// The union is to avoid pointer aliasing overoptimization.
|
||||
cmsINLINE int _cmsQuickFloor(cmsFloat64Number val)
|
||||
{
|
||||
#ifdef CMS_DONT_USE_FAST_FLOOR
|
||||
return (int) floor(val);
|
||||
#else
|
||||
const cmsFloat64Number _lcms_double2fixmagic = 68719476736.0 * 1.5; // 2^36 * 1.5, (52-16=36) uses limited precision to floor
|
||||
union {
|
||||
cmsFloat64Number val;
|
||||
int halves[2];
|
||||
} temp;
|
||||
|
||||
temp.val = val + _lcms_double2fixmagic;
|
||||
|
||||
#ifdef CMS_USE_BIG_ENDIAN
|
||||
return temp.halves[1] >> 16;
|
||||
#else
|
||||
return temp.halves[0] >> 16;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
// Fast floor restricted to 0..65535.0
|
||||
cmsINLINE cmsUInt16Number _cmsQuickFloorWord(cmsFloat64Number d)
|
||||
{
|
||||
return (cmsUInt16Number) _cmsQuickFloor(d - 32767.0) + 32767U;
|
||||
}
|
||||
|
||||
// Floor to word, taking care of saturation
|
||||
cmsINLINE cmsUInt16Number _cmsQuickSaturateWord(cmsFloat64Number d)
|
||||
{
|
||||
d += 0.5;
|
||||
if (d <= 0) return 0;
|
||||
if (d >= 65535.0) return 0xffff;
|
||||
|
||||
return _cmsQuickFloorWord(d);
|
||||
}
|
||||
|
||||
// Plug-In registering ---------------------------------------------------------------
|
||||
|
||||
// Specialized function for plug-in memory management. No pairing free() since whole pool is freed at once.
|
||||
void* _cmsPluginMalloc(cmsUInt32Number size);
|
||||
|
||||
// Memory management
|
||||
cmsBool _cmsRegisterMemHandlerPlugin(cmsPluginBase* Plugin);
|
||||
|
||||
// Interpolation
|
||||
cmsBool _cmsRegisterInterpPlugin(cmsPluginBase* Plugin);
|
||||
|
||||
// Parametric curves
|
||||
cmsBool _cmsRegisterParametricCurvesPlugin(cmsPluginBase* Plugin);
|
||||
|
||||
// Formatters management
|
||||
cmsBool _cmsRegisterFormattersPlugin(cmsPluginBase* Plugin);
|
||||
|
||||
// Tag type management
|
||||
cmsBool _cmsRegisterTagTypePlugin(cmsPluginBase* Plugin);
|
||||
|
||||
// Tag management
|
||||
cmsBool _cmsRegisterTagPlugin(cmsPluginBase* Plugin);
|
||||
|
||||
// Intent management
|
||||
cmsBool _cmsRegisterRenderingIntentPlugin(cmsPluginBase* Plugin);
|
||||
|
||||
// Multi Process elements
|
||||
cmsBool _cmsRegisterMultiProcessElementPlugin(cmsPluginBase* Plugin);
|
||||
|
||||
// Optimization
|
||||
cmsBool _cmsRegisterOptimizationPlugin(cmsPluginBase* Plugin);
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Suballocators. Those are blocks of memory that is freed at the end on whole block.
|
||||
typedef struct _cmsSubAllocator_chunk_st {
|
||||
|
||||
cmsUInt8Number* Block;
|
||||
cmsUInt32Number BlockSize;
|
||||
cmsUInt32Number Used;
|
||||
|
||||
struct _cmsSubAllocator_chunk_st* next;
|
||||
|
||||
} _cmsSubAllocator_chunk;
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
cmsContext ContextID;
|
||||
_cmsSubAllocator_chunk* h;
|
||||
|
||||
} _cmsSubAllocator;
|
||||
|
||||
|
||||
_cmsSubAllocator* _cmsCreateSubAlloc(cmsContext ContextID, cmsUInt32Number Initial);
|
||||
void _cmsSubAllocDestroy(_cmsSubAllocator* s);
|
||||
void* _cmsSubAlloc(_cmsSubAllocator* s, cmsUInt32Number size);
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
||||
// MLU internal representation
|
||||
typedef struct {
|
||||
|
||||
cmsUInt16Number Language;
|
||||
cmsUInt16Number Country;
|
||||
|
||||
cmsUInt32Number StrW; // Offset to current unicode string
|
||||
cmsUInt32Number Len; // Lenght in bytes
|
||||
|
||||
} _cmsMLUentry;
|
||||
|
||||
struct _cms_MLU_struct {
|
||||
|
||||
cmsContext ContextID;
|
||||
|
||||
// The directory
|
||||
int AllocatedEntries;
|
||||
int UsedEntries;
|
||||
_cmsMLUentry* Entries; // Array of pointers to strings allocated in MemPool
|
||||
|
||||
// The Pool
|
||||
cmsUInt32Number PoolSize; // The maximum allocated size
|
||||
cmsUInt32Number PoolUsed; // The used size
|
||||
void* MemPool; // Pointer to begin of memory pool
|
||||
};
|
||||
|
||||
// Named color list internal representation
|
||||
typedef struct {
|
||||
|
||||
char Name[cmsMAX_PATH];
|
||||
cmsUInt16Number PCS[3];
|
||||
cmsUInt16Number DeviceColorant[cmsMAXCHANNELS];
|
||||
|
||||
} _cmsNAMEDCOLOR;
|
||||
|
||||
struct _cms_NAMEDCOLORLIST_struct {
|
||||
|
||||
cmsUInt32Number nColors;
|
||||
cmsUInt32Number Allocated;
|
||||
cmsUInt32Number ColorantCount;
|
||||
|
||||
char Prefix[33]; // Prefix and suffix are defined to be 32 characters at most
|
||||
char Suffix[33];
|
||||
|
||||
_cmsNAMEDCOLOR* List;
|
||||
|
||||
cmsContext ContextID;
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
||||
// This is the internal struct holding profile details.
|
||||
|
||||
// Maximum supported tags in a profile
|
||||
#define MAX_TABLE_TAG 100
|
||||
|
||||
typedef struct _cms_iccprofile_struct {
|
||||
|
||||
// I/O handler
|
||||
cmsIOHANDLER* IOhandler;
|
||||
|
||||
// The thread ID
|
||||
cmsContext ContextID;
|
||||
|
||||
// Creation time
|
||||
struct tm Created;
|
||||
|
||||
// Only most important items found in ICC profiles
|
||||
cmsUInt32Number Version;
|
||||
cmsProfileClassSignature DeviceClass;
|
||||
cmsColorSpaceSignature ColorSpace;
|
||||
cmsColorSpaceSignature PCS;
|
||||
cmsUInt32Number RenderingIntent;
|
||||
cmsUInt32Number flags;
|
||||
cmsUInt32Number manufacturer, model;
|
||||
cmsUInt64Number attributes;
|
||||
|
||||
cmsProfileID ProfileID;
|
||||
|
||||
// Dictionary
|
||||
cmsUInt32Number TagCount;
|
||||
cmsTagSignature TagNames[MAX_TABLE_TAG];
|
||||
cmsTagSignature TagLinked[MAX_TABLE_TAG]; // The tag to wich is linked (0=none)
|
||||
cmsUInt32Number TagSizes[MAX_TABLE_TAG]; // Size on disk
|
||||
cmsUInt32Number TagOffsets[MAX_TABLE_TAG];
|
||||
cmsBool TagSaveAsRaw[MAX_TABLE_TAG]; // True to write uncooked
|
||||
void * TagPtrs[MAX_TABLE_TAG];
|
||||
cmsTagTypeHandler* TagTypeHandlers[MAX_TABLE_TAG]; // Same structure may be serialized on different types
|
||||
// depending on profile version, so we keep track of the // type handler for each tag in the list.
|
||||
// Special
|
||||
cmsBool IsWrite;
|
||||
|
||||
} _cmsICCPROFILE;
|
||||
|
||||
// IO helpers for profiles
|
||||
cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc);
|
||||
cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace);
|
||||
int _cmsSearchTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, cmsBool lFollowLinks);
|
||||
|
||||
// Tag types
|
||||
cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsTagTypeSignature sig);
|
||||
cmsTagTypeSignature _cmsGetTagTrueType(cmsHPROFILE hProfile, cmsTagSignature sig);
|
||||
cmsTagDescriptor* _cmsGetTagDescriptor(cmsTagSignature sig);
|
||||
|
||||
// Error logging ---------------------------------------------------------------------------------------------------------
|
||||
|
||||
void _cmsTagSignature2String(char String[5], cmsTagSignature sig);
|
||||
|
||||
// Interpolation ---------------------------------------------------------------------------------------------------------
|
||||
|
||||
cmsInterpParams* _cmsComputeInterpParams(cmsContext ContextID, int nSamples, int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags);
|
||||
cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags);
|
||||
void _cmsFreeInterpParams(cmsInterpParams* p);
|
||||
cmsBool _cmsSetInterpolationRoutine(cmsInterpParams* p);
|
||||
|
||||
// Curves ----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// This struct holds information about a segment, plus a pointer to the function that implements the evaluation.
|
||||
// In the case of table-based, Eval pointer is set to NULL
|
||||
|
||||
// The gamma function main structure
|
||||
struct _cms_curve_struct {
|
||||
|
||||
cmsInterpParams* InterpParams; // Private optimizations for interpolation
|
||||
|
||||
cmsUInt32Number nSegments; // Number of segments in the curve. Zero for a 16-bit based tables
|
||||
cmsCurveSegment* Segments; // The segments
|
||||
cmsInterpParams** SegInterp; // Array of private optimizations for interpolation in table-based segments
|
||||
|
||||
cmsParametricCurveEvaluator* Evals; // Evaluators (one per segment)
|
||||
|
||||
// 16 bit Table-based representation follows
|
||||
cmsUInt32Number nEntries; // Number of table elements
|
||||
cmsUInt16Number* Table16; // The table itself.
|
||||
};
|
||||
|
||||
|
||||
// Pipelines & Stages ---------------------------------------------------------------------------------------------
|
||||
|
||||
// A single stage
|
||||
struct _cmsStage_struct {
|
||||
|
||||
cmsContext ContextID;
|
||||
|
||||
cmsStageSignature Type; // Identifies the stage
|
||||
cmsStageSignature Implements; // Identifies the *function* of the stage (for optimizations)
|
||||
|
||||
cmsUInt32Number InputChannels; // Input channels -- for optimization purposes
|
||||
cmsUInt32Number OutputChannels; // Output channels -- for optimization purposes
|
||||
|
||||
_cmsStageEvalFn EvalPtr; // Points to fn that evaluates the stage (always in floating point)
|
||||
_cmsStageDupElemFn DupElemPtr; // Points to a fn that duplicates the *data* of the stage
|
||||
_cmsStageFreeElemFn FreePtr; // Points to a fn that sets the *data* of the stage free
|
||||
|
||||
// A generic pointer to whatever memory needed by the stage
|
||||
void* Data;
|
||||
|
||||
// Maintains linked list (used internally)
|
||||
struct _cmsStage_struct* Next;
|
||||
};
|
||||
|
||||
// Data kept in "Element" member of cmsStage
|
||||
|
||||
// Curves
|
||||
typedef struct {
|
||||
cmsUInt32Number nCurves;
|
||||
cmsToneCurve** TheCurves;
|
||||
|
||||
} _cmsStageToneCurvesData;
|
||||
|
||||
// Matrix
|
||||
typedef struct {
|
||||
cmsFloat64Number* Double; // floating point for the matrix
|
||||
cmsFloat64Number* Offset; // The offset
|
||||
|
||||
} _cmsStageMatrixData;
|
||||
|
||||
// CLUT
|
||||
typedef struct {
|
||||
|
||||
union { // Can have only one of both representations at same time
|
||||
cmsUInt16Number* T; // Points to the table 16 bits table
|
||||
cmsFloat32Number* TFloat; // Points to the cmsFloat32Number table
|
||||
|
||||
} Tab;
|
||||
|
||||
cmsInterpParams* Params;
|
||||
cmsUInt32Number nEntries;
|
||||
cmsBool HasFloatValues;
|
||||
|
||||
} _cmsStageCLutData;
|
||||
|
||||
|
||||
// Special Stages (cannot be saved)
|
||||
cmsStage* _cmsStageAllocLab2XYZ(cmsContext ContextID);
|
||||
cmsStage* _cmsStageAllocXYZ2Lab(cmsContext ContextID);
|
||||
cmsStage* _cmsStageAllocLabPrelin(cmsContext ContextID);
|
||||
cmsStage* _cmsStageAllocLabV2ToV4(cmsContext ContextID);
|
||||
cmsStage* _cmsStageAllocLabV2ToV4curves(cmsContext ContextID);
|
||||
cmsStage* _cmsStageAllocLabV4ToV2(cmsContext ContextID);
|
||||
cmsStage* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList);
|
||||
cmsStage* _cmsStageAllocIdentityCurves(cmsContext ContextID, int nChannels);
|
||||
cmsStage* _cmsStageAllocIdentityCLut(cmsContext ContextID, int nChan);
|
||||
|
||||
// For curve set only
|
||||
cmsToneCurve** _cmsStageGetPtrToCurveSet(const cmsStage* mpe);
|
||||
|
||||
|
||||
// Pipeline Evaluator (in floating point)
|
||||
typedef void (* _cmsPipelineEvalFloatFn)(const cmsFloat32Number In[],
|
||||
cmsFloat32Number Out[],
|
||||
const void* Data);
|
||||
|
||||
struct _cmsPipeline_struct {
|
||||
|
||||
cmsStage* Elements; // Points to elements chain
|
||||
cmsUInt32Number InputChannels, OutputChannels;
|
||||
|
||||
// Data & evaluators
|
||||
void *Data;
|
||||
|
||||
_cmsOPTeval16Fn Eval16Fn;
|
||||
_cmsPipelineEvalFloatFn EvalFloatFn;
|
||||
_cmsOPTfreeDataFn FreeDataFn;
|
||||
_cmsOPTdupDataFn DupDataFn;
|
||||
|
||||
cmsContext ContextID; // Environment
|
||||
|
||||
cmsBool SaveAs8Bits; // Implemntation-specific: save as 8 bits if possible
|
||||
};
|
||||
|
||||
// LUT reading & creation -------------------------------------------------------------------------------------------
|
||||
|
||||
// Read tags using low-level function, provide necessary glue code to adapt versions, etc. All those return a brand new copy
|
||||
// of the LUTS, since ownership of original is up to the profile. The user should free allocated resources.
|
||||
|
||||
cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent);
|
||||
cmsPipeline* _cmsReadOutputLUT(cmsHPROFILE hProfile, int Intent);
|
||||
cmsPipeline* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent);
|
||||
|
||||
// Special values
|
||||
cmsBool _cmsReadMediaWhitePoint(cmsCIEXYZ* Dest, cmsHPROFILE hProfile);
|
||||
cmsBool _cmsReadCHAD(cmsMAT3* Dest, cmsHPROFILE hProfile);
|
||||
|
||||
// Profile linker --------------------------------------------------------------------------------------------------
|
||||
|
||||
cmsPipeline* _cmsLinkProfiles(cmsContext ContextID,
|
||||
cmsUInt32Number nProfiles,
|
||||
cmsUInt32Number TheIntents[],
|
||||
cmsHPROFILE hProfiles[],
|
||||
cmsBool BPC[],
|
||||
cmsFloat64Number AdaptationStates[],
|
||||
cmsUInt32Number dwFlags);
|
||||
|
||||
// Sequence --------------------------------------------------------------------------------------------------------
|
||||
|
||||
cmsSEQ* _cmsReadProfileSequence(cmsHPROFILE hProfile);
|
||||
cmsBool _cmsWriteProfileSequence(cmsHPROFILE hProfile, const cmsSEQ* seq);
|
||||
cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[]);
|
||||
|
||||
|
||||
// LUT optimization ------------------------------------------------------------------------------------------------
|
||||
|
||||
cmsUInt16Number _cmsQuantizeVal(cmsFloat64Number i, int MaxSamples);
|
||||
int _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags);
|
||||
|
||||
cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
|
||||
cmsUInt16Number **White,
|
||||
cmsUInt16Number **Black,
|
||||
cmsUInt32Number *nOutputs);
|
||||
|
||||
cmsBool _cmsOptimizePipeline(cmsPipeline** Lut,
|
||||
int Intent,
|
||||
cmsUInt32Number* InputFormat,
|
||||
cmsUInt32Number* OutputFormat,
|
||||
cmsUInt32Number* dwFlags );
|
||||
|
||||
|
||||
// Hi level LUT building ----------------------------------------------------------------------------------------------
|
||||
|
||||
cmsPipeline* _cmsCreateGamutCheckPipeline(cmsContext ContextID,
|
||||
cmsHPROFILE hProfiles[],
|
||||
cmsBool BPC[],
|
||||
cmsUInt32Number Intents[],
|
||||
cmsFloat64Number AdaptationStates[],
|
||||
cmsUInt32Number nGamutPCSposition,
|
||||
cmsHPROFILE hGamut);
|
||||
|
||||
|
||||
// Formatters ------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define cmsFLAGS_CAN_CHANGE_FORMATTER 0x02000000 // Allow change buffer format
|
||||
|
||||
cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type);
|
||||
cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type);
|
||||
|
||||
cmsFormatter _cmsGetFormatter(cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8
|
||||
cmsFormatterDirection Dir,
|
||||
cmsUInt32Number dwFlags);
|
||||
|
||||
|
||||
// Transform logic ------------------------------------------------------------------------------------------------------
|
||||
|
||||
struct _cmstransform_struct;
|
||||
|
||||
// Full xform
|
||||
typedef void (* _cmsTransformFn)(struct _cmstransform_struct *Transform,
|
||||
const void* InputBuffer,
|
||||
void* OutputBuffer, cmsUInt32Number Size);
|
||||
|
||||
typedef struct {
|
||||
|
||||
cmsUInt32Number InputFormat, OutputFormat; // Keep formats for further reference
|
||||
cmsUInt32Number StrideIn, StrideOut; // Planar support
|
||||
|
||||
} cmsFormatterInfo;
|
||||
|
||||
// Transformation
|
||||
typedef struct _cmstransform_struct {
|
||||
|
||||
cmsUInt32Number InputFormat, OutputFormat; // Keep formats for further reference
|
||||
|
||||
// Points to transform code
|
||||
_cmsTransformFn xform;
|
||||
|
||||
// Formatters, cannot be embedded into LUT because cache
|
||||
cmsFormatter16 FromInput;
|
||||
cmsFormatter16 ToOutput;
|
||||
|
||||
cmsFormatterFloat FromInputFloat;
|
||||
cmsFormatterFloat ToOutputFloat;
|
||||
|
||||
// 1-pixel cache (16 bits only)
|
||||
cmsUInt16Number CacheIn[cmsMAXCHANNELS];
|
||||
cmsUInt16Number CacheOut[cmsMAXCHANNELS];
|
||||
|
||||
// Semaphor for cache
|
||||
LCMS_RWLOCK_T rwlock;
|
||||
|
||||
// A MPE LUT holding the full (optimized) transform
|
||||
cmsPipeline* Lut;
|
||||
|
||||
// A MPE LUT holding the gamut check. It goes from the input space to bilevel
|
||||
cmsPipeline* GamutCheck;
|
||||
|
||||
// Colorant tables
|
||||
cmsNAMEDCOLORLIST* InputColorant; // Input Colorant table
|
||||
cmsNAMEDCOLORLIST* OutputColorant; // Colorant table (for n chans > CMYK)
|
||||
|
||||
// Informational only
|
||||
cmsColorSpaceSignature EntryColorSpace;
|
||||
cmsColorSpaceSignature ExitColorSpace;
|
||||
|
||||
// Profiles used to create the transform
|
||||
cmsSEQ* Sequence;
|
||||
|
||||
cmsUInt32Number dwOriginalFlags;
|
||||
cmsFloat64Number AdaptationState;
|
||||
|
||||
// The intent of this transform. That is usually the last intent in the profilechain, but may differ
|
||||
cmsUInt32Number RenderingIntent;
|
||||
|
||||
// An id that uniquely identifies the running context. May be null.
|
||||
cmsContext ContextID;
|
||||
|
||||
} _cmsTRANSFORM;
|
||||
|
||||
// --------------------------------------------------------------------------------------------------
|
||||
|
||||
cmsHTRANSFORM _cmsChain2Lab(cmsContext ContextID,
|
||||
cmsUInt32Number nProfiles,
|
||||
cmsUInt32Number InputFormat,
|
||||
cmsUInt32Number OutputFormat,
|
||||
const cmsUInt32Number Intents[],
|
||||
const cmsHPROFILE hProfiles[],
|
||||
const cmsBool BPC[],
|
||||
const cmsFloat64Number AdaptationStates[],
|
||||
cmsUInt32Number dwFlags);
|
||||
|
||||
|
||||
cmsToneCurve* _cmsBuildKToneCurve(cmsContext ContextID,
|
||||
cmsUInt32Number nPoints,
|
||||
cmsUInt32Number nProfiles,
|
||||
const cmsUInt32Number Intents[],
|
||||
const cmsHPROFILE hProfiles[],
|
||||
const cmsBool BPC[],
|
||||
const cmsFloat64Number AdaptationStates[],
|
||||
cmsUInt32Number dwFlags);
|
||||
|
||||
cmsBool _cmsAdaptationMatrix(cmsMAT3* r, const cmsMAT3* ConeMatrix, const cmsCIEXYZ* FromIll, const cmsCIEXYZ* ToIll);
|
||||
|
||||
cmsBool _cmsBuildRGB2XYZtransferMatrix(cmsMAT3* r, const cmsCIExyY* WhitePoint, const cmsCIExyYTRIPLE* Primaries);
|
||||
|
||||
|
||||
#define _lcms_internal_H
|
||||
#endif
|
29
thirdparty/libpng/CMakeLists.txt
vendored
Normal file
29
thirdparty/libpng/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
PROJECT(libpng C)
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
${OPENJPEG_SOURCE_DIR}/thirdparty/include
|
||||
)
|
||||
|
||||
FILE(GLOB SRCS *.c)
|
||||
FILE(GLOB HDRS *.h)
|
||||
SET(EXT_HDRS
|
||||
${OPENJPEG_SOURCE_DIR}/thirdparty/include/zlib.h
|
||||
${OPENJPEG_SOURCE_DIR}/thirdparty/include/zconf.h
|
||||
)
|
||||
#
|
||||
SET(LIBTARGET "png")
|
||||
#
|
||||
ADD_LIBRARY(${LIBTARGET} STATIC ${SRCS} ${HDRS} ${EXT_HDRS})
|
||||
#
|
||||
IF(MSVC)
|
||||
SET_TARGET_PROPERTIES(${LIBTARGET} PROPERTIES PREFIX "lib")
|
||||
ENDIF(MSVC)
|
||||
#
|
||||
TARGET_LINK_LIBRARIES(${LIBTARGET} ${Z_LIBNAME} ${M_LIBRARY})
|
||||
#
|
||||
SET_TARGET_PROPERTIES(${LIBTARGET}
|
||||
PROPERTIES
|
||||
OUTPUT_NAME "${LIBTARGET}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/thirdparty/lib)
|
||||
#
|
111
thirdparty/libpng/LICENSE
vendored
Normal file
111
thirdparty/libpng/LICENSE
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
|
||||
This copy of the libpng notices is provided for your convenience. In case of
|
||||
any discrepancy between this copy and the notices in the file png.h that is
|
||||
included in the libpng distribution, the latter shall prevail.
|
||||
|
||||
COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
|
||||
|
||||
If you modify libpng you may insert additional notices immediately following
|
||||
this sentence.
|
||||
|
||||
This code is released under the libpng license.
|
||||
|
||||
libpng versions 1.2.6, August 15, 2004, through 1.4.4, September 23, 2010, are
|
||||
Copyright (c) 2004, 2006-2010 Glenn Randers-Pehrson, and are
|
||||
distributed according to the same disclaimer and license as libpng-1.2.5
|
||||
with the following individual added to the list of Contributing Authors
|
||||
|
||||
Cosmin Truta
|
||||
|
||||
libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are
|
||||
Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
|
||||
distributed according to the same disclaimer and license as libpng-1.0.6
|
||||
with the following individuals added to the list of Contributing Authors
|
||||
|
||||
Simon-Pierre Cadieux
|
||||
Eric S. Raymond
|
||||
Gilles Vollant
|
||||
|
||||
and with the following additions to the disclaimer:
|
||||
|
||||
There is no warranty against interference with your enjoyment of the
|
||||
library or against infringement. There is no warranty that our
|
||||
efforts or the library will fulfill any of your particular purposes
|
||||
or needs. This library is provided with all faults, and the entire
|
||||
risk of satisfactory quality, performance, accuracy, and effort is with
|
||||
the user.
|
||||
|
||||
libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
|
||||
Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are
|
||||
distributed according to the same disclaimer and license as libpng-0.96,
|
||||
with the following individuals added to the list of Contributing Authors:
|
||||
|
||||
Tom Lane
|
||||
Glenn Randers-Pehrson
|
||||
Willem van Schaik
|
||||
|
||||
libpng versions 0.89, June 1996, through 0.96, May 1997, are
|
||||
Copyright (c) 1996, 1997 Andreas Dilger
|
||||
Distributed according to the same disclaimer and license as libpng-0.88,
|
||||
with the following individuals added to the list of Contributing Authors:
|
||||
|
||||
John Bowler
|
||||
Kevin Bracey
|
||||
Sam Bushell
|
||||
Magnus Holmgren
|
||||
Greg Roelofs
|
||||
Tom Tanner
|
||||
|
||||
libpng versions 0.5, May 1995, through 0.88, January 1996, are
|
||||
Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
|
||||
For the purposes of this copyright and license, "Contributing Authors"
|
||||
is defined as the following set of individuals:
|
||||
|
||||
Andreas Dilger
|
||||
Dave Martindale
|
||||
Guy Eric Schalnat
|
||||
Paul Schmidt
|
||||
Tim Wegner
|
||||
|
||||
The PNG Reference Library is supplied "AS IS". The Contributing Authors
|
||||
and Group 42, Inc. disclaim all warranties, expressed or implied,
|
||||
including, without limitation, the warranties of merchantability and of
|
||||
fitness for any purpose. The Contributing Authors and Group 42, Inc.
|
||||
assume no liability for direct, indirect, incidental, special, exemplary,
|
||||
or consequential damages, which may result from the use of the PNG
|
||||
Reference Library, even if advised of the possibility of such damage.
|
||||
|
||||
Permission is hereby granted to use, copy, modify, and distribute this
|
||||
source code, or portions hereof, for any purpose, without fee, subject
|
||||
to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented.
|
||||
|
||||
2. Altered versions must be plainly marked as such and must not
|
||||
be misrepresented as being the original source.
|
||||
|
||||
3. This Copyright notice may not be removed or altered from any
|
||||
source or altered source distribution.
|
||||
|
||||
The Contributing Authors and Group 42, Inc. specifically permit, without
|
||||
fee, and encourage the use of this source code as a component to
|
||||
supporting the PNG file format in commercial products. If you use this
|
||||
source code in a product, acknowledgment is not required but would be
|
||||
appreciated.
|
||||
|
||||
|
||||
A "png_get_copyright" function is available, for convenient use in "about"
|
||||
boxes and the like:
|
||||
|
||||
printf("%s",png_get_copyright(NULL));
|
||||
|
||||
Also, the PNG logo (in PNG format, of course) is supplied in the
|
||||
files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
|
||||
|
||||
Libpng is OSI Certified Open Source Software. OSI Certified Open Source is a
|
||||
certification mark of the Open Source Initiative.
|
||||
|
||||
Glenn Randers-Pehrson
|
||||
glennrp at users.sourceforge.net
|
||||
September 23, 2010
|
838
thirdparty/libpng/example.c
vendored
Normal file
838
thirdparty/libpng/example.c
vendored
Normal file
@ -0,0 +1,838 @@
|
||||
|
||||
#if 0 /* in case someone actually tries to compile this */
|
||||
|
||||
/* example.c - an example of using libpng
|
||||
* Last changed in libpng 1.4.2 [May 6, 2010]
|
||||
* This file has been placed in the public domain by the authors.
|
||||
* Maintained 1998-2010 Glenn Randers-Pehrson
|
||||
* Maintained 1996, 1997 Andreas Dilger)
|
||||
* Written 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
||||
*/
|
||||
|
||||
/* This is an example of how to use libpng to read and write PNG files.
|
||||
* The file libpng.txt is much more verbose then this. If you have not
|
||||
* read it, do so first. This was designed to be a starting point of an
|
||||
* implementation. This is not officially part of libpng, is hereby placed
|
||||
* in the public domain, and therefore does not require a copyright notice.
|
||||
*
|
||||
* This file does not currently compile, because it is missing certain
|
||||
* parts, like allocating memory to hold an image. You will have to
|
||||
* supply these parts to get it to compile. For an example of a minimal
|
||||
* working PNG reader/writer, see pngtest.c, included in this distribution;
|
||||
* see also the programs in the contrib directory.
|
||||
*/
|
||||
|
||||
#include "png.h"
|
||||
|
||||
/* The png_jmpbuf() macro, used in error handling, became available in
|
||||
* libpng version 1.0.6. If you want to be able to run your code with older
|
||||
* versions of libpng, you must define the macro yourself (but only if it
|
||||
* is not already defined by libpng!).
|
||||
*/
|
||||
|
||||
#ifndef png_jmpbuf
|
||||
# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
|
||||
#endif
|
||||
|
||||
/* Check to see if a file is a PNG file using png_sig_cmp(). png_sig_cmp()
|
||||
* returns zero if the image is a PNG and nonzero if it isn't a PNG.
|
||||
*
|
||||
* The function check_if_png() shown here, but not used, returns nonzero (true)
|
||||
* if the file can be opened and is a PNG, 0 (false) otherwise.
|
||||
*
|
||||
* If this call is successful, and you are going to keep the file open,
|
||||
* you should call png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK); once
|
||||
* you have created the png_ptr, so that libpng knows your application
|
||||
* has read that many bytes from the start of the file. Make sure you
|
||||
* don't call png_set_sig_bytes() with more than 8 bytes read or give it
|
||||
* an incorrect number of bytes read, or you will either have read too
|
||||
* many bytes (your fault), or you are telling libpng to read the wrong
|
||||
* number of magic bytes (also your fault).
|
||||
*
|
||||
* Many applications already read the first 2 or 4 bytes from the start
|
||||
* of the image to determine the file type, so it would be easiest just
|
||||
* to pass the bytes to png_sig_cmp() or even skip that if you know
|
||||
* you have a PNG file, and call png_set_sig_bytes().
|
||||
*/
|
||||
#define PNG_BYTES_TO_CHECK 4
|
||||
int check_if_png(char *file_name, FILE **fp)
|
||||
{
|
||||
char buf[PNG_BYTES_TO_CHECK];
|
||||
|
||||
/* Open the prospective PNG file. */
|
||||
if ((*fp = fopen(file_name, "rb")) == NULL)
|
||||
return 0;
|
||||
|
||||
/* Read in some of the signature bytes */
|
||||
if (fread(buf, 1, PNG_BYTES_TO_CHECK, *fp) != PNG_BYTES_TO_CHECK)
|
||||
return 0;
|
||||
|
||||
/* Compare the first PNG_BYTES_TO_CHECK bytes of the signature.
|
||||
Return nonzero (true) if they match */
|
||||
|
||||
return(!png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK));
|
||||
}
|
||||
|
||||
/* Read a PNG file. You may want to return an error code if the read
|
||||
* fails (depending upon the failure). There are two "prototypes" given
|
||||
* here - one where we are given the filename, and we need to open the
|
||||
* file, and the other where we are given an open file (possibly with
|
||||
* some or all of the magic bytes read - see comments above).
|
||||
*/
|
||||
#ifdef open_file /* prototype 1 */
|
||||
void read_png(char *file_name) /* We need to open the file */
|
||||
{
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
unsigned int sig_read = 0;
|
||||
png_uint_32 width, height;
|
||||
int bit_depth, color_type, interlace_type;
|
||||
FILE *fp;
|
||||
|
||||
if ((fp = fopen(file_name, "rb")) == NULL)
|
||||
return (ERROR);
|
||||
|
||||
#else no_open_file /* prototype 2 */
|
||||
void read_png(FILE *fp, unsigned int sig_read) /* File is already open */
|
||||
{
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
png_uint_32 width, height;
|
||||
int bit_depth, color_type, interlace_type;
|
||||
#endif no_open_file /* Only use one prototype! */
|
||||
|
||||
/* Create and initialize the png_struct with the desired error handler
|
||||
* functions. If you want to use the default stderr and longjump method,
|
||||
* you can supply NULL for the last three parameters. We also supply the
|
||||
* the compiler header file version, so that we know if the application
|
||||
* was compiled with a compatible version of the library. REQUIRED
|
||||
*/
|
||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
|
||||
png_voidp user_error_ptr, user_error_fn, user_warning_fn);
|
||||
|
||||
if (png_ptr == NULL)
|
||||
{
|
||||
fclose(fp);
|
||||
return (ERROR);
|
||||
}
|
||||
|
||||
/* Allocate/initialize the memory for image information. REQUIRED. */
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (info_ptr == NULL)
|
||||
{
|
||||
fclose(fp);
|
||||
png_destroy_read_struct(&png_ptr, NULL, NULL);
|
||||
return (ERROR);
|
||||
}
|
||||
|
||||
/* Set error handling if you are using the setjmp/longjmp method (this is
|
||||
* the normal method of doing things with libpng). REQUIRED unless you
|
||||
* set up your own error handlers in the png_create_read_struct() earlier.
|
||||
*/
|
||||
|
||||
if (setjmp(png_jmpbuf(png_ptr)))
|
||||
{
|
||||
/* Free all of the memory associated with the png_ptr and info_ptr */
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
fclose(fp);
|
||||
/* If we get here, we had a problem reading the file */
|
||||
return (ERROR);
|
||||
}
|
||||
|
||||
/* One of the following I/O initialization methods is REQUIRED */
|
||||
#ifdef streams /* PNG file I/O method 1 */
|
||||
/* Set up the input control if you are using standard C streams */
|
||||
png_init_io(png_ptr, fp);
|
||||
|
||||
#else no_streams /* PNG file I/O method 2 */
|
||||
/* If you are using replacement read functions, instead of calling
|
||||
* png_init_io() here you would call:
|
||||
*/
|
||||
png_set_read_fn(png_ptr, (void *)user_io_ptr, user_read_fn);
|
||||
/* where user_io_ptr is a structure you want available to the callbacks */
|
||||
#endif no_streams /* Use only one I/O method! */
|
||||
|
||||
/* If we have already read some of the signature */
|
||||
png_set_sig_bytes(png_ptr, sig_read);
|
||||
|
||||
#ifdef hilevel
|
||||
/*
|
||||
* If you have enough memory to read in the entire image at once,
|
||||
* and you need to specify only transforms that can be controlled
|
||||
* with one of the PNG_TRANSFORM_* bits (this presently excludes
|
||||
* quantizing, filling, setting background, and doing gamma
|
||||
* adjustment), then you can read the entire image (including
|
||||
* pixels) into the info structure with this call:
|
||||
*/
|
||||
png_read_png(png_ptr, info_ptr, png_transforms, NULL);
|
||||
|
||||
#else
|
||||
/* OK, you're doing it the hard way, with the lower-level functions */
|
||||
|
||||
/* The call to png_read_info() gives us all of the information from the
|
||||
* PNG file before the first IDAT (image data chunk). REQUIRED
|
||||
*/
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
|
||||
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
|
||||
&interlace_type, NULL, NULL);
|
||||
|
||||
/* Set up the data transformations you want. Note that these are all
|
||||
* optional. Only call them if you want/need them. Many of the
|
||||
* transformations only work on specific types of images, and many
|
||||
* are mutually exclusive.
|
||||
*/
|
||||
|
||||
/* Tell libpng to strip 16 bit/color files down to 8 bits/color */
|
||||
png_set_strip_16(png_ptr);
|
||||
|
||||
/* Strip alpha bytes from the input data without combining with the
|
||||
* background (not recommended).
|
||||
*/
|
||||
png_set_strip_alpha(png_ptr);
|
||||
|
||||
/* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
|
||||
* byte into separate bytes (useful for paletted and grayscale images).
|
||||
*/
|
||||
png_set_packing(png_ptr);
|
||||
|
||||
/* Change the order of packed pixels to least significant bit first
|
||||
* (not useful if you are using png_set_packing). */
|
||||
png_set_packswap(png_ptr);
|
||||
|
||||
/* Expand paletted colors into true RGB triplets */
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE)
|
||||
png_set_palette_to_rgb(png_ptr);
|
||||
|
||||
/* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
|
||||
png_set_expand_gray_1_2_4_to_8(png_ptr);
|
||||
|
||||
/* Expand paletted or RGB images with transparency to full alpha channels
|
||||
* so the data will be available as RGBA quartets.
|
||||
*/
|
||||
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
|
||||
png_set_tRNS_to_alpha(png_ptr);
|
||||
|
||||
/* Set the background color to draw transparent and alpha images over.
|
||||
* It is possible to set the red, green, and blue components directly
|
||||
* for paletted images instead of supplying a palette index. Note that
|
||||
* even if the PNG file supplies a background, you are not required to
|
||||
* use it - you should use the (solid) application background if it has one.
|
||||
*/
|
||||
|
||||
png_color_16 my_background, *image_background;
|
||||
|
||||
if (png_get_bKGD(png_ptr, info_ptr, &image_background))
|
||||
png_set_background(png_ptr, image_background,
|
||||
PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
|
||||
else
|
||||
png_set_background(png_ptr, &my_background,
|
||||
PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
|
||||
|
||||
/* Some suggestions as to how to get a screen gamma value
|
||||
*
|
||||
* Note that screen gamma is the display_exponent, which includes
|
||||
* the CRT_exponent and any correction for viewing conditions
|
||||
*/
|
||||
if (/* We have a user-defined screen gamma value */)
|
||||
{
|
||||
screen_gamma = user-defined screen_gamma;
|
||||
}
|
||||
/* This is one way that applications share the same screen gamma value */
|
||||
else if ((gamma_str = getenv("SCREEN_GAMMA")) != NULL)
|
||||
{
|
||||
screen_gamma = atof(gamma_str);
|
||||
}
|
||||
/* If we don't have another value */
|
||||
else
|
||||
{
|
||||
screen_gamma = 2.2; /* A good guess for a PC monitor in a dimly
|
||||
lit room */
|
||||
screen_gamma = 1.7 or 1.0; /* A good guess for Mac systems */
|
||||
}
|
||||
|
||||
/* Tell libpng to handle the gamma conversion for you. The final call
|
||||
* is a good guess for PC generated images, but it should be configurable
|
||||
* by the user at run time by the user. It is strongly suggested that
|
||||
* your application support gamma correction.
|
||||
*/
|
||||
|
||||
int intent;
|
||||
|
||||
if (png_get_sRGB(png_ptr, info_ptr, &intent))
|
||||
png_set_gamma(png_ptr, screen_gamma, 0.45455);
|
||||
else
|
||||
{
|
||||
double image_gamma;
|
||||
if (png_get_gAMA(png_ptr, info_ptr, &image_gamma))
|
||||
png_set_gamma(png_ptr, screen_gamma, image_gamma);
|
||||
else
|
||||
png_set_gamma(png_ptr, screen_gamma, 0.45455);
|
||||
}
|
||||
|
||||
#ifdef PNG_READ_QUANTIZE_SUPPORTED
|
||||
/* Quantize RGB files down to 8 bit palette or reduce palettes
|
||||
* to the number of colors available on your screen.
|
||||
*/
|
||||
if (color_type & PNG_COLOR_MASK_COLOR)
|
||||
{
|
||||
int num_palette;
|
||||
png_colorp palette;
|
||||
|
||||
/* This reduces the image to the application supplied palette */
|
||||
if (/* We have our own palette */)
|
||||
{
|
||||
/* An array of colors to which the image should be quantized */
|
||||
png_color std_color_cube[MAX_SCREEN_COLORS];
|
||||
|
||||
/* Prior to libpng-1.4.2, this was png_set_dither(). */
|
||||
png_set_quantize(png_ptr, std_color_cube, MAX_SCREEN_COLORS,
|
||||
MAX_SCREEN_COLORS, NULL, 0);
|
||||
}
|
||||
/* This reduces the image to the palette supplied in the file */
|
||||
else if (png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette))
|
||||
{
|
||||
png_uint_16p histogram = NULL;
|
||||
|
||||
png_get_hIST(png_ptr, info_ptr, &histogram);
|
||||
|
||||
png_set_quantize(png_ptr, palette, num_palette,
|
||||
max_screen_colors, histogram, 0);
|
||||
}
|
||||
}
|
||||
#endif /* PNG_READ_QUANTIZE_SUPPORTED */
|
||||
|
||||
/* Invert monochrome files to have 0 as white and 1 as black */
|
||||
png_set_invert_mono(png_ptr);
|
||||
|
||||
/* If you want to shift the pixel values from the range [0,255] or
|
||||
* [0,65535] to the original [0,7] or [0,31], or whatever range the
|
||||
* colors were originally in:
|
||||
*/
|
||||
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
|
||||
{
|
||||
png_color_8p sig_bit_p;
|
||||
|
||||
png_get_sBIT(png_ptr, info_ptr, &sig_bit_p);
|
||||
png_set_shift(png_ptr, sig_bit_p);
|
||||
}
|
||||
|
||||
/* Flip the RGB pixels to BGR (or RGBA to BGRA) */
|
||||
if (color_type & PNG_COLOR_MASK_COLOR)
|
||||
png_set_bgr(png_ptr);
|
||||
|
||||
/* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
|
||||
png_set_swap_alpha(png_ptr);
|
||||
|
||||
/* Swap bytes of 16 bit files to least significant byte first */
|
||||
png_set_swap(png_ptr);
|
||||
|
||||
/* Add filler (or alpha) byte (before/after each RGB triplet) */
|
||||
png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
|
||||
|
||||
/* Turn on interlace handling. REQUIRED if you are not using
|
||||
* png_read_image(). To see how to handle interlacing passes,
|
||||
* see the png_read_row() method below:
|
||||
*/
|
||||
number_passes = png_set_interlace_handling(png_ptr);
|
||||
|
||||
/* Optional call to gamma correct and add the background to the palette
|
||||
* and update info structure. REQUIRED if you are expecting libpng to
|
||||
* update the palette for you (ie you selected such a transform above).
|
||||
*/
|
||||
png_read_update_info(png_ptr, info_ptr);
|
||||
|
||||
/* Allocate the memory to hold the image using the fields of info_ptr. */
|
||||
|
||||
/* The easiest way to read the image: */
|
||||
png_bytep row_pointers[height];
|
||||
|
||||
/* Clear the pointer array */
|
||||
for (row = 0; row < height; row++)
|
||||
row_pointers[row] = NULL;
|
||||
|
||||
for (row = 0; row < height; row++)
|
||||
row_pointers[row] = png_malloc(png_ptr, png_get_rowbytes(png_ptr,
|
||||
info_ptr));
|
||||
|
||||
/* Now it's time to read the image. One of these methods is REQUIRED */
|
||||
#ifdef entire /* Read the entire image in one go */
|
||||
png_read_image(png_ptr, row_pointers);
|
||||
|
||||
#else no_entire /* Read the image one or more scanlines at a time */
|
||||
/* The other way to read images - deal with interlacing: */
|
||||
|
||||
for (pass = 0; pass < number_passes; pass++)
|
||||
{
|
||||
#ifdef single /* Read the image a single row at a time */
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
png_read_rows(png_ptr, &row_pointers[y], NULL, 1);
|
||||
}
|
||||
|
||||
#else no_single /* Read the image several rows at a time */
|
||||
for (y = 0; y < height; y += number_of_rows)
|
||||
{
|
||||
#ifdef sparkle /* Read the image using the "sparkle" effect. */
|
||||
png_read_rows(png_ptr, &row_pointers[y], NULL,
|
||||
number_of_rows);
|
||||
#else no_sparkle /* Read the image using the "rectangle" effect */
|
||||
png_read_rows(png_ptr, NULL, &row_pointers[y],
|
||||
number_of_rows);
|
||||
#endif no_sparkle /* Use only one of these two methods */
|
||||
}
|
||||
|
||||
/* If you want to display the image after every pass, do so here */
|
||||
#endif no_single /* Use only one of these two methods */
|
||||
}
|
||||
#endif no_entire /* Use only one of these two methods */
|
||||
|
||||
/* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
|
||||
png_read_end(png_ptr, info_ptr);
|
||||
#endif hilevel
|
||||
|
||||
/* At this point you have read the entire image */
|
||||
|
||||
/* Clean up after the read, and free any memory allocated - REQUIRED */
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
|
||||
/* Close the file */
|
||||
fclose(fp);
|
||||
|
||||
/* That's it */
|
||||
return (OK);
|
||||
}
|
||||
|
||||
/* Progressively read a file */
|
||||
|
||||
int
|
||||
initialize_png_reader(png_structp *png_ptr, png_infop *info_ptr)
|
||||
{
|
||||
/* Create and initialize the png_struct with the desired error handler
|
||||
* functions. If you want to use the default stderr and longjump method,
|
||||
* you can supply NULL for the last three parameters. We also check that
|
||||
* the library version is compatible in case we are using dynamically
|
||||
* linked libraries.
|
||||
*/
|
||||
*png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
|
||||
png_voidp user_error_ptr, user_error_fn, user_warning_fn);
|
||||
|
||||
if (*png_ptr == NULL)
|
||||
{
|
||||
*info_ptr = NULL;
|
||||
return (ERROR);
|
||||
}
|
||||
|
||||
*info_ptr = png_create_info_struct(png_ptr);
|
||||
|
||||
if (*info_ptr == NULL)
|
||||
{
|
||||
png_destroy_read_struct(png_ptr, info_ptr, NULL);
|
||||
return (ERROR);
|
||||
}
|
||||
|
||||
if (setjmp(png_jmpbuf((*png_ptr))))
|
||||
{
|
||||
png_destroy_read_struct(png_ptr, info_ptr, NULL);
|
||||
return (ERROR);
|
||||
}
|
||||
|
||||
/* This one's new. You will need to provide all three
|
||||
* function callbacks, even if you aren't using them all.
|
||||
* If you aren't using all functions, you can specify NULL
|
||||
* parameters. Even when all three functions are NULL,
|
||||
* you need to call png_set_progressive_read_fn().
|
||||
* These functions shouldn't be dependent on global or
|
||||
* static variables if you are decoding several images
|
||||
* simultaneously. You should store stream specific data
|
||||
* in a separate struct, given as the second parameter,
|
||||
* and retrieve the pointer from inside the callbacks using
|
||||
* the function png_get_progressive_ptr(png_ptr).
|
||||
*/
|
||||
png_set_progressive_read_fn(*png_ptr, (void *)stream_data,
|
||||
info_callback, row_callback, end_callback);
|
||||
|
||||
return (OK);
|
||||
}
|
||||
|
||||
int
|
||||
process_data(png_structp *png_ptr, png_infop *info_ptr,
|
||||
png_bytep buffer, png_uint_32 length)
|
||||
{
|
||||
if (setjmp(png_jmpbuf((*png_ptr))))
|
||||
{
|
||||
/* Free the png_ptr and info_ptr memory on error */
|
||||
png_destroy_read_struct(png_ptr, info_ptr, NULL);
|
||||
return (ERROR);
|
||||
}
|
||||
|
||||
/* This one's new also. Simply give it chunks of data as
|
||||
* they arrive from the data stream (in order, of course).
|
||||
* On segmented machines, don't give it any more than 64K.
|
||||
* The library seems to run fine with sizes of 4K, although
|
||||
* you can give it much less if necessary (I assume you can
|
||||
* give it chunks of 1 byte, but I haven't tried with less
|
||||
* than 256 bytes yet). When this function returns, you may
|
||||
* want to display any rows that were generated in the row
|
||||
* callback, if you aren't already displaying them there.
|
||||
*/
|
||||
png_process_data(*png_ptr, *info_ptr, buffer, length);
|
||||
return (OK);
|
||||
}
|
||||
|
||||
info_callback(png_structp png_ptr, png_infop info)
|
||||
{
|
||||
/* Do any setup here, including setting any of the transformations
|
||||
* mentioned in the Reading PNG files section. For now, you _must_
|
||||
* call either png_start_read_image() or png_read_update_info()
|
||||
* after all the transformations are set (even if you don't set
|
||||
* any). You may start getting rows before png_process_data()
|
||||
* returns, so this is your last chance to prepare for that.
|
||||
*/
|
||||
}
|
||||
|
||||
row_callback(png_structp png_ptr, png_bytep new_row,
|
||||
png_uint_32 row_num, int pass)
|
||||
{
|
||||
/*
|
||||
* This function is called for every row in the image. If the
|
||||
* image is interlaced, and you turned on the interlace handler,
|
||||
* this function will be called for every row in every pass.
|
||||
*
|
||||
* In this function you will receive a pointer to new row data from
|
||||
* libpng called new_row that is to replace a corresponding row (of
|
||||
* the same data format) in a buffer allocated by your application.
|
||||
*
|
||||
* The new row data pointer "new_row" may be NULL, indicating there is
|
||||
* no new data to be replaced (in cases of interlace loading).
|
||||
*
|
||||
* If new_row is not NULL then you need to call
|
||||
* png_progressive_combine_row() to replace the corresponding row as
|
||||
* shown below:
|
||||
*/
|
||||
|
||||
/* Get pointer to corresponding row in our
|
||||
* PNG read buffer.
|
||||
*/
|
||||
png_bytep old_row = ((png_bytep *)our_data)[row_num];
|
||||
|
||||
/* If both rows are allocated then copy the new row
|
||||
* data to the corresponding row data.
|
||||
*/
|
||||
if ((old_row != NULL) && (new_row != NULL))
|
||||
png_progressive_combine_row(png_ptr, old_row, new_row);
|
||||
|
||||
/*
|
||||
* The rows and passes are called in order, so you don't really
|
||||
* need the row_num and pass, but I'm supplying them because it
|
||||
* may make your life easier.
|
||||
*
|
||||
* For the non-NULL rows of interlaced images, you must call
|
||||
* png_progressive_combine_row() passing in the new row and the
|
||||
* old row, as demonstrated above. You can call this function for
|
||||
* NULL rows (it will just return) and for non-interlaced images
|
||||
* (it just does the png_memcpy for you) if it will make the code
|
||||
* easier. Thus, you can just do this for all cases:
|
||||
*/
|
||||
|
||||
png_progressive_combine_row(png_ptr, old_row, new_row);
|
||||
|
||||
/* where old_row is what was displayed for previous rows. Note
|
||||
* that the first pass (pass == 0 really) will completely cover
|
||||
* the old row, so the rows do not have to be initialized. After
|
||||
* the first pass (and only for interlaced images), you will have
|
||||
* to pass the current row as new_row, and the function will combine
|
||||
* the old row and the new row.
|
||||
*/
|
||||
}
|
||||
|
||||
end_callback(png_structp png_ptr, png_infop info)
|
||||
{
|
||||
/* This function is called when the whole image has been read,
|
||||
* including any chunks after the image (up to and including
|
||||
* the IEND). You will usually have the same info chunk as you
|
||||
* had in the header, although some data may have been added
|
||||
* to the comments and time fields.
|
||||
*
|
||||
* Most people won't do much here, perhaps setting a flag that
|
||||
* marks the image as finished.
|
||||
*/
|
||||
}
|
||||
|
||||
/* Write a png file */
|
||||
void write_png(char *file_name /* , ... other image information ... */)
|
||||
{
|
||||
FILE *fp;
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
png_colorp palette;
|
||||
|
||||
/* Open the file */
|
||||
fp = fopen(file_name, "wb");
|
||||
if (fp == NULL)
|
||||
return (ERROR);
|
||||
|
||||
/* Create and initialize the png_struct with the desired error handler
|
||||
* functions. If you want to use the default stderr and longjump method,
|
||||
* you can supply NULL for the last three parameters. We also check that
|
||||
* the library version is compatible with the one used at compile time,
|
||||
* in case we are using dynamically linked libraries. REQUIRED.
|
||||
*/
|
||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
|
||||
png_voidp user_error_ptr, user_error_fn, user_warning_fn);
|
||||
|
||||
if (png_ptr == NULL)
|
||||
{
|
||||
fclose(fp);
|
||||
return (ERROR);
|
||||
}
|
||||
|
||||
/* Allocate/initialize the image information data. REQUIRED */
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (info_ptr == NULL)
|
||||
{
|
||||
fclose(fp);
|
||||
png_destroy_write_struct(&png_ptr, NULL);
|
||||
return (ERROR);
|
||||
}
|
||||
|
||||
/* Set error handling. REQUIRED if you aren't supplying your own
|
||||
* error handling functions in the png_create_write_struct() call.
|
||||
*/
|
||||
if (setjmp(png_jmpbuf(png_ptr)))
|
||||
{
|
||||
/* If we get here, we had a problem writing the file */
|
||||
fclose(fp);
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
return (ERROR);
|
||||
}
|
||||
|
||||
/* One of the following I/O initialization functions is REQUIRED */
|
||||
|
||||
#ifdef streams /* I/O initialization method 1 */
|
||||
/* Set up the output control if you are using standard C streams */
|
||||
png_init_io(png_ptr, fp);
|
||||
|
||||
#else no_streams /* I/O initialization method 2 */
|
||||
/* If you are using replacement write functions, instead of calling
|
||||
* png_init_io() here you would call
|
||||
*/
|
||||
png_set_write_fn(png_ptr, (void *)user_io_ptr, user_write_fn,
|
||||
user_IO_flush_function);
|
||||
/* where user_io_ptr is a structure you want available to the callbacks */
|
||||
#endif no_streams /* Only use one initialization method */
|
||||
|
||||
#ifdef hilevel
|
||||
/* This is the easy way. Use it if you already have all the
|
||||
* image info living in the structure. You could "|" many
|
||||
* PNG_TRANSFORM flags into the png_transforms integer here.
|
||||
*/
|
||||
png_write_png(png_ptr, info_ptr, png_transforms, NULL);
|
||||
|
||||
#else
|
||||
/* This is the hard way */
|
||||
|
||||
/* Set the image information here. Width and height are up to 2^31,
|
||||
* bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
|
||||
* the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
|
||||
* PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
|
||||
* or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or
|
||||
* PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
|
||||
* currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
|
||||
*/
|
||||
png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, PNG_COLOR_TYPE_???,
|
||||
PNG_INTERLACE_????, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||
|
||||
/* Set the palette if there is one. REQUIRED for indexed-color images */
|
||||
palette = (png_colorp)png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH
|
||||
* png_sizeof(png_color));
|
||||
/* ... Set palette colors ... */
|
||||
png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH);
|
||||
/* You must not free palette here, because png_set_PLTE only makes a link to
|
||||
* the palette that you malloced. Wait until you are about to destroy
|
||||
* the png structure.
|
||||
*/
|
||||
|
||||
/* Optional significant bit (sBIT) chunk */
|
||||
png_color_8 sig_bit;
|
||||
/* If we are dealing with a grayscale image then */
|
||||
sig_bit.gray = true_bit_depth;
|
||||
/* Otherwise, if we are dealing with a color image then */
|
||||
sig_bit.red = true_red_bit_depth;
|
||||
sig_bit.green = true_green_bit_depth;
|
||||
sig_bit.blue = true_blue_bit_depth;
|
||||
/* If the image has an alpha channel then */
|
||||
sig_bit.alpha = true_alpha_bit_depth;
|
||||
png_set_sBIT(png_ptr, info_ptr, &sig_bit);
|
||||
|
||||
|
||||
/* Optional gamma chunk is strongly suggested if you have any guess
|
||||
* as to the correct gamma of the image.
|
||||
*/
|
||||
png_set_gAMA(png_ptr, info_ptr, gamma);
|
||||
|
||||
/* Optionally write comments into the image */
|
||||
text_ptr[0].key = "Title";
|
||||
text_ptr[0].text = "Mona Lisa";
|
||||
text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
text_ptr[1].key = "Author";
|
||||
text_ptr[1].text = "Leonardo DaVinci";
|
||||
text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
text_ptr[2].key = "Description";
|
||||
text_ptr[2].text = "<long text>";
|
||||
text_ptr[2].compression = PNG_TEXT_COMPRESSION_zTXt;
|
||||
#ifdef PNG_iTXt_SUPPORTED
|
||||
text_ptr[0].lang = NULL;
|
||||
text_ptr[0].lang_key = NULL;
|
||||
text_ptr[1].lang = NULL;
|
||||
text_ptr[1].lang_key = NULL;
|
||||
text_ptr[2].lang = NULL;
|
||||
text_ptr[2].lang_key = NULL;
|
||||
#endif
|
||||
png_set_text(png_ptr, info_ptr, text_ptr, 3);
|
||||
|
||||
/* Other optional chunks like cHRM, bKGD, tRNS, tIME, oFFs, pHYs */
|
||||
|
||||
/* Note that if sRGB is present the gAMA and cHRM chunks must be ignored
|
||||
* on read and, if your application chooses to write them, they must
|
||||
* be written in accordance with the sRGB profile
|
||||
*/
|
||||
|
||||
/* Write the file header information. REQUIRED */
|
||||
png_write_info(png_ptr, info_ptr);
|
||||
|
||||
/* If you want, you can write the info in two steps, in case you need to
|
||||
* write your private chunk ahead of PLTE:
|
||||
*
|
||||
* png_write_info_before_PLTE(write_ptr, write_info_ptr);
|
||||
* write_my_chunk();
|
||||
* png_write_info(png_ptr, info_ptr);
|
||||
*
|
||||
* However, given the level of known- and unknown-chunk support in 1.2.0
|
||||
* and up, this should no longer be necessary.
|
||||
*/
|
||||
|
||||
/* Once we write out the header, the compression type on the text
|
||||
* chunks gets changed to PNG_TEXT_COMPRESSION_NONE_WR or
|
||||
* PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again
|
||||
* at the end.
|
||||
*/
|
||||
|
||||
/* Set up the transformations you want. Note that these are
|
||||
* all optional. Only call them if you want them.
|
||||
*/
|
||||
|
||||
/* Invert monochrome pixels */
|
||||
png_set_invert_mono(png_ptr);
|
||||
|
||||
/* Shift the pixels up to a legal bit depth and fill in
|
||||
* as appropriate to correctly scale the image.
|
||||
*/
|
||||
png_set_shift(png_ptr, &sig_bit);
|
||||
|
||||
/* Pack pixels into bytes */
|
||||
png_set_packing(png_ptr);
|
||||
|
||||
/* Swap location of alpha bytes from ARGB to RGBA */
|
||||
png_set_swap_alpha(png_ptr);
|
||||
|
||||
/* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into
|
||||
* RGB (4 channels -> 3 channels). The second parameter is not used.
|
||||
*/
|
||||
png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
|
||||
|
||||
/* Flip BGR pixels to RGB */
|
||||
png_set_bgr(png_ptr);
|
||||
|
||||
/* Swap bytes of 16-bit files to most significant byte first */
|
||||
png_set_swap(png_ptr);
|
||||
|
||||
/* Swap bits of 1, 2, 4 bit packed pixel formats */
|
||||
png_set_packswap(png_ptr);
|
||||
|
||||
/* Turn on interlace handling if you are not using png_write_image() */
|
||||
if (interlacing)
|
||||
number_passes = png_set_interlace_handling(png_ptr);
|
||||
else
|
||||
number_passes = 1;
|
||||
|
||||
/* The easiest way to write the image (you may have a different memory
|
||||
* layout, however, so choose what fits your needs best). You need to
|
||||
* use the first method if you aren't handling interlacing yourself.
|
||||
*/
|
||||
png_uint_32 k, height, width;
|
||||
png_byte image[height][width*bytes_per_pixel];
|
||||
png_bytep row_pointers[height];
|
||||
|
||||
if (height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
|
||||
png_error (png_ptr, "Image is too tall to process in memory");
|
||||
|
||||
for (k = 0; k < height; k++)
|
||||
row_pointers[k] = image + k*width*bytes_per_pixel;
|
||||
|
||||
/* One of the following output methods is REQUIRED */
|
||||
|
||||
#ifdef entire /* Write out the entire image data in one call */
|
||||
png_write_image(png_ptr, row_pointers);
|
||||
|
||||
/* The other way to write the image - deal with interlacing */
|
||||
|
||||
#else no_entire /* Write out the image data by one or more scanlines */
|
||||
|
||||
/* The number of passes is either 1 for non-interlaced images,
|
||||
* or 7 for interlaced images.
|
||||
*/
|
||||
for (pass = 0; pass < number_passes; pass++)
|
||||
{
|
||||
/* Write a few rows at a time. */
|
||||
png_write_rows(png_ptr, &row_pointers[first_row], number_of_rows);
|
||||
|
||||
/* If you are only writing one row at a time, this works */
|
||||
for (y = 0; y < height; y++)
|
||||
png_write_rows(png_ptr, &row_pointers[y], 1);
|
||||
}
|
||||
#endif no_entire /* Use only one output method */
|
||||
|
||||
/* You can write optional chunks like tEXt, zTXt, and tIME at the end
|
||||
* as well. Shouldn't be necessary in 1.2.0 and up as all the public
|
||||
* chunks are supported and you can use png_set_unknown_chunks() to
|
||||
* register unknown chunks into the info structure to be written out.
|
||||
*/
|
||||
|
||||
/* It is REQUIRED to call this to finish writing the rest of the file */
|
||||
png_write_end(png_ptr, info_ptr);
|
||||
#endif hilevel
|
||||
|
||||
/* If you png_malloced a palette, free it here (don't free info_ptr->palette,
|
||||
* as recommended in versions 1.0.5m and earlier of this example; if
|
||||
* libpng mallocs info_ptr->palette, libpng will free it). If you
|
||||
* allocated it with malloc() instead of png_malloc(), use free() instead
|
||||
* of png_free().
|
||||
*/
|
||||
png_free(png_ptr, palette);
|
||||
palette = NULL;
|
||||
|
||||
/* Similarly, if you png_malloced any data that you passed in with
|
||||
* png_set_something(), such as a hist or trans array, free it here,
|
||||
* when you can be sure that libpng is through with it.
|
||||
*/
|
||||
png_free(png_ptr, trans);
|
||||
trans = NULL;
|
||||
/* Whenever you use png_free() it is a good idea to set the pointer to
|
||||
* NULL in case your application inadvertently tries to png_free() it
|
||||
* again. When png_free() sees a NULL it returns without action, thus
|
||||
* avoiding the double-free security problem.
|
||||
*/
|
||||
|
||||
/* Clean up after the write, and free any memory allocated */
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
|
||||
/* Close the file */
|
||||
fclose(fp);
|
||||
|
||||
/* That's it */
|
||||
return (OK);
|
||||
}
|
||||
|
||||
#endif /* if 0 */
|
918
thirdparty/libpng/png.c
vendored
Normal file
918
thirdparty/libpng/png.c
vendored
Normal file
@ -0,0 +1,918 @@
|
||||
|
||||
/* png.c - location for general purpose libpng functions
|
||||
*
|
||||
* Last changed in libpng 1.4.2 [May 6, 2010]
|
||||
* Copyright (c) 1998-2010 Glenn Randers-Pehrson
|
||||
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
|
||||
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*/
|
||||
|
||||
#define PNG_NO_EXTERN
|
||||
#define PNG_NO_PEDANTIC_WARNINGS
|
||||
#include "png.h"
|
||||
#include "pngpriv.h"
|
||||
|
||||
/* Generate a compiler error if there is an old png.h in the search path. */
|
||||
typedef version_1_4_4 Your_png_h_is_not_version_1_4_4;
|
||||
|
||||
/* Version information for C files. This had better match the version
|
||||
* string defined in png.h.
|
||||
*/
|
||||
|
||||
/* Tells libpng that we have already handled the first "num_bytes" bytes
|
||||
* of the PNG file signature. If the PNG data is embedded into another
|
||||
* stream we can set num_bytes = 8 so that libpng will not attempt to read
|
||||
* or write any of the magic bytes before it starts on the IHDR.
|
||||
*/
|
||||
|
||||
#ifdef PNG_READ_SUPPORTED
|
||||
void PNGAPI
|
||||
png_set_sig_bytes(png_structp png_ptr, int num_bytes)
|
||||
{
|
||||
png_debug(1, "in png_set_sig_bytes");
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
|
||||
if (num_bytes > 8)
|
||||
png_error(png_ptr, "Too many bytes for PNG signature");
|
||||
|
||||
png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes);
|
||||
}
|
||||
|
||||
/* Checks whether the supplied bytes match the PNG signature. We allow
|
||||
* checking less than the full 8-byte signature so that those apps that
|
||||
* already read the first few bytes of a file to determine the file type
|
||||
* can simply check the remaining bytes for extra assurance. Returns
|
||||
* an integer less than, equal to, or greater than zero if sig is found,
|
||||
* respectively, to be less than, to match, or be greater than the correct
|
||||
* PNG signature (this is the same behaviour as strcmp, memcmp, etc).
|
||||
*/
|
||||
int PNGAPI
|
||||
png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check)
|
||||
{
|
||||
png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
|
||||
if (num_to_check > 8)
|
||||
num_to_check = 8;
|
||||
else if (num_to_check < 1)
|
||||
return (-1);
|
||||
|
||||
if (start > 7)
|
||||
return (-1);
|
||||
|
||||
if (start + num_to_check > 8)
|
||||
num_to_check = 8 - start;
|
||||
|
||||
return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check)));
|
||||
}
|
||||
|
||||
#endif /* PNG_READ_SUPPORTED */
|
||||
|
||||
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
|
||||
/* Function to allocate memory for zlib and clear it to 0. */
|
||||
voidpf /* PRIVATE */
|
||||
png_zalloc(voidpf png_ptr, uInt items, uInt size)
|
||||
{
|
||||
png_voidp ptr;
|
||||
png_structp p=(png_structp)png_ptr;
|
||||
png_uint_32 save_flags=p->flags;
|
||||
png_alloc_size_t num_bytes;
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return (NULL);
|
||||
if (items > PNG_UINT_32_MAX/size)
|
||||
{
|
||||
png_warning (p, "Potential overflow in png_zalloc()");
|
||||
return (NULL);
|
||||
}
|
||||
num_bytes = (png_alloc_size_t)items * size;
|
||||
|
||||
p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
|
||||
ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes);
|
||||
p->flags=save_flags;
|
||||
|
||||
return ((voidpf)ptr);
|
||||
}
|
||||
|
||||
/* Function to free memory for zlib */
|
||||
void /* PRIVATE */
|
||||
png_zfree(voidpf png_ptr, voidpf ptr)
|
||||
{
|
||||
png_free((png_structp)png_ptr, (png_voidp)ptr);
|
||||
}
|
||||
|
||||
/* Reset the CRC variable to 32 bits of 1's. Care must be taken
|
||||
* in case CRC is > 32 bits to leave the top bits 0.
|
||||
*/
|
||||
void /* PRIVATE */
|
||||
png_reset_crc(png_structp png_ptr)
|
||||
{
|
||||
png_ptr->crc = crc32(0, Z_NULL, 0);
|
||||
}
|
||||
|
||||
/* Calculate the CRC over a section of data. We can only pass as
|
||||
* much data to this routine as the largest single buffer size. We
|
||||
* also check that this data will actually be used before going to the
|
||||
* trouble of calculating it.
|
||||
*/
|
||||
void /* PRIVATE */
|
||||
png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length)
|
||||
{
|
||||
int need_crc = 1;
|
||||
|
||||
if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
|
||||
{
|
||||
if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
|
||||
(PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
|
||||
need_crc = 0;
|
||||
}
|
||||
else /* critical */
|
||||
{
|
||||
if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
|
||||
need_crc = 0;
|
||||
}
|
||||
|
||||
if (need_crc)
|
||||
png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length);
|
||||
}
|
||||
|
||||
/* Allocate the memory for an info_struct for the application. We don't
|
||||
* really need the png_ptr, but it could potentially be useful in the
|
||||
* future. This should be used in favour of malloc(png_sizeof(png_info))
|
||||
* and png_info_init() so that applications that want to use a shared
|
||||
* libpng don't have to be recompiled if png_info changes size.
|
||||
*/
|
||||
png_infop PNGAPI
|
||||
png_create_info_struct(png_structp png_ptr)
|
||||
{
|
||||
png_infop info_ptr;
|
||||
|
||||
png_debug(1, "in png_create_info_struct");
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return (NULL);
|
||||
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO,
|
||||
png_ptr->malloc_fn, png_ptr->mem_ptr);
|
||||
#else
|
||||
info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
|
||||
#endif
|
||||
if (info_ptr != NULL)
|
||||
png_info_init_3(&info_ptr, png_sizeof(png_info));
|
||||
|
||||
return (info_ptr);
|
||||
}
|
||||
|
||||
/* This function frees the memory associated with a single info struct.
|
||||
* Normally, one would use either png_destroy_read_struct() or
|
||||
* png_destroy_write_struct() to free an info struct, but this may be
|
||||
* useful for some applications.
|
||||
*/
|
||||
void PNGAPI
|
||||
png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr)
|
||||
{
|
||||
png_infop info_ptr = NULL;
|
||||
|
||||
png_debug(1, "in png_destroy_info_struct");
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
|
||||
if (info_ptr_ptr != NULL)
|
||||
info_ptr = *info_ptr_ptr;
|
||||
|
||||
if (info_ptr != NULL)
|
||||
{
|
||||
png_info_destroy(png_ptr, info_ptr);
|
||||
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn,
|
||||
png_ptr->mem_ptr);
|
||||
#else
|
||||
png_destroy_struct((png_voidp)info_ptr);
|
||||
#endif
|
||||
*info_ptr_ptr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize the info structure. This is now an internal function (0.89)
|
||||
* and applications using it are urged to use png_create_info_struct()
|
||||
* instead.
|
||||
*/
|
||||
|
||||
void PNGAPI
|
||||
png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size)
|
||||
{
|
||||
png_infop info_ptr = *ptr_ptr;
|
||||
|
||||
png_debug(1, "in png_info_init_3");
|
||||
|
||||
if (info_ptr == NULL)
|
||||
return;
|
||||
|
||||
if (png_sizeof(png_info) > png_info_struct_size)
|
||||
{
|
||||
png_destroy_struct(info_ptr);
|
||||
info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
|
||||
*ptr_ptr = info_ptr;
|
||||
}
|
||||
|
||||
/* Set everything to 0 */
|
||||
png_memset(info_ptr, 0, png_sizeof(png_info));
|
||||
}
|
||||
|
||||
void PNGAPI
|
||||
png_data_freer(png_structp png_ptr, png_infop info_ptr,
|
||||
int freer, png_uint_32 mask)
|
||||
{
|
||||
png_debug(1, "in png_data_freer");
|
||||
|
||||
if (png_ptr == NULL || info_ptr == NULL)
|
||||
return;
|
||||
|
||||
if (freer == PNG_DESTROY_WILL_FREE_DATA)
|
||||
info_ptr->free_me |= mask;
|
||||
else if (freer == PNG_USER_WILL_FREE_DATA)
|
||||
info_ptr->free_me &= ~mask;
|
||||
else
|
||||
png_warning(png_ptr,
|
||||
"Unknown freer parameter in png_data_freer");
|
||||
}
|
||||
|
||||
void PNGAPI
|
||||
png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask,
|
||||
int num)
|
||||
{
|
||||
png_debug(1, "in png_free_data");
|
||||
|
||||
if (png_ptr == NULL || info_ptr == NULL)
|
||||
return;
|
||||
|
||||
#ifdef PNG_TEXT_SUPPORTED
|
||||
/* Free text item num or (if num == -1) all text items */
|
||||
if ((mask & PNG_FREE_TEXT) & info_ptr->free_me)
|
||||
{
|
||||
if (num != -1)
|
||||
{
|
||||
if (info_ptr->text && info_ptr->text[num].key)
|
||||
{
|
||||
png_free(png_ptr, info_ptr->text[num].key);
|
||||
info_ptr->text[num].key = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < info_ptr->num_text; i++)
|
||||
png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i);
|
||||
png_free(png_ptr, info_ptr->text);
|
||||
info_ptr->text = NULL;
|
||||
info_ptr->num_text=0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_tRNS_SUPPORTED
|
||||
/* Free any tRNS entry */
|
||||
if ((mask & PNG_FREE_TRNS) & info_ptr->free_me)
|
||||
{
|
||||
png_free(png_ptr, info_ptr->trans_alpha);
|
||||
info_ptr->trans_alpha = NULL;
|
||||
info_ptr->valid &= ~PNG_INFO_tRNS;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_sCAL_SUPPORTED
|
||||
/* Free any sCAL entry */
|
||||
if ((mask & PNG_FREE_SCAL) & info_ptr->free_me)
|
||||
{
|
||||
#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
|
||||
png_free(png_ptr, info_ptr->scal_s_width);
|
||||
png_free(png_ptr, info_ptr->scal_s_height);
|
||||
info_ptr->scal_s_width = NULL;
|
||||
info_ptr->scal_s_height = NULL;
|
||||
#endif
|
||||
info_ptr->valid &= ~PNG_INFO_sCAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_pCAL_SUPPORTED
|
||||
/* Free any pCAL entry */
|
||||
if ((mask & PNG_FREE_PCAL) & info_ptr->free_me)
|
||||
{
|
||||
png_free(png_ptr, info_ptr->pcal_purpose);
|
||||
png_free(png_ptr, info_ptr->pcal_units);
|
||||
info_ptr->pcal_purpose = NULL;
|
||||
info_ptr->pcal_units = NULL;
|
||||
if (info_ptr->pcal_params != NULL)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
|
||||
{
|
||||
png_free(png_ptr, info_ptr->pcal_params[i]);
|
||||
info_ptr->pcal_params[i] = NULL;
|
||||
}
|
||||
png_free(png_ptr, info_ptr->pcal_params);
|
||||
info_ptr->pcal_params = NULL;
|
||||
}
|
||||
info_ptr->valid &= ~PNG_INFO_pCAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_iCCP_SUPPORTED
|
||||
/* Free any iCCP entry */
|
||||
if ((mask & PNG_FREE_ICCP) & info_ptr->free_me)
|
||||
{
|
||||
png_free(png_ptr, info_ptr->iccp_name);
|
||||
png_free(png_ptr, info_ptr->iccp_profile);
|
||||
info_ptr->iccp_name = NULL;
|
||||
info_ptr->iccp_profile = NULL;
|
||||
info_ptr->valid &= ~PNG_INFO_iCCP;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_sPLT_SUPPORTED
|
||||
/* Free a given sPLT entry, or (if num == -1) all sPLT entries */
|
||||
if ((mask & PNG_FREE_SPLT) & info_ptr->free_me)
|
||||
{
|
||||
if (num != -1)
|
||||
{
|
||||
if (info_ptr->splt_palettes)
|
||||
{
|
||||
png_free(png_ptr, info_ptr->splt_palettes[num].name);
|
||||
png_free(png_ptr, info_ptr->splt_palettes[num].entries);
|
||||
info_ptr->splt_palettes[num].name = NULL;
|
||||
info_ptr->splt_palettes[num].entries = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (info_ptr->splt_palettes_num)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
|
||||
png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i);
|
||||
|
||||
png_free(png_ptr, info_ptr->splt_palettes);
|
||||
info_ptr->splt_palettes = NULL;
|
||||
info_ptr->splt_palettes_num = 0;
|
||||
}
|
||||
info_ptr->valid &= ~PNG_INFO_sPLT;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
|
||||
if (png_ptr->unknown_chunk.data)
|
||||
{
|
||||
png_free(png_ptr, png_ptr->unknown_chunk.data);
|
||||
png_ptr->unknown_chunk.data = NULL;
|
||||
}
|
||||
|
||||
if ((mask & PNG_FREE_UNKN) & info_ptr->free_me)
|
||||
{
|
||||
if (num != -1)
|
||||
{
|
||||
if (info_ptr->unknown_chunks)
|
||||
{
|
||||
png_free(png_ptr, info_ptr->unknown_chunks[num].data);
|
||||
info_ptr->unknown_chunks[num].data = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
if (info_ptr->unknown_chunks_num)
|
||||
{
|
||||
for (i = 0; i < (int)info_ptr->unknown_chunks_num; i++)
|
||||
png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i);
|
||||
|
||||
png_free(png_ptr, info_ptr->unknown_chunks);
|
||||
info_ptr->unknown_chunks = NULL;
|
||||
info_ptr->unknown_chunks_num = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_hIST_SUPPORTED
|
||||
/* Free any hIST entry */
|
||||
if ((mask & PNG_FREE_HIST) & info_ptr->free_me)
|
||||
{
|
||||
png_free(png_ptr, info_ptr->hist);
|
||||
info_ptr->hist = NULL;
|
||||
info_ptr->valid &= ~PNG_INFO_hIST;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Free any PLTE entry that was internally allocated */
|
||||
if ((mask & PNG_FREE_PLTE) & info_ptr->free_me)
|
||||
{
|
||||
png_zfree(png_ptr, info_ptr->palette);
|
||||
info_ptr->palette = NULL;
|
||||
info_ptr->valid &= ~PNG_INFO_PLTE;
|
||||
info_ptr->num_palette = 0;
|
||||
}
|
||||
|
||||
#ifdef PNG_INFO_IMAGE_SUPPORTED
|
||||
/* Free any image bits attached to the info structure */
|
||||
if ((mask & PNG_FREE_ROWS) & info_ptr->free_me)
|
||||
{
|
||||
if (info_ptr->row_pointers)
|
||||
{
|
||||
int row;
|
||||
for (row = 0; row < (int)info_ptr->height; row++)
|
||||
{
|
||||
png_free(png_ptr, info_ptr->row_pointers[row]);
|
||||
info_ptr->row_pointers[row] = NULL;
|
||||
}
|
||||
png_free(png_ptr, info_ptr->row_pointers);
|
||||
info_ptr->row_pointers = NULL;
|
||||
}
|
||||
info_ptr->valid &= ~PNG_INFO_IDAT;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (num == -1)
|
||||
info_ptr->free_me &= ~mask;
|
||||
else
|
||||
info_ptr->free_me &= ~(mask & ~PNG_FREE_MUL);
|
||||
}
|
||||
|
||||
/* This is an internal routine to free any memory that the info struct is
|
||||
* pointing to before re-using it or freeing the struct itself. Recall
|
||||
* that png_free() checks for NULL pointers for us.
|
||||
*/
|
||||
void /* PRIVATE */
|
||||
png_info_destroy(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
png_debug(1, "in png_info_destroy");
|
||||
|
||||
png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
|
||||
|
||||
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
|
||||
if (png_ptr->num_chunk_list)
|
||||
{
|
||||
png_free(png_ptr, png_ptr->chunk_list);
|
||||
png_ptr->chunk_list = NULL;
|
||||
png_ptr->num_chunk_list = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
png_info_init_3(&info_ptr, png_sizeof(png_info));
|
||||
}
|
||||
#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
|
||||
|
||||
/* This function returns a pointer to the io_ptr associated with the user
|
||||
* functions. The application should free any memory associated with this
|
||||
* pointer before png_write_destroy() or png_read_destroy() are called.
|
||||
*/
|
||||
png_voidp PNGAPI
|
||||
png_get_io_ptr(png_structp png_ptr)
|
||||
{
|
||||
if (png_ptr == NULL)
|
||||
return (NULL);
|
||||
return (png_ptr->io_ptr);
|
||||
}
|
||||
|
||||
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
|
||||
#ifdef PNG_STDIO_SUPPORTED
|
||||
/* Initialize the default input/output functions for the PNG file. If you
|
||||
* use your own read or write routines, you can call either png_set_read_fn()
|
||||
* or png_set_write_fn() instead of png_init_io(). If you have defined
|
||||
* PNG_NO_STDIO, you must use a function of your own because "FILE *" isn't
|
||||
* necessarily available.
|
||||
*/
|
||||
void PNGAPI
|
||||
png_init_io(png_structp png_ptr, png_FILE_p fp)
|
||||
{
|
||||
png_debug(1, "in png_init_io");
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
|
||||
png_ptr->io_ptr = (png_voidp)fp;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_TIME_RFC1123_SUPPORTED
|
||||
/* Convert the supplied time into an RFC 1123 string suitable for use in
|
||||
* a "Creation Time" or other text-based time string.
|
||||
*/
|
||||
png_charp PNGAPI
|
||||
png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime)
|
||||
{
|
||||
static PNG_CONST char short_months[12][4] =
|
||||
{"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return (NULL);
|
||||
if (png_ptr->time_buffer == NULL)
|
||||
{
|
||||
png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29*
|
||||
png_sizeof(char)));
|
||||
}
|
||||
|
||||
#ifdef USE_FAR_KEYWORD
|
||||
{
|
||||
char near_time_buf[29];
|
||||
png_snprintf6(near_time_buf, 29, "%d %s %d %02d:%02d:%02d +0000",
|
||||
ptime->day % 32, short_months[(ptime->month - 1) % 12],
|
||||
ptime->year, ptime->hour % 24, ptime->minute % 60,
|
||||
ptime->second % 61);
|
||||
png_memcpy(png_ptr->time_buffer, near_time_buf,
|
||||
29*png_sizeof(char));
|
||||
}
|
||||
#else
|
||||
png_snprintf6(png_ptr->time_buffer, 29, "%d %s %d %02d:%02d:%02d +0000",
|
||||
ptime->day % 32, short_months[(ptime->month - 1) % 12],
|
||||
ptime->year, ptime->hour % 24, ptime->minute % 60,
|
||||
ptime->second % 61);
|
||||
#endif
|
||||
return ((png_charp)png_ptr->time_buffer);
|
||||
}
|
||||
#endif /* PNG_TIME_RFC1123_SUPPORTED */
|
||||
|
||||
#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
|
||||
|
||||
png_charp PNGAPI
|
||||
png_get_copyright(png_structp png_ptr)
|
||||
{
|
||||
png_ptr = png_ptr; /* Silence compiler warning about unused png_ptr */
|
||||
#ifdef PNG_STRING_COPYRIGHT
|
||||
return PNG_STRING_COPYRIGHT
|
||||
#else
|
||||
#ifdef __STDC__
|
||||
return ((png_charp) PNG_STRING_NEWLINE \
|
||||
"libpng version 1.4.4 - September 23, 2010" PNG_STRING_NEWLINE \
|
||||
"Copyright (c) 1998-2010 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
|
||||
"Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
|
||||
"Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
|
||||
PNG_STRING_NEWLINE);
|
||||
#else
|
||||
return ((png_charp) "libpng version 1.4.4 - September 23, 2010\
|
||||
Copyright (c) 1998-2010 Glenn Randers-Pehrson\
|
||||
Copyright (c) 1996-1997 Andreas Dilger\
|
||||
Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/* The following return the library version as a short string in the
|
||||
* format 1.0.0 through 99.99.99zz. To get the version of *.h files
|
||||
* used with your application, print out PNG_LIBPNG_VER_STRING, which
|
||||
* is defined in png.h.
|
||||
* Note: now there is no difference between png_get_libpng_ver() and
|
||||
* png_get_header_ver(). Due to the version_nn_nn_nn typedef guard,
|
||||
* it is guaranteed that png.c uses the correct version of png.h.
|
||||
*/
|
||||
png_charp PNGAPI
|
||||
png_get_libpng_ver(png_structp png_ptr)
|
||||
{
|
||||
/* Version of *.c files used when building libpng */
|
||||
png_ptr = png_ptr; /* Silence compiler warning about unused png_ptr */
|
||||
return ((png_charp) PNG_LIBPNG_VER_STRING);
|
||||
}
|
||||
|
||||
png_charp PNGAPI
|
||||
png_get_header_ver(png_structp png_ptr)
|
||||
{
|
||||
/* Version of *.h files used when building libpng */
|
||||
png_ptr = png_ptr; /* Silence compiler warning about unused png_ptr */
|
||||
return ((png_charp) PNG_LIBPNG_VER_STRING);
|
||||
}
|
||||
|
||||
png_charp PNGAPI
|
||||
png_get_header_version(png_structp png_ptr)
|
||||
{
|
||||
/* Returns longer string containing both version and date */
|
||||
png_ptr = png_ptr; /* Silence compiler warning about unused png_ptr */
|
||||
#ifdef __STDC__
|
||||
return ((png_charp) PNG_HEADER_VERSION_STRING
|
||||
#ifndef PNG_READ_SUPPORTED
|
||||
" (NO READ SUPPORT)"
|
||||
#endif
|
||||
PNG_STRING_NEWLINE);
|
||||
#else
|
||||
return ((png_charp) PNG_HEADER_VERSION_STRING);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
|
||||
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
|
||||
int PNGAPI
|
||||
png_handle_as_unknown(png_structp png_ptr, png_bytep chunk_name)
|
||||
{
|
||||
/* Check chunk_name and return "keep" value if it's on the list, else 0 */
|
||||
int i;
|
||||
png_bytep p;
|
||||
if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list<=0)
|
||||
return 0;
|
||||
p = png_ptr->chunk_list + png_ptr->num_chunk_list*5 - 5;
|
||||
for (i = png_ptr->num_chunk_list; i; i--, p -= 5)
|
||||
if (!png_memcmp(chunk_name, p, 4))
|
||||
return ((int)*(p + 4));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
|
||||
|
||||
#ifdef PNG_READ_SUPPORTED
|
||||
/* This function, added to libpng-1.0.6g, is untested. */
|
||||
int PNGAPI
|
||||
png_reset_zstream(png_structp png_ptr)
|
||||
{
|
||||
if (png_ptr == NULL)
|
||||
return Z_STREAM_ERROR;
|
||||
return (inflateReset(&png_ptr->zstream));
|
||||
}
|
||||
#endif /* PNG_READ_SUPPORTED */
|
||||
|
||||
/* This function was added to libpng-1.0.7 */
|
||||
png_uint_32 PNGAPI
|
||||
png_access_version_number(void)
|
||||
{
|
||||
/* Version of *.c files used when building libpng */
|
||||
return((png_uint_32) PNG_LIBPNG_VER);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
|
||||
#ifdef PNG_SIZE_T
|
||||
/* Added at libpng version 1.2.6 */
|
||||
PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size));
|
||||
png_size_t PNGAPI
|
||||
png_convert_size(size_t size)
|
||||
{
|
||||
if (size > (png_size_t)-1)
|
||||
PNG_ABORT(); /* We haven't got access to png_ptr, so no png_error() */
|
||||
return ((png_size_t)size);
|
||||
}
|
||||
#endif /* PNG_SIZE_T */
|
||||
|
||||
/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */
|
||||
#ifdef PNG_cHRM_SUPPORTED
|
||||
#ifdef PNG_CHECK_cHRM_SUPPORTED
|
||||
|
||||
/*
|
||||
* Multiply two 32-bit numbers, V1 and V2, using 32-bit
|
||||
* arithmetic, to produce a 64 bit result in the HI/LO words.
|
||||
*
|
||||
* A B
|
||||
* x C D
|
||||
* ------
|
||||
* AD || BD
|
||||
* AC || CB || 0
|
||||
*
|
||||
* where A and B are the high and low 16-bit words of V1,
|
||||
* C and D are the 16-bit words of V2, AD is the product of
|
||||
* A and D, and X || Y is (X << 16) + Y.
|
||||
*/
|
||||
|
||||
void /* PRIVATE */
|
||||
png_64bit_product (long v1, long v2, unsigned long *hi_product,
|
||||
unsigned long *lo_product)
|
||||
{
|
||||
int a, b, c, d;
|
||||
long lo, hi, x, y;
|
||||
|
||||
a = (v1 >> 16) & 0xffff;
|
||||
b = v1 & 0xffff;
|
||||
c = (v2 >> 16) & 0xffff;
|
||||
d = v2 & 0xffff;
|
||||
|
||||
lo = b * d; /* BD */
|
||||
x = a * d + c * b; /* AD + CB */
|
||||
y = ((lo >> 16) & 0xffff) + x;
|
||||
|
||||
lo = (lo & 0xffff) | ((y & 0xffff) << 16);
|
||||
hi = (y >> 16) & 0xffff;
|
||||
|
||||
hi += a * c; /* AC */
|
||||
|
||||
*hi_product = (unsigned long)hi;
|
||||
*lo_product = (unsigned long)lo;
|
||||
}
|
||||
|
||||
int /* PRIVATE */
|
||||
png_check_cHRM_fixed(png_structp png_ptr,
|
||||
png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
|
||||
png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
|
||||
png_fixed_point blue_x, png_fixed_point blue_y)
|
||||
{
|
||||
int ret = 1;
|
||||
unsigned long xy_hi,xy_lo,yx_hi,yx_lo;
|
||||
|
||||
png_debug(1, "in function png_check_cHRM_fixed");
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return 0;
|
||||
|
||||
if (white_x < 0 || white_y <= 0 ||
|
||||
red_x < 0 || red_y < 0 ||
|
||||
green_x < 0 || green_y < 0 ||
|
||||
blue_x < 0 || blue_y < 0)
|
||||
{
|
||||
png_warning(png_ptr,
|
||||
"Ignoring attempt to set negative chromaticity value");
|
||||
ret = 0;
|
||||
}
|
||||
if (white_x > (png_fixed_point) PNG_UINT_31_MAX ||
|
||||
white_y > (png_fixed_point) PNG_UINT_31_MAX ||
|
||||
red_x > (png_fixed_point) PNG_UINT_31_MAX ||
|
||||
red_y > (png_fixed_point) PNG_UINT_31_MAX ||
|
||||
green_x > (png_fixed_point) PNG_UINT_31_MAX ||
|
||||
green_y > (png_fixed_point) PNG_UINT_31_MAX ||
|
||||
blue_x > (png_fixed_point) PNG_UINT_31_MAX ||
|
||||
blue_y > (png_fixed_point) PNG_UINT_31_MAX )
|
||||
{
|
||||
png_warning(png_ptr,
|
||||
"Ignoring attempt to set chromaticity value exceeding 21474.83");
|
||||
ret = 0;
|
||||
}
|
||||
if (white_x > 100000L - white_y)
|
||||
{
|
||||
png_warning(png_ptr, "Invalid cHRM white point");
|
||||
ret = 0;
|
||||
}
|
||||
if (red_x > 100000L - red_y)
|
||||
{
|
||||
png_warning(png_ptr, "Invalid cHRM red point");
|
||||
ret = 0;
|
||||
}
|
||||
if (green_x > 100000L - green_y)
|
||||
{
|
||||
png_warning(png_ptr, "Invalid cHRM green point");
|
||||
ret = 0;
|
||||
}
|
||||
if (blue_x > 100000L - blue_y)
|
||||
{
|
||||
png_warning(png_ptr, "Invalid cHRM blue point");
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
png_64bit_product(green_x - red_x, blue_y - red_y, &xy_hi, &xy_lo);
|
||||
png_64bit_product(green_y - red_y, blue_x - red_x, &yx_hi, &yx_lo);
|
||||
|
||||
if (xy_hi == yx_hi && xy_lo == yx_lo)
|
||||
{
|
||||
png_warning(png_ptr,
|
||||
"Ignoring attempt to set cHRM RGB triangle with zero area");
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* PNG_CHECK_cHRM_SUPPORTED */
|
||||
#endif /* PNG_cHRM_SUPPORTED */
|
||||
|
||||
void /* PRIVATE */
|
||||
png_check_IHDR(png_structp png_ptr,
|
||||
png_uint_32 width, png_uint_32 height, int bit_depth,
|
||||
int color_type, int interlace_type, int compression_type,
|
||||
int filter_type)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
/* Check for width and height valid values */
|
||||
if (width == 0)
|
||||
{
|
||||
png_warning(png_ptr, "Image width is zero in IHDR");
|
||||
error = 1;
|
||||
}
|
||||
|
||||
if (height == 0)
|
||||
{
|
||||
png_warning(png_ptr, "Image height is zero in IHDR");
|
||||
error = 1;
|
||||
}
|
||||
|
||||
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
|
||||
if (width > png_ptr->user_width_max || width > PNG_USER_WIDTH_MAX)
|
||||
#else
|
||||
if (width > PNG_USER_WIDTH_MAX)
|
||||
#endif
|
||||
{
|
||||
png_warning(png_ptr, "Image width exceeds user limit in IHDR");
|
||||
error = 1;
|
||||
}
|
||||
|
||||
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
|
||||
if (height > png_ptr->user_height_max || height > PNG_USER_HEIGHT_MAX)
|
||||
#else
|
||||
if (height > PNG_USER_HEIGHT_MAX)
|
||||
#endif
|
||||
{
|
||||
png_warning(png_ptr, "Image height exceeds user limit in IHDR");
|
||||
error = 1;
|
||||
}
|
||||
|
||||
if (width > PNG_UINT_31_MAX)
|
||||
{
|
||||
png_warning(png_ptr, "Invalid image width in IHDR");
|
||||
error = 1;
|
||||
}
|
||||
|
||||
if ( height > PNG_UINT_31_MAX)
|
||||
{
|
||||
png_warning(png_ptr, "Invalid image height in IHDR");
|
||||
error = 1;
|
||||
}
|
||||
|
||||
if ( width > (PNG_UINT_32_MAX
|
||||
>> 3) /* 8-byte RGBA pixels */
|
||||
- 64 /* bigrowbuf hack */
|
||||
- 1 /* filter byte */
|
||||
- 7*8 /* rounding of width to multiple of 8 pixels */
|
||||
- 8) /* extra max_pixel_depth pad */
|
||||
png_warning(png_ptr, "Width is too large for libpng to process pixels");
|
||||
|
||||
/* Check other values */
|
||||
if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
|
||||
bit_depth != 8 && bit_depth != 16)
|
||||
{
|
||||
png_warning(png_ptr, "Invalid bit depth in IHDR");
|
||||
error = 1;
|
||||
}
|
||||
|
||||
if (color_type < 0 || color_type == 1 ||
|
||||
color_type == 5 || color_type > 6)
|
||||
{
|
||||
png_warning(png_ptr, "Invalid color type in IHDR");
|
||||
error = 1;
|
||||
}
|
||||
|
||||
if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
|
||||
((color_type == PNG_COLOR_TYPE_RGB ||
|
||||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
|
||||
color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
|
||||
{
|
||||
png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR");
|
||||
error = 1;
|
||||
}
|
||||
|
||||
if (interlace_type >= PNG_INTERLACE_LAST)
|
||||
{
|
||||
png_warning(png_ptr, "Unknown interlace method in IHDR");
|
||||
error = 1;
|
||||
}
|
||||
|
||||
if (compression_type != PNG_COMPRESSION_TYPE_BASE)
|
||||
{
|
||||
png_warning(png_ptr, "Unknown compression method in IHDR");
|
||||
error = 1;
|
||||
}
|
||||
|
||||
#ifdef PNG_MNG_FEATURES_SUPPORTED
|
||||
/* Accept filter_method 64 (intrapixel differencing) only if
|
||||
* 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
|
||||
* 2. Libpng did not read a PNG signature (this filter_method is only
|
||||
* used in PNG datastreams that are embedded in MNG datastreams) and
|
||||
* 3. The application called png_permit_mng_features with a mask that
|
||||
* included PNG_FLAG_MNG_FILTER_64 and
|
||||
* 4. The filter_method is 64 and
|
||||
* 5. The color_type is RGB or RGBA
|
||||
*/
|
||||
if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) &&
|
||||
png_ptr->mng_features_permitted)
|
||||
png_warning(png_ptr, "MNG features are not allowed in a PNG datastream");
|
||||
|
||||
if (filter_type != PNG_FILTER_TYPE_BASE)
|
||||
{
|
||||
if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
|
||||
(filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&
|
||||
((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) &&
|
||||
(color_type == PNG_COLOR_TYPE_RGB ||
|
||||
color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
|
||||
{
|
||||
png_warning(png_ptr, "Unknown filter method in IHDR");
|
||||
error = 1;
|
||||
}
|
||||
|
||||
if (png_ptr->mode & PNG_HAVE_PNG_SIGNATURE)
|
||||
{
|
||||
png_warning(png_ptr, "Invalid filter method in IHDR");
|
||||
error = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
if (filter_type != PNG_FILTER_TYPE_BASE)
|
||||
{
|
||||
png_warning(png_ptr, "Unknown filter method in IHDR");
|
||||
error = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (error == 1)
|
||||
png_error(png_ptr, "Invalid IHDR data");
|
||||
}
|
||||
#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
|
0
libs/png/png.h → thirdparty/libpng/png.h
vendored
Executable file → Normal file
0
libs/png/png.h → thirdparty/libpng/png.h
vendored
Executable file → Normal file
0
libs/png/pngconf.h → thirdparty/libpng/pngconf.h
vendored
Executable file → Normal file
0
libs/png/pngconf.h → thirdparty/libpng/pngconf.h
vendored
Executable file → Normal file
402
thirdparty/libpng/pngerror.c
vendored
Normal file
402
thirdparty/libpng/pngerror.c
vendored
Normal file
@ -0,0 +1,402 @@
|
||||
|
||||
/* pngerror.c - stub functions for i/o and memory allocation
|
||||
*
|
||||
* Last changed in libpng 1.4.0 [January 3, 2010]
|
||||
* Copyright (c) 1998-2010 Glenn Randers-Pehrson
|
||||
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
|
||||
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*
|
||||
* This file provides a location for all error handling. Users who
|
||||
* need special error handling are expected to write replacement functions
|
||||
* and use png_set_error_fn() to use those functions. See the instructions
|
||||
* at each function.
|
||||
*/
|
||||
|
||||
#define PNG_NO_PEDANTIC_WARNINGS
|
||||
#include "png.h"
|
||||
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
|
||||
#include "pngpriv.h"
|
||||
|
||||
static void /* PRIVATE */
|
||||
png_default_error PNGARG((png_structp png_ptr,
|
||||
png_const_charp error_message)) PNG_NORETURN;
|
||||
#ifdef PNG_WARNINGS_SUPPORTED
|
||||
static void /* PRIVATE */
|
||||
png_default_warning PNGARG((png_structp png_ptr,
|
||||
png_const_charp warning_message));
|
||||
#endif /* PNG_WARNINGS_SUPPORTED */
|
||||
|
||||
/* This function is called whenever there is a fatal error. This function
|
||||
* should not be changed. If there is a need to handle errors differently,
|
||||
* you should supply a replacement error function and use png_set_error_fn()
|
||||
* to replace the error function at run-time.
|
||||
*/
|
||||
#ifdef PNG_ERROR_TEXT_SUPPORTED
|
||||
void PNGAPI
|
||||
png_error(png_structp png_ptr, png_const_charp error_message)
|
||||
{
|
||||
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
|
||||
char msg[16];
|
||||
if (png_ptr != NULL)
|
||||
{
|
||||
if (png_ptr->flags&
|
||||
(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
|
||||
{
|
||||
if (*error_message == PNG_LITERAL_SHARP)
|
||||
{
|
||||
/* Strip "#nnnn " from beginning of error message. */
|
||||
int offset;
|
||||
for (offset = 1; offset<15; offset++)
|
||||
if (error_message[offset] == ' ')
|
||||
break;
|
||||
if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < offset - 1; i++)
|
||||
msg[i] = error_message[i + 1];
|
||||
msg[i - 1] = '\0';
|
||||
error_message = msg;
|
||||
}
|
||||
else
|
||||
error_message += offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
|
||||
{
|
||||
msg[0] = '0';
|
||||
msg[1] = '\0';
|
||||
error_message = msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (png_ptr != NULL && png_ptr->error_fn != NULL)
|
||||
(*(png_ptr->error_fn))(png_ptr, error_message);
|
||||
|
||||
/* If the custom handler doesn't exist, or if it returns,
|
||||
use the default handler, which will not return. */
|
||||
png_default_error(png_ptr, error_message);
|
||||
}
|
||||
#else
|
||||
void PNGAPI
|
||||
png_err(png_structp png_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && png_ptr->error_fn != NULL)
|
||||
(*(png_ptr->error_fn))(png_ptr, '\0');
|
||||
|
||||
/* If the custom handler doesn't exist, or if it returns,
|
||||
use the default handler, which will not return. */
|
||||
png_default_error(png_ptr, '\0');
|
||||
}
|
||||
#endif /* PNG_ERROR_TEXT_SUPPORTED */
|
||||
|
||||
#ifdef PNG_WARNINGS_SUPPORTED
|
||||
/* This function is called whenever there is a non-fatal error. This function
|
||||
* should not be changed. If there is a need to handle warnings differently,
|
||||
* you should supply a replacement warning function and use
|
||||
* png_set_error_fn() to replace the warning function at run-time.
|
||||
*/
|
||||
void PNGAPI
|
||||
png_warning(png_structp png_ptr, png_const_charp warning_message)
|
||||
{
|
||||
int offset = 0;
|
||||
if (png_ptr != NULL)
|
||||
{
|
||||
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
|
||||
if (png_ptr->flags&
|
||||
(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
|
||||
#endif
|
||||
{
|
||||
if (*warning_message == PNG_LITERAL_SHARP)
|
||||
{
|
||||
for (offset = 1; offset < 15; offset++)
|
||||
if (warning_message[offset] == ' ')
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (png_ptr != NULL && png_ptr->warning_fn != NULL)
|
||||
(*(png_ptr->warning_fn))(png_ptr, warning_message + offset);
|
||||
else
|
||||
png_default_warning(png_ptr, warning_message + offset);
|
||||
}
|
||||
#endif /* PNG_WARNINGS_SUPPORTED */
|
||||
|
||||
#ifdef PNG_BENIGN_ERRORS_SUPPORTED
|
||||
void PNGAPI
|
||||
png_benign_error(png_structp png_ptr, png_const_charp error_message)
|
||||
{
|
||||
if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)
|
||||
png_warning(png_ptr, error_message);
|
||||
else
|
||||
png_error(png_ptr, error_message);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* These utilities are used internally to build an error message that relates
|
||||
* to the current chunk. The chunk name comes from png_ptr->chunk_name,
|
||||
* this is used to prefix the message. The message is limited in length
|
||||
* to 63 bytes, the name characters are output as hex digits wrapped in []
|
||||
* if the character is invalid.
|
||||
*/
|
||||
#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
|
||||
static PNG_CONST char png_digit[16] = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||
'A', 'B', 'C', 'D', 'E', 'F'
|
||||
};
|
||||
|
||||
#define PNG_MAX_ERROR_TEXT 64
|
||||
#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED)
|
||||
static void /* PRIVATE */
|
||||
png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
|
||||
error_message)
|
||||
{
|
||||
int iout = 0, iin = 0;
|
||||
|
||||
while (iin < 4)
|
||||
{
|
||||
int c = png_ptr->chunk_name[iin++];
|
||||
if (isnonalpha(c))
|
||||
{
|
||||
buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET;
|
||||
buffer[iout++] = png_digit[(c & 0xf0) >> 4];
|
||||
buffer[iout++] = png_digit[c & 0x0f];
|
||||
buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer[iout++] = (png_byte)c;
|
||||
}
|
||||
}
|
||||
|
||||
if (error_message == NULL)
|
||||
buffer[iout] = '\0';
|
||||
else
|
||||
{
|
||||
buffer[iout++] = ':';
|
||||
buffer[iout++] = ' ';
|
||||
png_memcpy(buffer + iout, error_message, PNG_MAX_ERROR_TEXT);
|
||||
buffer[iout + PNG_MAX_ERROR_TEXT - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PNG_READ_SUPPORTED
|
||||
void PNGAPI
|
||||
png_chunk_error(png_structp png_ptr, png_const_charp error_message)
|
||||
{
|
||||
char msg[18+PNG_MAX_ERROR_TEXT];
|
||||
if (png_ptr == NULL)
|
||||
png_error(png_ptr, error_message);
|
||||
else
|
||||
{
|
||||
png_format_buffer(png_ptr, msg, error_message);
|
||||
png_error(png_ptr, msg);
|
||||
}
|
||||
}
|
||||
#endif /* PNG_READ_SUPPORTED */
|
||||
#endif /* PNG_WARNINGS_SUPPORTED || PNG_ERROR_TEXT_SUPPORTED */
|
||||
|
||||
#ifdef PNG_WARNINGS_SUPPORTED
|
||||
void PNGAPI
|
||||
png_chunk_warning(png_structp png_ptr, png_const_charp warning_message)
|
||||
{
|
||||
char msg[18+PNG_MAX_ERROR_TEXT];
|
||||
if (png_ptr == NULL)
|
||||
png_warning(png_ptr, warning_message);
|
||||
else
|
||||
{
|
||||
png_format_buffer(png_ptr, msg, warning_message);
|
||||
png_warning(png_ptr, msg);
|
||||
}
|
||||
}
|
||||
#endif /* PNG_WARNINGS_SUPPORTED */
|
||||
|
||||
#ifdef PNG_READ_SUPPORTED
|
||||
#ifdef PNG_BENIGN_ERRORS_SUPPORTED
|
||||
void PNGAPI
|
||||
png_chunk_benign_error(png_structp png_ptr, png_const_charp error_message)
|
||||
{
|
||||
if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)
|
||||
png_chunk_warning(png_ptr, error_message);
|
||||
else
|
||||
png_chunk_error(png_ptr, error_message);
|
||||
}
|
||||
#endif
|
||||
#endif /* PNG_READ_SUPPORTED */
|
||||
|
||||
#ifdef PNG_SETJMP_SUPPORTED
|
||||
/* This API only exists if ANSI-C style error handling is used,
|
||||
* otherwise it is necessary for png_default_error to be overridden.
|
||||
*/
|
||||
jmp_buf* PNGAPI
|
||||
png_set_longjmp_fn(png_structp png_ptr, png_longjmp_ptr longjmp_fn,
|
||||
size_t jmp_buf_size)
|
||||
{
|
||||
if (png_ptr == NULL || jmp_buf_size != png_sizeof(jmp_buf))
|
||||
return NULL;
|
||||
|
||||
png_ptr->longjmp_fn = longjmp_fn;
|
||||
return &png_ptr->jmpbuf;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This is the default error handling function. Note that replacements for
|
||||
* this function MUST NOT RETURN, or the program will likely crash. This
|
||||
* function is used by default, or if the program supplies NULL for the
|
||||
* error function pointer in png_set_error_fn().
|
||||
*/
|
||||
static void /* PRIVATE */
|
||||
png_default_error(png_structp png_ptr, png_const_charp error_message)
|
||||
{
|
||||
#ifdef PNG_CONSOLE_IO_SUPPORTED
|
||||
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
|
||||
if (*error_message == PNG_LITERAL_SHARP)
|
||||
{
|
||||
/* Strip "#nnnn " from beginning of error message. */
|
||||
int offset;
|
||||
char error_number[16];
|
||||
for (offset = 0; offset<15; offset++)
|
||||
{
|
||||
error_number[offset] = error_message[offset + 1];
|
||||
if (error_message[offset] == ' ')
|
||||
break;
|
||||
}
|
||||
if ((offset > 1) && (offset < 15))
|
||||
{
|
||||
error_number[offset - 1] = '\0';
|
||||
fprintf(stderr, "libpng error no. %s: %s",
|
||||
error_number, error_message + offset + 1);
|
||||
fprintf(stderr, PNG_STRING_NEWLINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "libpng error: %s, offset=%d",
|
||||
error_message, offset);
|
||||
fprintf(stderr, PNG_STRING_NEWLINE);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
fprintf(stderr, "libpng error: %s", error_message);
|
||||
fprintf(stderr, PNG_STRING_NEWLINE);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_SETJMP_SUPPORTED
|
||||
if (png_ptr && png_ptr->longjmp_fn)
|
||||
{
|
||||
# ifdef USE_FAR_KEYWORD
|
||||
{
|
||||
jmp_buf jmpbuf;
|
||||
png_memcpy(jmpbuf, png_ptr->jmpbuf, png_sizeof(jmp_buf));
|
||||
png_ptr->longjmp_fn(jmpbuf, 1);
|
||||
}
|
||||
# else
|
||||
png_ptr->longjmp_fn(png_ptr->jmpbuf, 1);
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
/* Here if not setjmp support or if png_ptr is null. */
|
||||
PNG_ABORT();
|
||||
#ifndef PNG_CONSOLE_IO_SUPPORTED
|
||||
error_message = error_message; /* Make compiler happy */
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef PNG_WARNINGS_SUPPORTED
|
||||
/* This function is called when there is a warning, but the library thinks
|
||||
* it can continue anyway. Replacement functions don't have to do anything
|
||||
* here if you don't want them to. In the default configuration, png_ptr is
|
||||
* not used, but it is passed in case it may be useful.
|
||||
*/
|
||||
static void /* PRIVATE */
|
||||
png_default_warning(png_structp png_ptr, png_const_charp warning_message)
|
||||
{
|
||||
#ifdef PNG_CONSOLE_IO_SUPPORTED
|
||||
# ifdef PNG_ERROR_NUMBERS_SUPPORTED
|
||||
if (*warning_message == PNG_LITERAL_SHARP)
|
||||
{
|
||||
int offset;
|
||||
char warning_number[16];
|
||||
for (offset = 0; offset < 15; offset++)
|
||||
{
|
||||
warning_number[offset] = warning_message[offset + 1];
|
||||
if (warning_message[offset] == ' ')
|
||||
break;
|
||||
}
|
||||
if ((offset > 1) && (offset < 15))
|
||||
{
|
||||
warning_number[offset + 1] = '\0';
|
||||
fprintf(stderr, "libpng warning no. %s: %s",
|
||||
warning_number, warning_message + offset);
|
||||
fprintf(stderr, PNG_STRING_NEWLINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "libpng warning: %s",
|
||||
warning_message);
|
||||
fprintf(stderr, PNG_STRING_NEWLINE);
|
||||
}
|
||||
}
|
||||
else
|
||||
# endif
|
||||
{
|
||||
fprintf(stderr, "libpng warning: %s", warning_message);
|
||||
fprintf(stderr, PNG_STRING_NEWLINE);
|
||||
}
|
||||
#else
|
||||
warning_message = warning_message; /* Make compiler happy */
|
||||
#endif
|
||||
png_ptr = png_ptr; /* Make compiler happy */
|
||||
}
|
||||
#endif /* PNG_WARNINGS_SUPPORTED */
|
||||
|
||||
/* This function is called when the application wants to use another method
|
||||
* of handling errors and warnings. Note that the error function MUST NOT
|
||||
* return to the calling routine or serious problems will occur. The return
|
||||
* method used in the default routine calls longjmp(png_ptr->jmpbuf, 1)
|
||||
*/
|
||||
void PNGAPI
|
||||
png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
|
||||
png_error_ptr error_fn, png_error_ptr warning_fn)
|
||||
{
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
png_ptr->error_ptr = error_ptr;
|
||||
png_ptr->error_fn = error_fn;
|
||||
png_ptr->warning_fn = warning_fn;
|
||||
}
|
||||
|
||||
|
||||
/* This function returns a pointer to the error_ptr associated with the user
|
||||
* functions. The application should free any memory associated with this
|
||||
* pointer before png_write_destroy and png_read_destroy are called.
|
||||
*/
|
||||
png_voidp PNGAPI
|
||||
png_get_error_ptr(png_structp png_ptr)
|
||||
{
|
||||
if (png_ptr == NULL)
|
||||
return NULL;
|
||||
return ((png_voidp)png_ptr->error_ptr);
|
||||
}
|
||||
|
||||
|
||||
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
|
||||
void PNGAPI
|
||||
png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode)
|
||||
{
|
||||
if (png_ptr != NULL)
|
||||
{
|
||||
png_ptr->flags &=
|
||||
((~(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
|
925
thirdparty/libpng/pngget.c
vendored
Normal file
925
thirdparty/libpng/pngget.c
vendored
Normal file
@ -0,0 +1,925 @@
|
||||
|
||||
/* pngget.c - retrieval of values from info struct
|
||||
*
|
||||
* Last changed in libpng 1.4.2 [May 6, 2010]
|
||||
* Copyright (c) 1998-2010 Glenn Randers-Pehrson
|
||||
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
|
||||
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*
|
||||
*/
|
||||
|
||||
#define PNG_NO_PEDANTIC_WARNINGS
|
||||
#include "png.h"
|
||||
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
|
||||
#include "pngpriv.h"
|
||||
|
||||
png_uint_32 PNGAPI
|
||||
png_get_valid(png_structp png_ptr, png_infop info_ptr, png_uint_32 flag)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
return(info_ptr->valid & flag);
|
||||
|
||||
else
|
||||
return(0);
|
||||
}
|
||||
|
||||
png_size_t PNGAPI
|
||||
png_get_rowbytes(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
return(info_ptr->rowbytes);
|
||||
|
||||
else
|
||||
return(0);
|
||||
}
|
||||
|
||||
#ifdef PNG_INFO_IMAGE_SUPPORTED
|
||||
png_bytepp PNGAPI
|
||||
png_get_rows(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
return(info_ptr->row_pointers);
|
||||
|
||||
else
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_EASY_ACCESS_SUPPORTED
|
||||
/* Easy access to info, added in libpng-0.99 */
|
||||
png_uint_32 PNGAPI
|
||||
png_get_image_width(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
return info_ptr->width;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_uint_32 PNGAPI
|
||||
png_get_image_height(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
return info_ptr->height;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_byte PNGAPI
|
||||
png_get_bit_depth(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
return info_ptr->bit_depth;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_byte PNGAPI
|
||||
png_get_color_type(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
return info_ptr->color_type;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_byte PNGAPI
|
||||
png_get_filter_type(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
return info_ptr->filter_type;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_byte PNGAPI
|
||||
png_get_interlace_type(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
return info_ptr->interlace_type;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_byte PNGAPI
|
||||
png_get_compression_type(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
return info_ptr->compression_type;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_uint_32 PNGAPI
|
||||
png_get_x_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
#ifdef PNG_pHYs_SUPPORTED
|
||||
if (info_ptr->valid & PNG_INFO_pHYs)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function", "png_get_x_pixels_per_meter");
|
||||
|
||||
if (info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
|
||||
return (0);
|
||||
|
||||
else
|
||||
return (info_ptr->x_pixels_per_unit);
|
||||
}
|
||||
#else
|
||||
return (0);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_uint_32 PNGAPI
|
||||
png_get_y_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
#ifdef PNG_pHYs_SUPPORTED
|
||||
if (info_ptr->valid & PNG_INFO_pHYs)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function", "png_get_y_pixels_per_meter");
|
||||
|
||||
if (info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
|
||||
return (0);
|
||||
|
||||
else
|
||||
return (info_ptr->y_pixels_per_unit);
|
||||
}
|
||||
#else
|
||||
return (0);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_uint_32 PNGAPI
|
||||
png_get_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
#ifdef PNG_pHYs_SUPPORTED
|
||||
if (info_ptr->valid & PNG_INFO_pHYs)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function", "png_get_pixels_per_meter");
|
||||
|
||||
if (info_ptr->phys_unit_type != PNG_RESOLUTION_METER ||
|
||||
info_ptr->x_pixels_per_unit != info_ptr->y_pixels_per_unit)
|
||||
return (0);
|
||||
|
||||
else
|
||||
return (info_ptr->x_pixels_per_unit);
|
||||
}
|
||||
#else
|
||||
return (0);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef PNG_FLOATING_POINT_SUPPORTED
|
||||
float PNGAPI
|
||||
png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
#ifdef PNG_pHYs_SUPPORTED
|
||||
|
||||
if (info_ptr->valid & PNG_INFO_pHYs)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio");
|
||||
|
||||
if (info_ptr->x_pixels_per_unit == 0)
|
||||
return ((float)0.0);
|
||||
|
||||
else
|
||||
return ((float)((float)info_ptr->y_pixels_per_unit
|
||||
/(float)info_ptr->x_pixels_per_unit));
|
||||
}
|
||||
#else
|
||||
return (0.0);
|
||||
#endif
|
||||
return ((float)0.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
png_int_32 PNGAPI
|
||||
png_get_x_offset_microns(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
#ifdef PNG_oFFs_SUPPORTED
|
||||
|
||||
if (info_ptr->valid & PNG_INFO_oFFs)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns");
|
||||
|
||||
if (info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
|
||||
return (0);
|
||||
|
||||
else
|
||||
return (info_ptr->x_offset);
|
||||
}
|
||||
#else
|
||||
return (0);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_int_32 PNGAPI
|
||||
png_get_y_offset_microns(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
|
||||
#ifdef PNG_oFFs_SUPPORTED
|
||||
if (info_ptr->valid & PNG_INFO_oFFs)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns");
|
||||
|
||||
if (info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
|
||||
return (0);
|
||||
|
||||
else
|
||||
return (info_ptr->y_offset);
|
||||
}
|
||||
#else
|
||||
return (0);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_int_32 PNGAPI
|
||||
png_get_x_offset_pixels(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
|
||||
#ifdef PNG_oFFs_SUPPORTED
|
||||
if (info_ptr->valid & PNG_INFO_oFFs)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns");
|
||||
|
||||
if (info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
|
||||
return (0);
|
||||
|
||||
else
|
||||
return (info_ptr->x_offset);
|
||||
}
|
||||
#else
|
||||
return (0);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_int_32 PNGAPI
|
||||
png_get_y_offset_pixels(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
|
||||
#ifdef PNG_oFFs_SUPPORTED
|
||||
if (info_ptr->valid & PNG_INFO_oFFs)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns");
|
||||
|
||||
if (info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
|
||||
return (0);
|
||||
|
||||
else
|
||||
return (info_ptr->y_offset);
|
||||
}
|
||||
#else
|
||||
return (0);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED)
|
||||
png_uint_32 PNGAPI
|
||||
png_get_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
return ((png_uint_32)((float)png_get_pixels_per_meter(png_ptr, info_ptr)
|
||||
*.0254 +.5));
|
||||
}
|
||||
|
||||
png_uint_32 PNGAPI
|
||||
png_get_x_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
return ((png_uint_32)((float)png_get_x_pixels_per_meter(png_ptr, info_ptr)
|
||||
*.0254 +.5));
|
||||
}
|
||||
|
||||
png_uint_32 PNGAPI
|
||||
png_get_y_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
return ((png_uint_32)((float)png_get_y_pixels_per_meter(png_ptr, info_ptr)
|
||||
*.0254 +.5));
|
||||
}
|
||||
|
||||
float PNGAPI
|
||||
png_get_x_offset_inches(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
return ((float)png_get_x_offset_microns(png_ptr, info_ptr)
|
||||
*.00003937);
|
||||
}
|
||||
|
||||
float PNGAPI
|
||||
png_get_y_offset_inches(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
return ((float)png_get_y_offset_microns(png_ptr, info_ptr)
|
||||
*.00003937);
|
||||
}
|
||||
|
||||
#ifdef PNG_pHYs_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_pHYs_dpi(png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
|
||||
{
|
||||
png_uint_32 retval = 0;
|
||||
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function", "pHYs");
|
||||
|
||||
if (res_x != NULL)
|
||||
{
|
||||
*res_x = info_ptr->x_pixels_per_unit;
|
||||
retval |= PNG_INFO_pHYs;
|
||||
}
|
||||
if (res_y != NULL)
|
||||
{
|
||||
*res_y = info_ptr->y_pixels_per_unit;
|
||||
retval |= PNG_INFO_pHYs;
|
||||
}
|
||||
if (unit_type != NULL)
|
||||
{
|
||||
*unit_type = (int)info_ptr->phys_unit_type;
|
||||
retval |= PNG_INFO_pHYs;
|
||||
if (*unit_type == 1)
|
||||
{
|
||||
if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50);
|
||||
if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (retval);
|
||||
}
|
||||
#endif /* PNG_pHYs_SUPPORTED */
|
||||
#endif /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */
|
||||
|
||||
/* png_get_channels really belongs in here, too, but it's been around longer */
|
||||
|
||||
#endif /* PNG_EASY_ACCESS_SUPPORTED */
|
||||
|
||||
png_byte PNGAPI
|
||||
png_get_channels(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
return(info_ptr->channels);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_bytep PNGAPI
|
||||
png_get_signature(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
return(info_ptr->signature);
|
||||
else
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
#ifdef PNG_bKGD_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_bKGD(png_structp png_ptr, png_infop info_ptr,
|
||||
png_color_16p *background)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)
|
||||
&& background != NULL)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function", "bKGD");
|
||||
|
||||
*background = &(info_ptr->background);
|
||||
return (PNG_INFO_bKGD);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_cHRM_SUPPORTED
|
||||
#ifdef PNG_FLOATING_POINT_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_cHRM(png_structp png_ptr, png_infop info_ptr,
|
||||
double *white_x, double *white_y, double *red_x, double *red_y,
|
||||
double *green_x, double *green_y, double *blue_x, double *blue_y)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function", "cHRM");
|
||||
|
||||
if (white_x != NULL)
|
||||
*white_x = (double)info_ptr->x_white;
|
||||
if (white_y != NULL)
|
||||
*white_y = (double)info_ptr->y_white;
|
||||
if (red_x != NULL)
|
||||
*red_x = (double)info_ptr->x_red;
|
||||
if (red_y != NULL)
|
||||
*red_y = (double)info_ptr->y_red;
|
||||
if (green_x != NULL)
|
||||
*green_x = (double)info_ptr->x_green;
|
||||
if (green_y != NULL)
|
||||
*green_y = (double)info_ptr->y_green;
|
||||
if (blue_x != NULL)
|
||||
*blue_x = (double)info_ptr->x_blue;
|
||||
if (blue_y != NULL)
|
||||
*blue_y = (double)info_ptr->y_blue;
|
||||
return (PNG_INFO_cHRM);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
#ifdef PNG_FIXED_POINT_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
|
||||
png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x,
|
||||
png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y,
|
||||
png_fixed_point *blue_x, png_fixed_point *blue_y)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function", "cHRM");
|
||||
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
|
||||
{
|
||||
if (white_x != NULL)
|
||||
*white_x = info_ptr->int_x_white;
|
||||
if (white_y != NULL)
|
||||
*white_y = info_ptr->int_y_white;
|
||||
if (red_x != NULL)
|
||||
*red_x = info_ptr->int_x_red;
|
||||
if (red_y != NULL)
|
||||
*red_y = info_ptr->int_y_red;
|
||||
if (green_x != NULL)
|
||||
*green_x = info_ptr->int_x_green;
|
||||
if (green_y != NULL)
|
||||
*green_y = info_ptr->int_y_green;
|
||||
if (blue_x != NULL)
|
||||
*blue_x = info_ptr->int_x_blue;
|
||||
if (blue_y != NULL)
|
||||
*blue_y = info_ptr->int_y_blue;
|
||||
return (PNG_INFO_cHRM);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef PNG_gAMA_SUPPORTED
|
||||
#ifdef PNG_FLOATING_POINT_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_gAMA(png_structp png_ptr, png_infop info_ptr, double *file_gamma)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function", "gAMA");
|
||||
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
|
||||
&& file_gamma != NULL)
|
||||
{
|
||||
*file_gamma = (double)info_ptr->gamma;
|
||||
return (PNG_INFO_gAMA);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
#ifdef PNG_FIXED_POINT_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_gAMA_fixed(png_structp png_ptr, png_infop info_ptr,
|
||||
png_fixed_point *int_file_gamma)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function", "gAMA");
|
||||
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
|
||||
&& int_file_gamma != NULL)
|
||||
{
|
||||
*int_file_gamma = info_ptr->int_gamma;
|
||||
return (PNG_INFO_gAMA);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef PNG_sRGB_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_sRGB(png_structp png_ptr, png_infop info_ptr, int *file_srgb_intent)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function", "sRGB");
|
||||
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)
|
||||
&& file_srgb_intent != NULL)
|
||||
{
|
||||
*file_srgb_intent = (int)info_ptr->srgb_intent;
|
||||
return (PNG_INFO_sRGB);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_iCCP_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_iCCP(png_structp png_ptr, png_infop info_ptr,
|
||||
png_charpp name, int *compression_type,
|
||||
png_charpp profile, png_uint_32 *proflen)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function", "iCCP");
|
||||
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)
|
||||
&& name != NULL && profile != NULL && proflen != NULL)
|
||||
{
|
||||
*name = info_ptr->iccp_name;
|
||||
*profile = info_ptr->iccp_profile;
|
||||
/* Compression_type is a dummy so the API won't have to change
|
||||
* if we introduce multiple compression types later.
|
||||
*/
|
||||
*proflen = (int)info_ptr->iccp_proflen;
|
||||
*compression_type = (int)info_ptr->iccp_compression;
|
||||
return (PNG_INFO_iCCP);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_sPLT_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_sPLT(png_structp png_ptr, png_infop info_ptr,
|
||||
png_sPLT_tpp spalettes)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)
|
||||
{
|
||||
*spalettes = info_ptr->splt_palettes;
|
||||
return ((png_uint_32)info_ptr->splt_palettes_num);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_hIST_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p *hist)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function", "hIST");
|
||||
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)
|
||||
&& hist != NULL)
|
||||
{
|
||||
*hist = info_ptr->hist;
|
||||
return (PNG_INFO_hIST);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
png_uint_32 PNGAPI
|
||||
png_get_IHDR(png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 *width, png_uint_32 *height, int *bit_depth,
|
||||
int *color_type, int *interlace_type, int *compression_type,
|
||||
int *filter_type)
|
||||
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function", "IHDR");
|
||||
|
||||
if (png_ptr == NULL || info_ptr == NULL || width == NULL ||
|
||||
height == NULL || bit_depth == NULL || color_type == NULL)
|
||||
return (0);
|
||||
|
||||
*width = info_ptr->width;
|
||||
*height = info_ptr->height;
|
||||
*bit_depth = info_ptr->bit_depth;
|
||||
*color_type = info_ptr->color_type;
|
||||
|
||||
if (compression_type != NULL)
|
||||
*compression_type = info_ptr->compression_type;
|
||||
|
||||
if (filter_type != NULL)
|
||||
*filter_type = info_ptr->filter_type;
|
||||
|
||||
if (interlace_type != NULL)
|
||||
*interlace_type = info_ptr->interlace_type;
|
||||
|
||||
/* This is redundant if we can be sure that the info_ptr values were all
|
||||
* assigned in png_set_IHDR(). We do the check anyhow in case an
|
||||
* application has ignored our advice not to mess with the members
|
||||
* of info_ptr directly.
|
||||
*/
|
||||
png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height,
|
||||
info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
|
||||
info_ptr->compression_type, info_ptr->filter_type);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
#ifdef PNG_oFFs_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_oFFs(png_structp png_ptr, png_infop info_ptr,
|
||||
png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function", "oFFs");
|
||||
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)
|
||||
&& offset_x != NULL && offset_y != NULL && unit_type != NULL)
|
||||
{
|
||||
*offset_x = info_ptr->x_offset;
|
||||
*offset_y = info_ptr->y_offset;
|
||||
*unit_type = (int)info_ptr->offset_unit_type;
|
||||
return (PNG_INFO_oFFs);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_pCAL_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_pCAL(png_structp png_ptr, png_infop info_ptr,
|
||||
png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,
|
||||
png_charp *units, png_charpp *params)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function", "pCAL");
|
||||
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)
|
||||
&& purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
|
||||
nparams != NULL && units != NULL && params != NULL)
|
||||
{
|
||||
*purpose = info_ptr->pcal_purpose;
|
||||
*X0 = info_ptr->pcal_X0;
|
||||
*X1 = info_ptr->pcal_X1;
|
||||
*type = (int)info_ptr->pcal_type;
|
||||
*nparams = (int)info_ptr->pcal_nparams;
|
||||
*units = info_ptr->pcal_units;
|
||||
*params = info_ptr->pcal_params;
|
||||
return (PNG_INFO_pCAL);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_sCAL_SUPPORTED
|
||||
#ifdef PNG_FLOATING_POINT_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_sCAL(png_structp png_ptr, png_infop info_ptr,
|
||||
int *unit, double *width, double *height)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL &&
|
||||
(info_ptr->valid & PNG_INFO_sCAL))
|
||||
{
|
||||
*unit = info_ptr->scal_unit;
|
||||
*width = info_ptr->scal_pixel_width;
|
||||
*height = info_ptr->scal_pixel_height;
|
||||
return (PNG_INFO_sCAL);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
#else
|
||||
#ifdef PNG_FIXED_POINT_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_sCAL_s(png_structp png_ptr, png_infop info_ptr,
|
||||
int *unit, png_charpp width, png_charpp height)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL &&
|
||||
(info_ptr->valid & PNG_INFO_sCAL))
|
||||
{
|
||||
*unit = info_ptr->scal_unit;
|
||||
*width = info_ptr->scal_s_width;
|
||||
*height = info_ptr->scal_s_height;
|
||||
return (PNG_INFO_sCAL);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef PNG_pHYs_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_pHYs(png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
|
||||
{
|
||||
png_uint_32 retval = 0;
|
||||
|
||||
png_debug1(1, "in %s retrieval function", "pHYs");
|
||||
|
||||
if (png_ptr != NULL && info_ptr != NULL &&
|
||||
(info_ptr->valid & PNG_INFO_pHYs))
|
||||
{
|
||||
if (res_x != NULL)
|
||||
{
|
||||
*res_x = info_ptr->x_pixels_per_unit;
|
||||
retval |= PNG_INFO_pHYs;
|
||||
}
|
||||
|
||||
if (res_y != NULL)
|
||||
{
|
||||
*res_y = info_ptr->y_pixels_per_unit;
|
||||
retval |= PNG_INFO_pHYs;
|
||||
}
|
||||
|
||||
if (unit_type != NULL)
|
||||
{
|
||||
*unit_type = (int)info_ptr->phys_unit_type;
|
||||
retval |= PNG_INFO_pHYs;
|
||||
}
|
||||
}
|
||||
return (retval);
|
||||
}
|
||||
#endif
|
||||
|
||||
png_uint_32 PNGAPI
|
||||
png_get_PLTE(png_structp png_ptr, png_infop info_ptr, png_colorp *palette,
|
||||
int *num_palette)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function", "PLTE");
|
||||
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_PLTE)
|
||||
&& palette != NULL)
|
||||
{
|
||||
*palette = info_ptr->palette;
|
||||
*num_palette = info_ptr->num_palette;
|
||||
png_debug1(3, "num_palette = %d", *num_palette);
|
||||
return (PNG_INFO_PLTE);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef PNG_sBIT_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function", "sBIT");
|
||||
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)
|
||||
&& sig_bit != NULL)
|
||||
{
|
||||
*sig_bit = &(info_ptr->sig_bit);
|
||||
return (PNG_INFO_sBIT);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_TEXT_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_text(png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr,
|
||||
int *num_text)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function",
|
||||
(png_ptr->chunk_name[0] == '\0' ? "text"
|
||||
: (png_const_charp)png_ptr->chunk_name));
|
||||
|
||||
if (text_ptr != NULL)
|
||||
*text_ptr = info_ptr->text;
|
||||
|
||||
if (num_text != NULL)
|
||||
*num_text = info_ptr->num_text;
|
||||
|
||||
return ((png_uint_32)info_ptr->num_text);
|
||||
}
|
||||
if (num_text != NULL)
|
||||
*num_text = 0;
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_tIME_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_tIME(png_structp png_ptr, png_infop info_ptr, png_timep *mod_time)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function", "tIME");
|
||||
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)
|
||||
&& mod_time != NULL)
|
||||
{
|
||||
*mod_time = &(info_ptr->mod_time);
|
||||
return (PNG_INFO_tIME);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_tRNS_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_tRNS(png_structp png_ptr, png_infop info_ptr,
|
||||
png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color)
|
||||
{
|
||||
png_uint_32 retval = 0;
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function", "tRNS");
|
||||
|
||||
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
|
||||
{
|
||||
if (trans_alpha != NULL)
|
||||
{
|
||||
*trans_alpha = info_ptr->trans_alpha;
|
||||
retval |= PNG_INFO_tRNS;
|
||||
}
|
||||
|
||||
if (trans_color != NULL)
|
||||
*trans_color = &(info_ptr->trans_color);
|
||||
}
|
||||
else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */
|
||||
{
|
||||
if (trans_color != NULL)
|
||||
{
|
||||
*trans_color = &(info_ptr->trans_color);
|
||||
retval |= PNG_INFO_tRNS;
|
||||
}
|
||||
|
||||
if (trans_alpha != NULL)
|
||||
*trans_alpha = NULL;
|
||||
}
|
||||
if (num_trans != NULL)
|
||||
{
|
||||
*num_trans = info_ptr->num_trans;
|
||||
retval |= PNG_INFO_tRNS;
|
||||
}
|
||||
}
|
||||
return (retval);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_unknown_chunks(png_structp png_ptr, png_infop info_ptr,
|
||||
png_unknown_chunkpp unknowns)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL)
|
||||
{
|
||||
*unknowns = info_ptr->unknown_chunks;
|
||||
return ((png_uint_32)info_ptr->unknown_chunks_num);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
|
||||
png_byte PNGAPI
|
||||
png_get_rgb_to_gray_status (png_structp png_ptr)
|
||||
{
|
||||
return (png_byte)(png_ptr? png_ptr->rgb_to_gray_status : 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_USER_CHUNKS_SUPPORTED
|
||||
png_voidp PNGAPI
|
||||
png_get_user_chunk_ptr(png_structp png_ptr)
|
||||
{
|
||||
return (png_ptr? png_ptr->user_chunk_ptr : NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
png_size_t PNGAPI
|
||||
png_get_compression_buffer_size(png_structp png_ptr)
|
||||
{
|
||||
return (png_ptr ? png_ptr->zbuf_size : 0L);
|
||||
}
|
||||
|
||||
|
||||
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
|
||||
/* These functions were added to libpng 1.2.6 and were enabled
|
||||
* by default in libpng-1.4.0 */
|
||||
png_uint_32 PNGAPI
|
||||
png_get_user_width_max (png_structp png_ptr)
|
||||
{
|
||||
return (png_ptr? png_ptr->user_width_max : 0);
|
||||
}
|
||||
png_uint_32 PNGAPI
|
||||
png_get_user_height_max (png_structp png_ptr)
|
||||
{
|
||||
return (png_ptr? png_ptr->user_height_max : 0);
|
||||
}
|
||||
/* This function was added to libpng 1.4.0 */
|
||||
png_uint_32 PNGAPI
|
||||
png_get_chunk_cache_max (png_structp png_ptr)
|
||||
{
|
||||
return (png_ptr? png_ptr->user_chunk_cache_max : 0);
|
||||
}
|
||||
/* This function was added to libpng 1.4.1 */
|
||||
png_alloc_size_t PNGAPI
|
||||
png_get_chunk_malloc_max (png_structp png_ptr)
|
||||
{
|
||||
return (png_ptr?
|
||||
png_ptr->user_chunk_malloc_max : 0);
|
||||
}
|
||||
#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
|
||||
|
||||
/* These functions were added to libpng 1.4.0 */
|
||||
#ifdef PNG_IO_STATE_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_io_state (png_structp png_ptr)
|
||||
{
|
||||
return png_ptr->io_state;
|
||||
}
|
||||
|
||||
png_bytep PNGAPI
|
||||
png_get_io_chunk_name (png_structp png_ptr)
|
||||
{
|
||||
return png_ptr->chunk_name;
|
||||
}
|
||||
#endif /* ?PNG_IO_STATE_SUPPORTED */
|
||||
|
||||
#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
|
611
thirdparty/libpng/pngmem.c
vendored
Normal file
611
thirdparty/libpng/pngmem.c
vendored
Normal file
@ -0,0 +1,611 @@
|
||||
|
||||
/* pngmem.c - stub functions for memory allocation
|
||||
*
|
||||
* Last changed in libpng 1.4.2 [May 6, 2010]
|
||||
* Copyright (c) 1998-2010 Glenn Randers-Pehrson
|
||||
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
|
||||
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*
|
||||
* This file provides a location for all memory allocation. Users who
|
||||
* need special memory handling are expected to supply replacement
|
||||
* functions for png_malloc() and png_free(), and to use
|
||||
* png_create_read_struct_2() and png_create_write_struct_2() to
|
||||
* identify the replacement functions.
|
||||
*/
|
||||
|
||||
#define PNG_NO_PEDANTIC_WARNINGS
|
||||
#include "png.h"
|
||||
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
|
||||
#include "pngpriv.h"
|
||||
|
||||
/* Borland DOS special memory handler */
|
||||
#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
|
||||
/* If you change this, be sure to change the one in png.h also */
|
||||
|
||||
/* Allocate memory for a png_struct. The malloc and memset can be replaced
|
||||
by a single call to calloc() if this is thought to improve performance. */
|
||||
png_voidp /* PRIVATE */
|
||||
png_create_struct(int type)
|
||||
{
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
return (png_create_struct_2(type, NULL, NULL));
|
||||
}
|
||||
|
||||
/* Alternate version of png_create_struct, for use with user-defined malloc. */
|
||||
png_voidp /* PRIVATE */
|
||||
png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
|
||||
{
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
||||
png_size_t size;
|
||||
png_voidp struct_ptr;
|
||||
|
||||
if (type == PNG_STRUCT_INFO)
|
||||
size = png_sizeof(png_info);
|
||||
else if (type == PNG_STRUCT_PNG)
|
||||
size = png_sizeof(png_struct);
|
||||
else
|
||||
return (png_get_copyright(NULL));
|
||||
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
if (malloc_fn != NULL)
|
||||
{
|
||||
png_struct dummy_struct;
|
||||
png_structp png_ptr = &dummy_struct;
|
||||
png_ptr->mem_ptr=mem_ptr;
|
||||
struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size);
|
||||
}
|
||||
else
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
||||
struct_ptr = (png_voidp)farmalloc(size);
|
||||
if (struct_ptr != NULL)
|
||||
png_memset(struct_ptr, 0, size);
|
||||
return (struct_ptr);
|
||||
}
|
||||
|
||||
/* Free memory allocated by a png_create_struct() call */
|
||||
void /* PRIVATE */
|
||||
png_destroy_struct(png_voidp struct_ptr)
|
||||
{
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
png_destroy_struct_2(struct_ptr, NULL, NULL);
|
||||
}
|
||||
|
||||
/* Free memory allocated by a png_create_struct() call */
|
||||
void /* PRIVATE */
|
||||
png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
|
||||
png_voidp mem_ptr)
|
||||
{
|
||||
#endif
|
||||
if (struct_ptr != NULL)
|
||||
{
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
if (free_fn != NULL)
|
||||
{
|
||||
png_struct dummy_struct;
|
||||
png_structp png_ptr = &dummy_struct;
|
||||
png_ptr->mem_ptr=mem_ptr;
|
||||
(*(free_fn))(png_ptr, struct_ptr);
|
||||
return;
|
||||
}
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
||||
farfree (struct_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate memory. For reasonable files, size should never exceed
|
||||
* 64K. However, zlib may allocate more then 64K if you don't tell
|
||||
* it not to. See zconf.h and png.h for more information. zlib does
|
||||
* need to allocate exactly 64K, so whatever you call here must
|
||||
* have the ability to do that.
|
||||
*
|
||||
* Borland seems to have a problem in DOS mode for exactly 64K.
|
||||
* It gives you a segment with an offset of 8 (perhaps to store its
|
||||
* memory stuff). zlib doesn't like this at all, so we have to
|
||||
* detect and deal with it. This code should not be needed in
|
||||
* Windows or OS/2 modes, and only in 16 bit mode. This code has
|
||||
* been updated by Alexander Lehmann for version 0.89 to waste less
|
||||
* memory.
|
||||
*
|
||||
* Note that we can't use png_size_t for the "size" declaration,
|
||||
* since on some systems a png_size_t is a 16-bit quantity, and as a
|
||||
* result, we would be truncating potentially larger memory requests
|
||||
* (which should cause a fatal error) and introducing major problems.
|
||||
*/
|
||||
png_voidp PNGAPI
|
||||
png_calloc(png_structp png_ptr, png_alloc_size_t size)
|
||||
{
|
||||
png_voidp ret;
|
||||
|
||||
ret = (png_malloc(png_ptr, size));
|
||||
if (ret != NULL)
|
||||
png_memset(ret,0,(png_size_t)size);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
png_voidp PNGAPI
|
||||
png_malloc(png_structp png_ptr, png_alloc_size_t size)
|
||||
{
|
||||
png_voidp ret;
|
||||
|
||||
if (png_ptr == NULL || size == 0)
|
||||
return (NULL);
|
||||
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
if (png_ptr->malloc_fn != NULL)
|
||||
ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
|
||||
else
|
||||
ret = (png_malloc_default(png_ptr, size));
|
||||
if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
|
||||
png_error(png_ptr, "Out of memory");
|
||||
return (ret);
|
||||
}
|
||||
|
||||
png_voidp PNGAPI
|
||||
png_malloc_default(png_structp png_ptr, png_alloc_size_t size)
|
||||
{
|
||||
png_voidp ret;
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
||||
|
||||
if (png_ptr == NULL || size == 0)
|
||||
return (NULL);
|
||||
|
||||
#ifdef PNG_MAX_MALLOC_64K
|
||||
if (size > (png_uint_32)65536L)
|
||||
{
|
||||
png_warning(png_ptr, "Cannot Allocate > 64K");
|
||||
ret = NULL;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
if (size != (size_t)size)
|
||||
ret = NULL;
|
||||
else if (size == (png_uint_32)65536L)
|
||||
{
|
||||
if (png_ptr->offset_table == NULL)
|
||||
{
|
||||
/* Try to see if we need to do any of this fancy stuff */
|
||||
ret = farmalloc(size);
|
||||
if (ret == NULL || ((png_size_t)ret & 0xffff))
|
||||
{
|
||||
int num_blocks;
|
||||
png_uint_32 total_size;
|
||||
png_bytep table;
|
||||
int i;
|
||||
png_byte huge * hptr;
|
||||
|
||||
if (ret != NULL)
|
||||
{
|
||||
farfree(ret);
|
||||
ret = NULL;
|
||||
}
|
||||
|
||||
if (png_ptr->zlib_window_bits > 14)
|
||||
num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
|
||||
else
|
||||
num_blocks = 1;
|
||||
if (png_ptr->zlib_mem_level >= 7)
|
||||
num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
|
||||
else
|
||||
num_blocks++;
|
||||
|
||||
total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
|
||||
|
||||
table = farmalloc(total_size);
|
||||
|
||||
if (table == NULL)
|
||||
{
|
||||
#ifndef PNG_USER_MEM_SUPPORTED
|
||||
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
|
||||
png_error(png_ptr, "Out Of Memory"); /* Note "O", "M" */
|
||||
else
|
||||
png_warning(png_ptr, "Out Of Memory");
|
||||
#endif
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if ((png_size_t)table & 0xfff0)
|
||||
{
|
||||
#ifndef PNG_USER_MEM_SUPPORTED
|
||||
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
|
||||
png_error(png_ptr,
|
||||
"Farmalloc didn't return normalized pointer");
|
||||
else
|
||||
png_warning(png_ptr,
|
||||
"Farmalloc didn't return normalized pointer");
|
||||
#endif
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
png_ptr->offset_table = table;
|
||||
png_ptr->offset_table_ptr = farmalloc(num_blocks *
|
||||
png_sizeof(png_bytep));
|
||||
|
||||
if (png_ptr->offset_table_ptr == NULL)
|
||||
{
|
||||
#ifndef PNG_USER_MEM_SUPPORTED
|
||||
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
|
||||
png_error(png_ptr, "Out Of memory"); /* Note "O", "m" */
|
||||
else
|
||||
png_warning(png_ptr, "Out Of memory");
|
||||
#endif
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
hptr = (png_byte huge *)table;
|
||||
if ((png_size_t)hptr & 0xf)
|
||||
{
|
||||
hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
|
||||
hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */
|
||||
}
|
||||
for (i = 0; i < num_blocks; i++)
|
||||
{
|
||||
png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
|
||||
hptr = hptr + (png_uint_32)65536L; /* "+=" fails on TC++3.0 */
|
||||
}
|
||||
|
||||
png_ptr->offset_table_number = num_blocks;
|
||||
png_ptr->offset_table_count = 0;
|
||||
png_ptr->offset_table_count_free = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
|
||||
{
|
||||
#ifndef PNG_USER_MEM_SUPPORTED
|
||||
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
|
||||
png_error(png_ptr, "Out of Memory"); /* Note "o" and "M" */
|
||||
else
|
||||
png_warning(png_ptr, "Out of Memory");
|
||||
#endif
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
|
||||
}
|
||||
else
|
||||
ret = farmalloc(size);
|
||||
|
||||
#ifndef PNG_USER_MEM_SUPPORTED
|
||||
if (ret == NULL)
|
||||
{
|
||||
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
|
||||
png_error(png_ptr, "Out of memory"); /* Note "o" and "m" */
|
||||
else
|
||||
png_warning(png_ptr, "Out of memory"); /* Note "o" and "m" */
|
||||
}
|
||||
#endif
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* Free a pointer allocated by png_malloc(). In the default
|
||||
* configuration, png_ptr is not used, but is passed in case it
|
||||
* is needed. If ptr is NULL, return without taking any action.
|
||||
*/
|
||||
void PNGAPI
|
||||
png_free(png_structp png_ptr, png_voidp ptr)
|
||||
{
|
||||
if (png_ptr == NULL || ptr == NULL)
|
||||
return;
|
||||
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
if (png_ptr->free_fn != NULL)
|
||||
{
|
||||
(*(png_ptr->free_fn))(png_ptr, ptr);
|
||||
return;
|
||||
}
|
||||
else
|
||||
png_free_default(png_ptr, ptr);
|
||||
}
|
||||
|
||||
void PNGAPI
|
||||
png_free_default(png_structp png_ptr, png_voidp ptr)
|
||||
{
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
||||
|
||||
if (png_ptr == NULL || ptr == NULL)
|
||||
return;
|
||||
|
||||
if (png_ptr->offset_table != NULL)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < png_ptr->offset_table_count; i++)
|
||||
{
|
||||
if (ptr == png_ptr->offset_table_ptr[i])
|
||||
{
|
||||
ptr = NULL;
|
||||
png_ptr->offset_table_count_free++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
|
||||
{
|
||||
farfree(png_ptr->offset_table);
|
||||
farfree(png_ptr->offset_table_ptr);
|
||||
png_ptr->offset_table = NULL;
|
||||
png_ptr->offset_table_ptr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (ptr != NULL)
|
||||
{
|
||||
farfree(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
#else /* Not the Borland DOS special memory handler */
|
||||
|
||||
/* Allocate memory for a png_struct or a png_info. The malloc and
|
||||
memset can be replaced by a single call to calloc() if this is thought
|
||||
to improve performance noticably. */
|
||||
png_voidp /* PRIVATE */
|
||||
png_create_struct(int type)
|
||||
{
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
return (png_create_struct_2(type, NULL, NULL));
|
||||
}
|
||||
|
||||
/* Allocate memory for a png_struct or a png_info. The malloc and
|
||||
memset can be replaced by a single call to calloc() if this is thought
|
||||
to improve performance noticably. */
|
||||
png_voidp /* PRIVATE */
|
||||
png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
|
||||
{
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
||||
png_size_t size;
|
||||
png_voidp struct_ptr;
|
||||
|
||||
if (type == PNG_STRUCT_INFO)
|
||||
size = png_sizeof(png_info);
|
||||
else if (type == PNG_STRUCT_PNG)
|
||||
size = png_sizeof(png_struct);
|
||||
else
|
||||
return (NULL);
|
||||
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
if (malloc_fn != NULL)
|
||||
{
|
||||
png_struct dummy_struct;
|
||||
png_structp png_ptr = &dummy_struct;
|
||||
png_ptr->mem_ptr=mem_ptr;
|
||||
struct_ptr = (*(malloc_fn))(png_ptr, size);
|
||||
if (struct_ptr != NULL)
|
||||
png_memset(struct_ptr, 0, size);
|
||||
return (struct_ptr);
|
||||
}
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
||||
|
||||
#if defined(__TURBOC__) && !defined(__FLAT__)
|
||||
struct_ptr = (png_voidp)farmalloc(size);
|
||||
#else
|
||||
# if defined(_MSC_VER) && defined(MAXSEG_64K)
|
||||
struct_ptr = (png_voidp)halloc(size, 1);
|
||||
# else
|
||||
struct_ptr = (png_voidp)malloc(size);
|
||||
# endif
|
||||
#endif
|
||||
if (struct_ptr != NULL)
|
||||
png_memset(struct_ptr, 0, size);
|
||||
|
||||
return (struct_ptr);
|
||||
}
|
||||
|
||||
|
||||
/* Free memory allocated by a png_create_struct() call */
|
||||
void /* PRIVATE */
|
||||
png_destroy_struct(png_voidp struct_ptr)
|
||||
{
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
png_destroy_struct_2(struct_ptr, NULL, NULL);
|
||||
}
|
||||
|
||||
/* Free memory allocated by a png_create_struct() call */
|
||||
void /* PRIVATE */
|
||||
png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
|
||||
png_voidp mem_ptr)
|
||||
{
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
||||
if (struct_ptr != NULL)
|
||||
{
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
if (free_fn != NULL)
|
||||
{
|
||||
png_struct dummy_struct;
|
||||
png_structp png_ptr = &dummy_struct;
|
||||
png_ptr->mem_ptr=mem_ptr;
|
||||
(*(free_fn))(png_ptr, struct_ptr);
|
||||
return;
|
||||
}
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
||||
#if defined(__TURBOC__) && !defined(__FLAT__)
|
||||
farfree(struct_ptr);
|
||||
#else
|
||||
# if defined(_MSC_VER) && defined(MAXSEG_64K)
|
||||
hfree(struct_ptr);
|
||||
# else
|
||||
free(struct_ptr);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate memory. For reasonable files, size should never exceed
|
||||
* 64K. However, zlib may allocate more then 64K if you don't tell
|
||||
* it not to. See zconf.h and png.h for more information. zlib does
|
||||
* need to allocate exactly 64K, so whatever you call here must
|
||||
* have the ability to do that.
|
||||
*/
|
||||
|
||||
png_voidp PNGAPI
|
||||
png_calloc(png_structp png_ptr, png_alloc_size_t size)
|
||||
{
|
||||
png_voidp ret;
|
||||
|
||||
ret = (png_malloc(png_ptr, size));
|
||||
if (ret != NULL)
|
||||
png_memset(ret,0,(png_size_t)size);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
png_voidp PNGAPI
|
||||
png_malloc(png_structp png_ptr, png_alloc_size_t size)
|
||||
{
|
||||
png_voidp ret;
|
||||
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
if (png_ptr == NULL || size == 0)
|
||||
return (NULL);
|
||||
|
||||
if (png_ptr->malloc_fn != NULL)
|
||||
ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
|
||||
else
|
||||
ret = (png_malloc_default(png_ptr, size));
|
||||
if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
|
||||
png_error(png_ptr, "Out of Memory");
|
||||
return (ret);
|
||||
}
|
||||
|
||||
png_voidp PNGAPI
|
||||
png_malloc_default(png_structp png_ptr, png_alloc_size_t size)
|
||||
{
|
||||
png_voidp ret;
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
||||
|
||||
if (png_ptr == NULL || size == 0)
|
||||
return (NULL);
|
||||
|
||||
#ifdef PNG_MAX_MALLOC_64K
|
||||
if (size > (png_uint_32)65536L)
|
||||
{
|
||||
#ifndef PNG_USER_MEM_SUPPORTED
|
||||
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
|
||||
png_error(png_ptr, "Cannot Allocate > 64K");
|
||||
else
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check for overflow */
|
||||
#if defined(__TURBOC__) && !defined(__FLAT__)
|
||||
if (size != (unsigned long)size)
|
||||
ret = NULL;
|
||||
else
|
||||
ret = farmalloc(size);
|
||||
#else
|
||||
# if defined(_MSC_VER) && defined(MAXSEG_64K)
|
||||
if (size != (unsigned long)size)
|
||||
ret = NULL;
|
||||
else
|
||||
ret = halloc(size, 1);
|
||||
# else
|
||||
if (size != (size_t)size)
|
||||
ret = NULL;
|
||||
else
|
||||
ret = malloc((size_t)size);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef PNG_USER_MEM_SUPPORTED
|
||||
if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
|
||||
png_error(png_ptr, "Out of Memory");
|
||||
#endif
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* Free a pointer allocated by png_malloc(). If ptr is NULL, return
|
||||
* without taking any action.
|
||||
*/
|
||||
void PNGAPI
|
||||
png_free(png_structp png_ptr, png_voidp ptr)
|
||||
{
|
||||
if (png_ptr == NULL || ptr == NULL)
|
||||
return;
|
||||
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
if (png_ptr->free_fn != NULL)
|
||||
{
|
||||
(*(png_ptr->free_fn))(png_ptr, ptr);
|
||||
return;
|
||||
}
|
||||
else
|
||||
png_free_default(png_ptr, ptr);
|
||||
}
|
||||
void PNGAPI
|
||||
png_free_default(png_structp png_ptr, png_voidp ptr)
|
||||
{
|
||||
if (png_ptr == NULL || ptr == NULL)
|
||||
return;
|
||||
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
||||
|
||||
#if defined(__TURBOC__) && !defined(__FLAT__)
|
||||
farfree(ptr);
|
||||
#else
|
||||
# if defined(_MSC_VER) && defined(MAXSEG_64K)
|
||||
hfree(ptr);
|
||||
# else
|
||||
free(ptr);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* Not Borland DOS special memory handler */
|
||||
|
||||
/* This function was added at libpng version 1.2.3. The png_malloc_warn()
|
||||
* function will set up png_malloc() to issue a png_warning and return NULL
|
||||
* instead of issuing a png_error, if it fails to allocate the requested
|
||||
* memory.
|
||||
*/
|
||||
png_voidp PNGAPI
|
||||
png_malloc_warn(png_structp png_ptr, png_alloc_size_t size)
|
||||
{
|
||||
png_voidp ptr;
|
||||
png_uint_32 save_flags;
|
||||
if (png_ptr == NULL)
|
||||
return (NULL);
|
||||
|
||||
save_flags = png_ptr->flags;
|
||||
png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
|
||||
ptr = (png_voidp)png_malloc((png_structp)png_ptr, size);
|
||||
png_ptr->flags=save_flags;
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
/* This function is called when the application wants to use another method
|
||||
* of allocating and freeing memory.
|
||||
*/
|
||||
void PNGAPI
|
||||
png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
|
||||
malloc_fn, png_free_ptr free_fn)
|
||||
{
|
||||
if (png_ptr != NULL)
|
||||
{
|
||||
png_ptr->mem_ptr = mem_ptr;
|
||||
png_ptr->malloc_fn = malloc_fn;
|
||||
png_ptr->free_fn = free_fn;
|
||||
}
|
||||
}
|
||||
|
||||
/* This function returns a pointer to the mem_ptr associated with the user
|
||||
* functions. The application should free any memory associated with this
|
||||
* pointer before png_write_destroy and png_read_destroy are called.
|
||||
*/
|
||||
png_voidp PNGAPI
|
||||
png_get_mem_ptr(png_structp png_ptr)
|
||||
{
|
||||
if (png_ptr == NULL)
|
||||
return (NULL);
|
||||
return ((png_voidp)png_ptr->mem_ptr);
|
||||
}
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
||||
#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
|
1765
thirdparty/libpng/pngpread.c
vendored
Normal file
1765
thirdparty/libpng/pngpread.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
954
thirdparty/libpng/pngpriv.h
vendored
Normal file
954
thirdparty/libpng/pngpriv.h
vendored
Normal file
@ -0,0 +1,954 @@
|
||||
|
||||
/* pngpriv.h - private declarations for use inside libpng
|
||||
*
|
||||
* libpng version 1.4.4 - September 23, 2010
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1998-2010 Glenn Randers-Pehrson
|
||||
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
|
||||
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*/
|
||||
|
||||
/* The symbols declared in this file (including the functions declared
|
||||
* as PNG_EXTERN) are PRIVATE. They are not part of the libpng public
|
||||
* interface, and are not recommended for use by regular applications.
|
||||
* Some of them may become public in the future; others may stay private,
|
||||
* change in an incompatible way, or even disappear.
|
||||
* Although the libpng users are not forbidden to include this header,
|
||||
* they should be well aware of the issues that may arise from doing so.
|
||||
*/
|
||||
|
||||
#ifndef PNGPRIV_H
|
||||
#define PNGPRIV_H
|
||||
|
||||
#ifndef PNG_VERSION_INFO_ONLY
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef PNG_EXTERN
|
||||
/* The functions exported by PNG_EXTERN are internal functions, which
|
||||
* aren't usually used outside the library (as far as I know), so it is
|
||||
* debatable if they should be exported at all. In the future, when it
|
||||
* is possible to have run-time registry of chunk-handling functions,
|
||||
* some of these will be made available again.
|
||||
# define PNG_EXTERN extern
|
||||
*/
|
||||
# define PNG_EXTERN
|
||||
#endif
|
||||
|
||||
/* Other defines specific to compilers can go here. Try to keep
|
||||
* them inside an appropriate ifdef/endif pair for portability.
|
||||
*/
|
||||
|
||||
#ifdef PNG_FLOATING_POINT_SUPPORTED
|
||||
# ifdef MACOS
|
||||
/* We need to check that <math.h> hasn't already been included earlier
|
||||
* as it seems it doesn't agree with <fp.h>, yet we should really use
|
||||
* <fp.h> if possible.
|
||||
*/
|
||||
# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
|
||||
# include <fp.h>
|
||||
# endif
|
||||
# else
|
||||
# include <math.h>
|
||||
# endif
|
||||
# if defined(_AMIGA) && defined(__SASC) && defined(_M68881)
|
||||
/* Amiga SAS/C: We must include builtin FPU functions when compiling using
|
||||
* MATH=68881
|
||||
*/
|
||||
# include <m68881.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Codewarrior on NT has linking problems without this. */
|
||||
#if (defined(__MWERKS__) && defined(WIN32)) || defined(__STDC__)
|
||||
# define PNG_ALWAYS_EXTERN
|
||||
#endif
|
||||
|
||||
/* This provides the non-ANSI (far) memory allocation routines. */
|
||||
#if defined(__TURBOC__) && defined(__MSDOS__)
|
||||
# include <mem.h>
|
||||
# include <alloc.h>
|
||||
#endif
|
||||
|
||||
#if defined(WIN32) || defined(_Windows) || defined(_WINDOWS) || \
|
||||
defined(_WIN32) || defined(__WIN32__)
|
||||
# include <windows.h> /* defines _WINDOWS_ macro */
|
||||
#endif
|
||||
|
||||
/* Various modes of operation. Note that after an init, mode is set to
|
||||
* zero automatically when the structure is created.
|
||||
*/
|
||||
#define PNG_HAVE_IHDR 0x01
|
||||
#define PNG_HAVE_PLTE 0x02
|
||||
#define PNG_HAVE_IDAT 0x04
|
||||
#define PNG_AFTER_IDAT 0x08 /* Have complete zlib datastream */
|
||||
#define PNG_HAVE_IEND 0x10
|
||||
#define PNG_HAVE_gAMA 0x20
|
||||
#define PNG_HAVE_cHRM 0x40
|
||||
#define PNG_HAVE_sRGB 0x80
|
||||
#define PNG_HAVE_CHUNK_HEADER 0x100
|
||||
#define PNG_WROTE_tIME 0x200
|
||||
#define PNG_WROTE_INFO_BEFORE_PLTE 0x400
|
||||
#define PNG_BACKGROUND_IS_GRAY 0x800
|
||||
#define PNG_HAVE_PNG_SIGNATURE 0x1000
|
||||
#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */
|
||||
|
||||
/* Flags for the transformations the PNG library does on the image data */
|
||||
#define PNG_BGR 0x0001
|
||||
#define PNG_INTERLACE 0x0002
|
||||
#define PNG_PACK 0x0004
|
||||
#define PNG_SHIFT 0x0008
|
||||
#define PNG_SWAP_BYTES 0x0010
|
||||
#define PNG_INVERT_MONO 0x0020
|
||||
#define PNG_QUANTIZE 0x0040 /* formerly PNG_DITHER */
|
||||
#define PNG_BACKGROUND 0x0080
|
||||
#define PNG_BACKGROUND_EXPAND 0x0100
|
||||
/* 0x0200 unused */
|
||||
#define PNG_16_TO_8 0x0400
|
||||
#define PNG_RGBA 0x0800
|
||||
#define PNG_EXPAND 0x1000
|
||||
#define PNG_GAMMA 0x2000
|
||||
#define PNG_GRAY_TO_RGB 0x4000
|
||||
#define PNG_FILLER 0x8000L
|
||||
#define PNG_PACKSWAP 0x10000L
|
||||
#define PNG_SWAP_ALPHA 0x20000L
|
||||
#define PNG_STRIP_ALPHA 0x40000L
|
||||
#define PNG_INVERT_ALPHA 0x80000L
|
||||
#define PNG_USER_TRANSFORM 0x100000L
|
||||
#define PNG_RGB_TO_GRAY_ERR 0x200000L
|
||||
#define PNG_RGB_TO_GRAY_WARN 0x400000L
|
||||
#define PNG_RGB_TO_GRAY 0x600000L /* two bits, RGB_TO_GRAY_ERR|WARN */
|
||||
/* 0x800000L Unused */
|
||||
#define PNG_ADD_ALPHA 0x1000000L /* Added to libpng-1.2.7 */
|
||||
#define PNG_EXPAND_tRNS 0x2000000L /* Added to libpng-1.2.9 */
|
||||
/* 0x4000000L unused */
|
||||
/* 0x8000000L unused */
|
||||
/* 0x10000000L unused */
|
||||
/* 0x20000000L unused */
|
||||
/* 0x40000000L unused */
|
||||
|
||||
/* Flags for png_create_struct */
|
||||
#define PNG_STRUCT_PNG 0x0001
|
||||
#define PNG_STRUCT_INFO 0x0002
|
||||
|
||||
/* Scaling factor for filter heuristic weighting calculations */
|
||||
#define PNG_WEIGHT_SHIFT 8
|
||||
#define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT))
|
||||
#define PNG_COST_SHIFT 3
|
||||
#define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT))
|
||||
|
||||
/* Flags for the png_ptr->flags rather than declaring a byte for each one */
|
||||
#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001
|
||||
#define PNG_FLAG_ZLIB_CUSTOM_LEVEL 0x0002
|
||||
#define PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL 0x0004
|
||||
#define PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS 0x0008
|
||||
#define PNG_FLAG_ZLIB_CUSTOM_METHOD 0x0010
|
||||
#define PNG_FLAG_ZLIB_FINISHED 0x0020
|
||||
#define PNG_FLAG_ROW_INIT 0x0040
|
||||
#define PNG_FLAG_FILLER_AFTER 0x0080
|
||||
#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100
|
||||
#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200
|
||||
#define PNG_FLAG_CRC_CRITICAL_USE 0x0400
|
||||
#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800
|
||||
/* 0x1000 unused */
|
||||
/* 0x2000 unused */
|
||||
/* 0x4000 unused */
|
||||
#define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000L
|
||||
#define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000L
|
||||
#define PNG_FLAG_LIBRARY_MISMATCH 0x20000L
|
||||
#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000L
|
||||
#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000L
|
||||
#define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000L
|
||||
#define PNG_FLAG_ADD_ALPHA 0x200000L /* Added to libpng-1.2.8 */
|
||||
#define PNG_FLAG_STRIP_ALPHA 0x400000L /* Added to libpng-1.2.8 */
|
||||
#define PNG_FLAG_BENIGN_ERRORS_WARN 0x800000L /* Added to libpng-1.4.0 */
|
||||
/* 0x1000000L unused */
|
||||
/* 0x2000000L unused */
|
||||
/* 0x4000000L unused */
|
||||
/* 0x8000000L unused */
|
||||
/* 0x10000000L unused */
|
||||
/* 0x20000000L unused */
|
||||
/* 0x40000000L unused */
|
||||
|
||||
#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
|
||||
PNG_FLAG_CRC_ANCILLARY_NOWARN)
|
||||
|
||||
#define PNG_FLAG_CRC_CRITICAL_MASK (PNG_FLAG_CRC_CRITICAL_USE | \
|
||||
PNG_FLAG_CRC_CRITICAL_IGNORE)
|
||||
|
||||
#define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \
|
||||
PNG_FLAG_CRC_CRITICAL_MASK)
|
||||
|
||||
/* Save typing and make code easier to understand */
|
||||
|
||||
#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \
|
||||
abs((int)((c1).green) - (int)((c2).green)) + \
|
||||
abs((int)((c1).blue) - (int)((c2).blue)))
|
||||
|
||||
/* Added to libpng-1.2.6 JB */
|
||||
#define PNG_ROWBYTES(pixel_bits, width) \
|
||||
((pixel_bits) >= 8 ? \
|
||||
((png_size_t)(width) * (((png_size_t)(pixel_bits)) >> 3)) : \
|
||||
(( ((png_size_t)(width) * ((png_size_t)(pixel_bits))) + 7) >> 3) )
|
||||
|
||||
/* PNG_OUT_OF_RANGE returns true if value is outside the range
|
||||
* ideal-delta..ideal+delta. Each argument is evaluated twice.
|
||||
* "ideal" and "delta" should be constants, normally simple
|
||||
* integers, "value" a variable. Added to libpng-1.2.6 JB
|
||||
*/
|
||||
#define PNG_OUT_OF_RANGE(value, ideal, delta) \
|
||||
( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) )
|
||||
|
||||
/* Constant strings for known chunk types. If you need to add a chunk,
|
||||
* define the name here, and add an invocation of the macro wherever it's
|
||||
* needed.
|
||||
*/
|
||||
#define PNG_IHDR PNG_CONST png_byte png_IHDR[5] = { 73, 72, 68, 82, '\0'}
|
||||
#define PNG_IDAT PNG_CONST png_byte png_IDAT[5] = { 73, 68, 65, 84, '\0'}
|
||||
#define PNG_IEND PNG_CONST png_byte png_IEND[5] = { 73, 69, 78, 68, '\0'}
|
||||
#define PNG_PLTE PNG_CONST png_byte png_PLTE[5] = { 80, 76, 84, 69, '\0'}
|
||||
#define PNG_bKGD PNG_CONST png_byte png_bKGD[5] = { 98, 75, 71, 68, '\0'}
|
||||
#define PNG_cHRM PNG_CONST png_byte png_cHRM[5] = { 99, 72, 82, 77, '\0'}
|
||||
#define PNG_gAMA PNG_CONST png_byte png_gAMA[5] = {103, 65, 77, 65, '\0'}
|
||||
#define PNG_hIST PNG_CONST png_byte png_hIST[5] = {104, 73, 83, 84, '\0'}
|
||||
#define PNG_iCCP PNG_CONST png_byte png_iCCP[5] = {105, 67, 67, 80, '\0'}
|
||||
#define PNG_iTXt PNG_CONST png_byte png_iTXt[5] = {105, 84, 88, 116, '\0'}
|
||||
#define PNG_oFFs PNG_CONST png_byte png_oFFs[5] = {111, 70, 70, 115, '\0'}
|
||||
#define PNG_pCAL PNG_CONST png_byte png_pCAL[5] = {112, 67, 65, 76, '\0'}
|
||||
#define PNG_sCAL PNG_CONST png_byte png_sCAL[5] = {115, 67, 65, 76, '\0'}
|
||||
#define PNG_pHYs PNG_CONST png_byte png_pHYs[5] = {112, 72, 89, 115, '\0'}
|
||||
#define PNG_sBIT PNG_CONST png_byte png_sBIT[5] = {115, 66, 73, 84, '\0'}
|
||||
#define PNG_sPLT PNG_CONST png_byte png_sPLT[5] = {115, 80, 76, 84, '\0'}
|
||||
#define PNG_sRGB PNG_CONST png_byte png_sRGB[5] = {115, 82, 71, 66, '\0'}
|
||||
#define PNG_sTER PNG_CONST png_byte png_sTER[5] = {115, 84, 69, 82, '\0'}
|
||||
#define PNG_tEXt PNG_CONST png_byte png_tEXt[5] = {116, 69, 88, 116, '\0'}
|
||||
#define PNG_tIME PNG_CONST png_byte png_tIME[5] = {116, 73, 77, 69, '\0'}
|
||||
#define PNG_tRNS PNG_CONST png_byte png_tRNS[5] = {116, 82, 78, 83, '\0'}
|
||||
#define PNG_zTXt PNG_CONST png_byte png_zTXt[5] = {122, 84, 88, 116, '\0'}
|
||||
|
||||
|
||||
/* Inhibit C++ name-mangling for libpng functions but not for system calls. */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* These functions are used internally in the code. They generally
|
||||
* shouldn't be used unless you are writing code to add or replace some
|
||||
* functionality in libpng. More information about most functions can
|
||||
* be found in the files where the functions are located.
|
||||
*/
|
||||
|
||||
/* Allocate memory for an internal libpng struct */
|
||||
PNG_EXTERN png_voidp png_create_struct PNGARG((int type));
|
||||
|
||||
/* Free memory from internal libpng struct */
|
||||
PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr));
|
||||
|
||||
PNG_EXTERN png_voidp png_create_struct_2 PNGARG((int type, png_malloc_ptr
|
||||
malloc_fn, png_voidp mem_ptr));
|
||||
PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr,
|
||||
png_free_ptr free_fn, png_voidp mem_ptr));
|
||||
|
||||
/* Free any memory that info_ptr points to and reset struct. */
|
||||
PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr,
|
||||
png_infop info_ptr));
|
||||
|
||||
/* Function to allocate memory for zlib. PNGAPI is disallowed. */
|
||||
PNG_EXTERN voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items, uInt size));
|
||||
|
||||
/* Function to free memory for zlib. PNGAPI is disallowed. */
|
||||
PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr));
|
||||
|
||||
/* Next four functions are used internally as callbacks. PNGAPI is required
|
||||
* but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3. */
|
||||
|
||||
PNG_EXTERN void PNGAPI png_default_read_data PNGARG((png_structp png_ptr,
|
||||
png_bytep data, png_size_t length));
|
||||
|
||||
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
|
||||
PNG_EXTERN void PNGAPI png_push_fill_buffer PNGARG((png_structp png_ptr,
|
||||
png_bytep buffer, png_size_t length));
|
||||
#endif
|
||||
|
||||
PNG_EXTERN void PNGAPI png_default_write_data PNGARG((png_structp png_ptr,
|
||||
png_bytep data, png_size_t length));
|
||||
|
||||
#ifdef PNG_WRITE_FLUSH_SUPPORTED
|
||||
#ifdef PNG_STDIO_SUPPORTED
|
||||
PNG_EXTERN void PNGAPI png_default_flush PNGARG((png_structp png_ptr));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Reset the CRC variable */
|
||||
PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr));
|
||||
|
||||
/* Write the "data" buffer to whatever output you are using */
|
||||
PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, png_bytep data,
|
||||
png_size_t length));
|
||||
|
||||
/* Read the chunk header (length + type name) */
|
||||
PNG_EXTERN png_uint_32 png_read_chunk_header PNGARG((png_structp png_ptr));
|
||||
|
||||
/* Read data from whatever input you are using into the "data" buffer */
|
||||
PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data,
|
||||
png_size_t length));
|
||||
|
||||
/* Read bytes into buf, and update png_ptr->crc */
|
||||
PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf,
|
||||
png_size_t length));
|
||||
|
||||
/* Decompress data in a chunk that uses compression */
|
||||
#if defined(PNG_zTXt_SUPPORTED) || defined(PNG_iTXt_SUPPORTED) || \
|
||||
defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED)
|
||||
PNG_EXTERN void png_decompress_chunk PNGARG((png_structp png_ptr,
|
||||
int comp_type, png_size_t chunklength, png_size_t prefix_length,
|
||||
png_size_t *data_length));
|
||||
#endif
|
||||
|
||||
/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */
|
||||
PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip));
|
||||
|
||||
/* Read the CRC from the file and compare it to the libpng calculated CRC */
|
||||
PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr));
|
||||
|
||||
/* Calculate the CRC over a section of data. Note that we are only
|
||||
* passing a maximum of 64K on systems that have this as a memory limit,
|
||||
* since this is the maximum buffer size we can specify.
|
||||
*/
|
||||
PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, png_bytep ptr,
|
||||
png_size_t length));
|
||||
|
||||
#ifdef PNG_WRITE_FLUSH_SUPPORTED
|
||||
PNG_EXTERN void png_flush PNGARG((png_structp png_ptr));
|
||||
#endif
|
||||
|
||||
/* Write various chunks */
|
||||
|
||||
/* Write the IHDR chunk, and update the png_struct with the necessary
|
||||
* information.
|
||||
*/
|
||||
PNG_EXTERN void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width,
|
||||
png_uint_32 height,
|
||||
int bit_depth, int color_type, int compression_method, int filter_method,
|
||||
int interlace_method));
|
||||
|
||||
PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr, png_colorp palette,
|
||||
png_uint_32 num_pal));
|
||||
|
||||
PNG_EXTERN void png_write_IDAT PNGARG((png_structp png_ptr, png_bytep data,
|
||||
png_size_t length));
|
||||
|
||||
PNG_EXTERN void png_write_IEND PNGARG((png_structp png_ptr));
|
||||
|
||||
#ifdef PNG_WRITE_gAMA_SUPPORTED
|
||||
#ifdef PNG_FLOATING_POINT_SUPPORTED
|
||||
PNG_EXTERN void png_write_gAMA PNGARG((png_structp png_ptr, double file_gamma));
|
||||
#endif
|
||||
#ifdef PNG_FIXED_POINT_SUPPORTED
|
||||
PNG_EXTERN void png_write_gAMA_fixed PNGARG((png_structp png_ptr,
|
||||
png_fixed_point file_gamma));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_sBIT_SUPPORTED
|
||||
PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, png_color_8p sbit,
|
||||
int color_type));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_cHRM_SUPPORTED
|
||||
#ifdef PNG_FLOATING_POINT_SUPPORTED
|
||||
PNG_EXTERN void png_write_cHRM PNGARG((png_structp png_ptr,
|
||||
double white_x, double white_y,
|
||||
double red_x, double red_y, double green_x, double green_y,
|
||||
double blue_x, double blue_y));
|
||||
#endif
|
||||
PNG_EXTERN void png_write_cHRM_fixed PNGARG((png_structp png_ptr,
|
||||
png_fixed_point int_white_x, png_fixed_point int_white_y,
|
||||
png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
|
||||
int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
|
||||
png_fixed_point int_blue_y));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_sRGB_SUPPORTED
|
||||
PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr,
|
||||
int intent));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_iCCP_SUPPORTED
|
||||
PNG_EXTERN void png_write_iCCP PNGARG((png_structp png_ptr,
|
||||
png_charp name, int compression_type,
|
||||
png_charp profile, int proflen));
|
||||
/* Note to maintainer: profile should be png_bytep */
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_sPLT_SUPPORTED
|
||||
PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr,
|
||||
png_sPLT_tp palette));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_tRNS_SUPPORTED
|
||||
PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, png_bytep trans,
|
||||
png_color_16p values, int number, int color_type));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_bKGD_SUPPORTED
|
||||
PNG_EXTERN void png_write_bKGD PNGARG((png_structp png_ptr,
|
||||
png_color_16p values, int color_type));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_hIST_SUPPORTED
|
||||
PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, png_uint_16p hist,
|
||||
int num_hist));
|
||||
#endif
|
||||
|
||||
#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
|
||||
defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
|
||||
PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr,
|
||||
png_charp key, png_charpp new_key));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_tEXt_SUPPORTED
|
||||
PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_charp key,
|
||||
png_charp text, png_size_t text_len));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_zTXt_SUPPORTED
|
||||
PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_charp key,
|
||||
png_charp text, png_size_t text_len, int compression));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_iTXt_SUPPORTED
|
||||
PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr,
|
||||
int compression, png_charp key, png_charp lang, png_charp lang_key,
|
||||
png_charp text));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_TEXT_SUPPORTED /* Added at version 1.0.14 and 1.2.4 */
|
||||
PNG_EXTERN int png_set_text_2 PNGARG((png_structp png_ptr,
|
||||
png_infop info_ptr, png_textp text_ptr, int num_text));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_oFFs_SUPPORTED
|
||||
PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr,
|
||||
png_int_32 x_offset, png_int_32 y_offset, int unit_type));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_pCAL_SUPPORTED
|
||||
PNG_EXTERN void png_write_pCAL PNGARG((png_structp png_ptr, png_charp purpose,
|
||||
png_int_32 X0, png_int_32 X1, int type, int nparams,
|
||||
png_charp units, png_charpp params));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_pHYs_SUPPORTED
|
||||
PNG_EXTERN void png_write_pHYs PNGARG((png_structp png_ptr,
|
||||
png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit,
|
||||
int unit_type));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_tIME_SUPPORTED
|
||||
PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr,
|
||||
png_timep mod_time));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_sCAL_SUPPORTED
|
||||
#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_STDIO_SUPPORTED)
|
||||
PNG_EXTERN void png_write_sCAL PNGARG((png_structp png_ptr,
|
||||
int unit, double width, double height));
|
||||
#else
|
||||
#ifdef PNG_FIXED_POINT_SUPPORTED
|
||||
PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr,
|
||||
int unit, png_charp width, png_charp height));
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Called when finished processing a row of data */
|
||||
PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr));
|
||||
|
||||
/* Internal use only. Called before first row of data */
|
||||
PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr));
|
||||
|
||||
#ifdef PNG_READ_GAMMA_SUPPORTED
|
||||
PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr,
|
||||
png_byte bit_depth));
|
||||
#endif
|
||||
|
||||
/* Combine a row of data, dealing with alpha, etc. if requested */
|
||||
PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row,
|
||||
int mask));
|
||||
|
||||
#ifdef PNG_READ_INTERLACING_SUPPORTED
|
||||
/* Expand an interlaced row */
|
||||
/* OLD pre-1.0.9 interface:
|
||||
PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info,
|
||||
png_bytep row, int pass, png_uint_32 transformations));
|
||||
*/
|
||||
PNG_EXTERN void png_do_read_interlace PNGARG((png_structp png_ptr));
|
||||
#endif
|
||||
|
||||
/* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */
|
||||
|
||||
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
|
||||
/* Grab pixels out of a row for an interlaced pass */
|
||||
PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info,
|
||||
png_bytep row, int pass));
|
||||
#endif
|
||||
|
||||
/* Unfilter a row */
|
||||
PNG_EXTERN void png_read_filter_row PNGARG((png_structp png_ptr,
|
||||
png_row_infop row_info, png_bytep row, png_bytep prev_row, int filter));
|
||||
|
||||
/* Choose the best filter to use and filter the row data */
|
||||
PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr,
|
||||
png_row_infop row_info));
|
||||
|
||||
/* Write out the filtered row. */
|
||||
PNG_EXTERN void png_write_filtered_row PNGARG((png_structp png_ptr,
|
||||
png_bytep filtered_row));
|
||||
/* Finish a row while reading, dealing with interlacing passes, etc. */
|
||||
PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr));
|
||||
|
||||
/* Initialize the row buffers, etc. */
|
||||
PNG_EXTERN void png_read_start_row PNGARG((png_structp png_ptr));
|
||||
/* Optional call to update the users info structure */
|
||||
PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr,
|
||||
png_infop info_ptr));
|
||||
|
||||
/* These are the functions that do the transformations */
|
||||
#ifdef PNG_READ_FILLER_SUPPORTED
|
||||
PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info,
|
||||
png_bytep row, png_uint_32 filler, png_uint_32 flags));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
|
||||
PNG_EXTERN void png_do_read_swap_alpha PNGARG((png_row_infop row_info,
|
||||
png_bytep row));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
|
||||
PNG_EXTERN void png_do_write_swap_alpha PNGARG((png_row_infop row_info,
|
||||
png_bytep row));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
|
||||
PNG_EXTERN void png_do_read_invert_alpha PNGARG((png_row_infop row_info,
|
||||
png_bytep row));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
|
||||
PNG_EXTERN void png_do_write_invert_alpha PNGARG((png_row_infop row_info,
|
||||
png_bytep row));
|
||||
#endif
|
||||
|
||||
#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
|
||||
defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
|
||||
PNG_EXTERN void png_do_strip_filler PNGARG((png_row_infop row_info,
|
||||
png_bytep row, png_uint_32 flags));
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
|
||||
PNG_EXTERN void png_do_swap PNGARG((png_row_infop row_info, png_bytep row));
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \
|
||||
defined(PNG_WRITE_PACKSWAP_SUPPORTED)
|
||||
PNG_EXTERN void png_do_packswap PNGARG((png_row_infop row_info, png_bytep row));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
|
||||
PNG_EXTERN int png_do_rgb_to_gray PNGARG((png_structp png_ptr, png_row_infop
|
||||
row_info, png_bytep row));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
|
||||
PNG_EXTERN void png_do_gray_to_rgb PNGARG((png_row_infop row_info,
|
||||
png_bytep row));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_PACK_SUPPORTED
|
||||
PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info, png_bytep row));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_SHIFT_SUPPORTED
|
||||
PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info, png_bytep row,
|
||||
png_color_8p sig_bits));
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
|
||||
PNG_EXTERN void png_do_invert PNGARG((png_row_infop row_info, png_bytep row));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_16_TO_8_SUPPORTED
|
||||
PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info, png_bytep row));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_QUANTIZE_SUPPORTED
|
||||
PNG_EXTERN void png_do_quantize PNGARG((png_row_infop row_info,
|
||||
png_bytep row, png_bytep palette_lookup, png_bytep quantize_lookup));
|
||||
|
||||
# ifdef PNG_CORRECT_PALETTE_SUPPORTED
|
||||
PNG_EXTERN void png_correct_palette PNGARG((png_structp png_ptr,
|
||||
png_colorp palette, int num_palette));
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
|
||||
PNG_EXTERN void png_do_bgr PNGARG((png_row_infop row_info, png_bytep row));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_PACK_SUPPORTED
|
||||
PNG_EXTERN void png_do_pack PNGARG((png_row_infop row_info,
|
||||
png_bytep row, png_uint_32 bit_depth));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_SHIFT_SUPPORTED
|
||||
PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info, png_bytep row,
|
||||
png_color_8p bit_depth));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_BACKGROUND_SUPPORTED
|
||||
#ifdef PNG_READ_GAMMA_SUPPORTED
|
||||
PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row,
|
||||
png_color_16p trans_color, png_color_16p background,
|
||||
png_color_16p background_1,
|
||||
png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
|
||||
png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
|
||||
png_uint_16pp gamma_16_to_1, int gamma_shift));
|
||||
#else
|
||||
PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row,
|
||||
png_color_16p trans_color, png_color_16p background));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_GAMMA_SUPPORTED
|
||||
PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info, png_bytep row,
|
||||
png_bytep gamma_table, png_uint_16pp gamma_16_table,
|
||||
int gamma_shift));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_EXPAND_SUPPORTED
|
||||
PNG_EXTERN void png_do_expand_palette PNGARG((png_row_infop row_info,
|
||||
png_bytep row, png_colorp palette, png_bytep trans, int num_trans));
|
||||
PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info,
|
||||
png_bytep row, png_color_16p trans_value));
|
||||
#endif
|
||||
|
||||
/* The following decodes the appropriate chunks, and does error correction,
|
||||
* then calls the appropriate callback for the chunk if it is valid.
|
||||
*/
|
||||
|
||||
/* Decode the IHDR chunk */
|
||||
PNG_EXTERN void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 length));
|
||||
PNG_EXTERN void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 length));
|
||||
PNG_EXTERN void png_handle_IEND PNGARG((png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 length));
|
||||
|
||||
#ifdef PNG_READ_bKGD_SUPPORTED
|
||||
PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 length));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_cHRM_SUPPORTED
|
||||
PNG_EXTERN void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 length));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_gAMA_SUPPORTED
|
||||
PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 length));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_hIST_SUPPORTED
|
||||
PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 length));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_iCCP_SUPPORTED
|
||||
PNG_EXTERN void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 length));
|
||||
#endif /* PNG_READ_iCCP_SUPPORTED */
|
||||
|
||||
#ifdef PNG_READ_iTXt_SUPPORTED
|
||||
PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 length));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_oFFs_SUPPORTED
|
||||
PNG_EXTERN void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 length));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_pCAL_SUPPORTED
|
||||
PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 length));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_pHYs_SUPPORTED
|
||||
PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 length));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_sBIT_SUPPORTED
|
||||
PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 length));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_sCAL_SUPPORTED
|
||||
PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 length));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_sPLT_SUPPORTED
|
||||
PNG_EXTERN void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 length));
|
||||
#endif /* PNG_READ_sPLT_SUPPORTED */
|
||||
|
||||
#ifdef PNG_READ_sRGB_SUPPORTED
|
||||
PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 length));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_tEXt_SUPPORTED
|
||||
PNG_EXTERN void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 length));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_tIME_SUPPORTED
|
||||
PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 length));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_tRNS_SUPPORTED
|
||||
PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 length));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_zTXt_SUPPORTED
|
||||
PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 length));
|
||||
#endif
|
||||
|
||||
PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr,
|
||||
png_infop info_ptr, png_uint_32 length));
|
||||
|
||||
PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr,
|
||||
png_bytep chunk_name));
|
||||
|
||||
/* Handle the transformations for reading and writing */
|
||||
PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr));
|
||||
PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr));
|
||||
|
||||
PNG_EXTERN void png_init_read_transformations PNGARG((png_structp png_ptr));
|
||||
|
||||
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
|
||||
PNG_EXTERN void png_push_read_chunk PNGARG((png_structp png_ptr,
|
||||
png_infop info_ptr));
|
||||
PNG_EXTERN void png_push_read_sig PNGARG((png_structp png_ptr,
|
||||
png_infop info_ptr));
|
||||
PNG_EXTERN void png_push_check_crc PNGARG((png_structp png_ptr));
|
||||
PNG_EXTERN void png_push_crc_skip PNGARG((png_structp png_ptr,
|
||||
png_uint_32 length));
|
||||
PNG_EXTERN void png_push_crc_finish PNGARG((png_structp png_ptr));
|
||||
PNG_EXTERN void png_push_save_buffer PNGARG((png_structp png_ptr));
|
||||
PNG_EXTERN void png_push_restore_buffer PNGARG((png_structp png_ptr,
|
||||
png_bytep buffer, png_size_t buffer_length));
|
||||
PNG_EXTERN void png_push_read_IDAT PNGARG((png_structp png_ptr));
|
||||
PNG_EXTERN void png_process_IDAT_data PNGARG((png_structp png_ptr,
|
||||
png_bytep buffer, png_size_t buffer_length));
|
||||
PNG_EXTERN void png_push_process_row PNGARG((png_structp png_ptr));
|
||||
PNG_EXTERN void png_push_handle_unknown PNGARG((png_structp png_ptr,
|
||||
png_infop info_ptr, png_uint_32 length));
|
||||
PNG_EXTERN void png_push_have_info PNGARG((png_structp png_ptr,
|
||||
png_infop info_ptr));
|
||||
PNG_EXTERN void png_push_have_end PNGARG((png_structp png_ptr,
|
||||
png_infop info_ptr));
|
||||
PNG_EXTERN void png_push_have_row PNGARG((png_structp png_ptr, png_bytep row));
|
||||
PNG_EXTERN void png_push_read_end PNGARG((png_structp png_ptr,
|
||||
png_infop info_ptr));
|
||||
PNG_EXTERN void png_process_some_data PNGARG((png_structp png_ptr,
|
||||
png_infop info_ptr));
|
||||
PNG_EXTERN void png_read_push_finish_row PNGARG((png_structp png_ptr));
|
||||
#ifdef PNG_READ_tEXt_SUPPORTED
|
||||
PNG_EXTERN void png_push_handle_tEXt PNGARG((png_structp png_ptr,
|
||||
png_infop info_ptr, png_uint_32 length));
|
||||
PNG_EXTERN void png_push_read_tEXt PNGARG((png_structp png_ptr,
|
||||
png_infop info_ptr));
|
||||
#endif
|
||||
#ifdef PNG_READ_zTXt_SUPPORTED
|
||||
PNG_EXTERN void png_push_handle_zTXt PNGARG((png_structp png_ptr,
|
||||
png_infop info_ptr, png_uint_32 length));
|
||||
PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr,
|
||||
png_infop info_ptr));
|
||||
#endif
|
||||
#ifdef PNG_READ_iTXt_SUPPORTED
|
||||
PNG_EXTERN void png_push_handle_iTXt PNGARG((png_structp png_ptr,
|
||||
png_infop info_ptr, png_uint_32 length));
|
||||
PNG_EXTERN void png_push_read_iTXt PNGARG((png_structp png_ptr,
|
||||
png_infop info_ptr));
|
||||
#endif
|
||||
|
||||
#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
|
||||
|
||||
#ifdef PNG_MNG_FEATURES_SUPPORTED
|
||||
PNG_EXTERN void png_do_read_intrapixel PNGARG((png_row_infop row_info,
|
||||
png_bytep row));
|
||||
PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info,
|
||||
png_bytep row));
|
||||
#endif
|
||||
|
||||
/* Added at libpng version 1.4.0 */
|
||||
#ifdef PNG_cHRM_SUPPORTED
|
||||
PNG_EXTERN int png_check_cHRM_fixed PNGARG((png_structp png_ptr,
|
||||
png_fixed_point int_white_x, png_fixed_point int_white_y,
|
||||
png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
|
||||
int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
|
||||
png_fixed_point int_blue_y));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_cHRM_SUPPORTED
|
||||
#ifdef PNG_CHECK_cHRM_SUPPORTED
|
||||
/* Added at libpng version 1.2.34 and 1.4.0 */
|
||||
PNG_EXTERN void png_64bit_product PNGARG((long v1, long v2,
|
||||
unsigned long *hi_product, unsigned long *lo_product));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Added at libpng version 1.4.0 */
|
||||
PNG_EXTERN void png_check_IHDR PNGARG((png_structp png_ptr,
|
||||
png_uint_32 width, png_uint_32 height, int bit_depth,
|
||||
int color_type, int interlace_type, int compression_type,
|
||||
int filter_type));
|
||||
|
||||
/* Free all memory used by the read (old method - NOT DLL EXPORTED) */
|
||||
PNG_EXTERN void png_read_destroy PNGARG((png_structp png_ptr, png_infop info_ptr,
|
||||
png_infop end_info_ptr));
|
||||
|
||||
/* Free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */
|
||||
PNG_EXTERN void png_write_destroy PNGARG((png_structp png_ptr));
|
||||
|
||||
#ifdef USE_FAR_KEYWORD /* memory model conversion function */
|
||||
PNG_EXTERN void *png_far_to_near PNGARG((png_structp png_ptr,png_voidp ptr,
|
||||
int check));
|
||||
#endif /* USE_FAR_KEYWORD */
|
||||
|
||||
/* Define PNG_DEBUG at compile time for debugging information. Higher
|
||||
* numbers for PNG_DEBUG mean more debugging information. This has
|
||||
* only been added since version 0.95 so it is not implemented throughout
|
||||
* libpng yet, but more support will be added as needed.
|
||||
*/
|
||||
#ifdef PNG_DEBUG
|
||||
#if (PNG_DEBUG > 0)
|
||||
#if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER)
|
||||
#include <crtdbg.h>
|
||||
#if (PNG_DEBUG > 1)
|
||||
#ifndef _DEBUG
|
||||
# define _DEBUG
|
||||
#endif
|
||||
#ifndef png_debug
|
||||
#define png_debug(l,m) _RPT0(_CRT_WARN,m PNG_STRING_NEWLINE)
|
||||
#endif
|
||||
#ifndef png_debug1
|
||||
#define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m PNG_STRING_NEWLINE,p1)
|
||||
#endif
|
||||
#ifndef png_debug2
|
||||
#define png_debug2(l,m,p1,p2) _RPT2(_CRT_WARN,m PNG_STRING_NEWLINE,p1,p2)
|
||||
#endif
|
||||
#endif
|
||||
#else /* PNG_DEBUG_FILE || !_MSC_VER */
|
||||
#ifndef PNG_DEBUG_FILE
|
||||
#define PNG_DEBUG_FILE stderr
|
||||
#endif /* PNG_DEBUG_FILE */
|
||||
|
||||
#if (PNG_DEBUG > 1)
|
||||
/* Note: ["%s"m PNG_STRING_NEWLINE] probably does not work on
|
||||
* non-ISO compilers
|
||||
*/
|
||||
# ifdef __STDC__
|
||||
# ifndef png_debug
|
||||
# define png_debug(l,m) \
|
||||
{ \
|
||||
int num_tabs=l; \
|
||||
fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
|
||||
(num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \
|
||||
}
|
||||
# endif
|
||||
# ifndef png_debug1
|
||||
# define png_debug1(l,m,p1) \
|
||||
{ \
|
||||
int num_tabs=l; \
|
||||
fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
|
||||
(num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \
|
||||
}
|
||||
# endif
|
||||
# ifndef png_debug2
|
||||
# define png_debug2(l,m,p1,p2) \
|
||||
{ \
|
||||
int num_tabs=l; \
|
||||
fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
|
||||
(num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \
|
||||
}
|
||||
# endif
|
||||
# else /* __STDC __ */
|
||||
# ifndef png_debug
|
||||
# define png_debug(l,m) \
|
||||
{ \
|
||||
int num_tabs=l; \
|
||||
char format[256]; \
|
||||
snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
|
||||
(num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
|
||||
m,PNG_STRING_NEWLINE); \
|
||||
fprintf(PNG_DEBUG_FILE,format); \
|
||||
}
|
||||
# endif
|
||||
# ifndef png_debug1
|
||||
# define png_debug1(l,m,p1) \
|
||||
{ \
|
||||
int num_tabs=l; \
|
||||
char format[256]; \
|
||||
snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
|
||||
(num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
|
||||
m,PNG_STRING_NEWLINE); \
|
||||
fprintf(PNG_DEBUG_FILE,format,p1); \
|
||||
}
|
||||
# endif
|
||||
# ifndef png_debug2
|
||||
# define png_debug2(l,m,p1,p2) \
|
||||
{ \
|
||||
int num_tabs=l; \
|
||||
char format[256]; \
|
||||
snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
|
||||
(num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
|
||||
m,PNG_STRING_NEWLINE); \
|
||||
fprintf(PNG_DEBUG_FILE,format,p1,p2); \
|
||||
}
|
||||
# endif
|
||||
# endif /* __STDC __ */
|
||||
#endif /* (PNG_DEBUG > 1) */
|
||||
|
||||
#endif /* _MSC_VER */
|
||||
#endif /* (PNG_DEBUG > 0) */
|
||||
#endif /* PNG_DEBUG */
|
||||
#ifndef png_debug
|
||||
#define png_debug(l, m)
|
||||
#endif
|
||||
#ifndef png_debug1
|
||||
#define png_debug1(l, m, p1)
|
||||
#endif
|
||||
#ifndef png_debug2
|
||||
#define png_debug2(l, m, p1, p2)
|
||||
#endif
|
||||
|
||||
/* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PNG_VERSION_INFO_ONLY */
|
||||
#endif /* PNGPRIV_H */
|
1361
thirdparty/libpng/pngread.c
vendored
Normal file
1361
thirdparty/libpng/pngread.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
163
thirdparty/libpng/pngrio.c
vendored
Normal file
163
thirdparty/libpng/pngrio.c
vendored
Normal file
@ -0,0 +1,163 @@
|
||||
|
||||
/* pngrio.c - functions for data input
|
||||
*
|
||||
* Last changed in libpng 1.4.1 [February 25, 2010]
|
||||
* Copyright (c) 1998-2010 Glenn Randers-Pehrson
|
||||
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
|
||||
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*
|
||||
* This file provides a location for all input. Users who need
|
||||
* special handling are expected to write a function that has the same
|
||||
* arguments as this and performs a similar function, but that possibly
|
||||
* has a different input method. Note that you shouldn't change this
|
||||
* function, but rather write a replacement function and then make
|
||||
* libpng use it at run time with png_set_read_fn(...).
|
||||
*/
|
||||
|
||||
#define PNG_NO_PEDANTIC_WARNINGS
|
||||
#include "png.h"
|
||||
#ifdef PNG_READ_SUPPORTED
|
||||
#include "pngpriv.h"
|
||||
|
||||
/* Read the data from whatever input you are using. The default routine
|
||||
* reads from a file pointer. Note that this routine sometimes gets called
|
||||
* with very small lengths, so you should implement some kind of simple
|
||||
* buffering if you are using unbuffered reads. This should never be asked
|
||||
* to read more then 64K on a 16 bit machine.
|
||||
*/
|
||||
void /* PRIVATE */
|
||||
png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
{
|
||||
png_debug1(4, "reading %d bytes", (int)length);
|
||||
|
||||
if (png_ptr->read_data_fn != NULL)
|
||||
(*(png_ptr->read_data_fn))(png_ptr, data, length);
|
||||
else
|
||||
png_error(png_ptr, "Call to NULL read function");
|
||||
}
|
||||
|
||||
#ifdef PNG_STDIO_SUPPORTED
|
||||
/* This is the function that does the actual reading of data. If you are
|
||||
* not reading from a standard C stream, you should create a replacement
|
||||
* read_data function and use it at run time with png_set_read_fn(), rather
|
||||
* than changing the library.
|
||||
*/
|
||||
#ifndef USE_FAR_KEYWORD
|
||||
void PNGAPI
|
||||
png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
{
|
||||
png_size_t check;
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
/* fread() returns 0 on error, so it is OK to store this in a png_size_t
|
||||
* instead of an int, which is what fread() actually returns.
|
||||
*/
|
||||
check = fread(data, 1, length, (png_FILE_p)png_ptr->io_ptr);
|
||||
|
||||
if (check != length)
|
||||
png_error(png_ptr, "Read Error");
|
||||
}
|
||||
#else
|
||||
/* This is the model-independent version. Since the standard I/O library
|
||||
can't handle far buffers in the medium and small models, we have to copy
|
||||
the data.
|
||||
*/
|
||||
|
||||
#define NEAR_BUF_SIZE 1024
|
||||
#define MIN(a,b) (a <= b ? a : b)
|
||||
|
||||
static void PNGAPI
|
||||
png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
{
|
||||
png_size_t check;
|
||||
png_byte *n_data;
|
||||
png_FILE_p io_ptr;
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
/* Check if data really is near. If so, use usual code. */
|
||||
n_data = (png_byte *)CVT_PTR_NOCHECK(data);
|
||||
io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
|
||||
if ((png_bytep)n_data == data)
|
||||
{
|
||||
check = fread(n_data, 1, length, io_ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
png_byte buf[NEAR_BUF_SIZE];
|
||||
png_size_t read, remaining, err;
|
||||
check = 0;
|
||||
remaining = length;
|
||||
do
|
||||
{
|
||||
read = MIN(NEAR_BUF_SIZE, remaining);
|
||||
err = fread(buf, 1, read, io_ptr);
|
||||
png_memcpy(data, buf, read); /* copy far buffer to near buffer */
|
||||
if (err != read)
|
||||
break;
|
||||
else
|
||||
check += err;
|
||||
data += read;
|
||||
remaining -= read;
|
||||
}
|
||||
while (remaining != 0);
|
||||
}
|
||||
if ((png_uint_32)check != (png_uint_32)length)
|
||||
png_error(png_ptr, "read Error");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* This function allows the application to supply a new input function
|
||||
* for libpng if standard C streams aren't being used.
|
||||
*
|
||||
* This function takes as its arguments:
|
||||
* png_ptr - pointer to a png input data structure
|
||||
* io_ptr - pointer to user supplied structure containing info about
|
||||
* the input functions. May be NULL.
|
||||
* read_data_fn - pointer to a new input function that takes as its
|
||||
* arguments a pointer to a png_struct, a pointer to
|
||||
* a location where input data can be stored, and a 32-bit
|
||||
* unsigned int that is the number of bytes to be read.
|
||||
* To exit and output any fatal error messages the new write
|
||||
* function should call png_error(png_ptr, "Error msg").
|
||||
* May be NULL, in which case libpng's default function will
|
||||
* be used.
|
||||
*/
|
||||
void PNGAPI
|
||||
png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
|
||||
png_rw_ptr read_data_fn)
|
||||
{
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
png_ptr->io_ptr = io_ptr;
|
||||
|
||||
#ifdef PNG_STDIO_SUPPORTED
|
||||
if (read_data_fn != NULL)
|
||||
png_ptr->read_data_fn = read_data_fn;
|
||||
else
|
||||
png_ptr->read_data_fn = png_default_read_data;
|
||||
#else
|
||||
png_ptr->read_data_fn = read_data_fn;
|
||||
#endif
|
||||
|
||||
/* It is an error to write to a read device */
|
||||
if (png_ptr->write_data_fn != NULL)
|
||||
{
|
||||
png_ptr->write_data_fn = NULL;
|
||||
png_warning(png_ptr,
|
||||
"It's an error to set both read_data_fn and write_data_fn in the ");
|
||||
png_warning(png_ptr,
|
||||
"same structure. Resetting write_data_fn to NULL");
|
||||
}
|
||||
|
||||
#ifdef PNG_WRITE_FLUSH_SUPPORTED
|
||||
png_ptr->output_flush_fn = NULL;
|
||||
#endif
|
||||
}
|
||||
#endif /* PNG_READ_SUPPORTED */
|
4203
thirdparty/libpng/pngrtran.c
vendored
Normal file
4203
thirdparty/libpng/pngrtran.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3379
thirdparty/libpng/pngrutil.c
vendored
Normal file
3379
thirdparty/libpng/pngrutil.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1167
thirdparty/libpng/pngset.c
vendored
Normal file
1167
thirdparty/libpng/pngset.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1632
thirdparty/libpng/pngtest.c
vendored
Normal file
1632
thirdparty/libpng/pngtest.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
677
thirdparty/libpng/pngtrans.c
vendored
Normal file
677
thirdparty/libpng/pngtrans.c
vendored
Normal file
@ -0,0 +1,677 @@
|
||||
|
||||
/* pngtrans.c - transforms the data in a row (used by both readers and writers)
|
||||
*
|
||||
* Last changed in libpng 1.4.2 [April 29, 2010]
|
||||
* Copyright (c) 1998-2010 Glenn Randers-Pehrson
|
||||
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
|
||||
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*/
|
||||
|
||||
#define PNG_NO_PEDANTIC_WARNINGS
|
||||
#include "png.h"
|
||||
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
|
||||
#include "pngpriv.h"
|
||||
|
||||
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
|
||||
/* Turn on BGR-to-RGB mapping */
|
||||
void PNGAPI
|
||||
png_set_bgr(png_structp png_ptr)
|
||||
{
|
||||
png_debug(1, "in png_set_bgr");
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
png_ptr->transformations |= PNG_BGR;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
|
||||
/* Turn on 16 bit byte swapping */
|
||||
void PNGAPI
|
||||
png_set_swap(png_structp png_ptr)
|
||||
{
|
||||
png_debug(1, "in png_set_swap");
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
if (png_ptr->bit_depth == 16)
|
||||
png_ptr->transformations |= PNG_SWAP_BYTES;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
|
||||
/* Turn on pixel packing */
|
||||
void PNGAPI
|
||||
png_set_packing(png_structp png_ptr)
|
||||
{
|
||||
png_debug(1, "in png_set_packing");
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
if (png_ptr->bit_depth < 8)
|
||||
{
|
||||
png_ptr->transformations |= PNG_PACK;
|
||||
png_ptr->usr_bit_depth = 8;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
|
||||
/* Turn on packed pixel swapping */
|
||||
void PNGAPI
|
||||
png_set_packswap(png_structp png_ptr)
|
||||
{
|
||||
png_debug(1, "in png_set_packswap");
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
if (png_ptr->bit_depth < 8)
|
||||
png_ptr->transformations |= PNG_PACKSWAP;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
|
||||
void PNGAPI
|
||||
png_set_shift(png_structp png_ptr, png_color_8p true_bits)
|
||||
{
|
||||
png_debug(1, "in png_set_shift");
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
png_ptr->transformations |= PNG_SHIFT;
|
||||
png_ptr->shift = *true_bits;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
|
||||
defined(PNG_WRITE_INTERLACING_SUPPORTED)
|
||||
int PNGAPI
|
||||
png_set_interlace_handling(png_structp png_ptr)
|
||||
{
|
||||
png_debug(1, "in png_set_interlace handling");
|
||||
|
||||
if (png_ptr && png_ptr->interlaced)
|
||||
{
|
||||
png_ptr->transformations |= PNG_INTERLACE;
|
||||
return (7);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
|
||||
/* Add a filler byte on read, or remove a filler or alpha byte on write.
|
||||
* The filler type has changed in v0.95 to allow future 2-byte fillers
|
||||
* for 48-bit input data, as well as to avoid problems with some compilers
|
||||
* that don't like bytes as parameters.
|
||||
*/
|
||||
void PNGAPI
|
||||
png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
|
||||
{
|
||||
png_debug(1, "in png_set_filler");
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
png_ptr->transformations |= PNG_FILLER;
|
||||
png_ptr->filler = (png_uint_16)filler;
|
||||
if (filler_loc == PNG_FILLER_AFTER)
|
||||
png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
|
||||
else
|
||||
png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
|
||||
|
||||
/* This should probably go in the "do_read_filler" routine.
|
||||
* I attempted to do that in libpng-1.0.1a but that caused problems
|
||||
* so I restored it in libpng-1.0.2a
|
||||
*/
|
||||
|
||||
if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
|
||||
{
|
||||
png_ptr->usr_channels = 4;
|
||||
}
|
||||
|
||||
/* Also I added this in libpng-1.0.2a (what happens when we expand
|
||||
* a less-than-8-bit grayscale to GA? */
|
||||
|
||||
if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
|
||||
{
|
||||
png_ptr->usr_channels = 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Added to libpng-1.2.7 */
|
||||
void PNGAPI
|
||||
png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
|
||||
{
|
||||
png_debug(1, "in png_set_add_alpha");
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
png_set_filler(png_ptr, filler, filler_loc);
|
||||
png_ptr->transformations |= PNG_ADD_ALPHA;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
|
||||
defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
|
||||
void PNGAPI
|
||||
png_set_swap_alpha(png_structp png_ptr)
|
||||
{
|
||||
png_debug(1, "in png_set_swap_alpha");
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
png_ptr->transformations |= PNG_SWAP_ALPHA;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
|
||||
defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
|
||||
void PNGAPI
|
||||
png_set_invert_alpha(png_structp png_ptr)
|
||||
{
|
||||
png_debug(1, "in png_set_invert_alpha");
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
png_ptr->transformations |= PNG_INVERT_ALPHA;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
|
||||
void PNGAPI
|
||||
png_set_invert_mono(png_structp png_ptr)
|
||||
{
|
||||
png_debug(1, "in png_set_invert_mono");
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
png_ptr->transformations |= PNG_INVERT_MONO;
|
||||
}
|
||||
|
||||
/* Invert monochrome grayscale data */
|
||||
void /* PRIVATE */
|
||||
png_do_invert(png_row_infop row_info, png_bytep row)
|
||||
{
|
||||
png_debug(1, "in png_do_invert");
|
||||
|
||||
/* This test removed from libpng version 1.0.13 and 1.2.0:
|
||||
* if (row_info->bit_depth == 1 &&
|
||||
*/
|
||||
if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
|
||||
{
|
||||
png_bytep rp = row;
|
||||
png_uint_32 i;
|
||||
png_uint_32 istop = row_info->rowbytes;
|
||||
|
||||
for (i = 0; i < istop; i++)
|
||||
{
|
||||
*rp = (png_byte)(~(*rp));
|
||||
rp++;
|
||||
}
|
||||
}
|
||||
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
|
||||
row_info->bit_depth == 8)
|
||||
{
|
||||
png_bytep rp = row;
|
||||
png_uint_32 i;
|
||||
png_uint_32 istop = row_info->rowbytes;
|
||||
|
||||
for (i = 0; i < istop; i+=2)
|
||||
{
|
||||
*rp = (png_byte)(~(*rp));
|
||||
rp+=2;
|
||||
}
|
||||
}
|
||||
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
|
||||
row_info->bit_depth == 16)
|
||||
{
|
||||
png_bytep rp = row;
|
||||
png_uint_32 i;
|
||||
png_uint_32 istop = row_info->rowbytes;
|
||||
|
||||
for (i = 0; i < istop; i+=4)
|
||||
{
|
||||
*rp = (png_byte)(~(*rp));
|
||||
*(rp+1) = (png_byte)(~(*(rp+1)));
|
||||
rp+=4;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
|
||||
/* Swaps byte order on 16 bit depth images */
|
||||
void /* PRIVATE */
|
||||
png_do_swap(png_row_infop row_info, png_bytep row)
|
||||
{
|
||||
png_debug(1, "in png_do_swap");
|
||||
|
||||
if (
|
||||
row_info->bit_depth == 16)
|
||||
{
|
||||
png_bytep rp = row;
|
||||
png_uint_32 i;
|
||||
png_uint_32 istop= row_info->width * row_info->channels;
|
||||
|
||||
for (i = 0; i < istop; i++, rp += 2)
|
||||
{
|
||||
png_byte t = *rp;
|
||||
*rp = *(rp + 1);
|
||||
*(rp + 1) = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
|
||||
static PNG_CONST png_byte onebppswaptable[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 PNG_CONST png_byte twobppswaptable[256] = {
|
||||
0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
|
||||
0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
|
||||
0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
|
||||
0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
|
||||
0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
|
||||
0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
|
||||
0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
|
||||
0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
|
||||
0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
|
||||
0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
|
||||
0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
|
||||
0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
|
||||
0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
|
||||
0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
|
||||
0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
|
||||
0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
|
||||
0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
|
||||
0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
|
||||
0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
|
||||
0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
|
||||
0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
|
||||
0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
|
||||
0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
|
||||
0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
|
||||
0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
|
||||
0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
|
||||
0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
|
||||
0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
|
||||
0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
|
||||
0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
|
||||
0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
|
||||
0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
|
||||
};
|
||||
|
||||
static PNG_CONST png_byte fourbppswaptable[256] = {
|
||||
0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
|
||||
0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
|
||||
0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
|
||||
0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
|
||||
0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
|
||||
0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
|
||||
0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
|
||||
0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
|
||||
0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
|
||||
0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
|
||||
0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
|
||||
0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
|
||||
0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
|
||||
0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
|
||||
0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
|
||||
0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
|
||||
0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
|
||||
0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
|
||||
0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
|
||||
0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
|
||||
0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
|
||||
0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
|
||||
0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
|
||||
0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
|
||||
0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
|
||||
0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
|
||||
0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
|
||||
0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
|
||||
0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
|
||||
0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
|
||||
0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
|
||||
0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
|
||||
};
|
||||
|
||||
/* Swaps pixel packing order within bytes */
|
||||
void /* PRIVATE */
|
||||
png_do_packswap(png_row_infop row_info, png_bytep row)
|
||||
{
|
||||
png_debug(1, "in png_do_packswap");
|
||||
|
||||
if (
|
||||
row_info->bit_depth < 8)
|
||||
{
|
||||
png_bytep rp, end, table;
|
||||
|
||||
end = row + row_info->rowbytes;
|
||||
|
||||
if (row_info->bit_depth == 1)
|
||||
table = (png_bytep)onebppswaptable;
|
||||
else if (row_info->bit_depth == 2)
|
||||
table = (png_bytep)twobppswaptable;
|
||||
else if (row_info->bit_depth == 4)
|
||||
table = (png_bytep)fourbppswaptable;
|
||||
else
|
||||
return;
|
||||
|
||||
for (rp = row; rp < end; rp++)
|
||||
*rp = table[*rp];
|
||||
}
|
||||
}
|
||||
#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
|
||||
|
||||
#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
|
||||
defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
|
||||
/* Remove filler or alpha byte(s) */
|
||||
void /* PRIVATE */
|
||||
png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
|
||||
{
|
||||
png_debug(1, "in png_do_strip_filler");
|
||||
|
||||
{
|
||||
png_bytep sp=row;
|
||||
png_bytep dp=row;
|
||||
png_uint_32 row_width=row_info->width;
|
||||
png_uint_32 i;
|
||||
|
||||
if ((row_info->color_type == PNG_COLOR_TYPE_RGB ||
|
||||
(row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
|
||||
(flags & PNG_FLAG_STRIP_ALPHA))) &&
|
||||
row_info->channels == 4)
|
||||
{
|
||||
if (row_info->bit_depth == 8)
|
||||
{
|
||||
/* This converts from RGBX or RGBA to RGB */
|
||||
if (flags & PNG_FLAG_FILLER_AFTER)
|
||||
{
|
||||
dp+=3; sp+=4;
|
||||
for (i = 1; i < row_width; i++)
|
||||
{
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
sp++;
|
||||
}
|
||||
}
|
||||
/* This converts from XRGB or ARGB to RGB */
|
||||
else
|
||||
{
|
||||
for (i = 0; i < row_width; i++)
|
||||
{
|
||||
sp++;
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
}
|
||||
}
|
||||
row_info->pixel_depth = 24;
|
||||
row_info->rowbytes = row_width * 3;
|
||||
}
|
||||
else /* if (row_info->bit_depth == 16) */
|
||||
{
|
||||
if (flags & PNG_FLAG_FILLER_AFTER)
|
||||
{
|
||||
/* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
|
||||
sp += 8; dp += 6;
|
||||
for (i = 1; i < row_width; i++)
|
||||
{
|
||||
/* This could be (although png_memcpy is probably slower):
|
||||
png_memcpy(dp, sp, 6);
|
||||
sp += 8;
|
||||
dp += 6;
|
||||
*/
|
||||
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
sp += 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
|
||||
for (i = 0; i < row_width; i++)
|
||||
{
|
||||
/* This could be (although png_memcpy is probably slower):
|
||||
png_memcpy(dp, sp, 6);
|
||||
sp += 8;
|
||||
dp += 6;
|
||||
*/
|
||||
|
||||
sp+=2;
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
}
|
||||
}
|
||||
row_info->pixel_depth = 48;
|
||||
row_info->rowbytes = row_width * 6;
|
||||
}
|
||||
row_info->channels = 3;
|
||||
}
|
||||
else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY ||
|
||||
(row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
|
||||
(flags & PNG_FLAG_STRIP_ALPHA))) &&
|
||||
row_info->channels == 2)
|
||||
{
|
||||
if (row_info->bit_depth == 8)
|
||||
{
|
||||
/* This converts from GX or GA to G */
|
||||
if (flags & PNG_FLAG_FILLER_AFTER)
|
||||
{
|
||||
for (i = 0; i < row_width; i++)
|
||||
{
|
||||
*dp++ = *sp++;
|
||||
sp++;
|
||||
}
|
||||
}
|
||||
/* This converts from XG or AG to G */
|
||||
else
|
||||
{
|
||||
for (i = 0; i < row_width; i++)
|
||||
{
|
||||
sp++;
|
||||
*dp++ = *sp++;
|
||||
}
|
||||
}
|
||||
row_info->pixel_depth = 8;
|
||||
row_info->rowbytes = row_width;
|
||||
}
|
||||
else /* if (row_info->bit_depth == 16) */
|
||||
{
|
||||
if (flags & PNG_FLAG_FILLER_AFTER)
|
||||
{
|
||||
/* This converts from GGXX or GGAA to GG */
|
||||
sp += 4; dp += 2;
|
||||
for (i = 1; i < row_width; i++)
|
||||
{
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
sp += 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This converts from XXGG or AAGG to GG */
|
||||
for (i = 0; i < row_width; i++)
|
||||
{
|
||||
sp += 2;
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
}
|
||||
}
|
||||
row_info->pixel_depth = 16;
|
||||
row_info->rowbytes = row_width * 2;
|
||||
}
|
||||
row_info->channels = 1;
|
||||
}
|
||||
if (flags & PNG_FLAG_STRIP_ALPHA)
|
||||
row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
|
||||
/* Swaps red and blue bytes within a pixel */
|
||||
void /* PRIVATE */
|
||||
png_do_bgr(png_row_infop row_info, png_bytep row)
|
||||
{
|
||||
png_debug(1, "in png_do_bgr");
|
||||
|
||||
if (
|
||||
(row_info->color_type & PNG_COLOR_MASK_COLOR))
|
||||
{
|
||||
png_uint_32 row_width = row_info->width;
|
||||
if (row_info->bit_depth == 8)
|
||||
{
|
||||
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
|
||||
{
|
||||
png_bytep rp;
|
||||
png_uint_32 i;
|
||||
|
||||
for (i = 0, rp = row; i < row_width; i++, rp += 3)
|
||||
{
|
||||
png_byte save = *rp;
|
||||
*rp = *(rp + 2);
|
||||
*(rp + 2) = save;
|
||||
}
|
||||
}
|
||||
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
||||
{
|
||||
png_bytep rp;
|
||||
png_uint_32 i;
|
||||
|
||||
for (i = 0, rp = row; i < row_width; i++, rp += 4)
|
||||
{
|
||||
png_byte save = *rp;
|
||||
*rp = *(rp + 2);
|
||||
*(rp + 2) = save;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (row_info->bit_depth == 16)
|
||||
{
|
||||
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
|
||||
{
|
||||
png_bytep rp;
|
||||
png_uint_32 i;
|
||||
|
||||
for (i = 0, rp = row; i < row_width; i++, rp += 6)
|
||||
{
|
||||
png_byte save = *rp;
|
||||
*rp = *(rp + 4);
|
||||
*(rp + 4) = save;
|
||||
save = *(rp + 1);
|
||||
*(rp + 1) = *(rp + 5);
|
||||
*(rp + 5) = save;
|
||||
}
|
||||
}
|
||||
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
||||
{
|
||||
png_bytep rp;
|
||||
png_uint_32 i;
|
||||
|
||||
for (i = 0, rp = row; i < row_width; i++, rp += 8)
|
||||
{
|
||||
png_byte save = *rp;
|
||||
*rp = *(rp + 4);
|
||||
*(rp + 4) = save;
|
||||
save = *(rp + 1);
|
||||
*(rp + 1) = *(rp + 5);
|
||||
*(rp + 5) = save;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
|
||||
|
||||
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
|
||||
defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
|
||||
void PNGAPI
|
||||
png_set_user_transform_info(png_structp png_ptr, png_voidp
|
||||
user_transform_ptr, int user_transform_depth, int user_transform_channels)
|
||||
{
|
||||
png_debug(1, "in png_set_user_transform_info");
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
|
||||
png_ptr->user_transform_ptr = user_transform_ptr;
|
||||
png_ptr->user_transform_depth = (png_byte)user_transform_depth;
|
||||
png_ptr->user_transform_channels = (png_byte)user_transform_channels;
|
||||
#else
|
||||
if (user_transform_ptr || user_transform_depth || user_transform_channels)
|
||||
png_warning(png_ptr,
|
||||
"This version of libpng does not support user transform info");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* This function returns a pointer to the user_transform_ptr associated with
|
||||
* the user transform functions. The application should free any memory
|
||||
* associated with this pointer before png_write_destroy and png_read_destroy
|
||||
* are called.
|
||||
*/
|
||||
png_voidp PNGAPI
|
||||
png_get_user_transform_ptr(png_structp png_ptr)
|
||||
{
|
||||
if (png_ptr == NULL)
|
||||
return (NULL);
|
||||
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
|
||||
return ((png_voidp)png_ptr->user_transform_ptr);
|
||||
#else
|
||||
return (NULL);
|
||||
#endif
|
||||
}
|
||||
#endif /* PNG_READ_USER_TRANSFORM_SUPPORTED ||
|
||||
PNG_WRITE_USER_TRANSFORM_SUPPORTED */
|
||||
#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
|
241
thirdparty/libpng/pngwio.c
vendored
Normal file
241
thirdparty/libpng/pngwio.c
vendored
Normal file
@ -0,0 +1,241 @@
|
||||
|
||||
/* pngwio.c - functions for data output
|
||||
*
|
||||
* Last changed in libpng 1.4.0 [January 3, 2010]
|
||||
* Copyright (c) 1998-2010 Glenn Randers-Pehrson
|
||||
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
|
||||
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*
|
||||
* This file provides a location for all output. Users who need
|
||||
* special handling are expected to write functions that have the same
|
||||
* arguments as these and perform similar functions, but that possibly
|
||||
* use different output methods. Note that you shouldn't change these
|
||||
* functions, but rather write replacement functions and then change
|
||||
* them at run time with png_set_write_fn(...).
|
||||
*/
|
||||
|
||||
#define PNG_NO_PEDANTIC_WARNINGS
|
||||
#include "png.h"
|
||||
#ifdef PNG_WRITE_SUPPORTED
|
||||
#include "pngpriv.h"
|
||||
|
||||
/* Write the data to whatever output you are using. The default routine
|
||||
* writes to a file pointer. Note that this routine sometimes gets called
|
||||
* with very small lengths, so you should implement some kind of simple
|
||||
* buffering if you are using unbuffered writes. This should never be asked
|
||||
* to write more than 64K on a 16 bit machine.
|
||||
*/
|
||||
|
||||
void /* PRIVATE */
|
||||
png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
{
|
||||
if (png_ptr->write_data_fn != NULL )
|
||||
(*(png_ptr->write_data_fn))(png_ptr, data, length);
|
||||
else
|
||||
png_error(png_ptr, "Call to NULL write function");
|
||||
}
|
||||
|
||||
#ifdef PNG_STDIO_SUPPORTED
|
||||
/* This is the function that does the actual writing of data. If you are
|
||||
* not writing to a standard C stream, you should create a replacement
|
||||
* write_data function and use it at run time with png_set_write_fn(), rather
|
||||
* than changing the library.
|
||||
*/
|
||||
#ifndef USE_FAR_KEYWORD
|
||||
void PNGAPI
|
||||
png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
{
|
||||
png_uint_32 check;
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr));
|
||||
if (check != length)
|
||||
png_error(png_ptr, "Write Error");
|
||||
}
|
||||
#else
|
||||
/* This is the model-independent version. Since the standard I/O library
|
||||
* can't handle far buffers in the medium and small models, we have to copy
|
||||
* the data.
|
||||
*/
|
||||
|
||||
#define NEAR_BUF_SIZE 1024
|
||||
#define MIN(a,b) (a <= b ? a : b)
|
||||
|
||||
void PNGAPI
|
||||
png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
{
|
||||
png_uint_32 check;
|
||||
png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */
|
||||
png_FILE_p io_ptr;
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
/* Check if data really is near. If so, use usual code. */
|
||||
near_data = (png_byte *)CVT_PTR_NOCHECK(data);
|
||||
io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
|
||||
if ((png_bytep)near_data == data)
|
||||
{
|
||||
check = fwrite(near_data, 1, length, io_ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
png_byte buf[NEAR_BUF_SIZE];
|
||||
png_size_t written, remaining, err;
|
||||
check = 0;
|
||||
remaining = length;
|
||||
do
|
||||
{
|
||||
written = MIN(NEAR_BUF_SIZE, remaining);
|
||||
png_memcpy(buf, data, written); /* Copy far buffer to near buffer */
|
||||
err = fwrite(buf, 1, written, io_ptr);
|
||||
if (err != written)
|
||||
break;
|
||||
|
||||
else
|
||||
check += err;
|
||||
|
||||
data += written;
|
||||
remaining -= written;
|
||||
}
|
||||
while (remaining != 0);
|
||||
}
|
||||
if (check != length)
|
||||
png_error(png_ptr, "Write Error");
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* This function is called to output any data pending writing (normally
|
||||
* to disk). After png_flush is called, there should be no data pending
|
||||
* writing in any buffers.
|
||||
*/
|
||||
#ifdef PNG_WRITE_FLUSH_SUPPORTED
|
||||
void /* PRIVATE */
|
||||
png_flush(png_structp png_ptr)
|
||||
{
|
||||
if (png_ptr->output_flush_fn != NULL)
|
||||
(*(png_ptr->output_flush_fn))(png_ptr);
|
||||
}
|
||||
|
||||
#ifdef PNG_STDIO_SUPPORTED
|
||||
void PNGAPI
|
||||
png_default_flush(png_structp png_ptr)
|
||||
{
|
||||
png_FILE_p io_ptr;
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr));
|
||||
fflush(io_ptr);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* This function allows the application to supply new output functions for
|
||||
* libpng if standard C streams aren't being used.
|
||||
*
|
||||
* This function takes as its arguments:
|
||||
* png_ptr - pointer to a png output data structure
|
||||
* io_ptr - pointer to user supplied structure containing info about
|
||||
* the output functions. May be NULL.
|
||||
* write_data_fn - pointer to a new output function that takes as its
|
||||
* arguments a pointer to a png_struct, a pointer to
|
||||
* data to be written, and a 32-bit unsigned int that is
|
||||
* the number of bytes to be written. The new write
|
||||
* function should call png_error(png_ptr, "Error msg")
|
||||
* to exit and output any fatal error messages. May be
|
||||
* NULL, in which case libpng's default function will
|
||||
* be used.
|
||||
* flush_data_fn - pointer to a new flush function that takes as its
|
||||
* arguments a pointer to a png_struct. After a call to
|
||||
* the flush function, there should be no data in any buffers
|
||||
* or pending transmission. If the output method doesn't do
|
||||
* any buffering of output, a function prototype must still be
|
||||
* supplied although it doesn't have to do anything. If
|
||||
* PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile
|
||||
* time, output_flush_fn will be ignored, although it must be
|
||||
* supplied for compatibility. May be NULL, in which case
|
||||
* libpng's default function will be used, if
|
||||
* PNG_WRITE_FLUSH_SUPPORTED is defined. This is not
|
||||
* a good idea if io_ptr does not point to a standard
|
||||
* *FILE structure.
|
||||
*/
|
||||
void PNGAPI
|
||||
png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
|
||||
png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
|
||||
{
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
|
||||
png_ptr->io_ptr = io_ptr;
|
||||
|
||||
#ifdef PNG_STDIO_SUPPORTED
|
||||
if (write_data_fn != NULL)
|
||||
png_ptr->write_data_fn = write_data_fn;
|
||||
|
||||
else
|
||||
png_ptr->write_data_fn = png_default_write_data;
|
||||
#else
|
||||
png_ptr->write_data_fn = write_data_fn;
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_FLUSH_SUPPORTED
|
||||
#ifdef PNG_STDIO_SUPPORTED
|
||||
if (output_flush_fn != NULL)
|
||||
png_ptr->output_flush_fn = output_flush_fn;
|
||||
|
||||
else
|
||||
png_ptr->output_flush_fn = png_default_flush;
|
||||
#else
|
||||
png_ptr->output_flush_fn = output_flush_fn;
|
||||
#endif
|
||||
#endif /* PNG_WRITE_FLUSH_SUPPORTED */
|
||||
|
||||
/* It is an error to read while writing a png file */
|
||||
if (png_ptr->read_data_fn != NULL)
|
||||
{
|
||||
png_ptr->read_data_fn = NULL;
|
||||
png_warning(png_ptr,
|
||||
"Attempted to set both read_data_fn and write_data_fn in");
|
||||
png_warning(png_ptr,
|
||||
"the same structure. Resetting read_data_fn to NULL");
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_FAR_KEYWORD
|
||||
#ifdef _MSC_VER
|
||||
void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check)
|
||||
{
|
||||
void *near_ptr;
|
||||
void FAR *far_ptr;
|
||||
FP_OFF(near_ptr) = FP_OFF(ptr);
|
||||
far_ptr = (void FAR *)near_ptr;
|
||||
|
||||
if (check != 0)
|
||||
if (FP_SEG(ptr) != FP_SEG(far_ptr))
|
||||
png_error(png_ptr, "segment lost in conversion");
|
||||
|
||||
return(near_ptr);
|
||||
}
|
||||
# else
|
||||
void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check)
|
||||
{
|
||||
void *near_ptr;
|
||||
void FAR *far_ptr;
|
||||
near_ptr = (void FAR *)ptr;
|
||||
far_ptr = (void FAR *)near_ptr;
|
||||
|
||||
if (check != 0)
|
||||
if (far_ptr != ptr)
|
||||
png_error(png_ptr, "segment lost in conversion");
|
||||
|
||||
return(near_ptr);
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
#endif /* PNG_WRITE_SUPPORTED */
|
1457
thirdparty/libpng/pngwrite.c
vendored
Normal file
1457
thirdparty/libpng/pngwrite.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
566
thirdparty/libpng/pngwtran.c
vendored
Normal file
566
thirdparty/libpng/pngwtran.c
vendored
Normal file
@ -0,0 +1,566 @@
|
||||
|
||||
/* pngwtran.c - transforms the data in a row for PNG writers
|
||||
*
|
||||
* Last changed in libpng 1.4.1 [February 25, 2010]
|
||||
* Copyright (c) 1998-2010 Glenn Randers-Pehrson
|
||||
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
|
||||
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*/
|
||||
|
||||
#define PNG_NO_PEDANTIC_WARNINGS
|
||||
#include "png.h"
|
||||
#ifdef PNG_WRITE_SUPPORTED
|
||||
#include "pngpriv.h"
|
||||
|
||||
/* Transform the data according to the user's wishes. The order of
|
||||
* transformations is significant.
|
||||
*/
|
||||
void /* PRIVATE */
|
||||
png_do_write_transformations(png_structp png_ptr)
|
||||
{
|
||||
png_debug(1, "in png_do_write_transformations");
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
|
||||
#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
|
||||
if (png_ptr->transformations & PNG_USER_TRANSFORM)
|
||||
if (png_ptr->write_user_transform_fn != NULL)
|
||||
(*(png_ptr->write_user_transform_fn)) /* User write transform
|
||||
function */
|
||||
(png_ptr, /* png_ptr */
|
||||
&(png_ptr->row_info), /* row_info: */
|
||||
/* png_uint_32 width; width of row */
|
||||
/* png_uint_32 rowbytes; number of bytes in row */
|
||||
/* png_byte color_type; color type of pixels */
|
||||
/* png_byte bit_depth; bit depth of samples */
|
||||
/* png_byte channels; number of channels (1-4) */
|
||||
/* png_byte pixel_depth; bits per pixel (depth*channels) */
|
||||
png_ptr->row_buf + 1); /* start of pixel data for row */
|
||||
#endif
|
||||
#ifdef PNG_WRITE_FILLER_SUPPORTED
|
||||
if (png_ptr->transformations & PNG_FILLER)
|
||||
png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
|
||||
png_ptr->flags);
|
||||
#endif
|
||||
#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
|
||||
if (png_ptr->transformations & PNG_PACKSWAP)
|
||||
png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
|
||||
#endif
|
||||
#ifdef PNG_WRITE_PACK_SUPPORTED
|
||||
if (png_ptr->transformations & PNG_PACK)
|
||||
png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1,
|
||||
(png_uint_32)png_ptr->bit_depth);
|
||||
#endif
|
||||
#ifdef PNG_WRITE_SWAP_SUPPORTED
|
||||
if (png_ptr->transformations & PNG_SWAP_BYTES)
|
||||
png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
|
||||
#endif
|
||||
#ifdef PNG_WRITE_SHIFT_SUPPORTED
|
||||
if (png_ptr->transformations & PNG_SHIFT)
|
||||
png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1,
|
||||
&(png_ptr->shift));
|
||||
#endif
|
||||
#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
|
||||
if (png_ptr->transformations & PNG_SWAP_ALPHA)
|
||||
png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
|
||||
#endif
|
||||
#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
|
||||
if (png_ptr->transformations & PNG_INVERT_ALPHA)
|
||||
png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
|
||||
#endif
|
||||
#ifdef PNG_WRITE_BGR_SUPPORTED
|
||||
if (png_ptr->transformations & PNG_BGR)
|
||||
png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
|
||||
#endif
|
||||
#ifdef PNG_WRITE_INVERT_SUPPORTED
|
||||
if (png_ptr->transformations & PNG_INVERT_MONO)
|
||||
png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef PNG_WRITE_PACK_SUPPORTED
|
||||
/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The
|
||||
* row_info bit depth should be 8 (one pixel per byte). The channels
|
||||
* should be 1 (this only happens on grayscale and paletted images).
|
||||
*/
|
||||
void /* PRIVATE */
|
||||
png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
|
||||
{
|
||||
png_debug(1, "in png_do_pack");
|
||||
|
||||
if (row_info->bit_depth == 8 &&
|
||||
row_info->channels == 1)
|
||||
{
|
||||
switch ((int)bit_depth)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
png_bytep sp, dp;
|
||||
int mask, v;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
|
||||
sp = row;
|
||||
dp = row;
|
||||
mask = 0x80;
|
||||
v = 0;
|
||||
|
||||
for (i = 0; i < row_width; i++)
|
||||
{
|
||||
if (*sp != 0)
|
||||
v |= mask;
|
||||
sp++;
|
||||
if (mask > 1)
|
||||
mask >>= 1;
|
||||
else
|
||||
{
|
||||
mask = 0x80;
|
||||
*dp = (png_byte)v;
|
||||
dp++;
|
||||
v = 0;
|
||||
}
|
||||
}
|
||||
if (mask != 0x80)
|
||||
*dp = (png_byte)v;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
png_bytep sp, dp;
|
||||
int shift, v;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
|
||||
sp = row;
|
||||
dp = row;
|
||||
shift = 6;
|
||||
v = 0;
|
||||
for (i = 0; i < row_width; i++)
|
||||
{
|
||||
png_byte value;
|
||||
|
||||
value = (png_byte)(*sp & 0x03);
|
||||
v |= (value << shift);
|
||||
if (shift == 0)
|
||||
{
|
||||
shift = 6;
|
||||
*dp = (png_byte)v;
|
||||
dp++;
|
||||
v = 0;
|
||||
}
|
||||
else
|
||||
shift -= 2;
|
||||
sp++;
|
||||
}
|
||||
if (shift != 6)
|
||||
*dp = (png_byte)v;
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
png_bytep sp, dp;
|
||||
int shift, v;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
|
||||
sp = row;
|
||||
dp = row;
|
||||
shift = 4;
|
||||
v = 0;
|
||||
for (i = 0; i < row_width; i++)
|
||||
{
|
||||
png_byte value;
|
||||
|
||||
value = (png_byte)(*sp & 0x0f);
|
||||
v |= (value << shift);
|
||||
|
||||
if (shift == 0)
|
||||
{
|
||||
shift = 4;
|
||||
*dp = (png_byte)v;
|
||||
dp++;
|
||||
v = 0;
|
||||
}
|
||||
else
|
||||
shift -= 4;
|
||||
|
||||
sp++;
|
||||
}
|
||||
if (shift != 4)
|
||||
*dp = (png_byte)v;
|
||||
break;
|
||||
}
|
||||
}
|
||||
row_info->bit_depth = (png_byte)bit_depth;
|
||||
row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
|
||||
row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
|
||||
row_info->width);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_SHIFT_SUPPORTED
|
||||
/* Shift pixel values to take advantage of whole range. Pass the
|
||||
* true number of bits in bit_depth. The row should be packed
|
||||
* according to row_info->bit_depth. Thus, if you had a row of
|
||||
* bit depth 4, but the pixels only had values from 0 to 7, you
|
||||
* would pass 3 as bit_depth, and this routine would translate the
|
||||
* data to 0 to 15.
|
||||
*/
|
||||
void /* PRIVATE */
|
||||
png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
|
||||
{
|
||||
png_debug(1, "in png_do_shift");
|
||||
|
||||
if (
|
||||
row_info->color_type != PNG_COLOR_TYPE_PALETTE)
|
||||
{
|
||||
int shift_start[4], shift_dec[4];
|
||||
int channels = 0;
|
||||
|
||||
if (row_info->color_type & PNG_COLOR_MASK_COLOR)
|
||||
{
|
||||
shift_start[channels] = row_info->bit_depth - bit_depth->red;
|
||||
shift_dec[channels] = bit_depth->red;
|
||||
channels++;
|
||||
shift_start[channels] = row_info->bit_depth - bit_depth->green;
|
||||
shift_dec[channels] = bit_depth->green;
|
||||
channels++;
|
||||
shift_start[channels] = row_info->bit_depth - bit_depth->blue;
|
||||
shift_dec[channels] = bit_depth->blue;
|
||||
channels++;
|
||||
}
|
||||
else
|
||||
{
|
||||
shift_start[channels] = row_info->bit_depth - bit_depth->gray;
|
||||
shift_dec[channels] = bit_depth->gray;
|
||||
channels++;
|
||||
}
|
||||
if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
|
||||
{
|
||||
shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
|
||||
shift_dec[channels] = bit_depth->alpha;
|
||||
channels++;
|
||||
}
|
||||
|
||||
/* With low row depths, could only be grayscale, so one channel */
|
||||
if (row_info->bit_depth < 8)
|
||||
{
|
||||
png_bytep bp = row;
|
||||
png_uint_32 i;
|
||||
png_byte mask;
|
||||
png_uint_32 row_bytes = row_info->rowbytes;
|
||||
|
||||
if (bit_depth->gray == 1 && row_info->bit_depth == 2)
|
||||
mask = 0x55;
|
||||
else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
|
||||
mask = 0x11;
|
||||
else
|
||||
mask = 0xff;
|
||||
|
||||
for (i = 0; i < row_bytes; i++, bp++)
|
||||
{
|
||||
png_uint_16 v;
|
||||
int j;
|
||||
|
||||
v = *bp;
|
||||
*bp = 0;
|
||||
for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
|
||||
{
|
||||
if (j > 0)
|
||||
*bp |= (png_byte)((v << j) & 0xff);
|
||||
else
|
||||
*bp |= (png_byte)((v >> (-j)) & mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (row_info->bit_depth == 8)
|
||||
{
|
||||
png_bytep bp = row;
|
||||
png_uint_32 i;
|
||||
png_uint_32 istop = channels * row_info->width;
|
||||
|
||||
for (i = 0; i < istop; i++, bp++)
|
||||
{
|
||||
|
||||
png_uint_16 v;
|
||||
int j;
|
||||
int c = (int)(i%channels);
|
||||
|
||||
v = *bp;
|
||||
*bp = 0;
|
||||
for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
|
||||
{
|
||||
if (j > 0)
|
||||
*bp |= (png_byte)((v << j) & 0xff);
|
||||
else
|
||||
*bp |= (png_byte)((v >> (-j)) & 0xff);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
png_bytep bp;
|
||||
png_uint_32 i;
|
||||
png_uint_32 istop = channels * row_info->width;
|
||||
|
||||
for (bp = row, i = 0; i < istop; i++)
|
||||
{
|
||||
int c = (int)(i%channels);
|
||||
png_uint_16 value, v;
|
||||
int j;
|
||||
|
||||
v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
|
||||
value = 0;
|
||||
for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
|
||||
{
|
||||
if (j > 0)
|
||||
value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
|
||||
else
|
||||
value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
|
||||
}
|
||||
*bp++ = (png_byte)(value >> 8);
|
||||
*bp++ = (png_byte)(value & 0xff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
|
||||
void /* PRIVATE */
|
||||
png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
|
||||
{
|
||||
png_debug(1, "in png_do_write_swap_alpha");
|
||||
|
||||
{
|
||||
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
||||
{
|
||||
/* This converts from ARGB to RGBA */
|
||||
if (row_info->bit_depth == 8)
|
||||
{
|
||||
png_bytep sp, dp;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
for (i = 0, sp = dp = row; i < row_width; i++)
|
||||
{
|
||||
png_byte save = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = save;
|
||||
}
|
||||
}
|
||||
/* This converts from AARRGGBB to RRGGBBAA */
|
||||
else
|
||||
{
|
||||
png_bytep sp, dp;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
|
||||
for (i = 0, sp = dp = row; i < row_width; i++)
|
||||
{
|
||||
png_byte save[2];
|
||||
save[0] = *(sp++);
|
||||
save[1] = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = save[0];
|
||||
*(dp++) = save[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
{
|
||||
/* This converts from AG to GA */
|
||||
if (row_info->bit_depth == 8)
|
||||
{
|
||||
png_bytep sp, dp;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
|
||||
for (i = 0, sp = dp = row; i < row_width; i++)
|
||||
{
|
||||
png_byte save = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = save;
|
||||
}
|
||||
}
|
||||
/* This converts from AAGG to GGAA */
|
||||
else
|
||||
{
|
||||
png_bytep sp, dp;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
|
||||
for (i = 0, sp = dp = row; i < row_width; i++)
|
||||
{
|
||||
png_byte save[2];
|
||||
save[0] = *(sp++);
|
||||
save[1] = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = save[0];
|
||||
*(dp++) = save[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
|
||||
void /* PRIVATE */
|
||||
png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
|
||||
{
|
||||
png_debug(1, "in png_do_write_invert_alpha");
|
||||
|
||||
{
|
||||
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
||||
{
|
||||
/* This inverts the alpha channel in RGBA */
|
||||
if (row_info->bit_depth == 8)
|
||||
{
|
||||
png_bytep sp, dp;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
for (i = 0, sp = dp = row; i < row_width; i++)
|
||||
{
|
||||
/* Does nothing
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*/
|
||||
sp+=3; dp = sp;
|
||||
*(dp++) = (png_byte)(255 - *(sp++));
|
||||
}
|
||||
}
|
||||
/* This inverts the alpha channel in RRGGBBAA */
|
||||
else
|
||||
{
|
||||
png_bytep sp, dp;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
|
||||
for (i = 0, sp = dp = row; i < row_width; i++)
|
||||
{
|
||||
/* Does nothing
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*/
|
||||
sp+=6; dp = sp;
|
||||
*(dp++) = (png_byte)(255 - *(sp++));
|
||||
*(dp++) = (png_byte)(255 - *(sp++));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
{
|
||||
/* This inverts the alpha channel in GA */
|
||||
if (row_info->bit_depth == 8)
|
||||
{
|
||||
png_bytep sp, dp;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
|
||||
for (i = 0, sp = dp = row; i < row_width; i++)
|
||||
{
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = (png_byte)(255 - *(sp++));
|
||||
}
|
||||
}
|
||||
/* This inverts the alpha channel in GGAA */
|
||||
else
|
||||
{
|
||||
png_bytep sp, dp;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
|
||||
for (i = 0, sp = dp = row; i < row_width; i++)
|
||||
{
|
||||
/* Does nothing
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*/
|
||||
sp+=2; dp = sp;
|
||||
*(dp++) = (png_byte)(255 - *(sp++));
|
||||
*(dp++) = (png_byte)(255 - *(sp++));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_MNG_FEATURES_SUPPORTED
|
||||
/* Undoes intrapixel differencing */
|
||||
void /* PRIVATE */
|
||||
png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
|
||||
{
|
||||
png_debug(1, "in png_do_write_intrapixel");
|
||||
|
||||
if (
|
||||
(row_info->color_type & PNG_COLOR_MASK_COLOR))
|
||||
{
|
||||
int bytes_per_pixel;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
if (row_info->bit_depth == 8)
|
||||
{
|
||||
png_bytep rp;
|
||||
png_uint_32 i;
|
||||
|
||||
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
|
||||
bytes_per_pixel = 3;
|
||||
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
||||
bytes_per_pixel = 4;
|
||||
else
|
||||
return;
|
||||
|
||||
for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
|
||||
{
|
||||
*(rp) = (png_byte)((*rp - *(rp+1))&0xff);
|
||||
*(rp+2) = (png_byte)((*(rp+2) - *(rp+1))&0xff);
|
||||
}
|
||||
}
|
||||
else if (row_info->bit_depth == 16)
|
||||
{
|
||||
png_bytep rp;
|
||||
png_uint_32 i;
|
||||
|
||||
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
|
||||
bytes_per_pixel = 6;
|
||||
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
||||
bytes_per_pixel = 8;
|
||||
else
|
||||
return;
|
||||
|
||||
for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
|
||||
{
|
||||
png_uint_32 s0 = (*(rp ) << 8) | *(rp+1);
|
||||
png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3);
|
||||
png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5);
|
||||
png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL);
|
||||
png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
|
||||
*(rp ) = (png_byte)((red >> 8) & 0xff);
|
||||
*(rp+1) = (png_byte)(red & 0xff);
|
||||
*(rp+4) = (png_byte)((blue >> 8) & 0xff);
|
||||
*(rp+5) = (png_byte)(blue & 0xff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* PNG_MNG_FEATURES_SUPPORTED */
|
||||
#endif /* PNG_WRITE_SUPPORTED */
|
2786
thirdparty/libpng/pngwutil.c
vendored
Normal file
2786
thirdparty/libpng/pngwutil.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
79
thirdparty/libtiff/CMakeLists.txt
vendored
Normal file
79
thirdparty/libtiff/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,79 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
|
||||
project(libtiff C)
|
||||
|
||||
INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
#
|
||||
ADD_DEFINITIONS(-DHAVE_STRING_H=1)
|
||||
|
||||
SET(TARGET_FILES
|
||||
t4.h
|
||||
tiffiop.h
|
||||
tif_aux.c
|
||||
tif_close.c
|
||||
tif_codec.c
|
||||
tif_color.c
|
||||
tif_compress.c
|
||||
tif_dir.c
|
||||
tif_dir.h
|
||||
tif_dirinfo.c
|
||||
tif_dirread.c
|
||||
tif_dirwrite.c
|
||||
tif_dumpmode.c
|
||||
tif_error.c
|
||||
tif_extension.c
|
||||
tif_fax3.c
|
||||
tif_fax3.h
|
||||
tif_fax3sm.c
|
||||
tif_flush.c
|
||||
tif_getimage.c
|
||||
tif_jbig.c
|
||||
tif_jpeg.c
|
||||
tif_luv.c
|
||||
tif_lzw.c
|
||||
tif_next.c
|
||||
tif_ojpeg.c
|
||||
tif_open.c
|
||||
tif_packbits.c
|
||||
tif_pixarlog.c
|
||||
tif_predict.c
|
||||
tif_predict.h
|
||||
tif_print.c
|
||||
tif_read.c
|
||||
tif_stream.cxx
|
||||
tif_strip.c
|
||||
tif_swab.c
|
||||
tif_thunder.c
|
||||
tif_tile.c
|
||||
tif_version.c
|
||||
tif_warning.c
|
||||
tif_write.c
|
||||
tif_zip.c
|
||||
uvcode.h
|
||||
)
|
||||
|
||||
IF(UNIX)
|
||||
SET(TARGET_FILES ${TARGET_FILES} tif_unix.c)
|
||||
ENDIF()
|
||||
|
||||
IF(WIN32)
|
||||
SET(TARGET_FILES ${TARGET_FILES} tif_win32.c)
|
||||
ENDIF(WIN32)
|
||||
|
||||
#IF(APPLE)
|
||||
# SET(TARGET_FILES ${TARGET_FILES} tif_apple.c)
|
||||
#ENDIF(APPLE)
|
||||
|
||||
SET(LIBTARGET "tiff")
|
||||
#
|
||||
ADD_LIBRARY(${LIBTARGET} STATIC ${TARGET_FILES})
|
||||
#
|
||||
IF(MSVC)
|
||||
SET_TARGET_PROPERTIES(${LIBTARGET} PROPERTIES PREFIX "lib")
|
||||
ENDIF(MSVC)
|
||||
#
|
||||
SET_TARGET_PROPERTIES(${LIBTARGET}
|
||||
PROPERTIES
|
||||
OUTPUT_NAME "${LIBTARGET}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/thirdparty/lib
|
||||
)
|
||||
#
|
292
thirdparty/libtiff/t4.h
vendored
Normal file
292
thirdparty/libtiff/t4.h
vendored
Normal file
@ -0,0 +1,292 @@
|
||||
/* $Id: t4.h,v 1.1.1.1.2.1 2010-06-08 18:50:41 bfriesen Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that (i) the above copyright notices and this permission notice appear in
|
||||
* all copies of the software and related documentation, and (ii) the names of
|
||||
* Sam Leffler and Silicon Graphics may not be used in any advertising or
|
||||
* publicity relating to the software without the specific, prior written
|
||||
* permission of Sam Leffler and Silicon Graphics.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
||||
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
|
||||
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
||||
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
||||
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#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_ */
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 8
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
281
thirdparty/libtiff/tif_apple.c
vendored
Normal file
281
thirdparty/libtiff/tif_apple.c
vendored
Normal file
@ -0,0 +1,281 @@
|
||||
/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/Attic/tif_apple.c,v 1.3.2.1 2010-06-08 18:50:41 bfriesen Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that (i) the above copyright notices and this permission notice appear in
|
||||
* all copies of the software and related documentation, and (ii) the names of
|
||||
* Sam Leffler and Silicon Graphics may not be used in any advertising or
|
||||
* publicity relating to the software without the specific, prior written
|
||||
* permission of Sam Leffler and Silicon Graphics.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
||||
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
|
||||
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
||||
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
||||
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TIFF Library Macintosh-specific routines.
|
||||
*
|
||||
* These routines use only Toolbox and high-level File Manager traps.
|
||||
* They make no calls to the THINK C "unix" compatibility library. Also,
|
||||
* malloc is not used directly but it is still referenced internally by
|
||||
* the ANSI library in rare cases. Heap fragmentation by the malloc ring
|
||||
* buffer is therefore minimized.
|
||||
*
|
||||
* O_RDONLY and O_RDWR are treated identically here. The tif_mode flag is
|
||||
* checked in TIFFWriteCheck().
|
||||
*
|
||||
* Create below fills in a blank creator signature and sets the file type
|
||||
* to 'TIFF'. It is much better for the application to do this by Create'ing
|
||||
* the file first and TIFFOpen'ing it later.
|
||||
* ---------
|
||||
* This code has been "Carbonized", and may not work with older MacOS versions.
|
||||
* If so, grab the tif_apple.c out of an older libtiff distribution, like
|
||||
* 3.5.5 from www.libtiff.org.
|
||||
*/
|
||||
|
||||
#include "tiffiop.h"
|
||||
#include <Errors.h>
|
||||
#include <Files.h>
|
||||
#include <Memory.h>
|
||||
#include <Script.h>
|
||||
|
||||
#if defined(__PPCC__) || defined(__SC__) || defined(__MRC__) || defined(applec)
|
||||
#define CtoPstr c2pstr
|
||||
#endif
|
||||
|
||||
static tsize_t
|
||||
_tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size)
|
||||
{
|
||||
return (FSRead((short) fd, (long*) &size, (char*) buf) == noErr ?
|
||||
size : (tsize_t) -1);
|
||||
}
|
||||
|
||||
static tsize_t
|
||||
_tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size)
|
||||
{
|
||||
return (FSWrite((short) fd, (long*) &size, (char*) buf) == noErr ?
|
||||
size : (tsize_t) -1);
|
||||
}
|
||||
|
||||
static toff_t
|
||||
_tiffSeekProc(thandle_t fd, toff_t off, int whence)
|
||||
{
|
||||
long fpos, size;
|
||||
|
||||
if (GetEOF((short) fd, &size) != noErr)
|
||||
return EOF;
|
||||
(void) GetFPos((short) fd, &fpos);
|
||||
|
||||
switch (whence) {
|
||||
case SEEK_CUR:
|
||||
if (off + fpos > size)
|
||||
SetEOF((short) fd, off + fpos);
|
||||
if (SetFPos((short) fd, fsFromMark, off) != noErr)
|
||||
return EOF;
|
||||
break;
|
||||
case SEEK_END:
|
||||
if (off > 0)
|
||||
SetEOF((short) fd, off + size);
|
||||
if (SetFPos((short) fd, fsFromStart, off + size) != noErr)
|
||||
return EOF;
|
||||
break;
|
||||
case SEEK_SET:
|
||||
if (off > size)
|
||||
SetEOF((short) fd, off);
|
||||
if (SetFPos((short) fd, fsFromStart, off) != noErr)
|
||||
return EOF;
|
||||
break;
|
||||
}
|
||||
|
||||
return (toff_t)(GetFPos((short) fd, &fpos) == noErr ? fpos : EOF);
|
||||
}
|
||||
|
||||
static int
|
||||
_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
_tiffCloseProc(thandle_t fd)
|
||||
{
|
||||
return (FSClose((short) fd));
|
||||
}
|
||||
|
||||
static toff_t
|
||||
_tiffSizeProc(thandle_t fd)
|
||||
{
|
||||
long size;
|
||||
|
||||
if (GetEOF((short) fd, &size) != noErr) {
|
||||
TIFFErrorExt(fd, "_tiffSizeProc", "%s: Cannot get file size");
|
||||
return (-1L);
|
||||
}
|
||||
return ((toff_t) size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Open a TIFF file descriptor for read/writing.
|
||||
*/
|
||||
TIFF*
|
||||
TIFFFdOpen(int fd, const char* name, const char* mode)
|
||||
{
|
||||
TIFF* tif;
|
||||
|
||||
tif = TIFFClientOpen(name, mode, (thandle_t) fd,
|
||||
_tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc,
|
||||
_tiffSizeProc, _tiffMapProc, _tiffUnmapProc);
|
||||
if (tif)
|
||||
tif->tif_fd = fd;
|
||||
return (tif);
|
||||
}
|
||||
|
||||
static void ourc2pstr( char* inString )
|
||||
{
|
||||
int sLen = strlen( inString );
|
||||
BlockMoveData( inString, &inString[1], sLen );
|
||||
inString[0] = sLen;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open a TIFF file for read/writing.
|
||||
*/
|
||||
TIFF*
|
||||
TIFFOpen(const char* name, const char* mode)
|
||||
{
|
||||
static const char module[] = "TIFFOpen";
|
||||
Str255 pname;
|
||||
FInfo finfo;
|
||||
short fref;
|
||||
OSErr err;
|
||||
FSSpec fSpec;
|
||||
|
||||
strcpy((char*) pname, name);
|
||||
ourc2pstr((char*) pname);
|
||||
|
||||
err = FSMakeFSSpec( 0, 0, pname, &fSpec );
|
||||
|
||||
switch (_TIFFgetMode(mode, module)) {
|
||||
default:
|
||||
return ((TIFF*) 0);
|
||||
case O_RDWR | O_CREAT | O_TRUNC:
|
||||
if (FSpGetFInfo(&fSpec, &finfo) == noErr)
|
||||
FSpDelete(&fSpec);
|
||||
/* fall through */
|
||||
case O_RDWR | O_CREAT:
|
||||
if ((err = FSpGetFInfo(&fSpec, &finfo)) == fnfErr) {
|
||||
if (FSpCreate(&fSpec, ' ', 'TIFF', smSystemScript) != noErr)
|
||||
goto badCreate;
|
||||
if (FSpOpenDF(&fSpec, fsRdWrPerm, &fref) != noErr)
|
||||
goto badOpen;
|
||||
} else if (err == noErr) {
|
||||
if (FSpOpenDF(&fSpec, fsRdWrPerm, &fref) != noErr)
|
||||
goto badOpen;
|
||||
} else
|
||||
goto badOpen;
|
||||
break;
|
||||
case O_RDONLY:
|
||||
if (FSpOpenDF(&fSpec, fsRdPerm, &fref) != noErr)
|
||||
goto badOpen;
|
||||
break;
|
||||
case O_RDWR:
|
||||
if (FSpOpenDF(&fSpec, fsRdWrPerm, &fref) != noErr)
|
||||
goto badOpen;
|
||||
break;
|
||||
}
|
||||
return (TIFFFdOpen((int) fref, name, mode));
|
||||
badCreate:
|
||||
TIFFErrorExt(0, module, "%s: Cannot create", name);
|
||||
return ((TIFF*) 0);
|
||||
badOpen:
|
||||
TIFFErrorExt(0, module, "%s: Cannot open", name);
|
||||
return ((TIFF*) 0);
|
||||
}
|
||||
|
||||
void
|
||||
_TIFFmemset(tdata_t p, int v, tsize_t c)
|
||||
{
|
||||
memset(p, v, (size_t) c);
|
||||
}
|
||||
|
||||
void
|
||||
_TIFFmemcpy(tdata_t d, const tdata_t s, tsize_t c)
|
||||
{
|
||||
memcpy(d, s, (size_t) c);
|
||||
}
|
||||
|
||||
int
|
||||
_TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c)
|
||||
{
|
||||
return (memcmp(p1, p2, (size_t) c));
|
||||
}
|
||||
|
||||
tdata_t
|
||||
_TIFFmalloc(tsize_t s)
|
||||
{
|
||||
return (NewPtr((size_t) s));
|
||||
}
|
||||
|
||||
void
|
||||
_TIFFfree(tdata_t p)
|
||||
{
|
||||
DisposePtr(p);
|
||||
}
|
||||
|
||||
tdata_t
|
||||
_TIFFrealloc(tdata_t p, tsize_t s)
|
||||
{
|
||||
Ptr n = p;
|
||||
|
||||
SetPtrSize(p, (size_t) s);
|
||||
if (MemError() && (n = NewPtr((size_t) s)) != NULL) {
|
||||
BlockMove(p, n, GetPtrSize(p));
|
||||
DisposePtr(p);
|
||||
}
|
||||
return ((tdata_t) n);
|
||||
}
|
||||
|
||||
static void
|
||||
appleWarningHandler(const char* module, const char* fmt, va_list ap)
|
||||
{
|
||||
if (module != NULL)
|
||||
fprintf(stderr, "%s: ", module);
|
||||
fprintf(stderr, "Warning, ");
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fprintf(stderr, ".\n");
|
||||
}
|
||||
TIFFErrorHandler _TIFFwarningHandler = appleWarningHandler;
|
||||
|
||||
static void
|
||||
appleErrorHandler(const char* module, const char* fmt, va_list ap)
|
||||
{
|
||||
if (module != NULL)
|
||||
fprintf(stderr, "%s: ", module);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fprintf(stderr, ".\n");
|
||||
}
|
||||
TIFFErrorHandler _TIFFerrorHandler = appleErrorHandler;
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 8
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
290
thirdparty/libtiff/tif_aux.c
vendored
Normal file
290
thirdparty/libtiff/tif_aux.c
vendored
Normal file
@ -0,0 +1,290 @@
|
||||
/* $Id: tif_aux.c,v 1.20.2.3 2010-06-09 21:15:27 bfriesen Exp $ */
|
||||
|
||||
/*
|
||||
* 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 "tiffiop.h"
|
||||
#include "tif_predict.h"
|
||||
#include <math.h>
|
||||
|
||||
tdata_t
|
||||
_TIFFCheckRealloc(TIFF* tif, tdata_t buffer,
|
||||
size_t nmemb, size_t elem_size, const char* what)
|
||||
{
|
||||
tdata_t cp = NULL;
|
||||
tsize_t bytes = nmemb * elem_size;
|
||||
|
||||
/*
|
||||
* XXX: Check for integer overflow.
|
||||
*/
|
||||
if (nmemb && elem_size && bytes / elem_size == nmemb)
|
||||
cp = _TIFFrealloc(buffer, bytes);
|
||||
|
||||
if (cp == NULL)
|
||||
TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
|
||||
"Failed to allocate memory for %s "
|
||||
"(%ld elements of %ld bytes each)",
|
||||
what,(long) nmemb, (long) elem_size);
|
||||
|
||||
return cp;
|
||||
}
|
||||
|
||||
tdata_t
|
||||
_TIFFCheckMalloc(TIFF* tif, size_t nmemb, size_t elem_size, const char* what)
|
||||
{
|
||||
return _TIFFCheckRealloc(tif, NULL, nmemb, elem_size, what);
|
||||
}
|
||||
|
||||
static int
|
||||
TIFFDefaultTransferFunction(TIFFDirectory* td)
|
||||
{
|
||||
uint16 **tf = td->td_transferfunction;
|
||||
tsize_t i, n, nbytes;
|
||||
|
||||
tf[0] = tf[1] = tf[2] = 0;
|
||||
if (td->td_bitspersample >= sizeof(tsize_t) * 8 - 2)
|
||||
return 0;
|
||||
|
||||
n = 1<<td->td_bitspersample;
|
||||
nbytes = n * sizeof (uint16);
|
||||
if (!(tf[0] = (uint16 *)_TIFFmalloc(nbytes)))
|
||||
return 0;
|
||||
tf[0][0] = 0;
|
||||
for (i = 1; i < n; i++) {
|
||||
double t = (double)i/((double) n-1.);
|
||||
tf[0][i] = (uint16)floor(65535.*pow(t, 2.2) + .5);
|
||||
}
|
||||
|
||||
if (td->td_samplesperpixel - td->td_extrasamples > 1) {
|
||||
if (!(tf[1] = (uint16 *)_TIFFmalloc(nbytes)))
|
||||
goto bad;
|
||||
_TIFFmemcpy(tf[1], tf[0], nbytes);
|
||||
if (!(tf[2] = (uint16 *)_TIFFmalloc(nbytes)))
|
||||
goto bad;
|
||||
_TIFFmemcpy(tf[2], tf[0], nbytes);
|
||||
}
|
||||
return 1;
|
||||
|
||||
bad:
|
||||
if (tf[0])
|
||||
_TIFFfree(tf[0]);
|
||||
if (tf[1])
|
||||
_TIFFfree(tf[1]);
|
||||
if (tf[2])
|
||||
_TIFFfree(tf[2]);
|
||||
tf[0] = tf[1] = tf[2] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
TIFFDefaultRefBlackWhite(TIFFDirectory* td)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!(td->td_refblackwhite = (float *)_TIFFmalloc(6*sizeof (float))))
|
||||
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
|
||||
* explcit values so that defaults exist only one
|
||||
* place in the library -- in TIFFDefaultDirectory.
|
||||
*/
|
||||
int
|
||||
TIFFVGetFieldDefaulted(TIFF* tif, ttag_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 *) = td->td_subfiletype;
|
||||
return (1);
|
||||
case TIFFTAG_BITSPERSAMPLE:
|
||||
*va_arg(ap, uint16 *) = td->td_bitspersample;
|
||||
return (1);
|
||||
case TIFFTAG_THRESHHOLDING:
|
||||
*va_arg(ap, uint16 *) = td->td_threshholding;
|
||||
return (1);
|
||||
case TIFFTAG_FILLORDER:
|
||||
*va_arg(ap, uint16 *) = td->td_fillorder;
|
||||
return (1);
|
||||
case TIFFTAG_ORIENTATION:
|
||||
*va_arg(ap, uint16 *) = td->td_orientation;
|
||||
return (1);
|
||||
case TIFFTAG_SAMPLESPERPIXEL:
|
||||
*va_arg(ap, uint16 *) = td->td_samplesperpixel;
|
||||
return (1);
|
||||
case TIFFTAG_ROWSPERSTRIP:
|
||||
*va_arg(ap, uint32 *) = td->td_rowsperstrip;
|
||||
return (1);
|
||||
case TIFFTAG_MINSAMPLEVALUE:
|
||||
*va_arg(ap, uint16 *) = td->td_minsamplevalue;
|
||||
return (1);
|
||||
case TIFFTAG_MAXSAMPLEVALUE:
|
||||
*va_arg(ap, uint16 *) = td->td_maxsamplevalue;
|
||||
return (1);
|
||||
case TIFFTAG_PLANARCONFIG:
|
||||
*va_arg(ap, uint16 *) = td->td_planarconfig;
|
||||
return (1);
|
||||
case TIFFTAG_RESOLUTIONUNIT:
|
||||
*va_arg(ap, uint16 *) = td->td_resolutionunit;
|
||||
return (1);
|
||||
case TIFFTAG_PREDICTOR:
|
||||
{
|
||||
TIFFPredictorState* sp = (TIFFPredictorState*) tif->tif_data;
|
||||
*va_arg(ap, uint16*) = (uint16) sp->predictor;
|
||||
return 1;
|
||||
}
|
||||
case TIFFTAG_DOTRANGE:
|
||||
*va_arg(ap, uint16 *) = 0;
|
||||
*va_arg(ap, uint16 *) = (1<<td->td_bitspersample)-1;
|
||||
return (1);
|
||||
case TIFFTAG_INKSET:
|
||||
*va_arg(ap, uint16 *) = INKSET_CMYK;
|
||||
return 1;
|
||||
case TIFFTAG_NUMBEROFINKS:
|
||||
*va_arg(ap, uint16 *) = 4;
|
||||
return (1);
|
||||
case TIFFTAG_EXTRASAMPLES:
|
||||
*va_arg(ap, uint16 *) = td->td_extrasamples;
|
||||
*va_arg(ap, uint16 **) = td->td_sampleinfo;
|
||||
return (1);
|
||||
case TIFFTAG_MATTEING:
|
||||
*va_arg(ap, uint16 *) =
|
||||
(td->td_extrasamples == 1 &&
|
||||
td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
|
||||
return (1);
|
||||
case TIFFTAG_TILEDEPTH:
|
||||
*va_arg(ap, uint32 *) = td->td_tiledepth;
|
||||
return (1);
|
||||
case TIFFTAG_DATATYPE:
|
||||
*va_arg(ap, uint16 *) = td->td_sampleformat-1;
|
||||
return (1);
|
||||
case TIFFTAG_SAMPLEFORMAT:
|
||||
*va_arg(ap, uint16 *) = td->td_sampleformat;
|
||||
return(1);
|
||||
case TIFFTAG_IMAGEDEPTH:
|
||||
*va_arg(ap, uint32 *) = td->td_imagedepth;
|
||||
return (1);
|
||||
case TIFFTAG_YCBCRCOEFFICIENTS:
|
||||
{
|
||||
/* defaults are from CCIR Recommendation 601-1 */
|
||||
static float ycbcrcoeffs[] = { 0.299f, 0.587f, 0.114f };
|
||||
*va_arg(ap, float **) = ycbcrcoeffs;
|
||||
return 1;
|
||||
}
|
||||
case TIFFTAG_YCBCRSUBSAMPLING:
|
||||
*va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[0];
|
||||
*va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[1];
|
||||
return (1);
|
||||
case TIFFTAG_YCBCRPOSITIONING:
|
||||
*va_arg(ap, uint16 *) = td->td_ycbcrpositioning;
|
||||
return (1);
|
||||
case TIFFTAG_WHITEPOINT:
|
||||
{
|
||||
static float whitepoint[2];
|
||||
|
||||
/* 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. */
|
||||
whitepoint[0] = D50_X0 / (D50_X0 + D50_Y0 + D50_Z0);
|
||||
whitepoint[1] = D50_Y0 / (D50_X0 + D50_Y0 + D50_Z0);
|
||||
*va_arg(ap, float **) = whitepoint;
|
||||
return 1;
|
||||
}
|
||||
case TIFFTAG_TRANSFERFUNCTION:
|
||||
if (!td->td_transferfunction[0] &&
|
||||
!TIFFDefaultTransferFunction(td)) {
|
||||
TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "No space for \"TransferFunction\" tag");
|
||||
return (0);
|
||||
}
|
||||
*va_arg(ap, uint16 **) = td->td_transferfunction[0];
|
||||
if (td->td_samplesperpixel - td->td_extrasamples > 1) {
|
||||
*va_arg(ap, uint16 **) = td->td_transferfunction[1];
|
||||
*va_arg(ap, uint16 **) = td->td_transferfunction[2];
|
||||
}
|
||||
return (1);
|
||||
case TIFFTAG_REFERENCEBLACKWHITE:
|
||||
if (!td->td_refblackwhite && !TIFFDefaultRefBlackWhite(td))
|
||||
return (0);
|
||||
*va_arg(ap, 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, ttag_t tag, ...)
|
||||
{
|
||||
int ok;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, tag);
|
||||
ok = TIFFVGetFieldDefaulted(tif, tag, ap);
|
||||
va_end(ap);
|
||||
return (ok);
|
||||
}
|
||||
|
||||
/* vim: set ts=8 sts=8 sw=8 noet: */
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 8
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
126
thirdparty/libtiff/tif_close.c
vendored
Normal file
126
thirdparty/libtiff/tif_close.c
vendored
Normal file
@ -0,0 +1,126 @@
|
||||
/* $Id: tif_close.c,v 1.10.2.1 2010-06-08 18:50:41 bfriesen Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that (i) the above copyright notices and this permission notice appear in
|
||||
* all copies of the software and related documentation, and (ii) the names of
|
||||
* Sam Leffler and Silicon Graphics may not be used in any advertising or
|
||||
* publicity relating to the software without the specific, prior written
|
||||
* permission of Sam Leffler and Silicon Graphics.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
||||
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
|
||||
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
||||
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
||||
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TIFF Library.
|
||||
*/
|
||||
#include "tiffiop.h"
|
||||
|
||||
/************************************************************************/
|
||||
/* TIFFCleanup() */
|
||||
/************************************************************************/
|
||||
|
||||
/**
|
||||
* Auxiliary function to free the TIFF structure. Given structure will be
|
||||
* completetly 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)
|
||||
{
|
||||
if (tif->tif_mode != O_RDONLY)
|
||||
/*
|
||||
* Flush buffered data and directory (if dirty).
|
||||
*/
|
||||
TIFFFlush(tif);
|
||||
(*tif->tif_cleanup)(tif);
|
||||
TIFFFreeDirectory(tif);
|
||||
|
||||
if (tif->tif_dirlist)
|
||||
_TIFFfree(tif->tif_dirlist);
|
||||
|
||||
/* Clean up client info links */
|
||||
while( tif->tif_clientinfo )
|
||||
{
|
||||
TIFFClientInfoLink *link = tif->tif_clientinfo;
|
||||
|
||||
tif->tif_clientinfo = link->next;
|
||||
_TIFFfree( link->name );
|
||||
_TIFFfree( link );
|
||||
}
|
||||
|
||||
if (tif->tif_rawdata && (tif->tif_flags&TIFF_MYBUFFER))
|
||||
_TIFFfree(tif->tif_rawdata);
|
||||
if (isMapped(tif))
|
||||
TIFFUnmapFileContents(tif, tif->tif_base, tif->tif_size);
|
||||
|
||||
/* Clean up custom fields */
|
||||
if (tif->tif_nfields > 0)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < tif->tif_nfields; i++)
|
||||
{
|
||||
TIFFFieldInfo *fld = tif->tif_fieldinfo[i];
|
||||
if (fld->field_bit == FIELD_CUSTOM &&
|
||||
strncmp("Tag ", fld->field_name, 4) == 0)
|
||||
{
|
||||
_TIFFfree(fld->field_name);
|
||||
_TIFFfree(fld);
|
||||
}
|
||||
}
|
||||
|
||||
_TIFFfree(tif->tif_fieldinfo);
|
||||
}
|
||||
|
||||
_TIFFfree(tif);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* 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)
|
||||
{
|
||||
TIFFCloseProc closeproc = tif->tif_closeproc;
|
||||
thandle_t fd = tif->tif_clientdata;
|
||||
|
||||
TIFFCleanup(tif);
|
||||
(void) (*closeproc)(fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 8
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
160
thirdparty/libtiff/tif_codec.c
vendored
Normal file
160
thirdparty/libtiff/tif_codec.c
vendored
Normal file
@ -0,0 +1,160 @@
|
||||
/* $Id: tif_codec.c,v 1.10.2.2 2010-06-08 18:50:41 bfriesen Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that (i) the above copyright notices and this permission notice appear in
|
||||
* all copies of the software and related documentation, and (ii) the names of
|
||||
* Sam Leffler and Silicon Graphics may not be used in any advertising or
|
||||
* publicity relating to the software without the specific, prior written
|
||||
* permission of Sam Leffler and Silicon Graphics.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
||||
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
|
||||
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
||||
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
||||
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TIFF Library
|
||||
*
|
||||
* 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
|
||||
|
||||
/*
|
||||
* Compression schemes statically built into the library.
|
||||
*/
|
||||
#ifdef VMS
|
||||
const TIFFCodec _TIFFBuiltinCODECS[] = {
|
||||
#else
|
||||
TIFFCodec _TIFFBuiltinCODECS[] = {
|
||||
#endif
|
||||
{ "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 },
|
||||
{ NULL, 0, NULL }
|
||||
};
|
||||
|
||||
static int
|
||||
_notConfigured(TIFF* tif)
|
||||
{
|
||||
const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression);
|
||||
char compression_code[20];
|
||||
|
||||
sprintf( compression_code, "%d", tif->tif_dir.td_compression );
|
||||
TIFFErrorExt(tif->tif_clientdata, 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_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 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 8
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
282
thirdparty/libtiff/tif_color.c
vendored
Normal file
282
thirdparty/libtiff/tif_color.c
vendored
Normal file
@ -0,0 +1,282 @@
|
||||
/* $Id: tif_color.c,v 1.12.2.1 2010-06-08 18:50:41 bfriesen Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that (i) the above copyright notices and this permission notice appear in
|
||||
* all copies of the software and related documentation, and (ii) the names of
|
||||
* Sam Leffler and Silicon Graphics may not be used in any advertising or
|
||||
* publicity relating to the software without the specific, prior written
|
||||
* permission of Sam Leffler and Silicon Graphics.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
||||
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
|
||||
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
||||
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
||||
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 l, int32 a, int32 b,
|
||||
float *X, float *Y, float *Z)
|
||||
{
|
||||
float L = (float)l * 100.0F / 255.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 / 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 / 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)((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 *r, uint32 *g, uint32 *b)
|
||||
{
|
||||
int 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 = (int)((Yr - cielab->display.d_Y0R) / cielab->rstep);
|
||||
i = TIFFmin(cielab->range, i);
|
||||
*r = RINT(cielab->Yr2r[i]);
|
||||
|
||||
i = (int)((Yg - cielab->display.d_Y0G) / cielab->gstep);
|
||||
i = TIFFmin(cielab->range, i);
|
||||
*g = RINT(cielab->Yg2g[i]);
|
||||
|
||||
i = (int)((Yb - cielab->display.d_Y0B) / cielab->bstep);
|
||||
i = TIFFmin(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,
|
||||
TIFFDisplay *display, float *refWhite)
|
||||
{
|
||||
int i;
|
||||
double gamma;
|
||||
|
||||
cielab->range = CIELABTORGB_TABLE_RANGE;
|
||||
|
||||
_TIFFmemcpy(&cielab->display, display, sizeof(TIFFDisplay));
|
||||
|
||||
/* Red */
|
||||
gamma = 1.0 / cielab->display.d_gammaR ;
|
||||
cielab->rstep =
|
||||
(cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
|
||||
for(i = 0; i <= cielab->range; i++) {
|
||||
cielab->Yr2r[i] = cielab->display.d_Vrwr
|
||||
* ((float)pow((double)i / cielab->range, gamma));
|
||||
}
|
||||
|
||||
/* Green */
|
||||
gamma = 1.0 / cielab->display.d_gammaG ;
|
||||
cielab->gstep =
|
||||
(cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
|
||||
for(i = 0; i <= cielab->range; i++) {
|
||||
cielab->Yg2g[i] = cielab->display.d_Vrwg
|
||||
* ((float)pow((double)i / cielab->range, gamma));
|
||||
}
|
||||
|
||||
/* Blue */
|
||||
gamma = 1.0 / cielab->display.d_gammaB ;
|
||||
cielab->bstep =
|
||||
(cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
|
||||
for(i = 0; i <= cielab->range; i++) {
|
||||
cielab->Yb2b[i] = cielab->display.d_Vrwb
|
||||
* ((float)pow((double)i / cielab->range, gamma));
|
||||
}
|
||||
|
||||
/* 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 CIE XYZ.
|
||||
* 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)((x) * (1L<<SHIFT) + 0.5))
|
||||
#define ONE_HALF ((int32)(1<<(SHIFT-1)))
|
||||
#define Code2V(c, RB, RW, CR) ((((c)-(int32)(RB))*(float)(CR))/(float)(((RW)-(RB)) ? ((RW)-(RB)) : 1))
|
||||
#define CLAMP(f,min,max) ((f)<(min)?(min):(f)>(max)?(max):(f))
|
||||
#define HICLAMP(f,max) ((f)>(max)?(max):(f))
|
||||
|
||||
void
|
||||
TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32 Y, int32 Cb, int32 Cr,
|
||||
uint32 *r, uint32 *g, uint32 *b)
|
||||
{
|
||||
/* XXX: Only 8-bit YCbCr input supported for now */
|
||||
Y = HICLAMP(Y, 255), Cb = CLAMP(Cb, 0, 255), Cr = CLAMP(Cr, 0, 255);
|
||||
|
||||
*r = ycbcr->clamptab[ycbcr->Y_tab[Y] + ycbcr->Cr_r_tab[Cr]];
|
||||
*g = ycbcr->clamptab[ycbcr->Y_tab[Y]
|
||||
+ (int)((ycbcr->Cb_g_tab[Cb] + ycbcr->Cr_g_tab[Cr]) >> SHIFT)];
|
||||
*b = ycbcr->clamptab[ycbcr->Y_tab[Y] + ycbcr->Cb_b_tab[Cb]];
|
||||
}
|
||||
|
||||
/*
|
||||
* 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*)(
|
||||
(tidata_t) ycbcr+TIFFroundup(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*) (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 D1 = FIX(f1);
|
||||
float f2 = LumaRed*f1/LumaGreen; int32 D2 = -FIX(f2);
|
||||
float f3 = 2-2*LumaBlue; int32 D3 = FIX(f3);
|
||||
float f4 = LumaBlue*f3/LumaGreen; int32 D4 = -FIX(f4);
|
||||
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 Cr = (int32)Code2V(x, refBlackWhite[4] - 128.0F,
|
||||
refBlackWhite[5] - 128.0F, 127);
|
||||
int32 Cb = (int32)Code2V(x, refBlackWhite[2] - 128.0F,
|
||||
refBlackWhite[3] - 128.0F, 127);
|
||||
|
||||
ycbcr->Cr_r_tab[i] = (int32)((D1*Cr + ONE_HALF)>>SHIFT);
|
||||
ycbcr->Cb_b_tab[i] = (int32)((D3*Cb + ONE_HALF)>>SHIFT);
|
||||
ycbcr->Cr_g_tab[i] = D2*Cr;
|
||||
ycbcr->Cb_g_tab[i] = D4*Cb + ONE_HALF;
|
||||
ycbcr->Y_tab[i] =
|
||||
(int32)Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#undef HICLAMP
|
||||
#undef CLAMP
|
||||
#undef Code2V
|
||||
#undef SHIFT
|
||||
#undef ONE_HALF
|
||||
#undef FIX
|
||||
|
||||
/* vim: set ts=8 sts=8 sw=8 noet: */
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 8
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
295
thirdparty/libtiff/tif_compress.c
vendored
Normal file
295
thirdparty/libtiff/tif_compress.c
vendored
Normal file
@ -0,0 +1,295 @@
|
||||
/* $Id: tif_compress.c,v 1.13.2.1 2010-06-08 18:50:41 bfriesen Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that (i) the above copyright notices and this permission notice appear in
|
||||
* all copies of the software and related documentation, and (ii) the names of
|
||||
* Sam Leffler and Silicon Graphics may not be used in any advertising or
|
||||
* publicity relating to the software without the specific, prior written
|
||||
* permission of Sam Leffler and Silicon Graphics.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
||||
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
|
||||
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
||||
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
||||
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TIFF Library
|
||||
*
|
||||
* 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) {
|
||||
TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
|
||||
"%s %s encoding is not implemented",
|
||||
c->name, method);
|
||||
} else {
|
||||
TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
|
||||
"Compression scheme %u %s encoding is not implemented",
|
||||
tif->tif_dir.td_compression, method);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
_TIFFNoRowEncode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s)
|
||||
{
|
||||
(void) pp; (void) cc; (void) s;
|
||||
return (TIFFNoEncode(tif, "scanline"));
|
||||
}
|
||||
|
||||
int
|
||||
_TIFFNoStripEncode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s)
|
||||
{
|
||||
(void) pp; (void) cc; (void) s;
|
||||
return (TIFFNoEncode(tif, "strip"));
|
||||
}
|
||||
|
||||
int
|
||||
_TIFFNoTileEncode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_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)
|
||||
TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
|
||||
"%s %s decoding is not implemented",
|
||||
c->name, method);
|
||||
else
|
||||
TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
|
||||
"Compression scheme %u %s decoding is not implemented",
|
||||
tif->tif_dir.td_compression, method);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
_TIFFNoRowDecode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s)
|
||||
{
|
||||
(void) pp; (void) cc; (void) s;
|
||||
return (TIFFNoDecode(tif, "scanline"));
|
||||
}
|
||||
|
||||
int
|
||||
_TIFFNoStripDecode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s)
|
||||
{
|
||||
(void) pp; (void) cc; (void) s;
|
||||
return (TIFFNoDecode(tif, "strip"));
|
||||
}
|
||||
|
||||
int
|
||||
_TIFFNoTileDecode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s)
|
||||
{
|
||||
(void) pp; (void) cc; (void) s;
|
||||
return (TIFFNoDecode(tif, "tile"));
|
||||
}
|
||||
|
||||
int
|
||||
_TIFFNoSeek(TIFF* tif, uint32 off)
|
||||
{
|
||||
(void) off;
|
||||
TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
|
||||
"Compression algorithm does not support random access");
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_TIFFNoPreCode(TIFF* tif, tsample_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_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) 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 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 scheme, const char* name, TIFFInitMethod init)
|
||||
{
|
||||
codec_t* cd = (codec_t*)
|
||||
_TIFFmalloc(sizeof (codec_t) + sizeof (TIFFCodec) + strlen(name)+1);
|
||||
|
||||
if (cd != NULL) {
|
||||
cd->info = (TIFFCodec*) ((tidata_t) cd + sizeof (codec_t));
|
||||
cd->info->name = (char*)
|
||||
((tidata_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 = ®isteredCODECS; (cd = *pcd); pcd = &cd->next)
|
||||
if (cd->info == c) {
|
||||
*pcd = cd->next;
|
||||
_TIFFfree(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, *new_codecs;
|
||||
|
||||
for (cd = registeredCODECS; cd; cd = cd->next) {
|
||||
new_codecs = (TIFFCodec *)
|
||||
_TIFFrealloc(codecs, i * sizeof(TIFFCodec));
|
||||
if (!new_codecs) {
|
||||
_TIFFfree (codecs);
|
||||
return NULL;
|
||||
}
|
||||
codecs = new_codecs;
|
||||
_TIFFmemcpy(codecs + i - 1, cd, sizeof(TIFFCodec));
|
||||
i++;
|
||||
}
|
||||
for (c = _TIFFBuiltinCODECS; c->name; c++) {
|
||||
if (TIFFIsCODECConfigured(c->scheme)) {
|
||||
new_codecs = (TIFFCodec *)
|
||||
_TIFFrealloc(codecs, i * sizeof(TIFFCodec));
|
||||
if (!new_codecs) {
|
||||
_TIFFfree (codecs);
|
||||
return NULL;
|
||||
}
|
||||
codecs = new_codecs;
|
||||
_TIFFmemcpy(codecs + i - 1, (const tdata_t)c, sizeof(TIFFCodec));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
new_codecs = (TIFFCodec *) _TIFFrealloc(codecs, i * sizeof(TIFFCodec));
|
||||
if (!new_codecs) {
|
||||
_TIFFfree (codecs);
|
||||
return NULL;
|
||||
}
|
||||
codecs = new_codecs;
|
||||
_TIFFmemset(codecs + i - 1, 0, sizeof(TIFFCodec));
|
||||
|
||||
return codecs;
|
||||
}
|
||||
|
||||
/* vim: set ts=8 sts=8 sw=8 noet: */
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 8
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
70
thirdparty/libtiff/tif_config.h
vendored
Normal file
70
thirdparty/libtiff/tif_config.h
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
/* Define to 1 if you have the <assert.h> header file. */
|
||||
#define HAVE_ASSERT_H 1
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Define as 0 or 1 according to the floating point format suported by the
|
||||
machine */
|
||||
#define HAVE_IEEEFP 1
|
||||
|
||||
/* Define to 1 if you have the `jbg_newlen' function. */
|
||||
#define HAVE_JBG_NEWLEN 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <io.h> header file. */
|
||||
#define HAVE_IO_H 1
|
||||
|
||||
/* Define to 1 if you have the <search.h> header file. */
|
||||
#define HAVE_SEARCH_H 1
|
||||
|
||||
/* Define to 1 if you have the `setmode' function. */
|
||||
#define HAVE_SETMODE 1
|
||||
|
||||
/* The size of a `int', as computed by sizeof. */
|
||||
#define SIZEOF_INT 4
|
||||
|
||||
/* The size of a `long', as computed by sizeof. */
|
||||
#define SIZEOF_LONG 4
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* Signed 64-bit type */
|
||||
#define TIFF_INT64_T signed __int64
|
||||
/* Unsigned 64-bit type */
|
||||
#define TIFF_UINT64_T unsigned __int64
|
||||
#else
|
||||
/* Signed 64-bit type */
|
||||
#define TIFF_INT64_T long long
|
||||
/* Signed 64-bit type */
|
||||
#define TIFF_UINT64_T unsigned long long
|
||||
#endif
|
||||
|
||||
/* Set the native cpu bit order */
|
||||
#define HOST_FILLORDER FILLORDER_LSB2MSB
|
||||
|
||||
/* Define to 1 if your processor stores words with the most significant byte
|
||||
first (like Motorola and SPARC, unlike Intel and VAX). */
|
||||
/* #undef WORDS_BIGENDIAN */
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
# ifndef inline
|
||||
# define inline __inline
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define lfind _lfind
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 8
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
1389
thirdparty/libtiff/tif_dir.c
vendored
Normal file
1389
thirdparty/libtiff/tif_dir.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
211
thirdparty/libtiff/tif_dir.h
vendored
Normal file
211
thirdparty/libtiff/tif_dir.h
vendored
Normal file
@ -0,0 +1,211 @@
|
||||
/* $Id: tif_dir.h,v 1.30.2.3 2010-06-09 21:15:27 bfriesen Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that (i) the above copyright notices and this permission notice appear in
|
||||
* all copies of the software and related documentation, and (ii) the names of
|
||||
* Sam Leffler and Silicon Graphics may not be used in any advertising or
|
||||
* publicity relating to the software without the specific, prior written
|
||||
* permission of Sam Leffler and Silicon Graphics.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
||||
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
|
||||
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
||||
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
||||
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _TIFFDIR_
|
||||
#define _TIFFDIR_
|
||||
/*
|
||||
* ``Library-private'' Directory-related Definitions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Internal format of a TIFF directory entry.
|
||||
*/
|
||||
typedef struct {
|
||||
#define FIELD_SETLONGS 4
|
||||
/* bit vector of fields that are set */
|
||||
unsigned long td_fieldsset[FIELD_SETLONGS];
|
||||
|
||||
uint32 td_imagewidth, td_imagelength, td_imagedepth;
|
||||
uint32 td_tilewidth, td_tilelength, td_tiledepth;
|
||||
uint32 td_subfiletype;
|
||||
uint16 td_bitspersample;
|
||||
uint16 td_sampleformat;
|
||||
uint16 td_compression;
|
||||
uint16 td_photometric;
|
||||
uint16 td_threshholding;
|
||||
uint16 td_fillorder;
|
||||
uint16 td_orientation;
|
||||
uint16 td_samplesperpixel;
|
||||
uint32 td_rowsperstrip;
|
||||
uint16 td_minsamplevalue, td_maxsamplevalue;
|
||||
double td_sminsamplevalue, td_smaxsamplevalue;
|
||||
float td_xresolution, td_yresolution;
|
||||
uint16 td_resolutionunit;
|
||||
uint16 td_planarconfig;
|
||||
float td_xposition, td_yposition;
|
||||
uint16 td_pagenumber[2];
|
||||
uint16* td_colormap[3];
|
||||
uint16 td_halftonehints[2];
|
||||
uint16 td_extrasamples;
|
||||
uint16* 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 */
|
||||
tstrile_t td_stripsperimage;
|
||||
tstrile_t td_nstrips; /* size of offset & bytecount arrays */
|
||||
toff_t* td_stripoffset;
|
||||
toff_t* td_stripbytecount; /* FIXME: it should be tsize_t array */
|
||||
int td_stripbytecountsorted; /* is the bytecount array sorted ascending? */
|
||||
uint16 td_nsubifd;
|
||||
uint32* td_subifd;
|
||||
/* YCbCr parameters */
|
||||
uint16 td_ycbcrsubsampling[2];
|
||||
uint16 td_ycbcrpositioning;
|
||||
/* Colorimetry parameters */
|
||||
float* td_refblackwhite;
|
||||
uint16* td_transferfunction[3];
|
||||
/* CMYK parameters */
|
||||
int td_inknameslen;
|
||||
char* td_inknames;
|
||||
|
||||
int td_customValueCount;
|
||||
TIFFTagValue *td_customValues;
|
||||
} 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
|
||||
/* 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*FIELD_SETLONGS-1)
|
||||
|
||||
#define TIFFExtractData(tif, type, v) \
|
||||
((uint32) ((tif)->tif_header.tiff_magic == TIFF_BIGENDIAN ? \
|
||||
((v) >> (tif)->tif_typeshift[type]) & (tif)->tif_typemask[type] : \
|
||||
(v) & (tif)->tif_typemask[type]))
|
||||
#define TIFFInsertData(tif, type, v) \
|
||||
((uint32) ((tif)->tif_header.tiff_magic == TIFF_BIGENDIAN ? \
|
||||
((v) & (tif)->tif_typemask[type]) << (tif)->tif_typeshift[type] : \
|
||||
(v) & (tif)->tif_typemask[type]))
|
||||
|
||||
|
||||
#define BITn(n) (((unsigned long)1L)<<((n)&0x1f))
|
||||
#define BITFIELDn(tif, n) ((tif)->tif_dir.td_fieldsset[(n)/32])
|
||||
#define TIFFFieldSet(tif, field) (BITFIELDn(tif, field) & BITn(field))
|
||||
#define 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))
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
extern const TIFFFieldInfo *_TIFFGetFieldInfo(size_t *);
|
||||
extern const TIFFFieldInfo *_TIFFGetExifFieldInfo(size_t *);
|
||||
extern void _TIFFSetupFieldInfo(TIFF*, const TIFFFieldInfo[], size_t);
|
||||
extern int _TIFFMergeFieldInfo(TIFF*, const TIFFFieldInfo[], int);
|
||||
extern void _TIFFPrintFieldInfo(TIFF*, FILE*);
|
||||
extern TIFFDataType _TIFFSampleToTagType(TIFF*);
|
||||
extern const TIFFFieldInfo* _TIFFFindOrRegisterFieldInfo( TIFF *tif,
|
||||
ttag_t tag,
|
||||
TIFFDataType dt );
|
||||
extern TIFFFieldInfo* _TIFFCreateAnonFieldInfo( TIFF *tif, ttag_t tag,
|
||||
TIFFDataType dt );
|
||||
|
||||
#define _TIFFFindFieldInfo TIFFFindFieldInfo
|
||||
#define _TIFFFindFieldInfoByName TIFFFindFieldInfoByName
|
||||
#define _TIFFFieldWithTag TIFFFieldWithTag
|
||||
#define _TIFFFieldWithName TIFFFieldWithName
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif /* _TIFFDIR_ */
|
||||
|
||||
/* vim: set ts=8 sts=8 sw=8 noet: */
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 8
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
904
thirdparty/libtiff/tif_dirinfo.c
vendored
Normal file
904
thirdparty/libtiff/tif_dirinfo.c
vendored
Normal file
@ -0,0 +1,904 @@
|
||||
/* $Id: tif_dirinfo.c,v 1.65.2.9 2010-06-09 21:15:27 bfriesen Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that (i) the above copyright notices and this permission notice appear in
|
||||
* all copies of the software and related documentation, and (ii) the names of
|
||||
* Sam Leffler and Silicon Graphics may not be used in any advertising or
|
||||
* publicity relating to the software without the specific, prior written
|
||||
* permission of Sam Leffler and Silicon Graphics.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
||||
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
|
||||
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
||||
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
||||
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TIFF Library.
|
||||
*
|
||||
* Core Directory Tag Support.
|
||||
*/
|
||||
#include "tiffiop.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* NB: NB: THIS ARRAY IS ASSUMED TO BE SORTED BY TAG.
|
||||
* If a tag can have both LONG and SHORT types then the LONG must be
|
||||
* placed before the SHORT for writing to work properly.
|
||||
*
|
||||
* NOTE: The second field (field_readcount) and third field (field_writecount)
|
||||
* sometimes use the values TIFF_VARIABLE (-1), TIFF_VARIABLE2 (-3)
|
||||
* and TIFFTAG_SPP (-2). The macros should be used but would throw off
|
||||
* the formatting of the code, so please interprete the -1, -2 and -3
|
||||
* values accordingly.
|
||||
*/
|
||||
static const TIFFFieldInfo
|
||||
tiffFieldInfo[] = {
|
||||
{ TIFFTAG_SUBFILETYPE, 1, 1, TIFF_LONG, FIELD_SUBFILETYPE,
|
||||
1, 0, "SubfileType" },
|
||||
/* XXX SHORT for compatibility w/ old versions of the library */
|
||||
{ TIFFTAG_SUBFILETYPE, 1, 1, TIFF_SHORT, FIELD_SUBFILETYPE,
|
||||
1, 0, "SubfileType" },
|
||||
{ TIFFTAG_OSUBFILETYPE, 1, 1, TIFF_SHORT, FIELD_SUBFILETYPE,
|
||||
1, 0, "OldSubfileType" },
|
||||
{ TIFFTAG_IMAGEWIDTH, 1, 1, TIFF_LONG, FIELD_IMAGEDIMENSIONS,
|
||||
0, 0, "ImageWidth" },
|
||||
{ TIFFTAG_IMAGEWIDTH, 1, 1, TIFF_SHORT, FIELD_IMAGEDIMENSIONS,
|
||||
0, 0, "ImageWidth" },
|
||||
{ TIFFTAG_IMAGELENGTH, 1, 1, TIFF_LONG, FIELD_IMAGEDIMENSIONS,
|
||||
1, 0, "ImageLength" },
|
||||
{ TIFFTAG_IMAGELENGTH, 1, 1, TIFF_SHORT, FIELD_IMAGEDIMENSIONS,
|
||||
1, 0, "ImageLength" },
|
||||
{ TIFFTAG_BITSPERSAMPLE, -1,-1, TIFF_SHORT, FIELD_BITSPERSAMPLE,
|
||||
0, 0, "BitsPerSample" },
|
||||
/* XXX LONG for compatibility with some broken TIFF writers */
|
||||
{ TIFFTAG_BITSPERSAMPLE, -1,-1, TIFF_LONG, FIELD_BITSPERSAMPLE,
|
||||
0, 0, "BitsPerSample" },
|
||||
{ TIFFTAG_COMPRESSION, -1, 1, TIFF_SHORT, FIELD_COMPRESSION,
|
||||
0, 0, "Compression" },
|
||||
/* XXX LONG for compatibility with some broken TIFF writers */
|
||||
{ TIFFTAG_COMPRESSION, -1, 1, TIFF_LONG, FIELD_COMPRESSION,
|
||||
0, 0, "Compression" },
|
||||
{ TIFFTAG_PHOTOMETRIC, 1, 1, TIFF_SHORT, FIELD_PHOTOMETRIC,
|
||||
0, 0, "PhotometricInterpretation" },
|
||||
/* XXX LONG for compatibility with some broken TIFF writers */
|
||||
{ TIFFTAG_PHOTOMETRIC, 1, 1, TIFF_LONG, FIELD_PHOTOMETRIC,
|
||||
0, 0, "PhotometricInterpretation" },
|
||||
{ TIFFTAG_THRESHHOLDING, 1, 1, TIFF_SHORT, FIELD_THRESHHOLDING,
|
||||
1, 0, "Threshholding" },
|
||||
{ TIFFTAG_CELLWIDTH, 1, 1, TIFF_SHORT, FIELD_IGNORE,
|
||||
1, 0, "CellWidth" },
|
||||
{ TIFFTAG_CELLLENGTH, 1, 1, TIFF_SHORT, FIELD_IGNORE,
|
||||
1, 0, "CellLength" },
|
||||
{ TIFFTAG_FILLORDER, 1, 1, TIFF_SHORT, FIELD_FILLORDER,
|
||||
0, 0, "FillOrder" },
|
||||
{ TIFFTAG_DOCUMENTNAME, -1,-1, TIFF_ASCII, FIELD_CUSTOM,
|
||||
1, 0, "DocumentName" },
|
||||
{ TIFFTAG_IMAGEDESCRIPTION, -1,-1, TIFF_ASCII, FIELD_CUSTOM,
|
||||
1, 0, "ImageDescription" },
|
||||
{ TIFFTAG_MAKE, -1,-1, TIFF_ASCII, FIELD_CUSTOM,
|
||||
1, 0, "Make" },
|
||||
{ TIFFTAG_MODEL, -1,-1, TIFF_ASCII, FIELD_CUSTOM,
|
||||
1, 0, "Model" },
|
||||
{ TIFFTAG_STRIPOFFSETS, -1,-1, TIFF_LONG, FIELD_STRIPOFFSETS,
|
||||
0, 0, "StripOffsets" },
|
||||
{ TIFFTAG_STRIPOFFSETS, -1,-1, TIFF_SHORT, FIELD_STRIPOFFSETS,
|
||||
0, 0, "StripOffsets" },
|
||||
{ TIFFTAG_ORIENTATION, 1, 1, TIFF_SHORT, FIELD_ORIENTATION,
|
||||
0, 0, "Orientation" },
|
||||
{ TIFFTAG_SAMPLESPERPIXEL, 1, 1, TIFF_SHORT, FIELD_SAMPLESPERPIXEL,
|
||||
0, 0, "SamplesPerPixel" },
|
||||
{ TIFFTAG_ROWSPERSTRIP, 1, 1, TIFF_LONG, FIELD_ROWSPERSTRIP,
|
||||
0, 0, "RowsPerStrip" },
|
||||
{ TIFFTAG_ROWSPERSTRIP, 1, 1, TIFF_SHORT, FIELD_ROWSPERSTRIP,
|
||||
0, 0, "RowsPerStrip" },
|
||||
{ TIFFTAG_STRIPBYTECOUNTS, -1,-1, TIFF_LONG, FIELD_STRIPBYTECOUNTS,
|
||||
0, 0, "StripByteCounts" },
|
||||
{ TIFFTAG_STRIPBYTECOUNTS, -1,-1, TIFF_SHORT, FIELD_STRIPBYTECOUNTS,
|
||||
0, 0, "StripByteCounts" },
|
||||
{ TIFFTAG_MINSAMPLEVALUE, -2,-1, TIFF_SHORT, FIELD_MINSAMPLEVALUE,
|
||||
1, 0, "MinSampleValue" },
|
||||
{ TIFFTAG_MAXSAMPLEVALUE, -2,-1, TIFF_SHORT, FIELD_MAXSAMPLEVALUE,
|
||||
1, 0, "MaxSampleValue" },
|
||||
{ TIFFTAG_XRESOLUTION, 1, 1, TIFF_RATIONAL, FIELD_RESOLUTION,
|
||||
1, 0, "XResolution" },
|
||||
{ TIFFTAG_YRESOLUTION, 1, 1, TIFF_RATIONAL, FIELD_RESOLUTION,
|
||||
1, 0, "YResolution" },
|
||||
{ TIFFTAG_PLANARCONFIG, 1, 1, TIFF_SHORT, FIELD_PLANARCONFIG,
|
||||
0, 0, "PlanarConfiguration" },
|
||||
{ TIFFTAG_PAGENAME, -1,-1, TIFF_ASCII, FIELD_CUSTOM,
|
||||
1, 0, "PageName" },
|
||||
{ TIFFTAG_XPOSITION, 1, 1, TIFF_RATIONAL, FIELD_POSITION,
|
||||
1, 0, "XPosition" },
|
||||
{ TIFFTAG_YPOSITION, 1, 1, TIFF_RATIONAL, FIELD_POSITION,
|
||||
1, 0, "YPosition" },
|
||||
{ TIFFTAG_FREEOFFSETS, -1,-1, TIFF_LONG, FIELD_IGNORE,
|
||||
0, 0, "FreeOffsets" },
|
||||
{ TIFFTAG_FREEBYTECOUNTS, -1,-1, TIFF_LONG, FIELD_IGNORE,
|
||||
0, 0, "FreeByteCounts" },
|
||||
{ TIFFTAG_GRAYRESPONSEUNIT, 1, 1, TIFF_SHORT, FIELD_IGNORE,
|
||||
1, 0, "GrayResponseUnit" },
|
||||
{ TIFFTAG_GRAYRESPONSECURVE,-1,-1, TIFF_SHORT, FIELD_IGNORE,
|
||||
1, 0, "GrayResponseCurve" },
|
||||
{ TIFFTAG_RESOLUTIONUNIT, 1, 1, TIFF_SHORT, FIELD_RESOLUTIONUNIT,
|
||||
1, 0, "ResolutionUnit" },
|
||||
{ TIFFTAG_PAGENUMBER, 2, 2, TIFF_SHORT, FIELD_PAGENUMBER,
|
||||
1, 0, "PageNumber" },
|
||||
{ TIFFTAG_COLORRESPONSEUNIT, 1, 1, TIFF_SHORT, FIELD_IGNORE,
|
||||
1, 0, "ColorResponseUnit" },
|
||||
{ TIFFTAG_TRANSFERFUNCTION, -1,-1, TIFF_SHORT, FIELD_TRANSFERFUNCTION,
|
||||
1, 0, "TransferFunction" },
|
||||
{ TIFFTAG_SOFTWARE, -1,-1, TIFF_ASCII, FIELD_CUSTOM,
|
||||
1, 0, "Software" },
|
||||
{ TIFFTAG_DATETIME, 20,20, TIFF_ASCII, FIELD_CUSTOM,
|
||||
1, 0, "DateTime" },
|
||||
{ TIFFTAG_ARTIST, -1,-1, TIFF_ASCII, FIELD_CUSTOM,
|
||||
1, 0, "Artist" },
|
||||
{ TIFFTAG_HOSTCOMPUTER, -1,-1, TIFF_ASCII, FIELD_CUSTOM,
|
||||
1, 0, "HostComputer" },
|
||||
{ TIFFTAG_WHITEPOINT, 2, 2, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
1, 0, "WhitePoint" },
|
||||
{ TIFFTAG_PRIMARYCHROMATICITIES,6,6,TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
1, 0, "PrimaryChromaticities" },
|
||||
{ TIFFTAG_COLORMAP, -1,-1, TIFF_SHORT, FIELD_COLORMAP,
|
||||
1, 0, "ColorMap" },
|
||||
{ TIFFTAG_HALFTONEHINTS, 2, 2, TIFF_SHORT, FIELD_HALFTONEHINTS,
|
||||
1, 0, "HalftoneHints" },
|
||||
{ TIFFTAG_TILEWIDTH, 1, 1, TIFF_LONG, FIELD_TILEDIMENSIONS,
|
||||
0, 0, "TileWidth" },
|
||||
{ TIFFTAG_TILEWIDTH, 1, 1, TIFF_SHORT, FIELD_TILEDIMENSIONS,
|
||||
0, 0, "TileWidth" },
|
||||
{ TIFFTAG_TILELENGTH, 1, 1, TIFF_LONG, FIELD_TILEDIMENSIONS,
|
||||
0, 0, "TileLength" },
|
||||
{ TIFFTAG_TILELENGTH, 1, 1, TIFF_SHORT, FIELD_TILEDIMENSIONS,
|
||||
0, 0, "TileLength" },
|
||||
{ TIFFTAG_TILEOFFSETS, -1, 1, TIFF_LONG, FIELD_STRIPOFFSETS,
|
||||
0, 0, "TileOffsets" },
|
||||
{ TIFFTAG_TILEBYTECOUNTS, -1, 1, TIFF_LONG, FIELD_STRIPBYTECOUNTS,
|
||||
0, 0, "TileByteCounts" },
|
||||
{ TIFFTAG_TILEBYTECOUNTS, -1, 1, TIFF_SHORT, FIELD_STRIPBYTECOUNTS,
|
||||
0, 0, "TileByteCounts" },
|
||||
{ TIFFTAG_SUBIFD, -1,-1, TIFF_IFD, FIELD_SUBIFD,
|
||||
1, 1, "SubIFD" },
|
||||
{ TIFFTAG_SUBIFD, -1,-1, TIFF_LONG, FIELD_SUBIFD,
|
||||
1, 1, "SubIFD" },
|
||||
{ TIFFTAG_INKSET, 1, 1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
0, 0, "InkSet" },
|
||||
{ TIFFTAG_INKNAMES, -1,-1, TIFF_ASCII, FIELD_INKNAMES,
|
||||
1, 1, "InkNames" },
|
||||
{ TIFFTAG_NUMBEROFINKS, 1, 1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
1, 0, "NumberOfInks" },
|
||||
{ TIFFTAG_DOTRANGE, 2, 2, TIFF_SHORT, FIELD_CUSTOM,
|
||||
0, 0, "DotRange" },
|
||||
{ TIFFTAG_DOTRANGE, 2, 2, TIFF_BYTE, FIELD_CUSTOM,
|
||||
0, 0, "DotRange" },
|
||||
{ TIFFTAG_TARGETPRINTER, -1,-1, TIFF_ASCII, FIELD_CUSTOM,
|
||||
1, 0, "TargetPrinter" },
|
||||
{ TIFFTAG_EXTRASAMPLES, -1,-1, TIFF_SHORT, FIELD_EXTRASAMPLES,
|
||||
0, 1, "ExtraSamples" },
|
||||
/* XXX for bogus Adobe Photoshop v2.5 files */
|
||||
{ TIFFTAG_EXTRASAMPLES, -1,-1, TIFF_BYTE, FIELD_EXTRASAMPLES,
|
||||
0, 1, "ExtraSamples" },
|
||||
{ TIFFTAG_SAMPLEFORMAT, -1,-1, TIFF_SHORT, FIELD_SAMPLEFORMAT,
|
||||
0, 0, "SampleFormat" },
|
||||
{ TIFFTAG_SMINSAMPLEVALUE, -2,-1, TIFF_ANY, FIELD_SMINSAMPLEVALUE,
|
||||
1, 0, "SMinSampleValue" },
|
||||
{ TIFFTAG_SMAXSAMPLEVALUE, -2,-1, TIFF_ANY, FIELD_SMAXSAMPLEVALUE,
|
||||
1, 0, "SMaxSampleValue" },
|
||||
{ TIFFTAG_CLIPPATH, -1, -3, TIFF_BYTE, FIELD_CUSTOM,
|
||||
0, 1, "ClipPath" },
|
||||
{ TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_SLONG, FIELD_CUSTOM,
|
||||
0, 0, "XClipPathUnits" },
|
||||
{ TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_SSHORT, FIELD_CUSTOM,
|
||||
0, 0, "XClipPathUnits" },
|
||||
{ TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_SBYTE, FIELD_CUSTOM,
|
||||
0, 0, "XClipPathUnits" },
|
||||
{ TIFFTAG_YCLIPPATHUNITS, 1, 1, TIFF_SLONG, FIELD_CUSTOM,
|
||||
0, 0, "YClipPathUnits" },
|
||||
{ TIFFTAG_YCLIPPATHUNITS, 1, 1, TIFF_SSHORT, FIELD_CUSTOM,
|
||||
0, 0, "YClipPathUnits" },
|
||||
{ TIFFTAG_YCLIPPATHUNITS, 1, 1, TIFF_SBYTE, FIELD_CUSTOM,
|
||||
0, 0, "YClipPathUnits" },
|
||||
{ TIFFTAG_YCBCRCOEFFICIENTS, 3, 3, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
0, 0, "YCbCrCoefficients" },
|
||||
{ TIFFTAG_YCBCRSUBSAMPLING, 2, 2, TIFF_SHORT, FIELD_YCBCRSUBSAMPLING,
|
||||
0, 0, "YCbCrSubsampling" },
|
||||
{ TIFFTAG_YCBCRPOSITIONING, 1, 1, TIFF_SHORT, FIELD_YCBCRPOSITIONING,
|
||||
0, 0, "YCbCrPositioning" },
|
||||
{ TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_RATIONAL, FIELD_REFBLACKWHITE,
|
||||
1, 0, "ReferenceBlackWhite" },
|
||||
/* XXX temporarily accept LONG for backwards compatibility */
|
||||
{ TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_LONG, FIELD_REFBLACKWHITE,
|
||||
1, 0, "ReferenceBlackWhite" },
|
||||
{ TIFFTAG_XMLPACKET, -3,-3, TIFF_BYTE, FIELD_CUSTOM,
|
||||
0, 1, "XMLPacket" },
|
||||
/* begin SGI tags */
|
||||
{ TIFFTAG_MATTEING, 1, 1, TIFF_SHORT, FIELD_EXTRASAMPLES,
|
||||
0, 0, "Matteing" },
|
||||
{ TIFFTAG_DATATYPE, -2,-1, TIFF_SHORT, FIELD_SAMPLEFORMAT,
|
||||
0, 0, "DataType" },
|
||||
{ TIFFTAG_IMAGEDEPTH, 1, 1, TIFF_LONG, FIELD_IMAGEDEPTH,
|
||||
0, 0, "ImageDepth" },
|
||||
{ TIFFTAG_IMAGEDEPTH, 1, 1, TIFF_SHORT, FIELD_IMAGEDEPTH,
|
||||
0, 0, "ImageDepth" },
|
||||
{ TIFFTAG_TILEDEPTH, 1, 1, TIFF_LONG, FIELD_TILEDEPTH,
|
||||
0, 0, "TileDepth" },
|
||||
{ TIFFTAG_TILEDEPTH, 1, 1, TIFF_SHORT, FIELD_TILEDEPTH,
|
||||
0, 0, "TileDepth" },
|
||||
/* end SGI tags */
|
||||
/* begin Pixar tags */
|
||||
{ TIFFTAG_PIXAR_IMAGEFULLWIDTH, 1, 1, TIFF_LONG, FIELD_CUSTOM,
|
||||
1, 0, "ImageFullWidth" },
|
||||
{ TIFFTAG_PIXAR_IMAGEFULLLENGTH, 1, 1, TIFF_LONG, FIELD_CUSTOM,
|
||||
1, 0, "ImageFullLength" },
|
||||
{ TIFFTAG_PIXAR_TEXTUREFORMAT, -1, -1, TIFF_ASCII, FIELD_CUSTOM,
|
||||
1, 0, "TextureFormat" },
|
||||
{ TIFFTAG_PIXAR_WRAPMODES, -1, -1, TIFF_ASCII, FIELD_CUSTOM,
|
||||
1, 0, "TextureWrapModes" },
|
||||
{ TIFFTAG_PIXAR_FOVCOT, 1, 1, TIFF_FLOAT, FIELD_CUSTOM,
|
||||
1, 0, "FieldOfViewCotangent" },
|
||||
{ TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN, 16,16, TIFF_FLOAT,
|
||||
FIELD_CUSTOM, 1, 0, "MatrixWorldToScreen" },
|
||||
{ TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA, 16,16, TIFF_FLOAT,
|
||||
FIELD_CUSTOM, 1, 0, "MatrixWorldToCamera" },
|
||||
{ TIFFTAG_COPYRIGHT, -1, -1, TIFF_ASCII, FIELD_CUSTOM,
|
||||
1, 0, "Copyright" },
|
||||
/* end Pixar tags */
|
||||
{ TIFFTAG_RICHTIFFIPTC, -3, -3, TIFF_LONG, FIELD_CUSTOM,
|
||||
0, 1, "RichTIFFIPTC" },
|
||||
{ TIFFTAG_PHOTOSHOP, -3, -3, TIFF_BYTE, FIELD_CUSTOM,
|
||||
0, 1, "Photoshop" },
|
||||
{ TIFFTAG_EXIFIFD, 1, 1, TIFF_LONG, FIELD_CUSTOM,
|
||||
0, 0, "EXIFIFDOffset" },
|
||||
{ TIFFTAG_ICCPROFILE, -3, -3, TIFF_UNDEFINED, FIELD_CUSTOM,
|
||||
0, 1, "ICC Profile" },
|
||||
{ TIFFTAG_GPSIFD, 1, 1, TIFF_LONG, FIELD_CUSTOM,
|
||||
0, 0, "GPSIFDOffset" },
|
||||
{ TIFFTAG_STONITS, 1, 1, TIFF_DOUBLE, FIELD_CUSTOM,
|
||||
0, 0, "StoNits" },
|
||||
{ TIFFTAG_INTEROPERABILITYIFD, 1, 1, TIFF_LONG, FIELD_CUSTOM,
|
||||
0, 0, "InteroperabilityIFDOffset" },
|
||||
/* begin DNG tags */
|
||||
{ TIFFTAG_DNGVERSION, 4, 4, TIFF_BYTE, FIELD_CUSTOM,
|
||||
0, 0, "DNGVersion" },
|
||||
{ TIFFTAG_DNGBACKWARDVERSION, 4, 4, TIFF_BYTE, FIELD_CUSTOM,
|
||||
0, 0, "DNGBackwardVersion" },
|
||||
{ TIFFTAG_UNIQUECAMERAMODEL, -1, -1, TIFF_ASCII, FIELD_CUSTOM,
|
||||
1, 0, "UniqueCameraModel" },
|
||||
{ TIFFTAG_LOCALIZEDCAMERAMODEL, -1, -1, TIFF_ASCII, FIELD_CUSTOM,
|
||||
1, 0, "LocalizedCameraModel" },
|
||||
{ TIFFTAG_LOCALIZEDCAMERAMODEL, -1, -1, TIFF_BYTE, FIELD_CUSTOM,
|
||||
1, 1, "LocalizedCameraModel" },
|
||||
{ TIFFTAG_CFAPLANECOLOR, -1, -1, TIFF_BYTE, FIELD_CUSTOM,
|
||||
0, 1, "CFAPlaneColor" },
|
||||
{ TIFFTAG_CFALAYOUT, 1, 1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
0, 0, "CFALayout" },
|
||||
{ TIFFTAG_LINEARIZATIONTABLE, -1, -1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
0, 1, "LinearizationTable" },
|
||||
{ TIFFTAG_BLACKLEVELREPEATDIM, 2, 2, TIFF_SHORT, FIELD_CUSTOM,
|
||||
0, 0, "BlackLevelRepeatDim" },
|
||||
{ TIFFTAG_BLACKLEVEL, -1, -1, TIFF_LONG, FIELD_CUSTOM,
|
||||
0, 1, "BlackLevel" },
|
||||
{ TIFFTAG_BLACKLEVEL, -1, -1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
0, 1, "BlackLevel" },
|
||||
{ TIFFTAG_BLACKLEVEL, -1, -1, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
0, 1, "BlackLevel" },
|
||||
{ TIFFTAG_BLACKLEVELDELTAH, -1, -1, TIFF_SRATIONAL, FIELD_CUSTOM,
|
||||
0, 1, "BlackLevelDeltaH" },
|
||||
{ TIFFTAG_BLACKLEVELDELTAV, -1, -1, TIFF_SRATIONAL, FIELD_CUSTOM,
|
||||
0, 1, "BlackLevelDeltaV" },
|
||||
{ TIFFTAG_WHITELEVEL, -2, -2, TIFF_LONG, FIELD_CUSTOM,
|
||||
0, 0, "WhiteLevel" },
|
||||
{ TIFFTAG_WHITELEVEL, -2, -2, TIFF_SHORT, FIELD_CUSTOM,
|
||||
0, 0, "WhiteLevel" },
|
||||
{ TIFFTAG_DEFAULTSCALE, 2, 2, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
0, 0, "DefaultScale" },
|
||||
{ TIFFTAG_BESTQUALITYSCALE, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
0, 0, "BestQualityScale" },
|
||||
{ TIFFTAG_DEFAULTCROPORIGIN, 2, 2, TIFF_LONG, FIELD_CUSTOM,
|
||||
0, 0, "DefaultCropOrigin" },
|
||||
{ TIFFTAG_DEFAULTCROPORIGIN, 2, 2, TIFF_SHORT, FIELD_CUSTOM,
|
||||
0, 0, "DefaultCropOrigin" },
|
||||
{ TIFFTAG_DEFAULTCROPORIGIN, 2, 2, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
0, 0, "DefaultCropOrigin" },
|
||||
{ TIFFTAG_DEFAULTCROPSIZE, 2, 2, TIFF_LONG, FIELD_CUSTOM,
|
||||
0, 0, "DefaultCropSize" },
|
||||
{ TIFFTAG_DEFAULTCROPSIZE, 2, 2, TIFF_SHORT, FIELD_CUSTOM,
|
||||
0, 0, "DefaultCropSize" },
|
||||
{ TIFFTAG_DEFAULTCROPSIZE, 2, 2, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
0, 0, "DefaultCropSize" },
|
||||
{ TIFFTAG_COLORMATRIX1, -1, -1, TIFF_SRATIONAL, FIELD_CUSTOM,
|
||||
0, 1, "ColorMatrix1" },
|
||||
{ TIFFTAG_COLORMATRIX2, -1, -1, TIFF_SRATIONAL, FIELD_CUSTOM,
|
||||
0, 1, "ColorMatrix2" },
|
||||
{ TIFFTAG_CAMERACALIBRATION1, -1, -1, TIFF_SRATIONAL, FIELD_CUSTOM,
|
||||
0, 1, "CameraCalibration1" },
|
||||
{ TIFFTAG_CAMERACALIBRATION2, -1, -1, TIFF_SRATIONAL, FIELD_CUSTOM,
|
||||
0, 1, "CameraCalibration2" },
|
||||
{ TIFFTAG_REDUCTIONMATRIX1, -1, -1, TIFF_SRATIONAL, FIELD_CUSTOM,
|
||||
0, 1, "ReductionMatrix1" },
|
||||
{ TIFFTAG_REDUCTIONMATRIX2, -1, -1, TIFF_SRATIONAL, FIELD_CUSTOM,
|
||||
0, 1, "ReductionMatrix2" },
|
||||
{ TIFFTAG_ANALOGBALANCE, -1, -1, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
0, 1, "AnalogBalance" },
|
||||
{ TIFFTAG_ASSHOTNEUTRAL, -1, -1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
0, 1, "AsShotNeutral" },
|
||||
{ TIFFTAG_ASSHOTNEUTRAL, -1, -1, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
0, 1, "AsShotNeutral" },
|
||||
{ TIFFTAG_ASSHOTWHITEXY, 2, 2, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
0, 0, "AsShotWhiteXY" },
|
||||
{ TIFFTAG_BASELINEEXPOSURE, 1, 1, TIFF_SRATIONAL, FIELD_CUSTOM,
|
||||
0, 0, "BaselineExposure" },
|
||||
{ TIFFTAG_BASELINENOISE, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
0, 0, "BaselineNoise" },
|
||||
{ TIFFTAG_BASELINESHARPNESS, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
0, 0, "BaselineSharpness" },
|
||||
{ TIFFTAG_BAYERGREENSPLIT, 1, 1, TIFF_LONG, FIELD_CUSTOM,
|
||||
0, 0, "BayerGreenSplit" },
|
||||
{ TIFFTAG_LINEARRESPONSELIMIT, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
0, 0, "LinearResponseLimit" },
|
||||
{ TIFFTAG_CAMERASERIALNUMBER, -1, -1, TIFF_ASCII, FIELD_CUSTOM,
|
||||
1, 0, "CameraSerialNumber" },
|
||||
{ TIFFTAG_LENSINFO, 4, 4, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
0, 0, "LensInfo" },
|
||||
{ TIFFTAG_CHROMABLURRADIUS, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
0, 0, "ChromaBlurRadius" },
|
||||
{ TIFFTAG_ANTIALIASSTRENGTH, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
0, 0, "AntiAliasStrength" },
|
||||
{ TIFFTAG_SHADOWSCALE, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
0, 0, "ShadowScale" },
|
||||
{ TIFFTAG_DNGPRIVATEDATA, -1, -1, TIFF_BYTE, FIELD_CUSTOM,
|
||||
0, 1, "DNGPrivateData" },
|
||||
{ TIFFTAG_MAKERNOTESAFETY, 1, 1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
0, 0, "MakerNoteSafety" },
|
||||
{ TIFFTAG_CALIBRATIONILLUMINANT1, 1, 1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
0, 0, "CalibrationIlluminant1" },
|
||||
{ TIFFTAG_CALIBRATIONILLUMINANT2, 1, 1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
0, 0, "CalibrationIlluminant2" },
|
||||
{ TIFFTAG_RAWDATAUNIQUEID, 16, 16, TIFF_BYTE, FIELD_CUSTOM,
|
||||
0, 0, "RawDataUniqueID" },
|
||||
{ TIFFTAG_ORIGINALRAWFILENAME, -1, -1, TIFF_ASCII, FIELD_CUSTOM,
|
||||
1, 0, "OriginalRawFileName" },
|
||||
{ TIFFTAG_ORIGINALRAWFILENAME, -1, -1, TIFF_BYTE, FIELD_CUSTOM,
|
||||
1, 1, "OriginalRawFileName" },
|
||||
{ TIFFTAG_ORIGINALRAWFILEDATA, -1, -1, TIFF_UNDEFINED, FIELD_CUSTOM,
|
||||
0, 1, "OriginalRawFileData" },
|
||||
{ TIFFTAG_ACTIVEAREA, 4, 4, TIFF_LONG, FIELD_CUSTOM,
|
||||
0, 0, "ActiveArea" },
|
||||
{ TIFFTAG_ACTIVEAREA, 4, 4, TIFF_SHORT, FIELD_CUSTOM,
|
||||
0, 0, "ActiveArea" },
|
||||
{ TIFFTAG_MASKEDAREAS, -1, -1, TIFF_LONG, FIELD_CUSTOM,
|
||||
0, 1, "MaskedAreas" },
|
||||
{ TIFFTAG_ASSHOTICCPROFILE, -1, -1, TIFF_UNDEFINED, FIELD_CUSTOM,
|
||||
0, 1, "AsShotICCProfile" },
|
||||
{ TIFFTAG_ASSHOTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, FIELD_CUSTOM,
|
||||
0, 1, "AsShotPreProfileMatrix" },
|
||||
{ TIFFTAG_CURRENTICCPROFILE, -1, -1, TIFF_UNDEFINED, FIELD_CUSTOM,
|
||||
0, 1, "CurrentICCProfile" },
|
||||
{ TIFFTAG_CURRENTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, FIELD_CUSTOM,
|
||||
0, 1, "CurrentPreProfileMatrix" },
|
||||
/* end DNG tags */
|
||||
};
|
||||
|
||||
static const TIFFFieldInfo
|
||||
exifFieldInfo[] = {
|
||||
{ EXIFTAG_EXPOSURETIME, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
1, 0, "ExposureTime" },
|
||||
{ EXIFTAG_FNUMBER, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
1, 0, "FNumber" },
|
||||
{ EXIFTAG_EXPOSUREPROGRAM, 1, 1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
1, 0, "ExposureProgram" },
|
||||
{ EXIFTAG_SPECTRALSENSITIVITY, -1, -1, TIFF_ASCII, FIELD_CUSTOM,
|
||||
1, 0, "SpectralSensitivity" },
|
||||
{ EXIFTAG_ISOSPEEDRATINGS, -1, -1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
1, 1, "ISOSpeedRatings" },
|
||||
{ EXIFTAG_OECF, -1, -1, TIFF_UNDEFINED, FIELD_CUSTOM,
|
||||
1, 1, "OptoelectricConversionFactor" },
|
||||
{ EXIFTAG_EXIFVERSION, 4, 4, TIFF_UNDEFINED, FIELD_CUSTOM,
|
||||
1, 0, "ExifVersion" },
|
||||
{ EXIFTAG_DATETIMEORIGINAL, 20, 20, TIFF_ASCII, FIELD_CUSTOM,
|
||||
1, 0, "DateTimeOriginal" },
|
||||
{ EXIFTAG_DATETIMEDIGITIZED, 20, 20, TIFF_ASCII, FIELD_CUSTOM,
|
||||
1, 0, "DateTimeDigitized" },
|
||||
{ EXIFTAG_COMPONENTSCONFIGURATION, 4, 4, TIFF_UNDEFINED, FIELD_CUSTOM,
|
||||
1, 0, "ComponentsConfiguration" },
|
||||
{ EXIFTAG_COMPRESSEDBITSPERPIXEL, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
1, 0, "CompressedBitsPerPixel" },
|
||||
{ EXIFTAG_SHUTTERSPEEDVALUE, 1, 1, TIFF_SRATIONAL, FIELD_CUSTOM,
|
||||
1, 0, "ShutterSpeedValue" },
|
||||
{ EXIFTAG_APERTUREVALUE, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
1, 0, "ApertureValue" },
|
||||
{ EXIFTAG_BRIGHTNESSVALUE, 1, 1, TIFF_SRATIONAL, FIELD_CUSTOM,
|
||||
1, 0, "BrightnessValue" },
|
||||
{ EXIFTAG_EXPOSUREBIASVALUE, 1, 1, TIFF_SRATIONAL, FIELD_CUSTOM,
|
||||
1, 0, "ExposureBiasValue" },
|
||||
{ EXIFTAG_MAXAPERTUREVALUE, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
1, 0, "MaxApertureValue" },
|
||||
{ EXIFTAG_SUBJECTDISTANCE, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
1, 0, "SubjectDistance" },
|
||||
{ EXIFTAG_METERINGMODE, 1, 1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
1, 0, "MeteringMode" },
|
||||
{ EXIFTAG_LIGHTSOURCE, 1, 1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
1, 0, "LightSource" },
|
||||
{ EXIFTAG_FLASH, 1, 1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
1, 0, "Flash" },
|
||||
{ EXIFTAG_FOCALLENGTH, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
1, 0, "FocalLength" },
|
||||
{ EXIFTAG_SUBJECTAREA, -1, -1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
1, 1, "SubjectArea" },
|
||||
{ EXIFTAG_MAKERNOTE, -1, -1, TIFF_UNDEFINED, FIELD_CUSTOM,
|
||||
1, 1, "MakerNote" },
|
||||
{ EXIFTAG_USERCOMMENT, -1, -1, TIFF_UNDEFINED, FIELD_CUSTOM,
|
||||
1, 1, "UserComment" },
|
||||
{ EXIFTAG_SUBSECTIME, -1, -1, TIFF_ASCII, FIELD_CUSTOM,
|
||||
1, 0, "SubSecTime" },
|
||||
{ EXIFTAG_SUBSECTIMEORIGINAL, -1, -1, TIFF_ASCII, FIELD_CUSTOM,
|
||||
1, 0, "SubSecTimeOriginal" },
|
||||
{ EXIFTAG_SUBSECTIMEDIGITIZED,-1, -1, TIFF_ASCII, FIELD_CUSTOM,
|
||||
1, 0, "SubSecTimeDigitized" },
|
||||
{ EXIFTAG_FLASHPIXVERSION, 4, 4, TIFF_UNDEFINED, FIELD_CUSTOM,
|
||||
1, 0, "FlashpixVersion" },
|
||||
{ EXIFTAG_COLORSPACE, 1, 1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
1, 0, "ColorSpace" },
|
||||
{ EXIFTAG_PIXELXDIMENSION, 1, 1, TIFF_LONG, FIELD_CUSTOM,
|
||||
1, 0, "PixelXDimension" },
|
||||
{ EXIFTAG_PIXELXDIMENSION, 1, 1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
1, 0, "PixelXDimension" },
|
||||
{ EXIFTAG_PIXELYDIMENSION, 1, 1, TIFF_LONG, FIELD_CUSTOM,
|
||||
1, 0, "PixelYDimension" },
|
||||
{ EXIFTAG_PIXELYDIMENSION, 1, 1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
1, 0, "PixelYDimension" },
|
||||
{ EXIFTAG_RELATEDSOUNDFILE, 13, 13, TIFF_ASCII, FIELD_CUSTOM,
|
||||
1, 0, "RelatedSoundFile" },
|
||||
{ EXIFTAG_FLASHENERGY, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
1, 0, "FlashEnergy" },
|
||||
{ EXIFTAG_SPATIALFREQUENCYRESPONSE, -1, -1, TIFF_UNDEFINED, FIELD_CUSTOM,
|
||||
1, 1, "SpatialFrequencyResponse" },
|
||||
{ EXIFTAG_FOCALPLANEXRESOLUTION, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
1, 0, "FocalPlaneXResolution" },
|
||||
{ EXIFTAG_FOCALPLANEYRESOLUTION, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
1, 0, "FocalPlaneYResolution" },
|
||||
{ EXIFTAG_FOCALPLANERESOLUTIONUNIT, 1, 1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
1, 0, "FocalPlaneResolutionUnit" },
|
||||
{ EXIFTAG_SUBJECTLOCATION, 2, 2, TIFF_SHORT, FIELD_CUSTOM,
|
||||
1, 0, "SubjectLocation" },
|
||||
{ EXIFTAG_EXPOSUREINDEX, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
1, 0, "ExposureIndex" },
|
||||
{ EXIFTAG_SENSINGMETHOD, 1, 1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
1, 0, "SensingMethod" },
|
||||
{ EXIFTAG_FILESOURCE, 1, 1, TIFF_UNDEFINED, FIELD_CUSTOM,
|
||||
1, 0, "FileSource" },
|
||||
{ EXIFTAG_SCENETYPE, 1, 1, TIFF_UNDEFINED, FIELD_CUSTOM,
|
||||
1, 0, "SceneType" },
|
||||
{ EXIFTAG_CFAPATTERN, -1, -1, TIFF_UNDEFINED, FIELD_CUSTOM,
|
||||
1, 1, "CFAPattern" },
|
||||
{ EXIFTAG_CUSTOMRENDERED, 1, 1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
1, 0, "CustomRendered" },
|
||||
{ EXIFTAG_EXPOSUREMODE, 1, 1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
1, 0, "ExposureMode" },
|
||||
{ EXIFTAG_WHITEBALANCE, 1, 1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
1, 0, "WhiteBalance" },
|
||||
{ EXIFTAG_DIGITALZOOMRATIO, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
1, 0, "DigitalZoomRatio" },
|
||||
{ EXIFTAG_FOCALLENGTHIN35MMFILM, 1, 1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
1, 0, "FocalLengthIn35mmFilm" },
|
||||
{ EXIFTAG_SCENECAPTURETYPE, 1, 1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
1, 0, "SceneCaptureType" },
|
||||
{ EXIFTAG_GAINCONTROL, 1, 1, TIFF_RATIONAL, FIELD_CUSTOM,
|
||||
1, 0, "GainControl" },
|
||||
{ EXIFTAG_CONTRAST, 1, 1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
1, 0, "Contrast" },
|
||||
{ EXIFTAG_SATURATION, 1, 1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
1, 0, "Saturation" },
|
||||
{ EXIFTAG_SHARPNESS, 1, 1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
1, 0, "Sharpness" },
|
||||
{ EXIFTAG_DEVICESETTINGDESCRIPTION, -1, -1, TIFF_UNDEFINED, FIELD_CUSTOM,
|
||||
1, 1, "DeviceSettingDescription" },
|
||||
{ EXIFTAG_SUBJECTDISTANCERANGE, 1, 1, TIFF_SHORT, FIELD_CUSTOM,
|
||||
1, 0, "SubjectDistanceRange" },
|
||||
{ EXIFTAG_IMAGEUNIQUEID, 33, 33, TIFF_ASCII, FIELD_CUSTOM,
|
||||
1, 0, "ImageUniqueID" }
|
||||
};
|
||||
|
||||
const TIFFFieldInfo *
|
||||
_TIFFGetFieldInfo(size_t *size)
|
||||
{
|
||||
*size = TIFFArrayCount(tiffFieldInfo);
|
||||
return tiffFieldInfo;
|
||||
}
|
||||
|
||||
const TIFFFieldInfo *
|
||||
_TIFFGetExifFieldInfo(size_t *size)
|
||||
{
|
||||
*size = TIFFArrayCount(exifFieldInfo);
|
||||
return exifFieldInfo;
|
||||
}
|
||||
|
||||
void
|
||||
_TIFFSetupFieldInfo(TIFF* tif, const TIFFFieldInfo info[], size_t n)
|
||||
{
|
||||
if (tif->tif_fieldinfo) {
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < tif->tif_nfields; i++)
|
||||
{
|
||||
TIFFFieldInfo *fld = tif->tif_fieldinfo[i];
|
||||
if (fld->field_bit == FIELD_CUSTOM &&
|
||||
strncmp("Tag ", fld->field_name, 4) == 0) {
|
||||
_TIFFfree(fld->field_name);
|
||||
_TIFFfree(fld);
|
||||
}
|
||||
}
|
||||
|
||||
_TIFFfree(tif->tif_fieldinfo);
|
||||
tif->tif_nfields = 0;
|
||||
}
|
||||
if (!_TIFFMergeFieldInfo(tif, info, n))
|
||||
{
|
||||
TIFFErrorExt(tif->tif_clientdata, "_TIFFSetupFieldInfo",
|
||||
"Setting up field info failed");
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
tagCompare(const void* a, const void* b)
|
||||
{
|
||||
const TIFFFieldInfo* ta = *(const TIFFFieldInfo**) a;
|
||||
const TIFFFieldInfo* tb = *(const TIFFFieldInfo**) b;
|
||||
/* NB: be careful of return values for 16-bit platforms */
|
||||
if (ta->field_tag != tb->field_tag)
|
||||
return (int)ta->field_tag - (int)tb->field_tag;
|
||||
else
|
||||
return (ta->field_type == TIFF_ANY) ?
|
||||
0 : ((int)tb->field_type - (int)ta->field_type);
|
||||
}
|
||||
|
||||
static int
|
||||
tagNameCompare(const void* a, const void* b)
|
||||
{
|
||||
const TIFFFieldInfo* ta = *(const TIFFFieldInfo**) a;
|
||||
const TIFFFieldInfo* tb = *(const TIFFFieldInfo**) b;
|
||||
int ret = strcmp(ta->field_name, tb->field_name);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
else
|
||||
return (ta->field_type == TIFF_ANY) ?
|
||||
0 : ((int)tb->field_type - (int)ta->field_type);
|
||||
}
|
||||
|
||||
void
|
||||
TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], int n)
|
||||
{
|
||||
if (_TIFFMergeFieldInfo(tif, info, n) < 0)
|
||||
{
|
||||
TIFFErrorExt(tif->tif_clientdata, "TIFFMergeFieldInfo",
|
||||
"Merging block of %d fields failed", n);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
_TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], int n)
|
||||
{
|
||||
static const char module[] = "_TIFFMergeFieldInfo";
|
||||
static const char reason[] = "for field info array";
|
||||
TIFFFieldInfo** tp;
|
||||
int i;
|
||||
|
||||
tif->tif_foundfield = NULL;
|
||||
|
||||
if (tif->tif_nfields > 0) {
|
||||
tif->tif_fieldinfo = (TIFFFieldInfo**)
|
||||
_TIFFCheckRealloc(tif, tif->tif_fieldinfo,
|
||||
(tif->tif_nfields + n),
|
||||
sizeof (TIFFFieldInfo*), reason);
|
||||
} else {
|
||||
tif->tif_fieldinfo = (TIFFFieldInfo**)
|
||||
_TIFFCheckMalloc(tif, n, sizeof (TIFFFieldInfo*),
|
||||
reason);
|
||||
}
|
||||
if (!tif->tif_fieldinfo) {
|
||||
TIFFErrorExt(tif->tif_clientdata, module,
|
||||
"Failed to allocate field info array");
|
||||
return 0;
|
||||
}
|
||||
tp = tif->tif_fieldinfo + tif->tif_nfields;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
const TIFFFieldInfo *fip =
|
||||
_TIFFFindFieldInfo(tif, info[i].field_tag, info[i].field_type);
|
||||
|
||||
/* only add definitions that aren't already present */
|
||||
if (!fip) {
|
||||
*tp++ = (TIFFFieldInfo*) (info + i);
|
||||
tif->tif_nfields++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Sort the field info by tag number */
|
||||
qsort(tif->tif_fieldinfo, tif->tif_nfields,
|
||||
sizeof (TIFFFieldInfo*), tagCompare);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void
|
||||
_TIFFPrintFieldInfo(TIFF* tif, FILE* fd)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
fprintf(fd, "%s: \n", tif->tif_name);
|
||||
for (i = 0; i < tif->tif_nfields; i++) {
|
||||
const TIFFFieldInfo* fip = tif->tif_fieldinfo[i];
|
||||
fprintf(fd, "field[%2d] %5lu, %2d, %2d, %d, %2d, %5s, %5s, %s\n"
|
||||
, (int)i
|
||||
, (unsigned long) fip->field_tag
|
||||
, fip->field_readcount, fip->field_writecount
|
||||
, fip->field_type
|
||||
, fip->field_bit
|
||||
, fip->field_oktochange ? "TRUE" : "FALSE"
|
||||
, fip->field_passcount ? "TRUE" : "FALSE"
|
||||
, fip->field_name
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return size of TIFFDataType in bytes
|
||||
*/
|
||||
int
|
||||
TIFFDataWidth(TIFFDataType type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case 0: /* nothing */
|
||||
case 1: /* TIFF_BYTE */
|
||||
case 2: /* TIFF_ASCII */
|
||||
case 6: /* TIFF_SBYTE */
|
||||
case 7: /* TIFF_UNDEFINED */
|
||||
return 1;
|
||||
case 3: /* TIFF_SHORT */
|
||||
case 8: /* TIFF_SSHORT */
|
||||
return 2;
|
||||
case 4: /* TIFF_LONG */
|
||||
case 9: /* TIFF_SLONG */
|
||||
case 11: /* TIFF_FLOAT */
|
||||
case 13: /* TIFF_IFD */
|
||||
return 4;
|
||||
case 5: /* TIFF_RATIONAL */
|
||||
case 10: /* TIFF_SRATIONAL */
|
||||
case 12: /* TIFF_DOUBLE */
|
||||
return 8;
|
||||
default:
|
||||
return 0; /* will return 0 for unknown types */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return size of TIFFDataType in bytes.
|
||||
*
|
||||
* XXX: We need a separate function to determine the space needed
|
||||
* to store the value. For TIFF_RATIONAL values TIFFDataWidth() returns 8,
|
||||
* but we use 4-byte float to represent rationals.
|
||||
*/
|
||||
int
|
||||
_TIFFDataSize(TIFFDataType type)
|
||||
{
|
||||
switch (type) {
|
||||
case TIFF_BYTE:
|
||||
case TIFF_SBYTE:
|
||||
case TIFF_ASCII:
|
||||
case TIFF_UNDEFINED:
|
||||
return 1;
|
||||
case TIFF_SHORT:
|
||||
case TIFF_SSHORT:
|
||||
return 2;
|
||||
case TIFF_LONG:
|
||||
case TIFF_SLONG:
|
||||
case TIFF_FLOAT:
|
||||
case TIFF_IFD:
|
||||
case TIFF_RATIONAL:
|
||||
case TIFF_SRATIONAL:
|
||||
return 4;
|
||||
case TIFF_DOUBLE:
|
||||
return 8;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return nearest TIFFDataType to the sample type of an image.
|
||||
*/
|
||||
TIFFDataType
|
||||
_TIFFSampleToTagType(TIFF* tif)
|
||||
{
|
||||
uint32 bps = TIFFhowmany8(tif->tif_dir.td_bitspersample);
|
||||
|
||||
switch (tif->tif_dir.td_sampleformat) {
|
||||
case SAMPLEFORMAT_IEEEFP:
|
||||
return (bps == 4 ? TIFF_FLOAT : TIFF_DOUBLE);
|
||||
case SAMPLEFORMAT_INT:
|
||||
return (bps <= 1 ? TIFF_SBYTE :
|
||||
bps <= 2 ? TIFF_SSHORT : TIFF_SLONG);
|
||||
case SAMPLEFORMAT_UINT:
|
||||
return (bps <= 1 ? TIFF_BYTE :
|
||||
bps <= 2 ? TIFF_SHORT : TIFF_LONG);
|
||||
case SAMPLEFORMAT_VOID:
|
||||
return (TIFF_UNDEFINED);
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
return (TIFF_UNDEFINED);
|
||||
}
|
||||
|
||||
const TIFFFieldInfo*
|
||||
_TIFFFindFieldInfo(TIFF* tif, ttag_t tag, TIFFDataType dt)
|
||||
{
|
||||
TIFFFieldInfo key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0};
|
||||
TIFFFieldInfo* pkey = &key;
|
||||
const TIFFFieldInfo **ret;
|
||||
|
||||
if (tif->tif_foundfield && tif->tif_foundfield->field_tag == tag &&
|
||||
(dt == TIFF_ANY || dt == tif->tif_foundfield->field_type))
|
||||
return tif->tif_foundfield;
|
||||
|
||||
/* If we are invoked with no field information, then just return. */
|
||||
if ( !tif->tif_fieldinfo ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* NB: use sorted search (e.g. binary search) */
|
||||
key.field_tag = tag;
|
||||
key.field_type = dt;
|
||||
|
||||
ret = (const TIFFFieldInfo **) bsearch(&pkey,
|
||||
tif->tif_fieldinfo,
|
||||
tif->tif_nfields,
|
||||
sizeof(TIFFFieldInfo *),
|
||||
tagCompare);
|
||||
return tif->tif_foundfield = (ret ? *ret : NULL);
|
||||
}
|
||||
|
||||
#undef lfind
|
||||
static void *
|
||||
lfind(const void *key, const void *base, size_t *nmemb, size_t size,
|
||||
int(*compar)(const void *, const void *))
|
||||
{
|
||||
char *element, *end;
|
||||
|
||||
end = (char *)base + *nmemb * size;
|
||||
for (element = (char *)base; element < end; element += size)
|
||||
if (!compar(element, key)) /* key found */
|
||||
return element;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
const TIFFFieldInfo*
|
||||
_TIFFFindFieldInfoByName(TIFF* tif, const char *field_name, TIFFDataType dt)
|
||||
{
|
||||
TIFFFieldInfo key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0};
|
||||
TIFFFieldInfo* pkey = &key;
|
||||
const TIFFFieldInfo **ret;
|
||||
|
||||
if (tif->tif_foundfield
|
||||
&& streq(tif->tif_foundfield->field_name, field_name)
|
||||
&& (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type))
|
||||
return (tif->tif_foundfield);
|
||||
|
||||
/* If we are invoked with no field information, then just return. */
|
||||
if ( !tif->tif_fieldinfo ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* NB: use sorted search (e.g. binary search) */
|
||||
key.field_name = (char *)field_name;
|
||||
key.field_type = dt;
|
||||
|
||||
ret = (const TIFFFieldInfo **) lfind(&pkey,
|
||||
tif->tif_fieldinfo,
|
||||
&tif->tif_nfields,
|
||||
sizeof(TIFFFieldInfo *),
|
||||
tagNameCompare);
|
||||
return tif->tif_foundfield = (ret ? *ret : NULL);
|
||||
}
|
||||
|
||||
const TIFFFieldInfo*
|
||||
_TIFFFieldWithTag(TIFF* tif, ttag_t tag)
|
||||
{
|
||||
const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
|
||||
if (!fip) {
|
||||
TIFFErrorExt(tif->tif_clientdata, "TIFFFieldWithTag",
|
||||
"Internal error, unknown tag 0x%x",
|
||||
(unsigned int) tag);
|
||||
assert(fip != NULL);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
return (fip);
|
||||
}
|
||||
|
||||
const TIFFFieldInfo*
|
||||
_TIFFFieldWithName(TIFF* tif, const char *field_name)
|
||||
{
|
||||
const TIFFFieldInfo* fip =
|
||||
_TIFFFindFieldInfoByName(tif, field_name, TIFF_ANY);
|
||||
if (!fip) {
|
||||
TIFFErrorExt(tif->tif_clientdata, "TIFFFieldWithName",
|
||||
"Internal error, unknown tag %s", field_name);
|
||||
assert(fip != NULL);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
return (fip);
|
||||
}
|
||||
|
||||
const TIFFFieldInfo*
|
||||
_TIFFFindOrRegisterFieldInfo( TIFF *tif, ttag_t tag, TIFFDataType dt )
|
||||
|
||||
{
|
||||
const TIFFFieldInfo *fld;
|
||||
|
||||
fld = _TIFFFindFieldInfo( tif, tag, dt );
|
||||
if( fld == NULL )
|
||||
{
|
||||
fld = _TIFFCreateAnonFieldInfo( tif, tag, dt );
|
||||
if (!_TIFFMergeFieldInfo(tif, fld, 1))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return fld;
|
||||
}
|
||||
|
||||
TIFFFieldInfo*
|
||||
_TIFFCreateAnonFieldInfo(TIFF *tif, ttag_t tag, TIFFDataType field_type)
|
||||
{
|
||||
TIFFFieldInfo *fld;
|
||||
(void) tif;
|
||||
|
||||
fld = (TIFFFieldInfo *) _TIFFmalloc(sizeof (TIFFFieldInfo));
|
||||
if (fld == NULL)
|
||||
return NULL;
|
||||
_TIFFmemset( fld, 0, sizeof(TIFFFieldInfo) );
|
||||
|
||||
fld->field_tag = tag;
|
||||
fld->field_readcount = TIFF_VARIABLE2;
|
||||
fld->field_writecount = TIFF_VARIABLE2;
|
||||
fld->field_type = field_type;
|
||||
fld->field_bit = FIELD_CUSTOM;
|
||||
fld->field_oktochange = TRUE;
|
||||
fld->field_passcount = TRUE;
|
||||
fld->field_name = (char *) _TIFFmalloc(32);
|
||||
if (fld->field_name == NULL) {
|
||||
_TIFFfree(fld);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* note that this name is a special sign to TIFFClose() and
|
||||
* _TIFFSetupFieldInfo() to free the field
|
||||
*/
|
||||
sprintf(fld->field_name, "Tag %d", (int) tag);
|
||||
|
||||
return fld;
|
||||
}
|
||||
|
||||
/* vim: set ts=8 sts=8 sw=8 noet: */
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 8
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
2081
thirdparty/libtiff/tif_dirread.c
vendored
Normal file
2081
thirdparty/libtiff/tif_dirread.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1414
thirdparty/libtiff/tif_dirwrite.c
vendored
Normal file
1414
thirdparty/libtiff/tif_dirwrite.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
126
thirdparty/libtiff/tif_dumpmode.c
vendored
Normal file
126
thirdparty/libtiff/tif_dumpmode.c
vendored
Normal file
@ -0,0 +1,126 @@
|
||||
/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_dumpmode.c,v 1.5.2.2 2010-06-08 18:50:42 bfriesen Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that (i) the above copyright notices and this permission notice appear in
|
||||
* all copies of the software and related documentation, and (ii) the names of
|
||||
* Sam Leffler and Silicon Graphics may not be used in any advertising or
|
||||
* publicity relating to the software without the specific, prior written
|
||||
* permission of Sam Leffler and Silicon Graphics.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
||||
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
|
||||
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
||||
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
||||
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TIFF Library.
|
||||
*
|
||||
* "Null" Compression Algorithm Support.
|
||||
*/
|
||||
#include "tiffiop.h"
|
||||
|
||||
/*
|
||||
* Encode a hunk of pixels.
|
||||
*/
|
||||
static int
|
||||
DumpModeEncode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s)
|
||||
{
|
||||
(void) s;
|
||||
while (cc > 0) {
|
||||
tsize_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 (-1);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode a hunk of pixels.
|
||||
*/
|
||||
static int
|
||||
DumpModeDecode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s)
|
||||
{
|
||||
(void) s;
|
||||
/* fprintf(stderr,"DumpModeDecode: scanline %ld, expected %ld bytes, got %ld bytes\n", */
|
||||
/* (long) tif->tif_row, (long) tif->tif_rawcc, (long) cc); */
|
||||
if (tif->tif_rawcc < cc) {
|
||||
TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
|
||||
"DumpModeDecode: Not enough data for scanline %d",
|
||||
tif->tif_row);
|
||||
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 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_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);
|
||||
}
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 8
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
80
thirdparty/libtiff/tif_error.c
vendored
Normal file
80
thirdparty/libtiff/tif_error.c
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_error.c,v 1.4.2.1 2010-06-08 18:50:42 bfriesen Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that (i) the above copyright notices and this permission notice appear in
|
||||
* all copies of the software and related documentation, and (ii) the names of
|
||||
* Sam Leffler and Silicon Graphics may not be used in any advertising or
|
||||
* publicity relating to the software without the specific, prior written
|
||||
* permission of Sam Leffler and Silicon Graphics.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
||||
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
|
||||
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
||||
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
||||
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TIFF Library.
|
||||
*/
|
||||
#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;
|
||||
va_start(ap, fmt);
|
||||
if (_TIFFerrorHandler)
|
||||
(*_TIFFerrorHandler)(module, fmt, ap);
|
||||
if (_TIFFerrorHandlerExt)
|
||||
(*_TIFFerrorHandlerExt)(0, module, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
TIFFErrorExt(thandle_t fd, const char* module, const char* fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
if (_TIFFerrorHandler)
|
||||
(*_TIFFerrorHandler)(module, fmt, ap);
|
||||
if (_TIFFerrorHandlerExt)
|
||||
(*_TIFFerrorHandlerExt)(fd, module, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 8
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
118
thirdparty/libtiff/tif_extension.c
vendored
Normal file
118
thirdparty/libtiff/tif_extension.c
vendored
Normal file
@ -0,0 +1,118 @@
|
||||
/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_extension.c,v 1.4.2.1 2010-06-08 18:50:42 bfriesen Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that (i) the above copyright notices and this permission notice appear in
|
||||
* all copies of the software and related documentation, and (ii) the names of
|
||||
* Sam Leffler and Silicon Graphics may not be used in any advertising or
|
||||
* publicity relating to the software without the specific, prior written
|
||||
* permission of Sam Leffler and Silicon Graphics.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
||||
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
|
||||
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
||||
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
||||
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TIFF Library.
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
|
||||
ttag_t TIFFGetTagListEntry( TIFF *tif, int tag_index )
|
||||
|
||||
{
|
||||
TIFFDirectory* td = &tif->tif_dir;
|
||||
|
||||
if( tag_index < 0 || tag_index >= td->td_customValueCount )
|
||||
return (ttag_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 *link = tif->tif_clientinfo;
|
||||
|
||||
while( link != NULL && strcmp(link->name,name) != 0 )
|
||||
link = link->next;
|
||||
|
||||
if( link != NULL )
|
||||
return link->data;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void TIFFSetClientInfo( TIFF *tif, void *data, const char *name )
|
||||
|
||||
{
|
||||
TIFFClientInfoLink *link = tif->tif_clientinfo;
|
||||
|
||||
/*
|
||||
** Do we have an existing link with this name? If so, just
|
||||
** set it.
|
||||
*/
|
||||
while( link != NULL && strcmp(link->name,name) != 0 )
|
||||
link = link->next;
|
||||
|
||||
if( link != NULL )
|
||||
{
|
||||
link->data = data;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
** Create a new link.
|
||||
*/
|
||||
|
||||
link = (TIFFClientInfoLink *) _TIFFmalloc(sizeof(TIFFClientInfoLink));
|
||||
assert (link != NULL);
|
||||
link->next = tif->tif_clientinfo;
|
||||
link->name = (char *) _TIFFmalloc(strlen(name)+1);
|
||||
assert (link->name != NULL);
|
||||
strcpy(link->name, name);
|
||||
link->data = data;
|
||||
|
||||
tif->tif_clientinfo = link;
|
||||
}
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 8
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
1626
thirdparty/libtiff/tif_fax3.c
vendored
Normal file
1626
thirdparty/libtiff/tif_fax3.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
532
thirdparty/libtiff/tif_fax3.h
vendored
Normal file
532
thirdparty/libtiff/tif_fax3.h
vendored
Normal file
@ -0,0 +1,532 @@
|
||||
/* $Id: tif_fax3.h,v 1.5.2.1 2010-06-08 18:50:42 bfriesen Exp $ */
|
||||
|
||||
/*
|
||||
* 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 pseduo tag TIFFTAG_FAXFILLFUNC.
|
||||
* The routine must have the type signature given below;
|
||||
* for example:
|
||||
*
|
||||
* fillruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 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*, uint32*, uint32);
|
||||
|
||||
/*
|
||||
* The default run filler; made external for other decoders.
|
||||
*/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
extern void _TIFFFax3fillruns(unsigned char*, uint32*, uint32*, uint32);
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* finite state machine codes */
|
||||
#define S_Null 0
|
||||
#define S_Pass 1
|
||||
#define S_Horiz 2
|
||||
#define S_V0 3
|
||||
#define S_VR 4
|
||||
#define S_VL 5
|
||||
#define S_Ext 6
|
||||
#define S_TermW 7
|
||||
#define S_TermB 8
|
||||
#define S_MakeUpW 9
|
||||
#define S_MakeUpB 10
|
||||
#define S_MakeUp 11
|
||||
#define S_EOL 12
|
||||
|
||||
typedef struct { /* state table entry */
|
||||
unsigned char State; /* see above */
|
||||
unsigned char Width; /* width of code in bits */
|
||||
uint32 Param; /* unsigned 32-bit run length in bits */
|
||||
} TIFFFaxTabEnt;
|
||||
|
||||
extern const TIFFFaxTabEnt TIFFFaxMainTable[];
|
||||
extern const TIFFFaxTabEnt TIFFFaxWhiteTable[];
|
||||
extern const TIFFFaxTabEnt TIFFFaxBlackTable[];
|
||||
|
||||
/*
|
||||
* 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) 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) 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) 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 { \
|
||||
*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) do { \
|
||||
if (EOLcnt == 0) { \
|
||||
for (;;) { \
|
||||
NeedBits16(11,eoflab); \
|
||||
if (GetBits(11) == 0) \
|
||||
break; \
|
||||
ClrBits(1); \
|
||||
} \
|
||||
} \
|
||||
for (;;) { \
|
||||
NeedBits8(8,eoflab); \
|
||||
if (GetBits(8)) \
|
||||
break; \
|
||||
ClrBits(8); \
|
||||
} \
|
||||
while (GetBits(1) == 0) \
|
||||
ClrBits(1); \
|
||||
ClrBits(1); /* EOL bit */ \
|
||||
EOLcnt = 0; /* reset EOL counter/flag */ \
|
||||
} 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) { \
|
||||
b1 += pb[0] + pb[1]; \
|
||||
pb += 2; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Expand a row of 2D-encoded data.
|
||||
*/
|
||||
#define EXPAND2D(eoflab) do { \
|
||||
while (a0 < lastx) { \
|
||||
LOOKUP8(7, TIFFFaxMainTable, eof2d); \
|
||||
switch (TabEnt->State) { \
|
||||
case S_Pass: \
|
||||
CHECK_b1; \
|
||||
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); \
|
||||
b1 += *pb++; \
|
||||
break; \
|
||||
case S_VR: \
|
||||
CHECK_b1; \
|
||||
SETVALUE(b1 - a0 + TabEnt->Param); \
|
||||
b1 += *pb++; \
|
||||
break; \
|
||||
case S_VL: \
|
||||
CHECK_b1; \
|
||||
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_ */
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 8
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
1260
thirdparty/libtiff/tif_fax3sm.c
vendored
Normal file
1260
thirdparty/libtiff/tif_fax3sm.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
74
thirdparty/libtiff/tif_flush.c
vendored
Normal file
74
thirdparty/libtiff/tif_flush.c
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_flush.c,v 1.3.2.1 2010-06-08 18:50:42 bfriesen Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that (i) the above copyright notices and this permission notice appear in
|
||||
* all copies of the software and related documentation, and (ii) the names of
|
||||
* Sam Leffler and Silicon Graphics may not be used in any advertising or
|
||||
* publicity relating to the software without the specific, prior written
|
||||
* permission of Sam Leffler and Silicon Graphics.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
||||
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
|
||||
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
||||
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
||||
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TIFF Library.
|
||||
*/
|
||||
#include "tiffiop.h"
|
||||
|
||||
int
|
||||
TIFFFlush(TIFF* tif)
|
||||
{
|
||||
|
||||
if (tif->tif_mode != O_RDONLY) {
|
||||
if (!TIFFFlushData(tif))
|
||||
return (0);
|
||||
if ((tif->tif_flags & TIFF_DIRTYDIRECT) &&
|
||||
!TIFFWriteDirectory(tif))
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 (0);
|
||||
if (tif->tif_flags & TIFF_POSTENCODE) {
|
||||
tif->tif_flags &= ~TIFF_POSTENCODE;
|
||||
if (!(*tif->tif_postencode)(tif))
|
||||
return (0);
|
||||
}
|
||||
return (TIFFFlushData1(tif));
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 8
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
2676
thirdparty/libtiff/tif_getimage.c
vendored
Normal file
2676
thirdparty/libtiff/tif_getimage.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
385
thirdparty/libtiff/tif_jbig.c
vendored
Normal file
385
thirdparty/libtiff/tif_jbig.c
vendored
Normal file
@ -0,0 +1,385 @@
|
||||
/* $Id: tif_jbig.c,v 1.2.2.3 2010-06-08 18:50:42 bfriesen Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that (i) the above copyright notices and this permission notice appear in
|
||||
* all copies of the software and related documentation, and (ii) the names of
|
||||
* Sam Leffler and Silicon Graphics may not be used in any advertising or
|
||||
* publicity relating to the software without the specific, prior written
|
||||
* permission of Sam Leffler and Silicon Graphics.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
||||
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
|
||||
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
||||
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
||||
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TIFF Library.
|
||||
*
|
||||
* JBIG Compression Algorithm Support.
|
||||
* Contributed by Lee Howard <faxguy@deanox.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tiffiop.h"
|
||||
|
||||
#ifdef JBIG_SUPPORT
|
||||
#include "jbig.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32 recvparams; /* encoded Class 2 session params */
|
||||
char* subaddress; /* subaddress string */
|
||||
uint32 recvtime; /* time spend receiving in seconds */
|
||||
char* faxdcs; /* encoded fax parameters (DCS, Table 2/T.30) */
|
||||
|
||||
TIFFVGetMethod vgetparent;
|
||||
TIFFVSetMethod vsetparent;
|
||||
} JBIGState;
|
||||
|
||||
#define GetJBIGState(tif) ((JBIGState*)(tif)->tif_data)
|
||||
|
||||
#define FIELD_RECVPARAMS (FIELD_CODEC+0)
|
||||
#define FIELD_SUBADDRESS (FIELD_CODEC+1)
|
||||
#define FIELD_RECVTIME (FIELD_CODEC+2)
|
||||
#define FIELD_FAXDCS (FIELD_CODEC+3)
|
||||
|
||||
static const TIFFFieldInfo jbigFieldInfo[] =
|
||||
{
|
||||
{TIFFTAG_FAXRECVPARAMS, 1, 1, TIFF_LONG, FIELD_RECVPARAMS, TRUE, FALSE, "FaxRecvParams"},
|
||||
{TIFFTAG_FAXSUBADDRESS, -1, -1, TIFF_ASCII, FIELD_SUBADDRESS, TRUE, FALSE, "FaxSubAddress"},
|
||||
{TIFFTAG_FAXRECVTIME, 1, 1, TIFF_LONG, FIELD_RECVTIME, TRUE, FALSE, "FaxRecvTime"},
|
||||
{TIFFTAG_FAXDCS, -1, -1, TIFF_ASCII, FIELD_FAXDCS, TRUE, FALSE, "FaxDcs"},
|
||||
};
|
||||
|
||||
static int JBIGSetupDecode(TIFF* tif)
|
||||
{
|
||||
if (TIFFNumberOfStrips(tif) != 1)
|
||||
{
|
||||
TIFFError("JBIG", "Multistrip images not supported in decoder");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int JBIGDecode(TIFF* tif, tidata_t buffer, tsize_t size, tsample_t s)
|
||||
{
|
||||
struct jbg_dec_state decoder;
|
||||
int decodeStatus = 0;
|
||||
unsigned char* pImage = NULL;
|
||||
(void) size, (void) s;
|
||||
|
||||
if (isFillOrder(tif, tif->tif_dir.td_fillorder))
|
||||
{
|
||||
TIFFReverseBits(tif->tif_rawdata, tif->tif_rawdatasize);
|
||||
}
|
||||
|
||||
jbg_dec_init(&decoder);
|
||||
|
||||
#if defined(HAVE_JBG_NEWLEN)
|
||||
jbg_newlen(tif->tif_rawdata, tif->tif_rawdatasize);
|
||||
/*
|
||||
* I do not check the return status of jbg_newlen because even if this
|
||||
* function fails it does not necessarily mean that decoding the image
|
||||
* will fail. It is generally only needed for received fax images
|
||||
* that do not contain the actual length of the image in the BIE
|
||||
* header. I do not log when an error occurs because that will cause
|
||||
* problems when converting JBIG encoded TIFF's to
|
||||
* PostScript. As long as the actual image length is contained in the
|
||||
* BIE header jbg_dec_in should succeed.
|
||||
*/
|
||||
#endif /* HAVE_JBG_NEWLEN */
|
||||
|
||||
decodeStatus = jbg_dec_in(&decoder, tif->tif_rawdata,
|
||||
tif->tif_rawdatasize, NULL);
|
||||
if (JBG_EOK != decodeStatus)
|
||||
{
|
||||
/*
|
||||
* XXX: JBG_EN constant was defined in pre-2.0 releases of the
|
||||
* JBIG-KIT. Since the 2.0 the error reporting functions were
|
||||
* changed. We will handle both cases here.
|
||||
*/
|
||||
TIFFError("JBIG", "Error (%d) decoding: %s", decodeStatus,
|
||||
#if defined(JBG_EN)
|
||||
jbg_strerror(decodeStatus, JBG_EN)
|
||||
#else
|
||||
jbg_strerror(decodeStatus)
|
||||
#endif
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pImage = jbg_dec_getimage(&decoder, 0);
|
||||
_TIFFmemcpy(buffer, pImage, jbg_dec_getsize(&decoder));
|
||||
jbg_dec_free(&decoder);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int JBIGSetupEncode(TIFF* tif)
|
||||
{
|
||||
if (TIFFNumberOfStrips(tif) != 1)
|
||||
{
|
||||
TIFFError("JBIG", "Multistrip images not supported in encoder");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int JBIGCopyEncodedData(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s)
|
||||
{
|
||||
(void) s;
|
||||
while (cc > 0)
|
||||
{
|
||||
tsize_t n = cc;
|
||||
|
||||
if (tif->tif_rawcc + n > tif->tif_rawdatasize)
|
||||
{
|
||||
n = tif->tif_rawdatasize - tif->tif_rawcc;
|
||||
}
|
||||
|
||||
assert(n > 0);
|
||||
_TIFFmemcpy(tif->tif_rawcp, pp, n);
|
||||
tif->tif_rawcp += n;
|
||||
tif->tif_rawcc += n;
|
||||
pp += n;
|
||||
cc -= n;
|
||||
if (tif->tif_rawcc >= tif->tif_rawdatasize &&
|
||||
!TIFFFlushData1(tif))
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
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, len);
|
||||
}
|
||||
|
||||
JBIGCopyEncodedData(tif, buffer, len, 0);
|
||||
}
|
||||
|
||||
static int JBIGEncode(TIFF* tif, tidata_t buffer, tsize_t size, tsample_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;
|
||||
}
|
||||
|
||||
static void JBIGCleanup(TIFF* tif)
|
||||
{
|
||||
JBIGState *sp = GetJBIGState(tif);
|
||||
|
||||
assert(sp != 0);
|
||||
|
||||
tif->tif_tagmethods.vgetfield = sp->vgetparent;
|
||||
tif->tif_tagmethods.vsetfield = sp->vsetparent;
|
||||
|
||||
_TIFFfree(tif->tif_data);
|
||||
tif->tif_data = NULL;
|
||||
|
||||
_TIFFSetDefaultCompressionState(tif);
|
||||
}
|
||||
|
||||
static void JBIGPrintDir(TIFF* tif, FILE* fd, long flags)
|
||||
{
|
||||
JBIGState* codec = GetJBIGState(tif);
|
||||
(void)flags;
|
||||
|
||||
if (TIFFFieldSet(tif, FIELD_RECVPARAMS))
|
||||
{
|
||||
fprintf(fd,
|
||||
" Fax Receive Parameters: %08lx\n",
|
||||
(unsigned long)codec->recvparams);
|
||||
}
|
||||
|
||||
if (TIFFFieldSet(tif, FIELD_SUBADDRESS))
|
||||
{
|
||||
fprintf(fd,
|
||||
" Fax SubAddress: %s\n",
|
||||
codec->subaddress);
|
||||
}
|
||||
|
||||
if (TIFFFieldSet(tif, FIELD_RECVTIME))
|
||||
{
|
||||
fprintf(fd,
|
||||
" Fax Receive Time: %lu secs\n",
|
||||
(unsigned long)codec->recvtime);
|
||||
}
|
||||
|
||||
if (TIFFFieldSet(tif, FIELD_FAXDCS))
|
||||
{
|
||||
fprintf(fd,
|
||||
" Fax DCS: %s\n",
|
||||
codec->faxdcs);
|
||||
}
|
||||
}
|
||||
|
||||
static int JBIGVGetField(TIFF* tif, ttag_t tag, va_list ap)
|
||||
{
|
||||
JBIGState* codec = GetJBIGState(tif);
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
case TIFFTAG_FAXRECVPARAMS:
|
||||
*va_arg(ap, uint32*) = codec->recvparams;
|
||||
break;
|
||||
|
||||
case TIFFTAG_FAXSUBADDRESS:
|
||||
*va_arg(ap, char**) = codec->subaddress;
|
||||
break;
|
||||
|
||||
case TIFFTAG_FAXRECVTIME:
|
||||
*va_arg(ap, uint32*) = codec->recvtime;
|
||||
break;
|
||||
|
||||
case TIFFTAG_FAXDCS:
|
||||
*va_arg(ap, char**) = codec->faxdcs;
|
||||
break;
|
||||
|
||||
default:
|
||||
return (*codec->vgetparent)(tif, tag, ap);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int JBIGVSetField(TIFF* tif, ttag_t tag, va_list ap)
|
||||
{
|
||||
JBIGState* codec = GetJBIGState(tif);
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
case TIFFTAG_FAXRECVPARAMS:
|
||||
codec->recvparams = va_arg(ap, uint32);
|
||||
break;
|
||||
|
||||
case TIFFTAG_FAXSUBADDRESS:
|
||||
_TIFFsetString(&codec->subaddress, va_arg(ap, char*));
|
||||
break;
|
||||
|
||||
case TIFFTAG_FAXRECVTIME:
|
||||
codec->recvtime = va_arg(ap, uint32);
|
||||
break;
|
||||
|
||||
case TIFFTAG_FAXDCS:
|
||||
_TIFFsetString(&codec->faxdcs, va_arg(ap, char*));
|
||||
break;
|
||||
|
||||
default:
|
||||
return (*codec->vsetparent)(tif, tag, ap);
|
||||
}
|
||||
|
||||
TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit);
|
||||
tif->tif_flags |= TIFF_DIRTYDIRECT;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int TIFFInitJBIG(TIFF* tif, int scheme)
|
||||
{
|
||||
JBIGState* codec = NULL;
|
||||
|
||||
assert(scheme == COMPRESSION_JBIG);
|
||||
|
||||
/*
|
||||
* Merge codec-specific tag information.
|
||||
*/
|
||||
if (!_TIFFMergeFieldInfo(tif, jbigFieldInfo,
|
||||
TIFFArrayCount(jbigFieldInfo))) {
|
||||
TIFFErrorExt(tif->tif_clientdata, "TIFFInitJBIG",
|
||||
"Merging JBIG codec-specific tags failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Allocate memory for the JBIGState structure.*/
|
||||
tif->tif_data = (tdata_t)_TIFFmalloc(sizeof(JBIGState));
|
||||
if (tif->tif_data == NULL)
|
||||
{
|
||||
TIFFError("TIFFInitJBIG", "Not enough memory for JBIGState");
|
||||
return 0;
|
||||
}
|
||||
_TIFFmemset(tif->tif_data, 0, sizeof(JBIGState));
|
||||
codec = GetJBIGState(tif);
|
||||
|
||||
/* Initialize codec private fields */
|
||||
codec->recvparams = 0;
|
||||
codec->subaddress = NULL;
|
||||
codec->faxdcs = NULL;
|
||||
codec->recvtime = 0;
|
||||
|
||||
/*
|
||||
* Override parent get/set field methods.
|
||||
*/
|
||||
codec->vgetparent = tif->tif_tagmethods.vgetfield;
|
||||
codec->vsetparent = tif->tif_tagmethods.vsetfield;
|
||||
tif->tif_tagmethods.vgetfield = JBIGVGetField;
|
||||
tif->tif_tagmethods.vsetfield = JBIGVSetField;
|
||||
tif->tif_tagmethods.printdir = JBIGPrintDir;
|
||||
|
||||
/*
|
||||
* These flags are set so the JBIG Codec can control when to reverse
|
||||
* bits and when not to and to allow the jbig decoder and bit reverser
|
||||
* to write to memory when necessary.
|
||||
*/
|
||||
tif->tif_flags |= TIFF_NOBITREV;
|
||||
tif->tif_flags &= ~TIFF_MAPPED;
|
||||
|
||||
/* Setup the function pointers for encode, decode, and cleanup. */
|
||||
tif->tif_setupdecode = JBIGSetupDecode;
|
||||
tif->tif_decodestrip = JBIGDecode;
|
||||
|
||||
tif->tif_setupencode = JBIGSetupEncode;
|
||||
tif->tif_encodestrip = JBIGEncode;
|
||||
|
||||
tif->tif_cleanup = JBIGCleanup;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* JBIG_SUPPORT */
|
||||
|
||||
/* vim: set ts=8 sts=8 sw=8 noet: */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 8
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
2065
thirdparty/libtiff/tif_jpeg.c
vendored
Normal file
2065
thirdparty/libtiff/tif_jpeg.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1629
thirdparty/libtiff/tif_luv.c
vendored
Normal file
1629
thirdparty/libtiff/tif_luv.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1129
thirdparty/libtiff/tif_lzw.c
vendored
Normal file
1129
thirdparty/libtiff/tif_lzw.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
154
thirdparty/libtiff/tif_next.c
vendored
Normal file
154
thirdparty/libtiff/tif_next.c
vendored
Normal file
@ -0,0 +1,154 @@
|
||||
/* $Id: tif_next.c,v 1.8.2.1 2010-06-08 18:50:42 bfriesen Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that (i) the above copyright notices and this permission notice appear in
|
||||
* all copies of the software and related documentation, and (ii) the names of
|
||||
* Sam Leffler and Silicon Graphics may not be used in any advertising or
|
||||
* publicity relating to the software without the specific, prior written
|
||||
* permission of Sam Leffler and Silicon Graphics.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
||||
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
|
||||
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
||||
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
||||
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#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); break; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define LITERALROW 0x00
|
||||
#define LITERALSPAN 0x40
|
||||
#define WHITE ((1<<2)-1)
|
||||
|
||||
static int
|
||||
NeXTDecode(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s)
|
||||
{
|
||||
unsigned char *bp, *op;
|
||||
tsize_t cc;
|
||||
tidata_t row;
|
||||
tsize_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 = buf, cc = occ; cc-- > 0;)
|
||||
*op++ = 0xff;
|
||||
|
||||
bp = (unsigned char *)tif->tif_rawcp;
|
||||
cc = tif->tif_rawcc;
|
||||
scanline = tif->tif_scanlinesize;
|
||||
for (row = buf; occ > 0; occ -= scanline, row += scanline) {
|
||||
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: {
|
||||
tsize_t off;
|
||||
/*
|
||||
* The scanline has a literal span that begins at some
|
||||
* offset.
|
||||
*/
|
||||
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 npixels = 0, grey;
|
||||
uint32 imagewidth = tif->tif_dir.td_imagewidth;
|
||||
|
||||
/*
|
||||
* 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 = (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)
|
||||
SETPIXEL(op, grey);
|
||||
if (npixels >= imagewidth)
|
||||
break;
|
||||
if (cc == 0)
|
||||
goto bad;
|
||||
n = *bp++, cc--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
tif->tif_rawcp = (tidata_t) bp;
|
||||
tif->tif_rawcc = cc;
|
||||
return (1);
|
||||
bad:
|
||||
TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "NeXTDecode: Not enough data for scanline %ld",
|
||||
(long) tif->tif_row);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
TIFFInitNeXT(TIFF* tif, int scheme)
|
||||
{
|
||||
(void) scheme;
|
||||
tif->tif_decoderow = NeXTDecode;
|
||||
tif->tif_decodestrip = NeXTDecode;
|
||||
tif->tif_decodetile = NeXTDecode;
|
||||
return (1);
|
||||
}
|
||||
#endif /* NEXT_SUPPORT */
|
||||
|
||||
/* vim: set ts=8 sts=8 sw=8 noet: */
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 8
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
2438
thirdparty/libtiff/tif_ojpeg.c
vendored
Normal file
2438
thirdparty/libtiff/tif_ojpeg.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
695
thirdparty/libtiff/tif_open.c
vendored
Normal file
695
thirdparty/libtiff/tif_open.c
vendored
Normal file
@ -0,0 +1,695 @@
|
||||
/* $Id: tif_open.c,v 1.33.2.1 2010-06-08 18:50:42 bfriesen Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that (i) the above copyright notices and this permission notice appear in
|
||||
* all copies of the software and related documentation, and (ii) the names of
|
||||
* Sam Leffler and Silicon Graphics may not be used in any advertising or
|
||||
* publicity relating to the software without the specific, prior written
|
||||
* permission of Sam Leffler and Silicon Graphics.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
||||
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
|
||||
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
||||
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
||||
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TIFF Library.
|
||||
*/
|
||||
#include "tiffiop.h"
|
||||
|
||||
static const long typemask[13] = {
|
||||
(long)0L, /* TIFF_NOTYPE */
|
||||
(long)0x000000ffL, /* TIFF_BYTE */
|
||||
(long)0xffffffffL, /* TIFF_ASCII */
|
||||
(long)0x0000ffffL, /* TIFF_SHORT */
|
||||
(long)0xffffffffL, /* TIFF_LONG */
|
||||
(long)0xffffffffL, /* TIFF_RATIONAL */
|
||||
(long)0x000000ffL, /* TIFF_SBYTE */
|
||||
(long)0x000000ffL, /* TIFF_UNDEFINED */
|
||||
(long)0x0000ffffL, /* TIFF_SSHORT */
|
||||
(long)0xffffffffL, /* TIFF_SLONG */
|
||||
(long)0xffffffffL, /* TIFF_SRATIONAL */
|
||||
(long)0xffffffffL, /* TIFF_FLOAT */
|
||||
(long)0xffffffffL, /* TIFF_DOUBLE */
|
||||
};
|
||||
static const int bigTypeshift[13] = {
|
||||
0, /* TIFF_NOTYPE */
|
||||
24, /* TIFF_BYTE */
|
||||
0, /* TIFF_ASCII */
|
||||
16, /* TIFF_SHORT */
|
||||
0, /* TIFF_LONG */
|
||||
0, /* TIFF_RATIONAL */
|
||||
24, /* TIFF_SBYTE */
|
||||
24, /* TIFF_UNDEFINED */
|
||||
16, /* TIFF_SSHORT */
|
||||
0, /* TIFF_SLONG */
|
||||
0, /* TIFF_SRATIONAL */
|
||||
0, /* TIFF_FLOAT */
|
||||
0, /* TIFF_DOUBLE */
|
||||
};
|
||||
static const int litTypeshift[13] = {
|
||||
0, /* TIFF_NOTYPE */
|
||||
0, /* TIFF_BYTE */
|
||||
0, /* TIFF_ASCII */
|
||||
0, /* TIFF_SHORT */
|
||||
0, /* TIFF_LONG */
|
||||
0, /* TIFF_RATIONAL */
|
||||
0, /* TIFF_SBYTE */
|
||||
0, /* TIFF_UNDEFINED */
|
||||
0, /* TIFF_SSHORT */
|
||||
0, /* TIFF_SLONG */
|
||||
0, /* TIFF_SRATIONAL */
|
||||
0, /* TIFF_FLOAT */
|
||||
0, /* TIFF_DOUBLE */
|
||||
};
|
||||
|
||||
/*
|
||||
* Dummy functions to fill the omitted client procedures.
|
||||
*/
|
||||
static int
|
||||
_tiffDummyMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize)
|
||||
{
|
||||
(void) fd; (void) pbase; (void) psize;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
_tiffDummyUnmapProc(thandle_t fd, tdata_t base, toff_t size)
|
||||
{
|
||||
(void) fd; (void) base; (void) size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the shift & mask tables, and the
|
||||
* byte swapping state according to the file
|
||||
* contents and the machine architecture.
|
||||
*/
|
||||
static void
|
||||
TIFFInitOrder(TIFF* tif, int magic)
|
||||
{
|
||||
tif->tif_typemask = typemask;
|
||||
if (magic == TIFF_BIGENDIAN) {
|
||||
tif->tif_typeshift = bigTypeshift;
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
tif->tif_flags |= TIFF_SWAB;
|
||||
#endif
|
||||
} else {
|
||||
tif->tif_typeshift = litTypeshift;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
tif->tif_flags |= TIFF_SWAB;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
_TIFFgetMode(const char* mode, const char* module)
|
||||
{
|
||||
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:
|
||||
TIFFErrorExt(0, module, "\"%s\": Bad mode", mode);
|
||||
break;
|
||||
}
|
||||
return (m);
|
||||
}
|
||||
|
||||
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
|
||||
)
|
||||
{
|
||||
static const char module[] = "TIFFClientOpen";
|
||||
TIFF *tif;
|
||||
int m;
|
||||
const char* cp;
|
||||
|
||||
m = _TIFFgetMode(mode, module);
|
||||
if (m == -1)
|
||||
goto bad2;
|
||||
tif = (TIFF *)_TIFFmalloc(sizeof (TIFF) + strlen(name) + 1);
|
||||
if (tif == NULL) {
|
||||
TIFFErrorExt(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 = (tdir_t) -1; /* non-existent directory */
|
||||
tif->tif_curoff = 0;
|
||||
tif->tif_curstrip = (tstrip_t) -1; /* invalid strip */
|
||||
tif->tif_row = (uint32) -1; /* read/write pre-increment */
|
||||
tif->tif_clientdata = clientdata;
|
||||
if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc) {
|
||||
TIFFErrorExt(clientdata, module,
|
||||
"One of the client procedures is NULL pointer.");
|
||||
goto bad2;
|
||||
}
|
||||
tif->tif_readproc = readproc;
|
||||
tif->tif_writeproc = writeproc;
|
||||
tif->tif_seekproc = seekproc;
|
||||
tif->tif_closeproc = closeproc;
|
||||
tif->tif_sizeproc = sizeproc;
|
||||
if (mapproc)
|
||||
tif->tif_mapproc = mapproc;
|
||||
else
|
||||
tif->tif_mapproc = _tiffDummyMapProc;
|
||||
if (unmapproc)
|
||||
tif->tif_unmapproc = unmapproc;
|
||||
else
|
||||
tif->tif_unmapproc = _tiffDummyUnmapProc;
|
||||
_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
|
||||
* behaviour that may or may not be desirable (usually for
|
||||
* compatibility with some application that claims to support
|
||||
* TIFF but only supports some braindead idea of what the
|
||||
* vendor thinks TIFF is):
|
||||
*
|
||||
* 'l' use little-endian byte order for creating a file
|
||||
* 'b' use big-endian byte order for creating a file
|
||||
* 'L' read/write information using LSB2MSB bit order
|
||||
* 'B' read/write information using MSB2LSB bit order
|
||||
* 'H' read/write information using host bit order
|
||||
* 'M' enable use of memory-mapped files when supported
|
||||
* 'm' disable use of memory-mapped files
|
||||
* 'C' enable strip chopping support when reading
|
||||
* 'c' disable strip chopping support
|
||||
* 'h' read TIFF header only, do not load the first IFD
|
||||
*
|
||||
* 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 compatibiltiy 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 behaviour 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':
|
||||
tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
|
||||
HOST_FILLORDER;
|
||||
break;
|
||||
case 'M':
|
||||
if (m == O_RDONLY)
|
||||
tif->tif_flags |= TIFF_MAPPED;
|
||||
break;
|
||||
case 'm':
|
||||
if (m == O_RDONLY)
|
||||
tif->tif_flags &= ~TIFF_MAPPED;
|
||||
break;
|
||||
case 'C':
|
||||
if (m == O_RDONLY)
|
||||
tif->tif_flags |= TIFF_STRIPCHOP;
|
||||
break;
|
||||
case 'c':
|
||||
if (m == O_RDONLY)
|
||||
tif->tif_flags &= ~TIFF_STRIPCHOP;
|
||||
break;
|
||||
case 'h':
|
||||
tif->tif_flags |= TIFF_HEADERONLY;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Read in TIFF header.
|
||||
*/
|
||||
if (tif->tif_mode & O_TRUNC ||
|
||||
!ReadOK(tif, &tif->tif_header, sizeof (TIFFHeader))) {
|
||||
if (tif->tif_mode == O_RDONLY) {
|
||||
TIFFErrorExt(tif->tif_clientdata, name,
|
||||
"Cannot read TIFF header");
|
||||
goto bad;
|
||||
}
|
||||
/*
|
||||
* Setup header and write.
|
||||
*/
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
tif->tif_header.tiff_magic = tif->tif_flags & TIFF_SWAB
|
||||
? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN;
|
||||
#else
|
||||
tif->tif_header.tiff_magic = tif->tif_flags & TIFF_SWAB
|
||||
? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN;
|
||||
#endif
|
||||
tif->tif_header.tiff_version = TIFF_VERSION;
|
||||
if (tif->tif_flags & TIFF_SWAB)
|
||||
TIFFSwabShort(&tif->tif_header.tiff_version);
|
||||
tif->tif_header.tiff_diroff = 0; /* filled in later */
|
||||
|
||||
|
||||
/*
|
||||
* The doc for "fopen" for some STD_C_LIBs says that if you
|
||||
* open a file for modify ("+"), then you must fseek (or
|
||||
* fflush?) between any freads and fwrites. This is not
|
||||
* necessary on most systems, but has been shown to be needed
|
||||
* on Solaris.
|
||||
*/
|
||||
TIFFSeekFile( tif, 0, SEEK_SET );
|
||||
|
||||
if (!WriteOK(tif, &tif->tif_header, sizeof (TIFFHeader))) {
|
||||
TIFFErrorExt(tif->tif_clientdata, name,
|
||||
"Error writing TIFF header");
|
||||
goto bad;
|
||||
}
|
||||
/*
|
||||
* Setup the byte order handling.
|
||||
*/
|
||||
TIFFInitOrder(tif, tif->tif_header.tiff_magic);
|
||||
/*
|
||||
* Setup default directory.
|
||||
*/
|
||||
if (!TIFFDefaultDirectory(tif))
|
||||
goto bad;
|
||||
tif->tif_diroff = 0;
|
||||
tif->tif_dirlist = NULL;
|
||||
tif->tif_dirlistsize = 0;
|
||||
tif->tif_dirnumber = 0;
|
||||
return (tif);
|
||||
}
|
||||
/*
|
||||
* Setup the byte order handling.
|
||||
*/
|
||||
if (tif->tif_header.tiff_magic != TIFF_BIGENDIAN &&
|
||||
tif->tif_header.tiff_magic != TIFF_LITTLEENDIAN
|
||||
#if MDI_SUPPORT
|
||||
&&
|
||||
#if HOST_BIGENDIAN
|
||||
tif->tif_header.tiff_magic != MDI_BIGENDIAN
|
||||
#else
|
||||
tif->tif_header.tiff_magic != MDI_LITTLEENDIAN
|
||||
#endif
|
||||
) {
|
||||
TIFFErrorExt(tif->tif_clientdata, name,
|
||||
"Not a TIFF or MDI file, bad magic number %d (0x%x)",
|
||||
#else
|
||||
) {
|
||||
TIFFErrorExt(tif->tif_clientdata, name,
|
||||
"Not a TIFF file, bad magic number %d (0x%x)",
|
||||
#endif
|
||||
tif->tif_header.tiff_magic,
|
||||
tif->tif_header.tiff_magic);
|
||||
goto bad;
|
||||
}
|
||||
TIFFInitOrder(tif, tif->tif_header.tiff_magic);
|
||||
/*
|
||||
* Swap header if required.
|
||||
*/
|
||||
if (tif->tif_flags & TIFF_SWAB) {
|
||||
TIFFSwabShort(&tif->tif_header.tiff_version);
|
||||
TIFFSwabLong(&tif->tif_header.tiff_diroff);
|
||||
}
|
||||
/*
|
||||
* Now check version (if needed, it's been byte-swapped).
|
||||
* Note that this isn't actually a version number, it's a
|
||||
* magic number that doesn't change (stupid).
|
||||
*/
|
||||
if (tif->tif_header.tiff_version == TIFF_BIGTIFF_VERSION) {
|
||||
TIFFErrorExt(tif->tif_clientdata, name,
|
||||
"This is a BigTIFF file. This format not supported\n"
|
||||
"by this version of libtiff." );
|
||||
goto bad;
|
||||
}
|
||||
if (tif->tif_header.tiff_version != TIFF_VERSION) {
|
||||
TIFFErrorExt(tif->tif_clientdata, name,
|
||||
"Not a TIFF file, bad version number %d (0x%x)",
|
||||
tif->tif_header.tiff_version,
|
||||
tif->tif_header.tiff_version);
|
||||
goto bad;
|
||||
}
|
||||
tif->tif_flags |= TIFF_MYBUFFER;
|
||||
tif->tif_rawcp = tif->tif_rawdata = 0;
|
||||
tif->tif_rawdatasize = 0;
|
||||
|
||||
/*
|
||||
* Sometimes we do not want to read the first directory (for example,
|
||||
* it may be broken) and want to proceed to other directories. I this
|
||||
* case we use the TIFF_HEADERONLY flag to open file and return
|
||||
* immediately after reading TIFF header.
|
||||
*/
|
||||
if (tif->tif_flags & TIFF_HEADERONLY)
|
||||
return (tif);
|
||||
|
||||
/*
|
||||
* Setup initial directory.
|
||||
*/
|
||||
switch (mode[0]) {
|
||||
case 'r':
|
||||
tif->tif_nextdiroff = tif->tif_header.tiff_diroff;
|
||||
/*
|
||||
* Try to use a memory-mapped file if the client
|
||||
* has not explicitly suppressed usage with the
|
||||
* 'm' flag in the open mode (see above).
|
||||
*/
|
||||
if ((tif->tif_flags & TIFF_MAPPED) &&
|
||||
!TIFFMapFileContents(tif, (tdata_t*) &tif->tif_base, &tif->tif_size))
|
||||
tif->tif_flags &= ~TIFF_MAPPED;
|
||||
if (TIFFReadDirectory(tif)) {
|
||||
tif->tif_rawcc = -1;
|
||||
tif->tif_flags |= TIFF_BUFFERSETUP;
|
||||
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
|
||||
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.
|
||||
*/
|
||||
tstrip_t
|
||||
TIFFCurrentStrip(TIFF* tif)
|
||||
{
|
||||
return (tif->tif_curstrip);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return current tile.
|
||||
*/
|
||||
ttile_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.tiff_magic == TIFF_BIGENDIAN);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
/* vim: set ts=8 sts=8 sw=8 noet: */
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 8
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
300
thirdparty/libtiff/tif_packbits.c
vendored
Normal file
300
thirdparty/libtiff/tif_packbits.c
vendored
Normal file
@ -0,0 +1,300 @@
|
||||
/* $Id: tif_packbits.c,v 1.13.2.2 2010-06-08 18:50:42 bfriesen Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that (i) the above copyright notices and this permission notice appear in
|
||||
* all copies of the software and related documentation, and (ii) the names of
|
||||
* Sam Leffler and Silicon Graphics may not be used in any advertising or
|
||||
* publicity relating to the software without the specific, prior written
|
||||
* permission of Sam Leffler and Silicon Graphics.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
||||
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
|
||||
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
||||
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
||||
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "tiffiop.h"
|
||||
#ifdef PACKBITS_SUPPORT
|
||||
/*
|
||||
* TIFF Library.
|
||||
*
|
||||
* PackBits Compression Algorithm Support
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
static int
|
||||
PackBitsPreEncode(TIFF* tif, tsample_t s)
|
||||
{
|
||||
(void) s;
|
||||
|
||||
if (!(tif->tif_data = (tidata_t)_TIFFmalloc(sizeof(tsize_t))))
|
||||
return (0);
|
||||
/*
|
||||
* Calculate the scanline/tile-width size in bytes.
|
||||
*/
|
||||
if (isTiled(tif))
|
||||
*(tsize_t*)tif->tif_data = TIFFTileRowSize(tif);
|
||||
else
|
||||
*(tsize_t*)tif->tif_data = TIFFScanlineSize(tif);
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
PackBitsPostEncode(TIFF* tif)
|
||||
{
|
||||
if (tif->tif_data)
|
||||
_TIFFfree(tif->tif_data);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* NB: tidata is the type representing *(tidata_t);
|
||||
* if tidata_t is made signed then this type must
|
||||
* be adjusted accordingly.
|
||||
*/
|
||||
typedef unsigned char tidata;
|
||||
|
||||
/*
|
||||
* Encode a run of pixels.
|
||||
*/
|
||||
static int
|
||||
PackBitsEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s)
|
||||
{
|
||||
unsigned char* bp = (unsigned char*) buf;
|
||||
tidata_t op, ep, 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 = 0;
|
||||
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 = op - lastliteral;
|
||||
tif->tif_rawcc += lastliteral - tif->tif_rawcp;
|
||||
if (!TIFFFlushData1(tif))
|
||||
return (-1);
|
||||
op = tif->tif_rawcp;
|
||||
while (slop-- > 0)
|
||||
*op++ = *lastliteral++;
|
||||
lastliteral = tif->tif_rawcp;
|
||||
} else {
|
||||
tif->tif_rawcc += op - tif->tif_rawcp;
|
||||
if (!TIFFFlushData1(tif))
|
||||
return (-1);
|
||||
op = tif->tif_rawcp;
|
||||
}
|
||||
}
|
||||
switch (state) {
|
||||
case BASE: /* initial state, set run/literal */
|
||||
if (n > 1) {
|
||||
state = RUN;
|
||||
if (n > 128) {
|
||||
*op++ = (tidata) -127;
|
||||
*op++ = (tidataval_t) b;
|
||||
n -= 128;
|
||||
goto again;
|
||||
}
|
||||
*op++ = (tidataval_t)(-(n-1));
|
||||
*op++ = (tidataval_t) b;
|
||||
} else {
|
||||
lastliteral = op;
|
||||
*op++ = 0;
|
||||
*op++ = (tidataval_t) b;
|
||||
state = LITERAL;
|
||||
}
|
||||
break;
|
||||
case LITERAL: /* last object was literal string */
|
||||
if (n > 1) {
|
||||
state = LITERAL_RUN;
|
||||
if (n > 128) {
|
||||
*op++ = (tidata) -127;
|
||||
*op++ = (tidataval_t) b;
|
||||
n -= 128;
|
||||
goto again;
|
||||
}
|
||||
*op++ = (tidataval_t)(-(n-1)); /* encode run */
|
||||
*op++ = (tidataval_t) b;
|
||||
} else { /* extend literal */
|
||||
if (++(*lastliteral) == 127)
|
||||
state = BASE;
|
||||
*op++ = (tidataval_t) b;
|
||||
}
|
||||
break;
|
||||
case RUN: /* last object was run */
|
||||
if (n > 1) {
|
||||
if (n > 128) {
|
||||
*op++ = (tidata) -127;
|
||||
*op++ = (tidataval_t) b;
|
||||
n -= 128;
|
||||
goto again;
|
||||
}
|
||||
*op++ = (tidataval_t)(-(n-1));
|
||||
*op++ = (tidataval_t) b;
|
||||
} else {
|
||||
lastliteral = op;
|
||||
*op++ = 0;
|
||||
*op++ = (tidataval_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] == (tidata) -1 &&
|
||||
*lastliteral < 126) {
|
||||
state = (((*lastliteral) += 2) == 127 ?
|
||||
BASE : LITERAL);
|
||||
op[-2] = op[-1]; /* replicate */
|
||||
} else
|
||||
state = RUN;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
tif->tif_rawcc += 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, tidata_t bp, tsize_t cc, tsample_t s)
|
||||
{
|
||||
tsize_t rowsize = *(tsize_t*)tif->tif_data;
|
||||
|
||||
while ((long)cc > 0) {
|
||||
int chunk = rowsize;
|
||||
|
||||
if( cc < chunk )
|
||||
chunk = cc;
|
||||
|
||||
if (PackBitsEncode(tif, bp, chunk, s) < 0)
|
||||
return (-1);
|
||||
bp += chunk;
|
||||
cc -= chunk;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
PackBitsDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s)
|
||||
{
|
||||
char *bp;
|
||||
tsize_t cc;
|
||||
long n;
|
||||
int b;
|
||||
|
||||
(void) s;
|
||||
bp = (char*) tif->tif_rawcp;
|
||||
cc = tif->tif_rawcc;
|
||||
while (cc > 0 && (long)occ > 0) {
|
||||
n = (long) *bp++, cc--;
|
||||
/*
|
||||
* Watch out for compilers that
|
||||
* don't sign extend chars...
|
||||
*/
|
||||
if (n >= 128)
|
||||
n -= 256;
|
||||
if (n < 0) { /* replicate next byte -n+1 times */
|
||||
if (n == -128) /* nop */
|
||||
continue;
|
||||
n = -n + 1;
|
||||
if( occ < n )
|
||||
{
|
||||
TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
|
||||
"PackBitsDecode: discarding %ld bytes "
|
||||
"to avoid buffer overrun",
|
||||
n - occ);
|
||||
n = occ;
|
||||
}
|
||||
occ -= n;
|
||||
b = *bp++, cc--;
|
||||
while (n-- > 0)
|
||||
*op++ = (tidataval_t) b;
|
||||
} else { /* copy next n+1 bytes literally */
|
||||
if (occ < n + 1)
|
||||
{
|
||||
TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
|
||||
"PackBitsDecode: discarding %ld bytes "
|
||||
"to avoid buffer overrun",
|
||||
n - occ + 1);
|
||||
n = occ - 1;
|
||||
}
|
||||
_TIFFmemcpy(op, bp, ++n);
|
||||
op += n; occ -= n;
|
||||
bp += n; cc -= n;
|
||||
}
|
||||
}
|
||||
tif->tif_rawcp = (tidata_t) bp;
|
||||
tif->tif_rawcc = cc;
|
||||
if (occ > 0) {
|
||||
TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
|
||||
"PackBitsDecode: Not enough data for scanline %ld",
|
||||
(long) tif->tif_row);
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
TIFFInitPackBits(TIFF* tif, int scheme)
|
||||
{
|
||||
(void) scheme;
|
||||
tif->tif_decoderow = PackBitsDecode;
|
||||
tif->tif_decodestrip = PackBitsDecode;
|
||||
tif->tif_decodetile = PackBitsDecode;
|
||||
tif->tif_preencode = PackBitsPreEncode;
|
||||
tif->tif_postencode = PackBitsPostEncode;
|
||||
tif->tif_encoderow = PackBitsEncode;
|
||||
tif->tif_encodestrip = PackBitsEncodeChunk;
|
||||
tif->tif_encodetile = PackBitsEncodeChunk;
|
||||
return (1);
|
||||
}
|
||||
#endif /* PACKBITS_SUPPORT */
|
||||
|
||||
/* vim: set ts=8 sts=8 sw=8 noet: */
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 8
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
1371
thirdparty/libtiff/tif_pixarlog.c
vendored
Normal file
1371
thirdparty/libtiff/tif_pixarlog.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
736
thirdparty/libtiff/tif_predict.c
vendored
Normal file
736
thirdparty/libtiff/tif_predict.c
vendored
Normal file
@ -0,0 +1,736 @@
|
||||
/* $Id: tif_predict.c,v 1.11.2.4 2010-06-08 18:50:42 bfriesen Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that (i) the above copyright notices and this permission notice appear in
|
||||
* all copies of the software and related documentation, and (ii) the names of
|
||||
* Sam Leffler and Silicon Graphics may not be used in any advertising or
|
||||
* publicity relating to the software without the specific, prior written
|
||||
* permission of Sam Leffler and Silicon Graphics.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
||||
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
|
||||
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
||||
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
||||
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TIFF Library.
|
||||
*
|
||||
* Predictor Tag Support (used by multiple codecs).
|
||||
*/
|
||||
#include "tiffiop.h"
|
||||
#include "tif_predict.h"
|
||||
|
||||
#define PredictorState(tif) ((TIFFPredictorState*) (tif)->tif_data)
|
||||
|
||||
static void horAcc8(TIFF*, tidata_t, tsize_t);
|
||||
static void horAcc16(TIFF*, tidata_t, tsize_t);
|
||||
static void horAcc32(TIFF*, tidata_t, tsize_t);
|
||||
static void swabHorAcc16(TIFF*, tidata_t, tsize_t);
|
||||
static void swabHorAcc32(TIFF*, tidata_t, tsize_t);
|
||||
static void horDiff8(TIFF*, tidata_t, tsize_t);
|
||||
static void horDiff16(TIFF*, tidata_t, tsize_t);
|
||||
static void horDiff32(TIFF*, tidata_t, tsize_t);
|
||||
static void fpAcc(TIFF*, tidata_t, tsize_t);
|
||||
static void fpDiff(TIFF*, tidata_t, tsize_t);
|
||||
static int PredictorDecodeRow(TIFF*, tidata_t, tsize_t, tsample_t);
|
||||
static int PredictorDecodeTile(TIFF*, tidata_t, tsize_t, tsample_t);
|
||||
static int PredictorEncodeRow(TIFF*, tidata_t, tsize_t, tsample_t);
|
||||
static int PredictorEncodeTile(TIFF*, tidata_t, tsize_t, tsample_t);
|
||||
|
||||
static int
|
||||
PredictorSetup(TIFF* tif)
|
||||
{
|
||||
static const char module[] = "PredictorSetup";
|
||||
|
||||
TIFFPredictorState* sp = PredictorState(tif);
|
||||
TIFFDirectory* td = &tif->tif_dir;
|
||||
|
||||
switch (sp->predictor) /* no differencing */
|
||||
{
|
||||
case PREDICTOR_NONE:
|
||||
return 1;
|
||||
case PREDICTOR_HORIZONTAL:
|
||||
if (td->td_bitspersample != 8
|
||||
&& td->td_bitspersample != 16
|
||||
&& td->td_bitspersample != 32) {
|
||||
TIFFErrorExt(tif->tif_clientdata, module,
|
||||
"Horizontal differencing \"Predictor\" not supported with %d-bit samples",
|
||||
td->td_bitspersample);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case PREDICTOR_FLOATINGPOINT:
|
||||
if (td->td_sampleformat != SAMPLEFORMAT_IEEEFP) {
|
||||
TIFFErrorExt(tif->tif_clientdata, module,
|
||||
"Floating point \"Predictor\" not supported with %d data format",
|
||||
td->td_sampleformat);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
TIFFErrorExt(tif->tif_clientdata, module,
|
||||
"\"Predictor\" value %d not supported",
|
||||
sp->predictor);
|
||||
return 0;
|
||||
}
|
||||
sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
|
||||
td->td_samplesperpixel : 1);
|
||||
/*
|
||||
* Calculate the scanline/tile-width size in bytes.
|
||||
*/
|
||||
if (isTiled(tif))
|
||||
sp->rowsize = TIFFTileRowSize(tif);
|
||||
else
|
||||
sp->rowsize = TIFFScanlineSize(tif);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
PredictorSetupDecode(TIFF* tif)
|
||||
{
|
||||
TIFFPredictorState* sp = PredictorState(tif);
|
||||
TIFFDirectory* td = &tif->tif_dir;
|
||||
|
||||
if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
|
||||
return 0;
|
||||
|
||||
if (sp->predictor == 2) {
|
||||
switch (td->td_bitspersample) {
|
||||
case 8: sp->decodepfunc = horAcc8; break;
|
||||
case 16: sp->decodepfunc = horAcc16; break;
|
||||
case 32: sp->decodepfunc = horAcc32; break;
|
||||
}
|
||||
/*
|
||||
* Override default decoding method with one that does the
|
||||
* predictor stuff.
|
||||
*/
|
||||
if( tif->tif_decoderow != PredictorDecodeRow )
|
||||
{
|
||||
sp->decoderow = tif->tif_decoderow;
|
||||
tif->tif_decoderow = PredictorDecodeRow;
|
||||
sp->decodestrip = tif->tif_decodestrip;
|
||||
tif->tif_decodestrip = PredictorDecodeTile;
|
||||
sp->decodetile = tif->tif_decodetile;
|
||||
tif->tif_decodetile = PredictorDecodeTile;
|
||||
}
|
||||
/*
|
||||
* If the data is horizontally differenced 16-bit data that
|
||||
* requires byte-swapping, then it must be byte swapped before
|
||||
* the accumulation step. We do this with a special-purpose
|
||||
* routine and override the normal post decoding logic that
|
||||
* the library setup when the directory was read.
|
||||
*/
|
||||
if (tif->tif_flags & TIFF_SWAB) {
|
||||
if (sp->decodepfunc == horAcc16) {
|
||||
sp->decodepfunc = swabHorAcc16;
|
||||
tif->tif_postdecode = _TIFFNoPostDecode;
|
||||
} else if (sp->decodepfunc == horAcc32) {
|
||||
sp->decodepfunc = swabHorAcc32;
|
||||
tif->tif_postdecode = _TIFFNoPostDecode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (sp->predictor == 3) {
|
||||
sp->decodepfunc = fpAcc;
|
||||
/*
|
||||
* Override default decoding method with one that does the
|
||||
* predictor stuff.
|
||||
*/
|
||||
if( tif->tif_decoderow != PredictorDecodeRow )
|
||||
{
|
||||
sp->decoderow = tif->tif_decoderow;
|
||||
tif->tif_decoderow = PredictorDecodeRow;
|
||||
sp->decodestrip = tif->tif_decodestrip;
|
||||
tif->tif_decodestrip = PredictorDecodeTile;
|
||||
sp->decodetile = tif->tif_decodetile;
|
||||
tif->tif_decodetile = PredictorDecodeTile;
|
||||
}
|
||||
/*
|
||||
* The data should not be swapped outside of the floating
|
||||
* point predictor, the accumulation routine should return
|
||||
* byres in the native order.
|
||||
*/
|
||||
if (tif->tif_flags & TIFF_SWAB) {
|
||||
tif->tif_postdecode = _TIFFNoPostDecode;
|
||||
}
|
||||
/*
|
||||
* Allocate buffer to keep the decoded bytes before
|
||||
* rearranging in the ight order
|
||||
*/
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
PredictorSetupEncode(TIFF* tif)
|
||||
{
|
||||
TIFFPredictorState* sp = PredictorState(tif);
|
||||
TIFFDirectory* td = &tif->tif_dir;
|
||||
|
||||
if (!(*sp->setupencode)(tif) || !PredictorSetup(tif))
|
||||
return 0;
|
||||
|
||||
if (sp->predictor == 2) {
|
||||
switch (td->td_bitspersample) {
|
||||
case 8: sp->encodepfunc = horDiff8; break;
|
||||
case 16: sp->encodepfunc = horDiff16; break;
|
||||
case 32: sp->encodepfunc = horDiff32; break;
|
||||
}
|
||||
/*
|
||||
* Override default encoding method with one that does the
|
||||
* predictor stuff.
|
||||
*/
|
||||
if( tif->tif_encoderow != PredictorEncodeRow )
|
||||
{
|
||||
sp->encoderow = tif->tif_encoderow;
|
||||
tif->tif_encoderow = PredictorEncodeRow;
|
||||
sp->encodestrip = tif->tif_encodestrip;
|
||||
tif->tif_encodestrip = PredictorEncodeTile;
|
||||
sp->encodetile = tif->tif_encodetile;
|
||||
tif->tif_encodetile = PredictorEncodeTile;
|
||||
}
|
||||
}
|
||||
|
||||
else if (sp->predictor == 3) {
|
||||
sp->encodepfunc = fpDiff;
|
||||
/*
|
||||
* Override default encoding method with one that does the
|
||||
* predictor stuff.
|
||||
*/
|
||||
if( tif->tif_encoderow != PredictorEncodeRow )
|
||||
{
|
||||
sp->encoderow = tif->tif_encoderow;
|
||||
tif->tif_encoderow = PredictorEncodeRow;
|
||||
sp->encodestrip = tif->tif_encodestrip;
|
||||
tif->tif_encodestrip = PredictorEncodeTile;
|
||||
sp->encodetile = tif->tif_encodetile;
|
||||
tif->tif_encodetile = PredictorEncodeTile;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define REPEAT4(n, op) \
|
||||
switch (n) { \
|
||||
default: { int i; for (i = n-4; i > 0; i--) { op; } } \
|
||||
case 4: op; \
|
||||
case 3: op; \
|
||||
case 2: op; \
|
||||
case 1: op; \
|
||||
case 0: ; \
|
||||
}
|
||||
|
||||
static void
|
||||
horAcc8(TIFF* tif, tidata_t cp0, tsize_t cc)
|
||||
{
|
||||
tsize_t stride = PredictorState(tif)->stride;
|
||||
|
||||
char* cp = (char*) cp0;
|
||||
if (cc > stride) {
|
||||
cc -= stride;
|
||||
/*
|
||||
* Pipeline the most common cases.
|
||||
*/
|
||||
if (stride == 3) {
|
||||
unsigned int cr = cp[0];
|
||||
unsigned int cg = cp[1];
|
||||
unsigned int cb = cp[2];
|
||||
do {
|
||||
cc -= 3, cp += 3;
|
||||
cp[0] = (char) (cr += cp[0]);
|
||||
cp[1] = (char) (cg += cp[1]);
|
||||
cp[2] = (char) (cb += cp[2]);
|
||||
} while ((int32) cc > 0);
|
||||
} else if (stride == 4) {
|
||||
unsigned int cr = cp[0];
|
||||
unsigned int cg = cp[1];
|
||||
unsigned int cb = cp[2];
|
||||
unsigned int ca = cp[3];
|
||||
do {
|
||||
cc -= 4, cp += 4;
|
||||
cp[0] = (char) (cr += cp[0]);
|
||||
cp[1] = (char) (cg += cp[1]);
|
||||
cp[2] = (char) (cb += cp[2]);
|
||||
cp[3] = (char) (ca += cp[3]);
|
||||
} while ((int32) cc > 0);
|
||||
} else {
|
||||
do {
|
||||
REPEAT4(stride, cp[stride] =
|
||||
(char) (cp[stride] + *cp); cp++)
|
||||
cc -= stride;
|
||||
} while ((int32) cc > 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
swabHorAcc16(TIFF* tif, tidata_t cp0, tsize_t cc)
|
||||
{
|
||||
tsize_t stride = PredictorState(tif)->stride;
|
||||
uint16* wp = (uint16*) cp0;
|
||||
tsize_t wc = cc / 2;
|
||||
|
||||
if (wc > stride) {
|
||||
TIFFSwabArrayOfShort(wp, wc);
|
||||
wc -= stride;
|
||||
do {
|
||||
REPEAT4(stride, wp[stride] += wp[0]; wp++)
|
||||
wc -= stride;
|
||||
} while ((int32) wc > 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
horAcc16(TIFF* tif, tidata_t cp0, tsize_t cc)
|
||||
{
|
||||
tsize_t stride = PredictorState(tif)->stride;
|
||||
uint16* wp = (uint16*) cp0;
|
||||
tsize_t wc = cc / 2;
|
||||
|
||||
if (wc > stride) {
|
||||
wc -= stride;
|
||||
do {
|
||||
REPEAT4(stride, wp[stride] += wp[0]; wp++)
|
||||
wc -= stride;
|
||||
} while ((int32) wc > 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
swabHorAcc32(TIFF* tif, tidata_t cp0, tsize_t cc)
|
||||
{
|
||||
tsize_t stride = PredictorState(tif)->stride;
|
||||
uint32* wp = (uint32*) cp0;
|
||||
tsize_t wc = cc / 4;
|
||||
|
||||
if (wc > stride) {
|
||||
TIFFSwabArrayOfLong(wp, wc);
|
||||
wc -= stride;
|
||||
do {
|
||||
REPEAT4(stride, wp[stride] += wp[0]; wp++)
|
||||
wc -= stride;
|
||||
} while ((int32) wc > 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
horAcc32(TIFF* tif, tidata_t cp0, tsize_t cc)
|
||||
{
|
||||
tsize_t stride = PredictorState(tif)->stride;
|
||||
uint32* wp = (uint32*) cp0;
|
||||
tsize_t wc = cc / 4;
|
||||
|
||||
if (wc > stride) {
|
||||
wc -= stride;
|
||||
do {
|
||||
REPEAT4(stride, wp[stride] += wp[0]; wp++)
|
||||
wc -= stride;
|
||||
} while ((int32) wc > 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Floating point predictor accumulation routine.
|
||||
*/
|
||||
static void
|
||||
fpAcc(TIFF* tif, tidata_t cp0, tsize_t cc)
|
||||
{
|
||||
tsize_t stride = PredictorState(tif)->stride;
|
||||
uint32 bps = tif->tif_dir.td_bitspersample / 8;
|
||||
tsize_t wc = cc / bps;
|
||||
tsize_t count = cc;
|
||||
uint8 *cp = (uint8 *) cp0;
|
||||
uint8 *tmp = (uint8 *)_TIFFmalloc(cc);
|
||||
|
||||
if (!tmp)
|
||||
return;
|
||||
|
||||
while (count > stride) {
|
||||
REPEAT4(stride, cp[stride] += cp[0]; cp++)
|
||||
count -= stride;
|
||||
}
|
||||
|
||||
_TIFFmemcpy(tmp, cp0, cc);
|
||||
cp = (uint8 *) cp0;
|
||||
for (count = 0; count < wc; count++) {
|
||||
uint32 byte;
|
||||
for (byte = 0; byte < bps; byte++) {
|
||||
#if WORDS_BIGENDIAN
|
||||
cp[bps * count + byte] = tmp[byte * wc + count];
|
||||
#else
|
||||
cp[bps * count + byte] =
|
||||
tmp[(bps - byte - 1) * wc + count];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
_TIFFfree(tmp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode a scanline and apply the predictor routine.
|
||||
*/
|
||||
static int
|
||||
PredictorDecodeRow(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s)
|
||||
{
|
||||
TIFFPredictorState *sp = PredictorState(tif);
|
||||
|
||||
assert(sp != NULL);
|
||||
assert(sp->decoderow != NULL);
|
||||
assert(sp->decodepfunc != NULL);
|
||||
|
||||
if ((*sp->decoderow)(tif, op0, occ0, s)) {
|
||||
(*sp->decodepfunc)(tif, op0, occ0);
|
||||
return 1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode a tile/strip and apply the predictor routine.
|
||||
* Note that horizontal differencing must be done on a
|
||||
* row-by-row basis. The width of a "row" has already
|
||||
* been calculated at pre-decode time according to the
|
||||
* strip/tile dimensions.
|
||||
*/
|
||||
static int
|
||||
PredictorDecodeTile(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s)
|
||||
{
|
||||
TIFFPredictorState *sp = PredictorState(tif);
|
||||
|
||||
assert(sp != NULL);
|
||||
assert(sp->decodetile != NULL);
|
||||
|
||||
if ((*sp->decodetile)(tif, op0, occ0, s)) {
|
||||
tsize_t rowsize = sp->rowsize;
|
||||
assert(rowsize > 0);
|
||||
assert(sp->decodepfunc != NULL);
|
||||
while ((long)occ0 > 0) {
|
||||
(*sp->decodepfunc)(tif, op0, (tsize_t) rowsize);
|
||||
occ0 -= rowsize;
|
||||
op0 += rowsize;
|
||||
}
|
||||
return 1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
horDiff8(TIFF* tif, tidata_t cp0, tsize_t cc)
|
||||
{
|
||||
TIFFPredictorState* sp = PredictorState(tif);
|
||||
tsize_t stride = sp->stride;
|
||||
char* cp = (char*) cp0;
|
||||
|
||||
if (cc > stride) {
|
||||
cc -= stride;
|
||||
/*
|
||||
* Pipeline the most common cases.
|
||||
*/
|
||||
if (stride == 3) {
|
||||
int r1, g1, b1;
|
||||
int r2 = cp[0];
|
||||
int g2 = cp[1];
|
||||
int b2 = cp[2];
|
||||
do {
|
||||
r1 = cp[3]; cp[3] = r1-r2; r2 = r1;
|
||||
g1 = cp[4]; cp[4] = g1-g2; g2 = g1;
|
||||
b1 = cp[5]; cp[5] = b1-b2; b2 = b1;
|
||||
cp += 3;
|
||||
} while ((int32)(cc -= 3) > 0);
|
||||
} else if (stride == 4) {
|
||||
int r1, g1, b1, a1;
|
||||
int r2 = cp[0];
|
||||
int g2 = cp[1];
|
||||
int b2 = cp[2];
|
||||
int a2 = cp[3];
|
||||
do {
|
||||
r1 = cp[4]; cp[4] = r1-r2; r2 = r1;
|
||||
g1 = cp[5]; cp[5] = g1-g2; g2 = g1;
|
||||
b1 = cp[6]; cp[6] = b1-b2; b2 = b1;
|
||||
a1 = cp[7]; cp[7] = a1-a2; a2 = a1;
|
||||
cp += 4;
|
||||
} while ((int32)(cc -= 4) > 0);
|
||||
} else {
|
||||
cp += cc - 1;
|
||||
do {
|
||||
REPEAT4(stride, cp[stride] -= cp[0]; cp--)
|
||||
} while ((int32)(cc -= stride) > 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
horDiff16(TIFF* tif, tidata_t cp0, tsize_t cc)
|
||||
{
|
||||
TIFFPredictorState* sp = PredictorState(tif);
|
||||
tsize_t stride = sp->stride;
|
||||
int16 *wp = (int16*) cp0;
|
||||
tsize_t wc = cc/2;
|
||||
|
||||
if (wc > stride) {
|
||||
wc -= stride;
|
||||
wp += wc - 1;
|
||||
do {
|
||||
REPEAT4(stride, wp[stride] -= wp[0]; wp--)
|
||||
wc -= stride;
|
||||
} while ((int32) wc > 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
horDiff32(TIFF* tif, tidata_t cp0, tsize_t cc)
|
||||
{
|
||||
TIFFPredictorState* sp = PredictorState(tif);
|
||||
tsize_t stride = sp->stride;
|
||||
int32 *wp = (int32*) cp0;
|
||||
tsize_t wc = cc/4;
|
||||
|
||||
if (wc > stride) {
|
||||
wc -= stride;
|
||||
wp += wc - 1;
|
||||
do {
|
||||
REPEAT4(stride, wp[stride] -= wp[0]; wp--)
|
||||
wc -= stride;
|
||||
} while ((int32) wc > 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Floating point predictor differencing routine.
|
||||
*/
|
||||
static void
|
||||
fpDiff(TIFF* tif, tidata_t cp0, tsize_t cc)
|
||||
{
|
||||
tsize_t stride = PredictorState(tif)->stride;
|
||||
uint32 bps = tif->tif_dir.td_bitspersample / 8;
|
||||
tsize_t wc = cc / bps;
|
||||
tsize_t count;
|
||||
uint8 *cp = (uint8 *) cp0;
|
||||
uint8 *tmp = (uint8 *)_TIFFmalloc(cc);
|
||||
|
||||
if (!tmp)
|
||||
return;
|
||||
|
||||
_TIFFmemcpy(tmp, cp0, cc);
|
||||
for (count = 0; count < wc; count++) {
|
||||
uint32 byte;
|
||||
for (byte = 0; byte < bps; byte++) {
|
||||
#if WORDS_BIGENDIAN
|
||||
cp[byte * wc + count] = tmp[bps * count + byte];
|
||||
#else
|
||||
cp[(bps - byte - 1) * wc + count] =
|
||||
tmp[bps * count + byte];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
_TIFFfree(tmp);
|
||||
|
||||
cp = (uint8 *) cp0;
|
||||
cp += cc - stride - 1;
|
||||
for (count = cc; count > stride; count -= stride)
|
||||
REPEAT4(stride, cp[stride] -= cp[0]; cp--)
|
||||
}
|
||||
|
||||
static int
|
||||
PredictorEncodeRow(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
|
||||
{
|
||||
TIFFPredictorState *sp = PredictorState(tif);
|
||||
|
||||
assert(sp != NULL);
|
||||
assert(sp->encodepfunc != NULL);
|
||||
assert(sp->encoderow != NULL);
|
||||
|
||||
/* XXX horizontal differencing alters user's data XXX */
|
||||
(*sp->encodepfunc)(tif, bp, cc);
|
||||
return (*sp->encoderow)(tif, bp, cc, s);
|
||||
}
|
||||
|
||||
static int
|
||||
PredictorEncodeTile(TIFF* tif, tidata_t bp0, tsize_t cc0, tsample_t s)
|
||||
{
|
||||
static const char module[] = "PredictorEncodeTile";
|
||||
TIFFPredictorState *sp = PredictorState(tif);
|
||||
uint8 *working_copy;
|
||||
tsize_t cc = cc0, rowsize;
|
||||
unsigned char* bp;
|
||||
int result_code;
|
||||
|
||||
assert(sp != NULL);
|
||||
assert(sp->encodepfunc != NULL);
|
||||
assert(sp->encodetile != NULL);
|
||||
|
||||
/*
|
||||
* Do predictor manipulation in a working buffer to avoid altering
|
||||
* the callers buffer. http://trac.osgeo.org/gdal/ticket/1965
|
||||
*/
|
||||
working_copy = (uint8*) _TIFFmalloc(cc0);
|
||||
if( working_copy == NULL )
|
||||
{
|
||||
TIFFErrorExt(tif->tif_clientdata, module,
|
||||
"Out of memory allocating %d byte temp buffer.",
|
||||
cc0 );
|
||||
return 0;
|
||||
}
|
||||
memcpy( working_copy, bp0, cc0 );
|
||||
bp = working_copy;
|
||||
|
||||
rowsize = sp->rowsize;
|
||||
assert(rowsize > 0);
|
||||
assert((cc0%rowsize)==0);
|
||||
while (cc > 0) {
|
||||
(*sp->encodepfunc)(tif, bp, rowsize);
|
||||
cc -= rowsize;
|
||||
bp += rowsize;
|
||||
}
|
||||
result_code = (*sp->encodetile)(tif, working_copy, cc0, s);
|
||||
|
||||
_TIFFfree( working_copy );
|
||||
|
||||
return result_code;
|
||||
}
|
||||
|
||||
#define FIELD_PREDICTOR (FIELD_CODEC+0) /* XXX */
|
||||
|
||||
static const TIFFFieldInfo predictFieldInfo[] = {
|
||||
{ TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, FIELD_PREDICTOR,
|
||||
FALSE, FALSE, "Predictor" },
|
||||
};
|
||||
|
||||
static int
|
||||
PredictorVSetField(TIFF* tif, ttag_t tag, va_list ap)
|
||||
{
|
||||
TIFFPredictorState *sp = PredictorState(tif);
|
||||
|
||||
assert(sp != NULL);
|
||||
assert(sp->vsetparent != NULL);
|
||||
|
||||
switch (tag) {
|
||||
case TIFFTAG_PREDICTOR:
|
||||
sp->predictor = (uint16) va_arg(ap, int);
|
||||
TIFFSetFieldBit(tif, FIELD_PREDICTOR);
|
||||
break;
|
||||
default:
|
||||
return (*sp->vsetparent)(tif, tag, ap);
|
||||
}
|
||||
tif->tif_flags |= TIFF_DIRTYDIRECT;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
PredictorVGetField(TIFF* tif, ttag_t tag, va_list ap)
|
||||
{
|
||||
TIFFPredictorState *sp = PredictorState(tif);
|
||||
|
||||
assert(sp != NULL);
|
||||
assert(sp->vgetparent != NULL);
|
||||
|
||||
switch (tag) {
|
||||
case TIFFTAG_PREDICTOR:
|
||||
*va_arg(ap, uint16*) = sp->predictor;
|
||||
break;
|
||||
default:
|
||||
return (*sp->vgetparent)(tif, tag, ap);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
PredictorPrintDir(TIFF* tif, FILE* fd, long flags)
|
||||
{
|
||||
TIFFPredictorState* sp = PredictorState(tif);
|
||||
|
||||
(void) flags;
|
||||
if (TIFFFieldSet(tif,FIELD_PREDICTOR)) {
|
||||
fprintf(fd, " Predictor: ");
|
||||
switch (sp->predictor) {
|
||||
case 1: fprintf(fd, "none "); break;
|
||||
case 2: fprintf(fd, "horizontal differencing "); break;
|
||||
case 3: fprintf(fd, "floating point predictor "); break;
|
||||
}
|
||||
fprintf(fd, "%u (0x%x)\n", sp->predictor, sp->predictor);
|
||||
}
|
||||
if (sp->printdir)
|
||||
(*sp->printdir)(tif, fd, flags);
|
||||
}
|
||||
|
||||
int
|
||||
TIFFPredictorInit(TIFF* tif)
|
||||
{
|
||||
TIFFPredictorState* sp = PredictorState(tif);
|
||||
|
||||
assert(sp != 0);
|
||||
|
||||
/*
|
||||
* Merge codec-specific tag information.
|
||||
*/
|
||||
if (!_TIFFMergeFieldInfo(tif, predictFieldInfo,
|
||||
TIFFArrayCount(predictFieldInfo))) {
|
||||
TIFFErrorExt(tif->tif_clientdata, "TIFFPredictorInit",
|
||||
"Merging Predictor codec-specific tags failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Override parent get/set field methods.
|
||||
*/
|
||||
sp->vgetparent = tif->tif_tagmethods.vgetfield;
|
||||
tif->tif_tagmethods.vgetfield =
|
||||
PredictorVGetField;/* hook for predictor tag */
|
||||
sp->vsetparent = tif->tif_tagmethods.vsetfield;
|
||||
tif->tif_tagmethods.vsetfield =
|
||||
PredictorVSetField;/* hook for predictor tag */
|
||||
sp->printdir = tif->tif_tagmethods.printdir;
|
||||
tif->tif_tagmethods.printdir =
|
||||
PredictorPrintDir; /* hook for predictor tag */
|
||||
|
||||
sp->setupdecode = tif->tif_setupdecode;
|
||||
tif->tif_setupdecode = PredictorSetupDecode;
|
||||
sp->setupencode = tif->tif_setupencode;
|
||||
tif->tif_setupencode = PredictorSetupEncode;
|
||||
|
||||
sp->predictor = 1; /* default value */
|
||||
sp->encodepfunc = NULL; /* no predictor routine */
|
||||
sp->decodepfunc = NULL; /* no predictor routine */
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
TIFFPredictorCleanup(TIFF* tif)
|
||||
{
|
||||
TIFFPredictorState* sp = PredictorState(tif);
|
||||
|
||||
assert(sp != 0);
|
||||
|
||||
tif->tif_tagmethods.vgetfield = sp->vgetparent;
|
||||
tif->tif_tagmethods.vsetfield = sp->vsetparent;
|
||||
tif->tif_tagmethods.printdir = sp->printdir;
|
||||
tif->tif_setupdecode = sp->setupdecode;
|
||||
tif->tif_setupencode = sp->setupencode;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* vim: set ts=8 sts=8 sw=8 noet: */
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 8
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
77
thirdparty/libtiff/tif_predict.h
vendored
Normal file
77
thirdparty/libtiff/tif_predict.h
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
/* $Id: tif_predict.h,v 1.3.2.2 2010-06-08 18:50:42 bfriesen Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995-1997 Sam Leffler
|
||||
* Copyright (c) 1995-1997 Silicon Graphics, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* 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_
|
||||
/*
|
||||
* ``Library-private'' Support for the Predictor Tag
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
int stride; /* sample stride over data */
|
||||
tsize_t rowsize; /* tile/strip row size */
|
||||
|
||||
TIFFCodeMethod encoderow; /* parent codec encode/decode row */
|
||||
TIFFCodeMethod encodestrip; /* parent codec encode/decode strip */
|
||||
TIFFCodeMethod encodetile; /* parent codec encode/decode tile */
|
||||
TIFFPostMethod encodepfunc; /* horizontal differencer */
|
||||
|
||||
TIFFCodeMethod decoderow; /* parent codec encode/decode row */
|
||||
TIFFCodeMethod decodestrip; /* parent codec encode/decode strip */
|
||||
TIFFCodeMethod decodetile; /* parent codec encode/decode tile */
|
||||
TIFFPostMethod decodepfunc; /* horizontal accumulator */
|
||||
|
||||
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_ */
|
||||
|
||||
/* vim: set ts=8 sts=8 sw=8 noet: */
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 8
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user