summaryrefslogtreecommitdiff
path: root/thirdparty/liblcms2/src/cmsintrp.c
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/liblcms2/src/cmsintrp.c')
-rw-r--r--thirdparty/liblcms2/src/cmsintrp.c669
1 files changed, 356 insertions, 313 deletions
diff --git a/thirdparty/liblcms2/src/cmsintrp.c b/thirdparty/liblcms2/src/cmsintrp.c
index 9aced860..5d5f35d3 100644
--- a/thirdparty/liblcms2/src/cmsintrp.c
+++ b/thirdparty/liblcms2/src/cmsintrp.c
@@ -1,24 +1,24 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2012 Marti Maria Saguer
//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the Software
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
-// The above copyright notice and this permission notice shall be included in
+// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
-// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//---------------------------------------------------------------------------------
@@ -33,59 +33,85 @@
static cmsInterpFunction DefaultInterpolatorsFactory(cmsUInt32Number nInputChannels, cmsUInt32Number nOutputChannels, cmsUInt32Number dwFlags);
// This is the default factory
-static cmsInterpFnFactory Interpolators = DefaultInterpolatorsFactory;
+_cmsInterpPluginChunkType _cmsInterpPluginChunk = { NULL };
+
+// The interpolation plug-in memory chunk allocator/dup
+void _cmsAllocInterpPluginChunk(struct _cmsContext_struct* ctx, const struct _cmsContext_struct* src)
+{
+ void* from;
+
+ _cmsAssert(ctx != NULL);
+
+ if (src != NULL) {
+ from = src ->chunks[InterpPlugin];
+ }
+ else {
+ static _cmsInterpPluginChunkType InterpPluginChunk = { NULL };
+
+ from = &InterpPluginChunk;
+ }
+
+ _cmsAssert(from != NULL);
+ ctx ->chunks[InterpPlugin] = _cmsSubAllocDup(ctx ->MemPool, from, sizeof(_cmsInterpPluginChunkType));
+}
// Main plug-in entry
-cmsBool _cmsRegisterInterpPlugin(cmsPluginBase* Data)
+cmsBool _cmsRegisterInterpPlugin(cmsContext ContextID, cmsPluginBase* Data)
{
cmsPluginInterpolation* Plugin = (cmsPluginInterpolation*) Data;
+ _cmsInterpPluginChunkType* ptr = (_cmsInterpPluginChunkType*) _cmsContextGetClientChunk(ContextID, InterpPlugin);
if (Data == NULL) {
-
- Interpolators = DefaultInterpolatorsFactory;
+
+ ptr ->Interpolators = NULL;
return TRUE;
}
// Set replacement functions
- Interpolators = Plugin ->InterpolatorsFactory;
+ ptr ->Interpolators = Plugin ->InterpolatorsFactory;
return TRUE;
}
// Set the interpolation method
+cmsBool _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p)
+{
+ _cmsInterpPluginChunkType* ptr = (_cmsInterpPluginChunkType*) _cmsContextGetClientChunk(ContextID, InterpPlugin);
-cmsBool _cmsSetInterpolationRoutine(cmsInterpParams* p)
-{
- // Invoke factory, possibly in the Plug-in
- p ->Interpolation = Interpolators(p -> nInputs, p ->nOutputs, p ->dwFlags);
+ p ->Interpolation.Lerp16 = NULL;
- // If unsupported by the plug-in, go for the LittleCMS default.
+ // Invoke factory, possibly in the Plug-in
+ if (ptr ->Interpolators != NULL)
+ p ->Interpolation = ptr->Interpolators(p -> nInputs, p ->nOutputs, p ->dwFlags);
+
+ // If unsupported by the plug-in, go for the LittleCMS default.
// If happens only if an extern plug-in is being used
if (p ->Interpolation.Lerp16 == NULL)
p ->Interpolation = DefaultInterpolatorsFactory(p ->nInputs, p ->nOutputs, p ->dwFlags);
// Check for valid interpolator (we just check one member of the union)
- if (p ->Interpolation.Lerp16 == NULL) {
+ if (p ->Interpolation.Lerp16 == NULL) {
return FALSE;
}
+
return TRUE;
}
// This function precalculates as many parameters as possible to speed up the interpolation.
cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID,
- const cmsUInt32Number nSamples[],
- int InputChan, int OutputChan,
+ const cmsUInt32Number nSamples[],
+ int InputChan, int OutputChan,
const void *Table,
cmsUInt32Number dwFlags)
-{
+{
cmsInterpParams* p;
int i;
-
+
// Check for maximum inputs
if (InputChan > MAX_INPUT_DIMENSIONS) {
- cmsSignalError(ContextID, cmsERROR_RANGE, "Too many input channels (%d channels, max=%d)", InputChan, MAX_INPUT_DIMENSIONS);
+ cmsSignalError(ContextID, cmsERROR_RANGE, "Too many input channels (%d channels, max=%d)", InputChan, MAX_INPUT_DIMENSIONS);
return NULL;
}
@@ -104,17 +130,17 @@ cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID,
for (i=0; i < InputChan; i++) {
p -> nSamples[i] = nSamples[i];
- p -> Domain[i] = nSamples[i] - 1;
+ p -> Domain[i] = nSamples[i] - 1;
}
// Compute factors to apply to each component to index the grid array
- p -> opta[0] = p -> nOutputs;
+ p -> opta[0] = p -> nOutputs;
for (i=1; i < InputChan; i++)
p ->opta[i] = p ->opta[i-1] * nSamples[InputChan-i];
- if (!_cmsSetInterpolationRoutine(p)) {
- cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported interpolation (%d->%d channels)", InputChan, OutputChan);
+ if (!_cmsSetInterpolationRoutine(ContextID, p)) {
+ cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported interpolation (%d->%d channels)", InputChan, OutputChan);
_cmsFree(ContextID, p);
return NULL;
}
@@ -131,7 +157,7 @@ cmsInterpParams* _cmsComputeInterpParams(cmsContext ContextID, int nSamples, int
cmsUInt32Number Samples[MAX_INPUT_DIMENSIONS];
// Fill the auxiliar array
- for (i=0; i < MAX_INPUT_DIMENSIONS; i++)
+ for (i=0; i < MAX_INPUT_DIMENSIONS; i++)
Samples[i] = nSamples;
// Call the extended function
@@ -146,27 +172,27 @@ void _cmsFreeInterpParams(cmsInterpParams* p)
}
-// Inline fixed point interpolation
+// Inline fixed point interpolation
cmsINLINE cmsUInt16Number LinearInterp(cmsS15Fixed16Number a, cmsS15Fixed16Number l, cmsS15Fixed16Number h)
{
- cmsUInt32Number dif = (cmsUInt32Number) (h - l) * a + 0x8000;
- dif = (dif >> 16) + l;
+ cmsUInt32Number dif = (cmsUInt32Number) (h - l) * a + 0x8000;
+ dif = (dif >> 16) + l;
return (cmsUInt16Number) (dif);
}
// Linear interpolation (Fixed-point optimized)
static
-void LinLerp1D(register const cmsUInt16Number Value[],
- register cmsUInt16Number Output[],
+void LinLerp1D(register const cmsUInt16Number Value[],
+ register cmsUInt16Number Output[],
register const cmsInterpParams* p)
{
- cmsUInt16Number y1, y0;
+ cmsUInt16Number y1, y0;
int cell0, rest;
int val3;
const cmsUInt16Number* LutTable = (cmsUInt16Number*) p ->Table;
- // if last value...
+ // if last value...
if (Value[0] == 0xffff) {
Output[0] = LutTable[p -> Domain[0]];
@@ -182,15 +208,20 @@ void LinLerp1D(register const cmsUInt16Number Value[],
y0 = LutTable[cell0];
y1 = LutTable[cell0+1];
-
+
Output[0] = LinearInterp(rest, y0, y1);
}
+// To prevent out of bounds indexing
+cmsINLINE cmsFloat32Number fclamp(cmsFloat32Number v)
+{
+ return v < 0.0f ? 0.0f : (v > 1.0f ? 1.0f : v);
+}
// Floating-point version of 1D interpolation
static
-void LinLerp1Dfloat(const cmsFloat32Number Value[],
- cmsFloat32Number Output[],
+void LinLerp1Dfloat(const cmsFloat32Number Value[],
+ cmsFloat32Number Output[],
const cmsInterpParams* p)
{
cmsFloat32Number y1, y0;
@@ -198,13 +229,15 @@ void LinLerp1Dfloat(const cmsFloat32Number Value[],
int cell0, cell1;
const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table;
+ val2 = fclamp(Value[0]);
+
// if last value...
- if (Value[0] == 1.0) {
+ if (val2 == 1.0) {
Output[0] = LutTable[p -> Domain[0]];
return;
}
- val2 = p -> Domain[0] * Value[0];
+ val2 *= p -> Domain[0];
cell0 = (int) floor(val2);
cell1 = (int) ceil(val2);
@@ -215,15 +248,15 @@ void LinLerp1Dfloat(const cmsFloat32Number Value[],
y0 = LutTable[cell0] ;
y1 = LutTable[cell1] ;
- Output[0] = y0 + (y1 - y0) * rest;
+ Output[0] = y0 + (y1 - y0) * rest;
}
-// Eval gray LUT having only one input channel
+// Eval gray LUT having only one input channel
static
-void Eval1Input(register const cmsUInt16Number Input[],
- register cmsUInt16Number Output[],
+void Eval1Input(register const cmsUInt16Number Input[],
+ register cmsUInt16Number Output[],
register const cmsInterpParams* p16)
{
cmsS15Fixed16Number fk;
@@ -251,32 +284,34 @@ void Eval1Input(register const cmsUInt16Number Input[],
-// Eval gray LUT having only one input channel
+// Eval gray LUT having only one input channel
static
-void Eval1InputFloat(const cmsFloat32Number Value[],
- cmsFloat32Number Output[],
+void Eval1InputFloat(const cmsFloat32Number Value[],
+ cmsFloat32Number Output[],
const cmsInterpParams* p)
{
cmsFloat32Number y1, y0;
cmsFloat32Number val2, rest;
int cell0, cell1;
cmsUInt32Number OutChan;
- const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table;
+ const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table;
+
+ val2 = fclamp(Value[0]);
// if last value...
- if (Value[0] == 1.0) {
+ if (val2 == 1.0) {
Output[0] = LutTable[p -> Domain[0]];
return;
}
- val2 = p -> Domain[0] * Value[0];
+ val2 *= p -> Domain[0];
cell0 = (int) floor(val2);
cell1 = (int) ceil(val2);
// Rest is 16 LSB bits
rest = val2 - cell0;
-
+
cell0 *= p -> opta[0];
cell1 *= p -> opta[0];
@@ -285,21 +320,21 @@ void Eval1InputFloat(const cmsFloat32Number Value[],
y0 = LutTable[cell0 + OutChan] ;
y1 = LutTable[cell1 + OutChan] ;
- Output[OutChan] = y0 + (y1 - y0) * rest;
+ Output[OutChan] = y0 + (y1 - y0) * rest;
}
}
// Bilinear interpolation (16 bits) - cmsFloat32Number version
static
-void BilinearInterpFloat(const cmsFloat32Number Input[],
- cmsFloat32Number Output[],
+void BilinearInterpFloat(const cmsFloat32Number Input[],
+ cmsFloat32Number Output[],
const cmsInterpParams* p)
{
# define LERP(a,l,h) (cmsFloat32Number) ((l)+(((h)-(l))*(a)))
# define DENS(i,j) (LutTable[(i)+(j)+OutChan])
- const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table;
+ const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table;
cmsFloat32Number px, py;
int x0, y0,
X0, Y0, X1, Y1;
@@ -308,22 +343,22 @@ void BilinearInterpFloat(const cmsFloat32Number Input[],
d00, d01, d10, d11,
dx0, dx1,
dxy;
-
+
TotalOut = p -> nOutputs;
- px = Input[0] * p->Domain[0];
- py = Input[1] * p->Domain[1];
+ px = fclamp(Input[0]) * p->Domain[0];
+ py = fclamp(Input[1]) * p->Domain[1];
x0 = (int) _cmsQuickFloor(px); fx = px - (cmsFloat32Number) x0;
y0 = (int) _cmsQuickFloor(py); fy = py - (cmsFloat32Number) y0;
-
+
X0 = p -> opta[1] * x0;
X1 = X0 + (Input[0] >= 1.0 ? 0 : p->opta[1]);
Y0 = p -> opta[0] * y0;
Y1 = Y0 + (Input[1] >= 1.0 ? 0 : p->opta[0]);
-
+
for (OutChan = 0; OutChan < TotalOut; OutChan++) {
-
+
d00 = DENS(X0, Y0);
d01 = DENS(X0, Y1);
d10 = DENS(X1, Y0);
@@ -344,7 +379,7 @@ void BilinearInterpFloat(const cmsFloat32Number Input[],
// Bilinear interpolation (16 bits) - optimized version
static
-void BilinearInterp16(register const cmsUInt16Number Input[],
+void BilinearInterp16(register const cmsUInt16Number Input[],
register cmsUInt16Number Output[],
register const cmsInterpParams* p)
@@ -352,7 +387,7 @@ void BilinearInterp16(register const cmsUInt16Number Input[],
#define DENS(i,j) (LutTable[(i)+(j)+OutChan])
#define LERP(a,l,h) (cmsUInt16Number) (l + ROUND_FIXED_TO_INT(((h-l)*a)))
- const cmsUInt16Number* LutTable = (cmsUInt16Number*) p ->Table;
+ const cmsUInt16Number* LutTable = (cmsUInt16Number*) p ->Table;
int OutChan, TotalOut;
cmsS15Fixed16Number fx, fy;
register int rx, ry;
@@ -379,7 +414,7 @@ void BilinearInterp16(register const cmsUInt16Number Input[],
Y0 = p -> opta[0] * y0;
Y1 = Y0 + (Input[1] == 0xFFFFU ? 0 : p->opta[0]);
-
+
for (OutChan = 0; OutChan < TotalOut; OutChan++) {
d00 = DENS(X0, Y0);
@@ -403,15 +438,15 @@ void BilinearInterp16(register const cmsUInt16Number Input[],
// Trilinear interpolation (16 bits) - cmsFloat32Number version
static
-void TrilinearInterpFloat(const cmsFloat32Number Input[],
- cmsFloat32Number Output[],
+void TrilinearInterpFloat(const cmsFloat32Number Input[],
+ cmsFloat32Number Output[],
const cmsInterpParams* p)
{
# define LERP(a,l,h) (cmsFloat32Number) ((l)+(((h)-(l))*(a)))
# define DENS(i,j,k) (LutTable[(i)+(j)+(k)+OutChan])
- const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table;
+ const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table;
cmsFloat32Number px, py, pz;
int x0, y0, z0,
X0, Y0, Z0, X1, Y1, Z1;
@@ -421,38 +456,27 @@ void TrilinearInterpFloat(const cmsFloat32Number Input[],
d100, d101, d110, d111,
dx00, dx01, dx10, dx11,
dxy0, dxy1, dxyz;
-
- TotalOut = p -> nOutputs;
-
- // We need some clipping here
- px = Input[0];
- py = Input[1];
- pz = Input[2];
- if (px < 0) px = 0;
- if (px > 1) px = 1;
- if (py < 0) py = 0;
- if (py > 1) py = 1;
- if (pz < 0) pz = 0;
- if (pz > 1) pz = 1;
+ TotalOut = p -> nOutputs;
- px *= p->Domain[0];
- py *= p->Domain[1];
- pz *= p->Domain[2];
+ // We need some clipping here
+ px = fclamp(Input[0]) * p->Domain[0];
+ py = fclamp(Input[1]) * p->Domain[1];
+ pz = fclamp(Input[2]) * p->Domain[2];
x0 = (int) _cmsQuickFloor(px); fx = px - (cmsFloat32Number) x0;
y0 = (int) _cmsQuickFloor(py); fy = py - (cmsFloat32Number) y0;
z0 = (int) _cmsQuickFloor(pz); fz = pz - (cmsFloat32Number) z0;
-
+
X0 = p -> opta[2] * x0;
X1 = X0 + (Input[0] >= 1.0 ? 0 : p->opta[2]);
Y0 = p -> opta[1] * y0;
Y1 = Y0 + (Input[1] >= 1.0 ? 0 : p->opta[1]);
-
+
Z0 = p -> opta[0] * z0;
Z1 = Z0 + (Input[2] >= 1.0 ? 0 : p->opta[0]);
-
+
for (OutChan = 0; OutChan < TotalOut; OutChan++) {
d000 = DENS(X0, Y0, Z0);
@@ -486,7 +510,7 @@ void TrilinearInterpFloat(const cmsFloat32Number Input[],
// Trilinear interpolation (16 bits) - optimized version
static
-void TrilinearInterp16(register const cmsUInt16Number Input[],
+void TrilinearInterp16(register const cmsUInt16Number Input[],
register cmsUInt16Number Output[],
register const cmsInterpParams* p)
@@ -494,7 +518,7 @@ void TrilinearInterp16(register const cmsUInt16Number Input[],
#define DENS(i,j,k) (LutTable[(i)+(j)+(k)+OutChan])
#define LERP(a,l,h) (cmsUInt16Number) (l + ROUND_FIXED_TO_INT(((h-l)*a)))
- const cmsUInt16Number* LutTable = (cmsUInt16Number*) p ->Table;
+ const cmsUInt16Number* LutTable = (cmsUInt16Number*) p ->Table;
int OutChan, TotalOut;
cmsS15Fixed16Number fx, fy, fz;
register int rx, ry, rz;
@@ -526,7 +550,7 @@ void TrilinearInterp16(register const cmsUInt16Number Input[],
Y0 = p -> opta[1] * y0;
Y1 = Y0 + (Input[1] == 0xFFFFU ? 0 : p->opta[1]);
-
+
Z0 = p -> opta[0] * z0;
Z1 = Z0 + (Input[2] == 0xFFFFU ? 0 : p->opta[0]);
@@ -562,14 +586,14 @@ void TrilinearInterp16(register const cmsUInt16Number Input[],
}
-// Tetrahedral interpolation, using Sakamoto algorithm.
+// Tetrahedral interpolation, using Sakamoto algorithm.
#define DENS(i,j,k) (LutTable[(i)+(j)+(k)+OutChan])
static
-void TetrahedralInterpFloat(const cmsFloat32Number Input[],
- cmsFloat32Number Output[],
+void TetrahedralInterpFloat(const cmsFloat32Number Input[],
+ cmsFloat32Number Output[],
const cmsInterpParams* p)
{
- const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;
+ const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;
cmsFloat32Number px, py, pz;
int x0, y0, z0,
X0, Y0, Z0, X1, Y1, Z1;
@@ -580,20 +604,9 @@ void TetrahedralInterpFloat(const cmsFloat32Number Input[],
TotalOut = p -> nOutputs;
// We need some clipping here
- px = Input[0];
- py = Input[1];
- pz = Input[2];
-
- if (px < 0) px = 0;
- if (px > 1) px = 1;
- if (py < 0) py = 0;
- if (py > 1) py = 1;
- if (pz < 0) pz = 0;
- if (pz > 1) pz = 1;
-
- px *= p->Domain[0];
- py *= p->Domain[1];
- pz *= p->Domain[2];
+ px = fclamp(Input[0]) * p->Domain[0];
+ py = fclamp(Input[1]) * p->Domain[1];
+ pz = fclamp(Input[2]) * p->Domain[2];
x0 = (int) _cmsQuickFloor(px); rx = (px - (cmsFloat32Number) x0);
y0 = (int) _cmsQuickFloor(py); ry = (py - (cmsFloat32Number) y0);
@@ -605,10 +618,10 @@ void TetrahedralInterpFloat(const cmsFloat32Number Input[],
Y0 = p -> opta[1] * y0;
Y1 = Y0 + (Input[1] >= 1.0 ? 0 : p->opta[1]);
-
+
Z0 = p -> opta[0] * z0;
Z1 = Z0 + (Input[2] >= 1.0 ? 0 : p->opta[0]);
-
+
for (OutChan=0; OutChan < TotalOut; OutChan++) {
// These are the 6 Tetrahedral
@@ -623,7 +636,7 @@ void TetrahedralInterpFloat(const cmsFloat32Number Input[],
}
else
- if (rx >= rz && rz >= ry) {
+ if (rx >= rz && rz >= ry) {
c1 = DENS(X1, Y0, Z0) - c0;
c2 = DENS(X1, Y1, Z1) - DENS(X1, Y0, Z1);
@@ -635,7 +648,7 @@ void TetrahedralInterpFloat(const cmsFloat32Number Input[],
c1 = DENS(X1, Y0, Z1) - DENS(X0, Y0, Z1);
c2 = DENS(X1, Y1, Z1) - DENS(X1, Y0, Z1);
- c3 = DENS(X0, Y0, Z1) - c0;
+ c3 = DENS(X0, Y0, Z1) - c0;
}
else
@@ -655,7 +668,7 @@ void TetrahedralInterpFloat(const cmsFloat32Number Input[],
}
else
- if (rz >= ry && ry >= rx) {
+ if (rz >= ry && ry >= rx) {
c1 = DENS(X1, Y1, Z1) - DENS(X0, Y1, Z1);
c2 = DENS(X0, Y1, Z1) - DENS(X0, Y0, Z1);
@@ -663,7 +676,7 @@ void TetrahedralInterpFloat(const cmsFloat32Number Input[],
}
else {
- c1 = c2 = c3 = 0;
+ c1 = c2 = c3 = 0;
}
Output[OutChan] = c0 + c1 * rx + c2 * ry + c3 * rz;
@@ -675,7 +688,6 @@ void TetrahedralInterpFloat(const cmsFloat32Number Input[],
-#define DENS(i,j,k) (LutTable[(i)+(j)+(k)+OutChan])
static
void TetrahedralInterp16(register const cmsUInt16Number Input[],
@@ -683,108 +695,140 @@ void TetrahedralInterp16(register const cmsUInt16Number Input[],
register const cmsInterpParams* p)
{
const cmsUInt16Number* LutTable = (cmsUInt16Number*) p -> Table;
- cmsS15Fixed16Number fx, fy, fz;
- cmsS15Fixed16Number rx, ry, rz;
- int x0, y0, z0;
- cmsS15Fixed16Number c0, c1, c2, c3, Rest;
- cmsUInt32Number OutChan;
- cmsS15Fixed16Number X0, X1, Y0, Y1, Z0, Z1;
- cmsUInt32Number TotalOut = p -> nOutputs;
-
+ cmsS15Fixed16Number fx, fy, fz;
+ cmsS15Fixed16Number rx, ry, rz;
+ int x0, y0, z0;
+ cmsS15Fixed16Number c0, c1, c2, c3, Rest;
+ cmsS15Fixed16Number X0, X1, Y0, Y1, Z0, Z1;
+ cmsUInt32Number TotalOut = p -> nOutputs;
- fx = _cmsToFixedDomain((int) Input[0] * p -> Domain[0]);
- fy = _cmsToFixedDomain((int) Input[1] * p -> Domain[1]);
- fz = _cmsToFixedDomain((int) Input[2] * p -> Domain[2]);
+ fx = _cmsToFixedDomain((int) Input[0] * p -> Domain[0]);
+ fy = _cmsToFixedDomain((int) Input[1] * p -> Domain[1]);
+ fz = _cmsToFixedDomain((int) Input[2] * p -> Domain[2]);
- x0 = FIXED_TO_INT(fx);
- y0 = FIXED_TO_INT(fy);
- z0 = FIXED_TO_INT(fz);
+ x0 = FIXED_TO_INT(fx);
+ y0 = FIXED_TO_INT(fy);
+ z0 = FIXED_TO_INT(fz);
- rx = FIXED_REST_TO_INT(fx);
- ry = FIXED_REST_TO_INT(fy);
- rz = FIXED_REST_TO_INT(fz);
+ rx = FIXED_REST_TO_INT(fx);
+ ry = FIXED_REST_TO_INT(fy);
+ rz = FIXED_REST_TO_INT(fz);
X0 = p -> opta[2] * x0;
- X1 = X0 + (Input[0] == 0xFFFFU ? 0 : p->opta[2]);
+ X1 = (Input[0] == 0xFFFFU ? 0 : p->opta[2]);
Y0 = p -> opta[1] * y0;
- Y1 = Y0 + (Input[1] == 0xFFFFU ? 0 : p->opta[1]);
+ Y1 = (Input[1] == 0xFFFFU ? 0 : p->opta[1]);
Z0 = p -> opta[0] * z0;
- Z1 = Z0 + (Input[2] == 0xFFFFU ? 0 : p->opta[0]);
-
- // These are the 6 Tetrahedral
- for (OutChan=0; OutChan < TotalOut; OutChan++) {
-
- c0 = DENS(X0, Y0, Z0);
-
- if (rx >= ry && ry >= rz) {
-
- c1 = DENS(X1, Y0, Z0) - c0;
- c2 = DENS(X1, Y1, Z0) - DENS(X1, Y0, Z0);
- c3 = DENS(X1, Y1, Z1) - DENS(X1, Y1, Z0);
-
+ Z1 = (Input[2] == 0xFFFFU ? 0 : p->opta[0]);
+
+ LutTable = &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
+ // This can be replaced by: t = Rest+0x8001, x = (t + (t>>16))>>16
+ // at the cost of being off by one at 7fff and 17ffe.
+
+ if (rx >= ry) {
+ if (ry >= rz) {
+ Y1 += X1;
+ Z1 += Y1;
+ for (; TotalOut; TotalOut--) {
+ c1 = LutTable[X1];
+ c2 = LutTable[Y1];
+ c3 = LutTable[Z1];
+ c0 = *LutTable++;
+ c3 -= c2;
+ c2 -= c1;
+ c1 -= c0;
+ Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001;
+ *Output++ = (cmsUInt16Number) c0 + ((Rest + (Rest>>16))>>16);
+ }
+ } else if (rz >= rx) {
+ X1 += Z1;
+ Y1 += X1;
+ for (; TotalOut; TotalOut--) {
+ c1 = LutTable[X1];
+ c2 = LutTable[Y1];
+ c3 = LutTable[Z1];
+ c0 = *LutTable++;
+ c2 -= c1;
+ c1 -= c3;
+ c3 -= c0;
+ Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001;
+ *Output++ = (cmsUInt16Number) c0 + ((Rest + (Rest>>16))>>16);
+ }
+ } else {
+ Z1 += X1;
+ Y1 += Z1;
+ for (; TotalOut; TotalOut--) {
+ c1 = LutTable[X1];
+ c2 = LutTable[Y1];
+ c3 = LutTable[Z1];
+ c0 = *LutTable++;
+ c2 -= c3;
+ c3 -= c1;
+ c1 -= c0;
+ Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001;
+ *Output++ = (cmsUInt16Number) c0 + ((Rest + (Rest>>16))>>16);
+ }
}
- else
- if (rx >= rz && rz >= ry) {
-
- c1 = DENS(X1, Y0, Z0) - c0;
- c2 = DENS(X1, Y1, Z1) - DENS(X1, Y0, Z1);
- c3 = DENS(X1, Y0, Z1) - DENS(X1, Y0, Z0);
-
+ } else {
+ if (rx >= rz) {
+ X1 += Y1;
+ Z1 += X1;
+ for (; TotalOut; TotalOut--) {
+ c1 = LutTable[X1];
+ c2 = LutTable[Y1];
+ c3 = LutTable[Z1];
+ c0 = *LutTable++;
+ c3 -= c1;
+ c1 -= c2;
+ c2 -= c0;
+ Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001;
+ *Output++ = (cmsUInt16Number) c0 + ((Rest + (Rest>>16))>>16);
}
- else
- if (rz >= rx && rx >= ry) {
-
- c1 = DENS(X1, Y0, Z1) - DENS(X0, Y0, Z1);
- c2 = DENS(X1, Y1, Z1) - DENS(X1, Y0, Z1);
- c3 = DENS(X0, Y0, Z1) - c0;
-
- }
- else
- if (ry >= rx && rx >= rz) {
-
- c1 = DENS(X1, Y1, Z0) - DENS(X0, Y1, Z0);
- c2 = DENS(X0, Y1, Z0) - c0;
- c3 = DENS(X1, Y1, Z1) - DENS(X1, Y1, Z0);
-
- }
- else
- if (ry >= rz && rz >= rx) {
-
- c1 = DENS(X1, Y1, Z1) - DENS(X0, Y1, Z1);
- c2 = DENS(X0, Y1, Z0) - c0;
- c3 = DENS(X0, Y1, Z1) - DENS(X0, Y1, Z0);
-
- }
- else
- if (rz >= ry && ry >= rx) {
-
- c1 = DENS(X1, Y1, Z1) - DENS(X0, Y1, Z1);
- c2 = DENS(X0, Y1, Z1) - DENS(X0, Y0, Z1);
- c3 = DENS(X0, Y0, Z1) - c0;
-
- }
- else {
- c1 = c2 = c3 = 0;
- }
-
- Rest = c1 * rx + c2 * ry + c3 * rz;
-
- Output[OutChan] = (cmsUInt16Number) c0 + ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest));
+ } else if (ry >= rz) {
+ Z1 += Y1;
+ X1 += Z1;
+ for (; TotalOut; TotalOut--) {
+ c1 = LutTable[X1];
+ c2 = LutTable[Y1];
+ c3 = LutTable[Z1];
+ c0 = *LutTable++;
+ c1 -= c3;
+ c3 -= c2;
+ c2 -= c0;
+ Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001;
+ *Output++ = (cmsUInt16Number) c0 + ((Rest + (Rest>>16))>>16);
+ }
+ } else {
+ Y1 += Z1;
+ X1 += Y1;
+ for (; TotalOut; TotalOut--) {
+ c1 = LutTable[X1];
+ c2 = LutTable[Y1];
+ c3 = LutTable[Z1];
+ c0 = *LutTable++;
+ c1 -= c2;
+ c2 -= c3;
+ c3 -= c0;
+ Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001;
+ *Output++ = (cmsUInt16Number) c0 + ((Rest + (Rest>>16))>>16);
+ }
+ }
}
-
}
-#undef DENS
#define DENS(i,j,k) (LutTable[(i)+(j)+(k)+OutChan])
static
-void Eval4Inputs(register const cmsUInt16Number Input[],
- register cmsUInt16Number Output[],
+void Eval4Inputs(register const cmsUInt16Number Input[],
+ register cmsUInt16Number Output[],
register const cmsInterpParams* p16)
-{
- const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
+{
+ const cmsUInt16Number* LutTable;
cmsS15Fixed16Number fk;
cmsS15Fixed16Number k0, rk;
int K0, K1;
@@ -793,7 +837,7 @@ void Eval4Inputs(register const cmsUInt16Number Input[],
int x0, y0, z0;
cmsS15Fixed16Number X0, X1, Y0, Y1, Z0, Z1;
cmsUInt32Number i;
- cmsS15Fixed16Number c0, c1, c2, c3, Rest;
+ cmsS15Fixed16Number c0, c1, c2, c3, Rest;
cmsUInt32Number OutChan;
cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
@@ -803,14 +847,14 @@ void Eval4Inputs(register const cmsUInt16Number Input[],
fy = _cmsToFixedDomain((int) Input[2] * p16 -> Domain[2]);
fz = _cmsToFixedDomain((int) Input[3] * p16 -> Domain[3]);
- k0 = FIXED_TO_INT(fk);
+ k0 = FIXED_TO_INT(fk);
x0 = FIXED_TO_INT(fx);
- y0 = FIXED_TO_INT(fy);
+ y0 = FIXED_TO_INT(fy);
z0 = FIXED_TO_INT(fz);
rk = FIXED_REST_TO_INT(fk);
- rx = FIXED_REST_TO_INT(fx);
- ry = FIXED_REST_TO_INT(fy);
+ rx = FIXED_REST_TO_INT(fx);
+ ry = FIXED_REST_TO_INT(fy);
rz = FIXED_REST_TO_INT(fz);
K0 = p16 -> opta[3] * k0;
@@ -840,7 +884,7 @@ void Eval4Inputs(register const cmsUInt16Number Input[],
}
else
- if (rx >= rz && rz >= ry) {
+ if (rx >= rz && rz >= ry) {
c1 = DENS(X1, Y0, Z0) - c0;
c2 = DENS(X1, Y1, Z1) - DENS(X1, Y0, Z1);
@@ -852,7 +896,7 @@ void Eval4Inputs(register const cmsUInt16Number Input[],
c1 = DENS(X1, Y0, Z1) - DENS(X0, Y0, Z1);
c2 = DENS(X1, Y1, Z1) - DENS(X1, Y0, Z1);
- c3 = DENS(X0, Y0, Z1) - c0;
+ c3 = DENS(X0, Y0, Z1) - c0;
}
else
@@ -872,7 +916,7 @@ void Eval4Inputs(register const cmsUInt16Number Input[],
}
else
- if (rz >= ry && ry >= rx) {
+ if (rz >= ry && ry >= rx) {
c1 = DENS(X1, Y1, Z1) - DENS(X0, Y1, Z1);
c2 = DENS(X0, Y1, Z1) - DENS(X0, Y0, Z1);
@@ -880,10 +924,10 @@ void Eval4Inputs(register const cmsUInt16Number Input[],
}
else {
- c1 = c2 = c3 = 0;
+ c1 = c2 = c3 = 0;
}
- Rest = c1 * rx + c2 * ry + c3 * rz;
+ Rest = c1 * rx + c2 * ry + c3 * rz;
Tmp1[OutChan] = (cmsUInt16Number) c0 + ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest));
}
@@ -904,7 +948,7 @@ void Eval4Inputs(register const cmsUInt16Number Input[],
}
else
- if (rx >= rz && rz >= ry) {
+ if (rx >= rz && rz >= ry) {
c1 = DENS(X1, Y0, Z0) - c0;
c2 = DENS(X1, Y1, Z1) - DENS(X1, Y0, Z1);
@@ -916,7 +960,7 @@ void Eval4Inputs(register const cmsUInt16Number Input[],
c1 = DENS(X1, Y0, Z1) - DENS(X0, Y0, Z1);
c2 = DENS(X1, Y1, Z1) - DENS(X1, Y0, Z1);
- c3 = DENS(X0, Y0, Z1) - c0;
+ c3 = DENS(X0, Y0, Z1) - c0;
}
else
@@ -936,7 +980,7 @@ void Eval4Inputs(register const cmsUInt16Number Input[],
}
else
- if (rz >= ry && ry >= rx) {
+ if (rz >= ry && ry >= rx) {
c1 = DENS(X1, Y1, Z1) - DENS(X0, Y1, Z1);
c2 = DENS(X0, Y1, Z1) - DENS(X0, Y0, Z1);
@@ -944,10 +988,10 @@ void Eval4Inputs(register const cmsUInt16Number Input[],
}
else {
- c1 = c2 = c3 = 0;
+ c1 = c2 = c3 = 0;
}
- Rest = c1 * rx + c2 * ry + c3 * rz;
+ Rest = c1 * rx + c2 * ry + c3 * rz;
Tmp2[OutChan] = (cmsUInt16Number) c0 + ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest));
}
@@ -955,7 +999,7 @@ void Eval4Inputs(register const cmsUInt16Number Input[],
for (i=0; i < p16 -> nOutputs; i++) {
- Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]);
+ Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]);
}
}
#undef DENS
@@ -966,11 +1010,11 @@ void Eval4Inputs(register const cmsUInt16Number Input[],
static
-void Eval4InputsFloat(const cmsFloat32Number Input[],
- cmsFloat32Number Output[],
+void Eval4InputsFloat(const cmsFloat32Number Input[],
+ cmsFloat32Number Output[],
const cmsInterpParams* p)
-{
- const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;
+{
+ const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;
cmsFloat32Number rest;
cmsFloat32Number pk;
int k0, K0, K1;
@@ -979,9 +1023,8 @@ void Eval4InputsFloat(const cmsFloat32Number Input[],
cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
cmsInterpParams p1;
-
- pk = Input[0] * p->Domain[0];
- k0 = _cmsQuickFloor(pk);
+ pk = fclamp(Input[0]) * p->Domain[0];
+ k0 = _cmsQuickFloor(pk);
rest = pk - (cmsFloat32Number) k0;
K0 = p -> opta[3] * k0;
@@ -989,7 +1032,7 @@ void Eval4InputsFloat(const cmsFloat32Number Input[],
p1 = *p;
memmove(&p1.Domain[0], &p ->Domain[1], 3*sizeof(cmsUInt32Number));
-
+
T = LutTable + K0;
p1.Table = T;
@@ -1004,18 +1047,18 @@ void Eval4InputsFloat(const cmsFloat32Number Input[],
cmsFloat32Number y0 = Tmp1[i];
cmsFloat32Number y1 = Tmp2[i];
- Output[i] = y0 + (y1 - y0) * rest;
+ Output[i] = y0 + (y1 - y0) * rest;
}
}
static
-void Eval5Inputs(register const cmsUInt16Number Input[],
- register cmsUInt16Number Output[],
+void Eval5Inputs(register const cmsUInt16Number Input[],
+ register cmsUInt16Number Output[],
register const cmsInterpParams* p16)
-{
- const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
+{
+ const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
cmsS15Fixed16Number fk;
cmsS15Fixed16Number k0, rk;
int K0, K1;
@@ -1024,7 +1067,7 @@ void Eval5Inputs(register const cmsUInt16Number Input[],
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);
@@ -1047,18 +1090,18 @@ void Eval5Inputs(register const cmsUInt16Number Input[],
for (i=0; i < p16 -> nOutputs; i++) {
- Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]);
+ Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]);
}
}
static
-void Eval5InputsFloat(const cmsFloat32Number Input[],
- cmsFloat32Number Output[],
+void Eval5InputsFloat(const cmsFloat32Number Input[],
+ cmsFloat32Number Output[],
const cmsInterpParams* p)
-{
- const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;
+{
+ const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;
cmsFloat32Number rest;
cmsFloat32Number pk;
int k0, K0, K1;
@@ -1067,8 +1110,8 @@ void Eval5InputsFloat(const cmsFloat32Number Input[],
cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
cmsInterpParams p1;
- pk = Input[0] * p->Domain[0];
- k0 = _cmsQuickFloor(pk);
+ pk = fclamp(Input[0]) * p->Domain[0];
+ k0 = _cmsQuickFloor(pk);
rest = pk - (cmsFloat32Number) k0;
K0 = p -> opta[4] * k0;
@@ -1079,31 +1122,31 @@ void Eval5InputsFloat(const cmsFloat32Number Input[],
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;
+ Output[i] = y0 + (y1 - y0) * rest;
}
}
static
-void Eval6Inputs(register const cmsUInt16Number Input[],
- register cmsUInt16Number Output[],
+void Eval6Inputs(register const cmsUInt16Number Input[],
+ register cmsUInt16Number Output[],
register const cmsInterpParams* p16)
-{
- const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
+{
+ const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
cmsS15Fixed16Number fk;
cmsS15Fixed16Number k0, rk;
int K0, K1;
@@ -1111,7 +1154,7 @@ void Eval6Inputs(register const cmsUInt16Number Input[],
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);
@@ -1141,11 +1184,11 @@ void Eval6Inputs(register const cmsUInt16Number Input[],
static
-void Eval6InputsFloat(const cmsFloat32Number Input[],
- cmsFloat32Number Output[],
+void Eval6InputsFloat(const cmsFloat32Number Input[],
+ cmsFloat32Number Output[],
const cmsInterpParams* p)
-{
- const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;
+{
+ const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;
cmsFloat32Number rest;
cmsFloat32Number pk;
int k0, K0, K1;
@@ -1154,8 +1197,8 @@ void Eval6InputsFloat(const cmsFloat32Number Input[],
cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
cmsInterpParams p1;
- pk = Input[0] * p->Domain[0];
- k0 = _cmsQuickFloor(pk);
+ pk = fclamp(Input[0]) * p->Domain[0];
+ k0 = _cmsQuickFloor(pk);
rest = pk - (cmsFloat32Number) k0;
K0 = p -> opta[5] * k0;
@@ -1163,33 +1206,33 @@ void Eval6InputsFloat(const cmsFloat32Number Input[],
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;
+ Output[i] = y0 + (y1 - y0) * rest;
}
}
static
-void Eval7Inputs(register const cmsUInt16Number Input[],
- register cmsUInt16Number Output[],
+void Eval7Inputs(register const cmsUInt16Number Input[],
+ register cmsUInt16Number Output[],
register const cmsInterpParams* p16)
-{
- const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
+{
+ const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
cmsS15Fixed16Number fk;
cmsS15Fixed16Number k0, rk;
int K0, K1;
@@ -1198,7 +1241,7 @@ void Eval7Inputs(register const cmsUInt16Number Input[],
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);
@@ -1207,8 +1250,8 @@ void Eval7Inputs(register const cmsUInt16Number Input[],
K1 = p16 -> opta[6] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));
p1 = *p16;
- memmove(&p1.Domain[0], &p16 ->Domain[1], 5*sizeof(cmsUInt32Number));
-
+ memmove(&p1.Domain[0], &p16 ->Domain[1], 6*sizeof(cmsUInt32Number));
+
T = LutTable + K0;
p1.Table = T;
@@ -1226,11 +1269,11 @@ void Eval7Inputs(register const cmsUInt16Number Input[],
static
-void Eval7InputsFloat(const cmsFloat32Number Input[],
- cmsFloat32Number Output[],
+void Eval7InputsFloat(const cmsFloat32Number Input[],
+ cmsFloat32Number Output[],
const cmsInterpParams* p)
-{
- const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;
+{
+ const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;
cmsFloat32Number rest;
cmsFloat32Number pk;
int k0, K0, K1;
@@ -1239,8 +1282,8 @@ void Eval7InputsFloat(const cmsFloat32Number Input[],
cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
cmsInterpParams p1;
- pk = Input[0] * p->Domain[0];
- k0 = _cmsQuickFloor(pk);
+ pk = fclamp(Input[0]) * p->Domain[0];
+ k0 = _cmsQuickFloor(pk);
rest = pk - (cmsFloat32Number) k0;
K0 = p -> opta[6] * k0;
@@ -1248,34 +1291,34 @@ void Eval7InputsFloat(const cmsFloat32Number Input[],
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;
-
+ Output[i] = y0 + (y1 - y0) * rest;
+
}
}
static
-void Eval8Inputs(register const cmsUInt16Number Input[],
- register cmsUInt16Number Output[],
+void Eval8Inputs(register const cmsUInt16Number Input[],
+ register cmsUInt16Number Output[],
register const cmsInterpParams* p16)
-{
- const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
+{
+ const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
cmsS15Fixed16Number fk;
cmsS15Fixed16Number k0, rk;
int K0, K1;
@@ -1283,7 +1326,7 @@ void Eval8Inputs(register const cmsUInt16Number Input[],
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);
@@ -1293,7 +1336,7 @@ void Eval8Inputs(register const cmsUInt16Number Input[],
p1 = *p16;
memmove(&p1.Domain[0], &p16 ->Domain[1], 7*sizeof(cmsUInt32Number));
-
+
T = LutTable + K0;
p1.Table = T;
@@ -1311,11 +1354,11 @@ void Eval8Inputs(register const cmsUInt16Number Input[],
static
-void Eval8InputsFloat(const cmsFloat32Number Input[],
- cmsFloat32Number Output[],
+void Eval8InputsFloat(const cmsFloat32Number Input[],
+ cmsFloat32Number Output[],
const cmsInterpParams* p)
-{
- const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;
+{
+ const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;
cmsFloat32Number rest;
cmsFloat32Number pk;
int k0, K0, K1;
@@ -1323,9 +1366,9 @@ void Eval8InputsFloat(const cmsFloat32Number Input[],
cmsUInt32Number i;
cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
cmsInterpParams p1;
-
- pk = Input[0] * p->Domain[0];
- k0 = _cmsQuickFloor(pk);
+
+ pk = fclamp(Input[0]) * p->Domain[0];
+ k0 = _cmsQuickFloor(pk);
rest = pk - (cmsFloat32Number) k0;
K0 = p -> opta[7] * k0;
@@ -1338,24 +1381,24 @@ void Eval8InputsFloat(const cmsFloat32Number Input[],
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];
- Output[i] = y0 + (y1 - y0) * rest;
+ Output[i] = y0 + (y1 - y0) * rest;
}
}
// The default factory
-static
+static
cmsInterpFunction DefaultInterpolatorsFactory(cmsUInt32Number nInputChannels, cmsUInt32Number nOutputChannels, cmsUInt32Number dwFlags)
{
@@ -1366,7 +1409,7 @@ cmsInterpFunction DefaultInterpolatorsFactory(cmsUInt32Number nInputChannels, cm
memset(&Interpolation, 0, sizeof(Interpolation));
// Safety check
- if (nInputChannels >= 4 && nOutputChannels >= MAX_STAGE_CHANNELS)
+ if (nInputChannels >= 4 && nOutputChannels >= MAX_STAGE_CHANNELS)
return Interpolation;
switch (nInputChannels) {
@@ -1375,7 +1418,7 @@ cmsInterpFunction DefaultInterpolatorsFactory(cmsUInt32Number nInputChannels, cm
if (nOutputChannels == 1) {
- if (IsFloat)
+ if (IsFloat)
Interpolation.LerpFloat = LinLerp1Dfloat;
else
Interpolation.Lerp16 = LinLerp1D;
@@ -1384,31 +1427,31 @@ cmsInterpFunction DefaultInterpolatorsFactory(cmsUInt32Number nInputChannels, cm
else {
if (IsFloat)
- Interpolation.LerpFloat = Eval1InputFloat;
+ Interpolation.LerpFloat = Eval1InputFloat;
else
- Interpolation.Lerp16 = Eval1Input;
+ Interpolation.Lerp16 = Eval1Input;
}
break;
case 2: // Duotone
- if (IsFloat)
+ if (IsFloat)
Interpolation.LerpFloat = BilinearInterpFloat;
else
Interpolation.Lerp16 = BilinearInterp16;
break;
- case 3: // RGB et al
+ case 3: // RGB et al
if (IsTrilinear) {
- if (IsFloat)
+ if (IsFloat)
Interpolation.LerpFloat = TrilinearInterpFloat;
else
Interpolation.Lerp16 = TrilinearInterp16;
}
else {
- if (IsFloat)
+ if (IsFloat)
Interpolation.LerpFloat = TetrahedralInterpFloat;
else {
@@ -1417,37 +1460,37 @@ cmsInterpFunction DefaultInterpolatorsFactory(cmsUInt32Number nInputChannels, cm
}
break;
- case 4: // CMYK lut
+ case 4: // CMYK lut
- if (IsFloat)
+ if (IsFloat)
Interpolation.LerpFloat = Eval4InputsFloat;
else
Interpolation.Lerp16 = Eval4Inputs;
break;
case 5: // 5 Inks
- if (IsFloat)
+ if (IsFloat)
Interpolation.LerpFloat = Eval5InputsFloat;
else
Interpolation.Lerp16 = Eval5Inputs;
- break;
+ break;
case 6: // 6 Inks
- if (IsFloat)
+ if (IsFloat)
Interpolation.LerpFloat = Eval6InputsFloat;
else
Interpolation.Lerp16 = Eval6Inputs;
break;
case 7: // 7 inks
- if (IsFloat)
+ if (IsFloat)
Interpolation.LerpFloat = Eval7InputsFloat;
else
Interpolation.Lerp16 = Eval7Inputs;
break;
case 8: // 8 inks
- if (IsFloat)
+ if (IsFloat)
Interpolation.LerpFloat = Eval8InputsFloat;
else
Interpolation.Lerp16 = Eval8Inputs;