1 //---------------------------------------------------------------------------------
3 // Little Color Management System
4 // Copyright (c) 1998-2023 Marti Maria Saguer
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:
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
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.
24 //---------------------------------------------------------------------------------
27 #include "lcms2_internal.h"
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
34 // ---------------------------------------------------------------------------
37 // This macro return words stored as big endian
38 #define CHANGE_ENDIAN(w) (cmsUInt16Number) ((cmsUInt16Number) ((w)<<8)|((w)>>8))
40 // These macros handles reversing (negative)
41 #define REVERSE_FLAVOR_8(x) ((cmsUInt8Number) (0xff-(x)))
42 #define REVERSE_FLAVOR_16(x) ((cmsUInt16Number)(0xffff-(x)))
44 // * 0xffff / 0xff00 = (255 * 257) / (255 * 256) = 257 / 256
45 cmsINLINE cmsUInt16Number
FomLabV2ToLabV4(cmsUInt16Number x
)
47 int a
= (x
<< 8 | x
) >> 8; // * 257 / 256
48 if ( a
> 0xffff) return 0xffff;
49 return (cmsUInt16Number
) a
;
52 // * 0xf00 / 0xffff = * 256 / 257
53 cmsINLINE cmsUInt16Number
FomLabV4ToLabV2(cmsUInt16Number x
)
55 return (cmsUInt16Number
) (((x
<< 8) + 0x80) / 257);
69 cmsFormatterFloat Frm
;
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)
85 // Suppress waning about info never being used
88 #pragma warning(disable : 4100)
91 // Unpacking routines (16 bits) ----------------------------------------------------------------------------------------
94 // Does almost everything but is slow
96 cmsUInt8Number
* UnrollChunkyBytes(CMSREGISTER _cmsTRANSFORM
* info
,
97 CMSREGISTER cmsUInt16Number wIn
[],
98 CMSREGISTER cmsUInt8Number
* accum
,
99 CMSREGISTER cmsUInt32Number Stride
)
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
);
108 cmsUInt32Number ExtraFirst
= DoSwap
^ SwapFirst
;
111 cmsUInt32Number alpha_factor
= 1;
116 alpha_factor
= _cmsToFixedDomain(FROM_8_TO_16(accum
[0]));
123 alpha_factor
= _cmsToFixedDomain(FROM_8_TO_16(accum
[nChan
]));
126 for (i
=0; i
< nChan
; i
++) {
128 cmsUInt32Number index
= DoSwap
? (nChan
- i
- 1) : i
;
130 v
= FROM_8_TO_16(*accum
);
131 v
= Reverse
? REVERSE_FLAVOR_16(v
) : v
;
133 if (Premul
&& alpha_factor
> 0)
135 v
= ((cmsUInt32Number
)((cmsUInt32Number
)v
<< 16) / alpha_factor
);
136 if (v
> 0xffff) v
= 0xffff;
139 wIn
[index
] = (cmsUInt16Number
) v
;
147 if (Extra
== 0 && SwapFirst
) {
148 cmsUInt16Number tmp
= wIn
[0];
150 memmove(&wIn
[0], &wIn
[1], (nChan
-1) * sizeof(cmsUInt16Number
));
156 cmsUNUSED_PARAMETER(info
);
157 cmsUNUSED_PARAMETER(Stride
);
162 // Extra channels are just ignored because come in the next planes
164 cmsUInt8Number
* UnrollPlanarBytes(CMSREGISTER _cmsTRANSFORM
* info
,
165 CMSREGISTER cmsUInt16Number wIn
[],
166 CMSREGISTER cmsUInt8Number
* accum
,
167 CMSREGISTER cmsUInt32Number Stride
)
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
);
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;
183 alpha_factor
= _cmsToFixedDomain(FROM_8_TO_16(accum
[0]));
186 accum
+= Extra
* Stride
;
191 alpha_factor
= _cmsToFixedDomain(FROM_8_TO_16(accum
[(nChan
) * Stride
]));
194 for (i
=0; i
< nChan
; i
++) {
196 cmsUInt32Number index
= DoSwap
? (nChan
- i
- 1) : i
;
197 cmsUInt32Number v
= FROM_8_TO_16(*accum
);
199 v
= Reverse
? REVERSE_FLAVOR_16(v
) : v
;
201 if (Premul
&& alpha_factor
> 0)
203 v
= ((cmsUInt32Number
)((cmsUInt32Number
)v
<< 16) / alpha_factor
);
204 if (v
> 0xffff) v
= 0xffff;
207 wIn
[index
] = (cmsUInt16Number
) v
;
215 // Special cases, provided for performance
217 cmsUInt8Number
* Unroll4Bytes(CMSREGISTER _cmsTRANSFORM
* info
,
218 CMSREGISTER cmsUInt16Number wIn
[],
219 CMSREGISTER cmsUInt8Number
* accum
,
220 CMSREGISTER cmsUInt32Number Stride
)
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
229 cmsUNUSED_PARAMETER(info
);
230 cmsUNUSED_PARAMETER(Stride
);
234 cmsUInt8Number
* Unroll4BytesReverse(CMSREGISTER _cmsTRANSFORM
* info
,
235 CMSREGISTER cmsUInt16Number wIn
[],
236 CMSREGISTER cmsUInt8Number
* accum
,
237 CMSREGISTER cmsUInt32Number Stride
)
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
246 cmsUNUSED_PARAMETER(info
);
247 cmsUNUSED_PARAMETER(Stride
);
251 cmsUInt8Number
* Unroll4BytesSwapFirst(CMSREGISTER _cmsTRANSFORM
* info
,
252 CMSREGISTER cmsUInt16Number wIn
[],
253 CMSREGISTER cmsUInt8Number
* accum
,
254 CMSREGISTER cmsUInt32Number Stride
)
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
263 cmsUNUSED_PARAMETER(info
);
264 cmsUNUSED_PARAMETER(Stride
);
269 cmsUInt8Number
* Unroll4BytesSwap(CMSREGISTER _cmsTRANSFORM
* info
,
270 CMSREGISTER cmsUInt16Number wIn
[],
271 CMSREGISTER cmsUInt8Number
* accum
,
272 CMSREGISTER cmsUInt32Number Stride
)
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
281 cmsUNUSED_PARAMETER(info
);
282 cmsUNUSED_PARAMETER(Stride
);
286 cmsUInt8Number
* Unroll4BytesSwapSwapFirst(CMSREGISTER _cmsTRANSFORM
* info
,
287 CMSREGISTER cmsUInt16Number wIn
[],
288 CMSREGISTER cmsUInt8Number
* accum
,
289 CMSREGISTER cmsUInt32Number Stride
)
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
298 cmsUNUSED_PARAMETER(info
);
299 cmsUNUSED_PARAMETER(Stride
);
303 cmsUInt8Number
* Unroll3Bytes(CMSREGISTER _cmsTRANSFORM
* info
,
304 CMSREGISTER cmsUInt16Number wIn
[],
305 CMSREGISTER cmsUInt8Number
* accum
,
306 CMSREGISTER cmsUInt32Number Stride
)
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
314 cmsUNUSED_PARAMETER(info
);
315 cmsUNUSED_PARAMETER(Stride
);
319 cmsUInt8Number
* Unroll3BytesSkip1Swap(CMSREGISTER _cmsTRANSFORM
* info
,
320 CMSREGISTER cmsUInt16Number wIn
[],
321 CMSREGISTER cmsUInt8Number
* accum
,
322 CMSREGISTER cmsUInt32Number Stride
)
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
331 cmsUNUSED_PARAMETER(info
);
332 cmsUNUSED_PARAMETER(Stride
);
336 cmsUInt8Number
* Unroll3BytesSkip1SwapSwapFirst(CMSREGISTER _cmsTRANSFORM
* info
,
337 CMSREGISTER cmsUInt16Number wIn
[],
338 CMSREGISTER cmsUInt8Number
* accum
,
339 CMSREGISTER cmsUInt32Number Stride
)
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
348 cmsUNUSED_PARAMETER(info
);
349 cmsUNUSED_PARAMETER(Stride
);
353 cmsUInt8Number
* Unroll3BytesSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM
* info
,
354 CMSREGISTER cmsUInt16Number wIn
[],
355 CMSREGISTER cmsUInt8Number
* accum
,
356 CMSREGISTER cmsUInt32Number Stride
)
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
365 cmsUNUSED_PARAMETER(info
);
366 cmsUNUSED_PARAMETER(Stride
);
372 cmsUInt8Number
* Unroll3BytesSwap(CMSREGISTER _cmsTRANSFORM
* info
,
373 CMSREGISTER cmsUInt16Number wIn
[],
374 CMSREGISTER cmsUInt8Number
* accum
,
375 CMSREGISTER cmsUInt32Number Stride
)
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
383 cmsUNUSED_PARAMETER(info
);
384 cmsUNUSED_PARAMETER(Stride
);
388 cmsUInt8Number
* UnrollLabV2_8(CMSREGISTER _cmsTRANSFORM
* info
,
389 CMSREGISTER cmsUInt16Number wIn
[],
390 CMSREGISTER cmsUInt8Number
* accum
,
391 CMSREGISTER cmsUInt32Number Stride
)
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
399 cmsUNUSED_PARAMETER(info
);
400 cmsUNUSED_PARAMETER(Stride
);
404 cmsUInt8Number
* UnrollALabV2_8(CMSREGISTER _cmsTRANSFORM
* info
,
405 CMSREGISTER cmsUInt16Number wIn
[],
406 CMSREGISTER cmsUInt8Number
* accum
,
407 CMSREGISTER cmsUInt32Number Stride
)
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
416 cmsUNUSED_PARAMETER(info
);
417 cmsUNUSED_PARAMETER(Stride
);
421 cmsUInt8Number
* UnrollLabV2_16(CMSREGISTER _cmsTRANSFORM
* info
,
422 CMSREGISTER cmsUInt16Number wIn
[],
423 CMSREGISTER cmsUInt8Number
* accum
,
424 CMSREGISTER cmsUInt32Number Stride
)
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
432 cmsUNUSED_PARAMETER(info
);
433 cmsUNUSED_PARAMETER(Stride
);
438 cmsUInt8Number
* Unroll2Bytes(CMSREGISTER _cmsTRANSFORM
* info
,
439 CMSREGISTER cmsUInt16Number wIn
[],
440 CMSREGISTER cmsUInt8Number
* accum
,
441 CMSREGISTER cmsUInt32Number Stride
)
443 wIn
[0] = FROM_8_TO_16(*accum
); accum
++; // ch1
444 wIn
[1] = FROM_8_TO_16(*accum
); accum
++; // ch2
448 cmsUNUSED_PARAMETER(info
);
449 cmsUNUSED_PARAMETER(Stride
);
455 // Monochrome duplicates L into RGB for null-transforms
457 cmsUInt8Number
* Unroll1Byte(CMSREGISTER _cmsTRANSFORM
* info
,
458 CMSREGISTER cmsUInt16Number wIn
[],
459 CMSREGISTER cmsUInt8Number
* accum
,
460 CMSREGISTER cmsUInt32Number Stride
)
462 wIn
[0] = wIn
[1] = wIn
[2] = FROM_8_TO_16(*accum
); accum
++; // L
466 cmsUNUSED_PARAMETER(info
);
467 cmsUNUSED_PARAMETER(Stride
);
472 cmsUInt8Number
* Unroll1ByteSkip1(CMSREGISTER _cmsTRANSFORM
* info
,
473 CMSREGISTER cmsUInt16Number wIn
[],
474 CMSREGISTER cmsUInt8Number
* accum
,
475 CMSREGISTER cmsUInt32Number Stride
)
477 wIn
[0] = wIn
[1] = wIn
[2] = FROM_8_TO_16(*accum
); accum
++; // L
482 cmsUNUSED_PARAMETER(info
);
483 cmsUNUSED_PARAMETER(Stride
);
487 cmsUInt8Number
* Unroll1ByteSkip2(CMSREGISTER _cmsTRANSFORM
* info
,
488 CMSREGISTER cmsUInt16Number wIn
[],
489 CMSREGISTER cmsUInt8Number
* accum
,
490 CMSREGISTER cmsUInt32Number Stride
)
492 wIn
[0] = wIn
[1] = wIn
[2] = FROM_8_TO_16(*accum
); accum
++; // L
497 cmsUNUSED_PARAMETER(info
);
498 cmsUNUSED_PARAMETER(Stride
);
502 cmsUInt8Number
* Unroll1ByteReversed(CMSREGISTER _cmsTRANSFORM
* info
,
503 CMSREGISTER cmsUInt16Number wIn
[],
504 CMSREGISTER cmsUInt8Number
* accum
,
505 CMSREGISTER cmsUInt32Number Stride
)
507 wIn
[0] = wIn
[1] = wIn
[2] = REVERSE_FLAVOR_16(FROM_8_TO_16(*accum
)); accum
++; // L
511 cmsUNUSED_PARAMETER(info
);
512 cmsUNUSED_PARAMETER(Stride
);
517 cmsUInt8Number
* UnrollAnyWords(CMSREGISTER _cmsTRANSFORM
* info
,
518 CMSREGISTER cmsUInt16Number wIn
[],
519 CMSREGISTER cmsUInt8Number
* accum
,
520 CMSREGISTER cmsUInt32Number Stride
)
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
;
532 accum
+= Extra
* sizeof(cmsUInt16Number
);
535 for (i
=0; i
< nChan
; i
++) {
537 cmsUInt32Number index
= DoSwap
? (nChan
- i
- 1) : i
;
538 cmsUInt16Number v
= *(cmsUInt16Number
*) accum
;
541 v
= CHANGE_ENDIAN(v
);
543 wIn
[index
] = Reverse
? REVERSE_FLAVOR_16(v
) : v
;
545 accum
+= sizeof(cmsUInt16Number
);
549 accum
+= Extra
* sizeof(cmsUInt16Number
);
552 if (Extra
== 0 && SwapFirst
) {
554 cmsUInt16Number tmp
= wIn
[0];
556 memmove(&wIn
[0], &wIn
[1], (nChan
-1) * sizeof(cmsUInt16Number
));
562 cmsUNUSED_PARAMETER(Stride
);
567 cmsUInt8Number
* UnrollAnyWordsPremul(CMSREGISTER _cmsTRANSFORM
* info
,
568 CMSREGISTER cmsUInt16Number wIn
[],
569 CMSREGISTER cmsUInt8Number
* accum
,
570 CMSREGISTER cmsUInt32Number Stride
)
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
;
580 cmsUInt16Number alpha
= (ExtraFirst
? accum
[0] : accum
[nChan
- 1]);
581 cmsUInt32Number alpha_factor
= _cmsToFixedDomain(FROM_8_TO_16(alpha
));
584 accum
+= sizeof(cmsUInt16Number
);
587 for (i
=0; i
< nChan
; i
++) {
589 cmsUInt32Number index
= DoSwap
? (nChan
- i
- 1) : i
;
590 cmsUInt32Number v
= *(cmsUInt16Number
*) accum
;
593 v
= CHANGE_ENDIAN(v
);
595 if (alpha_factor
> 0) {
597 v
= (v
<< 16) / alpha_factor
;
598 if (v
> 0xffff) v
= 0xffff;
601 wIn
[index
] = (cmsUInt16Number
) (Reverse
? REVERSE_FLAVOR_16(v
) : v
);
603 accum
+= sizeof(cmsUInt16Number
);
607 accum
+= sizeof(cmsUInt16Number
);
612 cmsUNUSED_PARAMETER(Stride
);
618 cmsUInt8Number
* UnrollPlanarWords(CMSREGISTER _cmsTRANSFORM
* info
,
619 CMSREGISTER cmsUInt16Number wIn
[],
620 CMSREGISTER cmsUInt8Number
* accum
,
621 CMSREGISTER cmsUInt32Number Stride
)
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
);
628 cmsUInt8Number
* Init
= accum
;
631 accum
+= T_EXTRA(info
-> InputFormat
) * Stride
;
634 for (i
=0; i
< nChan
; i
++) {
636 cmsUInt32Number index
= DoSwap
? (nChan
- i
- 1) : i
;
637 cmsUInt16Number v
= *(cmsUInt16Number
*) accum
;
640 v
= CHANGE_ENDIAN(v
);
642 wIn
[index
] = Reverse
? REVERSE_FLAVOR_16(v
) : v
;
647 return (Init
+ sizeof(cmsUInt16Number
));
651 cmsUInt8Number
* UnrollPlanarWordsPremul(CMSREGISTER _cmsTRANSFORM
* info
,
652 CMSREGISTER cmsUInt16Number wIn
[],
653 CMSREGISTER cmsUInt8Number
* accum
,
654 CMSREGISTER cmsUInt32Number Stride
)
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
);
662 cmsUInt32Number ExtraFirst
= DoSwap
^ SwapFirst
;
663 cmsUInt8Number
* Init
= accum
;
665 cmsUInt16Number alpha
= (ExtraFirst
? accum
[0] : accum
[(nChan
- 1) * Stride
]);
666 cmsUInt32Number alpha_factor
= _cmsToFixedDomain(FROM_8_TO_16(alpha
));
672 for (i
=0; i
< nChan
; i
++) {
674 cmsUInt32Number index
= DoSwap
? (nChan
- i
- 1) : i
;
675 cmsUInt32Number v
= (cmsUInt32Number
) *(cmsUInt16Number
*) accum
;
678 v
= CHANGE_ENDIAN(v
);
680 if (alpha_factor
> 0) {
682 v
= (v
<< 16) / alpha_factor
;
683 if (v
> 0xffff) v
= 0xffff;
686 wIn
[index
] = (cmsUInt16Number
) (Reverse
? REVERSE_FLAVOR_16(v
) : v
);
691 return (Init
+ sizeof(cmsUInt16Number
));
695 cmsUInt8Number
* Unroll4Words(CMSREGISTER _cmsTRANSFORM
* info
,
696 CMSREGISTER cmsUInt16Number wIn
[],
697 CMSREGISTER cmsUInt8Number
* accum
,
698 CMSREGISTER cmsUInt32Number Stride
)
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
707 cmsUNUSED_PARAMETER(info
);
708 cmsUNUSED_PARAMETER(Stride
);
712 cmsUInt8Number
* Unroll4WordsReverse(CMSREGISTER _cmsTRANSFORM
* info
,
713 CMSREGISTER cmsUInt16Number wIn
[],
714 CMSREGISTER cmsUInt8Number
* accum
,
715 CMSREGISTER cmsUInt32Number Stride
)
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
724 cmsUNUSED_PARAMETER(info
);
725 cmsUNUSED_PARAMETER(Stride
);
729 cmsUInt8Number
* Unroll4WordsSwapFirst(CMSREGISTER _cmsTRANSFORM
* info
,
730 CMSREGISTER cmsUInt16Number wIn
[],
731 CMSREGISTER cmsUInt8Number
* accum
,
732 CMSREGISTER cmsUInt32Number Stride
)
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
741 cmsUNUSED_PARAMETER(info
);
742 cmsUNUSED_PARAMETER(Stride
);
747 cmsUInt8Number
* Unroll4WordsSwap(CMSREGISTER _cmsTRANSFORM
* info
,
748 CMSREGISTER cmsUInt16Number wIn
[],
749 CMSREGISTER cmsUInt8Number
* accum
,
750 CMSREGISTER cmsUInt32Number Stride
)
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
759 cmsUNUSED_PARAMETER(info
);
760 cmsUNUSED_PARAMETER(Stride
);
764 cmsUInt8Number
* Unroll4WordsSwapSwapFirst(CMSREGISTER _cmsTRANSFORM
* info
,
765 CMSREGISTER cmsUInt16Number wIn
[],
766 CMSREGISTER cmsUInt8Number
* accum
,
767 CMSREGISTER cmsUInt32Number Stride
)
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
776 cmsUNUSED_PARAMETER(info
);
777 cmsUNUSED_PARAMETER(Stride
);
781 cmsUInt8Number
* Unroll3Words(CMSREGISTER _cmsTRANSFORM
* info
,
782 CMSREGISTER cmsUInt16Number wIn
[],
783 CMSREGISTER cmsUInt8Number
* accum
,
784 CMSREGISTER cmsUInt32Number Stride
)
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
792 cmsUNUSED_PARAMETER(info
);
793 cmsUNUSED_PARAMETER(Stride
);
797 cmsUInt8Number
* Unroll3WordsSwap(CMSREGISTER _cmsTRANSFORM
* info
,
798 CMSREGISTER cmsUInt16Number wIn
[],
799 CMSREGISTER cmsUInt8Number
* accum
,
800 CMSREGISTER cmsUInt32Number Stride
)
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
808 cmsUNUSED_PARAMETER(info
);
809 cmsUNUSED_PARAMETER(Stride
);
813 cmsUInt8Number
* Unroll3WordsSkip1Swap(CMSREGISTER _cmsTRANSFORM
* info
,
814 CMSREGISTER cmsUInt16Number wIn
[],
815 CMSREGISTER cmsUInt8Number
* accum
,
816 CMSREGISTER cmsUInt32Number Stride
)
819 wIn
[2] = *(cmsUInt16Number
*) accum
; accum
+= 2; // R
820 wIn
[1] = *(cmsUInt16Number
*) accum
; accum
+= 2; // G
821 wIn
[0] = *(cmsUInt16Number
*) accum
; accum
+= 2; // B
825 cmsUNUSED_PARAMETER(info
);
826 cmsUNUSED_PARAMETER(Stride
);
830 cmsUInt8Number
* Unroll3WordsSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM
* info
,
831 CMSREGISTER cmsUInt16Number wIn
[],
832 CMSREGISTER cmsUInt8Number
* accum
,
833 CMSREGISTER cmsUInt32Number Stride
)
836 wIn
[0] = *(cmsUInt16Number
*) accum
; accum
+= 2; // R
837 wIn
[1] = *(cmsUInt16Number
*) accum
; accum
+= 2; // G
838 wIn
[2] = *(cmsUInt16Number
*) accum
; accum
+= 2; // B
842 cmsUNUSED_PARAMETER(info
);
843 cmsUNUSED_PARAMETER(Stride
);
847 cmsUInt8Number
* Unroll1Word(CMSREGISTER _cmsTRANSFORM
* info
,
848 CMSREGISTER cmsUInt16Number wIn
[],
849 CMSREGISTER cmsUInt8Number
* accum
,
850 CMSREGISTER cmsUInt32Number Stride
)
852 wIn
[0] = wIn
[1] = wIn
[2] = *(cmsUInt16Number
*) accum
; accum
+= 2; // L
856 cmsUNUSED_PARAMETER(info
);
857 cmsUNUSED_PARAMETER(Stride
);
861 cmsUInt8Number
* Unroll1WordReversed(CMSREGISTER _cmsTRANSFORM
* info
,
862 CMSREGISTER cmsUInt16Number wIn
[],
863 CMSREGISTER cmsUInt8Number
* accum
,
864 CMSREGISTER cmsUInt32Number Stride
)
866 wIn
[0] = wIn
[1] = wIn
[2] = REVERSE_FLAVOR_16(*(cmsUInt16Number
*) accum
); accum
+= 2;
870 cmsUNUSED_PARAMETER(info
);
871 cmsUNUSED_PARAMETER(Stride
);
875 cmsUInt8Number
* Unroll1WordSkip3(CMSREGISTER _cmsTRANSFORM
* info
,
876 CMSREGISTER cmsUInt16Number wIn
[],
877 CMSREGISTER cmsUInt8Number
* accum
,
878 CMSREGISTER cmsUInt32Number Stride
)
880 wIn
[0] = wIn
[1] = wIn
[2] = *(cmsUInt16Number
*) accum
;
886 cmsUNUSED_PARAMETER(info
);
887 cmsUNUSED_PARAMETER(Stride
);
891 cmsUInt8Number
* Unroll2Words(CMSREGISTER _cmsTRANSFORM
* info
,
892 CMSREGISTER cmsUInt16Number wIn
[],
893 CMSREGISTER cmsUInt8Number
* accum
,
894 CMSREGISTER cmsUInt32Number Stride
)
896 wIn
[0] = *(cmsUInt16Number
*) accum
; accum
+= 2; // ch1
897 wIn
[1] = *(cmsUInt16Number
*) accum
; accum
+= 2; // ch2
901 cmsUNUSED_PARAMETER(info
);
902 cmsUNUSED_PARAMETER(Stride
);
906 // This is a conversion of Lab double to 16 bits
908 cmsUInt8Number
* UnrollLabDoubleTo16(CMSREGISTER _cmsTRANSFORM
* info
,
909 CMSREGISTER cmsUInt16Number wIn
[],
910 CMSREGISTER cmsUInt8Number
* accum
,
911 CMSREGISTER cmsUInt32Number Stride
)
913 if (T_PLANAR(info
-> InputFormat
)) {
916 cmsUInt8Number
* pos_L
;
917 cmsUInt8Number
* pos_a
;
918 cmsUInt8Number
* pos_b
;
921 pos_a
= accum
+ Stride
;
922 pos_b
= accum
+ Stride
* 2;
924 Lab
.L
= *(cmsFloat64Number
*) pos_L
;
925 Lab
.a
= *(cmsFloat64Number
*) pos_a
;
926 Lab
.b
= *(cmsFloat64Number
*) pos_b
;
928 cmsFloat2LabEncoded(wIn
, &Lab
);
929 return accum
+ sizeof(cmsFloat64Number
);
933 cmsFloat2LabEncoded(wIn
, (cmsCIELab
*) accum
);
934 accum
+= sizeof(cmsCIELab
) + T_EXTRA(info
->InputFormat
) * sizeof(cmsFloat64Number
);
940 // This is a conversion of Lab float to 16 bits
942 cmsUInt8Number
* UnrollLabFloatTo16(CMSREGISTER _cmsTRANSFORM
* info
,
943 CMSREGISTER cmsUInt16Number wIn
[],
944 CMSREGISTER cmsUInt8Number
* accum
,
945 CMSREGISTER cmsUInt32Number Stride
)
949 if (T_PLANAR(info
-> InputFormat
)) {
951 cmsUInt8Number
* pos_L
;
952 cmsUInt8Number
* pos_a
;
953 cmsUInt8Number
* pos_b
;
956 pos_a
= accum
+ Stride
;
957 pos_b
= accum
+ Stride
* 2;
959 Lab
.L
= *(cmsFloat32Number
*)pos_L
;
960 Lab
.a
= *(cmsFloat32Number
*)pos_a
;
961 Lab
.b
= *(cmsFloat32Number
*)pos_b
;
963 cmsFloat2LabEncoded(wIn
, &Lab
);
964 return accum
+ sizeof(cmsFloat32Number
);
968 Lab
.L
= ((cmsFloat32Number
*) accum
)[0];
969 Lab
.a
= ((cmsFloat32Number
*) accum
)[1];
970 Lab
.b
= ((cmsFloat32Number
*) accum
)[2];
972 cmsFloat2LabEncoded(wIn
, &Lab
);
973 accum
+= (3 + T_EXTRA(info
->InputFormat
)) * sizeof(cmsFloat32Number
);
978 // This is a conversion of XYZ double to 16 bits
980 cmsUInt8Number
* UnrollXYZDoubleTo16(CMSREGISTER _cmsTRANSFORM
* info
,
981 CMSREGISTER cmsUInt16Number wIn
[],
982 CMSREGISTER cmsUInt8Number
* accum
,
983 CMSREGISTER cmsUInt32Number Stride
)
985 if (T_PLANAR(info
-> InputFormat
)) {
988 cmsUInt8Number
* pos_X
;
989 cmsUInt8Number
* pos_Y
;
990 cmsUInt8Number
* pos_Z
;
993 pos_Y
= accum
+ Stride
;
994 pos_Z
= accum
+ Stride
* 2;
996 XYZ
.X
= *(cmsFloat64Number
*)pos_X
;
997 XYZ
.Y
= *(cmsFloat64Number
*)pos_Y
;
998 XYZ
.Z
= *(cmsFloat64Number
*)pos_Z
;
1000 cmsFloat2XYZEncoded(wIn
, &XYZ
);
1002 return accum
+ sizeof(cmsFloat64Number
);
1007 cmsFloat2XYZEncoded(wIn
, (cmsCIEXYZ
*) accum
);
1008 accum
+= sizeof(cmsCIEXYZ
) + T_EXTRA(info
->InputFormat
) * sizeof(cmsFloat64Number
);
1014 // This is a conversion of XYZ float to 16 bits
1016 cmsUInt8Number
* UnrollXYZFloatTo16(CMSREGISTER _cmsTRANSFORM
* info
,
1017 CMSREGISTER cmsUInt16Number wIn
[],
1018 CMSREGISTER cmsUInt8Number
* accum
,
1019 CMSREGISTER cmsUInt32Number Stride
)
1021 if (T_PLANAR(info
-> InputFormat
)) {
1024 cmsUInt8Number
* pos_X
;
1025 cmsUInt8Number
* pos_Y
;
1026 cmsUInt8Number
* pos_Z
;
1029 pos_Y
= accum
+ Stride
;
1030 pos_Z
= accum
+ Stride
* 2;
1032 XYZ
.X
= *(cmsFloat32Number
*)pos_X
;
1033 XYZ
.Y
= *(cmsFloat32Number
*)pos_Y
;
1034 XYZ
.Z
= *(cmsFloat32Number
*)pos_Z
;
1036 cmsFloat2XYZEncoded(wIn
, &XYZ
);
1038 return accum
+ sizeof(cmsFloat32Number
);
1043 cmsFloat32Number
* Pt
= (cmsFloat32Number
*) accum
;
1049 cmsFloat2XYZEncoded(wIn
, &XYZ
);
1051 accum
+= 3 * sizeof(cmsFloat32Number
) + T_EXTRA(info
->InputFormat
) * sizeof(cmsFloat32Number
);
1057 // Check if space is marked as ink
1058 cmsINLINE cmsBool
IsInkSpace(cmsUInt32Number Type
)
1060 switch (T_COLORSPACE(Type
)) {
1074 case PT_MCH15
: return TRUE
;
1076 default: return FALSE
;
1080 // Return the size in bytes of a given formatter
1082 cmsUInt32Number
PixelSize(cmsUInt32Number Format
)
1084 cmsUInt32Number fmt_bytes
= T_BYTES(Format
);
1086 // For double, the T_BYTES field is zero
1088 return sizeof(cmsUInt64Number
);
1090 // Otherwise, it is already correct for all formats
1094 // Inks does come in percentage, remaining cases are between 0..1.0, again to 16 bits
1096 cmsUInt8Number
* UnrollDoubleTo16(CMSREGISTER _cmsTRANSFORM
* info
,
1097 CMSREGISTER cmsUInt16Number wIn
[],
1098 CMSREGISTER cmsUInt8Number
* accum
,
1099 CMSREGISTER cmsUInt32Number Stride
)
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
);
1111 cmsUInt32Number i
, start
= 0;
1112 cmsFloat64Number maximum
= IsInkSpace(info
->InputFormat
) ? 655.35 : 65535.0;
1115 Stride
/= PixelSize(info
->InputFormat
);
1120 for (i
=0; i
< nChan
; i
++) {
1122 cmsUInt32Number index
= DoSwap
? (nChan
- i
- 1) : i
;
1125 v
= (cmsFloat32Number
) ((cmsFloat64Number
*) accum
)[(i
+ start
) * Stride
];
1127 v
= (cmsFloat32Number
) ((cmsFloat64Number
*) accum
)[i
+ start
];
1129 vi
= _cmsQuickSaturateWord(v
* maximum
);
1132 vi
= REVERSE_FLAVOR_16(vi
);
1138 if (Extra
== 0 && SwapFirst
) {
1139 cmsUInt16Number tmp
= wIn
[0];
1141 memmove(&wIn
[0], &wIn
[1], (nChan
-1) * sizeof(cmsUInt16Number
));
1145 if (T_PLANAR(info
-> InputFormat
))
1146 return accum
+ sizeof(cmsFloat64Number
);
1148 return accum
+ (nChan
+ Extra
) * sizeof(cmsFloat64Number
);
1154 cmsUInt8Number
* UnrollFloatTo16(CMSREGISTER _cmsTRANSFORM
* info
,
1155 CMSREGISTER cmsUInt16Number wIn
[],
1156 CMSREGISTER cmsUInt8Number
* accum
,
1157 CMSREGISTER cmsUInt32Number Stride
)
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
);
1169 cmsUInt32Number i
, start
= 0;
1170 cmsFloat64Number maximum
= IsInkSpace(info
->InputFormat
) ? 655.35 : 65535.0;
1172 Stride
/= PixelSize(info
->InputFormat
);
1177 for (i
=0; i
< nChan
; i
++) {
1179 cmsUInt32Number index
= DoSwap
? (nChan
- i
- 1) : i
;
1182 v
= (cmsFloat32Number
) ((cmsFloat32Number
*) accum
)[(i
+ start
) * Stride
];
1184 v
= (cmsFloat32Number
) ((cmsFloat32Number
*) accum
)[i
+ start
];
1186 vi
= _cmsQuickSaturateWord(v
* maximum
);
1189 vi
= REVERSE_FLAVOR_16(vi
);
1195 if (Extra
== 0 && SwapFirst
) {
1196 cmsUInt16Number tmp
= wIn
[0];
1198 memmove(&wIn
[0], &wIn
[1], (nChan
-1) * sizeof(cmsUInt16Number
));
1202 if (T_PLANAR(info
-> InputFormat
))
1203 return accum
+ sizeof(cmsFloat32Number
);
1205 return accum
+ (nChan
+ Extra
) * sizeof(cmsFloat32Number
);
1211 // For 1 channel, we need to duplicate data (it comes in 0..1.0 range)
1213 cmsUInt8Number
* UnrollDouble1Chan(CMSREGISTER _cmsTRANSFORM
* info
,
1214 CMSREGISTER cmsUInt16Number wIn
[],
1215 CMSREGISTER cmsUInt8Number
* accum
,
1216 CMSREGISTER cmsUInt32Number Stride
)
1218 cmsFloat64Number
* Inks
= (cmsFloat64Number
*) accum
;
1220 wIn
[0] = wIn
[1] = wIn
[2] = _cmsQuickSaturateWord(Inks
[0] * 65535.0);
1222 return accum
+ sizeof(cmsFloat64Number
);
1224 cmsUNUSED_PARAMETER(info
);
1225 cmsUNUSED_PARAMETER(Stride
);
1228 //-------------------------------------------------------------------------------------------------------------------
1230 // For anything going from cmsUInt8Number
1232 cmsUInt8Number
* Unroll8ToFloat(_cmsTRANSFORM
* info
,
1233 cmsFloat32Number wIn
[],
1234 cmsUInt8Number
* accum
,
1235 cmsUInt32Number Stride
)
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
);
1246 cmsUInt32Number i
, start
= 0;
1248 Stride
/= PixelSize(info
->InputFormat
);
1253 for (i
= 0; i
< nChan
; i
++) {
1255 cmsUInt32Number index
= DoSwap
? (nChan
- i
- 1) : i
;
1258 v
= (cmsFloat32Number
) ((cmsUInt8Number
*)accum
)[(i
+ start
) * Stride
];
1260 v
= (cmsFloat32Number
) ((cmsUInt8Number
*)accum
)[i
+ start
];
1264 wIn
[index
] = Reverse
? 1 - v
: v
;
1268 if (Extra
== 0 && SwapFirst
) {
1269 cmsFloat32Number tmp
= wIn
[0];
1271 memmove(&wIn
[0], &wIn
[1], (nChan
- 1) * sizeof(cmsFloat32Number
));
1272 wIn
[nChan
- 1] = tmp
;
1275 if (T_PLANAR(info
->InputFormat
))
1276 return accum
+ sizeof(cmsUInt8Number
);
1278 return accum
+ (nChan
+ Extra
) * sizeof(cmsUInt8Number
);
1282 // For anything going from cmsUInt16Number
1284 cmsUInt8Number
* Unroll16ToFloat(_cmsTRANSFORM
* info
,
1285 cmsFloat32Number wIn
[],
1286 cmsUInt8Number
* accum
,
1287 cmsUInt32Number Stride
)
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
);
1298 cmsUInt32Number i
, start
= 0;
1300 Stride
/= PixelSize(info
->InputFormat
);
1305 for (i
= 0; i
< nChan
; i
++) {
1307 cmsUInt32Number index
= DoSwap
? (nChan
- i
- 1) : i
;
1310 v
= (cmsFloat32Number
)((cmsUInt16Number
*)accum
)[(i
+ start
) * Stride
];
1312 v
= (cmsFloat32Number
)((cmsUInt16Number
*)accum
)[i
+ start
];
1316 wIn
[index
] = Reverse
? 1 - v
: v
;
1320 if (Extra
== 0 && SwapFirst
) {
1321 cmsFloat32Number tmp
= wIn
[0];
1323 memmove(&wIn
[0], &wIn
[1], (nChan
- 1) * sizeof(cmsFloat32Number
));
1324 wIn
[nChan
- 1] = tmp
;
1327 if (T_PLANAR(info
->InputFormat
))
1328 return accum
+ sizeof(cmsUInt16Number
);
1330 return accum
+ (nChan
+ Extra
) * sizeof(cmsUInt16Number
);
1334 // For anything going from cmsFloat32Number
1336 cmsUInt8Number
* UnrollFloatsToFloat(_cmsTRANSFORM
* info
,
1337 cmsFloat32Number wIn
[],
1338 cmsUInt8Number
* accum
,
1339 cmsUInt32Number Stride
)
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
);
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
;
1356 Stride
/= PixelSize(info
->InputFormat
);
1358 if (Premul
&& Extra
)
1361 alpha_factor
= (ExtraFirst
? ptr
[0] : ptr
[nChan
* Stride
]) / maximum
;
1363 alpha_factor
= (ExtraFirst
? ptr
[0] : ptr
[nChan
]) / maximum
;
1369 for (i
=0; i
< nChan
; i
++) {
1371 cmsUInt32Number index
= DoSwap
? (nChan
- i
- 1) : i
;
1374 v
= ptr
[(i
+ start
) * Stride
];
1378 if (Premul
&& alpha_factor
> 0)
1383 wIn
[index
] = Reverse
? 1 - v
: v
;
1387 if (Extra
== 0 && SwapFirst
) {
1388 cmsFloat32Number tmp
= wIn
[0];
1390 memmove(&wIn
[0], &wIn
[1], (nChan
-1) * sizeof(cmsFloat32Number
));
1394 if (T_PLANAR(info
-> InputFormat
))
1395 return accum
+ sizeof(cmsFloat32Number
);
1397 return accum
+ (nChan
+ Extra
) * sizeof(cmsFloat32Number
);
1400 // For anything going from double
1403 cmsUInt8Number
* UnrollDoublesToFloat(_cmsTRANSFORM
* info
,
1404 cmsFloat32Number wIn
[],
1405 cmsUInt8Number
* accum
,
1406 cmsUInt32Number Stride
)
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
);
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
;
1423 Stride
/= PixelSize(info
->InputFormat
);
1425 if (Premul
&& Extra
)
1428 alpha_factor
= (ExtraFirst
? ptr
[0] : ptr
[(nChan
) * Stride
]) / maximum
;
1430 alpha_factor
= (ExtraFirst
? ptr
[0] : ptr
[nChan
]) / maximum
;
1436 for (i
=0; i
< nChan
; i
++) {
1438 cmsUInt32Number index
= DoSwap
? (nChan
- i
- 1) : i
;
1441 v
= (cmsFloat64Number
) ((cmsFloat64Number
*) accum
)[(i
+ start
) * Stride
];
1443 v
= (cmsFloat64Number
) ((cmsFloat64Number
*) accum
)[i
+ start
];
1446 if (Premul
&& alpha_factor
> 0)
1451 wIn
[index
] = (cmsFloat32Number
) (Reverse
? 1.0 - v
: v
);
1455 if (Extra
== 0 && SwapFirst
) {
1456 cmsFloat32Number tmp
= wIn
[0];
1458 memmove(&wIn
[0], &wIn
[1], (nChan
-1) * sizeof(cmsFloat32Number
));
1462 if (T_PLANAR(info
-> InputFormat
))
1463 return accum
+ sizeof(cmsFloat64Number
);
1465 return accum
+ (nChan
+ Extra
) * sizeof(cmsFloat64Number
);
1470 // From Lab double to cmsFloat32Number
1472 cmsUInt8Number
* UnrollLabDoubleToFloat(_cmsTRANSFORM
* info
,
1473 cmsFloat32Number wIn
[],
1474 cmsUInt8Number
* accum
,
1475 cmsUInt32Number Stride
)
1477 cmsFloat64Number
* Pt
= (cmsFloat64Number
*) accum
;
1479 if (T_PLANAR(info
-> InputFormat
)) {
1481 Stride
/= PixelSize(info
->InputFormat
);
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);
1487 return accum
+ sizeof(cmsFloat64Number
);
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);
1495 accum
+= sizeof(cmsFloat64Number
)*(3 + T_EXTRA(info
->InputFormat
));
1500 // From Lab double to cmsFloat32Number
1502 cmsUInt8Number
* UnrollLabFloatToFloat(_cmsTRANSFORM
* info
,
1503 cmsFloat32Number wIn
[],
1504 cmsUInt8Number
* accum
,
1505 cmsUInt32Number Stride
)
1507 cmsFloat32Number
* Pt
= (cmsFloat32Number
*) accum
;
1509 if (T_PLANAR(info
-> InputFormat
)) {
1511 Stride
/= PixelSize(info
->InputFormat
);
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);
1517 return accum
+ sizeof(cmsFloat32Number
);
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);
1525 accum
+= sizeof(cmsFloat32Number
)*(3 + T_EXTRA(info
->InputFormat
));
1530 // 1.15 fixed point, that means maximum value is MAX_ENCODEABLE_XYZ (0xFFFF)
1532 cmsUInt8Number
* UnrollXYZDoubleToFloat(_cmsTRANSFORM
* info
,
1533 cmsFloat32Number wIn
[],
1534 cmsUInt8Number
* accum
,
1535 cmsUInt32Number Stride
)
1537 cmsFloat64Number
* Pt
= (cmsFloat64Number
*) accum
;
1539 if (T_PLANAR(info
-> InputFormat
)) {
1541 Stride
/= PixelSize(info
->InputFormat
);
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
);
1547 return accum
+ sizeof(cmsFloat64Number
);
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
);
1555 accum
+= sizeof(cmsFloat64Number
)*(3 + T_EXTRA(info
->InputFormat
));
1561 cmsUInt8Number
* UnrollXYZFloatToFloat(_cmsTRANSFORM
* info
,
1562 cmsFloat32Number wIn
[],
1563 cmsUInt8Number
* accum
,
1564 cmsUInt32Number Stride
)
1566 cmsFloat32Number
* Pt
= (cmsFloat32Number
*) accum
;
1568 if (T_PLANAR(info
-> InputFormat
)) {
1570 Stride
/= PixelSize(info
->InputFormat
);
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
);
1576 return accum
+ sizeof(cmsFloat32Number
);
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
);
1584 accum
+= sizeof(cmsFloat32Number
)*(3 + T_EXTRA(info
->InputFormat
));
1590 cmsINLINE
void lab4toFloat(cmsFloat32Number wIn
[], cmsUInt16Number lab4
[3])
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
;
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
);
1603 cmsUInt8Number
* UnrollLabV2_8ToFloat(_cmsTRANSFORM
* info
,
1604 cmsFloat32Number wIn
[],
1605 cmsUInt8Number
* accum
,
1606 cmsUInt32Number Stride
)
1608 cmsUInt16Number lab4
[3];
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
1614 lab4toFloat(wIn
, lab4
);
1618 cmsUNUSED_PARAMETER(info
);
1619 cmsUNUSED_PARAMETER(Stride
);
1623 cmsUInt8Number
* UnrollALabV2_8ToFloat(_cmsTRANSFORM
* info
,
1624 cmsFloat32Number wIn
[],
1625 cmsUInt8Number
* accum
,
1626 cmsUInt32Number Stride
)
1628 cmsUInt16Number lab4
[3];
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
1635 lab4toFloat(wIn
, lab4
);
1639 cmsUNUSED_PARAMETER(info
);
1640 cmsUNUSED_PARAMETER(Stride
);
1644 cmsUInt8Number
* UnrollLabV2_16ToFloat(_cmsTRANSFORM
* info
,
1645 cmsFloat32Number wIn
[],
1646 cmsUInt8Number
* accum
,
1647 cmsUInt32Number Stride
)
1649 cmsUInt16Number lab4
[3];
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
1655 lab4toFloat(wIn
, lab4
);
1659 cmsUNUSED_PARAMETER(info
);
1660 cmsUNUSED_PARAMETER(Stride
);
1664 // Packing routines -----------------------------------------------------------------------------------------------------------
1667 // Generic chunky for byte
1669 cmsUInt8Number
* PackChunkyBytes(CMSREGISTER _cmsTRANSFORM
* info
,
1670 CMSREGISTER cmsUInt16Number wOut
[],
1671 CMSREGISTER cmsUInt8Number
* output
,
1672 CMSREGISTER cmsUInt32Number Stride
)
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;
1684 cmsUInt32Number alpha_factor
= 0;
1690 if (Premul
&& Extra
)
1691 alpha_factor
= _cmsToFixedDomain(FROM_8_TO_16(output
[0]));
1697 if (Premul
&& Extra
)
1698 alpha_factor
= _cmsToFixedDomain(FROM_8_TO_16(output
[nChan
]));
1701 for (i
=0; i
< nChan
; i
++) {
1703 cmsUInt32Number index
= DoSwap
? (nChan
- i
- 1) : i
;
1708 v
= REVERSE_FLAVOR_16(v
);
1712 v
= (cmsUInt16Number
)((cmsUInt32Number
)((cmsUInt32Number
)v
* alpha_factor
+ 0x8000) >> 16);
1715 *output
++ = FROM_16_TO_8(v
);
1722 if (Extra
== 0 && SwapFirst
) {
1724 memmove(swap1
+ 1, swap1
, nChan
-1);
1725 *swap1
= FROM_16_TO_8(v
);
1730 cmsUNUSED_PARAMETER(Stride
);
1734 cmsUInt8Number
* PackChunkyWords(CMSREGISTER _cmsTRANSFORM
* info
,
1735 CMSREGISTER cmsUInt16Number wOut
[],
1736 CMSREGISTER cmsUInt8Number
* output
,
1737 CMSREGISTER cmsUInt32Number Stride
)
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;
1750 cmsUInt32Number alpha_factor
= 0;
1752 swap1
= (cmsUInt16Number
*) output
;
1756 if (Premul
&& Extra
)
1757 alpha_factor
= _cmsToFixedDomain(*(cmsUInt16Number
*) output
);
1759 output
+= Extra
* sizeof(cmsUInt16Number
);
1763 if (Premul
&& Extra
)
1764 alpha_factor
= _cmsToFixedDomain(((cmsUInt16Number
*) output
)[nChan
]);
1767 for (i
=0; i
< nChan
; i
++) {
1769 cmsUInt32Number index
= DoSwap
? (nChan
- i
- 1) : i
;
1774 v
= CHANGE_ENDIAN(v
);
1777 v
= REVERSE_FLAVOR_16(v
);
1781 v
= (cmsUInt16Number
)((cmsUInt32Number
)((cmsUInt32Number
)v
* alpha_factor
+ 0x8000) >> 16);
1784 *(cmsUInt16Number
*) output
= v
;
1786 output
+= sizeof(cmsUInt16Number
);
1790 output
+= Extra
* sizeof(cmsUInt16Number
);
1793 if (Extra
== 0 && SwapFirst
) {
1795 memmove(swap1
+ 1, swap1
, (nChan
-1)* sizeof(cmsUInt16Number
));
1801 cmsUNUSED_PARAMETER(Stride
);
1807 cmsUInt8Number
* PackPlanarBytes(CMSREGISTER _cmsTRANSFORM
* info
,
1808 CMSREGISTER cmsUInt16Number wOut
[],
1809 CMSREGISTER cmsUInt8Number
* output
,
1810 CMSREGISTER cmsUInt32Number Stride
)
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
);
1820 cmsUInt8Number
* Init
= output
;
1821 cmsUInt32Number alpha_factor
= 0;
1826 if (Premul
&& Extra
)
1827 alpha_factor
= _cmsToFixedDomain(FROM_8_TO_16(output
[0]));
1829 output
+= Extra
* Stride
;
1833 if (Premul
&& Extra
)
1834 alpha_factor
= _cmsToFixedDomain(FROM_8_TO_16(output
[nChan
* Stride
]));
1838 for (i
=0; i
< nChan
; i
++) {
1840 cmsUInt32Number index
= DoSwap
? (nChan
- i
- 1) : i
;
1841 cmsUInt16Number v
= wOut
[index
];
1844 v
= REVERSE_FLAVOR_16(v
);
1848 v
= (cmsUInt16Number
)((cmsUInt32Number
)((cmsUInt32Number
)v
* alpha_factor
+ 0x8000) >> 16);
1851 *(cmsUInt8Number
*)output
= FROM_16_TO_8(v
);
1858 cmsUNUSED_PARAMETER(Stride
);
1863 cmsUInt8Number
* PackPlanarWords(CMSREGISTER _cmsTRANSFORM
* info
,
1864 CMSREGISTER cmsUInt16Number wOut
[],
1865 CMSREGISTER cmsUInt8Number
* output
,
1866 CMSREGISTER cmsUInt32Number Stride
)
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
);
1877 cmsUInt8Number
* Init
= output
;
1879 cmsUInt32Number alpha_factor
= 0;
1883 if (Premul
&& Extra
)
1884 alpha_factor
= _cmsToFixedDomain(((cmsUInt16Number
*) output
)[0]);
1886 output
+= Extra
* Stride
;
1890 if (Premul
&& Extra
)
1891 alpha_factor
= _cmsToFixedDomain(((cmsUInt16Number
*)output
)[nChan
* Stride
]);
1894 for (i
=0; i
< nChan
; i
++) {
1896 cmsUInt32Number index
= DoSwap
? (nChan
- i
- 1) : i
;
1901 v
= CHANGE_ENDIAN(v
);
1904 v
= REVERSE_FLAVOR_16(v
);
1908 v
= (cmsUInt16Number
)((cmsUInt32Number
)((cmsUInt32Number
)v
* alpha_factor
+ 0x8000) >> 16);
1911 *(cmsUInt16Number
*) output
= v
;
1915 return (Init
+ sizeof(cmsUInt16Number
));
1918 // CMYKcm (unrolled for speed)
1921 cmsUInt8Number
* Pack6Bytes(CMSREGISTER _cmsTRANSFORM
* info
,
1922 CMSREGISTER cmsUInt16Number wOut
[],
1923 CMSREGISTER cmsUInt8Number
* output
,
1924 CMSREGISTER cmsUInt32Number Stride
)
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]);
1935 cmsUNUSED_PARAMETER(info
);
1936 cmsUNUSED_PARAMETER(Stride
);
1942 cmsUInt8Number
* Pack6BytesSwap(CMSREGISTER _cmsTRANSFORM
* info
,
1943 CMSREGISTER cmsUInt16Number wOut
[],
1944 CMSREGISTER cmsUInt8Number
* output
,
1945 CMSREGISTER cmsUInt32Number Stride
)
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]);
1956 cmsUNUSED_PARAMETER(info
);
1957 cmsUNUSED_PARAMETER(Stride
);
1962 cmsUInt8Number
* Pack6Words(CMSREGISTER _cmsTRANSFORM
* info
,
1963 CMSREGISTER cmsUInt16Number wOut
[],
1964 CMSREGISTER cmsUInt8Number
* output
,
1965 CMSREGISTER cmsUInt32Number Stride
)
1967 *(cmsUInt16Number
*) output
= wOut
[0];
1969 *(cmsUInt16Number
*) output
= wOut
[1];
1971 *(cmsUInt16Number
*) output
= wOut
[2];
1973 *(cmsUInt16Number
*) output
= wOut
[3];
1975 *(cmsUInt16Number
*) output
= wOut
[4];
1977 *(cmsUInt16Number
*) output
= wOut
[5];
1982 cmsUNUSED_PARAMETER(info
);
1983 cmsUNUSED_PARAMETER(Stride
);
1988 cmsUInt8Number
* Pack6WordsSwap(CMSREGISTER _cmsTRANSFORM
* info
,
1989 CMSREGISTER cmsUInt16Number wOut
[],
1990 CMSREGISTER cmsUInt8Number
* output
,
1991 CMSREGISTER cmsUInt32Number Stride
)
1993 *(cmsUInt16Number
*) output
= wOut
[5];
1995 *(cmsUInt16Number
*) output
= wOut
[4];
1997 *(cmsUInt16Number
*) output
= wOut
[3];
1999 *(cmsUInt16Number
*) output
= wOut
[2];
2001 *(cmsUInt16Number
*) output
= wOut
[1];
2003 *(cmsUInt16Number
*) output
= wOut
[0];
2008 cmsUNUSED_PARAMETER(info
);
2009 cmsUNUSED_PARAMETER(Stride
);
2014 cmsUInt8Number
* Pack4Bytes(CMSREGISTER _cmsTRANSFORM
* info
,
2015 CMSREGISTER cmsUInt16Number wOut
[],
2016 CMSREGISTER cmsUInt8Number
* output
,
2017 CMSREGISTER cmsUInt32Number Stride
)
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]);
2026 cmsUNUSED_PARAMETER(info
);
2027 cmsUNUSED_PARAMETER(Stride
);
2031 cmsUInt8Number
* Pack4BytesReverse(CMSREGISTER _cmsTRANSFORM
* info
,
2032 CMSREGISTER cmsUInt16Number wOut
[],
2033 CMSREGISTER cmsUInt8Number
* output
,
2034 CMSREGISTER cmsUInt32Number Stride
)
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]));
2043 cmsUNUSED_PARAMETER(info
);
2044 cmsUNUSED_PARAMETER(Stride
);
2049 cmsUInt8Number
* Pack4BytesSwapFirst(CMSREGISTER _cmsTRANSFORM
* info
,
2050 CMSREGISTER cmsUInt16Number wOut
[],
2051 CMSREGISTER cmsUInt8Number
* output
,
2052 CMSREGISTER cmsUInt32Number Stride
)
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]);
2061 cmsUNUSED_PARAMETER(info
);
2062 cmsUNUSED_PARAMETER(Stride
);
2067 cmsUInt8Number
* Pack4BytesSwap(CMSREGISTER _cmsTRANSFORM
* info
,
2068 CMSREGISTER cmsUInt16Number wOut
[],
2069 CMSREGISTER cmsUInt8Number
* output
,
2070 CMSREGISTER cmsUInt32Number Stride
)
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]);
2079 cmsUNUSED_PARAMETER(info
);
2080 cmsUNUSED_PARAMETER(Stride
);
2084 cmsUInt8Number
* Pack4BytesSwapSwapFirst(CMSREGISTER _cmsTRANSFORM
* info
,
2085 CMSREGISTER cmsUInt16Number wOut
[],
2086 CMSREGISTER cmsUInt8Number
* output
,
2087 CMSREGISTER cmsUInt32Number Stride
)
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]);
2096 cmsUNUSED_PARAMETER(info
);
2097 cmsUNUSED_PARAMETER(Stride
);
2101 cmsUInt8Number
* Pack4Words(CMSREGISTER _cmsTRANSFORM
* info
,
2102 CMSREGISTER cmsUInt16Number wOut
[],
2103 CMSREGISTER cmsUInt8Number
* output
,
2104 CMSREGISTER cmsUInt32Number Stride
)
2106 *(cmsUInt16Number
*) output
= wOut
[0];
2108 *(cmsUInt16Number
*) output
= wOut
[1];
2110 *(cmsUInt16Number
*) output
= wOut
[2];
2112 *(cmsUInt16Number
*) output
= wOut
[3];
2117 cmsUNUSED_PARAMETER(info
);
2118 cmsUNUSED_PARAMETER(Stride
);
2122 cmsUInt8Number
* Pack4WordsReverse(CMSREGISTER _cmsTRANSFORM
* info
,
2123 CMSREGISTER cmsUInt16Number wOut
[],
2124 CMSREGISTER cmsUInt8Number
* output
,
2125 CMSREGISTER cmsUInt32Number Stride
)
2127 *(cmsUInt16Number
*) output
= REVERSE_FLAVOR_16(wOut
[0]);
2129 *(cmsUInt16Number
*) output
= REVERSE_FLAVOR_16(wOut
[1]);
2131 *(cmsUInt16Number
*) output
= REVERSE_FLAVOR_16(wOut
[2]);
2133 *(cmsUInt16Number
*) output
= REVERSE_FLAVOR_16(wOut
[3]);
2138 cmsUNUSED_PARAMETER(info
);
2139 cmsUNUSED_PARAMETER(Stride
);
2144 cmsUInt8Number
* Pack4WordsSwap(CMSREGISTER _cmsTRANSFORM
* info
,
2145 CMSREGISTER cmsUInt16Number wOut
[],
2146 CMSREGISTER cmsUInt8Number
* output
,
2147 CMSREGISTER cmsUInt32Number Stride
)
2149 *(cmsUInt16Number
*) output
= wOut
[3];
2151 *(cmsUInt16Number
*) output
= wOut
[2];
2153 *(cmsUInt16Number
*) output
= wOut
[1];
2155 *(cmsUInt16Number
*) output
= wOut
[0];
2160 cmsUNUSED_PARAMETER(info
);
2161 cmsUNUSED_PARAMETER(Stride
);
2166 cmsUInt8Number
* Pack4WordsBigEndian(CMSREGISTER _cmsTRANSFORM
* info
,
2167 CMSREGISTER cmsUInt16Number wOut
[],
2168 CMSREGISTER cmsUInt8Number
* output
,
2169 CMSREGISTER cmsUInt32Number Stride
)
2171 *(cmsUInt16Number
*) output
= CHANGE_ENDIAN(wOut
[0]);
2173 *(cmsUInt16Number
*) output
= CHANGE_ENDIAN(wOut
[1]);
2175 *(cmsUInt16Number
*) output
= CHANGE_ENDIAN(wOut
[2]);
2177 *(cmsUInt16Number
*) output
= CHANGE_ENDIAN(wOut
[3]);
2182 cmsUNUSED_PARAMETER(info
);
2183 cmsUNUSED_PARAMETER(Stride
);
2188 cmsUInt8Number
* PackLabV2_8(CMSREGISTER _cmsTRANSFORM
* info
,
2189 CMSREGISTER cmsUInt16Number wOut
[],
2190 CMSREGISTER cmsUInt8Number
* output
,
2191 CMSREGISTER cmsUInt32Number Stride
)
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]));
2199 cmsUNUSED_PARAMETER(info
);
2200 cmsUNUSED_PARAMETER(Stride
);
2204 cmsUInt8Number
* PackALabV2_8(CMSREGISTER _cmsTRANSFORM
* info
,
2205 CMSREGISTER cmsUInt16Number wOut
[],
2206 CMSREGISTER cmsUInt8Number
* output
,
2207 CMSREGISTER cmsUInt32Number Stride
)
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]));
2216 cmsUNUSED_PARAMETER(info
);
2217 cmsUNUSED_PARAMETER(Stride
);
2221 cmsUInt8Number
* PackLabV2_16(CMSREGISTER _cmsTRANSFORM
* info
,
2222 CMSREGISTER cmsUInt16Number wOut
[],
2223 CMSREGISTER cmsUInt8Number
* output
,
2224 CMSREGISTER cmsUInt32Number Stride
)
2226 *(cmsUInt16Number
*) output
= FomLabV4ToLabV2(wOut
[0]);
2228 *(cmsUInt16Number
*) output
= FomLabV4ToLabV2(wOut
[1]);
2230 *(cmsUInt16Number
*) output
= FomLabV4ToLabV2(wOut
[2]);
2235 cmsUNUSED_PARAMETER(info
);
2236 cmsUNUSED_PARAMETER(Stride
);
2240 cmsUInt8Number
* Pack3Bytes(CMSREGISTER _cmsTRANSFORM
* info
,
2241 CMSREGISTER cmsUInt16Number wOut
[],
2242 CMSREGISTER cmsUInt8Number
* output
,
2243 CMSREGISTER cmsUInt32Number Stride
)
2245 *output
++ = FROM_16_TO_8(wOut
[0]);
2246 *output
++ = FROM_16_TO_8(wOut
[1]);
2247 *output
++ = FROM_16_TO_8(wOut
[2]);
2251 cmsUNUSED_PARAMETER(info
);
2252 cmsUNUSED_PARAMETER(Stride
);
2256 cmsUInt8Number
* Pack3BytesOptimized(CMSREGISTER _cmsTRANSFORM
* info
,
2257 CMSREGISTER cmsUInt16Number wOut
[],
2258 CMSREGISTER cmsUInt8Number
* output
,
2259 CMSREGISTER cmsUInt32Number Stride
)
2261 *output
++ = (wOut
[0] & 0xFFU
);
2262 *output
++ = (wOut
[1] & 0xFFU
);
2263 *output
++ = (wOut
[2] & 0xFFU
);
2267 cmsUNUSED_PARAMETER(info
);
2268 cmsUNUSED_PARAMETER(Stride
);
2272 cmsUInt8Number
* Pack3BytesSwap(CMSREGISTER _cmsTRANSFORM
* info
,
2273 CMSREGISTER cmsUInt16Number wOut
[],
2274 CMSREGISTER cmsUInt8Number
* output
,
2275 CMSREGISTER cmsUInt32Number Stride
)
2277 *output
++ = FROM_16_TO_8(wOut
[2]);
2278 *output
++ = FROM_16_TO_8(wOut
[1]);
2279 *output
++ = FROM_16_TO_8(wOut
[0]);
2283 cmsUNUSED_PARAMETER(info
);
2284 cmsUNUSED_PARAMETER(Stride
);
2288 cmsUInt8Number
* Pack3BytesSwapOptimized(CMSREGISTER _cmsTRANSFORM
* info
,
2289 CMSREGISTER cmsUInt16Number wOut
[],
2290 CMSREGISTER cmsUInt8Number
* output
,
2291 CMSREGISTER cmsUInt32Number Stride
)
2293 *output
++ = (wOut
[2] & 0xFFU
);
2294 *output
++ = (wOut
[1] & 0xFFU
);
2295 *output
++ = (wOut
[0] & 0xFFU
);
2299 cmsUNUSED_PARAMETER(info
);
2300 cmsUNUSED_PARAMETER(Stride
);
2305 cmsUInt8Number
* Pack3Words(CMSREGISTER _cmsTRANSFORM
* info
,
2306 CMSREGISTER cmsUInt16Number wOut
[],
2307 CMSREGISTER cmsUInt8Number
* output
,
2308 CMSREGISTER cmsUInt32Number Stride
)
2310 *(cmsUInt16Number
*) output
= wOut
[0];
2312 *(cmsUInt16Number
*) output
= wOut
[1];
2314 *(cmsUInt16Number
*) output
= wOut
[2];
2319 cmsUNUSED_PARAMETER(info
);
2320 cmsUNUSED_PARAMETER(Stride
);
2324 cmsUInt8Number
* Pack3WordsSwap(CMSREGISTER _cmsTRANSFORM
* info
,
2325 CMSREGISTER cmsUInt16Number wOut
[],
2326 CMSREGISTER cmsUInt8Number
* output
,
2327 CMSREGISTER cmsUInt32Number Stride
)
2329 *(cmsUInt16Number
*) output
= wOut
[2];
2331 *(cmsUInt16Number
*) output
= wOut
[1];
2333 *(cmsUInt16Number
*) output
= wOut
[0];
2338 cmsUNUSED_PARAMETER(info
);
2339 cmsUNUSED_PARAMETER(Stride
);
2343 cmsUInt8Number
* Pack3WordsBigEndian(CMSREGISTER _cmsTRANSFORM
* info
,
2344 CMSREGISTER cmsUInt16Number wOut
[],
2345 CMSREGISTER cmsUInt8Number
* output
,
2346 CMSREGISTER cmsUInt32Number Stride
)
2348 *(cmsUInt16Number
*) output
= CHANGE_ENDIAN(wOut
[0]);
2350 *(cmsUInt16Number
*) output
= CHANGE_ENDIAN(wOut
[1]);
2352 *(cmsUInt16Number
*) output
= CHANGE_ENDIAN(wOut
[2]);
2357 cmsUNUSED_PARAMETER(info
);
2358 cmsUNUSED_PARAMETER(Stride
);
2362 cmsUInt8Number
* Pack3BytesAndSkip1(CMSREGISTER _cmsTRANSFORM
* info
,
2363 CMSREGISTER cmsUInt16Number wOut
[],
2364 CMSREGISTER cmsUInt8Number
* output
,
2365 CMSREGISTER cmsUInt32Number Stride
)
2367 *output
++ = FROM_16_TO_8(wOut
[0]);
2368 *output
++ = FROM_16_TO_8(wOut
[1]);
2369 *output
++ = FROM_16_TO_8(wOut
[2]);
2374 cmsUNUSED_PARAMETER(info
);
2375 cmsUNUSED_PARAMETER(Stride
);
2379 cmsUInt8Number
* Pack3BytesAndSkip1Optimized(CMSREGISTER _cmsTRANSFORM
* info
,
2380 CMSREGISTER cmsUInt16Number wOut
[],
2381 CMSREGISTER cmsUInt8Number
* output
,
2382 CMSREGISTER cmsUInt32Number Stride
)
2384 *output
++ = (wOut
[0] & 0xFFU
);
2385 *output
++ = (wOut
[1] & 0xFFU
);
2386 *output
++ = (wOut
[2] & 0xFFU
);
2391 cmsUNUSED_PARAMETER(info
);
2392 cmsUNUSED_PARAMETER(Stride
);
2397 cmsUInt8Number
* Pack3BytesAndSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM
* info
,
2398 CMSREGISTER cmsUInt16Number wOut
[],
2399 CMSREGISTER cmsUInt8Number
* output
,
2400 CMSREGISTER cmsUInt32Number Stride
)
2403 *output
++ = FROM_16_TO_8(wOut
[0]);
2404 *output
++ = FROM_16_TO_8(wOut
[1]);
2405 *output
++ = FROM_16_TO_8(wOut
[2]);
2409 cmsUNUSED_PARAMETER(info
);
2410 cmsUNUSED_PARAMETER(Stride
);
2414 cmsUInt8Number
* Pack3BytesAndSkip1SwapFirstOptimized(CMSREGISTER _cmsTRANSFORM
* info
,
2415 CMSREGISTER cmsUInt16Number wOut
[],
2416 CMSREGISTER cmsUInt8Number
* output
,
2417 CMSREGISTER cmsUInt32Number Stride
)
2420 *output
++ = (wOut
[0] & 0xFFU
);
2421 *output
++ = (wOut
[1] & 0xFFU
);
2422 *output
++ = (wOut
[2] & 0xFFU
);
2426 cmsUNUSED_PARAMETER(info
);
2427 cmsUNUSED_PARAMETER(Stride
);
2431 cmsUInt8Number
* Pack3BytesAndSkip1Swap(CMSREGISTER _cmsTRANSFORM
* info
,
2432 CMSREGISTER cmsUInt16Number wOut
[],
2433 CMSREGISTER cmsUInt8Number
* output
,
2434 CMSREGISTER cmsUInt32Number Stride
)
2437 *output
++ = FROM_16_TO_8(wOut
[2]);
2438 *output
++ = FROM_16_TO_8(wOut
[1]);
2439 *output
++ = FROM_16_TO_8(wOut
[0]);
2443 cmsUNUSED_PARAMETER(info
);
2444 cmsUNUSED_PARAMETER(Stride
);
2448 cmsUInt8Number
* Pack3BytesAndSkip1SwapOptimized(CMSREGISTER _cmsTRANSFORM
* info
,
2449 CMSREGISTER cmsUInt16Number wOut
[],
2450 CMSREGISTER cmsUInt8Number
* output
,
2451 CMSREGISTER cmsUInt32Number Stride
)
2454 *output
++ = (wOut
[2] & 0xFFU
);
2455 *output
++ = (wOut
[1] & 0xFFU
);
2456 *output
++ = (wOut
[0] & 0xFFU
);
2460 cmsUNUSED_PARAMETER(info
);
2461 cmsUNUSED_PARAMETER(Stride
);
2466 cmsUInt8Number
* Pack3BytesAndSkip1SwapSwapFirst(CMSREGISTER _cmsTRANSFORM
* info
,
2467 CMSREGISTER cmsUInt16Number wOut
[],
2468 CMSREGISTER cmsUInt8Number
* output
,
2469 CMSREGISTER cmsUInt32Number Stride
)
2471 *output
++ = FROM_16_TO_8(wOut
[2]);
2472 *output
++ = FROM_16_TO_8(wOut
[1]);
2473 *output
++ = FROM_16_TO_8(wOut
[0]);
2478 cmsUNUSED_PARAMETER(info
);
2479 cmsUNUSED_PARAMETER(Stride
);
2483 cmsUInt8Number
* Pack3BytesAndSkip1SwapSwapFirstOptimized(CMSREGISTER _cmsTRANSFORM
* info
,
2484 CMSREGISTER cmsUInt16Number wOut
[],
2485 CMSREGISTER cmsUInt8Number
* output
,
2486 CMSREGISTER cmsUInt32Number Stride
)
2488 *output
++ = (wOut
[2] & 0xFFU
);
2489 *output
++ = (wOut
[1] & 0xFFU
);
2490 *output
++ = (wOut
[0] & 0xFFU
);
2495 cmsUNUSED_PARAMETER(info
);
2496 cmsUNUSED_PARAMETER(Stride
);
2500 cmsUInt8Number
* Pack3WordsAndSkip1(CMSREGISTER _cmsTRANSFORM
* info
,
2501 CMSREGISTER cmsUInt16Number wOut
[],
2502 CMSREGISTER cmsUInt8Number
* output
,
2503 CMSREGISTER cmsUInt32Number Stride
)
2505 *(cmsUInt16Number
*) output
= wOut
[0];
2507 *(cmsUInt16Number
*) output
= wOut
[1];
2509 *(cmsUInt16Number
*) output
= wOut
[2];
2515 cmsUNUSED_PARAMETER(info
);
2516 cmsUNUSED_PARAMETER(Stride
);
2520 cmsUInt8Number
* Pack3WordsAndSkip1Swap(CMSREGISTER _cmsTRANSFORM
* info
,
2521 CMSREGISTER cmsUInt16Number wOut
[],
2522 CMSREGISTER cmsUInt8Number
* output
,
2523 CMSREGISTER cmsUInt32Number Stride
)
2526 *(cmsUInt16Number
*) output
= wOut
[2];
2528 *(cmsUInt16Number
*) output
= wOut
[1];
2530 *(cmsUInt16Number
*) output
= wOut
[0];
2535 cmsUNUSED_PARAMETER(info
);
2536 cmsUNUSED_PARAMETER(Stride
);
2541 cmsUInt8Number
* Pack3WordsAndSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM
* info
,
2542 CMSREGISTER cmsUInt16Number wOut
[],
2543 CMSREGISTER cmsUInt8Number
* output
,
2544 CMSREGISTER cmsUInt32Number Stride
)
2547 *(cmsUInt16Number
*) output
= wOut
[0];
2549 *(cmsUInt16Number
*) output
= wOut
[1];
2551 *(cmsUInt16Number
*) output
= wOut
[2];
2556 cmsUNUSED_PARAMETER(info
);
2557 cmsUNUSED_PARAMETER(Stride
);
2562 cmsUInt8Number
* Pack3WordsAndSkip1SwapSwapFirst(CMSREGISTER _cmsTRANSFORM
* info
,
2563 CMSREGISTER cmsUInt16Number wOut
[],
2564 CMSREGISTER cmsUInt8Number
* output
,
2565 CMSREGISTER cmsUInt32Number Stride
)
2567 *(cmsUInt16Number
*) output
= wOut
[2];
2569 *(cmsUInt16Number
*) output
= wOut
[1];
2571 *(cmsUInt16Number
*) output
= wOut
[0];
2577 cmsUNUSED_PARAMETER(info
);
2578 cmsUNUSED_PARAMETER(Stride
);
2584 cmsUInt8Number
* Pack1Byte(CMSREGISTER _cmsTRANSFORM
* info
,
2585 CMSREGISTER cmsUInt16Number wOut
[],
2586 CMSREGISTER cmsUInt8Number
* output
,
2587 CMSREGISTER cmsUInt32Number Stride
)
2589 *output
++ = FROM_16_TO_8(wOut
[0]);
2593 cmsUNUSED_PARAMETER(info
);
2594 cmsUNUSED_PARAMETER(Stride
);
2599 cmsUInt8Number
* Pack1ByteReversed(CMSREGISTER _cmsTRANSFORM
* info
,
2600 CMSREGISTER cmsUInt16Number wOut
[],
2601 CMSREGISTER cmsUInt8Number
* output
,
2602 CMSREGISTER cmsUInt32Number Stride
)
2604 *output
++ = FROM_16_TO_8(REVERSE_FLAVOR_16(wOut
[0]));
2608 cmsUNUSED_PARAMETER(info
);
2609 cmsUNUSED_PARAMETER(Stride
);
2614 cmsUInt8Number
* Pack1ByteSkip1(CMSREGISTER _cmsTRANSFORM
* info
,
2615 CMSREGISTER cmsUInt16Number wOut
[],
2616 CMSREGISTER cmsUInt8Number
* output
,
2617 CMSREGISTER cmsUInt32Number Stride
)
2619 *output
++ = FROM_16_TO_8(wOut
[0]);
2624 cmsUNUSED_PARAMETER(info
);
2625 cmsUNUSED_PARAMETER(Stride
);
2630 cmsUInt8Number
* Pack1ByteSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM
* info
,
2631 CMSREGISTER cmsUInt16Number wOut
[],
2632 CMSREGISTER cmsUInt8Number
* output
,
2633 CMSREGISTER cmsUInt32Number Stride
)
2636 *output
++ = FROM_16_TO_8(wOut
[0]);
2640 cmsUNUSED_PARAMETER(info
);
2641 cmsUNUSED_PARAMETER(Stride
);
2645 cmsUInt8Number
* Pack1Word(CMSREGISTER _cmsTRANSFORM
* info
,
2646 CMSREGISTER cmsUInt16Number wOut
[],
2647 CMSREGISTER cmsUInt8Number
* output
,
2648 CMSREGISTER cmsUInt32Number Stride
)
2650 *(cmsUInt16Number
*) output
= wOut
[0];
2655 cmsUNUSED_PARAMETER(info
);
2656 cmsUNUSED_PARAMETER(Stride
);
2661 cmsUInt8Number
* Pack1WordReversed(CMSREGISTER _cmsTRANSFORM
* info
,
2662 CMSREGISTER cmsUInt16Number wOut
[],
2663 CMSREGISTER cmsUInt8Number
* output
,
2664 CMSREGISTER cmsUInt32Number Stride
)
2666 *(cmsUInt16Number
*) output
= REVERSE_FLAVOR_16(wOut
[0]);
2671 cmsUNUSED_PARAMETER(info
);
2672 cmsUNUSED_PARAMETER(Stride
);
2676 cmsUInt8Number
* Pack1WordBigEndian(CMSREGISTER _cmsTRANSFORM
* info
,
2677 CMSREGISTER cmsUInt16Number wOut
[],
2678 CMSREGISTER cmsUInt8Number
* output
,
2679 CMSREGISTER cmsUInt32Number Stride
)
2681 *(cmsUInt16Number
*) output
= CHANGE_ENDIAN(wOut
[0]);
2686 cmsUNUSED_PARAMETER(info
);
2687 cmsUNUSED_PARAMETER(Stride
);
2692 cmsUInt8Number
* Pack1WordSkip1(CMSREGISTER _cmsTRANSFORM
* info
,
2693 CMSREGISTER cmsUInt16Number wOut
[],
2694 CMSREGISTER cmsUInt8Number
* output
,
2695 CMSREGISTER cmsUInt32Number Stride
)
2697 *(cmsUInt16Number
*) output
= wOut
[0];
2702 cmsUNUSED_PARAMETER(info
);
2703 cmsUNUSED_PARAMETER(Stride
);
2707 cmsUInt8Number
* Pack1WordSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM
* info
,
2708 CMSREGISTER cmsUInt16Number wOut
[],
2709 CMSREGISTER cmsUInt8Number
* output
,
2710 CMSREGISTER cmsUInt32Number Stride
)
2713 *(cmsUInt16Number
*) output
= wOut
[0];
2718 cmsUNUSED_PARAMETER(info
);
2719 cmsUNUSED_PARAMETER(Stride
);
2723 // Unencoded Float values -- don't try optimize speed
2725 cmsUInt8Number
* PackLabDoubleFrom16(CMSREGISTER _cmsTRANSFORM
* info
,
2726 CMSREGISTER cmsUInt16Number wOut
[],
2727 CMSREGISTER cmsUInt8Number
* output
,
2728 CMSREGISTER cmsUInt32Number Stride
)
2731 if (T_PLANAR(info
-> OutputFormat
)) {
2734 cmsFloat64Number
* Out
= (cmsFloat64Number
*) output
;
2735 cmsLabEncoded2Float(&Lab
, wOut
);
2738 Out
[Stride
] = Lab
.a
;
2739 Out
[Stride
*2] = Lab
.b
;
2741 return output
+ sizeof(cmsFloat64Number
);
2745 cmsLabEncoded2Float((cmsCIELab
*) output
, wOut
);
2746 return output
+ (sizeof(cmsCIELab
) + T_EXTRA(info
->OutputFormat
) * sizeof(cmsFloat64Number
));
2752 cmsUInt8Number
* PackLabFloatFrom16(CMSREGISTER _cmsTRANSFORM
* info
,
2753 CMSREGISTER cmsUInt16Number wOut
[],
2754 CMSREGISTER cmsUInt8Number
* output
,
2755 CMSREGISTER cmsUInt32Number Stride
)
2758 cmsLabEncoded2Float(&Lab
, wOut
);
2760 if (T_PLANAR(info
-> OutputFormat
)) {
2762 cmsFloat32Number
* Out
= (cmsFloat32Number
*) output
;
2764 Stride
/= PixelSize(info
->OutputFormat
);
2766 Out
[0] = (cmsFloat32Number
)Lab
.L
;
2767 Out
[Stride
] = (cmsFloat32Number
)Lab
.a
;
2768 Out
[Stride
*2] = (cmsFloat32Number
)Lab
.b
;
2770 return output
+ sizeof(cmsFloat32Number
);
2774 ((cmsFloat32Number
*) output
)[0] = (cmsFloat32Number
) Lab
.L
;
2775 ((cmsFloat32Number
*) output
)[1] = (cmsFloat32Number
) Lab
.a
;
2776 ((cmsFloat32Number
*) output
)[2] = (cmsFloat32Number
) Lab
.b
;
2778 return output
+ (3 + T_EXTRA(info
->OutputFormat
)) * sizeof(cmsFloat32Number
);
2783 cmsUInt8Number
* PackXYZDoubleFrom16(CMSREGISTER _cmsTRANSFORM
* Info
,
2784 CMSREGISTER cmsUInt16Number wOut
[],
2785 CMSREGISTER cmsUInt8Number
* output
,
2786 CMSREGISTER cmsUInt32Number Stride
)
2788 if (T_PLANAR(Info
-> OutputFormat
)) {
2791 cmsFloat64Number
* Out
= (cmsFloat64Number
*) output
;
2792 cmsXYZEncoded2Float(&XYZ
, wOut
);
2794 Stride
/= PixelSize(Info
->OutputFormat
);
2797 Out
[Stride
] = XYZ
.Y
;
2798 Out
[Stride
*2] = XYZ
.Z
;
2800 return output
+ sizeof(cmsFloat64Number
);
2805 cmsXYZEncoded2Float((cmsCIEXYZ
*) output
, wOut
);
2807 return output
+ (sizeof(cmsCIEXYZ
) + T_EXTRA(Info
->OutputFormat
) * sizeof(cmsFloat64Number
));
2812 cmsUInt8Number
* PackXYZFloatFrom16(CMSREGISTER _cmsTRANSFORM
* Info
,
2813 CMSREGISTER cmsUInt16Number wOut
[],
2814 CMSREGISTER cmsUInt8Number
* output
,
2815 CMSREGISTER cmsUInt32Number Stride
)
2817 if (T_PLANAR(Info
-> OutputFormat
)) {
2820 cmsFloat32Number
* Out
= (cmsFloat32Number
*) output
;
2821 cmsXYZEncoded2Float(&XYZ
, wOut
);
2823 Stride
/= PixelSize(Info
->OutputFormat
);
2825 Out
[0] = (cmsFloat32Number
) XYZ
.X
;
2826 Out
[Stride
] = (cmsFloat32Number
) XYZ
.Y
;
2827 Out
[Stride
*2] = (cmsFloat32Number
) XYZ
.Z
;
2829 return output
+ sizeof(cmsFloat32Number
);
2835 cmsFloat32Number
* Out
= (cmsFloat32Number
*) output
;
2836 cmsXYZEncoded2Float(&XYZ
, wOut
);
2838 Out
[0] = (cmsFloat32Number
) XYZ
.X
;
2839 Out
[1] = (cmsFloat32Number
) XYZ
.Y
;
2840 Out
[2] = (cmsFloat32Number
) XYZ
.Z
;
2842 return output
+ (3 * sizeof(cmsFloat32Number
) + T_EXTRA(Info
->OutputFormat
) * sizeof(cmsFloat32Number
));
2847 cmsUInt8Number
* PackDoubleFrom16(CMSREGISTER _cmsTRANSFORM
* info
,
2848 CMSREGISTER cmsUInt16Number wOut
[],
2849 CMSREGISTER cmsUInt8Number
* output
,
2850 CMSREGISTER cmsUInt32Number Stride
)
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;
2864 Stride
/= PixelSize(info
->OutputFormat
);
2869 for (i
=0; i
< nChan
; i
++) {
2871 cmsUInt32Number index
= DoSwap
? (nChan
- i
- 1) : i
;
2873 v
= (cmsFloat64Number
) wOut
[index
] / maximum
;
2879 ((cmsFloat64Number
*) output
)[(i
+ start
) * Stride
]= v
;
2881 ((cmsFloat64Number
*) output
)[i
+ start
] = v
;
2885 if (Extra
== 0 && SwapFirst
) {
2887 memmove(swap1
+ 1, swap1
, (nChan
-1)* sizeof(cmsFloat64Number
));
2891 if (T_PLANAR(info
-> OutputFormat
))
2892 return output
+ sizeof(cmsFloat64Number
);
2894 return output
+ (nChan
+ Extra
) * sizeof(cmsFloat64Number
);
2900 cmsUInt8Number
* PackFloatFrom16(CMSREGISTER _cmsTRANSFORM
* info
,
2901 CMSREGISTER cmsUInt16Number wOut
[],
2902 CMSREGISTER cmsUInt8Number
* output
,
2903 CMSREGISTER cmsUInt32Number Stride
)
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;
2917 Stride
/= PixelSize(info
->OutputFormat
);
2922 for (i
= 0; i
< nChan
; i
++) {
2924 cmsUInt32Number index
= DoSwap
? (nChan
- i
- 1) : i
;
2926 v
= (cmsFloat64Number
)wOut
[index
] / maximum
;
2932 ((cmsFloat32Number
*)output
)[(i
+ start
) * Stride
] = (cmsFloat32Number
)v
;
2934 ((cmsFloat32Number
*)output
)[i
+ start
] = (cmsFloat32Number
)v
;
2938 if (Extra
== 0 && SwapFirst
) {
2940 memmove(swap1
+ 1, swap1
, (nChan
- 1)* sizeof(cmsFloat32Number
));
2941 *swap1
= (cmsFloat32Number
)v
;
2944 if (T_PLANAR(info
->OutputFormat
))
2945 return output
+ sizeof(cmsFloat32Number
);
2947 return output
+ (nChan
+ Extra
) * sizeof(cmsFloat32Number
);
2952 // --------------------------------------------------------------------------------------------------------
2955 cmsUInt8Number
* PackFloatsFromFloat(_cmsTRANSFORM
* info
,
2956 cmsFloat32Number wOut
[],
2957 cmsUInt8Number
* output
,
2958 cmsUInt32Number Stride
)
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;
2972 Stride
/= PixelSize(info
->OutputFormat
);
2977 for (i
= 0; i
< nChan
; i
++) {
2979 cmsUInt32Number index
= DoSwap
? (nChan
- i
- 1) : i
;
2981 v
= wOut
[index
] * maximum
;
2987 ((cmsFloat32Number
*)output
)[(i
+ start
)* Stride
] = (cmsFloat32Number
)v
;
2989 ((cmsFloat32Number
*)output
)[i
+ start
] = (cmsFloat32Number
)v
;
2993 if (Extra
== 0 && SwapFirst
) {
2995 memmove(swap1
+ 1, swap1
, (nChan
- 1)* sizeof(cmsFloat32Number
));
2996 *swap1
= (cmsFloat32Number
)v
;
2999 if (T_PLANAR(info
->OutputFormat
))
3000 return output
+ sizeof(cmsFloat32Number
);
3002 return output
+ (nChan
+ Extra
) * sizeof(cmsFloat32Number
);
3006 cmsUInt8Number
* PackDoublesFromFloat(_cmsTRANSFORM
* info
,
3007 cmsFloat32Number wOut
[],
3008 cmsUInt8Number
* output
,
3009 cmsUInt32Number Stride
)
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;
3023 Stride
/= PixelSize(info
->OutputFormat
);
3028 for (i
= 0; i
< nChan
; i
++) {
3030 cmsUInt32Number index
= DoSwap
? (nChan
- i
- 1) : i
;
3032 v
= wOut
[index
] * maximum
;
3038 ((cmsFloat64Number
*)output
)[(i
+ start
) * Stride
] = v
;
3040 ((cmsFloat64Number
*)output
)[i
+ start
] = v
;
3043 if (Extra
== 0 && SwapFirst
) {
3045 memmove(swap1
+ 1, swap1
, (nChan
- 1)* sizeof(cmsFloat64Number
));
3050 if (T_PLANAR(info
->OutputFormat
))
3051 return output
+ sizeof(cmsFloat64Number
);
3053 return output
+ (nChan
+ Extra
) * sizeof(cmsFloat64Number
);
3058 cmsUInt8Number
* PackLabFloatFromFloat(_cmsTRANSFORM
* Info
,
3059 cmsFloat32Number wOut
[],
3060 cmsUInt8Number
* output
,
3061 cmsUInt32Number Stride
)
3063 cmsFloat32Number
* Out
= (cmsFloat32Number
*) output
;
3065 if (T_PLANAR(Info
-> OutputFormat
)) {
3067 Stride
/= PixelSize(Info
->OutputFormat
);
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);
3073 return output
+ sizeof(cmsFloat32Number
);
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);
3081 return output
+ (sizeof(cmsFloat32Number
)*3 + T_EXTRA(Info
->OutputFormat
) * sizeof(cmsFloat32Number
));
3088 cmsUInt8Number
* PackLabDoubleFromFloat(_cmsTRANSFORM
* Info
,
3089 cmsFloat32Number wOut
[],
3090 cmsUInt8Number
* output
,
3091 cmsUInt32Number Stride
)
3093 cmsFloat64Number
* Out
= (cmsFloat64Number
*) output
;
3095 if (T_PLANAR(Info
-> OutputFormat
)) {
3097 Stride
/= PixelSize(Info
->OutputFormat
);
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);
3103 return output
+ sizeof(cmsFloat64Number
);
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);
3111 return output
+ (sizeof(cmsFloat64Number
)*3 + T_EXTRA(Info
->OutputFormat
) * sizeof(cmsFloat64Number
));
3117 // From 0..1 range to 0..MAX_ENCODEABLE_XYZ
3119 cmsUInt8Number
* PackXYZFloatFromFloat(_cmsTRANSFORM
* Info
,
3120 cmsFloat32Number wOut
[],
3121 cmsUInt8Number
* output
,
3122 cmsUInt32Number Stride
)
3124 cmsFloat32Number
* Out
= (cmsFloat32Number
*) output
;
3126 if (T_PLANAR(Info
-> OutputFormat
)) {
3128 Stride
/= PixelSize(Info
->OutputFormat
);
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
);
3134 return output
+ sizeof(cmsFloat32Number
);
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
);
3142 return output
+ (sizeof(cmsFloat32Number
)*3 + T_EXTRA(Info
->OutputFormat
) * sizeof(cmsFloat32Number
));
3147 // Same, but convert to double
3149 cmsUInt8Number
* PackXYZDoubleFromFloat(_cmsTRANSFORM
* Info
,
3150 cmsFloat32Number wOut
[],
3151 cmsUInt8Number
* output
,
3152 cmsUInt32Number Stride
)
3154 cmsFloat64Number
* Out
= (cmsFloat64Number
*) output
;
3156 if (T_PLANAR(Info
-> OutputFormat
)) {
3158 Stride
/= PixelSize(Info
->OutputFormat
);
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
);
3164 return output
+ sizeof(cmsFloat64Number
);
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
);
3172 return output
+ (sizeof(cmsFloat64Number
)*3 + T_EXTRA(Info
->OutputFormat
) * sizeof(cmsFloat64Number
));
3178 // ----------------------------------------------------------------------------------------------------------------
3180 #ifndef CMS_NO_HALF_SUPPORT
3182 // Decodes an stream of half floats to wIn[] described by input format
3185 cmsUInt8Number
* UnrollHalfTo16(CMSREGISTER _cmsTRANSFORM
* info
,
3186 CMSREGISTER cmsUInt16Number wIn
[],
3187 CMSREGISTER cmsUInt8Number
* accum
,
3188 CMSREGISTER cmsUInt32Number Stride
)
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
);
3199 cmsUInt32Number i
, start
= 0;
3200 cmsFloat32Number maximum
= IsInkSpace(info
->InputFormat
) ? 655.35F
: 65535.0F
;
3203 Stride
/= PixelSize(info
->OutputFormat
);
3208 for (i
=0; i
< nChan
; i
++) {
3210 cmsUInt32Number index
= DoSwap
? (nChan
- i
- 1) : i
;
3213 v
= _cmsHalf2Float ( ((cmsUInt16Number
*) accum
)[(i
+ start
) * Stride
] );
3215 v
= _cmsHalf2Float ( ((cmsUInt16Number
*) accum
)[i
+ start
] ) ;
3217 if (Reverse
) v
= maximum
- v
;
3219 wIn
[index
] = _cmsQuickSaturateWord((cmsFloat64Number
) v
* maximum
);
3223 if (Extra
== 0 && SwapFirst
) {
3224 cmsUInt16Number tmp
= wIn
[0];
3226 memmove(&wIn
[0], &wIn
[1], (nChan
-1) * sizeof(cmsUInt16Number
));
3230 if (T_PLANAR(info
-> InputFormat
))
3231 return accum
+ sizeof(cmsUInt16Number
);
3233 return accum
+ (nChan
+ Extra
) * sizeof(cmsUInt16Number
);
3236 // Decodes an stream of half floats to wIn[] described by input format
3239 cmsUInt8Number
* UnrollHalfToFloat(_cmsTRANSFORM
* info
,
3240 cmsFloat32Number wIn
[],
3241 cmsUInt8Number
* accum
,
3242 cmsUInt32Number Stride
)
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
);
3253 cmsUInt32Number i
, start
= 0;
3254 cmsFloat32Number maximum
= IsInkSpace(info
->InputFormat
) ? 100.0F
: 1.0F
;
3256 Stride
/= PixelSize(info
->OutputFormat
);
3261 for (i
=0; i
< nChan
; i
++) {
3263 cmsUInt32Number index
= DoSwap
? (nChan
- i
- 1) : i
;
3266 v
= _cmsHalf2Float ( ((cmsUInt16Number
*) accum
)[(i
+ start
) * Stride
] );
3268 v
= _cmsHalf2Float ( ((cmsUInt16Number
*) accum
)[i
+ start
] ) ;
3272 wIn
[index
] = Reverse
? 1 - v
: v
;
3276 if (Extra
== 0 && SwapFirst
) {
3277 cmsFloat32Number tmp
= wIn
[0];
3279 memmove(&wIn
[0], &wIn
[1], (nChan
-1) * sizeof(cmsFloat32Number
));
3283 if (T_PLANAR(info
-> InputFormat
))
3284 return accum
+ sizeof(cmsUInt16Number
);
3286 return accum
+ (nChan
+ Extra
) * sizeof(cmsUInt16Number
);
3291 cmsUInt8Number
* PackHalfFrom16(CMSREGISTER _cmsTRANSFORM
* info
,
3292 CMSREGISTER cmsUInt16Number wOut
[],
3293 CMSREGISTER cmsUInt8Number
* output
,
3294 CMSREGISTER cmsUInt32Number Stride
)
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;
3308 Stride
/= PixelSize(info
->OutputFormat
);
3313 for (i
= 0; i
< nChan
; i
++) {
3315 cmsUInt32Number index
= DoSwap
? (nChan
- i
- 1) : i
;
3317 v
= (cmsFloat32Number
)wOut
[index
] / maximum
;
3323 ((cmsUInt16Number
*)output
)[(i
+ start
) * Stride
] = _cmsFloat2Half(v
);
3325 ((cmsUInt16Number
*)output
)[i
+ start
] = _cmsFloat2Half(v
);
3329 if (Extra
== 0 && SwapFirst
) {
3331 memmove(swap1
+ 1, swap1
, (nChan
- 1)* sizeof(cmsUInt16Number
));
3332 *swap1
= _cmsFloat2Half(v
);
3335 if (T_PLANAR(info
->OutputFormat
))
3336 return output
+ sizeof(cmsUInt16Number
);
3338 return output
+ (nChan
+ Extra
) * sizeof(cmsUInt16Number
);
3344 cmsUInt8Number
* PackHalfFromFloat(_cmsTRANSFORM
* info
,
3345 cmsFloat32Number wOut
[],
3346 cmsUInt8Number
* output
,
3347 cmsUInt32Number Stride
)
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;
3361 Stride
/= PixelSize(info
->OutputFormat
);
3366 for (i
= 0; i
< nChan
; i
++) {
3368 cmsUInt32Number index
= DoSwap
? (nChan
- i
- 1) : i
;
3370 v
= wOut
[index
] * maximum
;
3376 ((cmsUInt16Number
*)output
)[(i
+ start
)* Stride
] = _cmsFloat2Half(v
);
3378 ((cmsUInt16Number
*)output
)[i
+ start
] = _cmsFloat2Half(v
);
3382 if (Extra
== 0 && SwapFirst
) {
3384 memmove(swap1
+ 1, swap1
, (nChan
- 1)* sizeof(cmsUInt16Number
));
3385 *swap1
= (cmsUInt16Number
)_cmsFloat2Half(v
);
3388 if (T_PLANAR(info
->OutputFormat
))
3389 return output
+ sizeof(cmsUInt16Number
);
3391 return output
+ (nChan
+ Extra
)* sizeof(cmsUInt16Number
);
3396 // ----------------------------------------------------------------------------------------------------------------
3399 static const cmsFormatters16 InputFormatters16
[] = {
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
},
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
},
3423 { TYPE_LabV2_8
, 0, UnrollLabV2_8
},
3424 { TYPE_ALabV2_8
, 0, UnrollALabV2_8
},
3425 { TYPE_LabV2_16
, 0, UnrollLabV2_16
},
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
},
3432 { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1),
3433 ANYSPACE
, Unroll3BytesSkip1SwapSwapFirst
},
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
},
3441 { BYTES_SH(1)|PLANAR_SH(1), ANYFLAVOR
|ANYSWAPFIRST
|ANYPREMUL
|
3442 ANYSWAP
|ANYEXTRA
|ANYCHANNELS
|ANYSPACE
, UnrollPlanarBytes
},
3444 { BYTES_SH(1), ANYFLAVOR
|ANYSWAPFIRST
|ANYSWAP
|ANYPREMUL
|
3445 ANYEXTRA
|ANYCHANNELS
|ANYSPACE
, UnrollChunkyBytes
},
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
},
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
},
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
},
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
},
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
}
3474 static const cmsFormattersFloat InputFormattersFloat
[] = {
3476 // Type Mask Function
3477 // ---------------------------- ------------------------------------ ----------------------------
3478 { TYPE_Lab_DBL
, ANYPLANAR
|ANYEXTRA
, UnrollLabDoubleToFloat
},
3479 { TYPE_Lab_FLT
, ANYPLANAR
|ANYEXTRA
, UnrollLabFloatToFloat
},
3481 { TYPE_XYZ_DBL
, ANYPLANAR
|ANYEXTRA
, UnrollXYZDoubleToFloat
},
3482 { TYPE_XYZ_FLT
, ANYPLANAR
|ANYEXTRA
, UnrollXYZFloatToFloat
},
3484 { FLOAT_SH(1)|BYTES_SH(4), ANYPLANAR
|ANYSWAPFIRST
|ANYSWAP
|ANYEXTRA
|
3485 ANYPREMUL
|ANYCHANNELS
|ANYSPACE
, UnrollFloatsToFloat
},
3487 { FLOAT_SH(1)|BYTES_SH(0), ANYPLANAR
|ANYSWAPFIRST
|ANYSWAP
|ANYEXTRA
|
3488 ANYCHANNELS
|ANYSPACE
|ANYPREMUL
, UnrollDoublesToFloat
},
3490 { TYPE_LabV2_8
, 0, UnrollLabV2_8ToFloat
},
3491 { TYPE_ALabV2_8
, 0, UnrollALabV2_8ToFloat
},
3492 { TYPE_LabV2_16
, 0, UnrollLabV2_16ToFloat
},
3494 { BYTES_SH(1), ANYPLANAR
|ANYSWAPFIRST
|ANYSWAP
|ANYEXTRA
|
3495 ANYCHANNELS
|ANYSPACE
, Unroll8ToFloat
},
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
},
3506 // Bit fields set to one in the mask are not compared
3508 cmsFormatter
_cmsGetStockInputFormatter(cmsUInt32Number dwInput
, cmsUInt32Number dwFlags
)
3515 case CMS_PACK_FLAGS_16BITS
: {
3516 for (i
=0; i
< sizeof(InputFormatters16
) / sizeof(cmsFormatters16
); i
++) {
3517 const cmsFormatters16
* f
= InputFormatters16
+ i
;
3519 if ((dwInput
& ~f
->Mask
) == f
->Type
) {
3527 case CMS_PACK_FLAGS_FLOAT
: {
3528 for (i
=0; i
< sizeof(InputFormattersFloat
) / sizeof(cmsFormattersFloat
); i
++) {
3529 const cmsFormattersFloat
* f
= InputFormattersFloat
+ i
;
3531 if ((dwInput
& ~f
->Mask
) == f
->Type
) {
3532 fr
.FmtFloat
= f
->Frm
;
3547 static const cmsFormatters16 OutputFormatters16
[] = {
3548 // Type Mask Function
3549 // ---------------------------- ------------------------------------ ----------------------------
3551 { TYPE_Lab_DBL
, ANYPLANAR
|ANYEXTRA
, PackLabDoubleFrom16
},
3552 { TYPE_XYZ_DBL
, ANYPLANAR
|ANYEXTRA
, PackXYZDoubleFrom16
},
3554 { TYPE_Lab_FLT
, ANYPLANAR
|ANYEXTRA
, PackLabFloatFrom16
},
3555 { TYPE_XYZ_FLT
, ANYPLANAR
|ANYEXTRA
, PackXYZFloatFrom16
},
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
},
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
},
3570 { CHANNELS_SH(1)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE
, Pack1ByteReversed
},
3572 { TYPE_LabV2_8
, 0, PackLabV2_8
},
3573 { TYPE_ALabV2_8
, 0, PackALabV2_8
},
3574 { TYPE_LabV2_16
, 0, PackLabV2_16
},
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
},
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
},
3603 { BYTES_SH(1), ANYFLAVOR
|ANYSWAPFIRST
|ANYSWAP
|ANYEXTRA
|ANYCHANNELS
|
3604 ANYSPACE
|ANYPREMUL
, PackChunkyBytes
},
3606 { BYTES_SH(1)|PLANAR_SH(1), ANYFLAVOR
|ANYSWAPFIRST
|ANYSWAP
|ANYEXTRA
|
3607 ANYCHANNELS
|ANYSPACE
|ANYPREMUL
, PackPlanarBytes
},
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
},
3622 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1),
3623 ANYSPACE
, Pack3WordsAndSkip1SwapSwapFirst
},
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
},
3630 { CHANNELS_SH(6)|BYTES_SH(2), ANYSPACE
, Pack6Words
},
3631 { CHANNELS_SH(6)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE
, Pack6WordsSwap
},
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
}
3641 static const cmsFormattersFloat OutputFormattersFloat
[] = {
3642 // Type Mask Function
3643 // ---------------------------- --------------------------------------------------- ----------------------------
3644 { TYPE_Lab_FLT
, ANYPLANAR
|ANYEXTRA
, PackLabFloatFromFloat
},
3645 { TYPE_XYZ_FLT
, ANYPLANAR
|ANYEXTRA
, PackXYZFloatFromFloat
},
3647 { TYPE_Lab_DBL
, ANYPLANAR
|ANYEXTRA
, PackLabDoubleFromFloat
},
3648 { TYPE_XYZ_DBL
, ANYPLANAR
|ANYEXTRA
, PackXYZDoubleFromFloat
},
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
},
3662 // Bit fields set to one in the mask are not compared
3664 cmsFormatter
_cmsGetStockOutputFormatter(cmsUInt32Number dwInput
, cmsUInt32Number dwFlags
)
3669 // Optimization is only a hint
3670 dwInput
&= ~OPTIMIZED_SH(1);
3675 case CMS_PACK_FLAGS_16BITS
: {
3677 for (i
=0; i
< sizeof(OutputFormatters16
) / sizeof(cmsFormatters16
); i
++) {
3678 const cmsFormatters16
* f
= OutputFormatters16
+ i
;
3680 if ((dwInput
& ~f
->Mask
) == f
->Type
) {
3688 case CMS_PACK_FLAGS_FLOAT
: {
3690 for (i
=0; i
< sizeof(OutputFormattersFloat
) / sizeof(cmsFormattersFloat
); i
++) {
3691 const cmsFormattersFloat
* f
= OutputFormattersFloat
+ i
;
3693 if ((dwInput
& ~f
->Mask
) == f
->Type
) {
3694 fr
.FmtFloat
= f
->Frm
;
3710 typedef struct _cms_formatters_factory_list
{
3712 cmsFormatterFactory Factory
;
3713 struct _cms_formatters_factory_list
*Next
;
3715 } cmsFormattersFactoryList
;
3717 _cmsFormattersPluginChunkType _cmsFormattersPluginChunk
= { NULL
};
3720 // Duplicates the zone of memory used by the plug-in in the new context
3722 void DupFormatterFactoryList(struct _cmsContext_struct
* ctx
,
3723 const struct _cmsContext_struct
* src
)
3725 _cmsFormattersPluginChunkType newHead
= { NULL
};
3726 cmsFormattersFactoryList
* entry
;
3727 cmsFormattersFactoryList
* Anterior
= NULL
;
3728 _cmsFormattersPluginChunkType
* head
= (_cmsFormattersPluginChunkType
*) src
->chunks
[FormattersPlugin
];
3730 _cmsAssert(head
!= NULL
);
3732 // Walk the list copying all nodes
3733 for (entry
= head
->FactoryList
;
3735 entry
= entry
->Next
) {
3737 cmsFormattersFactoryList
*newEntry
= ( cmsFormattersFactoryList
*) _cmsSubAllocDup(ctx
->MemPool
, entry
, sizeof(cmsFormattersFactoryList
));
3739 if (newEntry
== NULL
)
3742 // We want to keep the linked list order, so this is a little bit tricky
3743 newEntry
-> Next
= NULL
;
3745 Anterior
-> Next
= newEntry
;
3747 Anterior
= newEntry
;
3749 if (newHead
.FactoryList
== NULL
)
3750 newHead
.FactoryList
= newEntry
;
3753 ctx
->chunks
[FormattersPlugin
] = _cmsSubAllocDup(ctx
->MemPool
, &newHead
, sizeof(_cmsFormattersPluginChunkType
));
3756 // The interpolation plug-in memory chunk allocator/dup
3757 void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct
* ctx
,
3758 const struct _cmsContext_struct
* src
)
3760 _cmsAssert(ctx
!= NULL
);
3764 // Duplicate the LIST
3765 DupFormatterFactoryList(ctx
, src
);
3768 static _cmsFormattersPluginChunkType FormattersPluginChunk
= { NULL
};
3769 ctx
->chunks
[FormattersPlugin
] = _cmsSubAllocDup(ctx
->MemPool
, &FormattersPluginChunk
, sizeof(_cmsFormattersPluginChunkType
));
3775 // Formatters management
3776 cmsBool
_cmsRegisterFormattersPlugin(cmsContext ContextID
, cmsPluginBase
* Data
)
3778 _cmsFormattersPluginChunkType
* ctx
= ( _cmsFormattersPluginChunkType
*) _cmsContextGetClientChunk(ContextID
, FormattersPlugin
);
3779 cmsPluginFormatters
* Plugin
= (cmsPluginFormatters
*) Data
;
3780 cmsFormattersFactoryList
* fl
;
3782 // Reset to built-in defaults
3785 ctx
->FactoryList
= NULL
;
3789 fl
= (cmsFormattersFactoryList
*) _cmsPluginMalloc(ContextID
, sizeof(cmsFormattersFactoryList
));
3790 if (fl
== NULL
) return FALSE
;
3792 fl
->Factory
= Plugin
->FormattersFactory
;
3794 fl
->Next
= ctx
-> FactoryList
;
3795 ctx
->FactoryList
= fl
;
3800 cmsFormatter CMSEXPORT
_cmsGetFormatter(cmsContext ContextID
,
3801 cmsUInt32Number Type
, // Specific type, i.e. TYPE_RGB_8
3802 cmsFormatterDirection Dir
,
3803 cmsUInt32Number dwFlags
)
3805 _cmsFormattersPluginChunkType
* ctx
= ( _cmsFormattersPluginChunkType
*) _cmsContextGetClientChunk(ContextID
, FormattersPlugin
);
3806 cmsFormattersFactoryList
* f
;
3808 if (T_CHANNELS(Type
) == 0) {
3809 static const cmsFormatter nullFormatter
= { 0 };
3810 return nullFormatter
;
3813 for (f
=ctx
->FactoryList
; f
!= NULL
; f
= f
->Next
) {
3815 cmsFormatter fn
= f
->Factory(Type
, Dir
, dwFlags
);
3816 if (fn
.Fmt16
!= NULL
) return fn
;
3819 // Revert to default
3820 if (Dir
== cmsFormatterInput
)
3821 return _cmsGetStockInputFormatter(Type
, dwFlags
);
3823 return _cmsGetStockOutputFormatter(Type
, dwFlags
);
3827 // Return whatever given formatter refers to float values
3828 cmsBool
_cmsFormatterIsFloat(cmsUInt32Number Type
)
3830 return T_FLOAT(Type
) ? TRUE
: FALSE
;
3833 // Return whatever given formatter refers to 8 bits
3834 cmsBool
_cmsFormatterIs8bit(cmsUInt32Number Type
)
3836 cmsUInt32Number Bytes
= T_BYTES(Type
);
3838 return (Bytes
== 1);
3841 // Build a suitable formatter for the colorspace of this profile
3842 cmsUInt32Number CMSEXPORT
cmsFormatterForColorspaceOfProfile(cmsHPROFILE hProfile
, cmsUInt32Number nBytes
, cmsBool lIsFloat
)
3845 cmsColorSpaceSignature ColorSpace
= cmsGetColorSpace(hProfile
);
3846 cmsUInt32Number ColorSpaceBits
= (cmsUInt32Number
) _cmsLCMScolorSpace(ColorSpace
);
3847 cmsInt32Number nOutputChans
= cmsChannelsOfColorSpace(ColorSpace
);
3848 cmsUInt32Number Float
= lIsFloat
? 1U : 0;
3850 // Unsupported color space?
3851 if (nOutputChans
< 0) return 0;
3853 // Create a fake formatter for result
3854 return FLOAT_SH(Float
) | COLORSPACE_SH(ColorSpaceBits
) | BYTES_SH(nBytes
) | CHANNELS_SH(nOutputChans
);
3857 // Build a suitable formatter for the colorspace of this profile
3858 cmsUInt32Number CMSEXPORT
cmsFormatterForPCSOfProfile(cmsHPROFILE hProfile
, cmsUInt32Number nBytes
, cmsBool lIsFloat
)
3861 cmsColorSpaceSignature ColorSpace
= cmsGetPCS(hProfile
);
3863 cmsUInt32Number ColorSpaceBits
= (cmsUInt32Number
) _cmsLCMScolorSpace(ColorSpace
);
3864 cmsUInt32Number nOutputChans
= cmsChannelsOf(ColorSpace
);
3865 cmsUInt32Number Float
= lIsFloat
? 1U : 0;
3867 // Unsupported color space?
3868 if (nOutputChans
< 0) return 0;
3870 // Create a fake formatter for result
3871 return FLOAT_SH(Float
) | COLORSPACE_SH(ColorSpaceBits
) | BYTES_SH(nBytes
) | CHANNELS_SH(nOutputChans
);