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* Unroll3BytesSkip1SwapFirst(register _cmsTRANSFORM* info,
292 register cmsUInt16Number wIn[],
293 register cmsUInt8Number* accum,
294 register cmsUInt32Number Stride)
297 wIn[0] = FROM_8_TO_16(*accum); accum++; // R
298 wIn[1] = FROM_8_TO_16(*accum); accum++; // G
299 wIn[2] = FROM_8_TO_16(*accum); accum++; // B
303 cmsUNUSED_PARAMETER(info);
304 cmsUNUSED_PARAMETER(Stride);
310 cmsUInt8Number* Unroll3BytesSwap(register _cmsTRANSFORM* info,
311 register cmsUInt16Number wIn[],
312 register cmsUInt8Number* accum,
313 register cmsUInt32Number Stride)
315 wIn[2] = FROM_8_TO_16(*accum); accum++; // B
316 wIn[1] = FROM_8_TO_16(*accum); accum++; // G
317 wIn[0] = FROM_8_TO_16(*accum); accum++; // R
321 cmsUNUSED_PARAMETER(info);
322 cmsUNUSED_PARAMETER(Stride);
326 cmsUInt8Number* UnrollLabV2_8(register _cmsTRANSFORM* info,
327 register cmsUInt16Number wIn[],
328 register cmsUInt8Number* accum,
329 register cmsUInt32Number Stride)
331 wIn[0] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // L
332 wIn[1] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // a
333 wIn[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // b
337 cmsUNUSED_PARAMETER(info);
338 cmsUNUSED_PARAMETER(Stride);
342 cmsUInt8Number* UnrollALabV2_8(register _cmsTRANSFORM* info,
343 register cmsUInt16Number wIn[],
344 register cmsUInt8Number* accum,
345 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* UnrollLabV2_16(register _cmsTRANSFORM* info,
360 register cmsUInt16Number wIn[],
361 register cmsUInt8Number* accum,
362 register cmsUInt32Number Stride)
364 wIn[0] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // L
365 wIn[1] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // a
366 wIn[2] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // b
370 cmsUNUSED_PARAMETER(info);
371 cmsUNUSED_PARAMETER(Stride);
376 cmsUInt8Number* Unroll2Bytes(register _cmsTRANSFORM* info,
377 register cmsUInt16Number wIn[],
378 register cmsUInt8Number* accum,
379 register cmsUInt32Number Stride)
381 wIn[0] = FROM_8_TO_16(*accum); accum++; // ch1
382 wIn[1] = FROM_8_TO_16(*accum); accum++; // ch2
386 cmsUNUSED_PARAMETER(info);
387 cmsUNUSED_PARAMETER(Stride);
393 // Monochrome duplicates L into RGB for null-transforms
395 cmsUInt8Number* Unroll1Byte(register _cmsTRANSFORM* info,
396 register cmsUInt16Number wIn[],
397 register cmsUInt8Number* accum,
398 register cmsUInt32Number Stride)
400 wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L
404 cmsUNUSED_PARAMETER(info);
405 cmsUNUSED_PARAMETER(Stride);
410 cmsUInt8Number* Unroll1ByteSkip1(register _cmsTRANSFORM* info,
411 register cmsUInt16Number wIn[],
412 register cmsUInt8Number* accum,
413 register cmsUInt32Number Stride)
415 wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L
420 cmsUNUSED_PARAMETER(info);
421 cmsUNUSED_PARAMETER(Stride);
425 cmsUInt8Number* Unroll1ByteSkip2(register _cmsTRANSFORM* info,
426 register cmsUInt16Number wIn[],
427 register cmsUInt8Number* accum,
428 register cmsUInt32Number Stride)
430 wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L
435 cmsUNUSED_PARAMETER(info);
436 cmsUNUSED_PARAMETER(Stride);
440 cmsUInt8Number* Unroll1ByteReversed(register _cmsTRANSFORM* info,
441 register cmsUInt16Number wIn[],
442 register cmsUInt8Number* accum,
443 register cmsUInt32Number Stride)
445 wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(FROM_8_TO_16(*accum)); accum++; // L
449 cmsUNUSED_PARAMETER(info);
450 cmsUNUSED_PARAMETER(Stride);
455 cmsUInt8Number* UnrollAnyWords(register _cmsTRANSFORM* info,
456 register cmsUInt16Number wIn[],
457 register cmsUInt8Number* accum,
458 register cmsUInt32Number Stride)
460 int nChan = T_CHANNELS(info -> InputFormat);
461 int SwapEndian = T_ENDIAN16(info -> InputFormat);
462 int DoSwap = T_DOSWAP(info ->InputFormat);
463 int Reverse = T_FLAVOR(info ->InputFormat);
464 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
465 int Extra = T_EXTRA(info -> InputFormat);
466 int ExtraFirst = DoSwap ^ SwapFirst;
470 accum += Extra * sizeof(cmsUInt16Number);
473 for (i=0; i < nChan; i++) {
475 int index = DoSwap ? (nChan - i - 1) : i;
476 cmsUInt16Number v = *(cmsUInt16Number*) accum;
479 v = CHANGE_ENDIAN(v);
481 wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
483 accum += sizeof(cmsUInt16Number);
487 accum += Extra * sizeof(cmsUInt16Number);
490 if (Extra == 0 && SwapFirst) {
492 cmsUInt16Number tmp = wIn[0];
494 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
500 cmsUNUSED_PARAMETER(Stride);
504 cmsUInt8Number* UnrollPlanarWords(register _cmsTRANSFORM* info,
505 register cmsUInt16Number wIn[],
506 register cmsUInt8Number* accum,
507 register cmsUInt32Number Stride)
509 int nChan = T_CHANNELS(info -> InputFormat);
510 int DoSwap= T_DOSWAP(info ->InputFormat);
511 int Reverse= T_FLAVOR(info ->InputFormat);
512 int SwapEndian = T_ENDIAN16(info -> InputFormat);
514 cmsUInt8Number* Init = accum;
517 accum += T_EXTRA(info -> InputFormat) * Stride * sizeof(cmsUInt16Number);
520 for (i=0; i < nChan; i++) {
522 int index = DoSwap ? (nChan - i - 1) : i;
523 cmsUInt16Number v = *(cmsUInt16Number*) accum;
526 v = CHANGE_ENDIAN(v);
528 wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
530 accum += Stride * sizeof(cmsUInt16Number);
533 return (Init + sizeof(cmsUInt16Number));
538 cmsUInt8Number* Unroll4Words(register _cmsTRANSFORM* info,
539 register cmsUInt16Number wIn[],
540 register cmsUInt8Number* accum,
541 register cmsUInt32Number Stride)
543 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
544 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
545 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
546 wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
550 cmsUNUSED_PARAMETER(info);
551 cmsUNUSED_PARAMETER(Stride);
555 cmsUInt8Number* Unroll4WordsReverse(register _cmsTRANSFORM* info,
556 register cmsUInt16Number wIn[],
557 register cmsUInt8Number* accum,
558 register cmsUInt32Number Stride)
560 wIn[0] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // C
561 wIn[1] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // M
562 wIn[2] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // Y
563 wIn[3] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // K
567 cmsUNUSED_PARAMETER(info);
568 cmsUNUSED_PARAMETER(Stride);
572 cmsUInt8Number* Unroll4WordsSwapFirst(register _cmsTRANSFORM* info,
573 register cmsUInt16Number wIn[],
574 register cmsUInt8Number* accum,
575 register cmsUInt32Number Stride)
577 wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
578 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
579 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
580 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
584 cmsUNUSED_PARAMETER(info);
585 cmsUNUSED_PARAMETER(Stride);
590 cmsUInt8Number* Unroll4WordsSwap(register _cmsTRANSFORM* info,
591 register cmsUInt16Number wIn[],
592 register cmsUInt8Number* accum,
593 register cmsUInt32Number Stride)
595 wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
596 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
597 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
598 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
602 cmsUNUSED_PARAMETER(info);
603 cmsUNUSED_PARAMETER(Stride);
607 cmsUInt8Number* Unroll4WordsSwapSwapFirst(register _cmsTRANSFORM* info,
608 register cmsUInt16Number wIn[],
609 register cmsUInt8Number* accum,
610 register cmsUInt32Number Stride)
612 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // K
613 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // Y
614 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // M
615 wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // C
619 cmsUNUSED_PARAMETER(info);
620 cmsUNUSED_PARAMETER(Stride);
624 cmsUInt8Number* Unroll3Words(register _cmsTRANSFORM* info,
625 register cmsUInt16Number wIn[],
626 register cmsUInt8Number* accum,
627 register cmsUInt32Number Stride)
629 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C R
630 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M G
631 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y B
635 cmsUNUSED_PARAMETER(info);
636 cmsUNUSED_PARAMETER(Stride);
640 cmsUInt8Number* Unroll3WordsSwap(register _cmsTRANSFORM* info,
641 register cmsUInt16Number wIn[],
642 register cmsUInt8Number* accum,
643 register cmsUInt32Number Stride)
645 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // C R
646 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M G
647 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // Y B
651 cmsUNUSED_PARAMETER(info);
652 cmsUNUSED_PARAMETER(Stride);
656 cmsUInt8Number* Unroll3WordsSkip1Swap(register _cmsTRANSFORM* info,
657 register cmsUInt16Number wIn[],
658 register cmsUInt8Number* accum,
659 register cmsUInt32Number Stride)
662 wIn[2] = *(cmsUInt16Number*) accum; accum += 2; // R
663 wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // G
664 wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // B
668 cmsUNUSED_PARAMETER(info);
669 cmsUNUSED_PARAMETER(Stride);
673 cmsUInt8Number* Unroll3WordsSkip1SwapFirst(register _cmsTRANSFORM* info,
674 register cmsUInt16Number wIn[],
675 register cmsUInt8Number* accum,
676 register cmsUInt32Number Stride)
679 wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // R
680 wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // G
681 wIn[2] = *(cmsUInt16Number*) accum; accum += 2; // B
685 cmsUNUSED_PARAMETER(info);
686 cmsUNUSED_PARAMETER(Stride);
690 cmsUInt8Number* Unroll1Word(register _cmsTRANSFORM* info,
691 register cmsUInt16Number wIn[],
692 register cmsUInt8Number* accum,
693 register cmsUInt32Number Stride)
695 wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // L
699 cmsUNUSED_PARAMETER(info);
700 cmsUNUSED_PARAMETER(Stride);
704 cmsUInt8Number* Unroll1WordReversed(register _cmsTRANSFORM* info,
705 register cmsUInt16Number wIn[],
706 register cmsUInt8Number* accum,
707 register cmsUInt32Number Stride)
709 wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2;
713 cmsUNUSED_PARAMETER(info);
714 cmsUNUSED_PARAMETER(Stride);
718 cmsUInt8Number* Unroll1WordSkip3(register _cmsTRANSFORM* info,
719 register cmsUInt16Number wIn[],
720 register cmsUInt8Number* accum,
721 register cmsUInt32Number Stride)
723 wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum;
729 cmsUNUSED_PARAMETER(info);
730 cmsUNUSED_PARAMETER(Stride);
734 cmsUInt8Number* Unroll2Words(register _cmsTRANSFORM* info,
735 register cmsUInt16Number wIn[],
736 register cmsUInt8Number* accum,
737 register cmsUInt32Number Stride)
739 wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // ch1
740 wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // ch2
744 cmsUNUSED_PARAMETER(info);
745 cmsUNUSED_PARAMETER(Stride);
749 // This is a conversion of Lab double to 16 bits
751 cmsUInt8Number* UnrollLabDoubleTo16(register _cmsTRANSFORM* info,
752 register cmsUInt16Number wIn[],
753 register cmsUInt8Number* accum,
754 register cmsUInt32Number Stride)
756 if (T_PLANAR(info -> InputFormat)) {
758 cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
764 Lab.b = Pt[Stride*2];
766 cmsFloat2LabEncoded(wIn, &Lab);
767 return accum + sizeof(cmsFloat64Number);
771 cmsFloat2LabEncoded(wIn, (cmsCIELab*) accum);
772 accum += sizeof(cmsCIELab) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat64Number);
778 // This is a conversion of Lab float to 16 bits
780 cmsUInt8Number* UnrollLabFloatTo16(register _cmsTRANSFORM* info,
781 register cmsUInt16Number wIn[],
782 register cmsUInt8Number* accum,
783 register cmsUInt32Number Stride)
787 if (T_PLANAR(info -> InputFormat)) {
789 cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
794 Lab.b = Pt[Stride*2];
796 cmsFloat2LabEncoded(wIn, &Lab);
797 return accum + sizeof(cmsFloat32Number);
801 Lab.L = ((cmsFloat32Number*) accum)[0];
802 Lab.a = ((cmsFloat32Number*) accum)[1];
803 Lab.b = ((cmsFloat32Number*) accum)[2];
805 cmsFloat2LabEncoded(wIn, &Lab);
806 accum += (3 + T_EXTRA(info ->InputFormat)) * sizeof(cmsFloat32Number);
811 // This is a conversion of XYZ double to 16 bits
813 cmsUInt8Number* UnrollXYZDoubleTo16(register _cmsTRANSFORM* info,
814 register cmsUInt16Number wIn[],
815 register cmsUInt8Number* accum,
816 register cmsUInt32Number Stride)
818 if (T_PLANAR(info -> InputFormat)) {
820 cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
825 XYZ.Z = Pt[Stride*2];
826 cmsFloat2XYZEncoded(wIn, &XYZ);
828 return accum + sizeof(cmsFloat64Number);
833 cmsFloat2XYZEncoded(wIn, (cmsCIEXYZ*) accum);
834 accum += sizeof(cmsCIEXYZ) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat64Number);
840 // Check if space is marked as ink
841 cmsINLINE cmsBool IsInkSpace(cmsUInt32Number Type)
843 switch (T_COLORSPACE(Type)) {
857 case PT_MCH15: return TRUE;
859 default: return FALSE;
863 // Inks does come in percentage, remaining cases are between 0..1.0, again to 16 bits
865 cmsUInt8Number* UnrollDoubleTo16(register _cmsTRANSFORM* info,
866 register cmsUInt16Number wIn[],
867 register cmsUInt8Number* accum,
868 register cmsUInt32Number Stride)
871 int nChan = T_CHANNELS(info -> InputFormat);
872 int DoSwap = T_DOSWAP(info ->InputFormat);
873 int Reverse = T_FLAVOR(info ->InputFormat);
874 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
875 int Extra = T_EXTRA(info -> InputFormat);
876 int ExtraFirst = DoSwap ^ SwapFirst;
877 int Planar = T_PLANAR(info -> InputFormat);
881 cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
887 for (i=0; i < nChan; i++) {
889 int index = DoSwap ? (nChan - i - 1) : i;
892 v = (cmsFloat32Number) ((cmsFloat64Number*) accum)[(i + start) * Stride];
894 v = (cmsFloat32Number) ((cmsFloat64Number*) accum)[i + start];
896 vi = _cmsQuickSaturateWord(v * maximum);
899 vi = REVERSE_FLAVOR_16(vi);
905 if (Extra == 0 && SwapFirst) {
906 cmsUInt16Number tmp = wIn[0];
908 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
912 if (T_PLANAR(info -> InputFormat))
913 return accum + sizeof(cmsFloat64Number);
915 return accum + (nChan + Extra) * sizeof(cmsFloat64Number);
921 cmsUInt8Number* UnrollFloatTo16(register _cmsTRANSFORM* info,
922 register cmsUInt16Number wIn[],
923 register cmsUInt8Number* accum,
924 register cmsUInt32Number Stride)
927 int nChan = T_CHANNELS(info -> InputFormat);
928 int DoSwap = T_DOSWAP(info ->InputFormat);
929 int Reverse = T_FLAVOR(info ->InputFormat);
930 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
931 int Extra = T_EXTRA(info -> InputFormat);
932 int ExtraFirst = DoSwap ^ SwapFirst;
933 int Planar = T_PLANAR(info -> InputFormat);
937 cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
943 for (i=0; i < nChan; i++) {
945 int index = DoSwap ? (nChan - i - 1) : i;
948 v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[(i + start) * Stride];
950 v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[i + start];
952 vi = _cmsQuickSaturateWord(v * maximum);
955 vi = REVERSE_FLAVOR_16(vi);
961 if (Extra == 0 && SwapFirst) {
962 cmsUInt16Number tmp = wIn[0];
964 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
968 if (T_PLANAR(info -> InputFormat))
969 return accum + sizeof(cmsFloat32Number);
971 return accum + (nChan + Extra) * sizeof(cmsFloat32Number);
977 // For 1 channel, we need to duplicate data (it comes in 0..1.0 range)
979 cmsUInt8Number* UnrollDouble1Chan(register _cmsTRANSFORM* info,
980 register cmsUInt16Number wIn[],
981 register cmsUInt8Number* accum,
982 register cmsUInt32Number Stride)
984 cmsFloat64Number* Inks = (cmsFloat64Number*) accum;
986 wIn[0] = wIn[1] = wIn[2] = _cmsQuickSaturateWord(Inks[0] * 65535.0);
988 return accum + sizeof(cmsFloat64Number);
990 cmsUNUSED_PARAMETER(info);
991 cmsUNUSED_PARAMETER(Stride);
994 //-------------------------------------------------------------------------------------------------------------------
996 // For anything going from cmsFloat32Number
998 cmsUInt8Number* UnrollFloatsToFloat(_cmsTRANSFORM* info,
999 cmsFloat32Number wIn[],
1000 cmsUInt8Number* accum,
1001 cmsUInt32Number Stride)
1004 int nChan = T_CHANNELS(info -> InputFormat);
1005 int DoSwap = T_DOSWAP(info ->InputFormat);
1006 int Reverse = T_FLAVOR(info ->InputFormat);
1007 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
1008 int Extra = T_EXTRA(info -> InputFormat);
1009 int ExtraFirst = DoSwap ^ SwapFirst;
1010 int Planar = T_PLANAR(info -> InputFormat);
1013 cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 100.0F : 1.0F;
1019 for (i=0; i < nChan; i++) {
1021 int index = DoSwap ? (nChan - i - 1) : i;
1024 v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[(i + start) * Stride];
1026 v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[i + start];
1030 wIn[index] = Reverse ? 1 - v : v;
1034 if (Extra == 0 && SwapFirst) {
1035 cmsFloat32Number tmp = wIn[0];
1037 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number));
1041 if (T_PLANAR(info -> InputFormat))
1042 return accum + sizeof(cmsFloat32Number);
1044 return accum + (nChan + Extra) * sizeof(cmsFloat32Number);
1047 // For anything going from double
1050 cmsUInt8Number* UnrollDoublesToFloat(_cmsTRANSFORM* info,
1051 cmsFloat32Number wIn[],
1052 cmsUInt8Number* accum,
1053 cmsUInt32Number Stride)
1056 int nChan = T_CHANNELS(info -> InputFormat);
1057 int DoSwap = T_DOSWAP(info ->InputFormat);
1058 int Reverse = T_FLAVOR(info ->InputFormat);
1059 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
1060 int Extra = T_EXTRA(info -> InputFormat);
1061 int ExtraFirst = DoSwap ^ SwapFirst;
1062 int Planar = T_PLANAR(info -> InputFormat);
1065 cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 100.0 : 1.0;
1071 for (i=0; i < nChan; i++) {
1073 int index = DoSwap ? (nChan - i - 1) : i;
1076 v = (cmsFloat64Number) ((cmsFloat64Number*) accum)[(i + start) * Stride];
1078 v = (cmsFloat64Number) ((cmsFloat64Number*) accum)[i + start];
1082 wIn[index] = (cmsFloat32Number) (Reverse ? 1.0 - v : v);
1086 if (Extra == 0 && SwapFirst) {
1087 cmsFloat32Number tmp = wIn[0];
1089 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number));
1093 if (T_PLANAR(info -> InputFormat))
1094 return accum + sizeof(cmsFloat64Number);
1096 return accum + (nChan + Extra) * sizeof(cmsFloat64Number);
1101 // From Lab double to cmsFloat32Number
1103 cmsUInt8Number* UnrollLabDoubleToFloat(_cmsTRANSFORM* info,
1104 cmsFloat32Number wIn[],
1105 cmsUInt8Number* accum,
1106 cmsUInt32Number Stride)
1108 cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
1110 if (T_PLANAR(info -> InputFormat)) {
1112 wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
1113 wIn[1] = (cmsFloat32Number) ((Pt[Stride] + 128) / 255.0); // form -128..+127 to 0..1
1114 wIn[2] = (cmsFloat32Number) ((Pt[Stride*2] + 128) / 255.0);
1116 return accum + sizeof(cmsFloat64Number);
1120 wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
1121 wIn[1] = (cmsFloat32Number) ((Pt[1] + 128) / 255.0); // form -128..+127 to 0..1
1122 wIn[2] = (cmsFloat32Number) ((Pt[2] + 128) / 255.0);
1124 accum += sizeof(cmsFloat64Number)*(3 + T_EXTRA(info ->InputFormat));
1129 // From Lab double to cmsFloat32Number
1131 cmsUInt8Number* UnrollLabFloatToFloat(_cmsTRANSFORM* info,
1132 cmsFloat32Number wIn[],
1133 cmsUInt8Number* accum,
1134 cmsUInt32Number Stride)
1136 cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
1138 if (T_PLANAR(info -> InputFormat)) {
1140 wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
1141 wIn[1] = (cmsFloat32Number) ((Pt[Stride] + 128) / 255.0); // form -128..+127 to 0..1
1142 wIn[2] = (cmsFloat32Number) ((Pt[Stride*2] + 128) / 255.0);
1144 return accum + sizeof(cmsFloat32Number);
1148 wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
1149 wIn[1] = (cmsFloat32Number) ((Pt[1] + 128) / 255.0); // form -128..+127 to 0..1
1150 wIn[2] = (cmsFloat32Number) ((Pt[2] + 128) / 255.0);
1152 accum += sizeof(cmsFloat32Number)*(3 + T_EXTRA(info ->InputFormat));
1159 // 1.15 fixed point, that means maximum value is MAX_ENCODEABLE_XYZ (0xFFFF)
1161 cmsUInt8Number* UnrollXYZDoubleToFloat(_cmsTRANSFORM* info,
1162 cmsFloat32Number wIn[],
1163 cmsUInt8Number* accum,
1164 cmsUInt32Number Stride)
1166 cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
1168 if (T_PLANAR(info -> InputFormat)) {
1170 wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
1171 wIn[1] = (cmsFloat32Number) (Pt[Stride] / MAX_ENCODEABLE_XYZ);
1172 wIn[2] = (cmsFloat32Number) (Pt[Stride*2] / MAX_ENCODEABLE_XYZ);
1174 return accum + sizeof(cmsFloat64Number);
1178 wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
1179 wIn[1] = (cmsFloat32Number) (Pt[1] / MAX_ENCODEABLE_XYZ);
1180 wIn[2] = (cmsFloat32Number) (Pt[2] / MAX_ENCODEABLE_XYZ);
1182 accum += sizeof(cmsFloat64Number)*(3 + T_EXTRA(info ->InputFormat));
1188 cmsUInt8Number* UnrollXYZFloatToFloat(_cmsTRANSFORM* info,
1189 cmsFloat32Number wIn[],
1190 cmsUInt8Number* accum,
1191 cmsUInt32Number Stride)
1193 cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
1195 if (T_PLANAR(info -> InputFormat)) {
1197 wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
1198 wIn[1] = (cmsFloat32Number) (Pt[Stride] / MAX_ENCODEABLE_XYZ);
1199 wIn[2] = (cmsFloat32Number) (Pt[Stride*2] / MAX_ENCODEABLE_XYZ);
1201 return accum + sizeof(cmsFloat32Number);
1205 wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
1206 wIn[1] = (cmsFloat32Number) (Pt[1] / MAX_ENCODEABLE_XYZ);
1207 wIn[2] = (cmsFloat32Number) (Pt[2] / MAX_ENCODEABLE_XYZ);
1209 accum += sizeof(cmsFloat32Number)*(3 + T_EXTRA(info ->InputFormat));
1216 // Packing routines -----------------------------------------------------------------------------------------------------------
1219 // Generic chunky for byte
1222 cmsUInt8Number* PackAnyBytes(register _cmsTRANSFORM* info,
1223 register cmsUInt16Number wOut[],
1224 register cmsUInt8Number* output,
1225 register cmsUInt32Number Stride)
1227 int nChan = T_CHANNELS(info -> OutputFormat);
1228 int DoSwap = T_DOSWAP(info ->OutputFormat);
1229 int Reverse = T_FLAVOR(info ->OutputFormat);
1230 int Extra = T_EXTRA(info -> OutputFormat);
1231 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
1232 int ExtraFirst = DoSwap ^ SwapFirst;
1233 cmsUInt8Number* swap1;
1234 cmsUInt8Number v = 0;
1243 for (i=0; i < nChan; i++) {
1245 int index = DoSwap ? (nChan - i - 1) : i;
1247 v = FROM_16_TO_8(wOut[index]);
1250 v = REVERSE_FLAVOR_8(v);
1259 if (Extra == 0 && SwapFirst) {
1261 memmove(swap1 + 1, swap1, nChan-1);
1268 cmsUNUSED_PARAMETER(Stride);
1274 cmsUInt8Number* PackAnyWords(register _cmsTRANSFORM* info,
1275 register cmsUInt16Number wOut[],
1276 register cmsUInt8Number* output,
1277 register cmsUInt32Number Stride)
1279 int nChan = T_CHANNELS(info -> OutputFormat);
1280 int SwapEndian = T_ENDIAN16(info -> InputFormat);
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 cmsUInt16Number* swap1;
1287 cmsUInt16Number v = 0;
1290 swap1 = (cmsUInt16Number*) output;
1293 output += Extra * sizeof(cmsUInt16Number);
1296 for (i=0; i < nChan; i++) {
1298 int index = DoSwap ? (nChan - i - 1) : i;
1303 v = CHANGE_ENDIAN(v);
1306 v = REVERSE_FLAVOR_16(v);
1308 *(cmsUInt16Number*) output = v;
1310 output += sizeof(cmsUInt16Number);
1314 output += Extra * sizeof(cmsUInt16Number);
1317 if (Extra == 0 && SwapFirst) {
1319 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number));
1326 cmsUNUSED_PARAMETER(Stride);
1331 cmsUInt8Number* PackPlanarBytes(register _cmsTRANSFORM* info,
1332 register cmsUInt16Number wOut[],
1333 register cmsUInt8Number* output,
1334 register cmsUInt32Number Stride)
1336 int nChan = T_CHANNELS(info -> OutputFormat);
1337 int DoSwap = T_DOSWAP(info ->OutputFormat);
1338 int SwapFirst = T_SWAPFIRST(info ->OutputFormat);
1339 int Reverse = T_FLAVOR(info ->OutputFormat);
1341 cmsUInt8Number* Init = output;
1344 if (DoSwap ^ SwapFirst) {
1345 output += T_EXTRA(info -> OutputFormat) * Stride;
1349 for (i=0; i < nChan; i++) {
1351 int index = DoSwap ? (nChan - i - 1) : i;
1352 cmsUInt8Number v = FROM_16_TO_8(wOut[index]);
1354 *(cmsUInt8Number*) output = (cmsUInt8Number) (Reverse ? REVERSE_FLAVOR_8(v) : v);
1360 cmsUNUSED_PARAMETER(Stride);
1365 cmsUInt8Number* PackPlanarWords(register _cmsTRANSFORM* info,
1366 register cmsUInt16Number wOut[],
1367 register cmsUInt8Number* output,
1368 register cmsUInt32Number Stride)
1370 int nChan = T_CHANNELS(info -> OutputFormat);
1371 int DoSwap = T_DOSWAP(info ->OutputFormat);
1372 int Reverse= T_FLAVOR(info ->OutputFormat);
1373 int SwapEndian = T_ENDIAN16(info -> OutputFormat);
1375 cmsUInt8Number* Init = output;
1379 output += T_EXTRA(info -> OutputFormat) * Stride * sizeof(cmsUInt16Number);
1382 for (i=0; i < nChan; i++) {
1384 int index = DoSwap ? (nChan - i - 1) : i;
1389 v = CHANGE_ENDIAN(v);
1392 v = REVERSE_FLAVOR_16(v);
1394 *(cmsUInt16Number*) output = v;
1395 output += (Stride * sizeof(cmsUInt16Number));
1398 return (Init + sizeof(cmsUInt16Number));
1401 // CMYKcm (unrolled for speed)
1404 cmsUInt8Number* Pack6Bytes(register _cmsTRANSFORM* info,
1405 register cmsUInt16Number wOut[],
1406 register cmsUInt8Number* output,
1407 register cmsUInt32Number Stride)
1409 *output++ = FROM_16_TO_8(wOut[0]);
1410 *output++ = FROM_16_TO_8(wOut[1]);
1411 *output++ = FROM_16_TO_8(wOut[2]);
1412 *output++ = FROM_16_TO_8(wOut[3]);
1413 *output++ = FROM_16_TO_8(wOut[4]);
1414 *output++ = FROM_16_TO_8(wOut[5]);
1418 cmsUNUSED_PARAMETER(info);
1419 cmsUNUSED_PARAMETER(Stride);
1425 cmsUInt8Number* Pack6BytesSwap(register _cmsTRANSFORM* info,
1426 register cmsUInt16Number wOut[],
1427 register cmsUInt8Number* output,
1428 register cmsUInt32Number Stride)
1430 *output++ = FROM_16_TO_8(wOut[5]);
1431 *output++ = FROM_16_TO_8(wOut[4]);
1432 *output++ = FROM_16_TO_8(wOut[3]);
1433 *output++ = FROM_16_TO_8(wOut[2]);
1434 *output++ = FROM_16_TO_8(wOut[1]);
1435 *output++ = FROM_16_TO_8(wOut[0]);
1439 cmsUNUSED_PARAMETER(info);
1440 cmsUNUSED_PARAMETER(Stride);
1445 cmsUInt8Number* Pack6Words(register _cmsTRANSFORM* info,
1446 register cmsUInt16Number wOut[],
1447 register cmsUInt8Number* output,
1448 register cmsUInt32Number Stride)
1450 *(cmsUInt16Number*) output = wOut[0];
1452 *(cmsUInt16Number*) output = wOut[1];
1454 *(cmsUInt16Number*) output = wOut[2];
1456 *(cmsUInt16Number*) output = wOut[3];
1458 *(cmsUInt16Number*) output = wOut[4];
1460 *(cmsUInt16Number*) output = wOut[5];
1465 cmsUNUSED_PARAMETER(info);
1466 cmsUNUSED_PARAMETER(Stride);
1471 cmsUInt8Number* Pack6WordsSwap(register _cmsTRANSFORM* info,
1472 register cmsUInt16Number wOut[],
1473 register cmsUInt8Number* output,
1474 register cmsUInt32Number Stride)
1476 *(cmsUInt16Number*) output = wOut[5];
1478 *(cmsUInt16Number*) output = wOut[4];
1480 *(cmsUInt16Number*) output = wOut[3];
1482 *(cmsUInt16Number*) output = wOut[2];
1484 *(cmsUInt16Number*) output = wOut[1];
1486 *(cmsUInt16Number*) output = wOut[0];
1491 cmsUNUSED_PARAMETER(info);
1492 cmsUNUSED_PARAMETER(Stride);
1497 cmsUInt8Number* Pack4Bytes(register _cmsTRANSFORM* info,
1498 register cmsUInt16Number wOut[],
1499 register cmsUInt8Number* output,
1500 register cmsUInt32Number Stride)
1502 *output++ = FROM_16_TO_8(wOut[0]);
1503 *output++ = FROM_16_TO_8(wOut[1]);
1504 *output++ = FROM_16_TO_8(wOut[2]);
1505 *output++ = FROM_16_TO_8(wOut[3]);
1509 cmsUNUSED_PARAMETER(info);
1510 cmsUNUSED_PARAMETER(Stride);
1514 cmsUInt8Number* Pack4BytesReverse(register _cmsTRANSFORM* info,
1515 register cmsUInt16Number wOut[],
1516 register cmsUInt8Number* output,
1517 register cmsUInt32Number Stride)
1519 *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[0]));
1520 *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[1]));
1521 *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[2]));
1522 *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[3]));
1526 cmsUNUSED_PARAMETER(info);
1527 cmsUNUSED_PARAMETER(Stride);
1532 cmsUInt8Number* Pack4BytesSwapFirst(register _cmsTRANSFORM* info,
1533 register cmsUInt16Number wOut[],
1534 register cmsUInt8Number* output,
1535 register cmsUInt32Number Stride)
1537 *output++ = FROM_16_TO_8(wOut[3]);
1538 *output++ = FROM_16_TO_8(wOut[0]);
1539 *output++ = FROM_16_TO_8(wOut[1]);
1540 *output++ = FROM_16_TO_8(wOut[2]);
1544 cmsUNUSED_PARAMETER(info);
1545 cmsUNUSED_PARAMETER(Stride);
1550 cmsUInt8Number* Pack4BytesSwap(register _cmsTRANSFORM* info,
1551 register cmsUInt16Number wOut[],
1552 register cmsUInt8Number* output,
1553 register cmsUInt32Number Stride)
1555 *output++ = FROM_16_TO_8(wOut[3]);
1556 *output++ = FROM_16_TO_8(wOut[2]);
1557 *output++ = FROM_16_TO_8(wOut[1]);
1558 *output++ = FROM_16_TO_8(wOut[0]);
1562 cmsUNUSED_PARAMETER(info);
1563 cmsUNUSED_PARAMETER(Stride);
1567 cmsUInt8Number* Pack4BytesSwapSwapFirst(register _cmsTRANSFORM* info,
1568 register cmsUInt16Number wOut[],
1569 register cmsUInt8Number* output,
1570 register cmsUInt32Number Stride)
1572 *output++ = FROM_16_TO_8(wOut[2]);
1573 *output++ = FROM_16_TO_8(wOut[1]);
1574 *output++ = FROM_16_TO_8(wOut[0]);
1575 *output++ = FROM_16_TO_8(wOut[3]);
1579 cmsUNUSED_PARAMETER(info);
1580 cmsUNUSED_PARAMETER(Stride);
1584 cmsUInt8Number* Pack4Words(register _cmsTRANSFORM* info,
1585 register cmsUInt16Number wOut[],
1586 register cmsUInt8Number* output,
1587 register cmsUInt32Number Stride)
1589 *(cmsUInt16Number*) output = wOut[0];
1591 *(cmsUInt16Number*) output = wOut[1];
1593 *(cmsUInt16Number*) output = wOut[2];
1595 *(cmsUInt16Number*) output = wOut[3];
1600 cmsUNUSED_PARAMETER(info);
1601 cmsUNUSED_PARAMETER(Stride);
1605 cmsUInt8Number* Pack4WordsReverse(register _cmsTRANSFORM* info,
1606 register cmsUInt16Number wOut[],
1607 register cmsUInt8Number* output,
1608 register cmsUInt32Number Stride)
1610 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[0]);
1612 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[1]);
1614 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[2]);
1616 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[3]);
1621 cmsUNUSED_PARAMETER(info);
1622 cmsUNUSED_PARAMETER(Stride);
1627 cmsUInt8Number* Pack4WordsSwap(register _cmsTRANSFORM* info,
1628 register cmsUInt16Number wOut[],
1629 register cmsUInt8Number* output,
1630 register cmsUInt32Number Stride)
1632 *(cmsUInt16Number*) output = wOut[3];
1634 *(cmsUInt16Number*) output = wOut[2];
1636 *(cmsUInt16Number*) output = wOut[1];
1638 *(cmsUInt16Number*) output = wOut[0];
1643 cmsUNUSED_PARAMETER(info);
1644 cmsUNUSED_PARAMETER(Stride);
1649 cmsUInt8Number* Pack4WordsBigEndian(register _cmsTRANSFORM* info,
1650 register cmsUInt16Number wOut[],
1651 register cmsUInt8Number* output,
1652 register cmsUInt32Number Stride)
1654 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
1656 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[1]);
1658 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[2]);
1660 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[3]);
1665 cmsUNUSED_PARAMETER(info);
1666 cmsUNUSED_PARAMETER(Stride);
1671 cmsUInt8Number* PackLabV2_8(register _cmsTRANSFORM* info,
1672 register cmsUInt16Number wOut[],
1673 register cmsUInt8Number* output,
1674 register cmsUInt32Number Stride)
1676 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[0]));
1677 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[1]));
1678 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[2]));
1682 cmsUNUSED_PARAMETER(info);
1683 cmsUNUSED_PARAMETER(Stride);
1687 cmsUInt8Number* PackALabV2_8(register _cmsTRANSFORM* info,
1688 register cmsUInt16Number wOut[],
1689 register cmsUInt8Number* output,
1690 register cmsUInt32Number Stride)
1693 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[0]));
1694 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[1]));
1695 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[2]));
1699 cmsUNUSED_PARAMETER(info);
1700 cmsUNUSED_PARAMETER(Stride);
1704 cmsUInt8Number* PackLabV2_16(register _cmsTRANSFORM* info,
1705 register cmsUInt16Number wOut[],
1706 register cmsUInt8Number* output,
1707 register cmsUInt32Number Stride)
1709 *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[0]);
1711 *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[1]);
1713 *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[2]);
1718 cmsUNUSED_PARAMETER(info);
1719 cmsUNUSED_PARAMETER(Stride);
1723 cmsUInt8Number* Pack3Bytes(register _cmsTRANSFORM* info,
1724 register cmsUInt16Number wOut[],
1725 register cmsUInt8Number* output,
1726 register cmsUInt32Number Stride)
1728 *output++ = FROM_16_TO_8(wOut[0]);
1729 *output++ = FROM_16_TO_8(wOut[1]);
1730 *output++ = FROM_16_TO_8(wOut[2]);
1734 cmsUNUSED_PARAMETER(info);
1735 cmsUNUSED_PARAMETER(Stride);
1739 cmsUInt8Number* Pack3BytesOptimized(register _cmsTRANSFORM* info,
1740 register cmsUInt16Number wOut[],
1741 register cmsUInt8Number* output,
1742 register cmsUInt32Number Stride)
1744 *output++ = (wOut[0] & 0xFF);
1745 *output++ = (wOut[1] & 0xFF);
1746 *output++ = (wOut[2] & 0xFF);
1750 cmsUNUSED_PARAMETER(info);
1751 cmsUNUSED_PARAMETER(Stride);
1755 cmsUInt8Number* Pack3BytesSwap(register _cmsTRANSFORM* info,
1756 register cmsUInt16Number wOut[],
1757 register cmsUInt8Number* output,
1758 register cmsUInt32Number Stride)
1760 *output++ = FROM_16_TO_8(wOut[2]);
1761 *output++ = FROM_16_TO_8(wOut[1]);
1762 *output++ = FROM_16_TO_8(wOut[0]);
1766 cmsUNUSED_PARAMETER(info);
1767 cmsUNUSED_PARAMETER(Stride);
1771 cmsUInt8Number* Pack3BytesSwapOptimized(register _cmsTRANSFORM* info,
1772 register cmsUInt16Number wOut[],
1773 register cmsUInt8Number* output,
1774 register cmsUInt32Number Stride)
1776 *output++ = (wOut[2] & 0xFF);
1777 *output++ = (wOut[1] & 0xFF);
1778 *output++ = (wOut[0] & 0xFF);
1782 cmsUNUSED_PARAMETER(info);
1783 cmsUNUSED_PARAMETER(Stride);
1788 cmsUInt8Number* Pack3Words(register _cmsTRANSFORM* info,
1789 register cmsUInt16Number wOut[],
1790 register cmsUInt8Number* output,
1791 register cmsUInt32Number Stride)
1793 *(cmsUInt16Number*) output = wOut[0];
1795 *(cmsUInt16Number*) output = wOut[1];
1797 *(cmsUInt16Number*) output = wOut[2];
1802 cmsUNUSED_PARAMETER(info);
1803 cmsUNUSED_PARAMETER(Stride);
1807 cmsUInt8Number* Pack3WordsSwap(register _cmsTRANSFORM* info,
1808 register cmsUInt16Number wOut[],
1809 register cmsUInt8Number* output,
1810 register cmsUInt32Number Stride)
1812 *(cmsUInt16Number*) output = wOut[2];
1814 *(cmsUInt16Number*) output = wOut[1];
1816 *(cmsUInt16Number*) output = wOut[0];
1821 cmsUNUSED_PARAMETER(info);
1822 cmsUNUSED_PARAMETER(Stride);
1826 cmsUInt8Number* Pack3WordsBigEndian(register _cmsTRANSFORM* info,
1827 register cmsUInt16Number wOut[],
1828 register cmsUInt8Number* output,
1829 register cmsUInt32Number Stride)
1831 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
1833 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[1]);
1835 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[2]);
1840 cmsUNUSED_PARAMETER(info);
1841 cmsUNUSED_PARAMETER(Stride);
1845 cmsUInt8Number* Pack3BytesAndSkip1(register _cmsTRANSFORM* info,
1846 register cmsUInt16Number wOut[],
1847 register cmsUInt8Number* output,
1848 register cmsUInt32Number Stride)
1850 *output++ = FROM_16_TO_8(wOut[0]);
1851 *output++ = FROM_16_TO_8(wOut[1]);
1852 *output++ = FROM_16_TO_8(wOut[2]);
1857 cmsUNUSED_PARAMETER(info);
1858 cmsUNUSED_PARAMETER(Stride);
1862 cmsUInt8Number* Pack3BytesAndSkip1Optimized(register _cmsTRANSFORM* info,
1863 register cmsUInt16Number wOut[],
1864 register cmsUInt8Number* output,
1865 register cmsUInt32Number Stride)
1867 *output++ = (wOut[0] & 0xFF);
1868 *output++ = (wOut[1] & 0xFF);
1869 *output++ = (wOut[2] & 0xFF);
1874 cmsUNUSED_PARAMETER(info);
1875 cmsUNUSED_PARAMETER(Stride);
1880 cmsUInt8Number* Pack3BytesAndSkip1SwapFirst(register _cmsTRANSFORM* info,
1881 register cmsUInt16Number wOut[],
1882 register cmsUInt8Number* output,
1883 register cmsUInt32Number Stride)
1886 *output++ = FROM_16_TO_8(wOut[0]);
1887 *output++ = FROM_16_TO_8(wOut[1]);
1888 *output++ = FROM_16_TO_8(wOut[2]);
1892 cmsUNUSED_PARAMETER(info);
1893 cmsUNUSED_PARAMETER(Stride);
1897 cmsUInt8Number* Pack3BytesAndSkip1SwapFirstOptimized(register _cmsTRANSFORM* info,
1898 register cmsUInt16Number wOut[],
1899 register cmsUInt8Number* output,
1900 register cmsUInt32Number Stride)
1903 *output++ = (wOut[0] & 0xFF);
1904 *output++ = (wOut[1] & 0xFF);
1905 *output++ = (wOut[2] & 0xFF);
1909 cmsUNUSED_PARAMETER(info);
1910 cmsUNUSED_PARAMETER(Stride);
1914 cmsUInt8Number* Pack3BytesAndSkip1Swap(register _cmsTRANSFORM* info,
1915 register cmsUInt16Number wOut[],
1916 register cmsUInt8Number* output,
1917 register cmsUInt32Number Stride)
1920 *output++ = FROM_16_TO_8(wOut[2]);
1921 *output++ = FROM_16_TO_8(wOut[1]);
1922 *output++ = FROM_16_TO_8(wOut[0]);
1926 cmsUNUSED_PARAMETER(info);
1927 cmsUNUSED_PARAMETER(Stride);
1931 cmsUInt8Number* Pack3BytesAndSkip1SwapOptimized(register _cmsTRANSFORM* info,
1932 register cmsUInt16Number wOut[],
1933 register cmsUInt8Number* output,
1934 register cmsUInt32Number Stride)
1937 *output++ = (wOut[2] & 0xFF);
1938 *output++ = (wOut[1] & 0xFF);
1939 *output++ = (wOut[0] & 0xFF);
1943 cmsUNUSED_PARAMETER(info);
1944 cmsUNUSED_PARAMETER(Stride);
1949 cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirst(register _cmsTRANSFORM* info,
1950 register cmsUInt16Number wOut[],
1951 register cmsUInt8Number* output,
1952 register cmsUInt32Number Stride)
1954 *output++ = FROM_16_TO_8(wOut[2]);
1955 *output++ = FROM_16_TO_8(wOut[1]);
1956 *output++ = FROM_16_TO_8(wOut[0]);
1961 cmsUNUSED_PARAMETER(info);
1962 cmsUNUSED_PARAMETER(Stride);
1966 cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirstOptimized(register _cmsTRANSFORM* info,
1967 register cmsUInt16Number wOut[],
1968 register cmsUInt8Number* output,
1969 register cmsUInt32Number Stride)
1971 *output++ = (wOut[2] & 0xFF);
1972 *output++ = (wOut[1] & 0xFF);
1973 *output++ = (wOut[0] & 0xFF);
1978 cmsUNUSED_PARAMETER(info);
1979 cmsUNUSED_PARAMETER(Stride);
1983 cmsUInt8Number* Pack3WordsAndSkip1(register _cmsTRANSFORM* info,
1984 register cmsUInt16Number wOut[],
1985 register cmsUInt8Number* output,
1986 register cmsUInt32Number Stride)
1988 *(cmsUInt16Number*) output = wOut[0];
1990 *(cmsUInt16Number*) output = wOut[1];
1992 *(cmsUInt16Number*) output = wOut[2];
1998 cmsUNUSED_PARAMETER(info);
1999 cmsUNUSED_PARAMETER(Stride);
2003 cmsUInt8Number* Pack3WordsAndSkip1Swap(register _cmsTRANSFORM* info,
2004 register cmsUInt16Number wOut[],
2005 register cmsUInt8Number* output,
2006 register cmsUInt32Number Stride)
2009 *(cmsUInt16Number*) output = wOut[2];
2011 *(cmsUInt16Number*) output = wOut[1];
2013 *(cmsUInt16Number*) output = wOut[0];
2018 cmsUNUSED_PARAMETER(info);
2019 cmsUNUSED_PARAMETER(Stride);
2024 cmsUInt8Number* Pack3WordsAndSkip1SwapFirst(register _cmsTRANSFORM* info,
2025 register cmsUInt16Number wOut[],
2026 register cmsUInt8Number* output,
2027 register cmsUInt32Number Stride)
2030 *(cmsUInt16Number*) output = wOut[0];
2032 *(cmsUInt16Number*) output = wOut[1];
2034 *(cmsUInt16Number*) output = wOut[2];
2039 cmsUNUSED_PARAMETER(info);
2040 cmsUNUSED_PARAMETER(Stride);
2045 cmsUInt8Number* Pack3WordsAndSkip1SwapSwapFirst(register _cmsTRANSFORM* info,
2046 register cmsUInt16Number wOut[],
2047 register cmsUInt8Number* output,
2048 register cmsUInt32Number Stride)
2050 *(cmsUInt16Number*) output = wOut[2];
2052 *(cmsUInt16Number*) output = wOut[1];
2054 *(cmsUInt16Number*) output = wOut[0];
2060 cmsUNUSED_PARAMETER(info);
2061 cmsUNUSED_PARAMETER(Stride);
2067 cmsUInt8Number* Pack1Byte(register _cmsTRANSFORM* info,
2068 register cmsUInt16Number wOut[],
2069 register cmsUInt8Number* output,
2070 register cmsUInt32Number Stride)
2072 *output++ = FROM_16_TO_8(wOut[0]);
2076 cmsUNUSED_PARAMETER(info);
2077 cmsUNUSED_PARAMETER(Stride);
2082 cmsUInt8Number* Pack1ByteReversed(register _cmsTRANSFORM* info,
2083 register cmsUInt16Number wOut[],
2084 register cmsUInt8Number* output,
2085 register cmsUInt32Number Stride)
2087 *output++ = FROM_16_TO_8(REVERSE_FLAVOR_16(wOut[0]));
2091 cmsUNUSED_PARAMETER(info);
2092 cmsUNUSED_PARAMETER(Stride);
2097 cmsUInt8Number* Pack1ByteSkip1(register _cmsTRANSFORM* info,
2098 register cmsUInt16Number wOut[],
2099 register cmsUInt8Number* output,
2100 register cmsUInt32Number Stride)
2102 *output++ = FROM_16_TO_8(wOut[0]);
2107 cmsUNUSED_PARAMETER(info);
2108 cmsUNUSED_PARAMETER(Stride);
2113 cmsUInt8Number* Pack1ByteSkip1SwapFirst(register _cmsTRANSFORM* info,
2114 register cmsUInt16Number wOut[],
2115 register cmsUInt8Number* output,
2116 register cmsUInt32Number Stride)
2119 *output++ = FROM_16_TO_8(wOut[0]);
2123 cmsUNUSED_PARAMETER(info);
2124 cmsUNUSED_PARAMETER(Stride);
2128 cmsUInt8Number* Pack1Word(register _cmsTRANSFORM* info,
2129 register cmsUInt16Number wOut[],
2130 register cmsUInt8Number* output,
2131 register cmsUInt32Number Stride)
2133 *(cmsUInt16Number*) output = wOut[0];
2138 cmsUNUSED_PARAMETER(info);
2139 cmsUNUSED_PARAMETER(Stride);
2144 cmsUInt8Number* Pack1WordReversed(register _cmsTRANSFORM* info,
2145 register cmsUInt16Number wOut[],
2146 register cmsUInt8Number* output,
2147 register cmsUInt32Number Stride)
2149 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[0]);
2154 cmsUNUSED_PARAMETER(info);
2155 cmsUNUSED_PARAMETER(Stride);
2159 cmsUInt8Number* Pack1WordBigEndian(register _cmsTRANSFORM* info,
2160 register cmsUInt16Number wOut[],
2161 register cmsUInt8Number* output,
2162 register cmsUInt32Number Stride)
2164 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
2169 cmsUNUSED_PARAMETER(info);
2170 cmsUNUSED_PARAMETER(Stride);
2175 cmsUInt8Number* Pack1WordSkip1(register _cmsTRANSFORM* info,
2176 register cmsUInt16Number wOut[],
2177 register cmsUInt8Number* output,
2178 register cmsUInt32Number Stride)
2180 *(cmsUInt16Number*) output = wOut[0];
2185 cmsUNUSED_PARAMETER(info);
2186 cmsUNUSED_PARAMETER(Stride);
2190 cmsUInt8Number* Pack1WordSkip1SwapFirst(register _cmsTRANSFORM* info,
2191 register cmsUInt16Number wOut[],
2192 register cmsUInt8Number* output,
2193 register cmsUInt32Number Stride)
2196 *(cmsUInt16Number*) output = wOut[0];
2201 cmsUNUSED_PARAMETER(info);
2202 cmsUNUSED_PARAMETER(Stride);
2206 // Unencoded Float values -- don't try optimize speed
2208 cmsUInt8Number* PackLabDoubleFrom16(register _cmsTRANSFORM* info,
2209 register cmsUInt16Number wOut[],
2210 register cmsUInt8Number* output,
2211 register cmsUInt32Number Stride)
2214 if (T_PLANAR(info -> OutputFormat)) {
2217 cmsFloat64Number* Out = (cmsFloat64Number*) output;
2218 cmsLabEncoded2Float(&Lab, wOut);
2221 Out[Stride] = Lab.a;
2222 Out[Stride*2] = Lab.b;
2224 return output + sizeof(cmsFloat64Number);
2228 cmsLabEncoded2Float((cmsCIELab*) output, wOut);
2229 return output + (sizeof(cmsCIELab) + T_EXTRA(info ->OutputFormat) * sizeof(cmsFloat64Number));
2235 cmsUInt8Number* PackLabFloatFrom16(register _cmsTRANSFORM* info,
2236 register cmsUInt16Number wOut[],
2237 register cmsUInt8Number* output,
2238 register cmsUInt32Number Stride)
2241 cmsLabEncoded2Float(&Lab, wOut);
2243 if (T_PLANAR(info -> OutputFormat)) {
2245 cmsFloat32Number* Out = (cmsFloat32Number*) output;
2247 Out[0] = (cmsFloat32Number)Lab.L;
2248 Out[Stride] = (cmsFloat32Number)Lab.a;
2249 Out[Stride*2] = (cmsFloat32Number)Lab.b;
2251 return output + sizeof(cmsFloat32Number);
2255 ((cmsFloat32Number*) output)[0] = (cmsFloat32Number) Lab.L;
2256 ((cmsFloat32Number*) output)[1] = (cmsFloat32Number) Lab.a;
2257 ((cmsFloat32Number*) output)[2] = (cmsFloat32Number) Lab.b;
2259 return output + (3 + T_EXTRA(info ->OutputFormat)) * sizeof(cmsFloat32Number);
2264 cmsUInt8Number* PackXYZDoubleFrom16(register _cmsTRANSFORM* Info,
2265 register cmsUInt16Number wOut[],
2266 register cmsUInt8Number* output,
2267 register cmsUInt32Number Stride)
2269 if (T_PLANAR(Info -> OutputFormat)) {
2272 cmsFloat64Number* Out = (cmsFloat64Number*) output;
2273 cmsXYZEncoded2Float(&XYZ, wOut);
2276 Out[Stride] = XYZ.Y;
2277 Out[Stride*2] = XYZ.Z;
2279 return output + sizeof(cmsFloat64Number);
2284 cmsXYZEncoded2Float((cmsCIEXYZ*) output, wOut);
2286 return output + (sizeof(cmsCIEXYZ) + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
2291 cmsUInt8Number* PackDoubleFrom16(register _cmsTRANSFORM* info,
2292 register cmsUInt16Number wOut[],
2293 register cmsUInt8Number* output,
2294 register cmsUInt32Number Stride)
2296 int nChan = T_CHANNELS(info -> OutputFormat);
2297 int DoSwap = T_DOSWAP(info ->OutputFormat);
2298 int Reverse = T_FLAVOR(info ->OutputFormat);
2299 int Extra = T_EXTRA(info -> OutputFormat);
2300 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2301 int Planar = T_PLANAR(info -> OutputFormat);
2302 int ExtraFirst = DoSwap ^ SwapFirst;
2303 cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35 : 65535.0;
2304 cmsFloat64Number v = 0;
2305 cmsFloat64Number* swap1 = (cmsFloat64Number*) output;
2311 for (i=0; i < nChan; i++) {
2313 int index = DoSwap ? (nChan - i - 1) : i;
2315 v = (cmsFloat64Number) wOut[index] / maximum;
2321 ((cmsFloat64Number*) output)[(i + start) * Stride]= v;
2323 ((cmsFloat64Number*) output)[i + start] = v;
2327 output += Extra * sizeof(cmsFloat64Number);
2330 if (Extra == 0 && SwapFirst) {
2332 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat64Number));
2336 if (T_PLANAR(info -> OutputFormat))
2337 return output + sizeof(cmsFloat64Number);
2339 return output + nChan * sizeof(cmsFloat64Number);
2345 cmsUInt8Number* PackFloatFrom16(register _cmsTRANSFORM* info,
2346 register cmsUInt16Number wOut[],
2347 register cmsUInt8Number* output,
2348 register cmsUInt32Number Stride)
2350 int nChan = T_CHANNELS(info -> OutputFormat);
2351 int DoSwap = T_DOSWAP(info ->OutputFormat);
2352 int Reverse = T_FLAVOR(info ->OutputFormat);
2353 int Extra = T_EXTRA(info -> OutputFormat);
2354 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2355 int Planar = T_PLANAR(info -> OutputFormat);
2356 int ExtraFirst = DoSwap ^ SwapFirst;
2357 cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35 : 65535.0;
2358 cmsFloat64Number v = 0;
2359 cmsFloat32Number* swap1 = (cmsFloat32Number*) output;
2365 for (i=0; i < nChan; i++) {
2367 int index = DoSwap ? (nChan - i - 1) : i;
2369 v = (cmsFloat64Number) wOut[index] / maximum;
2375 ((cmsFloat32Number*) output)[(i + start ) * Stride]= (cmsFloat32Number) v;
2377 ((cmsFloat32Number*) output)[i + start] = (cmsFloat32Number) v;
2381 output += Extra * sizeof(cmsFloat32Number);
2384 if (Extra == 0 && SwapFirst) {
2386 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat32Number));
2387 *swap1 = (cmsFloat32Number) v;
2390 if (T_PLANAR(info -> OutputFormat))
2391 return output + sizeof(cmsFloat32Number);
2393 return output + nChan * sizeof(cmsFloat32Number);
2398 // --------------------------------------------------------------------------------------------------------
2401 cmsUInt8Number* PackFloatsFromFloat(_cmsTRANSFORM* info,
2402 cmsFloat32Number wOut[],
2403 cmsUInt8Number* output,
2404 cmsUInt32Number Stride)
2406 int nChan = T_CHANNELS(info -> OutputFormat);
2407 int DoSwap = T_DOSWAP(info ->OutputFormat);
2408 int Reverse = T_FLAVOR(info ->OutputFormat);
2409 int Extra = T_EXTRA(info -> OutputFormat);
2410 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2411 int Planar = T_PLANAR(info -> OutputFormat);
2412 int ExtraFirst = DoSwap ^ SwapFirst;
2413 cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
2414 cmsFloat32Number* swap1 = (cmsFloat32Number*) output;
2415 cmsFloat64Number v = 0;
2421 for (i=0; i < nChan; i++) {
2423 int index = DoSwap ? (nChan - i - 1) : i;
2425 v = wOut[index] * maximum;
2431 ((cmsFloat32Number*) output)[(i + start)* Stride]= (cmsFloat32Number) v;
2433 ((cmsFloat32Number*) output)[i + start] = (cmsFloat32Number) v;
2437 output += Extra * sizeof(cmsFloat32Number);
2440 if (Extra == 0 && SwapFirst) {
2442 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat32Number));
2443 *swap1 = (cmsFloat32Number) v;
2446 if (T_PLANAR(info -> OutputFormat))
2447 return output + sizeof(cmsFloat32Number);
2449 return output + nChan * sizeof(cmsFloat32Number);
2453 cmsUInt8Number* PackDoublesFromFloat(_cmsTRANSFORM* info,
2454 cmsFloat32Number wOut[],
2455 cmsUInt8Number* output,
2456 cmsUInt32Number Stride)
2458 int nChan = T_CHANNELS(info -> OutputFormat);
2459 int DoSwap = T_DOSWAP(info ->OutputFormat);
2460 int Reverse = T_FLAVOR(info ->OutputFormat);
2461 int Extra = T_EXTRA(info -> OutputFormat);
2462 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2463 int Planar = T_PLANAR(info -> OutputFormat);
2464 int ExtraFirst = DoSwap ^ SwapFirst;
2465 cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
2466 cmsFloat64Number v = 0;
2467 cmsFloat64Number* swap1 = (cmsFloat64Number*) output;
2473 for (i=0; i < nChan; i++) {
2475 int index = DoSwap ? (nChan - i - 1) : i;
2477 v = wOut[index] * maximum;
2483 ((cmsFloat64Number*) output)[(i + start) * Stride] = v;
2485 ((cmsFloat64Number*) output)[i + start] = v;
2489 output += Extra * sizeof(cmsFloat64Number);
2492 if (Extra == 0 && SwapFirst) {
2494 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat64Number));
2499 if (T_PLANAR(info -> OutputFormat))
2500 return output + sizeof(cmsFloat64Number);
2502 return output + nChan * sizeof(cmsFloat64Number);
2511 cmsUInt8Number* PackLabFloatFromFloat(_cmsTRANSFORM* Info,
2512 cmsFloat32Number wOut[],
2513 cmsUInt8Number* output,
2514 cmsUInt32Number Stride)
2516 cmsFloat32Number* Out = (cmsFloat32Number*) output;
2518 if (T_PLANAR(Info -> OutputFormat)) {
2520 Out[0] = (cmsFloat32Number) (wOut[0] * 100.0);
2521 Out[Stride] = (cmsFloat32Number) (wOut[1] * 255.0 - 128.0);
2522 Out[Stride*2] = (cmsFloat32Number) (wOut[2] * 255.0 - 128.0);
2524 return output + sizeof(cmsFloat32Number);
2528 Out[0] = (cmsFloat32Number) (wOut[0] * 100.0);
2529 Out[1] = (cmsFloat32Number) (wOut[1] * 255.0 - 128.0);
2530 Out[2] = (cmsFloat32Number) (wOut[2] * 255.0 - 128.0);
2532 return output + (sizeof(cmsFloat32Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
2539 cmsUInt8Number* PackLabDoubleFromFloat(_cmsTRANSFORM* Info,
2540 cmsFloat32Number wOut[],
2541 cmsUInt8Number* output,
2542 cmsUInt32Number Stride)
2544 cmsFloat64Number* Out = (cmsFloat64Number*) output;
2546 if (T_PLANAR(Info -> OutputFormat)) {
2548 Out[0] = (cmsFloat64Number) (wOut[0] * 100.0);
2549 Out[Stride] = (cmsFloat64Number) (wOut[1] * 255.0 - 128.0);
2550 Out[Stride*2] = (cmsFloat64Number) (wOut[2] * 255.0 - 128.0);
2552 return output + sizeof(cmsFloat64Number);
2556 Out[0] = (cmsFloat64Number) (wOut[0] * 100.0);
2557 Out[1] = (cmsFloat64Number) (wOut[1] * 255.0 - 128.0);
2558 Out[2] = (cmsFloat64Number) (wOut[2] * 255.0 - 128.0);
2560 return output + (sizeof(cmsFloat64Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
2566 // From 0..1 range to 0..MAX_ENCODEABLE_XYZ
2568 cmsUInt8Number* PackXYZFloatFromFloat(_cmsTRANSFORM* Info,
2569 cmsFloat32Number wOut[],
2570 cmsUInt8Number* output,
2571 cmsUInt32Number Stride)
2573 cmsFloat32Number* Out = (cmsFloat32Number*) output;
2575 if (T_PLANAR(Info -> OutputFormat)) {
2577 Out[0] = (cmsFloat32Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
2578 Out[Stride] = (cmsFloat32Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
2579 Out[Stride*2] = (cmsFloat32Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
2581 return output + sizeof(cmsFloat32Number);
2585 Out[0] = (cmsFloat32Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
2586 Out[1] = (cmsFloat32Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
2587 Out[2] = (cmsFloat32Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
2589 return output + (sizeof(cmsFloat32Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
2594 // Same, but convert to double
2596 cmsUInt8Number* PackXYZDoubleFromFloat(_cmsTRANSFORM* Info,
2597 cmsFloat32Number wOut[],
2598 cmsUInt8Number* output,
2599 cmsUInt32Number Stride)
2601 cmsFloat64Number* Out = (cmsFloat64Number*) output;
2603 if (T_PLANAR(Info -> OutputFormat)) {
2605 Out[0] = (cmsFloat64Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
2606 Out[Stride] = (cmsFloat64Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
2607 Out[Stride*2] = (cmsFloat64Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
2609 return output + sizeof(cmsFloat64Number);
2613 Out[0] = (cmsFloat64Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
2614 Out[1] = (cmsFloat64Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
2615 Out[2] = (cmsFloat64Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
2617 return output + (sizeof(cmsFloat64Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
2623 // ----------------------------------------------------------------------------------------------------------------
2625 #ifndef CMS_NO_HALF_SUPPORT
2627 // Decodes an stream of half floats to wIn[] described by input format
2630 cmsUInt8Number* UnrollHalfTo16(register _cmsTRANSFORM* info,
2631 register cmsUInt16Number wIn[],
2632 register cmsUInt8Number* accum,
2633 register cmsUInt32Number Stride)
2636 int nChan = T_CHANNELS(info -> InputFormat);
2637 int DoSwap = T_DOSWAP(info ->InputFormat);
2638 int Reverse = T_FLAVOR(info ->InputFormat);
2639 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
2640 int Extra = T_EXTRA(info -> InputFormat);
2641 int ExtraFirst = DoSwap ^ SwapFirst;
2642 int Planar = T_PLANAR(info -> InputFormat);
2645 cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 655.35F : 65535.0F;
2651 for (i=0; i < nChan; i++) {
2653 int index = DoSwap ? (nChan - i - 1) : i;
2656 v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[(i + start) * Stride] );
2658 v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[i + start] ) ;
2660 if (Reverse) v = maximum - v;
2662 wIn[index] = _cmsQuickSaturateWord(v * maximum);
2666 if (Extra == 0 && SwapFirst) {
2667 cmsUInt16Number tmp = wIn[0];
2669 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
2673 if (T_PLANAR(info -> InputFormat))
2674 return accum + sizeof(cmsUInt16Number);
2676 return accum + (nChan + Extra) * sizeof(cmsUInt16Number);
2679 // Decodes an stream of half floats to wIn[] described by input format
2682 cmsUInt8Number* UnrollHalfToFloat(_cmsTRANSFORM* info,
2683 cmsFloat32Number wIn[],
2684 cmsUInt8Number* accum,
2685 cmsUInt32Number Stride)
2688 int nChan = T_CHANNELS(info -> InputFormat);
2689 int DoSwap = T_DOSWAP(info ->InputFormat);
2690 int Reverse = T_FLAVOR(info ->InputFormat);
2691 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
2692 int Extra = T_EXTRA(info -> InputFormat);
2693 int ExtraFirst = DoSwap ^ SwapFirst;
2694 int Planar = T_PLANAR(info -> InputFormat);
2697 cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 100.0F : 1.0F;
2703 for (i=0; i < nChan; i++) {
2705 int index = DoSwap ? (nChan - i - 1) : i;
2708 v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[(i + start) * Stride] );
2710 v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[i + start] ) ;
2714 wIn[index] = Reverse ? 1 - v : v;
2718 if (Extra == 0 && SwapFirst) {
2719 cmsFloat32Number tmp = wIn[0];
2721 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number));
2725 if (T_PLANAR(info -> InputFormat))
2726 return accum + sizeof(cmsUInt16Number);
2728 return accum + (nChan + Extra) * sizeof(cmsUInt16Number);
2733 cmsUInt8Number* PackHalfFrom16(register _cmsTRANSFORM* info,
2734 register cmsUInt16Number wOut[],
2735 register cmsUInt8Number* output,
2736 register cmsUInt32Number Stride)
2738 int nChan = T_CHANNELS(info -> OutputFormat);
2739 int DoSwap = T_DOSWAP(info ->OutputFormat);
2740 int Reverse = T_FLAVOR(info ->OutputFormat);
2741 int Extra = T_EXTRA(info -> OutputFormat);
2742 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2743 int Planar = T_PLANAR(info -> OutputFormat);
2744 int ExtraFirst = DoSwap ^ SwapFirst;
2745 cmsFloat32Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35F : 65535.0F;
2746 cmsFloat32Number v = 0;
2747 cmsUInt16Number* swap1 = (cmsUInt16Number*) output;
2753 for (i=0; i < nChan; i++) {
2755 int index = DoSwap ? (nChan - i - 1) : i;
2757 v = (cmsFloat32Number) wOut[index] / maximum;
2763 ((cmsUInt16Number*) output)[(i + start ) * Stride]= _cmsFloat2Half(v);
2765 ((cmsUInt16Number*) output)[i + start] = _cmsFloat2Half(v);
2769 output += Extra * sizeof(cmsUInt16Number);
2772 if (Extra == 0 && SwapFirst) {
2774 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number));
2775 *swap1 = _cmsFloat2Half(v);
2778 if (T_PLANAR(info -> OutputFormat))
2779 return output + sizeof(cmsUInt16Number);
2781 return output + nChan * sizeof(cmsUInt16Number);
2787 cmsUInt8Number* PackHalfFromFloat(_cmsTRANSFORM* info,
2788 cmsFloat32Number wOut[],
2789 cmsUInt8Number* output,
2790 cmsUInt32Number Stride)
2792 int nChan = T_CHANNELS(info -> OutputFormat);
2793 int DoSwap = T_DOSWAP(info ->OutputFormat);
2794 int Reverse = T_FLAVOR(info ->OutputFormat);
2795 int Extra = T_EXTRA(info -> OutputFormat);
2796 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2797 int Planar = T_PLANAR(info -> OutputFormat);
2798 int ExtraFirst = DoSwap ^ SwapFirst;
2799 cmsFloat32Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0F : 1.0F;
2800 cmsUInt16Number* swap1 = (cmsUInt16Number*) output;
2801 cmsFloat32Number v = 0;
2807 for (i=0; i < nChan; i++) {
2809 int index = DoSwap ? (nChan - i - 1) : i;
2811 v = wOut[index] * maximum;
2817 ((cmsUInt16Number*) output)[(i + start)* Stride]= _cmsFloat2Half( v );
2819 ((cmsUInt16Number*) output)[i + start] = _cmsFloat2Half( v );
2823 output += Extra * sizeof(cmsUInt16Number);
2826 if (Extra == 0 && SwapFirst) {
2828 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number));
2829 *swap1 = (cmsUInt16Number) _cmsFloat2Half( v );
2832 if (T_PLANAR(info -> OutputFormat))
2833 return output + sizeof(cmsUInt16Number);
2835 return output + nChan * sizeof(cmsUInt16Number);
2840 // ----------------------------------------------------------------------------------------------------------------
2843 static cmsFormatters16 InputFormatters16[] = {
2845 // Type Mask Function
2846 // ---------------------------- ------------------------------------ ----------------------------
2847 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, UnrollLabDoubleTo16},
2848 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, UnrollXYZDoubleTo16},
2849 { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, UnrollLabFloatTo16},
2850 { TYPE_GRAY_DBL, 0, UnrollDouble1Chan},
2851 { FLOAT_SH(1)|BYTES_SH(0), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR|
2852 ANYSWAP|ANYEXTRA|ANYSPACE, UnrollDoubleTo16},
2853 { FLOAT_SH(1)|BYTES_SH(4), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR|
2854 ANYSWAP|ANYEXTRA|ANYSPACE, UnrollFloatTo16},
2855 #ifndef CMS_NO_HALF_SUPPORT
2856 { FLOAT_SH(1)|BYTES_SH(2), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR|
2857 ANYEXTRA|ANYSWAP|ANYSPACE, UnrollHalfTo16},
2860 { CHANNELS_SH(1)|BYTES_SH(1), ANYSPACE, Unroll1Byte},
2861 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Unroll1ByteSkip1},
2862 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(2), ANYSPACE, Unroll1ByteSkip2},
2863 { CHANNELS_SH(1)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Unroll1ByteReversed},
2864 { COLORSPACE_SH(PT_MCH2)|CHANNELS_SH(2)|BYTES_SH(1), 0, Unroll2Bytes},
2866 { TYPE_LabV2_8, 0, UnrollLabV2_8 },
2867 { TYPE_ALabV2_8, 0, UnrollALabV2_8 },
2868 { TYPE_LabV2_16, 0, UnrollLabV2_16 },
2870 { CHANNELS_SH(3)|BYTES_SH(1), ANYSPACE, Unroll3Bytes},
2871 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3BytesSwap},
2872 { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3BytesSkip1Swap},
2873 { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll3BytesSkip1SwapFirst},
2875 { CHANNELS_SH(4)|BYTES_SH(1), ANYSPACE, Unroll4Bytes},
2876 { CHANNELS_SH(4)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Unroll4BytesReverse},
2877 { CHANNELS_SH(4)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4BytesSwapFirst},
2878 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll4BytesSwap},
2879 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4BytesSwapSwapFirst},
2881 { BYTES_SH(1)|PLANAR_SH(1), ANYFLAVOR|ANYSWAPFIRST|
2882 ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollPlanarBytes},
2884 { BYTES_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
2885 ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollChunkyBytes},
2887 { CHANNELS_SH(1)|BYTES_SH(2), ANYSPACE, Unroll1Word},
2888 { CHANNELS_SH(1)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Unroll1WordReversed},
2889 { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(3), ANYSPACE, Unroll1WordSkip3},
2891 { CHANNELS_SH(2)|BYTES_SH(2), ANYSPACE, Unroll2Words},
2892 { CHANNELS_SH(3)|BYTES_SH(2), ANYSPACE, Unroll3Words},
2893 { CHANNELS_SH(4)|BYTES_SH(2), ANYSPACE, Unroll4Words},
2895 { CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Unroll3WordsSwap},
2896 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll3WordsSkip1SwapFirst},
2897 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3WordsSkip1Swap},
2898 { CHANNELS_SH(4)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Unroll4WordsReverse},
2899 { CHANNELS_SH(4)|BYTES_SH(2)|SWAPFIRST_SH(1), ANYSPACE, Unroll4WordsSwapFirst},
2900 { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Unroll4WordsSwap},
2901 { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4WordsSwapSwapFirst},
2904 { BYTES_SH(2)|PLANAR_SH(1), ANYFLAVOR|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollPlanarWords},
2905 { BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollAnyWords},
2910 static cmsFormattersFloat InputFormattersFloat[] = {
2912 // Type Mask Function
2913 // ---------------------------- ------------------------------------ ----------------------------
2914 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, UnrollLabDoubleToFloat},
2915 { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, UnrollLabFloatToFloat},
2917 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, UnrollXYZDoubleToFloat},
2918 { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, UnrollXYZFloatToFloat},
2920 { FLOAT_SH(1)|BYTES_SH(4), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
2921 ANYCHANNELS|ANYSPACE, UnrollFloatsToFloat},
2923 { FLOAT_SH(1)|BYTES_SH(0), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
2924 ANYCHANNELS|ANYSPACE, UnrollDoublesToFloat},
2925 #ifndef CMS_NO_HALF_SUPPORT
2926 { FLOAT_SH(1)|BYTES_SH(2), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
2927 ANYCHANNELS|ANYSPACE, UnrollHalfToFloat},
2932 // Bit fields set to one in the mask are not compared
2934 cmsFormatter _cmsGetStockInputFormatter(cmsUInt32Number dwInput, cmsUInt32Number dwFlags)
2941 case CMS_PACK_FLAGS_16BITS: {
2942 for (i=0; i < sizeof(InputFormatters16) / sizeof(cmsFormatters16); i++) {
2943 cmsFormatters16* f = InputFormatters16 + i;
2945 if ((dwInput & ~f ->Mask) == f ->Type) {
2953 case CMS_PACK_FLAGS_FLOAT: {
2954 for (i=0; i < sizeof(InputFormattersFloat) / sizeof(cmsFormattersFloat); i++) {
2955 cmsFormattersFloat* f = InputFormattersFloat + i;
2957 if ((dwInput & ~f ->Mask) == f ->Type) {
2958 fr.FmtFloat = f ->Frm;
2973 static cmsFormatters16 OutputFormatters16[] = {
2974 // Type Mask Function
2975 // ---------------------------- ------------------------------------ ----------------------------
2977 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, PackLabDoubleFrom16},
2978 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, PackXYZDoubleFrom16},
2980 { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, PackLabFloatFrom16},
2982 { FLOAT_SH(1)|BYTES_SH(0), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
2983 ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackDoubleFrom16},
2984 { FLOAT_SH(1)|BYTES_SH(4), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
2985 ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackFloatFrom16},
2986 #ifndef CMS_NO_HALF_SUPPORT
2987 { FLOAT_SH(1)|BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
2988 ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackHalfFrom16},
2991 { CHANNELS_SH(1)|BYTES_SH(1), ANYSPACE, Pack1Byte},
2992 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Pack1ByteSkip1},
2993 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack1ByteSkip1SwapFirst},
2995 { CHANNELS_SH(1)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Pack1ByteReversed},
2997 { TYPE_LabV2_8, 0, PackLabV2_8 },
2998 { TYPE_ALabV2_8, 0, PackALabV2_8 },
2999 { TYPE_LabV2_16, 0, PackLabV2_16 },
3001 { CHANNELS_SH(3)|BYTES_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesOptimized},
3002 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesAndSkip1Optimized},
3003 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1)|OPTIMIZED_SH(1),
3004 ANYSPACE, Pack3BytesAndSkip1SwapFirstOptimized},
3005 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1)|OPTIMIZED_SH(1),
3006 ANYSPACE, Pack3BytesAndSkip1SwapSwapFirstOptimized},
3007 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|EXTRA_SH(1)|OPTIMIZED_SH(1),
3008 ANYSPACE, Pack3BytesAndSkip1SwapOptimized},
3009 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesSwapOptimized},
3013 { CHANNELS_SH(3)|BYTES_SH(1), ANYSPACE, Pack3Bytes},
3014 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Pack3BytesAndSkip1},
3015 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack3BytesAndSkip1SwapFirst},
3016 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1),
3017 ANYSPACE, Pack3BytesAndSkip1SwapSwapFirst},
3018 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|EXTRA_SH(1), ANYSPACE, Pack3BytesAndSkip1Swap},
3019 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack3BytesSwap},
3020 { CHANNELS_SH(6)|BYTES_SH(1), ANYSPACE, Pack6Bytes},
3021 { CHANNELS_SH(6)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack6BytesSwap},
3022 { CHANNELS_SH(4)|BYTES_SH(1), ANYSPACE, Pack4Bytes},
3023 { CHANNELS_SH(4)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Pack4BytesReverse},
3024 { CHANNELS_SH(4)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack4BytesSwapFirst},
3025 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack4BytesSwap},
3026 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack4BytesSwapSwapFirst},
3028 { BYTES_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackAnyBytes},
3029 { BYTES_SH(1)|PLANAR_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackPlanarBytes},
3031 { CHANNELS_SH(1)|BYTES_SH(2), ANYSPACE, Pack1Word},
3032 { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(1), ANYSPACE, Pack1WordSkip1},
3033 { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack1WordSkip1SwapFirst},
3034 { CHANNELS_SH(1)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Pack1WordReversed},
3035 { CHANNELS_SH(1)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack1WordBigEndian},
3036 { CHANNELS_SH(3)|BYTES_SH(2), ANYSPACE, Pack3Words},
3037 { CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack3WordsSwap},
3038 { CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack3WordsBigEndian},
3039 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1), ANYSPACE, Pack3WordsAndSkip1},
3040 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack3WordsAndSkip1Swap},
3041 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack3WordsAndSkip1SwapFirst},
3043 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1),
3044 ANYSPACE, Pack3WordsAndSkip1SwapSwapFirst},
3046 { CHANNELS_SH(4)|BYTES_SH(2), ANYSPACE, Pack4Words},
3047 { CHANNELS_SH(4)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Pack4WordsReverse},
3048 { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack4WordsSwap},
3049 { CHANNELS_SH(4)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack4WordsBigEndian},
3051 { CHANNELS_SH(6)|BYTES_SH(2), ANYSPACE, Pack6Words},
3052 { CHANNELS_SH(6)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack6WordsSwap},
3054 { BYTES_SH(2)|PLANAR_SH(1), ANYFLAVOR|ANYENDIAN|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackPlanarWords},
3055 { BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackAnyWords}
3060 static cmsFormattersFloat OutputFormattersFloat[] = {
3061 // Type Mask Function
3062 // ---------------------------- --------------------------------------------------- ----------------------------
3063 { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, PackLabFloatFromFloat},
3064 { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, PackXYZFloatFromFloat},
3066 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, PackLabDoubleFromFloat},
3067 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, PackXYZDoubleFromFloat},
3069 { FLOAT_SH(1)|BYTES_SH(4), ANYPLANAR|
3070 ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackFloatsFromFloat },
3071 { FLOAT_SH(1)|BYTES_SH(0), ANYPLANAR|
3072 ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackDoublesFromFloat },
3073 #ifndef CMS_NO_HALF_SUPPORT
3074 { FLOAT_SH(1)|BYTES_SH(2),
3075 ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackHalfFromFloat },
3083 // Bit fields set to one in the mask are not compared
3085 cmsFormatter _cmsGetStockOutputFormatter(cmsUInt32Number dwInput, cmsUInt32Number dwFlags)
3094 case CMS_PACK_FLAGS_16BITS: {
3096 for (i=0; i < sizeof(OutputFormatters16) / sizeof(cmsFormatters16); i++) {
3097 cmsFormatters16* f = OutputFormatters16 + i;
3099 if ((dwInput & ~f ->Mask) == f ->Type) {
3107 case CMS_PACK_FLAGS_FLOAT: {
3109 for (i=0; i < sizeof(OutputFormattersFloat) / sizeof(cmsFormattersFloat); i++) {
3110 cmsFormattersFloat* f = OutputFormattersFloat + i;
3112 if ((dwInput & ~f ->Mask) == f ->Type) {
3113 fr.FmtFloat = f ->Frm;
3129 typedef struct _cms_formatters_factory_list {
3131 cmsFormatterFactory Factory;
3132 struct _cms_formatters_factory_list *Next;
3134 } cmsFormattersFactoryList;
3136 static cmsFormattersFactoryList* FactoryList = NULL;
3139 // Formatters management
3140 cmsBool _cmsRegisterFormattersPlugin(cmsPluginBase* Data)
3142 cmsPluginFormatters* Plugin = (cmsPluginFormatters*) Data;
3143 cmsFormattersFactoryList* fl ;
3152 fl = (cmsFormattersFactoryList*) _cmsPluginMalloc(sizeof(cmsFormattersFactoryList));
3153 if (fl == NULL) return FALSE;
3155 fl ->Factory = Plugin ->FormattersFactory;
3157 fl ->Next = FactoryList;
3163 cmsFormatter _cmsGetFormatter(cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8
3164 cmsFormatterDirection Dir,
3165 cmsUInt32Number dwFlags)
3167 cmsFormattersFactoryList* f;
3169 for (f = FactoryList; f != NULL; f = f ->Next) {
3171 cmsFormatter fn = f ->Factory(Type, Dir, dwFlags);
3172 if (fn.Fmt16 != NULL) return fn;
3175 // Revert to default
3176 if (Dir == cmsFormatterInput)
3177 return _cmsGetStockInputFormatter(Type, dwFlags);
3179 return _cmsGetStockOutputFormatter(Type, dwFlags);
3183 // Return whatever given formatter refers to float values
3184 cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type)
3186 return T_FLOAT(Type) ? TRUE : FALSE;
3189 // Return whatever given formatter refers to 8 bits
3190 cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type)
3192 int Bytes = T_BYTES(Type);
3194 return (Bytes == 1);
3197 // Build a suitable formatter for the colorspace of this profile
3198 cmsUInt32Number CMSEXPORT cmsFormatterForColorspaceOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat)
3201 cmsColorSpaceSignature ColorSpace = cmsGetColorSpace(hProfile);
3202 cmsUInt32Number ColorSpaceBits = _cmsLCMScolorSpace(ColorSpace);
3203 cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace);
3204 cmsUInt32Number Float = lIsFloat ? 1 : 0;
3206 // Create a fake formatter for result
3207 return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans);
3210 // Build a suitable formatter for the colorspace of this profile
3211 cmsUInt32Number CMSEXPORT cmsFormatterForPCSOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat)
3214 cmsColorSpaceSignature ColorSpace = cmsGetPCS(hProfile);
3215 int ColorSpaceBits = _cmsLCMScolorSpace(ColorSpace);
3216 cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace);
3217 cmsUInt32Number Float = lIsFloat ? 1 : 0;
3219 // Create a fake formatter for result
3220 return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans);