< prev index next >

src/java.desktop/share/native/liblcms/cmsintrp.c

Print this page




  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 // This file is available under and governed by the GNU General Public
  26 // License version 2 only, as published by the Free Software Foundation.
  27 // However, the following notice accompanied the original version of this
  28 // file:
  29 //
  30 //---------------------------------------------------------------------------------
  31 //
  32 //  Little Color Management System
  33 //  Copyright (c) 1998-2017 Marti Maria Saguer
  34 //
  35 // Permission is hereby granted, free of charge, to any person obtaining
  36 // a copy of this software and associated documentation files (the "Software"),
  37 // to deal in the Software without restriction, including without limitation
  38 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  39 // and/or sell copies of the Software, and to permit persons to whom the Software
  40 // is furnished to do so, subject to the following conditions:
  41 //
  42 // The above copyright notice and this permission notice shall be included in
  43 // all copies or substantial portions of the Software.
  44 //
  45 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  46 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  47 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  48 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  49 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  50 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  51 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  52 //
  53 //---------------------------------------------------------------------------------


 193     int i;
 194     cmsUInt32Number Samples[MAX_INPUT_DIMENSIONS];
 195 
 196     // Fill the auxiliary array
 197     for (i=0; i < MAX_INPUT_DIMENSIONS; i++)
 198         Samples[i] = nSamples;
 199 
 200     // Call the extended function
 201     return _cmsComputeInterpParamsEx(ContextID, Samples, InputChan, OutputChan, Table, dwFlags);
 202 }
 203 
 204 
 205 // Free all associated memory
 206 void CMSEXPORT _cmsFreeInterpParams(cmsInterpParams* p)
 207 {
 208     if (p != NULL) _cmsFree(p ->ContextID, p);
 209 }
 210 
 211 
 212 // Inline fixed point interpolation
 213 cmsINLINE cmsUInt16Number LinearInterp(cmsS15Fixed16Number a, cmsS15Fixed16Number l, cmsS15Fixed16Number h)
 214 {
 215     cmsUInt32Number dif = (cmsUInt32Number) (h - l) * a + 0x8000;
 216     dif = (dif >> 16) + l;
 217     return (cmsUInt16Number) (dif);
 218 }
 219 
 220 
 221 //  Linear interpolation (Fixed-point optimized)
 222 static
 223 void LinLerp1D(register const cmsUInt16Number Value[],
 224                register cmsUInt16Number Output[],
 225                register const cmsInterpParams* p)
 226 {
 227     cmsUInt16Number y1, y0;
 228     int cell0, rest;
 229     int val3;
 230     const cmsUInt16Number* LutTable = (cmsUInt16Number*) p ->Table;
 231 
 232     // if last value...
 233     if (Value[0] == 0xffff) {
 234 
 235         Output[0] = LutTable[p -> Domain[0]];
 236         return;
 237     }
 238 
 239     val3 = p -> Domain[0] * Value[0];

 240     val3 = _cmsToFixedDomain(val3);    // To fixed 15.16
 241 
 242     cell0 = FIXED_TO_INT(val3);             // Cell is 16 MSB bits
 243     rest  = FIXED_REST_TO_INT(val3);        // Rest is 16 LSB bits
 244 
 245     y0 = LutTable[cell0];
 246     y1 = LutTable[cell0+1];
 247 
 248 
 249     Output[0] = LinearInterp(rest, y0, y1);

 250 }
 251 
 252 // To prevent out of bounds indexing
 253 cmsINLINE cmsFloat32Number fclamp(cmsFloat32Number v)
 254 {
 255     return ((v < 1.0e-9f) || isnan(v)) ? 0.0f : (v > 1.0f ? 1.0f : v);
 256 }
 257 
 258 // Floating-point version of 1D interpolation
 259 static
 260 void LinLerp1Dfloat(const cmsFloat32Number Value[],
 261                     cmsFloat32Number Output[],
 262                     const cmsInterpParams* p)
 263 {
 264        cmsFloat32Number y1, y0;
 265        cmsFloat32Number val2, rest;
 266        int cell0, cell1;
 267        const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table;
 268 
 269        val2 = fclamp(Value[0]);
 270 
 271        // if last value...
 272        if (val2 == 1.0) {
 273            Output[0] = LutTable[p -> Domain[0]];
 274            return;
 275        }



 276 
 277        val2 *= p -> Domain[0];
 278 
 279        cell0 = (int) floor(val2);
 280        cell1 = (int) ceil(val2);
 281 
 282        // Rest is 16 LSB bits
 283        rest = val2 - cell0;
 284 
 285        y0 = LutTable[cell0] ;
 286        y1 = LutTable[cell1] ;
 287 
 288        Output[0] = y0 + (y1 - y0) * rest;

 289 }
 290 
 291 
 292 
 293 // Eval gray LUT having only one input channel
 294 static
 295 void Eval1Input(register const cmsUInt16Number Input[],
 296                 register cmsUInt16Number Output[],
 297                 register const cmsInterpParams* p16)
 298 {
 299        cmsS15Fixed16Number fk;
 300        cmsS15Fixed16Number k0, k1, rk, K0, K1;
 301        int v;
 302        cmsUInt32Number OutChan;
 303        const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
 304 
 305        v = Input[0] * p16 -> Domain[0];
 306        fk = _cmsToFixedDomain(v);
 307 
 308        k0 = FIXED_TO_INT(fk);
 309        rk = (cmsUInt16Number) FIXED_REST_TO_INT(fk);
 310 
 311        k1 = k0 + (Input[0] != 0xFFFFU ? 1 : 0);
 312 
 313        K0 = p16 -> opta[0] * k0;
 314        K1 = p16 -> opta[0] * k1;
 315 
 316        for (OutChan=0; OutChan < p16->nOutputs; OutChan++) {
 317 


 320 }
 321 
 322 
 323 
 324 // Eval gray LUT having only one input channel
 325 static
 326 void Eval1InputFloat(const cmsFloat32Number Value[],
 327                      cmsFloat32Number Output[],
 328                      const cmsInterpParams* p)
 329 {
 330     cmsFloat32Number y1, y0;
 331     cmsFloat32Number val2, rest;
 332     int cell0, cell1;
 333     cmsUInt32Number OutChan;
 334     const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table;
 335 
 336     val2 = fclamp(Value[0]);
 337 
 338         // if last value...
 339        if (val2 == 1.0) {
 340            Output[0] = LutTable[p -> Domain[0]];
 341            return;
 342        }
 343 
 344        val2 *= p -> Domain[0];
 345 
 346        cell0 = (int) floor(val2);
 347        cell1 = (int) ceil(val2);








 348 
 349        // Rest is 16 LSB bits
 350        rest = val2 - cell0;
 351 
 352        cell0 *= p -> opta[0];
 353        cell1 *= p -> opta[0];
 354 
 355        for (OutChan=0; OutChan < p->nOutputs; OutChan++) {
 356 
 357             y0 = LutTable[cell0 + OutChan] ;
 358             y1 = LutTable[cell1 + OutChan] ;
 359 
 360             Output[OutChan] = y0 + (y1 - y0) * rest;
 361        }

 362 }
 363 
 364 // Bilinear interpolation (16 bits) - cmsFloat32Number version
 365 static
 366 void BilinearInterpFloat(const cmsFloat32Number Input[],
 367                          cmsFloat32Number Output[],
 368                          const cmsInterpParams* p)
 369 
 370 {
 371 #   define LERP(a,l,h)    (cmsFloat32Number) ((l)+(((h)-(l))*(a)))
 372 #   define DENS(i,j)      (LutTable[(i)+(j)+OutChan])
 373 
 374     const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table;
 375     cmsFloat32Number      px, py;
 376     int        x0, y0,
 377                X0, Y0, X1, Y1;
 378     int        TotalOut, OutChan;
 379     cmsFloat32Number      fx, fy,
 380         d00, d01, d10, d11,
 381         dx0, dx1,


 398 
 399         d00 = DENS(X0, Y0);
 400         d01 = DENS(X0, Y1);
 401         d10 = DENS(X1, Y0);
 402         d11 = DENS(X1, Y1);
 403 
 404         dx0 = LERP(fx, d00, d10);
 405         dx1 = LERP(fx, d01, d11);
 406 
 407         dxy = LERP(fy, dx0, dx1);
 408 
 409         Output[OutChan] = dxy;
 410     }
 411 
 412 
 413 #   undef LERP
 414 #   undef DENS
 415 }
 416 
 417 // Bilinear interpolation (16 bits) - optimized version
 418 static
 419 void BilinearInterp16(register const cmsUInt16Number Input[],
 420                       register cmsUInt16Number Output[],
 421                       register const cmsInterpParams* p)
 422 
 423 {
 424 #define DENS(i,j) (LutTable[(i)+(j)+OutChan])
 425 #define LERP(a,l,h)     (cmsUInt16Number) (l + ROUND_FIXED_TO_INT(((h-l)*a)))
 426 
 427            const cmsUInt16Number* LutTable = (cmsUInt16Number*) p ->Table;
 428            int        OutChan, TotalOut;
 429            cmsS15Fixed16Number    fx, fy;
 430   register int        rx, ry;
 431            int        x0, y0;
 432   register int        X0, X1, Y0, Y1;
 433            int        d00, d01, d10, d11,
 434                       dx0, dx1,
 435                       dxy;
 436 
 437     TotalOut   = p -> nOutputs;
 438 
 439     fx = _cmsToFixedDomain((int) Input[0] * p -> Domain[0]);
 440     x0  = FIXED_TO_INT(fx);
 441     rx  = FIXED_REST_TO_INT(fx);    // Rest in 0..1.0 domain
 442 
 443 
 444     fy = _cmsToFixedDomain((int) Input[1] * p -> Domain[1]);
 445     y0  = FIXED_TO_INT(fy);
 446     ry  = FIXED_REST_TO_INT(fy);
 447 
 448 
 449     X0 = p -> opta[1] * x0;
 450     X1 = X0 + (Input[0] == 0xFFFFU ? 0 : p->opta[1]);
 451 
 452     Y0 = p -> opta[0] * y0;


 529 
 530         dx00 = LERP(fx, d000, d100);
 531         dx01 = LERP(fx, d001, d101);
 532         dx10 = LERP(fx, d010, d110);
 533         dx11 = LERP(fx, d011, d111);
 534 
 535         dxy0 = LERP(fy, dx00, dx10);
 536         dxy1 = LERP(fy, dx01, dx11);
 537 
 538         dxyz = LERP(fz, dxy0, dxy1);
 539 
 540         Output[OutChan] = dxyz;
 541     }
 542 
 543 
 544 #   undef LERP
 545 #   undef DENS
 546 }
 547 
 548 // Trilinear interpolation (16 bits) - optimized version
 549 static
 550 void TrilinearInterp16(register const cmsUInt16Number Input[],
 551                        register cmsUInt16Number Output[],
 552                        register const cmsInterpParams* p)
 553 
 554 {
 555 #define DENS(i,j,k) (LutTable[(i)+(j)+(k)+OutChan])
 556 #define LERP(a,l,h)     (cmsUInt16Number) (l + ROUND_FIXED_TO_INT(((h-l)*a)))
 557 
 558            const cmsUInt16Number* LutTable = (cmsUInt16Number*) p ->Table;
 559            int        OutChan, TotalOut;
 560            cmsS15Fixed16Number    fx, fy, fz;
 561   register int        rx, ry, rz;
 562            int        x0, y0, z0;
 563   register int        X0, X1, Y0, Y1, Z0, Z1;
 564            int        d000, d001, d010, d011,
 565                       d100, d101, d110, d111,
 566                       dx00, dx01, dx10, dx11,
 567                       dxy0, dxy1, dxyz;
 568 
 569     TotalOut   = p -> nOutputs;
 570 
 571     fx = _cmsToFixedDomain((int) Input[0] * p -> Domain[0]);
 572     x0  = FIXED_TO_INT(fx);
 573     rx  = FIXED_REST_TO_INT(fx);    // Rest in 0..1.0 domain
 574 
 575 
 576     fy = _cmsToFixedDomain((int) Input[1] * p -> Domain[1]);
 577     y0  = FIXED_TO_INT(fy);
 578     ry  = FIXED_REST_TO_INT(fy);
 579 
 580     fz = _cmsToFixedDomain((int) Input[2] * p -> Domain[2]);
 581     z0 = FIXED_TO_INT(fz);
 582     rz = FIXED_REST_TO_INT(fz);
 583 


 709 
 710                                 c1 = DENS(X1, Y1, Z1) - DENS(X0, Y1, Z1);
 711                                 c2 = DENS(X0, Y1, Z1) - DENS(X0, Y0, Z1);
 712                                 c3 = DENS(X0, Y0, Z1) - c0;
 713 
 714                             }
 715                             else  {
 716                                 c1 = c2 = c3 = 0;
 717                             }
 718 
 719        Output[OutChan] = c0 + c1 * rx + c2 * ry + c3 * rz;
 720        }
 721 
 722 }
 723 
 724 #undef DENS
 725 
 726 
 727 
 728 
 729 static
 730 void TetrahedralInterp16(register const cmsUInt16Number Input[],
 731                          register cmsUInt16Number Output[],
 732                          register const cmsInterpParams* p)
 733 {
 734     const cmsUInt16Number* LutTable = (cmsUInt16Number*) p -> Table;
 735     cmsS15Fixed16Number fx, fy, fz;
 736     cmsS15Fixed16Number rx, ry, rz;
 737     int x0, y0, z0;
 738     cmsS15Fixed16Number c0, c1, c2, c3, Rest;
 739     cmsS15Fixed16Number X0, X1, Y0, Y1, Z0, Z1;
 740     cmsUInt32Number TotalOut = p -> nOutputs;
 741 
 742     fx = _cmsToFixedDomain((int) Input[0] * p -> Domain[0]);
 743     fy = _cmsToFixedDomain((int) Input[1] * p -> Domain[1]);
 744     fz = _cmsToFixedDomain((int) Input[2] * p -> Domain[2]);
 745 
 746     x0 = FIXED_TO_INT(fx);
 747     y0 = FIXED_TO_INT(fy);
 748     z0 = FIXED_TO_INT(fz);
 749 
 750     rx = FIXED_REST_TO_INT(fx);
 751     ry = FIXED_REST_TO_INT(fy);
 752     rz = FIXED_REST_TO_INT(fz);


 843         } else {
 844             Y1 += Z1;
 845             X1 += Y1;
 846             for (; TotalOut; TotalOut--) {
 847                 c1 = LutTable[X1];
 848                 c2 = LutTable[Y1];
 849                 c3 = LutTable[Z1];
 850                 c0 = *LutTable++;
 851                 c1 -= c2;
 852                 c2 -= c3;
 853                 c3 -= c0;
 854                 Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001;
 855                 *Output++ = (cmsUInt16Number) c0 + ((Rest + (Rest>>16))>>16);
 856             }
 857         }
 858     }
 859 }
 860 
 861 
 862 #define DENS(i,j,k) (LutTable[(i)+(j)+(k)+OutChan])
 863 static
 864 void Eval4Inputs(register const cmsUInt16Number Input[],
 865                      register cmsUInt16Number Output[],
 866                      register const cmsInterpParams* p16)
 867 {
 868     const cmsUInt16Number* LutTable;
 869     cmsS15Fixed16Number fk;
 870     cmsS15Fixed16Number k0, rk;
 871     int K0, K1;
 872     cmsS15Fixed16Number    fx, fy, fz;
 873     cmsS15Fixed16Number    rx, ry, rz;
 874     int                    x0, y0, z0;
 875     cmsS15Fixed16Number    X0, X1, Y0, Y1, Z0, Z1;
 876     cmsUInt32Number i;
 877     cmsS15Fixed16Number    c0, c1, c2, c3, Rest;
 878     cmsUInt32Number        OutChan;
 879     cmsUInt16Number        Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
 880 
 881 
 882     fk  = _cmsToFixedDomain((int) Input[0] * p16 -> Domain[0]);
 883     fx  = _cmsToFixedDomain((int) Input[1] * p16 -> Domain[1]);
 884     fy  = _cmsToFixedDomain((int) Input[2] * p16 -> Domain[2]);
 885     fz  = _cmsToFixedDomain((int) Input[3] * p16 -> Domain[3]);
 886 


1072 
1073        T = LutTable + K0;
1074        p1.Table = T;
1075 
1076        TetrahedralInterpFloat(Input + 1,  Tmp1, &p1);
1077 
1078        T = LutTable + K1;
1079        p1.Table = T;
1080        TetrahedralInterpFloat(Input + 1,  Tmp2, &p1);
1081 
1082        for (i=0; i < p -> nOutputs; i++)
1083        {
1084               cmsFloat32Number y0 = Tmp1[i];
1085               cmsFloat32Number y1 = Tmp2[i];
1086 
1087               Output[i] = y0 + (y1 - y0) * rest;
1088        }
1089 }
1090 
1091 
1092 static
1093 void Eval5Inputs(register const cmsUInt16Number Input[],
1094                  register cmsUInt16Number Output[],
1095 
1096                  register const cmsInterpParams* p16)
1097 {
1098        const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
1099        cmsS15Fixed16Number fk;
1100        cmsS15Fixed16Number k0, rk;
1101        int K0, K1;
1102        const cmsUInt16Number* T;
1103        cmsUInt32Number i;
1104        cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
1105        cmsInterpParams p1;
1106 
1107 
1108        fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);
1109        k0 = FIXED_TO_INT(fk);
1110        rk = FIXED_REST_TO_INT(fk);
1111 
1112        K0 = p16 -> opta[4] * k0;
1113        K1 = p16 -> opta[4] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));
1114 
1115        p1 = *p16;
1116        memmove(&p1.Domain[0], &p16 ->Domain[1], 4*sizeof(cmsUInt32Number));


1161        p1.Table = T;
1162 
1163        Eval4InputsFloat(Input + 1,  Tmp1, &p1);
1164 
1165        T = LutTable + K1;
1166        p1.Table = T;
1167 
1168        Eval4InputsFloat(Input + 1,  Tmp2, &p1);
1169 
1170        for (i=0; i < p -> nOutputs; i++) {
1171 
1172               cmsFloat32Number y0 = Tmp1[i];
1173               cmsFloat32Number y1 = Tmp2[i];
1174 
1175               Output[i] = y0 + (y1 - y0) * rest;
1176        }
1177 }
1178 
1179 
1180 
1181 static
1182 void Eval6Inputs(register const cmsUInt16Number Input[],
1183                  register cmsUInt16Number Output[],
1184                  register const cmsInterpParams* p16)
1185 {
1186        const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
1187        cmsS15Fixed16Number fk;
1188        cmsS15Fixed16Number k0, rk;
1189        int K0, K1;
1190        const cmsUInt16Number* T;
1191        cmsUInt32Number i;
1192        cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
1193        cmsInterpParams p1;
1194 
1195        fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);
1196        k0 = FIXED_TO_INT(fk);
1197        rk = FIXED_REST_TO_INT(fk);
1198 
1199        K0 = p16 -> opta[5] * k0;
1200        K1 = p16 -> opta[5] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));
1201 
1202        p1 = *p16;
1203        memmove(&p1.Domain[0], &p16 ->Domain[1], 5*sizeof(cmsUInt32Number));
1204 


1247        T = LutTable + K0;
1248        p1.Table = T;
1249 
1250        Eval5InputsFloat(Input + 1,  Tmp1, &p1);
1251 
1252        T = LutTable + K1;
1253        p1.Table = T;
1254 
1255        Eval5InputsFloat(Input + 1,  Tmp2, &p1);
1256 
1257        for (i=0; i < p -> nOutputs; i++) {
1258 
1259               cmsFloat32Number y0 = Tmp1[i];
1260               cmsFloat32Number y1 = Tmp2[i];
1261 
1262               Output[i] = y0 + (y1 - y0) * rest;
1263        }
1264 }
1265 
1266 
1267 static
1268 void Eval7Inputs(register const cmsUInt16Number Input[],
1269                  register cmsUInt16Number Output[],
1270                  register const cmsInterpParams* p16)
1271 {
1272        const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
1273        cmsS15Fixed16Number fk;
1274        cmsS15Fixed16Number k0, rk;
1275        int K0, K1;
1276        const cmsUInt16Number* T;
1277        cmsUInt32Number i;
1278        cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
1279        cmsInterpParams p1;
1280 
1281 
1282        fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);
1283        k0 = FIXED_TO_INT(fk);
1284        rk = FIXED_REST_TO_INT(fk);
1285 
1286        K0 = p16 -> opta[6] * k0;
1287        K1 = p16 -> opta[6] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));
1288 
1289        p1 = *p16;
1290        memmove(&p1.Domain[0], &p16 ->Domain[1], 6*sizeof(cmsUInt32Number));


1333        p1.Table = T;
1334 
1335        Eval6InputsFloat(Input + 1,  Tmp1, &p1);
1336 
1337        T = LutTable + K1;
1338        p1.Table = T;
1339 
1340        Eval6InputsFloat(Input + 1,  Tmp2, &p1);
1341 
1342 
1343        for (i=0; i < p -> nOutputs; i++) {
1344 
1345               cmsFloat32Number y0 = Tmp1[i];
1346               cmsFloat32Number y1 = Tmp2[i];
1347 
1348               Output[i] = y0 + (y1 - y0) * rest;
1349 
1350        }
1351 }
1352 
1353 static
1354 void Eval8Inputs(register const cmsUInt16Number Input[],
1355                  register cmsUInt16Number Output[],
1356                  register const cmsInterpParams* p16)
1357 {
1358        const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
1359        cmsS15Fixed16Number fk;
1360        cmsS15Fixed16Number k0, rk;
1361        int K0, K1;
1362        const cmsUInt16Number* T;
1363        cmsUInt32Number i;
1364        cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
1365        cmsInterpParams p1;
1366 
1367        fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);
1368        k0 = FIXED_TO_INT(fk);
1369        rk = FIXED_REST_TO_INT(fk);
1370 
1371        K0 = p16 -> opta[7] * k0;
1372        K1 = p16 -> opta[7] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));
1373 
1374        p1 = *p16;
1375        memmove(&p1.Domain[0], &p16 ->Domain[1], 7*sizeof(cmsUInt32Number));
1376 




  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 // This file is available under and governed by the GNU General Public
  26 // License version 2 only, as published by the Free Software Foundation.
  27 // However, the following notice accompanied the original version of this
  28 // file:
  29 //
  30 //---------------------------------------------------------------------------------
  31 //
  32 //  Little Color Management System
  33 //  Copyright (c) 1998-2020 Marti Maria Saguer
  34 //
  35 // Permission is hereby granted, free of charge, to any person obtaining
  36 // a copy of this software and associated documentation files (the "Software"),
  37 // to deal in the Software without restriction, including without limitation
  38 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  39 // and/or sell copies of the Software, and to permit persons to whom the Software
  40 // is furnished to do so, subject to the following conditions:
  41 //
  42 // The above copyright notice and this permission notice shall be included in
  43 // all copies or substantial portions of the Software.
  44 //
  45 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  46 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  47 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  48 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  49 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  50 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  51 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  52 //
  53 //---------------------------------------------------------------------------------


 193     int i;
 194     cmsUInt32Number Samples[MAX_INPUT_DIMENSIONS];
 195 
 196     // Fill the auxiliary array
 197     for (i=0; i < MAX_INPUT_DIMENSIONS; i++)
 198         Samples[i] = nSamples;
 199 
 200     // Call the extended function
 201     return _cmsComputeInterpParamsEx(ContextID, Samples, InputChan, OutputChan, Table, dwFlags);
 202 }
 203 
 204 
 205 // Free all associated memory
 206 void CMSEXPORT _cmsFreeInterpParams(cmsInterpParams* p)
 207 {
 208     if (p != NULL) _cmsFree(p ->ContextID, p);
 209 }
 210 
 211 
 212 // Inline fixed point interpolation
 213 cmsINLINE CMS_NO_SANITIZE cmsUInt16Number LinearInterp(cmsS15Fixed16Number a, cmsS15Fixed16Number l, cmsS15Fixed16Number h)
 214 {
 215     cmsUInt32Number dif = (cmsUInt32Number) (h - l) * a + 0x8000;
 216     dif = (dif >> 16) + l;
 217     return (cmsUInt16Number) (dif);
 218 }
 219 
 220 
 221 //  Linear interpolation (Fixed-point optimized)
 222 static
 223 void LinLerp1D(CMSREGISTER const cmsUInt16Number Value[],
 224                CMSREGISTER cmsUInt16Number Output[],
 225                CMSREGISTER const cmsInterpParams* p)
 226 {
 227     cmsUInt16Number y1, y0;
 228     int cell0, rest;
 229     int val3;
 230     const cmsUInt16Number* LutTable = (cmsUInt16Number*) p ->Table;
 231 
 232     // if last value...
 233     if (Value[0] == 0xffff) {
 234 
 235         Output[0] = LutTable[p -> Domain[0]];

 236     }
 237     else
 238     {
 239         val3 = p->Domain[0] * Value[0];
 240         val3 = _cmsToFixedDomain(val3);    // To fixed 15.16
 241 
 242         cell0 = FIXED_TO_INT(val3);             // Cell is 16 MSB bits
 243         rest = FIXED_REST_TO_INT(val3);        // Rest is 16 LSB bits
 244 
 245         y0 = LutTable[cell0];
 246         y1 = LutTable[cell0 + 1];

 247 
 248         Output[0] = LinearInterp(rest, y0, y1);
 249     }
 250 }
 251 
 252 // To prevent out of bounds indexing
 253 cmsINLINE cmsFloat32Number fclamp(cmsFloat32Number v)
 254 {
 255     return ((v < 1.0e-9f) || isnan(v)) ? 0.0f : (v > 1.0f ? 1.0f : v);
 256 }
 257 
 258 // Floating-point version of 1D interpolation
 259 static
 260 void LinLerp1Dfloat(const cmsFloat32Number Value[],
 261                     cmsFloat32Number Output[],
 262                     const cmsInterpParams* p)
 263 {
 264        cmsFloat32Number y1, y0;
 265        cmsFloat32Number val2, rest;
 266        int cell0, cell1;
 267        const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table;
 268 
 269        val2 = fclamp(Value[0]);
 270 
 271        // if last value...
 272        if (val2 == 1.0) {
 273            Output[0] = LutTable[p -> Domain[0]];

 274        }
 275        else
 276        {
 277            val2 *= p->Domain[0];
 278 
 279            cell0 = (int)floor(val2);
 280            cell1 = (int)ceil(val2);


 281 
 282            // Rest is 16 LSB bits
 283            rest = val2 - cell0;
 284 
 285            y0 = LutTable[cell0];
 286            y1 = LutTable[cell1];
 287 
 288            Output[0] = y0 + (y1 - y0) * rest;
 289        }
 290 }
 291 
 292 
 293 
 294 // Eval gray LUT having only one input channel
 295 static CMS_NO_SANITIZE
 296 void Eval1Input(CMSREGISTER const cmsUInt16Number Input[],
 297                 CMSREGISTER cmsUInt16Number Output[],
 298                 CMSREGISTER const cmsInterpParams* p16)
 299 {
 300        cmsS15Fixed16Number fk;
 301        cmsS15Fixed16Number k0, k1, rk, K0, K1;
 302        int v;
 303        cmsUInt32Number OutChan;
 304        const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
 305 
 306        v = Input[0] * p16 -> Domain[0];
 307        fk = _cmsToFixedDomain(v);
 308 
 309        k0 = FIXED_TO_INT(fk);
 310        rk = (cmsUInt16Number) FIXED_REST_TO_INT(fk);
 311 
 312        k1 = k0 + (Input[0] != 0xFFFFU ? 1 : 0);
 313 
 314        K0 = p16 -> opta[0] * k0;
 315        K1 = p16 -> opta[0] * k1;
 316 
 317        for (OutChan=0; OutChan < p16->nOutputs; OutChan++) {
 318 


 321 }
 322 
 323 
 324 
 325 // Eval gray LUT having only one input channel
 326 static
 327 void Eval1InputFloat(const cmsFloat32Number Value[],
 328                      cmsFloat32Number Output[],
 329                      const cmsInterpParams* p)
 330 {
 331     cmsFloat32Number y1, y0;
 332     cmsFloat32Number val2, rest;
 333     int cell0, cell1;
 334     cmsUInt32Number OutChan;
 335     const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table;
 336 
 337     val2 = fclamp(Value[0]);
 338 
 339     // if last value...
 340     if (val2 == 1.0) {



 341 
 342         y0 = LutTable[p->Domain[0]];
 343 
 344         for (OutChan = 0; OutChan < p->nOutputs; OutChan++) {
 345             Output[OutChan] = y0;
 346         }
 347     }
 348     else
 349     {
 350         val2 *= p->Domain[0];
 351 
 352         cell0 = (int)floor(val2);
 353         cell1 = (int)ceil(val2);
 354 
 355         // Rest is 16 LSB bits
 356         rest = val2 - cell0;
 357 
 358         cell0 *= p->opta[0];
 359         cell1 *= p->opta[0];
 360 
 361         for (OutChan = 0; OutChan < p->nOutputs; OutChan++) {
 362 
 363             y0 = LutTable[cell0 + OutChan];
 364             y1 = LutTable[cell1 + OutChan];
 365 
 366             Output[OutChan] = y0 + (y1 - y0) * rest;
 367         }
 368     }
 369 }
 370 
 371 // Bilinear interpolation (16 bits) - cmsFloat32Number version
 372 static
 373 void BilinearInterpFloat(const cmsFloat32Number Input[],
 374                          cmsFloat32Number Output[],
 375                          const cmsInterpParams* p)
 376 
 377 {
 378 #   define LERP(a,l,h)    (cmsFloat32Number) ((l)+(((h)-(l))*(a)))
 379 #   define DENS(i,j)      (LutTable[(i)+(j)+OutChan])
 380 
 381     const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table;
 382     cmsFloat32Number      px, py;
 383     int        x0, y0,
 384                X0, Y0, X1, Y1;
 385     int        TotalOut, OutChan;
 386     cmsFloat32Number      fx, fy,
 387         d00, d01, d10, d11,
 388         dx0, dx1,


 405 
 406         d00 = DENS(X0, Y0);
 407         d01 = DENS(X0, Y1);
 408         d10 = DENS(X1, Y0);
 409         d11 = DENS(X1, Y1);
 410 
 411         dx0 = LERP(fx, d00, d10);
 412         dx1 = LERP(fx, d01, d11);
 413 
 414         dxy = LERP(fy, dx0, dx1);
 415 
 416         Output[OutChan] = dxy;
 417     }
 418 
 419 
 420 #   undef LERP
 421 #   undef DENS
 422 }
 423 
 424 // Bilinear interpolation (16 bits) - optimized version
 425 static CMS_NO_SANITIZE
 426 void BilinearInterp16(CMSREGISTER const cmsUInt16Number Input[],
 427                       CMSREGISTER cmsUInt16Number Output[],
 428                       CMSREGISTER const cmsInterpParams* p)
 429 
 430 {
 431 #define DENS(i,j) (LutTable[(i)+(j)+OutChan])
 432 #define LERP(a,l,h)     (cmsUInt16Number) (l + ROUND_FIXED_TO_INT(((h-l)*a)))
 433 
 434            const cmsUInt16Number* LutTable = (cmsUInt16Number*) p ->Table;
 435            int        OutChan, TotalOut;
 436            cmsS15Fixed16Number    fx, fy;
 437   CMSREGISTER int        rx, ry;
 438            int        x0, y0;
 439   CMSREGISTER int        X0, X1, Y0, Y1;
 440            int        d00, d01, d10, d11,
 441                       dx0, dx1,
 442                       dxy;
 443 
 444     TotalOut   = p -> nOutputs;
 445 
 446     fx = _cmsToFixedDomain((int) Input[0] * p -> Domain[0]);
 447     x0  = FIXED_TO_INT(fx);
 448     rx  = FIXED_REST_TO_INT(fx);    // Rest in 0..1.0 domain
 449 
 450 
 451     fy = _cmsToFixedDomain((int) Input[1] * p -> Domain[1]);
 452     y0  = FIXED_TO_INT(fy);
 453     ry  = FIXED_REST_TO_INT(fy);
 454 
 455 
 456     X0 = p -> opta[1] * x0;
 457     X1 = X0 + (Input[0] == 0xFFFFU ? 0 : p->opta[1]);
 458 
 459     Y0 = p -> opta[0] * y0;


 536 
 537         dx00 = LERP(fx, d000, d100);
 538         dx01 = LERP(fx, d001, d101);
 539         dx10 = LERP(fx, d010, d110);
 540         dx11 = LERP(fx, d011, d111);
 541 
 542         dxy0 = LERP(fy, dx00, dx10);
 543         dxy1 = LERP(fy, dx01, dx11);
 544 
 545         dxyz = LERP(fz, dxy0, dxy1);
 546 
 547         Output[OutChan] = dxyz;
 548     }
 549 
 550 
 551 #   undef LERP
 552 #   undef DENS
 553 }
 554 
 555 // Trilinear interpolation (16 bits) - optimized version
 556 static CMS_NO_SANITIZE
 557 void TrilinearInterp16(CMSREGISTER const cmsUInt16Number Input[],
 558                        CMSREGISTER cmsUInt16Number Output[],
 559                        CMSREGISTER const cmsInterpParams* p)
 560 
 561 {
 562 #define DENS(i,j,k) (LutTable[(i)+(j)+(k)+OutChan])
 563 #define LERP(a,l,h)     (cmsUInt16Number) (l + ROUND_FIXED_TO_INT(((h-l)*a)))
 564 
 565            const cmsUInt16Number* LutTable = (cmsUInt16Number*) p ->Table;
 566            int        OutChan, TotalOut;
 567            cmsS15Fixed16Number    fx, fy, fz;
 568   CMSREGISTER int        rx, ry, rz;
 569            int        x0, y0, z0;
 570   CMSREGISTER int        X0, X1, Y0, Y1, Z0, Z1;
 571            int        d000, d001, d010, d011,
 572                       d100, d101, d110, d111,
 573                       dx00, dx01, dx10, dx11,
 574                       dxy0, dxy1, dxyz;
 575 
 576     TotalOut   = p -> nOutputs;
 577 
 578     fx = _cmsToFixedDomain((int) Input[0] * p -> Domain[0]);
 579     x0  = FIXED_TO_INT(fx);
 580     rx  = FIXED_REST_TO_INT(fx);    // Rest in 0..1.0 domain
 581 
 582 
 583     fy = _cmsToFixedDomain((int) Input[1] * p -> Domain[1]);
 584     y0  = FIXED_TO_INT(fy);
 585     ry  = FIXED_REST_TO_INT(fy);
 586 
 587     fz = _cmsToFixedDomain((int) Input[2] * p -> Domain[2]);
 588     z0 = FIXED_TO_INT(fz);
 589     rz = FIXED_REST_TO_INT(fz);
 590 


 716 
 717                                 c1 = DENS(X1, Y1, Z1) - DENS(X0, Y1, Z1);
 718                                 c2 = DENS(X0, Y1, Z1) - DENS(X0, Y0, Z1);
 719                                 c3 = DENS(X0, Y0, Z1) - c0;
 720 
 721                             }
 722                             else  {
 723                                 c1 = c2 = c3 = 0;
 724                             }
 725 
 726        Output[OutChan] = c0 + c1 * rx + c2 * ry + c3 * rz;
 727        }
 728 
 729 }
 730 
 731 #undef DENS
 732 
 733 
 734 
 735 
 736 static CMS_NO_SANITIZE
 737 void TetrahedralInterp16(CMSREGISTER const cmsUInt16Number Input[],
 738                          CMSREGISTER cmsUInt16Number Output[],
 739                          CMSREGISTER const cmsInterpParams* p)
 740 {
 741     const cmsUInt16Number* LutTable = (cmsUInt16Number*) p -> Table;
 742     cmsS15Fixed16Number fx, fy, fz;
 743     cmsS15Fixed16Number rx, ry, rz;
 744     int x0, y0, z0;
 745     cmsS15Fixed16Number c0, c1, c2, c3, Rest;
 746     cmsS15Fixed16Number X0, X1, Y0, Y1, Z0, Z1;
 747     cmsUInt32Number TotalOut = p -> nOutputs;
 748 
 749     fx = _cmsToFixedDomain((int) Input[0] * p -> Domain[0]);
 750     fy = _cmsToFixedDomain((int) Input[1] * p -> Domain[1]);
 751     fz = _cmsToFixedDomain((int) Input[2] * p -> Domain[2]);
 752 
 753     x0 = FIXED_TO_INT(fx);
 754     y0 = FIXED_TO_INT(fy);
 755     z0 = FIXED_TO_INT(fz);
 756 
 757     rx = FIXED_REST_TO_INT(fx);
 758     ry = FIXED_REST_TO_INT(fy);
 759     rz = FIXED_REST_TO_INT(fz);


 850         } else {
 851             Y1 += Z1;
 852             X1 += Y1;
 853             for (; TotalOut; TotalOut--) {
 854                 c1 = LutTable[X1];
 855                 c2 = LutTable[Y1];
 856                 c3 = LutTable[Z1];
 857                 c0 = *LutTable++;
 858                 c1 -= c2;
 859                 c2 -= c3;
 860                 c3 -= c0;
 861                 Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001;
 862                 *Output++ = (cmsUInt16Number) c0 + ((Rest + (Rest>>16))>>16);
 863             }
 864         }
 865     }
 866 }
 867 
 868 
 869 #define DENS(i,j,k) (LutTable[(i)+(j)+(k)+OutChan])
 870 static CMS_NO_SANITIZE
 871 void Eval4Inputs(CMSREGISTER const cmsUInt16Number Input[],
 872                      CMSREGISTER cmsUInt16Number Output[],
 873                      CMSREGISTER const cmsInterpParams* p16)
 874 {
 875     const cmsUInt16Number* LutTable;
 876     cmsS15Fixed16Number fk;
 877     cmsS15Fixed16Number k0, rk;
 878     int K0, K1;
 879     cmsS15Fixed16Number    fx, fy, fz;
 880     cmsS15Fixed16Number    rx, ry, rz;
 881     int                    x0, y0, z0;
 882     cmsS15Fixed16Number    X0, X1, Y0, Y1, Z0, Z1;
 883     cmsUInt32Number i;
 884     cmsS15Fixed16Number    c0, c1, c2, c3, Rest;
 885     cmsUInt32Number        OutChan;
 886     cmsUInt16Number        Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
 887 
 888 
 889     fk  = _cmsToFixedDomain((int) Input[0] * p16 -> Domain[0]);
 890     fx  = _cmsToFixedDomain((int) Input[1] * p16 -> Domain[1]);
 891     fy  = _cmsToFixedDomain((int) Input[2] * p16 -> Domain[2]);
 892     fz  = _cmsToFixedDomain((int) Input[3] * p16 -> Domain[3]);
 893 


1079 
1080        T = LutTable + K0;
1081        p1.Table = T;
1082 
1083        TetrahedralInterpFloat(Input + 1,  Tmp1, &p1);
1084 
1085        T = LutTable + K1;
1086        p1.Table = T;
1087        TetrahedralInterpFloat(Input + 1,  Tmp2, &p1);
1088 
1089        for (i=0; i < p -> nOutputs; i++)
1090        {
1091               cmsFloat32Number y0 = Tmp1[i];
1092               cmsFloat32Number y1 = Tmp2[i];
1093 
1094               Output[i] = y0 + (y1 - y0) * rest;
1095        }
1096 }
1097 
1098 
1099 static CMS_NO_SANITIZE
1100 void Eval5Inputs(CMSREGISTER const cmsUInt16Number Input[],
1101                  CMSREGISTER cmsUInt16Number Output[],
1102 
1103                  CMSREGISTER const cmsInterpParams* p16)
1104 {
1105        const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
1106        cmsS15Fixed16Number fk;
1107        cmsS15Fixed16Number k0, rk;
1108        int K0, K1;
1109        const cmsUInt16Number* T;
1110        cmsUInt32Number i;
1111        cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
1112        cmsInterpParams p1;
1113 
1114 
1115        fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);
1116        k0 = FIXED_TO_INT(fk);
1117        rk = FIXED_REST_TO_INT(fk);
1118 
1119        K0 = p16 -> opta[4] * k0;
1120        K1 = p16 -> opta[4] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));
1121 
1122        p1 = *p16;
1123        memmove(&p1.Domain[0], &p16 ->Domain[1], 4*sizeof(cmsUInt32Number));


1168        p1.Table = T;
1169 
1170        Eval4InputsFloat(Input + 1,  Tmp1, &p1);
1171 
1172        T = LutTable + K1;
1173        p1.Table = T;
1174 
1175        Eval4InputsFloat(Input + 1,  Tmp2, &p1);
1176 
1177        for (i=0; i < p -> nOutputs; i++) {
1178 
1179               cmsFloat32Number y0 = Tmp1[i];
1180               cmsFloat32Number y1 = Tmp2[i];
1181 
1182               Output[i] = y0 + (y1 - y0) * rest;
1183        }
1184 }
1185 
1186 
1187 
1188 static CMS_NO_SANITIZE
1189 void Eval6Inputs(CMSREGISTER const cmsUInt16Number Input[],
1190                  CMSREGISTER cmsUInt16Number Output[],
1191                  CMSREGISTER const cmsInterpParams* p16)
1192 {
1193        const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
1194        cmsS15Fixed16Number fk;
1195        cmsS15Fixed16Number k0, rk;
1196        int K0, K1;
1197        const cmsUInt16Number* T;
1198        cmsUInt32Number i;
1199        cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
1200        cmsInterpParams p1;
1201 
1202        fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);
1203        k0 = FIXED_TO_INT(fk);
1204        rk = FIXED_REST_TO_INT(fk);
1205 
1206        K0 = p16 -> opta[5] * k0;
1207        K1 = p16 -> opta[5] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));
1208 
1209        p1 = *p16;
1210        memmove(&p1.Domain[0], &p16 ->Domain[1], 5*sizeof(cmsUInt32Number));
1211 


1254        T = LutTable + K0;
1255        p1.Table = T;
1256 
1257        Eval5InputsFloat(Input + 1,  Tmp1, &p1);
1258 
1259        T = LutTable + K1;
1260        p1.Table = T;
1261 
1262        Eval5InputsFloat(Input + 1,  Tmp2, &p1);
1263 
1264        for (i=0; i < p -> nOutputs; i++) {
1265 
1266               cmsFloat32Number y0 = Tmp1[i];
1267               cmsFloat32Number y1 = Tmp2[i];
1268 
1269               Output[i] = y0 + (y1 - y0) * rest;
1270        }
1271 }
1272 
1273 
1274 static CMS_NO_SANITIZE
1275 void Eval7Inputs(CMSREGISTER const cmsUInt16Number Input[],
1276                  CMSREGISTER cmsUInt16Number Output[],
1277                  CMSREGISTER const cmsInterpParams* p16)
1278 {
1279        const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
1280        cmsS15Fixed16Number fk;
1281        cmsS15Fixed16Number k0, rk;
1282        int K0, K1;
1283        const cmsUInt16Number* T;
1284        cmsUInt32Number i;
1285        cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
1286        cmsInterpParams p1;
1287 
1288 
1289        fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);
1290        k0 = FIXED_TO_INT(fk);
1291        rk = FIXED_REST_TO_INT(fk);
1292 
1293        K0 = p16 -> opta[6] * k0;
1294        K1 = p16 -> opta[6] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));
1295 
1296        p1 = *p16;
1297        memmove(&p1.Domain[0], &p16 ->Domain[1], 6*sizeof(cmsUInt32Number));


1340        p1.Table = T;
1341 
1342        Eval6InputsFloat(Input + 1,  Tmp1, &p1);
1343 
1344        T = LutTable + K1;
1345        p1.Table = T;
1346 
1347        Eval6InputsFloat(Input + 1,  Tmp2, &p1);
1348 
1349 
1350        for (i=0; i < p -> nOutputs; i++) {
1351 
1352               cmsFloat32Number y0 = Tmp1[i];
1353               cmsFloat32Number y1 = Tmp2[i];
1354 
1355               Output[i] = y0 + (y1 - y0) * rest;
1356 
1357        }
1358 }
1359 
1360 static CMS_NO_SANITIZE
1361 void Eval8Inputs(CMSREGISTER const cmsUInt16Number Input[],
1362                  CMSREGISTER cmsUInt16Number Output[],
1363                  CMSREGISTER const cmsInterpParams* p16)
1364 {
1365        const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
1366        cmsS15Fixed16Number fk;
1367        cmsS15Fixed16Number k0, rk;
1368        int K0, K1;
1369        const cmsUInt16Number* T;
1370        cmsUInt32Number i;
1371        cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
1372        cmsInterpParams p1;
1373 
1374        fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);
1375        k0 = FIXED_TO_INT(fk);
1376        rk = FIXED_REST_TO_INT(fk);
1377 
1378        K0 = p16 -> opta[7] * k0;
1379        K1 = p16 -> opta[7] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));
1380 
1381        p1 = *p16;
1382        memmove(&p1.Domain[0], &p16 ->Domain[1], 7*sizeof(cmsUInt32Number));
1383 


< prev index next >