mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-15 18:33:41 +00:00
8183032: Upgrade to LittleCMS 2.9
Reviewed-by: serb, psadhukhan, mschoene, rhalade
This commit is contained in:
parent
0b873290a4
commit
232855d24e
@ -391,12 +391,12 @@ JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative
|
||||
{
|
||||
lcmsProfile_p sProf = (lcmsProfile_p)jlong_to_ptr(id);
|
||||
TagSignature_t sig;
|
||||
cmsInt32Number tagSize;
|
||||
cmsUInt32Number tagSize;
|
||||
|
||||
jbyte* dataArray = NULL;
|
||||
jbyteArray data = NULL;
|
||||
|
||||
jint bufSize;
|
||||
cmsUInt32Number bufSize;
|
||||
|
||||
sig.j = tagSig;
|
||||
|
||||
@ -839,7 +839,7 @@ static cmsHPROFILE _writeCookedTag(const cmsHPROFILE pfTarget,
|
||||
for (i = 0; i < tagCount; i++) {
|
||||
cmsBool isTagReady = FALSE;
|
||||
const cmsTagSignature s = cmsGetTagSignature(pfTarget, i);
|
||||
const cmsInt32Number tagSize = cmsReadRawTag(pfTarget, s, NULL, 0);
|
||||
const cmsUInt32Number tagSize = cmsReadRawTag(pfTarget, s, NULL, 0);
|
||||
|
||||
if (s == sig) {
|
||||
// skip the user supplied tag
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
@ -55,7 +55,6 @@
|
||||
|
||||
#include "lcms2_internal.h"
|
||||
|
||||
|
||||
// Alpha copy ------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Floor to byte, taking care of saturation
|
||||
@ -71,16 +70,16 @@ cmsINLINE cmsUInt8Number _cmsQuickSaturateByte(cmsFloat64Number d)
|
||||
|
||||
// Return the size in bytes of a given formatter
|
||||
static
|
||||
int trueBytesSize(cmsUInt32Number Format)
|
||||
cmsUInt32Number trueBytesSize(cmsUInt32Number Format)
|
||||
{
|
||||
int fmt_bytes = T_BYTES(Format);
|
||||
cmsUInt32Number fmt_bytes = T_BYTES(Format);
|
||||
|
||||
// For double, the T_BYTES field returns zero
|
||||
if (fmt_bytes == 0)
|
||||
return sizeof(double);
|
||||
// For double, the T_BYTES field returns zero
|
||||
if (fmt_bytes == 0)
|
||||
return sizeof(double);
|
||||
|
||||
// Otherwise, it is already correct for all formats
|
||||
return fmt_bytes;
|
||||
// Otherwise, it is already correct for all formats
|
||||
return fmt_bytes;
|
||||
}
|
||||
|
||||
|
||||
@ -119,8 +118,13 @@ void from8toDBL(void* dst, const void* src)
|
||||
static
|
||||
void from8toHLF(void* dst, const void* src)
|
||||
{
|
||||
#ifndef CMS_NO_HALF_SUPPORT
|
||||
cmsFloat32Number n = (*(cmsUInt8Number*)src) / 255.0f;
|
||||
*(cmsUInt16Number*)dst = _cmsFloat2Half(n);
|
||||
#else
|
||||
cmsUNUSED_PARAMETER(dst);
|
||||
cmsUNUSED_PARAMETER(src);
|
||||
#endif
|
||||
}
|
||||
|
||||
// From 16
|
||||
@ -151,8 +155,13 @@ void from16toDBL(void* dst, const void* src)
|
||||
static
|
||||
void from16toHLF(void* dst, const void* src)
|
||||
{
|
||||
#ifndef CMS_NO_HALF_SUPPORT
|
||||
cmsFloat32Number n = (*(cmsUInt16Number*)src) / 65535.0f;
|
||||
*(cmsUInt16Number*)dst = _cmsFloat2Half(n);
|
||||
#else
|
||||
cmsUNUSED_PARAMETER(dst);
|
||||
cmsUNUSED_PARAMETER(src);
|
||||
#endif
|
||||
}
|
||||
|
||||
// From Float
|
||||
@ -187,8 +196,13 @@ void fromFLTtoDBL(void* dst, const void* src)
|
||||
static
|
||||
void fromFLTtoHLF(void* dst, const void* src)
|
||||
{
|
||||
#ifndef CMS_NO_HALF_SUPPORT
|
||||
cmsFloat32Number n = *(cmsFloat32Number*)src;
|
||||
*(cmsUInt16Number*)dst = _cmsFloat2Half(n);
|
||||
#else
|
||||
cmsUNUSED_PARAMETER(dst);
|
||||
cmsUNUSED_PARAMETER(src);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -197,27 +211,48 @@ void fromFLTtoHLF(void* dst, const void* src)
|
||||
static
|
||||
void fromHLFto8(void* dst, const void* src)
|
||||
{
|
||||
#ifndef CMS_NO_HALF_SUPPORT
|
||||
cmsFloat32Number n = _cmsHalf2Float(*(cmsUInt16Number*)src);
|
||||
*(cmsUInt8Number*)dst = _cmsQuickSaturateByte(n * 255.0f);
|
||||
#else
|
||||
cmsUNUSED_PARAMETER(dst);
|
||||
cmsUNUSED_PARAMETER(src);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static
|
||||
void fromHLFto16(void* dst, const void* src)
|
||||
{
|
||||
#ifndef CMS_NO_HALF_SUPPORT
|
||||
cmsFloat32Number n = _cmsHalf2Float(*(cmsUInt16Number*)src);
|
||||
*(cmsUInt16Number*)dst = _cmsQuickSaturateWord(n * 65535.0f);
|
||||
#else
|
||||
cmsUNUSED_PARAMETER(dst);
|
||||
cmsUNUSED_PARAMETER(src);
|
||||
#endif
|
||||
}
|
||||
|
||||
static
|
||||
void fromHLFtoFLT(void* dst, const void* src)
|
||||
{
|
||||
#ifndef CMS_NO_HALF_SUPPORT
|
||||
*(cmsFloat32Number*)dst = _cmsHalf2Float(*(cmsUInt16Number*)src);
|
||||
#else
|
||||
cmsUNUSED_PARAMETER(dst);
|
||||
cmsUNUSED_PARAMETER(src);
|
||||
#endif
|
||||
}
|
||||
|
||||
static
|
||||
void fromHLFtoDBL(void* dst, const void* src)
|
||||
{
|
||||
#ifndef CMS_NO_HALF_SUPPORT
|
||||
*(cmsFloat64Number*)dst = (cmsFloat64Number)_cmsHalf2Float(*(cmsUInt16Number*)src);
|
||||
#else
|
||||
cmsUNUSED_PARAMETER(dst);
|
||||
cmsUNUSED_PARAMETER(src);
|
||||
#endif
|
||||
}
|
||||
|
||||
// From double
|
||||
@ -245,8 +280,13 @@ void fromDBLtoFLT(void* dst, const void* src)
|
||||
static
|
||||
void fromDBLtoHLF(void* dst, const void* src)
|
||||
{
|
||||
#ifndef CMS_NO_HALF_SUPPORT
|
||||
cmsFloat32Number n = (cmsFloat32Number) *(cmsFloat64Number*)src;
|
||||
*(cmsUInt16Number*)dst = _cmsFloat2Half(n);
|
||||
#else
|
||||
cmsUNUSED_PARAMETER(dst);
|
||||
cmsUNUSED_PARAMETER(src);
|
||||
#endif
|
||||
}
|
||||
|
||||
static
|
||||
@ -260,21 +300,22 @@ void copy64(void* dst, const void* src)
|
||||
static
|
||||
int FormatterPos(cmsUInt32Number frm)
|
||||
{
|
||||
int b = T_BYTES(frm);
|
||||
cmsUInt32Number b = T_BYTES(frm);
|
||||
|
||||
if (b == 0 && T_FLOAT(frm))
|
||||
return 4; // DBL
|
||||
if (b == 2 && T_FLOAT(frm))
|
||||
return 2; // HLF
|
||||
if (b == 4 && T_FLOAT(frm))
|
||||
return 3; // FLT
|
||||
if (b == 2 && !T_FLOAT(frm))
|
||||
return 1; // 16
|
||||
if (b == 1 && !T_FLOAT(frm))
|
||||
return 0; // 8
|
||||
|
||||
return -1; // not recognized
|
||||
if (b == 0 && T_FLOAT(frm))
|
||||
return 4; // DBL
|
||||
#ifndef CMS_NO_HALF_SUPPORT
|
||||
if (b == 2 && T_FLOAT(frm))
|
||||
return 2; // HLF
|
||||
#endif
|
||||
if (b == 4 && T_FLOAT(frm))
|
||||
return 3; // FLT
|
||||
if (b == 2 && !T_FLOAT(frm))
|
||||
return 1; // 16
|
||||
if (b == 1 && !T_FLOAT(frm))
|
||||
return 0; // 8
|
||||
|
||||
return -1; // not recognized
|
||||
}
|
||||
|
||||
// Obtains a alpha-to-alpha funmction formatter
|
||||
@ -310,12 +351,12 @@ void ComputeIncrementsForChunky(cmsUInt32Number Format,
|
||||
cmsUInt32Number ComponentPointerIncrements[])
|
||||
{
|
||||
cmsUInt32Number channels[cmsMAXCHANNELS];
|
||||
int extra = T_EXTRA(Format);
|
||||
int nchannels = T_CHANNELS(Format);
|
||||
int total_chans = nchannels + extra;
|
||||
int i;
|
||||
int channelSize = trueBytesSize(Format);
|
||||
int pixelSize = channelSize * total_chans;
|
||||
cmsUInt32Number extra = T_EXTRA(Format);
|
||||
cmsUInt32Number nchannels = T_CHANNELS(Format);
|
||||
cmsUInt32Number total_chans = nchannels + extra;
|
||||
cmsUInt32Number i;
|
||||
cmsUInt32Number channelSize = trueBytesSize(Format);
|
||||
cmsUInt32Number pixelSize = channelSize * total_chans;
|
||||
|
||||
// Sanity check
|
||||
if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS)
|
||||
@ -368,11 +409,11 @@ void ComputeIncrementsForPlanar(cmsUInt32Number Format,
|
||||
cmsUInt32Number ComponentPointerIncrements[])
|
||||
{
|
||||
cmsUInt32Number channels[cmsMAXCHANNELS];
|
||||
int extra = T_EXTRA(Format);
|
||||
int nchannels = T_CHANNELS(Format);
|
||||
int total_chans = nchannels + extra;
|
||||
int i;
|
||||
int channelSize = trueBytesSize(Format);
|
||||
cmsUInt32Number extra = T_EXTRA(Format);
|
||||
cmsUInt32Number nchannels = T_CHANNELS(Format);
|
||||
cmsUInt32Number total_chans = nchannels + extra;
|
||||
cmsUInt32Number i;
|
||||
cmsUInt32Number channelSize = trueBytesSize(Format);
|
||||
|
||||
// Sanity check
|
||||
if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS)
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
@ -176,23 +176,24 @@ typedef struct {
|
||||
SUBALLOCATOR Allocator; // String suballocator -- just to keep it fast
|
||||
|
||||
// Parser state machine
|
||||
SYMBOL sy; // Current symbol
|
||||
int ch; // Current character
|
||||
SYMBOL sy; // Current symbol
|
||||
int ch; // Current character
|
||||
|
||||
cmsInt32Number inum; // integer value
|
||||
cmsFloat64Number dnum; // real value
|
||||
|
||||
int inum; // integer value
|
||||
cmsFloat64Number dnum; // real value
|
||||
char id[MAXID]; // identifier
|
||||
char str[MAXSTR]; // string
|
||||
|
||||
// Allowed keywords & datasets. They have visibility on whole stream
|
||||
KEYVALUE* ValidKeywords;
|
||||
KEYVALUE* ValidSampleID;
|
||||
KEYVALUE* ValidKeywords;
|
||||
KEYVALUE* ValidSampleID;
|
||||
|
||||
char* Source; // Points to loc. being parsed
|
||||
int lineno; // line counter for error reporting
|
||||
cmsInt32Number lineno; // line counter for error reporting
|
||||
|
||||
FILECTX* FileStack[MAXINCLUDE]; // Stack of files being parsed
|
||||
int IncludeSP; // Include Stack Pointer
|
||||
cmsInt32Number IncludeSP; // Include Stack Pointer
|
||||
|
||||
char* MemoryBlock; // The stream if holded in memory
|
||||
|
||||
@ -265,65 +266,64 @@ static PROPERTY PredefinedProperties[] = {
|
||||
{"PROD_DATE", WRITE_STRINGIFY}, // Identifies year and month of production of the target in the form yyyy:mm.
|
||||
{"SERIAL", WRITE_STRINGIFY}, // Uniquely identifies individual physical target.
|
||||
|
||||
{"MATERIAL", WRITE_STRINGIFY}, // Identifies the material on which the target was produced using a code
|
||||
// uniquely identifying th e material. This is intend ed to be used for IT8.7
|
||||
// physical targets only (i.e . IT8.7/1 a nd IT8.7/2).
|
||||
{"MATERIAL", WRITE_STRINGIFY}, // Identifies the material on which the target was produced using a code
|
||||
// uniquely identifying th e material. This is intend ed to be used for IT8.7
|
||||
// physical targets only (i.e . IT8.7/1 a nd IT8.7/2).
|
||||
|
||||
{"INSTRUMENTATION", WRITE_STRINGIFY}, // Used to report the specific instrumentation used (manufacturer and
|
||||
// model number) to generate the data reported. This data will often
|
||||
// provide more information about the particular data collected than an
|
||||
// extensive list of specific details. This is particularly important for
|
||||
// spectral data or data derived from spectrophotometry.
|
||||
{"INSTRUMENTATION", WRITE_STRINGIFY}, // Used to report the specific instrumentation used (manufacturer and
|
||||
// model number) to generate the data reported. This data will often
|
||||
// provide more information about the particular data collected than an
|
||||
// extensive list of specific details. This is particularly important for
|
||||
// spectral data or data derived from spectrophotometry.
|
||||
|
||||
{"MEASUREMENT_SOURCE", WRITE_STRINGIFY}, // Illumination used for spectral measurements. This data helps provide
|
||||
// a guide to the potential for issues of paper fluorescence, etc.
|
||||
{"MEASUREMENT_SOURCE", WRITE_STRINGIFY}, // Illumination used for spectral measurements. This data helps provide
|
||||
// a guide to the potential for issues of paper fluorescence, etc.
|
||||
|
||||
{"PRINT_CONDITIONS", WRITE_STRINGIFY}, // Used to define the characteristics of the printed sheet being reported.
|
||||
// Where standard conditions have been defined (e.g., SWOP at nominal)
|
||||
// named conditions may suffice. Otherwise, detailed information is
|
||||
// needed.
|
||||
{"PRINT_CONDITIONS", WRITE_STRINGIFY}, // Used to define the characteristics of the printed sheet being reported.
|
||||
// Where standard conditions have been defined (e.g., SWOP at nominal)
|
||||
// named conditions may suffice. Otherwise, detailed information is
|
||||
// needed.
|
||||
|
||||
{"SAMPLE_BACKING", WRITE_STRINGIFY}, // Identifies the backing material used behind the sample during
|
||||
// measurement. Allowed values are “black”, “white”, or {"na".
|
||||
{"SAMPLE_BACKING", WRITE_STRINGIFY}, // Identifies the backing material used behind the sample during
|
||||
// measurement. Allowed values are “black”, “white”, or {"na".
|
||||
|
||||
{"CHISQ_DOF", WRITE_STRINGIFY}, // Degrees of freedom associated with the Chi squared statistic
|
||||
|
||||
// below properties are new in recent specs:
|
||||
{"CHISQ_DOF", WRITE_STRINGIFY}, // Degrees of freedom associated with the Chi squared statistic
|
||||
// below properties are new in recent specs:
|
||||
|
||||
{"MEASUREMENT_GEOMETRY", WRITE_STRINGIFY}, // The type of measurement, either reflection or transmission, should be indicated
|
||||
// along with details of the geometry and the aperture size and shape. For example,
|
||||
// for transmission measurements it is important to identify 0/diffuse, diffuse/0,
|
||||
// opal or integrating sphere, etc. For reflection it is important to identify 0/45,
|
||||
// 45/0, sphere (specular included or excluded), etc.
|
||||
// along with details of the geometry and the aperture size and shape. For example,
|
||||
// for transmission measurements it is important to identify 0/diffuse, diffuse/0,
|
||||
// opal or integrating sphere, etc. For reflection it is important to identify 0/45,
|
||||
// 45/0, sphere (specular included or excluded), etc.
|
||||
|
||||
{"FILTER", WRITE_STRINGIFY}, // Identifies the use of physical filter(s) during measurement. Typically used to
|
||||
// denote the use of filters such as none, D65, Red, Green or Blue.
|
||||
{"FILTER", WRITE_STRINGIFY}, // Identifies the use of physical filter(s) during measurement. Typically used to
|
||||
// denote the use of filters such as none, D65, Red, Green or Blue.
|
||||
|
||||
{"POLARIZATION", WRITE_STRINGIFY}, // Identifies the use of a physical polarization filter during measurement. Allowed
|
||||
// values are {"yes”, “white”, “none” or “na”.
|
||||
{"POLARIZATION", WRITE_STRINGIFY}, // Identifies the use of a physical polarization filter during measurement. Allowed
|
||||
// values are {"yes”, “white”, “none” or “na”.
|
||||
|
||||
{"WEIGHTING_FUNCTION", WRITE_PAIR}, // Indicates such functions as: the CIE standard observer functions used in the
|
||||
// calculation of various data parameters (2 degree and 10 degree), CIE standard
|
||||
// illuminant functions used in the calculation of various data parameters (e.g., D50,
|
||||
// D65, etc.), density status response, etc. If used there shall be at least one
|
||||
// name-value pair following the WEIGHTING_FUNCTION tag/keyword. The first attribute
|
||||
// in the set shall be {"name" and shall identify the particular parameter used.
|
||||
// The second shall be {"value" and shall provide the value associated with that name.
|
||||
// For ASCII data, a string containing the Name and Value attribute pairs shall follow
|
||||
// the weighting function keyword. A semi-colon separates attribute pairs from each
|
||||
// other and within the attribute the name and value are separated by a comma.
|
||||
{"WEIGHTING_FUNCTION", WRITE_PAIR}, // Indicates such functions as: the CIE standard observer functions used in the
|
||||
// calculation of various data parameters (2 degree and 10 degree), CIE standard
|
||||
// illuminant functions used in the calculation of various data parameters (e.g., D50,
|
||||
// D65, etc.), density status response, etc. If used there shall be at least one
|
||||
// name-value pair following the WEIGHTING_FUNCTION tag/keyword. The first attribute
|
||||
// in the set shall be {"name" and shall identify the particular parameter used.
|
||||
// The second shall be {"value" and shall provide the value associated with that name.
|
||||
// For ASCII data, a string containing the Name and Value attribute pairs shall follow
|
||||
// the weighting function keyword. A semi-colon separates attribute pairs from each
|
||||
// other and within the attribute the name and value are separated by a comma.
|
||||
|
||||
{"COMPUTATIONAL_PARAMETER", WRITE_PAIR}, // Parameter that is used in computing a value from measured data. Name is the name
|
||||
// of the calculation, parameter is the name of the parameter used in the calculation
|
||||
// and value is the value of the parameter.
|
||||
{"COMPUTATIONAL_PARAMETER", WRITE_PAIR}, // Parameter that is used in computing a value from measured data. Name is the name
|
||||
// of the calculation, parameter is the name of the parameter used in the calculation
|
||||
// and value is the value of the parameter.
|
||||
|
||||
{"TARGET_TYPE", WRITE_STRINGIFY}, // The type of target being measured, e.g. IT8.7/1, IT8.7/3, user defined, etc.
|
||||
{"TARGET_TYPE", WRITE_STRINGIFY}, // The type of target being measured, e.g. IT8.7/1, IT8.7/3, user defined, etc.
|
||||
|
||||
{"COLORANT", WRITE_STRINGIFY}, // Identifies the colorant(s) used in creating the target.
|
||||
{"COLORANT", WRITE_STRINGIFY}, // Identifies the colorant(s) used in creating the target.
|
||||
|
||||
{"TABLE_DESCRIPTOR", WRITE_STRINGIFY}, // Describes the purpose or contents of a data table.
|
||||
{"TABLE_DESCRIPTOR", WRITE_STRINGIFY}, // Describes the purpose or contents of a data table.
|
||||
|
||||
{"TABLE_NAME", WRITE_STRINGIFY} // Provides a short name for a data table.
|
||||
{"TABLE_NAME", WRITE_STRINGIFY} // Provides a short name for a data table.
|
||||
};
|
||||
|
||||
#define NUMPREDEFINEDPROPS (sizeof(PredefinedProperties)/sizeof(PROPERTY))
|
||||
@ -564,13 +564,13 @@ cmsFloat64Number xpow10(int n)
|
||||
|
||||
// Reads a Real number, tries to follow from integer number
|
||||
static
|
||||
void ReadReal(cmsIT8* it8, int inum)
|
||||
void ReadReal(cmsIT8* it8, cmsInt32Number inum)
|
||||
{
|
||||
it8->dnum = (cmsFloat64Number) inum;
|
||||
it8->dnum = (cmsFloat64Number)inum;
|
||||
|
||||
while (isdigit(it8->ch)) {
|
||||
|
||||
it8->dnum = it8->dnum * 10.0 + (it8->ch - '0');
|
||||
it8->dnum = (cmsFloat64Number)it8->dnum * 10.0 + (cmsFloat64Number)(it8->ch - '0');
|
||||
NextCh(it8);
|
||||
}
|
||||
|
||||
@ -583,7 +583,7 @@ void ReadReal(cmsIT8* it8, int inum)
|
||||
|
||||
while (isdigit(it8->ch)) {
|
||||
|
||||
frac = frac * 10.0 + (it8->ch - '0');
|
||||
frac = frac * 10.0 + (cmsFloat64Number)(it8->ch - '0');
|
||||
prec++;
|
||||
NextCh(it8);
|
||||
}
|
||||
@ -594,8 +594,8 @@ void ReadReal(cmsIT8* it8, int inum)
|
||||
// Exponent, example 34.00E+20
|
||||
if (toupper(it8->ch) == 'E') {
|
||||
|
||||
int e;
|
||||
int sgn;
|
||||
cmsInt32Number e;
|
||||
cmsInt32Number sgn;
|
||||
|
||||
NextCh(it8); sgn = 1;
|
||||
|
||||
@ -610,17 +610,19 @@ void ReadReal(cmsIT8* it8, int inum)
|
||||
NextCh(it8);
|
||||
}
|
||||
|
||||
e = 0;
|
||||
while (isdigit(it8->ch)) {
|
||||
e = 0;
|
||||
while (isdigit(it8->ch)) {
|
||||
|
||||
if ((cmsFloat64Number) e * 10L < INT_MAX)
|
||||
e = e * 10 + (it8->ch - '0');
|
||||
cmsInt32Number digit = (it8->ch - '0');
|
||||
|
||||
NextCh(it8);
|
||||
}
|
||||
if ((cmsFloat64Number)e * 10.0 + (cmsFloat64Number)digit < (cmsFloat64Number)+2147483647.0)
|
||||
e = e * 10 + digit;
|
||||
|
||||
e = sgn*e;
|
||||
it8 -> dnum = it8 -> dnum * xpow10(e);
|
||||
NextCh(it8);
|
||||
}
|
||||
|
||||
e = sgn*e;
|
||||
it8->dnum = it8->dnum * xpow10(e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -638,12 +640,12 @@ cmsFloat64Number ParseFloatNumber(const char *Buffer)
|
||||
|
||||
if (*Buffer == '-' || *Buffer == '+') {
|
||||
|
||||
sign = (*Buffer == '-') ? -1 : 1;
|
||||
Buffer++;
|
||||
sign = (*Buffer == '-') ? -1 : 1;
|
||||
Buffer++;
|
||||
}
|
||||
|
||||
|
||||
while (*Buffer && isdigit((int) *Buffer)) {
|
||||
while (*Buffer && isdigit((int)*Buffer)) {
|
||||
|
||||
dnum = dnum * 10.0 + (*Buffer - '0');
|
||||
if (*Buffer) Buffer++;
|
||||
@ -652,11 +654,11 @@ cmsFloat64Number ParseFloatNumber(const char *Buffer)
|
||||
if (*Buffer == '.') {
|
||||
|
||||
cmsFloat64Number frac = 0.0; // fraction
|
||||
int prec = 0; // precission
|
||||
int prec = 0; // precision
|
||||
|
||||
if (*Buffer) Buffer++;
|
||||
|
||||
while (*Buffer && isdigit((int) *Buffer)) {
|
||||
while (*Buffer && isdigit((int)*Buffer)) {
|
||||
|
||||
frac = frac * 10.0 + (*Buffer - '0');
|
||||
prec++;
|
||||
@ -687,17 +689,19 @@ cmsFloat64Number ParseFloatNumber(const char *Buffer)
|
||||
if (*Buffer) Buffer++;
|
||||
}
|
||||
|
||||
e = 0;
|
||||
while (*Buffer && isdigit((int) *Buffer)) {
|
||||
e = 0;
|
||||
while (*Buffer && isdigit((int)*Buffer)) {
|
||||
|
||||
if ((cmsFloat64Number) e * 10L < INT_MAX)
|
||||
e = e * 10 + (*Buffer - '0');
|
||||
cmsInt32Number digit = (*Buffer - '0');
|
||||
|
||||
if (*Buffer) Buffer++;
|
||||
}
|
||||
if ((cmsFloat64Number)e * 10.0 + digit < (cmsFloat64Number)+2147483647.0)
|
||||
e = e * 10 + digit;
|
||||
|
||||
e = sgn*e;
|
||||
dnum = dnum * xpow10(e);
|
||||
if (*Buffer) Buffer++;
|
||||
}
|
||||
|
||||
e = sgn*e;
|
||||
dnum = dnum * xpow10(e);
|
||||
}
|
||||
|
||||
return sign * dnum;
|
||||
@ -766,7 +770,7 @@ void InSymbol(cmsIT8* it8)
|
||||
if (it8->ch >= 'A' && it8->ch <= 'F') j = it8->ch -'A'+10;
|
||||
else j = it8->ch - '0';
|
||||
|
||||
if ((long) it8->inum * 16L > (long) INT_MAX)
|
||||
if ((cmsFloat64Number) it8->inum * 16.0 + (cmsFloat64Number) j > (cmsFloat64Number)+2147483647.0)
|
||||
{
|
||||
SynError(it8, "Invalid hexadecimal number");
|
||||
return;
|
||||
@ -787,7 +791,7 @@ void InSymbol(cmsIT8* it8)
|
||||
{
|
||||
j = it8->ch - '0';
|
||||
|
||||
if ((long) it8->inum * 2L > (long) INT_MAX)
|
||||
if ((cmsFloat64Number) it8->inum * 2.0 + j > (cmsFloat64Number)+2147483647.0)
|
||||
{
|
||||
SynError(it8, "Invalid binary number");
|
||||
return;
|
||||
@ -803,14 +807,16 @@ void InSymbol(cmsIT8* it8)
|
||||
|
||||
while (isdigit(it8->ch)) {
|
||||
|
||||
if ((long) it8->inum * 10L > (long) INT_MAX) {
|
||||
cmsInt32Number digit = (it8->ch - '0');
|
||||
|
||||
if ((cmsFloat64Number) it8->inum * 10.0 + (cmsFloat64Number) digit > (cmsFloat64Number) +2147483647.0) {
|
||||
ReadReal(it8, it8->inum);
|
||||
it8->sy = SDNUM;
|
||||
it8->dnum *= sign;
|
||||
return;
|
||||
}
|
||||
|
||||
it8->inum = it8->inum * 10 + (it8->ch - '0');
|
||||
it8->inum = it8->inum * 10 + digit;
|
||||
NextCh(it8);
|
||||
}
|
||||
|
||||
@ -1515,8 +1521,8 @@ cmsBool SetDataFormat(cmsIT8* it8, int n, const char *label)
|
||||
|
||||
cmsBool CMSEXPORT cmsIT8SetDataFormat(cmsHANDLE h, int n, const char *Sample)
|
||||
{
|
||||
cmsIT8* it8 = (cmsIT8*) h;
|
||||
return SetDataFormat(it8, n, Sample);
|
||||
cmsIT8* it8 = (cmsIT8*)h;
|
||||
return SetDataFormat(it8, n, Sample);
|
||||
}
|
||||
|
||||
static
|
||||
@ -1541,8 +1547,8 @@ static
|
||||
char* GetData(cmsIT8* it8, int nSet, int nField)
|
||||
{
|
||||
TABLE* t = GetTable(it8);
|
||||
int nSamples = t -> nSamples;
|
||||
int nPatches = t -> nPatches;
|
||||
int nSamples = t -> nSamples;
|
||||
int nPatches = t -> nPatches;
|
||||
|
||||
if (nSet >= nPatches || nField >= nSamples)
|
||||
return NULL;
|
||||
@ -1973,67 +1979,67 @@ cmsBool HeaderSection(cmsIT8* it8)
|
||||
|
||||
|
||||
case SIDENT:
|
||||
strncpy(VarName, it8->id, MAXID-1);
|
||||
VarName[MAXID-1] = 0;
|
||||
strncpy(VarName, it8->id, MAXID - 1);
|
||||
VarName[MAXID - 1] = 0;
|
||||
|
||||
if (!IsAvailableOnList(it8-> ValidKeywords, VarName, NULL, &Key)) {
|
||||
if (!IsAvailableOnList(it8->ValidKeywords, VarName, NULL, &Key)) {
|
||||
|
||||
#ifdef CMS_STRICT_CGATS
|
||||
return SynError(it8, "Undefined keyword '%s'", VarName);
|
||||
return SynError(it8, "Undefined keyword '%s'", VarName);
|
||||
#else
|
||||
Key = AddAvailableProperty(it8, VarName, WRITE_UNCOOKED);
|
||||
if (Key == NULL) return FALSE;
|
||||
Key = AddAvailableProperty(it8, VarName, WRITE_UNCOOKED);
|
||||
if (Key == NULL) return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
InSymbol(it8);
|
||||
if (!GetVal(it8, Buffer, MAXSTR - 1, "Property data expected")) return FALSE;
|
||||
|
||||
if (Key->WriteAs != WRITE_PAIR) {
|
||||
AddToList(it8, &GetTable(it8)->HeaderList, VarName, NULL, Buffer,
|
||||
(it8->sy == SSTRING) ? WRITE_STRINGIFY : WRITE_UNCOOKED);
|
||||
}
|
||||
else {
|
||||
const char *Subkey;
|
||||
char *Nextkey;
|
||||
if (it8->sy != SSTRING)
|
||||
return SynError(it8, "Invalid value '%s' for property '%s'.", Buffer, VarName);
|
||||
|
||||
// chop the string as a list of "subkey, value" pairs, using ';' as a separator
|
||||
for (Subkey = Buffer; Subkey != NULL; Subkey = Nextkey)
|
||||
{
|
||||
char *Value, *temp;
|
||||
|
||||
// identify token pair boundary
|
||||
Nextkey = (char*)strchr(Subkey, ';');
|
||||
if (Nextkey)
|
||||
*Nextkey++ = '\0';
|
||||
|
||||
// for each pair, split the subkey and the value
|
||||
Value = (char*)strrchr(Subkey, ',');
|
||||
if (Value == NULL)
|
||||
return SynError(it8, "Invalid value for property '%s'.", VarName);
|
||||
|
||||
// gobble the spaces before the coma, and the coma itself
|
||||
temp = Value++;
|
||||
do *temp-- = '\0'; while (temp >= Subkey && *temp == ' ');
|
||||
|
||||
// gobble any space at the right
|
||||
temp = Value + strlen(Value) - 1;
|
||||
while (*temp == ' ') *temp-- = '\0';
|
||||
|
||||
// trim the strings from the left
|
||||
Subkey += strspn(Subkey, " ");
|
||||
Value += strspn(Value, " ");
|
||||
|
||||
if (Subkey[0] == 0 || Value[0] == 0)
|
||||
return SynError(it8, "Invalid value for property '%s'.", VarName);
|
||||
AddToList(it8, &GetTable(it8)->HeaderList, VarName, Subkey, Value, WRITE_PAIR);
|
||||
}
|
||||
}
|
||||
|
||||
InSymbol(it8);
|
||||
if (!GetVal(it8, Buffer, MAXSTR-1, "Property data expected")) return FALSE;
|
||||
|
||||
if(Key->WriteAs != WRITE_PAIR) {
|
||||
AddToList(it8, &GetTable(it8)->HeaderList, VarName, NULL, Buffer,
|
||||
(it8->sy == SSTRING) ? WRITE_STRINGIFY : WRITE_UNCOOKED);
|
||||
}
|
||||
else {
|
||||
const char *Subkey;
|
||||
char *Nextkey;
|
||||
if (it8->sy != SSTRING)
|
||||
return SynError(it8, "Invalid value '%s' for property '%s'.", Buffer, VarName);
|
||||
|
||||
// chop the string as a list of "subkey, value" pairs, using ';' as a separator
|
||||
for (Subkey = Buffer; Subkey != NULL; Subkey = Nextkey)
|
||||
{
|
||||
char *Value, *temp;
|
||||
|
||||
// identify token pair boundary
|
||||
Nextkey = (char*) strchr(Subkey, ';');
|
||||
if(Nextkey)
|
||||
*Nextkey++ = '\0';
|
||||
|
||||
// for each pair, split the subkey and the value
|
||||
Value = (char*) strrchr(Subkey, ',');
|
||||
if(Value == NULL)
|
||||
return SynError(it8, "Invalid value for property '%s'.", VarName);
|
||||
|
||||
// gobble the spaces before the coma, and the coma itself
|
||||
temp = Value++;
|
||||
do *temp-- = '\0'; while(temp >= Subkey && *temp == ' ');
|
||||
|
||||
// gobble any space at the right
|
||||
temp = Value + strlen(Value) - 1;
|
||||
while(*temp == ' ') *temp-- = '\0';
|
||||
|
||||
// trim the strings from the left
|
||||
Subkey += strspn(Subkey, " ");
|
||||
Value += strspn(Value, " ");
|
||||
|
||||
if(Subkey[0] == 0 || Value[0] == 0)
|
||||
return SynError(it8, "Invalid value for property '%s'.", VarName);
|
||||
AddToList(it8, &GetTable(it8)->HeaderList, VarName, Subkey, Value, WRITE_PAIR);
|
||||
}
|
||||
}
|
||||
|
||||
InSymbol(it8);
|
||||
break;
|
||||
InSymbol(it8);
|
||||
break;
|
||||
|
||||
|
||||
case SEOLN: break;
|
||||
@ -2062,7 +2068,6 @@ void ReadType(cmsIT8* it8, char* SheetTypePtr)
|
||||
|
||||
while (it8->ch != '\r' && it8 ->ch != '\n' && it8->ch != '\t' && it8 -> ch != 0) {
|
||||
|
||||
*SheetTypePtr++= (char) it8 ->ch;
|
||||
if (cnt++ < MAXSTR)
|
||||
*SheetTypePtr++= (char) it8 ->ch;
|
||||
NextCh(it8);
|
||||
@ -2257,10 +2262,10 @@ void CookPointers(cmsIT8* it8)
|
||||
// that should be something like some printable characters plus a \n
|
||||
// returns 0 if this is not like a CGATS, or an integer otherwise. This integer is the number of words in first line?
|
||||
static
|
||||
int IsMyBlock(const cmsUInt8Number* Buffer, int n)
|
||||
int IsMyBlock(const cmsUInt8Number* Buffer, cmsUInt32Number n)
|
||||
{
|
||||
int words = 1, space = 0, quot = 0;
|
||||
int i;
|
||||
cmsUInt32Number i;
|
||||
|
||||
if (n < 10) return 0; // Too small
|
||||
|
||||
@ -2748,7 +2753,7 @@ int CMSEXPORT cmsIT8SetTableByLabel(cmsHANDLE hIT8, const char* cSet, const char
|
||||
{
|
||||
const char* cLabelFld;
|
||||
char Type[256], Label[256];
|
||||
int nTable;
|
||||
cmsUInt32Number nTable;
|
||||
|
||||
_cmsAssert(hIT8 != NULL);
|
||||
|
||||
@ -2761,7 +2766,7 @@ int CMSEXPORT cmsIT8SetTableByLabel(cmsHANDLE hIT8, const char* cSet, const char
|
||||
cLabelFld = cmsIT8GetData(hIT8, cSet, cField);
|
||||
if (!cLabelFld) return -1;
|
||||
|
||||
if (sscanf(cLabelFld, "%255s %d %255s", Label, &nTable, Type) != 3)
|
||||
if (sscanf(cLabelFld, "%255s %u %255s", Label, &nTable, Type) != 3)
|
||||
return -1;
|
||||
|
||||
if (ExpectedType != NULL && *ExpectedType == 0)
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
@ -392,11 +392,12 @@ cmsBool IsEmptyLayer(cmsMAT3* m, cmsVEC3* off)
|
||||
|
||||
// Compute the conversion layer
|
||||
static
|
||||
cmsBool ComputeConversion(int i, cmsHPROFILE hProfiles[],
|
||||
cmsUInt32Number Intent,
|
||||
cmsBool BPC,
|
||||
cmsFloat64Number AdaptationState,
|
||||
cmsMAT3* m, cmsVEC3* off)
|
||||
cmsBool ComputeConversion(cmsUInt32Number i,
|
||||
cmsHPROFILE hProfiles[],
|
||||
cmsUInt32Number Intent,
|
||||
cmsBool BPC,
|
||||
cmsFloat64Number AdaptationState,
|
||||
cmsMAT3* m, cmsVEC3* off)
|
||||
{
|
||||
|
||||
int k;
|
||||
@ -708,7 +709,7 @@ cmsPipeline* CMSEXPORT _cmsDefaultICCintents(cmsContext ContextID,
|
||||
|
||||
// Translate black-preserving intents to ICC ones
|
||||
static
|
||||
int TranslateNonICCIntents(int Intent)
|
||||
cmsUInt32Number TranslateNonICCIntents(cmsUInt32Number Intent)
|
||||
{
|
||||
switch (Intent) {
|
||||
case INTENT_PRESERVE_K_ONLY_PERCEPTUAL:
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
@ -83,9 +83,11 @@ long int CMSEXPORT cmsfilelength(FILE* f)
|
||||
long int p , n;
|
||||
|
||||
p = ftell(f); // register current file position
|
||||
if (p == -1L)
|
||||
return -1L;
|
||||
|
||||
if (fseek(f, 0, SEEK_END) != 0) {
|
||||
return -1;
|
||||
return -1L;
|
||||
}
|
||||
|
||||
n = ftell(f);
|
||||
@ -115,7 +117,7 @@ cmsBool _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plug
|
||||
// *********************************************************************************
|
||||
|
||||
// This is the default memory allocation function. It does a very coarse
|
||||
// check of amout of memory, just to prevent exploits
|
||||
// check of amount of memory, just to prevent exploits
|
||||
static
|
||||
void* _cmsMallocDefaultFn(cmsContext ContextID, cmsUInt32Number size)
|
||||
{
|
||||
@ -222,7 +224,7 @@ void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx, const struct _cmsCo
|
||||
}
|
||||
else {
|
||||
|
||||
// To reset it, we use the default allocators, which cannot be overriden
|
||||
// To reset it, we use the default allocators, which cannot be overridden
|
||||
ctx ->chunks[MemPlugin] = &ctx ->DefaultMemoryManager;
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,10 +73,11 @@
|
||||
// The list of supported parametric curves
|
||||
typedef struct _cmsParametricCurvesCollection_st {
|
||||
|
||||
int nFunctions; // Number of supported functions in this chunk
|
||||
int FunctionTypes[MAX_TYPES_IN_LCMS_PLUGIN]; // The identification types
|
||||
int ParameterCount[MAX_TYPES_IN_LCMS_PLUGIN]; // Number of parameters for each function
|
||||
cmsParametricCurveEvaluator Evaluator; // The evaluator
|
||||
cmsUInt32Number nFunctions; // Number of supported functions in this chunk
|
||||
cmsInt32Number FunctionTypes[MAX_TYPES_IN_LCMS_PLUGIN]; // The identification types
|
||||
cmsUInt32Number ParameterCount[MAX_TYPES_IN_LCMS_PLUGIN]; // Number of parameters for each function
|
||||
|
||||
cmsParametricCurveEvaluator Evaluator; // The evaluator
|
||||
|
||||
struct _cmsParametricCurvesCollection_st* Next; // Next in list
|
||||
|
||||
@ -194,7 +195,7 @@ int IsInSet(int Type, _cmsParametricCurvesCollection* c)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < c ->nFunctions; i++)
|
||||
for (i=0; i < (int) c ->nFunctions; i++)
|
||||
if (abs(Type) == c ->FunctionTypes[i]) return i;
|
||||
|
||||
return -1;
|
||||
@ -238,20 +239,20 @@ _cmsParametricCurvesCollection *GetParametricCurveByType(cmsContext ContextID, i
|
||||
// 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, cmsUInt32Number nEntries,
|
||||
cmsUInt32Number nSegments, const cmsCurveSegment* Segments,
|
||||
const cmsUInt16Number* Values)
|
||||
{
|
||||
cmsToneCurve* p;
|
||||
int i;
|
||||
cmsUInt32Number i;
|
||||
|
||||
// We allow huge tables, which are then restricted for smoothing operations
|
||||
if (nEntries > 65530 || nEntries < 0) {
|
||||
if (nEntries > 65530) {
|
||||
cmsSignalError(ContextID, cmsERROR_RANGE, "Couldn't create tone curve of more than 65530 entries");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (nEntries <= 0 && nSegments <= 0) {
|
||||
if (nEntries == 0 && nSegments == 0) {
|
||||
cmsSignalError(ContextID, cmsERROR_RANGE, "Couldn't create tone curve with zero segments and no table");
|
||||
return NULL;
|
||||
}
|
||||
@ -261,7 +262,7 @@ cmsToneCurve* AllocateToneCurveStruct(cmsContext ContextID, cmsInt32Number nEntr
|
||||
if (!p) return NULL;
|
||||
|
||||
// In this case, there are no segments
|
||||
if (nSegments <= 0) {
|
||||
if (nSegments == 0) {
|
||||
p ->Segments = NULL;
|
||||
p ->Evals = NULL;
|
||||
}
|
||||
@ -277,7 +278,7 @@ cmsToneCurve* AllocateToneCurveStruct(cmsContext ContextID, cmsInt32Number nEntr
|
||||
|
||||
// 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) {
|
||||
if (nEntries == 0) {
|
||||
p ->Table16 = NULL;
|
||||
}
|
||||
else {
|
||||
@ -303,7 +304,7 @@ cmsToneCurve* AllocateToneCurveStruct(cmsContext ContextID, cmsInt32Number nEntr
|
||||
p ->SegInterp = (cmsInterpParams**) _cmsCalloc(ContextID, nSegments, sizeof(cmsInterpParams*));
|
||||
if (p ->SegInterp == NULL) goto Error;
|
||||
|
||||
for (i=0; i< nSegments; i++) {
|
||||
for (i=0; i < nSegments; i++) {
|
||||
|
||||
// Type 0 is a special marker for table-based curves
|
||||
if (Segments[i].Type == 0)
|
||||
@ -359,7 +360,7 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
|
||||
|
||||
// Type 1 Reversed: X = Y ^1/gamma
|
||||
case -1:
|
||||
if (R < 0) {
|
||||
if (R < 0) {
|
||||
|
||||
if (fabs(Params[0] - 1.0) < MATRIX_DET_TOLERANCE)
|
||||
Val = R;
|
||||
@ -367,80 +368,123 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
|
||||
Val = 0;
|
||||
}
|
||||
else
|
||||
Val = pow(R, 1/Params[0]);
|
||||
{
|
||||
if (fabs(Params[0]) < MATRIX_DET_TOLERANCE)
|
||||
Val = PLUS_INF;
|
||||
else
|
||||
Val = pow(R, 1 / Params[0]);
|
||||
}
|
||||
break;
|
||||
|
||||
// CIE 122-1966
|
||||
// Y = (aX + b)^Gamma | X >= -b/a
|
||||
// Y = 0 | else
|
||||
case 2:
|
||||
disc = -Params[2] / Params[1];
|
||||
{
|
||||
|
||||
if (R >= disc ) {
|
||||
if (fabs(Params[1]) < MATRIX_DET_TOLERANCE)
|
||||
{
|
||||
Val = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
disc = -Params[2] / Params[1];
|
||||
|
||||
e = Params[1]*R + Params[2];
|
||||
if (R >= disc) {
|
||||
|
||||
if (e > 0)
|
||||
Val = pow(e, Params[0]);
|
||||
e = Params[1] * R + Params[2];
|
||||
|
||||
if (e > 0)
|
||||
Val = pow(e, Params[0]);
|
||||
else
|
||||
Val = 0;
|
||||
}
|
||||
else
|
||||
Val = 0;
|
||||
}
|
||||
else
|
||||
Val = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
// Type 2 Reversed
|
||||
// X = (Y ^1/g - b) / a
|
||||
case -2:
|
||||
if (R < 0)
|
||||
{
|
||||
if (fabs(Params[0]) < MATRIX_DET_TOLERANCE ||
|
||||
fabs(Params[1]) < MATRIX_DET_TOLERANCE)
|
||||
{
|
||||
Val = 0;
|
||||
}
|
||||
else
|
||||
Val = (pow(R, 1.0/Params[0]) - Params[2]) / Params[1];
|
||||
{
|
||||
if (R < 0)
|
||||
Val = 0;
|
||||
else
|
||||
Val = (pow(R, 1.0 / Params[0]) - Params[2]) / Params[1];
|
||||
|
||||
if (Val < 0)
|
||||
Val = 0;
|
||||
break;
|
||||
if (Val < 0)
|
||||
Val = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
// IEC 61966-3
|
||||
// Y = (aX + b)^Gamma | X <= -b/a
|
||||
// Y = c | else
|
||||
case 3:
|
||||
disc = -Params[2] / Params[1];
|
||||
if (disc < 0)
|
||||
disc = 0;
|
||||
|
||||
if (R >= disc) {
|
||||
|
||||
e = Params[1]*R + Params[2];
|
||||
|
||||
if (e > 0)
|
||||
Val = pow(e, Params[0]) + Params[3];
|
||||
else
|
||||
Val = 0;
|
||||
{
|
||||
if (fabs(Params[1]) < MATRIX_DET_TOLERANCE)
|
||||
{
|
||||
Val = 0;
|
||||
}
|
||||
else
|
||||
Val = Params[3];
|
||||
break;
|
||||
{
|
||||
disc = -Params[2] / Params[1];
|
||||
if (disc < 0)
|
||||
disc = 0;
|
||||
|
||||
if (R >= disc) {
|
||||
|
||||
e = Params[1] * R + Params[2];
|
||||
|
||||
if (e > 0)
|
||||
Val = pow(e, Params[0]) + Params[3];
|
||||
else
|
||||
Val = 0;
|
||||
}
|
||||
else
|
||||
Val = Params[3];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
// Type 3 reversed
|
||||
// X=((Y-c)^1/g - 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
|
||||
Val = 0;
|
||||
{
|
||||
if (fabs(Params[1]) < MATRIX_DET_TOLERANCE)
|
||||
{
|
||||
Val = 0;
|
||||
}
|
||||
else {
|
||||
Val = -Params[2] / Params[1];
|
||||
else
|
||||
{
|
||||
if (R >= Params[3]) {
|
||||
|
||||
e = R - Params[3];
|
||||
|
||||
if (e > 0)
|
||||
Val = (pow(e, 1 / Params[0]) - Params[2]) / Params[1];
|
||||
else
|
||||
Val = 0;
|
||||
}
|
||||
else {
|
||||
Val = -Params[2] / Params[1];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
// IEC 61966-2.1 (sRGB)
|
||||
@ -464,20 +508,31 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
|
||||
// X=((Y^1/g-b)/a) | Y >= (ad+b)^g
|
||||
// X=Y/c | Y< (ad+b)^g
|
||||
case -4:
|
||||
e = Params[1] * Params[4] + Params[2];
|
||||
if (e < 0)
|
||||
disc = 0;
|
||||
{
|
||||
if (fabs(Params[0]) < MATRIX_DET_TOLERANCE ||
|
||||
fabs(Params[1]) < MATRIX_DET_TOLERANCE ||
|
||||
fabs(Params[3]) < MATRIX_DET_TOLERANCE)
|
||||
{
|
||||
Val = 0;
|
||||
}
|
||||
else
|
||||
disc = pow(e, Params[0]);
|
||||
{
|
||||
e = Params[1] * Params[4] + Params[2];
|
||||
if (e < 0)
|
||||
disc = 0;
|
||||
else
|
||||
disc = pow(e, Params[0]);
|
||||
|
||||
if (R >= disc) {
|
||||
if (R >= disc) {
|
||||
|
||||
Val = (pow(R, 1.0/Params[0]) - Params[2]) / Params[1];
|
||||
Val = (pow(R, 1.0 / Params[0]) - Params[2]) / Params[1];
|
||||
}
|
||||
else {
|
||||
Val = R / Params[3];
|
||||
}
|
||||
}
|
||||
else {
|
||||
Val = R / Params[3];
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
// Y = (aX + b)^Gamma + e | X >= d
|
||||
@ -501,20 +556,29 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
|
||||
// X=((Y-e)1/g-b)/a | Y >=(ad+b)^g+e), cd+f
|
||||
// X=(Y-f)/c | else
|
||||
case -5:
|
||||
|
||||
disc = Params[3] * Params[4] + Params[6];
|
||||
if (R >= disc) {
|
||||
|
||||
e = R - Params[5];
|
||||
if (e < 0)
|
||||
Val = 0;
|
||||
else
|
||||
Val = (pow(e, 1.0/Params[0]) - Params[2]) / Params[1];
|
||||
{
|
||||
if (fabs(Params[1]) < MATRIX_DET_TOLERANCE ||
|
||||
fabs(Params[3]) < MATRIX_DET_TOLERANCE)
|
||||
{
|
||||
Val = 0;
|
||||
}
|
||||
else {
|
||||
Val = (R - Params[6]) / Params[3];
|
||||
else
|
||||
{
|
||||
disc = Params[3] * Params[4] + Params[6];
|
||||
if (R >= disc) {
|
||||
|
||||
e = R - Params[5];
|
||||
if (e < 0)
|
||||
Val = 0;
|
||||
else
|
||||
Val = (pow(e, 1.0 / Params[0]) - Params[2]) / Params[1];
|
||||
}
|
||||
else {
|
||||
Val = (R - Params[6]) / Params[3];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
// Types 6,7,8 comes from segmented curves as described in ICCSpecRevision_02_11_06_Float.pdf
|
||||
@ -532,12 +596,21 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
|
||||
|
||||
// ((Y - c) ^1/Gamma - b) / a
|
||||
case -6:
|
||||
e = R - Params[3];
|
||||
if (e < 0)
|
||||
{
|
||||
if (fabs(Params[1]) < MATRIX_DET_TOLERANCE)
|
||||
{
|
||||
Val = 0;
|
||||
}
|
||||
else
|
||||
Val = (pow(e, 1.0/Params[0]) - Params[2]) / Params[1];
|
||||
break;
|
||||
{
|
||||
e = R - Params[3];
|
||||
if (e < 0)
|
||||
Val = 0;
|
||||
else
|
||||
Val = (pow(e, 1.0 / Params[0]) - Params[2]) / Params[1];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
// Y = a * log (b * X^Gamma + c) + d
|
||||
@ -554,8 +627,19 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
|
||||
// pow(10, (Y-d) / a) = b * X ^Gamma + c
|
||||
// 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;
|
||||
{
|
||||
if (fabs(Params[0]) < MATRIX_DET_TOLERANCE ||
|
||||
fabs(Params[1]) < MATRIX_DET_TOLERANCE ||
|
||||
fabs(Params[2]) < MATRIX_DET_TOLERANCE)
|
||||
{
|
||||
Val = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
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
|
||||
@ -571,12 +655,25 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
|
||||
disc = R - Params[4];
|
||||
if (disc < 0) Val = 0;
|
||||
else
|
||||
Val = (log(disc / Params[0]) / log(Params[1]) - Params[3]) / Params[2];
|
||||
{
|
||||
if (fabs(Params[0]) < MATRIX_DET_TOLERANCE ||
|
||||
fabs(Params[2]) < MATRIX_DET_TOLERANCE)
|
||||
{
|
||||
Val = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Val = (log(disc / Params[0]) / log(Params[1]) - Params[3]) / Params[2];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// S-Shaped: (1 - (1-x)^1/g)^1/g
|
||||
case 108:
|
||||
Val = pow(1.0 - pow(1 - R, 1/Params[0]), 1/Params[0]);
|
||||
if (fabs(Params[0]) < MATRIX_DET_TOLERANCE)
|
||||
Val = 0;
|
||||
else
|
||||
Val = pow(1.0 - pow(1 - R, 1/Params[0]), 1/Params[0]);
|
||||
break;
|
||||
|
||||
// y = (1 - (1-x)^1/g)^1/g
|
||||
@ -596,33 +693,45 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
|
||||
return Val;
|
||||
}
|
||||
|
||||
// Evaluate a segmented function for a single value. Return -1 if no valid segment found .
|
||||
// Evaluate a segmented function for a single value. Return -Inf if no valid segment found .
|
||||
// If fn type is 0, perform an interpolation on the table
|
||||
static
|
||||
cmsFloat64Number EvalSegmentedFn(const cmsToneCurve *g, cmsFloat64Number R)
|
||||
{
|
||||
int i;
|
||||
cmsFloat32Number Out32;
|
||||
cmsFloat64Number Out;
|
||||
|
||||
for (i = g ->nSegments-1; i >= 0 ; --i) {
|
||||
for (i = (int) g->nSegments - 1; i >= 0; --i) {
|
||||
|
||||
// Check for domain
|
||||
if ((R > g ->Segments[i].x0) && (R <= g ->Segments[i].x1)) {
|
||||
if ((R > g->Segments[i].x0) && (R <= g->Segments[i].x1)) {
|
||||
|
||||
// Type == 0 means segment is sampled
|
||||
if (g ->Segments[i].Type == 0) {
|
||||
if (g->Segments[i].Type == 0) {
|
||||
|
||||
cmsFloat32Number R1 = (cmsFloat32Number) (R - g ->Segments[i].x0) / (g ->Segments[i].x1 - g ->Segments[i].x0);
|
||||
cmsFloat32Number Out;
|
||||
cmsFloat32Number R1 = (cmsFloat32Number)(R - g->Segments[i].x0) / (g->Segments[i].x1 - g->Segments[i].x0);
|
||||
|
||||
// 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]);
|
||||
g->SegInterp[i]->Interpolation.LerpFloat(&R1, &Out32, g->SegInterp[i]);
|
||||
Out = (cmsFloat64Number) Out32;
|
||||
|
||||
return Out;
|
||||
}
|
||||
else {
|
||||
Out = g->Evals[i](g->Segments[i].Type, g->Segments[i].Params, R);
|
||||
}
|
||||
|
||||
if (isinf(Out))
|
||||
return PLUS_INF;
|
||||
else
|
||||
return g ->Evals[i](g->Segments[i].Type, g ->Segments[i].Params, R);
|
||||
{
|
||||
if (isinf(-Out))
|
||||
return MINUS_INF;
|
||||
}
|
||||
|
||||
return Out;
|
||||
}
|
||||
}
|
||||
|
||||
@ -645,13 +754,13 @@ const cmsUInt16Number* CMSEXPORT cmsGetToneCurveEstimatedTable(const cmsToneCurv
|
||||
|
||||
// Create an empty gamma curve, by using tables. This specifies only the limited-precision part, and leaves the
|
||||
// floating point description empty.
|
||||
cmsToneCurve* CMSEXPORT cmsBuildTabulatedToneCurve16(cmsContext ContextID, cmsInt32Number nEntries, const cmsUInt16Number Values[])
|
||||
cmsToneCurve* CMSEXPORT cmsBuildTabulatedToneCurve16(cmsContext ContextID, cmsUInt32Number nEntries, const cmsUInt16Number Values[])
|
||||
{
|
||||
return AllocateToneCurveStruct(ContextID, nEntries, 0, NULL, Values);
|
||||
}
|
||||
|
||||
static
|
||||
int EntriesByGamma(cmsFloat64Number Gamma)
|
||||
cmsUInt32Number EntriesByGamma(cmsFloat64Number Gamma)
|
||||
{
|
||||
if (fabs(Gamma - 1.0) < 0.001) return 2;
|
||||
return 4096;
|
||||
@ -660,12 +769,12 @@ int EntriesByGamma(cmsFloat64Number Gamma)
|
||||
|
||||
// Create a segmented gamma, fill the table
|
||||
cmsToneCurve* CMSEXPORT cmsBuildSegmentedToneCurve(cmsContext ContextID,
|
||||
cmsInt32Number nSegments, const cmsCurveSegment Segments[])
|
||||
cmsUInt32Number nSegments, const cmsCurveSegment Segments[])
|
||||
{
|
||||
int i;
|
||||
cmsUInt32Number i;
|
||||
cmsFloat64Number R, Val;
|
||||
cmsToneCurve* g;
|
||||
int nGridPoints = 4096;
|
||||
cmsUInt32Number nGridPoints = 4096;
|
||||
|
||||
_cmsAssert(Segments != NULL);
|
||||
|
||||
@ -680,7 +789,7 @@ cmsToneCurve* CMSEXPORT cmsBuildSegmentedToneCurve(cmsContext ContextID,
|
||||
|
||||
// Once we have the floating point version, we can approximate a 16 bit table of 4096 entries
|
||||
// for performance reasons. This table would normally not be used except on 8/16 bits transforms.
|
||||
for (i=0; i < nGridPoints; i++) {
|
||||
for (i = 0; i < nGridPoints; i++) {
|
||||
|
||||
R = (cmsFloat64Number) i / (nGridPoints-1);
|
||||
|
||||
@ -893,7 +1002,7 @@ int GetInterval(cmsFloat64Number In, const cmsUInt16Number LutTable[], const str
|
||||
if (LutTable[0] < LutTable[p ->Domain[0]]) {
|
||||
|
||||
// Table is overall ascending
|
||||
for (i=p->Domain[0]-1; i >=0; --i) {
|
||||
for (i = (int) p->Domain[0] - 1; i >= 0; --i) {
|
||||
|
||||
y0 = LutTable[i];
|
||||
y1 = LutTable[i+1];
|
||||
@ -928,7 +1037,7 @@ int GetInterval(cmsFloat64Number In, const cmsUInt16Number LutTable[], const str
|
||||
}
|
||||
|
||||
// Reverse a gamma table
|
||||
cmsToneCurve* CMSEXPORT cmsReverseToneCurveEx(cmsInt32Number nResultSamples, const cmsToneCurve* InCurve)
|
||||
cmsToneCurve* CMSEXPORT cmsReverseToneCurveEx(cmsUInt32Number nResultSamples, const cmsToneCurve* InCurve)
|
||||
{
|
||||
cmsToneCurve *out;
|
||||
cmsFloat64Number a = 0, b = 0, y, x1, y1, x2, y2;
|
||||
@ -957,7 +1066,7 @@ cmsToneCurve* CMSEXPORT cmsReverseToneCurveEx(cmsInt32Number nResultSamples, con
|
||||
Ascending = !cmsIsToneCurveDescending(InCurve);
|
||||
|
||||
// Iterate across Y axis
|
||||
for (i=0; i < nResultSamples; i++) {
|
||||
for (i=0; i < (int) nResultSamples; i++) {
|
||||
|
||||
y = (cmsFloat64Number) i * 65535.0 / (nResultSamples - 1);
|
||||
|
||||
@ -1012,7 +1121,8 @@ cmsToneCurve* CMSEXPORT cmsReverseToneCurve(const cmsToneCurve* InGamma)
|
||||
// Output: smoothed vector (z): vector from 1 to m.
|
||||
|
||||
static
|
||||
cmsBool smooth2(cmsContext ContextID, cmsFloat32Number w[], cmsFloat32Number y[], cmsFloat32Number z[], cmsFloat32Number lambda, int m)
|
||||
cmsBool smooth2(cmsContext ContextID, cmsFloat32Number w[], cmsFloat32Number y[],
|
||||
cmsFloat32Number z[], cmsFloat32Number lambda, int m)
|
||||
{
|
||||
int i, i1, i2;
|
||||
cmsFloat32Number *c, *d, *e;
|
||||
@ -1071,73 +1181,121 @@ cmsBool smooth2(cmsContext ContextID, cmsFloat32Number w[], cmsFloat32Number y[]
|
||||
// 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];
|
||||
int i, nItems, Zeros, Poles;
|
||||
cmsBool SuccessStatus = TRUE;
|
||||
cmsFloat32Number *w, *y, *z;
|
||||
cmsUInt32Number i, nItems, Zeros, Poles;
|
||||
|
||||
if (Tab == NULL) return FALSE;
|
||||
|
||||
if (cmsIsToneCurveLinear(Tab)) return TRUE; // Nothing to do
|
||||
|
||||
nItems = Tab -> nEntries;
|
||||
|
||||
if (nItems >= MAX_NODES_IN_CURVE) {
|
||||
cmsSignalError(Tab ->InterpParams->ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: too many points.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memset(w, 0, nItems * sizeof(cmsFloat32Number));
|
||||
memset(y, 0, nItems * sizeof(cmsFloat32Number));
|
||||
memset(z, 0, nItems * sizeof(cmsFloat32Number));
|
||||
|
||||
for (i=0; i < nItems; i++)
|
||||
if (Tab != NULL && Tab->InterpParams != NULL)
|
||||
{
|
||||
y[i+1] = (cmsFloat32Number) Tab -> Table16[i];
|
||||
w[i+1] = 1.0;
|
||||
}
|
||||
cmsContext ContextID = Tab->InterpParams->ContextID;
|
||||
|
||||
if (!smooth2(Tab ->InterpParams->ContextID, w, y, z, (cmsFloat32Number) lambda, nItems)) return FALSE;
|
||||
if (!cmsIsToneCurveLinear(Tab)) // Only non-linear curves need smoothing
|
||||
{
|
||||
nItems = Tab->nEntries;
|
||||
if (nItems < MAX_NODES_IN_CURVE)
|
||||
{
|
||||
// Allocate one more item than needed
|
||||
w = (cmsFloat32Number *)_cmsCalloc(ContextID, nItems + 1, sizeof(cmsFloat32Number));
|
||||
y = (cmsFloat32Number *)_cmsCalloc(ContextID, nItems + 1, sizeof(cmsFloat32Number));
|
||||
z = (cmsFloat32Number *)_cmsCalloc(ContextID, nItems + 1, sizeof(cmsFloat32Number));
|
||||
|
||||
// Do some reality - checking...
|
||||
Zeros = Poles = 0;
|
||||
for (i=nItems; i > 1; --i) {
|
||||
if (w != NULL && y != NULL && z != NULL) // Ensure no memory allocation failure
|
||||
{
|
||||
memset(w, 0, (nItems + 1) * sizeof(cmsFloat32Number));
|
||||
memset(y, 0, (nItems + 1) * sizeof(cmsFloat32Number));
|
||||
memset(z, 0, (nItems + 1) * sizeof(cmsFloat32Number));
|
||||
|
||||
if (z[i] == 0.) Zeros++;
|
||||
if (z[i] >= 65535.) Poles++;
|
||||
if (z[i] < z[i-1]) {
|
||||
cmsSignalError(Tab ->InterpParams->ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Non-Monotonic.");
|
||||
return FALSE;
|
||||
for (i = 0; i < nItems; i++)
|
||||
{
|
||||
y[i + 1] = (cmsFloat32Number)Tab->Table16[i];
|
||||
w[i + 1] = 1.0;
|
||||
}
|
||||
|
||||
if (smooth2(ContextID, w, y, z, (cmsFloat32Number)lambda, (int)nItems))
|
||||
{
|
||||
// Do some reality - checking...
|
||||
|
||||
Zeros = Poles = 0;
|
||||
for (i = nItems; i > 1; --i)
|
||||
{
|
||||
if (z[i] == 0.) Zeros++;
|
||||
if (z[i] >= 65535.) Poles++;
|
||||
if (z[i] < z[i - 1])
|
||||
{
|
||||
cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Non-Monotonic.");
|
||||
SuccessStatus = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (SuccessStatus && Zeros > (nItems / 3))
|
||||
{
|
||||
cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Degenerated, mostly zeros.");
|
||||
SuccessStatus = FALSE;
|
||||
}
|
||||
|
||||
if (SuccessStatus && Poles > (nItems / 3))
|
||||
{
|
||||
cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Degenerated, mostly poles.");
|
||||
SuccessStatus = FALSE;
|
||||
}
|
||||
|
||||
if (SuccessStatus) // Seems ok
|
||||
{
|
||||
for (i = 0; i < nItems; i++)
|
||||
{
|
||||
// Clamp to cmsUInt16Number
|
||||
Tab->Table16[i] = _cmsQuickSaturateWord(z[i + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Could not smooth
|
||||
{
|
||||
cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Function smooth2 failed.");
|
||||
SuccessStatus = FALSE;
|
||||
}
|
||||
}
|
||||
else // One or more buffers could not be allocated
|
||||
{
|
||||
cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Could not allocate memory.");
|
||||
SuccessStatus = FALSE;
|
||||
}
|
||||
|
||||
if (z != NULL)
|
||||
_cmsFree(ContextID, z);
|
||||
|
||||
if (y != NULL)
|
||||
_cmsFree(ContextID, y);
|
||||
|
||||
if (w != NULL)
|
||||
_cmsFree(ContextID, w);
|
||||
}
|
||||
else // too many items in the table
|
||||
{
|
||||
cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Too many points.");
|
||||
SuccessStatus = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
else // Tab parameter or Tab->InterpParams is NULL
|
||||
{
|
||||
// Can't signal an error here since the ContextID is not known at this point
|
||||
SuccessStatus = FALSE;
|
||||
}
|
||||
|
||||
// Seems ok
|
||||
for (i=0; i < nItems; i++) {
|
||||
|
||||
// Clamp to cmsUInt16Number
|
||||
Tab -> Table16[i] = _cmsQuickSaturateWord(z[i+1]);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return SuccessStatus;
|
||||
}
|
||||
|
||||
// Is a table linear? Do not use parametric since we cannot guarantee some weird parameters resulting
|
||||
// in a linear table. This way assures it is linear in 12 bits, which should be enought in most cases.
|
||||
cmsBool CMSEXPORT cmsIsToneCurveLinear(const cmsToneCurve* Curve)
|
||||
{
|
||||
cmsUInt32Number i;
|
||||
int i;
|
||||
int diff;
|
||||
|
||||
_cmsAssert(Curve != NULL);
|
||||
|
||||
for (i=0; i < Curve ->nEntries; i++) {
|
||||
for (i=0; i < (int) Curve ->nEntries; i++) {
|
||||
|
||||
diff = abs((int) Curve->Table16[i] - (int) _cmsQuantizeVal(i, Curve ->nEntries));
|
||||
if (diff > 0x0f)
|
||||
@ -1150,7 +1308,7 @@ cmsBool CMSEXPORT cmsIsToneCurveLinear(const cmsToneCurve* Curve)
|
||||
// Same, but for monotonicity
|
||||
cmsBool CMSEXPORT cmsIsToneCurveMonotonic(const cmsToneCurve* t)
|
||||
{
|
||||
int n;
|
||||
cmsUInt32Number n;
|
||||
int i, last;
|
||||
cmsBool lDescending;
|
||||
|
||||
@ -1167,7 +1325,7 @@ cmsBool CMSEXPORT cmsIsToneCurveMonotonic(const cmsToneCurve* t)
|
||||
|
||||
last = t ->Table16[0];
|
||||
|
||||
for (i = 1; i < n; i++) {
|
||||
for (i = 1; i < (int) n; i++) {
|
||||
|
||||
if (t ->Table16[i] - last > 2) // We allow some ripple
|
||||
return FALSE;
|
||||
@ -1180,7 +1338,7 @@ cmsBool CMSEXPORT cmsIsToneCurveMonotonic(const cmsToneCurve* t)
|
||||
|
||||
last = t ->Table16[n-1];
|
||||
|
||||
for (i = n-2; i >= 0; --i) {
|
||||
for (i = (int) n - 2; i >= 0; --i) {
|
||||
|
||||
if (t ->Table16[i] - last > 2)
|
||||
return FALSE;
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
@ -326,7 +326,7 @@ cmsPipeline* _cmsCreateGamutCheckPipeline(cmsContext ContextID,
|
||||
cmsStage* CLUT;
|
||||
cmsUInt32Number dwFormat;
|
||||
GAMUTCHAIN Chain;
|
||||
int nChannels, nGridpoints;
|
||||
cmsUInt32Number nChannels, nGridpoints;
|
||||
cmsColorSpaceSignature ColorSpace;
|
||||
cmsUInt32Number i;
|
||||
cmsHPROFILE ProfileList[256];
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
@ -532,7 +532,7 @@ static cmsUInt8Number Shift[512] = {
|
||||
0x18, 0x18, 0x18, 0x18, 0x0d
|
||||
};
|
||||
|
||||
cmsFloat32Number _cmsHalf2Float(cmsUInt16Number h)
|
||||
cmsFloat32Number CMSEXPORT _cmsHalf2Float(cmsUInt16Number h)
|
||||
{
|
||||
union {
|
||||
cmsFloat32Number flt;
|
||||
@ -545,7 +545,7 @@ cmsFloat32Number _cmsHalf2Float(cmsUInt16Number h)
|
||||
return out.flt;
|
||||
}
|
||||
|
||||
cmsUInt16Number _cmsFloat2Half(cmsFloat32Number flt)
|
||||
cmsUInt16Number CMSEXPORT _cmsFloat2Half(cmsFloat32Number flt)
|
||||
{
|
||||
union {
|
||||
cmsFloat32Number flt;
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
@ -58,6 +58,13 @@
|
||||
// This module incorporates several interpolation routines, for 1 to 8 channels on input and
|
||||
// up to 65535 channels on output. The user may change those by using the interpolation plug-in
|
||||
|
||||
// Some people may want to compile as C++ with all warnings on, in this case make compiler silent
|
||||
#ifdef _MSC_VER
|
||||
# if (_MSC_VER >= 1400)
|
||||
# pragma warning( disable : 4365 )
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Interpolation routines by default
|
||||
static cmsInterpFunction DefaultInterpolatorsFactory(cmsUInt32Number nInputChannels, cmsUInt32Number nOutputChannels, cmsUInt32Number dwFlags);
|
||||
|
||||
@ -131,12 +138,12 @@ cmsBool _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p)
|
||||
// This function precalculates as many parameters as possible to speed up the interpolation.
|
||||
cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID,
|
||||
const cmsUInt32Number nSamples[],
|
||||
int InputChan, int OutputChan,
|
||||
cmsUInt32Number InputChan, cmsUInt32Number OutputChan,
|
||||
const void *Table,
|
||||
cmsUInt32Number dwFlags)
|
||||
{
|
||||
cmsInterpParams* p;
|
||||
int i;
|
||||
cmsUInt32Number i;
|
||||
|
||||
// Check for maximum inputs
|
||||
if (InputChan > MAX_INPUT_DIMENSIONS) {
|
||||
@ -180,7 +187,8 @@ cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID,
|
||||
|
||||
|
||||
// This one is a wrapper on the anterior, but assuming all directions have same number of nodes
|
||||
cmsInterpParams* _cmsComputeInterpParams(cmsContext ContextID, int nSamples, int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags)
|
||||
cmsInterpParams* CMSEXPORT _cmsComputeInterpParams(cmsContext ContextID, cmsUInt32Number nSamples,
|
||||
cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags)
|
||||
{
|
||||
int i;
|
||||
cmsUInt32Number Samples[MAX_INPUT_DIMENSIONS];
|
||||
@ -195,7 +203,7 @@ cmsInterpParams* _cmsComputeInterpParams(cmsContext ContextID, int nSamples, int
|
||||
|
||||
|
||||
// Free all associated memory
|
||||
void _cmsFreeInterpParams(cmsInterpParams* p)
|
||||
void CMSEXPORT _cmsFreeInterpParams(cmsInterpParams* p)
|
||||
{
|
||||
if (p != NULL) _cmsFree(p ->ContextID, p);
|
||||
}
|
||||
@ -244,7 +252,7 @@ void LinLerp1D(register const cmsUInt16Number Value[],
|
||||
// To prevent out of bounds indexing
|
||||
cmsINLINE cmsFloat32Number fclamp(cmsFloat32Number v)
|
||||
{
|
||||
return v < 0.0f || v != v ? 0.0f : (v > 1.0f ? 1.0f : v);
|
||||
return ((v < 1.0e-9f) || isnan(v)) ? 0.0f : (v > 1.0f ? 1.0f : v);
|
||||
}
|
||||
|
||||
// Floating-point version of 1D interpolation
|
||||
@ -381,10 +389,10 @@ void BilinearInterpFloat(const cmsFloat32Number Input[],
|
||||
y0 = (int) _cmsQuickFloor(py); fy = py - (cmsFloat32Number) y0;
|
||||
|
||||
X0 = p -> opta[1] * x0;
|
||||
X1 = X0 + (Input[0] >= 1.0 ? 0 : p->opta[1]);
|
||||
X1 = X0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[1]);
|
||||
|
||||
Y0 = p -> opta[0] * y0;
|
||||
Y1 = Y0 + (Input[1] >= 1.0 ? 0 : p->opta[0]);
|
||||
Y1 = Y0 + (fclamp(Input[1]) >= 1.0 ? 0 : p->opta[0]);
|
||||
|
||||
for (OutChan = 0; OutChan < TotalOut; OutChan++) {
|
||||
|
||||
@ -493,18 +501,18 @@ void TrilinearInterpFloat(const cmsFloat32Number Input[],
|
||||
py = fclamp(Input[1]) * p->Domain[1];
|
||||
pz = fclamp(Input[2]) * p->Domain[2];
|
||||
|
||||
x0 = (int) _cmsQuickFloor(px); fx = px - (cmsFloat32Number) x0;
|
||||
y0 = (int) _cmsQuickFloor(py); fy = py - (cmsFloat32Number) y0;
|
||||
z0 = (int) _cmsQuickFloor(pz); fz = pz - (cmsFloat32Number) z0;
|
||||
x0 = (int) floor(px); fx = px - (cmsFloat32Number) x0; // We need full floor funcionality here
|
||||
y0 = (int) floor(py); fy = py - (cmsFloat32Number) y0;
|
||||
z0 = (int) floor(pz); fz = pz - (cmsFloat32Number) z0;
|
||||
|
||||
X0 = p -> opta[2] * x0;
|
||||
X1 = X0 + (Input[0] >= 1.0 ? 0 : p->opta[2]);
|
||||
X1 = X0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[2]);
|
||||
|
||||
Y0 = p -> opta[1] * y0;
|
||||
Y1 = Y0 + (Input[1] >= 1.0 ? 0 : p->opta[1]);
|
||||
Y1 = Y0 + (fclamp(Input[1]) >= 1.0 ? 0 : p->opta[1]);
|
||||
|
||||
Z0 = p -> opta[0] * z0;
|
||||
Z1 = Z0 + (Input[2] >= 1.0 ? 0 : p->opta[0]);
|
||||
Z1 = Z0 + (fclamp(Input[2]) >= 1.0 ? 0 : p->opta[0]);
|
||||
|
||||
for (OutChan = 0; OutChan < TotalOut; OutChan++) {
|
||||
|
||||
@ -637,19 +645,19 @@ void TetrahedralInterpFloat(const cmsFloat32Number Input[],
|
||||
py = fclamp(Input[1]) * p->Domain[1];
|
||||
pz = fclamp(Input[2]) * p->Domain[2];
|
||||
|
||||
x0 = (int) _cmsQuickFloor(px); rx = (px - (cmsFloat32Number) x0);
|
||||
y0 = (int) _cmsQuickFloor(py); ry = (py - (cmsFloat32Number) y0);
|
||||
z0 = (int) _cmsQuickFloor(pz); rz = (pz - (cmsFloat32Number) z0);
|
||||
x0 = (int) floor(px); rx = (px - (cmsFloat32Number) x0); // We need full floor functionality here
|
||||
y0 = (int) floor(py); ry = (py - (cmsFloat32Number) y0);
|
||||
z0 = (int) floor(pz); rz = (pz - (cmsFloat32Number) z0);
|
||||
|
||||
|
||||
X0 = p -> opta[2] * x0;
|
||||
X1 = X0 + (Input[0] >= 1.0 ? 0 : p->opta[2]);
|
||||
X1 = X0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[2]);
|
||||
|
||||
Y0 = p -> opta[1] * y0;
|
||||
Y1 = Y0 + (Input[1] >= 1.0 ? 0 : p->opta[1]);
|
||||
Y1 = Y0 + (fclamp(Input[1]) >= 1.0 ? 0 : p->opta[1]);
|
||||
|
||||
Z0 = p -> opta[0] * z0;
|
||||
Z1 = Z0 + (Input[2] >= 1.0 ? 0 : p->opta[0]);
|
||||
Z1 = Z0 + (fclamp(Input[2]) >= 1.0 ? 0 : p->opta[0]);
|
||||
|
||||
for (OutChan=0; OutChan < TotalOut; OutChan++) {
|
||||
|
||||
@ -952,13 +960,13 @@ void Eval4Inputs(register const cmsUInt16Number Input[],
|
||||
c3 = DENS(X0, Y0, Z1) - c0;
|
||||
|
||||
}
|
||||
else {
|
||||
else {
|
||||
c1 = c2 = c3 = 0;
|
||||
}
|
||||
|
||||
Rest = c1 * rx + c2 * ry + c3 * rz;
|
||||
|
||||
Tmp1[OutChan] = (cmsUInt16Number) ( c0 + ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest)));
|
||||
Tmp1[OutChan] = (cmsUInt16Number)(c0 + ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest)));
|
||||
}
|
||||
|
||||
|
||||
@ -1057,7 +1065,7 @@ void Eval4InputsFloat(const cmsFloat32Number Input[],
|
||||
rest = pk - (cmsFloat32Number) k0;
|
||||
|
||||
K0 = p -> opta[3] * k0;
|
||||
K1 = K0 + (Input[0] >= 1.0 ? 0 : p->opta[3]);
|
||||
K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[3]);
|
||||
|
||||
p1 = *p;
|
||||
memmove(&p1.Domain[0], &p ->Domain[1], 3*sizeof(cmsUInt32Number));
|
||||
@ -1144,7 +1152,7 @@ void Eval5InputsFloat(const cmsFloat32Number Input[],
|
||||
rest = pk - (cmsFloat32Number) k0;
|
||||
|
||||
K0 = p -> opta[4] * k0;
|
||||
K1 = K0 + (Input[0] >= 1.0 ? 0 : p->opta[4]);
|
||||
K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[4]);
|
||||
|
||||
p1 = *p;
|
||||
memmove(&p1.Domain[0], &p ->Domain[1], 4*sizeof(cmsUInt32Number));
|
||||
@ -1231,7 +1239,7 @@ void Eval6InputsFloat(const cmsFloat32Number Input[],
|
||||
rest = pk - (cmsFloat32Number) k0;
|
||||
|
||||
K0 = p -> opta[5] * k0;
|
||||
K1 = K0 + (Input[0] >= 1.0 ? 0 : p->opta[5]);
|
||||
K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[5]);
|
||||
|
||||
p1 = *p;
|
||||
memmove(&p1.Domain[0], &p ->Domain[1], 5*sizeof(cmsUInt32Number));
|
||||
@ -1316,7 +1324,7 @@ void Eval7InputsFloat(const cmsFloat32Number Input[],
|
||||
rest = pk - (cmsFloat32Number) k0;
|
||||
|
||||
K0 = p -> opta[6] * k0;
|
||||
K1 = K0 + (Input[0] >= 1.0 ? 0 : p->opta[6]);
|
||||
K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[6]);
|
||||
|
||||
p1 = *p;
|
||||
memmove(&p1.Domain[0], &p ->Domain[1], 6*sizeof(cmsUInt32Number));
|
||||
@ -1401,7 +1409,7 @@ void Eval8InputsFloat(const cmsFloat32Number Input[],
|
||||
rest = pk - (cmsFloat32Number) k0;
|
||||
|
||||
K0 = p -> opta[7] * k0;
|
||||
K1 = K0 + (Input[0] >= 1.0 ? 0 : p->opta[7]);
|
||||
K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[7]);
|
||||
|
||||
p1 = *p;
|
||||
memmove(&p1.Domain[0], &p ->Domain[1], 7*sizeof(cmsUInt32Number));
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
@ -366,21 +366,27 @@ cmsBool FileSeek(cmsIOHANDLER* iohandler, cmsUInt32Number offset)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Returns file pointer position
|
||||
// Returns file pointer position or 0 on error, which is also a valid position.
|
||||
static
|
||||
cmsUInt32Number FileTell(cmsIOHANDLER* iohandler)
|
||||
{
|
||||
return (cmsUInt32Number) ftell((FILE*)iohandler ->stream);
|
||||
long t = ftell((FILE*)iohandler ->stream);
|
||||
if (t == -1L) {
|
||||
cmsSignalError(iohandler->ContextID, cmsERROR_FILE, "Tell error; probably corrupted file");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (cmsUInt32Number)t;
|
||||
}
|
||||
|
||||
// Writes data to stream, also keeps used space for further reference. Returns TRUE on success, FALSE on error
|
||||
static
|
||||
cmsBool FileWrite(cmsIOHANDLER* iohandler, cmsUInt32Number size, const void* Buffer)
|
||||
{
|
||||
if (size == 0) return TRUE; // We allow to write 0 bytes, but nothing is written
|
||||
if (size == 0) return TRUE; // We allow to write 0 bytes, but nothing is written
|
||||
|
||||
iohandler->UsedSpace += size;
|
||||
return (fwrite(Buffer, size, 1, (FILE*) iohandler->stream) == 1);
|
||||
iohandler->UsedSpace += size;
|
||||
return (fwrite(Buffer, size, 1, (FILE*)iohandler->stream) == 1);
|
||||
}
|
||||
|
||||
// Closes the file
|
||||
@ -548,7 +554,7 @@ cmsInt32Number CMSEXPORT cmsGetTagCount(cmsHPROFILE hProfile)
|
||||
_cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile;
|
||||
if (Icc == NULL) return -1;
|
||||
|
||||
return Icc->TagCount;
|
||||
return (cmsInt32Number) Icc->TagCount;
|
||||
}
|
||||
|
||||
// Return the tag signature of a given tag number
|
||||
@ -566,9 +572,9 @@ cmsTagSignature CMSEXPORT cmsGetTagSignature(cmsHPROFILE hProfile, cmsUInt32Numb
|
||||
static
|
||||
int SearchOneTag(_cmsICCPROFILE* Profile, cmsTagSignature sig)
|
||||
{
|
||||
cmsUInt32Number i;
|
||||
int i;
|
||||
|
||||
for (i=0; i < Profile -> TagCount; i++) {
|
||||
for (i=0; i < (int) Profile -> TagCount; i++) {
|
||||
|
||||
if (sig == Profile -> TagNames[i])
|
||||
return i;
|
||||
@ -662,7 +668,7 @@ cmsBool _cmsNewTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, int* NewPos)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*NewPos = Icc ->TagCount;
|
||||
*NewPos = (int) Icc ->TagCount;
|
||||
Icc -> TagCount++;
|
||||
}
|
||||
|
||||
@ -693,10 +699,10 @@ cmsUInt32Number _validatedVersion(cmsUInt32Number DWord)
|
||||
cmsUInt8Number temp2;
|
||||
|
||||
if (*pByte > 0x09) *pByte = (cmsUInt8Number) 0x09;
|
||||
temp1 = *(pByte+1) & 0xf0;
|
||||
temp2 = *(pByte+1) & 0x0f;
|
||||
if (temp1 > 0x90) temp1 = 0x90;
|
||||
if (temp2 > 0x09) temp2 = 0x09;
|
||||
temp1 = (cmsUInt8Number) (*(pByte+1) & 0xf0);
|
||||
temp2 = (cmsUInt8Number) (*(pByte+1) & 0x0f);
|
||||
if (temp1 > 0x90U) temp1 = 0x90U;
|
||||
if (temp2 > 0x09U) temp2 = 0x09U;
|
||||
*(pByte+1) = (cmsUInt8Number)(temp1 | temp2);
|
||||
*(pByte+2) = (cmsUInt8Number)0;
|
||||
*(pByte+3) = (cmsUInt8Number)0;
|
||||
@ -804,7 +810,7 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace)
|
||||
cmsICCHeader Header;
|
||||
cmsUInt32Number i;
|
||||
cmsTagEntry Tag;
|
||||
cmsInt32Number Count = 0;
|
||||
cmsUInt32Number Count;
|
||||
|
||||
Header.size = _cmsAdjustEndianess32(UsedSpace);
|
||||
Header.cmmId = _cmsAdjustEndianess32(lcmsSignature);
|
||||
@ -835,9 +841,9 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace)
|
||||
Header.renderingIntent = _cmsAdjustEndianess32(Icc -> RenderingIntent);
|
||||
|
||||
// Illuminant is always D50
|
||||
Header.illuminant.X = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(cmsD50_XYZ()->X));
|
||||
Header.illuminant.Y = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(cmsD50_XYZ()->Y));
|
||||
Header.illuminant.Z = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(cmsD50_XYZ()->Z));
|
||||
Header.illuminant.X = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(cmsD50_XYZ()->X));
|
||||
Header.illuminant.Y = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(cmsD50_XYZ()->Y));
|
||||
Header.illuminant.Z = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(cmsD50_XYZ()->Z));
|
||||
|
||||
// Created by LittleCMS (that's me!)
|
||||
Header.creator = _cmsAdjustEndianess32(lcmsSignature);
|
||||
@ -853,6 +859,7 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace)
|
||||
// Saves Tag directory
|
||||
|
||||
// Get true count
|
||||
Count = 0;
|
||||
for (i=0; i < Icc -> TagCount; i++) {
|
||||
if (Icc ->TagNames[i] != (cmsTagSignature) 0)
|
||||
Count++;
|
||||
@ -865,9 +872,9 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace)
|
||||
|
||||
if (Icc ->TagNames[i] == (cmsTagSignature) 0) continue; // It is just a placeholder
|
||||
|
||||
Tag.sig = (cmsTagSignature) _cmsAdjustEndianess32((cmsInt32Number) Icc -> TagNames[i]);
|
||||
Tag.offset = _cmsAdjustEndianess32((cmsInt32Number) Icc -> TagOffsets[i]);
|
||||
Tag.size = _cmsAdjustEndianess32((cmsInt32Number) Icc -> TagSizes[i]);
|
||||
Tag.sig = (cmsTagSignature) _cmsAdjustEndianess32((cmsUInt32Number) Icc -> TagNames[i]);
|
||||
Tag.offset = _cmsAdjustEndianess32((cmsUInt32Number) Icc -> TagOffsets[i]);
|
||||
Tag.size = _cmsAdjustEndianess32((cmsUInt32Number) Icc -> TagSizes[i]);
|
||||
|
||||
if (!Icc ->IOhandler -> Write(Icc-> IOhandler, sizeof(cmsTagEntry), &Tag)) return FALSE;
|
||||
}
|
||||
@ -1176,7 +1183,7 @@ cmsHPROFILE CMSEXPORT cmsOpenProfileFromMemTHR(cmsContext ContextID, const void*
|
||||
NewIcc = (_cmsICCPROFILE*) hEmpty;
|
||||
|
||||
// Ok, in this case const void* is casted to void* just because open IO handler
|
||||
// shares read and writting modes. Don't abuse this feature!
|
||||
// shares read and writing modes. Don't abuse this feature!
|
||||
NewIcc ->IOhandler = cmsOpenIOhandlerFromMem(ContextID, (void*) MemPtr, dwSize, "r");
|
||||
if (NewIcc ->IOhandler == NULL) goto Error;
|
||||
|
||||
@ -1466,7 +1473,7 @@ cmsBool CMSEXPORT cmsCloseProfile(cmsHPROFILE hProfile)
|
||||
// Was open in write mode?
|
||||
if (Icc ->IsWrite) {
|
||||
|
||||
Icc ->IsWrite = FALSE; // Assure no further writting
|
||||
Icc ->IsWrite = FALSE; // Assure no further writing
|
||||
rc &= cmsSaveProfileToFile(hProfile, Icc ->IOhandler->PhysicalFile);
|
||||
}
|
||||
|
||||
@ -1543,11 +1550,15 @@ void* CMSEXPORT cmsReadTag(cmsHPROFILE hProfile, cmsTagSignature sig)
|
||||
// If the element is already in memory, return the pointer
|
||||
if (Icc -> TagPtrs[n]) {
|
||||
|
||||
if (Icc -> TagTypeHandlers[n] == NULL) goto Error;
|
||||
BaseType = Icc -> TagTypeHandlers[n]->Signature;
|
||||
if (Icc->TagTypeHandlers[n] == NULL) goto Error;
|
||||
|
||||
// Sanity check
|
||||
BaseType = Icc->TagTypeHandlers[n]->Signature;
|
||||
if (BaseType == 0) goto Error;
|
||||
TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, sig);
|
||||
|
||||
TagDescriptor = _cmsGetTagDescriptor(Icc->ContextID, sig);
|
||||
if (TagDescriptor == NULL) goto Error;
|
||||
|
||||
if (!IsTypeSupported(TagDescriptor, BaseType)) goto Error;
|
||||
|
||||
if (Icc ->TagSaveAsRaw[n]) goto Error; // We don't support read raw tags as cooked
|
||||
@ -1560,6 +1571,8 @@ void* CMSEXPORT cmsReadTag(cmsHPROFILE hProfile, cmsTagSignature sig)
|
||||
Offset = Icc -> TagOffsets[n];
|
||||
TagSize = Icc -> TagSizes[n];
|
||||
|
||||
if (TagSize < 8) goto Error;
|
||||
|
||||
// Seek to its location
|
||||
if (!io -> Seek(io, Offset))
|
||||
goto Error;
|
||||
@ -1583,7 +1596,7 @@ void* CMSEXPORT cmsReadTag(cmsHPROFILE hProfile, cmsTagSignature sig)
|
||||
|
||||
if (!IsTypeSupported(TagDescriptor, BaseType)) goto Error;
|
||||
|
||||
TagSize -= 8; // Alredy read by the type base logic
|
||||
TagSize -= 8; // Alredy read by the type base logic
|
||||
|
||||
// Get type handler
|
||||
TypeHandler = _cmsGetTagTypeHandler(Icc ->ContextID, BaseType);
|
||||
@ -1772,7 +1785,7 @@ Error:
|
||||
// raw data written does not exactly correspond with the raw data proposed to cmsWriteRaw data, but this approach allows
|
||||
// to write a tag as raw data and the read it as handled.
|
||||
|
||||
cmsInt32Number CMSEXPORT cmsReadRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, void* data, cmsUInt32Number BufferSize)
|
||||
cmsUInt32Number CMSEXPORT cmsReadRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, void* data, cmsUInt32Number BufferSize)
|
||||
{
|
||||
_cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile;
|
||||
void *Object;
|
||||
@ -1890,7 +1903,7 @@ Error:
|
||||
}
|
||||
|
||||
// Similar to the anterior. This function allows to write directly to the ICC profile any data, without
|
||||
// checking anything. As a rule, mixing Raw with cooked doesn't work, so writting a tag as raw and then reading
|
||||
// checking anything. As a rule, mixing Raw with cooked doesn't work, so writing a tag as raw and then reading
|
||||
// it as cooked without serializing does result into an error. If that is what you want, you will need to dump
|
||||
// the profile to memry or disk and then reopen it.
|
||||
cmsBool CMSEXPORT cmsWriteRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, const void* data, cmsUInt32Number Size)
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
@ -335,8 +335,8 @@ Error:
|
||||
|
||||
// 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.
|
||||
// We add intent = -1 as a way to read matrix shaper always, no matter of other LUT
|
||||
cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent)
|
||||
// We add intent = 0xffffffff as a way to read matrix shaper always, no matter of other LUT
|
||||
cmsPipeline* CMSEXPORT _cmsReadInputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent)
|
||||
{
|
||||
cmsTagTypeSignature OriginalType;
|
||||
cmsTagSignature tag16;
|
||||
@ -366,8 +366,8 @@ cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent)
|
||||
}
|
||||
|
||||
// This is an attempt to reuse this function to retrieve the matrix-shaper as pipeline no
|
||||
// matter other LUT are present and have precedence. Intent = -1 means just this.
|
||||
if (Intent >= INTENT_PERCEPTUAL && Intent <= INTENT_ABSOLUTE_COLORIMETRIC) {
|
||||
// matter other LUT are present and have precedence. Intent = 0xffffffff can be used for that.
|
||||
if (Intent <= INTENT_ABSOLUTE_COLORIMETRIC) {
|
||||
|
||||
tag16 = Device2PCS16[Intent];
|
||||
tagFloat = Device2PCSFloat[Intent];
|
||||
@ -611,7 +611,7 @@ Error:
|
||||
}
|
||||
|
||||
// Create an output MPE LUT from agiven profile. Version mismatches are handled here
|
||||
cmsPipeline* _cmsReadOutputLUT(cmsHPROFILE hProfile, int Intent)
|
||||
cmsPipeline* CMSEXPORT _cmsReadOutputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent)
|
||||
{
|
||||
cmsTagTypeSignature OriginalType;
|
||||
cmsTagSignature tag16;
|
||||
@ -619,7 +619,7 @@ cmsPipeline* _cmsReadOutputLUT(cmsHPROFILE hProfile, int Intent)
|
||||
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
||||
|
||||
|
||||
if (Intent >= INTENT_PERCEPTUAL && Intent <= INTENT_ABSOLUTE_COLORIMETRIC) {
|
||||
if (Intent <= INTENT_ABSOLUTE_COLORIMETRIC) {
|
||||
|
||||
tag16 = PCS2Device16[Intent];
|
||||
tagFloat = PCS2DeviceFloat[Intent];
|
||||
@ -695,8 +695,8 @@ Error:
|
||||
static
|
||||
cmsPipeline* _cmsReadFloatDevicelinkTag(cmsHPROFILE hProfile, cmsTagSignature tagFloat)
|
||||
{
|
||||
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
||||
cmsPipeline* Lut = cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat));
|
||||
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
||||
cmsPipeline* Lut = cmsPipelineDup((cmsPipeline*)cmsReadTag(hProfile, tagFloat));
|
||||
cmsColorSpaceSignature PCS = cmsGetPCS(hProfile);
|
||||
cmsColorSpaceSignature spc = cmsGetColorSpace(hProfile);
|
||||
|
||||
@ -714,17 +714,17 @@ cmsPipeline* _cmsReadFloatDevicelinkTag(cmsHPROFILE hProfile, cmsTagSignature ta
|
||||
goto Error;
|
||||
}
|
||||
|
||||
if (PCS == cmsSigLabData)
|
||||
if (PCS == cmsSigLabData)
|
||||
{
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromLabFloat(ContextID)))
|
||||
goto Error;
|
||||
}
|
||||
else
|
||||
if (PCS == cmsSigXYZData)
|
||||
{
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromLabFloat(ContextID)))
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromXyzFloat(ContextID)))
|
||||
goto Error;
|
||||
}
|
||||
else
|
||||
if (PCS == cmsSigXYZData)
|
||||
{
|
||||
if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromXyzFloat(ContextID)))
|
||||
goto Error;
|
||||
}
|
||||
|
||||
return Lut;
|
||||
Error:
|
||||
@ -734,7 +734,7 @@ Error:
|
||||
|
||||
// This one includes abstract profiles as well. Matrix-shaper cannot be obtained on that device class. The
|
||||
// tag name here may default to AToB0
|
||||
cmsPipeline* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent)
|
||||
cmsPipeline* CMSEXPORT _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent)
|
||||
{
|
||||
cmsPipeline* Lut;
|
||||
cmsTagTypeSignature OriginalType;
|
||||
@ -743,7 +743,7 @@ cmsPipeline* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent)
|
||||
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
||||
|
||||
|
||||
if (Intent < INTENT_PERCEPTUAL || Intent > INTENT_ABSOLUTE_COLORIMETRIC)
|
||||
if (Intent > INTENT_ABSOLUTE_COLORIMETRIC)
|
||||
return NULL;
|
||||
|
||||
tag16 = Device2PCS16[Intent];
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
@ -153,8 +153,8 @@ cmsBool CMSEXPORT cmsPipelineCheckAndRetreiveStages(const cmsPipeline* Lut, cms
|
||||
mpe = Lut ->Elements;
|
||||
for (i=0; i < n; i++) {
|
||||
|
||||
// Get asked type
|
||||
Type = (cmsStageSignature)va_arg(args, cmsStageSignature);
|
||||
// Get asked type. cmsStageSignature is promoted to int by compiler
|
||||
Type = (cmsStageSignature)va_arg(args, int);
|
||||
if (mpe ->Type != Type) {
|
||||
|
||||
va_end(args); // Mismatch. We are done.
|
||||
@ -321,7 +321,7 @@ cmsStage* CMSEXPORT cmsStageAllocToneCurves(cmsContext ContextID, cmsUInt32Numbe
|
||||
|
||||
|
||||
// Create a bunch of identity curves
|
||||
cmsStage* _cmsStageAllocIdentityCurves(cmsContext ContextID, int nChannels)
|
||||
cmsStage* CMSEXPORT _cmsStageAllocIdentityCurves(cmsContext ContextID, cmsUInt32Number nChannels)
|
||||
{
|
||||
cmsStage* mpe = cmsStageAllocToneCurves(ContextID, nChannels, NULL);
|
||||
|
||||
@ -443,13 +443,13 @@ cmsStage* CMSEXPORT cmsStageAllocMatrix(cmsContext ContextID, cmsUInt32Number R
|
||||
|
||||
if (Offset != NULL) {
|
||||
|
||||
NewElem ->Offset = (cmsFloat64Number*) _cmsCalloc(ContextID, Cols, sizeof(cmsFloat64Number));
|
||||
NewElem ->Offset = (cmsFloat64Number*) _cmsCalloc(ContextID, Rows, sizeof(cmsFloat64Number));
|
||||
if (NewElem->Offset == NULL) {
|
||||
MatrixElemTypeFree(NewMPE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i=0; i < Cols; i++) {
|
||||
for (i=0; i < Rows; i++) {
|
||||
NewElem ->Offset[i] = Offset[i];
|
||||
}
|
||||
|
||||
@ -741,7 +741,7 @@ int IdentitySampler(register const cmsUInt16Number In[], register cmsUInt16Numbe
|
||||
}
|
||||
|
||||
// Creates an MPE that just copies input to output
|
||||
cmsStage* _cmsStageAllocIdentityCLut(cmsContext ContextID, int nChan)
|
||||
cmsStage* CMSEXPORT _cmsStageAllocIdentityCLut(cmsContext ContextID, cmsUInt32Number nChan)
|
||||
{
|
||||
cmsUInt32Number Dimensions[MAX_INPUT_DIMENSIONS];
|
||||
cmsStage* mpe ;
|
||||
@ -765,7 +765,7 @@ cmsStage* _cmsStageAllocIdentityCLut(cmsContext ContextID, int nChan)
|
||||
|
||||
|
||||
// Quantize a value 0 <= i < MaxSamples to 0..0xffff
|
||||
cmsUInt16Number _cmsQuantizeVal(cmsFloat64Number i, int MaxSamples)
|
||||
cmsUInt16Number CMSEXPORT _cmsQuantizeVal(cmsFloat64Number i, cmsUInt32Number MaxSamples)
|
||||
{
|
||||
cmsFloat64Number x;
|
||||
|
||||
@ -778,8 +778,9 @@ cmsUInt16Number _cmsQuantizeVal(cmsFloat64Number i, int MaxSamples)
|
||||
// function on knots. returns TRUE if all ok, FALSE otherwise.
|
||||
cmsBool CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe, cmsSAMPLER16 Sampler, void * Cargo, cmsUInt32Number dwFlags)
|
||||
{
|
||||
int i, t, nTotalPoints, index, rest;
|
||||
int nInputs, nOutputs;
|
||||
int i, t, index, rest;
|
||||
cmsUInt32Number nTotalPoints;
|
||||
cmsUInt32Number nInputs, nOutputs;
|
||||
cmsUInt32Number* nSamples;
|
||||
cmsUInt16Number In[MAX_INPUT_DIMENSIONS+1], Out[MAX_STAGE_CHANNELS];
|
||||
_cmsStageCLutData* clut;
|
||||
@ -799,14 +800,17 @@ cmsBool CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe, cmsSAMPLER16 Sampler, v
|
||||
if (nInputs > MAX_INPUT_DIMENSIONS) return FALSE;
|
||||
if (nOutputs >= MAX_STAGE_CHANNELS) return FALSE;
|
||||
|
||||
memset(In, 0, sizeof(In));
|
||||
memset(Out, 0, sizeof(Out));
|
||||
|
||||
nTotalPoints = CubeSize(nSamples, nInputs);
|
||||
if (nTotalPoints == 0) return FALSE;
|
||||
|
||||
index = 0;
|
||||
for (i = 0; i < nTotalPoints; i++) {
|
||||
for (i = 0; i < (int) nTotalPoints; i++) {
|
||||
|
||||
rest = i;
|
||||
for (t = nInputs-1; t >=0; --t) {
|
||||
for (t = (int)nInputs - 1; t >= 0; --t) {
|
||||
|
||||
cmsUInt32Number Colorant = rest % nSamples[t];
|
||||
|
||||
@ -816,7 +820,7 @@ cmsBool CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe, cmsSAMPLER16 Sampler, v
|
||||
}
|
||||
|
||||
if (clut ->Tab.T != NULL) {
|
||||
for (t=0; t < nOutputs; t++)
|
||||
for (t = 0; t < (int)nOutputs; t++)
|
||||
Out[t] = clut->Tab.T[index + t];
|
||||
}
|
||||
|
||||
@ -826,7 +830,7 @@ cmsBool CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe, cmsSAMPLER16 Sampler, v
|
||||
if (!(dwFlags & SAMPLER_INSPECT)) {
|
||||
|
||||
if (clut ->Tab.T != NULL) {
|
||||
for (t=0; t < nOutputs; t++)
|
||||
for (t=0; t < (int) nOutputs; t++)
|
||||
clut->Tab.T[index + t] = Out[t];
|
||||
}
|
||||
}
|
||||
@ -837,11 +841,12 @@ cmsBool CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe, cmsSAMPLER16 Sampler, v
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Same as anterior, but for floting point
|
||||
// Same as anterior, but for floating point
|
||||
cmsBool CMSEXPORT cmsStageSampleCLutFloat(cmsStage* mpe, cmsSAMPLERFLOAT Sampler, void * Cargo, cmsUInt32Number dwFlags)
|
||||
{
|
||||
int i, t, nTotalPoints, index, rest;
|
||||
int nInputs, nOutputs;
|
||||
int i, t, index, rest;
|
||||
cmsUInt32Number nTotalPoints;
|
||||
cmsUInt32Number nInputs, nOutputs;
|
||||
cmsUInt32Number* nSamples;
|
||||
cmsFloat32Number In[MAX_INPUT_DIMENSIONS+1], Out[MAX_STAGE_CHANNELS];
|
||||
_cmsStageCLutData* clut = (_cmsStageCLutData*) mpe->Data;
|
||||
@ -859,10 +864,10 @@ cmsBool CMSEXPORT cmsStageSampleCLutFloat(cmsStage* mpe, cmsSAMPLERFLOAT Sampler
|
||||
if (nTotalPoints == 0) return FALSE;
|
||||
|
||||
index = 0;
|
||||
for (i = 0; i < nTotalPoints; i++) {
|
||||
for (i = 0; i < (int)nTotalPoints; i++) {
|
||||
|
||||
rest = i;
|
||||
for (t = nInputs-1; t >=0; --t) {
|
||||
for (t = (int) nInputs-1; t >=0; --t) {
|
||||
|
||||
cmsUInt32Number Colorant = rest % nSamples[t];
|
||||
|
||||
@ -872,7 +877,7 @@ cmsBool CMSEXPORT cmsStageSampleCLutFloat(cmsStage* mpe, cmsSAMPLERFLOAT Sampler
|
||||
}
|
||||
|
||||
if (clut ->Tab.TFloat != NULL) {
|
||||
for (t=0; t < nOutputs; t++)
|
||||
for (t=0; t < (int) nOutputs; t++)
|
||||
Out[t] = clut->Tab.TFloat[index + t];
|
||||
}
|
||||
|
||||
@ -882,7 +887,7 @@ cmsBool CMSEXPORT cmsStageSampleCLutFloat(cmsStage* mpe, cmsSAMPLERFLOAT Sampler
|
||||
if (!(dwFlags & SAMPLER_INSPECT)) {
|
||||
|
||||
if (clut ->Tab.TFloat != NULL) {
|
||||
for (t=0; t < nOutputs; t++)
|
||||
for (t=0; t < (int) nOutputs; t++)
|
||||
clut->Tab.TFloat[index + t] = Out[t];
|
||||
}
|
||||
}
|
||||
@ -900,7 +905,8 @@ cmsBool CMSEXPORT cmsStageSampleCLutFloat(cmsStage* mpe, cmsSAMPLERFLOAT Sampler
|
||||
cmsBool CMSEXPORT cmsSliceSpace16(cmsUInt32Number nInputs, const cmsUInt32Number clutPoints[],
|
||||
cmsSAMPLER16 Sampler, void * Cargo)
|
||||
{
|
||||
int i, t, nTotalPoints, rest;
|
||||
int i, t, rest;
|
||||
cmsUInt32Number nTotalPoints;
|
||||
cmsUInt16Number In[cmsMAXCHANNELS];
|
||||
|
||||
if (nInputs >= cmsMAXCHANNELS) return FALSE;
|
||||
@ -908,10 +914,10 @@ cmsBool CMSEXPORT cmsSliceSpace16(cmsUInt32Number nInputs, const cmsUInt32Number
|
||||
nTotalPoints = CubeSize(clutPoints, nInputs);
|
||||
if (nTotalPoints == 0) return FALSE;
|
||||
|
||||
for (i = 0; i < nTotalPoints; i++) {
|
||||
for (i = 0; i < (int) nTotalPoints; i++) {
|
||||
|
||||
rest = i;
|
||||
for (t = nInputs-1; t >=0; --t) {
|
||||
for (t = (int) nInputs-1; t >=0; --t) {
|
||||
|
||||
cmsUInt32Number Colorant = rest % clutPoints[t];
|
||||
|
||||
@ -930,7 +936,8 @@ cmsBool CMSEXPORT cmsSliceSpace16(cmsUInt32Number nInputs, const cmsUInt32Number
|
||||
cmsInt32Number CMSEXPORT cmsSliceSpaceFloat(cmsUInt32Number nInputs, const cmsUInt32Number clutPoints[],
|
||||
cmsSAMPLERFLOAT Sampler, void * Cargo)
|
||||
{
|
||||
int i, t, nTotalPoints, rest;
|
||||
int i, t, rest;
|
||||
cmsUInt32Number nTotalPoints;
|
||||
cmsFloat32Number In[cmsMAXCHANNELS];
|
||||
|
||||
if (nInputs >= cmsMAXCHANNELS) return FALSE;
|
||||
@ -938,10 +945,10 @@ cmsInt32Number CMSEXPORT cmsSliceSpaceFloat(cmsUInt32Number nInputs, const cmsUI
|
||||
nTotalPoints = CubeSize(clutPoints, nInputs);
|
||||
if (nTotalPoints == 0) return FALSE;
|
||||
|
||||
for (i = 0; i < nTotalPoints; i++) {
|
||||
for (i = 0; i < (int) nTotalPoints; i++) {
|
||||
|
||||
rest = i;
|
||||
for (t = nInputs-1; t >=0; --t) {
|
||||
for (t = (int) nInputs-1; t >=0; --t) {
|
||||
|
||||
cmsUInt32Number Colorant = rest % clutPoints[t];
|
||||
|
||||
@ -991,7 +998,7 @@ void EvaluateLab2XYZ(const cmsFloat32Number In[],
|
||||
|
||||
|
||||
// No dup or free routines needed, as the structure has no pointers in it.
|
||||
cmsStage* _cmsStageAllocLab2XYZ(cmsContext ContextID)
|
||||
cmsStage* CMSEXPORT _cmsStageAllocLab2XYZ(cmsContext ContextID)
|
||||
{
|
||||
return _cmsStageAllocPlaceholder(ContextID, cmsSigLab2XYZElemType, 3, 3, EvaluateLab2XYZ, NULL, NULL, NULL);
|
||||
}
|
||||
@ -1021,7 +1028,7 @@ cmsStage* _cmsStageAllocLabV2ToV4curves(cmsContext ContextID)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// We need to map * (0xffff / 0xff00), thats same as (257 / 256)
|
||||
// We need to map * (0xffff / 0xff00), that's same as (257 / 256)
|
||||
// So we can use 258-entry tables to do the trick (i / 257) * (255 * 257) * (257 / 256);
|
||||
for (i=0; i < 257; i++) {
|
||||
|
||||
@ -1042,7 +1049,7 @@ cmsStage* _cmsStageAllocLabV2ToV4curves(cmsContext ContextID)
|
||||
// ********************************************************************************
|
||||
|
||||
// Matrix-based conversion, which is more accurate, but slower and cannot properly be saved in devicelink profiles
|
||||
cmsStage* _cmsStageAllocLabV2ToV4(cmsContext ContextID)
|
||||
cmsStage* CMSEXPORT _cmsStageAllocLabV2ToV4(cmsContext ContextID)
|
||||
{
|
||||
static const cmsFloat64Number V2ToV4[] = { 65535.0/65280.0, 0, 0,
|
||||
0, 65535.0/65280.0, 0,
|
||||
@ -1058,7 +1065,7 @@ cmsStage* _cmsStageAllocLabV2ToV4(cmsContext ContextID)
|
||||
|
||||
|
||||
// Reverse direction
|
||||
cmsStage* _cmsStageAllocLabV4ToV2(cmsContext ContextID)
|
||||
cmsStage* CMSEXPORT _cmsStageAllocLabV4ToV2(cmsContext ContextID)
|
||||
{
|
||||
static const cmsFloat64Number V4ToV2[] = { 65280.0/65535.0, 0, 0,
|
||||
0, 65280.0/65535.0, 0,
|
||||
@ -1166,7 +1173,7 @@ void Clipper(const cmsFloat32Number In[], cmsFloat32Number Out[], const cmsStage
|
||||
}
|
||||
}
|
||||
|
||||
cmsStage* _cmsStageClipNegatives(cmsContext ContextID, int nChannels)
|
||||
cmsStage* _cmsStageClipNegatives(cmsContext ContextID, cmsUInt32Number nChannels)
|
||||
{
|
||||
return _cmsStageAllocPlaceholder(ContextID, cmsSigClipNegativesElemType,
|
||||
nChannels, nChannels, Clipper, NULL, NULL, NULL);
|
||||
@ -1201,7 +1208,7 @@ void EvaluateXYZ2Lab(const cmsFloat32Number In[], cmsFloat32Number Out[], const
|
||||
cmsUNUSED_PARAMETER(mpe);
|
||||
}
|
||||
|
||||
cmsStage* _cmsStageAllocXYZ2Lab(cmsContext ContextID)
|
||||
cmsStage* CMSEXPORT _cmsStageAllocXYZ2Lab(cmsContext ContextID)
|
||||
{
|
||||
return _cmsStageAllocPlaceholder(ContextID, cmsSigXYZ2LabElemType, 3, 3, EvaluateXYZ2Lab, NULL, NULL, NULL);
|
||||
|
||||
@ -1300,23 +1307,42 @@ cmsStage* CMSEXPORT cmsStageDup(cmsStage* mpe)
|
||||
// ***********************************************************************************************************
|
||||
|
||||
// This function sets up the channel count
|
||||
|
||||
static
|
||||
void BlessLUT(cmsPipeline* lut)
|
||||
cmsBool BlessLUT(cmsPipeline* lut)
|
||||
{
|
||||
// We can set the input/ouput channels only if we have elements.
|
||||
// We can set the input/output channels only if we have elements.
|
||||
if (lut ->Elements != NULL) {
|
||||
|
||||
cmsStage *First, *Last;
|
||||
cmsStage* prev;
|
||||
cmsStage* next;
|
||||
cmsStage* First;
|
||||
cmsStage* Last;
|
||||
|
||||
First = cmsPipelineGetPtrToFirstStage(lut);
|
||||
Last = cmsPipelineGetPtrToLastStage(lut);
|
||||
|
||||
if (First != NULL)lut ->InputChannels = First ->InputChannels;
|
||||
if (Last != NULL) lut ->OutputChannels = Last ->OutputChannels;
|
||||
if (First == NULL || Last == NULL) return FALSE;
|
||||
|
||||
lut->InputChannels = First->InputChannels;
|
||||
lut->OutputChannels = Last->OutputChannels;
|
||||
|
||||
// Check chain consistency
|
||||
prev = First;
|
||||
next = prev->Next;
|
||||
|
||||
while (next != NULL)
|
||||
{
|
||||
if (next->InputChannels != prev->OutputChannels)
|
||||
return FALSE;
|
||||
|
||||
next = next->Next;
|
||||
prev = prev->Next;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Default to evaluate the LUT on 16 bit-basis. Precision is retained.
|
||||
static
|
||||
@ -1368,21 +1394,18 @@ void _LUTevalFloat(register const cmsFloat32Number In[], register cmsFloat32Numb
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// LUT Creation & Destruction
|
||||
|
||||
cmsPipeline* CMSEXPORT cmsPipelineAlloc(cmsContext ContextID, cmsUInt32Number InputChannels, cmsUInt32Number OutputChannels)
|
||||
{
|
||||
cmsPipeline* NewLUT;
|
||||
|
||||
// A value of zero in channels is allowed as placeholder
|
||||
if (InputChannels >= cmsMAXCHANNELS ||
|
||||
OutputChannels >= cmsMAXCHANNELS) return NULL;
|
||||
|
||||
NewLUT = (cmsPipeline*) _cmsMallocZero(ContextID, sizeof(cmsPipeline));
|
||||
if (NewLUT == NULL) return NULL;
|
||||
|
||||
|
||||
NewLUT -> InputChannels = InputChannels;
|
||||
NewLUT -> OutputChannels = OutputChannels;
|
||||
|
||||
@ -1393,7 +1416,11 @@ cmsPipeline* CMSEXPORT cmsPipelineAlloc(cmsContext ContextID, cmsUInt32Number In
|
||||
NewLUT ->Data = NewLUT;
|
||||
NewLUT ->ContextID = ContextID;
|
||||
|
||||
BlessLUT(NewLUT);
|
||||
if (!BlessLUT(NewLUT))
|
||||
{
|
||||
_cmsFree(ContextID, NewLUT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NewLUT;
|
||||
}
|
||||
@ -1500,7 +1527,12 @@ cmsPipeline* CMSEXPORT cmsPipelineDup(const cmsPipeline* lut)
|
||||
|
||||
NewLUT ->SaveAs8Bits = lut ->SaveAs8Bits;
|
||||
|
||||
BlessLUT(NewLUT);
|
||||
if (!BlessLUT(NewLUT))
|
||||
{
|
||||
_cmsFree(lut->ContextID, NewLUT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NewLUT;
|
||||
}
|
||||
|
||||
@ -1537,8 +1569,7 @@ int CMSEXPORT cmsPipelineInsertStage(cmsPipeline* lut, cmsStageLoc loc, cmsStage
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BlessLUT(lut);
|
||||
return TRUE;
|
||||
return BlessLUT(lut);
|
||||
}
|
||||
|
||||
// Unlink an element and return the pointer to it
|
||||
@ -1593,6 +1624,7 @@ void CMSEXPORT cmsPipelineUnlinkStage(cmsPipeline* lut, cmsStageLoc loc, cmsStag
|
||||
else
|
||||
cmsStageFree(Unlinked);
|
||||
|
||||
// May fail, but we ignore it
|
||||
BlessLUT(lut);
|
||||
}
|
||||
|
||||
@ -1619,8 +1651,7 @@ cmsBool CMSEXPORT cmsPipelineCat(cmsPipeline* l1, const cmsPipeline* l2)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BlessLUT(l1);
|
||||
return TRUE;
|
||||
return BlessLUT(l1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
@ -156,7 +156,7 @@ int SearchMLUEntry(cmsMLU* mlu, cmsUInt16Number LanguageCode, cmsUInt16Number Co
|
||||
for (i=0; i < mlu ->UsedEntries; i++) {
|
||||
|
||||
if (mlu ->Entries[i].Country == CountryCode &&
|
||||
mlu ->Entries[i].Language == LanguageCode) return i;
|
||||
mlu ->Entries[i].Language == LanguageCode) return (int) i;
|
||||
}
|
||||
|
||||
// Not found
|
||||
@ -207,31 +207,24 @@ cmsBool AddMLUBlock(cmsMLU* mlu, cmsUInt32Number size, const wchar_t *Block,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Convert from a 3-char code to a cmsUInt16Number. It is done inthis way because some
|
||||
// Convert from a 3-char code to a cmsUInt16Number. It is done in this way because some
|
||||
// compilers don't properly align beginning of strings
|
||||
|
||||
static
|
||||
cmsUInt16Number strTo16(const char str[3])
|
||||
{
|
||||
cmsUInt16Number n = ((cmsUInt16Number) str[0] << 8) | str[1];
|
||||
const cmsUInt8Number* ptr8 = (const cmsUInt8Number*)str;
|
||||
cmsUInt16Number n = (cmsUInt16Number)(((cmsUInt16Number)ptr8[0] << 8) | ptr8[1]);
|
||||
|
||||
return n; // Always big endian in this case
|
||||
return n;
|
||||
}
|
||||
|
||||
static
|
||||
void strFrom16(char str[3], cmsUInt16Number n)
|
||||
{
|
||||
// Assiming this would be aligned
|
||||
union {
|
||||
|
||||
cmsUInt16Number n;
|
||||
char str[2];
|
||||
|
||||
} c;
|
||||
|
||||
c.n = n; // Always big endian in this case
|
||||
|
||||
str[0] = c.str[0]; str[1] = c.str[1]; str[2] = 0;
|
||||
str[0] = (char)(n >> 8);
|
||||
str[1] = (char)n;
|
||||
str[2] = (char)0;
|
||||
|
||||
}
|
||||
|
||||
@ -354,7 +347,7 @@ const wchar_t* _cmsMLUgetWide(const cmsMLU* mlu,
|
||||
cmsUInt16Number* UsedLanguageCode, cmsUInt16Number* UsedCountryCode)
|
||||
{
|
||||
cmsUInt32Number i;
|
||||
cmsInt32Number Best = -1;
|
||||
int Best = -1;
|
||||
_cmsMLUentry* v;
|
||||
|
||||
if (mlu == NULL) return NULL;
|
||||
@ -367,7 +360,7 @@ const wchar_t* _cmsMLUgetWide(const cmsMLU* mlu,
|
||||
|
||||
if (v -> Language == LanguageCode) {
|
||||
|
||||
if (Best == -1) Best = i;
|
||||
if (Best == -1) Best = (int) i;
|
||||
|
||||
if (v -> Country == CountryCode) {
|
||||
|
||||
@ -633,10 +626,10 @@ cmsBool CMSEXPORT cmsAppendNamedColor(cmsNAMEDCOLORLIST* NamedColorList,
|
||||
}
|
||||
|
||||
for (i=0; i < NamedColorList ->ColorantCount; i++)
|
||||
NamedColorList ->List[NamedColorList ->nColors].DeviceColorant[i] = Colorant == NULL? 0 : Colorant[i];
|
||||
NamedColorList ->List[NamedColorList ->nColors].DeviceColorant[i] = Colorant == NULL ? (cmsUInt16Number)0 : Colorant[i];
|
||||
|
||||
for (i=0; i < 3; i++)
|
||||
NamedColorList ->List[NamedColorList ->nColors].PCS[i] = PCS == NULL ? 0 : PCS[i];
|
||||
NamedColorList ->List[NamedColorList ->nColors].PCS[i] = PCS == NULL ? (cmsUInt16Number) 0 : PCS[i];
|
||||
|
||||
if (Name != NULL) {
|
||||
|
||||
@ -671,6 +664,7 @@ cmsBool CMSEXPORT cmsNamedColorInfo(const cmsNAMEDCOLORLIST* NamedColorList, cm
|
||||
|
||||
if (nColor >= cmsNamedColorCount(NamedColorList)) return FALSE;
|
||||
|
||||
// strcpy instead of strncpy because many apps are using small buffers
|
||||
if (Name) strcpy(Name, NamedColorList->List[nColor].Name);
|
||||
if (Prefix) strcpy(Prefix, NamedColorList->Prefix);
|
||||
if (Suffix) strcpy(Suffix, NamedColorList->Suffix);
|
||||
@ -688,13 +682,14 @@ 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;
|
||||
cmsUInt32Number i;
|
||||
cmsUInt32Number n;
|
||||
|
||||
if (NamedColorList == NULL) return -1;
|
||||
n = cmsNamedColorCount(NamedColorList);
|
||||
for (i=0; i < n; i++) {
|
||||
if (cmsstrcasecmp(Name, NamedColorList->List[i].Name) == 0)
|
||||
return i;
|
||||
return (cmsInt32Number) i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
@ -723,7 +718,8 @@ void EvalNamedColorPCS(const cmsFloat32Number In[], cmsFloat32Number Out[], cons
|
||||
cmsUInt16Number index = (cmsUInt16Number) _cmsQuickSaturateWord(In[0] * 65535.0);
|
||||
|
||||
if (index >= NamedColorList-> nColors) {
|
||||
cmsSignalError(NamedColorList ->ContextID, cmsERROR_RANGE, "Color %d out of range; ignored", index);
|
||||
cmsSignalError(NamedColorList ->ContextID, cmsERROR_RANGE, "Color %d out of range", index);
|
||||
Out[0] = Out[1] = Out[2] = 0.0f;
|
||||
}
|
||||
else {
|
||||
|
||||
@ -742,7 +738,10 @@ void EvalNamedColor(const cmsFloat32Number In[], cmsFloat32Number Out[], const c
|
||||
cmsUInt32Number j;
|
||||
|
||||
if (index >= NamedColorList-> nColors) {
|
||||
cmsSignalError(NamedColorList ->ContextID, cmsERROR_RANGE, "Color %d out of range; ignored", index);
|
||||
cmsSignalError(NamedColorList ->ContextID, cmsERROR_RANGE, "Color %d out of range", index);
|
||||
for (j = 0; j < NamedColorList->ColorantCount; j++)
|
||||
Out[j] = 0.0f;
|
||||
|
||||
}
|
||||
else {
|
||||
for (j=0; j < NamedColorList ->ColorantCount; j++)
|
||||
@ -752,7 +751,7 @@ void EvalNamedColor(const cmsFloat32Number In[], cmsFloat32Number Out[], const c
|
||||
|
||||
|
||||
// Named color lookup element
|
||||
cmsStage* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS)
|
||||
cmsStage* CMSEXPORT _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS)
|
||||
{
|
||||
return _cmsStageAllocPlaceholder(NamedColorList ->ContextID,
|
||||
cmsSigNamedColorElemType,
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
@ -78,8 +78,8 @@ typedef struct {
|
||||
cmsContext ContextID;
|
||||
|
||||
// Number of channels
|
||||
int nInputs;
|
||||
int nOutputs;
|
||||
cmsUInt32Number nInputs;
|
||||
cmsUInt32Number nOutputs;
|
||||
|
||||
_cmsInterpFn16 EvalCurveIn16[MAX_INPUT_DIMENSIONS]; // The maximum number of input channels is known in advance
|
||||
cmsInterpParams* ParamsCurveIn16[MAX_INPUT_DIMENSIONS];
|
||||
@ -123,8 +123,8 @@ typedef struct {
|
||||
|
||||
cmsContext ContextID;
|
||||
|
||||
int nCurves; // Number of curves
|
||||
int nElements; // Elements in curves
|
||||
cmsUInt32Number nCurves; // Number of curves
|
||||
cmsUInt32Number nElements; // Elements in curves
|
||||
cmsUInt16Number** Curves; // Points to a dynamically allocated array
|
||||
|
||||
} Curves16Data;
|
||||
@ -245,7 +245,7 @@ cmsBool _MultiplyMatrix(cmsPipeline* Lut)
|
||||
// Multiply both matrices to get the result
|
||||
_cmsMAT3per(&res, (cmsMAT3*)m2->Double, (cmsMAT3*)m1->Double);
|
||||
|
||||
// Get the next in chain afer the matrices
|
||||
// Get the next in chain after the matrices
|
||||
chain = (*pt2)->Next;
|
||||
|
||||
// Remove both matrices
|
||||
@ -334,7 +334,7 @@ void PrelinEval16(register const cmsUInt16Number Input[],
|
||||
Prelin16Data* p16 = (Prelin16Data*) D;
|
||||
cmsUInt16Number StageABC[MAX_INPUT_DIMENSIONS];
|
||||
cmsUInt16Number StageDEF[cmsMAXCHANNELS];
|
||||
int i;
|
||||
cmsUInt32Number i;
|
||||
|
||||
for (i=0; i < p16 ->nInputs; i++) {
|
||||
|
||||
@ -379,15 +379,15 @@ void* Prelin16dup(cmsContext ContextID, const void* ptr)
|
||||
static
|
||||
Prelin16Data* PrelinOpt16alloc(cmsContext ContextID,
|
||||
const cmsInterpParams* ColorMap,
|
||||
int nInputs, cmsToneCurve** In,
|
||||
int nOutputs, cmsToneCurve** Out )
|
||||
cmsUInt32Number nInputs, cmsToneCurve** In,
|
||||
cmsUInt32Number nOutputs, cmsToneCurve** Out )
|
||||
{
|
||||
int i;
|
||||
cmsUInt32Number i;
|
||||
Prelin16Data* p16 = (Prelin16Data*)_cmsMallocZero(ContextID, sizeof(Prelin16Data));
|
||||
if (p16 == NULL) return NULL;
|
||||
|
||||
p16 ->nInputs = nInputs;
|
||||
p16 -> nOutputs = nOutputs;
|
||||
p16 ->nOutputs = nOutputs;
|
||||
|
||||
|
||||
for (i=0; i < nInputs; i++) {
|
||||
@ -435,7 +435,7 @@ Prelin16Data* PrelinOpt16alloc(cmsContext ContextID,
|
||||
// Sampler implemented by another LUT. This is a clean way to precalculate the devicelink 3D CLUT for
|
||||
// almost any transform. We use floating point precision and then convert from floating point to 16 bits.
|
||||
static
|
||||
int XFormSampler16(register const cmsUInt16Number In[], register cmsUInt16Number Out[], register void* Cargo)
|
||||
cmsInt32Number XFormSampler16(register const cmsUInt16Number In[], register cmsUInt16Number Out[], register void* Cargo)
|
||||
{
|
||||
cmsPipeline* Lut = (cmsPipeline*) Cargo;
|
||||
cmsFloat32Number InFloat[cmsMAXCHANNELS], OutFloat[cmsMAXCHANNELS];
|
||||
@ -482,7 +482,7 @@ cmsBool AllCurvesAreLinear(cmsStage* mpe)
|
||||
// is to fix scum dot on broken profiles/transforms. Works on 1, 3 and 4 channels
|
||||
static
|
||||
cmsBool PatchLUT(cmsStage* CLUT, cmsUInt16Number At[], cmsUInt16Number Value[],
|
||||
int nChannelsOut, int nChannelsIn)
|
||||
cmsUInt32Number nChannelsOut, cmsUInt32Number nChannelsIn)
|
||||
{
|
||||
_cmsStageCLutData* Grid = (_cmsStageCLutData*) CLUT ->Data;
|
||||
cmsInterpParams* p16 = Grid ->Params;
|
||||
@ -512,10 +512,10 @@ cmsBool PatchLUT(cmsStage* CLUT, cmsUInt16Number At[], cmsUInt16Number Value[],
|
||||
((pz - z0) != 0) ||
|
||||
((pw - w0) != 0)) return FALSE; // Not on exact node
|
||||
|
||||
index = p16 -> opta[3] * x0 +
|
||||
p16 -> opta[2] * y0 +
|
||||
p16 -> opta[1] * z0 +
|
||||
p16 -> opta[0] * w0;
|
||||
index = (int) p16 -> opta[3] * x0 +
|
||||
(int) p16 -> opta[2] * y0 +
|
||||
(int) p16 -> opta[1] * z0 +
|
||||
(int) p16 -> opta[0] * w0;
|
||||
}
|
||||
else
|
||||
if (nChannelsIn == 3) {
|
||||
@ -532,9 +532,9 @@ cmsBool PatchLUT(cmsStage* CLUT, cmsUInt16Number At[], cmsUInt16Number Value[],
|
||||
((py - y0) != 0) ||
|
||||
((pz - z0) != 0)) return FALSE; // Not on exact node
|
||||
|
||||
index = p16 -> opta[2] * x0 +
|
||||
p16 -> opta[1] * y0 +
|
||||
p16 -> opta[0] * z0;
|
||||
index = (int) p16 -> opta[2] * x0 +
|
||||
(int) p16 -> opta[1] * y0 +
|
||||
(int) p16 -> opta[0] * z0;
|
||||
}
|
||||
else
|
||||
if (nChannelsIn == 1) {
|
||||
@ -545,24 +545,24 @@ cmsBool PatchLUT(cmsStage* CLUT, cmsUInt16Number At[], cmsUInt16Number Value[],
|
||||
|
||||
if (((px - x0) != 0)) return FALSE; // Not on exact node
|
||||
|
||||
index = p16 -> opta[0] * x0;
|
||||
index = (int) p16 -> opta[0] * x0;
|
||||
}
|
||||
else {
|
||||
cmsSignalError(CLUT->ContextID, cmsERROR_INTERNAL, "(internal) %d Channels are not supported on PatchLUT", nChannelsIn);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (i=0; i < nChannelsOut; i++)
|
||||
Grid -> Tab.T[index + i] = Value[i];
|
||||
for (i = 0; i < (int) nChannelsOut; i++)
|
||||
Grid->Tab.T[index + i] = Value[i];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Auxiliary, to see if two values are equal or very different
|
||||
static
|
||||
cmsBool WhitesAreEqual(int n, cmsUInt16Number White1[], cmsUInt16Number White2[] )
|
||||
cmsBool WhitesAreEqual(cmsUInt32Number n, cmsUInt16Number White1[], cmsUInt16Number White2[] )
|
||||
{
|
||||
int i;
|
||||
cmsUInt32Number i;
|
||||
|
||||
for (i=0; i < n; i++) {
|
||||
|
||||
@ -664,7 +664,7 @@ cmsBool OptimizeByResampling(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3
|
||||
cmsStage* mpe;
|
||||
cmsStage* CLUT;
|
||||
cmsStage *KeepPreLin = NULL, *KeepPostLin = NULL;
|
||||
int nGridPoints;
|
||||
cmsUInt32Number nGridPoints;
|
||||
cmsColorSpaceSignature ColorSpace, OutputColorSpace;
|
||||
cmsStage *NewPreLin = NULL;
|
||||
cmsStage *NewPostLin = NULL;
|
||||
@ -676,8 +676,13 @@ cmsBool OptimizeByResampling(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3
|
||||
// This is a loosy optimization! does not apply in floating-point cases
|
||||
if (_cmsFormatterIsFloat(*InputFormat) || _cmsFormatterIsFloat(*OutputFormat)) return FALSE;
|
||||
|
||||
ColorSpace = _cmsICCcolorSpace(T_COLORSPACE(*InputFormat));
|
||||
OutputColorSpace = _cmsICCcolorSpace(T_COLORSPACE(*OutputFormat));
|
||||
ColorSpace = _cmsICCcolorSpace((int) T_COLORSPACE(*InputFormat));
|
||||
OutputColorSpace = _cmsICCcolorSpace((int) T_COLORSPACE(*OutputFormat));
|
||||
|
||||
// Color space must be specified
|
||||
if (ColorSpace == (cmsColorSpaceSignature)0 ||
|
||||
OutputColorSpace == (cmsColorSpaceSignature)0) return FALSE;
|
||||
|
||||
nGridPoints = _cmsReasonableGridpointsByColorspace(ColorSpace, *dwFlags);
|
||||
|
||||
// For empty LUTs, 2 points are enough
|
||||
@ -715,7 +720,7 @@ cmsBool OptimizeByResampling(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3
|
||||
goto Error;
|
||||
|
||||
// Remove prelinearization. Since we have duplicated the curve
|
||||
// in destination LUT, the sampling shoud be applied after this stage.
|
||||
// in destination LUT, the sampling should be applied after this stage.
|
||||
cmsPipelineUnlinkStage(Src, cmsAT_BEGIN, &KeepPreLin);
|
||||
}
|
||||
}
|
||||
@ -723,7 +728,7 @@ cmsBool OptimizeByResampling(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3
|
||||
|
||||
// Allocate the CLUT
|
||||
CLUT = cmsStageAllocCLut16bit(Src ->ContextID, nGridPoints, Src ->InputChannels, Src->OutputChannels, NULL);
|
||||
if (CLUT == NULL) return FALSE;
|
||||
if (CLUT == NULL) goto Error;
|
||||
|
||||
// Add the CLUT to the destination LUT
|
||||
if (!cmsPipelineInsertStage(Dest, cmsAT_END, CLUT)) {
|
||||
@ -747,14 +752,14 @@ cmsBool OptimizeByResampling(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3
|
||||
if (!cmsPipelineInsertStage(Dest, cmsAT_END, NewPostLin))
|
||||
goto Error;
|
||||
|
||||
// In destination LUT, the sampling shoud be applied after this stage.
|
||||
// In destination LUT, the sampling should be applied after this stage.
|
||||
cmsPipelineUnlinkStage(Src, cmsAT_END, &KeepPostLin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now its time to do the sampling. We have to ignore pre/post linearization
|
||||
// The source LUT whithout pre/post curves is passed as parameter.
|
||||
// The source LUT without pre/post curves is passed as parameter.
|
||||
if (!cmsStageSampleCLut16bit(CLUT, XFormSampler16, (void*) Src, 0)) {
|
||||
Error:
|
||||
// Ops, something went wrong, Restore stages
|
||||
@ -834,7 +839,7 @@ void SlopeLimiting(cmsToneCurve* g)
|
||||
{
|
||||
int BeginVal, EndVal;
|
||||
int AtBegin = (int) floor((cmsFloat64Number) g ->nEntries * 0.02 + 0.5); // Cutoff at 2%
|
||||
int AtEnd = g ->nEntries - AtBegin - 1; // And 98%
|
||||
int AtEnd = (int) g ->nEntries - AtBegin - 1; // And 98%
|
||||
cmsFloat64Number Val, Slope, beta;
|
||||
int i;
|
||||
|
||||
@ -895,9 +900,9 @@ Prelin8Data* PrelinOpt8alloc(cmsContext ContextID, const cmsInterpParams* p, cms
|
||||
|
||||
|
||||
// Move to 0..1.0 in fixed domain
|
||||
v1 = _cmsToFixedDomain(Input[0] * p -> Domain[0]);
|
||||
v2 = _cmsToFixedDomain(Input[1] * p -> Domain[1]);
|
||||
v3 = _cmsToFixedDomain(Input[2] * p -> Domain[2]);
|
||||
v1 = _cmsToFixedDomain((int) (Input[0] * p -> Domain[0]));
|
||||
v2 = _cmsToFixedDomain((int) (Input[1] * p -> Domain[1]));
|
||||
v3 = _cmsToFixedDomain((int) (Input[2] * p -> Domain[2]));
|
||||
|
||||
// Store the precalculated table of nodes
|
||||
p8 ->X0[i] = (p->opta[2] * FIXED_TO_INT(v1));
|
||||
@ -942,27 +947,27 @@ void PrelinEval8(register const cmsUInt16Number Input[],
|
||||
cmsS15Fixed16Number rx, ry, rz;
|
||||
cmsS15Fixed16Number c0, c1, c2, c3, Rest;
|
||||
int OutChan;
|
||||
register cmsS15Fixed16Number X0, X1, Y0, Y1, Z0, Z1;
|
||||
register cmsS15Fixed16Number X0, X1, Y0, Y1, Z0, Z1;
|
||||
Prelin8Data* p8 = (Prelin8Data*) D;
|
||||
register const cmsInterpParams* p = p8 ->p;
|
||||
int TotalOut = p -> nOutputs;
|
||||
int TotalOut = (int) p -> nOutputs;
|
||||
const cmsUInt16Number* LutTable = (const cmsUInt16Number*) p->Table;
|
||||
|
||||
r = Input[0] >> 8;
|
||||
g = Input[1] >> 8;
|
||||
b = Input[2] >> 8;
|
||||
r = (cmsUInt8Number) (Input[0] >> 8);
|
||||
g = (cmsUInt8Number) (Input[1] >> 8);
|
||||
b = (cmsUInt8Number) (Input[2] >> 8);
|
||||
|
||||
X0 = X1 = p8->X0[r];
|
||||
Y0 = Y1 = p8->Y0[g];
|
||||
Z0 = Z1 = p8->Z0[b];
|
||||
X0 = X1 = (cmsS15Fixed16Number) p8->X0[r];
|
||||
Y0 = Y1 = (cmsS15Fixed16Number) p8->Y0[g];
|
||||
Z0 = Z1 = (cmsS15Fixed16Number) p8->Z0[b];
|
||||
|
||||
rx = p8 ->rx[r];
|
||||
ry = p8 ->ry[g];
|
||||
rz = p8 ->rz[b];
|
||||
|
||||
X1 = X0 + ((rx == 0) ? 0 : p ->opta[2]);
|
||||
Y1 = Y0 + ((ry == 0) ? 0 : p ->opta[1]);
|
||||
Z1 = Z0 + ((rz == 0) ? 0 : p ->opta[0]);
|
||||
X1 = X0 + (cmsS15Fixed16Number)((rx == 0) ? 0 : p ->opta[2]);
|
||||
Y1 = Y0 + (cmsS15Fixed16Number)((ry == 0) ? 0 : p ->opta[1]);
|
||||
Z1 = Z0 + (cmsS15Fixed16Number)((rz == 0) ? 0 : p ->opta[0]);
|
||||
|
||||
|
||||
// These are the 6 Tetrahedral
|
||||
@ -1015,9 +1020,8 @@ void PrelinEval8(register const cmsUInt16Number Input[],
|
||||
c1 = c2 = c3 = 0;
|
||||
}
|
||||
|
||||
|
||||
Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001;
|
||||
Output[OutChan] = (cmsUInt16Number)c0 + ((Rest + (Rest>>16))>>16);
|
||||
Output[OutChan] = (cmsUInt16Number) (c0 + ((Rest + (Rest >> 16)) >> 16));
|
||||
|
||||
}
|
||||
}
|
||||
@ -1029,8 +1033,8 @@ void PrelinEval8(register const cmsUInt16Number Input[],
|
||||
static
|
||||
cmsBool IsDegenerated(const cmsToneCurve* g)
|
||||
{
|
||||
int i, Zeros = 0, Poles = 0;
|
||||
int nEntries = g ->nEntries;
|
||||
cmsUInt32Number i, Zeros = 0, Poles = 0;
|
||||
cmsUInt32Number nEntries = g ->nEntries;
|
||||
|
||||
for (i=0; i < nEntries; i++) {
|
||||
|
||||
@ -1052,7 +1056,7 @@ static
|
||||
cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt32Number* InputFormat, cmsUInt32Number* OutputFormat, cmsUInt32Number* dwFlags)
|
||||
{
|
||||
cmsPipeline* OriginalLut;
|
||||
int nGridPoints;
|
||||
cmsUInt32Number nGridPoints;
|
||||
cmsToneCurve *Trans[cmsMAXCHANNELS], *TransReverse[cmsMAXCHANNELS];
|
||||
cmsUInt32Number t, i;
|
||||
cmsFloat32Number v, In[cmsMAXCHANNELS], Out[cmsMAXCHANNELS];
|
||||
@ -1090,8 +1094,13 @@ cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Inte
|
||||
if (cmsStageType(mpe) == cmsSigNamedColorElemType) return FALSE;
|
||||
}
|
||||
|
||||
ColorSpace = _cmsICCcolorSpace(T_COLORSPACE(*InputFormat));
|
||||
OutputColorSpace = _cmsICCcolorSpace(T_COLORSPACE(*OutputFormat));
|
||||
ColorSpace = _cmsICCcolorSpace((int) T_COLORSPACE(*InputFormat));
|
||||
OutputColorSpace = _cmsICCcolorSpace((int) T_COLORSPACE(*OutputFormat));
|
||||
|
||||
// Color space must be specified
|
||||
if (ColorSpace == (cmsColorSpaceSignature)0 ||
|
||||
OutputColorSpace == (cmsColorSpaceSignature)0) return FALSE;
|
||||
|
||||
nGridPoints = _cmsReasonableGridpointsByColorspace(ColorSpace, *dwFlags);
|
||||
|
||||
// Empty gamma containers
|
||||
@ -1212,7 +1221,10 @@ cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Inte
|
||||
Prelin8Data* p8 = PrelinOpt8alloc(OptimizedLUT ->ContextID,
|
||||
OptimizedPrelinCLUT ->Params,
|
||||
OptimizedPrelinCurves);
|
||||
if (p8 == NULL) return FALSE;
|
||||
if (p8 == NULL) {
|
||||
cmsPipelineFree(OptimizedLUT);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_cmsPipelineSetOptimizationParameters(OptimizedLUT, PrelinEval8, (void*) p8, Prelin8free, Prelin8dup);
|
||||
|
||||
@ -1222,7 +1234,10 @@ cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Inte
|
||||
Prelin16Data* p16 = PrelinOpt16alloc(OptimizedLUT ->ContextID,
|
||||
OptimizedPrelinCLUT ->Params,
|
||||
3, OptimizedPrelinCurves, 3, NULL);
|
||||
if (p16 == NULL) return FALSE;
|
||||
if (p16 == NULL) {
|
||||
cmsPipelineFree(OptimizedLUT);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_cmsPipelineSetOptimizationParameters(OptimizedLUT, PrelinEval16, (void*) p16, PrelinOpt16free, Prelin16dup);
|
||||
|
||||
@ -1260,6 +1275,7 @@ Error:
|
||||
return FALSE;
|
||||
|
||||
cmsUNUSED_PARAMETER(Intent);
|
||||
cmsUNUSED_PARAMETER(lIsLinear);
|
||||
}
|
||||
|
||||
|
||||
@ -1269,7 +1285,7 @@ static
|
||||
void CurvesFree(cmsContext ContextID, void* ptr)
|
||||
{
|
||||
Curves16Data* Data = (Curves16Data*) ptr;
|
||||
int i;
|
||||
cmsUInt32Number i;
|
||||
|
||||
for (i=0; i < Data -> nCurves; i++) {
|
||||
|
||||
@ -1284,7 +1300,7 @@ static
|
||||
void* CurvesDup(cmsContext ContextID, const void* ptr)
|
||||
{
|
||||
Curves16Data* Data = (Curves16Data*)_cmsDupMem(ContextID, ptr, sizeof(Curves16Data));
|
||||
int i;
|
||||
cmsUInt32Number i;
|
||||
|
||||
if (Data == NULL) return NULL;
|
||||
|
||||
@ -1299,9 +1315,9 @@ void* CurvesDup(cmsContext ContextID, const void* ptr)
|
||||
|
||||
// Precomputes tables for 8-bit on input devicelink.
|
||||
static
|
||||
Curves16Data* CurvesAlloc(cmsContext ContextID, int nCurves, int nElements, cmsToneCurve** G)
|
||||
Curves16Data* CurvesAlloc(cmsContext ContextID, cmsUInt32Number nCurves, cmsUInt32Number nElements, cmsToneCurve** G)
|
||||
{
|
||||
int i, j;
|
||||
cmsUInt32Number i, j;
|
||||
Curves16Data* c16;
|
||||
|
||||
c16 = (Curves16Data*)_cmsMallocZero(ContextID, sizeof(Curves16Data));
|
||||
@ -1311,7 +1327,10 @@ Curves16Data* CurvesAlloc(cmsContext ContextID, int nCurves, int nElements, cmsT
|
||||
c16 ->nElements = nElements;
|
||||
|
||||
c16->Curves = (cmsUInt16Number**) _cmsCalloc(ContextID, nCurves, sizeof(cmsUInt16Number*));
|
||||
if (c16 ->Curves == NULL) return NULL;
|
||||
if (c16->Curves == NULL) {
|
||||
_cmsFree(ContextID, c16);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i=0; i < nCurves; i++) {
|
||||
|
||||
@ -1327,7 +1346,7 @@ Curves16Data* CurvesAlloc(cmsContext ContextID, int nCurves, int nElements, cmsT
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (nElements == 256) {
|
||||
if (nElements == 256U) {
|
||||
|
||||
for (j=0; j < nElements; j++) {
|
||||
|
||||
@ -1351,8 +1370,8 @@ void FastEvaluateCurves8(register const cmsUInt16Number In[],
|
||||
register const void* D)
|
||||
{
|
||||
Curves16Data* Data = (Curves16Data*) D;
|
||||
cmsUInt8Number x;
|
||||
int i;
|
||||
int x;
|
||||
cmsUInt32Number i;
|
||||
|
||||
for (i=0; i < Data ->nCurves; i++) {
|
||||
|
||||
@ -1368,7 +1387,7 @@ void FastEvaluateCurves16(register const cmsUInt16Number In[],
|
||||
register const void* D)
|
||||
{
|
||||
Curves16Data* Data = (Curves16Data*) D;
|
||||
int i;
|
||||
cmsUInt32Number i;
|
||||
|
||||
for (i=0; i < Data ->nCurves; i++) {
|
||||
Out[i] = Data -> Curves[i][In[i]];
|
||||
@ -1548,9 +1567,9 @@ void MatShaperEval16(register const cmsUInt16Number In[],
|
||||
|
||||
// In this case (and only in this case!) we can use this simplification since
|
||||
// In[] is assured to come from a 8 bit number. (a << 8 | a)
|
||||
ri = In[0] & 0xFF;
|
||||
gi = In[1] & 0xFF;
|
||||
bi = In[2] & 0xFF;
|
||||
ri = In[0] & 0xFFU;
|
||||
gi = In[1] & 0xFFU;
|
||||
bi = In[2] & 0xFFU;
|
||||
|
||||
// Across first shaper, which also converts to 1.14 fixed point
|
||||
r = p->Shaper1R[ri];
|
||||
@ -1563,9 +1582,9 @@ void MatShaperEval16(register const cmsUInt16Number In[],
|
||||
l3 = (p->Mat[2][0] * r + p->Mat[2][1] * g + p->Mat[2][2] * b + p->Off[2] + 0x2000) >> 14;
|
||||
|
||||
// Now we have to clip to 0..1.0 range
|
||||
ri = (l1 < 0) ? 0 : ((l1 > 16384) ? 16384 : l1);
|
||||
gi = (l2 < 0) ? 0 : ((l2 > 16384) ? 16384 : l2);
|
||||
bi = (l3 < 0) ? 0 : ((l3 > 16384) ? 16384 : l3);
|
||||
ri = (l1 < 0) ? 0 : ((l1 > 16384) ? 16384U : (cmsUInt32Number) l1);
|
||||
gi = (l2 < 0) ? 0 : ((l2 > 16384) ? 16384U : (cmsUInt32Number) l2);
|
||||
bi = (l3 < 0) ? 0 : ((l3 > 16384) ? 16384U : (cmsUInt32Number) l3);
|
||||
|
||||
// And across second shaper,
|
||||
Out[0] = p->Shaper2R[ri];
|
||||
@ -1586,7 +1605,10 @@ void FillFirstShaper(cmsS1Fixed14Number* Table, cmsToneCurve* Curve)
|
||||
R = (cmsFloat32Number) (i / 255.0);
|
||||
y = cmsEvalToneCurveFloat(Curve, R);
|
||||
|
||||
Table[i] = DOUBLE_TO_1FIXED14(y);
|
||||
if (y < 131072.0)
|
||||
Table[i] = DOUBLE_TO_1FIXED14(y);
|
||||
else
|
||||
Table[i] = 0x7fffffff;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1602,6 +1624,12 @@ void FillSecondShaper(cmsUInt16Number* Table, cmsToneCurve* Curve, cmsBool Is8Bi
|
||||
R = (cmsFloat32Number) (i / 16384.0);
|
||||
Val = cmsEvalToneCurveFloat(Curve, R); // Val comes 0..1.0
|
||||
|
||||
if (Val < 0)
|
||||
Val = 0;
|
||||
|
||||
if (Val > 1.0)
|
||||
Val = 1.0;
|
||||
|
||||
if (Is8BitsOutput) {
|
||||
|
||||
// If 8 bits output, we can optimize further by computing the / 257 part.
|
||||
@ -1640,7 +1668,7 @@ cmsBool SetMatShaper(cmsPipeline* Dest, cmsToneCurve* Curve1[3], cmsMAT3* Mat, c
|
||||
FillSecondShaper(p ->Shaper2G, Curve2[1], Is8Bits);
|
||||
FillSecondShaper(p ->Shaper2B, Curve2[2], Is8Bits);
|
||||
|
||||
// Convert matrix to nFixed14. Note that those values may take more than 16 bits as
|
||||
// Convert matrix to nFixed14. Note that those values may take more than 16 bits
|
||||
for (i=0; i < 3; i++) {
|
||||
for (j=0; j < 3; j++) {
|
||||
p ->Mat[i][j] = DOUBLE_TO_1FIXED14(Mat->v[i].n[j]);
|
||||
@ -1902,7 +1930,7 @@ cmsBool _cmsRegisterOptimizationPlugin(cmsContext ContextID, cmsPluginBase* Dat
|
||||
// The entry point for LUT optimization
|
||||
cmsBool _cmsOptimizePipeline(cmsContext ContextID,
|
||||
cmsPipeline** PtrLut,
|
||||
int Intent,
|
||||
cmsUInt32Number Intent,
|
||||
cmsUInt32Number* InputFormat,
|
||||
cmsUInt32Number* OutputFormat,
|
||||
cmsUInt32Number* dwFlags)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -30,7 +30,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
@ -685,9 +685,9 @@ cmsFloat64Number CMSEXPORT cmsCIE2000DeltaE(const cmsCIELab* Lab1, const cmsCIEL
|
||||
|
||||
// This function returns a number of gridpoints to be used as LUT table. It assumes same number
|
||||
// of gripdpoints in all dimensions. Flags may override the choice.
|
||||
int _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags)
|
||||
cmsUInt32Number _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags)
|
||||
{
|
||||
int nChannels;
|
||||
cmsUInt32Number nChannels;
|
||||
|
||||
// Already specified?
|
||||
if (dwFlags & 0x00FF0000) {
|
||||
@ -831,7 +831,7 @@ cmsColorSpaceSignature CMSEXPORT _cmsICCcolorSpace(int OurNotation)
|
||||
case PT_MCH14: return cmsSigMCHEData;
|
||||
case PT_MCH15: return cmsSigMCHFData;
|
||||
|
||||
default: return (cmsColorSpaceSignature) (-1);
|
||||
default: return (cmsColorSpaceSignature) 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -898,7 +898,7 @@ int CMSEXPORT _cmsLCMScolorSpace(cmsColorSpaceSignature ProfileSpace)
|
||||
case cmsSigMCHFData:
|
||||
case cmsSig15colorData:return PT_MCH15;
|
||||
|
||||
default: return (cmsColorSpaceSignature) (-1);
|
||||
default: return (cmsColorSpaceSignature) 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
@ -201,14 +201,28 @@ cmsBool CMSEXPORT _cmsReadFloat32Number(cmsIOHANDLER* io, cmsFloat32Number* 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) {
|
||||
|
||||
tmp = _cmsAdjustEndianess32(tmp);
|
||||
*n = *(cmsFloat32Number*) (void*) &tmp;
|
||||
*n = *(cmsFloat32Number*)(void*)&tmp;
|
||||
|
||||
// Safeguard which covers against absurd values
|
||||
if (*n > 1E+20 || *n < -1E+20) return FALSE;
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1800
|
||||
return TRUE;
|
||||
#elif defined (__BORLANDC__)
|
||||
return TRUE;
|
||||
#else
|
||||
|
||||
// fpclassify() required by C99 (only provided by MSVC >= 1800, VS2013 onwards)
|
||||
return ((fpclassify(*n) == FP_ZERO) || (fpclassify(*n) == FP_NORMAL));
|
||||
#endif
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -222,7 +236,11 @@ cmsBool CMSEXPORT _cmsReadUInt64Number(cmsIOHANDLER* io, cmsUInt64Number* n)
|
||||
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;
|
||||
}
|
||||
|
||||
@ -237,7 +255,7 @@ cmsBool CMSEXPORT _cmsRead15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number* n
|
||||
return FALSE;
|
||||
|
||||
if (n != NULL) {
|
||||
*n = _cms15Fixed16toDouble(_cmsAdjustEndianess32(tmp));
|
||||
*n = _cms15Fixed16toDouble((cmsS15Fixed16Number) _cmsAdjustEndianess32(tmp));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@ -254,9 +272,9 @@ cmsBool CMSEXPORT _cmsReadXYZNumber(cmsIOHANDLER* io, cmsCIEXYZ* XYZ)
|
||||
|
||||
if (XYZ != NULL) {
|
||||
|
||||
XYZ->X = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.X));
|
||||
XYZ->Y = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.Y));
|
||||
XYZ->Z = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.Z));
|
||||
XYZ->X = _cms15Fixed16toDouble((cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) xyz.X));
|
||||
XYZ->Y = _cms15Fixed16toDouble((cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) xyz.Y));
|
||||
XYZ->Z = _cms15Fixed16toDouble((cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) xyz.Z));
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@ -345,7 +363,7 @@ cmsBool CMSEXPORT _cmsWrite15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number n
|
||||
|
||||
_cmsAssert(io != NULL);
|
||||
|
||||
tmp = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(n));
|
||||
tmp = _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(n));
|
||||
if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
|
||||
return FALSE;
|
||||
|
||||
@ -359,9 +377,9 @@ cmsBool CMSEXPORT _cmsWriteXYZNumber(cmsIOHANDLER* io, const cmsCIEXYZ* XYZ)
|
||||
_cmsAssert(io != NULL);
|
||||
_cmsAssert(XYZ != NULL);
|
||||
|
||||
xyz.X = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(XYZ->X));
|
||||
xyz.Y = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(XYZ->Y));
|
||||
xyz.Z = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(XYZ->Z));
|
||||
xyz.X = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(XYZ->X));
|
||||
xyz.Y = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(XYZ->Y));
|
||||
xyz.Z = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(XYZ->Z));
|
||||
|
||||
return io -> Write(io, sizeof(cmsEncodedXYZNumber), &xyz);
|
||||
}
|
||||
@ -519,7 +537,7 @@ cmsBool CMSEXPORT _cmsIOPrintf(cmsIOHANDLER* io, const char* frm, ...)
|
||||
return FALSE; // Truncated, which is a fatal error for us
|
||||
}
|
||||
|
||||
rc = io ->Write(io, len, Buffer);
|
||||
rc = io ->Write(io, (cmsUInt32Number) len, Buffer);
|
||||
|
||||
va_end(args);
|
||||
|
||||
@ -779,6 +797,30 @@ cmsContext CMSEXPORT cmsCreateContext(void* Plugin, void* UserData)
|
||||
struct _cmsContext_struct* ctx;
|
||||
struct _cmsContext_struct fakeContext;
|
||||
|
||||
// See the comments regarding locking in lcms2_internal.h
|
||||
// for an explanation of why we need the following code.
|
||||
#ifdef CMS_IS_WINDOWS_
|
||||
#ifndef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT
|
||||
{
|
||||
static HANDLE _cmsWindowsInitMutex = NULL;
|
||||
static volatile HANDLE* mutex = &_cmsWindowsInitMutex;
|
||||
|
||||
if (*mutex == NULL)
|
||||
{
|
||||
HANDLE p = CreateMutex(NULL, FALSE, NULL);
|
||||
if (p && InterlockedCompareExchangePointer((void **)mutex, (void*)p, NULL) != NULL)
|
||||
CloseHandle(p);
|
||||
}
|
||||
if (*mutex == NULL || WaitForSingleObject(*mutex, INFINITE) == WAIT_FAILED)
|
||||
return NULL;
|
||||
if (((void **)&_cmsContextPoolHeadMutex)[0] == NULL)
|
||||
InitializeCriticalSection(&_cmsContextPoolHeadMutex);
|
||||
if (*mutex == NULL || !ReleaseMutex(*mutex))
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
_cmsInstallAllocFunctions(_cmsFindMemoryPlugin(Plugin), &fakeContext.DefaultMemoryManager);
|
||||
|
||||
fakeContext.chunks[UserPtr] = UserData;
|
||||
@ -805,7 +847,7 @@ cmsContext CMSEXPORT cmsCreateContext(void* Plugin, void* 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
|
||||
ctx ->MemPool = _cmsCreateSubAlloc(ctx, 22 * sizeof(void*)); // default size about 22 pointers
|
||||
if (ctx ->MemPool == NULL) {
|
||||
|
||||
cmsDeleteContext(ctx);
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
@ -429,7 +429,7 @@ void EmitRangeCheck(cmsIOHANDLER* m)
|
||||
// Does write the intent
|
||||
|
||||
static
|
||||
void EmitIntent(cmsIOHANDLER* m, int RenderingIntent)
|
||||
void EmitIntent(cmsIOHANDLER* m, cmsUInt32Number RenderingIntent)
|
||||
{
|
||||
const char *intent;
|
||||
|
||||
@ -563,7 +563,7 @@ void Emit1Gamma(cmsIOHANDLER* m, cmsToneCurve* Table)
|
||||
// Compare gamma table
|
||||
|
||||
static
|
||||
cmsBool GammaTableEquals(cmsUInt16Number* g1, cmsUInt16Number* g2, int nEntries)
|
||||
cmsBool GammaTableEquals(cmsUInt16Number* g1, cmsUInt16Number* g2, cmsUInt32Number nEntries)
|
||||
{
|
||||
return memcmp(g1, g2, nEntries* sizeof(cmsUInt16Number)) == 0;
|
||||
}
|
||||
@ -572,9 +572,9 @@ cmsBool GammaTableEquals(cmsUInt16Number* g1, cmsUInt16Number* g2, int nEntries)
|
||||
// Does write a set of gamma curves
|
||||
|
||||
static
|
||||
void EmitNGamma(cmsIOHANDLER* m, int n, cmsToneCurve* g[])
|
||||
void EmitNGamma(cmsIOHANDLER* m, cmsUInt32Number n, cmsToneCurve* g[])
|
||||
{
|
||||
int i;
|
||||
cmsUInt32Number i;
|
||||
|
||||
for( i=0; i < n; i++ )
|
||||
{
|
||||
@ -797,7 +797,7 @@ int EmitCIEBasedABC(cmsIOHANDLER* m, cmsFloat64Number* Matrix, cmsToneCurve** Cu
|
||||
|
||||
|
||||
static
|
||||
int EmitCIEBasedDEF(cmsIOHANDLER* m, cmsPipeline* Pipeline, int Intent, cmsCIEXYZ* BlackPoint)
|
||||
int EmitCIEBasedDEF(cmsIOHANDLER* m, cmsPipeline* Pipeline, cmsUInt32Number Intent, cmsCIEXYZ* BlackPoint)
|
||||
{
|
||||
const char* PreMaj;
|
||||
const char* PostMaj;
|
||||
@ -857,14 +857,14 @@ int EmitCIEBasedDEF(cmsIOHANDLER* m, cmsPipeline* Pipeline, int Intent, cmsCIEXY
|
||||
// Generates a curve from a gray profile
|
||||
|
||||
static
|
||||
cmsToneCurve* ExtractGray2Y(cmsContext ContextID, cmsHPROFILE hProfile, int Intent)
|
||||
cmsToneCurve* ExtractGray2Y(cmsContext ContextID, cmsHPROFILE hProfile, cmsUInt32Number Intent)
|
||||
{
|
||||
cmsToneCurve* Out = cmsBuildTabulatedToneCurve16(ContextID, 256, NULL);
|
||||
cmsHPROFILE hXYZ = cmsCreateXYZProfile();
|
||||
cmsHTRANSFORM xform = cmsCreateTransformTHR(ContextID, hProfile, TYPE_GRAY_8, hXYZ, TYPE_XYZ_DBL, Intent, cmsFLAGS_NOOPTIMIZE);
|
||||
int i;
|
||||
|
||||
if (Out != NULL) {
|
||||
if (Out != NULL && xform != NULL) {
|
||||
for (i=0; i < 256; i++) {
|
||||
|
||||
cmsUInt8Number Gray = (cmsUInt8Number) i;
|
||||
@ -876,8 +876,8 @@ static
|
||||
}
|
||||
}
|
||||
|
||||
cmsDeleteTransform(xform);
|
||||
cmsCloseProfile(hXYZ);
|
||||
if (xform) cmsDeleteTransform(xform);
|
||||
if (hXYZ) cmsCloseProfile(hXYZ);
|
||||
return Out;
|
||||
}
|
||||
|
||||
@ -887,7 +887,7 @@ static
|
||||
// a more perceptually uniform space... I do choose Lab.
|
||||
|
||||
static
|
||||
int WriteInputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, int Intent, cmsUInt32Number dwFlags)
|
||||
int WriteInputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags)
|
||||
{
|
||||
cmsHPROFILE hLab;
|
||||
cmsHTRANSFORM xform;
|
||||
@ -972,7 +972,6 @@ cmsFloat64Number* GetPtrToMatrix(const cmsStage* mpe)
|
||||
|
||||
|
||||
// Does create CSA based on matrix-shaper. Allowed types are gray and RGB based
|
||||
|
||||
static
|
||||
int WriteInputMatrixShaper(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsStage* Matrix, cmsStage* Shaper)
|
||||
{
|
||||
@ -998,17 +997,17 @@ int WriteInputMatrixShaper(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsStage* Matr
|
||||
|
||||
memmove(&Mat, GetPtrToMatrix(Matrix), sizeof(Mat));
|
||||
|
||||
for (i=0; i < 3; i++)
|
||||
for (j=0; j < 3; j++)
|
||||
for (i = 0; i < 3; i++)
|
||||
for (j = 0; j < 3; j++)
|
||||
Mat.v[i].n[j] *= MAX_ENCODEABLE_XYZ;
|
||||
|
||||
rc = EmitCIEBasedABC(m, (cmsFloat64Number *) &Mat,
|
||||
_cmsStageGetPtrToCurveSet(Shaper),
|
||||
&BlackPointAdaptedToD50);
|
||||
rc = EmitCIEBasedABC(m, (cmsFloat64Number *)&Mat,
|
||||
_cmsStageGetPtrToCurveSet(Shaper),
|
||||
&BlackPointAdaptedToD50);
|
||||
}
|
||||
else {
|
||||
else {
|
||||
|
||||
cmsSignalError(m ->ContextID, cmsERROR_COLORSPACE_CHECK, "Profile is not suitable for CSA. Unsupported colorspace.");
|
||||
cmsSignalError(m->ContextID, cmsERROR_COLORSPACE_CHECK, "Profile is not suitable for CSA. Unsupported colorspace.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1021,12 +1020,12 @@ int WriteInputMatrixShaper(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsStage* Matr
|
||||
// This is a HP extension, and it works in Lab instead of XYZ
|
||||
|
||||
static
|
||||
int WriteNamedColorCSA(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, int Intent)
|
||||
int WriteNamedColorCSA(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, cmsUInt32Number Intent)
|
||||
{
|
||||
cmsHTRANSFORM xform;
|
||||
cmsHPROFILE hLab;
|
||||
int i, nColors;
|
||||
char ColorName[32];
|
||||
cmsUInt32Number i, nColors;
|
||||
char ColorName[cmsMAX_PATH];
|
||||
cmsNAMEDCOLORLIST* NamedColorList;
|
||||
|
||||
hLab = cmsCreateLab4ProfileTHR(m ->ContextID, NULL);
|
||||
@ -1304,20 +1303,20 @@ void EmitXYZ2Lab(cmsIOHANDLER* m)
|
||||
// 8 bits.
|
||||
|
||||
static
|
||||
int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, int Intent, cmsUInt32Number dwFlags)
|
||||
int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags)
|
||||
{
|
||||
cmsHPROFILE hLab;
|
||||
cmsHTRANSFORM xform;
|
||||
int i, nChannels;
|
||||
cmsUInt32Number i, nChannels;
|
||||
cmsUInt32Number OutputFormat;
|
||||
_cmsTRANSFORM* v;
|
||||
cmsPipeline* DeviceLink;
|
||||
cmsHPROFILE Profiles[3];
|
||||
cmsCIEXYZ BlackPointAdaptedToD50;
|
||||
cmsBool lDoBPC = (dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION);
|
||||
cmsBool lFixWhite = !(dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP);
|
||||
cmsBool lDoBPC = (cmsBool) (dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION);
|
||||
cmsBool lFixWhite = (cmsBool) !(dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP);
|
||||
cmsUInt32Number InFrm = TYPE_Lab_16;
|
||||
int RelativeEncodingIntent;
|
||||
cmsUInt32Number RelativeEncodingIntent;
|
||||
cmsColorSpaceSignature ColorSpace;
|
||||
|
||||
|
||||
@ -1413,10 +1412,10 @@ int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, int Intent, cmsUInt32N
|
||||
|
||||
// Builds a ASCII string containing colorant list in 0..1.0 range
|
||||
static
|
||||
void BuildColorantList(char *Colorant, int nColorant, cmsUInt16Number Out[])
|
||||
void BuildColorantList(char *Colorant, cmsUInt32Number nColorant, cmsUInt16Number Out[])
|
||||
{
|
||||
char Buff[32];
|
||||
int j;
|
||||
cmsUInt32Number j;
|
||||
|
||||
Colorant[0] = 0;
|
||||
if (nColorant > cmsMAXCHANNELS)
|
||||
@ -1438,12 +1437,12 @@ void BuildColorantList(char *Colorant, int nColorant, cmsUInt16Number Out[])
|
||||
// This is a HP extension.
|
||||
|
||||
static
|
||||
int WriteNamedColorCRD(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, int Intent, cmsUInt32Number dwFlags)
|
||||
int WriteNamedColorCRD(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, cmsUInt32Number Intent, cmsUInt32Number dwFlags)
|
||||
{
|
||||
cmsHTRANSFORM xform;
|
||||
int i, nColors, nColorant;
|
||||
cmsUInt32Number i, nColors, nColorant;
|
||||
cmsUInt32Number OutputFormat;
|
||||
char ColorName[32];
|
||||
char ColorName[cmsMAX_PATH];
|
||||
char Colorant[128];
|
||||
cmsNAMEDCOLORLIST* NamedColorList;
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
@ -89,6 +89,11 @@ typedef struct _cmsTagTypeLinkedList_st {
|
||||
// Helper macro to define a MPE handler. Callbacks do have a fixed naming convention
|
||||
#define TYPE_MPE_HANDLER(t, x) { (t), READ_FN(x), WRITE_FN(x), GenericMPEdup, GenericMPEfree, NULL, 0 }
|
||||
|
||||
// Infinites
|
||||
#define MINUS_INF (-1E22F)
|
||||
#define PLUS_INF (+1E22F)
|
||||
|
||||
|
||||
// Register a new type handler. This routine is shared between normal types and MPE. LinkedList points to the optional list head
|
||||
static
|
||||
cmsBool RegisterTypesPlugin(cmsContext id, cmsPluginBase* Data, _cmsMemoryClient pos)
|
||||
@ -202,6 +207,13 @@ cmsBool ReadPositionTable(struct _cms_typehandler_struct* self,
|
||||
{
|
||||
cmsUInt32Number i;
|
||||
cmsUInt32Number *ElementOffsets = NULL, *ElementSizes = NULL;
|
||||
cmsUInt32Number currentPosition;
|
||||
|
||||
currentPosition = io->Tell(io);
|
||||
|
||||
// Verify there is enough space left to read at least two cmsUInt32Number items for Count items.
|
||||
if (((io->ReportedSize - currentPosition) / (2 * sizeof(cmsUInt32Number))) < Count)
|
||||
return FALSE;
|
||||
|
||||
// Let's take the offsets to each element
|
||||
ElementOffsets = (cmsUInt32Number *) _cmsCalloc(io ->ContextID, Count, sizeof(cmsUInt32Number));
|
||||
@ -424,8 +436,8 @@ Error:
|
||||
static
|
||||
cmsBool SaveOneChromaticity(cmsFloat64Number x, cmsFloat64Number y, cmsIOHANDLER* io)
|
||||
{
|
||||
if (!_cmsWriteUInt32Number(io, _cmsDoubleTo15Fixed16(x))) return FALSE;
|
||||
if (!_cmsWriteUInt32Number(io, _cmsDoubleTo15Fixed16(y))) return FALSE;
|
||||
if (!_cmsWriteUInt32Number(io, (cmsUInt32Number) _cmsDoubleTo15Fixed16(x))) return FALSE;
|
||||
if (!_cmsWriteUInt32Number(io, (cmsUInt32Number) _cmsDoubleTo15Fixed16(y))) return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -984,7 +996,7 @@ cmsBool Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIO
|
||||
cmsBool rc = FALSE;
|
||||
char Filler[68];
|
||||
|
||||
// Used below for writting zeroes
|
||||
// Used below for writing zeroes
|
||||
memset(Filler, 0, sizeof(Filler));
|
||||
|
||||
// Get the len of string
|
||||
@ -1146,7 +1158,10 @@ void *Type_Curve_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cm
|
||||
NewGamma = cmsBuildTabulatedToneCurve16(self ->ContextID, Count, NULL);
|
||||
if (!NewGamma) return NULL;
|
||||
|
||||
if (!_cmsReadUInt16Array(io, Count, NewGamma -> Table16)) return NULL;
|
||||
if (!_cmsReadUInt16Array(io, Count, NewGamma -> Table16)) {
|
||||
cmsFreeToneCurve(NewGamma);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*nItems = 1;
|
||||
return NewGamma;
|
||||
@ -1206,7 +1221,7 @@ void Type_Curve_Free(struct _cms_typehandler_struct* self, void* Ptr)
|
||||
// ********************************************************************************
|
||||
|
||||
|
||||
// Decide which curve type to use on writting
|
||||
// Decide which curve type to use on writing
|
||||
static
|
||||
cmsTagTypeSignature DecideCurveType(cmsFloat64Number ICCVersion, const void *Data)
|
||||
{
|
||||
@ -1599,7 +1614,7 @@ void Type_MLU_Free(struct _cms_typehandler_struct* self, void* Ptr)
|
||||
// Type cmsSigLut8Type
|
||||
// ********************************************************************************
|
||||
|
||||
// Decide which LUT type to use on writting
|
||||
// Decide which LUT type to use on writing
|
||||
static
|
||||
cmsTagTypeSignature DecideLUTtypeA2B(cmsFloat64Number ICCVersion, const void *Data)
|
||||
{
|
||||
@ -1648,10 +1663,10 @@ Byte Position Field Length (bytes) Content Encoded as...
|
||||
|
||||
// Read 8 bit tables as gamma functions
|
||||
static
|
||||
cmsBool Read8bitTables(cmsContext ContextID, cmsIOHANDLER* io, cmsPipeline* lut, int nChannels)
|
||||
cmsBool Read8bitTables(cmsContext ContextID, cmsIOHANDLER* io, cmsPipeline* lut, cmsUInt32Number nChannels)
|
||||
{
|
||||
cmsUInt8Number* Temp = NULL;
|
||||
int i, j;
|
||||
cmsUInt32Number i, j;
|
||||
cmsToneCurve* Tables[cmsMAXCHANNELS];
|
||||
|
||||
if (nChannels > cmsMAXCHANNELS) return FALSE;
|
||||
@ -1784,8 +1799,8 @@ void *Type_LUT8_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cms
|
||||
if (!_cmsReadUInt8Number(io, NULL)) goto Error;
|
||||
|
||||
// Do some checking
|
||||
if (InputChannels > cmsMAXCHANNELS) goto Error;
|
||||
if (OutputChannels > cmsMAXCHANNELS) goto Error;
|
||||
if (InputChannels == 0 || InputChannels > cmsMAXCHANNELS) goto Error;
|
||||
if (OutputChannels == 0 || OutputChannels > cmsMAXCHANNELS) goto Error;
|
||||
|
||||
// Allocates an empty Pipeline
|
||||
NewLUT = cmsPipelineAlloc(self ->ContextID, InputChannels, OutputChannels);
|
||||
@ -1842,8 +1857,10 @@ void *Type_LUT8_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cms
|
||||
_cmsFree(self ->ContextID, Temp);
|
||||
Temp = NULL;
|
||||
|
||||
if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, cmsStageAllocCLut16bit(self ->ContextID, CLUTpoints, InputChannels, OutputChannels, T)))
|
||||
if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, cmsStageAllocCLut16bit(self ->ContextID, CLUTpoints, InputChannels, OutputChannels, T))) {
|
||||
_cmsFree(self ->ContextID, T);
|
||||
goto Error;
|
||||
}
|
||||
_cmsFree(self ->ContextID, T);
|
||||
}
|
||||
|
||||
@ -1872,7 +1889,7 @@ cmsBool Type_LUT8_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
|
||||
_cmsStageToneCurvesData* PreMPE = NULL, *PostMPE = NULL;
|
||||
_cmsStageMatrixData* MatMPE = NULL;
|
||||
_cmsStageCLutData* clut = NULL;
|
||||
int clutPoints;
|
||||
cmsUInt32Number clutPoints;
|
||||
|
||||
// Disassemble the LUT into components.
|
||||
mpe = NewLUT -> Elements;
|
||||
@ -1992,9 +2009,10 @@ void Type_LUT8_Free(struct _cms_typehandler_struct* self, void* Ptr)
|
||||
|
||||
// Read 16 bit tables as gamma functions
|
||||
static
|
||||
cmsBool Read16bitTables(cmsContext ContextID, cmsIOHANDLER* io, cmsPipeline* lut, int nChannels, int nEntries)
|
||||
cmsBool Read16bitTables(cmsContext ContextID, cmsIOHANDLER* io, cmsPipeline* lut,
|
||||
cmsUInt32Number nChannels, cmsUInt32Number nEntries)
|
||||
{
|
||||
int i;
|
||||
cmsUInt32Number i;
|
||||
cmsToneCurve* Tables[cmsMAXCHANNELS];
|
||||
|
||||
// Maybe an empty table? (this is a lcms extension)
|
||||
@ -2036,10 +2054,10 @@ Error:
|
||||
static
|
||||
cmsBool Write16bitTables(cmsContext ContextID, cmsIOHANDLER* io, _cmsStageToneCurvesData* Tables)
|
||||
{
|
||||
int j;
|
||||
cmsUInt32Number j;
|
||||
cmsUInt32Number i;
|
||||
cmsUInt16Number val;
|
||||
int nEntries;
|
||||
cmsUInt32Number nEntries;
|
||||
|
||||
_cmsAssert(Tables != NULL);
|
||||
|
||||
@ -2077,8 +2095,8 @@ void *Type_LUT16_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cm
|
||||
if (!_cmsReadUInt8Number(io, NULL)) return NULL;
|
||||
|
||||
// Do some checking
|
||||
if (InputChannels > cmsMAXCHANNELS) goto Error;
|
||||
if (OutputChannels > cmsMAXCHANNELS) goto Error;
|
||||
if (InputChannels == 0 || InputChannels > cmsMAXCHANNELS) goto Error;
|
||||
if (OutputChannels == 0 || OutputChannels > cmsMAXCHANNELS) goto Error;
|
||||
|
||||
// Allocates an empty LUT
|
||||
NewLUT = cmsPipelineAlloc(self ->ContextID, InputChannels, OutputChannels);
|
||||
@ -2160,7 +2178,7 @@ cmsBool Type_LUT16_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io
|
||||
_cmsStageToneCurvesData* PreMPE = NULL, *PostMPE = NULL;
|
||||
_cmsStageMatrixData* MatMPE = NULL;
|
||||
_cmsStageCLutData* clut = NULL;
|
||||
int i, InputChannels, OutputChannels, clutPoints;
|
||||
cmsUInt32Number i, InputChannels, OutputChannels, clutPoints;
|
||||
|
||||
// Disassemble the LUT into components.
|
||||
mpe = NewLUT -> Elements;
|
||||
@ -2346,7 +2364,8 @@ cmsStage* ReadMatrix(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cms
|
||||
// V4 stuff. Read CLUT part for LutAtoB and LutBtoA
|
||||
|
||||
static
|
||||
cmsStage* ReadCLUT(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number Offset, int InputChannels, int OutputChannels)
|
||||
cmsStage* ReadCLUT(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
|
||||
cmsUInt32Number Offset, cmsUInt32Number InputChannels, cmsUInt32Number OutputChannels)
|
||||
{
|
||||
cmsUInt8Number gridPoints8[cmsMAXCHANNELS]; // Number of grid points in each dimension.
|
||||
cmsUInt32Number GridPoints[cmsMAXCHANNELS], i;
|
||||
@ -2382,7 +2401,10 @@ cmsStage* ReadCLUT(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUI
|
||||
|
||||
for (i=0; i < Data ->nEntries; i++) {
|
||||
|
||||
if (io ->Read(io, &v, sizeof(cmsUInt8Number), 1) != 1) return NULL;
|
||||
if (io ->Read(io, &v, sizeof(cmsUInt8Number), 1) != 1) {
|
||||
cmsStageFree(CLUT);
|
||||
return NULL;
|
||||
}
|
||||
Data ->Tab.T[i] = FROM_8_TO_16(v);
|
||||
}
|
||||
|
||||
@ -2512,7 +2534,10 @@ void* Type_LUTA2B_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, c
|
||||
if (!_cmsReadUInt32Number(io, &offsetC)) return NULL;
|
||||
if (!_cmsReadUInt32Number(io, &offsetA)) return NULL;
|
||||
|
||||
// Allocates an empty LUT
|
||||
if (inputChan == 0 || inputChan >= cmsMAXCHANNELS) return NULL;
|
||||
if (outputChan == 0 || outputChan >= cmsMAXCHANNELS) return NULL;
|
||||
|
||||
// Allocates an empty LUT
|
||||
NewLUT = cmsPipelineAlloc(self ->ContextID, inputChan, outputChan);
|
||||
if (NewLUT == NULL) return NULL;
|
||||
|
||||
@ -2694,7 +2719,7 @@ static
|
||||
cmsBool Type_LUTA2B_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
|
||||
{
|
||||
cmsPipeline* Lut = (cmsPipeline*) Ptr;
|
||||
int inputChan, outputChan;
|
||||
cmsUInt32Number inputChan, outputChan;
|
||||
cmsStage *A = NULL, *B = NULL, *M = NULL;
|
||||
cmsStage * Matrix = NULL;
|
||||
cmsStage * CLUT = NULL;
|
||||
@ -2742,7 +2767,7 @@ cmsBool Type_LUTA2B_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io
|
||||
|
||||
if (CLUT != NULL) {
|
||||
offsetC = io ->Tell(io) - BaseOffset;
|
||||
if (!WriteCLUT(self, io, Lut ->SaveAs8Bits ? 1 : 2, CLUT)) return FALSE;
|
||||
if (!WriteCLUT(self, io, (Lut ->SaveAs8Bits ? 1U : 2U), CLUT)) return FALSE;
|
||||
|
||||
}
|
||||
if (M != NULL) {
|
||||
@ -2820,6 +2845,9 @@ void* Type_LUTB2A_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, c
|
||||
if (!_cmsReadUInt8Number(io, &inputChan)) return NULL;
|
||||
if (!_cmsReadUInt8Number(io, &outputChan)) return NULL;
|
||||
|
||||
if (inputChan == 0 || inputChan >= cmsMAXCHANNELS) return NULL;
|
||||
if (outputChan == 0 || outputChan >= cmsMAXCHANNELS) return NULL;
|
||||
|
||||
// Padding
|
||||
if (!_cmsReadUInt16Number(io, NULL)) return NULL;
|
||||
|
||||
@ -2879,7 +2907,7 @@ static
|
||||
cmsBool Type_LUTB2A_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
|
||||
{
|
||||
cmsPipeline* Lut = (cmsPipeline*) Ptr;
|
||||
int inputChan, outputChan;
|
||||
cmsUInt32Number inputChan, outputChan;
|
||||
cmsStage *A = NULL, *B = NULL, *M = NULL;
|
||||
cmsStage *Matrix = NULL;
|
||||
cmsStage *CLUT = NULL;
|
||||
@ -2921,7 +2949,7 @@ cmsBool Type_LUTB2A_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* i
|
||||
|
||||
if (CLUT != NULL) {
|
||||
offsetC = io ->Tell(io) - BaseOffset;
|
||||
if (!WriteCLUT(self, io, Lut ->SaveAs8Bits ? 1 : 2, CLUT)) return FALSE;
|
||||
if (!WriteCLUT(self, io, (Lut ->SaveAs8Bits ? 1U : 2U), CLUT)) return FALSE;
|
||||
|
||||
}
|
||||
if (M != NULL) {
|
||||
@ -3011,7 +3039,7 @@ void *Type_ColorantTable_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER
|
||||
for (i=0; i < Count; i++) {
|
||||
|
||||
if (io ->Read(io, Name, 32, 1) != 1) goto Error;
|
||||
Name[33] = 0;
|
||||
Name[32] = 0;
|
||||
|
||||
if (!_cmsReadUInt16Array(io, 3, PCS)) goto Error;
|
||||
|
||||
@ -3037,7 +3065,7 @@ static
|
||||
cmsBool Type_ColorantTable_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
|
||||
{
|
||||
cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) Ptr;
|
||||
int i, nColors;
|
||||
cmsUInt32Number i, nColors;
|
||||
|
||||
nColors = cmsNamedColorCount(NamedColorList);
|
||||
|
||||
@ -3045,9 +3073,11 @@ cmsBool Type_ColorantTable_Write(struct _cms_typehandler_struct* self, cmsIOHAN
|
||||
|
||||
for (i=0; i < nColors; i++) {
|
||||
|
||||
char root[33];
|
||||
char root[cmsMAX_PATH];
|
||||
cmsUInt16Number PCS[3];
|
||||
|
||||
memset(root, 0, sizeof(root));
|
||||
|
||||
if (!cmsNamedColorInfo(NamedColorList, i, root, NULL, NULL, PCS, NULL)) return 0;
|
||||
root[32] = 0;
|
||||
|
||||
@ -3107,8 +3137,8 @@ void *Type_NamedColor_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* i
|
||||
cmsUInt32Number nDeviceCoords; // Num of device coordinates
|
||||
char prefix[32]; // Prefix for each color name
|
||||
char suffix[32]; // Suffix for each color name
|
||||
cmsNAMEDCOLORLIST* v;
|
||||
cmsUInt32Number i;
|
||||
cmsNAMEDCOLORLIST* v;
|
||||
cmsUInt32Number i;
|
||||
|
||||
|
||||
*nItems = 0;
|
||||
@ -3129,7 +3159,7 @@ void *Type_NamedColor_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* i
|
||||
|
||||
if (nDeviceCoords > cmsMAXCHANNELS) {
|
||||
cmsSignalError(self->ContextID, cmsERROR_RANGE, "Too many device coordinates '%d'", nDeviceCoords);
|
||||
return 0;
|
||||
goto Error;
|
||||
}
|
||||
for (i=0; i < count; i++) {
|
||||
|
||||
@ -3138,7 +3168,7 @@ void *Type_NamedColor_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* i
|
||||
char Root[33];
|
||||
|
||||
memset(Colorant, 0, sizeof(Colorant));
|
||||
if (io -> Read(io, Root, 32, 1) != 1) return NULL;
|
||||
if (io -> Read(io, Root, 32, 1) != 1) goto Error;
|
||||
Root[32] = 0; // To prevent exploits
|
||||
|
||||
if (!_cmsReadUInt16Array(io, 3, PCS)) goto Error;
|
||||
@ -3165,7 +3195,7 @@ cmsBool Type_NamedColor_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER
|
||||
cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) Ptr;
|
||||
char prefix[33]; // Prefix for each color name
|
||||
char suffix[33]; // Suffix for each color name
|
||||
int i, nColors;
|
||||
cmsUInt32Number i, nColors;
|
||||
|
||||
nColors = cmsNamedColorCount(NamedColorList);
|
||||
|
||||
@ -3185,7 +3215,7 @@ cmsBool Type_NamedColor_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER
|
||||
|
||||
cmsUInt16Number PCS[3];
|
||||
cmsUInt16Number Colorant[cmsMAXCHANNELS];
|
||||
char Root[33];
|
||||
char Root[cmsMAX_PATH];
|
||||
|
||||
if (!cmsNamedColorInfo(NamedColorList, i, Root, NULL, NULL, PCS, Colorant)) return 0;
|
||||
Root[32] = 0;
|
||||
@ -3939,7 +3969,7 @@ cmsToneCurve* ReadSegmentedCurve(struct _cms_typehandler_struct* self, cmsIOHAND
|
||||
cmsUInt16Number nSegments;
|
||||
cmsCurveSegment* Segments;
|
||||
cmsToneCurve* Curve;
|
||||
cmsFloat32Number PrevBreak = -1E22F; // - infinite
|
||||
cmsFloat32Number PrevBreak = MINUS_INF; // - infinite
|
||||
|
||||
// Take signature and channels for each element.
|
||||
if (!_cmsReadUInt32Number(io, (cmsUInt32Number*) &ElementSig)) return NULL;
|
||||
@ -3964,7 +3994,7 @@ cmsToneCurve* ReadSegmentedCurve(struct _cms_typehandler_struct* self, cmsIOHAND
|
||||
}
|
||||
|
||||
Segments[nSegments-1].x0 = PrevBreak;
|
||||
Segments[nSegments-1].x1 = 1E22F; // A big cmsFloat32Number number
|
||||
Segments[nSegments-1].x1 = PLUS_INF; // A big cmsFloat32Number number
|
||||
|
||||
// Read segments
|
||||
for (i=0; i < nSegments; i++) {
|
||||
@ -3998,7 +4028,7 @@ cmsToneCurve* ReadSegmentedCurve(struct _cms_typehandler_struct* self, cmsIOHAND
|
||||
case cmsSigSampledCurveSeg: {
|
||||
cmsUInt32Number Count;
|
||||
|
||||
if (!_cmsReadUInt32Number(io, &Count)) return NULL;
|
||||
if (!_cmsReadUInt32Number(io, &Count)) goto Error;
|
||||
|
||||
Segments[i].nGridPoints = Count;
|
||||
Segments[i].SampledPoints = (cmsFloat32Number*) _cmsCalloc(self ->ContextID, Count, sizeof(cmsFloat32Number));
|
||||
@ -4017,7 +4047,7 @@ cmsToneCurve* ReadSegmentedCurve(struct _cms_typehandler_struct* self, cmsIOHAND
|
||||
_cmsTagSignature2String(String, (cmsTagSignature) ElementSig);
|
||||
cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown curve element type '%s' found.", String);
|
||||
}
|
||||
return NULL;
|
||||
goto Error;
|
||||
|
||||
}
|
||||
}
|
||||
@ -4031,7 +4061,12 @@ cmsToneCurve* ReadSegmentedCurve(struct _cms_typehandler_struct* self, cmsIOHAND
|
||||
return Curve;
|
||||
|
||||
Error:
|
||||
if (Segments) _cmsFree(self ->ContextID, Segments);
|
||||
if (Segments) {
|
||||
for (i=0; i < nSegments; i++) {
|
||||
if (Segments[i].SampledPoints) _cmsFree(self ->ContextID, Segments[i].SampledPoints);
|
||||
}
|
||||
_cmsFree(self ->ContextID, Segments);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -4085,7 +4120,7 @@ void *Type_MPEcurve_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
|
||||
}
|
||||
|
||||
_cmsFree(self ->ContextID, GammaTables);
|
||||
*nItems = (mpe != NULL) ? 1 : 0;
|
||||
*nItems = (mpe != NULL) ? 1U : 0;
|
||||
return mpe;
|
||||
|
||||
cmsUNUSED_PARAMETER(SizeOfTag);
|
||||
@ -4216,9 +4251,13 @@ void *Type_MPEmatrix_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io
|
||||
if (!_cmsReadUInt16Number(io, &OutputChans)) return NULL;
|
||||
|
||||
|
||||
nElems = InputChans * OutputChans;
|
||||
// Input and output chans may be ANY (up to 0xffff),
|
||||
// but we choose to limit to 16 channels for now
|
||||
if (InputChans >= cmsMAXCHANNELS) return NULL;
|
||||
if (OutputChans >= cmsMAXCHANNELS) return NULL;
|
||||
|
||||
nElems = (cmsUInt32Number) InputChans * OutputChans;
|
||||
|
||||
// Input and output chans may be ANY (up to 0xffff)
|
||||
Matrix = (cmsFloat64Number*) _cmsCalloc(self ->ContextID, nElems, sizeof(cmsFloat64Number));
|
||||
if (Matrix == NULL) return NULL;
|
||||
|
||||
@ -4233,7 +4272,11 @@ void *Type_MPEmatrix_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io
|
||||
|
||||
cmsFloat32Number v;
|
||||
|
||||
if (!_cmsReadFloat32Number(io, &v)) return NULL;
|
||||
if (!_cmsReadFloat32Number(io, &v)) {
|
||||
_cmsFree(self ->ContextID, Matrix);
|
||||
_cmsFree(self ->ContextID, Offsets);
|
||||
return NULL;
|
||||
}
|
||||
Matrix[i] = v;
|
||||
}
|
||||
|
||||
@ -4242,7 +4285,11 @@ void *Type_MPEmatrix_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io
|
||||
|
||||
cmsFloat32Number v;
|
||||
|
||||
if (!_cmsReadFloat32Number(io, &v)) return NULL;
|
||||
if (!_cmsReadFloat32Number(io, &v)) {
|
||||
_cmsFree(self ->ContextID, Matrix);
|
||||
_cmsFree(self ->ContextID, Offsets);
|
||||
return NULL;
|
||||
}
|
||||
Offsets[i] = v;
|
||||
}
|
||||
|
||||
@ -4313,8 +4360,9 @@ void *Type_MPEclut_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
|
||||
goto Error;
|
||||
|
||||
// Copy MAX_INPUT_DIMENSIONS at most. Expand to cmsUInt32Number
|
||||
nMaxGrids = InputChans > MAX_INPUT_DIMENSIONS ? MAX_INPUT_DIMENSIONS : InputChans;
|
||||
for (i=0; i < nMaxGrids; i++) {
|
||||
nMaxGrids = InputChans > MAX_INPUT_DIMENSIONS ? (cmsUInt32Number) MAX_INPUT_DIMENSIONS : InputChans;
|
||||
|
||||
for (i = 0; i < nMaxGrids; i++) {
|
||||
if (Dimensions8[i] == 1) goto Error; // Impossible value, 0 for no CLUT and then 2 at least
|
||||
GridPoints[i] = (cmsUInt32Number)Dimensions8[i];
|
||||
}
|
||||
@ -4323,11 +4371,11 @@ void *Type_MPEclut_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
|
||||
mpe = cmsStageAllocCLutFloatGranular(self ->ContextID, GridPoints, InputChans, OutputChans, NULL);
|
||||
if (mpe == NULL) goto Error;
|
||||
|
||||
// Read the data
|
||||
// Read and sanitize the data
|
||||
clut = (_cmsStageCLutData*) mpe ->Data;
|
||||
for (i=0; i < clut ->nEntries; i++) {
|
||||
|
||||
if (!_cmsReadFloat32Number(io, &clut ->Tab.TFloat[i])) goto Error;
|
||||
if (!_cmsReadFloat32Number(io, &clut->Tab.TFloat[i])) goto Error;
|
||||
}
|
||||
|
||||
*nItems = 1;
|
||||
@ -4457,6 +4505,9 @@ void *Type_MPE_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsU
|
||||
if (!_cmsReadUInt16Number(io, &InputChans)) return NULL;
|
||||
if (!_cmsReadUInt16Number(io, &OutputChans)) return NULL;
|
||||
|
||||
if (InputChans == 0 || InputChans >= cmsMAXCHANNELS) return NULL;
|
||||
if (OutputChans == 0 || OutputChans >= cmsMAXCHANNELS) return NULL;
|
||||
|
||||
// Allocates an empty LUT
|
||||
NewLUT = cmsPipelineAlloc(self ->ContextID, InputChans, OutputChans);
|
||||
if (NewLUT == NULL) return NULL;
|
||||
@ -4464,6 +4515,10 @@ void *Type_MPE_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsU
|
||||
if (!_cmsReadUInt32Number(io, &ElementCount)) goto Error;
|
||||
if (!ReadPositionTable(self, io, ElementCount, BaseOffset, NewLUT, ReadMPEElem)) goto Error;
|
||||
|
||||
// Check channel count
|
||||
if (InputChans != NewLUT->InputChannels ||
|
||||
OutputChans != NewLUT->OutputChannels) goto Error;
|
||||
|
||||
// Success
|
||||
*nItems = 1;
|
||||
return NewLUT;
|
||||
@ -4484,7 +4539,7 @@ static
|
||||
cmsBool Type_MPE_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
|
||||
{
|
||||
cmsUInt32Number i, BaseOffset, DirectoryPos, CurrentPos;
|
||||
int inputChan, outputChan;
|
||||
cmsUInt32Number inputChan, outputChan;
|
||||
cmsUInt32Number ElemCount;
|
||||
cmsUInt32Number *ElementOffsets = NULL, *ElementSizes = NULL, Before;
|
||||
cmsStageSignature ElementSig;
|
||||
@ -4532,7 +4587,7 @@ cmsBool Type_MPE_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, v
|
||||
|
||||
_cmsTagSignature2String(String, (cmsTagSignature) ElementSig);
|
||||
|
||||
// An unknow element was found.
|
||||
// An unknown element was found.
|
||||
cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Found unknown MPE type '%s'", String);
|
||||
goto Error;
|
||||
}
|
||||
@ -5267,38 +5322,38 @@ void Type_Dictionary_Free(struct _cms_typehandler_struct* self, void* Ptr)
|
||||
|
||||
|
||||
// This is the list of built-in types
|
||||
static _cmsTagTypeLinkedList SupportedTagTypes[] = {
|
||||
static const _cmsTagTypeLinkedList SupportedTagTypes[] = {
|
||||
|
||||
{TYPE_HANDLER(cmsSigChromaticityType, Chromaticity), &SupportedTagTypes[1] },
|
||||
{TYPE_HANDLER(cmsSigColorantOrderType, ColorantOrderType), &SupportedTagTypes[2] },
|
||||
{TYPE_HANDLER(cmsSigS15Fixed16ArrayType, S15Fixed16), &SupportedTagTypes[3] },
|
||||
{TYPE_HANDLER(cmsSigU16Fixed16ArrayType, U16Fixed16), &SupportedTagTypes[4] },
|
||||
{TYPE_HANDLER(cmsSigTextType, Text), &SupportedTagTypes[5] },
|
||||
{TYPE_HANDLER(cmsSigTextDescriptionType, Text_Description), &SupportedTagTypes[6] },
|
||||
{TYPE_HANDLER(cmsSigCurveType, Curve), &SupportedTagTypes[7] },
|
||||
{TYPE_HANDLER(cmsSigParametricCurveType, ParametricCurve), &SupportedTagTypes[8] },
|
||||
{TYPE_HANDLER(cmsSigDateTimeType, DateTime), &SupportedTagTypes[9] },
|
||||
{TYPE_HANDLER(cmsSigLut8Type, LUT8), &SupportedTagTypes[10] },
|
||||
{TYPE_HANDLER(cmsSigLut16Type, LUT16), &SupportedTagTypes[11] },
|
||||
{TYPE_HANDLER(cmsSigColorantTableType, ColorantTable), &SupportedTagTypes[12] },
|
||||
{TYPE_HANDLER(cmsSigNamedColor2Type, NamedColor), &SupportedTagTypes[13] },
|
||||
{TYPE_HANDLER(cmsSigMultiLocalizedUnicodeType, MLU), &SupportedTagTypes[14] },
|
||||
{TYPE_HANDLER(cmsSigProfileSequenceDescType, ProfileSequenceDesc), &SupportedTagTypes[15] },
|
||||
{TYPE_HANDLER(cmsSigSignatureType, Signature), &SupportedTagTypes[16] },
|
||||
{TYPE_HANDLER(cmsSigMeasurementType, Measurement), &SupportedTagTypes[17] },
|
||||
{TYPE_HANDLER(cmsSigDataType, Data), &SupportedTagTypes[18] },
|
||||
{TYPE_HANDLER(cmsSigLutAtoBType, LUTA2B), &SupportedTagTypes[19] },
|
||||
{TYPE_HANDLER(cmsSigLutBtoAType, LUTB2A), &SupportedTagTypes[20] },
|
||||
{TYPE_HANDLER(cmsSigUcrBgType, UcrBg), &SupportedTagTypes[21] },
|
||||
{TYPE_HANDLER(cmsSigCrdInfoType, CrdInfo), &SupportedTagTypes[22] },
|
||||
{TYPE_HANDLER(cmsSigMultiProcessElementType, MPE), &SupportedTagTypes[23] },
|
||||
{TYPE_HANDLER(cmsSigScreeningType, Screening), &SupportedTagTypes[24] },
|
||||
{TYPE_HANDLER(cmsSigViewingConditionsType, ViewingConditions), &SupportedTagTypes[25] },
|
||||
{TYPE_HANDLER(cmsSigXYZType, XYZ), &SupportedTagTypes[26] },
|
||||
{TYPE_HANDLER(cmsCorbisBrokenXYZtype, XYZ), &SupportedTagTypes[27] },
|
||||
{TYPE_HANDLER(cmsMonacoBrokenCurveType, Curve), &SupportedTagTypes[28] },
|
||||
{TYPE_HANDLER(cmsSigProfileSequenceIdType, ProfileSequenceId), &SupportedTagTypes[29] },
|
||||
{TYPE_HANDLER(cmsSigDictType, Dictionary), &SupportedTagTypes[30] },
|
||||
{TYPE_HANDLER(cmsSigChromaticityType, Chromaticity), (_cmsTagTypeLinkedList*) &SupportedTagTypes[1] },
|
||||
{TYPE_HANDLER(cmsSigColorantOrderType, ColorantOrderType), (_cmsTagTypeLinkedList*) &SupportedTagTypes[2] },
|
||||
{TYPE_HANDLER(cmsSigS15Fixed16ArrayType, S15Fixed16), (_cmsTagTypeLinkedList*) &SupportedTagTypes[3] },
|
||||
{TYPE_HANDLER(cmsSigU16Fixed16ArrayType, U16Fixed16), (_cmsTagTypeLinkedList*) &SupportedTagTypes[4] },
|
||||
{TYPE_HANDLER(cmsSigTextType, Text), (_cmsTagTypeLinkedList*) &SupportedTagTypes[5] },
|
||||
{TYPE_HANDLER(cmsSigTextDescriptionType, Text_Description), (_cmsTagTypeLinkedList*) &SupportedTagTypes[6] },
|
||||
{TYPE_HANDLER(cmsSigCurveType, Curve), (_cmsTagTypeLinkedList*) &SupportedTagTypes[7] },
|
||||
{TYPE_HANDLER(cmsSigParametricCurveType, ParametricCurve), (_cmsTagTypeLinkedList*) &SupportedTagTypes[8] },
|
||||
{TYPE_HANDLER(cmsSigDateTimeType, DateTime), (_cmsTagTypeLinkedList*) &SupportedTagTypes[9] },
|
||||
{TYPE_HANDLER(cmsSigLut8Type, LUT8), (_cmsTagTypeLinkedList*) &SupportedTagTypes[10] },
|
||||
{TYPE_HANDLER(cmsSigLut16Type, LUT16), (_cmsTagTypeLinkedList*) &SupportedTagTypes[11] },
|
||||
{TYPE_HANDLER(cmsSigColorantTableType, ColorantTable), (_cmsTagTypeLinkedList*) &SupportedTagTypes[12] },
|
||||
{TYPE_HANDLER(cmsSigNamedColor2Type, NamedColor), (_cmsTagTypeLinkedList*) &SupportedTagTypes[13] },
|
||||
{TYPE_HANDLER(cmsSigMultiLocalizedUnicodeType, MLU), (_cmsTagTypeLinkedList*) &SupportedTagTypes[14] },
|
||||
{TYPE_HANDLER(cmsSigProfileSequenceDescType, ProfileSequenceDesc),(_cmsTagTypeLinkedList*) &SupportedTagTypes[15] },
|
||||
{TYPE_HANDLER(cmsSigSignatureType, Signature), (_cmsTagTypeLinkedList*) &SupportedTagTypes[16] },
|
||||
{TYPE_HANDLER(cmsSigMeasurementType, Measurement), (_cmsTagTypeLinkedList*) &SupportedTagTypes[17] },
|
||||
{TYPE_HANDLER(cmsSigDataType, Data), (_cmsTagTypeLinkedList*) &SupportedTagTypes[18] },
|
||||
{TYPE_HANDLER(cmsSigLutAtoBType, LUTA2B), (_cmsTagTypeLinkedList*) &SupportedTagTypes[19] },
|
||||
{TYPE_HANDLER(cmsSigLutBtoAType, LUTB2A), (_cmsTagTypeLinkedList*) &SupportedTagTypes[20] },
|
||||
{TYPE_HANDLER(cmsSigUcrBgType, UcrBg), (_cmsTagTypeLinkedList*) &SupportedTagTypes[21] },
|
||||
{TYPE_HANDLER(cmsSigCrdInfoType, CrdInfo), (_cmsTagTypeLinkedList*) &SupportedTagTypes[22] },
|
||||
{TYPE_HANDLER(cmsSigMultiProcessElementType, MPE), (_cmsTagTypeLinkedList*) &SupportedTagTypes[23] },
|
||||
{TYPE_HANDLER(cmsSigScreeningType, Screening), (_cmsTagTypeLinkedList*) &SupportedTagTypes[24] },
|
||||
{TYPE_HANDLER(cmsSigViewingConditionsType, ViewingConditions), (_cmsTagTypeLinkedList*) &SupportedTagTypes[25] },
|
||||
{TYPE_HANDLER(cmsSigXYZType, XYZ), (_cmsTagTypeLinkedList*) &SupportedTagTypes[26] },
|
||||
{TYPE_HANDLER(cmsCorbisBrokenXYZtype, XYZ), (_cmsTagTypeLinkedList*) &SupportedTagTypes[27] },
|
||||
{TYPE_HANDLER(cmsMonacoBrokenCurveType, Curve), (_cmsTagTypeLinkedList*) &SupportedTagTypes[28] },
|
||||
{TYPE_HANDLER(cmsSigProfileSequenceIdType, ProfileSequenceId), (_cmsTagTypeLinkedList*) &SupportedTagTypes[29] },
|
||||
{TYPE_HANDLER(cmsSigDictType, Dictionary), (_cmsTagTypeLinkedList*) &SupportedTagTypes[30] },
|
||||
{TYPE_HANDLER(cmsSigVcgtType, vcgt), NULL }
|
||||
};
|
||||
|
||||
@ -5390,7 +5445,7 @@ cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignatu
|
||||
{
|
||||
_cmsTagTypePluginChunkType* ctx = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(ContextID, TagTypePlugin);
|
||||
|
||||
return GetHandler(sig, ctx->TagTypes, SupportedTagTypes);
|
||||
return GetHandler(sig, ctx->TagTypes, (_cmsTagTypeLinkedList*) SupportedTagTypes);
|
||||
}
|
||||
|
||||
// ********************************************************************************
|
||||
@ -5405,7 +5460,7 @@ typedef struct _cmsTagLinkedList_st {
|
||||
|
||||
} _cmsTagLinkedList;
|
||||
|
||||
// This is the list of built-in tags
|
||||
// This is the list of built-in tags. The data of this list can be modified by plug-ins
|
||||
static _cmsTagLinkedList SupportedTags[] = {
|
||||
|
||||
{ cmsSigAToB0Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutAtoBType, cmsSigLut8Type}, DecideLUTtypeA2B}, &SupportedTags[1]},
|
||||
@ -5454,7 +5509,7 @@ static _cmsTagLinkedList SupportedTags[] = {
|
||||
{ cmsSigPreview2Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutBtoAType, cmsSigLut8Type }, DecideLUTtypeB2A}, &SupportedTags[32]},
|
||||
|
||||
{ cmsSigProfileDescriptionTag, { 1, 3, { cmsSigTextDescriptionType, cmsSigMultiLocalizedUnicodeType, cmsSigTextType}, DecideTextDescType}, &SupportedTags[33]},
|
||||
{ cmsSigProfileSequenceDescTag, { 1, 1, { cmsSigProfileSequenceDescType }, NULL}, &SupportedTags[34]},
|
||||
{ cmsSigProfileSequenceDescTag, { 1, 1, { cmsSigProfileSequenceDescType }, NULL}, &SupportedTags[34]},
|
||||
{ cmsSigTechnologyTag, { 1, 1, { cmsSigSignatureType }, NULL}, &SupportedTags[35]},
|
||||
|
||||
{ cmsSigColorimetricIntentImageStateTag, { 1, 1, { cmsSigSignatureType }, NULL}, &SupportedTags[36]},
|
||||
@ -5491,10 +5546,10 @@ static _cmsTagLinkedList SupportedTags[] = {
|
||||
{ cmsSigVcgtTag, { 1, 1, { cmsSigVcgtType}, NULL }, &SupportedTags[60]},
|
||||
{ cmsSigMetaTag, { 1, 1, { cmsSigDictType}, NULL }, &SupportedTags[61]},
|
||||
{ cmsSigProfileSequenceIdTag, { 1, 1, { cmsSigProfileSequenceIdType}, NULL }, &SupportedTags[62]},
|
||||
|
||||
{ cmsSigProfileDescriptionMLTag,{ 1, 1, { cmsSigMultiLocalizedUnicodeType}, NULL}, &SupportedTags[63]},
|
||||
{ cmsSigArgyllArtsTag, { 9, 1, { cmsSigS15Fixed16ArrayType}, NULL}, NULL}
|
||||
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
@ -320,7 +320,7 @@ cmsHPROFILE CMSEXPORT cmsCreateLinearizationDeviceLinkTHR(cmsContext ContextID,
|
||||
{
|
||||
cmsHPROFILE hICC;
|
||||
cmsPipeline* Pipeline;
|
||||
int nChannels;
|
||||
cmsUInt32Number nChannels;
|
||||
|
||||
hICC = cmsCreateProfilePlaceholder(ContextID);
|
||||
if (!hICC)
|
||||
@ -426,7 +426,7 @@ cmsHPROFILE CMSEXPORT cmsCreateInkLimitingDeviceLinkTHR(cmsContext ContextID,
|
||||
cmsHPROFILE hICC;
|
||||
cmsPipeline* LUT;
|
||||
cmsStage* CLUT;
|
||||
int nChannels;
|
||||
cmsUInt32Number nChannels;
|
||||
|
||||
if (ColorSpace != cmsSigCmykData) {
|
||||
cmsSignalError(ContextID, cmsERROR_COLORSPACE_CHECK, "InkLimiting: Only CMYK currently supported");
|
||||
@ -755,13 +755,13 @@ 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)
|
||||
cmsUInt32Number nLUTPoints,
|
||||
cmsFloat64Number Bright,
|
||||
cmsFloat64Number Contrast,
|
||||
cmsFloat64Number Hue,
|
||||
cmsFloat64Number Saturation,
|
||||
cmsUInt32Number TempSrc,
|
||||
cmsUInt32Number TempDest)
|
||||
{
|
||||
cmsHPROFILE hICC;
|
||||
cmsPipeline* Pipeline;
|
||||
@ -769,7 +769,7 @@ cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfileTHR(cmsContext ContextID,
|
||||
cmsCIExyY WhitePnt;
|
||||
cmsStage* CLUT;
|
||||
cmsUInt32Number Dimensions[MAX_INPUT_DIMENSIONS];
|
||||
int i;
|
||||
cmsUInt32Number i;
|
||||
|
||||
bchsw.Brightness = Bright;
|
||||
bchsw.Contrast = Contrast;
|
||||
@ -807,7 +807,7 @@ cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfileTHR(cmsContext ContextID,
|
||||
|
||||
for (i=0; i < MAX_INPUT_DIMENSIONS; i++) Dimensions[i] = nLUTPoints;
|
||||
CLUT = cmsStageAllocCLut16bitGranular(ContextID, Dimensions, 3, 3, NULL);
|
||||
if (CLUT == NULL) return NULL;
|
||||
if (CLUT == NULL) goto Error;
|
||||
|
||||
|
||||
if (!cmsStageSampleCLut16bit(CLUT, bchswSampler, (void*) &bchsw, 0)) {
|
||||
@ -840,13 +840,13 @@ Error:
|
||||
}
|
||||
|
||||
|
||||
CMSAPI cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfile(int nLUTPoints,
|
||||
CMSAPI cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfile(cmsUInt32Number nLUTPoints,
|
||||
cmsFloat64Number Bright,
|
||||
cmsFloat64Number Contrast,
|
||||
cmsFloat64Number Hue,
|
||||
cmsFloat64Number Saturation,
|
||||
int TempSrc,
|
||||
int TempDest)
|
||||
cmsUInt32Number TempSrc,
|
||||
cmsUInt32Number TempDest)
|
||||
{
|
||||
return cmsCreateBCHSWabstractProfileTHR(NULL, nLUTPoints, Bright, Contrast, Hue, Saturation, TempSrc, TempDest);
|
||||
}
|
||||
@ -859,8 +859,10 @@ cmsHPROFILE CMSEXPORT cmsCreateNULLProfileTHR(cmsContext ContextID)
|
||||
cmsHPROFILE hProfile;
|
||||
cmsPipeline* LUT = NULL;
|
||||
cmsStage* PostLin;
|
||||
cmsToneCurve* EmptyTab;
|
||||
cmsStage* OutLin;
|
||||
cmsToneCurve* EmptyTab[3];
|
||||
cmsUInt16Number Zero[2] = { 0, 0 };
|
||||
const cmsFloat64Number PickLstarMatrix[] = { 1, 0, 0 };
|
||||
|
||||
hProfile = cmsCreateProfilePlaceholder(ContextID);
|
||||
if (!hProfile) // can't allocate
|
||||
@ -871,22 +873,28 @@ cmsHPROFILE CMSEXPORT cmsCreateNULLProfileTHR(cmsContext ContextID)
|
||||
if (!SetTextTags(hProfile, L"NULL profile built-in")) goto Error;
|
||||
|
||||
|
||||
|
||||
cmsSetDeviceClass(hProfile, cmsSigOutputClass);
|
||||
cmsSetColorSpace(hProfile, cmsSigGrayData);
|
||||
cmsSetPCS(hProfile, cmsSigLabData);
|
||||
|
||||
// An empty LUTs is all we need
|
||||
LUT = cmsPipelineAlloc(ContextID, 1, 1);
|
||||
// Create a valid ICC 4 structure
|
||||
LUT = cmsPipelineAlloc(ContextID, 3, 1);
|
||||
if (LUT == NULL) goto Error;
|
||||
|
||||
EmptyTab = cmsBuildTabulatedToneCurve16(ContextID, 2, Zero);
|
||||
PostLin = cmsStageAllocToneCurves(ContextID, 1, &EmptyTab);
|
||||
cmsFreeToneCurve(EmptyTab);
|
||||
EmptyTab[0] = EmptyTab[1] = EmptyTab[2] = cmsBuildTabulatedToneCurve16(ContextID, 2, Zero);
|
||||
PostLin = cmsStageAllocToneCurves(ContextID, 3, EmptyTab);
|
||||
OutLin = cmsStageAllocToneCurves(ContextID, 1, EmptyTab);
|
||||
cmsFreeToneCurve(EmptyTab[0]);
|
||||
|
||||
if (!cmsPipelineInsertStage(LUT, cmsAT_END, PostLin))
|
||||
goto Error;
|
||||
|
||||
if (!cmsPipelineInsertStage(LUT, cmsAT_END, cmsStageAllocMatrix(ContextID, 1, 3, PickLstarMatrix, NULL)))
|
||||
goto Error;
|
||||
|
||||
if (!cmsPipelineInsertStage(LUT, cmsAT_END, OutLin))
|
||||
goto Error;
|
||||
|
||||
if (!cmsWriteTag(hProfile, cmsSigBToA0Tag, (void*) LUT)) goto Error;
|
||||
if (!cmsWriteTag(hProfile, cmsSigMediaWhitePointTag, cmsD50_XYZ())) goto Error;
|
||||
|
||||
@ -967,7 +975,7 @@ cmsHPROFILE CreateNamedColorDevicelink(cmsHTRANSFORM xform)
|
||||
{
|
||||
_cmsTRANSFORM* v = (_cmsTRANSFORM*) xform;
|
||||
cmsHPROFILE hICC = NULL;
|
||||
int i, nColors;
|
||||
cmsUInt32Number i, nColors;
|
||||
cmsNAMEDCOLORLIST *nc2 = NULL, *Original = NULL;
|
||||
|
||||
// Create an empty placeholder
|
||||
@ -1084,7 +1092,7 @@ cmsHPROFILE CMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, cmsFloat
|
||||
{
|
||||
cmsHPROFILE hProfile = NULL;
|
||||
cmsUInt32Number FrmIn, FrmOut, ChansIn, ChansOut;
|
||||
cmsUInt32Number ColorSpaceBitsIn, ColorSpaceBitsOut;
|
||||
int ColorSpaceBitsIn, ColorSpaceBitsOut;
|
||||
_cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform;
|
||||
cmsPipeline* LUT = NULL;
|
||||
cmsStage* mpe;
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
@ -105,7 +105,6 @@ cmsBool CMSEXPORT cmsWhitePointFromTemp(cmsCIExyY* WhitePoint, cmsFloat64Number
|
||||
}
|
||||
|
||||
// Obtain y(x)
|
||||
|
||||
y = -3.000*(x*x) + 2.870*x - 0.275;
|
||||
|
||||
// wave factors (not used, but here for futures extensions)
|
||||
@ -131,7 +130,7 @@ typedef struct {
|
||||
|
||||
} ISOTEMPERATURE;
|
||||
|
||||
static ISOTEMPERATURE isotempdata[] = {
|
||||
static const ISOTEMPERATURE isotempdata[] = {
|
||||
// {Mirek, Ut, Vt, Tt }
|
||||
{0, 0.18006, 0.26352, -0.24341},
|
||||
{10, 0.18066, 0.26589, -0.25479},
|
||||
@ -295,7 +294,7 @@ cmsBool _cmsAdaptMatrixToD50(cmsMAT3* r, const cmsCIExyY* SourceWhitePt)
|
||||
// Build a White point, primary chromas transfer matrix from RGB to CIE XYZ
|
||||
// This is just an approximation, I am not handling all the non-linear
|
||||
// aspects of the RGB to XYZ process, and assumming that the gamma correction
|
||||
// has transitive property in the tranformation chain.
|
||||
// has transitive property in the transformation chain.
|
||||
//
|
||||
// the alghoritm:
|
||||
//
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
@ -284,6 +284,8 @@ void FloatXFORM(_cmsTRANSFORM* p,
|
||||
|
||||
strideIn = 0;
|
||||
strideOut = 0;
|
||||
memset(fIn, 0, sizeof(fIn));
|
||||
memset(fOut, 0, sizeof(fIn));
|
||||
|
||||
for (i = 0; i < LineCount; i++) {
|
||||
|
||||
@ -348,6 +350,7 @@ void NullFloatXFORM(_cmsTRANSFORM* p,
|
||||
|
||||
strideIn = 0;
|
||||
strideOut = 0;
|
||||
memset(fIn, 0, sizeof(fIn));
|
||||
|
||||
for (i = 0; i < LineCount; i++) {
|
||||
|
||||
@ -385,6 +388,7 @@ void NullXFORM(_cmsTRANSFORM* p,
|
||||
|
||||
strideIn = 0;
|
||||
strideOut = 0;
|
||||
memset(wIn, 0, sizeof(wIn));
|
||||
|
||||
for (i = 0; i < LineCount; i++) {
|
||||
|
||||
@ -422,6 +426,8 @@ void PrecalculatedXFORM(_cmsTRANSFORM* p,
|
||||
|
||||
strideIn = 0;
|
||||
strideOut = 0;
|
||||
memset(wIn, 0, sizeof(wIn));
|
||||
memset(wOut, 0, sizeof(wOut));
|
||||
|
||||
for (i = 0; i < LineCount; i++) {
|
||||
|
||||
@ -483,6 +489,8 @@ void PrecalculatedXFORMGamutCheck(_cmsTRANSFORM* p,
|
||||
|
||||
strideIn = 0;
|
||||
strideOut = 0;
|
||||
memset(wIn, 0, sizeof(wIn));
|
||||
memset(wOut, 0, sizeof(wOut));
|
||||
|
||||
for (i = 0; i < LineCount; i++) {
|
||||
|
||||
@ -790,7 +798,10 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
|
||||
|
||||
// Allocate needed memory
|
||||
_cmsTRANSFORM* p = (_cmsTRANSFORM*)_cmsMallocZero(ContextID, sizeof(_cmsTRANSFORM));
|
||||
if (!p) return NULL;
|
||||
if (!p) {
|
||||
cmsPipelineFree(lut);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Store the proposed pipeline
|
||||
p->Lut = lut;
|
||||
@ -823,7 +834,7 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
|
||||
p->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
|
||||
p->ToOutputFloat = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
|
||||
|
||||
// Save the day?
|
||||
// Save the day? (Ignore the warning)
|
||||
if (Plugin->OldXform) {
|
||||
p->OldXform = (_cmsTransformFn) p->xform;
|
||||
p->xform = _cmsTransform2toTransformAdaptor;
|
||||
@ -848,7 +859,7 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
|
||||
if (p ->FromInputFloat == NULL || p ->ToOutputFloat == NULL) {
|
||||
|
||||
cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported raster format");
|
||||
_cmsFree(ContextID, p);
|
||||
cmsDeleteTransform(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -870,7 +881,7 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
|
||||
}
|
||||
else {
|
||||
|
||||
int BytesPerPixelInput;
|
||||
cmsUInt32Number BytesPerPixelInput;
|
||||
|
||||
p ->FromInput = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16;
|
||||
p ->ToOutput = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16;
|
||||
@ -878,7 +889,7 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
|
||||
if (p ->FromInput == NULL || p ->ToOutput == NULL) {
|
||||
|
||||
cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported raster format");
|
||||
_cmsFree(ContextID, p);
|
||||
cmsDeleteTransform(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -920,13 +931,13 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
|
||||
}
|
||||
|
||||
static
|
||||
cmsBool GetXFormColorSpaces(int nProfiles, cmsHPROFILE hProfiles[], cmsColorSpaceSignature* Input, cmsColorSpaceSignature* Output)
|
||||
cmsBool GetXFormColorSpaces(cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[], cmsColorSpaceSignature* Input, cmsColorSpaceSignature* Output)
|
||||
{
|
||||
cmsColorSpaceSignature ColorSpaceIn, ColorSpaceOut;
|
||||
cmsColorSpaceSignature PostColorSpace;
|
||||
int i;
|
||||
cmsUInt32Number i;
|
||||
|
||||
if (nProfiles <= 0) return FALSE;
|
||||
if (nProfiles == 0) return FALSE;
|
||||
if (hProfiles[0] == NULL) return FALSE;
|
||||
|
||||
*Input = PostColorSpace = cmsGetColorSpace(hProfiles[0]);
|
||||
@ -975,7 +986,7 @@ cmsBool GetXFormColorSpaces(int nProfiles, cmsHPROFILE hProfiles[], cmsColorSpac
|
||||
static
|
||||
cmsBool IsProperColorSpace(cmsColorSpaceSignature Check, cmsUInt32Number dwFormat)
|
||||
{
|
||||
int Space1 = T_COLORSPACE(dwFormat);
|
||||
int Space1 = (int) T_COLORSPACE(dwFormat);
|
||||
int Space2 = _cmsLCMScolorSpace(Check);
|
||||
|
||||
if (Space1 == PT_ANY) return TRUE;
|
||||
@ -1231,7 +1242,7 @@ cmsHTRANSFORM CMSEXPORT cmsCreateTransformTHR(cmsContext ContextID,
|
||||
hArray[0] = Input;
|
||||
hArray[1] = Output;
|
||||
|
||||
return cmsCreateMultiprofileTransformTHR(ContextID, hArray, Output == NULL ? 1 : 2, InputFormat, OutputFormat, Intent, dwFlags);
|
||||
return cmsCreateMultiprofileTransformTHR(ContextID, hArray, Output == NULL ? 1U : 2U, InputFormat, OutputFormat, Intent, dwFlags);
|
||||
}
|
||||
|
||||
CMSAPI cmsHTRANSFORM CMSEXPORT cmsCreateTransform(cmsHPROFILE Input,
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
@ -52,7 +52,7 @@
|
||||
//
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Version 2.8
|
||||
// Version 2.9rc3
|
||||
//
|
||||
|
||||
#ifndef _lcms2_H
|
||||
@ -78,7 +78,7 @@
|
||||
// #define CMS_USE_CPP_API
|
||||
|
||||
// Uncomment this line if you need strict CGATS syntax. Makes CGATS files to
|
||||
// require "KEYWORD" on undefined identifiers, keep it comented out unless needed
|
||||
// require "KEYWORD" on undefined identifiers, keep it commented out unless needed
|
||||
// #define CMS_STRICT_CGATS 1
|
||||
|
||||
// Uncomment to get rid of the tables for "half" float support
|
||||
@ -87,6 +87,9 @@
|
||||
// Uncomment to get rid of pthreads/windows dependency
|
||||
// #define CMS_NO_PTHREADS 1
|
||||
|
||||
// Uncomment this for special windows mutex initialization (see lcms2_internal.h)
|
||||
// #define CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT
|
||||
|
||||
// ********** End of configuration toggles ******************************
|
||||
|
||||
// Needed for streams
|
||||
@ -104,7 +107,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
// Version/release
|
||||
#define LCMS_VERSION 2080
|
||||
#define LCMS_VERSION 2090
|
||||
|
||||
// I will give the chance of redefining basic types for compilers that are not fully C99 compliant
|
||||
#ifndef CMS_BASIC_TYPES_ALREADY_DEFINED
|
||||
@ -254,16 +257,21 @@ typedef int cmsBool;
|
||||
# define CMSAPI __declspec(dllexport)
|
||||
# else
|
||||
# define CMSAPI __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# else
|
||||
# define CMSEXPORT
|
||||
# define CMSAPI
|
||||
# define CMSEXPORT
|
||||
# define CMSAPI
|
||||
# endif
|
||||
#else
|
||||
# define CMSEXPORT
|
||||
# define CMSAPI
|
||||
#endif
|
||||
#else // not Windows
|
||||
# ifdef HAVE_FUNC_ATTRIBUTE_VISIBILITY
|
||||
# define CMSEXPORT
|
||||
# define CMSAPI __attribute__((visibility("default")))
|
||||
# else
|
||||
# define CMSEXPORT
|
||||
# define CMSAPI
|
||||
# endif
|
||||
#endif // CMS_IS_WINDOWS_
|
||||
|
||||
#ifdef HasTHREADS
|
||||
# if HasTHREADS == 1
|
||||
@ -284,9 +292,9 @@ typedef int cmsBool;
|
||||
#endif
|
||||
|
||||
// D50 XYZ normalized to Y=1.0
|
||||
#define cmsD50X 0.9642
|
||||
#define cmsD50Y 1.0
|
||||
#define cmsD50Z 0.8249
|
||||
#define cmsD50X 0.9642
|
||||
#define cmsD50Y 1.0
|
||||
#define cmsD50Z 0.8249
|
||||
|
||||
// V4 perceptual black
|
||||
#define cmsPERCEPTUAL_BLACK_X 0.00336
|
||||
@ -294,8 +302,8 @@ typedef int cmsBool;
|
||||
#define cmsPERCEPTUAL_BLACK_Z 0.00287
|
||||
|
||||
// Definitions in ICC spec
|
||||
#define cmsMagicNumber 0x61637370 // 'acsp'
|
||||
#define lcmsSignature 0x6c636d73 // 'lcms'
|
||||
#define cmsMagicNumber 0x61637370 // 'acsp'
|
||||
#define lcmsSignature 0x6c636d73 // 'lcms'
|
||||
|
||||
|
||||
// Base ICC type definitions
|
||||
@ -1154,7 +1162,7 @@ typedef struct {
|
||||
cmsCIEXYZ whitePoint;
|
||||
cmsFloat64Number Yb;
|
||||
cmsFloat64Number La;
|
||||
int surround;
|
||||
cmsUInt32Number surround;
|
||||
cmsFloat64Number D_value;
|
||||
|
||||
} cmsViewingConditions;
|
||||
@ -1182,16 +1190,16 @@ typedef struct {
|
||||
// The internal representation is none of your business.
|
||||
typedef struct _cms_curve_struct cmsToneCurve;
|
||||
|
||||
CMSAPI cmsToneCurve* CMSEXPORT cmsBuildSegmentedToneCurve(cmsContext ContextID, cmsInt32Number nSegments, const cmsCurveSegment Segments[]);
|
||||
CMSAPI cmsToneCurve* CMSEXPORT cmsBuildSegmentedToneCurve(cmsContext ContextID, cmsUInt32Number nSegments, const cmsCurveSegment Segments[]);
|
||||
CMSAPI cmsToneCurve* CMSEXPORT cmsBuildParametricToneCurve(cmsContext ContextID, cmsInt32Number Type, const cmsFloat64Number Params[]);
|
||||
CMSAPI cmsToneCurve* CMSEXPORT cmsBuildGamma(cmsContext ContextID, cmsFloat64Number Gamma);
|
||||
CMSAPI cmsToneCurve* CMSEXPORT cmsBuildTabulatedToneCurve16(cmsContext ContextID, cmsInt32Number nEntries, const cmsUInt16Number values[]);
|
||||
CMSAPI cmsToneCurve* CMSEXPORT cmsBuildTabulatedToneCurve16(cmsContext ContextID, cmsUInt32Number nEntries, const cmsUInt16Number values[]);
|
||||
CMSAPI cmsToneCurve* CMSEXPORT cmsBuildTabulatedToneCurveFloat(cmsContext ContextID, cmsUInt32Number nEntries, const cmsFloat32Number values[]);
|
||||
CMSAPI void CMSEXPORT cmsFreeToneCurve(cmsToneCurve* Curve);
|
||||
CMSAPI void CMSEXPORT cmsFreeToneCurveTriple(cmsToneCurve* Curve[3]);
|
||||
CMSAPI cmsToneCurve* CMSEXPORT cmsDupToneCurve(const cmsToneCurve* Src);
|
||||
CMSAPI cmsToneCurve* CMSEXPORT cmsReverseToneCurve(const cmsToneCurve* InGamma);
|
||||
CMSAPI cmsToneCurve* CMSEXPORT cmsReverseToneCurveEx(cmsInt32Number nResultSamples, const cmsToneCurve* InGamma);
|
||||
CMSAPI cmsToneCurve* CMSEXPORT cmsReverseToneCurveEx(cmsUInt32Number nResultSamples, const cmsToneCurve* InGamma);
|
||||
CMSAPI cmsToneCurve* CMSEXPORT cmsJoinToneCurve(cmsContext ContextID, const cmsToneCurve* X, const cmsToneCurve* Y, cmsUInt32Number nPoints);
|
||||
CMSAPI cmsBool CMSEXPORT cmsSmoothToneCurve(cmsToneCurve* Tab, cmsFloat64Number lambda);
|
||||
CMSAPI cmsFloat32Number CMSEXPORT cmsEvalToneCurveFloat(const cmsToneCurve* Curve, cmsFloat32Number v);
|
||||
@ -1236,7 +1244,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 int CMSEXPORT cmsPipelineInsertStage(cmsPipeline* lut, cmsStageLoc loc, cmsStage* mpe);
|
||||
CMSAPI cmsBool 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
|
||||
@ -1459,7 +1467,7 @@ CMSAPI cmsBool CMSEXPORT cmsLinkTag(cmsHPROFILE hProfile, cmsTagSignat
|
||||
CMSAPI cmsTagSignature CMSEXPORT cmsTagLinkedTo(cmsHPROFILE hProfile, cmsTagSignature sig);
|
||||
|
||||
// Read and write raw data
|
||||
CMSAPI cmsInt32Number CMSEXPORT cmsReadRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, void* Buffer, cmsUInt32Number BufferSize);
|
||||
CMSAPI cmsUInt32Number CMSEXPORT cmsReadRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, void* Buffer, cmsUInt32Number BufferSize);
|
||||
CMSAPI cmsBool CMSEXPORT cmsWriteRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, const void* data, cmsUInt32Number Size);
|
||||
|
||||
// Access header data
|
||||
@ -1550,7 +1558,7 @@ CMSAPI cmsBool CMSEXPORT cmsCloseIOhandler(cmsIOHANDLER* io);
|
||||
|
||||
CMSAPI cmsBool CMSEXPORT cmsMD5computeID(cmsHPROFILE hProfile);
|
||||
|
||||
// Profile high level funtions ------------------------------------------------------------------------------------------
|
||||
// Profile high level functions ------------------------------------------------------------------------------------------
|
||||
|
||||
CMSAPI cmsHPROFILE CMSEXPORT cmsOpenProfileFromFile(const char *ICCProfile, const char *sAccess);
|
||||
CMSAPI cmsHPROFILE CMSEXPORT cmsOpenProfileFromFileTHR(cmsContext ContextID, const char *ICCProfile, const char *sAccess);
|
||||
@ -1610,21 +1618,21 @@ CMSAPI cmsHPROFILE CMSEXPORT cmsCreate_sRGBProfileTHR(cmsContext ContextID)
|
||||
CMSAPI cmsHPROFILE CMSEXPORT cmsCreate_sRGBProfile(void);
|
||||
|
||||
CMSAPI cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfileTHR(cmsContext ContextID,
|
||||
int nLUTPoints,
|
||||
cmsUInt32Number nLUTPoints,
|
||||
cmsFloat64Number Bright,
|
||||
cmsFloat64Number Contrast,
|
||||
cmsFloat64Number Hue,
|
||||
cmsFloat64Number Saturation,
|
||||
int TempSrc,
|
||||
int TempDest);
|
||||
cmsUInt32Number TempSrc,
|
||||
cmsUInt32Number TempDest);
|
||||
|
||||
CMSAPI cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfile(int nLUTPoints,
|
||||
CMSAPI cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfile(cmsUInt32Number nLUTPoints,
|
||||
cmsFloat64Number Bright,
|
||||
cmsFloat64Number Contrast,
|
||||
cmsFloat64Number Hue,
|
||||
cmsFloat64Number Saturation,
|
||||
int TempSrc,
|
||||
int TempDest);
|
||||
cmsUInt32Number TempSrc,
|
||||
cmsUInt32Number TempDest);
|
||||
|
||||
CMSAPI cmsHPROFILE CMSEXPORT cmsCreateNULLProfileTHR(cmsContext ContextID);
|
||||
CMSAPI cmsHPROFILE CMSEXPORT cmsCreateNULLProfile(void);
|
||||
@ -1666,7 +1674,7 @@ CMSAPI cmsUInt32Number CMSEXPORT cmsGetSupportedIntentsTHR(cmsContext ContextID
|
||||
#define cmsFLAGS_BLACKPOINTCOMPENSATION 0x2000
|
||||
#define cmsFLAGS_NOWHITEONWHITEFIXUP 0x0004 // Don't fix scum dot
|
||||
#define cmsFLAGS_HIGHRESPRECALC 0x0400 // Use more memory to give better accurancy
|
||||
#define cmsFLAGS_LOWRESPRECALC 0x0800 // Use less memory to minimize resouces
|
||||
#define cmsFLAGS_LOWRESPRECALC 0x0800 // Use less memory to minimize resources
|
||||
|
||||
// For devicelink creation
|
||||
#define cmsFLAGS_8BITS_DEVICELINK 0x0008 // Create 8 bits devicelinks
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
@ -106,7 +106,7 @@
|
||||
// Maximum of channels for internal pipeline evaluation
|
||||
#define MAX_STAGE_CHANNELS 128
|
||||
|
||||
// Unused parameter warning supression
|
||||
// Unused parameter warning suppression
|
||||
#define cmsUNUSED_PARAMETER(x) ((void)x)
|
||||
|
||||
// The specification for "inline" is section 6.7.4 of the C99 standard (ISO/IEC 9899:1999).
|
||||
@ -125,8 +125,16 @@
|
||||
# ifndef vsnprintf
|
||||
# define vsnprintf _vsnprintf
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/// Properly define some macros to accommodate
|
||||
/// older MSVC versions.
|
||||
# if _MSC_VER <= 1700
|
||||
#include <float.h>
|
||||
#define isnan _isnan
|
||||
#define isinf(x) (!_finite((x)))
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
// A fast way to convert from/to 16 <-> 8 bits
|
||||
#define FROM_8_TO_16(rgb) (cmsUInt16Number) ((((cmsUInt16Number) (rgb)) << 8)|(rgb))
|
||||
@ -201,19 +209,48 @@ cmsINLINE cmsUInt16Number _cmsQuickSaturateWord(cmsFloat64Number d)
|
||||
return _cmsQuickFloorWord(d);
|
||||
}
|
||||
|
||||
// Test bed entry points---------------------------------------------------------------
|
||||
#define CMSCHECKPOINT CMSAPI
|
||||
|
||||
// Pthread support --------------------------------------------------------------------
|
||||
#ifndef CMS_NO_PTHREADS
|
||||
|
||||
// This is the threading support. Unfortunately, it has to be platform-dependent because
|
||||
// windows does not support pthreads.
|
||||
|
||||
#ifdef CMS_IS_WINDOWS_
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
// The locking scheme in LCMS requires a single 'top level' mutex
|
||||
// to work. This is actually implemented on Windows as a
|
||||
// CriticalSection, because they are lighter weight. With
|
||||
// pthreads, this is statically inited. Unfortunately, windows
|
||||
// can't officially statically init critical sections.
|
||||
//
|
||||
// We can work around this in 2 ways.
|
||||
//
|
||||
// 1) We can use a proper mutex purely to protect the init
|
||||
// of the CriticalSection. This in turns requires us to protect
|
||||
// the Mutex creation, which we can do using the snappily
|
||||
// named InterlockedCompareExchangePointer API (present on
|
||||
// windows XP and above).
|
||||
//
|
||||
// 2) In cases where we want to work on pre-Windows XP, we
|
||||
// can use an even more horrible hack described below.
|
||||
//
|
||||
// So why wouldn't we always use 2)? Because not calling
|
||||
// the init function for a critical section means it fails
|
||||
// testing with ApplicationVerifier (and presumably similar
|
||||
// tools).
|
||||
//
|
||||
// We therefore default to 1, and people who want to be able
|
||||
// to run on pre-Windows XP boxes can build with:
|
||||
// CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT
|
||||
// defined. This is automatically set for builds using
|
||||
// versions of MSVC that don't have this API available.
|
||||
//
|
||||
// From: http://locklessinc.com/articles/pthreads_on_windows/
|
||||
// The pthreads API has an initialization macro that has no correspondence to anything in
|
||||
// the windows API. By investigating the internal definition of the critical section type,
|
||||
@ -235,14 +272,30 @@ cmsINLINE cmsUInt16Number _cmsQuickSaturateWord(cmsFloat64Number d)
|
||||
|
||||
typedef CRITICAL_SECTION _cmsMutex;
|
||||
|
||||
#define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG) -1,-1,0,0,0,0}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# if (_MSC_VER >= 1800)
|
||||
# pragma warning(disable : 26135)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT
|
||||
// If we are building with a version of MSVC smaller
|
||||
// than 1400 (i.e. before VS2005) then we don't have
|
||||
// the InterlockedCompareExchangePointer API, so use
|
||||
// the old version.
|
||||
# ifdef _MSC_VER
|
||||
# if _MSC_VER < 1400
|
||||
# define CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT
|
||||
# define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG) -1,-1,0,0,0,0}
|
||||
#else
|
||||
# define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG)NULL,-1,0,0,0,0}
|
||||
#endif
|
||||
|
||||
cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
|
||||
{
|
||||
EnterCriticalSection(m);
|
||||
@ -478,7 +531,7 @@ struct _cmsContext_struct {
|
||||
void* chunks[MemoryClientMax]; // array of pointers to client chunks. Memory itself is hold in the suballocator.
|
||||
// If NULL, then it reverts to global Context0
|
||||
|
||||
_cmsMemPluginChunkType DefaultMemoryManager; // The allocators used for creating the context itself. Cannot be overriden
|
||||
_cmsMemPluginChunkType DefaultMemoryManager; // The allocators used for creating the context itself. Cannot be overridden
|
||||
};
|
||||
|
||||
// Returns a pointer to a valid context structure, including the global one if id is zero.
|
||||
@ -800,10 +853,10 @@ void _cmsTagSignature2String(char String[5], cmsTagSignature sig
|
||||
|
||||
// Interpolation ---------------------------------------------------------------------------------------------------------
|
||||
|
||||
cmsInterpParams* _cmsComputeInterpParams(cmsContext ContextID, int nSamples, int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags);
|
||||
cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags);
|
||||
void _cmsFreeInterpParams(cmsInterpParams* p);
|
||||
cmsBool _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p);
|
||||
CMSCHECKPOINT cmsInterpParams* CMSEXPORT _cmsComputeInterpParams(cmsContext ContextID, cmsUInt32Number nSamples, cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags);
|
||||
cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags);
|
||||
CMSCHECKPOINT void CMSEXPORT _cmsFreeInterpParams(cmsInterpParams* p);
|
||||
cmsBool _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p);
|
||||
|
||||
// Curves ----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@ -853,20 +906,20 @@ struct _cmsStage_struct {
|
||||
|
||||
|
||||
// Special Stages (cannot be saved)
|
||||
cmsStage* _cmsStageAllocLab2XYZ(cmsContext ContextID);
|
||||
cmsStage* _cmsStageAllocXYZ2Lab(cmsContext ContextID);
|
||||
cmsStage* _cmsStageAllocLabPrelin(cmsContext ContextID);
|
||||
cmsStage* _cmsStageAllocLabV2ToV4(cmsContext ContextID);
|
||||
cmsStage* _cmsStageAllocLabV2ToV4curves(cmsContext ContextID);
|
||||
cmsStage* _cmsStageAllocLabV4ToV2(cmsContext ContextID);
|
||||
cmsStage* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS);
|
||||
cmsStage* _cmsStageAllocIdentityCurves(cmsContext ContextID, int nChannels);
|
||||
cmsStage* _cmsStageAllocIdentityCLut(cmsContext ContextID, int nChan);
|
||||
cmsStage* _cmsStageNormalizeFromLabFloat(cmsContext ContextID);
|
||||
cmsStage* _cmsStageNormalizeFromXyzFloat(cmsContext ContextID);
|
||||
cmsStage* _cmsStageNormalizeToLabFloat(cmsContext ContextID);
|
||||
cmsStage* _cmsStageNormalizeToXyzFloat(cmsContext ContextID);
|
||||
cmsStage* _cmsStageClipNegatives(cmsContext ContextID, int nChannels);
|
||||
CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocLab2XYZ(cmsContext ContextID);
|
||||
CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocXYZ2Lab(cmsContext ContextID);
|
||||
cmsStage* _cmsStageAllocLabPrelin(cmsContext ContextID);
|
||||
CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocLabV2ToV4(cmsContext ContextID);
|
||||
cmsStage* _cmsStageAllocLabV2ToV4curves(cmsContext ContextID);
|
||||
CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocLabV4ToV2(cmsContext ContextID);
|
||||
CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS);
|
||||
CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocIdentityCurves(cmsContext ContextID, cmsUInt32Number nChannels);
|
||||
CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocIdentityCLut(cmsContext ContextID, cmsUInt32Number nChan);
|
||||
cmsStage* _cmsStageNormalizeFromLabFloat(cmsContext ContextID);
|
||||
cmsStage* _cmsStageNormalizeFromXyzFloat(cmsContext ContextID);
|
||||
cmsStage* _cmsStageNormalizeToLabFloat(cmsContext ContextID);
|
||||
cmsStage* _cmsStageNormalizeToXyzFloat(cmsContext ContextID);
|
||||
cmsStage* _cmsStageClipNegatives(cmsContext ContextID, cmsUInt32Number nChannels);
|
||||
|
||||
|
||||
// For curve set only
|
||||
@ -901,9 +954,9 @@ struct _cmsPipeline_struct {
|
||||
// Read tags using low-level function, provide necessary glue code to adapt versions, etc. All those return a brand new copy
|
||||
// of the LUTS, since ownership of original is up to the profile. The user should free allocated resources.
|
||||
|
||||
cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent);
|
||||
cmsPipeline* _cmsReadOutputLUT(cmsHPROFILE hProfile, int Intent);
|
||||
cmsPipeline* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent);
|
||||
CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadInputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent);
|
||||
CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadOutputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent);
|
||||
CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent);
|
||||
|
||||
// Special values
|
||||
cmsBool _cmsReadMediaWhitePoint(cmsCIEXYZ* Dest, cmsHPROFILE hProfile);
|
||||
@ -928,8 +981,9 @@ cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfil
|
||||
|
||||
// LUT optimization ------------------------------------------------------------------------------------------------
|
||||
|
||||
cmsUInt16Number _cmsQuantizeVal(cmsFloat64Number i, int MaxSamples);
|
||||
int _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags);
|
||||
CMSCHECKPOINT cmsUInt16Number CMSEXPORT _cmsQuantizeVal(cmsFloat64Number i, cmsUInt32Number MaxSamples);
|
||||
|
||||
cmsUInt32Number _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags);
|
||||
|
||||
cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
|
||||
cmsUInt16Number **White,
|
||||
@ -938,7 +992,7 @@ cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
|
||||
|
||||
cmsBool _cmsOptimizePipeline(cmsContext ContextID,
|
||||
cmsPipeline** Lut,
|
||||
int Intent,
|
||||
cmsUInt32Number Intent,
|
||||
cmsUInt32Number* InputFormat,
|
||||
cmsUInt32Number* OutputFormat,
|
||||
cmsUInt32Number* dwFlags );
|
||||
@ -962,17 +1016,17 @@ cmsPipeline* _cmsCreateGamutCheckPipeline(cmsContext ContextID,
|
||||
cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type);
|
||||
cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type);
|
||||
|
||||
cmsFormatter _cmsGetFormatter(cmsContext ContextID,
|
||||
cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8
|
||||
cmsFormatterDirection Dir,
|
||||
cmsUInt32Number dwFlags);
|
||||
CMSCHECKPOINT cmsFormatter CMSEXPORT _cmsGetFormatter(cmsContext ContextID,
|
||||
cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8
|
||||
cmsFormatterDirection Dir,
|
||||
cmsUInt32Number dwFlags);
|
||||
|
||||
|
||||
#ifndef CMS_NO_HALF_SUPPORT
|
||||
|
||||
// Half float
|
||||
cmsFloat32Number _cmsHalf2Float(cmsUInt16Number h);
|
||||
cmsUInt16Number _cmsFloat2Half(cmsFloat32Number flt);
|
||||
CMSCHECKPOINT cmsFloat32Number CMSEXPORT _cmsHalf2Float(cmsUInt16Number h);
|
||||
CMSCHECKPOINT cmsUInt16Number CMSEXPORT _cmsFloat2Half(cmsFloat32Number flt);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// Little Color Management System
|
||||
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||
// Copyright (c) 1998-2017 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"),
|
||||
@ -347,7 +347,7 @@ typedef struct {
|
||||
|
||||
// Parametric curves. A negative type means same function but analytically inverted. Max. number of params is 10
|
||||
|
||||
// Evaluator callback for user-suplied parametric curves. May implement more than one type
|
||||
// Evaluator callback for user-supplied parametric curves. May implement more than one type
|
||||
typedef cmsFloat64Number (* cmsParametricCurveEvaluator)(cmsInt32Number Type, const cmsFloat64Number Params[10], cmsFloat64Number R);
|
||||
|
||||
// Plug-in may implement an arbitrary number of parametric curves
|
||||
@ -457,7 +457,7 @@ typedef struct {
|
||||
cmsUInt32Number nSupportedTypes; // In how many types this tag can come (MAX_TYPES_IN_LCMS_PLUGIN maximum)
|
||||
cmsTagTypeSignature SupportedTypes[MAX_TYPES_IN_LCMS_PLUGIN];
|
||||
|
||||
// For writting
|
||||
// For writing
|
||||
cmsTagTypeSignature (* DecideType)(cmsFloat64Number ICCVersion, const void *Data);
|
||||
|
||||
} cmsTagDescriptor;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user