[gs-commits] ghostpdl branch, master, updated. jbig2dec-0.14-1655-gbc48c29
[email protected] (Robin Watts)
| Newsgroups | gmane.comp.printing.ghostscript.cvs |
|---|---|
| Message-ID | <[email protected]> |
The ghostpdl branch, master has been updated
via bc48c29c5e86e6c528e23140c71ecfb58588333f (commit)
via 63e1fd40674a4f89f6593098cf100382061753e5 (commit)
via 1cc72912138544dcf00ed0dbc77ceaf47de04e91 (commit)
via 3f46434c0fe3707f53a825f39fa1bab8c0875c03 (commit)
from b5e5ed8620f348e0fa619171d6f05a966a4bcf83 (commit)
----------------------------------------------------------------------
commit bc48c29c5e86e6c528e23140c71ecfb58588333f
Author: Robin Watts <[email protected]>
Date: Mon Sep 9 14:19:33 2019 +0100
Optimise Eval{5,6,7,8}Inputs{,Float}.
Only use 1 Temporary array, and avoid needless work in the
0xFFFF cases.
diff --git a/lcms2mt/src/cmsintrp.c b/lcms2mt/src/cmsintrp.c
index 3585e4f..b6846f6 100644
--- a/lcms2mt/src/cmsintrp.c
+++ b/lcms2mt/src/cmsintrp.c
@@ -1180,41 +1180,27 @@ void Eval5Inputs(cmsContext ContextID, register const cmsUInt16Number Input[],
register cmsUInt16Number Output[],
register 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;
+ cmsS15Fixed16Number fk;
+ cmsUInt32Number i, n;
+ cmsUInt16Number Tmp[MAX_STAGE_CHANNELS];
+ cmsInterpParams p1 = *p16;
+ memmove(&p1.Domain[0], &p16 ->Domain[1], 4*sizeof(cmsUInt32Number));
+ fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);
+ p1.Table = ((cmsUInt16Number*)p16 -> Table) + p16 -> opta[4] * FIXED_TO_INT(fk);
- fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);
- k0 = FIXED_TO_INT(fk);
- rk = FIXED_REST_TO_INT(fk);
+ Eval4Inputs(ContextID, Input + 1, Output, &p1);
- K0 = p16 -> opta[4] * k0;
- K1 = p16 -> opta[4] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));
+ if (Input[0] == 0xFFFFU)
+ return;
- p1 = *p16;
- memmove(&p1.Domain[0], &p16 ->Domain[1], 4*sizeof(cmsUInt32Number));
-
- T = LutTable + K0;
- p1.Table = T;
-
- Eval4Inputs(ContextID, Input + 1, Tmp1, &p1);
-
- T = LutTable + K1;
- p1.Table = T;
-
- Eval4Inputs(ContextID, Input + 1, Tmp2, &p1);
-
- for (i=0; i < p16 -> nOutputs; i++) {
-
- Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]);
- }
+ p1.Table = ((cmsUInt16Number*)p1.Table) + p16 -> opta[4];
+ Eval4Inputs(ContextID, Input + 1, Tmp, &p1);
+ fk = FIXED_REST_TO_INT(fk);
+ n = p16 -> nOutputs;
+ for (i=0; i < n; i++)
+ Output[i] = LinearInterp(fk, Output[i], Tmp[i]);
}
@@ -1223,42 +1209,36 @@ void Eval5InputsFloat(cmsContext ContextID, 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;
+ cmsFloat32Number rest;
+ cmsFloat32Number pk;
+ int k0;
+ cmsUInt32Number i, n;
+ cmsFloat32Number Tmp[MAX_STAGE_CHANNELS];
+ cmsInterpParams p1 = *p;
+ cmsFloat32Number i0 = fclamp(Input[0]);
- pk = fclamp(Input[0]) * p->Domain[0];
- k0 = _cmsQuickFloor(pk);
- rest = pk - (cmsFloat32Number) k0;
+ pk = i0 * 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]);
+ memmove(&p1.Domain[0], &p ->Domain[1], 4*sizeof(cmsUInt32Number));
+ p1.Table = ((cmsFloat32Number*) p -> Table) + p -> opta[4] * k0;
- p1 = *p;
- memmove(&p1.Domain[0], &p ->Domain[1], 4*sizeof(cmsUInt32Number));
+ Eval4InputsFloat(ContextID, Input + 1, Output, &p1);
- T = LutTable + K0;
- p1.Table = T;
+ if (i0 == 1.0)
+ return;
- Eval4InputsFloat(ContextID, Input + 1, Tmp1, &p1);
+ p1.Table = ((cmsFloat32Number*) p1.Table) + p->opta[4];
+ Eval4InputsFloat(ContextID, Input + 1, Tmp, &p1);
- T = LutTable + K1;
- p1.Table = T;
+ n = p -> nOutputs;
+ for (i=0; i < n; i++) {
+ cmsFloat32Number y0 = Output[i];
+ cmsFloat32Number y1 = Tmp[i];
- Eval4InputsFloat(ContextID, 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;
+ }
}
@@ -1268,40 +1248,27 @@ void Eval6Inputs(cmsContext ContextID, register const cmsUInt16Number Input[],
register cmsUInt16Number Output[],
register 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;
+ cmsS15Fixed16Number fk;
+ cmsUInt32Number i, n;
+ cmsUInt16Number Tmp[MAX_STAGE_CHANNELS];
+ cmsInterpParams p1 = *p16;
- fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);
- k0 = FIXED_TO_INT(fk);
- rk = FIXED_REST_TO_INT(fk);
+ memmove(&p1.Domain[0], &p16 ->Domain[1], 5*sizeof(cmsUInt32Number));
+ fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);
+ p1.Table = ((cmsUInt16Number*)p16 -> Table) + p16 -> opta[5] * FIXED_TO_INT(fk);
- K0 = p16 -> opta[5] * k0;
- K1 = p16 -> opta[5] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));
+ Eval5Inputs(ContextID, Input + 1, Output, &p1);
- p1 = *p16;
- memmove(&p1.Domain[0], &p16 ->Domain[1], 5*sizeof(cmsUInt32Number));
+ if (Input[0] == 0xFFFFU)
+ return;
- T = LutTable + K0;
- p1.Table = T;
-
- Eval5Inputs(ContextID, Input + 1, Tmp1, &p1);
-
- T = LutTable + K1;
- p1.Table = T;
-
- Eval5Inputs(ContextID, Input + 1, Tmp2, &p1);
-
- for (i=0; i < p16 -> nOutputs; i++) {
-
- Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]);
- }
+ p1.Table = ((cmsUInt16Number*)p1.Table) + p16 -> opta[5];
+ Eval5Inputs(ContextID, Input + 1, Tmp, &p1);
+ fk = FIXED_REST_TO_INT(fk);
+ n = p16 -> nOutputs;
+ for (i=0; i < n; i++)
+ Output[i] = LinearInterp(fk, Output[i], Tmp[i]);
}
@@ -1310,42 +1277,36 @@ void Eval6InputsFloat(cmsContext ContextID, 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;
+ cmsFloat32Number rest;
+ cmsFloat32Number pk;
+ int k0;
+ cmsUInt32Number i, n;
+ cmsFloat32Number Tmp[MAX_STAGE_CHANNELS];
+ cmsInterpParams p1 = *p;
+ cmsFloat32Number i0 = fclamp(Input[0]);
- pk = fclamp(Input[0]) * p->Domain[0];
- k0 = _cmsQuickFloor(pk);
- rest = pk - (cmsFloat32Number) k0;
+ pk = i0 * 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]);
+ memmove(&p1.Domain[0], &p ->Domain[1], 5*sizeof(cmsUInt32Number));
+ p1.Table = ((cmsFloat32Number*) p -> Table) + p -> opta[5] * k0;
- p1 = *p;
- memmove(&p1.Domain[0], &p ->Domain[1], 5*sizeof(cmsUInt32Number));
+ Eval5InputsFloat(ContextID, Input + 1, Output, &p1);
- T = LutTable + K0;
- p1.Table = T;
+ if (i0 == 1.0)
+ return;
- Eval5InputsFloat(ContextID, Input + 1, Tmp1, &p1);
+ p1.Table = ((cmsFloat32Number*) p1.Table) + p->opta[5];
+ Eval5InputsFloat(ContextID, Input + 1, Tmp, &p1);
- T = LutTable + K1;
- p1.Table = T;
+ n = p -> nOutputs;
+ for (i=0; i < n; i++) {
+ cmsFloat32Number y0 = Output[i];
+ cmsFloat32Number y1 = Tmp[i];
- Eval5InputsFloat(ContextID, 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;
+ }
}
@@ -1354,39 +1315,27 @@ void Eval7Inputs(cmsContext ContextID, register const cmsUInt16Number Input[],
register cmsUInt16Number Output[],
register 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;
+ cmsS15Fixed16Number fk;
+ cmsUInt32Number i, n;
+ cmsUInt16Number Tmp[MAX_STAGE_CHANNELS];
+ cmsInterpParams p1 = *p16;
+ memmove(&p1.Domain[0], &p16 ->Domain[1], 6*sizeof(cmsUInt32Number));
+ fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);
+ p1.Table = ((cmsUInt16Number*)p16 -> Table) + p16 -> opta[6] * FIXED_TO_INT(fk);
- fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);
- k0 = FIXED_TO_INT(fk);
- rk = FIXED_REST_TO_INT(fk);
+ Eval6Inputs(ContextID, Input + 1, Output, &p1);
- K0 = p16 -> opta[6] * k0;
- K1 = p16 -> opta[6] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));
+ if (Input[0] == 0xFFFFU)
+ return;
- p1 = *p16;
- memmove(&p1.Domain[0], &p16 ->Domain[1], 6*sizeof(cmsUInt32Number));
+ p1.Table = ((cmsUInt16Number*)p1.Table) + p16 -> opta[6];
+ Eval6Inputs(ContextID, Input + 1, Tmp, &p1);
- T = LutTable + K0;
- p1.Table = T;
-
- Eval6Inputs(ContextID, Input + 1, Tmp1, &p1);
-
- T = LutTable + K1;
- p1.Table = T;
-
- Eval6Inputs(ContextID, Input + 1, Tmp2, &p1);
-
- for (i=0; i < p16 -> nOutputs; i++) {
- Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]);
- }
+ fk = FIXED_REST_TO_INT(fk);
+ n = p16 -> nOutputs;
+ for (i=0; i < n; i++)
+ Output[i] = LinearInterp(fk, Output[i], Tmp[i]);
}
@@ -1395,44 +1344,36 @@ void Eval7InputsFloat(cmsContext ContextID, 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;
+ cmsFloat32Number rest;
+ cmsFloat32Number pk;
+ int k0;
+ cmsUInt32Number i, n;
+ cmsFloat32Number Tmp[MAX_STAGE_CHANNELS];
+ cmsInterpParams p1 = *p;
+ cmsFloat32Number i0 = fclamp(Input[0]);
- pk = fclamp(Input[0]) * p->Domain[0];
- k0 = _cmsQuickFloor(pk);
- rest = pk - (cmsFloat32Number) k0;
+ pk = i0 * 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]);
+ memmove(&p1.Domain[0], &p ->Domain[1], 6*sizeof(cmsUInt32Number));
+ p1.Table = ((cmsFloat32Number*) p -> Table) + p -> opta[6] * k0;
- p1 = *p;
- memmove(&p1.Domain[0], &p ->Domain[1], 6*sizeof(cmsUInt32Number));
+ Eval6InputsFloat(ContextID, Input + 1, Output, &p1);
- T = LutTable + K0;
- p1.Table = T;
+ if (i0 == 1.0)
+ return;
- Eval6InputsFloat(ContextID, Input + 1, Tmp1, &p1);
+ p1.Table = ((cmsFloat32Number*) p1.Table) + p->opta[6];
+ Eval6InputsFloat(ContextID, Input + 1, Tmp, &p1);
- T = LutTable + K1;
- p1.Table = T;
+ n = p -> nOutputs;
+ for (i=0; i < n; i++) {
+ cmsFloat32Number y0 = Output[i];
+ cmsFloat32Number y1 = Tmp[i];
- Eval6InputsFloat(ContextID, 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 CMS_NO_SANITIZE
@@ -1440,37 +1381,27 @@ void Eval8Inputs(cmsContext ContextID, register const cmsUInt16Number Input[],
register cmsUInt16Number Output[],
register 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;
+ cmsS15Fixed16Number fk;
+ cmsUInt32Number i, n;
+ cmsUInt16Number Tmp[MAX_STAGE_CHANNELS];
+ cmsInterpParams p1 = *p16;
- fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);
- k0 = FIXED_TO_INT(fk);
- rk = FIXED_REST_TO_INT(fk);
+ memmove(&p1.Domain[0], &p16 ->Domain[1], 7*sizeof(cmsUInt32Number));
+ fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);
+ p1.Table = ((cmsUInt16Number*)p16 -> Table) + p16 -> opta[7] * FIXED_TO_INT(fk);
- K0 = p16 -> opta[7] * k0;
- K1 = p16 -> opta[7] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));
+ Eval7Inputs(ContextID, Input + 1, Output, &p1);
- p1 = *p16;
- memmove(&p1.Domain[0], &p16 ->Domain[1], 7*sizeof(cmsUInt32Number));
+ if (Input[0] == 0xFFFFU)
+ return;
- T = LutTable + K0;
- p1.Table = T;
+ p1.Table = ((cmsUInt16Number*)p1.Table) + p16 -> opta[7];
+ Eval7Inputs(ContextID, Input + 1, Tmp, &p1);
- Eval7Inputs(ContextID, Input + 1, Tmp1, &p1);
-
- T = LutTable + K1;
- p1.Table = T;
- Eval7Inputs(ContextID, Input + 1, Tmp2, &p1);
-
- for (i=0; i < p16 -> nOutputs; i++) {
- Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]);
- }
+ fk = FIXED_REST_TO_INT(fk);
+ n = p16 -> nOutputs;
+ for (i=0; i < n; i++)
+ Output[i] = LinearInterp(fk, Output[i], Tmp[i]);
}
@@ -1480,43 +1411,36 @@ void Eval8InputsFloat(cmsContext ContextID, 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;
+ cmsFloat32Number rest;
+ cmsFloat32Number pk;
+ int k0;
+ cmsUInt32Number i, n;
+ cmsFloat32Number Tmp[MAX_STAGE_CHANNELS];
+ cmsInterpParams p1 = *p;
+ cmsFloat32Number i0 = fclamp(Input[0]);
- pk = fclamp(Input[0]) * p->Domain[0];
- k0 = _cmsQuickFloor(pk);
- rest = pk - (cmsFloat32Number) k0;
+ pk = i0 * 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]);
+ memmove(&p1.Domain[0], &p ->Domain[1], 7*sizeof(cmsUInt32Number));
+ p1.Table = ((cmsFloat32Number*) p -> Table) + p -> opta[7] * k0;
- p1 = *p;
- memmove(&p1.Domain[0], &p ->Domain[1], 7*sizeof(cmsUInt32Number));
+ Eval7InputsFloat(ContextID, Input + 1, Output, &p1);
- T = LutTable + K0;
- p1.Table = T;
+ if (i0 == 1.0)
+ return;
- Eval7InputsFloat(ContextID, Input + 1, Tmp1, &p1);
+ p1.Table = ((cmsFloat32Number*) p1.Table) + p->opta[7];
+ Eval7InputsFloat(ContextID, Input + 1, Tmp, &p1);
- T = LutTable + K1;
- p1.Table = T;
+ n = p -> nOutputs;
+ for (i=0; i < n; i++) {
+ cmsFloat32Number y0 = Output[i];
+ cmsFloat32Number y1 = Tmp[i];
- Eval7InputsFloat(ContextID, 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
----------------------------------------------------------------------
commit 63e1fd40674a4f89f6593098cf100382061753e5
Author: Robin Watts <[email protected]>
Date: Mon Sep 9 11:03:59 2019 +0100
Tweak Eval4InputsFloat for speed.
Move to the Pentachoronal Interpolation algorithm.
diff --git a/lcms2mt/src/cmsintrp.c b/lcms2mt/src/cmsintrp.c
index f4f22be..3585e4f 100644
--- a/lcms2mt/src/cmsintrp.c
+++ b/lcms2mt/src/cmsintrp.c
@@ -1061,69 +1061,81 @@ void Eval4InputsFloat(cmsContext ContextID, const cmsFloat32Number Input[],
LutTable = (cmsFloat32Number*) p -> Table;
LutTable += K0 + X0 + Y0 + Z0;
- which = (ry > rx ? 1 : 0) +
- (rz > rx ? 2 : 0) +
- (rk > rx ? 4 : 0) +
- (rz > ry ? 8 : 0) +
- (rk > ry ? 16 : 0) +
- (rk > rz ? 32 : 0);
- /* This gives us 24 possible cases:
- * which Tetrahedral corners
- * 0x00 rx >= ry >= rz >= rk (0,0,0,0) (1,0,0,0) (1,1,0,0) (1,1,1,0) (1,1,1,1)
- * 0x01 ry > rx >= rz >= rk (0,0,0,0) (0,1,0,0) (1,1,0,0) (1,1,1,0) (1,1,1,1)
- * 0x03 ry >= rz > rx >= rk (0,0,0,0) (0,1,0,0) (0,1,1,0) (1,1,1,0) (1,1,1,1)
- * 0x07 ry >= rz >= rk > rx (0,0,0,0) (0,1,0,0) (0,1,1,0) (0,1,1,1) (1,1,1,1)
- * 0x08 rx >= rz > ry >= rk (0,0,0,0) (1,0,0,0) (1,0,1,0) (1,1,1,0) (1,1,1,1)
- * 0x0a rz > rx >= ry >= rk (0,0,0,0) (0,0,1,0) (1,0,1,0) (1,1,1,0) (1,1,1,1)
- * 0x0b rz > ry > rx >= rk (0,0,0,0) (0,0,1,0) (0,1,1,0) (1,1,1,0) (1,1,1,1)
- * 0x0f rz > ry >= rk > rx (0,0,0,0) (0,0,1,0) (0,1,1,0) (0,1,1,1) (1,1,1,1)
- * 0x18 rx >= rz >= rk > ry (0,0,0,0) (1,0,0,0) (1,0,1,0) (1,0,1,1) (1,1,1,1)
- * 0x1a rz > rx >= rk > ry (0,0,0,0) (0,0,1,0) (1,0,1,0) (1,0,1,1) (1,1,1,1)
- * 0x1e rz >= rk > rx >= ry (0,0,0,0) (0,0,1,0) (0,0,1,1) (1,0,1,1) (1,1,1,1)
- * 0x1f rz >= rk > ry > rx (0,0,0,0) (0,0,1,0) (0,0,1,1) (0,1,1,1) (1,1,1,1)
- * 0x20 rx >= ry >= rk > rz (0,0,0,0) (1,0,0,0) (1,1,0,0) (1,1,0,1) (1,1,1,1)
- * 0x21 ry > rx >= rk > rz (0,0,0,0) (0,1,0,0) (1,1,0,0) (1,1,0,1) (1,1,1,1)
- * 0x25 ry >= rk > rx >= rz (0,0,0,0) (0,1,0,0) (0,1,0,1) (1,1,0,1) (1,1,1,1)
- * 0x27 ry >= rk > rz > rx (0,0,0,0) (0,1,0,0) (0,1,0,1) (0,1,1,1) (1,1,1,1)
- * 0x30 rx >= rk > ry >= rz (0,0,0,0) (1,0,0,0) (1,0,0,1) (1,1,0,1) (1,1,1,1)
- * 0x34 rk > rx >= ry >= rz (0,0,0,0) (0,0,0,1) (1,0,0,1) (1,1,0,1) (1,1,1,1)
- * 0x35 rk > ry > rx >= rz (0,0,0,0) (0,0,0,1) (0,1,0,1) (1,1,0,1) (1,1,1,1)
- * 0x37 rk > ry >= rz > rx (0,0,0,0) (0,0,0,1) (0,1,0,1) (0,1,1,1) (1,1,1,1)
- * 0x38 rx >= rk > rz > ry (0,0,0,0) (1,0,0,0) (1,0,0,1) (1,0,1,1) (1,1,1,1)
- * 0x3c rk > rx >= rz > ry (0,0,0,0) (0,0,0,1) (1,0,0,1) (1,0,1,1) (1,1,1,1)
- * 0x3e rk > rz > rx >= ry (0,0,0,0) (0,0,0,1) (0,0,1,1) (1,0,1,1) (1,1,1,1)
- * 0x3f rk > rz > ry > rx (0,0,0,0) (0,0,0,1) (0,0,1,1) (0,1,1,1) (1,1,1,1)
- */
+ /* We carefully choose the following tests, a) cos these
+ * work nicely in SSE (see CAL), and b) because, as well
+ * as the standard 24 pentachorons, we get some useful
+ * special cases. */
+ which = (rx > ry ? 1 : 0) +
+ (ry > rz ? 2 : 0) +
+ (rz > rk ? 4 : 0) +
+ (rk > rx ? 8 : 0) +
+ (rz > rx ? 16 : 0) +
+ (rk > ry ? 32 : 0);
o4 = X1+Y1+Z1+K1;
switch(which)
{
- default: /* Never happens, but stops the compiler complaining of uninitialised vars */
- case 0x00: o1 = X1; o2 = Y1; o3 = Z1; m1 = rx; m2 = ry; m3 = rz; m4 = rk; break;
- case 0x01: o1 = Y1; o2 = X1; o3 = Z1; m1 = ry; m2 = rx; m3 = rz; m4 = rk; break;
- case 0x03: o1 = Y1; o2 = Z1; o3 = X1; m1 = ry; m2 = rz; m3 = rx; m4 = rk; break;
- case 0x07: o1 = Y1; o2 = Z1; o3 = K1; m1 = ry; m2 = rz; m3 = rk; m4 = rx; break;
- case 0x08: o1 = X1; o2 = Z1; o3 = Y1; m1 = rx; m2 = rz; m3 = ry; m4 = rk; break;
- case 0x0a: o1 = Z1; o2 = X1; o3 = Y1; m1 = rz; m2 = rx; m3 = ry; m4 = rk; break;
- case 0x0b: o1 = Z1; o2 = Y1; o3 = X1; m1 = rz; m2 = ry; m3 = rx; m4 = rk; break;
- case 0x0f: o1 = Z1; o2 = Y1; o3 = K1; m1 = rz; m2 = ry; m3 = rk; m4 = rx; break;
- case 0x18: o1 = X1; o2 = Z1; o3 = K1; m1 = rx; m2 = rz; m3 = rk; m4 = ry; break;
- case 0x1a: o1 = Z1; o2 = X1; o3 = K1; m1 = rz; m2 = rx; m3 = rk; m4 = ry; break;
- case 0x1e: o1 = Z1; o2 = K1; o3 = X1; m1 = rz; m2 = rk; m3 = rx; m4 = ry; break;
- case 0x1f: o1 = Z1; o2 = K1; o3 = Y1; m1 = rz; m2 = rk; m3 = ry; m4 = rx; break;
- case 0x20: o1 = X1; o2 = Y1; o3 = K1; m1 = rx; m2 = ry; m3 = rk; m4 = rz; break;
- case 0x21: o1 = Y1; o2 = X1; o3 = K1; m1 = ry; m2 = rx; m3 = rk; m4 = rz; break;
- case 0x25: o1 = Y1; o2 = K1; o3 = X1; m1 = ry; m2 = rk; m3 = rx; m4 = rz; break;
- case 0x27: o1 = Y1; o2 = K1; o3 = Z1; m1 = ry; m2 = rk; m3 = rz; m4 = rx; break;
- case 0x30: o1 = X1; o2 = K1; o3 = Y1; m1 = rx; m2 = rk; m3 = ry; m4 = rz; break;
- case 0x34: o1 = K1; o2 = X1; o3 = Y1; m1 = rk; m2 = rx; m3 = ry; m4 = rz; break;
- case 0x35: o1 = K1; o2 = Y1; o3 = X1; m1 = rk; m2 = ry; m3 = rx; m4 = rz; break;
- case 0x37: o1 = K1; o2 = Y1; o3 = Z1; m1 = rk; m2 = ry; m3 = rz; m4 = rx; break;
- case 0x38: o1 = X1; o2 = K1; o3 = Z1; m1 = rx; m2 = rk; m3 = rz; m4 = ry; break;
- case 0x3c: o1 = K1; o2 = X1; o3 = Z1; m1 = rk; m2 = rx; m3 = rz; m4 = ry; break;
- case 0x3e: o1 = K1; o2 = Z1; o3 = X1; m1 = rk; m2 = rz; m3 = rx; m4 = ry; break;
- case 0x3f: o1 = K1; o2 = Z1; o3 = Y1; m1 = rk; m2 = rz; m3 = ry; m4 = rx; break;
+ default: /* Never happens, but stops the compiler complaining of uninitialised vars */
+ case 0x00: /* x == y == z == k - special case */
+ m1 = rx; goto one_lerp;
+ case 0x01: /* x > k == z == y - special case */
+ o1 = X1; m1 = rx; m2 = ry; goto two_lerps;
+ case 0x18: /* y == z == k > x - special case */
+ o1 = Y1+Z1+K1; m1 = ry; m2 = rx; goto two_lerps;
+ case 0x04: /* z == y == x > k - special case */
+ o1 = X1+Y1+Z1; m1 = ry; m2 = rk; goto two_lerps;
+ case 0x28: /* k > z == y == x - special case */
+ o1 = K1; m1 = rk; m2 = ry; goto two_lerps;
+ case 0x02: /* y >= x >= k >= z */
+ o1 = Y1; o2 = X1; o3 = K1; m1 = ry; m2 = rx; m3 = rk; m4 = rz; break;
+ case 0x03: /* x > y >= k >= z */
+ o1 = X1; o2 = Y1; o3 = K1; m1 = rx; m2 = ry; m3 = rk; m4 = rz; break;
+ case 0x05: /* x >= z >= y >= k */
+ o1 = X1; o2 = Z1; o3 = Y1; m1 = rx; m2 = rz; m3 = ry; m4 = rk; break;
+ case 0x06: /* y >= x >= z > k */
+ o1 = Y1; o2 = X1; o3 = Z1; m1 = ry; m2 = rx; m3 = rz; m4 = rk; break;
+ case 0x07: /* x > y > z > k */
+ o1 = X1; o2 = Y1; o3 = Z1; m1 = rx; m2 = ry; m3 = rz; m4 = rk; break;
+ case 0x0a: /* y >= k > x >= z */
+ o1 = Y1; o2 = K1; o3 = X1; m1 = ry; m2 = rk; m3 = rx; m4 = rz; break;
+ case 0x14: /* z >= y >= x >= k */
+ o1 = Z1; o2 = Y1; o3 = X1; m1 = rz; m2 = ry; m3 = rx; m4 = rk; break;
+ case 0x15: /* z > x >= y >= k */
+ o1 = Z1; o2 = X1; o3 = Y1; m1 = rz; m2 = rx; m3 = ry; m4 = rk; break;
+ case 0x16: /* y >= z > x >= k */
+ o1 = Y1; o2 = Z1; o3 = X1; m1 = ry; m2 = rz; m3 = rx; m4 = rk; break;
+ case 0x1a: /* y >= k >= z > x */
+ o1 = Y1; o2 = K1; o3 = Z1; m1 = ry; m2 = rk; m3 = rz; m4 = rx; break;
+ case 0x1c: /* z >= y >= k > x */
+ o1 = Z1; o2 = Y1; o3 = K1; m1 = rz; m2 = ry; m3 = rk; m4 = rx; break;
+ case 0x1e: /* y > z > k > x */
+ o1 = Y1; o2 = Z1; o3 = K1; m1 = ry; m2 = rz; m3 = rk; m4 = rx; break;
+ case 0x21: /* x >= k >= z >= y */
+ o1 = X1; o2 = K1; o3 = Z1; m1 = rx; m2 = rk; m3 = rz; m4 = ry; break;
+ case 0x23: /* x >= k > y > z */
+ o1 = X1; o2 = K1; o3 = Y1; m1 = rx; m2 = rk; m3 = ry; m4 = rz; break;
+ case 0x25: /* x >= z > k > y */
+ o1 = X1; o2 = Z1; o3 = K1; m1 = rx; m2 = rz; m3 = rk; m4 = ry; break;
+ case 0x29: /* k > x >= z >= y */
+ o1 = K1; o2 = X1; o3 = Z1; m1 = rk; m2 = rx; m3 = rz; m4 = ry; break;
+ case 0x2a: /* k > y >= x >= z */
+ o1 = K1; o2 = Y1; o3 = X1; m1 = rk; m2 = ry; m3 = rx; m4 = rz; break;
+ case 0x2b: /* k > x > y > z */
+ o1 = K1; o2 = X1; o3 = Y1; m1 = rk; m2 = rx; m3 = ry; m4 = rz; break;
+ case 0x35: /* z > x >= k > y */
+ o1 = Z1; o2 = X1; o3 = K1; m1 = rz; m2 = rx; m3 = rk; m4 = ry; break;
+ case 0x38: /* k >= z >= y >= x */
+ o1 = K1; o2 = Z1; o3 = Y1; m1 = rk; m2 = rz; m3 = ry; m4 = rx; break;
+ case 0x39: /* k >= z > x > y */
+ o1 = K1; o2 = Z1; o3 = X1; m1 = rk; m2 = rz; m3 = rx; m4 = ry; break;
+ case 0x3a: /* k > y > z > x */
+ o1 = K1; o2 = Y1; o3 = Z1; m1 = rk; m2 = ry; m3 = rz; m4 = rx; break;
+ case 0x3c: /* z > k > y >= x */
+ o1 = Z1; o2 = K1; o3 = Y1; m1 = rz; m2 = rk; m3 = ry; m4 = rx; break;
+ case 0x3d: /* z > k > x > y */
+ o1 = Z1; o2 = K1; o3 = X1; m1 = rz; m2 = rk; m3 = rx; m4 = ry; break;
}
+ assert(m1 >= m2 && m2 >= m3 && m3 >= m4);
o2 += o1;
o3 += o2;
for (OutChan=TotalOut; OutChan != 0; OutChan--) {
@@ -1138,6 +1150,29 @@ void Eval4InputsFloat(cmsContext ContextID, const cmsFloat32Number Input[],
*Out++ = c0 + c1 * m1 + c2 * m2 + c3 * m3 + c4 * m4;
}
+ return;
+
+two_lerps:
+ assert(m1 >= m2);
+ for (OutChan=TotalOut; OutChan != 0; OutChan--) {
+ c1 = LutTable[o1];
+ c2 = LutTable[o4] - c1;
+ c0 = *LutTable++;
+ c1 -= c0;
+
+ *Out++ = c0 + c1 * m1 + c2 * m2;
+ }
+ return;
+
+one_lerp:
+ for (OutChan=TotalOut; OutChan != 0; OutChan--) {
+ c1 = LutTable[o4];
+ c0 = *LutTable++;
+ c1 -= c0;
+
+ *Out++ = c0 + c1 * m1;
+ }
+ return;
}
static CMS_NO_SANITIZE
----------------------------------------------------------------------
commit 1cc72912138544dcf00ed0dbc77ceaf47de04e91
Author: Robin Watts <[email protected]>
Date: Fri Sep 6 18:04:17 2019 +0100
Tweak Eval4Inputs for speed.
In coding the SSE version for CAL, I spotted a slightly
preferable test that allows us to capture some special
cases for free. These special cases accelerate some
useful cases including:
* C=M=Y=K (such as when all 0 = white?)
* C=M=Y (such as when pure black)
* M=Y=K (possibly useful in case we ever have profiles that
store K first).
diff --git a/lcms2mt/src/cmsintrp.c b/lcms2mt/src/cmsintrp.c
index d1fe0b2..f4f22be 100644
--- a/lcms2mt/src/cmsintrp.c
+++ b/lcms2mt/src/cmsintrp.c
@@ -846,7 +846,7 @@ void TetrahedralInterp16(cmsContext ContextID, register const cmsUInt16Number In
}
-/* Hyper-Pentahedral Interpolation */
+/* Pentachoronal Interpolation */
static CMS_NO_SANITIZE
void Eval4Inputs(cmsContext ContextID, register const cmsUInt16Number Input[],
register cmsUInt16Number Output[],
@@ -895,69 +895,81 @@ void Eval4Inputs(cmsContext ContextID, register const cmsUInt16Number Input[],
LutTable = (cmsUInt16Number*) p16 -> Table;
LutTable += K0 + X0 + Y0 + Z0;
- which = (ry > rx ? 1 : 0) +
- (rz > rx ? 2 : 0) +
- (rk > rx ? 4 : 0) +
- (rz > ry ? 8 : 0) +
- (rk > ry ? 16 : 0) +
- (rk > rz ? 32 : 0);
- /* This gives us 24 possible cases:
- * which Tetrahedral corners
- * 0x00 rx >= ry >= rz >= rk (0,0,0,0) (1,0,0,0) (1,1,0,0) (1,1,1,0) (1,1,1,1)
- * 0x01 ry > rx >= rz >= rk (0,0,0,0) (0,1,0,0) (1,1,0,0) (1,1,1,0) (1,1,1,1)
- * 0x03 ry >= rz > rx >= rk (0,0,0,0) (0,1,0,0) (0,1,1,0) (1,1,1,0) (1,1,1,1)
- * 0x07 ry >= rz >= rk > rx (0,0,0,0) (0,1,0,0) (0,1,1,0) (0,1,1,1) (1,1,1,1)
- * 0x08 rx >= rz > ry >= rk (0,0,0,0) (1,0,0,0) (1,0,1,0) (1,1,1,0) (1,1,1,1)
- * 0x0a rz > rx >= ry >= rk (0,0,0,0) (0,0,1,0) (1,0,1,0) (1,1,1,0) (1,1,1,1)
- * 0x0b rz > ry > rx >= rk (0,0,0,0) (0,0,1,0) (0,1,1,0) (1,1,1,0) (1,1,1,1)
- * 0x0f rz > ry >= rk > rx (0,0,0,0) (0,0,1,0) (0,1,1,0) (0,1,1,1) (1,1,1,1)
- * 0x18 rx >= rz >= rk > ry (0,0,0,0) (1,0,0,0) (1,0,1,0) (1,0,1,1) (1,1,1,1)
- * 0x1a rz > rx >= rk > ry (0,0,0,0) (0,0,1,0) (1,0,1,0) (1,0,1,1) (1,1,1,1)
- * 0x1e rz >= rk > rx >= ry (0,0,0,0) (0,0,1,0) (0,0,1,1) (1,0,1,1) (1,1,1,1)
- * 0x1f rz >= rk > ry > rx (0,0,0,0) (0,0,1,0) (0,0,1,1) (0,1,1,1) (1,1,1,1)
- * 0x20 rx >= ry >= rk > rz (0,0,0,0) (1,0,0,0) (1,1,0,0) (1,1,0,1) (1,1,1,1)
- * 0x21 ry > rx >= rk > rz (0,0,0,0) (0,1,0,0) (1,1,0,0) (1,1,0,1) (1,1,1,1)
- * 0x25 ry >= rk > rx >= rz (0,0,0,0) (0,1,0,0) (0,1,0,1) (1,1,0,1) (1,1,1,1)
- * 0x27 ry >= rk > rz > rx (0,0,0,0) (0,1,0,0) (0,1,0,1) (0,1,1,1) (1,1,1,1)
- * 0x30 rx >= rk > ry >= rz (0,0,0,0) (1,0,0,0) (1,0,0,1) (1,1,0,1) (1,1,1,1)
- * 0x34 rk > rx >= ry >= rz (0,0,0,0) (0,0,0,1) (1,0,0,1) (1,1,0,1) (1,1,1,1)
- * 0x35 rk > ry > rx >= rz (0,0,0,0) (0,0,0,1) (0,1,0,1) (1,1,0,1) (1,1,1,1)
- * 0x37 rk > ry >= rz > rx (0,0,0,0) (0,0,0,1) (0,1,0,1) (0,1,1,1) (1,1,1,1)
- * 0x38 rx >= rk > rz > ry (0,0,0,0) (1,0,0,0) (1,0,0,1) (1,0,1,1) (1,1,1,1)
- * 0x3c rk > rx >= rz > ry (0,0,0,0) (0,0,0,1) (1,0,0,1) (1,0,1,1) (1,1,1,1)
- * 0x3e rk > rz > rx >= ry (0,0,0,0) (0,0,0,1) (0,0,1,1) (1,0,1,1) (1,1,1,1)
- * 0x3f rk > rz > ry > rx (0,0,0,0) (0,0,0,1) (0,0,1,1) (0,1,1,1) (1,1,1,1)
- */
-
+ /* We carefully choose the following tests, a) cos these
+ * work nicely in SSE (see CAL), and b) because, as well
+ * as the standard 24 pentachorons, we get some useful
+ * special cases. */
+ which = (rx > ry ? 1 : 0) +
+ (ry > rz ? 2 : 0) +
+ (rz > rk ? 4 : 0) +
+ (rk > rx ? 8 : 0) +
+ (rz > rx ? 16 : 0) +
+ (rk > ry ? 32 : 0);
+
o4 = X1+Y1+Z1+K1;
switch(which)
{
- default: /* Never happens, but stops the compiler complaining of uninitialised vars */
- case 0x00: o1 = X1; o2 = Y1; o3 = Z1; m1 = rx; m2 = ry; m3 = rz; m4 = rk; break;
- case 0x01: o1 = Y1; o2 = X1; o3 = Z1; m1 = ry; m2 = rx; m3 = rz; m4 = rk; break;
- case 0x03: o1 = Y1; o2 = Z1; o3 = X1; m1 = ry; m2 = rz; m3 = rx; m4 = rk; break;
- case 0x07: o1 = Y1; o2 = Z1; o3 = K1; m1 = ry; m2 = rz; m3 = rk; m4 = rx; break;
- case 0x08: o1 = X1; o2 = Z1; o3 = Y1; m1 = rx; m2 = rz; m3 = ry; m4 = rk; break;
- case 0x0a: o1 = Z1; o2 = X1; o3 = Y1; m1 = rz; m2 = rx; m3 = ry; m4 = rk; break;
- case 0x0b: o1 = Z1; o2 = Y1; o3 = X1; m1 = rz; m2 = ry; m3 = rx; m4 = rk; break;
- case 0x0f: o1 = Z1; o2 = Y1; o3 = K1; m1 = rz; m2 = ry; m3 = rk; m4 = rx; break;
- case 0x18: o1 = X1; o2 = Z1; o3 = K1; m1 = rx; m2 = rz; m3 = rk; m4 = ry; break;
- case 0x1a: o1 = Z1; o2 = X1; o3 = K1; m1 = rz; m2 = rx; m3 = rk; m4 = ry; break;
- case 0x1e: o1 = Z1; o2 = K1; o3 = X1; m1 = rz; m2 = rk; m3 = rx; m4 = ry; break;
- case 0x1f: o1 = Z1; o2 = K1; o3 = Y1; m1 = rz; m2 = rk; m3 = ry; m4 = rx; break;
- case 0x20: o1 = X1; o2 = Y1; o3 = K1; m1 = rx; m2 = ry; m3 = rk; m4 = rz; break;
- case 0x21: o1 = Y1; o2 = X1; o3 = K1; m1 = ry; m2 = rx; m3 = rk; m4 = rz; break;
- case 0x25: o1 = Y1; o2 = K1; o3 = X1; m1 = ry; m2 = rk; m3 = rx; m4 = rz; break;
- case 0x27: o1 = Y1; o2 = K1; o3 = Z1; m1 = ry; m2 = rk; m3 = rz; m4 = rx; break;
- case 0x30: o1 = X1; o2 = K1; o3 = Y1; m1 = rx; m2 = rk; m3 = ry; m4 = rz; break;
- case 0x34: o1 = K1; o2 = X1; o3 = Y1; m1 = rk; m2 = rx; m3 = ry; m4 = rz; break;
- case 0x35: o1 = K1; o2 = Y1; o3 = X1; m1 = rk; m2 = ry; m3 = rx; m4 = rz; break;
- case 0x37: o1 = K1; o2 = Y1; o3 = Z1; m1 = rk; m2 = ry; m3 = rz; m4 = rx; break;
- case 0x38: o1 = X1; o2 = K1; o3 = Z1; m1 = rx; m2 = rk; m3 = rz; m4 = ry; break;
- case 0x3c: o1 = K1; o2 = X1; o3 = Z1; m1 = rk; m2 = rx; m3 = rz; m4 = ry; break;
- case 0x3e: o1 = K1; o2 = Z1; o3 = X1; m1 = rk; m2 = rz; m3 = rx; m4 = ry; break;
- case 0x3f: o1 = K1; o2 = Z1; o3 = Y1; m1 = rk; m2 = rz; m3 = ry; m4 = rx; break;
+ default: /* Never happens, but stops the compiler complaining of uninitialised vars */
+ case 0x00: /* x == y == z == k - special case */
+ m1 = rx; goto one_lerp;
+ case 0x01: /* x > k == z == y - special case */
+ o1 = X1; m1 = rx; m2 = ry; goto two_lerps;
+ case 0x18: /* y == z == k > x - special case */
+ o1 = Y1+Z1+K1; m1 = ry; m2 = rx; goto two_lerps;
+ case 0x04: /* z == y == x > k - special case */
+ o1 = X1+Y1+Z1; m1 = ry; m2 = rk; goto two_lerps;
+ case 0x28: /* k > z == y == x - special case */
+ o1 = K1; m1 = rk; m2 = ry; goto two_lerps;
+ case 0x02: /* y >= x >= k >= z */
+ o1 = Y1; o2 = X1; o3 = K1; m1 = ry; m2 = rx; m3 = rk; m4 = rz; break;
+ case 0x03: /* x > y >= k >= z */
+ o1 = X1; o2 = Y1; o3 = K1; m1 = rx; m2 = ry; m3 = rk; m4 = rz; break;
+ case 0x05: /* x >= z >= y >= k */
+ o1 = X1; o2 = Z1; o3 = Y1; m1 = rx; m2 = rz; m3 = ry; m4 = rk; break;
+ case 0x06: /* y >= x >= z > k */
+ o1 = Y1; o2 = X1; o3 = Z1; m1 = ry; m2 = rx; m3 = rz; m4 = rk; break;
+ case 0x07: /* x > y > z > k */
+ o1 = X1; o2 = Y1; o3 = Z1; m1 = rx; m2 = ry; m3 = rz; m4 = rk; break;
+ case 0x0a: /* y >= k > x >= z */
+ o1 = Y1; o2 = K1; o3 = X1; m1 = ry; m2 = rk; m3 = rx; m4 = rz; break;
+ case 0x14: /* z >= y >= x >= k */
+ o1 = Z1; o2 = Y1; o3 = X1; m1 = rz; m2 = ry; m3 = rx; m4 = rk; break;
+ case 0x15: /* z > x >= y >= k */
+ o1 = Z1; o2 = X1; o3 = Y1; m1 = rz; m2 = rx; m3 = ry; m4 = rk; break;
+ case 0x16: /* y >= z > x >= k */
+ o1 = Y1; o2 = Z1; o3 = X1; m1 = ry; m2 = rz; m3 = rx; m4 = rk; break;
+ case 0x1a: /* y >= k >= z > x */
+ o1 = Y1; o2 = K1; o3 = Z1; m1 = ry; m2 = rk; m3 = rz; m4 = rx; break;
+ case 0x1c: /* z >= y >= k > x */
+ o1 = Z1; o2 = Y1; o3 = K1; m1 = rz; m2 = ry; m3 = rk; m4 = rx; break;
+ case 0x1e: /* y > z > k > x */
+ o1 = Y1; o2 = Z1; o3 = K1; m1 = ry; m2 = rz; m3 = rk; m4 = rx; break;
+ case 0x21: /* x >= k >= z >= y */
+ o1 = X1; o2 = K1; o3 = Z1; m1 = rx; m2 = rk; m3 = rz; m4 = ry; break;
+ case 0x23: /* x >= k > y > z */
+ o1 = X1; o2 = K1; o3 = Y1; m1 = rx; m2 = rk; m3 = ry; m4 = rz; break;
+ case 0x25: /* x >= z > k > y */
+ o1 = X1; o2 = Z1; o3 = K1; m1 = rx; m2 = rz; m3 = rk; m4 = ry; break;
+ case 0x29: /* k > x >= z >= y */
+ o1 = K1; o2 = X1; o3 = Z1; m1 = rk; m2 = rx; m3 = rz; m4 = ry; break;
+ case 0x2a: /* k > y >= x >= z */
+ o1 = K1; o2 = Y1; o3 = X1; m1 = rk; m2 = ry; m3 = rx; m4 = rz; break;
+ case 0x2b: /* k > x > y > z */
+ o1 = K1; o2 = X1; o3 = Y1; m1 = rk; m2 = rx; m3 = ry; m4 = rz; break;
+ case 0x35: /* z > x >= k > y */
+ o1 = Z1; o2 = X1; o3 = K1; m1 = rz; m2 = rx; m3 = rk; m4 = ry; break;
+ case 0x38: /* k >= z >= y >= x */
+ o1 = K1; o2 = Z1; o3 = Y1; m1 = rk; m2 = rz; m3 = ry; m4 = rx; break;
+ case 0x39: /* k >= z > x > y */
+ o1 = K1; o2 = Z1; o3 = X1; m1 = rk; m2 = rz; m3 = rx; m4 = ry; break;
+ case 0x3a: /* k > y > z > x */
+ o1 = K1; o2 = Y1; o3 = Z1; m1 = rk; m2 = ry; m3 = rz; m4 = rx; break;
+ case 0x3c: /* z > k > y >= x */
+ o1 = Z1; o2 = K1; o3 = Y1; m1 = rz; m2 = rk; m3 = ry; m4 = rx; break;
+ case 0x3d: /* z > k > x > y */
+ o1 = Z1; o2 = K1; o3 = X1; m1 = rz; m2 = rk; m3 = rx; m4 = ry; break;
}
+ assert(m1 >= m2 && m2 >= m3 && m3 >= m4);
o2 += o1;
o3 += o2;
for (OutChan=p16 -> nOutputs; OutChan != 0; OutChan--) {
@@ -974,6 +986,33 @@ void Eval4Inputs(cmsContext ContextID, register const cmsUInt16Number Input[],
*Out++ = (cmsUInt16Number)(c0 + ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest)));
}
+ return;
+
+two_lerps:
+ assert(m1 >= m2);
+ for (OutChan=p16 -> nOutputs; OutChan != 0; OutChan--) {
+ c1 = LutTable[o1];
+ c2 = LutTable[o4] - c1;
+ c0 = *LutTable++;
+ c1 -= c0;
+
+ Rest = c1 * m1 + c2 * m2;
+
+ *Out++ = (cmsUInt16Number)(c0 + ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest)));
+ }
+ return;
+
+one_lerp:
+ for (OutChan=p16 -> nOutputs; OutChan != 0; OutChan--) {
+ c1 = LutTable[o4];
+ c0 = *LutTable++;
+ c1 -= c0;
+
+ Rest = c1 * m1;
+
+ *Out++ = (cmsUInt16Number)(c0 + ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest)));
+ }
+ return;
}
static
----------------------------------------------------------------------
commit 3f46434c0fe3707f53a825f39fa1bab8c0875c03
Author: Robin Watts <[email protected]>
Date: Fri Sep 6 17:10:22 2019 +0100
Update CAL initialisation to register second lcms2mt plugin.
The first plugin deals with transformations. The second deals
with interpolation.
diff --git a/base/gsicc_lcms2mt.c b/base/gsicc_lcms2mt.c
index ff128ee..1748b16 100644
--- a/base/gsicc_lcms2mt.c
+++ b/base/gsicc_lcms2mt.c
@@ -877,6 +877,7 @@ gscms_create(gs_memory_t *memory)
#ifdef WITH_CAL
cmsPlugin(ctx, cal_cms_extensions());
+ cmsPlugin(ctx, cal_cms_extensions2());
#endif
cmsSetLogErrorHandler(ctx, gscms_error);
Summary of changes:
base/gsicc_lcms2mt.c | 1 +
lcms2mt/src/cmsintrp.c | 698 ++++++++++++++++++++++++-------------------------
2 files changed, 349 insertions(+), 350 deletions(-)