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 as special
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)
49 a = (x << 8 | x) >> 8; // * 257 / 256
50 if ( a > 0xffff) return 0xffff;
51 return (cmsUInt16Number) a;
54 // * 0xf00 / 0xffff = * 256 / 257
55 cmsINLINE cmsUInt16Number FomLabV4ToLabV2(cmsUInt16Number x)
57 return (cmsUInt16Number) (((x << 8) + 0x80) / 257);
71 cmsFormatterFloat Frm;
75 #define ANYSPACE COLORSPACE_SH(31)
76 #define ANYCHANNELS CHANNELS_SH(15)
77 #define ANYEXTRA EXTRA_SH(7)
78 #define ANYPLANAR PLANAR_SH(1)
79 #define ANYENDIAN ENDIAN16_SH(1)
80 #define ANYSWAP DOSWAP_SH(1)
81 #define ANYSWAPFIRST SWAPFIRST_SH(1)
82 #define ANYFLAVOR FLAVOR_SH(1)
85 // Supress waning about info never being used
88 #pragma warning(disable : 4100)
91 // 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 Reverse= T_FLAVOR(info ->InputFormat);
151 cmsUInt8Number* Init = accum;
154 accum += T_EXTRA(info -> InputFormat) * Stride;
157 for (i=0; i < nChan; i++) {
159 int index = DoSwap ? (nChan - i - 1) : i;
160 cmsUInt16Number v = FROM_8_TO_16(*accum);
162 wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
169 // Special cases, provided for performance
171 cmsUInt8Number* Unroll4Bytes(register _cmsTRANSFORM* info,
172 register cmsUInt16Number wIn[],
173 register cmsUInt8Number* accum,
174 register cmsUInt32Number Stride)
176 wIn[0] = FROM_8_TO_16(*accum); accum++; // C
177 wIn[1] = FROM_8_TO_16(*accum); accum++; // M
178 wIn[2] = FROM_8_TO_16(*accum); accum++; // Y
179 wIn[3] = FROM_8_TO_16(*accum); accum++; // K
183 cmsUNUSED_PARAMETER(info);
184 cmsUNUSED_PARAMETER(Stride);
188 cmsUInt8Number* Unroll4BytesReverse(register _cmsTRANSFORM* info,
189 register cmsUInt16Number wIn[],
190 register cmsUInt8Number* accum,
191 register cmsUInt32Number Stride)
193 wIn[0] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // C
194 wIn[1] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // M
195 wIn[2] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // Y
196 wIn[3] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // K
200 cmsUNUSED_PARAMETER(info);
201 cmsUNUSED_PARAMETER(Stride);
205 cmsUInt8Number* Unroll4BytesSwapFirst(register _cmsTRANSFORM* info,
206 register cmsUInt16Number wIn[],
207 register cmsUInt8Number* accum,
208 register cmsUInt32Number Stride)
210 wIn[3] = FROM_8_TO_16(*accum); accum++; // K
211 wIn[0] = FROM_8_TO_16(*accum); accum++; // C
212 wIn[1] = FROM_8_TO_16(*accum); accum++; // M
213 wIn[2] = FROM_8_TO_16(*accum); accum++; // Y
217 cmsUNUSED_PARAMETER(info);
218 cmsUNUSED_PARAMETER(Stride);
223 cmsUInt8Number* Unroll4BytesSwap(register _cmsTRANSFORM* info,
224 register cmsUInt16Number wIn[],
225 register cmsUInt8Number* accum,
226 register cmsUInt32Number Stride)
228 wIn[3] = FROM_8_TO_16(*accum); accum++; // K
229 wIn[2] = FROM_8_TO_16(*accum); accum++; // Y
230 wIn[1] = FROM_8_TO_16(*accum); accum++; // M
231 wIn[0] = FROM_8_TO_16(*accum); accum++; // C
235 cmsUNUSED_PARAMETER(info);
236 cmsUNUSED_PARAMETER(Stride);
240 cmsUInt8Number* Unroll4BytesSwapSwapFirst(register _cmsTRANSFORM* info,
241 register cmsUInt16Number wIn[],
242 register cmsUInt8Number* accum,
243 register cmsUInt32Number Stride)
245 wIn[2] = FROM_8_TO_16(*accum); accum++; // K
246 wIn[1] = FROM_8_TO_16(*accum); accum++; // Y
247 wIn[0] = FROM_8_TO_16(*accum); accum++; // M
248 wIn[3] = FROM_8_TO_16(*accum); accum++; // C
252 cmsUNUSED_PARAMETER(info);
253 cmsUNUSED_PARAMETER(Stride);
257 cmsUInt8Number* Unroll3Bytes(register _cmsTRANSFORM* info,
258 register cmsUInt16Number wIn[],
259 register cmsUInt8Number* accum,
260 register cmsUInt32Number Stride)
262 wIn[0] = FROM_8_TO_16(*accum); accum++; // R
263 wIn[1] = FROM_8_TO_16(*accum); accum++; // G
264 wIn[2] = FROM_8_TO_16(*accum); accum++; // B
268 cmsUNUSED_PARAMETER(info);
269 cmsUNUSED_PARAMETER(Stride);
273 cmsUInt8Number* Unroll3BytesSkip1Swap(register _cmsTRANSFORM* info,
274 register cmsUInt16Number wIn[],
275 register cmsUInt8Number* accum,
276 register cmsUInt32Number Stride)
279 wIn[2] = FROM_8_TO_16(*accum); accum++; // B
280 wIn[1] = FROM_8_TO_16(*accum); accum++; // G
281 wIn[0] = FROM_8_TO_16(*accum); accum++; // R
285 cmsUNUSED_PARAMETER(info);
286 cmsUNUSED_PARAMETER(Stride);
290 cmsUInt8Number* Unroll3BytesSkip1SwapFirst(register _cmsTRANSFORM* info,
291 register cmsUInt16Number wIn[],
292 register cmsUInt8Number* accum,
293 register cmsUInt32Number Stride)
296 wIn[0] = FROM_8_TO_16(*accum); accum++; // R
297 wIn[1] = FROM_8_TO_16(*accum); accum++; // G
298 wIn[2] = FROM_8_TO_16(*accum); accum++; // B
302 cmsUNUSED_PARAMETER(info);
303 cmsUNUSED_PARAMETER(Stride);
309 cmsUInt8Number* Unroll3BytesSwap(register _cmsTRANSFORM* info,
310 register cmsUInt16Number wIn[],
311 register cmsUInt8Number* accum,
312 register cmsUInt32Number Stride)
314 wIn[2] = FROM_8_TO_16(*accum); accum++; // B
315 wIn[1] = FROM_8_TO_16(*accum); accum++; // G
316 wIn[0] = FROM_8_TO_16(*accum); accum++; // R
320 cmsUNUSED_PARAMETER(info);
321 cmsUNUSED_PARAMETER(Stride);
325 cmsUInt8Number* UnrollLabV2_8(register _cmsTRANSFORM* info,
326 register cmsUInt16Number wIn[],
327 register cmsUInt8Number* accum,
328 register cmsUInt32Number Stride)
330 wIn[0] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // L
331 wIn[1] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // a
332 wIn[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // b
336 cmsUNUSED_PARAMETER(info);
337 cmsUNUSED_PARAMETER(Stride);
341 cmsUInt8Number* UnrollALabV2_8(register _cmsTRANSFORM* info,
342 register cmsUInt16Number wIn[],
343 register cmsUInt8Number* accum,
344 register cmsUInt32Number Stride)
347 wIn[0] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // L
348 wIn[1] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // a
349 wIn[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // b
353 cmsUNUSED_PARAMETER(info);
354 cmsUNUSED_PARAMETER(Stride);
358 cmsUInt8Number* UnrollLabV2_16(register _cmsTRANSFORM* info,
359 register cmsUInt16Number wIn[],
360 register cmsUInt8Number* accum,
361 register cmsUInt32Number Stride)
363 wIn[0] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // L
364 wIn[1] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // a
365 wIn[2] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // b
369 cmsUNUSED_PARAMETER(info);
370 cmsUNUSED_PARAMETER(Stride);
375 cmsUInt8Number* Unroll2Bytes(register _cmsTRANSFORM* info,
376 register cmsUInt16Number wIn[],
377 register cmsUInt8Number* accum,
378 register cmsUInt32Number Stride)
380 wIn[0] = FROM_8_TO_16(*accum); accum++; // ch1
381 wIn[1] = FROM_8_TO_16(*accum); accum++; // ch2
385 cmsUNUSED_PARAMETER(info);
386 cmsUNUSED_PARAMETER(Stride);
392 // Monochrome duplicates L into RGB for null-transforms
394 cmsUInt8Number* Unroll1Byte(register _cmsTRANSFORM* info,
395 register cmsUInt16Number wIn[],
396 register cmsUInt8Number* accum,
397 register cmsUInt32Number Stride)
399 wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L
403 cmsUNUSED_PARAMETER(info);
404 cmsUNUSED_PARAMETER(Stride);
409 cmsUInt8Number* Unroll1ByteSkip1(register _cmsTRANSFORM* info,
410 register cmsUInt16Number wIn[],
411 register cmsUInt8Number* accum,
412 register cmsUInt32Number Stride)
414 wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L
419 cmsUNUSED_PARAMETER(info);
420 cmsUNUSED_PARAMETER(Stride);
424 cmsUInt8Number* Unroll1ByteSkip2(register _cmsTRANSFORM* info,
425 register cmsUInt16Number wIn[],
426 register cmsUInt8Number* accum,
427 register cmsUInt32Number Stride)
429 wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L
434 cmsUNUSED_PARAMETER(info);
435 cmsUNUSED_PARAMETER(Stride);
439 cmsUInt8Number* Unroll1ByteReversed(register _cmsTRANSFORM* info,
440 register cmsUInt16Number wIn[],
441 register cmsUInt8Number* accum,
442 register cmsUInt32Number Stride)
444 wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(FROM_8_TO_16(*accum)); accum++; // L
448 cmsUNUSED_PARAMETER(info);
449 cmsUNUSED_PARAMETER(Stride);
454 cmsUInt8Number* UnrollAnyWords(register _cmsTRANSFORM* info,
455 register cmsUInt16Number wIn[],
456 register cmsUInt8Number* accum,
457 register cmsUInt32Number Stride)
459 int nChan = T_CHANNELS(info -> InputFormat);
460 int SwapEndian = T_ENDIAN16(info -> InputFormat);
461 int DoSwap = T_DOSWAP(info ->InputFormat);
462 int Reverse = T_FLAVOR(info ->InputFormat);
463 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
464 int Extra = T_EXTRA(info -> InputFormat);
465 int ExtraFirst = DoSwap && !SwapFirst;
469 accum += Extra * sizeof(cmsUInt16Number);
472 for (i=0; i < nChan; i++) {
474 int index = DoSwap ? (nChan - i - 1) : i;
475 cmsUInt16Number v = *(cmsUInt16Number*) accum;
478 v = CHANGE_ENDIAN(v);
480 wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
482 accum += sizeof(cmsUInt16Number);
486 accum += Extra * sizeof(cmsUInt16Number);
489 if (Extra == 0 && SwapFirst) {
491 cmsUInt16Number tmp = wIn[0];
493 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
499 cmsUNUSED_PARAMETER(Stride);
503 cmsUInt8Number* UnrollPlanarWords(register _cmsTRANSFORM* info,
504 register cmsUInt16Number wIn[],
505 register cmsUInt8Number* accum,
506 register cmsUInt32Number Stride)
508 int nChan = T_CHANNELS(info -> InputFormat);
509 int DoSwap= T_DOSWAP(info ->InputFormat);
510 int Reverse= T_FLAVOR(info ->InputFormat);
511 int SwapEndian = T_ENDIAN16(info -> InputFormat);
513 cmsUInt8Number* Init = accum;
516 accum += T_EXTRA(info -> InputFormat) * Stride * sizeof(cmsUInt16Number);
519 for (i=0; i < nChan; i++) {
521 int index = DoSwap ? (nChan - i - 1) : i;
522 cmsUInt16Number v = *(cmsUInt16Number*) accum;
525 v = CHANGE_ENDIAN(v);
527 wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
529 accum += Stride * sizeof(cmsUInt16Number);
532 return (Init + sizeof(cmsUInt16Number));
537 cmsUInt8Number* Unroll4Words(register _cmsTRANSFORM* info,
538 register cmsUInt16Number wIn[],
539 register cmsUInt8Number* accum,
540 register cmsUInt32Number Stride)
542 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
543 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
544 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
545 wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
549 cmsUNUSED_PARAMETER(info);
550 cmsUNUSED_PARAMETER(Stride);
554 cmsUInt8Number* Unroll4WordsReverse(register _cmsTRANSFORM* info,
555 register cmsUInt16Number wIn[],
556 register cmsUInt8Number* accum,
557 register cmsUInt32Number Stride)
559 wIn[0] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // C
560 wIn[1] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // M
561 wIn[2] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // Y
562 wIn[3] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // K
566 cmsUNUSED_PARAMETER(info);
567 cmsUNUSED_PARAMETER(Stride);
571 cmsUInt8Number* Unroll4WordsSwapFirst(register _cmsTRANSFORM* info,
572 register cmsUInt16Number wIn[],
573 register cmsUInt8Number* accum,
574 register cmsUInt32Number Stride)
576 wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
577 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
578 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
579 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
583 cmsUNUSED_PARAMETER(info);
584 cmsUNUSED_PARAMETER(Stride);
589 cmsUInt8Number* Unroll4WordsSwap(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[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
596 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
597 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
601 cmsUNUSED_PARAMETER(info);
602 cmsUNUSED_PARAMETER(Stride);
606 cmsUInt8Number* Unroll4WordsSwapSwapFirst(register _cmsTRANSFORM* info,
607 register cmsUInt16Number wIn[],
608 register cmsUInt8Number* accum,
609 register cmsUInt32Number Stride)
611 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // K
612 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // Y
613 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // M
614 wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // C
618 cmsUNUSED_PARAMETER(info);
619 cmsUNUSED_PARAMETER(Stride);
623 cmsUInt8Number* Unroll3Words(register _cmsTRANSFORM* info,
624 register cmsUInt16Number wIn[],
625 register cmsUInt8Number* accum,
626 register cmsUInt32Number Stride)
628 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C R
629 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M G
630 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y B
634 cmsUNUSED_PARAMETER(info);
635 cmsUNUSED_PARAMETER(Stride);
639 cmsUInt8Number* Unroll3WordsSwap(register _cmsTRANSFORM* info,
640 register cmsUInt16Number wIn[],
641 register cmsUInt8Number* accum,
642 register cmsUInt32Number Stride)
644 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // C R
645 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M G
646 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // Y B
650 cmsUNUSED_PARAMETER(info);
651 cmsUNUSED_PARAMETER(Stride);
655 cmsUInt8Number* Unroll3WordsSkip1Swap(register _cmsTRANSFORM* info,
656 register cmsUInt16Number wIn[],
657 register cmsUInt8Number* accum,
658 register cmsUInt32Number Stride)
661 wIn[2] = *(cmsUInt16Number*) accum; accum += 2; // R
662 wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // G
663 wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // B
667 cmsUNUSED_PARAMETER(info);
668 cmsUNUSED_PARAMETER(Stride);
672 cmsUInt8Number* Unroll3WordsSkip1SwapFirst(register _cmsTRANSFORM* info,
673 register cmsUInt16Number wIn[],
674 register cmsUInt8Number* accum,
675 register cmsUInt32Number Stride)
678 wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // R
679 wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // G
680 wIn[2] = *(cmsUInt16Number*) accum; accum += 2; // B
684 cmsUNUSED_PARAMETER(info);
685 cmsUNUSED_PARAMETER(Stride);
689 cmsUInt8Number* Unroll1Word(register _cmsTRANSFORM* info,
690 register cmsUInt16Number wIn[],
691 register cmsUInt8Number* accum,
692 register cmsUInt32Number Stride)
694 wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // L
698 cmsUNUSED_PARAMETER(info);
699 cmsUNUSED_PARAMETER(Stride);
703 cmsUInt8Number* Unroll1WordReversed(register _cmsTRANSFORM* info,
704 register cmsUInt16Number wIn[],
705 register cmsUInt8Number* accum,
706 register cmsUInt32Number Stride)
708 wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2;
712 cmsUNUSED_PARAMETER(info);
713 cmsUNUSED_PARAMETER(Stride);
717 cmsUInt8Number* Unroll1WordSkip3(register _cmsTRANSFORM* info,
718 register cmsUInt16Number wIn[],
719 register cmsUInt8Number* accum,
720 register cmsUInt32Number Stride)
722 wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum;
728 cmsUNUSED_PARAMETER(info);
729 cmsUNUSED_PARAMETER(Stride);
733 cmsUInt8Number* Unroll2Words(register _cmsTRANSFORM* info,
734 register cmsUInt16Number wIn[],
735 register cmsUInt8Number* accum,
736 register cmsUInt32Number Stride)
738 wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // ch1
739 wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // ch2
743 cmsUNUSED_PARAMETER(info);
744 cmsUNUSED_PARAMETER(Stride);
748 // This is a conversion of Lab double to 16 bits
750 cmsUInt8Number* UnrollLabDoubleTo16(register _cmsTRANSFORM* info,
751 register cmsUInt16Number wIn[],
752 register cmsUInt8Number* accum,
753 register cmsUInt32Number Stride)
755 if (T_PLANAR(info -> InputFormat)) {
757 cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
763 Lab.b = Pt[Stride*2];
765 cmsFloat2LabEncoded(wIn, &Lab);
766 return accum + sizeof(cmsFloat64Number);
770 cmsFloat2LabEncoded(wIn, (cmsCIELab*) accum);
771 accum += sizeof(cmsCIELab) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat64Number);
776 // This is a conversion of XYZ double to 16 bits
778 cmsUInt8Number* UnrollXYZDoubleTo16(register _cmsTRANSFORM* info,
779 register cmsUInt16Number wIn[],
780 register cmsUInt8Number* accum,
781 register cmsUInt32Number Stride)
783 if (T_PLANAR(info -> InputFormat)) {
785 cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
790 XYZ.Z = Pt[Stride*2];
791 cmsFloat2XYZEncoded(wIn, &XYZ);
793 return accum + sizeof(cmsFloat64Number);
798 cmsFloat2XYZEncoded(wIn, (cmsCIEXYZ*) accum);
799 accum += sizeof(cmsCIEXYZ) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat64Number);
805 // Check if space is marked as ink
806 cmsINLINE cmsBool IsInkSpace(cmsUInt32Number Type)
808 switch (T_COLORSPACE(Type)) {
822 case PT_MCH15: return TRUE;
824 default: return FALSE;
828 // Inks does come in percentage, remaining cases are between 0..1.0, again to 16 bits
830 cmsUInt8Number* UnrollDoubleTo16(register _cmsTRANSFORM* info,
831 register cmsUInt16Number wIn[],
832 register cmsUInt8Number* accum,
833 register cmsUInt32Number Stride)
835 cmsFloat64Number* Inks = (cmsFloat64Number*) accum;
836 int nChan = T_CHANNELS(info -> InputFormat);
837 int Planar = T_PLANAR(info -> InputFormat);
840 cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
842 for (i=0; i < nChan; i++) {
846 v = Inks[i * Stride];
850 wIn[i] = _cmsQuickSaturateWord(v * maximum);
853 if (T_PLANAR(info -> InputFormat))
854 return accum + sizeof(cmsFloat64Number);
856 return accum + (nChan + T_EXTRA(info ->InputFormat)) * sizeof(cmsFloat64Number);
860 cmsUInt8Number* UnrollFloatTo16(register _cmsTRANSFORM* info,
861 register cmsUInt16Number wIn[],
862 register cmsUInt8Number* accum,
863 register cmsUInt32Number Stride)
865 cmsFloat32Number* Inks = (cmsFloat32Number*) accum;
866 int nChan = T_CHANNELS(info -> InputFormat);
867 int Planar = T_PLANAR(info -> InputFormat);
870 cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
872 for (i=0; i < nChan; i++) {
876 v = Inks[i * Stride];
880 wIn[i] = _cmsQuickSaturateWord(v * maximum);
883 if (T_PLANAR(info -> InputFormat))
884 return accum + sizeof(cmsFloat32Number);
886 return accum + (nChan + T_EXTRA(info ->InputFormat)) * sizeof(cmsFloat32Number);
890 // For 1 channel, we need to duplicate data (it comes in 0..1.0 range)
892 cmsUInt8Number* UnrollDouble1Chan(register _cmsTRANSFORM* info,
893 register cmsUInt16Number wIn[],
894 register cmsUInt8Number* accum,
895 register cmsUInt32Number Stride)
897 cmsFloat64Number* Inks = (cmsFloat64Number*) accum;
899 wIn[0] = wIn[1] = wIn[2] = _cmsQuickSaturateWord(Inks[0] * 65535.0);
901 return accum + sizeof(cmsFloat64Number);
903 cmsUNUSED_PARAMETER(info);
904 cmsUNUSED_PARAMETER(Stride);
907 //-------------------------------------------------------------------------------------------------------------------
909 // True float transformation.
911 // For anything going from cmsFloat32Number
913 cmsUInt8Number* UnrollFloatsToFloat(_cmsTRANSFORM* info,
914 cmsFloat32Number wIn[],
915 cmsUInt8Number* accum,
916 cmsUInt32Number Stride)
918 cmsFloat32Number* Inks = (cmsFloat32Number*) accum;
919 int nChan = T_CHANNELS(info -> InputFormat);
920 int Planar = T_PLANAR(info -> InputFormat);
922 cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 100.0 : 1.0;
925 for (i=0; i < nChan; i++) {
928 wIn[i] = (cmsFloat32Number) (Inks[i * Stride] / maximum);
930 wIn[i] = (cmsFloat32Number) (Inks[i] / maximum);
933 if (T_PLANAR(info -> InputFormat))
934 return accum + sizeof(cmsFloat32Number);
936 return accum + (nChan + T_EXTRA(info ->InputFormat)) * sizeof(cmsFloat32Number);
939 // For anything going from double
941 cmsUInt8Number* UnrollDoublesToFloat(_cmsTRANSFORM* info,
942 cmsFloat32Number wIn[],
943 cmsUInt8Number* accum,
944 cmsUInt32Number Stride)
946 cmsFloat64Number* Inks = (cmsFloat64Number*) accum;
947 int nChan = T_CHANNELS(info -> InputFormat);
948 int Planar = T_PLANAR(info -> InputFormat);
950 cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 100.0 : 1.0;
952 for (i=0; i < nChan; i++) {
955 wIn[i] = (cmsFloat32Number) (Inks[i * Stride] / maximum);
957 wIn[i] = (cmsFloat32Number) (Inks[i] / maximum);
960 if (T_PLANAR(info -> InputFormat))
961 return accum + sizeof(cmsFloat64Number);
963 return accum + (nChan + T_EXTRA(info ->InputFormat)) * sizeof(cmsFloat64Number);
967 // From Lab double to cmsFloat32Number
969 cmsUInt8Number* UnrollLabDoubleToFloat(_cmsTRANSFORM* info,
970 cmsFloat32Number wIn[],
971 cmsUInt8Number* accum,
972 cmsUInt32Number Stride)
974 cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
976 if (T_PLANAR(info -> InputFormat)) {
978 wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
979 wIn[1] = (cmsFloat32Number) ((Pt[Stride] + 128) / 255.0); // form -128..+127 to 0..1
980 wIn[2] = (cmsFloat32Number) ((Pt[Stride*2] + 128) / 255.0);
982 return accum + sizeof(cmsFloat64Number);
986 wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
987 wIn[1] = (cmsFloat32Number) ((Pt[1] + 128) / 255.0); // form -128..+127 to 0..1
988 wIn[2] = (cmsFloat32Number) ((Pt[2] + 128) / 255.0);
990 accum += sizeof(cmsFloat64Number)*(3 + T_EXTRA(info ->InputFormat));
995 // From Lab double to cmsFloat32Number
997 cmsUInt8Number* UnrollLabFloatToFloat(_cmsTRANSFORM* info,
998 cmsFloat32Number wIn[],
999 cmsUInt8Number* accum,
1000 cmsUInt32Number Stride)
1002 cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
1004 if (T_PLANAR(info -> InputFormat)) {
1006 wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
1007 wIn[1] = (cmsFloat32Number) ((Pt[Stride] + 128) / 255.0); // form -128..+127 to 0..1
1008 wIn[2] = (cmsFloat32Number) ((Pt[Stride*2] + 128) / 255.0);
1010 return accum + sizeof(cmsFloat32Number);
1014 wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
1015 wIn[1] = (cmsFloat32Number) ((Pt[1] + 128) / 255.0); // form -128..+127 to 0..1
1016 wIn[2] = (cmsFloat32Number) ((Pt[2] + 128) / 255.0);
1018 accum += sizeof(cmsFloat32Number)*(3 + T_EXTRA(info ->InputFormat));
1024 // 1.15 fixed point, that means maximum value is MAX_ENCODEABLE_XYZ (0xFFFF)
1026 cmsUInt8Number* UnrollXYZDoubleToFloat(_cmsTRANSFORM* info,
1027 cmsFloat32Number wIn[],
1028 cmsUInt8Number* accum,
1029 cmsUInt32Number Stride)
1031 cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
1033 if (T_PLANAR(info -> InputFormat)) {
1035 wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
1036 wIn[1] = (cmsFloat32Number) (Pt[Stride] / MAX_ENCODEABLE_XYZ);
1037 wIn[2] = (cmsFloat32Number) (Pt[Stride*2] / MAX_ENCODEABLE_XYZ);
1039 return accum + sizeof(cmsFloat64Number);
1043 wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
1044 wIn[1] = (cmsFloat32Number) (Pt[1] / MAX_ENCODEABLE_XYZ);
1045 wIn[2] = (cmsFloat32Number) (Pt[2] / MAX_ENCODEABLE_XYZ);
1047 accum += sizeof(cmsFloat64Number)*(3 + T_EXTRA(info ->InputFormat));
1053 cmsUInt8Number* UnrollXYZFloatToFloat(_cmsTRANSFORM* info,
1054 cmsFloat32Number wIn[],
1055 cmsUInt8Number* accum,
1056 cmsUInt32Number Stride)
1058 cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
1060 if (T_PLANAR(info -> InputFormat)) {
1062 wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
1063 wIn[1] = (cmsFloat32Number) (Pt[Stride] / MAX_ENCODEABLE_XYZ);
1064 wIn[2] = (cmsFloat32Number) (Pt[Stride*2] / MAX_ENCODEABLE_XYZ);
1066 return accum + sizeof(cmsFloat32Number);
1070 wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
1071 wIn[1] = (cmsFloat32Number) (Pt[1] / MAX_ENCODEABLE_XYZ);
1072 wIn[2] = (cmsFloat32Number) (Pt[2] / MAX_ENCODEABLE_XYZ);
1074 accum += sizeof(cmsFloat32Number)*(3 + T_EXTRA(info ->InputFormat));
1079 // Packing routines -----------------------------------------------------------------------------------------------------------
1082 // Generic chunky for byte
1085 cmsUInt8Number* PackAnyBytes(register _cmsTRANSFORM* info,
1086 register cmsUInt16Number wOut[],
1087 register cmsUInt8Number* output,
1088 register cmsUInt32Number Stride)
1090 int nChan = T_CHANNELS(info -> OutputFormat);
1091 int DoSwap = T_DOSWAP(info ->OutputFormat);
1092 int Reverse = T_FLAVOR(info ->OutputFormat);
1093 int Extra = T_EXTRA(info -> OutputFormat);
1094 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
1095 int ExtraFirst = DoSwap && !SwapFirst;
1096 cmsUInt8Number* swap1;
1097 cmsUInt8Number v = 0;
1106 for (i=0; i < nChan; i++) {
1108 int index = DoSwap ? (nChan - i - 1) : i;
1110 v = FROM_16_TO_8(wOut[index]);
1113 v = REVERSE_FLAVOR_8(v);
1122 if (Extra == 0 && SwapFirst) {
1124 memmove(swap1 + 1, swap1, nChan-1);
1131 cmsUNUSED_PARAMETER(Stride);
1137 cmsUInt8Number* PackAnyWords(register _cmsTRANSFORM* info,
1138 register cmsUInt16Number wOut[],
1139 register cmsUInt8Number* output,
1140 register cmsUInt32Number Stride)
1142 int nChan = T_CHANNELS(info -> OutputFormat);
1143 int SwapEndian = T_ENDIAN16(info -> InputFormat);
1144 int DoSwap = T_DOSWAP(info ->OutputFormat);
1145 int Reverse = T_FLAVOR(info ->OutputFormat);
1146 int Extra = T_EXTRA(info -> OutputFormat);
1147 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
1148 int ExtraFirst = DoSwap && !SwapFirst;
1149 cmsUInt16Number* swap1;
1150 cmsUInt16Number v = 0;
1153 swap1 = (cmsUInt16Number*) output;
1156 output += Extra * sizeof(cmsUInt16Number);
1159 for (i=0; i < nChan; i++) {
1161 int index = DoSwap ? (nChan - i - 1) : i;
1166 v = CHANGE_ENDIAN(v);
1169 v = REVERSE_FLAVOR_16(v);
1171 *(cmsUInt16Number*) output = v;
1173 output += sizeof(cmsUInt16Number);
1177 output += Extra * sizeof(cmsUInt16Number);
1180 if (Extra == 0 && SwapFirst) {
1182 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number));
1189 cmsUNUSED_PARAMETER(Stride);
1194 cmsUInt8Number* PackPlanarBytes(register _cmsTRANSFORM* info,
1195 register cmsUInt16Number wOut[],
1196 register cmsUInt8Number* output,
1197 register cmsUInt32Number Stride)
1199 int nChan = T_CHANNELS(info -> OutputFormat);
1200 int DoSwap = T_DOSWAP(info ->OutputFormat);
1201 int Reverse= T_FLAVOR(info ->OutputFormat);
1203 cmsUInt8Number* Init = output;
1205 for (i=0; i < nChan; i++) {
1207 int index = DoSwap ? (nChan - i - 1) : i;
1208 cmsUInt8Number v = FROM_16_TO_8(wOut[index]);
1210 *(cmsUInt8Number*) output = (cmsUInt8Number) (Reverse ? REVERSE_FLAVOR_8(v) : v);
1216 cmsUNUSED_PARAMETER(Stride);
1221 cmsUInt8Number* PackPlanarWords(register _cmsTRANSFORM* info,
1222 register cmsUInt16Number wOut[],
1223 register cmsUInt8Number* output,
1224 register cmsUInt32Number Stride)
1226 int nChan = T_CHANNELS(info -> OutputFormat);
1227 int DoSwap = T_DOSWAP(info ->OutputFormat);
1228 int Reverse= T_FLAVOR(info ->OutputFormat);
1229 int SwapEndian = T_ENDIAN16(info -> OutputFormat);
1231 cmsUInt8Number* Init = output;
1235 output += T_EXTRA(info -> OutputFormat) * Stride * sizeof(cmsUInt16Number);
1238 for (i=0; i < nChan; i++) {
1240 int index = DoSwap ? (nChan - i - 1) : i;
1245 v = CHANGE_ENDIAN(v);
1248 v = REVERSE_FLAVOR_16(v);
1250 *(cmsUInt16Number*) output = v;
1251 output += (Stride * sizeof(cmsUInt16Number));
1254 return (Init + sizeof(cmsUInt16Number));
1257 // CMYKcm (unrolled for speed)
1260 cmsUInt8Number* Pack6Bytes(register _cmsTRANSFORM* info,
1261 register cmsUInt16Number wOut[],
1262 register cmsUInt8Number* output,
1263 register cmsUInt32Number Stride)
1265 *output++ = FROM_16_TO_8(wOut[0]);
1266 *output++ = FROM_16_TO_8(wOut[1]);
1267 *output++ = FROM_16_TO_8(wOut[2]);
1268 *output++ = FROM_16_TO_8(wOut[3]);
1269 *output++ = FROM_16_TO_8(wOut[4]);
1270 *output++ = FROM_16_TO_8(wOut[5]);
1274 cmsUNUSED_PARAMETER(info);
1275 cmsUNUSED_PARAMETER(Stride);
1281 cmsUInt8Number* Pack6BytesSwap(register _cmsTRANSFORM* info,
1282 register cmsUInt16Number wOut[],
1283 register cmsUInt8Number* output,
1284 register cmsUInt32Number Stride)
1286 *output++ = FROM_16_TO_8(wOut[5]);
1287 *output++ = FROM_16_TO_8(wOut[4]);
1288 *output++ = FROM_16_TO_8(wOut[3]);
1289 *output++ = FROM_16_TO_8(wOut[2]);
1290 *output++ = FROM_16_TO_8(wOut[1]);
1291 *output++ = FROM_16_TO_8(wOut[0]);
1295 cmsUNUSED_PARAMETER(info);
1296 cmsUNUSED_PARAMETER(Stride);
1301 cmsUInt8Number* Pack6Words(register _cmsTRANSFORM* info,
1302 register cmsUInt16Number wOut[],
1303 register cmsUInt8Number* output,
1304 register cmsUInt32Number Stride)
1306 *(cmsUInt16Number*) output = wOut[0];
1308 *(cmsUInt16Number*) output = wOut[1];
1310 *(cmsUInt16Number*) output = wOut[2];
1312 *(cmsUInt16Number*) output = wOut[3];
1314 *(cmsUInt16Number*) output = wOut[4];
1316 *(cmsUInt16Number*) output = wOut[5];
1321 cmsUNUSED_PARAMETER(info);
1322 cmsUNUSED_PARAMETER(Stride);
1327 cmsUInt8Number* Pack6WordsSwap(register _cmsTRANSFORM* info,
1328 register cmsUInt16Number wOut[],
1329 register cmsUInt8Number* output,
1330 register cmsUInt32Number Stride)
1332 *(cmsUInt16Number*) output = wOut[5];
1334 *(cmsUInt16Number*) output = wOut[4];
1336 *(cmsUInt16Number*) output = wOut[3];
1338 *(cmsUInt16Number*) output = wOut[2];
1340 *(cmsUInt16Number*) output = wOut[1];
1342 *(cmsUInt16Number*) output = wOut[0];
1347 cmsUNUSED_PARAMETER(info);
1348 cmsUNUSED_PARAMETER(Stride);
1353 cmsUInt8Number* Pack4Bytes(register _cmsTRANSFORM* info,
1354 register cmsUInt16Number wOut[],
1355 register cmsUInt8Number* output,
1356 register cmsUInt32Number Stride)
1358 *output++ = FROM_16_TO_8(wOut[0]);
1359 *output++ = FROM_16_TO_8(wOut[1]);
1360 *output++ = FROM_16_TO_8(wOut[2]);
1361 *output++ = FROM_16_TO_8(wOut[3]);
1365 cmsUNUSED_PARAMETER(info);
1366 cmsUNUSED_PARAMETER(Stride);
1370 cmsUInt8Number* Pack4BytesReverse(register _cmsTRANSFORM* info,
1371 register cmsUInt16Number wOut[],
1372 register cmsUInt8Number* output,
1373 register cmsUInt32Number Stride)
1375 *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[0]));
1376 *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[1]));
1377 *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[2]));
1378 *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[3]));
1382 cmsUNUSED_PARAMETER(info);
1383 cmsUNUSED_PARAMETER(Stride);
1388 cmsUInt8Number* Pack4BytesSwapFirst(register _cmsTRANSFORM* info,
1389 register cmsUInt16Number wOut[],
1390 register cmsUInt8Number* output,
1391 register cmsUInt32Number Stride)
1393 *output++ = FROM_16_TO_8(wOut[3]);
1394 *output++ = FROM_16_TO_8(wOut[0]);
1395 *output++ = FROM_16_TO_8(wOut[1]);
1396 *output++ = FROM_16_TO_8(wOut[2]);
1400 cmsUNUSED_PARAMETER(info);
1401 cmsUNUSED_PARAMETER(Stride);
1406 cmsUInt8Number* Pack4BytesSwap(register _cmsTRANSFORM* info,
1407 register cmsUInt16Number wOut[],
1408 register cmsUInt8Number* output,
1409 register cmsUInt32Number Stride)
1411 *output++ = FROM_16_TO_8(wOut[3]);
1412 *output++ = FROM_16_TO_8(wOut[2]);
1413 *output++ = FROM_16_TO_8(wOut[1]);
1414 *output++ = FROM_16_TO_8(wOut[0]);
1418 cmsUNUSED_PARAMETER(info);
1419 cmsUNUSED_PARAMETER(Stride);
1423 cmsUInt8Number* Pack4BytesSwapSwapFirst(register _cmsTRANSFORM* info,
1424 register cmsUInt16Number wOut[],
1425 register cmsUInt8Number* output,
1426 register cmsUInt32Number Stride)
1428 *output++ = FROM_16_TO_8(wOut[2]);
1429 *output++ = FROM_16_TO_8(wOut[1]);
1430 *output++ = FROM_16_TO_8(wOut[0]);
1431 *output++ = FROM_16_TO_8(wOut[3]);
1435 cmsUNUSED_PARAMETER(info);
1436 cmsUNUSED_PARAMETER(Stride);
1440 cmsUInt8Number* Pack4Words(register _cmsTRANSFORM* info,
1441 register cmsUInt16Number wOut[],
1442 register cmsUInt8Number* output,
1443 register cmsUInt32Number Stride)
1445 *(cmsUInt16Number*) output = wOut[0];
1447 *(cmsUInt16Number*) output = wOut[1];
1449 *(cmsUInt16Number*) output = wOut[2];
1451 *(cmsUInt16Number*) output = wOut[3];
1456 cmsUNUSED_PARAMETER(info);
1457 cmsUNUSED_PARAMETER(Stride);
1461 cmsUInt8Number* Pack4WordsReverse(register _cmsTRANSFORM* info,
1462 register cmsUInt16Number wOut[],
1463 register cmsUInt8Number* output,
1464 register cmsUInt32Number Stride)
1466 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[0]);
1468 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[1]);
1470 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[2]);
1472 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[3]);
1477 cmsUNUSED_PARAMETER(info);
1478 cmsUNUSED_PARAMETER(Stride);
1483 cmsUInt8Number* Pack4WordsSwap(register _cmsTRANSFORM* info,
1484 register cmsUInt16Number wOut[],
1485 register cmsUInt8Number* output,
1486 register cmsUInt32Number Stride)
1488 *(cmsUInt16Number*) output = wOut[3];
1490 *(cmsUInt16Number*) output = wOut[2];
1492 *(cmsUInt16Number*) output = wOut[1];
1494 *(cmsUInt16Number*) output = wOut[0];
1499 cmsUNUSED_PARAMETER(info);
1500 cmsUNUSED_PARAMETER(Stride);
1505 cmsUInt8Number* Pack4WordsBigEndian(register _cmsTRANSFORM* info,
1506 register cmsUInt16Number wOut[],
1507 register cmsUInt8Number* output,
1508 register cmsUInt32Number Stride)
1510 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
1512 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[1]);
1514 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[2]);
1516 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[3]);
1521 cmsUNUSED_PARAMETER(info);
1522 cmsUNUSED_PARAMETER(Stride);
1527 cmsUInt8Number* PackLabV2_8(register _cmsTRANSFORM* info,
1528 register cmsUInt16Number wOut[],
1529 register cmsUInt8Number* output,
1530 register cmsUInt32Number Stride)
1532 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[0]));
1533 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[1]));
1534 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[2]));
1538 cmsUNUSED_PARAMETER(info);
1539 cmsUNUSED_PARAMETER(Stride);
1543 cmsUInt8Number* PackALabV2_8(register _cmsTRANSFORM* info,
1544 register cmsUInt16Number wOut[],
1545 register cmsUInt8Number* output,
1546 register cmsUInt32Number Stride)
1549 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[0]));
1550 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[1]));
1551 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[2]));
1555 cmsUNUSED_PARAMETER(info);
1556 cmsUNUSED_PARAMETER(Stride);
1560 cmsUInt8Number* PackLabV2_16(register _cmsTRANSFORM* info,
1561 register cmsUInt16Number wOut[],
1562 register cmsUInt8Number* output,
1563 register cmsUInt32Number Stride)
1565 *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[0]);
1567 *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[1]);
1569 *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[2]);
1574 cmsUNUSED_PARAMETER(info);
1575 cmsUNUSED_PARAMETER(Stride);
1579 cmsUInt8Number* Pack3Bytes(register _cmsTRANSFORM* info,
1580 register cmsUInt16Number wOut[],
1581 register cmsUInt8Number* output,
1582 register cmsUInt32Number Stride)
1584 *output++ = FROM_16_TO_8(wOut[0]);
1585 *output++ = FROM_16_TO_8(wOut[1]);
1586 *output++ = FROM_16_TO_8(wOut[2]);
1590 cmsUNUSED_PARAMETER(info);
1591 cmsUNUSED_PARAMETER(Stride);
1595 cmsUInt8Number* Pack3BytesOptimized(register _cmsTRANSFORM* info,
1596 register cmsUInt16Number wOut[],
1597 register cmsUInt8Number* output,
1598 register cmsUInt32Number Stride)
1600 *output++ = (wOut[0] & 0xFF);
1601 *output++ = (wOut[1] & 0xFF);
1602 *output++ = (wOut[2] & 0xFF);
1606 cmsUNUSED_PARAMETER(info);
1607 cmsUNUSED_PARAMETER(Stride);
1611 cmsUInt8Number* Pack3BytesSwap(register _cmsTRANSFORM* info,
1612 register cmsUInt16Number wOut[],
1613 register cmsUInt8Number* output,
1614 register cmsUInt32Number Stride)
1616 *output++ = FROM_16_TO_8(wOut[2]);
1617 *output++ = FROM_16_TO_8(wOut[1]);
1618 *output++ = FROM_16_TO_8(wOut[0]);
1622 cmsUNUSED_PARAMETER(info);
1623 cmsUNUSED_PARAMETER(Stride);
1627 cmsUInt8Number* Pack3BytesSwapOptimized(register _cmsTRANSFORM* info,
1628 register cmsUInt16Number wOut[],
1629 register cmsUInt8Number* output,
1630 register cmsUInt32Number Stride)
1632 *output++ = (wOut[2] & 0xFF);
1633 *output++ = (wOut[1] & 0xFF);
1634 *output++ = (wOut[0] & 0xFF);
1638 cmsUNUSED_PARAMETER(info);
1639 cmsUNUSED_PARAMETER(Stride);
1644 cmsUInt8Number* Pack3Words(register _cmsTRANSFORM* info,
1645 register cmsUInt16Number wOut[],
1646 register cmsUInt8Number* output,
1647 register cmsUInt32Number Stride)
1649 *(cmsUInt16Number*) output = wOut[0];
1651 *(cmsUInt16Number*) output = wOut[1];
1653 *(cmsUInt16Number*) output = wOut[2];
1658 cmsUNUSED_PARAMETER(info);
1659 cmsUNUSED_PARAMETER(Stride);
1663 cmsUInt8Number* Pack3WordsSwap(register _cmsTRANSFORM* info,
1664 register cmsUInt16Number wOut[],
1665 register cmsUInt8Number* output,
1666 register cmsUInt32Number Stride)
1668 *(cmsUInt16Number*) output = wOut[2];
1670 *(cmsUInt16Number*) output = wOut[1];
1672 *(cmsUInt16Number*) output = wOut[0];
1677 cmsUNUSED_PARAMETER(info);
1678 cmsUNUSED_PARAMETER(Stride);
1682 cmsUInt8Number* Pack3WordsBigEndian(register _cmsTRANSFORM* info,
1683 register cmsUInt16Number wOut[],
1684 register cmsUInt8Number* output,
1685 register cmsUInt32Number Stride)
1687 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
1689 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[1]);
1691 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[2]);
1696 cmsUNUSED_PARAMETER(info);
1697 cmsUNUSED_PARAMETER(Stride);
1701 cmsUInt8Number* Pack3BytesAndSkip1(register _cmsTRANSFORM* info,
1702 register cmsUInt16Number wOut[],
1703 register cmsUInt8Number* output,
1704 register cmsUInt32Number Stride)
1706 *output++ = FROM_16_TO_8(wOut[0]);
1707 *output++ = FROM_16_TO_8(wOut[1]);
1708 *output++ = FROM_16_TO_8(wOut[2]);
1713 cmsUNUSED_PARAMETER(info);
1714 cmsUNUSED_PARAMETER(Stride);
1718 cmsUInt8Number* Pack3BytesAndSkip1Optimized(register _cmsTRANSFORM* info,
1719 register cmsUInt16Number wOut[],
1720 register cmsUInt8Number* output,
1721 register cmsUInt32Number Stride)
1723 *output++ = (wOut[0] & 0xFF);
1724 *output++ = (wOut[1] & 0xFF);
1725 *output++ = (wOut[2] & 0xFF);
1730 cmsUNUSED_PARAMETER(info);
1731 cmsUNUSED_PARAMETER(Stride);
1736 cmsUInt8Number* Pack3BytesAndSkip1SwapFirst(register _cmsTRANSFORM* info,
1737 register cmsUInt16Number wOut[],
1738 register cmsUInt8Number* output,
1739 register cmsUInt32Number Stride)
1742 *output++ = FROM_16_TO_8(wOut[0]);
1743 *output++ = FROM_16_TO_8(wOut[1]);
1744 *output++ = FROM_16_TO_8(wOut[2]);
1748 cmsUNUSED_PARAMETER(info);
1749 cmsUNUSED_PARAMETER(Stride);
1753 cmsUInt8Number* Pack3BytesAndSkip1SwapFirstOptimized(register _cmsTRANSFORM* info,
1754 register cmsUInt16Number wOut[],
1755 register cmsUInt8Number* output,
1756 register cmsUInt32Number Stride)
1759 *output++ = (wOut[0] & 0xFF);
1760 *output++ = (wOut[1] & 0xFF);
1761 *output++ = (wOut[2] & 0xFF);
1765 cmsUNUSED_PARAMETER(info);
1766 cmsUNUSED_PARAMETER(Stride);
1770 cmsUInt8Number* Pack3BytesAndSkip1Swap(register _cmsTRANSFORM* info,
1771 register cmsUInt16Number wOut[],
1772 register cmsUInt8Number* output,
1773 register cmsUInt32Number Stride)
1776 *output++ = FROM_16_TO_8(wOut[2]);
1777 *output++ = FROM_16_TO_8(wOut[1]);
1778 *output++ = FROM_16_TO_8(wOut[0]);
1782 cmsUNUSED_PARAMETER(info);
1783 cmsUNUSED_PARAMETER(Stride);
1787 cmsUInt8Number* Pack3BytesAndSkip1SwapOptimized(register _cmsTRANSFORM* info,
1788 register cmsUInt16Number wOut[],
1789 register cmsUInt8Number* output,
1790 register cmsUInt32Number Stride)
1793 *output++ = (wOut[2] & 0xFF);
1794 *output++ = (wOut[1] & 0xFF);
1795 *output++ = (wOut[0] & 0xFF);
1799 cmsUNUSED_PARAMETER(info);
1800 cmsUNUSED_PARAMETER(Stride);
1805 cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirst(register _cmsTRANSFORM* info,
1806 register cmsUInt16Number wOut[],
1807 register cmsUInt8Number* output,
1808 register cmsUInt32Number Stride)
1810 *output++ = FROM_16_TO_8(wOut[2]);
1811 *output++ = FROM_16_TO_8(wOut[1]);
1812 *output++ = FROM_16_TO_8(wOut[0]);
1817 cmsUNUSED_PARAMETER(info);
1818 cmsUNUSED_PARAMETER(Stride);
1822 cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirstOptimized(register _cmsTRANSFORM* info,
1823 register cmsUInt16Number wOut[],
1824 register cmsUInt8Number* output,
1825 register cmsUInt32Number Stride)
1827 *output++ = (wOut[2] & 0xFF);
1828 *output++ = (wOut[1] & 0xFF);
1829 *output++ = (wOut[0] & 0xFF);
1834 cmsUNUSED_PARAMETER(info);
1835 cmsUNUSED_PARAMETER(Stride);
1839 cmsUInt8Number* Pack3WordsAndSkip1(register _cmsTRANSFORM* info,
1840 register cmsUInt16Number wOut[],
1841 register cmsUInt8Number* output,
1842 register cmsUInt32Number Stride)
1844 *(cmsUInt16Number*) output = wOut[0];
1846 *(cmsUInt16Number*) output = wOut[1];
1848 *(cmsUInt16Number*) output = wOut[2];
1854 cmsUNUSED_PARAMETER(info);
1855 cmsUNUSED_PARAMETER(Stride);
1859 cmsUInt8Number* Pack3WordsAndSkip1Swap(register _cmsTRANSFORM* info,
1860 register cmsUInt16Number wOut[],
1861 register cmsUInt8Number* output,
1862 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);
1880 cmsUInt8Number* Pack3WordsAndSkip1SwapFirst(register _cmsTRANSFORM* info,
1881 register cmsUInt16Number wOut[],
1882 register cmsUInt8Number* output,
1883 register cmsUInt32Number Stride)
1886 *(cmsUInt16Number*) output = wOut[0];
1888 *(cmsUInt16Number*) output = wOut[1];
1890 *(cmsUInt16Number*) output = wOut[2];
1895 cmsUNUSED_PARAMETER(info);
1896 cmsUNUSED_PARAMETER(Stride);
1901 cmsUInt8Number* Pack3WordsAndSkip1SwapSwapFirst(register _cmsTRANSFORM* info,
1902 register cmsUInt16Number wOut[],
1903 register cmsUInt8Number* output,
1904 register cmsUInt32Number Stride)
1906 *(cmsUInt16Number*) output = wOut[2];
1908 *(cmsUInt16Number*) output = wOut[1];
1910 *(cmsUInt16Number*) output = wOut[0];
1916 cmsUNUSED_PARAMETER(info);
1917 cmsUNUSED_PARAMETER(Stride);
1923 cmsUInt8Number* Pack1Byte(register _cmsTRANSFORM* info,
1924 register cmsUInt16Number wOut[],
1925 register cmsUInt8Number* output,
1926 register cmsUInt32Number Stride)
1928 *output++ = FROM_16_TO_8(wOut[0]);
1932 cmsUNUSED_PARAMETER(info);
1933 cmsUNUSED_PARAMETER(Stride);
1938 cmsUInt8Number* Pack1ByteReversed(register _cmsTRANSFORM* info,
1939 register cmsUInt16Number wOut[],
1940 register cmsUInt8Number* output,
1941 register cmsUInt32Number Stride)
1943 *output++ = FROM_16_TO_8(REVERSE_FLAVOR_16(wOut[0]));
1947 cmsUNUSED_PARAMETER(info);
1948 cmsUNUSED_PARAMETER(Stride);
1953 cmsUInt8Number* Pack1ByteSkip1(register _cmsTRANSFORM* info,
1954 register cmsUInt16Number wOut[],
1955 register cmsUInt8Number* output,
1956 register cmsUInt32Number Stride)
1958 *output++ = FROM_16_TO_8(wOut[0]);
1963 cmsUNUSED_PARAMETER(info);
1964 cmsUNUSED_PARAMETER(Stride);
1969 cmsUInt8Number* Pack1ByteSkip1SwapFirst(register _cmsTRANSFORM* info,
1970 register cmsUInt16Number wOut[],
1971 register cmsUInt8Number* output,
1972 register cmsUInt32Number Stride)
1975 *output++ = FROM_16_TO_8(wOut[0]);
1979 cmsUNUSED_PARAMETER(info);
1980 cmsUNUSED_PARAMETER(Stride);
1984 cmsUInt8Number* Pack1Word(register _cmsTRANSFORM* info,
1985 register cmsUInt16Number wOut[],
1986 register cmsUInt8Number* output,
1987 register cmsUInt32Number Stride)
1989 *(cmsUInt16Number*) output = wOut[0];
1994 cmsUNUSED_PARAMETER(info);
1995 cmsUNUSED_PARAMETER(Stride);
2000 cmsUInt8Number* Pack1WordReversed(register _cmsTRANSFORM* info,
2001 register cmsUInt16Number wOut[],
2002 register cmsUInt8Number* output,
2003 register cmsUInt32Number Stride)
2005 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[0]);
2010 cmsUNUSED_PARAMETER(info);
2011 cmsUNUSED_PARAMETER(Stride);
2015 cmsUInt8Number* Pack1WordBigEndian(register _cmsTRANSFORM* info,
2016 register cmsUInt16Number wOut[],
2017 register cmsUInt8Number* output,
2018 register cmsUInt32Number Stride)
2020 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
2025 cmsUNUSED_PARAMETER(info);
2026 cmsUNUSED_PARAMETER(Stride);
2031 cmsUInt8Number* Pack1WordSkip1(register _cmsTRANSFORM* info,
2032 register cmsUInt16Number wOut[],
2033 register cmsUInt8Number* output,
2034 register cmsUInt32Number Stride)
2036 *(cmsUInt16Number*) output = wOut[0];
2041 cmsUNUSED_PARAMETER(info);
2042 cmsUNUSED_PARAMETER(Stride);
2046 cmsUInt8Number* Pack1WordSkip1SwapFirst(register _cmsTRANSFORM* info,
2047 register cmsUInt16Number wOut[],
2048 register cmsUInt8Number* output,
2049 register cmsUInt32Number Stride)
2052 *(cmsUInt16Number*) output = wOut[0];
2057 cmsUNUSED_PARAMETER(info);
2058 cmsUNUSED_PARAMETER(Stride);
2062 // Unencoded Float values -- don't try optimize speed
2064 cmsUInt8Number* PackLabDoubleFrom16(register _cmsTRANSFORM* info,
2065 register cmsUInt16Number wOut[],
2066 register cmsUInt8Number* output,
2067 register cmsUInt32Number Stride)
2070 if (T_PLANAR(info -> OutputFormat)) {
2073 cmsFloat64Number* Out = (cmsFloat64Number*) output;
2074 cmsLabEncoded2Float(&Lab, wOut);
2077 Out[Stride] = Lab.a;
2078 Out[Stride*2] = Lab.b;
2080 return output + sizeof(cmsFloat64Number);
2084 cmsLabEncoded2Float((cmsCIELab*) output, wOut);
2085 return output + (sizeof(cmsCIELab) + T_EXTRA(info ->OutputFormat) * sizeof(cmsFloat64Number));
2091 cmsUInt8Number* PackXYZDoubleFrom16(register _cmsTRANSFORM* Info,
2092 register cmsUInt16Number wOut[],
2093 register cmsUInt8Number* output,
2094 register cmsUInt32Number Stride)
2096 if (T_PLANAR(Info -> OutputFormat)) {
2099 cmsFloat64Number* Out = (cmsFloat64Number*) output;
2100 cmsXYZEncoded2Float(&XYZ, wOut);
2103 Out[Stride] = XYZ.Y;
2104 Out[Stride*2] = XYZ.Z;
2106 return output + sizeof(cmsFloat64Number);
2111 cmsXYZEncoded2Float((cmsCIEXYZ*) output, wOut);
2113 return output + (sizeof(cmsCIEXYZ) + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
2118 cmsUInt8Number* PackDoubleFrom16(register _cmsTRANSFORM* Info,
2119 register cmsUInt16Number wOut[],
2120 register cmsUInt8Number* output,
2121 register cmsUInt32Number Stride)
2123 cmsFloat64Number* Inks = (cmsFloat64Number*) output;
2124 int nChan = T_CHANNELS(Info -> OutputFormat);
2126 cmsFloat64Number maximum = IsInkSpace(Info ->OutputFormat) ? 655.35 : 65535.0;
2128 if (T_PLANAR(Info -> OutputFormat)) {
2130 for (i=0; i < nChan; i++) {
2132 Inks[i*Stride] = wOut[i] / maximum;
2135 return output + sizeof(cmsFloat64Number);
2139 for (i=0; i < nChan; i++) {
2141 Inks[i] = wOut[i] / maximum;
2145 return output + (nChan + T_EXTRA(Info ->OutputFormat)) * sizeof(cmsFloat64Number);
2151 cmsUInt8Number* PackFloatFrom16(register _cmsTRANSFORM* Info,
2152 register cmsUInt16Number wOut[],
2153 register cmsUInt8Number* output,
2154 register cmsUInt32Number Stride)
2156 cmsFloat32Number* Inks = (cmsFloat32Number*) output;
2157 int nChan = T_CHANNELS(Info -> OutputFormat);
2159 cmsFloat64Number maximum = IsInkSpace(Info ->OutputFormat) ? 655.35 : 65535.0;
2161 if (T_PLANAR(Info -> OutputFormat)) {
2163 for (i=0; i < nChan; i++) {
2165 Inks[i*Stride] = (cmsFloat32Number) (wOut[i] / maximum);
2168 return output + sizeof(cmsFloat32Number);
2172 for (i=0; i < nChan; i++) {
2174 Inks[i] = (cmsFloat32Number) (wOut[i] / maximum);
2178 return output + (nChan + T_EXTRA(Info ->OutputFormat)) * sizeof(cmsFloat32Number);
2184 // --------------------------------------------------------------------------------------------------------
2187 cmsUInt8Number* PackChunkyFloatsFromFloat(_cmsTRANSFORM* info,
2188 cmsFloat32Number wOut[],
2189 cmsUInt8Number* output,
2190 cmsUInt32Number Stride)
2192 int nChan = T_CHANNELS(info -> OutputFormat);
2193 int DoSwap = T_DOSWAP(info ->OutputFormat);
2194 int Reverse = T_FLAVOR(info ->OutputFormat);
2195 int Extra = T_EXTRA(info -> OutputFormat);
2196 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2197 int ExtraFirst = DoSwap && !SwapFirst;
2198 cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
2199 cmsFloat32Number* swap1;
2200 cmsFloat64Number v = 0;
2203 swap1 = (cmsFloat32Number*) output;
2206 output += Extra * sizeof(cmsFloat32Number);
2209 for (i=0; i < nChan; i++) {
2211 int index = DoSwap ? (nChan - i - 1) : i;
2213 v = wOut[index] * maximum;
2218 *(cmsFloat32Number*) output = (cmsFloat32Number) v;
2220 output += sizeof(cmsFloat32Number);
2224 output += Extra * sizeof(cmsFloat32Number);
2227 if (Extra == 0 && SwapFirst) {
2229 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat32Number));
2230 *swap1 = (cmsFloat32Number) v;
2236 cmsUNUSED_PARAMETER(Stride);
2240 cmsUInt8Number* PackPlanarFloatsFromFloat(_cmsTRANSFORM* info,
2241 cmsFloat32Number wOut[],
2242 cmsUInt8Number* output,
2243 cmsUInt32Number Stride)
2245 int nChan = T_CHANNELS(info -> OutputFormat);
2246 int DoSwap = T_DOSWAP(info ->OutputFormat);
2247 int Reverse= T_FLAVOR(info ->OutputFormat);
2249 cmsUInt8Number* Init = output;
2250 cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
2254 output += T_EXTRA(info -> OutputFormat) * Stride * sizeof(cmsFloat32Number);
2257 for (i=0; i < nChan; i++) {
2259 int index = DoSwap ? (nChan - i - 1) : i;
2261 v = wOut[index] * maximum;
2266 *(cmsFloat32Number*) output = (cmsFloat32Number) v;
2267 output += (Stride * sizeof(cmsFloat32Number));
2270 return (Init + sizeof(cmsFloat32Number));
2276 cmsUInt8Number* PackChunkyDoublesFromFloat(_cmsTRANSFORM* info,
2277 cmsFloat32Number wOut[],
2278 cmsUInt8Number* output,
2279 cmsUInt32Number Stride)
2281 int nChan = T_CHANNELS(info -> OutputFormat);
2282 int DoSwap = T_DOSWAP(info ->OutputFormat);
2283 int Reverse = T_FLAVOR(info ->OutputFormat);
2284 int Extra = T_EXTRA(info -> OutputFormat);
2285 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2286 int ExtraFirst = DoSwap && !SwapFirst;
2287 cmsFloat64Number* swap1;
2288 cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
2289 cmsFloat64Number v = 0;
2292 swap1 = (cmsFloat64Number*) output;
2295 output += Extra * sizeof(cmsFloat64Number);
2298 for (i=0; i < nChan; i++) {
2300 int index = DoSwap ? (nChan - i - 1) : i;
2302 v = (cmsFloat64Number) wOut[index] * maximum;
2307 *(cmsFloat64Number*) output = v;
2309 output += sizeof(cmsFloat64Number);
2313 output += Extra * sizeof(cmsFloat64Number);
2316 if (Extra == 0 && SwapFirst) {
2318 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat64Number));
2325 cmsUNUSED_PARAMETER(Stride);
2329 cmsUInt8Number* PackPlanarDoublesFromFloat(_cmsTRANSFORM* info,
2330 cmsFloat32Number wOut[],
2331 cmsUInt8Number* output,
2332 cmsUInt32Number Stride)
2334 int nChan = T_CHANNELS(info -> OutputFormat);
2335 int DoSwap = T_DOSWAP(info ->OutputFormat);
2336 int Reverse= T_FLAVOR(info ->OutputFormat);
2338 cmsUInt8Number* Init = output;
2339 cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
2343 output += T_EXTRA(info -> OutputFormat) * Stride * sizeof(cmsFloat64Number);
2346 for (i=0; i < nChan; i++) {
2348 int index = DoSwap ? (nChan - i - 1) : i;
2350 v = (cmsFloat64Number) wOut[index] * maximum;
2355 *(cmsFloat64Number*) output = v;
2356 output += (Stride * sizeof(cmsFloat64Number));
2359 return (Init + sizeof(cmsFloat64Number));
2366 cmsUInt8Number* PackLabFloatFromFloat(_cmsTRANSFORM* Info,
2367 cmsFloat32Number wOut[],
2368 cmsUInt8Number* output,
2369 cmsUInt32Number Stride)
2371 cmsFloat32Number* Out = (cmsFloat32Number*) output;
2373 if (T_PLANAR(Info -> OutputFormat)) {
2375 Out[0] = (cmsFloat32Number) (wOut[0] * 100.0);
2376 Out[Stride] = (cmsFloat32Number) (wOut[1] * 255.0 - 128.0);
2377 Out[Stride*2] = (cmsFloat32Number) (wOut[2] * 255.0 - 128.0);
2379 return output + sizeof(cmsFloat32Number);
2383 Out[0] = (cmsFloat32Number) (wOut[0] * 100.0);
2384 Out[1] = (cmsFloat32Number) (wOut[1] * 255.0 - 128.0);
2385 Out[2] = (cmsFloat32Number) (wOut[2] * 255.0 - 128.0);
2387 return output + (sizeof(cmsFloat32Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
2393 cmsUInt8Number* PackLabDoubleFromFloat(_cmsTRANSFORM* Info,
2394 cmsFloat32Number wOut[],
2395 cmsUInt8Number* output,
2396 cmsUInt32Number Stride)
2398 cmsFloat64Number* Out = (cmsFloat64Number*) output;
2400 if (T_PLANAR(Info -> OutputFormat)) {
2402 Out[0] = (cmsFloat64Number) (wOut[0] * 100.0);
2403 Out[Stride] = (cmsFloat64Number) (wOut[1] * 255.0 - 128.0);
2404 Out[Stride*2] = (cmsFloat64Number) (wOut[2] * 255.0 - 128.0);
2406 return output + sizeof(cmsFloat64Number);
2410 Out[0] = (cmsFloat64Number) (wOut[0] * 100.0);
2411 Out[1] = (cmsFloat64Number) (wOut[1] * 255.0 - 128.0);
2412 Out[2] = (cmsFloat64Number) (wOut[2] * 255.0 - 128.0);
2414 return output + (sizeof(cmsFloat64Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
2420 // From 0..1 range to 0..MAX_ENCODEABLE_XYZ
2422 cmsUInt8Number* PackXYZFloatFromFloat(_cmsTRANSFORM* Info,
2423 cmsFloat32Number wOut[],
2424 cmsUInt8Number* output,
2425 cmsUInt32Number Stride)
2427 cmsFloat32Number* Out = (cmsFloat32Number*) output;
2429 if (T_PLANAR(Info -> OutputFormat)) {
2431 Out[0] = (cmsFloat32Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
2432 Out[Stride] = (cmsFloat32Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
2433 Out[Stride*2] = (cmsFloat32Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
2435 return output + sizeof(cmsFloat32Number);
2439 Out[0] = (cmsFloat32Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
2440 Out[1] = (cmsFloat32Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
2441 Out[2] = (cmsFloat32Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
2443 return output + (sizeof(cmsFloat32Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
2449 // Same, but convert to double
2451 cmsUInt8Number* PackXYZDoubleFromFloat(_cmsTRANSFORM* Info,
2452 cmsFloat32Number wOut[],
2453 cmsUInt8Number* output,
2454 cmsUInt32Number Stride)
2456 cmsFloat64Number* Out = (cmsFloat64Number*) output;
2458 if (T_PLANAR(Info -> OutputFormat)) {
2460 Out[0] = (cmsFloat64Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
2461 Out[Stride] = (cmsFloat64Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
2462 Out[Stride*2] = (cmsFloat64Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
2464 return output + sizeof(cmsFloat64Number);
2468 Out[0] = (cmsFloat64Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
2469 Out[1] = (cmsFloat64Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
2470 Out[2] = (cmsFloat64Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
2472 return output + (sizeof(cmsFloat64Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
2478 // ----------------------------------------------------------------------------------------------------------------
2481 static cmsFormatters16 InputFormatters16[] = {
2483 // Type Mask Function
2484 // ---------------------------- ------------------------------------ ----------------------------
2485 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, UnrollLabDoubleTo16},
2486 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, UnrollXYZDoubleTo16},
2487 { TYPE_GRAY_DBL, 0, UnrollDouble1Chan},
2488 { FLOAT_SH(1)|BYTES_SH(0), ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, UnrollDoubleTo16},
2489 { FLOAT_SH(1)|BYTES_SH(4), ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, UnrollFloatTo16},
2492 { CHANNELS_SH(1)|BYTES_SH(1), ANYSPACE, Unroll1Byte},
2493 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Unroll1ByteSkip1},
2494 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(2), ANYSPACE, Unroll1ByteSkip2},
2495 { CHANNELS_SH(1)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Unroll1ByteReversed},
2496 { COLORSPACE_SH(PT_MCH2)|CHANNELS_SH(2)|BYTES_SH(1), 0, Unroll2Bytes},
2498 { TYPE_LabV2_8, 0, UnrollLabV2_8 },
2499 { TYPE_ALabV2_8, 0, UnrollALabV2_8 },
2500 { TYPE_LabV2_16, 0, UnrollLabV2_16 },
2502 { CHANNELS_SH(3)|BYTES_SH(1), ANYSPACE, Unroll3Bytes},
2503 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3BytesSwap},
2504 { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3BytesSkip1Swap},
2505 { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll3BytesSkip1SwapFirst},
2507 { CHANNELS_SH(4)|BYTES_SH(1), ANYSPACE, Unroll4Bytes},
2508 { CHANNELS_SH(4)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Unroll4BytesReverse},
2509 { CHANNELS_SH(4)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4BytesSwapFirst},
2510 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll4BytesSwap},
2511 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4BytesSwapSwapFirst},
2513 { BYTES_SH(1)|PLANAR_SH(1), ANYFLAVOR|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollPlanarBytes},
2514 { BYTES_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollChunkyBytes},
2517 { CHANNELS_SH(1)|BYTES_SH(2), ANYSPACE, Unroll1Word},
2518 { CHANNELS_SH(1)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Unroll1WordReversed},
2519 { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(3), ANYSPACE, Unroll1WordSkip3},
2521 { CHANNELS_SH(2)|BYTES_SH(2), ANYSPACE, Unroll2Words},
2522 { CHANNELS_SH(3)|BYTES_SH(2), ANYSPACE, Unroll3Words},
2523 { CHANNELS_SH(4)|BYTES_SH(2), ANYSPACE, Unroll4Words},
2525 { CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Unroll3WordsSwap},
2526 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll3WordsSkip1SwapFirst},
2527 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3WordsSkip1Swap},
2528 { CHANNELS_SH(4)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Unroll4WordsReverse},
2529 { CHANNELS_SH(4)|BYTES_SH(2)|SWAPFIRST_SH(1), ANYSPACE, Unroll4WordsSwapFirst},
2530 { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Unroll4WordsSwap},
2531 { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4WordsSwapSwapFirst},
2534 { BYTES_SH(2)|PLANAR_SH(1), ANYFLAVOR|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollPlanarWords },
2535 { BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollAnyWords},
2540 static cmsFormattersFloat InputFormattersFloat[] = {
2542 // Type Mask Function
2543 // ---------------------------- ------------------------------------ ----------------------------
2544 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, UnrollLabDoubleToFloat},
2545 { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, UnrollLabFloatToFloat},
2546 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, UnrollXYZDoubleToFloat},
2547 { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, UnrollXYZFloatToFloat},
2549 { FLOAT_SH(1)|BYTES_SH(4), ANYPLANAR|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollFloatsToFloat},
2550 { FLOAT_SH(1)|BYTES_SH(0), ANYPLANAR|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollDoublesToFloat},
2554 // Bit fields set to one in the mask are not compared
2556 cmsFormatter _cmsGetStockInputFormatter(cmsUInt32Number dwInput, cmsUInt32Number dwFlags)
2562 if (!(dwFlags & CMS_PACK_FLAGS_FLOAT)) {
2564 for (i=0; i < sizeof(InputFormatters16) / sizeof(cmsFormatters16); i++) {
2565 cmsFormatters16* f = InputFormatters16 + i;
2567 if ((dwInput & ~f ->Mask) == f ->Type) {
2574 for (i=0; i < sizeof(InputFormattersFloat) / sizeof(cmsFormattersFloat); i++) {
2575 cmsFormattersFloat* f = InputFormattersFloat + i;
2577 if ((dwInput & ~f ->Mask) == f ->Type) {
2578 fr.FmtFloat = f ->Frm;
2588 static cmsFormatters16 OutputFormatters16[] = {
2589 // Type Mask Function
2590 // ---------------------------- ------------------------------------ ----------------------------
2592 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, PackLabDoubleFrom16},
2593 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, PackXYZDoubleFrom16},
2594 { FLOAT_SH(1)|BYTES_SH(0), ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackDoubleFrom16},
2595 { FLOAT_SH(1)|BYTES_SH(4), ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackFloatFrom16},
2597 { CHANNELS_SH(1)|BYTES_SH(1), ANYSPACE, Pack1Byte},
2598 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Pack1ByteSkip1},
2599 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack1ByteSkip1SwapFirst},
2601 { CHANNELS_SH(1)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Pack1ByteReversed},
2603 { TYPE_LabV2_8, 0, PackLabV2_8 },
2604 { TYPE_ALabV2_8, 0, PackALabV2_8 },
2605 { TYPE_LabV2_16, 0, PackLabV2_16 },
2607 { CHANNELS_SH(3)|BYTES_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesOptimized},
2608 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesAndSkip1Optimized},
2609 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1)|OPTIMIZED_SH(1),
2610 ANYSPACE, Pack3BytesAndSkip1SwapFirstOptimized},
2611 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1)|OPTIMIZED_SH(1),
2612 ANYSPACE, Pack3BytesAndSkip1SwapSwapFirstOptimized},
2613 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|EXTRA_SH(1)|OPTIMIZED_SH(1),
2614 ANYSPACE, Pack3BytesAndSkip1SwapOptimized},
2615 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesSwapOptimized},
2619 { CHANNELS_SH(3)|BYTES_SH(1), ANYSPACE, Pack3Bytes},
2620 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Pack3BytesAndSkip1},
2621 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack3BytesAndSkip1SwapFirst},
2622 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1),
2623 ANYSPACE, Pack3BytesAndSkip1SwapSwapFirst},
2624 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|EXTRA_SH(1), ANYSPACE, Pack3BytesAndSkip1Swap},
2625 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack3BytesSwap},
2626 { CHANNELS_SH(6)|BYTES_SH(1), ANYSPACE, Pack6Bytes},
2627 { CHANNELS_SH(6)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack6BytesSwap},
2628 { CHANNELS_SH(4)|BYTES_SH(1), ANYSPACE, Pack4Bytes},
2629 { CHANNELS_SH(4)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Pack4BytesReverse},
2630 { CHANNELS_SH(4)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack4BytesSwapFirst},
2631 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack4BytesSwap},
2632 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack4BytesSwapSwapFirst},
2634 { BYTES_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackAnyBytes},
2635 { BYTES_SH(1)|PLANAR_SH(1), ANYFLAVOR|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackPlanarBytes},
2637 { CHANNELS_SH(1)|BYTES_SH(2), ANYSPACE, Pack1Word},
2638 { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(1), ANYSPACE, Pack1WordSkip1},
2639 { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack1WordSkip1SwapFirst},
2640 { CHANNELS_SH(1)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Pack1WordReversed},
2641 { CHANNELS_SH(1)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack1WordBigEndian},
2642 { CHANNELS_SH(3)|BYTES_SH(2), ANYSPACE, Pack3Words},
2643 { CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack3WordsSwap},
2644 { CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack3WordsBigEndian},
2645 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1), ANYSPACE, Pack3WordsAndSkip1},
2646 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack3WordsAndSkip1Swap},
2647 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack3WordsAndSkip1SwapFirst},
2649 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1),
2650 ANYSPACE, Pack3WordsAndSkip1SwapSwapFirst},
2652 { CHANNELS_SH(4)|BYTES_SH(2), ANYSPACE, Pack4Words},
2653 { CHANNELS_SH(4)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Pack4WordsReverse},
2654 { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack4WordsSwap},
2655 { CHANNELS_SH(4)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack4WordsBigEndian},
2657 { CHANNELS_SH(6)|BYTES_SH(2), ANYSPACE, Pack6Words},
2658 { CHANNELS_SH(6)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack6WordsSwap},
2660 { BYTES_SH(2)|PLANAR_SH(1), ANYFLAVOR|ANYENDIAN|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackPlanarWords},
2661 { BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackAnyWords}
2666 static cmsFormattersFloat OutputFormattersFloat[] = {
2667 // Type Mask Function
2668 // ---------------------------- --------------------------------------------------- ----------------------------
2669 { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, PackLabFloatFromFloat},
2670 { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, PackXYZFloatFromFloat},
2671 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, PackLabDoubleFromFloat},
2672 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, PackXYZDoubleFromFloat},
2673 { FLOAT_SH(1)|BYTES_SH(4),
2674 ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackChunkyFloatsFromFloat },
2675 { FLOAT_SH(1)|BYTES_SH(4)|PLANAR_SH(1), ANYEXTRA|ANYCHANNELS|ANYSPACE, PackPlanarFloatsFromFloat},
2676 { FLOAT_SH(1)|BYTES_SH(0),
2677 ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackChunkyDoublesFromFloat },
2678 { FLOAT_SH(1)|BYTES_SH(0)|PLANAR_SH(1), ANYEXTRA|ANYCHANNELS|ANYSPACE, PackPlanarDoublesFromFloat},
2684 // Bit fields set to one in the mask are not compared
2685 cmsFormatter _cmsGetStockOutputFormatter(cmsUInt32Number dwInput, cmsUInt32Number dwFlags)
2691 if (dwFlags & CMS_PACK_FLAGS_FLOAT) {
2693 for (i=0; i < sizeof(OutputFormattersFloat) / sizeof(cmsFormattersFloat); i++) {
2694 cmsFormattersFloat* f = OutputFormattersFloat + i;
2696 if ((dwInput & ~f ->Mask) == f ->Type) {
2697 fr.FmtFloat = f ->Frm;
2705 for (i=0; i < sizeof(OutputFormatters16) / sizeof(cmsFormatters16); i++) {
2706 cmsFormatters16* f = OutputFormatters16 + i;
2708 if ((dwInput & ~f ->Mask) == f ->Type) {
2720 typedef struct _cms_formatters_factory_list {
2722 cmsFormatterFactory Factory;
2723 struct _cms_formatters_factory_list *Next;
2725 } cmsFormattersFactoryList;
2727 static cmsFormattersFactoryList* FactoryList = NULL;
2730 // Formatters management
2731 cmsBool _cmsRegisterFormattersPlugin(cmsPluginBase* Data)
2733 cmsPluginFormatters* Plugin = (cmsPluginFormatters*) Data;
2734 cmsFormattersFactoryList* fl ;
2743 fl = (cmsFormattersFactoryList*) _cmsPluginMalloc(sizeof(cmsFormattersFactoryList));
2744 if (fl == NULL) return FALSE;
2746 fl ->Factory = Plugin ->FormattersFactory;
2748 fl ->Next = FactoryList;
2754 cmsFormatter _cmsGetFormatter(cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8
2755 cmsFormatterDirection Dir,
2756 cmsUInt32Number dwFlags) // Float or 16 bits
2758 cmsFormattersFactoryList* f;
2760 for (f = FactoryList; f != NULL; f = f ->Next) {
2762 cmsFormatter fn = f ->Factory(Type, Dir, dwFlags);
2763 if (fn.Fmt16 != NULL) return fn;
2766 // Revert to default
2767 if (Dir == cmsFormatterInput)
2768 return _cmsGetStockInputFormatter(Type, dwFlags);
2770 return _cmsGetStockOutputFormatter(Type, dwFlags);
2774 // Return whatever given formatter refers to float values
2775 cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type)
2777 return T_FLOAT(Type) ? TRUE : FALSE;
2780 // Return whatever given formatter refers to 8 bits
2781 cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type)
2783 int Bytes = T_BYTES(Type);
2785 return (Bytes == 1);
2788 // Build a suitable formatter for the colorspace of this profile
2789 cmsUInt32Number CMSEXPORT cmsFormatterForColorspaceOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat)
2792 cmsColorSpaceSignature ColorSpace = cmsGetColorSpace(hProfile);
2793 cmsUInt32Number ColorSpaceBits = _cmsLCMScolorSpace(ColorSpace);
2794 cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace);
2795 cmsUInt32Number Float = lIsFloat ? 1 : 0;
2797 // Create a fake formatter for result
2798 return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans);
2801 // Build a suitable formatter for the colorspace of this profile
2802 cmsUInt32Number CMSEXPORT cmsFormatterForPCSOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat)
2805 cmsColorSpaceSignature ColorSpace = cmsGetPCS(hProfile);
2806 int ColorSpaceBits = _cmsLCMScolorSpace(ColorSpace);
2807 cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace);
2808 cmsUInt32Number Float = lIsFloat ? 1 : 0;
2810 // Create a fake formatter for result
2811 return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans);