1 //---------------------------------------------------------------------------------
3 // Little Color Management System
4 // Copyright (c) 1998-2010 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)
84 // Supress waning about info never being used
87 #pragma warning(disable : 4100)
90 // Unpacking routines (16 bits) ----------------------------------------------------------------------------------------
93 // Does almost everything but is slow
95 cmsUInt8Number* UnrollChunkyBytes(register _cmsTRANSFORM* info,
96 register cmsUInt16Number wIn[],
97 register cmsUInt8Number* accum,
98 register cmsUInt32Number Stride)
100 int nChan = T_CHANNELS(info -> InputFormat);
101 int DoSwap = T_DOSWAP(info ->InputFormat);
102 int Reverse = T_FLAVOR(info ->InputFormat);
103 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
104 int Extra = T_EXTRA(info -> InputFormat);
105 int ExtraFirst = DoSwap ^ SwapFirst;
113 for (i=0; i < nChan; i++) {
114 int index = DoSwap ? (nChan - i - 1) : i;
116 v = FROM_8_TO_16(*accum);
117 v = Reverse ? REVERSE_FLAVOR_16(v) : v;
126 if (Extra == 0 && SwapFirst) {
127 cmsUInt16Number tmp = wIn[0];
129 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
135 cmsUNUSED_PARAMETER(info);
136 cmsUNUSED_PARAMETER(Stride);
140 // Extra channels are just ignored because come in the next planes
142 cmsUInt8Number* UnrollPlanarBytes(register _cmsTRANSFORM* info,
143 register cmsUInt16Number wIn[],
144 register cmsUInt8Number* accum,
145 register cmsUInt32Number Stride)
147 int nChan = T_CHANNELS(info -> InputFormat);
148 int DoSwap = T_DOSWAP(info ->InputFormat);
149 int SwapFirst = T_SWAPFIRST(info ->InputFormat);
150 int Reverse = T_FLAVOR(info ->InputFormat);
152 cmsUInt8Number* Init = accum;
154 if (DoSwap ^ SwapFirst) {
155 accum += T_EXTRA(info -> InputFormat) * Stride;
158 for (i=0; i < nChan; i++) {
160 int index = DoSwap ? (nChan - i - 1) : i;
161 cmsUInt16Number v = FROM_8_TO_16(*accum);
163 wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
170 // Special cases, provided for performance
172 cmsUInt8Number* Unroll4Bytes(register _cmsTRANSFORM* info,
173 register cmsUInt16Number wIn[],
174 register cmsUInt8Number* accum,
175 register cmsUInt32Number Stride)
177 wIn[0] = FROM_8_TO_16(*accum); accum++; // C
178 wIn[1] = FROM_8_TO_16(*accum); accum++; // M
179 wIn[2] = FROM_8_TO_16(*accum); accum++; // Y
180 wIn[3] = FROM_8_TO_16(*accum); accum++; // K
184 cmsUNUSED_PARAMETER(info);
185 cmsUNUSED_PARAMETER(Stride);
189 cmsUInt8Number* Unroll4BytesReverse(register _cmsTRANSFORM* info,
190 register cmsUInt16Number wIn[],
191 register cmsUInt8Number* accum,
192 register cmsUInt32Number Stride)
194 wIn[0] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // C
195 wIn[1] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // M
196 wIn[2] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // Y
197 wIn[3] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // K
201 cmsUNUSED_PARAMETER(info);
202 cmsUNUSED_PARAMETER(Stride);
206 cmsUInt8Number* Unroll4BytesSwapFirst(register _cmsTRANSFORM* info,
207 register cmsUInt16Number wIn[],
208 register cmsUInt8Number* accum,
209 register cmsUInt32Number Stride)
211 wIn[3] = FROM_8_TO_16(*accum); accum++; // K
212 wIn[0] = FROM_8_TO_16(*accum); accum++; // C
213 wIn[1] = FROM_8_TO_16(*accum); accum++; // M
214 wIn[2] = FROM_8_TO_16(*accum); accum++; // Y
218 cmsUNUSED_PARAMETER(info);
219 cmsUNUSED_PARAMETER(Stride);
224 cmsUInt8Number* Unroll4BytesSwap(register _cmsTRANSFORM* info,
225 register cmsUInt16Number wIn[],
226 register cmsUInt8Number* accum,
227 register cmsUInt32Number Stride)
229 wIn[3] = FROM_8_TO_16(*accum); accum++; // K
230 wIn[2] = FROM_8_TO_16(*accum); accum++; // Y
231 wIn[1] = FROM_8_TO_16(*accum); accum++; // M
232 wIn[0] = FROM_8_TO_16(*accum); accum++; // C
236 cmsUNUSED_PARAMETER(info);
237 cmsUNUSED_PARAMETER(Stride);
241 cmsUInt8Number* Unroll4BytesSwapSwapFirst(register _cmsTRANSFORM* info,
242 register cmsUInt16Number wIn[],
243 register cmsUInt8Number* accum,
244 register cmsUInt32Number Stride)
246 wIn[2] = FROM_8_TO_16(*accum); accum++; // K
247 wIn[1] = FROM_8_TO_16(*accum); accum++; // Y
248 wIn[0] = FROM_8_TO_16(*accum); accum++; // M
249 wIn[3] = FROM_8_TO_16(*accum); accum++; // C
253 cmsUNUSED_PARAMETER(info);
254 cmsUNUSED_PARAMETER(Stride);
258 cmsUInt8Number* Unroll3Bytes(register _cmsTRANSFORM* info,
259 register cmsUInt16Number wIn[],
260 register cmsUInt8Number* accum,
261 register cmsUInt32Number Stride)
263 wIn[0] = FROM_8_TO_16(*accum); accum++; // R
264 wIn[1] = FROM_8_TO_16(*accum); accum++; // G
265 wIn[2] = FROM_8_TO_16(*accum); accum++; // B
269 cmsUNUSED_PARAMETER(info);
270 cmsUNUSED_PARAMETER(Stride);
274 cmsUInt8Number* Unroll3BytesSkip1Swap(register _cmsTRANSFORM* info,
275 register cmsUInt16Number wIn[],
276 register cmsUInt8Number* accum,
277 register cmsUInt32Number Stride)
280 wIn[2] = FROM_8_TO_16(*accum); accum++; // B
281 wIn[1] = FROM_8_TO_16(*accum); accum++; // G
282 wIn[0] = FROM_8_TO_16(*accum); accum++; // R
286 cmsUNUSED_PARAMETER(info);
287 cmsUNUSED_PARAMETER(Stride);
291 cmsUInt8Number* Unroll3BytesSkip1SwapSwapFirst(register _cmsTRANSFORM* info,
292 register cmsUInt16Number wIn[],
293 register cmsUInt8Number* accum,
294 register cmsUInt32Number Stride)
296 wIn[2] = FROM_8_TO_16(*accum); accum++; // B
297 wIn[1] = FROM_8_TO_16(*accum); accum++; // G
298 wIn[0] = FROM_8_TO_16(*accum); accum++; // R
303 cmsUNUSED_PARAMETER(info);
304 cmsUNUSED_PARAMETER(Stride);
308 cmsUInt8Number* Unroll3BytesSkip1SwapFirst(register _cmsTRANSFORM* info,
309 register cmsUInt16Number wIn[],
310 register cmsUInt8Number* accum,
311 register cmsUInt32Number Stride)
314 wIn[0] = FROM_8_TO_16(*accum); accum++; // R
315 wIn[1] = FROM_8_TO_16(*accum); accum++; // G
316 wIn[2] = FROM_8_TO_16(*accum); accum++; // B
320 cmsUNUSED_PARAMETER(info);
321 cmsUNUSED_PARAMETER(Stride);
327 cmsUInt8Number* Unroll3BytesSwap(register _cmsTRANSFORM* info,
328 register cmsUInt16Number wIn[],
329 register cmsUInt8Number* accum,
330 register cmsUInt32Number Stride)
332 wIn[2] = FROM_8_TO_16(*accum); accum++; // B
333 wIn[1] = FROM_8_TO_16(*accum); accum++; // G
334 wIn[0] = FROM_8_TO_16(*accum); accum++; // R
338 cmsUNUSED_PARAMETER(info);
339 cmsUNUSED_PARAMETER(Stride);
343 cmsUInt8Number* UnrollLabV2_8(register _cmsTRANSFORM* info,
344 register cmsUInt16Number wIn[],
345 register cmsUInt8Number* accum,
346 register cmsUInt32Number Stride)
348 wIn[0] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // L
349 wIn[1] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // a
350 wIn[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // b
354 cmsUNUSED_PARAMETER(info);
355 cmsUNUSED_PARAMETER(Stride);
359 cmsUInt8Number* UnrollALabV2_8(register _cmsTRANSFORM* info,
360 register cmsUInt16Number wIn[],
361 register cmsUInt8Number* accum,
362 register cmsUInt32Number Stride)
365 wIn[0] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // L
366 wIn[1] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // a
367 wIn[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // b
371 cmsUNUSED_PARAMETER(info);
372 cmsUNUSED_PARAMETER(Stride);
376 cmsUInt8Number* UnrollLabV2_16(register _cmsTRANSFORM* info,
377 register cmsUInt16Number wIn[],
378 register cmsUInt8Number* accum,
379 register cmsUInt32Number Stride)
381 wIn[0] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // L
382 wIn[1] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // a
383 wIn[2] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // b
387 cmsUNUSED_PARAMETER(info);
388 cmsUNUSED_PARAMETER(Stride);
393 cmsUInt8Number* Unroll2Bytes(register _cmsTRANSFORM* info,
394 register cmsUInt16Number wIn[],
395 register cmsUInt8Number* accum,
396 register cmsUInt32Number Stride)
398 wIn[0] = FROM_8_TO_16(*accum); accum++; // ch1
399 wIn[1] = FROM_8_TO_16(*accum); accum++; // ch2
403 cmsUNUSED_PARAMETER(info);
404 cmsUNUSED_PARAMETER(Stride);
410 // Monochrome duplicates L into RGB for null-transforms
412 cmsUInt8Number* Unroll1Byte(register _cmsTRANSFORM* info,
413 register cmsUInt16Number wIn[],
414 register cmsUInt8Number* accum,
415 register cmsUInt32Number Stride)
417 wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L
421 cmsUNUSED_PARAMETER(info);
422 cmsUNUSED_PARAMETER(Stride);
427 cmsUInt8Number* Unroll1ByteSkip1(register _cmsTRANSFORM* info,
428 register cmsUInt16Number wIn[],
429 register cmsUInt8Number* accum,
430 register cmsUInt32Number Stride)
432 wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L
437 cmsUNUSED_PARAMETER(info);
438 cmsUNUSED_PARAMETER(Stride);
442 cmsUInt8Number* Unroll1ByteSkip2(register _cmsTRANSFORM* info,
443 register cmsUInt16Number wIn[],
444 register cmsUInt8Number* accum,
445 register cmsUInt32Number Stride)
447 wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L
452 cmsUNUSED_PARAMETER(info);
453 cmsUNUSED_PARAMETER(Stride);
457 cmsUInt8Number* Unroll1ByteReversed(register _cmsTRANSFORM* info,
458 register cmsUInt16Number wIn[],
459 register cmsUInt8Number* accum,
460 register cmsUInt32Number Stride)
462 wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(FROM_8_TO_16(*accum)); accum++; // L
466 cmsUNUSED_PARAMETER(info);
467 cmsUNUSED_PARAMETER(Stride);
472 cmsUInt8Number* UnrollAnyWords(register _cmsTRANSFORM* info,
473 register cmsUInt16Number wIn[],
474 register cmsUInt8Number* accum,
475 register cmsUInt32Number Stride)
477 int nChan = T_CHANNELS(info -> InputFormat);
478 int SwapEndian = T_ENDIAN16(info -> InputFormat);
479 int DoSwap = T_DOSWAP(info ->InputFormat);
480 int Reverse = T_FLAVOR(info ->InputFormat);
481 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
482 int Extra = T_EXTRA(info -> InputFormat);
483 int ExtraFirst = DoSwap ^ SwapFirst;
487 accum += Extra * sizeof(cmsUInt16Number);
490 for (i=0; i < nChan; i++) {
492 int index = DoSwap ? (nChan - i - 1) : i;
493 cmsUInt16Number v = *(cmsUInt16Number*) accum;
496 v = CHANGE_ENDIAN(v);
498 wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
500 accum += sizeof(cmsUInt16Number);
504 accum += Extra * sizeof(cmsUInt16Number);
507 if (Extra == 0 && SwapFirst) {
509 cmsUInt16Number tmp = wIn[0];
511 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
517 cmsUNUSED_PARAMETER(Stride);
521 cmsUInt8Number* UnrollPlanarWords(register _cmsTRANSFORM* info,
522 register cmsUInt16Number wIn[],
523 register cmsUInt8Number* accum,
524 register cmsUInt32Number Stride)
526 int nChan = T_CHANNELS(info -> InputFormat);
527 int DoSwap= T_DOSWAP(info ->InputFormat);
528 int Reverse= T_FLAVOR(info ->InputFormat);
529 int SwapEndian = T_ENDIAN16(info -> InputFormat);
531 cmsUInt8Number* Init = accum;
534 accum += T_EXTRA(info -> InputFormat) * Stride * sizeof(cmsUInt16Number);
537 for (i=0; i < nChan; i++) {
539 int index = DoSwap ? (nChan - i - 1) : i;
540 cmsUInt16Number v = *(cmsUInt16Number*) accum;
543 v = CHANGE_ENDIAN(v);
545 wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
547 accum += Stride * sizeof(cmsUInt16Number);
550 return (Init + sizeof(cmsUInt16Number));
555 cmsUInt8Number* Unroll4Words(register _cmsTRANSFORM* info,
556 register cmsUInt16Number wIn[],
557 register cmsUInt8Number* accum,
558 register cmsUInt32Number Stride)
560 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
561 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
562 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
563 wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
567 cmsUNUSED_PARAMETER(info);
568 cmsUNUSED_PARAMETER(Stride);
572 cmsUInt8Number* Unroll4WordsReverse(register _cmsTRANSFORM* info,
573 register cmsUInt16Number wIn[],
574 register cmsUInt8Number* accum,
575 register cmsUInt32Number Stride)
577 wIn[0] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // C
578 wIn[1] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // M
579 wIn[2] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // Y
580 wIn[3] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // K
584 cmsUNUSED_PARAMETER(info);
585 cmsUNUSED_PARAMETER(Stride);
589 cmsUInt8Number* Unroll4WordsSwapFirst(register _cmsTRANSFORM* info,
590 register cmsUInt16Number wIn[],
591 register cmsUInt8Number* accum,
592 register cmsUInt32Number Stride)
594 wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
595 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
596 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
597 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
601 cmsUNUSED_PARAMETER(info);
602 cmsUNUSED_PARAMETER(Stride);
607 cmsUInt8Number* Unroll4WordsSwap(register _cmsTRANSFORM* info,
608 register cmsUInt16Number wIn[],
609 register cmsUInt8Number* accum,
610 register cmsUInt32Number Stride)
612 wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
613 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
614 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
615 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
619 cmsUNUSED_PARAMETER(info);
620 cmsUNUSED_PARAMETER(Stride);
624 cmsUInt8Number* Unroll4WordsSwapSwapFirst(register _cmsTRANSFORM* info,
625 register cmsUInt16Number wIn[],
626 register cmsUInt8Number* accum,
627 register cmsUInt32Number Stride)
629 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // K
630 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // Y
631 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // M
632 wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // C
636 cmsUNUSED_PARAMETER(info);
637 cmsUNUSED_PARAMETER(Stride);
641 cmsUInt8Number* Unroll3Words(register _cmsTRANSFORM* info,
642 register cmsUInt16Number wIn[],
643 register cmsUInt8Number* accum,
644 register cmsUInt32Number Stride)
646 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C R
647 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M G
648 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y B
652 cmsUNUSED_PARAMETER(info);
653 cmsUNUSED_PARAMETER(Stride);
657 cmsUInt8Number* Unroll3WordsSwap(register _cmsTRANSFORM* info,
658 register cmsUInt16Number wIn[],
659 register cmsUInt8Number* accum,
660 register cmsUInt32Number Stride)
662 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // C R
663 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M G
664 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // Y B
668 cmsUNUSED_PARAMETER(info);
669 cmsUNUSED_PARAMETER(Stride);
673 cmsUInt8Number* Unroll3WordsSkip1Swap(register _cmsTRANSFORM* info,
674 register cmsUInt16Number wIn[],
675 register cmsUInt8Number* accum,
676 register cmsUInt32Number Stride)
679 wIn[2] = *(cmsUInt16Number*) accum; accum += 2; // R
680 wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // G
681 wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // B
685 cmsUNUSED_PARAMETER(info);
686 cmsUNUSED_PARAMETER(Stride);
690 cmsUInt8Number* Unroll3WordsSkip1SwapFirst(register _cmsTRANSFORM* info,
691 register cmsUInt16Number wIn[],
692 register cmsUInt8Number* accum,
693 register cmsUInt32Number Stride)
696 wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // R
697 wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // G
698 wIn[2] = *(cmsUInt16Number*) accum; accum += 2; // B
702 cmsUNUSED_PARAMETER(info);
703 cmsUNUSED_PARAMETER(Stride);
707 cmsUInt8Number* Unroll1Word(register _cmsTRANSFORM* info,
708 register cmsUInt16Number wIn[],
709 register cmsUInt8Number* accum,
710 register cmsUInt32Number Stride)
712 wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // L
716 cmsUNUSED_PARAMETER(info);
717 cmsUNUSED_PARAMETER(Stride);
721 cmsUInt8Number* Unroll1WordReversed(register _cmsTRANSFORM* info,
722 register cmsUInt16Number wIn[],
723 register cmsUInt8Number* accum,
724 register cmsUInt32Number Stride)
726 wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2;
730 cmsUNUSED_PARAMETER(info);
731 cmsUNUSED_PARAMETER(Stride);
735 cmsUInt8Number* Unroll1WordSkip3(register _cmsTRANSFORM* info,
736 register cmsUInt16Number wIn[],
737 register cmsUInt8Number* accum,
738 register cmsUInt32Number Stride)
740 wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum;
746 cmsUNUSED_PARAMETER(info);
747 cmsUNUSED_PARAMETER(Stride);
751 cmsUInt8Number* Unroll2Words(register _cmsTRANSFORM* info,
752 register cmsUInt16Number wIn[],
753 register cmsUInt8Number* accum,
754 register cmsUInt32Number Stride)
756 wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // ch1
757 wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // ch2
761 cmsUNUSED_PARAMETER(info);
762 cmsUNUSED_PARAMETER(Stride);
766 // This is a conversion of Lab double to 16 bits
768 cmsUInt8Number* UnrollLabDoubleTo16(register _cmsTRANSFORM* info,
769 register cmsUInt16Number wIn[],
770 register cmsUInt8Number* accum,
771 register cmsUInt32Number Stride)
773 if (T_PLANAR(info -> InputFormat)) {
775 cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
781 Lab.b = Pt[Stride*2];
783 cmsFloat2LabEncoded(wIn, &Lab);
784 return accum + sizeof(cmsFloat64Number);
788 cmsFloat2LabEncoded(wIn, (cmsCIELab*) accum);
789 accum += sizeof(cmsCIELab) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat64Number);
795 // This is a conversion of Lab float to 16 bits
797 cmsUInt8Number* UnrollLabFloatTo16(register _cmsTRANSFORM* info,
798 register cmsUInt16Number wIn[],
799 register cmsUInt8Number* accum,
800 register cmsUInt32Number Stride)
804 if (T_PLANAR(info -> InputFormat)) {
806 cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
811 Lab.b = Pt[Stride*2];
813 cmsFloat2LabEncoded(wIn, &Lab);
814 return accum + sizeof(cmsFloat32Number);
818 Lab.L = ((cmsFloat32Number*) accum)[0];
819 Lab.a = ((cmsFloat32Number*) accum)[1];
820 Lab.b = ((cmsFloat32Number*) accum)[2];
822 cmsFloat2LabEncoded(wIn, &Lab);
823 accum += (3 + T_EXTRA(info ->InputFormat)) * sizeof(cmsFloat32Number);
828 // This is a conversion of XYZ double to 16 bits
830 cmsUInt8Number* UnrollXYZDoubleTo16(register _cmsTRANSFORM* info,
831 register cmsUInt16Number wIn[],
832 register cmsUInt8Number* accum,
833 register cmsUInt32Number Stride)
835 if (T_PLANAR(info -> InputFormat)) {
837 cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
842 XYZ.Z = Pt[Stride*2];
843 cmsFloat2XYZEncoded(wIn, &XYZ);
845 return accum + sizeof(cmsFloat64Number);
850 cmsFloat2XYZEncoded(wIn, (cmsCIEXYZ*) accum);
851 accum += sizeof(cmsCIEXYZ) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat64Number);
857 // This is a conversion of XYZ float to 16 bits
859 cmsUInt8Number* UnrollXYZFloatTo16(register _cmsTRANSFORM* info,
860 register cmsUInt16Number wIn[],
861 register cmsUInt8Number* accum,
862 register cmsUInt32Number Stride)
864 if (T_PLANAR(info -> InputFormat)) {
866 cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
871 XYZ.Z = Pt[Stride*2];
872 cmsFloat2XYZEncoded(wIn, &XYZ);
874 return accum + sizeof(cmsFloat32Number);
879 cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
885 cmsFloat2XYZEncoded(wIn, &XYZ);
887 accum += 3 * sizeof(cmsFloat32Number) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat32Number);
893 // Check if space is marked as ink
894 cmsINLINE cmsBool IsInkSpace(cmsUInt32Number Type)
896 switch (T_COLORSPACE(Type)) {
910 case PT_MCH15: return TRUE;
912 default: return FALSE;
916 // Inks does come in percentage, remaining cases are between 0..1.0, again to 16 bits
918 cmsUInt8Number* UnrollDoubleTo16(register _cmsTRANSFORM* info,
919 register cmsUInt16Number wIn[],
920 register cmsUInt8Number* accum,
921 register cmsUInt32Number Stride)
924 int nChan = T_CHANNELS(info -> InputFormat);
925 int DoSwap = T_DOSWAP(info ->InputFormat);
926 int Reverse = T_FLAVOR(info ->InputFormat);
927 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
928 int Extra = T_EXTRA(info -> InputFormat);
929 int ExtraFirst = DoSwap ^ SwapFirst;
930 int Planar = T_PLANAR(info -> InputFormat);
934 cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
940 for (i=0; i < nChan; i++) {
942 int index = DoSwap ? (nChan - i - 1) : i;
945 v = (cmsFloat32Number) ((cmsFloat64Number*) accum)[(i + start) * Stride];
947 v = (cmsFloat32Number) ((cmsFloat64Number*) accum)[i + start];
949 vi = _cmsQuickSaturateWord(v * maximum);
952 vi = REVERSE_FLAVOR_16(vi);
958 if (Extra == 0 && SwapFirst) {
959 cmsUInt16Number tmp = wIn[0];
961 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
965 if (T_PLANAR(info -> InputFormat))
966 return accum + sizeof(cmsFloat64Number);
968 return accum + (nChan + Extra) * sizeof(cmsFloat64Number);
974 cmsUInt8Number* UnrollFloatTo16(register _cmsTRANSFORM* info,
975 register cmsUInt16Number wIn[],
976 register cmsUInt8Number* accum,
977 register cmsUInt32Number Stride)
980 int nChan = T_CHANNELS(info -> InputFormat);
981 int DoSwap = T_DOSWAP(info ->InputFormat);
982 int Reverse = T_FLAVOR(info ->InputFormat);
983 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
984 int Extra = T_EXTRA(info -> InputFormat);
985 int ExtraFirst = DoSwap ^ SwapFirst;
986 int Planar = T_PLANAR(info -> InputFormat);
990 cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
996 for (i=0; i < nChan; i++) {
998 int index = DoSwap ? (nChan - i - 1) : i;
1001 v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[(i + start) * Stride];
1003 v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[i + start];
1005 vi = _cmsQuickSaturateWord(v * maximum);
1008 vi = REVERSE_FLAVOR_16(vi);
1014 if (Extra == 0 && SwapFirst) {
1015 cmsUInt16Number tmp = wIn[0];
1017 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
1021 if (T_PLANAR(info -> InputFormat))
1022 return accum + sizeof(cmsFloat32Number);
1024 return accum + (nChan + Extra) * sizeof(cmsFloat32Number);
1030 // For 1 channel, we need to duplicate data (it comes in 0..1.0 range)
1032 cmsUInt8Number* UnrollDouble1Chan(register _cmsTRANSFORM* info,
1033 register cmsUInt16Number wIn[],
1034 register cmsUInt8Number* accum,
1035 register cmsUInt32Number Stride)
1037 cmsFloat64Number* Inks = (cmsFloat64Number*) accum;
1039 wIn[0] = wIn[1] = wIn[2] = _cmsQuickSaturateWord(Inks[0] * 65535.0);
1041 return accum + sizeof(cmsFloat64Number);
1043 cmsUNUSED_PARAMETER(info);
1044 cmsUNUSED_PARAMETER(Stride);
1047 //-------------------------------------------------------------------------------------------------------------------
1049 // For anything going from cmsFloat32Number
1051 cmsUInt8Number* UnrollFloatsToFloat(_cmsTRANSFORM* info,
1052 cmsFloat32Number wIn[],
1053 cmsUInt8Number* accum,
1054 cmsUInt32Number Stride)
1057 int nChan = T_CHANNELS(info -> InputFormat);
1058 int DoSwap = T_DOSWAP(info ->InputFormat);
1059 int Reverse = T_FLAVOR(info ->InputFormat);
1060 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
1061 int Extra = T_EXTRA(info -> InputFormat);
1062 int ExtraFirst = DoSwap ^ SwapFirst;
1063 int Planar = T_PLANAR(info -> InputFormat);
1066 cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 100.0F : 1.0F;
1072 for (i=0; i < nChan; i++) {
1074 int index = DoSwap ? (nChan - i - 1) : i;
1077 v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[(i + start) * Stride];
1079 v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[i + start];
1083 wIn[index] = Reverse ? 1 - v : v;
1087 if (Extra == 0 && SwapFirst) {
1088 cmsFloat32Number tmp = wIn[0];
1090 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number));
1094 if (T_PLANAR(info -> InputFormat))
1095 return accum + sizeof(cmsFloat32Number);
1097 return accum + (nChan + Extra) * sizeof(cmsFloat32Number);
1100 // For anything going from double
1103 cmsUInt8Number* UnrollDoublesToFloat(_cmsTRANSFORM* info,
1104 cmsFloat32Number wIn[],
1105 cmsUInt8Number* accum,
1106 cmsUInt32Number Stride)
1109 int nChan = T_CHANNELS(info -> InputFormat);
1110 int DoSwap = T_DOSWAP(info ->InputFormat);
1111 int Reverse = T_FLAVOR(info ->InputFormat);
1112 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
1113 int Extra = T_EXTRA(info -> InputFormat);
1114 int ExtraFirst = DoSwap ^ SwapFirst;
1115 int Planar = T_PLANAR(info -> InputFormat);
1118 cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 100.0 : 1.0;
1124 for (i=0; i < nChan; i++) {
1126 int index = DoSwap ? (nChan - i - 1) : i;
1129 v = (cmsFloat64Number) ((cmsFloat64Number*) accum)[(i + start) * Stride];
1131 v = (cmsFloat64Number) ((cmsFloat64Number*) accum)[i + start];
1135 wIn[index] = (cmsFloat32Number) (Reverse ? 1.0 - v : v);
1139 if (Extra == 0 && SwapFirst) {
1140 cmsFloat32Number tmp = wIn[0];
1142 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number));
1146 if (T_PLANAR(info -> InputFormat))
1147 return accum + sizeof(cmsFloat64Number);
1149 return accum + (nChan + Extra) * sizeof(cmsFloat64Number);
1154 // From Lab double to cmsFloat32Number
1156 cmsUInt8Number* UnrollLabDoubleToFloat(_cmsTRANSFORM* info,
1157 cmsFloat32Number wIn[],
1158 cmsUInt8Number* accum,
1159 cmsUInt32Number Stride)
1161 cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
1163 if (T_PLANAR(info -> InputFormat)) {
1165 wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
1166 wIn[1] = (cmsFloat32Number) ((Pt[Stride] + 128) / 255.0); // form -128..+127 to 0..1
1167 wIn[2] = (cmsFloat32Number) ((Pt[Stride*2] + 128) / 255.0);
1169 return accum + sizeof(cmsFloat64Number);
1173 wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
1174 wIn[1] = (cmsFloat32Number) ((Pt[1] + 128) / 255.0); // form -128..+127 to 0..1
1175 wIn[2] = (cmsFloat32Number) ((Pt[2] + 128) / 255.0);
1177 accum += sizeof(cmsFloat64Number)*(3 + T_EXTRA(info ->InputFormat));
1182 // From Lab double to cmsFloat32Number
1184 cmsUInt8Number* UnrollLabFloatToFloat(_cmsTRANSFORM* info,
1185 cmsFloat32Number wIn[],
1186 cmsUInt8Number* accum,
1187 cmsUInt32Number Stride)
1189 cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
1191 if (T_PLANAR(info -> InputFormat)) {
1193 wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
1194 wIn[1] = (cmsFloat32Number) ((Pt[Stride] + 128) / 255.0); // form -128..+127 to 0..1
1195 wIn[2] = (cmsFloat32Number) ((Pt[Stride*2] + 128) / 255.0);
1197 return accum + sizeof(cmsFloat32Number);
1201 wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
1202 wIn[1] = (cmsFloat32Number) ((Pt[1] + 128) / 255.0); // form -128..+127 to 0..1
1203 wIn[2] = (cmsFloat32Number) ((Pt[2] + 128) / 255.0);
1205 accum += sizeof(cmsFloat32Number)*(3 + T_EXTRA(info ->InputFormat));
1212 // 1.15 fixed point, that means maximum value is MAX_ENCODEABLE_XYZ (0xFFFF)
1214 cmsUInt8Number* UnrollXYZDoubleToFloat(_cmsTRANSFORM* info,
1215 cmsFloat32Number wIn[],
1216 cmsUInt8Number* accum,
1217 cmsUInt32Number Stride)
1219 cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
1221 if (T_PLANAR(info -> InputFormat)) {
1223 wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
1224 wIn[1] = (cmsFloat32Number) (Pt[Stride] / MAX_ENCODEABLE_XYZ);
1225 wIn[2] = (cmsFloat32Number) (Pt[Stride*2] / MAX_ENCODEABLE_XYZ);
1227 return accum + sizeof(cmsFloat64Number);
1231 wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
1232 wIn[1] = (cmsFloat32Number) (Pt[1] / MAX_ENCODEABLE_XYZ);
1233 wIn[2] = (cmsFloat32Number) (Pt[2] / MAX_ENCODEABLE_XYZ);
1235 accum += sizeof(cmsFloat64Number)*(3 + T_EXTRA(info ->InputFormat));
1241 cmsUInt8Number* UnrollXYZFloatToFloat(_cmsTRANSFORM* info,
1242 cmsFloat32Number wIn[],
1243 cmsUInt8Number* accum,
1244 cmsUInt32Number Stride)
1246 cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
1248 if (T_PLANAR(info -> InputFormat)) {
1250 wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
1251 wIn[1] = (cmsFloat32Number) (Pt[Stride] / MAX_ENCODEABLE_XYZ);
1252 wIn[2] = (cmsFloat32Number) (Pt[Stride*2] / MAX_ENCODEABLE_XYZ);
1254 return accum + sizeof(cmsFloat32Number);
1258 wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
1259 wIn[1] = (cmsFloat32Number) (Pt[1] / MAX_ENCODEABLE_XYZ);
1260 wIn[2] = (cmsFloat32Number) (Pt[2] / MAX_ENCODEABLE_XYZ);
1262 accum += sizeof(cmsFloat32Number)*(3 + T_EXTRA(info ->InputFormat));
1269 // Packing routines -----------------------------------------------------------------------------------------------------------
1272 // Generic chunky for byte
1275 cmsUInt8Number* PackAnyBytes(register _cmsTRANSFORM* info,
1276 register cmsUInt16Number wOut[],
1277 register cmsUInt8Number* output,
1278 register cmsUInt32Number Stride)
1280 int nChan = T_CHANNELS(info -> OutputFormat);
1281 int DoSwap = T_DOSWAP(info ->OutputFormat);
1282 int Reverse = T_FLAVOR(info ->OutputFormat);
1283 int Extra = T_EXTRA(info -> OutputFormat);
1284 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
1285 int ExtraFirst = DoSwap ^ SwapFirst;
1286 cmsUInt8Number* swap1;
1287 cmsUInt8Number v = 0;
1296 for (i=0; i < nChan; i++) {
1298 int index = DoSwap ? (nChan - i - 1) : i;
1300 v = FROM_16_TO_8(wOut[index]);
1303 v = REVERSE_FLAVOR_8(v);
1312 if (Extra == 0 && SwapFirst) {
1314 memmove(swap1 + 1, swap1, nChan-1);
1321 cmsUNUSED_PARAMETER(Stride);
1327 cmsUInt8Number* PackAnyWords(register _cmsTRANSFORM* info,
1328 register cmsUInt16Number wOut[],
1329 register cmsUInt8Number* output,
1330 register cmsUInt32Number Stride)
1332 int nChan = T_CHANNELS(info -> OutputFormat);
1333 int SwapEndian = T_ENDIAN16(info -> InputFormat);
1334 int DoSwap = T_DOSWAP(info ->OutputFormat);
1335 int Reverse = T_FLAVOR(info ->OutputFormat);
1336 int Extra = T_EXTRA(info -> OutputFormat);
1337 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
1338 int ExtraFirst = DoSwap ^ SwapFirst;
1339 cmsUInt16Number* swap1;
1340 cmsUInt16Number v = 0;
1343 swap1 = (cmsUInt16Number*) output;
1346 output += Extra * sizeof(cmsUInt16Number);
1349 for (i=0; i < nChan; i++) {
1351 int index = DoSwap ? (nChan - i - 1) : i;
1356 v = CHANGE_ENDIAN(v);
1359 v = REVERSE_FLAVOR_16(v);
1361 *(cmsUInt16Number*) output = v;
1363 output += sizeof(cmsUInt16Number);
1367 output += Extra * sizeof(cmsUInt16Number);
1370 if (Extra == 0 && SwapFirst) {
1372 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number));
1379 cmsUNUSED_PARAMETER(Stride);
1384 cmsUInt8Number* PackPlanarBytes(register _cmsTRANSFORM* info,
1385 register cmsUInt16Number wOut[],
1386 register cmsUInt8Number* output,
1387 register cmsUInt32Number Stride)
1389 int nChan = T_CHANNELS(info -> OutputFormat);
1390 int DoSwap = T_DOSWAP(info ->OutputFormat);
1391 int SwapFirst = T_SWAPFIRST(info ->OutputFormat);
1392 int Reverse = T_FLAVOR(info ->OutputFormat);
1394 cmsUInt8Number* Init = output;
1397 if (DoSwap ^ SwapFirst) {
1398 output += T_EXTRA(info -> OutputFormat) * Stride;
1402 for (i=0; i < nChan; i++) {
1404 int index = DoSwap ? (nChan - i - 1) : i;
1405 cmsUInt8Number v = FROM_16_TO_8(wOut[index]);
1407 *(cmsUInt8Number*) output = (cmsUInt8Number) (Reverse ? REVERSE_FLAVOR_8(v) : v);
1413 cmsUNUSED_PARAMETER(Stride);
1418 cmsUInt8Number* PackPlanarWords(register _cmsTRANSFORM* info,
1419 register cmsUInt16Number wOut[],
1420 register cmsUInt8Number* output,
1421 register cmsUInt32Number Stride)
1423 int nChan = T_CHANNELS(info -> OutputFormat);
1424 int DoSwap = T_DOSWAP(info ->OutputFormat);
1425 int Reverse= T_FLAVOR(info ->OutputFormat);
1426 int SwapEndian = T_ENDIAN16(info -> OutputFormat);
1428 cmsUInt8Number* Init = output;
1432 output += T_EXTRA(info -> OutputFormat) * Stride * sizeof(cmsUInt16Number);
1435 for (i=0; i < nChan; i++) {
1437 int index = DoSwap ? (nChan - i - 1) : i;
1442 v = CHANGE_ENDIAN(v);
1445 v = REVERSE_FLAVOR_16(v);
1447 *(cmsUInt16Number*) output = v;
1448 output += (Stride * sizeof(cmsUInt16Number));
1451 return (Init + sizeof(cmsUInt16Number));
1454 // CMYKcm (unrolled for speed)
1457 cmsUInt8Number* Pack6Bytes(register _cmsTRANSFORM* info,
1458 register cmsUInt16Number wOut[],
1459 register cmsUInt8Number* output,
1460 register cmsUInt32Number Stride)
1462 *output++ = FROM_16_TO_8(wOut[0]);
1463 *output++ = FROM_16_TO_8(wOut[1]);
1464 *output++ = FROM_16_TO_8(wOut[2]);
1465 *output++ = FROM_16_TO_8(wOut[3]);
1466 *output++ = FROM_16_TO_8(wOut[4]);
1467 *output++ = FROM_16_TO_8(wOut[5]);
1471 cmsUNUSED_PARAMETER(info);
1472 cmsUNUSED_PARAMETER(Stride);
1478 cmsUInt8Number* Pack6BytesSwap(register _cmsTRANSFORM* info,
1479 register cmsUInt16Number wOut[],
1480 register cmsUInt8Number* output,
1481 register cmsUInt32Number Stride)
1483 *output++ = FROM_16_TO_8(wOut[5]);
1484 *output++ = FROM_16_TO_8(wOut[4]);
1485 *output++ = FROM_16_TO_8(wOut[3]);
1486 *output++ = FROM_16_TO_8(wOut[2]);
1487 *output++ = FROM_16_TO_8(wOut[1]);
1488 *output++ = FROM_16_TO_8(wOut[0]);
1492 cmsUNUSED_PARAMETER(info);
1493 cmsUNUSED_PARAMETER(Stride);
1498 cmsUInt8Number* Pack6Words(register _cmsTRANSFORM* info,
1499 register cmsUInt16Number wOut[],
1500 register cmsUInt8Number* output,
1501 register cmsUInt32Number Stride)
1503 *(cmsUInt16Number*) output = wOut[0];
1505 *(cmsUInt16Number*) output = wOut[1];
1507 *(cmsUInt16Number*) output = wOut[2];
1509 *(cmsUInt16Number*) output = wOut[3];
1511 *(cmsUInt16Number*) output = wOut[4];
1513 *(cmsUInt16Number*) output = wOut[5];
1518 cmsUNUSED_PARAMETER(info);
1519 cmsUNUSED_PARAMETER(Stride);
1524 cmsUInt8Number* Pack6WordsSwap(register _cmsTRANSFORM* info,
1525 register cmsUInt16Number wOut[],
1526 register cmsUInt8Number* output,
1527 register cmsUInt32Number Stride)
1529 *(cmsUInt16Number*) output = wOut[5];
1531 *(cmsUInt16Number*) output = wOut[4];
1533 *(cmsUInt16Number*) output = wOut[3];
1535 *(cmsUInt16Number*) output = wOut[2];
1537 *(cmsUInt16Number*) output = wOut[1];
1539 *(cmsUInt16Number*) output = wOut[0];
1544 cmsUNUSED_PARAMETER(info);
1545 cmsUNUSED_PARAMETER(Stride);
1550 cmsUInt8Number* Pack4Bytes(register _cmsTRANSFORM* info,
1551 register cmsUInt16Number wOut[],
1552 register cmsUInt8Number* output,
1553 register cmsUInt32Number Stride)
1555 *output++ = FROM_16_TO_8(wOut[0]);
1556 *output++ = FROM_16_TO_8(wOut[1]);
1557 *output++ = FROM_16_TO_8(wOut[2]);
1558 *output++ = FROM_16_TO_8(wOut[3]);
1562 cmsUNUSED_PARAMETER(info);
1563 cmsUNUSED_PARAMETER(Stride);
1567 cmsUInt8Number* Pack4BytesReverse(register _cmsTRANSFORM* info,
1568 register cmsUInt16Number wOut[],
1569 register cmsUInt8Number* output,
1570 register cmsUInt32Number Stride)
1572 *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[0]));
1573 *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[1]));
1574 *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[2]));
1575 *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[3]));
1579 cmsUNUSED_PARAMETER(info);
1580 cmsUNUSED_PARAMETER(Stride);
1585 cmsUInt8Number* Pack4BytesSwapFirst(register _cmsTRANSFORM* info,
1586 register cmsUInt16Number wOut[],
1587 register cmsUInt8Number* output,
1588 register cmsUInt32Number Stride)
1590 *output++ = FROM_16_TO_8(wOut[3]);
1591 *output++ = FROM_16_TO_8(wOut[0]);
1592 *output++ = FROM_16_TO_8(wOut[1]);
1593 *output++ = FROM_16_TO_8(wOut[2]);
1597 cmsUNUSED_PARAMETER(info);
1598 cmsUNUSED_PARAMETER(Stride);
1603 cmsUInt8Number* Pack4BytesSwap(register _cmsTRANSFORM* info,
1604 register cmsUInt16Number wOut[],
1605 register cmsUInt8Number* output,
1606 register cmsUInt32Number Stride)
1608 *output++ = FROM_16_TO_8(wOut[3]);
1609 *output++ = FROM_16_TO_8(wOut[2]);
1610 *output++ = FROM_16_TO_8(wOut[1]);
1611 *output++ = FROM_16_TO_8(wOut[0]);
1615 cmsUNUSED_PARAMETER(info);
1616 cmsUNUSED_PARAMETER(Stride);
1620 cmsUInt8Number* Pack4BytesSwapSwapFirst(register _cmsTRANSFORM* info,
1621 register cmsUInt16Number wOut[],
1622 register cmsUInt8Number* output,
1623 register cmsUInt32Number Stride)
1625 *output++ = FROM_16_TO_8(wOut[2]);
1626 *output++ = FROM_16_TO_8(wOut[1]);
1627 *output++ = FROM_16_TO_8(wOut[0]);
1628 *output++ = FROM_16_TO_8(wOut[3]);
1632 cmsUNUSED_PARAMETER(info);
1633 cmsUNUSED_PARAMETER(Stride);
1637 cmsUInt8Number* Pack4Words(register _cmsTRANSFORM* info,
1638 register cmsUInt16Number wOut[],
1639 register cmsUInt8Number* output,
1640 register cmsUInt32Number Stride)
1642 *(cmsUInt16Number*) output = wOut[0];
1644 *(cmsUInt16Number*) output = wOut[1];
1646 *(cmsUInt16Number*) output = wOut[2];
1648 *(cmsUInt16Number*) output = wOut[3];
1653 cmsUNUSED_PARAMETER(info);
1654 cmsUNUSED_PARAMETER(Stride);
1658 cmsUInt8Number* Pack4WordsReverse(register _cmsTRANSFORM* info,
1659 register cmsUInt16Number wOut[],
1660 register cmsUInt8Number* output,
1661 register cmsUInt32Number Stride)
1663 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[0]);
1665 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[1]);
1667 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[2]);
1669 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[3]);
1674 cmsUNUSED_PARAMETER(info);
1675 cmsUNUSED_PARAMETER(Stride);
1680 cmsUInt8Number* Pack4WordsSwap(register _cmsTRANSFORM* info,
1681 register cmsUInt16Number wOut[],
1682 register cmsUInt8Number* output,
1683 register cmsUInt32Number Stride)
1685 *(cmsUInt16Number*) output = wOut[3];
1687 *(cmsUInt16Number*) output = wOut[2];
1689 *(cmsUInt16Number*) output = wOut[1];
1691 *(cmsUInt16Number*) output = wOut[0];
1696 cmsUNUSED_PARAMETER(info);
1697 cmsUNUSED_PARAMETER(Stride);
1702 cmsUInt8Number* Pack4WordsBigEndian(register _cmsTRANSFORM* info,
1703 register cmsUInt16Number wOut[],
1704 register cmsUInt8Number* output,
1705 register cmsUInt32Number Stride)
1707 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
1709 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[1]);
1711 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[2]);
1713 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[3]);
1718 cmsUNUSED_PARAMETER(info);
1719 cmsUNUSED_PARAMETER(Stride);
1724 cmsUInt8Number* PackLabV2_8(register _cmsTRANSFORM* info,
1725 register cmsUInt16Number wOut[],
1726 register cmsUInt8Number* output,
1727 register cmsUInt32Number Stride)
1729 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[0]));
1730 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[1]));
1731 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[2]));
1735 cmsUNUSED_PARAMETER(info);
1736 cmsUNUSED_PARAMETER(Stride);
1740 cmsUInt8Number* PackALabV2_8(register _cmsTRANSFORM* info,
1741 register cmsUInt16Number wOut[],
1742 register cmsUInt8Number* output,
1743 register cmsUInt32Number Stride)
1746 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[0]));
1747 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[1]));
1748 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[2]));
1752 cmsUNUSED_PARAMETER(info);
1753 cmsUNUSED_PARAMETER(Stride);
1757 cmsUInt8Number* PackLabV2_16(register _cmsTRANSFORM* info,
1758 register cmsUInt16Number wOut[],
1759 register cmsUInt8Number* output,
1760 register cmsUInt32Number Stride)
1762 *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[0]);
1764 *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[1]);
1766 *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[2]);
1771 cmsUNUSED_PARAMETER(info);
1772 cmsUNUSED_PARAMETER(Stride);
1776 cmsUInt8Number* Pack3Bytes(register _cmsTRANSFORM* info,
1777 register cmsUInt16Number wOut[],
1778 register cmsUInt8Number* output,
1779 register cmsUInt32Number Stride)
1781 *output++ = FROM_16_TO_8(wOut[0]);
1782 *output++ = FROM_16_TO_8(wOut[1]);
1783 *output++ = FROM_16_TO_8(wOut[2]);
1787 cmsUNUSED_PARAMETER(info);
1788 cmsUNUSED_PARAMETER(Stride);
1792 cmsUInt8Number* Pack3BytesOptimized(register _cmsTRANSFORM* info,
1793 register cmsUInt16Number wOut[],
1794 register cmsUInt8Number* output,
1795 register cmsUInt32Number Stride)
1797 *output++ = (wOut[0] & 0xFF);
1798 *output++ = (wOut[1] & 0xFF);
1799 *output++ = (wOut[2] & 0xFF);
1803 cmsUNUSED_PARAMETER(info);
1804 cmsUNUSED_PARAMETER(Stride);
1808 cmsUInt8Number* Pack3BytesSwap(register _cmsTRANSFORM* info,
1809 register cmsUInt16Number wOut[],
1810 register cmsUInt8Number* output,
1811 register cmsUInt32Number Stride)
1813 *output++ = FROM_16_TO_8(wOut[2]);
1814 *output++ = FROM_16_TO_8(wOut[1]);
1815 *output++ = FROM_16_TO_8(wOut[0]);
1819 cmsUNUSED_PARAMETER(info);
1820 cmsUNUSED_PARAMETER(Stride);
1824 cmsUInt8Number* Pack3BytesSwapOptimized(register _cmsTRANSFORM* info,
1825 register cmsUInt16Number wOut[],
1826 register cmsUInt8Number* output,
1827 register cmsUInt32Number Stride)
1829 *output++ = (wOut[2] & 0xFF);
1830 *output++ = (wOut[1] & 0xFF);
1831 *output++ = (wOut[0] & 0xFF);
1835 cmsUNUSED_PARAMETER(info);
1836 cmsUNUSED_PARAMETER(Stride);
1841 cmsUInt8Number* Pack3Words(register _cmsTRANSFORM* info,
1842 register cmsUInt16Number wOut[],
1843 register cmsUInt8Number* output,
1844 register cmsUInt32Number Stride)
1846 *(cmsUInt16Number*) output = wOut[0];
1848 *(cmsUInt16Number*) output = wOut[1];
1850 *(cmsUInt16Number*) output = wOut[2];
1855 cmsUNUSED_PARAMETER(info);
1856 cmsUNUSED_PARAMETER(Stride);
1860 cmsUInt8Number* Pack3WordsSwap(register _cmsTRANSFORM* info,
1861 register cmsUInt16Number wOut[],
1862 register cmsUInt8Number* output,
1863 register cmsUInt32Number Stride)
1865 *(cmsUInt16Number*) output = wOut[2];
1867 *(cmsUInt16Number*) output = wOut[1];
1869 *(cmsUInt16Number*) output = wOut[0];
1874 cmsUNUSED_PARAMETER(info);
1875 cmsUNUSED_PARAMETER(Stride);
1879 cmsUInt8Number* Pack3WordsBigEndian(register _cmsTRANSFORM* info,
1880 register cmsUInt16Number wOut[],
1881 register cmsUInt8Number* output,
1882 register cmsUInt32Number Stride)
1884 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
1886 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[1]);
1888 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[2]);
1893 cmsUNUSED_PARAMETER(info);
1894 cmsUNUSED_PARAMETER(Stride);
1898 cmsUInt8Number* Pack3BytesAndSkip1(register _cmsTRANSFORM* info,
1899 register cmsUInt16Number wOut[],
1900 register cmsUInt8Number* output,
1901 register cmsUInt32Number Stride)
1903 *output++ = FROM_16_TO_8(wOut[0]);
1904 *output++ = FROM_16_TO_8(wOut[1]);
1905 *output++ = FROM_16_TO_8(wOut[2]);
1910 cmsUNUSED_PARAMETER(info);
1911 cmsUNUSED_PARAMETER(Stride);
1915 cmsUInt8Number* Pack3BytesAndSkip1Optimized(register _cmsTRANSFORM* info,
1916 register cmsUInt16Number wOut[],
1917 register cmsUInt8Number* output,
1918 register cmsUInt32Number Stride)
1920 *output++ = (wOut[0] & 0xFF);
1921 *output++ = (wOut[1] & 0xFF);
1922 *output++ = (wOut[2] & 0xFF);
1927 cmsUNUSED_PARAMETER(info);
1928 cmsUNUSED_PARAMETER(Stride);
1933 cmsUInt8Number* Pack3BytesAndSkip1SwapFirst(register _cmsTRANSFORM* info,
1934 register cmsUInt16Number wOut[],
1935 register cmsUInt8Number* output,
1936 register cmsUInt32Number Stride)
1939 *output++ = FROM_16_TO_8(wOut[0]);
1940 *output++ = FROM_16_TO_8(wOut[1]);
1941 *output++ = FROM_16_TO_8(wOut[2]);
1945 cmsUNUSED_PARAMETER(info);
1946 cmsUNUSED_PARAMETER(Stride);
1950 cmsUInt8Number* Pack3BytesAndSkip1SwapFirstOptimized(register _cmsTRANSFORM* info,
1951 register cmsUInt16Number wOut[],
1952 register cmsUInt8Number* output,
1953 register cmsUInt32Number Stride)
1956 *output++ = (wOut[0] & 0xFF);
1957 *output++ = (wOut[1] & 0xFF);
1958 *output++ = (wOut[2] & 0xFF);
1962 cmsUNUSED_PARAMETER(info);
1963 cmsUNUSED_PARAMETER(Stride);
1967 cmsUInt8Number* Pack3BytesAndSkip1Swap(register _cmsTRANSFORM* info,
1968 register cmsUInt16Number wOut[],
1969 register cmsUInt8Number* output,
1970 register cmsUInt32Number Stride)
1973 *output++ = FROM_16_TO_8(wOut[2]);
1974 *output++ = FROM_16_TO_8(wOut[1]);
1975 *output++ = FROM_16_TO_8(wOut[0]);
1979 cmsUNUSED_PARAMETER(info);
1980 cmsUNUSED_PARAMETER(Stride);
1984 cmsUInt8Number* Pack3BytesAndSkip1SwapOptimized(register _cmsTRANSFORM* info,
1985 register cmsUInt16Number wOut[],
1986 register cmsUInt8Number* output,
1987 register cmsUInt32Number Stride)
1990 *output++ = (wOut[2] & 0xFF);
1991 *output++ = (wOut[1] & 0xFF);
1992 *output++ = (wOut[0] & 0xFF);
1996 cmsUNUSED_PARAMETER(info);
1997 cmsUNUSED_PARAMETER(Stride);
2002 cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirst(register _cmsTRANSFORM* info,
2003 register cmsUInt16Number wOut[],
2004 register cmsUInt8Number* output,
2005 register cmsUInt32Number Stride)
2007 *output++ = FROM_16_TO_8(wOut[2]);
2008 *output++ = FROM_16_TO_8(wOut[1]);
2009 *output++ = FROM_16_TO_8(wOut[0]);
2014 cmsUNUSED_PARAMETER(info);
2015 cmsUNUSED_PARAMETER(Stride);
2019 cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirstOptimized(register _cmsTRANSFORM* info,
2020 register cmsUInt16Number wOut[],
2021 register cmsUInt8Number* output,
2022 register cmsUInt32Number Stride)
2024 *output++ = (wOut[2] & 0xFF);
2025 *output++ = (wOut[1] & 0xFF);
2026 *output++ = (wOut[0] & 0xFF);
2031 cmsUNUSED_PARAMETER(info);
2032 cmsUNUSED_PARAMETER(Stride);
2036 cmsUInt8Number* Pack3WordsAndSkip1(register _cmsTRANSFORM* info,
2037 register cmsUInt16Number wOut[],
2038 register cmsUInt8Number* output,
2039 register cmsUInt32Number Stride)
2041 *(cmsUInt16Number*) output = wOut[0];
2043 *(cmsUInt16Number*) output = wOut[1];
2045 *(cmsUInt16Number*) output = wOut[2];
2051 cmsUNUSED_PARAMETER(info);
2052 cmsUNUSED_PARAMETER(Stride);
2056 cmsUInt8Number* Pack3WordsAndSkip1Swap(register _cmsTRANSFORM* info,
2057 register cmsUInt16Number wOut[],
2058 register cmsUInt8Number* output,
2059 register cmsUInt32Number Stride)
2062 *(cmsUInt16Number*) output = wOut[2];
2064 *(cmsUInt16Number*) output = wOut[1];
2066 *(cmsUInt16Number*) output = wOut[0];
2071 cmsUNUSED_PARAMETER(info);
2072 cmsUNUSED_PARAMETER(Stride);
2077 cmsUInt8Number* Pack3WordsAndSkip1SwapFirst(register _cmsTRANSFORM* info,
2078 register cmsUInt16Number wOut[],
2079 register cmsUInt8Number* output,
2080 register cmsUInt32Number Stride)
2083 *(cmsUInt16Number*) output = wOut[0];
2085 *(cmsUInt16Number*) output = wOut[1];
2087 *(cmsUInt16Number*) output = wOut[2];
2092 cmsUNUSED_PARAMETER(info);
2093 cmsUNUSED_PARAMETER(Stride);
2098 cmsUInt8Number* Pack3WordsAndSkip1SwapSwapFirst(register _cmsTRANSFORM* info,
2099 register cmsUInt16Number wOut[],
2100 register cmsUInt8Number* output,
2101 register cmsUInt32Number Stride)
2103 *(cmsUInt16Number*) output = wOut[2];
2105 *(cmsUInt16Number*) output = wOut[1];
2107 *(cmsUInt16Number*) output = wOut[0];
2113 cmsUNUSED_PARAMETER(info);
2114 cmsUNUSED_PARAMETER(Stride);
2120 cmsUInt8Number* Pack1Byte(register _cmsTRANSFORM* info,
2121 register cmsUInt16Number wOut[],
2122 register cmsUInt8Number* output,
2123 register cmsUInt32Number Stride)
2125 *output++ = FROM_16_TO_8(wOut[0]);
2129 cmsUNUSED_PARAMETER(info);
2130 cmsUNUSED_PARAMETER(Stride);
2135 cmsUInt8Number* Pack1ByteReversed(register _cmsTRANSFORM* info,
2136 register cmsUInt16Number wOut[],
2137 register cmsUInt8Number* output,
2138 register cmsUInt32Number Stride)
2140 *output++ = FROM_16_TO_8(REVERSE_FLAVOR_16(wOut[0]));
2144 cmsUNUSED_PARAMETER(info);
2145 cmsUNUSED_PARAMETER(Stride);
2150 cmsUInt8Number* Pack1ByteSkip1(register _cmsTRANSFORM* info,
2151 register cmsUInt16Number wOut[],
2152 register cmsUInt8Number* output,
2153 register cmsUInt32Number Stride)
2155 *output++ = FROM_16_TO_8(wOut[0]);
2160 cmsUNUSED_PARAMETER(info);
2161 cmsUNUSED_PARAMETER(Stride);
2166 cmsUInt8Number* Pack1ByteSkip1SwapFirst(register _cmsTRANSFORM* info,
2167 register cmsUInt16Number wOut[],
2168 register cmsUInt8Number* output,
2169 register cmsUInt32Number Stride)
2172 *output++ = FROM_16_TO_8(wOut[0]);
2176 cmsUNUSED_PARAMETER(info);
2177 cmsUNUSED_PARAMETER(Stride);
2181 cmsUInt8Number* Pack1Word(register _cmsTRANSFORM* info,
2182 register cmsUInt16Number wOut[],
2183 register cmsUInt8Number* output,
2184 register cmsUInt32Number Stride)
2186 *(cmsUInt16Number*) output = wOut[0];
2191 cmsUNUSED_PARAMETER(info);
2192 cmsUNUSED_PARAMETER(Stride);
2197 cmsUInt8Number* Pack1WordReversed(register _cmsTRANSFORM* info,
2198 register cmsUInt16Number wOut[],
2199 register cmsUInt8Number* output,
2200 register cmsUInt32Number Stride)
2202 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[0]);
2207 cmsUNUSED_PARAMETER(info);
2208 cmsUNUSED_PARAMETER(Stride);
2212 cmsUInt8Number* Pack1WordBigEndian(register _cmsTRANSFORM* info,
2213 register cmsUInt16Number wOut[],
2214 register cmsUInt8Number* output,
2215 register cmsUInt32Number Stride)
2217 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
2222 cmsUNUSED_PARAMETER(info);
2223 cmsUNUSED_PARAMETER(Stride);
2228 cmsUInt8Number* Pack1WordSkip1(register _cmsTRANSFORM* info,
2229 register cmsUInt16Number wOut[],
2230 register cmsUInt8Number* output,
2231 register cmsUInt32Number Stride)
2233 *(cmsUInt16Number*) output = wOut[0];
2238 cmsUNUSED_PARAMETER(info);
2239 cmsUNUSED_PARAMETER(Stride);
2243 cmsUInt8Number* Pack1WordSkip1SwapFirst(register _cmsTRANSFORM* info,
2244 register cmsUInt16Number wOut[],
2245 register cmsUInt8Number* output,
2246 register cmsUInt32Number Stride)
2249 *(cmsUInt16Number*) output = wOut[0];
2254 cmsUNUSED_PARAMETER(info);
2255 cmsUNUSED_PARAMETER(Stride);
2259 // Unencoded Float values -- don't try optimize speed
2261 cmsUInt8Number* PackLabDoubleFrom16(register _cmsTRANSFORM* info,
2262 register cmsUInt16Number wOut[],
2263 register cmsUInt8Number* output,
2264 register cmsUInt32Number Stride)
2267 if (T_PLANAR(info -> OutputFormat)) {
2270 cmsFloat64Number* Out = (cmsFloat64Number*) output;
2271 cmsLabEncoded2Float(&Lab, wOut);
2274 Out[Stride] = Lab.a;
2275 Out[Stride*2] = Lab.b;
2277 return output + sizeof(cmsFloat64Number);
2281 cmsLabEncoded2Float((cmsCIELab*) output, wOut);
2282 return output + (sizeof(cmsCIELab) + T_EXTRA(info ->OutputFormat) * sizeof(cmsFloat64Number));
2288 cmsUInt8Number* PackLabFloatFrom16(register _cmsTRANSFORM* info,
2289 register cmsUInt16Number wOut[],
2290 register cmsUInt8Number* output,
2291 register cmsUInt32Number Stride)
2294 cmsLabEncoded2Float(&Lab, wOut);
2296 if (T_PLANAR(info -> OutputFormat)) {
2298 cmsFloat32Number* Out = (cmsFloat32Number*) output;
2300 Out[0] = (cmsFloat32Number)Lab.L;
2301 Out[Stride] = (cmsFloat32Number)Lab.a;
2302 Out[Stride*2] = (cmsFloat32Number)Lab.b;
2304 return output + sizeof(cmsFloat32Number);
2308 ((cmsFloat32Number*) output)[0] = (cmsFloat32Number) Lab.L;
2309 ((cmsFloat32Number*) output)[1] = (cmsFloat32Number) Lab.a;
2310 ((cmsFloat32Number*) output)[2] = (cmsFloat32Number) Lab.b;
2312 return output + (3 + T_EXTRA(info ->OutputFormat)) * sizeof(cmsFloat32Number);
2317 cmsUInt8Number* PackXYZDoubleFrom16(register _cmsTRANSFORM* Info,
2318 register cmsUInt16Number wOut[],
2319 register cmsUInt8Number* output,
2320 register cmsUInt32Number Stride)
2322 if (T_PLANAR(Info -> OutputFormat)) {
2325 cmsFloat64Number* Out = (cmsFloat64Number*) output;
2326 cmsXYZEncoded2Float(&XYZ, wOut);
2329 Out[Stride] = XYZ.Y;
2330 Out[Stride*2] = XYZ.Z;
2332 return output + sizeof(cmsFloat64Number);
2337 cmsXYZEncoded2Float((cmsCIEXYZ*) output, wOut);
2339 return output + (sizeof(cmsCIEXYZ) + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
2344 cmsUInt8Number* PackXYZFloatFrom16(register _cmsTRANSFORM* Info,
2345 register cmsUInt16Number wOut[],
2346 register cmsUInt8Number* output,
2347 register cmsUInt32Number Stride)
2349 if (T_PLANAR(Info -> OutputFormat)) {
2352 cmsFloat32Number* Out = (cmsFloat32Number*) output;
2353 cmsXYZEncoded2Float(&XYZ, wOut);
2355 Out[0] = (cmsFloat32Number) XYZ.X;
2356 Out[Stride] = (cmsFloat32Number) XYZ.Y;
2357 Out[Stride*2] = (cmsFloat32Number) XYZ.Z;
2359 return output + sizeof(cmsFloat32Number);
2365 cmsFloat32Number* Out = (cmsFloat32Number*) output;
2366 cmsXYZEncoded2Float(&XYZ, wOut);
2368 Out[0] = (cmsFloat32Number) XYZ.X;
2369 Out[1] = (cmsFloat32Number) XYZ.Y;
2370 Out[2] = (cmsFloat32Number) XYZ.Z;
2372 return output + (3 * sizeof(cmsFloat32Number) + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
2377 cmsUInt8Number* PackDoubleFrom16(register _cmsTRANSFORM* info,
2378 register cmsUInt16Number wOut[],
2379 register cmsUInt8Number* output,
2380 register cmsUInt32Number Stride)
2382 int nChan = T_CHANNELS(info -> OutputFormat);
2383 int DoSwap = T_DOSWAP(info ->OutputFormat);
2384 int Reverse = T_FLAVOR(info ->OutputFormat);
2385 int Extra = T_EXTRA(info -> OutputFormat);
2386 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2387 int Planar = T_PLANAR(info -> OutputFormat);
2388 int ExtraFirst = DoSwap ^ SwapFirst;
2389 cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35 : 65535.0;
2390 cmsFloat64Number v = 0;
2391 cmsFloat64Number* swap1 = (cmsFloat64Number*) output;
2397 for (i=0; i < nChan; i++) {
2399 int index = DoSwap ? (nChan - i - 1) : i;
2401 v = (cmsFloat64Number) wOut[index] / maximum;
2407 ((cmsFloat64Number*) output)[(i + start) * Stride]= v;
2409 ((cmsFloat64Number*) output)[i + start] = v;
2413 output += Extra * sizeof(cmsFloat64Number);
2416 if (Extra == 0 && SwapFirst) {
2418 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat64Number));
2422 if (T_PLANAR(info -> OutputFormat))
2423 return output + sizeof(cmsFloat64Number);
2425 return output + nChan * sizeof(cmsFloat64Number);
2431 cmsUInt8Number* PackFloatFrom16(register _cmsTRANSFORM* info,
2432 register cmsUInt16Number wOut[],
2433 register cmsUInt8Number* output,
2434 register cmsUInt32Number Stride)
2436 int nChan = T_CHANNELS(info -> OutputFormat);
2437 int DoSwap = T_DOSWAP(info ->OutputFormat);
2438 int Reverse = T_FLAVOR(info ->OutputFormat);
2439 int Extra = T_EXTRA(info -> OutputFormat);
2440 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2441 int Planar = T_PLANAR(info -> OutputFormat);
2442 int ExtraFirst = DoSwap ^ SwapFirst;
2443 cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35 : 65535.0;
2444 cmsFloat64Number v = 0;
2445 cmsFloat32Number* swap1 = (cmsFloat32Number*) output;
2451 for (i=0; i < nChan; i++) {
2453 int index = DoSwap ? (nChan - i - 1) : i;
2455 v = (cmsFloat64Number) wOut[index] / maximum;
2461 ((cmsFloat32Number*) output)[(i + start ) * Stride]= (cmsFloat32Number) v;
2463 ((cmsFloat32Number*) output)[i + start] = (cmsFloat32Number) v;
2467 output += Extra * sizeof(cmsFloat32Number);
2470 if (Extra == 0 && SwapFirst) {
2472 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat32Number));
2473 *swap1 = (cmsFloat32Number) v;
2476 if (T_PLANAR(info -> OutputFormat))
2477 return output + sizeof(cmsFloat32Number);
2479 return output + nChan * sizeof(cmsFloat32Number);
2484 // --------------------------------------------------------------------------------------------------------
2487 cmsUInt8Number* PackFloatsFromFloat(_cmsTRANSFORM* info,
2488 cmsFloat32Number wOut[],
2489 cmsUInt8Number* output,
2490 cmsUInt32Number Stride)
2492 int nChan = T_CHANNELS(info -> OutputFormat);
2493 int DoSwap = T_DOSWAP(info ->OutputFormat);
2494 int Reverse = T_FLAVOR(info ->OutputFormat);
2495 int Extra = T_EXTRA(info -> OutputFormat);
2496 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2497 int Planar = T_PLANAR(info -> OutputFormat);
2498 int ExtraFirst = DoSwap ^ SwapFirst;
2499 cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
2500 cmsFloat32Number* swap1 = (cmsFloat32Number*) output;
2501 cmsFloat64Number v = 0;
2507 for (i=0; i < nChan; i++) {
2509 int index = DoSwap ? (nChan - i - 1) : i;
2511 v = wOut[index] * maximum;
2517 ((cmsFloat32Number*) output)[(i + start)* Stride]= (cmsFloat32Number) v;
2519 ((cmsFloat32Number*) output)[i + start] = (cmsFloat32Number) v;
2523 output += Extra * sizeof(cmsFloat32Number);
2526 if (Extra == 0 && SwapFirst) {
2528 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat32Number));
2529 *swap1 = (cmsFloat32Number) v;
2532 if (T_PLANAR(info -> OutputFormat))
2533 return output + sizeof(cmsFloat32Number);
2535 return output + nChan * sizeof(cmsFloat32Number);
2539 cmsUInt8Number* PackDoublesFromFloat(_cmsTRANSFORM* info,
2540 cmsFloat32Number wOut[],
2541 cmsUInt8Number* output,
2542 cmsUInt32Number Stride)
2544 int nChan = T_CHANNELS(info -> OutputFormat);
2545 int DoSwap = T_DOSWAP(info ->OutputFormat);
2546 int Reverse = T_FLAVOR(info ->OutputFormat);
2547 int Extra = T_EXTRA(info -> OutputFormat);
2548 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2549 int Planar = T_PLANAR(info -> OutputFormat);
2550 int ExtraFirst = DoSwap ^ SwapFirst;
2551 cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
2552 cmsFloat64Number v = 0;
2553 cmsFloat64Number* swap1 = (cmsFloat64Number*) output;
2559 for (i=0; i < nChan; i++) {
2561 int index = DoSwap ? (nChan - i - 1) : i;
2563 v = wOut[index] * maximum;
2569 ((cmsFloat64Number*) output)[(i + start) * Stride] = v;
2571 ((cmsFloat64Number*) output)[i + start] = v;
2575 output += Extra * sizeof(cmsFloat64Number);
2578 if (Extra == 0 && SwapFirst) {
2580 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat64Number));
2585 if (T_PLANAR(info -> OutputFormat))
2586 return output + sizeof(cmsFloat64Number);
2588 return output + nChan * sizeof(cmsFloat64Number);
2597 cmsUInt8Number* PackLabFloatFromFloat(_cmsTRANSFORM* Info,
2598 cmsFloat32Number wOut[],
2599 cmsUInt8Number* output,
2600 cmsUInt32Number Stride)
2602 cmsFloat32Number* Out = (cmsFloat32Number*) output;
2604 if (T_PLANAR(Info -> OutputFormat)) {
2606 Out[0] = (cmsFloat32Number) (wOut[0] * 100.0);
2607 Out[Stride] = (cmsFloat32Number) (wOut[1] * 255.0 - 128.0);
2608 Out[Stride*2] = (cmsFloat32Number) (wOut[2] * 255.0 - 128.0);
2610 return output + sizeof(cmsFloat32Number);
2614 Out[0] = (cmsFloat32Number) (wOut[0] * 100.0);
2615 Out[1] = (cmsFloat32Number) (wOut[1] * 255.0 - 128.0);
2616 Out[2] = (cmsFloat32Number) (wOut[2] * 255.0 - 128.0);
2618 return output + (sizeof(cmsFloat32Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
2625 cmsUInt8Number* PackLabDoubleFromFloat(_cmsTRANSFORM* Info,
2626 cmsFloat32Number wOut[],
2627 cmsUInt8Number* output,
2628 cmsUInt32Number Stride)
2630 cmsFloat64Number* Out = (cmsFloat64Number*) output;
2632 if (T_PLANAR(Info -> OutputFormat)) {
2634 Out[0] = (cmsFloat64Number) (wOut[0] * 100.0);
2635 Out[Stride] = (cmsFloat64Number) (wOut[1] * 255.0 - 128.0);
2636 Out[Stride*2] = (cmsFloat64Number) (wOut[2] * 255.0 - 128.0);
2638 return output + sizeof(cmsFloat64Number);
2642 Out[0] = (cmsFloat64Number) (wOut[0] * 100.0);
2643 Out[1] = (cmsFloat64Number) (wOut[1] * 255.0 - 128.0);
2644 Out[2] = (cmsFloat64Number) (wOut[2] * 255.0 - 128.0);
2646 return output + (sizeof(cmsFloat64Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
2652 // From 0..1 range to 0..MAX_ENCODEABLE_XYZ
2654 cmsUInt8Number* PackXYZFloatFromFloat(_cmsTRANSFORM* Info,
2655 cmsFloat32Number wOut[],
2656 cmsUInt8Number* output,
2657 cmsUInt32Number Stride)
2659 cmsFloat32Number* Out = (cmsFloat32Number*) output;
2661 if (T_PLANAR(Info -> OutputFormat)) {
2663 Out[0] = (cmsFloat32Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
2664 Out[Stride] = (cmsFloat32Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
2665 Out[Stride*2] = (cmsFloat32Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
2667 return output + sizeof(cmsFloat32Number);
2671 Out[0] = (cmsFloat32Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
2672 Out[1] = (cmsFloat32Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
2673 Out[2] = (cmsFloat32Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
2675 return output + (sizeof(cmsFloat32Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
2680 // Same, but convert to double
2682 cmsUInt8Number* PackXYZDoubleFromFloat(_cmsTRANSFORM* Info,
2683 cmsFloat32Number wOut[],
2684 cmsUInt8Number* output,
2685 cmsUInt32Number Stride)
2687 cmsFloat64Number* Out = (cmsFloat64Number*) output;
2689 if (T_PLANAR(Info -> OutputFormat)) {
2691 Out[0] = (cmsFloat64Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
2692 Out[Stride] = (cmsFloat64Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
2693 Out[Stride*2] = (cmsFloat64Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
2695 return output + sizeof(cmsFloat64Number);
2699 Out[0] = (cmsFloat64Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
2700 Out[1] = (cmsFloat64Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
2701 Out[2] = (cmsFloat64Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
2703 return output + (sizeof(cmsFloat64Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
2709 // ----------------------------------------------------------------------------------------------------------------
2711 #ifndef CMS_NO_HALF_SUPPORT
2713 // Decodes an stream of half floats to wIn[] described by input format
2716 cmsUInt8Number* UnrollHalfTo16(register _cmsTRANSFORM* info,
2717 register cmsUInt16Number wIn[],
2718 register cmsUInt8Number* accum,
2719 register cmsUInt32Number Stride)
2722 int nChan = T_CHANNELS(info -> InputFormat);
2723 int DoSwap = T_DOSWAP(info ->InputFormat);
2724 int Reverse = T_FLAVOR(info ->InputFormat);
2725 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
2726 int Extra = T_EXTRA(info -> InputFormat);
2727 int ExtraFirst = DoSwap ^ SwapFirst;
2728 int Planar = T_PLANAR(info -> InputFormat);
2731 cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 655.35F : 65535.0F;
2737 for (i=0; i < nChan; i++) {
2739 int index = DoSwap ? (nChan - i - 1) : i;
2742 v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[(i + start) * Stride] );
2744 v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[i + start] ) ;
2746 if (Reverse) v = maximum - v;
2748 wIn[index] = _cmsQuickSaturateWord(v * maximum);
2752 if (Extra == 0 && SwapFirst) {
2753 cmsUInt16Number tmp = wIn[0];
2755 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
2759 if (T_PLANAR(info -> InputFormat))
2760 return accum + sizeof(cmsUInt16Number);
2762 return accum + (nChan + Extra) * sizeof(cmsUInt16Number);
2765 // Decodes an stream of half floats to wIn[] described by input format
2768 cmsUInt8Number* UnrollHalfToFloat(_cmsTRANSFORM* info,
2769 cmsFloat32Number wIn[],
2770 cmsUInt8Number* accum,
2771 cmsUInt32Number Stride)
2774 int nChan = T_CHANNELS(info -> InputFormat);
2775 int DoSwap = T_DOSWAP(info ->InputFormat);
2776 int Reverse = T_FLAVOR(info ->InputFormat);
2777 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
2778 int Extra = T_EXTRA(info -> InputFormat);
2779 int ExtraFirst = DoSwap ^ SwapFirst;
2780 int Planar = T_PLANAR(info -> InputFormat);
2783 cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 100.0F : 1.0F;
2789 for (i=0; i < nChan; i++) {
2791 int index = DoSwap ? (nChan - i - 1) : i;
2794 v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[(i + start) * Stride] );
2796 v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[i + start] ) ;
2800 wIn[index] = Reverse ? 1 - v : v;
2804 if (Extra == 0 && SwapFirst) {
2805 cmsFloat32Number tmp = wIn[0];
2807 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number));
2811 if (T_PLANAR(info -> InputFormat))
2812 return accum + sizeof(cmsUInt16Number);
2814 return accum + (nChan + Extra) * sizeof(cmsUInt16Number);
2819 cmsUInt8Number* PackHalfFrom16(register _cmsTRANSFORM* info,
2820 register cmsUInt16Number wOut[],
2821 register cmsUInt8Number* output,
2822 register cmsUInt32Number Stride)
2824 int nChan = T_CHANNELS(info -> OutputFormat);
2825 int DoSwap = T_DOSWAP(info ->OutputFormat);
2826 int Reverse = T_FLAVOR(info ->OutputFormat);
2827 int Extra = T_EXTRA(info -> OutputFormat);
2828 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2829 int Planar = T_PLANAR(info -> OutputFormat);
2830 int ExtraFirst = DoSwap ^ SwapFirst;
2831 cmsFloat32Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35F : 65535.0F;
2832 cmsFloat32Number v = 0;
2833 cmsUInt16Number* swap1 = (cmsUInt16Number*) output;
2839 for (i=0; i < nChan; i++) {
2841 int index = DoSwap ? (nChan - i - 1) : i;
2843 v = (cmsFloat32Number) wOut[index] / maximum;
2849 ((cmsUInt16Number*) output)[(i + start ) * Stride]= _cmsFloat2Half(v);
2851 ((cmsUInt16Number*) output)[i + start] = _cmsFloat2Half(v);
2855 output += Extra * sizeof(cmsUInt16Number);
2858 if (Extra == 0 && SwapFirst) {
2860 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number));
2861 *swap1 = _cmsFloat2Half(v);
2864 if (T_PLANAR(info -> OutputFormat))
2865 return output + sizeof(cmsUInt16Number);
2867 return output + nChan * sizeof(cmsUInt16Number);
2873 cmsUInt8Number* PackHalfFromFloat(_cmsTRANSFORM* info,
2874 cmsFloat32Number wOut[],
2875 cmsUInt8Number* output,
2876 cmsUInt32Number Stride)
2878 int nChan = T_CHANNELS(info -> OutputFormat);
2879 int DoSwap = T_DOSWAP(info ->OutputFormat);
2880 int Reverse = T_FLAVOR(info ->OutputFormat);
2881 int Extra = T_EXTRA(info -> OutputFormat);
2882 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2883 int Planar = T_PLANAR(info -> OutputFormat);
2884 int ExtraFirst = DoSwap ^ SwapFirst;
2885 cmsFloat32Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0F : 1.0F;
2886 cmsUInt16Number* swap1 = (cmsUInt16Number*) output;
2887 cmsFloat32Number v = 0;
2893 for (i=0; i < nChan; i++) {
2895 int index = DoSwap ? (nChan - i - 1) : i;
2897 v = wOut[index] * maximum;
2903 ((cmsUInt16Number*) output)[(i + start)* Stride]= _cmsFloat2Half( v );
2905 ((cmsUInt16Number*) output)[i + start] = _cmsFloat2Half( v );
2909 output += Extra * sizeof(cmsUInt16Number);
2912 if (Extra == 0 && SwapFirst) {
2914 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number));
2915 *swap1 = (cmsUInt16Number) _cmsFloat2Half( v );
2918 if (T_PLANAR(info -> OutputFormat))
2919 return output + sizeof(cmsUInt16Number);
2921 return output + nChan * sizeof(cmsUInt16Number);
2926 // ----------------------------------------------------------------------------------------------------------------
2929 static cmsFormatters16 InputFormatters16[] = {
2931 // Type Mask Function
2932 // ---------------------------- ------------------------------------ ----------------------------
2933 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, UnrollLabDoubleTo16},
2934 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, UnrollXYZDoubleTo16},
2935 { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, UnrollLabFloatTo16},
2936 { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, UnrollXYZFloatTo16},
2937 { TYPE_GRAY_DBL, 0, UnrollDouble1Chan},
2938 { FLOAT_SH(1)|BYTES_SH(0), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR|
2939 ANYSWAP|ANYEXTRA|ANYSPACE, UnrollDoubleTo16},
2940 { FLOAT_SH(1)|BYTES_SH(4), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR|
2941 ANYSWAP|ANYEXTRA|ANYSPACE, UnrollFloatTo16},
2942 #ifndef CMS_NO_HALF_SUPPORT
2943 { FLOAT_SH(1)|BYTES_SH(2), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR|
2944 ANYEXTRA|ANYSWAP|ANYSPACE, UnrollHalfTo16},
2947 { CHANNELS_SH(1)|BYTES_SH(1), ANYSPACE, Unroll1Byte},
2948 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Unroll1ByteSkip1},
2949 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(2), ANYSPACE, Unroll1ByteSkip2},
2950 { CHANNELS_SH(1)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Unroll1ByteReversed},
2951 { COLORSPACE_SH(PT_MCH2)|CHANNELS_SH(2)|BYTES_SH(1), 0, Unroll2Bytes},
2953 { TYPE_LabV2_8, 0, UnrollLabV2_8 },
2954 { TYPE_ALabV2_8, 0, UnrollALabV2_8 },
2955 { TYPE_LabV2_16, 0, UnrollLabV2_16 },
2957 { CHANNELS_SH(3)|BYTES_SH(1), ANYSPACE, Unroll3Bytes},
2958 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3BytesSwap},
2959 { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3BytesSkip1Swap},
2960 { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll3BytesSkip1SwapFirst},
2962 { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1),
2963 ANYSPACE, Unroll3BytesSkip1SwapSwapFirst},
2965 { CHANNELS_SH(4)|BYTES_SH(1), ANYSPACE, Unroll4Bytes},
2966 { CHANNELS_SH(4)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Unroll4BytesReverse},
2967 { CHANNELS_SH(4)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4BytesSwapFirst},
2968 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll4BytesSwap},
2969 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4BytesSwapSwapFirst},
2971 { BYTES_SH(1)|PLANAR_SH(1), ANYFLAVOR|ANYSWAPFIRST|
2972 ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollPlanarBytes},
2974 { BYTES_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
2975 ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollChunkyBytes},
2977 { CHANNELS_SH(1)|BYTES_SH(2), ANYSPACE, Unroll1Word},
2978 { CHANNELS_SH(1)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Unroll1WordReversed},
2979 { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(3), ANYSPACE, Unroll1WordSkip3},
2981 { CHANNELS_SH(2)|BYTES_SH(2), ANYSPACE, Unroll2Words},
2982 { CHANNELS_SH(3)|BYTES_SH(2), ANYSPACE, Unroll3Words},
2983 { CHANNELS_SH(4)|BYTES_SH(2), ANYSPACE, Unroll4Words},
2985 { CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Unroll3WordsSwap},
2986 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll3WordsSkip1SwapFirst},
2987 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3WordsSkip1Swap},
2988 { CHANNELS_SH(4)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Unroll4WordsReverse},
2989 { CHANNELS_SH(4)|BYTES_SH(2)|SWAPFIRST_SH(1), ANYSPACE, Unroll4WordsSwapFirst},
2990 { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Unroll4WordsSwap},
2991 { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4WordsSwapSwapFirst},
2994 { BYTES_SH(2)|PLANAR_SH(1), ANYFLAVOR|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollPlanarWords},
2995 { BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollAnyWords},
3000 static cmsFormattersFloat InputFormattersFloat[] = {
3002 // Type Mask Function
3003 // ---------------------------- ------------------------------------ ----------------------------
3004 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, UnrollLabDoubleToFloat},
3005 { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, UnrollLabFloatToFloat},
3007 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, UnrollXYZDoubleToFloat},
3008 { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, UnrollXYZFloatToFloat},
3010 { FLOAT_SH(1)|BYTES_SH(4), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
3011 ANYCHANNELS|ANYSPACE, UnrollFloatsToFloat},
3013 { FLOAT_SH(1)|BYTES_SH(0), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
3014 ANYCHANNELS|ANYSPACE, UnrollDoublesToFloat},
3015 #ifndef CMS_NO_HALF_SUPPORT
3016 { FLOAT_SH(1)|BYTES_SH(2), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
3017 ANYCHANNELS|ANYSPACE, UnrollHalfToFloat},
3022 // Bit fields set to one in the mask are not compared
3024 cmsFormatter _cmsGetStockInputFormatter(cmsUInt32Number dwInput, cmsUInt32Number dwFlags)
3031 case CMS_PACK_FLAGS_16BITS: {
3032 for (i=0; i < sizeof(InputFormatters16) / sizeof(cmsFormatters16); i++) {
3033 cmsFormatters16* f = InputFormatters16 + i;
3035 if ((dwInput & ~f ->Mask) == f ->Type) {
3043 case CMS_PACK_FLAGS_FLOAT: {
3044 for (i=0; i < sizeof(InputFormattersFloat) / sizeof(cmsFormattersFloat); i++) {
3045 cmsFormattersFloat* f = InputFormattersFloat + i;
3047 if ((dwInput & ~f ->Mask) == f ->Type) {
3048 fr.FmtFloat = f ->Frm;
3063 static cmsFormatters16 OutputFormatters16[] = {
3064 // Type Mask Function
3065 // ---------------------------- ------------------------------------ ----------------------------
3067 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, PackLabDoubleFrom16},
3068 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, PackXYZDoubleFrom16},
3070 { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, PackLabFloatFrom16},
3071 { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, PackXYZFloatFrom16},
3073 { FLOAT_SH(1)|BYTES_SH(0), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
3074 ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackDoubleFrom16},
3075 { FLOAT_SH(1)|BYTES_SH(4), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
3076 ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackFloatFrom16},
3077 #ifndef CMS_NO_HALF_SUPPORT
3078 { FLOAT_SH(1)|BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
3079 ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackHalfFrom16},
3082 { CHANNELS_SH(1)|BYTES_SH(1), ANYSPACE, Pack1Byte},
3083 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Pack1ByteSkip1},
3084 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack1ByteSkip1SwapFirst},
3086 { CHANNELS_SH(1)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Pack1ByteReversed},
3088 { TYPE_LabV2_8, 0, PackLabV2_8 },
3089 { TYPE_ALabV2_8, 0, PackALabV2_8 },
3090 { TYPE_LabV2_16, 0, PackLabV2_16 },
3092 { CHANNELS_SH(3)|BYTES_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesOptimized},
3093 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesAndSkip1Optimized},
3094 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1)|OPTIMIZED_SH(1),
3095 ANYSPACE, Pack3BytesAndSkip1SwapFirstOptimized},
3096 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1)|OPTIMIZED_SH(1),
3097 ANYSPACE, Pack3BytesAndSkip1SwapSwapFirstOptimized},
3098 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|EXTRA_SH(1)|OPTIMIZED_SH(1),
3099 ANYSPACE, Pack3BytesAndSkip1SwapOptimized},
3100 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesSwapOptimized},
3104 { CHANNELS_SH(3)|BYTES_SH(1), ANYSPACE, Pack3Bytes},
3105 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Pack3BytesAndSkip1},
3106 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack3BytesAndSkip1SwapFirst},
3107 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1),
3108 ANYSPACE, Pack3BytesAndSkip1SwapSwapFirst},
3109 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|EXTRA_SH(1), ANYSPACE, Pack3BytesAndSkip1Swap},
3110 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack3BytesSwap},
3111 { CHANNELS_SH(6)|BYTES_SH(1), ANYSPACE, Pack6Bytes},
3112 { CHANNELS_SH(6)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack6BytesSwap},
3113 { CHANNELS_SH(4)|BYTES_SH(1), ANYSPACE, Pack4Bytes},
3114 { CHANNELS_SH(4)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Pack4BytesReverse},
3115 { CHANNELS_SH(4)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack4BytesSwapFirst},
3116 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack4BytesSwap},
3117 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack4BytesSwapSwapFirst},
3119 { BYTES_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackAnyBytes},
3120 { BYTES_SH(1)|PLANAR_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackPlanarBytes},
3122 { CHANNELS_SH(1)|BYTES_SH(2), ANYSPACE, Pack1Word},
3123 { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(1), ANYSPACE, Pack1WordSkip1},
3124 { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack1WordSkip1SwapFirst},
3125 { CHANNELS_SH(1)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Pack1WordReversed},
3126 { CHANNELS_SH(1)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack1WordBigEndian},
3127 { CHANNELS_SH(3)|BYTES_SH(2), ANYSPACE, Pack3Words},
3128 { CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack3WordsSwap},
3129 { CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack3WordsBigEndian},
3130 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1), ANYSPACE, Pack3WordsAndSkip1},
3131 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack3WordsAndSkip1Swap},
3132 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack3WordsAndSkip1SwapFirst},
3134 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1),
3135 ANYSPACE, Pack3WordsAndSkip1SwapSwapFirst},
3137 { CHANNELS_SH(4)|BYTES_SH(2), ANYSPACE, Pack4Words},
3138 { CHANNELS_SH(4)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Pack4WordsReverse},
3139 { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack4WordsSwap},
3140 { CHANNELS_SH(4)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack4WordsBigEndian},
3142 { CHANNELS_SH(6)|BYTES_SH(2), ANYSPACE, Pack6Words},
3143 { CHANNELS_SH(6)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack6WordsSwap},
3145 { BYTES_SH(2)|PLANAR_SH(1), ANYFLAVOR|ANYENDIAN|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackPlanarWords},
3146 { BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackAnyWords}
3151 static cmsFormattersFloat OutputFormattersFloat[] = {
3152 // Type Mask Function
3153 // ---------------------------- --------------------------------------------------- ----------------------------
3154 { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, PackLabFloatFromFloat},
3155 { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, PackXYZFloatFromFloat},
3157 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, PackLabDoubleFromFloat},
3158 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, PackXYZDoubleFromFloat},
3160 { FLOAT_SH(1)|BYTES_SH(4), ANYPLANAR|
3161 ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackFloatsFromFloat },
3162 { FLOAT_SH(1)|BYTES_SH(0), ANYPLANAR|
3163 ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackDoublesFromFloat },
3164 #ifndef CMS_NO_HALF_SUPPORT
3165 { FLOAT_SH(1)|BYTES_SH(2),
3166 ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackHalfFromFloat },
3174 // Bit fields set to one in the mask are not compared
3176 cmsFormatter _cmsGetStockOutputFormatter(cmsUInt32Number dwInput, cmsUInt32Number dwFlags)
3185 case CMS_PACK_FLAGS_16BITS: {
3187 for (i=0; i < sizeof(OutputFormatters16) / sizeof(cmsFormatters16); i++) {
3188 cmsFormatters16* f = OutputFormatters16 + i;
3190 if ((dwInput & ~f ->Mask) == f ->Type) {
3198 case CMS_PACK_FLAGS_FLOAT: {
3200 for (i=0; i < sizeof(OutputFormattersFloat) / sizeof(cmsFormattersFloat); i++) {
3201 cmsFormattersFloat* f = OutputFormattersFloat + i;
3203 if ((dwInput & ~f ->Mask) == f ->Type) {
3204 fr.FmtFloat = f ->Frm;
3220 typedef struct _cms_formatters_factory_list {
3222 cmsFormatterFactory Factory;
3223 struct _cms_formatters_factory_list *Next;
3225 } cmsFormattersFactoryList;
3227 _cmsFormattersPluginChunkType _cmsFormattersPluginChunk = { NULL };
3230 // Duplicates the zone of memory used by the plug-in in the new context
3232 void DupFormatterFactoryList(struct _cmsContext_struct* ctx,
3233 const struct _cmsContext_struct* src)
3235 _cmsFormattersPluginChunkType newHead = { NULL };
3236 cmsFormattersFactoryList* entry;
3237 cmsFormattersFactoryList* Anterior = NULL;
3238 _cmsFormattersPluginChunkType* head = (_cmsFormattersPluginChunkType*) src->chunks[FormattersPlugin];
3240 _cmsAssert(head != NULL);
3242 // Walk the list copying all nodes
3243 for (entry = head->FactoryList;
3245 entry = entry ->Next) {
3247 cmsFormattersFactoryList *newEntry = ( cmsFormattersFactoryList *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(cmsFormattersFactoryList));
3249 if (newEntry == NULL)
3252 // We want to keep the linked list order, so this is a little bit tricky
3253 newEntry -> Next = NULL;
3255 Anterior -> Next = newEntry;
3257 Anterior = newEntry;
3259 if (newHead.FactoryList == NULL)
3260 newHead.FactoryList = newEntry;
3263 ctx ->chunks[FormattersPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsFormattersPluginChunkType));
3266 // The interpolation plug-in memory chunk allocator/dup
3267 void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct* ctx,
3268 const struct _cmsContext_struct* src)
3270 _cmsAssert(ctx != NULL);
3274 // Duplicate the LIST
3275 DupFormatterFactoryList(ctx, src);
3278 static _cmsFormattersPluginChunkType FormattersPluginChunk = { NULL };
3279 ctx ->chunks[FormattersPlugin] = _cmsSubAllocDup(ctx ->MemPool, &FormattersPluginChunk, sizeof(_cmsFormattersPluginChunkType));
3285 // Formatters management
3286 cmsBool _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Data)
3288 _cmsFormattersPluginChunkType* ctx = ( _cmsFormattersPluginChunkType*) _cmsContextGetClientChunk(ContextID, FormattersPlugin);
3289 cmsPluginFormatters* Plugin = (cmsPluginFormatters*) Data;
3290 cmsFormattersFactoryList* fl ;
3292 // Reset to built-in defaults
3295 ctx ->FactoryList = NULL;
3299 fl = (cmsFormattersFactoryList*) _cmsPluginMalloc(ContextID, sizeof(cmsFormattersFactoryList));
3300 if (fl == NULL) return FALSE;
3302 fl ->Factory = Plugin ->FormattersFactory;
3304 fl ->Next = ctx -> FactoryList;
3305 ctx ->FactoryList = fl;
3310 cmsFormatter _cmsGetFormatter(cmsContext ContextID,
3311 cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8
3312 cmsFormatterDirection Dir,
3313 cmsUInt32Number dwFlags)
3315 _cmsFormattersPluginChunkType* ctx = ( _cmsFormattersPluginChunkType*) _cmsContextGetClientChunk(ContextID, FormattersPlugin);
3316 cmsFormattersFactoryList* f;
3318 for (f =ctx->FactoryList; f != NULL; f = f ->Next) {
3320 cmsFormatter fn = f ->Factory(Type, Dir, dwFlags);
3321 if (fn.Fmt16 != NULL) return fn;
3324 // Revert to default
3325 if (Dir == cmsFormatterInput)
3326 return _cmsGetStockInputFormatter(Type, dwFlags);
3328 return _cmsGetStockOutputFormatter(Type, dwFlags);
3332 // Return whatever given formatter refers to float values
3333 cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type)
3335 return T_FLOAT(Type) ? TRUE : FALSE;
3338 // Return whatever given formatter refers to 8 bits
3339 cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type)
3341 int Bytes = T_BYTES(Type);
3343 return (Bytes == 1);
3346 // Build a suitable formatter for the colorspace of this profile
3347 cmsUInt32Number CMSEXPORT cmsFormatterForColorspaceOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat)
3350 cmsColorSpaceSignature ColorSpace = cmsGetColorSpace(hProfile);
3351 cmsUInt32Number ColorSpaceBits = _cmsLCMScolorSpace(ColorSpace);
3352 cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace);
3353 cmsUInt32Number Float = lIsFloat ? 1 : 0;
3355 // Create a fake formatter for result
3356 return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans);
3359 // Build a suitable formatter for the colorspace of this profile
3360 cmsUInt32Number CMSEXPORT cmsFormatterForPCSOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat)
3363 cmsColorSpaceSignature ColorSpace = cmsGetPCS(hProfile);
3364 int ColorSpaceBits = _cmsLCMScolorSpace(ColorSpace);
3365 cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace);
3366 cmsUInt32Number Float = lIsFloat ? 1 : 0;
3368 // Create a fake formatter for result
3369 return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans);