提交 06bdbf91 编写于 作者: P prr

8183032: Upgrade to LittleCMS 2.9

Reviewed-by: serb, psadhukhan, mschoene, rhalade
上级 6774b980
...@@ -391,12 +391,12 @@ JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative ...@@ -391,12 +391,12 @@ JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative
{ {
lcmsProfile_p sProf = (lcmsProfile_p)jlong_to_ptr(id); lcmsProfile_p sProf = (lcmsProfile_p)jlong_to_ptr(id);
TagSignature_t sig; TagSignature_t sig;
cmsInt32Number tagSize; cmsUInt32Number tagSize;
jbyte* dataArray = NULL; jbyte* dataArray = NULL;
jbyteArray data = NULL; jbyteArray data = NULL;
jint bufSize; cmsUInt32Number bufSize;
sig.j = tagSig; sig.j = tagSig;
...@@ -839,7 +839,7 @@ static cmsHPROFILE _writeCookedTag(const cmsHPROFILE pfTarget, ...@@ -839,7 +839,7 @@ static cmsHPROFILE _writeCookedTag(const cmsHPROFILE pfTarget,
for (i = 0; i < tagCount; i++) { for (i = 0; i < tagCount; i++) {
cmsBool isTagReady = FALSE; cmsBool isTagReady = FALSE;
const cmsTagSignature s = cmsGetTagSignature(pfTarget, i); 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) { if (s == sig) {
// skip the user supplied tag // skip the user supplied tag
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
...@@ -55,7 +55,6 @@ ...@@ -55,7 +55,6 @@
#include "lcms2_internal.h" #include "lcms2_internal.h"
// Alpha copy ------------------------------------------------------------------------------------------------------------------ // Alpha copy ------------------------------------------------------------------------------------------------------------------
// Floor to byte, taking care of saturation // Floor to byte, taking care of saturation
...@@ -71,16 +70,16 @@ cmsINLINE cmsUInt8Number _cmsQuickSaturateByte(cmsFloat64Number d) ...@@ -71,16 +70,16 @@ cmsINLINE cmsUInt8Number _cmsQuickSaturateByte(cmsFloat64Number d)
// Return the size in bytes of a given formatter // Return the size in bytes of a given formatter
static 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 // For double, the T_BYTES field returns zero
if (fmt_bytes == 0) if (fmt_bytes == 0)
return sizeof(double); return sizeof(double);
// Otherwise, it is already correct for all formats // Otherwise, it is already correct for all formats
return fmt_bytes; return fmt_bytes;
} }
...@@ -119,8 +118,13 @@ void from8toDBL(void* dst, const void* src) ...@@ -119,8 +118,13 @@ void from8toDBL(void* dst, const void* src)
static static
void from8toHLF(void* dst, const void* src) void from8toHLF(void* dst, const void* src)
{ {
#ifndef CMS_NO_HALF_SUPPORT
cmsFloat32Number n = (*(cmsUInt8Number*)src) / 255.0f; cmsFloat32Number n = (*(cmsUInt8Number*)src) / 255.0f;
*(cmsUInt16Number*)dst = _cmsFloat2Half(n); *(cmsUInt16Number*)dst = _cmsFloat2Half(n);
#else
cmsUNUSED_PARAMETER(dst);
cmsUNUSED_PARAMETER(src);
#endif
} }
// From 16 // From 16
...@@ -151,8 +155,13 @@ void from16toDBL(void* dst, const void* src) ...@@ -151,8 +155,13 @@ void from16toDBL(void* dst, const void* src)
static static
void from16toHLF(void* dst, const void* src) void from16toHLF(void* dst, const void* src)
{ {
#ifndef CMS_NO_HALF_SUPPORT
cmsFloat32Number n = (*(cmsUInt16Number*)src) / 65535.0f; cmsFloat32Number n = (*(cmsUInt16Number*)src) / 65535.0f;
*(cmsUInt16Number*)dst = _cmsFloat2Half(n); *(cmsUInt16Number*)dst = _cmsFloat2Half(n);
#else
cmsUNUSED_PARAMETER(dst);
cmsUNUSED_PARAMETER(src);
#endif
} }
// From Float // From Float
...@@ -187,8 +196,13 @@ void fromFLTtoDBL(void* dst, const void* src) ...@@ -187,8 +196,13 @@ void fromFLTtoDBL(void* dst, const void* src)
static static
void fromFLTtoHLF(void* dst, const void* src) void fromFLTtoHLF(void* dst, const void* src)
{ {
#ifndef CMS_NO_HALF_SUPPORT
cmsFloat32Number n = *(cmsFloat32Number*)src; cmsFloat32Number n = *(cmsFloat32Number*)src;
*(cmsUInt16Number*)dst = _cmsFloat2Half(n); *(cmsUInt16Number*)dst = _cmsFloat2Half(n);
#else
cmsUNUSED_PARAMETER(dst);
cmsUNUSED_PARAMETER(src);
#endif
} }
...@@ -197,27 +211,48 @@ void fromFLTtoHLF(void* dst, const void* src) ...@@ -197,27 +211,48 @@ void fromFLTtoHLF(void* dst, const void* src)
static static
void fromHLFto8(void* dst, const void* src) void fromHLFto8(void* dst, const void* src)
{ {
#ifndef CMS_NO_HALF_SUPPORT
cmsFloat32Number n = _cmsHalf2Float(*(cmsUInt16Number*)src); cmsFloat32Number n = _cmsHalf2Float(*(cmsUInt16Number*)src);
*(cmsUInt8Number*)dst = _cmsQuickSaturateByte(n * 255.0f); *(cmsUInt8Number*)dst = _cmsQuickSaturateByte(n * 255.0f);
#else
cmsUNUSED_PARAMETER(dst);
cmsUNUSED_PARAMETER(src);
#endif
} }
static static
void fromHLFto16(void* dst, const void* src) void fromHLFto16(void* dst, const void* src)
{ {
#ifndef CMS_NO_HALF_SUPPORT
cmsFloat32Number n = _cmsHalf2Float(*(cmsUInt16Number*)src); cmsFloat32Number n = _cmsHalf2Float(*(cmsUInt16Number*)src);
*(cmsUInt16Number*)dst = _cmsQuickSaturateWord(n * 65535.0f); *(cmsUInt16Number*)dst = _cmsQuickSaturateWord(n * 65535.0f);
#else
cmsUNUSED_PARAMETER(dst);
cmsUNUSED_PARAMETER(src);
#endif
} }
static static
void fromHLFtoFLT(void* dst, const void* src) void fromHLFtoFLT(void* dst, const void* src)
{ {
#ifndef CMS_NO_HALF_SUPPORT
*(cmsFloat32Number*)dst = _cmsHalf2Float(*(cmsUInt16Number*)src); *(cmsFloat32Number*)dst = _cmsHalf2Float(*(cmsUInt16Number*)src);
#else
cmsUNUSED_PARAMETER(dst);
cmsUNUSED_PARAMETER(src);
#endif
} }
static static
void fromHLFtoDBL(void* dst, const void* src) void fromHLFtoDBL(void* dst, const void* src)
{ {
#ifndef CMS_NO_HALF_SUPPORT
*(cmsFloat64Number*)dst = (cmsFloat64Number)_cmsHalf2Float(*(cmsUInt16Number*)src); *(cmsFloat64Number*)dst = (cmsFloat64Number)_cmsHalf2Float(*(cmsUInt16Number*)src);
#else
cmsUNUSED_PARAMETER(dst);
cmsUNUSED_PARAMETER(src);
#endif
} }
// From double // From double
...@@ -245,8 +280,13 @@ void fromDBLtoFLT(void* dst, const void* src) ...@@ -245,8 +280,13 @@ void fromDBLtoFLT(void* dst, const void* src)
static static
void fromDBLtoHLF(void* dst, const void* src) void fromDBLtoHLF(void* dst, const void* src)
{ {
#ifndef CMS_NO_HALF_SUPPORT
cmsFloat32Number n = (cmsFloat32Number) *(cmsFloat64Number*)src; cmsFloat32Number n = (cmsFloat32Number) *(cmsFloat64Number*)src;
*(cmsUInt16Number*)dst = _cmsFloat2Half(n); *(cmsUInt16Number*)dst = _cmsFloat2Half(n);
#else
cmsUNUSED_PARAMETER(dst);
cmsUNUSED_PARAMETER(src);
#endif
} }
static static
...@@ -260,21 +300,22 @@ void copy64(void* dst, const void* src) ...@@ -260,21 +300,22 @@ void copy64(void* dst, const void* src)
static static
int FormatterPos(cmsUInt32Number frm) 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 // Obtains a alpha-to-alpha funmction formatter
...@@ -310,12 +351,12 @@ void ComputeIncrementsForChunky(cmsUInt32Number Format, ...@@ -310,12 +351,12 @@ void ComputeIncrementsForChunky(cmsUInt32Number Format,
cmsUInt32Number ComponentPointerIncrements[]) cmsUInt32Number ComponentPointerIncrements[])
{ {
cmsUInt32Number channels[cmsMAXCHANNELS]; cmsUInt32Number channels[cmsMAXCHANNELS];
int extra = T_EXTRA(Format); cmsUInt32Number extra = T_EXTRA(Format);
int nchannels = T_CHANNELS(Format); cmsUInt32Number nchannels = T_CHANNELS(Format);
int total_chans = nchannels + extra; cmsUInt32Number total_chans = nchannels + extra;
int i; cmsUInt32Number i;
int channelSize = trueBytesSize(Format); cmsUInt32Number channelSize = trueBytesSize(Format);
int pixelSize = channelSize * total_chans; cmsUInt32Number pixelSize = channelSize * total_chans;
// Sanity check // Sanity check
if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS) if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS)
...@@ -368,11 +409,11 @@ void ComputeIncrementsForPlanar(cmsUInt32Number Format, ...@@ -368,11 +409,11 @@ void ComputeIncrementsForPlanar(cmsUInt32Number Format,
cmsUInt32Number ComponentPointerIncrements[]) cmsUInt32Number ComponentPointerIncrements[])
{ {
cmsUInt32Number channels[cmsMAXCHANNELS]; cmsUInt32Number channels[cmsMAXCHANNELS];
int extra = T_EXTRA(Format); cmsUInt32Number extra = T_EXTRA(Format);
int nchannels = T_CHANNELS(Format); cmsUInt32Number nchannels = T_CHANNELS(Format);
int total_chans = nchannels + extra; cmsUInt32Number total_chans = nchannels + extra;
int i; cmsUInt32Number i;
int channelSize = trueBytesSize(Format); cmsUInt32Number channelSize = trueBytesSize(Format);
// Sanity check // Sanity check
if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS) if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS)
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
...@@ -176,23 +176,24 @@ typedef struct { ...@@ -176,23 +176,24 @@ typedef struct {
SUBALLOCATOR Allocator; // String suballocator -- just to keep it fast SUBALLOCATOR Allocator; // String suballocator -- just to keep it fast
// Parser state machine // Parser state machine
SYMBOL sy; // Current symbol SYMBOL sy; // Current symbol
int ch; // Current character 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 id[MAXID]; // identifier
char str[MAXSTR]; // string char str[MAXSTR]; // string
// Allowed keywords & datasets. They have visibility on whole stream // Allowed keywords & datasets. They have visibility on whole stream
KEYVALUE* ValidKeywords; KEYVALUE* ValidKeywords;
KEYVALUE* ValidSampleID; KEYVALUE* ValidSampleID;
char* Source; // Points to loc. being parsed 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 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 char* MemoryBlock; // The stream if holded in memory
...@@ -265,65 +266,64 @@ static PROPERTY PredefinedProperties[] = { ...@@ -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. {"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. {"SERIAL", WRITE_STRINGIFY}, // Uniquely identifies individual physical target.
{"MATERIAL", WRITE_STRINGIFY}, // Identifies the material on which the target was produced using a code {"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 // 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). // 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.
{"MEASUREMENT_SOURCE", WRITE_STRINGIFY}, // Illumination used for spectral measurements. This data helps provide {"INSTRUMENTATION", WRITE_STRINGIFY}, // Used to report the specific instrumentation used (manufacturer and
// a guide to the potential for issues of paper fluorescence, etc. // 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.
{"PRINT_CONDITIONS", WRITE_STRINGIFY}, // Used to define the characteristics of the printed sheet being reported. {"MEASUREMENT_SOURCE", WRITE_STRINGIFY}, // Illumination used for spectral measurements. This data helps provide
// Where standard conditions have been defined (e.g., SWOP at nominal) // a guide to the potential for issues of paper fluorescence, etc.
// named conditions may suffice. Otherwise, detailed information is
// needed.
{"SAMPLE_BACKING", WRITE_STRINGIFY}, // Identifies the backing material used behind the sample during {"PRINT_CONDITIONS", WRITE_STRINGIFY}, // Used to define the characteristics of the printed sheet being reported.
// measurement. Allowed values are “black”, “white”, or {"na". // Where standard conditions have been defined (e.g., SWOP at nominal)
// named conditions may suffice. Otherwise, detailed information is
// needed.
{"CHISQ_DOF", WRITE_STRINGIFY}, // Degrees of freedom associated with the Chi squared statistic {"SAMPLE_BACKING", WRITE_STRINGIFY}, // Identifies the backing material used behind the sample during
// measurement. Allowed values are “black”, “white”, or {"na".
// 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 {"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, // 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, // 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, // opal or integrating sphere, etc. For reflection it is important to identify 0/45,
// 45/0, sphere (specular included or excluded), etc. // 45/0, sphere (specular included or excluded), etc.
{"FILTER", WRITE_STRINGIFY}, // Identifies the use of physical filter(s) during measurement. Typically used to {"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. // 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 {"POLARIZATION", WRITE_STRINGIFY}, // Identifies the use of a physical polarization filter during measurement. Allowed
// values are {"yes”, “white”, “none” or “na”. // values are {"yes”, “white”, “none” or “na”.
{"WEIGHTING_FUNCTION", WRITE_PAIR}, // Indicates such functions as: the CIE standard observer functions used in the {"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 // 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, // 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 // 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 // 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. // 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. // 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 // 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 // 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. // 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 {"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 // of the calculation, parameter is the name of the parameter used in the calculation
// and value is the value of the parameter. // 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)) #define NUMPREDEFINEDPROPS (sizeof(PredefinedProperties)/sizeof(PROPERTY))
...@@ -564,13 +564,13 @@ cmsFloat64Number xpow10(int n) ...@@ -564,13 +564,13 @@ cmsFloat64Number xpow10(int n)
// Reads a Real number, tries to follow from integer number // Reads a Real number, tries to follow from integer number
static 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)) { 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); NextCh(it8);
} }
...@@ -583,7 +583,7 @@ void ReadReal(cmsIT8* it8, int inum) ...@@ -583,7 +583,7 @@ void ReadReal(cmsIT8* it8, int inum)
while (isdigit(it8->ch)) { while (isdigit(it8->ch)) {
frac = frac * 10.0 + (it8->ch - '0'); frac = frac * 10.0 + (cmsFloat64Number)(it8->ch - '0');
prec++; prec++;
NextCh(it8); NextCh(it8);
} }
...@@ -594,8 +594,8 @@ void ReadReal(cmsIT8* it8, int inum) ...@@ -594,8 +594,8 @@ void ReadReal(cmsIT8* it8, int inum)
// Exponent, example 34.00E+20 // Exponent, example 34.00E+20
if (toupper(it8->ch) == 'E') { if (toupper(it8->ch) == 'E') {
int e; cmsInt32Number e;
int sgn; cmsInt32Number sgn;
NextCh(it8); sgn = 1; NextCh(it8); sgn = 1;
...@@ -610,17 +610,19 @@ void ReadReal(cmsIT8* it8, int inum) ...@@ -610,17 +610,19 @@ void ReadReal(cmsIT8* it8, int inum)
NextCh(it8); NextCh(it8);
} }
e = 0; e = 0;
while (isdigit(it8->ch)) { while (isdigit(it8->ch)) {
if ((cmsFloat64Number) e * 10L < INT_MAX) cmsInt32Number digit = (it8->ch - '0');
e = e * 10 + (it8->ch - '0');
NextCh(it8); if ((cmsFloat64Number)e * 10.0 + (cmsFloat64Number)digit < (cmsFloat64Number)+2147483647.0)
} e = e * 10 + digit;
NextCh(it8);
}
e = sgn*e; e = sgn*e;
it8 -> dnum = it8 -> dnum * xpow10(e); it8->dnum = it8->dnum * xpow10(e);
} }
} }
...@@ -638,12 +640,12 @@ cmsFloat64Number ParseFloatNumber(const char *Buffer) ...@@ -638,12 +640,12 @@ cmsFloat64Number ParseFloatNumber(const char *Buffer)
if (*Buffer == '-' || *Buffer == '+') { if (*Buffer == '-' || *Buffer == '+') {
sign = (*Buffer == '-') ? -1 : 1; sign = (*Buffer == '-') ? -1 : 1;
Buffer++; Buffer++;
} }
while (*Buffer && isdigit((int) *Buffer)) { while (*Buffer && isdigit((int)*Buffer)) {
dnum = dnum * 10.0 + (*Buffer - '0'); dnum = dnum * 10.0 + (*Buffer - '0');
if (*Buffer) Buffer++; if (*Buffer) Buffer++;
...@@ -652,11 +654,11 @@ cmsFloat64Number ParseFloatNumber(const char *Buffer) ...@@ -652,11 +654,11 @@ cmsFloat64Number ParseFloatNumber(const char *Buffer)
if (*Buffer == '.') { if (*Buffer == '.') {
cmsFloat64Number frac = 0.0; // fraction cmsFloat64Number frac = 0.0; // fraction
int prec = 0; // precission int prec = 0; // precision
if (*Buffer) Buffer++; if (*Buffer) Buffer++;
while (*Buffer && isdigit((int) *Buffer)) { while (*Buffer && isdigit((int)*Buffer)) {
frac = frac * 10.0 + (*Buffer - '0'); frac = frac * 10.0 + (*Buffer - '0');
prec++; prec++;
...@@ -687,17 +689,19 @@ cmsFloat64Number ParseFloatNumber(const char *Buffer) ...@@ -687,17 +689,19 @@ cmsFloat64Number ParseFloatNumber(const char *Buffer)
if (*Buffer) Buffer++; if (*Buffer) Buffer++;
} }
e = 0; e = 0;
while (*Buffer && isdigit((int) *Buffer)) { while (*Buffer && isdigit((int)*Buffer)) {
if ((cmsFloat64Number) e * 10L < INT_MAX) cmsInt32Number digit = (*Buffer - '0');
e = e * 10 + (*Buffer - '0');
if (*Buffer) Buffer++; if ((cmsFloat64Number)e * 10.0 + digit < (cmsFloat64Number)+2147483647.0)
} e = e * 10 + digit;
if (*Buffer) Buffer++;
}
e = sgn*e; e = sgn*e;
dnum = dnum * xpow10(e); dnum = dnum * xpow10(e);
} }
return sign * dnum; return sign * dnum;
...@@ -766,7 +770,7 @@ void InSymbol(cmsIT8* it8) ...@@ -766,7 +770,7 @@ void InSymbol(cmsIT8* it8)
if (it8->ch >= 'A' && it8->ch <= 'F') j = it8->ch -'A'+10; if (it8->ch >= 'A' && it8->ch <= 'F') j = it8->ch -'A'+10;
else j = it8->ch - '0'; 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"); SynError(it8, "Invalid hexadecimal number");
return; return;
...@@ -787,7 +791,7 @@ void InSymbol(cmsIT8* it8) ...@@ -787,7 +791,7 @@ void InSymbol(cmsIT8* it8)
{ {
j = it8->ch - '0'; 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"); SynError(it8, "Invalid binary number");
return; return;
...@@ -803,14 +807,16 @@ void InSymbol(cmsIT8* it8) ...@@ -803,14 +807,16 @@ void InSymbol(cmsIT8* it8)
while (isdigit(it8->ch)) { 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); ReadReal(it8, it8->inum);
it8->sy = SDNUM; it8->sy = SDNUM;
it8->dnum *= sign; it8->dnum *= sign;
return; return;
} }
it8->inum = it8->inum * 10 + (it8->ch - '0'); it8->inum = it8->inum * 10 + digit;
NextCh(it8); NextCh(it8);
} }
...@@ -1515,8 +1521,8 @@ cmsBool SetDataFormat(cmsIT8* it8, int n, const char *label) ...@@ -1515,8 +1521,8 @@ cmsBool SetDataFormat(cmsIT8* it8, int n, const char *label)
cmsBool CMSEXPORT cmsIT8SetDataFormat(cmsHANDLE h, int n, const char *Sample) cmsBool CMSEXPORT cmsIT8SetDataFormat(cmsHANDLE h, int n, const char *Sample)
{ {
cmsIT8* it8 = (cmsIT8*) h; cmsIT8* it8 = (cmsIT8*)h;
return SetDataFormat(it8, n, Sample); return SetDataFormat(it8, n, Sample);
} }
static static
...@@ -1541,8 +1547,8 @@ static ...@@ -1541,8 +1547,8 @@ static
char* GetData(cmsIT8* it8, int nSet, int nField) char* GetData(cmsIT8* it8, int nSet, int nField)
{ {
TABLE* t = GetTable(it8); TABLE* t = GetTable(it8);
int nSamples = t -> nSamples; int nSamples = t -> nSamples;
int nPatches = t -> nPatches; int nPatches = t -> nPatches;
if (nSet >= nPatches || nField >= nSamples) if (nSet >= nPatches || nField >= nSamples)
return NULL; return NULL;
...@@ -1973,67 +1979,67 @@ cmsBool HeaderSection(cmsIT8* it8) ...@@ -1973,67 +1979,67 @@ cmsBool HeaderSection(cmsIT8* it8)
case SIDENT: case SIDENT:
strncpy(VarName, it8->id, MAXID-1); strncpy(VarName, it8->id, MAXID - 1);
VarName[MAXID-1] = 0; VarName[MAXID - 1] = 0;
if (!IsAvailableOnList(it8-> ValidKeywords, VarName, NULL, &Key)) { if (!IsAvailableOnList(it8->ValidKeywords, VarName, NULL, &Key)) {
#ifdef CMS_STRICT_CGATS #ifdef CMS_STRICT_CGATS
return SynError(it8, "Undefined keyword '%s'", VarName); return SynError(it8, "Undefined keyword '%s'", VarName);
#else #else
Key = AddAvailableProperty(it8, VarName, WRITE_UNCOOKED); Key = AddAvailableProperty(it8, VarName, WRITE_UNCOOKED);
if (Key == NULL) return FALSE; if (Key == NULL) return FALSE;
#endif #endif
} }
InSymbol(it8); InSymbol(it8);
if (!GetVal(it8, Buffer, MAXSTR-1, "Property data expected")) return FALSE; if (!GetVal(it8, Buffer, MAXSTR - 1, "Property data expected")) return FALSE;
if(Key->WriteAs != WRITE_PAIR) { if (Key->WriteAs != WRITE_PAIR) {
AddToList(it8, &GetTable(it8)->HeaderList, VarName, NULL, Buffer, AddToList(it8, &GetTable(it8)->HeaderList, VarName, NULL, Buffer,
(it8->sy == SSTRING) ? WRITE_STRINGIFY : WRITE_UNCOOKED); (it8->sy == SSTRING) ? WRITE_STRINGIFY : WRITE_UNCOOKED);
} }
else { else {
const char *Subkey; const char *Subkey;
char *Nextkey; char *Nextkey;
if (it8->sy != SSTRING) if (it8->sy != SSTRING)
return SynError(it8, "Invalid value '%s' for property '%s'.", Buffer, VarName); 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 // chop the string as a list of "subkey, value" pairs, using ';' as a separator
for (Subkey = Buffer; Subkey != NULL; Subkey = Nextkey) for (Subkey = Buffer; Subkey != NULL; Subkey = Nextkey)
{ {
char *Value, *temp; char *Value, *temp;
// identify token pair boundary // identify token pair boundary
Nextkey = (char*) strchr(Subkey, ';'); Nextkey = (char*)strchr(Subkey, ';');
if(Nextkey) if (Nextkey)
*Nextkey++ = '\0'; *Nextkey++ = '\0';
// for each pair, split the subkey and the value // for each pair, split the subkey and the value
Value = (char*) strrchr(Subkey, ','); Value = (char*)strrchr(Subkey, ',');
if(Value == NULL) if (Value == NULL)
return SynError(it8, "Invalid value for property '%s'.", VarName); return SynError(it8, "Invalid value for property '%s'.", VarName);
// gobble the spaces before the coma, and the coma itself // gobble the spaces before the coma, and the coma itself
temp = Value++; temp = Value++;
do *temp-- = '\0'; while(temp >= Subkey && *temp == ' '); do *temp-- = '\0'; while (temp >= Subkey && *temp == ' ');
// gobble any space at the right // gobble any space at the right
temp = Value + strlen(Value) - 1; temp = Value + strlen(Value) - 1;
while(*temp == ' ') *temp-- = '\0'; while (*temp == ' ') *temp-- = '\0';
// trim the strings from the left // trim the strings from the left
Subkey += strspn(Subkey, " "); Subkey += strspn(Subkey, " ");
Value += strspn(Value, " "); Value += strspn(Value, " ");
if(Subkey[0] == 0 || Value[0] == 0) if (Subkey[0] == 0 || Value[0] == 0)
return SynError(it8, "Invalid value for property '%s'.", VarName); return SynError(it8, "Invalid value for property '%s'.", VarName);
AddToList(it8, &GetTable(it8)->HeaderList, VarName, Subkey, Value, WRITE_PAIR); AddToList(it8, &GetTable(it8)->HeaderList, VarName, Subkey, Value, WRITE_PAIR);
}
} }
}
InSymbol(it8); InSymbol(it8);
break; break;
case SEOLN: break; case SEOLN: break;
...@@ -2062,7 +2068,6 @@ void ReadType(cmsIT8* it8, char* SheetTypePtr) ...@@ -2062,7 +2068,6 @@ void ReadType(cmsIT8* it8, char* SheetTypePtr)
while (it8->ch != '\r' && it8 ->ch != '\n' && it8->ch != '\t' && it8 -> ch != 0) { while (it8->ch != '\r' && it8 ->ch != '\n' && it8->ch != '\t' && it8 -> ch != 0) {
*SheetTypePtr++= (char) it8 ->ch;
if (cnt++ < MAXSTR) if (cnt++ < MAXSTR)
*SheetTypePtr++= (char) it8 ->ch; *SheetTypePtr++= (char) it8 ->ch;
NextCh(it8); NextCh(it8);
...@@ -2257,10 +2262,10 @@ void CookPointers(cmsIT8* it8) ...@@ -2257,10 +2262,10 @@ void CookPointers(cmsIT8* it8)
// that should be something like some printable characters plus a \n // 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? // returns 0 if this is not like a CGATS, or an integer otherwise. This integer is the number of words in first line?
static static
int IsMyBlock(const cmsUInt8Number* Buffer, int n) int IsMyBlock(const cmsUInt8Number* Buffer, cmsUInt32Number n)
{ {
int words = 1, space = 0, quot = 0; int words = 1, space = 0, quot = 0;
int i; cmsUInt32Number i;
if (n < 10) return 0; // Too small if (n < 10) return 0; // Too small
...@@ -2748,7 +2753,7 @@ int CMSEXPORT cmsIT8SetTableByLabel(cmsHANDLE hIT8, const char* cSet, const char ...@@ -2748,7 +2753,7 @@ int CMSEXPORT cmsIT8SetTableByLabel(cmsHANDLE hIT8, const char* cSet, const char
{ {
const char* cLabelFld; const char* cLabelFld;
char Type[256], Label[256]; char Type[256], Label[256];
int nTable; cmsUInt32Number nTable;
_cmsAssert(hIT8 != NULL); _cmsAssert(hIT8 != NULL);
...@@ -2761,7 +2766,7 @@ int CMSEXPORT cmsIT8SetTableByLabel(cmsHANDLE hIT8, const char* cSet, const char ...@@ -2761,7 +2766,7 @@ int CMSEXPORT cmsIT8SetTableByLabel(cmsHANDLE hIT8, const char* cSet, const char
cLabelFld = cmsIT8GetData(hIT8, cSet, cField); cLabelFld = cmsIT8GetData(hIT8, cSet, cField);
if (!cLabelFld) return -1; 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; return -1;
if (ExpectedType != NULL && *ExpectedType == 0) if (ExpectedType != NULL && *ExpectedType == 0)
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
...@@ -392,11 +392,12 @@ cmsBool IsEmptyLayer(cmsMAT3* m, cmsVEC3* off) ...@@ -392,11 +392,12 @@ cmsBool IsEmptyLayer(cmsMAT3* m, cmsVEC3* off)
// Compute the conversion layer // Compute the conversion layer
static static
cmsBool ComputeConversion(int i, cmsHPROFILE hProfiles[], cmsBool ComputeConversion(cmsUInt32Number i,
cmsUInt32Number Intent, cmsHPROFILE hProfiles[],
cmsBool BPC, cmsUInt32Number Intent,
cmsFloat64Number AdaptationState, cmsBool BPC,
cmsMAT3* m, cmsVEC3* off) cmsFloat64Number AdaptationState,
cmsMAT3* m, cmsVEC3* off)
{ {
int k; int k;
...@@ -708,7 +709,7 @@ cmsPipeline* CMSEXPORT _cmsDefaultICCintents(cmsContext ContextID, ...@@ -708,7 +709,7 @@ cmsPipeline* CMSEXPORT _cmsDefaultICCintents(cmsContext ContextID,
// Translate black-preserving intents to ICC ones // Translate black-preserving intents to ICC ones
static static
int TranslateNonICCIntents(int Intent) cmsUInt32Number TranslateNonICCIntents(cmsUInt32Number Intent)
{ {
switch (Intent) { switch (Intent) {
case INTENT_PRESERVE_K_ONLY_PERCEPTUAL: case INTENT_PRESERVE_K_ONLY_PERCEPTUAL:
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
...@@ -83,9 +83,11 @@ long int CMSEXPORT cmsfilelength(FILE* f) ...@@ -83,9 +83,11 @@ long int CMSEXPORT cmsfilelength(FILE* f)
long int p , n; long int p , n;
p = ftell(f); // register current file position p = ftell(f); // register current file position
if (p == -1L)
return -1L;
if (fseek(f, 0, SEEK_END) != 0) { if (fseek(f, 0, SEEK_END) != 0) {
return -1; return -1L;
} }
n = ftell(f); n = ftell(f);
...@@ -115,7 +117,7 @@ cmsBool _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plug ...@@ -115,7 +117,7 @@ cmsBool _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plug
// ********************************************************************************* // *********************************************************************************
// This is the default memory allocation function. It does a very coarse // This is the default memory allocation function. It does a very coarse
// check of amout of memory, just to prevent exploits // check of amount of memory, just to prevent exploits
static static
void* _cmsMallocDefaultFn(cmsContext ContextID, cmsUInt32Number size) void* _cmsMallocDefaultFn(cmsContext ContextID, cmsUInt32Number size)
{ {
...@@ -222,7 +224,7 @@ void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx, const struct _cmsCo ...@@ -222,7 +224,7 @@ void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx, const struct _cmsCo
} }
else { 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; ctx ->chunks[MemPlugin] = &ctx ->DefaultMemoryManager;
} }
} }
......
...@@ -73,10 +73,11 @@ ...@@ -73,10 +73,11 @@
// The list of supported parametric curves // The list of supported parametric curves
typedef struct _cmsParametricCurvesCollection_st { typedef struct _cmsParametricCurvesCollection_st {
int nFunctions; // Number of supported functions in this chunk cmsUInt32Number nFunctions; // Number of supported functions in this chunk
int FunctionTypes[MAX_TYPES_IN_LCMS_PLUGIN]; // The identification types cmsInt32Number FunctionTypes[MAX_TYPES_IN_LCMS_PLUGIN]; // The identification types
int ParameterCount[MAX_TYPES_IN_LCMS_PLUGIN]; // Number of parameters for each function cmsUInt32Number ParameterCount[MAX_TYPES_IN_LCMS_PLUGIN]; // Number of parameters for each function
cmsParametricCurveEvaluator Evaluator; // The evaluator
cmsParametricCurveEvaluator Evaluator; // The evaluator
struct _cmsParametricCurvesCollection_st* Next; // Next in list struct _cmsParametricCurvesCollection_st* Next; // Next in list
...@@ -194,7 +195,7 @@ int IsInSet(int Type, _cmsParametricCurvesCollection* c) ...@@ -194,7 +195,7 @@ int IsInSet(int Type, _cmsParametricCurvesCollection* c)
{ {
int i; 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; if (abs(Type) == c ->FunctionTypes[i]) return i;
return -1; return -1;
...@@ -238,20 +239,20 @@ _cmsParametricCurvesCollection *GetParametricCurveByType(cmsContext ContextID, i ...@@ -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 // 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 // optimization curve is given. Both features simultaneously is an error
static static
cmsToneCurve* AllocateToneCurveStruct(cmsContext ContextID, cmsInt32Number nEntries, cmsToneCurve* AllocateToneCurveStruct(cmsContext ContextID, cmsUInt32Number nEntries,
cmsInt32Number nSegments, const cmsCurveSegment* Segments, cmsUInt32Number nSegments, const cmsCurveSegment* Segments,
const cmsUInt16Number* Values) const cmsUInt16Number* Values)
{ {
cmsToneCurve* p; cmsToneCurve* p;
int i; cmsUInt32Number i;
// We allow huge tables, which are then restricted for smoothing operations // 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"); cmsSignalError(ContextID, cmsERROR_RANGE, "Couldn't create tone curve of more than 65530 entries");
return NULL; 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"); cmsSignalError(ContextID, cmsERROR_RANGE, "Couldn't create tone curve with zero segments and no table");
return NULL; return NULL;
} }
...@@ -261,7 +262,7 @@ cmsToneCurve* AllocateToneCurveStruct(cmsContext ContextID, cmsInt32Number nEntr ...@@ -261,7 +262,7 @@ cmsToneCurve* AllocateToneCurveStruct(cmsContext ContextID, cmsInt32Number nEntr
if (!p) return NULL; if (!p) return NULL;
// In this case, there are no segments // In this case, there are no segments
if (nSegments <= 0) { if (nSegments == 0) {
p ->Segments = NULL; p ->Segments = NULL;
p ->Evals = NULL; p ->Evals = NULL;
} }
...@@ -277,7 +278,7 @@ cmsToneCurve* AllocateToneCurveStruct(cmsContext ContextID, cmsInt32Number nEntr ...@@ -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 // This 16-bit table contains a limited precision representation of the whole curve and is kept for
// increasing xput on certain operations. // increasing xput on certain operations.
if (nEntries <= 0) { if (nEntries == 0) {
p ->Table16 = NULL; p ->Table16 = NULL;
} }
else { else {
...@@ -303,7 +304,7 @@ cmsToneCurve* AllocateToneCurveStruct(cmsContext ContextID, cmsInt32Number nEntr ...@@ -303,7 +304,7 @@ cmsToneCurve* AllocateToneCurveStruct(cmsContext ContextID, cmsInt32Number nEntr
p ->SegInterp = (cmsInterpParams**) _cmsCalloc(ContextID, nSegments, sizeof(cmsInterpParams*)); p ->SegInterp = (cmsInterpParams**) _cmsCalloc(ContextID, nSegments, sizeof(cmsInterpParams*));
if (p ->SegInterp == NULL) goto Error; 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 // Type 0 is a special marker for table-based curves
if (Segments[i].Type == 0) if (Segments[i].Type == 0)
...@@ -359,7 +360,7 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu ...@@ -359,7 +360,7 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
// Type 1 Reversed: X = Y ^1/gamma // Type 1 Reversed: X = Y ^1/gamma
case -1: case -1:
if (R < 0) { if (R < 0) {
if (fabs(Params[0] - 1.0) < MATRIX_DET_TOLERANCE) if (fabs(Params[0] - 1.0) < MATRIX_DET_TOLERANCE)
Val = R; Val = R;
...@@ -367,80 +368,123 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu ...@@ -367,80 +368,123 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
Val = 0; Val = 0;
} }
else 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; break;
// CIE 122-1966 // CIE 122-1966
// Y = (aX + b)^Gamma | X >= -b/a // Y = (aX + b)^Gamma | X >= -b/a
// Y = 0 | else // Y = 0 | else
case 2: 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) e = Params[1] * R + Params[2];
Val = pow(e, Params[0]);
if (e > 0)
Val = pow(e, Params[0]);
else
Val = 0;
}
else else
Val = 0; Val = 0;
} }
else }
Val = 0; break;
break;
// Type 2 Reversed // Type 2 Reversed
// X = (Y ^1/g - b) / a // X = (Y ^1/g - b) / a
case -2: case -2:
if (R < 0) {
if (fabs(Params[0]) < MATRIX_DET_TOLERANCE ||
fabs(Params[1]) < MATRIX_DET_TOLERANCE)
{
Val = 0; Val = 0;
}
else 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) if (Val < 0)
Val = 0; Val = 0;
break; }
}
break;
// IEC 61966-3 // IEC 61966-3
// Y = (aX + b)^Gamma | X <= -b/a // Y = (aX + b)^Gamma | X <= -b/a
// Y = c | else // Y = c | else
case 3: case 3:
disc = -Params[2] / Params[1]; {
if (disc < 0) if (fabs(Params[1]) < MATRIX_DET_TOLERANCE)
disc = 0; {
Val = 0;
}
else
{
disc = -Params[2] / Params[1];
if (disc < 0)
disc = 0;
if (R >= disc) { if (R >= disc) {
e = Params[1]*R + Params[2]; e = Params[1] * R + Params[2];
if (e > 0) if (e > 0)
Val = pow(e, Params[0]) + Params[3]; Val = pow(e, Params[0]) + Params[3];
else
Val = 0;
}
else else
Val = 0; Val = Params[3];
} }
else }
Val = Params[3]; break;
break;
// Type 3 reversed // Type 3 reversed
// X=((Y-c)^1/g - b)/a | (Y>=c) // X=((Y-c)^1/g - b)/a | (Y>=c)
// X=-b/a | (Y<c) // X=-b/a | (Y<c)
case -3: case -3:
if (R >= Params[3]) { {
if (fabs(Params[1]) < MATRIX_DET_TOLERANCE)
{
Val = 0;
}
else
{
if (R >= Params[3]) {
e = R - Params[3]; e = R - Params[3];
if (e > 0) if (e > 0)
Val = (pow(e, 1/Params[0]) - Params[2]) / Params[1]; Val = (pow(e, 1 / Params[0]) - Params[2]) / Params[1];
else else
Val = 0; Val = 0;
} }
else { else {
Val = -Params[2] / Params[1]; Val = -Params[2] / Params[1];
}
} }
break; }
break;
// IEC 61966-2.1 (sRGB) // IEC 61966-2.1 (sRGB)
...@@ -464,20 +508,31 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu ...@@ -464,20 +508,31 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
// X=((Y^1/g-b)/a) | Y >= (ad+b)^g // X=((Y^1/g-b)/a) | Y >= (ad+b)^g
// X=Y/c | Y< (ad+b)^g // X=Y/c | Y< (ad+b)^g
case -4: case -4:
e = Params[1] * Params[4] + Params[2]; {
if (e < 0) if (fabs(Params[0]) < MATRIX_DET_TOLERANCE ||
disc = 0; fabs(Params[1]) < MATRIX_DET_TOLERANCE ||
fabs(Params[3]) < MATRIX_DET_TOLERANCE)
{
Val = 0;
}
else 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 { else {
Val = R / Params[3]; Val = R / Params[3];
}
} }
break; }
break;
// Y = (aX + b)^Gamma + e | X >= d // Y = (aX + b)^Gamma + e | X >= d
...@@ -501,20 +556,29 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu ...@@ -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-e)1/g-b)/a | Y >=(ad+b)^g+e), cd+f
// X=(Y-f)/c | else // X=(Y-f)/c | else
case -5: case -5:
{
disc = Params[3] * Params[4] + Params[6]; if (fabs(Params[1]) < MATRIX_DET_TOLERANCE ||
if (R >= disc) { fabs(Params[3]) < MATRIX_DET_TOLERANCE)
{
e = R - Params[5]; Val = 0;
if (e < 0)
Val = 0;
else
Val = (pow(e, 1.0/Params[0]) - Params[2]) / Params[1];
} }
else { else
Val = (R - Params[6]) / Params[3]; {
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 // 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 ...@@ -532,12 +596,21 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
// ((Y - c) ^1/Gamma - b) / a // ((Y - c) ^1/Gamma - b) / a
case -6: case -6:
e = R - Params[3]; {
if (e < 0) if (fabs(Params[1]) < MATRIX_DET_TOLERANCE)
{
Val = 0; Val = 0;
}
else 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 // Y = a * log (b * X^Gamma + c) + d
...@@ -554,8 +627,19 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu ...@@ -554,8 +627,19 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
// pow(10, (Y-d) / a) = b * X ^Gamma + c // pow(10, (Y-d) / a) = b * X ^Gamma + c
// pow((pow(10, (Y-d) / a) - c) / b, 1/g) = X // pow((pow(10, (Y-d) / a) - c) / b, 1/g) = X
case -7: 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 //Y = a * b^(c*X+d) + e
...@@ -571,12 +655,25 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu ...@@ -571,12 +655,25 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
disc = R - Params[4]; disc = R - Params[4];
if (disc < 0) Val = 0; if (disc < 0) Val = 0;
else 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; break;
// S-Shaped: (1 - (1-x)^1/g)^1/g // S-Shaped: (1 - (1-x)^1/g)^1/g
case 108: 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; break;
// y = (1 - (1-x)^1/g)^1/g // y = (1 - (1-x)^1/g)^1/g
...@@ -596,33 +693,45 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu ...@@ -596,33 +693,45 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
return Val; 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 // If fn type is 0, perform an interpolation on the table
static static
cmsFloat64Number EvalSegmentedFn(const cmsToneCurve *g, cmsFloat64Number R) cmsFloat64Number EvalSegmentedFn(const cmsToneCurve *g, cmsFloat64Number R)
{ {
int i; 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 // 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 // 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 R1 = (cmsFloat32Number)(R - g->Segments[i].x0) / (g->Segments[i].x1 - g->Segments[i].x0);
cmsFloat32Number Out;
// Setup the table (TODO: clean that) // 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 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 ...@@ -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 // Create an empty gamma curve, by using tables. This specifies only the limited-precision part, and leaves the
// floating point description empty. // 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); return AllocateToneCurveStruct(ContextID, nEntries, 0, NULL, Values);
} }
static static
int EntriesByGamma(cmsFloat64Number Gamma) cmsUInt32Number EntriesByGamma(cmsFloat64Number Gamma)
{ {
if (fabs(Gamma - 1.0) < 0.001) return 2; if (fabs(Gamma - 1.0) < 0.001) return 2;
return 4096; return 4096;
...@@ -660,12 +769,12 @@ int EntriesByGamma(cmsFloat64Number Gamma) ...@@ -660,12 +769,12 @@ int EntriesByGamma(cmsFloat64Number Gamma)
// Create a segmented gamma, fill the table // Create a segmented gamma, fill the table
cmsToneCurve* CMSEXPORT cmsBuildSegmentedToneCurve(cmsContext ContextID, cmsToneCurve* CMSEXPORT cmsBuildSegmentedToneCurve(cmsContext ContextID,
cmsInt32Number nSegments, const cmsCurveSegment Segments[]) cmsUInt32Number nSegments, const cmsCurveSegment Segments[])
{ {
int i; cmsUInt32Number i;
cmsFloat64Number R, Val; cmsFloat64Number R, Val;
cmsToneCurve* g; cmsToneCurve* g;
int nGridPoints = 4096; cmsUInt32Number nGridPoints = 4096;
_cmsAssert(Segments != NULL); _cmsAssert(Segments != NULL);
...@@ -680,7 +789,7 @@ cmsToneCurve* CMSEXPORT cmsBuildSegmentedToneCurve(cmsContext ContextID, ...@@ -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 // 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 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); R = (cmsFloat64Number) i / (nGridPoints-1);
...@@ -893,7 +1002,7 @@ int GetInterval(cmsFloat64Number In, const cmsUInt16Number LutTable[], const str ...@@ -893,7 +1002,7 @@ int GetInterval(cmsFloat64Number In, const cmsUInt16Number LutTable[], const str
if (LutTable[0] < LutTable[p ->Domain[0]]) { if (LutTable[0] < LutTable[p ->Domain[0]]) {
// Table is overall ascending // 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]; y0 = LutTable[i];
y1 = LutTable[i+1]; y1 = LutTable[i+1];
...@@ -928,7 +1037,7 @@ int GetInterval(cmsFloat64Number In, const cmsUInt16Number LutTable[], const str ...@@ -928,7 +1037,7 @@ int GetInterval(cmsFloat64Number In, const cmsUInt16Number LutTable[], const str
} }
// Reverse a gamma table // Reverse a gamma table
cmsToneCurve* CMSEXPORT cmsReverseToneCurveEx(cmsInt32Number nResultSamples, const cmsToneCurve* InCurve) cmsToneCurve* CMSEXPORT cmsReverseToneCurveEx(cmsUInt32Number nResultSamples, const cmsToneCurve* InCurve)
{ {
cmsToneCurve *out; cmsToneCurve *out;
cmsFloat64Number a = 0, b = 0, y, x1, y1, x2, y2; cmsFloat64Number a = 0, b = 0, y, x1, y1, x2, y2;
...@@ -957,7 +1066,7 @@ cmsToneCurve* CMSEXPORT cmsReverseToneCurveEx(cmsInt32Number nResultSamples, con ...@@ -957,7 +1066,7 @@ cmsToneCurve* CMSEXPORT cmsReverseToneCurveEx(cmsInt32Number nResultSamples, con
Ascending = !cmsIsToneCurveDescending(InCurve); Ascending = !cmsIsToneCurveDescending(InCurve);
// Iterate across Y axis // Iterate across Y axis
for (i=0; i < nResultSamples; i++) { for (i=0; i < (int) nResultSamples; i++) {
y = (cmsFloat64Number) i * 65535.0 / (nResultSamples - 1); y = (cmsFloat64Number) i * 65535.0 / (nResultSamples - 1);
...@@ -1012,7 +1121,8 @@ cmsToneCurve* CMSEXPORT cmsReverseToneCurve(const cmsToneCurve* InGamma) ...@@ -1012,7 +1121,8 @@ cmsToneCurve* CMSEXPORT cmsReverseToneCurve(const cmsToneCurve* InGamma)
// Output: smoothed vector (z): vector from 1 to m. // Output: smoothed vector (z): vector from 1 to m.
static 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; int i, i1, i2;
cmsFloat32Number *c, *d, *e; cmsFloat32Number *c, *d, *e;
...@@ -1071,73 +1181,121 @@ cmsBool smooth2(cmsContext ContextID, cmsFloat32Number w[], cmsFloat32Number y[] ...@@ -1071,73 +1181,121 @@ cmsBool smooth2(cmsContext ContextID, cmsFloat32Number w[], cmsFloat32Number y[]
// Smooths a curve sampled at regular intervals. // Smooths a curve sampled at regular intervals.
cmsBool CMSEXPORT cmsSmoothToneCurve(cmsToneCurve* Tab, cmsFloat64Number lambda) cmsBool CMSEXPORT cmsSmoothToneCurve(cmsToneCurve* Tab, cmsFloat64Number lambda)
{ {
cmsFloat32Number w[MAX_NODES_IN_CURVE], y[MAX_NODES_IN_CURVE], z[MAX_NODES_IN_CURVE]; cmsBool SuccessStatus = TRUE;
int i, nItems, Zeros, Poles; cmsFloat32Number *w, *y, *z;
cmsUInt32Number i, nItems, Zeros, Poles;
if (Tab == NULL) return FALSE; if (Tab != NULL && Tab->InterpParams != NULL)
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++)
{ {
y[i+1] = (cmsFloat32Number) Tab -> Table16[i]; cmsContext ContextID = Tab->InterpParams->ContextID;
w[i+1] = 1.0;
} 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));
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));
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 (!smooth2(Tab ->InterpParams->ContextID, w, y, z, (cmsFloat32Number) lambda, nItems)) return FALSE; if (z != NULL)
_cmsFree(ContextID, z);
// Do some reality - checking... if (y != NULL)
Zeros = Poles = 0; _cmsFree(ContextID, y);
for (i=nItems; i > 1; --i) {
if (z[i] == 0.) Zeros++; if (w != NULL)
if (z[i] >= 65535.) Poles++; _cmsFree(ContextID, w);
if (z[i] < z[i-1]) { }
cmsSignalError(Tab ->InterpParams->ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Non-Monotonic."); else // too many items in the table
return FALSE; {
cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Too many points.");
SuccessStatus = FALSE;
}
} }
} }
else // Tab parameter or Tab->InterpParams is NULL
if (Zeros > (nItems / 3)) { {
cmsSignalError(Tab ->InterpParams->ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Degenerated, mostly zeros."); // Can't signal an error here since the ContextID is not known at this point
return FALSE; SuccessStatus = FALSE;
}
if (Poles > (nItems / 3)) {
cmsSignalError(Tab ->InterpParams->ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Degenerated, mostly poles.");
return FALSE;
}
// Seems ok
for (i=0; i < nItems; i++) {
// 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 // 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. // 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) cmsBool CMSEXPORT cmsIsToneCurveLinear(const cmsToneCurve* Curve)
{ {
cmsUInt32Number i; int i;
int diff; int diff;
_cmsAssert(Curve != NULL); _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)); diff = abs((int) Curve->Table16[i] - (int) _cmsQuantizeVal(i, Curve ->nEntries));
if (diff > 0x0f) if (diff > 0x0f)
...@@ -1150,7 +1308,7 @@ cmsBool CMSEXPORT cmsIsToneCurveLinear(const cmsToneCurve* Curve) ...@@ -1150,7 +1308,7 @@ cmsBool CMSEXPORT cmsIsToneCurveLinear(const cmsToneCurve* Curve)
// Same, but for monotonicity // Same, but for monotonicity
cmsBool CMSEXPORT cmsIsToneCurveMonotonic(const cmsToneCurve* t) cmsBool CMSEXPORT cmsIsToneCurveMonotonic(const cmsToneCurve* t)
{ {
int n; cmsUInt32Number n;
int i, last; int i, last;
cmsBool lDescending; cmsBool lDescending;
...@@ -1167,7 +1325,7 @@ cmsBool CMSEXPORT cmsIsToneCurveMonotonic(const cmsToneCurve* t) ...@@ -1167,7 +1325,7 @@ cmsBool CMSEXPORT cmsIsToneCurveMonotonic(const cmsToneCurve* t)
last = t ->Table16[0]; 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 if (t ->Table16[i] - last > 2) // We allow some ripple
return FALSE; return FALSE;
...@@ -1180,7 +1338,7 @@ cmsBool CMSEXPORT cmsIsToneCurveMonotonic(const cmsToneCurve* t) ...@@ -1180,7 +1338,7 @@ cmsBool CMSEXPORT cmsIsToneCurveMonotonic(const cmsToneCurve* t)
last = t ->Table16[n-1]; 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) if (t ->Table16[i] - last > 2)
return FALSE; return FALSE;
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
...@@ -326,7 +326,7 @@ cmsPipeline* _cmsCreateGamutCheckPipeline(cmsContext ContextID, ...@@ -326,7 +326,7 @@ cmsPipeline* _cmsCreateGamutCheckPipeline(cmsContext ContextID,
cmsStage* CLUT; cmsStage* CLUT;
cmsUInt32Number dwFormat; cmsUInt32Number dwFormat;
GAMUTCHAIN Chain; GAMUTCHAIN Chain;
int nChannels, nGridpoints; cmsUInt32Number nChannels, nGridpoints;
cmsColorSpaceSignature ColorSpace; cmsColorSpaceSignature ColorSpace;
cmsUInt32Number i; cmsUInt32Number i;
cmsHPROFILE ProfileList[256]; cmsHPROFILE ProfileList[256];
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
...@@ -532,7 +532,7 @@ static cmsUInt8Number Shift[512] = { ...@@ -532,7 +532,7 @@ static cmsUInt8Number Shift[512] = {
0x18, 0x18, 0x18, 0x18, 0x0d 0x18, 0x18, 0x18, 0x18, 0x0d
}; };
cmsFloat32Number _cmsHalf2Float(cmsUInt16Number h) cmsFloat32Number CMSEXPORT _cmsHalf2Float(cmsUInt16Number h)
{ {
union { union {
cmsFloat32Number flt; cmsFloat32Number flt;
...@@ -545,7 +545,7 @@ cmsFloat32Number _cmsHalf2Float(cmsUInt16Number h) ...@@ -545,7 +545,7 @@ cmsFloat32Number _cmsHalf2Float(cmsUInt16Number h)
return out.flt; return out.flt;
} }
cmsUInt16Number _cmsFloat2Half(cmsFloat32Number flt) cmsUInt16Number CMSEXPORT _cmsFloat2Half(cmsFloat32Number flt)
{ {
union { union {
cmsFloat32Number flt; cmsFloat32Number flt;
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
...@@ -58,6 +58,13 @@ ...@@ -58,6 +58,13 @@
// This module incorporates several interpolation routines, for 1 to 8 channels on input and // 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 // 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 // Interpolation routines by default
static cmsInterpFunction DefaultInterpolatorsFactory(cmsUInt32Number nInputChannels, cmsUInt32Number nOutputChannels, cmsUInt32Number dwFlags); static cmsInterpFunction DefaultInterpolatorsFactory(cmsUInt32Number nInputChannels, cmsUInt32Number nOutputChannels, cmsUInt32Number dwFlags);
...@@ -131,12 +138,12 @@ cmsBool _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p) ...@@ -131,12 +138,12 @@ cmsBool _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p)
// This function precalculates as many parameters as possible to speed up the interpolation. // This function precalculates as many parameters as possible to speed up the interpolation.
cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID, cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID,
const cmsUInt32Number nSamples[], const cmsUInt32Number nSamples[],
int InputChan, int OutputChan, cmsUInt32Number InputChan, cmsUInt32Number OutputChan,
const void *Table, const void *Table,
cmsUInt32Number dwFlags) cmsUInt32Number dwFlags)
{ {
cmsInterpParams* p; cmsInterpParams* p;
int i; cmsUInt32Number i;
// Check for maximum inputs // Check for maximum inputs
if (InputChan > MAX_INPUT_DIMENSIONS) { if (InputChan > MAX_INPUT_DIMENSIONS) {
...@@ -180,7 +187,8 @@ cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID, ...@@ -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 // 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; int i;
cmsUInt32Number Samples[MAX_INPUT_DIMENSIONS]; cmsUInt32Number Samples[MAX_INPUT_DIMENSIONS];
...@@ -195,7 +203,7 @@ cmsInterpParams* _cmsComputeInterpParams(cmsContext ContextID, int nSamples, int ...@@ -195,7 +203,7 @@ cmsInterpParams* _cmsComputeInterpParams(cmsContext ContextID, int nSamples, int
// Free all associated memory // Free all associated memory
void _cmsFreeInterpParams(cmsInterpParams* p) void CMSEXPORT _cmsFreeInterpParams(cmsInterpParams* p)
{ {
if (p != NULL) _cmsFree(p ->ContextID, p); if (p != NULL) _cmsFree(p ->ContextID, p);
} }
...@@ -244,7 +252,7 @@ void LinLerp1D(register const cmsUInt16Number Value[], ...@@ -244,7 +252,7 @@ void LinLerp1D(register const cmsUInt16Number Value[],
// To prevent out of bounds indexing // To prevent out of bounds indexing
cmsINLINE cmsFloat32Number fclamp(cmsFloat32Number v) 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 // Floating-point version of 1D interpolation
...@@ -381,10 +389,10 @@ void BilinearInterpFloat(const cmsFloat32Number Input[], ...@@ -381,10 +389,10 @@ void BilinearInterpFloat(const cmsFloat32Number Input[],
y0 = (int) _cmsQuickFloor(py); fy = py - (cmsFloat32Number) y0; y0 = (int) _cmsQuickFloor(py); fy = py - (cmsFloat32Number) y0;
X0 = p -> opta[1] * x0; 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; 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++) { for (OutChan = 0; OutChan < TotalOut; OutChan++) {
...@@ -493,18 +501,18 @@ void TrilinearInterpFloat(const cmsFloat32Number Input[], ...@@ -493,18 +501,18 @@ void TrilinearInterpFloat(const cmsFloat32Number Input[],
py = fclamp(Input[1]) * p->Domain[1]; py = fclamp(Input[1]) * p->Domain[1];
pz = fclamp(Input[2]) * p->Domain[2]; pz = fclamp(Input[2]) * p->Domain[2];
x0 = (int) _cmsQuickFloor(px); fx = px - (cmsFloat32Number) x0; x0 = (int) floor(px); fx = px - (cmsFloat32Number) x0; // We need full floor funcionality here
y0 = (int) _cmsQuickFloor(py); fy = py - (cmsFloat32Number) y0; y0 = (int) floor(py); fy = py - (cmsFloat32Number) y0;
z0 = (int) _cmsQuickFloor(pz); fz = pz - (cmsFloat32Number) z0; z0 = (int) floor(pz); fz = pz - (cmsFloat32Number) z0;
X0 = p -> opta[2] * x0; 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; 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; 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++) { for (OutChan = 0; OutChan < TotalOut; OutChan++) {
...@@ -637,19 +645,19 @@ void TetrahedralInterpFloat(const cmsFloat32Number Input[], ...@@ -637,19 +645,19 @@ void TetrahedralInterpFloat(const cmsFloat32Number Input[],
py = fclamp(Input[1]) * p->Domain[1]; py = fclamp(Input[1]) * p->Domain[1];
pz = fclamp(Input[2]) * p->Domain[2]; pz = fclamp(Input[2]) * p->Domain[2];
x0 = (int) _cmsQuickFloor(px); rx = (px - (cmsFloat32Number) x0); x0 = (int) floor(px); rx = (px - (cmsFloat32Number) x0); // We need full floor functionality here
y0 = (int) _cmsQuickFloor(py); ry = (py - (cmsFloat32Number) y0); y0 = (int) floor(py); ry = (py - (cmsFloat32Number) y0);
z0 = (int) _cmsQuickFloor(pz); rz = (pz - (cmsFloat32Number) z0); z0 = (int) floor(pz); rz = (pz - (cmsFloat32Number) z0);
X0 = p -> opta[2] * x0; 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; 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; 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++) { for (OutChan=0; OutChan < TotalOut; OutChan++) {
...@@ -952,13 +960,13 @@ void Eval4Inputs(register const cmsUInt16Number Input[], ...@@ -952,13 +960,13 @@ void Eval4Inputs(register const cmsUInt16Number Input[],
c3 = DENS(X0, Y0, Z1) - c0; c3 = DENS(X0, Y0, Z1) - c0;
} }
else { else {
c1 = c2 = c3 = 0; c1 = c2 = c3 = 0;
} }
Rest = c1 * rx + c2 * ry + c3 * rz; 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[], ...@@ -1057,7 +1065,7 @@ void Eval4InputsFloat(const cmsFloat32Number Input[],
rest = pk - (cmsFloat32Number) k0; rest = pk - (cmsFloat32Number) k0;
K0 = p -> opta[3] * 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; p1 = *p;
memmove(&p1.Domain[0], &p ->Domain[1], 3*sizeof(cmsUInt32Number)); memmove(&p1.Domain[0], &p ->Domain[1], 3*sizeof(cmsUInt32Number));
...@@ -1144,7 +1152,7 @@ void Eval5InputsFloat(const cmsFloat32Number Input[], ...@@ -1144,7 +1152,7 @@ void Eval5InputsFloat(const cmsFloat32Number Input[],
rest = pk - (cmsFloat32Number) k0; rest = pk - (cmsFloat32Number) k0;
K0 = p -> opta[4] * 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; p1 = *p;
memmove(&p1.Domain[0], &p ->Domain[1], 4*sizeof(cmsUInt32Number)); memmove(&p1.Domain[0], &p ->Domain[1], 4*sizeof(cmsUInt32Number));
...@@ -1231,7 +1239,7 @@ void Eval6InputsFloat(const cmsFloat32Number Input[], ...@@ -1231,7 +1239,7 @@ void Eval6InputsFloat(const cmsFloat32Number Input[],
rest = pk - (cmsFloat32Number) k0; rest = pk - (cmsFloat32Number) k0;
K0 = p -> opta[5] * 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; p1 = *p;
memmove(&p1.Domain[0], &p ->Domain[1], 5*sizeof(cmsUInt32Number)); memmove(&p1.Domain[0], &p ->Domain[1], 5*sizeof(cmsUInt32Number));
...@@ -1316,7 +1324,7 @@ void Eval7InputsFloat(const cmsFloat32Number Input[], ...@@ -1316,7 +1324,7 @@ void Eval7InputsFloat(const cmsFloat32Number Input[],
rest = pk - (cmsFloat32Number) k0; rest = pk - (cmsFloat32Number) k0;
K0 = p -> opta[6] * 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; p1 = *p;
memmove(&p1.Domain[0], &p ->Domain[1], 6*sizeof(cmsUInt32Number)); memmove(&p1.Domain[0], &p ->Domain[1], 6*sizeof(cmsUInt32Number));
...@@ -1401,7 +1409,7 @@ void Eval8InputsFloat(const cmsFloat32Number Input[], ...@@ -1401,7 +1409,7 @@ void Eval8InputsFloat(const cmsFloat32Number Input[],
rest = pk - (cmsFloat32Number) k0; rest = pk - (cmsFloat32Number) k0;
K0 = p -> opta[7] * 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; p1 = *p;
memmove(&p1.Domain[0], &p ->Domain[1], 7*sizeof(cmsUInt32Number)); memmove(&p1.Domain[0], &p ->Domain[1], 7*sizeof(cmsUInt32Number));
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
...@@ -366,21 +366,27 @@ cmsBool FileSeek(cmsIOHANDLER* iohandler, cmsUInt32Number offset) ...@@ -366,21 +366,27 @@ cmsBool FileSeek(cmsIOHANDLER* iohandler, cmsUInt32Number offset)
return TRUE; return TRUE;
} }
// Returns file pointer position // Returns file pointer position or 0 on error, which is also a valid position.
static static
cmsUInt32Number FileTell(cmsIOHANDLER* iohandler) 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 // Writes data to stream, also keeps used space for further reference. Returns TRUE on success, FALSE on error
static static
cmsBool FileWrite(cmsIOHANDLER* iohandler, cmsUInt32Number size, const void* Buffer) 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; iohandler->UsedSpace += size;
return (fwrite(Buffer, size, 1, (FILE*) iohandler->stream) == 1); return (fwrite(Buffer, size, 1, (FILE*)iohandler->stream) == 1);
} }
// Closes the file // Closes the file
...@@ -548,7 +554,7 @@ cmsInt32Number CMSEXPORT cmsGetTagCount(cmsHPROFILE hProfile) ...@@ -548,7 +554,7 @@ cmsInt32Number CMSEXPORT cmsGetTagCount(cmsHPROFILE hProfile)
_cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile;
if (Icc == NULL) return -1; if (Icc == NULL) return -1;
return Icc->TagCount; return (cmsInt32Number) Icc->TagCount;
} }
// Return the tag signature of a given tag number // Return the tag signature of a given tag number
...@@ -566,9 +572,9 @@ cmsTagSignature CMSEXPORT cmsGetTagSignature(cmsHPROFILE hProfile, cmsUInt32Numb ...@@ -566,9 +572,9 @@ cmsTagSignature CMSEXPORT cmsGetTagSignature(cmsHPROFILE hProfile, cmsUInt32Numb
static static
int SearchOneTag(_cmsICCPROFILE* Profile, cmsTagSignature sig) 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]) if (sig == Profile -> TagNames[i])
return i; return i;
...@@ -662,7 +668,7 @@ cmsBool _cmsNewTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, int* NewPos) ...@@ -662,7 +668,7 @@ cmsBool _cmsNewTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, int* NewPos)
return FALSE; return FALSE;
} }
*NewPos = Icc ->TagCount; *NewPos = (int) Icc ->TagCount;
Icc -> TagCount++; Icc -> TagCount++;
} }
...@@ -693,10 +699,10 @@ cmsUInt32Number _validatedVersion(cmsUInt32Number DWord) ...@@ -693,10 +699,10 @@ cmsUInt32Number _validatedVersion(cmsUInt32Number DWord)
cmsUInt8Number temp2; cmsUInt8Number temp2;
if (*pByte > 0x09) *pByte = (cmsUInt8Number) 0x09; if (*pByte > 0x09) *pByte = (cmsUInt8Number) 0x09;
temp1 = *(pByte+1) & 0xf0; temp1 = (cmsUInt8Number) (*(pByte+1) & 0xf0);
temp2 = *(pByte+1) & 0x0f; temp2 = (cmsUInt8Number) (*(pByte+1) & 0x0f);
if (temp1 > 0x90) temp1 = 0x90; if (temp1 > 0x90U) temp1 = 0x90U;
if (temp2 > 0x09) temp2 = 0x09; if (temp2 > 0x09U) temp2 = 0x09U;
*(pByte+1) = (cmsUInt8Number)(temp1 | temp2); *(pByte+1) = (cmsUInt8Number)(temp1 | temp2);
*(pByte+2) = (cmsUInt8Number)0; *(pByte+2) = (cmsUInt8Number)0;
*(pByte+3) = (cmsUInt8Number)0; *(pByte+3) = (cmsUInt8Number)0;
...@@ -804,7 +810,7 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace) ...@@ -804,7 +810,7 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace)
cmsICCHeader Header; cmsICCHeader Header;
cmsUInt32Number i; cmsUInt32Number i;
cmsTagEntry Tag; cmsTagEntry Tag;
cmsInt32Number Count = 0; cmsUInt32Number Count;
Header.size = _cmsAdjustEndianess32(UsedSpace); Header.size = _cmsAdjustEndianess32(UsedSpace);
Header.cmmId = _cmsAdjustEndianess32(lcmsSignature); Header.cmmId = _cmsAdjustEndianess32(lcmsSignature);
...@@ -835,9 +841,9 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace) ...@@ -835,9 +841,9 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace)
Header.renderingIntent = _cmsAdjustEndianess32(Icc -> RenderingIntent); Header.renderingIntent = _cmsAdjustEndianess32(Icc -> RenderingIntent);
// Illuminant is always D50 // Illuminant is always D50
Header.illuminant.X = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(cmsD50_XYZ()->X)); Header.illuminant.X = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(cmsD50_XYZ()->X));
Header.illuminant.Y = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(cmsD50_XYZ()->Y)); Header.illuminant.Y = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(cmsD50_XYZ()->Y));
Header.illuminant.Z = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(cmsD50_XYZ()->Z)); Header.illuminant.Z = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(cmsD50_XYZ()->Z));
// Created by LittleCMS (that's me!) // Created by LittleCMS (that's me!)
Header.creator = _cmsAdjustEndianess32(lcmsSignature); Header.creator = _cmsAdjustEndianess32(lcmsSignature);
...@@ -853,6 +859,7 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace) ...@@ -853,6 +859,7 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace)
// Saves Tag directory // Saves Tag directory
// Get true count // Get true count
Count = 0;
for (i=0; i < Icc -> TagCount; i++) { for (i=0; i < Icc -> TagCount; i++) {
if (Icc ->TagNames[i] != (cmsTagSignature) 0) if (Icc ->TagNames[i] != (cmsTagSignature) 0)
Count++; Count++;
...@@ -865,9 +872,9 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace) ...@@ -865,9 +872,9 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace)
if (Icc ->TagNames[i] == (cmsTagSignature) 0) continue; // It is just a placeholder if (Icc ->TagNames[i] == (cmsTagSignature) 0) continue; // It is just a placeholder
Tag.sig = (cmsTagSignature) _cmsAdjustEndianess32((cmsInt32Number) Icc -> TagNames[i]); Tag.sig = (cmsTagSignature) _cmsAdjustEndianess32((cmsUInt32Number) Icc -> TagNames[i]);
Tag.offset = _cmsAdjustEndianess32((cmsInt32Number) Icc -> TagOffsets[i]); Tag.offset = _cmsAdjustEndianess32((cmsUInt32Number) Icc -> TagOffsets[i]);
Tag.size = _cmsAdjustEndianess32((cmsInt32Number) Icc -> TagSizes[i]); Tag.size = _cmsAdjustEndianess32((cmsUInt32Number) Icc -> TagSizes[i]);
if (!Icc ->IOhandler -> Write(Icc-> IOhandler, sizeof(cmsTagEntry), &Tag)) return FALSE; if (!Icc ->IOhandler -> Write(Icc-> IOhandler, sizeof(cmsTagEntry), &Tag)) return FALSE;
} }
...@@ -1176,7 +1183,7 @@ cmsHPROFILE CMSEXPORT cmsOpenProfileFromMemTHR(cmsContext ContextID, const void* ...@@ -1176,7 +1183,7 @@ cmsHPROFILE CMSEXPORT cmsOpenProfileFromMemTHR(cmsContext ContextID, const void*
NewIcc = (_cmsICCPROFILE*) hEmpty; NewIcc = (_cmsICCPROFILE*) hEmpty;
// Ok, in this case const void* is casted to void* just because open IO handler // 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"); NewIcc ->IOhandler = cmsOpenIOhandlerFromMem(ContextID, (void*) MemPtr, dwSize, "r");
if (NewIcc ->IOhandler == NULL) goto Error; if (NewIcc ->IOhandler == NULL) goto Error;
...@@ -1466,7 +1473,7 @@ cmsBool CMSEXPORT cmsCloseProfile(cmsHPROFILE hProfile) ...@@ -1466,7 +1473,7 @@ cmsBool CMSEXPORT cmsCloseProfile(cmsHPROFILE hProfile)
// Was open in write mode? // Was open in write mode?
if (Icc ->IsWrite) { if (Icc ->IsWrite) {
Icc ->IsWrite = FALSE; // Assure no further writting Icc ->IsWrite = FALSE; // Assure no further writing
rc &= cmsSaveProfileToFile(hProfile, Icc ->IOhandler->PhysicalFile); rc &= cmsSaveProfileToFile(hProfile, Icc ->IOhandler->PhysicalFile);
} }
...@@ -1543,11 +1550,15 @@ void* CMSEXPORT cmsReadTag(cmsHPROFILE hProfile, cmsTagSignature sig) ...@@ -1543,11 +1550,15 @@ void* CMSEXPORT cmsReadTag(cmsHPROFILE hProfile, cmsTagSignature sig)
// If the element is already in memory, return the pointer // If the element is already in memory, return the pointer
if (Icc -> TagPtrs[n]) { if (Icc -> TagPtrs[n]) {
if (Icc -> TagTypeHandlers[n] == NULL) goto Error; if (Icc->TagTypeHandlers[n] == NULL) goto Error;
BaseType = Icc -> TagTypeHandlers[n]->Signature;
// Sanity check
BaseType = Icc->TagTypeHandlers[n]->Signature;
if (BaseType == 0) goto Error; if (BaseType == 0) goto Error;
TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, sig);
TagDescriptor = _cmsGetTagDescriptor(Icc->ContextID, sig);
if (TagDescriptor == NULL) goto Error; if (TagDescriptor == NULL) goto Error;
if (!IsTypeSupported(TagDescriptor, BaseType)) goto Error; if (!IsTypeSupported(TagDescriptor, BaseType)) goto Error;
if (Icc ->TagSaveAsRaw[n]) goto Error; // We don't support read raw tags as cooked 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) ...@@ -1560,6 +1571,8 @@ void* CMSEXPORT cmsReadTag(cmsHPROFILE hProfile, cmsTagSignature sig)
Offset = Icc -> TagOffsets[n]; Offset = Icc -> TagOffsets[n];
TagSize = Icc -> TagSizes[n]; TagSize = Icc -> TagSizes[n];
if (TagSize < 8) goto Error;
// Seek to its location // Seek to its location
if (!io -> Seek(io, Offset)) if (!io -> Seek(io, Offset))
goto Error; goto Error;
...@@ -1583,7 +1596,7 @@ void* CMSEXPORT cmsReadTag(cmsHPROFILE hProfile, cmsTagSignature sig) ...@@ -1583,7 +1596,7 @@ void* CMSEXPORT cmsReadTag(cmsHPROFILE hProfile, cmsTagSignature sig)
if (!IsTypeSupported(TagDescriptor, BaseType)) goto Error; 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 // Get type handler
TypeHandler = _cmsGetTagTypeHandler(Icc ->ContextID, BaseType); TypeHandler = _cmsGetTagTypeHandler(Icc ->ContextID, BaseType);
...@@ -1772,7 +1785,7 @@ Error: ...@@ -1772,7 +1785,7 @@ Error:
// raw data written does not exactly correspond with the raw data proposed to cmsWriteRaw data, but this approach allows // 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. // 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; _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile;
void *Object; void *Object;
...@@ -1890,7 +1903,7 @@ Error: ...@@ -1890,7 +1903,7 @@ Error:
} }
// Similar to the anterior. This function allows to write directly to the ICC profile any data, without // 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 // 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. // the profile to memry or disk and then reopen it.
cmsBool CMSEXPORT cmsWriteRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, const void* data, cmsUInt32Number Size) cmsBool CMSEXPORT cmsWriteRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, const void* data, cmsUInt32Number Size)
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
...@@ -335,8 +335,8 @@ Error: ...@@ -335,8 +335,8 @@ Error:
// Read and create a BRAND NEW MPE LUT from a given profile. All stuff dependent of version, etc // Read and create a BRAND NEW MPE LUT from a given profile. All stuff dependent of version, etc
// is adjusted here in order to create a LUT that takes care of all those details. // is adjusted here in order to create a LUT that takes care of all those details.
// We add intent = -1 as a way to read matrix shaper always, no matter of other LUT // We add intent = 0xffffffff as a way to read matrix shaper always, no matter of other LUT
cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent) cmsPipeline* CMSEXPORT _cmsReadInputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent)
{ {
cmsTagTypeSignature OriginalType; cmsTagTypeSignature OriginalType;
cmsTagSignature tag16; cmsTagSignature tag16;
...@@ -366,8 +366,8 @@ cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent) ...@@ -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 // 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. // matter other LUT are present and have precedence. Intent = 0xffffffff can be used for that.
if (Intent >= INTENT_PERCEPTUAL && Intent <= INTENT_ABSOLUTE_COLORIMETRIC) { if (Intent <= INTENT_ABSOLUTE_COLORIMETRIC) {
tag16 = Device2PCS16[Intent]; tag16 = Device2PCS16[Intent];
tagFloat = Device2PCSFloat[Intent]; tagFloat = Device2PCSFloat[Intent];
...@@ -611,7 +611,7 @@ Error: ...@@ -611,7 +611,7 @@ Error:
} }
// Create an output MPE LUT from agiven profile. Version mismatches are handled here // 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; cmsTagTypeSignature OriginalType;
cmsTagSignature tag16; cmsTagSignature tag16;
...@@ -619,7 +619,7 @@ cmsPipeline* _cmsReadOutputLUT(cmsHPROFILE hProfile, int Intent) ...@@ -619,7 +619,7 @@ cmsPipeline* _cmsReadOutputLUT(cmsHPROFILE hProfile, int Intent)
cmsContext ContextID = cmsGetProfileContextID(hProfile); cmsContext ContextID = cmsGetProfileContextID(hProfile);
if (Intent >= INTENT_PERCEPTUAL && Intent <= INTENT_ABSOLUTE_COLORIMETRIC) { if (Intent <= INTENT_ABSOLUTE_COLORIMETRIC) {
tag16 = PCS2Device16[Intent]; tag16 = PCS2Device16[Intent];
tagFloat = PCS2DeviceFloat[Intent]; tagFloat = PCS2DeviceFloat[Intent];
...@@ -695,8 +695,8 @@ Error: ...@@ -695,8 +695,8 @@ Error:
static static
cmsPipeline* _cmsReadFloatDevicelinkTag(cmsHPROFILE hProfile, cmsTagSignature tagFloat) cmsPipeline* _cmsReadFloatDevicelinkTag(cmsHPROFILE hProfile, cmsTagSignature tagFloat)
{ {
cmsContext ContextID = cmsGetProfileContextID(hProfile); cmsContext ContextID = cmsGetProfileContextID(hProfile);
cmsPipeline* Lut = cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat)); cmsPipeline* Lut = cmsPipelineDup((cmsPipeline*)cmsReadTag(hProfile, tagFloat));
cmsColorSpaceSignature PCS = cmsGetPCS(hProfile); cmsColorSpaceSignature PCS = cmsGetPCS(hProfile);
cmsColorSpaceSignature spc = cmsGetColorSpace(hProfile); cmsColorSpaceSignature spc = cmsGetColorSpace(hProfile);
...@@ -714,17 +714,17 @@ cmsPipeline* _cmsReadFloatDevicelinkTag(cmsHPROFILE hProfile, cmsTagSignature ta ...@@ -714,17 +714,17 @@ cmsPipeline* _cmsReadFloatDevicelinkTag(cmsHPROFILE hProfile, cmsTagSignature ta
goto Error; 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; goto Error;
} }
else
if (PCS == cmsSigXYZData)
{
if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromXyzFloat(ContextID)))
goto Error;
}
return Lut; return Lut;
Error: Error:
...@@ -734,7 +734,7 @@ Error: ...@@ -734,7 +734,7 @@ Error:
// This one includes abstract profiles as well. Matrix-shaper cannot be obtained on that device class. The // This one includes abstract profiles as well. Matrix-shaper cannot be obtained on that device class. The
// tag name here may default to AToB0 // tag name here may default to AToB0
cmsPipeline* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent) cmsPipeline* CMSEXPORT _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent)
{ {
cmsPipeline* Lut; cmsPipeline* Lut;
cmsTagTypeSignature OriginalType; cmsTagTypeSignature OriginalType;
...@@ -743,7 +743,7 @@ cmsPipeline* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent) ...@@ -743,7 +743,7 @@ cmsPipeline* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent)
cmsContext ContextID = cmsGetProfileContextID(hProfile); cmsContext ContextID = cmsGetProfileContextID(hProfile);
if (Intent < INTENT_PERCEPTUAL || Intent > INTENT_ABSOLUTE_COLORIMETRIC) if (Intent > INTENT_ABSOLUTE_COLORIMETRIC)
return NULL; return NULL;
tag16 = Device2PCS16[Intent]; tag16 = Device2PCS16[Intent];
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
...@@ -153,8 +153,8 @@ cmsBool CMSEXPORT cmsPipelineCheckAndRetreiveStages(const cmsPipeline* Lut, cms ...@@ -153,8 +153,8 @@ cmsBool CMSEXPORT cmsPipelineCheckAndRetreiveStages(const cmsPipeline* Lut, cms
mpe = Lut ->Elements; mpe = Lut ->Elements;
for (i=0; i < n; i++) { for (i=0; i < n; i++) {
// Get asked type // Get asked type. cmsStageSignature is promoted to int by compiler
Type = (cmsStageSignature)va_arg(args, cmsStageSignature); Type = (cmsStageSignature)va_arg(args, int);
if (mpe ->Type != Type) { if (mpe ->Type != Type) {
va_end(args); // Mismatch. We are done. va_end(args); // Mismatch. We are done.
...@@ -321,7 +321,7 @@ cmsStage* CMSEXPORT cmsStageAllocToneCurves(cmsContext ContextID, cmsUInt32Numbe ...@@ -321,7 +321,7 @@ cmsStage* CMSEXPORT cmsStageAllocToneCurves(cmsContext ContextID, cmsUInt32Numbe
// Create a bunch of identity curves // 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); cmsStage* mpe = cmsStageAllocToneCurves(ContextID, nChannels, NULL);
...@@ -443,13 +443,13 @@ cmsStage* CMSEXPORT cmsStageAllocMatrix(cmsContext ContextID, cmsUInt32Number R ...@@ -443,13 +443,13 @@ cmsStage* CMSEXPORT cmsStageAllocMatrix(cmsContext ContextID, cmsUInt32Number R
if (Offset != NULL) { if (Offset != NULL) {
NewElem ->Offset = (cmsFloat64Number*) _cmsCalloc(ContextID, Cols, sizeof(cmsFloat64Number)); NewElem ->Offset = (cmsFloat64Number*) _cmsCalloc(ContextID, Rows, sizeof(cmsFloat64Number));
if (NewElem->Offset == NULL) { if (NewElem->Offset == NULL) {
MatrixElemTypeFree(NewMPE); MatrixElemTypeFree(NewMPE);
return NULL; return NULL;
} }
for (i=0; i < Cols; i++) { for (i=0; i < Rows; i++) {
NewElem ->Offset[i] = Offset[i]; NewElem ->Offset[i] = Offset[i];
} }
...@@ -741,7 +741,7 @@ int IdentitySampler(register const cmsUInt16Number In[], register cmsUInt16Numbe ...@@ -741,7 +741,7 @@ int IdentitySampler(register const cmsUInt16Number In[], register cmsUInt16Numbe
} }
// Creates an MPE that just copies input to output // 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]; cmsUInt32Number Dimensions[MAX_INPUT_DIMENSIONS];
cmsStage* mpe ; cmsStage* mpe ;
...@@ -765,7 +765,7 @@ cmsStage* _cmsStageAllocIdentityCLut(cmsContext ContextID, int nChan) ...@@ -765,7 +765,7 @@ cmsStage* _cmsStageAllocIdentityCLut(cmsContext ContextID, int nChan)
// Quantize a value 0 <= i < MaxSamples to 0..0xffff // Quantize a value 0 <= i < MaxSamples to 0..0xffff
cmsUInt16Number _cmsQuantizeVal(cmsFloat64Number i, int MaxSamples) cmsUInt16Number CMSEXPORT _cmsQuantizeVal(cmsFloat64Number i, cmsUInt32Number MaxSamples)
{ {
cmsFloat64Number x; cmsFloat64Number x;
...@@ -778,8 +778,9 @@ cmsUInt16Number _cmsQuantizeVal(cmsFloat64Number i, int MaxSamples) ...@@ -778,8 +778,9 @@ cmsUInt16Number _cmsQuantizeVal(cmsFloat64Number i, int MaxSamples)
// function on knots. returns TRUE if all ok, FALSE otherwise. // function on knots. returns TRUE if all ok, FALSE otherwise.
cmsBool CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe, cmsSAMPLER16 Sampler, void * Cargo, cmsUInt32Number dwFlags) cmsBool CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe, cmsSAMPLER16 Sampler, void * Cargo, cmsUInt32Number dwFlags)
{ {
int i, t, nTotalPoints, index, rest; int i, t, index, rest;
int nInputs, nOutputs; cmsUInt32Number nTotalPoints;
cmsUInt32Number nInputs, nOutputs;
cmsUInt32Number* nSamples; cmsUInt32Number* nSamples;
cmsUInt16Number In[MAX_INPUT_DIMENSIONS+1], Out[MAX_STAGE_CHANNELS]; cmsUInt16Number In[MAX_INPUT_DIMENSIONS+1], Out[MAX_STAGE_CHANNELS];
_cmsStageCLutData* clut; _cmsStageCLutData* clut;
...@@ -799,14 +800,17 @@ cmsBool CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe, cmsSAMPLER16 Sampler, v ...@@ -799,14 +800,17 @@ cmsBool CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe, cmsSAMPLER16 Sampler, v
if (nInputs > MAX_INPUT_DIMENSIONS) return FALSE; if (nInputs > MAX_INPUT_DIMENSIONS) return FALSE;
if (nOutputs >= MAX_STAGE_CHANNELS) return FALSE; if (nOutputs >= MAX_STAGE_CHANNELS) return FALSE;
memset(In, 0, sizeof(In));
memset(Out, 0, sizeof(Out));
nTotalPoints = CubeSize(nSamples, nInputs); nTotalPoints = CubeSize(nSamples, nInputs);
if (nTotalPoints == 0) return FALSE; if (nTotalPoints == 0) return FALSE;
index = 0; index = 0;
for (i = 0; i < nTotalPoints; i++) { for (i = 0; i < (int) nTotalPoints; i++) {
rest = i; rest = i;
for (t = nInputs-1; t >=0; --t) { for (t = (int)nInputs - 1; t >= 0; --t) {
cmsUInt32Number Colorant = rest % nSamples[t]; cmsUInt32Number Colorant = rest % nSamples[t];
...@@ -816,7 +820,7 @@ cmsBool CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe, cmsSAMPLER16 Sampler, v ...@@ -816,7 +820,7 @@ cmsBool CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe, cmsSAMPLER16 Sampler, v
} }
if (clut ->Tab.T != NULL) { 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]; Out[t] = clut->Tab.T[index + t];
} }
...@@ -826,7 +830,7 @@ cmsBool CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe, cmsSAMPLER16 Sampler, v ...@@ -826,7 +830,7 @@ cmsBool CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe, cmsSAMPLER16 Sampler, v
if (!(dwFlags & SAMPLER_INSPECT)) { if (!(dwFlags & SAMPLER_INSPECT)) {
if (clut ->Tab.T != NULL) { 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]; clut->Tab.T[index + t] = Out[t];
} }
} }
...@@ -837,11 +841,12 @@ cmsBool CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe, cmsSAMPLER16 Sampler, v ...@@ -837,11 +841,12 @@ cmsBool CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe, cmsSAMPLER16 Sampler, v
return TRUE; 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) cmsBool CMSEXPORT cmsStageSampleCLutFloat(cmsStage* mpe, cmsSAMPLERFLOAT Sampler, void * Cargo, cmsUInt32Number dwFlags)
{ {
int i, t, nTotalPoints, index, rest; int i, t, index, rest;
int nInputs, nOutputs; cmsUInt32Number nTotalPoints;
cmsUInt32Number nInputs, nOutputs;
cmsUInt32Number* nSamples; cmsUInt32Number* nSamples;
cmsFloat32Number In[MAX_INPUT_DIMENSIONS+1], Out[MAX_STAGE_CHANNELS]; cmsFloat32Number In[MAX_INPUT_DIMENSIONS+1], Out[MAX_STAGE_CHANNELS];
_cmsStageCLutData* clut = (_cmsStageCLutData*) mpe->Data; _cmsStageCLutData* clut = (_cmsStageCLutData*) mpe->Data;
...@@ -859,10 +864,10 @@ cmsBool CMSEXPORT cmsStageSampleCLutFloat(cmsStage* mpe, cmsSAMPLERFLOAT Sampler ...@@ -859,10 +864,10 @@ cmsBool CMSEXPORT cmsStageSampleCLutFloat(cmsStage* mpe, cmsSAMPLERFLOAT Sampler
if (nTotalPoints == 0) return FALSE; if (nTotalPoints == 0) return FALSE;
index = 0; index = 0;
for (i = 0; i < nTotalPoints; i++) { for (i = 0; i < (int)nTotalPoints; i++) {
rest = i; rest = i;
for (t = nInputs-1; t >=0; --t) { for (t = (int) nInputs-1; t >=0; --t) {
cmsUInt32Number Colorant = rest % nSamples[t]; cmsUInt32Number Colorant = rest % nSamples[t];
...@@ -872,7 +877,7 @@ cmsBool CMSEXPORT cmsStageSampleCLutFloat(cmsStage* mpe, cmsSAMPLERFLOAT Sampler ...@@ -872,7 +877,7 @@ cmsBool CMSEXPORT cmsStageSampleCLutFloat(cmsStage* mpe, cmsSAMPLERFLOAT Sampler
} }
if (clut ->Tab.TFloat != NULL) { 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]; Out[t] = clut->Tab.TFloat[index + t];
} }
...@@ -882,7 +887,7 @@ cmsBool CMSEXPORT cmsStageSampleCLutFloat(cmsStage* mpe, cmsSAMPLERFLOAT Sampler ...@@ -882,7 +887,7 @@ cmsBool CMSEXPORT cmsStageSampleCLutFloat(cmsStage* mpe, cmsSAMPLERFLOAT Sampler
if (!(dwFlags & SAMPLER_INSPECT)) { if (!(dwFlags & SAMPLER_INSPECT)) {
if (clut ->Tab.TFloat != NULL) { 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]; clut->Tab.TFloat[index + t] = Out[t];
} }
} }
...@@ -900,7 +905,8 @@ cmsBool CMSEXPORT cmsStageSampleCLutFloat(cmsStage* mpe, cmsSAMPLERFLOAT Sampler ...@@ -900,7 +905,8 @@ cmsBool CMSEXPORT cmsStageSampleCLutFloat(cmsStage* mpe, cmsSAMPLERFLOAT Sampler
cmsBool CMSEXPORT cmsSliceSpace16(cmsUInt32Number nInputs, const cmsUInt32Number clutPoints[], cmsBool CMSEXPORT cmsSliceSpace16(cmsUInt32Number nInputs, const cmsUInt32Number clutPoints[],
cmsSAMPLER16 Sampler, void * Cargo) cmsSAMPLER16 Sampler, void * Cargo)
{ {
int i, t, nTotalPoints, rest; int i, t, rest;
cmsUInt32Number nTotalPoints;
cmsUInt16Number In[cmsMAXCHANNELS]; cmsUInt16Number In[cmsMAXCHANNELS];
if (nInputs >= cmsMAXCHANNELS) return FALSE; if (nInputs >= cmsMAXCHANNELS) return FALSE;
...@@ -908,10 +914,10 @@ cmsBool CMSEXPORT cmsSliceSpace16(cmsUInt32Number nInputs, const cmsUInt32Number ...@@ -908,10 +914,10 @@ cmsBool CMSEXPORT cmsSliceSpace16(cmsUInt32Number nInputs, const cmsUInt32Number
nTotalPoints = CubeSize(clutPoints, nInputs); nTotalPoints = CubeSize(clutPoints, nInputs);
if (nTotalPoints == 0) return FALSE; if (nTotalPoints == 0) return FALSE;
for (i = 0; i < nTotalPoints; i++) { for (i = 0; i < (int) nTotalPoints; i++) {
rest = i; rest = i;
for (t = nInputs-1; t >=0; --t) { for (t = (int) nInputs-1; t >=0; --t) {
cmsUInt32Number Colorant = rest % clutPoints[t]; cmsUInt32Number Colorant = rest % clutPoints[t];
...@@ -930,7 +936,8 @@ cmsBool CMSEXPORT cmsSliceSpace16(cmsUInt32Number nInputs, const cmsUInt32Number ...@@ -930,7 +936,8 @@ cmsBool CMSEXPORT cmsSliceSpace16(cmsUInt32Number nInputs, const cmsUInt32Number
cmsInt32Number CMSEXPORT cmsSliceSpaceFloat(cmsUInt32Number nInputs, const cmsUInt32Number clutPoints[], cmsInt32Number CMSEXPORT cmsSliceSpaceFloat(cmsUInt32Number nInputs, const cmsUInt32Number clutPoints[],
cmsSAMPLERFLOAT Sampler, void * Cargo) cmsSAMPLERFLOAT Sampler, void * Cargo)
{ {
int i, t, nTotalPoints, rest; int i, t, rest;
cmsUInt32Number nTotalPoints;
cmsFloat32Number In[cmsMAXCHANNELS]; cmsFloat32Number In[cmsMAXCHANNELS];
if (nInputs >= cmsMAXCHANNELS) return FALSE; if (nInputs >= cmsMAXCHANNELS) return FALSE;
...@@ -938,10 +945,10 @@ cmsInt32Number CMSEXPORT cmsSliceSpaceFloat(cmsUInt32Number nInputs, const cmsUI ...@@ -938,10 +945,10 @@ cmsInt32Number CMSEXPORT cmsSliceSpaceFloat(cmsUInt32Number nInputs, const cmsUI
nTotalPoints = CubeSize(clutPoints, nInputs); nTotalPoints = CubeSize(clutPoints, nInputs);
if (nTotalPoints == 0) return FALSE; if (nTotalPoints == 0) return FALSE;
for (i = 0; i < nTotalPoints; i++) { for (i = 0; i < (int) nTotalPoints; i++) {
rest = i; rest = i;
for (t = nInputs-1; t >=0; --t) { for (t = (int) nInputs-1; t >=0; --t) {
cmsUInt32Number Colorant = rest % clutPoints[t]; cmsUInt32Number Colorant = rest % clutPoints[t];
...@@ -991,7 +998,7 @@ void EvaluateLab2XYZ(const cmsFloat32Number In[], ...@@ -991,7 +998,7 @@ void EvaluateLab2XYZ(const cmsFloat32Number In[],
// No dup or free routines needed, as the structure has no pointers in it. // 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); return _cmsStageAllocPlaceholder(ContextID, cmsSigLab2XYZElemType, 3, 3, EvaluateLab2XYZ, NULL, NULL, NULL);
} }
...@@ -1021,7 +1028,7 @@ cmsStage* _cmsStageAllocLabV2ToV4curves(cmsContext ContextID) ...@@ -1021,7 +1028,7 @@ cmsStage* _cmsStageAllocLabV2ToV4curves(cmsContext ContextID)
return NULL; 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); // So we can use 258-entry tables to do the trick (i / 257) * (255 * 257) * (257 / 256);
for (i=0; i < 257; i++) { for (i=0; i < 257; i++) {
...@@ -1042,7 +1049,7 @@ cmsStage* _cmsStageAllocLabV2ToV4curves(cmsContext ContextID) ...@@ -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 // 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, static const cmsFloat64Number V2ToV4[] = { 65535.0/65280.0, 0, 0,
0, 65535.0/65280.0, 0, 0, 65535.0/65280.0, 0,
...@@ -1058,7 +1065,7 @@ cmsStage* _cmsStageAllocLabV2ToV4(cmsContext ContextID) ...@@ -1058,7 +1065,7 @@ cmsStage* _cmsStageAllocLabV2ToV4(cmsContext ContextID)
// Reverse direction // Reverse direction
cmsStage* _cmsStageAllocLabV4ToV2(cmsContext ContextID) cmsStage* CMSEXPORT _cmsStageAllocLabV4ToV2(cmsContext ContextID)
{ {
static const cmsFloat64Number V4ToV2[] = { 65280.0/65535.0, 0, 0, static const cmsFloat64Number V4ToV2[] = { 65280.0/65535.0, 0, 0,
0, 65280.0/65535.0, 0, 0, 65280.0/65535.0, 0,
...@@ -1166,7 +1173,7 @@ void Clipper(const cmsFloat32Number In[], cmsFloat32Number Out[], const cmsStage ...@@ -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, return _cmsStageAllocPlaceholder(ContextID, cmsSigClipNegativesElemType,
nChannels, nChannels, Clipper, NULL, NULL, NULL); nChannels, nChannels, Clipper, NULL, NULL, NULL);
...@@ -1201,7 +1208,7 @@ void EvaluateXYZ2Lab(const cmsFloat32Number In[], cmsFloat32Number Out[], const ...@@ -1201,7 +1208,7 @@ void EvaluateXYZ2Lab(const cmsFloat32Number In[], cmsFloat32Number Out[], const
cmsUNUSED_PARAMETER(mpe); cmsUNUSED_PARAMETER(mpe);
} }
cmsStage* _cmsStageAllocXYZ2Lab(cmsContext ContextID) cmsStage* CMSEXPORT _cmsStageAllocXYZ2Lab(cmsContext ContextID)
{ {
return _cmsStageAllocPlaceholder(ContextID, cmsSigXYZ2LabElemType, 3, 3, EvaluateXYZ2Lab, NULL, NULL, NULL); return _cmsStageAllocPlaceholder(ContextID, cmsSigXYZ2LabElemType, 3, 3, EvaluateXYZ2Lab, NULL, NULL, NULL);
...@@ -1300,23 +1307,42 @@ cmsStage* CMSEXPORT cmsStageDup(cmsStage* mpe) ...@@ -1300,23 +1307,42 @@ cmsStage* CMSEXPORT cmsStageDup(cmsStage* mpe)
// *********************************************************************************************************** // ***********************************************************************************************************
// This function sets up the channel count // This function sets up the channel count
static 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) { if (lut ->Elements != NULL) {
cmsStage *First, *Last; cmsStage* prev;
cmsStage* next;
cmsStage* First;
cmsStage* Last;
First = cmsPipelineGetPtrToFirstStage(lut); First = cmsPipelineGetPtrToFirstStage(lut);
Last = cmsPipelineGetPtrToLastStage(lut); Last = cmsPipelineGetPtrToLastStage(lut);
if (First != NULL)lut ->InputChannels = First ->InputChannels; if (First == NULL || Last == NULL) return FALSE;
if (Last != NULL) lut ->OutputChannels = Last ->OutputChannels;
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. // Default to evaluate the LUT on 16 bit-basis. Precision is retained.
static static
...@@ -1368,21 +1394,18 @@ void _LUTevalFloat(register const cmsFloat32Number In[], register cmsFloat32Numb ...@@ -1368,21 +1394,18 @@ void _LUTevalFloat(register const cmsFloat32Number In[], register cmsFloat32Numb
} }
// LUT Creation & Destruction // LUT Creation & Destruction
cmsPipeline* CMSEXPORT cmsPipelineAlloc(cmsContext ContextID, cmsUInt32Number InputChannels, cmsUInt32Number OutputChannels) cmsPipeline* CMSEXPORT cmsPipelineAlloc(cmsContext ContextID, cmsUInt32Number InputChannels, cmsUInt32Number OutputChannels)
{ {
cmsPipeline* NewLUT; cmsPipeline* NewLUT;
// A value of zero in channels is allowed as placeholder
if (InputChannels >= cmsMAXCHANNELS || if (InputChannels >= cmsMAXCHANNELS ||
OutputChannels >= cmsMAXCHANNELS) return NULL; OutputChannels >= cmsMAXCHANNELS) return NULL;
NewLUT = (cmsPipeline*) _cmsMallocZero(ContextID, sizeof(cmsPipeline)); NewLUT = (cmsPipeline*) _cmsMallocZero(ContextID, sizeof(cmsPipeline));
if (NewLUT == NULL) return NULL; if (NewLUT == NULL) return NULL;
NewLUT -> InputChannels = InputChannels; NewLUT -> InputChannels = InputChannels;
NewLUT -> OutputChannels = OutputChannels; NewLUT -> OutputChannels = OutputChannels;
...@@ -1393,7 +1416,11 @@ cmsPipeline* CMSEXPORT cmsPipelineAlloc(cmsContext ContextID, cmsUInt32Number In ...@@ -1393,7 +1416,11 @@ cmsPipeline* CMSEXPORT cmsPipelineAlloc(cmsContext ContextID, cmsUInt32Number In
NewLUT ->Data = NewLUT; NewLUT ->Data = NewLUT;
NewLUT ->ContextID = ContextID; NewLUT ->ContextID = ContextID;
BlessLUT(NewLUT); if (!BlessLUT(NewLUT))
{
_cmsFree(ContextID, NewLUT);
return NULL;
}
return NewLUT; return NewLUT;
} }
...@@ -1500,7 +1527,12 @@ cmsPipeline* CMSEXPORT cmsPipelineDup(const cmsPipeline* lut) ...@@ -1500,7 +1527,12 @@ cmsPipeline* CMSEXPORT cmsPipelineDup(const cmsPipeline* lut)
NewLUT ->SaveAs8Bits = lut ->SaveAs8Bits; NewLUT ->SaveAs8Bits = lut ->SaveAs8Bits;
BlessLUT(NewLUT); if (!BlessLUT(NewLUT))
{
_cmsFree(lut->ContextID, NewLUT);
return NULL;
}
return NewLUT; return NewLUT;
} }
...@@ -1537,8 +1569,7 @@ int CMSEXPORT cmsPipelineInsertStage(cmsPipeline* lut, cmsStageLoc loc, cmsStage ...@@ -1537,8 +1569,7 @@ int CMSEXPORT cmsPipelineInsertStage(cmsPipeline* lut, cmsStageLoc loc, cmsStage
return FALSE; return FALSE;
} }
BlessLUT(lut); return BlessLUT(lut);
return TRUE;
} }
// Unlink an element and return the pointer to it // Unlink an element and return the pointer to it
...@@ -1593,6 +1624,7 @@ void CMSEXPORT cmsPipelineUnlinkStage(cmsPipeline* lut, cmsStageLoc loc, cmsStag ...@@ -1593,6 +1624,7 @@ void CMSEXPORT cmsPipelineUnlinkStage(cmsPipeline* lut, cmsStageLoc loc, cmsStag
else else
cmsStageFree(Unlinked); cmsStageFree(Unlinked);
// May fail, but we ignore it
BlessLUT(lut); BlessLUT(lut);
} }
...@@ -1619,8 +1651,7 @@ cmsBool CMSEXPORT cmsPipelineCat(cmsPipeline* l1, const cmsPipeline* l2) ...@@ -1619,8 +1651,7 @@ cmsBool CMSEXPORT cmsPipelineCat(cmsPipeline* l1, const cmsPipeline* l2)
return FALSE; return FALSE;
} }
BlessLUT(l1); return BlessLUT(l1);
return TRUE;
} }
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
...@@ -156,7 +156,7 @@ int SearchMLUEntry(cmsMLU* mlu, cmsUInt16Number LanguageCode, cmsUInt16Number Co ...@@ -156,7 +156,7 @@ int SearchMLUEntry(cmsMLU* mlu, cmsUInt16Number LanguageCode, cmsUInt16Number Co
for (i=0; i < mlu ->UsedEntries; i++) { for (i=0; i < mlu ->UsedEntries; i++) {
if (mlu ->Entries[i].Country == CountryCode && if (mlu ->Entries[i].Country == CountryCode &&
mlu ->Entries[i].Language == LanguageCode) return i; mlu ->Entries[i].Language == LanguageCode) return (int) i;
} }
// Not found // Not found
...@@ -207,31 +207,24 @@ cmsBool AddMLUBlock(cmsMLU* mlu, cmsUInt32Number size, const wchar_t *Block, ...@@ -207,31 +207,24 @@ cmsBool AddMLUBlock(cmsMLU* mlu, cmsUInt32Number size, const wchar_t *Block,
return TRUE; 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 // compilers don't properly align beginning of strings
static static
cmsUInt16Number strTo16(const char str[3]) 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 static
void strFrom16(char str[3], cmsUInt16Number n) void strFrom16(char str[3], cmsUInt16Number n)
{ {
// Assiming this would be aligned str[0] = (char)(n >> 8);
union { str[1] = (char)n;
str[2] = (char)0;
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;
} }
...@@ -354,7 +347,7 @@ const wchar_t* _cmsMLUgetWide(const cmsMLU* mlu, ...@@ -354,7 +347,7 @@ const wchar_t* _cmsMLUgetWide(const cmsMLU* mlu,
cmsUInt16Number* UsedLanguageCode, cmsUInt16Number* UsedCountryCode) cmsUInt16Number* UsedLanguageCode, cmsUInt16Number* UsedCountryCode)
{ {
cmsUInt32Number i; cmsUInt32Number i;
cmsInt32Number Best = -1; int Best = -1;
_cmsMLUentry* v; _cmsMLUentry* v;
if (mlu == NULL) return NULL; if (mlu == NULL) return NULL;
...@@ -367,7 +360,7 @@ const wchar_t* _cmsMLUgetWide(const cmsMLU* mlu, ...@@ -367,7 +360,7 @@ const wchar_t* _cmsMLUgetWide(const cmsMLU* mlu,
if (v -> Language == LanguageCode) { if (v -> Language == LanguageCode) {
if (Best == -1) Best = i; if (Best == -1) Best = (int) i;
if (v -> Country == CountryCode) { if (v -> Country == CountryCode) {
...@@ -633,10 +626,10 @@ cmsBool CMSEXPORT cmsAppendNamedColor(cmsNAMEDCOLORLIST* NamedColorList, ...@@ -633,10 +626,10 @@ cmsBool CMSEXPORT cmsAppendNamedColor(cmsNAMEDCOLORLIST* NamedColorList,
} }
for (i=0; i < NamedColorList ->ColorantCount; i++) 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++) 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) { if (Name != NULL) {
...@@ -671,6 +664,7 @@ cmsBool CMSEXPORT cmsNamedColorInfo(const cmsNAMEDCOLORLIST* NamedColorList, cm ...@@ -671,6 +664,7 @@ cmsBool CMSEXPORT cmsNamedColorInfo(const cmsNAMEDCOLORLIST* NamedColorList, cm
if (nColor >= cmsNamedColorCount(NamedColorList)) return FALSE; 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 (Name) strcpy(Name, NamedColorList->List[nColor].Name);
if (Prefix) strcpy(Prefix, NamedColorList->Prefix); if (Prefix) strcpy(Prefix, NamedColorList->Prefix);
if (Suffix) strcpy(Suffix, NamedColorList->Suffix); if (Suffix) strcpy(Suffix, NamedColorList->Suffix);
...@@ -688,13 +682,14 @@ cmsBool CMSEXPORT cmsNamedColorInfo(const cmsNAMEDCOLORLIST* NamedColorList, cm ...@@ -688,13 +682,14 @@ cmsBool CMSEXPORT cmsNamedColorInfo(const cmsNAMEDCOLORLIST* NamedColorList, cm
// Search for a given color name (no prefix or suffix) // Search for a given color name (no prefix or suffix)
cmsInt32Number CMSEXPORT cmsNamedColorIndex(const cmsNAMEDCOLORLIST* NamedColorList, const char* Name) cmsInt32Number CMSEXPORT cmsNamedColorIndex(const cmsNAMEDCOLORLIST* NamedColorList, const char* Name)
{ {
int i, n; cmsUInt32Number i;
cmsUInt32Number n;
if (NamedColorList == NULL) return -1; if (NamedColorList == NULL) return -1;
n = cmsNamedColorCount(NamedColorList); n = cmsNamedColorCount(NamedColorList);
for (i=0; i < n; i++) { for (i=0; i < n; i++) {
if (cmsstrcasecmp(Name, NamedColorList->List[i].Name) == 0) if (cmsstrcasecmp(Name, NamedColorList->List[i].Name) == 0)
return i; return (cmsInt32Number) i;
} }
return -1; return -1;
...@@ -723,7 +718,8 @@ void EvalNamedColorPCS(const cmsFloat32Number In[], cmsFloat32Number Out[], cons ...@@ -723,7 +718,8 @@ void EvalNamedColorPCS(const cmsFloat32Number In[], cmsFloat32Number Out[], cons
cmsUInt16Number index = (cmsUInt16Number) _cmsQuickSaturateWord(In[0] * 65535.0); cmsUInt16Number index = (cmsUInt16Number) _cmsQuickSaturateWord(In[0] * 65535.0);
if (index >= NamedColorList-> nColors) { 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 { else {
...@@ -742,7 +738,10 @@ void EvalNamedColor(const cmsFloat32Number In[], cmsFloat32Number Out[], const c ...@@ -742,7 +738,10 @@ void EvalNamedColor(const cmsFloat32Number In[], cmsFloat32Number Out[], const c
cmsUInt32Number j; cmsUInt32Number j;
if (index >= NamedColorList-> nColors) { 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 { else {
for (j=0; j < NamedColorList ->ColorantCount; j++) for (j=0; j < NamedColorList ->ColorantCount; j++)
...@@ -752,7 +751,7 @@ void EvalNamedColor(const cmsFloat32Number In[], cmsFloat32Number Out[], const c ...@@ -752,7 +751,7 @@ void EvalNamedColor(const cmsFloat32Number In[], cmsFloat32Number Out[], const c
// Named color lookup element // Named color lookup element
cmsStage* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS) cmsStage* CMSEXPORT _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS)
{ {
return _cmsStageAllocPlaceholder(NamedColorList ->ContextID, return _cmsStageAllocPlaceholder(NamedColorList ->ContextID,
cmsSigNamedColorElemType, cmsSigNamedColorElemType,
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
...@@ -78,8 +78,8 @@ typedef struct { ...@@ -78,8 +78,8 @@ typedef struct {
cmsContext ContextID; cmsContext ContextID;
// Number of channels // Number of channels
int nInputs; cmsUInt32Number nInputs;
int nOutputs; cmsUInt32Number nOutputs;
_cmsInterpFn16 EvalCurveIn16[MAX_INPUT_DIMENSIONS]; // The maximum number of input channels is known in advance _cmsInterpFn16 EvalCurveIn16[MAX_INPUT_DIMENSIONS]; // The maximum number of input channels is known in advance
cmsInterpParams* ParamsCurveIn16[MAX_INPUT_DIMENSIONS]; cmsInterpParams* ParamsCurveIn16[MAX_INPUT_DIMENSIONS];
...@@ -123,8 +123,8 @@ typedef struct { ...@@ -123,8 +123,8 @@ typedef struct {
cmsContext ContextID; cmsContext ContextID;
int nCurves; // Number of curves cmsUInt32Number nCurves; // Number of curves
int nElements; // Elements in curves cmsUInt32Number nElements; // Elements in curves
cmsUInt16Number** Curves; // Points to a dynamically allocated array cmsUInt16Number** Curves; // Points to a dynamically allocated array
} Curves16Data; } Curves16Data;
...@@ -245,7 +245,7 @@ cmsBool _MultiplyMatrix(cmsPipeline* Lut) ...@@ -245,7 +245,7 @@ cmsBool _MultiplyMatrix(cmsPipeline* Lut)
// Multiply both matrices to get the result // Multiply both matrices to get the result
_cmsMAT3per(&res, (cmsMAT3*)m2->Double, (cmsMAT3*)m1->Double); _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; chain = (*pt2)->Next;
// Remove both matrices // Remove both matrices
...@@ -334,7 +334,7 @@ void PrelinEval16(register const cmsUInt16Number Input[], ...@@ -334,7 +334,7 @@ void PrelinEval16(register const cmsUInt16Number Input[],
Prelin16Data* p16 = (Prelin16Data*) D; Prelin16Data* p16 = (Prelin16Data*) D;
cmsUInt16Number StageABC[MAX_INPUT_DIMENSIONS]; cmsUInt16Number StageABC[MAX_INPUT_DIMENSIONS];
cmsUInt16Number StageDEF[cmsMAXCHANNELS]; cmsUInt16Number StageDEF[cmsMAXCHANNELS];
int i; cmsUInt32Number i;
for (i=0; i < p16 ->nInputs; i++) { for (i=0; i < p16 ->nInputs; i++) {
...@@ -379,15 +379,15 @@ void* Prelin16dup(cmsContext ContextID, const void* ptr) ...@@ -379,15 +379,15 @@ void* Prelin16dup(cmsContext ContextID, const void* ptr)
static static
Prelin16Data* PrelinOpt16alloc(cmsContext ContextID, Prelin16Data* PrelinOpt16alloc(cmsContext ContextID,
const cmsInterpParams* ColorMap, const cmsInterpParams* ColorMap,
int nInputs, cmsToneCurve** In, cmsUInt32Number nInputs, cmsToneCurve** In,
int nOutputs, cmsToneCurve** Out ) cmsUInt32Number nOutputs, cmsToneCurve** Out )
{ {
int i; cmsUInt32Number i;
Prelin16Data* p16 = (Prelin16Data*)_cmsMallocZero(ContextID, sizeof(Prelin16Data)); Prelin16Data* p16 = (Prelin16Data*)_cmsMallocZero(ContextID, sizeof(Prelin16Data));
if (p16 == NULL) return NULL; if (p16 == NULL) return NULL;
p16 ->nInputs = nInputs; p16 ->nInputs = nInputs;
p16 -> nOutputs = nOutputs; p16 ->nOutputs = nOutputs;
for (i=0; i < nInputs; i++) { for (i=0; i < nInputs; i++) {
...@@ -435,7 +435,7 @@ Prelin16Data* PrelinOpt16alloc(cmsContext ContextID, ...@@ -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 // 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. // almost any transform. We use floating point precision and then convert from floating point to 16 bits.
static 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; cmsPipeline* Lut = (cmsPipeline*) Cargo;
cmsFloat32Number InFloat[cmsMAXCHANNELS], OutFloat[cmsMAXCHANNELS]; cmsFloat32Number InFloat[cmsMAXCHANNELS], OutFloat[cmsMAXCHANNELS];
...@@ -482,7 +482,7 @@ cmsBool AllCurvesAreLinear(cmsStage* mpe) ...@@ -482,7 +482,7 @@ cmsBool AllCurvesAreLinear(cmsStage* mpe)
// is to fix scum dot on broken profiles/transforms. Works on 1, 3 and 4 channels // is to fix scum dot on broken profiles/transforms. Works on 1, 3 and 4 channels
static static
cmsBool PatchLUT(cmsStage* CLUT, cmsUInt16Number At[], cmsUInt16Number Value[], cmsBool PatchLUT(cmsStage* CLUT, cmsUInt16Number At[], cmsUInt16Number Value[],
int nChannelsOut, int nChannelsIn) cmsUInt32Number nChannelsOut, cmsUInt32Number nChannelsIn)
{ {
_cmsStageCLutData* Grid = (_cmsStageCLutData*) CLUT ->Data; _cmsStageCLutData* Grid = (_cmsStageCLutData*) CLUT ->Data;
cmsInterpParams* p16 = Grid ->Params; cmsInterpParams* p16 = Grid ->Params;
...@@ -512,10 +512,10 @@ cmsBool PatchLUT(cmsStage* CLUT, cmsUInt16Number At[], cmsUInt16Number Value[], ...@@ -512,10 +512,10 @@ cmsBool PatchLUT(cmsStage* CLUT, cmsUInt16Number At[], cmsUInt16Number Value[],
((pz - z0) != 0) || ((pz - z0) != 0) ||
((pw - w0) != 0)) return FALSE; // Not on exact node ((pw - w0) != 0)) return FALSE; // Not on exact node
index = p16 -> opta[3] * x0 + index = (int) p16 -> opta[3] * x0 +
p16 -> opta[2] * y0 + (int) p16 -> opta[2] * y0 +
p16 -> opta[1] * z0 + (int) p16 -> opta[1] * z0 +
p16 -> opta[0] * w0; (int) p16 -> opta[0] * w0;
} }
else else
if (nChannelsIn == 3) { if (nChannelsIn == 3) {
...@@ -532,9 +532,9 @@ cmsBool PatchLUT(cmsStage* CLUT, cmsUInt16Number At[], cmsUInt16Number Value[], ...@@ -532,9 +532,9 @@ cmsBool PatchLUT(cmsStage* CLUT, cmsUInt16Number At[], cmsUInt16Number Value[],
((py - y0) != 0) || ((py - y0) != 0) ||
((pz - z0) != 0)) return FALSE; // Not on exact node ((pz - z0) != 0)) return FALSE; // Not on exact node
index = p16 -> opta[2] * x0 + index = (int) p16 -> opta[2] * x0 +
p16 -> opta[1] * y0 + (int) p16 -> opta[1] * y0 +
p16 -> opta[0] * z0; (int) p16 -> opta[0] * z0;
} }
else else
if (nChannelsIn == 1) { if (nChannelsIn == 1) {
...@@ -545,24 +545,24 @@ cmsBool PatchLUT(cmsStage* CLUT, cmsUInt16Number At[], cmsUInt16Number Value[], ...@@ -545,24 +545,24 @@ cmsBool PatchLUT(cmsStage* CLUT, cmsUInt16Number At[], cmsUInt16Number Value[],
if (((px - x0) != 0)) return FALSE; // Not on exact node if (((px - x0) != 0)) return FALSE; // Not on exact node
index = p16 -> opta[0] * x0; index = (int) p16 -> opta[0] * x0;
} }
else { else {
cmsSignalError(CLUT->ContextID, cmsERROR_INTERNAL, "(internal) %d Channels are not supported on PatchLUT", nChannelsIn); cmsSignalError(CLUT->ContextID, cmsERROR_INTERNAL, "(internal) %d Channels are not supported on PatchLUT", nChannelsIn);
return FALSE; return FALSE;
} }
for (i=0; i < nChannelsOut; i++) for (i = 0; i < (int) nChannelsOut; i++)
Grid -> Tab.T[index + i] = Value[i]; Grid->Tab.T[index + i] = Value[i];
return TRUE; return TRUE;
} }
// Auxiliary, to see if two values are equal or very different // Auxiliary, to see if two values are equal or very different
static 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++) { for (i=0; i < n; i++) {
...@@ -664,7 +664,7 @@ cmsBool OptimizeByResampling(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3 ...@@ -664,7 +664,7 @@ cmsBool OptimizeByResampling(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3
cmsStage* mpe; cmsStage* mpe;
cmsStage* CLUT; cmsStage* CLUT;
cmsStage *KeepPreLin = NULL, *KeepPostLin = NULL; cmsStage *KeepPreLin = NULL, *KeepPostLin = NULL;
int nGridPoints; cmsUInt32Number nGridPoints;
cmsColorSpaceSignature ColorSpace, OutputColorSpace; cmsColorSpaceSignature ColorSpace, OutputColorSpace;
cmsStage *NewPreLin = NULL; cmsStage *NewPreLin = NULL;
cmsStage *NewPostLin = NULL; cmsStage *NewPostLin = NULL;
...@@ -676,8 +676,13 @@ cmsBool OptimizeByResampling(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3 ...@@ -676,8 +676,13 @@ cmsBool OptimizeByResampling(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3
// This is a loosy optimization! does not apply in floating-point cases // This is a loosy optimization! does not apply in floating-point cases
if (_cmsFormatterIsFloat(*InputFormat) || _cmsFormatterIsFloat(*OutputFormat)) return FALSE; if (_cmsFormatterIsFloat(*InputFormat) || _cmsFormatterIsFloat(*OutputFormat)) return FALSE;
ColorSpace = _cmsICCcolorSpace(T_COLORSPACE(*InputFormat)); ColorSpace = _cmsICCcolorSpace((int) T_COLORSPACE(*InputFormat));
OutputColorSpace = _cmsICCcolorSpace(T_COLORSPACE(*OutputFormat)); OutputColorSpace = _cmsICCcolorSpace((int) T_COLORSPACE(*OutputFormat));
// Color space must be specified
if (ColorSpace == (cmsColorSpaceSignature)0 ||
OutputColorSpace == (cmsColorSpaceSignature)0) return FALSE;
nGridPoints = _cmsReasonableGridpointsByColorspace(ColorSpace, *dwFlags); nGridPoints = _cmsReasonableGridpointsByColorspace(ColorSpace, *dwFlags);
// For empty LUTs, 2 points are enough // For empty LUTs, 2 points are enough
...@@ -715,7 +720,7 @@ cmsBool OptimizeByResampling(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3 ...@@ -715,7 +720,7 @@ cmsBool OptimizeByResampling(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3
goto Error; goto Error;
// Remove prelinearization. Since we have duplicated the curve // 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); cmsPipelineUnlinkStage(Src, cmsAT_BEGIN, &KeepPreLin);
} }
} }
...@@ -723,7 +728,7 @@ cmsBool OptimizeByResampling(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3 ...@@ -723,7 +728,7 @@ cmsBool OptimizeByResampling(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3
// Allocate the CLUT // Allocate the CLUT
CLUT = cmsStageAllocCLut16bit(Src ->ContextID, nGridPoints, Src ->InputChannels, Src->OutputChannels, NULL); 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 // Add the CLUT to the destination LUT
if (!cmsPipelineInsertStage(Dest, cmsAT_END, CLUT)) { if (!cmsPipelineInsertStage(Dest, cmsAT_END, CLUT)) {
...@@ -747,14 +752,14 @@ cmsBool OptimizeByResampling(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3 ...@@ -747,14 +752,14 @@ cmsBool OptimizeByResampling(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3
if (!cmsPipelineInsertStage(Dest, cmsAT_END, NewPostLin)) if (!cmsPipelineInsertStage(Dest, cmsAT_END, NewPostLin))
goto Error; 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); cmsPipelineUnlinkStage(Src, cmsAT_END, &KeepPostLin);
} }
} }
} }
// Now its time to do the sampling. We have to ignore pre/post linearization // 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)) { if (!cmsStageSampleCLut16bit(CLUT, XFormSampler16, (void*) Src, 0)) {
Error: Error:
// Ops, something went wrong, Restore stages // Ops, something went wrong, Restore stages
...@@ -834,7 +839,7 @@ void SlopeLimiting(cmsToneCurve* g) ...@@ -834,7 +839,7 @@ void SlopeLimiting(cmsToneCurve* g)
{ {
int BeginVal, EndVal; int BeginVal, EndVal;
int AtBegin = (int) floor((cmsFloat64Number) g ->nEntries * 0.02 + 0.5); // Cutoff at 2% 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; cmsFloat64Number Val, Slope, beta;
int i; int i;
...@@ -895,9 +900,9 @@ Prelin8Data* PrelinOpt8alloc(cmsContext ContextID, const cmsInterpParams* p, cms ...@@ -895,9 +900,9 @@ Prelin8Data* PrelinOpt8alloc(cmsContext ContextID, const cmsInterpParams* p, cms
// Move to 0..1.0 in fixed domain // Move to 0..1.0 in fixed domain
v1 = _cmsToFixedDomain(Input[0] * p -> Domain[0]); v1 = _cmsToFixedDomain((int) (Input[0] * p -> Domain[0]));
v2 = _cmsToFixedDomain(Input[1] * p -> Domain[1]); v2 = _cmsToFixedDomain((int) (Input[1] * p -> Domain[1]));
v3 = _cmsToFixedDomain(Input[2] * p -> Domain[2]); v3 = _cmsToFixedDomain((int) (Input[2] * p -> Domain[2]));
// Store the precalculated table of nodes // Store the precalculated table of nodes
p8 ->X0[i] = (p->opta[2] * FIXED_TO_INT(v1)); p8 ->X0[i] = (p->opta[2] * FIXED_TO_INT(v1));
...@@ -942,27 +947,27 @@ void PrelinEval8(register const cmsUInt16Number Input[], ...@@ -942,27 +947,27 @@ void PrelinEval8(register const cmsUInt16Number Input[],
cmsS15Fixed16Number rx, ry, rz; cmsS15Fixed16Number rx, ry, rz;
cmsS15Fixed16Number c0, c1, c2, c3, Rest; cmsS15Fixed16Number c0, c1, c2, c3, Rest;
int OutChan; int OutChan;
register cmsS15Fixed16Number X0, X1, Y0, Y1, Z0, Z1; register cmsS15Fixed16Number X0, X1, Y0, Y1, Z0, Z1;
Prelin8Data* p8 = (Prelin8Data*) D; Prelin8Data* p8 = (Prelin8Data*) D;
register const cmsInterpParams* p = p8 ->p; register const cmsInterpParams* p = p8 ->p;
int TotalOut = p -> nOutputs; int TotalOut = (int) p -> nOutputs;
const cmsUInt16Number* LutTable = (const cmsUInt16Number*) p->Table; const cmsUInt16Number* LutTable = (const cmsUInt16Number*) p->Table;
r = Input[0] >> 8; r = (cmsUInt8Number) (Input[0] >> 8);
g = Input[1] >> 8; g = (cmsUInt8Number) (Input[1] >> 8);
b = Input[2] >> 8; b = (cmsUInt8Number) (Input[2] >> 8);
X0 = X1 = p8->X0[r]; X0 = X1 = (cmsS15Fixed16Number) p8->X0[r];
Y0 = Y1 = p8->Y0[g]; Y0 = Y1 = (cmsS15Fixed16Number) p8->Y0[g];
Z0 = Z1 = p8->Z0[b]; Z0 = Z1 = (cmsS15Fixed16Number) p8->Z0[b];
rx = p8 ->rx[r]; rx = p8 ->rx[r];
ry = p8 ->ry[g]; ry = p8 ->ry[g];
rz = p8 ->rz[b]; rz = p8 ->rz[b];
X1 = X0 + ((rx == 0) ? 0 : p ->opta[2]); X1 = X0 + (cmsS15Fixed16Number)((rx == 0) ? 0 : p ->opta[2]);
Y1 = Y0 + ((ry == 0) ? 0 : p ->opta[1]); Y1 = Y0 + (cmsS15Fixed16Number)((ry == 0) ? 0 : p ->opta[1]);
Z1 = Z0 + ((rz == 0) ? 0 : p ->opta[0]); Z1 = Z0 + (cmsS15Fixed16Number)((rz == 0) ? 0 : p ->opta[0]);
// These are the 6 Tetrahedral // These are the 6 Tetrahedral
...@@ -1015,9 +1020,8 @@ void PrelinEval8(register const cmsUInt16Number Input[], ...@@ -1015,9 +1020,8 @@ void PrelinEval8(register const cmsUInt16Number Input[],
c1 = c2 = c3 = 0; c1 = c2 = c3 = 0;
} }
Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001; 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[], ...@@ -1029,8 +1033,8 @@ void PrelinEval8(register const cmsUInt16Number Input[],
static static
cmsBool IsDegenerated(const cmsToneCurve* g) cmsBool IsDegenerated(const cmsToneCurve* g)
{ {
int i, Zeros = 0, Poles = 0; cmsUInt32Number i, Zeros = 0, Poles = 0;
int nEntries = g ->nEntries; cmsUInt32Number nEntries = g ->nEntries;
for (i=0; i < nEntries; i++) { for (i=0; i < nEntries; i++) {
...@@ -1052,7 +1056,7 @@ static ...@@ -1052,7 +1056,7 @@ static
cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt32Number* InputFormat, cmsUInt32Number* OutputFormat, cmsUInt32Number* dwFlags) cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt32Number* InputFormat, cmsUInt32Number* OutputFormat, cmsUInt32Number* dwFlags)
{ {
cmsPipeline* OriginalLut; cmsPipeline* OriginalLut;
int nGridPoints; cmsUInt32Number nGridPoints;
cmsToneCurve *Trans[cmsMAXCHANNELS], *TransReverse[cmsMAXCHANNELS]; cmsToneCurve *Trans[cmsMAXCHANNELS], *TransReverse[cmsMAXCHANNELS];
cmsUInt32Number t, i; cmsUInt32Number t, i;
cmsFloat32Number v, In[cmsMAXCHANNELS], Out[cmsMAXCHANNELS]; cmsFloat32Number v, In[cmsMAXCHANNELS], Out[cmsMAXCHANNELS];
...@@ -1090,8 +1094,13 @@ cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Inte ...@@ -1090,8 +1094,13 @@ cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Inte
if (cmsStageType(mpe) == cmsSigNamedColorElemType) return FALSE; if (cmsStageType(mpe) == cmsSigNamedColorElemType) return FALSE;
} }
ColorSpace = _cmsICCcolorSpace(T_COLORSPACE(*InputFormat)); ColorSpace = _cmsICCcolorSpace((int) T_COLORSPACE(*InputFormat));
OutputColorSpace = _cmsICCcolorSpace(T_COLORSPACE(*OutputFormat)); OutputColorSpace = _cmsICCcolorSpace((int) T_COLORSPACE(*OutputFormat));
// Color space must be specified
if (ColorSpace == (cmsColorSpaceSignature)0 ||
OutputColorSpace == (cmsColorSpaceSignature)0) return FALSE;
nGridPoints = _cmsReasonableGridpointsByColorspace(ColorSpace, *dwFlags); nGridPoints = _cmsReasonableGridpointsByColorspace(ColorSpace, *dwFlags);
// Empty gamma containers // Empty gamma containers
...@@ -1212,7 +1221,10 @@ cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Inte ...@@ -1212,7 +1221,10 @@ cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Inte
Prelin8Data* p8 = PrelinOpt8alloc(OptimizedLUT ->ContextID, Prelin8Data* p8 = PrelinOpt8alloc(OptimizedLUT ->ContextID,
OptimizedPrelinCLUT ->Params, OptimizedPrelinCLUT ->Params,
OptimizedPrelinCurves); OptimizedPrelinCurves);
if (p8 == NULL) return FALSE; if (p8 == NULL) {
cmsPipelineFree(OptimizedLUT);
return FALSE;
}
_cmsPipelineSetOptimizationParameters(OptimizedLUT, PrelinEval8, (void*) p8, Prelin8free, Prelin8dup); _cmsPipelineSetOptimizationParameters(OptimizedLUT, PrelinEval8, (void*) p8, Prelin8free, Prelin8dup);
...@@ -1222,7 +1234,10 @@ cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Inte ...@@ -1222,7 +1234,10 @@ cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Inte
Prelin16Data* p16 = PrelinOpt16alloc(OptimizedLUT ->ContextID, Prelin16Data* p16 = PrelinOpt16alloc(OptimizedLUT ->ContextID,
OptimizedPrelinCLUT ->Params, OptimizedPrelinCLUT ->Params,
3, OptimizedPrelinCurves, 3, NULL); 3, OptimizedPrelinCurves, 3, NULL);
if (p16 == NULL) return FALSE; if (p16 == NULL) {
cmsPipelineFree(OptimizedLUT);
return FALSE;
}
_cmsPipelineSetOptimizationParameters(OptimizedLUT, PrelinEval16, (void*) p16, PrelinOpt16free, Prelin16dup); _cmsPipelineSetOptimizationParameters(OptimizedLUT, PrelinEval16, (void*) p16, PrelinOpt16free, Prelin16dup);
...@@ -1260,6 +1275,7 @@ Error: ...@@ -1260,6 +1275,7 @@ Error:
return FALSE; return FALSE;
cmsUNUSED_PARAMETER(Intent); cmsUNUSED_PARAMETER(Intent);
cmsUNUSED_PARAMETER(lIsLinear);
} }
...@@ -1269,7 +1285,7 @@ static ...@@ -1269,7 +1285,7 @@ static
void CurvesFree(cmsContext ContextID, void* ptr) void CurvesFree(cmsContext ContextID, void* ptr)
{ {
Curves16Data* Data = (Curves16Data*) ptr; Curves16Data* Data = (Curves16Data*) ptr;
int i; cmsUInt32Number i;
for (i=0; i < Data -> nCurves; i++) { for (i=0; i < Data -> nCurves; i++) {
...@@ -1284,7 +1300,7 @@ static ...@@ -1284,7 +1300,7 @@ static
void* CurvesDup(cmsContext ContextID, const void* ptr) void* CurvesDup(cmsContext ContextID, const void* ptr)
{ {
Curves16Data* Data = (Curves16Data*)_cmsDupMem(ContextID, ptr, sizeof(Curves16Data)); Curves16Data* Data = (Curves16Data*)_cmsDupMem(ContextID, ptr, sizeof(Curves16Data));
int i; cmsUInt32Number i;
if (Data == NULL) return NULL; if (Data == NULL) return NULL;
...@@ -1299,9 +1315,9 @@ void* CurvesDup(cmsContext ContextID, const void* ptr) ...@@ -1299,9 +1315,9 @@ void* CurvesDup(cmsContext ContextID, const void* ptr)
// Precomputes tables for 8-bit on input devicelink. // Precomputes tables for 8-bit on input devicelink.
static 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; Curves16Data* c16;
c16 = (Curves16Data*)_cmsMallocZero(ContextID, sizeof(Curves16Data)); c16 = (Curves16Data*)_cmsMallocZero(ContextID, sizeof(Curves16Data));
...@@ -1311,7 +1327,10 @@ Curves16Data* CurvesAlloc(cmsContext ContextID, int nCurves, int nElements, cmsT ...@@ -1311,7 +1327,10 @@ Curves16Data* CurvesAlloc(cmsContext ContextID, int nCurves, int nElements, cmsT
c16 ->nElements = nElements; c16 ->nElements = nElements;
c16->Curves = (cmsUInt16Number**) _cmsCalloc(ContextID, nCurves, sizeof(cmsUInt16Number*)); 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++) { for (i=0; i < nCurves; i++) {
...@@ -1327,7 +1346,7 @@ Curves16Data* CurvesAlloc(cmsContext ContextID, int nCurves, int nElements, cmsT ...@@ -1327,7 +1346,7 @@ Curves16Data* CurvesAlloc(cmsContext ContextID, int nCurves, int nElements, cmsT
return NULL; return NULL;
} }
if (nElements == 256) { if (nElements == 256U) {
for (j=0; j < nElements; j++) { for (j=0; j < nElements; j++) {
...@@ -1351,8 +1370,8 @@ void FastEvaluateCurves8(register const cmsUInt16Number In[], ...@@ -1351,8 +1370,8 @@ void FastEvaluateCurves8(register const cmsUInt16Number In[],
register const void* D) register const void* D)
{ {
Curves16Data* Data = (Curves16Data*) D; Curves16Data* Data = (Curves16Data*) D;
cmsUInt8Number x; int x;
int i; cmsUInt32Number i;
for (i=0; i < Data ->nCurves; i++) { for (i=0; i < Data ->nCurves; i++) {
...@@ -1368,7 +1387,7 @@ void FastEvaluateCurves16(register const cmsUInt16Number In[], ...@@ -1368,7 +1387,7 @@ void FastEvaluateCurves16(register const cmsUInt16Number In[],
register const void* D) register const void* D)
{ {
Curves16Data* Data = (Curves16Data*) D; Curves16Data* Data = (Curves16Data*) D;
int i; cmsUInt32Number i;
for (i=0; i < Data ->nCurves; i++) { for (i=0; i < Data ->nCurves; i++) {
Out[i] = Data -> Curves[i][In[i]]; Out[i] = Data -> Curves[i][In[i]];
...@@ -1548,9 +1567,9 @@ void MatShaperEval16(register const cmsUInt16Number In[], ...@@ -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 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) // In[] is assured to come from a 8 bit number. (a << 8 | a)
ri = In[0] & 0xFF; ri = In[0] & 0xFFU;
gi = In[1] & 0xFF; gi = In[1] & 0xFFU;
bi = In[2] & 0xFF; bi = In[2] & 0xFFU;
// Across first shaper, which also converts to 1.14 fixed point // Across first shaper, which also converts to 1.14 fixed point
r = p->Shaper1R[ri]; r = p->Shaper1R[ri];
...@@ -1563,9 +1582,9 @@ void MatShaperEval16(register const cmsUInt16Number In[], ...@@ -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; 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 // Now we have to clip to 0..1.0 range
ri = (l1 < 0) ? 0 : ((l1 > 16384) ? 16384 : l1); ri = (l1 < 0) ? 0 : ((l1 > 16384) ? 16384U : (cmsUInt32Number) l1);
gi = (l2 < 0) ? 0 : ((l2 > 16384) ? 16384 : l2); gi = (l2 < 0) ? 0 : ((l2 > 16384) ? 16384U : (cmsUInt32Number) l2);
bi = (l3 < 0) ? 0 : ((l3 > 16384) ? 16384 : l3); bi = (l3 < 0) ? 0 : ((l3 > 16384) ? 16384U : (cmsUInt32Number) l3);
// And across second shaper, // And across second shaper,
Out[0] = p->Shaper2R[ri]; Out[0] = p->Shaper2R[ri];
...@@ -1586,7 +1605,10 @@ void FillFirstShaper(cmsS1Fixed14Number* Table, cmsToneCurve* Curve) ...@@ -1586,7 +1605,10 @@ void FillFirstShaper(cmsS1Fixed14Number* Table, cmsToneCurve* Curve)
R = (cmsFloat32Number) (i / 255.0); R = (cmsFloat32Number) (i / 255.0);
y = cmsEvalToneCurveFloat(Curve, R); 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 ...@@ -1602,6 +1624,12 @@ void FillSecondShaper(cmsUInt16Number* Table, cmsToneCurve* Curve, cmsBool Is8Bi
R = (cmsFloat32Number) (i / 16384.0); R = (cmsFloat32Number) (i / 16384.0);
Val = cmsEvalToneCurveFloat(Curve, R); // Val comes 0..1.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 (Is8BitsOutput) {
// If 8 bits output, we can optimize further by computing the / 257 part. // 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 ...@@ -1640,7 +1668,7 @@ cmsBool SetMatShaper(cmsPipeline* Dest, cmsToneCurve* Curve1[3], cmsMAT3* Mat, c
FillSecondShaper(p ->Shaper2G, Curve2[1], Is8Bits); FillSecondShaper(p ->Shaper2G, Curve2[1], Is8Bits);
FillSecondShaper(p ->Shaper2B, Curve2[2], 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 (i=0; i < 3; i++) {
for (j=0; j < 3; j++) { for (j=0; j < 3; j++) {
p ->Mat[i][j] = DOUBLE_TO_1FIXED14(Mat->v[i].n[j]); p ->Mat[i][j] = DOUBLE_TO_1FIXED14(Mat->v[i].n[j]);
...@@ -1902,7 +1930,7 @@ cmsBool _cmsRegisterOptimizationPlugin(cmsContext ContextID, cmsPluginBase* Dat ...@@ -1902,7 +1930,7 @@ cmsBool _cmsRegisterOptimizationPlugin(cmsContext ContextID, cmsPluginBase* Dat
// The entry point for LUT optimization // The entry point for LUT optimization
cmsBool _cmsOptimizePipeline(cmsContext ContextID, cmsBool _cmsOptimizePipeline(cmsContext ContextID,
cmsPipeline** PtrLut, cmsPipeline** PtrLut,
int Intent, cmsUInt32Number Intent,
cmsUInt32Number* InputFormat, cmsUInt32Number* InputFormat,
cmsUInt32Number* OutputFormat, cmsUInt32Number* OutputFormat,
cmsUInt32Number* dwFlags) cmsUInt32Number* dwFlags)
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
...@@ -126,21 +126,21 @@ cmsUInt8Number* UnrollChunkyBytes(register _cmsTRANSFORM* info, ...@@ -126,21 +126,21 @@ cmsUInt8Number* UnrollChunkyBytes(register _cmsTRANSFORM* info,
register cmsUInt8Number* accum, register cmsUInt8Number* accum,
register cmsUInt32Number Stride) register cmsUInt32Number Stride)
{ {
int nChan = T_CHANNELS(info -> InputFormat); cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
int DoSwap = T_DOSWAP(info ->InputFormat); cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat);
int Reverse = T_FLAVOR(info ->InputFormat); cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat);
int SwapFirst = T_SWAPFIRST(info -> InputFormat); cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat);
int Extra = T_EXTRA(info -> InputFormat); cmsUInt32Number Extra = T_EXTRA(info -> InputFormat);
int ExtraFirst = DoSwap ^ SwapFirst; cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsUInt16Number v; cmsUInt16Number v;
int i; cmsUInt32Number i;
if (ExtraFirst) { if (ExtraFirst) {
accum += Extra; accum += Extra;
} }
for (i=0; i < nChan; i++) { for (i=0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i; cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
v = FROM_8_TO_16(*accum); v = FROM_8_TO_16(*accum);
v = Reverse ? REVERSE_FLAVOR_16(v) : v; v = Reverse ? REVERSE_FLAVOR_16(v) : v;
...@@ -173,11 +173,11 @@ cmsUInt8Number* UnrollPlanarBytes(register _cmsTRANSFORM* info, ...@@ -173,11 +173,11 @@ cmsUInt8Number* UnrollPlanarBytes(register _cmsTRANSFORM* info,
register cmsUInt8Number* accum, register cmsUInt8Number* accum,
register cmsUInt32Number Stride) register cmsUInt32Number Stride)
{ {
int nChan = T_CHANNELS(info -> InputFormat); cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
int DoSwap = T_DOSWAP(info ->InputFormat); cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat);
int SwapFirst = T_SWAPFIRST(info ->InputFormat); cmsUInt32Number SwapFirst = T_SWAPFIRST(info ->InputFormat);
int Reverse = T_FLAVOR(info ->InputFormat); cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat);
int i; cmsUInt32Number i;
cmsUInt8Number* Init = accum; cmsUInt8Number* Init = accum;
if (DoSwap ^ SwapFirst) { if (DoSwap ^ SwapFirst) {
...@@ -186,7 +186,7 @@ cmsUInt8Number* UnrollPlanarBytes(register _cmsTRANSFORM* info, ...@@ -186,7 +186,7 @@ cmsUInt8Number* UnrollPlanarBytes(register _cmsTRANSFORM* info,
for (i=0; i < nChan; i++) { for (i=0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i; cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
cmsUInt16Number v = FROM_8_TO_16(*accum); cmsUInt16Number v = FROM_8_TO_16(*accum);
wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v; wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
...@@ -503,14 +503,14 @@ cmsUInt8Number* UnrollAnyWords(register _cmsTRANSFORM* info, ...@@ -503,14 +503,14 @@ cmsUInt8Number* UnrollAnyWords(register _cmsTRANSFORM* info,
register cmsUInt8Number* accum, register cmsUInt8Number* accum,
register cmsUInt32Number Stride) register cmsUInt32Number Stride)
{ {
int nChan = T_CHANNELS(info -> InputFormat); cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
int SwapEndian = T_ENDIAN16(info -> InputFormat); cmsUInt32Number SwapEndian = T_ENDIAN16(info -> InputFormat);
int DoSwap = T_DOSWAP(info ->InputFormat); cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat);
int Reverse = T_FLAVOR(info ->InputFormat); cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat);
int SwapFirst = T_SWAPFIRST(info -> InputFormat); cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat);
int Extra = T_EXTRA(info -> InputFormat); cmsUInt32Number Extra = T_EXTRA(info -> InputFormat);
int ExtraFirst = DoSwap ^ SwapFirst; cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
int i; cmsUInt32Number i;
if (ExtraFirst) { if (ExtraFirst) {
accum += Extra * sizeof(cmsUInt16Number); accum += Extra * sizeof(cmsUInt16Number);
...@@ -518,7 +518,7 @@ cmsUInt8Number* UnrollAnyWords(register _cmsTRANSFORM* info, ...@@ -518,7 +518,7 @@ cmsUInt8Number* UnrollAnyWords(register _cmsTRANSFORM* info,
for (i=0; i < nChan; i++) { for (i=0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i; cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
cmsUInt16Number v = *(cmsUInt16Number*) accum; cmsUInt16Number v = *(cmsUInt16Number*) accum;
if (SwapEndian) if (SwapEndian)
...@@ -552,20 +552,20 @@ cmsUInt8Number* UnrollPlanarWords(register _cmsTRANSFORM* info, ...@@ -552,20 +552,20 @@ cmsUInt8Number* UnrollPlanarWords(register _cmsTRANSFORM* info,
register cmsUInt8Number* accum, register cmsUInt8Number* accum,
register cmsUInt32Number Stride) register cmsUInt32Number Stride)
{ {
int nChan = T_CHANNELS(info -> InputFormat); cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
int DoSwap= T_DOSWAP(info ->InputFormat); cmsUInt32Number DoSwap= T_DOSWAP(info ->InputFormat);
int Reverse= T_FLAVOR(info ->InputFormat); cmsUInt32Number Reverse= T_FLAVOR(info ->InputFormat);
int SwapEndian = T_ENDIAN16(info -> InputFormat); cmsUInt32Number SwapEndian = T_ENDIAN16(info -> InputFormat);
int i; cmsUInt32Number i;
cmsUInt8Number* Init = accum; cmsUInt8Number* Init = accum;
if (DoSwap) { if (DoSwap) {
accum += T_EXTRA(info -> InputFormat) * Stride * sizeof(cmsUInt16Number); accum += T_EXTRA(info -> InputFormat) * Stride;
} }
for (i=0; i < nChan; i++) { for (i=0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i; cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
cmsUInt16Number v = *(cmsUInt16Number*) accum; cmsUInt16Number v = *(cmsUInt16Number*) accum;
if (SwapEndian) if (SwapEndian)
...@@ -573,7 +573,7 @@ cmsUInt8Number* UnrollPlanarWords(register _cmsTRANSFORM* info, ...@@ -573,7 +573,7 @@ cmsUInt8Number* UnrollPlanarWords(register _cmsTRANSFORM* info,
wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v; wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
accum += Stride * sizeof(cmsUInt16Number); accum += Stride;
} }
return (Init + sizeof(cmsUInt16Number)); return (Init + sizeof(cmsUInt16Number));
...@@ -801,13 +801,18 @@ cmsUInt8Number* UnrollLabDoubleTo16(register _cmsTRANSFORM* info, ...@@ -801,13 +801,18 @@ cmsUInt8Number* UnrollLabDoubleTo16(register _cmsTRANSFORM* info,
{ {
if (T_PLANAR(info -> InputFormat)) { if (T_PLANAR(info -> InputFormat)) {
cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
cmsCIELab Lab; cmsCIELab Lab;
cmsUInt8Number* pos_L;
cmsUInt8Number* pos_a;
cmsUInt8Number* pos_b;
pos_L = accum;
pos_a = accum + Stride;
pos_b = accum + Stride * 2;
Lab.L = Pt[0]; Lab.L = *(cmsFloat64Number*) pos_L;
Lab.a = Pt[Stride]; Lab.a = *(cmsFloat64Number*) pos_a;
Lab.b = Pt[Stride*2]; Lab.b = *(cmsFloat64Number*) pos_b;
cmsFloat2LabEncoded(wIn, &Lab); cmsFloat2LabEncoded(wIn, &Lab);
return accum + sizeof(cmsFloat64Number); return accum + sizeof(cmsFloat64Number);
...@@ -832,12 +837,17 @@ cmsUInt8Number* UnrollLabFloatTo16(register _cmsTRANSFORM* info, ...@@ -832,12 +837,17 @@ cmsUInt8Number* UnrollLabFloatTo16(register _cmsTRANSFORM* info,
if (T_PLANAR(info -> InputFormat)) { if (T_PLANAR(info -> InputFormat)) {
cmsFloat32Number* Pt = (cmsFloat32Number*) accum; cmsUInt8Number* pos_L;
cmsUInt8Number* pos_a;
cmsUInt8Number* pos_b;
pos_L = accum;
pos_a = accum + Stride;
pos_b = accum + Stride * 2;
Lab.L = Pt[0]; Lab.L = *(cmsFloat32Number*)pos_L;
Lab.a = Pt[Stride]; Lab.a = *(cmsFloat32Number*)pos_a;
Lab.b = Pt[Stride*2]; Lab.b = *(cmsFloat32Number*)pos_b;
cmsFloat2LabEncoded(wIn, &Lab); cmsFloat2LabEncoded(wIn, &Lab);
return accum + sizeof(cmsFloat32Number); return accum + sizeof(cmsFloat32Number);
...@@ -863,12 +873,19 @@ cmsUInt8Number* UnrollXYZDoubleTo16(register _cmsTRANSFORM* info, ...@@ -863,12 +873,19 @@ cmsUInt8Number* UnrollXYZDoubleTo16(register _cmsTRANSFORM* info,
{ {
if (T_PLANAR(info -> InputFormat)) { if (T_PLANAR(info -> InputFormat)) {
cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
cmsCIEXYZ XYZ; cmsCIEXYZ XYZ;
cmsUInt8Number* pos_X;
cmsUInt8Number* pos_Y;
cmsUInt8Number* pos_Z;
pos_X = accum;
pos_Y = accum + Stride;
pos_Z = accum + Stride * 2;
XYZ.X = *(cmsFloat64Number*)pos_X;
XYZ.Y = *(cmsFloat64Number*)pos_Y;
XYZ.Z = *(cmsFloat64Number*)pos_Z;
XYZ.X = Pt[0];
XYZ.Y = Pt[Stride];
XYZ.Z = Pt[Stride*2];
cmsFloat2XYZEncoded(wIn, &XYZ); cmsFloat2XYZEncoded(wIn, &XYZ);
return accum + sizeof(cmsFloat64Number); return accum + sizeof(cmsFloat64Number);
...@@ -892,12 +909,19 @@ cmsUInt8Number* UnrollXYZFloatTo16(register _cmsTRANSFORM* info, ...@@ -892,12 +909,19 @@ cmsUInt8Number* UnrollXYZFloatTo16(register _cmsTRANSFORM* info,
{ {
if (T_PLANAR(info -> InputFormat)) { if (T_PLANAR(info -> InputFormat)) {
cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
cmsCIEXYZ XYZ; cmsCIEXYZ XYZ;
cmsUInt8Number* pos_X;
cmsUInt8Number* pos_Y;
cmsUInt8Number* pos_Z;
pos_X = accum;
pos_Y = accum + Stride;
pos_Z = accum + Stride * 2;
XYZ.X = *(cmsFloat32Number*)pos_X;
XYZ.Y = *(cmsFloat32Number*)pos_Y;
XYZ.Z = *(cmsFloat32Number*)pos_Z;
XYZ.X = Pt[0];
XYZ.Y = Pt[Stride];
XYZ.Z = Pt[Stride*2];
cmsFloat2XYZEncoded(wIn, &XYZ); cmsFloat2XYZEncoded(wIn, &XYZ);
return accum + sizeof(cmsFloat32Number); return accum + sizeof(cmsFloat32Number);
...@@ -942,6 +966,20 @@ cmsINLINE cmsBool IsInkSpace(cmsUInt32Number Type) ...@@ -942,6 +966,20 @@ cmsINLINE cmsBool IsInkSpace(cmsUInt32Number Type)
} }
} }
// Return the size in bytes of a given formatter
static
cmsUInt32Number PixelSize(cmsUInt32Number Format)
{
cmsUInt32Number fmt_bytes = T_BYTES(Format);
// For double, the T_BYTES field is zero
if (fmt_bytes == 0)
return sizeof(cmsUInt64Number);
// Otherwise, it is already correct for all formats
return fmt_bytes;
}
// Inks does come in percentage, remaining cases are between 0..1.0, again to 16 bits // Inks does come in percentage, remaining cases are between 0..1.0, again to 16 bits
static static
cmsUInt8Number* UnrollDoubleTo16(register _cmsTRANSFORM* info, cmsUInt8Number* UnrollDoubleTo16(register _cmsTRANSFORM* info,
...@@ -950,25 +988,27 @@ cmsUInt8Number* UnrollDoubleTo16(register _cmsTRANSFORM* info, ...@@ -950,25 +988,27 @@ cmsUInt8Number* UnrollDoubleTo16(register _cmsTRANSFORM* info,
register cmsUInt32Number Stride) register cmsUInt32Number Stride)
{ {
int nChan = T_CHANNELS(info -> InputFormat); cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
int DoSwap = T_DOSWAP(info ->InputFormat); cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat);
int Reverse = T_FLAVOR(info ->InputFormat); cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat);
int SwapFirst = T_SWAPFIRST(info -> InputFormat); cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat);
int Extra = T_EXTRA(info -> InputFormat); cmsUInt32Number Extra = T_EXTRA(info -> InputFormat);
int ExtraFirst = DoSwap ^ SwapFirst; cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
int Planar = T_PLANAR(info -> InputFormat); cmsUInt32Number Planar = T_PLANAR(info -> InputFormat);
cmsFloat64Number v; cmsFloat64Number v;
cmsUInt16Number vi; cmsUInt16Number vi;
int i, start = 0; cmsUInt32Number i, start = 0;
cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0; cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
Stride /= PixelSize(info->InputFormat);
if (ExtraFirst) if (ExtraFirst)
start = Extra; start = Extra;
for (i=0; i < nChan; i++) { for (i=0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i; cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
if (Planar) if (Planar)
v = (cmsFloat32Number) ((cmsFloat64Number*) accum)[(i + start) * Stride]; v = (cmsFloat32Number) ((cmsFloat64Number*) accum)[(i + start) * Stride];
...@@ -1006,25 +1046,26 @@ cmsUInt8Number* UnrollFloatTo16(register _cmsTRANSFORM* info, ...@@ -1006,25 +1046,26 @@ cmsUInt8Number* UnrollFloatTo16(register _cmsTRANSFORM* info,
register cmsUInt32Number Stride) register cmsUInt32Number Stride)
{ {
int nChan = T_CHANNELS(info -> InputFormat); cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
int DoSwap = T_DOSWAP(info ->InputFormat); cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat);
int Reverse = T_FLAVOR(info ->InputFormat); cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat);
int SwapFirst = T_SWAPFIRST(info -> InputFormat); cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat);
int Extra = T_EXTRA(info -> InputFormat); cmsUInt32Number Extra = T_EXTRA(info -> InputFormat);
int ExtraFirst = DoSwap ^ SwapFirst; cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
int Planar = T_PLANAR(info -> InputFormat); cmsUInt32Number Planar = T_PLANAR(info -> InputFormat);
cmsFloat32Number v; cmsFloat32Number v;
cmsUInt16Number vi; cmsUInt16Number vi;
int i, start = 0; cmsUInt32Number i, start = 0;
cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0; cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
Stride /= PixelSize(info->InputFormat);
if (ExtraFirst) if (ExtraFirst)
start = Extra; start = Extra;
for (i=0; i < nChan; i++) { for (i=0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i; cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
if (Planar) if (Planar)
v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[(i + start) * Stride]; v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[(i + start) * Stride];
...@@ -1083,24 +1124,25 @@ cmsUInt8Number* UnrollFloatsToFloat(_cmsTRANSFORM* info, ...@@ -1083,24 +1124,25 @@ cmsUInt8Number* UnrollFloatsToFloat(_cmsTRANSFORM* info,
cmsUInt32Number Stride) cmsUInt32Number Stride)
{ {
int nChan = T_CHANNELS(info -> InputFormat); cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
int DoSwap = T_DOSWAP(info ->InputFormat); cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat);
int Reverse = T_FLAVOR(info ->InputFormat); cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat);
int SwapFirst = T_SWAPFIRST(info -> InputFormat); cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat);
int Extra = T_EXTRA(info -> InputFormat); cmsUInt32Number Extra = T_EXTRA(info -> InputFormat);
int ExtraFirst = DoSwap ^ SwapFirst; cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
int Planar = T_PLANAR(info -> InputFormat); cmsUInt32Number Planar = T_PLANAR(info -> InputFormat);
cmsFloat32Number v; cmsFloat32Number v;
int i, start = 0; cmsUInt32Number i, start = 0;
cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 100.0F : 1.0F; cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 100.0F : 1.0F;
Stride /= PixelSize(info->InputFormat);
if (ExtraFirst) if (ExtraFirst)
start = Extra; start = Extra;
for (i=0; i < nChan; i++) { for (i=0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i; cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
if (Planar) if (Planar)
v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[(i + start) * Stride]; v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[(i + start) * Stride];
...@@ -1135,24 +1177,25 @@ cmsUInt8Number* UnrollDoublesToFloat(_cmsTRANSFORM* info, ...@@ -1135,24 +1177,25 @@ cmsUInt8Number* UnrollDoublesToFloat(_cmsTRANSFORM* info,
cmsUInt32Number Stride) cmsUInt32Number Stride)
{ {
int nChan = T_CHANNELS(info -> InputFormat); cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
int DoSwap = T_DOSWAP(info ->InputFormat); cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat);
int Reverse = T_FLAVOR(info ->InputFormat); cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat);
int SwapFirst = T_SWAPFIRST(info -> InputFormat); cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat);
int Extra = T_EXTRA(info -> InputFormat); cmsUInt32Number Extra = T_EXTRA(info -> InputFormat);
int ExtraFirst = DoSwap ^ SwapFirst; cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
int Planar = T_PLANAR(info -> InputFormat); cmsUInt32Number Planar = T_PLANAR(info -> InputFormat);
cmsFloat64Number v; cmsFloat64Number v;
int i, start = 0; cmsUInt32Number i, start = 0;
cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 100.0 : 1.0; cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 100.0 : 1.0;
Stride /= PixelSize(info->InputFormat);
if (ExtraFirst) if (ExtraFirst)
start = Extra; start = Extra;
for (i=0; i < nChan; i++) { for (i=0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i; cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
if (Planar) if (Planar)
v = (cmsFloat64Number) ((cmsFloat64Number*) accum)[(i + start) * Stride]; v = (cmsFloat64Number) ((cmsFloat64Number*) accum)[(i + start) * Stride];
...@@ -1191,7 +1234,9 @@ cmsUInt8Number* UnrollLabDoubleToFloat(_cmsTRANSFORM* info, ...@@ -1191,7 +1234,9 @@ cmsUInt8Number* UnrollLabDoubleToFloat(_cmsTRANSFORM* info,
if (T_PLANAR(info -> InputFormat)) { if (T_PLANAR(info -> InputFormat)) {
wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1 Stride /= PixelSize(info->InputFormat);
wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
wIn[1] = (cmsFloat32Number) ((Pt[Stride] + 128) / 255.0); // form -128..+127 to 0..1 wIn[1] = (cmsFloat32Number) ((Pt[Stride] + 128) / 255.0); // form -128..+127 to 0..1
wIn[2] = (cmsFloat32Number) ((Pt[Stride*2] + 128) / 255.0); wIn[2] = (cmsFloat32Number) ((Pt[Stride*2] + 128) / 255.0);
...@@ -1219,6 +1264,8 @@ cmsUInt8Number* UnrollLabFloatToFloat(_cmsTRANSFORM* info, ...@@ -1219,6 +1264,8 @@ cmsUInt8Number* UnrollLabFloatToFloat(_cmsTRANSFORM* info,
if (T_PLANAR(info -> InputFormat)) { if (T_PLANAR(info -> InputFormat)) {
Stride /= PixelSize(info->InputFormat);
wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1 wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
wIn[1] = (cmsFloat32Number) ((Pt[Stride] + 128) / 255.0); // form -128..+127 to 0..1 wIn[1] = (cmsFloat32Number) ((Pt[Stride] + 128) / 255.0); // form -128..+127 to 0..1
wIn[2] = (cmsFloat32Number) ((Pt[Stride*2] + 128) / 255.0); wIn[2] = (cmsFloat32Number) ((Pt[Stride*2] + 128) / 255.0);
...@@ -1249,6 +1296,8 @@ cmsUInt8Number* UnrollXYZDoubleToFloat(_cmsTRANSFORM* info, ...@@ -1249,6 +1296,8 @@ cmsUInt8Number* UnrollXYZDoubleToFloat(_cmsTRANSFORM* info,
if (T_PLANAR(info -> InputFormat)) { if (T_PLANAR(info -> InputFormat)) {
Stride /= PixelSize(info->InputFormat);
wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ); wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
wIn[1] = (cmsFloat32Number) (Pt[Stride] / MAX_ENCODEABLE_XYZ); wIn[1] = (cmsFloat32Number) (Pt[Stride] / MAX_ENCODEABLE_XYZ);
wIn[2] = (cmsFloat32Number) (Pt[Stride*2] / MAX_ENCODEABLE_XYZ); wIn[2] = (cmsFloat32Number) (Pt[Stride*2] / MAX_ENCODEABLE_XYZ);
...@@ -1276,6 +1325,8 @@ cmsUInt8Number* UnrollXYZFloatToFloat(_cmsTRANSFORM* info, ...@@ -1276,6 +1325,8 @@ cmsUInt8Number* UnrollXYZFloatToFloat(_cmsTRANSFORM* info,
if (T_PLANAR(info -> InputFormat)) { if (T_PLANAR(info -> InputFormat)) {
Stride /= PixelSize(info->InputFormat);
wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ); wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
wIn[1] = (cmsFloat32Number) (Pt[Stride] / MAX_ENCODEABLE_XYZ); wIn[1] = (cmsFloat32Number) (Pt[Stride] / MAX_ENCODEABLE_XYZ);
wIn[2] = (cmsFloat32Number) (Pt[Stride*2] / MAX_ENCODEABLE_XYZ); wIn[2] = (cmsFloat32Number) (Pt[Stride*2] / MAX_ENCODEABLE_XYZ);
...@@ -1306,15 +1357,15 @@ cmsUInt8Number* PackAnyBytes(register _cmsTRANSFORM* info, ...@@ -1306,15 +1357,15 @@ cmsUInt8Number* PackAnyBytes(register _cmsTRANSFORM* info,
register cmsUInt8Number* output, register cmsUInt8Number* output,
register cmsUInt32Number Stride) register cmsUInt32Number Stride)
{ {
int nChan = T_CHANNELS(info -> OutputFormat); cmsUInt32Number nChan = T_CHANNELS(info -> OutputFormat);
int DoSwap = T_DOSWAP(info ->OutputFormat); cmsUInt32Number DoSwap = T_DOSWAP(info ->OutputFormat);
int Reverse = T_FLAVOR(info ->OutputFormat); cmsUInt32Number Reverse = T_FLAVOR(info ->OutputFormat);
int Extra = T_EXTRA(info -> OutputFormat); cmsUInt32Number Extra = T_EXTRA(info -> OutputFormat);
int SwapFirst = T_SWAPFIRST(info -> OutputFormat); cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> OutputFormat);
int ExtraFirst = DoSwap ^ SwapFirst; cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsUInt8Number* swap1; cmsUInt8Number* swap1;
cmsUInt8Number v = 0; cmsUInt8Number v = 0;
int i; cmsUInt32Number i;
swap1 = output; swap1 = output;
...@@ -1324,7 +1375,7 @@ cmsUInt8Number* PackAnyBytes(register _cmsTRANSFORM* info, ...@@ -1324,7 +1375,7 @@ cmsUInt8Number* PackAnyBytes(register _cmsTRANSFORM* info,
for (i=0; i < nChan; i++) { for (i=0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i; cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
v = FROM_16_TO_8(wOut[index]); v = FROM_16_TO_8(wOut[index]);
...@@ -1358,16 +1409,16 @@ cmsUInt8Number* PackAnyWords(register _cmsTRANSFORM* info, ...@@ -1358,16 +1409,16 @@ cmsUInt8Number* PackAnyWords(register _cmsTRANSFORM* info,
register cmsUInt8Number* output, register cmsUInt8Number* output,
register cmsUInt32Number Stride) register cmsUInt32Number Stride)
{ {
int nChan = T_CHANNELS(info -> OutputFormat); cmsUInt32Number nChan = T_CHANNELS(info -> OutputFormat);
int SwapEndian = T_ENDIAN16(info -> InputFormat); cmsUInt32Number SwapEndian = T_ENDIAN16(info -> OutputFormat);
int DoSwap = T_DOSWAP(info ->OutputFormat); cmsUInt32Number DoSwap = T_DOSWAP(info ->OutputFormat);
int Reverse = T_FLAVOR(info ->OutputFormat); cmsUInt32Number Reverse = T_FLAVOR(info ->OutputFormat);
int Extra = T_EXTRA(info -> OutputFormat); cmsUInt32Number Extra = T_EXTRA(info -> OutputFormat);
int SwapFirst = T_SWAPFIRST(info -> OutputFormat); cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> OutputFormat);
int ExtraFirst = DoSwap ^ SwapFirst; cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsUInt16Number* swap1; cmsUInt16Number* swap1;
cmsUInt16Number v = 0; cmsUInt16Number v = 0;
int i; cmsUInt32Number i;
swap1 = (cmsUInt16Number*) output; swap1 = (cmsUInt16Number*) output;
...@@ -1377,7 +1428,7 @@ cmsUInt8Number* PackAnyWords(register _cmsTRANSFORM* info, ...@@ -1377,7 +1428,7 @@ cmsUInt8Number* PackAnyWords(register _cmsTRANSFORM* info,
for (i=0; i < nChan; i++) { for (i=0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i; cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
v = wOut[index]; v = wOut[index];
...@@ -1415,11 +1466,11 @@ cmsUInt8Number* PackPlanarBytes(register _cmsTRANSFORM* info, ...@@ -1415,11 +1466,11 @@ cmsUInt8Number* PackPlanarBytes(register _cmsTRANSFORM* info,
register cmsUInt8Number* output, register cmsUInt8Number* output,
register cmsUInt32Number Stride) register cmsUInt32Number Stride)
{ {
int nChan = T_CHANNELS(info -> OutputFormat); cmsUInt32Number nChan = T_CHANNELS(info -> OutputFormat);
int DoSwap = T_DOSWAP(info ->OutputFormat); cmsUInt32Number DoSwap = T_DOSWAP(info ->OutputFormat);
int SwapFirst = T_SWAPFIRST(info ->OutputFormat); cmsUInt32Number SwapFirst = T_SWAPFIRST(info ->OutputFormat);
int Reverse = T_FLAVOR(info ->OutputFormat); cmsUInt32Number Reverse = T_FLAVOR(info ->OutputFormat);
int i; cmsUInt32Number i;
cmsUInt8Number* Init = output; cmsUInt8Number* Init = output;
...@@ -1430,7 +1481,7 @@ cmsUInt8Number* PackPlanarBytes(register _cmsTRANSFORM* info, ...@@ -1430,7 +1481,7 @@ cmsUInt8Number* PackPlanarBytes(register _cmsTRANSFORM* info,
for (i=0; i < nChan; i++) { for (i=0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i; cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
cmsUInt8Number v = FROM_16_TO_8(wOut[index]); cmsUInt8Number v = FROM_16_TO_8(wOut[index]);
*(cmsUInt8Number*) output = (cmsUInt8Number) (Reverse ? REVERSE_FLAVOR_8(v) : v); *(cmsUInt8Number*) output = (cmsUInt8Number) (Reverse ? REVERSE_FLAVOR_8(v) : v);
...@@ -1449,21 +1500,21 @@ cmsUInt8Number* PackPlanarWords(register _cmsTRANSFORM* info, ...@@ -1449,21 +1500,21 @@ cmsUInt8Number* PackPlanarWords(register _cmsTRANSFORM* info,
register cmsUInt8Number* output, register cmsUInt8Number* output,
register cmsUInt32Number Stride) register cmsUInt32Number Stride)
{ {
int nChan = T_CHANNELS(info -> OutputFormat); cmsUInt32Number nChan = T_CHANNELS(info -> OutputFormat);
int DoSwap = T_DOSWAP(info ->OutputFormat); cmsUInt32Number DoSwap = T_DOSWAP(info ->OutputFormat);
int Reverse= T_FLAVOR(info ->OutputFormat); cmsUInt32Number Reverse = T_FLAVOR(info ->OutputFormat);
int SwapEndian = T_ENDIAN16(info -> OutputFormat); cmsUInt32Number SwapEndian = T_ENDIAN16(info -> OutputFormat);
int i; cmsUInt32Number i;
cmsUInt8Number* Init = output; cmsUInt8Number* Init = output;
cmsUInt16Number v; cmsUInt16Number v;
if (DoSwap) { if (DoSwap) {
output += T_EXTRA(info -> OutputFormat) * Stride * sizeof(cmsUInt16Number); output += T_EXTRA(info -> OutputFormat) * Stride;
} }
for (i=0; i < nChan; i++) { for (i=0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i; cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
v = wOut[index]; v = wOut[index];
...@@ -1474,7 +1525,7 @@ cmsUInt8Number* PackPlanarWords(register _cmsTRANSFORM* info, ...@@ -1474,7 +1525,7 @@ cmsUInt8Number* PackPlanarWords(register _cmsTRANSFORM* info,
v = REVERSE_FLAVOR_16(v); v = REVERSE_FLAVOR_16(v);
*(cmsUInt16Number*) output = v; *(cmsUInt16Number*) output = v;
output += (Stride * sizeof(cmsUInt16Number)); output += Stride;
} }
return (Init + sizeof(cmsUInt16Number)); return (Init + sizeof(cmsUInt16Number));
...@@ -1823,9 +1874,9 @@ cmsUInt8Number* Pack3BytesOptimized(register _cmsTRANSFORM* info, ...@@ -1823,9 +1874,9 @@ cmsUInt8Number* Pack3BytesOptimized(register _cmsTRANSFORM* info,
register cmsUInt8Number* output, register cmsUInt8Number* output,
register cmsUInt32Number Stride) register cmsUInt32Number Stride)
{ {
*output++ = (wOut[0] & 0xFF); *output++ = (wOut[0] & 0xFFU);
*output++ = (wOut[1] & 0xFF); *output++ = (wOut[1] & 0xFFU);
*output++ = (wOut[2] & 0xFF); *output++ = (wOut[2] & 0xFFU);
return output; return output;
...@@ -1855,9 +1906,9 @@ cmsUInt8Number* Pack3BytesSwapOptimized(register _cmsTRANSFORM* info, ...@@ -1855,9 +1906,9 @@ cmsUInt8Number* Pack3BytesSwapOptimized(register _cmsTRANSFORM* info,
register cmsUInt8Number* output, register cmsUInt8Number* output,
register cmsUInt32Number Stride) register cmsUInt32Number Stride)
{ {
*output++ = (wOut[2] & 0xFF); *output++ = (wOut[2] & 0xFFU);
*output++ = (wOut[1] & 0xFF); *output++ = (wOut[1] & 0xFFU);
*output++ = (wOut[0] & 0xFF); *output++ = (wOut[0] & 0xFFU);
return output; return output;
...@@ -1946,9 +1997,9 @@ cmsUInt8Number* Pack3BytesAndSkip1Optimized(register _cmsTRANSFORM* info, ...@@ -1946,9 +1997,9 @@ cmsUInt8Number* Pack3BytesAndSkip1Optimized(register _cmsTRANSFORM* info,
register cmsUInt8Number* output, register cmsUInt8Number* output,
register cmsUInt32Number Stride) register cmsUInt32Number Stride)
{ {
*output++ = (wOut[0] & 0xFF); *output++ = (wOut[0] & 0xFFU);
*output++ = (wOut[1] & 0xFF); *output++ = (wOut[1] & 0xFFU);
*output++ = (wOut[2] & 0xFF); *output++ = (wOut[2] & 0xFFU);
output++; output++;
return output; return output;
...@@ -1982,9 +2033,9 @@ cmsUInt8Number* Pack3BytesAndSkip1SwapFirstOptimized(register _cmsTRANSFORM* inf ...@@ -1982,9 +2033,9 @@ cmsUInt8Number* Pack3BytesAndSkip1SwapFirstOptimized(register _cmsTRANSFORM* inf
register cmsUInt32Number Stride) register cmsUInt32Number Stride)
{ {
output++; output++;
*output++ = (wOut[0] & 0xFF); *output++ = (wOut[0] & 0xFFU);
*output++ = (wOut[1] & 0xFF); *output++ = (wOut[1] & 0xFFU);
*output++ = (wOut[2] & 0xFF); *output++ = (wOut[2] & 0xFFU);
return output; return output;
...@@ -2016,9 +2067,9 @@ cmsUInt8Number* Pack3BytesAndSkip1SwapOptimized(register _cmsTRANSFORM* info, ...@@ -2016,9 +2067,9 @@ cmsUInt8Number* Pack3BytesAndSkip1SwapOptimized(register _cmsTRANSFORM* info,
register cmsUInt32Number Stride) register cmsUInt32Number Stride)
{ {
output++; output++;
*output++ = (wOut[2] & 0xFF); *output++ = (wOut[2] & 0xFFU);
*output++ = (wOut[1] & 0xFF); *output++ = (wOut[1] & 0xFFU);
*output++ = (wOut[0] & 0xFF); *output++ = (wOut[0] & 0xFFU);
return output; return output;
...@@ -2050,9 +2101,9 @@ cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirstOptimized(register _cmsTRANSFORM* ...@@ -2050,9 +2101,9 @@ cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirstOptimized(register _cmsTRANSFORM*
register cmsUInt8Number* output, register cmsUInt8Number* output,
register cmsUInt32Number Stride) register cmsUInt32Number Stride)
{ {
*output++ = (wOut[2] & 0xFF); *output++ = (wOut[2] & 0xFFU);
*output++ = (wOut[1] & 0xFF); *output++ = (wOut[1] & 0xFFU);
*output++ = (wOut[0] & 0xFF); *output++ = (wOut[0] & 0xFFU);
output++; output++;
return output; return output;
...@@ -2326,6 +2377,8 @@ cmsUInt8Number* PackLabFloatFrom16(register _cmsTRANSFORM* info, ...@@ -2326,6 +2377,8 @@ cmsUInt8Number* PackLabFloatFrom16(register _cmsTRANSFORM* info,
cmsFloat32Number* Out = (cmsFloat32Number*) output; cmsFloat32Number* Out = (cmsFloat32Number*) output;
Stride /= PixelSize(info->OutputFormat);
Out[0] = (cmsFloat32Number)Lab.L; Out[0] = (cmsFloat32Number)Lab.L;
Out[Stride] = (cmsFloat32Number)Lab.a; Out[Stride] = (cmsFloat32Number)Lab.a;
Out[Stride*2] = (cmsFloat32Number)Lab.b; Out[Stride*2] = (cmsFloat32Number)Lab.b;
...@@ -2354,6 +2407,8 @@ cmsUInt8Number* PackXYZDoubleFrom16(register _cmsTRANSFORM* Info, ...@@ -2354,6 +2407,8 @@ cmsUInt8Number* PackXYZDoubleFrom16(register _cmsTRANSFORM* Info,
cmsFloat64Number* Out = (cmsFloat64Number*) output; cmsFloat64Number* Out = (cmsFloat64Number*) output;
cmsXYZEncoded2Float(&XYZ, wOut); cmsXYZEncoded2Float(&XYZ, wOut);
Stride /= PixelSize(Info->OutputFormat);
Out[0] = XYZ.X; Out[0] = XYZ.X;
Out[Stride] = XYZ.Y; Out[Stride] = XYZ.Y;
Out[Stride*2] = XYZ.Z; Out[Stride*2] = XYZ.Z;
...@@ -2381,6 +2436,8 @@ cmsUInt8Number* PackXYZFloatFrom16(register _cmsTRANSFORM* Info, ...@@ -2381,6 +2436,8 @@ cmsUInt8Number* PackXYZFloatFrom16(register _cmsTRANSFORM* Info,
cmsFloat32Number* Out = (cmsFloat32Number*) output; cmsFloat32Number* Out = (cmsFloat32Number*) output;
cmsXYZEncoded2Float(&XYZ, wOut); cmsXYZEncoded2Float(&XYZ, wOut);
Stride /= PixelSize(Info->OutputFormat);
Out[0] = (cmsFloat32Number) XYZ.X; Out[0] = (cmsFloat32Number) XYZ.X;
Out[Stride] = (cmsFloat32Number) XYZ.Y; Out[Stride] = (cmsFloat32Number) XYZ.Y;
Out[Stride*2] = (cmsFloat32Number) XYZ.Z; Out[Stride*2] = (cmsFloat32Number) XYZ.Z;
...@@ -2408,24 +2465,26 @@ cmsUInt8Number* PackDoubleFrom16(register _cmsTRANSFORM* info, ...@@ -2408,24 +2465,26 @@ cmsUInt8Number* PackDoubleFrom16(register _cmsTRANSFORM* info,
register cmsUInt8Number* output, register cmsUInt8Number* output,
register cmsUInt32Number Stride) register cmsUInt32Number Stride)
{ {
int nChan = T_CHANNELS(info -> OutputFormat); cmsUInt32Number nChan = T_CHANNELS(info -> OutputFormat);
int DoSwap = T_DOSWAP(info ->OutputFormat); cmsUInt32Number DoSwap = T_DOSWAP(info ->OutputFormat);
int Reverse = T_FLAVOR(info ->OutputFormat); cmsUInt32Number Reverse = T_FLAVOR(info ->OutputFormat);
int Extra = T_EXTRA(info -> OutputFormat); cmsUInt32Number Extra = T_EXTRA(info -> OutputFormat);
int SwapFirst = T_SWAPFIRST(info -> OutputFormat); cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> OutputFormat);
int Planar = T_PLANAR(info -> OutputFormat); cmsUInt32Number Planar = T_PLANAR(info -> OutputFormat);
int ExtraFirst = DoSwap ^ SwapFirst; cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35 : 65535.0; cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35 : 65535.0;
cmsFloat64Number v = 0; cmsFloat64Number v = 0;
cmsFloat64Number* swap1 = (cmsFloat64Number*) output; cmsFloat64Number* swap1 = (cmsFloat64Number*) output;
int i, start = 0; cmsUInt32Number i, start = 0;
Stride /= PixelSize(info->OutputFormat);
if (ExtraFirst) if (ExtraFirst)
start = Extra; start = Extra;
for (i=0; i < nChan; i++) { for (i=0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i; cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
v = (cmsFloat64Number) wOut[index] / maximum; v = (cmsFloat64Number) wOut[index] / maximum;
...@@ -2459,24 +2518,26 @@ cmsUInt8Number* PackFloatFrom16(register _cmsTRANSFORM* info, ...@@ -2459,24 +2518,26 @@ cmsUInt8Number* PackFloatFrom16(register _cmsTRANSFORM* info,
register cmsUInt8Number* output, register cmsUInt8Number* output,
register cmsUInt32Number Stride) register cmsUInt32Number Stride)
{ {
int nChan = T_CHANNELS(info->OutputFormat); cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat);
int DoSwap = T_DOSWAP(info->OutputFormat); cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat);
int Reverse = T_FLAVOR(info->OutputFormat); cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat);
int Extra = T_EXTRA(info->OutputFormat); cmsUInt32Number Extra = T_EXTRA(info->OutputFormat);
int SwapFirst = T_SWAPFIRST(info->OutputFormat); cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat);
int Planar = T_PLANAR(info->OutputFormat); cmsUInt32Number Planar = T_PLANAR(info->OutputFormat);
int ExtraFirst = DoSwap ^ SwapFirst; cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 655.35 : 65535.0; cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 655.35 : 65535.0;
cmsFloat64Number v = 0; cmsFloat64Number v = 0;
cmsFloat32Number* swap1 = (cmsFloat32Number*)output; cmsFloat32Number* swap1 = (cmsFloat32Number*)output;
int i, start = 0; cmsUInt32Number i, start = 0;
Stride /= PixelSize(info->OutputFormat);
if (ExtraFirst) if (ExtraFirst)
start = Extra; start = Extra;
for (i = 0; i < nChan; i++) { for (i = 0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i; cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
v = (cmsFloat64Number)wOut[index] / maximum; v = (cmsFloat64Number)wOut[index] / maximum;
...@@ -2512,24 +2573,26 @@ cmsUInt8Number* PackFloatsFromFloat(_cmsTRANSFORM* info, ...@@ -2512,24 +2573,26 @@ cmsUInt8Number* PackFloatsFromFloat(_cmsTRANSFORM* info,
cmsUInt8Number* output, cmsUInt8Number* output,
cmsUInt32Number Stride) cmsUInt32Number Stride)
{ {
int nChan = T_CHANNELS(info->OutputFormat); cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat);
int DoSwap = T_DOSWAP(info->OutputFormat); cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat);
int Reverse = T_FLAVOR(info->OutputFormat); cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat);
int Extra = T_EXTRA(info->OutputFormat); cmsUInt32Number Extra = T_EXTRA(info->OutputFormat);
int SwapFirst = T_SWAPFIRST(info->OutputFormat); cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat);
int Planar = T_PLANAR(info->OutputFormat); cmsUInt32Number Planar = T_PLANAR(info->OutputFormat);
int ExtraFirst = DoSwap ^ SwapFirst; cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 100.0 : 1.0; cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 100.0 : 1.0;
cmsFloat32Number* swap1 = (cmsFloat32Number*)output; cmsFloat32Number* swap1 = (cmsFloat32Number*)output;
cmsFloat64Number v = 0; cmsFloat64Number v = 0;
int i, start = 0; cmsUInt32Number i, start = 0;
Stride /= PixelSize(info->OutputFormat);
if (ExtraFirst) if (ExtraFirst)
start = Extra; start = Extra;
for (i = 0; i < nChan; i++) { for (i = 0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i; cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
v = wOut[index] * maximum; v = wOut[index] * maximum;
...@@ -2561,24 +2624,26 @@ cmsUInt8Number* PackDoublesFromFloat(_cmsTRANSFORM* info, ...@@ -2561,24 +2624,26 @@ cmsUInt8Number* PackDoublesFromFloat(_cmsTRANSFORM* info,
cmsUInt8Number* output, cmsUInt8Number* output,
cmsUInt32Number Stride) cmsUInt32Number Stride)
{ {
int nChan = T_CHANNELS(info->OutputFormat); cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat);
int DoSwap = T_DOSWAP(info->OutputFormat); cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat);
int Reverse = T_FLAVOR(info->OutputFormat); cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat);
int Extra = T_EXTRA(info->OutputFormat); cmsUInt32Number Extra = T_EXTRA(info->OutputFormat);
int SwapFirst = T_SWAPFIRST(info->OutputFormat); cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat);
int Planar = T_PLANAR(info->OutputFormat); cmsUInt32Number Planar = T_PLANAR(info->OutputFormat);
int ExtraFirst = DoSwap ^ SwapFirst; cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 100.0 : 1.0; cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 100.0 : 1.0;
cmsFloat64Number v = 0; cmsFloat64Number v = 0;
cmsFloat64Number* swap1 = (cmsFloat64Number*)output; cmsFloat64Number* swap1 = (cmsFloat64Number*)output;
int i, start = 0; cmsUInt32Number i, start = 0;
Stride /= PixelSize(info->OutputFormat);
if (ExtraFirst) if (ExtraFirst)
start = Extra; start = Extra;
for (i = 0; i < nChan; i++) { for (i = 0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i; cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
v = wOut[index] * maximum; v = wOut[index] * maximum;
...@@ -2619,6 +2684,8 @@ cmsUInt8Number* PackLabFloatFromFloat(_cmsTRANSFORM* Info, ...@@ -2619,6 +2684,8 @@ cmsUInt8Number* PackLabFloatFromFloat(_cmsTRANSFORM* Info,
if (T_PLANAR(Info -> OutputFormat)) { if (T_PLANAR(Info -> OutputFormat)) {
Stride /= PixelSize(Info->OutputFormat);
Out[0] = (cmsFloat32Number) (wOut[0] * 100.0); Out[0] = (cmsFloat32Number) (wOut[0] * 100.0);
Out[Stride] = (cmsFloat32Number) (wOut[1] * 255.0 - 128.0); Out[Stride] = (cmsFloat32Number) (wOut[1] * 255.0 - 128.0);
Out[Stride*2] = (cmsFloat32Number) (wOut[2] * 255.0 - 128.0); Out[Stride*2] = (cmsFloat32Number) (wOut[2] * 255.0 - 128.0);
...@@ -2647,6 +2714,8 @@ cmsUInt8Number* PackLabDoubleFromFloat(_cmsTRANSFORM* Info, ...@@ -2647,6 +2714,8 @@ cmsUInt8Number* PackLabDoubleFromFloat(_cmsTRANSFORM* Info,
if (T_PLANAR(Info -> OutputFormat)) { if (T_PLANAR(Info -> OutputFormat)) {
Stride /= PixelSize(Info->OutputFormat);
Out[0] = (cmsFloat64Number) (wOut[0] * 100.0); Out[0] = (cmsFloat64Number) (wOut[0] * 100.0);
Out[Stride] = (cmsFloat64Number) (wOut[1] * 255.0 - 128.0); Out[Stride] = (cmsFloat64Number) (wOut[1] * 255.0 - 128.0);
Out[Stride*2] = (cmsFloat64Number) (wOut[2] * 255.0 - 128.0); Out[Stride*2] = (cmsFloat64Number) (wOut[2] * 255.0 - 128.0);
...@@ -2676,6 +2745,8 @@ cmsUInt8Number* PackXYZFloatFromFloat(_cmsTRANSFORM* Info, ...@@ -2676,6 +2745,8 @@ cmsUInt8Number* PackXYZFloatFromFloat(_cmsTRANSFORM* Info,
if (T_PLANAR(Info -> OutputFormat)) { if (T_PLANAR(Info -> OutputFormat)) {
Stride /= PixelSize(Info->OutputFormat);
Out[0] = (cmsFloat32Number) (wOut[0] * MAX_ENCODEABLE_XYZ); Out[0] = (cmsFloat32Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
Out[Stride] = (cmsFloat32Number) (wOut[1] * MAX_ENCODEABLE_XYZ); Out[Stride] = (cmsFloat32Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
Out[Stride*2] = (cmsFloat32Number) (wOut[2] * MAX_ENCODEABLE_XYZ); Out[Stride*2] = (cmsFloat32Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
...@@ -2704,6 +2775,8 @@ cmsUInt8Number* PackXYZDoubleFromFloat(_cmsTRANSFORM* Info, ...@@ -2704,6 +2775,8 @@ cmsUInt8Number* PackXYZDoubleFromFloat(_cmsTRANSFORM* Info,
if (T_PLANAR(Info -> OutputFormat)) { if (T_PLANAR(Info -> OutputFormat)) {
Stride /= PixelSize(Info->OutputFormat);
Out[0] = (cmsFloat64Number) (wOut[0] * MAX_ENCODEABLE_XYZ); Out[0] = (cmsFloat64Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
Out[Stride] = (cmsFloat64Number) (wOut[1] * MAX_ENCODEABLE_XYZ); Out[Stride] = (cmsFloat64Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
Out[Stride*2] = (cmsFloat64Number) (wOut[2] * MAX_ENCODEABLE_XYZ); Out[Stride*2] = (cmsFloat64Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
...@@ -2735,24 +2808,26 @@ cmsUInt8Number* UnrollHalfTo16(register _cmsTRANSFORM* info, ...@@ -2735,24 +2808,26 @@ cmsUInt8Number* UnrollHalfTo16(register _cmsTRANSFORM* info,
register cmsUInt32Number Stride) register cmsUInt32Number Stride)
{ {
int nChan = T_CHANNELS(info -> InputFormat); cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
int DoSwap = T_DOSWAP(info ->InputFormat); cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat);
int Reverse = T_FLAVOR(info ->InputFormat); cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat);
int SwapFirst = T_SWAPFIRST(info -> InputFormat); cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat);
int Extra = T_EXTRA(info -> InputFormat); cmsUInt32Number Extra = T_EXTRA(info -> InputFormat);
int ExtraFirst = DoSwap ^ SwapFirst; cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
int Planar = T_PLANAR(info -> InputFormat); cmsUInt32Number Planar = T_PLANAR(info -> InputFormat);
cmsFloat32Number v; cmsFloat32Number v;
int i, start = 0; cmsUInt32Number i, start = 0;
cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 655.35F : 65535.0F; cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 655.35F : 65535.0F;
Stride /= PixelSize(info->OutputFormat);
if (ExtraFirst) if (ExtraFirst)
start = Extra; start = Extra;
for (i=0; i < nChan; i++) { for (i=0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i; cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
if (Planar) if (Planar)
v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[(i + start) * Stride] ); v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[(i + start) * Stride] );
...@@ -2787,24 +2862,25 @@ cmsUInt8Number* UnrollHalfToFloat(_cmsTRANSFORM* info, ...@@ -2787,24 +2862,25 @@ cmsUInt8Number* UnrollHalfToFloat(_cmsTRANSFORM* info,
cmsUInt32Number Stride) cmsUInt32Number Stride)
{ {
int nChan = T_CHANNELS(info -> InputFormat); cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
int DoSwap = T_DOSWAP(info ->InputFormat); cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat);
int Reverse = T_FLAVOR(info ->InputFormat); cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat);
int SwapFirst = T_SWAPFIRST(info -> InputFormat); cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat);
int Extra = T_EXTRA(info -> InputFormat); cmsUInt32Number Extra = T_EXTRA(info -> InputFormat);
int ExtraFirst = DoSwap ^ SwapFirst; cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
int Planar = T_PLANAR(info -> InputFormat); cmsUInt32Number Planar = T_PLANAR(info -> InputFormat);
cmsFloat32Number v; cmsFloat32Number v;
int i, start = 0; cmsUInt32Number i, start = 0;
cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 100.0F : 1.0F; cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 100.0F : 1.0F;
Stride /= PixelSize(info->OutputFormat);
if (ExtraFirst) if (ExtraFirst)
start = Extra; start = Extra;
for (i=0; i < nChan; i++) { for (i=0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i; cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
if (Planar) if (Planar)
v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[(i + start) * Stride] ); v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[(i + start) * Stride] );
...@@ -2837,24 +2913,26 @@ cmsUInt8Number* PackHalfFrom16(register _cmsTRANSFORM* info, ...@@ -2837,24 +2913,26 @@ cmsUInt8Number* PackHalfFrom16(register _cmsTRANSFORM* info,
register cmsUInt8Number* output, register cmsUInt8Number* output,
register cmsUInt32Number Stride) register cmsUInt32Number Stride)
{ {
int nChan = T_CHANNELS(info->OutputFormat); cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat);
int DoSwap = T_DOSWAP(info->OutputFormat); cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat);
int Reverse = T_FLAVOR(info->OutputFormat); cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat);
int Extra = T_EXTRA(info->OutputFormat); cmsUInt32Number Extra = T_EXTRA(info->OutputFormat);
int SwapFirst = T_SWAPFIRST(info->OutputFormat); cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat);
int Planar = T_PLANAR(info->OutputFormat); cmsUInt32Number Planar = T_PLANAR(info->OutputFormat);
int ExtraFirst = DoSwap ^ SwapFirst; cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsFloat32Number maximum = IsInkSpace(info->OutputFormat) ? 655.35F : 65535.0F; cmsFloat32Number maximum = IsInkSpace(info->OutputFormat) ? 655.35F : 65535.0F;
cmsFloat32Number v = 0; cmsFloat32Number v = 0;
cmsUInt16Number* swap1 = (cmsUInt16Number*)output; cmsUInt16Number* swap1 = (cmsUInt16Number*)output;
int i, start = 0; cmsUInt32Number i, start = 0;
Stride /= PixelSize(info->OutputFormat);
if (ExtraFirst) if (ExtraFirst)
start = Extra; start = Extra;
for (i = 0; i < nChan; i++) { for (i = 0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i; cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
v = (cmsFloat32Number)wOut[index] / maximum; v = (cmsFloat32Number)wOut[index] / maximum;
...@@ -2888,24 +2966,26 @@ cmsUInt8Number* PackHalfFromFloat(_cmsTRANSFORM* info, ...@@ -2888,24 +2966,26 @@ cmsUInt8Number* PackHalfFromFloat(_cmsTRANSFORM* info,
cmsUInt8Number* output, cmsUInt8Number* output,
cmsUInt32Number Stride) cmsUInt32Number Stride)
{ {
int nChan = T_CHANNELS(info->OutputFormat); cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat);
int DoSwap = T_DOSWAP(info->OutputFormat); cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat);
int Reverse = T_FLAVOR(info->OutputFormat); cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat);
int Extra = T_EXTRA(info->OutputFormat); cmsUInt32Number Extra = T_EXTRA(info->OutputFormat);
int SwapFirst = T_SWAPFIRST(info->OutputFormat); cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat);
int Planar = T_PLANAR(info->OutputFormat); cmsUInt32Number Planar = T_PLANAR(info->OutputFormat);
int ExtraFirst = DoSwap ^ SwapFirst; cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsFloat32Number maximum = IsInkSpace(info->OutputFormat) ? 100.0F : 1.0F; cmsFloat32Number maximum = IsInkSpace(info->OutputFormat) ? 100.0F : 1.0F;
cmsUInt16Number* swap1 = (cmsUInt16Number*)output; cmsUInt16Number* swap1 = (cmsUInt16Number*)output;
cmsFloat32Number v = 0; cmsFloat32Number v = 0;
int i, start = 0; cmsUInt32Number i, start = 0;
Stride /= PixelSize(info->OutputFormat);
if (ExtraFirst) if (ExtraFirst)
start = Extra; start = Extra;
for (i = 0; i < nChan; i++) { for (i = 0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i; cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
v = wOut[index] * maximum; v = wOut[index] * maximum;
...@@ -2936,7 +3016,7 @@ cmsUInt8Number* PackHalfFromFloat(_cmsTRANSFORM* info, ...@@ -2936,7 +3016,7 @@ cmsUInt8Number* PackHalfFromFloat(_cmsTRANSFORM* info,
// ---------------------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------------
static cmsFormatters16 InputFormatters16[] = { static const cmsFormatters16 InputFormatters16[] = {
// Type Mask Function // Type Mask Function
// ---------------------------- ------------------------------------ ---------------------------- // ---------------------------- ------------------------------------ ----------------------------
...@@ -3007,7 +3087,7 @@ static cmsFormatters16 InputFormatters16[] = { ...@@ -3007,7 +3087,7 @@ static cmsFormatters16 InputFormatters16[] = {
static cmsFormattersFloat InputFormattersFloat[] = { static const cmsFormattersFloat InputFormattersFloat[] = {
// Type Mask Function // Type Mask Function
// ---------------------------- ------------------------------------ ---------------------------- // ---------------------------- ------------------------------------ ----------------------------
...@@ -3040,7 +3120,7 @@ cmsFormatter _cmsGetStockInputFormatter(cmsUInt32Number dwInput, cmsUInt32Number ...@@ -3040,7 +3120,7 @@ cmsFormatter _cmsGetStockInputFormatter(cmsUInt32Number dwInput, cmsUInt32Number
case CMS_PACK_FLAGS_16BITS: { case CMS_PACK_FLAGS_16BITS: {
for (i=0; i < sizeof(InputFormatters16) / sizeof(cmsFormatters16); i++) { for (i=0; i < sizeof(InputFormatters16) / sizeof(cmsFormatters16); i++) {
cmsFormatters16* f = InputFormatters16 + i; const cmsFormatters16* f = InputFormatters16 + i;
if ((dwInput & ~f ->Mask) == f ->Type) { if ((dwInput & ~f ->Mask) == f ->Type) {
fr.Fmt16 = f ->Frm; fr.Fmt16 = f ->Frm;
...@@ -3052,7 +3132,7 @@ cmsFormatter _cmsGetStockInputFormatter(cmsUInt32Number dwInput, cmsUInt32Number ...@@ -3052,7 +3132,7 @@ cmsFormatter _cmsGetStockInputFormatter(cmsUInt32Number dwInput, cmsUInt32Number
case CMS_PACK_FLAGS_FLOAT: { case CMS_PACK_FLAGS_FLOAT: {
for (i=0; i < sizeof(InputFormattersFloat) / sizeof(cmsFormattersFloat); i++) { for (i=0; i < sizeof(InputFormattersFloat) / sizeof(cmsFormattersFloat); i++) {
cmsFormattersFloat* f = InputFormattersFloat + i; const cmsFormattersFloat* f = InputFormattersFloat + i;
if ((dwInput & ~f ->Mask) == f ->Type) { if ((dwInput & ~f ->Mask) == f ->Type) {
fr.FmtFloat = f ->Frm; fr.FmtFloat = f ->Frm;
...@@ -3070,7 +3150,7 @@ cmsFormatter _cmsGetStockInputFormatter(cmsUInt32Number dwInput, cmsUInt32Number ...@@ -3070,7 +3150,7 @@ cmsFormatter _cmsGetStockInputFormatter(cmsUInt32Number dwInput, cmsUInt32Number
return fr; return fr;
} }
static cmsFormatters16 OutputFormatters16[] = { static const cmsFormatters16 OutputFormatters16[] = {
// Type Mask Function // Type Mask Function
// ---------------------------- ------------------------------------ ---------------------------- // ---------------------------- ------------------------------------ ----------------------------
...@@ -3158,7 +3238,7 @@ static cmsFormatters16 OutputFormatters16[] = { ...@@ -3158,7 +3238,7 @@ static cmsFormatters16 OutputFormatters16[] = {
}; };
static cmsFormattersFloat OutputFormattersFloat[] = { static const cmsFormattersFloat OutputFormattersFloat[] = {
// Type Mask Function // Type Mask Function
// ---------------------------- --------------------------------------------------- ---------------------------- // ---------------------------- --------------------------------------------------- ----------------------------
{ TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, PackLabFloatFromFloat}, { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, PackLabFloatFromFloat},
...@@ -3176,8 +3256,6 @@ static cmsFormattersFloat OutputFormattersFloat[] = { ...@@ -3176,8 +3256,6 @@ static cmsFormattersFloat OutputFormattersFloat[] = {
ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackHalfFromFloat }, ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackHalfFromFloat },
#endif #endif
}; };
...@@ -3197,7 +3275,7 @@ cmsFormatter _cmsGetStockOutputFormatter(cmsUInt32Number dwInput, cmsUInt32Numbe ...@@ -3197,7 +3275,7 @@ cmsFormatter _cmsGetStockOutputFormatter(cmsUInt32Number dwInput, cmsUInt32Numbe
case CMS_PACK_FLAGS_16BITS: { case CMS_PACK_FLAGS_16BITS: {
for (i=0; i < sizeof(OutputFormatters16) / sizeof(cmsFormatters16); i++) { for (i=0; i < sizeof(OutputFormatters16) / sizeof(cmsFormatters16); i++) {
cmsFormatters16* f = OutputFormatters16 + i; const cmsFormatters16* f = OutputFormatters16 + i;
if ((dwInput & ~f ->Mask) == f ->Type) { if ((dwInput & ~f ->Mask) == f ->Type) {
fr.Fmt16 = f ->Frm; fr.Fmt16 = f ->Frm;
...@@ -3210,7 +3288,7 @@ cmsFormatter _cmsGetStockOutputFormatter(cmsUInt32Number dwInput, cmsUInt32Numbe ...@@ -3210,7 +3288,7 @@ cmsFormatter _cmsGetStockOutputFormatter(cmsUInt32Number dwInput, cmsUInt32Numbe
case CMS_PACK_FLAGS_FLOAT: { case CMS_PACK_FLAGS_FLOAT: {
for (i=0; i < sizeof(OutputFormattersFloat) / sizeof(cmsFormattersFloat); i++) { for (i=0; i < sizeof(OutputFormattersFloat) / sizeof(cmsFormattersFloat); i++) {
cmsFormattersFloat* f = OutputFormattersFloat + i; const cmsFormattersFloat* f = OutputFormattersFloat + i;
if ((dwInput & ~f ->Mask) == f ->Type) { if ((dwInput & ~f ->Mask) == f ->Type) {
fr.FmtFloat = f ->Frm; fr.FmtFloat = f ->Frm;
...@@ -3319,10 +3397,10 @@ cmsBool _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Data) ...@@ -3319,10 +3397,10 @@ cmsBool _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Data)
return TRUE; return TRUE;
} }
cmsFormatter _cmsGetFormatter(cmsContext ContextID, cmsFormatter CMSEXPORT _cmsGetFormatter(cmsContext ContextID,
cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8 cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8
cmsFormatterDirection Dir, cmsFormatterDirection Dir,
cmsUInt32Number dwFlags) cmsUInt32Number dwFlags)
{ {
_cmsFormattersPluginChunkType* ctx = ( _cmsFormattersPluginChunkType*) _cmsContextGetClientChunk(ContextID, FormattersPlugin); _cmsFormattersPluginChunkType* ctx = ( _cmsFormattersPluginChunkType*) _cmsContextGetClientChunk(ContextID, FormattersPlugin);
cmsFormattersFactoryList* f; cmsFormattersFactoryList* f;
...@@ -3350,7 +3428,7 @@ cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type) ...@@ -3350,7 +3428,7 @@ cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type)
// Return whatever given formatter refers to 8 bits // Return whatever given formatter refers to 8 bits
cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type) cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type)
{ {
int Bytes = T_BYTES(Type); cmsUInt32Number Bytes = T_BYTES(Type);
return (Bytes == 1); return (Bytes == 1);
} }
...@@ -3360,9 +3438,9 @@ cmsUInt32Number CMSEXPORT cmsFormatterForColorspaceOfProfile(cmsHPROFILE hProfil ...@@ -3360,9 +3438,9 @@ cmsUInt32Number CMSEXPORT cmsFormatterForColorspaceOfProfile(cmsHPROFILE hProfil
{ {
cmsColorSpaceSignature ColorSpace = cmsGetColorSpace(hProfile); cmsColorSpaceSignature ColorSpace = cmsGetColorSpace(hProfile);
cmsUInt32Number ColorSpaceBits = _cmsLCMScolorSpace(ColorSpace); cmsUInt32Number ColorSpaceBits = (cmsUInt32Number) _cmsLCMScolorSpace(ColorSpace);
cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace); cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace);
cmsUInt32Number Float = lIsFloat ? 1 : 0; cmsUInt32Number Float = lIsFloat ? 1U : 0;
// Create a fake formatter for result // Create a fake formatter for result
return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans); return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans);
...@@ -3372,10 +3450,11 @@ cmsUInt32Number CMSEXPORT cmsFormatterForColorspaceOfProfile(cmsHPROFILE hProfil ...@@ -3372,10 +3450,11 @@ cmsUInt32Number CMSEXPORT cmsFormatterForColorspaceOfProfile(cmsHPROFILE hProfil
cmsUInt32Number CMSEXPORT cmsFormatterForPCSOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat) cmsUInt32Number CMSEXPORT cmsFormatterForPCSOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat)
{ {
cmsColorSpaceSignature ColorSpace = cmsGetPCS(hProfile); cmsColorSpaceSignature ColorSpace = cmsGetPCS(hProfile);
int ColorSpaceBits = _cmsLCMScolorSpace(ColorSpace);
cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace); cmsUInt32Number ColorSpaceBits = (cmsUInt32Number) _cmsLCMScolorSpace(ColorSpace);
cmsUInt32Number Float = lIsFloat ? 1 : 0; cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace);
cmsUInt32Number Float = lIsFloat ? 1U : 0;
// Create a fake formatter for result // Create a fake formatter for result
return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans); return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans);
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
...@@ -685,9 +685,9 @@ cmsFloat64Number CMSEXPORT cmsCIE2000DeltaE(const cmsCIELab* Lab1, const cmsCIEL ...@@ -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 // 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. // 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? // Already specified?
if (dwFlags & 0x00FF0000) { if (dwFlags & 0x00FF0000) {
...@@ -831,7 +831,7 @@ cmsColorSpaceSignature CMSEXPORT _cmsICCcolorSpace(int OurNotation) ...@@ -831,7 +831,7 @@ cmsColorSpaceSignature CMSEXPORT _cmsICCcolorSpace(int OurNotation)
case PT_MCH14: return cmsSigMCHEData; case PT_MCH14: return cmsSigMCHEData;
case PT_MCH15: return cmsSigMCHFData; case PT_MCH15: return cmsSigMCHFData;
default: return (cmsColorSpaceSignature) (-1); default: return (cmsColorSpaceSignature) 0;
} }
} }
...@@ -898,7 +898,7 @@ int CMSEXPORT _cmsLCMScolorSpace(cmsColorSpaceSignature ProfileSpace) ...@@ -898,7 +898,7 @@ int CMSEXPORT _cmsLCMScolorSpace(cmsColorSpaceSignature ProfileSpace)
case cmsSigMCHFData: case cmsSigMCHFData:
case cmsSig15colorData:return PT_MCH15; case cmsSig15colorData:return PT_MCH15;
default: return (cmsColorSpaceSignature) (-1); default: return (cmsColorSpaceSignature) 0;
} }
} }
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
...@@ -201,14 +201,28 @@ cmsBool CMSEXPORT _cmsReadFloat32Number(cmsIOHANDLER* io, cmsFloat32Number* n) ...@@ -201,14 +201,28 @@ cmsBool CMSEXPORT _cmsReadFloat32Number(cmsIOHANDLER* io, cmsFloat32Number* n)
_cmsAssert(io != NULL); _cmsAssert(io != NULL);
if (io -> Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1) if (io->Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1)
return FALSE; return FALSE;
if (n != NULL) { if (n != NULL) {
tmp = _cmsAdjustEndianess32(tmp); 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; return TRUE;
} }
...@@ -222,7 +236,11 @@ cmsBool CMSEXPORT _cmsReadUInt64Number(cmsIOHANDLER* io, cmsUInt64Number* n) ...@@ -222,7 +236,11 @@ cmsBool CMSEXPORT _cmsReadUInt64Number(cmsIOHANDLER* io, cmsUInt64Number* n)
if (io -> Read(io, &tmp, sizeof(cmsUInt64Number), 1) != 1) if (io -> Read(io, &tmp, sizeof(cmsUInt64Number), 1) != 1)
return FALSE; return FALSE;
if (n != NULL) _cmsAdjustEndianess64(n, &tmp); if (n != NULL) {
_cmsAdjustEndianess64(n, &tmp);
}
return TRUE; return TRUE;
} }
...@@ -237,7 +255,7 @@ cmsBool CMSEXPORT _cmsRead15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number* n ...@@ -237,7 +255,7 @@ cmsBool CMSEXPORT _cmsRead15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number* n
return FALSE; return FALSE;
if (n != NULL) { if (n != NULL) {
*n = _cms15Fixed16toDouble(_cmsAdjustEndianess32(tmp)); *n = _cms15Fixed16toDouble((cmsS15Fixed16Number) _cmsAdjustEndianess32(tmp));
} }
return TRUE; return TRUE;
...@@ -254,9 +272,9 @@ cmsBool CMSEXPORT _cmsReadXYZNumber(cmsIOHANDLER* io, cmsCIEXYZ* XYZ) ...@@ -254,9 +272,9 @@ cmsBool CMSEXPORT _cmsReadXYZNumber(cmsIOHANDLER* io, cmsCIEXYZ* XYZ)
if (XYZ != NULL) { if (XYZ != NULL) {
XYZ->X = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.X)); XYZ->X = _cms15Fixed16toDouble((cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) xyz.X));
XYZ->Y = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.Y)); XYZ->Y = _cms15Fixed16toDouble((cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) xyz.Y));
XYZ->Z = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.Z)); XYZ->Z = _cms15Fixed16toDouble((cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) xyz.Z));
} }
return TRUE; return TRUE;
} }
...@@ -345,7 +363,7 @@ cmsBool CMSEXPORT _cmsWrite15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number n ...@@ -345,7 +363,7 @@ cmsBool CMSEXPORT _cmsWrite15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number n
_cmsAssert(io != NULL); _cmsAssert(io != NULL);
tmp = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(n)); tmp = _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(n));
if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1) if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
return FALSE; return FALSE;
...@@ -359,9 +377,9 @@ cmsBool CMSEXPORT _cmsWriteXYZNumber(cmsIOHANDLER* io, const cmsCIEXYZ* XYZ) ...@@ -359,9 +377,9 @@ cmsBool CMSEXPORT _cmsWriteXYZNumber(cmsIOHANDLER* io, const cmsCIEXYZ* XYZ)
_cmsAssert(io != NULL); _cmsAssert(io != NULL);
_cmsAssert(XYZ != NULL); _cmsAssert(XYZ != NULL);
xyz.X = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(XYZ->X)); xyz.X = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(XYZ->X));
xyz.Y = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(XYZ->Y)); xyz.Y = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(XYZ->Y));
xyz.Z = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(XYZ->Z)); xyz.Z = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(XYZ->Z));
return io -> Write(io, sizeof(cmsEncodedXYZNumber), &xyz); return io -> Write(io, sizeof(cmsEncodedXYZNumber), &xyz);
} }
...@@ -519,7 +537,7 @@ cmsBool CMSEXPORT _cmsIOPrintf(cmsIOHANDLER* io, const char* frm, ...) ...@@ -519,7 +537,7 @@ cmsBool CMSEXPORT _cmsIOPrintf(cmsIOHANDLER* io, const char* frm, ...)
return FALSE; // Truncated, which is a fatal error for us 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); va_end(args);
...@@ -779,6 +797,30 @@ cmsContext CMSEXPORT cmsCreateContext(void* Plugin, void* UserData) ...@@ -779,6 +797,30 @@ cmsContext CMSEXPORT cmsCreateContext(void* Plugin, void* UserData)
struct _cmsContext_struct* ctx; struct _cmsContext_struct* ctx;
struct _cmsContext_struct fakeContext; 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); _cmsInstallAllocFunctions(_cmsFindMemoryPlugin(Plugin), &fakeContext.DefaultMemoryManager);
fakeContext.chunks[UserPtr] = UserData; fakeContext.chunks[UserPtr] = UserData;
...@@ -805,7 +847,7 @@ cmsContext CMSEXPORT cmsCreateContext(void* Plugin, void* UserData) ...@@ -805,7 +847,7 @@ cmsContext CMSEXPORT cmsCreateContext(void* Plugin, void* UserData)
ctx ->chunks[MemPlugin] = &ctx->DefaultMemoryManager; ctx ->chunks[MemPlugin] = &ctx->DefaultMemoryManager;
// Now we can allocate the pool by using default memory manager // 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) { if (ctx ->MemPool == NULL) {
cmsDeleteContext(ctx); cmsDeleteContext(ctx);
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
...@@ -429,7 +429,7 @@ void EmitRangeCheck(cmsIOHANDLER* m) ...@@ -429,7 +429,7 @@ void EmitRangeCheck(cmsIOHANDLER* m)
// Does write the intent // Does write the intent
static static
void EmitIntent(cmsIOHANDLER* m, int RenderingIntent) void EmitIntent(cmsIOHANDLER* m, cmsUInt32Number RenderingIntent)
{ {
const char *intent; const char *intent;
...@@ -563,7 +563,7 @@ void Emit1Gamma(cmsIOHANDLER* m, cmsToneCurve* Table) ...@@ -563,7 +563,7 @@ void Emit1Gamma(cmsIOHANDLER* m, cmsToneCurve* Table)
// Compare gamma table // Compare gamma table
static 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; return memcmp(g1, g2, nEntries* sizeof(cmsUInt16Number)) == 0;
} }
...@@ -572,9 +572,9 @@ cmsBool GammaTableEquals(cmsUInt16Number* g1, cmsUInt16Number* g2, int nEntries) ...@@ -572,9 +572,9 @@ cmsBool GammaTableEquals(cmsUInt16Number* g1, cmsUInt16Number* g2, int nEntries)
// Does write a set of gamma curves // Does write a set of gamma curves
static 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++ ) for( i=0; i < n; i++ )
{ {
...@@ -797,7 +797,7 @@ int EmitCIEBasedABC(cmsIOHANDLER* m, cmsFloat64Number* Matrix, cmsToneCurve** Cu ...@@ -797,7 +797,7 @@ int EmitCIEBasedABC(cmsIOHANDLER* m, cmsFloat64Number* Matrix, cmsToneCurve** Cu
static 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* PreMaj;
const char* PostMaj; const char* PostMaj;
...@@ -857,14 +857,14 @@ int EmitCIEBasedDEF(cmsIOHANDLER* m, cmsPipeline* Pipeline, int Intent, cmsCIEXY ...@@ -857,14 +857,14 @@ int EmitCIEBasedDEF(cmsIOHANDLER* m, cmsPipeline* Pipeline, int Intent, cmsCIEXY
// Generates a curve from a gray profile // Generates a curve from a gray profile
static static
cmsToneCurve* ExtractGray2Y(cmsContext ContextID, cmsHPROFILE hProfile, int Intent) cmsToneCurve* ExtractGray2Y(cmsContext ContextID, cmsHPROFILE hProfile, cmsUInt32Number Intent)
{ {
cmsToneCurve* Out = cmsBuildTabulatedToneCurve16(ContextID, 256, NULL); cmsToneCurve* Out = cmsBuildTabulatedToneCurve16(ContextID, 256, NULL);
cmsHPROFILE hXYZ = cmsCreateXYZProfile(); cmsHPROFILE hXYZ = cmsCreateXYZProfile();
cmsHTRANSFORM xform = cmsCreateTransformTHR(ContextID, hProfile, TYPE_GRAY_8, hXYZ, TYPE_XYZ_DBL, Intent, cmsFLAGS_NOOPTIMIZE); cmsHTRANSFORM xform = cmsCreateTransformTHR(ContextID, hProfile, TYPE_GRAY_8, hXYZ, TYPE_XYZ_DBL, Intent, cmsFLAGS_NOOPTIMIZE);
int i; int i;
if (Out != NULL) { if (Out != NULL && xform != NULL) {
for (i=0; i < 256; i++) { for (i=0; i < 256; i++) {
cmsUInt8Number Gray = (cmsUInt8Number) i; cmsUInt8Number Gray = (cmsUInt8Number) i;
...@@ -876,8 +876,8 @@ static ...@@ -876,8 +876,8 @@ static
} }
} }
cmsDeleteTransform(xform); if (xform) cmsDeleteTransform(xform);
cmsCloseProfile(hXYZ); if (hXYZ) cmsCloseProfile(hXYZ);
return Out; return Out;
} }
...@@ -887,7 +887,7 @@ static ...@@ -887,7 +887,7 @@ static
// a more perceptually uniform space... I do choose Lab. // a more perceptually uniform space... I do choose Lab.
static static
int WriteInputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, int Intent, cmsUInt32Number dwFlags) int WriteInputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags)
{ {
cmsHPROFILE hLab; cmsHPROFILE hLab;
cmsHTRANSFORM xform; cmsHTRANSFORM xform;
...@@ -972,7 +972,6 @@ cmsFloat64Number* GetPtrToMatrix(const cmsStage* mpe) ...@@ -972,7 +972,6 @@ cmsFloat64Number* GetPtrToMatrix(const cmsStage* mpe)
// Does create CSA based on matrix-shaper. Allowed types are gray and RGB based // Does create CSA based on matrix-shaper. Allowed types are gray and RGB based
static static
int WriteInputMatrixShaper(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsStage* Matrix, cmsStage* Shaper) int WriteInputMatrixShaper(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsStage* Matrix, cmsStage* Shaper)
{ {
...@@ -998,17 +997,17 @@ int WriteInputMatrixShaper(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsStage* Matr ...@@ -998,17 +997,17 @@ int WriteInputMatrixShaper(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsStage* Matr
memmove(&Mat, GetPtrToMatrix(Matrix), sizeof(Mat)); memmove(&Mat, GetPtrToMatrix(Matrix), sizeof(Mat));
for (i=0; i < 3; i++) for (i = 0; i < 3; i++)
for (j=0; j < 3; j++) for (j = 0; j < 3; j++)
Mat.v[i].n[j] *= MAX_ENCODEABLE_XYZ; Mat.v[i].n[j] *= MAX_ENCODEABLE_XYZ;
rc = EmitCIEBasedABC(m, (cmsFloat64Number *) &Mat, rc = EmitCIEBasedABC(m, (cmsFloat64Number *)&Mat,
_cmsStageGetPtrToCurveSet(Shaper), _cmsStageGetPtrToCurveSet(Shaper),
&BlackPointAdaptedToD50); &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; return 0;
} }
...@@ -1021,12 +1020,12 @@ int WriteInputMatrixShaper(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsStage* Matr ...@@ -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 // This is a HP extension, and it works in Lab instead of XYZ
static static
int WriteNamedColorCSA(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, int Intent) int WriteNamedColorCSA(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, cmsUInt32Number Intent)
{ {
cmsHTRANSFORM xform; cmsHTRANSFORM xform;
cmsHPROFILE hLab; cmsHPROFILE hLab;
int i, nColors; cmsUInt32Number i, nColors;
char ColorName[32]; char ColorName[cmsMAX_PATH];
cmsNAMEDCOLORLIST* NamedColorList; cmsNAMEDCOLORLIST* NamedColorList;
hLab = cmsCreateLab4ProfileTHR(m ->ContextID, NULL); hLab = cmsCreateLab4ProfileTHR(m ->ContextID, NULL);
...@@ -1304,20 +1303,20 @@ void EmitXYZ2Lab(cmsIOHANDLER* m) ...@@ -1304,20 +1303,20 @@ void EmitXYZ2Lab(cmsIOHANDLER* m)
// 8 bits. // 8 bits.
static static
int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, int Intent, cmsUInt32Number dwFlags) int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags)
{ {
cmsHPROFILE hLab; cmsHPROFILE hLab;
cmsHTRANSFORM xform; cmsHTRANSFORM xform;
int i, nChannels; cmsUInt32Number i, nChannels;
cmsUInt32Number OutputFormat; cmsUInt32Number OutputFormat;
_cmsTRANSFORM* v; _cmsTRANSFORM* v;
cmsPipeline* DeviceLink; cmsPipeline* DeviceLink;
cmsHPROFILE Profiles[3]; cmsHPROFILE Profiles[3];
cmsCIEXYZ BlackPointAdaptedToD50; cmsCIEXYZ BlackPointAdaptedToD50;
cmsBool lDoBPC = (dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION); cmsBool lDoBPC = (cmsBool) (dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION);
cmsBool lFixWhite = !(dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP); cmsBool lFixWhite = (cmsBool) !(dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP);
cmsUInt32Number InFrm = TYPE_Lab_16; cmsUInt32Number InFrm = TYPE_Lab_16;
int RelativeEncodingIntent; cmsUInt32Number RelativeEncodingIntent;
cmsColorSpaceSignature ColorSpace; cmsColorSpaceSignature ColorSpace;
...@@ -1413,10 +1412,10 @@ int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, int Intent, cmsUInt32N ...@@ -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 // Builds a ASCII string containing colorant list in 0..1.0 range
static static
void BuildColorantList(char *Colorant, int nColorant, cmsUInt16Number Out[]) void BuildColorantList(char *Colorant, cmsUInt32Number nColorant, cmsUInt16Number Out[])
{ {
char Buff[32]; char Buff[32];
int j; cmsUInt32Number j;
Colorant[0] = 0; Colorant[0] = 0;
if (nColorant > cmsMAXCHANNELS) if (nColorant > cmsMAXCHANNELS)
...@@ -1438,12 +1437,12 @@ void BuildColorantList(char *Colorant, int nColorant, cmsUInt16Number Out[]) ...@@ -1438,12 +1437,12 @@ void BuildColorantList(char *Colorant, int nColorant, cmsUInt16Number Out[])
// This is a HP extension. // This is a HP extension.
static static
int WriteNamedColorCRD(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, int Intent, cmsUInt32Number dwFlags) int WriteNamedColorCRD(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, cmsUInt32Number Intent, cmsUInt32Number dwFlags)
{ {
cmsHTRANSFORM xform; cmsHTRANSFORM xform;
int i, nColors, nColorant; cmsUInt32Number i, nColors, nColorant;
cmsUInt32Number OutputFormat; cmsUInt32Number OutputFormat;
char ColorName[32]; char ColorName[cmsMAX_PATH];
char Colorant[128]; char Colorant[128];
cmsNAMEDCOLORLIST* NamedColorList; cmsNAMEDCOLORLIST* NamedColorList;
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
...@@ -89,6 +89,11 @@ typedef struct _cmsTagTypeLinkedList_st { ...@@ -89,6 +89,11 @@ typedef struct _cmsTagTypeLinkedList_st {
// Helper macro to define a MPE handler. Callbacks do have a fixed naming convention // 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 } #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 // Register a new type handler. This routine is shared between normal types and MPE. LinkedList points to the optional list head
static static
cmsBool RegisterTypesPlugin(cmsContext id, cmsPluginBase* Data, _cmsMemoryClient pos) cmsBool RegisterTypesPlugin(cmsContext id, cmsPluginBase* Data, _cmsMemoryClient pos)
...@@ -202,6 +207,13 @@ cmsBool ReadPositionTable(struct _cms_typehandler_struct* self, ...@@ -202,6 +207,13 @@ cmsBool ReadPositionTable(struct _cms_typehandler_struct* self,
{ {
cmsUInt32Number i; cmsUInt32Number i;
cmsUInt32Number *ElementOffsets = NULL, *ElementSizes = NULL; 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 // Let's take the offsets to each element
ElementOffsets = (cmsUInt32Number *) _cmsCalloc(io ->ContextID, Count, sizeof(cmsUInt32Number)); ElementOffsets = (cmsUInt32Number *) _cmsCalloc(io ->ContextID, Count, sizeof(cmsUInt32Number));
...@@ -424,8 +436,8 @@ Error: ...@@ -424,8 +436,8 @@ Error:
static static
cmsBool SaveOneChromaticity(cmsFloat64Number x, cmsFloat64Number y, cmsIOHANDLER* io) cmsBool SaveOneChromaticity(cmsFloat64Number x, cmsFloat64Number y, cmsIOHANDLER* io)
{ {
if (!_cmsWriteUInt32Number(io, _cmsDoubleTo15Fixed16(x))) return FALSE; if (!_cmsWriteUInt32Number(io, (cmsUInt32Number) _cmsDoubleTo15Fixed16(x))) return FALSE;
if (!_cmsWriteUInt32Number(io, _cmsDoubleTo15Fixed16(y))) return FALSE; if (!_cmsWriteUInt32Number(io, (cmsUInt32Number) _cmsDoubleTo15Fixed16(y))) return FALSE;
return TRUE; return TRUE;
} }
...@@ -984,7 +996,7 @@ cmsBool Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIO ...@@ -984,7 +996,7 @@ cmsBool Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIO
cmsBool rc = FALSE; cmsBool rc = FALSE;
char Filler[68]; char Filler[68];
// Used below for writting zeroes // Used below for writing zeroes
memset(Filler, 0, sizeof(Filler)); memset(Filler, 0, sizeof(Filler));
// Get the len of string // Get the len of string
...@@ -1146,7 +1158,10 @@ void *Type_Curve_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cm ...@@ -1146,7 +1158,10 @@ void *Type_Curve_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cm
NewGamma = cmsBuildTabulatedToneCurve16(self ->ContextID, Count, NULL); NewGamma = cmsBuildTabulatedToneCurve16(self ->ContextID, Count, NULL);
if (!NewGamma) return 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; *nItems = 1;
return NewGamma; return NewGamma;
...@@ -1206,7 +1221,7 @@ void Type_Curve_Free(struct _cms_typehandler_struct* self, void* Ptr) ...@@ -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 static
cmsTagTypeSignature DecideCurveType(cmsFloat64Number ICCVersion, const void *Data) cmsTagTypeSignature DecideCurveType(cmsFloat64Number ICCVersion, const void *Data)
{ {
...@@ -1599,7 +1614,7 @@ void Type_MLU_Free(struct _cms_typehandler_struct* self, void* Ptr) ...@@ -1599,7 +1614,7 @@ void Type_MLU_Free(struct _cms_typehandler_struct* self, void* Ptr)
// Type cmsSigLut8Type // Type cmsSigLut8Type
// ******************************************************************************** // ********************************************************************************
// Decide which LUT type to use on writting // Decide which LUT type to use on writing
static static
cmsTagTypeSignature DecideLUTtypeA2B(cmsFloat64Number ICCVersion, const void *Data) cmsTagTypeSignature DecideLUTtypeA2B(cmsFloat64Number ICCVersion, const void *Data)
{ {
...@@ -1648,10 +1663,10 @@ Byte Position Field Length (bytes) Content Encoded as... ...@@ -1648,10 +1663,10 @@ Byte Position Field Length (bytes) Content Encoded as...
// Read 8 bit tables as gamma functions // Read 8 bit tables as gamma functions
static static
cmsBool Read8bitTables(cmsContext ContextID, cmsIOHANDLER* io, cmsPipeline* lut, int nChannels) cmsBool Read8bitTables(cmsContext ContextID, cmsIOHANDLER* io, cmsPipeline* lut, cmsUInt32Number nChannels)
{ {
cmsUInt8Number* Temp = NULL; cmsUInt8Number* Temp = NULL;
int i, j; cmsUInt32Number i, j;
cmsToneCurve* Tables[cmsMAXCHANNELS]; cmsToneCurve* Tables[cmsMAXCHANNELS];
if (nChannels > cmsMAXCHANNELS) return FALSE; if (nChannels > cmsMAXCHANNELS) return FALSE;
...@@ -1784,8 +1799,8 @@ void *Type_LUT8_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cms ...@@ -1784,8 +1799,8 @@ void *Type_LUT8_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cms
if (!_cmsReadUInt8Number(io, NULL)) goto Error; if (!_cmsReadUInt8Number(io, NULL)) goto Error;
// Do some checking // Do some checking
if (InputChannels > cmsMAXCHANNELS) goto Error; if (InputChannels == 0 || InputChannels > cmsMAXCHANNELS) goto Error;
if (OutputChannels > cmsMAXCHANNELS) goto Error; if (OutputChannels == 0 || OutputChannels > cmsMAXCHANNELS) goto Error;
// Allocates an empty Pipeline // Allocates an empty Pipeline
NewLUT = cmsPipelineAlloc(self ->ContextID, InputChannels, OutputChannels); NewLUT = cmsPipelineAlloc(self ->ContextID, InputChannels, OutputChannels);
...@@ -1842,8 +1857,10 @@ void *Type_LUT8_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cms ...@@ -1842,8 +1857,10 @@ void *Type_LUT8_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cms
_cmsFree(self ->ContextID, Temp); _cmsFree(self ->ContextID, Temp);
Temp = NULL; 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; goto Error;
}
_cmsFree(self ->ContextID, T); _cmsFree(self ->ContextID, T);
} }
...@@ -1872,7 +1889,7 @@ cmsBool Type_LUT8_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, ...@@ -1872,7 +1889,7 @@ cmsBool Type_LUT8_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
_cmsStageToneCurvesData* PreMPE = NULL, *PostMPE = NULL; _cmsStageToneCurvesData* PreMPE = NULL, *PostMPE = NULL;
_cmsStageMatrixData* MatMPE = NULL; _cmsStageMatrixData* MatMPE = NULL;
_cmsStageCLutData* clut = NULL; _cmsStageCLutData* clut = NULL;
int clutPoints; cmsUInt32Number clutPoints;
// Disassemble the LUT into components. // Disassemble the LUT into components.
mpe = NewLUT -> Elements; mpe = NewLUT -> Elements;
...@@ -1992,9 +2009,10 @@ void Type_LUT8_Free(struct _cms_typehandler_struct* self, void* Ptr) ...@@ -1992,9 +2009,10 @@ void Type_LUT8_Free(struct _cms_typehandler_struct* self, void* Ptr)
// Read 16 bit tables as gamma functions // Read 16 bit tables as gamma functions
static 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]; cmsToneCurve* Tables[cmsMAXCHANNELS];
// Maybe an empty table? (this is a lcms extension) // Maybe an empty table? (this is a lcms extension)
...@@ -2036,10 +2054,10 @@ Error: ...@@ -2036,10 +2054,10 @@ Error:
static static
cmsBool Write16bitTables(cmsContext ContextID, cmsIOHANDLER* io, _cmsStageToneCurvesData* Tables) cmsBool Write16bitTables(cmsContext ContextID, cmsIOHANDLER* io, _cmsStageToneCurvesData* Tables)
{ {
int j; cmsUInt32Number j;
cmsUInt32Number i; cmsUInt32Number i;
cmsUInt16Number val; cmsUInt16Number val;
int nEntries; cmsUInt32Number nEntries;
_cmsAssert(Tables != NULL); _cmsAssert(Tables != NULL);
...@@ -2077,8 +2095,8 @@ void *Type_LUT16_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cm ...@@ -2077,8 +2095,8 @@ void *Type_LUT16_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cm
if (!_cmsReadUInt8Number(io, NULL)) return NULL; if (!_cmsReadUInt8Number(io, NULL)) return NULL;
// Do some checking // Do some checking
if (InputChannels > cmsMAXCHANNELS) goto Error; if (InputChannels == 0 || InputChannels > cmsMAXCHANNELS) goto Error;
if (OutputChannels > cmsMAXCHANNELS) goto Error; if (OutputChannels == 0 || OutputChannels > cmsMAXCHANNELS) goto Error;
// Allocates an empty LUT // Allocates an empty LUT
NewLUT = cmsPipelineAlloc(self ->ContextID, InputChannels, OutputChannels); NewLUT = cmsPipelineAlloc(self ->ContextID, InputChannels, OutputChannels);
...@@ -2160,7 +2178,7 @@ cmsBool Type_LUT16_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io ...@@ -2160,7 +2178,7 @@ cmsBool Type_LUT16_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io
_cmsStageToneCurvesData* PreMPE = NULL, *PostMPE = NULL; _cmsStageToneCurvesData* PreMPE = NULL, *PostMPE = NULL;
_cmsStageMatrixData* MatMPE = NULL; _cmsStageMatrixData* MatMPE = NULL;
_cmsStageCLutData* clut = NULL; _cmsStageCLutData* clut = NULL;
int i, InputChannels, OutputChannels, clutPoints; cmsUInt32Number i, InputChannels, OutputChannels, clutPoints;
// Disassemble the LUT into components. // Disassemble the LUT into components.
mpe = NewLUT -> Elements; mpe = NewLUT -> Elements;
...@@ -2346,7 +2364,8 @@ cmsStage* ReadMatrix(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cms ...@@ -2346,7 +2364,8 @@ cmsStage* ReadMatrix(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cms
// V4 stuff. Read CLUT part for LutAtoB and LutBtoA // V4 stuff. Read CLUT part for LutAtoB and LutBtoA
static 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. cmsUInt8Number gridPoints8[cmsMAXCHANNELS]; // Number of grid points in each dimension.
cmsUInt32Number GridPoints[cmsMAXCHANNELS], i; cmsUInt32Number GridPoints[cmsMAXCHANNELS], i;
...@@ -2382,7 +2401,10 @@ cmsStage* ReadCLUT(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUI ...@@ -2382,7 +2401,10 @@ cmsStage* ReadCLUT(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUI
for (i=0; i < Data ->nEntries; i++) { 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); 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 ...@@ -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, &offsetC)) return NULL;
if (!_cmsReadUInt32Number(io, &offsetA)) 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); NewLUT = cmsPipelineAlloc(self ->ContextID, inputChan, outputChan);
if (NewLUT == NULL) return NULL; if (NewLUT == NULL) return NULL;
...@@ -2694,7 +2719,7 @@ static ...@@ -2694,7 +2719,7 @@ static
cmsBool Type_LUTA2B_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) cmsBool Type_LUTA2B_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{ {
cmsPipeline* Lut = (cmsPipeline*) Ptr; cmsPipeline* Lut = (cmsPipeline*) Ptr;
int inputChan, outputChan; cmsUInt32Number inputChan, outputChan;
cmsStage *A = NULL, *B = NULL, *M = NULL; cmsStage *A = NULL, *B = NULL, *M = NULL;
cmsStage * Matrix = NULL; cmsStage * Matrix = NULL;
cmsStage * CLUT = NULL; cmsStage * CLUT = NULL;
...@@ -2742,7 +2767,7 @@ cmsBool Type_LUTA2B_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io ...@@ -2742,7 +2767,7 @@ cmsBool Type_LUTA2B_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io
if (CLUT != NULL) { if (CLUT != NULL) {
offsetC = io ->Tell(io) - BaseOffset; 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) { if (M != NULL) {
...@@ -2820,6 +2845,9 @@ void* Type_LUTB2A_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, c ...@@ -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, &inputChan)) return NULL;
if (!_cmsReadUInt8Number(io, &outputChan)) return NULL; if (!_cmsReadUInt8Number(io, &outputChan)) return NULL;
if (inputChan == 0 || inputChan >= cmsMAXCHANNELS) return NULL;
if (outputChan == 0 || outputChan >= cmsMAXCHANNELS) return NULL;
// Padding // Padding
if (!_cmsReadUInt16Number(io, NULL)) return NULL; if (!_cmsReadUInt16Number(io, NULL)) return NULL;
...@@ -2879,7 +2907,7 @@ static ...@@ -2879,7 +2907,7 @@ static
cmsBool Type_LUTB2A_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) cmsBool Type_LUTB2A_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{ {
cmsPipeline* Lut = (cmsPipeline*) Ptr; cmsPipeline* Lut = (cmsPipeline*) Ptr;
int inputChan, outputChan; cmsUInt32Number inputChan, outputChan;
cmsStage *A = NULL, *B = NULL, *M = NULL; cmsStage *A = NULL, *B = NULL, *M = NULL;
cmsStage *Matrix = NULL; cmsStage *Matrix = NULL;
cmsStage *CLUT = NULL; cmsStage *CLUT = NULL;
...@@ -2921,7 +2949,7 @@ cmsBool Type_LUTB2A_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* i ...@@ -2921,7 +2949,7 @@ cmsBool Type_LUTB2A_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* i
if (CLUT != NULL) { if (CLUT != NULL) {
offsetC = io ->Tell(io) - BaseOffset; 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) { if (M != NULL) {
...@@ -3011,7 +3039,7 @@ void *Type_ColorantTable_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER ...@@ -3011,7 +3039,7 @@ void *Type_ColorantTable_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER
for (i=0; i < Count; i++) { for (i=0; i < Count; i++) {
if (io ->Read(io, Name, 32, 1) != 1) goto Error; if (io ->Read(io, Name, 32, 1) != 1) goto Error;
Name[33] = 0; Name[32] = 0;
if (!_cmsReadUInt16Array(io, 3, PCS)) goto Error; if (!_cmsReadUInt16Array(io, 3, PCS)) goto Error;
...@@ -3037,7 +3065,7 @@ static ...@@ -3037,7 +3065,7 @@ static
cmsBool Type_ColorantTable_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) cmsBool Type_ColorantTable_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{ {
cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) Ptr; cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) Ptr;
int i, nColors; cmsUInt32Number i, nColors;
nColors = cmsNamedColorCount(NamedColorList); nColors = cmsNamedColorCount(NamedColorList);
...@@ -3045,9 +3073,11 @@ cmsBool Type_ColorantTable_Write(struct _cms_typehandler_struct* self, cmsIOHAN ...@@ -3045,9 +3073,11 @@ cmsBool Type_ColorantTable_Write(struct _cms_typehandler_struct* self, cmsIOHAN
for (i=0; i < nColors; i++) { for (i=0; i < nColors; i++) {
char root[33]; char root[cmsMAX_PATH];
cmsUInt16Number PCS[3]; cmsUInt16Number PCS[3];
memset(root, 0, sizeof(root));
if (!cmsNamedColorInfo(NamedColorList, i, root, NULL, NULL, PCS, NULL)) return 0; if (!cmsNamedColorInfo(NamedColorList, i, root, NULL, NULL, PCS, NULL)) return 0;
root[32] = 0; root[32] = 0;
...@@ -3107,8 +3137,8 @@ void *Type_NamedColor_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* i ...@@ -3107,8 +3137,8 @@ void *Type_NamedColor_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* i
cmsUInt32Number nDeviceCoords; // Num of device coordinates cmsUInt32Number nDeviceCoords; // Num of device coordinates
char prefix[32]; // Prefix for each color name char prefix[32]; // Prefix for each color name
char suffix[32]; // Suffix for each color name char suffix[32]; // Suffix for each color name
cmsNAMEDCOLORLIST* v; cmsNAMEDCOLORLIST* v;
cmsUInt32Number i; cmsUInt32Number i;
*nItems = 0; *nItems = 0;
...@@ -3129,7 +3159,7 @@ void *Type_NamedColor_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* i ...@@ -3129,7 +3159,7 @@ void *Type_NamedColor_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* i
if (nDeviceCoords > cmsMAXCHANNELS) { if (nDeviceCoords > cmsMAXCHANNELS) {
cmsSignalError(self->ContextID, cmsERROR_RANGE, "Too many device coordinates '%d'", nDeviceCoords); cmsSignalError(self->ContextID, cmsERROR_RANGE, "Too many device coordinates '%d'", nDeviceCoords);
return 0; goto Error;
} }
for (i=0; i < count; i++) { for (i=0; i < count; i++) {
...@@ -3138,7 +3168,7 @@ void *Type_NamedColor_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* i ...@@ -3138,7 +3168,7 @@ void *Type_NamedColor_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* i
char Root[33]; char Root[33];
memset(Colorant, 0, sizeof(Colorant)); 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 Root[32] = 0; // To prevent exploits
if (!_cmsReadUInt16Array(io, 3, PCS)) goto Error; if (!_cmsReadUInt16Array(io, 3, PCS)) goto Error;
...@@ -3165,7 +3195,7 @@ cmsBool Type_NamedColor_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER ...@@ -3165,7 +3195,7 @@ cmsBool Type_NamedColor_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER
cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) Ptr; cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) Ptr;
char prefix[33]; // Prefix for each color name char prefix[33]; // Prefix for each color name
char suffix[33]; // Suffix for each color name char suffix[33]; // Suffix for each color name
int i, nColors; cmsUInt32Number i, nColors;
nColors = cmsNamedColorCount(NamedColorList); nColors = cmsNamedColorCount(NamedColorList);
...@@ -3185,7 +3215,7 @@ cmsBool Type_NamedColor_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER ...@@ -3185,7 +3215,7 @@ cmsBool Type_NamedColor_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER
cmsUInt16Number PCS[3]; cmsUInt16Number PCS[3];
cmsUInt16Number Colorant[cmsMAXCHANNELS]; cmsUInt16Number Colorant[cmsMAXCHANNELS];
char Root[33]; char Root[cmsMAX_PATH];
if (!cmsNamedColorInfo(NamedColorList, i, Root, NULL, NULL, PCS, Colorant)) return 0; if (!cmsNamedColorInfo(NamedColorList, i, Root, NULL, NULL, PCS, Colorant)) return 0;
Root[32] = 0; Root[32] = 0;
...@@ -3939,7 +3969,7 @@ cmsToneCurve* ReadSegmentedCurve(struct _cms_typehandler_struct* self, cmsIOHAND ...@@ -3939,7 +3969,7 @@ cmsToneCurve* ReadSegmentedCurve(struct _cms_typehandler_struct* self, cmsIOHAND
cmsUInt16Number nSegments; cmsUInt16Number nSegments;
cmsCurveSegment* Segments; cmsCurveSegment* Segments;
cmsToneCurve* Curve; cmsToneCurve* Curve;
cmsFloat32Number PrevBreak = -1E22F; // - infinite cmsFloat32Number PrevBreak = MINUS_INF; // - infinite
// Take signature and channels for each element. // Take signature and channels for each element.
if (!_cmsReadUInt32Number(io, (cmsUInt32Number*) &ElementSig)) return NULL; if (!_cmsReadUInt32Number(io, (cmsUInt32Number*) &ElementSig)) return NULL;
...@@ -3964,7 +3994,7 @@ cmsToneCurve* ReadSegmentedCurve(struct _cms_typehandler_struct* self, cmsIOHAND ...@@ -3964,7 +3994,7 @@ cmsToneCurve* ReadSegmentedCurve(struct _cms_typehandler_struct* self, cmsIOHAND
} }
Segments[nSegments-1].x0 = PrevBreak; 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 // Read segments
for (i=0; i < nSegments; i++) { for (i=0; i < nSegments; i++) {
...@@ -3998,7 +4028,7 @@ cmsToneCurve* ReadSegmentedCurve(struct _cms_typehandler_struct* self, cmsIOHAND ...@@ -3998,7 +4028,7 @@ cmsToneCurve* ReadSegmentedCurve(struct _cms_typehandler_struct* self, cmsIOHAND
case cmsSigSampledCurveSeg: { case cmsSigSampledCurveSeg: {
cmsUInt32Number Count; cmsUInt32Number Count;
if (!_cmsReadUInt32Number(io, &Count)) return NULL; if (!_cmsReadUInt32Number(io, &Count)) goto Error;
Segments[i].nGridPoints = Count; Segments[i].nGridPoints = Count;
Segments[i].SampledPoints = (cmsFloat32Number*) _cmsCalloc(self ->ContextID, Count, sizeof(cmsFloat32Number)); Segments[i].SampledPoints = (cmsFloat32Number*) _cmsCalloc(self ->ContextID, Count, sizeof(cmsFloat32Number));
...@@ -4017,7 +4047,7 @@ cmsToneCurve* ReadSegmentedCurve(struct _cms_typehandler_struct* self, cmsIOHAND ...@@ -4017,7 +4047,7 @@ cmsToneCurve* ReadSegmentedCurve(struct _cms_typehandler_struct* self, cmsIOHAND
_cmsTagSignature2String(String, (cmsTagSignature) ElementSig); _cmsTagSignature2String(String, (cmsTagSignature) ElementSig);
cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown curve element type '%s' found.", String); 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 ...@@ -4031,7 +4061,12 @@ cmsToneCurve* ReadSegmentedCurve(struct _cms_typehandler_struct* self, cmsIOHAND
return Curve; return Curve;
Error: 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; return NULL;
} }
...@@ -4085,7 +4120,7 @@ void *Type_MPEcurve_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, ...@@ -4085,7 +4120,7 @@ void *Type_MPEcurve_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
} }
_cmsFree(self ->ContextID, GammaTables); _cmsFree(self ->ContextID, GammaTables);
*nItems = (mpe != NULL) ? 1 : 0; *nItems = (mpe != NULL) ? 1U : 0;
return mpe; return mpe;
cmsUNUSED_PARAMETER(SizeOfTag); cmsUNUSED_PARAMETER(SizeOfTag);
...@@ -4216,9 +4251,13 @@ void *Type_MPEmatrix_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io ...@@ -4216,9 +4251,13 @@ void *Type_MPEmatrix_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io
if (!_cmsReadUInt16Number(io, &OutputChans)) return NULL; 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)); Matrix = (cmsFloat64Number*) _cmsCalloc(self ->ContextID, nElems, sizeof(cmsFloat64Number));
if (Matrix == NULL) return NULL; if (Matrix == NULL) return NULL;
...@@ -4233,7 +4272,11 @@ void *Type_MPEmatrix_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io ...@@ -4233,7 +4272,11 @@ void *Type_MPEmatrix_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io
cmsFloat32Number v; 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; Matrix[i] = v;
} }
...@@ -4242,7 +4285,11 @@ void *Type_MPEmatrix_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io ...@@ -4242,7 +4285,11 @@ void *Type_MPEmatrix_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io
cmsFloat32Number v; 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; Offsets[i] = v;
} }
...@@ -4313,8 +4360,9 @@ void *Type_MPEclut_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, ...@@ -4313,8 +4360,9 @@ void *Type_MPEclut_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
goto Error; goto Error;
// Copy MAX_INPUT_DIMENSIONS at most. Expand to cmsUInt32Number // Copy MAX_INPUT_DIMENSIONS at most. Expand to cmsUInt32Number
nMaxGrids = InputChans > MAX_INPUT_DIMENSIONS ? MAX_INPUT_DIMENSIONS : InputChans; nMaxGrids = InputChans > MAX_INPUT_DIMENSIONS ? (cmsUInt32Number) MAX_INPUT_DIMENSIONS : InputChans;
for (i=0; i < nMaxGrids; i++) {
for (i = 0; i < nMaxGrids; i++) {
if (Dimensions8[i] == 1) goto Error; // Impossible value, 0 for no CLUT and then 2 at least if (Dimensions8[i] == 1) goto Error; // Impossible value, 0 for no CLUT and then 2 at least
GridPoints[i] = (cmsUInt32Number)Dimensions8[i]; GridPoints[i] = (cmsUInt32Number)Dimensions8[i];
} }
...@@ -4323,11 +4371,11 @@ void *Type_MPEclut_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, ...@@ -4323,11 +4371,11 @@ void *Type_MPEclut_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
mpe = cmsStageAllocCLutFloatGranular(self ->ContextID, GridPoints, InputChans, OutputChans, NULL); mpe = cmsStageAllocCLutFloatGranular(self ->ContextID, GridPoints, InputChans, OutputChans, NULL);
if (mpe == NULL) goto Error; if (mpe == NULL) goto Error;
// Read the data // Read and sanitize the data
clut = (_cmsStageCLutData*) mpe ->Data; clut = (_cmsStageCLutData*) mpe ->Data;
for (i=0; i < clut ->nEntries; i++) { 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; *nItems = 1;
...@@ -4457,6 +4505,9 @@ void *Type_MPE_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsU ...@@ -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, &InputChans)) return NULL;
if (!_cmsReadUInt16Number(io, &OutputChans)) 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 // Allocates an empty LUT
NewLUT = cmsPipelineAlloc(self ->ContextID, InputChans, OutputChans); NewLUT = cmsPipelineAlloc(self ->ContextID, InputChans, OutputChans);
if (NewLUT == NULL) return NULL; if (NewLUT == NULL) return NULL;
...@@ -4464,6 +4515,10 @@ void *Type_MPE_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsU ...@@ -4464,6 +4515,10 @@ void *Type_MPE_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsU
if (!_cmsReadUInt32Number(io, &ElementCount)) goto Error; if (!_cmsReadUInt32Number(io, &ElementCount)) goto Error;
if (!ReadPositionTable(self, io, ElementCount, BaseOffset, NewLUT, ReadMPEElem)) 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 // Success
*nItems = 1; *nItems = 1;
return NewLUT; return NewLUT;
...@@ -4484,7 +4539,7 @@ static ...@@ -4484,7 +4539,7 @@ static
cmsBool Type_MPE_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) cmsBool Type_MPE_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{ {
cmsUInt32Number i, BaseOffset, DirectoryPos, CurrentPos; cmsUInt32Number i, BaseOffset, DirectoryPos, CurrentPos;
int inputChan, outputChan; cmsUInt32Number inputChan, outputChan;
cmsUInt32Number ElemCount; cmsUInt32Number ElemCount;
cmsUInt32Number *ElementOffsets = NULL, *ElementSizes = NULL, Before; cmsUInt32Number *ElementOffsets = NULL, *ElementSizes = NULL, Before;
cmsStageSignature ElementSig; cmsStageSignature ElementSig;
...@@ -4532,7 +4587,7 @@ cmsBool Type_MPE_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, v ...@@ -4532,7 +4587,7 @@ cmsBool Type_MPE_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, v
_cmsTagSignature2String(String, (cmsTagSignature) ElementSig); _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); cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Found unknown MPE type '%s'", String);
goto Error; goto Error;
} }
...@@ -5267,38 +5322,38 @@ void Type_Dictionary_Free(struct _cms_typehandler_struct* self, void* Ptr) ...@@ -5267,38 +5322,38 @@ void Type_Dictionary_Free(struct _cms_typehandler_struct* self, void* Ptr)
// This is the list of built-in types // This is the list of built-in types
static _cmsTagTypeLinkedList SupportedTagTypes[] = { static const _cmsTagTypeLinkedList SupportedTagTypes[] = {
{TYPE_HANDLER(cmsSigChromaticityType, Chromaticity), &SupportedTagTypes[1] }, {TYPE_HANDLER(cmsSigChromaticityType, Chromaticity), (_cmsTagTypeLinkedList*) &SupportedTagTypes[1] },
{TYPE_HANDLER(cmsSigColorantOrderType, ColorantOrderType), &SupportedTagTypes[2] }, {TYPE_HANDLER(cmsSigColorantOrderType, ColorantOrderType), (_cmsTagTypeLinkedList*) &SupportedTagTypes[2] },
{TYPE_HANDLER(cmsSigS15Fixed16ArrayType, S15Fixed16), &SupportedTagTypes[3] }, {TYPE_HANDLER(cmsSigS15Fixed16ArrayType, S15Fixed16), (_cmsTagTypeLinkedList*) &SupportedTagTypes[3] },
{TYPE_HANDLER(cmsSigU16Fixed16ArrayType, U16Fixed16), &SupportedTagTypes[4] }, {TYPE_HANDLER(cmsSigU16Fixed16ArrayType, U16Fixed16), (_cmsTagTypeLinkedList*) &SupportedTagTypes[4] },
{TYPE_HANDLER(cmsSigTextType, Text), &SupportedTagTypes[5] }, {TYPE_HANDLER(cmsSigTextType, Text), (_cmsTagTypeLinkedList*) &SupportedTagTypes[5] },
{TYPE_HANDLER(cmsSigTextDescriptionType, Text_Description), &SupportedTagTypes[6] }, {TYPE_HANDLER(cmsSigTextDescriptionType, Text_Description), (_cmsTagTypeLinkedList*) &SupportedTagTypes[6] },
{TYPE_HANDLER(cmsSigCurveType, Curve), &SupportedTagTypes[7] }, {TYPE_HANDLER(cmsSigCurveType, Curve), (_cmsTagTypeLinkedList*) &SupportedTagTypes[7] },
{TYPE_HANDLER(cmsSigParametricCurveType, ParametricCurve), &SupportedTagTypes[8] }, {TYPE_HANDLER(cmsSigParametricCurveType, ParametricCurve), (_cmsTagTypeLinkedList*) &SupportedTagTypes[8] },
{TYPE_HANDLER(cmsSigDateTimeType, DateTime), &SupportedTagTypes[9] }, {TYPE_HANDLER(cmsSigDateTimeType, DateTime), (_cmsTagTypeLinkedList*) &SupportedTagTypes[9] },
{TYPE_HANDLER(cmsSigLut8Type, LUT8), &SupportedTagTypes[10] }, {TYPE_HANDLER(cmsSigLut8Type, LUT8), (_cmsTagTypeLinkedList*) &SupportedTagTypes[10] },
{TYPE_HANDLER(cmsSigLut16Type, LUT16), &SupportedTagTypes[11] }, {TYPE_HANDLER(cmsSigLut16Type, LUT16), (_cmsTagTypeLinkedList*) &SupportedTagTypes[11] },
{TYPE_HANDLER(cmsSigColorantTableType, ColorantTable), &SupportedTagTypes[12] }, {TYPE_HANDLER(cmsSigColorantTableType, ColorantTable), (_cmsTagTypeLinkedList*) &SupportedTagTypes[12] },
{TYPE_HANDLER(cmsSigNamedColor2Type, NamedColor), &SupportedTagTypes[13] }, {TYPE_HANDLER(cmsSigNamedColor2Type, NamedColor), (_cmsTagTypeLinkedList*) &SupportedTagTypes[13] },
{TYPE_HANDLER(cmsSigMultiLocalizedUnicodeType, MLU), &SupportedTagTypes[14] }, {TYPE_HANDLER(cmsSigMultiLocalizedUnicodeType, MLU), (_cmsTagTypeLinkedList*) &SupportedTagTypes[14] },
{TYPE_HANDLER(cmsSigProfileSequenceDescType, ProfileSequenceDesc), &SupportedTagTypes[15] }, {TYPE_HANDLER(cmsSigProfileSequenceDescType, ProfileSequenceDesc),(_cmsTagTypeLinkedList*) &SupportedTagTypes[15] },
{TYPE_HANDLER(cmsSigSignatureType, Signature), &SupportedTagTypes[16] }, {TYPE_HANDLER(cmsSigSignatureType, Signature), (_cmsTagTypeLinkedList*) &SupportedTagTypes[16] },
{TYPE_HANDLER(cmsSigMeasurementType, Measurement), &SupportedTagTypes[17] }, {TYPE_HANDLER(cmsSigMeasurementType, Measurement), (_cmsTagTypeLinkedList*) &SupportedTagTypes[17] },
{TYPE_HANDLER(cmsSigDataType, Data), &SupportedTagTypes[18] }, {TYPE_HANDLER(cmsSigDataType, Data), (_cmsTagTypeLinkedList*) &SupportedTagTypes[18] },
{TYPE_HANDLER(cmsSigLutAtoBType, LUTA2B), &SupportedTagTypes[19] }, {TYPE_HANDLER(cmsSigLutAtoBType, LUTA2B), (_cmsTagTypeLinkedList*) &SupportedTagTypes[19] },
{TYPE_HANDLER(cmsSigLutBtoAType, LUTB2A), &SupportedTagTypes[20] }, {TYPE_HANDLER(cmsSigLutBtoAType, LUTB2A), (_cmsTagTypeLinkedList*) &SupportedTagTypes[20] },
{TYPE_HANDLER(cmsSigUcrBgType, UcrBg), &SupportedTagTypes[21] }, {TYPE_HANDLER(cmsSigUcrBgType, UcrBg), (_cmsTagTypeLinkedList*) &SupportedTagTypes[21] },
{TYPE_HANDLER(cmsSigCrdInfoType, CrdInfo), &SupportedTagTypes[22] }, {TYPE_HANDLER(cmsSigCrdInfoType, CrdInfo), (_cmsTagTypeLinkedList*) &SupportedTagTypes[22] },
{TYPE_HANDLER(cmsSigMultiProcessElementType, MPE), &SupportedTagTypes[23] }, {TYPE_HANDLER(cmsSigMultiProcessElementType, MPE), (_cmsTagTypeLinkedList*) &SupportedTagTypes[23] },
{TYPE_HANDLER(cmsSigScreeningType, Screening), &SupportedTagTypes[24] }, {TYPE_HANDLER(cmsSigScreeningType, Screening), (_cmsTagTypeLinkedList*) &SupportedTagTypes[24] },
{TYPE_HANDLER(cmsSigViewingConditionsType, ViewingConditions), &SupportedTagTypes[25] }, {TYPE_HANDLER(cmsSigViewingConditionsType, ViewingConditions), (_cmsTagTypeLinkedList*) &SupportedTagTypes[25] },
{TYPE_HANDLER(cmsSigXYZType, XYZ), &SupportedTagTypes[26] }, {TYPE_HANDLER(cmsSigXYZType, XYZ), (_cmsTagTypeLinkedList*) &SupportedTagTypes[26] },
{TYPE_HANDLER(cmsCorbisBrokenXYZtype, XYZ), &SupportedTagTypes[27] }, {TYPE_HANDLER(cmsCorbisBrokenXYZtype, XYZ), (_cmsTagTypeLinkedList*) &SupportedTagTypes[27] },
{TYPE_HANDLER(cmsMonacoBrokenCurveType, Curve), &SupportedTagTypes[28] }, {TYPE_HANDLER(cmsMonacoBrokenCurveType, Curve), (_cmsTagTypeLinkedList*) &SupportedTagTypes[28] },
{TYPE_HANDLER(cmsSigProfileSequenceIdType, ProfileSequenceId), &SupportedTagTypes[29] }, {TYPE_HANDLER(cmsSigProfileSequenceIdType, ProfileSequenceId), (_cmsTagTypeLinkedList*) &SupportedTagTypes[29] },
{TYPE_HANDLER(cmsSigDictType, Dictionary), &SupportedTagTypes[30] }, {TYPE_HANDLER(cmsSigDictType, Dictionary), (_cmsTagTypeLinkedList*) &SupportedTagTypes[30] },
{TYPE_HANDLER(cmsSigVcgtType, vcgt), NULL } {TYPE_HANDLER(cmsSigVcgtType, vcgt), NULL }
}; };
...@@ -5390,7 +5445,7 @@ cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignatu ...@@ -5390,7 +5445,7 @@ cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignatu
{ {
_cmsTagTypePluginChunkType* ctx = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(ContextID, TagTypePlugin); _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 { ...@@ -5405,7 +5460,7 @@ typedef struct _cmsTagLinkedList_st {
} _cmsTagLinkedList; } _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[] = { static _cmsTagLinkedList SupportedTags[] = {
{ cmsSigAToB0Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutAtoBType, cmsSigLut8Type}, DecideLUTtypeA2B}, &SupportedTags[1]}, { cmsSigAToB0Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutAtoBType, cmsSigLut8Type}, DecideLUTtypeA2B}, &SupportedTags[1]},
...@@ -5454,7 +5509,7 @@ static _cmsTagLinkedList SupportedTags[] = { ...@@ -5454,7 +5509,7 @@ static _cmsTagLinkedList SupportedTags[] = {
{ cmsSigPreview2Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutBtoAType, cmsSigLut8Type }, DecideLUTtypeB2A}, &SupportedTags[32]}, { cmsSigPreview2Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutBtoAType, cmsSigLut8Type }, DecideLUTtypeB2A}, &SupportedTags[32]},
{ cmsSigProfileDescriptionTag, { 1, 3, { cmsSigTextDescriptionType, cmsSigMultiLocalizedUnicodeType, cmsSigTextType}, DecideTextDescType}, &SupportedTags[33]}, { 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]}, { cmsSigTechnologyTag, { 1, 1, { cmsSigSignatureType }, NULL}, &SupportedTags[35]},
{ cmsSigColorimetricIntentImageStateTag, { 1, 1, { cmsSigSignatureType }, NULL}, &SupportedTags[36]}, { cmsSigColorimetricIntentImageStateTag, { 1, 1, { cmsSigSignatureType }, NULL}, &SupportedTags[36]},
...@@ -5491,10 +5546,10 @@ static _cmsTagLinkedList SupportedTags[] = { ...@@ -5491,10 +5546,10 @@ static _cmsTagLinkedList SupportedTags[] = {
{ cmsSigVcgtTag, { 1, 1, { cmsSigVcgtType}, NULL }, &SupportedTags[60]}, { cmsSigVcgtTag, { 1, 1, { cmsSigVcgtType}, NULL }, &SupportedTags[60]},
{ cmsSigMetaTag, { 1, 1, { cmsSigDictType}, NULL }, &SupportedTags[61]}, { cmsSigMetaTag, { 1, 1, { cmsSigDictType}, NULL }, &SupportedTags[61]},
{ cmsSigProfileSequenceIdTag, { 1, 1, { cmsSigProfileSequenceIdType}, NULL }, &SupportedTags[62]}, { cmsSigProfileSequenceIdTag, { 1, 1, { cmsSigProfileSequenceIdType}, NULL }, &SupportedTags[62]},
{ cmsSigProfileDescriptionMLTag,{ 1, 1, { cmsSigMultiLocalizedUnicodeType}, NULL}, &SupportedTags[63]}, { cmsSigProfileDescriptionMLTag,{ 1, 1, { cmsSigMultiLocalizedUnicodeType}, NULL}, &SupportedTags[63]},
{ cmsSigArgyllArtsTag, { 9, 1, { cmsSigS15Fixed16ArrayType}, NULL}, NULL} { cmsSigArgyllArtsTag, { 9, 1, { cmsSigS15Fixed16ArrayType}, NULL}, NULL}
}; };
/* /*
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
...@@ -320,7 +320,7 @@ cmsHPROFILE CMSEXPORT cmsCreateLinearizationDeviceLinkTHR(cmsContext ContextID, ...@@ -320,7 +320,7 @@ cmsHPROFILE CMSEXPORT cmsCreateLinearizationDeviceLinkTHR(cmsContext ContextID,
{ {
cmsHPROFILE hICC; cmsHPROFILE hICC;
cmsPipeline* Pipeline; cmsPipeline* Pipeline;
int nChannels; cmsUInt32Number nChannels;
hICC = cmsCreateProfilePlaceholder(ContextID); hICC = cmsCreateProfilePlaceholder(ContextID);
if (!hICC) if (!hICC)
...@@ -426,7 +426,7 @@ cmsHPROFILE CMSEXPORT cmsCreateInkLimitingDeviceLinkTHR(cmsContext ContextID, ...@@ -426,7 +426,7 @@ cmsHPROFILE CMSEXPORT cmsCreateInkLimitingDeviceLinkTHR(cmsContext ContextID,
cmsHPROFILE hICC; cmsHPROFILE hICC;
cmsPipeline* LUT; cmsPipeline* LUT;
cmsStage* CLUT; cmsStage* CLUT;
int nChannels; cmsUInt32Number nChannels;
if (ColorSpace != cmsSigCmykData) { if (ColorSpace != cmsSigCmykData) {
cmsSignalError(ContextID, cmsERROR_COLORSPACE_CHECK, "InkLimiting: Only CMYK currently supported"); cmsSignalError(ContextID, cmsERROR_COLORSPACE_CHECK, "InkLimiting: Only CMYK currently supported");
...@@ -755,13 +755,13 @@ int bchswSampler(register const cmsUInt16Number In[], register cmsUInt16Number O ...@@ -755,13 +755,13 @@ int bchswSampler(register const cmsUInt16Number In[], register cmsUInt16Number O
// contrast, Saturation and white point displacement // contrast, Saturation and white point displacement
cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfileTHR(cmsContext ContextID, cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfileTHR(cmsContext ContextID,
int nLUTPoints, cmsUInt32Number nLUTPoints,
cmsFloat64Number Bright, cmsFloat64Number Bright,
cmsFloat64Number Contrast, cmsFloat64Number Contrast,
cmsFloat64Number Hue, cmsFloat64Number Hue,
cmsFloat64Number Saturation, cmsFloat64Number Saturation,
int TempSrc, cmsUInt32Number TempSrc,
int TempDest) cmsUInt32Number TempDest)
{ {
cmsHPROFILE hICC; cmsHPROFILE hICC;
cmsPipeline* Pipeline; cmsPipeline* Pipeline;
...@@ -769,7 +769,7 @@ cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfileTHR(cmsContext ContextID, ...@@ -769,7 +769,7 @@ cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfileTHR(cmsContext ContextID,
cmsCIExyY WhitePnt; cmsCIExyY WhitePnt;
cmsStage* CLUT; cmsStage* CLUT;
cmsUInt32Number Dimensions[MAX_INPUT_DIMENSIONS]; cmsUInt32Number Dimensions[MAX_INPUT_DIMENSIONS];
int i; cmsUInt32Number i;
bchsw.Brightness = Bright; bchsw.Brightness = Bright;
bchsw.Contrast = Contrast; bchsw.Contrast = Contrast;
...@@ -807,7 +807,7 @@ cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfileTHR(cmsContext ContextID, ...@@ -807,7 +807,7 @@ cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfileTHR(cmsContext ContextID,
for (i=0; i < MAX_INPUT_DIMENSIONS; i++) Dimensions[i] = nLUTPoints; for (i=0; i < MAX_INPUT_DIMENSIONS; i++) Dimensions[i] = nLUTPoints;
CLUT = cmsStageAllocCLut16bitGranular(ContextID, Dimensions, 3, 3, NULL); CLUT = cmsStageAllocCLut16bitGranular(ContextID, Dimensions, 3, 3, NULL);
if (CLUT == NULL) return NULL; if (CLUT == NULL) goto Error;
if (!cmsStageSampleCLut16bit(CLUT, bchswSampler, (void*) &bchsw, 0)) { if (!cmsStageSampleCLut16bit(CLUT, bchswSampler, (void*) &bchsw, 0)) {
...@@ -840,13 +840,13 @@ Error: ...@@ -840,13 +840,13 @@ Error:
} }
CMSAPI cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfile(int nLUTPoints, CMSAPI cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfile(cmsUInt32Number nLUTPoints,
cmsFloat64Number Bright, cmsFloat64Number Bright,
cmsFloat64Number Contrast, cmsFloat64Number Contrast,
cmsFloat64Number Hue, cmsFloat64Number Hue,
cmsFloat64Number Saturation, cmsFloat64Number Saturation,
int TempSrc, cmsUInt32Number TempSrc,
int TempDest) cmsUInt32Number TempDest)
{ {
return cmsCreateBCHSWabstractProfileTHR(NULL, nLUTPoints, Bright, Contrast, Hue, Saturation, TempSrc, TempDest); return cmsCreateBCHSWabstractProfileTHR(NULL, nLUTPoints, Bright, Contrast, Hue, Saturation, TempSrc, TempDest);
} }
...@@ -859,8 +859,10 @@ cmsHPROFILE CMSEXPORT cmsCreateNULLProfileTHR(cmsContext ContextID) ...@@ -859,8 +859,10 @@ cmsHPROFILE CMSEXPORT cmsCreateNULLProfileTHR(cmsContext ContextID)
cmsHPROFILE hProfile; cmsHPROFILE hProfile;
cmsPipeline* LUT = NULL; cmsPipeline* LUT = NULL;
cmsStage* PostLin; cmsStage* PostLin;
cmsToneCurve* EmptyTab; cmsStage* OutLin;
cmsToneCurve* EmptyTab[3];
cmsUInt16Number Zero[2] = { 0, 0 }; cmsUInt16Number Zero[2] = { 0, 0 };
const cmsFloat64Number PickLstarMatrix[] = { 1, 0, 0 };
hProfile = cmsCreateProfilePlaceholder(ContextID); hProfile = cmsCreateProfilePlaceholder(ContextID);
if (!hProfile) // can't allocate if (!hProfile) // can't allocate
...@@ -871,22 +873,28 @@ cmsHPROFILE CMSEXPORT cmsCreateNULLProfileTHR(cmsContext ContextID) ...@@ -871,22 +873,28 @@ cmsHPROFILE CMSEXPORT cmsCreateNULLProfileTHR(cmsContext ContextID)
if (!SetTextTags(hProfile, L"NULL profile built-in")) goto Error; if (!SetTextTags(hProfile, L"NULL profile built-in")) goto Error;
cmsSetDeviceClass(hProfile, cmsSigOutputClass); cmsSetDeviceClass(hProfile, cmsSigOutputClass);
cmsSetColorSpace(hProfile, cmsSigGrayData); cmsSetColorSpace(hProfile, cmsSigGrayData);
cmsSetPCS(hProfile, cmsSigLabData); cmsSetPCS(hProfile, cmsSigLabData);
// An empty LUTs is all we need // Create a valid ICC 4 structure
LUT = cmsPipelineAlloc(ContextID, 1, 1); LUT = cmsPipelineAlloc(ContextID, 3, 1);
if (LUT == NULL) goto Error; if (LUT == NULL) goto Error;
EmptyTab = cmsBuildTabulatedToneCurve16(ContextID, 2, Zero); EmptyTab[0] = EmptyTab[1] = EmptyTab[2] = cmsBuildTabulatedToneCurve16(ContextID, 2, Zero);
PostLin = cmsStageAllocToneCurves(ContextID, 1, &EmptyTab); PostLin = cmsStageAllocToneCurves(ContextID, 3, EmptyTab);
cmsFreeToneCurve(EmptyTab); OutLin = cmsStageAllocToneCurves(ContextID, 1, EmptyTab);
cmsFreeToneCurve(EmptyTab[0]);
if (!cmsPipelineInsertStage(LUT, cmsAT_END, PostLin)) if (!cmsPipelineInsertStage(LUT, cmsAT_END, PostLin))
goto Error; 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, cmsSigBToA0Tag, (void*) LUT)) goto Error;
if (!cmsWriteTag(hProfile, cmsSigMediaWhitePointTag, cmsD50_XYZ())) goto Error; if (!cmsWriteTag(hProfile, cmsSigMediaWhitePointTag, cmsD50_XYZ())) goto Error;
...@@ -967,7 +975,7 @@ cmsHPROFILE CreateNamedColorDevicelink(cmsHTRANSFORM xform) ...@@ -967,7 +975,7 @@ cmsHPROFILE CreateNamedColorDevicelink(cmsHTRANSFORM xform)
{ {
_cmsTRANSFORM* v = (_cmsTRANSFORM*) xform; _cmsTRANSFORM* v = (_cmsTRANSFORM*) xform;
cmsHPROFILE hICC = NULL; cmsHPROFILE hICC = NULL;
int i, nColors; cmsUInt32Number i, nColors;
cmsNAMEDCOLORLIST *nc2 = NULL, *Original = NULL; cmsNAMEDCOLORLIST *nc2 = NULL, *Original = NULL;
// Create an empty placeholder // Create an empty placeholder
...@@ -1084,7 +1092,7 @@ cmsHPROFILE CMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, cmsFloat ...@@ -1084,7 +1092,7 @@ cmsHPROFILE CMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, cmsFloat
{ {
cmsHPROFILE hProfile = NULL; cmsHPROFILE hProfile = NULL;
cmsUInt32Number FrmIn, FrmOut, ChansIn, ChansOut; cmsUInt32Number FrmIn, FrmOut, ChansIn, ChansOut;
cmsUInt32Number ColorSpaceBitsIn, ColorSpaceBitsOut; int ColorSpaceBitsIn, ColorSpaceBitsOut;
_cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform; _cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform;
cmsPipeline* LUT = NULL; cmsPipeline* LUT = NULL;
cmsStage* mpe; cmsStage* mpe;
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
...@@ -105,7 +105,6 @@ cmsBool CMSEXPORT cmsWhitePointFromTemp(cmsCIExyY* WhitePoint, cmsFloat64Number ...@@ -105,7 +105,6 @@ cmsBool CMSEXPORT cmsWhitePointFromTemp(cmsCIExyY* WhitePoint, cmsFloat64Number
} }
// Obtain y(x) // Obtain y(x)
y = -3.000*(x*x) + 2.870*x - 0.275; y = -3.000*(x*x) + 2.870*x - 0.275;
// wave factors (not used, but here for futures extensions) // wave factors (not used, but here for futures extensions)
...@@ -131,7 +130,7 @@ typedef struct { ...@@ -131,7 +130,7 @@ typedef struct {
} ISOTEMPERATURE; } ISOTEMPERATURE;
static ISOTEMPERATURE isotempdata[] = { static const ISOTEMPERATURE isotempdata[] = {
// {Mirek, Ut, Vt, Tt } // {Mirek, Ut, Vt, Tt }
{0, 0.18006, 0.26352, -0.24341}, {0, 0.18006, 0.26352, -0.24341},
{10, 0.18066, 0.26589, -0.25479}, {10, 0.18066, 0.26589, -0.25479},
...@@ -295,7 +294,7 @@ cmsBool _cmsAdaptMatrixToD50(cmsMAT3* r, const cmsCIExyY* SourceWhitePt) ...@@ -295,7 +294,7 @@ cmsBool _cmsAdaptMatrixToD50(cmsMAT3* r, const cmsCIExyY* SourceWhitePt)
// Build a White point, primary chromas transfer matrix from RGB to CIE XYZ // 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 // 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 // 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: // the alghoritm:
// //
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
...@@ -284,6 +284,8 @@ void FloatXFORM(_cmsTRANSFORM* p, ...@@ -284,6 +284,8 @@ void FloatXFORM(_cmsTRANSFORM* p,
strideIn = 0; strideIn = 0;
strideOut = 0; strideOut = 0;
memset(fIn, 0, sizeof(fIn));
memset(fOut, 0, sizeof(fIn));
for (i = 0; i < LineCount; i++) { for (i = 0; i < LineCount; i++) {
...@@ -348,6 +350,7 @@ void NullFloatXFORM(_cmsTRANSFORM* p, ...@@ -348,6 +350,7 @@ void NullFloatXFORM(_cmsTRANSFORM* p,
strideIn = 0; strideIn = 0;
strideOut = 0; strideOut = 0;
memset(fIn, 0, sizeof(fIn));
for (i = 0; i < LineCount; i++) { for (i = 0; i < LineCount; i++) {
...@@ -385,6 +388,7 @@ void NullXFORM(_cmsTRANSFORM* p, ...@@ -385,6 +388,7 @@ void NullXFORM(_cmsTRANSFORM* p,
strideIn = 0; strideIn = 0;
strideOut = 0; strideOut = 0;
memset(wIn, 0, sizeof(wIn));
for (i = 0; i < LineCount; i++) { for (i = 0; i < LineCount; i++) {
...@@ -422,6 +426,8 @@ void PrecalculatedXFORM(_cmsTRANSFORM* p, ...@@ -422,6 +426,8 @@ void PrecalculatedXFORM(_cmsTRANSFORM* p,
strideIn = 0; strideIn = 0;
strideOut = 0; strideOut = 0;
memset(wIn, 0, sizeof(wIn));
memset(wOut, 0, sizeof(wOut));
for (i = 0; i < LineCount; i++) { for (i = 0; i < LineCount; i++) {
...@@ -483,6 +489,8 @@ void PrecalculatedXFORMGamutCheck(_cmsTRANSFORM* p, ...@@ -483,6 +489,8 @@ void PrecalculatedXFORMGamutCheck(_cmsTRANSFORM* p,
strideIn = 0; strideIn = 0;
strideOut = 0; strideOut = 0;
memset(wIn, 0, sizeof(wIn));
memset(wOut, 0, sizeof(wOut));
for (i = 0; i < LineCount; i++) { for (i = 0; i < LineCount; i++) {
...@@ -790,7 +798,10 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut, ...@@ -790,7 +798,10 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
// Allocate needed memory // Allocate needed memory
_cmsTRANSFORM* p = (_cmsTRANSFORM*)_cmsMallocZero(ContextID, sizeof(_cmsTRANSFORM)); _cmsTRANSFORM* p = (_cmsTRANSFORM*)_cmsMallocZero(ContextID, sizeof(_cmsTRANSFORM));
if (!p) return NULL; if (!p) {
cmsPipelineFree(lut);
return NULL;
}
// Store the proposed pipeline // Store the proposed pipeline
p->Lut = lut; p->Lut = lut;
...@@ -823,7 +834,7 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut, ...@@ -823,7 +834,7 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
p->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat; p->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
p->ToOutputFloat = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, 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) { if (Plugin->OldXform) {
p->OldXform = (_cmsTransformFn) p->xform; p->OldXform = (_cmsTransformFn) p->xform;
p->xform = _cmsTransform2toTransformAdaptor; p->xform = _cmsTransform2toTransformAdaptor;
...@@ -848,7 +859,7 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut, ...@@ -848,7 +859,7 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
if (p ->FromInputFloat == NULL || p ->ToOutputFloat == NULL) { if (p ->FromInputFloat == NULL || p ->ToOutputFloat == NULL) {
cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported raster format"); cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported raster format");
_cmsFree(ContextID, p); cmsDeleteTransform(p);
return NULL; return NULL;
} }
...@@ -870,7 +881,7 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut, ...@@ -870,7 +881,7 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
} }
else { else {
int BytesPerPixelInput; cmsUInt32Number BytesPerPixelInput;
p ->FromInput = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16; p ->FromInput = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16;
p ->ToOutput = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, 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, ...@@ -878,7 +889,7 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
if (p ->FromInput == NULL || p ->ToOutput == NULL) { if (p ->FromInput == NULL || p ->ToOutput == NULL) {
cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported raster format"); cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported raster format");
_cmsFree(ContextID, p); cmsDeleteTransform(p);
return NULL; return NULL;
} }
...@@ -920,13 +931,13 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut, ...@@ -920,13 +931,13 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
} }
static 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 ColorSpaceIn, ColorSpaceOut;
cmsColorSpaceSignature PostColorSpace; cmsColorSpaceSignature PostColorSpace;
int i; cmsUInt32Number i;
if (nProfiles <= 0) return FALSE; if (nProfiles == 0) return FALSE;
if (hProfiles[0] == NULL) return FALSE; if (hProfiles[0] == NULL) return FALSE;
*Input = PostColorSpace = cmsGetColorSpace(hProfiles[0]); *Input = PostColorSpace = cmsGetColorSpace(hProfiles[0]);
...@@ -975,7 +986,7 @@ cmsBool GetXFormColorSpaces(int nProfiles, cmsHPROFILE hProfiles[], cmsColorSpac ...@@ -975,7 +986,7 @@ cmsBool GetXFormColorSpaces(int nProfiles, cmsHPROFILE hProfiles[], cmsColorSpac
static static
cmsBool IsProperColorSpace(cmsColorSpaceSignature Check, cmsUInt32Number dwFormat) cmsBool IsProperColorSpace(cmsColorSpaceSignature Check, cmsUInt32Number dwFormat)
{ {
int Space1 = T_COLORSPACE(dwFormat); int Space1 = (int) T_COLORSPACE(dwFormat);
int Space2 = _cmsLCMScolorSpace(Check); int Space2 = _cmsLCMScolorSpace(Check);
if (Space1 == PT_ANY) return TRUE; if (Space1 == PT_ANY) return TRUE;
...@@ -1231,7 +1242,7 @@ cmsHTRANSFORM CMSEXPORT cmsCreateTransformTHR(cmsContext ContextID, ...@@ -1231,7 +1242,7 @@ cmsHTRANSFORM CMSEXPORT cmsCreateTransformTHR(cmsContext ContextID,
hArray[0] = Input; hArray[0] = Input;
hArray[1] = Output; 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, CMSAPI cmsHTRANSFORM CMSEXPORT cmsCreateTransform(cmsHPROFILE Input,
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
// //
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Version 2.8 // Version 2.9rc3
// //
#ifndef _lcms2_H #ifndef _lcms2_H
...@@ -78,7 +78,7 @@ ...@@ -78,7 +78,7 @@
// #define CMS_USE_CPP_API // #define CMS_USE_CPP_API
// Uncomment this line if you need strict CGATS syntax. Makes CGATS files to // 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 // #define CMS_STRICT_CGATS 1
// Uncomment to get rid of the tables for "half" float support // Uncomment to get rid of the tables for "half" float support
...@@ -87,6 +87,9 @@ ...@@ -87,6 +87,9 @@
// Uncomment to get rid of pthreads/windows dependency // Uncomment to get rid of pthreads/windows dependency
// #define CMS_NO_PTHREADS 1 // #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 ****************************** // ********** End of configuration toggles ******************************
// Needed for streams // Needed for streams
...@@ -104,7 +107,7 @@ extern "C" { ...@@ -104,7 +107,7 @@ extern "C" {
#endif #endif
// Version/release // 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 // I will give the chance of redefining basic types for compilers that are not fully C99 compliant
#ifndef CMS_BASIC_TYPES_ALREADY_DEFINED #ifndef CMS_BASIC_TYPES_ALREADY_DEFINED
...@@ -254,16 +257,21 @@ typedef int cmsBool; ...@@ -254,16 +257,21 @@ typedef int cmsBool;
# define CMSAPI __declspec(dllexport) # define CMSAPI __declspec(dllexport)
# else # else
# define CMSAPI __declspec(dllimport) # define CMSAPI __declspec(dllimport)
# endif # endif
# endif # endif
# else # else
# define CMSEXPORT # define CMSEXPORT
# define CMSAPI # define CMSAPI
# endif # endif
#else #else // not Windows
# define CMSEXPORT # ifdef HAVE_FUNC_ATTRIBUTE_VISIBILITY
# define CMSAPI # define CMSEXPORT
#endif # define CMSAPI __attribute__((visibility("default")))
# else
# define CMSEXPORT
# define CMSAPI
# endif
#endif // CMS_IS_WINDOWS_
#ifdef HasTHREADS #ifdef HasTHREADS
# if HasTHREADS == 1 # if HasTHREADS == 1
...@@ -284,9 +292,9 @@ typedef int cmsBool; ...@@ -284,9 +292,9 @@ typedef int cmsBool;
#endif #endif
// D50 XYZ normalized to Y=1.0 // D50 XYZ normalized to Y=1.0
#define cmsD50X 0.9642 #define cmsD50X 0.9642
#define cmsD50Y 1.0 #define cmsD50Y 1.0
#define cmsD50Z 0.8249 #define cmsD50Z 0.8249
// V4 perceptual black // V4 perceptual black
#define cmsPERCEPTUAL_BLACK_X 0.00336 #define cmsPERCEPTUAL_BLACK_X 0.00336
...@@ -294,8 +302,8 @@ typedef int cmsBool; ...@@ -294,8 +302,8 @@ typedef int cmsBool;
#define cmsPERCEPTUAL_BLACK_Z 0.00287 #define cmsPERCEPTUAL_BLACK_Z 0.00287
// Definitions in ICC spec // Definitions in ICC spec
#define cmsMagicNumber 0x61637370 // 'acsp' #define cmsMagicNumber 0x61637370 // 'acsp'
#define lcmsSignature 0x6c636d73 // 'lcms' #define lcmsSignature 0x6c636d73 // 'lcms'
// Base ICC type definitions // Base ICC type definitions
...@@ -1154,7 +1162,7 @@ typedef struct { ...@@ -1154,7 +1162,7 @@ typedef struct {
cmsCIEXYZ whitePoint; cmsCIEXYZ whitePoint;
cmsFloat64Number Yb; cmsFloat64Number Yb;
cmsFloat64Number La; cmsFloat64Number La;
int surround; cmsUInt32Number surround;
cmsFloat64Number D_value; cmsFloat64Number D_value;
} cmsViewingConditions; } cmsViewingConditions;
...@@ -1182,16 +1190,16 @@ typedef struct { ...@@ -1182,16 +1190,16 @@ typedef struct {
// The internal representation is none of your business. // The internal representation is none of your business.
typedef struct _cms_curve_struct cmsToneCurve; 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 cmsBuildParametricToneCurve(cmsContext ContextID, cmsInt32Number Type, const cmsFloat64Number Params[]);
CMSAPI cmsToneCurve* CMSEXPORT cmsBuildGamma(cmsContext ContextID, cmsFloat64Number Gamma); 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 cmsToneCurve* CMSEXPORT cmsBuildTabulatedToneCurveFloat(cmsContext ContextID, cmsUInt32Number nEntries, const cmsFloat32Number values[]);
CMSAPI void CMSEXPORT cmsFreeToneCurve(cmsToneCurve* Curve); CMSAPI void CMSEXPORT cmsFreeToneCurve(cmsToneCurve* Curve);
CMSAPI void CMSEXPORT cmsFreeToneCurveTriple(cmsToneCurve* Curve[3]); CMSAPI void CMSEXPORT cmsFreeToneCurveTriple(cmsToneCurve* Curve[3]);
CMSAPI cmsToneCurve* CMSEXPORT cmsDupToneCurve(const cmsToneCurve* Src); CMSAPI cmsToneCurve* CMSEXPORT cmsDupToneCurve(const cmsToneCurve* Src);
CMSAPI cmsToneCurve* CMSEXPORT cmsReverseToneCurve(const cmsToneCurve* InGamma); 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 cmsToneCurve* CMSEXPORT cmsJoinToneCurve(cmsContext ContextID, const cmsToneCurve* X, const cmsToneCurve* Y, cmsUInt32Number nPoints);
CMSAPI cmsBool CMSEXPORT cmsSmoothToneCurve(cmsToneCurve* Tab, cmsFloat64Number lambda); CMSAPI cmsBool CMSEXPORT cmsSmoothToneCurve(cmsToneCurve* Tab, cmsFloat64Number lambda);
CMSAPI cmsFloat32Number CMSEXPORT cmsEvalToneCurveFloat(const cmsToneCurve* Curve, cmsFloat32Number v); CMSAPI cmsFloat32Number CMSEXPORT cmsEvalToneCurveFloat(const cmsToneCurve* Curve, cmsFloat32Number v);
...@@ -1236,7 +1244,7 @@ CMSAPI cmsBool CMSEXPORT cmsPipelineSetSaveAs8bitsFlag(cmsPipeline* lu ...@@ -1236,7 +1244,7 @@ CMSAPI cmsBool CMSEXPORT cmsPipelineSetSaveAs8bitsFlag(cmsPipeline* lu
// Where to place/locate the stages in the pipeline chain // Where to place/locate the stages in the pipeline chain
typedef enum { cmsAT_BEGIN, cmsAT_END } cmsStageLoc; 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); 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 // 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 ...@@ -1459,7 +1467,7 @@ CMSAPI cmsBool CMSEXPORT cmsLinkTag(cmsHPROFILE hProfile, cmsTagSignat
CMSAPI cmsTagSignature CMSEXPORT cmsTagLinkedTo(cmsHPROFILE hProfile, cmsTagSignature sig); CMSAPI cmsTagSignature CMSEXPORT cmsTagLinkedTo(cmsHPROFILE hProfile, cmsTagSignature sig);
// Read and write raw data // 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); CMSAPI cmsBool CMSEXPORT cmsWriteRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, const void* data, cmsUInt32Number Size);
// Access header data // Access header data
...@@ -1550,7 +1558,7 @@ CMSAPI cmsBool CMSEXPORT cmsCloseIOhandler(cmsIOHANDLER* io); ...@@ -1550,7 +1558,7 @@ CMSAPI cmsBool CMSEXPORT cmsCloseIOhandler(cmsIOHANDLER* io);
CMSAPI cmsBool CMSEXPORT cmsMD5computeID(cmsHPROFILE hProfile); 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 cmsOpenProfileFromFile(const char *ICCProfile, const char *sAccess);
CMSAPI cmsHPROFILE CMSEXPORT cmsOpenProfileFromFileTHR(cmsContext ContextID, 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) ...@@ -1610,21 +1618,21 @@ CMSAPI cmsHPROFILE CMSEXPORT cmsCreate_sRGBProfileTHR(cmsContext ContextID)
CMSAPI cmsHPROFILE CMSEXPORT cmsCreate_sRGBProfile(void); CMSAPI cmsHPROFILE CMSEXPORT cmsCreate_sRGBProfile(void);
CMSAPI cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfileTHR(cmsContext ContextID, CMSAPI cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfileTHR(cmsContext ContextID,
int nLUTPoints, cmsUInt32Number nLUTPoints,
cmsFloat64Number Bright, cmsFloat64Number Bright,
cmsFloat64Number Contrast, cmsFloat64Number Contrast,
cmsFloat64Number Hue, cmsFloat64Number Hue,
cmsFloat64Number Saturation, cmsFloat64Number Saturation,
int TempSrc, cmsUInt32Number TempSrc,
int TempDest); cmsUInt32Number TempDest);
CMSAPI cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfile(int nLUTPoints, CMSAPI cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfile(cmsUInt32Number nLUTPoints,
cmsFloat64Number Bright, cmsFloat64Number Bright,
cmsFloat64Number Contrast, cmsFloat64Number Contrast,
cmsFloat64Number Hue, cmsFloat64Number Hue,
cmsFloat64Number Saturation, cmsFloat64Number Saturation,
int TempSrc, cmsUInt32Number TempSrc,
int TempDest); cmsUInt32Number TempDest);
CMSAPI cmsHPROFILE CMSEXPORT cmsCreateNULLProfileTHR(cmsContext ContextID); CMSAPI cmsHPROFILE CMSEXPORT cmsCreateNULLProfileTHR(cmsContext ContextID);
CMSAPI cmsHPROFILE CMSEXPORT cmsCreateNULLProfile(void); CMSAPI cmsHPROFILE CMSEXPORT cmsCreateNULLProfile(void);
...@@ -1666,7 +1674,7 @@ CMSAPI cmsUInt32Number CMSEXPORT cmsGetSupportedIntentsTHR(cmsContext ContextID ...@@ -1666,7 +1674,7 @@ CMSAPI cmsUInt32Number CMSEXPORT cmsGetSupportedIntentsTHR(cmsContext ContextID
#define cmsFLAGS_BLACKPOINTCOMPENSATION 0x2000 #define cmsFLAGS_BLACKPOINTCOMPENSATION 0x2000
#define cmsFLAGS_NOWHITEONWHITEFIXUP 0x0004 // Don't fix scum dot #define cmsFLAGS_NOWHITEONWHITEFIXUP 0x0004 // Don't fix scum dot
#define cmsFLAGS_HIGHRESPRECALC 0x0400 // Use more memory to give better accurancy #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 // For devicelink creation
#define cmsFLAGS_8BITS_DEVICELINK 0x0008 // Create 8 bits devicelinks #define cmsFLAGS_8BITS_DEVICELINK 0x0008 // Create 8 bits devicelinks
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
...@@ -106,7 +106,7 @@ ...@@ -106,7 +106,7 @@
// Maximum of channels for internal pipeline evaluation // Maximum of channels for internal pipeline evaluation
#define MAX_STAGE_CHANNELS 128 #define MAX_STAGE_CHANNELS 128
// Unused parameter warning supression // Unused parameter warning suppression
#define cmsUNUSED_PARAMETER(x) ((void)x) #define cmsUNUSED_PARAMETER(x) ((void)x)
// The specification for "inline" is section 6.7.4 of the C99 standard (ISO/IEC 9899:1999). // The specification for "inline" is section 6.7.4 of the C99 standard (ISO/IEC 9899:1999).
...@@ -125,8 +125,16 @@ ...@@ -125,8 +125,16 @@
# ifndef vsnprintf # ifndef vsnprintf
# define vsnprintf _vsnprintf # define vsnprintf _vsnprintf
# endif # 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 // A fast way to convert from/to 16 <-> 8 bits
#define FROM_8_TO_16(rgb) (cmsUInt16Number) ((((cmsUInt16Number) (rgb)) << 8)|(rgb)) #define FROM_8_TO_16(rgb) (cmsUInt16Number) ((((cmsUInt16Number) (rgb)) << 8)|(rgb))
...@@ -201,19 +209,48 @@ cmsINLINE cmsUInt16Number _cmsQuickSaturateWord(cmsFloat64Number d) ...@@ -201,19 +209,48 @@ cmsINLINE cmsUInt16Number _cmsQuickSaturateWord(cmsFloat64Number d)
return _cmsQuickFloorWord(d); return _cmsQuickFloorWord(d);
} }
// Test bed entry points---------------------------------------------------------------
#define CMSCHECKPOINT CMSAPI
// Pthread support -------------------------------------------------------------------- // Pthread support --------------------------------------------------------------------
#ifndef CMS_NO_PTHREADS #ifndef CMS_NO_PTHREADS
// This is the threading support. Unfortunately, it has to be platform-dependent because // This is the threading support. Unfortunately, it has to be platform-dependent because
// windows does not support pthreads. // windows does not support pthreads.
#ifdef CMS_IS_WINDOWS_ #ifdef CMS_IS_WINDOWS_
#define WIN32_LEAN_AND_MEAN 1 #define WIN32_LEAN_AND_MEAN 1
#include <windows.h> #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/ // From: http://locklessinc.com/articles/pthreads_on_windows/
// The pthreads API has an initialization macro that has no correspondence to anything in // 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, // the windows API. By investigating the internal definition of the critical section type,
...@@ -235,14 +272,30 @@ cmsINLINE cmsUInt16Number _cmsQuickSaturateWord(cmsFloat64Number d) ...@@ -235,14 +272,30 @@ cmsINLINE cmsUInt16Number _cmsQuickSaturateWord(cmsFloat64Number d)
typedef CRITICAL_SECTION _cmsMutex; typedef CRITICAL_SECTION _cmsMutex;
#define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG) -1,-1,0,0,0,0}
#ifdef _MSC_VER #ifdef _MSC_VER
# if (_MSC_VER >= 1800) # if (_MSC_VER >= 1800)
# pragma warning(disable : 26135) # pragma warning(disable : 26135)
# endif # endif
#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) cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
{ {
EnterCriticalSection(m); EnterCriticalSection(m);
...@@ -478,7 +531,7 @@ struct _cmsContext_struct { ...@@ -478,7 +531,7 @@ struct _cmsContext_struct {
void* chunks[MemoryClientMax]; // array of pointers to client chunks. Memory itself is hold in the suballocator. void* chunks[MemoryClientMax]; // array of pointers to client chunks. Memory itself is hold in the suballocator.
// If NULL, then it reverts to global Context0 // 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. // 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 ...@@ -800,10 +853,10 @@ void _cmsTagSignature2String(char String[5], cmsTagSignature sig
// Interpolation --------------------------------------------------------------------------------------------------------- // Interpolation ---------------------------------------------------------------------------------------------------------
cmsInterpParams* _cmsComputeInterpParams(cmsContext ContextID, int nSamples, int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags); CMSCHECKPOINT cmsInterpParams* CMSEXPORT _cmsComputeInterpParams(cmsContext ContextID, cmsUInt32Number nSamples, cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags);
cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags); cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags);
void _cmsFreeInterpParams(cmsInterpParams* p); CMSCHECKPOINT void CMSEXPORT _cmsFreeInterpParams(cmsInterpParams* p);
cmsBool _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p); cmsBool _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p);
// Curves ---------------------------------------------------------------------------------------------------------------- // Curves ----------------------------------------------------------------------------------------------------------------
...@@ -853,20 +906,20 @@ struct _cmsStage_struct { ...@@ -853,20 +906,20 @@ struct _cmsStage_struct {
// Special Stages (cannot be saved) // Special Stages (cannot be saved)
cmsStage* _cmsStageAllocLab2XYZ(cmsContext ContextID); CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocLab2XYZ(cmsContext ContextID);
cmsStage* _cmsStageAllocXYZ2Lab(cmsContext ContextID); CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocXYZ2Lab(cmsContext ContextID);
cmsStage* _cmsStageAllocLabPrelin(cmsContext ContextID); cmsStage* _cmsStageAllocLabPrelin(cmsContext ContextID);
cmsStage* _cmsStageAllocLabV2ToV4(cmsContext ContextID); CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocLabV2ToV4(cmsContext ContextID);
cmsStage* _cmsStageAllocLabV2ToV4curves(cmsContext ContextID); cmsStage* _cmsStageAllocLabV2ToV4curves(cmsContext ContextID);
cmsStage* _cmsStageAllocLabV4ToV2(cmsContext ContextID); CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocLabV4ToV2(cmsContext ContextID);
cmsStage* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS); CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS);
cmsStage* _cmsStageAllocIdentityCurves(cmsContext ContextID, int nChannels); CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocIdentityCurves(cmsContext ContextID, cmsUInt32Number nChannels);
cmsStage* _cmsStageAllocIdentityCLut(cmsContext ContextID, int nChan); CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocIdentityCLut(cmsContext ContextID, cmsUInt32Number nChan);
cmsStage* _cmsStageNormalizeFromLabFloat(cmsContext ContextID); cmsStage* _cmsStageNormalizeFromLabFloat(cmsContext ContextID);
cmsStage* _cmsStageNormalizeFromXyzFloat(cmsContext ContextID); cmsStage* _cmsStageNormalizeFromXyzFloat(cmsContext ContextID);
cmsStage* _cmsStageNormalizeToLabFloat(cmsContext ContextID); cmsStage* _cmsStageNormalizeToLabFloat(cmsContext ContextID);
cmsStage* _cmsStageNormalizeToXyzFloat(cmsContext ContextID); cmsStage* _cmsStageNormalizeToXyzFloat(cmsContext ContextID);
cmsStage* _cmsStageClipNegatives(cmsContext ContextID, int nChannels); cmsStage* _cmsStageClipNegatives(cmsContext ContextID, cmsUInt32Number nChannels);
// For curve set only // For curve set only
...@@ -901,9 +954,9 @@ struct _cmsPipeline_struct { ...@@ -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 // 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. // of the LUTS, since ownership of original is up to the profile. The user should free allocated resources.
cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent); CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadInputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent);
cmsPipeline* _cmsReadOutputLUT(cmsHPROFILE hProfile, int Intent); CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadOutputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent);
cmsPipeline* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent); CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent);
// Special values // Special values
cmsBool _cmsReadMediaWhitePoint(cmsCIEXYZ* Dest, cmsHPROFILE hProfile); cmsBool _cmsReadMediaWhitePoint(cmsCIEXYZ* Dest, cmsHPROFILE hProfile);
...@@ -928,8 +981,9 @@ cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfil ...@@ -928,8 +981,9 @@ cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfil
// LUT optimization ------------------------------------------------------------------------------------------------ // LUT optimization ------------------------------------------------------------------------------------------------
cmsUInt16Number _cmsQuantizeVal(cmsFloat64Number i, int MaxSamples); CMSCHECKPOINT cmsUInt16Number CMSEXPORT _cmsQuantizeVal(cmsFloat64Number i, cmsUInt32Number MaxSamples);
int _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags);
cmsUInt32Number _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags);
cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space, cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
cmsUInt16Number **White, cmsUInt16Number **White,
...@@ -938,7 +992,7 @@ cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space, ...@@ -938,7 +992,7 @@ cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
cmsBool _cmsOptimizePipeline(cmsContext ContextID, cmsBool _cmsOptimizePipeline(cmsContext ContextID,
cmsPipeline** Lut, cmsPipeline** Lut,
int Intent, cmsUInt32Number Intent,
cmsUInt32Number* InputFormat, cmsUInt32Number* InputFormat,
cmsUInt32Number* OutputFormat, cmsUInt32Number* OutputFormat,
cmsUInt32Number* dwFlags ); cmsUInt32Number* dwFlags );
...@@ -962,17 +1016,17 @@ cmsPipeline* _cmsCreateGamutCheckPipeline(cmsContext ContextID, ...@@ -962,17 +1016,17 @@ cmsPipeline* _cmsCreateGamutCheckPipeline(cmsContext ContextID,
cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type); cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type);
cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type); cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type);
cmsFormatter _cmsGetFormatter(cmsContext ContextID, CMSCHECKPOINT cmsFormatter CMSEXPORT _cmsGetFormatter(cmsContext ContextID,
cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8 cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8
cmsFormatterDirection Dir, cmsFormatterDirection Dir,
cmsUInt32Number dwFlags); cmsUInt32Number dwFlags);
#ifndef CMS_NO_HALF_SUPPORT #ifndef CMS_NO_HALF_SUPPORT
// Half float // Half float
cmsFloat32Number _cmsHalf2Float(cmsUInt16Number h); CMSCHECKPOINT cmsFloat32Number CMSEXPORT _cmsHalf2Float(cmsUInt16Number h);
cmsUInt16Number _cmsFloat2Half(cmsFloat32Number flt); CMSCHECKPOINT cmsUInt16Number CMSEXPORT _cmsFloat2Half(cmsFloat32Number flt);
#endif #endif
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// //
// Little Color Management System // 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 // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
...@@ -347,7 +347,7 @@ typedef struct { ...@@ -347,7 +347,7 @@ typedef struct {
// Parametric curves. A negative type means same function but analytically inverted. Max. number of params is 10 // 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); typedef cmsFloat64Number (* cmsParametricCurveEvaluator)(cmsInt32Number Type, const cmsFloat64Number Params[10], cmsFloat64Number R);
// Plug-in may implement an arbitrary number of parametric curves // Plug-in may implement an arbitrary number of parametric curves
...@@ -457,7 +457,7 @@ typedef struct { ...@@ -457,7 +457,7 @@ typedef struct {
cmsUInt32Number nSupportedTypes; // In how many types this tag can come (MAX_TYPES_IN_LCMS_PLUGIN maximum) cmsUInt32Number nSupportedTypes; // In how many types this tag can come (MAX_TYPES_IN_LCMS_PLUGIN maximum)
cmsTagTypeSignature SupportedTypes[MAX_TYPES_IN_LCMS_PLUGIN]; cmsTagTypeSignature SupportedTypes[MAX_TYPES_IN_LCMS_PLUGIN];
// For writting // For writing
cmsTagTypeSignature (* DecideType)(cmsFloat64Number ICCVersion, const void *Data); cmsTagTypeSignature (* DecideType)(cmsFloat64Number ICCVersion, const void *Data);
} cmsTagDescriptor; } cmsTagDescriptor;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册