summaryrefslogtreecommitdiff
path: root/thirdparty/liblcms2/src
diff options
context:
space:
mode:
authorMatthieu Darbois <mayeut@users.noreply.github.com>2016-04-30 17:58:04 +0200
committerMatthieu Darbois <mayeut@users.noreply.github.com>2016-04-30 17:58:04 +0200
commit9a20f8e8d1a91bd032e81ac53bf9a48dbb92bc29 (patch)
treed5387a97517acf7e8f5880a9f44bda772a0022dd /thirdparty/liblcms2/src
parent72deb588cbc8d5f56f8b0db3a2d120913e792cb8 (diff)
Update lcms (#544)
Update to mm2/Little-CMS@0e8234e090d6aab33f90e2eb0296f30aa0705e57
Diffstat (limited to 'thirdparty/liblcms2/src')
-rw-r--r--thirdparty/liblcms2/src/cmsalpha.c481
-rw-r--r--thirdparty/liblcms2/src/cmscam02.c2
-rw-r--r--thirdparty/liblcms2/src/cmscgats.c28
-rw-r--r--thirdparty/liblcms2/src/cmscnvrt.c27
-rw-r--r--thirdparty/liblcms2/src/cmserr.c9
-rw-r--r--thirdparty/liblcms2/src/cmsgmt.c2
-rw-r--r--thirdparty/liblcms2/src/cmshalf.c2
-rw-r--r--thirdparty/liblcms2/src/cmsintrp.c6
-rw-r--r--thirdparty/liblcms2/src/cmsio0.c66
-rw-r--r--thirdparty/liblcms2/src/cmsio1.c20
-rw-r--r--thirdparty/liblcms2/src/cmslut.c25
-rw-r--r--thirdparty/liblcms2/src/cmsmd5.c2
-rw-r--r--thirdparty/liblcms2/src/cmsmtrx.c2
-rw-r--r--thirdparty/liblcms2/src/cmsnamed.c78
-rw-r--r--thirdparty/liblcms2/src/cmsopt.c259
-rw-r--r--thirdparty/liblcms2/src/cmspack.c337
-rw-r--r--thirdparty/liblcms2/src/cmspcs.c11
-rw-r--r--thirdparty/liblcms2/src/cmsplugin.c42
-rw-r--r--thirdparty/liblcms2/src/cmsps2.c15
-rw-r--r--thirdparty/liblcms2/src/cmssamp.c29
-rw-r--r--thirdparty/liblcms2/src/cmssm.c7
-rw-r--r--thirdparty/liblcms2/src/cmstypes.c62
-rw-r--r--thirdparty/liblcms2/src/cmsvirt.c41
-rw-r--r--thirdparty/liblcms2/src/cmswtpnt.c2
-rw-r--r--thirdparty/liblcms2/src/cmsxform.c492
-rw-r--r--thirdparty/liblcms2/src/lcms2.def341
-rw-r--r--thirdparty/liblcms2/src/lcms2_internal.h55
27 files changed, 1523 insertions, 920 deletions
diff --git a/thirdparty/liblcms2/src/cmsalpha.c b/thirdparty/liblcms2/src/cmsalpha.c
new file mode 100644
index 00000000..904ce715
--- /dev/null
+++ b/thirdparty/liblcms2/src/cmsalpha.c
@@ -0,0 +1,481 @@
+//---------------------------------------------------------------------------------
+//
+// Little Color Management System
+// Copyright (c) 1998-2016 Marti Maria Saguer
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the Software
+// is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//---------------------------------------------------------------------------------
+//
+
+#include "lcms2_internal.h"
+
+
+// Alpha copy ------------------------------------------------------------------------------------------------------------------
+
+// Floor to byte, taking care of saturation
+cmsINLINE cmsUInt8Number _cmsQuickSaturateByte(cmsFloat64Number d)
+{
+ d += 0.5;
+ if (d <= 0) return 0;
+ if (d >= 255.0) return 255;
+
+ return (cmsUInt8Number) _cmsQuickFloorWord(d);
+}
+
+
+// Return the size in bytes of a given formatter
+static
+int trueBytesSize(cmsUInt32Number Format)
+{
+ int fmt_bytes = T_BYTES(Format);
+
+ // For double, the T_BYTES field returns zero
+ if (fmt_bytes == 0)
+ return sizeof(double);
+
+ // Otherwise, it is already correct for all formats
+ return fmt_bytes;
+}
+
+
+// Several format converters
+
+typedef void(*cmsFormatterAlphaFn)(void* dst, const void* src);
+
+
+// From 8
+
+static
+void copy8(void* dst, const void* src)
+{
+ memmove(dst, src, 1);
+}
+
+static
+void from8to16(void* dst, const void* src)
+{
+ cmsUInt8Number n = *(cmsUInt8Number*)src;
+ *(cmsUInt16Number*) dst = FROM_8_TO_16(n);
+}
+
+static
+void from8toFLT(void* dst, const void* src)
+{
+ *(cmsFloat32Number*)dst = (*(cmsUInt8Number*)src) / 255.0f;
+}
+
+static
+void from8toDBL(void* dst, const void* src)
+{
+ *(cmsFloat64Number*)dst = (*(cmsUInt8Number*)src) / 255.0;
+}
+
+static
+void from8toHLF(void* dst, const void* src)
+{
+ cmsFloat32Number n = (*(cmsUInt8Number*)src) / 255.0f;
+ *(cmsUInt16Number*)dst = _cmsFloat2Half(n);
+}
+
+// From 16
+
+static
+void from16to8(void* dst, const void* src)
+{
+ cmsUInt16Number n = *(cmsUInt16Number*)src;
+ *(cmsUInt8Number*) dst = FROM_16_TO_8(n);
+}
+
+static
+void copy16(void* dst, const void* src)
+{
+ memmove(dst, src, 2);
+}
+
+void from16toFLT(void* dst, const void* src)
+{
+ *(cmsFloat32Number*)dst = (*(cmsUInt16Number*)src) / 65535.0f;
+}
+
+void from16toDBL(void* dst, const void* src)
+{
+ *(cmsFloat64Number*)dst = (*(cmsUInt16Number*)src) / 65535.0f;
+}
+
+static
+void from16toHLF(void* dst, const void* src)
+{
+ cmsFloat32Number n = (*(cmsUInt16Number*)src) / 65535.0f;
+ *(cmsUInt16Number*)dst = _cmsFloat2Half(n);
+}
+
+// From Float
+
+static
+void fromFLTto8(void* dst, const void* src)
+{
+ cmsFloat32Number n = *(cmsFloat32Number*)src;
+ *(cmsUInt8Number*)dst = _cmsQuickSaturateByte(n * 255.0f);
+}
+
+static
+void fromFLTto16(void* dst, const void* src)
+{
+ cmsFloat32Number n = *(cmsFloat32Number*)src;
+ *(cmsUInt16Number*)dst = _cmsQuickSaturateWord(n * 65535.0f);
+}
+
+static
+void copy32(void* dst, const void* src)
+{
+ memmove(dst, src, sizeof(cmsFloat32Number));
+}
+
+static
+void fromFLTtoDBL(void* dst, const void* src)
+{
+ cmsFloat32Number n = *(cmsFloat32Number*)src;
+ *(cmsFloat64Number*)dst = (cmsFloat64Number)n;
+}
+
+static
+void fromFLTtoHLF(void* dst, const void* src)
+{
+ cmsFloat32Number n = *(cmsFloat32Number*)src;
+ *(cmsUInt16Number*)dst = _cmsFloat2Half(n);
+}
+
+
+// From HALF
+
+static
+void fromHLFto8(void* dst, const void* src)
+{
+ cmsFloat32Number n = _cmsHalf2Float(*(cmsUInt16Number*)src);
+ *(cmsUInt8Number*)dst = _cmsQuickSaturateByte(n * 255.0f);
+}
+
+static
+void fromHLFto16(void* dst, const void* src)
+{
+ cmsFloat32Number n = _cmsHalf2Float(*(cmsUInt16Number*)src);
+ *(cmsUInt16Number*)dst = _cmsQuickSaturateWord(n * 65535.0f);
+}
+
+static
+void fromHLFtoFLT(void* dst, const void* src)
+{
+ *(cmsFloat32Number*)dst = _cmsHalf2Float(*(cmsUInt16Number*)src);
+}
+
+static
+void fromHLFtoDBL(void* dst, const void* src)
+{
+ *(cmsFloat64Number*)dst = (cmsFloat64Number)_cmsHalf2Float(*(cmsUInt16Number*)src);
+}
+
+// From double
+static
+void fromDBLto8(void* dst, const void* src)
+{
+ cmsFloat64Number n = *(cmsFloat64Number*)src;
+ *(cmsUInt8Number*)dst = _cmsQuickSaturateByte(n * 255.0);
+}
+
+static
+void fromDBLto16(void* dst, const void* src)
+{
+ cmsFloat64Number n = *(cmsFloat64Number*)src;
+ *(cmsUInt16Number*)dst = _cmsQuickSaturateWord(n * 65535.0f);
+}
+
+static
+void fromDBLtoFLT(void* dst, const void* src)
+{
+ cmsFloat64Number n = *(cmsFloat64Number*)src;
+ *(cmsFloat32Number*)dst = (cmsFloat32Number) n;
+}
+
+static
+void fromDBLtoHLF(void* dst, const void* src)
+{
+ cmsFloat32Number n = (cmsFloat32Number) *(cmsFloat64Number*)src;
+ *(cmsUInt16Number*)dst = _cmsFloat2Half(n);
+}
+
+static
+void copy64(void* dst, const void* src)
+{
+ memmove(dst, src, sizeof(cmsFloat64Number));
+}
+
+
+// Returns the position (x or y) of the formatter in the table of functions
+static
+int FormatterPos(cmsUInt32Number frm)
+{
+ int 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
+
+}
+
+// Obtains a alpha-to-alpha funmction formatter
+static
+cmsFormatterAlphaFn _cmsGetFormatterAlpha(cmsContext id, cmsUInt32Number in, cmsUInt32Number out)
+{
+static cmsFormatterAlphaFn FormattersAlpha[5][5] = {
+
+ /* from 8 */ { copy8, from8to16, from8toHLF, from8toFLT, from8toDBL },
+ /* from 16*/ { from16to8, copy16, from16toHLF, from16toFLT, from16toDBL },
+ /* from HLF*/ { fromHLFto8, fromHLFto16, copy16, fromHLFtoFLT, fromHLFtoDBL },
+ /* from FLT*/ { fromFLTto8, fromFLTto16, fromFLTtoHLF, copy32, fromFLTtoDBL },
+ /* from DBL*/ { fromDBLto8, fromDBLto16, fromDBLtoHLF, fromDBLtoFLT, copy64 }};
+
+ int in_n = FormatterPos(in);
+ int out_n = FormatterPos(out);
+
+ if (in_n < 0 || out_n < 0 || in_n > 4 || out_n > 4) {
+
+ cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized alpha channel width");
+ return NULL;
+ }
+
+ return FormattersAlpha[in_n][out_n];
+}
+
+
+
+// This function computes the distance from each component to the next one in bytes.
+static
+void ComputeIncrementsForChunky(cmsUInt32Number Format,
+ cmsUInt32Number ComponentStartingOrder[],
+ cmsUInt32Number ComponentPointerIncrements[])
+{
+ cmsUInt32Number channels[cmsMAXCHANNELS];
+ int extra = T_EXTRA(Format);
+ int nchannels = T_CHANNELS(Format);
+ int total_chans = nchannels + extra;
+ int i;
+ int channelSize = trueBytesSize(Format);
+ int pixelSize = channelSize * total_chans;
+
+ // Sanity check
+ if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS)
+ return;
+
+ memset(channels, 0, sizeof(channels));
+
+ // Separation is independent of starting point and only depends on channel size
+ for (i = 0; i < extra; i++)
+ ComponentPointerIncrements[i] = pixelSize;
+
+ // Handle do swap
+ for (i = 0; i < total_chans; i++)
+ {
+ if (T_DOSWAP(Format)) {
+ channels[i] = total_chans - i - 1;
+ }
+ else {
+ channels[i] = i;
+ }
+ }
+
+ // Handle swap first (ROL of positions), example CMYK -> KCMY | 0123 -> 3012
+ if (T_SWAPFIRST(Format) && total_chans > 1) {
+
+ cmsUInt32Number tmp = channels[0];
+ for (i = 0; i < total_chans-1; i++)
+ channels[i] = channels[i + 1];
+
+ channels[total_chans - 1] = tmp;
+ }
+
+ // Handle size
+ if (channelSize > 1)
+ for (i = 0; i < total_chans; i++) {
+ channels[i] *= channelSize;
+ }
+
+ for (i = 0; i < extra; i++)
+ ComponentStartingOrder[i] = channels[i + nchannels];
+}
+
+
+
+// On planar configurations, the distance is the stride added to any non-negative
+static
+void ComputeIncrementsForPlanar(cmsUInt32Number Format,
+ cmsUInt32Number BytesPerPlane,
+ cmsUInt32Number ComponentStartingOrder[],
+ cmsUInt32Number ComponentPointerIncrements[])
+{
+ cmsUInt32Number channels[cmsMAXCHANNELS];
+ int extra = T_EXTRA(Format);
+ int nchannels = T_CHANNELS(Format);
+ int total_chans = nchannels + extra;
+ int i;
+ int channelSize = trueBytesSize(Format);
+
+ // Sanity check
+ if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS)
+ return;
+
+ memset(channels, 0, sizeof(channels));
+
+ // Separation is independent of starting point and only depends on channel size
+ for (i = 0; i < extra; i++)
+ ComponentPointerIncrements[i] = channelSize;
+
+ // Handle do swap
+ for (i = 0; i < total_chans; i++)
+ {
+ if (T_DOSWAP(Format)) {
+ channels[i] = total_chans - i - 1;
+ }
+ else {
+ channels[i] = i;
+ }
+ }
+
+ // Handle swap first (ROL of positions), example CMYK -> KCMY | 0123 -> 3012
+ if (T_SWAPFIRST(Format) && total_chans > 0) {
+
+ cmsUInt32Number tmp = channels[0];
+ for (i = 0; i < total_chans - 1; i++)
+ channels[i] = channels[i + 1];
+
+ channels[total_chans - 1] = tmp;
+ }
+
+ // Handle size
+ for (i = 0; i < total_chans; i++) {
+ channels[i] *= BytesPerPlane;
+ }
+
+ for (i = 0; i < extra; i++)
+ ComponentStartingOrder[i] = channels[i + nchannels];
+}
+
+
+
+// Dispatcher por chunky and planar RGB
+static
+void ComputeComponentIncrements(cmsUInt32Number Format,
+ cmsUInt32Number BytesPerPlane,
+ cmsUInt32Number ComponentStartingOrder[],
+ cmsUInt32Number ComponentPointerIncrements[])
+{
+ if (T_PLANAR(Format)) {
+
+ ComputeIncrementsForPlanar(Format, BytesPerPlane, ComponentStartingOrder, ComponentPointerIncrements);
+ }
+ else {
+ ComputeIncrementsForChunky(Format, ComponentStartingOrder, ComponentPointerIncrements);
+ }
+
+}
+
+
+
+// Handles extra channels copying alpha if requested by the flags
+void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,
+ void* out,
+ cmsUInt32Number PixelsPerLine,
+ cmsUInt32Number LineCount,
+ const cmsStride* Stride)
+{
+ size_t i, j, k;
+ cmsUInt32Number nExtra;
+ cmsUInt32Number SourceStartingOrder[cmsMAXCHANNELS];
+ cmsUInt32Number SourceIncrements[cmsMAXCHANNELS];
+ cmsUInt32Number DestStartingOrder[cmsMAXCHANNELS];
+ cmsUInt32Number DestIncrements[cmsMAXCHANNELS];
+ cmsUInt32Number SourceStrideIncrements[cmsMAXCHANNELS];
+ cmsUInt32Number DestStrideIncrements[cmsMAXCHANNELS];
+
+ cmsUInt8Number* SourcePtr[cmsMAXCHANNELS];
+ cmsUInt8Number* DestPtr[cmsMAXCHANNELS];
+
+ cmsFormatterAlphaFn copyValueFn;
+
+ // Make sure we need some copy
+ if (!(p->dwOriginalFlags & cmsFLAGS_COPY_ALPHA))
+ return;
+
+ // Make sure we have same number of alpha channels. If not, just return as this should be checked at transform creation time.
+ nExtra = T_EXTRA(p->InputFormat);
+ if (nExtra != T_EXTRA(p->OutputFormat))
+ return;
+
+ // Anything to do?
+ if (nExtra == 0)
+ return;
+
+ // Compute the increments
+ ComputeComponentIncrements(p->InputFormat, Stride->BytesPerPlaneIn, SourceStartingOrder, SourceIncrements);
+ ComputeComponentIncrements(p->OutputFormat, Stride->BytesPerPlaneOut, DestStartingOrder, DestIncrements);
+
+ // Check for conversions 8, 16, half, float, dbl
+ copyValueFn = _cmsGetFormatterAlpha(p->ContextID, p->InputFormat, p->OutputFormat);
+
+ memset(SourceStrideIncrements, 0, sizeof(SourceStrideIncrements));
+ memset(DestStrideIncrements, 0, sizeof(DestStrideIncrements));
+
+ // The loop itself
+ for (i = 0; i < LineCount; i++) {
+
+ // Prepare pointers for the loop
+ for (j = 0; j < nExtra; j++) {
+
+ SourcePtr[j] = (cmsUInt8Number*)in + SourceStartingOrder[j] + SourceStrideIncrements[j];
+ DestPtr[j] = (cmsUInt8Number*)out + DestStartingOrder[j] + DestStrideIncrements[j];
+ }
+
+ for (j = 0; j < PixelsPerLine; j++) {
+
+ for (k = 0; k < nExtra; k++) {
+
+ copyValueFn(DestPtr[k], SourcePtr[k]);
+
+ SourcePtr[k] += SourceIncrements[k];
+ DestPtr[k] += DestIncrements[k];
+ }
+ }
+
+ for (j = 0; j < nExtra; j++) {
+
+ SourceStrideIncrements[j] += Stride->BytesPerLineIn;
+ DestStrideIncrements[j] += Stride->BytesPerLineOut;
+ }
+ }
+}
+
diff --git a/thirdparty/liblcms2/src/cmscam02.c b/thirdparty/liblcms2/src/cmscam02.c
index 9d874aa2..5f0ac1f8 100644
--- a/thirdparty/liblcms2/src/cmscam02.c
+++ b/thirdparty/liblcms2/src/cmscam02.c
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2012 Marti Maria Saguer
+// Copyright (c) 1998-2016 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
diff --git a/thirdparty/liblcms2/src/cmscgats.c b/thirdparty/liblcms2/src/cmscgats.c
index 099b07bb..591e4caa 100644
--- a/thirdparty/liblcms2/src/cmscgats.c
+++ b/thirdparty/liblcms2/src/cmscgats.c
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2012 Marti Maria Saguer
+// Copyright (c) 1998-2016 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -48,7 +48,7 @@
// Symbols
typedef enum {
- SNONE,
+ SUNDEFINED,
SINUM, // Integer
SDNUM, // Real
SIDENT, // Identifier
@@ -324,7 +324,7 @@ static const char* PredefinedSampleID[] = {
"XYZ_X", // X component of tristimulus data
"XYZ_Y", // Y component of tristimulus data
"XYZ_Z", // Z component of tristimulus data
- "XYY_X" // x component of chromaticity data
+ "XYY_X", // x component of chromaticity data
"XYY_Y", // y component of chromaticity data
"XYY_CAPY", // Y component of tristimulus data
"LAB_L", // L* component of Lab data
@@ -521,7 +521,7 @@ SYMBOL BinSrchKey(const char *id)
else l = x + 1;
}
- return SNONE;
+ return SUNDEFINED;
}
@@ -706,7 +706,7 @@ void InSymbol(cmsIT8* it8)
key = BinSrchKey(it8->id);
- if (key == SNONE) it8->sy = SIDENT;
+ if (key == SUNDEFINED) it8->sy = SIDENT;
else it8->sy = key;
}
@@ -801,11 +801,11 @@ void InSymbol(cmsIT8* it8)
if (it8 ->sy == SINUM) {
- sprintf(it8->id, "%d", it8->inum);
+ snprintf(it8->id, 127, "%d", it8->inum);
}
else {
- sprintf(it8->id, it8 ->DoubleFormatter, it8->dnum);
+ snprintf(it8->id, 127, it8 ->DoubleFormatter, it8->dnum);
}
k = (int) strlen(it8 ->id);
@@ -1297,7 +1297,7 @@ cmsHANDLE CMSEXPORT cmsIT8Alloc(cmsContext ContextID)
it8->ValidKeywords = NULL;
it8->ValidSampleID = NULL;
- it8 -> sy = SNONE;
+ it8 -> sy = SUNDEFINED;
it8 -> ch = ' ';
it8 -> Source = NULL;
it8 -> inum = 0;
@@ -1363,7 +1363,7 @@ cmsBool CMSEXPORT cmsIT8SetPropertyDbl(cmsHANDLE hIT8, const char* cProp, cmsFlo
cmsIT8* it8 = (cmsIT8*) hIT8;
char Buffer[1024];
- sprintf(Buffer, it8->DoubleFormatter, Val);
+ snprintf(Buffer, 1023, it8->DoubleFormatter, Val);
return AddToList(it8, &GetTable(it8)->HeaderList, cProp, NULL, Buffer, WRITE_UNCOOKED) != NULL;
}
@@ -1373,7 +1373,7 @@ cmsBool CMSEXPORT cmsIT8SetPropertyHex(cmsHANDLE hIT8, const char* cProp, cmsUIn
cmsIT8* it8 = (cmsIT8*) hIT8;
char Buffer[1024];
- sprintf(Buffer, "%u", Val);
+ snprintf(Buffer, 1023, "%u", Val);
return AddToList(it8, &GetTable(it8)->HeaderList, cProp, NULL, Buffer, WRITE_HEXADECIMAL) != NULL;
}
@@ -2516,8 +2516,10 @@ int LocateSample(cmsIT8* it8, const char* cSample)
for (i=0; i < t->nSamples; i++) {
fld = GetDataFormat(it8, i);
- if (cmsstrcasecmp(fld, cSample) == 0)
- return i;
+ if (fld != NULL) {
+ if (cmsstrcasecmp(fld, cSample) == 0)
+ return i;
+ }
}
return -1;
@@ -2575,7 +2577,7 @@ cmsBool CMSEXPORT cmsIT8SetDataRowColDbl(cmsHANDLE hIT8, int row, int col, cmsFl
_cmsAssert(hIT8 != NULL);
- sprintf(Buff, it8->DoubleFormatter, Val);
+ snprintf(Buff, 255, it8->DoubleFormatter, Val);
return SetData(it8, row, col, Buff);
}
diff --git a/thirdparty/liblcms2/src/cmscnvrt.c b/thirdparty/liblcms2/src/cmscnvrt.c
index 1a93e83f..42e5f78b 100644
--- a/thirdparty/liblcms2/src/cmscnvrt.c
+++ b/thirdparty/liblcms2/src/cmscnvrt.c
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2012 Marti Maria Saguer
+// Copyright (c) 1998-2016 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -269,6 +269,9 @@ cmsBool ComputeAbsoluteIntent(cmsFloat64Number AdaptationState,
{
cmsMAT3 Scale, m1, m2, m3, m4;
+ // TODO: Follow Marc Mahy's recommendation to check if CHAD is same by using M1*M2 == M2*M1. If so, do nothing.
+ // TODO: Add support for ArgyllArts tag
+
// Adaptation state
if (AdaptationState == 1.0) {
@@ -288,7 +291,7 @@ cmsBool ComputeAbsoluteIntent(cmsFloat64Number AdaptationState,
if (AdaptationState == 0.0) {
-
+
m1 = *ChromaticAdaptationMatrixOut;
_cmsMAT3per(&m2, &m1, &Scale);
// m2 holds CHAD from output white to D50 times abs. col. scaling
@@ -530,7 +533,7 @@ cmsPipeline* DefaultICCintents(cmsContext ContextID,
cmsHPROFILE hProfile;
cmsMAT3 m;
cmsVEC3 off;
- cmsColorSpaceSignature ColorSpaceIn, ColorSpaceOut, CurrentColorSpace;
+ cmsColorSpaceSignature ColorSpaceIn, ColorSpaceOut = cmsSigLabData, CurrentColorSpace;
cmsProfileClassSignature ClassSig;
cmsUInt32Number i, Intent;
@@ -632,6 +635,22 @@ cmsPipeline* DefaultICCintents(cmsContext ContextID,
CurrentColorSpace = ColorSpaceOut;
}
+ // Check for non-negatives clip
+ if (dwFlags & cmsFLAGS_NONEGATIVES) {
+
+ if (ColorSpaceOut == cmsSigGrayData ||
+ ColorSpaceOut == cmsSigRgbData ||
+ ColorSpaceOut == cmsSigCmykData) {
+
+ cmsStage* clip = _cmsStageClipNegatives(Result->ContextID, cmsChannelsOf(ColorSpaceOut));
+ if (clip == NULL) goto Error;
+
+ if (!cmsPipelineInsertStage(Result, cmsAT_END, clip))
+ goto Error;
+ }
+
+ }
+
return Result;
Error:
@@ -1045,7 +1064,7 @@ cmsPipeline* _cmsLinkProfiles(cmsContext ContextID,
if (TheIntents[i] == INTENT_PERCEPTUAL || TheIntents[i] == INTENT_SATURATION) {
// Force BPC for V4 profiles in perceptual and saturation
- if (cmsGetProfileVersion(hProfiles[i]) >= 4.0)
+ if (cmsGetEncodedICCversion(hProfiles[i]) >= 0x4000000)
BPC[i] = TRUE;
}
}
diff --git a/thirdparty/liblcms2/src/cmserr.c b/thirdparty/liblcms2/src/cmserr.c
index 29516db4..78a1f947 100644
--- a/thirdparty/liblcms2/src/cmserr.c
+++ b/thirdparty/liblcms2/src/cmserr.c
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2012 Marti Maria Saguer
+// Copyright (c) 1998-2016 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -25,6 +25,13 @@
#include "lcms2_internal.h"
+
+// This function is here to help applications to prevent mixing lcms versions on header and shared objects.
+int CMSEXPORT cmsGetEncodedCMMversion(void)
+{
+ return LCMS_VERSION;
+}
+
// I am so tired about incompatibilities on those functions that here are some replacements
// that hopefully would be fully portable.
diff --git a/thirdparty/liblcms2/src/cmsgmt.c b/thirdparty/liblcms2/src/cmsgmt.c
index 09427650..51c2fefe 100644
--- a/thirdparty/liblcms2/src/cmsgmt.c
+++ b/thirdparty/liblcms2/src/cmsgmt.c
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2012 Marti Maria Saguer
+// Copyright (c) 1998-2016 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
diff --git a/thirdparty/liblcms2/src/cmshalf.c b/thirdparty/liblcms2/src/cmshalf.c
index 204dee96..cdd4e37b 100644
--- a/thirdparty/liblcms2/src/cmshalf.c
+++ b/thirdparty/liblcms2/src/cmshalf.c
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2012 Marti Maria Saguer
+// Copyright (c) 1998-2016 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
diff --git a/thirdparty/liblcms2/src/cmsintrp.c b/thirdparty/liblcms2/src/cmsintrp.c
index 5d5f35d3..889b6981 100644
--- a/thirdparty/liblcms2/src/cmsintrp.c
+++ b/thirdparty/liblcms2/src/cmsintrp.c
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2012 Marti Maria Saguer
+// Copyright (c) 1998-2016 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -929,7 +929,7 @@ void Eval4Inputs(register const cmsUInt16Number Input[],
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)));
}
@@ -993,7 +993,7 @@ void Eval4Inputs(register const cmsUInt16Number Input[],
Rest = c1 * rx + c2 * ry + c3 * rz;
- Tmp2[OutChan] = (cmsUInt16Number) c0 + ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest));
+ Tmp2[OutChan] = (cmsUInt16Number) (c0 + ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest)));
}
diff --git a/thirdparty/liblcms2/src/cmsio0.c b/thirdparty/liblcms2/src/cmsio0.c
index 4449acd4..2084c7c4 100644
--- a/thirdparty/liblcms2/src/cmsio0.c
+++ b/thirdparty/liblcms2/src/cmsio0.c
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2012 Marti Maria Saguer
+// Copyright (c) 1998-2016 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -453,6 +453,14 @@ cmsBool CMSEXPORT cmsCloseIOhandler(cmsIOHANDLER* io)
// -------------------------------------------------------------------------------------------------------
+cmsIOHANDLER* CMSEXPORT cmsGetProfileIOhandler(cmsHPROFILE hProfile)
+{
+ _cmsICCPROFILE* Icc = (_cmsICCPROFILE*)hProfile;
+
+ if (Icc == NULL) return NULL;
+ return Icc->IOhandler;
+}
+
// Creates an empty structure holding all required parameters
cmsHPROFILE CMSEXPORT cmsCreateProfilePlaceholder(cmsContext ContextID)
{
@@ -623,6 +631,32 @@ cmsBool CMSEXPORT cmsIsTag(cmsHPROFILE hProfile, cmsTagSignature sig)
}
+
+// Enforces that the profile version is per. spec.
+// Operates on the big endian bytes from the profile.
+// Called before converting to platform endianness.
+// Byte 0 is BCD major version, so max 9.
+// Byte 1 is 2 BCD digits, one per nibble.
+// Reserved bytes 2 & 3 must be 0.
+static
+cmsUInt32Number _validatedVersion(cmsUInt32Number DWord)
+{
+ cmsUInt8Number* pByte = (cmsUInt8Number*) &DWord;
+ cmsUInt8Number temp1;
+ cmsUInt8Number temp2;
+
+ if (*pByte > 0x09) *pByte = (cmsUInt8Number) 0x09;
+ temp1 = *(pByte+1) & 0xf0;
+ temp2 = *(pByte+1) & 0x0f;
+ if (temp1 > 0x90) temp1 = 0x90;
+ if (temp2 > 0x09) temp2 = 0x09;
+ *(pByte+1) = (cmsUInt8Number)(temp1 | temp2);
+ *(pByte+2) = (cmsUInt8Number)0;
+ *(pByte+3) = (cmsUInt8Number)0;
+
+ return DWord;
+}
+
// Read profile header and validate it
cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc)
{
@@ -657,7 +691,7 @@ cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc)
Icc -> creator = _cmsAdjustEndianess32(Header.creator);
_cmsAdjustEndianess64(&Icc -> attributes, &Header.attributes);
- Icc -> Version = _cmsAdjustEndianess32(Header.version);
+ Icc -> Version = _cmsAdjustEndianess32(_validatedVersion(Header.version));
// Get size as reported in header
HeaderSize = _cmsAdjustEndianess32(Header.size);
@@ -773,7 +807,7 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace)
// Get true count
for (i=0; i < Icc -> TagCount; i++) {
- if (Icc ->TagNames[i] != 0)
+ if (Icc ->TagNames[i] != (cmsTagSignature) 0)
Count++;
}
@@ -782,7 +816,7 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace)
for (i=0; i < Icc -> TagCount; i++) {
- if (Icc ->TagNames[i] == 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.offset = _cmsAdjustEndianess32((cmsInt32Number) Icc -> TagOffsets[i]);
@@ -1132,7 +1166,7 @@ cmsBool SaveTags(_cmsICCPROFILE* Icc, _cmsICCPROFILE* FileOrig)
for (i=0; i < Icc -> TagCount; i++) {
- if (Icc ->TagNames[i] == 0) continue;
+ if (Icc ->TagNames[i] == (cmsTagSignature) 0) continue;
// Linked tags are not written
if (Icc ->TagLinked[i] != (cmsTagSignature) 0) continue;
@@ -1265,12 +1299,16 @@ cmsUInt32Number CMSEXPORT cmsSaveProfileToIOhandler(cmsHPROFILE hProfile, cmsIOH
cmsContext ContextID;
_cmsAssert(hProfile != NULL);
-
+
+ if (!_cmsLockMutex(Icc->ContextID, Icc->UsrMutex)) return 0;
memmove(&Keep, Icc, sizeof(_cmsICCPROFILE));
ContextID = cmsGetProfileContextID(hProfile);
PrevIO = Icc ->IOhandler = cmsOpenIOhandlerFromNULL(ContextID);
- if (PrevIO == NULL) return 0;
+ if (PrevIO == NULL) {
+ _cmsUnlockMutex(Icc->ContextID, Icc->UsrMutex);
+ return 0;
+ }
// Pass #1 does compute offsets
@@ -1290,7 +1328,10 @@ cmsUInt32Number CMSEXPORT cmsSaveProfileToIOhandler(cmsHPROFILE hProfile, cmsIOH
}
memmove(Icc, &Keep, sizeof(_cmsICCPROFILE));
- if (!cmsCloseIOhandler(PrevIO)) return 0;
+ if (!cmsCloseIOhandler(PrevIO))
+ UsedSpace = 0; // As a error marker
+
+ _cmsUnlockMutex(Icc->ContextID, Icc->UsrMutex);
return UsedSpace;
@@ -1298,6 +1339,8 @@ cmsUInt32Number CMSEXPORT cmsSaveProfileToIOhandler(cmsHPROFILE hProfile, cmsIOH
Error:
cmsCloseIOhandler(PrevIO);
memmove(Icc, &Keep, sizeof(_cmsICCPROFILE));
+ _cmsUnlockMutex(Icc->ContextID, Icc->UsrMutex);
+
return 0;
}
@@ -1794,7 +1837,7 @@ Error:
// Similar to the anterior. This function allows to write directly to the ICC profile any data, without
// checking anything. As a rule, mixing Raw with cooked doesn't work, so writting a tag as raw and then reading
-// it as cooked without serializing does result into an error. If that is wha 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.
cmsBool CMSEXPORT cmsWriteRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, const void* data, cmsUInt32Number Size)
{
@@ -1818,6 +1861,11 @@ cmsBool CMSEXPORT cmsWriteRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, cons
Icc ->TagSizes[i] = Size;
_cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
+
+ if (Icc->TagPtrs[i] == NULL) {
+ Icc->TagNames[i] = (cmsTagSignature) 0;
+ return FALSE;
+ }
return TRUE;
}
diff --git a/thirdparty/liblcms2/src/cmsio1.c b/thirdparty/liblcms2/src/cmsio1.c
index 89856e57..73ecbdc8 100644
--- a/thirdparty/liblcms2/src/cmsio1.c
+++ b/thirdparty/liblcms2/src/cmsio1.c
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2012 Marti Maria Saguer
+// Copyright (c) 1998-2016 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -310,8 +310,8 @@ Error:
cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent)
{
cmsTagTypeSignature OriginalType;
- cmsTagSignature tag16 = Device2PCS16[Intent];
- cmsTagSignature tagFloat = Device2PCSFloat[Intent];
+ cmsTagSignature tag16;
+ cmsTagSignature tagFloat;
cmsContext ContextID = cmsGetProfileContextID(hProfile);
// On named color, take the appropiate tag
@@ -340,6 +340,9 @@ cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent)
// matter other LUT are present and have precedence. Intent = -1 means just this.
if (Intent != -1) {
+ tag16 = Device2PCS16[Intent];
+ tagFloat = Device2PCSFloat[Intent];
+
if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
// Floating point LUT are always V4, but the encoding range is no
@@ -582,13 +585,16 @@ Error:
cmsPipeline* _cmsReadOutputLUT(cmsHPROFILE hProfile, int Intent)
{
cmsTagTypeSignature OriginalType;
- cmsTagSignature tag16 = PCS2Device16[Intent];
- cmsTagSignature tagFloat = PCS2DeviceFloat[Intent];
- cmsContext ContextID = cmsGetProfileContextID(hProfile);
+ cmsTagSignature tag16;
+ cmsTagSignature tagFloat;
+ cmsContext ContextID = cmsGetProfileContextID(hProfile);
if (Intent != -1) {
+ tag16 = PCS2Device16[Intent];
+ tagFloat = PCS2DeviceFloat[Intent];
+
if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
// Floating point LUT are always V4
@@ -906,7 +912,7 @@ cmsBool _cmsWriteProfileSequence(cmsHPROFILE hProfile, const cmsSEQ* seq)
{
if (!cmsWriteTag(hProfile, cmsSigProfileSequenceDescTag, seq)) return FALSE;
- if (cmsGetProfileVersion(hProfile) >= 4.0) {
+ if (cmsGetEncodedICCversion(hProfile) >= 0x4000000) {
if (!cmsWriteTag(hProfile, cmsSigProfileSequenceIdTag, seq)) return FALSE;
}
diff --git a/thirdparty/liblcms2/src/cmslut.c b/thirdparty/liblcms2/src/cmslut.c
index c491662b..df3dfc1a 100644
--- a/thirdparty/liblcms2/src/cmslut.c
+++ b/thirdparty/liblcms2/src/cmslut.c
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2012 Marti Maria Saguer
+// Copyright (c) 1998-2016 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -505,7 +505,7 @@ void* CLUTElemDup(cmsStage* mpe)
goto Error;
} else {
NewElem ->Tab.T = (cmsUInt16Number*) _cmsDupMem(mpe ->ContextID, Data ->Tab.T, Data ->nEntries * sizeof (cmsUInt16Number));
- if (NewElem ->Tab.TFloat == NULL)
+ if (NewElem ->Tab.T == NULL)
goto Error;
}
}
@@ -1125,7 +1125,23 @@ cmsStage* _cmsStageNormalizeToXyzFloat(cmsContext ContextID)
return mpe;
}
+// Clips values smaller than zero
+static
+void Clipper(const cmsFloat32Number In[], cmsFloat32Number Out[], const cmsStage *mpe)
+{
+ cmsUInt32Number i;
+ for (i = 0; i < mpe->InputChannels; i++) {
+
+ cmsFloat32Number n = In[i];
+ Out[i] = n < 0 ? 0 : n;
+ }
+}
+cmsStage* _cmsStageClipNegatives(cmsContext ContextID, int nChannels)
+{
+ return _cmsStageAllocPlaceholder(ContextID, cmsSigClipNegativesElemType,
+ nChannels, nChannels, Clipper, NULL, NULL, NULL);
+}
// ********************************************************************************
// Type cmsSigXYZ2LabElemType
@@ -1437,7 +1453,8 @@ cmsPipeline* CMSEXPORT cmsPipelineDup(const cmsPipeline* lut)
First = FALSE;
}
else {
- Anterior ->Next = NewMPE;
+ if (Anterior != NULL)
+ Anterior ->Next = NewMPE;
}
Anterior = NewMPE;
@@ -1482,7 +1499,7 @@ int CMSEXPORT cmsPipelineInsertStage(cmsPipeline* lut, cmsStageLoc loc, cmsStage
for (pt = lut ->Elements;
pt != NULL;
pt = pt -> Next) Anterior = pt;
-
+
Anterior ->Next = mpe;
mpe ->Next = NULL;
}
diff --git a/thirdparty/liblcms2/src/cmsmd5.c b/thirdparty/liblcms2/src/cmsmd5.c
index 966730cf..c7380ca8 100644
--- a/thirdparty/liblcms2/src/cmsmd5.c
+++ b/thirdparty/liblcms2/src/cmsmd5.c
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2012 Marti Maria Saguer
+// Copyright (c) 1998-2016 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
diff --git a/thirdparty/liblcms2/src/cmsmtrx.c b/thirdparty/liblcms2/src/cmsmtrx.c
index 583b1ab2..1dbdc4c2 100644
--- a/thirdparty/liblcms2/src/cmsmtrx.c
+++ b/thirdparty/liblcms2/src/cmsmtrx.c
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2012 Marti Maria Saguer
+// Copyright (c) 1998-2016 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
diff --git a/thirdparty/liblcms2/src/cmsnamed.c b/thirdparty/liblcms2/src/cmsnamed.c
index acfd1c8c..0da01d99 100644
--- a/thirdparty/liblcms2/src/cmsnamed.c
+++ b/thirdparty/liblcms2/src/cmsnamed.c
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2012 Marti Maria Saguer
+// Copyright (c) 1998-2016 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -92,7 +92,7 @@ cmsBool GrowMLUpool(cmsMLU* mlu)
static
cmsBool GrowMLUtable(cmsMLU* mlu)
{
- int AllocatedEntries;
+ cmsUInt32Number AllocatedEntries;
_cmsMLUentry *NewPtr;
// Sanity check
@@ -118,7 +118,7 @@ cmsBool GrowMLUtable(cmsMLU* mlu)
static
int SearchMLUEntry(cmsMLU* mlu, cmsUInt16Number LanguageCode, cmsUInt16Number CountryCode)
{
- int i;
+ cmsUInt32Number i;
// Sanity check
if (mlu == NULL) return -1;
@@ -178,6 +178,33 @@ cmsBool AddMLUBlock(cmsMLU* mlu, cmsUInt32Number size, const wchar_t *Block,
return TRUE;
}
+// Convert from a 3-char code to a cmsUInt16Number. It is done inthis way because some
+// compilers don't properly align beginning of strings
+
+static
+cmsUInt16Number strTo16(const char str[3])
+{
+ cmsUInt16Number n = ((cmsUInt16Number) str[0] << 8) | str[1];
+
+ return n; // Always big endian in this case
+}
+
+static
+void strFrom16(char str[3], cmsUInt16Number n)
+{
+ // Assiming this would be aligned
+ union {
+
+ cmsUInt16Number n;
+ char str[2];
+
+ } c;
+
+ c.n = n; // Always big endian in this case
+
+ str[0] = c.str[0]; str[1] = c.str[1]; str[2] = 0;
+
+}
// Add an ASCII entry.
cmsBool CMSEXPORT cmsMLUsetASCII(cmsMLU* mlu, const char LanguageCode[3], const char CountryCode[3], const char* ASCIIString)
@@ -185,8 +212,8 @@ cmsBool CMSEXPORT cmsMLUsetASCII(cmsMLU* mlu, const char LanguageCode[3], const
cmsUInt32Number i, len = (cmsUInt32Number) strlen(ASCIIString)+1;
wchar_t* WStr;
cmsBool rc;
- cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode);
- cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode);
+ cmsUInt16Number Lang = strTo16(LanguageCode);
+ cmsUInt16Number Cntry = strTo16(CountryCode);
if (mlu == NULL) return FALSE;
@@ -220,8 +247,8 @@ cmsUInt32Number mywcslen(const wchar_t *s)
// Add a wide entry
cmsBool CMSEXPORT cmsMLUsetWide(cmsMLU* mlu, const char Language[3], const char Country[3], const wchar_t* WideString)
{
- cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) Language);
- cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) Country);
+ cmsUInt16Number Lang = strTo16(Language);
+ cmsUInt16Number Cntry = strTo16(Country);
cmsUInt32Number len;
if (mlu == NULL) return FALSE;
@@ -298,8 +325,8 @@ const wchar_t* _cmsMLUgetWide(const cmsMLU* mlu,
cmsUInt16Number LanguageCode, cmsUInt16Number CountryCode,
cmsUInt16Number* UsedLanguageCode, cmsUInt16Number* UsedCountryCode)
{
- int i;
- int Best = -1;
+ cmsUInt32Number i;
+ cmsInt32Number Best = -1;
_cmsMLUentry* v;
if (mlu == NULL) return NULL;
@@ -350,8 +377,8 @@ cmsUInt32Number CMSEXPORT cmsMLUgetASCII(const cmsMLU* mlu,
cmsUInt32Number StrLen = 0;
cmsUInt32Number ASCIIlen, i;
- cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode);
- cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode);
+ cmsUInt16Number Lang = strTo16(LanguageCode);
+ cmsUInt16Number Cntry = strTo16(CountryCode);
// Sanitize
if (mlu == NULL) return 0;
@@ -394,8 +421,8 @@ cmsUInt32Number CMSEXPORT cmsMLUgetWide(const cmsMLU* mlu,
const wchar_t *Wide;
cmsUInt32Number StrLen = 0;
- cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode);
- cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode);
+ cmsUInt16Number Lang = strTo16(LanguageCode);
+ cmsUInt16Number Cntry = strTo16(CountryCode);
// Sanitize
if (mlu == NULL) return 0;
@@ -427,8 +454,8 @@ CMSAPI cmsBool CMSEXPORT cmsMLUgetTranslation(const cmsMLU* mlu,
{
const wchar_t *Wide;
- cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode);
- cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode);
+ cmsUInt16Number Lang = strTo16(LanguageCode);
+ cmsUInt16Number Cntry = strTo16(CountryCode);
cmsUInt16Number ObtLang, ObtCode;
// Sanitize
@@ -438,10 +465,9 @@ CMSAPI cmsBool CMSEXPORT cmsMLUgetTranslation(const cmsMLU* mlu,
if (Wide == NULL) return FALSE;
// Get used language and code
- *(cmsUInt16Number *)ObtainedLanguage = _cmsAdjustEndianess16(ObtLang);
- *(cmsUInt16Number *)ObtainedCountry = _cmsAdjustEndianess16(ObtCode);
+ strFrom16(ObtainedLanguage, ObtLang);
+ strFrom16(ObtainedCountry, ObtCode);
- ObtainedLanguage[2] = ObtainedCountry[2] = 0;
return TRUE;
}
@@ -464,12 +490,12 @@ cmsBool CMSEXPORT cmsMLUtranslationsCodes(const cmsMLU* mlu,
if (mlu == NULL) return FALSE;
- if (idx >= (cmsUInt32Number) mlu->UsedEntries) return FALSE;
+ if (idx >= mlu->UsedEntries) return FALSE;
entry = &mlu->Entries[idx];
- *(cmsUInt16Number *)LanguageCode = _cmsAdjustEndianess16(entry->Language);
- *(cmsUInt16Number *)CountryCode = _cmsAdjustEndianess16(entry->Country);
+ strFrom16(LanguageCode, entry->Language);
+ strFrom16(CountryCode, entry->Country);
return TRUE;
}
@@ -514,8 +540,9 @@ cmsNAMEDCOLORLIST* CMSEXPORT cmsAllocNamedColorList(cmsContext ContextID, cmsUIn
v ->nColors = 0;
v ->ContextID = ContextID;
- while (v -> Allocated < n)
- GrowNamedColorList(v);
+ while (v -> Allocated < n){
+ if (!GrowNamedColorList(v)) return NULL;
+ }
strncpy(v ->Prefix, Prefix, sizeof(v ->Prefix)-1);
strncpy(v ->Suffix, Suffix, sizeof(v ->Suffix)-1);
@@ -544,8 +571,9 @@ cmsNAMEDCOLORLIST* CMSEXPORT cmsDupNamedColorList(const cmsNAMEDCOLORLIST* v)
if (NewNC == NULL) return NULL;
// For really large tables we need this
- while (NewNC ->Allocated < v ->Allocated)
- GrowNamedColorList(NewNC);
+ while (NewNC ->Allocated < v ->Allocated){
+ if (!GrowNamedColorList(NewNC)) return NULL;
+ }
memmove(NewNC ->Prefix, v ->Prefix, sizeof(v ->Prefix));
memmove(NewNC ->Suffix, v ->Suffix, sizeof(v ->Suffix));
diff --git a/thirdparty/liblcms2/src/cmsopt.c b/thirdparty/liblcms2/src/cmsopt.c
index bf950917..2fba94b2 100644
--- a/thirdparty/liblcms2/src/cmsopt.c
+++ b/thirdparty/liblcms2/src/cmsopt.c
@@ -1,8 +1,7 @@
-
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2011 Marti Maria Saguer
+// Copyright (c) 1998-2016 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -163,6 +162,89 @@ cmsBool _Remove2Op(cmsPipeline* Lut, cmsStageSignature Op1, cmsStageSignature Op
return AnyOpt;
}
+
+static
+cmsBool CloseEnoughFloat(cmsFloat64Number a, cmsFloat64Number b)
+{
+ return fabs(b - a) < 0.00001f;
+}
+
+static
+cmsBool isFloatMatrixIdentity(const cmsMAT3* a)
+{
+ cmsMAT3 Identity;
+ int i, j;
+
+ _cmsMAT3identity(&Identity);
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++)
+ if (!CloseEnoughFloat(a->v[i].n[j], Identity.v[i].n[j])) return FALSE;
+
+ return TRUE;
+}
+// if two adjacent matrices are found, multiply them.
+static
+cmsBool _MultiplyMatrix(cmsPipeline* Lut)
+{
+ cmsStage** pt1;
+ cmsStage** pt2;
+ cmsStage* chain;
+ cmsBool AnyOpt = FALSE;
+
+ pt1 = &Lut->Elements;
+ if (*pt1 == NULL) return AnyOpt;
+
+ while (*pt1 != NULL) {
+
+ pt2 = &((*pt1)->Next);
+ if (*pt2 == NULL) return AnyOpt;
+
+ if ((*pt1)->Implements == cmsSigMatrixElemType && (*pt2)->Implements == cmsSigMatrixElemType) {
+
+ // Get both matrices
+ _cmsStageMatrixData* m1 = (_cmsStageMatrixData*) cmsStageData(*pt1);
+ _cmsStageMatrixData* m2 = (_cmsStageMatrixData*) cmsStageData(*pt2);
+ cmsMAT3 res;
+
+ // Input offset and output offset should be zero to use this optimization
+ if (m1->Offset != NULL || m2 ->Offset != NULL ||
+ cmsStageInputChannels(*pt1) != 3 || cmsStageOutputChannels(*pt1) != 3 ||
+ cmsStageInputChannels(*pt2) != 3 || cmsStageOutputChannels(*pt2) != 3)
+ return FALSE;
+
+ // Multiply both matrices to get the result
+ _cmsMAT3per(&res, (cmsMAT3*)m2->Double, (cmsMAT3*)m1->Double);
+
+ // Get the next in chain afer the matrices
+ chain = (*pt2)->Next;
+
+ // Remove both matrices
+ _RemoveElement(pt2);
+ _RemoveElement(pt1);
+
+ // Now what if the result is a plain identity?
+ if (!isFloatMatrixIdentity(&res)) {
+
+ // We can not get rid of full matrix
+ cmsStage* Multmat = cmsStageAllocMatrix(Lut->ContextID, 3, 3, (const cmsFloat64Number*) &res, NULL);
+ if (Multmat == NULL) return FALSE; // Should never happen
+
+ // Recover the chain
+ Multmat->Next = chain;
+ *pt1 = Multmat;
+ }
+
+ AnyOpt = TRUE;
+ }
+ else
+ pt1 = &((*pt1)->Next);
+ }
+
+ return AnyOpt;
+}
+
+
// Preoptimize just gets rif of no-ops coming paired. Conversion from v2 to v4 followed
// by a v4 to v2 and vice-versa. The elements are then discarded.
static
@@ -195,6 +277,9 @@ cmsBool PreOptimize(cmsPipeline* Lut)
// Remove float pcs Lab conversions
Opt |= _Remove2Op(Lut, cmsSigXYZ2FloatPCS, cmsSigFloatPCS2XYZ);
+ // Simplify matrix.
+ Opt |= _MultiplyMatrix(Lut);
+
if (Opt) AnyOpt = TRUE;
} while (Opt);
@@ -251,12 +336,12 @@ static
void* Prelin16dup(cmsContext ContextID, const void* ptr)
{
Prelin16Data* p16 = (Prelin16Data*) ptr;
- Prelin16Data* Duped = _cmsDupMem(ContextID, p16, sizeof(Prelin16Data));
+ Prelin16Data* Duped = (Prelin16Data*) _cmsDupMem(ContextID, p16, sizeof(Prelin16Data));
if (Duped == NULL) return NULL;
- Duped ->EvalCurveOut16 = _cmsDupMem(ContextID, p16 ->EvalCurveOut16, p16 ->nOutputs * sizeof(_cmsInterpFn16));
- Duped ->ParamsCurveOut16 = _cmsDupMem(ContextID, p16 ->ParamsCurveOut16, p16 ->nOutputs * sizeof(cmsInterpParams* ));
+ Duped->EvalCurveOut16 = (_cmsInterpFn16*) _cmsDupMem(ContextID, p16->EvalCurveOut16, p16->nOutputs * sizeof(_cmsInterpFn16));
+ Duped->ParamsCurveOut16 = (cmsInterpParams**)_cmsDupMem(ContextID, p16->ParamsCurveOut16, p16->nOutputs * sizeof(cmsInterpParams*));
return Duped;
}
@@ -269,7 +354,7 @@ Prelin16Data* PrelinOpt16alloc(cmsContext ContextID,
int nOutputs, cmsToneCurve** Out )
{
int i;
- Prelin16Data* p16 = _cmsMallocZero(ContextID, sizeof(Prelin16Data));
+ Prelin16Data* p16 = (Prelin16Data*)_cmsMallocZero(ContextID, sizeof(Prelin16Data));
if (p16 == NULL) return NULL;
p16 ->nInputs = nInputs;
@@ -590,7 +675,7 @@ cmsBool OptimizeByResampling(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3
cmsStage* PreLin = cmsPipelineGetPtrToFirstStage(Src);
// Check if suitable
- if (PreLin ->Type == cmsSigCurveSetElemType) {
+ if (PreLin && PreLin ->Type == cmsSigCurveSetElemType) {
// Maybe this is a linear tram, so we can avoid the whole stuff
if (!AllCurvesAreLinear(PreLin)) {
@@ -623,7 +708,7 @@ cmsBool OptimizeByResampling(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3
cmsStage* PostLin = cmsPipelineGetPtrToLastStage(Src);
// Check if suitable
- if (cmsStageType(PostLin) == cmsSigCurveSetElemType) {
+ if (PostLin && cmsStageType(PostLin) == cmsSigCurveSetElemType) {
// Maybe this is a linear tram, so we can avoid the whole stuff
if (!AllCurvesAreLinear(PostLin)) {
@@ -758,7 +843,7 @@ Prelin8Data* PrelinOpt8alloc(cmsContext ContextID, const cmsInterpParams* p, cms
cmsS15Fixed16Number v1, v2, v3;
Prelin8Data* p8;
- p8 = _cmsMallocZero(ContextID, sizeof(Prelin8Data));
+ p8 = (Prelin8Data*)_cmsMallocZero(ContextID, sizeof(Prelin8Data));
if (p8 == NULL) return NULL;
// Since this only works for 8 bit input, values comes always as x * 257,
@@ -832,7 +917,7 @@ void PrelinEval8(register const cmsUInt16Number Input[],
Prelin8Data* p8 = (Prelin8Data*) D;
register const cmsInterpParams* p = p8 ->p;
int TotalOut = p -> nOutputs;
- const cmsUInt16Number* LutTable = p -> Table;
+ const cmsUInt16Number* LutTable = (const cmsUInt16Number*) p->Table;
r = Input[0] >> 8;
g = Input[1] >> 8;
@@ -925,8 +1010,8 @@ cmsBool IsDegenerated(const cmsToneCurve* g)
}
if (Zeros == 1 && Poles == 1) return FALSE; // For linear tables
- if (Zeros > (nEntries / 4)) return TRUE; // Degenerated, mostly zeros
- if (Poles > (nEntries / 4)) return TRUE; // Degenerated, mostly poles
+ if (Zeros > (nEntries / 20)) return TRUE; // Degenerated, many zeros
+ if (Poles > (nEntries / 20)) return TRUE; // Degenerated, many poles
return FALSE;
}
@@ -948,17 +1033,19 @@ cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Inte
cmsColorSpaceSignature ColorSpace, OutputColorSpace;
cmsStage* OptimizedPrelinMpe;
cmsStage* mpe;
- cmsToneCurve** OptimizedPrelinCurves;
- _cmsStageCLutData* OptimizedPrelinCLUT;
+ cmsToneCurve** OptimizedPrelinCurves;
+ _cmsStageCLutData* OptimizedPrelinCLUT;
// This is a loosy optimization! does not apply in floating-point cases
if (_cmsFormatterIsFloat(*InputFormat) || _cmsFormatterIsFloat(*OutputFormat)) return FALSE;
- // Only on RGB
+ // Only on chunky RGB
if (T_COLORSPACE(*InputFormat) != PT_RGB) return FALSE;
- if (T_COLORSPACE(*OutputFormat) != PT_RGB) return FALSE;
+ if (T_PLANAR(*InputFormat)) return FALSE;
+ if (T_COLORSPACE(*OutputFormat) != PT_RGB) return FALSE;
+ if (T_PLANAR(*OutputFormat)) return FALSE;
// On 16 bits, user has to specify the feature
if (!_cmsFormatterIs8bit(*InputFormat)) {
@@ -982,6 +1069,22 @@ cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Inte
memset(Trans, 0, sizeof(Trans));
memset(TransReverse, 0, sizeof(TransReverse));
+ // If the last stage of the original lut are curves, and those curves are
+ // degenerated, it is likely the transform is squeezing and clipping
+ // the output from previous CLUT. We cannot optimize this case
+ {
+ cmsStage* last = cmsPipelineGetPtrToLastStage(OriginalLut);
+
+ if (cmsStageType(last) == cmsSigCurveSetElemType) {
+
+ _cmsStageToneCurvesData* Data = (_cmsStageToneCurvesData*)cmsStageData(last);
+ for (i = 0; i < Data->nCurves; i++) {
+ if (IsDegenerated(Data->TheCurves[i]))
+ goto Error;
+ }
+ }
+ }
+
for (t = 0; t < OriginalLut ->InputChannels; t++) {
Trans[t] = cmsBuildTabulatedToneCurve16(OriginalLut ->ContextID, PRELINEARIZATION_POINTS, NULL);
if (Trans[t] == NULL) goto Error;
@@ -1151,15 +1254,15 @@ void CurvesFree(cmsContext ContextID, void* ptr)
static
void* CurvesDup(cmsContext ContextID, const void* ptr)
{
- Curves16Data* Data = _cmsDupMem(ContextID, ptr, sizeof(Curves16Data));
+ Curves16Data* Data = (Curves16Data*)_cmsDupMem(ContextID, ptr, sizeof(Curves16Data));
int i;
if (Data == NULL) return NULL;
- Data ->Curves = _cmsDupMem(ContextID, Data ->Curves, Data ->nCurves * sizeof(cmsUInt16Number*));
+ Data->Curves = (cmsUInt16Number**) _cmsDupMem(ContextID, Data->Curves, Data->nCurves * sizeof(cmsUInt16Number*));
for (i=0; i < Data -> nCurves; i++) {
- Data ->Curves[i] = _cmsDupMem(ContextID, Data ->Curves[i], Data -> nElements * sizeof(cmsUInt16Number));
+ Data->Curves[i] = (cmsUInt16Number*) _cmsDupMem(ContextID, Data->Curves[i], Data->nElements * sizeof(cmsUInt16Number));
}
return (void*) Data;
@@ -1172,18 +1275,18 @@ Curves16Data* CurvesAlloc(cmsContext ContextID, int nCurves, int nElements, cmsT
int i, j;
Curves16Data* c16;
- c16 = _cmsMallocZero(ContextID, sizeof(Curves16Data));
+ c16 = (Curves16Data*)_cmsMallocZero(ContextID, sizeof(Curves16Data));
if (c16 == NULL) return NULL;
c16 ->nCurves = nCurves;
c16 ->nElements = nElements;
- c16 ->Curves = _cmsCalloc(ContextID, nCurves, sizeof(cmsUInt16Number*));
+ c16->Curves = (cmsUInt16Number**) _cmsCalloc(ContextID, nCurves, sizeof(cmsUInt16Number*));
if (c16 ->Curves == NULL) return NULL;
for (i=0; i < nCurves; i++) {
- c16->Curves[i] = _cmsCalloc(ContextID, nElements, sizeof(cmsUInt16Number));
+ c16->Curves[i] = (cmsUInt16Number*) _cmsCalloc(ContextID, nElements, sizeof(cmsUInt16Number));
if (c16->Curves[i] == NULL) {
@@ -1315,7 +1418,10 @@ cmsBool OptimizeByJoiningCurves(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUI
GammaTables[i] = NULL;
}
- if (GammaTables != NULL) _cmsFree(Src ->ContextID, GammaTables);
+ if (GammaTables != NULL) {
+ _cmsFree(Src->ContextID, GammaTables);
+ GammaTables = NULL;
+ }
// Maybe the curves are linear at the end
if (!AllCurvesAreLinear(ObtainedCurves)) {
@@ -1531,49 +1637,83 @@ cmsBool SetMatShaper(cmsPipeline* Dest, cmsToneCurve* Curve1[3], cmsMAT3* Mat, c
}
// 8 bits on input allows matrix-shaper boot up to 25 Mpixels per second on RGB. That's fast!
-// TODO: Allow a third matrix for abs. colorimetric
static
cmsBool OptimizeMatrixShaper(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt32Number* InputFormat, cmsUInt32Number* OutputFormat, cmsUInt32Number* dwFlags)
{
- cmsStage* Curve1, *Curve2;
- cmsStage* Matrix1, *Matrix2;
- _cmsStageMatrixData* Data1;
- _cmsStageMatrixData* Data2;
- cmsMAT3 res;
- cmsBool IdentityMat;
- cmsPipeline* Dest, *Src;
+ cmsStage* Curve1, *Curve2;
+ cmsStage* Matrix1, *Matrix2;
+ cmsMAT3 res;
+ cmsBool IdentityMat;
+ cmsPipeline* Dest, *Src;
+ cmsFloat64Number* Offset;
- // Only works on RGB to RGB
- if (T_CHANNELS(*InputFormat) != 3 || T_CHANNELS(*OutputFormat) != 3) return FALSE;
+ // Only works on RGB to RGB
+ if (T_CHANNELS(*InputFormat) != 3 || T_CHANNELS(*OutputFormat) != 3) return FALSE;
- // Only works on 8 bit input
- if (!_cmsFormatterIs8bit(*InputFormat)) return FALSE;
+ // Only works on 8 bit input
+ if (!_cmsFormatterIs8bit(*InputFormat)) return FALSE;
- // Seems suitable, proceed
- Src = *Lut;
+ // Seems suitable, proceed
+ Src = *Lut;
- // Check for shaper-matrix-matrix-shaper structure, that is what this optimizer stands for
- if (!cmsPipelineCheckAndRetreiveStages(Src, 4,
- cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType,
- &Curve1, &Matrix1, &Matrix2, &Curve2)) return FALSE;
+ // Check for:
+ //
+ // shaper-matrix-matrix-shaper
+ // shaper-matrix-shaper
+ //
+ // Both of those constructs are possible (first because abs. colorimetric).
+ // additionally, In the first case, the input matrix offset should be zero.
- // Get both matrices
- Data1 = (_cmsStageMatrixData*) cmsStageData(Matrix1);
- Data2 = (_cmsStageMatrixData*) cmsStageData(Matrix2);
+ IdentityMat = FALSE;
+ if (cmsPipelineCheckAndRetreiveStages(Src, 4,
+ cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType,
+ &Curve1, &Matrix1, &Matrix2, &Curve2)) {
- // Input offset should be zero
- if (Data1 ->Offset != NULL) return FALSE;
+ // Get both matrices
+ _cmsStageMatrixData* Data1 = (_cmsStageMatrixData*)cmsStageData(Matrix1);
+ _cmsStageMatrixData* Data2 = (_cmsStageMatrixData*)cmsStageData(Matrix2);
- // Multiply both matrices to get the result
- _cmsMAT3per(&res, (cmsMAT3*) Data2 ->Double, (cmsMAT3*) Data1 ->Double);
+ // Input offset should be zero
+ if (Data1->Offset != NULL) return FALSE;
- // Now the result is in res + Data2 -> Offset. Maybe is a plain identity?
- IdentityMat = FALSE;
- if (_cmsMAT3isIdentity(&res) && Data2 ->Offset == NULL) {
+ // Multiply both matrices to get the result
+ _cmsMAT3per(&res, (cmsMAT3*)Data2->Double, (cmsMAT3*)Data1->Double);
- // We can get rid of full matrix
- IdentityMat = TRUE;
- }
+ // Only 2nd matrix has offset, or it is zero
+ Offset = Data2->Offset;
+
+ // Now the result is in res + Data2 -> Offset. Maybe is a plain identity?
+ if (_cmsMAT3isIdentity(&res) && Offset == NULL) {
+
+ // We can get rid of full matrix
+ IdentityMat = TRUE;
+ }
+
+ }
+ else {
+
+ if (cmsPipelineCheckAndRetreiveStages(Src, 3,
+ cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType,
+ &Curve1, &Matrix1, &Curve2)) {
+
+ _cmsStageMatrixData* Data = (_cmsStageMatrixData*)cmsStageData(Matrix1);
+
+ // Copy the matrix to our result
+ memcpy(&res, Data->Double, sizeof(res));
+
+ // Preserve the Odffset (may be NULL as a zero offset)
+ Offset = Data->Offset;
+
+ if (_cmsMAT3isIdentity(&res) && Offset == NULL) {
+
+ // We can get rid of full matrix
+ IdentityMat = TRUE;
+ }
+ }
+ else
+ return FALSE; // Not optimizeable this time
+
+ }
// Allocate an empty LUT
Dest = cmsPipelineAlloc(Src ->ContextID, Src ->InputChannels, Src ->OutputChannels);
@@ -1583,9 +1723,12 @@ cmsBool OptimizeMatrixShaper(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3
if (!cmsPipelineInsertStage(Dest, cmsAT_BEGIN, cmsStageDup(Curve1)))
goto Error;
- if (!IdentityMat)
- if (!cmsPipelineInsertStage(Dest, cmsAT_END, cmsStageAllocMatrix(Dest ->ContextID, 3, 3, (const cmsFloat64Number*) &res, Data2 ->Offset)))
- goto Error;
+ if (!IdentityMat) {
+
+ if (!cmsPipelineInsertStage(Dest, cmsAT_END, cmsStageAllocMatrix(Dest->ContextID, 3, 3, (const cmsFloat64Number*)&res, Offset)))
+ goto Error;
+ }
+
if (!cmsPipelineInsertStage(Dest, cmsAT_END, cmsStageDup(Curve2)))
goto Error;
@@ -1603,7 +1746,7 @@ cmsBool OptimizeMatrixShaper(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3
*dwFlags |= cmsFLAGS_NOCACHE;
// Setup the optimizarion routines
- SetMatShaper(Dest, mpeC1 ->TheCurves, &res, (cmsVEC3*) Data2 ->Offset, mpeC2->TheCurves, OutputFormat);
+ SetMatShaper(Dest, mpeC1 ->TheCurves, &res, (cmsVEC3*) Offset, mpeC2->TheCurves, OutputFormat);
}
cmsPipelineFree(Src);
diff --git a/thirdparty/liblcms2/src/cmspack.c b/thirdparty/liblcms2/src/cmspack.c
index c84fd822..12d6aae7 100644
--- a/thirdparty/liblcms2/src/cmspack.c
+++ b/thirdparty/liblcms2/src/cmspack.c
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2016 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -2409,9 +2409,6 @@ cmsUInt8Number* PackDoubleFrom16(register _cmsTRANSFORM* info,
((cmsFloat64Number*) output)[i + start] = v;
}
- if (!ExtraFirst) {
- output += Extra * sizeof(cmsFloat64Number);
- }
if (Extra == 0 && SwapFirst) {
@@ -2422,7 +2419,7 @@ cmsUInt8Number* PackDoubleFrom16(register _cmsTRANSFORM* info,
if (T_PLANAR(info -> OutputFormat))
return output + sizeof(cmsFloat64Number);
else
- return output + nChan * sizeof(cmsFloat64Number);
+ return output + (nChan + Extra) * sizeof(cmsFloat64Number);
}
@@ -2433,50 +2430,47 @@ cmsUInt8Number* PackFloatFrom16(register _cmsTRANSFORM* info,
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
{
- int nChan = T_CHANNELS(info -> OutputFormat);
- int DoSwap = T_DOSWAP(info ->OutputFormat);
- int Reverse = T_FLAVOR(info ->OutputFormat);
- int Extra = T_EXTRA(info -> OutputFormat);
- int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
- int Planar = T_PLANAR(info -> OutputFormat);
- int ExtraFirst = DoSwap ^ SwapFirst;
- cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35 : 65535.0;
- cmsFloat64Number v = 0;
- cmsFloat32Number* swap1 = (cmsFloat32Number*) output;
- int i, start = 0;
+ int nChan = T_CHANNELS(info->OutputFormat);
+ int DoSwap = T_DOSWAP(info->OutputFormat);
+ int Reverse = T_FLAVOR(info->OutputFormat);
+ int Extra = T_EXTRA(info->OutputFormat);
+ int SwapFirst = T_SWAPFIRST(info->OutputFormat);
+ int Planar = T_PLANAR(info->OutputFormat);
+ int ExtraFirst = DoSwap ^ SwapFirst;
+ cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 655.35 : 65535.0;
+ cmsFloat64Number v = 0;
+ cmsFloat32Number* swap1 = (cmsFloat32Number*)output;
+ int i, start = 0;
- if (ExtraFirst)
- start = Extra;
-
- for (i=0; i < nChan; i++) {
+ if (ExtraFirst)
+ start = Extra;
- int index = DoSwap ? (nChan - i - 1) : i;
+ for (i = 0; i < nChan; i++) {
- v = (cmsFloat64Number) wOut[index] / maximum;
+ int index = DoSwap ? (nChan - i - 1) : i;
- if (Reverse)
- v = maximum - v;
+ v = (cmsFloat64Number)wOut[index] / maximum;
- if (Planar)
- ((cmsFloat32Number*) output)[(i + start ) * Stride]= (cmsFloat32Number) v;
- else
- ((cmsFloat32Number*) output)[i + start] = (cmsFloat32Number) v;
- }
+ if (Reverse)
+ v = maximum - v;
- if (!ExtraFirst) {
- output += Extra * sizeof(cmsFloat32Number);
- }
+ if (Planar)
+ ((cmsFloat32Number*)output)[(i + start) * Stride] = (cmsFloat32Number)v;
+ else
+ ((cmsFloat32Number*)output)[i + start] = (cmsFloat32Number)v;
+ }
- if (Extra == 0 && SwapFirst) {
+
+ if (Extra == 0 && SwapFirst) {
- memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat32Number));
- *swap1 = (cmsFloat32Number) v;
- }
+ memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsFloat32Number));
+ *swap1 = (cmsFloat32Number)v;
+ }
- if (T_PLANAR(info -> OutputFormat))
- return output + sizeof(cmsFloat32Number);
- else
- return output + nChan * sizeof(cmsFloat32Number);
+ if (T_PLANAR(info->OutputFormat))
+ return output + sizeof(cmsFloat32Number);
+ else
+ return output + (nChan + Extra) * sizeof(cmsFloat32Number);
}
@@ -2489,50 +2483,47 @@ cmsUInt8Number* PackFloatsFromFloat(_cmsTRANSFORM* info,
cmsUInt8Number* output,
cmsUInt32Number Stride)
{
- int nChan = T_CHANNELS(info -> OutputFormat);
- int DoSwap = T_DOSWAP(info ->OutputFormat);
- int Reverse = T_FLAVOR(info ->OutputFormat);
- int Extra = T_EXTRA(info -> OutputFormat);
- int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
- int Planar = T_PLANAR(info -> OutputFormat);
- int ExtraFirst = DoSwap ^ SwapFirst;
- cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
- cmsFloat32Number* swap1 = (cmsFloat32Number*) output;
- cmsFloat64Number v = 0;
- int i, start = 0;
+ int nChan = T_CHANNELS(info->OutputFormat);
+ int DoSwap = T_DOSWAP(info->OutputFormat);
+ int Reverse = T_FLAVOR(info->OutputFormat);
+ int Extra = T_EXTRA(info->OutputFormat);
+ int SwapFirst = T_SWAPFIRST(info->OutputFormat);
+ int Planar = T_PLANAR(info->OutputFormat);
+ int ExtraFirst = DoSwap ^ SwapFirst;
+ cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 100.0 : 1.0;
+ cmsFloat32Number* swap1 = (cmsFloat32Number*)output;
+ cmsFloat64Number v = 0;
+ int i, start = 0;
- if (ExtraFirst)
- start = Extra;
+ if (ExtraFirst)
+ start = Extra;
- for (i=0; i < nChan; i++) {
+ for (i = 0; i < nChan; i++) {
- int index = DoSwap ? (nChan - i - 1) : i;
+ int index = DoSwap ? (nChan - i - 1) : i;
- v = wOut[index] * maximum;
+ v = wOut[index] * maximum;
- if (Reverse)
- v = maximum - v;
+ if (Reverse)
+ v = maximum - v;
- if (Planar)
- ((cmsFloat32Number*) output)[(i + start)* Stride]= (cmsFloat32Number) v;
- else
- ((cmsFloat32Number*) output)[i + start] = (cmsFloat32Number) v;
- }
+ if (Planar)
+ ((cmsFloat32Number*)output)[(i + start)* Stride] = (cmsFloat32Number)v;
+ else
+ ((cmsFloat32Number*)output)[i + start] = (cmsFloat32Number)v;
+ }
- if (!ExtraFirst) {
- output += Extra * sizeof(cmsFloat32Number);
- }
- if (Extra == 0 && SwapFirst) {
+ if (Extra == 0 && SwapFirst) {
- memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat32Number));
- *swap1 = (cmsFloat32Number) v;
- }
+ memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsFloat32Number));
+ *swap1 = (cmsFloat32Number)v;
+ }
- if (T_PLANAR(info -> OutputFormat))
- return output + sizeof(cmsFloat32Number);
- else
- return output + nChan * sizeof(cmsFloat32Number);
+ if (T_PLANAR(info->OutputFormat))
+ return output + sizeof(cmsFloat32Number);
+ else
+ return output + (nChan + Extra) * sizeof(cmsFloat32Number);
}
static
@@ -2541,51 +2532,47 @@ cmsUInt8Number* PackDoublesFromFloat(_cmsTRANSFORM* info,
cmsUInt8Number* output,
cmsUInt32Number Stride)
{
- int nChan = T_CHANNELS(info -> OutputFormat);
- int DoSwap = T_DOSWAP(info ->OutputFormat);
- int Reverse = T_FLAVOR(info ->OutputFormat);
- int Extra = T_EXTRA(info -> OutputFormat);
- int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
- int Planar = T_PLANAR(info -> OutputFormat);
- int ExtraFirst = DoSwap ^ SwapFirst;
- cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
- cmsFloat64Number v = 0;
- cmsFloat64Number* swap1 = (cmsFloat64Number*) output;
- int i, start = 0;
+ int nChan = T_CHANNELS(info->OutputFormat);
+ int DoSwap = T_DOSWAP(info->OutputFormat);
+ int Reverse = T_FLAVOR(info->OutputFormat);
+ int Extra = T_EXTRA(info->OutputFormat);
+ int SwapFirst = T_SWAPFIRST(info->OutputFormat);
+ int Planar = T_PLANAR(info->OutputFormat);
+ int ExtraFirst = DoSwap ^ SwapFirst;
+ cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 100.0 : 1.0;
+ cmsFloat64Number v = 0;
+ cmsFloat64Number* swap1 = (cmsFloat64Number*)output;
+ int i, start = 0;
- if (ExtraFirst)
- start = Extra;
-
- for (i=0; i < nChan; i++) {
+ if (ExtraFirst)
+ start = Extra;
- int index = DoSwap ? (nChan - i - 1) : i;
+ for (i = 0; i < nChan; i++) {
- v = wOut[index] * maximum;
+ int index = DoSwap ? (nChan - i - 1) : i;
- if (Reverse)
- v = maximum - v;
+ v = wOut[index] * maximum;
- if (Planar)
- ((cmsFloat64Number*) output)[(i + start) * Stride] = v;
- else
- ((cmsFloat64Number*) output)[i + start] = v;
- }
+ if (Reverse)
+ v = maximum - v;
- if (!ExtraFirst) {
- output += Extra * sizeof(cmsFloat64Number);
- }
+ if (Planar)
+ ((cmsFloat64Number*)output)[(i + start) * Stride] = v;
+ else
+ ((cmsFloat64Number*)output)[i + start] = v;
+ }
- if (Extra == 0 && SwapFirst) {
+ if (Extra == 0 && SwapFirst) {
- memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat64Number));
- *swap1 = v;
- }
+ memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsFloat64Number));
+ *swap1 = v;
+ }
- if (T_PLANAR(info -> OutputFormat))
- return output + sizeof(cmsFloat64Number);
- else
- return output + nChan * sizeof(cmsFloat64Number);
+ if (T_PLANAR(info->OutputFormat))
+ return output + sizeof(cmsFloat64Number);
+ else
+ return output + (nChan + Extra) * sizeof(cmsFloat64Number);
}
@@ -2821,50 +2808,47 @@ cmsUInt8Number* PackHalfFrom16(register _cmsTRANSFORM* info,
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
{
- int nChan = T_CHANNELS(info -> OutputFormat);
- int DoSwap = T_DOSWAP(info ->OutputFormat);
- int Reverse = T_FLAVOR(info ->OutputFormat);
- int Extra = T_EXTRA(info -> OutputFormat);
- int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
- int Planar = T_PLANAR(info -> OutputFormat);
- int ExtraFirst = DoSwap ^ SwapFirst;
- cmsFloat32Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35F : 65535.0F;
- cmsFloat32Number v = 0;
- cmsUInt16Number* swap1 = (cmsUInt16Number*) output;
- int i, start = 0;
+ int nChan = T_CHANNELS(info->OutputFormat);
+ int DoSwap = T_DOSWAP(info->OutputFormat);
+ int Reverse = T_FLAVOR(info->OutputFormat);
+ int Extra = T_EXTRA(info->OutputFormat);
+ int SwapFirst = T_SWAPFIRST(info->OutputFormat);
+ int Planar = T_PLANAR(info->OutputFormat);
+ int ExtraFirst = DoSwap ^ SwapFirst;
+ cmsFloat32Number maximum = IsInkSpace(info->OutputFormat) ? 655.35F : 65535.0F;
+ cmsFloat32Number v = 0;
+ cmsUInt16Number* swap1 = (cmsUInt16Number*)output;
+ int i, start = 0;
- if (ExtraFirst)
- start = Extra;
+ if (ExtraFirst)
+ start = Extra;
- for (i=0; i < nChan; i++) {
+ for (i = 0; i < nChan; i++) {
- int index = DoSwap ? (nChan - i - 1) : i;
+ int index = DoSwap ? (nChan - i - 1) : i;
- v = (cmsFloat32Number) wOut[index] / maximum;
+ v = (cmsFloat32Number)wOut[index] / maximum;
- if (Reverse)
- v = maximum - v;
+ if (Reverse)
+ v = maximum - v;
- if (Planar)
- ((cmsUInt16Number*) output)[(i + start ) * Stride]= _cmsFloat2Half(v);
- else
- ((cmsUInt16Number*) output)[i + start] = _cmsFloat2Half(v);
- }
+ if (Planar)
+ ((cmsUInt16Number*)output)[(i + start) * Stride] = _cmsFloat2Half(v);
+ else
+ ((cmsUInt16Number*)output)[i + start] = _cmsFloat2Half(v);
+ }
- if (!ExtraFirst) {
- output += Extra * sizeof(cmsUInt16Number);
- }
- if (Extra == 0 && SwapFirst) {
+ if (Extra == 0 && SwapFirst) {
- memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number));
- *swap1 = _cmsFloat2Half(v);
- }
+ memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsUInt16Number));
+ *swap1 = _cmsFloat2Half(v);
+ }
- if (T_PLANAR(info -> OutputFormat))
- return output + sizeof(cmsUInt16Number);
- else
- return output + nChan * sizeof(cmsUInt16Number);
+ if (T_PLANAR(info->OutputFormat))
+ return output + sizeof(cmsUInt16Number);
+ else
+ return output + (nChan + Extra) * sizeof(cmsUInt16Number);
}
@@ -2875,50 +2859,47 @@ cmsUInt8Number* PackHalfFromFloat(_cmsTRANSFORM* info,
cmsUInt8Number* output,
cmsUInt32Number Stride)
{
- int nChan = T_CHANNELS(info -> OutputFormat);
- int DoSwap = T_DOSWAP(info ->OutputFormat);
- int Reverse = T_FLAVOR(info ->OutputFormat);
- int Extra = T_EXTRA(info -> OutputFormat);
- int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
- int Planar = T_PLANAR(info -> OutputFormat);
- int ExtraFirst = DoSwap ^ SwapFirst;
- cmsFloat32Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0F : 1.0F;
- cmsUInt16Number* swap1 = (cmsUInt16Number*) output;
- cmsFloat32Number v = 0;
- int i, start = 0;
+ int nChan = T_CHANNELS(info->OutputFormat);
+ int DoSwap = T_DOSWAP(info->OutputFormat);
+ int Reverse = T_FLAVOR(info->OutputFormat);
+ int Extra = T_EXTRA(info->OutputFormat);
+ int SwapFirst = T_SWAPFIRST(info->OutputFormat);
+ int Planar = T_PLANAR(info->OutputFormat);
+ int ExtraFirst = DoSwap ^ SwapFirst;
+ cmsFloat32Number maximum = IsInkSpace(info->OutputFormat) ? 100.0F : 1.0F;
+ cmsUInt16Number* swap1 = (cmsUInt16Number*)output;
+ cmsFloat32Number v = 0;
+ int i, start = 0;
- if (ExtraFirst)
- start = Extra;
+ if (ExtraFirst)
+ start = Extra;
- for (i=0; i < nChan; i++) {
+ for (i = 0; i < nChan; i++) {
- int index = DoSwap ? (nChan - i - 1) : i;
+ int index = DoSwap ? (nChan - i - 1) : i;
- v = wOut[index] * maximum;
+ v = wOut[index] * maximum;
- if (Reverse)
- v = maximum - v;
+ if (Reverse)
+ v = maximum - v;
- if (Planar)
- ((cmsUInt16Number*) output)[(i + start)* Stride]= _cmsFloat2Half( v );
- else
- ((cmsUInt16Number*) output)[i + start] = _cmsFloat2Half( v );
- }
+ if (Planar)
+ ((cmsUInt16Number*)output)[(i + start)* Stride] = _cmsFloat2Half(v);
+ else
+ ((cmsUInt16Number*)output)[i + start] = _cmsFloat2Half(v);
+ }
- if (!ExtraFirst) {
- output += Extra * sizeof(cmsUInt16Number);
- }
- if (Extra == 0 && SwapFirst) {
+ if (Extra == 0 && SwapFirst) {
- memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number));
- *swap1 = (cmsUInt16Number) _cmsFloat2Half( v );
- }
+ memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsUInt16Number));
+ *swap1 = (cmsUInt16Number)_cmsFloat2Half(v);
+ }
- if (T_PLANAR(info -> OutputFormat))
- return output + sizeof(cmsUInt16Number);
- else
- return output + nChan * sizeof(cmsUInt16Number);
+ if (T_PLANAR(info->OutputFormat))
+ return output + sizeof(cmsUInt16Number);
+ else
+ return output + (nChan + Extra)* sizeof(cmsUInt16Number);
}
#endif
@@ -3178,6 +3159,8 @@ cmsFormatter _cmsGetStockOutputFormatter(cmsUInt32Number dwInput, cmsUInt32Numbe
cmsUInt32Number i;
cmsFormatter fr;
+ // Optimization is only a hint
+ dwInput &= ~OPTIMIZED_SH(1);
switch (dwFlags)
{
diff --git a/thirdparty/liblcms2/src/cmspcs.c b/thirdparty/liblcms2/src/cmspcs.c
index 102cd7d2..a08538d3 100644
--- a/thirdparty/liblcms2/src/cmspcs.c
+++ b/thirdparty/liblcms2/src/cmspcs.c
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2016 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -106,6 +106,15 @@ void CMSEXPORT cmsxyY2XYZ(cmsCIEXYZ* Dest, const cmsCIExyY* Source)
Dest -> Z = ((1 - Source -> x - Source -> y) / Source -> y) * Source -> Y;
}
+/*
+ The break point (24/116)^3 = (6/29)^3 is a very small amount of tristimulus
+ primary (0.008856). Generally, this only happens for
+ nearly ideal blacks and for some orange / amber colors in transmission mode.
+ For example, the Z value of the orange turn indicator lamp lens on an
+ automobile will often be below this value. But the Z does not
+ contribute to the perceived color directly.
+*/
+
static
cmsFloat64Number f(cmsFloat64Number t)
{
diff --git a/thirdparty/liblcms2/src/cmsplugin.c b/thirdparty/liblcms2/src/cmsplugin.c
index 317e33e2..dc13eadb 100644
--- a/thirdparty/liblcms2/src/cmsplugin.c
+++ b/thirdparty/liblcms2/src/cmsplugin.c
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2016 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -215,22 +215,6 @@ cmsBool CMSEXPORT _cmsRead15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number* n
}
-// Jun-21-2000: Some profiles (those that comes with W2K) comes
-// with the media white (media black?) x 100. Add a sanity check
-
-static
-void NormalizeXYZ(cmsCIEXYZ* Dest)
-{
- while (Dest -> X > 2. &&
- Dest -> Y > 2. &&
- Dest -> Z > 2.) {
-
- Dest -> X /= 10.;
- Dest -> Y /= 10.;
- Dest -> Z /= 10.;
- }
-}
-
cmsBool CMSEXPORT _cmsReadXYZNumber(cmsIOHANDLER* io, cmsCIEXYZ* XYZ)
{
cmsEncodedXYZNumber xyz;
@@ -244,8 +228,6 @@ cmsBool CMSEXPORT _cmsReadXYZNumber(cmsIOHANDLER* io, cmsCIEXYZ* XYZ)
XYZ->X = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.X));
XYZ->Y = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.Y));
XYZ->Z = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.Z));
-
- NormalizeXYZ(XYZ);
}
return TRUE;
}
@@ -525,6 +507,7 @@ void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size)
if (ContextID == NULL) {
ctx->MemPool = _cmsCreateSubAlloc(0, 2*1024);
+ if (ctx->MemPool == NULL) return NULL;
}
else {
cmsSignalError(ContextID, cmsERROR_CORRUPTION_DETECTED, "NULL memory pool on context");
@@ -683,15 +666,21 @@ struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID)
// Internal: get the memory area associanted with each context client
-// Returns the block assigned to the specific zone.
+// Returns the block assigned to the specific zone. Never return NULL.
void* _cmsContextGetClientChunk(cmsContext ContextID, _cmsMemoryClient mc)
{
struct _cmsContext_struct* ctx;
void *ptr;
- if (mc < 0 || mc >= MemoryClientMax) {
- cmsSignalError(ContextID, cmsERROR_RANGE, "Bad context client");
- return NULL;
+ if ((int) mc < 0 || mc >= MemoryClientMax) {
+
+ cmsSignalError(ContextID, cmsERROR_INTERNAL, "Bad context client -- possible corruption");
+
+ // This is catastrophic. Should never reach here
+ _cmsAssert(0);
+
+ // Reverts to global context
+ return globalContext.chunks[UserPtr];
}
ctx = _cmsGetContext(ContextID);
@@ -880,7 +869,7 @@ cmsContext CMSEXPORT cmsDupContext(cmsContext ContextID, void* NewUserData)
}
-
+/*
static
struct _cmsContext_struct* FindPrev(struct _cmsContext_struct* id)
{
@@ -897,6 +886,7 @@ struct _cmsContext_struct* FindPrev(struct _cmsContext_struct* id)
return NULL; // List is empty or only one element!
}
+*/
// Frees any resources associated with the given context,
// and destroys the context placeholder.
@@ -932,8 +922,8 @@ void CMSEXPORT cmsDeleteContext(cmsContext ContextID)
// Search for previous
for (prev = _cmsContextPoolHead;
- prev != NULL;
- prev = prev ->Next)
+ prev != NULL;
+ prev = prev ->Next)
{
if (prev -> Next == ctx) {
prev -> Next = ctx ->Next;
diff --git a/thirdparty/liblcms2/src/cmsps2.c b/thirdparty/liblcms2/src/cmsps2.c
index 224b44b5..0f007732 100644
--- a/thirdparty/liblcms2/src/cmsps2.c
+++ b/thirdparty/liblcms2/src/cmsps2.c
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2011 Marti Maria Saguer
+// Copyright (c) 1998-2016 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -1393,14 +1393,15 @@ void BuildColorantList(char *Colorant, int nColorant, cmsUInt16Number Out[])
if (nColorant > cmsMAXCHANNELS)
nColorant = cmsMAXCHANNELS;
- for (j=0; j < nColorant; j++) {
+ for (j = 0; j < nColorant; j++) {
- sprintf(Buff, "%.3f", Out[j] / 65535.0);
- strcat(Colorant, Buff);
- if (j < nColorant -1)
- strcat(Colorant, " ");
+ snprintf(Buff, 31, "%.3f", Out[j] / 65535.0);
+ Buff[31] = 0;
+ strcat(Colorant, Buff);
+ if (j < nColorant - 1)
+ strcat(Colorant, " ");
- }
+ }
}
diff --git a/thirdparty/liblcms2/src/cmssamp.c b/thirdparty/liblcms2/src/cmssamp.c
index 70e46916..a9997fa8 100644
--- a/thirdparty/liblcms2/src/cmssamp.c
+++ b/thirdparty/liblcms2/src/cmssamp.c
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2016 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -340,28 +340,7 @@ cmsFloat64Number RootOfLeastSquaresFitQuadraticCurve(int n, cmsFloat64Number x[]
}
-/*
-static
-cmsBool IsMonotonic(int n, const cmsFloat64Number Table[])
-{
- int i;
- cmsFloat64Number last;
-
- last = Table[n-1];
-
- for (i = n-2; i >= 0; --i) {
-
- if (Table[i] > last)
-
- return FALSE;
- else
- last = Table[i];
- }
-
- return TRUE;
-}
-*/
// Calculates the black point of a destination profile.
// This algorithm comes from the Adobe paper disclosing its black point compensation method.
@@ -486,7 +465,6 @@ cmsBool CMSEXPORT cmsDetectDestinationBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROF
// Test for mid range straight (only on relative colorimetric)
-
NearlyStraightMidrange = TRUE;
MinL = outRamp[0]; MaxL = outRamp[255];
if (Intent == INTENT_RELATIVE_COLORIMETRIC) {
@@ -502,7 +480,6 @@ cmsBool CMSEXPORT cmsDetectDestinationBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROF
// DestinationBlackPoint shall be the same as initialLab.
// Otherwise, the DestinationBlackPoint shall be determined
// using curve fitting.
-
if (NearlyStraightMidrange) {
cmsLab2XYZ(NULL, BlackPoint, &InitialLab);
@@ -513,15 +490,13 @@ cmsBool CMSEXPORT cmsDetectDestinationBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROF
// curve fitting: The round-trip curve normally looks like a nearly constant section at the black point,
- // with a corner and a nearly straight line to the white point.
-
+ // with a corner and a nearly straight line to the white point.
for (l=0; l < 256; l++) {
yRamp[l] = (outRamp[l] - MinL) / (MaxL - MinL);
}
// find the black point using the least squares error quadratic curve fitting
-
if (Intent == INTENT_RELATIVE_COLORIMETRIC) {
lo = 0.1;
hi = 0.5;
diff --git a/thirdparty/liblcms2/src/cmssm.c b/thirdparty/liblcms2/src/cmssm.c
index e41cb68b..76c566b4 100644
--- a/thirdparty/liblcms2/src/cmssm.c
+++ b/thirdparty/liblcms2/src/cmssm.c
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2011 Marti Maria Saguer
+// Copyright (c) 1998-2016 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -218,7 +218,8 @@ cmsBool ClosestLineToLine(cmsVEC3* r, const cmsLine* line1, const cmsLine* line2
{
cmsFloat64Number a, b, c, d, e, D;
cmsFloat64Number sc, sN, sD;
- cmsFloat64Number tc, tN, tD;
+ //cmsFloat64Number tc; // left for future use
+ cmsFloat64Number tN, tD;
cmsVEC3 w0;
_cmsVEC3minus(&w0, &line1 ->a, &line2 ->a);
@@ -286,7 +287,7 @@ cmsBool ClosestLineToLine(cmsVEC3* r, const cmsLine* line1, const cmsLine* line2
}
// finally do the division to get sc and tc
sc = (fabs(sN) < MATRIX_DET_TOLERANCE ? 0.0 : sN / sD);
- tc = (fabs(tN) < MATRIX_DET_TOLERANCE ? 0.0 : tN / tD);
+ //tc = (fabs(tN) < MATRIX_DET_TOLERANCE ? 0.0 : tN / tD); // left for future use.
GetPointOfLine(r, line1, sc);
return TRUE;
diff --git a/thirdparty/liblcms2/src/cmstypes.c b/thirdparty/liblcms2/src/cmstypes.c
index 60c09ef8..010996ef 100644
--- a/thirdparty/liblcms2/src/cmstypes.c
+++ b/thirdparty/liblcms2/src/cmstypes.c
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2014 Marti Maria Saguer
+// Copyright (c) 1998-2016 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -951,7 +951,7 @@ cmsBool Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIO
cmsMLU* mlu = (cmsMLU*) Ptr;
char *Text = NULL;
wchar_t *Wide = NULL;
- cmsUInt32Number len, len_aligned, len_filler_alignment;
+ cmsUInt32Number len, len_text, len_tag_requirement, len_aligned;
cmsBool rc = FALSE;
char Filler[68];
@@ -961,17 +961,18 @@ cmsBool Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIO
// Get the len of string
len = cmsMLUgetASCII(mlu, cmsNoLanguage, cmsNoCountry, NULL, 0);
- // From ICC3.4: It has been found that textDescriptionType can contain misaligned data
+ // Specification ICC.1:2001-04 (v2.4.0): It has been found that textDescriptionType can contain misaligned data
//(see clause 4.1 for the definition of “aligned”). Because the Unicode language
// code and Unicode count immediately follow the ASCII description, their
// alignment is not correct if the ASCII count is not a multiple of four. The
// ScriptCode code is misaligned when the ASCII count is odd. Profile reading and
// writing software must be written carefully in order to handle these alignment
// problems.
-
- // Compute an aligned size
- len_aligned = _cmsALIGNLONG(len);
- len_filler_alignment = len_aligned - len;
+ //
+ // The above last sentence suggest to handle alignment issues in the
+ // parser. The provided example (Table 69 on Page 60) makes this clear.
+ // The padding only in the ASCII count is not sufficient for a aligned tag
+ // size, with the same text size in ASCII and Unicode.
// Null strings
if (len <= 0) {
@@ -992,6 +993,12 @@ cmsBool Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIO
cmsMLUgetWide(mlu, cmsNoLanguage, cmsNoCountry, Wide, len * sizeof(wchar_t));
}
+ // Tell the real text len including the null terminator and padding
+ len_text = strlen(Text) + 1;
+ // Compute an total tag size requirement
+ len_tag_requirement = (8+4+len_text+4+4+2*len_text+2+1+67);
+ len_aligned = _cmsALIGNLONG(len_tag_requirement);
+
// * cmsUInt32Number count; * Description length
// * cmsInt8Number desc[count] * NULL terminated ascii string
// * cmsUInt32Number ucLangCode; * UniCode language code
@@ -1001,20 +1008,14 @@ cmsBool Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIO
// * cmsUInt8Number scCount; * ScriptCode count
// * cmsInt8Number scDesc[67]; * ScriptCode Description
- if (!_cmsWriteUInt32Number(io, len_aligned)) goto Error;
- if (!io ->Write(io, len, Text)) goto Error;
- if (!io ->Write(io, len_filler_alignment, Filler)) goto Error;
+ if (!_cmsWriteUInt32Number(io, len_text)) goto Error;
+ if (!io ->Write(io, len_text, Text)) goto Error;
if (!_cmsWriteUInt32Number(io, 0)) goto Error; // ucLanguageCode
- // This part is tricky: we need an aligned tag size, and the ScriptCode part
- // takes 70 bytes, so we need 2 extra bytes to do the alignment
-
- if (!_cmsWriteUInt32Number(io, len_aligned+1)) goto Error;
-
+ if (!_cmsWriteUInt32Number(io, len_text)) goto Error;
// Note that in some compilers sizeof(cmsUInt16Number) != sizeof(wchar_t)
- if (!_cmsWriteWCharArray(io, len, Wide)) goto Error;
- if (!_cmsWriteUInt16Array(io, len_filler_alignment+1, (cmsUInt16Number*) Filler)) goto Error;
+ if (!_cmsWriteWCharArray(io, len_text, Wide)) goto Error;
// ScriptCode Code & count (unused)
if (!_cmsWriteUInt16Number(io, 0)) goto Error;
@@ -1022,6 +1023,10 @@ cmsBool Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIO
if (!io ->Write(io, 67, Filler)) goto Error;
+ // possibly add pad at the end of tag
+ if(len_aligned - len_tag_requirement > 0)
+ if (!io ->Write(io, len_aligned - len_tag_requirement, Filler)) goto Error;
+
rc = TRUE;
Error:
@@ -1503,7 +1508,7 @@ cmsBool Type_MLU_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
cmsMLU* mlu =(cmsMLU*) Ptr;
cmsUInt32Number HeaderSize;
cmsUInt32Number Len, Offset;
- int i;
+ cmsUInt32Number i;
if (Ptr == NULL) {
@@ -1689,10 +1694,7 @@ cmsBool Write8bitTables(cmsContext ContextID, cmsIOHANDLER* io, cmsUInt32Number
else
for (j=0; j < 256; j++) {
- if (Tables != NULL)
- val = (cmsUInt8Number) FROM_16_TO_8(Tables->TheCurves[i]->Table16[j]);
- else
- val = (cmsUInt8Number) j;
+ val = (cmsUInt8Number) FROM_16_TO_8(Tables->TheCurves[i]->Table16[j]);
if (!_cmsWriteUInt8Number(io, val)) return FALSE;
}
@@ -3107,6 +3109,8 @@ void *Type_NamedColor_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* i
memset(Colorant, 0, sizeof(Colorant));
if (io -> Read(io, Root, 32, 1) != 1) return NULL;
+ Root[32] = 0; // To prevent exploits
+
if (!_cmsReadUInt16Array(io, 3, PCS)) goto Error;
if (!_cmsReadUInt16Array(io, nDeviceCoords, Colorant)) goto Error;
@@ -3129,8 +3133,8 @@ static
cmsBool Type_NamedColor_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) Ptr;
- char prefix[32]; // Prefix for each color name
- char suffix[32]; // Suffix for each color name
+ char prefix[33]; // Prefix for each color name
+ char suffix[33]; // Suffix for each color name
int i, nColors;
nColors = cmsNamedColorCount(NamedColorList);
@@ -3142,7 +3146,7 @@ cmsBool Type_NamedColor_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER
strncpy(prefix, (const char*) NamedColorList->Prefix, 32);
strncpy(suffix, (const char*) NamedColorList->Suffix, 32);
- suffix[31] = prefix[31] = 0;
+ suffix[32] = prefix[32] = 0;
if (!io ->Write(io, 32, prefix)) return FALSE;
if (!io ->Write(io, 32, suffix)) return FALSE;
@@ -3154,6 +3158,7 @@ cmsBool Type_NamedColor_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER
char Root[33];
if (!cmsNamedColorInfo(NamedColorList, i, Root, NULL, NULL, PCS, Colorant)) return 0;
+ Root[32] = 0;
if (!io ->Write(io, 32 , Root)) return FALSE;
if (!_cmsWriteUInt16Array(io, 3, PCS)) return FALSE;
if (!_cmsWriteUInt16Array(io, NamedColorList ->ColorantCount, Colorant)) return FALSE;
@@ -3853,7 +3858,7 @@ cmsBool Type_ViewingConditions_Write(struct _cms_typehandler_struct* self, cmsIO
static
void* Type_ViewingConditions_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
- return _cmsDupMem(self ->ContextID, Ptr, sizeof(cmsScreening));
+ return _cmsDupMem(self->ContextID, Ptr, sizeof(cmsICCViewingConditions));
cmsUNUSED_PARAMETER(n);
}
@@ -5451,8 +5456,9 @@ static _cmsTagLinkedList SupportedTags[] = {
{ cmsSigScreeningTag, { 1, 1, { cmsSigScreeningType}, NULL }, &SupportedTags[59]},
{ cmsSigVcgtTag, { 1, 1, { cmsSigVcgtType}, NULL }, &SupportedTags[60]},
{ cmsSigMetaTag, { 1, 1, { cmsSigDictType}, NULL }, &SupportedTags[61]},
- { cmsSigProfileSequenceIdTag, { 1, 1, { cmsSigProfileSequenceIdType}, NULL }, &SupportedTags[62]},
- { cmsSigProfileDescriptionMLTag,{ 1, 1, { cmsSigMultiLocalizedUnicodeType}, NULL}, NULL}
+ { cmsSigProfileSequenceIdTag, { 1, 1, { cmsSigProfileSequenceIdType}, NULL }, &SupportedTags[62]},
+ { cmsSigProfileDescriptionMLTag,{ 1, 1, { cmsSigMultiLocalizedUnicodeType}, NULL}, &SupportedTags[63]},
+ { cmsSigArgyllArtsTag, { 9, 1, { cmsSigS15Fixed16ArrayType}, NULL}, NULL}
};
diff --git a/thirdparty/liblcms2/src/cmsvirt.c b/thirdparty/liblcms2/src/cmsvirt.c
index b324c990..2897adb3 100644
--- a/thirdparty/liblcms2/src/cmsvirt.c
+++ b/thirdparty/liblcms2/src/cmsvirt.c
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2014 Marti Maria Saguer
+// Copyright (c) 1998-2016 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -642,7 +642,7 @@ cmsToneCurve* Build_sRGBGamma(cmsContext ContextID)
// Create the ICC virtual profile for sRGB space
cmsHPROFILE CMSEXPORT cmsCreate_sRGBProfileTHR(cmsContext ContextID)
{
- cmsCIExyY D65;
+ cmsCIExyY D65 = { 0.3127, 0.3290, 1.0 };
cmsCIExyYTRIPLE Rec709Primaries = {
{0.6400, 0.3300, 1.0},
{0.3000, 0.6000, 1.0},
@@ -651,7 +651,7 @@ cmsHPROFILE CMSEXPORT cmsCreate_sRGBProfileTHR(cmsContext ContextID)
cmsToneCurve* Gamma22[3];
cmsHPROFILE hsRGB;
- cmsWhitePointFromTemp(&D65, 6504);
+ // cmsWhitePointFromTemp(&D65, 6504);
Gamma22[0] = Gamma22[1] = Gamma22[2] = Build_sRGBGamma(ContextID);
if (Gamma22[0] == NULL) return NULL;
@@ -679,6 +679,7 @@ typedef struct {
cmsFloat64Number Contrast;
cmsFloat64Number Hue;
cmsFloat64Number Saturation;
+ cmsBool lAdjustWP;
cmsCIEXYZ WPsrc, WPdest;
} BCHSWADJUSTS, *LPBCHSWADJUSTS;
@@ -708,9 +709,10 @@ int bchswSampler(register const cmsUInt16Number In[], register cmsUInt16Number O
cmsLCh2Lab(&LabOut, &LChOut);
// Move white point in Lab
-
- cmsLab2XYZ(&bchsw ->WPsrc, &XYZ, &LabOut);
- cmsXYZ2Lab(&bchsw ->WPdest, &LabOut, &XYZ);
+ if (bchsw->lAdjustWP) {
+ cmsLab2XYZ(&bchsw->WPsrc, &XYZ, &LabOut);
+ cmsXYZ2Lab(&bchsw->WPdest, &LabOut, &XYZ);
+ }
// Back to encoded
@@ -744,18 +746,23 @@ cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfileTHR(cmsContext ContextID,
bchsw.Contrast = Contrast;
bchsw.Hue = Hue;
bchsw.Saturation = Saturation;
+ if (TempSrc == TempDest) {
- cmsWhitePointFromTemp(&WhitePnt, TempSrc );
- cmsxyY2XYZ(&bchsw.WPsrc, &WhitePnt);
-
- cmsWhitePointFromTemp(&WhitePnt, TempDest);
- cmsxyY2XYZ(&bchsw.WPdest, &WhitePnt);
+ bchsw.lAdjustWP = FALSE;
+ }
+ else {
+ bchsw.lAdjustWP = TRUE;
+ cmsWhitePointFromTemp(&WhitePnt, TempSrc);
+ cmsxyY2XYZ(&bchsw.WPsrc, &WhitePnt);
+ cmsWhitePointFromTemp(&WhitePnt, TempDest);
+ cmsxyY2XYZ(&bchsw.WPdest, &WhitePnt);
+
+ }
hICC = cmsCreateProfilePlaceholder(ContextID);
if (!hICC) // can't allocate
return NULL;
-
cmsSetDeviceClass(hICC, cmsSigAbstractClass);
cmsSetColorSpace(hICC, cmsSigLabData);
cmsSetPCS(hICC, cmsSigLabData);
@@ -988,12 +995,14 @@ typedef struct {
} cmsAllowedLUT;
+#define cmsSig0 ((cmsTagSignature) 0)
+
static const cmsAllowedLUT AllowedLUTTypes[] = {
- { FALSE, 0, cmsSigLut16Type, 4, { cmsSigMatrixElemType, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType}},
- { FALSE, 0, cmsSigLut16Type, 3, { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType}},
- { FALSE, 0, cmsSigLut16Type, 2, { cmsSigCurveSetElemType, cmsSigCLutElemType}},
- { TRUE , 0, cmsSigLutAtoBType, 1, { cmsSigCurveSetElemType }},
+ { FALSE, cmsSig0, cmsSigLut16Type, 4, { cmsSigMatrixElemType, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType } },
+ { FALSE, cmsSig0, cmsSigLut16Type, 3, { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType } },
+ { FALSE, cmsSig0, cmsSigLut16Type, 2, { cmsSigCurveSetElemType, cmsSigCLutElemType } },
+ { TRUE, cmsSig0, cmsSigLutAtoBType, 1, { cmsSigCurveSetElemType } },
{ TRUE , cmsSigAToB0Tag, cmsSigLutAtoBType, 3, { cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType } },
{ TRUE , cmsSigAToB0Tag, cmsSigLutAtoBType, 3, { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType } },
{ TRUE , cmsSigAToB0Tag, cmsSigLutAtoBType, 5, { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType }},
diff --git a/thirdparty/liblcms2/src/cmswtpnt.c b/thirdparty/liblcms2/src/cmswtpnt.c
index e657b132..c6b61258 100644
--- a/thirdparty/liblcms2/src/cmswtpnt.c
+++ b/thirdparty/liblcms2/src/cmswtpnt.c
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2014 Marti Maria Saguer
+// Copyright (c) 1998-2016 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
diff --git a/thirdparty/liblcms2/src/cmsxform.c b/thirdparty/liblcms2/src/cmsxform.c
index 56afede2..0364d062 100644
--- a/thirdparty/liblcms2/src/cmsxform.c
+++ b/thirdparty/liblcms2/src/cmsxform.c
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2014 Marti Maria Saguer
+// Copyright (c) 1998-2016 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -179,12 +179,18 @@ void CMSEXPORT cmsDoTransform(cmsHTRANSFORM Transform,
{
_cmsTRANSFORM* p = (_cmsTRANSFORM*) Transform;
-
- p -> xform(p, InputBuffer, OutputBuffer, Size, Size);
+ cmsStride stride;
+
+ stride.BytesPerLineIn = 0; // Not used
+ stride.BytesPerLineOut = 0;
+ stride.BytesPerPlaneIn = Size;
+ stride.BytesPerPlaneOut = Size;
+
+ p -> xform(p, InputBuffer, OutputBuffer, Size, 1, &stride);
}
-// Apply transform.
+// This is a legacy stride for planar
void CMSEXPORT cmsDoTransformStride(cmsHTRANSFORM Transform,
const void* InputBuffer,
void* OutputBuffer,
@@ -192,10 +198,40 @@ void CMSEXPORT cmsDoTransformStride(cmsHTRANSFORM Transform,
{
_cmsTRANSFORM* p = (_cmsTRANSFORM*) Transform;
+ cmsStride stride;
- p -> xform(p, InputBuffer, OutputBuffer, Size, Stride);
+ stride.BytesPerLineIn = 0;
+ stride.BytesPerLineOut = 0;
+ stride.BytesPerPlaneIn = Stride;
+ stride.BytesPerPlaneOut = Stride;
+
+ p -> xform(p, InputBuffer, OutputBuffer, Size, 1, &stride);
}
+// This is the "fast" function for plugins
+void CMSEXPORT cmsDoTransformLineStride(cmsHTRANSFORM Transform,
+ const void* InputBuffer,
+ void* OutputBuffer,
+ cmsUInt32Number PixelsPerLine,
+ cmsUInt32Number LineCount,
+ cmsUInt32Number BytesPerLineIn,
+ cmsUInt32Number BytesPerLineOut,
+ cmsUInt32Number BytesPerPlaneIn,
+ cmsUInt32Number BytesPerPlaneOut)
+
+{
+ _cmsTRANSFORM* p = (_cmsTRANSFORM*) Transform;
+ cmsStride stride;
+
+ stride.BytesPerLineIn = BytesPerLineIn;
+ stride.BytesPerLineOut = BytesPerLineOut;
+ stride.BytesPerPlaneIn = BytesPerPlaneIn;
+ stride.BytesPerPlaneOut = BytesPerPlaneOut;
+
+ p->xform(p, InputBuffer, OutputBuffer, PixelsPerLine, LineCount, &stride);
+}
+
+
// Transform routines ----------------------------------------------------------------------------------------------------------
@@ -204,49 +240,64 @@ void CMSEXPORT cmsDoTransformStride(cmsHTRANSFORM Transform,
static
void FloatXFORM(_cmsTRANSFORM* p,
const void* in,
- void* out, cmsUInt32Number Size, cmsUInt32Number Stride)
+ void* out,
+ cmsUInt32Number PixelsPerLine,
+ cmsUInt32Number LineCount,
+ const cmsStride* Stride)
{
cmsUInt8Number* accum;
cmsUInt8Number* output;
cmsFloat32Number fIn[cmsMAXCHANNELS], fOut[cmsMAXCHANNELS];
cmsFloat32Number OutOfGamut;
- cmsUInt32Number i, j;
+ cmsUInt32Number i, j, c, strideIn, strideOut;
- accum = (cmsUInt8Number*) in;
- output = (cmsUInt8Number*) out;
+ _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
- for (i=0; i < Size; i++) {
+ strideIn = 0;
+ strideOut = 0;
- accum = p -> FromInputFloat(p, fIn, accum, Stride);
+ for (i = 0; i < LineCount; i++) {
- // Any gamut chack to do?
- if (p ->GamutCheck != NULL) {
+ accum = (cmsUInt8Number*)in + strideIn;
+ output = (cmsUInt8Number*)out + strideOut;
- // Evaluate gamut marker.
- cmsPipelineEvalFloat( fIn, &OutOfGamut, p ->GamutCheck);
+ for (j = 0; j < PixelsPerLine; j++) {
- // Is current color out of gamut?
- if (OutOfGamut > 0.0) {
+ accum = p->FromInputFloat(p, fIn, accum, Stride->BytesPerPlaneIn);
- // Certainly, out of gamut
- for (j=0; j < cmsMAXCHANNELS; j++)
- fOut[j] = -1.0;
+ // Any gamut chack to do?
+ if (p->GamutCheck != NULL) {
+ // Evaluate gamut marker.
+ cmsPipelineEvalFloat(fIn, &OutOfGamut, p->GamutCheck);
+
+ // Is current color out of gamut?
+ if (OutOfGamut > 0.0) {
+
+ // Certainly, out of gamut
+ for (c = 0; c < cmsMAXCHANNELS; c++)
+ fOut[c] = -1.0;
+
+ }
+ else {
+ // No, proceed normally
+ cmsPipelineEvalFloat(fIn, fOut, p->Lut);
+ }
}
else {
- // No, proceed normally
- cmsPipelineEvalFloat(fIn, fOut, p -> Lut);
+
+ // No gamut check at all
+ cmsPipelineEvalFloat(fIn, fOut, p->Lut);
}
- }
- else {
- // No gamut check at all
- cmsPipelineEvalFloat(fIn, fOut, p -> Lut);
+
+ output = p->ToOutputFloat(p, fOut, output, Stride->BytesPerPlaneOut);
}
- // Back to asked representation
- output = p -> ToOutputFloat(p, fOut, output, Stride);
+ strideIn += Stride->BytesPerLineIn;
+ strideOut += Stride->BytesPerLineOut;
}
+
}
@@ -254,22 +305,34 @@ static
void NullFloatXFORM(_cmsTRANSFORM* p,
const void* in,
void* out,
- cmsUInt32Number Size,
- cmsUInt32Number Stride)
+ cmsUInt32Number PixelsPerLine,
+ cmsUInt32Number LineCount,
+ const cmsStride* Stride)
+
{
cmsUInt8Number* accum;
cmsUInt8Number* output;
cmsFloat32Number fIn[cmsMAXCHANNELS];
- cmsUInt32Number i, n;
+ cmsUInt32Number i, j, strideIn, strideOut;
+
+ _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
+
+ strideIn = 0;
+ strideOut = 0;
+
+ for (i = 0; i < LineCount; i++) {
- accum = (cmsUInt8Number*) in;
- output = (cmsUInt8Number*) out;
- n = Size;
+ accum = (cmsUInt8Number*) in + strideIn;
+ output = (cmsUInt8Number*) out + strideOut;
- for (i=0; i < n; i++) {
+ for (j = 0; j < PixelsPerLine; j++) {
- accum = p -> FromInputFloat(p, fIn, accum, Stride);
- output = p -> ToOutputFloat(p, fIn, output, Stride);
+ accum = p->FromInputFloat(p, fIn, accum, Stride ->BytesPerPlaneIn);
+ output = p->ToOutputFloat(p, fIn, output, Stride->BytesPerPlaneOut);
+ }
+
+ strideIn += Stride->BytesPerLineIn;
+ strideOut += Stride->BytesPerLineOut;
}
}
@@ -279,23 +342,36 @@ void NullFloatXFORM(_cmsTRANSFORM* p,
static
void NullXFORM(_cmsTRANSFORM* p,
const void* in,
- void* out, cmsUInt32Number Size,
- cmsUInt32Number Stride)
+ void* out,
+ cmsUInt32Number PixelsPerLine,
+ cmsUInt32Number LineCount,
+ const cmsStride* Stride)
{
cmsUInt8Number* accum;
cmsUInt8Number* output;
cmsUInt16Number wIn[cmsMAXCHANNELS];
- cmsUInt32Number i, n;
+ cmsUInt32Number i, j, strideIn, strideOut;
+
+ _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
+
+ strideIn = 0;
+ strideOut = 0;
+
+ for (i = 0; i < LineCount; i++) {
- accum = (cmsUInt8Number*) in;
- output = (cmsUInt8Number*) out;
- n = Size; // Buffer len
+ accum = (cmsUInt8Number*)in + strideIn;
+ output = (cmsUInt8Number*)out + strideOut;
- for (i=0; i < n; i++) {
+ for (j = 0; j < PixelsPerLine; j++) {
- accum = p -> FromInput(p, wIn, accum, Stride);
- output = p -> ToOutput(p, wIn, output, Stride);
+ accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn);
+ output = p->ToOutput(p, wIn, output, Stride->BytesPerPlaneOut);
}
+
+ strideIn += Stride->BytesPerLineIn;
+ strideOut += Stride->BytesPerLineOut;
+ }
+
}
@@ -303,23 +379,37 @@ void NullXFORM(_cmsTRANSFORM* p,
static
void PrecalculatedXFORM(_cmsTRANSFORM* p,
const void* in,
- void* out, cmsUInt32Number Size, cmsUInt32Number Stride)
+ void* out,
+ cmsUInt32Number PixelsPerLine,
+ cmsUInt32Number LineCount,
+ const cmsStride* Stride)
{
register cmsUInt8Number* accum;
register cmsUInt8Number* output;
cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
- cmsUInt32Number i, n;
+ cmsUInt32Number i, j, strideIn, strideOut;
- accum = (cmsUInt8Number*) in;
- output = (cmsUInt8Number*) out;
- n = Size;
+ _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
- for (i=0; i < n; i++) {
+ strideIn = 0;
+ strideOut = 0;
- accum = p -> FromInput(p, wIn, accum, Stride);
- p ->Lut ->Eval16Fn(wIn, wOut, p -> Lut->Data);
- output = p -> ToOutput(p, wOut, output, Stride);
+ for (i = 0; i < LineCount; i++) {
+
+ accum = (cmsUInt8Number*)in + strideIn;
+ output = (cmsUInt8Number*)out + strideOut;
+
+ for (j = 0; j < PixelsPerLine; j++) {
+
+ accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn);
+ p->Lut->Eval16Fn(wIn, wOut, p->Lut->Data);
+ output = p->ToOutput(p, wOut, output, Stride->BytesPerPlaneOut);
+ }
+
+ strideIn += Stride->BytesPerLineIn;
+ strideOut += Stride->BytesPerLineOut;
}
+
}
@@ -350,22 +440,35 @@ void TransformOnePixelWithGamutCheck(_cmsTRANSFORM* p,
static
void PrecalculatedXFORMGamutCheck(_cmsTRANSFORM* p,
const void* in,
- void* out, cmsUInt32Number Size, cmsUInt32Number Stride)
+ void* out,
+ cmsUInt32Number PixelsPerLine,
+ cmsUInt32Number LineCount,
+ const cmsStride* Stride)
{
cmsUInt8Number* accum;
cmsUInt8Number* output;
cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
- cmsUInt32Number i, n;
+ cmsUInt32Number i, j, strideIn, strideOut;
+
+ _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
+
+ strideIn = 0;
+ strideOut = 0;
- accum = (cmsUInt8Number*) in;
- output = (cmsUInt8Number*) out;
- n = Size; // Buffer len
+ for (i = 0; i < LineCount; i++) {
- for (i=0; i < n; i++) {
+ accum = (cmsUInt8Number*)in + strideIn;
+ output = (cmsUInt8Number*)out + strideOut;
- accum = p -> FromInput(p, wIn, accum, Stride);
- TransformOnePixelWithGamutCheck(p, wIn, wOut);
- output = p -> ToOutput(p, wOut, output, Stride);
+ for (j = 0; j < PixelsPerLine; j++) {
+
+ accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn);
+ TransformOnePixelWithGamutCheck(p, wIn, wOut);
+ output = p->ToOutput(p, wOut, output, Stride->BytesPerPlaneOut);
+ }
+
+ strideIn += Stride->BytesPerLineIn;
+ strideOut += Stride->BytesPerLineOut;
}
}
@@ -374,94 +477,120 @@ void PrecalculatedXFORMGamutCheck(_cmsTRANSFORM* p,
static
void CachedXFORM(_cmsTRANSFORM* p,
const void* in,
- void* out, cmsUInt32Number Size, cmsUInt32Number Stride)
+ void* out,
+ cmsUInt32Number PixelsPerLine,
+ cmsUInt32Number LineCount,
+ const cmsStride* Stride)
{
cmsUInt8Number* accum;
cmsUInt8Number* output;
cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
- cmsUInt32Number i, n;
_cmsCACHE Cache;
+ cmsUInt32Number i, j, strideIn, strideOut;
- accum = (cmsUInt8Number*) in;
- output = (cmsUInt8Number*) out;
- n = Size; // Buffer len
+ _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
// Empty buffers for quick memcmp
- memset(wIn, 0, sizeof(wIn));
+ memset(wIn, 0, sizeof(wIn));
memset(wOut, 0, sizeof(wOut));
// Get copy of zero cache
- memcpy(&Cache, &p ->Cache, sizeof(Cache));
+ memcpy(&Cache, &p->Cache, sizeof(Cache));
- for (i=0; i < n; i++) {
+ strideIn = 0;
+ strideOut = 0;
- accum = p -> FromInput(p, wIn, accum, Stride);
+ for (i = 0; i < LineCount; i++) {
- if (memcmp(wIn, Cache.CacheIn, sizeof(Cache.CacheIn)) == 0) {
+ accum = (cmsUInt8Number*)in + strideIn;
+ output = (cmsUInt8Number*)out + strideOut;
- memcpy(wOut, Cache.CacheOut, sizeof(Cache.CacheOut));
- }
- else {
+ for (j = 0; j < PixelsPerLine; j++) {
+
+ accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn);
+
+ if (memcmp(wIn, Cache.CacheIn, sizeof(Cache.CacheIn)) == 0) {
- p ->Lut ->Eval16Fn(wIn, wOut, p -> Lut->Data);
+ memcpy(wOut, Cache.CacheOut, sizeof(Cache.CacheOut));
+ }
+ else {
+ p->Lut->Eval16Fn(wIn, wOut, p->Lut->Data);
- memcpy(Cache.CacheIn, wIn, sizeof(Cache.CacheIn));
- memcpy(Cache.CacheOut, wOut, sizeof(Cache.CacheOut));
+ memcpy(Cache.CacheIn, wIn, sizeof(Cache.CacheIn));
+ memcpy(Cache.CacheOut, wOut, sizeof(Cache.CacheOut));
+ }
+
+ output = p->ToOutput(p, wOut, output, Stride->BytesPerPlaneOut);
}
- output = p -> ToOutput(p, wOut, output, Stride);
+ strideIn += Stride->BytesPerLineIn;
+ strideOut += Stride->BytesPerLineOut;
}
-
}
-
// All those nice features together
static
void CachedXFORMGamutCheck(_cmsTRANSFORM* p,
const void* in,
- void* out, cmsUInt32Number Size, cmsUInt32Number Stride)
+ void* out,
+ cmsUInt32Number PixelsPerLine,
+ cmsUInt32Number LineCount,
+ const cmsStride* Stride)
{
- cmsUInt8Number* accum;
- cmsUInt8Number* output;
- cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
- cmsUInt32Number i, n;
- _cmsCACHE Cache;
+ cmsUInt8Number* accum;
+ cmsUInt8Number* output;
+ cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
+ _cmsCACHE Cache;
+ cmsUInt32Number i, j, strideIn, strideOut;
+
+ _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
+
+ // Empty buffers for quick memcmp
+ memset(wIn, 0, sizeof(wIn));
+ memset(wOut, 0, sizeof(wOut));
- accum = (cmsUInt8Number*) in;
- output = (cmsUInt8Number*) out;
- n = Size; // Buffer len
+ // Get copy of zero cache
+ memcpy(&Cache, &p->Cache, sizeof(Cache));
- // Empty buffers for quick memcmp
- memset(wIn, 0, sizeof(cmsUInt16Number) * cmsMAXCHANNELS);
- memset(wOut, 0, sizeof(cmsUInt16Number) * cmsMAXCHANNELS);
+ strideIn = 0;
+ strideOut = 0;
- // Get copy of zero cache
- memcpy(&Cache, &p ->Cache, sizeof(Cache));
+ for (i = 0; i < LineCount; i++) {
- for (i=0; i < n; i++) {
+ accum = (cmsUInt8Number*)in + strideIn;
+ output = (cmsUInt8Number*)out + strideOut;
- accum = p -> FromInput(p, wIn, accum, Stride);
+ for (j = 0; j < PixelsPerLine; j++) {
+
+ accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn);
if (memcmp(wIn, Cache.CacheIn, sizeof(Cache.CacheIn)) == 0) {
- memcpy(wOut, Cache.CacheOut, sizeof(Cache.CacheOut));
+
+ memcpy(wOut, Cache.CacheOut, sizeof(Cache.CacheOut));
}
else {
- TransformOnePixelWithGamutCheck(p, wIn, wOut);
- memcpy(Cache.CacheIn, wIn, sizeof(Cache.CacheIn));
- memcpy(Cache.CacheOut, wOut, sizeof(Cache.CacheOut));
+ TransformOnePixelWithGamutCheck(p, wIn, wOut);
+
+ memcpy(Cache.CacheIn, wIn, sizeof(Cache.CacheIn));
+ memcpy(Cache.CacheOut, wOut, sizeof(Cache.CacheOut));
}
- output = p -> ToOutput(p, wOut, output, Stride);
- }
+ output = p->ToOutput(p, wOut, output, Stride->BytesPerPlaneOut);
+ }
+ strideIn += Stride->BytesPerLineIn;
+ strideOut += Stride->BytesPerLineOut;
+ }
}
-// -------------------------------------------------------------------------------------------------------------
+// Transform plug-ins ----------------------------------------------------------------------------------------------------
// List of used-defined transform factories
typedef struct _cmsTransformCollection_st {
- _cmsTransformFactory Factory;
+ _cmsTransform2Factory Factory;
+ cmsBool OldXform; // Factory returns xform function in the old style
+
struct _cmsTransformCollection_st *Next;
} _cmsTransformCollection;
@@ -504,6 +633,7 @@ void DupPluginTransformList(struct _cmsContext_struct* ctx,
ctx ->chunks[TransformPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsTransformPluginChunkType));
}
+// Allocates memory for transform plugin factory
void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx,
const struct _cmsContext_struct* src)
{
@@ -518,6 +648,35 @@ void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx,
}
}
+// Adaptor for old versions of plug-in
+static
+void _cmsTransform2toTransformAdaptor(struct _cmstransform_struct *CMMcargo,
+ const void* InputBuffer,
+ void* OutputBuffer,
+ cmsUInt32Number PixelsPerLine,
+ cmsUInt32Number LineCount,
+ const cmsStride* Stride)
+{
+
+ cmsUInt32Number i, strideIn, strideOut;
+
+ _cmsHandleExtraChannels(CMMcargo, InputBuffer, OutputBuffer, PixelsPerLine, LineCount, Stride);
+
+ strideIn = 0;
+ strideOut = 0;
+
+ for (i = 0; i < LineCount; i++) {
+
+ void *accum = (cmsUInt8Number*)InputBuffer + strideIn;
+ void *output = (cmsUInt8Number*)OutputBuffer + strideOut;
+
+ CMMcargo->OldXform(CMMcargo, accum, output, PixelsPerLine, Stride->BytesPerPlaneIn);
+
+ strideIn += Stride->BytesPerLineIn;
+ strideOut += Stride->BytesPerLineOut;
+ }
+}
+
// Register new ways to transform
@@ -535,14 +694,22 @@ cmsBool _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Data)
}
// Factory callback is required
- if (Plugin ->Factory == NULL) return FALSE;
+ if (Plugin->factories.xform == NULL) return FALSE;
fl = (_cmsTransformCollection*) _cmsPluginMalloc(ContextID, sizeof(_cmsTransformCollection));
if (fl == NULL) return FALSE;
+ // Check for full xform plug-ins previous to 2.8, we would need an adapter in that case
+ if (Plugin->base.ExpectedVersion < 2080) {
+
+ fl->OldXform = TRUE;
+ }
+ else
+ fl->OldXform = FALSE;
+
// Copy the parameters
- fl ->Factory = Plugin ->Factory;
+ fl->Factory = Plugin->factories.xform;
// Keep linked list
fl ->Next = ctx->TransformCollection;
@@ -592,46 +759,54 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
_cmsTransformPluginChunkType* ctx = ( _cmsTransformPluginChunkType*) _cmsContextGetClientChunk(ContextID, TransformPlugin);
_cmsTransformCollection* Plugin;
- // Allocate needed memory
- _cmsTRANSFORM* p = (_cmsTRANSFORM*) _cmsMallocZero(ContextID, sizeof(_cmsTRANSFORM));
- if (!p) return NULL;
-
- // Store the proposed pipeline
- p ->Lut = lut;
-
- // Let's see if any plug-in want to do the transform by itself
- for (Plugin = ctx ->TransformCollection;
- Plugin != NULL;
- Plugin = Plugin ->Next) {
-
- if (Plugin ->Factory(&p->xform, &p->UserData, &p ->FreeUserData, &p ->Lut, InputFormat, OutputFormat, dwFlags)) {
-
- // Last plugin in the declaration order takes control. We just keep
- // the original parameters as a logging.
- // Note that cmsFLAGS_CAN_CHANGE_FORMATTER is not set, so by default
- // an optimized transform is not reusable. The plug-in can, however, change
- // the flags and make it suitable.
-
- p ->ContextID = ContextID;
- p ->InputFormat = *InputFormat;
- p ->OutputFormat = *OutputFormat;
- p ->dwOriginalFlags = *dwFlags;
-
- // Fill the formatters just in case the optimized routine is interested.
- // No error is thrown if the formatter doesn't exist. It is up to the optimization
- // factory to decide what to do in those cases.
- p ->FromInput = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16;
- p ->ToOutput = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16;
- p ->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
- p ->ToOutputFloat = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
-
- return p;
- }
- }
-
- // Not suitable for the transform plug-in, let's check the pipeline plug-in
- if (p ->Lut != NULL)
- _cmsOptimizePipeline(ContextID, &p->Lut, Intent, InputFormat, OutputFormat, dwFlags);
+ // Allocate needed memory
+ _cmsTRANSFORM* p = (_cmsTRANSFORM*)_cmsMallocZero(ContextID, sizeof(_cmsTRANSFORM));
+ if (!p) return NULL;
+
+ // Store the proposed pipeline
+ p->Lut = lut;
+
+ // Let's see if any plug-in want to do the transform by itself
+ if (p->Lut != NULL) {
+
+ for (Plugin = ctx->TransformCollection;
+ Plugin != NULL;
+ Plugin = Plugin->Next) {
+
+ if (Plugin->Factory(&p->xform, &p->UserData, &p->FreeUserData, &p->Lut, InputFormat, OutputFormat, dwFlags)) {
+
+ // Last plugin in the declaration order takes control. We just keep
+ // the original parameters as a logging.
+ // Note that cmsFLAGS_CAN_CHANGE_FORMATTER is not set, so by default
+ // an optimized transform is not reusable. The plug-in can, however, change
+ // the flags and make it suitable.
+
+ p->ContextID = ContextID;
+ p->InputFormat = *InputFormat;
+ p->OutputFormat = *OutputFormat;
+ p->dwOriginalFlags = *dwFlags;
+
+ // Fill the formatters just in case the optimized routine is interested.
+ // No error is thrown if the formatter doesn't exist. It is up to the optimization
+ // factory to decide what to do in those cases.
+ p->FromInput = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16;
+ p->ToOutput = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16;
+ p->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
+ p->ToOutputFloat = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
+
+ // Save the day?
+ if (Plugin->OldXform) {
+ p->OldXform = (_cmsTransformFn) p->xform;
+ p->xform = _cmsTransform2toTransformAdaptor;
+ }
+
+ return p;
+ }
+ }
+
+ // Not suitable for the transform plug-in, let's check the pipeline plug-in
+ _cmsOptimizePipeline(ContextID, &p->Lut, Intent, InputFormat, OutputFormat, dwFlags);
+ }
// Check whatever this is a true floating point transform
if (_cmsFormatterIsFloat(*InputFormat) && _cmsFormatterIsFloat(*OutputFormat)) {
@@ -785,6 +960,22 @@ cmsBool IsProperColorSpace(cmsColorSpaceSignature Check, cmsUInt32Number dwForm
// ----------------------------------------------------------------------------------------------------------------
+// Jun-21-2000: Some profiles (those that comes with W2K) comes
+// with the media white (media black?) x 100. Add a sanity check
+
+static
+void NormalizeXYZ(cmsCIEXYZ* Dest)
+{
+ while (Dest -> X > 2. &&
+ Dest -> Y > 2. &&
+ Dest -> Z > 2.) {
+
+ Dest -> X /= 10.;
+ Dest -> Y /= 10.;
+ Dest -> Z /= 10.;
+ }
+}
+
static
void SetWhitePoint(cmsCIEXYZ* wtPt, const cmsCIEXYZ* src)
{
@@ -797,6 +988,8 @@ void SetWhitePoint(cmsCIEXYZ* wtPt, const cmsCIEXYZ* src)
wtPt ->X = src->X;
wtPt ->Y = src->Y;
wtPt ->Z = src->Z;
+
+ NormalizeXYZ(wtPt);
}
}
@@ -1107,7 +1300,6 @@ cmsBool CMSEXPORT cmsChangeBuffersFormat(cmsHTRANSFORM hTransform,
cmsUInt32Number InputFormat,
cmsUInt32Number OutputFormat)
{
-
_cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform;
cmsFormatter16 FromInput, ToOutput;
diff --git a/thirdparty/liblcms2/src/lcms2.def b/thirdparty/liblcms2/src/lcms2.def
deleted file mode 100644
index a1f69c42..00000000
--- a/thirdparty/liblcms2/src/lcms2.def
+++ /dev/null
@@ -1,341 +0,0 @@
-LIBRARY LCMS2.DLL
-
-EXPORTS
-
-_cms15Fixed16toDouble = _cms15Fixed16toDouble
-_cms8Fixed8toDouble = _cms8Fixed8toDouble
-cmsAdaptToIlluminant = cmsAdaptToIlluminant
-_cmsAdjustEndianess16 = _cmsAdjustEndianess16
-_cmsAdjustEndianess32 = _cmsAdjustEndianess32
-_cmsAdjustEndianess64 = _cmsAdjustEndianess64
-cmsAllocNamedColorList = cmsAllocNamedColorList
-cmsAllocProfileSequenceDescription = cmsAllocProfileSequenceDescription
-cmsAppendNamedColor = cmsAppendNamedColor
-cmsBFDdeltaE = cmsBFDdeltaE
-cmsBuildGamma = cmsBuildGamma
-cmsBuildParametricToneCurve = cmsBuildParametricToneCurve
-cmsBuildSegmentedToneCurve = cmsBuildSegmentedToneCurve
-cmsBuildTabulatedToneCurve16 = cmsBuildTabulatedToneCurve16
-cmsBuildTabulatedToneCurveFloat = cmsBuildTabulatedToneCurveFloat
-_cmsCalloc = _cmsCalloc
-cmsChannelsOf = cmsChannelsOf
-cmsCIE2000DeltaE = cmsCIE2000DeltaE
-cmsCIE94DeltaE = cmsCIE94DeltaE
-cmsCIECAM02Done = cmsCIECAM02Done
-cmsCIECAM02Forward = cmsCIECAM02Forward
-cmsCIECAM02Init = cmsCIECAM02Init
-cmsCIECAM02Reverse = cmsCIECAM02Reverse
-cmsCloseIOhandler = cmsCloseIOhandler
-cmsCloseProfile = cmsCloseProfile
-cmsCMCdeltaE = cmsCMCdeltaE
-cmsCreate_sRGBProfile = cmsCreate_sRGBProfile
-cmsCreate_sRGBProfileTHR = cmsCreate_sRGBProfileTHR
-cmsCreateBCHSWabstractProfile = cmsCreateBCHSWabstractProfile
-cmsCreateBCHSWabstractProfileTHR = cmsCreateBCHSWabstractProfileTHR
-cmsCreateExtendedTransform = cmsCreateExtendedTransform
-cmsCreateGrayProfile = cmsCreateGrayProfile
-cmsCreateGrayProfileTHR = cmsCreateGrayProfileTHR
-cmsCreateInkLimitingDeviceLink = cmsCreateInkLimitingDeviceLink
-cmsCreateInkLimitingDeviceLinkTHR = cmsCreateInkLimitingDeviceLinkTHR
-cmsCreateLab2Profile = cmsCreateLab2Profile
-cmsCreateLab2ProfileTHR = cmsCreateLab2ProfileTHR
-cmsCreateLab4Profile = cmsCreateLab4Profile
-cmsCreateLab4ProfileTHR = cmsCreateLab4ProfileTHR
-cmsCreateLinearizationDeviceLink = cmsCreateLinearizationDeviceLink
-cmsCreateLinearizationDeviceLinkTHR = cmsCreateLinearizationDeviceLinkTHR
-cmsCreateMultiprofileTransform = cmsCreateMultiprofileTransform
-cmsCreateMultiprofileTransformTHR = cmsCreateMultiprofileTransformTHR
-cmsCreateNULLProfile = cmsCreateNULLProfile
-cmsCreateNULLProfileTHR = cmsCreateNULLProfileTHR
-cmsCreateProfilePlaceholder = cmsCreateProfilePlaceholder
-cmsCreateProofingTransform = cmsCreateProofingTransform
-cmsCreateProofingTransformTHR = cmsCreateProofingTransformTHR
-cmsCreateRGBProfile = cmsCreateRGBProfile
-cmsCreateRGBProfileTHR = cmsCreateRGBProfileTHR
-cmsCreateTransform = cmsCreateTransform
-cmsCreateTransformTHR = cmsCreateTransformTHR
-cmsCreateXYZProfile = cmsCreateXYZProfile
-cmsCreateXYZProfileTHR = cmsCreateXYZProfileTHR
-cmsD50_xyY = cmsD50_xyY
-cmsD50_XYZ = cmsD50_XYZ
-_cmsDecodeDateTimeNumber = _cmsDecodeDateTimeNumber
-_cmsDefaultICCintents = _cmsDefaultICCintents
-cmsDeleteTransform = cmsDeleteTransform
-cmsDeltaE = cmsDeltaE
-cmsDetectBlackPoint = cmsDetectBlackPoint
-cmsDetectDestinationBlackPoint = cmsDetectDestinationBlackPoint
-cmsDetectTAC = cmsDetectTAC
-cmsDesaturateLab = cmsDesaturateLab
-cmsDoTransform = cmsDoTransform
-cmsDoTransformStride = cmsDoTransformStride
-_cmsDoubleTo15Fixed16 = _cmsDoubleTo15Fixed16
-_cmsDoubleTo8Fixed8 = _cmsDoubleTo8Fixed8
-_cmsDupMem = _cmsDupMem
-cmsDupNamedColorList = cmsDupNamedColorList
-cmsDupProfileSequenceDescription = cmsDupProfileSequenceDescription
-cmsDupToneCurve = cmsDupToneCurve
-_cmsEncodeDateTimeNumber = _cmsEncodeDateTimeNumber
-cmsEstimateGamma = cmsEstimateGamma
-cmsGetToneCurveEstimatedTableEntries = cmsGetToneCurveEstimatedTableEntries
-cmsGetToneCurveEstimatedTable = cmsGetToneCurveEstimatedTable
-cmsEvalToneCurve16 = cmsEvalToneCurve16
-cmsEvalToneCurveFloat = cmsEvalToneCurveFloat
-cmsfilelength = cmsfilelength
-cmsFloat2LabEncoded = cmsFloat2LabEncoded
-cmsFloat2LabEncodedV2 = cmsFloat2LabEncodedV2
-cmsFloat2XYZEncoded = cmsFloat2XYZEncoded
-cmsFormatterForColorspaceOfProfile = cmsFormatterForColorspaceOfProfile
-cmsFormatterForPCSOfProfile = cmsFormatterForPCSOfProfile
-_cmsFree = _cmsFree
-cmsFreeNamedColorList = cmsFreeNamedColorList
-cmsFreeProfileSequenceDescription = cmsFreeProfileSequenceDescription
-cmsFreeToneCurve = cmsFreeToneCurve
-cmsFreeToneCurveTriple = cmsFreeToneCurveTriple
-cmsGBDAlloc = cmsGBDAlloc
-cmsGBDFree = cmsGBDFree
-cmsGDBAddPoint = cmsGDBAddPoint
-cmsGDBCheckPoint = cmsGDBCheckPoint
-cmsGDBCompute = cmsGDBCompute
-cmsGetAlarmCodes = cmsGetAlarmCodes
-cmsGetColorSpace = cmsGetColorSpace
-cmsGetDeviceClass = cmsGetDeviceClass
-cmsGetEncodedICCversion = cmsGetEncodedICCversion
-cmsGetHeaderAttributes = cmsGetHeaderAttributes
-cmsGetHeaderCreationDateTime = cmsGetHeaderCreationDateTime
-cmsGetHeaderFlags = cmsGetHeaderFlags
-cmsGetHeaderManufacturer = cmsGetHeaderManufacturer
-cmsGetHeaderModel = cmsGetHeaderModel
-cmsGetHeaderProfileID = cmsGetHeaderProfileID
-cmsGetHeaderRenderingIntent = cmsGetHeaderRenderingIntent
-cmsGetNamedColorList = cmsGetNamedColorList
-cmsGetPCS = cmsGetPCS
-cmsGetPostScriptColorResource = cmsGetPostScriptColorResource
-cmsGetPostScriptCRD = cmsGetPostScriptCRD
-cmsGetPostScriptCSA = cmsGetPostScriptCSA
-cmsGetProfileInfo = cmsGetProfileInfo
-cmsGetProfileInfoASCII = cmsGetProfileInfoASCII
-cmsGetProfileContextID = cmsGetProfileContextID
-cmsGetProfileVersion = cmsGetProfileVersion
-cmsGetSupportedIntents = cmsGetSupportedIntents
-cmsGetTagCount = cmsGetTagCount
-cmsGetTagSignature = cmsGetTagSignature
-cmsGetTransformContextID = cmsGetTransformContextID
-_cmsICCcolorSpace = _cmsICCcolorSpace
-_cmsIOPrintf = _cmsIOPrintf
-cmsIsCLUT = cmsIsCLUT
-cmsIsIntentSupported = cmsIsIntentSupported
-cmsIsMatrixShaper = cmsIsMatrixShaper
-cmsIsTag = cmsIsTag
-cmsIsToneCurveDescending = cmsIsToneCurveDescending
-cmsIsToneCurveLinear = cmsIsToneCurveLinear
-cmsIsToneCurveMonotonic = cmsIsToneCurveMonotonic
-cmsIsToneCurveMultisegment = cmsIsToneCurveMultisegment
-cmsGetToneCurveParametricType = cmsGetToneCurveParametricType
-cmsIT8Alloc = cmsIT8Alloc
-cmsIT8DefineDblFormat = cmsIT8DefineDblFormat
-cmsIT8EnumDataFormat = cmsIT8EnumDataFormat
-cmsIT8EnumProperties = cmsIT8EnumProperties
-cmsIT8EnumPropertyMulti = cmsIT8EnumPropertyMulti
-cmsIT8Free = cmsIT8Free
-cmsIT8GetData = cmsIT8GetData
-cmsIT8GetDataDbl = cmsIT8GetDataDbl
-cmsIT8FindDataFormat = cmsIT8FindDataFormat
-cmsIT8GetDataRowCol = cmsIT8GetDataRowCol
-cmsIT8GetDataRowColDbl = cmsIT8GetDataRowColDbl
-cmsIT8GetPatchName = cmsIT8GetPatchName
-cmsIT8GetPatchByName = cmsIT8GetPatchByName
-cmsIT8GetProperty = cmsIT8GetProperty
-cmsIT8GetPropertyDbl = cmsIT8GetPropertyDbl
-cmsIT8GetPropertyMulti = cmsIT8GetPropertyMulti
-cmsIT8GetSheetType = cmsIT8GetSheetType
-cmsIT8LoadFromFile = cmsIT8LoadFromFile
-cmsIT8LoadFromMem = cmsIT8LoadFromMem
-cmsIT8SaveToFile = cmsIT8SaveToFile
-cmsIT8SaveToMem = cmsIT8SaveToMem
-cmsIT8SetComment = cmsIT8SetComment
-cmsIT8SetData = cmsIT8SetData
-cmsIT8SetDataDbl = cmsIT8SetDataDbl
-cmsIT8SetDataFormat = cmsIT8SetDataFormat
-cmsIT8SetDataRowCol = cmsIT8SetDataRowCol
-cmsIT8SetDataRowColDbl = cmsIT8SetDataRowColDbl
-cmsIT8SetPropertyDbl = cmsIT8SetPropertyDbl
-cmsIT8SetPropertyHex = cmsIT8SetPropertyHex
-cmsIT8SetPropertyStr = cmsIT8SetPropertyStr
-cmsIT8SetPropertyMulti = cmsIT8SetPropertyMulti
-cmsIT8SetPropertyUncooked = cmsIT8SetPropertyUncooked
-cmsIT8SetSheetType = cmsIT8SetSheetType
-cmsIT8SetTable = cmsIT8SetTable
-cmsIT8SetTableByLabel = cmsIT8SetTableByLabel
-cmsIT8SetIndexColumn = cmsIT8SetIndexColumn
-cmsIT8TableCount = cmsIT8TableCount
-cmsJoinToneCurve = cmsJoinToneCurve
-cmsLab2LCh = cmsLab2LCh
-cmsLab2XYZ = cmsLab2XYZ
-cmsLabEncoded2Float = cmsLabEncoded2Float
-cmsLabEncoded2FloatV2 = cmsLabEncoded2FloatV2
-cmsLCh2Lab = cmsLCh2Lab
-_cmsLCMScolorSpace = _cmsLCMScolorSpace
-cmsLinkTag = cmsLinkTag
-cmsTagLinkedTo = cmsTagLinkedTo
-cmsPipelineAlloc = cmsPipelineAlloc
-cmsPipelineCat = cmsPipelineCat
-cmsPipelineCheckAndRetreiveStages = cmsPipelineCheckAndRetreiveStages
-cmsPipelineDup = cmsPipelineDup
-cmsPipelineStageCount = cmsPipelineStageCount
-cmsPipelineEval16 = cmsPipelineEval16
-cmsPipelineEvalFloat = cmsPipelineEvalFloat
-cmsPipelineEvalReverseFloat = cmsPipelineEvalReverseFloat
-cmsPipelineFree = cmsPipelineFree
-cmsPipelineGetPtrToFirstStage = cmsPipelineGetPtrToFirstStage
-cmsPipelineGetPtrToLastStage = cmsPipelineGetPtrToLastStage
-cmsPipelineInputChannels = cmsPipelineInputChannels
-cmsPipelineInsertStage = cmsPipelineInsertStage
-cmsPipelineOutputChannels = cmsPipelineOutputChannels
-cmsPipelineSetSaveAs8bitsFlag = cmsPipelineSetSaveAs8bitsFlag
-_cmsPipelineSetOptimizationParameters = _cmsPipelineSetOptimizationParameters
-cmsPipelineUnlinkStage = cmsPipelineUnlinkStage
-_cmsMalloc = _cmsMalloc
-_cmsMallocZero = _cmsMallocZero
-_cmsMAT3eval = _cmsMAT3eval
-_cmsMAT3identity = _cmsMAT3identity
-_cmsMAT3inverse = _cmsMAT3inverse
-_cmsMAT3isIdentity = _cmsMAT3isIdentity
-_cmsMAT3per = _cmsMAT3per
-_cmsMAT3solve = _cmsMAT3solve
-cmsMD5computeID = cmsMD5computeID
-cmsMLUalloc = cmsMLUalloc
-cmsMLUdup = cmsMLUdup
-cmsMLUfree = cmsMLUfree
-cmsMLUgetASCII = cmsMLUgetASCII
-cmsMLUgetTranslation = cmsMLUgetTranslation
-cmsMLUgetWide = cmsMLUgetWide
-cmsMLUsetASCII = cmsMLUsetASCII
-cmsMLUsetWide = cmsMLUsetWide
-cmsStageAllocCLut16bit = cmsStageAllocCLut16bit
-cmsStageAllocCLut16bitGranular = cmsStageAllocCLut16bitGranular
-cmsStageAllocCLutFloat = cmsStageAllocCLutFloat
-cmsStageAllocCLutFloatGranular = cmsStageAllocCLutFloatGranular
-cmsStageAllocToneCurves = cmsStageAllocToneCurves
-cmsStageAllocIdentity = cmsStageAllocIdentity
-cmsStageAllocMatrix = cmsStageAllocMatrix
-_cmsStageAllocPlaceholder = _cmsStageAllocPlaceholder
-cmsStageDup = cmsStageDup
-cmsStageFree = cmsStageFree
-cmsStageNext = cmsStageNext
-cmsStageInputChannels = cmsStageInputChannels
-cmsStageOutputChannels = cmsStageOutputChannels
-cmsStageSampleCLut16bit = cmsStageSampleCLut16bit
-cmsStageSampleCLutFloat = cmsStageSampleCLutFloat
-cmsStageType = cmsStageType
-cmsStageData = cmsStageData
-cmsNamedColorCount = cmsNamedColorCount
-cmsNamedColorIndex = cmsNamedColorIndex
-cmsNamedColorInfo = cmsNamedColorInfo
-cmsOpenIOhandlerFromFile = cmsOpenIOhandlerFromFile
-cmsOpenIOhandlerFromMem = cmsOpenIOhandlerFromMem
-cmsOpenIOhandlerFromNULL = cmsOpenIOhandlerFromNULL
-cmsOpenIOhandlerFromStream = cmsOpenIOhandlerFromStream
-cmsOpenProfileFromFile = cmsOpenProfileFromFile
-cmsOpenProfileFromFileTHR = cmsOpenProfileFromFileTHR
-cmsOpenProfileFromIOhandlerTHR = cmsOpenProfileFromIOhandlerTHR
-cmsOpenProfileFromMem = cmsOpenProfileFromMem
-cmsOpenProfileFromMemTHR = cmsOpenProfileFromMemTHR
-cmsOpenProfileFromStream = cmsOpenProfileFromStream
-cmsOpenProfileFromStreamTHR = cmsOpenProfileFromStreamTHR
-cmsPlugin = cmsPlugin
-_cmsRead15Fixed16Number = _cmsRead15Fixed16Number
-_cmsReadAlignment = _cmsReadAlignment
-_cmsReadFloat32Number = _cmsReadFloat32Number
-cmsReadRawTag = cmsReadRawTag
-cmsReadTag = cmsReadTag
-_cmsReadTypeBase = _cmsReadTypeBase
-_cmsReadUInt16Array = _cmsReadUInt16Array
-_cmsReadUInt16Number = _cmsReadUInt16Number
-_cmsReadUInt32Number = _cmsReadUInt32Number
-_cmsReadUInt64Number = _cmsReadUInt64Number
-_cmsReadUInt8Number = _cmsReadUInt8Number
-_cmsReadXYZNumber = _cmsReadXYZNumber
-_cmsRealloc = _cmsRealloc
-cmsReverseToneCurve = cmsReverseToneCurve
-cmsReverseToneCurveEx = cmsReverseToneCurveEx
-cmsSaveProfileToFile = cmsSaveProfileToFile
-cmsSaveProfileToIOhandler = cmsSaveProfileToIOhandler
-cmsSaveProfileToMem = cmsSaveProfileToMem
-cmsSaveProfileToStream = cmsSaveProfileToStream
-cmsSetAdaptationState = cmsSetAdaptationState
-cmsSetAlarmCodes = cmsSetAlarmCodes
-cmsSetColorSpace = cmsSetColorSpace
-cmsSetDeviceClass = cmsSetDeviceClass
-cmsSetEncodedICCversion = cmsSetEncodedICCversion
-cmsSetHeaderAttributes = cmsSetHeaderAttributes
-cmsSetHeaderFlags = cmsSetHeaderFlags
-cmsSetHeaderManufacturer = cmsSetHeaderManufacturer
-cmsSetHeaderModel = cmsSetHeaderModel
-cmsSetHeaderProfileID = cmsSetHeaderProfileID
-cmsSetHeaderRenderingIntent = cmsSetHeaderRenderingIntent
-cmsSetLogErrorHandler = cmsSetLogErrorHandler
-cmsSetPCS = cmsSetPCS
-cmsSetProfileVersion = cmsSetProfileVersion
-cmsSignalError = cmsSignalError
-cmsSmoothToneCurve = cmsSmoothToneCurve
-cmsstrcasecmp = cmsstrcasecmp
-cmsTempFromWhitePoint = cmsTempFromWhitePoint
-cmsTransform2DeviceLink = cmsTransform2DeviceLink
-cmsUnregisterPlugins = cmsUnregisterPlugins
-_cmsVEC3cross = _cmsVEC3cross
-_cmsVEC3distance = _cmsVEC3distance
-_cmsVEC3dot = _cmsVEC3dot
-_cmsVEC3init = _cmsVEC3init
-_cmsVEC3length = _cmsVEC3length
-_cmsVEC3minus = _cmsVEC3minus
-cmsWhitePointFromTemp = cmsWhitePointFromTemp
-_cmsWrite15Fixed16Number = _cmsWrite15Fixed16Number
-_cmsWriteAlignment = _cmsWriteAlignment
-_cmsWriteFloat32Number = _cmsWriteFloat32Number
-cmsWriteRawTag = cmsWriteRawTag
-cmsWriteTag = cmsWriteTag
-_cmsWriteTypeBase = _cmsWriteTypeBase
-_cmsWriteUInt16Array = _cmsWriteUInt16Array
-_cmsWriteUInt16Number = _cmsWriteUInt16Number
-_cmsWriteUInt32Number = _cmsWriteUInt32Number
-_cmsWriteUInt64Number = _cmsWriteUInt64Number
-_cmsWriteUInt8Number = _cmsWriteUInt8Number
-_cmsWriteXYZNumber = _cmsWriteXYZNumber
-cmsxyY2XYZ = cmsxyY2XYZ
-cmsXYZ2Lab = cmsXYZ2Lab
-cmsXYZ2xyY = cmsXYZ2xyY
-cmsXYZEncoded2Float = cmsXYZEncoded2Float
-cmsSliceSpace16 = cmsSliceSpace16
-cmsSliceSpaceFloat = cmsSliceSpaceFloat
-cmsChangeBuffersFormat = cmsChangeBuffersFormat
-cmsDictAlloc = cmsDictAlloc
-cmsDictFree = cmsDictFree
-cmsDictDup = cmsDictDup
-cmsDictAddEntry = cmsDictAddEntry
-cmsDictGetEntryList = cmsDictGetEntryList
-cmsDictNextEntry = cmsDictNextEntry
-_cmsGetTransformUserData = _cmsGetTransformUserData
-_cmsSetTransformUserData = _cmsSetTransformUserData
-_cmsGetTransformFormatters16 = _cmsGetTransformFormatters16
-_cmsGetTransformFormattersFloat = _cmsGetTransformFormattersFloat
-cmsGetHeaderCreator = cmsGetHeaderCreator
-cmsPluginTHR = cmsPluginTHR
-cmsGetPipelineContextID = cmsGetPipelineContextID
-cmsGetTransformInputFormat = cmsGetTransformInputFormat
-cmsGetTransformOutputFormat = cmsGetTransformOutputFormat
-cmsCreateContext = cmsCreateContext
-cmsDupContext = cmsDupContext
-cmsDeleteContext = cmsDeleteContext
-cmsGetContextUserData = cmsGetContextUserData
-cmsUnregisterPluginsTHR = cmsUnregisterPluginsTHR
-cmsSetAlarmCodesTHR = cmsSetAlarmCodesTHR
-cmsGetAlarmCodesTHR = cmsGetAlarmCodesTHR
-cmsSetAdaptationStateTHR = cmsSetAdaptationStateTHR
-cmsSetLogErrorHandlerTHR = cmsSetLogErrorHandlerTHR
-cmsGetSupportedIntentsTHR = cmsGetSupportedIntentsTHR
-cmsMLUtranslationsCount = cmsMLUtranslationsCount
-cmsMLUtranslationsCodes = cmsMLUtranslationsCodes
-_cmsCreateMutex = _cmsCreateMutex
-_cmsDestroyMutex = _cmsDestroyMutex
-_cmsLockMutex = _cmsLockMutex
-_cmsUnlockMutex = _cmsUnlockMutex \ No newline at end of file
diff --git a/thirdparty/liblcms2/src/lcms2_internal.h b/thirdparty/liblcms2/src/lcms2_internal.h
index 1a648302..e1219036 100644
--- a/thirdparty/liblcms2/src/lcms2_internal.h
+++ b/thirdparty/liblcms2/src/lcms2_internal.h
@@ -1,7 +1,7 @@
//
// Little Color Management System
-// Copyright (c) 1998-2014 Marti Maria Saguer
+// Copyright (c) 1998-2016 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -57,7 +57,15 @@
#define _cmsALIGNLONG(x) (((x)+(sizeof(cmsUInt32Number)-1)) & ~(sizeof(cmsUInt32Number)-1))
// Alignment to memory pointer
-#define _cmsALIGNMEM(x) (((x)+(sizeof(void *) - 1)) & ~(sizeof(void *) - 1))
+
+// (Ultra)SPARC with gcc requires ptr alignment of 8 bytes
+// even though sizeof(void *) is only four: for greatest flexibility
+// allow the build to specify ptr alignment.
+#ifndef CMS_PTR_ALIGNMENT
+# define CMS_PTR_ALIGNMENT sizeof(void *)
+#endif
+
+#define _cmsALIGNMEM(x) (((x)+(CMS_PTR_ALIGNMENT - 1)) & ~(CMS_PTR_ALIGNMENT - 1))
// Maximum encodeable values in floating point
#define MAX_ENCODEABLE_XYZ (1.0 + 32767.0/32768.0)
@@ -194,11 +202,17 @@ cmsINLINE cmsUInt16Number _cmsQuickSaturateWord(cmsFloat64Number d)
// Microsoft felt that it was necessary to keep it set at -1 for an unlocked critical
// section, even when they changed the underlying algorithm to be more scalable.
// The final parts of the critical section object are unimportant, and can be set
-// to zero for their defaults. This yields an initialization macro:
+// to zero for their defaults. This yields to an initialization macro:
typedef CRITICAL_SECTION _cmsMutex;
-#define CMS_MUTEX_INITIALIZER {(void*) -1,-1,0,0,0,0}
+#define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG) -1,-1,0,0,0,0}
+
+#ifdef _MSC_VER
+# if (_MSC_VER >= 1800)
+# pragma warning(disable : 26135)
+# endif
+#endif
cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
{
@@ -284,38 +298,38 @@ typedef int _cmsMutex;
cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
{
- return 0;
cmsUNUSED_PARAMETER(m);
+ return 0;
}
cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
{
- return 0;
cmsUNUSED_PARAMETER(m);
+ return 0;
}
cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
{
- return 0;
cmsUNUSED_PARAMETER(m);
+ return 0;
}
cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
{
- return 0;
cmsUNUSED_PARAMETER(m);
+ return 0;
}
cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
{
- return 0;
cmsUNUSED_PARAMETER(m);
+ return 0;
}
cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
{
- return 0;
cmsUNUSED_PARAMETER(m);
+ return 0;
}
#endif
@@ -656,8 +670,8 @@ struct _cms_MLU_struct {
cmsContext ContextID;
// The directory
- int AllocatedEntries;
- int UsedEntries;
+ cmsUInt32Number AllocatedEntries;
+ cmsUInt32Number UsedEntries;
_cmsMLUentry* Entries; // Array of pointers to strings allocated in MemPool
// The Pool
@@ -823,6 +837,8 @@ cmsStage* _cmsStageNormalizeFromLabFloat(cmsContext ContextID);
cmsStage* _cmsStageNormalizeFromXyzFloat(cmsContext ContextID);
cmsStage* _cmsStageNormalizeToLabFloat(cmsContext ContextID);
cmsStage* _cmsStageNormalizeToXyzFloat(cmsContext ContextID);
+cmsStage* _cmsStageClipNegatives(cmsContext ContextID, int nChannels);
+
// For curve set only
cmsToneCurve** _cmsStageGetPtrToCurveSet(const cmsStage* mpe);
@@ -951,7 +967,7 @@ typedef struct _cmstransform_struct {
cmsUInt32Number InputFormat, OutputFormat; // Keep formats for further reference
// Points to transform code
- _cmsTransformFn xform;
+ _cmsTransform2Fn xform;
// Formatters, cannot be embedded into LUT because cache
cmsFormatter16 FromInput;
@@ -997,9 +1013,20 @@ typedef struct _cmstransform_struct {
void* UserData;
_cmsFreeUserDataFn FreeUserData;
+ // A way to provide backwards compatibility with full xform plugins
+ _cmsTransformFn OldXform;
+
} _cmsTRANSFORM;
-// --------------------------------------------------------------------------------------------------
+// Copies extra channels from input to output if the original flags in the transform structure
+// instructs to do so. This function is called on all standard transform functions.
+void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,
+ void* out,
+ cmsUInt32Number PixelsPerLine,
+ cmsUInt32Number LineCount,
+ const cmsStride* Stride);
+
+// -----------------------------------------------------------------------------------------------------------------------
cmsHTRANSFORM _cmsChain2Lab(cmsContext ContextID,
cmsUInt32Number nProfiles,