Compare commits
44 Commits
version.1.
...
openjpeg-1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f0dd842b11 | ||
|
|
96c3a8315b | ||
|
|
6711fa669a | ||
|
|
935816e8c9 | ||
|
|
c0abb808f5 | ||
|
|
348e96e44b | ||
|
|
e94720fea0 | ||
|
|
04291bf0ab | ||
|
|
46440fe368 | ||
|
|
9cf9018ffc | ||
|
|
001cd957ba | ||
|
|
a024c148fc | ||
|
|
a4bd2ed06e | ||
|
|
66f65919cf | ||
|
|
7ad3e2a870 | ||
|
|
9542c08d62 | ||
|
|
cbaa2d7d98 | ||
|
|
650df81e09 | ||
|
|
618e50954f | ||
|
|
959ebdab5e | ||
|
|
3cee252347 | ||
|
|
2a4101c60e | ||
|
|
32b04ad49d | ||
|
|
5e3fae7f48 | ||
|
|
4469a98cd7 | ||
|
|
93c79f8fb1 | ||
|
|
e755ebd1b0 | ||
|
|
f35aaa8a82 | ||
|
|
b44e07fe19 | ||
|
|
d3c0915992 | ||
|
|
c91e2099b1 | ||
|
|
d0e85b0c52 | ||
|
|
31e35fcf7b | ||
|
|
2d47938b25 | ||
|
|
2e508f1c89 | ||
|
|
f8013bec95 | ||
|
|
770e81eebc | ||
|
|
2c3f5c269a | ||
|
|
0ec0b2594c | ||
|
|
2eebb05ca2 | ||
|
|
ff72d131ed | ||
|
|
7d6d19c473 | ||
|
|
78053c44c8 | ||
|
|
902fe2569c |
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
CMakeLists.txt.user
|
||||
|
||||
*.bak
|
||||
16
CMake/FindCPPCHECK.cmake
Normal file
16
CMake/FindCPPCHECK.cmake
Normal file
@@ -0,0 +1,16 @@
|
||||
# cppcheck
|
||||
#
|
||||
# Copyright (c) 2011 Mathieu Malaterre <mathieu.malaterre@gmail.com>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New
|
||||
# BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
#
|
||||
|
||||
find_program(CPPCHECK_EXECUTABLE
|
||||
cppcheck
|
||||
)
|
||||
|
||||
mark_as_advanced(
|
||||
CPPCHECK_EXECUTABLE
|
||||
)
|
||||
12
CMake/FindJPYLYZER.cmake
Normal file
12
CMake/FindJPYLYZER.cmake
Normal file
@@ -0,0 +1,12 @@
|
||||
#
|
||||
# this module looks for JPYLYZER
|
||||
# http://jpylyzer.openpreservation.org
|
||||
#
|
||||
|
||||
find_program(JPYLYZER_EXECUTABLE
|
||||
jpylyzer
|
||||
)
|
||||
|
||||
mark_as_advanced(
|
||||
JPYLYZER_EXECUTABLE
|
||||
)
|
||||
@@ -11,6 +11,9 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
|
||||
|
||||
IF(COMMAND CMAKE_POLICY)
|
||||
CMAKE_POLICY(SET CMP0003 NEW)
|
||||
if (NOT (${CMAKE_VERSION} VERSION_LESS 3.0))
|
||||
cmake_policy(SET CMP0042 NEW)
|
||||
endif()
|
||||
ENDIF(COMMAND CMAKE_POLICY)
|
||||
|
||||
IF(NOT OPENJPEG_NAMESPACE)
|
||||
@@ -29,7 +32,7 @@ INCLUDE_REGULAR_EXPRESSION("^.*$")
|
||||
# OPENJPEG version number, useful for packaging and doxygen doc:
|
||||
SET(OPENJPEG_VERSION_MAJOR 1)
|
||||
SET(OPENJPEG_VERSION_MINOR 5)
|
||||
SET(OPENJPEG_VERSION_BUILD 2)
|
||||
SET(OPENJPEG_VERSION_BUILD 3)
|
||||
SET(OPENJPEG_VERSION
|
||||
"${OPENJPEG_VERSION_MAJOR}.${OPENJPEG_VERSION_MINOR}.${OPENJPEG_VERSION_BUILD}")
|
||||
SET(PACKAGE_VERSION
|
||||
@@ -200,7 +203,7 @@ IF(CMAKE_COMPILER_IS_GNUCC)
|
||||
# For all builds, make sure openjpeg is std99 compliant:
|
||||
# SET(CMAKE_C_FLAGS "-Wall -std=c99 ${CMAKE_C_FLAGS}") # FIXME: this setting prevented us from setting a coverage build.
|
||||
# Do not use ffast-math for all build, it would produce incorrect results, only set for release:
|
||||
SET(CMAKE_C_FLAGS_RELEASE "-ffast-math ${CMAKE_C_FLAGS_RELEASE}")
|
||||
SET(OPENJPEG_LIBRARY_COMPILE_OPTIONS ${OPENJPEG_LIBRARY_COMPILE_OPTIONS} "$<$<CONFIG:Release>:-ffast-math>")
|
||||
ENDIF(CMAKE_COMPILER_IS_GNUCC)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
@@ -7,8 +7,12 @@ SET(openjpegjni_SRCS
|
||||
${OPENJPEG_SOURCE_DIR}/applications/codec/index.c
|
||||
${OPENJPEG_SOURCE_DIR}/applications/codec/convert.c
|
||||
#${OPENJPEG_SOURCE_DIR}/applications/common/color.c
|
||||
${OPENJPEG_SOURCE_DIR}/applications/common/opj_getopt.c
|
||||
)
|
||||
if(NOT USE_SYSTEM_GETOPT)
|
||||
list(APPEND openjpegjni_SRCS
|
||||
${OPENJPEG_SOURCE_DIR}/applications/common/opj_getopt.c
|
||||
)
|
||||
endif()
|
||||
|
||||
# JNI binding:
|
||||
find_package(JNI REQUIRED)
|
||||
@@ -41,6 +45,14 @@ INSTALL(TARGETS openjpegjni
|
||||
# build jar:
|
||||
FIND_PACKAGE(Java 1.5 REQUIRED) # javac, jar
|
||||
|
||||
# User can override this:
|
||||
if(NOT DEFINED JAVA_SOURCE_VERSION)
|
||||
set(JAVA_SOURCE_VERSION 1.5)
|
||||
endif()
|
||||
if(NOT DEFINED JAVA_TARGET_VERSION)
|
||||
set(JAVA_TARGET_VERSION 1.5)
|
||||
endif()
|
||||
|
||||
# build dep list:
|
||||
file(GLOB java_srcs "java-sources/org/openJpeg/*.java")
|
||||
|
||||
@@ -49,7 +61,9 @@ file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/classes)
|
||||
# Build java
|
||||
ADD_CUSTOM_COMMAND(
|
||||
OUTPUT ${LIBRARY_OUTPUT_PATH}/openjpeg.jar
|
||||
COMMAND ${Java_JAVAC_EXECUTABLE} -sourcepath "${CMAKE_CURRENT_SOURCE_DIR}/java-sources"
|
||||
COMMAND ${Java_JAVAC_EXECUTABLE}
|
||||
-source ${JAVA_SOURCE_VERSION} -target ${JAVA_TARGET_VERSION}
|
||||
-sourcepath "${CMAKE_CURRENT_SOURCE_DIR}/java-sources"
|
||||
${java_srcs} -d ${CMAKE_CURRENT_BINARY_DIR}/classes
|
||||
COMMAND ${Java_JAR_EXECUTABLE} cvf ${LIBRARY_OUTPUT_PATH}/openjpeg.jar org
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/classes
|
||||
|
||||
@@ -1721,7 +1721,7 @@ opj_image_t* loadImage(opj_cparameters_t *parameters, JNIEnv *env, jobject obj,
|
||||
len = (*env)->GetArrayLength(env, jba);
|
||||
|
||||
jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, &isCopy);
|
||||
/* printf("C: before transfering 8 bpp image\n"); */
|
||||
/* printf("C: before transferring 8 bpp image\n"); */
|
||||
if (comp->sgnd) {
|
||||
for(i=0; i< len;i++) {
|
||||
comp->data[i] = (char) jbBody[i];
|
||||
@@ -1740,7 +1740,7 @@ opj_image_t* loadImage(opj_cparameters_t *parameters, JNIEnv *env, jobject obj,
|
||||
len = (*env)->GetArrayLength(env, jsa);
|
||||
|
||||
jsBody = (*env)->GetPrimitiveArrayCritical(env, jsa, &isCopy);
|
||||
/*printf("C: before transfering 16 bpp image\n"); */
|
||||
/*printf("C: before transferring 16 bpp image\n"); */
|
||||
if (comp->sgnd) {
|
||||
/* Special behaviour to deal with signed elements ?? */
|
||||
comp->data[i] = (short) jsBody[i];
|
||||
@@ -1761,7 +1761,7 @@ opj_image_t* loadImage(opj_cparameters_t *parameters, JNIEnv *env, jobject obj,
|
||||
shift = compno*8;
|
||||
|
||||
jiBody = (*env)->GetPrimitiveArrayCritical(env, jia, &isCopy);
|
||||
/*printf("C: before transfering 24 bpp image (component %d, signed = %d)\n", compno, comp->sgnd);*/
|
||||
/*printf("C: before transferring 24 bpp image (component %d, signed = %d)\n", compno, comp->sgnd);*/
|
||||
if (comp->sgnd) {
|
||||
/* Special behaviour to deal with signed elements ?? XXXXX */
|
||||
for(i=0; i< len;i++) {
|
||||
|
||||
@@ -615,7 +615,7 @@ JNIEXPORT jint JNICALL Java_org_openJpeg_OpenJPEGJavaDecoder_internalDecodeJ2Kto
|
||||
/* printf("C: %d bytes read from file\n",file_length); */
|
||||
} else {
|
||||
/* Preparing the transfer of the codestream from Java to C */
|
||||
/* printf("C: before transfering codestream\n"); */
|
||||
/* printf("C: before transferring codestream\n"); */
|
||||
fid = (*env)->GetFieldID(env, cls,"compressedStream", "[B");
|
||||
jba = (*env)->GetObjectField(env, obj, fid);
|
||||
file_length = (*env)->GetArrayLength(env, jba);
|
||||
@@ -797,7 +797,7 @@ JNIEXPORT jint JNICALL Java_org_openJpeg_OpenJPEGJavaDecoder_internalDecodeJ2Kto
|
||||
jia = (*env)->GetObjectField(env, obj, fid);
|
||||
jiBody = (*env)->GetIntArrayElements(env, jia, 0);
|
||||
ptrIBody = jiBody;
|
||||
printf("C: transfering image24: %d int to Java pointer=%d\n",image->numcomps*w*h, ptrIBody);
|
||||
printf("C: transferring image24: %d int to Java pointer=%d\n",image->numcomps*w*h, ptrIBody);
|
||||
|
||||
for (i=0; i<w*h; i++) {
|
||||
tempUC = (unsigned char)(ptr[i]);
|
||||
@@ -823,7 +823,7 @@ JNIEXPORT jint JNICALL Java_org_openJpeg_OpenJPEGJavaDecoder_internalDecodeJ2Kto
|
||||
|
||||
} else { /* 1 component 8 or 16 bpp image */
|
||||
ptr = image->comps[0].data;
|
||||
printf("C: before transfering a %d bpp image to java (length = %d)\n",image->comps[0].prec ,w*h);
|
||||
printf("C: before transferring a %d bpp image to java (length = %d)\n",image->comps[0].prec ,w*h);
|
||||
if (image->comps[0].prec<=8) {
|
||||
fid = (*env)->GetFieldID(env, cls,"image8", "[B");
|
||||
jba = (*env)->GetObjectField(env, obj, fid);
|
||||
@@ -838,7 +838,7 @@ JNIEXPORT jint JNICALL Java_org_openJpeg_OpenJPEGJavaDecoder_internalDecodeJ2Kto
|
||||
max_value = 255;
|
||||
}
|
||||
#endif
|
||||
/* printf("C: transfering %d shorts to Java image8 pointer = %d\n", wr*hr,ptrSBody); */
|
||||
/* printf("C: transferring %d shorts to Java image8 pointer = %d\n", wr*hr,ptrSBody); */
|
||||
for (i=0; i<w*h; i++) {
|
||||
tempUC = (unsigned char) (ptr[i]);
|
||||
#ifdef CHECK_THRESHOLDS
|
||||
@@ -866,7 +866,7 @@ JNIEXPORT jint JNICALL Java_org_openJpeg_OpenJPEGJavaDecoder_internalDecodeJ2Kto
|
||||
}
|
||||
printf("C: minValue = %d, maxValue = %d\n", min_value, max_value);
|
||||
#endif
|
||||
printf("C: transfering %d shorts to Java image16 pointer = %d\n", w*h,ptrSBody);
|
||||
printf("C: transferring %d shorts to Java image16 pointer = %d\n", w*h,ptrSBody);
|
||||
for (i=0; i<w*h; i++) {
|
||||
tempS = (short) (ptr[i]);
|
||||
#ifdef CHECK_THRESHOLDS
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
# First thing define the common source:
|
||||
SET(common_SRCS
|
||||
convert.c
|
||||
converttif.c
|
||||
convertbmp.c
|
||||
convertpng.c
|
||||
index.c
|
||||
${OPENJPEG_SOURCE_DIR}/applications/common/color.c
|
||||
)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -47,6 +47,21 @@ typedef struct raw_cparameters {
|
||||
/*@}*/
|
||||
} raw_cparameters_t;
|
||||
|
||||
/* Component precision scaling */
|
||||
void clip_component(opj_image_comp_t* component, int precision);
|
||||
void scale_component(opj_image_comp_t* component, int precision);
|
||||
|
||||
/* planar / interleaved conversions */
|
||||
typedef void (* convert_32s_CXPX)(const int* pSrc, int* const* pDst, size_t length);
|
||||
extern const convert_32s_CXPX convert_32s_CXPX_LUT[5];
|
||||
typedef void (* convert_32s_PXCX)(int const* const* pSrc, int* pDst, size_t length, int adjust);
|
||||
extern const convert_32s_PXCX convert_32s_PXCX_LUT[5];
|
||||
/* bit depth conversions */
|
||||
typedef void (* convert_XXx32s_C1R)(const unsigned char* pSrc, int* pDst, size_t length);
|
||||
extern const convert_XXx32s_C1R convert_XXu32s_C1R_LUT[9]; /* up to 8bpp */
|
||||
typedef void (* convert_32sXXx_C1R)(const int* pSrc, unsigned char* pDst, size_t length);
|
||||
extern const convert_32sXXx_C1R convert_32sXXu_C1R_LUT[9]; /* up to 8bpp */
|
||||
|
||||
/* TGA conversion */
|
||||
opj_image_t* tgatoimage(const char *filename, opj_cparameters_t *parameters);
|
||||
int imagetotga(opj_image_t * image, const char *outfile);
|
||||
|
||||
995
applications/codec/convertbmp.c
Normal file
995
applications/codec/convertbmp.c
Normal file
@@ -0,0 +1,995 @@
|
||||
/*
|
||||
* The copyright in this software is being made available under the 2-clauses
|
||||
* BSD License, included below. This software may be subject to other third
|
||||
* party and contributor rights, including patent rights, and no such rights
|
||||
* are granted under this license.
|
||||
*
|
||||
* Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
|
||||
* Copyright (c) 2002-2014, Professor Benoit Macq
|
||||
* Copyright (c) 2001-2003, David Janssens
|
||||
* Copyright (c) 2002-2003, Yannick Verschueren
|
||||
* Copyright (c) 2003-2007, Francois-Olivier Devaux
|
||||
* Copyright (c) 2003-2014, Antonin Descampe
|
||||
* Copyright (c) 2005, Herve Drolon, FreeImage Team
|
||||
* Copyright (c) 2006-2007, Parvatha Elangovan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "opj_config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "openjpeg.h"
|
||||
#include "convert.h"
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#if defined(_WIN32)
|
||||
typedef signed __int8 int8_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef signed __int16 int16_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef signed __int32 int32_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef signed __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
#error unsupported platform
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint16_t bfType; /* 'BM' for Bitmap (19776) */
|
||||
uint32_t bfSize; /* Size of the file */
|
||||
uint16_t bfReserved1; /* Reserved : 0 */
|
||||
uint16_t bfReserved2; /* Reserved : 0 */
|
||||
uint32_t bfOffBits; /* Offset */
|
||||
} OPJ_BITMAPFILEHEADER;
|
||||
|
||||
typedef struct {
|
||||
uint32_t biSize; /* Size of the structure in bytes */
|
||||
uint32_t biWidth; /* Width of the image in pixels */
|
||||
uint32_t biHeight; /* Heigth of the image in pixels */
|
||||
uint16_t biPlanes; /* 1 */
|
||||
uint16_t biBitCount; /* Number of color bits by pixels */
|
||||
uint32_t biCompression; /* Type of encoding 0: none 1: RLE8 2: RLE4 */
|
||||
uint32_t biSizeImage; /* Size of the image in bytes */
|
||||
uint32_t biXpelsPerMeter; /* Horizontal (X) resolution in pixels/meter */
|
||||
uint32_t biYpelsPerMeter; /* Vertical (Y) resolution in pixels/meter */
|
||||
uint32_t biClrUsed; /* Number of color used in the image (0: ALL) */
|
||||
uint32_t biClrImportant; /* Number of important color (0: ALL) */
|
||||
uint32_t biRedMask; /* Red channel bit mask */
|
||||
uint32_t biGreenMask; /* Green channel bit mask */
|
||||
uint32_t biBlueMask; /* Blue channel bit mask */
|
||||
uint32_t biAlphaMask; /* Alpha channel bit mask */
|
||||
uint32_t biColorSpaceType; /* Color space type */
|
||||
uint8_t biColorSpaceEP[36]; /* Color space end points */
|
||||
uint32_t biRedGamma; /* Red channel gamma */
|
||||
uint32_t biGreenGamma; /* Green channel gamma */
|
||||
uint32_t biBlueGamma; /* Blue channel gamma */
|
||||
uint32_t biIntent; /* Intent */
|
||||
uint32_t biIccProfileData; /* ICC profile data */
|
||||
uint32_t biIccProfileSize; /* ICC profile size */
|
||||
uint32_t biReserved; /* Reserved */
|
||||
} OPJ_BITMAPINFOHEADER;
|
||||
|
||||
static void opj_applyLUT8u_8u32s_C1R(
|
||||
uint8_t const* pSrc, int32_t srcStride,
|
||||
int32_t* pDst, int32_t dstStride,
|
||||
uint8_t const* pLUT,
|
||||
uint32_t width, uint32_t height)
|
||||
{
|
||||
uint32_t y;
|
||||
|
||||
for (y = height; y != 0U; --y) {
|
||||
uint32_t x;
|
||||
|
||||
for(x = 0; x < width; x++)
|
||||
{
|
||||
pDst[x] = (int32_t)pLUT[pSrc[x]];
|
||||
}
|
||||
pSrc += srcStride;
|
||||
pDst += dstStride;
|
||||
}
|
||||
}
|
||||
|
||||
static void opj_applyLUT8u_8u32s_C1P3R(
|
||||
uint8_t const* pSrc, int32_t srcStride,
|
||||
int32_t* const* pDst, int32_t const* pDstStride,
|
||||
uint8_t const* const* pLUT,
|
||||
uint32_t width, uint32_t height)
|
||||
{
|
||||
uint32_t y;
|
||||
int32_t* pR = pDst[0];
|
||||
int32_t* pG = pDst[1];
|
||||
int32_t* pB = pDst[2];
|
||||
uint8_t const* pLUT_R = pLUT[0];
|
||||
uint8_t const* pLUT_G = pLUT[1];
|
||||
uint8_t const* pLUT_B = pLUT[2];
|
||||
|
||||
for (y = height; y != 0U; --y) {
|
||||
uint32_t x;
|
||||
|
||||
for(x = 0; x < width; x++)
|
||||
{
|
||||
uint8_t idx = pSrc[x];
|
||||
pR[x] = (int32_t)pLUT_R[idx];
|
||||
pG[x] = (int32_t)pLUT_G[idx];
|
||||
pB[x] = (int32_t)pLUT_B[idx];
|
||||
}
|
||||
pSrc += srcStride;
|
||||
pR += pDstStride[0];
|
||||
pG += pDstStride[1];
|
||||
pB += pDstStride[2];
|
||||
}
|
||||
}
|
||||
|
||||
static void bmp24toimage(const uint8_t* pData, uint32_t stride, opj_image_t* image)
|
||||
{
|
||||
int index;
|
||||
uint32_t width, height;
|
||||
uint32_t x, y;
|
||||
const uint8_t *pSrc = NULL;
|
||||
|
||||
width = image->comps[0].w;
|
||||
height = image->comps[0].h;
|
||||
|
||||
index = 0;
|
||||
pSrc = pData + (height - 1U) * stride;
|
||||
for(y = 0; y < height; y++)
|
||||
{
|
||||
for(x = 0; x < width; x++)
|
||||
{
|
||||
image->comps[0].data[index] = (int32_t)pSrc[3*x+2]; /* R */
|
||||
image->comps[1].data[index] = (int32_t)pSrc[3*x+1]; /* G */
|
||||
image->comps[2].data[index] = (int32_t)pSrc[3*x+0]; /* B */
|
||||
index++;
|
||||
}
|
||||
pSrc -= stride;
|
||||
}
|
||||
}
|
||||
|
||||
static void bmp_mask_get_shift_and_prec(uint32_t mask, uint32_t* shift, uint32_t* prec)
|
||||
{
|
||||
uint32_t l_shift, l_prec;
|
||||
|
||||
l_shift = l_prec = 0U;
|
||||
|
||||
if (mask != 0U) {
|
||||
while ((mask & 1U) == 0U) {
|
||||
mask >>= 1;
|
||||
l_shift++;
|
||||
}
|
||||
while (mask & 1U) {
|
||||
mask >>= 1;
|
||||
l_prec++;
|
||||
}
|
||||
}
|
||||
*shift = l_shift; *prec = l_prec;
|
||||
}
|
||||
|
||||
static void bmpmask32toimage(const uint8_t* pData, uint32_t stride, opj_image_t* image, uint32_t redMask, uint32_t greenMask, uint32_t blueMask, uint32_t alphaMask)
|
||||
{
|
||||
int index;
|
||||
uint32_t width, height;
|
||||
uint32_t x, y;
|
||||
const uint8_t *pSrc = NULL;
|
||||
opj_bool hasAlpha = OPJ_FALSE;
|
||||
uint32_t redShift, redPrec;
|
||||
uint32_t greenShift, greenPrec;
|
||||
uint32_t blueShift, bluePrec;
|
||||
uint32_t alphaShift, alphaPrec;
|
||||
|
||||
width = image->comps[0].w;
|
||||
height = image->comps[0].h;
|
||||
|
||||
hasAlpha = image->numcomps > 3U;
|
||||
|
||||
bmp_mask_get_shift_and_prec(redMask, &redShift, &redPrec);
|
||||
bmp_mask_get_shift_and_prec(greenMask, &greenShift, &greenPrec);
|
||||
bmp_mask_get_shift_and_prec(blueMask, &blueShift, &bluePrec);
|
||||
bmp_mask_get_shift_and_prec(alphaMask, &alphaShift, &alphaPrec);
|
||||
|
||||
image->comps[0].bpp = redPrec;
|
||||
image->comps[0].prec = redPrec;
|
||||
image->comps[1].bpp = greenPrec;
|
||||
image->comps[1].prec = greenPrec;
|
||||
image->comps[2].bpp = bluePrec;
|
||||
image->comps[2].prec = bluePrec;
|
||||
if (hasAlpha) {
|
||||
image->comps[3].bpp = alphaPrec;
|
||||
image->comps[3].prec = alphaPrec;
|
||||
}
|
||||
|
||||
index = 0;
|
||||
pSrc = pData + (height - 1U) * stride;
|
||||
for(y = 0; y < height; y++)
|
||||
{
|
||||
for(x = 0; x < width; x++)
|
||||
{
|
||||
uint32_t value = 0U;
|
||||
|
||||
value |= ((uint32_t)pSrc[4*x+0]) << 0;
|
||||
value |= ((uint32_t)pSrc[4*x+1]) << 8;
|
||||
value |= ((uint32_t)pSrc[4*x+2]) << 16;
|
||||
value |= ((uint32_t)pSrc[4*x+3]) << 24;
|
||||
|
||||
image->comps[0].data[index] = (int32_t)((value & redMask) >> redShift); /* R */
|
||||
image->comps[1].data[index] = (int32_t)((value & greenMask) >> greenShift); /* G */
|
||||
image->comps[2].data[index] = (int32_t)((value & blueMask) >> blueShift); /* B */
|
||||
if (hasAlpha) {
|
||||
image->comps[3].data[index] = (int32_t)((value & alphaMask) >> alphaShift); /* A */
|
||||
}
|
||||
index++;
|
||||
}
|
||||
pSrc -= stride;
|
||||
}
|
||||
}
|
||||
|
||||
static void bmpmask16toimage(const uint8_t* pData, uint32_t stride, opj_image_t* image, uint32_t redMask, uint32_t greenMask, uint32_t blueMask, uint32_t alphaMask)
|
||||
{
|
||||
int index;
|
||||
uint32_t width, height;
|
||||
uint32_t x, y;
|
||||
const uint8_t *pSrc = NULL;
|
||||
opj_bool hasAlpha = OPJ_FALSE;
|
||||
uint32_t redShift, redPrec;
|
||||
uint32_t greenShift, greenPrec;
|
||||
uint32_t blueShift, bluePrec;
|
||||
uint32_t alphaShift, alphaPrec;
|
||||
|
||||
width = image->comps[0].w;
|
||||
height = image->comps[0].h;
|
||||
|
||||
hasAlpha = image->numcomps > 3U;
|
||||
|
||||
bmp_mask_get_shift_and_prec(redMask, &redShift, &redPrec);
|
||||
bmp_mask_get_shift_and_prec(greenMask, &greenShift, &greenPrec);
|
||||
bmp_mask_get_shift_and_prec(blueMask, &blueShift, &bluePrec);
|
||||
bmp_mask_get_shift_and_prec(alphaMask, &alphaShift, &alphaPrec);
|
||||
|
||||
image->comps[0].bpp = redPrec;
|
||||
image->comps[0].prec = redPrec;
|
||||
image->comps[1].bpp = greenPrec;
|
||||
image->comps[1].prec = greenPrec;
|
||||
image->comps[2].bpp = bluePrec;
|
||||
image->comps[2].prec = bluePrec;
|
||||
if (hasAlpha) {
|
||||
image->comps[3].bpp = alphaPrec;
|
||||
image->comps[3].prec = alphaPrec;
|
||||
}
|
||||
|
||||
index = 0;
|
||||
pSrc = pData + (height - 1U) * stride;
|
||||
for(y = 0; y < height; y++)
|
||||
{
|
||||
for(x = 0; x < width; x++)
|
||||
{
|
||||
uint32_t value = 0U;
|
||||
|
||||
value |= ((uint32_t)pSrc[2*x+0]) << 0;
|
||||
value |= ((uint32_t)pSrc[2*x+1]) << 8;
|
||||
|
||||
image->comps[0].data[index] = (int32_t)((value & redMask) >> redShift); /* R */
|
||||
image->comps[1].data[index] = (int32_t)((value & greenMask) >> greenShift); /* G */
|
||||
image->comps[2].data[index] = (int32_t)((value & blueMask) >> blueShift); /* B */
|
||||
if (hasAlpha) {
|
||||
image->comps[3].data[index] = (int32_t)((value & alphaMask) >> alphaShift); /* A */
|
||||
}
|
||||
index++;
|
||||
}
|
||||
pSrc -= stride;
|
||||
}
|
||||
}
|
||||
|
||||
static opj_image_t* bmp8toimage(const uint8_t* pData, uint32_t stride, opj_image_t* image, uint8_t const* const* pLUT)
|
||||
{
|
||||
uint32_t width, height;
|
||||
const uint8_t *pSrc = NULL;
|
||||
|
||||
width = image->comps[0].w;
|
||||
height = image->comps[0].h;
|
||||
|
||||
pSrc = pData + (height - 1U) * stride;
|
||||
if (image->numcomps == 1U) {
|
||||
opj_applyLUT8u_8u32s_C1R(pSrc, -(int32_t)stride, image->comps[0].data, (int32_t)width, pLUT[0], width, height);
|
||||
}
|
||||
else {
|
||||
int32_t* pDst[3];
|
||||
int32_t pDstStride[3];
|
||||
|
||||
pDst[0] = image->comps[0].data; pDst[1] = image->comps[1].data; pDst[2] = image->comps[2].data;
|
||||
pDstStride[0] = (int32_t)width; pDstStride[1] = (int32_t)width; pDstStride[2] = (int32_t)width;
|
||||
opj_applyLUT8u_8u32s_C1P3R(pSrc, -(int32_t)stride, pDst, pDstStride, pLUT, width, height);
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
static opj_bool bmp_read_file_header(FILE* IN, OPJ_BITMAPFILEHEADER* header)
|
||||
{
|
||||
header->bfType = (uint16_t)getc(IN);
|
||||
header->bfType |= (uint16_t)((uint32_t)getc(IN) << 8);
|
||||
|
||||
if (header->bfType != 19778) {
|
||||
fprintf(stderr,"Error, not a BMP file!\n");
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
/* FILE HEADER */
|
||||
/* ------------- */
|
||||
header->bfSize = (uint32_t)getc(IN);
|
||||
header->bfSize |= (uint32_t)getc(IN) << 8;
|
||||
header->bfSize |= (uint32_t)getc(IN) << 16;
|
||||
header->bfSize |= (uint32_t)getc(IN) << 24;
|
||||
|
||||
header->bfReserved1 = (uint16_t)getc(IN);
|
||||
header->bfReserved1 |= (uint16_t)((uint32_t)getc(IN) << 8);
|
||||
|
||||
header->bfReserved2 = (uint16_t)getc(IN);
|
||||
header->bfReserved2 |= (uint16_t)((uint32_t)getc(IN) << 8);
|
||||
|
||||
header->bfOffBits = (uint32_t)getc(IN);
|
||||
header->bfOffBits |= (uint32_t)getc(IN) << 8;
|
||||
header->bfOffBits |= (uint32_t)getc(IN) << 16;
|
||||
header->bfOffBits |= (uint32_t)getc(IN) << 24;
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
static opj_bool bmp_read_info_header(FILE* IN, OPJ_BITMAPINFOHEADER* header)
|
||||
{
|
||||
memset(header, 0, sizeof(*header));
|
||||
/* INFO HEADER */
|
||||
/* ------------- */
|
||||
header->biSize = (uint32_t)getc(IN);
|
||||
header->biSize |= (uint32_t)getc(IN) << 8;
|
||||
header->biSize |= (uint32_t)getc(IN) << 16;
|
||||
header->biSize |= (uint32_t)getc(IN) << 24;
|
||||
|
||||
switch (header->biSize) {
|
||||
case 12U: /* BITMAPCOREHEADER */
|
||||
case 40U: /* BITMAPINFOHEADER */
|
||||
case 52U: /* BITMAPV2INFOHEADER */
|
||||
case 56U: /* BITMAPV3INFOHEADER */
|
||||
case 108U: /* BITMAPV4HEADER */
|
||||
case 124U: /* BITMAPV5HEADER */
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"Error, unknown BMP header size %d\n", header->biSize);
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
header->biWidth = (uint32_t)getc(IN);
|
||||
header->biWidth |= (uint32_t)getc(IN) << 8;
|
||||
header->biWidth |= (uint32_t)getc(IN) << 16;
|
||||
header->biWidth |= (uint32_t)getc(IN) << 24;
|
||||
|
||||
header->biHeight = (uint32_t)getc(IN);
|
||||
header->biHeight |= (uint32_t)getc(IN) << 8;
|
||||
header->biHeight |= (uint32_t)getc(IN) << 16;
|
||||
header->biHeight |= (uint32_t)getc(IN) << 24;
|
||||
|
||||
header->biPlanes = (uint16_t)getc(IN);
|
||||
header->biPlanes |= (uint16_t)((uint32_t)getc(IN) << 8);
|
||||
|
||||
header->biBitCount = (uint16_t)getc(IN);
|
||||
header->biBitCount |= (uint16_t)((uint32_t)getc(IN) << 8);
|
||||
|
||||
if(header->biSize >= 40U) {
|
||||
header->biCompression = (uint32_t)getc(IN);
|
||||
header->biCompression |= (uint32_t)getc(IN) << 8;
|
||||
header->biCompression |= (uint32_t)getc(IN) << 16;
|
||||
header->biCompression |= (uint32_t)getc(IN) << 24;
|
||||
|
||||
header->biSizeImage = (uint32_t)getc(IN);
|
||||
header->biSizeImage |= (uint32_t)getc(IN) << 8;
|
||||
header->biSizeImage |= (uint32_t)getc(IN) << 16;
|
||||
header->biSizeImage |= (uint32_t)getc(IN) << 24;
|
||||
|
||||
header->biXpelsPerMeter = (uint32_t)getc(IN);
|
||||
header->biXpelsPerMeter |= (uint32_t)getc(IN) << 8;
|
||||
header->biXpelsPerMeter |= (uint32_t)getc(IN) << 16;
|
||||
header->biXpelsPerMeter |= (uint32_t)getc(IN) << 24;
|
||||
|
||||
header->biYpelsPerMeter = (uint32_t)getc(IN);
|
||||
header->biYpelsPerMeter |= (uint32_t)getc(IN) << 8;
|
||||
header->biYpelsPerMeter |= (uint32_t)getc(IN) << 16;
|
||||
header->biYpelsPerMeter |= (uint32_t)getc(IN) << 24;
|
||||
|
||||
header->biClrUsed = (uint32_t)getc(IN);
|
||||
header->biClrUsed |= (uint32_t)getc(IN) << 8;
|
||||
header->biClrUsed |= (uint32_t)getc(IN) << 16;
|
||||
header->biClrUsed |= (uint32_t)getc(IN) << 24;
|
||||
|
||||
header->biClrImportant = (uint32_t)getc(IN);
|
||||
header->biClrImportant |= (uint32_t)getc(IN) << 8;
|
||||
header->biClrImportant |= (uint32_t)getc(IN) << 16;
|
||||
header->biClrImportant |= (uint32_t)getc(IN) << 24;
|
||||
}
|
||||
|
||||
if(header->biSize >= 56U) {
|
||||
header->biRedMask = (uint32_t)getc(IN);
|
||||
header->biRedMask |= (uint32_t)getc(IN) << 8;
|
||||
header->biRedMask |= (uint32_t)getc(IN) << 16;
|
||||
header->biRedMask |= (uint32_t)getc(IN) << 24;
|
||||
|
||||
header->biGreenMask = (uint32_t)getc(IN);
|
||||
header->biGreenMask |= (uint32_t)getc(IN) << 8;
|
||||
header->biGreenMask |= (uint32_t)getc(IN) << 16;
|
||||
header->biGreenMask |= (uint32_t)getc(IN) << 24;
|
||||
|
||||
header->biBlueMask = (uint32_t)getc(IN);
|
||||
header->biBlueMask |= (uint32_t)getc(IN) << 8;
|
||||
header->biBlueMask |= (uint32_t)getc(IN) << 16;
|
||||
header->biBlueMask |= (uint32_t)getc(IN) << 24;
|
||||
|
||||
header->biAlphaMask = (uint32_t)getc(IN);
|
||||
header->biAlphaMask |= (uint32_t)getc(IN) << 8;
|
||||
header->biAlphaMask |= (uint32_t)getc(IN) << 16;
|
||||
header->biAlphaMask |= (uint32_t)getc(IN) << 24;
|
||||
}
|
||||
|
||||
if(header->biSize >= 108U) {
|
||||
header->biColorSpaceType = (uint32_t)getc(IN);
|
||||
header->biColorSpaceType |= (uint32_t)getc(IN) << 8;
|
||||
header->biColorSpaceType |= (uint32_t)getc(IN) << 16;
|
||||
header->biColorSpaceType |= (uint32_t)getc(IN) << 24;
|
||||
|
||||
if (fread(&(header->biColorSpaceEP), 1U, sizeof(header->biColorSpaceEP), IN) != sizeof(header->biColorSpaceEP)) {
|
||||
fprintf(stderr,"Error, can't read BMP header\n");
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
header->biRedGamma = (uint32_t)getc(IN);
|
||||
header->biRedGamma |= (uint32_t)getc(IN) << 8;
|
||||
header->biRedGamma |= (uint32_t)getc(IN) << 16;
|
||||
header->biRedGamma |= (uint32_t)getc(IN) << 24;
|
||||
|
||||
header->biGreenGamma = (uint32_t)getc(IN);
|
||||
header->biGreenGamma |= (uint32_t)getc(IN) << 8;
|
||||
header->biGreenGamma |= (uint32_t)getc(IN) << 16;
|
||||
header->biGreenGamma |= (uint32_t)getc(IN) << 24;
|
||||
|
||||
header->biBlueGamma = (uint32_t)getc(IN);
|
||||
header->biBlueGamma |= (uint32_t)getc(IN) << 8;
|
||||
header->biBlueGamma |= (uint32_t)getc(IN) << 16;
|
||||
header->biBlueGamma |= (uint32_t)getc(IN) << 24;
|
||||
}
|
||||
|
||||
if(header->biSize >= 124U) {
|
||||
header->biIntent = (uint32_t)getc(IN);
|
||||
header->biIntent |= (uint32_t)getc(IN) << 8;
|
||||
header->biIntent |= (uint32_t)getc(IN) << 16;
|
||||
header->biIntent |= (uint32_t)getc(IN) << 24;
|
||||
|
||||
header->biIccProfileData = (uint32_t)getc(IN);
|
||||
header->biIccProfileData |= (uint32_t)getc(IN) << 8;
|
||||
header->biIccProfileData |= (uint32_t)getc(IN) << 16;
|
||||
header->biIccProfileData |= (uint32_t)getc(IN) << 24;
|
||||
|
||||
header->biIccProfileSize = (uint32_t)getc(IN);
|
||||
header->biIccProfileSize |= (uint32_t)getc(IN) << 8;
|
||||
header->biIccProfileSize |= (uint32_t)getc(IN) << 16;
|
||||
header->biIccProfileSize |= (uint32_t)getc(IN) << 24;
|
||||
|
||||
header->biReserved = (uint32_t)getc(IN);
|
||||
header->biReserved |= (uint32_t)getc(IN) << 8;
|
||||
header->biReserved |= (uint32_t)getc(IN) << 16;
|
||||
header->biReserved |= (uint32_t)getc(IN) << 24;
|
||||
}
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
static opj_bool bmp_read_raw_data(FILE* IN, uint8_t* pData, uint32_t stride, uint32_t width, uint32_t height)
|
||||
{
|
||||
OPJ_ARG_NOT_USED(width);
|
||||
|
||||
if ( fread(pData, sizeof(uint8_t), stride * height, IN) != (stride * height) )
|
||||
{
|
||||
fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
static opj_bool bmp_read_rle8_data(FILE* IN, uint8_t* pData, uint32_t stride, uint32_t width, uint32_t height)
|
||||
{
|
||||
uint32_t x, y;
|
||||
uint8_t *pix;
|
||||
const uint8_t *beyond;
|
||||
|
||||
beyond = pData + stride * height;
|
||||
pix = pData;
|
||||
|
||||
x = y = 0U;
|
||||
while (y < height)
|
||||
{
|
||||
int c = getc(IN);
|
||||
|
||||
if (c) {
|
||||
int j;
|
||||
uint8_t c1 = (uint8_t)getc(IN);
|
||||
|
||||
for (j = 0; (j < c) && (x < width) && ((size_t)pix < (size_t)beyond); j++, x++, pix++) {
|
||||
*pix = c1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
c = getc(IN);
|
||||
if (c == 0x00) { /* EOL */
|
||||
x = 0;
|
||||
++y;
|
||||
pix = pData + y * stride + x;
|
||||
}
|
||||
else if (c == 0x01) { /* EOP */
|
||||
break;
|
||||
}
|
||||
else if (c == 0x02) { /* MOVE by dxdy */
|
||||
c = getc(IN);
|
||||
x += (uint32_t)c;
|
||||
c = getc(IN);
|
||||
y += (uint32_t)c;
|
||||
pix = pData + y * stride + x;
|
||||
}
|
||||
else /* 03 .. 255 */
|
||||
{
|
||||
int j;
|
||||
for (j = 0; (j < c) && (x < width) && ((size_t)pix < (size_t)beyond); j++, x++, pix++)
|
||||
{
|
||||
uint8_t c1 = (uint8_t)getc(IN);
|
||||
*pix = c1;
|
||||
}
|
||||
if ((uint32_t)c & 1U) { /* skip padding byte */
|
||||
getc(IN);
|
||||
}
|
||||
}
|
||||
}
|
||||
}/* while() */
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
static opj_bool bmp_read_rle4_data(FILE* IN, uint8_t* pData, uint32_t stride, uint32_t width, uint32_t height)
|
||||
{
|
||||
uint32_t x, y;
|
||||
uint8_t *pix;
|
||||
const uint8_t *beyond;
|
||||
|
||||
beyond = pData + stride * height;
|
||||
pix = pData;
|
||||
x = y = 0U;
|
||||
while(y < height)
|
||||
{
|
||||
int c = getc(IN);
|
||||
if(c == EOF) break;
|
||||
|
||||
if(c) {/* encoded mode */
|
||||
int j;
|
||||
uint8_t c1 = (uint8_t)getc(IN);
|
||||
|
||||
for (j = 0; (j < c) && (x < width) && ((size_t)pix < (size_t)beyond); j++, x++, pix++) {
|
||||
*pix = (uint8_t)((j&1) ? (c1 & 0x0fU) : ((c1>>4)&0x0fU));
|
||||
}
|
||||
}
|
||||
else { /* absolute mode */
|
||||
c = getc(IN);
|
||||
if(c == EOF) break;
|
||||
|
||||
if(c == 0x00) { /* EOL */
|
||||
x = 0; y++; pix = pData + y * stride;
|
||||
}
|
||||
else if(c == 0x01) { /* EOP */
|
||||
break;
|
||||
}
|
||||
else if(c == 0x02) { /* MOVE by dxdy */
|
||||
c = getc(IN); x += (uint32_t)c;
|
||||
c = getc(IN); y += (uint32_t)c;
|
||||
pix = pData + y * stride + x;
|
||||
}
|
||||
else { /* 03 .. 255 : absolute mode */
|
||||
int j;
|
||||
uint8_t c1 = 0U;
|
||||
|
||||
for (j = 0; (j < c) && (x < width) && ((size_t)pix < (size_t)beyond); j++, x++, pix++) {
|
||||
if((j&1) == 0) {
|
||||
c1 = (uint8_t)getc(IN);
|
||||
}
|
||||
*pix = (uint8_t)((j&1) ? (c1 & 0x0fU) : ((c1>>4)&0x0fU));
|
||||
}
|
||||
if(((c&3) == 1) || ((c&3) == 2)) { /* skip padding byte */
|
||||
getc(IN);
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* while(y < height) */
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters)
|
||||
{
|
||||
opj_image_cmptparm_t cmptparm[4]; /* maximum of 4 components */
|
||||
uint8_t lut_R[256], lut_G[256], lut_B[256];
|
||||
uint8_t const* pLUT[3];
|
||||
opj_image_t * image = NULL;
|
||||
FILE *IN;
|
||||
OPJ_BITMAPFILEHEADER File_h;
|
||||
OPJ_BITMAPINFOHEADER Info_h;
|
||||
uint32_t i, palette_len, numcmpts = 1U;
|
||||
opj_bool l_result = OPJ_FALSE;
|
||||
uint8_t* pData = NULL;
|
||||
uint32_t stride;
|
||||
|
||||
pLUT[0] = lut_R; pLUT[1] = lut_G; pLUT[2] = lut_B;
|
||||
|
||||
IN = fopen(filename, "rb");
|
||||
if (!IN)
|
||||
{
|
||||
fprintf(stderr, "Failed to open %s for reading !!\n", filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!bmp_read_file_header(IN, &File_h)) {
|
||||
fclose(IN);
|
||||
return NULL;
|
||||
}
|
||||
if (!bmp_read_info_header(IN, &Info_h)) {
|
||||
fclose(IN);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Load palette */
|
||||
if (Info_h.biBitCount <= 8U)
|
||||
{
|
||||
memset(&lut_R[0], 0, sizeof(lut_R));
|
||||
memset(&lut_G[0], 0, sizeof(lut_G));
|
||||
memset(&lut_B[0], 0, sizeof(lut_B));
|
||||
|
||||
palette_len = Info_h.biClrUsed;
|
||||
if((palette_len == 0U) && (Info_h.biBitCount <= 8U)) {
|
||||
palette_len = (1U << Info_h.biBitCount);
|
||||
}
|
||||
if (palette_len > 256U) {
|
||||
palette_len = 256U;
|
||||
}
|
||||
if (palette_len > 0U) {
|
||||
uint8_t has_color = 0U;
|
||||
for (i = 0U; i < palette_len; i++) {
|
||||
lut_B[i] = (uint8_t)getc(IN);
|
||||
lut_G[i] = (uint8_t)getc(IN);
|
||||
lut_R[i] = (uint8_t)getc(IN);
|
||||
(void)getc(IN); /* padding */
|
||||
has_color |= (lut_B[i] ^ lut_G[i]) | (lut_G[i] ^ lut_R[i]);
|
||||
}
|
||||
if(has_color) {
|
||||
numcmpts = 3U;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
numcmpts = 3U;
|
||||
if ((Info_h.biCompression == 3) && (Info_h.biAlphaMask != 0U)) {
|
||||
numcmpts++;
|
||||
}
|
||||
}
|
||||
|
||||
stride = ((Info_h.biWidth * Info_h.biBitCount + 31U) / 32U) * 4U; /* rows are aligned on 32bits */
|
||||
if (Info_h.biBitCount == 4 && Info_h.biCompression == 2) { /* RLE 4 gets decoded as 8 bits data for now... */
|
||||
stride = ((Info_h.biWidth * 8U + 31U) / 32U) * 4U;
|
||||
}
|
||||
pData = (uint8_t *) calloc(1, stride * Info_h.biHeight * sizeof(uint8_t));
|
||||
if (pData == NULL) {
|
||||
fclose(IN);
|
||||
return NULL;
|
||||
}
|
||||
/* Place the cursor at the beginning of the image information */
|
||||
fseek(IN, 0, SEEK_SET);
|
||||
fseek(IN, (long)File_h.bfOffBits, SEEK_SET);
|
||||
|
||||
switch (Info_h.biCompression) {
|
||||
case 0:
|
||||
case 3:
|
||||
/* read raw data */
|
||||
l_result = bmp_read_raw_data(IN, pData, stride, Info_h.biWidth, Info_h.biHeight);
|
||||
break;
|
||||
case 1:
|
||||
/* read rle8 data */
|
||||
l_result = bmp_read_rle8_data(IN, pData, stride, Info_h.biWidth, Info_h.biHeight);
|
||||
break;
|
||||
case 2:
|
||||
/* read rle4 data */
|
||||
l_result = bmp_read_rle4_data(IN, pData, stride, Info_h.biWidth, Info_h.biHeight);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unsupported BMP compression\n");
|
||||
l_result = OPJ_FALSE;
|
||||
break;
|
||||
}
|
||||
if (!l_result) {
|
||||
free(pData);
|
||||
fclose(IN);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* create the image */
|
||||
memset(&cmptparm[0], 0, sizeof(cmptparm));
|
||||
for(i = 0; i < 4U; i++)
|
||||
{
|
||||
cmptparm[i].prec = 8;
|
||||
cmptparm[i].bpp = 8;
|
||||
cmptparm[i].sgnd = 0;
|
||||
cmptparm[i].dx = parameters->subsampling_dx;
|
||||
cmptparm[i].dy = parameters->subsampling_dy;
|
||||
cmptparm[i].w = Info_h.biWidth;
|
||||
cmptparm[i].h = Info_h.biHeight;
|
||||
}
|
||||
|
||||
image = opj_image_create(numcmpts, &cmptparm[0], (numcmpts == 1U) ? CLRSPC_GRAY : CLRSPC_SRGB);
|
||||
if(!image) {
|
||||
fclose(IN);
|
||||
free(pData);
|
||||
return NULL;
|
||||
}
|
||||
/* if (numcmpts == 4U) {
|
||||
image->comps[3].alpha = 1;
|
||||
} */
|
||||
|
||||
/* set image offset and reference grid */
|
||||
image->x0 = (uint32_t)parameters->image_offset_x0;
|
||||
image->y0 = (uint32_t)parameters->image_offset_y0;
|
||||
image->x1 = image->x0 + (Info_h.biWidth - 1U) * (uint32_t)parameters->subsampling_dx + 1U;
|
||||
image->y1 = image->y0 + (Info_h.biHeight - 1U) * (uint32_t)parameters->subsampling_dy + 1U;
|
||||
|
||||
/* Read the data */
|
||||
if (Info_h.biBitCount == 24 && Info_h.biCompression == 0) { /*RGB */
|
||||
bmp24toimage(pData, stride, image);
|
||||
}
|
||||
else if (Info_h.biBitCount == 8 && Info_h.biCompression == 0) { /* RGB 8bpp Indexed */
|
||||
bmp8toimage(pData, stride, image, pLUT);
|
||||
}
|
||||
else if (Info_h.biBitCount == 8 && Info_h.biCompression == 1) { /*RLE8*/
|
||||
bmp8toimage(pData, stride, image, pLUT);
|
||||
}
|
||||
else if (Info_h.biBitCount == 4 && Info_h.biCompression == 2) { /*RLE4*/
|
||||
bmp8toimage(pData, stride, image, pLUT); /* RLE 4 gets decoded as 8 bits data for now */
|
||||
}
|
||||
else if (Info_h.biBitCount == 32 && Info_h.biCompression == 0) { /* RGBX */
|
||||
bmpmask32toimage(pData, stride, image, 0x00FF0000U, 0x0000FF00U, 0x000000FFU, 0x00000000U);
|
||||
}
|
||||
else if (Info_h.biBitCount == 32 && Info_h.biCompression == 3) { /* bitmask */
|
||||
bmpmask32toimage(pData, stride, image, Info_h.biRedMask, Info_h.biGreenMask, Info_h.biBlueMask, Info_h.biAlphaMask);
|
||||
}
|
||||
else if (Info_h.biBitCount == 16 && Info_h.biCompression == 0) { /* RGBX */
|
||||
bmpmask16toimage(pData, stride, image, 0x7C00U, 0x03E0U, 0x001FU, 0x0000U);
|
||||
}
|
||||
else if (Info_h.biBitCount == 16 && Info_h.biCompression == 3) { /* bitmask */
|
||||
if ((Info_h.biRedMask == 0U) && (Info_h.biGreenMask == 0U) && (Info_h.biBlueMask == 0U)) {
|
||||
Info_h.biRedMask = 0xF800U;
|
||||
Info_h.biGreenMask = 0x07E0U;
|
||||
Info_h.biBlueMask = 0x001FU;
|
||||
}
|
||||
bmpmask16toimage(pData, stride, image, Info_h.biRedMask, Info_h.biGreenMask, Info_h.biBlueMask, Info_h.biAlphaMask);
|
||||
}
|
||||
else {
|
||||
opj_image_destroy(image);
|
||||
image = NULL;
|
||||
fprintf(stderr, "Other system than 24 bits/pixels or 8 bits (no RLE coding) is not yet implemented [%d]\n", Info_h.biBitCount);
|
||||
}
|
||||
free(pData);
|
||||
fclose(IN);
|
||||
return image;
|
||||
}
|
||||
|
||||
int imagetobmp(opj_image_t * image, const char *outfile) {
|
||||
int w, h;
|
||||
int i, pad;
|
||||
FILE *fdest = NULL;
|
||||
int adjustR, adjustG, adjustB;
|
||||
|
||||
if (image->comps[0].prec < 8) {
|
||||
fprintf(stderr, "Unsupported number of components: %d\n", image->comps[0].prec);
|
||||
return 1;
|
||||
}
|
||||
if (image->numcomps >= 3 && image->comps[0].dx == image->comps[1].dx
|
||||
&& image->comps[1].dx == image->comps[2].dx
|
||||
&& image->comps[0].dy == image->comps[1].dy
|
||||
&& image->comps[1].dy == image->comps[2].dy
|
||||
&& image->comps[0].prec == image->comps[1].prec
|
||||
&& image->comps[1].prec == image->comps[2].prec) {
|
||||
|
||||
/* -->> -->> -->> -->>
|
||||
24 bits color
|
||||
<<-- <<-- <<-- <<-- */
|
||||
|
||||
fdest = fopen(outfile, "wb");
|
||||
if (!fdest) {
|
||||
fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
|
||||
return 1;
|
||||
}
|
||||
|
||||
w = (int)image->comps[0].w;
|
||||
h = (int)image->comps[0].h;
|
||||
|
||||
fprintf(fdest, "BM");
|
||||
|
||||
/* FILE HEADER */
|
||||
/* ------------- */
|
||||
fprintf(fdest, "%c%c%c%c",
|
||||
(uint8_t) (h * w * 3 + 3 * h * (w % 2) + 54) & 0xff,
|
||||
(uint8_t) ((h * w * 3 + 3 * h * (w % 2) + 54) >> 8) & 0xff,
|
||||
(uint8_t) ((h * w * 3 + 3 * h * (w % 2) + 54) >> 16) & 0xff,
|
||||
(uint8_t) ((h * w * 3 + 3 * h * (w % 2) + 54) >> 24) & 0xff);
|
||||
fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
|
||||
fprintf(fdest, "%c%c%c%c", (54) & 0xff, ((54) >> 8) & 0xff,((54) >> 16) & 0xff, ((54) >> 24) & 0xff);
|
||||
|
||||
/* INFO HEADER */
|
||||
/* ------------- */
|
||||
fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff, ((40) >> 16) & 0xff, ((40) >> 24) & 0xff);
|
||||
fprintf(fdest, "%c%c%c%c", (uint8_t) ((w) & 0xff),
|
||||
(uint8_t) ((w) >> 8) & 0xff,
|
||||
(uint8_t) ((w) >> 16) & 0xff,
|
||||
(uint8_t) ((w) >> 24) & 0xff);
|
||||
fprintf(fdest, "%c%c%c%c", (uint8_t) ((h) & 0xff),
|
||||
(uint8_t) ((h) >> 8) & 0xff,
|
||||
(uint8_t) ((h) >> 16) & 0xff,
|
||||
(uint8_t) ((h) >> 24) & 0xff);
|
||||
fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff);
|
||||
fprintf(fdest, "%c%c", (24) & 0xff, ((24) >> 8) & 0xff);
|
||||
fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
|
||||
fprintf(fdest, "%c%c%c%c", (uint8_t) (3 * h * w + 3 * h * (w % 2)) & 0xff,
|
||||
(uint8_t) ((h * w * 3 + 3 * h * (w % 2)) >> 8) & 0xff,
|
||||
(uint8_t) ((h * w * 3 + 3 * h * (w % 2)) >> 16) & 0xff,
|
||||
(uint8_t) ((h * w * 3 + 3 * h * (w % 2)) >> 24) & 0xff);
|
||||
fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
|
||||
fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
|
||||
fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
|
||||
fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
|
||||
|
||||
if (image->comps[0].prec > 8) {
|
||||
adjustR = (int)image->comps[0].prec - 8;
|
||||
printf("BMP CONVERSION: Truncating component 0 from %d bits to 8 bits\n", image->comps[0].prec);
|
||||
}
|
||||
else
|
||||
adjustR = 0;
|
||||
if (image->comps[1].prec > 8) {
|
||||
adjustG = (int)image->comps[1].prec - 8;
|
||||
printf("BMP CONVERSION: Truncating component 1 from %d bits to 8 bits\n", image->comps[1].prec);
|
||||
}
|
||||
else
|
||||
adjustG = 0;
|
||||
if (image->comps[2].prec > 8) {
|
||||
adjustB = (int)image->comps[2].prec - 8;
|
||||
printf("BMP CONVERSION: Truncating component 2 from %d bits to 8 bits\n", image->comps[2].prec);
|
||||
}
|
||||
else
|
||||
adjustB = 0;
|
||||
|
||||
for (i = 0; i < w * h; i++) {
|
||||
uint8_t rc, gc, bc;
|
||||
int r, g, b;
|
||||
|
||||
r = image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
|
||||
r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
|
||||
r = ((r >> adjustR)+((r >> (adjustR-1))%2));
|
||||
if(r > 255) r = 255; else if(r < 0) r = 0;
|
||||
rc = (uint8_t)r;
|
||||
|
||||
g = image->comps[1].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
|
||||
g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
|
||||
g = ((g >> adjustG)+((g >> (adjustG-1))%2));
|
||||
if(g > 255) g = 255; else if(g < 0) g = 0;
|
||||
gc = (uint8_t)g;
|
||||
|
||||
b = image->comps[2].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
|
||||
b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
|
||||
b = ((b >> adjustB)+((b >> (adjustB-1))%2));
|
||||
if(b > 255) b = 255; else if(b < 0) b = 0;
|
||||
bc = (uint8_t)b;
|
||||
|
||||
fprintf(fdest, "%c%c%c", bc, gc, rc);
|
||||
|
||||
if ((i + 1) % w == 0) {
|
||||
for (pad = (3 * w) % 4 ? 4 - (3 * w) % 4 : 0; pad > 0; pad--) /* ADD */
|
||||
fprintf(fdest, "%c", 0);
|
||||
}
|
||||
}
|
||||
fclose(fdest);
|
||||
} else { /* Gray-scale */
|
||||
|
||||
/* -->> -->> -->> -->>
|
||||
8 bits non code (Gray scale)
|
||||
<<-- <<-- <<-- <<-- */
|
||||
|
||||
fdest = fopen(outfile, "wb");
|
||||
if (!fdest) {
|
||||
fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
|
||||
return 1;
|
||||
}
|
||||
w = (int)image->comps[0].w;
|
||||
h = (int)image->comps[0].h;
|
||||
|
||||
fprintf(fdest, "BM");
|
||||
|
||||
/* FILE HEADER */
|
||||
/* ------------- */
|
||||
fprintf(fdest, "%c%c%c%c", (uint8_t) (h * w + 54 + 1024 + h * (w % 2)) & 0xff,
|
||||
(uint8_t) ((h * w + 54 + 1024 + h * (w % 2)) >> 8) & 0xff,
|
||||
(uint8_t) ((h * w + 54 + 1024 + h * (w % 2)) >> 16) & 0xff,
|
||||
(uint8_t) ((h * w + 54 + 1024 + w * (w % 2)) >> 24) & 0xff);
|
||||
fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
|
||||
fprintf(fdest, "%c%c%c%c", (54 + 1024) & 0xff, ((54 + 1024) >> 8) & 0xff,
|
||||
((54 + 1024) >> 16) & 0xff,
|
||||
((54 + 1024) >> 24) & 0xff);
|
||||
|
||||
/* INFO HEADER */
|
||||
/* ------------- */
|
||||
fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff, ((40) >> 16) & 0xff, ((40) >> 24) & 0xff);
|
||||
fprintf(fdest, "%c%c%c%c", (uint8_t) ((w) & 0xff),
|
||||
(uint8_t) ((w) >> 8) & 0xff,
|
||||
(uint8_t) ((w) >> 16) & 0xff,
|
||||
(uint8_t) ((w) >> 24) & 0xff);
|
||||
fprintf(fdest, "%c%c%c%c", (uint8_t) ((h) & 0xff),
|
||||
(uint8_t) ((h) >> 8) & 0xff,
|
||||
(uint8_t) ((h) >> 16) & 0xff,
|
||||
(uint8_t) ((h) >> 24) & 0xff);
|
||||
fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff);
|
||||
fprintf(fdest, "%c%c", (8) & 0xff, ((8) >> 8) & 0xff);
|
||||
fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
|
||||
fprintf(fdest, "%c%c%c%c", (uint8_t) (h * w + h * (w % 2)) & 0xff,
|
||||
(uint8_t) ((h * w + h * (w % 2)) >> 8) & 0xff,
|
||||
(uint8_t) ((h * w + h * (w % 2)) >> 16) & 0xff,
|
||||
(uint8_t) ((h * w + h * (w % 2)) >> 24) & 0xff);
|
||||
fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
|
||||
fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
|
||||
fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff);
|
||||
fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff);
|
||||
|
||||
if (image->comps[0].prec > 8) {
|
||||
adjustR = (int)image->comps[0].prec - 8;
|
||||
printf("BMP CONVERSION: Truncating component 0 from %d bits to 8 bits\n", image->comps[0].prec);
|
||||
}else
|
||||
adjustR = 0;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
fprintf(fdest, "%c%c%c%c", i, i, i, 0);
|
||||
}
|
||||
|
||||
for (i = 0; i < w * h; i++) {
|
||||
int r;
|
||||
|
||||
r = image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
|
||||
r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
|
||||
r = ((r >> adjustR)+((r >> (adjustR-1))%2));
|
||||
if(r > 255) r = 255; else if(r < 0) r = 0;
|
||||
|
||||
fprintf(fdest, "%c", (uint8_t)r);
|
||||
|
||||
if ((i + 1) % w == 0) {
|
||||
for (pad = w % 4 ? 4 - w % 4 : 0; pad > 0; pad--) /* ADD */
|
||||
fprintf(fdest, "%c", 0);
|
||||
}
|
||||
}
|
||||
fclose(fdest);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
496
applications/codec/convertpng.c
Normal file
496
applications/codec/convertpng.c
Normal file
@@ -0,0 +1,496 @@
|
||||
/*
|
||||
* The copyright in this software is being made available under the 2-clauses
|
||||
* BSD License, included below. This software may be subject to other third
|
||||
* party and contributor rights, including patent rights, and no such rights
|
||||
* are granted under this license.
|
||||
*
|
||||
* Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
|
||||
* Copyright (c) 2002-2014, Professor Benoit Macq
|
||||
* Copyright (c) 2001-2003, David Janssens
|
||||
* Copyright (c) 2002-2003, Yannick Verschueren
|
||||
* Copyright (c) 2003-2007, Francois-Olivier Devaux
|
||||
* Copyright (c) 2003-2014, Antonin Descampe
|
||||
* Copyright (c) 2005, Herve Drolon, FreeImage Team
|
||||
* Copyright (c) 2006-2007, Parvatha Elangovan
|
||||
* Copyright (c) 2015, Matthieu Darbois
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "opj_config.h"
|
||||
|
||||
#ifndef HAVE_LIBPNG
|
||||
# error HAVE_LIBPNG_NOT_DEFINED
|
||||
#endif /* HAVE_LIBPNG */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <zlib.h>
|
||||
#include <png.h>
|
||||
|
||||
#include "openjpeg.h"
|
||||
#include "convert.h"
|
||||
|
||||
#define PNG_MAGIC "\x89PNG\x0d\x0a\x1a\x0a"
|
||||
#define MAGIC_SIZE 8
|
||||
/* PNG allows bits per sample: 1, 2, 4, 8, 16 */
|
||||
|
||||
|
||||
static void convert_16u32s_C1R(const png_byte* pSrc, png_int_32* pDst, size_t length)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < length; i++) {
|
||||
png_int_32 val0 = *pSrc++;
|
||||
png_int_32 val1 = *pSrc++;
|
||||
pDst[i] = val0 << 8 | val1;
|
||||
}
|
||||
}
|
||||
|
||||
opj_image_t *pngtoimage(const char *read_idf, opj_cparameters_t * params)
|
||||
{
|
||||
png_structp png = NULL;
|
||||
png_infop info = NULL;
|
||||
double gamma;
|
||||
int bit_depth, interlace_type,compression_type, filter_type;
|
||||
png_uint_32 i;
|
||||
png_uint_32 width, height = 0U;
|
||||
int color_type;
|
||||
FILE *reader = NULL;
|
||||
png_byte** rows = NULL;
|
||||
png_int_32* row32s = NULL;
|
||||
/* j2k: */
|
||||
opj_image_t *image = NULL;
|
||||
opj_image_cmptparm_t cmptparm[4];
|
||||
png_uint_32 nr_comp;
|
||||
png_byte sigbuf[8];
|
||||
convert_XXx32s_C1R cvtXXTo32s = NULL;
|
||||
convert_32s_CXPX cvtCxToPx = NULL;
|
||||
png_int_32* planes[4];
|
||||
|
||||
if((reader = fopen(read_idf, "rb")) == NULL)
|
||||
{
|
||||
fprintf(stderr,"pngtoimage: can not open %s\n",read_idf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(fread(sigbuf, 1, MAGIC_SIZE, reader) != MAGIC_SIZE
|
||||
|| memcmp(sigbuf, PNG_MAGIC, MAGIC_SIZE) != 0)
|
||||
{
|
||||
fprintf(stderr,"pngtoimage: %s is no valid PNG file\n",read_idf);
|
||||
goto fin;
|
||||
}
|
||||
|
||||
if((png = png_create_read_struct(PNG_LIBPNG_VER_STRING,
|
||||
NULL, NULL, NULL)) == NULL)
|
||||
goto fin;
|
||||
if((info = png_create_info_struct(png)) == NULL)
|
||||
goto fin;
|
||||
|
||||
if(setjmp(png_jmpbuf(png)))
|
||||
goto fin;
|
||||
|
||||
png_init_io(png, reader);
|
||||
png_set_sig_bytes(png, MAGIC_SIZE);
|
||||
|
||||
png_read_info(png, info);
|
||||
|
||||
if(png_get_IHDR(png, info, &width, &height,
|
||||
&bit_depth, &color_type, &interlace_type,
|
||||
&compression_type, &filter_type) == 0)
|
||||
goto fin;
|
||||
|
||||
/* png_set_expand():
|
||||
* expand paletted images to RGB, expand grayscale images of
|
||||
* less than 8-bit depth to 8-bit depth, and expand tRNS chunks
|
||||
* to alpha channels.
|
||||
*/
|
||||
if(color_type == PNG_COLOR_TYPE_PALETTE) {
|
||||
png_set_expand(png);
|
||||
}
|
||||
|
||||
if(png_get_valid(png, info, PNG_INFO_tRNS)) {
|
||||
png_set_expand(png);
|
||||
}
|
||||
/* We might wan't to expand background */
|
||||
/*
|
||||
if(png_get_valid(png, info, PNG_INFO_bKGD)) {
|
||||
png_color_16p bgnd;
|
||||
png_get_bKGD(png, info, &bgnd);
|
||||
png_set_background(png, bgnd, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
|
||||
}
|
||||
*/
|
||||
|
||||
if( !png_get_gAMA(png, info, &gamma))
|
||||
gamma = 1.0;
|
||||
|
||||
/* we're not displaying but converting, screen gamma == 1.0 */
|
||||
png_set_gamma(png, 1.0, gamma);
|
||||
|
||||
png_read_update_info(png, info);
|
||||
|
||||
color_type = png_get_color_type(png, info);
|
||||
|
||||
switch (color_type) {
|
||||
case PNG_COLOR_TYPE_GRAY:
|
||||
nr_comp = 1;
|
||||
break;
|
||||
case PNG_COLOR_TYPE_GRAY_ALPHA:
|
||||
nr_comp = 2;
|
||||
break;
|
||||
case PNG_COLOR_TYPE_RGB:
|
||||
nr_comp = 3;
|
||||
break;
|
||||
case PNG_COLOR_TYPE_RGB_ALPHA:
|
||||
nr_comp = 4;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"pngtoimage: colortype %d is not supported\n", color_type);
|
||||
goto fin;
|
||||
}
|
||||
cvtCxToPx = convert_32s_CXPX_LUT[nr_comp];
|
||||
bit_depth = png_get_bit_depth(png, info);
|
||||
|
||||
switch (bit_depth) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 8:
|
||||
cvtXXTo32s = convert_XXu32s_C1R_LUT[bit_depth];
|
||||
break;
|
||||
case 16: /* 16 bpp is specific to PNG */
|
||||
cvtXXTo32s = convert_16u32s_C1R;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"pngtoimage: bit depth %d is not supported\n", bit_depth);
|
||||
goto fin;
|
||||
}
|
||||
|
||||
|
||||
rows = (png_byte**)calloc(height+1, sizeof(png_byte*));
|
||||
for(i = 0; i < height; ++i)
|
||||
rows[i] = (png_byte*)malloc(png_get_rowbytes(png,info));
|
||||
|
||||
png_read_image(png, rows);
|
||||
|
||||
/* Create image */
|
||||
memset(cmptparm, 0, sizeof(cmptparm));
|
||||
for(i = 0; i < nr_comp; ++i)
|
||||
{
|
||||
cmptparm[i].prec = (png_uint_32)bit_depth;
|
||||
/* bits_per_pixel: 8 or 16 */
|
||||
cmptparm[i].bpp = (png_uint_32)bit_depth;
|
||||
cmptparm[i].sgnd = 0;
|
||||
cmptparm[i].dx = (png_uint_32)params->subsampling_dx;
|
||||
cmptparm[i].dy = (png_uint_32)params->subsampling_dy;
|
||||
cmptparm[i].w = (png_uint_32)width;
|
||||
cmptparm[i].h = (png_uint_32)height;
|
||||
}
|
||||
|
||||
image = opj_image_create(nr_comp, &cmptparm[0], (nr_comp > 2U) ? CLRSPC_SRGB : CLRSPC_GRAY);
|
||||
if(image == NULL) goto fin;
|
||||
image->x0 = (png_uint_32)params->image_offset_x0;
|
||||
image->y0 = (png_uint_32)params->image_offset_y0;
|
||||
image->x1 = (png_uint_32)(image->x0 + (width - 1) * (png_uint_32)params->subsampling_dx + 1 + image->x0);
|
||||
image->y1 = (png_uint_32)(image->y0 + (height - 1) * (png_uint_32)params->subsampling_dy + 1 + image->y0);
|
||||
|
||||
row32s = (png_int_32 *)malloc((size_t)width * nr_comp * sizeof(png_int_32));
|
||||
if(row32s == NULL) goto fin;
|
||||
|
||||
/* Set alpha channel */
|
||||
/* image->comps[nr_comp-1U].alpha = 1U - (nr_comp & 1U); */
|
||||
|
||||
for(i = 0; i < nr_comp; i++)
|
||||
{
|
||||
planes[i] = image->comps[i].data;
|
||||
}
|
||||
|
||||
for(i = 0; i < height; ++i)
|
||||
{
|
||||
cvtXXTo32s(rows[i], row32s, (size_t)width * nr_comp);
|
||||
cvtCxToPx(row32s, planes, width);
|
||||
planes[0] += width;
|
||||
planes[1] += width;
|
||||
planes[2] += width;
|
||||
planes[3] += width;
|
||||
}
|
||||
fin:
|
||||
if(rows)
|
||||
{
|
||||
for(i = 0; i < height; ++i)
|
||||
free(rows[i]);
|
||||
free(rows);
|
||||
}
|
||||
if (row32s) {
|
||||
free(row32s);
|
||||
}
|
||||
if(png)
|
||||
png_destroy_read_struct(&png, &info, NULL);
|
||||
|
||||
fclose(reader);
|
||||
|
||||
return image;
|
||||
|
||||
}/* pngtoimage() */
|
||||
|
||||
|
||||
static void convert_32s16u_C1R(const png_int_32* pSrc, png_byte* pDst, size_t length)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < length; i++) {
|
||||
png_uint_32 val = (png_uint_32)pSrc[i];
|
||||
*pDst++ = (png_byte)(val >> 8);
|
||||
*pDst++ = (png_byte)val;
|
||||
}
|
||||
}
|
||||
int imagetopng(opj_image_t * image, const char *write_idf)
|
||||
{
|
||||
FILE * volatile writer = NULL;
|
||||
png_structp png = NULL;
|
||||
png_infop info = NULL;
|
||||
png_bytep volatile row_buf = NULL;
|
||||
int nr_comp, color_type;
|
||||
volatile int prec;
|
||||
png_color_8 sig_bit;
|
||||
png_int_32 const* planes[4];
|
||||
int i;
|
||||
png_int_32* volatile buffer32s = NULL;
|
||||
|
||||
volatile int fails = 1;
|
||||
|
||||
memset(&sig_bit, 0, sizeof(sig_bit));
|
||||
prec = (int)image->comps[0].prec;
|
||||
planes[0] = image->comps[0].data;
|
||||
nr_comp = (int)image->numcomps;
|
||||
|
||||
if (nr_comp > 4) {
|
||||
nr_comp = 4;
|
||||
}
|
||||
for (i = 1; i < nr_comp; ++i) {
|
||||
if (image->comps[0].dx != image->comps[i].dx) {
|
||||
break;
|
||||
}
|
||||
if (image->comps[0].dy != image->comps[i].dy) {
|
||||
break;
|
||||
}
|
||||
if (image->comps[0].prec != image->comps[i].prec) {
|
||||
break;
|
||||
}
|
||||
if (image->comps[0].sgnd != image->comps[i].sgnd) {
|
||||
break;
|
||||
}
|
||||
planes[i] = image->comps[i].data;
|
||||
}
|
||||
if (i != nr_comp) {
|
||||
fprintf(stderr,"imagetopng: All components shall have the same subsampling, same bit depth, same sign.\n");
|
||||
fprintf(stderr,"\tAborting\n");
|
||||
return 1;
|
||||
}
|
||||
for (i = 0; i < nr_comp; ++i) {
|
||||
clip_component(&(image->comps[i]), image->comps[0].prec);
|
||||
}
|
||||
if(prec > 8 && prec < 16)
|
||||
{
|
||||
for (i = 0; i < nr_comp; ++i) {
|
||||
scale_component(&(image->comps[i]), 16);
|
||||
}
|
||||
prec = 16;
|
||||
}
|
||||
else if(prec < 8 && nr_comp > 1)/* GRAY_ALPHA, RGB, RGB_ALPHA */
|
||||
{
|
||||
for (i = 0; i < nr_comp; ++i) {
|
||||
scale_component(&(image->comps[i]), 8);
|
||||
}
|
||||
prec = 8;
|
||||
} else if((prec > 1) && (prec < 8) && ((prec == 6) || ((prec & 1)==1))) { /* GRAY with non native precision */
|
||||
if ((prec == 5) || (prec == 6)) {
|
||||
prec = 8;
|
||||
} else {
|
||||
prec++;
|
||||
}
|
||||
for (i = 0; i < nr_comp; ++i) {
|
||||
scale_component(&(image->comps[i]), (png_uint_32)prec);
|
||||
}
|
||||
}
|
||||
|
||||
if(prec != 1 && prec != 2 && prec != 4 && prec != 8 && prec != 16)
|
||||
{
|
||||
fprintf(stderr,"imagetopng: can not create %s\n\twrong bit_depth %d\n", write_idf, prec);
|
||||
return fails;
|
||||
}
|
||||
|
||||
writer = fopen(write_idf, "wb");
|
||||
|
||||
if(writer == NULL) return fails;
|
||||
|
||||
/* 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 = png_create_write_struct(PNG_LIBPNG_VER_STRING,
|
||||
NULL, NULL, NULL);
|
||||
/*png_voidp user_error_ptr, user_error_fn, user_warning_fn); */
|
||||
|
||||
if(png == NULL) goto fin;
|
||||
|
||||
/* Allocate/initialize the image information data. REQUIRED
|
||||
*/
|
||||
info = png_create_info_struct(png);
|
||||
|
||||
if(info == NULL) goto fin;
|
||||
|
||||
/* Set error handling. REQUIRED if you are not supplying your own
|
||||
* error handling functions in the png_create_write_struct() call.
|
||||
*/
|
||||
if(setjmp(png_jmpbuf(png))) goto fin;
|
||||
|
||||
/* I/O initialization functions is REQUIRED
|
||||
*/
|
||||
png_init_io(png, writer);
|
||||
|
||||
/* 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
|
||||
*
|
||||
* ERRORS:
|
||||
*
|
||||
* color_type == PNG_COLOR_TYPE_PALETTE && bit_depth > 8
|
||||
* color_type == PNG_COLOR_TYPE_RGB && bit_depth < 8
|
||||
* color_type == PNG_COLOR_TYPE_GRAY_ALPHA && bit_depth < 8
|
||||
* color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8
|
||||
*
|
||||
*/
|
||||
png_set_compression_level(png, Z_BEST_COMPRESSION);
|
||||
|
||||
if(nr_comp >= 3) /* RGB(A) */
|
||||
{
|
||||
color_type = PNG_COLOR_TYPE_RGB;
|
||||
sig_bit.red = sig_bit.green = sig_bit.blue = (png_byte)prec;
|
||||
}
|
||||
else /* GRAY(A) */
|
||||
{
|
||||
color_type = PNG_COLOR_TYPE_GRAY;
|
||||
sig_bit.gray = (png_byte)prec;
|
||||
}
|
||||
if((nr_comp & 1) == 0) /* ALPHA */
|
||||
{
|
||||
color_type |= PNG_COLOR_MASK_ALPHA;
|
||||
sig_bit.alpha = (png_byte)prec;
|
||||
}
|
||||
|
||||
png_set_IHDR(png, info, image->comps[0].w, image->comps[0].h, prec, color_type,
|
||||
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||
|
||||
png_set_sBIT(png, info, &sig_bit);
|
||||
/* png_set_gamma(png, 2.2, 1./2.2); */
|
||||
/* png_set_sRGB(png, info, PNG_sRGB_INTENT_PERCEPTUAL); */
|
||||
png_write_info(png, info);
|
||||
|
||||
/* setup conversion */
|
||||
{
|
||||
size_t rowStride;
|
||||
png_size_t png_row_size;
|
||||
|
||||
png_row_size = png_get_rowbytes(png, info);
|
||||
rowStride = ((size_t)image->comps[0].w * (size_t)nr_comp * (size_t)prec + 7U) / 8U;
|
||||
if (rowStride != (size_t)png_row_size) {
|
||||
fprintf(stderr, "Invalid PNG row size\n");
|
||||
goto fin;
|
||||
}
|
||||
row_buf = (png_bytep)malloc(png_row_size);
|
||||
if (row_buf == NULL) {
|
||||
fprintf(stderr, "Can't allocate memory for PNG row\n");
|
||||
goto fin;
|
||||
}
|
||||
buffer32s = (png_int_32*)malloc((size_t)image->comps[0].w * (size_t)nr_comp * sizeof(png_int_32));
|
||||
if (buffer32s == NULL) {
|
||||
fprintf(stderr, "Can't allocate memory for interleaved 32s row\n");
|
||||
goto fin;
|
||||
}
|
||||
}
|
||||
|
||||
/* convert */
|
||||
{
|
||||
size_t width= image->comps[0].w;
|
||||
int y;
|
||||
convert_32s_PXCX cvtPxToCx = convert_32s_PXCX_LUT[nr_comp];
|
||||
convert_32sXXx_C1R cvt32sToPack = NULL;
|
||||
png_int_32 adjust = image->comps[0].sgnd ? 1 << (prec - 1) : 0;
|
||||
png_bytep row_buf_cpy = row_buf;
|
||||
png_int_32* buffer32s_cpy = buffer32s;
|
||||
|
||||
switch (prec) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 8:
|
||||
cvt32sToPack = convert_32sXXu_C1R_LUT[prec];
|
||||
break;
|
||||
case 16:
|
||||
cvt32sToPack = convert_32s16u_C1R;
|
||||
break;
|
||||
default:
|
||||
/* never here */
|
||||
break;
|
||||
}
|
||||
|
||||
for(y = 0; y < image->comps[0].h; ++y)
|
||||
{
|
||||
cvtPxToCx(planes, buffer32s_cpy, width, adjust);
|
||||
cvt32sToPack(buffer32s_cpy, row_buf_cpy, width * (size_t)nr_comp);
|
||||
png_write_row(png, row_buf_cpy);
|
||||
planes[0] += width;
|
||||
planes[1] += width;
|
||||
planes[2] += width;
|
||||
planes[3] += width;
|
||||
}
|
||||
}
|
||||
|
||||
png_write_end(png, info);
|
||||
|
||||
fails = 0;
|
||||
|
||||
fin:
|
||||
if(png) {
|
||||
png_destroy_write_struct(&png, &info);
|
||||
}
|
||||
if(row_buf) {
|
||||
free(row_buf);
|
||||
}
|
||||
if(buffer32s) {
|
||||
free(buffer32s);
|
||||
}
|
||||
fclose(writer);
|
||||
|
||||
if(fails) (void)remove(write_idf); /* ignore return value */
|
||||
|
||||
return fails;
|
||||
}/* imagetopng() */
|
||||
633
applications/codec/converttif.c
Normal file
633
applications/codec/converttif.c
Normal file
@@ -0,0 +1,633 @@
|
||||
/*
|
||||
* The copyright in this software is being made available under the 2-clauses
|
||||
* BSD License, included below. This software may be subject to other third
|
||||
* party and contributor rights, including patent rights, and no such rights
|
||||
* are granted under this license.
|
||||
*
|
||||
* Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
|
||||
* Copyright (c) 2002-2014, Professor Benoit Macq
|
||||
* Copyright (c) 2001-2003, David Janssens
|
||||
* Copyright (c) 2002-2003, Yannick Verschueren
|
||||
* Copyright (c) 2003-2007, Francois-Olivier Devaux
|
||||
* Copyright (c) 2003-2014, Antonin Descampe
|
||||
* Copyright (c) 2005, Herve Drolon, FreeImage Team
|
||||
* Copyright (c) 2006-2007, Parvatha Elangovan
|
||||
* Copyright (c) 2015, Matthieu Darbois
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "opj_config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef HAVE_LIBTIFF
|
||||
# error HAVE_LIBTIFF_NOT_DEFINED
|
||||
#endif /* HAVE_LIBTIFF */
|
||||
|
||||
#include <tiffio.h>
|
||||
#include "openjpeg.h"
|
||||
#include "convert.h"
|
||||
|
||||
/* -->> -->> -->> -->>
|
||||
|
||||
TIFF IMAGE FORMAT
|
||||
|
||||
<<-- <<-- <<-- <<-- */
|
||||
|
||||
static void tif_32sto10u(const int32* pSrc, uint8* pDst, size_t length)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < (length & ~(size_t)3U); i+=4U) {
|
||||
uint32 src0 = (uint32)pSrc[i+0];
|
||||
uint32 src1 = (uint32)pSrc[i+1];
|
||||
uint32 src2 = (uint32)pSrc[i+2];
|
||||
uint32 src3 = (uint32)pSrc[i+3];
|
||||
|
||||
*pDst++ = (uint8)(src0 >> 2);
|
||||
*pDst++ = (uint8)(((src0 & 0x3U) << 6) | (src1 >> 4));
|
||||
*pDst++ = (uint8)(((src1 & 0xFU) << 4) | (src2 >> 6));
|
||||
*pDst++ = (uint8)(((src2 & 0x3FU) << 2) | (src3 >> 8));
|
||||
*pDst++ = (uint8)(src3);
|
||||
}
|
||||
|
||||
if (length & 3U) {
|
||||
uint32 src0 = (uint32)pSrc[i+0];
|
||||
uint32 src1 = 0U;
|
||||
uint32 src2 = 0U;
|
||||
length = length & 3U;
|
||||
|
||||
if (length > 1U) {
|
||||
src1 = (uint32)pSrc[i+1];
|
||||
if (length > 2U) {
|
||||
src2 = (uint32)pSrc[i+2];
|
||||
}
|
||||
}
|
||||
*pDst++ = (uint8)(src0 >> 2);
|
||||
*pDst++ = (uint8)(((src0 & 0x3U) << 6) | (src1 >> 4));
|
||||
if (length > 1U) {
|
||||
*pDst++ = (uint8)(((src1 & 0xFU) << 4) | (src2 >> 6));
|
||||
if (length > 2U) {
|
||||
*pDst++ = (uint8)(((src2 & 0x3FU) << 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
static void tif_32sto12u(const int32* pSrc, uint8* pDst, size_t length)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < (length & ~(size_t)1U); i+=2U) {
|
||||
uint32 src0 = (uint32)pSrc[i+0];
|
||||
uint32 src1 = (uint32)pSrc[i+1];
|
||||
|
||||
*pDst++ = (uint8)(src0 >> 4);
|
||||
*pDst++ = (uint8)(((src0 & 0xFU) << 4) | (src1 >> 8));
|
||||
*pDst++ = (uint8)(src1);
|
||||
}
|
||||
|
||||
if (length & 1U) {
|
||||
uint32 src0 = (uint32)pSrc[i+0];
|
||||
*pDst++ = (uint8)(src0 >> 4);
|
||||
*pDst++ = (uint8)(((src0 & 0xFU) << 4));
|
||||
}
|
||||
}
|
||||
static void tif_32sto14u(const int32* pSrc, uint8* pDst, size_t length)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < (length & ~(size_t)3U); i+=4U) {
|
||||
uint32 src0 = (uint32)pSrc[i+0];
|
||||
uint32 src1 = (uint32)pSrc[i+1];
|
||||
uint32 src2 = (uint32)pSrc[i+2];
|
||||
uint32 src3 = (uint32)pSrc[i+3];
|
||||
|
||||
*pDst++ = (uint8)(src0 >> 6);
|
||||
*pDst++ = (uint8)(((src0 & 0x3FU) << 2) | (src1 >> 12));
|
||||
*pDst++ = (uint8)(src1 >> 4);
|
||||
*pDst++ = (uint8)(((src1 & 0xFU) << 4) | (src2 >> 10));
|
||||
*pDst++ = (uint8)(src2 >> 2);
|
||||
*pDst++ = (uint8)(((src2 & 0x3U) << 6) | (src3 >> 8));
|
||||
*pDst++ = (uint8)(src3);
|
||||
}
|
||||
|
||||
if (length & 3U) {
|
||||
uint32 src0 = (uint32)pSrc[i+0];
|
||||
uint32 src1 = 0U;
|
||||
uint32 src2 = 0U;
|
||||
length = length & 3U;
|
||||
|
||||
if (length > 1U) {
|
||||
src1 = (uint32)pSrc[i+1];
|
||||
if (length > 2U) {
|
||||
src2 = (uint32)pSrc[i+2];
|
||||
}
|
||||
}
|
||||
*pDst++ = (uint8)(src0 >> 6);
|
||||
*pDst++ = (uint8)(((src0 & 0x3FU) << 2) | (src1 >> 12));
|
||||
if (length > 1U) {
|
||||
*pDst++ = (uint8)(src1 >> 4);
|
||||
*pDst++ = (uint8)(((src1 & 0xFU) << 4) | (src2 >> 10));
|
||||
if (length > 2U) {
|
||||
*pDst++ = (uint8)(src2 >> 2);
|
||||
*pDst++ = (uint8)(((src2 & 0x3U) << 6));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
static void tif_32sto16u(const int32* pSrc, uint16* pDst, size_t length)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < length; ++i) {
|
||||
pDst[i] = (uint16)pSrc[i];
|
||||
}
|
||||
}
|
||||
|
||||
int imagetotif(opj_image_t * image, const char *outfile)
|
||||
{
|
||||
int width, height;
|
||||
int bps,adjust, sgnd;
|
||||
int tiPhoto;
|
||||
TIFF *tif;
|
||||
tdata_t buf;
|
||||
tsize_t strip_size;
|
||||
int32 i, numcomps;
|
||||
size_t rowStride;
|
||||
int32* buffer32s = NULL;
|
||||
int32 const* planes[4];
|
||||
convert_32s_PXCX cvtPxToCx = NULL;
|
||||
convert_32sXXx_C1R cvt32sToTif = NULL;
|
||||
|
||||
bps = image->comps[0].prec;
|
||||
planes[0] = image->comps[0].data;
|
||||
|
||||
numcomps = image->numcomps;
|
||||
|
||||
if (numcomps > 2) {
|
||||
tiPhoto = PHOTOMETRIC_RGB;
|
||||
if (numcomps > 4) {
|
||||
numcomps = 4;
|
||||
}
|
||||
} else {
|
||||
tiPhoto = PHOTOMETRIC_MINISBLACK;
|
||||
}
|
||||
for (i = 1; i < numcomps; ++i) {
|
||||
if (image->comps[0].dx != image->comps[i].dx) {
|
||||
break;
|
||||
}
|
||||
if (image->comps[0].dy != image->comps[i].dy) {
|
||||
break;
|
||||
}
|
||||
if (image->comps[0].prec != image->comps[i].prec) {
|
||||
break;
|
||||
}
|
||||
if (image->comps[0].sgnd != image->comps[i].sgnd) {
|
||||
break;
|
||||
}
|
||||
planes[i] = image->comps[i].data;
|
||||
}
|
||||
if (i != numcomps) {
|
||||
fprintf(stderr,"imagetotif: All components shall have the same subsampling, same bit depth.\n");
|
||||
fprintf(stderr,"\tAborting\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if((bps > 16) || ((bps != 1) && (bps & 1))) bps = 0;
|
||||
if(bps == 0)
|
||||
{
|
||||
fprintf(stderr,"imagetotif: Bits=%d, Only 1, 2, 4, 6, 8, 10, 12, 14 and 16 bits implemented\n",bps);
|
||||
fprintf(stderr,"\tAborting\n");
|
||||
return 1;
|
||||
}
|
||||
tif = TIFFOpen(outfile, "wb");
|
||||
if (!tif)
|
||||
{
|
||||
fprintf(stderr, "imagetotif:failed to open %s for writing\n", outfile);
|
||||
return 1;
|
||||
}
|
||||
for (i = 0; i < numcomps; ++i) {
|
||||
clip_component(&(image->comps[i]), image->comps[0].prec);
|
||||
}
|
||||
cvtPxToCx = convert_32s_PXCX_LUT[numcomps];
|
||||
switch (bps) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 6:
|
||||
case 8:
|
||||
cvt32sToTif = convert_32sXXu_C1R_LUT[bps];
|
||||
break;
|
||||
case 10:
|
||||
cvt32sToTif = tif_32sto10u;
|
||||
break;
|
||||
case 12:
|
||||
cvt32sToTif = tif_32sto12u;
|
||||
break;
|
||||
case 14:
|
||||
cvt32sToTif = tif_32sto14u;
|
||||
break;
|
||||
case 16:
|
||||
cvt32sToTif = (convert_32sXXx_C1R)tif_32sto16u;
|
||||
break;
|
||||
default:
|
||||
/* never here */
|
||||
break;
|
||||
}
|
||||
sgnd = (int)image->comps[0].sgnd;
|
||||
adjust = sgnd ? 1 << (image->comps[0].prec - 1) : 0;
|
||||
width = (int)image->comps[0].w;
|
||||
height = (int)image->comps[0].h;
|
||||
|
||||
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
|
||||
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
|
||||
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, numcomps);
|
||||
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
|
||||
TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
|
||||
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
|
||||
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, tiPhoto);
|
||||
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
|
||||
|
||||
strip_size = TIFFStripSize(tif);
|
||||
rowStride = ((size_t)width * numcomps * (size_t)bps + 7U) / 8U;
|
||||
if (rowStride != (size_t)strip_size) {
|
||||
fprintf(stderr, "Invalid TIFF strip size\n");
|
||||
TIFFClose(tif);
|
||||
return 1;
|
||||
}
|
||||
buf = _TIFFmalloc(strip_size);
|
||||
if (buf == NULL) {
|
||||
TIFFClose(tif);
|
||||
return 1;
|
||||
}
|
||||
buffer32s = (int32 *)malloc((size_t)width * numcomps * sizeof(int32));
|
||||
if (buffer32s == NULL) {
|
||||
_TIFFfree(buf);
|
||||
TIFFClose(tif);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < image->comps[0].h; ++i) {
|
||||
cvtPxToCx(planes, buffer32s, (size_t)width, adjust);
|
||||
cvt32sToTif(buffer32s, (uint8 *)buf, (size_t)width * numcomps);
|
||||
(void)TIFFWriteEncodedStrip(tif, i, (void*)buf, strip_size);
|
||||
planes[0] += width;
|
||||
planes[1] += width;
|
||||
planes[2] += width;
|
||||
planes[3] += width;
|
||||
}
|
||||
_TIFFfree((void*)buf);
|
||||
TIFFClose(tif);
|
||||
free(buffer32s);
|
||||
|
||||
return 0;
|
||||
}/* imagetotif() */
|
||||
|
||||
static void tif_10uto32s(const uint8* pSrc, int32* pDst, size_t length)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < (length & ~(size_t)3U); i+=4U) {
|
||||
uint32 val0 = *pSrc++;
|
||||
uint32 val1 = *pSrc++;
|
||||
uint32 val2 = *pSrc++;
|
||||
uint32 val3 = *pSrc++;
|
||||
uint32 val4 = *pSrc++;
|
||||
|
||||
pDst[i+0] = (int32)((val0 << 2) | (val1 >> 6));
|
||||
pDst[i+1] = (int32)(((val1 & 0x3FU) << 4) | (val2 >> 4));
|
||||
pDst[i+2] = (int32)(((val2 & 0xFU) << 6) | (val3 >> 2));
|
||||
pDst[i+3] = (int32)(((val3 & 0x3U) << 8) | val4);
|
||||
|
||||
}
|
||||
if (length & 3U) {
|
||||
uint32 val0 = *pSrc++;
|
||||
uint32 val1 = *pSrc++;
|
||||
length = length & 3U;
|
||||
pDst[i+0] = (int32)((val0 << 2) | (val1 >> 6));
|
||||
|
||||
if (length > 1U) {
|
||||
uint32 val2 = *pSrc++;
|
||||
pDst[i+1] = (int32)(((val1 & 0x3FU) << 4) | (val2 >> 4));
|
||||
if (length > 2U) {
|
||||
uint32 val3 = *pSrc++;
|
||||
pDst[i+2] = (int32)(((val2 & 0xFU) << 6) | (val3 >> 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
static void tif_12uto32s(const uint8* pSrc, int32* pDst, size_t length)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < (length & ~(size_t)1U); i+=2U) {
|
||||
uint32 val0 = *pSrc++;
|
||||
uint32 val1 = *pSrc++;
|
||||
uint32 val2 = *pSrc++;
|
||||
|
||||
pDst[i+0] = (int32)((val0 << 4) | (val1 >> 4));
|
||||
pDst[i+1] = (int32)(((val1 & 0xFU) << 8) | val2);
|
||||
}
|
||||
if (length & 1U) {
|
||||
uint32 val0 = *pSrc++;
|
||||
uint32 val1 = *pSrc++;
|
||||
pDst[i+0] = (int32)((val0 << 4) | (val1 >> 4));
|
||||
}
|
||||
}
|
||||
static void tif_14uto32s(const uint8* pSrc, int32* pDst, size_t length)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < (length & ~(size_t)3U); i+=4U) {
|
||||
uint32 val0 = *pSrc++;
|
||||
uint32 val1 = *pSrc++;
|
||||
uint32 val2 = *pSrc++;
|
||||
uint32 val3 = *pSrc++;
|
||||
uint32 val4 = *pSrc++;
|
||||
uint32 val5 = *pSrc++;
|
||||
uint32 val6 = *pSrc++;
|
||||
|
||||
pDst[i+0] = (int32)((val0 << 6) | (val1 >> 2));
|
||||
pDst[i+1] = (int32)(((val1 & 0x3U) << 12) | (val2 << 4) | (val3 >> 4));
|
||||
pDst[i+2] = (int32)(((val3 & 0xFU) << 10) | (val4 << 2) | (val5 >> 6));
|
||||
pDst[i+3] = (int32)(((val5 & 0x3FU) << 8) | val6);
|
||||
|
||||
}
|
||||
if (length & 3U) {
|
||||
uint32 val0 = *pSrc++;
|
||||
uint32 val1 = *pSrc++;
|
||||
length = length & 3U;
|
||||
pDst[i+0] = (int32)((val0 << 6) | (val1 >> 2));
|
||||
|
||||
if (length > 1U) {
|
||||
uint32 val2 = *pSrc++;
|
||||
uint32 val3 = *pSrc++;
|
||||
pDst[i+1] = (int32)(((val1 & 0x3U) << 12) | (val2 << 4) | (val3 >> 4));
|
||||
if (length > 2U) {
|
||||
uint32 val4 = *pSrc++;
|
||||
uint32 val5 = *pSrc++;
|
||||
pDst[i+2] = (int32)(((val3 & 0xFU) << 10) | (val4 << 2) | (val5 >> 6));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* seems that libtiff decodes this to machine endianness */
|
||||
static void tif_16uto32s(const uint16* pSrc, int32* pDst, size_t length)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < length; i++) {
|
||||
pDst[i] = pSrc[i];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* libtiff/tif_getimage.c : 1,2,4,8,16 bitspersample accepted
|
||||
* CINEMA : 12 bit precision
|
||||
*/
|
||||
opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters)
|
||||
{
|
||||
int subsampling_dx = parameters->subsampling_dx;
|
||||
int subsampling_dy = parameters->subsampling_dy;
|
||||
TIFF *tif;
|
||||
tdata_t buf;
|
||||
tstrip_t strip;
|
||||
tsize_t strip_size;
|
||||
int j, currentPlane, numcomps = 0, w, h;
|
||||
OPJ_COLOR_SPACE color_space = CLRSPC_UNKNOWN;
|
||||
opj_image_cmptparm_t cmptparm[4]; /* RGBA */
|
||||
opj_image_t *image = NULL;
|
||||
int has_alpha = 0;
|
||||
unsigned short tiBps, tiPhoto, tiSf, tiSpp, tiPC;
|
||||
unsigned int tiWidth, tiHeight;
|
||||
opj_bool is_cinema = (parameters->cp_cinema != OFF) ? OPJ_TRUE : OPJ_FALSE;
|
||||
convert_XXx32s_C1R cvtTifTo32s = NULL;
|
||||
convert_32s_CXPX cvtCxToPx = NULL;
|
||||
int32* buffer32s = NULL;
|
||||
int32* planes[4];
|
||||
size_t rowStride;
|
||||
|
||||
tif = TIFFOpen(filename, "r");
|
||||
|
||||
if(!tif)
|
||||
{
|
||||
fprintf(stderr, "tiftoimage:Failed to open %s for reading\n", filename);
|
||||
return 0;
|
||||
}
|
||||
tiBps = tiPhoto = tiSf = tiSpp = tiPC = 0;
|
||||
tiWidth = tiHeight = 0;
|
||||
|
||||
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &tiWidth);
|
||||
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &tiHeight);
|
||||
TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &tiBps);
|
||||
TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &tiSf);
|
||||
TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &tiSpp);
|
||||
TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &tiPhoto);
|
||||
TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &tiPC);
|
||||
w= (int)tiWidth;
|
||||
h= (int)tiHeight;
|
||||
|
||||
if((tiBps > 16U) || ((tiBps != 1U) && (tiBps & 1U))) {
|
||||
fprintf(stderr,"tiftoimage: Bits=%d, Only 1, 2, 4, 6, 8, 10, 12, 14 and 16 bits implemented\n",tiBps);
|
||||
fprintf(stderr,"\tAborting\n");
|
||||
TIFFClose(tif);
|
||||
return NULL;
|
||||
}
|
||||
if(tiPhoto != PHOTOMETRIC_MINISBLACK && tiPhoto != PHOTOMETRIC_RGB) {
|
||||
fprintf(stderr,"tiftoimage: Bad color format %d.\n\tOnly RGB(A) and GRAY(A) has been implemented\n",(int) tiPhoto);
|
||||
fprintf(stderr,"\tAborting\n");
|
||||
TIFFClose(tif);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (tiBps) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 6:
|
||||
case 8:
|
||||
cvtTifTo32s = convert_XXu32s_C1R_LUT[tiBps];
|
||||
break;
|
||||
/* others are specific to TIFF */
|
||||
case 10:
|
||||
cvtTifTo32s = tif_10uto32s;
|
||||
break;
|
||||
case 12:
|
||||
cvtTifTo32s = tif_12uto32s;
|
||||
break;
|
||||
case 14:
|
||||
cvtTifTo32s = tif_14uto32s;
|
||||
break;
|
||||
case 16:
|
||||
cvtTifTo32s = (convert_XXx32s_C1R)tif_16uto32s;
|
||||
break;
|
||||
default:
|
||||
/* never here */
|
||||
break;
|
||||
}
|
||||
|
||||
{/* From: tiff-4.0.x/libtiff/tif_getimage.c : */
|
||||
uint16* sampleinfo;
|
||||
uint16 extrasamples;
|
||||
|
||||
TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
|
||||
&extrasamples, &sampleinfo);
|
||||
|
||||
if(extrasamples >= 1)
|
||||
{
|
||||
switch(sampleinfo[0])
|
||||
{
|
||||
case EXTRASAMPLE_UNSPECIFIED:
|
||||
/* Workaround for some images without correct info about alpha channel
|
||||
*/
|
||||
if(tiSpp > 3)
|
||||
has_alpha = 1;
|
||||
break;
|
||||
|
||||
case EXTRASAMPLE_ASSOCALPHA: /* data pre-multiplied */
|
||||
case EXTRASAMPLE_UNASSALPHA: /* data not pre-multiplied */
|
||||
has_alpha = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else /* extrasamples == 0 */
|
||||
if(tiSpp == 4 || tiSpp == 2) has_alpha = 1;
|
||||
}
|
||||
|
||||
/* initialize image components */
|
||||
memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t));
|
||||
|
||||
if ((tiPhoto == PHOTOMETRIC_RGB) && (is_cinema) && (tiBps != 12U)) {
|
||||
fprintf(stdout,"WARNING:\n"
|
||||
"Input image bitdepth is %d bits\n"
|
||||
"TIF conversion has automatically rescaled to 12-bits\n"
|
||||
"to comply with cinema profiles.\n",
|
||||
tiBps);
|
||||
} else {
|
||||
is_cinema = 0U;
|
||||
}
|
||||
|
||||
if(tiPhoto == PHOTOMETRIC_RGB) /* RGB(A) */
|
||||
{
|
||||
numcomps = 3 + has_alpha;
|
||||
color_space = CLRSPC_SRGB;
|
||||
}
|
||||
else if (tiPhoto == PHOTOMETRIC_MINISBLACK) /* GRAY(A) */
|
||||
{
|
||||
numcomps = 1 + has_alpha;
|
||||
color_space = CLRSPC_GRAY;
|
||||
}
|
||||
|
||||
cvtCxToPx = convert_32s_CXPX_LUT[numcomps];
|
||||
if (tiPC == PLANARCONFIG_SEPARATE) {
|
||||
cvtCxToPx = convert_32s_CXPX_LUT[1]; /* override */
|
||||
tiSpp = 1U; /* consider only one sample per plane */
|
||||
}
|
||||
|
||||
for(j = 0; j < numcomps; j++)
|
||||
{
|
||||
cmptparm[j].prec = tiBps;
|
||||
cmptparm[j].bpp = tiBps;
|
||||
cmptparm[j].dx = (uint32)subsampling_dx;
|
||||
cmptparm[j].dy = (uint32)subsampling_dy;
|
||||
cmptparm[j].w = (uint32)w;
|
||||
cmptparm[j].h = (uint32)h;
|
||||
}
|
||||
|
||||
image = opj_image_create((uint32)numcomps, &cmptparm[0], color_space);
|
||||
if(!image)
|
||||
{
|
||||
TIFFClose(tif);
|
||||
return NULL;
|
||||
}
|
||||
/* set image offset and reference grid */
|
||||
image->x0 = (uint32)parameters->image_offset_x0;
|
||||
image->y0 = (uint32)parameters->image_offset_y0;
|
||||
image->x1 = !image->x0 ? (uint32)(w - 1) * (uint32)subsampling_dx + 1 :
|
||||
image->x0 + (uint32)(w - 1) * (uint32)subsampling_dx + 1;
|
||||
image->y1 = !image->y0 ? (uint32)(h - 1) * (uint32)subsampling_dy + 1 :
|
||||
image->y0 + (uint32)(h - 1) * (uint32)subsampling_dy + 1;
|
||||
|
||||
for(j = 0; j < numcomps; j++)
|
||||
{
|
||||
planes[j] = image->comps[j].data;
|
||||
}
|
||||
/* image->comps[numcomps - 1].alpha = (uint16)(1 - (numcomps & 1)); */
|
||||
|
||||
strip_size = TIFFStripSize(tif);
|
||||
|
||||
buf = _TIFFmalloc(strip_size);
|
||||
if (buf == NULL) {
|
||||
TIFFClose(tif);
|
||||
opj_image_destroy(image);
|
||||
return NULL;
|
||||
}
|
||||
rowStride = ((size_t)w * tiSpp * tiBps + 7U) / 8U;
|
||||
buffer32s = (int32 *)malloc((size_t)w * tiSpp * sizeof(int32));
|
||||
if (buffer32s == NULL) {
|
||||
_TIFFfree(buf);
|
||||
TIFFClose(tif);
|
||||
opj_image_destroy(image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strip = 0;
|
||||
currentPlane = 0;
|
||||
do
|
||||
{
|
||||
planes[0] = image->comps[currentPlane].data; /* to manage planar data */
|
||||
h= (int)tiHeight;
|
||||
/* Read the Image components */
|
||||
for(; (h > 0) && (strip < TIFFNumberOfStrips(tif)); strip++)
|
||||
{
|
||||
const uint8 *dat8;
|
||||
size_t ssize;
|
||||
|
||||
ssize = (size_t)TIFFReadEncodedStrip(tif, strip, buf, strip_size);
|
||||
dat8 = (const uint8*)buf;
|
||||
|
||||
while (ssize >= rowStride) {
|
||||
cvtTifTo32s(dat8, buffer32s, (size_t)w * tiSpp);
|
||||
cvtCxToPx(buffer32s, planes, (size_t)w);
|
||||
planes[0] += w;
|
||||
planes[1] += w;
|
||||
planes[2] += w;
|
||||
planes[3] += w;
|
||||
dat8 += rowStride;
|
||||
ssize -= rowStride;
|
||||
h--;
|
||||
}
|
||||
}
|
||||
currentPlane++;
|
||||
} while ((tiPC == PLANARCONFIG_SEPARATE) && (currentPlane < numcomps));
|
||||
|
||||
free(buffer32s);
|
||||
_TIFFfree(buf);
|
||||
TIFFClose(tif);
|
||||
|
||||
if (is_cinema) {
|
||||
for (j=0; j < numcomps; ++j) {
|
||||
scale_component(&(image->comps[j]), 12);
|
||||
}
|
||||
|
||||
}
|
||||
return image;
|
||||
|
||||
}/* tiftoimage() */
|
||||
|
||||
@@ -591,7 +591,9 @@ static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *param
|
||||
{"POC",REQ_ARG, NULL ,'P'},
|
||||
{"ROI",REQ_ARG, NULL ,'R'},
|
||||
{"jpip",NO_ARG, NULL, 'J'},
|
||||
{0,0,0,0} /* GNU getopt_long requirement */
|
||||
#ifdef USE_SYSTEM_GETOPT
|
||||
{0,0,0,0} /* GNU getopt_long requirement */
|
||||
#endif
|
||||
};
|
||||
|
||||
/* parse the command line */
|
||||
@@ -601,7 +603,7 @@ static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *param
|
||||
#endif /* USE_JPWL */
|
||||
"h";
|
||||
|
||||
totlen=sizeof(long_option)-1;
|
||||
totlen=sizeof(long_option);
|
||||
img_fol->set_out_format=0;
|
||||
raw_cp->rawWidth = 0;
|
||||
|
||||
@@ -1391,10 +1393,10 @@ static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *param
|
||||
/* ------------------------------------------------------ */
|
||||
|
||||
|
||||
default:
|
||||
fprintf(stderr, "ERROR -> Command line not valid\n");
|
||||
return 1;
|
||||
}
|
||||
default:
|
||||
fprintf(stderr, "[WARNING] An invalid option has been ignored\n");
|
||||
break;
|
||||
}
|
||||
}while(c != -1);
|
||||
|
||||
/* check for possible errors */
|
||||
|
||||
@@ -201,13 +201,15 @@ int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,i
|
||||
int totlen, c;
|
||||
opj_option_t long_option[]={
|
||||
{"ImgDir",REQ_ARG, NULL ,'y'},
|
||||
#ifdef USE_SYSTEM_GETOPT
|
||||
{0,0,0,0} /* GNU getopt_long requirement */
|
||||
#endif
|
||||
};
|
||||
const char optlist[] = "i:o:h";
|
||||
|
||||
OPJ_ARG_NOT_USED(indexfilename);
|
||||
|
||||
totlen=sizeof(long_option)-1;
|
||||
totlen=sizeof(long_option);
|
||||
img_fol->set_out_format = 0;
|
||||
do {
|
||||
#ifdef USE_SYSTEM_GETOPT
|
||||
@@ -265,7 +267,7 @@ int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,i
|
||||
/* ----------------------------------------------------- */
|
||||
|
||||
default:
|
||||
fprintf(stderr,"WARNING -> this option is not valid \"-%c %s\"\n",c, opj_optarg);
|
||||
fprintf(stderr,"[WARNING] An invalid option has been ignored\n");
|
||||
break;
|
||||
}
|
||||
}while(c != -1);
|
||||
@@ -357,6 +359,11 @@ int main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* j2k_dump focuses on j2k codestream and skips JP2 boxes */
|
||||
parameters.flags = 1;
|
||||
/* j2k_dump shall not actually decode packets (parsing codestream is enough). */
|
||||
parameters.cp_limit_decoding = DECODE_ALL_BUT_PACKETS;
|
||||
|
||||
/* Initialize reading of directory */
|
||||
if(img_fol.set_imgdir==1){
|
||||
num_images=get_num_images(img_fol.imgdirpath);
|
||||
@@ -452,7 +459,7 @@ int main(int argc, char *argv[])
|
||||
cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
|
||||
|
||||
/* decode the stream and fill the image structure */
|
||||
if (*indexfilename) /* If need to extract codestream information*/
|
||||
if (*indexfilename) /* If need to extract codestream information*/
|
||||
image = opj_decode_with_info(dinfo, cio, &cstr_info);
|
||||
else
|
||||
image = opj_decode(dinfo, cio);
|
||||
@@ -501,7 +508,7 @@ int main(int argc, char *argv[])
|
||||
cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
|
||||
|
||||
/* decode the stream and fill the image structure */
|
||||
if (*indexfilename) /* If need to extract codestream information*/
|
||||
if (*indexfilename) /* If need to extract codestream information*/
|
||||
image = opj_decode_with_info(dinfo, cio, &cstr_info);
|
||||
else
|
||||
image = opj_decode(dinfo, cio);
|
||||
|
||||
@@ -85,6 +85,40 @@ typedef struct img_folder{
|
||||
|
||||
}img_fol_t;
|
||||
|
||||
typedef enum opj_prec_mode
|
||||
{
|
||||
OPJ_PREC_MODE_CLIP,
|
||||
OPJ_PREC_MODE_SCALE
|
||||
} opj_precision_mode;
|
||||
|
||||
typedef struct opj_prec
|
||||
{
|
||||
int prec;
|
||||
opj_precision_mode mode;
|
||||
}opj_precision;
|
||||
|
||||
typedef struct opj_decompress_params
|
||||
{
|
||||
/** core library parameters */
|
||||
opj_dparameters_t core;
|
||||
|
||||
/** input file name */
|
||||
char infile[OPJ_PATH_LEN];
|
||||
/** output file name */
|
||||
char outfile[OPJ_PATH_LEN];
|
||||
/** input file format 0: J2K, 1: JP2, 2: JPT */
|
||||
int decod_format;
|
||||
/** output file format 0: PGX, 1: PxM, 2: BMP */
|
||||
int cod_format;
|
||||
|
||||
opj_precision* precision;
|
||||
int nb_precision;
|
||||
/* force output colorspace to RGB */
|
||||
int force_rgb;
|
||||
/* upsample components according to their dx/dy values */
|
||||
int upsample;
|
||||
}opj_decompress_parameters;
|
||||
|
||||
static void decode_help_display(void) {
|
||||
fprintf(stdout,"HELP for j2k_to_image\n----\n\n");
|
||||
fprintf(stdout,"- the -h option displays this help information on screen\n\n");
|
||||
@@ -128,6 +162,18 @@ static void decode_help_display(void) {
|
||||
fprintf(stdout," are decoded.\n");
|
||||
fprintf(stdout," -x \n");
|
||||
fprintf(stdout," Create an index file *.Idx (-x index_name.Idx) \n");
|
||||
fprintf(stdout," -p <comp 0 precision>[C|S][,<comp 1 precision>[C|S][,...]]\n");
|
||||
fprintf(stdout," OPTIONAL\n");
|
||||
fprintf(stdout," Force the precision (bit depth) of components.\n");
|
||||
fprintf(stdout," There shall be at least 1 value. Theres no limit on the number of values (comma separated, last values ignored if too much values).\n");
|
||||
fprintf(stdout," If there are less values than components, the last value is used for remaining components.\n");
|
||||
fprintf(stdout," If 'C' is specified (default), values are clipped.\n");
|
||||
fprintf(stdout," If 'S' is specified, values are scaled.\n");
|
||||
fprintf(stdout," A 0 value can be specified (meaning original bit depth).\n");
|
||||
fprintf(stdout," -force-rgb\n");
|
||||
fprintf(stdout," Force output image colorspace to RGB\n");
|
||||
fprintf(stdout," -upsample\n");
|
||||
fprintf(stdout," Downsampled components will be upsampled to image size\n");
|
||||
fprintf(stdout,"\n");
|
||||
/* UniPG>> */
|
||||
#ifdef USE_JPWL
|
||||
@@ -144,6 +190,111 @@ static void decode_help_display(void) {
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static opj_bool parse_precision(const char* option, opj_decompress_parameters* parameters)
|
||||
{
|
||||
const char* l_remaining = option;
|
||||
opj_bool l_result = OPJ_TRUE;
|
||||
|
||||
/* reset */
|
||||
if (parameters->precision) {
|
||||
free(parameters->precision);
|
||||
parameters->precision = NULL;
|
||||
}
|
||||
parameters->nb_precision = 0U;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
int prec;
|
||||
char mode;
|
||||
char comma;
|
||||
int count;
|
||||
|
||||
count = sscanf(l_remaining, "%d%c%c", &prec, &mode, &comma);
|
||||
if (count == 1) {
|
||||
mode = 'C';
|
||||
count++;
|
||||
}
|
||||
if ((count == 2) || (mode==',')) {
|
||||
if (mode==',') {
|
||||
mode = 'C';
|
||||
}
|
||||
comma=',';
|
||||
count = 3;
|
||||
}
|
||||
if (count == 3) {
|
||||
if ((prec < 1) || (prec > 32)) {
|
||||
fprintf(stderr,"Invalid precision %d in precision option %s\n", prec, option);
|
||||
l_result = OPJ_FALSE;
|
||||
break;
|
||||
}
|
||||
if ((mode != 'C') && (mode != 'S')) {
|
||||
fprintf(stderr,"Invalid precision mode %c in precision option %s\n", mode, option);
|
||||
l_result = OPJ_FALSE;
|
||||
break;
|
||||
}
|
||||
if (comma != ',') {
|
||||
fprintf(stderr,"Invalid character %c in precision option %s\n", comma, option);
|
||||
l_result = OPJ_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (parameters->precision == NULL) {
|
||||
/* first one */
|
||||
parameters->precision = (opj_precision *)malloc(sizeof(opj_precision));
|
||||
if (parameters->precision == NULL) {
|
||||
fprintf(stderr,"Could not allocate memory for precision option\n");
|
||||
l_result = OPJ_FALSE;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
int l_new_size = parameters->nb_precision + 1U;
|
||||
opj_precision* l_new;
|
||||
|
||||
if (l_new_size == 0U) {
|
||||
fprintf(stderr,"Could not allocate memory for precision option\n");
|
||||
l_result = OPJ_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
l_new = (opj_precision *)realloc(parameters->precision, l_new_size * sizeof(opj_precision));
|
||||
if (l_new == NULL) {
|
||||
fprintf(stderr,"Could not allocate memory for precision option\n");
|
||||
l_result = OPJ_FALSE;
|
||||
break;
|
||||
}
|
||||
parameters->precision = l_new;
|
||||
}
|
||||
|
||||
parameters->precision[parameters->nb_precision].prec = prec;
|
||||
switch (mode) {
|
||||
case 'C':
|
||||
parameters->precision[parameters->nb_precision].mode = OPJ_PREC_MODE_CLIP;
|
||||
break;
|
||||
case 'S':
|
||||
parameters->precision[parameters->nb_precision].mode = OPJ_PREC_MODE_SCALE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
parameters->nb_precision++;
|
||||
|
||||
l_remaining = strchr(l_remaining, ',');
|
||||
if (l_remaining == NULL) {
|
||||
break;
|
||||
}
|
||||
l_remaining += 1;
|
||||
} else {
|
||||
fprintf(stderr,"Could not parse precision option %s\n", option);
|
||||
l_result = OPJ_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return l_result;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static int get_num_images(char *imgdirpath){
|
||||
DIR *dir;
|
||||
struct dirent* content;
|
||||
@@ -211,7 +362,7 @@ static int get_file_format(char *filename) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
static char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_dparameters_t *parameters){
|
||||
static char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_decompress_parameters *parameters){
|
||||
char image_filename[OPJ_PATH_LEN], infilename[OPJ_PATH_LEN],outfilename[OPJ_PATH_LEN],temp_ofname[OPJ_PATH_LEN];
|
||||
char *temp_p, temp1[OPJ_PATH_LEN]="";
|
||||
|
||||
@@ -237,16 +388,20 @@ static char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_d
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
static int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,img_fol_t *img_fol, char *indexfilename) {
|
||||
static int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *parameters,img_fol_t *img_fol, char *indexfilename) {
|
||||
/* parse the command line */
|
||||
int totlen, c;
|
||||
opj_option_t long_option[]={
|
||||
{"ImgDir",REQ_ARG, NULL ,'y'},
|
||||
{"OutFor",REQ_ARG, NULL ,'O'},
|
||||
{"force-rgb", NO_ARG, NULL, 1},
|
||||
{"upsample", NO_ARG, NULL, 1},
|
||||
#ifdef USE_SYSTEM_GETOPT
|
||||
{0,0,0,0} /* GNU getopt_long requirement */
|
||||
#endif
|
||||
};
|
||||
|
||||
const char optlist[] = "i:o:r:l:x:"
|
||||
const char optlist[] = "i:o:r:l:x:p:"
|
||||
|
||||
/* UniPG>> */
|
||||
#ifdef USE_JPWL
|
||||
@@ -254,7 +409,10 @@ static int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *param
|
||||
#endif /* USE_JPWL */
|
||||
/* <<UniPG */
|
||||
"h" ;
|
||||
totlen=sizeof(long_option) - 1;
|
||||
|
||||
long_option[2].flag = &(parameters->force_rgb);
|
||||
long_option[3].flag = &(parameters->upsample);
|
||||
totlen=sizeof(long_option);
|
||||
img_fol->set_out_format = 0;
|
||||
do {
|
||||
#ifdef USE_SYSTEM_GETOPT
|
||||
@@ -265,6 +423,8 @@ static int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *param
|
||||
if (c == -1)
|
||||
break;
|
||||
switch (c) {
|
||||
case 0: /* long opt with flag */
|
||||
break;
|
||||
case 'i': /* input file */
|
||||
{
|
||||
char *infile = opj_optarg;
|
||||
@@ -351,7 +511,7 @@ static int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *param
|
||||
|
||||
case 'r': /* reduce option */
|
||||
{
|
||||
sscanf(opj_optarg, "%d", ¶meters->cp_reduce);
|
||||
sscanf(opj_optarg, "%d", ¶meters->core.cp_reduce);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -360,7 +520,7 @@ static int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *param
|
||||
|
||||
case 'l': /* layering option */
|
||||
{
|
||||
sscanf(opj_optarg, "%d", ¶meters->cp_layer);
|
||||
sscanf(opj_optarg, "%d", ¶meters->core.cp_layer);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -387,6 +547,15 @@ static int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *param
|
||||
}
|
||||
break;
|
||||
/* ----------------------------------------------------- */
|
||||
case 'p': /* Force precision */
|
||||
{
|
||||
if (!parse_precision(opj_optarg, parameters))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
/* ----------------------------------------------------- */
|
||||
/* UniPG>> */
|
||||
#ifdef USE_JPWL
|
||||
|
||||
@@ -461,7 +630,7 @@ static int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *param
|
||||
/* ----------------------------------------------------- */
|
||||
|
||||
default:
|
||||
fprintf(stderr,"WARNING -> this option is not valid \"-%c %s\"\n",c, opj_optarg);
|
||||
fprintf(stderr,"[WARNING] An invalid option has been ignored\n");
|
||||
break;
|
||||
}
|
||||
}while(c != -1);
|
||||
@@ -494,6 +663,32 @@ static int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *param
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static void set_default_parameters(opj_decompress_parameters* parameters)
|
||||
{
|
||||
if (parameters) {
|
||||
memset(parameters, 0, sizeof(opj_decompress_parameters));
|
||||
|
||||
/* default decoding parameters (command line specific) */
|
||||
parameters->decod_format = -1;
|
||||
parameters->cod_format = -1;
|
||||
|
||||
/* default decoding parameters (core) */
|
||||
opj_set_default_decoder_parameters(&(parameters->core));
|
||||
}
|
||||
}
|
||||
|
||||
static void destroy_parameters(opj_decompress_parameters* parameters)
|
||||
{
|
||||
if (parameters) {
|
||||
if (parameters->precision) {
|
||||
free(parameters->precision);
|
||||
parameters->precision = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
sample error callback expecting a FILE* client object
|
||||
*/
|
||||
@@ -518,8 +713,233 @@ static void info_callback(const char *msg, void *client_data) {
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static opj_image_t* convert_gray_to_rgb(opj_image_t* original)
|
||||
{
|
||||
int compno;
|
||||
opj_image_t* l_new_image = NULL;
|
||||
opj_image_cmptparm_t* l_new_components = NULL;
|
||||
|
||||
l_new_components = (opj_image_cmptparm_t*)malloc((original->numcomps + 2U) * sizeof(opj_image_cmptparm_t));
|
||||
if (l_new_components == NULL) {
|
||||
fprintf(stderr, "ERROR -> j2k_to_image: failed to allocate memory for RGB image!\n");
|
||||
opj_image_destroy(original);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
l_new_components[0].bpp = l_new_components[1].bpp = l_new_components[2].bpp = original->comps[0].bpp;
|
||||
l_new_components[0].dx = l_new_components[1].dx = l_new_components[2].dx = original->comps[0].dx;
|
||||
l_new_components[0].dy = l_new_components[1].dy = l_new_components[2].dy = original->comps[0].dy;
|
||||
l_new_components[0].h = l_new_components[1].h = l_new_components[2].h = original->comps[0].h;
|
||||
l_new_components[0].w = l_new_components[1].w = l_new_components[2].w = original->comps[0].w;
|
||||
l_new_components[0].prec = l_new_components[1].prec = l_new_components[2].prec = original->comps[0].prec;
|
||||
l_new_components[0].sgnd = l_new_components[1].sgnd = l_new_components[2].sgnd = original->comps[0].sgnd;
|
||||
l_new_components[0].x0 = l_new_components[1].x0 = l_new_components[2].x0 = original->comps[0].x0;
|
||||
l_new_components[0].y0 = l_new_components[1].y0 = l_new_components[2].y0 = original->comps[0].y0;
|
||||
|
||||
for(compno = 1; compno < original->numcomps; ++compno) {
|
||||
l_new_components[compno+2].bpp = original->comps[compno].bpp;
|
||||
l_new_components[compno+2].dx = original->comps[compno].dx;
|
||||
l_new_components[compno+2].dy = original->comps[compno].dy;
|
||||
l_new_components[compno+2].h = original->comps[compno].h;
|
||||
l_new_components[compno+2].w = original->comps[compno].w;
|
||||
l_new_components[compno+2].prec = original->comps[compno].prec;
|
||||
l_new_components[compno+2].sgnd = original->comps[compno].sgnd;
|
||||
l_new_components[compno+2].x0 = original->comps[compno].x0;
|
||||
l_new_components[compno+2].y0 = original->comps[compno].y0;
|
||||
}
|
||||
|
||||
l_new_image = opj_image_create(original->numcomps + 2, l_new_components, CLRSPC_SRGB);
|
||||
free(l_new_components);
|
||||
if (l_new_image == NULL) {
|
||||
fprintf(stderr, "ERROR -> j2k_to_image: failed to allocate memory for RGB image!\n");
|
||||
opj_image_destroy(original);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
l_new_image->x0 = original->x0;
|
||||
l_new_image->x1 = original->x1;
|
||||
l_new_image->y0 = original->y0;
|
||||
l_new_image->y1 = original->y1;
|
||||
|
||||
l_new_image->comps[0].factor = l_new_image->comps[1].factor = l_new_image->comps[2].factor = original->comps[0].factor;
|
||||
l_new_image->comps[0].resno_decoded = l_new_image->comps[1].resno_decoded = l_new_image->comps[2].resno_decoded = original->comps[0].resno_decoded;
|
||||
|
||||
memcpy(l_new_image->comps[0].data, original->comps[0].data, original->comps[0].w * original->comps[0].h * sizeof(int));
|
||||
memcpy(l_new_image->comps[1].data, original->comps[0].data, original->comps[0].w * original->comps[0].h * sizeof(int));
|
||||
memcpy(l_new_image->comps[2].data, original->comps[0].data, original->comps[0].w * original->comps[0].h * sizeof(int));
|
||||
|
||||
for(compno = 1; compno < original->numcomps; ++compno) {
|
||||
l_new_image->comps[compno+2].factor = original->comps[compno].factor;
|
||||
l_new_image->comps[compno+2].resno_decoded = original->comps[compno].resno_decoded;
|
||||
memcpy(l_new_image->comps[compno+2].data, original->comps[compno].data, original->comps[compno].w * original->comps[compno].h * sizeof(int));
|
||||
}
|
||||
opj_image_destroy(original);
|
||||
return l_new_image;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static opj_image_t* upsample_image_components(opj_image_t* original)
|
||||
{
|
||||
opj_image_t* l_new_image = NULL;
|
||||
opj_image_cmptparm_t* l_new_components = NULL;
|
||||
opj_bool l_upsample_need = OPJ_FALSE;
|
||||
int compno;
|
||||
|
||||
for (compno = 0; compno < original->numcomps; ++compno) {
|
||||
if (original->comps[compno].factor > 0) {
|
||||
fprintf(stderr, "ERROR -> j2k_to_image: -upsample not supported with reduction\n");
|
||||
opj_image_destroy(original);
|
||||
return NULL;
|
||||
}
|
||||
if ((original->comps[compno].dx > 1) || (original->comps[compno].dy > 1)) {
|
||||
l_upsample_need = OPJ_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!l_upsample_need) {
|
||||
return original;
|
||||
}
|
||||
/* Upsample is needed */
|
||||
l_new_components = (opj_image_cmptparm_t*)malloc(original->numcomps * sizeof(opj_image_cmptparm_t));
|
||||
if (l_new_components == NULL) {
|
||||
fprintf(stderr, "ERROR -> j2k_to_image: failed to allocate memory for upsampled components!\n");
|
||||
opj_image_destroy(original);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (compno = 0; compno < original->numcomps; ++compno) {
|
||||
opj_image_cmptparm_t* l_new_cmp = &(l_new_components[compno]);
|
||||
opj_image_comp_t* l_org_cmp = &(original->comps[compno]);
|
||||
|
||||
l_new_cmp->bpp = l_org_cmp->bpp;
|
||||
l_new_cmp->prec = l_org_cmp->prec;
|
||||
l_new_cmp->sgnd = l_org_cmp->sgnd;
|
||||
l_new_cmp->x0 = original->x0;
|
||||
l_new_cmp->y0 = original->y0;
|
||||
l_new_cmp->dx = 1;
|
||||
l_new_cmp->dy = 1;
|
||||
l_new_cmp->w = l_org_cmp->w; /* should be original->x1 - original->x0 for dx==1 */
|
||||
l_new_cmp->h = l_org_cmp->h; /* should be original->y1 - original->y0 for dy==0 */
|
||||
|
||||
if (l_org_cmp->dx > 1) {
|
||||
l_new_cmp->w = original->x1 - original->x0;
|
||||
}
|
||||
|
||||
if (l_org_cmp->dy > 1) {
|
||||
l_new_cmp->h = original->y1 - original->y0;
|
||||
}
|
||||
}
|
||||
|
||||
l_new_image = opj_image_create(original->numcomps, l_new_components, original->color_space);
|
||||
free(l_new_components);
|
||||
if (l_new_image == NULL) {
|
||||
fprintf(stderr, "ERROR -> j2k_to_image: failed to allocate memory for upsampled components!\n");
|
||||
opj_image_destroy(original);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
l_new_image->x0 = original->x0;
|
||||
l_new_image->x1 = original->x1;
|
||||
l_new_image->y0 = original->y0;
|
||||
l_new_image->y1 = original->y1;
|
||||
|
||||
for (compno = 0; compno < original->numcomps; ++compno) {
|
||||
opj_image_comp_t* l_new_cmp = &(l_new_image->comps[compno]);
|
||||
opj_image_comp_t* l_org_cmp = &(original->comps[compno]);
|
||||
|
||||
l_new_cmp->factor = l_org_cmp->factor;
|
||||
l_new_cmp->resno_decoded = l_org_cmp->resno_decoded;
|
||||
|
||||
if ((l_org_cmp->dx > 1) || (l_org_cmp->dy > 1)) {
|
||||
const int* l_src = l_org_cmp->data;
|
||||
int* l_dst = l_new_cmp->data;
|
||||
int y;
|
||||
int xoff, yoff;
|
||||
|
||||
/* need to take into account dx & dy */
|
||||
xoff = l_org_cmp->dx * l_org_cmp->x0 - original->x0;
|
||||
yoff = l_org_cmp->dy * l_org_cmp->y0 - original->y0;
|
||||
if ((xoff >= l_org_cmp->dx) || (yoff >= l_org_cmp->dy)) {
|
||||
fprintf(stderr, "ERROR -> j2k_to_image: Invalid image/component parameters found when upsampling\n");
|
||||
opj_image_destroy(original);
|
||||
opj_image_destroy(l_new_image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (y = 0; y < yoff; ++y) {
|
||||
memset(l_dst, 0, l_new_cmp->w * sizeof(int));
|
||||
l_dst += l_new_cmp->w;
|
||||
}
|
||||
|
||||
if(l_new_cmp->h > (l_org_cmp->dy - 1)) { /* check subtraction overflow for really small images */
|
||||
for (; y < l_new_cmp->h - (l_org_cmp->dy - 1); y += l_org_cmp->dy) {
|
||||
int x, dy;
|
||||
int xorg;
|
||||
|
||||
xorg = 0;
|
||||
for (x = 0; x < xoff; ++x) {
|
||||
l_dst[x] = 0;
|
||||
}
|
||||
if (l_new_cmp->w > (l_org_cmp->dx - 1)) { /* check subtraction overflow for really small images */
|
||||
for (; x < l_new_cmp->w - (l_org_cmp->dx - 1); x += l_org_cmp->dx, ++xorg) {
|
||||
int dx;
|
||||
for (dx = 0; dx < l_org_cmp->dx; ++dx) {
|
||||
l_dst[x + dx] = l_src[xorg];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (; x < l_new_cmp->w; ++x) {
|
||||
l_dst[x] = l_src[xorg];
|
||||
}
|
||||
l_dst += l_new_cmp->w;
|
||||
|
||||
for (dy = 1; dy < l_org_cmp->dy; ++dy) {
|
||||
memcpy(l_dst, l_dst - l_new_cmp->w, l_new_cmp->w * sizeof(int));
|
||||
l_dst += l_new_cmp->w;
|
||||
}
|
||||
l_src += l_org_cmp->w;
|
||||
}
|
||||
}
|
||||
if (y < l_new_cmp->h) {
|
||||
int x;
|
||||
int xorg;
|
||||
|
||||
xorg = 0;
|
||||
for (x = 0; x < xoff; ++x) {
|
||||
l_dst[x] = 0;
|
||||
}
|
||||
if (l_new_cmp->w > (l_org_cmp->dx - 1)) { /* check subtraction overflow for really small images */
|
||||
for (; x < l_new_cmp->w - (l_org_cmp->dx - 1); x += l_org_cmp->dx, ++xorg) {
|
||||
int dx;
|
||||
for (dx = 0; dx < l_org_cmp->dx; ++dx) {
|
||||
l_dst[x + dx] = l_src[xorg];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (; x < l_new_cmp->w; ++x) {
|
||||
l_dst[x] = l_src[xorg];
|
||||
}
|
||||
l_dst += l_new_cmp->w;
|
||||
++y;
|
||||
for (; y < l_new_cmp->h; ++y) {
|
||||
memcpy(l_dst, l_dst - l_new_cmp->w, l_new_cmp->w * sizeof(int));
|
||||
l_dst += l_new_cmp->w;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
memcpy(l_new_cmp->data, l_org_cmp->data, l_org_cmp->w * l_org_cmp->h * sizeof(int));
|
||||
}
|
||||
}
|
||||
opj_image_destroy(original);
|
||||
return l_new_image;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
opj_dparameters_t parameters; /* decompression parameters */
|
||||
opj_decompress_parameters parameters; /* decompression parameters */
|
||||
img_fol_t img_fol;
|
||||
opj_event_mgr_t event_mgr; /* event manager */
|
||||
opj_image_t *image = NULL;
|
||||
@@ -541,7 +961,7 @@ int main(int argc, char **argv) {
|
||||
event_mgr.info_handler = info_callback;
|
||||
|
||||
/* set decoding parameters to default values */
|
||||
opj_set_default_decoder_parameters(¶meters);
|
||||
set_default_parameters(¶meters);
|
||||
|
||||
/* Initialize indexfilename and img_fol */
|
||||
*indexfilename = 0;
|
||||
@@ -549,6 +969,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
/* parse input and get user encoding parameters */
|
||||
if(parse_cmdline_decoder(argc, argv, ¶meters,&img_fol, indexfilename) == 1) {
|
||||
destroy_parameters(¶meters);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -562,6 +983,7 @@ int main(int argc, char **argv) {
|
||||
dirptr->filename = (char**) malloc(num_images*sizeof(char*));
|
||||
|
||||
if(!dirptr->filename_buf){
|
||||
destroy_parameters(¶meters);
|
||||
return 1;
|
||||
}
|
||||
for(i=0;i<num_images;i++){
|
||||
@@ -569,10 +991,12 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
}
|
||||
if(load_images(dirptr,img_fol.imgdirpath)==1){
|
||||
destroy_parameters(¶meters);
|
||||
return 1;
|
||||
}
|
||||
if (num_images==0){
|
||||
fprintf(stdout,"Folder is empty\n");
|
||||
destroy_parameters(¶meters);
|
||||
return 1;
|
||||
}
|
||||
}else{
|
||||
@@ -596,6 +1020,7 @@ int main(int argc, char **argv) {
|
||||
fsrc = fopen(parameters.infile, "rb");
|
||||
if (!fsrc) {
|
||||
fprintf(stderr, "ERROR -> failed to open %s for reading\n", parameters.infile);
|
||||
destroy_parameters(¶meters);
|
||||
return 1;
|
||||
}
|
||||
fseek(fsrc, 0, SEEK_END);
|
||||
@@ -607,6 +1032,7 @@ int main(int argc, char **argv) {
|
||||
free(src);
|
||||
fclose(fsrc);
|
||||
fprintf(stderr, "\nERROR: fread return a number of element different from the expected.\n");
|
||||
destroy_parameters(¶meters);
|
||||
return 1;
|
||||
}
|
||||
fclose(fsrc);
|
||||
@@ -626,7 +1052,7 @@ int main(int argc, char **argv) {
|
||||
opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
|
||||
|
||||
/* setup the decoder decoding parameters using user parameters */
|
||||
opj_setup_decoder(dinfo, ¶meters);
|
||||
opj_setup_decoder(dinfo, ¶meters.core);
|
||||
|
||||
/* open a byte stream */
|
||||
cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
|
||||
@@ -641,6 +1067,7 @@ int main(int argc, char **argv) {
|
||||
opj_destroy_decompress(dinfo);
|
||||
opj_cio_close(cio);
|
||||
free(src);
|
||||
destroy_parameters(¶meters);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -669,7 +1096,7 @@ int main(int argc, char **argv) {
|
||||
opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
|
||||
|
||||
/* setup the decoder decoding parameters using the current image and user parameters */
|
||||
opj_setup_decoder(dinfo, ¶meters);
|
||||
opj_setup_decoder(dinfo, ¶meters.core);
|
||||
|
||||
/* open a byte stream */
|
||||
cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
|
||||
@@ -684,6 +1111,7 @@ int main(int argc, char **argv) {
|
||||
opj_destroy_decompress(dinfo);
|
||||
opj_cio_close(cio);
|
||||
free(src);
|
||||
destroy_parameters(¶meters);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -712,7 +1140,7 @@ int main(int argc, char **argv) {
|
||||
opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
|
||||
|
||||
/* setup the decoder decoding parameters using user parameters */
|
||||
opj_setup_decoder(dinfo, ¶meters);
|
||||
opj_setup_decoder(dinfo, ¶meters.core);
|
||||
|
||||
/* open a byte stream */
|
||||
cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
|
||||
@@ -727,6 +1155,7 @@ int main(int argc, char **argv) {
|
||||
opj_destroy_decompress(dinfo);
|
||||
opj_cio_close(cio);
|
||||
free(src);
|
||||
destroy_parameters(¶meters);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -753,20 +1182,89 @@ int main(int argc, char **argv) {
|
||||
free(src);
|
||||
src = NULL;
|
||||
|
||||
if(image->color_space == CLRSPC_SYCC)
|
||||
{
|
||||
color_sycc_to_rgb(image);
|
||||
}
|
||||
if(image->color_space == CLRSPC_SYCC)
|
||||
{
|
||||
color_sycc_to_rgb(image);
|
||||
}
|
||||
|
||||
if(image->icc_profile_buf)
|
||||
{
|
||||
if(image->icc_profile_buf)
|
||||
{
|
||||
#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
|
||||
color_apply_icc_profile(image);
|
||||
color_apply_icc_profile(image);
|
||||
#endif
|
||||
|
||||
free(image->icc_profile_buf);
|
||||
image->icc_profile_buf = NULL; image->icc_profile_len = 0;
|
||||
}
|
||||
free(image->icc_profile_buf);
|
||||
image->icc_profile_buf = NULL; image->icc_profile_len = 0;
|
||||
}
|
||||
|
||||
/* Force output precision */
|
||||
/* ---------------------- */
|
||||
if (parameters.precision != NULL)
|
||||
{
|
||||
int compno;
|
||||
for (compno = 0; compno < image->numcomps; ++compno)
|
||||
{
|
||||
int precno = compno;
|
||||
int prec;
|
||||
|
||||
if (precno >= parameters.nb_precision) {
|
||||
precno = parameters.nb_precision - 1U;
|
||||
}
|
||||
|
||||
prec = parameters.precision[precno].prec;
|
||||
if (prec == 0) {
|
||||
prec = image->comps[compno].prec;
|
||||
}
|
||||
|
||||
switch (parameters.precision[precno].mode) {
|
||||
case OPJ_PREC_MODE_CLIP:
|
||||
clip_component(&(image->comps[compno]), prec);
|
||||
break;
|
||||
case OPJ_PREC_MODE_SCALE:
|
||||
scale_component(&(image->comps[compno]), prec);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Upsample components */
|
||||
/* ------------------- */
|
||||
if (parameters.upsample)
|
||||
{
|
||||
image = upsample_image_components(image);
|
||||
if (image == NULL) {
|
||||
fprintf(stderr, "ERROR -> j2k_to_image: failed to upsample image components!\n");
|
||||
destroy_parameters(¶meters);
|
||||
opj_destroy_decompress(dinfo);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Force RGB output */
|
||||
/* ---------------- */
|
||||
if (parameters.force_rgb)
|
||||
{
|
||||
switch (image->color_space) {
|
||||
case CLRSPC_SRGB:
|
||||
break;
|
||||
case CLRSPC_GRAY:
|
||||
image = convert_gray_to_rgb(image);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "ERROR -> j2k_to_image: don't know how to convert image to RGB colorspace!\n");
|
||||
opj_image_destroy(image);
|
||||
image = NULL;
|
||||
break;
|
||||
}
|
||||
if (image == NULL) {
|
||||
fprintf(stderr, "ERROR -> j2k_to_image: failed to convert to RGB image!\n");
|
||||
destroy_parameters(¶meters);
|
||||
opj_destroy_decompress(dinfo);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* create output image */
|
||||
/* ------------------- */
|
||||
@@ -852,6 +1350,7 @@ int main(int argc, char **argv) {
|
||||
opj_image_destroy(image);
|
||||
|
||||
}
|
||||
destroy_parameters(¶meters);
|
||||
return 0;
|
||||
}
|
||||
/*end main*/
|
||||
|
||||
@@ -46,31 +46,31 @@
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------
|
||||
Matrix f<EFBFBD>r sYCC, Amendment 1 to IEC 61966-2-1
|
||||
|
||||
Y : 0.299 0.587 0.114 :R
|
||||
Cb: -0.1687 -0.3312 0.5 :G
|
||||
Cr: 0.5 -0.4187 -0.0812 :B
|
||||
|
||||
Inverse:
|
||||
|
||||
R: 1 -3.68213e-05 1.40199 :Y
|
||||
G: 1.00003 -0.344125 -0.714128 :Cb - 2^(prec - 1)
|
||||
B: 0.999823 1.77204 -8.04142e-06 :Cr - 2^(prec - 1)
|
||||
|
||||
-----------------------------------------------------------*/
|
||||
Matrix for sYCC, Amendment 1 to IEC 61966-2-1
|
||||
|
||||
Y : 0.299 0.587 0.114 :R
|
||||
Cb: -0.1687 -0.3312 0.5 :G
|
||||
Cr: 0.5 -0.4187 -0.0812 :B
|
||||
|
||||
Inverse:
|
||||
|
||||
R: 1 -3.68213e-05 1.40199 :Y
|
||||
G: 1.00003 -0.344125 -0.714128 :Cb - 2^(prec - 1)
|
||||
B: 0.999823 1.77204 -8.04142e-06 :Cr - 2^(prec - 1)
|
||||
|
||||
-----------------------------------------------------------*/
|
||||
static void sycc_to_rgb(int offset, int upb, int y, int cb, int cr,
|
||||
int *out_r, int *out_g, int *out_b)
|
||||
int *out_r, int *out_g, int *out_b)
|
||||
{
|
||||
int r, g, b;
|
||||
|
||||
|
||||
cb -= offset; cr -= offset;
|
||||
r = y + (int)(1.402 * (float)cr);
|
||||
if(r < 0) r = 0; else if(r > upb) r = upb; *out_r = r;
|
||||
|
||||
|
||||
g = y - (int)(0.344 * (float)cb + 0.714 * (float)cr);
|
||||
if(g < 0) g = 0; else if(g > upb) g = upb; *out_g = g;
|
||||
|
||||
|
||||
b = y + (int)(1.772 * (float)cb);
|
||||
if(b < 0) b = 0; else if(b > upb) b = upb; *out_b = b;
|
||||
}
|
||||
@@ -79,185 +79,206 @@ static void sycc444_to_rgb(opj_image_t *img)
|
||||
{
|
||||
int *d0, *d1, *d2, *r, *g, *b;
|
||||
const int *y, *cb, *cr;
|
||||
int maxw, maxh, max, i, offset, upb;
|
||||
|
||||
i = img->comps[0].prec;
|
||||
offset = 1<<(i - 1); upb = (1<<i)-1;
|
||||
|
||||
maxw = img->comps[0].w; maxh = img->comps[0].h;
|
||||
unsigned int maxw, maxh, max, i;
|
||||
int offset, upb;
|
||||
|
||||
upb = (int)img->comps[0].prec;
|
||||
offset = 1<<(upb - 1); upb = (1<<upb)-1;
|
||||
|
||||
maxw = (unsigned int)img->comps[0].w; maxh = (unsigned int)img->comps[0].h;
|
||||
max = maxw * maxh;
|
||||
|
||||
|
||||
y = img->comps[0].data;
|
||||
cb = img->comps[1].data;
|
||||
cr = img->comps[2].data;
|
||||
|
||||
d0 = r = (int*)malloc(sizeof(int) * max);
|
||||
d1 = g = (int*)malloc(sizeof(int) * max);
|
||||
d2 = b = (int*)malloc(sizeof(int) * max);
|
||||
|
||||
for(i = 0; i < max; ++i)
|
||||
{
|
||||
sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
|
||||
|
||||
++y; ++cb; ++cr; ++r; ++g; ++b;
|
||||
}
|
||||
|
||||
d0 = r = (int*)malloc(sizeof(int) * (size_t)max);
|
||||
d1 = g = (int*)malloc(sizeof(int) * (size_t)max);
|
||||
d2 = b = (int*)malloc(sizeof(int) * (size_t)max);
|
||||
|
||||
for(i = 0U; i < max; ++i)
|
||||
{
|
||||
sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
|
||||
++y; ++cb; ++cr; ++r; ++g; ++b;
|
||||
}
|
||||
free(img->comps[0].data); img->comps[0].data = d0;
|
||||
free(img->comps[1].data); img->comps[1].data = d1;
|
||||
free(img->comps[2].data); img->comps[2].data = d2;
|
||||
|
||||
|
||||
}/* sycc444_to_rgb() */
|
||||
|
||||
static void sycc422_to_rgb(opj_image_t *img)
|
||||
{
|
||||
{
|
||||
int *d0, *d1, *d2, *r, *g, *b;
|
||||
const int *y, *cb, *cr;
|
||||
int maxw, maxh, max, offset, upb;
|
||||
int i, j;
|
||||
|
||||
i = img->comps[0].prec;
|
||||
offset = 1<<(i - 1); upb = (1<<i)-1;
|
||||
|
||||
maxw = img->comps[0].w; maxh = img->comps[0].h;
|
||||
unsigned int maxw, maxh, max;
|
||||
int offset, upb;
|
||||
unsigned int i, j;
|
||||
|
||||
upb = (int)img->comps[0].prec;
|
||||
offset = 1<<(upb - 1); upb = (1<<upb)-1;
|
||||
|
||||
maxw = (unsigned int)img->comps[0].w; maxh = (unsigned int)img->comps[0].h;
|
||||
max = maxw * maxh;
|
||||
|
||||
|
||||
y = img->comps[0].data;
|
||||
cb = img->comps[1].data;
|
||||
cr = img->comps[2].data;
|
||||
|
||||
d0 = r = (int*)malloc(sizeof(int) * max);
|
||||
d1 = g = (int*)malloc(sizeof(int) * max);
|
||||
d2 = b = (int*)malloc(sizeof(int) * max);
|
||||
|
||||
for(i=0; i < maxh; ++i)
|
||||
{
|
||||
for(j=0; j < maxw; j += 2)
|
||||
{
|
||||
sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
|
||||
|
||||
++y; ++r; ++g; ++b;
|
||||
|
||||
sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
|
||||
|
||||
++y; ++r; ++g; ++b; ++cb; ++cr;
|
||||
}
|
||||
}
|
||||
|
||||
d0 = r = (int*)malloc(sizeof(int) * (size_t)max);
|
||||
d1 = g = (int*)malloc(sizeof(int) * (size_t)max);
|
||||
d2 = b = (int*)malloc(sizeof(int) * (size_t)max);
|
||||
|
||||
for(i=0U; i < maxh; ++i)
|
||||
{
|
||||
for(j=0U; j < (maxw & ~(unsigned int)1U); j += 2U)
|
||||
{
|
||||
sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
|
||||
++y; ++r; ++g; ++b;
|
||||
sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
|
||||
++y; ++r; ++g; ++b; ++cb; ++cr;
|
||||
}
|
||||
if (j < maxw) {
|
||||
sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
|
||||
++y; ++r; ++g; ++b; ++cb; ++cr;
|
||||
}
|
||||
}
|
||||
free(img->comps[0].data); img->comps[0].data = d0;
|
||||
free(img->comps[1].data); img->comps[1].data = d1;
|
||||
free(img->comps[2].data); img->comps[2].data = d2;
|
||||
|
||||
|
||||
img->comps[1].w = maxw; img->comps[1].h = maxh;
|
||||
img->comps[2].w = maxw; img->comps[2].h = maxh;
|
||||
img->comps[1].dx = img->comps[0].dx;
|
||||
img->comps[2].dx = img->comps[0].dx;
|
||||
img->comps[1].dy = img->comps[0].dy;
|
||||
img->comps[2].dy = img->comps[0].dy;
|
||||
|
||||
}/* sycc422_to_rgb() */
|
||||
|
||||
static void sycc420_to_rgb(opj_image_t *img)
|
||||
{
|
||||
int *d0, *d1, *d2, *r, *g, *b, *nr, *ng, *nb;
|
||||
const int *y, *cb, *cr, *ny;
|
||||
int maxw, maxh, max, offset, upb;
|
||||
int i, j;
|
||||
|
||||
i = img->comps[0].prec;
|
||||
offset = 1<<(i - 1); upb = (1<<i)-1;
|
||||
|
||||
maxw = img->comps[0].w; maxh = img->comps[0].h;
|
||||
unsigned int maxw, maxh, max;
|
||||
int offset, upb;
|
||||
unsigned int i, j;
|
||||
|
||||
upb = (int)img->comps[0].prec;
|
||||
offset = 1<<(upb - 1); upb = (1<<upb)-1;
|
||||
|
||||
maxw = (unsigned int)img->comps[0].w; maxh = (unsigned int)img->comps[0].h;
|
||||
max = maxw * maxh;
|
||||
|
||||
|
||||
y = img->comps[0].data;
|
||||
cb = img->comps[1].data;
|
||||
cr = img->comps[2].data;
|
||||
|
||||
d0 = r = (int*)malloc(sizeof(int) * max);
|
||||
d1 = g = (int*)malloc(sizeof(int) * max);
|
||||
d2 = b = (int*)malloc(sizeof(int) * max);
|
||||
|
||||
for(i=0; i < maxh; i += 2)
|
||||
{
|
||||
ny = y + maxw;
|
||||
nr = r + maxw; ng = g + maxw; nb = b + maxw;
|
||||
|
||||
for(j=0; j < maxw; j += 2)
|
||||
{
|
||||
sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
|
||||
|
||||
++y; ++r; ++g; ++b;
|
||||
|
||||
sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
|
||||
|
||||
++y; ++r; ++g; ++b;
|
||||
|
||||
sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb);
|
||||
|
||||
++ny; ++nr; ++ng; ++nb;
|
||||
|
||||
sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb);
|
||||
|
||||
++ny; ++nr; ++ng; ++nb; ++cb; ++cr;
|
||||
}
|
||||
y += maxw; r += maxw; g += maxw; b += maxw;
|
||||
}
|
||||
|
||||
d0 = r = (int*)malloc(sizeof(int) * (size_t)max);
|
||||
d1 = g = (int*)malloc(sizeof(int) * (size_t)max);
|
||||
d2 = b = (int*)malloc(sizeof(int) * (size_t)max);
|
||||
|
||||
for(i=0U; i < (maxh & ~(unsigned int)1U); i += 2U)
|
||||
{
|
||||
ny = y + maxw;
|
||||
nr = r + maxw; ng = g + maxw; nb = b + maxw;
|
||||
|
||||
for(j=0; j < (maxw & ~(unsigned int)1U); j += 2U)
|
||||
{
|
||||
sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
|
||||
++y; ++r; ++g; ++b;
|
||||
sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
|
||||
++y; ++r; ++g; ++b;
|
||||
|
||||
sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb);
|
||||
++ny; ++nr; ++ng; ++nb;
|
||||
sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb);
|
||||
++ny; ++nr; ++ng; ++nb; ++cb; ++cr;
|
||||
}
|
||||
if(j < maxw)
|
||||
{
|
||||
sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
|
||||
++y; ++r; ++g; ++b;
|
||||
|
||||
sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb);
|
||||
++ny; ++nr; ++ng; ++nb; ++cb; ++cr;
|
||||
}
|
||||
y += maxw; r += maxw; g += maxw; b += maxw;
|
||||
}
|
||||
if(i < maxh)
|
||||
{
|
||||
for(j=0U; j < (maxw & ~(unsigned int)1U); j += 2U)
|
||||
{
|
||||
sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
|
||||
|
||||
++y; ++r; ++g; ++b;
|
||||
|
||||
sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
|
||||
|
||||
++y; ++r; ++g; ++b; ++cb; ++cr;
|
||||
}
|
||||
if(j < maxw)
|
||||
{
|
||||
sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
|
||||
}
|
||||
}
|
||||
|
||||
free(img->comps[0].data); img->comps[0].data = d0;
|
||||
free(img->comps[1].data); img->comps[1].data = d1;
|
||||
free(img->comps[2].data); img->comps[2].data = d2;
|
||||
|
||||
|
||||
img->comps[1].w = maxw; img->comps[1].h = maxh;
|
||||
img->comps[2].w = maxw; img->comps[2].h = maxh;
|
||||
img->comps[1].dx = img->comps[0].dx;
|
||||
img->comps[2].dx = img->comps[0].dx;
|
||||
img->comps[1].dy = img->comps[0].dy;
|
||||
img->comps[2].dy = img->comps[0].dy;
|
||||
|
||||
|
||||
}/* sycc420_to_rgb() */
|
||||
|
||||
void color_sycc_to_rgb(opj_image_t *img)
|
||||
{
|
||||
if(img->numcomps < 3)
|
||||
{
|
||||
img->color_space = CLRSPC_GRAY;
|
||||
return;
|
||||
}
|
||||
|
||||
if(img->numcomps < 3)
|
||||
{
|
||||
img->color_space = CLRSPC_GRAY;
|
||||
return;
|
||||
}
|
||||
|
||||
if((img->comps[0].dx == 1)
|
||||
&& (img->comps[1].dx == 2)
|
||||
&& (img->comps[2].dx == 2)
|
||||
&& (img->comps[0].dy == 1)
|
||||
&& (img->comps[1].dy == 2)
|
||||
&& (img->comps[2].dy == 2))/* horizontal and vertical sub-sample */
|
||||
{
|
||||
sycc420_to_rgb(img);
|
||||
}
|
||||
&& (img->comps[1].dx == 2)
|
||||
&& (img->comps[2].dx == 2)
|
||||
&& (img->comps[0].dy == 1)
|
||||
&& (img->comps[1].dy == 2)
|
||||
&& (img->comps[2].dy == 2))/* horizontal and vertical sub-sample */
|
||||
{
|
||||
sycc420_to_rgb(img);
|
||||
}
|
||||
else
|
||||
if((img->comps[0].dx == 1)
|
||||
&& (img->comps[1].dx == 2)
|
||||
&& (img->comps[2].dx == 2)
|
||||
&& (img->comps[0].dy == 1)
|
||||
&& (img->comps[1].dy == 1)
|
||||
&& (img->comps[2].dy == 1))/* horizontal sub-sample only */
|
||||
if((img->comps[0].dx == 1)
|
||||
&& (img->comps[1].dx == 2)
|
||||
&& (img->comps[2].dx == 2)
|
||||
&& (img->comps[0].dy == 1)
|
||||
&& (img->comps[1].dy == 1)
|
||||
&& (img->comps[2].dy == 1))/* horizontal sub-sample only */
|
||||
{
|
||||
sycc422_to_rgb(img);
|
||||
}
|
||||
else
|
||||
if((img->comps[0].dx == 1)
|
||||
&& (img->comps[1].dx == 1)
|
||||
&& (img->comps[2].dx == 1)
|
||||
&& (img->comps[0].dy == 1)
|
||||
&& (img->comps[1].dy == 1)
|
||||
&& (img->comps[2].dy == 1))/* no sub-sample */
|
||||
{
|
||||
sycc444_to_rgb(img);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"%s:%d:color_sycc_to_rgb\n\tCAN NOT CONVERT\n",
|
||||
__FILE__,__LINE__);
|
||||
return;
|
||||
}
|
||||
sycc422_to_rgb(img);
|
||||
}
|
||||
else
|
||||
if((img->comps[0].dx == 1)
|
||||
&& (img->comps[1].dx == 1)
|
||||
&& (img->comps[2].dx == 1)
|
||||
&& (img->comps[0].dy == 1)
|
||||
&& (img->comps[1].dy == 1)
|
||||
&& (img->comps[2].dy == 1))/* no sub-sample */
|
||||
{
|
||||
sycc444_to_rgb(img);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"%s:%d:color_sycc_to_rgb\n\tCAN NOT CONVERT\n", __FILE__,__LINE__);
|
||||
return;
|
||||
}
|
||||
img->color_space = CLRSPC_SRGB;
|
||||
|
||||
|
||||
}/* color_sycc_to_rgb() */
|
||||
|
||||
#if defined(HAVE_LIBLCMS2) || defined(HAVE_LIBLCMS1)
|
||||
@@ -286,178 +307,226 @@ void color_apply_icc_profile(opj_image_t *image)
|
||||
int *r, *g, *b;
|
||||
int prec, i, max, max_w, max_h;
|
||||
OPJ_COLOR_SPACE oldspace;
|
||||
|
||||
in_prof =
|
||||
cmsOpenProfileFromMem(image->icc_profile_buf, image->icc_profile_len);
|
||||
|
||||
|
||||
in_prof =
|
||||
cmsOpenProfileFromMem(image->icc_profile_buf, image->icc_profile_len);
|
||||
#ifdef DEBUG_PROFILE
|
||||
FILE *icm = fopen("debug.icm","wb");
|
||||
fwrite( image->icc_profile_buf,1, image->icc_profile_len,icm);
|
||||
fclose(icm);
|
||||
#endif
|
||||
|
||||
if(in_prof == NULL) return;
|
||||
|
||||
|
||||
in_space = cmsGetPCS(in_prof);
|
||||
(void)in_space;
|
||||
out_space = cmsGetColorSpace(in_prof);
|
||||
intent = cmsGetHeaderRenderingIntent(in_prof);
|
||||
|
||||
|
||||
max_w = image->comps[0].w; max_h = image->comps[0].h;
|
||||
prec = image->comps[0].prec;
|
||||
(void)prec;
|
||||
|
||||
max_w = (int)image->comps[0].w;
|
||||
max_h = (int)image->comps[0].h;
|
||||
prec = (int)image->comps[0].prec;
|
||||
oldspace = image->color_space;
|
||||
|
||||
|
||||
if(out_space == cmsSigRgbData) /* enumCS 16 */
|
||||
{
|
||||
in_type = TYPE_RGB_16;
|
||||
out_type = TYPE_RGB_16;
|
||||
out_prof = cmsCreate_sRGBProfile();
|
||||
image->color_space = CLRSPC_SRGB;
|
||||
}
|
||||
{
|
||||
if( prec <= 8 )
|
||||
{
|
||||
in_type = TYPE_RGB_8;
|
||||
out_type = TYPE_RGB_8;
|
||||
}
|
||||
else
|
||||
{
|
||||
in_type = TYPE_RGB_16;
|
||||
out_type = TYPE_RGB_16;
|
||||
}
|
||||
out_prof = cmsCreate_sRGBProfile();
|
||||
image->color_space = CLRSPC_SRGB;
|
||||
}
|
||||
else if(out_space == cmsSigGrayData) /* enumCS 17 */
|
||||
{
|
||||
in_type = TYPE_GRAY_8;
|
||||
out_type = TYPE_RGB_8;
|
||||
out_prof = cmsCreate_sRGBProfile();
|
||||
image->color_space = CLRSPC_SRGB;
|
||||
}
|
||||
else if(out_space == cmsSigYCbCrData) /* enumCS 18 */
|
||||
{
|
||||
in_type = TYPE_YCbCr_16;
|
||||
out_type = TYPE_RGB_16;
|
||||
out_prof = cmsCreate_sRGBProfile();
|
||||
image->color_space = CLRSPC_SRGB;
|
||||
}
|
||||
else
|
||||
if(out_space == cmsSigGrayData) /* enumCS 17 */
|
||||
{
|
||||
in_type = TYPE_GRAY_8;
|
||||
out_type = TYPE_RGB_8;
|
||||
out_prof = cmsCreate_sRGBProfile();
|
||||
image->color_space = CLRSPC_SRGB;
|
||||
}
|
||||
else
|
||||
if(out_space == cmsSigYCbCrData) /* enumCS 18 */
|
||||
{
|
||||
in_type = TYPE_YCbCr_16;
|
||||
out_type = TYPE_RGB_16;
|
||||
out_prof = cmsCreate_sRGBProfile();
|
||||
image->color_space = CLRSPC_SRGB;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
#ifdef DEBUG_PROFILE
|
||||
fprintf(stderr,"%s:%d: color_apply_icc_profile\n\tICC Profile has unknown "
|
||||
"output colorspace(%#x)(%c%c%c%c)\n\tICC Profile ignored.\n",
|
||||
__FILE__,__LINE__,out_space,
|
||||
(out_space>>24) & 0xff,(out_space>>16) & 0xff,
|
||||
(out_space>>8) & 0xff, out_space & 0xff);
|
||||
fprintf(stderr,"%s:%d: color_apply_icc_profile\n\tICC Profile has unknown "
|
||||
"output colorspace(%#x)(%c%c%c%c)\n\tICC Profile ignored.\n",
|
||||
__FILE__,__LINE__,out_space,
|
||||
(out_space>>24) & 0xff,(out_space>>16) & 0xff,
|
||||
(out_space>>8) & 0xff, out_space & 0xff);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_PROFILE
|
||||
fprintf(stderr,"%s:%d:color_apply_icc_profile\n\tchannels(%d) prec(%d) w(%d) h(%d)"
|
||||
"\n\tprofile: in(%p) out(%p)\n",__FILE__,__LINE__,image->numcomps,prec,
|
||||
max_w,max_h, (void*)in_prof,(void*)out_prof);
|
||||
|
||||
fprintf(stderr,"\trender_intent (%u)\n\t"
|
||||
"color_space: in(%#x)(%c%c%c%c) out:(%#x)(%c%c%c%c)\n\t"
|
||||
" type: in(%u) out:(%u)\n",
|
||||
intent,
|
||||
in_space,
|
||||
(in_space>>24) & 0xff,(in_space>>16) & 0xff,
|
||||
(in_space>>8) & 0xff, in_space & 0xff,
|
||||
|
||||
out_space,
|
||||
(out_space>>24) & 0xff,(out_space>>16) & 0xff,
|
||||
(out_space>>8) & 0xff, out_space & 0xff,
|
||||
|
||||
in_type,out_type
|
||||
);
|
||||
fprintf(stderr,"%s:%d:color_apply_icc_profile\n\tchannels(%d) prec(%d) w(%d) h(%d)"
|
||||
"\n\tprofile: in(%p) out(%p)\n",__FILE__,__LINE__,image->numcomps,prec,
|
||||
max_w,max_h, (void*)in_prof,(void*)out_prof);
|
||||
|
||||
fprintf(stderr,"\trender_intent (%u)\n\t"
|
||||
"color_space: in(%#x)(%c%c%c%c) out:(%#x)(%c%c%c%c)\n\t"
|
||||
" type: in(%u) out:(%u)\n",
|
||||
intent,
|
||||
in_space,
|
||||
(in_space>>24) & 0xff,(in_space>>16) & 0xff,
|
||||
(in_space>>8) & 0xff, in_space & 0xff,
|
||||
|
||||
out_space,
|
||||
(out_space>>24) & 0xff,(out_space>>16) & 0xff,
|
||||
(out_space>>8) & 0xff, out_space & 0xff,
|
||||
|
||||
in_type,out_type
|
||||
);
|
||||
#else
|
||||
(void)prec;
|
||||
(void)in_space;
|
||||
#endif /* DEBUG_PROFILE */
|
||||
|
||||
transform = cmsCreateTransform(in_prof, in_type,
|
||||
out_prof, out_type, intent, 0);
|
||||
|
||||
|
||||
transform = cmsCreateTransform(in_prof, in_type, out_prof, out_type, intent, 0);
|
||||
|
||||
#ifdef HAVE_LIBLCMS2
|
||||
/* Possible for: LCMS_VERSION >= 2000 :*/
|
||||
/* Possible for: LCMS_VERSION >= 2000 :*/
|
||||
cmsCloseProfile(in_prof);
|
||||
cmsCloseProfile(out_prof);
|
||||
#endif
|
||||
|
||||
|
||||
if(transform == NULL)
|
||||
{
|
||||
{
|
||||
#ifdef DEBUG_PROFILE
|
||||
fprintf(stderr,"%s:%d:color_apply_icc_profile\n\tcmsCreateTransform failed. "
|
||||
"ICC Profile ignored.\n",__FILE__,__LINE__);
|
||||
fprintf(stderr,"%s:%d:color_apply_icc_profile\n\tcmsCreateTransform failed. "
|
||||
"ICC Profile ignored.\n",__FILE__,__LINE__);
|
||||
#endif
|
||||
image->color_space = oldspace;
|
||||
image->color_space = oldspace;
|
||||
#ifdef HAVE_LIBLCMS1
|
||||
cmsCloseProfile(in_prof);
|
||||
cmsCloseProfile(out_prof);
|
||||
cmsCloseProfile(in_prof);
|
||||
cmsCloseProfile(out_prof);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(image->numcomps > 2)/* RGB, RGBA */
|
||||
{
|
||||
unsigned short *inbuf, *outbuf, *in, *out;
|
||||
max = max_w * max_h; nr_samples = max * 3 * sizeof(unsigned short);
|
||||
in = inbuf = (unsigned short*)malloc(nr_samples);
|
||||
out = outbuf = (unsigned short*)malloc(nr_samples);
|
||||
|
||||
r = image->comps[0].data;
|
||||
g = image->comps[1].data;
|
||||
b = image->comps[2].data;
|
||||
|
||||
for(i = 0; i < max; ++i)
|
||||
{
|
||||
*in++ = (unsigned short)*r++;
|
||||
*in++ = (unsigned short)*g++;
|
||||
*in++ = (unsigned short)*b++;
|
||||
}
|
||||
|
||||
cmsDoTransform(transform, inbuf, outbuf, max);
|
||||
|
||||
r = image->comps[0].data;
|
||||
g = image->comps[1].data;
|
||||
b = image->comps[2].data;
|
||||
|
||||
for(i = 0; i < max; ++i)
|
||||
{
|
||||
*r++ = (int)*out++;
|
||||
*g++ = (int)*out++;
|
||||
*b++ = (int)*out++;
|
||||
}
|
||||
free(inbuf); free(outbuf);
|
||||
}
|
||||
{
|
||||
if( prec <= 8 )
|
||||
{
|
||||
unsigned char *inbuf, *outbuf, *in, *out;
|
||||
max = max_w * max_h;
|
||||
nr_samples = (cmsUInt32Number)max * 3 * (cmsUInt32Number)sizeof(unsigned char);
|
||||
in = inbuf = (unsigned char*)malloc(nr_samples);
|
||||
out = outbuf = (unsigned char*)malloc(nr_samples);
|
||||
|
||||
r = image->comps[0].data;
|
||||
g = image->comps[1].data;
|
||||
b = image->comps[2].data;
|
||||
|
||||
for(i = 0; i < max; ++i)
|
||||
{
|
||||
*in++ = (unsigned char)*r++;
|
||||
*in++ = (unsigned char)*g++;
|
||||
*in++ = (unsigned char)*b++;
|
||||
}
|
||||
|
||||
cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
|
||||
|
||||
r = image->comps[0].data;
|
||||
g = image->comps[1].data;
|
||||
b = image->comps[2].data;
|
||||
|
||||
for(i = 0; i < max; ++i)
|
||||
{
|
||||
*r++ = (int)*out++;
|
||||
*g++ = (int)*out++;
|
||||
*b++ = (int)*out++;
|
||||
}
|
||||
free(inbuf); free(outbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned short *inbuf, *outbuf, *in, *out;
|
||||
max = max_w * max_h;
|
||||
nr_samples = (cmsUInt32Number)max * 3 * (cmsUInt32Number)sizeof(unsigned short);
|
||||
in = inbuf = (unsigned short*)malloc(nr_samples);
|
||||
out = outbuf = (unsigned short*)malloc(nr_samples);
|
||||
|
||||
r = image->comps[0].data;
|
||||
g = image->comps[1].data;
|
||||
b = image->comps[2].data;
|
||||
|
||||
for(i = 0; i < max; ++i)
|
||||
{
|
||||
*in++ = (unsigned short)*r++;
|
||||
*in++ = (unsigned short)*g++;
|
||||
*in++ = (unsigned short)*b++;
|
||||
}
|
||||
|
||||
cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
|
||||
|
||||
r = image->comps[0].data;
|
||||
g = image->comps[1].data;
|
||||
b = image->comps[2].data;
|
||||
|
||||
for(i = 0; i < max; ++i)
|
||||
{
|
||||
*r++ = (int)*out++;
|
||||
*g++ = (int)*out++;
|
||||
*b++ = (int)*out++;
|
||||
}
|
||||
free(inbuf); free(outbuf);
|
||||
}
|
||||
}
|
||||
else /* GRAY, GRAYA */
|
||||
{
|
||||
unsigned char *in, *inbuf, *out, *outbuf;
|
||||
|
||||
max = max_w * max_h; nr_samples = max * 3 * sizeof(unsigned char);
|
||||
in = inbuf = (unsigned char*)malloc(nr_samples);
|
||||
out = outbuf = (unsigned char*)malloc(nr_samples);
|
||||
|
||||
image->comps = (opj_image_comp_t*)
|
||||
realloc(image->comps, (image->numcomps+2)*sizeof(opj_image_comp_t));
|
||||
|
||||
if(image->numcomps == 2)
|
||||
image->comps[3] = image->comps[1];
|
||||
|
||||
image->comps[1] = image->comps[0];
|
||||
image->comps[2] = image->comps[0];
|
||||
|
||||
image->comps[1].data = (int*)calloc(max, sizeof(int));
|
||||
image->comps[2].data = (int*)calloc(max, sizeof(int));
|
||||
|
||||
image->numcomps += 2;
|
||||
|
||||
r = image->comps[0].data;
|
||||
|
||||
for(i = 0; i < max; ++i)
|
||||
{
|
||||
*in++ = (unsigned char)*r++;
|
||||
}
|
||||
cmsDoTransform(transform, inbuf, outbuf, max);
|
||||
|
||||
r = image->comps[0].data;
|
||||
g = image->comps[1].data;
|
||||
b = image->comps[2].data;
|
||||
|
||||
for(i = 0; i < max; ++i)
|
||||
{
|
||||
*r++ = (int)*out++; *g++ = (int)*out++; *b++ = (int)*out++;
|
||||
}
|
||||
free(inbuf); free(outbuf);
|
||||
|
||||
}/* if(image->numcomps */
|
||||
|
||||
{
|
||||
unsigned char *in, *inbuf, *out, *outbuf;
|
||||
max = max_w * max_h;
|
||||
nr_samples = (cmsUInt32Number)max * 3 * sizeof(unsigned char);
|
||||
in = inbuf = (unsigned char*)malloc(nr_samples);
|
||||
out = outbuf = (unsigned char*)malloc(nr_samples);
|
||||
|
||||
image->comps = (opj_image_comp_t*)realloc(image->comps, (image->numcomps+2)*sizeof(opj_image_comp_t));
|
||||
|
||||
if(image->numcomps == 2)
|
||||
image->comps[3] = image->comps[1];
|
||||
|
||||
image->comps[1] = image->comps[0];
|
||||
image->comps[2] = image->comps[0];
|
||||
|
||||
image->comps[1].data = (int*)calloc((size_t)max, sizeof(int));
|
||||
image->comps[2].data = (int*)calloc((size_t)max, sizeof(int));
|
||||
|
||||
image->numcomps += 2;
|
||||
|
||||
r = image->comps[0].data;
|
||||
|
||||
for(i = 0; i < max; ++i)
|
||||
{
|
||||
*in++ = (unsigned char)*r++;
|
||||
}
|
||||
cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
|
||||
|
||||
r = image->comps[0].data;
|
||||
g = image->comps[1].data;
|
||||
b = image->comps[2].data;
|
||||
|
||||
for(i = 0; i < max; ++i)
|
||||
{
|
||||
*r++ = (int)*out++; *g++ = (int)*out++; *b++ = (int)*out++;
|
||||
}
|
||||
free(inbuf); free(outbuf);
|
||||
|
||||
}/* if(image->numcomps */
|
||||
|
||||
cmsDeleteTransform(transform);
|
||||
|
||||
|
||||
#ifdef HAVE_LIBLCMS1
|
||||
cmsCloseProfile(in_prof);
|
||||
cmsCloseProfile(out_prof);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# Makefile for the MJ2 codecs of the OpenJPEG library: frames_to_mj2, mj2_to_frames, extract_j2k_from_mj2 and wrap_j2k_in_mj2
|
||||
|
||||
if(NOT USE_SYSTEM_GETOPT)
|
||||
SET(common_SRCS ${OPENJPEG_SOURCE_DIR}/applications/common/opj_getopt.c)
|
||||
endif()
|
||||
|
||||
# While mj2 executables do not use the API correctly, we do not link with the library but rather compile the sources files.
|
||||
SET(OPJ_SRCS
|
||||
|
||||
@@ -39,7 +39,9 @@ IF(UNIX)
|
||||
TARGET_LINK_LIBRARIES(${OPENJPEG_LIBRARY_NAME} m)
|
||||
ENDIF(UNIX)
|
||||
SET_TARGET_PROPERTIES(${OPENJPEG_LIBRARY_NAME} PROPERTIES ${OPENJPEG_LIBRARY_PROPERTIES})
|
||||
|
||||
IF(${CMAKE_VERSION} VERSION_GREATER "2.8.11")
|
||||
TARGET_COMPILE_OPTIONS(${OPENJPEG_LIBRARY_NAME} PRIVATE ${OPENJPEG_LIBRARY_COMPILE_OPTIONS})
|
||||
ENDIF()
|
||||
# Build the JPWL library ?
|
||||
IF(BUILD_JPWL)
|
||||
ADD_SUBDIRECTORY(jpwl)
|
||||
|
||||
@@ -43,6 +43,26 @@ The functions in INT.H have for goal to realize operations on integers.
|
||||
/** @name Exported functions (see also openjpeg.h) */
|
||||
/*@{*/
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#if defined(_WIN32)
|
||||
typedef signed __int8 int8_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef signed __int16 int16_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef signed __int32 int32_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef signed __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
#error unsupported platform
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
Get the minimum of two integers
|
||||
@return Returns a if a < b else b
|
||||
@@ -84,15 +104,26 @@ Divide an integer and round upwards
|
||||
@return Returns a divided by b
|
||||
*/
|
||||
static INLINE int int_ceildiv(int a, int b) {
|
||||
return (a + b - 1) / b;
|
||||
assert(b);
|
||||
return (a + b - 1) / b;
|
||||
}
|
||||
|
||||
/**
|
||||
Divide an integer by a power of 2 and round upwards
|
||||
@return Returns a divided by 2^b
|
||||
*/
|
||||
static INLINE int int_ceildivpow2(int a, int b) {
|
||||
return (a + (1 << b) - 1) >> b;
|
||||
return (int)((a + ((int64_t)1 << b) - 1) >> b);
|
||||
}
|
||||
|
||||
/**
|
||||
Divide a 64bits integer by a power of 2 and round upwards
|
||||
@return Returns a divided by 2^b
|
||||
*/
|
||||
static INLINE int int64_ceildivpow2(int64_t a, int b) {
|
||||
return (int)((a + ((int64_t)1 << b) - 1) >> b);
|
||||
}
|
||||
|
||||
/**
|
||||
Divide an integer by a power of 2 and round downwards
|
||||
@return Returns a divided by 2^b
|
||||
|
||||
@@ -247,6 +247,12 @@ Add tile header marker information
|
||||
@param len length of marker segment
|
||||
*/
|
||||
static void j2k_add_tlmarker( int tileno, opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len);
|
||||
/**
|
||||
Validate encoding parameters and image before actual encoding
|
||||
@param j2k J2K handle
|
||||
@param image IMAGE handle
|
||||
*/
|
||||
static opj_bool j2k_validate_encode( opj_j2k_t *j2k, opj_image_t *image);
|
||||
|
||||
/*@}*/
|
||||
|
||||
@@ -426,13 +432,17 @@ static void j2k_read_siz(opj_j2k_t *j2k) {
|
||||
opj_event_msg(j2k->cinfo, EVT_ERROR,
|
||||
"invalid image size (x0:%d, x1:%d, y0:%d, y1:%d)\n",
|
||||
image->x0,image->x1,image->y0,image->y1);
|
||||
j2k->state |= J2K_STATE_ERR;
|
||||
return;
|
||||
}
|
||||
|
||||
n_comps = (len - 36 - 2 ) / 3;
|
||||
assert( (len - 36 - 2 ) % 3 == 0 );
|
||||
image->numcomps = cio_read(cio, 2); /* Csiz */
|
||||
assert( n_comps == image->numcomps );
|
||||
image->numcomps = cio_read(cio, 2); /* Csiz */
|
||||
if (((len - 36 - 2 ) % 3 != 0)||(n_comps != image->numcomps)) {
|
||||
opj_event_msg(j2k->cinfo, EVT_ERROR,"invalid SIZ marker value\n");
|
||||
j2k->state |= J2K_STATE_ERR;
|
||||
return;
|
||||
}
|
||||
|
||||
/* testcase 4035.pdf.SIGSEGV.d8b.3375 */
|
||||
if (image->x0 > image->x1 || image->y0 > image->y1) {
|
||||
@@ -1125,6 +1135,8 @@ static void j2k_read_poc(opj_j2k_t *j2k) {
|
||||
poc->resno0 = cio_read(cio, 1); /* RSpoc_i */
|
||||
poc->compno0 = cio_read(cio, numcomps <= 256 ? 1 : 2); /* CSpoc_i */
|
||||
poc->layno1 = cio_read(cio, 2); /* LYEpoc_i */
|
||||
/* make sure layer end is in acceptable bounds - issue 80*/
|
||||
poc->layno1 = int_min(poc->layno1, (unsigned int) tcp->numlayers);
|
||||
poc->resno1 = cio_read(cio, 1); /* REpoc_i */
|
||||
poc->compno1 = int_min(
|
||||
cio_read(cio, numcomps <= 256 ? 1 : 2), (unsigned int) numcomps); /* CEpoc_i */
|
||||
@@ -1227,6 +1239,7 @@ static void j2k_read_ppm(opj_j2k_t *j2k) {
|
||||
|
||||
Z_ppm = cio_read(cio, 1); /* Z_ppm */
|
||||
len -= 3;
|
||||
|
||||
while (len > 0) {
|
||||
if (cp->ppm_previous == 0) {
|
||||
N_ppm = cio_read(cio, 4); /* N_ppm */
|
||||
@@ -1234,9 +1247,16 @@ static void j2k_read_ppm(opj_j2k_t *j2k) {
|
||||
} else {
|
||||
N_ppm = cp->ppm_previous;
|
||||
}
|
||||
|
||||
/* issue 362-2863, issue 393 */
|
||||
if (N_ppm < 0) {
|
||||
j2k->state = J2K_STATE_ERR;
|
||||
return;
|
||||
}
|
||||
|
||||
j = cp->ppm_store;
|
||||
if (Z_ppm == 0) { /* First PPM marker */
|
||||
cp->ppm_data = (unsigned char *) opj_malloc(N_ppm * sizeof(unsigned char));
|
||||
if (Z_ppm == 0) { /* First PPM marker */
|
||||
cp->ppm_data = (unsigned char *) opj_malloc(N_ppm * sizeof(unsigned char));
|
||||
cp->ppm_data_first = cp->ppm_data;
|
||||
cp->ppm_len = N_ppm;
|
||||
} else { /* NON-first PPM marker */
|
||||
@@ -1710,6 +1730,8 @@ static void j2k_read_eoc(opj_j2k_t *j2k) {
|
||||
}
|
||||
/* if packets should not be decoded */
|
||||
else {
|
||||
opj_event_msg(j2k->cinfo, EVT_INFO, "Codestream parsing complete.\n");
|
||||
opj_event_msg(j2k->cinfo, EVT_INFO, "Skipped actual packet decoding.\n");
|
||||
for (i = 0; i < j2k->cp->tileno_size; i++) {
|
||||
tileno = j2k->cp->tileno[i];
|
||||
opj_free(j2k->tile_data[tileno]);
|
||||
@@ -2448,6 +2470,9 @@ opj_bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_code
|
||||
|
||||
cp = j2k->cp;
|
||||
|
||||
/* Parameters validation */
|
||||
if (!j2k_validate_encode(j2k, image)) return OPJ_FALSE;
|
||||
|
||||
/* INDEX >> */
|
||||
j2k->cstr_info = cstr_info;
|
||||
if (cstr_info) {
|
||||
@@ -2696,3 +2721,21 @@ static void j2k_add_tlmarker( int tileno, opj_codestream_info_t *cstr_info, unsi
|
||||
marker->len = len;
|
||||
cstr_info->tile[tileno].marknum++;
|
||||
}
|
||||
|
||||
static opj_bool j2k_validate_encode(opj_j2k_t *j2k, opj_image_t *image) {
|
||||
|
||||
int compno;
|
||||
opj_bool is_valid = OPJ_TRUE;
|
||||
|
||||
/* preconditions */
|
||||
assert(j2k != 00);
|
||||
assert(image != 00);
|
||||
|
||||
/* PARAMETERS checking */
|
||||
for (compno=0; compno < image->numcomps; compno++) {
|
||||
is_valid &= (image->comps[compno].dx >= 1 && j2k->image->comps[compno].dx <= 255);
|
||||
is_valid &= (image->comps[compno].dy >= 1 && j2k->image->comps[compno].dy <= 255);
|
||||
}
|
||||
|
||||
return is_valid;
|
||||
}
|
||||
|
||||
@@ -26,8 +26,10 @@ ADD_LIBRARY(${OPENJPEG_LIBRARY_NAME}_JPWL ${JPWL_SRCS} ${OPENJPEG_SRCS})
|
||||
IF(UNIX)
|
||||
TARGET_LINK_LIBRARIES(${OPENJPEG_LIBRARY_NAME}_JPWL m)
|
||||
ENDIF(UNIX)
|
||||
SET_TARGET_PROPERTIES(${OPENJPEG_LIBRARY_NAME}_JPWL
|
||||
PROPERTIES ${OPENJPEG_LIBRARY_PROPERTIES})
|
||||
SET_TARGET_PROPERTIES(${OPENJPEG_LIBRARY_NAME}_JPWL PROPERTIES ${OPENJPEG_LIBRARY_PROPERTIES})
|
||||
IF(${CMAKE_VERSION} VERSION_GREATER "2.8.11")
|
||||
TARGET_COMPILE_OPTIONS(${OPENJPEG_LIBRARY_NAME}_JPWL PRIVATE ${OPENJPEG_LIBRARY_COMPILE_OPTIONS})
|
||||
ENDIF()
|
||||
|
||||
# Install library
|
||||
INSTALL(TARGETS ${OPENJPEG_LIBRARY_NAME}_JPWL
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
OpenJPEG interface
|
||||
==========================================================
|
||||
*/
|
||||
#include "opj_config.h"
|
||||
#include "openjpeg.h"
|
||||
|
||||
/*
|
||||
|
||||
@@ -340,12 +340,12 @@ static opj_bool pi_next_cprl(opj_pi_iterator_t * pi) {
|
||||
pi->dx = 0;
|
||||
pi->dy = 0;
|
||||
for (resno = 0; resno < comp->numresolutions; resno++) {
|
||||
int dx, dy;
|
||||
int64 dx, dy;
|
||||
res = &comp->resolutions[resno];
|
||||
dx = comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno));
|
||||
dy = comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno));
|
||||
pi->dx = !pi->dx ? dx : int_min(pi->dx, dx);
|
||||
pi->dy = !pi->dy ? dy : int_min(pi->dy, dy);
|
||||
dx = comp->dx * (((int64) 1) << (res->pdx + comp->numresolutions - 1 - resno));
|
||||
dy = comp->dy * (((int64) 1) << (res->pdy + comp->numresolutions - 1 - resno));
|
||||
pi->dx = !pi->dx ? dx : pi->dx < dx ? pi->dx : dx;
|
||||
pi->dy = !pi->dy ? dy : pi->dy < dy ? pi->dy : dy;
|
||||
}
|
||||
if (!pi->tp_on){
|
||||
pi->poc.ty0 = pi->ty0;
|
||||
|
||||
@@ -93,8 +93,8 @@ typedef struct opj_pi_iterator {
|
||||
int numcomps;
|
||||
/** Components*/
|
||||
opj_pi_comp_t *comps;
|
||||
int tx0, ty0, tx1, ty1;
|
||||
int x, y, dx, dy;
|
||||
int tx0, ty0, tx1, ty1;
|
||||
int64 x, y, dx, dy;
|
||||
} opj_pi_iterator_t;
|
||||
|
||||
/** @name Exported functions */
|
||||
|
||||
@@ -276,10 +276,10 @@ void tcd_malloc_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int c
|
||||
band->y1 = int_ceildivpow2(tilec->y1, levelno);
|
||||
} else {
|
||||
/* band border (global) */
|
||||
band->x0 = int_ceildivpow2(tilec->x0 - (1 << levelno) * x0b, levelno + 1);
|
||||
band->y0 = int_ceildivpow2(tilec->y0 - (1 << levelno) * y0b, levelno + 1);
|
||||
band->x1 = int_ceildivpow2(tilec->x1 - (1 << levelno) * x0b, levelno + 1);
|
||||
band->y1 = int_ceildivpow2(tilec->y1 - (1 << levelno) * y0b, levelno + 1);
|
||||
band->x0 = int64_ceildivpow2(tilec->x0 - ((int64_t)x0b << levelno), levelno + 1);
|
||||
band->y0 = int64_ceildivpow2(tilec->y0 - ((int64_t)y0b << levelno), levelno + 1);
|
||||
band->x1 = int64_ceildivpow2(tilec->x1 - ((int64_t)x0b << levelno), levelno + 1);
|
||||
band->y1 = int64_ceildivpow2(tilec->y1 - ((int64_t)y0b << levelno), levelno + 1);
|
||||
}
|
||||
|
||||
ss = &tccp->stepsizes[resno == 0 ? 0 : 3 * (resno - 1) + bandno + 1];
|
||||
@@ -789,10 +789,10 @@ void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp,
|
||||
band->y1 = int_ceildivpow2(tilec->y1, levelno);
|
||||
} else {
|
||||
/* band border (global) */
|
||||
band->x0 = int_ceildivpow2(tilec->x0 - (1 << levelno) * x0b, levelno + 1);
|
||||
band->y0 = int_ceildivpow2(tilec->y0 - (1 << levelno) * y0b, levelno + 1);
|
||||
band->x1 = int_ceildivpow2(tilec->x1 - (1 << levelno) * x0b, levelno + 1);
|
||||
band->y1 = int_ceildivpow2(tilec->y1 - (1 << levelno) * y0b, levelno + 1);
|
||||
band->x0 = int64_ceildivpow2(tilec->x0 - ((int64_t)x0b << levelno), levelno + 1);
|
||||
band->y0 = int64_ceildivpow2(tilec->y0 - ((int64_t)y0b << levelno), levelno + 1);
|
||||
band->x1 = int64_ceildivpow2(tilec->x1 - ((int64_t)x0b << levelno), levelno + 1);
|
||||
band->y1 = int64_ceildivpow2(tilec->y1 - ((int64_t)y0b << levelno), levelno + 1);
|
||||
}
|
||||
|
||||
ss = &tccp->stepsizes[resno == 0 ? 0 : 3 * (resno - 1) + bandno + 1];
|
||||
@@ -988,7 +988,7 @@ void tcd_makelayer(opj_tcd_t *tcd, int layno, double thresh, int final) {
|
||||
n = passno + 1;
|
||||
continue;
|
||||
}
|
||||
if (dd / dr >= thresh)
|
||||
if (thresh - (dd / dr) < DBL_EPSILON) /* do not rely on float equality, check with DBL_EPSILON margin */
|
||||
n = passno + 1;
|
||||
}
|
||||
layer->numpasses = n - cblk->numpassesinlayers;
|
||||
@@ -1433,10 +1433,12 @@ opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
else {
|
||||
tcd->image->comps[compno].resno_decoded =
|
||||
tile->comps[compno].numresolutions - tcd->cp->reduce - 1;
|
||||
tcd->image->comps[compno].resno_decoded = tile->comps[compno].numresolutions - tcd->cp->reduce - 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
tcd->image->comps[compno].resno_decoded = tile->comps[compno].numresolutions - 1;
|
||||
}
|
||||
|
||||
numres2decode = tcd->image->comps[compno].resno_decoded + 1;
|
||||
if(numres2decode > 0){
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Tests
|
||||
INCLUDE_DIRECTORIES(
|
||||
include_directories(
|
||||
${OPENJPEG_SOURCE_DIR}/libopenjpeg
|
||||
${OPENJPEG_SOURCE_DIR}/applications/codec
|
||||
${OPENJPEG_SOURCE_DIR}/applications/common
|
||||
@@ -9,50 +9,73 @@ INCLUDE_DIRECTORIES(
|
||||
)
|
||||
|
||||
# First thing define the common source:
|
||||
SET(comparePGXimages_SRCS comparePGXimages.c
|
||||
set(compare_images_SRCS compare_images.c
|
||||
${OPENJPEG_SOURCE_DIR}/applications/codec/convert.c
|
||||
${OPENJPEG_SOURCE_DIR}/applications/codec/converttif.c
|
||||
# ${OPENJPEG_SOURCE_DIR}/applications/common/opj_getopt.c
|
||||
)
|
||||
SET(compare_dump_files_SRCS compare_dump_files.c)
|
||||
SET(compareRAWimages_SRCS compareRAWimages.c)
|
||||
|
||||
if(NOT USE_SYSTEM_GETOPT)
|
||||
list(APPEND comparePGXimages_SRCS ${OPENJPEG_SOURCE_DIR}/applications/common/opj_getopt.c)
|
||||
list(APPEND compare_dump_files_SRCS ${OPENJPEG_SOURCE_DIR}/applications/common/opj_getopt.c)
|
||||
list(APPEND compareRAWimages_SRCS ${OPENJPEG_SOURCE_DIR}/applications/common/opj_getopt.c)
|
||||
list(APPEND compare_images_SRCS
|
||||
${OPENJPEG_SOURCE_DIR}/applications/common/opj_getopt.c
|
||||
)
|
||||
endif()
|
||||
|
||||
ADD_EXECUTABLE(comparePGXimages ${comparePGXimages_SRCS})
|
||||
TARGET_LINK_LIBRARIES(comparePGXimages
|
||||
set(compare_dump_files_SRCS compare_dump_files.c
|
||||
#${OPENJPEG_SOURCE_DIR}/applications/common/opj_getopt.c
|
||||
)
|
||||
|
||||
if(NOT USE_SYSTEM_GETOPT)
|
||||
list(APPEND compare_dump_files_SRCS
|
||||
${OPENJPEG_SOURCE_DIR}/applications/common/opj_getopt.c
|
||||
)
|
||||
endif()
|
||||
|
||||
set(compare_raw_files_SRCS compare_raw_files.c
|
||||
#${OPENJPEG_SOURCE_DIR}/applications/common/opj_getopt.c
|
||||
)
|
||||
|
||||
if(NOT USE_SYSTEM_GETOPT)
|
||||
list(APPEND compare_raw_files_SRCS
|
||||
${OPENJPEG_SOURCE_DIR}/applications/common/opj_getopt.c
|
||||
)
|
||||
endif()
|
||||
|
||||
add_executable(compare_images ${compare_images_SRCS})
|
||||
target_link_libraries(compare_images
|
||||
${OPENJPEG_LIBRARY_NAME}
|
||||
${PNG_LIBNAME} ${TIFF_LIBNAME}
|
||||
)
|
||||
# To support universal exe:
|
||||
IF(ZLIB_FOUND AND APPLE)
|
||||
TARGET_LINK_LIBRARIES(comparePGXimages z)
|
||||
ELSe(ZLIB_FOUND AND APPLE)
|
||||
TARGET_LINK_LIBRARIES(comparePGXimages ${Z_LIBNAME})
|
||||
ENDIF(ZLIB_FOUND AND APPLE)
|
||||
if(ZLIB_FOUND AND APPLE)
|
||||
target_link_libraries(compare_images z)
|
||||
else(ZLIB_FOUND AND APPLE)
|
||||
target_link_libraries(compare_images ${Z_LIBNAME})
|
||||
endif()
|
||||
|
||||
ADD_EXECUTABLE(compare_dump_files ${compare_dump_files_SRCS})
|
||||
add_executable(compare_dump_files ${compare_dump_files_SRCS})
|
||||
|
||||
ADD_EXECUTABLE(compareRAWimages ${compareRAWimages_SRCS})
|
||||
add_executable(compare_raw_files ${compare_raw_files_SRCS})
|
||||
|
||||
# No image send to the dashboard if lib PNG is not available.
|
||||
IF(NOT HAVE_LIBPNG)
|
||||
MESSAGE(WARNING "Lib PNG seems to be not available: if you want run the non-regression tests with images reported to the dashboard, you need it (try BUILD_THIRDPARTY)")
|
||||
ENDIF(NOT HAVE_LIBPNG)
|
||||
if(NOT HAVE_LIBPNG)
|
||||
message(WARNING "Lib PNG seems to be not available: if you want run the non-regression tests with images reported to the dashboard, you need it (try BUILD_THIRDPARTY)")
|
||||
endif()
|
||||
|
||||
ADD_SUBDIRECTORY(conformance)
|
||||
ADD_SUBDIRECTORY(nonregression)
|
||||
ADD_SUBDIRECTORY(unit)
|
||||
add_subdirectory(conformance)
|
||||
add_subdirectory(nonregression)
|
||||
add_subdirectory(unit)
|
||||
|
||||
IF(BUILD_JPIP)
|
||||
IF(JPIP_SERVER)
|
||||
#SET(s "http://jpip.example.com/myFCGI?target=16.jp2&fsiz=170,170&cnew=http&type=jpp-stream")
|
||||
SET(s "${JPIP_SERVER}?target=16.jp2&fsiz=170,170&cnew=http&type=jpp-stream")
|
||||
SET(p "${CMAKE_CURRENT_BINARY_DIR}/jpip.dat")
|
||||
SET(md5 "62b00c620fb0a600c5ffd413cada4674")
|
||||
ADD_TEST(NAME TestJPIP1 COMMAND ${CMAKE_COMMAND} -DD_URL:STRING=${s} -DD_FILE:PATH=${p}
|
||||
-DEXPECTED_MD5=${md5} -P ${PROJECT_SOURCE_DIR}/CMake/JPIPTestDriver.cmake)
|
||||
ENDIF(JPIP_SERVER)
|
||||
ENDIF(BUILD_JPIP)
|
||||
if(BUILD_JPIP)
|
||||
if(JPIP_SERVER)
|
||||
#set(s "http://jpip.example.com/myFCGI?target=16.jp2&fsiz=170,170&cnew=http&type=jpp-stream")
|
||||
set(s "${JPIP_SERVER}?target=16.jp2&fsiz=170,170&cnew=http&type=jpp-stream")
|
||||
set(p "${CMAKE_CURRENT_BINARY_DIR}/jpip.dat")
|
||||
set(md5 "d41d8cd98f00b204e9800998ecf8427e")
|
||||
add_test(NAME TestJPIP1 COMMAND ${CMAKE_COMMAND} -DD_URL:STRING=${s} -DD_FILE:PATH=${p}
|
||||
-DEXPECTED_MD5=${md5} -P ${PROJECT_SOURCE_DIR}/cmake/JPIPTestDriver.cmake)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_executable(ppm2rgb3 ppm2rgb3.c)
|
||||
#add_executable(pdf2jp2 pdf2jp2.c)
|
||||
|
||||
@@ -1,236 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Mickael Savinaud, Communications & Systemes <mickael.savinaud@c-s.fr>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* compareRAWimages.c
|
||||
*
|
||||
* Created on: 31 August 2011
|
||||
* Author: mickael
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "opj_getopt.h"
|
||||
|
||||
void compareRAWimages_help_display(void);
|
||||
|
||||
typedef struct test_cmp_parameters
|
||||
{
|
||||
/** */
|
||||
char* base_filename;
|
||||
/** */
|
||||
char* test_filename;
|
||||
} test_cmp_parameters;
|
||||
|
||||
/*******************************************************************************
|
||||
* Command line help function
|
||||
*******************************************************************************/
|
||||
void compareRAWimages_help_display(void) {
|
||||
fprintf(stdout,"\nList of parameters for the comparePGX function \n");
|
||||
fprintf(stdout,"\n");
|
||||
fprintf(stdout," -b \t REQUIRED \t filename to the reference/baseline RAW image \n");
|
||||
fprintf(stdout," -t \t REQUIRED \t filename to the test RAW image\n");
|
||||
fprintf(stdout,"\n");
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Parse command line
|
||||
*******************************************************************************/
|
||||
int parse_cmdline_cmp(int argc, char **argv, test_cmp_parameters* param)
|
||||
{
|
||||
int sizemembasefile, sizememtestfile;
|
||||
int index;
|
||||
const char optlist[] = "b:t:";
|
||||
int c;
|
||||
|
||||
/* Init parameters*/
|
||||
param->base_filename = NULL;
|
||||
param->test_filename = NULL;
|
||||
|
||||
opj_opterr = 0;
|
||||
while ((c = opj_getopt(argc, argv, optlist)) != -1)
|
||||
switch (c)
|
||||
{
|
||||
case 'b':
|
||||
sizemembasefile = (int)strlen(opj_optarg)+1;
|
||||
param->base_filename = (char*) malloc(sizemembasefile);
|
||||
param->base_filename[0] = '\0';
|
||||
strncpy(param->base_filename, opj_optarg, strlen(opj_optarg));
|
||||
param->base_filename[strlen(opj_optarg)] = '\0';
|
||||
/*printf("param->base_filename = %s [%d / %d]\n", param->base_filename, strlen(param->base_filename), sizemembasefile );*/
|
||||
break;
|
||||
case 't':
|
||||
sizememtestfile = (int) strlen(opj_optarg) + 1;
|
||||
param->test_filename = (char*) malloc(sizememtestfile);
|
||||
param->test_filename[0] = '\0';
|
||||
strncpy(param->test_filename, opj_optarg, strlen(opj_optarg));
|
||||
param->test_filename[strlen(opj_optarg)] = '\0';
|
||||
/*printf("param->test_filename = %s [%d / %d]\n", param->test_filename, strlen(param->test_filename), sizememtestfile);*/
|
||||
break;
|
||||
case '?':
|
||||
if ((opj_optopt == 'b') || (opj_optopt == 't'))
|
||||
fprintf(stderr, "Option -%c requires an argument.\n", opj_optopt);
|
||||
else
|
||||
if (isprint(opj_optopt)) fprintf(stderr, "Unknown option `-%c'.\n", opj_optopt);
|
||||
else fprintf(stderr, "Unknown option character `\\x%x'.\n", opj_optopt);
|
||||
return 1;
|
||||
default:
|
||||
fprintf(stderr, "WARNING -> this option is not valid \"-%c %s\"\n", c, opj_optarg);
|
||||
break;
|
||||
}
|
||||
|
||||
if (opj_optind != argc) {
|
||||
for (index = opj_optind; index < argc; index++)
|
||||
fprintf(stderr,"Non-option argument %s\n", argv[index]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* MAIN
|
||||
*******************************************************************************/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
test_cmp_parameters inParam;
|
||||
FILE *file_test=NULL, *file_base=NULL;
|
||||
unsigned char equal = 1;
|
||||
|
||||
/* Get parameters from command line*/
|
||||
if (parse_cmdline_cmp(argc, argv, &inParam) == EXIT_FAILURE)
|
||||
{
|
||||
compareRAWimages_help_display();
|
||||
|
||||
/* Free Memory */
|
||||
if (inParam.base_filename){
|
||||
free(inParam.base_filename);
|
||||
inParam.base_filename = NULL;
|
||||
}
|
||||
if (inParam.test_filename){
|
||||
free(inParam.test_filename);
|
||||
inParam.test_filename = NULL;
|
||||
}
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
file_test = fopen(inParam.test_filename, "rb");
|
||||
if (!file_test) {
|
||||
fprintf(stderr, "Failed to open %s for reading !!\n", inParam.test_filename);
|
||||
|
||||
/* Free Memory */
|
||||
if (inParam.base_filename){
|
||||
free(inParam.base_filename);
|
||||
inParam.base_filename = NULL;
|
||||
}
|
||||
if (inParam.test_filename){
|
||||
free(inParam.test_filename);
|
||||
inParam.test_filename = NULL;
|
||||
}
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
file_base = fopen(inParam.base_filename, "rb");
|
||||
if (!file_base) {
|
||||
fprintf(stderr, "Failed to open %s for reading !!\n", inParam.base_filename);
|
||||
|
||||
/* Free Memory */
|
||||
if (inParam.base_filename){
|
||||
free(inParam.base_filename);
|
||||
inParam.base_filename = NULL;
|
||||
}
|
||||
if (inParam.test_filename){
|
||||
free(inParam.test_filename);
|
||||
inParam.test_filename = NULL;
|
||||
}
|
||||
|
||||
fclose(file_test);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Read simultaneously the two files*/
|
||||
while (equal)
|
||||
{
|
||||
unsigned char value_test = 0;
|
||||
unsigned char eof_test = 0;
|
||||
unsigned char value_base = 0;
|
||||
unsigned char eof_base = 0;
|
||||
|
||||
/* Read one byte*/
|
||||
if (!fread(&value_test, 1, 1, file_test)) {
|
||||
eof_test = 1;
|
||||
}
|
||||
|
||||
/* Read one byte*/
|
||||
if (!fread(&value_base, 1, 1, file_base)) {
|
||||
eof_base = 1;;
|
||||
}
|
||||
|
||||
/* End of file reached by the two files?*/
|
||||
if (eof_test && eof_base)
|
||||
break;
|
||||
|
||||
/* End of file reached only by one file?*/
|
||||
if (eof_test || eof_base)
|
||||
{
|
||||
fprintf(stdout,"Files have different sizes.\n");
|
||||
equal = 0;
|
||||
}
|
||||
|
||||
/* Binary values are equal?*/
|
||||
if (value_test != value_base)
|
||||
{
|
||||
fprintf(stdout,"Binary values read in the file are different.\n");
|
||||
equal = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Free Memory */
|
||||
if (inParam.base_filename){
|
||||
free(inParam.base_filename);
|
||||
inParam.base_filename = NULL;
|
||||
}
|
||||
if (inParam.test_filename){
|
||||
free(inParam.test_filename);
|
||||
inParam.test_filename = NULL;
|
||||
}
|
||||
|
||||
fclose(file_test);
|
||||
fclose(file_base);
|
||||
|
||||
if (equal)
|
||||
{
|
||||
fprintf(stdout,"---- TEST SUCCEED: Files are equal ----\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
else
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Mickael Savinaud, Communications & Systemes <mickael.savinaud@c-s.fr>
|
||||
* Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -29,13 +29,13 @@
|
||||
*
|
||||
* Created on: 25 juil. 2011
|
||||
* Author: mickael
|
||||
* BASELINE MUST BE GENERATED BY UNIX PLATFORM REGARDING TO THE CRLF PROBLEM
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "opj_getopt.h"
|
||||
|
||||
@@ -50,7 +50,7 @@ typedef struct test_cmp_parameters
|
||||
/*******************************************************************************
|
||||
* Command line help function
|
||||
*******************************************************************************/
|
||||
void compare_dump_files_help_display(void) {
|
||||
static void compare_dump_files_help_display(void) {
|
||||
fprintf(stdout,"\nList of parameters for the compare_dump_files function \n");
|
||||
fprintf(stdout,"\n");
|
||||
fprintf(stdout," -b \t REQUIRED \t filename to the reference/baseline dump file \n");
|
||||
@@ -60,9 +60,9 @@ void compare_dump_files_help_display(void) {
|
||||
/*******************************************************************************
|
||||
* Parse command line
|
||||
*******************************************************************************/
|
||||
int parse_cmdline_cmp(int argc, char **argv, test_cmp_parameters* param)
|
||||
static int parse_cmdline_cmp(int argc, char **argv, test_cmp_parameters* param)
|
||||
{
|
||||
int sizemembasefile, sizememtestfile;
|
||||
size_t sizemembasefile, sizememtestfile;
|
||||
int index;
|
||||
const char optlist[] = "b:t:";
|
||||
int c;
|
||||
@@ -76,43 +76,40 @@ int parse_cmdline_cmp(int argc, char **argv, test_cmp_parameters* param)
|
||||
while ((c = opj_getopt(argc, argv, optlist)) != -1)
|
||||
switch (c)
|
||||
{
|
||||
case 'b':
|
||||
sizemembasefile = (int)strlen(opj_optarg)+1;
|
||||
param->base_filename = (char*) malloc(sizemembasefile);
|
||||
param->base_filename[0] = '\0';
|
||||
strncpy(param->base_filename, opj_optarg, strlen(opj_optarg));
|
||||
param->base_filename[strlen(opj_optarg)] = '\0';
|
||||
/*printf("param->base_filename = %s [%d / %d]\n", param->base_filename, strlen(param->base_filename), sizemembasefile );*/
|
||||
break;
|
||||
case 't':
|
||||
sizememtestfile = (int) strlen(opj_optarg) + 1;
|
||||
param->test_filename = (char*) malloc(sizememtestfile);
|
||||
param->test_filename[0] = '\0';
|
||||
strncpy(param->test_filename, opj_optarg, strlen(opj_optarg));
|
||||
param->test_filename[strlen(opj_optarg)] = '\0';
|
||||
/*printf("param->test_filename = %s [%d / %d]\n", param->test_filename, strlen(param->test_filename), sizememtestfile);*/
|
||||
break;
|
||||
case '?':
|
||||
if ( (opj_optopt == 'b') || (opj_optopt == 't') )
|
||||
fprintf(stderr, "Option -%c requires an argument.\n", opj_optopt);
|
||||
else
|
||||
if (isprint(opj_optopt)) fprintf(stderr, "Unknown option `-%c'.\n", opj_optopt);
|
||||
else fprintf(stderr, "Unknown option character `\\x%x'.\n", opj_optopt);
|
||||
return 1;
|
||||
default:
|
||||
fprintf(stderr, "WARNING -> this option is not valid \"-%c %s\"\n", c, opj_optarg);
|
||||
break;
|
||||
case 'b':
|
||||
sizemembasefile = strlen(opj_optarg) + 1;
|
||||
param->base_filename = (char*) malloc(sizemembasefile);
|
||||
strcpy(param->base_filename, opj_optarg);
|
||||
/*printf("param->base_filename = %s [%d / %d]\n", param->base_filename, strlen(param->base_filename), sizemembasefile );*/
|
||||
break;
|
||||
case 't':
|
||||
sizememtestfile = strlen(opj_optarg) + 1;
|
||||
param->test_filename = (char*) malloc(sizememtestfile);
|
||||
strcpy(param->test_filename, opj_optarg);
|
||||
/*printf("param->test_filename = %s [%d / %d]\n", param->test_filename, strlen(param->test_filename), sizememtestfile);*/
|
||||
break;
|
||||
case '?':
|
||||
if ( (opj_optopt == 'b') || (opj_optopt == 't') )
|
||||
fprintf(stderr, "Option -%c requires an argument.\n", opj_optopt);
|
||||
else
|
||||
if (isprint(opj_optopt)) fprintf(stderr, "Unknown option `-%c'.\n", opj_optopt);
|
||||
else fprintf(stderr, "Unknown option character `\\x%x'.\n", opj_optopt);
|
||||
return 1;
|
||||
default:
|
||||
fprintf(stderr, "WARNING -> this option is not valid \"-%c %s\"\n", c, opj_optarg);
|
||||
break;
|
||||
}
|
||||
|
||||
if (opj_optind != argc)
|
||||
{
|
||||
for (index = opj_optind; index < argc; index++)
|
||||
fprintf(stderr,"Non-option argument %s\n", argv[index]);
|
||||
return EXIT_FAILURE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* MAIN
|
||||
*******************************************************************************/
|
||||
@@ -120,33 +117,30 @@ int main(int argc, char **argv)
|
||||
{
|
||||
test_cmp_parameters inParam;
|
||||
FILE *fbase=NULL, *ftest=NULL;
|
||||
int chbase, chtest;
|
||||
int same = 1;
|
||||
unsigned long l=1, pos;
|
||||
int same = 0;
|
||||
char lbase[256];
|
||||
char strbase[256];
|
||||
char ltest[256];
|
||||
char strtest[256];
|
||||
|
||||
if( parse_cmdline_cmp(argc, argv, &inParam) == EXIT_FAILURE )
|
||||
if( parse_cmdline_cmp(argc, argv, &inParam) == 1 )
|
||||
{
|
||||
compare_dump_files_help_display();
|
||||
if (!inParam.base_filename) free(inParam.base_filename);
|
||||
if (!inParam.test_filename) free(inParam.test_filename);
|
||||
return EXIT_FAILURE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Display Parameters*/
|
||||
printf("******Parameters********* \n");
|
||||
printf(" base_filename = %s\n"
|
||||
" test_filename = %s\n",
|
||||
inParam.base_filename, inParam.test_filename);
|
||||
" test_filename = %s\n",
|
||||
inParam.base_filename, inParam.test_filename);
|
||||
printf("************************* \n");
|
||||
|
||||
/* open base file */
|
||||
printf("Try to open: %s for reading ... ", inParam.base_filename);
|
||||
if((fbase = fopen(inParam.base_filename, "rb"))==NULL)
|
||||
{
|
||||
printf("Failed.\n");
|
||||
free(inParam.base_filename);
|
||||
free(inParam.test_filename);
|
||||
return EXIT_FAILURE;
|
||||
goto cleanup;
|
||||
}
|
||||
printf("Ok.\n");
|
||||
|
||||
@@ -154,105 +148,37 @@ int main(int argc, char **argv)
|
||||
printf("Try to open: %s for reading ... ", inParam.test_filename);
|
||||
if((ftest = fopen(inParam.test_filename, "rb"))==NULL)
|
||||
{
|
||||
printf("Failed.\n");
|
||||
fclose(fbase);
|
||||
free(inParam.base_filename);
|
||||
free(inParam.test_filename);
|
||||
return EXIT_FAILURE;
|
||||
goto cleanup;
|
||||
}
|
||||
printf("Ok.\n");
|
||||
|
||||
pos=ftell(fbase);
|
||||
|
||||
while(!feof(fbase))
|
||||
while (fgets(lbase, sizeof(lbase), fbase) && fgets(ltest,sizeof(ltest),ftest))
|
||||
{
|
||||
chbase = fgetc(fbase);
|
||||
if(ferror(fbase))
|
||||
int nbase = sscanf(lbase, "%255[^\r\n]", strbase);
|
||||
int ntest = sscanf(ltest, "%255[^\r\n]", strtest);
|
||||
assert( nbase != 255 && ntest != 255 );
|
||||
if( nbase != 1 || ntest != 1 )
|
||||
{
|
||||
printf("Error reading base file.\n");
|
||||
return EXIT_FAILURE;
|
||||
fprintf(stderr, "could not parse line from files\n" );
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
chtest = fgetc(ftest);
|
||||
if(ferror(ftest))
|
||||
if( strcmp( strbase, strtest ) != 0 )
|
||||
{
|
||||
printf("Error reading test file.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* CRLF problem (Baseline must be always generated by unix platform)*/
|
||||
if (chbase == '\n' && chtest == '\r')
|
||||
if (fgetc(ftest) == '\n')
|
||||
chtest = '\n';
|
||||
|
||||
if(chbase != chtest)
|
||||
{
|
||||
size_t nbytes = 2048;
|
||||
int CRLF_shift=1;
|
||||
char *strbase, *strtest, *strbase_d, *strtest_d;
|
||||
|
||||
printf("Files differ at line %lu:\n", l);
|
||||
fseek(fbase,pos,SEEK_SET);
|
||||
|
||||
/* Take into account CRLF characters when we write \n into
|
||||
// dump file when we used WIN platform*/
|
||||
#ifdef _WIN32
|
||||
CRLF_shift = 2;
|
||||
fseek(ftest,pos + l - 1,SEEK_SET);
|
||||
#else
|
||||
fseek(ftest,pos,SEEK_SET);
|
||||
#endif
|
||||
|
||||
strbase = (char *) malloc(nbytes + 1);
|
||||
strtest = (char *) malloc(nbytes + 1);
|
||||
|
||||
if (fgets(strbase, nbytes, fbase) == NULL)
|
||||
fprintf(stderr,"\nWARNING: fgets return a NULL value");
|
||||
else
|
||||
{
|
||||
if (fgets(strtest, nbytes, ftest) == NULL)
|
||||
fprintf(stderr,"\nWARNING: fgets return a NULL value");
|
||||
else
|
||||
{
|
||||
strbase_d = (char *) malloc(strlen(strbase)+1);
|
||||
strtest_d = (char *) malloc(strlen(strtest)+1);
|
||||
strncpy(strbase_d, strbase, strlen(strbase)-1);
|
||||
strncpy(strtest_d, strtest, strlen(strtest)-CRLF_shift);
|
||||
strbase_d[strlen(strbase)-1] = '\0';
|
||||
strtest_d[strlen(strtest)-CRLF_shift] = '\0';
|
||||
printf("<%s> vs. <%s>\n", strbase_d, strtest_d);
|
||||
free(strbase_d);free(strtest_d);
|
||||
}
|
||||
}
|
||||
|
||||
free(strbase);free(strtest);
|
||||
|
||||
same = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (chbase == '\n')
|
||||
{
|
||||
l++;
|
||||
pos = ftell(fbase);
|
||||
}
|
||||
fprintf(stderr,"<%s> vs. <%s>\n", strbase, strtest);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
same = 1;
|
||||
printf("\n***** TEST SUCCEED: Files are the same. *****\n");
|
||||
cleanup:
|
||||
/*Close File*/
|
||||
fclose(fbase);
|
||||
fclose(ftest);
|
||||
if(fbase) fclose(fbase);
|
||||
if(ftest) fclose(ftest);
|
||||
|
||||
/* Free memory*/
|
||||
free(inParam.base_filename);
|
||||
free(inParam.test_filename);
|
||||
|
||||
if(same)
|
||||
{
|
||||
printf("\n***** TEST SUCCEED: Files are the same. *****\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
else return EXIT_FAILURE;
|
||||
return same ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
193
tests/compare_raw_files.c
Normal file
193
tests/compare_raw_files.c
Normal file
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* compare_raw_files.c
|
||||
*
|
||||
* Created on: 31 August 2011
|
||||
* Author: mickael
|
||||
*
|
||||
* This is equivalent to the UNIX `cmp` command
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "opj_getopt.h"
|
||||
|
||||
typedef struct test_cmp_parameters
|
||||
{
|
||||
/** */
|
||||
char* base_filename;
|
||||
/** */
|
||||
char* test_filename;
|
||||
} test_cmp_parameters;
|
||||
|
||||
/*******************************************************************************
|
||||
* Command line help function
|
||||
*******************************************************************************/
|
||||
static void compare_raw_files_help_display(void) {
|
||||
fprintf(stdout,"\nList of parameters for the compare_raw_files function \n");
|
||||
fprintf(stdout,"\n");
|
||||
fprintf(stdout," -b \t REQUIRED \t filename to the reference/baseline RAW image \n");
|
||||
fprintf(stdout," -t \t REQUIRED \t filename to the test RAW image\n");
|
||||
fprintf(stdout,"\n");
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Parse command line
|
||||
*******************************************************************************/
|
||||
static int parse_cmdline_cmp(int argc, char **argv, test_cmp_parameters* param)
|
||||
{
|
||||
size_t sizemembasefile, sizememtestfile;
|
||||
int index;
|
||||
const char optlist[] = "b:t:";
|
||||
int c;
|
||||
|
||||
/* Init parameters*/
|
||||
param->base_filename = NULL;
|
||||
param->test_filename = NULL;
|
||||
|
||||
opj_opterr = 0;
|
||||
while ((c = opj_getopt(argc, argv, optlist)) != -1)
|
||||
switch (c)
|
||||
{
|
||||
case 'b':
|
||||
sizemembasefile = strlen(opj_optarg)+1;
|
||||
free(param->base_filename); /* handle dup option */
|
||||
param->base_filename = (char*) malloc(sizemembasefile);
|
||||
strcpy(param->base_filename, opj_optarg);
|
||||
/*printf("param->base_filename = %s [%d / %d]\n", param->base_filename, strlen(param->base_filename), sizemembasefile );*/
|
||||
break;
|
||||
case 't':
|
||||
sizememtestfile = strlen(opj_optarg) + 1;
|
||||
free(param->test_filename); /* handle dup option */
|
||||
param->test_filename = (char*) malloc(sizememtestfile);
|
||||
strcpy(param->test_filename, opj_optarg);
|
||||
/*printf("param->test_filename = %s [%d / %d]\n", param->test_filename, strlen(param->test_filename), sizememtestfile);*/
|
||||
break;
|
||||
case '?':
|
||||
if ((opj_optopt == 'b') || (opj_optopt == 't'))
|
||||
fprintf(stderr, "Option -%c requires an argument.\n", opj_optopt);
|
||||
else
|
||||
if (isprint(opj_optopt)) fprintf(stderr, "Unknown option `-%c'.\n", opj_optopt);
|
||||
else fprintf(stderr, "Unknown option character `\\x%x'.\n", opj_optopt);
|
||||
return 1;
|
||||
default:
|
||||
fprintf(stderr, "WARNING -> this option is not valid \"-%c %s\"\n", c, opj_optarg);
|
||||
break;
|
||||
}
|
||||
|
||||
if (opj_optind != argc) {
|
||||
for (index = opj_optind; index < argc; index++)
|
||||
fprintf(stderr,"Non-option argument %s\n", argv[index]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* MAIN
|
||||
*******************************************************************************/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int pos = 0;
|
||||
test_cmp_parameters inParam;
|
||||
FILE *file_test=NULL, *file_base=NULL;
|
||||
unsigned char equal = 0U; /* returns error by default */
|
||||
|
||||
/* Get parameters from command line*/
|
||||
if (parse_cmdline_cmp(argc, argv, &inParam))
|
||||
{
|
||||
compare_raw_files_help_display();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
file_test = fopen(inParam.test_filename, "rb");
|
||||
if (!file_test) {
|
||||
fprintf(stderr, "Failed to open %s for reading !!\n", inParam.test_filename);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
file_base = fopen(inParam.base_filename, "rb");
|
||||
if (!file_base) {
|
||||
fprintf(stderr, "Failed to open %s for reading !!\n", inParam.base_filename);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Read simultaneously the two files*/
|
||||
equal = 1U;
|
||||
while (equal)
|
||||
{
|
||||
unsigned char value_test = 0;
|
||||
unsigned char eof_test = 0;
|
||||
unsigned char value_base = 0;
|
||||
unsigned char eof_base = 0;
|
||||
|
||||
/* Read one byte*/
|
||||
if (!fread(&value_test, 1, 1, file_test)) {
|
||||
eof_test = 1;
|
||||
}
|
||||
|
||||
/* Read one byte*/
|
||||
if (!fread(&value_base, 1, 1, file_base)) {
|
||||
eof_base = 1;
|
||||
}
|
||||
|
||||
/* End of file reached by the two files?*/
|
||||
if (eof_test && eof_base)
|
||||
break;
|
||||
|
||||
/* End of file reached only by one file?*/
|
||||
if (eof_test || eof_base)
|
||||
{
|
||||
fprintf(stdout,"Files have different sizes.\n");
|
||||
equal = 0;
|
||||
}
|
||||
|
||||
/* Binary values are equal?*/
|
||||
if (value_test != value_base)
|
||||
{
|
||||
fprintf(stdout,"Binary values read in the file are different %x vs %x at position %d.\n", value_test, value_base, pos);
|
||||
equal = 0;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
|
||||
if(equal) fprintf(stdout,"---- TEST SUCCEED: Files are equal ----\n");
|
||||
cleanup:
|
||||
if(file_test) fclose(file_test);
|
||||
if(file_base) fclose(file_base);
|
||||
|
||||
/* Free Memory */
|
||||
free(inParam.base_filename);
|
||||
free(inParam.test_filename);
|
||||
|
||||
return equal ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,7 @@
|
||||
# NON-REGRESSION TESTS ON THIS DATASET LOCATED ${OPJ_DATA_ROOT}/input/nonregression
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.7)
|
||||
|
||||
FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Temporary)
|
||||
|
||||
SET(TEMP ${CMAKE_CURRENT_BINARY_DIR}/Temporary)
|
||||
@@ -8,19 +10,130 @@ SET(INPUT_NR ${OPJ_DATA_ROOT}/input/nonregression)
|
||||
|
||||
SET(INPUT_NR_PATH ${INPUT_NR})
|
||||
SET(TEMP_PATH ${TEMP})
|
||||
set(INPUT_CONF_PATH ${OPJ_DATA_ROOT}/input/conformance)
|
||||
|
||||
# need kdu_expand if possible
|
||||
find_package(KAKADU)
|
||||
# need jpylyzer if possible
|
||||
find_package(JPYLYZER)
|
||||
|
||||
#########################################################################
|
||||
# GENERATION OF THE TEST SUITE
|
||||
# GENERATION OF THE TEST SUITE (DUMP)
|
||||
# Dump all files with the selected extension inside the input directory
|
||||
|
||||
# technically j2k_dump should simply parse these one, since syntax is ok.
|
||||
set(BLACKLIST_JPEG2000_TMP
|
||||
2539.pdf.SIGFPE.706.1712.jp2
|
||||
0290cb77c5df21828fa74cf2ab2c84d8.SIGFPE.d25.31.jp2
|
||||
26ccf3651020967f7778238ef5af08af.SIGFPE.d25.527.jp2
|
||||
4035.pdf.SIGSEGV.d8b.3375.jp2
|
||||
3635.pdf.asan.77.2930.jp2
|
||||
issue165.jp2
|
||||
#edf_c2_1103421.jp2
|
||||
edf_c2_1178956.jp2
|
||||
edf_c2_1000290.jp2
|
||||
#edf_c2_1000691.jp2 # ok
|
||||
#edf_c2_20.jp2 #looks ok as per kdu_jp2info
|
||||
edf_c2_1377017.jp2
|
||||
edf_c2_1002767.jp2
|
||||
#edf_c2_10025.jp2
|
||||
edf_c2_1000234.jp2
|
||||
edf_c2_225881.jp2
|
||||
edf_c2_1000671.jp2
|
||||
#edf_c2_1013627.jp2 # weird box, but kdu_jp2info ok
|
||||
edf_c2_1015644.jp2
|
||||
edf_c2_101463.jp2
|
||||
edf_c2_1674177.jp2
|
||||
edf_c2_1673169.jp2
|
||||
issue429.jp2
|
||||
issue427-null-image-size.jp2
|
||||
issue427-illegal-tile-offset.jp2
|
||||
)
|
||||
|
||||
# Define a list of file which should be gracefully rejected:
|
||||
set(BLACKLIST_JPEG2000
|
||||
${BLACKLIST_JPEG2000_TMP}
|
||||
broken1.jp2
|
||||
broken2.jp2
|
||||
broken3.jp2
|
||||
broken4.jp2
|
||||
gdal_fuzzer_assert_in_opj_j2k_read_SQcd_SQcc.patch.jp2
|
||||
gdal_fuzzer_check_comp_dx_dy.jp2
|
||||
gdal_fuzzer_check_number_of_tiles.jp2
|
||||
gdal_fuzzer_unchecked_numresolutions.jp2
|
||||
mem-b2ace68c-1381.jp2
|
||||
1851.pdf.SIGSEGV.ce9.948.jp2
|
||||
1888.pdf.asan.35.988.jp2
|
||||
issue362-2863.jp2 #kdu_jp2info ok
|
||||
issue362-2866.jp2
|
||||
issue362-2894.jp2
|
||||
issue400.jp2 #kdu_jp2info ok
|
||||
issue364-38.jp2
|
||||
issue364-903.jp2 #kdu_jp2info ok
|
||||
issue393.jp2 #kdu_jp2info ok
|
||||
issue408.jp2 #kdu_jp2info ok
|
||||
issue420.jp2 #kdu_jp2info ok
|
||||
27ac957758a35d00d6765a0c86350d9c.SIGFPE.d25.537.jpc #kdu_jp2info crash
|
||||
3672da2f1f67bbecad27d7181b4e9d7c.SIGFPE.d25.805.jpc #kdu_jp2info crash
|
||||
issue476.jp2 #kdu_jp2info ok
|
||||
issue475.jp2 #kdu_jp2info ok
|
||||
issue413.jp2 #kdu_jp2info ok
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE OPJ_DATA_NR_LIST
|
||||
"${INPUT_NR}/*.j2k"
|
||||
"${INPUT_NR}/*.j2c"
|
||||
"${INPUT_NR}/*.jp2"
|
||||
"${INPUT_NR}/*.jpc"
|
||||
#"${INPUT_NR}/*.jpx"
|
||||
)
|
||||
|
||||
foreach(INPUT_FILENAME ${OPJ_DATA_NR_LIST})
|
||||
get_filename_component(INPUT_FILENAME_NAME ${INPUT_FILENAME} NAME)
|
||||
#get_filename_component(INPUT_FILENAME_NAME_WE ${INPUT_FILENAME_NAME} NAME_WE)
|
||||
# cannot use longest extension function, since some name contains multiples
|
||||
# dots. Instead write out own shortest extension function:
|
||||
string(FIND ${INPUT_FILENAME_NAME} "." SHORTEST_EXT_POS REVERSE)
|
||||
string(SUBSTRING ${INPUT_FILENAME_NAME} 0 ${SHORTEST_EXT_POS} INPUT_FILENAME_NAME_WE)
|
||||
string(REGEX MATCH ${INPUT_FILENAME_NAME} bad_jpeg2000 ${BLACKLIST_JPEG2000})
|
||||
|
||||
# Dump the input image
|
||||
add_test(NAME NR-${INPUT_FILENAME_NAME}-dump
|
||||
COMMAND j2k_dump
|
||||
-i ${INPUT_FILENAME}
|
||||
-o ${TEMP}/${INPUT_FILENAME_NAME}.txt
|
||||
)
|
||||
|
||||
if(bad_jpeg2000)
|
||||
set_tests_properties(NR-${INPUT_FILENAME_NAME}-dump
|
||||
PROPERTIES WILL_FAIL TRUE)
|
||||
|
||||
else()
|
||||
|
||||
# Compare the dump output with the baseline
|
||||
add_test(NAME NR-${INPUT_FILENAME_NAME}-compare_dump2base
|
||||
COMMAND compare_dump_files
|
||||
-b ${BASELINE_NR}/opj_${INPUT_FILENAME_NAME_WE}.txt
|
||||
-t ${TEMP}/${INPUT_FILENAME_NAME}.txt
|
||||
)
|
||||
|
||||
set_tests_properties(NR-${INPUT_FILENAME_NAME}-compare_dump2base
|
||||
PROPERTIES DEPENDS
|
||||
NR-${INPUT_FILENAME_NAME}-dump)
|
||||
endif()
|
||||
|
||||
endforeach()
|
||||
|
||||
|
||||
#########################################################################
|
||||
# GENERATION OF THE TEST SUITE (DECODE AND ENCODE)
|
||||
# Read one and more input file(s) (located in ${OPJ_DATA_ROOT}/input/nonregression)
|
||||
# to know which files processed and with which options.
|
||||
|
||||
# Configure the test suite file:
|
||||
CONFIGURE_FILE("test_suite.ctest.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/test_suite.ctest"
|
||||
@ONLY)
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/test_suite.ctest"
|
||||
@ONLY)
|
||||
|
||||
# Read the file into a list
|
||||
FILE(STRINGS ${CMAKE_CURRENT_BINARY_DIR}/test_suite.ctest OPJ_TEST_CMD_LINE_LIST)
|
||||
@@ -29,22 +142,23 @@ FILE(STRINGS ${CMAKE_CURRENT_BINARY_DIR}/test_suite.ctest OPJ_TEST_CMD_LINE_LIST
|
||||
FILE(GLOB TEST_SUITE_FILES *.ctest.in)
|
||||
IF (TEST_SUITE_FILES)
|
||||
FOREACH(TEST_SUITE_FILE ${TEST_SUITE_FILES})
|
||||
|
||||
|
||||
# Avoid to process the official test suite
|
||||
SET(FILE_ALREADY_READ 0)
|
||||
STRING(REGEX MATCH "test_suite.ctest.in$" FILE_ALREADY_READ ${TEST_SUITE_FILE})
|
||||
|
||||
get_filename_component(TEST_SUITE_FILENAME ${TEST_SUITE_FILE} NAME)
|
||||
string(REGEX MATCH "^test_suite.ctest.in$" FILE_ALREADY_READ ${TEST_SUITE_FILENAME})
|
||||
|
||||
IF(NOT FILE_ALREADY_READ)
|
||||
# Configure the additional test suite file:
|
||||
GET_FILENAME_COMPONENT(TEST_SUITE_FILE_SUB ${TEST_SUITE_FILE} NAME_WE)
|
||||
CONFIGURE_FILE("${TEST_SUITE_FILE}"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${TEST_SUITE_FILE_SUB}.ctest"
|
||||
@ONLY)
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${TEST_SUITE_FILE_SUB}.ctest"
|
||||
@ONLY)
|
||||
# Read the additional file into a list
|
||||
FILE(STRINGS ${CMAKE_CURRENT_BINARY_DIR}/${TEST_SUITE_FILE_SUB}.ctest OPJ_TEST_CMD_LINE_LIST_TEMP)
|
||||
# Append the list of command
|
||||
SET(OPJ_TEST_CMD_LINE_LIST ${OPJ_TEST_CMD_LINE_LIST} ${OPJ_TEST_CMD_LINE_LIST_TEMP})
|
||||
|
||||
|
||||
ENDIF(NOT FILE_ALREADY_READ)
|
||||
|
||||
ENDFOREACH(TEST_SUITE_FILE)
|
||||
@@ -56,11 +170,12 @@ ELSE(TEST_SUITE_FILES)
|
||||
ENDIF(TEST_SUITE_FILES)
|
||||
|
||||
|
||||
set(nonregression_filenames_used)
|
||||
# Parse the command line found in the file(s)
|
||||
SET(IT_TEST_ENC 0)
|
||||
SET(IT_TEST_DEC 0)
|
||||
FOREACH(OPJ_TEST_CMD_LINE ${OPJ_TEST_CMD_LINE_LIST})
|
||||
|
||||
|
||||
SET(IGNORE_LINE_FOUND 0)
|
||||
|
||||
# Replace space by ; to generate a list
|
||||
@@ -68,40 +183,43 @@ FOREACH(OPJ_TEST_CMD_LINE ${OPJ_TEST_CMD_LINE_LIST})
|
||||
|
||||
# Check if the first argument begin by the comment sign
|
||||
LIST(GET CMD_ARG_LIST 0 EXE_NAME)
|
||||
STRING(REGEX MATCH "^#" IGNORE_LINE_FOUND ${EXE_NAME})
|
||||
|
||||
IF(IGNORE_LINE_FOUND)
|
||||
|
||||
|
||||
if(EXE_NAME)
|
||||
STRING(REGEX MATCH "^#" IGNORE_LINE_FOUND ${EXE_NAME})
|
||||
endif()
|
||||
|
||||
IF(IGNORE_LINE_FOUND OR NOT EXE_NAME)
|
||||
|
||||
#MESSAGE( STATUS "Current line is ignored: ${OPJ_TEST_CMD_LINE}")
|
||||
|
||||
|
||||
ELSE(IGNORE_LINE_FOUND)
|
||||
|
||||
|
||||
# Check if the first argument begin by the failed sign
|
||||
SET(FAILED_TEST_FOUND 0)
|
||||
STRING(REGEX MATCH "^!" FAILED_TEST_FOUND ${EXE_NAME})
|
||||
|
||||
|
||||
IF (FAILED_TEST_FOUND)
|
||||
# Manage the different cases with the failed sign to remove the first argument which must be image_to_j2k
|
||||
SET(FAILED_TEST_FOUND_1 0)
|
||||
STRING(REGEX MATCH "^!image_to_j2k$|^!j2k_to_image$" FAILED_TEST_FOUND_1 ${EXE_NAME})
|
||||
|
||||
IF (FAILED_TEST_FOUND_1)
|
||||
|
||||
|
||||
LIST(REMOVE_AT CMD_ARG_LIST 0)
|
||||
|
||||
|
||||
ELSE (FAILED_TEST_FOUND_1)
|
||||
|
||||
|
||||
SET(FAILED_TEST_FOUND_2 0)
|
||||
LIST(GET CMD_ARG_LIST 1 EXE_NAME)
|
||||
STRING(REGEX MATCH "^image_to_j2k$|^j2k_to_image$" FAILED_TEST_FOUND_2 ${EXE_NAME})
|
||||
|
||||
|
||||
IF (FAILED_TEST_FOUND_2)
|
||||
|
||||
|
||||
LIST(REMOVE_AT CMD_ARG_LIST 0)
|
||||
LIST(REMOVE_AT CMD_ARG_LIST 0)
|
||||
|
||||
|
||||
ELSE (FAILED_TEST_FOUND_2)
|
||||
|
||||
|
||||
MESSAGE( FATAL_ERROR "${EXE_NAME} is not the right executable name to encode file (try to use image_to_j2k or j2k_to_image)")
|
||||
|
||||
ENDIF (FAILED_TEST_FOUND_2)
|
||||
@@ -112,11 +230,11 @@ FOREACH(OPJ_TEST_CMD_LINE ${OPJ_TEST_CMD_LINE_LIST})
|
||||
STRING(REGEX MATCH "^image_to_j2k$|^j2k_to_image$" EXE_NAME_FOUND ${EXE_NAME})
|
||||
|
||||
IF(EXE_NAME_FOUND)
|
||||
|
||||
|
||||
STRING(REGEX MATCH "image_to_j2k" ENC_TEST_FOUND ${EXE_NAME})
|
||||
|
||||
|
||||
ELSE(EXE_NAME_FOUND)
|
||||
|
||||
|
||||
MESSAGE( FATAL_ERROR "${EXE_NAME} is not the right executable name to encode file (try to use image_to_j2k)")
|
||||
|
||||
ENDIF(EXE_NAME_FOUND)
|
||||
@@ -124,15 +242,15 @@ FOREACH(OPJ_TEST_CMD_LINE ${OPJ_TEST_CMD_LINE_LIST})
|
||||
LIST(REMOVE_AT CMD_ARG_LIST 0)
|
||||
|
||||
ENDIF (FAILED_TEST_FOUND)
|
||||
|
||||
|
||||
# Parse the argument list to find the input filename and output filename
|
||||
SET(CMD_ARG_LIST_2 "")
|
||||
SET(ARG_POS 0)
|
||||
SET(INPUT_ARG_POS 0)
|
||||
SET(OUTPUT_ARG_POS 0)
|
||||
|
||||
|
||||
FOREACH(CMD_ARG_ELT ${CMD_ARG_LIST})
|
||||
|
||||
|
||||
math(EXPR ARG_POS "${ARG_POS}+1" )
|
||||
|
||||
STRING(COMPARE EQUAL ${CMD_ARG_ELT} "-i" INPUT_ARG_FOUND)
|
||||
@@ -148,9 +266,9 @@ FOREACH(OPJ_TEST_CMD_LINE ${OPJ_TEST_CMD_LINE_LIST})
|
||||
ENDIF(OUTPUT_ARG_FOUND)
|
||||
|
||||
LIST (APPEND CMD_ARG_LIST_2 ${CMD_ARG_ELT})
|
||||
|
||||
|
||||
ENDFOREACH(CMD_ARG_ELT)
|
||||
|
||||
|
||||
LIST(GET CMD_ARG_LIST_2 ${INPUT_ARG_POS} INPUT_FILENAME)
|
||||
GET_FILENAME_COMPONENT(INPUT_FILENAME_NAME ${INPUT_FILENAME} NAME)
|
||||
GET_FILENAME_COMPONENT(INPUT_FILENAME_NAME_WE ${INPUT_FILENAME_NAME} NAME_WE)
|
||||
@@ -163,125 +281,164 @@ FOREACH(OPJ_TEST_CMD_LINE ${OPJ_TEST_CMD_LINE_LIST})
|
||||
|
||||
# ENCODER TEST SUITE
|
||||
IF(ENC_TEST_FOUND)
|
||||
math(EXPR IT_TEST_ENC "${IT_TEST_ENC}+1" )
|
||||
|
||||
# Encode an image into the jpeg2000 format
|
||||
ADD_TEST(NAME NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-encode
|
||||
COMMAND image_to_j2k
|
||||
${CMD_ARG_LIST_2}
|
||||
math(EXPR IT_TEST_ENC "${IT_TEST_ENC}+1" )
|
||||
|
||||
# Encode an image into the jpeg2000 format
|
||||
ADD_TEST(NAME NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-encode
|
||||
COMMAND image_to_j2k
|
||||
${CMD_ARG_LIST_2}
|
||||
)
|
||||
|
||||
IF(FAILED_TEST_FOUND)
|
||||
SET_TESTS_PROPERTIES(NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-encode PROPERTIES WILL_FAIL TRUE)
|
||||
ELSE(FAILED_TEST_FOUND)
|
||||
|
||||
# Dump the encoding file
|
||||
ADD_TEST(NAME NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-dump
|
||||
COMMAND j2k_dump
|
||||
-i ${OUTPUT_FILENAME}
|
||||
-o ${OUTPUT_FILENAME}-ENC-${IT_TEST_ENC}.txt
|
||||
)
|
||||
SET_TESTS_PROPERTIES(NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-dump
|
||||
PROPERTIES DEPENDS
|
||||
NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-encode)
|
||||
|
||||
IF(FAILED_TEST_FOUND)
|
||||
SET_TESTS_PROPERTIES(NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-encode PROPERTIES WILL_FAIL TRUE)
|
||||
ELSE(FAILED_TEST_FOUND)
|
||||
|
||||
# Dump the encoding file
|
||||
ADD_TEST(NAME NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-dump
|
||||
COMMAND j2k_dump
|
||||
# Compare the dump file with the baseline
|
||||
ADD_TEST(NAME NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-compare_dump2base
|
||||
COMMAND compare_dump_files
|
||||
-b ${BASELINE_NR}/opj_${OUTPUT_FILENAME_NAME_WE}-ENC-${IT_TEST_ENC}.txt
|
||||
-t ${OUTPUT_FILENAME}-ENC-${IT_TEST_ENC}.txt
|
||||
)
|
||||
|
||||
SET_TESTS_PROPERTIES(NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-compare_dump2base
|
||||
PROPERTIES DEPENDS
|
||||
NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-dump)
|
||||
|
||||
# Decode the encoding file with kakadu expand command
|
||||
IF (KDU_EXPAND_EXECUTABLE)
|
||||
ADD_TEST(NAME NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-decode-ref
|
||||
COMMAND ${KDU_EXPAND_EXECUTABLE}
|
||||
-i ${OUTPUT_FILENAME}
|
||||
-o ${OUTPUT_FILENAME}-ENC-${IT_TEST_ENC}.txt
|
||||
)
|
||||
SET_TESTS_PROPERTIES(NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-dump
|
||||
PROPERTIES DEPENDS
|
||||
NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-encode)
|
||||
|
||||
# Compare the dump file with the baseline
|
||||
ADD_TEST(NAME NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-compare_dump2base
|
||||
COMMAND compare_dump_files
|
||||
-b ${BASELINE_NR}/opj_${OUTPUT_FILENAME_NAME_WE}-ENC-${IT_TEST_ENC}.txt
|
||||
-t ${OUTPUT_FILENAME}-ENC-${IT_TEST_ENC}.txt
|
||||
)
|
||||
|
||||
SET_TESTS_PROPERTIES(NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-compare_dump2base
|
||||
PROPERTIES DEPENDS
|
||||
NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-dump)
|
||||
|
||||
# Decode the encoding file with kakadu expand command
|
||||
IF (KDU_EXPAND_EXECUTABLE)
|
||||
ADD_TEST(NAME NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-decode-ref
|
||||
COMMAND ${KDU_EXPAND_EXECUTABLE}
|
||||
-i ${OUTPUT_FILENAME}
|
||||
-o ${OUTPUT_FILENAME}.raw
|
||||
)
|
||||
|
||||
SET_TESTS_PROPERTIES(NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-decode-ref
|
||||
PROPERTIES DEPENDS
|
||||
NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-encode)
|
||||
|
||||
# Compare the decoding file with baseline generated from the kdu_expand and baseline.j2k
|
||||
ADD_TEST(NAME NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-compare_dec-ref-out2base
|
||||
COMMAND compareRAWimages
|
||||
-b ${BASELINE_NR}/opj_${OUTPUT_FILENAME_NAME_WE}-ENC-${IT_TEST_ENC}.raw
|
||||
-t ${OUTPUT_FILENAME}.raw
|
||||
-o ${OUTPUT_FILENAME}.raw
|
||||
)
|
||||
|
||||
SET_TESTS_PROPERTIES(NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-compare_dec-ref-out2base
|
||||
PROPERTIES DEPENDS
|
||||
NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-decode-ref)
|
||||
|
||||
ENDIF()
|
||||
ENDIF(FAILED_TEST_FOUND)
|
||||
|
||||
# DECODER TEST SUITE
|
||||
|
||||
SET_TESTS_PROPERTIES(NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-decode-ref
|
||||
PROPERTIES DEPENDS
|
||||
NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-encode)
|
||||
|
||||
# Compare the decoding file with baseline generated from the kdu_expand and baseline.j2k
|
||||
ADD_TEST(NAME NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-compare_dec-ref-out2base
|
||||
COMMAND compare_raw_files
|
||||
-b ${BASELINE_NR}/opj_${OUTPUT_FILENAME_NAME_WE}-ENC-${IT_TEST_ENC}.raw
|
||||
-t ${OUTPUT_FILENAME}.raw
|
||||
)
|
||||
|
||||
SET_TESTS_PROPERTIES(NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-compare_dec-ref-out2base
|
||||
PROPERTIES DEPENDS
|
||||
NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-decode-ref)
|
||||
|
||||
ENDIF()
|
||||
|
||||
# Test the encoded file is a valid JP2 file
|
||||
if (JPYLYZER_EXECUTABLE)
|
||||
if (${OUTPUT_FILENAME} MATCHES "\\.jp2$")
|
||||
add_test(NAME NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-jpylyser
|
||||
COMMAND ${JPYLYZER_EXECUTABLE}
|
||||
${OUTPUT_FILENAME}
|
||||
)
|
||||
set_tests_properties(NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-jpylyser PROPERTIES
|
||||
DEPENDS NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-encode
|
||||
PASS_REGULAR_EXPRESSION "<isValidJP2>True</isValidJP2>"
|
||||
)
|
||||
endif()
|
||||
endif(JPYLYZER_EXECUTABLE)
|
||||
|
||||
# If lossless compression (simple test is 4 arguments), decompress & compare
|
||||
list(LENGTH CMD_ARG_LIST_2 ARG_COUNT)
|
||||
if (ARG_COUNT EQUAL 4)
|
||||
# can we compare with the input image ?
|
||||
if (${INPUT_FILENAME_NAME} MATCHES "\\.tif$")
|
||||
add_test(NAME NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-lossless-decode
|
||||
COMMAND j2k_to_image -i ${OUTPUT_FILENAME} -o ${OUTPUT_FILENAME}.lossless.tif
|
||||
)
|
||||
set_tests_properties(NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-lossless-decode PROPERTIES
|
||||
DEPENDS NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-encode
|
||||
)
|
||||
add_test(NAME NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-lossless-compare
|
||||
COMMAND compare_images -b ${INPUT_FILENAME} -t ${OUTPUT_FILENAME}.lossless.tif -n 1 -d
|
||||
)
|
||||
set_tests_properties(NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-lossless-compare PROPERTIES
|
||||
DEPENDS NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-lossless-decode
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# DECODER TEST SUITE
|
||||
ELSE(ENC_TEST_FOUND)
|
||||
string(FIND ${INPUT_FILENAME} "nonregression" nr_pos)
|
||||
if(${nr_pos} GREATER 0)
|
||||
list(APPEND nonregression_filenames_used ${INPUT_FILENAME_NAME})
|
||||
endif()
|
||||
math(EXPR IT_TEST_DEC "${IT_TEST_DEC}+1" )
|
||||
|
||||
|
||||
# Decode the input image
|
||||
ADD_TEST(NAME NR-DEC-${INPUT_FILENAME_NAME}-${IT_TEST_DEC}-decode
|
||||
COMMAND j2k_to_image
|
||||
${CMD_ARG_LIST_2}
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
IF(FAILED_TEST_FOUND)
|
||||
|
||||
|
||||
SET_TESTS_PROPERTIES(NR-DEC-${INPUT_FILENAME_NAME}-${IT_TEST_DEC}-decode PROPERTIES WILL_FAIL TRUE)
|
||||
|
||||
|
||||
ELSE(FAILED_TEST_FOUND)
|
||||
# if not failed, check against registered md5:
|
||||
add_test(NAME NR-DEC-${INPUT_FILENAME_NAME}-${IT_TEST_DEC}-decode-md5 COMMAND ${CMAKE_COMMAND}
|
||||
-DREFFILE:STRING=${CMAKE_CURRENT_SOURCE_DIR}/md5refs.txt
|
||||
-DFILENAME:STRING=${INPUT_FILENAME_NAME}
|
||||
-DOUTFILENAME:STRING=${OUTPUT_FILENAME}
|
||||
-P ${CMAKE_CURRENT_SOURCE_DIR}/checkmd5refs.cmake)
|
||||
|
||||
# FIXME: add a compare2base function base on raw which
|
||||
# can output png diff files if necesary
|
||||
# ADD_TEST(NAME NR-${filename}-compare2base
|
||||
# COMMAND comparePGXimages
|
||||
# -b ${BASELINE_NR}/opj_${filenameRef}
|
||||
# -t ${TEMP}/${filename}.pgx
|
||||
# -n ${nbComponents}
|
||||
# -d
|
||||
# -s b_t_
|
||||
# )
|
||||
set_tests_properties(NR-DEC-${INPUT_FILENAME_NAME}-${IT_TEST_DEC}-decode-md5
|
||||
PROPERTIES DEPENDS NR-DEC-${INPUT_FILENAME_NAME}-${IT_TEST_DEC}-decode
|
||||
)
|
||||
|
||||
# FIXME: add a compare2base function base on raw which
|
||||
# can output png diff files if necesary
|
||||
# add_test(NR-${filename}-compare2base
|
||||
# ${EXECUTABLE_OUTPUT_PATH}/compare_images
|
||||
# -b ${BASELINE_NR}/opj_${filenameRef}
|
||||
# -t ${TEMP}/${filename}.pgx
|
||||
# -n ${nbComponents}
|
||||
# -d
|
||||
# -s b_t_
|
||||
# )
|
||||
#
|
||||
# SET_TESTS_PROPERTIES(NR-${filename}-compare2base
|
||||
# PROPERTIES DEPENDS
|
||||
# NR-${filename}-decode)
|
||||
|
||||
# Dump the input image
|
||||
ADD_TEST(NAME NR-DEC-${INPUT_FILENAME_NAME}-${IT_TEST_DEC}-dump
|
||||
COMMAND j2k_dump
|
||||
-i ${INPUT_FILENAME}
|
||||
-o ${TEMP}/${INPUT_FILENAME_NAME}.txt
|
||||
)
|
||||
|
||||
# Compare the dump output with the baseline
|
||||
ADD_TEST(NAME NR-DEC-${INPUT_FILENAME_NAME}-${IT_TEST_DEC}-compare_dump2base
|
||||
COMMAND compare_dump_files
|
||||
-b ${BASELINE_NR}/opj_${INPUT_FILENAME_NAME_WE}.txt
|
||||
-t ${TEMP}/${INPUT_FILENAME_NAME}.txt
|
||||
)
|
||||
|
||||
SET_TESTS_PROPERTIES(NR-DEC-${INPUT_FILENAME_NAME}-${IT_TEST_DEC}-compare_dump2base
|
||||
PROPERTIES DEPENDS
|
||||
NR-DEC-${INPUT_FILENAME_NAME}-${IT_TEST_DEC}-dump)
|
||||
|
||||
# PROPERTIES DEPENDS
|
||||
# NR-${filename}-decode)
|
||||
|
||||
ENDIF(FAILED_TEST_FOUND)
|
||||
|
||||
ENDIF(ENC_TEST_FOUND)
|
||||
|
||||
ENDIF(IGNORE_LINE_FOUND)
|
||||
ENDIF()
|
||||
|
||||
ENDFOREACH(OPJ_TEST_CMD_LINE)
|
||||
ENDIF()
|
||||
|
||||
ENDIF()
|
||||
|
||||
ENDFOREACH()
|
||||
|
||||
set(existing_filenames)
|
||||
foreach(f ${OPJ_DATA_NR_LIST})
|
||||
get_filename_component(ff ${f} NAME)
|
||||
list(APPEND existing_filenames ${ff})
|
||||
endforeach()
|
||||
if(existing_filenames)
|
||||
list(REMOVE_ITEM existing_filenames ${nonregression_filenames_used})
|
||||
endif()
|
||||
|
||||
# keep track of new addition:
|
||||
# if we reach here, then a J2K files was added but no test is present in
|
||||
# test_suite.ctest.in:
|
||||
foreach(found_but_no_test ${existing_filenames})
|
||||
add_test(NAME Found-But-No-Test-${found_but_no_test} COMMAND ${CMAKE_COMMAND} -E echo "${found_but_no_test}")
|
||||
set_tests_properties(Found-But-No-Test-${found_but_no_test} PROPERTIES WILL_FAIL TRUE)
|
||||
endforeach()
|
||||
|
||||
@@ -16,40 +16,40 @@
|
||||
# decoding process that the output would be bitwise different (while PSNR would
|
||||
# be kept identical).
|
||||
|
||||
#message("0: ${REFFILE}")
|
||||
#message("1: ${CMAKE_CURRENT_BINARY_DIR}")
|
||||
#message("2: ${FILENAME}")
|
||||
file(GLOB globfiles "Temporary/${FILENAME}*.pgx" )
|
||||
#message("6: ${globfiles}")
|
||||
# Another more conventional approach is to store the generated output from
|
||||
# openjpeg however storing the full generated output is generally useless since
|
||||
# we do not really care about the exact pixel value, we simply need to known
|
||||
# when a code change impact output generation. furthermore storing the
|
||||
# complete generated output file, tends to make the svn:/openjpeg-data really
|
||||
# big.
|
||||
|
||||
# REFFILE follow what md5sum -c would expect as input:
|
||||
# This script expect two inputs
|
||||
# REFFILE: Path to the md5sum.txt file
|
||||
# OUTFILENAME: The name of the generated file we want to check The script will
|
||||
# check whether a PGX or a PNG file was generated in the test suite (computed
|
||||
# from OUTFILENAME)
|
||||
|
||||
get_filename_component(OUTFILENAME_NAME ${OUTFILENAME} NAME)
|
||||
string(FIND ${OUTFILENAME_NAME} "." SHORTEST_EXT_POS REVERSE)
|
||||
string(SUBSTRING ${OUTFILENAME_NAME} 0 ${SHORTEST_EXT_POS} OUTFILENAME_NAME_WE)
|
||||
file(GLOB globfiles "Temporary/${OUTFILENAME_NAME_WE}*.pgx" "Temporary/${OUTFILENAME_NAME_WE}*.png" "Temporary/${OUTFILENAME_NAME_WE}*.tif")
|
||||
if(NOT globfiles)
|
||||
message(SEND_ERROR "Could not find output PGX files: ${OUTFILENAME_NAME_WE}")
|
||||
endif()
|
||||
|
||||
# REFFILE follow what `md5sum -c` would expect as input:
|
||||
file(READ ${REFFILE} variable)
|
||||
#string(REGEX REPLACE "\r?\n" ";" variable "${variable}")
|
||||
|
||||
foreach(pgxfullpath ${globfiles})
|
||||
file(MD5 ${pgxfullpath} output)
|
||||
get_filename_component(pgxfile ${pgxfullpath} NAME)
|
||||
#message("8: ${pgxfile}")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E md5sum ${pgxfile}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Temporary
|
||||
RESULT_VARIABLE res
|
||||
OUTPUT_VARIABLE output
|
||||
ERROR_VARIABLE error_output
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE # important
|
||||
)
|
||||
|
||||
# Pass the output back to ctest
|
||||
if(res)
|
||||
message(SEND_ERROR "md5 could not be computed, it failed with value ${res}. Output was: ${error_output}")
|
||||
endif()
|
||||
#message("3: ${output}")
|
||||
|
||||
#message("4: ${variable}")
|
||||
string(REGEX MATCH "[0-9a-f]+ ${pgxfile}" output_var "${variable}")
|
||||
#message("5: ${output_var}")
|
||||
|
||||
set(output "${output} ${pgxfile}")
|
||||
|
||||
if("${output_var}" STREQUAL "${output}")
|
||||
#message("6: eqal")
|
||||
message(STATUS "equal: [${output_var}] vs [${output}]")
|
||||
else()
|
||||
message(SEND_ERROR "not equal: [${output_var}] vs [${output}]")
|
||||
endif()
|
||||
|
||||
@@ -11,13 +11,25 @@ b8f473c07ba5ebfc195bdd53c3b3b97f buxR.j2k_0.pgx
|
||||
05c062aca83d13b8095460f38a690a08 Cannotreaddatawithnosizeknown.j2k_0.pgx
|
||||
6276da0ec5fac44d683d3468b290331d cthead1.j2k_0.pgx
|
||||
8afcac9a696cc8d753b0eb9f4ae692ff CT_Phillips_JPEG2K_Decompr_Problem.j2k_0.pgx
|
||||
04d35ab6160c9029549f72358df984da file409752_0.pgx
|
||||
2813bd6fdc2c306b91b3da3688b8bf49 file409752_1.pgx
|
||||
e273e2aaea4a4fc1b2cf7c09c53c3cc6 file409752_2.pgx
|
||||
04d35ab6160c9029549f72358df984da file409752.jp2_0.pgx
|
||||
2813bd6fdc2c306b91b3da3688b8bf49 file409752.jp2_1.pgx
|
||||
e273e2aaea4a4fc1b2cf7c09c53c3cc6 file409752.jp2_2.pgx
|
||||
05c062aca83d13b8095460f38a690a08 illegalcolortransform.j2k_0.pgx
|
||||
cb28787aa7c223f03e6acad71e244108 issue104_jpxstream.jp2_0.pgx
|
||||
cb28787aa7c223f03e6acad71e244108 issue104_jpxstream.jp2_1.pgx
|
||||
cb28787aa7c223f03e6acad71e244108 issue104_jpxstream.jp2_2.pgx
|
||||
c74edbb49e132b2cfc1eaf7908197b17 issue134.jp2_0.pgx
|
||||
16fe8ed450da10a6aaae4cf6f467fc21 issue134.jp2_1.pgx
|
||||
c6091c07bf0ff221008dfb60d893cdff issue134.jp2_2.pgx
|
||||
cccccccccccccccccccccccccccccccc issue135.j2k_0.pgx
|
||||
cccccccccccccccccccccccccccccccc issue135.j2k_1.pgx
|
||||
cccccccccccccccccccccccccccccccc issue135.j2k_2.pgx
|
||||
aa7461b31e14641586803b23b7fb04f2 issue142.j2k_0.pgx
|
||||
a809006e7a0c1eed68bc86c96af43fe3 issue142.j2k_1.pgx
|
||||
74f7a7a194a74a947245b843c62c4054 issue142.j2k_2.pgx
|
||||
c44662b1f7fe01caa2ebf3ad62948e3e issue171.jp2_0.pgx
|
||||
f70e8a4e5dbefeb44d50edd79b6c4cf6 issue171.jp2_1.pgx
|
||||
18bc167a1c851db2fd9f8c7af3289134 issue171.jp2_2.pgx
|
||||
adda4f5e46845b96dd3df14a76aa7229 issue188_beach_64bitsbox.jp2_0.pgx
|
||||
90a9709c166019d1e101e7b96d257ed9 issue188_beach_64bitsbox.jp2_1.pgx
|
||||
37e23d2df06ee60bf0f9f5e1c16054d8 issue188_beach_64bitsbox.jp2_2.pgx
|
||||
@@ -28,7 +40,15 @@ de992d54d59032eb07d21983dbe8155b issue205.jp2_3.pgx
|
||||
8fae7a39e459409f64e4529d2214087a issue206_image-000.jp2_0.pgx
|
||||
555a504a93c9a14f61c894da3b393e87 issue206_image-000.jp2_1.pgx
|
||||
5f06b7c45446ae20c22cada46478a9dc issue206_image-000.jp2_2.pgx
|
||||
6e40cbf1dbf7db68ff7975a7a99362b9 issue208.jp2_0.pgx
|
||||
822f330a38c053130c707cadd31d3b41 issue208.jp2_1.pgx
|
||||
60316fb101af743c0f3e24924365b178 issue208.jp2_2.pgx
|
||||
a0823d21d9de699353a3bd1adb23bd1c issue211.jp2_0.pgx
|
||||
1820161df26c360a62d11800d6cf173f issue211.jp2_1.pgx
|
||||
e1807db57b5f5192c4b77b83e8b5c477 issue228.j2k_0.pgx
|
||||
e58242abc2c6d44df187397c55e6fbff issue254.jp2_0.pgx
|
||||
e58242abc2c6d44df187397c55e6fbff issue254.jp2_1.pgx
|
||||
e58242abc2c6d44df187397c55e6fbff issue254.jp2_2.pgx
|
||||
4093cc34d838780b35a8be410247fa7f j2k32.j2k_0.pgx
|
||||
ce4e556aaa0844b92a92c35c200fc43e j2k32.j2k_1.pgx
|
||||
ea926520f990640862f3fe6616097613 j2k32.j2k_2.pgx
|
||||
@@ -36,6 +56,9 @@ ea926520f990640862f3fe6616097613 j2k32.j2k_2.pgx
|
||||
12a8a4668315d9ae27969991251ce85f kodak_2layers_lrcp.j2c_0.pgx
|
||||
56d0b0c547d6d5bb12f0c36e88722b11 kodak_2layers_lrcp.j2c_1.pgx
|
||||
48ba092fb40090c160bbd08bdf7bdbf2 kodak_2layers_lrcp.j2c_2.pgx
|
||||
12a8a4668315d9ae27969991251ce85f kodak_2layers_lrcp-l2.j2c_0.pgx
|
||||
56d0b0c547d6d5bb12f0c36e88722b11 kodak_2layers_lrcp-l2.j2c_1.pgx
|
||||
48ba092fb40090c160bbd08bdf7bdbf2 kodak_2layers_lrcp-l2.j2c_2.pgx
|
||||
05c062aca83d13b8095460f38a690a08 MarkerIsNotCompliant.j2k_0.pgx
|
||||
ff73d2bd32951d9e55b02186aac24aff Marrin.jp2_0.pgx
|
||||
55ce884dd2346af6a5172a434ee578fa Marrin.jp2_1.pgx
|
||||
@@ -74,6 +97,58 @@ fdad26b1e078aa32bd4b77a5f44da43c orb-blue10-lin-jp2.jp2_2.pgx
|
||||
7442756e83571c0e87493e03f12b2d34 orb-blue10-win-jp2.jp2_1.pgx
|
||||
5f99ff2aeb17e167fe7049bcf339d0b3 orb-blue10-win-jp2.jp2_2.pgx
|
||||
fe028d56d6c7aaee87239a115093412a orb-blue10-win-jp2.jp2_3.pgx
|
||||
03bd6de1f4e9924f2dcff8d4edaab718 p0_04_1.j2k.png
|
||||
7898b580781d69fda800016378bab80c p0_04_2.j2k.png
|
||||
e7cde963434e37ba00e128efb7e5c5c3 p0_04_3.j2k.png
|
||||
a486db59bf5e7c39275aaf62304cf0b7 p0_04_4.j2k.png
|
||||
59a08fe073e52a778128f22feffcdaf8 p0_04_5.j2k.png
|
||||
c6f01ceef58442fed6a6af181b27ff06 p0_04_6_1.j2k.png
|
||||
c3cbab7a2a5bf6b10f67afdd4e125120 p0_04_6_2.j2k.png
|
||||
04457ca5d9bde5700140cedf8cf2aeea p0_04_6_3.j2k.png
|
||||
dac32a0a17d0cc4e4f67d49767fc54c1 p0_04_6_4.j2k.png
|
||||
ef27ff4ff2f6d7d3919808d7378bf119 p0_04_6_5.j2k.png
|
||||
44ac3a7d98c90f5ab24b6801a601faa9 p0_04_6.j2k.png
|
||||
bd0f12125f8e3f367dae1c6179f52212 p0_04.j2k.png
|
||||
ff00bc86aa73a8266e381c5428c17c28 p1_04_10.j2k.png
|
||||
72a6b3b455c6b3397f95cdf40ead75a0 p1_04_11.j2k.png
|
||||
060809d8a5969f162f3b662adc3cbccb p1_04_12.j2k.png
|
||||
92d8168db18cf51d108b0fc1a4f0aeea p1_04_13.j2k.png
|
||||
bd5650ff4c977e42e4d84304c92222a0 p1_04_14.j2k.png
|
||||
3920307d5b6cb855065f144b7683609b p1_04_15.j2k.png
|
||||
1e94024252ca36e86b09e37370005ad0 p1_04_16.j2k.png
|
||||
d271f149dc89c4d897fbd935189b159b p1_04_17_t63.j2k.png
|
||||
060809d8a5969f162f3b662adc3cbccb p1_04_17_t63_r2.j2k.png
|
||||
c92cb973e7dc716830ddf3d257e93fb3 p1_04_18.t12.j2k.png
|
||||
c9b66b78895609fb0250ca5bd2e89c1d p1_04_19_t12_r1.j2k.png
|
||||
68e1408710e68669f434937714fd5623 p1_04_1.j2k.png
|
||||
d271f149dc89c4d897fbd935189b159b p1_04_2.j2k.png
|
||||
9583a4c09567d8b67d23c5857ca10dc5 p1_04_3.j2k.png
|
||||
6f405d502508b37f6133342ab2e7876c p1_04_4.j2k.png
|
||||
4f084579cba30bec1cc9d89e55e99c5a p1_04_5.j2k.png
|
||||
cd5326c62fa50d68b0d8f08bc3da617c p1_04_6.j2k.png
|
||||
e50b0e1c1d28f0a40ad9d5c64a4b1cf4 p1_04.j2k.png
|
||||
b367ad625d2a44a066b3cdd291da619c p1_06_10_1.j2k.png
|
||||
0bc2db37548e0f6e342af2ea86380300 p1_06_10_2.j2k.png
|
||||
32415e97cb64b4fda976c883bbb16103 p1_06_10.j2k.png
|
||||
32415e97cb64b4fda976c883bbb16103 p1_06_11.j2k.png
|
||||
3a99df46b0fbf7a9e7703d2b0e7355a5 p1_06_1.j2k.png
|
||||
2702da6fca94765767365c7d80933ee2 p1_06_2.j2k.png
|
||||
bb8d24257705393e5536fa77bdeb362c p1_06_3.j2k.png
|
||||
9add0b9211f51ae2da1d01588ed3f9cf p1_06_4.j2k.png
|
||||
5d037fefa22029a90d8e3ac82246a2e1 p1_06_5.j2k.png
|
||||
821d1c176a2908136f5246599a47c462 p1_06_6.j2k.png
|
||||
9d4cf96edeae63e461bff66d8c0b7b82 p1_06_7_1.j2k.png
|
||||
6d6713374c1e443539a02f82baad5c98 p1_06_7_2.j2k.png
|
||||
8317d23c60a0e891405339e0d9848efa p1_06_7_3.j2k.png
|
||||
aa4a63ad4322a92c7f4d5a7f29ad0723 p1_06_7_4.j2k.png
|
||||
e8748d54c7696069e14501c85d6f6638 p1_06_7_5.j2k.png
|
||||
b367ad625d2a44a066b3cdd291da619c p1_06_7_6.j2k.png
|
||||
93c72c4eaffdf0c3081a00e1d21829f6 p1_06_7.j2k.png
|
||||
024d2b209513c21438f9b5c60b7d945d p1_06_9_1.j2k.png
|
||||
c3f42d42eef90d42a98ad27d0612af9f p1_06_9_2.j2k.png
|
||||
2702da6fca94765767365c7d80933ee2 p1_06_9_3.j2k.png
|
||||
695444198428363c61871586add6d666 p1_06_9.j2k.png
|
||||
c494419005e8aae82f46d3f48da6caf1 p1_06.j2k.png
|
||||
371aa0a7ff40a73b45f1fa41e210d1db pacs.ge.j2k_0.pgx
|
||||
6ae110e1fb5a869af3dbc5fbc735b0bd relax.jp2_0.pgx
|
||||
518a8f28dacc034982507f43763b88dd relax.jp2_1.pgx
|
||||
@@ -82,3 +157,121 @@ cdb1d69eb48ffd8545751326b86d9d7e test_lossless.j2k_0.pgx
|
||||
a37e7e5811d7c0c7adb61582790ccd33 text_GBR.jp2_0.pgx
|
||||
fc2173be54954a146b4e2887ee14be06 text_GBR.jp2_1.pgx
|
||||
14108b4fb8d9126750db0424417ed17d text_GBR.jp2_2.pgx
|
||||
a73bec4d6d82c8a64203e8fdf893b86d issue412.jp2_0.pgx
|
||||
a73bec4d6d82c8a64203e8fdf893b86d issue428.jp2_0.pgx
|
||||
2354cf24a1cc5e4a3b72896b333ba361 issue412.jp2_1.pgx
|
||||
2354cf24a1cc5e4a3b72896b333ba361 issue428.jp2_1.pgx
|
||||
77d707ff949371e561e13a8d720108b5 issue412.jp2_2.pgx
|
||||
77d707ff949371e561e13a8d720108b5 issue428.jp2_2.pgx
|
||||
2fc600f30ec0bc013befb1874e7adaeb issue414.jp2_0.pgx
|
||||
354f9bb4668717d5c814cda354ec2b43 issue414.jp2_1.pgx
|
||||
8b96a253937c4c7dd6b41b4aa11367d9 issue414.jp2_2.pgx
|
||||
ec6886229ffaeaddfe22ce02b7a75e15 issue414.jp2_3.pgx
|
||||
6aa5c69c83d6f4d5d65968f34f9bc2a3 issue414.jp2_4.pgx
|
||||
00f34217ad2f88f4d4e1c5cd0d2c4329 issue399.j2k_0.pgx
|
||||
d8fb69def2a48a3686483c4353544f4b issue411-ycc444.jp2_0.pgx
|
||||
d2911f75ed1758057f9b1bf26bcb2400 issue411-ycc444.jp2_1.pgx
|
||||
f7c23ee589ceda07ffb77a83018606cc issue411-ycc444.jp2_2.pgx
|
||||
7e5e5546ae7ab4e9257ec30185ff9155 issue411-ycc422.jp2_0.pgx
|
||||
d5ecef537edf294af83826763c0cf860 issue411-ycc422.jp2_1.pgx
|
||||
3a8d91d7cf3e8887dd0d29beac030620 issue411-ycc422.jp2_2.pgx
|
||||
07480962d25b3d8cce18096648963c8a issue411-ycc420.jp2_0.pgx
|
||||
149a69831b42401f20b8f7492ef99d97 issue411-ycc420.jp2_1.pgx
|
||||
ec8d1c99db9763a8ba489df4f41dda53 issue411-ycc420.jp2_2.pgx
|
||||
3c7ff2e4bdae849167be36589f32bcd5 issue458.jp2_0.pgx
|
||||
f004b48eafb2e52529cc9c7b6a3ff5d2 issue458.jp2_1.pgx
|
||||
3127bd0a591d113c3c2428c8d2c14ec8 issue458.jp2_2.pgx
|
||||
dacaf60e4c430916a8c2a9ebec32e71c issue458.jp2_3.pgx
|
||||
d33fb5dbddb9b9b4438eb51fa27445a3 issue495.jp2_0.pgx
|
||||
27db8c35e12a5d5eb94d403d2aae2909 issue495.jp2_1.pgx
|
||||
97da625d2f2d0b75bf891d8083ce8bfb issue495.jp2_2.pgx
|
||||
86729c5f2b74b2dfd42cb0d8e47aef79 a1_mono_tif-1.tif
|
||||
fa9b7b896536b25a7a1d8eeeacb59141 a1_mono_tif-10.tif
|
||||
b0ee13aa90ca4421e09a3b7b41f410c0 a1_mono_tif-12.tif
|
||||
4699894fedd3758727d8288cd7adb56c a1_mono_tif-14.tif
|
||||
4ad682c58e63d3223914c10a6656c8ae a1_mono_tif-16.tif
|
||||
22c2fa09a4d7b9fade6a3cddc6c6a4dc a1_mono_tif-2.tif
|
||||
996c5e67a663218be90e86bff8ecad89 a1_mono_tif-4.tif
|
||||
7f451a5ac89915c5cdc023fd8c813a3c a1_mono_tif-6.tif
|
||||
c3ebfcf478b1c4fc786748813f2b5d53 a1_mono_tif-8.tif
|
||||
31650ec40241737634179fff6ad306f8 basn4a08_tif-1.tif
|
||||
abf884080bcfbf58c044a9d86bfa5e5d basn4a08_tif-10.tif
|
||||
916d97c098d9792993cc91fee4a83f77 basn4a08_tif-12.tif
|
||||
57643174986481d336db6ddf04b970df basn4a08_tif-14.tif
|
||||
fb5cf848d63c61dc485c87c9246ee9c7 basn4a08_tif-16.tif
|
||||
5d7b01d98c82ad563bb28c2d83484a2a basn4a08_tif-2.tif
|
||||
2401cebbb1d5494fcbe0d899484c342d basn4a08_tif-4.tif
|
||||
6dbeb5b708bbde76e204c0887da61f6b basn4a08_tif-6.tif
|
||||
dc40cc1da6de28e7e973c8ba796ca189 basn4a08_tif-8.tif
|
||||
59e32c45591fd3bb44fe99381a116ba1 basn6a08_tif-1.tif
|
||||
630e6fb6deba0b3efd93b610561d607a basn6a08_tif-10.tif
|
||||
765555e75e59de27f7b2177d04f36bc1 basn6a08_tif-12.tif
|
||||
62384c112d5fe40aefd0a9b0b9a4bcc6 basn6a08_tif-14.tif
|
||||
d725d41557658a28ab31dff74e2467fa basn6a08_tif-16.tif
|
||||
96d91df6b10e866ea26ebbf0b8ddc7da basn6a08_tif-2.tif
|
||||
a324032339808d5fe85d6e354f14c183 basn6a08_tif-4.tif
|
||||
d60864a6a5c8a49a202d98ae6f5165c7 basn6a08_tif-6.tif
|
||||
c3e93f61125f82a9832d0b9440468034 basn6a08_tif-8.tif
|
||||
cfe04d15cf9d615fc36357dcb3b3956b p0_14_tif-1.tif
|
||||
9ad87e7fddc77ac85e2e92509bee2365 p0_14_tif-10.tif
|
||||
38e67f9d573e61166761d5eee0104448 p0_14_tif-12.tif
|
||||
77486f0468694b94290d0b55361498a0 p0_14_tif-14.tif
|
||||
51be675689949dd08b6ee1427af3eb4a p0_14_tif-16.tif
|
||||
3e34e94bd8f7380c8d159676fee9ea57 p0_14_tif-2.tif
|
||||
b6f71c941e3a5b8d2547792ccec58d54 p0_14_tif-4.tif
|
||||
81fcdd90917efb95aed94c6522d1c188 p0_14_tif-6.tif
|
||||
6808377b760b4ef3559ba8b14ed9b91a p0_14_tif-8.tif
|
||||
dd15b3d487d36a3682be0679300a4319 issue235.jp2_0.pgx
|
||||
b9cd6dc76b141fb1fec15f50c1f70e01 issue235.jp2_1.pgx
|
||||
3edef2ae197ef30b08deda1b28825399 issue235.jp2_2.pgx
|
||||
b6a84b3215333efc80326715f9078c58 a1_mono_png-1.png
|
||||
88f96456667b8b3fd69c406fe40636b5 a1_mono_png-10.png
|
||||
077148452a9506a2337afa2777c57834 a1_mono_png-12.png
|
||||
c4eee75c1da8d43e1510cb36326f948b a1_mono_png-14.png
|
||||
b22b7badb943c5c375b7c55032f49def a1_mono_png-16.png
|
||||
c7e209abe0d4c5ec1407bfe2cfa932de a1_mono_png-2.png
|
||||
313d1e2d0d41231003587d3061b6119f a1_mono_png-4.png
|
||||
d92241d97e8603509027176dd3b3168a a1_mono_png-6.png
|
||||
a86b3b0720229491ce82556d3fc97bf3 a1_mono_png-8.png
|
||||
159d1413263e2183e50ecc8dc7487b98 basn4a08_png-1.png
|
||||
cc501ac5219200ed5d7d33df907d3390 basn4a08_png-10.png
|
||||
9006ec767be7645c1808eef4e8c6ee7a basn4a08_png-12.png
|
||||
df3484a4ecfaddc1f62d4bf202944ad5 basn4a08_png-14.png
|
||||
699c25624e99c72fd45cfdb5660920c2 basn4a08_png-16.png
|
||||
95090b2194e811e8c490e12632e8a5f3 basn4a08_png-2.png
|
||||
c66f969b198eff8ddf663a3ccbb8e272 basn4a08_png-4.png
|
||||
02484627d57e7bcb45d3c1bff11a4687 basn4a08_png-6.png
|
||||
3bf91c974abc17e520c6a5efa883a58a basn4a08_png-8.png
|
||||
cd6b948268967b1e9b54d60607b8de0a basn6a08_png-1.png
|
||||
549e7a5566f37f7e08030cfa2aee8994 basn6a08_png-10.png
|
||||
d9e6472bc020607327cd082464d03616 basn6a08_png-12.png
|
||||
54e9b4d5e3fadd939a54722f05cadbe9 basn6a08_png-14.png
|
||||
94bba5bebc9e9209f2af13c6dd5a2c12 basn6a08_png-16.png
|
||||
16a9287d409a1c80158973f95eb3c04e basn6a08_png-2.png
|
||||
4065c615d124289bd06cd9c9bfb4adab basn6a08_png-4.png
|
||||
3235c0b759dd47e0c2df5bc9ac827e70 basn6a08_png-6.png
|
||||
0db8bf6fa69191c20936701ef365b82a basn6a08_png-8.png
|
||||
d3c82c8552f2e47c179372933725c8d7 p0_14_png-1.png
|
||||
7bce012868556bd04e5c0567b67d2896 p0_14_png-10.png
|
||||
d66fe6bbe653a18e60416e0cda1b1949 p0_14_png-12.png
|
||||
b3f01308ae57518ff157c926563b01b2 p0_14_png-14.png
|
||||
629bc0a76c5454e875eab9cacc653dfd p0_14_png-16.png
|
||||
fc2844a9f3c8e924e349180ba9e122dd p0_14_png-2.png
|
||||
428c7a19b9df4120d35b5df7fafdf253 p0_14_png-4.png
|
||||
0c1cc85c051dd95394d06103c8d9bbef p0_14_png-6.png
|
||||
230e4968cb445b222ee2095014ba1d26 p0_14_png-8.png
|
||||
5a6131ad9ea5d191ffcdf6435be89cb4 v4dwt_interleave_h.gsr105.j2k_0.pgx
|
||||
4426ed46f75a45782c551d82818b9e60 dwt_interleave_h.gsr105.jp2_0.pgx
|
||||
382e7297e062d729a7a7726e964f1a0a dwt_interleave_h.gsr105.jp2_1.pgx
|
||||
64c1027db97421e348f823178b5d9c4b dwt_interleave_h.gsr105.jp2_2.pgx
|
||||
63bf755af5a1f8a478d65079dc7c8964 issue205-tif.jp2.tif
|
||||
b01ed87dbac424bc820b2ac590e4884e issue236-ESYCC-CDEF.jp2_0.pgx
|
||||
2635cc00b1e18ef11adcba09e845d459 issue236-ESYCC-CDEF.jp2_1.pgx
|
||||
f9c95d0aec2f6e7b814fa1d09edcdbda issue236-ESYCC-CDEF.jp2_2.pgx
|
||||
5f0c1d5c5127c1eabb86a5e0112f139b issue559-eci-090-CIELab.jp2_0.pgx
|
||||
cdae87485eaada56be3671eec39452e6 issue559-eci-090-CIELab.jp2_1.pgx
|
||||
e163102afcc857cf001337178241f518 issue559-eci-090-CIELab.jp2_2.pgx
|
||||
b004b2e08b0dfb217c131b353cf157eb issue559-eci-091-CIELab.jp2_0.pgx
|
||||
2400da6b8ed6b1747b9913af544580f9 issue559-eci-091-CIELab.jp2_1.pgx
|
||||
cf73dda887967928dbcf5cc87ab204cc issue559-eci-091-CIELab.jp2_2.pgx
|
||||
|
||||
|
||||
@@ -29,16 +29,126 @@ image_to_j2k -i @INPUT_NR_PATH@/Bretagne2.ppm -o @TEMP_PATH@/Bretagne2_4.j2k -d
|
||||
image_to_j2k -i @INPUT_NR_PATH@/Cevennes1.bmp -o @TEMP_PATH@/Cevennes1.j2k -r 10
|
||||
image_to_j2k -i @INPUT_NR_PATH@/Cevennes2.ppm -o @TEMP_PATH@/Cevennes2.jp2 -r 50
|
||||
image_to_j2k -i @INPUT_NR_PATH@/Rome.bmp -o @TEMP_PATH@/Rome.jp2 -q 30,35,50 -p LRCP -n 3
|
||||
image_to_j2k -i @INPUT_NR_PATH@/X_4_2K_24_185_CBR_WB_000.tif -o @TEMP_PATH@/X_4_2K_24_185_CBR_WB_000.j2k -cinema2K 24
|
||||
image_to_j2k -i @INPUT_NR_PATH@/X_5_2K_24_235_CBR_STEM24_000.tif -o @TEMP_PATH@/X_5_2K_24_235_CBR_STEM24_000.j2k -cinema2K 24
|
||||
image_to_j2k -i @INPUT_NR_PATH@/X_6_2K_24_FULL_CBR_CIRCLE_000.tif -o @TEMP_PATH@/X_6_2K_24_FULL_CBR_CIRCLE_000.j2k -cinema2K 24
|
||||
|
||||
# related to issue 5
|
||||
image_to_j2k -i @INPUT_NR_PATH@/random-issue-0005.tif -o @TEMP_PATH@/random-issue-0005.tif.j2k
|
||||
# related to issue 62
|
||||
image_to_j2k -i @INPUT_NR_PATH@/tmp-issue-0062.raw -o @TEMP_PATH@/tmp-issue-0062-u.raw.j2k -F 512,512,1,16,u
|
||||
image_to_j2k -i @INPUT_NR_PATH@/tmp-issue-0062.raw -o @TEMP_PATH@/tmp-issue-0062-s.raw.j2k -F 512,512,1,16,s
|
||||
image_to_j2k -i @INPUT_NR_PATH@/X_4_2K_24_185_CBR_WB_000.tif -o @TEMP_PATH@/X_4_2K_24_185_CBR_WB_000_C2K_24.j2k -cinema2K 24
|
||||
image_to_j2k -i @INPUT_NR_PATH@/X_5_2K_24_235_CBR_STEM24_000.tif -o @TEMP_PATH@/X_5_2K_24_235_CBR_STEM24_000_C2K_24.j2k -cinema2K 24
|
||||
image_to_j2k -i @INPUT_NR_PATH@/X_6_2K_24_FULL_CBR_CIRCLE_000.tif -o @TEMP_PATH@/X_6_2K_24_FULL_CBR_CIRCLE_000_C2K_24.j2k -cinema2K 24
|
||||
image_to_j2k -i @INPUT_NR_PATH@/X_4_2K_24_185_CBR_WB_000.tif -o @TEMP_PATH@/X_4_2K_24_185_CBR_WB_000_C2K_48.j2k -cinema2K 48
|
||||
image_to_j2k -i @INPUT_NR_PATH@/X_5_2K_24_235_CBR_STEM24_000.tif -o @TEMP_PATH@/X_5_2K_24_235_CBR_STEM24_000_C2K_48.j2k -cinema2K 48
|
||||
image_to_j2k -i @INPUT_NR_PATH@/X_6_2K_24_FULL_CBR_CIRCLE_000.tif -o @TEMP_PATH@/X_6_2K_24_FULL_CBR_CIRCLE_000_C2K_48.j2k -cinema2K 48
|
||||
#not implemented in 1.5
|
||||
!image_to_j2k -i @INPUT_NR_PATH@/ElephantDream_4K.tif -o @TEMP_PATH@/ElephantDream_4K_C4K.j2k -cinema4K
|
||||
# issue 141
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue141.rawl -o @TEMP_PATH@/issue141.rawl.j2k -F 2048,32,1,16,u
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue141.rawl -o @TEMP_PATH@/issue141-I.rawl.j2k -F 2048,32,1,16,u -I
|
||||
# issue 46:
|
||||
image_to_j2k -i @INPUT_NR_PATH@/Bretagne2.ppm -o @TEMP_PATH@/Bretagne2_5.j2k -c [64,64]
|
||||
# issue 316
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue316.png -o @TEMP_PATH@/issue316.png.jp2
|
||||
# issue 416 (cdef for png with alpha) + issue 436 (MCT norm read buffer overflow for num comp > 3 + Issue 215 number of decomp levels
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/basn6a08.png -o @TEMP_PATH@/basn6a08.png.jp2 -n 6
|
||||
|
||||
# issue 322 limited tif support
|
||||
image_to_j2k -i @INPUT_NR_PATH@/flower-minisblack-01.tif -o @TEMP_PATH@/flower-minisblack-01.tif.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/flower-minisblack-02.tif -o @TEMP_PATH@/flower-minisblack-02.tif.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/flower-minisblack-04.tif -o @TEMP_PATH@/flower-minisblack-04.tif.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/flower-minisblack-06.tif -o @TEMP_PATH@/flower-minisblack-06.tif.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/flower-minisblack-08.tif -o @TEMP_PATH@/flower-minisblack-08.tif.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/flower-minisblack-10.tif -o @TEMP_PATH@/flower-minisblack-10.tif.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/flower-minisblack-12.tif -o @TEMP_PATH@/flower-minisblack-12.tif.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/flower-minisblack-14.tif -o @TEMP_PATH@/flower-minisblack-14.tif.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/flower-minisblack-16.tif -o @TEMP_PATH@/flower-minisblack-16.tif.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/flower-rgb-contig-02.tif -o @TEMP_PATH@/flower-rgb-contig-02.tif.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/flower-rgb-contig-04.tif -o @TEMP_PATH@/flower-rgb-contig-04.tif.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/flower-rgb-contig-08.tif -o @TEMP_PATH@/flower-rgb-contig-08.tif.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/flower-rgb-contig-10.tif -o @TEMP_PATH@/flower-rgb-contig-10.tif.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/flower-rgb-contig-12.tif -o @TEMP_PATH@/flower-rgb-contig-12.tif.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/flower-rgb-contig-14.tif -o @TEMP_PATH@/flower-rgb-contig-14.tif.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/flower-rgb-contig-16.tif -o @TEMP_PATH@/flower-rgb-contig-16.tif.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/flower-rgb-planar-02.tif -o @TEMP_PATH@/flower-rgb-planar-02.tif.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/flower-rgb-planar-04.tif -o @TEMP_PATH@/flower-rgb-planar-04.tif.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/flower-rgb-planar-08.tif -o @TEMP_PATH@/flower-rgb-planar-08.tif.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/flower-rgb-planar-10.tif -o @TEMP_PATH@/flower-rgb-planar-10.tif.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/flower-rgb-planar-12.tif -o @TEMP_PATH@/flower-rgb-planar-12.tif.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/flower-rgb-planar-14.tif -o @TEMP_PATH@/flower-rgb-planar-14.tif.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/flower-rgb-planar-16.tif -o @TEMP_PATH@/flower-rgb-planar-16.tif.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/basn6a08.tif -o @TEMP_PATH@/basn6a08.tif.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/basn4a08.tif -o @TEMP_PATH@/basn4a08.tif.jp2
|
||||
|
||||
# issue 203 BMP Files not handled properly
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue203-8bpp-width1.bmp -o @TEMP_PATH@/issue203-8bpp-width1.bmp.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue203-rle8.bmp -o @TEMP_PATH@/issue203-rle8.bmp.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue203-32x32-y8.bmp -o @TEMP_PATH@/issue203-32x32-y8.bmp.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue203-33x33-y8.bmp -o @TEMP_PATH@/issue203-33x33-y8.bmp.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue203-34x34-y8.bmp -o @TEMP_PATH@/issue203-34x34-y8.bmp.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue203-35x35-y8.bmp -o @TEMP_PATH@/issue203-35x35-y8.bmp.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue203-32x32-bgr.bmp -o @TEMP_PATH@/issue203-32x32-bgr.bmp.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue203-33x33-bgr.bmp -o @TEMP_PATH@/issue203-33x33-bgr.bmp.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue203-34x34-bgr.bmp -o @TEMP_PATH@/issue203-34x34-bgr.bmp.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue203-35x35-bgr.bmp -o @TEMP_PATH@/issue203-35x35-bgr.bmp.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue203-32x32-y-rle8.bmp -o @TEMP_PATH@/issue203-32x32-y-rle8.bmp.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue203-32x32-bgr-rle8.bmp -o @TEMP_PATH@/issue203-32x32-bgr-rle8.bmp.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue203-32x32-y-rle4.bmp -o @TEMP_PATH@/issue203-32x32-y-rle4.bmp.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue203-32x32-bgr-rle4.bmp -o @TEMP_PATH@/issue203-32x32-bgr-rle4.bmp.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue203-32x32-bgra.bmp -o @TEMP_PATH@/issue203-32x32-bgra.bmp.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue203-32x32-bgrx.bmp -o @TEMP_PATH@/issue203-32x32-bgrx.bmp.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue203-32x32-bgr16.bmp -o @TEMP_PATH@/issue203-32x32-bgr16.bmp.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue203-33x33-bgr16.bmp -o @TEMP_PATH@/issue203-33x33-bgr16.bmp.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue203-32x32-bgra16.bmp -o @TEMP_PATH@/issue203-32x32-bgra16.bmp.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue203-33x33-bgra16.bmp -o @TEMP_PATH@/issue203-33x33-bgra16.bmp.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue203-32x32-bgrx16.bmp -o @TEMP_PATH@/issue203-32x32-bgrx16.bmp.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue203-33x33-bgrx16.bmp -o @TEMP_PATH@/issue203-33x33-bgrx16.bmp.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue203-127x64-bgr16.bmp -o @TEMP_PATH@/issue203-127x64-bgr16.bmp.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue203-127x64-bgrx.bmp -o @TEMP_PATH@/issue203-127x64-bgrx.bmp.jp2
|
||||
|
||||
# issue 571 Lossless is not lossless on linux x86
|
||||
image_to_j2k -i @INPUT_NR_PATH@/issue571.tif -o @TEMP_PATH@/issue571.tif.j2k
|
||||
|
||||
# issue 536 (PNG images are always read as RGB(A) images) + issue 264 (convert.c is unmaintainable)
|
||||
# Test all images from pngsuite
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/basn0g01.png -o @TEMP_PATH@/basn0g01.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/basn0g02.png -o @TEMP_PATH@/basn0g02.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/basn0g04.png -o @TEMP_PATH@/basn0g04.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/basn0g08.png -o @TEMP_PATH@/basn0g08.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/basn0g16.png -o @TEMP_PATH@/basn0g16.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/basn2c08.png -o @TEMP_PATH@/basn2c08.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/basn2c16.png -o @TEMP_PATH@/basn2c16.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/basn3p01.png -o @TEMP_PATH@/basn3p01.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/basn3p02.png -o @TEMP_PATH@/basn3p02.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/basn3p04.png -o @TEMP_PATH@/basn3p04.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/basn3p08.png -o @TEMP_PATH@/basn3p08.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/basn4a08.png -o @TEMP_PATH@/basn4a08.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/basn4a16.png -o @TEMP_PATH@/basn4a16.png.jp2
|
||||
# already done image_to_j2k -i @INPUT_NR_PATH@/pngsuite/basn6a08.png -o @TEMP_PATH@/basn6a08.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/basn6a16.png -o @TEMP_PATH@/basn6a16.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/ftbbn0g01.png -o @TEMP_PATH@/ftbbn0g01.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/ftbbn0g02.png -o @TEMP_PATH@/ftbbn0g02.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/ftbbn0g04.png -o @TEMP_PATH@/ftbbn0g04.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/ftbbn2c16.png -o @TEMP_PATH@/ftbbn2c16.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/ftbbn3p08.png -o @TEMP_PATH@/ftbbn3p08.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/ftbgn2c16.png -o @TEMP_PATH@/ftbgn2c16.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/ftbgn3p08.png -o @TEMP_PATH@/ftbgn3p08.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/ftbrn2c08.png -o @TEMP_PATH@/ftbrn2c08.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/ftbwn0g16.png -o @TEMP_PATH@/ftbwn0g16.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/ftbwn3p08.png -o @TEMP_PATH@/ftbwn3p08.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/ftbyn3p08.png -o @TEMP_PATH@/ftbyn3p08.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/ftp0n0g08.png -o @TEMP_PATH@/ftp0n0g08.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/ftp0n2c08.png -o @TEMP_PATH@/ftp0n2c08.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/ftp0n3p08.png -o @TEMP_PATH@/ftp0n3p08.png.jp2
|
||||
image_to_j2k -i @INPUT_NR_PATH@/pngsuite/ftp1n3p08.png -o @TEMP_PATH@/ftp1n3p08.png.jp2
|
||||
|
||||
|
||||
# DECODER TEST SUITE
|
||||
j2k_to_image -i @INPUT_NR_PATH@/Bretagne2.j2k -o @TEMP_PATH@/Bretagne2.j2k.pgx
|
||||
j2k_to_image -i @INPUT_NR_PATH@/_00042.j2k -o @TEMP_PATH@/_00042.j2k.pgx
|
||||
j2k_to_image -i @INPUT_NR_PATH@/123.j2c -o @TEMP_PATH@/123.j2c.pgx
|
||||
# The 4 following tests should failed (kakadu indicates that they are corrupted)
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/broken.jp2 -o @TEMP_PATH@/broken.jp2.pgx
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/broken1.jp2 -o @TEMP_PATH@/broken1.jp2.pgx
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/broken2.jp2 -o @TEMP_PATH@/broken2.jp2.pgx
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/broken3.jp2 -o @TEMP_PATH@/broken3.jp2.pgx
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/broken4.jp2 -o @TEMP_PATH@/broken4.jp2.pgx
|
||||
@@ -153,3 +263,254 @@ j2k_to_image -i @INPUT_NR_PATH@/issue226.j2k -o @TEMP_PATH@/is
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/edf_c2_101463.jp2 -o @TEMP_PATH@/edf_c2_101463.jp2.pgx
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/edf_c2_1674177.jp2 -o @TEMP_PATH@/edf_c2_1674177.jp2.pgx
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/edf_c2_1673169.jp2 -o @TEMP_PATH@/edf_c2_1673169.jp2.pgx
|
||||
# issue 296
|
||||
#!j2k_to_image -i @INPUT_NR_PATH@/3459.pdf.asan.78.2734.0.jp2 -o @TEMP_PATH@/3459.pdf.asan.78.2734.0.jp2.pgx
|
||||
#!j2k_to_image -i @INPUT_NR_PATH@/3459.pdf.asan.78.2734.1.jp2 -o @TEMP_PATH@/3459.pdf.asan.78.2734.1.jp2.pgx
|
||||
#!j2k_to_image -i @INPUT_NR_PATH@/3459.pdf.asan.78.2734.2.jp2 -o @TEMP_PATH@/3459.pdf.asan.78.2734.2.jp2.pgx
|
||||
#!j2k_to_image -i @INPUT_NR_PATH@/3459.pdf.asan.6c.2734.0.jp2 -o @TEMP_PATH@/3459.pdf.asan.6c.2734.0.jp2.pgx
|
||||
#!j2k_to_image -i @INPUT_NR_PATH@/3459.pdf.asan.6c.2734.1.jp2 -o @TEMP_PATH@/3459.pdf.asan.6c.2734.1.jp2.pgx
|
||||
#!j2k_to_image -i @INPUT_NR_PATH@/3459.pdf.asan.6c.2734.2.jp2 -o @TEMP_PATH@/3459.pdf.asan.6c.2734.2.jp2.pgx
|
||||
# issue 362 (from pdfium fuzz engine)
|
||||
# Invalid PPM Marker
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/issue362-2863.jp2 -o @TEMP_PATH@/issue362-2863.jp2.pgx
|
||||
# Invalid ftyp box size
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/issue362-2866.jp2 -o @TEMP_PATH@/issue362-2866.jp2.pgx
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/issue362-2894.jp2 -o @TEMP_PATH@/issue362-2894.jp2.pgx
|
||||
# issue 363 (from pdfium fuzz engine)
|
||||
# Invalid Tile part length
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/issue363-4723.jp2 -o @TEMP_PATH@/issue363-4723.jp2.pgx
|
||||
# Invalid Marker length
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/issue363-4740.jp2 -o @TEMP_PATH@/issue363-4740.jp2.pgx
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/issue363-4792.jp2 -o @TEMP_PATH@/issue363-4792.jp2.pgx
|
||||
# issue 390 (from pdfium fuzz engine) Invalid segment size
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/issue390.jp2 -o @TEMP_PATH@/issue390.jp2.pgx
|
||||
# issue 391 (from pdfium fuzz engine) Invalid segment size
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/issue391.jp2 -o @TEMP_PATH@/issue391.jp2.pgx
|
||||
# issue 400 (from pdfium fuzz engine) Unknown Scod value in COD marker
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/issue400.jp2 -o @TEMP_PATH@/issue400.jp2.pgx
|
||||
# issue 413 (from pdfium fuzz engine) Unknown progression order in COD marker
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/issue413.jp2 -o @TEMP_PATH@/issue413.jp2.pgx
|
||||
# issue 364 (from pdfium fuzz engine)
|
||||
# Inconsistent box length for jp2 box
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/issue364-38.jp2 -o @TEMP_PATH@/issue364-38.jp2.pgx
|
||||
# No ihdr box
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/issue364-903.jp2 -o @TEMP_PATH@/issue364-903.jp2.pgx
|
||||
# issue 393 (from pdfium fuzz engine) Zppm found twice
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/issue393.jp2 -o @TEMP_PATH@/issue393.jp2.pgx
|
||||
# issue 395 (from pdfium fuzz engine) Stream too short
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/issue395.jp2 -o @TEMP_PATH@/issue395.jp2.pgx
|
||||
# issue 397 (from pdfium fuzz engine) Incomplete channel definitions.
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/issue397.jp2 -o @TEMP_PATH@/issue397.jp2.pgx
|
||||
# issue 399 (from pdfium fuzz engine) Incomplete channel definitions.
|
||||
j2k_to_image -i @INPUT_NR_PATH@/issue399.j2k -o @TEMP_PATH@/issue399.j2k.pgx
|
||||
# issue 408 (from pdfium fuzz engine) No COD marker in main j2k header.
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/issue408.jp2 -o @TEMP_PATH@/issue408.jp2.pgx
|
||||
# issue 412 Palette image with cdef fails to decompress.
|
||||
j2k_to_image -i @INPUT_NR_PATH@/issue412.jp2 -o @TEMP_PATH@/issue412.jp2.pgx
|
||||
# issue 428 Palette image with cdef fails to decompress properly.
|
||||
j2k_to_image -i @INPUT_NR_PATH@/issue412.jp2 -o @TEMP_PATH@/issue428.jp2.pgx -t 0
|
||||
# issue 414 Image with per channel alpha (cdef) does not decode properly.
|
||||
j2k_to_image -i @INPUT_NR_PATH@/issue414.jp2 -o @TEMP_PATH@/issue414.jp2.pgx
|
||||
# issue 418 (from pdfium fuzz engine) Tile part length size inconsistent with stream length.
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/issue418.jp2 -o @TEMP_PATH@/issue418.jp2.pgx
|
||||
# issue 420 (from pdfium fuzz engine) Illegal custom precinct exponent.
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/issue420.jp2 -o @TEMP_PATH@/issue420.jp2.pgx
|
||||
# issue 422 (rework of issue 411). ycc with odd width/height
|
||||
j2k_to_image -i @INPUT_NR_PATH@/issue411-ycc444.jp2 -o @TEMP_PATH@/issue411-ycc444.jp2.pgx
|
||||
j2k_to_image -i @INPUT_NR_PATH@/issue411-ycc422.jp2 -o @TEMP_PATH@/issue411-ycc422.jp2.pgx
|
||||
j2k_to_image -i @INPUT_NR_PATH@/issue411-ycc420.jp2 -o @TEMP_PATH@/issue411-ycc420.jp2.pgx
|
||||
# issue 429 (from pdfium fuzz engine) 0 entries in PCLR box.
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/issue429.jp2 -o @TEMP_PATH@/issue429.jp2.pgx
|
||||
# issue 432 (from pdfium fuzz engine) Overflow in tcd tilec data size computation.
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/issue432.jp2 -o @TEMP_PATH@/issue432.jp2.pgx
|
||||
# issue 427 image width is 0
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/issue427-null-image-size.jp2 -o @TEMP_PATH@/issue427-null-image-size.jp2.pgx
|
||||
# issue 427 illegal tile offset
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/issue427-illegal-tile-offset.jp2 -o @TEMP_PATH@/issue427-illegal-tile-offset.jp2.pgx
|
||||
# issue 458 component precision upscaling
|
||||
j2k_to_image -i @INPUT_NR_PATH@/issue458.jp2 -o @TEMP_PATH@/issue458.jp2.pgx
|
||||
# issue 476 Multiple COD in MH
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/issue476.jp2 -o @TEMP_PATH@/issue476.jp2.pgx
|
||||
# issue 475 Invalid number of layers
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/issue475.jp2 -o @TEMP_PATH@/issue475.jp2.pgx
|
||||
# issue 495 Overflow op_image_comp_header_updat
|
||||
j2k_to_image -i @INPUT_NR_PATH@/issue495.jp2 -o @TEMP_PATH@/issue495.jp2.pgx
|
||||
|
||||
# OPTIONS NOT IMPLEMENTED >
|
||||
|
||||
# # decode with specific area
|
||||
# # prec=12; nb_c=1
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_04.j2k -o @TEMP_PATH@/p1_04.j2k.png -d 0,0,1024,1024
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_04.j2k -o @TEMP_PATH@/p1_04_1.j2k.png -d 512,640,640,768
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_04.j2k -o @TEMP_PATH@/p1_04_2.j2k.png -d 896,896,1024,1024
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_04.j2k -o @TEMP_PATH@/p1_04_3.j2k.png -d 100,500,300,800
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_04.j2k -o @TEMP_PATH@/p1_04_4.j2k.png -d 260,520,360,600
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_04.j2k -o @TEMP_PATH@/p1_04_5.j2k.png -d 260,520,360,660
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_04.j2k -o @TEMP_PATH@/p1_04_6.j2k.png -d 360,520,400,600
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_04.j2k -o @TEMP_PATH@/p1_04_10.j2k.png -d 0,0,1024,1024 -r 2
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_04.j2k -o @TEMP_PATH@/p1_04_11.j2k.png -d 512,640,640,768 -r 2
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_04.j2k -o @TEMP_PATH@/p1_04_12.j2k.png -d 896,896,1024,1024 -r 2
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_04.j2k -o @TEMP_PATH@/p1_04_13.j2k.png -d 100,500,300,800 -r 2
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_04.j2k -o @TEMP_PATH@/p1_04_14.j2k.png -d 260,520,360,600 -r 2
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_04.j2k -o @TEMP_PATH@/p1_04_15.j2k.png -d 260,520,360,660 -r 2
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_04.j2k -o @TEMP_PATH@/p1_04_16.j2k.png -d 360,520,400,600 -r 2
|
||||
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_04.j2k -o @TEMP_PATH@/p1_04_17_t63.j2k.png -t 63
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_04.j2k -o @TEMP_PATH@/p1_04_17_t63_r2.j2k.png -t 63 -r 2
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_04.j2k -o @TEMP_PATH@/p1_04_18.t12.j2k.png -t 12
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_04.j2k -o @TEMP_PATH@/p1_04_19_t12_r1.j2k.png -t 12 -r 1
|
||||
|
||||
# # prec=8; nb_c=3
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06.j2k.png -d 0,0,12,12
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_1.j2k.png -d 1,8,8,11
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_2.j2k.png -d 9,9,12,12
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_3.j2k.png -d 10,4,12,10
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_4.j2k.png -d 3,3,9,9
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_5.j2k.png -d 4,4,7,7
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_6.j2k.png -d 4,4,5,5
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_7.j2k.png -d 0,0,12,12 -r 1
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_7_1.j2k.png -d 1,8,8,11 -r 1
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_7_2.j2k.png -d 9,9,12,12 -r 1
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_7_3.j2k.png -d 10,4,12,10 -r 1
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_7_4.j2k.png -d 3,3,9,9 -r 1
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_7_5.j2k.png -d 4,4,7,7 -r 1
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_7_6.j2k.png -d 4,4,5,5 -r 1
|
||||
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_8_6.j2k.png -d 9,9,12,12 -r 2
|
||||
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_9.j2k.png -t 0
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_9_1.j2k.png -t 5
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_9_2.j2k.png -t 9
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_9_3.j2k.png -t 15
|
||||
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_10.j2k.png -t 0 -r 2
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_10_1.j2k.png -t 5 -r 2
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_10_2.j2k.png -t 9 -r 2
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_10_3.j2k.png -t 15 -r 2
|
||||
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_11.j2k.png -r 4
|
||||
|
||||
# # prec=4; nb_c=3 ; signd=yes
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04.j2k.png -d 0,0,256,256
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04_1.j2k.png -d 128,0,256,128
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04_2.j2k.png -d 50,10,120,200
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04_3.j2k.png -d 10,150,190,210
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04_4.j2k.png -d 100,80,200,150
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04_5.j2k.png -d 150,20,200,50
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04_6.j2k.png -d 0,0,256,256 -r 2
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04_6_1.j2k.png -d 128,0,256,128 -r 2
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04_6_2.j2k.png -d 50,10,120,200 -r 2
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04_6_3.j2k.png -d 10,150,190,210 -r 2
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04_6_4.j2k.png -d 100,80,200,150 -r 2
|
||||
# j2k_to_image -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04_6_5.j2k.png -d 150,20,200,50 -r 2
|
||||
|
||||
# # prec=8; nb_c=1 ; non standard origin (image offset and tile offset); sample sep: 2x1
|
||||
# #j2k_to_image -i @INPUT_CONF_PATH@/p1_01.j2k -o @TEMP_PATH@/p1_01.j2k.png -d 5,128,127,226
|
||||
# #j2k_to_image -i @INPUT_CONF_PATH@/p1_01.j2k -o @TEMP_PATH@/p1_01_1.j2k.png -d 5,128,122,99
|
||||
# #j2k_to_image -i @INPUT_CONF_PATH@/p1_01.j2k -o @TEMP_PATH@/p1_01_2.j2k.png -d 50,10,120,200
|
||||
# #j2k_to_image -i @INPUT_CONF_PATH@/p1_01.j2k -o @TEMP_PATH@/p1_01_3.j2k.png -d 10,150,190,210
|
||||
# #j2k_to_image -i @INPUT_CONF_PATH@/p1_01.j2k -o @TEMP_PATH@/p1_01_4.j2k.png -d 100,80,200,150
|
||||
# #j2k_to_image -i @INPUT_CONF_PATH@/p1_01.j2k -o @TEMP_PATH@/p1_01_5.j2k.png -d 150,20,200,50
|
||||
|
||||
# < NOT IMPLEMENTED
|
||||
|
||||
# issue 322 limited tif support
|
||||
# GRAYSCALE
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/a1_mono.j2c -o @TEMP_PATH@/a1_mono_tif-1.tif -p 1S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/a1_mono.j2c -o @TEMP_PATH@/a1_mono_tif-2.tif -p 2S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/a1_mono.j2c -o @TEMP_PATH@/a1_mono_tif-4.tif -p 4S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/a1_mono.j2c -o @TEMP_PATH@/a1_mono_tif-6.tif -p 6S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/a1_mono.j2c -o @TEMP_PATH@/a1_mono_tif-8.tif -p 8S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/a1_mono.j2c -o @TEMP_PATH@/a1_mono_tif-10.tif -p 10S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/a1_mono.j2c -o @TEMP_PATH@/a1_mono_tif-12.tif -p 12S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/a1_mono.j2c -o @TEMP_PATH@/a1_mono_tif-14.tif -p 14S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/a1_mono.j2c -o @TEMP_PATH@/a1_mono_tif-16.tif -p 16S
|
||||
# GRAYSCALE ALPHA
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn4a08.jp2 -o @TEMP_PATH@/basn4a08_tif-1.tif -p 1S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn4a08.jp2 -o @TEMP_PATH@/basn4a08_tif-2.tif -p 2S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn4a08.jp2 -o @TEMP_PATH@/basn4a08_tif-4.tif -p 4S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn4a08.jp2 -o @TEMP_PATH@/basn4a08_tif-6.tif -p 6S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn4a08.jp2 -o @TEMP_PATH@/basn4a08_tif-8.tif -p 8S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn4a08.jp2 -o @TEMP_PATH@/basn4a08_tif-10.tif -p 10S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn4a08.jp2 -o @TEMP_PATH@/basn4a08_tif-12.tif -p 12S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn4a08.jp2 -o @TEMP_PATH@/basn4a08_tif-14.tif -p 14S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn4a08.jp2 -o @TEMP_PATH@/basn4a08_tif-16.tif -p 16S
|
||||
# RGB
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/p0_14.j2k -o @TEMP_PATH@/p0_14_tif-1.tif -p 1S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/p0_14.j2k -o @TEMP_PATH@/p0_14_tif-2.tif -p 2S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/p0_14.j2k -o @TEMP_PATH@/p0_14_tif-4.tif -p 4S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/p0_14.j2k -o @TEMP_PATH@/p0_14_tif-6.tif -p 6S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/p0_14.j2k -o @TEMP_PATH@/p0_14_tif-8.tif -p 8S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/p0_14.j2k -o @TEMP_PATH@/p0_14_tif-10.tif -p 10S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/p0_14.j2k -o @TEMP_PATH@/p0_14_tif-12.tif -p 12S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/p0_14.j2k -o @TEMP_PATH@/p0_14_tif-14.tif -p 14S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/p0_14.j2k -o @TEMP_PATH@/p0_14_tif-16.tif -p 16S
|
||||
# RGBA
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn6a08.jp2 -o @TEMP_PATH@/basn6a08_tif-1.tif -p 1S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn6a08.jp2 -o @TEMP_PATH@/basn6a08_tif-2.tif -p 2S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn6a08.jp2 -o @TEMP_PATH@/basn6a08_tif-4.tif -p 4S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn6a08.jp2 -o @TEMP_PATH@/basn6a08_tif-6.tif -p 6S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn6a08.jp2 -o @TEMP_PATH@/basn6a08_tif-8.tif -p 8S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn6a08.jp2 -o @TEMP_PATH@/basn6a08_tif-10.tif -p 10S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn6a08.jp2 -o @TEMP_PATH@/basn6a08_tif-12.tif -p 12S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn6a08.jp2 -o @TEMP_PATH@/basn6a08_tif-14.tif -p 14S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn6a08.jp2 -o @TEMP_PATH@/basn6a08_tif-16.tif -p 16S
|
||||
|
||||
#issue 235 CMAP outside jp2h box. CMAP is buggy
|
||||
j2k_to_image -i @INPUT_NR_PATH@/issue235.jp2 -o @TEMP_PATH@/issue235.jp2.pgx
|
||||
|
||||
# issue 264, add checks for png
|
||||
# GRAYSCALE
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/a1_mono.j2c -o @TEMP_PATH@/a1_mono_png-1.png -p 1S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/a1_mono.j2c -o @TEMP_PATH@/a1_mono_png-2.png -p 2S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/a1_mono.j2c -o @TEMP_PATH@/a1_mono_png-4.png -p 4S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/a1_mono.j2c -o @TEMP_PATH@/a1_mono_png-6.png -p 6S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/a1_mono.j2c -o @TEMP_PATH@/a1_mono_png-8.png -p 8S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/a1_mono.j2c -o @TEMP_PATH@/a1_mono_png-10.png -p 10S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/a1_mono.j2c -o @TEMP_PATH@/a1_mono_png-12.png -p 12S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/a1_mono.j2c -o @TEMP_PATH@/a1_mono_png-14.png -p 14S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/a1_mono.j2c -o @TEMP_PATH@/a1_mono_png-16.png -p 16S
|
||||
# GRAYSCALE ALPHA
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn4a08.jp2 -o @TEMP_PATH@/basn4a08_png-1.png -p 1S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn4a08.jp2 -o @TEMP_PATH@/basn4a08_png-2.png -p 2S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn4a08.jp2 -o @TEMP_PATH@/basn4a08_png-4.png -p 4S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn4a08.jp2 -o @TEMP_PATH@/basn4a08_png-6.png -p 6S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn4a08.jp2 -o @TEMP_PATH@/basn4a08_png-8.png -p 8S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn4a08.jp2 -o @TEMP_PATH@/basn4a08_png-10.png -p 10S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn4a08.jp2 -o @TEMP_PATH@/basn4a08_png-12.png -p 12S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn4a08.jp2 -o @TEMP_PATH@/basn4a08_png-14.png -p 14S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn4a08.jp2 -o @TEMP_PATH@/basn4a08_png-16.png -p 16S
|
||||
# RGB
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/p0_14.j2k -o @TEMP_PATH@/p0_14_png-1.png -p 1S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/p0_14.j2k -o @TEMP_PATH@/p0_14_png-2.png -p 2S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/p0_14.j2k -o @TEMP_PATH@/p0_14_png-4.png -p 4S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/p0_14.j2k -o @TEMP_PATH@/p0_14_png-6.png -p 6S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/p0_14.j2k -o @TEMP_PATH@/p0_14_png-8.png -p 8S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/p0_14.j2k -o @TEMP_PATH@/p0_14_png-10.png -p 10S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/p0_14.j2k -o @TEMP_PATH@/p0_14_png-12.png -p 12S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/p0_14.j2k -o @TEMP_PATH@/p0_14_png-14.png -p 14S
|
||||
j2k_to_image -i @INPUT_CONF_PATH@/p0_14.j2k -o @TEMP_PATH@/p0_14_png-16.png -p 16S
|
||||
# RGBA
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn6a08.jp2 -o @TEMP_PATH@/basn6a08_png-1.png -p 1S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn6a08.jp2 -o @TEMP_PATH@/basn6a08_png-2.png -p 2S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn6a08.jp2 -o @TEMP_PATH@/basn6a08_png-4.png -p 4S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn6a08.jp2 -o @TEMP_PATH@/basn6a08_png-6.png -p 6S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn6a08.jp2 -o @TEMP_PATH@/basn6a08_png-8.png -p 8S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn6a08.jp2 -o @TEMP_PATH@/basn6a08_png-10.png -p 10S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn6a08.jp2 -o @TEMP_PATH@/basn6a08_png-12.png -p 12S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn6a08.jp2 -o @TEMP_PATH@/basn6a08_png-14.png -p 14S
|
||||
j2k_to_image -i @INPUT_NR_PATH@/basn6a08.jp2 -o @TEMP_PATH@/basn6a08_png-16.png -p 16S
|
||||
|
||||
# issue 388
|
||||
!j2k_to_image -i @INPUT_NR_PATH@/v4dwt_interleave_h.gsr105.j2k -o @TEMP_PATH@/v4dwt_interleave_h.gsr105.j2k.pgx
|
||||
j2k_to_image -i @INPUT_NR_PATH@/dwt_interleave_h.gsr105.jp2 -o @TEMP_PATH@/dwt_interleave_h.gsr105.jp2.pgx
|
||||
|
||||
# PR 559 : CMYK tif output
|
||||
j2k_to_image -i @INPUT_NR_PATH@/issue205.jp2 -o @TEMP_PATH@/issue205-tif.jp2.tif
|
||||
|
||||
# issue 236: esYCC colorspace
|
||||
j2k_to_image -i @INPUT_NR_PATH@/issue236-ESYCC-CDEF.jp2 -o @TEMP_PATH@/issue236-ESYCC-CDEF.jp2.pgx
|
||||
|
||||
# issue 326 + PR 559: CIELab colorspace
|
||||
j2k_to_image -i @INPUT_NR_PATH@/issue559-eci-090-CIELab.jp2 -o @TEMP_PATH@/issue559-eci-090-CIELab.jp2.pgx
|
||||
j2k_to_image -i @INPUT_NR_PATH@/issue559-eci-091-CIELab.jp2 -o @TEMP_PATH@/issue559-eci-091-CIELab.jp2.pgx
|
||||
|
||||
142
tests/pdf2jp2.c
Normal file
142
tests/pdf2jp2.c
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Mathieu Malaterre <mathieu.malaterre@voxxl.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Extract all JP2 files contained within a PDF file.
|
||||
*
|
||||
* Technically you could simply use mutool, eg:
|
||||
*
|
||||
* $ mutool show -be -o obj58.jp2 Bug691816.pdf 58
|
||||
*
|
||||
* to extract a given JP2 file from within a PDF
|
||||
* However it happens sometimes that the PDF is itself corrupted, this tools is
|
||||
* a lame PDF parser which only extract stream contained in JPXDecode box
|
||||
* only work on linux since I need memmem function
|
||||
*/
|
||||
|
||||
/*
|
||||
* Add support for other signatures:
|
||||
*
|
||||
* obj<</Subtype/Image/Length 110494/Filter/JPXDecode/BitsPerComponent 8/ColorSpace/DeviceRGB/Width 712/Height 1052>>stream
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#define NUMJP2 32
|
||||
int i, c = 0;
|
||||
long offets[NUMJP2];
|
||||
char buffer[512];
|
||||
#define BUFLEN 4096
|
||||
int cont = 1;
|
||||
FILE *f;
|
||||
size_t nread;
|
||||
char haystack[BUFLEN];
|
||||
const char needle[] = "JPXDecode";
|
||||
|
||||
const size_t nlen = strlen( needle );
|
||||
const size_t flen = BUFLEN - nlen;
|
||||
char *fpos = haystack + nlen;
|
||||
const char *filename;
|
||||
if( argc < 2 ) return 1;
|
||||
|
||||
filename = argv[1];
|
||||
|
||||
memset( haystack, 0, nlen );
|
||||
|
||||
f = fopen( filename, "rb" );
|
||||
while( cont )
|
||||
{
|
||||
const char *ret;
|
||||
size_t hlen;
|
||||
nread = fread(fpos, 1, flen, f);
|
||||
hlen = nlen + nread;
|
||||
ret = memmem( haystack, hlen, needle, nlen);
|
||||
if( ret )
|
||||
{
|
||||
const long cpos = ftell(f);
|
||||
const ptrdiff_t diff = ret - haystack;
|
||||
assert( diff >= 0 );
|
||||
/*fprintf( stdout, "Found it: %lx\n", (ptrdiff_t)cpos - (ptrdiff_t)hlen + diff);*/
|
||||
offets[c++] = (ptrdiff_t)cpos - (ptrdiff_t)hlen + diff;
|
||||
}
|
||||
cont = (nread == flen);
|
||||
memcpy( haystack, haystack + nread, nlen );
|
||||
}
|
||||
|
||||
assert( feof( f ) );
|
||||
|
||||
for( i = 0; i < c; ++i )
|
||||
{
|
||||
int s, len = 0;
|
||||
char *r;
|
||||
const int ret = fseek(f, offets[i], SEEK_SET);
|
||||
assert( ret == 0 );
|
||||
r = fgets(buffer, sizeof(buffer), f);
|
||||
assert( r );
|
||||
/*fprintf( stderr, "DEBUG: %s", r );*/
|
||||
s = sscanf(r, "JPXDecode]/Length %d/Width %*d/BitsPerComponent %*d/Height %*d", &len);
|
||||
if( s == 0 )
|
||||
{ // try again harder
|
||||
const int ret = fseek(f, offets[i] - 40, SEEK_SET); // 40 is magic number
|
||||
assert( ret == 0 );
|
||||
r = fgets(buffer, sizeof(buffer), f);
|
||||
assert( r );
|
||||
const char needle2[] = "/Length";
|
||||
char * s2 = strstr(buffer, needle2);
|
||||
s = sscanf(s2, "/Length %d/", &len);
|
||||
}
|
||||
if( s == 1 )
|
||||
{
|
||||
FILE *jp2;
|
||||
int j;
|
||||
char jp2fn[512];
|
||||
sprintf( jp2fn, "%s.%d.jp2", filename, i );
|
||||
jp2 = fopen( jp2fn, "wb" );
|
||||
for( j = 0; j < len; ++j )
|
||||
{
|
||||
int v = fgetc(f);
|
||||
int ret2 = fputc(v, jp2);
|
||||
assert( ret2 != EOF );
|
||||
}
|
||||
fclose( jp2 );
|
||||
#if 0
|
||||
/* TODO need to check we reached endstream */
|
||||
r = fgets(buffer, sizeof(buffer), f);
|
||||
fprintf( stderr, "DEBUG: [%s]", r );
|
||||
r = fgets(buffer, sizeof(buffer), f);
|
||||
fprintf( stderr, "DEBUG: [%s]", r );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
139
tests/ppm2rgb3.c
Normal file
139
tests/ppm2rgb3.c
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Mathieu Malaterre <mathieu.malaterre@voxxl.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Technically on UNIX, one can simply call `ppmtorgb3`, but on my system it
|
||||
* did not work. So I had to write my own.
|
||||
*/
|
||||
|
||||
#include <stdio.h> /* fprintf */
|
||||
#include <string.h> /* strcmp */
|
||||
#include <stdlib.h> /* malloc */
|
||||
|
||||
static const char magic[] = "P6";
|
||||
|
||||
static int readheader( FILE *ppm, int *X, int *Y, int *bpp )
|
||||
{
|
||||
char buffer[256];
|
||||
char strbuffer[256];
|
||||
char *line;
|
||||
int n;
|
||||
|
||||
*X = *Y = *bpp = 0;
|
||||
|
||||
line = fgets(buffer, sizeof(buffer), ppm);
|
||||
if( !line ) return 0;
|
||||
n = sscanf(buffer, "%255[^\r\n]", strbuffer);
|
||||
if( n != 1 ) return 0;
|
||||
if( strcmp(strbuffer, magic ) != 0 ) return 0;
|
||||
|
||||
/* skip comments */
|
||||
while( fgets(buffer, sizeof(buffer), ppm) && *buffer == '#' )
|
||||
{
|
||||
}
|
||||
n = sscanf(buffer, "%d %d", X,Y);
|
||||
if( n != 2 ) return 0;
|
||||
line = fgets(buffer, sizeof(buffer), ppm);
|
||||
if( !line ) return 0;
|
||||
n = sscanf(buffer, "%d", bpp);
|
||||
if( n != 1 ) return 0;
|
||||
if( *bpp != 255 ) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int writeoutput( const char *fn, FILE *ppm, int X, int Y, int bpp )
|
||||
{
|
||||
FILE *outf[] = {NULL, NULL, NULL};
|
||||
int i, x, y = 0;
|
||||
char outfn[256];
|
||||
static const char *exts[3] = {
|
||||
"red",
|
||||
"grn",
|
||||
"blu"
|
||||
};
|
||||
char *image_line = NULL;
|
||||
int ok = 0;
|
||||
|
||||
/* write single comp as PGM: P5 */
|
||||
for( i = 0; i < 3; ++i )
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
#define snprintf _snprintf /* Visual Studio */
|
||||
#endif
|
||||
snprintf( outfn, sizeof(outfn), "%s.%s.pgm", fn, exts[i] );
|
||||
outf[i] = fopen( outfn, "wb" );
|
||||
if( !outf[i] ) goto cleanup;
|
||||
/* write header */
|
||||
fprintf( outf[i], "P5\n" );
|
||||
fprintf( outf[i], "%d %d\n", X, Y );
|
||||
fprintf( outf[i], "%d\n", bpp );
|
||||
}
|
||||
|
||||
/* write pixel data */
|
||||
image_line = (char*)malloc( (size_t)X * 3 * sizeof(char) );
|
||||
if( !image_line ) goto cleanup;
|
||||
while( fread(image_line, sizeof(char), (size_t)X * 3, ppm) == (size_t)X * 3 )
|
||||
{
|
||||
for( x = 0; x < X; ++x )
|
||||
for( i = 0; i < 3; ++i )
|
||||
if( fputc( image_line[3*x+i], outf[i] ) == EOF ) goto cleanup;
|
||||
++y;
|
||||
}
|
||||
if( y == Y )
|
||||
ok = 1;
|
||||
cleanup:
|
||||
free(image_line);
|
||||
for( i = 0; i < 3; ++i )
|
||||
if( outf[i] ) fclose( outf[i] );
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const char *fn;
|
||||
FILE *ppm = NULL;
|
||||
int X, Y, bpp;
|
||||
int ok = 0;
|
||||
|
||||
if( argc < 2 )
|
||||
{
|
||||
fprintf( stderr, "%s input.ppm\n", argv[0] );
|
||||
goto cleanup;
|
||||
}
|
||||
fn = argv[1];
|
||||
ppm = fopen( fn, "rb" );
|
||||
|
||||
if( !readheader( ppm, &X, &Y, &bpp ) ) goto cleanup;
|
||||
|
||||
if( !writeoutput(fn, ppm, X, Y, bpp ) ) goto cleanup;
|
||||
|
||||
ok = 1;
|
||||
cleanup:
|
||||
if(ppm) fclose(ppm);
|
||||
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
@@ -1,9 +1,17 @@
|
||||
# UNIT TESTS
|
||||
# UNIT TESTS
|
||||
|
||||
add_executable(testempty1 testempty1.c)
|
||||
add_executable(testempty2 testempty2.c)
|
||||
target_link_libraries(testempty1 openjpeg)
|
||||
target_link_libraries(testempty2 openjpeg)
|
||||
include_directories(
|
||||
${OPENJPEG_BINARY_DIR}/libopenjpeg # opj_config.h
|
||||
${OPENJPEG_SOURCE_DIR}/libopenjpeg
|
||||
)
|
||||
|
||||
add_test(NAME testempty1 COMMAND testempty1)
|
||||
add_test(NAME testempty2 COMMAND testempty2)
|
||||
set(unit_test
|
||||
testempty0
|
||||
testempty1
|
||||
testempty2
|
||||
)
|
||||
foreach(ut ${unit_test})
|
||||
add_executable(${ut} ${ut}.c)
|
||||
target_link_libraries(${ut} openjpeg)
|
||||
add_test(NAME ${ut} COMMAND ${ut})
|
||||
endforeach()
|
||||
|
||||
7
tests/unit/testempty0.c
Normal file
7
tests/unit/testempty0.c
Normal file
@@ -0,0 +1,7 @@
|
||||
#include "openjpeg.h"
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
return 0;
|
||||
}
|
||||
@@ -111,6 +111,15 @@ int main(int argc, char *argv[])
|
||||
cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
|
||||
assert( cio );
|
||||
bSuccess = opj_encode(cinfo, cio, image, NULL);
|
||||
|
||||
if( !bSuccess )
|
||||
{
|
||||
opj_cio_close(cio);
|
||||
opj_destroy_compress(cinfo);
|
||||
opj_image_destroy(image);
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert( bSuccess );
|
||||
|
||||
codestream_length = (size_t)cio_tell(cio);
|
||||
|
||||
@@ -115,6 +115,15 @@ int main(int argc, char *argv[])
|
||||
cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
|
||||
assert( cio );
|
||||
bSuccess = opj_encode(cinfo, cio, image, NULL);
|
||||
|
||||
if( !bSuccess )
|
||||
{
|
||||
opj_cio_close(cio);
|
||||
opj_destroy_compress(cinfo);
|
||||
opj_image_destroy(image);
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert( bSuccess );
|
||||
|
||||
codestream_length = (size_t)cio_tell(cio);
|
||||
|
||||
5
thirdparty/CMakeLists.txt
vendored
5
thirdparty/CMakeLists.txt
vendored
@@ -57,7 +57,10 @@ IF(BUILD_THIRDPARTY)
|
||||
message(STATUS "We will build TIFF lib from thirdparty")
|
||||
ADD_SUBDIRECTORY(libtiff)
|
||||
SET(TIFF_LIBNAME tiff PARENT_SCOPE)
|
||||
SET(TIFF_INCLUDE_DIRNAME ${OPENJPEG_SOURCE_DIR}/thirdparty/libtiff PARENT_SCOPE)
|
||||
SET(TIFF_INCLUDE_DIRNAME
|
||||
${OPENJPEG_SOURCE_DIR}/thirdparty/libtiff
|
||||
${OPENJPEG_BINARY_DIR}/thirdparty/libtiff
|
||||
PARENT_SCOPE)
|
||||
SET(HAVE_TIFF_H 1 PARENT_SCOPE)
|
||||
SET(HAVE_LIBTIFF 1 PARENT_SCOPE)
|
||||
ELSE (BUILD_THIRDPARTY)
|
||||
|
||||
201
thirdparty/include/zconf.h
vendored
201
thirdparty/include/zconf.h
vendored
@@ -1,5 +1,5 @@
|
||||
/* zconf.h -- configuration of the zlib compression library
|
||||
* Copyright (C) 1995-2010 Jean-loup Gailly.
|
||||
* Copyright (C) 1995-2013 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@@ -15,11 +15,13 @@
|
||||
* this permanently in zconf.h using "./configure --zprefix".
|
||||
*/
|
||||
#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
|
||||
# define Z_PREFIX_SET
|
||||
|
||||
/* all linked symbols */
|
||||
# define _dist_code z__dist_code
|
||||
# define _length_code z__length_code
|
||||
# define _tr_align z__tr_align
|
||||
# define _tr_flush_bits z__tr_flush_bits
|
||||
# define _tr_flush_block z__tr_flush_block
|
||||
# define _tr_init z__tr_init
|
||||
# define _tr_stored_block z__tr_stored_block
|
||||
@@ -27,9 +29,11 @@
|
||||
# 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
|
||||
# ifndef Z_SOLO
|
||||
# define compress z_compress
|
||||
# define compress2 z_compress2
|
||||
# define compressBound z_compressBound
|
||||
# endif
|
||||
# define crc32 z_crc32
|
||||
# define crc32_combine z_crc32_combine
|
||||
# define crc32_combine64 z_crc32_combine64
|
||||
@@ -40,44 +44,53 @@
|
||||
# define deflateInit2_ z_deflateInit2_
|
||||
# define deflateInit_ z_deflateInit_
|
||||
# define deflateParams z_deflateParams
|
||||
# define deflatePending z_deflatePending
|
||||
# define deflatePrime z_deflatePrime
|
||||
# define deflateReset z_deflateReset
|
||||
# define deflateResetKeep z_deflateResetKeep
|
||||
# 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
|
||||
# ifndef Z_SOLO
|
||||
# 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 gzgetc_ z_gzgetc_
|
||||
# define gzgets z_gzgets
|
||||
# define gzoffset z_gzoffset
|
||||
# define gzoffset64 z_gzoffset64
|
||||
# define gzopen z_gzopen
|
||||
# define gzopen64 z_gzopen64
|
||||
# ifdef _WIN32
|
||||
# define gzopen_w z_gzopen_w
|
||||
# endif
|
||||
# define gzprintf z_gzprintf
|
||||
# define gzvprintf z_gzvprintf
|
||||
# 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
|
||||
# endif
|
||||
# define inflate z_inflate
|
||||
# define inflateBack z_inflateBack
|
||||
# define inflateBackEnd z_inflateBackEnd
|
||||
@@ -92,16 +105,22 @@
|
||||
# define inflateReset z_inflateReset
|
||||
# define inflateReset2 z_inflateReset2
|
||||
# define inflateSetDictionary z_inflateSetDictionary
|
||||
# define inflateGetDictionary z_inflateGetDictionary
|
||||
# define inflateSync z_inflateSync
|
||||
# define inflateSyncPoint z_inflateSyncPoint
|
||||
# define inflateUndermine z_inflateUndermine
|
||||
# define inflateResetKeep z_inflateResetKeep
|
||||
# define inflate_copyright z_inflate_copyright
|
||||
# define inflate_fast z_inflate_fast
|
||||
# define inflate_table z_inflate_table
|
||||
# define uncompress z_uncompress
|
||||
# ifndef Z_SOLO
|
||||
# define uncompress z_uncompress
|
||||
# endif
|
||||
# define zError z_zError
|
||||
# define zcalloc z_zcalloc
|
||||
# define zcfree z_zcfree
|
||||
# ifndef Z_SOLO
|
||||
# define zcalloc z_zcalloc
|
||||
# define zcfree z_zcfree
|
||||
# endif
|
||||
# define zlibCompileFlags z_zlibCompileFlags
|
||||
# define zlibVersion z_zlibVersion
|
||||
|
||||
@@ -111,7 +130,9 @@
|
||||
# define alloc_func z_alloc_func
|
||||
# define charf z_charf
|
||||
# define free_func z_free_func
|
||||
# define gzFile z_gzFile
|
||||
# ifndef Z_SOLO
|
||||
# define gzFile z_gzFile
|
||||
# endif
|
||||
# define gz_header z_gz_header
|
||||
# define gz_headerp z_gz_headerp
|
||||
# define in_func z_in_func
|
||||
@@ -197,6 +218,12 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(ZLIB_CONST) && !defined(z_const)
|
||||
# define z_const const
|
||||
#else
|
||||
# define z_const
|
||||
#endif
|
||||
|
||||
/* Some Mac compilers merge all .h files incorrectly: */
|
||||
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
|
||||
# define NO_DUMMY_DECL
|
||||
@@ -243,6 +270,14 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef Z_ARG /* function prototypes for stdarg */
|
||||
# if defined(STDC) || defined(Z_HAVE_STDARG_H)
|
||||
# define Z_ARG(args) args
|
||||
# else
|
||||
# define Z_ARG(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
|
||||
@@ -356,12 +391,47 @@ typedef uLong FAR uLongf;
|
||||
typedef Byte *voidp;
|
||||
#endif
|
||||
|
||||
#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
|
||||
# include <limits.h>
|
||||
# if (UINT_MAX == 0xffffffffUL)
|
||||
# define Z_U4 unsigned
|
||||
# elif (ULONG_MAX == 0xffffffffUL)
|
||||
# define Z_U4 unsigned long
|
||||
# elif (USHRT_MAX == 0xffffffffUL)
|
||||
# define Z_U4 unsigned short
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef Z_U4
|
||||
typedef Z_U4 z_crc_t;
|
||||
#else
|
||||
typedef unsigned long z_crc_t;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
|
||||
# define Z_HAVE_UNISTD_H
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */
|
||||
# define Z_HAVE_STDARG_H
|
||||
#endif
|
||||
|
||||
#ifdef STDC
|
||||
# include <sys/types.h> /* for off_t */
|
||||
# ifndef Z_SOLO
|
||||
# include <sys/types.h> /* for off_t */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
|
||||
# ifndef Z_SOLO
|
||||
# include <stdarg.h> /* for va_list */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifndef Z_SOLO
|
||||
# include <stddef.h> /* for wchar_t */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
|
||||
@@ -370,21 +440,38 @@ typedef uLong FAR uLongf;
|
||||
* both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
|
||||
* equivalently requesting no 64-bit operations
|
||||
*/
|
||||
#if -_LARGEFILE64_SOURCE - -1 == 1
|
||||
#if defined(_LARGEFILE64_SOURCE) && -_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
|
||||
#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
|
||||
# define Z_HAVE_UNISTD_H
|
||||
#endif
|
||||
#ifndef Z_SOLO
|
||||
# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
|
||||
# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
|
||||
# ifdef VMS
|
||||
# include <unixio.h> /* for off_t */
|
||||
# endif
|
||||
# ifndef z_off_t
|
||||
# define z_off_t off_t
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef SEEK_SET
|
||||
#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
|
||||
# define Z_LFS64
|
||||
#endif
|
||||
|
||||
#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
|
||||
# define Z_LARGE64
|
||||
#endif
|
||||
|
||||
#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
|
||||
# define Z_WANT64
|
||||
#endif
|
||||
|
||||
#if !defined(SEEK_SET) && !defined(Z_SOLO)
|
||||
# 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" */
|
||||
@@ -394,18 +481,14 @@ typedef uLong FAR uLongf;
|
||||
# define z_off_t long
|
||||
#endif
|
||||
|
||||
#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
|
||||
#if !defined(_WIN32) && defined(Z_LARGE64)
|
||||
# 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
|
||||
# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
|
||||
# define z_off64_t __int64
|
||||
# else
|
||||
# define z_off64_t z_off_t
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* MVS linker does not support external names larger than 8 bytes */
|
||||
|
||||
430
thirdparty/include/zconf.h.cmake.msvc
vendored
430
thirdparty/include/zconf.h.cmake.msvc
vendored
@@ -1,430 +0,0 @@
|
||||
/* 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 */
|
||||
343
thirdparty/include/zlib.h
vendored
343
thirdparty/include/zlib.h
vendored
@@ -1,7 +1,7 @@
|
||||
/* zlib.h -- interface of the 'zlib' general purpose compression library
|
||||
version 1.2.5, April 19th, 2010
|
||||
version 1.2.8, April 28th, 2013
|
||||
|
||||
Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
|
||||
Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,8 +24,8 @@
|
||||
|
||||
|
||||
The data format used by the zlib library is described by RFCs (Request for
|
||||
Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
|
||||
(zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
|
||||
Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
|
||||
(zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
|
||||
*/
|
||||
|
||||
#ifndef ZLIB_H
|
||||
@@ -37,11 +37,11 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ZLIB_VERSION "1.2.5"
|
||||
#define ZLIB_VERNUM 0x1250
|
||||
#define ZLIB_VERSION "1.2.8"
|
||||
#define ZLIB_VERNUM 0x1280
|
||||
#define ZLIB_VER_MAJOR 1
|
||||
#define ZLIB_VER_MINOR 2
|
||||
#define ZLIB_VER_REVISION 5
|
||||
#define ZLIB_VER_REVISION 8
|
||||
#define ZLIB_VER_SUBREVISION 0
|
||||
|
||||
/*
|
||||
@@ -83,15 +83,15 @@ typedef void (*free_func) OF((voidpf opaque, voidpf address));
|
||||
struct internal_state;
|
||||
|
||||
typedef struct z_stream_s {
|
||||
Bytef *next_in; /* next input byte */
|
||||
z_const Bytef *next_in; /* next input byte */
|
||||
uInt avail_in; /* number of bytes available at next_in */
|
||||
uLong total_in; /* total nb of input bytes read so far */
|
||||
uLong total_in; /* total number of input bytes read so far */
|
||||
|
||||
Bytef *next_out; /* next output byte should be put there */
|
||||
uInt avail_out; /* remaining free space at next_out */
|
||||
uLong total_out; /* total nb of bytes output so far */
|
||||
uLong total_out; /* total number of bytes output so far */
|
||||
|
||||
char *msg; /* last error message, NULL if no error */
|
||||
z_const char *msg; /* last error message, NULL if no error */
|
||||
struct internal_state FAR *state; /* not visible by applications */
|
||||
|
||||
alloc_func zalloc; /* used to allocate the internal state */
|
||||
@@ -327,8 +327,9 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
|
||||
|
||||
Z_FINISH can be used immediately after deflateInit if all the compression
|
||||
is to be done in a single step. In this case, avail_out must be at least the
|
||||
value returned by deflateBound (see below). If deflate does not return
|
||||
Z_STREAM_END, then it must be called again as described above.
|
||||
value returned by deflateBound (see below). Then deflate is guaranteed to
|
||||
return Z_STREAM_END. If not enough output space is provided, deflate will
|
||||
not return Z_STREAM_END, and it must be called again as described above.
|
||||
|
||||
deflate() sets strm->adler to the adler32 checksum of all input read
|
||||
so far (that is, total_in bytes).
|
||||
@@ -451,23 +452,29 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
|
||||
error. However if all decompression is to be performed in a single step (a
|
||||
single call of inflate), the parameter flush should be set to Z_FINISH. In
|
||||
this case all pending input is processed and all pending output is flushed;
|
||||
avail_out must be large enough to hold all the uncompressed data. (The size
|
||||
of the uncompressed data may have been saved by the compressor for this
|
||||
purpose.) The next operation on this stream must be inflateEnd to deallocate
|
||||
the decompression state. The use of Z_FINISH is never required, but can be
|
||||
used to inform inflate that a faster approach may be used for the single
|
||||
inflate() call.
|
||||
avail_out must be large enough to hold all of the uncompressed data for the
|
||||
operation to complete. (The size of the uncompressed data may have been
|
||||
saved by the compressor for this purpose.) The use of Z_FINISH is not
|
||||
required to perform an inflation in one step. However it may be used to
|
||||
inform inflate that a faster approach can be used for the single inflate()
|
||||
call. Z_FINISH also informs inflate to not maintain a sliding window if the
|
||||
stream completes, which reduces inflate's memory footprint. If the stream
|
||||
does not complete, either because not all of the stream is provided or not
|
||||
enough output space is provided, then a sliding window will be allocated and
|
||||
inflate() can be called again to continue the operation as if Z_NO_FLUSH had
|
||||
been used.
|
||||
|
||||
In this implementation, inflate() always flushes as much output as
|
||||
possible to the output buffer, and always uses the faster approach on the
|
||||
first call. So the only effect of the flush parameter in this implementation
|
||||
is on the return value of inflate(), as noted below, or when it returns early
|
||||
because Z_BLOCK or Z_TREES is used.
|
||||
first call. So the effects of the flush parameter in this implementation are
|
||||
on the return value of inflate() as noted below, when inflate() returns early
|
||||
when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of
|
||||
memory for a sliding window when Z_FINISH is used.
|
||||
|
||||
If a preset dictionary is needed after this call (see inflateSetDictionary
|
||||
below), inflate sets strm->adler to the adler32 checksum of the dictionary
|
||||
below), inflate sets strm->adler to the Adler-32 checksum of the dictionary
|
||||
chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
|
||||
strm->adler to the adler32 checksum of all output produced so far (that is,
|
||||
strm->adler to the Adler-32 checksum of all output produced so far (that is,
|
||||
total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
|
||||
below. At the end of the stream, inflate() checks that its computed adler32
|
||||
checksum is equal to that saved by the compressor and returns Z_STREAM_END
|
||||
@@ -478,7 +485,9 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
|
||||
initializing with inflateInit2(). Any information contained in the gzip
|
||||
header is not retained, so applications that need that information should
|
||||
instead use raw inflate, see inflateInit2() below, or inflateBack() and
|
||||
perform their own processing of the gzip header and trailer.
|
||||
perform their own processing of the gzip header and trailer. When processing
|
||||
gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output
|
||||
producted so far. The CRC-32 is checked against the gzip trailer.
|
||||
|
||||
inflate() returns Z_OK if some progress has been made (more input processed
|
||||
or more output produced), Z_STREAM_END if the end of the compressed data has
|
||||
@@ -580,10 +589,15 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
|
||||
uInt dictLength));
|
||||
/*
|
||||
Initializes the compression dictionary from the given byte sequence
|
||||
without producing any compressed output. This function must be called
|
||||
immediately after deflateInit, deflateInit2 or deflateReset, before any call
|
||||
of deflate. The compressor and decompressor must use exactly the same
|
||||
dictionary (see inflateSetDictionary).
|
||||
without producing any compressed output. When using the zlib format, this
|
||||
function must be called immediately after deflateInit, deflateInit2 or
|
||||
deflateReset, and before any call of deflate. When doing raw deflate, this
|
||||
function must be called either before any call of deflate, or immediately
|
||||
after the completion of a deflate block, i.e. after all input has been
|
||||
consumed and all output has been delivered when using any of the flush
|
||||
options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The
|
||||
compressor and decompressor must use exactly the same dictionary (see
|
||||
inflateSetDictionary).
|
||||
|
||||
The dictionary should consist of strings (byte sequences) that are likely
|
||||
to be encountered later in the data to be compressed, with the most commonly
|
||||
@@ -610,8 +624,8 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
|
||||
deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
|
||||
parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
|
||||
inconsistent (for example if deflate has already been called for this stream
|
||||
or if the compression method is bsort). deflateSetDictionary does not
|
||||
perform any compression: this will be done by deflate().
|
||||
or if not at a block boundary for raw deflate). deflateSetDictionary does
|
||||
not perform any compression: this will be done by deflate().
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
|
||||
@@ -688,9 +702,29 @@ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
|
||||
deflation of sourceLen bytes. It must be called after deflateInit() or
|
||||
deflateInit2(), and after deflateSetHeader(), if used. This would be used
|
||||
to allocate an output buffer for deflation in a single pass, and so would be
|
||||
called before deflate().
|
||||
called before deflate(). If that first deflate() call is provided the
|
||||
sourceLen input bytes, an output buffer allocated to the size returned by
|
||||
deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed
|
||||
to return Z_STREAM_END. Note that it is possible for the compressed size to
|
||||
be larger than the value returned by deflateBound() if flush options other
|
||||
than Z_FINISH or Z_NO_FLUSH are used.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
|
||||
unsigned *pending,
|
||||
int *bits));
|
||||
/*
|
||||
deflatePending() returns the number of bytes and bits of output that have
|
||||
been generated, but not yet provided in the available output. The bytes not
|
||||
provided would be due to the available output space having being consumed.
|
||||
The number of bits of output not provided are between 0 and 7, where they
|
||||
await more bits to join them in order to fill out a full byte. If pending
|
||||
or bits are Z_NULL, then those values are not set.
|
||||
|
||||
deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source
|
||||
stream state was inconsistent.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
|
||||
int bits,
|
||||
int value));
|
||||
@@ -703,8 +737,9 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
|
||||
than or equal to 16, and that many of the least significant bits of value
|
||||
will be inserted in the output.
|
||||
|
||||
deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
|
||||
stream state was inconsistent.
|
||||
deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough
|
||||
room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the
|
||||
source stream state was inconsistent.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
|
||||
@@ -790,10 +825,11 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
|
||||
if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
|
||||
can be determined from the adler32 value returned by that call of inflate.
|
||||
The compressor and decompressor must use exactly the same dictionary (see
|
||||
deflateSetDictionary). For raw inflate, this function can be called
|
||||
immediately after inflateInit2() or inflateReset() and before any call of
|
||||
inflate() to set the dictionary. The application must insure that the
|
||||
dictionary that was used for compression is provided.
|
||||
deflateSetDictionary). For raw inflate, this function can be called at any
|
||||
time to set the dictionary. If the provided dictionary is smaller than the
|
||||
window and there is already data in the window, then the provided dictionary
|
||||
will amend what's there. The application must insure that the dictionary
|
||||
that was used for compression is provided.
|
||||
|
||||
inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
|
||||
parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
|
||||
@@ -803,19 +839,38 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
|
||||
inflate().
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
|
||||
Bytef *dictionary,
|
||||
uInt *dictLength));
|
||||
/*
|
||||
Returns the sliding dictionary being maintained by inflate. dictLength is
|
||||
set to the number of bytes in the dictionary, and that many bytes are copied
|
||||
to dictionary. dictionary must have enough space, where 32768 bytes is
|
||||
always enough. If inflateGetDictionary() is called with dictionary equal to
|
||||
Z_NULL, then only the dictionary length is returned, and nothing is copied.
|
||||
Similary, if dictLength is Z_NULL, then it is not set.
|
||||
|
||||
inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
|
||||
stream state is inconsistent.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
|
||||
/*
|
||||
Skips invalid compressed data until a full flush point (see above the
|
||||
description of deflate with Z_FULL_FLUSH) can be found, or until all
|
||||
Skips invalid compressed data until a possible full flush point (see above
|
||||
for the description of deflate with Z_FULL_FLUSH) can be found, or until all
|
||||
available input is skipped. No output is provided.
|
||||
|
||||
inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
|
||||
if no more input was provided, Z_DATA_ERROR if no flush point has been
|
||||
found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the
|
||||
success case, the application may save the current current value of total_in
|
||||
which indicates where valid compressed data was found. In the error case,
|
||||
the application may repeatedly call inflateSync, providing more input each
|
||||
time, until success or end of the input data.
|
||||
inflateSync searches for a 00 00 FF FF pattern in the compressed data.
|
||||
All full flush points have this pattern, but not all occurrences of this
|
||||
pattern are full flush points.
|
||||
|
||||
inflateSync returns Z_OK if a possible full flush point has been found,
|
||||
Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
|
||||
has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
|
||||
In the success case, the application may save the current current value of
|
||||
total_in which indicates where valid compressed data was found. In the
|
||||
error case, the application may repeatedly call inflateSync, providing more
|
||||
input each time, until success or end of the input data.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
|
||||
@@ -962,12 +1017,13 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
|
||||
See inflateBack() for the usage of these routines.
|
||||
|
||||
inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
|
||||
the paramaters are invalid, Z_MEM_ERROR if the internal state could not be
|
||||
the parameters are invalid, Z_MEM_ERROR if the internal state could not be
|
||||
allocated, or Z_VERSION_ERROR if the version of the library does not match
|
||||
the version of the header file.
|
||||
*/
|
||||
|
||||
typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
|
||||
typedef unsigned (*in_func) OF((void FAR *,
|
||||
z_const unsigned char FAR * FAR *));
|
||||
typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
|
||||
|
||||
ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
|
||||
@@ -975,11 +1031,12 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
|
||||
out_func out, void FAR *out_desc));
|
||||
/*
|
||||
inflateBack() does a raw inflate with a single call using a call-back
|
||||
interface for input and output. This is more efficient than inflate() for
|
||||
file i/o applications in that it avoids copying between the output and the
|
||||
sliding window by simply making the window itself the output buffer. This
|
||||
function trusts the application to not change the output buffer passed by
|
||||
the output function, at least until inflateBack() returns.
|
||||
interface for input and output. This is potentially more efficient than
|
||||
inflate() for file i/o applications, in that it avoids copying between the
|
||||
output and the sliding window by simply making the window itself the output
|
||||
buffer. inflate() can be faster on modern CPUs when used with large
|
||||
buffers. inflateBack() trusts the application to not change the output
|
||||
buffer passed by the output function, at least until inflateBack() returns.
|
||||
|
||||
inflateBackInit() must be called first to allocate the internal state
|
||||
and to initialize the state with the user-provided window buffer.
|
||||
@@ -1088,6 +1145,7 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
|
||||
27-31: 0 (reserved)
|
||||
*/
|
||||
|
||||
#ifndef Z_SOLO
|
||||
|
||||
/* utility functions */
|
||||
|
||||
@@ -1149,10 +1207,11 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
|
||||
|
||||
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
|
||||
enough memory, Z_BUF_ERROR if there was not enough room in the output
|
||||
buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
|
||||
buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In
|
||||
the case where there is not enough room, uncompress() will fill the output
|
||||
buffer with the uncompressed data up to that point.
|
||||
*/
|
||||
|
||||
|
||||
/* gzip file access functions */
|
||||
|
||||
/*
|
||||
@@ -1162,7 +1221,7 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
|
||||
wrapper, documented in RFC 1952, wrapped around a deflate stream.
|
||||
*/
|
||||
|
||||
typedef voidp gzFile; /* opaque gzip file descriptor */
|
||||
typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */
|
||||
|
||||
/*
|
||||
ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
|
||||
@@ -1172,13 +1231,28 @@ ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
|
||||
a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
|
||||
compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
|
||||
for fixed code compression as in "wb9F". (See the description of
|
||||
deflateInit2 for more information about the strategy parameter.) Also "a"
|
||||
can be used instead of "w" to request that the gzip stream that will be
|
||||
written be appended to the file. "+" will result in an error, since reading
|
||||
and writing to the same gzip file is not supported.
|
||||
deflateInit2 for more information about the strategy parameter.) 'T' will
|
||||
request transparent writing or appending with no compression and not using
|
||||
the gzip format.
|
||||
|
||||
"a" can be used instead of "w" to request that the gzip stream that will
|
||||
be written be appended to the file. "+" will result in an error, since
|
||||
reading and writing to the same gzip file is not supported. The addition of
|
||||
"x" when writing will create the file exclusively, which fails if the file
|
||||
already exists. On systems that support it, the addition of "e" when
|
||||
reading or writing will set the flag to close the file on an execve() call.
|
||||
|
||||
These functions, as well as gzip, will read and decode a sequence of gzip
|
||||
streams in a file. The append function of gzopen() can be used to create
|
||||
such a file. (Also see gzflush() for another way to do this.) When
|
||||
appending, gzopen does not test whether the file begins with a gzip stream,
|
||||
nor does it look for the end of the gzip streams to begin appending. gzopen
|
||||
will simply append a gzip stream to the existing file.
|
||||
|
||||
gzopen can be used to read a file which is not in gzip format; in this
|
||||
case gzread will directly read from the file without decompression.
|
||||
case gzread will directly read from the file without decompression. When
|
||||
reading, this will be detected automatically by looking for the magic two-
|
||||
byte gzip header.
|
||||
|
||||
gzopen returns NULL if the file could not be opened, if there was
|
||||
insufficient memory to allocate the gzFile state, or if an invalid mode was
|
||||
@@ -1197,7 +1271,11 @@ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
|
||||
descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
|
||||
fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
|
||||
mode);. The duplicated descriptor should be saved to avoid a leak, since
|
||||
gzdopen does not close fd if it fails.
|
||||
gzdopen does not close fd if it fails. If you are using fileno() to get the
|
||||
file descriptor from a FILE *, then you will have to use dup() to avoid
|
||||
double-close()ing the file descriptor. Both gzclose() and fclose() will
|
||||
close the associated file descriptor, so they need to have different file
|
||||
descriptors.
|
||||
|
||||
gzdopen returns NULL if there was insufficient memory to allocate the
|
||||
gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
|
||||
@@ -1235,14 +1313,26 @@ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
|
||||
ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
|
||||
/*
|
||||
Reads the given number of uncompressed bytes from the compressed file. If
|
||||
the input file was not in gzip format, gzread copies the given number of
|
||||
bytes into the buffer.
|
||||
the input file is not in gzip format, gzread copies the given number of
|
||||
bytes into the buffer directly from the file.
|
||||
|
||||
After reaching the end of a gzip stream in the input, gzread will continue
|
||||
to read, looking for another gzip stream, or failing that, reading the rest
|
||||
of the input file directly without decompression. The entire input file
|
||||
will be read if gzread is called until it returns less than the requested
|
||||
len.
|
||||
to read, looking for another gzip stream. Any number of gzip streams may be
|
||||
concatenated in the input file, and will all be decompressed by gzread().
|
||||
If something other than a gzip stream is encountered after a gzip stream,
|
||||
that remaining trailing garbage is ignored (and no error is returned).
|
||||
|
||||
gzread can be used to read a gzip file that is being concurrently written.
|
||||
Upon reaching the end of the input, gzread will return with the available
|
||||
data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then
|
||||
gzclearerr can be used to clear the end of file indicator in order to permit
|
||||
gzread to be tried again. Z_OK indicates that a gzip stream was completed
|
||||
on the last gzread. Z_BUF_ERROR indicates that the input file ended in the
|
||||
middle of a gzip stream. Note that gzread does not return -1 in the event
|
||||
of an incomplete gzip stream. This error is deferred until gzclose(), which
|
||||
will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip
|
||||
stream. Alternatively, gzerror can be used before gzclose to detect this
|
||||
case.
|
||||
|
||||
gzread returns the number of uncompressed bytes actually read, less than
|
||||
len for end of file, or -1 for error.
|
||||
@@ -1256,7 +1346,7 @@ ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
|
||||
error.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
|
||||
ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
|
||||
/*
|
||||
Converts, formats, and writes the arguments to the compressed file under
|
||||
control of the format string, as in fprintf. gzprintf returns the number of
|
||||
@@ -1301,7 +1391,10 @@ ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
|
||||
ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
|
||||
/*
|
||||
Reads one byte from the compressed file. gzgetc returns this byte or -1
|
||||
in case of end of file or error.
|
||||
in case of end of file or error. This is implemented as a macro for speed.
|
||||
As such, it does not do all of the checking the other functions do. I.e.
|
||||
it does not check to see if file is NULL, nor whether the structure file
|
||||
points to has been clobbered or not.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
|
||||
@@ -1397,9 +1490,7 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file));
|
||||
ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
|
||||
/*
|
||||
Returns true (1) if file is being copied directly while reading, or false
|
||||
(0) if file is a gzip stream being decompressed. This state can change from
|
||||
false to true while reading the input file if the end of a gzip stream is
|
||||
reached, but is followed by data that is not another gzip stream.
|
||||
(0) if file is a gzip stream being decompressed.
|
||||
|
||||
If the input file is empty, gzdirect() will return true, since the input
|
||||
does not contain a gzip stream.
|
||||
@@ -1408,6 +1499,13 @@ ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
|
||||
cause buffers to be allocated to allow reading the file to determine if it
|
||||
is a gzip file. Therefore if gzbuffer() is used, it should be called before
|
||||
gzdirect().
|
||||
|
||||
When writing, gzdirect() returns true (1) if transparent writing was
|
||||
requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note:
|
||||
gzdirect() is not needed when writing. Transparent writing must be
|
||||
explicitly requested, so the application already knows the answer. When
|
||||
linking statically, using gzdirect() will include all of the zlib code for
|
||||
gzip file reading and decompression, which may not be desired.)
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT gzclose OF((gzFile file));
|
||||
@@ -1419,7 +1517,8 @@ ZEXTERN int ZEXPORT gzclose OF((gzFile file));
|
||||
must not be called more than once on the same allocation.
|
||||
|
||||
gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
|
||||
file operation error, or Z_OK on success.
|
||||
file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the
|
||||
last read ended in the middle of a gzip stream, or Z_OK on success.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
|
||||
@@ -1457,6 +1556,7 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
|
||||
file that is being written concurrently.
|
||||
*/
|
||||
|
||||
#endif /* !Z_SOLO */
|
||||
|
||||
/* checksum functions */
|
||||
|
||||
@@ -1492,16 +1592,17 @@ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
|
||||
Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
|
||||
and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
|
||||
each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
|
||||
seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
|
||||
seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note
|
||||
that the z_off_t type (like off_t) is a signed integer. If len2 is
|
||||
negative, the result has no meaning or utility.
|
||||
*/
|
||||
|
||||
ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
|
||||
/*
|
||||
Update a running CRC-32 with the bytes buf[0..len-1] and return the
|
||||
updated CRC-32. If buf is Z_NULL, this function returns the required
|
||||
initial value for the for the crc. Pre- and post-conditioning (one's
|
||||
complement) is performed within this function so it shouldn't be done by the
|
||||
application.
|
||||
initial value for the crc. Pre- and post-conditioning (one's complement) is
|
||||
performed within this function so it shouldn't be done by the application.
|
||||
|
||||
Usage example:
|
||||
|
||||
@@ -1544,17 +1645,42 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
|
||||
const char *version,
|
||||
int stream_size));
|
||||
#define deflateInit(strm, level) \
|
||||
deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
|
||||
deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
|
||||
#define inflateInit(strm) \
|
||||
inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
|
||||
inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
|
||||
#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
|
||||
deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
|
||||
(strategy), ZLIB_VERSION, sizeof(z_stream))
|
||||
(strategy), ZLIB_VERSION, (int)sizeof(z_stream))
|
||||
#define inflateInit2(strm, windowBits) \
|
||||
inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
|
||||
inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
|
||||
(int)sizeof(z_stream))
|
||||
#define inflateBackInit(strm, windowBits, window) \
|
||||
inflateBackInit_((strm), (windowBits), (window), \
|
||||
ZLIB_VERSION, sizeof(z_stream))
|
||||
ZLIB_VERSION, (int)sizeof(z_stream))
|
||||
|
||||
#ifndef Z_SOLO
|
||||
|
||||
/* gzgetc() macro and its supporting function and exposed data structure. Note
|
||||
* that the real internal state is much larger than the exposed structure.
|
||||
* This abbreviated structure exposes just enough for the gzgetc() macro. The
|
||||
* user should not mess with these exposed elements, since their names or
|
||||
* behavior could change in the future, perhaps even capriciously. They can
|
||||
* only be used by the gzgetc() macro. You have been warned.
|
||||
*/
|
||||
struct gzFile_s {
|
||||
unsigned have;
|
||||
unsigned char *next;
|
||||
z_off64_t pos;
|
||||
};
|
||||
ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
|
||||
#ifdef Z_PREFIX_SET
|
||||
# undef z_gzgetc
|
||||
# define z_gzgetc(g) \
|
||||
((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
|
||||
#else
|
||||
# define gzgetc(g) \
|
||||
((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
|
||||
#endif
|
||||
|
||||
/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
|
||||
* change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
|
||||
@@ -1562,7 +1688,7 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
|
||||
* functions are changed to 64 bits) -- in case these are set on systems
|
||||
* without large file support, _LFS64_LARGEFILE must also be true
|
||||
*/
|
||||
#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
|
||||
#ifdef Z_LARGE64
|
||||
ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
|
||||
ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
|
||||
ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
|
||||
@@ -1571,14 +1697,23 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
|
||||
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
|
||||
#endif
|
||||
|
||||
#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0
|
||||
# define gzopen gzopen64
|
||||
# define gzseek gzseek64
|
||||
# define gztell gztell64
|
||||
# define gzoffset gzoffset64
|
||||
# define adler32_combine adler32_combine64
|
||||
# define crc32_combine crc32_combine64
|
||||
# ifdef _LARGEFILE64_SOURCE
|
||||
#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
|
||||
# ifdef Z_PREFIX_SET
|
||||
# define z_gzopen z_gzopen64
|
||||
# define z_gzseek z_gzseek64
|
||||
# define z_gztell z_gztell64
|
||||
# define z_gzoffset z_gzoffset64
|
||||
# define z_adler32_combine z_adler32_combine64
|
||||
# define z_crc32_combine z_crc32_combine64
|
||||
# else
|
||||
# define gzopen gzopen64
|
||||
# define gzseek gzseek64
|
||||
# define gztell gztell64
|
||||
# define gzoffset gzoffset64
|
||||
# define adler32_combine adler32_combine64
|
||||
# define crc32_combine crc32_combine64
|
||||
# endif
|
||||
# ifndef Z_LARGE64
|
||||
ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
|
||||
ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
|
||||
ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
|
||||
@@ -1595,6 +1730,13 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
|
||||
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
|
||||
#endif
|
||||
|
||||
#else /* Z_SOLO */
|
||||
|
||||
ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
|
||||
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
|
||||
|
||||
#endif /* !Z_SOLO */
|
||||
|
||||
/* hack for buggy compilers */
|
||||
#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
|
||||
struct internal_state {int dummy;};
|
||||
@@ -1603,8 +1745,21 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
|
||||
/* undocumented functions */
|
||||
ZEXTERN const char * ZEXPORT zError OF((int));
|
||||
ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp));
|
||||
ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
|
||||
ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void));
|
||||
ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int));
|
||||
ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp));
|
||||
ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp));
|
||||
#if defined(_WIN32) && !defined(Z_SOLO)
|
||||
ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path,
|
||||
const char *mode));
|
||||
#endif
|
||||
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
|
||||
# ifndef Z_SOLO
|
||||
ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file,
|
||||
const char *format,
|
||||
va_list va));
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
234
thirdparty/liblcms2/include/lcms2.h
vendored
234
thirdparty/liblcms2/include/lcms2.h
vendored
@@ -1,7 +1,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2014 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"),
|
||||
@@ -23,7 +23,7 @@
|
||||
//
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Version 2.1
|
||||
// Version 2.6
|
||||
//
|
||||
|
||||
#ifndef _lcms2_H
|
||||
@@ -40,9 +40,6 @@
|
||||
// Uncomment this if your compiler doesn't work with fast floor function
|
||||
// #define CMS_DONT_USE_FAST_FLOOR 1
|
||||
|
||||
// Uncomment this line if your system does not support multithreading
|
||||
#define CMS_DONT_USE_PTHREADS 1
|
||||
|
||||
// Uncomment this line if you want lcms to use the black point tag in profile,
|
||||
// if commented, lcms will compute the black point by its own.
|
||||
// It is safer to leave it commented out
|
||||
@@ -55,6 +52,12 @@
|
||||
// require "KEYWORD" on undefined identifiers, keep it comented out unless needed
|
||||
// #define CMS_STRICT_CGATS 1
|
||||
|
||||
// Uncomment to get rid of the tables for "half" float support
|
||||
// #define CMS_NO_HALF_SUPPORT 1
|
||||
|
||||
// Uncomment to get rid of pthreads/windows dependency
|
||||
// #define CMS_NO_PTHREADS 1
|
||||
|
||||
// ********** End of configuration toggles ******************************
|
||||
|
||||
// Needed for streams
|
||||
@@ -72,7 +75,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
// Version/release
|
||||
#define LCMS_VERSION 2010
|
||||
#define LCMS_VERSION 2060
|
||||
|
||||
// I will give the chance of redefining basic types for compilers that are not fully C99 compliant
|
||||
#ifndef CMS_BASIC_TYPES_ALREADY_DEFINED
|
||||
@@ -81,6 +84,10 @@ extern "C" {
|
||||
typedef unsigned char cmsUInt8Number; // That is guaranteed by the C99 spec
|
||||
typedef signed char cmsInt8Number; // That is guaranteed by the C99 spec
|
||||
|
||||
#if CHAR_BIT != 8
|
||||
# error "Unable to find 8 bit type, unsupported compiler"
|
||||
#endif
|
||||
|
||||
// IEEE float storage numbers
|
||||
typedef float cmsFloat32Number;
|
||||
typedef double cmsFloat64Number;
|
||||
@@ -169,26 +176,42 @@ typedef int cmsBool;
|
||||
// Try to detect big endian platforms. This list can be endless, so only some checks are performed over here.
|
||||
// you can pass this toggle to the compiler by using -DCMS_USE_BIG_ENDIAN or something similar
|
||||
|
||||
#if defined(__sgi__) || defined(__sgi) || defined(sparc)
|
||||
# define CMS_USE_BIG_ENDIAN 1
|
||||
#endif
|
||||
|
||||
#if defined(__s390__) || defined(__s390x__)
|
||||
# define CMS_USE_BIG_ENDIAN 1
|
||||
#endif
|
||||
|
||||
# ifdef TARGET_CPU_PPC
|
||||
# if TARGET_CPU_PPC
|
||||
# define CMS_USE_BIG_ENDIAN 1
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#if defined(__powerpc__) || defined(__ppc__) || defined(TARGET_CPU_PPC)
|
||||
# define CMS_USE_BIG_ENDIAN 1
|
||||
# if defined (__GNUC__) && defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN)
|
||||
# if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
// // Don't use big endian for PowerPC little endian mode
|
||||
# undef CMS_USE_BIG_ENDIAN
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// WORDS_BIGENDIAN takes precedence
|
||||
#if defined(_HOST_BIG_ENDIAN) || defined(__BIG_ENDIAN__) || defined(WORDS_BIGENDIAN)
|
||||
# define CMS_USE_BIG_ENDIAN 1
|
||||
#endif
|
||||
|
||||
#if defined(__sgi__) || defined(__sgi) || defined(__powerpc__) || defined(sparc)
|
||||
# define CMS_USE_BIG_ENDIAN 1
|
||||
#endif
|
||||
|
||||
#if defined(__ppc__) || defined(__s390__) || defined(__s390x__)
|
||||
# define CMS_USE_BIG_ENDIAN 1
|
||||
#endif
|
||||
|
||||
#if TARGET_CPU_PPC
|
||||
# define CMS_USE_BIG_ENDIAN 1
|
||||
#endif
|
||||
|
||||
#ifdef macintosh
|
||||
# ifdef __BIG_ENDIAN__
|
||||
# define CMS_USE_BIG_ENDIAN 1
|
||||
# endif
|
||||
# ifdef __LITTLE_ENDIAN__
|
||||
# undef CMS_USE_BIG_ENDIAN
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Calling convention -- this is hardly platform and compiler dependent
|
||||
@@ -214,6 +237,14 @@ typedef int cmsBool;
|
||||
# define CMSAPI
|
||||
#endif
|
||||
|
||||
#ifdef HasTHREADS
|
||||
# if HasTHREADS == 1
|
||||
# undef CMS_NO_PTHREADS
|
||||
# else
|
||||
# define CMS_NO_PTHREADS 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Some common definitions
|
||||
#define cmsMAX_PATH 256
|
||||
|
||||
@@ -247,6 +278,7 @@ typedef enum {
|
||||
cmsSigCrdInfoType = 0x63726469, // 'crdi'
|
||||
cmsSigCurveType = 0x63757276, // 'curv'
|
||||
cmsSigDataType = 0x64617461, // 'data'
|
||||
cmsSigDictType = 0x64696374, // 'dict'
|
||||
cmsSigDateTimeType = 0x6474696D, // 'dtim'
|
||||
cmsSigDeviceSettingsType = 0x64657673, // 'devs'
|
||||
cmsSigLut16Type = 0x6d667432, // 'mft2'
|
||||
@@ -273,9 +305,10 @@ typedef enum {
|
||||
cmsSigUInt32ArrayType = 0x75693332, // 'ui32'
|
||||
cmsSigUInt64ArrayType = 0x75693634, // 'ui64'
|
||||
cmsSigUInt8ArrayType = 0x75693038, // 'ui08'
|
||||
cmsSigVcgtType = 0x76636774, // 'vcgt'
|
||||
cmsSigViewingConditionsType = 0x76696577, // 'view'
|
||||
cmsSigXYZType = 0x58595A20, // 'XYZ '
|
||||
cmsSigVcgtType = 0x76636774 // 'vcgt'
|
||||
cmsSigXYZType = 0x58595A20 // 'XYZ '
|
||||
|
||||
|
||||
} cmsTagTypeSignature;
|
||||
|
||||
@@ -330,6 +363,7 @@ typedef enum {
|
||||
cmsSigPreview1Tag = 0x70726531, // 'pre1'
|
||||
cmsSigPreview2Tag = 0x70726532, // 'pre2'
|
||||
cmsSigProfileDescriptionTag = 0x64657363, // 'desc'
|
||||
cmsSigProfileDescriptionMLTag = 0x6473636d, // 'dscm'
|
||||
cmsSigProfileSequenceDescTag = 0x70736571, // 'pseq'
|
||||
cmsSigProfileSequenceIdTag = 0x70736964, // 'psid'
|
||||
cmsSigPs2CRD0Tag = 0x70736430, // 'psd0'
|
||||
@@ -348,7 +382,8 @@ typedef enum {
|
||||
cmsSigUcrBgTag = 0x62666420, // 'bfd '
|
||||
cmsSigViewingCondDescTag = 0x76756564, // 'vued'
|
||||
cmsSigViewingConditionsTag = 0x76696577, // 'view'
|
||||
cmsSigVcgtTag = 0x76636774 // 'vcgt'
|
||||
cmsSigVcgtTag = 0x76636774, // 'vcgt'
|
||||
cmsSigMetaTag = 0x6D657461 // 'meta'
|
||||
|
||||
} cmsTagSignature;
|
||||
|
||||
@@ -407,12 +442,12 @@ typedef enum {
|
||||
cmsSigMCH7Data = 0x4D434837, // 'MCH7'
|
||||
cmsSigMCH8Data = 0x4D434838, // 'MCH8'
|
||||
cmsSigMCH9Data = 0x4D434839, // 'MCH9'
|
||||
cmsSigMCHAData = 0x4D43483A, // 'MCHA'
|
||||
cmsSigMCHBData = 0x4D43483B, // 'MCHB'
|
||||
cmsSigMCHCData = 0x4D43483C, // 'MCHC'
|
||||
cmsSigMCHDData = 0x4D43483D, // 'MCHD'
|
||||
cmsSigMCHEData = 0x4D43483E, // 'MCHE'
|
||||
cmsSigMCHFData = 0x4D43483F, // 'MCHF'
|
||||
cmsSigMCHAData = 0x4D434841, // 'MCHA'
|
||||
cmsSigMCHBData = 0x4D434842, // 'MCHB'
|
||||
cmsSigMCHCData = 0x4D434843, // 'MCHC'
|
||||
cmsSigMCHDData = 0x4D434844, // 'MCHD'
|
||||
cmsSigMCHEData = 0x4D434845, // 'MCHE'
|
||||
cmsSigMCHFData = 0x4D434846, // 'MCHF'
|
||||
cmsSigNamedData = 0x6e6d636c, // 'nmcl'
|
||||
cmsSig1colorData = 0x31434C52, // '1CLR'
|
||||
cmsSig2colorData = 0x32434C52, // '2CLR'
|
||||
@@ -483,7 +518,13 @@ typedef enum {
|
||||
cmsSigLabV4toV2 = 0x34203220, // '4 2 '
|
||||
|
||||
// Identities
|
||||
cmsSigIdentityElemType = 0x69646E20 // 'idn '
|
||||
cmsSigIdentityElemType = 0x69646E20, // 'idn '
|
||||
|
||||
// Float to floatPCS
|
||||
cmsSigLab2FloatPCS = 0x64326C20, // 'd2l '
|
||||
cmsSigFloatPCS2Lab = 0x6C326420, // 'l2d '
|
||||
cmsSigXYZ2FloatPCS = 0x64327820, // 'd2x '
|
||||
cmsSigFloatPCS2XYZ = 0x78326420 // 'x2d '
|
||||
|
||||
} cmsStageSignature;
|
||||
|
||||
@@ -597,7 +638,6 @@ typedef struct {
|
||||
|
||||
// Little CMS specific typedefs
|
||||
|
||||
typedef void* cmsContext; // Context identifier for multithreaded environments
|
||||
typedef void* cmsHANDLE ; // Generic handle
|
||||
typedef void* cmsHPROFILE; // Opaque typedefs to hide internals
|
||||
typedef void* cmsHTRANSFORM;
|
||||
@@ -606,7 +646,9 @@ typedef void* cmsHTRANSFORM;
|
||||
|
||||
// Format of pixel is defined by one cmsUInt32Number, using bit fields as follows
|
||||
//
|
||||
// A O TTTTT U Y F P X S EEE CCCC BBB
|
||||
// 2 1 0
|
||||
// 3 2 10987 6 5 4 3 2 1 098 7654 321
|
||||
// A O TTTTT U Y F P X S EEE CCCC BBB
|
||||
//
|
||||
// A: Floating point -- With this flag we can differentiate 16 bits as float and as int
|
||||
// O: Optimized -- previous optimization already returns the final 8-bit value
|
||||
@@ -714,16 +756,19 @@ typedef void* cmsHTRANSFORM;
|
||||
#define TYPE_RGBA_16_SE (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1))
|
||||
|
||||
#define TYPE_ARGB_8 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|SWAPFIRST_SH(1))
|
||||
#define TYPE_ARGB_8_PLANAR (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|SWAPFIRST_SH(1)|PLANAR_SH(1))
|
||||
#define TYPE_ARGB_16 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|SWAPFIRST_SH(1))
|
||||
|
||||
#define TYPE_ABGR_8 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1))
|
||||
#define TYPE_ABGR_8_PLANAR (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|PLANAR_SH(1))
|
||||
#define TYPE_ABGR_16 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1))
|
||||
#define TYPE_ABGR_16_PLANAR (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)|PLANAR_SH(1))
|
||||
#define TYPE_ABGR_16_SE (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)|ENDIAN16_SH(1))
|
||||
|
||||
#define TYPE_BGRA_8 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1))
|
||||
#define TYPE_BGRA_8_PLANAR (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1)|PLANAR_SH(1))
|
||||
#define TYPE_BGRA_16 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)|SWAPFIRST_SH(1))
|
||||
#define TYPE_BGRA_16_SE (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1)|SWAPFIRST_SH(1))
|
||||
#define TYPE_BGRA_16_SE (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1))
|
||||
|
||||
#define TYPE_CMY_8 (COLORSPACE_SH(PT_CMY)|CHANNELS_SH(3)|BYTES_SH(1))
|
||||
#define TYPE_CMY_8_PLANAR (COLORSPACE_SH(PT_CMY)|CHANNELS_SH(3)|BYTES_SH(1)|PLANAR_SH(1))
|
||||
@@ -805,8 +850,8 @@ typedef void* cmsHTRANSFORM;
|
||||
#define TYPE_Lab_8 (COLORSPACE_SH(PT_Lab)|CHANNELS_SH(3)|BYTES_SH(1))
|
||||
#define TYPE_LabV2_8 (COLORSPACE_SH(PT_LabV2)|CHANNELS_SH(3)|BYTES_SH(1))
|
||||
|
||||
#define TYPE_ALab_8 (COLORSPACE_SH(PT_Lab)|CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|DOSWAP_SH(1))
|
||||
#define TYPE_ALabV2_8 (COLORSPACE_SH(PT_LabV2)|CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|DOSWAP_SH(1))
|
||||
#define TYPE_ALab_8 (COLORSPACE_SH(PT_Lab)|CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1))
|
||||
#define TYPE_ALabV2_8 (COLORSPACE_SH(PT_LabV2)|CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1))
|
||||
#define TYPE_Lab_16 (COLORSPACE_SH(PT_Lab)|CHANNELS_SH(3)|BYTES_SH(2))
|
||||
#define TYPE_LabV2_16 (COLORSPACE_SH(PT_LabV2)|CHANNELS_SH(3)|BYTES_SH(2))
|
||||
#define TYPE_Yxy_16 (COLORSPACE_SH(PT_Yxy)|CHANNELS_SH(3)|BYTES_SH(2))
|
||||
@@ -844,22 +889,40 @@ 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_ARGB_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4)|SWAPFIRST_SH(1))
|
||||
#define TYPE_BGR_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|DOSWAP_SH(1))
|
||||
#define TYPE_BGRA_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4)|DOSWAP_SH(1)|SWAPFIRST_SH(1))
|
||||
#define TYPE_ABGR_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|DOSWAP_SH(1))
|
||||
|
||||
#define TYPE_CMYK_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(4))
|
||||
|
||||
// Floating point formatters.
|
||||
// Floating point formatters.
|
||||
// NOTE THAT 'BYTES' FIELD IS SET TO ZERO ON DLB because 8 bytes overflows the bitfield
|
||||
#define TYPE_XYZ_DBL (FLOAT_SH(1)|COLORSPACE_SH(PT_XYZ)|CHANNELS_SH(3)|BYTES_SH(0))
|
||||
#define TYPE_Lab_DBL (FLOAT_SH(1)|COLORSPACE_SH(PT_Lab)|CHANNELS_SH(3)|BYTES_SH(0))
|
||||
#define TYPE_GRAY_DBL (FLOAT_SH(1)|COLORSPACE_SH(PT_GRAY)|CHANNELS_SH(1)|BYTES_SH(0))
|
||||
#define TYPE_RGB_DBL (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(0))
|
||||
#define TYPE_BGR_DBL (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(0)|DOSWAP_SH(1))
|
||||
#define TYPE_CMYK_DBL (FLOAT_SH(1)|COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(0))
|
||||
|
||||
// IEEE 754-2008 "half"
|
||||
#define TYPE_GRAY_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_GRAY)|CHANNELS_SH(1)|BYTES_SH(2))
|
||||
#define TYPE_RGB_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(2))
|
||||
#define TYPE_RGBA_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2))
|
||||
#define TYPE_CMYK_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(2))
|
||||
|
||||
#define TYPE_RGBA_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2))
|
||||
#define TYPE_ARGB_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|SWAPFIRST_SH(1))
|
||||
#define TYPE_BGR_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1))
|
||||
#define TYPE_BGRA_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)|SWAPFIRST_SH(1))
|
||||
#define TYPE_ABGR_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1))
|
||||
|
||||
#endif
|
||||
|
||||
// Colorspaces
|
||||
@@ -944,10 +1007,25 @@ typedef struct {
|
||||
CMSAPI int CMSEXPORT cmsstrcasecmp(const char* s1, const char* s2);
|
||||
CMSAPI long int CMSEXPORT cmsfilelength(FILE* f);
|
||||
|
||||
// Plug-In registering ---------------------------------------------------------------------------------------------------
|
||||
|
||||
// Context handling --------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Each context holds its owns globals and its own plug-ins. There is a global context with the id = 0 for lecacy compatibility
|
||||
// though using the global context is not recomended. Proper context handling makes lcms more thread-safe.
|
||||
|
||||
typedef struct _cmsContext_struct* cmsContext;
|
||||
|
||||
CMSAPI cmsContext CMSEXPORT cmsCreateContext(void* Plugin, void* UserData);
|
||||
CMSAPI void CMSEXPORT cmsDeleteContext(cmsContext ContexID);
|
||||
CMSAPI cmsContext CMSEXPORT cmsDupContext(cmsContext ContextID, void* NewUserData);
|
||||
CMSAPI void* CMSEXPORT cmsGetContextUserData(cmsContext ContextID);
|
||||
|
||||
// Plug-In registering --------------------------------------------------------------------------------------------------
|
||||
|
||||
CMSAPI cmsBool CMSEXPORT cmsPlugin(void* Plugin);
|
||||
CMSAPI cmsBool CMSEXPORT cmsPluginTHR(cmsContext ContextID, void* Plugin);
|
||||
CMSAPI void CMSEXPORT cmsUnregisterPlugins(void);
|
||||
CMSAPI void CMSEXPORT cmsUnregisterPluginsTHR(cmsContext ContextID);
|
||||
|
||||
// Error logging ----------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -984,6 +1062,7 @@ typedef void (* cmsLogErrorHandlerFunction)(cmsContext ContextID, cmsUInt32Numb
|
||||
|
||||
// Allows user to set any specific logger
|
||||
CMSAPI void CMSEXPORT cmsSetLogErrorHandler(cmsLogErrorHandlerFunction Fn);
|
||||
CMSAPI void CMSEXPORT cmsSetLogErrorHandlerTHR(cmsContext ContextID, cmsLogErrorHandlerFunction Fn);
|
||||
|
||||
// Conversions --------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -1090,6 +1169,10 @@ CMSAPI cmsBool CMSEXPORT cmsIsToneCurveDescending(const cmsToneCurve*
|
||||
CMSAPI cmsInt32Number CMSEXPORT cmsGetToneCurveParametricType(const cmsToneCurve* t);
|
||||
CMSAPI cmsFloat64Number CMSEXPORT cmsEstimateGamma(const cmsToneCurve* t, cmsFloat64Number Precision);
|
||||
|
||||
// Tone curve tabular estimation
|
||||
CMSAPI cmsUInt32Number CMSEXPORT cmsGetToneCurveEstimatedTableEntries(const cmsToneCurve* t);
|
||||
CMSAPI const cmsUInt16Number* CMSEXPORT cmsGetToneCurveEstimatedTable(const cmsToneCurve* t);
|
||||
|
||||
|
||||
// Implements pipelines of multi-processing elements -------------------------------------------------------------
|
||||
|
||||
@@ -1102,6 +1185,7 @@ CMSAPI cmsPipeline* CMSEXPORT cmsPipelineAlloc(cmsContext ContextID, cmsUIn
|
||||
CMSAPI void CMSEXPORT cmsPipelineFree(cmsPipeline* lut);
|
||||
CMSAPI cmsPipeline* CMSEXPORT cmsPipelineDup(const cmsPipeline* Orig);
|
||||
|
||||
CMSAPI cmsContext CMSEXPORT cmsGetPipelineContextID(const cmsPipeline* lut);
|
||||
CMSAPI cmsUInt32Number CMSEXPORT cmsPipelineInputChannels(const cmsPipeline* lut);
|
||||
CMSAPI cmsUInt32Number CMSEXPORT cmsPipelineOutputChannels(const cmsPipeline* lut);
|
||||
|
||||
@@ -1118,7 +1202,7 @@ CMSAPI cmsBool CMSEXPORT cmsPipelineSetSaveAs8bitsFlag(cmsPipeline* lu
|
||||
// Where to place/locate the stages in the pipeline chain
|
||||
typedef enum { cmsAT_BEGIN, cmsAT_END } cmsStageLoc;
|
||||
|
||||
CMSAPI void CMSEXPORT cmsPipelineInsertStage(cmsPipeline* lut, cmsStageLoc loc, cmsStage* mpe);
|
||||
CMSAPI int CMSEXPORT cmsPipelineInsertStage(cmsPipeline* lut, cmsStageLoc loc, cmsStage* mpe);
|
||||
CMSAPI void CMSEXPORT cmsPipelineUnlinkStage(cmsPipeline* lut, cmsStageLoc loc, cmsStage** mpe);
|
||||
|
||||
// This function is quite useful to analyze the structure of a Pipeline and retrieve the Stage elements
|
||||
@@ -1162,10 +1246,9 @@ typedef cmsInt32Number (* cmsSAMPLERFLOAT)(register const cmsFloat32Number In[],
|
||||
#define SAMPLER_INSPECT 0x01000000
|
||||
|
||||
// For CLUT only
|
||||
CMSAPI cmsBool CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe, cmsSAMPLER16 Sampler, void* Cargo, cmsUInt32Number dwFlags);
|
||||
CMSAPI cmsBool CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe, cmsSAMPLER16 Sampler, void* Cargo, cmsUInt32Number dwFlags);
|
||||
CMSAPI cmsBool CMSEXPORT cmsStageSampleCLutFloat(cmsStage* mpe, cmsSAMPLERFLOAT Sampler, void* Cargo, cmsUInt32Number dwFlags);
|
||||
|
||||
|
||||
// Slicers
|
||||
CMSAPI cmsBool CMSEXPORT cmsSliceSpace16(cmsUInt32Number nInputs, const cmsUInt32Number clutPoints[],
|
||||
cmsSAMPLER16 Sampler, void * Cargo);
|
||||
@@ -1203,6 +1286,13 @@ CMSAPI cmsBool CMSEXPORT cmsMLUgetTranslation(const cmsMLU* mlu,
|
||||
const char LanguageCode[3], const char CountryCode[3],
|
||||
char ObtainedLanguage[3], char ObtainedCountry[3]);
|
||||
|
||||
CMSAPI cmsUInt32Number CMSEXPORT cmsMLUtranslationsCount(const cmsMLU* mlu);
|
||||
|
||||
CMSAPI cmsBool CMSEXPORT cmsMLUtranslationsCodes(const cmsMLU* mlu,
|
||||
cmsUInt32Number idx,
|
||||
char LanguageCode[3],
|
||||
char CountryCode[3]);
|
||||
|
||||
// Undercolorremoval & black generation -------------------------------------------------------------------------------------
|
||||
|
||||
typedef struct {
|
||||
@@ -1275,6 +1365,7 @@ CMSAPI cmsNAMEDCOLORLIST* CMSEXPORT cmsGetNamedColorList(cmsHTRANSFORM xform);
|
||||
// Profile sequence descriptor. Some fields come from profile sequence descriptor tag, others
|
||||
// come from Profile Sequence Identifier Tag
|
||||
typedef struct {
|
||||
|
||||
cmsSignature deviceMfg;
|
||||
cmsSignature deviceModel;
|
||||
cmsUInt64Number attributes;
|
||||
@@ -1298,6 +1389,27 @@ CMSAPI cmsSEQ* CMSEXPORT cmsAllocProfileSequenceDescription(cmsContext
|
||||
CMSAPI cmsSEQ* CMSEXPORT cmsDupProfileSequenceDescription(const cmsSEQ* pseq);
|
||||
CMSAPI void CMSEXPORT cmsFreeProfileSequenceDescription(cmsSEQ* pseq);
|
||||
|
||||
// Dictionaries --------------------------------------------------------------------------------------------------------
|
||||
|
||||
typedef struct _cmsDICTentry_struct {
|
||||
|
||||
struct _cmsDICTentry_struct* Next;
|
||||
|
||||
cmsMLU *DisplayName;
|
||||
cmsMLU *DisplayValue;
|
||||
wchar_t* Name;
|
||||
wchar_t* Value;
|
||||
|
||||
} cmsDICTentry;
|
||||
|
||||
CMSAPI cmsHANDLE CMSEXPORT cmsDictAlloc(cmsContext ContextID);
|
||||
CMSAPI void CMSEXPORT cmsDictFree(cmsHANDLE hDict);
|
||||
CMSAPI cmsHANDLE CMSEXPORT cmsDictDup(cmsHANDLE hDict);
|
||||
|
||||
CMSAPI cmsBool CMSEXPORT cmsDictAddEntry(cmsHANDLE hDict, const wchar_t* Name, const wchar_t* Value, const cmsMLU *DisplayName, const cmsMLU *DisplayValue);
|
||||
CMSAPI const cmsDICTentry* CMSEXPORT cmsDictGetEntryList(cmsHANDLE hDict);
|
||||
CMSAPI const cmsDICTentry* CMSEXPORT cmsDictNextEntry(const cmsDICTentry* e);
|
||||
|
||||
// Access to Profile data ----------------------------------------------------------------------------------------------
|
||||
CMSAPI cmsHPROFILE CMSEXPORT cmsCreateProfilePlaceholder(cmsContext ContextID);
|
||||
|
||||
@@ -1317,9 +1429,9 @@ CMSAPI cmsInt32Number CMSEXPORT cmsReadRawTag(cmsHPROFILE hProfile, cmsTagSig
|
||||
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 cmsEmbeddedProfileFalse 0x00000000
|
||||
#define cmsEmbeddedProfileTrue 0x00000001
|
||||
#define cmsUseAnywhere 0x00000000
|
||||
#define cmsUseWithEmbeddedDataOnly 0x00000002
|
||||
|
||||
CMSAPI cmsUInt32Number CMSEXPORT cmsGetHeaderFlags(cmsHPROFILE hProfile);
|
||||
@@ -1331,6 +1443,7 @@ CMSAPI cmsUInt32Number CMSEXPORT cmsGetHeaderRenderingIntent(cmsHPROFILE hProf
|
||||
CMSAPI void CMSEXPORT cmsSetHeaderFlags(cmsHPROFILE hProfile, cmsUInt32Number Flags);
|
||||
CMSAPI cmsUInt32Number CMSEXPORT cmsGetHeaderManufacturer(cmsHPROFILE hProfile);
|
||||
CMSAPI void CMSEXPORT cmsSetHeaderManufacturer(cmsHPROFILE hProfile, cmsUInt32Number manufacturer);
|
||||
CMSAPI cmsUInt32Number CMSEXPORT cmsGetHeaderCreator(cmsHPROFILE hProfile);
|
||||
CMSAPI cmsUInt32Number CMSEXPORT cmsGetHeaderModel(cmsHPROFILE hProfile);
|
||||
CMSAPI void CMSEXPORT cmsSetHeaderModel(cmsHPROFILE hProfile, cmsUInt32Number model);
|
||||
CMSAPI void CMSEXPORT cmsSetHeaderAttributes(cmsHPROFILE hProfile, cmsUInt64Number Flags);
|
||||
@@ -1411,6 +1524,7 @@ CMSAPI cmsHPROFILE CMSEXPORT cmsOpenProfileFromStreamTHR(cmsContext Context
|
||||
CMSAPI cmsHPROFILE CMSEXPORT cmsOpenProfileFromMem(const void * MemPtr, cmsUInt32Number dwSize);
|
||||
CMSAPI cmsHPROFILE CMSEXPORT cmsOpenProfileFromMemTHR(cmsContext ContextID, const void * MemPtr, cmsUInt32Number dwSize);
|
||||
CMSAPI cmsHPROFILE CMSEXPORT cmsOpenProfileFromIOhandlerTHR(cmsContext ContextID, cmsIOHANDLER* io);
|
||||
CMSAPI cmsHPROFILE CMSEXPORT cmsOpenProfileFromIOhandler2THR(cmsContext ContextID, cmsIOHANDLER* io, cmsBool write);
|
||||
CMSAPI cmsBool CMSEXPORT cmsCloseProfile(cmsHPROFILE hProfile);
|
||||
|
||||
CMSAPI cmsBool CMSEXPORT cmsSaveProfileToFile(cmsHPROFILE hProfile, const char* FileName);
|
||||
@@ -1501,6 +1615,7 @@ CMSAPI cmsHPROFILE CMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransfo
|
||||
|
||||
// Call with NULL as parameters to get the intent count
|
||||
CMSAPI cmsUInt32Number CMSEXPORT cmsGetSupportedIntents(cmsUInt32Number nMax, cmsUInt32Number* Codes, char** Descriptions);
|
||||
CMSAPI cmsUInt32Number CMSEXPORT cmsGetSupportedIntentsTHR(cmsContext ContextID, cmsUInt32Number nMax, cmsUInt32Number* Codes, char** Descriptions);
|
||||
|
||||
// Flags
|
||||
|
||||
@@ -1605,18 +1720,40 @@ CMSAPI void CMSEXPORT cmsDoTransform(cmsHTRANSFORM Transform,
|
||||
void * OutputBuffer,
|
||||
cmsUInt32Number Size);
|
||||
|
||||
CMSAPI void CMSEXPORT cmsSetAlarmCodes(cmsUInt16Number NewAlarm[cmsMAXCHANNELS]);
|
||||
CMSAPI void CMSEXPORT cmsDoTransformStride(cmsHTRANSFORM Transform,
|
||||
const void * InputBuffer,
|
||||
void * OutputBuffer,
|
||||
cmsUInt32Number Size,
|
||||
cmsUInt32Number Stride);
|
||||
|
||||
|
||||
CMSAPI void CMSEXPORT cmsSetAlarmCodes(const cmsUInt16Number NewAlarm[cmsMAXCHANNELS]);
|
||||
CMSAPI void CMSEXPORT cmsGetAlarmCodes(cmsUInt16Number NewAlarm[cmsMAXCHANNELS]);
|
||||
|
||||
|
||||
CMSAPI void CMSEXPORT cmsSetAlarmCodesTHR(cmsContext ContextID,
|
||||
const cmsUInt16Number AlarmCodes[cmsMAXCHANNELS]);
|
||||
CMSAPI void CMSEXPORT cmsGetAlarmCodesTHR(cmsContext ContextID,
|
||||
cmsUInt16Number AlarmCodes[cmsMAXCHANNELS]);
|
||||
|
||||
|
||||
|
||||
// Adaptation state for absolute colorimetric intent
|
||||
CMSAPI cmsFloat64Number CMSEXPORT cmsSetAdaptationState(cmsFloat64Number d);
|
||||
CMSAPI cmsFloat64Number CMSEXPORT cmsSetAdaptationStateTHR(cmsContext ContextID, cmsFloat64Number d);
|
||||
|
||||
|
||||
|
||||
// Grab the ContextID from an open transform. Returns NULL if a NULL transform is passed
|
||||
CMSAPI cmsContext CMSEXPORT cmsGetTransformContextID(cmsHTRANSFORM hTransform);
|
||||
|
||||
// Grab the input/output formats
|
||||
CMSAPI cmsUInt32Number CMSEXPORT cmsGetTransformInputFormat(cmsHTRANSFORM hTransform);
|
||||
CMSAPI cmsUInt32Number CMSEXPORT cmsGetTransformOutputFormat(cmsHTRANSFORM hTransform);
|
||||
|
||||
// For backwards compatibility
|
||||
CMSAPI cmsBool CMSEXPORT cmsChangeBuffersFormat(cmsHTRANSFORM hTransform,
|
||||
cmsUInt32Number InputFormat,
|
||||
CMSAPI cmsBool CMSEXPORT cmsChangeBuffersFormat(cmsHTRANSFORM hTransform,
|
||||
cmsUInt32Number InputFormat,
|
||||
cmsUInt32Number OutputFormat);
|
||||
|
||||
|
||||
@@ -1663,12 +1800,15 @@ CMSAPI cmsBool CMSEXPORT cmsIT8SetComment(cmsHANDLE hIT8, const char* c
|
||||
CMSAPI cmsBool CMSEXPORT cmsIT8SetPropertyStr(cmsHANDLE hIT8, const char* cProp, const char *Str);
|
||||
CMSAPI cmsBool CMSEXPORT cmsIT8SetPropertyDbl(cmsHANDLE hIT8, const char* cProp, cmsFloat64Number Val);
|
||||
CMSAPI cmsBool CMSEXPORT cmsIT8SetPropertyHex(cmsHANDLE hIT8, const char* cProp, cmsUInt32Number Val);
|
||||
CMSAPI cmsBool CMSEXPORT cmsIT8SetPropertyMulti(cmsHANDLE hIT8, const char* Key, const char* SubKey, const char *Buffer);
|
||||
CMSAPI cmsBool CMSEXPORT cmsIT8SetPropertyUncooked(cmsHANDLE hIT8, const char* Key, const char* Buffer);
|
||||
|
||||
|
||||
CMSAPI const char* CMSEXPORT cmsIT8GetProperty(cmsHANDLE hIT8, const char* cProp);
|
||||
CMSAPI cmsFloat64Number CMSEXPORT cmsIT8GetPropertyDbl(cmsHANDLE hIT8, const char* cProp);
|
||||
CMSAPI const char* CMSEXPORT cmsIT8GetPropertyMulti(cmsHANDLE hIT8, const char* Key, const char *SubKey);
|
||||
CMSAPI cmsUInt32Number CMSEXPORT cmsIT8EnumProperties(cmsHANDLE hIT8, char ***PropertyNames);
|
||||
CMSAPI cmsUInt32Number CMSEXPORT cmsIT8EnumPropertyMulti(cmsHANDLE hIT8, const char* cProp, const char ***SubpropertyNames);
|
||||
|
||||
// Datasets
|
||||
CMSAPI const char* CMSEXPORT cmsIT8GetDataRowCol(cmsHANDLE hIT8, int row, int col);
|
||||
@@ -1698,10 +1838,13 @@ CMSAPI cmsBool CMSEXPORT cmsIT8SetDataFormat(cmsHANDLE hIT8, int n, con
|
||||
CMSAPI int CMSEXPORT cmsIT8EnumDataFormat(cmsHANDLE hIT8, char ***SampleNames);
|
||||
|
||||
CMSAPI const char* CMSEXPORT cmsIT8GetPatchName(cmsHANDLE hIT8, int nPatch, char* buffer);
|
||||
CMSAPI int CMSEXPORT cmsIT8GetPatchByName(cmsHANDLE hIT8, const char *cPatch);
|
||||
|
||||
// The LABEL extension
|
||||
CMSAPI int CMSEXPORT cmsIT8SetTableByLabel(cmsHANDLE hIT8, const char* cSet, const char* cField, const char* ExpectedType);
|
||||
|
||||
CMSAPI cmsBool CMSEXPORT cmsIT8SetIndexColumn(cmsHANDLE hIT8, const char* cSample);
|
||||
|
||||
// Formatter for double
|
||||
CMSAPI void CMSEXPORT cmsIT8DefineDblFormat(cmsHANDLE hIT8, const char* Formatter);
|
||||
|
||||
@@ -1717,6 +1860,7 @@ CMSAPI cmsBool CMSEXPORT cmsGDBCheckPoint(cmsHANDLE hGBD, const cmsCIEL
|
||||
|
||||
// Estimate the black point
|
||||
CMSAPI cmsBool CMSEXPORT cmsDetectBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags);
|
||||
CMSAPI cmsBool CMSEXPORT cmsDetectDestinationBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags);
|
||||
|
||||
// Estimate total area coverage
|
||||
CMSAPI cmsFloat64Number CMSEXPORT cmsDetectTAC(cmsHPROFILE hProfile);
|
||||
|
||||
132
thirdparty/liblcms2/include/lcms2_plugin.h
vendored
132
thirdparty/liblcms2/include/lcms2_plugin.h
vendored
@@ -1,7 +1,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2011 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"),
|
||||
@@ -131,7 +131,7 @@ struct _cms_io_handler {
|
||||
// Endianess adjust functions
|
||||
CMSAPI cmsUInt16Number CMSEXPORT _cmsAdjustEndianess16(cmsUInt16Number Word);
|
||||
CMSAPI cmsUInt32Number CMSEXPORT _cmsAdjustEndianess32(cmsUInt32Number Value);
|
||||
CMSAPI void CMSEXPORT _cmsAdjustEndianess64(cmsUInt64Number* Result, cmsUInt64Number QWord);
|
||||
CMSAPI void CMSEXPORT _cmsAdjustEndianess64(cmsUInt64Number* Result, cmsUInt64Number* QWord);
|
||||
|
||||
// Helper IO functions
|
||||
CMSAPI cmsBool CMSEXPORT _cmsReadUInt8Number(cmsIOHANDLER* io, cmsUInt8Number* n);
|
||||
@@ -147,7 +147,7 @@ CMSAPI cmsBool CMSEXPORT _cmsWriteUInt8Number(cmsIOHANDLER* io, cmsUI
|
||||
CMSAPI cmsBool CMSEXPORT _cmsWriteUInt16Number(cmsIOHANDLER* io, cmsUInt16Number n);
|
||||
CMSAPI cmsBool CMSEXPORT _cmsWriteUInt32Number(cmsIOHANDLER* io, cmsUInt32Number n);
|
||||
CMSAPI cmsBool CMSEXPORT _cmsWriteFloat32Number(cmsIOHANDLER* io, cmsFloat32Number n);
|
||||
CMSAPI cmsBool CMSEXPORT _cmsWriteUInt64Number(cmsIOHANDLER* io, cmsUInt64Number n);
|
||||
CMSAPI cmsBool CMSEXPORT _cmsWriteUInt64Number(cmsIOHANDLER* io, cmsUInt64Number* n);
|
||||
CMSAPI cmsBool CMSEXPORT _cmsWrite15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number n);
|
||||
CMSAPI cmsBool CMSEXPORT _cmsWriteXYZNumber(cmsIOHANDLER* io, const cmsCIEXYZ* XYZ);
|
||||
CMSAPI cmsBool CMSEXPORT _cmsWriteUInt16Array(cmsIOHANDLER* io, cmsUInt32Number n, const cmsUInt16Number* Array);
|
||||
@@ -181,6 +181,11 @@ CMSAPI cmsS15Fixed16Number CMSEXPORT _cmsDoubleTo15Fixed16(cmsFloat64Number v);
|
||||
CMSAPI void CMSEXPORT _cmsEncodeDateTimeNumber(cmsDateTimeNumber *Dest, const struct tm *Source);
|
||||
CMSAPI void CMSEXPORT _cmsDecodeDateTimeNumber(const cmsDateTimeNumber *Source, struct tm *Dest);
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Shared callbacks for user data
|
||||
typedef void (* _cmsFreeUserDataFn)(cmsContext ContextID, void* Data);
|
||||
typedef void* (* _cmsDupUserDataFn)(cmsContext ContextID, const void* Data);
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -196,6 +201,8 @@ CMSAPI void CMSEXPORT _cmsDecodeDateTimeNumber(const cmsDateTimeN
|
||||
#define cmsPluginRenderingIntentSig 0x696E7448 // 'intH'
|
||||
#define cmsPluginMultiProcessElementSig 0x6D706548 // 'mpeH'
|
||||
#define cmsPluginOptimizationSig 0x6F707448 // 'optH'
|
||||
#define cmsPluginTransformSig 0x7A666D48 // 'xfmH'
|
||||
#define cmsPluginMutexSig 0x6D747A48 // 'mtxH'
|
||||
|
||||
typedef struct _cmsPluginBaseStruct {
|
||||
|
||||
@@ -212,19 +219,28 @@ typedef struct _cmsPluginBaseStruct {
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Memory handler. Each new plug-in type replaces current behaviour
|
||||
|
||||
typedef void* (* _cmsMallocFnPtrType)(cmsContext ContextID, cmsUInt32Number size);
|
||||
typedef void (* _cmsFreeFnPtrType)(cmsContext ContextID, void *Ptr);
|
||||
typedef void* (* _cmsReallocFnPtrType)(cmsContext ContextID, void* Ptr, cmsUInt32Number NewSize);
|
||||
|
||||
typedef void* (* _cmsMalloZerocFnPtrType)(cmsContext ContextID, cmsUInt32Number size);
|
||||
typedef void* (* _cmsCallocFnPtrType)(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Number size);
|
||||
typedef void* (* _cmsDupFnPtrType)(cmsContext ContextID, const void* Org, cmsUInt32Number size);
|
||||
|
||||
typedef struct {
|
||||
|
||||
cmsPluginBase base;
|
||||
|
||||
// Required
|
||||
void * (* MallocPtr)(cmsContext ContextID, cmsUInt32Number size);
|
||||
void (* FreePtr)(cmsContext ContextID, void *Ptr);
|
||||
void * (* ReallocPtr)(cmsContext ContextID, void* Ptr, cmsUInt32Number NewSize);
|
||||
_cmsMallocFnPtrType MallocPtr;
|
||||
_cmsFreeFnPtrType FreePtr;
|
||||
_cmsReallocFnPtrType ReallocPtr;
|
||||
|
||||
// Optional
|
||||
void * (* MallocZeroPtr)(cmsContext ContextID, cmsUInt32Number size);
|
||||
void * (* CallocPtr)(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Number size);
|
||||
void * (* DupPtr)(cmsContext ContextID, const void* Org, cmsUInt32Number size);
|
||||
_cmsMalloZerocFnPtrType MallocZeroPtr;
|
||||
_cmsCallocFnPtrType CallocPtr;
|
||||
_cmsDupFnPtrType DupPtr;
|
||||
|
||||
} cmsPluginMemHandler;
|
||||
|
||||
@@ -387,7 +403,7 @@ typedef struct _cms_typehandler_struct {
|
||||
void *Ptr);
|
||||
|
||||
// Additional parameters used by the calling thread
|
||||
cmsContext ContextID;
|
||||
cmsContext ContextID;
|
||||
cmsUInt32Number ICCVersion;
|
||||
|
||||
} cmsTagTypeHandler;
|
||||
@@ -486,6 +502,39 @@ typedef struct {
|
||||
|
||||
} cmsPluginMultiProcessElement;
|
||||
|
||||
|
||||
// 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;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
// Optimization. Using this plug-in, additional optimization strategies may be implemented.
|
||||
// The function should return TRUE if any optimization is done on the LUT, this terminates
|
||||
@@ -496,9 +545,6 @@ typedef void (* _cmsOPTeval16Fn)(register const cmsUInt16Number In[],
|
||||
register cmsUInt16Number Out[],
|
||||
register const void* Data);
|
||||
|
||||
typedef void (* _cmsOPTfreeDataFn)(cmsContext ContextID, void* Data);
|
||||
typedef void* (* _cmsOPTdupDataFn)(cmsContext ContextID, const void* Data);
|
||||
|
||||
|
||||
typedef cmsBool (* _cmsOPToptimizeFn)(cmsPipeline** Lut,
|
||||
cmsUInt32Number Intent,
|
||||
@@ -512,8 +558,8 @@ typedef cmsBool (* _cmsOPToptimizeFn)(cmsPipeline** Lut,
|
||||
CMSAPI void CMSEXPORT _cmsPipelineSetOptimizationParameters(cmsPipeline* Lut,
|
||||
_cmsOPTeval16Fn Eval16,
|
||||
void* PrivateData,
|
||||
_cmsOPTfreeDataFn FreePrivateDataFn,
|
||||
_cmsOPTdupDataFn DupPrivateDataFn);
|
||||
_cmsFreeUserDataFn FreePrivateDataFn,
|
||||
_cmsDupUserDataFn DupPrivateDataFn);
|
||||
|
||||
typedef struct {
|
||||
cmsPluginBase base;
|
||||
@@ -524,6 +570,62 @@ typedef struct {
|
||||
} cmsPluginOptimization;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
// Full xform
|
||||
typedef void (* _cmsTransformFn)(struct _cmstransform_struct *CMMcargo,
|
||||
const void* InputBuffer,
|
||||
void* OutputBuffer,
|
||||
cmsUInt32Number Size,
|
||||
cmsUInt32Number Stride);
|
||||
|
||||
typedef cmsBool (* _cmsTransformFactory)(_cmsTransformFn* xform,
|
||||
void** UserData,
|
||||
_cmsFreeUserDataFn* FreePrivateDataFn,
|
||||
cmsPipeline** Lut,
|
||||
cmsUInt32Number* InputFormat,
|
||||
cmsUInt32Number* OutputFormat,
|
||||
cmsUInt32Number* dwFlags);
|
||||
|
||||
|
||||
// Retrieve user data as specified by the factory
|
||||
CMSAPI void CMSEXPORT _cmsSetTransformUserData(struct _cmstransform_struct *CMMcargo, void* ptr, _cmsFreeUserDataFn FreePrivateDataFn);
|
||||
CMSAPI void * CMSEXPORT _cmsGetTransformUserData(struct _cmstransform_struct *CMMcargo);
|
||||
|
||||
|
||||
// Retrieve formatters
|
||||
CMSAPI void CMSEXPORT _cmsGetTransformFormatters16 (struct _cmstransform_struct *CMMcargo, cmsFormatter16* FromInput, cmsFormatter16* ToOutput);
|
||||
CMSAPI void CMSEXPORT _cmsGetTransformFormattersFloat(struct _cmstransform_struct *CMMcargo, cmsFormatterFloat* FromInput, cmsFormatterFloat* ToOutput);
|
||||
|
||||
typedef struct {
|
||||
cmsPluginBase base;
|
||||
|
||||
// Transform entry point
|
||||
_cmsTransformFactory Factory;
|
||||
|
||||
} cmsPluginTransform;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
// Mutex
|
||||
|
||||
typedef void* (* _cmsCreateMutexFnPtrType)(cmsContext ContextID);
|
||||
typedef void (* _cmsDestroyMutexFnPtrType)(cmsContext ContextID, void* mtx);
|
||||
typedef cmsBool (* _cmsLockMutexFnPtrType)(cmsContext ContextID, void* mtx);
|
||||
typedef void (* _cmsUnlockMutexFnPtrType)(cmsContext ContextID, void* mtx);
|
||||
|
||||
typedef struct {
|
||||
cmsPluginBase base;
|
||||
|
||||
_cmsCreateMutexFnPtrType CreateMutexPtr;
|
||||
_cmsDestroyMutexFnPtrType DestroyMutexPtr;
|
||||
_cmsLockMutexFnPtrType LockMutexPtr;
|
||||
_cmsUnlockMutexFnPtrType UnlockMutexPtr;
|
||||
|
||||
} cmsPluginMutex;
|
||||
|
||||
CMSAPI void* CMSEXPORT _cmsCreateMutex(cmsContext ContextID);
|
||||
CMSAPI void CMSEXPORT _cmsDestroyMutex(cmsContext ContextID, void* mtx);
|
||||
CMSAPI cmsBool CMSEXPORT _cmsLockMutex(cmsContext ContextID, void* mtx);
|
||||
CMSAPI void CMSEXPORT _cmsUnlockMutex(cmsContext ContextID, void* mtx);
|
||||
|
||||
|
||||
#ifndef CMS_USE_CPP_API
|
||||
# ifdef __cplusplus
|
||||
|
||||
267
thirdparty/liblcms2/src/cmscam02.c
vendored
267
thirdparty/liblcms2/src/cmscam02.c
vendored
@@ -1,24 +1,24 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2012 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
|
||||
// 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
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
//---------------------------------------------------------------------------------
|
||||
@@ -31,7 +31,7 @@
|
||||
// ---------- Implementation --------------------------------------------
|
||||
|
||||
typedef struct {
|
||||
|
||||
|
||||
cmsFloat64Number XYZ[3];
|
||||
cmsFloat64Number RGB[3];
|
||||
cmsFloat64Number RGBc[3];
|
||||
@@ -41,55 +41,55 @@ typedef struct {
|
||||
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;
|
||||
|
||||
cmsContext ContextID;
|
||||
|
||||
} cmsCIECAM02;
|
||||
|
||||
|
||||
static
|
||||
cmsFloat64Number compute_n(cmsCIECAM02* pMod)
|
||||
cmsFloat64Number compute_n(cmsCIECAM02* pMod)
|
||||
{
|
||||
return (pMod -> Yb / pMod -> adoptedWhite.XYZ[1]);
|
||||
}
|
||||
|
||||
static
|
||||
cmsFloat64Number compute_z(cmsCIECAM02* pMod)
|
||||
cmsFloat64Number compute_z(cmsCIECAM02* pMod)
|
||||
{
|
||||
return (1.48 + pow(pMod -> n, 0.5));
|
||||
}
|
||||
|
||||
static
|
||||
cmsFloat64Number computeNbb(cmsCIECAM02* pMod)
|
||||
cmsFloat64Number computeNbb(cmsCIECAM02* pMod)
|
||||
{
|
||||
return (0.725 * pow((1.0 / pMod -> n), 0.2));
|
||||
}
|
||||
|
||||
static
|
||||
cmsFloat64Number computeFL(cmsCIECAM02* pMod)
|
||||
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)
|
||||
static
|
||||
cmsFloat64Number computeD(cmsCIECAM02* pMod)
|
||||
{
|
||||
cmsFloat64Number D;
|
||||
|
||||
@@ -100,17 +100,17 @@ cmsFloat64Number computeD(cmsCIECAM02* pMod)
|
||||
|
||||
|
||||
static
|
||||
CAM02COLOR XYZtoCAT02(CAM02COLOR clr)
|
||||
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)
|
||||
CAM02COLOR ChromaticAdaptation(CAM02COLOR clr, cmsCIECAM02* pMod)
|
||||
{
|
||||
cmsUInt32Number i;
|
||||
|
||||
@@ -120,15 +120,15 @@ CAM02COLOR ChromaticAdaptation(CAM02COLOR clr, cmsCIECAM02* pMod)
|
||||
(1.0 - pMod->D)) * clr.RGB[i];
|
||||
}
|
||||
|
||||
return clr;
|
||||
return clr;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
CAM02COLOR CAT02toHPE(CAM02COLOR clr)
|
||||
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));
|
||||
@@ -138,16 +138,16 @@ CAM02COLOR CAT02toHPE(CAM02COLOR clr)
|
||||
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)
|
||||
CAM02COLOR NonlinearCompression(CAM02COLOR clr, cmsCIECAM02* pMod)
|
||||
{
|
||||
cmsUInt32Number i;
|
||||
cmsFloat64Number temp;
|
||||
@@ -163,21 +163,21 @@ CAM02COLOR NonlinearCompression(CAM02COLOR clr, cmsCIECAM02* pMod)
|
||||
clr.RGBpa[i] = (400.0 * temp) / (temp + 27.13) + 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
clr.A = (((2.0 * clr.RGBpa[0]) + clr.RGBpa[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)
|
||||
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;
|
||||
@@ -194,11 +194,11 @@ CAM02COLOR ComputeCorrelates(CAM02COLOR clr, cmsCIECAM02* pMod)
|
||||
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);
|
||||
|
||||
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;
|
||||
@@ -219,15 +219,15 @@ CAM02COLOR ComputeCorrelates(CAM02COLOR clr, cmsCIECAM02* pMod)
|
||||
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),
|
||||
|
||||
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] +
|
||||
(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) *
|
||||
@@ -235,34 +235,34 @@ CAM02COLOR ComputeCorrelates(CAM02COLOR clr, cmsCIECAM02* pMod)
|
||||
|
||||
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)
|
||||
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)))),
|
||||
(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)) /
|
||||
@@ -279,17 +279,17 @@ CAM02COLOR InverseCorrelates(CAM02COLOR clr, cmsCIECAM02* pMod)
|
||||
(sin(hr) / cos(hr)));
|
||||
clr.b = clr.a * (sin(hr) / cos(hr));
|
||||
}
|
||||
|
||||
clr.RGBpa[0] = ((460.0 / 1403.0) * p2) +
|
||||
|
||||
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) -
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -298,7 +298,7 @@ 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;
|
||||
@@ -307,15 +307,15 @@ CAM02COLOR InverseNonlinearity(CAM02COLOR clr, cmsCIECAM02* pMod)
|
||||
(400.0 - fabs(clr.RGBpa[i] - 0.1))),
|
||||
(1.0 / 0.42));
|
||||
}
|
||||
|
||||
|
||||
return clr;
|
||||
}
|
||||
|
||||
static
|
||||
CAM02COLOR HPEtoCAT02(CAM02COLOR clr)
|
||||
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);
|
||||
@@ -325,7 +325,7 @@ CAM02COLOR HPEtoCAT02(CAM02COLOR clr)
|
||||
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]);
|
||||
@@ -334,10 +334,10 @@ CAM02COLOR HPEtoCAT02(CAM02COLOR clr)
|
||||
|
||||
|
||||
static
|
||||
CAM02COLOR InverseChromaticAdaptation(CAM02COLOR clr, cmsCIECAM02* pMod)
|
||||
CAM02COLOR InverseChromaticAdaptation(CAM02COLOR clr, cmsCIECAM02* pMod)
|
||||
{
|
||||
cmsUInt32Number i;
|
||||
for (i = 0; i < 3; 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);
|
||||
}
|
||||
@@ -346,82 +346,82 @@ CAM02COLOR InverseChromaticAdaptation(CAM02COLOR clr, cmsCIECAM02* pMod)
|
||||
|
||||
|
||||
static
|
||||
CAM02COLOR CAT02toXYZ(CAM02COLOR clr)
|
||||
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;
|
||||
cmsCIECAM02* lpMod;
|
||||
|
||||
_cmsAssert(pVC != NULL);
|
||||
_cmsAssert(pVC != NULL);
|
||||
|
||||
if((lpMod = (cmsCIECAM02*) _cmsMallocZero(ContextID, sizeof(cmsCIECAM02))) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if((lpMod = (cmsCIECAM02*) _cmsMallocZero(ContextID, sizeof(cmsCIECAM02))) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lpMod ->ContextID = ContextID;
|
||||
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 ->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;
|
||||
lpMod -> LA = pVC ->La;
|
||||
lpMod -> Yb = pVC ->Yb;
|
||||
lpMod -> D = pVC ->D_value;
|
||||
lpMod -> surround = pVC ->surround;
|
||||
|
||||
switch (lpMod -> surround) {
|
||||
switch (lpMod -> surround) {
|
||||
|
||||
|
||||
case CUTSHEET_SURROUND:
|
||||
lpMod->F = 0.8;
|
||||
lpMod->c = 0.41;
|
||||
lpMod->Nc = 0.8;
|
||||
break;
|
||||
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 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;
|
||||
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;
|
||||
}
|
||||
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);
|
||||
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);
|
||||
}
|
||||
if (lpMod -> D == D_CALCULATE) {
|
||||
lpMod -> D = computeD(lpMod);
|
||||
}
|
||||
|
||||
lpMod -> Ncb = lpMod -> Nbb;
|
||||
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);
|
||||
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;
|
||||
return (cmsHANDLE) lpMod;
|
||||
|
||||
}
|
||||
|
||||
@@ -429,32 +429,34 @@ void CMSEXPORT cmsCIECAM02Done(cmsHANDLE hModel)
|
||||
{
|
||||
cmsCIECAM02* lpMod = (cmsCIECAM02*) hModel;
|
||||
|
||||
if (lpMod) _cmsFree(lpMod ->ContextID, lpMod);
|
||||
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);
|
||||
|
||||
_cmsAssert(lpMod != NULL);
|
||||
_cmsAssert(pIn != NULL);
|
||||
_cmsAssert(pOut != NULL);
|
||||
|
||||
memset(&clr, 0, sizeof(clr));
|
||||
|
||||
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;
|
||||
pOut ->h = clr.h;
|
||||
}
|
||||
|
||||
void CMSEXPORT cmsCIECAM02Reverse(cmsHANDLE hModel, const cmsJCh* pIn, cmsCIEXYZ* pOut)
|
||||
@@ -462,22 +464,23 @@ void CMSEXPORT cmsCIECAM02Reverse(cmsHANDLE hModel, const cmsJCh* pIn, cmsCIEXYZ
|
||||
CAM02COLOR clr;
|
||||
cmsCIECAM02* lpMod = (cmsCIECAM02*) hModel;
|
||||
|
||||
_cmsAssert(lpMod != NULL);
|
||||
_cmsAssert(pIn != NULL);
|
||||
_cmsAssert(pOut != NULL);
|
||||
_cmsAssert(lpMod != NULL);
|
||||
_cmsAssert(pIn != NULL);
|
||||
_cmsAssert(pOut != NULL);
|
||||
|
||||
memset(&clr, 0, sizeof(clr));
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
|
||||
852
thirdparty/liblcms2/src/cmscgats.c
vendored
852
thirdparty/liblcms2/src/cmscgats.c
vendored
File diff suppressed because it is too large
Load Diff
583
thirdparty/liblcms2/src/cmscnvrt.c
vendored
583
thirdparty/liblcms2/src/cmscnvrt.c
vendored
File diff suppressed because it is too large
Load Diff
418
thirdparty/liblcms2/src/cmserr.c
vendored
418
thirdparty/liblcms2/src/cmserr.c
vendored
@@ -1,24 +1,24 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2012 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
|
||||
// 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
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
//---------------------------------------------------------------------------------
|
||||
@@ -31,30 +31,31 @@
|
||||
// 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;
|
||||
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));
|
||||
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;
|
||||
long int p , n;
|
||||
|
||||
p = ftell(f); // register current file position
|
||||
p = ftell(f); // register current file position
|
||||
|
||||
if (fseek(f, 0, SEEK_END) != 0) {
|
||||
return -1;
|
||||
}
|
||||
if (fseek(f, 0, SEEK_END) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
n = ftell(f);
|
||||
fseek(f, p, SEEK_SET); // file position restored
|
||||
fseek(f, p, SEEK_SET); // file position restored
|
||||
|
||||
return n;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
@@ -62,23 +63,22 @@ long int CMSEXPORT cmsfilelength(FILE* f)
|
||||
//
|
||||
// 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.
|
||||
// amount of memoy that can be reclaimed. This is mostly as a safety feature to prevent
|
||||
// bogus or evil 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
|
||||
// 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);
|
||||
cmsBool _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
|
||||
|
||||
// *********************************************************************************
|
||||
|
||||
// This is the default memory allocation function. It does a very coarse
|
||||
// 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)
|
||||
@@ -109,13 +109,13 @@ 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);
|
||||
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.
|
||||
// The default realloc function. Again it checks 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)
|
||||
{
|
||||
@@ -139,13 +139,13 @@ void* _cmsCallocDefaultFn(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Nu
|
||||
if (Total == 0) return NULL;
|
||||
|
||||
// Safe check for overflow.
|
||||
if (num >= UINT_MAX / size) return NULL;
|
||||
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);
|
||||
@@ -156,7 +156,7 @@ 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);
|
||||
@@ -167,95 +167,149 @@ void* _cmsDupDefaultFn(cmsContext ContextID, const void* Org, cmsUInt32Number si
|
||||
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;
|
||||
|
||||
// Pointers to memory manager functions in Context0
|
||||
_cmsMemPluginChunkType _cmsMemPluginChunk = { _cmsMallocDefaultFn, _cmsMallocZeroDefaultFn, _cmsFreeDefaultFn,
|
||||
_cmsReallocDefaultFn, _cmsCallocDefaultFn, _cmsDupDefaultFn
|
||||
};
|
||||
|
||||
|
||||
// Reset and duplicate memory manager
|
||||
void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx, const struct _cmsContext_struct* src)
|
||||
{
|
||||
_cmsAssert(ctx != NULL);
|
||||
|
||||
if (src != NULL) {
|
||||
|
||||
// Duplicate
|
||||
ctx ->chunks[MemPlugin] = _cmsSubAllocDup(ctx ->MemPool, src ->chunks[MemPlugin], sizeof(_cmsMemPluginChunkType));
|
||||
}
|
||||
else {
|
||||
|
||||
// To reset it, we use the default allocators, which cannot be overriden
|
||||
ctx ->chunks[MemPlugin] = &ctx ->DefaultMemoryManager;
|
||||
}
|
||||
}
|
||||
|
||||
// Auxiliar to fill memory management functions from plugin (or context 0 defaults)
|
||||
void _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr)
|
||||
{
|
||||
if (Plugin == NULL) {
|
||||
|
||||
memcpy(ptr, &_cmsMemPluginChunk, sizeof(_cmsMemPluginChunk));
|
||||
}
|
||||
else {
|
||||
|
||||
ptr ->MallocPtr = Plugin -> MallocPtr;
|
||||
ptr ->FreePtr = Plugin -> FreePtr;
|
||||
ptr ->ReallocPtr = Plugin -> ReallocPtr;
|
||||
|
||||
// Make sure we revert to defaults
|
||||
ptr ->MallocZeroPtr= _cmsMallocZeroDefaultFn;
|
||||
ptr ->CallocPtr = _cmsCallocDefaultFn;
|
||||
ptr ->DupPtr = _cmsDupDefaultFn;
|
||||
|
||||
if (Plugin ->MallocZeroPtr != NULL) ptr ->MallocZeroPtr = Plugin -> MallocZeroPtr;
|
||||
if (Plugin ->CallocPtr != NULL) ptr ->CallocPtr = Plugin -> CallocPtr;
|
||||
if (Plugin ->DupPtr != NULL) ptr ->DupPtr = Plugin -> DupPtr;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Plug-in replacement entry
|
||||
cmsBool _cmsRegisterMemHandlerPlugin(cmsPluginBase *Data)
|
||||
cmsBool _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase *Data)
|
||||
{
|
||||
cmsPluginMemHandler* Plugin = (cmsPluginMemHandler*) Data;
|
||||
cmsPluginMemHandler* Plugin = (cmsPluginMemHandler*) Data;
|
||||
_cmsMemPluginChunkType* ptr;
|
||||
|
||||
// NULL forces to reset to defaults
|
||||
// NULL forces to reset to defaults. In this special case, the defaults are stored in the context structure.
|
||||
// Remaining plug-ins does NOT have any copy in the context structure, but this is somehow special as the
|
||||
// context internal data should be malloce'd by using those functions.
|
||||
if (Data == NULL) {
|
||||
|
||||
MallocPtr = _cmsMallocDefaultFn;
|
||||
MallocZeroPtr= _cmsMallocZeroDefaultFn;
|
||||
FreePtr = _cmsFreeDefaultFn;
|
||||
ReallocPtr = _cmsReallocDefaultFn;
|
||||
CallocPtr = _cmsCallocDefaultFn;
|
||||
DupPtr = _cmsDupDefaultFn;
|
||||
struct _cmsContext_struct* ctx = ( struct _cmsContext_struct*) ContextID;
|
||||
|
||||
// Return to the default allocators
|
||||
if (ContextID != NULL) {
|
||||
ctx->chunks[MemPlugin] = (void*) &ctx->DefaultMemoryManager;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Check for required callbacks
|
||||
if (Plugin -> MallocPtr == NULL ||
|
||||
// Check for required callbacks
|
||||
if (Plugin -> MallocPtr == NULL ||
|
||||
Plugin -> FreePtr == NULL ||
|
||||
Plugin -> ReallocPtr == NULL) return FALSE;
|
||||
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;
|
||||
ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin);
|
||||
if (ptr == NULL)
|
||||
return FALSE;
|
||||
|
||||
_cmsInstallAllocFunctions(Plugin, ptr);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Generic allocate
|
||||
void* CMSEXPORT _cmsMalloc(cmsContext ContextID, cmsUInt32Number size)
|
||||
{
|
||||
return MallocPtr(ContextID, size);
|
||||
_cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin);
|
||||
return ptr ->MallocPtr(ContextID, size);
|
||||
}
|
||||
|
||||
// Generic allocate & zero
|
||||
void* CMSEXPORT _cmsMallocZero(cmsContext ContextID, cmsUInt32Number size)
|
||||
{
|
||||
return MallocZeroPtr(ContextID, size);
|
||||
_cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin);
|
||||
return ptr->MallocZeroPtr(ContextID, size);
|
||||
}
|
||||
|
||||
// Generic calloc
|
||||
void* CMSEXPORT _cmsCalloc(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Number size)
|
||||
{
|
||||
return CallocPtr(ContextID, num, size);
|
||||
_cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin);
|
||||
return ptr->CallocPtr(ContextID, num, size);
|
||||
}
|
||||
|
||||
// Generic reallocate
|
||||
void* CMSEXPORT _cmsRealloc(cmsContext ContextID, void* Ptr, cmsUInt32Number size)
|
||||
{
|
||||
return ReallocPtr(ContextID, Ptr, size);
|
||||
_cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin);
|
||||
return ptr->ReallocPtr(ContextID, Ptr, size);
|
||||
}
|
||||
|
||||
// Generic free memory
|
||||
void CMSEXPORT _cmsFree(cmsContext ContextID, void* Ptr)
|
||||
{
|
||||
if (Ptr != NULL) FreePtr(ContextID, Ptr);
|
||||
if (Ptr != NULL) {
|
||||
_cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin);
|
||||
ptr ->FreePtr(ContextID, Ptr);
|
||||
}
|
||||
}
|
||||
|
||||
// Generic block duplication
|
||||
void* CMSEXPORT _cmsDupMem(cmsContext ContextID, const void* Org, cmsUInt32Number size)
|
||||
{
|
||||
return DupPtr(ContextID, Org, size);
|
||||
_cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin);
|
||||
return ptr ->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)
|
||||
// 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 that may not be true on all platforms)
|
||||
static
|
||||
_cmsSubAllocator_chunk* _cmsCreateSubAllocChunk(cmsContext ContextID, cmsUInt32Number Initial)
|
||||
{
|
||||
_cmsSubAllocator_chunk* chunk;
|
||||
|
||||
// 20K by default
|
||||
if (Initial == 0)
|
||||
Initial = 20*1024;
|
||||
|
||||
// Create the container
|
||||
chunk = (_cmsSubAllocator_chunk*) _cmsMallocZero(ContextID, sizeof(_cmsSubAllocator_chunk));
|
||||
if (chunk == NULL) return NULL;
|
||||
@@ -269,10 +323,6 @@ _cmsSubAllocator_chunk* _cmsCreateSubAllocChunk(cmsContext ContextID, cmsUInt32N
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 20K by default
|
||||
if (Initial == 0)
|
||||
Initial = 20*1024;
|
||||
|
||||
chunk ->BlockSize = Initial;
|
||||
chunk ->Used = 0;
|
||||
chunk ->next = NULL;
|
||||
@@ -325,9 +375,9 @@ void* _cmsSubAlloc(_cmsSubAllocator* sub, cmsUInt32Number size)
|
||||
cmsUInt32Number Free = sub -> h ->BlockSize - sub -> h -> Used;
|
||||
cmsUInt8Number* ptr;
|
||||
|
||||
size = _cmsALIGNLONG(size);
|
||||
size = _cmsALIGNMEM(size);
|
||||
|
||||
// Check for memory. If there is no room, allocate a new chunk of double memory size.
|
||||
// Check for memory. If there is no room, allocate a new chunk of double memory size.
|
||||
if (size > Free) {
|
||||
|
||||
_cmsSubAllocator_chunk* chunk;
|
||||
@@ -344,20 +394,40 @@ void* _cmsSubAlloc(_cmsSubAllocator* sub, cmsUInt32Number size)
|
||||
sub ->h = chunk;
|
||||
|
||||
}
|
||||
|
||||
|
||||
ptr = sub -> h ->Block + sub -> h ->Used;
|
||||
sub -> h -> Used += size;
|
||||
|
||||
return (void*) ptr;
|
||||
}
|
||||
|
||||
// Duplicate in pool
|
||||
void* _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size)
|
||||
{
|
||||
void *NewPtr;
|
||||
|
||||
// Dup of null pointer is also NULL
|
||||
if (ptr == NULL)
|
||||
return NULL;
|
||||
|
||||
NewPtr = _cmsSubAlloc(s, size);
|
||||
|
||||
if (ptr != NULL && NewPtr != NULL) {
|
||||
memcpy(NewPtr, ptr, size);
|
||||
}
|
||||
|
||||
return NewPtr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 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
|
||||
// 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
|
||||
@@ -372,8 +442,26 @@ void* _cmsSubAlloc(_cmsSubAllocator* sub, cmsUInt32Number size)
|
||||
// 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;
|
||||
// Context0 storage, which is global
|
||||
_cmsLogErrorChunkType _cmsLogErrorChunk = { DefaultLogErrorHandlerFunction };
|
||||
|
||||
// Allocates and inits error logger container for a given context. If src is NULL, only initializes the value
|
||||
// to the default. Otherwise, it duplicates the value. The interface is standard across all context clients
|
||||
void _cmsAllocLogErrorChunk(struct _cmsContext_struct* ctx,
|
||||
const struct _cmsContext_struct* src)
|
||||
{
|
||||
static _cmsLogErrorChunkType LogErrorChunk = { DefaultLogErrorHandlerFunction };
|
||||
void* from;
|
||||
|
||||
if (src != NULL) {
|
||||
from = src ->chunks[Logger];
|
||||
}
|
||||
else {
|
||||
from = &LogErrorChunk;
|
||||
}
|
||||
|
||||
ctx ->chunks[Logger] = _cmsSubAllocDup(ctx ->MemPool, from, sizeof(_cmsLogErrorChunkType));
|
||||
}
|
||||
|
||||
// The default error logger does nothing.
|
||||
static
|
||||
@@ -381,34 +469,50 @@ void DefaultLogErrorHandlerFunction(cmsContext ContextID, cmsUInt32Number ErrorC
|
||||
{
|
||||
// fprintf(stderr, "[lcms]: %s\n", Text);
|
||||
// fflush(stderr);
|
||||
|
||||
|
||||
cmsUNUSED_PARAMETER(ContextID);
|
||||
cmsUNUSED_PARAMETER(ErrorCode);
|
||||
cmsUNUSED_PARAMETER(Text);
|
||||
cmsUNUSED_PARAMETER(Text);
|
||||
}
|
||||
|
||||
// Change log error
|
||||
// Change log error, context based
|
||||
void CMSEXPORT cmsSetLogErrorHandlerTHR(cmsContext ContextID, cmsLogErrorHandlerFunction Fn)
|
||||
{
|
||||
_cmsLogErrorChunkType* lhg = (_cmsLogErrorChunkType*) _cmsContextGetClientChunk(ContextID, Logger);
|
||||
|
||||
if (lhg != NULL) {
|
||||
|
||||
if (Fn == NULL)
|
||||
lhg -> LogErrorHandler = DefaultLogErrorHandlerFunction;
|
||||
else
|
||||
lhg -> LogErrorHandler = Fn;
|
||||
}
|
||||
}
|
||||
|
||||
// Change log error, legacy
|
||||
void CMSEXPORT cmsSetLogErrorHandler(cmsLogErrorHandlerFunction Fn)
|
||||
{
|
||||
if (Fn == NULL)
|
||||
LogErrorHandler = DefaultLogErrorHandlerFunction;
|
||||
else
|
||||
LogErrorHandler = Fn;
|
||||
cmsSetLogErrorHandlerTHR(NULL, Fn);
|
||||
}
|
||||
|
||||
// Log an error
|
||||
// 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];
|
||||
_cmsLogErrorChunkType* lhg;
|
||||
|
||||
|
||||
va_start(args, ErrorText);
|
||||
vsnprintf(Buffer, MAX_ERROR_MESSAGE_LEN-1, ErrorText, args);
|
||||
va_end(args);
|
||||
va_end(args);
|
||||
|
||||
// Call handler
|
||||
LogErrorHandler(ContextID, ErrorCode, Buffer);
|
||||
// Check for the context, if specified go there. If not, go for the global
|
||||
lhg = (_cmsLogErrorChunkType*) _cmsContextGetClientChunk(ContextID, Logger);
|
||||
if (lhg ->LogErrorHandler) {
|
||||
lhg ->LogErrorHandler(ContextID, ErrorCode, Buffer);
|
||||
}
|
||||
}
|
||||
|
||||
// Utility function to print signatures
|
||||
@@ -419,10 +523,132 @@ void _cmsTagSignature2String(char String[5], cmsTagSignature sig)
|
||||
// Convert to big endian
|
||||
be = _cmsAdjustEndianess32((cmsUInt32Number) sig);
|
||||
|
||||
// Move chars
|
||||
// Move chars
|
||||
memmove(String, &be, 4);
|
||||
|
||||
// Make sure of terminator
|
||||
String[4] = 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
static
|
||||
void* defMtxCreate(cmsContext id)
|
||||
{
|
||||
_cmsMutex* ptr_mutex = (_cmsMutex*) _cmsMalloc(id, sizeof(_cmsMutex));
|
||||
_cmsInitMutexPrimitive(ptr_mutex);
|
||||
return (void*) ptr_mutex;
|
||||
}
|
||||
|
||||
static
|
||||
void defMtxDestroy(cmsContext id, void* mtx)
|
||||
{
|
||||
_cmsDestroyMutexPrimitive((_cmsMutex *) mtx);
|
||||
_cmsFree(id, mtx);
|
||||
}
|
||||
|
||||
static
|
||||
cmsBool defMtxLock(cmsContext id, void* mtx)
|
||||
{
|
||||
cmsUNUSED_PARAMETER(id);
|
||||
return _cmsLockPrimitive((_cmsMutex *) mtx) == 0;
|
||||
}
|
||||
|
||||
static
|
||||
void defMtxUnlock(cmsContext id, void* mtx)
|
||||
{
|
||||
cmsUNUSED_PARAMETER(id);
|
||||
_cmsUnlockPrimitive((_cmsMutex *) mtx);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Pointers to memory manager functions in Context0
|
||||
_cmsMutexPluginChunkType _cmsMutexPluginChunk = { defMtxCreate, defMtxDestroy, defMtxLock, defMtxUnlock };
|
||||
|
||||
// Allocate and init mutex container.
|
||||
void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx,
|
||||
const struct _cmsContext_struct* src)
|
||||
{
|
||||
static _cmsMutexPluginChunkType MutexChunk = {defMtxCreate, defMtxDestroy, defMtxLock, defMtxUnlock };
|
||||
void* from;
|
||||
|
||||
if (src != NULL) {
|
||||
from = src ->chunks[MutexPlugin];
|
||||
}
|
||||
else {
|
||||
from = &MutexChunk;
|
||||
}
|
||||
|
||||
ctx ->chunks[MutexPlugin] = _cmsSubAllocDup(ctx ->MemPool, from, sizeof(_cmsMutexPluginChunkType));
|
||||
}
|
||||
|
||||
// Register new ways to transform
|
||||
cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Data)
|
||||
{
|
||||
cmsPluginMutex* Plugin = (cmsPluginMutex*) Data;
|
||||
_cmsMutexPluginChunkType* ctx = ( _cmsMutexPluginChunkType*) _cmsContextGetClientChunk(ContextID, MutexPlugin);
|
||||
|
||||
if (Data == NULL) {
|
||||
|
||||
// No lock routines
|
||||
ctx->CreateMutexPtr = NULL;
|
||||
ctx->DestroyMutexPtr = NULL;
|
||||
ctx->LockMutexPtr = NULL;
|
||||
ctx ->UnlockMutexPtr = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Factory callback is required
|
||||
if (Plugin ->CreateMutexPtr == NULL || Plugin ->DestroyMutexPtr == NULL ||
|
||||
Plugin ->LockMutexPtr == NULL || Plugin ->UnlockMutexPtr == NULL) return FALSE;
|
||||
|
||||
|
||||
ctx->CreateMutexPtr = Plugin->CreateMutexPtr;
|
||||
ctx->DestroyMutexPtr = Plugin ->DestroyMutexPtr;
|
||||
ctx ->LockMutexPtr = Plugin ->LockMutexPtr;
|
||||
ctx ->UnlockMutexPtr = Plugin ->UnlockMutexPtr;
|
||||
|
||||
// All is ok
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Generic Mutex fns
|
||||
void* CMSEXPORT _cmsCreateMutex(cmsContext ContextID)
|
||||
{
|
||||
_cmsMutexPluginChunkType* ptr = (_cmsMutexPluginChunkType*) _cmsContextGetClientChunk(ContextID, MutexPlugin);
|
||||
|
||||
if (ptr ->CreateMutexPtr == NULL) return NULL;
|
||||
|
||||
return ptr ->CreateMutexPtr(ContextID);
|
||||
}
|
||||
|
||||
void CMSEXPORT _cmsDestroyMutex(cmsContext ContextID, void* mtx)
|
||||
{
|
||||
_cmsMutexPluginChunkType* ptr = (_cmsMutexPluginChunkType*) _cmsContextGetClientChunk(ContextID, MutexPlugin);
|
||||
|
||||
if (ptr ->DestroyMutexPtr != NULL) {
|
||||
|
||||
ptr ->DestroyMutexPtr(ContextID, mtx);
|
||||
}
|
||||
}
|
||||
|
||||
cmsBool CMSEXPORT _cmsLockMutex(cmsContext ContextID, void* mtx)
|
||||
{
|
||||
_cmsMutexPluginChunkType* ptr = (_cmsMutexPluginChunkType*) _cmsContextGetClientChunk(ContextID, MutexPlugin);
|
||||
|
||||
if (ptr ->LockMutexPtr == NULL) return TRUE;
|
||||
|
||||
return ptr ->LockMutexPtr(ContextID, mtx);
|
||||
}
|
||||
|
||||
void CMSEXPORT _cmsUnlockMutex(cmsContext ContextID, void* mtx)
|
||||
{
|
||||
_cmsMutexPluginChunkType* ptr = (_cmsMutexPluginChunkType*) _cmsContextGetClientChunk(ContextID, MutexPlugin);
|
||||
|
||||
if (ptr ->UnlockMutexPtr != NULL) {
|
||||
|
||||
ptr ->UnlockMutexPtr(ContextID, mtx);
|
||||
}
|
||||
}
|
||||
|
||||
431
thirdparty/liblcms2/src/cmsgamma.c
vendored
431
thirdparty/liblcms2/src/cmsgamma.c
vendored
@@ -1,42 +1,42 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2013 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
|
||||
// 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
|
||||
// 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
|
||||
// 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"
|
||||
|
||||
// Tone curves are powerful constructs that can contain curves specified in diverse ways.
|
||||
// Tone curves are powerful constructs that can contain curves specified in diverse ways.
|
||||
// The curve is stored in segments, where each segment can be sampled or specified by parameters.
|
||||
// a 16.bit simplification of the *whole* curve is kept for optimization purposes. For float operation,
|
||||
// each segment is evaluated separately. Plug-ins may be used to define new parametric schemes,
|
||||
// each plug-in may define up to MAX_TYPES_IN_LCMS_PLUGIN functions types. For defining a function,
|
||||
// a 16.bit simplification of the *whole* curve is kept for optimization purposes. For float operation,
|
||||
// each segment is evaluated separately. Plug-ins may be used to define new parametric schemes,
|
||||
// each plug-in may define up to MAX_TYPES_IN_LCMS_PLUGIN functions types. For defining a function,
|
||||
// the plug-in should provide the type id, how many parameters each type has, and a pointer to
|
||||
// a procedure that evaluates the function. In the case of reverse evaluation, the evaluator will
|
||||
// be called with the type id as a negative value, and a sampled version of the reversed curve
|
||||
// a procedure that evaluates the function. In the case of reverse evaluation, the evaluator will
|
||||
// be called with the type id as a negative value, and a sampled version of the reversed curve
|
||||
// will be built.
|
||||
|
||||
// ----------------------------------------------------------------- Implementation
|
||||
// Maxim number of nodes
|
||||
// Maxim number of nodes
|
||||
#define MAX_NODES_IN_CURVE 4097
|
||||
#define MINUS_INF (-1E22F)
|
||||
#define PLUS_INF (+1E22F)
|
||||
@@ -53,12 +53,11 @@ typedef struct _cmsParametricCurvesCollection_st {
|
||||
|
||||
} _cmsParametricCurvesCollection;
|
||||
|
||||
|
||||
// This is the default (built-in) evaluator
|
||||
// This is the default (built-in) evaluator
|
||||
static cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Number Params[], cmsFloat64Number R);
|
||||
|
||||
// The built-in list
|
||||
static _cmsParametricCurvesCollection DefaultCurves = {
|
||||
static _cmsParametricCurvesCollection DefaultCurves = {
|
||||
9, // # of curve types
|
||||
{ 1, 2, 3, 4, 5, 6, 7, 8, 108 }, // Parametric curve ID
|
||||
{ 1, 3, 4, 5, 7, 4, 5, 5, 1 }, // Parameters by type
|
||||
@@ -66,22 +65,77 @@ static _cmsParametricCurvesCollection DefaultCurves = {
|
||||
NULL // Next in chain
|
||||
};
|
||||
|
||||
// Duplicates the zone of memory used by the plug-in in the new context
|
||||
static
|
||||
void DupPluginCurvesList(struct _cmsContext_struct* ctx,
|
||||
const struct _cmsContext_struct* src)
|
||||
{
|
||||
_cmsCurvesPluginChunkType newHead = { NULL };
|
||||
_cmsParametricCurvesCollection* entry;
|
||||
_cmsParametricCurvesCollection* Anterior = NULL;
|
||||
_cmsCurvesPluginChunkType* head = (_cmsCurvesPluginChunkType*) src->chunks[CurvesPlugin];
|
||||
|
||||
_cmsAssert(head != NULL);
|
||||
|
||||
// Walk the list copying all nodes
|
||||
for (entry = head->ParametricCurves;
|
||||
entry != NULL;
|
||||
entry = entry ->Next) {
|
||||
|
||||
_cmsParametricCurvesCollection *newEntry = ( _cmsParametricCurvesCollection *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(_cmsParametricCurvesCollection));
|
||||
|
||||
if (newEntry == NULL)
|
||||
return;
|
||||
|
||||
// We want to keep the linked list order, so this is a little bit tricky
|
||||
newEntry -> Next = NULL;
|
||||
if (Anterior)
|
||||
Anterior -> Next = newEntry;
|
||||
|
||||
Anterior = newEntry;
|
||||
|
||||
if (newHead.ParametricCurves == NULL)
|
||||
newHead.ParametricCurves = newEntry;
|
||||
}
|
||||
|
||||
ctx ->chunks[CurvesPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsCurvesPluginChunkType));
|
||||
}
|
||||
|
||||
// The allocator have to follow the chain
|
||||
void _cmsAllocCurvesPluginChunk(struct _cmsContext_struct* ctx,
|
||||
const struct _cmsContext_struct* src)
|
||||
{
|
||||
_cmsAssert(ctx != NULL);
|
||||
|
||||
if (src != NULL) {
|
||||
|
||||
// Copy all linked list
|
||||
DupPluginCurvesList(ctx, src);
|
||||
}
|
||||
else {
|
||||
static _cmsCurvesPluginChunkType CurvesPluginChunk = { NULL };
|
||||
ctx ->chunks[CurvesPlugin] = _cmsSubAllocDup(ctx ->MemPool, &CurvesPluginChunk, sizeof(_cmsCurvesPluginChunkType));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// The linked list head
|
||||
static _cmsParametricCurvesCollection* ParametricCurves = &DefaultCurves;
|
||||
_cmsCurvesPluginChunkType _cmsCurvesPluginChunk = { NULL };
|
||||
|
||||
// As a way to install new parametric curves
|
||||
cmsBool _cmsRegisterParametricCurvesPlugin(cmsPluginBase* Data)
|
||||
cmsBool _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase* Data)
|
||||
{
|
||||
_cmsCurvesPluginChunkType* ctx = ( _cmsCurvesPluginChunkType*) _cmsContextGetClientChunk(ContextID, CurvesPlugin);
|
||||
cmsPluginParametricCurves* Plugin = (cmsPluginParametricCurves*) Data;
|
||||
_cmsParametricCurvesCollection* fl;
|
||||
|
||||
|
||||
if (Data == NULL) {
|
||||
|
||||
ParametricCurves = &DefaultCurves;
|
||||
|
||||
ctx -> ParametricCurves = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
fl = (_cmsParametricCurvesCollection*) _cmsPluginMalloc(sizeof(_cmsParametricCurvesCollection));
|
||||
fl = (_cmsParametricCurvesCollection*) _cmsPluginMalloc(ContextID, sizeof(_cmsParametricCurvesCollection));
|
||||
if (fl == NULL) return FALSE;
|
||||
|
||||
// Copy the parameters
|
||||
@@ -97,8 +151,8 @@ cmsBool _cmsRegisterParametricCurvesPlugin(cmsPluginBase* Data)
|
||||
memmove(fl->ParameterCount, Plugin ->ParameterCount, fl->nFunctions * sizeof(cmsUInt32Number));
|
||||
|
||||
// Keep linked list
|
||||
fl ->Next = ParametricCurves;
|
||||
ParametricCurves = fl;
|
||||
fl ->Next = ctx->ParametricCurves;
|
||||
ctx->ParametricCurves = fl;
|
||||
|
||||
// All is ok
|
||||
return TRUE;
|
||||
@@ -120,17 +174,29 @@ int IsInSet(int Type, _cmsParametricCurvesCollection* c)
|
||||
|
||||
// Search for the collection which contains a specific type
|
||||
static
|
||||
_cmsParametricCurvesCollection *GetParametricCurveByType(int Type, int* index)
|
||||
_cmsParametricCurvesCollection *GetParametricCurveByType(cmsContext ContextID, int Type, int* index)
|
||||
{
|
||||
_cmsParametricCurvesCollection* c;
|
||||
int Position;
|
||||
_cmsCurvesPluginChunkType* ctx = ( _cmsCurvesPluginChunkType*) _cmsContextGetClientChunk(ContextID, CurvesPlugin);
|
||||
|
||||
for (c = ParametricCurves; c != NULL; c = c ->Next) {
|
||||
for (c = ctx->ParametricCurves; c != NULL; c = c ->Next) {
|
||||
|
||||
Position = IsInSet(Type, c);
|
||||
|
||||
if (Position != -1) {
|
||||
if (index != NULL)
|
||||
if (index != NULL)
|
||||
*index = Position;
|
||||
return c;
|
||||
}
|
||||
}
|
||||
// If none found, revert for defaults
|
||||
for (c = &DefaultCurves; c != NULL; c = c ->Next) {
|
||||
|
||||
Position = IsInSet(Type, c);
|
||||
|
||||
if (Position != -1) {
|
||||
if (index != NULL)
|
||||
*index = Position;
|
||||
return c;
|
||||
}
|
||||
@@ -139,12 +205,12 @@ _cmsParametricCurvesCollection *GetParametricCurveByType(int Type, int* index)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Low level allocate, which takes care of memory details. nEntries may be zero, and in this case
|
||||
// Low level allocate, which takes care of memory details. nEntries may be zero, and in this case
|
||||
// no optimation curve is computed. nSegments may also be zero in the inverse case, where only the
|
||||
// optimization curve is given. Both features simultaneously is an error
|
||||
static
|
||||
cmsToneCurve* AllocateToneCurveStruct(cmsContext ContextID, cmsInt32Number nEntries,
|
||||
cmsInt32Number nSegments, const cmsCurveSegment* Segments,
|
||||
cmsToneCurve* AllocateToneCurveStruct(cmsContext ContextID, cmsInt32Number nEntries,
|
||||
cmsInt32Number nSegments, const cmsCurveSegment* Segments,
|
||||
const cmsUInt16Number* Values)
|
||||
{
|
||||
cmsToneCurve* p;
|
||||
@@ -179,7 +245,7 @@ cmsToneCurve* AllocateToneCurveStruct(cmsContext ContextID, cmsInt32Number nEntr
|
||||
}
|
||||
|
||||
p -> nSegments = nSegments;
|
||||
|
||||
|
||||
// This 16-bit table contains a limited precision representation of the whole curve and is kept for
|
||||
// increasing xput on certain operations.
|
||||
if (nEntries <= 0) {
|
||||
@@ -189,13 +255,13 @@ cmsToneCurve* AllocateToneCurveStruct(cmsContext ContextID, cmsInt32Number nEntr
|
||||
p ->Table16 = (cmsUInt16Number*) _cmsCalloc(ContextID, nEntries, sizeof(cmsUInt16Number));
|
||||
if (p ->Table16 == NULL) goto Error;
|
||||
}
|
||||
|
||||
|
||||
p -> nEntries = nEntries;
|
||||
|
||||
|
||||
// Initialize members if requested
|
||||
if (Values != NULL && (nEntries > 0)) {
|
||||
|
||||
for (i=0; i < nEntries; i++)
|
||||
for (i=0; i < nEntries; i++)
|
||||
p ->Table16[i] = Values[i];
|
||||
}
|
||||
|
||||
@@ -222,14 +288,15 @@ cmsToneCurve* AllocateToneCurveStruct(cmsContext ContextID, cmsInt32Number nEntr
|
||||
p ->Segments[i].SampledPoints = NULL;
|
||||
|
||||
|
||||
c = GetParametricCurveByType(Segments[i].Type, NULL);
|
||||
c = GetParametricCurveByType(ContextID, Segments[i].Type, NULL);
|
||||
if (c != NULL)
|
||||
p ->Evals[i] = c ->Evaluator;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
p ->InterpParams = _cmsComputeInterpParams(ContextID, p ->nEntries, 1, 1, p->Table16, CMS_LERP_FLAGS_16BITS);
|
||||
return p;
|
||||
if (p->InterpParams != NULL)
|
||||
return p;
|
||||
|
||||
Error:
|
||||
if (p -> Segments) _cmsFree(ContextID, p ->Segments);
|
||||
@@ -248,18 +315,28 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
|
||||
|
||||
switch (Type) {
|
||||
|
||||
// X = Y ^ Gamma
|
||||
// X = Y ^ Gamma
|
||||
case 1:
|
||||
if (R < 0)
|
||||
Val = 0;
|
||||
if (R < 0) {
|
||||
|
||||
if (fabs(Params[0] - 1.0) < MATRIX_DET_TOLERANCE)
|
||||
Val = R;
|
||||
else
|
||||
Val = 0;
|
||||
}
|
||||
else
|
||||
Val = pow(R, Params[0]);
|
||||
break;
|
||||
|
||||
// Type 1 Reversed: X = Y ^1/gamma
|
||||
case -1:
|
||||
if (R < 0)
|
||||
Val = 0;
|
||||
if (R < 0) {
|
||||
|
||||
if (fabs(Params[0] - 1.0) < MATRIX_DET_TOLERANCE)
|
||||
Val = R;
|
||||
else
|
||||
Val = 0;
|
||||
}
|
||||
else
|
||||
Val = pow(R, 1/Params[0]);
|
||||
break;
|
||||
@@ -285,14 +362,14 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
|
||||
|
||||
// Type 2 Reversed
|
||||
// X = (Y ^1/g - b) / a
|
||||
case -2:
|
||||
case -2:
|
||||
if (R < 0)
|
||||
Val = 0;
|
||||
else
|
||||
Val = (pow(R, 1.0/Params[0]) - Params[2]) / Params[1];
|
||||
|
||||
if (Val < 0)
|
||||
Val = 0;
|
||||
Val = 0;
|
||||
break;
|
||||
|
||||
|
||||
@@ -306,7 +383,7 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
|
||||
|
||||
if (R >= disc) {
|
||||
|
||||
e = Params[1]*R + Params[2];
|
||||
e = Params[1]*R + Params[2];
|
||||
|
||||
if (e > 0)
|
||||
Val = pow(e, Params[0]) + Params[3];
|
||||
@@ -320,15 +397,15 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
|
||||
|
||||
// Type 3 reversed
|
||||
// X=((Y-c)^1/g - b)/a | (Y>=c)
|
||||
// X=-b/a | (Y<c)
|
||||
// X=-b/a | (Y<c)
|
||||
case -3:
|
||||
if (R >= Params[3]) {
|
||||
|
||||
|
||||
e = R - Params[3];
|
||||
|
||||
if (e > 0)
|
||||
Val = (pow(e, 1/Params[0]) - Params[2]) / Params[1];
|
||||
else
|
||||
else
|
||||
Val = 0;
|
||||
}
|
||||
else {
|
||||
@@ -384,8 +461,8 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
|
||||
if (e > 0)
|
||||
Val = pow(e, Params[0]) + Params[5];
|
||||
else
|
||||
Val = 0;
|
||||
}
|
||||
Val = Params[5];
|
||||
}
|
||||
else
|
||||
Val = R*Params[3] + Params[6];
|
||||
break;
|
||||
@@ -400,7 +477,7 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
|
||||
if (R >= disc) {
|
||||
|
||||
e = R - Params[5];
|
||||
if (e < 0)
|
||||
if (e < 0)
|
||||
Val = 0;
|
||||
else
|
||||
Val = (pow(e, 1.0/Params[0]) - Params[2]) / Params[1];
|
||||
@@ -413,46 +490,46 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
|
||||
|
||||
// Types 6,7,8 comes from segmented curves as described in ICCSpecRevision_02_11_06_Float.pdf
|
||||
// Type 6 is basically identical to type 5 without d
|
||||
|
||||
|
||||
// Y = (a * X + b) ^ Gamma + c
|
||||
case 6:
|
||||
case 6:
|
||||
e = Params[1]*R + Params[2];
|
||||
|
||||
if (e < 0)
|
||||
Val = 0;
|
||||
else
|
||||
if (e < 0)
|
||||
Val = Params[3];
|
||||
else
|
||||
Val = pow(e, Params[0]) + Params[3];
|
||||
break;
|
||||
|
||||
// ((Y - c) ^1/Gamma - b) / a
|
||||
// ((Y - c) ^1/Gamma - b) / a
|
||||
case -6:
|
||||
e = R - Params[3];
|
||||
if (e < 0)
|
||||
Val = 0;
|
||||
else
|
||||
else
|
||||
Val = (pow(e, 1.0/Params[0]) - Params[2]) / Params[1];
|
||||
break;
|
||||
|
||||
|
||||
// Y = a * log (b * X^Gamma + c) + d
|
||||
case 7:
|
||||
case 7:
|
||||
|
||||
e = Params[2] * pow(R, Params[0]) + Params[3];
|
||||
if (e <= 0)
|
||||
Val = 0;
|
||||
Val = Params[4];
|
||||
else
|
||||
Val = Params[1]*log10(e) + Params[4];
|
||||
break;
|
||||
|
||||
// (Y - d) / a = log(b * X ^Gamma + c)
|
||||
// pow(10, (Y-d) / a) = b * X ^Gamma + c
|
||||
// pow((pow(10, (Y-d) / a) - c) / b, 1/g) = X
|
||||
// pow((pow(10, (Y-d) / a) - c) / b, 1/g) = X
|
||||
case -7:
|
||||
Val = pow((pow(10.0, (R-Params[4]) / Params[1]) - Params[3]) / Params[2], 1.0 / Params[0]);
|
||||
break;
|
||||
|
||||
|
||||
//Y = a * b^(c*X+d) + e
|
||||
//Y = a * b^(c*X+d) + e
|
||||
case 8:
|
||||
Val = (Params[0] * pow(Params[1], Params[2] * R + Params[3]) + Params[4]);
|
||||
break;
|
||||
@@ -461,14 +538,14 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
|
||||
// Y = (log((y-e) / a) / log(b) - d ) / c
|
||||
// a=0, b=1, c=2, d=3, e=4,
|
||||
case -8:
|
||||
|
||||
|
||||
disc = R - Params[4];
|
||||
if (disc < 0) Val = 0;
|
||||
else
|
||||
Val = (log(disc / Params[0]) / log(Params[1]) - Params[3]) / Params[2];
|
||||
else
|
||||
Val = (log(disc / Params[0]) / log(Params[1]) - Params[3]) / Params[2];
|
||||
break;
|
||||
|
||||
// S-Shaped: (1 - (1-x)^1/g)^1/g
|
||||
// S-Shaped: (1 - (1-x)^1/g)^1/g
|
||||
case 108:
|
||||
Val = pow(1.0 - pow(1 - R, 1/Params[0]), 1/Params[0]);
|
||||
break;
|
||||
@@ -491,7 +568,7 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
|
||||
}
|
||||
|
||||
// Evaluate a segmented funtion for a single value. Return -1 if no valid segment found .
|
||||
// If fn type is 0, perform an interpolation on the table
|
||||
// If fn type is 0, perform an interpolation on the table
|
||||
static
|
||||
cmsFloat64Number EvalSegmentedFn(const cmsToneCurve *g, cmsFloat64Number R)
|
||||
{
|
||||
@@ -505,14 +582,14 @@ cmsFloat64Number EvalSegmentedFn(const cmsToneCurve *g, cmsFloat64Number R)
|
||||
// Type == 0 means segment is sampled
|
||||
if (g ->Segments[i].Type == 0) {
|
||||
|
||||
cmsFloat32Number R1 = (cmsFloat32Number) (R - g ->Segments[i].x0);
|
||||
cmsFloat32Number R1 = (cmsFloat32Number) (R - g ->Segments[i].x0) / (g ->Segments[i].x1 - g ->Segments[i].x0);
|
||||
cmsFloat32Number Out;
|
||||
|
||||
// Setup the table (TODO: clean that)
|
||||
g ->SegInterp[i]-> Table = g ->Segments[i].SampledPoints;
|
||||
g ->SegInterp[i]-> Table = g ->Segments[i].SampledPoints;
|
||||
|
||||
g ->SegInterp[i] -> Interpolation.LerpFloat(&R1, &Out, g ->SegInterp[i]);
|
||||
|
||||
|
||||
return Out;
|
||||
}
|
||||
else
|
||||
@@ -523,6 +600,19 @@ cmsFloat64Number EvalSegmentedFn(const cmsToneCurve *g, cmsFloat64Number R)
|
||||
return MINUS_INF;
|
||||
}
|
||||
|
||||
// Access to estimated low-res table
|
||||
cmsUInt32Number CMSEXPORT cmsGetToneCurveEstimatedTableEntries(const cmsToneCurve* t)
|
||||
{
|
||||
_cmsAssert(t != NULL);
|
||||
return t ->nEntries;
|
||||
}
|
||||
|
||||
const cmsUInt16Number* CMSEXPORT cmsGetToneCurveEstimatedTable(const cmsToneCurve* t)
|
||||
{
|
||||
_cmsAssert(t != NULL);
|
||||
return t ->Table16;
|
||||
}
|
||||
|
||||
|
||||
// Create an empty gamma curve, by using tables. This specifies only the limited-precision part, and leaves the
|
||||
// floating point description empty.
|
||||
@@ -540,17 +630,17 @@ int EntriesByGamma(cmsFloat64Number Gamma)
|
||||
|
||||
|
||||
// Create a segmented gamma, fill the table
|
||||
cmsToneCurve* CMSEXPORT cmsBuildSegmentedToneCurve(cmsContext ContextID,
|
||||
cmsToneCurve* CMSEXPORT cmsBuildSegmentedToneCurve(cmsContext ContextID,
|
||||
cmsInt32Number nSegments, const cmsCurveSegment Segments[])
|
||||
{
|
||||
int i;
|
||||
cmsFloat64Number R, Val;
|
||||
cmsToneCurve* g;
|
||||
int nGridPoints = 4096;
|
||||
|
||||
|
||||
_cmsAssert(Segments != NULL);
|
||||
|
||||
// Optimizatin for identity curves.
|
||||
// Optimizatin for identity curves.
|
||||
if (nSegments == 1 && Segments[0].Type == 1) {
|
||||
|
||||
nGridPoints = EntriesByGamma(Segments[0].Params[0]);
|
||||
@@ -577,28 +667,41 @@ cmsToneCurve* CMSEXPORT cmsBuildSegmentedToneCurve(cmsContext ContextID,
|
||||
// Use a segmented curve to store the floating point table
|
||||
cmsToneCurve* CMSEXPORT cmsBuildTabulatedToneCurveFloat(cmsContext ContextID, cmsUInt32Number nEntries, const cmsFloat32Number values[])
|
||||
{
|
||||
cmsCurveSegment Seg[2];
|
||||
cmsCurveSegment Seg[3];
|
||||
|
||||
// Initialize segmented curve part up to 0
|
||||
Seg[0].x0 = -1;
|
||||
// A segmented tone curve should have function segments in the first and last positions
|
||||
// Initialize segmented curve part up to 0 to constant value = samples[0]
|
||||
Seg[0].x0 = MINUS_INF;
|
||||
Seg[0].x1 = 0;
|
||||
Seg[0].Type = 6;
|
||||
|
||||
Seg[0].Params[0] = 1;
|
||||
Seg[0].Params[1] = 0;
|
||||
Seg[0].Params[2] = 0;
|
||||
Seg[0].Params[3] = 0;
|
||||
Seg[0].Params[3] = values[0];
|
||||
Seg[0].Params[4] = 0;
|
||||
|
||||
// From zero to any
|
||||
// From zero to 1
|
||||
Seg[1].x0 = 0;
|
||||
Seg[1].x1 = 1.0;
|
||||
Seg[1].x1 = 1.0;
|
||||
Seg[1].Type = 0;
|
||||
|
||||
Seg[1].nGridPoints = nEntries;
|
||||
Seg[1].SampledPoints = (cmsFloat32Number*) values;
|
||||
|
||||
return cmsBuildSegmentedToneCurve(ContextID, 2, Seg);
|
||||
// Final segment is constant = lastsample
|
||||
Seg[2].x0 = 1.0;
|
||||
Seg[2].x1 = PLUS_INF;
|
||||
Seg[2].Type = 6;
|
||||
|
||||
Seg[2].Params[0] = 1;
|
||||
Seg[2].Params[1] = 0;
|
||||
Seg[2].Params[2] = 0;
|
||||
Seg[2].Params[3] = values[nEntries-1];
|
||||
Seg[2].Params[4] = 0;
|
||||
|
||||
|
||||
return cmsBuildSegmentedToneCurve(ContextID, 3, Seg);
|
||||
}
|
||||
|
||||
// Parametric curves
|
||||
@@ -611,12 +714,12 @@ cmsToneCurve* CMSEXPORT cmsBuildParametricToneCurve(cmsContext ContextID, cmsInt
|
||||
cmsCurveSegment Seg0;
|
||||
int Pos = 0;
|
||||
cmsUInt32Number size;
|
||||
_cmsParametricCurvesCollection* c = GetParametricCurveByType(Type, &Pos);
|
||||
_cmsParametricCurvesCollection* c = GetParametricCurveByType(ContextID, Type, &Pos);
|
||||
|
||||
_cmsAssert(Params != NULL);
|
||||
|
||||
if (c == NULL) {
|
||||
cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Invalid parametric curve type %d", Type);
|
||||
cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Invalid parametric curve type %d", Type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -645,27 +748,27 @@ cmsToneCurve* CMSEXPORT cmsBuildGamma(cmsContext ContextID, cmsFloat64Number Gam
|
||||
void CMSEXPORT cmsFreeToneCurve(cmsToneCurve* Curve)
|
||||
{
|
||||
cmsContext ContextID;
|
||||
|
||||
|
||||
if (Curve == NULL) return;
|
||||
|
||||
ContextID = Curve ->InterpParams->ContextID;
|
||||
|
||||
_cmsFreeInterpParams(Curve ->InterpParams);
|
||||
|
||||
|
||||
if (Curve -> Table16)
|
||||
_cmsFree(ContextID, Curve ->Table16);
|
||||
|
||||
if (Curve ->Segments) {
|
||||
|
||||
cmsUInt32Number i;
|
||||
|
||||
|
||||
for (i=0; i < Curve ->nSegments; i++) {
|
||||
|
||||
if (Curve ->Segments[i].SampledPoints) {
|
||||
_cmsFree(ContextID, Curve ->Segments[i].SampledPoints);
|
||||
}
|
||||
|
||||
if (Curve ->SegInterp[i] != 0)
|
||||
if (Curve ->SegInterp[i] != 0)
|
||||
_cmsFreeInterpParams(Curve->SegInterp[i]);
|
||||
}
|
||||
|
||||
@@ -695,18 +798,18 @@ void CMSEXPORT cmsFreeToneCurveTriple(cmsToneCurve* Curve[3])
|
||||
|
||||
// Duplicate a gamma table
|
||||
cmsToneCurve* CMSEXPORT cmsDupToneCurve(const cmsToneCurve* In)
|
||||
{
|
||||
{
|
||||
if (In == NULL) return NULL;
|
||||
|
||||
return AllocateToneCurveStruct(In ->InterpParams ->ContextID, In ->nEntries, In ->nSegments, In ->Segments, In ->Table16);
|
||||
}
|
||||
|
||||
// Joins two curves for X and Y. Curves should be monotonic.
|
||||
// We want to get
|
||||
// We want to get
|
||||
//
|
||||
// y = Y^-1(X(t))
|
||||
// y = Y^-1(X(t))
|
||||
//
|
||||
cmsToneCurve* CMSEXPORT cmsJoinToneCurve(cmsContext ContextID,
|
||||
cmsToneCurve* CMSEXPORT cmsJoinToneCurve(cmsContext ContextID,
|
||||
const cmsToneCurve* X,
|
||||
const cmsToneCurve* Y, cmsUInt32Number nResultingPoints)
|
||||
{
|
||||
@@ -725,7 +828,7 @@ cmsToneCurve* CMSEXPORT cmsJoinToneCurve(cmsContext ContextID,
|
||||
|
||||
Res = (cmsFloat32Number*) _cmsCalloc(ContextID, nResultingPoints, sizeof(cmsFloat32Number));
|
||||
if (Res == NULL) goto Error;
|
||||
|
||||
|
||||
//Iterate
|
||||
for (i=0; i < nResultingPoints; i++) {
|
||||
|
||||
@@ -736,7 +839,7 @@ cmsToneCurve* CMSEXPORT cmsJoinToneCurve(cmsContext ContextID,
|
||||
|
||||
// Allocate space for output
|
||||
out = cmsBuildTabulatedToneCurveFloat(ContextID, nResultingPoints, Res);
|
||||
|
||||
|
||||
Error:
|
||||
|
||||
if (Res != NULL) _cmsFree(ContextID, Res);
|
||||
@@ -747,25 +850,25 @@ Error:
|
||||
|
||||
|
||||
|
||||
// Get the surrounding nodes. This is tricky on non-monotonic tables
|
||||
// Get the surrounding nodes. This is tricky on non-monotonic tables
|
||||
static
|
||||
int GetInterval(cmsFloat64Number In, const cmsUInt16Number LutTable[], const struct _cms_interp_struc* p)
|
||||
{
|
||||
{
|
||||
int i;
|
||||
int y0, y1;
|
||||
|
||||
|
||||
// A 1 point table is not allowed
|
||||
if (p -> Domain[0] < 1) return -1;
|
||||
|
||||
// Let's see if ascending or descending.
|
||||
// Let's see if ascending or descending.
|
||||
if (LutTable[0] < LutTable[p ->Domain[0]]) {
|
||||
|
||||
// Table is overall ascending
|
||||
for (i=p->Domain[0]-1; i >=0; --i) {
|
||||
|
||||
y0 = LutTable[i];
|
||||
y0 = LutTable[i];
|
||||
y1 = LutTable[i+1];
|
||||
|
||||
|
||||
if (y0 <= y1) { // Increasing
|
||||
if (In >= y0 && In <= y1) return i;
|
||||
}
|
||||
@@ -779,7 +882,7 @@ int GetInterval(cmsFloat64Number In, const cmsUInt16Number LutTable[], const str
|
||||
// Table is overall descending
|
||||
for (i=0; i < (int) p -> Domain[0]; i++) {
|
||||
|
||||
y0 = LutTable[i];
|
||||
y0 = LutTable[i];
|
||||
y1 = LutTable[i+1];
|
||||
|
||||
if (y0 <= y1) { // Increasing
|
||||
@@ -802,18 +905,21 @@ cmsToneCurve* CMSEXPORT cmsReverseToneCurveEx(cmsInt32Number nResultSamples, con
|
||||
cmsFloat64Number a = 0, b = 0, y, x1, y1, x2, y2;
|
||||
int i, j;
|
||||
int Ascending;
|
||||
|
||||
|
||||
_cmsAssert(InCurve != NULL);
|
||||
|
||||
// Try to reverse it analytically whatever possible
|
||||
if (InCurve ->nSegments == 1 && InCurve ->Segments[0].Type > 0 && InCurve -> Segments[0].Type <= 5) {
|
||||
|
||||
if (InCurve ->nSegments == 1 && InCurve ->Segments[0].Type > 0 &&
|
||||
/* InCurve -> Segments[0].Type <= 5 */
|
||||
GetParametricCurveByType(InCurve ->InterpParams->ContextID, InCurve ->Segments[0].Type, NULL) != NULL) {
|
||||
|
||||
return cmsBuildParametricToneCurve(InCurve ->InterpParams->ContextID,
|
||||
-(InCurve -> Segments[0].Type),
|
||||
return cmsBuildParametricToneCurve(InCurve ->InterpParams->ContextID,
|
||||
-(InCurve -> Segments[0].Type),
|
||||
InCurve -> Segments[0].Params);
|
||||
}
|
||||
|
||||
// Nope, reverse the table.
|
||||
// Nope, reverse the table.
|
||||
out = cmsBuildTabulatedToneCurve16(InCurve ->InterpParams->ContextID, nResultSamples, NULL);
|
||||
if (out == NULL)
|
||||
return NULL;
|
||||
@@ -826,18 +932,18 @@ cmsToneCurve* CMSEXPORT cmsReverseToneCurveEx(cmsInt32Number nResultSamples, con
|
||||
|
||||
y = (cmsFloat64Number) i * 65535.0 / (nResultSamples - 1);
|
||||
|
||||
// Find interval in which y is within.
|
||||
// Find interval in which y is within.
|
||||
j = GetInterval(y, InCurve->Table16, InCurve->InterpParams);
|
||||
if (j >= 0) {
|
||||
|
||||
|
||||
// Get limits of interval
|
||||
x1 = InCurve ->Table16[j];
|
||||
x1 = InCurve ->Table16[j];
|
||||
x2 = InCurve ->Table16[j+1];
|
||||
|
||||
y1 = (cmsFloat64Number) (j * 65535.0) / (InCurve ->nEntries - 1);
|
||||
y2 = (cmsFloat64Number) ((j+1) * 65535.0 ) / (InCurve ->nEntries - 1);
|
||||
|
||||
|
||||
// If collapsed, then use any
|
||||
if (x1 == x2) {
|
||||
|
||||
@@ -846,12 +952,12 @@ cmsToneCurve* CMSEXPORT cmsReverseToneCurveEx(cmsInt32Number nResultSamples, con
|
||||
|
||||
} else {
|
||||
|
||||
// Interpolate
|
||||
// Interpolate
|
||||
a = (y2 - y1) / (x2 - x1);
|
||||
b = y2 - a * x2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
out ->Table16[i] = _cmsQuickSaturateWord(a* y + b);
|
||||
}
|
||||
|
||||
@@ -887,7 +993,7 @@ cmsBool smooth2(cmsContext ContextID, cmsFloat32Number w[], cmsFloat32Number y[]
|
||||
c = (cmsFloat32Number*) _cmsCalloc(ContextID, MAX_NODES_IN_CURVE, sizeof(cmsFloat32Number));
|
||||
d = (cmsFloat32Number*) _cmsCalloc(ContextID, MAX_NODES_IN_CURVE, sizeof(cmsFloat32Number));
|
||||
e = (cmsFloat32Number*) _cmsCalloc(ContextID, MAX_NODES_IN_CURVE, sizeof(cmsFloat32Number));
|
||||
|
||||
|
||||
if (c != NULL && d != NULL && e != NULL) {
|
||||
|
||||
|
||||
@@ -899,7 +1005,7 @@ cmsBool smooth2(cmsContext ContextID, cmsFloat32Number w[], cmsFloat32Number y[]
|
||||
c[2] = (-4 * lambda - d[1] * c[1] * e[1]) / d[2];
|
||||
e[2] = lambda / d[2];
|
||||
z[2] = w[2] * y[2] - c[1] * z[1];
|
||||
|
||||
|
||||
for (i = 3; i < m - 1; i++) {
|
||||
i1 = i - 1; i2 = i - 2;
|
||||
d[i]= w[i] + 6 * lambda - c[i1] * c[i1] * d[i1] - e[i2] * e[i2] * d[i2];
|
||||
@@ -907,18 +1013,18 @@ cmsBool smooth2(cmsContext ContextID, cmsFloat32Number w[], cmsFloat32Number y[]
|
||||
e[i] = lambda / d[i];
|
||||
z[i] = w[i] * y[i] - c[i1] * z[i1] - e[i2] * z[i2];
|
||||
}
|
||||
|
||||
|
||||
i1 = m - 2; i2 = m - 3;
|
||||
|
||||
|
||||
d[m - 1] = w[m - 1] + 5 * lambda -c[i1] * c[i1] * d[i1] - e[i2] * e[i2] * d[i2];
|
||||
c[m - 1] = (-2 * lambda - d[i1] * c[i1] * e[i1]) / d[m - 1];
|
||||
z[m - 1] = w[m - 1] * y[m - 1] - c[i1] * z[i1] - e[i2] * z[i2];
|
||||
i1 = m - 1; i2 = m - 2;
|
||||
|
||||
|
||||
d[m] = w[m] + lambda - c[i1] * c[i1] * d[i1] - e[i2] * e[i2] * d[i2];
|
||||
z[m] = (w[m] * y[m] - c[i1] * z[i1] - e[i2] * z[i2]) / d[m];
|
||||
z[m - 1] = z[m - 1] / d[m - 1] - c[m - 1] * z[m];
|
||||
|
||||
|
||||
for (i = m - 2; 1<= i; i--)
|
||||
z[i] = z[i] / d[i] - c[i] * z[i + 1] - e[i] * z[i + 2];
|
||||
|
||||
@@ -933,7 +1039,7 @@ cmsBool smooth2(cmsContext ContextID, cmsFloat32Number w[], cmsFloat32Number y[]
|
||||
return st;
|
||||
}
|
||||
|
||||
// Smooths a curve sampled at regular intervals.
|
||||
// Smooths a curve sampled at regular intervals.
|
||||
cmsBool CMSEXPORT cmsSmoothToneCurve(cmsToneCurve* Tab, cmsFloat64Number lambda)
|
||||
{
|
||||
cmsFloat32Number w[MAX_NODES_IN_CURVE], y[MAX_NODES_IN_CURVE], z[MAX_NODES_IN_CURVE];
|
||||
@@ -941,7 +1047,7 @@ cmsBool CMSEXPORT cmsSmoothToneCurve(cmsToneCurve* Tab, cmsFloat64Number lambda
|
||||
|
||||
if (Tab == NULL) return FALSE;
|
||||
|
||||
if (cmsIsToneCurveLinear(Tab)) return FALSE; // Nothing to do
|
||||
if (cmsIsToneCurveLinear(Tab)) return TRUE; // Nothing to do
|
||||
|
||||
nItems = Tab -> nEntries;
|
||||
|
||||
@@ -968,11 +1074,20 @@ cmsBool CMSEXPORT cmsSmoothToneCurve(cmsToneCurve* Tab, cmsFloat64Number lambda
|
||||
|
||||
if (z[i] == 0.) Zeros++;
|
||||
if (z[i] >= 65535.) Poles++;
|
||||
if (z[i] < z[i-1]) return FALSE; // Non-Monotonic
|
||||
if (z[i] < z[i-1]) {
|
||||
cmsSignalError(Tab ->InterpParams->ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Non-Monotonic.");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (Zeros > (nItems / 3)) return FALSE; // Degenerated, mostly zeros
|
||||
if (Poles > (nItems / 3)) return FALSE; // Degenerated, mostly poles
|
||||
if (Zeros > (nItems / 3)) {
|
||||
cmsSignalError(Tab ->InterpParams->ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Degenerated, mostly zeros.");
|
||||
return FALSE;
|
||||
}
|
||||
if (Poles > (nItems / 3)) {
|
||||
cmsSignalError(Tab ->InterpParams->ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Degenerated, mostly poles.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Seems ok
|
||||
for (i=0; i < nItems; i++) {
|
||||
@@ -1008,20 +1123,42 @@ cmsBool CMSEXPORT cmsIsToneCurveMonotonic(const cmsToneCurve* t)
|
||||
{
|
||||
int n;
|
||||
int i, last;
|
||||
cmsBool lDescending;
|
||||
|
||||
_cmsAssert(t != NULL);
|
||||
|
||||
n = t ->nEntries;
|
||||
last = t ->Table16[n-1];
|
||||
// Degenerated curves are monotonic? Ok, let's pass them
|
||||
n = t ->nEntries;
|
||||
if (n < 2) return TRUE;
|
||||
|
||||
for (i = n-2; i >= 0; --i) {
|
||||
// Curve direction
|
||||
lDescending = cmsIsToneCurveDescending(t);
|
||||
|
||||
if (t ->Table16[i] > last)
|
||||
if (lDescending) {
|
||||
|
||||
return FALSE;
|
||||
else
|
||||
last = t ->Table16[i];
|
||||
last = t ->Table16[0];
|
||||
|
||||
for (i = 1; i < n; i++) {
|
||||
|
||||
if (t ->Table16[i] - last > 2) // We allow some ripple
|
||||
return FALSE;
|
||||
else
|
||||
last = t ->Table16[i];
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
last = t ->Table16[n-1];
|
||||
|
||||
for (i = n-2; i >= 0; --i) {
|
||||
|
||||
if (t ->Table16[i] - last > 2)
|
||||
return FALSE;
|
||||
else
|
||||
last = t ->Table16[i];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -1061,10 +1198,10 @@ cmsFloat32Number CMSEXPORT cmsEvalToneCurveFloat(const cmsToneCurve* Curve, cmsF
|
||||
if (Curve ->nSegments == 0) {
|
||||
|
||||
cmsUInt16Number In, Out;
|
||||
|
||||
|
||||
In = (cmsUInt16Number) _cmsQuickSaturateWord(v * 65535.0);
|
||||
Out = cmsEvalToneCurve16(Curve, In);
|
||||
|
||||
|
||||
return (cmsFloat32Number) (Out / 65535.0);
|
||||
}
|
||||
|
||||
@@ -1084,21 +1221,21 @@ cmsUInt16Number CMSEXPORT cmsEvalToneCurve16(const cmsToneCurve* Curve, cmsUInt1
|
||||
|
||||
|
||||
// Least squares fitting.
|
||||
// A mathematical procedure for finding the best-fitting curve to a given set of points by
|
||||
// minimizing the sum of the squares of the offsets ("the residuals") of the points from the curve.
|
||||
// The sum of the squares of the offsets is used instead of the offset absolute values because
|
||||
// this allows the residuals to be treated as a continuous differentiable quantity.
|
||||
// A mathematical procedure for finding the best-fitting curve to a given set of points by
|
||||
// minimizing the sum of the squares of the offsets ("the residuals") of the points from the curve.
|
||||
// The sum of the squares of the offsets is used instead of the offset absolute values because
|
||||
// this allows the residuals to be treated as a continuous differentiable quantity.
|
||||
//
|
||||
// y = f(x) = x ^ g
|
||||
//
|
||||
// R = (yi - (xi^g))
|
||||
// R2 = (yi - (xi^g))2
|
||||
// SUM R2 = SUM (yi - (xi^g))2
|
||||
//
|
||||
// dR2/dg = -2 SUM x^g log(x)(y - x^g)
|
||||
// solving for dR2/dg = 0
|
||||
//
|
||||
// g = 1/n * SUM(log(y) / log(x))
|
||||
//
|
||||
// dR2/dg = -2 SUM x^g log(x)(y - x^g)
|
||||
// solving for dR2/dg = 0
|
||||
//
|
||||
// g = 1/n * SUM(log(y) / log(x))
|
||||
|
||||
cmsFloat64Number CMSEXPORT cmsEstimateGamma(const cmsToneCurve* t, cmsFloat64Number Precision)
|
||||
{
|
||||
@@ -1110,13 +1247,13 @@ cmsFloat64Number CMSEXPORT cmsEstimateGamma(const cmsToneCurve* t, cmsFloat64Num
|
||||
|
||||
sum = sum2 = n = 0;
|
||||
|
||||
// Excluding endpoints
|
||||
// Excluding endpoints
|
||||
for (i=1; i < (MAX_NODES_IN_CURVE-1); i++) {
|
||||
|
||||
x = (cmsFloat64Number) i / (MAX_NODES_IN_CURVE-1);
|
||||
y = (cmsFloat64Number) cmsEvalToneCurveFloat(t, (cmsFloat32Number) x);
|
||||
|
||||
// Avoid 7% on lower part to prevent
|
||||
// Avoid 7% on lower part to prevent
|
||||
// artifacts due to linear ramps
|
||||
|
||||
if (y > 0. && y < 1. && x > 0.07) {
|
||||
|
||||
1181
thirdparty/liblcms2/src/cmsgmt.c
vendored
1181
thirdparty/liblcms2/src/cmsgmt.c
vendored
File diff suppressed because it is too large
Load Diff
535
thirdparty/liblcms2/src/cmshalf.c
vendored
Normal file
535
thirdparty/liblcms2/src/cmshalf.c
vendored
Normal file
@@ -0,0 +1,535 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2012 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"
|
||||
|
||||
#ifndef CMS_NO_HALF_SUPPORT
|
||||
|
||||
// This code is inspired in the paper "Fast Half Float Conversions"
|
||||
// by Jeroen van der Zijp
|
||||
|
||||
static cmsUInt32Number Mantissa[2048] = {
|
||||
|
||||
0x00000000, 0x33800000, 0x34000000, 0x34400000, 0x34800000, 0x34a00000,
|
||||
0x34c00000, 0x34e00000, 0x35000000, 0x35100000, 0x35200000, 0x35300000,
|
||||
0x35400000, 0x35500000, 0x35600000, 0x35700000, 0x35800000, 0x35880000,
|
||||
0x35900000, 0x35980000, 0x35a00000, 0x35a80000, 0x35b00000, 0x35b80000,
|
||||
0x35c00000, 0x35c80000, 0x35d00000, 0x35d80000, 0x35e00000, 0x35e80000,
|
||||
0x35f00000, 0x35f80000, 0x36000000, 0x36040000, 0x36080000, 0x360c0000,
|
||||
0x36100000, 0x36140000, 0x36180000, 0x361c0000, 0x36200000, 0x36240000,
|
||||
0x36280000, 0x362c0000, 0x36300000, 0x36340000, 0x36380000, 0x363c0000,
|
||||
0x36400000, 0x36440000, 0x36480000, 0x364c0000, 0x36500000, 0x36540000,
|
||||
0x36580000, 0x365c0000, 0x36600000, 0x36640000, 0x36680000, 0x366c0000,
|
||||
0x36700000, 0x36740000, 0x36780000, 0x367c0000, 0x36800000, 0x36820000,
|
||||
0x36840000, 0x36860000, 0x36880000, 0x368a0000, 0x368c0000, 0x368e0000,
|
||||
0x36900000, 0x36920000, 0x36940000, 0x36960000, 0x36980000, 0x369a0000,
|
||||
0x369c0000, 0x369e0000, 0x36a00000, 0x36a20000, 0x36a40000, 0x36a60000,
|
||||
0x36a80000, 0x36aa0000, 0x36ac0000, 0x36ae0000, 0x36b00000, 0x36b20000,
|
||||
0x36b40000, 0x36b60000, 0x36b80000, 0x36ba0000, 0x36bc0000, 0x36be0000,
|
||||
0x36c00000, 0x36c20000, 0x36c40000, 0x36c60000, 0x36c80000, 0x36ca0000,
|
||||
0x36cc0000, 0x36ce0000, 0x36d00000, 0x36d20000, 0x36d40000, 0x36d60000,
|
||||
0x36d80000, 0x36da0000, 0x36dc0000, 0x36de0000, 0x36e00000, 0x36e20000,
|
||||
0x36e40000, 0x36e60000, 0x36e80000, 0x36ea0000, 0x36ec0000, 0x36ee0000,
|
||||
0x36f00000, 0x36f20000, 0x36f40000, 0x36f60000, 0x36f80000, 0x36fa0000,
|
||||
0x36fc0000, 0x36fe0000, 0x37000000, 0x37010000, 0x37020000, 0x37030000,
|
||||
0x37040000, 0x37050000, 0x37060000, 0x37070000, 0x37080000, 0x37090000,
|
||||
0x370a0000, 0x370b0000, 0x370c0000, 0x370d0000, 0x370e0000, 0x370f0000,
|
||||
0x37100000, 0x37110000, 0x37120000, 0x37130000, 0x37140000, 0x37150000,
|
||||
0x37160000, 0x37170000, 0x37180000, 0x37190000, 0x371a0000, 0x371b0000,
|
||||
0x371c0000, 0x371d0000, 0x371e0000, 0x371f0000, 0x37200000, 0x37210000,
|
||||
0x37220000, 0x37230000, 0x37240000, 0x37250000, 0x37260000, 0x37270000,
|
||||
0x37280000, 0x37290000, 0x372a0000, 0x372b0000, 0x372c0000, 0x372d0000,
|
||||
0x372e0000, 0x372f0000, 0x37300000, 0x37310000, 0x37320000, 0x37330000,
|
||||
0x37340000, 0x37350000, 0x37360000, 0x37370000, 0x37380000, 0x37390000,
|
||||
0x373a0000, 0x373b0000, 0x373c0000, 0x373d0000, 0x373e0000, 0x373f0000,
|
||||
0x37400000, 0x37410000, 0x37420000, 0x37430000, 0x37440000, 0x37450000,
|
||||
0x37460000, 0x37470000, 0x37480000, 0x37490000, 0x374a0000, 0x374b0000,
|
||||
0x374c0000, 0x374d0000, 0x374e0000, 0x374f0000, 0x37500000, 0x37510000,
|
||||
0x37520000, 0x37530000, 0x37540000, 0x37550000, 0x37560000, 0x37570000,
|
||||
0x37580000, 0x37590000, 0x375a0000, 0x375b0000, 0x375c0000, 0x375d0000,
|
||||
0x375e0000, 0x375f0000, 0x37600000, 0x37610000, 0x37620000, 0x37630000,
|
||||
0x37640000, 0x37650000, 0x37660000, 0x37670000, 0x37680000, 0x37690000,
|
||||
0x376a0000, 0x376b0000, 0x376c0000, 0x376d0000, 0x376e0000, 0x376f0000,
|
||||
0x37700000, 0x37710000, 0x37720000, 0x37730000, 0x37740000, 0x37750000,
|
||||
0x37760000, 0x37770000, 0x37780000, 0x37790000, 0x377a0000, 0x377b0000,
|
||||
0x377c0000, 0x377d0000, 0x377e0000, 0x377f0000, 0x37800000, 0x37808000,
|
||||
0x37810000, 0x37818000, 0x37820000, 0x37828000, 0x37830000, 0x37838000,
|
||||
0x37840000, 0x37848000, 0x37850000, 0x37858000, 0x37860000, 0x37868000,
|
||||
0x37870000, 0x37878000, 0x37880000, 0x37888000, 0x37890000, 0x37898000,
|
||||
0x378a0000, 0x378a8000, 0x378b0000, 0x378b8000, 0x378c0000, 0x378c8000,
|
||||
0x378d0000, 0x378d8000, 0x378e0000, 0x378e8000, 0x378f0000, 0x378f8000,
|
||||
0x37900000, 0x37908000, 0x37910000, 0x37918000, 0x37920000, 0x37928000,
|
||||
0x37930000, 0x37938000, 0x37940000, 0x37948000, 0x37950000, 0x37958000,
|
||||
0x37960000, 0x37968000, 0x37970000, 0x37978000, 0x37980000, 0x37988000,
|
||||
0x37990000, 0x37998000, 0x379a0000, 0x379a8000, 0x379b0000, 0x379b8000,
|
||||
0x379c0000, 0x379c8000, 0x379d0000, 0x379d8000, 0x379e0000, 0x379e8000,
|
||||
0x379f0000, 0x379f8000, 0x37a00000, 0x37a08000, 0x37a10000, 0x37a18000,
|
||||
0x37a20000, 0x37a28000, 0x37a30000, 0x37a38000, 0x37a40000, 0x37a48000,
|
||||
0x37a50000, 0x37a58000, 0x37a60000, 0x37a68000, 0x37a70000, 0x37a78000,
|
||||
0x37a80000, 0x37a88000, 0x37a90000, 0x37a98000, 0x37aa0000, 0x37aa8000,
|
||||
0x37ab0000, 0x37ab8000, 0x37ac0000, 0x37ac8000, 0x37ad0000, 0x37ad8000,
|
||||
0x37ae0000, 0x37ae8000, 0x37af0000, 0x37af8000, 0x37b00000, 0x37b08000,
|
||||
0x37b10000, 0x37b18000, 0x37b20000, 0x37b28000, 0x37b30000, 0x37b38000,
|
||||
0x37b40000, 0x37b48000, 0x37b50000, 0x37b58000, 0x37b60000, 0x37b68000,
|
||||
0x37b70000, 0x37b78000, 0x37b80000, 0x37b88000, 0x37b90000, 0x37b98000,
|
||||
0x37ba0000, 0x37ba8000, 0x37bb0000, 0x37bb8000, 0x37bc0000, 0x37bc8000,
|
||||
0x37bd0000, 0x37bd8000, 0x37be0000, 0x37be8000, 0x37bf0000, 0x37bf8000,
|
||||
0x37c00000, 0x37c08000, 0x37c10000, 0x37c18000, 0x37c20000, 0x37c28000,
|
||||
0x37c30000, 0x37c38000, 0x37c40000, 0x37c48000, 0x37c50000, 0x37c58000,
|
||||
0x37c60000, 0x37c68000, 0x37c70000, 0x37c78000, 0x37c80000, 0x37c88000,
|
||||
0x37c90000, 0x37c98000, 0x37ca0000, 0x37ca8000, 0x37cb0000, 0x37cb8000,
|
||||
0x37cc0000, 0x37cc8000, 0x37cd0000, 0x37cd8000, 0x37ce0000, 0x37ce8000,
|
||||
0x37cf0000, 0x37cf8000, 0x37d00000, 0x37d08000, 0x37d10000, 0x37d18000,
|
||||
0x37d20000, 0x37d28000, 0x37d30000, 0x37d38000, 0x37d40000, 0x37d48000,
|
||||
0x37d50000, 0x37d58000, 0x37d60000, 0x37d68000, 0x37d70000, 0x37d78000,
|
||||
0x37d80000, 0x37d88000, 0x37d90000, 0x37d98000, 0x37da0000, 0x37da8000,
|
||||
0x37db0000, 0x37db8000, 0x37dc0000, 0x37dc8000, 0x37dd0000, 0x37dd8000,
|
||||
0x37de0000, 0x37de8000, 0x37df0000, 0x37df8000, 0x37e00000, 0x37e08000,
|
||||
0x37e10000, 0x37e18000, 0x37e20000, 0x37e28000, 0x37e30000, 0x37e38000,
|
||||
0x37e40000, 0x37e48000, 0x37e50000, 0x37e58000, 0x37e60000, 0x37e68000,
|
||||
0x37e70000, 0x37e78000, 0x37e80000, 0x37e88000, 0x37e90000, 0x37e98000,
|
||||
0x37ea0000, 0x37ea8000, 0x37eb0000, 0x37eb8000, 0x37ec0000, 0x37ec8000,
|
||||
0x37ed0000, 0x37ed8000, 0x37ee0000, 0x37ee8000, 0x37ef0000, 0x37ef8000,
|
||||
0x37f00000, 0x37f08000, 0x37f10000, 0x37f18000, 0x37f20000, 0x37f28000,
|
||||
0x37f30000, 0x37f38000, 0x37f40000, 0x37f48000, 0x37f50000, 0x37f58000,
|
||||
0x37f60000, 0x37f68000, 0x37f70000, 0x37f78000, 0x37f80000, 0x37f88000,
|
||||
0x37f90000, 0x37f98000, 0x37fa0000, 0x37fa8000, 0x37fb0000, 0x37fb8000,
|
||||
0x37fc0000, 0x37fc8000, 0x37fd0000, 0x37fd8000, 0x37fe0000, 0x37fe8000,
|
||||
0x37ff0000, 0x37ff8000, 0x38000000, 0x38004000, 0x38008000, 0x3800c000,
|
||||
0x38010000, 0x38014000, 0x38018000, 0x3801c000, 0x38020000, 0x38024000,
|
||||
0x38028000, 0x3802c000, 0x38030000, 0x38034000, 0x38038000, 0x3803c000,
|
||||
0x38040000, 0x38044000, 0x38048000, 0x3804c000, 0x38050000, 0x38054000,
|
||||
0x38058000, 0x3805c000, 0x38060000, 0x38064000, 0x38068000, 0x3806c000,
|
||||
0x38070000, 0x38074000, 0x38078000, 0x3807c000, 0x38080000, 0x38084000,
|
||||
0x38088000, 0x3808c000, 0x38090000, 0x38094000, 0x38098000, 0x3809c000,
|
||||
0x380a0000, 0x380a4000, 0x380a8000, 0x380ac000, 0x380b0000, 0x380b4000,
|
||||
0x380b8000, 0x380bc000, 0x380c0000, 0x380c4000, 0x380c8000, 0x380cc000,
|
||||
0x380d0000, 0x380d4000, 0x380d8000, 0x380dc000, 0x380e0000, 0x380e4000,
|
||||
0x380e8000, 0x380ec000, 0x380f0000, 0x380f4000, 0x380f8000, 0x380fc000,
|
||||
0x38100000, 0x38104000, 0x38108000, 0x3810c000, 0x38110000, 0x38114000,
|
||||
0x38118000, 0x3811c000, 0x38120000, 0x38124000, 0x38128000, 0x3812c000,
|
||||
0x38130000, 0x38134000, 0x38138000, 0x3813c000, 0x38140000, 0x38144000,
|
||||
0x38148000, 0x3814c000, 0x38150000, 0x38154000, 0x38158000, 0x3815c000,
|
||||
0x38160000, 0x38164000, 0x38168000, 0x3816c000, 0x38170000, 0x38174000,
|
||||
0x38178000, 0x3817c000, 0x38180000, 0x38184000, 0x38188000, 0x3818c000,
|
||||
0x38190000, 0x38194000, 0x38198000, 0x3819c000, 0x381a0000, 0x381a4000,
|
||||
0x381a8000, 0x381ac000, 0x381b0000, 0x381b4000, 0x381b8000, 0x381bc000,
|
||||
0x381c0000, 0x381c4000, 0x381c8000, 0x381cc000, 0x381d0000, 0x381d4000,
|
||||
0x381d8000, 0x381dc000, 0x381e0000, 0x381e4000, 0x381e8000, 0x381ec000,
|
||||
0x381f0000, 0x381f4000, 0x381f8000, 0x381fc000, 0x38200000, 0x38204000,
|
||||
0x38208000, 0x3820c000, 0x38210000, 0x38214000, 0x38218000, 0x3821c000,
|
||||
0x38220000, 0x38224000, 0x38228000, 0x3822c000, 0x38230000, 0x38234000,
|
||||
0x38238000, 0x3823c000, 0x38240000, 0x38244000, 0x38248000, 0x3824c000,
|
||||
0x38250000, 0x38254000, 0x38258000, 0x3825c000, 0x38260000, 0x38264000,
|
||||
0x38268000, 0x3826c000, 0x38270000, 0x38274000, 0x38278000, 0x3827c000,
|
||||
0x38280000, 0x38284000, 0x38288000, 0x3828c000, 0x38290000, 0x38294000,
|
||||
0x38298000, 0x3829c000, 0x382a0000, 0x382a4000, 0x382a8000, 0x382ac000,
|
||||
0x382b0000, 0x382b4000, 0x382b8000, 0x382bc000, 0x382c0000, 0x382c4000,
|
||||
0x382c8000, 0x382cc000, 0x382d0000, 0x382d4000, 0x382d8000, 0x382dc000,
|
||||
0x382e0000, 0x382e4000, 0x382e8000, 0x382ec000, 0x382f0000, 0x382f4000,
|
||||
0x382f8000, 0x382fc000, 0x38300000, 0x38304000, 0x38308000, 0x3830c000,
|
||||
0x38310000, 0x38314000, 0x38318000, 0x3831c000, 0x38320000, 0x38324000,
|
||||
0x38328000, 0x3832c000, 0x38330000, 0x38334000, 0x38338000, 0x3833c000,
|
||||
0x38340000, 0x38344000, 0x38348000, 0x3834c000, 0x38350000, 0x38354000,
|
||||
0x38358000, 0x3835c000, 0x38360000, 0x38364000, 0x38368000, 0x3836c000,
|
||||
0x38370000, 0x38374000, 0x38378000, 0x3837c000, 0x38380000, 0x38384000,
|
||||
0x38388000, 0x3838c000, 0x38390000, 0x38394000, 0x38398000, 0x3839c000,
|
||||
0x383a0000, 0x383a4000, 0x383a8000, 0x383ac000, 0x383b0000, 0x383b4000,
|
||||
0x383b8000, 0x383bc000, 0x383c0000, 0x383c4000, 0x383c8000, 0x383cc000,
|
||||
0x383d0000, 0x383d4000, 0x383d8000, 0x383dc000, 0x383e0000, 0x383e4000,
|
||||
0x383e8000, 0x383ec000, 0x383f0000, 0x383f4000, 0x383f8000, 0x383fc000,
|
||||
0x38400000, 0x38404000, 0x38408000, 0x3840c000, 0x38410000, 0x38414000,
|
||||
0x38418000, 0x3841c000, 0x38420000, 0x38424000, 0x38428000, 0x3842c000,
|
||||
0x38430000, 0x38434000, 0x38438000, 0x3843c000, 0x38440000, 0x38444000,
|
||||
0x38448000, 0x3844c000, 0x38450000, 0x38454000, 0x38458000, 0x3845c000,
|
||||
0x38460000, 0x38464000, 0x38468000, 0x3846c000, 0x38470000, 0x38474000,
|
||||
0x38478000, 0x3847c000, 0x38480000, 0x38484000, 0x38488000, 0x3848c000,
|
||||
0x38490000, 0x38494000, 0x38498000, 0x3849c000, 0x384a0000, 0x384a4000,
|
||||
0x384a8000, 0x384ac000, 0x384b0000, 0x384b4000, 0x384b8000, 0x384bc000,
|
||||
0x384c0000, 0x384c4000, 0x384c8000, 0x384cc000, 0x384d0000, 0x384d4000,
|
||||
0x384d8000, 0x384dc000, 0x384e0000, 0x384e4000, 0x384e8000, 0x384ec000,
|
||||
0x384f0000, 0x384f4000, 0x384f8000, 0x384fc000, 0x38500000, 0x38504000,
|
||||
0x38508000, 0x3850c000, 0x38510000, 0x38514000, 0x38518000, 0x3851c000,
|
||||
0x38520000, 0x38524000, 0x38528000, 0x3852c000, 0x38530000, 0x38534000,
|
||||
0x38538000, 0x3853c000, 0x38540000, 0x38544000, 0x38548000, 0x3854c000,
|
||||
0x38550000, 0x38554000, 0x38558000, 0x3855c000, 0x38560000, 0x38564000,
|
||||
0x38568000, 0x3856c000, 0x38570000, 0x38574000, 0x38578000, 0x3857c000,
|
||||
0x38580000, 0x38584000, 0x38588000, 0x3858c000, 0x38590000, 0x38594000,
|
||||
0x38598000, 0x3859c000, 0x385a0000, 0x385a4000, 0x385a8000, 0x385ac000,
|
||||
0x385b0000, 0x385b4000, 0x385b8000, 0x385bc000, 0x385c0000, 0x385c4000,
|
||||
0x385c8000, 0x385cc000, 0x385d0000, 0x385d4000, 0x385d8000, 0x385dc000,
|
||||
0x385e0000, 0x385e4000, 0x385e8000, 0x385ec000, 0x385f0000, 0x385f4000,
|
||||
0x385f8000, 0x385fc000, 0x38600000, 0x38604000, 0x38608000, 0x3860c000,
|
||||
0x38610000, 0x38614000, 0x38618000, 0x3861c000, 0x38620000, 0x38624000,
|
||||
0x38628000, 0x3862c000, 0x38630000, 0x38634000, 0x38638000, 0x3863c000,
|
||||
0x38640000, 0x38644000, 0x38648000, 0x3864c000, 0x38650000, 0x38654000,
|
||||
0x38658000, 0x3865c000, 0x38660000, 0x38664000, 0x38668000, 0x3866c000,
|
||||
0x38670000, 0x38674000, 0x38678000, 0x3867c000, 0x38680000, 0x38684000,
|
||||
0x38688000, 0x3868c000, 0x38690000, 0x38694000, 0x38698000, 0x3869c000,
|
||||
0x386a0000, 0x386a4000, 0x386a8000, 0x386ac000, 0x386b0000, 0x386b4000,
|
||||
0x386b8000, 0x386bc000, 0x386c0000, 0x386c4000, 0x386c8000, 0x386cc000,
|
||||
0x386d0000, 0x386d4000, 0x386d8000, 0x386dc000, 0x386e0000, 0x386e4000,
|
||||
0x386e8000, 0x386ec000, 0x386f0000, 0x386f4000, 0x386f8000, 0x386fc000,
|
||||
0x38700000, 0x38704000, 0x38708000, 0x3870c000, 0x38710000, 0x38714000,
|
||||
0x38718000, 0x3871c000, 0x38720000, 0x38724000, 0x38728000, 0x3872c000,
|
||||
0x38730000, 0x38734000, 0x38738000, 0x3873c000, 0x38740000, 0x38744000,
|
||||
0x38748000, 0x3874c000, 0x38750000, 0x38754000, 0x38758000, 0x3875c000,
|
||||
0x38760000, 0x38764000, 0x38768000, 0x3876c000, 0x38770000, 0x38774000,
|
||||
0x38778000, 0x3877c000, 0x38780000, 0x38784000, 0x38788000, 0x3878c000,
|
||||
0x38790000, 0x38794000, 0x38798000, 0x3879c000, 0x387a0000, 0x387a4000,
|
||||
0x387a8000, 0x387ac000, 0x387b0000, 0x387b4000, 0x387b8000, 0x387bc000,
|
||||
0x387c0000, 0x387c4000, 0x387c8000, 0x387cc000, 0x387d0000, 0x387d4000,
|
||||
0x387d8000, 0x387dc000, 0x387e0000, 0x387e4000, 0x387e8000, 0x387ec000,
|
||||
0x387f0000, 0x387f4000, 0x387f8000, 0x387fc000, 0x38000000, 0x38002000,
|
||||
0x38004000, 0x38006000, 0x38008000, 0x3800a000, 0x3800c000, 0x3800e000,
|
||||
0x38010000, 0x38012000, 0x38014000, 0x38016000, 0x38018000, 0x3801a000,
|
||||
0x3801c000, 0x3801e000, 0x38020000, 0x38022000, 0x38024000, 0x38026000,
|
||||
0x38028000, 0x3802a000, 0x3802c000, 0x3802e000, 0x38030000, 0x38032000,
|
||||
0x38034000, 0x38036000, 0x38038000, 0x3803a000, 0x3803c000, 0x3803e000,
|
||||
0x38040000, 0x38042000, 0x38044000, 0x38046000, 0x38048000, 0x3804a000,
|
||||
0x3804c000, 0x3804e000, 0x38050000, 0x38052000, 0x38054000, 0x38056000,
|
||||
0x38058000, 0x3805a000, 0x3805c000, 0x3805e000, 0x38060000, 0x38062000,
|
||||
0x38064000, 0x38066000, 0x38068000, 0x3806a000, 0x3806c000, 0x3806e000,
|
||||
0x38070000, 0x38072000, 0x38074000, 0x38076000, 0x38078000, 0x3807a000,
|
||||
0x3807c000, 0x3807e000, 0x38080000, 0x38082000, 0x38084000, 0x38086000,
|
||||
0x38088000, 0x3808a000, 0x3808c000, 0x3808e000, 0x38090000, 0x38092000,
|
||||
0x38094000, 0x38096000, 0x38098000, 0x3809a000, 0x3809c000, 0x3809e000,
|
||||
0x380a0000, 0x380a2000, 0x380a4000, 0x380a6000, 0x380a8000, 0x380aa000,
|
||||
0x380ac000, 0x380ae000, 0x380b0000, 0x380b2000, 0x380b4000, 0x380b6000,
|
||||
0x380b8000, 0x380ba000, 0x380bc000, 0x380be000, 0x380c0000, 0x380c2000,
|
||||
0x380c4000, 0x380c6000, 0x380c8000, 0x380ca000, 0x380cc000, 0x380ce000,
|
||||
0x380d0000, 0x380d2000, 0x380d4000, 0x380d6000, 0x380d8000, 0x380da000,
|
||||
0x380dc000, 0x380de000, 0x380e0000, 0x380e2000, 0x380e4000, 0x380e6000,
|
||||
0x380e8000, 0x380ea000, 0x380ec000, 0x380ee000, 0x380f0000, 0x380f2000,
|
||||
0x380f4000, 0x380f6000, 0x380f8000, 0x380fa000, 0x380fc000, 0x380fe000,
|
||||
0x38100000, 0x38102000, 0x38104000, 0x38106000, 0x38108000, 0x3810a000,
|
||||
0x3810c000, 0x3810e000, 0x38110000, 0x38112000, 0x38114000, 0x38116000,
|
||||
0x38118000, 0x3811a000, 0x3811c000, 0x3811e000, 0x38120000, 0x38122000,
|
||||
0x38124000, 0x38126000, 0x38128000, 0x3812a000, 0x3812c000, 0x3812e000,
|
||||
0x38130000, 0x38132000, 0x38134000, 0x38136000, 0x38138000, 0x3813a000,
|
||||
0x3813c000, 0x3813e000, 0x38140000, 0x38142000, 0x38144000, 0x38146000,
|
||||
0x38148000, 0x3814a000, 0x3814c000, 0x3814e000, 0x38150000, 0x38152000,
|
||||
0x38154000, 0x38156000, 0x38158000, 0x3815a000, 0x3815c000, 0x3815e000,
|
||||
0x38160000, 0x38162000, 0x38164000, 0x38166000, 0x38168000, 0x3816a000,
|
||||
0x3816c000, 0x3816e000, 0x38170000, 0x38172000, 0x38174000, 0x38176000,
|
||||
0x38178000, 0x3817a000, 0x3817c000, 0x3817e000, 0x38180000, 0x38182000,
|
||||
0x38184000, 0x38186000, 0x38188000, 0x3818a000, 0x3818c000, 0x3818e000,
|
||||
0x38190000, 0x38192000, 0x38194000, 0x38196000, 0x38198000, 0x3819a000,
|
||||
0x3819c000, 0x3819e000, 0x381a0000, 0x381a2000, 0x381a4000, 0x381a6000,
|
||||
0x381a8000, 0x381aa000, 0x381ac000, 0x381ae000, 0x381b0000, 0x381b2000,
|
||||
0x381b4000, 0x381b6000, 0x381b8000, 0x381ba000, 0x381bc000, 0x381be000,
|
||||
0x381c0000, 0x381c2000, 0x381c4000, 0x381c6000, 0x381c8000, 0x381ca000,
|
||||
0x381cc000, 0x381ce000, 0x381d0000, 0x381d2000, 0x381d4000, 0x381d6000,
|
||||
0x381d8000, 0x381da000, 0x381dc000, 0x381de000, 0x381e0000, 0x381e2000,
|
||||
0x381e4000, 0x381e6000, 0x381e8000, 0x381ea000, 0x381ec000, 0x381ee000,
|
||||
0x381f0000, 0x381f2000, 0x381f4000, 0x381f6000, 0x381f8000, 0x381fa000,
|
||||
0x381fc000, 0x381fe000, 0x38200000, 0x38202000, 0x38204000, 0x38206000,
|
||||
0x38208000, 0x3820a000, 0x3820c000, 0x3820e000, 0x38210000, 0x38212000,
|
||||
0x38214000, 0x38216000, 0x38218000, 0x3821a000, 0x3821c000, 0x3821e000,
|
||||
0x38220000, 0x38222000, 0x38224000, 0x38226000, 0x38228000, 0x3822a000,
|
||||
0x3822c000, 0x3822e000, 0x38230000, 0x38232000, 0x38234000, 0x38236000,
|
||||
0x38238000, 0x3823a000, 0x3823c000, 0x3823e000, 0x38240000, 0x38242000,
|
||||
0x38244000, 0x38246000, 0x38248000, 0x3824a000, 0x3824c000, 0x3824e000,
|
||||
0x38250000, 0x38252000, 0x38254000, 0x38256000, 0x38258000, 0x3825a000,
|
||||
0x3825c000, 0x3825e000, 0x38260000, 0x38262000, 0x38264000, 0x38266000,
|
||||
0x38268000, 0x3826a000, 0x3826c000, 0x3826e000, 0x38270000, 0x38272000,
|
||||
0x38274000, 0x38276000, 0x38278000, 0x3827a000, 0x3827c000, 0x3827e000,
|
||||
0x38280000, 0x38282000, 0x38284000, 0x38286000, 0x38288000, 0x3828a000,
|
||||
0x3828c000, 0x3828e000, 0x38290000, 0x38292000, 0x38294000, 0x38296000,
|
||||
0x38298000, 0x3829a000, 0x3829c000, 0x3829e000, 0x382a0000, 0x382a2000,
|
||||
0x382a4000, 0x382a6000, 0x382a8000, 0x382aa000, 0x382ac000, 0x382ae000,
|
||||
0x382b0000, 0x382b2000, 0x382b4000, 0x382b6000, 0x382b8000, 0x382ba000,
|
||||
0x382bc000, 0x382be000, 0x382c0000, 0x382c2000, 0x382c4000, 0x382c6000,
|
||||
0x382c8000, 0x382ca000, 0x382cc000, 0x382ce000, 0x382d0000, 0x382d2000,
|
||||
0x382d4000, 0x382d6000, 0x382d8000, 0x382da000, 0x382dc000, 0x382de000,
|
||||
0x382e0000, 0x382e2000, 0x382e4000, 0x382e6000, 0x382e8000, 0x382ea000,
|
||||
0x382ec000, 0x382ee000, 0x382f0000, 0x382f2000, 0x382f4000, 0x382f6000,
|
||||
0x382f8000, 0x382fa000, 0x382fc000, 0x382fe000, 0x38300000, 0x38302000,
|
||||
0x38304000, 0x38306000, 0x38308000, 0x3830a000, 0x3830c000, 0x3830e000,
|
||||
0x38310000, 0x38312000, 0x38314000, 0x38316000, 0x38318000, 0x3831a000,
|
||||
0x3831c000, 0x3831e000, 0x38320000, 0x38322000, 0x38324000, 0x38326000,
|
||||
0x38328000, 0x3832a000, 0x3832c000, 0x3832e000, 0x38330000, 0x38332000,
|
||||
0x38334000, 0x38336000, 0x38338000, 0x3833a000, 0x3833c000, 0x3833e000,
|
||||
0x38340000, 0x38342000, 0x38344000, 0x38346000, 0x38348000, 0x3834a000,
|
||||
0x3834c000, 0x3834e000, 0x38350000, 0x38352000, 0x38354000, 0x38356000,
|
||||
0x38358000, 0x3835a000, 0x3835c000, 0x3835e000, 0x38360000, 0x38362000,
|
||||
0x38364000, 0x38366000, 0x38368000, 0x3836a000, 0x3836c000, 0x3836e000,
|
||||
0x38370000, 0x38372000, 0x38374000, 0x38376000, 0x38378000, 0x3837a000,
|
||||
0x3837c000, 0x3837e000, 0x38380000, 0x38382000, 0x38384000, 0x38386000,
|
||||
0x38388000, 0x3838a000, 0x3838c000, 0x3838e000, 0x38390000, 0x38392000,
|
||||
0x38394000, 0x38396000, 0x38398000, 0x3839a000, 0x3839c000, 0x3839e000,
|
||||
0x383a0000, 0x383a2000, 0x383a4000, 0x383a6000, 0x383a8000, 0x383aa000,
|
||||
0x383ac000, 0x383ae000, 0x383b0000, 0x383b2000, 0x383b4000, 0x383b6000,
|
||||
0x383b8000, 0x383ba000, 0x383bc000, 0x383be000, 0x383c0000, 0x383c2000,
|
||||
0x383c4000, 0x383c6000, 0x383c8000, 0x383ca000, 0x383cc000, 0x383ce000,
|
||||
0x383d0000, 0x383d2000, 0x383d4000, 0x383d6000, 0x383d8000, 0x383da000,
|
||||
0x383dc000, 0x383de000, 0x383e0000, 0x383e2000, 0x383e4000, 0x383e6000,
|
||||
0x383e8000, 0x383ea000, 0x383ec000, 0x383ee000, 0x383f0000, 0x383f2000,
|
||||
0x383f4000, 0x383f6000, 0x383f8000, 0x383fa000, 0x383fc000, 0x383fe000,
|
||||
0x38400000, 0x38402000, 0x38404000, 0x38406000, 0x38408000, 0x3840a000,
|
||||
0x3840c000, 0x3840e000, 0x38410000, 0x38412000, 0x38414000, 0x38416000,
|
||||
0x38418000, 0x3841a000, 0x3841c000, 0x3841e000, 0x38420000, 0x38422000,
|
||||
0x38424000, 0x38426000, 0x38428000, 0x3842a000, 0x3842c000, 0x3842e000,
|
||||
0x38430000, 0x38432000, 0x38434000, 0x38436000, 0x38438000, 0x3843a000,
|
||||
0x3843c000, 0x3843e000, 0x38440000, 0x38442000, 0x38444000, 0x38446000,
|
||||
0x38448000, 0x3844a000, 0x3844c000, 0x3844e000, 0x38450000, 0x38452000,
|
||||
0x38454000, 0x38456000, 0x38458000, 0x3845a000, 0x3845c000, 0x3845e000,
|
||||
0x38460000, 0x38462000, 0x38464000, 0x38466000, 0x38468000, 0x3846a000,
|
||||
0x3846c000, 0x3846e000, 0x38470000, 0x38472000, 0x38474000, 0x38476000,
|
||||
0x38478000, 0x3847a000, 0x3847c000, 0x3847e000, 0x38480000, 0x38482000,
|
||||
0x38484000, 0x38486000, 0x38488000, 0x3848a000, 0x3848c000, 0x3848e000,
|
||||
0x38490000, 0x38492000, 0x38494000, 0x38496000, 0x38498000, 0x3849a000,
|
||||
0x3849c000, 0x3849e000, 0x384a0000, 0x384a2000, 0x384a4000, 0x384a6000,
|
||||
0x384a8000, 0x384aa000, 0x384ac000, 0x384ae000, 0x384b0000, 0x384b2000,
|
||||
0x384b4000, 0x384b6000, 0x384b8000, 0x384ba000, 0x384bc000, 0x384be000,
|
||||
0x384c0000, 0x384c2000, 0x384c4000, 0x384c6000, 0x384c8000, 0x384ca000,
|
||||
0x384cc000, 0x384ce000, 0x384d0000, 0x384d2000, 0x384d4000, 0x384d6000,
|
||||
0x384d8000, 0x384da000, 0x384dc000, 0x384de000, 0x384e0000, 0x384e2000,
|
||||
0x384e4000, 0x384e6000, 0x384e8000, 0x384ea000, 0x384ec000, 0x384ee000,
|
||||
0x384f0000, 0x384f2000, 0x384f4000, 0x384f6000, 0x384f8000, 0x384fa000,
|
||||
0x384fc000, 0x384fe000, 0x38500000, 0x38502000, 0x38504000, 0x38506000,
|
||||
0x38508000, 0x3850a000, 0x3850c000, 0x3850e000, 0x38510000, 0x38512000,
|
||||
0x38514000, 0x38516000, 0x38518000, 0x3851a000, 0x3851c000, 0x3851e000,
|
||||
0x38520000, 0x38522000, 0x38524000, 0x38526000, 0x38528000, 0x3852a000,
|
||||
0x3852c000, 0x3852e000, 0x38530000, 0x38532000, 0x38534000, 0x38536000,
|
||||
0x38538000, 0x3853a000, 0x3853c000, 0x3853e000, 0x38540000, 0x38542000,
|
||||
0x38544000, 0x38546000, 0x38548000, 0x3854a000, 0x3854c000, 0x3854e000,
|
||||
0x38550000, 0x38552000, 0x38554000, 0x38556000, 0x38558000, 0x3855a000,
|
||||
0x3855c000, 0x3855e000, 0x38560000, 0x38562000, 0x38564000, 0x38566000,
|
||||
0x38568000, 0x3856a000, 0x3856c000, 0x3856e000, 0x38570000, 0x38572000,
|
||||
0x38574000, 0x38576000, 0x38578000, 0x3857a000, 0x3857c000, 0x3857e000,
|
||||
0x38580000, 0x38582000, 0x38584000, 0x38586000, 0x38588000, 0x3858a000,
|
||||
0x3858c000, 0x3858e000, 0x38590000, 0x38592000, 0x38594000, 0x38596000,
|
||||
0x38598000, 0x3859a000, 0x3859c000, 0x3859e000, 0x385a0000, 0x385a2000,
|
||||
0x385a4000, 0x385a6000, 0x385a8000, 0x385aa000, 0x385ac000, 0x385ae000,
|
||||
0x385b0000, 0x385b2000, 0x385b4000, 0x385b6000, 0x385b8000, 0x385ba000,
|
||||
0x385bc000, 0x385be000, 0x385c0000, 0x385c2000, 0x385c4000, 0x385c6000,
|
||||
0x385c8000, 0x385ca000, 0x385cc000, 0x385ce000, 0x385d0000, 0x385d2000,
|
||||
0x385d4000, 0x385d6000, 0x385d8000, 0x385da000, 0x385dc000, 0x385de000,
|
||||
0x385e0000, 0x385e2000, 0x385e4000, 0x385e6000, 0x385e8000, 0x385ea000,
|
||||
0x385ec000, 0x385ee000, 0x385f0000, 0x385f2000, 0x385f4000, 0x385f6000,
|
||||
0x385f8000, 0x385fa000, 0x385fc000, 0x385fe000, 0x38600000, 0x38602000,
|
||||
0x38604000, 0x38606000, 0x38608000, 0x3860a000, 0x3860c000, 0x3860e000,
|
||||
0x38610000, 0x38612000, 0x38614000, 0x38616000, 0x38618000, 0x3861a000,
|
||||
0x3861c000, 0x3861e000, 0x38620000, 0x38622000, 0x38624000, 0x38626000,
|
||||
0x38628000, 0x3862a000, 0x3862c000, 0x3862e000, 0x38630000, 0x38632000,
|
||||
0x38634000, 0x38636000, 0x38638000, 0x3863a000, 0x3863c000, 0x3863e000,
|
||||
0x38640000, 0x38642000, 0x38644000, 0x38646000, 0x38648000, 0x3864a000,
|
||||
0x3864c000, 0x3864e000, 0x38650000, 0x38652000, 0x38654000, 0x38656000,
|
||||
0x38658000, 0x3865a000, 0x3865c000, 0x3865e000, 0x38660000, 0x38662000,
|
||||
0x38664000, 0x38666000, 0x38668000, 0x3866a000, 0x3866c000, 0x3866e000,
|
||||
0x38670000, 0x38672000, 0x38674000, 0x38676000, 0x38678000, 0x3867a000,
|
||||
0x3867c000, 0x3867e000, 0x38680000, 0x38682000, 0x38684000, 0x38686000,
|
||||
0x38688000, 0x3868a000, 0x3868c000, 0x3868e000, 0x38690000, 0x38692000,
|
||||
0x38694000, 0x38696000, 0x38698000, 0x3869a000, 0x3869c000, 0x3869e000,
|
||||
0x386a0000, 0x386a2000, 0x386a4000, 0x386a6000, 0x386a8000, 0x386aa000,
|
||||
0x386ac000, 0x386ae000, 0x386b0000, 0x386b2000, 0x386b4000, 0x386b6000,
|
||||
0x386b8000, 0x386ba000, 0x386bc000, 0x386be000, 0x386c0000, 0x386c2000,
|
||||
0x386c4000, 0x386c6000, 0x386c8000, 0x386ca000, 0x386cc000, 0x386ce000,
|
||||
0x386d0000, 0x386d2000, 0x386d4000, 0x386d6000, 0x386d8000, 0x386da000,
|
||||
0x386dc000, 0x386de000, 0x386e0000, 0x386e2000, 0x386e4000, 0x386e6000,
|
||||
0x386e8000, 0x386ea000, 0x386ec000, 0x386ee000, 0x386f0000, 0x386f2000,
|
||||
0x386f4000, 0x386f6000, 0x386f8000, 0x386fa000, 0x386fc000, 0x386fe000,
|
||||
0x38700000, 0x38702000, 0x38704000, 0x38706000, 0x38708000, 0x3870a000,
|
||||
0x3870c000, 0x3870e000, 0x38710000, 0x38712000, 0x38714000, 0x38716000,
|
||||
0x38718000, 0x3871a000, 0x3871c000, 0x3871e000, 0x38720000, 0x38722000,
|
||||
0x38724000, 0x38726000, 0x38728000, 0x3872a000, 0x3872c000, 0x3872e000,
|
||||
0x38730000, 0x38732000, 0x38734000, 0x38736000, 0x38738000, 0x3873a000,
|
||||
0x3873c000, 0x3873e000, 0x38740000, 0x38742000, 0x38744000, 0x38746000,
|
||||
0x38748000, 0x3874a000, 0x3874c000, 0x3874e000, 0x38750000, 0x38752000,
|
||||
0x38754000, 0x38756000, 0x38758000, 0x3875a000, 0x3875c000, 0x3875e000,
|
||||
0x38760000, 0x38762000, 0x38764000, 0x38766000, 0x38768000, 0x3876a000,
|
||||
0x3876c000, 0x3876e000, 0x38770000, 0x38772000, 0x38774000, 0x38776000,
|
||||
0x38778000, 0x3877a000, 0x3877c000, 0x3877e000, 0x38780000, 0x38782000,
|
||||
0x38784000, 0x38786000, 0x38788000, 0x3878a000, 0x3878c000, 0x3878e000,
|
||||
0x38790000, 0x38792000, 0x38794000, 0x38796000, 0x38798000, 0x3879a000,
|
||||
0x3879c000, 0x3879e000, 0x387a0000, 0x387a2000, 0x387a4000, 0x387a6000,
|
||||
0x387a8000, 0x387aa000, 0x387ac000, 0x387ae000, 0x387b0000, 0x387b2000,
|
||||
0x387b4000, 0x387b6000, 0x387b8000, 0x387ba000, 0x387bc000, 0x387be000,
|
||||
0x387c0000, 0x387c2000, 0x387c4000, 0x387c6000, 0x387c8000, 0x387ca000,
|
||||
0x387cc000, 0x387ce000, 0x387d0000, 0x387d2000, 0x387d4000, 0x387d6000,
|
||||
0x387d8000, 0x387da000, 0x387dc000, 0x387de000, 0x387e0000, 0x387e2000,
|
||||
0x387e4000, 0x387e6000, 0x387e8000, 0x387ea000, 0x387ec000, 0x387ee000,
|
||||
0x387f0000, 0x387f2000, 0x387f4000, 0x387f6000, 0x387f8000, 0x387fa000,
|
||||
0x387fc000, 0x387fe000
|
||||
};
|
||||
|
||||
static cmsUInt16Number Offset[64] = {
|
||||
0x0000, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400,
|
||||
0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400,
|
||||
0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400,
|
||||
0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400,
|
||||
0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400,
|
||||
0x0400, 0x0400, 0x0000, 0x0400, 0x0400, 0x0400,
|
||||
0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400,
|
||||
0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400,
|
||||
0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400,
|
||||
0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400,
|
||||
0x0400, 0x0400, 0x0400, 0x0400
|
||||
};
|
||||
|
||||
static cmsUInt32Number Exponent[64] = {
|
||||
0x00000000, 0x00800000, 0x01000000, 0x01800000, 0x02000000, 0x02800000,
|
||||
0x03000000, 0x03800000, 0x04000000, 0x04800000, 0x05000000, 0x05800000,
|
||||
0x06000000, 0x06800000, 0x07000000, 0x07800000, 0x08000000, 0x08800000,
|
||||
0x09000000, 0x09800000, 0x0a000000, 0x0a800000, 0x0b000000, 0x0b800000,
|
||||
0x0c000000, 0x0c800000, 0x0d000000, 0x0d800000, 0x0e000000, 0x0e800000,
|
||||
0x0f000000, 0x47800000, 0x80000000, 0x80800000, 0x81000000, 0x81800000,
|
||||
0x82000000, 0x82800000, 0x83000000, 0x83800000, 0x84000000, 0x84800000,
|
||||
0x85000000, 0x85800000, 0x86000000, 0x86800000, 0x87000000, 0x87800000,
|
||||
0x88000000, 0x88800000, 0x89000000, 0x89800000, 0x8a000000, 0x8a800000,
|
||||
0x8b000000, 0x8b800000, 0x8c000000, 0x8c800000, 0x8d000000, 0x8d800000,
|
||||
0x8e000000, 0x8e800000, 0x8f000000, 0xc7800000
|
||||
};
|
||||
|
||||
static cmsUInt16Number Base[512] = {
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040,
|
||||
0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x0c00, 0x1000, 0x1400, 0x1800, 0x1c00,
|
||||
0x2000, 0x2400, 0x2800, 0x2c00, 0x3000, 0x3400, 0x3800, 0x3c00, 0x4000, 0x4400,
|
||||
0x4800, 0x4c00, 0x5000, 0x5400, 0x5800, 0x5c00, 0x6000, 0x6400, 0x6800, 0x6c00,
|
||||
0x7000, 0x7400, 0x7800, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
|
||||
0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
|
||||
0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
|
||||
0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
|
||||
0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
|
||||
0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
|
||||
0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
|
||||
0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
|
||||
0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
|
||||
0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
|
||||
0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
|
||||
0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x8000, 0x8000, 0x8000, 0x8000,
|
||||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
|
||||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
|
||||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
|
||||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
|
||||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
|
||||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
|
||||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
|
||||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
|
||||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
|
||||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8001,
|
||||
0x8002, 0x8004, 0x8008, 0x8010, 0x8020, 0x8040, 0x8080, 0x8100, 0x8200, 0x8400,
|
||||
0x8800, 0x8c00, 0x9000, 0x9400, 0x9800, 0x9c00, 0xa000, 0xa400, 0xa800, 0xac00,
|
||||
0xb000, 0xb400, 0xb800, 0xbc00, 0xc000, 0xc400, 0xc800, 0xcc00, 0xd000, 0xd400,
|
||||
0xd800, 0xdc00, 0xe000, 0xe400, 0xe800, 0xec00, 0xf000, 0xf400, 0xf800, 0xfc00,
|
||||
0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
|
||||
0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
|
||||
0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
|
||||
0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
|
||||
0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
|
||||
0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
|
||||
0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
|
||||
0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
|
||||
0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
|
||||
0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
|
||||
0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
|
||||
0xfc00, 0xfc00
|
||||
};
|
||||
|
||||
static cmsUInt8Number Shift[512] = {
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x17,
|
||||
0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d,
|
||||
0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
|
||||
0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0d, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13,
|
||||
0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
|
||||
0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
|
||||
0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x0d
|
||||
};
|
||||
|
||||
cmsFloat32Number _cmsHalf2Float(cmsUInt16Number h)
|
||||
{
|
||||
union {
|
||||
cmsFloat32Number flt;
|
||||
cmsUInt32Number num;
|
||||
} out;
|
||||
|
||||
int n = h >> 10;
|
||||
|
||||
out.num = Mantissa[ (h & 0x3ff) + Offset[ n ] ] + Exponent[ n ];
|
||||
return out.flt;
|
||||
}
|
||||
|
||||
cmsUInt16Number _cmsFloat2Half(cmsFloat32Number flt)
|
||||
{
|
||||
union {
|
||||
cmsFloat32Number flt;
|
||||
cmsUInt32Number num;
|
||||
} in;
|
||||
|
||||
cmsUInt32Number n, j;
|
||||
|
||||
in.flt = flt;
|
||||
n = in.num;
|
||||
j = (n >> 23) & 0x1ff;
|
||||
|
||||
return (cmsUInt16Number) ((cmsUInt32Number) Base[ j ] + (( n & 0x007fffff) >> Shift[ j ]));
|
||||
}
|
||||
|
||||
#endif
|
||||
665
thirdparty/liblcms2/src/cmsintrp.c
vendored
665
thirdparty/liblcms2/src/cmsintrp.c
vendored
File diff suppressed because it is too large
Load Diff
774
thirdparty/liblcms2/src/cmsio0.c
vendored
774
thirdparty/liblcms2/src/cmsio0.c
vendored
File diff suppressed because it is too large
Load Diff
586
thirdparty/liblcms2/src/cmsio1.c
vendored
586
thirdparty/liblcms2/src/cmsio1.c
vendored
@@ -1,24 +1,24 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2012 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
|
||||
// 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
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
//---------------------------------------------------------------------------------
|
||||
@@ -56,9 +56,9 @@ static const cmsTagSignature PCS2DeviceFloat[] = {cmsSigBToD0Tag, // Percept
|
||||
|
||||
// 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 };
|
||||
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)
|
||||
@@ -67,7 +67,7 @@ cmsBool _cmsReadMediaWhitePoint(cmsCIEXYZ* Dest, cmsHPROFILE hProfile)
|
||||
|
||||
_cmsAssert(Dest != NULL);
|
||||
|
||||
Tag = (cmsCIEXYZ*) cmsReadTag(hProfile, cmsSigMediaWhitePointTag);
|
||||
Tag = (cmsCIEXYZ*) cmsReadTag(hProfile, cmsSigMediaWhitePointTag);
|
||||
|
||||
// If no wp, take D50
|
||||
if (Tag == NULL) {
|
||||
@@ -80,7 +80,7 @@ cmsBool _cmsReadMediaWhitePoint(cmsCIEXYZ* Dest, cmsHPROFILE hProfile)
|
||||
|
||||
if (cmsGetDeviceClass(hProfile) == cmsSigDisplayClass) {
|
||||
*Dest = *cmsD50_XYZ();
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +100,6 @@ cmsBool _cmsReadCHAD(cmsMAT3* Dest, cmsHPROFILE hProfile)
|
||||
Tag = (cmsMAT3*) cmsReadTag(hProfile, cmsSigChromaticAdaptationTag);
|
||||
|
||||
if (Tag != NULL) {
|
||||
|
||||
*Dest = *Tag;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -113,7 +112,7 @@ cmsBool _cmsReadCHAD(cmsMAT3* Dest, cmsHPROFILE hProfile)
|
||||
|
||||
if (cmsGetDeviceClass(hProfile) == cmsSigDisplayClass) {
|
||||
|
||||
cmsCIEXYZ* White = (cmsCIEXYZ*) cmsReadTag(hProfile, cmsSigMediaWhitePointTag);
|
||||
cmsCIEXYZ* White = (cmsCIEXYZ*) cmsReadTag(hProfile, cmsSigMediaWhitePointTag);
|
||||
|
||||
if (White == NULL) {
|
||||
|
||||
@@ -121,7 +120,7 @@ cmsBool _cmsReadCHAD(cmsMAT3* Dest, cmsHPROFILE hProfile)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return _cmsAdaptationMatrix(Dest, NULL, cmsD50_XYZ(), White);
|
||||
return _cmsAdaptationMatrix(Dest, NULL, White, cmsD50_XYZ());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +140,7 @@ cmsBool ReadICCMatrixRGB2XYZ(cmsMAT3* r, cmsHPROFILE hProfile)
|
||||
PtrGreen = (cmsCIEXYZ *) cmsReadTag(hProfile, cmsSigGreenColorantTag);
|
||||
PtrBlue = (cmsCIEXYZ *) cmsReadTag(hProfile, cmsSigBlueColorantTag);
|
||||
|
||||
if (PtrRed == NULL || PtrGreen == NULL || PtrBlue == NULL)
|
||||
if (PtrRed == NULL || PtrGreen == NULL || PtrBlue == NULL)
|
||||
return FALSE;
|
||||
|
||||
_cmsVEC3init(&r -> v[0], PtrRed -> X, PtrGreen -> X, PtrBlue -> X);
|
||||
@@ -159,12 +158,13 @@ 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 (Lut == NULL)
|
||||
goto Error;
|
||||
|
||||
if (cmsGetPCS(hProfile) == cmsSigLabData) {
|
||||
|
||||
@@ -172,31 +172,38 @@ cmsPipeline* BuildGrayInputMatrixPipeline(cmsHPROFILE hProfile)
|
||||
cmsUInt16Number Zero[2] = { 0x8080, 0x8080 };
|
||||
cmsToneCurve* EmptyTab;
|
||||
cmsToneCurve* LabCurves[3];
|
||||
|
||||
EmptyTab = cmsBuildTabulatedToneCurve16(ContextID, 2, Zero);
|
||||
|
||||
if (EmptyTab == NULL) {
|
||||
EmptyTab = cmsBuildTabulatedToneCurve16(ContextID, 2, Zero);
|
||||
|
||||
cmsPipelineFree(Lut);
|
||||
return NULL;
|
||||
}
|
||||
if (EmptyTab == NULL)
|
||||
goto Error;
|
||||
|
||||
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));
|
||||
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 3, 1, OneToThreeInputMatrix, NULL)) ||
|
||||
!cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 3, LabCurves))) {
|
||||
cmsFreeToneCurve(EmptyTab);
|
||||
goto Error;
|
||||
}
|
||||
|
||||
cmsFreeToneCurve(EmptyTab);
|
||||
|
||||
}
|
||||
else {
|
||||
cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 1, &GrayTRC));
|
||||
cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 3, 1, GrayInputMatrix, NULL));
|
||||
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 1, &GrayTRC)) ||
|
||||
!cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 3, 1, GrayInputMatrix, NULL)))
|
||||
goto Error;
|
||||
}
|
||||
|
||||
|
||||
return Lut;
|
||||
|
||||
Error:
|
||||
cmsFreeToneCurve(GrayTRC);
|
||||
cmsPipelineFree(Lut);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// RGB Matrix shaper
|
||||
@@ -212,15 +219,15 @@ cmsPipeline* BuildRGBInputMatrixShaper(cmsHPROFILE hProfile)
|
||||
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
|
||||
// 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[0] = (cmsToneCurve *) cmsReadTag(hProfile, cmsSigRedTRCTag);
|
||||
Shapes[1] = (cmsToneCurve *) cmsReadTag(hProfile, cmsSigGreenTRCTag);
|
||||
Shapes[2] = (cmsToneCurve *) cmsReadTag(hProfile, cmsSigBlueTRCTag);
|
||||
|
||||
@@ -230,15 +237,76 @@ cmsPipeline* BuildRGBInputMatrixShaper(cmsHPROFILE hProfile)
|
||||
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));
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 3, Shapes)) ||
|
||||
!cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 3, 3, (cmsFloat64Number*) &Mat, NULL)))
|
||||
goto Error;
|
||||
|
||||
// Note that it is certainly possible a single profile would have a LUT based
|
||||
// tag for output working in lab and a matrix-shaper for the fallback cases.
|
||||
// This is not allowed by the spec, but this code is tolerant to those cases
|
||||
if (cmsGetPCS(hProfile) == cmsSigLabData) {
|
||||
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocXYZ2Lab(ContextID)))
|
||||
goto Error;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return Lut;
|
||||
|
||||
Error:
|
||||
cmsPipelineFree(Lut);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Read the DToAX tag, adjusting the encoding of Lab or XYZ if neded
|
||||
static
|
||||
cmsPipeline* _cmsReadFloatInputTag(cmsHPROFILE hProfile, cmsTagSignature tagFloat)
|
||||
{
|
||||
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
||||
cmsPipeline* Lut = cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat));
|
||||
cmsColorSpaceSignature spc = cmsGetColorSpace(hProfile);
|
||||
cmsColorSpaceSignature PCS = cmsGetPCS(hProfile);
|
||||
|
||||
if (Lut == NULL) return NULL;
|
||||
|
||||
// input and output of transform are in lcms 0..1 encoding. If XYZ or Lab spaces are used,
|
||||
// these need to be normalized into the appropriate ranges (Lab = 100,0,0, XYZ=1.0,1.0,1.0)
|
||||
if ( spc == cmsSigLabData)
|
||||
{
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToLabFloat(ContextID)))
|
||||
goto Error;
|
||||
}
|
||||
else if (spc == cmsSigXYZData)
|
||||
{
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToXyzFloat(ContextID)))
|
||||
goto Error;
|
||||
}
|
||||
|
||||
if ( PCS == cmsSigLabData)
|
||||
{
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromLabFloat(ContextID)))
|
||||
goto Error;
|
||||
}
|
||||
else if( PCS == cmsSigXYZData)
|
||||
{
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromXyzFloat(ContextID)))
|
||||
goto Error;
|
||||
}
|
||||
|
||||
return Lut;
|
||||
|
||||
Error:
|
||||
cmsPipelineFree(Lut);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// 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
|
||||
// is adjusted here in order to create a LUT that takes care of all those details.
|
||||
// We add intent = -1 as a way to read matrix shaper always, no matter of other LUT
|
||||
cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent)
|
||||
{
|
||||
cmsTagTypeSignature OriginalType;
|
||||
@@ -246,57 +314,95 @@ cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent)
|
||||
cmsTagSignature tagFloat = Device2PCSFloat[Intent];
|
||||
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
||||
|
||||
if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
|
||||
// On named color, take the appropiate tag
|
||||
if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) {
|
||||
|
||||
// Floating point LUT are always V4, so no adjustment is required
|
||||
return cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat));
|
||||
}
|
||||
cmsPipeline* Lut;
|
||||
cmsNAMEDCOLORLIST* nc = (cmsNAMEDCOLORLIST*) cmsReadTag(hProfile, cmsSigNamedColor2Tag);
|
||||
|
||||
// Revert to perceptual if no tag is found
|
||||
if (!cmsIsTag(hProfile, tag16)) {
|
||||
tag16 = Device2PCS16[0];
|
||||
}
|
||||
if (nc == NULL) return NULL;
|
||||
|
||||
if (cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table?
|
||||
Lut = cmsPipelineAlloc(ContextID, 0, 0);
|
||||
if (Lut == NULL) {
|
||||
cmsFreeNamedColorList(nc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 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));
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocNamedColor(nc, TRUE)) ||
|
||||
!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID))) {
|
||||
cmsPipelineFree(Lut);
|
||||
return NULL;
|
||||
}
|
||||
return Lut;
|
||||
}
|
||||
}
|
||||
|
||||
// This is an attempt to reuse this funtion to retrieve the matrix-shaper as pipeline no
|
||||
// matter other LUT are present and have precedence. Intent = -1 means just this.
|
||||
if (Intent != -1) {
|
||||
|
||||
if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
|
||||
|
||||
// Floating point LUT are always V4, but the encoding range is no
|
||||
// longer 0..1.0, so we need to add an stage depending on the color space
|
||||
return _cmsReadFloatInputTag(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;
|
||||
|
||||
// If the input is Lab, add also a conversion at the begin
|
||||
if (cmsGetColorSpace(hProfile) == cmsSigLabData &&
|
||||
!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID)))
|
||||
goto Error;
|
||||
|
||||
// Add a matrix for conversion V2 to V4 Lab PCS
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID)))
|
||||
goto Error;
|
||||
|
||||
return Lut;
|
||||
Error:
|
||||
cmsPipelineFree(Lut);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
// if so, build appropiate conversion tables.
|
||||
// The tables are the PCS iluminant, scaled across GrayTRC
|
||||
return BuildGrayInputMatrixPipeline(hProfile);
|
||||
return BuildGrayInputMatrixPipeline(hProfile);
|
||||
}
|
||||
|
||||
// Not gray, create a normal matrix-shaper
|
||||
// Not gray, create a normal matrix-shaper
|
||||
return BuildRGBInputMatrixShaper(hProfile);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Gray output pipeline.
|
||||
// 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.
|
||||
@@ -308,7 +414,7 @@ cmsPipeline* BuildGrayOutputPipeline(cmsHPROFILE hProfile)
|
||||
cmsPipeline* Lut;
|
||||
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
||||
|
||||
GrayTRC = (cmsToneCurve *) cmsReadTag(hProfile, cmsSigGrayTRCTag);
|
||||
GrayTRC = (cmsToneCurve *) cmsReadTag(hProfile, cmsSigGrayTRCTag);
|
||||
if (GrayTRC == NULL) return NULL;
|
||||
|
||||
RevGrayTRC = cmsReverseToneCurve(GrayTRC);
|
||||
@@ -322,21 +428,27 @@ cmsPipeline* BuildGrayOutputPipeline(cmsHPROFILE hProfile)
|
||||
|
||||
if (cmsGetPCS(hProfile) == cmsSigLabData) {
|
||||
|
||||
cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 1, 3, PickLstarMatrix, NULL));
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 1, 3, PickLstarMatrix, NULL)))
|
||||
goto Error;
|
||||
}
|
||||
else {
|
||||
cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 1, 3, PickYMatrix, NULL));
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 1, 3, PickYMatrix, NULL)))
|
||||
goto Error;
|
||||
}
|
||||
|
||||
cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 1, &RevGrayTRC));
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 1, &RevGrayTRC)))
|
||||
goto Error;
|
||||
|
||||
cmsFreeToneCurve(RevGrayTRC);
|
||||
|
||||
return Lut;
|
||||
|
||||
Error:
|
||||
cmsFreeToneCurve(RevGrayTRC);
|
||||
cmsPipelineFree(Lut);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static
|
||||
cmsPipeline* BuildRGBOutputMatrixShaper(cmsHPROFILE hProfile)
|
||||
{
|
||||
@@ -353,14 +465,14 @@ cmsPipeline* BuildRGBOutputMatrixShaper(cmsHPROFILE hProfile)
|
||||
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
|
||||
// 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[0] = (cmsToneCurve *) cmsReadTag(hProfile, cmsSigRedTRCTag);
|
||||
Shapes[1] = (cmsToneCurve *) cmsReadTag(hProfile, cmsSigGreenTRCTag);
|
||||
Shapes[2] = (cmsToneCurve *) cmsReadTag(hProfile, cmsSigBlueTRCTag);
|
||||
|
||||
@@ -371,19 +483,33 @@ cmsPipeline* BuildRGBOutputMatrixShaper(cmsHPROFILE hProfile)
|
||||
InvShapes[1] = cmsReverseToneCurve(Shapes[1]);
|
||||
InvShapes[2] = cmsReverseToneCurve(Shapes[2]);
|
||||
|
||||
if (!InvShapes[0] || !InvShapes[1] || !InvShapes[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));
|
||||
// Note that it is certainly possible a single profile would have a LUT based
|
||||
// tag for output working in lab and a matrix-shaper for the fallback cases.
|
||||
// This is not allowed by the spec, but this code is tolerant to those cases
|
||||
if (cmsGetPCS(hProfile) == cmsSigLabData) {
|
||||
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLab2XYZ(ContextID)))
|
||||
goto Error;
|
||||
}
|
||||
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 3, 3, (cmsFloat64Number*) &Inv, NULL)) ||
|
||||
!cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 3, InvShapes)))
|
||||
goto Error;
|
||||
}
|
||||
|
||||
cmsFreeToneCurveTriple(InvShapes);
|
||||
return Lut;
|
||||
Error:
|
||||
cmsFreeToneCurveTriple(InvShapes);
|
||||
cmsPipelineFree(Lut);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -402,11 +528,56 @@ void ChangeInterpolationToTrilinear(cmsPipeline* Lut)
|
||||
_cmsStageCLutData* CLUT = (_cmsStageCLutData*) Stage ->Data;
|
||||
|
||||
CLUT ->Params->dwFlags |= CMS_LERP_FLAGS_TRILINEAR;
|
||||
_cmsSetInterpolationRoutine(CLUT ->Params);
|
||||
_cmsSetInterpolationRoutine(Lut->ContextID, CLUT ->Params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Read the DToAX tag, adjusting the encoding of Lab or XYZ if neded
|
||||
static
|
||||
cmsPipeline* _cmsReadFloatOutputTag(cmsHPROFILE hProfile, cmsTagSignature tagFloat)
|
||||
{
|
||||
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
||||
cmsPipeline* Lut = cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat));
|
||||
cmsColorSpaceSignature PCS = cmsGetPCS(hProfile);
|
||||
cmsColorSpaceSignature dataSpace = cmsGetColorSpace(hProfile);
|
||||
|
||||
if (Lut == NULL) return NULL;
|
||||
|
||||
// If PCS is Lab or XYZ, the floating point tag is accepting data in the space encoding,
|
||||
// and since the formatter has already accomodated to 0..1.0, we should undo this change
|
||||
if ( PCS == cmsSigLabData)
|
||||
{
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToLabFloat(ContextID)))
|
||||
goto Error;
|
||||
}
|
||||
else
|
||||
if (PCS == cmsSigXYZData)
|
||||
{
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToXyzFloat(ContextID)))
|
||||
goto Error;
|
||||
}
|
||||
|
||||
// the output can be Lab or XYZ, in which case normalisation is needed on the end of the pipeline
|
||||
if ( dataSpace == cmsSigLabData)
|
||||
{
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromLabFloat(ContextID)))
|
||||
goto Error;
|
||||
}
|
||||
else if (dataSpace == cmsSigXYZData)
|
||||
{
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromXyzFloat(ContextID)))
|
||||
goto Error;
|
||||
}
|
||||
|
||||
return Lut;
|
||||
|
||||
Error:
|
||||
cmsPipelineFree(Lut);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Create an output MPE LUT from agiven profile. Version mismatches are handled here
|
||||
cmsPipeline* _cmsReadOutputLUT(cmsHPROFILE hProfile, int Intent)
|
||||
{
|
||||
@@ -415,63 +586,118 @@ cmsPipeline* _cmsReadOutputLUT(cmsHPROFILE hProfile, int 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));
|
||||
}
|
||||
if (Intent != -1) {
|
||||
|
||||
// Revert to perceptual if no tag is found
|
||||
if (!cmsIsTag(hProfile, tag16)) {
|
||||
tag16 = PCS2Device16[0];
|
||||
}
|
||||
if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
|
||||
|
||||
if (cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table?
|
||||
// Floating point LUT are always V4
|
||||
return _cmsReadFloatOutputTag(hProfile, tagFloat);
|
||||
}
|
||||
|
||||
// Check profile version and LUT type. Do the necessary adjustments if needed
|
||||
// Revert to perceptual if no tag is found
|
||||
if (!cmsIsTag(hProfile, tag16)) {
|
||||
tag16 = PCS2Device16[0];
|
||||
}
|
||||
|
||||
// First read the tag
|
||||
cmsPipeline* Lut = (cmsPipeline*) cmsReadTag(hProfile, tag16);
|
||||
if (Lut == NULL) return NULL;
|
||||
if (cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table?
|
||||
|
||||
// After reading it, we have info about the original type
|
||||
OriginalType = _cmsGetTagTrueType(hProfile, tag16);
|
||||
// Check profile version and LUT type. Do the necessary adjustments if needed
|
||||
|
||||
// The profile owns the Lut, so we need to copy it
|
||||
Lut = cmsPipelineDup(Lut);
|
||||
if (Lut == NULL) return NULL;
|
||||
// First read the tag
|
||||
cmsPipeline* Lut = (cmsPipeline*) cmsReadTag(hProfile, tag16);
|
||||
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);
|
||||
// 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
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID)))
|
||||
goto Error;
|
||||
|
||||
// If the output is Lab, add also a conversion at the end
|
||||
if (cmsGetColorSpace(hProfile) == cmsSigLabData)
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID)))
|
||||
goto Error;
|
||||
|
||||
// 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;
|
||||
}
|
||||
Error:
|
||||
cmsPipelineFree(Lut);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Lut not found, try to create a matrix-shaper
|
||||
|
||||
// Check if this is a grayscale profile.
|
||||
if (cmsGetColorSpace(hProfile) == cmsSigGrayData) {
|
||||
if (cmsGetColorSpace(hProfile) == cmsSigGrayData) {
|
||||
|
||||
// if so, build appropiate conversion tables.
|
||||
// The tables are the PCS iluminant, scaled across GrayTRC
|
||||
return BuildGrayOutputPipeline(hProfile);
|
||||
// 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
|
||||
// Not gray, create a normal matrix-shaper, which only operates in XYZ space
|
||||
return BuildRGBOutputMatrixShaper(hProfile);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// This one includes abstract profiles as well. Matrix-shaper cannot be obtained on that device class. The
|
||||
// Read the AToD0 tag, adjusting the encoding of Lab or XYZ if neded
|
||||
static
|
||||
cmsPipeline* _cmsReadFloatDevicelinkTag(cmsHPROFILE hProfile, cmsTagSignature tagFloat)
|
||||
{
|
||||
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
||||
cmsPipeline* Lut = cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat));
|
||||
cmsColorSpaceSignature PCS = cmsGetPCS(hProfile);
|
||||
cmsColorSpaceSignature spc = cmsGetColorSpace(hProfile);
|
||||
|
||||
if (Lut == NULL) return NULL;
|
||||
|
||||
if (spc == cmsSigLabData)
|
||||
{
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToLabFloat(ContextID)))
|
||||
goto Error;
|
||||
}
|
||||
else
|
||||
if (spc == cmsSigXYZData)
|
||||
{
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToXyzFloat(ContextID)))
|
||||
goto Error;
|
||||
}
|
||||
|
||||
if (PCS == cmsSigLabData)
|
||||
{
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromLabFloat(ContextID)))
|
||||
goto Error;
|
||||
}
|
||||
else
|
||||
if (PCS == cmsSigXYZData)
|
||||
{
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromXyzFloat(ContextID)))
|
||||
goto Error;
|
||||
}
|
||||
|
||||
return Lut;
|
||||
Error:
|
||||
cmsPipelineFree(Lut);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
@@ -481,22 +707,48 @@ cmsPipeline* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent)
|
||||
cmsTagSignature tagFloat = Device2PCSFloat[Intent];
|
||||
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
||||
|
||||
|
||||
// On named color, take the appropiate tag
|
||||
if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) {
|
||||
|
||||
cmsNAMEDCOLORLIST* nc = (cmsNAMEDCOLORLIST*) cmsReadTag(hProfile, cmsSigNamedColor2Tag);
|
||||
|
||||
if (nc == NULL) return NULL;
|
||||
|
||||
Lut = cmsPipelineAlloc(ContextID, 0, 0);
|
||||
if (Lut == NULL)
|
||||
goto Error;
|
||||
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocNamedColor(nc, FALSE)))
|
||||
goto Error;
|
||||
|
||||
if (cmsGetColorSpace(hProfile) == cmsSigLabData)
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID)))
|
||||
goto Error;
|
||||
|
||||
return Lut;
|
||||
Error:
|
||||
cmsPipelineFree(Lut);
|
||||
cmsFreeNamedColorList(nc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
|
||||
|
||||
// Floating point LUT are always V4, no adjustment is required
|
||||
return cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat));
|
||||
// Floating point LUT are always V
|
||||
return _cmsReadFloatDevicelinkTag(hProfile, tagFloat);
|
||||
}
|
||||
|
||||
tagFloat = Device2PCSFloat[0];
|
||||
if (cmsIsTag(hProfile, tagFloat)) {
|
||||
|
||||
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;
|
||||
if (!cmsIsTag(hProfile, tag16)) return NULL;
|
||||
}
|
||||
|
||||
// Check profile version and LUT type. Do the necessary adjustments if needed
|
||||
@@ -509,41 +761,45 @@ cmsPipeline* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent)
|
||||
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);
|
||||
// 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);
|
||||
|
||||
// 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) {
|
||||
if(!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID)))
|
||||
goto Error2;
|
||||
}
|
||||
|
||||
if (cmsGetColorSpace(hProfile) == cmsSigLabData) {
|
||||
cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID));
|
||||
if (cmsGetPCS(hProfile) == cmsSigLabData) {
|
||||
if(!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID)))
|
||||
goto Error2;
|
||||
}
|
||||
|
||||
return Lut;
|
||||
|
||||
|
||||
Error2:
|
||||
cmsPipelineFree(Lut);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// 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:
|
||||
@@ -563,7 +819,7 @@ cmsBool CMSEXPORT cmsIsMatrixShaper(cmsHPROFILE hProfile)
|
||||
|
||||
// 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
|
||||
@@ -574,10 +830,10 @@ cmsBool CMSEXPORT cmsIsCLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUI
|
||||
switch (UsedDirection) {
|
||||
|
||||
case LCMS_USED_AS_INPUT: TagTable = Device2PCS16; break;
|
||||
case LCMS_USED_AS_OUTPUT:TagTable = PCS2Device16; 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:
|
||||
case LCMS_USED_AS_PROOF:
|
||||
return cmsIsIntentSupported(hProfile, Intent, LCMS_USED_AS_INPUT) &&
|
||||
cmsIsIntentSupported(hProfile, INTENT_RELATIVE_COLORIMETRIC, LCMS_USED_AS_OUTPUT);
|
||||
|
||||
@@ -611,7 +867,6 @@ cmsBool CMSEXPORT cmsIsIntentSupported(cmsHPROFILE 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;
|
||||
@@ -621,7 +876,7 @@ cmsSEQ* _cmsReadProfileSequence(cmsHPROFILE hProfile)
|
||||
|
||||
// Take profile sequence description first
|
||||
ProfileSeq = (cmsSEQ*) cmsReadTag(hProfile, cmsSigProfileSequenceDescTag);
|
||||
|
||||
|
||||
// Take profile sequence ID
|
||||
ProfileId = (cmsSEQ*) cmsReadTag(hProfile, cmsSigProfileSequenceIdTag);
|
||||
|
||||
@@ -630,18 +885,19 @@ cmsSEQ* _cmsReadProfileSequence(cmsHPROFILE hProfile)
|
||||
if (ProfileSeq == NULL) return cmsDupProfileSequenceDescription(ProfileId);
|
||||
if (ProfileId == NULL) return cmsDupProfileSequenceDescription(ProfileSeq);
|
||||
|
||||
// We have to mix both together. For that they must agree
|
||||
// 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);
|
||||
}
|
||||
|
||||
// Ok, proceed to the mixing
|
||||
if (NewSeq != NULL) {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -682,22 +938,22 @@ cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfil
|
||||
cmsPSEQDESC* ps = &seq ->seq[i];
|
||||
cmsHPROFILE h = hProfiles[i];
|
||||
cmsTechnologySignature* techpt;
|
||||
|
||||
|
||||
cmsGetHeaderAttributes(h, &ps ->attributes);
|
||||
cmsGetHeaderProfileID(h, ps ->ProfileID.ID8);
|
||||
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 ->Model = GetMLUFromProfile(h, cmsSigDeviceModelDescTag);
|
||||
ps ->Description = GetMLUFromProfile(h, cmsSigProfileDescriptionTag);
|
||||
|
||||
|
||||
}
|
||||
|
||||
return seq;
|
||||
@@ -714,7 +970,7 @@ const cmsMLU* GetInfo(cmsHPROFILE hProfile, cmsInfoType Info)
|
||||
switch (Info) {
|
||||
|
||||
case cmsInfoDescription:
|
||||
sig = cmsSigProfileDescriptionTag;
|
||||
sig = cmsSigProfileDescriptionTag;
|
||||
break;
|
||||
|
||||
case cmsInfoManufacturer:
|
||||
@@ -738,8 +994,8 @@ const cmsMLU* GetInfo(cmsHPROFILE hProfile, cmsInfoType Info)
|
||||
|
||||
|
||||
|
||||
cmsUInt32Number CMSEXPORT cmsGetProfileInfo(cmsHPROFILE hProfile, cmsInfoType Info,
|
||||
const char LanguageCode[3], const char CountryCode[3],
|
||||
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);
|
||||
@@ -749,8 +1005,8 @@ cmsUInt32Number CMSEXPORT cmsGetProfileInfo(cmsHPROFILE hProfile, cmsInfoType In
|
||||
}
|
||||
|
||||
|
||||
cmsUInt32Number CMSEXPORT cmsGetProfileInfoASCII(cmsHPROFILE hProfile, cmsInfoType Info,
|
||||
const char LanguageCode[3], const char CountryCode[3],
|
||||
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);
|
||||
|
||||
640
thirdparty/liblcms2/src/cmslut.c
vendored
640
thirdparty/liblcms2/src/cmslut.c
vendored
File diff suppressed because it is too large
Load Diff
48
thirdparty/liblcms2/src/cmsmd5.c
vendored
48
thirdparty/liblcms2/src/cmsmd5.c
vendored
@@ -1,24 +1,24 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2012 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
|
||||
// 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
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
//---------------------------------------------------------------------------------
|
||||
@@ -42,7 +42,7 @@ void byteReverse(cmsUInt8Number * buf, cmsUInt32Number longs)
|
||||
}
|
||||
|
||||
#else
|
||||
#define byteReverse(buf, len)
|
||||
#define byteReverse(buf, len)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ typedef struct {
|
||||
|
||||
static
|
||||
void MD5_Transform(cmsUInt32Number buf[4], cmsUInt32Number in[16])
|
||||
|
||||
|
||||
{
|
||||
register cmsUInt32Number a, b, c, d;
|
||||
|
||||
@@ -176,14 +176,14 @@ 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]++;
|
||||
|
||||
ctx->bits[1] += len >> 29;
|
||||
|
||||
t = (t >> 3) & 0x3f;
|
||||
t = (t >> 3) & 0x3f;
|
||||
|
||||
if (t) {
|
||||
|
||||
@@ -265,15 +265,15 @@ cmsBool CMSEXPORT cmsMD5computeID(cmsHPROFILE hProfile)
|
||||
cmsUInt8Number* Mem = NULL;
|
||||
cmsHANDLE MD5 = NULL;
|
||||
_cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile;
|
||||
_cmsICCPROFILE Keep;
|
||||
_cmsICCPROFILE Keep;
|
||||
|
||||
_cmsAssert(hProfile != NULL);
|
||||
_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;
|
||||
@@ -288,7 +288,7 @@ cmsBool CMSEXPORT cmsMD5computeID(cmsHPROFILE hProfile)
|
||||
|
||||
// Save to temporary storage
|
||||
if (!cmsSaveProfileToMem(hProfile, Mem, &BytesNeeded)) goto Error;
|
||||
|
||||
|
||||
// Create MD5 object
|
||||
MD5 = MD5alloc(ContextID);
|
||||
if (MD5 == NULL) goto Error;
|
||||
@@ -298,7 +298,7 @@ cmsBool CMSEXPORT cmsMD5computeID(cmsHPROFILE hProfile)
|
||||
|
||||
// Temp storage is no longer needed
|
||||
_cmsFree(ContextID, Mem);
|
||||
|
||||
|
||||
// Restore header
|
||||
memmove(Icc, &Keep, sizeof(_cmsICCPROFILE));
|
||||
|
||||
@@ -309,7 +309,7 @@ cmsBool CMSEXPORT cmsMD5computeID(cmsHPROFILE hProfile)
|
||||
Error:
|
||||
|
||||
// Free resources as something went wrong
|
||||
if (MD5 != NULL) _cmsFree(ContextID, MD5);
|
||||
// "MD5" cannot be other than NULL here, so no need to free it
|
||||
if (Mem != NULL) _cmsFree(ContextID, Mem);
|
||||
memmove(Icc, &Keep, sizeof(_cmsICCPROFILE));
|
||||
return FALSE;
|
||||
|
||||
44
thirdparty/liblcms2/src/cmsmtrx.c
vendored
44
thirdparty/liblcms2/src/cmsmtrx.c
vendored
@@ -1,24 +1,24 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2012 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
|
||||
// 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
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
//---------------------------------------------------------------------------------
|
||||
@@ -30,7 +30,7 @@
|
||||
#define DSWAP(x, y) {cmsFloat64Number tmp = (x); (x)=(y); (y)=tmp;}
|
||||
|
||||
|
||||
// Initiate a vector
|
||||
// Initiate a vector
|
||||
void CMSEXPORT _cmsVEC3init(cmsVEC3* r, cmsFloat64Number x, cmsFloat64Number y, cmsFloat64Number z)
|
||||
{
|
||||
r -> n[VX] = x;
|
||||
@@ -60,7 +60,7 @@ 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
|
||||
// Euclidean length
|
||||
cmsFloat64Number CMSEXPORT _cmsVEC3length(const cmsVEC3* a)
|
||||
{
|
||||
return sqrt(a ->n[VX] * a ->n[VX] +
|
||||
@@ -97,16 +97,16 @@ cmsBool CloseEnough(cmsFloat64Number a, cmsFloat64Number b)
|
||||
|
||||
cmsBool CMSEXPORT _cmsMAT3isIdentity(const cmsMAT3* a)
|
||||
{
|
||||
cmsMAT3 Identity;
|
||||
int i, j;
|
||||
cmsMAT3 Identity;
|
||||
int i, j;
|
||||
|
||||
_cmsMAT3identity(&Identity);
|
||||
_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;
|
||||
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;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
585
thirdparty/liblcms2/src/cmsnamed.c
vendored
585
thirdparty/liblcms2/src/cmsnamed.c
vendored
@@ -1,24 +1,24 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2012 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
|
||||
// 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
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
//---------------------------------------------------------------------------------
|
||||
@@ -32,81 +32,81 @@
|
||||
// Allocates an empty multi localizad unicode object
|
||||
cmsMLU* CMSEXPORT cmsMLUalloc(cmsContext ContextID, cmsUInt32Number nItems)
|
||||
{
|
||||
cmsMLU* mlu;
|
||||
cmsMLU* mlu;
|
||||
|
||||
// nItems should be positive if given
|
||||
if (nItems <= 0) nItems = 2;
|
||||
// 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;
|
||||
// Create the container
|
||||
mlu = (cmsMLU*) _cmsMallocZero(ContextID, sizeof(cmsMLU));
|
||||
if (mlu == NULL) return NULL;
|
||||
|
||||
mlu ->ContextID = ContextID;
|
||||
mlu ->ContextID = ContextID;
|
||||
|
||||
// Create entry array
|
||||
mlu ->Entries = (_cmsMLUentry*) _cmsCalloc(ContextID, nItems, sizeof(_cmsMLUentry));
|
||||
if (mlu ->Entries == NULL) {
|
||||
_cmsFree(ContextID, mlu);
|
||||
return NULL;
|
||||
}
|
||||
// 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;
|
||||
// Ok, keep indexes up to date
|
||||
mlu ->AllocatedEntries = nItems;
|
||||
mlu ->UsedEntries = 0;
|
||||
|
||||
return mlu;
|
||||
return mlu;
|
||||
}
|
||||
|
||||
|
||||
// Grows a mempool table for a MLU. Each time this function is called, mempool size is multiplied times two.
|
||||
// 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;
|
||||
cmsUInt32Number size;
|
||||
void *NewPtr;
|
||||
|
||||
// Sanity check
|
||||
if (mlu == NULL) return FALSE;
|
||||
// Sanity check
|
||||
if (mlu == NULL) return FALSE;
|
||||
|
||||
if (mlu ->PoolSize == 0)
|
||||
size = 256;
|
||||
else
|
||||
size = mlu ->PoolSize * 2;
|
||||
if (mlu ->PoolSize == 0)
|
||||
size = 256;
|
||||
else
|
||||
size = mlu ->PoolSize * 2;
|
||||
|
||||
// Check for overflow
|
||||
if (size < mlu ->PoolSize) return FALSE;
|
||||
// Check for overflow
|
||||
if (size < mlu ->PoolSize) return FALSE;
|
||||
|
||||
// Reallocate the pool
|
||||
NewPtr = _cmsRealloc(mlu ->ContextID, mlu ->MemPool, size);
|
||||
if (NewPtr == NULL) return FALSE;
|
||||
// Reallocate the pool
|
||||
NewPtr = _cmsRealloc(mlu ->ContextID, mlu ->MemPool, size);
|
||||
if (NewPtr == NULL) return FALSE;
|
||||
|
||||
|
||||
mlu ->MemPool = NewPtr;
|
||||
mlu ->PoolSize = size;
|
||||
mlu ->MemPool = NewPtr;
|
||||
mlu ->PoolSize = size;
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Grows a ntry table for a MLU. Each time this function is called, table size is multiplied times two.
|
||||
// Grows a entry 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;
|
||||
|
||||
// Sanity check
|
||||
if (mlu == NULL) return FALSE;
|
||||
|
||||
AllocatedEntries = mlu ->AllocatedEntries * 2;
|
||||
|
||||
// Check for overflow
|
||||
if (AllocatedEntries / 2 != mlu ->AllocatedEntries) return FALSE;
|
||||
// Check for overflow
|
||||
if (AllocatedEntries / 2 != mlu ->AllocatedEntries) return FALSE;
|
||||
|
||||
// Reallocate the memory
|
||||
// Reallocate the memory
|
||||
NewPtr = (_cmsMLUentry*)_cmsRealloc(mlu ->ContextID, mlu ->Entries, AllocatedEntries*sizeof(_cmsMLUentry));
|
||||
if (NewPtr == NULL) return FALSE;
|
||||
|
||||
|
||||
mlu ->Entries = NewPtr;
|
||||
mlu ->AllocatedEntries = AllocatedEntries;
|
||||
|
||||
@@ -114,37 +114,37 @@ cmsBool GrowMLUtable(cmsMLU* mlu)
|
||||
}
|
||||
|
||||
|
||||
// Search for a specific entry in the structure. Language and Country are used.
|
||||
// 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
|
||||
// Sanity check
|
||||
if (mlu == NULL) return -1;
|
||||
|
||||
// Iterate whole table
|
||||
for (i=0; i < mlu ->UsedEntries; i++) {
|
||||
|
||||
if (mlu ->Entries[i].Country == CountryCode &&
|
||||
if (mlu ->Entries[i].Country == CountryCode &&
|
||||
mlu ->Entries[i].Language == LanguageCode) return i;
|
||||
}
|
||||
|
||||
// Not found
|
||||
// Not found
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Add a block of characters to the intended MLU. Language and country are specified.
|
||||
// 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,
|
||||
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;
|
||||
// Sanity check
|
||||
if (mlu == NULL) return FALSE;
|
||||
|
||||
// Is there any room available?
|
||||
if (mlu ->UsedEntries >= mlu ->AllocatedEntries) {
|
||||
@@ -155,20 +155,20 @@ cmsBool AddMLUBlock(cmsMLU* mlu, cmsUInt32Number size, const wchar_t *Block,
|
||||
if (SearchMLUEntry(mlu, LanguageCode, CountryCode) >= 0) return FALSE; // Only one is allowed!
|
||||
|
||||
// Check for size
|
||||
while ((mlu ->PoolSize - mlu ->PoolUsed) < 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
|
||||
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;
|
||||
@@ -179,7 +179,7 @@ cmsBool AddMLUBlock(cmsMLU* mlu, cmsUInt32Number size, const wchar_t *Block,
|
||||
}
|
||||
|
||||
|
||||
// Add an ASCII entry.
|
||||
// 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;
|
||||
@@ -195,21 +195,21 @@ cmsBool CMSEXPORT cmsMLUsetASCII(cmsMLU* mlu, const char LanguageCode[3], const
|
||||
|
||||
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
|
||||
static
|
||||
cmsUInt32Number mywcslen(const wchar_t *s)
|
||||
{
|
||||
const wchar_t *p;
|
||||
|
||||
p = s;
|
||||
p = s;
|
||||
while (*p)
|
||||
p++;
|
||||
|
||||
@@ -223,9 +223,9 @@ cmsBool CMSEXPORT cmsMLUsetWide(cmsMLU* mlu, const char Language[3], const char
|
||||
cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) Language);
|
||||
cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) Country);
|
||||
cmsUInt32Number len;
|
||||
|
||||
|
||||
if (mlu == NULL) return FALSE;
|
||||
if (WideString == NULL) return FALSE;
|
||||
if (WideString == NULL) return FALSE;
|
||||
|
||||
len = (cmsUInt32Number) (mywcslen(WideString) + 1) * sizeof(wchar_t);
|
||||
return AddMLUBlock(mlu, len, WideString, Lang, Cntry);
|
||||
@@ -234,73 +234,73 @@ cmsBool CMSEXPORT cmsMLUsetWide(cmsMLU* mlu, const char Language[3], const char
|
||||
// Duplicating a MLU is as easy as copying all members
|
||||
cmsMLU* CMSEXPORT cmsMLUdup(const cmsMLU* mlu)
|
||||
{
|
||||
cmsMLU* NewMlu = NULL;
|
||||
cmsMLU* NewMlu = NULL;
|
||||
|
||||
// Duplicating a NULL obtains a NULL
|
||||
if (mlu == NULL) return NULL;
|
||||
// Duplicating a NULL obtains a NULL
|
||||
if (mlu == NULL) return NULL;
|
||||
|
||||
NewMlu = cmsMLUalloc(mlu ->ContextID, mlu ->UsedEntries);
|
||||
if (NewMlu == NULL) return NULL;
|
||||
NewMlu = cmsMLUalloc(mlu ->ContextID, mlu ->UsedEntries);
|
||||
if (NewMlu == NULL) return NULL;
|
||||
|
||||
// Should never happen
|
||||
if (NewMlu ->AllocatedEntries < mlu ->UsedEntries)
|
||||
goto Error;
|
||||
// Should never happen
|
||||
if (NewMlu ->AllocatedEntries < mlu ->UsedEntries)
|
||||
goto Error;
|
||||
|
||||
// Sanitize...
|
||||
if (NewMlu ->Entries == NULL || mlu ->Entries == NULL) 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;
|
||||
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;
|
||||
}
|
||||
// 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;
|
||||
NewMlu ->PoolSize = mlu ->PoolUsed;
|
||||
|
||||
if (NewMlu ->MemPool == NULL || mlu ->MemPool == NULL) goto Error;
|
||||
if (NewMlu ->MemPool == NULL || mlu ->MemPool == NULL) goto Error;
|
||||
|
||||
memmove(NewMlu ->MemPool, mlu->MemPool, mlu ->PoolUsed);
|
||||
NewMlu ->PoolUsed = mlu ->PoolUsed;
|
||||
memmove(NewMlu ->MemPool, mlu->MemPool, mlu ->PoolUsed);
|
||||
NewMlu ->PoolUsed = mlu ->PoolUsed;
|
||||
|
||||
return NewMlu;
|
||||
return NewMlu;
|
||||
|
||||
Error:
|
||||
|
||||
if (NewMlu != NULL) cmsMLUfree(NewMlu);
|
||||
return NULL;
|
||||
if (NewMlu != NULL) cmsMLUfree(NewMlu);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Free any used memory
|
||||
void CMSEXPORT cmsMLUfree(cmsMLU* mlu)
|
||||
{
|
||||
if (mlu) {
|
||||
if (mlu) {
|
||||
|
||||
if (mlu -> Entries) _cmsFree(mlu ->ContextID, mlu->Entries);
|
||||
if (mlu -> MemPool) _cmsFree(mlu ->ContextID, mlu->MemPool);
|
||||
if (mlu -> Entries) _cmsFree(mlu ->ContextID, mlu->Entries);
|
||||
if (mlu -> MemPool) _cmsFree(mlu ->ContextID, mlu->MemPool);
|
||||
|
||||
_cmsFree(mlu ->ContextID, mlu);
|
||||
}
|
||||
_cmsFree(mlu ->ContextID, mlu);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// The algorithm first searches for an exact match of country and language, if not found it uses
|
||||
// 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)
|
||||
const wchar_t* _cmsMLUgetWide(const cmsMLU* mlu,
|
||||
cmsUInt32Number *len,
|
||||
cmsUInt16Number LanguageCode, cmsUInt16Number CountryCode,
|
||||
cmsUInt16Number* UsedLanguageCode, cmsUInt16Number* UsedCountryCode)
|
||||
{
|
||||
int i;
|
||||
int Best = -1;
|
||||
_cmsMLUentry* v;
|
||||
_cmsMLUentry* v;
|
||||
|
||||
if (mlu == NULL) return NULL;
|
||||
|
||||
@@ -316,12 +316,12 @@ const wchar_t* _cmsMLUgetWide(const cmsMLU* mlu,
|
||||
|
||||
if (v -> Country == CountryCode) {
|
||||
|
||||
if (UsedLanguageCode != NULL) *UsedLanguageCode = v ->Language;
|
||||
if (UsedCountryCode != NULL) *UsedCountryCode = v ->Country;
|
||||
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
|
||||
return (wchar_t*) ((cmsUInt8Number*) mlu ->MemPool + v -> StrW); // Found exact match
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -330,30 +330,30 @@ const wchar_t* _cmsMLUgetWide(const cmsMLU* mlu,
|
||||
if (Best == -1)
|
||||
Best = 0;
|
||||
|
||||
v = mlu ->Entries + Best;
|
||||
v = mlu ->Entries + Best;
|
||||
|
||||
if (UsedLanguageCode != NULL) *UsedLanguageCode = v ->Language;
|
||||
if (UsedCountryCode != NULL) *UsedCountryCode = v ->Country;
|
||||
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);
|
||||
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)
|
||||
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 Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode);
|
||||
cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode);
|
||||
|
||||
// Sanitize
|
||||
// Sanitize
|
||||
if (mlu == NULL) return 0;
|
||||
|
||||
// Get WideChar
|
||||
@@ -373,7 +373,7 @@ cmsUInt32Number CMSEXPORT cmsMLUgetASCII(const cmsMLU* mlu,
|
||||
ASCIIlen = BufferSize - 1;
|
||||
|
||||
// Precess each character
|
||||
for (i=0; i < ASCIIlen; i++) {
|
||||
for (i=0; i < ASCIIlen; i++) {
|
||||
|
||||
if (Wide[i] == 0)
|
||||
Buffer[i] = 0;
|
||||
@@ -381,28 +381,28 @@ cmsUInt32Number CMSEXPORT cmsMLUgetASCII(const cmsMLU* mlu,
|
||||
Buffer[i] = (char) Wide[i];
|
||||
}
|
||||
|
||||
// We put a termination "\0"
|
||||
// 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)
|
||||
// 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 Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode);
|
||||
cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode);
|
||||
|
||||
// Sanitize
|
||||
// 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);
|
||||
|
||||
@@ -414,35 +414,64 @@ cmsUInt32Number CMSEXPORT cmsMLUgetWide(const cmsMLU* mlu,
|
||||
StrLen = BufferSize - + sizeof(wchar_t);
|
||||
|
||||
memmove(Buffer, Wide, StrLen);
|
||||
Buffer[StrLen / sizeof(wchar_t)] = 0;
|
||||
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])
|
||||
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;
|
||||
const wchar_t *Wide;
|
||||
|
||||
// Sanitize
|
||||
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);
|
||||
if (Wide == NULL) return FALSE;
|
||||
|
||||
ObtainedLanguage[2] = ObtainedCountry[2] = 0;
|
||||
return TRUE;
|
||||
// Get used language and code
|
||||
*(cmsUInt16Number *)ObtainedLanguage = _cmsAdjustEndianess16(ObtLang);
|
||||
*(cmsUInt16Number *)ObtainedCountry = _cmsAdjustEndianess16(ObtCode);
|
||||
|
||||
ObtainedLanguage[2] = ObtainedCountry[2] = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Get the number of translations in the MLU object
|
||||
cmsUInt32Number CMSEXPORT cmsMLUtranslationsCount(const cmsMLU* mlu)
|
||||
{
|
||||
if (mlu == NULL) return 0;
|
||||
return mlu->UsedEntries;
|
||||
}
|
||||
|
||||
// Get the language and country codes for a specific MLU index
|
||||
cmsBool CMSEXPORT cmsMLUtranslationsCodes(const cmsMLU* mlu,
|
||||
cmsUInt32Number idx,
|
||||
char LanguageCode[3],
|
||||
char CountryCode[3])
|
||||
{
|
||||
_cmsMLUentry *entry;
|
||||
|
||||
if (mlu == NULL) return FALSE;
|
||||
|
||||
if (idx >= (cmsUInt32Number) mlu->UsedEntries) return FALSE;
|
||||
|
||||
entry = &mlu->Entries[idx];
|
||||
|
||||
*(cmsUInt16Number *)LanguageCode = _cmsAdjustEndianess16(entry->Language);
|
||||
*(cmsUInt16Number *)CountryCode = _cmsAdjustEndianess16(entry->Country);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -451,7 +480,7 @@ CMSAPI cmsBool CMSEXPORT cmsMLUgetTranslation(const cmsMLU* mlu,
|
||||
// Grow the list to keep at least NumElements
|
||||
static
|
||||
cmsBool GrowNamedColorList(cmsNAMEDCOLORLIST* v)
|
||||
{
|
||||
{
|
||||
cmsUInt32Number size;
|
||||
_cmsNAMEDCOLOR * NewPtr;
|
||||
|
||||
@@ -466,9 +495,9 @@ cmsBool GrowNamedColorList(cmsNAMEDCOLORLIST* v)
|
||||
if (size > 1024*100) return FALSE;
|
||||
|
||||
NewPtr = (_cmsNAMEDCOLOR*) _cmsRealloc(v ->ContextID, v ->List, size * sizeof(_cmsNAMEDCOLOR));
|
||||
if (NewPtr == NULL)
|
||||
if (NewPtr == NULL)
|
||||
return FALSE;
|
||||
|
||||
|
||||
v ->List = NewPtr;
|
||||
v ->Allocated = size;
|
||||
return TRUE;
|
||||
@@ -478,9 +507,9 @@ cmsBool GrowNamedColorList(cmsNAMEDCOLORLIST* v)
|
||||
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;
|
||||
@@ -488,8 +517,10 @@ cmsNAMEDCOLORLIST* CMSEXPORT cmsAllocNamedColorList(cmsContext ContextID, cmsUIn
|
||||
while (v -> Allocated < n)
|
||||
GrowNamedColorList(v);
|
||||
|
||||
strncpy(v ->Prefix, Prefix, sizeof(v ->Prefix));
|
||||
strncpy(v ->Suffix, Suffix, sizeof(v ->Suffix));
|
||||
strncpy(v ->Prefix, Prefix, sizeof(v ->Prefix)-1);
|
||||
strncpy(v ->Suffix, Suffix, sizeof(v ->Suffix)-1);
|
||||
v->Prefix[32] = v->Suffix[32] = 0;
|
||||
|
||||
v -> ColorantCount = ColorantCount;
|
||||
|
||||
return v;
|
||||
@@ -497,15 +528,16 @@ cmsNAMEDCOLORLIST* CMSEXPORT cmsAllocNamedColorList(cmsContext ContextID, cmsUIn
|
||||
|
||||
// Free a list
|
||||
void CMSEXPORT cmsFreeNamedColorList(cmsNAMEDCOLORLIST* v)
|
||||
{
|
||||
{
|
||||
if (v == NULL) return;
|
||||
if (v ->List) _cmsFree(v ->ContextID, v ->List);
|
||||
if (v) _cmsFree(v ->ContextID, 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);
|
||||
@@ -525,10 +557,10 @@ cmsNAMEDCOLORLIST* CMSEXPORT cmsDupNamedColorList(const cmsNAMEDCOLORLIST* v)
|
||||
|
||||
|
||||
// Append a color to a list. List pointer may change if reallocated
|
||||
cmsBool CMSEXPORT cmsAppendNamedColor(cmsNAMEDCOLORLIST* NamedColorList,
|
||||
const char* Name,
|
||||
cmsBool CMSEXPORT cmsAppendNamedColor(cmsNAMEDCOLORLIST* NamedColorList,
|
||||
const char* Name,
|
||||
cmsUInt16Number PCS[3], cmsUInt16Number Colorant[cmsMAXCHANNELS])
|
||||
{
|
||||
{
|
||||
cmsUInt32Number i;
|
||||
|
||||
if (NamedColorList == NULL) return FALSE;
|
||||
@@ -543,9 +575,12 @@ cmsBool CMSEXPORT cmsAppendNamedColor(cmsNAMEDCOLORLIST* NamedColorList,
|
||||
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));
|
||||
if (Name != NULL) {
|
||||
|
||||
strncpy(NamedColorList ->List[NamedColorList ->nColors].Name, Name, cmsMAX_PATH-1);
|
||||
NamedColorList ->List[NamedColorList ->nColors].Name[cmsMAX_PATH-1] = 0;
|
||||
|
||||
}
|
||||
else
|
||||
NamedColorList ->List[NamedColorList ->nColors].Name[0] = 0;
|
||||
|
||||
@@ -554,21 +589,21 @@ cmsBool CMSEXPORT cmsAppendNamedColor(cmsNAMEDCOLORLIST* NamedColorList,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Returns number of elements
|
||||
// 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,
|
||||
cmsBool CMSEXPORT cmsNamedColorInfo(const cmsNAMEDCOLORLIST* NamedColorList, cmsUInt32Number nColor,
|
||||
char* Name,
|
||||
char* Prefix,
|
||||
char* Suffix,
|
||||
cmsUInt16Number* PCS,
|
||||
cmsUInt16Number* PCS,
|
||||
cmsUInt16Number* Colorant)
|
||||
{
|
||||
{
|
||||
if (NamedColorList == NULL) return FALSE;
|
||||
|
||||
if (nColor >= cmsNamedColorCount(NamedColorList)) return FALSE;
|
||||
@@ -576,11 +611,11 @@ cmsBool CMSEXPORT cmsNamedColorInfo(const cmsNAMEDCOLORLIST* NamedColorList, cm
|
||||
if (Name) strcpy(Name, NamedColorList->List[nColor].Name);
|
||||
if (Prefix) strcpy(Prefix, NamedColorList->Prefix);
|
||||
if (Suffix) strcpy(Suffix, NamedColorList->Suffix);
|
||||
if (PCS)
|
||||
if (PCS)
|
||||
memmove(PCS, NamedColorList ->List[nColor].PCS, 3*sizeof(cmsUInt16Number));
|
||||
|
||||
if (Colorant)
|
||||
memmove(Colorant, NamedColorList ->List[nColor].DeviceColorant,
|
||||
if (Colorant)
|
||||
memmove(Colorant, NamedColorList ->List[nColor].DeviceColorant,
|
||||
sizeof(cmsUInt16Number) * NamedColorList ->ColorantCount);
|
||||
|
||||
|
||||
@@ -589,7 +624,7 @@ cmsBool CMSEXPORT cmsNamedColorInfo(const cmsNAMEDCOLORLIST* NamedColorList, cm
|
||||
|
||||
// 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;
|
||||
@@ -618,6 +653,24 @@ void* DupNamedColorList(cmsStage* mpe)
|
||||
return cmsDupNamedColorList(List);
|
||||
}
|
||||
|
||||
static
|
||||
void EvalNamedColorPCS(const cmsFloat32Number In[], cmsFloat32Number Out[], const cmsStage *mpe)
|
||||
{
|
||||
cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) mpe ->Data;
|
||||
cmsUInt16Number index = (cmsUInt16Number) _cmsQuickSaturateWord(In[0] * 65535.0);
|
||||
|
||||
if (index >= NamedColorList-> nColors) {
|
||||
cmsSignalError(NamedColorList ->ContextID, cmsERROR_RANGE, "Color %d out of range; ignored", index);
|
||||
}
|
||||
else {
|
||||
|
||||
// Named color always uses Lab
|
||||
Out[0] = (cmsFloat32Number) (NamedColorList->List[index].PCS[0] / 65535.0);
|
||||
Out[1] = (cmsFloat32Number) (NamedColorList->List[index].PCS[1] / 65535.0);
|
||||
Out[2] = (cmsFloat32Number) (NamedColorList->List[index].PCS[2] / 65535.0);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void EvalNamedColor(const cmsFloat32Number In[], cmsFloat32Number Out[], const cmsStage *mpe)
|
||||
{
|
||||
@@ -629,23 +682,23 @@ void EvalNamedColor(const cmsFloat32Number In[], cmsFloat32Number Out[], const c
|
||||
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);
|
||||
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)
|
||||
cmsStage* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS)
|
||||
{
|
||||
return _cmsStageAllocPlaceholder(NamedColorList ->ContextID,
|
||||
cmsSigNamedColorElemType,
|
||||
1, 3,
|
||||
EvalNamedColor,
|
||||
DupNamedColorList,
|
||||
FreeNamedColorList,
|
||||
cmsDupNamedColorList(NamedColorList));
|
||||
|
||||
return _cmsStageAllocPlaceholder(NamedColorList ->ContextID,
|
||||
cmsSigNamedColorElemType,
|
||||
1, UsePCS ? 3 : NamedColorList ->ColorantCount,
|
||||
UsePCS ? EvalNamedColorPCS : EvalNamedColor,
|
||||
DupNamedColorList,
|
||||
FreeNamedColorList,
|
||||
cmsDupNamedColorList(NamedColorList));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -674,19 +727,23 @@ cmsSEQ* CMSEXPORT cmsAllocProfileSequenceDescription(cmsContext ContextID, cmsUI
|
||||
if (n > 255) return NULL;
|
||||
|
||||
Seq = (cmsSEQ*) _cmsMallocZero(ContextID, sizeof(cmsSEQ));
|
||||
if (Seq == NULL) return NULL;
|
||||
|
||||
if (Seq == NULL) return NULL;
|
||||
|
||||
Seq -> ContextID = ContextID;
|
||||
Seq -> seq = (cmsPSEQDESC*) _cmsCalloc(ContextID, n, sizeof(cmsPSEQDESC));
|
||||
Seq -> n = n;
|
||||
|
||||
|
||||
if (Seq -> seq == NULL) {
|
||||
_cmsFree(ContextID, Seq);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i=0; i < n; i++) {
|
||||
Seq -> seq[i].Manufacturer = NULL;
|
||||
Seq -> seq[i].Model = NULL;
|
||||
Seq -> seq[i].Description = NULL;
|
||||
}
|
||||
|
||||
|
||||
return Seq;
|
||||
}
|
||||
|
||||
@@ -715,10 +772,10 @@ cmsSEQ* CMSEXPORT cmsDupProfileSequenceDescription(const cmsSEQ* pseq)
|
||||
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;
|
||||
|
||||
@@ -734,7 +791,7 @@ cmsSEQ* CMSEXPORT cmsDupProfileSequenceDescription(const cmsSEQ* pseq)
|
||||
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;
|
||||
@@ -745,6 +802,128 @@ Error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Dictionaries --------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Dictionaries are just very simple linked lists
|
||||
|
||||
|
||||
typedef struct _cmsDICT_struct {
|
||||
cmsDICTentry* head;
|
||||
cmsContext ContextID;
|
||||
} _cmsDICT;
|
||||
|
||||
|
||||
// Allocate an empty dictionary
|
||||
cmsHANDLE CMSEXPORT cmsDictAlloc(cmsContext ContextID)
|
||||
{
|
||||
_cmsDICT* dict = (_cmsDICT*) _cmsMallocZero(ContextID, sizeof(_cmsDICT));
|
||||
if (dict == NULL) return NULL;
|
||||
|
||||
dict ->ContextID = ContextID;
|
||||
return (cmsHANDLE) dict;
|
||||
|
||||
}
|
||||
|
||||
// Dispose resources
|
||||
void CMSEXPORT cmsDictFree(cmsHANDLE hDict)
|
||||
{
|
||||
_cmsDICT* dict = (_cmsDICT*) hDict;
|
||||
cmsDICTentry *entry, *next;
|
||||
|
||||
_cmsAssert(dict != NULL);
|
||||
|
||||
// Walk the list freeing all nodes
|
||||
entry = dict ->head;
|
||||
while (entry != NULL) {
|
||||
|
||||
if (entry ->DisplayName != NULL) cmsMLUfree(entry ->DisplayName);
|
||||
if (entry ->DisplayValue != NULL) cmsMLUfree(entry ->DisplayValue);
|
||||
if (entry ->Name != NULL) _cmsFree(dict ->ContextID, entry -> Name);
|
||||
if (entry ->Value != NULL) _cmsFree(dict ->ContextID, entry -> Value);
|
||||
|
||||
// Don't fall in the habitual trap...
|
||||
next = entry ->Next;
|
||||
_cmsFree(dict ->ContextID, entry);
|
||||
|
||||
entry = next;
|
||||
}
|
||||
|
||||
_cmsFree(dict ->ContextID, dict);
|
||||
}
|
||||
|
||||
|
||||
// Duplicate a wide char string
|
||||
static
|
||||
wchar_t* DupWcs(cmsContext ContextID, const wchar_t* ptr)
|
||||
{
|
||||
if (ptr == NULL) return NULL;
|
||||
return (wchar_t*) _cmsDupMem(ContextID, ptr, (mywcslen(ptr) + 1) * sizeof(wchar_t));
|
||||
}
|
||||
|
||||
// Add a new entry to the linked list
|
||||
cmsBool CMSEXPORT cmsDictAddEntry(cmsHANDLE hDict, const wchar_t* Name, const wchar_t* Value, const cmsMLU *DisplayName, const cmsMLU *DisplayValue)
|
||||
{
|
||||
_cmsDICT* dict = (_cmsDICT*) hDict;
|
||||
cmsDICTentry *entry;
|
||||
|
||||
_cmsAssert(dict != NULL);
|
||||
_cmsAssert(Name != NULL);
|
||||
|
||||
entry = (cmsDICTentry*) _cmsMallocZero(dict ->ContextID, sizeof(cmsDICTentry));
|
||||
if (entry == NULL) return FALSE;
|
||||
|
||||
entry ->DisplayName = cmsMLUdup(DisplayName);
|
||||
entry ->DisplayValue = cmsMLUdup(DisplayValue);
|
||||
entry ->Name = DupWcs(dict ->ContextID, Name);
|
||||
entry ->Value = DupWcs(dict ->ContextID, Value);
|
||||
|
||||
entry ->Next = dict ->head;
|
||||
dict ->head = entry;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Duplicates an existing dictionary
|
||||
cmsHANDLE CMSEXPORT cmsDictDup(cmsHANDLE hDict)
|
||||
{
|
||||
_cmsDICT* old_dict = (_cmsDICT*) hDict;
|
||||
cmsHANDLE hNew;
|
||||
cmsDICTentry *entry;
|
||||
|
||||
_cmsAssert(old_dict != NULL);
|
||||
|
||||
hNew = cmsDictAlloc(old_dict ->ContextID);
|
||||
if (hNew == NULL) return NULL;
|
||||
|
||||
// Walk the list freeing all nodes
|
||||
entry = old_dict ->head;
|
||||
while (entry != NULL) {
|
||||
|
||||
if (!cmsDictAddEntry(hNew, entry ->Name, entry ->Value, entry ->DisplayName, entry ->DisplayValue)) {
|
||||
|
||||
cmsDictFree(hNew);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
entry = entry -> Next;
|
||||
}
|
||||
|
||||
return hNew;
|
||||
}
|
||||
|
||||
// Get a pointer to the linked list
|
||||
const cmsDICTentry* CMSEXPORT cmsDictGetEntryList(cmsHANDLE hDict)
|
||||
{
|
||||
_cmsDICT* dict = (_cmsDICT*) hDict;
|
||||
|
||||
if (dict == NULL) return NULL;
|
||||
return dict ->head;
|
||||
}
|
||||
|
||||
// Helper For external languages
|
||||
const cmsDICTentry* CMSEXPORT cmsDictNextEntry(const cmsDICTentry* e)
|
||||
{
|
||||
if (e == NULL) return NULL;
|
||||
return e ->Next;
|
||||
}
|
||||
|
||||
656
thirdparty/liblcms2/src/cmsopt.c
vendored
656
thirdparty/liblcms2/src/cmsopt.c
vendored
File diff suppressed because it is too large
Load Diff
1939
thirdparty/liblcms2/src/cmspack.c
vendored
1939
thirdparty/liblcms2/src/cmspack.c
vendored
File diff suppressed because it is too large
Load Diff
203
thirdparty/liblcms2/src/cmspcs.c
vendored
203
thirdparty/liblcms2/src/cmspcs.c
vendored
@@ -3,22 +3,22 @@
|
||||
// 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
|
||||
// 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
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
//---------------------------------------------------------------------------------
|
||||
@@ -114,7 +114,7 @@ cmsFloat64Number f(cmsFloat64Number t)
|
||||
if (t <= Limit)
|
||||
return (841.0/108.0) * t + (16.0/116.0);
|
||||
else
|
||||
return pow(t, 1.0/3.0);
|
||||
return pow(t, 1.0/3.0);
|
||||
}
|
||||
|
||||
static
|
||||
@@ -135,7 +135,7 @@ void CMSEXPORT cmsXYZ2Lab(const cmsCIEXYZ* WhitePoint, cmsCIELab* Lab, const cms
|
||||
{
|
||||
cmsFloat64Number fx, fy, fz;
|
||||
|
||||
if (WhitePoint == NULL)
|
||||
if (WhitePoint == NULL)
|
||||
WhitePoint = cmsD50_XYZ();
|
||||
|
||||
fx = f(xyz->X / WhitePoint->X);
|
||||
@@ -153,7 +153,7 @@ void CMSEXPORT cmsLab2XYZ(const cmsCIEXYZ* WhitePoint, cmsCIEXYZ* xyz, const cm
|
||||
{
|
||||
cmsFloat64Number x, y, z;
|
||||
|
||||
if (WhitePoint == NULL)
|
||||
if (WhitePoint == NULL)
|
||||
WhitePoint = cmsD50_XYZ();
|
||||
|
||||
y = (Lab-> L + 16.0) / 116.0;
|
||||
@@ -169,26 +169,26 @@ void CMSEXPORT cmsLab2XYZ(const cmsCIEXYZ* WhitePoint, cmsCIEXYZ* xyz, const cm
|
||||
static
|
||||
cmsFloat64Number L2float2(cmsUInt16Number v)
|
||||
{
|
||||
return (cmsFloat64Number) v / 652.800;
|
||||
return (cmsFloat64Number) v / 652.800;
|
||||
}
|
||||
|
||||
// the a/b part
|
||||
static
|
||||
cmsFloat64Number ab2float2(cmsUInt16Number v)
|
||||
{
|
||||
return ((cmsFloat64Number) v / 256.0) - 128.0;
|
||||
{
|
||||
return ((cmsFloat64Number) v / 256.0) - 128.0;
|
||||
}
|
||||
|
||||
static
|
||||
cmsUInt16Number L2Fix2(cmsFloat64Number L)
|
||||
{
|
||||
return _cmsQuickSaturateWord(L * 652.8);
|
||||
return _cmsQuickSaturateWord(L * 652.8);
|
||||
}
|
||||
|
||||
static
|
||||
cmsUInt16Number ab2Fix2(cmsFloat64Number ab)
|
||||
{
|
||||
return _cmsQuickSaturateWord((ab + 128.0) * 256.0);
|
||||
return _cmsQuickSaturateWord((ab + 128.0) * 256.0);
|
||||
}
|
||||
|
||||
|
||||
@@ -249,7 +249,7 @@ void CMSEXPORT cmsFloat2LabEncodedV2(cmsUInt16Number wLab[3], const cmsCIELab* f
|
||||
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);
|
||||
@@ -274,7 +274,7 @@ cmsFloat64Number Clamp_ab_doubleV4(cmsFloat64Number ab)
|
||||
return ab;
|
||||
}
|
||||
|
||||
static
|
||||
static
|
||||
cmsUInt16Number L2Fix4(cmsFloat64Number L)
|
||||
{
|
||||
return _cmsQuickSaturateWord(L * 655.35);
|
||||
@@ -289,11 +289,11 @@ cmsUInt16Number ab2Fix4(cmsFloat64Number ab)
|
||||
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);
|
||||
@@ -317,15 +317,15 @@ cmsFloat64Number atan2deg(cmsFloat64Number a, cmsFloat64Number b)
|
||||
h = 0;
|
||||
else
|
||||
h = atan2(a, b);
|
||||
|
||||
|
||||
h *= (180. / M_PI);
|
||||
|
||||
while (h > 360.)
|
||||
|
||||
while (h > 360.)
|
||||
h -= 360.;
|
||||
|
||||
|
||||
while ( h < 0)
|
||||
h += 360.;
|
||||
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
@@ -334,7 +334,7 @@ cmsFloat64Number atan2deg(cmsFloat64Number a, cmsFloat64Number b)
|
||||
static
|
||||
cmsFloat64Number Sqr(cmsFloat64Number v)
|
||||
{
|
||||
return v * v;
|
||||
return v * v;
|
||||
}
|
||||
// From cylindrical coordinates. No check is performed, then negative values are allowed
|
||||
void CMSEXPORT cmsLab2LCh(cmsCIELCh* LCh, const cmsCIELab* Lab)
|
||||
@@ -352,13 +352,13 @@ void CMSEXPORT cmsLCh2Lab(cmsCIELab* Lab, const cmsCIELCh* LCh)
|
||||
|
||||
Lab -> L = LCh -> L;
|
||||
Lab -> a = LCh -> C * cos(h);
|
||||
Lab -> b = LCh -> C * sin(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);
|
||||
}
|
||||
|
||||
@@ -370,7 +370,7 @@ void CMSEXPORT cmsFloat2XYZEncoded(cmsUInt16Number XYZ[3], const cmsCIEXYZ* fXYZ
|
||||
xyz.Y = fXYZ -> Y;
|
||||
xyz.Z = fXYZ -> Z;
|
||||
|
||||
// Clamp to encodeable values.
|
||||
// Clamp to encodeable values.
|
||||
if (xyz.Y <= 0) {
|
||||
|
||||
xyz.X = 0;
|
||||
@@ -378,19 +378,19 @@ void CMSEXPORT cmsFloat2XYZEncoded(cmsUInt16Number XYZ[3], const cmsCIEXYZ* fXYZ
|
||||
xyz.Z = 0;
|
||||
}
|
||||
|
||||
if (xyz.X > MAX_ENCODEABLE_XYZ)
|
||||
if (xyz.X > MAX_ENCODEABLE_XYZ)
|
||||
xyz.X = MAX_ENCODEABLE_XYZ;
|
||||
|
||||
if (xyz.X < 0)
|
||||
xyz.X = 0;
|
||||
|
||||
if (xyz.Y > MAX_ENCODEABLE_XYZ)
|
||||
if (xyz.Y > MAX_ENCODEABLE_XYZ)
|
||||
xyz.Y = MAX_ENCODEABLE_XYZ;
|
||||
|
||||
if (xyz.Y < 0)
|
||||
xyz.Y = 0;
|
||||
|
||||
if (xyz.Z > MAX_ENCODEABLE_XYZ)
|
||||
if (xyz.Z > MAX_ENCODEABLE_XYZ)
|
||||
xyz.Z = MAX_ENCODEABLE_XYZ;
|
||||
|
||||
if (xyz.Z < 0)
|
||||
@@ -399,7 +399,7 @@ void CMSEXPORT cmsFloat2XYZEncoded(cmsUInt16Number XYZ[3], const cmsCIEXYZ* fXYZ
|
||||
|
||||
XYZ[0] = XYZ2Fix(xyz.X);
|
||||
XYZ[1] = XYZ2Fix(xyz.Y);
|
||||
XYZ[2] = XYZ2Fix(xyz.Z);
|
||||
XYZ[2] = XYZ2Fix(xyz.Z);
|
||||
}
|
||||
|
||||
|
||||
@@ -422,7 +422,7 @@ 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
|
||||
@@ -438,7 +438,7 @@ cmsFloat64Number CMSEXPORT cmsDeltaE(const cmsCIELab* Lab1, const cmsCIELab* Lab
|
||||
}
|
||||
|
||||
|
||||
// Return the CIE94 Delta E
|
||||
// Return the CIE94 Delta E
|
||||
cmsFloat64Number CMSEXPORT cmsCIE94DeltaE(const cmsCIELab* Lab1, const cmsCIELab* Lab2)
|
||||
{
|
||||
cmsCIELCh LCh1, LCh2;
|
||||
@@ -452,7 +452,7 @@ cmsFloat64Number CMSEXPORT cmsCIE94DeltaE(const cmsCIELab* Lab1, const cmsCIELab
|
||||
|
||||
dC = fabs(LCh1.C - LCh2.C);
|
||||
dE = cmsDeltaE(Lab1, Lab2);
|
||||
|
||||
|
||||
dhsq = Sqr(dE) - Sqr(dL) - Sqr(dC);
|
||||
if (dhsq < 0)
|
||||
dh = 0;
|
||||
@@ -463,7 +463,7 @@ cmsFloat64Number CMSEXPORT cmsCIE94DeltaE(const cmsCIELab* Lab1, const cmsCIELab
|
||||
|
||||
sc = 1.0 + (0.048 * c12);
|
||||
sh = 1.0 + (0.014 * c12);
|
||||
|
||||
|
||||
return sqrt(Sqr(dL) + Sqr(dC) / Sqr(sc) + Sqr(dh) / Sqr(sh));
|
||||
}
|
||||
|
||||
@@ -513,7 +513,7 @@ cmsFloat64Number CMSEXPORT cmsBFDdeltaE(const cmsCIELab* Lab1, const cmsCIELab*
|
||||
|
||||
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))-
|
||||
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))-
|
||||
@@ -546,27 +546,27 @@ cmsFloat64Number CMSEXPORT cmsCMCdeltaE(const cmsCIELab* Lab1, const cmsCIELab*
|
||||
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)))
|
||||
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))
|
||||
if ((LCh1.h > 164) && (LCh1.h < 345))
|
||||
t = 0.56 + fabs(0.2 * cos(((LCh1.h + 168)/(180/M_PI))));
|
||||
else
|
||||
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;
|
||||
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);
|
||||
@@ -575,7 +575,7 @@ cmsFloat64Number CMSEXPORT cmsCMCdeltaE(const cmsCIELab* Lab1, const cmsCIELab*
|
||||
return cmc;
|
||||
}
|
||||
|
||||
// dE2000 The weightings KL, KC and KH can be modified to reflect the relative
|
||||
// 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)
|
||||
@@ -595,25 +595,25 @@ cmsFloat64Number CMSEXPORT cmsCIE2000DeltaE(const cmsCIELab* Lab1, const cmsCIEL
|
||||
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 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 :
|
||||
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) > 180 ? (hps_minus_hp - 360) :
|
||||
(hps_minus_hp);
|
||||
cmsFloat64Number delta_L = (Ls - L1);
|
||||
cmsFloat64Number delta_C = (C_ps - C_p );
|
||||
@@ -621,9 +621,9 @@ cmsFloat64Number CMSEXPORT cmsCIE2000DeltaE(const cmsCIELab* Lab1, const cmsCIEL
|
||||
|
||||
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))
|
||||
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) );
|
||||
@@ -637,9 +637,9 @@ cmsFloat64Number CMSEXPORT cmsCIE2000DeltaE(const cmsCIELab* Lab1, const cmsCIEL
|
||||
|
||||
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)) +
|
||||
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;
|
||||
@@ -662,41 +662,41 @@ int _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsU
|
||||
// HighResPrecalc is maximum resolution
|
||||
if (dwFlags & cmsFLAGS_HIGHRESPRECALC) {
|
||||
|
||||
if (nChannels > 4)
|
||||
if (nChannels > 4)
|
||||
return 7; // 7 for Hifi
|
||||
|
||||
if (nChannels == 4) // 23 for CMYK
|
||||
return 23;
|
||||
|
||||
return 49; // 49 for RGB and others
|
||||
|
||||
return 49; // 49 for RGB and others
|
||||
}
|
||||
|
||||
|
||||
// LowResPrecal is lower resolution
|
||||
if (dwFlags & cmsFLAGS_LOWRESPRECALC) {
|
||||
|
||||
if (nChannels > 4)
|
||||
|
||||
if (nChannels > 4)
|
||||
return 6; // 6 for more than 4 channels
|
||||
|
||||
if (nChannels == 1)
|
||||
if (nChannels == 1)
|
||||
return 33; // For monochrome
|
||||
|
||||
return 17; // 17 for remaining
|
||||
}
|
||||
|
||||
// Default values
|
||||
if (nChannels > 4)
|
||||
if (nChannels > 4)
|
||||
return 7; // 7 for Hifi
|
||||
|
||||
if (nChannels == 4)
|
||||
return 17; // 17 for CMYK
|
||||
|
||||
return 33; // 33 for RGB
|
||||
return 33; // 33 for RGB
|
||||
}
|
||||
|
||||
|
||||
cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
|
||||
cmsUInt16Number **White,
|
||||
cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
|
||||
cmsUInt16Number **White,
|
||||
cmsUInt16Number **Black,
|
||||
cmsUInt32Number *nOutputs)
|
||||
{
|
||||
@@ -719,7 +719,7 @@ cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
|
||||
if (Black) *Black = Grayblack;
|
||||
if (nOutputs) *nOutputs = 1;
|
||||
return TRUE;
|
||||
|
||||
|
||||
case cmsSigRgbData: if (White) *White = RGBwhite;
|
||||
if (Black) *Black = RGBblack;
|
||||
if (nOutputs) *nOutputs = 3;
|
||||
@@ -746,7 +746,7 @@ cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Several utilities -------------------------------------------------------
|
||||
|
||||
@@ -799,9 +799,9 @@ cmsColorSpaceSignature CMSEXPORT _cmsICCcolorSpace(int OurNotation)
|
||||
|
||||
|
||||
int CMSEXPORT _cmsLCMScolorSpace(cmsColorSpaceSignature ProfileSpace)
|
||||
{
|
||||
{
|
||||
switch (ProfileSpace) {
|
||||
|
||||
|
||||
case cmsSigGrayData: return PT_GRAY;
|
||||
case cmsSigRgbData: return PT_RGB;
|
||||
case cmsSigCmyData: return PT_CMY;
|
||||
@@ -814,52 +814,52 @@ int CMSEXPORT _cmsLCMScolorSpace(cmsColorSpaceSignature ProfileSpace)
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -869,31 +869,36 @@ cmsUInt32Number CMSEXPORT cmsChannelsOf(cmsColorSpaceSignature ColorSpace)
|
||||
{
|
||||
switch (ColorSpace) {
|
||||
|
||||
case cmsSigMCH1Data:
|
||||
case cmsSig1colorData:
|
||||
case cmsSigGrayData: return 1;
|
||||
|
||||
case cmsSigMCH2Data:
|
||||
case cmsSig2colorData: return 2;
|
||||
|
||||
|
||||
case cmsSigXYZData:
|
||||
case cmsSigLabData:
|
||||
case cmsSigLuvData:
|
||||
case cmsSigYCbCrData:
|
||||
case cmsSigYxyData:
|
||||
case cmsSigRgbData:
|
||||
case cmsSigRgbData:
|
||||
case cmsSigHsvData:
|
||||
case cmsSigHlsData:
|
||||
case cmsSigCmyData:
|
||||
case cmsSigCmyData:
|
||||
case cmsSigMCH3Data:
|
||||
case cmsSig3colorData: return 3;
|
||||
|
||||
|
||||
case cmsSigLuvKData:
|
||||
case cmsSigCmykData:
|
||||
case cmsSigMCH4Data:
|
||||
case cmsSig4colorData: return 4;
|
||||
|
||||
case cmsSigMCH5Data:
|
||||
case cmsSig5colorData: return 5;
|
||||
case cmsSig5colorData: return 5;
|
||||
|
||||
case cmsSigMCH6Data:
|
||||
case cmsSigMCH6Data:
|
||||
case cmsSig6colorData: return 6;
|
||||
|
||||
|
||||
case cmsSigMCH7Data:
|
||||
case cmsSig7colorData: return 7;
|
||||
|
||||
@@ -908,7 +913,7 @@ cmsUInt32Number CMSEXPORT cmsChannelsOf(cmsColorSpaceSignature ColorSpace)
|
||||
|
||||
case cmsSigMCHBData:
|
||||
case cmsSig11colorData: return 11;
|
||||
|
||||
|
||||
case cmsSigMCHCData:
|
||||
case cmsSig12colorData: return 12;
|
||||
|
||||
|
||||
545
thirdparty/liblcms2/src/cmsplugin.c
vendored
545
thirdparty/liblcms2/src/cmsplugin.c
vendored
@@ -3,22 +3,22 @@
|
||||
// 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
|
||||
// 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
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
//---------------------------------------------------------------------------------
|
||||
@@ -44,7 +44,7 @@ cmsUInt16Number CMSEXPORT _cmsAdjustEndianess16(cmsUInt16Number Word)
|
||||
tmp = pByte[0];
|
||||
pByte[0] = pByte[1];
|
||||
pByte[1] = tmp;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return Word;
|
||||
}
|
||||
@@ -76,12 +76,12 @@ cmsUInt32Number CMSEXPORT _cmsAdjustEndianess32(cmsUInt32Number DWord)
|
||||
// 1 2 3 4 5 6 7 8
|
||||
// 8 7 6 5 4 3 2 1
|
||||
|
||||
void CMSEXPORT _cmsAdjustEndianess64(cmsUInt64Number* Result, cmsUInt64Number QWord)
|
||||
void CMSEXPORT _cmsAdjustEndianess64(cmsUInt64Number* Result, cmsUInt64Number* QWord)
|
||||
{
|
||||
|
||||
|
||||
#ifndef CMS_USE_BIG_ENDIAN
|
||||
|
||||
cmsUInt8Number* pIn = (cmsUInt8Number*) &QWord;
|
||||
|
||||
cmsUInt8Number* pIn = (cmsUInt8Number*) QWord;
|
||||
cmsUInt8Number* pOut = (cmsUInt8Number*) Result;
|
||||
|
||||
_cmsAssert(Result != NULL);
|
||||
@@ -91,15 +91,19 @@ void CMSEXPORT _cmsAdjustEndianess64(cmsUInt64Number* Result, cmsUInt64Number Q
|
||||
pOut[5] = pIn[2];
|
||||
pOut[4] = pIn[3];
|
||||
pOut[3] = pIn[4];
|
||||
pOut[2] = pIn[5];
|
||||
pOut[2] = pIn[5];
|
||||
pOut[1] = pIn[6];
|
||||
pOut[0] = pIn[7];
|
||||
|
||||
#else
|
||||
|
||||
_cmsAssert(Result != NULL);
|
||||
|
||||
*Result = QWord;
|
||||
# ifdef CMS_DONT_USE_INT64
|
||||
(*Result)[0] = QWord[0];
|
||||
(*Result)[1] = QWord[1];
|
||||
# else
|
||||
*Result = *QWord;
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -110,8 +114,8 @@ cmsBool CMSEXPORT _cmsReadUInt8Number(cmsIOHANDLER* io, cmsUInt8Number* n)
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
if (io -> Read(io, &tmp, sizeof(cmsUInt8Number), 1) != 1)
|
||||
return FALSE;
|
||||
if (io -> Read(io, &tmp, sizeof(cmsUInt8Number), 1) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (n != NULL) *n = tmp;
|
||||
return TRUE;
|
||||
@@ -123,8 +127,8 @@ cmsBool CMSEXPORT _cmsReadUInt16Number(cmsIOHANDLER* io, cmsUInt16Number* n)
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
if (io -> Read(io, &tmp, sizeof(cmsUInt16Number), 1) != 1)
|
||||
return FALSE;
|
||||
if (io -> Read(io, &tmp, sizeof(cmsUInt16Number), 1) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (n != NULL) *n = _cmsAdjustEndianess16(tmp);
|
||||
return TRUE;
|
||||
@@ -155,8 +159,8 @@ cmsBool CMSEXPORT _cmsReadUInt32Number(cmsIOHANDLER* io, cmsUInt32Number* n)
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
if (io -> Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1)
|
||||
return FALSE;
|
||||
if (io -> Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (n != NULL) *n = _cmsAdjustEndianess32(tmp);
|
||||
return TRUE;
|
||||
@@ -168,8 +172,8 @@ cmsBool CMSEXPORT _cmsReadFloat32Number(cmsIOHANDLER* io, cmsFloat32Number* n)
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
if (io -> Read(io, &tmp, sizeof(cmsFloat32Number), 1) != 1)
|
||||
return FALSE;
|
||||
if (io -> Read(io, &tmp, sizeof(cmsFloat32Number), 1) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (n != NULL) {
|
||||
|
||||
@@ -186,10 +190,10 @@ cmsBool CMSEXPORT _cmsReadUInt64Number(cmsIOHANDLER* io, cmsUInt64Number* n)
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
if (io -> Read(io, &tmp, sizeof(cmsUInt64Number), 1) != 1)
|
||||
return FALSE;
|
||||
if (io -> Read(io, &tmp, sizeof(cmsUInt64Number), 1) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (n != NULL) _cmsAdjustEndianess64(n, tmp);
|
||||
if (n != NULL) _cmsAdjustEndianess64(n, &tmp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -200,8 +204,8 @@ cmsBool CMSEXPORT _cmsRead15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number* n
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
if (io -> Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1)
|
||||
return FALSE;
|
||||
if (io -> Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (n != NULL) {
|
||||
*n = _cms15Fixed16toDouble(_cmsAdjustEndianess32(tmp));
|
||||
@@ -250,9 +254,9 @@ cmsBool CMSEXPORT _cmsWriteUInt8Number(cmsIOHANDLER* io, cmsUInt8Number n)
|
||||
{
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
if (io -> Write(io, sizeof(cmsUInt8Number), &n) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (io -> Write(io, sizeof(cmsUInt8Number), &n) != 1)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -263,9 +267,9 @@ cmsBool CMSEXPORT _cmsWriteUInt16Number(cmsIOHANDLER* io, cmsUInt16Number n)
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
tmp = _cmsAdjustEndianess16(n);
|
||||
if (io -> Write(io, sizeof(cmsUInt16Number), &tmp) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (io -> Write(io, sizeof(cmsUInt16Number), &tmp) != 1)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -290,9 +294,9 @@ cmsBool CMSEXPORT _cmsWriteUInt32Number(cmsIOHANDLER* io, cmsUInt32Number n)
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
tmp = _cmsAdjustEndianess32(n);
|
||||
if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -305,22 +309,22 @@ cmsBool CMSEXPORT _cmsWriteFloat32Number(cmsIOHANDLER* io, cmsFloat32Number n)
|
||||
|
||||
tmp = *(cmsUInt32Number*) &n;
|
||||
tmp = _cmsAdjustEndianess32(tmp);
|
||||
if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
cmsBool CMSEXPORT _cmsWriteUInt64Number(cmsIOHANDLER* io, cmsUInt64Number n)
|
||||
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;
|
||||
|
||||
if (io -> Write(io, sizeof(cmsUInt64Number), &tmp) != 1)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -331,16 +335,16 @@ cmsBool CMSEXPORT _cmsWrite15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number n
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
tmp = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(n));
|
||||
if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
|
||||
return FALSE;
|
||||
|
||||
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);
|
||||
|
||||
@@ -365,7 +369,7 @@ cmsFloat64Number CMSEXPORT _cms8Fixed8toDouble(cmsUInt16Number fixed8)
|
||||
cmsUInt16Number CMSEXPORT _cmsDoubleTo8Fixed8(cmsFloat64Number val)
|
||||
{
|
||||
cmsS15Fixed16Number GammaFixed32 = _cmsDoubleTo15Fixed16(val);
|
||||
return (cmsUInt16Number) ((GammaFixed32 >> 8) & 0xFFFF);
|
||||
return (cmsUInt16Number) ((GammaFixed32 >> 8) & 0xFFFF);
|
||||
}
|
||||
|
||||
// from Fixed point 15.16 to double
|
||||
@@ -386,13 +390,13 @@ cmsFloat64Number CMSEXPORT _cms15Fixed16toDouble(cmsS15Fixed16Number fix32)
|
||||
return sign * floater;
|
||||
}
|
||||
|
||||
// from double to Fixed point 15.16
|
||||
// from double to Fixed point 15.16
|
||||
cmsS15Fixed16Number CMSEXPORT _cmsDoubleTo15Fixed16(cmsFloat64Number v)
|
||||
{
|
||||
return ((cmsS15Fixed16Number) floor((v)*65536.0 + 0.5));
|
||||
}
|
||||
|
||||
// Date/Time functions
|
||||
// Date/Time functions
|
||||
|
||||
void CMSEXPORT _cmsDecodeDateTimeNumber(const cmsDateTimeNumber *Source, struct tm *Dest)
|
||||
{
|
||||
@@ -431,7 +435,7 @@ cmsTagTypeSignature CMSEXPORT _cmsReadTypeBase(cmsIOHANDLER* io)
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
if (io -> Read(io, &Base, sizeof(_cmsTagBase), 1) != 1)
|
||||
if (io -> Read(io, &Base, sizeof(_cmsTagBase), 1) != 1)
|
||||
return (cmsTagTypeSignature) 0;
|
||||
|
||||
return (cmsTagTypeSignature) _cmsAdjustEndianess32(Base.sig);
|
||||
@@ -454,7 +458,7 @@ cmsBool CMSEXPORT _cmsReadAlignment(cmsIOHANDLER* io)
|
||||
cmsUInt8Number Buffer[4];
|
||||
cmsUInt32Number NextAligned, At;
|
||||
cmsUInt32Number BytesToNextAlignedPos;
|
||||
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
At = io -> Tell(io);
|
||||
@@ -502,7 +506,7 @@ cmsBool CMSEXPORT _cmsIOPrintf(cmsIOHANDLER* io, const char* frm, ...)
|
||||
if (len < 0) return FALSE; // Truncated, which is a fatal error for us
|
||||
|
||||
rc = io ->Write(io, len, Buffer);
|
||||
|
||||
|
||||
va_end(args);
|
||||
|
||||
return rc;
|
||||
@@ -511,80 +515,102 @@ cmsBool CMSEXPORT _cmsIOPrintf(cmsIOHANDLER* io, const char* frm, ...)
|
||||
|
||||
// Plugin memory management -------------------------------------------------------------------------------------------------
|
||||
|
||||
static _cmsSubAllocator* PluginPool = NULL;
|
||||
|
||||
// Specialized malloc for plug-ins, that is freed upon exit.
|
||||
void* _cmsPluginMalloc(cmsUInt32Number size)
|
||||
void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size)
|
||||
{
|
||||
if (PluginPool == NULL)
|
||||
PluginPool = _cmsCreateSubAlloc(0, 4*1024);
|
||||
struct _cmsContext_struct* ctx = _cmsGetContext(ContextID);
|
||||
|
||||
return _cmsSubAlloc(PluginPool, size);
|
||||
if (ctx ->MemPool == NULL) {
|
||||
|
||||
if (ContextID == NULL) {
|
||||
|
||||
ctx->MemPool = _cmsCreateSubAlloc(0, 2*1024);
|
||||
}
|
||||
else {
|
||||
cmsSignalError(ContextID, cmsERROR_CORRUPTION_DETECTED, "NULL memory pool on context");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return _cmsSubAlloc(ctx->MemPool, size);
|
||||
}
|
||||
|
||||
|
||||
// Main plug-in dispatcher
|
||||
cmsBool CMSEXPORT cmsPlugin(void* Plug_in)
|
||||
{
|
||||
return cmsPluginTHR(NULL, Plug_in);
|
||||
}
|
||||
|
||||
cmsBool CMSEXPORT cmsPluginTHR(cmsContext id, void* Plug_in)
|
||||
{
|
||||
cmsPluginBase* Plugin;
|
||||
|
||||
for (Plugin = (cmsPluginBase*) Plug_in;
|
||||
Plugin != NULL;
|
||||
for (Plugin = (cmsPluginBase*) Plug_in;
|
||||
Plugin != NULL;
|
||||
Plugin = Plugin -> Next) {
|
||||
|
||||
if (Plugin -> Magic != cmsPluginMagicNumber) {
|
||||
cmsSignalError(0, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin");
|
||||
cmsSignalError(id, 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;
|
||||
}
|
||||
if (Plugin ->ExpectedVersion > LCMS_VERSION) {
|
||||
cmsSignalError(id, 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;
|
||||
if (!_cmsRegisterMemHandlerPlugin(id, Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
case cmsPluginInterpolationSig:
|
||||
if (!_cmsRegisterInterpPlugin(Plugin)) return FALSE;
|
||||
if (!_cmsRegisterInterpPlugin(id, Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
|
||||
case cmsPluginTagTypeSig:
|
||||
if (!_cmsRegisterTagTypePlugin(Plugin)) return FALSE;
|
||||
if (!_cmsRegisterTagTypePlugin(id, Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
|
||||
case cmsPluginTagSig:
|
||||
if (!_cmsRegisterTagPlugin(Plugin)) return FALSE;
|
||||
if (!_cmsRegisterTagPlugin(id, Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
case cmsPluginFormattersSig:
|
||||
if (!_cmsRegisterFormattersPlugin(Plugin)) return FALSE;
|
||||
if (!_cmsRegisterFormattersPlugin(id, Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
case cmsPluginRenderingIntentSig:
|
||||
if (!_cmsRegisterRenderingIntentPlugin(Plugin)) return FALSE;
|
||||
if (!_cmsRegisterRenderingIntentPlugin(id, Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
case cmsPluginParametricCurveSig:
|
||||
if (!_cmsRegisterParametricCurvesPlugin(Plugin)) return FALSE;
|
||||
if (!_cmsRegisterParametricCurvesPlugin(id, Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
case cmsPluginMultiProcessElementSig:
|
||||
if (!_cmsRegisterMultiProcessElementPlugin(Plugin)) return FALSE;
|
||||
if (!_cmsRegisterMultiProcessElementPlugin(id, Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
case cmsPluginOptimizationSig:
|
||||
if (!_cmsRegisterOptimizationPlugin(Plugin)) return FALSE;
|
||||
if (!_cmsRegisterOptimizationPlugin(id, Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
case cmsPluginTransformSig:
|
||||
if (!_cmsRegisterTransformPlugin(id, Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
case cmsPluginMutexSig:
|
||||
if (!_cmsRegisterMutexPlugin(id, Plugin)) return FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
cmsSignalError(0, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin type '%X'", Plugin -> Type);
|
||||
cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin type '%X'", Plugin -> Type);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Keep a reference to the plug-in
|
||||
@@ -595,18 +621,337 @@ cmsBool CMSEXPORT cmsPlugin(void* Plug_in)
|
||||
// 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;
|
||||
cmsUnregisterPluginsTHR(NULL);
|
||||
}
|
||||
|
||||
|
||||
// The Global storage for system context. This is the one and only global variable
|
||||
// pointers structure. All global vars are referenced here.
|
||||
static struct _cmsContext_struct globalContext = {
|
||||
|
||||
NULL, // Not in the linked list
|
||||
NULL, // No suballocator
|
||||
{
|
||||
NULL, // UserPtr,
|
||||
&_cmsLogErrorChunk, // Logger,
|
||||
&_cmsAlarmCodesChunk, // AlarmCodes,
|
||||
&_cmsAdaptationStateChunk, // AdaptationState,
|
||||
&_cmsMemPluginChunk, // MemPlugin,
|
||||
&_cmsInterpPluginChunk, // InterpPlugin,
|
||||
&_cmsCurvesPluginChunk, // CurvesPlugin,
|
||||
&_cmsFormattersPluginChunk, // FormattersPlugin,
|
||||
&_cmsTagTypePluginChunk, // TagTypePlugin,
|
||||
&_cmsTagPluginChunk, // TagPlugin,
|
||||
&_cmsIntentsPluginChunk, // IntentPlugin,
|
||||
&_cmsMPETypePluginChunk, // MPEPlugin,
|
||||
&_cmsOptimizationPluginChunk, // OptimizationPlugin,
|
||||
&_cmsTransformPluginChunk, // TransformPlugin,
|
||||
&_cmsMutexPluginChunk // MutexPlugin
|
||||
},
|
||||
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL } // The default memory allocator is not used for context 0
|
||||
};
|
||||
|
||||
|
||||
// The context pool (linked list head)
|
||||
static _cmsMutex _cmsContextPoolHeadMutex = CMS_MUTEX_INITIALIZER;
|
||||
static struct _cmsContext_struct* _cmsContextPoolHead = NULL;
|
||||
|
||||
// Internal, get associated pointer, with guessing. Never returns NULL.
|
||||
struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID)
|
||||
{
|
||||
struct _cmsContext_struct* id = (struct _cmsContext_struct*) ContextID;
|
||||
struct _cmsContext_struct* ctx;
|
||||
|
||||
|
||||
// On 0, use global settings
|
||||
if (id == NULL)
|
||||
return &globalContext;
|
||||
|
||||
// Search
|
||||
for (ctx = _cmsContextPoolHead;
|
||||
ctx != NULL;
|
||||
ctx = ctx ->Next) {
|
||||
|
||||
// Found it?
|
||||
if (id == ctx)
|
||||
return ctx; // New-style context,
|
||||
}
|
||||
|
||||
return &globalContext;
|
||||
}
|
||||
|
||||
|
||||
// Internal: get the memory area associanted with each context client
|
||||
// Returns the block assigned to the specific zone.
|
||||
void* _cmsContextGetClientChunk(cmsContext ContextID, _cmsMemoryClient mc)
|
||||
{
|
||||
struct _cmsContext_struct* ctx;
|
||||
void *ptr;
|
||||
|
||||
if (mc < 0 || mc >= MemoryClientMax) {
|
||||
cmsSignalError(ContextID, cmsERROR_RANGE, "Bad context client");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx = _cmsGetContext(ContextID);
|
||||
ptr = ctx ->chunks[mc];
|
||||
|
||||
if (ptr != NULL)
|
||||
return ptr;
|
||||
|
||||
// A null ptr means no special settings for that context, and this
|
||||
// reverts to Context0 globals
|
||||
return globalContext.chunks[mc];
|
||||
}
|
||||
|
||||
|
||||
// This function returns the given context its default pristine state,
|
||||
// as no plug-ins were declared. There is no way to unregister a single
|
||||
// plug-in, as a single call to cmsPluginTHR() function may register
|
||||
// many different plug-ins simultaneously, then there is no way to
|
||||
// identify which plug-in to unregister.
|
||||
void CMSEXPORT cmsUnregisterPluginsTHR(cmsContext ContextID)
|
||||
{
|
||||
_cmsRegisterMemHandlerPlugin(ContextID, NULL);
|
||||
_cmsRegisterInterpPlugin(ContextID, NULL);
|
||||
_cmsRegisterTagTypePlugin(ContextID, NULL);
|
||||
_cmsRegisterTagPlugin(ContextID, NULL);
|
||||
_cmsRegisterFormattersPlugin(ContextID, NULL);
|
||||
_cmsRegisterRenderingIntentPlugin(ContextID, NULL);
|
||||
_cmsRegisterParametricCurvesPlugin(ContextID, NULL);
|
||||
_cmsRegisterMultiProcessElementPlugin(ContextID, NULL);
|
||||
_cmsRegisterOptimizationPlugin(ContextID, NULL);
|
||||
_cmsRegisterTransformPlugin(ContextID, NULL);
|
||||
_cmsRegisterMutexPlugin(ContextID, NULL);
|
||||
}
|
||||
|
||||
|
||||
// Returns the memory manager plug-in, if any, from the Plug-in bundle
|
||||
static
|
||||
cmsPluginMemHandler* _cmsFindMemoryPlugin(void* PluginBundle)
|
||||
{
|
||||
cmsPluginBase* Plugin;
|
||||
|
||||
for (Plugin = (cmsPluginBase*) PluginBundle;
|
||||
Plugin != NULL;
|
||||
Plugin = Plugin -> Next) {
|
||||
|
||||
if (Plugin -> Magic == cmsPluginMagicNumber &&
|
||||
Plugin -> ExpectedVersion <= LCMS_VERSION &&
|
||||
Plugin -> Type == cmsPluginMemHandlerSig) {
|
||||
|
||||
// Found!
|
||||
return (cmsPluginMemHandler*) Plugin;
|
||||
}
|
||||
}
|
||||
|
||||
// Nope, revert to defaults
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// Creates a new context with optional associated plug-ins. Caller may also specify an optional pointer to user-defined
|
||||
// data that will be forwarded to plug-ins and logger.
|
||||
cmsContext CMSEXPORT cmsCreateContext(void* Plugin, void* UserData)
|
||||
{
|
||||
struct _cmsContext_struct* ctx;
|
||||
struct _cmsContext_struct fakeContext;
|
||||
|
||||
_cmsInstallAllocFunctions(_cmsFindMemoryPlugin(Plugin), &fakeContext.DefaultMemoryManager);
|
||||
|
||||
fakeContext.chunks[UserPtr] = UserData;
|
||||
fakeContext.chunks[MemPlugin] = &fakeContext.DefaultMemoryManager;
|
||||
|
||||
// Create the context structure.
|
||||
ctx = (struct _cmsContext_struct*) _cmsMalloc(&fakeContext, sizeof(struct _cmsContext_struct));
|
||||
if (ctx == NULL)
|
||||
return NULL; // Something very wrong happened!
|
||||
|
||||
// Init the structure and the memory manager
|
||||
memset(ctx, 0, sizeof(struct _cmsContext_struct));
|
||||
|
||||
// Keep memory manager
|
||||
memcpy(&ctx->DefaultMemoryManager, &fakeContext.DefaultMemoryManager, sizeof(_cmsMemPluginChunk));
|
||||
|
||||
// Maintain the linked list (with proper locking)
|
||||
_cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
|
||||
ctx ->Next = _cmsContextPoolHead;
|
||||
_cmsContextPoolHead = ctx;
|
||||
_cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
|
||||
|
||||
ctx ->chunks[UserPtr] = UserData;
|
||||
ctx ->chunks[MemPlugin] = &ctx->DefaultMemoryManager;
|
||||
|
||||
// Now we can allocate the pool by using default memory manager
|
||||
ctx ->MemPool = _cmsCreateSubAlloc(ctx, 22 * sizeof(void*)); // default size about 32 pointers
|
||||
if (ctx ->MemPool == NULL) {
|
||||
|
||||
cmsDeleteContext(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_cmsAllocLogErrorChunk(ctx, NULL);
|
||||
_cmsAllocAlarmCodesChunk(ctx, NULL);
|
||||
_cmsAllocAdaptationStateChunk(ctx, NULL);
|
||||
_cmsAllocMemPluginChunk(ctx, NULL);
|
||||
_cmsAllocInterpPluginChunk(ctx, NULL);
|
||||
_cmsAllocCurvesPluginChunk(ctx, NULL);
|
||||
_cmsAllocFormattersPluginChunk(ctx, NULL);
|
||||
_cmsAllocTagTypePluginChunk(ctx, NULL);
|
||||
_cmsAllocMPETypePluginChunk(ctx, NULL);
|
||||
_cmsAllocTagPluginChunk(ctx, NULL);
|
||||
_cmsAllocIntentsPluginChunk(ctx, NULL);
|
||||
_cmsAllocOptimizationPluginChunk(ctx, NULL);
|
||||
_cmsAllocTransformPluginChunk(ctx, NULL);
|
||||
_cmsAllocMutexPluginChunk(ctx, NULL);
|
||||
|
||||
// Setup the plug-ins
|
||||
if (!cmsPluginTHR(ctx, Plugin)) {
|
||||
|
||||
cmsDeleteContext(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (cmsContext) ctx;
|
||||
}
|
||||
|
||||
// Duplicates a context with all associated plug-ins.
|
||||
// Caller may specify an optional pointer to user-defined
|
||||
// data that will be forwarded to plug-ins and logger.
|
||||
cmsContext CMSEXPORT cmsDupContext(cmsContext ContextID, void* NewUserData)
|
||||
{
|
||||
int i;
|
||||
struct _cmsContext_struct* ctx;
|
||||
const struct _cmsContext_struct* src = _cmsGetContext(ContextID);
|
||||
|
||||
void* userData = (NewUserData != NULL) ? NewUserData : src -> chunks[UserPtr];
|
||||
|
||||
|
||||
ctx = (struct _cmsContext_struct*) _cmsMalloc(ContextID, sizeof(struct _cmsContext_struct));
|
||||
if (ctx == NULL)
|
||||
return NULL; // Something very wrong happened
|
||||
|
||||
// Setup default memory allocators
|
||||
memcpy(&ctx->DefaultMemoryManager, &src->DefaultMemoryManager, sizeof(ctx->DefaultMemoryManager));
|
||||
|
||||
// Maintain the linked list
|
||||
_cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
|
||||
ctx ->Next = _cmsContextPoolHead;
|
||||
_cmsContextPoolHead = ctx;
|
||||
_cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
|
||||
|
||||
ctx ->chunks[UserPtr] = userData;
|
||||
ctx ->chunks[MemPlugin] = &ctx->DefaultMemoryManager;
|
||||
|
||||
ctx ->MemPool = _cmsCreateSubAlloc(ctx, 22 * sizeof(void*));
|
||||
if (ctx ->MemPool == NULL) {
|
||||
|
||||
cmsDeleteContext(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Allocate all required chunks.
|
||||
_cmsAllocLogErrorChunk(ctx, src);
|
||||
_cmsAllocAlarmCodesChunk(ctx, src);
|
||||
_cmsAllocAdaptationStateChunk(ctx, src);
|
||||
_cmsAllocMemPluginChunk(ctx, src);
|
||||
_cmsAllocInterpPluginChunk(ctx, src);
|
||||
_cmsAllocCurvesPluginChunk(ctx, src);
|
||||
_cmsAllocFormattersPluginChunk(ctx, src);
|
||||
_cmsAllocTagTypePluginChunk(ctx, src);
|
||||
_cmsAllocMPETypePluginChunk(ctx, src);
|
||||
_cmsAllocTagPluginChunk(ctx, src);
|
||||
_cmsAllocIntentsPluginChunk(ctx, src);
|
||||
_cmsAllocOptimizationPluginChunk(ctx, src);
|
||||
_cmsAllocTransformPluginChunk(ctx, src);
|
||||
_cmsAllocMutexPluginChunk(ctx, src);
|
||||
|
||||
// Make sure no one failed
|
||||
for (i=Logger; i < MemoryClientMax; i++) {
|
||||
|
||||
if (src ->chunks[i] == NULL) {
|
||||
cmsDeleteContext((cmsContext) ctx);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return (cmsContext) ctx;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static
|
||||
struct _cmsContext_struct* FindPrev(struct _cmsContext_struct* id)
|
||||
{
|
||||
struct _cmsContext_struct* prev;
|
||||
|
||||
// Search for previous
|
||||
for (prev = _cmsContextPoolHead;
|
||||
prev != NULL;
|
||||
prev = prev ->Next)
|
||||
{
|
||||
if (prev ->Next == id)
|
||||
return prev;
|
||||
}
|
||||
|
||||
return NULL; // List is empty or only one element!
|
||||
}
|
||||
|
||||
// Frees any resources associated with the given context,
|
||||
// and destroys the context placeholder.
|
||||
// The ContextID can no longer be used in any THR operation.
|
||||
void CMSEXPORT cmsDeleteContext(cmsContext ContextID)
|
||||
{
|
||||
if (ContextID != NULL) {
|
||||
|
||||
struct _cmsContext_struct* ctx = (struct _cmsContext_struct*) ContextID;
|
||||
struct _cmsContext_struct fakeContext;
|
||||
struct _cmsContext_struct* prev;
|
||||
|
||||
memcpy(&fakeContext.DefaultMemoryManager, &ctx->DefaultMemoryManager, sizeof(ctx->DefaultMemoryManager));
|
||||
|
||||
fakeContext.chunks[UserPtr] = ctx ->chunks[UserPtr];
|
||||
fakeContext.chunks[MemPlugin] = &fakeContext.DefaultMemoryManager;
|
||||
|
||||
// Get rid of plugins
|
||||
cmsUnregisterPluginsTHR(ContextID);
|
||||
|
||||
// Since all memory is allocated in the private pool, all what we need to do is destroy the pool
|
||||
if (ctx -> MemPool != NULL)
|
||||
_cmsSubAllocDestroy(ctx ->MemPool);
|
||||
ctx -> MemPool = NULL;
|
||||
|
||||
// Maintain list
|
||||
_cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
|
||||
if (_cmsContextPoolHead == ctx) {
|
||||
|
||||
_cmsContextPoolHead = ctx->Next;
|
||||
}
|
||||
else {
|
||||
|
||||
// Search for previous
|
||||
for (prev = _cmsContextPoolHead;
|
||||
prev != NULL;
|
||||
prev = prev ->Next)
|
||||
{
|
||||
if (prev -> Next == ctx) {
|
||||
prev -> Next = ctx ->Next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
_cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
|
||||
|
||||
// free the memory block itself
|
||||
_cmsFree(&fakeContext, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the user data associated to the given ContextID, or NULL if no user data was attached on context creation
|
||||
void* CMSEXPORT cmsGetContextUserData(cmsContext ContextID)
|
||||
{
|
||||
return _cmsContextGetClientChunk(ContextID, UserPtr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
918
thirdparty/liblcms2/src/cmsps2.c
vendored
918
thirdparty/liblcms2/src/cmsps2.c
vendored
File diff suppressed because it is too large
Load Diff
434
thirdparty/liblcms2/src/cmssamp.c
vendored
434
thirdparty/liblcms2/src/cmssamp.c
vendored
@@ -3,22 +3,22 @@
|
||||
// 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
|
||||
// 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
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
//---------------------------------------------------------------------------------
|
||||
@@ -27,29 +27,31 @@
|
||||
#include "lcms2_internal.h"
|
||||
|
||||
|
||||
#define cmsmin(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#define cmsmax(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
// This file contains routines for resampling and LUT optimization, black point detection
|
||||
// and black preservation.
|
||||
// and black preservation.
|
||||
|
||||
// Black point detection -------------------------------------------------------------------------
|
||||
|
||||
|
||||
// PCS -> PCS round trip transform, always uses relative intent on the device -> pcs
|
||||
// PCS -> PCS round trip transform, always uses relative intent on the device -> pcs
|
||||
static
|
||||
cmsHTRANSFORM CreateRoundtripXForm(cmsHPROFILE hProfile, cmsUInt32Number nIntent)
|
||||
{
|
||||
cmsHPROFILE hLab = cmsCreateLab4Profile(NULL);
|
||||
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
||||
cmsHPROFILE hLab = cmsCreateLab4ProfileTHR(ContextID, 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,
|
||||
xform = cmsCreateExtendedTransform(ContextID, 4, hProfiles, BPC, Intents,
|
||||
States, NULL, 0, TYPE_Lab_DBL, TYPE_Lab_DBL, cmsFLAGS_NOCACHE|cmsFLAGS_NOOPTIMIZE);
|
||||
|
||||
cmsCloseProfile(hLab);
|
||||
@@ -59,7 +61,7 @@ cmsHTRANSFORM CreateRoundtripXForm(cmsHPROFILE hProfile, cmsUInt32Number nIntent
|
||||
// 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,
|
||||
cmsBool BlackPointAsDarkerColorant(cmsHPROFILE hInput,
|
||||
cmsUInt32Number Intent,
|
||||
cmsCIEXYZ* BlackPoint,
|
||||
cmsUInt32Number dwFlags)
|
||||
@@ -68,28 +70,28 @@ cmsBool BlackPointAsDarkerColorant(cmsHPROFILE hInput,
|
||||
cmsHTRANSFORM xform;
|
||||
cmsColorSpaceSignature Space;
|
||||
cmsUInt32Number nChannels;
|
||||
cmsUInt32Number dwFormat;
|
||||
cmsUInt32Number dwFormat;
|
||||
cmsHPROFILE hLab;
|
||||
cmsCIELab Lab;
|
||||
cmsCIEXYZ BlackXYZ;
|
||||
cmsCIEXYZ BlackXYZ;
|
||||
cmsContext ContextID = cmsGetProfileContextID(hInput);
|
||||
|
||||
// If the profile does not support input direction, assume Black point 0
|
||||
|
||||
// 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
|
||||
// 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;
|
||||
}
|
||||
@@ -103,21 +105,21 @@ cmsBool BlackPointAsDarkerColorant(cmsHPROFILE hInput,
|
||||
hLab = cmsCreateLab2ProfileTHR(ContextID, NULL);
|
||||
if (hLab == NULL) {
|
||||
BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
|
||||
return FALSE;
|
||||
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);
|
||||
|
||||
@@ -125,38 +127,37 @@ cmsBool BlackPointAsDarkerColorant(cmsHPROFILE hInput,
|
||||
Lab.a = Lab.b = 0;
|
||||
if (Lab.L > 50) Lab.L = 50;
|
||||
|
||||
// Free the resources
|
||||
// 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
|
||||
// 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;
|
||||
{
|
||||
cmsHTRANSFORM hRoundTrip;
|
||||
cmsCIELab LabIn, LabOut;
|
||||
cmsCIEXYZ BlackXYZ;
|
||||
|
||||
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;
|
||||
@@ -171,10 +172,10 @@ cmsBool BlackPointUsingPerceptualBlack(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfi
|
||||
LabOut.a = LabOut.b = 0;
|
||||
|
||||
cmsDeleteTransform(hRoundTrip);
|
||||
|
||||
|
||||
// Convert it to XYZ
|
||||
cmsLab2XYZ(NULL, &BlackXYZ, &LabOut);
|
||||
|
||||
cmsLab2XYZ(NULL, &BlackXYZ, &LabOut);
|
||||
|
||||
if (BlackPoint != NULL)
|
||||
*BlackPoint = BlackXYZ;
|
||||
|
||||
@@ -182,34 +183,43 @@ cmsBool BlackPointUsingPerceptualBlack(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfi
|
||||
}
|
||||
|
||||
// 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
|
||||
// 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.
|
||||
|
||||
// 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)
|
||||
{
|
||||
{
|
||||
cmsProfileClassSignature devClass;
|
||||
|
||||
// Zero for black point
|
||||
if (cmsGetDeviceClass(hProfile) == cmsSigLinkClass) {
|
||||
|
||||
BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
|
||||
return FALSE;
|
||||
// Make sure the device class is adequate
|
||||
devClass = cmsGetDeviceClass(hProfile);
|
||||
if (devClass == cmsSigLinkClass ||
|
||||
devClass == cmsSigAbstractClass ||
|
||||
devClass == cmsSigNamedColorClass) {
|
||||
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.
|
||||
// Make sure intent is adequate
|
||||
if (Intent != INTENT_PERCEPTUAL &&
|
||||
Intent != INTENT_RELATIVE_COLORIMETRIC &&
|
||||
Intent != INTENT_SATURATION) {
|
||||
BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((cmsGetEncodedICCversion(hProfile) >= 0x4000000) &&
|
||||
// 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))
|
||||
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 -> X = cmsPERCEPTUAL_BLACK_X;
|
||||
BlackPoint -> Y = cmsPERCEPTUAL_BLACK_Y;
|
||||
BlackPoint -> Z = cmsPERCEPTUAL_BLACK_Z;
|
||||
|
||||
@@ -220,13 +230,13 @@ cmsBool CMSEXPORT cmsDetectBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfil
|
||||
#ifdef CMS_USE_PROFILE_BLACK_POINT_TAG
|
||||
|
||||
// v2, v4 rel/abs colorimetric
|
||||
if (cmsIsTag(hProfile, cmsSigMediaBlackPointTag) &&
|
||||
if (cmsIsTag(hProfile, cmsSigMediaBlackPointTag) &&
|
||||
Intent == INTENT_RELATIVE_COLORIMETRIC) {
|
||||
|
||||
cmsCIEXYZ *BlackPtr, BlackXYZ, UntrustedBlackPoint, TrustedBlackPoint, MediaWhite;
|
||||
cmsCIELab Lab;
|
||||
|
||||
// If black point is specified, then use it,
|
||||
// If black point is specified, then use it,
|
||||
|
||||
BlackPtr = cmsReadTag(hProfile, cmsSigMediaBlackPointTag);
|
||||
if (BlackPtr != NULL) {
|
||||
@@ -245,16 +255,16 @@ cmsBool CMSEXPORT cmsDetectBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfil
|
||||
|
||||
if (BlackPoint != NULL)
|
||||
*BlackPoint = TrustedBlackPoint;
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// That is about v2 profiles.
|
||||
// That is about v2 profiles.
|
||||
|
||||
// If output profile, discount ink-limiting and that's all
|
||||
if (Intent == INTENT_RELATIVE_COLORIMETRIC &&
|
||||
if (Intent == INTENT_RELATIVE_COLORIMETRIC &&
|
||||
(cmsGetDeviceClass(hProfile) == cmsSigOutputClass) &&
|
||||
(cmsGetColorSpace(hProfile) == cmsSigCmykData))
|
||||
return BlackPointUsingPerceptualBlack(BlackPoint, hProfile);
|
||||
@@ -264,3 +274,299 @@ cmsBool CMSEXPORT cmsDetectBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfil
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Least Squares Fit of a Quadratic Curve to Data
|
||||
// http://www.personal.psu.edu/jhm/f90/lectures/lsq2.html
|
||||
|
||||
static
|
||||
cmsFloat64Number RootOfLeastSquaresFitQuadraticCurve(int n, cmsFloat64Number x[], cmsFloat64Number y[])
|
||||
{
|
||||
double sum_x = 0, sum_x2 = 0, sum_x3 = 0, sum_x4 = 0;
|
||||
double sum_y = 0, sum_yx = 0, sum_yx2 = 0;
|
||||
double d, a, b, c;
|
||||
int i;
|
||||
cmsMAT3 m;
|
||||
cmsVEC3 v, res;
|
||||
|
||||
if (n < 4) return 0;
|
||||
|
||||
for (i=0; i < n; i++) {
|
||||
|
||||
double xn = x[i];
|
||||
double yn = y[i];
|
||||
|
||||
sum_x += xn;
|
||||
sum_x2 += xn*xn;
|
||||
sum_x3 += xn*xn*xn;
|
||||
sum_x4 += xn*xn*xn*xn;
|
||||
|
||||
sum_y += yn;
|
||||
sum_yx += yn*xn;
|
||||
sum_yx2 += yn*xn*xn;
|
||||
}
|
||||
|
||||
_cmsVEC3init(&m.v[0], n, sum_x, sum_x2);
|
||||
_cmsVEC3init(&m.v[1], sum_x, sum_x2, sum_x3);
|
||||
_cmsVEC3init(&m.v[2], sum_x2, sum_x3, sum_x4);
|
||||
|
||||
_cmsVEC3init(&v, sum_y, sum_yx, sum_yx2);
|
||||
|
||||
if (!_cmsMAT3solve(&res, &m, &v)) return 0;
|
||||
|
||||
|
||||
a = res.n[2];
|
||||
b = res.n[1];
|
||||
c = res.n[0];
|
||||
|
||||
if (fabs(a) < 1.0E-10) {
|
||||
|
||||
return cmsmin(0, cmsmax(50, -c/b ));
|
||||
}
|
||||
else {
|
||||
|
||||
d = b*b - 4.0 * a * c;
|
||||
if (d <= 0) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
|
||||
double rt = (-b + sqrt(d)) / (2.0 * a);
|
||||
|
||||
return cmsmax(0, cmsmin(50, rt));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
static
|
||||
cmsBool IsMonotonic(int n, const cmsFloat64Number Table[])
|
||||
{
|
||||
int i;
|
||||
cmsFloat64Number last;
|
||||
|
||||
last = Table[n-1];
|
||||
|
||||
for (i = n-2; i >= 0; --i) {
|
||||
|
||||
if (Table[i] > last)
|
||||
|
||||
return FALSE;
|
||||
else
|
||||
last = Table[i];
|
||||
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
*/
|
||||
|
||||
// Calculates the black point of a destination profile.
|
||||
// This algorithm comes from the Adobe paper disclosing its black point compensation method.
|
||||
cmsBool CMSEXPORT cmsDetectDestinationBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags)
|
||||
{
|
||||
cmsColorSpaceSignature ColorSpace;
|
||||
cmsHTRANSFORM hRoundTrip = NULL;
|
||||
cmsCIELab InitialLab, destLab, Lab;
|
||||
cmsFloat64Number inRamp[256], outRamp[256];
|
||||
cmsFloat64Number MinL, MaxL;
|
||||
cmsBool NearlyStraightMidrange = TRUE;
|
||||
cmsFloat64Number yRamp[256];
|
||||
cmsFloat64Number x[256], y[256];
|
||||
cmsFloat64Number lo, hi;
|
||||
int n, l;
|
||||
cmsProfileClassSignature devClass;
|
||||
|
||||
// Make sure the device class is adequate
|
||||
devClass = cmsGetDeviceClass(hProfile);
|
||||
if (devClass == cmsSigLinkClass ||
|
||||
devClass == cmsSigAbstractClass ||
|
||||
devClass == cmsSigNamedColorClass) {
|
||||
BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Make sure intent is adequate
|
||||
if (Intent != INTENT_PERCEPTUAL &&
|
||||
Intent != INTENT_RELATIVE_COLORIMETRIC &&
|
||||
Intent != INTENT_SATURATION) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
// Check if the profile is lut based and gray, rgb or cmyk (7.2 in Adobe's document)
|
||||
ColorSpace = cmsGetColorSpace(hProfile);
|
||||
if (!cmsIsCLUT(hProfile, Intent, LCMS_USED_AS_OUTPUT ) ||
|
||||
(ColorSpace != cmsSigGrayData &&
|
||||
ColorSpace != cmsSigRgbData &&
|
||||
ColorSpace != cmsSigCmykData)) {
|
||||
|
||||
// In this case, handle as input case
|
||||
return cmsDetectBlackPoint(BlackPoint, hProfile, Intent, dwFlags);
|
||||
}
|
||||
|
||||
// It is one of the valid cases!, use Adobe algorithm
|
||||
|
||||
|
||||
// Set a first guess, that should work on good profiles.
|
||||
if (Intent == INTENT_RELATIVE_COLORIMETRIC) {
|
||||
|
||||
cmsCIEXYZ IniXYZ;
|
||||
|
||||
// calculate initial Lab as source black point
|
||||
if (!cmsDetectBlackPoint(&IniXYZ, hProfile, Intent, dwFlags)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// convert the XYZ to lab
|
||||
cmsXYZ2Lab(NULL, &InitialLab, &IniXYZ);
|
||||
|
||||
} else {
|
||||
|
||||
// set the initial Lab to zero, that should be the black point for perceptual and saturation
|
||||
InitialLab.L = 0;
|
||||
InitialLab.a = 0;
|
||||
InitialLab.b = 0;
|
||||
}
|
||||
|
||||
|
||||
// Step 2
|
||||
// ======
|
||||
|
||||
// Create a roundtrip. Define a Transform BT for all x in L*a*b*
|
||||
hRoundTrip = CreateRoundtripXForm(hProfile, Intent);
|
||||
if (hRoundTrip == NULL) return FALSE;
|
||||
|
||||
// Compute ramps
|
||||
|
||||
for (l=0; l < 256; l++) {
|
||||
|
||||
Lab.L = (cmsFloat64Number) (l * 100.0) / 255.0;
|
||||
Lab.a = cmsmin(50, cmsmax(-50, InitialLab.a));
|
||||
Lab.b = cmsmin(50, cmsmax(-50, InitialLab.b));
|
||||
|
||||
cmsDoTransform(hRoundTrip, &Lab, &destLab, 1);
|
||||
|
||||
inRamp[l] = Lab.L;
|
||||
outRamp[l] = destLab.L;
|
||||
}
|
||||
|
||||
// Make monotonic
|
||||
for (l = 254; l > 0; --l) {
|
||||
outRamp[l] = cmsmin(outRamp[l], outRamp[l+1]);
|
||||
}
|
||||
|
||||
// Check
|
||||
if (! (outRamp[0] < outRamp[255])) {
|
||||
|
||||
cmsDeleteTransform(hRoundTrip);
|
||||
BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
// Test for mid range straight (only on relative colorimetric)
|
||||
|
||||
NearlyStraightMidrange = TRUE;
|
||||
MinL = outRamp[0]; MaxL = outRamp[255];
|
||||
if (Intent == INTENT_RELATIVE_COLORIMETRIC) {
|
||||
|
||||
for (l=0; l < 256; l++) {
|
||||
|
||||
if (! ((inRamp[l] <= MinL + 0.2 * (MaxL - MinL) ) ||
|
||||
(fabs(inRamp[l] - outRamp[l]) < 4.0 )))
|
||||
NearlyStraightMidrange = FALSE;
|
||||
}
|
||||
|
||||
// If the mid range is straight (as determined above) then the
|
||||
// DestinationBlackPoint shall be the same as initialLab.
|
||||
// Otherwise, the DestinationBlackPoint shall be determined
|
||||
// using curve fitting.
|
||||
|
||||
if (NearlyStraightMidrange) {
|
||||
|
||||
cmsLab2XYZ(NULL, BlackPoint, &InitialLab);
|
||||
cmsDeleteTransform(hRoundTrip);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// curve fitting: The round-trip curve normally looks like a nearly constant section at the black point,
|
||||
// with a corner and a nearly straight line to the white point.
|
||||
|
||||
for (l=0; l < 256; l++) {
|
||||
|
||||
yRamp[l] = (outRamp[l] - MinL) / (MaxL - MinL);
|
||||
}
|
||||
|
||||
// find the black point using the least squares error quadratic curve fitting
|
||||
|
||||
if (Intent == INTENT_RELATIVE_COLORIMETRIC) {
|
||||
lo = 0.1;
|
||||
hi = 0.5;
|
||||
}
|
||||
else {
|
||||
|
||||
// Perceptual and saturation
|
||||
lo = 0.03;
|
||||
hi = 0.25;
|
||||
}
|
||||
|
||||
// Capture shadow points for the fitting.
|
||||
n = 0;
|
||||
for (l=0; l < 256; l++) {
|
||||
|
||||
cmsFloat64Number ff = yRamp[l];
|
||||
|
||||
if (ff >= lo && ff < hi) {
|
||||
x[n] = inRamp[l];
|
||||
y[n] = yRamp[l];
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// No suitable points
|
||||
if (n < 3 ) {
|
||||
cmsDeleteTransform(hRoundTrip);
|
||||
BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
// fit and get the vertex of quadratic curve
|
||||
Lab.L = RootOfLeastSquaresFitQuadraticCurve(n, x, y);
|
||||
|
||||
if (Lab.L < 0.0) { // clip to zero L* if the vertex is negative
|
||||
Lab.L = 0;
|
||||
}
|
||||
|
||||
Lab.a = InitialLab.a;
|
||||
Lab.b = InitialLab.b;
|
||||
|
||||
cmsLab2XYZ(NULL, BlackPoint, &Lab);
|
||||
|
||||
cmsDeleteTransform(hRoundTrip);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
211
thirdparty/liblcms2/src/cmssm.c
vendored
211
thirdparty/liblcms2/src/cmssm.c
vendored
@@ -1,24 +1,24 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2011 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
|
||||
// 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
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
//---------------------------------------------------------------------------------
|
||||
@@ -36,7 +36,7 @@
|
||||
// alpha = Hab
|
||||
// theta = L*
|
||||
|
||||
#define SECTORS 16 // number of divisions in alpha and theta
|
||||
#define SECTORS 16 // number of divisions in alpha and theta
|
||||
|
||||
// Spherical coordinates
|
||||
typedef struct {
|
||||
@@ -47,7 +47,7 @@ typedef struct {
|
||||
|
||||
} cmsSpherical;
|
||||
|
||||
typedef enum {
|
||||
typedef enum {
|
||||
GP_EMPTY,
|
||||
GP_SPECIFIED,
|
||||
GP_MODELED
|
||||
@@ -101,7 +101,7 @@ static
|
||||
cmsFloat64Number _cmsAtan2(cmsFloat64Number y, cmsFloat64Number x)
|
||||
{
|
||||
cmsFloat64Number a;
|
||||
|
||||
|
||||
// Deal with undefined case
|
||||
if (x == 0.0 && y == 0.0) return 0;
|
||||
|
||||
@@ -120,20 +120,20 @@ 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);
|
||||
|
||||
sp ->alpha = _cmsAtan2(a, b);
|
||||
sp ->theta = _cmsAtan2(sqrt(a*a + b*b), L);
|
||||
}
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ void ToCartesian(cmsVEC3* v, const cmsSpherical* sp)
|
||||
cos_theta = cos((M_PI * sp ->theta) / 180.0);
|
||||
|
||||
a = sp ->r * sin_theta * sin_alpha;
|
||||
b = sp ->r * sin_theta * cos_alpha;
|
||||
b = sp ->r * sin_theta * cos_alpha;
|
||||
L = sp ->r * cos_theta;
|
||||
|
||||
v ->n[VX] = L;
|
||||
@@ -166,14 +166,14 @@ void ToCartesian(cmsVEC3* v, const cmsSpherical* sp)
|
||||
// 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) );
|
||||
{
|
||||
*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;
|
||||
if (*alpha >= SECTORS)
|
||||
*alpha = SECTORS-1;
|
||||
if (*theta >= SECTORS)
|
||||
*theta = SECTORS-1;
|
||||
}
|
||||
|
||||
|
||||
@@ -183,19 +183,19 @@ 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]);
|
||||
_cmsVEC3init(&line ->u, b ->n[VX] - a ->n[VX],
|
||||
b ->n[VY] - a ->n[VY],
|
||||
b ->n[VZ] - a ->n[VZ]);
|
||||
}
|
||||
|
||||
|
||||
// Evaluate parametric line
|
||||
// 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];
|
||||
p ->n[VZ] = line ->a.n[VZ] + t * line->u.n[VZ];
|
||||
}
|
||||
|
||||
|
||||
@@ -217,7 +217,7 @@ static
|
||||
cmsBool ClosestLineToLine(cmsVEC3* r, const cmsLine* line1, const cmsLine* line2)
|
||||
{
|
||||
cmsFloat64Number a, b, c, d, e, D;
|
||||
cmsFloat64Number sc, sN, sD;
|
||||
cmsFloat64Number sc, sN, sD;
|
||||
cmsFloat64Number tc, tN, tD;
|
||||
cmsVEC3 w0;
|
||||
|
||||
@@ -271,9 +271,9 @@ cmsBool ClosestLineToLine(cmsVEC3* r, const cmsLine* line1, const cmsLine* line2
|
||||
}
|
||||
}
|
||||
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;
|
||||
@@ -302,7 +302,7 @@ cmsHANDLE CMSEXPORT cmsGBDAlloc(cmsContext ContextID)
|
||||
{
|
||||
cmsGDB* gbd = (cmsGDB*) _cmsMallocZero(ContextID, sizeof(cmsGDB));
|
||||
if (gbd == NULL) return NULL;
|
||||
|
||||
|
||||
gbd -> ContextID = ContextID;
|
||||
|
||||
return (cmsHANDLE) gbd;
|
||||
@@ -310,9 +310,9 @@ cmsHANDLE CMSEXPORT cmsGBDAlloc(cmsContext ContextID)
|
||||
|
||||
|
||||
void CMSEXPORT cmsGBDFree(cmsHANDLE hGBD)
|
||||
{
|
||||
{
|
||||
cmsGDB* gbd = (cmsGDB*) hGBD;
|
||||
if (hGBD != NULL)
|
||||
if (hGBD != NULL)
|
||||
_cmsFree(gbd->ContextID, (void*) gbd);
|
||||
}
|
||||
|
||||
@@ -321,20 +321,20 @@ void CMSEXPORT cmsGBDFree(cmsHANDLE hGBD)
|
||||
static
|
||||
cmsGDBPoint* GetPoint(cmsGDB* gbd, const cmsCIELab* Lab, cmsSpherical* sp)
|
||||
{
|
||||
cmsVEC3 v;
|
||||
cmsVEC3 v;
|
||||
int alpha, theta;
|
||||
|
||||
// Housekeeping
|
||||
_cmsAssert(gbd != NULL);
|
||||
_cmsAssert(Lab != NULL);
|
||||
_cmsAssert(sp != NULL);
|
||||
_cmsAssert(Lab != NULL);
|
||||
_cmsAssert(sp != NULL);
|
||||
|
||||
// Center L* by substracting half of its domain, that's 50
|
||||
// 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;
|
||||
@@ -342,7 +342,7 @@ cmsGDBPoint* GetPoint(cmsGDB* gbd, const cmsCIELab* Lab, cmsSpherical* sp)
|
||||
|
||||
// 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;
|
||||
@@ -352,7 +352,7 @@ cmsGDBPoint* GetPoint(cmsGDB* gbd, const cmsCIELab* Lab, cmsSpherical* sp)
|
||||
return &gbd ->Gamut[theta][alpha];
|
||||
}
|
||||
|
||||
// Add a point to gamut descriptor. Point to add is in Lab color space.
|
||||
// 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)
|
||||
{
|
||||
@@ -388,7 +388,7 @@ cmsBool CMSEXPORT cmsGDBAddPoint(cmsHANDLE hGBD, const cmsCIELab* Lab)
|
||||
// Check if a given point falls inside gamut
|
||||
cmsBool CMSEXPORT cmsGDBCheckPoint(cmsHANDLE hGBD, const cmsCIELab* Lab)
|
||||
{
|
||||
cmsGDB* gbd = (cmsGDB*) hGBD;
|
||||
cmsGDB* gbd = (cmsGDB*) hGBD;
|
||||
cmsGDBPoint* ptr;
|
||||
cmsSpherical sp;
|
||||
|
||||
@@ -406,7 +406,7 @@ cmsBool CMSEXPORT cmsGDBCheckPoint(cmsHANDLE hGBD, const cmsCIELab* Lab)
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Find near sectors. The list of sectors found is returned on Close[].
|
||||
// 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
|
||||
@@ -416,21 +416,21 @@ cmsBool CMSEXPORT cmsGDBCheckPoint(cmsHANDLE hGBD, const cmsCIELab* Lab)
|
||||
// 20 19 18 17 16
|
||||
//
|
||||
// Those are the relative movements
|
||||
// {-2,-2}, {-1, -2}, {0, -2}, {+1, -2}, {+2, -2},
|
||||
// {-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 {
|
||||
|
||||
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},
|
||||
|
||||
} 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))
|
||||
@@ -439,7 +439,8 @@ static
|
||||
int FindNearSectors(cmsGDB* gbd, int alpha, int theta, cmsGDBPoint* Close[])
|
||||
{
|
||||
int nSectors = 0;
|
||||
int i, a, t;
|
||||
int a, t;
|
||||
cmsUInt32Number i;
|
||||
cmsGDBPoint* pt;
|
||||
|
||||
for (i=0; i < NSTEPS; i++) {
|
||||
@@ -453,14 +454,14 @@ int FindNearSectors(cmsGDB* gbd, int alpha, int theta, cmsGDBPoint* Close[])
|
||||
|
||||
// Cycle at the begin
|
||||
if (a < 0) a = SECTORS + a;
|
||||
if (t < 0) t = SECTORS + t;
|
||||
if (t < 0) t = SECTORS + t;
|
||||
|
||||
pt = &gbd ->Gamut[t][a];
|
||||
|
||||
|
||||
if (pt -> Type != GP_EMPTY) {
|
||||
|
||||
Close[nSectors++] = pt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nSectors;
|
||||
@@ -470,17 +471,17 @@ int FindNearSectors(cmsGDB* gbd, int alpha, int theta, cmsGDBPoint* Close[])
|
||||
// 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];
|
||||
cmsGDBPoint* Close[NSTEPS + 1];
|
||||
cmsSpherical closel, templ;
|
||||
cmsLine edge;
|
||||
int k, m;
|
||||
|
||||
|
||||
// Is that point already specified?
|
||||
if (gbd ->Gamut[theta][alpha].Type != GP_EMPTY) return TRUE;
|
||||
|
||||
@@ -488,10 +489,10 @@ cmsBool InterpolateMissingSector(cmsGDB* gbd, int alpha, int theta)
|
||||
nCloseSectors = FindNearSectors(gbd, alpha, theta, Close);
|
||||
|
||||
|
||||
// Find a central point on the sector
|
||||
// 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;
|
||||
sp.r = 50.0;
|
||||
|
||||
// Convert to Cartesian
|
||||
ToCartesian(&Lab, &sp);
|
||||
@@ -510,28 +511,28 @@ cmsBool InterpolateMissingSector(cmsGDB* gbd, int alpha, int theta)
|
||||
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
|
||||
// Find a line
|
||||
ClosestLineToLine(&temp, &ray, &edge);
|
||||
|
||||
// Convert to spherical
|
||||
ToSpherical(&templ, &temp);
|
||||
|
||||
|
||||
if ( templ.r > closel.r &&
|
||||
templ.theta >= (theta*180.0/SECTORS) &&
|
||||
|
||||
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;
|
||||
}
|
||||
closel = templ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -553,13 +554,13 @@ cmsBool CMSEXPORT cmsGDBCompute(cmsHANDLE hGBD, cmsUInt32Number dwFlags)
|
||||
_cmsAssert(hGBD != NULL);
|
||||
|
||||
// Interpolate black
|
||||
for (alpha = 0; alpha <= SECTORS; alpha++) {
|
||||
for (alpha = 0; alpha < SECTORS; alpha++) {
|
||||
|
||||
if (!InterpolateMissingSector(gbd, alpha, 0)) return FALSE;
|
||||
}
|
||||
|
||||
// Interpolate white
|
||||
for (alpha = 0; alpha <= SECTORS; alpha++) {
|
||||
for (alpha = 0; alpha < SECTORS; alpha++) {
|
||||
|
||||
if (!InterpolateMissingSector(gbd, alpha, SECTORS-1)) return FALSE;
|
||||
}
|
||||
@@ -567,7 +568,7 @@ cmsBool CMSEXPORT cmsGDBCompute(cmsHANDLE hGBD, cmsUInt32Number dwFlags)
|
||||
|
||||
// Interpolate Mid
|
||||
for (theta = 1; theta < SECTORS; theta++) {
|
||||
for (alpha = 0; alpha <= SECTORS; alpha++) {
|
||||
for (alpha = 0; alpha < SECTORS; alpha++) {
|
||||
|
||||
if (!InterpolateMissingSector(gbd, alpha, theta)) return FALSE;
|
||||
}
|
||||
@@ -600,34 +601,34 @@ cmsBool cmsGBDdumpVRML(cmsHANDLE hGBD, const char* fname)
|
||||
|
||||
fprintf (fp, "#VRML V2.0 utf8\n");
|
||||
|
||||
// set the viewing orientation and distance
|
||||
// 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");
|
||||
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
|
||||
// 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
|
||||
// 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:
|
||||
// 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");
|
||||
@@ -651,7 +652,7 @@ cmsBool cmsGBDdumpVRML(cmsHANDLE hGBD, const char* fname)
|
||||
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");
|
||||
@@ -661,8 +662,8 @@ cmsBool cmsGBDdumpVRML(cmsHANDLE hGBD, const char* fname)
|
||||
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
|
||||
|
||||
// fill in the points here
|
||||
fprintf (fp, "\t\t\t\tcoord Coordinate {\n");
|
||||
fprintf (fp, "\t\t\t\t\tpoint [\n");
|
||||
|
||||
@@ -677,7 +678,7 @@ cmsBool cmsGBDdumpVRML(cmsHANDLE hGBD, const char* fname)
|
||||
|
||||
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))
|
||||
if ((j == SECTORS - 1) && (i == SECTORS - 1))
|
||||
fprintf (fp, "]\n");
|
||||
else
|
||||
fprintf (fp, ",\n");
|
||||
@@ -688,7 +689,7 @@ cmsBool cmsGBDdumpVRML(cmsHANDLE hGBD, const char* fname)
|
||||
|
||||
|
||||
|
||||
// fill in the face colors
|
||||
// fill in the face colors
|
||||
fprintf (fp, "\t\t\t\tcolor Color {\n");
|
||||
fprintf (fp, "\t\t\t\t\tcolor [\n");
|
||||
|
||||
@@ -696,30 +697,30 @@ cmsBool cmsGBDdumpVRML(cmsHANDLE hGBD, const char* fname)
|
||||
for (j=0; j < SECTORS; j++) {
|
||||
|
||||
cmsVEC3 v;
|
||||
|
||||
|
||||
pt = &gbd ->Gamut[i][j];
|
||||
|
||||
|
||||
|
||||
ToCartesian(&v, &pt ->p);
|
||||
|
||||
|
||||
if (pt ->Type == GP_EMPTY)
|
||||
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 {
|
||||
else {
|
||||
fprintf (fp, "\t\t\t\t\t%g %g %g", 1.0, 1.0, 1.0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ((j == SECTORS - 1) && (i == SECTORS - 1))
|
||||
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");
|
||||
|
||||
1958
thirdparty/liblcms2/src/cmstypes.c
vendored
1958
thirdparty/liblcms2/src/cmstypes.c
vendored
File diff suppressed because it is too large
Load Diff
442
thirdparty/liblcms2/src/cmsvirt.c
vendored
442
thirdparty/liblcms2/src/cmsvirt.c
vendored
@@ -1,24 +1,24 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2014 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
|
||||
// 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
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
//---------------------------------------------------------------------------------
|
||||
@@ -35,7 +35,7 @@ cmsBool SetTextTags(cmsHPROFILE hProfile, const wchar_t* Description)
|
||||
cmsMLU *DescriptionMLU, *CopyrightMLU;
|
||||
cmsBool rc = FALSE;
|
||||
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
||||
|
||||
|
||||
DescriptionMLU = cmsMLUalloc(ContextID, 1);
|
||||
CopyrightMLU = cmsMLUalloc(ContextID, 1);
|
||||
|
||||
@@ -45,8 +45,8 @@ cmsBool SetTextTags(cmsHPROFILE hProfile, const wchar_t* Description)
|
||||
if (!cmsMLUsetWide(CopyrightMLU, "en", "US", L"No copyright, use freely")) goto Error;
|
||||
|
||||
if (!cmsWriteTag(hProfile, cmsSigProfileDescriptionTag, DescriptionMLU)) goto Error;
|
||||
if (!cmsWriteTag(hProfile, cmsSigCopyrightTag, CopyrightMLU)) goto Error;
|
||||
|
||||
if (!cmsWriteTag(hProfile, cmsSigCopyrightTag, CopyrightMLU)) goto Error;
|
||||
|
||||
rc = TRUE;
|
||||
|
||||
Error:
|
||||
@@ -57,7 +57,7 @@ Error:
|
||||
cmsMLUfree(CopyrightMLU);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static
|
||||
cmsBool SetSeqDescTag(cmsHPROFILE hProfile, const char* Model)
|
||||
@@ -72,10 +72,10 @@ cmsBool SetSeqDescTag(cmsHPROFILE hProfile, const char* Model)
|
||||
Seq->seq[0].deviceModel = (cmsSignature) 0;
|
||||
|
||||
#ifdef CMS_DONT_USE_INT64
|
||||
Seq->seq[0].attributes[0] = 0;
|
||||
Seq->seq[0].attributes[1] = 0;
|
||||
Seq->seq[0].attributes[0] = 0;
|
||||
Seq->seq[0].attributes[1] = 0;
|
||||
#else
|
||||
Seq->seq[0].attributes = 0;
|
||||
Seq->seq[0].attributes = 0;
|
||||
#endif
|
||||
|
||||
Seq->seq[0].technology = (cmsTechnologySignature) 0;
|
||||
@@ -84,11 +84,11 @@ cmsBool SetSeqDescTag(cmsHPROFILE hProfile, const char* Model)
|
||||
cmsMLUsetASCII( Seq->seq[0].Model, cmsNoLanguage, cmsNoCountry, Model);
|
||||
|
||||
if (!_cmsWriteProfileSequence(hProfile, Seq)) goto Error;
|
||||
|
||||
|
||||
rc = TRUE;
|
||||
|
||||
Error:
|
||||
if (Seq)
|
||||
if (Seq)
|
||||
cmsFreeProfileSequenceDescription(Seq);
|
||||
|
||||
return rc;
|
||||
@@ -103,7 +103,7 @@ cmsHPROFILE CMSEXPORT cmsCreateRGBProfileTHR(cmsContext ContextID,
|
||||
const cmsCIExyYTRIPLE* Primaries,
|
||||
cmsToneCurve* const TransferFunction[3])
|
||||
{
|
||||
cmsHPROFILE hICC;
|
||||
cmsHPROFILE hICC;
|
||||
cmsMAT3 MColorants;
|
||||
cmsCIEXYZTRIPLE Colorants;
|
||||
cmsCIExyY MaxWhite;
|
||||
@@ -114,13 +114,13 @@ cmsHPROFILE CMSEXPORT cmsCreateRGBProfileTHR(cmsContext ContextID,
|
||||
if (!hICC) // can't allocate
|
||||
return NULL;
|
||||
|
||||
cmsSetProfileVersion(hICC, 4.2);
|
||||
cmsSetProfileVersion(hICC, 4.3);
|
||||
|
||||
cmsSetDeviceClass(hICC, cmsSigDisplayClass);
|
||||
cmsSetColorSpace(hICC, cmsSigRgbData);
|
||||
cmsSetPCS(hICC, cmsSigXYZData);
|
||||
|
||||
cmsSetHeaderRenderingIntent(hICC, INTENT_PERCEPTUAL);
|
||||
cmsSetHeaderRenderingIntent(hICC, INTENT_PERCEPTUAL);
|
||||
|
||||
|
||||
// Implement profile using following tags:
|
||||
@@ -137,7 +137,7 @@ cmsHPROFILE CMSEXPORT cmsCreateRGBProfileTHR(cmsContext ContextID,
|
||||
// This conforms a standard RGB DisplayProfile as says ICC, and then I add (As per addendum II)
|
||||
// 10 cmsSigChromaticityTag
|
||||
|
||||
|
||||
|
||||
if (!SetTextTags(hICC, L"RGB built-in")) goto Error;
|
||||
|
||||
if (WhitePoint) {
|
||||
@@ -145,9 +145,9 @@ cmsHPROFILE CMSEXPORT cmsCreateRGBProfileTHR(cmsContext ContextID,
|
||||
if (!cmsWriteTag(hICC, cmsSigMediaWhitePointTag, cmsD50_XYZ())) goto Error;
|
||||
|
||||
cmsxyY2XYZ(&WhitePointXYZ, WhitePoint);
|
||||
_cmsAdaptationMatrix(&CHAD, NULL, &WhitePointXYZ, cmsD50_XYZ());
|
||||
_cmsAdaptationMatrix(&CHAD, NULL, &WhitePointXYZ, cmsD50_XYZ());
|
||||
|
||||
// This is a V4 tag, but many CMM does read and understand it no matter which version
|
||||
// This is a V4 tag, but many CMM does read and understand it no matter which version
|
||||
if (!cmsWriteTag(hICC, cmsSigChromaticAdaptationTag, (void*) &CHAD)) goto Error;
|
||||
}
|
||||
|
||||
@@ -157,8 +157,8 @@ cmsHPROFILE CMSEXPORT cmsCreateRGBProfileTHR(cmsContext ContextID,
|
||||
MaxWhite.y = WhitePoint -> y;
|
||||
MaxWhite.Y = 1.0;
|
||||
|
||||
if (!_cmsBuildRGB2XYZtransferMatrix(&MColorants, &MaxWhite, Primaries)) goto Error;
|
||||
|
||||
if (!_cmsBuildRGB2XYZtransferMatrix(&MColorants, &MaxWhite, Primaries)) goto Error;
|
||||
|
||||
Colorants.Red.X = MColorants.v[0].n[0];
|
||||
Colorants.Red.Y = MColorants.v[1].n[0];
|
||||
Colorants.Red.Z = MColorants.v[2].n[0];
|
||||
@@ -178,10 +178,27 @@ cmsHPROFILE CMSEXPORT cmsCreateRGBProfileTHR(cmsContext ContextID,
|
||||
|
||||
|
||||
if (TransferFunction) {
|
||||
|
||||
|
||||
// Tries to minimize space. Thanks to Richard Hughes for this nice idea
|
||||
if (!cmsWriteTag(hICC, cmsSigRedTRCTag, (void*) TransferFunction[0])) goto Error;
|
||||
if (!cmsWriteTag(hICC, cmsSigGreenTRCTag, (void*) TransferFunction[1])) goto Error;
|
||||
if (!cmsWriteTag(hICC, cmsSigBlueTRCTag, (void*) TransferFunction[2])) goto Error;
|
||||
|
||||
if (TransferFunction[1] == TransferFunction[0]) {
|
||||
|
||||
if (!cmsLinkTag (hICC, cmsSigGreenTRCTag, cmsSigRedTRCTag)) goto Error;
|
||||
|
||||
} else {
|
||||
|
||||
if (!cmsWriteTag(hICC, cmsSigGreenTRCTag, (void*) TransferFunction[1])) goto Error;
|
||||
}
|
||||
|
||||
if (TransferFunction[2] == TransferFunction[0]) {
|
||||
|
||||
if (!cmsLinkTag (hICC, cmsSigBlueTRCTag, cmsSigRedTRCTag)) goto Error;
|
||||
|
||||
} else {
|
||||
|
||||
if (!cmsWriteTag(hICC, cmsSigBlueTRCTag, (void*) TransferFunction[2])) goto Error;
|
||||
}
|
||||
}
|
||||
|
||||
if (Primaries) {
|
||||
@@ -212,18 +229,18 @@ cmsHPROFILE CMSEXPORT cmsCreateGrayProfileTHR(cmsContext ContextID,
|
||||
const cmsToneCurve* TransferFunction)
|
||||
{
|
||||
cmsHPROFILE hICC;
|
||||
cmsCIEXYZ tmp;
|
||||
cmsCIEXYZ tmp;
|
||||
|
||||
hICC = cmsCreateProfilePlaceholder(ContextID);
|
||||
if (!hICC) // can't allocate
|
||||
return NULL;
|
||||
|
||||
cmsSetProfileVersion(hICC, 4.2);
|
||||
cmsSetProfileVersion(hICC, 4.3);
|
||||
|
||||
cmsSetDeviceClass(hICC, cmsSigDisplayClass);
|
||||
cmsSetColorSpace(hICC, cmsSigGrayData);
|
||||
cmsSetPCS(hICC, cmsSigXYZData);
|
||||
cmsSetHeaderRenderingIntent(hICC, INTENT_PERCEPTUAL);
|
||||
cmsSetHeaderRenderingIntent(hICC, INTENT_PERCEPTUAL);
|
||||
|
||||
|
||||
// Implement profile using following tags:
|
||||
@@ -232,7 +249,7 @@ cmsHPROFILE CMSEXPORT cmsCreateGrayProfileTHR(cmsContext ContextID,
|
||||
// 2 cmsSigMediaWhitePointTag
|
||||
// 3 cmsSigGrayTRCTag
|
||||
|
||||
// This conforms a standard Gray DisplayProfile
|
||||
// This conforms a standard Gray DisplayProfile
|
||||
|
||||
// Fill-in the tags
|
||||
|
||||
@@ -274,20 +291,19 @@ cmsHPROFILE CMSEXPORT cmsCreateLinearizationDeviceLinkTHR(cmsContext ContextID,
|
||||
{
|
||||
cmsHPROFILE hICC;
|
||||
cmsPipeline* Pipeline;
|
||||
cmsStage* Lin;
|
||||
int nChannels;
|
||||
|
||||
hICC = cmsCreateProfilePlaceholder(ContextID);
|
||||
if (!hICC)
|
||||
if (!hICC)
|
||||
return NULL;
|
||||
|
||||
cmsSetProfileVersion(hICC, 4.2);
|
||||
cmsSetProfileVersion(hICC, 4.3);
|
||||
|
||||
cmsSetDeviceClass(hICC, cmsSigLinkClass);
|
||||
cmsSetColorSpace(hICC, ColorSpace);
|
||||
cmsSetPCS(hICC, ColorSpace);
|
||||
|
||||
cmsSetHeaderRenderingIntent(hICC, INTENT_PERCEPTUAL);
|
||||
cmsSetHeaderRenderingIntent(hICC, INTENT_PERCEPTUAL);
|
||||
|
||||
// Set up channels
|
||||
nChannels = cmsChannelsOf(ColorSpace);
|
||||
@@ -298,14 +314,12 @@ cmsHPROFILE CMSEXPORT cmsCreateLinearizationDeviceLinkTHR(cmsContext ContextID,
|
||||
|
||||
|
||||
// Copy tables to Pipeline
|
||||
Lin = cmsStageAllocToneCurves(ContextID, nChannels, TransferFunctions);
|
||||
if (Lin == NULL) goto Error;
|
||||
if (!cmsPipelineInsertStage(Pipeline, cmsAT_BEGIN, cmsStageAllocToneCurves(ContextID, nChannels, TransferFunctions)))
|
||||
goto Error;
|
||||
|
||||
cmsPipelineInsertStage(Pipeline, cmsAT_BEGIN, Lin);
|
||||
|
||||
// Create tags
|
||||
if (!SetTextTags(hICC, L"Linearization built-in")) goto Error;
|
||||
if (!cmsWriteTag(hICC, cmsSigAToB0Tag, (void*) Pipeline)) goto Error;
|
||||
// Create tags
|
||||
if (!SetTextTags(hICC, L"Linearization built-in")) goto Error;
|
||||
if (!cmsWriteTag(hICC, cmsSigAToB0Tag, (void*) Pipeline)) goto Error;
|
||||
if (!SetSeqDescTag(hICC, "Linearization built-in")) goto Error;
|
||||
|
||||
// Pipeline is already on virtual profile
|
||||
@@ -315,6 +329,7 @@ cmsHPROFILE CMSEXPORT cmsCreateLinearizationDeviceLinkTHR(cmsContext ContextID,
|
||||
return hICC;
|
||||
|
||||
Error:
|
||||
cmsPipelineFree(Pipeline);
|
||||
if (hICC)
|
||||
cmsCloseProfile(hICC);
|
||||
|
||||
@@ -330,13 +345,13 @@ cmsHPROFILE CMSEXPORT cmsCreateLinearizationDeviceLink(cmsColorSpaceSignature Co
|
||||
|
||||
// Ink-limiting algorithm
|
||||
//
|
||||
// Sum = C + M + Y + K
|
||||
// If Sum > InkLimit
|
||||
// Sum = C + M + Y + K
|
||||
// If Sum > InkLimit
|
||||
// Ratio= 1 - (Sum - InkLimit) / (C + M + Y)
|
||||
// if Ratio <0
|
||||
// if Ratio <0
|
||||
// Ratio=0
|
||||
// endif
|
||||
// Else
|
||||
// endif
|
||||
// Else
|
||||
// Ratio=1
|
||||
// endif
|
||||
//
|
||||
@@ -354,7 +369,7 @@ int InkLimitingSampler(register const cmsUInt16Number In[], register cmsUInt16Nu
|
||||
InkLimit = (InkLimit * 655.35);
|
||||
|
||||
SumCMY = In[0] + In[1] + In[2];
|
||||
SumCMYK = SumCMY + In[3];
|
||||
SumCMYK = SumCMY + In[3];
|
||||
|
||||
if (SumCMYK > InkLimit) {
|
||||
|
||||
@@ -375,7 +390,7 @@ int InkLimitingSampler(register const cmsUInt16Number In[], register cmsUInt16Nu
|
||||
|
||||
// This is a devicelink operating in CMYK for ink-limiting
|
||||
|
||||
cmsHPROFILE CMSEXPORT cmsCreateInkLimitingDeviceLinkTHR(cmsContext ContextID,
|
||||
cmsHPROFILE CMSEXPORT cmsCreateInkLimitingDeviceLinkTHR(cmsContext ContextID,
|
||||
cmsColorSpaceSignature ColorSpace,
|
||||
cmsFloat64Number Limit)
|
||||
{
|
||||
@@ -383,7 +398,7 @@ cmsHPROFILE CMSEXPORT cmsCreateInkLimitingDeviceLinkTHR(cmsContext ContextID,
|
||||
cmsPipeline* LUT;
|
||||
cmsStage* CLUT;
|
||||
int nChannels;
|
||||
|
||||
|
||||
if (ColorSpace != cmsSigCmykData) {
|
||||
cmsSignalError(ContextID, cmsERROR_COLORSPACE_CHECK, "InkLimiting: Only CMYK currently supported");
|
||||
return NULL;
|
||||
@@ -391,7 +406,7 @@ cmsHPROFILE CMSEXPORT cmsCreateInkLimitingDeviceLinkTHR(cmsContext ContextID,
|
||||
|
||||
if (Limit < 0.0 || Limit > 400) {
|
||||
|
||||
cmsSignalError(ContextID, cmsERROR_RANGE, "InkLimiting: Limit should be between 0..400");
|
||||
cmsSignalError(ContextID, cmsERROR_RANGE, "InkLimiting: Limit should be between 0..400");
|
||||
if (Limit < 0) Limit = 0;
|
||||
if (Limit > 400) Limit = 400;
|
||||
|
||||
@@ -401,37 +416,38 @@ cmsHPROFILE CMSEXPORT cmsCreateInkLimitingDeviceLinkTHR(cmsContext ContextID,
|
||||
if (!hICC) // can't allocate
|
||||
return NULL;
|
||||
|
||||
cmsSetProfileVersion(hICC, 4.2);
|
||||
cmsSetProfileVersion(hICC, 4.3);
|
||||
|
||||
cmsSetDeviceClass(hICC, cmsSigLinkClass);
|
||||
cmsSetColorSpace(hICC, ColorSpace);
|
||||
cmsSetPCS(hICC, ColorSpace);
|
||||
|
||||
cmsSetHeaderRenderingIntent(hICC, INTENT_PERCEPTUAL);
|
||||
cmsSetHeaderRenderingIntent(hICC, INTENT_PERCEPTUAL);
|
||||
|
||||
|
||||
// Creates a Pipeline with 3D grid only
|
||||
LUT = cmsPipelineAlloc(ContextID, 4, 4);
|
||||
if (LUT == NULL) goto Error;
|
||||
|
||||
|
||||
|
||||
nChannels = cmsChannelsOf(ColorSpace);
|
||||
|
||||
|
||||
CLUT = cmsStageAllocCLut16bit(ContextID, 17, nChannels, nChannels, NULL);
|
||||
if (CLUT == NULL) goto Error;
|
||||
|
||||
if (!cmsStageSampleCLut16bit(CLUT, InkLimitingSampler, (void*) &Limit, 0)) goto Error;
|
||||
|
||||
cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, nChannels));
|
||||
cmsPipelineInsertStage(LUT, cmsAT_END, CLUT);
|
||||
cmsPipelineInsertStage(LUT, cmsAT_END, _cmsStageAllocIdentityCurves(ContextID, nChannels));
|
||||
if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, nChannels)) ||
|
||||
!cmsPipelineInsertStage(LUT, cmsAT_END, CLUT) ||
|
||||
!cmsPipelineInsertStage(LUT, cmsAT_END, _cmsStageAllocIdentityCurves(ContextID, nChannels)))
|
||||
goto Error;
|
||||
|
||||
// Create tags
|
||||
if (!SetTextTags(hICC, L"ink-limiting built-in")) goto Error;
|
||||
|
||||
if (!cmsWriteTag(hICC, cmsSigAToB0Tag, (void*) LUT)) goto Error;
|
||||
if (!SetSeqDescTag(hICC, "ink-limiting built-in")) goto Error;
|
||||
|
||||
|
||||
// cmsPipeline is already on virtual profile
|
||||
cmsPipelineFree(LUT);
|
||||
|
||||
@@ -457,9 +473,9 @@ cmsHPROFILE CMSEXPORT cmsCreateInkLimitingDeviceLink(cmsColorSpaceSignature Colo
|
||||
// Creates a fake Lab identity.
|
||||
cmsHPROFILE CMSEXPORT cmsCreateLab2ProfileTHR(cmsContext ContextID, const cmsCIExyY* WhitePoint)
|
||||
{
|
||||
cmsHPROFILE hProfile;
|
||||
cmsHPROFILE hProfile;
|
||||
cmsPipeline* LUT = NULL;
|
||||
|
||||
|
||||
hProfile = cmsCreateRGBProfileTHR(ContextID, WhitePoint == NULL ? cmsD50_xyY() : WhitePoint, NULL, NULL);
|
||||
if (hProfile == NULL) return NULL;
|
||||
|
||||
@@ -475,7 +491,8 @@ cmsHPROFILE CMSEXPORT cmsCreateLab2ProfileTHR(cmsContext ContextID, const cmsCIE
|
||||
LUT = cmsPipelineAlloc(ContextID, 3, 3);
|
||||
if (LUT == NULL) goto Error;
|
||||
|
||||
cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCLut(ContextID, 3));
|
||||
if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCLut(ContextID, 3)))
|
||||
goto Error;
|
||||
|
||||
if (!cmsWriteTag(hProfile, cmsSigAToB0Tag, LUT)) goto Error;
|
||||
cmsPipelineFree(LUT);
|
||||
@@ -503,13 +520,13 @@ cmsHPROFILE CMSEXPORT cmsCreateLab2Profile(const cmsCIExyY* WhitePoint)
|
||||
// Creates a fake Lab V4 identity.
|
||||
cmsHPROFILE CMSEXPORT cmsCreateLab4ProfileTHR(cmsContext ContextID, const cmsCIExyY* WhitePoint)
|
||||
{
|
||||
cmsHPROFILE hProfile;
|
||||
cmsHPROFILE hProfile;
|
||||
cmsPipeline* LUT = NULL;
|
||||
|
||||
|
||||
hProfile = cmsCreateRGBProfileTHR(ContextID, WhitePoint == NULL ? cmsD50_xyY() : WhitePoint, NULL, NULL);
|
||||
if (hProfile == NULL) return NULL;
|
||||
|
||||
cmsSetProfileVersion(hProfile, 4.2);
|
||||
cmsSetProfileVersion(hProfile, 4.3);
|
||||
|
||||
cmsSetDeviceClass(hProfile, cmsSigAbstractClass);
|
||||
cmsSetColorSpace(hProfile, cmsSigLabData);
|
||||
@@ -521,7 +538,8 @@ cmsHPROFILE CMSEXPORT cmsCreateLab4ProfileTHR(cmsContext ContextID, const cmsCIE
|
||||
LUT = cmsPipelineAlloc(ContextID, 3, 3);
|
||||
if (LUT == NULL) goto Error;
|
||||
|
||||
cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, 3));
|
||||
if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, 3)))
|
||||
goto Error;
|
||||
|
||||
if (!cmsWriteTag(hProfile, cmsSigAToB0Tag, LUT)) goto Error;
|
||||
cmsPipelineFree(LUT);
|
||||
@@ -548,13 +566,13 @@ cmsHPROFILE CMSEXPORT cmsCreateLab4Profile(const cmsCIExyY* WhitePoint)
|
||||
// Creates a fake XYZ identity
|
||||
cmsHPROFILE CMSEXPORT cmsCreateXYZProfileTHR(cmsContext ContextID)
|
||||
{
|
||||
cmsHPROFILE hProfile;
|
||||
cmsHPROFILE hProfile;
|
||||
cmsPipeline* LUT = NULL;
|
||||
|
||||
|
||||
hProfile = cmsCreateRGBProfileTHR(ContextID, cmsD50_xyY(), NULL, NULL);
|
||||
if (hProfile == NULL) return NULL;
|
||||
|
||||
cmsSetProfileVersion(hProfile, 4.2);
|
||||
cmsSetProfileVersion(hProfile, 4.3);
|
||||
|
||||
cmsSetDeviceClass(hProfile, cmsSigAbstractClass);
|
||||
cmsSetColorSpace(hProfile, cmsSigXYZData);
|
||||
@@ -566,7 +584,8 @@ cmsHPROFILE CMSEXPORT cmsCreateXYZProfileTHR(cmsContext ContextID)
|
||||
LUT = cmsPipelineAlloc(ContextID, 3, 3);
|
||||
if (LUT == NULL) goto Error;
|
||||
|
||||
cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, 3));
|
||||
if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, 3)))
|
||||
goto Error;
|
||||
|
||||
if (!cmsWriteTag(hProfile, cmsSigAToB0Tag, LUT)) goto Error;
|
||||
cmsPipelineFree(LUT);
|
||||
@@ -615,12 +634,12 @@ cmsToneCurve* Build_sRGBGamma(cmsContext ContextID)
|
||||
Parameters[1] = 1. / 1.055;
|
||||
Parameters[2] = 0.055 / 1.055;
|
||||
Parameters[3] = 1. / 12.92;
|
||||
Parameters[4] = 0.04045;
|
||||
Parameters[4] = 0.04045;
|
||||
|
||||
return cmsBuildParametricToneCurve(ContextID, 4, Parameters);
|
||||
}
|
||||
|
||||
// Create the ICC virtual profile for sRGB space
|
||||
// Create the ICC virtual profile for sRGB space
|
||||
cmsHPROFILE CMSEXPORT cmsCreate_sRGBProfileTHR(cmsContext ContextID)
|
||||
{
|
||||
cmsCIExyY D65;
|
||||
@@ -631,11 +650,11 @@ cmsHPROFILE CMSEXPORT cmsCreate_sRGBProfileTHR(cmsContext ContextID)
|
||||
};
|
||||
cmsToneCurve* Gamma22[3];
|
||||
cmsHPROFILE hsRGB;
|
||||
|
||||
|
||||
cmsWhitePointFromTemp(&D65, 6504);
|
||||
Gamma22[0] = Gamma22[1] = Gamma22[2] = Build_sRGBGamma(ContextID);
|
||||
if (Gamma22[0] == NULL) return NULL;
|
||||
|
||||
|
||||
hsRGB = cmsCreateRGBProfileTHR(ContextID, &D65, &Rec709Primaries, Gamma22);
|
||||
cmsFreeToneCurve(Gamma22[0]);
|
||||
if (hsRGB == NULL) return NULL;
|
||||
@@ -672,31 +691,31 @@ int bchswSampler(register const cmsUInt16Number In[], register cmsUInt16Number O
|
||||
cmsCIELCh LChIn, LChOut;
|
||||
cmsCIEXYZ XYZ;
|
||||
LPBCHSWADJUSTS bchsw = (LPBCHSWADJUSTS) Cargo;
|
||||
|
||||
|
||||
|
||||
cmsLabEncoded2Float(&LabIn, In);
|
||||
|
||||
|
||||
|
||||
cmsLab2LCh(&LChIn, &LabIn);
|
||||
|
||||
// Do some adjusts on LCh
|
||||
|
||||
|
||||
LChOut.L = LChIn.L * bchsw ->Contrast + bchsw ->Brightness;
|
||||
LChOut.C = LChIn.C + bchsw -> Saturation;
|
||||
LChOut.h = LChIn.h + bchsw -> Hue;
|
||||
|
||||
|
||||
|
||||
|
||||
cmsLCh2Lab(&LabOut, &LChOut);
|
||||
|
||||
// Move white point in Lab
|
||||
|
||||
cmsLab2XYZ(&bchsw ->WPsrc, &XYZ, &LabOut);
|
||||
cmsXYZ2Lab(&bchsw ->WPdest, &LabOut, &XYZ);
|
||||
|
||||
|
||||
// Back to encoded
|
||||
|
||||
cmsFloat2LabEncoded(Out, &LabOut);
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -705,101 +724,103 @@ int bchswSampler(register const cmsUInt16Number In[], register cmsUInt16Number O
|
||||
// contrast, Saturation and white point displacement
|
||||
|
||||
cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfileTHR(cmsContext ContextID,
|
||||
int nLUTPoints,
|
||||
cmsFloat64Number Bright,
|
||||
cmsFloat64Number Contrast,
|
||||
cmsFloat64Number Hue,
|
||||
cmsFloat64Number Saturation,
|
||||
int TempSrc,
|
||||
int TempDest)
|
||||
int nLUTPoints,
|
||||
cmsFloat64Number Bright,
|
||||
cmsFloat64Number Contrast,
|
||||
cmsFloat64Number Hue,
|
||||
cmsFloat64Number Saturation,
|
||||
int TempSrc,
|
||||
int TempDest)
|
||||
{
|
||||
cmsHPROFILE hICC;
|
||||
cmsPipeline* Pipeline;
|
||||
BCHSWADJUSTS bchsw;
|
||||
cmsCIExyY WhitePnt;
|
||||
cmsStage* CLUT;
|
||||
cmsUInt32Number Dimensions[MAX_INPUT_DIMENSIONS];
|
||||
int i;
|
||||
cmsHPROFILE hICC;
|
||||
cmsPipeline* Pipeline;
|
||||
BCHSWADJUSTS bchsw;
|
||||
cmsCIExyY WhitePnt;
|
||||
cmsStage* CLUT;
|
||||
cmsUInt32Number Dimensions[MAX_INPUT_DIMENSIONS];
|
||||
int i;
|
||||
|
||||
bchsw.Brightness = Bright;
|
||||
bchsw.Contrast = Contrast;
|
||||
bchsw.Hue = Hue;
|
||||
bchsw.Saturation = Saturation;
|
||||
|
||||
cmsWhitePointFromTemp(&WhitePnt, TempSrc );
|
||||
cmsxyY2XYZ(&bchsw.WPsrc, &WhitePnt);
|
||||
|
||||
cmsWhitePointFromTemp(&WhitePnt, TempDest);
|
||||
cmsxyY2XYZ(&bchsw.WPdest, &WhitePnt);
|
||||
|
||||
hICC = cmsCreateProfilePlaceholder(ContextID);
|
||||
if (!hICC) // can't allocate
|
||||
return NULL;
|
||||
|
||||
|
||||
bchsw.Brightness = Bright;
|
||||
bchsw.Contrast = Contrast;
|
||||
bchsw.Hue = Hue;
|
||||
bchsw.Saturation = Saturation;
|
||||
|
||||
cmsWhitePointFromTemp(&WhitePnt, TempSrc );
|
||||
cmsxyY2XYZ(&bchsw.WPsrc, &WhitePnt);
|
||||
cmsSetDeviceClass(hICC, cmsSigAbstractClass);
|
||||
cmsSetColorSpace(hICC, cmsSigLabData);
|
||||
cmsSetPCS(hICC, cmsSigLabData);
|
||||
|
||||
cmsWhitePointFromTemp(&WhitePnt, TempDest);
|
||||
cmsxyY2XYZ(&bchsw.WPdest, &WhitePnt);
|
||||
|
||||
hICC = cmsCreateProfilePlaceholder(ContextID);
|
||||
if (!hICC) // can't allocate
|
||||
return NULL;
|
||||
|
||||
cmsSetHeaderRenderingIntent(hICC, INTENT_PERCEPTUAL);
|
||||
|
||||
cmsSetDeviceClass(hICC, cmsSigAbstractClass);
|
||||
cmsSetColorSpace(hICC, cmsSigLabData);
|
||||
cmsSetPCS(hICC, cmsSigLabData);
|
||||
// Creates a Pipeline with 3D grid only
|
||||
Pipeline = cmsPipelineAlloc(ContextID, 3, 3);
|
||||
if (Pipeline == NULL) {
|
||||
cmsCloseProfile(hICC);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cmsSetHeaderRenderingIntent(hICC, INTENT_PERCEPTUAL);
|
||||
for (i=0; i < MAX_INPUT_DIMENSIONS; i++) Dimensions[i] = nLUTPoints;
|
||||
CLUT = cmsStageAllocCLut16bitGranular(ContextID, Dimensions, 3, 3, NULL);
|
||||
if (CLUT == NULL) return NULL;
|
||||
|
||||
|
||||
// Creates a Pipeline with 3D grid only
|
||||
Pipeline = cmsPipelineAlloc(ContextID, 3, 3);
|
||||
if (Pipeline == NULL) {
|
||||
cmsCloseProfile(hICC);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i=0; i < MAX_INPUT_DIMENSIONS; i++) Dimensions[i] = nLUTPoints;
|
||||
CLUT = cmsStageAllocCLut16bitGranular(ContextID, Dimensions, 3, 3, NULL);
|
||||
if (CLUT == NULL) return NULL;
|
||||
|
||||
|
||||
if (!cmsStageSampleCLut16bit(CLUT, bchswSampler, (void*) &bchsw, 0)) {
|
||||
if (!cmsStageSampleCLut16bit(CLUT, bchswSampler, (void*) &bchsw, 0)) {
|
||||
|
||||
// Shouldn't reach here
|
||||
cmsPipelineFree(Pipeline);
|
||||
cmsCloseProfile(hICC);
|
||||
return NULL;
|
||||
}
|
||||
// Shouldn't reach here
|
||||
goto Error;
|
||||
}
|
||||
|
||||
cmsPipelineInsertStage(Pipeline, cmsAT_END, CLUT);
|
||||
if (!cmsPipelineInsertStage(Pipeline, cmsAT_END, CLUT)) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
// Create tags
|
||||
|
||||
if (!SetTextTags(hICC, L"BCHS built-in")) return NULL;
|
||||
|
||||
cmsWriteTag(hICC, cmsSigMediaWhitePointTag, (void*) cmsD50_XYZ());
|
||||
// Create tags
|
||||
if (!SetTextTags(hICC, L"BCHS built-in")) return NULL;
|
||||
|
||||
cmsWriteTag(hICC, cmsSigAToB0Tag, (void*) Pipeline);
|
||||
|
||||
// Pipeline is already on virtual profile
|
||||
cmsPipelineFree(Pipeline);
|
||||
cmsWriteTag(hICC, cmsSigMediaWhitePointTag, (void*) cmsD50_XYZ());
|
||||
|
||||
// Ok, done
|
||||
return hICC;
|
||||
cmsWriteTag(hICC, cmsSigAToB0Tag, (void*) Pipeline);
|
||||
|
||||
// Pipeline is already on virtual profile
|
||||
cmsPipelineFree(Pipeline);
|
||||
|
||||
// Ok, done
|
||||
return hICC;
|
||||
|
||||
Error:
|
||||
cmsPipelineFree(Pipeline);
|
||||
cmsCloseProfile(hICC);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
CMSAPI cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfile(int nLUTPoints,
|
||||
cmsFloat64Number Bright,
|
||||
cmsFloat64Number Bright,
|
||||
cmsFloat64Number Contrast,
|
||||
cmsFloat64Number Hue,
|
||||
cmsFloat64Number Saturation,
|
||||
int TempSrc,
|
||||
int TempSrc,
|
||||
int TempDest)
|
||||
{
|
||||
return cmsCreateBCHSWabstractProfileTHR(NULL, nLUTPoints, Bright, Contrast, Hue, Saturation, TempSrc, TempDest);
|
||||
}
|
||||
|
||||
|
||||
// Creates a fake NULL profile. This profile return 1 channel as always 0.
|
||||
// Creates a fake NULL profile. This profile return 1 channel as always 0.
|
||||
// Is useful only for gamut checking tricks
|
||||
cmsHPROFILE CMSEXPORT cmsCreateNULLProfileTHR(cmsContext ContextID)
|
||||
{
|
||||
cmsHPROFILE hProfile;
|
||||
cmsHPROFILE hProfile;
|
||||
cmsPipeline* LUT = NULL;
|
||||
cmsStage* PostLin;
|
||||
cmsToneCurve* EmptyTab;
|
||||
@@ -809,11 +830,11 @@ cmsHPROFILE CMSEXPORT cmsCreateNULLProfileTHR(cmsContext ContextID)
|
||||
if (!hProfile) // can't allocate
|
||||
return NULL;
|
||||
|
||||
cmsSetProfileVersion(hProfile, 4.2);
|
||||
cmsSetProfileVersion(hProfile, 4.3);
|
||||
|
||||
if (!SetTextTags(hProfile, L"NULL profile built-in")) goto Error;
|
||||
|
||||
if (!SetTextTags(hProfile, L"NULL profile built-in")) goto Error;
|
||||
|
||||
|
||||
|
||||
cmsSetDeviceClass(hProfile, cmsSigOutputClass);
|
||||
cmsSetColorSpace(hProfile, cmsSigGrayData);
|
||||
@@ -823,16 +844,17 @@ cmsHPROFILE CMSEXPORT cmsCreateNULLProfileTHR(cmsContext ContextID)
|
||||
LUT = cmsPipelineAlloc(ContextID, 1, 1);
|
||||
if (LUT == NULL) goto Error;
|
||||
|
||||
EmptyTab = cmsBuildTabulatedToneCurve16(ContextID, 2, Zero);
|
||||
EmptyTab = cmsBuildTabulatedToneCurve16(ContextID, 2, Zero);
|
||||
PostLin = cmsStageAllocToneCurves(ContextID, 1, &EmptyTab);
|
||||
cmsFreeToneCurve(EmptyTab);
|
||||
|
||||
cmsPipelineInsertStage(LUT, cmsAT_END, PostLin);
|
||||
if (!cmsPipelineInsertStage(LUT, cmsAT_END, PostLin))
|
||||
goto Error;
|
||||
|
||||
if (!cmsWriteTag(hProfile, cmsSigBToA0Tag, (void*) LUT)) goto Error;
|
||||
if (!cmsWriteTag(hProfile, cmsSigMediaWhitePointTag, cmsD50_XYZ())) goto Error;
|
||||
|
||||
cmsPipelineFree(LUT);
|
||||
cmsPipelineFree(LUT);
|
||||
return hProfile;
|
||||
|
||||
Error:
|
||||
@@ -861,14 +883,14 @@ int IsPCS(cmsColorSpaceSignature ColorSpace)
|
||||
|
||||
|
||||
static
|
||||
void FixColorSpaces(cmsHPROFILE hProfile,
|
||||
cmsColorSpaceSignature ColorSpace,
|
||||
void FixColorSpaces(cmsHPROFILE hProfile,
|
||||
cmsColorSpaceSignature ColorSpace,
|
||||
cmsColorSpaceSignature PCS,
|
||||
cmsUInt32Number dwFlags)
|
||||
{
|
||||
if (dwFlags & cmsFLAGS_GUESSDEVICECLASS) {
|
||||
|
||||
if (IsPCS(ColorSpace) && IsPCS(PCS)) {
|
||||
if (IsPCS(ColorSpace) && IsPCS(PCS)) {
|
||||
|
||||
cmsSetDeviceClass(hProfile, cmsSigAbstractClass);
|
||||
cmsSetColorSpace(hProfile, ColorSpace);
|
||||
@@ -880,7 +902,7 @@ void FixColorSpaces(cmsHPROFILE hProfile,
|
||||
|
||||
cmsSetDeviceClass(hProfile, cmsSigOutputClass);
|
||||
cmsSetPCS(hProfile, ColorSpace);
|
||||
cmsSetColorSpace(hProfile, PCS);
|
||||
cmsSetColorSpace(hProfile, PCS);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -908,7 +930,7 @@ static
|
||||
cmsHPROFILE CreateNamedColorDevicelink(cmsHTRANSFORM xform)
|
||||
{
|
||||
_cmsTRANSFORM* v = (_cmsTRANSFORM*) xform;
|
||||
cmsHPROFILE hICC = NULL;
|
||||
cmsHPROFILE hICC = NULL;
|
||||
int i, nColors;
|
||||
cmsNAMEDCOLORLIST *nc2 = NULL, *Original = NULL;
|
||||
|
||||
@@ -922,7 +944,7 @@ cmsHPROFILE CreateNamedColorDevicelink(cmsHTRANSFORM xform)
|
||||
cmsSetPCS(hICC, cmsSigLabData);
|
||||
|
||||
// Tag profile with information
|
||||
if (!SetTextTags(hICC, L"Named color devicelink")) goto Error;
|
||||
if (!SetTextTags(hICC, L"Named color devicelink")) goto Error;
|
||||
|
||||
Original = cmsGetNamedColorList(xform);
|
||||
if (Original == NULL) goto Error;
|
||||
@@ -931,9 +953,14 @@ cmsHPROFILE CreateNamedColorDevicelink(cmsHTRANSFORM xform)
|
||||
nc2 = cmsDupNamedColorList(Original);
|
||||
if (nc2 == NULL) goto Error;
|
||||
|
||||
// Colorant count now depends on the output space
|
||||
// Colorant count now depends on the output space
|
||||
nc2 ->ColorantCount = cmsPipelineOutputChannels(v ->Lut);
|
||||
|
||||
// Make sure we have proper formatters
|
||||
cmsChangeBuffersFormat(xform, TYPE_NAMED_COLOR_INDEX,
|
||||
FLOAT_SH(0) | COLORSPACE_SH(_cmsLCMScolorSpace(v ->ExitColorSpace))
|
||||
| BYTES_SH(2) | CHANNELS_SH(cmsChannelsOf(v ->ExitColorSpace)));
|
||||
|
||||
// Apply the transfor to colorants.
|
||||
for (i=0; i < nColors; i++) {
|
||||
cmsDoTransform(xform, &i, nc2 ->List[i].DeviceColorant, 1);
|
||||
@@ -963,8 +990,9 @@ typedef struct {
|
||||
|
||||
static const cmsAllowedLUT AllowedLUTTypes[] = {
|
||||
|
||||
{ FALSE, 0, cmsSigLut16Type, 4, { cmsSigMatrixElemType, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType}},
|
||||
{ FALSE, 0, cmsSigLut16Type, 4, { cmsSigMatrixElemType, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType}},
|
||||
{ FALSE, 0, cmsSigLut16Type, 3, { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType}},
|
||||
{ FALSE, 0, cmsSigLut16Type, 2, { cmsSigCurveSetElemType, cmsSigCLutElemType}},
|
||||
{ TRUE , 0, cmsSigLutAtoBType, 1, { cmsSigCurveSetElemType }},
|
||||
{ TRUE , cmsSigAToB0Tag, cmsSigLutAtoBType, 3, { cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType } },
|
||||
{ TRUE , cmsSigAToB0Tag, cmsSigLutAtoBType, 3, { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType } },
|
||||
@@ -987,17 +1015,17 @@ cmsBool CheckOne(const cmsAllowedLUT* Tab, const cmsPipeline* Lut)
|
||||
for (n=0, mpe = Lut ->Elements; mpe != NULL; mpe = mpe ->Next, n++) {
|
||||
|
||||
if (n > Tab ->nTypes) return FALSE;
|
||||
if (cmsStageType(mpe) != Tab ->MpeTypes[n]) return FALSE;
|
||||
if (cmsStageType(mpe) != Tab ->MpeTypes[n]) return FALSE;
|
||||
}
|
||||
|
||||
return (n == Tab ->nTypes);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
static
|
||||
const cmsAllowedLUT* FindCombination(const cmsPipeline* Lut, cmsBool IsV4, cmsTagSignature DestinationTag)
|
||||
{
|
||||
int n;
|
||||
cmsUInt32Number n;
|
||||
|
||||
for (n=0; n < SIZE_OF_ALLOWED_LUT; n++) {
|
||||
|
||||
@@ -1011,7 +1039,7 @@ const cmsAllowedLUT* FindCombination(const cmsPipeline* Lut, cmsBool IsV4, cmsTa
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Does convert a transform into a device link profile
|
||||
cmsHPROFILE CMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, cmsFloat64Number Version, cmsUInt32Number dwFlags)
|
||||
@@ -1025,12 +1053,13 @@ cmsHPROFILE CMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, cmsFloat
|
||||
cmsContext ContextID = cmsGetTransformContextID(hTransform);
|
||||
const cmsAllowedLUT* AllowedLUT;
|
||||
cmsTagSignature DestinationTag;
|
||||
cmsProfileClassSignature deviceClass;
|
||||
|
||||
_cmsAssert(hTransform != NULL);
|
||||
|
||||
|
||||
// Get the first mpe to check for named color
|
||||
mpe = cmsPipelineGetPtrToFirstStage(xform ->Lut);
|
||||
|
||||
|
||||
// Check if is a named color transform
|
||||
if (mpe != NULL) {
|
||||
|
||||
@@ -1046,22 +1075,24 @@ cmsHPROFILE CMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, cmsFloat
|
||||
// Time to fix the Lab2/Lab4 issue.
|
||||
if ((xform ->EntryColorSpace == cmsSigLabData) && (Version < 4.0)) {
|
||||
|
||||
cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocLabV2ToV4curves(ContextID));
|
||||
if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocLabV2ToV4curves(ContextID)))
|
||||
goto Error;
|
||||
}
|
||||
|
||||
// On the output side too
|
||||
if ((xform ->ExitColorSpace) == cmsSigLabData && (Version < 4.0)) {
|
||||
|
||||
cmsPipelineInsertStage(LUT, cmsAT_END, _cmsStageAllocLabV4ToV2(ContextID));
|
||||
if (!cmsPipelineInsertStage(LUT, cmsAT_END, _cmsStageAllocLabV4ToV2(ContextID)))
|
||||
goto Error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
hProfile = cmsCreateProfilePlaceholder(ContextID);
|
||||
if (!hProfile) goto Error; // can't allocate
|
||||
|
||||
if (!hProfile) goto Error; // can't allocate
|
||||
|
||||
cmsSetProfileVersion(hProfile, Version);
|
||||
|
||||
FixColorSpaces(hProfile, xform -> EntryColorSpace, xform -> ExitColorSpace, dwFlags);
|
||||
FixColorSpaces(hProfile, xform -> EntryColorSpace, xform -> ExitColorSpace, dwFlags);
|
||||
|
||||
// Optimize the LUT and precalculate a devicelink
|
||||
|
||||
@@ -1074,8 +1105,9 @@ cmsHPROFILE CMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, cmsFloat
|
||||
FrmIn = COLORSPACE_SH(ColorSpaceBitsIn) | CHANNELS_SH(ChansIn)|BYTES_SH(2);
|
||||
FrmOut = COLORSPACE_SH(ColorSpaceBitsOut) | CHANNELS_SH(ChansOut)|BYTES_SH(2);
|
||||
|
||||
deviceClass = cmsGetDeviceClass(hProfile);
|
||||
|
||||
if (cmsGetDeviceClass(hProfile) == cmsSigOutputClass)
|
||||
if (deviceClass == cmsSigOutputClass)
|
||||
DestinationTag = cmsSigBToA0Tag;
|
||||
else
|
||||
DestinationTag = cmsSigAToB0Tag;
|
||||
@@ -1084,12 +1116,12 @@ cmsHPROFILE CMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, cmsFloat
|
||||
if (dwFlags & cmsFLAGS_FORCE_CLUT)
|
||||
AllowedLUT = NULL;
|
||||
else
|
||||
AllowedLUT = FindCombination(LUT, Version >= 4.0, DestinationTag);
|
||||
AllowedLUT = FindCombination(LUT, Version >= 4.0, DestinationTag);
|
||||
|
||||
if (AllowedLUT == NULL) {
|
||||
|
||||
// Try to optimize
|
||||
_cmsOptimizePipeline(&LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags);
|
||||
_cmsOptimizePipeline(ContextID, &LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags);
|
||||
AllowedLUT = FindCombination(LUT, Version >= 4.0, DestinationTag);
|
||||
|
||||
}
|
||||
@@ -1098,14 +1130,16 @@ cmsHPROFILE CMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, cmsFloat
|
||||
if (AllowedLUT == NULL) {
|
||||
|
||||
dwFlags |= cmsFLAGS_FORCE_CLUT;
|
||||
_cmsOptimizePipeline(&LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags);
|
||||
_cmsOptimizePipeline(ContextID, &LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags);
|
||||
|
||||
// Put identity curves if needed
|
||||
if (cmsPipelineStageCount(LUT) == 1) {
|
||||
if (cmsPipelineGetPtrToFirstStage(LUT) ->Type != cmsSigCurveSetElemType)
|
||||
if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, ChansIn)))
|
||||
goto Error;
|
||||
|
||||
cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, ChansIn));
|
||||
cmsPipelineInsertStage(LUT, cmsAT_END, _cmsStageAllocIdentityCurves(ContextID, ChansOut));
|
||||
}
|
||||
if (cmsPipelineGetPtrToLastStage(LUT) ->Type != cmsSigCurveSetElemType)
|
||||
if (!cmsPipelineInsertStage(LUT, cmsAT_END, _cmsStageAllocIdentityCurves(ContextID, ChansOut)))
|
||||
goto Error;
|
||||
|
||||
AllowedLUT = FindCombination(LUT, Version >= 4.0, DestinationTag);
|
||||
}
|
||||
@@ -1116,16 +1150,16 @@ cmsHPROFILE CMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, cmsFloat
|
||||
}
|
||||
|
||||
|
||||
if (dwFlags & cmsFLAGS_8BITS_DEVICELINK)
|
||||
if (dwFlags & cmsFLAGS_8BITS_DEVICELINK)
|
||||
cmsPipelineSetSaveAs8bitsFlag(LUT, TRUE);
|
||||
|
||||
|
||||
// Tag profile with information
|
||||
if (!SetTextTags(hProfile, L"devicelink")) goto Error;
|
||||
|
||||
// Store result
|
||||
if (!SetTextTags(hProfile, L"devicelink")) goto Error;
|
||||
|
||||
// Store result
|
||||
if (!cmsWriteTag(hProfile, DestinationTag, LUT)) goto Error;
|
||||
|
||||
|
||||
|
||||
|
||||
if (xform -> InputColorant != NULL) {
|
||||
if (!cmsWriteTag(hProfile, cmsSigColorantTableTag, xform->InputColorant)) goto Error;
|
||||
}
|
||||
@@ -1133,16 +1167,28 @@ cmsHPROFILE CMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, cmsFloat
|
||||
if (xform -> OutputColorant != NULL) {
|
||||
if (!cmsWriteTag(hProfile, cmsSigColorantTableOutTag, xform->OutputColorant)) goto Error;
|
||||
}
|
||||
|
||||
if (xform ->Sequence != NULL) {
|
||||
|
||||
if ((deviceClass == cmsSigLinkClass) && (xform ->Sequence != NULL)) {
|
||||
if (!_cmsWriteProfileSequence(hProfile, xform ->Sequence)) goto Error;
|
||||
}
|
||||
|
||||
cmsPipelineFree(LUT);
|
||||
// Set the white point
|
||||
if (deviceClass == cmsSigInputClass) {
|
||||
if (!cmsWriteTag(hProfile, cmsSigMediaWhitePointTag, &xform ->EntryWhitePoint)) goto Error;
|
||||
}
|
||||
else {
|
||||
if (!cmsWriteTag(hProfile, cmsSigMediaWhitePointTag, &xform ->ExitWhitePoint)) goto Error;
|
||||
}
|
||||
|
||||
|
||||
// Per 7.2.15 in spec 4.3
|
||||
cmsSetHeaderRenderingIntent(hProfile, xform ->RenderingIntent);
|
||||
|
||||
cmsPipelineFree(LUT);
|
||||
return hProfile;
|
||||
|
||||
Error:
|
||||
if (LUT != NULL) cmsPipelineFree(LUT);
|
||||
if (LUT != NULL) cmsPipelineFree(LUT);
|
||||
cmsCloseProfile(hProfile);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
286
thirdparty/liblcms2/src/cmswtpnt.c
vendored
286
thirdparty/liblcms2/src/cmswtpnt.c
vendored
@@ -1,24 +1,24 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2014 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
|
||||
// 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
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
//---------------------------------------------------------------------------------
|
||||
@@ -47,63 +47,63 @@ const cmsCIExyY* CMSEXPORT cmsD50_xyY(void)
|
||||
// Obtains WhitePoint from Temperature
|
||||
cmsBool CMSEXPORT cmsWhitePointFromTemp(cmsCIExyY* WhitePoint, cmsFloat64Number TempK)
|
||||
{
|
||||
cmsFloat64Number x, y;
|
||||
cmsFloat64Number T, T2, T3;
|
||||
// cmsFloat64Number M1, M2;
|
||||
cmsFloat64Number x, y;
|
||||
cmsFloat64Number T, T2, T3;
|
||||
// cmsFloat64Number M1, M2;
|
||||
|
||||
_cmsAssert(WhitePoint != NULL);
|
||||
_cmsAssert(WhitePoint != NULL);
|
||||
|
||||
T = TempK;
|
||||
T2 = T*T; // Square
|
||||
T3 = T2*T; // Cube
|
||||
T = TempK;
|
||||
T2 = T*T; // Square
|
||||
T3 = T2*T; // Cube
|
||||
|
||||
// For correlated color temperature (T) between 4000K and 7000K:
|
||||
// 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 >= 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;
|
||||
}
|
||||
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)
|
||||
// Obtain y(x)
|
||||
|
||||
y = -3.000*(x*x) + 2.870*x - 0.275;
|
||||
y = -3.000*(x*x) + 2.870*x - 0.275;
|
||||
|
||||
// wave factors (not used, but here for futures extensions)
|
||||
// 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);
|
||||
// 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;
|
||||
WhitePoint -> x = x;
|
||||
WhitePoint -> y = y;
|
||||
WhitePoint -> Y = 1.0;
|
||||
|
||||
return TRUE;
|
||||
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
|
||||
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 }
|
||||
// {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},
|
||||
@@ -143,50 +143,50 @@ static ISOTEMPERATURE isotempdata[] = {
|
||||
// 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;
|
||||
cmsUInt32Number j;
|
||||
cmsFloat64Number us,vs;
|
||||
cmsFloat64Number uj,vj,tj,di,dj,mi,mj;
|
||||
cmsFloat64Number xs, ys;
|
||||
|
||||
_cmsAssert(WhitePoint != NULL);
|
||||
_cmsAssert(WhitePoint != NULL);
|
||||
_cmsAssert(TempK != NULL);
|
||||
|
||||
di = mi = 0;
|
||||
xs = WhitePoint -> x;
|
||||
ys = WhitePoint -> y;
|
||||
di = mi = 0;
|
||||
xs = WhitePoint -> x;
|
||||
ys = WhitePoint -> y;
|
||||
|
||||
// convert (x,y) to CIE 1960 (u,WhitePoint)
|
||||
// convert (x,y) to CIE 1960 (u,WhitePoint)
|
||||
|
||||
us = (2*xs) / (-xs + 6*ys + 1.5);
|
||||
vs = (3*ys) / (-xs + 6*ys + 1.5);
|
||||
us = (2*xs) / (-xs + 6*ys + 1.5);
|
||||
vs = (3*ys) / (-xs + 6*ys + 1.5);
|
||||
|
||||
|
||||
for (j=0; j < NISO; j++) {
|
||||
for (j=0; j < NISO; j++) {
|
||||
|
||||
uj = isotempdata[j].ut;
|
||||
vj = isotempdata[j].vt;
|
||||
tj = isotempdata[j].tt;
|
||||
mj = isotempdata[j].mirek;
|
||||
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);
|
||||
dj = ((vs - vj) - tj * (us - uj)) / sqrt(1.0 + tj * tj);
|
||||
|
||||
if ((j != 0) && (di/dj < 0.0)) {
|
||||
if ((j != 0) && (di/dj < 0.0)) {
|
||||
|
||||
// Found a match
|
||||
*TempK = 1000000.0 / (mi + (di / (di - dj)) * (mj - mi));
|
||||
return TRUE;
|
||||
}
|
||||
// Found a match
|
||||
*TempK = 1000000.0 / (mi + (di / (di - dj)) * (mj - mi));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
di = dj;
|
||||
mi = mj;
|
||||
}
|
||||
di = dj;
|
||||
mi = mj;
|
||||
}
|
||||
|
||||
// Not found
|
||||
return FALSE;
|
||||
// Not found
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
// Compute chromatic adaptation matrix using Chad as cone matrix
|
||||
// Compute chromatic adaptation matrix using Chad as cone matrix
|
||||
|
||||
static
|
||||
cmsBool ComputeChromaticAdaptation(cmsMAT3* Conversion,
|
||||
@@ -195,7 +195,7 @@ cmsBool ComputeChromaticAdaptation(cmsMAT3* Conversion,
|
||||
const cmsMAT3* Chad)
|
||||
|
||||
{
|
||||
|
||||
|
||||
cmsMAT3 Chad_Inv;
|
||||
cmsVEC3 ConeSourceXYZ, ConeSourceRGB;
|
||||
cmsVEC3 ConeDestXYZ, ConeDestRGB;
|
||||
@@ -226,41 +226,41 @@ cmsBool ComputeChromaticAdaptation(cmsMAT3* Conversion,
|
||||
_cmsMAT3per(&Tmp, &Cone, Chad);
|
||||
_cmsMAT3per(Conversion, &Chad_Inv, &Tmp);
|
||||
|
||||
return TRUE;
|
||||
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 }}
|
||||
}};
|
||||
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;
|
||||
if (ConeMatrix == NULL)
|
||||
ConeMatrix = &LamRigg;
|
||||
|
||||
return ComputeChromaticAdaptation(r, FromIll, ToIll, ConeMatrix);
|
||||
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;
|
||||
cmsCIEXYZ Dn;
|
||||
cmsMAT3 Bradford;
|
||||
cmsMAT3 Tmp;
|
||||
|
||||
cmsxyY2XYZ(&Dn, SourceWhitePt);
|
||||
cmsxyY2XYZ(&Dn, SourceWhitePt);
|
||||
|
||||
if (!_cmsAdaptationMatrix(&Bradford, NULL, &Dn, cmsD50_XYZ())) return FALSE;
|
||||
if (!_cmsAdaptationMatrix(&Bradford, NULL, &Dn, cmsD50_XYZ())) return FALSE;
|
||||
|
||||
Tmp = *r;
|
||||
_cmsMAT3per(r, &Bradford, &Tmp);
|
||||
Tmp = *r;
|
||||
_cmsMAT3per(r, &Bradford, &Tmp);
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Build a White point, primary chromas transfer matrix from RGB to CIE XYZ
|
||||
@@ -278,74 +278,74 @@ cmsBool _cmsAdaptMatrixToD50(cmsMAT3* r, const cmsCIExyY* SourceWhitePt)
|
||||
//
|
||||
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;
|
||||
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;
|
||||
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));
|
||||
// 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;
|
||||
// Result = Primaries ^ (-1) inverse matrix
|
||||
if (!_cmsMAT3inverse(&Primaries, &Result))
|
||||
return FALSE;
|
||||
|
||||
|
||||
_cmsVEC3init(&WhitePoint, xn/yn, 1.0, (1.0-xn-yn)/yn);
|
||||
_cmsVEC3init(&WhitePoint, xn/yn, 1.0, (1.0-xn-yn)/yn);
|
||||
|
||||
// Across inverse primaries ...
|
||||
_cmsMAT3eval(&Coef, &Result, &WhitePoint);
|
||||
// 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));
|
||||
// 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);
|
||||
|
||||
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)
|
||||
// a SourceWhitePt white point.
|
||||
cmsBool CMSEXPORT cmsAdaptToIlluminant(cmsCIEXYZ* Result,
|
||||
const cmsCIEXYZ* SourceWhitePt,
|
||||
const cmsCIEXYZ* Illuminant,
|
||||
const cmsCIEXYZ* Value)
|
||||
{
|
||||
cmsMAT3 Bradford;
|
||||
cmsVEC3 In, Out;
|
||||
cmsMAT3 Bradford;
|
||||
cmsVEC3 In, Out;
|
||||
|
||||
_cmsAssert(Result != NULL);
|
||||
_cmsAssert(SourceWhitePt != NULL);
|
||||
_cmsAssert(Illuminant != NULL);
|
||||
_cmsAssert(Value != NULL);
|
||||
_cmsAssert(Result != NULL);
|
||||
_cmsAssert(SourceWhitePt != NULL);
|
||||
_cmsAssert(Illuminant != NULL);
|
||||
_cmsAssert(Value != NULL);
|
||||
|
||||
if (!_cmsAdaptationMatrix(&Bradford, NULL, SourceWhitePt, Illuminant)) return FALSE;
|
||||
if (!_cmsAdaptationMatrix(&Bradford, NULL, SourceWhitePt, Illuminant)) return FALSE;
|
||||
|
||||
_cmsVEC3init(&In, Value -> X, Value -> Y, Value -> Z);
|
||||
_cmsMAT3eval(&Out, &Bradford, &In);
|
||||
_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];
|
||||
Result -> X = Out.n[0];
|
||||
Result -> Y = Out.n[1];
|
||||
Result -> Z = Out.n[2];
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
723
thirdparty/liblcms2/src/cmsxform.c
vendored
723
thirdparty/liblcms2/src/cmsxform.c
vendored
File diff suppressed because it is too large
Load Diff
641
thirdparty/liblcms2/src/lcms2.def
vendored
641
thirdparty/liblcms2/src/lcms2.def
vendored
@@ -1,300 +1,341 @@
|
||||
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
|
||||
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
|
||||
cmsDetectDestinationBlackPoint = cmsDetectDestinationBlackPoint
|
||||
cmsDetectTAC = cmsDetectTAC
|
||||
cmsDesaturateLab = cmsDesaturateLab
|
||||
cmsDoTransform = cmsDoTransform
|
||||
cmsDoTransformStride = cmsDoTransformStride
|
||||
_cmsDoubleTo15Fixed16 = _cmsDoubleTo15Fixed16
|
||||
_cmsDoubleTo8Fixed8 = _cmsDoubleTo8Fixed8
|
||||
_cmsDupMem = _cmsDupMem
|
||||
cmsDupNamedColorList = cmsDupNamedColorList
|
||||
cmsDupProfileSequenceDescription = cmsDupProfileSequenceDescription
|
||||
cmsDupToneCurve = cmsDupToneCurve
|
||||
_cmsEncodeDateTimeNumber = _cmsEncodeDateTimeNumber
|
||||
cmsEstimateGamma = cmsEstimateGamma
|
||||
cmsGetToneCurveEstimatedTableEntries = cmsGetToneCurveEstimatedTableEntries
|
||||
cmsGetToneCurveEstimatedTable = cmsGetToneCurveEstimatedTable
|
||||
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
|
||||
cmsIT8EnumPropertyMulti = cmsIT8EnumPropertyMulti
|
||||
cmsIT8Free = cmsIT8Free
|
||||
cmsIT8GetData = cmsIT8GetData
|
||||
cmsIT8GetDataDbl = cmsIT8GetDataDbl
|
||||
cmsIT8FindDataFormat = cmsIT8FindDataFormat
|
||||
cmsIT8GetDataRowCol = cmsIT8GetDataRowCol
|
||||
cmsIT8GetDataRowColDbl = cmsIT8GetDataRowColDbl
|
||||
cmsIT8GetPatchName = cmsIT8GetPatchName
|
||||
cmsIT8GetPatchByName = cmsIT8GetPatchByName
|
||||
cmsIT8GetProperty = cmsIT8GetProperty
|
||||
cmsIT8GetPropertyDbl = cmsIT8GetPropertyDbl
|
||||
cmsIT8GetPropertyMulti = cmsIT8GetPropertyMulti
|
||||
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
|
||||
cmsIT8SetPropertyMulti = cmsIT8SetPropertyMulti
|
||||
cmsIT8SetPropertyUncooked = cmsIT8SetPropertyUncooked
|
||||
cmsIT8SetSheetType = cmsIT8SetSheetType
|
||||
cmsIT8SetTable = cmsIT8SetTable
|
||||
cmsIT8SetTableByLabel = cmsIT8SetTableByLabel
|
||||
cmsIT8SetIndexColumn = cmsIT8SetIndexColumn
|
||||
cmsIT8TableCount = cmsIT8TableCount
|
||||
cmsJoinToneCurve = cmsJoinToneCurve
|
||||
cmsLab2LCh = cmsLab2LCh
|
||||
cmsLab2XYZ = cmsLab2XYZ
|
||||
cmsLabEncoded2Float = cmsLabEncoded2Float
|
||||
cmsLabEncoded2FloatV2 = cmsLabEncoded2FloatV2
|
||||
cmsLCh2Lab = cmsLCh2Lab
|
||||
_cmsLCMScolorSpace = _cmsLCMScolorSpace
|
||||
cmsLinkTag = cmsLinkTag
|
||||
cmsTagLinkedTo = cmsTagLinkedTo
|
||||
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
|
||||
cmsDictAlloc = cmsDictAlloc
|
||||
cmsDictFree = cmsDictFree
|
||||
cmsDictDup = cmsDictDup
|
||||
cmsDictAddEntry = cmsDictAddEntry
|
||||
cmsDictGetEntryList = cmsDictGetEntryList
|
||||
cmsDictNextEntry = cmsDictNextEntry
|
||||
_cmsGetTransformUserData = _cmsGetTransformUserData
|
||||
_cmsSetTransformUserData = _cmsSetTransformUserData
|
||||
_cmsGetTransformFormatters16 = _cmsGetTransformFormatters16
|
||||
_cmsGetTransformFormattersFloat = _cmsGetTransformFormattersFloat
|
||||
cmsGetHeaderCreator = cmsGetHeaderCreator
|
||||
cmsPluginTHR = cmsPluginTHR
|
||||
cmsGetPipelineContextID = cmsGetPipelineContextID
|
||||
cmsGetTransformInputFormat = cmsGetTransformInputFormat
|
||||
cmsGetTransformOutputFormat = cmsGetTransformOutputFormat
|
||||
cmsCreateContext = cmsCreateContext
|
||||
cmsDupContext = cmsDupContext
|
||||
cmsDeleteContext = cmsDeleteContext
|
||||
cmsGetContextUserData = cmsGetContextUserData
|
||||
cmsUnregisterPluginsTHR = cmsUnregisterPluginsTHR
|
||||
cmsSetAlarmCodesTHR = cmsSetAlarmCodesTHR
|
||||
cmsGetAlarmCodesTHR = cmsGetAlarmCodesTHR
|
||||
cmsSetAdaptationStateTHR = cmsSetAdaptationStateTHR
|
||||
cmsSetLogErrorHandlerTHR = cmsSetLogErrorHandlerTHR
|
||||
cmsGetSupportedIntentsTHR = cmsGetSupportedIntentsTHR
|
||||
cmsMLUtranslationsCount = cmsMLUtranslationsCount
|
||||
cmsMLUtranslationsCodes = cmsMLUtranslationsCodes
|
||||
_cmsCreateMutex = _cmsCreateMutex
|
||||
_cmsDestroyMutex = _cmsDestroyMutex
|
||||
_cmsLockMutex = _cmsLockMutex
|
||||
_cmsUnlockMutex = _cmsUnlockMutex
|
||||
724
thirdparty/liblcms2/src/lcms2_internal.h
vendored
724
thirdparty/liblcms2/src/lcms2_internal.h
vendored
File diff suppressed because it is too large
Load Diff
4
thirdparty/libpng/CMakeLists.txt
vendored
4
thirdparty/libpng/CMakeLists.txt
vendored
@@ -7,7 +7,7 @@ INCLUDE_DIRECTORIES(
|
||||
|
||||
FILE(GLOB SRCS *.c)
|
||||
FILE(GLOB HDRS *.h)
|
||||
SET(EXT_HDRS
|
||||
SET(EXT_HDRS
|
||||
${OPENJPEG_SOURCE_DIR}/thirdparty/include/zlib.h
|
||||
${OPENJPEG_SOURCE_DIR}/thirdparty/include/zconf.h
|
||||
)
|
||||
@@ -23,7 +23,7 @@ ENDIF(MSVC)
|
||||
TARGET_LINK_LIBRARIES(${LIBTARGET} ${Z_LIBNAME} ${M_LIBRARY})
|
||||
#
|
||||
SET_TARGET_PROPERTIES(${LIBTARGET}
|
||||
PROPERTIES
|
||||
PROPERTIES
|
||||
OUTPUT_NAME "${LIBTARGET}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/thirdparty/lib)
|
||||
#
|
||||
|
||||
6
thirdparty/libpng/LICENSE
vendored
6
thirdparty/libpng/LICENSE
vendored
@@ -10,8 +10,8 @@ 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
|
||||
libpng versions 1.2.6, August 15, 2004, through 1.6.17, March 26, 2015, are
|
||||
Copyright (c) 2004, 2006-2015 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
|
||||
|
||||
@@ -108,4 +108,4 @@ certification mark of the Open Source Initiative.
|
||||
|
||||
Glenn Randers-Pehrson
|
||||
glennrp at users.sourceforge.net
|
||||
September 23, 2010
|
||||
March 26, 2015
|
||||
|
||||
838
thirdparty/libpng/example.c
vendored
838
thirdparty/libpng/example.c
vendored
@@ -1,838 +0,0 @@
|
||||
|
||||
#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 */
|
||||
4362
thirdparty/libpng/png.c
vendored
4362
thirdparty/libpng/png.c
vendored
File diff suppressed because it is too large
Load Diff
3397
thirdparty/libpng/png.h
vendored
3397
thirdparty/libpng/png.h
vendored
File diff suppressed because it is too large
Load Diff
1922
thirdparty/libpng/pngconf.h
vendored
1922
thirdparty/libpng/pngconf.h
vendored
File diff suppressed because it is too large
Load Diff
153
thirdparty/libpng/pngdebug.h
vendored
Normal file
153
thirdparty/libpng/pngdebug.h
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
|
||||
/* pngdebug.h - Debugging macros for libpng, also used in pngtest.c
|
||||
*
|
||||
* Last changed in libpng 1.6.8 [December 19, 2013]
|
||||
* Copyright (c) 1998-2013 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_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.
|
||||
*
|
||||
* png_debug[1-2]?(level, message ,arg{0-2})
|
||||
* Expands to a statement (either a simple expression or a compound
|
||||
* do..while(0) statement) that outputs a message with parameter
|
||||
* substitution if PNG_DEBUG is defined to 2 or more. If PNG_DEBUG
|
||||
* is undefined, 0 or 1 every png_debug expands to a simple expression
|
||||
* (actually ((void)0)).
|
||||
*
|
||||
* level: level of detail of message, starting at 0. A level 'n'
|
||||
* message is preceded by 'n' 3-space indentations (not implemented
|
||||
* on Microsoft compilers unless PNG_DEBUG_FILE is also
|
||||
* defined, to allow debug DLL compilation with no standard IO).
|
||||
* message: a printf(3) style text string. A trailing '\n' is added
|
||||
* to the message.
|
||||
* arg: 0 to 2 arguments for printf(3) style substitution in message.
|
||||
*/
|
||||
#ifndef PNGDEBUG_H
|
||||
#define PNGDEBUG_H
|
||||
/* These settings control the formatting of messages in png.c and pngerror.c */
|
||||
/* Moved to pngdebug.h at 1.5.0 */
|
||||
# ifndef PNG_LITERAL_SHARP
|
||||
# define PNG_LITERAL_SHARP 0x23
|
||||
# endif
|
||||
# ifndef PNG_LITERAL_LEFT_SQUARE_BRACKET
|
||||
# define PNG_LITERAL_LEFT_SQUARE_BRACKET 0x5b
|
||||
# endif
|
||||
# ifndef PNG_LITERAL_RIGHT_SQUARE_BRACKET
|
||||
# define PNG_LITERAL_RIGHT_SQUARE_BRACKET 0x5d
|
||||
# endif
|
||||
# ifndef PNG_STRING_NEWLINE
|
||||
# define PNG_STRING_NEWLINE "\n"
|
||||
# endif
|
||||
|
||||
#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_STDIO_SUPPORTED
|
||||
# include <stdio.h> /* not included yet */
|
||||
# endif
|
||||
# ifndef PNG_DEBUG_FILE
|
||||
# define PNG_DEBUG_FILE stderr
|
||||
# endif /* PNG_DEBUG_FILE */
|
||||
|
||||
# if (PNG_DEBUG > 1)
|
||||
# ifdef __STDC__
|
||||
# ifndef png_debug
|
||||
# define png_debug(l,m) \
|
||||
do { \
|
||||
int num_tabs=l; \
|
||||
fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \
|
||||
(num_tabs==2 ? " " : (num_tabs>2 ? " " : "")))); \
|
||||
} while (0)
|
||||
# endif
|
||||
# ifndef png_debug1
|
||||
# define png_debug1(l,m,p1) \
|
||||
do { \
|
||||
int num_tabs=l; \
|
||||
fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \
|
||||
(num_tabs==2 ? " " : (num_tabs>2 ? " " : ""))),p1); \
|
||||
} while (0)
|
||||
# endif
|
||||
# ifndef png_debug2
|
||||
# define png_debug2(l,m,p1,p2) \
|
||||
do { \
|
||||
int num_tabs=l; \
|
||||
fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \
|
||||
(num_tabs==2 ? " " : (num_tabs>2 ? " " : ""))),p1,p2);\
|
||||
} while (0)
|
||||
# endif
|
||||
# else /* __STDC __ */
|
||||
# ifndef png_debug
|
||||
# define png_debug(l,m) \
|
||||
do { \
|
||||
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); \
|
||||
} while (0)
|
||||
# endif
|
||||
# ifndef png_debug1
|
||||
# define png_debug1(l,m,p1) \
|
||||
do { \
|
||||
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); \
|
||||
} while (0)
|
||||
# endif
|
||||
# ifndef png_debug2
|
||||
# define png_debug2(l,m,p1,p2) \
|
||||
do { \
|
||||
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); \
|
||||
} while (0)
|
||||
# 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) ((void)0)
|
||||
#endif
|
||||
#ifndef png_debug1
|
||||
# define png_debug1(l, m, p1) ((void)0)
|
||||
#endif
|
||||
#ifndef png_debug2
|
||||
# define png_debug2(l, m, p1, p2) ((void)0)
|
||||
#endif
|
||||
#endif /* PNGDEBUG_H */
|
||||
915
thirdparty/libpng/pngerror.c
vendored
915
thirdparty/libpng/pngerror.c
vendored
File diff suppressed because it is too large
Load Diff
952
thirdparty/libpng/pngget.c
vendored
952
thirdparty/libpng/pngget.c
vendored
File diff suppressed because it is too large
Load Diff
259
thirdparty/libpng/pnginfo.h
vendored
Normal file
259
thirdparty/libpng/pnginfo.h
vendored
Normal file
@@ -0,0 +1,259 @@
|
||||
|
||||
/* pnginfo.h - header file for PNG reference library
|
||||
*
|
||||
* Last changed in libpng 1.6.1 [March 28, 2013]
|
||||
* Copyright (c) 1998-2013 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
|
||||
*/
|
||||
|
||||
/* png_info is a structure that holds the information in a PNG file so
|
||||
* that the application can find out the characteristics of the image.
|
||||
* If you are reading the file, this structure will tell you what is
|
||||
* in the PNG file. If you are writing the file, fill in the information
|
||||
* you want to put into the PNG file, using png_set_*() functions, then
|
||||
* call png_write_info().
|
||||
*
|
||||
* The names chosen should be very close to the PNG specification, so
|
||||
* consult that document for information about the meaning of each field.
|
||||
*
|
||||
* With libpng < 0.95, it was only possible to directly set and read the
|
||||
* the values in the png_info_struct, which meant that the contents and
|
||||
* order of the values had to remain fixed. With libpng 0.95 and later,
|
||||
* however, there are now functions that abstract the contents of
|
||||
* png_info_struct from the application, so this makes it easier to use
|
||||
* libpng with dynamic libraries, and even makes it possible to use
|
||||
* libraries that don't have all of the libpng ancillary chunk-handing
|
||||
* functionality. In libpng-1.5.0 this was moved into a separate private
|
||||
* file that is not visible to applications.
|
||||
*
|
||||
* The following members may have allocated storage attached that should be
|
||||
* cleaned up before the structure is discarded: palette, trans, text,
|
||||
* pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile,
|
||||
* splt_palettes, scal_unit, row_pointers, and unknowns. By default, these
|
||||
* are automatically freed when the info structure is deallocated, if they were
|
||||
* allocated internally by libpng. This behavior can be changed by means
|
||||
* of the png_data_freer() function.
|
||||
*
|
||||
* More allocation details: all the chunk-reading functions that
|
||||
* change these members go through the corresponding png_set_*
|
||||
* functions. A function to clear these members is available: see
|
||||
* png_free_data(). The png_set_* functions do not depend on being
|
||||
* able to point info structure members to any of the storage they are
|
||||
* passed (they make their own copies), EXCEPT that the png_set_text
|
||||
* functions use the same storage passed to them in the text_ptr or
|
||||
* itxt_ptr structure argument, and the png_set_rows and png_set_unknowns
|
||||
* functions do not make their own copies.
|
||||
*/
|
||||
#ifndef PNGINFO_H
|
||||
#define PNGINFO_H
|
||||
|
||||
struct png_info_def
|
||||
{
|
||||
/* The following are necessary for every PNG file */
|
||||
png_uint_32 width; /* width of image in pixels (from IHDR) */
|
||||
png_uint_32 height; /* height of image in pixels (from IHDR) */
|
||||
png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */
|
||||
png_size_t rowbytes; /* bytes needed to hold an untransformed row */
|
||||
png_colorp palette; /* array of color values (valid & PNG_INFO_PLTE) */
|
||||
png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */
|
||||
png_uint_16 num_trans; /* number of transparent palette color (tRNS) */
|
||||
png_byte bit_depth; /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */
|
||||
png_byte color_type; /* see PNG_COLOR_TYPE_ below (from IHDR) */
|
||||
/* The following three should have been named *_method not *_type */
|
||||
png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */
|
||||
png_byte filter_type; /* must be PNG_FILTER_TYPE_BASE (from IHDR) */
|
||||
png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
|
||||
|
||||
/* The following are set by png_set_IHDR, called from the application on
|
||||
* write, but the are never actually used by the write code.
|
||||
*/
|
||||
png_byte channels; /* number of data channels per pixel (1, 2, 3, 4) */
|
||||
png_byte pixel_depth; /* number of bits per pixel */
|
||||
png_byte spare_byte; /* to align the data, and for future use */
|
||||
|
||||
#ifdef PNG_READ_SUPPORTED
|
||||
/* This is never set during write */
|
||||
png_byte signature[8]; /* magic bytes read by libpng from start of file */
|
||||
#endif
|
||||
|
||||
/* The rest of the data is optional. If you are reading, check the
|
||||
* valid field to see if the information in these are valid. If you
|
||||
* are writing, set the valid field to those chunks you want written,
|
||||
* and initialize the appropriate fields below.
|
||||
*/
|
||||
|
||||
#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)
|
||||
/* png_colorspace only contains 'flags' if neither GAMMA or COLORSPACE are
|
||||
* defined. When COLORSPACE is switched on all the colorspace-defining
|
||||
* chunks should be enabled, when GAMMA is switched on all the gamma-defining
|
||||
* chunks should be enabled. If this is not done it becomes possible to read
|
||||
* inconsistent PNG files and assign a probably incorrect interpretation to
|
||||
* the information. (In other words, by carefully choosing which chunks to
|
||||
* recognize the system configuration can select an interpretation for PNG
|
||||
* files containing ambiguous data and this will result in inconsistent
|
||||
* behavior between different libpng builds!)
|
||||
*/
|
||||
png_colorspace colorspace;
|
||||
#endif
|
||||
|
||||
#ifdef PNG_iCCP_SUPPORTED
|
||||
/* iCCP chunk data. */
|
||||
png_charp iccp_name; /* profile name */
|
||||
png_bytep iccp_profile; /* International Color Consortium profile data */
|
||||
png_uint_32 iccp_proflen; /* ICC profile data length */
|
||||
#endif
|
||||
|
||||
#ifdef PNG_TEXT_SUPPORTED
|
||||
/* The tEXt, and zTXt chunks contain human-readable textual data in
|
||||
* uncompressed, compressed, and optionally compressed forms, respectively.
|
||||
* The data in "text" is an array of pointers to uncompressed,
|
||||
* null-terminated C strings. Each chunk has a keyword that describes the
|
||||
* textual data contained in that chunk. Keywords are not required to be
|
||||
* unique, and the text string may be empty. Any number of text chunks may
|
||||
* be in an image.
|
||||
*/
|
||||
int num_text; /* number of comments read or comments to write */
|
||||
int max_text; /* current size of text array */
|
||||
png_textp text; /* array of comments read or comments to write */
|
||||
#endif /* TEXT */
|
||||
|
||||
#ifdef PNG_tIME_SUPPORTED
|
||||
/* The tIME chunk holds the last time the displayed image data was
|
||||
* modified. See the png_time struct for the contents of this struct.
|
||||
*/
|
||||
png_time mod_time;
|
||||
#endif
|
||||
|
||||
#ifdef PNG_sBIT_SUPPORTED
|
||||
/* The sBIT chunk specifies the number of significant high-order bits
|
||||
* in the pixel data. Values are in the range [1, bit_depth], and are
|
||||
* only specified for the channels in the pixel data. The contents of
|
||||
* the low-order bits is not specified. Data is valid if
|
||||
* (valid & PNG_INFO_sBIT) is non-zero.
|
||||
*/
|
||||
png_color_8 sig_bit; /* significant bits in color channels */
|
||||
#endif
|
||||
|
||||
#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \
|
||||
defined(PNG_READ_BACKGROUND_SUPPORTED)
|
||||
/* The tRNS chunk supplies transparency data for paletted images and
|
||||
* other image types that don't need a full alpha channel. There are
|
||||
* "num_trans" transparency values for a paletted image, stored in the
|
||||
* same order as the palette colors, starting from index 0. Values
|
||||
* for the data are in the range [0, 255], ranging from fully transparent
|
||||
* to fully opaque, respectively. For non-paletted images, there is a
|
||||
* single color specified that should be treated as fully transparent.
|
||||
* Data is valid if (valid & PNG_INFO_tRNS) is non-zero.
|
||||
*/
|
||||
png_bytep trans_alpha; /* alpha values for paletted image */
|
||||
png_color_16 trans_color; /* transparent color for non-palette image */
|
||||
#endif
|
||||
|
||||
#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
|
||||
/* The bKGD chunk gives the suggested image background color if the
|
||||
* display program does not have its own background color and the image
|
||||
* is needs to composited onto a background before display. The colors
|
||||
* in "background" are normally in the same color space/depth as the
|
||||
* pixel data. Data is valid if (valid & PNG_INFO_bKGD) is non-zero.
|
||||
*/
|
||||
png_color_16 background;
|
||||
#endif
|
||||
|
||||
#ifdef PNG_oFFs_SUPPORTED
|
||||
/* The oFFs chunk gives the offset in "offset_unit_type" units rightwards
|
||||
* and downwards from the top-left corner of the display, page, or other
|
||||
* application-specific co-ordinate space. See the PNG_OFFSET_ defines
|
||||
* below for the unit types. Valid if (valid & PNG_INFO_oFFs) non-zero.
|
||||
*/
|
||||
png_int_32 x_offset; /* x offset on page */
|
||||
png_int_32 y_offset; /* y offset on page */
|
||||
png_byte offset_unit_type; /* offset units type */
|
||||
#endif
|
||||
|
||||
#ifdef PNG_pHYs_SUPPORTED
|
||||
/* The pHYs chunk gives the physical pixel density of the image for
|
||||
* display or printing in "phys_unit_type" units (see PNG_RESOLUTION_
|
||||
* defines below). Data is valid if (valid & PNG_INFO_pHYs) is non-zero.
|
||||
*/
|
||||
png_uint_32 x_pixels_per_unit; /* horizontal pixel density */
|
||||
png_uint_32 y_pixels_per_unit; /* vertical pixel density */
|
||||
png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
|
||||
#endif
|
||||
|
||||
#ifdef PNG_hIST_SUPPORTED
|
||||
/* The hIST chunk contains the relative frequency or importance of the
|
||||
* various palette entries, so that a viewer can intelligently select a
|
||||
* reduced-color palette, if required. Data is an array of "num_palette"
|
||||
* values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST)
|
||||
* is non-zero.
|
||||
*/
|
||||
png_uint_16p hist;
|
||||
#endif
|
||||
|
||||
#ifdef PNG_pCAL_SUPPORTED
|
||||
/* The pCAL chunk describes a transformation between the stored pixel
|
||||
* values and original physical data values used to create the image.
|
||||
* The integer range [0, 2^bit_depth - 1] maps to the floating-point
|
||||
* range given by [pcal_X0, pcal_X1], and are further transformed by a
|
||||
* (possibly non-linear) transformation function given by "pcal_type"
|
||||
* and "pcal_params" into "pcal_units". Please see the PNG_EQUATION_
|
||||
* defines below, and the PNG-Group's PNG extensions document for a
|
||||
* complete description of the transformations and how they should be
|
||||
* implemented, and for a description of the ASCII parameter strings.
|
||||
* Data values are valid if (valid & PNG_INFO_pCAL) non-zero.
|
||||
*/
|
||||
png_charp pcal_purpose; /* pCAL chunk description string */
|
||||
png_int_32 pcal_X0; /* minimum value */
|
||||
png_int_32 pcal_X1; /* maximum value */
|
||||
png_charp pcal_units; /* Latin-1 string giving physical units */
|
||||
png_charpp pcal_params; /* ASCII strings containing parameter values */
|
||||
png_byte pcal_type; /* equation type (see PNG_EQUATION_ below) */
|
||||
png_byte pcal_nparams; /* number of parameters given in pcal_params */
|
||||
#endif
|
||||
|
||||
/* New members added in libpng-1.0.6 */
|
||||
png_uint_32 free_me; /* flags items libpng is responsible for freeing */
|
||||
|
||||
#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
|
||||
/* Storage for unknown chunks that the library doesn't recognize. */
|
||||
png_unknown_chunkp unknown_chunks;
|
||||
|
||||
/* The type of this field is limited by the type of
|
||||
* png_struct::user_chunk_cache_max, else overflow can occur.
|
||||
*/
|
||||
int unknown_chunks_num;
|
||||
#endif
|
||||
|
||||
#ifdef PNG_sPLT_SUPPORTED
|
||||
/* Data on sPLT chunks (there may be more than one). */
|
||||
png_sPLT_tp splt_palettes;
|
||||
int splt_palettes_num; /* Match type returned by png_get API */
|
||||
#endif
|
||||
|
||||
#ifdef PNG_sCAL_SUPPORTED
|
||||
/* The sCAL chunk describes the actual physical dimensions of the
|
||||
* subject matter of the graphic. The chunk contains a unit specification
|
||||
* a byte value, and two ASCII strings representing floating-point
|
||||
* values. The values are width and height corresponsing to one pixel
|
||||
* in the image. Data values are valid if (valid & PNG_INFO_sCAL) is
|
||||
* non-zero.
|
||||
*/
|
||||
png_byte scal_unit; /* unit of physical scale */
|
||||
png_charp scal_s_width; /* string containing height */
|
||||
png_charp scal_s_height; /* string containing width */
|
||||
#endif
|
||||
|
||||
#ifdef PNG_INFO_IMAGE_SUPPORTED
|
||||
/* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS)
|
||||
non-zero */
|
||||
/* Data valid if (valid & PNG_INFO_IDAT) non-zero */
|
||||
png_bytepp row_pointers; /* the image bits */
|
||||
#endif
|
||||
|
||||
};
|
||||
#endif /* PNGINFO_H */
|
||||
214
thirdparty/libpng/pnglibconf.h
vendored
Normal file
214
thirdparty/libpng/pnglibconf.h
vendored
Normal file
@@ -0,0 +1,214 @@
|
||||
/* libpng 1.6.17 STANDARD API DEFINITION */
|
||||
|
||||
/* pnglibconf.h - library build configuration */
|
||||
|
||||
/* Libpng version 1.6.17 - March 26, 2015 */
|
||||
|
||||
/* Copyright (c) 1998-2014 Glenn Randers-Pehrson */
|
||||
|
||||
/* This code is released under the libpng license. */
|
||||
/* For conditions of distribution and use, see the disclaimer */
|
||||
/* and license in png.h */
|
||||
|
||||
/* pnglibconf.h */
|
||||
/* Machine generated file: DO NOT EDIT */
|
||||
/* Derived from: scripts/pnglibconf.dfa */
|
||||
#ifndef PNGLCONF_H
|
||||
#define PNGLCONF_H
|
||||
/* options */
|
||||
#define PNG_16BIT_SUPPORTED
|
||||
#define PNG_ALIGNED_MEMORY_SUPPORTED
|
||||
/*#undef PNG_ARM_NEON_API_SUPPORTED*/
|
||||
/*#undef PNG_ARM_NEON_CHECK_SUPPORTED*/
|
||||
#define PNG_BENIGN_ERRORS_SUPPORTED
|
||||
#define PNG_BENIGN_READ_ERRORS_SUPPORTED
|
||||
/*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/
|
||||
#define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
|
||||
#define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
|
||||
#define PNG_COLORSPACE_SUPPORTED
|
||||
#define PNG_CONSOLE_IO_SUPPORTED
|
||||
#define PNG_CONVERT_tIME_SUPPORTED
|
||||
#define PNG_EASY_ACCESS_SUPPORTED
|
||||
/*#undef PNG_ERROR_NUMBERS_SUPPORTED*/
|
||||
#define PNG_ERROR_TEXT_SUPPORTED
|
||||
#define PNG_FIXED_POINT_SUPPORTED
|
||||
#define PNG_FLOATING_ARITHMETIC_SUPPORTED
|
||||
#define PNG_FLOATING_POINT_SUPPORTED
|
||||
#define PNG_FORMAT_AFIRST_SUPPORTED
|
||||
#define PNG_FORMAT_BGR_SUPPORTED
|
||||
#define PNG_GAMMA_SUPPORTED
|
||||
#define PNG_GET_PALETTE_MAX_SUPPORTED
|
||||
#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
|
||||
#define PNG_INCH_CONVERSIONS_SUPPORTED
|
||||
#define PNG_INFO_IMAGE_SUPPORTED
|
||||
#define PNG_IO_STATE_SUPPORTED
|
||||
#define PNG_MNG_FEATURES_SUPPORTED
|
||||
#define PNG_POINTER_INDEXING_SUPPORTED
|
||||
#define PNG_PROGRESSIVE_READ_SUPPORTED
|
||||
#define PNG_READ_16BIT_SUPPORTED
|
||||
#define PNG_READ_ALPHA_MODE_SUPPORTED
|
||||
#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
|
||||
#define PNG_READ_BACKGROUND_SUPPORTED
|
||||
#define PNG_READ_BGR_SUPPORTED
|
||||
#define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
|
||||
#define PNG_READ_COMPOSITE_NODIV_SUPPORTED
|
||||
#define PNG_READ_COMPRESSED_TEXT_SUPPORTED
|
||||
#define PNG_READ_EXPAND_16_SUPPORTED
|
||||
#define PNG_READ_EXPAND_SUPPORTED
|
||||
#define PNG_READ_FILLER_SUPPORTED
|
||||
#define PNG_READ_GAMMA_SUPPORTED
|
||||
#define PNG_READ_GET_PALETTE_MAX_SUPPORTED
|
||||
#define PNG_READ_GRAY_TO_RGB_SUPPORTED
|
||||
#define PNG_READ_INTERLACING_SUPPORTED
|
||||
#define PNG_READ_INT_FUNCTIONS_SUPPORTED
|
||||
#define PNG_READ_INVERT_ALPHA_SUPPORTED
|
||||
#define PNG_READ_INVERT_SUPPORTED
|
||||
#define PNG_READ_OPT_PLTE_SUPPORTED
|
||||
#define PNG_READ_PACKSWAP_SUPPORTED
|
||||
#define PNG_READ_PACK_SUPPORTED
|
||||
#define PNG_READ_QUANTIZE_SUPPORTED
|
||||
#define PNG_READ_RGB_TO_GRAY_SUPPORTED
|
||||
#define PNG_READ_SCALE_16_TO_8_SUPPORTED
|
||||
#define PNG_READ_SHIFT_SUPPORTED
|
||||
#define PNG_READ_STRIP_16_TO_8_SUPPORTED
|
||||
#define PNG_READ_STRIP_ALPHA_SUPPORTED
|
||||
#define PNG_READ_SUPPORTED
|
||||
#define PNG_READ_SWAP_ALPHA_SUPPORTED
|
||||
#define PNG_READ_SWAP_SUPPORTED
|
||||
#define PNG_READ_TEXT_SUPPORTED
|
||||
#define PNG_READ_TRANSFORMS_SUPPORTED
|
||||
#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
|
||||
#define PNG_READ_USER_CHUNKS_SUPPORTED
|
||||
#define PNG_READ_USER_TRANSFORM_SUPPORTED
|
||||
#define PNG_READ_bKGD_SUPPORTED
|
||||
#define PNG_READ_cHRM_SUPPORTED
|
||||
#define PNG_READ_gAMA_SUPPORTED
|
||||
#define PNG_READ_hIST_SUPPORTED
|
||||
#define PNG_READ_iCCP_SUPPORTED
|
||||
#define PNG_READ_iTXt_SUPPORTED
|
||||
#define PNG_READ_oFFs_SUPPORTED
|
||||
#define PNG_READ_pCAL_SUPPORTED
|
||||
#define PNG_READ_pHYs_SUPPORTED
|
||||
#define PNG_READ_sBIT_SUPPORTED
|
||||
#define PNG_READ_sCAL_SUPPORTED
|
||||
#define PNG_READ_sPLT_SUPPORTED
|
||||
#define PNG_READ_sRGB_SUPPORTED
|
||||
#define PNG_READ_tEXt_SUPPORTED
|
||||
#define PNG_READ_tIME_SUPPORTED
|
||||
#define PNG_READ_tRNS_SUPPORTED
|
||||
#define PNG_READ_zTXt_SUPPORTED
|
||||
#define PNG_SAVE_INT_32_SUPPORTED
|
||||
#define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
|
||||
#define PNG_SEQUENTIAL_READ_SUPPORTED
|
||||
#define PNG_SETJMP_SUPPORTED
|
||||
#define PNG_SET_CHUNK_CACHE_LIMIT_SUPPORTED
|
||||
#define PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
|
||||
#define PNG_SET_OPTION_SUPPORTED
|
||||
#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
|
||||
#define PNG_SET_USER_LIMITS_SUPPORTED
|
||||
#define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED
|
||||
#define PNG_SIMPLIFIED_READ_BGR_SUPPORTED
|
||||
#define PNG_SIMPLIFIED_READ_SUPPORTED
|
||||
#define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
|
||||
#define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
|
||||
#define PNG_SIMPLIFIED_WRITE_SUPPORTED
|
||||
#define PNG_STDIO_SUPPORTED
|
||||
#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
|
||||
#define PNG_TEXT_SUPPORTED
|
||||
#define PNG_TIME_RFC1123_SUPPORTED
|
||||
#define PNG_UNKNOWN_CHUNKS_SUPPORTED
|
||||
#define PNG_USER_CHUNKS_SUPPORTED
|
||||
#define PNG_USER_LIMITS_SUPPORTED
|
||||
#define PNG_USER_MEM_SUPPORTED
|
||||
#define PNG_USER_TRANSFORM_INFO_SUPPORTED
|
||||
#define PNG_USER_TRANSFORM_PTR_SUPPORTED
|
||||
#define PNG_WARNINGS_SUPPORTED
|
||||
#define PNG_WRITE_16BIT_SUPPORTED
|
||||
#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
|
||||
#define PNG_WRITE_BGR_SUPPORTED
|
||||
#define PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
|
||||
#define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
|
||||
#define PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
|
||||
#define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
|
||||
#define PNG_WRITE_FILLER_SUPPORTED
|
||||
#define PNG_WRITE_FILTER_SUPPORTED
|
||||
#define PNG_WRITE_FLUSH_SUPPORTED
|
||||
#define PNG_WRITE_GET_PALETTE_MAX_SUPPORTED
|
||||
#define PNG_WRITE_INTERLACING_SUPPORTED
|
||||
#define PNG_WRITE_INT_FUNCTIONS_SUPPORTED
|
||||
#define PNG_WRITE_INVERT_ALPHA_SUPPORTED
|
||||
#define PNG_WRITE_INVERT_SUPPORTED
|
||||
#define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
|
||||
#define PNG_WRITE_PACKSWAP_SUPPORTED
|
||||
#define PNG_WRITE_PACK_SUPPORTED
|
||||
#define PNG_WRITE_SHIFT_SUPPORTED
|
||||
#define PNG_WRITE_SUPPORTED
|
||||
#define PNG_WRITE_SWAP_ALPHA_SUPPORTED
|
||||
#define PNG_WRITE_SWAP_SUPPORTED
|
||||
#define PNG_WRITE_TEXT_SUPPORTED
|
||||
#define PNG_WRITE_TRANSFORMS_SUPPORTED
|
||||
#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
|
||||
#define PNG_WRITE_USER_TRANSFORM_SUPPORTED
|
||||
#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
|
||||
#define PNG_WRITE_bKGD_SUPPORTED
|
||||
#define PNG_WRITE_cHRM_SUPPORTED
|
||||
#define PNG_WRITE_gAMA_SUPPORTED
|
||||
#define PNG_WRITE_hIST_SUPPORTED
|
||||
#define PNG_WRITE_iCCP_SUPPORTED
|
||||
#define PNG_WRITE_iTXt_SUPPORTED
|
||||
#define PNG_WRITE_oFFs_SUPPORTED
|
||||
#define PNG_WRITE_pCAL_SUPPORTED
|
||||
#define PNG_WRITE_pHYs_SUPPORTED
|
||||
#define PNG_WRITE_sBIT_SUPPORTED
|
||||
#define PNG_WRITE_sCAL_SUPPORTED
|
||||
#define PNG_WRITE_sPLT_SUPPORTED
|
||||
#define PNG_WRITE_sRGB_SUPPORTED
|
||||
#define PNG_WRITE_tEXt_SUPPORTED
|
||||
#define PNG_WRITE_tIME_SUPPORTED
|
||||
#define PNG_WRITE_tRNS_SUPPORTED
|
||||
#define PNG_WRITE_zTXt_SUPPORTED
|
||||
#define PNG_bKGD_SUPPORTED
|
||||
#define PNG_cHRM_SUPPORTED
|
||||
#define PNG_gAMA_SUPPORTED
|
||||
#define PNG_hIST_SUPPORTED
|
||||
#define PNG_iCCP_SUPPORTED
|
||||
#define PNG_iTXt_SUPPORTED
|
||||
#define PNG_oFFs_SUPPORTED
|
||||
#define PNG_pCAL_SUPPORTED
|
||||
#define PNG_pHYs_SUPPORTED
|
||||
#define PNG_sBIT_SUPPORTED
|
||||
#define PNG_sCAL_SUPPORTED
|
||||
#define PNG_sPLT_SUPPORTED
|
||||
#define PNG_sRGB_SUPPORTED
|
||||
#define PNG_tEXt_SUPPORTED
|
||||
#define PNG_tIME_SUPPORTED
|
||||
#define PNG_tRNS_SUPPORTED
|
||||
#define PNG_zTXt_SUPPORTED
|
||||
/* end of options */
|
||||
/* settings */
|
||||
#define PNG_API_RULE 0
|
||||
#define PNG_COST_SHIFT 3
|
||||
#define PNG_DEFAULT_READ_MACROS 1
|
||||
#define PNG_GAMMA_THRESHOLD_FIXED 5000
|
||||
#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE
|
||||
#define PNG_INFLATE_BUF_SIZE 1024
|
||||
#define PNG_MAX_GAMMA_8 11
|
||||
#define PNG_QUANTIZE_BLUE_BITS 5
|
||||
#define PNG_QUANTIZE_GREEN_BITS 5
|
||||
#define PNG_QUANTIZE_RED_BITS 5
|
||||
#define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1)
|
||||
#define PNG_TEXT_Z_DEFAULT_STRATEGY 0
|
||||
#define PNG_USER_CHUNK_CACHE_MAX 1000
|
||||
#define PNG_USER_CHUNK_MALLOC_MAX 8000000
|
||||
#define PNG_USER_HEIGHT_MAX 1000000
|
||||
#define PNG_USER_WIDTH_MAX 1000000
|
||||
#define PNG_WEIGHT_SHIFT 8
|
||||
#define PNG_ZBUF_SIZE 8192
|
||||
#define PNG_ZLIB_VERNUM 0 /* unknown */
|
||||
#define PNG_Z_DEFAULT_COMPRESSION (-1)
|
||||
#define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0
|
||||
#define PNG_Z_DEFAULT_STRATEGY 1
|
||||
#define PNG_sCAL_PRECISION 5
|
||||
#define PNG_sRGB_PROFILE_CHECKS 2
|
||||
/* end of settings */
|
||||
#endif /* PNGLCONF_H */
|
||||
712
thirdparty/libpng/pngmem.c
vendored
712
thirdparty/libpng/pngmem.c
vendored
@@ -1,8 +1,8 @@
|
||||
|
||||
/* pngmem.c - stub functions for memory allocation
|
||||
*
|
||||
* Last changed in libpng 1.4.2 [May 6, 2010]
|
||||
* Copyright (c) 1998-2010 Glenn Randers-Pehrson
|
||||
* Last changed in libpng 1.6.15 [November 20, 2014]
|
||||
* Copyright (c) 1998-2014 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.)
|
||||
*
|
||||
@@ -17,575 +17,244 @@
|
||||
* 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 */
|
||||
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
|
||||
/* Free a png_struct */
|
||||
void /* PRIVATE */
|
||||
png_destroy_struct(png_voidp struct_ptr)
|
||||
png_destroy_png_struct(png_structrp png_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)
|
||||
if (png_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);
|
||||
/* png_free might call png_error and may certainly call
|
||||
* png_get_mem_ptr, so fake a temporary png_struct to support this.
|
||||
*/
|
||||
png_struct dummy_struct = *png_ptr;
|
||||
memset(png_ptr, 0, (sizeof *png_ptr));
|
||||
png_free(&dummy_struct, png_ptr);
|
||||
|
||||
# ifdef PNG_SETJMP_SUPPORTED
|
||||
/* We may have a jmp_buf left to deallocate. */
|
||||
png_free_jmpbuf(&dummy_struct);
|
||||
# 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.
|
||||
*
|
||||
* 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
|
||||
* 64K. However, zlib may allocate more than 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_FUNCTION(png_voidp,PNGAPI
|
||||
png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
|
||||
{
|
||||
png_voidp ret;
|
||||
|
||||
ret = (png_malloc(png_ptr, size));
|
||||
ret = png_malloc(png_ptr, size);
|
||||
|
||||
if (ret != NULL)
|
||||
png_memset(ret,0,(png_size_t)size);
|
||||
return (ret);
|
||||
memset(ret, 0, size);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
png_voidp PNGAPI
|
||||
png_malloc(png_structp png_ptr, png_alloc_size_t size)
|
||||
/* png_malloc_base, an internal function added at libpng 1.6.0, does the work of
|
||||
* allocating memory, taking into account limits and PNG_USER_MEM_SUPPORTED.
|
||||
* Checking and error handling must happen outside this routine; it returns NULL
|
||||
* if the allocation cannot be done (for any reason.)
|
||||
*/
|
||||
PNG_FUNCTION(png_voidp /* PRIVATE */,
|
||||
png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size),
|
||||
PNG_ALLOCATED)
|
||||
{
|
||||
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)
|
||||
{
|
||||
/* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS
|
||||
* allocators have also been removed in 1.6.0, so any 16-bit system now has
|
||||
* to implement a user memory handler. This checks to be sure it isn't
|
||||
* called with big numbers.
|
||||
*/
|
||||
#ifndef PNG_USER_MEM_SUPPORTED
|
||||
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
|
||||
png_error(png_ptr, "Cannot Allocate > 64K");
|
||||
PNG_UNUSED(png_ptr)
|
||||
#endif
|
||||
|
||||
if (size > 0 && size <= PNG_SIZE_MAX
|
||||
# ifdef PNG_MAX_MALLOC_64K
|
||||
&& size <= 65536U
|
||||
# endif
|
||||
)
|
||||
{
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
if (png_ptr != NULL && png_ptr->malloc_fn != NULL)
|
||||
return png_ptr->malloc_fn(png_constcast(png_structrp,png_ptr), size);
|
||||
|
||||
else
|
||||
#endif
|
||||
return NULL;
|
||||
return malloc((size_t)size); /* checked for truncation above */
|
||||
}
|
||||
#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
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#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
|
||||
#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\
|
||||
defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED)
|
||||
/* This is really here only to work round a spurious warning in GCC 4.6 and 4.7
|
||||
* that arises because of the checks in png_realloc_array that are repeated in
|
||||
* png_malloc_array.
|
||||
*/
|
||||
static png_voidp
|
||||
png_malloc_array_checked(png_const_structrp png_ptr, int nelements,
|
||||
size_t element_size)
|
||||
{
|
||||
png_alloc_size_t req = nelements; /* known to be > 0 */
|
||||
|
||||
return (ret);
|
||||
if (req <= PNG_SIZE_MAX/element_size)
|
||||
return png_malloc_base(png_ptr, req * element_size);
|
||||
|
||||
/* The failure case when the request is too large */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PNG_FUNCTION(png_voidp /* PRIVATE */,
|
||||
png_malloc_array,(png_const_structrp png_ptr, int nelements,
|
||||
size_t element_size),PNG_ALLOCATED)
|
||||
{
|
||||
if (nelements <= 0 || element_size == 0)
|
||||
png_error(png_ptr, "internal error: array alloc");
|
||||
|
||||
return png_malloc_array_checked(png_ptr, nelements, element_size);
|
||||
}
|
||||
|
||||
PNG_FUNCTION(png_voidp /* PRIVATE */,
|
||||
png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,
|
||||
int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED)
|
||||
{
|
||||
/* These are internal errors: */
|
||||
if (add_elements <= 0 || element_size == 0 || old_elements < 0 ||
|
||||
(old_array == NULL && old_elements > 0))
|
||||
png_error(png_ptr, "internal error: array realloc");
|
||||
|
||||
/* Check for overflow on the elements count (so the caller does not have to
|
||||
* check.)
|
||||
*/
|
||||
if (add_elements <= INT_MAX - old_elements)
|
||||
{
|
||||
png_voidp new_array = png_malloc_array_checked(png_ptr,
|
||||
old_elements+add_elements, element_size);
|
||||
|
||||
if (new_array != NULL)
|
||||
{
|
||||
/* Because png_malloc_array worked the size calculations below cannot
|
||||
* overflow.
|
||||
*/
|
||||
if (old_elements > 0)
|
||||
memcpy(new_array, old_array, element_size*(unsigned)old_elements);
|
||||
|
||||
memset((char*)new_array + element_size*(unsigned)old_elements, 0,
|
||||
element_size*(unsigned)add_elements);
|
||||
|
||||
return new_array;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL; /* error */
|
||||
}
|
||||
#endif /* TEXT || sPLT || STORE_UNKNOWN_CHUNKS */
|
||||
|
||||
/* Various functions that have different error handling are derived from this.
|
||||
* png_malloc always exists, but if PNG_USER_MEM_SUPPORTED is defined a separate
|
||||
* function png_malloc_default is also provided.
|
||||
*/
|
||||
PNG_FUNCTION(png_voidp,PNGAPI
|
||||
png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
|
||||
{
|
||||
png_voidp ret;
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return NULL;
|
||||
|
||||
ret = png_malloc_base(png_ptr, size);
|
||||
|
||||
if (ret == NULL)
|
||||
png_error(png_ptr, "Out of memory"); /* 'm' means png_malloc */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
PNG_FUNCTION(png_voidp,PNGAPI
|
||||
png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size),
|
||||
PNG_ALLOCATED PNG_DEPRECATED)
|
||||
{
|
||||
png_voidp ret;
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Passing 'NULL' here bypasses the application provided memory handler. */
|
||||
ret = png_malloc_base(NULL/*use malloc*/, size);
|
||||
|
||||
if (ret == NULL)
|
||||
png_error(png_ptr, "Out of Memory"); /* 'M' means png_malloc_default */
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* USER_MEM */
|
||||
|
||||
/* This function was added at libpng version 1.2.3. The png_malloc_warn()
|
||||
* function will issue a png_warning and return NULL instead of issuing a
|
||||
* png_error, if it fails to allocate the requested memory.
|
||||
*/
|
||||
PNG_FUNCTION(png_voidp,PNGAPI
|
||||
png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size),
|
||||
PNG_ALLOCATED)
|
||||
{
|
||||
if (png_ptr != NULL)
|
||||
{
|
||||
png_voidp ret = png_malloc_base(png_ptr, size);
|
||||
|
||||
if (ret != NULL)
|
||||
return ret;
|
||||
|
||||
png_warning(png_ptr, "Out of memory");
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
png_free(png_const_structrp 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;
|
||||
}
|
||||
png_ptr->free_fn(png_constcast(png_structrp,png_ptr), ptr);
|
||||
|
||||
else
|
||||
png_free_default(png_ptr, ptr);
|
||||
}
|
||||
void PNGAPI
|
||||
png_free_default(png_structp png_ptr, png_voidp ptr)
|
||||
|
||||
PNG_FUNCTION(void,PNGAPI
|
||||
png_free_default,(png_const_structrp png_ptr, png_voidp ptr),PNG_DEPRECATED)
|
||||
{
|
||||
if (png_ptr == NULL || ptr == NULL)
|
||||
return;
|
||||
#endif /* USER_MEM */
|
||||
|
||||
#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
|
||||
png_set_mem_fn(png_structrp png_ptr, png_voidp mem_ptr, png_malloc_ptr
|
||||
malloc_fn, png_free_ptr free_fn)
|
||||
{
|
||||
if (png_ptr != NULL)
|
||||
@@ -601,11 +270,12 @@ png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
|
||||
* pointer before png_write_destroy and png_read_destroy are called.
|
||||
*/
|
||||
png_voidp PNGAPI
|
||||
png_get_mem_ptr(png_structp png_ptr)
|
||||
png_get_mem_ptr(png_const_structrp png_ptr)
|
||||
{
|
||||
if (png_ptr == NULL)
|
||||
return (NULL);
|
||||
return ((png_voidp)png_ptr->mem_ptr);
|
||||
return NULL;
|
||||
|
||||
return png_ptr->mem_ptr;
|
||||
}
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
||||
#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
|
||||
#endif /* USER_MEM */
|
||||
#endif /* READ || WRITE */
|
||||
|
||||
1327
thirdparty/libpng/pngpread.c
vendored
1327
thirdparty/libpng/pngpread.c
vendored
File diff suppressed because it is too large
Load Diff
2132
thirdparty/libpng/pngpriv.h
vendored
2132
thirdparty/libpng/pngpriv.h
vendored
File diff suppressed because it is too large
Load Diff
4319
thirdparty/libpng/pngread.c
vendored
4319
thirdparty/libpng/pngread.c
vendored
File diff suppressed because it is too large
Load Diff
87
thirdparty/libpng/pngrio.c
vendored
87
thirdparty/libpng/pngrio.c
vendored
@@ -1,8 +1,8 @@
|
||||
|
||||
/* pngrio.c - functions for data input
|
||||
*
|
||||
* Last changed in libpng 1.4.1 [February 25, 2010]
|
||||
* Copyright (c) 1998-2010 Glenn Randers-Pehrson
|
||||
* Last changed in libpng 1.6.17 [March 26, 2015]
|
||||
* Copyright (c) 1998-2015 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.)
|
||||
*
|
||||
@@ -18,24 +18,24 @@
|
||||
* 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"
|
||||
|
||||
#ifdef PNG_READ_SUPPORTED
|
||||
|
||||
/* 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.
|
||||
* to read more than 64K on a 16 bit machine.
|
||||
*/
|
||||
void /* PRIVATE */
|
||||
png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
png_read_data(png_structrp 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");
|
||||
}
|
||||
@@ -46,80 +46,34 @@ png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
* 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
|
||||
void PNGCBAPI
|
||||
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);
|
||||
check = fread(data, 1, length, png_voidcast(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
|
||||
@@ -130,34 +84,37 @@ png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
* be used.
|
||||
*/
|
||||
void PNGAPI
|
||||
png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
|
||||
png_set_read_fn(png_structrp 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
|
||||
|
||||
#ifdef PNG_WRITE_SUPPORTED
|
||||
/* 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");
|
||||
"Can't set both read_data_fn and write_data_fn in the"
|
||||
" same structure");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_FLUSH_SUPPORTED
|
||||
png_ptr->output_flush_fn = NULL;
|
||||
#endif
|
||||
}
|
||||
#endif /* PNG_READ_SUPPORTED */
|
||||
#endif /* READ */
|
||||
|
||||
4294
thirdparty/libpng/pngrtran.c
vendored
4294
thirdparty/libpng/pngrtran.c
vendored
File diff suppressed because it is too large
Load Diff
4749
thirdparty/libpng/pngrutil.c
vendored
4749
thirdparty/libpng/pngrutil.c
vendored
File diff suppressed because it is too large
Load Diff
1573
thirdparty/libpng/pngset.c
vendored
1573
thirdparty/libpng/pngset.c
vendored
File diff suppressed because it is too large
Load Diff
488
thirdparty/libpng/pngstruct.h
vendored
Normal file
488
thirdparty/libpng/pngstruct.h
vendored
Normal file
@@ -0,0 +1,488 @@
|
||||
|
||||
/* pngstruct.h - header file for PNG reference library
|
||||
*
|
||||
* Last changed in libpng 1.6.1 [March 28, 2013]
|
||||
* Copyright (c) 1998-2013 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 structure that holds the information to read and write PNG files.
|
||||
* The only people who need to care about what is inside of this are the
|
||||
* people who will be modifying the library for their own special needs.
|
||||
* It should NOT be accessed directly by an application.
|
||||
*/
|
||||
|
||||
#ifndef PNGSTRUCT_H
|
||||
#define PNGSTRUCT_H
|
||||
/* zlib.h defines the structure z_stream, an instance of which is included
|
||||
* in this structure and is required for decompressing the LZ compressed
|
||||
* data in PNG files.
|
||||
*/
|
||||
#ifndef ZLIB_CONST
|
||||
/* We must ensure that zlib uses 'const' in declarations. */
|
||||
# define ZLIB_CONST
|
||||
#endif
|
||||
#include "zlib.h"
|
||||
#ifdef const
|
||||
/* zlib.h sometimes #defines const to nothing, undo this. */
|
||||
# undef const
|
||||
#endif
|
||||
|
||||
/* zlib.h has mediocre z_const use before 1.2.6, this stuff is for compatibility
|
||||
* with older builds.
|
||||
*/
|
||||
#if ZLIB_VERNUM < 0x1260
|
||||
# define PNGZ_MSG_CAST(s) png_constcast(char*,s)
|
||||
# define PNGZ_INPUT_CAST(b) png_constcast(png_bytep,b)
|
||||
#else
|
||||
# define PNGZ_MSG_CAST(s) (s)
|
||||
# define PNGZ_INPUT_CAST(b) (b)
|
||||
#endif
|
||||
|
||||
/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib
|
||||
* can handle at once. This type need be no larger than 16 bits (so maximum of
|
||||
* 65535), this define allows us to discover how big it is, but limited by the
|
||||
* maximuum for png_size_t. The value can be overriden in a library build
|
||||
* (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably
|
||||
* lower value (e.g. 255 works). A lower value may help memory usage (slightly)
|
||||
* and may even improve performance on some systems (and degrade it on others.)
|
||||
*/
|
||||
#ifndef ZLIB_IO_MAX
|
||||
# define ZLIB_IO_MAX ((uInt)-1)
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_SUPPORTED
|
||||
/* The type of a compression buffer list used by the write code. */
|
||||
typedef struct png_compression_buffer
|
||||
{
|
||||
struct png_compression_buffer *next;
|
||||
png_byte output[1]; /* actually zbuf_size */
|
||||
} png_compression_buffer, *png_compression_bufferp;
|
||||
|
||||
#define PNG_COMPRESSION_BUFFER_SIZE(pp)\
|
||||
(offsetof(png_compression_buffer, output) + (pp)->zbuffer_size)
|
||||
#endif
|
||||
|
||||
/* Colorspace support; structures used in png_struct, png_info and in internal
|
||||
* functions to hold and communicate information about the color space.
|
||||
*
|
||||
* PNG_COLORSPACE_SUPPORTED is only required if the application will perform
|
||||
* colorspace corrections, otherwise all the colorspace information can be
|
||||
* skipped and the size of libpng can be reduced (significantly) by compiling
|
||||
* out the colorspace support.
|
||||
*/
|
||||
#ifdef PNG_COLORSPACE_SUPPORTED
|
||||
/* The chromaticities of the red, green and blue colorants and the chromaticity
|
||||
* of the corresponding white point (i.e. of rgb(1.0,1.0,1.0)).
|
||||
*/
|
||||
typedef struct png_xy
|
||||
{
|
||||
png_fixed_point redx, redy;
|
||||
png_fixed_point greenx, greeny;
|
||||
png_fixed_point bluex, bluey;
|
||||
png_fixed_point whitex, whitey;
|
||||
} png_xy;
|
||||
|
||||
/* The same data as above but encoded as CIE XYZ values. When this data comes
|
||||
* from chromaticities the sum of the Y values is assumed to be 1.0
|
||||
*/
|
||||
typedef struct png_XYZ
|
||||
{
|
||||
png_fixed_point red_X, red_Y, red_Z;
|
||||
png_fixed_point green_X, green_Y, green_Z;
|
||||
png_fixed_point blue_X, blue_Y, blue_Z;
|
||||
} png_XYZ;
|
||||
#endif /* COLORSPACE */
|
||||
|
||||
#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)
|
||||
/* A colorspace is all the above plus, potentially, profile information;
|
||||
* however at present libpng does not use the profile internally so it is only
|
||||
* stored in the png_info struct (if iCCP is supported.) The rendering intent
|
||||
* is retained here and is checked.
|
||||
*
|
||||
* The file gamma encoding information is also stored here and gamma correction
|
||||
* is done by libpng, whereas color correction must currently be done by the
|
||||
* application.
|
||||
*/
|
||||
typedef struct png_colorspace
|
||||
{
|
||||
#ifdef PNG_GAMMA_SUPPORTED
|
||||
png_fixed_point gamma; /* File gamma */
|
||||
#endif
|
||||
|
||||
#ifdef PNG_COLORSPACE_SUPPORTED
|
||||
png_xy end_points_xy; /* End points as chromaticities */
|
||||
png_XYZ end_points_XYZ; /* End points as CIE XYZ colorant values */
|
||||
png_uint_16 rendering_intent; /* Rendering intent of a profile */
|
||||
#endif
|
||||
|
||||
/* Flags are always defined to simplify the code. */
|
||||
png_uint_16 flags; /* As defined below */
|
||||
} png_colorspace, * PNG_RESTRICT png_colorspacerp;
|
||||
|
||||
typedef const png_colorspace * PNG_RESTRICT png_const_colorspacerp;
|
||||
|
||||
/* General flags for the 'flags' field */
|
||||
#define PNG_COLORSPACE_HAVE_GAMMA 0x0001
|
||||
#define PNG_COLORSPACE_HAVE_ENDPOINTS 0x0002
|
||||
#define PNG_COLORSPACE_HAVE_INTENT 0x0004
|
||||
#define PNG_COLORSPACE_FROM_gAMA 0x0008
|
||||
#define PNG_COLORSPACE_FROM_cHRM 0x0010
|
||||
#define PNG_COLORSPACE_FROM_sRGB 0x0020
|
||||
#define PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB 0x0040
|
||||
#define PNG_COLORSPACE_MATCHES_sRGB 0x0080 /* exact match on profile */
|
||||
#define PNG_COLORSPACE_INVALID 0x8000
|
||||
#define PNG_COLORSPACE_CANCEL(flags) (0xffff ^ (flags))
|
||||
#endif /* COLORSPACE || GAMMA */
|
||||
|
||||
struct png_struct_def
|
||||
{
|
||||
#ifdef PNG_SETJMP_SUPPORTED
|
||||
jmp_buf jmp_buf_local; /* New name in 1.6.0 for jmp_buf in png_struct */
|
||||
png_longjmp_ptr longjmp_fn;/* setjmp non-local goto function. */
|
||||
jmp_buf *jmp_buf_ptr; /* passed to longjmp_fn */
|
||||
size_t jmp_buf_size; /* size of the above, if allocated */
|
||||
#endif
|
||||
png_error_ptr error_fn; /* function for printing errors and aborting */
|
||||
#ifdef PNG_WARNINGS_SUPPORTED
|
||||
png_error_ptr warning_fn; /* function for printing warnings */
|
||||
#endif
|
||||
png_voidp error_ptr; /* user supplied struct for error functions */
|
||||
png_rw_ptr write_data_fn; /* function for writing output data */
|
||||
png_rw_ptr read_data_fn; /* function for reading input data */
|
||||
png_voidp io_ptr; /* ptr to application struct for I/O functions */
|
||||
|
||||
#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
|
||||
png_user_transform_ptr read_user_transform_fn; /* user read transform */
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
|
||||
png_user_transform_ptr write_user_transform_fn; /* user write transform */
|
||||
#endif
|
||||
|
||||
/* These were added in libpng-1.0.2 */
|
||||
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
|
||||
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
|
||||
defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
|
||||
png_voidp user_transform_ptr; /* user supplied struct for user transform */
|
||||
png_byte user_transform_depth; /* bit depth of user transformed pixels */
|
||||
png_byte user_transform_channels; /* channels in user transformed pixels */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
png_uint_32 mode; /* tells us where we are in the PNG file */
|
||||
png_uint_32 flags; /* flags indicating various things to libpng */
|
||||
png_uint_32 transformations; /* which transformations to perform */
|
||||
|
||||
png_uint_32 zowner; /* ID (chunk type) of zstream owner, 0 if none */
|
||||
z_stream zstream; /* decompression structure */
|
||||
|
||||
#ifdef PNG_WRITE_SUPPORTED
|
||||
png_compression_bufferp zbuffer_list; /* Created on demand during write */
|
||||
uInt zbuffer_size; /* size of the actual buffer */
|
||||
|
||||
int zlib_level; /* holds zlib compression level */
|
||||
int zlib_method; /* holds zlib compression method */
|
||||
int zlib_window_bits; /* holds zlib compression window bits */
|
||||
int zlib_mem_level; /* holds zlib compression memory level */
|
||||
int zlib_strategy; /* holds zlib compression strategy */
|
||||
#endif
|
||||
/* Added at libpng 1.5.4 */
|
||||
#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
|
||||
int zlib_text_level; /* holds zlib compression level */
|
||||
int zlib_text_method; /* holds zlib compression method */
|
||||
int zlib_text_window_bits; /* holds zlib compression window bits */
|
||||
int zlib_text_mem_level; /* holds zlib compression memory level */
|
||||
int zlib_text_strategy; /* holds zlib compression strategy */
|
||||
#endif
|
||||
/* End of material added at libpng 1.5.4 */
|
||||
/* Added at libpng 1.6.0 */
|
||||
#ifdef PNG_WRITE_SUPPORTED
|
||||
int zlib_set_level; /* Actual values set into the zstream on write */
|
||||
int zlib_set_method;
|
||||
int zlib_set_window_bits;
|
||||
int zlib_set_mem_level;
|
||||
int zlib_set_strategy;
|
||||
#endif
|
||||
|
||||
png_uint_32 width; /* width of image in pixels */
|
||||
png_uint_32 height; /* height of image in pixels */
|
||||
png_uint_32 num_rows; /* number of rows in current pass */
|
||||
png_uint_32 usr_width; /* width of row at start of write */
|
||||
png_size_t rowbytes; /* size of row in bytes */
|
||||
png_uint_32 iwidth; /* width of current interlaced row in pixels */
|
||||
png_uint_32 row_number; /* current row in interlace pass */
|
||||
png_uint_32 chunk_name; /* PNG_CHUNK() id of current chunk */
|
||||
png_bytep prev_row; /* buffer to save previous (unfiltered) row.
|
||||
* This is a pointer into big_prev_row
|
||||
*/
|
||||
png_bytep row_buf; /* buffer to save current (unfiltered) row.
|
||||
* This is a pointer into big_row_buf
|
||||
*/
|
||||
#ifdef PNG_WRITE_SUPPORTED
|
||||
png_bytep sub_row; /* buffer to save "sub" row when filtering */
|
||||
png_bytep up_row; /* buffer to save "up" row when filtering */
|
||||
png_bytep avg_row; /* buffer to save "avg" row when filtering */
|
||||
png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */
|
||||
#endif
|
||||
png_size_t info_rowbytes; /* Added in 1.5.4: cache of updated row bytes */
|
||||
|
||||
png_uint_32 idat_size; /* current IDAT size for read */
|
||||
png_uint_32 crc; /* current chunk CRC value */
|
||||
png_colorp palette; /* palette from the input file */
|
||||
png_uint_16 num_palette; /* number of color entries in palette */
|
||||
|
||||
/* Added at libpng-1.5.10 */
|
||||
#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
|
||||
int num_palette_max; /* maximum palette index found in IDAT */
|
||||
#endif
|
||||
|
||||
png_uint_16 num_trans; /* number of transparency values */
|
||||
png_byte compression; /* file compression type (always 0) */
|
||||
png_byte filter; /* file filter type (always 0) */
|
||||
png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
|
||||
png_byte pass; /* current interlace pass (0 - 6) */
|
||||
png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */
|
||||
png_byte color_type; /* color type of file */
|
||||
png_byte bit_depth; /* bit depth of file */
|
||||
png_byte usr_bit_depth; /* bit depth of users row: write only */
|
||||
png_byte pixel_depth; /* number of bits per pixel */
|
||||
png_byte channels; /* number of channels in file */
|
||||
#ifdef PNG_WRITE_SUPPORTED
|
||||
png_byte usr_channels; /* channels at start of write: write only */
|
||||
#endif
|
||||
png_byte sig_bytes; /* magic bytes read/written from start of file */
|
||||
png_byte maximum_pixel_depth;
|
||||
/* pixel depth used for the row buffers */
|
||||
png_byte transformed_pixel_depth;
|
||||
/* pixel depth after read/write transforms */
|
||||
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
|
||||
png_uint_16 filler; /* filler bytes for pixel expansion */
|
||||
#endif
|
||||
|
||||
#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
|
||||
defined(PNG_READ_ALPHA_MODE_SUPPORTED)
|
||||
png_byte background_gamma_type;
|
||||
png_fixed_point background_gamma;
|
||||
png_color_16 background; /* background color in screen gamma space */
|
||||
#ifdef PNG_READ_GAMMA_SUPPORTED
|
||||
png_color_16 background_1; /* background normalized to gamma 1.0 */
|
||||
#endif
|
||||
#endif /* bKGD */
|
||||
|
||||
#ifdef PNG_WRITE_FLUSH_SUPPORTED
|
||||
png_flush_ptr output_flush_fn; /* Function for flushing output */
|
||||
png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */
|
||||
png_uint_32 flush_rows; /* number of rows written since last flush */
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_GAMMA_SUPPORTED
|
||||
int gamma_shift; /* number of "insignificant" bits in 16-bit gamma */
|
||||
png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */
|
||||
|
||||
png_bytep gamma_table; /* gamma table for 8-bit depth files */
|
||||
png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */
|
||||
#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
|
||||
defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
|
||||
defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
|
||||
png_bytep gamma_from_1; /* converts from 1.0 to screen */
|
||||
png_bytep gamma_to_1; /* converts from file to 1.0 */
|
||||
png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */
|
||||
png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */
|
||||
#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED)
|
||||
png_color_8 sig_bit; /* significant bits in each available channel */
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
|
||||
png_color_8 shift; /* shift for significant bit tranformation */
|
||||
#endif
|
||||
|
||||
#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \
|
||||
|| defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
|
||||
png_bytep trans_alpha; /* alpha values for paletted files */
|
||||
png_color_16 trans_color; /* transparent color for non-paletted files */
|
||||
#endif
|
||||
|
||||
png_read_status_ptr read_row_fn; /* called after each row is decoded */
|
||||
png_write_status_ptr write_row_fn; /* called after each row is encoded */
|
||||
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
|
||||
png_progressive_info_ptr info_fn; /* called after header data fully read */
|
||||
png_progressive_row_ptr row_fn; /* called after a prog. row is decoded */
|
||||
png_progressive_end_ptr end_fn; /* called after image is complete */
|
||||
png_bytep save_buffer_ptr; /* current location in save_buffer */
|
||||
png_bytep save_buffer; /* buffer for previously read data */
|
||||
png_bytep current_buffer_ptr; /* current location in current_buffer */
|
||||
png_bytep current_buffer; /* buffer for recently used data */
|
||||
png_uint_32 push_length; /* size of current input chunk */
|
||||
png_uint_32 skip_length; /* bytes to skip in input data */
|
||||
png_size_t save_buffer_size; /* amount of data now in save_buffer */
|
||||
png_size_t save_buffer_max; /* total size of save_buffer */
|
||||
png_size_t buffer_size; /* total amount of available input data */
|
||||
png_size_t current_buffer_size; /* amount of data now in current_buffer */
|
||||
int process_mode; /* what push library is currently doing */
|
||||
int cur_palette; /* current push library palette index */
|
||||
|
||||
#endif /* PROGRESSIVE_READ */
|
||||
|
||||
#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
|
||||
/* For the Borland special 64K segment handler */
|
||||
png_bytepp offset_table_ptr;
|
||||
png_bytep offset_table;
|
||||
png_uint_16 offset_table_number;
|
||||
png_uint_16 offset_table_count;
|
||||
png_uint_16 offset_table_count_free;
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_QUANTIZE_SUPPORTED
|
||||
png_bytep palette_lookup; /* lookup table for quantizing */
|
||||
png_bytep quantize_index; /* index translation for palette files */
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
|
||||
png_byte heuristic_method; /* heuristic for row filter selection */
|
||||
png_byte num_prev_filters; /* number of weights for previous rows */
|
||||
png_bytep prev_filters; /* filter type(s) of previous row(s) */
|
||||
png_uint_16p filter_weights; /* weight(s) for previous line(s) */
|
||||
png_uint_16p inv_filter_weights; /* 1/weight(s) for previous line(s) */
|
||||
png_uint_16p filter_costs; /* relative filter calculation cost */
|
||||
png_uint_16p inv_filter_costs; /* 1/relative filter calculation cost */
|
||||
#endif
|
||||
|
||||
/* Options */
|
||||
#ifdef PNG_SET_OPTION_SUPPORTED
|
||||
png_byte options; /* On/off state (up to 4 options) */
|
||||
#endif
|
||||
|
||||
#if PNG_LIBPNG_VER < 10700
|
||||
/* To do: remove this from libpng-1.7 */
|
||||
#ifdef PNG_TIME_RFC1123_SUPPORTED
|
||||
char time_buffer[29]; /* String to hold RFC 1123 time text */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* New members added in libpng-1.0.6 */
|
||||
|
||||
png_uint_32 free_me; /* flags items libpng is responsible for freeing */
|
||||
|
||||
#ifdef PNG_USER_CHUNKS_SUPPORTED
|
||||
png_voidp user_chunk_ptr;
|
||||
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
|
||||
png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
|
||||
int unknown_default; /* As PNG_HANDLE_* */
|
||||
unsigned int num_chunk_list; /* Number of entries in the list */
|
||||
png_bytep chunk_list; /* List of png_byte[5]; the textual chunk name
|
||||
* followed by a PNG_HANDLE_* byte */
|
||||
#endif
|
||||
|
||||
/* New members added in libpng-1.0.3 */
|
||||
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
|
||||
png_byte rgb_to_gray_status;
|
||||
/* Added in libpng 1.5.5 to record setting of coefficients: */
|
||||
png_byte rgb_to_gray_coefficients_set;
|
||||
/* These were changed from png_byte in libpng-1.0.6 */
|
||||
png_uint_16 rgb_to_gray_red_coeff;
|
||||
png_uint_16 rgb_to_gray_green_coeff;
|
||||
/* deleted in 1.5.5: rgb_to_gray_blue_coeff; */
|
||||
#endif
|
||||
|
||||
/* New member added in libpng-1.0.4 (renamed in 1.0.9) */
|
||||
#if defined(PNG_MNG_FEATURES_SUPPORTED)
|
||||
/* Changed from png_byte to png_uint_32 at version 1.2.0 */
|
||||
png_uint_32 mng_features_permitted;
|
||||
#endif
|
||||
|
||||
/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */
|
||||
#ifdef PNG_MNG_FEATURES_SUPPORTED
|
||||
png_byte filter_type;
|
||||
#endif
|
||||
|
||||
/* New members added in libpng-1.2.0 */
|
||||
|
||||
/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
png_voidp mem_ptr; /* user supplied struct for mem functions */
|
||||
png_malloc_ptr malloc_fn; /* function for allocating memory */
|
||||
png_free_ptr free_fn; /* function for freeing memory */
|
||||
#endif
|
||||
|
||||
/* New member added in libpng-1.0.13 and 1.2.0 */
|
||||
png_bytep big_row_buf; /* buffer to save current (unfiltered) row */
|
||||
|
||||
#ifdef PNG_READ_QUANTIZE_SUPPORTED
|
||||
/* The following three members were added at version 1.0.14 and 1.2.4 */
|
||||
png_bytep quantize_sort; /* working sort array */
|
||||
png_bytep index_to_palette; /* where the original index currently is
|
||||
in the palette */
|
||||
png_bytep palette_to_index; /* which original index points to this
|
||||
palette color */
|
||||
#endif
|
||||
|
||||
/* New members added in libpng-1.0.16 and 1.2.6 */
|
||||
png_byte compression_type;
|
||||
|
||||
#ifdef PNG_USER_LIMITS_SUPPORTED
|
||||
png_uint_32 user_width_max;
|
||||
png_uint_32 user_height_max;
|
||||
|
||||
/* Added in libpng-1.4.0: Total number of sPLT, text, and unknown
|
||||
* chunks that can be stored (0 means unlimited).
|
||||
*/
|
||||
png_uint_32 user_chunk_cache_max;
|
||||
|
||||
/* Total memory that a zTXt, sPLT, iTXt, iCCP, or unknown chunk
|
||||
* can occupy when decompressed. 0 means unlimited.
|
||||
*/
|
||||
png_alloc_size_t user_chunk_malloc_max;
|
||||
#endif
|
||||
|
||||
/* New member added in libpng-1.0.25 and 1.2.17 */
|
||||
#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
|
||||
/* Temporary storage for unknown chunk that the library doesn't recognize,
|
||||
* used while reading the chunk.
|
||||
*/
|
||||
png_unknown_chunk unknown_chunk;
|
||||
#endif
|
||||
|
||||
/* New member added in libpng-1.2.26 */
|
||||
png_size_t old_big_row_buf_size;
|
||||
|
||||
#ifdef PNG_READ_SUPPORTED
|
||||
/* New member added in libpng-1.2.30 */
|
||||
png_bytep read_buffer; /* buffer for reading chunk data */
|
||||
png_alloc_size_t read_buffer_size; /* current size of the buffer */
|
||||
#endif
|
||||
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
|
||||
uInt IDAT_read_size; /* limit on read buffer size for IDAT */
|
||||
#endif
|
||||
|
||||
#ifdef PNG_IO_STATE_SUPPORTED
|
||||
/* New member added in libpng-1.4.0 */
|
||||
png_uint_32 io_state;
|
||||
#endif
|
||||
|
||||
/* New member added in libpng-1.5.6 */
|
||||
png_bytep big_prev_row;
|
||||
|
||||
/* New member added in libpng-1.5.7 */
|
||||
void (*read_filter[PNG_FILTER_VALUE_LAST-1])(png_row_infop row_info,
|
||||
png_bytep row, png_const_bytep prev_row);
|
||||
|
||||
#ifdef PNG_READ_SUPPORTED
|
||||
#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)
|
||||
png_colorspace colorspace;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
#endif /* PNGSTRUCT_H */
|
||||
1632
thirdparty/libpng/pngtest.c
vendored
1632
thirdparty/libpng/pngtest.c
vendored
File diff suppressed because it is too large
Load Diff
608
thirdparty/libpng/pngtrans.c
vendored
608
thirdparty/libpng/pngtrans.c
vendored
@@ -1,8 +1,8 @@
|
||||
|
||||
/* 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
|
||||
* Last changed in libpng 1.6.17 [March 26, 2015]
|
||||
* Copyright (c) 1998-2015 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.)
|
||||
*
|
||||
@@ -11,20 +11,20 @@
|
||||
* 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_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
|
||||
|
||||
#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_set_bgr(png_structrp png_ptr)
|
||||
{
|
||||
png_debug(1, "in png_set_bgr");
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
|
||||
png_ptr->transformations |= PNG_BGR;
|
||||
}
|
||||
#endif
|
||||
@@ -32,12 +32,13 @@ png_set_bgr(png_structp png_ptr)
|
||||
#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_set_swap(png_structrp 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;
|
||||
}
|
||||
@@ -46,16 +47,19 @@ png_set_swap(png_structp png_ptr)
|
||||
#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_set_packing(png_structrp 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;
|
||||
# ifdef PNG_WRITE_SUPPORTED
|
||||
png_ptr->usr_bit_depth = 8;
|
||||
# endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -63,12 +67,13 @@ png_set_packing(png_structp png_ptr)
|
||||
#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_set_packswap(png_structrp 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;
|
||||
}
|
||||
@@ -76,12 +81,13 @@ png_set_packswap(png_structp png_ptr)
|
||||
|
||||
#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_set_shift(png_structrp png_ptr, png_const_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;
|
||||
}
|
||||
@@ -90,11 +96,11 @@ png_set_shift(png_structp png_ptr, png_color_8p true_bits)
|
||||
#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
|
||||
defined(PNG_WRITE_INTERLACING_SUPPORTED)
|
||||
int PNGAPI
|
||||
png_set_interlace_handling(png_structp png_ptr)
|
||||
png_set_interlace_handling(png_structrp png_ptr)
|
||||
{
|
||||
png_debug(1, "in png_set_interlace handling");
|
||||
|
||||
if (png_ptr && png_ptr->interlaced)
|
||||
if (png_ptr != 0 && png_ptr->interlaced != 0)
|
||||
{
|
||||
png_ptr->transformations |= PNG_INTERLACE;
|
||||
return (7);
|
||||
@@ -111,48 +117,101 @@ png_set_interlace_handling(png_structp png_ptr)
|
||||
* that don't like bytes as parameters.
|
||||
*/
|
||||
void PNGAPI
|
||||
png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
|
||||
png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
|
||||
{
|
||||
png_debug(1, "in png_set_filler");
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
|
||||
/* In libpng 1.6 it is possible to determine whether this is a read or write
|
||||
* operation and therefore to do more checking here for a valid call.
|
||||
*/
|
||||
if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
|
||||
{
|
||||
# ifdef PNG_READ_FILLER_SUPPORTED
|
||||
/* On read png_set_filler is always valid, regardless of the base PNG
|
||||
* format, because other transformations can give a format where the
|
||||
* filler code can execute (basically an 8 or 16-bit component RGB or G
|
||||
* format.)
|
||||
*
|
||||
* NOTE: usr_channels is not used by the read code! (This has led to
|
||||
* confusion in the past.) The filler is only used in the read code.
|
||||
*/
|
||||
png_ptr->filler = (png_uint_16)filler;
|
||||
# else
|
||||
png_app_error(png_ptr, "png_set_filler not supported on read");
|
||||
PNG_UNUSED(filler) /* not used in the write case */
|
||||
return;
|
||||
# endif
|
||||
}
|
||||
|
||||
else /* write */
|
||||
{
|
||||
# ifdef PNG_WRITE_FILLER_SUPPORTED
|
||||
/* On write the usr_channels parameter must be set correctly at the
|
||||
* start to record the number of channels in the app-supplied data.
|
||||
*/
|
||||
switch (png_ptr->color_type)
|
||||
{
|
||||
case PNG_COLOR_TYPE_RGB:
|
||||
png_ptr->usr_channels = 4;
|
||||
break;
|
||||
|
||||
case PNG_COLOR_TYPE_GRAY:
|
||||
if (png_ptr->bit_depth >= 8)
|
||||
{
|
||||
png_ptr->usr_channels = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* There simply isn't any code in libpng to strip out bits
|
||||
* from bytes when the components are less than a byte in
|
||||
* size!
|
||||
*/
|
||||
png_app_error(png_ptr,
|
||||
"png_set_filler is invalid for low bit depth gray output");
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
png_app_error(png_ptr,
|
||||
"png_set_filler: inappropriate color type");
|
||||
return;
|
||||
}
|
||||
# else
|
||||
png_app_error(png_ptr, "png_set_filler not supported on write");
|
||||
return;
|
||||
# endif
|
||||
}
|
||||
|
||||
/* Here on success - libpng supports the operation, set the transformation
|
||||
* and the flag to say where the filler channel is.
|
||||
*/
|
||||
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_set_add_alpha(png_structrp 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;
|
||||
/* The above may fail to do anything. */
|
||||
if ((png_ptr->transformations & PNG_FILLER) != 0)
|
||||
png_ptr->transformations |= PNG_ADD_ALPHA;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -160,12 +219,13 @@ png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
|
||||
#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
|
||||
defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
|
||||
void PNGAPI
|
||||
png_set_swap_alpha(png_structp png_ptr)
|
||||
png_set_swap_alpha(png_structrp png_ptr)
|
||||
{
|
||||
png_debug(1, "in png_set_swap_alpha");
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
|
||||
png_ptr->transformations |= PNG_SWAP_ALPHA;
|
||||
}
|
||||
#endif
|
||||
@@ -173,24 +233,26 @@ png_set_swap_alpha(png_structp png_ptr)
|
||||
#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
|
||||
defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
|
||||
void PNGAPI
|
||||
png_set_invert_alpha(png_structp png_ptr)
|
||||
png_set_invert_alpha(png_structrp 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_set_invert_mono(png_structrp png_ptr)
|
||||
{
|
||||
png_debug(1, "in png_set_invert_mono");
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
|
||||
png_ptr->transformations |= PNG_INVERT_MONO;
|
||||
}
|
||||
|
||||
@@ -206,8 +268,8 @@ png_do_invert(png_row_infop row_info, png_bytep row)
|
||||
if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
|
||||
{
|
||||
png_bytep rp = row;
|
||||
png_uint_32 i;
|
||||
png_uint_32 istop = row_info->rowbytes;
|
||||
png_size_t i;
|
||||
png_size_t istop = row_info->rowbytes;
|
||||
|
||||
for (i = 0; i < istop; i++)
|
||||
{
|
||||
@@ -215,36 +277,41 @@ png_do_invert(png_row_infop row_info, png_bytep row)
|
||||
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;
|
||||
png_size_t i;
|
||||
png_size_t istop = row_info->rowbytes;
|
||||
|
||||
for (i = 0; i < istop; i+=2)
|
||||
for (i = 0; i < istop; i += 2)
|
||||
{
|
||||
*rp = (png_byte)(~(*rp));
|
||||
rp+=2;
|
||||
rp += 2;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PNG_16BIT_SUPPORTED
|
||||
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;
|
||||
png_size_t i;
|
||||
png_size_t istop = row_info->rowbytes;
|
||||
|
||||
for (i = 0; i < istop; i+=4)
|
||||
for (i = 0; i < istop; i += 4)
|
||||
{
|
||||
*rp = (png_byte)(~(*rp));
|
||||
*(rp+1) = (png_byte)(~(*(rp+1)));
|
||||
rp+=4;
|
||||
*(rp + 1) = (png_byte)(~(*(rp + 1)));
|
||||
rp += 4;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_16BIT_SUPPORTED
|
||||
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
|
||||
/* Swaps byte order on 16 bit depth images */
|
||||
void /* PRIVATE */
|
||||
@@ -252,8 +319,7 @@ png_do_swap(png_row_infop row_info, png_bytep row)
|
||||
{
|
||||
png_debug(1, "in png_do_swap");
|
||||
|
||||
if (
|
||||
row_info->bit_depth == 16)
|
||||
if (row_info->bit_depth == 16)
|
||||
{
|
||||
png_bytep rp = row;
|
||||
png_uint_32 i;
|
||||
@@ -261,13 +327,21 @@ png_do_swap(png_row_infop row_info, png_bytep row)
|
||||
|
||||
for (i = 0; i < istop; i++, rp += 2)
|
||||
{
|
||||
#ifdef PNG_BUILTIN_BSWAP16_SUPPORTED
|
||||
/* Feature added to libpng-1.6.11 for testing purposes, not
|
||||
* enabled by default.
|
||||
*/
|
||||
*(png_uint_16*)rp = __builtin_bswap16(*(png_uint_16*)rp);
|
||||
#else
|
||||
png_byte t = *rp;
|
||||
*rp = *(rp + 1);
|
||||
*(rp + 1) = t;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
|
||||
static PNG_CONST png_byte onebppswaptable[256] = {
|
||||
@@ -381,19 +455,22 @@ png_do_packswap(png_row_infop row_info, png_bytep row)
|
||||
{
|
||||
png_debug(1, "in png_do_packswap");
|
||||
|
||||
if (
|
||||
row_info->bit_depth < 8)
|
||||
if (row_info->bit_depth < 8)
|
||||
{
|
||||
png_bytep rp, end, table;
|
||||
png_bytep rp;
|
||||
png_const_bytep end, table;
|
||||
|
||||
end = row + row_info->rowbytes;
|
||||
|
||||
if (row_info->bit_depth == 1)
|
||||
table = (png_bytep)onebppswaptable;
|
||||
table = onebppswaptable;
|
||||
|
||||
else if (row_info->bit_depth == 2)
|
||||
table = (png_bytep)twobppswaptable;
|
||||
table = twobppswaptable;
|
||||
|
||||
else if (row_info->bit_depth == 4)
|
||||
table = (png_bytep)fourbppswaptable;
|
||||
table = fourbppswaptable;
|
||||
|
||||
else
|
||||
return;
|
||||
|
||||
@@ -401,162 +478,123 @@ png_do_packswap(png_row_infop row_info, png_bytep row)
|
||||
*rp = table[*rp];
|
||||
}
|
||||
}
|
||||
#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
|
||||
#endif /* PACKSWAP || WRITE_PACKSWAP */
|
||||
|
||||
#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
|
||||
defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
|
||||
/* Remove filler or alpha byte(s) */
|
||||
/* Remove a channel - this used to be 'png_do_strip_filler' but it used a
|
||||
* somewhat weird combination of flags to determine what to do. All the calls
|
||||
* to png_do_strip_filler are changed in 1.5.2 to call this instead with the
|
||||
* correct arguments.
|
||||
*
|
||||
* The routine isn't general - the channel must be the channel at the start or
|
||||
* end (not in the middle) of each pixel.
|
||||
*/
|
||||
void /* PRIVATE */
|
||||
png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
|
||||
png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
|
||||
{
|
||||
png_debug(1, "in png_do_strip_filler");
|
||||
png_bytep sp = row; /* source pointer */
|
||||
png_bytep dp = row; /* destination pointer */
|
||||
png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */
|
||||
|
||||
/* At the start sp will point to the first byte to copy and dp to where
|
||||
* it is copied to. ep always points just beyond the end of the row, so
|
||||
* the loop simply copies (channels-1) channels until sp reaches ep.
|
||||
*
|
||||
* at_start: 0 -- convert AG, XG, ARGB, XRGB, AAGG, XXGG, etc.
|
||||
* nonzero -- convert GA, GX, RGBA, RGBX, GGAA, RRGGBBXX, etc.
|
||||
*/
|
||||
|
||||
/* GA, GX, XG cases */
|
||||
if (row_info->channels == 2)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
*/
|
||||
if (at_start != 0) /* Skip initial filler */
|
||||
++sp;
|
||||
else /* Skip initial channel and, for sp, the filler */
|
||||
sp += 2, ++dp;
|
||||
|
||||
*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;
|
||||
*/
|
||||
/* For a 1 pixel wide image there is nothing to do */
|
||||
while (sp < ep)
|
||||
*dp++ = *sp, sp += 2;
|
||||
|
||||
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;
|
||||
row_info->pixel_depth = 8;
|
||||
}
|
||||
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)
|
||||
|
||||
else if (row_info->bit_depth == 16)
|
||||
{
|
||||
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 (at_start != 0) /* Skip initial filler */
|
||||
sp += 2;
|
||||
else /* Skip initial channel and, for sp, the filler */
|
||||
sp += 4, dp += 2;
|
||||
|
||||
while (sp < ep)
|
||||
*dp++ = *sp++, *dp++ = *sp, sp += 3;
|
||||
|
||||
row_info->pixel_depth = 16;
|
||||
}
|
||||
if (flags & PNG_FLAG_STRIP_ALPHA)
|
||||
row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
|
||||
|
||||
else
|
||||
return; /* bad bit depth */
|
||||
|
||||
row_info->channels = 1;
|
||||
|
||||
/* Finally fix the color type if it records an alpha channel */
|
||||
if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
row_info->color_type = PNG_COLOR_TYPE_GRAY;
|
||||
}
|
||||
|
||||
/* RGBA, RGBX, XRGB cases */
|
||||
else if (row_info->channels == 4)
|
||||
{
|
||||
if (row_info->bit_depth == 8)
|
||||
{
|
||||
if (at_start != 0) /* Skip initial filler */
|
||||
++sp;
|
||||
else /* Skip initial channels and, for sp, the filler */
|
||||
sp += 4, dp += 3;
|
||||
|
||||
/* Note that the loop adds 3 to dp and 4 to sp each time. */
|
||||
while (sp < ep)
|
||||
*dp++ = *sp++, *dp++ = *sp++, *dp++ = *sp, sp += 2;
|
||||
|
||||
row_info->pixel_depth = 24;
|
||||
}
|
||||
|
||||
else if (row_info->bit_depth == 16)
|
||||
{
|
||||
if (at_start != 0) /* Skip initial filler */
|
||||
sp += 2;
|
||||
else /* Skip initial channels and, for sp, the filler */
|
||||
sp += 8, dp += 6;
|
||||
|
||||
while (sp < ep)
|
||||
{
|
||||
/* Copy 6 bytes, skip 2 */
|
||||
*dp++ = *sp++, *dp++ = *sp++;
|
||||
*dp++ = *sp++, *dp++ = *sp++;
|
||||
*dp++ = *sp++, *dp++ = *sp, sp += 3;
|
||||
}
|
||||
|
||||
row_info->pixel_depth = 48;
|
||||
}
|
||||
|
||||
else
|
||||
return; /* bad bit depth */
|
||||
|
||||
row_info->channels = 3;
|
||||
|
||||
/* Finally fix the color type if it records an alpha channel */
|
||||
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
||||
row_info->color_type = PNG_COLOR_TYPE_RGB;
|
||||
}
|
||||
|
||||
else
|
||||
return; /* The filler channel has gone already */
|
||||
|
||||
/* Fix the rowbytes value. */
|
||||
row_info->rowbytes = dp-row;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -567,8 +605,7 @@ 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))
|
||||
if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
|
||||
{
|
||||
png_uint_32 row_width = row_info->width;
|
||||
if (row_info->bit_depth == 8)
|
||||
@@ -585,6 +622,7 @@ png_do_bgr(png_row_infop row_info, png_bytep row)
|
||||
*(rp + 2) = save;
|
||||
}
|
||||
}
|
||||
|
||||
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
||||
{
|
||||
png_bytep rp;
|
||||
@@ -598,6 +636,8 @@ png_do_bgr(png_row_infop row_info, png_bytep row)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PNG_16BIT_SUPPORTED
|
||||
else if (row_info->bit_depth == 16)
|
||||
{
|
||||
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
|
||||
@@ -615,6 +655,7 @@ png_do_bgr(png_row_infop row_info, png_bytep row)
|
||||
*(rp + 5) = save;
|
||||
}
|
||||
}
|
||||
|
||||
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
||||
{
|
||||
png_bytep rp;
|
||||
@@ -631,47 +672,178 @@ png_do_bgr(png_row_infop row_info, png_bytep row)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
|
||||
#endif /* READ_BGR || WRITE_BGR */
|
||||
|
||||
#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \
|
||||
defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
|
||||
/* Added at libpng-1.5.10 */
|
||||
void /* PRIVATE */
|
||||
png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
|
||||
{
|
||||
if (png_ptr->num_palette < (1 << row_info->bit_depth) &&
|
||||
png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */
|
||||
{
|
||||
/* Calculations moved outside switch in an attempt to stop different
|
||||
* compiler warnings. 'padding' is in *bits* within the last byte, it is
|
||||
* an 'int' because pixel_depth becomes an 'int' in the expression below,
|
||||
* and this calculation is used because it avoids warnings that other
|
||||
* forms produced on either GCC or MSVC.
|
||||
*/
|
||||
int padding = (-row_info->pixel_depth * row_info->width) & 7;
|
||||
png_bytep rp = png_ptr->row_buf + row_info->rowbytes;
|
||||
|
||||
switch (row_info->bit_depth)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
/* in this case, all bytes must be 0 so we don't need
|
||||
* to unpack the pixels except for the rightmost one.
|
||||
*/
|
||||
for (; rp > png_ptr->row_buf; rp--)
|
||||
{
|
||||
if (*rp >> padding != 0)
|
||||
png_ptr->num_palette_max = 1;
|
||||
padding = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
for (; rp > png_ptr->row_buf; rp--)
|
||||
{
|
||||
int i = ((*rp >> padding) & 0x03);
|
||||
|
||||
if (i > png_ptr->num_palette_max)
|
||||
png_ptr->num_palette_max = i;
|
||||
|
||||
i = (((*rp >> padding) >> 2) & 0x03);
|
||||
|
||||
if (i > png_ptr->num_palette_max)
|
||||
png_ptr->num_palette_max = i;
|
||||
|
||||
i = (((*rp >> padding) >> 4) & 0x03);
|
||||
|
||||
if (i > png_ptr->num_palette_max)
|
||||
png_ptr->num_palette_max = i;
|
||||
|
||||
i = (((*rp >> padding) >> 6) & 0x03);
|
||||
|
||||
if (i > png_ptr->num_palette_max)
|
||||
png_ptr->num_palette_max = i;
|
||||
|
||||
padding = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
for (; rp > png_ptr->row_buf; rp--)
|
||||
{
|
||||
int i = ((*rp >> padding) & 0x0f);
|
||||
|
||||
if (i > png_ptr->num_palette_max)
|
||||
png_ptr->num_palette_max = i;
|
||||
|
||||
i = (((*rp >> padding) >> 4) & 0x0f);
|
||||
|
||||
if (i > png_ptr->num_palette_max)
|
||||
png_ptr->num_palette_max = i;
|
||||
|
||||
padding = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 8:
|
||||
{
|
||||
for (; rp > png_ptr->row_buf; rp--)
|
||||
{
|
||||
if (*rp > png_ptr->num_palette_max)
|
||||
png_ptr->num_palette_max = (int) *rp;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* CHECK_FOR_INVALID_INDEX */
|
||||
|
||||
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
|
||||
defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
|
||||
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
|
||||
void PNGAPI
|
||||
png_set_user_transform_info(png_structp png_ptr, png_voidp
|
||||
png_set_user_transform_info(png_structrp 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
|
||||
|
||||
#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
|
||||
if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
|
||||
(png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
|
||||
{
|
||||
png_app_error(png_ptr,
|
||||
"info change after png_start_read_image or png_read_update_info");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
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
|
||||
}
|
||||
#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.
|
||||
*/
|
||||
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
|
||||
png_voidp PNGAPI
|
||||
png_get_user_transform_ptr(png_structp png_ptr)
|
||||
png_get_user_transform_ptr(png_const_structrp 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
|
||||
|
||||
return png_ptr->user_transform_ptr;
|
||||
}
|
||||
#endif /* PNG_READ_USER_TRANSFORM_SUPPORTED ||
|
||||
PNG_WRITE_USER_TRANSFORM_SUPPORTED */
|
||||
#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
|
||||
#endif
|
||||
|
||||
#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_current_row_number(png_const_structrp png_ptr)
|
||||
{
|
||||
/* See the comments in png.h - this is the sub-image row when reading an
|
||||
* interlaced image.
|
||||
*/
|
||||
if (png_ptr != NULL)
|
||||
return png_ptr->row_number;
|
||||
|
||||
return PNG_UINT_32_MAX; /* help the app not to fail silently */
|
||||
}
|
||||
|
||||
png_byte PNGAPI
|
||||
png_get_current_pass_number(png_const_structrp png_ptr)
|
||||
{
|
||||
if (png_ptr != NULL)
|
||||
return png_ptr->pass;
|
||||
return 8; /* invalid */
|
||||
}
|
||||
#endif /* USER_TRANSFORM_INFO */
|
||||
#endif /* READ_USER_TRANSFORM || WRITE_USER_TRANSFORM */
|
||||
#endif /* READ || WRITE */
|
||||
|
||||
147
thirdparty/libpng/pngwio.c
vendored
147
thirdparty/libpng/pngwio.c
vendored
@@ -1,8 +1,8 @@
|
||||
|
||||
/* pngwio.c - functions for data output
|
||||
*
|
||||
* Last changed in libpng 1.4.0 [January 3, 2010]
|
||||
* Copyright (c) 1998-2010 Glenn Randers-Pehrson
|
||||
* Last changed in libpng 1.6.15 [November 20, 2014]
|
||||
* Copyright (c) 1998-2014 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.)
|
||||
*
|
||||
@@ -18,11 +18,10 @@
|
||||
* them at run time with png_set_write_fn(...).
|
||||
*/
|
||||
|
||||
#define PNG_NO_PEDANTIC_WARNINGS
|
||||
#include "png.h"
|
||||
#ifdef PNG_WRITE_SUPPORTED
|
||||
#include "pngpriv.h"
|
||||
|
||||
#ifdef PNG_WRITE_SUPPORTED
|
||||
|
||||
/* 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
|
||||
@@ -31,10 +30,13 @@
|
||||
*/
|
||||
|
||||
void /* PRIVATE */
|
||||
png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
png_write_data(png_structrp png_ptr, png_const_bytep data, png_size_t length)
|
||||
{
|
||||
/* NOTE: write_data_fn must not change the buffer! */
|
||||
if (png_ptr->write_data_fn != NULL )
|
||||
(*(png_ptr->write_data_fn))(png_ptr, data, length);
|
||||
(*(png_ptr->write_data_fn))(png_ptr, png_constcast(png_bytep,data),
|
||||
length);
|
||||
|
||||
else
|
||||
png_error(png_ptr, "Call to NULL write function");
|
||||
}
|
||||
@@ -45,70 +47,19 @@ png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
* 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
|
||||
void PNGCBAPI
|
||||
png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
{
|
||||
png_uint_32 check;
|
||||
png_size_t 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
|
||||
@@ -117,23 +68,25 @@ png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
*/
|
||||
#ifdef PNG_WRITE_FLUSH_SUPPORTED
|
||||
void /* PRIVATE */
|
||||
png_flush(png_structp png_ptr)
|
||||
png_flush(png_structrp png_ptr)
|
||||
{
|
||||
if (png_ptr->output_flush_fn != NULL)
|
||||
(*(png_ptr->output_flush_fn))(png_ptr);
|
||||
}
|
||||
|
||||
#ifdef PNG_STDIO_SUPPORTED
|
||||
void PNGAPI
|
||||
# ifdef PNG_STDIO_SUPPORTED
|
||||
void PNGCBAPI
|
||||
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));
|
||||
|
||||
io_ptr = png_voidcast(png_FILE_p, (png_ptr->io_ptr));
|
||||
fflush(io_ptr);
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* This function allows the application to supply new output functions for
|
||||
@@ -166,8 +119,8 @@ png_default_flush(png_structp png_ptr)
|
||||
* *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)
|
||||
png_set_write_fn(png_structrp png_ptr, png_voidp io_ptr,
|
||||
png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
|
||||
{
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
@@ -185,57 +138,31 @@ png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_FLUSH_SUPPORTED
|
||||
#ifdef PNG_STDIO_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 */
|
||||
|
||||
# else
|
||||
png_ptr->output_flush_fn = output_flush_fn;
|
||||
# endif
|
||||
#else
|
||||
PNG_UNUSED(output_flush_fn)
|
||||
#endif /* WRITE_FLUSH */
|
||||
|
||||
#ifdef PNG_READ_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");
|
||||
"Can't set both read_data_fn and write_data_fn in the"
|
||||
" same structure");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#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 */
|
||||
#endif /* WRITE */
|
||||
|
||||
2354
thirdparty/libpng/pngwrite.c
vendored
2354
thirdparty/libpng/pngwrite.c
vendored
File diff suppressed because it is too large
Load Diff
324
thirdparty/libpng/pngwtran.c
vendored
324
thirdparty/libpng/pngwtran.c
vendored
@@ -1,8 +1,8 @@
|
||||
|
||||
/* 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
|
||||
* Last changed in libpng 1.6.17 [March 26, 2015]
|
||||
* Copyright (c) 1998-2015 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.)
|
||||
*
|
||||
@@ -11,84 +11,17 @@
|
||||
* 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_SUPPORTED
|
||||
#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
|
||||
|
||||
#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 */
|
||||
static void
|
||||
png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
|
||||
{
|
||||
png_debug(1, "in png_do_pack");
|
||||
@@ -114,9 +47,12 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
|
||||
{
|
||||
if (*sp != 0)
|
||||
v |= mask;
|
||||
|
||||
sp++;
|
||||
|
||||
if (mask > 1)
|
||||
mask >>= 1;
|
||||
|
||||
else
|
||||
{
|
||||
mask = 0x80;
|
||||
@@ -125,10 +61,13 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
|
||||
v = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (mask != 0x80)
|
||||
*dp = (png_byte)v;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
png_bytep sp, dp;
|
||||
@@ -140,12 +79,14 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
|
||||
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;
|
||||
@@ -153,14 +94,19 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
|
||||
dp++;
|
||||
v = 0;
|
||||
}
|
||||
|
||||
else
|
||||
shift -= 2;
|
||||
|
||||
sp++;
|
||||
}
|
||||
|
||||
if (shift != 6)
|
||||
*dp = (png_byte)v;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
png_bytep sp, dp;
|
||||
@@ -172,6 +118,7 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
|
||||
dp = row;
|
||||
shift = 4;
|
||||
v = 0;
|
||||
|
||||
for (i = 0; i < row_width; i++)
|
||||
{
|
||||
png_byte value;
|
||||
@@ -186,20 +133,27 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
|
||||
dp++;
|
||||
v = 0;
|
||||
}
|
||||
|
||||
else
|
||||
shift -= 4;
|
||||
|
||||
sp++;
|
||||
}
|
||||
|
||||
if (shift != 4)
|
||||
*dp = (png_byte)v;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
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);
|
||||
row_info->width);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -212,36 +166,40 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
|
||||
* 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)
|
||||
static void
|
||||
png_do_shift(png_row_infop row_info, png_bytep row,
|
||||
png_const_color_8p bit_depth)
|
||||
{
|
||||
png_debug(1, "in png_do_shift");
|
||||
|
||||
if (
|
||||
row_info->color_type != PNG_COLOR_TYPE_PALETTE)
|
||||
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)
|
||||
if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
|
||||
{
|
||||
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)
|
||||
|
||||
if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
|
||||
{
|
||||
shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
|
||||
shift_dec[channels] = bit_depth->alpha;
|
||||
@@ -252,33 +210,40 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
|
||||
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;
|
||||
png_size_t i;
|
||||
unsigned int mask;
|
||||
png_size_t 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;
|
||||
unsigned int v, out;
|
||||
|
||||
v = *bp;
|
||||
*bp = 0;
|
||||
out = 0;
|
||||
|
||||
for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
|
||||
{
|
||||
if (j > 0)
|
||||
*bp |= (png_byte)((v << j) & 0xff);
|
||||
out |= v << j;
|
||||
|
||||
else
|
||||
*bp |= (png_byte)((v >> (-j)) & mask);
|
||||
out |= (v >> (-j)) & mask;
|
||||
}
|
||||
|
||||
*bp = (png_byte)(out & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
else if (row_info->bit_depth == 8)
|
||||
{
|
||||
png_bytep bp = row;
|
||||
@@ -288,21 +253,26 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
|
||||
for (i = 0; i < istop; i++, bp++)
|
||||
{
|
||||
|
||||
png_uint_16 v;
|
||||
const unsigned int c = i%channels;
|
||||
int j;
|
||||
int c = (int)(i%channels);
|
||||
unsigned int v, out;
|
||||
|
||||
v = *bp;
|
||||
*bp = 0;
|
||||
out = 0;
|
||||
|
||||
for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
|
||||
{
|
||||
if (j > 0)
|
||||
*bp |= (png_byte)((v << j) & 0xff);
|
||||
out |= v << j;
|
||||
|
||||
else
|
||||
*bp |= (png_byte)((v >> (-j)) & 0xff);
|
||||
out |= v >> (-j);
|
||||
}
|
||||
|
||||
*bp = (png_byte)(out & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
png_bytep bp;
|
||||
@@ -311,20 +281,22 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
|
||||
|
||||
for (bp = row, i = 0; i < istop; i++)
|
||||
{
|
||||
int c = (int)(i%channels);
|
||||
png_uint_16 value, v;
|
||||
const unsigned int c = i%channels;
|
||||
int j;
|
||||
unsigned int value, v;
|
||||
|
||||
v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
|
||||
v = png_get_uint_16(bp);
|
||||
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);
|
||||
value |= v << j;
|
||||
|
||||
else
|
||||
value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
|
||||
value |= v >> (-j);
|
||||
}
|
||||
*bp++ = (png_byte)(value >> 8);
|
||||
*bp++ = (png_byte)((value >> 8) & 0xff);
|
||||
*bp++ = (png_byte)(value & 0xff);
|
||||
}
|
||||
}
|
||||
@@ -333,7 +305,7 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
|
||||
void /* PRIVATE */
|
||||
static void
|
||||
png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
|
||||
{
|
||||
png_debug(1, "in png_do_write_swap_alpha");
|
||||
@@ -341,12 +313,13 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
|
||||
{
|
||||
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
||||
{
|
||||
/* This converts from ARGB to RGBA */
|
||||
if (row_info->bit_depth == 8)
|
||||
{
|
||||
/* This converts from ARGB to RGBA */
|
||||
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++);
|
||||
@@ -356,9 +329,11 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
|
||||
*(dp++) = save;
|
||||
}
|
||||
}
|
||||
/* This converts from AARRGGBB to RRGGBBAA */
|
||||
|
||||
#ifdef PNG_WRITE_16BIT_SUPPORTED
|
||||
else
|
||||
{
|
||||
/* This converts from AARRGGBB to RRGGBBAA */
|
||||
png_bytep sp, dp;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
@@ -378,12 +353,14 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
|
||||
*(dp++) = save[1];
|
||||
}
|
||||
}
|
||||
#endif /* WRITE_16BIT */
|
||||
}
|
||||
|
||||
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
{
|
||||
/* This converts from AG to GA */
|
||||
if (row_info->bit_depth == 8)
|
||||
{
|
||||
/* This converts from AG to GA */
|
||||
png_bytep sp, dp;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
@@ -395,9 +372,11 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
|
||||
*(dp++) = save;
|
||||
}
|
||||
}
|
||||
/* This converts from AAGG to GGAA */
|
||||
|
||||
#ifdef PNG_WRITE_16BIT_SUPPORTED
|
||||
else
|
||||
{
|
||||
/* This converts from AAGG to GGAA */
|
||||
png_bytep sp, dp;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
@@ -413,13 +392,14 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
|
||||
*(dp++) = save[1];
|
||||
}
|
||||
}
|
||||
#endif /* WRITE_16BIT */
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
|
||||
void /* PRIVATE */
|
||||
static void
|
||||
png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
|
||||
{
|
||||
png_debug(1, "in png_do_write_invert_alpha");
|
||||
@@ -427,12 +407,13 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
|
||||
{
|
||||
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
||||
{
|
||||
/* This inverts the alpha channel in RGBA */
|
||||
if (row_info->bit_depth == 8)
|
||||
{
|
||||
/* This inverts the alpha channel in RGBA */
|
||||
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
|
||||
@@ -444,9 +425,11 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
|
||||
*(dp++) = (png_byte)(255 - *(sp++));
|
||||
}
|
||||
}
|
||||
/* This inverts the alpha channel in RRGGBBAA */
|
||||
|
||||
#ifdef PNG_WRITE_16BIT_SUPPORTED
|
||||
else
|
||||
{
|
||||
/* This inverts the alpha channel in RRGGBBAA */
|
||||
png_bytep sp, dp;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
@@ -466,12 +449,14 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
|
||||
*(dp++) = (png_byte)(255 - *(sp++));
|
||||
}
|
||||
}
|
||||
#endif /* WRITE_16BIT */
|
||||
}
|
||||
|
||||
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
{
|
||||
/* This inverts the alpha channel in GA */
|
||||
if (row_info->bit_depth == 8)
|
||||
{
|
||||
/* This inverts the alpha channel in GA */
|
||||
png_bytep sp, dp;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
@@ -482,9 +467,11 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
|
||||
*(dp++) = (png_byte)(255 - *(sp++));
|
||||
}
|
||||
}
|
||||
/* This inverts the alpha channel in GGAA */
|
||||
|
||||
#ifdef PNG_WRITE_16BIT_SUPPORTED
|
||||
else
|
||||
{
|
||||
/* This inverts the alpha channel in GGAA */
|
||||
png_bytep sp, dp;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
@@ -500,67 +487,88 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
|
||||
*(dp++) = (png_byte)(255 - *(sp++));
|
||||
}
|
||||
}
|
||||
#endif /* WRITE_16BIT */
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_MNG_FEATURES_SUPPORTED
|
||||
/* Undoes intrapixel differencing */
|
||||
/* Transform the data according to the user's wishes. The order of
|
||||
* transformations is significant.
|
||||
*/
|
||||
void /* PRIVATE */
|
||||
png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
|
||||
png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info)
|
||||
{
|
||||
png_debug(1, "in png_do_write_intrapixel");
|
||||
png_debug(1, "in png_do_write_transformations");
|
||||
|
||||
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 (png_ptr == NULL)
|
||||
return;
|
||||
|
||||
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;
|
||||
#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
|
||||
if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
|
||||
if (png_ptr->write_user_transform_fn != NULL)
|
||||
(*(png_ptr->write_user_transform_fn)) /* User write transform
|
||||
function */
|
||||
(png_ptr, /* png_ptr */
|
||||
row_info, /* row_info: */
|
||||
/* png_uint_32 width; width of row */
|
||||
/* png_size_t 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
|
||||
|
||||
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;
|
||||
#ifdef PNG_WRITE_FILLER_SUPPORTED
|
||||
if ((png_ptr->transformations & PNG_FILLER) != 0)
|
||||
png_do_strip_channel(row_info, png_ptr->row_buf + 1,
|
||||
!(png_ptr->flags & PNG_FLAG_FILLER_AFTER));
|
||||
#endif
|
||||
|
||||
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;
|
||||
#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
|
||||
if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
|
||||
png_do_packswap(row_info, png_ptr->row_buf + 1);
|
||||
#endif
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef PNG_WRITE_PACK_SUPPORTED
|
||||
if ((png_ptr->transformations & PNG_PACK) != 0)
|
||||
png_do_pack(row_info, png_ptr->row_buf + 1,
|
||||
(png_uint_32)png_ptr->bit_depth);
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_SWAP_SUPPORTED
|
||||
# ifdef PNG_16BIT_SUPPORTED
|
||||
if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)
|
||||
png_do_swap(row_info, png_ptr->row_buf + 1);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_SHIFT_SUPPORTED
|
||||
if ((png_ptr->transformations & PNG_SHIFT) != 0)
|
||||
png_do_shift(row_info, png_ptr->row_buf + 1,
|
||||
&(png_ptr->shift));
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
|
||||
if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0)
|
||||
png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1);
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
|
||||
if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
|
||||
png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1);
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_BGR_SUPPORTED
|
||||
if ((png_ptr->transformations & PNG_BGR) != 0)
|
||||
png_do_bgr(row_info, png_ptr->row_buf + 1);
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_INVERT_SUPPORTED
|
||||
if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)
|
||||
png_do_invert(row_info, png_ptr->row_buf + 1);
|
||||
#endif
|
||||
}
|
||||
#endif /* PNG_MNG_FEATURES_SUPPORTED */
|
||||
#endif /* PNG_WRITE_SUPPORTED */
|
||||
#endif /* WRITE_TRANSFORMS */
|
||||
#endif /* WRITE */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user