Upgrade to lcms 2.12.
Update 0030-const-data.patch to patch cleanly, as some of the data to be
made const has changed.
Change-Id: Ie09cc33a7c97f70f061783a57c80024d2c5c4d8e
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/85430
Reviewed-by: Daniel Hosseinian <dhoss@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/third_party/lcms/0030-const-data.patch b/third_party/lcms/0030-const-data.patch
index 3b28020..42a3b93 100644
--- a/third_party/lcms/0030-const-data.patch
+++ b/third_party/lcms/0030-const-data.patch
@@ -21,9 +21,9 @@
// The built-in list
-static _cmsParametricCurvesCollection DefaultCurves = {
+static const _cmsParametricCurvesCollection DefaultCurves = {
- 9, // # of curve types
- { 1, 2, 3, 4, 5, 6, 7, 8, 108 }, // Parametric curve ID
- { 1, 3, 4, 5, 7, 4, 5, 5, 1 }, // Parameters by type
+ 10, // # of curve types
+ { 1, 2, 3, 4, 5, 6, 7, 8, 108, 109 }, // Parametric curve ID
+ { 1, 3, 4, 5, 7, 4, 5, 5, 1, 1 }, // Parameters by type
@@ -162,7 +162,7 @@ cmsBool _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase*
// Search in type list, return position or -1 if not found
diff --git a/third_party/lcms/include/lcms2.h b/third_party/lcms/include/lcms2.h
index a8237d7..f60f5f7 100644
--- a/third_party/lcms/include/lcms2.h
+++ b/third_party/lcms/include/lcms2.h
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2020 Marti Maria Saguer
+// Copyright (c) 1998-2021 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -23,7 +23,7 @@
//
//---------------------------------------------------------------------------------
//
-// Version 2.11
+// Version 2.12
//
#ifndef _lcms2_H
@@ -81,7 +81,7 @@
#endif
// Version/release
-#define LCMS_VERSION 2100
+#define LCMS_VERSION 2120
// I will give the chance of redefining basic types for compilers that are not fully C99 compliant
#ifndef CMS_BASIC_TYPES_ALREADY_DEFINED
@@ -1270,7 +1270,7 @@
#define SAMPLER_INSPECT 0x01000000
// For CLUT only
-CMSAPI cmsBool CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe, cmsSAMPLER16 Sampler, void* Cargo, cmsUInt32Number dwFlags);
+CMSAPI cmsBool CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe, cmsSAMPLER16 Sampler, void* Cargo, cmsUInt32Number dwFlags);
CMSAPI cmsBool CMSEXPORT cmsStageSampleCLutFloat(cmsStage* mpe, cmsSAMPLERFLOAT Sampler, void* Cargo, cmsUInt32Number dwFlags);
// Slicers
diff --git a/third_party/lcms/include/lcms2_plugin.h b/third_party/lcms/include/lcms2_plugin.h
index c36998e..5bc8227 100644
--- a/third_party/lcms/include/lcms2_plugin.h
+++ b/third_party/lcms/include/lcms2_plugin.h
@@ -286,7 +286,7 @@
#define CMS_LERP_FLAGS_TRILINEAR 0x0100 // Hint only
-#define MAX_INPUT_DIMENSIONS 8
+#define MAX_INPUT_DIMENSIONS 15
typedef struct _cms_interp_struc { // Used on all interpolations. Supplied by lcms2 when calling the interpolation function
@@ -547,22 +547,28 @@
// the optimization search. Or FALSE if it is unable to optimize and want to give a chance
// to the rest of optimizers.
-typedef void (* _cmsOPTeval16Fn)(CMSREGISTER const cmsUInt16Number In[],
- CMSREGISTER cmsUInt16Number Out[],
- CMSREGISTER const void* Data);
-
-
typedef cmsBool (* _cmsOPToptimizeFn)(cmsPipeline** Lut,
cmsUInt32Number Intent,
cmsUInt32Number* InputFormat,
cmsUInt32Number* OutputFormat,
cmsUInt32Number* dwFlags);
+// Pipeline Evaluator (in 16 bits)
+typedef void (* _cmsPipelineEval16Fn)(CMSREGISTER const cmsUInt16Number In[],
+ CMSREGISTER cmsUInt16Number Out[],
+ const void* Data);
+
+// Pipeline Evaluator (in floating point)
+typedef void (* _cmsPipelineEvalFloatFn)(const cmsFloat32Number In[],
+ cmsFloat32Number Out[],
+ const void* Data);
+
+
// This function may be used to set the optional evaluator and a block of private data. If private data is being used, an optional
// duplicator and free functions should also be specified in order to duplicate the LUT construct. Use NULL to inhibit such functionality.
CMSAPI void CMSEXPORT _cmsPipelineSetOptimizationParameters(cmsPipeline* Lut,
- _cmsOPTeval16Fn Eval16,
+ _cmsPipelineEval16Fn Eval16,
void* PrivateData,
_cmsFreeUserDataFn FreePrivateDataFn,
_cmsDupUserDataFn DupPrivateDataFn);
@@ -626,6 +632,9 @@
CMSAPI void CMSEXPORT _cmsGetTransformFormatters16 (struct _cmstransform_struct *CMMcargo, cmsFormatter16* FromInput, cmsFormatter16* ToOutput);
CMSAPI void CMSEXPORT _cmsGetTransformFormattersFloat(struct _cmstransform_struct *CMMcargo, cmsFormatterFloat* FromInput, cmsFormatterFloat* ToOutput);
+// Retrieve original flags
+CMSAPI cmsUInt32Number CMSEXPORT _cmsGetTransformFlags(struct _cmstransform_struct* CMMcargo);
+
typedef struct {
cmsPluginBase base;
diff --git a/third_party/lcms/src/cmsalpha.c b/third_party/lcms/src/cmsalpha.c
index a211318..36fdc9c 100644
--- a/third_party/lcms/src/cmsalpha.c
+++ b/third_party/lcms/src/cmsalpha.c
@@ -75,7 +75,7 @@
void from8to16(void* dst, const void* src)
{
cmsUInt8Number n = *(cmsUInt8Number*)src;
- *(cmsUInt16Number*) dst = FROM_8_TO_16(n);
+ *(cmsUInt16Number*) dst = (cmsUInt16Number) FROM_8_TO_16(n);
}
static
@@ -88,13 +88,13 @@
static
void from8toFLT(void* dst, const void* src)
{
- *(cmsFloat32Number*)dst = (*(cmsUInt8Number*)src) / 255.0f;
+ *(cmsFloat32Number*)dst = (cmsFloat32Number) (*(cmsUInt8Number*)src) / 255.0f;
}
static
void from8toDBL(void* dst, const void* src)
{
- *(cmsFloat64Number*)dst = (*(cmsUInt8Number*)src) / 255.0;
+ *(cmsFloat64Number*)dst = (cmsFloat64Number) (*(cmsUInt8Number*)src) / 255.0;
}
static
@@ -153,13 +153,13 @@
static
void from16toDBL(void* dst, const void* src)
{
- *(cmsFloat64Number*)dst = (*(cmsUInt16Number*)src) / 65535.0f;
+ *(cmsFloat64Number*)dst = (cmsFloat64Number) (*(cmsUInt16Number*)src) / 65535.0;
}
static
void from16SEtoDBL(void* dst, const void* src)
{
- *(cmsFloat64Number*)dst = (CHANGE_ENDIAN(*(cmsUInt16Number*)src)) / 65535.0f;
+ *(cmsFloat64Number*)dst = (cmsFloat64Number) (CHANGE_ENDIAN(*(cmsUInt16Number*)src)) / 65535.0;
}
static
diff --git a/third_party/lcms/src/cmscgats.c b/third_party/lcms/src/cmscgats.c
index 217c67a..e0d5c12 100644
--- a/third_party/lcms/src/cmscgats.c
+++ b/third_party/lcms/src/cmscgats.c
@@ -1499,6 +1499,14 @@
return SetDataFormat(it8, n, Sample);
}
+// A safe atoi that returns 0 when NULL input is given
+static
+cmsInt32Number satoi(const char* b)
+{
+ if (b == NULL) return 0;
+ return atoi(b);
+}
+
static
void AllocateDataSet(cmsIT8* it8)
{
@@ -1506,14 +1514,15 @@
if (t -> Data) return; // Already allocated
- t-> nSamples = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
- t-> nPatches = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS"));
+ t-> nSamples = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
+ t-> nPatches = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS"));
if (t -> nSamples < 0 || t->nSamples > 0x7ffe || t->nPatches < 0 || t->nPatches > 0x7ffe)
{
SynError(it8, "AllocateDataSet: too much data");
}
else {
+ // Some dumb analizers warns of possible overflow here, just take a look couple of lines above.
t->Data = (char**)AllocChunk(it8, ((cmsUInt32Number)t->nSamples + 1) * ((cmsUInt32Number)t->nPatches + 1) * sizeof(char*));
if (t->Data == NULL) {
@@ -1679,11 +1688,11 @@
break;
case WRITE_HEXADECIMAL:
- Writef(fp, "\t0x%X", atoi(p ->Value));
+ Writef(fp, "\t0x%X", satoi(p ->Value));
break;
case WRITE_BINARY:
- Writef(fp, "\t0x%B", atoi(p ->Value));
+ Writef(fp, "\t0x%B", satoi(p ->Value));
break;
case WRITE_PAIR:
@@ -1712,7 +1721,7 @@
WriteStr(fp, "BEGIN_DATA_FORMAT\n");
WriteStr(fp, " ");
- nSamples = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
+ nSamples = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
for (i = 0; i < nSamples; i++) {
@@ -1735,7 +1744,7 @@
WriteStr (fp, "BEGIN_DATA\n");
- t->nPatches = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS"));
+ t->nPatches = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS"));
for (i = 0; i < t-> nPatches; i++) {
diff --git a/third_party/lcms/src/cmscnvrt.c b/third_party/lcms/src/cmscnvrt.c
index 301c3c8..b471da7 100644
--- a/third_party/lcms/src/cmscnvrt.c
+++ b/third_party/lcms/src/cmscnvrt.c
@@ -730,6 +730,9 @@
cmsUInt32Number ICCIntents[256];
cmsStage* CLUT;
cmsUInt32Number i, nGridPoints;
+ cmsUInt32Number lastProfilePos;
+ cmsUInt32Number preservationProfilesCount;
+ cmsHPROFILE hLastProfile;
// Sanity check
@@ -739,20 +742,36 @@
for (i=0; i < nProfiles; i++)
ICCIntents[i] = TranslateNonICCIntents(TheIntents[i]);
+
+ // Trim all CMYK devicelinks at the end
+ lastProfilePos = nProfiles - 1;
+ hLastProfile = hProfiles[lastProfilePos];
+
+ while (lastProfilePos > 1)
+ {
+ hLastProfile = hProfiles[--lastProfilePos];
+ if (cmsGetColorSpace(hLastProfile) != cmsSigCmykData ||
+ cmsGetDeviceClass(hLastProfile) != cmsSigLinkClass)
+ break;
+ }
+
+ preservationProfilesCount = lastProfilePos + 1;
+
// Check for non-cmyk profiles
if (cmsGetColorSpace(hProfiles[0]) != cmsSigCmykData ||
- cmsGetColorSpace(hProfiles[nProfiles-1]) != cmsSigCmykData)
+ !(cmsGetColorSpace(hLastProfile) == cmsSigCmykData ||
+ cmsGetDeviceClass(hLastProfile) == cmsSigOutputClass))
return DefaultICCintents(ContextID, nProfiles, ICCIntents, hProfiles, BPC, AdaptationStates, dwFlags);
- memset(&bp, 0, sizeof(bp));
-
// Allocate an empty LUT for holding the result
Result = cmsPipelineAlloc(ContextID, 4, 4);
if (Result == NULL) return NULL;
+ memset(&bp, 0, sizeof(bp));
+
// Create a LUT holding normal ICC transform
bp.cmyk2cmyk = DefaultICCintents(ContextID,
- nProfiles,
+ preservationProfilesCount,
ICCIntents,
hProfiles,
BPC,
@@ -764,7 +783,7 @@
// Now, compute the tone curve
bp.KTone = _cmsBuildKToneCurve(ContextID,
4096,
- nProfiles,
+ preservationProfilesCount,
ICCIntents,
hProfiles,
BPC,
@@ -789,6 +808,19 @@
if (!cmsStageSampleCLut16bit(CLUT, BlackPreservingGrayOnlySampler, (void*) &bp, 0))
goto Error;
+
+ // Insert possible devicelinks at the end
+ for (i = lastProfilePos + 1; i < nProfiles; i++)
+ {
+ cmsPipeline* devlink = _cmsReadDevicelinkLUT(hProfiles[i], ICCIntents[i]);
+ if (devlink == NULL)
+ goto Error;
+
+ if (!cmsPipelineCat(Result, devlink))
+ goto Error;
+ }
+
+
// Get rid of xform and tone curve
cmsPipelineFree(bp.cmyk2cmyk);
cmsFreeToneCurve(bp.KTone);
@@ -907,6 +939,8 @@
return TRUE;
}
+
+
// This is the entry for black-plane preserving, which are non-ICC
static
cmsPipeline* BlackPreservingKPlaneIntents(cmsContext ContextID,
@@ -918,10 +952,14 @@
cmsUInt32Number dwFlags)
{
PreserveKPlaneParams bp;
+
cmsPipeline* Result = NULL;
cmsUInt32Number ICCIntents[256];
cmsStage* CLUT;
cmsUInt32Number i, nGridPoints;
+ cmsUInt32Number lastProfilePos;
+ cmsUInt32Number preservationProfilesCount;
+ cmsHPROFILE hLastProfile;
cmsHPROFILE hLab;
// Sanity check
@@ -931,32 +969,45 @@
for (i=0; i < nProfiles; i++)
ICCIntents[i] = TranslateNonICCIntents(TheIntents[i]);
+ // Trim all CMYK devicelinks at the end
+ lastProfilePos = nProfiles - 1;
+ hLastProfile = hProfiles[lastProfilePos];
+
+ while (lastProfilePos > 1)
+ {
+ hLastProfile = hProfiles[--lastProfilePos];
+ if (cmsGetColorSpace(hLastProfile) != cmsSigCmykData ||
+ cmsGetDeviceClass(hLastProfile) != cmsSigLinkClass)
+ break;
+ }
+
+ preservationProfilesCount = lastProfilePos + 1;
+
// Check for non-cmyk profiles
if (cmsGetColorSpace(hProfiles[0]) != cmsSigCmykData ||
- !(cmsGetColorSpace(hProfiles[nProfiles-1]) == cmsSigCmykData ||
- cmsGetDeviceClass(hProfiles[nProfiles-1]) == cmsSigOutputClass))
+ !(cmsGetColorSpace(hLastProfile) == cmsSigCmykData ||
+ cmsGetDeviceClass(hLastProfile) == cmsSigOutputClass))
return DefaultICCintents(ContextID, nProfiles, ICCIntents, hProfiles, BPC, AdaptationStates, dwFlags);
// Allocate an empty LUT for holding the result
Result = cmsPipelineAlloc(ContextID, 4, 4);
if (Result == NULL) return NULL;
-
memset(&bp, 0, sizeof(bp));
// We need the input LUT of the last profile, assuming this one is responsible of
// black generation. This LUT will be searched in inverse order.
- bp.LabK2cmyk = _cmsReadInputLUT(hProfiles[nProfiles-1], INTENT_RELATIVE_COLORIMETRIC);
+ bp.LabK2cmyk = _cmsReadInputLUT(hLastProfile, INTENT_RELATIVE_COLORIMETRIC);
if (bp.LabK2cmyk == NULL) goto Cleanup;
// Get total area coverage (in 0..1 domain)
- bp.MaxTAC = cmsDetectTAC(hProfiles[nProfiles-1]) / 100.0;
+ bp.MaxTAC = cmsDetectTAC(hLastProfile) / 100.0;
if (bp.MaxTAC <= 0) goto Cleanup;
// Create a LUT holding normal ICC transform
bp.cmyk2cmyk = DefaultICCintents(ContextID,
- nProfiles,
+ preservationProfilesCount,
ICCIntents,
hProfiles,
BPC,
@@ -965,7 +1016,7 @@
if (bp.cmyk2cmyk == NULL) goto Cleanup;
// Now the tone curve
- bp.KTone = _cmsBuildKToneCurve(ContextID, 4096, nProfiles,
+ bp.KTone = _cmsBuildKToneCurve(ContextID, 4096, preservationProfilesCount,
ICCIntents,
hProfiles,
BPC,
@@ -975,14 +1026,14 @@
// To measure the output, Last profile to Lab
hLab = cmsCreateLab4ProfileTHR(ContextID, NULL);
- bp.hProofOutput = cmsCreateTransformTHR(ContextID, hProfiles[nProfiles-1],
+ bp.hProofOutput = cmsCreateTransformTHR(ContextID, hLastProfile,
CHANNELS_SH(4)|BYTES_SH(2), hLab, TYPE_Lab_DBL,
INTENT_RELATIVE_COLORIMETRIC,
cmsFLAGS_NOCACHE|cmsFLAGS_NOOPTIMIZE);
if ( bp.hProofOutput == NULL) goto Cleanup;
// Same as anterior, but lab in the 0..1 range
- bp.cmyk2Lab = cmsCreateTransformTHR(ContextID, hProfiles[nProfiles-1],
+ bp.cmyk2Lab = cmsCreateTransformTHR(ContextID, hLastProfile,
FLOAT_SH(1)|CHANNELS_SH(4)|BYTES_SH(4), hLab,
FLOAT_SH(1)|CHANNELS_SH(3)|BYTES_SH(4),
INTENT_RELATIVE_COLORIMETRIC,
@@ -1005,6 +1056,18 @@
cmsStageSampleCLut16bit(CLUT, BlackPreservingSampler, (void*) &bp, 0);
+ // Insert possible devicelinks at the end
+ for (i = lastProfilePos + 1; i < nProfiles; i++)
+ {
+ cmsPipeline* devlink = _cmsReadDevicelinkLUT(hProfiles[i], ICCIntents[i]);
+ if (devlink == NULL)
+ goto Cleanup;
+
+ if (!cmsPipelineCat(Result, devlink))
+ goto Cleanup;
+ }
+
+
Cleanup:
if (bp.cmyk2cmyk) cmsPipelineFree(bp.cmyk2cmyk);
@@ -1017,6 +1080,8 @@
return Result;
}
+
+
// Link routines ------------------------------------------------------------------------------------------------------
// Chain several profiles into a single LUT. It just checks the parameters and then calls the handler
diff --git a/third_party/lcms/src/cmsgamma.c b/third_party/lcms/src/cmsgamma.c
index bef57ae..08a7c22 100644
--- a/third_party/lcms/src/cmsgamma.c
+++ b/third_party/lcms/src/cmsgamma.c
@@ -59,11 +59,11 @@
// The built-in list
static const _cmsParametricCurvesCollection DefaultCurves = {
- 9, // # of curve types
- { 1, 2, 3, 4, 5, 6, 7, 8, 108 }, // Parametric curve ID
- { 1, 3, 4, 5, 7, 4, 5, 5, 1 }, // Parameters by type
- DefaultEvalParametricFn, // Evaluator
- NULL // Next in chain
+ 10, // # of curve types
+ { 1, 2, 3, 4, 5, 6, 7, 8, 108, 109 }, // Parametric curve ID
+ { 1, 3, 4, 5, 7, 4, 5, 5, 1, 1 }, // Parameters by type
+ DefaultEvalParametricFn, // Evaluator
+ NULL // Next in chain
};
// Duplicates the zone of memory used by the plug-in in the new context
@@ -309,6 +309,32 @@
}
+// Generates a sigmoidal function with desired steepness.
+cmsINLINE double sigmoid_base(double k, double t)
+{
+ return (1.0 / (1.0 + exp(-k * t))) - 0.5;
+}
+
+cmsINLINE double inverted_sigmoid_base(double k, double t)
+{
+ return -log((1.0 / (t + 0.5)) - 1.0) / k;
+}
+
+cmsINLINE double sigmoid_factory(double k, double t)
+{
+ double correction = 0.5 / sigmoid_base(k, 1);
+
+ return correction * sigmoid_base(k, 2.0 * t - 1.0) + 0.5;
+}
+
+cmsINLINE double inverse_sigmoid_factory(double k, double t)
+{
+ double correction = 0.5 / sigmoid_base(k, 1);
+
+ return (inverted_sigmoid_base(k, (t - 0.5) / correction) + 1.0) / 2.0;
+}
+
+
// Parametric Fn using floating point
static
cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Number Params[], cmsFloat64Number R)
@@ -640,6 +666,7 @@
}
break;
+
// S-Shaped: (1 - (1-x)^1/g)^1/g
case 108:
if (fabs(Params[0]) < MATRIX_DET_TOLERANCE)
@@ -657,6 +684,15 @@
Val = 1 - pow(1 - pow(R, Params[0]), Params[0]);
break;
+ // Sigmoidals
+ case 109:
+ Val = sigmoid_factory(Params[0], R);
+ break;
+
+ case -109:
+ Val = inverse_sigmoid_factory(Params[0], R);
+ break;
+
default:
// Unsupported parametric curve. Should never reach here
return 0;
@@ -957,7 +993,7 @@
//Iterate
for (i=0; i < nResultingPoints; i++) {
- t = (cmsFloat32Number) i / (nResultingPoints-1);
+ t = (cmsFloat32Number) i / (cmsFloat32Number)(nResultingPoints-1);
x = cmsEvalToneCurveFloat(X, t);
Res[i] = cmsEvalToneCurveFloat(Yreversed, x);
}
@@ -1171,6 +1207,7 @@
cmsBool SuccessStatus = TRUE;
cmsFloat32Number *w, *y, *z;
cmsUInt32Number i, nItems, Zeros, Poles;
+ cmsBool notCheck = FALSE;
if (Tab != NULL && Tab->InterpParams != NULL)
{
@@ -1198,6 +1235,12 @@
w[i + 1] = 1.0;
}
+ if (lambda < 0)
+ {
+ notCheck = TRUE;
+ lambda = -lambda;
+ }
+
if (smooth2(ContextID, w, y, z, (cmsFloat32Number)lambda, (int)nItems))
{
// Do some reality - checking...
@@ -1210,7 +1253,7 @@
if (z[i] < z[i - 1])
{
cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Non-Monotonic.");
- SuccessStatus = FALSE;
+ SuccessStatus = notCheck;
break;
}
}
@@ -1218,13 +1261,13 @@
if (SuccessStatus && Zeros > (nItems / 3))
{
cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Degenerated, mostly zeros.");
- SuccessStatus = FALSE;
+ SuccessStatus = notCheck;
}
if (SuccessStatus && Poles > (nItems / 3))
{
cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Degenerated, mostly poles.");
- SuccessStatus = FALSE;
+ SuccessStatus = notCheck;
}
if (SuccessStatus) // Seems ok
diff --git a/third_party/lcms/src/cmsintrp.c b/third_party/lcms/src/cmsintrp.c
index 4fc5c59..3d9a405 100644
--- a/third_party/lcms/src/cmsintrp.c
+++ b/third_party/lcms/src/cmsintrp.c
@@ -405,12 +405,13 @@
const cmsUInt16Number* LutTable = (cmsUInt16Number*) p ->Table;
int OutChan, TotalOut;
cmsS15Fixed16Number fx, fy;
- CMSREGISTER int rx, ry;
- int x0, y0;
- CMSREGISTER int X0, X1, Y0, Y1;
- int d00, d01, d10, d11,
- dx0, dx1,
- dxy;
+ CMSREGISTER int rx, ry;
+ int x0, y0;
+ CMSREGISTER int X0, X1, Y0, Y1;
+
+ int d00, d01, d10, d11,
+ dx0, dx1,
+ dxy;
TotalOut = p -> nOutputs;
@@ -466,11 +467,12 @@
int x0, y0, z0,
X0, Y0, Z0, X1, Y1, Z1;
int TotalOut, OutChan;
+
cmsFloat32Number fx, fy, fz,
- d000, d001, d010, d011,
- d100, d101, d110, d111,
- dx00, dx01, dx10, dx11,
- dxy0, dxy1, dxyz;
+ d000, d001, d010, d011,
+ d100, d101, d110, d111,
+ dx00, dx01, dx10, dx11,
+ dxy0, dxy1, dxyz;
TotalOut = p -> nOutputs;
@@ -536,13 +538,13 @@
const cmsUInt16Number* LutTable = (cmsUInt16Number*) p ->Table;
int OutChan, TotalOut;
cmsS15Fixed16Number fx, fy, fz;
- CMSREGISTER int rx, ry, rz;
- int x0, y0, z0;
- CMSREGISTER int X0, X1, Y0, Y1, Z0, Z1;
- int d000, d001, d010, d011,
- d100, d101, d110, d111,
- dx00, dx01, dx10, dx11,
- dxy0, dxy1, dxyz;
+ CMSREGISTER int rx, ry, rz;
+ int x0, y0, z0;
+ CMSREGISTER int X0, X1, Y0, Y1, Z0, Z1;
+ int d000, d001, d010, d011,
+ d100, d101, d110, d111,
+ dx00, dx01, dx10, dx11,
+ dxy0, dxy1, dxyz;
TotalOut = p -> nOutputs;
@@ -610,8 +612,8 @@
{
const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;
cmsFloat32Number px, py, pz;
- int x0, y0, z0,
- X0, Y0, Z0, X1, Y1, Z1;
+ int x0, y0, z0,
+ X0, Y0, Z0, X1, Y1, Z1;
cmsFloat32Number rx, ry, rz;
cmsFloat32Number c0, c1=0, c2=0, c3=0;
int OutChan, TotalOut;
@@ -701,9 +703,6 @@
#undef DENS
-
-
-
static CMS_NO_SANITIZE
void TetrahedralInterp16(CMSREGISTER const cmsUInt16Number Input[],
CMSREGISTER cmsUInt16Number Output[],
@@ -714,7 +713,7 @@
cmsS15Fixed16Number rx, ry, rz;
int x0, y0, z0;
cmsS15Fixed16Number c0, c1, c2, c3, Rest;
- cmsS15Fixed16Number X0, X1, Y0, Y1, Z0, Z1;
+ cmsUInt32Number X0, X1, Y0, Y1, Z0, Z1;
cmsUInt32Number TotalOut = p -> nOutputs;
fx = _cmsToFixedDomain((int) Input[0] * p -> Domain[0]);
@@ -737,8 +736,8 @@
Z0 = p -> opta[0] * z0;
Z1 = (Input[2] == 0xFFFFU ? 0 : p->opta[0]);
-
- LutTable = &LutTable[X0+Y0+Z0];
+
+ LutTable += X0+Y0+Z0;
// Output should be computed as x = ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest))
// which expands as: x = (Rest + ((Rest+0x7fff)/0xFFFF) + 0x8000)>>16
@@ -1022,8 +1021,6 @@
// For more that 3 inputs (i.e., CMYK)
// evaluate two 3-dimensional interpolations and then linearly interpolate between them.
-
-
static
void Eval4InputsFloat(const cmsFloat32Number Input[],
cmsFloat32Number Output[],
@@ -1066,351 +1063,102 @@
}
}
-
-static CMS_NO_SANITIZE
-void Eval5Inputs(CMSREGISTER const cmsUInt16Number Input[],
- CMSREGISTER cmsUInt16Number Output[],
-
- CMSREGISTER const cmsInterpParams* p16)
-{
- const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
- cmsS15Fixed16Number fk;
- cmsS15Fixed16Number k0, rk;
- int K0, K1;
- const cmsUInt16Number* T;
- cmsUInt32Number i;
- cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
- cmsInterpParams p1;
-
-
- fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);
- k0 = FIXED_TO_INT(fk);
- rk = FIXED_REST_TO_INT(fk);
-
- K0 = p16 -> opta[4] * k0;
- K1 = p16 -> opta[4] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));
-
- p1 = *p16;
- memmove(&p1.Domain[0], &p16 ->Domain[1], 4*sizeof(cmsUInt32Number));
-
- T = LutTable + K0;
- p1.Table = T;
-
- Eval4Inputs(Input + 1, Tmp1, &p1);
-
- T = LutTable + K1;
- p1.Table = T;
-
- Eval4Inputs(Input + 1, Tmp2, &p1);
-
- for (i=0; i < p16 -> nOutputs; i++) {
-
- Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]);
- }
-
+#define EVAL_FNS(N,NM) static CMS_NO_SANITIZE \
+void Eval##N##Inputs(CMSREGISTER const cmsUInt16Number Input[], CMSREGISTER cmsUInt16Number Output[], CMSREGISTER const cmsInterpParams* p16)\
+{\
+ const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;\
+ cmsS15Fixed16Number fk;\
+ cmsS15Fixed16Number k0, rk;\
+ int K0, K1;\
+ const cmsUInt16Number* T;\
+ cmsUInt32Number i;\
+ cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];\
+ cmsInterpParams p1;\
+\
+ fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);\
+ k0 = FIXED_TO_INT(fk);\
+ rk = FIXED_REST_TO_INT(fk);\
+\
+ K0 = p16 -> opta[NM] * k0;\
+ K1 = p16 -> opta[NM] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));\
+\
+ p1 = *p16;\
+ memmove(&p1.Domain[0], &p16 ->Domain[1], NM*sizeof(cmsUInt32Number));\
+\
+ T = LutTable + K0;\
+ p1.Table = T;\
+\
+ Eval##NM##Inputs(Input + 1, Tmp1, &p1);\
+\
+ T = LutTable + K1;\
+ p1.Table = T;\
+\
+ Eval##NM##Inputs(Input + 1, Tmp2, &p1);\
+\
+ for (i=0; i < p16 -> nOutputs; i++) {\
+\
+ Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]);\
+ }\
+}\
+\
+static void Eval##N##InputsFloat(const cmsFloat32Number Input[], \
+ cmsFloat32Number Output[],\
+ const cmsInterpParams * p)\
+{\
+ const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;\
+ cmsFloat32Number rest;\
+ cmsFloat32Number pk;\
+ int k0, K0, K1;\
+ const cmsFloat32Number* T;\
+ cmsUInt32Number i;\
+ cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];\
+ cmsInterpParams p1;\
+\
+ pk = fclamp(Input[0]) * p->Domain[0];\
+ k0 = _cmsQuickFloor(pk);\
+ rest = pk - (cmsFloat32Number) k0;\
+\
+ K0 = p -> opta[NM] * k0;\
+ K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[NM]);\
+\
+ p1 = *p;\
+ memmove(&p1.Domain[0], &p ->Domain[1], NM*sizeof(cmsUInt32Number));\
+\
+ T = LutTable + K0;\
+ p1.Table = T;\
+\
+ Eval##NM##InputsFloat(Input + 1, Tmp1, &p1);\
+\
+ T = LutTable + K1;\
+ p1.Table = T;\
+\
+ Eval##NM##InputsFloat(Input + 1, Tmp2, &p1);\
+\
+ for (i=0; i < p -> nOutputs; i++) {\
+\
+ cmsFloat32Number y0 = Tmp1[i];\
+ cmsFloat32Number y1 = Tmp2[i];\
+\
+ Output[i] = y0 + (y1 - y0) * rest;\
+ }\
}
-static
-void Eval5InputsFloat(const cmsFloat32Number Input[],
- cmsFloat32Number Output[],
- const cmsInterpParams* p)
-{
- const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;
- cmsFloat32Number rest;
- cmsFloat32Number pk;
- int k0, K0, K1;
- const cmsFloat32Number* T;
- cmsUInt32Number i;
- cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
- cmsInterpParams p1;
-
- pk = fclamp(Input[0]) * p->Domain[0];
- k0 = _cmsQuickFloor(pk);
- rest = pk - (cmsFloat32Number) k0;
-
- K0 = p -> opta[4] * k0;
- K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[4]);
-
- p1 = *p;
- memmove(&p1.Domain[0], &p ->Domain[1], 4*sizeof(cmsUInt32Number));
-
- T = LutTable + K0;
- p1.Table = T;
-
- Eval4InputsFloat(Input + 1, Tmp1, &p1);
-
- T = LutTable + K1;
- p1.Table = T;
-
- Eval4InputsFloat(Input + 1, Tmp2, &p1);
-
- for (i=0; i < p -> nOutputs; i++) {
-
- cmsFloat32Number y0 = Tmp1[i];
- cmsFloat32Number y1 = Tmp2[i];
-
- Output[i] = y0 + (y1 - y0) * rest;
- }
-}
-
-
-
-static CMS_NO_SANITIZE
-void Eval6Inputs(CMSREGISTER const cmsUInt16Number Input[],
- CMSREGISTER cmsUInt16Number Output[],
- CMSREGISTER const cmsInterpParams* p16)
-{
- const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
- cmsS15Fixed16Number fk;
- cmsS15Fixed16Number k0, rk;
- int K0, K1;
- const cmsUInt16Number* T;
- cmsUInt32Number i;
- cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
- cmsInterpParams p1;
-
- fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);
- k0 = FIXED_TO_INT(fk);
- rk = FIXED_REST_TO_INT(fk);
-
- K0 = p16 -> opta[5] * k0;
- K1 = p16 -> opta[5] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));
-
- p1 = *p16;
- memmove(&p1.Domain[0], &p16 ->Domain[1], 5*sizeof(cmsUInt32Number));
-
- T = LutTable + K0;
- p1.Table = T;
-
- Eval5Inputs(Input + 1, Tmp1, &p1);
-
- T = LutTable + K1;
- p1.Table = T;
-
- Eval5Inputs(Input + 1, Tmp2, &p1);
-
- for (i=0; i < p16 -> nOutputs; i++) {
-
- Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]);
- }
-
-}
-
-
-static
-void Eval6InputsFloat(const cmsFloat32Number Input[],
- cmsFloat32Number Output[],
- const cmsInterpParams* p)
-{
- const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;
- cmsFloat32Number rest;
- cmsFloat32Number pk;
- int k0, K0, K1;
- const cmsFloat32Number* T;
- cmsUInt32Number i;
- cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
- cmsInterpParams p1;
-
- pk = fclamp(Input[0]) * p->Domain[0];
- k0 = _cmsQuickFloor(pk);
- rest = pk - (cmsFloat32Number) k0;
-
- K0 = p -> opta[5] * k0;
- K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[5]);
-
- p1 = *p;
- memmove(&p1.Domain[0], &p ->Domain[1], 5*sizeof(cmsUInt32Number));
-
- T = LutTable + K0;
- p1.Table = T;
-
- Eval5InputsFloat(Input + 1, Tmp1, &p1);
-
- T = LutTable + K1;
- p1.Table = T;
-
- Eval5InputsFloat(Input + 1, Tmp2, &p1);
-
- for (i=0; i < p -> nOutputs; i++) {
-
- cmsFloat32Number y0 = Tmp1[i];
- cmsFloat32Number y1 = Tmp2[i];
-
- Output[i] = y0 + (y1 - y0) * rest;
- }
-}
-
-
-static CMS_NO_SANITIZE
-void Eval7Inputs(CMSREGISTER const cmsUInt16Number Input[],
- CMSREGISTER cmsUInt16Number Output[],
- CMSREGISTER const cmsInterpParams* p16)
-{
- const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
- cmsS15Fixed16Number fk;
- cmsS15Fixed16Number k0, rk;
- int K0, K1;
- const cmsUInt16Number* T;
- cmsUInt32Number i;
- cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
- cmsInterpParams p1;
-
-
- fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);
- k0 = FIXED_TO_INT(fk);
- rk = FIXED_REST_TO_INT(fk);
-
- K0 = p16 -> opta[6] * k0;
- K1 = p16 -> opta[6] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));
-
- p1 = *p16;
- memmove(&p1.Domain[0], &p16 ->Domain[1], 6*sizeof(cmsUInt32Number));
-
- T = LutTable + K0;
- p1.Table = T;
-
- Eval6Inputs(Input + 1, Tmp1, &p1);
-
- T = LutTable + K1;
- p1.Table = T;
-
- Eval6Inputs(Input + 1, Tmp2, &p1);
-
- for (i=0; i < p16 -> nOutputs; i++) {
- Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]);
- }
-}
-
-
-static
-void Eval7InputsFloat(const cmsFloat32Number Input[],
- cmsFloat32Number Output[],
- const cmsInterpParams* p)
-{
- const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;
- cmsFloat32Number rest;
- cmsFloat32Number pk;
- int k0, K0, K1;
- const cmsFloat32Number* T;
- cmsUInt32Number i;
- cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
- cmsInterpParams p1;
-
- pk = fclamp(Input[0]) * p->Domain[0];
- k0 = _cmsQuickFloor(pk);
- rest = pk - (cmsFloat32Number) k0;
-
- K0 = p -> opta[6] * k0;
- K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[6]);
-
- p1 = *p;
- memmove(&p1.Domain[0], &p ->Domain[1], 6*sizeof(cmsUInt32Number));
-
- T = LutTable + K0;
- p1.Table = T;
-
- Eval6InputsFloat(Input + 1, Tmp1, &p1);
-
- T = LutTable + K1;
- p1.Table = T;
-
- Eval6InputsFloat(Input + 1, Tmp2, &p1);
-
-
- for (i=0; i < p -> nOutputs; i++) {
-
- cmsFloat32Number y0 = Tmp1[i];
- cmsFloat32Number y1 = Tmp2[i];
-
- Output[i] = y0 + (y1 - y0) * rest;
-
- }
-}
-
-static CMS_NO_SANITIZE
-void Eval8Inputs(CMSREGISTER const cmsUInt16Number Input[],
- CMSREGISTER cmsUInt16Number Output[],
- CMSREGISTER const cmsInterpParams* p16)
-{
- const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
- cmsS15Fixed16Number fk;
- cmsS15Fixed16Number k0, rk;
- int K0, K1;
- const cmsUInt16Number* T;
- cmsUInt32Number i;
- cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
- cmsInterpParams p1;
-
- fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);
- k0 = FIXED_TO_INT(fk);
- rk = FIXED_REST_TO_INT(fk);
-
- K0 = p16 -> opta[7] * k0;
- K1 = p16 -> opta[7] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));
-
- p1 = *p16;
- memmove(&p1.Domain[0], &p16 ->Domain[1], 7*sizeof(cmsUInt32Number));
-
- T = LutTable + K0;
- p1.Table = T;
-
- Eval7Inputs(Input + 1, Tmp1, &p1);
-
- T = LutTable + K1;
- p1.Table = T;
- Eval7Inputs(Input + 1, Tmp2, &p1);
-
- for (i=0; i < p16 -> nOutputs; i++) {
- Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]);
- }
-}
-
-
-
-static
-void Eval8InputsFloat(const cmsFloat32Number Input[],
- cmsFloat32Number Output[],
- const cmsInterpParams* p)
-{
- const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;
- cmsFloat32Number rest;
- cmsFloat32Number pk;
- int k0, K0, K1;
- const cmsFloat32Number* T;
- cmsUInt32Number i;
- cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
- cmsInterpParams p1;
-
- pk = fclamp(Input[0]) * p->Domain[0];
- k0 = _cmsQuickFloor(pk);
- rest = pk - (cmsFloat32Number) k0;
-
- K0 = p -> opta[7] * k0;
- K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[7]);
-
- p1 = *p;
- memmove(&p1.Domain[0], &p ->Domain[1], 7*sizeof(cmsUInt32Number));
-
- T = LutTable + K0;
- p1.Table = T;
-
- Eval7InputsFloat(Input + 1, Tmp1, &p1);
-
- T = LutTable + K1;
- p1.Table = T;
-
- Eval7InputsFloat(Input + 1, Tmp2, &p1);
-
-
- for (i=0; i < p -> nOutputs; i++) {
-
- cmsFloat32Number y0 = Tmp1[i];
- cmsFloat32Number y1 = Tmp2[i];
+/**
+* Thanks to Carles Llopis for the templating idea
+*/
+EVAL_FNS(5, 4)
+EVAL_FNS(6, 5)
+EVAL_FNS(7, 6)
+EVAL_FNS(8, 7)
+EVAL_FNS(9, 8)
+EVAL_FNS(10, 9)
+EVAL_FNS(11, 10)
+EVAL_FNS(12, 11)
+EVAL_FNS(13, 12)
+EVAL_FNS(14, 13)
+EVAL_FNS(15, 14)
- Output[i] = y0 + (y1 - y0) * rest;
- }
-}
// The default factory
static
@@ -1511,6 +1259,53 @@
Interpolation.Lerp16 = Eval8Inputs;
break;
+ case 9:
+ if (IsFloat)
+ Interpolation.LerpFloat = Eval9InputsFloat;
+ else
+ Interpolation.Lerp16 = Eval9Inputs;
+ break;
+
+ case 10:
+ if (IsFloat)
+ Interpolation.LerpFloat = Eval10InputsFloat;
+ else
+ Interpolation.Lerp16 = Eval10Inputs;
+ break;
+
+ case 11:
+ if (IsFloat)
+ Interpolation.LerpFloat = Eval11InputsFloat;
+ else
+ Interpolation.Lerp16 = Eval11Inputs;
+ break;
+
+ case 12:
+ if (IsFloat)
+ Interpolation.LerpFloat = Eval12InputsFloat;
+ else
+ Interpolation.Lerp16 = Eval12Inputs;
+ break;
+
+ case 13:
+ if (IsFloat)
+ Interpolation.LerpFloat = Eval13InputsFloat;
+ else
+ Interpolation.Lerp16 = Eval13Inputs;
+ break;
+
+ case 14:
+ if (IsFloat)
+ Interpolation.LerpFloat = Eval14InputsFloat;
+ else
+ Interpolation.Lerp16 = Eval14Inputs;
+ break;
+
+ case 15:
+ if (IsFloat)
+ Interpolation.LerpFloat = Eval15InputsFloat;
+ else
+ Interpolation.Lerp16 = Eval15Inputs;
break;
default:
diff --git a/third_party/lcms/src/cmsio0.c b/third_party/lcms/src/cmsio0.c
index 475d62b..743b958 100644
--- a/third_party/lcms/src/cmsio0.c
+++ b/third_party/lcms/src/cmsio0.c
@@ -261,7 +261,7 @@
_cmsFree(ContextID, fm);
_cmsFree(ContextID, iohandler);
- cmsSignalError(ContextID, cmsERROR_READ, "Couldn't allocate %ld bytes for profile", size);
+ cmsSignalError(ContextID, cmsERROR_READ, "Couldn't allocate %ld bytes for profile", (long) size);
return NULL;
}
@@ -1220,25 +1220,28 @@
// In this case a blind copy of the block data is performed
if (FileOrig != NULL && Icc -> TagOffsets[i]) {
- cmsUInt32Number TagSize = FileOrig -> TagSizes[i];
- cmsUInt32Number TagOffset = FileOrig -> TagOffsets[i];
- void* Mem;
+ if (FileOrig->IOhandler != NULL)
+ {
+ cmsUInt32Number TagSize = FileOrig->TagSizes[i];
+ cmsUInt32Number TagOffset = FileOrig->TagOffsets[i];
+ void* Mem;
- if (!FileOrig ->IOhandler->Seek(FileOrig ->IOhandler, TagOffset)) return FALSE;
+ if (!FileOrig->IOhandler->Seek(FileOrig->IOhandler, TagOffset)) return FALSE;
- Mem = _cmsMalloc(Icc ->ContextID, TagSize);
- if (Mem == NULL) return FALSE;
+ Mem = _cmsMalloc(Icc->ContextID, TagSize);
+ if (Mem == NULL) return FALSE;
- if (FileOrig ->IOhandler->Read(FileOrig->IOhandler, Mem, TagSize, 1) != 1) return FALSE;
- if (!io ->Write(io, TagSize, Mem)) return FALSE;
- _cmsFree(Icc ->ContextID, Mem);
+ if (FileOrig->IOhandler->Read(FileOrig->IOhandler, Mem, TagSize, 1) != 1) return FALSE;
+ if (!io->Write(io, TagSize, Mem)) return FALSE;
+ _cmsFree(Icc->ContextID, Mem);
- Icc -> TagSizes[i] = (io ->UsedSpace - Begin);
+ Icc->TagSizes[i] = (io->UsedSpace - Begin);
- // Align to 32 bit boundary.
- if (! _cmsWriteAlignment(io))
- return FALSE;
+ // Align to 32 bit boundary.
+ if (!_cmsWriteAlignment(io))
+ return FALSE;
+ }
}
continue;
diff --git a/third_party/lcms/src/cmslut.c b/third_party/lcms/src/cmslut.c
index 47f88df..04ece7f 100644
--- a/third_party/lcms/src/cmslut.c
+++ b/third_party/lcms/src/cmslut.c
@@ -1337,7 +1337,7 @@
// Does evaluate the LUT on cmsFloat32Number-basis.
static
-void _LUTevalFloat(CMSREGISTER const cmsFloat32Number In[], CMSREGISTER cmsFloat32Number Out[], const void* D)
+void _LUTevalFloat(const cmsFloat32Number In[], cmsFloat32Number Out[], const void* D)
{
cmsPipeline* lut = (cmsPipeline*) D;
cmsStage *mpe;
@@ -1658,7 +1658,7 @@
// This function may be used to set the optional evaluator and a block of private data. If private data is being used, an optional
// duplicator and free functions should also be specified in order to duplicate the LUT construct. Use NULL to inhibit such functionality.
void CMSEXPORT _cmsPipelineSetOptimizationParameters(cmsPipeline* Lut,
- _cmsOPTeval16Fn Eval16,
+ _cmsPipelineEval16Fn Eval16,
void* PrivateData,
_cmsFreeUserDataFn FreePrivateDataFn,
_cmsDupUserDataFn DupPrivateDataFn)
diff --git a/third_party/lcms/src/cmsnamed.c b/third_party/lcms/src/cmsnamed.c
index 082a944..c0595dd 100644
--- a/third_party/lcms/src/cmsnamed.c
+++ b/third_party/lcms/src/cmsnamed.c
@@ -180,12 +180,16 @@
// Convert from a 3-char code to a cmsUInt16Number. It is done in this way because some
// compilers don't properly align beginning of strings
-
static
cmsUInt16Number strTo16(const char str[3])
{
- const cmsUInt8Number* ptr8 = (const cmsUInt8Number*)str;
- cmsUInt16Number n = (cmsUInt16Number)(((cmsUInt16Number)ptr8[0] << 8) | ptr8[1]);
+ const cmsUInt8Number* ptr8;
+ cmsUInt16Number n;
+
+ // For non-existent strings
+ if (str == NULL) return 0;
+ ptr8 = (const cmsUInt8Number*)str;
+ n = (cmsUInt16Number)(((cmsUInt16Number)ptr8[0] << 8) | ptr8[1]);
return n;
}
@@ -200,6 +204,7 @@
}
// Add an ASCII entry. Do not add any \0 termination (ICC1v43_2010-12.pdf page 61)
+// In the case the user explicitely sets an empty string, we force a \0
cmsBool CMSEXPORT cmsMLUsetASCII(cmsMLU* mlu, const char LanguageCode[3], const char CountryCode[3], const char* ASCIIString)
{
cmsUInt32Number i, len = (cmsUInt32Number) strlen(ASCIIString);
@@ -210,6 +215,12 @@
if (mlu == NULL) return FALSE;
+ // len == 0 would prevent operation, so we set a empty string pointing to zero
+ if (len == 0)
+ {
+ len = 1;
+ }
+
WStr = (wchar_t*) _cmsCalloc(mlu ->ContextID, len, sizeof(wchar_t));
if (WStr == NULL) return FALSE;
@@ -247,6 +258,9 @@
if (WideString == NULL) return FALSE;
len = (cmsUInt32Number) (mywcslen(WideString)) * sizeof(wchar_t);
+ if (len == 0)
+ len = sizeof(wchar_t);
+
return AddMLUBlock(mlu, len, WideString, Lang, Cntry);
}
diff --git a/third_party/lcms/src/cmsopt.c b/third_party/lcms/src/cmsopt.c
index ca47254..1f1173f 100644
--- a/third_party/lcms/src/cmsopt.c
+++ b/third_party/lcms/src/cmsopt.c
@@ -412,7 +412,20 @@
p16 -> EvalCurveOut16 = (_cmsInterpFn16*) _cmsCalloc(ContextID, nOutputs, sizeof(_cmsInterpFn16));
+ if (p16->EvalCurveOut16 == NULL)
+ {
+ _cmsFree(ContextID, p16);
+ return NULL;
+ }
+
p16 -> ParamsCurveOut16 = (cmsInterpParams**) _cmsCalloc(ContextID, nOutputs, sizeof(cmsInterpParams* ));
+ if (p16->ParamsCurveOut16 == NULL)
+ {
+
+ _cmsFree(ContextID, p16->EvalCurveOut16);
+ _cmsFree(ContextID, p16);
+ return NULL;
+ }
for (i=0; i < nOutputs; i++) {
@@ -439,7 +452,9 @@
// Sampler implemented by another LUT. This is a clean way to precalculate the devicelink 3D CLUT for
// almost any transform. We use floating point precision and then convert from floating point to 16 bits.
static
-cmsInt32Number XFormSampler16(CMSREGISTER const cmsUInt16Number In[], CMSREGISTER cmsUInt16Number Out[], CMSREGISTER void* Cargo)
+cmsInt32Number XFormSampler16(CMSREGISTER const cmsUInt16Number In[],
+ CMSREGISTER cmsUInt16Number Out[],
+ CMSREGISTER void* Cargo)
{
cmsPipeline* Lut = (cmsPipeline*) Cargo;
cmsFloat32Number InFloat[cmsMAXCHANNELS], OutFloat[cmsMAXCHANNELS];
@@ -798,7 +813,7 @@
if (DataSetIn == NULL && DataSetOut == NULL) {
- _cmsPipelineSetOptimizationParameters(Dest, (_cmsOPTeval16Fn) DataCLUT->Params->Interpolation.Lerp16, DataCLUT->Params, NULL, NULL);
+ _cmsPipelineSetOptimizationParameters(Dest, (_cmsPipelineEval16Fn) DataCLUT->Params->Interpolation.Lerp16, DataCLUT->Params, NULL, NULL);
}
else {
@@ -943,8 +958,8 @@
#define DENS(i,j,k) (LutTable[(i)+(j)+(k)+OutChan])
static CMS_NO_SANITIZE
void PrelinEval8(CMSREGISTER const cmsUInt16Number Input[],
- CMSREGISTER cmsUInt16Number Output[],
- CMSREGISTER const void* D)
+ CMSREGISTER cmsUInt16Number Output[],
+ CMSREGISTER const void* D)
{
cmsUInt8Number r, g, b;
@@ -961,9 +976,9 @@
g = (cmsUInt8Number) (Input[1] >> 8);
b = (cmsUInt8Number) (Input[2] >> 8);
- X0 = X1 = (cmsS15Fixed16Number) p8->X0[r];
- Y0 = Y1 = (cmsS15Fixed16Number) p8->Y0[g];
- Z0 = Z1 = (cmsS15Fixed16Number) p8->Z0[b];
+ X0 = (cmsS15Fixed16Number) p8->X0[r];
+ Y0 = (cmsS15Fixed16Number) p8->Y0[g];
+ Z0 = (cmsS15Fixed16Number) p8->Z0[b];
rx = p8 ->rx[r];
ry = p8 ->ry[g];
@@ -1365,8 +1380,8 @@
static
void FastEvaluateCurves8(CMSREGISTER const cmsUInt16Number In[],
- CMSREGISTER cmsUInt16Number Out[],
- CMSREGISTER const void* D)
+ CMSREGISTER cmsUInt16Number Out[],
+ CMSREGISTER const void* D)
{
Curves16Data* Data = (Curves16Data*) D;
int x;
@@ -1927,7 +1942,7 @@
}
// The entry point for LUT optimization
-cmsBool _cmsOptimizePipeline(cmsContext ContextID,
+cmsBool CMSEXPORT _cmsOptimizePipeline(cmsContext ContextID,
cmsPipeline** PtrLut,
cmsUInt32Number Intent,
cmsUInt32Number* InputFormat,
diff --git a/third_party/lcms/src/cmspack.c b/third_party/lcms/src/cmspack.c
index b8a47c2..9510802 100644
--- a/third_party/lcms/src/cmspack.c
+++ b/third_party/lcms/src/cmspack.c
@@ -2807,7 +2807,7 @@
if (Reverse) v = maximum - v;
- wIn[index] = _cmsQuickSaturateWord(v * maximum);
+ wIn[index] = _cmsQuickSaturateWord((cmsFloat64Number) v * maximum);
}
diff --git a/third_party/lcms/src/cmspcs.c b/third_party/lcms/src/cmspcs.c
index c60f716..9f03fc5 100644
--- a/third_party/lcms/src/cmspcs.c
+++ b/third_party/lcms/src/cmspcs.c
@@ -656,7 +656,7 @@
// This function returns a number of gridpoints to be used as LUT table. It assumes same number
// of gripdpoints in all dimensions. Flags may override the choice.
-cmsUInt32Number _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags)
+cmsUInt32Number CMSEXPORT _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags)
{
cmsUInt32Number nChannels;
diff --git a/third_party/lcms/src/cmsplugin.c b/third_party/lcms/src/cmsplugin.c
index 062d9db..2b86b64 100644
--- a/third_party/lcms/src/cmsplugin.c
+++ b/third_party/lcms/src/cmsplugin.c
@@ -498,6 +498,7 @@
int len;
cmsUInt8Number Buffer[2048];
cmsBool rc;
+ cmsUInt8Number* ptr;
_cmsAssert(io != NULL);
_cmsAssert(frm != NULL);
@@ -510,6 +511,13 @@
return FALSE; // Truncated, which is a fatal error for us
}
+ // setlocale may be active, no commas are needed in PS generator
+ // and PS generator is our only client
+ for (ptr = Buffer; *ptr; ptr++)
+ {
+ if (*ptr == ',') *ptr = '.';
+ }
+
rc = io ->Write(io, (cmsUInt32Number) len, Buffer);
va_end(args);
diff --git a/third_party/lcms/src/cmsps2.c b/third_party/lcms/src/cmsps2.c
index d101e8d..43c9f74 100644
--- a/third_party/lcms/src/cmsps2.c
+++ b/third_party/lcms/src/cmsps2.c
@@ -529,9 +529,10 @@
// Compare gamma table
static
-cmsBool GammaTableEquals(cmsUInt16Number* g1, cmsUInt16Number* g2, cmsUInt32Number nEntries)
+cmsBool GammaTableEquals(cmsUInt16Number* g1, cmsUInt16Number* g2, cmsUInt32Number nG1, cmsUInt32Number nG2)
{
- return memcmp(g1, g2, nEntries* sizeof(cmsUInt16Number)) == 0;
+ if (nG1 != nG2) return FALSE;
+ return memcmp(g1, g2, nG1 * sizeof(cmsUInt16Number)) == 0;
}
@@ -547,12 +548,12 @@
{
if (g[i] == NULL) return; // Error
- if (i > 0 && GammaTableEquals(g[i-1]->Table16, g[i]->Table16, g[i]->nEntries)) {
+ if (i > 0 && GammaTableEquals(g[i-1]->Table16, g[i]->Table16, g[i-1]->nEntries, g[i]->nEntries)) {
_cmsIOPrintf(m, "/%s%d /%s%d load def\n", nameprefix, i, nameprefix, i-1);
}
else {
- snprintf(buffer, sizeof(buffer), "%s%d", nameprefix, i);
+ snprintf(buffer, sizeof(buffer), "%s%d", nameprefix, (int) i);
buffer[sizeof(buffer)-1] = '\0';
Emit1Gamma(m, g[i], buffer);
}
@@ -807,7 +808,7 @@
if (cmsStageType(mpe) == cmsSigCurveSetElemType) {
- numchans = cmsStageOutputChannels(mpe);
+ numchans = (int) cmsStageOutputChannels(mpe);
for (i = 0; i < numchans; ++i) {
snprintf(buffer, sizeof(buffer), "lcms2gammaproc%d", i);
buffer[sizeof(buffer) - 1] = '\0';
diff --git a/third_party/lcms/src/cmssamp.c b/third_party/lcms/src/cmssamp.c
index f785478..6434d53 100644
--- a/third_party/lcms/src/cmssamp.c
+++ b/third_party/lcms/src/cmssamp.c
@@ -83,10 +83,10 @@
return FALSE;
}
- // Create a formatter which has n channels and floating point
+ // Create a formatter which has n channels and no floating point
dwFormat = cmsFormatterForColorspaceOfProfile(hInput, 2, FALSE);
- // Try to get black by using black colorant
+ // Try to get black by using black colorant
Space = cmsGetColorSpace(hInput);
// This function returns darker colorant in 16 bits for several spaces
diff --git a/third_party/lcms/src/cmstypes.c b/third_party/lcms/src/cmstypes.c
index b780436..825b11e 100644
--- a/third_party/lcms/src/cmstypes.c
+++ b/third_party/lcms/src/cmstypes.c
@@ -1866,6 +1866,7 @@
mpe = NewLUT -> Elements;
if (mpe ->Type == cmsSigMatrixElemType) {
+ if (mpe->InputChannels != 3 || mpe->OutputChannels != 3) return FALSE;
MatMPE = (_cmsStageMatrixData*) mpe ->Data;
mpe = mpe -> Next;
}
@@ -1891,7 +1892,6 @@
return FALSE;
}
-
if (clut == NULL)
clutPoints = 0;
else
@@ -1905,16 +1905,14 @@
n = NewLUT->InputChannels * NewLUT->OutputChannels;
if (MatMPE != NULL) {
-
- for (i = 0; i < n; i++)
+
+ for (i = 0; i < 9; i++)
{
if (!_cmsWrite15Fixed16Number(io, MatMPE->Double[i])) return FALSE;
}
}
else {
-
- if (n != 9) return FALSE;
-
+
if (!_cmsWrite15Fixed16Number(io, 1)) return FALSE;
if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE;
if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE;
@@ -2193,7 +2191,7 @@
if (!_cmsWriteUInt8Number(io, 0)) return FALSE; // Padding
if (MatMPE != NULL) {
-
+
for (i = 0; i < 9; i++)
{
if (!_cmsWrite15Fixed16Number(io, MatMPE->Double[i])) return FALSE;
@@ -3000,6 +2998,9 @@
}
List = cmsAllocNamedColorList(self ->ContextID, Count, 0, "", "");
+ if (List == NULL)
+ return NULL;
+
for (i=0; i < Count; i++) {
if (io ->Read(io, Name, 32, 1) != 1) goto Error;
diff --git a/third_party/lcms/src/cmsxform.c b/third_party/lcms/src/cmsxform.c
index 5a90306..9d182e1 100644
--- a/third_party/lcms/src/cmsxform.c
+++ b/third_party/lcms/src/cmsxform.c
@@ -273,7 +273,7 @@
strideIn = 0;
strideOut = 0;
memset(fIn, 0, sizeof(fIn));
- memset(fOut, 0, sizeof(fIn));
+ memset(fOut, 0, sizeof(fOut));
for (i = 0; i < LineCount; i++) {
@@ -447,7 +447,7 @@
p ->GamutCheck ->Eval16Fn(wIn, &wOutOfGamut, p ->GamutCheck ->Data);
if (wOutOfGamut >= 1) {
- cmsUInt16Number i;
+ cmsUInt32Number i;
_cmsAlarmCodesChunkType* ContextAlarmCodes = (_cmsAlarmCodesChunkType*) _cmsContextGetClientChunk(p->ContextID, AlarmCodesContext);
for (i=0; i < p ->Lut->OutputChannels; i++) {
@@ -774,6 +774,12 @@
if (ToOutput) *ToOutput = CMMcargo ->ToOutputFloat;
}
+// returns original flags
+cmsUInt32Number CMSEXPORT _cmsGetTransformFlags(struct _cmstransform_struct* CMMcargo)
+{
+ _cmsAssert(CMMcargo != NULL);
+ return CMMcargo->dwOriginalFlags;
+}
// Allocate transform struct and set it to defaults. Ask the optimization plug-in about if those formats are proper
// for separated transforms. If this is the case,
diff --git a/third_party/lcms/src/lcms2_internal.h b/third_party/lcms/src/lcms2_internal.h
index fe1243e..9560fc4 100644
--- a/third_party/lcms/src/lcms2_internal.h
+++ b/third_party/lcms/src/lcms2_internal.h
@@ -908,13 +908,7 @@
// For curve set only
-cmsToneCurve** _cmsStageGetPtrToCurveSet(const cmsStage* mpe);
-
-
-// Pipeline Evaluator (in floating point)
-typedef void (* _cmsPipelineEvalFloatFn)(const cmsFloat32Number In[],
- cmsFloat32Number Out[],
- const void* Data);
+cmsToneCurve** _cmsStageGetPtrToCurveSet(const cmsStage* mpe);
struct _cmsPipeline_struct {
@@ -924,7 +918,7 @@
// Data & evaluators
void *Data;
- _cmsOPTeval16Fn Eval16Fn;
+ _cmsPipelineEval16Fn Eval16Fn;
_cmsPipelineEvalFloatFn EvalFloatFn;
_cmsFreeUserDataFn FreeDataFn;
_cmsDupUserDataFn DupDataFn;
@@ -971,14 +965,14 @@
CMSCHECKPOINT cmsUInt16Number CMSEXPORT _cmsQuantizeVal(cmsFloat64Number i, cmsUInt32Number MaxSamples);
-cmsUInt32Number _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags);
+CMSAPI cmsUInt32Number CMSEXPORT _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags);
cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
cmsUInt16Number **White,
cmsUInt16Number **Black,
cmsUInt32Number *nOutputs);
-cmsBool _cmsOptimizePipeline(cmsContext ContextID,
+CMSAPI cmsBool CMSEXPORT _cmsOptimizePipeline(cmsContext ContextID,
cmsPipeline** Lut,
cmsUInt32Number Intent,
cmsUInt32Number* InputFormat,