1 //---------------------------------------------------------------------------------
2 //
3 // Little Color Management System
4 // Copyright (c) 1998-2023 Marti Maria Saguer
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining
7 // a copy of this software and associated documentation files (the "Software"),
8 // to deal in the Software without restriction, including without limitation
9 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 // and/or sell copies of the Software, and to permit persons to whom the Software
11 // is furnished to do so, subject to the following conditions:
12 //
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
18 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 //
24 //---------------------------------------------------------------------------------
25 //
26
27 #include "lcms2_internal.h"
28
29 // This module handles all formats supported by lcms. There are two flavors, 16 bits and
30 // floating point. Floating point is supported only in a subset, those formats holding
31 // cmsFloat32Number (4 bytes per component) and double (marked as 0 bytes per component
32 // as special case)
33
34 // ---------------------------------------------------------------------------
35
36
37 // This macro return words stored as big endian
38 #define CHANGE_ENDIAN(w) (cmsUInt16Number) ((cmsUInt16Number) ((w)<<8)|((w)>>8))
39
40 // These macros handles reversing (negative)
41 #define REVERSE_FLAVOR_8(x) ((cmsUInt8Number) (0xff-(x)))
42 #define REVERSE_FLAVOR_16(x) ((cmsUInt16Number)(0xffff-(x)))
43
44 // * 0xffff / 0xff00 = (255 * 257) / (255 * 256) = 257 / 256
FomLabV2ToLabV4(cmsUInt16Number x)45 cmsINLINE cmsUInt16Number FomLabV2ToLabV4(cmsUInt16Number x)
46 {
47 int a = (x << 8 | x) >> 8; // * 257 / 256
48 if ( a > 0xffff) return 0xffff;
49 return (cmsUInt16Number) a;
50 }
51
52 // * 0xf00 / 0xffff = * 256 / 257
FomLabV4ToLabV2(cmsUInt16Number x)53 cmsINLINE cmsUInt16Number FomLabV4ToLabV2(cmsUInt16Number x)
54 {
55 return (cmsUInt16Number) (((x << 8) + 0x80) / 257);
56 }
57
58
59 typedef struct {
60 cmsUInt32Number Type;
61 cmsUInt32Number Mask;
62 cmsFormatter16 Frm;
63
64 } cmsFormatters16;
65
66 typedef struct {
67 cmsUInt32Number Type;
68 cmsUInt32Number Mask;
69 cmsFormatterFloat Frm;
70
71 } cmsFormattersFloat;
72
73
74 #define ANYSPACE COLORSPACE_SH(31)
75 #define ANYCHANNELS CHANNELS_SH(15)
76 #define ANYEXTRA EXTRA_SH(7)
77 #define ANYPLANAR PLANAR_SH(1)
78 #define ANYENDIAN ENDIAN16_SH(1)
79 #define ANYSWAP DOSWAP_SH(1)
80 #define ANYSWAPFIRST SWAPFIRST_SH(1)
81 #define ANYFLAVOR FLAVOR_SH(1)
82 #define ANYPREMUL PREMUL_SH(1)
83
84
85 // Suppress waning about info never being used
86
87 #ifdef _MSC_VER
88 #pragma warning(disable : 4100)
89 #endif
90
91 // Unpacking routines (16 bits) ----------------------------------------------------------------------------------------
92
93
94 // Does almost everything but is slow
95 static
UnrollChunkyBytes(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)96 cmsUInt8Number* UnrollChunkyBytes(CMSREGISTER _cmsTRANSFORM* info,
97 CMSREGISTER cmsUInt16Number wIn[],
98 CMSREGISTER cmsUInt8Number* accum,
99 CMSREGISTER cmsUInt32Number Stride)
100 {
101 cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
102 cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat);
103 cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat);
104 cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat);
105 cmsUInt32Number Extra = T_EXTRA(info -> InputFormat);
106 cmsUInt32Number Premul = T_PREMUL(info->InputFormat);
107
108 cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
109 cmsUInt32Number v;
110 cmsUInt32Number i;
111 cmsUInt32Number alpha_factor = 1;
112
113 if (ExtraFirst) {
114
115 if (Premul && Extra)
116 alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(accum[0]));
117
118 accum += Extra;
119 }
120 else
121 {
122 if (Premul && Extra)
123 alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(accum[nChan]));
124 }
125
126 for (i=0; i < nChan; i++) {
127
128 cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
129
130 v = FROM_8_TO_16(*accum);
131 v = Reverse ? REVERSE_FLAVOR_16(v) : v;
132
133 if (Premul && alpha_factor > 0)
134 {
135 v = ((cmsUInt32Number)((cmsUInt32Number)v << 16) / alpha_factor);
136 if (v > 0xffff) v = 0xffff;
137 }
138
139 wIn[index] = (cmsUInt16Number) v;
140 accum++;
141 }
142
143 if (!ExtraFirst) {
144 accum += Extra;
145 }
146
147 if (Extra == 0 && SwapFirst) {
148 cmsUInt16Number tmp = wIn[0];
149
150 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
151 wIn[nChan-1] = tmp;
152 }
153
154 return accum;
155
156 cmsUNUSED_PARAMETER(info);
157 cmsUNUSED_PARAMETER(Stride);
158
159 }
160
161
162 // Extra channels are just ignored because come in the next planes
163 static
UnrollPlanarBytes(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)164 cmsUInt8Number* UnrollPlanarBytes(CMSREGISTER _cmsTRANSFORM* info,
165 CMSREGISTER cmsUInt16Number wIn[],
166 CMSREGISTER cmsUInt8Number* accum,
167 CMSREGISTER cmsUInt32Number Stride)
168 {
169 cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
170 cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat);
171 cmsUInt32Number SwapFirst = T_SWAPFIRST(info ->InputFormat);
172 cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat);
173 cmsUInt32Number i;
174 cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
175 cmsUInt32Number Extra = T_EXTRA(info->InputFormat);
176 cmsUInt32Number Premul = T_PREMUL(info->InputFormat);
177 cmsUInt8Number* Init = accum;
178 cmsUInt32Number alpha_factor = 1;
179
180 if (ExtraFirst) {
181
182 if (Premul && Extra)
183 alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(accum[0]));
184
185
186 accum += Extra * Stride;
187 }
188 else
189 {
190 if (Premul && Extra)
191 alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(accum[(nChan) * Stride]));
192 }
193
194 for (i=0; i < nChan; i++) {
195
196 cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
197 cmsUInt32Number v = FROM_8_TO_16(*accum);
198
199 v = Reverse ? REVERSE_FLAVOR_16(v) : v;
200
201 if (Premul && alpha_factor > 0)
202 {
203 v = ((cmsUInt32Number)((cmsUInt32Number)v << 16) / alpha_factor);
204 if (v > 0xffff) v = 0xffff;
205 }
206
207 wIn[index] = (cmsUInt16Number) v;
208 accum += Stride;
209 }
210
211 return (Init + 1);
212 }
213
214
215 // Special cases, provided for performance
216 static
Unroll4Bytes(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)217 cmsUInt8Number* Unroll4Bytes(CMSREGISTER _cmsTRANSFORM* info,
218 CMSREGISTER cmsUInt16Number wIn[],
219 CMSREGISTER cmsUInt8Number* accum,
220 CMSREGISTER cmsUInt32Number Stride)
221 {
222 wIn[0] = FROM_8_TO_16(*accum); accum++; // C
223 wIn[1] = FROM_8_TO_16(*accum); accum++; // M
224 wIn[2] = FROM_8_TO_16(*accum); accum++; // Y
225 wIn[3] = FROM_8_TO_16(*accum); accum++; // K
226
227 return accum;
228
229 cmsUNUSED_PARAMETER(info);
230 cmsUNUSED_PARAMETER(Stride);
231 }
232
233 static
Unroll4BytesReverse(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)234 cmsUInt8Number* Unroll4BytesReverse(CMSREGISTER _cmsTRANSFORM* info,
235 CMSREGISTER cmsUInt16Number wIn[],
236 CMSREGISTER cmsUInt8Number* accum,
237 CMSREGISTER cmsUInt32Number Stride)
238 {
239 wIn[0] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // C
240 wIn[1] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // M
241 wIn[2] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // Y
242 wIn[3] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // K
243
244 return accum;
245
246 cmsUNUSED_PARAMETER(info);
247 cmsUNUSED_PARAMETER(Stride);
248 }
249
250 static
Unroll4BytesSwapFirst(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)251 cmsUInt8Number* Unroll4BytesSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
252 CMSREGISTER cmsUInt16Number wIn[],
253 CMSREGISTER cmsUInt8Number* accum,
254 CMSREGISTER cmsUInt32Number Stride)
255 {
256 wIn[3] = FROM_8_TO_16(*accum); accum++; // K
257 wIn[0] = FROM_8_TO_16(*accum); accum++; // C
258 wIn[1] = FROM_8_TO_16(*accum); accum++; // M
259 wIn[2] = FROM_8_TO_16(*accum); accum++; // Y
260
261 return accum;
262
263 cmsUNUSED_PARAMETER(info);
264 cmsUNUSED_PARAMETER(Stride);
265 }
266
267 // KYMC
268 static
Unroll4BytesSwap(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)269 cmsUInt8Number* Unroll4BytesSwap(CMSREGISTER _cmsTRANSFORM* info,
270 CMSREGISTER cmsUInt16Number wIn[],
271 CMSREGISTER cmsUInt8Number* accum,
272 CMSREGISTER cmsUInt32Number Stride)
273 {
274 wIn[3] = FROM_8_TO_16(*accum); accum++; // K
275 wIn[2] = FROM_8_TO_16(*accum); accum++; // Y
276 wIn[1] = FROM_8_TO_16(*accum); accum++; // M
277 wIn[0] = FROM_8_TO_16(*accum); accum++; // C
278
279 return accum;
280
281 cmsUNUSED_PARAMETER(info);
282 cmsUNUSED_PARAMETER(Stride);
283 }
284
285 static
Unroll4BytesSwapSwapFirst(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)286 cmsUInt8Number* Unroll4BytesSwapSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
287 CMSREGISTER cmsUInt16Number wIn[],
288 CMSREGISTER cmsUInt8Number* accum,
289 CMSREGISTER cmsUInt32Number Stride)
290 {
291 wIn[2] = FROM_8_TO_16(*accum); accum++; // K
292 wIn[1] = FROM_8_TO_16(*accum); accum++; // Y
293 wIn[0] = FROM_8_TO_16(*accum); accum++; // M
294 wIn[3] = FROM_8_TO_16(*accum); accum++; // C
295
296 return accum;
297
298 cmsUNUSED_PARAMETER(info);
299 cmsUNUSED_PARAMETER(Stride);
300 }
301
302 static
Unroll3Bytes(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)303 cmsUInt8Number* Unroll3Bytes(CMSREGISTER _cmsTRANSFORM* info,
304 CMSREGISTER cmsUInt16Number wIn[],
305 CMSREGISTER cmsUInt8Number* accum,
306 CMSREGISTER cmsUInt32Number Stride)
307 {
308 wIn[0] = FROM_8_TO_16(*accum); accum++; // R
309 wIn[1] = FROM_8_TO_16(*accum); accum++; // G
310 wIn[2] = FROM_8_TO_16(*accum); accum++; // B
311
312 return accum;
313
314 cmsUNUSED_PARAMETER(info);
315 cmsUNUSED_PARAMETER(Stride);
316 }
317
318 static
Unroll3BytesSkip1Swap(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)319 cmsUInt8Number* Unroll3BytesSkip1Swap(CMSREGISTER _cmsTRANSFORM* info,
320 CMSREGISTER cmsUInt16Number wIn[],
321 CMSREGISTER cmsUInt8Number* accum,
322 CMSREGISTER cmsUInt32Number Stride)
323 {
324 accum++; // A
325 wIn[2] = FROM_8_TO_16(*accum); accum++; // B
326 wIn[1] = FROM_8_TO_16(*accum); accum++; // G
327 wIn[0] = FROM_8_TO_16(*accum); accum++; // R
328
329 return accum;
330
331 cmsUNUSED_PARAMETER(info);
332 cmsUNUSED_PARAMETER(Stride);
333 }
334
335 static
Unroll3BytesSkip1SwapSwapFirst(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)336 cmsUInt8Number* Unroll3BytesSkip1SwapSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
337 CMSREGISTER cmsUInt16Number wIn[],
338 CMSREGISTER cmsUInt8Number* accum,
339 CMSREGISTER cmsUInt32Number Stride)
340 {
341 wIn[2] = FROM_8_TO_16(*accum); accum++; // B
342 wIn[1] = FROM_8_TO_16(*accum); accum++; // G
343 wIn[0] = FROM_8_TO_16(*accum); accum++; // R
344 accum++; // A
345
346 return accum;
347
348 cmsUNUSED_PARAMETER(info);
349 cmsUNUSED_PARAMETER(Stride);
350 }
351
352 static
Unroll3BytesSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)353 cmsUInt8Number* Unroll3BytesSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM* info,
354 CMSREGISTER cmsUInt16Number wIn[],
355 CMSREGISTER cmsUInt8Number* accum,
356 CMSREGISTER cmsUInt32Number Stride)
357 {
358 accum++; // A
359 wIn[0] = FROM_8_TO_16(*accum); accum++; // R
360 wIn[1] = FROM_8_TO_16(*accum); accum++; // G
361 wIn[2] = FROM_8_TO_16(*accum); accum++; // B
362
363 return accum;
364
365 cmsUNUSED_PARAMETER(info);
366 cmsUNUSED_PARAMETER(Stride);
367 }
368
369
370 // BRG
371 static
Unroll3BytesSwap(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)372 cmsUInt8Number* Unroll3BytesSwap(CMSREGISTER _cmsTRANSFORM* info,
373 CMSREGISTER cmsUInt16Number wIn[],
374 CMSREGISTER cmsUInt8Number* accum,
375 CMSREGISTER cmsUInt32Number Stride)
376 {
377 wIn[2] = FROM_8_TO_16(*accum); accum++; // B
378 wIn[1] = FROM_8_TO_16(*accum); accum++; // G
379 wIn[0] = FROM_8_TO_16(*accum); accum++; // R
380
381 return accum;
382
383 cmsUNUSED_PARAMETER(info);
384 cmsUNUSED_PARAMETER(Stride);
385 }
386
387 static
UnrollLabV2_8(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)388 cmsUInt8Number* UnrollLabV2_8(CMSREGISTER _cmsTRANSFORM* info,
389 CMSREGISTER cmsUInt16Number wIn[],
390 CMSREGISTER cmsUInt8Number* accum,
391 CMSREGISTER cmsUInt32Number Stride)
392 {
393 wIn[0] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // L
394 wIn[1] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // a
395 wIn[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // b
396
397 return accum;
398
399 cmsUNUSED_PARAMETER(info);
400 cmsUNUSED_PARAMETER(Stride);
401 }
402
403 static
UnrollALabV2_8(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)404 cmsUInt8Number* UnrollALabV2_8(CMSREGISTER _cmsTRANSFORM* info,
405 CMSREGISTER cmsUInt16Number wIn[],
406 CMSREGISTER cmsUInt8Number* accum,
407 CMSREGISTER cmsUInt32Number Stride)
408 {
409 accum++; // A
410 wIn[0] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // L
411 wIn[1] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // a
412 wIn[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // b
413
414 return accum;
415
416 cmsUNUSED_PARAMETER(info);
417 cmsUNUSED_PARAMETER(Stride);
418 }
419
420 static
UnrollLabV2_16(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)421 cmsUInt8Number* UnrollLabV2_16(CMSREGISTER _cmsTRANSFORM* info,
422 CMSREGISTER cmsUInt16Number wIn[],
423 CMSREGISTER cmsUInt8Number* accum,
424 CMSREGISTER cmsUInt32Number Stride)
425 {
426 wIn[0] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // L
427 wIn[1] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // a
428 wIn[2] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // b
429
430 return accum;
431
432 cmsUNUSED_PARAMETER(info);
433 cmsUNUSED_PARAMETER(Stride);
434 }
435
436 // for duplex
437 static
Unroll2Bytes(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)438 cmsUInt8Number* Unroll2Bytes(CMSREGISTER _cmsTRANSFORM* info,
439 CMSREGISTER cmsUInt16Number wIn[],
440 CMSREGISTER cmsUInt8Number* accum,
441 CMSREGISTER cmsUInt32Number Stride)
442 {
443 wIn[0] = FROM_8_TO_16(*accum); accum++; // ch1
444 wIn[1] = FROM_8_TO_16(*accum); accum++; // ch2
445
446 return accum;
447
448 cmsUNUSED_PARAMETER(info);
449 cmsUNUSED_PARAMETER(Stride);
450 }
451
452
453
454
455 // Monochrome duplicates L into RGB for null-transforms
456 static
Unroll1Byte(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)457 cmsUInt8Number* Unroll1Byte(CMSREGISTER _cmsTRANSFORM* info,
458 CMSREGISTER cmsUInt16Number wIn[],
459 CMSREGISTER cmsUInt8Number* accum,
460 CMSREGISTER cmsUInt32Number Stride)
461 {
462 wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L
463
464 return accum;
465
466 cmsUNUSED_PARAMETER(info);
467 cmsUNUSED_PARAMETER(Stride);
468 }
469
470
471 static
Unroll1ByteSkip1(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)472 cmsUInt8Number* Unroll1ByteSkip1(CMSREGISTER _cmsTRANSFORM* info,
473 CMSREGISTER cmsUInt16Number wIn[],
474 CMSREGISTER cmsUInt8Number* accum,
475 CMSREGISTER cmsUInt32Number Stride)
476 {
477 wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L
478 accum += 1;
479
480 return accum;
481
482 cmsUNUSED_PARAMETER(info);
483 cmsUNUSED_PARAMETER(Stride);
484 }
485
486 static
Unroll1ByteSkip2(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)487 cmsUInt8Number* Unroll1ByteSkip2(CMSREGISTER _cmsTRANSFORM* info,
488 CMSREGISTER cmsUInt16Number wIn[],
489 CMSREGISTER cmsUInt8Number* accum,
490 CMSREGISTER cmsUInt32Number Stride)
491 {
492 wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L
493 accum += 2;
494
495 return accum;
496
497 cmsUNUSED_PARAMETER(info);
498 cmsUNUSED_PARAMETER(Stride);
499 }
500
501 static
Unroll1ByteReversed(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)502 cmsUInt8Number* Unroll1ByteReversed(CMSREGISTER _cmsTRANSFORM* info,
503 CMSREGISTER cmsUInt16Number wIn[],
504 CMSREGISTER cmsUInt8Number* accum,
505 CMSREGISTER cmsUInt32Number Stride)
506 {
507 wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(FROM_8_TO_16(*accum)); accum++; // L
508
509 return accum;
510
511 cmsUNUSED_PARAMETER(info);
512 cmsUNUSED_PARAMETER(Stride);
513 }
514
515
516 static
UnrollAnyWords(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)517 cmsUInt8Number* UnrollAnyWords(CMSREGISTER _cmsTRANSFORM* info,
518 CMSREGISTER cmsUInt16Number wIn[],
519 CMSREGISTER cmsUInt8Number* accum,
520 CMSREGISTER cmsUInt32Number Stride)
521 {
522 cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
523 cmsUInt32Number SwapEndian = T_ENDIAN16(info -> InputFormat);
524 cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat);
525 cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat);
526 cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat);
527 cmsUInt32Number Extra = T_EXTRA(info -> InputFormat);
528 cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
529 cmsUInt32Number i;
530
531 if (ExtraFirst) {
532 accum += Extra * sizeof(cmsUInt16Number);
533 }
534
535 for (i=0; i < nChan; i++) {
536
537 cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
538 cmsUInt16Number v = *(cmsUInt16Number*) accum;
539
540 if (SwapEndian)
541 v = CHANGE_ENDIAN(v);
542
543 wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
544
545 accum += sizeof(cmsUInt16Number);
546 }
547
548 if (!ExtraFirst) {
549 accum += Extra * sizeof(cmsUInt16Number);
550 }
551
552 if (Extra == 0 && SwapFirst) {
553
554 cmsUInt16Number tmp = wIn[0];
555
556 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
557 wIn[nChan-1] = tmp;
558 }
559
560 return accum;
561
562 cmsUNUSED_PARAMETER(Stride);
563 }
564
565
566 static
UnrollAnyWordsPremul(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)567 cmsUInt8Number* UnrollAnyWordsPremul(CMSREGISTER _cmsTRANSFORM* info,
568 CMSREGISTER cmsUInt16Number wIn[],
569 CMSREGISTER cmsUInt8Number* accum,
570 CMSREGISTER cmsUInt32Number Stride)
571 {
572 cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
573 cmsUInt32Number SwapEndian = T_ENDIAN16(info -> InputFormat);
574 cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat);
575 cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat);
576 cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat);
577 cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
578 cmsUInt32Number i;
579
580 cmsUInt16Number alpha = (ExtraFirst ? accum[0] : accum[nChan - 1]);
581 cmsUInt32Number alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(alpha));
582
583 if (ExtraFirst) {
584 accum += sizeof(cmsUInt16Number);
585 }
586
587 for (i=0; i < nChan; i++) {
588
589 cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
590 cmsUInt32Number v = *(cmsUInt16Number*) accum;
591
592 if (SwapEndian)
593 v = CHANGE_ENDIAN(v);
594
595 if (alpha_factor > 0) {
596
597 v = (v << 16) / alpha_factor;
598 if (v > 0xffff) v = 0xffff;
599 }
600
601 wIn[index] = (cmsUInt16Number) (Reverse ? REVERSE_FLAVOR_16(v) : v);
602
603 accum += sizeof(cmsUInt16Number);
604 }
605
606 if (!ExtraFirst) {
607 accum += sizeof(cmsUInt16Number);
608 }
609
610 return accum;
611
612 cmsUNUSED_PARAMETER(Stride);
613 }
614
615
616
617 static
UnrollPlanarWords(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)618 cmsUInt8Number* UnrollPlanarWords(CMSREGISTER _cmsTRANSFORM* info,
619 CMSREGISTER cmsUInt16Number wIn[],
620 CMSREGISTER cmsUInt8Number* accum,
621 CMSREGISTER cmsUInt32Number Stride)
622 {
623 cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
624 cmsUInt32Number DoSwap= T_DOSWAP(info ->InputFormat);
625 cmsUInt32Number Reverse= T_FLAVOR(info ->InputFormat);
626 cmsUInt32Number SwapEndian = T_ENDIAN16(info -> InputFormat);
627 cmsUInt32Number i;
628 cmsUInt8Number* Init = accum;
629
630 if (DoSwap) {
631 accum += T_EXTRA(info -> InputFormat) * Stride;
632 }
633
634 for (i=0; i < nChan; i++) {
635
636 cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
637 cmsUInt16Number v = *(cmsUInt16Number*) accum;
638
639 if (SwapEndian)
640 v = CHANGE_ENDIAN(v);
641
642 wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
643
644 accum += Stride;
645 }
646
647 return (Init + sizeof(cmsUInt16Number));
648 }
649
650 static
UnrollPlanarWordsPremul(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)651 cmsUInt8Number* UnrollPlanarWordsPremul(CMSREGISTER _cmsTRANSFORM* info,
652 CMSREGISTER cmsUInt16Number wIn[],
653 CMSREGISTER cmsUInt8Number* accum,
654 CMSREGISTER cmsUInt32Number Stride)
655 {
656 cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
657 cmsUInt32Number DoSwap= T_DOSWAP(info ->InputFormat);
658 cmsUInt32Number SwapFirst = T_SWAPFIRST(info->InputFormat);
659 cmsUInt32Number Reverse= T_FLAVOR(info ->InputFormat);
660 cmsUInt32Number SwapEndian = T_ENDIAN16(info -> InputFormat);
661 cmsUInt32Number i;
662 cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
663 cmsUInt8Number* Init = accum;
664
665 cmsUInt16Number alpha = (ExtraFirst ? accum[0] : accum[(nChan - 1) * Stride]);
666 cmsUInt32Number alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(alpha));
667
668 if (ExtraFirst) {
669 accum += Stride;
670 }
671
672 for (i=0; i < nChan; i++) {
673
674 cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
675 cmsUInt32Number v = (cmsUInt32Number) *(cmsUInt16Number*) accum;
676
677 if (SwapEndian)
678 v = CHANGE_ENDIAN(v);
679
680 if (alpha_factor > 0) {
681
682 v = (v << 16) / alpha_factor;
683 if (v > 0xffff) v = 0xffff;
684 }
685
686 wIn[index] = (cmsUInt16Number) (Reverse ? REVERSE_FLAVOR_16(v) : v);
687
688 accum += Stride;
689 }
690
691 return (Init + sizeof(cmsUInt16Number));
692 }
693
694 static
Unroll4Words(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)695 cmsUInt8Number* Unroll4Words(CMSREGISTER _cmsTRANSFORM* info,
696 CMSREGISTER cmsUInt16Number wIn[],
697 CMSREGISTER cmsUInt8Number* accum,
698 CMSREGISTER cmsUInt32Number Stride)
699 {
700 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
701 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
702 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
703 wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
704
705 return accum;
706
707 cmsUNUSED_PARAMETER(info);
708 cmsUNUSED_PARAMETER(Stride);
709 }
710
711 static
Unroll4WordsReverse(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)712 cmsUInt8Number* Unroll4WordsReverse(CMSREGISTER _cmsTRANSFORM* info,
713 CMSREGISTER cmsUInt16Number wIn[],
714 CMSREGISTER cmsUInt8Number* accum,
715 CMSREGISTER cmsUInt32Number Stride)
716 {
717 wIn[0] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // C
718 wIn[1] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // M
719 wIn[2] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // Y
720 wIn[3] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // K
721
722 return accum;
723
724 cmsUNUSED_PARAMETER(info);
725 cmsUNUSED_PARAMETER(Stride);
726 }
727
728 static
Unroll4WordsSwapFirst(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)729 cmsUInt8Number* Unroll4WordsSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
730 CMSREGISTER cmsUInt16Number wIn[],
731 CMSREGISTER cmsUInt8Number* accum,
732 CMSREGISTER cmsUInt32Number Stride)
733 {
734 wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
735 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
736 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
737 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
738
739 return accum;
740
741 cmsUNUSED_PARAMETER(info);
742 cmsUNUSED_PARAMETER(Stride);
743 }
744
745 // KYMC
746 static
Unroll4WordsSwap(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)747 cmsUInt8Number* Unroll4WordsSwap(CMSREGISTER _cmsTRANSFORM* info,
748 CMSREGISTER cmsUInt16Number wIn[],
749 CMSREGISTER cmsUInt8Number* accum,
750 CMSREGISTER cmsUInt32Number Stride)
751 {
752 wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
753 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
754 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
755 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
756
757 return accum;
758
759 cmsUNUSED_PARAMETER(info);
760 cmsUNUSED_PARAMETER(Stride);
761 }
762
763 static
Unroll4WordsSwapSwapFirst(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)764 cmsUInt8Number* Unroll4WordsSwapSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
765 CMSREGISTER cmsUInt16Number wIn[],
766 CMSREGISTER cmsUInt8Number* accum,
767 CMSREGISTER cmsUInt32Number Stride)
768 {
769 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // K
770 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // Y
771 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // M
772 wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // C
773
774 return accum;
775
776 cmsUNUSED_PARAMETER(info);
777 cmsUNUSED_PARAMETER(Stride);
778 }
779
780 static
Unroll3Words(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)781 cmsUInt8Number* Unroll3Words(CMSREGISTER _cmsTRANSFORM* info,
782 CMSREGISTER cmsUInt16Number wIn[],
783 CMSREGISTER cmsUInt8Number* accum,
784 CMSREGISTER cmsUInt32Number Stride)
785 {
786 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C R
787 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M G
788 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y B
789
790 return accum;
791
792 cmsUNUSED_PARAMETER(info);
793 cmsUNUSED_PARAMETER(Stride);
794 }
795
796 static
Unroll3WordsSwap(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)797 cmsUInt8Number* Unroll3WordsSwap(CMSREGISTER _cmsTRANSFORM* info,
798 CMSREGISTER cmsUInt16Number wIn[],
799 CMSREGISTER cmsUInt8Number* accum,
800 CMSREGISTER cmsUInt32Number Stride)
801 {
802 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // C R
803 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M G
804 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // Y B
805
806 return accum;
807
808 cmsUNUSED_PARAMETER(info);
809 cmsUNUSED_PARAMETER(Stride);
810 }
811
812 static
Unroll3WordsSkip1Swap(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)813 cmsUInt8Number* Unroll3WordsSkip1Swap(CMSREGISTER _cmsTRANSFORM* info,
814 CMSREGISTER cmsUInt16Number wIn[],
815 CMSREGISTER cmsUInt8Number* accum,
816 CMSREGISTER cmsUInt32Number Stride)
817 {
818 accum += 2; // A
819 wIn[2] = *(cmsUInt16Number*) accum; accum += 2; // R
820 wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // G
821 wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // B
822
823 return accum;
824
825 cmsUNUSED_PARAMETER(info);
826 cmsUNUSED_PARAMETER(Stride);
827 }
828
829 static
Unroll3WordsSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)830 cmsUInt8Number* Unroll3WordsSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM* info,
831 CMSREGISTER cmsUInt16Number wIn[],
832 CMSREGISTER cmsUInt8Number* accum,
833 CMSREGISTER cmsUInt32Number Stride)
834 {
835 accum += 2; // A
836 wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // R
837 wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // G
838 wIn[2] = *(cmsUInt16Number*) accum; accum += 2; // B
839
840 return accum;
841
842 cmsUNUSED_PARAMETER(info);
843 cmsUNUSED_PARAMETER(Stride);
844 }
845
846 static
Unroll1Word(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)847 cmsUInt8Number* Unroll1Word(CMSREGISTER _cmsTRANSFORM* info,
848 CMSREGISTER cmsUInt16Number wIn[],
849 CMSREGISTER cmsUInt8Number* accum,
850 CMSREGISTER cmsUInt32Number Stride)
851 {
852 wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // L
853
854 return accum;
855
856 cmsUNUSED_PARAMETER(info);
857 cmsUNUSED_PARAMETER(Stride);
858 }
859
860 static
Unroll1WordReversed(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)861 cmsUInt8Number* Unroll1WordReversed(CMSREGISTER _cmsTRANSFORM* info,
862 CMSREGISTER cmsUInt16Number wIn[],
863 CMSREGISTER cmsUInt8Number* accum,
864 CMSREGISTER cmsUInt32Number Stride)
865 {
866 wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2;
867
868 return accum;
869
870 cmsUNUSED_PARAMETER(info);
871 cmsUNUSED_PARAMETER(Stride);
872 }
873
874 static
Unroll1WordSkip3(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)875 cmsUInt8Number* Unroll1WordSkip3(CMSREGISTER _cmsTRANSFORM* info,
876 CMSREGISTER cmsUInt16Number wIn[],
877 CMSREGISTER cmsUInt8Number* accum,
878 CMSREGISTER cmsUInt32Number Stride)
879 {
880 wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum;
881
882 accum += 8;
883
884 return accum;
885
886 cmsUNUSED_PARAMETER(info);
887 cmsUNUSED_PARAMETER(Stride);
888 }
889
890 static
Unroll2Words(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)891 cmsUInt8Number* Unroll2Words(CMSREGISTER _cmsTRANSFORM* info,
892 CMSREGISTER cmsUInt16Number wIn[],
893 CMSREGISTER cmsUInt8Number* accum,
894 CMSREGISTER cmsUInt32Number Stride)
895 {
896 wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // ch1
897 wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // ch2
898
899 return accum;
900
901 cmsUNUSED_PARAMETER(info);
902 cmsUNUSED_PARAMETER(Stride);
903 }
904
905
906 // This is a conversion of Lab double to 16 bits
907 static
UnrollLabDoubleTo16(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)908 cmsUInt8Number* UnrollLabDoubleTo16(CMSREGISTER _cmsTRANSFORM* info,
909 CMSREGISTER cmsUInt16Number wIn[],
910 CMSREGISTER cmsUInt8Number* accum,
911 CMSREGISTER cmsUInt32Number Stride)
912 {
913 if (T_PLANAR(info -> InputFormat)) {
914
915 cmsCIELab Lab;
916 cmsUInt8Number* pos_L;
917 cmsUInt8Number* pos_a;
918 cmsUInt8Number* pos_b;
919
920 pos_L = accum;
921 pos_a = accum + Stride;
922 pos_b = accum + Stride * 2;
923
924 Lab.L = *(cmsFloat64Number*) pos_L;
925 Lab.a = *(cmsFloat64Number*) pos_a;
926 Lab.b = *(cmsFloat64Number*) pos_b;
927
928 cmsFloat2LabEncoded(wIn, &Lab);
929 return accum + sizeof(cmsFloat64Number);
930 }
931 else {
932
933 cmsFloat2LabEncoded(wIn, (cmsCIELab*) accum);
934 accum += sizeof(cmsCIELab) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat64Number);
935 return accum;
936 }
937 }
938
939
940 // This is a conversion of Lab float to 16 bits
941 static
UnrollLabFloatTo16(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)942 cmsUInt8Number* UnrollLabFloatTo16(CMSREGISTER _cmsTRANSFORM* info,
943 CMSREGISTER cmsUInt16Number wIn[],
944 CMSREGISTER cmsUInt8Number* accum,
945 CMSREGISTER cmsUInt32Number Stride)
946 {
947 cmsCIELab Lab;
948
949 if (T_PLANAR(info -> InputFormat)) {
950
951 cmsUInt8Number* pos_L;
952 cmsUInt8Number* pos_a;
953 cmsUInt8Number* pos_b;
954
955 pos_L = accum;
956 pos_a = accum + Stride;
957 pos_b = accum + Stride * 2;
958
959 Lab.L = *(cmsFloat32Number*)pos_L;
960 Lab.a = *(cmsFloat32Number*)pos_a;
961 Lab.b = *(cmsFloat32Number*)pos_b;
962
963 cmsFloat2LabEncoded(wIn, &Lab);
964 return accum + sizeof(cmsFloat32Number);
965 }
966 else {
967
968 Lab.L = ((cmsFloat32Number*) accum)[0];
969 Lab.a = ((cmsFloat32Number*) accum)[1];
970 Lab.b = ((cmsFloat32Number*) accum)[2];
971
972 cmsFloat2LabEncoded(wIn, &Lab);
973 accum += (3 + T_EXTRA(info ->InputFormat)) * sizeof(cmsFloat32Number);
974 return accum;
975 }
976 }
977
978 // This is a conversion of XYZ double to 16 bits
979 static
UnrollXYZDoubleTo16(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)980 cmsUInt8Number* UnrollXYZDoubleTo16(CMSREGISTER _cmsTRANSFORM* info,
981 CMSREGISTER cmsUInt16Number wIn[],
982 CMSREGISTER cmsUInt8Number* accum,
983 CMSREGISTER cmsUInt32Number Stride)
984 {
985 if (T_PLANAR(info -> InputFormat)) {
986
987 cmsCIEXYZ XYZ;
988 cmsUInt8Number* pos_X;
989 cmsUInt8Number* pos_Y;
990 cmsUInt8Number* pos_Z;
991
992 pos_X = accum;
993 pos_Y = accum + Stride;
994 pos_Z = accum + Stride * 2;
995
996 XYZ.X = *(cmsFloat64Number*)pos_X;
997 XYZ.Y = *(cmsFloat64Number*)pos_Y;
998 XYZ.Z = *(cmsFloat64Number*)pos_Z;
999
1000 cmsFloat2XYZEncoded(wIn, &XYZ);
1001
1002 return accum + sizeof(cmsFloat64Number);
1003
1004 }
1005
1006 else {
1007 cmsFloat2XYZEncoded(wIn, (cmsCIEXYZ*) accum);
1008 accum += sizeof(cmsCIEXYZ) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat64Number);
1009
1010 return accum;
1011 }
1012 }
1013
1014 // This is a conversion of XYZ float to 16 bits
1015 static
UnrollXYZFloatTo16(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)1016 cmsUInt8Number* UnrollXYZFloatTo16(CMSREGISTER _cmsTRANSFORM* info,
1017 CMSREGISTER cmsUInt16Number wIn[],
1018 CMSREGISTER cmsUInt8Number* accum,
1019 CMSREGISTER cmsUInt32Number Stride)
1020 {
1021 if (T_PLANAR(info -> InputFormat)) {
1022
1023 cmsCIEXYZ XYZ;
1024 cmsUInt8Number* pos_X;
1025 cmsUInt8Number* pos_Y;
1026 cmsUInt8Number* pos_Z;
1027
1028 pos_X = accum;
1029 pos_Y = accum + Stride;
1030 pos_Z = accum + Stride * 2;
1031
1032 XYZ.X = *(cmsFloat32Number*)pos_X;
1033 XYZ.Y = *(cmsFloat32Number*)pos_Y;
1034 XYZ.Z = *(cmsFloat32Number*)pos_Z;
1035
1036 cmsFloat2XYZEncoded(wIn, &XYZ);
1037
1038 return accum + sizeof(cmsFloat32Number);
1039
1040 }
1041
1042 else {
1043 cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
1044 cmsCIEXYZ XYZ;
1045
1046 XYZ.X = Pt[0];
1047 XYZ.Y = Pt[1];
1048 XYZ.Z = Pt[2];
1049 cmsFloat2XYZEncoded(wIn, &XYZ);
1050
1051 accum += 3 * sizeof(cmsFloat32Number) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat32Number);
1052
1053 return accum;
1054 }
1055 }
1056
1057 // Check if space is marked as ink
IsInkSpace(cmsUInt32Number Type)1058 cmsINLINE cmsBool IsInkSpace(cmsUInt32Number Type)
1059 {
1060 switch (T_COLORSPACE(Type)) {
1061
1062 case PT_CMY:
1063 case PT_CMYK:
1064 case PT_MCH5:
1065 case PT_MCH6:
1066 case PT_MCH7:
1067 case PT_MCH8:
1068 case PT_MCH9:
1069 case PT_MCH10:
1070 case PT_MCH11:
1071 case PT_MCH12:
1072 case PT_MCH13:
1073 case PT_MCH14:
1074 case PT_MCH15: return TRUE;
1075
1076 default: return FALSE;
1077 }
1078 }
1079
1080 // Return the size in bytes of a given formatter
1081 static
PixelSize(cmsUInt32Number Format)1082 cmsUInt32Number PixelSize(cmsUInt32Number Format)
1083 {
1084 cmsUInt32Number fmt_bytes = T_BYTES(Format);
1085
1086 // For double, the T_BYTES field is zero
1087 if (fmt_bytes == 0)
1088 return sizeof(cmsUInt64Number);
1089
1090 // Otherwise, it is already correct for all formats
1091 return fmt_bytes;
1092 }
1093
1094 // Inks does come in percentage, remaining cases are between 0..1.0, again to 16 bits
1095 static
UnrollDoubleTo16(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)1096 cmsUInt8Number* UnrollDoubleTo16(CMSREGISTER _cmsTRANSFORM* info,
1097 CMSREGISTER cmsUInt16Number wIn[],
1098 CMSREGISTER cmsUInt8Number* accum,
1099 CMSREGISTER cmsUInt32Number Stride)
1100 {
1101
1102 cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
1103 cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat);
1104 cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat);
1105 cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat);
1106 cmsUInt32Number Extra = T_EXTRA(info -> InputFormat);
1107 cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
1108 cmsUInt32Number Planar = T_PLANAR(info -> InputFormat);
1109 cmsFloat64Number v;
1110 cmsUInt16Number vi;
1111 cmsUInt32Number i, start = 0;
1112 cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
1113
1114
1115 Stride /= PixelSize(info->InputFormat);
1116
1117 if (ExtraFirst)
1118 start = Extra;
1119
1120 for (i=0; i < nChan; i++) {
1121
1122 cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
1123
1124 if (Planar)
1125 v = (cmsFloat32Number) ((cmsFloat64Number*) accum)[(i + start) * Stride];
1126 else
1127 v = (cmsFloat32Number) ((cmsFloat64Number*) accum)[i + start];
1128
1129 vi = _cmsQuickSaturateWord(v * maximum);
1130
1131 if (Reverse)
1132 vi = REVERSE_FLAVOR_16(vi);
1133
1134 wIn[index] = vi;
1135 }
1136
1137
1138 if (Extra == 0 && SwapFirst) {
1139 cmsUInt16Number tmp = wIn[0];
1140
1141 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
1142 wIn[nChan-1] = tmp;
1143 }
1144
1145 if (T_PLANAR(info -> InputFormat))
1146 return accum + sizeof(cmsFloat64Number);
1147 else
1148 return accum + (nChan + Extra) * sizeof(cmsFloat64Number);
1149 }
1150
1151
1152
1153 static
UnrollFloatTo16(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)1154 cmsUInt8Number* UnrollFloatTo16(CMSREGISTER _cmsTRANSFORM* info,
1155 CMSREGISTER cmsUInt16Number wIn[],
1156 CMSREGISTER cmsUInt8Number* accum,
1157 CMSREGISTER cmsUInt32Number Stride)
1158 {
1159
1160 cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
1161 cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat);
1162 cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat);
1163 cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat);
1164 cmsUInt32Number Extra = T_EXTRA(info -> InputFormat);
1165 cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
1166 cmsUInt32Number Planar = T_PLANAR(info -> InputFormat);
1167 cmsFloat32Number v;
1168 cmsUInt16Number vi;
1169 cmsUInt32Number i, start = 0;
1170 cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
1171
1172 Stride /= PixelSize(info->InputFormat);
1173
1174 if (ExtraFirst)
1175 start = Extra;
1176
1177 for (i=0; i < nChan; i++) {
1178
1179 cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
1180
1181 if (Planar)
1182 v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[(i + start) * Stride];
1183 else
1184 v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[i + start];
1185
1186 vi = _cmsQuickSaturateWord(v * maximum);
1187
1188 if (Reverse)
1189 vi = REVERSE_FLAVOR_16(vi);
1190
1191 wIn[index] = vi;
1192 }
1193
1194
1195 if (Extra == 0 && SwapFirst) {
1196 cmsUInt16Number tmp = wIn[0];
1197
1198 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
1199 wIn[nChan-1] = tmp;
1200 }
1201
1202 if (T_PLANAR(info -> InputFormat))
1203 return accum + sizeof(cmsFloat32Number);
1204 else
1205 return accum + (nChan + Extra) * sizeof(cmsFloat32Number);
1206 }
1207
1208
1209
1210
1211 // For 1 channel, we need to duplicate data (it comes in 0..1.0 range)
1212 static
UnrollDouble1Chan(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)1213 cmsUInt8Number* UnrollDouble1Chan(CMSREGISTER _cmsTRANSFORM* info,
1214 CMSREGISTER cmsUInt16Number wIn[],
1215 CMSREGISTER cmsUInt8Number* accum,
1216 CMSREGISTER cmsUInt32Number Stride)
1217 {
1218 cmsFloat64Number* Inks = (cmsFloat64Number*) accum;
1219
1220 wIn[0] = wIn[1] = wIn[2] = _cmsQuickSaturateWord(Inks[0] * 65535.0);
1221
1222 return accum + sizeof(cmsFloat64Number);
1223
1224 cmsUNUSED_PARAMETER(info);
1225 cmsUNUSED_PARAMETER(Stride);
1226 }
1227
1228 //-------------------------------------------------------------------------------------------------------------------
1229
1230 // For anything going from cmsUInt8Number
1231 static
Unroll8ToFloat(_cmsTRANSFORM * info,cmsFloat32Number wIn[],cmsUInt8Number * accum,cmsUInt32Number Stride)1232 cmsUInt8Number* Unroll8ToFloat(_cmsTRANSFORM* info,
1233 cmsFloat32Number wIn[],
1234 cmsUInt8Number* accum,
1235 cmsUInt32Number Stride)
1236 {
1237
1238 cmsUInt32Number nChan = T_CHANNELS(info->InputFormat);
1239 cmsUInt32Number DoSwap = T_DOSWAP(info->InputFormat);
1240 cmsUInt32Number Reverse = T_FLAVOR(info->InputFormat);
1241 cmsUInt32Number SwapFirst = T_SWAPFIRST(info->InputFormat);
1242 cmsUInt32Number Extra = T_EXTRA(info->InputFormat);
1243 cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
1244 cmsUInt32Number Planar = T_PLANAR(info->InputFormat);
1245 cmsFloat32Number v;
1246 cmsUInt32Number i, start = 0;
1247
1248 Stride /= PixelSize(info->InputFormat);
1249
1250 if (ExtraFirst)
1251 start = Extra;
1252
1253 for (i = 0; i < nChan; i++) {
1254
1255 cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
1256
1257 if (Planar)
1258 v = (cmsFloat32Number) ((cmsUInt8Number *)accum)[(i + start) * Stride];
1259 else
1260 v = (cmsFloat32Number) ((cmsUInt8Number *)accum)[i + start];
1261
1262 v /= 255.0F;
1263
1264 wIn[index] = Reverse ? 1 - v : v;
1265 }
1266
1267
1268 if (Extra == 0 && SwapFirst) {
1269 cmsFloat32Number tmp = wIn[0];
1270
1271 memmove(&wIn[0], &wIn[1], (nChan - 1) * sizeof(cmsFloat32Number));
1272 wIn[nChan - 1] = tmp;
1273 }
1274
1275 if (T_PLANAR(info->InputFormat))
1276 return accum + sizeof(cmsUInt8Number);
1277 else
1278 return accum + (nChan + Extra) * sizeof(cmsUInt8Number);
1279 }
1280
1281
1282 // For anything going from cmsUInt16Number
1283 static
Unroll16ToFloat(_cmsTRANSFORM * info,cmsFloat32Number wIn[],cmsUInt8Number * accum,cmsUInt32Number Stride)1284 cmsUInt8Number* Unroll16ToFloat(_cmsTRANSFORM* info,
1285 cmsFloat32Number wIn[],
1286 cmsUInt8Number* accum,
1287 cmsUInt32Number Stride)
1288 {
1289
1290 cmsUInt32Number nChan = T_CHANNELS(info->InputFormat);
1291 cmsUInt32Number DoSwap = T_DOSWAP(info->InputFormat);
1292 cmsUInt32Number Reverse = T_FLAVOR(info->InputFormat);
1293 cmsUInt32Number SwapFirst = T_SWAPFIRST(info->InputFormat);
1294 cmsUInt32Number Extra = T_EXTRA(info->InputFormat);
1295 cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
1296 cmsUInt32Number Planar = T_PLANAR(info->InputFormat);
1297 cmsFloat32Number v;
1298 cmsUInt32Number i, start = 0;
1299
1300 Stride /= PixelSize(info->InputFormat);
1301
1302 if (ExtraFirst)
1303 start = Extra;
1304
1305 for (i = 0; i < nChan; i++) {
1306
1307 cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
1308
1309 if (Planar)
1310 v = (cmsFloat32Number)((cmsUInt16Number*)accum)[(i + start) * Stride];
1311 else
1312 v = (cmsFloat32Number)((cmsUInt16Number*)accum)[i + start];
1313
1314 v /= 65535.0F;
1315
1316 wIn[index] = Reverse ? 1 - v : v;
1317 }
1318
1319
1320 if (Extra == 0 && SwapFirst) {
1321 cmsFloat32Number tmp = wIn[0];
1322
1323 memmove(&wIn[0], &wIn[1], (nChan - 1) * sizeof(cmsFloat32Number));
1324 wIn[nChan - 1] = tmp;
1325 }
1326
1327 if (T_PLANAR(info->InputFormat))
1328 return accum + sizeof(cmsUInt16Number);
1329 else
1330 return accum + (nChan + Extra) * sizeof(cmsUInt16Number);
1331 }
1332
1333
1334 // For anything going from cmsFloat32Number
1335 static
UnrollFloatsToFloat(_cmsTRANSFORM * info,cmsFloat32Number wIn[],cmsUInt8Number * accum,cmsUInt32Number Stride)1336 cmsUInt8Number* UnrollFloatsToFloat(_cmsTRANSFORM* info,
1337 cmsFloat32Number wIn[],
1338 cmsUInt8Number* accum,
1339 cmsUInt32Number Stride)
1340 {
1341
1342 cmsUInt32Number nChan = T_CHANNELS(info->InputFormat);
1343 cmsUInt32Number DoSwap = T_DOSWAP(info->InputFormat);
1344 cmsUInt32Number Reverse = T_FLAVOR(info->InputFormat);
1345 cmsUInt32Number SwapFirst = T_SWAPFIRST(info->InputFormat);
1346 cmsUInt32Number Extra = T_EXTRA(info->InputFormat);
1347 cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
1348 cmsUInt32Number Planar = T_PLANAR(info->InputFormat);
1349 cmsUInt32Number Premul = T_PREMUL(info->InputFormat);
1350 cmsFloat32Number v;
1351 cmsUInt32Number i, start = 0;
1352 cmsFloat32Number maximum = IsInkSpace(info->InputFormat) ? 100.0F : 1.0F;
1353 cmsFloat32Number alpha_factor = 1.0f;
1354 cmsFloat32Number* ptr = (cmsFloat32Number*)accum;
1355
1356 Stride /= PixelSize(info->InputFormat);
1357
1358 if (Premul && Extra)
1359 {
1360 if (Planar)
1361 alpha_factor = (ExtraFirst ? ptr[0] : ptr[nChan * Stride]) / maximum;
1362 else
1363 alpha_factor = (ExtraFirst ? ptr[0] : ptr[nChan]) / maximum;
1364 }
1365
1366 if (ExtraFirst)
1367 start = Extra;
1368
1369 for (i=0; i < nChan; i++) {
1370
1371 cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
1372
1373 if (Planar)
1374 v = ptr[(i + start) * Stride];
1375 else
1376 v = ptr[i + start];
1377
1378 if (Premul && alpha_factor > 0)
1379 v /= alpha_factor;
1380
1381 v /= maximum;
1382
1383 wIn[index] = Reverse ? 1 - v : v;
1384 }
1385
1386
1387 if (Extra == 0 && SwapFirst) {
1388 cmsFloat32Number tmp = wIn[0];
1389
1390 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number));
1391 wIn[nChan-1] = tmp;
1392 }
1393
1394 if (T_PLANAR(info -> InputFormat))
1395 return accum + sizeof(cmsFloat32Number);
1396 else
1397 return accum + (nChan + Extra) * sizeof(cmsFloat32Number);
1398 }
1399
1400 // For anything going from double
1401
1402 static
UnrollDoublesToFloat(_cmsTRANSFORM * info,cmsFloat32Number wIn[],cmsUInt8Number * accum,cmsUInt32Number Stride)1403 cmsUInt8Number* UnrollDoublesToFloat(_cmsTRANSFORM* info,
1404 cmsFloat32Number wIn[],
1405 cmsUInt8Number* accum,
1406 cmsUInt32Number Stride)
1407 {
1408
1409 cmsUInt32Number nChan = T_CHANNELS(info->InputFormat);
1410 cmsUInt32Number DoSwap = T_DOSWAP(info->InputFormat);
1411 cmsUInt32Number Reverse = T_FLAVOR(info->InputFormat);
1412 cmsUInt32Number SwapFirst = T_SWAPFIRST(info->InputFormat);
1413 cmsUInt32Number Extra = T_EXTRA(info->InputFormat);
1414 cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
1415 cmsUInt32Number Planar = T_PLANAR(info->InputFormat);
1416 cmsUInt32Number Premul = T_PREMUL(info->InputFormat);
1417 cmsFloat64Number v;
1418 cmsUInt32Number i, start = 0;
1419 cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 100.0 : 1.0;
1420 cmsFloat64Number alpha_factor = 1.0;
1421 cmsFloat64Number* ptr = (cmsFloat64Number*)accum;
1422
1423 Stride /= PixelSize(info->InputFormat);
1424
1425 if (Premul && Extra)
1426 {
1427 if (Planar)
1428 alpha_factor = (ExtraFirst ? ptr[0] : ptr[(nChan) * Stride]) / maximum;
1429 else
1430 alpha_factor = (ExtraFirst ? ptr[0] : ptr[nChan]) / maximum;
1431 }
1432
1433 if (ExtraFirst)
1434 start = Extra;
1435
1436 for (i=0; i < nChan; i++) {
1437
1438 cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
1439
1440 if (Planar)
1441 v = (cmsFloat64Number) ((cmsFloat64Number*) accum)[(i + start) * Stride];
1442 else
1443 v = (cmsFloat64Number) ((cmsFloat64Number*) accum)[i + start];
1444
1445
1446 if (Premul && alpha_factor > 0)
1447 v /= alpha_factor;
1448
1449 v /= maximum;
1450
1451 wIn[index] = (cmsFloat32Number) (Reverse ? 1.0 - v : v);
1452 }
1453
1454
1455 if (Extra == 0 && SwapFirst) {
1456 cmsFloat32Number tmp = wIn[0];
1457
1458 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number));
1459 wIn[nChan-1] = tmp;
1460 }
1461
1462 if (T_PLANAR(info -> InputFormat))
1463 return accum + sizeof(cmsFloat64Number);
1464 else
1465 return accum + (nChan + Extra) * sizeof(cmsFloat64Number);
1466 }
1467
1468
1469
1470 // From Lab double to cmsFloat32Number
1471 static
UnrollLabDoubleToFloat(_cmsTRANSFORM * info,cmsFloat32Number wIn[],cmsUInt8Number * accum,cmsUInt32Number Stride)1472 cmsUInt8Number* UnrollLabDoubleToFloat(_cmsTRANSFORM* info,
1473 cmsFloat32Number wIn[],
1474 cmsUInt8Number* accum,
1475 cmsUInt32Number Stride)
1476 {
1477 cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
1478
1479 if (T_PLANAR(info -> InputFormat)) {
1480
1481 Stride /= PixelSize(info->InputFormat);
1482
1483 wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
1484 wIn[1] = (cmsFloat32Number) ((Pt[Stride] + 128) / 255.0); // form -128..+127 to 0..1
1485 wIn[2] = (cmsFloat32Number) ((Pt[Stride*2] + 128) / 255.0);
1486
1487 return accum + sizeof(cmsFloat64Number);
1488 }
1489 else {
1490
1491 wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
1492 wIn[1] = (cmsFloat32Number) ((Pt[1] + 128) / 255.0); // form -128..+127 to 0..1
1493 wIn[2] = (cmsFloat32Number) ((Pt[2] + 128) / 255.0);
1494
1495 accum += sizeof(cmsFloat64Number)*(3 + T_EXTRA(info ->InputFormat));
1496 return accum;
1497 }
1498 }
1499
1500 // From Lab double to cmsFloat32Number
1501 static
UnrollLabFloatToFloat(_cmsTRANSFORM * info,cmsFloat32Number wIn[],cmsUInt8Number * accum,cmsUInt32Number Stride)1502 cmsUInt8Number* UnrollLabFloatToFloat(_cmsTRANSFORM* info,
1503 cmsFloat32Number wIn[],
1504 cmsUInt8Number* accum,
1505 cmsUInt32Number Stride)
1506 {
1507 cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
1508
1509 if (T_PLANAR(info -> InputFormat)) {
1510
1511 Stride /= PixelSize(info->InputFormat);
1512
1513 wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
1514 wIn[1] = (cmsFloat32Number) ((Pt[Stride] + 128) / 255.0); // form -128..+127 to 0..1
1515 wIn[2] = (cmsFloat32Number) ((Pt[Stride*2] + 128) / 255.0);
1516
1517 return accum + sizeof(cmsFloat32Number);
1518 }
1519 else {
1520
1521 wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
1522 wIn[1] = (cmsFloat32Number) ((Pt[1] + 128) / 255.0); // form -128..+127 to 0..1
1523 wIn[2] = (cmsFloat32Number) ((Pt[2] + 128) / 255.0);
1524
1525 accum += sizeof(cmsFloat32Number)*(3 + T_EXTRA(info ->InputFormat));
1526 return accum;
1527 }
1528 }
1529
1530 // 1.15 fixed point, that means maximum value is MAX_ENCODEABLE_XYZ (0xFFFF)
1531 static
UnrollXYZDoubleToFloat(_cmsTRANSFORM * info,cmsFloat32Number wIn[],cmsUInt8Number * accum,cmsUInt32Number Stride)1532 cmsUInt8Number* UnrollXYZDoubleToFloat(_cmsTRANSFORM* info,
1533 cmsFloat32Number wIn[],
1534 cmsUInt8Number* accum,
1535 cmsUInt32Number Stride)
1536 {
1537 cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
1538
1539 if (T_PLANAR(info -> InputFormat)) {
1540
1541 Stride /= PixelSize(info->InputFormat);
1542
1543 wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
1544 wIn[1] = (cmsFloat32Number) (Pt[Stride] / MAX_ENCODEABLE_XYZ);
1545 wIn[2] = (cmsFloat32Number) (Pt[Stride*2] / MAX_ENCODEABLE_XYZ);
1546
1547 return accum + sizeof(cmsFloat64Number);
1548 }
1549 else {
1550
1551 wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
1552 wIn[1] = (cmsFloat32Number) (Pt[1] / MAX_ENCODEABLE_XYZ);
1553 wIn[2] = (cmsFloat32Number) (Pt[2] / MAX_ENCODEABLE_XYZ);
1554
1555 accum += sizeof(cmsFloat64Number)*(3 + T_EXTRA(info ->InputFormat));
1556 return accum;
1557 }
1558 }
1559
1560 static
UnrollXYZFloatToFloat(_cmsTRANSFORM * info,cmsFloat32Number wIn[],cmsUInt8Number * accum,cmsUInt32Number Stride)1561 cmsUInt8Number* UnrollXYZFloatToFloat(_cmsTRANSFORM* info,
1562 cmsFloat32Number wIn[],
1563 cmsUInt8Number* accum,
1564 cmsUInt32Number Stride)
1565 {
1566 cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
1567
1568 if (T_PLANAR(info -> InputFormat)) {
1569
1570 Stride /= PixelSize(info->InputFormat);
1571
1572 wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
1573 wIn[1] = (cmsFloat32Number) (Pt[Stride] / MAX_ENCODEABLE_XYZ);
1574 wIn[2] = (cmsFloat32Number) (Pt[Stride*2] / MAX_ENCODEABLE_XYZ);
1575
1576 return accum + sizeof(cmsFloat32Number);
1577 }
1578 else {
1579
1580 wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
1581 wIn[1] = (cmsFloat32Number) (Pt[1] / MAX_ENCODEABLE_XYZ);
1582 wIn[2] = (cmsFloat32Number) (Pt[2] / MAX_ENCODEABLE_XYZ);
1583
1584 accum += sizeof(cmsFloat32Number)*(3 + T_EXTRA(info ->InputFormat));
1585 return accum;
1586 }
1587 }
1588
1589
lab4toFloat(cmsFloat32Number wIn[],cmsUInt16Number lab4[3])1590 cmsINLINE void lab4toFloat(cmsFloat32Number wIn[], cmsUInt16Number lab4[3])
1591 {
1592 cmsFloat32Number L = (cmsFloat32Number) lab4[0] / 655.35F;
1593 cmsFloat32Number a = ((cmsFloat32Number) lab4[1] / 257.0F) - 128.0F;
1594 cmsFloat32Number b = ((cmsFloat32Number) lab4[2] / 257.0F) - 128.0F;
1595
1596 wIn[0] = (L / 100.0F); // from 0..100 to 0..1
1597 wIn[1] = ((a + 128.0F) / 255.0F); // form -128..+127 to 0..1
1598 wIn[2] = ((b + 128.0F) / 255.0F);
1599
1600 }
1601
1602 static
UnrollLabV2_8ToFloat(_cmsTRANSFORM * info,cmsFloat32Number wIn[],cmsUInt8Number * accum,cmsUInt32Number Stride)1603 cmsUInt8Number* UnrollLabV2_8ToFloat(_cmsTRANSFORM* info,
1604 cmsFloat32Number wIn[],
1605 cmsUInt8Number* accum,
1606 cmsUInt32Number Stride)
1607 {
1608 cmsUInt16Number lab4[3];
1609
1610 lab4[0] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // L
1611 lab4[1] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // a
1612 lab4[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // b
1613
1614 lab4toFloat(wIn, lab4);
1615
1616 return accum;
1617
1618 cmsUNUSED_PARAMETER(info);
1619 cmsUNUSED_PARAMETER(Stride);
1620 }
1621
1622 static
UnrollALabV2_8ToFloat(_cmsTRANSFORM * info,cmsFloat32Number wIn[],cmsUInt8Number * accum,cmsUInt32Number Stride)1623 cmsUInt8Number* UnrollALabV2_8ToFloat(_cmsTRANSFORM* info,
1624 cmsFloat32Number wIn[],
1625 cmsUInt8Number* accum,
1626 cmsUInt32Number Stride)
1627 {
1628 cmsUInt16Number lab4[3];
1629
1630 accum++; // A
1631 lab4[0] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // L
1632 lab4[1] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // a
1633 lab4[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // b
1634
1635 lab4toFloat(wIn, lab4);
1636
1637 return accum;
1638
1639 cmsUNUSED_PARAMETER(info);
1640 cmsUNUSED_PARAMETER(Stride);
1641 }
1642
1643 static
UnrollLabV2_16ToFloat(_cmsTRANSFORM * info,cmsFloat32Number wIn[],cmsUInt8Number * accum,cmsUInt32Number Stride)1644 cmsUInt8Number* UnrollLabV2_16ToFloat(_cmsTRANSFORM* info,
1645 cmsFloat32Number wIn[],
1646 cmsUInt8Number* accum,
1647 cmsUInt32Number Stride)
1648 {
1649 cmsUInt16Number lab4[3];
1650
1651 lab4[0] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // L
1652 lab4[1] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // a
1653 lab4[2] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // b
1654
1655 lab4toFloat(wIn, lab4);
1656
1657 return accum;
1658
1659 cmsUNUSED_PARAMETER(info);
1660 cmsUNUSED_PARAMETER(Stride);
1661 }
1662
1663
1664 // Packing routines -----------------------------------------------------------------------------------------------------------
1665
1666
1667 // Generic chunky for byte
1668 static
PackChunkyBytes(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)1669 cmsUInt8Number* PackChunkyBytes(CMSREGISTER _cmsTRANSFORM* info,
1670 CMSREGISTER cmsUInt16Number wOut[],
1671 CMSREGISTER cmsUInt8Number* output,
1672 CMSREGISTER cmsUInt32Number Stride)
1673 {
1674 cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat);
1675 cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat);
1676 cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat);
1677 cmsUInt32Number Extra = T_EXTRA(info->OutputFormat);
1678 cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat);
1679 cmsUInt32Number Premul = T_PREMUL(info->OutputFormat);
1680 cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
1681 cmsUInt8Number* swap1;
1682 cmsUInt16Number v = 0;
1683 cmsUInt32Number i;
1684 cmsUInt32Number alpha_factor = 0;
1685
1686 swap1 = output;
1687
1688 if (ExtraFirst) {
1689
1690 if (Premul && Extra)
1691 alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(output[0]));
1692
1693 output += Extra;
1694 }
1695 else
1696 {
1697 if (Premul && Extra)
1698 alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(output[nChan]));
1699 }
1700
1701 for (i=0; i < nChan; i++) {
1702
1703 cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
1704
1705 v = wOut[index];
1706
1707 if (Reverse)
1708 v = REVERSE_FLAVOR_16(v);
1709
1710 if (Premul)
1711 {
1712 v = (cmsUInt16Number)((cmsUInt32Number)((cmsUInt32Number)v * alpha_factor + 0x8000) >> 16);
1713 }
1714
1715 *output++ = FROM_16_TO_8(v);
1716 }
1717
1718 if (!ExtraFirst) {
1719 output += Extra;
1720 }
1721
1722 if (Extra == 0 && SwapFirst) {
1723
1724 memmove(swap1 + 1, swap1, nChan-1);
1725 *swap1 = FROM_16_TO_8(v);
1726 }
1727
1728 return output;
1729
1730 cmsUNUSED_PARAMETER(Stride);
1731 }
1732
1733 static
PackChunkyWords(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)1734 cmsUInt8Number* PackChunkyWords(CMSREGISTER _cmsTRANSFORM* info,
1735 CMSREGISTER cmsUInt16Number wOut[],
1736 CMSREGISTER cmsUInt8Number* output,
1737 CMSREGISTER cmsUInt32Number Stride)
1738 {
1739 cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat);
1740 cmsUInt32Number SwapEndian = T_ENDIAN16(info->OutputFormat);
1741 cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat);
1742 cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat);
1743 cmsUInt32Number Extra = T_EXTRA(info->OutputFormat);
1744 cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat);
1745 cmsUInt32Number Premul = T_PREMUL(info->OutputFormat);
1746 cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
1747 cmsUInt16Number* swap1;
1748 cmsUInt16Number v = 0;
1749 cmsUInt32Number i;
1750 cmsUInt32Number alpha_factor = 0;
1751
1752 swap1 = (cmsUInt16Number*) output;
1753
1754 if (ExtraFirst) {
1755
1756 if (Premul && Extra)
1757 alpha_factor = _cmsToFixedDomain(*(cmsUInt16Number*) output);
1758
1759 output += Extra * sizeof(cmsUInt16Number);
1760 }
1761 else
1762 {
1763 if (Premul && Extra)
1764 alpha_factor = _cmsToFixedDomain(((cmsUInt16Number*) output)[nChan]);
1765 }
1766
1767 for (i=0; i < nChan; i++) {
1768
1769 cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
1770
1771 v = wOut[index];
1772
1773 if (SwapEndian)
1774 v = CHANGE_ENDIAN(v);
1775
1776 if (Reverse)
1777 v = REVERSE_FLAVOR_16(v);
1778
1779 if (Premul)
1780 {
1781 v = (cmsUInt16Number)((cmsUInt32Number)((cmsUInt32Number)v * alpha_factor + 0x8000) >> 16);
1782 }
1783
1784 *(cmsUInt16Number*) output = v;
1785
1786 output += sizeof(cmsUInt16Number);
1787 }
1788
1789 if (!ExtraFirst) {
1790 output += Extra * sizeof(cmsUInt16Number);
1791 }
1792
1793 if (Extra == 0 && SwapFirst) {
1794
1795 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number));
1796 *swap1 = v;
1797 }
1798
1799 return output;
1800
1801 cmsUNUSED_PARAMETER(Stride);
1802 }
1803
1804
1805
1806 static
PackPlanarBytes(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)1807 cmsUInt8Number* PackPlanarBytes(CMSREGISTER _cmsTRANSFORM* info,
1808 CMSREGISTER cmsUInt16Number wOut[],
1809 CMSREGISTER cmsUInt8Number* output,
1810 CMSREGISTER cmsUInt32Number Stride)
1811 {
1812 cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat);
1813 cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat);
1814 cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat);
1815 cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat);
1816 cmsUInt32Number Extra = T_EXTRA(info->OutputFormat);
1817 cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
1818 cmsUInt32Number Premul = T_PREMUL(info->OutputFormat);
1819 cmsUInt32Number i;
1820 cmsUInt8Number* Init = output;
1821 cmsUInt32Number alpha_factor = 0;
1822
1823
1824 if (ExtraFirst) {
1825
1826 if (Premul && Extra)
1827 alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(output[0]));
1828
1829 output += Extra * Stride;
1830 }
1831 else
1832 {
1833 if (Premul && Extra)
1834 alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(output[nChan * Stride]));
1835 }
1836
1837
1838 for (i=0; i < nChan; i++) {
1839
1840 cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
1841 cmsUInt16Number v = wOut[index];
1842
1843 if (Reverse)
1844 v = REVERSE_FLAVOR_16(v);
1845
1846 if (Premul)
1847 {
1848 v = (cmsUInt16Number)((cmsUInt32Number)((cmsUInt32Number)v * alpha_factor + 0x8000) >> 16);
1849 }
1850
1851 *(cmsUInt8Number*)output = FROM_16_TO_8(v);
1852
1853 output += Stride;
1854 }
1855
1856 return (Init + 1);
1857
1858 cmsUNUSED_PARAMETER(Stride);
1859 }
1860
1861
1862 static
PackPlanarWords(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)1863 cmsUInt8Number* PackPlanarWords(CMSREGISTER _cmsTRANSFORM* info,
1864 CMSREGISTER cmsUInt16Number wOut[],
1865 CMSREGISTER cmsUInt8Number* output,
1866 CMSREGISTER cmsUInt32Number Stride)
1867 {
1868 cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat);
1869 cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat);
1870 cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat);
1871 cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat);
1872 cmsUInt32Number Extra = T_EXTRA(info->OutputFormat);
1873 cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
1874 cmsUInt32Number Premul = T_PREMUL(info->OutputFormat);
1875 cmsUInt32Number SwapEndian = T_ENDIAN16(info->OutputFormat);
1876 cmsUInt32Number i;
1877 cmsUInt8Number* Init = output;
1878 cmsUInt16Number v;
1879 cmsUInt32Number alpha_factor = 0;
1880
1881 if (ExtraFirst) {
1882
1883 if (Premul && Extra)
1884 alpha_factor = _cmsToFixedDomain(((cmsUInt16Number*) output)[0]);
1885
1886 output += Extra * Stride;
1887 }
1888 else
1889 {
1890 if (Premul && Extra)
1891 alpha_factor = _cmsToFixedDomain(((cmsUInt16Number*)output)[nChan * Stride]);
1892 }
1893
1894 for (i=0; i < nChan; i++) {
1895
1896 cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
1897
1898 v = wOut[index];
1899
1900 if (SwapEndian)
1901 v = CHANGE_ENDIAN(v);
1902
1903 if (Reverse)
1904 v = REVERSE_FLAVOR_16(v);
1905
1906 if (Premul)
1907 {
1908 v = (cmsUInt16Number)((cmsUInt32Number)((cmsUInt32Number)v * alpha_factor + 0x8000) >> 16);
1909 }
1910
1911 *(cmsUInt16Number*) output = v;
1912 output += Stride;
1913 }
1914
1915 return (Init + sizeof(cmsUInt16Number));
1916 }
1917
1918 // CMYKcm (unrolled for speed)
1919
1920 static
Pack6Bytes(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)1921 cmsUInt8Number* Pack6Bytes(CMSREGISTER _cmsTRANSFORM* info,
1922 CMSREGISTER cmsUInt16Number wOut[],
1923 CMSREGISTER cmsUInt8Number* output,
1924 CMSREGISTER cmsUInt32Number Stride)
1925 {
1926 *output++ = FROM_16_TO_8(wOut[0]);
1927 *output++ = FROM_16_TO_8(wOut[1]);
1928 *output++ = FROM_16_TO_8(wOut[2]);
1929 *output++ = FROM_16_TO_8(wOut[3]);
1930 *output++ = FROM_16_TO_8(wOut[4]);
1931 *output++ = FROM_16_TO_8(wOut[5]);
1932
1933 return output;
1934
1935 cmsUNUSED_PARAMETER(info);
1936 cmsUNUSED_PARAMETER(Stride);
1937 }
1938
1939 // KCMYcm
1940
1941 static
Pack6BytesSwap(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)1942 cmsUInt8Number* Pack6BytesSwap(CMSREGISTER _cmsTRANSFORM* info,
1943 CMSREGISTER cmsUInt16Number wOut[],
1944 CMSREGISTER cmsUInt8Number* output,
1945 CMSREGISTER cmsUInt32Number Stride)
1946 {
1947 *output++ = FROM_16_TO_8(wOut[5]);
1948 *output++ = FROM_16_TO_8(wOut[4]);
1949 *output++ = FROM_16_TO_8(wOut[3]);
1950 *output++ = FROM_16_TO_8(wOut[2]);
1951 *output++ = FROM_16_TO_8(wOut[1]);
1952 *output++ = FROM_16_TO_8(wOut[0]);
1953
1954 return output;
1955
1956 cmsUNUSED_PARAMETER(info);
1957 cmsUNUSED_PARAMETER(Stride);
1958 }
1959
1960 // CMYKcm
1961 static
Pack6Words(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)1962 cmsUInt8Number* Pack6Words(CMSREGISTER _cmsTRANSFORM* info,
1963 CMSREGISTER cmsUInt16Number wOut[],
1964 CMSREGISTER cmsUInt8Number* output,
1965 CMSREGISTER cmsUInt32Number Stride)
1966 {
1967 *(cmsUInt16Number*) output = wOut[0];
1968 output+= 2;
1969 *(cmsUInt16Number*) output = wOut[1];
1970 output+= 2;
1971 *(cmsUInt16Number*) output = wOut[2];
1972 output+= 2;
1973 *(cmsUInt16Number*) output = wOut[3];
1974 output+= 2;
1975 *(cmsUInt16Number*) output = wOut[4];
1976 output+= 2;
1977 *(cmsUInt16Number*) output = wOut[5];
1978 output+= 2;
1979
1980 return output;
1981
1982 cmsUNUSED_PARAMETER(info);
1983 cmsUNUSED_PARAMETER(Stride);
1984 }
1985
1986 // KCMYcm
1987 static
Pack6WordsSwap(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)1988 cmsUInt8Number* Pack6WordsSwap(CMSREGISTER _cmsTRANSFORM* info,
1989 CMSREGISTER cmsUInt16Number wOut[],
1990 CMSREGISTER cmsUInt8Number* output,
1991 CMSREGISTER cmsUInt32Number Stride)
1992 {
1993 *(cmsUInt16Number*) output = wOut[5];
1994 output+= 2;
1995 *(cmsUInt16Number*) output = wOut[4];
1996 output+= 2;
1997 *(cmsUInt16Number*) output = wOut[3];
1998 output+= 2;
1999 *(cmsUInt16Number*) output = wOut[2];
2000 output+= 2;
2001 *(cmsUInt16Number*) output = wOut[1];
2002 output+= 2;
2003 *(cmsUInt16Number*) output = wOut[0];
2004 output+= 2;
2005
2006 return output;
2007
2008 cmsUNUSED_PARAMETER(info);
2009 cmsUNUSED_PARAMETER(Stride);
2010 }
2011
2012
2013 static
Pack4Bytes(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2014 cmsUInt8Number* Pack4Bytes(CMSREGISTER _cmsTRANSFORM* info,
2015 CMSREGISTER cmsUInt16Number wOut[],
2016 CMSREGISTER cmsUInt8Number* output,
2017 CMSREGISTER cmsUInt32Number Stride)
2018 {
2019 *output++ = FROM_16_TO_8(wOut[0]);
2020 *output++ = FROM_16_TO_8(wOut[1]);
2021 *output++ = FROM_16_TO_8(wOut[2]);
2022 *output++ = FROM_16_TO_8(wOut[3]);
2023
2024 return output;
2025
2026 cmsUNUSED_PARAMETER(info);
2027 cmsUNUSED_PARAMETER(Stride);
2028 }
2029
2030 static
Pack4BytesReverse(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2031 cmsUInt8Number* Pack4BytesReverse(CMSREGISTER _cmsTRANSFORM* info,
2032 CMSREGISTER cmsUInt16Number wOut[],
2033 CMSREGISTER cmsUInt8Number* output,
2034 CMSREGISTER cmsUInt32Number Stride)
2035 {
2036 *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[0]));
2037 *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[1]));
2038 *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[2]));
2039 *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[3]));
2040
2041 return output;
2042
2043 cmsUNUSED_PARAMETER(info);
2044 cmsUNUSED_PARAMETER(Stride);
2045 }
2046
2047
2048 static
Pack4BytesSwapFirst(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2049 cmsUInt8Number* Pack4BytesSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
2050 CMSREGISTER cmsUInt16Number wOut[],
2051 CMSREGISTER cmsUInt8Number* output,
2052 CMSREGISTER cmsUInt32Number Stride)
2053 {
2054 *output++ = FROM_16_TO_8(wOut[3]);
2055 *output++ = FROM_16_TO_8(wOut[0]);
2056 *output++ = FROM_16_TO_8(wOut[1]);
2057 *output++ = FROM_16_TO_8(wOut[2]);
2058
2059 return output;
2060
2061 cmsUNUSED_PARAMETER(info);
2062 cmsUNUSED_PARAMETER(Stride);
2063 }
2064
2065 // ABGR
2066 static
Pack4BytesSwap(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2067 cmsUInt8Number* Pack4BytesSwap(CMSREGISTER _cmsTRANSFORM* info,
2068 CMSREGISTER cmsUInt16Number wOut[],
2069 CMSREGISTER cmsUInt8Number* output,
2070 CMSREGISTER cmsUInt32Number Stride)
2071 {
2072 *output++ = FROM_16_TO_8(wOut[3]);
2073 *output++ = FROM_16_TO_8(wOut[2]);
2074 *output++ = FROM_16_TO_8(wOut[1]);
2075 *output++ = FROM_16_TO_8(wOut[0]);
2076
2077 return output;
2078
2079 cmsUNUSED_PARAMETER(info);
2080 cmsUNUSED_PARAMETER(Stride);
2081 }
2082
2083 static
Pack4BytesSwapSwapFirst(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2084 cmsUInt8Number* Pack4BytesSwapSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
2085 CMSREGISTER cmsUInt16Number wOut[],
2086 CMSREGISTER cmsUInt8Number* output,
2087 CMSREGISTER cmsUInt32Number Stride)
2088 {
2089 *output++ = FROM_16_TO_8(wOut[2]);
2090 *output++ = FROM_16_TO_8(wOut[1]);
2091 *output++ = FROM_16_TO_8(wOut[0]);
2092 *output++ = FROM_16_TO_8(wOut[3]);
2093
2094 return output;
2095
2096 cmsUNUSED_PARAMETER(info);
2097 cmsUNUSED_PARAMETER(Stride);
2098 }
2099
2100 static
Pack4Words(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2101 cmsUInt8Number* Pack4Words(CMSREGISTER _cmsTRANSFORM* info,
2102 CMSREGISTER cmsUInt16Number wOut[],
2103 CMSREGISTER cmsUInt8Number* output,
2104 CMSREGISTER cmsUInt32Number Stride)
2105 {
2106 *(cmsUInt16Number*) output = wOut[0];
2107 output+= 2;
2108 *(cmsUInt16Number*) output = wOut[1];
2109 output+= 2;
2110 *(cmsUInt16Number*) output = wOut[2];
2111 output+= 2;
2112 *(cmsUInt16Number*) output = wOut[3];
2113 output+= 2;
2114
2115 return output;
2116
2117 cmsUNUSED_PARAMETER(info);
2118 cmsUNUSED_PARAMETER(Stride);
2119 }
2120
2121 static
Pack4WordsReverse(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2122 cmsUInt8Number* Pack4WordsReverse(CMSREGISTER _cmsTRANSFORM* info,
2123 CMSREGISTER cmsUInt16Number wOut[],
2124 CMSREGISTER cmsUInt8Number* output,
2125 CMSREGISTER cmsUInt32Number Stride)
2126 {
2127 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[0]);
2128 output+= 2;
2129 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[1]);
2130 output+= 2;
2131 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[2]);
2132 output+= 2;
2133 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[3]);
2134 output+= 2;
2135
2136 return output;
2137
2138 cmsUNUSED_PARAMETER(info);
2139 cmsUNUSED_PARAMETER(Stride);
2140 }
2141
2142 // ABGR
2143 static
Pack4WordsSwap(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2144 cmsUInt8Number* Pack4WordsSwap(CMSREGISTER _cmsTRANSFORM* info,
2145 CMSREGISTER cmsUInt16Number wOut[],
2146 CMSREGISTER cmsUInt8Number* output,
2147 CMSREGISTER cmsUInt32Number Stride)
2148 {
2149 *(cmsUInt16Number*) output = wOut[3];
2150 output+= 2;
2151 *(cmsUInt16Number*) output = wOut[2];
2152 output+= 2;
2153 *(cmsUInt16Number*) output = wOut[1];
2154 output+= 2;
2155 *(cmsUInt16Number*) output = wOut[0];
2156 output+= 2;
2157
2158 return output;
2159
2160 cmsUNUSED_PARAMETER(info);
2161 cmsUNUSED_PARAMETER(Stride);
2162 }
2163
2164 // CMYK
2165 static
Pack4WordsBigEndian(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2166 cmsUInt8Number* Pack4WordsBigEndian(CMSREGISTER _cmsTRANSFORM* info,
2167 CMSREGISTER cmsUInt16Number wOut[],
2168 CMSREGISTER cmsUInt8Number* output,
2169 CMSREGISTER cmsUInt32Number Stride)
2170 {
2171 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
2172 output+= 2;
2173 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[1]);
2174 output+= 2;
2175 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[2]);
2176 output+= 2;
2177 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[3]);
2178 output+= 2;
2179
2180 return output;
2181
2182 cmsUNUSED_PARAMETER(info);
2183 cmsUNUSED_PARAMETER(Stride);
2184 }
2185
2186
2187 static
PackLabV2_8(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2188 cmsUInt8Number* PackLabV2_8(CMSREGISTER _cmsTRANSFORM* info,
2189 CMSREGISTER cmsUInt16Number wOut[],
2190 CMSREGISTER cmsUInt8Number* output,
2191 CMSREGISTER cmsUInt32Number Stride)
2192 {
2193 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[0]));
2194 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[1]));
2195 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[2]));
2196
2197 return output;
2198
2199 cmsUNUSED_PARAMETER(info);
2200 cmsUNUSED_PARAMETER(Stride);
2201 }
2202
2203 static
PackALabV2_8(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2204 cmsUInt8Number* PackALabV2_8(CMSREGISTER _cmsTRANSFORM* info,
2205 CMSREGISTER cmsUInt16Number wOut[],
2206 CMSREGISTER cmsUInt8Number* output,
2207 CMSREGISTER cmsUInt32Number Stride)
2208 {
2209 output++;
2210 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[0]));
2211 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[1]));
2212 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[2]));
2213
2214 return output;
2215
2216 cmsUNUSED_PARAMETER(info);
2217 cmsUNUSED_PARAMETER(Stride);
2218 }
2219
2220 static
PackLabV2_16(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2221 cmsUInt8Number* PackLabV2_16(CMSREGISTER _cmsTRANSFORM* info,
2222 CMSREGISTER cmsUInt16Number wOut[],
2223 CMSREGISTER cmsUInt8Number* output,
2224 CMSREGISTER cmsUInt32Number Stride)
2225 {
2226 *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[0]);
2227 output += 2;
2228 *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[1]);
2229 output += 2;
2230 *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[2]);
2231 output += 2;
2232
2233 return output;
2234
2235 cmsUNUSED_PARAMETER(info);
2236 cmsUNUSED_PARAMETER(Stride);
2237 }
2238
2239 static
Pack3Bytes(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2240 cmsUInt8Number* Pack3Bytes(CMSREGISTER _cmsTRANSFORM* info,
2241 CMSREGISTER cmsUInt16Number wOut[],
2242 CMSREGISTER cmsUInt8Number* output,
2243 CMSREGISTER cmsUInt32Number Stride)
2244 {
2245 *output++ = FROM_16_TO_8(wOut[0]);
2246 *output++ = FROM_16_TO_8(wOut[1]);
2247 *output++ = FROM_16_TO_8(wOut[2]);
2248
2249 return output;
2250
2251 cmsUNUSED_PARAMETER(info);
2252 cmsUNUSED_PARAMETER(Stride);
2253 }
2254
2255 static
Pack3BytesOptimized(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2256 cmsUInt8Number* Pack3BytesOptimized(CMSREGISTER _cmsTRANSFORM* info,
2257 CMSREGISTER cmsUInt16Number wOut[],
2258 CMSREGISTER cmsUInt8Number* output,
2259 CMSREGISTER cmsUInt32Number Stride)
2260 {
2261 *output++ = (wOut[0] & 0xFFU);
2262 *output++ = (wOut[1] & 0xFFU);
2263 *output++ = (wOut[2] & 0xFFU);
2264
2265 return output;
2266
2267 cmsUNUSED_PARAMETER(info);
2268 cmsUNUSED_PARAMETER(Stride);
2269 }
2270
2271 static
Pack3BytesSwap(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2272 cmsUInt8Number* Pack3BytesSwap(CMSREGISTER _cmsTRANSFORM* info,
2273 CMSREGISTER cmsUInt16Number wOut[],
2274 CMSREGISTER cmsUInt8Number* output,
2275 CMSREGISTER cmsUInt32Number Stride)
2276 {
2277 *output++ = FROM_16_TO_8(wOut[2]);
2278 *output++ = FROM_16_TO_8(wOut[1]);
2279 *output++ = FROM_16_TO_8(wOut[0]);
2280
2281 return output;
2282
2283 cmsUNUSED_PARAMETER(info);
2284 cmsUNUSED_PARAMETER(Stride);
2285 }
2286
2287 static
Pack3BytesSwapOptimized(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2288 cmsUInt8Number* Pack3BytesSwapOptimized(CMSREGISTER _cmsTRANSFORM* info,
2289 CMSREGISTER cmsUInt16Number wOut[],
2290 CMSREGISTER cmsUInt8Number* output,
2291 CMSREGISTER cmsUInt32Number Stride)
2292 {
2293 *output++ = (wOut[2] & 0xFFU);
2294 *output++ = (wOut[1] & 0xFFU);
2295 *output++ = (wOut[0] & 0xFFU);
2296
2297 return output;
2298
2299 cmsUNUSED_PARAMETER(info);
2300 cmsUNUSED_PARAMETER(Stride);
2301 }
2302
2303
2304 static
Pack3Words(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2305 cmsUInt8Number* Pack3Words(CMSREGISTER _cmsTRANSFORM* info,
2306 CMSREGISTER cmsUInt16Number wOut[],
2307 CMSREGISTER cmsUInt8Number* output,
2308 CMSREGISTER cmsUInt32Number Stride)
2309 {
2310 *(cmsUInt16Number*) output = wOut[0];
2311 output+= 2;
2312 *(cmsUInt16Number*) output = wOut[1];
2313 output+= 2;
2314 *(cmsUInt16Number*) output = wOut[2];
2315 output+= 2;
2316
2317 return output;
2318
2319 cmsUNUSED_PARAMETER(info);
2320 cmsUNUSED_PARAMETER(Stride);
2321 }
2322
2323 static
Pack3WordsSwap(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2324 cmsUInt8Number* Pack3WordsSwap(CMSREGISTER _cmsTRANSFORM* info,
2325 CMSREGISTER cmsUInt16Number wOut[],
2326 CMSREGISTER cmsUInt8Number* output,
2327 CMSREGISTER cmsUInt32Number Stride)
2328 {
2329 *(cmsUInt16Number*) output = wOut[2];
2330 output+= 2;
2331 *(cmsUInt16Number*) output = wOut[1];
2332 output+= 2;
2333 *(cmsUInt16Number*) output = wOut[0];
2334 output+= 2;
2335
2336 return output;
2337
2338 cmsUNUSED_PARAMETER(info);
2339 cmsUNUSED_PARAMETER(Stride);
2340 }
2341
2342 static
Pack3WordsBigEndian(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2343 cmsUInt8Number* Pack3WordsBigEndian(CMSREGISTER _cmsTRANSFORM* info,
2344 CMSREGISTER cmsUInt16Number wOut[],
2345 CMSREGISTER cmsUInt8Number* output,
2346 CMSREGISTER cmsUInt32Number Stride)
2347 {
2348 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
2349 output+= 2;
2350 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[1]);
2351 output+= 2;
2352 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[2]);
2353 output+= 2;
2354
2355 return output;
2356
2357 cmsUNUSED_PARAMETER(info);
2358 cmsUNUSED_PARAMETER(Stride);
2359 }
2360
2361 static
Pack3BytesAndSkip1(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2362 cmsUInt8Number* Pack3BytesAndSkip1(CMSREGISTER _cmsTRANSFORM* info,
2363 CMSREGISTER cmsUInt16Number wOut[],
2364 CMSREGISTER cmsUInt8Number* output,
2365 CMSREGISTER cmsUInt32Number Stride)
2366 {
2367 *output++ = FROM_16_TO_8(wOut[0]);
2368 *output++ = FROM_16_TO_8(wOut[1]);
2369 *output++ = FROM_16_TO_8(wOut[2]);
2370 output++;
2371
2372 return output;
2373
2374 cmsUNUSED_PARAMETER(info);
2375 cmsUNUSED_PARAMETER(Stride);
2376 }
2377
2378 static
Pack3BytesAndSkip1Optimized(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2379 cmsUInt8Number* Pack3BytesAndSkip1Optimized(CMSREGISTER _cmsTRANSFORM* info,
2380 CMSREGISTER cmsUInt16Number wOut[],
2381 CMSREGISTER cmsUInt8Number* output,
2382 CMSREGISTER cmsUInt32Number Stride)
2383 {
2384 *output++ = (wOut[0] & 0xFFU);
2385 *output++ = (wOut[1] & 0xFFU);
2386 *output++ = (wOut[2] & 0xFFU);
2387 output++;
2388
2389 return output;
2390
2391 cmsUNUSED_PARAMETER(info);
2392 cmsUNUSED_PARAMETER(Stride);
2393 }
2394
2395
2396 static
Pack3BytesAndSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2397 cmsUInt8Number* Pack3BytesAndSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM* info,
2398 CMSREGISTER cmsUInt16Number wOut[],
2399 CMSREGISTER cmsUInt8Number* output,
2400 CMSREGISTER cmsUInt32Number Stride)
2401 {
2402 output++;
2403 *output++ = FROM_16_TO_8(wOut[0]);
2404 *output++ = FROM_16_TO_8(wOut[1]);
2405 *output++ = FROM_16_TO_8(wOut[2]);
2406
2407 return output;
2408
2409 cmsUNUSED_PARAMETER(info);
2410 cmsUNUSED_PARAMETER(Stride);
2411 }
2412
2413 static
Pack3BytesAndSkip1SwapFirstOptimized(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2414 cmsUInt8Number* Pack3BytesAndSkip1SwapFirstOptimized(CMSREGISTER _cmsTRANSFORM* info,
2415 CMSREGISTER cmsUInt16Number wOut[],
2416 CMSREGISTER cmsUInt8Number* output,
2417 CMSREGISTER cmsUInt32Number Stride)
2418 {
2419 output++;
2420 *output++ = (wOut[0] & 0xFFU);
2421 *output++ = (wOut[1] & 0xFFU);
2422 *output++ = (wOut[2] & 0xFFU);
2423
2424 return output;
2425
2426 cmsUNUSED_PARAMETER(info);
2427 cmsUNUSED_PARAMETER(Stride);
2428 }
2429
2430 static
Pack3BytesAndSkip1Swap(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2431 cmsUInt8Number* Pack3BytesAndSkip1Swap(CMSREGISTER _cmsTRANSFORM* info,
2432 CMSREGISTER cmsUInt16Number wOut[],
2433 CMSREGISTER cmsUInt8Number* output,
2434 CMSREGISTER cmsUInt32Number Stride)
2435 {
2436 output++;
2437 *output++ = FROM_16_TO_8(wOut[2]);
2438 *output++ = FROM_16_TO_8(wOut[1]);
2439 *output++ = FROM_16_TO_8(wOut[0]);
2440
2441 return output;
2442
2443 cmsUNUSED_PARAMETER(info);
2444 cmsUNUSED_PARAMETER(Stride);
2445 }
2446
2447 static
Pack3BytesAndSkip1SwapOptimized(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2448 cmsUInt8Number* Pack3BytesAndSkip1SwapOptimized(CMSREGISTER _cmsTRANSFORM* info,
2449 CMSREGISTER cmsUInt16Number wOut[],
2450 CMSREGISTER cmsUInt8Number* output,
2451 CMSREGISTER cmsUInt32Number Stride)
2452 {
2453 output++;
2454 *output++ = (wOut[2] & 0xFFU);
2455 *output++ = (wOut[1] & 0xFFU);
2456 *output++ = (wOut[0] & 0xFFU);
2457
2458 return output;
2459
2460 cmsUNUSED_PARAMETER(info);
2461 cmsUNUSED_PARAMETER(Stride);
2462 }
2463
2464
2465 static
Pack3BytesAndSkip1SwapSwapFirst(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2466 cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
2467 CMSREGISTER cmsUInt16Number wOut[],
2468 CMSREGISTER cmsUInt8Number* output,
2469 CMSREGISTER cmsUInt32Number Stride)
2470 {
2471 *output++ = FROM_16_TO_8(wOut[2]);
2472 *output++ = FROM_16_TO_8(wOut[1]);
2473 *output++ = FROM_16_TO_8(wOut[0]);
2474 output++;
2475
2476 return output;
2477
2478 cmsUNUSED_PARAMETER(info);
2479 cmsUNUSED_PARAMETER(Stride);
2480 }
2481
2482 static
Pack3BytesAndSkip1SwapSwapFirstOptimized(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2483 cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirstOptimized(CMSREGISTER _cmsTRANSFORM* info,
2484 CMSREGISTER cmsUInt16Number wOut[],
2485 CMSREGISTER cmsUInt8Number* output,
2486 CMSREGISTER cmsUInt32Number Stride)
2487 {
2488 *output++ = (wOut[2] & 0xFFU);
2489 *output++ = (wOut[1] & 0xFFU);
2490 *output++ = (wOut[0] & 0xFFU);
2491 output++;
2492
2493 return output;
2494
2495 cmsUNUSED_PARAMETER(info);
2496 cmsUNUSED_PARAMETER(Stride);
2497 }
2498
2499 static
Pack3WordsAndSkip1(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2500 cmsUInt8Number* Pack3WordsAndSkip1(CMSREGISTER _cmsTRANSFORM* info,
2501 CMSREGISTER cmsUInt16Number wOut[],
2502 CMSREGISTER cmsUInt8Number* output,
2503 CMSREGISTER cmsUInt32Number Stride)
2504 {
2505 *(cmsUInt16Number*) output = wOut[0];
2506 output+= 2;
2507 *(cmsUInt16Number*) output = wOut[1];
2508 output+= 2;
2509 *(cmsUInt16Number*) output = wOut[2];
2510 output+= 2;
2511 output+= 2;
2512
2513 return output;
2514
2515 cmsUNUSED_PARAMETER(info);
2516 cmsUNUSED_PARAMETER(Stride);
2517 }
2518
2519 static
Pack3WordsAndSkip1Swap(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2520 cmsUInt8Number* Pack3WordsAndSkip1Swap(CMSREGISTER _cmsTRANSFORM* info,
2521 CMSREGISTER cmsUInt16Number wOut[],
2522 CMSREGISTER cmsUInt8Number* output,
2523 CMSREGISTER cmsUInt32Number Stride)
2524 {
2525 output+= 2;
2526 *(cmsUInt16Number*) output = wOut[2];
2527 output+= 2;
2528 *(cmsUInt16Number*) output = wOut[1];
2529 output+= 2;
2530 *(cmsUInt16Number*) output = wOut[0];
2531 output+= 2;
2532
2533 return output;
2534
2535 cmsUNUSED_PARAMETER(info);
2536 cmsUNUSED_PARAMETER(Stride);
2537 }
2538
2539
2540 static
Pack3WordsAndSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2541 cmsUInt8Number* Pack3WordsAndSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM* info,
2542 CMSREGISTER cmsUInt16Number wOut[],
2543 CMSREGISTER cmsUInt8Number* output,
2544 CMSREGISTER cmsUInt32Number Stride)
2545 {
2546 output+= 2;
2547 *(cmsUInt16Number*) output = wOut[0];
2548 output+= 2;
2549 *(cmsUInt16Number*) output = wOut[1];
2550 output+= 2;
2551 *(cmsUInt16Number*) output = wOut[2];
2552 output+= 2;
2553
2554 return output;
2555
2556 cmsUNUSED_PARAMETER(info);
2557 cmsUNUSED_PARAMETER(Stride);
2558 }
2559
2560
2561 static
Pack3WordsAndSkip1SwapSwapFirst(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2562 cmsUInt8Number* Pack3WordsAndSkip1SwapSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
2563 CMSREGISTER cmsUInt16Number wOut[],
2564 CMSREGISTER cmsUInt8Number* output,
2565 CMSREGISTER cmsUInt32Number Stride)
2566 {
2567 *(cmsUInt16Number*) output = wOut[2];
2568 output+= 2;
2569 *(cmsUInt16Number*) output = wOut[1];
2570 output+= 2;
2571 *(cmsUInt16Number*) output = wOut[0];
2572 output+= 2;
2573 output+= 2;
2574
2575 return output;
2576
2577 cmsUNUSED_PARAMETER(info);
2578 cmsUNUSED_PARAMETER(Stride);
2579 }
2580
2581
2582
2583 static
Pack1Byte(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2584 cmsUInt8Number* Pack1Byte(CMSREGISTER _cmsTRANSFORM* info,
2585 CMSREGISTER cmsUInt16Number wOut[],
2586 CMSREGISTER cmsUInt8Number* output,
2587 CMSREGISTER cmsUInt32Number Stride)
2588 {
2589 *output++ = FROM_16_TO_8(wOut[0]);
2590
2591 return output;
2592
2593 cmsUNUSED_PARAMETER(info);
2594 cmsUNUSED_PARAMETER(Stride);
2595 }
2596
2597
2598 static
Pack1ByteReversed(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2599 cmsUInt8Number* Pack1ByteReversed(CMSREGISTER _cmsTRANSFORM* info,
2600 CMSREGISTER cmsUInt16Number wOut[],
2601 CMSREGISTER cmsUInt8Number* output,
2602 CMSREGISTER cmsUInt32Number Stride)
2603 {
2604 *output++ = FROM_16_TO_8(REVERSE_FLAVOR_16(wOut[0]));
2605
2606 return output;
2607
2608 cmsUNUSED_PARAMETER(info);
2609 cmsUNUSED_PARAMETER(Stride);
2610 }
2611
2612
2613 static
Pack1ByteSkip1(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2614 cmsUInt8Number* Pack1ByteSkip1(CMSREGISTER _cmsTRANSFORM* info,
2615 CMSREGISTER cmsUInt16Number wOut[],
2616 CMSREGISTER cmsUInt8Number* output,
2617 CMSREGISTER cmsUInt32Number Stride)
2618 {
2619 *output++ = FROM_16_TO_8(wOut[0]);
2620 output++;
2621
2622 return output;
2623
2624 cmsUNUSED_PARAMETER(info);
2625 cmsUNUSED_PARAMETER(Stride);
2626 }
2627
2628
2629 static
Pack1ByteSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2630 cmsUInt8Number* Pack1ByteSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM* info,
2631 CMSREGISTER cmsUInt16Number wOut[],
2632 CMSREGISTER cmsUInt8Number* output,
2633 CMSREGISTER cmsUInt32Number Stride)
2634 {
2635 output++;
2636 *output++ = FROM_16_TO_8(wOut[0]);
2637
2638 return output;
2639
2640 cmsUNUSED_PARAMETER(info);
2641 cmsUNUSED_PARAMETER(Stride);
2642 }
2643
2644 static
Pack1Word(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2645 cmsUInt8Number* Pack1Word(CMSREGISTER _cmsTRANSFORM* info,
2646 CMSREGISTER cmsUInt16Number wOut[],
2647 CMSREGISTER cmsUInt8Number* output,
2648 CMSREGISTER cmsUInt32Number Stride)
2649 {
2650 *(cmsUInt16Number*) output = wOut[0];
2651 output+= 2;
2652
2653 return output;
2654
2655 cmsUNUSED_PARAMETER(info);
2656 cmsUNUSED_PARAMETER(Stride);
2657 }
2658
2659
2660 static
Pack1WordReversed(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2661 cmsUInt8Number* Pack1WordReversed(CMSREGISTER _cmsTRANSFORM* info,
2662 CMSREGISTER cmsUInt16Number wOut[],
2663 CMSREGISTER cmsUInt8Number* output,
2664 CMSREGISTER cmsUInt32Number Stride)
2665 {
2666 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[0]);
2667 output+= 2;
2668
2669 return output;
2670
2671 cmsUNUSED_PARAMETER(info);
2672 cmsUNUSED_PARAMETER(Stride);
2673 }
2674
2675 static
Pack1WordBigEndian(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2676 cmsUInt8Number* Pack1WordBigEndian(CMSREGISTER _cmsTRANSFORM* info,
2677 CMSREGISTER cmsUInt16Number wOut[],
2678 CMSREGISTER cmsUInt8Number* output,
2679 CMSREGISTER cmsUInt32Number Stride)
2680 {
2681 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
2682 output+= 2;
2683
2684 return output;
2685
2686 cmsUNUSED_PARAMETER(info);
2687 cmsUNUSED_PARAMETER(Stride);
2688 }
2689
2690
2691 static
Pack1WordSkip1(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2692 cmsUInt8Number* Pack1WordSkip1(CMSREGISTER _cmsTRANSFORM* info,
2693 CMSREGISTER cmsUInt16Number wOut[],
2694 CMSREGISTER cmsUInt8Number* output,
2695 CMSREGISTER cmsUInt32Number Stride)
2696 {
2697 *(cmsUInt16Number*) output = wOut[0];
2698 output+= 4;
2699
2700 return output;
2701
2702 cmsUNUSED_PARAMETER(info);
2703 cmsUNUSED_PARAMETER(Stride);
2704 }
2705
2706 static
Pack1WordSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2707 cmsUInt8Number* Pack1WordSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM* info,
2708 CMSREGISTER cmsUInt16Number wOut[],
2709 CMSREGISTER cmsUInt8Number* output,
2710 CMSREGISTER cmsUInt32Number Stride)
2711 {
2712 output += 2;
2713 *(cmsUInt16Number*) output = wOut[0];
2714 output+= 2;
2715
2716 return output;
2717
2718 cmsUNUSED_PARAMETER(info);
2719 cmsUNUSED_PARAMETER(Stride);
2720 }
2721
2722
2723 // Unencoded Float values -- don't try optimize speed
2724 static
PackLabDoubleFrom16(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2725 cmsUInt8Number* PackLabDoubleFrom16(CMSREGISTER _cmsTRANSFORM* info,
2726 CMSREGISTER cmsUInt16Number wOut[],
2727 CMSREGISTER cmsUInt8Number* output,
2728 CMSREGISTER cmsUInt32Number Stride)
2729 {
2730
2731 if (T_PLANAR(info -> OutputFormat)) {
2732
2733 cmsCIELab Lab;
2734 cmsFloat64Number* Out = (cmsFloat64Number*) output;
2735 cmsLabEncoded2Float(&Lab, wOut);
2736
2737 Out[0] = Lab.L;
2738 Out[Stride] = Lab.a;
2739 Out[Stride*2] = Lab.b;
2740
2741 return output + sizeof(cmsFloat64Number);
2742 }
2743 else {
2744
2745 cmsLabEncoded2Float((cmsCIELab*) output, wOut);
2746 return output + (sizeof(cmsCIELab) + T_EXTRA(info ->OutputFormat) * sizeof(cmsFloat64Number));
2747 }
2748 }
2749
2750
2751 static
PackLabFloatFrom16(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2752 cmsUInt8Number* PackLabFloatFrom16(CMSREGISTER _cmsTRANSFORM* info,
2753 CMSREGISTER cmsUInt16Number wOut[],
2754 CMSREGISTER cmsUInt8Number* output,
2755 CMSREGISTER cmsUInt32Number Stride)
2756 {
2757 cmsCIELab Lab;
2758 cmsLabEncoded2Float(&Lab, wOut);
2759
2760 if (T_PLANAR(info -> OutputFormat)) {
2761
2762 cmsFloat32Number* Out = (cmsFloat32Number*) output;
2763
2764 Stride /= PixelSize(info->OutputFormat);
2765
2766 Out[0] = (cmsFloat32Number)Lab.L;
2767 Out[Stride] = (cmsFloat32Number)Lab.a;
2768 Out[Stride*2] = (cmsFloat32Number)Lab.b;
2769
2770 return output + sizeof(cmsFloat32Number);
2771 }
2772 else {
2773
2774 ((cmsFloat32Number*) output)[0] = (cmsFloat32Number) Lab.L;
2775 ((cmsFloat32Number*) output)[1] = (cmsFloat32Number) Lab.a;
2776 ((cmsFloat32Number*) output)[2] = (cmsFloat32Number) Lab.b;
2777
2778 return output + (3 + T_EXTRA(info ->OutputFormat)) * sizeof(cmsFloat32Number);
2779 }
2780 }
2781
2782 static
PackXYZDoubleFrom16(CMSREGISTER _cmsTRANSFORM * Info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2783 cmsUInt8Number* PackXYZDoubleFrom16(CMSREGISTER _cmsTRANSFORM* Info,
2784 CMSREGISTER cmsUInt16Number wOut[],
2785 CMSREGISTER cmsUInt8Number* output,
2786 CMSREGISTER cmsUInt32Number Stride)
2787 {
2788 if (T_PLANAR(Info -> OutputFormat)) {
2789
2790 cmsCIEXYZ XYZ;
2791 cmsFloat64Number* Out = (cmsFloat64Number*) output;
2792 cmsXYZEncoded2Float(&XYZ, wOut);
2793
2794 Stride /= PixelSize(Info->OutputFormat);
2795
2796 Out[0] = XYZ.X;
2797 Out[Stride] = XYZ.Y;
2798 Out[Stride*2] = XYZ.Z;
2799
2800 return output + sizeof(cmsFloat64Number);
2801
2802 }
2803 else {
2804
2805 cmsXYZEncoded2Float((cmsCIEXYZ*) output, wOut);
2806
2807 return output + (sizeof(cmsCIEXYZ) + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
2808 }
2809 }
2810
2811 static
PackXYZFloatFrom16(CMSREGISTER _cmsTRANSFORM * Info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2812 cmsUInt8Number* PackXYZFloatFrom16(CMSREGISTER _cmsTRANSFORM* Info,
2813 CMSREGISTER cmsUInt16Number wOut[],
2814 CMSREGISTER cmsUInt8Number* output,
2815 CMSREGISTER cmsUInt32Number Stride)
2816 {
2817 if (T_PLANAR(Info -> OutputFormat)) {
2818
2819 cmsCIEXYZ XYZ;
2820 cmsFloat32Number* Out = (cmsFloat32Number*) output;
2821 cmsXYZEncoded2Float(&XYZ, wOut);
2822
2823 Stride /= PixelSize(Info->OutputFormat);
2824
2825 Out[0] = (cmsFloat32Number) XYZ.X;
2826 Out[Stride] = (cmsFloat32Number) XYZ.Y;
2827 Out[Stride*2] = (cmsFloat32Number) XYZ.Z;
2828
2829 return output + sizeof(cmsFloat32Number);
2830
2831 }
2832 else {
2833
2834 cmsCIEXYZ XYZ;
2835 cmsFloat32Number* Out = (cmsFloat32Number*) output;
2836 cmsXYZEncoded2Float(&XYZ, wOut);
2837
2838 Out[0] = (cmsFloat32Number) XYZ.X;
2839 Out[1] = (cmsFloat32Number) XYZ.Y;
2840 Out[2] = (cmsFloat32Number) XYZ.Z;
2841
2842 return output + (3 * sizeof(cmsFloat32Number) + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
2843 }
2844 }
2845
2846 static
PackDoubleFrom16(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2847 cmsUInt8Number* PackDoubleFrom16(CMSREGISTER _cmsTRANSFORM* info,
2848 CMSREGISTER cmsUInt16Number wOut[],
2849 CMSREGISTER cmsUInt8Number* output,
2850 CMSREGISTER cmsUInt32Number Stride)
2851 {
2852 cmsUInt32Number nChan = T_CHANNELS(info -> OutputFormat);
2853 cmsUInt32Number DoSwap = T_DOSWAP(info ->OutputFormat);
2854 cmsUInt32Number Reverse = T_FLAVOR(info ->OutputFormat);
2855 cmsUInt32Number Extra = T_EXTRA(info -> OutputFormat);
2856 cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2857 cmsUInt32Number Planar = T_PLANAR(info -> OutputFormat);
2858 cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
2859 cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35 : 65535.0;
2860 cmsFloat64Number v = 0;
2861 cmsFloat64Number* swap1 = (cmsFloat64Number*) output;
2862 cmsUInt32Number i, start = 0;
2863
2864 Stride /= PixelSize(info->OutputFormat);
2865
2866 if (ExtraFirst)
2867 start = Extra;
2868
2869 for (i=0; i < nChan; i++) {
2870
2871 cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
2872
2873 v = (cmsFloat64Number) wOut[index] / maximum;
2874
2875 if (Reverse)
2876 v = maximum - v;
2877
2878 if (Planar)
2879 ((cmsFloat64Number*) output)[(i + start) * Stride]= v;
2880 else
2881 ((cmsFloat64Number*) output)[i + start] = v;
2882 }
2883
2884
2885 if (Extra == 0 && SwapFirst) {
2886
2887 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat64Number));
2888 *swap1 = v;
2889 }
2890
2891 if (T_PLANAR(info -> OutputFormat))
2892 return output + sizeof(cmsFloat64Number);
2893 else
2894 return output + (nChan + Extra) * sizeof(cmsFloat64Number);
2895
2896 }
2897
2898
2899 static
PackFloatFrom16(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)2900 cmsUInt8Number* PackFloatFrom16(CMSREGISTER _cmsTRANSFORM* info,
2901 CMSREGISTER cmsUInt16Number wOut[],
2902 CMSREGISTER cmsUInt8Number* output,
2903 CMSREGISTER cmsUInt32Number Stride)
2904 {
2905 cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat);
2906 cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat);
2907 cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat);
2908 cmsUInt32Number Extra = T_EXTRA(info->OutputFormat);
2909 cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat);
2910 cmsUInt32Number Planar = T_PLANAR(info->OutputFormat);
2911 cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
2912 cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 655.35 : 65535.0;
2913 cmsFloat64Number v = 0;
2914 cmsFloat32Number* swap1 = (cmsFloat32Number*)output;
2915 cmsUInt32Number i, start = 0;
2916
2917 Stride /= PixelSize(info->OutputFormat);
2918
2919 if (ExtraFirst)
2920 start = Extra;
2921
2922 for (i = 0; i < nChan; i++) {
2923
2924 cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
2925
2926 v = (cmsFloat64Number)wOut[index] / maximum;
2927
2928 if (Reverse)
2929 v = maximum - v;
2930
2931 if (Planar)
2932 ((cmsFloat32Number*)output)[(i + start) * Stride] = (cmsFloat32Number)v;
2933 else
2934 ((cmsFloat32Number*)output)[i + start] = (cmsFloat32Number)v;
2935 }
2936
2937
2938 if (Extra == 0 && SwapFirst) {
2939
2940 memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsFloat32Number));
2941 *swap1 = (cmsFloat32Number)v;
2942 }
2943
2944 if (T_PLANAR(info->OutputFormat))
2945 return output + sizeof(cmsFloat32Number);
2946 else
2947 return output + (nChan + Extra) * sizeof(cmsFloat32Number);
2948 }
2949
2950
2951
2952 // --------------------------------------------------------------------------------------------------------
2953
2954 static
PackFloatsFromFloat(_cmsTRANSFORM * info,cmsFloat32Number wOut[],cmsUInt8Number * output,cmsUInt32Number Stride)2955 cmsUInt8Number* PackFloatsFromFloat(_cmsTRANSFORM* info,
2956 cmsFloat32Number wOut[],
2957 cmsUInt8Number* output,
2958 cmsUInt32Number Stride)
2959 {
2960 cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat);
2961 cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat);
2962 cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat);
2963 cmsUInt32Number Extra = T_EXTRA(info->OutputFormat);
2964 cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat);
2965 cmsUInt32Number Planar = T_PLANAR(info->OutputFormat);
2966 cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
2967 cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 100.0 : 1.0;
2968 cmsFloat32Number* swap1 = (cmsFloat32Number*)output;
2969 cmsFloat64Number v = 0;
2970 cmsUInt32Number i, start = 0;
2971
2972 Stride /= PixelSize(info->OutputFormat);
2973
2974 if (ExtraFirst)
2975 start = Extra;
2976
2977 for (i = 0; i < nChan; i++) {
2978
2979 cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
2980
2981 v = wOut[index] * maximum;
2982
2983 if (Reverse)
2984 v = maximum - v;
2985
2986 if (Planar)
2987 ((cmsFloat32Number*)output)[(i + start)* Stride] = (cmsFloat32Number)v;
2988 else
2989 ((cmsFloat32Number*)output)[i + start] = (cmsFloat32Number)v;
2990 }
2991
2992
2993 if (Extra == 0 && SwapFirst) {
2994
2995 memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsFloat32Number));
2996 *swap1 = (cmsFloat32Number)v;
2997 }
2998
2999 if (T_PLANAR(info->OutputFormat))
3000 return output + sizeof(cmsFloat32Number);
3001 else
3002 return output + (nChan + Extra) * sizeof(cmsFloat32Number);
3003 }
3004
3005 static
PackDoublesFromFloat(_cmsTRANSFORM * info,cmsFloat32Number wOut[],cmsUInt8Number * output,cmsUInt32Number Stride)3006 cmsUInt8Number* PackDoublesFromFloat(_cmsTRANSFORM* info,
3007 cmsFloat32Number wOut[],
3008 cmsUInt8Number* output,
3009 cmsUInt32Number Stride)
3010 {
3011 cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat);
3012 cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat);
3013 cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat);
3014 cmsUInt32Number Extra = T_EXTRA(info->OutputFormat);
3015 cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat);
3016 cmsUInt32Number Planar = T_PLANAR(info->OutputFormat);
3017 cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
3018 cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 100.0 : 1.0;
3019 cmsFloat64Number v = 0;
3020 cmsFloat64Number* swap1 = (cmsFloat64Number*)output;
3021 cmsUInt32Number i, start = 0;
3022
3023 Stride /= PixelSize(info->OutputFormat);
3024
3025 if (ExtraFirst)
3026 start = Extra;
3027
3028 for (i = 0; i < nChan; i++) {
3029
3030 cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
3031
3032 v = wOut[index] * maximum;
3033
3034 if (Reverse)
3035 v = maximum - v;
3036
3037 if (Planar)
3038 ((cmsFloat64Number*)output)[(i + start) * Stride] = v;
3039 else
3040 ((cmsFloat64Number*)output)[i + start] = v;
3041 }
3042
3043 if (Extra == 0 && SwapFirst) {
3044
3045 memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsFloat64Number));
3046 *swap1 = v;
3047 }
3048
3049
3050 if (T_PLANAR(info->OutputFormat))
3051 return output + sizeof(cmsFloat64Number);
3052 else
3053 return output + (nChan + Extra) * sizeof(cmsFloat64Number);
3054
3055 }
3056
3057 static
PackLabFloatFromFloat(_cmsTRANSFORM * Info,cmsFloat32Number wOut[],cmsUInt8Number * output,cmsUInt32Number Stride)3058 cmsUInt8Number* PackLabFloatFromFloat(_cmsTRANSFORM* Info,
3059 cmsFloat32Number wOut[],
3060 cmsUInt8Number* output,
3061 cmsUInt32Number Stride)
3062 {
3063 cmsFloat32Number* Out = (cmsFloat32Number*) output;
3064
3065 if (T_PLANAR(Info -> OutputFormat)) {
3066
3067 Stride /= PixelSize(Info->OutputFormat);
3068
3069 Out[0] = (cmsFloat32Number) (wOut[0] * 100.0);
3070 Out[Stride] = (cmsFloat32Number) (wOut[1] * 255.0 - 128.0);
3071 Out[Stride*2] = (cmsFloat32Number) (wOut[2] * 255.0 - 128.0);
3072
3073 return output + sizeof(cmsFloat32Number);
3074 }
3075 else {
3076
3077 Out[0] = (cmsFloat32Number) (wOut[0] * 100.0);
3078 Out[1] = (cmsFloat32Number) (wOut[1] * 255.0 - 128.0);
3079 Out[2] = (cmsFloat32Number) (wOut[2] * 255.0 - 128.0);
3080
3081 return output + (sizeof(cmsFloat32Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
3082 }
3083
3084 }
3085
3086
3087 static
PackLabDoubleFromFloat(_cmsTRANSFORM * Info,cmsFloat32Number wOut[],cmsUInt8Number * output,cmsUInt32Number Stride)3088 cmsUInt8Number* PackLabDoubleFromFloat(_cmsTRANSFORM* Info,
3089 cmsFloat32Number wOut[],
3090 cmsUInt8Number* output,
3091 cmsUInt32Number Stride)
3092 {
3093 cmsFloat64Number* Out = (cmsFloat64Number*) output;
3094
3095 if (T_PLANAR(Info -> OutputFormat)) {
3096
3097 Stride /= PixelSize(Info->OutputFormat);
3098
3099 Out[0] = (cmsFloat64Number) (wOut[0] * 100.0);
3100 Out[Stride] = (cmsFloat64Number) (wOut[1] * 255.0 - 128.0);
3101 Out[Stride*2] = (cmsFloat64Number) (wOut[2] * 255.0 - 128.0);
3102
3103 return output + sizeof(cmsFloat64Number);
3104 }
3105 else {
3106
3107 Out[0] = (cmsFloat64Number) (wOut[0] * 100.0);
3108 Out[1] = (cmsFloat64Number) (wOut[1] * 255.0 - 128.0);
3109 Out[2] = (cmsFloat64Number) (wOut[2] * 255.0 - 128.0);
3110
3111 return output + (sizeof(cmsFloat64Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
3112 }
3113
3114 }
3115
3116
3117 // From 0..1 range to 0..MAX_ENCODEABLE_XYZ
3118 static
PackXYZFloatFromFloat(_cmsTRANSFORM * Info,cmsFloat32Number wOut[],cmsUInt8Number * output,cmsUInt32Number Stride)3119 cmsUInt8Number* PackXYZFloatFromFloat(_cmsTRANSFORM* Info,
3120 cmsFloat32Number wOut[],
3121 cmsUInt8Number* output,
3122 cmsUInt32Number Stride)
3123 {
3124 cmsFloat32Number* Out = (cmsFloat32Number*) output;
3125
3126 if (T_PLANAR(Info -> OutputFormat)) {
3127
3128 Stride /= PixelSize(Info->OutputFormat);
3129
3130 Out[0] = (cmsFloat32Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
3131 Out[Stride] = (cmsFloat32Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
3132 Out[Stride*2] = (cmsFloat32Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
3133
3134 return output + sizeof(cmsFloat32Number);
3135 }
3136 else {
3137
3138 Out[0] = (cmsFloat32Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
3139 Out[1] = (cmsFloat32Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
3140 Out[2] = (cmsFloat32Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
3141
3142 return output + (sizeof(cmsFloat32Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
3143 }
3144
3145 }
3146
3147 // Same, but convert to double
3148 static
PackXYZDoubleFromFloat(_cmsTRANSFORM * Info,cmsFloat32Number wOut[],cmsUInt8Number * output,cmsUInt32Number Stride)3149 cmsUInt8Number* PackXYZDoubleFromFloat(_cmsTRANSFORM* Info,
3150 cmsFloat32Number wOut[],
3151 cmsUInt8Number* output,
3152 cmsUInt32Number Stride)
3153 {
3154 cmsFloat64Number* Out = (cmsFloat64Number*) output;
3155
3156 if (T_PLANAR(Info -> OutputFormat)) {
3157
3158 Stride /= PixelSize(Info->OutputFormat);
3159
3160 Out[0] = (cmsFloat64Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
3161 Out[Stride] = (cmsFloat64Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
3162 Out[Stride*2] = (cmsFloat64Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
3163
3164 return output + sizeof(cmsFloat64Number);
3165 }
3166 else {
3167
3168 Out[0] = (cmsFloat64Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
3169 Out[1] = (cmsFloat64Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
3170 Out[2] = (cmsFloat64Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
3171
3172 return output + (sizeof(cmsFloat64Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
3173 }
3174
3175 }
3176
3177
3178 // ----------------------------------------------------------------------------------------------------------------
3179
3180 #ifndef CMS_NO_HALF_SUPPORT
3181
3182 // Decodes an stream of half floats to wIn[] described by input format
3183
3184 static
UnrollHalfTo16(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wIn[],CMSREGISTER cmsUInt8Number * accum,CMSREGISTER cmsUInt32Number Stride)3185 cmsUInt8Number* UnrollHalfTo16(CMSREGISTER _cmsTRANSFORM* info,
3186 CMSREGISTER cmsUInt16Number wIn[],
3187 CMSREGISTER cmsUInt8Number* accum,
3188 CMSREGISTER cmsUInt32Number Stride)
3189 {
3190
3191 cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
3192 cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat);
3193 cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat);
3194 cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat);
3195 cmsUInt32Number Extra = T_EXTRA(info -> InputFormat);
3196 cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
3197 cmsUInt32Number Planar = T_PLANAR(info -> InputFormat);
3198 cmsFloat32Number v;
3199 cmsUInt32Number i, start = 0;
3200 cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 655.35F : 65535.0F;
3201
3202
3203 Stride /= PixelSize(info->OutputFormat);
3204
3205 if (ExtraFirst)
3206 start = Extra;
3207
3208 for (i=0; i < nChan; i++) {
3209
3210 cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
3211
3212 if (Planar)
3213 v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[(i + start) * Stride] );
3214 else
3215 v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[i + start] ) ;
3216
3217 if (Reverse) v = maximum - v;
3218
3219 wIn[index] = _cmsQuickSaturateWord((cmsFloat64Number) v * maximum);
3220 }
3221
3222
3223 if (Extra == 0 && SwapFirst) {
3224 cmsUInt16Number tmp = wIn[0];
3225
3226 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
3227 wIn[nChan-1] = tmp;
3228 }
3229
3230 if (T_PLANAR(info -> InputFormat))
3231 return accum + sizeof(cmsUInt16Number);
3232 else
3233 return accum + (nChan + Extra) * sizeof(cmsUInt16Number);
3234 }
3235
3236 // Decodes an stream of half floats to wIn[] described by input format
3237
3238 static
UnrollHalfToFloat(_cmsTRANSFORM * info,cmsFloat32Number wIn[],cmsUInt8Number * accum,cmsUInt32Number Stride)3239 cmsUInt8Number* UnrollHalfToFloat(_cmsTRANSFORM* info,
3240 cmsFloat32Number wIn[],
3241 cmsUInt8Number* accum,
3242 cmsUInt32Number Stride)
3243 {
3244
3245 cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
3246 cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat);
3247 cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat);
3248 cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat);
3249 cmsUInt32Number Extra = T_EXTRA(info -> InputFormat);
3250 cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
3251 cmsUInt32Number Planar = T_PLANAR(info -> InputFormat);
3252 cmsFloat32Number v;
3253 cmsUInt32Number i, start = 0;
3254 cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 100.0F : 1.0F;
3255
3256 Stride /= PixelSize(info->OutputFormat);
3257
3258 if (ExtraFirst)
3259 start = Extra;
3260
3261 for (i=0; i < nChan; i++) {
3262
3263 cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
3264
3265 if (Planar)
3266 v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[(i + start) * Stride] );
3267 else
3268 v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[i + start] ) ;
3269
3270 v /= maximum;
3271
3272 wIn[index] = Reverse ? 1 - v : v;
3273 }
3274
3275
3276 if (Extra == 0 && SwapFirst) {
3277 cmsFloat32Number tmp = wIn[0];
3278
3279 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number));
3280 wIn[nChan-1] = tmp;
3281 }
3282
3283 if (T_PLANAR(info -> InputFormat))
3284 return accum + sizeof(cmsUInt16Number);
3285 else
3286 return accum + (nChan + Extra) * sizeof(cmsUInt16Number);
3287 }
3288
3289
3290 static
PackHalfFrom16(CMSREGISTER _cmsTRANSFORM * info,CMSREGISTER cmsUInt16Number wOut[],CMSREGISTER cmsUInt8Number * output,CMSREGISTER cmsUInt32Number Stride)3291 cmsUInt8Number* PackHalfFrom16(CMSREGISTER _cmsTRANSFORM* info,
3292 CMSREGISTER cmsUInt16Number wOut[],
3293 CMSREGISTER cmsUInt8Number* output,
3294 CMSREGISTER cmsUInt32Number Stride)
3295 {
3296 cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat);
3297 cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat);
3298 cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat);
3299 cmsUInt32Number Extra = T_EXTRA(info->OutputFormat);
3300 cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat);
3301 cmsUInt32Number Planar = T_PLANAR(info->OutputFormat);
3302 cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
3303 cmsFloat32Number maximum = IsInkSpace(info->OutputFormat) ? 655.35F : 65535.0F;
3304 cmsFloat32Number v = 0;
3305 cmsUInt16Number* swap1 = (cmsUInt16Number*)output;
3306 cmsUInt32Number i, start = 0;
3307
3308 Stride /= PixelSize(info->OutputFormat);
3309
3310 if (ExtraFirst)
3311 start = Extra;
3312
3313 for (i = 0; i < nChan; i++) {
3314
3315 cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
3316
3317 v = (cmsFloat32Number)wOut[index] / maximum;
3318
3319 if (Reverse)
3320 v = maximum - v;
3321
3322 if (Planar)
3323 ((cmsUInt16Number*)output)[(i + start) * Stride] = _cmsFloat2Half(v);
3324 else
3325 ((cmsUInt16Number*)output)[i + start] = _cmsFloat2Half(v);
3326 }
3327
3328
3329 if (Extra == 0 && SwapFirst) {
3330
3331 memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsUInt16Number));
3332 *swap1 = _cmsFloat2Half(v);
3333 }
3334
3335 if (T_PLANAR(info->OutputFormat))
3336 return output + sizeof(cmsUInt16Number);
3337 else
3338 return output + (nChan + Extra) * sizeof(cmsUInt16Number);
3339 }
3340
3341
3342
3343 static
PackHalfFromFloat(_cmsTRANSFORM * info,cmsFloat32Number wOut[],cmsUInt8Number * output,cmsUInt32Number Stride)3344 cmsUInt8Number* PackHalfFromFloat(_cmsTRANSFORM* info,
3345 cmsFloat32Number wOut[],
3346 cmsUInt8Number* output,
3347 cmsUInt32Number Stride)
3348 {
3349 cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat);
3350 cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat);
3351 cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat);
3352 cmsUInt32Number Extra = T_EXTRA(info->OutputFormat);
3353 cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat);
3354 cmsUInt32Number Planar = T_PLANAR(info->OutputFormat);
3355 cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
3356 cmsFloat32Number maximum = IsInkSpace(info->OutputFormat) ? 100.0F : 1.0F;
3357 cmsUInt16Number* swap1 = (cmsUInt16Number*)output;
3358 cmsFloat32Number v = 0;
3359 cmsUInt32Number i, start = 0;
3360
3361 Stride /= PixelSize(info->OutputFormat);
3362
3363 if (ExtraFirst)
3364 start = Extra;
3365
3366 for (i = 0; i < nChan; i++) {
3367
3368 cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
3369
3370 v = wOut[index] * maximum;
3371
3372 if (Reverse)
3373 v = maximum - v;
3374
3375 if (Planar)
3376 ((cmsUInt16Number*)output)[(i + start)* Stride] = _cmsFloat2Half(v);
3377 else
3378 ((cmsUInt16Number*)output)[i + start] = _cmsFloat2Half(v);
3379 }
3380
3381
3382 if (Extra == 0 && SwapFirst) {
3383
3384 memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsUInt16Number));
3385 *swap1 = (cmsUInt16Number)_cmsFloat2Half(v);
3386 }
3387
3388 if (T_PLANAR(info->OutputFormat))
3389 return output + sizeof(cmsUInt16Number);
3390 else
3391 return output + (nChan + Extra)* sizeof(cmsUInt16Number);
3392 }
3393
3394 #endif
3395
3396 // ----------------------------------------------------------------------------------------------------------------
3397
3398
3399 static const cmsFormatters16 InputFormatters16[] = {
3400
3401 // Type Mask Function
3402 // ---------------------------- ------------------------------------ ----------------------------
3403 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, UnrollLabDoubleTo16},
3404 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, UnrollXYZDoubleTo16},
3405 { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, UnrollLabFloatTo16},
3406 { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, UnrollXYZFloatTo16},
3407 { TYPE_GRAY_DBL, 0, UnrollDouble1Chan},
3408 { FLOAT_SH(1)|BYTES_SH(0), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR|
3409 ANYSWAP|ANYEXTRA|ANYSPACE, UnrollDoubleTo16},
3410 { FLOAT_SH(1)|BYTES_SH(4), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR|
3411 ANYSWAP|ANYEXTRA|ANYSPACE, UnrollFloatTo16},
3412 #ifndef CMS_NO_HALF_SUPPORT
3413 { FLOAT_SH(1)|BYTES_SH(2), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR|
3414 ANYEXTRA|ANYSWAP|ANYSPACE, UnrollHalfTo16},
3415 #endif
3416
3417 { CHANNELS_SH(1)|BYTES_SH(1), ANYSPACE, Unroll1Byte},
3418 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Unroll1ByteSkip1},
3419 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(2), ANYSPACE, Unroll1ByteSkip2},
3420 { CHANNELS_SH(1)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Unroll1ByteReversed},
3421 { COLORSPACE_SH(PT_MCH2)|CHANNELS_SH(2)|BYTES_SH(1), 0, Unroll2Bytes},
3422
3423 { TYPE_LabV2_8, 0, UnrollLabV2_8 },
3424 { TYPE_ALabV2_8, 0, UnrollALabV2_8 },
3425 { TYPE_LabV2_16, 0, UnrollLabV2_16 },
3426
3427 { CHANNELS_SH(3)|BYTES_SH(1), ANYSPACE, Unroll3Bytes},
3428 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3BytesSwap},
3429 { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3BytesSkip1Swap},
3430 { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll3BytesSkip1SwapFirst},
3431
3432 { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1),
3433 ANYSPACE, Unroll3BytesSkip1SwapSwapFirst},
3434
3435 { CHANNELS_SH(4)|BYTES_SH(1), ANYSPACE, Unroll4Bytes},
3436 { CHANNELS_SH(4)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Unroll4BytesReverse},
3437 { CHANNELS_SH(4)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4BytesSwapFirst},
3438 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll4BytesSwap},
3439 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4BytesSwapSwapFirst},
3440
3441 { BYTES_SH(1)|PLANAR_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYPREMUL|
3442 ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollPlanarBytes},
3443
3444 { BYTES_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYPREMUL|
3445 ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollChunkyBytes},
3446
3447 { CHANNELS_SH(1)|BYTES_SH(2), ANYSPACE, Unroll1Word},
3448 { CHANNELS_SH(1)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Unroll1WordReversed},
3449 { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(3), ANYSPACE, Unroll1WordSkip3},
3450
3451 { CHANNELS_SH(2)|BYTES_SH(2), ANYSPACE, Unroll2Words},
3452 { CHANNELS_SH(3)|BYTES_SH(2), ANYSPACE, Unroll3Words},
3453 { CHANNELS_SH(4)|BYTES_SH(2), ANYSPACE, Unroll4Words},
3454
3455 { CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Unroll3WordsSwap},
3456 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll3WordsSkip1SwapFirst},
3457 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3WordsSkip1Swap},
3458 { CHANNELS_SH(4)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Unroll4WordsReverse},
3459 { CHANNELS_SH(4)|BYTES_SH(2)|SWAPFIRST_SH(1), ANYSPACE, Unroll4WordsSwapFirst},
3460 { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Unroll4WordsSwap},
3461 { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4WordsSwapSwapFirst},
3462
3463
3464 { BYTES_SH(2)|PLANAR_SH(1), ANYFLAVOR|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollPlanarWords},
3465 { BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollAnyWords},
3466
3467 { BYTES_SH(2)|PLANAR_SH(1), ANYFLAVOR|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE|PREMUL_SH(1), UnrollPlanarWordsPremul},
3468 { BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE|PREMUL_SH(1), UnrollAnyWordsPremul}
3469
3470 };
3471
3472
3473
3474 static const cmsFormattersFloat InputFormattersFloat[] = {
3475
3476 // Type Mask Function
3477 // ---------------------------- ------------------------------------ ----------------------------
3478 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, UnrollLabDoubleToFloat},
3479 { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, UnrollLabFloatToFloat},
3480
3481 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, UnrollXYZDoubleToFloat},
3482 { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, UnrollXYZFloatToFloat},
3483
3484 { FLOAT_SH(1)|BYTES_SH(4), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
3485 ANYPREMUL|ANYCHANNELS|ANYSPACE, UnrollFloatsToFloat},
3486
3487 { FLOAT_SH(1)|BYTES_SH(0), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
3488 ANYCHANNELS|ANYSPACE|ANYPREMUL, UnrollDoublesToFloat},
3489
3490 { TYPE_LabV2_8, 0, UnrollLabV2_8ToFloat },
3491 { TYPE_ALabV2_8, 0, UnrollALabV2_8ToFloat },
3492 { TYPE_LabV2_16, 0, UnrollLabV2_16ToFloat },
3493
3494 { BYTES_SH(1), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
3495 ANYCHANNELS|ANYSPACE, Unroll8ToFloat},
3496
3497 { BYTES_SH(2), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
3498 ANYCHANNELS|ANYSPACE, Unroll16ToFloat},
3499 #ifndef CMS_NO_HALF_SUPPORT
3500 { FLOAT_SH(1)|BYTES_SH(2), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
3501 ANYCHANNELS|ANYSPACE, UnrollHalfToFloat},
3502 #endif
3503 };
3504
3505
3506 // Bit fields set to one in the mask are not compared
3507 static
_cmsGetStockInputFormatter(cmsUInt32Number dwInput,cmsUInt32Number dwFlags)3508 cmsFormatter _cmsGetStockInputFormatter(cmsUInt32Number dwInput, cmsUInt32Number dwFlags)
3509 {
3510 cmsUInt32Number i;
3511 cmsFormatter fr;
3512
3513 switch (dwFlags) {
3514
3515 case CMS_PACK_FLAGS_16BITS: {
3516 for (i=0; i < sizeof(InputFormatters16) / sizeof(cmsFormatters16); i++) {
3517 const cmsFormatters16* f = InputFormatters16 + i;
3518
3519 if ((dwInput & ~f ->Mask) == f ->Type) {
3520 fr.Fmt16 = f ->Frm;
3521 return fr;
3522 }
3523 }
3524 }
3525 break;
3526
3527 case CMS_PACK_FLAGS_FLOAT: {
3528 for (i=0; i < sizeof(InputFormattersFloat) / sizeof(cmsFormattersFloat); i++) {
3529 const cmsFormattersFloat* f = InputFormattersFloat + i;
3530
3531 if ((dwInput & ~f ->Mask) == f ->Type) {
3532 fr.FmtFloat = f ->Frm;
3533 return fr;
3534 }
3535 }
3536 }
3537 break;
3538
3539 default:;
3540
3541 }
3542
3543 fr.Fmt16 = NULL;
3544 return fr;
3545 }
3546
3547 static const cmsFormatters16 OutputFormatters16[] = {
3548 // Type Mask Function
3549 // ---------------------------- ------------------------------------ ----------------------------
3550
3551 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, PackLabDoubleFrom16},
3552 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, PackXYZDoubleFrom16},
3553
3554 { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, PackLabFloatFrom16},
3555 { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, PackXYZFloatFrom16},
3556
3557 { FLOAT_SH(1)|BYTES_SH(0), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
3558 ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackDoubleFrom16},
3559 { FLOAT_SH(1)|BYTES_SH(4), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
3560 ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackFloatFrom16},
3561 #ifndef CMS_NO_HALF_SUPPORT
3562 { FLOAT_SH(1)|BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
3563 ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackHalfFrom16},
3564 #endif
3565
3566 { CHANNELS_SH(1)|BYTES_SH(1), ANYSPACE, Pack1Byte},
3567 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Pack1ByteSkip1},
3568 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack1ByteSkip1SwapFirst},
3569
3570 { CHANNELS_SH(1)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Pack1ByteReversed},
3571
3572 { TYPE_LabV2_8, 0, PackLabV2_8 },
3573 { TYPE_ALabV2_8, 0, PackALabV2_8 },
3574 { TYPE_LabV2_16, 0, PackLabV2_16 },
3575
3576 { CHANNELS_SH(3)|BYTES_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesOptimized},
3577 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesAndSkip1Optimized},
3578 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1)|OPTIMIZED_SH(1),
3579 ANYSPACE, Pack3BytesAndSkip1SwapFirstOptimized},
3580 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1)|OPTIMIZED_SH(1),
3581 ANYSPACE, Pack3BytesAndSkip1SwapSwapFirstOptimized},
3582 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|EXTRA_SH(1)|OPTIMIZED_SH(1),
3583 ANYSPACE, Pack3BytesAndSkip1SwapOptimized},
3584 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesSwapOptimized},
3585
3586
3587
3588 { CHANNELS_SH(3)|BYTES_SH(1), ANYSPACE, Pack3Bytes},
3589 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Pack3BytesAndSkip1},
3590 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack3BytesAndSkip1SwapFirst},
3591 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1),
3592 ANYSPACE, Pack3BytesAndSkip1SwapSwapFirst},
3593 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|EXTRA_SH(1), ANYSPACE, Pack3BytesAndSkip1Swap},
3594 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack3BytesSwap},
3595 { CHANNELS_SH(4)|BYTES_SH(1), ANYSPACE, Pack4Bytes},
3596 { CHANNELS_SH(4)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Pack4BytesReverse},
3597 { CHANNELS_SH(4)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack4BytesSwapFirst},
3598 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack4BytesSwap},
3599 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack4BytesSwapSwapFirst},
3600 { CHANNELS_SH(6)|BYTES_SH(1), ANYSPACE, Pack6Bytes},
3601 { CHANNELS_SH(6)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack6BytesSwap},
3602
3603 { BYTES_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|
3604 ANYSPACE|ANYPREMUL, PackChunkyBytes},
3605
3606 { BYTES_SH(1)|PLANAR_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
3607 ANYCHANNELS|ANYSPACE|ANYPREMUL, PackPlanarBytes},
3608
3609
3610 { CHANNELS_SH(1)|BYTES_SH(2), ANYSPACE, Pack1Word},
3611 { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(1), ANYSPACE, Pack1WordSkip1},
3612 { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack1WordSkip1SwapFirst},
3613 { CHANNELS_SH(1)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Pack1WordReversed},
3614 { CHANNELS_SH(1)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack1WordBigEndian},
3615 { CHANNELS_SH(3)|BYTES_SH(2), ANYSPACE, Pack3Words},
3616 { CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack3WordsSwap},
3617 { CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack3WordsBigEndian},
3618 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1), ANYSPACE, Pack3WordsAndSkip1},
3619 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack3WordsAndSkip1Swap},
3620 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack3WordsAndSkip1SwapFirst},
3621
3622 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1),
3623 ANYSPACE, Pack3WordsAndSkip1SwapSwapFirst},
3624
3625 { CHANNELS_SH(4)|BYTES_SH(2), ANYSPACE, Pack4Words},
3626 { CHANNELS_SH(4)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Pack4WordsReverse},
3627 { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack4WordsSwap},
3628 { CHANNELS_SH(4)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack4WordsBigEndian},
3629
3630 { CHANNELS_SH(6)|BYTES_SH(2), ANYSPACE, Pack6Words},
3631 { CHANNELS_SH(6)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack6WordsSwap},
3632
3633 { BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYENDIAN|
3634 ANYEXTRA|ANYCHANNELS|ANYSPACE|ANYPREMUL, PackChunkyWords},
3635 { BYTES_SH(2)|PLANAR_SH(1), ANYFLAVOR|ANYENDIAN|ANYSWAP|ANYEXTRA|
3636 ANYCHANNELS|ANYSPACE|ANYPREMUL, PackPlanarWords}
3637
3638 };
3639
3640
3641 static const cmsFormattersFloat OutputFormattersFloat[] = {
3642 // Type Mask Function
3643 // ---------------------------- --------------------------------------------------- ----------------------------
3644 { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, PackLabFloatFromFloat},
3645 { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, PackXYZFloatFromFloat},
3646
3647 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, PackLabDoubleFromFloat},
3648 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, PackXYZDoubleFromFloat},
3649
3650 { FLOAT_SH(1)|BYTES_SH(4), ANYPLANAR|
3651 ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackFloatsFromFloat },
3652 { FLOAT_SH(1)|BYTES_SH(0), ANYPLANAR|
3653 ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackDoublesFromFloat },
3654 #ifndef CMS_NO_HALF_SUPPORT
3655 { FLOAT_SH(1)|BYTES_SH(2),
3656 ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackHalfFromFloat },
3657 #endif
3658
3659 };
3660
3661
3662 // Bit fields set to one in the mask are not compared
3663 static
_cmsGetStockOutputFormatter(cmsUInt32Number dwInput,cmsUInt32Number dwFlags)3664 cmsFormatter _cmsGetStockOutputFormatter(cmsUInt32Number dwInput, cmsUInt32Number dwFlags)
3665 {
3666 cmsUInt32Number i;
3667 cmsFormatter fr;
3668
3669 // Optimization is only a hint
3670 dwInput &= ~OPTIMIZED_SH(1);
3671
3672 switch (dwFlags)
3673 {
3674
3675 case CMS_PACK_FLAGS_16BITS: {
3676
3677 for (i=0; i < sizeof(OutputFormatters16) / sizeof(cmsFormatters16); i++) {
3678 const cmsFormatters16* f = OutputFormatters16 + i;
3679
3680 if ((dwInput & ~f ->Mask) == f ->Type) {
3681 fr.Fmt16 = f ->Frm;
3682 return fr;
3683 }
3684 }
3685 }
3686 break;
3687
3688 case CMS_PACK_FLAGS_FLOAT: {
3689
3690 for (i=0; i < sizeof(OutputFormattersFloat) / sizeof(cmsFormattersFloat); i++) {
3691 const cmsFormattersFloat* f = OutputFormattersFloat + i;
3692
3693 if ((dwInput & ~f ->Mask) == f ->Type) {
3694 fr.FmtFloat = f ->Frm;
3695 return fr;
3696 }
3697 }
3698 }
3699 break;
3700
3701 default:;
3702
3703 }
3704
3705 fr.Fmt16 = NULL;
3706 return fr;
3707 }
3708
3709
3710 typedef struct _cms_formatters_factory_list {
3711
3712 cmsFormatterFactory Factory;
3713 struct _cms_formatters_factory_list *Next;
3714
3715 } cmsFormattersFactoryList;
3716
3717 _cmsFormattersPluginChunkType _cmsFormattersPluginChunk = { NULL };
3718
3719
3720 // Duplicates the zone of memory used by the plug-in in the new context
3721 static
DupFormatterFactoryList(struct _cmsContext_struct * ctx,const struct _cmsContext_struct * src)3722 void DupFormatterFactoryList(struct _cmsContext_struct* ctx,
3723 const struct _cmsContext_struct* src)
3724 {
3725 _cmsFormattersPluginChunkType newHead = { NULL };
3726 cmsFormattersFactoryList* entry;
3727 cmsFormattersFactoryList* Anterior = NULL;
3728 _cmsFormattersPluginChunkType* head = (_cmsFormattersPluginChunkType*) src->chunks[FormattersPlugin];
3729
3730 _cmsAssert(head != NULL);
3731
3732 // Walk the list copying all nodes
3733 for (entry = head->FactoryList;
3734 entry != NULL;
3735 entry = entry ->Next) {
3736
3737 cmsFormattersFactoryList *newEntry = ( cmsFormattersFactoryList *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(cmsFormattersFactoryList));
3738
3739 if (newEntry == NULL)
3740 return;
3741
3742 // We want to keep the linked list order, so this is a little bit tricky
3743 newEntry -> Next = NULL;
3744 if (Anterior)
3745 Anterior -> Next = newEntry;
3746
3747 Anterior = newEntry;
3748
3749 if (newHead.FactoryList == NULL)
3750 newHead.FactoryList = newEntry;
3751 }
3752
3753 ctx ->chunks[FormattersPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsFormattersPluginChunkType));
3754 }
3755
3756 // The interpolation plug-in memory chunk allocator/dup
_cmsAllocFormattersPluginChunk(struct _cmsContext_struct * ctx,const struct _cmsContext_struct * src)3757 void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct* ctx,
3758 const struct _cmsContext_struct* src)
3759 {
3760 _cmsAssert(ctx != NULL);
3761
3762 if (src != NULL) {
3763
3764 // Duplicate the LIST
3765 DupFormatterFactoryList(ctx, src);
3766 }
3767 else {
3768 static _cmsFormattersPluginChunkType FormattersPluginChunk = { NULL };
3769 ctx ->chunks[FormattersPlugin] = _cmsSubAllocDup(ctx ->MemPool, &FormattersPluginChunk, sizeof(_cmsFormattersPluginChunkType));
3770 }
3771 }
3772
3773
3774
3775 // Formatters management
_cmsRegisterFormattersPlugin(cmsContext ContextID,cmsPluginBase * Data)3776 cmsBool _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Data)
3777 {
3778 _cmsFormattersPluginChunkType* ctx = ( _cmsFormattersPluginChunkType*) _cmsContextGetClientChunk(ContextID, FormattersPlugin);
3779 cmsPluginFormatters* Plugin = (cmsPluginFormatters*) Data;
3780 cmsFormattersFactoryList* fl ;
3781
3782 // Reset to built-in defaults
3783 if (Data == NULL) {
3784
3785 ctx ->FactoryList = NULL;
3786 return TRUE;
3787 }
3788
3789 fl = (cmsFormattersFactoryList*) _cmsPluginMalloc(ContextID, sizeof(cmsFormattersFactoryList));
3790 if (fl == NULL) return FALSE;
3791
3792 fl ->Factory = Plugin ->FormattersFactory;
3793
3794 fl ->Next = ctx -> FactoryList;
3795 ctx ->FactoryList = fl;
3796
3797 return TRUE;
3798 }
3799
_cmsGetFormatter(cmsContext ContextID,cmsUInt32Number Type,cmsFormatterDirection Dir,cmsUInt32Number dwFlags)3800 cmsFormatter CMSEXPORT _cmsGetFormatter(cmsContext ContextID,
3801 cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8
3802 cmsFormatterDirection Dir,
3803 cmsUInt32Number dwFlags)
3804 {
3805 _cmsFormattersPluginChunkType* ctx = ( _cmsFormattersPluginChunkType*) _cmsContextGetClientChunk(ContextID, FormattersPlugin);
3806 cmsFormattersFactoryList* f;
3807
3808 if (T_CHANNELS(Type) == 0) {
3809 static const cmsFormatter nullFormatter = { 0 };
3810 return nullFormatter;
3811 }
3812
3813 for (f =ctx->FactoryList; f != NULL; f = f ->Next) {
3814
3815 cmsFormatter fn = f ->Factory(Type, Dir, dwFlags);
3816 if (fn.Fmt16 != NULL) return fn;
3817 }
3818
3819 // Revert to default
3820 if (Dir == cmsFormatterInput)
3821 return _cmsGetStockInputFormatter(Type, dwFlags);
3822 else
3823 return _cmsGetStockOutputFormatter(Type, dwFlags);
3824 }
3825
3826
3827 // Return whatever given formatter refers to float values
_cmsFormatterIsFloat(cmsUInt32Number Type)3828 cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type)
3829 {
3830 return T_FLOAT(Type) ? TRUE : FALSE;
3831 }
3832
3833 // Return whatever given formatter refers to 8 bits
_cmsFormatterIs8bit(cmsUInt32Number Type)3834 cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type)
3835 {
3836 cmsUInt32Number Bytes = T_BYTES(Type);
3837
3838 return (Bytes == 1);
3839 }
3840
3841 // Build a suitable formatter for the colorspace of this profile
cmsFormatterForColorspaceOfProfile(cmsHPROFILE hProfile,cmsUInt32Number nBytes,cmsBool lIsFloat)3842 cmsUInt32Number CMSEXPORT cmsFormatterForColorspaceOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat)
3843 {
3844
3845 cmsColorSpaceSignature ColorSpace = cmsGetColorSpace(hProfile);
3846 cmsUInt32Number ColorSpaceBits = (cmsUInt32Number) _cmsLCMScolorSpace(ColorSpace);
3847 cmsInt32Number nOutputChans = cmsChannelsOfColorSpace(ColorSpace);
3848 cmsUInt32Number Float = lIsFloat ? 1U : 0;
3849
3850 // Unsupported color space?
3851 if (nOutputChans < 0) return 0;
3852
3853 // Create a fake formatter for result
3854 return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans);
3855 }
3856
3857 // Build a suitable formatter for the colorspace of this profile
cmsFormatterForPCSOfProfile(cmsHPROFILE hProfile,cmsUInt32Number nBytes,cmsBool lIsFloat)3858 cmsUInt32Number CMSEXPORT cmsFormatterForPCSOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat)
3859 {
3860
3861 cmsColorSpaceSignature ColorSpace = cmsGetPCS(hProfile);
3862
3863 cmsUInt32Number ColorSpaceBits = (cmsUInt32Number) _cmsLCMScolorSpace(ColorSpace);
3864 cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace);
3865 cmsUInt32Number Float = lIsFloat ? 1U : 0;
3866
3867 // Create a fake formatter for result
3868 return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans);
3869 }
3870
3871