1 //---------------------------------------------------------------------------------
3 // Little Color Management System
4 // Copyright (c) 1998-2016 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 // Suppress 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 if (Extra == 0 && SwapFirst) {
2415 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat64Number));
2419 if (T_PLANAR(info -> OutputFormat))
2420 return output + sizeof(cmsFloat64Number);
2422 return output + (nChan + Extra) * sizeof(cmsFloat64Number);
2428 cmsUInt8Number* PackFloatFrom16(register _cmsTRANSFORM* info,
2429 register cmsUInt16Number wOut[],
2430 register cmsUInt8Number* output,
2431 register cmsUInt32Number Stride)
2433 int nChan = T_CHANNELS(info->OutputFormat);
2434 int DoSwap = T_DOSWAP(info->OutputFormat);
2435 int Reverse = T_FLAVOR(info->OutputFormat);
2436 int Extra = T_EXTRA(info->OutputFormat);
2437 int SwapFirst = T_SWAPFIRST(info->OutputFormat);
2438 int Planar = T_PLANAR(info->OutputFormat);
2439 int ExtraFirst = DoSwap ^ SwapFirst;
2440 cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 655.35 : 65535.0;
2441 cmsFloat64Number v = 0;
2442 cmsFloat32Number* swap1 = (cmsFloat32Number*)output;
2448 for (i = 0; i < nChan; i++) {
2450 int index = DoSwap ? (nChan - i - 1) : i;
2452 v = (cmsFloat64Number)wOut[index] / maximum;
2458 ((cmsFloat32Number*)output)[(i + start) * Stride] = (cmsFloat32Number)v;
2460 ((cmsFloat32Number*)output)[i + start] = (cmsFloat32Number)v;
2464 if (Extra == 0 && SwapFirst) {
2466 memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsFloat32Number));
2467 *swap1 = (cmsFloat32Number)v;
2470 if (T_PLANAR(info->OutputFormat))
2471 return output + sizeof(cmsFloat32Number);
2473 return output + (nChan + Extra) * sizeof(cmsFloat32Number);
2478 // --------------------------------------------------------------------------------------------------------
2481 cmsUInt8Number* PackFloatsFromFloat(_cmsTRANSFORM* info,
2482 cmsFloat32Number wOut[],
2483 cmsUInt8Number* output,
2484 cmsUInt32Number Stride)
2486 int nChan = T_CHANNELS(info->OutputFormat);
2487 int DoSwap = T_DOSWAP(info->OutputFormat);
2488 int Reverse = T_FLAVOR(info->OutputFormat);
2489 int Extra = T_EXTRA(info->OutputFormat);
2490 int SwapFirst = T_SWAPFIRST(info->OutputFormat);
2491 int Planar = T_PLANAR(info->OutputFormat);
2492 int ExtraFirst = DoSwap ^ SwapFirst;
2493 cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 100.0 : 1.0;
2494 cmsFloat32Number* swap1 = (cmsFloat32Number*)output;
2495 cmsFloat64Number v = 0;
2501 for (i = 0; i < nChan; i++) {
2503 int index = DoSwap ? (nChan - i - 1) : i;
2505 v = wOut[index] * maximum;
2511 ((cmsFloat32Number*)output)[(i + start)* Stride] = (cmsFloat32Number)v;
2513 ((cmsFloat32Number*)output)[i + start] = (cmsFloat32Number)v;
2517 if (Extra == 0 && SwapFirst) {
2519 memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsFloat32Number));
2520 *swap1 = (cmsFloat32Number)v;
2523 if (T_PLANAR(info->OutputFormat))
2524 return output + sizeof(cmsFloat32Number);
2526 return output + (nChan + Extra) * sizeof(cmsFloat32Number);
2530 cmsUInt8Number* PackDoublesFromFloat(_cmsTRANSFORM* info,
2531 cmsFloat32Number wOut[],
2532 cmsUInt8Number* output,
2533 cmsUInt32Number Stride)
2535 int nChan = T_CHANNELS(info->OutputFormat);
2536 int DoSwap = T_DOSWAP(info->OutputFormat);
2537 int Reverse = T_FLAVOR(info->OutputFormat);
2538 int Extra = T_EXTRA(info->OutputFormat);
2539 int SwapFirst = T_SWAPFIRST(info->OutputFormat);
2540 int Planar = T_PLANAR(info->OutputFormat);
2541 int ExtraFirst = DoSwap ^ SwapFirst;
2542 cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 100.0 : 1.0;
2543 cmsFloat64Number v = 0;
2544 cmsFloat64Number* swap1 = (cmsFloat64Number*)output;
2550 for (i = 0; i < nChan; i++) {
2552 int index = DoSwap ? (nChan - i - 1) : i;
2554 v = wOut[index] * maximum;
2560 ((cmsFloat64Number*)output)[(i + start) * Stride] = v;
2562 ((cmsFloat64Number*)output)[i + start] = v;
2565 if (Extra == 0 && SwapFirst) {
2567 memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsFloat64Number));
2572 if (T_PLANAR(info->OutputFormat))
2573 return output + sizeof(cmsFloat64Number);
2575 return output + (nChan + Extra) * sizeof(cmsFloat64Number);
2584 cmsUInt8Number* PackLabFloatFromFloat(_cmsTRANSFORM* Info,
2585 cmsFloat32Number wOut[],
2586 cmsUInt8Number* output,
2587 cmsUInt32Number Stride)
2589 cmsFloat32Number* Out = (cmsFloat32Number*) output;
2591 if (T_PLANAR(Info -> OutputFormat)) {
2593 Out[0] = (cmsFloat32Number) (wOut[0] * 100.0);
2594 Out[Stride] = (cmsFloat32Number) (wOut[1] * 255.0 - 128.0);
2595 Out[Stride*2] = (cmsFloat32Number) (wOut[2] * 255.0 - 128.0);
2597 return output + sizeof(cmsFloat32Number);
2601 Out[0] = (cmsFloat32Number) (wOut[0] * 100.0);
2602 Out[1] = (cmsFloat32Number) (wOut[1] * 255.0 - 128.0);
2603 Out[2] = (cmsFloat32Number) (wOut[2] * 255.0 - 128.0);
2605 return output + (sizeof(cmsFloat32Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
2612 cmsUInt8Number* PackLabDoubleFromFloat(_cmsTRANSFORM* Info,
2613 cmsFloat32Number wOut[],
2614 cmsUInt8Number* output,
2615 cmsUInt32Number Stride)
2617 cmsFloat64Number* Out = (cmsFloat64Number*) output;
2619 if (T_PLANAR(Info -> OutputFormat)) {
2621 Out[0] = (cmsFloat64Number) (wOut[0] * 100.0);
2622 Out[Stride] = (cmsFloat64Number) (wOut[1] * 255.0 - 128.0);
2623 Out[Stride*2] = (cmsFloat64Number) (wOut[2] * 255.0 - 128.0);
2625 return output + sizeof(cmsFloat64Number);
2629 Out[0] = (cmsFloat64Number) (wOut[0] * 100.0);
2630 Out[1] = (cmsFloat64Number) (wOut[1] * 255.0 - 128.0);
2631 Out[2] = (cmsFloat64Number) (wOut[2] * 255.0 - 128.0);
2633 return output + (sizeof(cmsFloat64Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
2639 // From 0..1 range to 0..MAX_ENCODEABLE_XYZ
2641 cmsUInt8Number* PackXYZFloatFromFloat(_cmsTRANSFORM* Info,
2642 cmsFloat32Number wOut[],
2643 cmsUInt8Number* output,
2644 cmsUInt32Number Stride)
2646 cmsFloat32Number* Out = (cmsFloat32Number*) output;
2648 if (T_PLANAR(Info -> OutputFormat)) {
2650 Out[0] = (cmsFloat32Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
2651 Out[Stride] = (cmsFloat32Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
2652 Out[Stride*2] = (cmsFloat32Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
2654 return output + sizeof(cmsFloat32Number);
2658 Out[0] = (cmsFloat32Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
2659 Out[1] = (cmsFloat32Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
2660 Out[2] = (cmsFloat32Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
2662 return output + (sizeof(cmsFloat32Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
2667 // Same, but convert to double
2669 cmsUInt8Number* PackXYZDoubleFromFloat(_cmsTRANSFORM* Info,
2670 cmsFloat32Number wOut[],
2671 cmsUInt8Number* output,
2672 cmsUInt32Number Stride)
2674 cmsFloat64Number* Out = (cmsFloat64Number*) output;
2676 if (T_PLANAR(Info -> OutputFormat)) {
2678 Out[0] = (cmsFloat64Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
2679 Out[Stride] = (cmsFloat64Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
2680 Out[Stride*2] = (cmsFloat64Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
2682 return output + sizeof(cmsFloat64Number);
2686 Out[0] = (cmsFloat64Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
2687 Out[1] = (cmsFloat64Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
2688 Out[2] = (cmsFloat64Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
2690 return output + (sizeof(cmsFloat64Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
2696 // ----------------------------------------------------------------------------------------------------------------
2698 #ifndef CMS_NO_HALF_SUPPORT
2700 // Decodes an stream of half floats to wIn[] described by input format
2703 cmsUInt8Number* UnrollHalfTo16(register _cmsTRANSFORM* info,
2704 register cmsUInt16Number wIn[],
2705 register cmsUInt8Number* accum,
2706 register cmsUInt32Number Stride)
2709 int nChan = T_CHANNELS(info -> InputFormat);
2710 int DoSwap = T_DOSWAP(info ->InputFormat);
2711 int Reverse = T_FLAVOR(info ->InputFormat);
2712 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
2713 int Extra = T_EXTRA(info -> InputFormat);
2714 int ExtraFirst = DoSwap ^ SwapFirst;
2715 int Planar = T_PLANAR(info -> InputFormat);
2718 cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 655.35F : 65535.0F;
2724 for (i=0; i < nChan; i++) {
2726 int index = DoSwap ? (nChan - i - 1) : i;
2729 v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[(i + start) * Stride] );
2731 v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[i + start] ) ;
2733 if (Reverse) v = maximum - v;
2735 wIn[index] = _cmsQuickSaturateWord(v * maximum);
2739 if (Extra == 0 && SwapFirst) {
2740 cmsUInt16Number tmp = wIn[0];
2742 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
2746 if (T_PLANAR(info -> InputFormat))
2747 return accum + sizeof(cmsUInt16Number);
2749 return accum + (nChan + Extra) * sizeof(cmsUInt16Number);
2752 // Decodes an stream of half floats to wIn[] described by input format
2755 cmsUInt8Number* UnrollHalfToFloat(_cmsTRANSFORM* info,
2756 cmsFloat32Number wIn[],
2757 cmsUInt8Number* accum,
2758 cmsUInt32Number Stride)
2761 int nChan = T_CHANNELS(info -> InputFormat);
2762 int DoSwap = T_DOSWAP(info ->InputFormat);
2763 int Reverse = T_FLAVOR(info ->InputFormat);
2764 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
2765 int Extra = T_EXTRA(info -> InputFormat);
2766 int ExtraFirst = DoSwap ^ SwapFirst;
2767 int Planar = T_PLANAR(info -> InputFormat);
2770 cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 100.0F : 1.0F;
2776 for (i=0; i < nChan; i++) {
2778 int index = DoSwap ? (nChan - i - 1) : i;
2781 v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[(i + start) * Stride] );
2783 v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[i + start] ) ;
2787 wIn[index] = Reverse ? 1 - v : v;
2791 if (Extra == 0 && SwapFirst) {
2792 cmsFloat32Number tmp = wIn[0];
2794 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number));
2798 if (T_PLANAR(info -> InputFormat))
2799 return accum + sizeof(cmsUInt16Number);
2801 return accum + (nChan + Extra) * sizeof(cmsUInt16Number);
2806 cmsUInt8Number* PackHalfFrom16(register _cmsTRANSFORM* info,
2807 register cmsUInt16Number wOut[],
2808 register cmsUInt8Number* output,
2809 register cmsUInt32Number Stride)
2811 int nChan = T_CHANNELS(info->OutputFormat);
2812 int DoSwap = T_DOSWAP(info->OutputFormat);
2813 int Reverse = T_FLAVOR(info->OutputFormat);
2814 int Extra = T_EXTRA(info->OutputFormat);
2815 int SwapFirst = T_SWAPFIRST(info->OutputFormat);
2816 int Planar = T_PLANAR(info->OutputFormat);
2817 int ExtraFirst = DoSwap ^ SwapFirst;
2818 cmsFloat32Number maximum = IsInkSpace(info->OutputFormat) ? 655.35F : 65535.0F;
2819 cmsFloat32Number v = 0;
2820 cmsUInt16Number* swap1 = (cmsUInt16Number*)output;
2826 for (i = 0; i < nChan; i++) {
2828 int index = DoSwap ? (nChan - i - 1) : i;
2830 v = (cmsFloat32Number)wOut[index] / maximum;
2836 ((cmsUInt16Number*)output)[(i + start) * Stride] = _cmsFloat2Half(v);
2838 ((cmsUInt16Number*)output)[i + start] = _cmsFloat2Half(v);
2842 if (Extra == 0 && SwapFirst) {
2844 memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsUInt16Number));
2845 *swap1 = _cmsFloat2Half(v);
2848 if (T_PLANAR(info->OutputFormat))
2849 return output + sizeof(cmsUInt16Number);
2851 return output + (nChan + Extra) * sizeof(cmsUInt16Number);
2857 cmsUInt8Number* PackHalfFromFloat(_cmsTRANSFORM* info,
2858 cmsFloat32Number wOut[],
2859 cmsUInt8Number* output,
2860 cmsUInt32Number Stride)
2862 int nChan = T_CHANNELS(info->OutputFormat);
2863 int DoSwap = T_DOSWAP(info->OutputFormat);
2864 int Reverse = T_FLAVOR(info->OutputFormat);
2865 int Extra = T_EXTRA(info->OutputFormat);
2866 int SwapFirst = T_SWAPFIRST(info->OutputFormat);
2867 int Planar = T_PLANAR(info->OutputFormat);
2868 int ExtraFirst = DoSwap ^ SwapFirst;
2869 cmsFloat32Number maximum = IsInkSpace(info->OutputFormat) ? 100.0F : 1.0F;
2870 cmsUInt16Number* swap1 = (cmsUInt16Number*)output;
2871 cmsFloat32Number v = 0;
2877 for (i = 0; i < nChan; i++) {
2879 int index = DoSwap ? (nChan - i - 1) : i;
2881 v = wOut[index] * maximum;
2887 ((cmsUInt16Number*)output)[(i + start)* Stride] = _cmsFloat2Half(v);
2889 ((cmsUInt16Number*)output)[i + start] = _cmsFloat2Half(v);
2893 if (Extra == 0 && SwapFirst) {
2895 memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsUInt16Number));
2896 *swap1 = (cmsUInt16Number)_cmsFloat2Half(v);
2899 if (T_PLANAR(info->OutputFormat))
2900 return output + sizeof(cmsUInt16Number);
2902 return output + (nChan + Extra)* sizeof(cmsUInt16Number);
2907 // ----------------------------------------------------------------------------------------------------------------
2910 static cmsFormatters16 InputFormatters16[] = {
2912 // Type Mask Function
2913 // ---------------------------- ------------------------------------ ----------------------------
2914 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, UnrollLabDoubleTo16},
2915 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, UnrollXYZDoubleTo16},
2916 { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, UnrollLabFloatTo16},
2917 { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, UnrollXYZFloatTo16},
2918 { TYPE_GRAY_DBL, 0, UnrollDouble1Chan},
2919 { FLOAT_SH(1)|BYTES_SH(0), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR|
2920 ANYSWAP|ANYEXTRA|ANYSPACE, UnrollDoubleTo16},
2921 { FLOAT_SH(1)|BYTES_SH(4), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR|
2922 ANYSWAP|ANYEXTRA|ANYSPACE, UnrollFloatTo16},
2923 #ifndef CMS_NO_HALF_SUPPORT
2924 { FLOAT_SH(1)|BYTES_SH(2), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR|
2925 ANYEXTRA|ANYSWAP|ANYSPACE, UnrollHalfTo16},
2928 { CHANNELS_SH(1)|BYTES_SH(1), ANYSPACE, Unroll1Byte},
2929 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Unroll1ByteSkip1},
2930 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(2), ANYSPACE, Unroll1ByteSkip2},
2931 { CHANNELS_SH(1)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Unroll1ByteReversed},
2932 { COLORSPACE_SH(PT_MCH2)|CHANNELS_SH(2)|BYTES_SH(1), 0, Unroll2Bytes},
2934 { TYPE_LabV2_8, 0, UnrollLabV2_8 },
2935 { TYPE_ALabV2_8, 0, UnrollALabV2_8 },
2936 { TYPE_LabV2_16, 0, UnrollLabV2_16 },
2938 { CHANNELS_SH(3)|BYTES_SH(1), ANYSPACE, Unroll3Bytes},
2939 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3BytesSwap},
2940 { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3BytesSkip1Swap},
2941 { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll3BytesSkip1SwapFirst},
2943 { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1),
2944 ANYSPACE, Unroll3BytesSkip1SwapSwapFirst},
2946 { CHANNELS_SH(4)|BYTES_SH(1), ANYSPACE, Unroll4Bytes},
2947 { CHANNELS_SH(4)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Unroll4BytesReverse},
2948 { CHANNELS_SH(4)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4BytesSwapFirst},
2949 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll4BytesSwap},
2950 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4BytesSwapSwapFirst},
2952 { BYTES_SH(1)|PLANAR_SH(1), ANYFLAVOR|ANYSWAPFIRST|
2953 ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollPlanarBytes},
2955 { BYTES_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
2956 ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollChunkyBytes},
2958 { CHANNELS_SH(1)|BYTES_SH(2), ANYSPACE, Unroll1Word},
2959 { CHANNELS_SH(1)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Unroll1WordReversed},
2960 { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(3), ANYSPACE, Unroll1WordSkip3},
2962 { CHANNELS_SH(2)|BYTES_SH(2), ANYSPACE, Unroll2Words},
2963 { CHANNELS_SH(3)|BYTES_SH(2), ANYSPACE, Unroll3Words},
2964 { CHANNELS_SH(4)|BYTES_SH(2), ANYSPACE, Unroll4Words},
2966 { CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Unroll3WordsSwap},
2967 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll3WordsSkip1SwapFirst},
2968 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3WordsSkip1Swap},
2969 { CHANNELS_SH(4)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Unroll4WordsReverse},
2970 { CHANNELS_SH(4)|BYTES_SH(2)|SWAPFIRST_SH(1), ANYSPACE, Unroll4WordsSwapFirst},
2971 { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Unroll4WordsSwap},
2972 { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4WordsSwapSwapFirst},
2975 { BYTES_SH(2)|PLANAR_SH(1), ANYFLAVOR|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollPlanarWords},
2976 { BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollAnyWords},
2981 static cmsFormattersFloat InputFormattersFloat[] = {
2983 // Type Mask Function
2984 // ---------------------------- ------------------------------------ ----------------------------
2985 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, UnrollLabDoubleToFloat},
2986 { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, UnrollLabFloatToFloat},
2988 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, UnrollXYZDoubleToFloat},
2989 { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, UnrollXYZFloatToFloat},
2991 { FLOAT_SH(1)|BYTES_SH(4), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
2992 ANYCHANNELS|ANYSPACE, UnrollFloatsToFloat},
2994 { FLOAT_SH(1)|BYTES_SH(0), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
2995 ANYCHANNELS|ANYSPACE, UnrollDoublesToFloat},
2996 #ifndef CMS_NO_HALF_SUPPORT
2997 { FLOAT_SH(1)|BYTES_SH(2), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
2998 ANYCHANNELS|ANYSPACE, UnrollHalfToFloat},
3003 // Bit fields set to one in the mask are not compared
3005 cmsFormatter _cmsGetStockInputFormatter(cmsUInt32Number dwInput, cmsUInt32Number dwFlags)
3012 case CMS_PACK_FLAGS_16BITS: {
3013 for (i=0; i < sizeof(InputFormatters16) / sizeof(cmsFormatters16); i++) {
3014 cmsFormatters16* f = InputFormatters16 + i;
3016 if ((dwInput & ~f ->Mask) == f ->Type) {
3024 case CMS_PACK_FLAGS_FLOAT: {
3025 for (i=0; i < sizeof(InputFormattersFloat) / sizeof(cmsFormattersFloat); i++) {
3026 cmsFormattersFloat* f = InputFormattersFloat + i;
3028 if ((dwInput & ~f ->Mask) == f ->Type) {
3029 fr.FmtFloat = f ->Frm;
3044 static cmsFormatters16 OutputFormatters16[] = {
3045 // Type Mask Function
3046 // ---------------------------- ------------------------------------ ----------------------------
3048 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, PackLabDoubleFrom16},
3049 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, PackXYZDoubleFrom16},
3051 { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, PackLabFloatFrom16},
3052 { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, PackXYZFloatFrom16},
3054 { FLOAT_SH(1)|BYTES_SH(0), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
3055 ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackDoubleFrom16},
3056 { FLOAT_SH(1)|BYTES_SH(4), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
3057 ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackFloatFrom16},
3058 #ifndef CMS_NO_HALF_SUPPORT
3059 { FLOAT_SH(1)|BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
3060 ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackHalfFrom16},
3063 { CHANNELS_SH(1)|BYTES_SH(1), ANYSPACE, Pack1Byte},
3064 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Pack1ByteSkip1},
3065 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack1ByteSkip1SwapFirst},
3067 { CHANNELS_SH(1)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Pack1ByteReversed},
3069 { TYPE_LabV2_8, 0, PackLabV2_8 },
3070 { TYPE_ALabV2_8, 0, PackALabV2_8 },
3071 { TYPE_LabV2_16, 0, PackLabV2_16 },
3073 { CHANNELS_SH(3)|BYTES_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesOptimized},
3074 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesAndSkip1Optimized},
3075 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1)|OPTIMIZED_SH(1),
3076 ANYSPACE, Pack3BytesAndSkip1SwapFirstOptimized},
3077 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1)|OPTIMIZED_SH(1),
3078 ANYSPACE, Pack3BytesAndSkip1SwapSwapFirstOptimized},
3079 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|EXTRA_SH(1)|OPTIMIZED_SH(1),
3080 ANYSPACE, Pack3BytesAndSkip1SwapOptimized},
3081 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesSwapOptimized},
3085 { CHANNELS_SH(3)|BYTES_SH(1), ANYSPACE, Pack3Bytes},
3086 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Pack3BytesAndSkip1},
3087 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack3BytesAndSkip1SwapFirst},
3088 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1),
3089 ANYSPACE, Pack3BytesAndSkip1SwapSwapFirst},
3090 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|EXTRA_SH(1), ANYSPACE, Pack3BytesAndSkip1Swap},
3091 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack3BytesSwap},
3092 { CHANNELS_SH(6)|BYTES_SH(1), ANYSPACE, Pack6Bytes},
3093 { CHANNELS_SH(6)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack6BytesSwap},
3094 { CHANNELS_SH(4)|BYTES_SH(1), ANYSPACE, Pack4Bytes},
3095 { CHANNELS_SH(4)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Pack4BytesReverse},
3096 { CHANNELS_SH(4)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack4BytesSwapFirst},
3097 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack4BytesSwap},
3098 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack4BytesSwapSwapFirst},
3100 { BYTES_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackAnyBytes},
3101 { BYTES_SH(1)|PLANAR_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackPlanarBytes},
3103 { CHANNELS_SH(1)|BYTES_SH(2), ANYSPACE, Pack1Word},
3104 { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(1), ANYSPACE, Pack1WordSkip1},
3105 { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack1WordSkip1SwapFirst},
3106 { CHANNELS_SH(1)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Pack1WordReversed},
3107 { CHANNELS_SH(1)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack1WordBigEndian},
3108 { CHANNELS_SH(3)|BYTES_SH(2), ANYSPACE, Pack3Words},
3109 { CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack3WordsSwap},
3110 { CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack3WordsBigEndian},
3111 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1), ANYSPACE, Pack3WordsAndSkip1},
3112 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack3WordsAndSkip1Swap},
3113 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack3WordsAndSkip1SwapFirst},
3115 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1),
3116 ANYSPACE, Pack3WordsAndSkip1SwapSwapFirst},
3118 { CHANNELS_SH(4)|BYTES_SH(2), ANYSPACE, Pack4Words},
3119 { CHANNELS_SH(4)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Pack4WordsReverse},
3120 { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack4WordsSwap},
3121 { CHANNELS_SH(4)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack4WordsBigEndian},
3123 { CHANNELS_SH(6)|BYTES_SH(2), ANYSPACE, Pack6Words},
3124 { CHANNELS_SH(6)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack6WordsSwap},
3126 { BYTES_SH(2)|PLANAR_SH(1), ANYFLAVOR|ANYENDIAN|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackPlanarWords},
3127 { BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackAnyWords}
3132 static cmsFormattersFloat OutputFormattersFloat[] = {
3133 // Type Mask Function
3134 // ---------------------------- --------------------------------------------------- ----------------------------
3135 { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, PackLabFloatFromFloat},
3136 { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, PackXYZFloatFromFloat},
3138 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, PackLabDoubleFromFloat},
3139 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, PackXYZDoubleFromFloat},
3141 { FLOAT_SH(1)|BYTES_SH(4), ANYPLANAR|
3142 ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackFloatsFromFloat },
3143 { FLOAT_SH(1)|BYTES_SH(0), ANYPLANAR|
3144 ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackDoublesFromFloat },
3145 #ifndef CMS_NO_HALF_SUPPORT
3146 { FLOAT_SH(1)|BYTES_SH(2),
3147 ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackHalfFromFloat },
3155 // Bit fields set to one in the mask are not compared
3157 cmsFormatter _cmsGetStockOutputFormatter(cmsUInt32Number dwInput, cmsUInt32Number dwFlags)
3162 // Optimization is only a hint
3163 dwInput &= ~OPTIMIZED_SH(1);
3168 case CMS_PACK_FLAGS_16BITS: {
3170 for (i=0; i < sizeof(OutputFormatters16) / sizeof(cmsFormatters16); i++) {
3171 cmsFormatters16* f = OutputFormatters16 + i;
3173 if ((dwInput & ~f ->Mask) == f ->Type) {
3181 case CMS_PACK_FLAGS_FLOAT: {
3183 for (i=0; i < sizeof(OutputFormattersFloat) / sizeof(cmsFormattersFloat); i++) {
3184 cmsFormattersFloat* f = OutputFormattersFloat + i;
3186 if ((dwInput & ~f ->Mask) == f ->Type) {
3187 fr.FmtFloat = f ->Frm;
3203 typedef struct _cms_formatters_factory_list {
3205 cmsFormatterFactory Factory;
3206 struct _cms_formatters_factory_list *Next;
3208 } cmsFormattersFactoryList;
3210 _cmsFormattersPluginChunkType _cmsFormattersPluginChunk = { NULL };
3213 // Duplicates the zone of memory used by the plug-in in the new context
3215 void DupFormatterFactoryList(struct _cmsContext_struct* ctx,
3216 const struct _cmsContext_struct* src)
3218 _cmsFormattersPluginChunkType newHead = { NULL };
3219 cmsFormattersFactoryList* entry;
3220 cmsFormattersFactoryList* Anterior = NULL;
3221 _cmsFormattersPluginChunkType* head = (_cmsFormattersPluginChunkType*) src->chunks[FormattersPlugin];
3223 _cmsAssert(head != NULL);
3225 // Walk the list copying all nodes
3226 for (entry = head->FactoryList;
3228 entry = entry ->Next) {
3230 cmsFormattersFactoryList *newEntry = ( cmsFormattersFactoryList *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(cmsFormattersFactoryList));
3232 if (newEntry == NULL)
3235 // We want to keep the linked list order, so this is a little bit tricky
3236 newEntry -> Next = NULL;
3238 Anterior -> Next = newEntry;
3240 Anterior = newEntry;
3242 if (newHead.FactoryList == NULL)
3243 newHead.FactoryList = newEntry;
3246 ctx ->chunks[FormattersPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsFormattersPluginChunkType));
3249 // The interpolation plug-in memory chunk allocator/dup
3250 void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct* ctx,
3251 const struct _cmsContext_struct* src)
3253 _cmsAssert(ctx != NULL);
3257 // Duplicate the LIST
3258 DupFormatterFactoryList(ctx, src);
3261 static _cmsFormattersPluginChunkType FormattersPluginChunk = { NULL };
3262 ctx ->chunks[FormattersPlugin] = _cmsSubAllocDup(ctx ->MemPool, &FormattersPluginChunk, sizeof(_cmsFormattersPluginChunkType));
3268 // Formatters management
3269 cmsBool _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Data)
3271 _cmsFormattersPluginChunkType* ctx = ( _cmsFormattersPluginChunkType*) _cmsContextGetClientChunk(ContextID, FormattersPlugin);
3272 cmsPluginFormatters* Plugin = (cmsPluginFormatters*) Data;
3273 cmsFormattersFactoryList* fl ;
3275 // Reset to built-in defaults
3278 ctx ->FactoryList = NULL;
3282 fl = (cmsFormattersFactoryList*) _cmsPluginMalloc(ContextID, sizeof(cmsFormattersFactoryList));
3283 if (fl == NULL) return FALSE;
3285 fl ->Factory = Plugin ->FormattersFactory;
3287 fl ->Next = ctx -> FactoryList;
3288 ctx ->FactoryList = fl;
3293 cmsFormatter _cmsGetFormatter(cmsContext ContextID,
3294 cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8
3295 cmsFormatterDirection Dir,
3296 cmsUInt32Number dwFlags)
3298 _cmsFormattersPluginChunkType* ctx = ( _cmsFormattersPluginChunkType*) _cmsContextGetClientChunk(ContextID, FormattersPlugin);
3299 cmsFormattersFactoryList* f;
3301 for (f =ctx->FactoryList; f != NULL; f = f ->Next) {
3303 cmsFormatter fn = f ->Factory(Type, Dir, dwFlags);
3304 if (fn.Fmt16 != NULL) return fn;
3307 // Revert to default
3308 if (Dir == cmsFormatterInput)
3309 return _cmsGetStockInputFormatter(Type, dwFlags);
3311 return _cmsGetStockOutputFormatter(Type, dwFlags);
3315 // Return whatever given formatter refers to float values
3316 cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type)
3318 return T_FLOAT(Type) ? TRUE : FALSE;
3321 // Return whatever given formatter refers to 8 bits
3322 cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type)
3324 int Bytes = T_BYTES(Type);
3326 return (Bytes == 1);
3329 // Build a suitable formatter for the colorspace of this profile
3330 cmsUInt32Number CMSEXPORT cmsFormatterForColorspaceOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat)
3333 cmsColorSpaceSignature ColorSpace = cmsGetColorSpace(hProfile);
3334 cmsUInt32Number ColorSpaceBits = _cmsLCMScolorSpace(ColorSpace);
3335 cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace);
3336 cmsUInt32Number Float = lIsFloat ? 1 : 0;
3338 // Create a fake formatter for result
3339 return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans);
3342 // Build a suitable formatter for the colorspace of this profile
3343 cmsUInt32Number CMSEXPORT cmsFormatterForPCSOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat)
3346 cmsColorSpaceSignature ColorSpace = cmsGetPCS(hProfile);
3347 int ColorSpaceBits = _cmsLCMScolorSpace(ColorSpace);
3348 cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace);
3349 cmsUInt32Number Float = lIsFloat ? 1 : 0;
3351 // Create a fake formatter for result
3352 return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans);