Bug Summary

File:jdk/src/java.desktop/share/native/liblcms/cmsintrp.c
Warning:line 1184, column 1
2nd function call argument is an uninitialized value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name cmsintrp.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base/linux -I /home/daniel/Projects/java/jdk/src/java.base/share/native/libjava -I /home/daniel/Projects/java/jdk/src/java.base/unix/native/libjava -I /home/daniel/Projects/java/jdk/src/hotspot/share/include -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix/include -D LIBC=gnu -D _GNU_SOURCE -D _REENTRANT -D _LARGEFILE64_SOURCE -D LINUX -D DEBUG -D _LITTLE_ENDIAN -D ARCH="amd64" -D amd64 -D _LP64=1 -D CMS_DONT_USE_FAST_FLOOR -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/liblcms -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/headers/java.desktop -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/awt/debug -I /home/daniel/Projects/java/jdk/src/java.desktop/unix/native/libawt/java2d -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libawt/java2d -D _FORTIFY_SOURCE=2 -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-unused-parameter -Wno-unused -Wno-format-nonliteral -Wno-type-limits -Wno-misleading-indentation -Wno-undef -Wno-unused-function -Wno-stringop-truncation -std=c99 -fdebug-compilation-dir /home/daniel/Projects/java/jdk/make -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -stack-protector 1 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /home/daniel/Projects/java/scan/2021-12-21-193737-8510-1 -x c /home/daniel/Projects/java/jdk/src/java.desktop/share/native/liblcms/cmsintrp.c
1/*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 *
4 * This code is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 only, as
6 * published by the Free Software Foundation. Oracle designates this
7 * particular file as subject to the "Classpath" exception as provided
8 * by Oracle in the LICENSE file that accompanied this code.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
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//---------------------------------------------------------------------------------
54//
55
56#include "lcms2_internal.h"
57
58// This module incorporates several interpolation routines, for 1 to 8 channels on input and
59// up to 65535 channels on output. The user may change those by using the interpolation plug-in
60
61// Some people may want to compile as C++ with all warnings on, in this case make compiler silent
62#ifdef _MSC_VER
63# if (_MSC_VER >= 1400)
64# pragma warning( disable : 4365 )
65# endif
66#endif
67
68// Interpolation routines by default
69static cmsInterpFunction DefaultInterpolatorsFactory(cmsUInt32Number nInputChannels, cmsUInt32Number nOutputChannels, cmsUInt32Number dwFlags);
70
71// This is the default factory
72_cmsInterpPluginChunkType _cmsInterpPluginChunk = { NULL((void*)0) };
73
74// The interpolation plug-in memory chunk allocator/dup
75void _cmsAllocInterpPluginChunk(struct _cmsContext_struct* ctx, const struct _cmsContext_struct* src)
76{
77 void* from;
78
79 _cmsAssert(ctx != NULL)(((ctx != ((void*)0))) ? (void) (0) : __assert_fail ("(ctx != ((void*)0))"
, "/home/daniel/Projects/java/jdk/src/java.desktop/share/native/liblcms/cmsintrp.c"
, 79, __extension__ __PRETTY_FUNCTION__))
;
80
81 if (src != NULL((void*)0)) {
82 from = src ->chunks[InterpPlugin];
83 }
84 else {
85 static _cmsInterpPluginChunkType InterpPluginChunk = { NULL((void*)0) };
86
87 from = &InterpPluginChunk;
88 }
89
90 _cmsAssert(from != NULL)(((from != ((void*)0))) ? (void) (0) : __assert_fail ("(from != ((void*)0))"
, "/home/daniel/Projects/java/jdk/src/java.desktop/share/native/liblcms/cmsintrp.c"
, 90, __extension__ __PRETTY_FUNCTION__))
;
91 ctx ->chunks[InterpPlugin] = _cmsSubAllocDup(ctx ->MemPool, from, sizeof(_cmsInterpPluginChunkType));
92}
93
94
95// Main plug-in entry
96cmsBool _cmsRegisterInterpPlugin(cmsContext ContextID, cmsPluginBase* Data)
97{
98 cmsPluginInterpolation* Plugin = (cmsPluginInterpolation*) Data;
99 _cmsInterpPluginChunkType* ptr = (_cmsInterpPluginChunkType*) _cmsContextGetClientChunk(ContextID, InterpPlugin);
100
101 if (Data == NULL((void*)0)) {
102
103 ptr ->Interpolators = NULL((void*)0);
104 return TRUE1;
105 }
106
107 // Set replacement functions
108 ptr ->Interpolators = Plugin ->InterpolatorsFactory;
109 return TRUE1;
110}
111
112
113// Set the interpolation method
114cmsBool _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p)
115{
116 _cmsInterpPluginChunkType* ptr = (_cmsInterpPluginChunkType*) _cmsContextGetClientChunk(ContextID, InterpPlugin);
117
118 p ->Interpolation.Lerp16 = NULL((void*)0);
119
120 // Invoke factory, possibly in the Plug-in
121 if (ptr ->Interpolators != NULL((void*)0))
122 p ->Interpolation = ptr->Interpolators(p -> nInputs, p ->nOutputs, p ->dwFlags);
123
124 // If unsupported by the plug-in, go for the LittleCMS default.
125 // If happens only if an extern plug-in is being used
126 if (p ->Interpolation.Lerp16 == NULL((void*)0))
127 p ->Interpolation = DefaultInterpolatorsFactory(p ->nInputs, p ->nOutputs, p ->dwFlags);
128
129 // Check for valid interpolator (we just check one member of the union)
130 if (p ->Interpolation.Lerp16 == NULL((void*)0)) {
131 return FALSE0;
132 }
133
134 return TRUE1;
135}
136
137
138// This function precalculates as many parameters as possible to speed up the interpolation.
139cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID,
140 const cmsUInt32Number nSamples[],
141 cmsUInt32Number InputChan, cmsUInt32Number OutputChan,
142 const void *Table,
143 cmsUInt32Number dwFlags)
144{
145 cmsInterpParams* p;
146 cmsUInt32Number i;
147
148 // Check for maximum inputs
149 if (InputChan > MAX_INPUT_DIMENSIONS15) {
150 cmsSignalError(ContextID, cmsERROR_RANGE2, "Too many input channels (%d channels, max=%d)", InputChan, MAX_INPUT_DIMENSIONS15);
151 return NULL((void*)0);
152 }
153
154 // Creates an empty object
155 p = (cmsInterpParams*) _cmsMallocZero(ContextID, sizeof(cmsInterpParams));
156 if (p == NULL((void*)0)) return NULL((void*)0);
157
158 // Keep original parameters
159 p -> dwFlags = dwFlags;
160 p -> nInputs = InputChan;
161 p -> nOutputs = OutputChan;
162 p ->Table = Table;
163 p ->ContextID = ContextID;
164
165 // Fill samples per input direction and domain (which is number of nodes minus one)
166 for (i=0; i < InputChan; i++) {
167
168 p -> nSamples[i] = nSamples[i];
169 p -> Domain[i] = nSamples[i] - 1;
170 }
171
172 // Compute factors to apply to each component to index the grid array
173 p -> opta[0] = p -> nOutputs;
174 for (i=1; i < InputChan; i++)
175 p ->opta[i] = p ->opta[i-1] * nSamples[InputChan-i];
176
177
178 if (!_cmsSetInterpolationRoutine(ContextID, p)) {
179 cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION8, "Unsupported interpolation (%d->%d channels)", InputChan, OutputChan);
180 _cmsFree(ContextID, p);
181 return NULL((void*)0);
182 }
183
184 // All seems ok
185 return p;
186}
187
188
189// This one is a wrapper on the anterior, but assuming all directions have same number of nodes
190cmsInterpParams* CMSEXPORT _cmsComputeInterpParams(cmsContext ContextID, cmsUInt32Number nSamples,
191 cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags)
192{
193 int i;
194 cmsUInt32Number Samples[MAX_INPUT_DIMENSIONS15];
195
196 // Fill the auxiliary array
197 for (i=0; i < MAX_INPUT_DIMENSIONS15; 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
206void CMSEXPORT _cmsFreeInterpParams(cmsInterpParams* p)
207{
208 if (p != NULL((void*)0)) _cmsFree(p ->ContextID, p);
209}
210
211
212// Inline fixed point interpolation
213cmsINLINEstatic inline CMS_NO_SANITIZE__attribute__((no_sanitize("signed-integer-overflow"))) 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)
222static
223void LinLerp1D(CMSREGISTERregister const cmsUInt16Number Value[],
224 CMSREGISTERregister cmsUInt16Number Output[],
225 CMSREGISTERregister 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)((val3)>>16); // Cell is 16 MSB bits
243 rest = FIXED_REST_TO_INT(val3)((val3)&0xFFFFU); // 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
253cmsINLINEstatic inline cmsFloat32Number fclamp(cmsFloat32Number v)
254{
255 return ((v < 1.0e-9f) || isnan(v)(sizeof ((v)) == sizeof (float) ? __isnanf (v) : sizeof ((v))
== sizeof (double) ? __isnan (v) : __isnanl (v))
) ? 0.0f : (v > 1.0f ? 1.0f : v);
256}
257
258// Floating-point version of 1D interpolation
259static
260void 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
295static CMS_NO_SANITIZE__attribute__((no_sanitize("signed-integer-overflow")))
296void Eval1Input(CMSREGISTERregister const cmsUInt16Number Input[],
297 CMSREGISTERregister cmsUInt16Number Output[],
298 CMSREGISTERregister 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)((fk)>>16);
310 rk = (cmsUInt16Number) FIXED_REST_TO_INT(fk)((fk)&0xFFFFU);
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
319 Output[OutChan] = LinearInterp(rk, LutTable[K0+OutChan], LutTable[K1+OutChan]);
320 }
321}
322
323
324
325// Eval gray LUT having only one input channel
326static
327void 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
372static
373void 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,
389 dxy;
390
391 TotalOut = p -> nOutputs;
392 px = fclamp(Input[0]) * p->Domain[0];
393 py = fclamp(Input[1]) * p->Domain[1];
394
395 x0 = (int) _cmsQuickFloor(px); fx = px - (cmsFloat32Number) x0;
396 y0 = (int) _cmsQuickFloor(py); fy = py - (cmsFloat32Number) y0;
397
398 X0 = p -> opta[1] * x0;
399 X1 = X0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[1]);
400
401 Y0 = p -> opta[0] * y0;
402 Y1 = Y0 + (fclamp(Input[1]) >= 1.0 ? 0 : p->opta[0]);
403
404 for (OutChan = 0; OutChan < TotalOut; OutChan++) {
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
425static CMS_NO_SANITIZE__attribute__((no_sanitize("signed-integer-overflow")))
426void BilinearInterp16(CMSREGISTERregister const cmsUInt16Number Input[],
427 CMSREGISTERregister cmsUInt16Number Output[],
428 CMSREGISTERregister 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))(((((h-l)*a))+0x8000)>>16))
433
434 const cmsUInt16Number* LutTable = (cmsUInt16Number*) p ->Table;
435 int OutChan, TotalOut;
436 cmsS15Fixed16Number fx, fy;
437 CMSREGISTERregister int rx, ry;
438 int x0, y0;
439 CMSREGISTERregister int X0, X1, Y0, Y1;
440
441 int d00, d01, d10, d11,
442 dx0, dx1,
443 dxy;
444
445 TotalOut = p -> nOutputs;
446
447 fx = _cmsToFixedDomain((int) Input[0] * p -> Domain[0]);
448 x0 = FIXED_TO_INT(fx)((fx)>>16);
449 rx = FIXED_REST_TO_INT(fx)((fx)&0xFFFFU); // Rest in 0..1.0 domain
450
451
452 fy = _cmsToFixedDomain((int) Input[1] * p -> Domain[1]);
453 y0 = FIXED_TO_INT(fy)((fy)>>16);
454 ry = FIXED_REST_TO_INT(fy)((fy)&0xFFFFU);
455
456
457 X0 = p -> opta[1] * x0;
458 X1 = X0 + (Input[0] == 0xFFFFU ? 0 : p->opta[1]);
459
460 Y0 = p -> opta[0] * y0;
461 Y1 = Y0 + (Input[1] == 0xFFFFU ? 0 : p->opta[0]);
462
463 for (OutChan = 0; OutChan < TotalOut; OutChan++) {
464
465 d00 = DENS(X0, Y0);
466 d01 = DENS(X0, Y1);
467 d10 = DENS(X1, Y0);
468 d11 = DENS(X1, Y1);
469
470 dx0 = LERP(rx, d00, d10);
471 dx1 = LERP(rx, d01, d11);
472
473 dxy = LERP(ry, dx0, dx1);
474
475 Output[OutChan] = (cmsUInt16Number) dxy;
476 }
477
478
479# undef LERP
480# undef DENS
481}
482
483
484// Trilinear interpolation (16 bits) - cmsFloat32Number version
485static
486void TrilinearInterpFloat(const cmsFloat32Number Input[],
487 cmsFloat32Number Output[],
488 const cmsInterpParams* p)
489
490{
491# define LERP(a,l,h) (cmsFloat32Number) ((l)+(((h)-(l))*(a)))
492# define DENS(i,j,k) (LutTable[(i)+(j)+(k)+OutChan])
493
494 const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table;
495 cmsFloat32Number px, py, pz;
496 int x0, y0, z0,
497 X0, Y0, Z0, X1, Y1, Z1;
498 int TotalOut, OutChan;
499
500 cmsFloat32Number fx, fy, fz,
501 d000, d001, d010, d011,
502 d100, d101, d110, d111,
503 dx00, dx01, dx10, dx11,
504 dxy0, dxy1, dxyz;
505
506 TotalOut = p -> nOutputs;
507
508 // We need some clipping here
509 px = fclamp(Input[0]) * p->Domain[0];
510 py = fclamp(Input[1]) * p->Domain[1];
511 pz = fclamp(Input[2]) * p->Domain[2];
512
513 x0 = (int) floor(px); fx = px - (cmsFloat32Number) x0; // We need full floor funcionality here
514 y0 = (int) floor(py); fy = py - (cmsFloat32Number) y0;
515 z0 = (int) floor(pz); fz = pz - (cmsFloat32Number) z0;
516
517 X0 = p -> opta[2] * x0;
518 X1 = X0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[2]);
519
520 Y0 = p -> opta[1] * y0;
521 Y1 = Y0 + (fclamp(Input[1]) >= 1.0 ? 0 : p->opta[1]);
522
523 Z0 = p -> opta[0] * z0;
524 Z1 = Z0 + (fclamp(Input[2]) >= 1.0 ? 0 : p->opta[0]);
525
526 for (OutChan = 0; OutChan < TotalOut; OutChan++) {
527
528 d000 = DENS(X0, Y0, Z0);
529 d001 = DENS(X0, Y0, Z1);
530 d010 = DENS(X0, Y1, Z0);
531 d011 = DENS(X0, Y1, Z1);
532
533 d100 = DENS(X1, Y0, Z0);
534 d101 = DENS(X1, Y0, Z1);
535 d110 = DENS(X1, Y1, Z0);
536 d111 = DENS(X1, Y1, Z1);
537
538
539 dx00 = LERP(fx, d000, d100);
540 dx01 = LERP(fx, d001, d101);
541 dx10 = LERP(fx, d010, d110);
542 dx11 = LERP(fx, d011, d111);
543
544 dxy0 = LERP(fy, dx00, dx10);
545 dxy1 = LERP(fy, dx01, dx11);
546
547 dxyz = LERP(fz, dxy0, dxy1);
548
549 Output[OutChan] = dxyz;
550 }
551
552
553# undef LERP
554# undef DENS
555}
556
557// Trilinear interpolation (16 bits) - optimized version
558static CMS_NO_SANITIZE__attribute__((no_sanitize("signed-integer-overflow")))
559void TrilinearInterp16(CMSREGISTERregister const cmsUInt16Number Input[],
560 CMSREGISTERregister cmsUInt16Number Output[],
561 CMSREGISTERregister const cmsInterpParams* p)
562
563{
564#define DENS(i,j,k) (LutTable[(i)+(j)+(k)+OutChan])
565#define LERP(a,l,h) (cmsUInt16Number) (l + ROUND_FIXED_TO_INT(((h-l)*a))(((((h-l)*a))+0x8000)>>16))
566
567 const cmsUInt16Number* LutTable = (cmsUInt16Number*) p ->Table;
568 int OutChan, TotalOut;
569 cmsS15Fixed16Number fx, fy, fz;
570 CMSREGISTERregister int rx, ry, rz;
571 int x0, y0, z0;
572 CMSREGISTERregister int X0, X1, Y0, Y1, Z0, Z1;
573 int d000, d001, d010, d011,
574 d100, d101, d110, d111,
575 dx00, dx01, dx10, dx11,
576 dxy0, dxy1, dxyz;
577
578 TotalOut = p -> nOutputs;
579
580 fx = _cmsToFixedDomain((int) Input[0] * p -> Domain[0]);
581 x0 = FIXED_TO_INT(fx)((fx)>>16);
582 rx = FIXED_REST_TO_INT(fx)((fx)&0xFFFFU); // Rest in 0..1.0 domain
583
584
585 fy = _cmsToFixedDomain((int) Input[1] * p -> Domain[1]);
586 y0 = FIXED_TO_INT(fy)((fy)>>16);
587 ry = FIXED_REST_TO_INT(fy)((fy)&0xFFFFU);
588
589 fz = _cmsToFixedDomain((int) Input[2] * p -> Domain[2]);
590 z0 = FIXED_TO_INT(fz)((fz)>>16);
591 rz = FIXED_REST_TO_INT(fz)((fz)&0xFFFFU);
592
593
594 X0 = p -> opta[2] * x0;
595 X1 = X0 + (Input[0] == 0xFFFFU ? 0 : p->opta[2]);
596
597 Y0 = p -> opta[1] * y0;
598 Y1 = Y0 + (Input[1] == 0xFFFFU ? 0 : p->opta[1]);
599
600 Z0 = p -> opta[0] * z0;
601 Z1 = Z0 + (Input[2] == 0xFFFFU ? 0 : p->opta[0]);
602
603 for (OutChan = 0; OutChan < TotalOut; OutChan++) {
604
605 d000 = DENS(X0, Y0, Z0);
606 d001 = DENS(X0, Y0, Z1);
607 d010 = DENS(X0, Y1, Z0);
608 d011 = DENS(X0, Y1, Z1);
609
610 d100 = DENS(X1, Y0, Z0);
611 d101 = DENS(X1, Y0, Z1);
612 d110 = DENS(X1, Y1, Z0);
613 d111 = DENS(X1, Y1, Z1);
614
615
616 dx00 = LERP(rx, d000, d100);
617 dx01 = LERP(rx, d001, d101);
618 dx10 = LERP(rx, d010, d110);
619 dx11 = LERP(rx, d011, d111);
620
621 dxy0 = LERP(ry, dx00, dx10);
622 dxy1 = LERP(ry, dx01, dx11);
623
624 dxyz = LERP(rz, dxy0, dxy1);
625
626 Output[OutChan] = (cmsUInt16Number) dxyz;
627 }
628
629
630# undef LERP
631# undef DENS
632}
633
634
635// Tetrahedral interpolation, using Sakamoto algorithm.
636#define DENS(i,j,k) (LutTable[(i)+(j)+(k)+OutChan])
637static
638void TetrahedralInterpFloat(const cmsFloat32Number Input[],
639 cmsFloat32Number Output[],
640 const cmsInterpParams* p)
641{
642 const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;
643 cmsFloat32Number px, py, pz;
644 int x0, y0, z0,
645 X0, Y0, Z0, X1, Y1, Z1;
646 cmsFloat32Number rx, ry, rz;
647 cmsFloat32Number c0, c1=0, c2=0, c3=0;
648 int OutChan, TotalOut;
649
650 TotalOut = p -> nOutputs;
651
652 // We need some clipping here
653 px = fclamp(Input[0]) * p->Domain[0];
654 py = fclamp(Input[1]) * p->Domain[1];
655 pz = fclamp(Input[2]) * p->Domain[2];
656
657 x0 = (int) floor(px); rx = (px - (cmsFloat32Number) x0); // We need full floor functionality here
658 y0 = (int) floor(py); ry = (py - (cmsFloat32Number) y0);
659 z0 = (int) floor(pz); rz = (pz - (cmsFloat32Number) z0);
660
661
662 X0 = p -> opta[2] * x0;
663 X1 = X0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[2]);
664
665 Y0 = p -> opta[1] * y0;
666 Y1 = Y0 + (fclamp(Input[1]) >= 1.0 ? 0 : p->opta[1]);
667
668 Z0 = p -> opta[0] * z0;
669 Z1 = Z0 + (fclamp(Input[2]) >= 1.0 ? 0 : p->opta[0]);
670
671 for (OutChan=0; OutChan < TotalOut; OutChan++) {
672
673 // These are the 6 Tetrahedral
674
675 c0 = DENS(X0, Y0, Z0);
676
677 if (rx >= ry && ry >= rz) {
678
679 c1 = DENS(X1, Y0, Z0) - c0;
680 c2 = DENS(X1, Y1, Z0) - DENS(X1, Y0, Z0);
681 c3 = DENS(X1, Y1, Z1) - DENS(X1, Y1, Z0);
682
683 }
684 else
685 if (rx >= rz && rz >= ry) {
686
687 c1 = DENS(X1, Y0, Z0) - c0;
688 c2 = DENS(X1, Y1, Z1) - DENS(X1, Y0, Z1);
689 c3 = DENS(X1, Y0, Z1) - DENS(X1, Y0, Z0);
690
691 }
692 else
693 if (rz >= rx && rx >= ry) {
694
695 c1 = DENS(X1, Y0, Z1) - DENS(X0, Y0, Z1);
696 c2 = DENS(X1, Y1, Z1) - DENS(X1, Y0, Z1);
697 c3 = DENS(X0, Y0, Z1) - c0;
698
699 }
700 else
701 if (ry >= rx && rx >= rz) {
702
703 c1 = DENS(X1, Y1, Z0) - DENS(X0, Y1, Z0);
704 c2 = DENS(X0, Y1, Z0) - c0;
705 c3 = DENS(X1, Y1, Z1) - DENS(X1, Y1, Z0);
706
707 }
708 else
709 if (ry >= rz && rz >= rx) {
710
711 c1 = DENS(X1, Y1, Z1) - DENS(X0, Y1, Z1);
712 c2 = DENS(X0, Y1, Z0) - c0;
713 c3 = DENS(X0, Y1, Z1) - DENS(X0, Y1, Z0);
714
715 }
716 else
717 if (rz >= ry && ry >= rx) {
718
719 c1 = DENS(X1, Y1, Z1) - DENS(X0, Y1, Z1);
720 c2 = DENS(X0, Y1, Z1) - DENS(X0, Y0, Z1);
721 c3 = DENS(X0, Y0, Z1) - c0;
722
723 }
724 else {
725 c1 = c2 = c3 = 0;
726 }
727
728 Output[OutChan] = c0 + c1 * rx + c2 * ry + c3 * rz;
729 }
730
731}
732
733#undef DENS
734
735static CMS_NO_SANITIZE__attribute__((no_sanitize("signed-integer-overflow")))
736void TetrahedralInterp16(CMSREGISTERregister const cmsUInt16Number Input[],
737 CMSREGISTERregister cmsUInt16Number Output[],
738 CMSREGISTERregister const cmsInterpParams* p)
739{
740 const cmsUInt16Number* LutTable = (cmsUInt16Number*) p -> Table;
741 cmsS15Fixed16Number fx, fy, fz;
742 cmsS15Fixed16Number rx, ry, rz;
743 int x0, y0, z0;
744 cmsS15Fixed16Number c0, c1, c2, c3, Rest;
745 cmsUInt32Number X0, X1, Y0, Y1, Z0, Z1;
746 cmsUInt32Number TotalOut = p -> nOutputs;
747
748 fx = _cmsToFixedDomain((int) Input[0] * p -> Domain[0]);
749 fy = _cmsToFixedDomain((int) Input[1] * p -> Domain[1]);
750 fz = _cmsToFixedDomain((int) Input[2] * p -> Domain[2]);
751
752 x0 = FIXED_TO_INT(fx)((fx)>>16);
753 y0 = FIXED_TO_INT(fy)((fy)>>16);
754 z0 = FIXED_TO_INT(fz)((fz)>>16);
755
756 rx = FIXED_REST_TO_INT(fx)((fx)&0xFFFFU);
757 ry = FIXED_REST_TO_INT(fy)((fy)&0xFFFFU);
758 rz = FIXED_REST_TO_INT(fz)((fz)&0xFFFFU);
759
760 X0 = p -> opta[2] * x0;
761 X1 = (Input[0] == 0xFFFFU ? 0 : p->opta[2]);
762
763 Y0 = p -> opta[1] * y0;
764 Y1 = (Input[1] == 0xFFFFU ? 0 : p->opta[1]);
765
766 Z0 = p -> opta[0] * z0;
767 Z1 = (Input[2] == 0xFFFFU ? 0 : p->opta[0]);
768
769 LutTable += X0+Y0+Z0;
770
771 // Output should be computed as x = ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest))
772 // which expands as: x = (Rest + ((Rest+0x7fff)/0xFFFF) + 0x8000)>>16
773 // This can be replaced by: t = Rest+0x8001, x = (t + (t>>16))>>16
774 // at the cost of being off by one at 7fff and 17ffe.
775
776 if (rx >= ry) {
777 if (ry >= rz) {
778 Y1 += X1;
779 Z1 += Y1;
780 for (; TotalOut; TotalOut--) {
781 c1 = LutTable[X1];
782 c2 = LutTable[Y1];
783 c3 = LutTable[Z1];
784 c0 = *LutTable++;
785 c3 -= c2;
786 c2 -= c1;
787 c1 -= c0;
788 Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001;
789 *Output++ = (cmsUInt16Number) c0 + ((Rest + (Rest>>16))>>16);
790 }
791 } else if (rz >= rx) {
792 X1 += Z1;
793 Y1 += X1;
794 for (; TotalOut; TotalOut--) {
795 c1 = LutTable[X1];
796 c2 = LutTable[Y1];
797 c3 = LutTable[Z1];
798 c0 = *LutTable++;
799 c2 -= c1;
800 c1 -= c3;
801 c3 -= c0;
802 Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001;
803 *Output++ = (cmsUInt16Number) c0 + ((Rest + (Rest>>16))>>16);
804 }
805 } else {
806 Z1 += X1;
807 Y1 += Z1;
808 for (; TotalOut; TotalOut--) {
809 c1 = LutTable[X1];
810 c2 = LutTable[Y1];
811 c3 = LutTable[Z1];
812 c0 = *LutTable++;
813 c2 -= c3;
814 c3 -= c1;
815 c1 -= c0;
816 Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001;
817 *Output++ = (cmsUInt16Number) c0 + ((Rest + (Rest>>16))>>16);
818 }
819 }
820 } else {
821 if (rx >= rz) {
822 X1 += Y1;
823 Z1 += X1;
824 for (; TotalOut; TotalOut--) {
825 c1 = LutTable[X1];
826 c2 = LutTable[Y1];
827 c3 = LutTable[Z1];
828 c0 = *LutTable++;
829 c3 -= c1;
830 c1 -= c2;
831 c2 -= c0;
832 Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001;
833 *Output++ = (cmsUInt16Number) c0 + ((Rest + (Rest>>16))>>16);
834 }
835 } else if (ry >= rz) {
836 Z1 += Y1;
837 X1 += Z1;
838 for (; TotalOut; TotalOut--) {
839 c1 = LutTable[X1];
840 c2 = LutTable[Y1];
841 c3 = LutTable[Z1];
842 c0 = *LutTable++;
843 c1 -= c3;
844 c3 -= c2;
845 c2 -= c0;
846 Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001;
847 *Output++ = (cmsUInt16Number) c0 + ((Rest + (Rest>>16))>>16);
848 }
849 } else {
850 Y1 += Z1;
851 X1 += Y1;
852 for (; TotalOut; TotalOut--) {
853 c1 = LutTable[X1];
854 c2 = LutTable[Y1];
855 c3 = LutTable[Z1];
856 c0 = *LutTable++;
857 c1 -= c2;
858 c2 -= c3;
859 c3 -= c0;
860 Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001;
861 *Output++ = (cmsUInt16Number) c0 + ((Rest + (Rest>>16))>>16);
862 }
863 }
864 }
865}
866
867
868#define DENS(i,j,k) (LutTable[(i)+(j)+(k)+OutChan])
869static CMS_NO_SANITIZE__attribute__((no_sanitize("signed-integer-overflow")))
870void Eval4Inputs(CMSREGISTERregister const cmsUInt16Number Input[],
871 CMSREGISTERregister cmsUInt16Number Output[],
872 CMSREGISTERregister const cmsInterpParams* p16)
873{
874 const cmsUInt16Number* LutTable;
875 cmsS15Fixed16Number fk;
876 cmsS15Fixed16Number k0, rk;
877 int K0, K1;
878 cmsS15Fixed16Number fx, fy, fz;
879 cmsS15Fixed16Number rx, ry, rz;
880 int x0, y0, z0;
881 cmsS15Fixed16Number X0, X1, Y0, Y1, Z0, Z1;
882 cmsUInt32Number i;
883 cmsS15Fixed16Number c0, c1, c2, c3, Rest;
884 cmsUInt32Number OutChan;
885 cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS128], Tmp2[MAX_STAGE_CHANNELS128];
886
887
888 fk = _cmsToFixedDomain((int) Input[0] * p16 -> Domain[0]);
889 fx = _cmsToFixedDomain((int) Input[1] * p16 -> Domain[1]);
890 fy = _cmsToFixedDomain((int) Input[2] * p16 -> Domain[2]);
891 fz = _cmsToFixedDomain((int) Input[3] * p16 -> Domain[3]);
892
893 k0 = FIXED_TO_INT(fk)((fk)>>16);
894 x0 = FIXED_TO_INT(fx)((fx)>>16);
895 y0 = FIXED_TO_INT(fy)((fy)>>16);
896 z0 = FIXED_TO_INT(fz)((fz)>>16);
897
898 rk = FIXED_REST_TO_INT(fk)((fk)&0xFFFFU);
899 rx = FIXED_REST_TO_INT(fx)((fx)&0xFFFFU);
900 ry = FIXED_REST_TO_INT(fy)((fy)&0xFFFFU);
901 rz = FIXED_REST_TO_INT(fz)((fz)&0xFFFFU);
902
903 K0 = p16 -> opta[3] * k0;
904 K1 = K0 + (Input[0] == 0xFFFFU ? 0 : p16->opta[3]);
905
906 X0 = p16 -> opta[2] * x0;
907 X1 = X0 + (Input[1] == 0xFFFFU ? 0 : p16->opta[2]);
908
909 Y0 = p16 -> opta[1] * y0;
910 Y1 = Y0 + (Input[2] == 0xFFFFU ? 0 : p16->opta[1]);
911
912 Z0 = p16 -> opta[0] * z0;
913 Z1 = Z0 + (Input[3] == 0xFFFFU ? 0 : p16->opta[0]);
914
915 LutTable = (cmsUInt16Number*) p16 -> Table;
916 LutTable += K0;
917
918 for (OutChan=0; OutChan < p16 -> nOutputs; OutChan++) {
919
920 c0 = DENS(X0, Y0, Z0);
921
922 if (rx >= ry && ry >= rz) {
923
924 c1 = DENS(X1, Y0, Z0) - c0;
925 c2 = DENS(X1, Y1, Z0) - DENS(X1, Y0, Z0);
926 c3 = DENS(X1, Y1, Z1) - DENS(X1, Y1, Z0);
927
928 }
929 else
930 if (rx >= rz && rz >= ry) {
931
932 c1 = DENS(X1, Y0, Z0) - c0;
933 c2 = DENS(X1, Y1, Z1) - DENS(X1, Y0, Z1);
934 c3 = DENS(X1, Y0, Z1) - DENS(X1, Y0, Z0);
935
936 }
937 else
938 if (rz >= rx && rx >= ry) {
939
940 c1 = DENS(X1, Y0, Z1) - DENS(X0, Y0, Z1);
941 c2 = DENS(X1, Y1, Z1) - DENS(X1, Y0, Z1);
942 c3 = DENS(X0, Y0, Z1) - c0;
943
944 }
945 else
946 if (ry >= rx && rx >= rz) {
947
948 c1 = DENS(X1, Y1, Z0) - DENS(X0, Y1, Z0);
949 c2 = DENS(X0, Y1, Z0) - c0;
950 c3 = DENS(X1, Y1, Z1) - DENS(X1, Y1, Z0);
951
952 }
953 else
954 if (ry >= rz && rz >= rx) {
955
956 c1 = DENS(X1, Y1, Z1) - DENS(X0, Y1, Z1);
957 c2 = DENS(X0, Y1, Z0) - c0;
958 c3 = DENS(X0, Y1, Z1) - DENS(X0, Y1, Z0);
959
960 }
961 else
962 if (rz >= ry && ry >= rx) {
963
964 c1 = DENS(X1, Y1, Z1) - DENS(X0, Y1, Z1);
965 c2 = DENS(X0, Y1, Z1) - DENS(X0, Y0, Z1);
966 c3 = DENS(X0, Y0, Z1) - c0;
967
968 }
969 else {
970 c1 = c2 = c3 = 0;
971 }
972
973 Rest = c1 * rx + c2 * ry + c3 * rz;
974
975 Tmp1[OutChan] = (cmsUInt16Number)(c0 + ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest))(((_cmsToFixedDomain(Rest))+0x8000)>>16));
976 }
977
978
979 LutTable = (cmsUInt16Number*) p16 -> Table;
980 LutTable += K1;
981
982 for (OutChan=0; OutChan < p16 -> nOutputs; OutChan++) {
983
984 c0 = DENS(X0, Y0, Z0);
985
986 if (rx >= ry && ry >= rz) {
987
988 c1 = DENS(X1, Y0, Z0) - c0;
989 c2 = DENS(X1, Y1, Z0) - DENS(X1, Y0, Z0);
990 c3 = DENS(X1, Y1, Z1) - DENS(X1, Y1, Z0);
991
992 }
993 else
994 if (rx >= rz && rz >= ry) {
995
996 c1 = DENS(X1, Y0, Z0) - c0;
997 c2 = DENS(X1, Y1, Z1) - DENS(X1, Y0, Z1);
998 c3 = DENS(X1, Y0, Z1) - DENS(X1, Y0, Z0);
999
1000 }
1001 else
1002 if (rz >= rx && rx >= ry) {
1003
1004 c1 = DENS(X1, Y0, Z1) - DENS(X0, Y0, Z1);
1005 c2 = DENS(X1, Y1, Z1) - DENS(X1, Y0, Z1);
1006 c3 = DENS(X0, Y0, Z1) - c0;
1007
1008 }
1009 else
1010 if (ry >= rx && rx >= rz) {
1011
1012 c1 = DENS(X1, Y1, Z0) - DENS(X0, Y1, Z0);
1013 c2 = DENS(X0, Y1, Z0) - c0;
1014 c3 = DENS(X1, Y1, Z1) - DENS(X1, Y1, Z0);
1015
1016 }
1017 else
1018 if (ry >= rz && rz >= rx) {
1019
1020 c1 = DENS(X1, Y1, Z1) - DENS(X0, Y1, Z1);
1021 c2 = DENS(X0, Y1, Z0) - c0;
1022 c3 = DENS(X0, Y1, Z1) - DENS(X0, Y1, Z0);
1023
1024 }
1025 else
1026 if (rz >= ry && ry >= rx) {
1027
1028 c1 = DENS(X1, Y1, Z1) - DENS(X0, Y1, Z1);
1029 c2 = DENS(X0, Y1, Z1) - DENS(X0, Y0, Z1);
1030 c3 = DENS(X0, Y0, Z1) - c0;
1031
1032 }
1033 else {
1034 c1 = c2 = c3 = 0;
1035 }
1036
1037 Rest = c1 * rx + c2 * ry + c3 * rz;
1038
1039 Tmp2[OutChan] = (cmsUInt16Number) (c0 + ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest))(((_cmsToFixedDomain(Rest))+0x8000)>>16));
1040 }
1041
1042
1043
1044 for (i=0; i < p16 -> nOutputs; i++) {
1045 Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]);
1046 }
1047}
1048#undef DENS
1049
1050
1051// For more that 3 inputs (i.e., CMYK)
1052// evaluate two 3-dimensional interpolations and then linearly interpolate between them.
1053static
1054void Eval4InputsFloat(const cmsFloat32Number Input[],
1055 cmsFloat32Number Output[],
1056 const cmsInterpParams* p)
1057{
1058 const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;
1059 cmsFloat32Number rest;
1060 cmsFloat32Number pk;
1061 int k0, K0, K1;
1062 const cmsFloat32Number* T;
1063 cmsUInt32Number i;
1064 cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS128], Tmp2[MAX_STAGE_CHANNELS128];
1065 cmsInterpParams p1;
1066
1067 pk = fclamp(Input[0]) * p->Domain[0];
1068 k0 = _cmsQuickFloor(pk);
1069 rest = pk - (cmsFloat32Number) k0;
1070
1071 K0 = p -> opta[3] * k0;
1072 K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[3]);
1073
1074 p1 = *p;
1075 memmove(&p1.Domain[0], &p ->Domain[1], 3*sizeof(cmsUInt32Number));
1076
1077 T = LutTable + K0;
1078 p1.Table = T;
1079
1080 TetrahedralInterpFloat(Input + 1, Tmp1, &p1);
1081
1082 T = LutTable + K1;
1083 p1.Table = T;
1084 TetrahedralInterpFloat(Input + 1, Tmp2, &p1);
1085
1086 for (i=0; i < p -> nOutputs; i++)
1087 {
1088 cmsFloat32Number y0 = Tmp1[i];
1089 cmsFloat32Number y1 = Tmp2[i];
1090
1091 Output[i] = y0 + (y1 - y0) * rest;
1092 }
1093}
1094
1095#define EVAL_FNS(N,NM)static __attribute__((no_sanitize("signed-integer-overflow"))
) void EvalNInputs(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[128], Tmp2[128]; cmsInterpParams p1; fk = _cmsToFixedDomain
((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]); k0 = (
(fk)>>16); rk = ((fk)&0xFFFFU); K0 = p16 -> opta
[NM] * k0; K1 = p16 -> opta[NM] * (k0 + (Input[0] != 0xFFFFU
? 1 : 0)); p1 = *p16; memmove(&p1.Domain[0], &p16 ->
Domain[1], NM*sizeof(cmsUInt32Number)); T = LutTable + K0; p1
.Table = T; EvalNMInputs(Input + 1, Tmp1, &p1); T = LutTable
+ K1; p1.Table = T; EvalNMInputs(Input + 1, Tmp2, &p1); for
(i=0; i < p16 -> nOutputs; i++) { Output[i] = LinearInterp
(rk, Tmp1[i], Tmp2[i]); }}static void EvalNInputsFloat(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[128], Tmp2[128]; cmsInterpParams p1; pk = fclamp(Input[
0]) * p->Domain[0]; k0 = _cmsQuickFloor(pk); rest = pk - (
cmsFloat32Number) k0; K0 = p -> opta[NM] * k0; K1 = K0 + (
fclamp(Input[0]) >= 1.0 ? 0 : p->opta[NM]); p1 = *p; memmove
(&p1.Domain[0], &p ->Domain[1], NM*sizeof(cmsUInt32Number
)); T = LutTable + K0; p1.Table = T; EvalNMInputsFloat(Input +
1, Tmp1, &p1); T = LutTable + K1; p1.Table = T; EvalNMInputsFloat
(Input + 1, Tmp2, &p1); for (i=0; i < p -> nOutputs
; i++) { cmsFloat32Number y0 = Tmp1[i]; cmsFloat32Number y1 =
Tmp2[i]; Output[i] = y0 + (y1 - y0) * rest; }}
static CMS_NO_SANITIZE__attribute__((no_sanitize("signed-integer-overflow"))) \
1096void Eval##N##Inputs(CMSREGISTERregister const cmsUInt16Number Input[], CMSREGISTERregister cmsUInt16Number Output[], CMSREGISTERregister 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_CHANNELS128], Tmp2[MAX_STAGE_CHANNELS128];\
1105 cmsInterpParams p1;\
1106\
1107 fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);\
1108 k0 = FIXED_TO_INT(fk)((fk)>>16);\
1109 rk = FIXED_REST_TO_INT(fk)((fk)&0xFFFFU);\
1110\
1111 K0 = p16 -> opta[NM] * k0;\
1112 K1 = p16 -> opta[NM] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));\
1113\
1114 p1 = *p16;\
1115 memmove(&p1.Domain[0], &p16 ->Domain[1], NM*sizeof(cmsUInt32Number));\
1116\
1117 T = LutTable + K0;\
1118 p1.Table = T;\
1119\
1120 Eval##NM##Inputs(Input + 1, Tmp1, &p1);\
1121\
1122 T = LutTable + K1;\
1123 p1.Table = T;\
1124\
1125 Eval##NM##Inputs(Input + 1, Tmp2, &p1);\
1126\
1127 for (i=0; i < p16 -> nOutputs; i++) {\
1128\
1129 Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]);\
1130 }\
1131}\
1132\
1133static void Eval##N##InputsFloat(const cmsFloat32Number Input[], \
1134 cmsFloat32Number Output[],\
1135 const cmsInterpParams * p)\
1136{\
1137 const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;\
1138 cmsFloat32Number rest;\
1139 cmsFloat32Number pk;\
1140 int k0, K0, K1;\
1141 const cmsFloat32Number* T;\
1142 cmsUInt32Number i;\
1143 cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS128], Tmp2[MAX_STAGE_CHANNELS128];\
1144 cmsInterpParams p1;\
1145\
1146 pk = fclamp(Input[0]) * p->Domain[0];\
1147 k0 = _cmsQuickFloor(pk);\
1148 rest = pk - (cmsFloat32Number) k0;\
1149\
1150 K0 = p -> opta[NM] * k0;\
1151 K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[NM]);\
1152\
1153 p1 = *p;\
1154 memmove(&p1.Domain[0], &p ->Domain[1], NM*sizeof(cmsUInt32Number));\
1155\
1156 T = LutTable + K0;\
1157 p1.Table = T;\
1158\
1159 Eval##NM##InputsFloat(Input + 1, Tmp1, &p1);\
1160\
1161 T = LutTable + K1;\
1162 p1.Table = T;\
1163\
1164 Eval##NM##InputsFloat(Input + 1, Tmp2, &p1);\
1165\
1166 for (i=0; i < p -> nOutputs; i++) {\
1167\
1168 cmsFloat32Number y0 = Tmp1[i];\
1169 cmsFloat32Number y1 = Tmp2[i];\
1170\
1171 Output[i] = y0 + (y1 - y0) * rest;\
1172 }\
1173}
1174
1175
1176/**
1177* Thanks to Carles Llopis for the templating idea
1178*/
1179EVAL_FNS(5, 4)static __attribute__((no_sanitize("signed-integer-overflow"))
) void Eval5Inputs(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[128], Tmp2[128]; cmsInterpParams p1; fk = _cmsToFixedDomain
((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]); k0 = (
(fk)>>16); rk = ((fk)&0xFFFFU); K0 = p16 -> opta
[4] * k0; K1 = p16 -> opta[4] * (k0 + (Input[0] != 0xFFFFU
? 1 : 0)); p1 = *p16; memmove(&p1.Domain[0], &p16 ->
Domain[1], 4*sizeof(cmsUInt32Number)); T = LutTable + K0; p1.
Table = T; Eval4Inputs(Input + 1, Tmp1, &p1); T = LutTable
+ K1; p1.Table = T; Eval4Inputs(Input + 1, Tmp2, &p1); for
(i=0; i < p16 -> nOutputs; i++) { Output[i] = LinearInterp
(rk, Tmp1[i], Tmp2[i]); }}static void Eval5InputsFloat(const cmsFloat32Number
Input[], cmsFloat32Number Output[], const cmsInterpParams * p
){ const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->
Table; cmsFloat32Number rest; cmsFloat32Number pk; int k0, K0
, K1; const cmsFloat32Number* T; cmsUInt32Number i; cmsFloat32Number
Tmp1[128], Tmp2[128]; cmsInterpParams p1; pk = fclamp(Input[
0]) * p->Domain[0]; k0 = _cmsQuickFloor(pk); rest = pk - (
cmsFloat32Number) k0; K0 = p -> opta[4] * k0; K1 = K0 + (fclamp
(Input[0]) >= 1.0 ? 0 : p->opta[4]); p1 = *p; memmove(&
p1.Domain[0], &p ->Domain[1], 4*sizeof(cmsUInt32Number
)); T = LutTable + K0; p1.Table = T; Eval4InputsFloat(Input +
1, Tmp1, &p1); T = LutTable + K1; p1.Table = T; Eval4InputsFloat
(Input + 1, Tmp2, &p1); for (i=0; i < p -> nOutputs
; i++) { cmsFloat32Number y0 = Tmp1[i]; cmsFloat32Number y1 =
Tmp2[i]; Output[i] = y0 + (y1 - y0) * rest; }}
1180EVAL_FNS(6, 5)static __attribute__((no_sanitize("signed-integer-overflow"))
) void Eval6Inputs(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[128], Tmp2[128]; cmsInterpParams p1; fk = _cmsToFixedDomain
((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]); k0 = (
(fk)>>16); rk = ((fk)&0xFFFFU); K0 = p16 -> opta
[5] * k0; K1 = p16 -> opta[5] * (k0 + (Input[0] != 0xFFFFU
? 1 : 0)); p1 = *p16; memmove(&p1.Domain[0], &p16 ->
Domain[1], 5*sizeof(cmsUInt32Number)); T = LutTable + K0; p1.
Table = T; Eval5Inputs(Input + 1, Tmp1, &p1); T = LutTable
+ K1; p1.Table = T; Eval5Inputs(Input + 1, Tmp2, &p1); for
(i=0; i < p16 -> nOutputs; i++) { Output[i] = LinearInterp
(rk, Tmp1[i], Tmp2[i]); }}static void Eval6InputsFloat(const cmsFloat32Number
Input[], cmsFloat32Number Output[], const cmsInterpParams * p
){ const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->
Table; cmsFloat32Number rest; cmsFloat32Number pk; int k0, K0
, K1; const cmsFloat32Number* T; cmsUInt32Number i; cmsFloat32Number
Tmp1[128], Tmp2[128]; cmsInterpParams p1; pk = fclamp(Input[
0]) * p->Domain[0]; k0 = _cmsQuickFloor(pk); rest = pk - (
cmsFloat32Number) k0; K0 = p -> opta[5] * k0; K1 = K0 + (fclamp
(Input[0]) >= 1.0 ? 0 : p->opta[5]); p1 = *p; memmove(&
p1.Domain[0], &p ->Domain[1], 5*sizeof(cmsUInt32Number
)); T = LutTable + K0; p1.Table = T; Eval5InputsFloat(Input +
1, Tmp1, &p1); T = LutTable + K1; p1.Table = T; Eval5InputsFloat
(Input + 1, Tmp2, &p1); for (i=0; i < p -> nOutputs
; i++) { cmsFloat32Number y0 = Tmp1[i]; cmsFloat32Number y1 =
Tmp2[i]; Output[i] = y0 + (y1 - y0) * rest; }}
1181EVAL_FNS(7, 6)static __attribute__((no_sanitize("signed-integer-overflow"))
) void Eval7Inputs(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[128], Tmp2[128]; cmsInterpParams p1; fk = _cmsToFixedDomain
((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]); k0 = (
(fk)>>16); rk = ((fk)&0xFFFFU); K0 = p16 -> opta
[6] * k0; K1 = p16 -> opta[6] * (k0 + (Input[0] != 0xFFFFU
? 1 : 0)); p1 = *p16; memmove(&p1.Domain[0], &p16 ->
Domain[1], 6*sizeof(cmsUInt32Number)); T = LutTable + K0; p1.
Table = T; Eval6Inputs(Input + 1, Tmp1, &p1); T = LutTable
+ K1; p1.Table = T; Eval6Inputs(Input + 1, Tmp2, &p1); for
(i=0; i < p16 -> nOutputs; i++) { Output[i] = LinearInterp
(rk, Tmp1[i], Tmp2[i]); }}static void Eval7InputsFloat(const cmsFloat32Number
Input[], cmsFloat32Number Output[], const cmsInterpParams * p
){ const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->
Table; cmsFloat32Number rest; cmsFloat32Number pk; int k0, K0
, K1; const cmsFloat32Number* T; cmsUInt32Number i; cmsFloat32Number
Tmp1[128], Tmp2[128]; cmsInterpParams p1; pk = fclamp(Input[
0]) * p->Domain[0]; k0 = _cmsQuickFloor(pk); rest = pk - (
cmsFloat32Number) k0; K0 = p -> opta[6] * k0; K1 = K0 + (fclamp
(Input[0]) >= 1.0 ? 0 : p->opta[6]); p1 = *p; memmove(&
p1.Domain[0], &p ->Domain[1], 6*sizeof(cmsUInt32Number
)); T = LutTable + K0; p1.Table = T; Eval6InputsFloat(Input +
1, Tmp1, &p1); T = LutTable + K1; p1.Table = T; Eval6InputsFloat
(Input + 1, Tmp2, &p1); for (i=0; i < p -> nOutputs
; i++) { cmsFloat32Number y0 = Tmp1[i]; cmsFloat32Number y1 =
Tmp2[i]; Output[i] = y0 + (y1 - y0) * rest; }}
1182EVAL_FNS(8, 7)static __attribute__((no_sanitize("signed-integer-overflow"))
) void Eval8Inputs(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[128], Tmp2[128]; cmsInterpParams p1; fk = _cmsToFixedDomain
((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]); k0 = (
(fk)>>16); rk = ((fk)&0xFFFFU); K0 = p16 -> opta
[7] * k0; K1 = p16 -> opta[7] * (k0 + (Input[0] != 0xFFFFU
? 1 : 0)); p1 = *p16; memmove(&p1.Domain[0], &p16 ->
Domain[1], 7*sizeof(cmsUInt32Number)); T = LutTable + K0; p1.
Table = T; Eval7Inputs(Input + 1, Tmp1, &p1); T = LutTable
+ K1; p1.Table = T; Eval7Inputs(Input + 1, Tmp2, &p1); for
(i=0; i < p16 -> nOutputs; i++) { Output[i] = LinearInterp
(rk, Tmp1[i], Tmp2[i]); }}static void Eval8InputsFloat(const cmsFloat32Number
Input[], cmsFloat32Number Output[], const cmsInterpParams * p
){ const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->
Table; cmsFloat32Number rest; cmsFloat32Number pk; int k0, K0
, K1; const cmsFloat32Number* T; cmsUInt32Number i; cmsFloat32Number
Tmp1[128], Tmp2[128]; cmsInterpParams p1; pk = fclamp(Input[
0]) * p->Domain[0]; k0 = _cmsQuickFloor(pk); rest = pk - (
cmsFloat32Number) k0; K0 = p -> opta[7] * k0; K1 = K0 + (fclamp
(Input[0]) >= 1.0 ? 0 : p->opta[7]); p1 = *p; memmove(&
p1.Domain[0], &p ->Domain[1], 7*sizeof(cmsUInt32Number
)); T = LutTable + K0; p1.Table = T; Eval7InputsFloat(Input +
1, Tmp1, &p1); T = LutTable + K1; p1.Table = T; Eval7InputsFloat
(Input + 1, Tmp2, &p1); for (i=0; i < p -> nOutputs
; i++) { cmsFloat32Number y0 = Tmp1[i]; cmsFloat32Number y1 =
Tmp2[i]; Output[i] = y0 + (y1 - y0) * rest; }}
1183EVAL_FNS(9, 8)static __attribute__((no_sanitize("signed-integer-overflow"))
) void Eval9Inputs(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[128], Tmp2[128]; cmsInterpParams p1; fk = _cmsToFixedDomain
((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]); k0 = (
(fk)>>16); rk = ((fk)&0xFFFFU); K0 = p16 -> opta
[8] * k0; K1 = p16 -> opta[8] * (k0 + (Input[0] != 0xFFFFU
? 1 : 0)); p1 = *p16; memmove(&p1.Domain[0], &p16 ->
Domain[1], 8*sizeof(cmsUInt32Number)); T = LutTable + K0; p1.
Table = T; Eval8Inputs(Input + 1, Tmp1, &p1); T = LutTable
+ K1; p1.Table = T; Eval8Inputs(Input + 1, Tmp2, &p1); for
(i=0; i < p16 -> nOutputs; i++) { Output[i] = LinearInterp
(rk, Tmp1[i], Tmp2[i]); }}static void Eval9InputsFloat(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[128], Tmp2[128]; cmsInterpParams p1; pk = fclamp(Input[
0]) * p->Domain[0]; k0 = _cmsQuickFloor(pk); rest = pk - (
cmsFloat32Number) k0; K0 = p -> opta[8] * k0; K1 = K0 + (fclamp
(Input[0]) >= 1.0 ? 0 : p->opta[8]); p1 = *p; memmove(&
p1.Domain[0], &p ->Domain[1], 8*sizeof(cmsUInt32Number
)); T = LutTable + K0; p1.Table = T; Eval8InputsFloat(Input +
1, Tmp1, &p1); T = LutTable + K1; p1.Table = T; Eval8InputsFloat
(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; }}
4
Assuming the condition is true
5
'?' condition is true
6
Assuming 'i' is >= field 'nOutputs'
7
Loop condition is false. Execution continues on line 1183
1184EVAL_FNS(10, 9)static __attribute__((no_sanitize("signed-integer-overflow"))
) void Eval10Inputs(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[128], Tmp2[128]; cmsInterpParams p1; fk = _cmsToFixedDomain
((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]); k0 = (
(fk)>>16); rk = ((fk)&0xFFFFU); K0 = p16 -> opta
[9] * k0; K1 = p16 -> opta[9] * (k0 + (Input[0] != 0xFFFFU
? 1 : 0)); p1 = *p16; memmove(&p1.Domain[0], &p16 ->
Domain[1], 9*sizeof(cmsUInt32Number)); T = LutTable + K0; p1.
Table = T; Eval9Inputs(Input + 1, Tmp1, &p1); T = LutTable
+ K1; p1.Table = T; Eval9Inputs(Input + 1, Tmp2, &p1); for
(i=0; i < p16 -> nOutputs; i++) { Output[i] = LinearInterp
(rk, Tmp1[i], Tmp2[i]); }}static void Eval10InputsFloat(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[128], Tmp2[128]; cmsInterpParams p1; pk = fclamp(Input[
0]) * p->Domain[0]; k0 = _cmsQuickFloor(pk); rest = pk - (
cmsFloat32Number) k0; K0 = p -> opta[9] * k0; K1 = K0 + (fclamp
(Input[0]) >= 1.0 ? 0 : p->opta[9]); p1 = *p; memmove(&
p1.Domain[0], &p ->Domain[1], 9*sizeof(cmsUInt32Number
)); T = LutTable + K0; p1.Table = T; Eval9InputsFloat(Input +
1, Tmp1, &p1); T = LutTable + K1; p1.Table = T; Eval9InputsFloat
(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; }}
1
Assuming the condition is false
2
'?' condition is false
3
Calling 'Eval9Inputs'
8
Returning from 'Eval9Inputs'
9
The value 0 is assigned to 'i'
10
Assuming 'i' is < field 'nOutputs'
11
Loop condition is true. Entering loop body
12
2nd function call argument is an uninitialized value
1185EVAL_FNS(11, 10)static __attribute__((no_sanitize("signed-integer-overflow"))
) void Eval11Inputs(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[128], Tmp2[128]; cmsInterpParams p1; fk = _cmsToFixedDomain
((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]); k0 = (
(fk)>>16); rk = ((fk)&0xFFFFU); K0 = p16 -> opta
[10] * k0; K1 = p16 -> opta[10] * (k0 + (Input[0] != 0xFFFFU
? 1 : 0)); p1 = *p16; memmove(&p1.Domain[0], &p16 ->
Domain[1], 10*sizeof(cmsUInt32Number)); T = LutTable + K0; p1
.Table = T; Eval10Inputs(Input + 1, Tmp1, &p1); T = LutTable
+ K1; p1.Table = T; Eval10Inputs(Input + 1, Tmp2, &p1); for
(i=0; i < p16 -> nOutputs; i++) { Output[i] = LinearInterp
(rk, Tmp1[i], Tmp2[i]); }}static void Eval11InputsFloat(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[128], Tmp2[128]; cmsInterpParams p1; pk = fclamp(Input[
0]) * p->Domain[0]; k0 = _cmsQuickFloor(pk); rest = pk - (
cmsFloat32Number) k0; K0 = p -> opta[10] * k0; K1 = K0 + (
fclamp(Input[0]) >= 1.0 ? 0 : p->opta[10]); p1 = *p; memmove
(&p1.Domain[0], &p ->Domain[1], 10*sizeof(cmsUInt32Number
)); T = LutTable + K0; p1.Table = T; Eval10InputsFloat(Input +
1, Tmp1, &p1); T = LutTable + K1; p1.Table = T; Eval10InputsFloat
(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; }}
1186EVAL_FNS(12, 11)static __attribute__((no_sanitize("signed-integer-overflow"))
) void Eval12Inputs(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[128], Tmp2[128]; cmsInterpParams p1; fk = _cmsToFixedDomain
((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]); k0 = (
(fk)>>16); rk = ((fk)&0xFFFFU); K0 = p16 -> opta
[11] * k0; K1 = p16 -> opta[11] * (k0 + (Input[0] != 0xFFFFU
? 1 : 0)); p1 = *p16; memmove(&p1.Domain[0], &p16 ->
Domain[1], 11*sizeof(cmsUInt32Number)); T = LutTable + K0; p1
.Table = T; Eval11Inputs(Input + 1, Tmp1, &p1); T = LutTable
+ K1; p1.Table = T; Eval11Inputs(Input + 1, Tmp2, &p1); for
(i=0; i < p16 -> nOutputs; i++) { Output[i] = LinearInterp
(rk, Tmp1[i], Tmp2[i]); }}static void Eval12InputsFloat(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[128], Tmp2[128]; cmsInterpParams p1; pk = fclamp(Input[
0]) * p->Domain[0]; k0 = _cmsQuickFloor(pk); rest = pk - (
cmsFloat32Number) k0; K0 = p -> opta[11] * k0; K1 = K0 + (
fclamp(Input[0]) >= 1.0 ? 0 : p->opta[11]); p1 = *p; memmove
(&p1.Domain[0], &p ->Domain[1], 11*sizeof(cmsUInt32Number
)); T = LutTable + K0; p1.Table = T; Eval11InputsFloat(Input +
1, Tmp1, &p1); T = LutTable + K1; p1.Table = T; Eval11InputsFloat
(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; }}
1187EVAL_FNS(13, 12)static __attribute__((no_sanitize("signed-integer-overflow"))
) void Eval13Inputs(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[128], Tmp2[128]; cmsInterpParams p1; fk = _cmsToFixedDomain
((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]); k0 = (
(fk)>>16); rk = ((fk)&0xFFFFU); K0 = p16 -> opta
[12] * k0; K1 = p16 -> opta[12] * (k0 + (Input[0] != 0xFFFFU
? 1 : 0)); p1 = *p16; memmove(&p1.Domain[0], &p16 ->
Domain[1], 12*sizeof(cmsUInt32Number)); T = LutTable + K0; p1
.Table = T; Eval12Inputs(Input + 1, Tmp1, &p1); T = LutTable
+ K1; p1.Table = T; Eval12Inputs(Input + 1, Tmp2, &p1); for
(i=0; i < p16 -> nOutputs; i++) { Output[i] = LinearInterp
(rk, Tmp1[i], Tmp2[i]); }}static void Eval13InputsFloat(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[128], Tmp2[128]; cmsInterpParams p1; pk = fclamp(Input[
0]) * p->Domain[0]; k0 = _cmsQuickFloor(pk); rest = pk - (
cmsFloat32Number) k0; K0 = p -> opta[12] * k0; K1 = K0 + (
fclamp(Input[0]) >= 1.0 ? 0 : p->opta[12]); p1 = *p; memmove
(&p1.Domain[0], &p ->Domain[1], 12*sizeof(cmsUInt32Number
)); T = LutTable + K0; p1.Table = T; Eval12InputsFloat(Input +
1, Tmp1, &p1); T = LutTable + K1; p1.Table = T; Eval12InputsFloat
(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; }}
1188EVAL_FNS(14, 13)static __attribute__((no_sanitize("signed-integer-overflow"))
) void Eval14Inputs(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[128], Tmp2[128]; cmsInterpParams p1; fk = _cmsToFixedDomain
((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]); k0 = (
(fk)>>16); rk = ((fk)&0xFFFFU); K0 = p16 -> opta
[13] * k0; K1 = p16 -> opta[13] * (k0 + (Input[0] != 0xFFFFU
? 1 : 0)); p1 = *p16; memmove(&p1.Domain[0], &p16 ->
Domain[1], 13*sizeof(cmsUInt32Number)); T = LutTable + K0; p1
.Table = T; Eval13Inputs(Input + 1, Tmp1, &p1); T = LutTable
+ K1; p1.Table = T; Eval13Inputs(Input + 1, Tmp2, &p1); for
(i=0; i < p16 -> nOutputs; i++) { Output[i] = LinearInterp
(rk, Tmp1[i], Tmp2[i]); }}static void Eval14InputsFloat(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[128], Tmp2[128]; cmsInterpParams p1; pk = fclamp(Input[
0]) * p->Domain[0]; k0 = _cmsQuickFloor(pk); rest = pk - (
cmsFloat32Number) k0; K0 = p -> opta[13] * k0; K1 = K0 + (
fclamp(Input[0]) >= 1.0 ? 0 : p->opta[13]); p1 = *p; memmove
(&p1.Domain[0], &p ->Domain[1], 13*sizeof(cmsUInt32Number
)); T = LutTable + K0; p1.Table = T; Eval13InputsFloat(Input +
1, Tmp1, &p1); T = LutTable + K1; p1.Table = T; Eval13InputsFloat
(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; }}
1189EVAL_FNS(15, 14)static __attribute__((no_sanitize("signed-integer-overflow"))
) void Eval15Inputs(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[128], Tmp2[128]; cmsInterpParams p1; fk = _cmsToFixedDomain
((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]); k0 = (
(fk)>>16); rk = ((fk)&0xFFFFU); K0 = p16 -> opta
[14] * k0; K1 = p16 -> opta[14] * (k0 + (Input[0] != 0xFFFFU
? 1 : 0)); p1 = *p16; memmove(&p1.Domain[0], &p16 ->
Domain[1], 14*sizeof(cmsUInt32Number)); T = LutTable + K0; p1
.Table = T; Eval14Inputs(Input + 1, Tmp1, &p1); T = LutTable
+ K1; p1.Table = T; Eval14Inputs(Input + 1, Tmp2, &p1); for
(i=0; i < p16 -> nOutputs; i++) { Output[i] = LinearInterp
(rk, Tmp1[i], Tmp2[i]); }}static void Eval15InputsFloat(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[128], Tmp2[128]; cmsInterpParams p1; pk = fclamp(Input[
0]) * p->Domain[0]; k0 = _cmsQuickFloor(pk); rest = pk - (
cmsFloat32Number) k0; K0 = p -> opta[14] * k0; K1 = K0 + (
fclamp(Input[0]) >= 1.0 ? 0 : p->opta[14]); p1 = *p; memmove
(&p1.Domain[0], &p ->Domain[1], 14*sizeof(cmsUInt32Number
)); T = LutTable + K0; p1.Table = T; Eval14InputsFloat(Input +
1, Tmp1, &p1); T = LutTable + K1; p1.Table = T; Eval14InputsFloat
(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; }}
1190
1191
1192// The default factory
1193static
1194cmsInterpFunction DefaultInterpolatorsFactory(cmsUInt32Number nInputChannels, cmsUInt32Number nOutputChannels, cmsUInt32Number dwFlags)
1195{
1196
1197 cmsInterpFunction Interpolation;
1198 cmsBool IsFloat = (dwFlags & CMS_LERP_FLAGS_FLOAT0x0001);
1199 cmsBool IsTrilinear = (dwFlags & CMS_LERP_FLAGS_TRILINEAR0x0100);
1200
1201 memset(&Interpolation, 0, sizeof(Interpolation));
1202
1203 // Safety check
1204 if (nInputChannels >= 4 && nOutputChannels >= MAX_STAGE_CHANNELS128)
1205 return Interpolation;
1206
1207 switch (nInputChannels) {
1208
1209 case 1: // Gray LUT / linear
1210
1211 if (nOutputChannels == 1) {
1212
1213 if (IsFloat)
1214 Interpolation.LerpFloat = LinLerp1Dfloat;
1215 else
1216 Interpolation.Lerp16 = LinLerp1D;
1217
1218 }
1219 else {
1220
1221 if (IsFloat)
1222 Interpolation.LerpFloat = Eval1InputFloat;
1223 else
1224 Interpolation.Lerp16 = Eval1Input;
1225 }
1226 break;
1227
1228 case 2: // Duotone
1229 if (IsFloat)
1230 Interpolation.LerpFloat = BilinearInterpFloat;
1231 else
1232 Interpolation.Lerp16 = BilinearInterp16;
1233 break;
1234
1235 case 3: // RGB et al
1236
1237 if (IsTrilinear) {
1238
1239 if (IsFloat)
1240 Interpolation.LerpFloat = TrilinearInterpFloat;
1241 else
1242 Interpolation.Lerp16 = TrilinearInterp16;
1243 }
1244 else {
1245
1246 if (IsFloat)
1247 Interpolation.LerpFloat = TetrahedralInterpFloat;
1248 else {
1249
1250 Interpolation.Lerp16 = TetrahedralInterp16;
1251 }
1252 }
1253 break;
1254
1255 case 4: // CMYK lut
1256
1257 if (IsFloat)
1258 Interpolation.LerpFloat = Eval4InputsFloat;
1259 else
1260 Interpolation.Lerp16 = Eval4Inputs;
1261 break;
1262
1263 case 5: // 5 Inks
1264 if (IsFloat)
1265 Interpolation.LerpFloat = Eval5InputsFloat;
1266 else
1267 Interpolation.Lerp16 = Eval5Inputs;
1268 break;
1269
1270 case 6: // 6 Inks
1271 if (IsFloat)
1272 Interpolation.LerpFloat = Eval6InputsFloat;
1273 else
1274 Interpolation.Lerp16 = Eval6Inputs;
1275 break;
1276
1277 case 7: // 7 inks
1278 if (IsFloat)
1279 Interpolation.LerpFloat = Eval7InputsFloat;
1280 else
1281 Interpolation.Lerp16 = Eval7Inputs;
1282 break;
1283
1284 case 8: // 8 inks
1285 if (IsFloat)
1286 Interpolation.LerpFloat = Eval8InputsFloat;
1287 else
1288 Interpolation.Lerp16 = Eval8Inputs;
1289 break;
1290
1291 case 9:
1292 if (IsFloat)
1293 Interpolation.LerpFloat = Eval9InputsFloat;
1294 else
1295 Interpolation.Lerp16 = Eval9Inputs;
1296 break;
1297
1298 case 10:
1299 if (IsFloat)
1300 Interpolation.LerpFloat = Eval10InputsFloat;
1301 else
1302 Interpolation.Lerp16 = Eval10Inputs;
1303 break;
1304
1305 case 11:
1306 if (IsFloat)
1307 Interpolation.LerpFloat = Eval11InputsFloat;
1308 else
1309 Interpolation.Lerp16 = Eval11Inputs;
1310 break;
1311
1312 case 12:
1313 if (IsFloat)
1314 Interpolation.LerpFloat = Eval12InputsFloat;
1315 else
1316 Interpolation.Lerp16 = Eval12Inputs;
1317 break;
1318
1319 case 13:
1320 if (IsFloat)
1321 Interpolation.LerpFloat = Eval13InputsFloat;
1322 else
1323 Interpolation.Lerp16 = Eval13Inputs;
1324 break;
1325
1326 case 14:
1327 if (IsFloat)
1328 Interpolation.LerpFloat = Eval14InputsFloat;
1329 else
1330 Interpolation.Lerp16 = Eval14Inputs;
1331 break;
1332
1333 case 15:
1334 if (IsFloat)
1335 Interpolation.LerpFloat = Eval15InputsFloat;
1336 else
1337 Interpolation.Lerp16 = Eval15Inputs;
1338 break;
1339
1340 default:
1341 Interpolation.Lerp16 = NULL((void*)0);
1342 }
1343
1344 return Interpolation;
1345}