Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / libs / lcms2 / src / cmspack.c
blobd54a8cf6f762c264444eb484db959756cee95f89
1 //---------------------------------------------------------------------------------
2 //
3 // Little Color Management System
4 // Copyright (c) 1998-2010 Marti Maria Saguer
5 //
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
32 // as special case)
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);
59 typedef struct {
60 cmsUInt32Number Type;
61 cmsUInt32Number Mask;
62 cmsFormatter16 Frm;
64 } cmsFormatters16;
66 typedef struct {
67 cmsUInt32Number Type;
68 cmsUInt32Number Mask;
69 cmsFormatterFloat Frm;
71 } cmsFormattersFloat;
74 #define ANYSPACE COLORSPACE_SH(31)
75 #define ANYCHANNELS CHANNELS_SH(15)
76 #define ANYEXTRA EXTRA_SH(7)
77 #define ANYPLANAR PLANAR_SH(1)
78 #define ANYENDIAN ENDIAN16_SH(1)
79 #define ANYSWAP DOSWAP_SH(1)
80 #define ANYSWAPFIRST SWAPFIRST_SH(1)
81 #define ANYFLAVOR FLAVOR_SH(1)
84 // Supress waning about info never being used
86 #ifdef _MSC_VER
87 #pragma warning(disable : 4100)
88 #endif
90 // Unpacking routines (16 bits) ----------------------------------------------------------------------------------------
93 // Does almost everything but is slow
94 static
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;
106 cmsUInt16Number v;
107 int i;
109 if (ExtraFirst) {
110 accum += Extra;
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;
118 wIn[index] = v;
119 accum++;
122 if (!ExtraFirst) {
123 accum += Extra;
126 if (Extra == 0 && SwapFirst) {
127 cmsUInt16Number tmp = wIn[0];
129 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
130 wIn[nChan-1] = tmp;
133 return accum;
135 cmsUNUSED_PARAMETER(info);
136 cmsUNUSED_PARAMETER(Stride);
140 // Extra channels are just ignored because come in the next planes
141 static
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);
151 int i;
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;
164 accum += Stride;
167 return (Init + 1);
170 // Special cases, provided for performance
171 static
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
182 return accum;
184 cmsUNUSED_PARAMETER(info);
185 cmsUNUSED_PARAMETER(Stride);
188 static
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
199 return accum;
201 cmsUNUSED_PARAMETER(info);
202 cmsUNUSED_PARAMETER(Stride);
205 static
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
216 return accum;
218 cmsUNUSED_PARAMETER(info);
219 cmsUNUSED_PARAMETER(Stride);
222 // KYMC
223 static
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
234 return accum;
236 cmsUNUSED_PARAMETER(info);
237 cmsUNUSED_PARAMETER(Stride);
240 static
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
251 return accum;
253 cmsUNUSED_PARAMETER(info);
254 cmsUNUSED_PARAMETER(Stride);
257 static
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
267 return accum;
269 cmsUNUSED_PARAMETER(info);
270 cmsUNUSED_PARAMETER(Stride);
273 static
274 cmsUInt8Number* Unroll3BytesSkip1Swap(register _cmsTRANSFORM* info,
275 register cmsUInt16Number wIn[],
276 register cmsUInt8Number* accum,
277 register cmsUInt32Number Stride)
279 accum++; // A
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
284 return accum;
286 cmsUNUSED_PARAMETER(info);
287 cmsUNUSED_PARAMETER(Stride);
290 static
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
299 accum++; // A
301 return accum;
303 cmsUNUSED_PARAMETER(info);
304 cmsUNUSED_PARAMETER(Stride);
307 static
308 cmsUInt8Number* Unroll3BytesSkip1SwapFirst(register _cmsTRANSFORM* info,
309 register cmsUInt16Number wIn[],
310 register cmsUInt8Number* accum,
311 register cmsUInt32Number Stride)
313 accum++; // A
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
318 return accum;
320 cmsUNUSED_PARAMETER(info);
321 cmsUNUSED_PARAMETER(Stride);
325 // BRG
326 static
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
336 return accum;
338 cmsUNUSED_PARAMETER(info);
339 cmsUNUSED_PARAMETER(Stride);
342 static
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
352 return accum;
354 cmsUNUSED_PARAMETER(info);
355 cmsUNUSED_PARAMETER(Stride);
358 static
359 cmsUInt8Number* UnrollALabV2_8(register _cmsTRANSFORM* info,
360 register cmsUInt16Number wIn[],
361 register cmsUInt8Number* accum,
362 register cmsUInt32Number Stride)
364 accum++; // A
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
369 return accum;
371 cmsUNUSED_PARAMETER(info);
372 cmsUNUSED_PARAMETER(Stride);
375 static
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
385 return accum;
387 cmsUNUSED_PARAMETER(info);
388 cmsUNUSED_PARAMETER(Stride);
391 // for duplex
392 static
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
401 return accum;
403 cmsUNUSED_PARAMETER(info);
404 cmsUNUSED_PARAMETER(Stride);
410 // Monochrome duplicates L into RGB for null-transforms
411 static
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
419 return accum;
421 cmsUNUSED_PARAMETER(info);
422 cmsUNUSED_PARAMETER(Stride);
426 static
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
433 accum += 1;
435 return accum;
437 cmsUNUSED_PARAMETER(info);
438 cmsUNUSED_PARAMETER(Stride);
441 static
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
448 accum += 2;
450 return accum;
452 cmsUNUSED_PARAMETER(info);
453 cmsUNUSED_PARAMETER(Stride);
456 static
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
464 return accum;
466 cmsUNUSED_PARAMETER(info);
467 cmsUNUSED_PARAMETER(Stride);
471 static
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;
484 int i;
486 if (ExtraFirst) {
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;
495 if (SwapEndian)
496 v = CHANGE_ENDIAN(v);
498 wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
500 accum += sizeof(cmsUInt16Number);
503 if (!ExtraFirst) {
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));
512 wIn[nChan-1] = tmp;
515 return accum;
517 cmsUNUSED_PARAMETER(Stride);
520 static
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);
530 int i;
531 cmsUInt8Number* Init = accum;
533 if (DoSwap) {
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;
542 if (SwapEndian)
543 v = CHANGE_ENDIAN(v);
545 wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
547 accum += Stride * sizeof(cmsUInt16Number);
550 return (Init + sizeof(cmsUInt16Number));
554 static
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
565 return accum;
567 cmsUNUSED_PARAMETER(info);
568 cmsUNUSED_PARAMETER(Stride);
571 static
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
582 return accum;
584 cmsUNUSED_PARAMETER(info);
585 cmsUNUSED_PARAMETER(Stride);
588 static
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
599 return accum;
601 cmsUNUSED_PARAMETER(info);
602 cmsUNUSED_PARAMETER(Stride);
605 // KYMC
606 static
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
617 return accum;
619 cmsUNUSED_PARAMETER(info);
620 cmsUNUSED_PARAMETER(Stride);
623 static
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
634 return accum;
636 cmsUNUSED_PARAMETER(info);
637 cmsUNUSED_PARAMETER(Stride);
640 static
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
650 return accum;
652 cmsUNUSED_PARAMETER(info);
653 cmsUNUSED_PARAMETER(Stride);
656 static
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
666 return accum;
668 cmsUNUSED_PARAMETER(info);
669 cmsUNUSED_PARAMETER(Stride);
672 static
673 cmsUInt8Number* Unroll3WordsSkip1Swap(register _cmsTRANSFORM* info,
674 register cmsUInt16Number wIn[],
675 register cmsUInt8Number* accum,
676 register cmsUInt32Number Stride)
678 accum += 2; // A
679 wIn[2] = *(cmsUInt16Number*) accum; accum += 2; // R
680 wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // G
681 wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // B
683 return accum;
685 cmsUNUSED_PARAMETER(info);
686 cmsUNUSED_PARAMETER(Stride);
689 static
690 cmsUInt8Number* Unroll3WordsSkip1SwapFirst(register _cmsTRANSFORM* info,
691 register cmsUInt16Number wIn[],
692 register cmsUInt8Number* accum,
693 register cmsUInt32Number Stride)
695 accum += 2; // A
696 wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // R
697 wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // G
698 wIn[2] = *(cmsUInt16Number*) accum; accum += 2; // B
700 return accum;
702 cmsUNUSED_PARAMETER(info);
703 cmsUNUSED_PARAMETER(Stride);
706 static
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
714 return accum;
716 cmsUNUSED_PARAMETER(info);
717 cmsUNUSED_PARAMETER(Stride);
720 static
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;
728 return accum;
730 cmsUNUSED_PARAMETER(info);
731 cmsUNUSED_PARAMETER(Stride);
734 static
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;
742 accum += 8;
744 return accum;
746 cmsUNUSED_PARAMETER(info);
747 cmsUNUSED_PARAMETER(Stride);
750 static
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
759 return accum;
761 cmsUNUSED_PARAMETER(info);
762 cmsUNUSED_PARAMETER(Stride);
766 // This is a conversion of Lab double to 16 bits
767 static
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;
777 cmsCIELab Lab;
779 Lab.L = Pt[0];
780 Lab.a = Pt[Stride];
781 Lab.b = Pt[Stride*2];
783 cmsFloat2LabEncoded(wIn, &Lab);
784 return accum + sizeof(cmsFloat64Number);
786 else {
788 cmsFloat2LabEncoded(wIn, (cmsCIELab*) accum);
789 accum += sizeof(cmsCIELab) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat64Number);
790 return accum;
795 // This is a conversion of Lab float to 16 bits
796 static
797 cmsUInt8Number* UnrollLabFloatTo16(register _cmsTRANSFORM* info,
798 register cmsUInt16Number wIn[],
799 register cmsUInt8Number* accum,
800 register cmsUInt32Number Stride)
802 cmsCIELab Lab;
804 if (T_PLANAR(info -> InputFormat)) {
806 cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
809 Lab.L = Pt[0];
810 Lab.a = Pt[Stride];
811 Lab.b = Pt[Stride*2];
813 cmsFloat2LabEncoded(wIn, &Lab);
814 return accum + sizeof(cmsFloat32Number);
816 else {
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);
824 return accum;
828 // This is a conversion of XYZ double to 16 bits
829 static
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;
838 cmsCIEXYZ XYZ;
840 XYZ.X = Pt[0];
841 XYZ.Y = Pt[Stride];
842 XYZ.Z = Pt[Stride*2];
843 cmsFloat2XYZEncoded(wIn, &XYZ);
845 return accum + sizeof(cmsFloat64Number);
849 else {
850 cmsFloat2XYZEncoded(wIn, (cmsCIEXYZ*) accum);
851 accum += sizeof(cmsCIEXYZ) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat64Number);
853 return accum;
857 // Check if space is marked as ink
858 cmsINLINE cmsBool IsInkSpace(cmsUInt32Number Type)
860 switch (T_COLORSPACE(Type)) {
862 case PT_CMY:
863 case PT_CMYK:
864 case PT_MCH5:
865 case PT_MCH6:
866 case PT_MCH7:
867 case PT_MCH8:
868 case PT_MCH9:
869 case PT_MCH10:
870 case PT_MCH11:
871 case PT_MCH12:
872 case PT_MCH13:
873 case PT_MCH14:
874 case PT_MCH15: return TRUE;
876 default: return FALSE;
880 // Inks does come in percentage, remaining cases are between 0..1.0, again to 16 bits
881 static
882 cmsUInt8Number* UnrollDoubleTo16(register _cmsTRANSFORM* info,
883 register cmsUInt16Number wIn[],
884 register cmsUInt8Number* accum,
885 register cmsUInt32Number Stride)
888 int nChan = T_CHANNELS(info -> InputFormat);
889 int DoSwap = T_DOSWAP(info ->InputFormat);
890 int Reverse = T_FLAVOR(info ->InputFormat);
891 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
892 int Extra = T_EXTRA(info -> InputFormat);
893 int ExtraFirst = DoSwap ^ SwapFirst;
894 int Planar = T_PLANAR(info -> InputFormat);
895 cmsFloat64Number v;
896 cmsUInt16Number vi;
897 int i, start = 0;
898 cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
901 if (ExtraFirst)
902 start = Extra;
904 for (i=0; i < nChan; i++) {
906 int index = DoSwap ? (nChan - i - 1) : i;
908 if (Planar)
909 v = (cmsFloat32Number) ((cmsFloat64Number*) accum)[(i + start) * Stride];
910 else
911 v = (cmsFloat32Number) ((cmsFloat64Number*) accum)[i + start];
913 vi = _cmsQuickSaturateWord(v * maximum);
915 if (Reverse)
916 vi = REVERSE_FLAVOR_16(vi);
918 wIn[index] = vi;
922 if (Extra == 0 && SwapFirst) {
923 cmsUInt16Number tmp = wIn[0];
925 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
926 wIn[nChan-1] = tmp;
929 if (T_PLANAR(info -> InputFormat))
930 return accum + sizeof(cmsFloat64Number);
931 else
932 return accum + (nChan + Extra) * sizeof(cmsFloat64Number);
937 static
938 cmsUInt8Number* UnrollFloatTo16(register _cmsTRANSFORM* info,
939 register cmsUInt16Number wIn[],
940 register cmsUInt8Number* accum,
941 register cmsUInt32Number Stride)
944 int nChan = T_CHANNELS(info -> InputFormat);
945 int DoSwap = T_DOSWAP(info ->InputFormat);
946 int Reverse = T_FLAVOR(info ->InputFormat);
947 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
948 int Extra = T_EXTRA(info -> InputFormat);
949 int ExtraFirst = DoSwap ^ SwapFirst;
950 int Planar = T_PLANAR(info -> InputFormat);
951 cmsFloat32Number v;
952 cmsUInt16Number vi;
953 int i, start = 0;
954 cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
957 if (ExtraFirst)
958 start = Extra;
960 for (i=0; i < nChan; i++) {
962 int index = DoSwap ? (nChan - i - 1) : i;
964 if (Planar)
965 v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[(i + start) * Stride];
966 else
967 v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[i + start];
969 vi = _cmsQuickSaturateWord(v * maximum);
971 if (Reverse)
972 vi = REVERSE_FLAVOR_16(vi);
974 wIn[index] = vi;
978 if (Extra == 0 && SwapFirst) {
979 cmsUInt16Number tmp = wIn[0];
981 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
982 wIn[nChan-1] = tmp;
985 if (T_PLANAR(info -> InputFormat))
986 return accum + sizeof(cmsFloat32Number);
987 else
988 return accum + (nChan + Extra) * sizeof(cmsFloat32Number);
994 // For 1 channel, we need to duplicate data (it comes in 0..1.0 range)
995 static
996 cmsUInt8Number* UnrollDouble1Chan(register _cmsTRANSFORM* info,
997 register cmsUInt16Number wIn[],
998 register cmsUInt8Number* accum,
999 register cmsUInt32Number Stride)
1001 cmsFloat64Number* Inks = (cmsFloat64Number*) accum;
1003 wIn[0] = wIn[1] = wIn[2] = _cmsQuickSaturateWord(Inks[0] * 65535.0);
1005 return accum + sizeof(cmsFloat64Number);
1007 cmsUNUSED_PARAMETER(info);
1008 cmsUNUSED_PARAMETER(Stride);
1011 //-------------------------------------------------------------------------------------------------------------------
1013 // For anything going from cmsFloat32Number
1014 static
1015 cmsUInt8Number* UnrollFloatsToFloat(_cmsTRANSFORM* info,
1016 cmsFloat32Number wIn[],
1017 cmsUInt8Number* accum,
1018 cmsUInt32Number Stride)
1021 int nChan = T_CHANNELS(info -> InputFormat);
1022 int DoSwap = T_DOSWAP(info ->InputFormat);
1023 int Reverse = T_FLAVOR(info ->InputFormat);
1024 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
1025 int Extra = T_EXTRA(info -> InputFormat);
1026 int ExtraFirst = DoSwap ^ SwapFirst;
1027 int Planar = T_PLANAR(info -> InputFormat);
1028 cmsFloat32Number v;
1029 int i, start = 0;
1030 cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 100.0F : 1.0F;
1033 if (ExtraFirst)
1034 start = Extra;
1036 for (i=0; i < nChan; i++) {
1038 int index = DoSwap ? (nChan - i - 1) : i;
1040 if (Planar)
1041 v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[(i + start) * Stride];
1042 else
1043 v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[i + start];
1045 v /= maximum;
1047 wIn[index] = Reverse ? 1 - v : v;
1051 if (Extra == 0 && SwapFirst) {
1052 cmsFloat32Number tmp = wIn[0];
1054 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number));
1055 wIn[nChan-1] = tmp;
1058 if (T_PLANAR(info -> InputFormat))
1059 return accum + sizeof(cmsFloat32Number);
1060 else
1061 return accum + (nChan + Extra) * sizeof(cmsFloat32Number);
1064 // For anything going from double
1066 static
1067 cmsUInt8Number* UnrollDoublesToFloat(_cmsTRANSFORM* info,
1068 cmsFloat32Number wIn[],
1069 cmsUInt8Number* accum,
1070 cmsUInt32Number Stride)
1073 int nChan = T_CHANNELS(info -> InputFormat);
1074 int DoSwap = T_DOSWAP(info ->InputFormat);
1075 int Reverse = T_FLAVOR(info ->InputFormat);
1076 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
1077 int Extra = T_EXTRA(info -> InputFormat);
1078 int ExtraFirst = DoSwap ^ SwapFirst;
1079 int Planar = T_PLANAR(info -> InputFormat);
1080 cmsFloat64Number v;
1081 int i, start = 0;
1082 cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 100.0 : 1.0;
1085 if (ExtraFirst)
1086 start = Extra;
1088 for (i=0; i < nChan; i++) {
1090 int index = DoSwap ? (nChan - i - 1) : i;
1092 if (Planar)
1093 v = (cmsFloat64Number) ((cmsFloat64Number*) accum)[(i + start) * Stride];
1094 else
1095 v = (cmsFloat64Number) ((cmsFloat64Number*) accum)[i + start];
1097 v /= maximum;
1099 wIn[index] = (cmsFloat32Number) (Reverse ? 1.0 - v : v);
1103 if (Extra == 0 && SwapFirst) {
1104 cmsFloat32Number tmp = wIn[0];
1106 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number));
1107 wIn[nChan-1] = tmp;
1110 if (T_PLANAR(info -> InputFormat))
1111 return accum + sizeof(cmsFloat64Number);
1112 else
1113 return accum + (nChan + Extra) * sizeof(cmsFloat64Number);
1118 // From Lab double to cmsFloat32Number
1119 static
1120 cmsUInt8Number* UnrollLabDoubleToFloat(_cmsTRANSFORM* info,
1121 cmsFloat32Number wIn[],
1122 cmsUInt8Number* accum,
1123 cmsUInt32Number Stride)
1125 cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
1127 if (T_PLANAR(info -> InputFormat)) {
1129 wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
1130 wIn[1] = (cmsFloat32Number) ((Pt[Stride] + 128) / 255.0); // form -128..+127 to 0..1
1131 wIn[2] = (cmsFloat32Number) ((Pt[Stride*2] + 128) / 255.0);
1133 return accum + sizeof(cmsFloat64Number);
1135 else {
1137 wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
1138 wIn[1] = (cmsFloat32Number) ((Pt[1] + 128) / 255.0); // form -128..+127 to 0..1
1139 wIn[2] = (cmsFloat32Number) ((Pt[2] + 128) / 255.0);
1141 accum += sizeof(cmsFloat64Number)*(3 + T_EXTRA(info ->InputFormat));
1142 return accum;
1146 // From Lab double to cmsFloat32Number
1147 static
1148 cmsUInt8Number* UnrollLabFloatToFloat(_cmsTRANSFORM* info,
1149 cmsFloat32Number wIn[],
1150 cmsUInt8Number* accum,
1151 cmsUInt32Number Stride)
1153 cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
1155 if (T_PLANAR(info -> InputFormat)) {
1157 wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
1158 wIn[1] = (cmsFloat32Number) ((Pt[Stride] + 128) / 255.0); // form -128..+127 to 0..1
1159 wIn[2] = (cmsFloat32Number) ((Pt[Stride*2] + 128) / 255.0);
1161 return accum + sizeof(cmsFloat32Number);
1163 else {
1165 wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
1166 wIn[1] = (cmsFloat32Number) ((Pt[1] + 128) / 255.0); // form -128..+127 to 0..1
1167 wIn[2] = (cmsFloat32Number) ((Pt[2] + 128) / 255.0);
1169 accum += sizeof(cmsFloat32Number)*(3 + T_EXTRA(info ->InputFormat));
1170 return accum;
1176 // 1.15 fixed point, that means maximum value is MAX_ENCODEABLE_XYZ (0xFFFF)
1177 static
1178 cmsUInt8Number* UnrollXYZDoubleToFloat(_cmsTRANSFORM* info,
1179 cmsFloat32Number wIn[],
1180 cmsUInt8Number* accum,
1181 cmsUInt32Number Stride)
1183 cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
1185 if (T_PLANAR(info -> InputFormat)) {
1187 wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
1188 wIn[1] = (cmsFloat32Number) (Pt[Stride] / MAX_ENCODEABLE_XYZ);
1189 wIn[2] = (cmsFloat32Number) (Pt[Stride*2] / MAX_ENCODEABLE_XYZ);
1191 return accum + sizeof(cmsFloat64Number);
1193 else {
1195 wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
1196 wIn[1] = (cmsFloat32Number) (Pt[1] / MAX_ENCODEABLE_XYZ);
1197 wIn[2] = (cmsFloat32Number) (Pt[2] / MAX_ENCODEABLE_XYZ);
1199 accum += sizeof(cmsFloat64Number)*(3 + T_EXTRA(info ->InputFormat));
1200 return accum;
1204 static
1205 cmsUInt8Number* UnrollXYZFloatToFloat(_cmsTRANSFORM* info,
1206 cmsFloat32Number wIn[],
1207 cmsUInt8Number* accum,
1208 cmsUInt32Number Stride)
1210 cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
1212 if (T_PLANAR(info -> InputFormat)) {
1214 wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
1215 wIn[1] = (cmsFloat32Number) (Pt[Stride] / MAX_ENCODEABLE_XYZ);
1216 wIn[2] = (cmsFloat32Number) (Pt[Stride*2] / MAX_ENCODEABLE_XYZ);
1218 return accum + sizeof(cmsFloat32Number);
1220 else {
1222 wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
1223 wIn[1] = (cmsFloat32Number) (Pt[1] / MAX_ENCODEABLE_XYZ);
1224 wIn[2] = (cmsFloat32Number) (Pt[2] / MAX_ENCODEABLE_XYZ);
1226 accum += sizeof(cmsFloat32Number)*(3 + T_EXTRA(info ->InputFormat));
1227 return accum;
1233 // Packing routines -----------------------------------------------------------------------------------------------------------
1236 // Generic chunky for byte
1238 static
1239 cmsUInt8Number* PackAnyBytes(register _cmsTRANSFORM* info,
1240 register cmsUInt16Number wOut[],
1241 register cmsUInt8Number* output,
1242 register cmsUInt32Number Stride)
1244 int nChan = T_CHANNELS(info -> OutputFormat);
1245 int DoSwap = T_DOSWAP(info ->OutputFormat);
1246 int Reverse = T_FLAVOR(info ->OutputFormat);
1247 int Extra = T_EXTRA(info -> OutputFormat);
1248 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
1249 int ExtraFirst = DoSwap ^ SwapFirst;
1250 cmsUInt8Number* swap1;
1251 cmsUInt8Number v = 0;
1252 int i;
1254 swap1 = output;
1256 if (ExtraFirst) {
1257 output += Extra;
1260 for (i=0; i < nChan; i++) {
1262 int index = DoSwap ? (nChan - i - 1) : i;
1264 v = FROM_16_TO_8(wOut[index]);
1266 if (Reverse)
1267 v = REVERSE_FLAVOR_8(v);
1269 *output++ = v;
1272 if (!ExtraFirst) {
1273 output += Extra;
1276 if (Extra == 0 && SwapFirst) {
1278 memmove(swap1 + 1, swap1, nChan-1);
1279 *swap1 = v;
1283 return output;
1285 cmsUNUSED_PARAMETER(Stride);
1290 static
1291 cmsUInt8Number* PackAnyWords(register _cmsTRANSFORM* info,
1292 register cmsUInt16Number wOut[],
1293 register cmsUInt8Number* output,
1294 register cmsUInt32Number Stride)
1296 int nChan = T_CHANNELS(info -> OutputFormat);
1297 int SwapEndian = T_ENDIAN16(info -> InputFormat);
1298 int DoSwap = T_DOSWAP(info ->OutputFormat);
1299 int Reverse = T_FLAVOR(info ->OutputFormat);
1300 int Extra = T_EXTRA(info -> OutputFormat);
1301 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
1302 int ExtraFirst = DoSwap ^ SwapFirst;
1303 cmsUInt16Number* swap1;
1304 cmsUInt16Number v = 0;
1305 int i;
1307 swap1 = (cmsUInt16Number*) output;
1309 if (ExtraFirst) {
1310 output += Extra * sizeof(cmsUInt16Number);
1313 for (i=0; i < nChan; i++) {
1315 int index = DoSwap ? (nChan - i - 1) : i;
1317 v = wOut[index];
1319 if (SwapEndian)
1320 v = CHANGE_ENDIAN(v);
1322 if (Reverse)
1323 v = REVERSE_FLAVOR_16(v);
1325 *(cmsUInt16Number*) output = v;
1327 output += sizeof(cmsUInt16Number);
1330 if (!ExtraFirst) {
1331 output += Extra * sizeof(cmsUInt16Number);
1334 if (Extra == 0 && SwapFirst) {
1336 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number));
1337 *swap1 = v;
1341 return output;
1343 cmsUNUSED_PARAMETER(Stride);
1347 static
1348 cmsUInt8Number* PackPlanarBytes(register _cmsTRANSFORM* info,
1349 register cmsUInt16Number wOut[],
1350 register cmsUInt8Number* output,
1351 register cmsUInt32Number Stride)
1353 int nChan = T_CHANNELS(info -> OutputFormat);
1354 int DoSwap = T_DOSWAP(info ->OutputFormat);
1355 int SwapFirst = T_SWAPFIRST(info ->OutputFormat);
1356 int Reverse = T_FLAVOR(info ->OutputFormat);
1357 int i;
1358 cmsUInt8Number* Init = output;
1361 if (DoSwap ^ SwapFirst) {
1362 output += T_EXTRA(info -> OutputFormat) * Stride;
1366 for (i=0; i < nChan; i++) {
1368 int index = DoSwap ? (nChan - i - 1) : i;
1369 cmsUInt8Number v = FROM_16_TO_8(wOut[index]);
1371 *(cmsUInt8Number*) output = (cmsUInt8Number) (Reverse ? REVERSE_FLAVOR_8(v) : v);
1372 output += Stride;
1375 return (Init + 1);
1377 cmsUNUSED_PARAMETER(Stride);
1381 static
1382 cmsUInt8Number* PackPlanarWords(register _cmsTRANSFORM* info,
1383 register cmsUInt16Number wOut[],
1384 register cmsUInt8Number* output,
1385 register cmsUInt32Number Stride)
1387 int nChan = T_CHANNELS(info -> OutputFormat);
1388 int DoSwap = T_DOSWAP(info ->OutputFormat);
1389 int Reverse= T_FLAVOR(info ->OutputFormat);
1390 int SwapEndian = T_ENDIAN16(info -> OutputFormat);
1391 int i;
1392 cmsUInt8Number* Init = output;
1393 cmsUInt16Number v;
1395 if (DoSwap) {
1396 output += T_EXTRA(info -> OutputFormat) * Stride * sizeof(cmsUInt16Number);
1399 for (i=0; i < nChan; i++) {
1401 int index = DoSwap ? (nChan - i - 1) : i;
1403 v = wOut[index];
1405 if (SwapEndian)
1406 v = CHANGE_ENDIAN(v);
1408 if (Reverse)
1409 v = REVERSE_FLAVOR_16(v);
1411 *(cmsUInt16Number*) output = v;
1412 output += (Stride * sizeof(cmsUInt16Number));
1415 return (Init + sizeof(cmsUInt16Number));
1418 // CMYKcm (unrolled for speed)
1420 static
1421 cmsUInt8Number* Pack6Bytes(register _cmsTRANSFORM* info,
1422 register cmsUInt16Number wOut[],
1423 register cmsUInt8Number* output,
1424 register cmsUInt32Number Stride)
1426 *output++ = FROM_16_TO_8(wOut[0]);
1427 *output++ = FROM_16_TO_8(wOut[1]);
1428 *output++ = FROM_16_TO_8(wOut[2]);
1429 *output++ = FROM_16_TO_8(wOut[3]);
1430 *output++ = FROM_16_TO_8(wOut[4]);
1431 *output++ = FROM_16_TO_8(wOut[5]);
1433 return output;
1435 cmsUNUSED_PARAMETER(info);
1436 cmsUNUSED_PARAMETER(Stride);
1439 // KCMYcm
1441 static
1442 cmsUInt8Number* Pack6BytesSwap(register _cmsTRANSFORM* info,
1443 register cmsUInt16Number wOut[],
1444 register cmsUInt8Number* output,
1445 register cmsUInt32Number Stride)
1447 *output++ = FROM_16_TO_8(wOut[5]);
1448 *output++ = FROM_16_TO_8(wOut[4]);
1449 *output++ = FROM_16_TO_8(wOut[3]);
1450 *output++ = FROM_16_TO_8(wOut[2]);
1451 *output++ = FROM_16_TO_8(wOut[1]);
1452 *output++ = FROM_16_TO_8(wOut[0]);
1454 return output;
1456 cmsUNUSED_PARAMETER(info);
1457 cmsUNUSED_PARAMETER(Stride);
1460 // CMYKcm
1461 static
1462 cmsUInt8Number* Pack6Words(register _cmsTRANSFORM* info,
1463 register cmsUInt16Number wOut[],
1464 register cmsUInt8Number* output,
1465 register cmsUInt32Number Stride)
1467 *(cmsUInt16Number*) output = wOut[0];
1468 output+= 2;
1469 *(cmsUInt16Number*) output = wOut[1];
1470 output+= 2;
1471 *(cmsUInt16Number*) output = wOut[2];
1472 output+= 2;
1473 *(cmsUInt16Number*) output = wOut[3];
1474 output+= 2;
1475 *(cmsUInt16Number*) output = wOut[4];
1476 output+= 2;
1477 *(cmsUInt16Number*) output = wOut[5];
1478 output+= 2;
1480 return output;
1482 cmsUNUSED_PARAMETER(info);
1483 cmsUNUSED_PARAMETER(Stride);
1486 // KCMYcm
1487 static
1488 cmsUInt8Number* Pack6WordsSwap(register _cmsTRANSFORM* info,
1489 register cmsUInt16Number wOut[],
1490 register cmsUInt8Number* output,
1491 register cmsUInt32Number Stride)
1493 *(cmsUInt16Number*) output = wOut[5];
1494 output+= 2;
1495 *(cmsUInt16Number*) output = wOut[4];
1496 output+= 2;
1497 *(cmsUInt16Number*) output = wOut[3];
1498 output+= 2;
1499 *(cmsUInt16Number*) output = wOut[2];
1500 output+= 2;
1501 *(cmsUInt16Number*) output = wOut[1];
1502 output+= 2;
1503 *(cmsUInt16Number*) output = wOut[0];
1504 output+= 2;
1506 return output;
1508 cmsUNUSED_PARAMETER(info);
1509 cmsUNUSED_PARAMETER(Stride);
1513 static
1514 cmsUInt8Number* Pack4Bytes(register _cmsTRANSFORM* info,
1515 register cmsUInt16Number wOut[],
1516 register cmsUInt8Number* output,
1517 register cmsUInt32Number Stride)
1519 *output++ = FROM_16_TO_8(wOut[0]);
1520 *output++ = FROM_16_TO_8(wOut[1]);
1521 *output++ = FROM_16_TO_8(wOut[2]);
1522 *output++ = FROM_16_TO_8(wOut[3]);
1524 return output;
1526 cmsUNUSED_PARAMETER(info);
1527 cmsUNUSED_PARAMETER(Stride);
1530 static
1531 cmsUInt8Number* Pack4BytesReverse(register _cmsTRANSFORM* info,
1532 register cmsUInt16Number wOut[],
1533 register cmsUInt8Number* output,
1534 register cmsUInt32Number Stride)
1536 *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[0]));
1537 *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[1]));
1538 *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[2]));
1539 *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[3]));
1541 return output;
1543 cmsUNUSED_PARAMETER(info);
1544 cmsUNUSED_PARAMETER(Stride);
1548 static
1549 cmsUInt8Number* Pack4BytesSwapFirst(register _cmsTRANSFORM* info,
1550 register cmsUInt16Number wOut[],
1551 register cmsUInt8Number* output,
1552 register cmsUInt32Number Stride)
1554 *output++ = FROM_16_TO_8(wOut[3]);
1555 *output++ = FROM_16_TO_8(wOut[0]);
1556 *output++ = FROM_16_TO_8(wOut[1]);
1557 *output++ = FROM_16_TO_8(wOut[2]);
1559 return output;
1561 cmsUNUSED_PARAMETER(info);
1562 cmsUNUSED_PARAMETER(Stride);
1565 // ABGR
1566 static
1567 cmsUInt8Number* Pack4BytesSwap(register _cmsTRANSFORM* info,
1568 register cmsUInt16Number wOut[],
1569 register cmsUInt8Number* output,
1570 register cmsUInt32Number Stride)
1572 *output++ = FROM_16_TO_8(wOut[3]);
1573 *output++ = FROM_16_TO_8(wOut[2]);
1574 *output++ = FROM_16_TO_8(wOut[1]);
1575 *output++ = FROM_16_TO_8(wOut[0]);
1577 return output;
1579 cmsUNUSED_PARAMETER(info);
1580 cmsUNUSED_PARAMETER(Stride);
1583 static
1584 cmsUInt8Number* Pack4BytesSwapSwapFirst(register _cmsTRANSFORM* info,
1585 register cmsUInt16Number wOut[],
1586 register cmsUInt8Number* output,
1587 register cmsUInt32Number Stride)
1589 *output++ = FROM_16_TO_8(wOut[2]);
1590 *output++ = FROM_16_TO_8(wOut[1]);
1591 *output++ = FROM_16_TO_8(wOut[0]);
1592 *output++ = FROM_16_TO_8(wOut[3]);
1594 return output;
1596 cmsUNUSED_PARAMETER(info);
1597 cmsUNUSED_PARAMETER(Stride);
1600 static
1601 cmsUInt8Number* Pack4Words(register _cmsTRANSFORM* info,
1602 register cmsUInt16Number wOut[],
1603 register cmsUInt8Number* output,
1604 register cmsUInt32Number Stride)
1606 *(cmsUInt16Number*) output = wOut[0];
1607 output+= 2;
1608 *(cmsUInt16Number*) output = wOut[1];
1609 output+= 2;
1610 *(cmsUInt16Number*) output = wOut[2];
1611 output+= 2;
1612 *(cmsUInt16Number*) output = wOut[3];
1613 output+= 2;
1615 return output;
1617 cmsUNUSED_PARAMETER(info);
1618 cmsUNUSED_PARAMETER(Stride);
1621 static
1622 cmsUInt8Number* Pack4WordsReverse(register _cmsTRANSFORM* info,
1623 register cmsUInt16Number wOut[],
1624 register cmsUInt8Number* output,
1625 register cmsUInt32Number Stride)
1627 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[0]);
1628 output+= 2;
1629 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[1]);
1630 output+= 2;
1631 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[2]);
1632 output+= 2;
1633 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[3]);
1634 output+= 2;
1636 return output;
1638 cmsUNUSED_PARAMETER(info);
1639 cmsUNUSED_PARAMETER(Stride);
1642 // ABGR
1643 static
1644 cmsUInt8Number* Pack4WordsSwap(register _cmsTRANSFORM* info,
1645 register cmsUInt16Number wOut[],
1646 register cmsUInt8Number* output,
1647 register cmsUInt32Number Stride)
1649 *(cmsUInt16Number*) output = wOut[3];
1650 output+= 2;
1651 *(cmsUInt16Number*) output = wOut[2];
1652 output+= 2;
1653 *(cmsUInt16Number*) output = wOut[1];
1654 output+= 2;
1655 *(cmsUInt16Number*) output = wOut[0];
1656 output+= 2;
1658 return output;
1660 cmsUNUSED_PARAMETER(info);
1661 cmsUNUSED_PARAMETER(Stride);
1664 // CMYK
1665 static
1666 cmsUInt8Number* Pack4WordsBigEndian(register _cmsTRANSFORM* info,
1667 register cmsUInt16Number wOut[],
1668 register cmsUInt8Number* output,
1669 register cmsUInt32Number Stride)
1671 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
1672 output+= 2;
1673 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[1]);
1674 output+= 2;
1675 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[2]);
1676 output+= 2;
1677 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[3]);
1678 output+= 2;
1680 return output;
1682 cmsUNUSED_PARAMETER(info);
1683 cmsUNUSED_PARAMETER(Stride);
1687 static
1688 cmsUInt8Number* PackLabV2_8(register _cmsTRANSFORM* info,
1689 register cmsUInt16Number wOut[],
1690 register cmsUInt8Number* output,
1691 register cmsUInt32Number Stride)
1693 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[0]));
1694 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[1]));
1695 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[2]));
1697 return output;
1699 cmsUNUSED_PARAMETER(info);
1700 cmsUNUSED_PARAMETER(Stride);
1703 static
1704 cmsUInt8Number* PackALabV2_8(register _cmsTRANSFORM* info,
1705 register cmsUInt16Number wOut[],
1706 register cmsUInt8Number* output,
1707 register cmsUInt32Number Stride)
1709 output++;
1710 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[0]));
1711 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[1]));
1712 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[2]));
1714 return output;
1716 cmsUNUSED_PARAMETER(info);
1717 cmsUNUSED_PARAMETER(Stride);
1720 static
1721 cmsUInt8Number* PackLabV2_16(register _cmsTRANSFORM* info,
1722 register cmsUInt16Number wOut[],
1723 register cmsUInt8Number* output,
1724 register cmsUInt32Number Stride)
1726 *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[0]);
1727 output += 2;
1728 *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[1]);
1729 output += 2;
1730 *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[2]);
1731 output += 2;
1733 return output;
1735 cmsUNUSED_PARAMETER(info);
1736 cmsUNUSED_PARAMETER(Stride);
1739 static
1740 cmsUInt8Number* Pack3Bytes(register _cmsTRANSFORM* info,
1741 register cmsUInt16Number wOut[],
1742 register cmsUInt8Number* output,
1743 register cmsUInt32Number Stride)
1745 *output++ = FROM_16_TO_8(wOut[0]);
1746 *output++ = FROM_16_TO_8(wOut[1]);
1747 *output++ = FROM_16_TO_8(wOut[2]);
1749 return output;
1751 cmsUNUSED_PARAMETER(info);
1752 cmsUNUSED_PARAMETER(Stride);
1755 static
1756 cmsUInt8Number* Pack3BytesOptimized(register _cmsTRANSFORM* info,
1757 register cmsUInt16Number wOut[],
1758 register cmsUInt8Number* output,
1759 register cmsUInt32Number Stride)
1761 *output++ = (wOut[0] & 0xFF);
1762 *output++ = (wOut[1] & 0xFF);
1763 *output++ = (wOut[2] & 0xFF);
1765 return output;
1767 cmsUNUSED_PARAMETER(info);
1768 cmsUNUSED_PARAMETER(Stride);
1771 static
1772 cmsUInt8Number* Pack3BytesSwap(register _cmsTRANSFORM* info,
1773 register cmsUInt16Number wOut[],
1774 register cmsUInt8Number* output,
1775 register cmsUInt32Number Stride)
1777 *output++ = FROM_16_TO_8(wOut[2]);
1778 *output++ = FROM_16_TO_8(wOut[1]);
1779 *output++ = FROM_16_TO_8(wOut[0]);
1781 return output;
1783 cmsUNUSED_PARAMETER(info);
1784 cmsUNUSED_PARAMETER(Stride);
1787 static
1788 cmsUInt8Number* Pack3BytesSwapOptimized(register _cmsTRANSFORM* info,
1789 register cmsUInt16Number wOut[],
1790 register cmsUInt8Number* output,
1791 register cmsUInt32Number Stride)
1793 *output++ = (wOut[2] & 0xFF);
1794 *output++ = (wOut[1] & 0xFF);
1795 *output++ = (wOut[0] & 0xFF);
1797 return output;
1799 cmsUNUSED_PARAMETER(info);
1800 cmsUNUSED_PARAMETER(Stride);
1804 static
1805 cmsUInt8Number* Pack3Words(register _cmsTRANSFORM* info,
1806 register cmsUInt16Number wOut[],
1807 register cmsUInt8Number* output,
1808 register cmsUInt32Number Stride)
1810 *(cmsUInt16Number*) output = wOut[0];
1811 output+= 2;
1812 *(cmsUInt16Number*) output = wOut[1];
1813 output+= 2;
1814 *(cmsUInt16Number*) output = wOut[2];
1815 output+= 2;
1817 return output;
1819 cmsUNUSED_PARAMETER(info);
1820 cmsUNUSED_PARAMETER(Stride);
1823 static
1824 cmsUInt8Number* Pack3WordsSwap(register _cmsTRANSFORM* info,
1825 register cmsUInt16Number wOut[],
1826 register cmsUInt8Number* output,
1827 register cmsUInt32Number Stride)
1829 *(cmsUInt16Number*) output = wOut[2];
1830 output+= 2;
1831 *(cmsUInt16Number*) output = wOut[1];
1832 output+= 2;
1833 *(cmsUInt16Number*) output = wOut[0];
1834 output+= 2;
1836 return output;
1838 cmsUNUSED_PARAMETER(info);
1839 cmsUNUSED_PARAMETER(Stride);
1842 static
1843 cmsUInt8Number* Pack3WordsBigEndian(register _cmsTRANSFORM* info,
1844 register cmsUInt16Number wOut[],
1845 register cmsUInt8Number* output,
1846 register cmsUInt32Number Stride)
1848 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
1849 output+= 2;
1850 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[1]);
1851 output+= 2;
1852 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[2]);
1853 output+= 2;
1855 return output;
1857 cmsUNUSED_PARAMETER(info);
1858 cmsUNUSED_PARAMETER(Stride);
1861 static
1862 cmsUInt8Number* Pack3BytesAndSkip1(register _cmsTRANSFORM* info,
1863 register cmsUInt16Number wOut[],
1864 register cmsUInt8Number* output,
1865 register cmsUInt32Number Stride)
1867 *output++ = FROM_16_TO_8(wOut[0]);
1868 *output++ = FROM_16_TO_8(wOut[1]);
1869 *output++ = FROM_16_TO_8(wOut[2]);
1870 output++;
1872 return output;
1874 cmsUNUSED_PARAMETER(info);
1875 cmsUNUSED_PARAMETER(Stride);
1878 static
1879 cmsUInt8Number* Pack3BytesAndSkip1Optimized(register _cmsTRANSFORM* info,
1880 register cmsUInt16Number wOut[],
1881 register cmsUInt8Number* output,
1882 register cmsUInt32Number Stride)
1884 *output++ = (wOut[0] & 0xFF);
1885 *output++ = (wOut[1] & 0xFF);
1886 *output++ = (wOut[2] & 0xFF);
1887 output++;
1889 return output;
1891 cmsUNUSED_PARAMETER(info);
1892 cmsUNUSED_PARAMETER(Stride);
1896 static
1897 cmsUInt8Number* Pack3BytesAndSkip1SwapFirst(register _cmsTRANSFORM* info,
1898 register cmsUInt16Number wOut[],
1899 register cmsUInt8Number* output,
1900 register cmsUInt32Number Stride)
1902 output++;
1903 *output++ = FROM_16_TO_8(wOut[0]);
1904 *output++ = FROM_16_TO_8(wOut[1]);
1905 *output++ = FROM_16_TO_8(wOut[2]);
1907 return output;
1909 cmsUNUSED_PARAMETER(info);
1910 cmsUNUSED_PARAMETER(Stride);
1913 static
1914 cmsUInt8Number* Pack3BytesAndSkip1SwapFirstOptimized(register _cmsTRANSFORM* info,
1915 register cmsUInt16Number wOut[],
1916 register cmsUInt8Number* output,
1917 register cmsUInt32Number Stride)
1919 output++;
1920 *output++ = (wOut[0] & 0xFF);
1921 *output++ = (wOut[1] & 0xFF);
1922 *output++ = (wOut[2] & 0xFF);
1924 return output;
1926 cmsUNUSED_PARAMETER(info);
1927 cmsUNUSED_PARAMETER(Stride);
1930 static
1931 cmsUInt8Number* Pack3BytesAndSkip1Swap(register _cmsTRANSFORM* info,
1932 register cmsUInt16Number wOut[],
1933 register cmsUInt8Number* output,
1934 register cmsUInt32Number Stride)
1936 output++;
1937 *output++ = FROM_16_TO_8(wOut[2]);
1938 *output++ = FROM_16_TO_8(wOut[1]);
1939 *output++ = FROM_16_TO_8(wOut[0]);
1941 return output;
1943 cmsUNUSED_PARAMETER(info);
1944 cmsUNUSED_PARAMETER(Stride);
1947 static
1948 cmsUInt8Number* Pack3BytesAndSkip1SwapOptimized(register _cmsTRANSFORM* info,
1949 register cmsUInt16Number wOut[],
1950 register cmsUInt8Number* output,
1951 register cmsUInt32Number Stride)
1953 output++;
1954 *output++ = (wOut[2] & 0xFF);
1955 *output++ = (wOut[1] & 0xFF);
1956 *output++ = (wOut[0] & 0xFF);
1958 return output;
1960 cmsUNUSED_PARAMETER(info);
1961 cmsUNUSED_PARAMETER(Stride);
1965 static
1966 cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirst(register _cmsTRANSFORM* info,
1967 register cmsUInt16Number wOut[],
1968 register cmsUInt8Number* output,
1969 register cmsUInt32Number Stride)
1971 *output++ = FROM_16_TO_8(wOut[2]);
1972 *output++ = FROM_16_TO_8(wOut[1]);
1973 *output++ = FROM_16_TO_8(wOut[0]);
1974 output++;
1976 return output;
1978 cmsUNUSED_PARAMETER(info);
1979 cmsUNUSED_PARAMETER(Stride);
1982 static
1983 cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirstOptimized(register _cmsTRANSFORM* info,
1984 register cmsUInt16Number wOut[],
1985 register cmsUInt8Number* output,
1986 register cmsUInt32Number Stride)
1988 *output++ = (wOut[2] & 0xFF);
1989 *output++ = (wOut[1] & 0xFF);
1990 *output++ = (wOut[0] & 0xFF);
1991 output++;
1993 return output;
1995 cmsUNUSED_PARAMETER(info);
1996 cmsUNUSED_PARAMETER(Stride);
1999 static
2000 cmsUInt8Number* Pack3WordsAndSkip1(register _cmsTRANSFORM* info,
2001 register cmsUInt16Number wOut[],
2002 register cmsUInt8Number* output,
2003 register cmsUInt32Number Stride)
2005 *(cmsUInt16Number*) output = wOut[0];
2006 output+= 2;
2007 *(cmsUInt16Number*) output = wOut[1];
2008 output+= 2;
2009 *(cmsUInt16Number*) output = wOut[2];
2010 output+= 2;
2011 output+= 2;
2013 return output;
2015 cmsUNUSED_PARAMETER(info);
2016 cmsUNUSED_PARAMETER(Stride);
2019 static
2020 cmsUInt8Number* Pack3WordsAndSkip1Swap(register _cmsTRANSFORM* info,
2021 register cmsUInt16Number wOut[],
2022 register cmsUInt8Number* output,
2023 register cmsUInt32Number Stride)
2025 output+= 2;
2026 *(cmsUInt16Number*) output = wOut[2];
2027 output+= 2;
2028 *(cmsUInt16Number*) output = wOut[1];
2029 output+= 2;
2030 *(cmsUInt16Number*) output = wOut[0];
2031 output+= 2;
2033 return output;
2035 cmsUNUSED_PARAMETER(info);
2036 cmsUNUSED_PARAMETER(Stride);
2040 static
2041 cmsUInt8Number* Pack3WordsAndSkip1SwapFirst(register _cmsTRANSFORM* info,
2042 register cmsUInt16Number wOut[],
2043 register cmsUInt8Number* output,
2044 register cmsUInt32Number Stride)
2046 output+= 2;
2047 *(cmsUInt16Number*) output = wOut[0];
2048 output+= 2;
2049 *(cmsUInt16Number*) output = wOut[1];
2050 output+= 2;
2051 *(cmsUInt16Number*) output = wOut[2];
2052 output+= 2;
2054 return output;
2056 cmsUNUSED_PARAMETER(info);
2057 cmsUNUSED_PARAMETER(Stride);
2061 static
2062 cmsUInt8Number* Pack3WordsAndSkip1SwapSwapFirst(register _cmsTRANSFORM* info,
2063 register cmsUInt16Number wOut[],
2064 register cmsUInt8Number* output,
2065 register cmsUInt32Number Stride)
2067 *(cmsUInt16Number*) output = wOut[2];
2068 output+= 2;
2069 *(cmsUInt16Number*) output = wOut[1];
2070 output+= 2;
2071 *(cmsUInt16Number*) output = wOut[0];
2072 output+= 2;
2073 output+= 2;
2075 return output;
2077 cmsUNUSED_PARAMETER(info);
2078 cmsUNUSED_PARAMETER(Stride);
2083 static
2084 cmsUInt8Number* Pack1Byte(register _cmsTRANSFORM* info,
2085 register cmsUInt16Number wOut[],
2086 register cmsUInt8Number* output,
2087 register cmsUInt32Number Stride)
2089 *output++ = FROM_16_TO_8(wOut[0]);
2091 return output;
2093 cmsUNUSED_PARAMETER(info);
2094 cmsUNUSED_PARAMETER(Stride);
2098 static
2099 cmsUInt8Number* Pack1ByteReversed(register _cmsTRANSFORM* info,
2100 register cmsUInt16Number wOut[],
2101 register cmsUInt8Number* output,
2102 register cmsUInt32Number Stride)
2104 *output++ = FROM_16_TO_8(REVERSE_FLAVOR_16(wOut[0]));
2106 return output;
2108 cmsUNUSED_PARAMETER(info);
2109 cmsUNUSED_PARAMETER(Stride);
2113 static
2114 cmsUInt8Number* Pack1ByteSkip1(register _cmsTRANSFORM* info,
2115 register cmsUInt16Number wOut[],
2116 register cmsUInt8Number* output,
2117 register cmsUInt32Number Stride)
2119 *output++ = FROM_16_TO_8(wOut[0]);
2120 output++;
2122 return output;
2124 cmsUNUSED_PARAMETER(info);
2125 cmsUNUSED_PARAMETER(Stride);
2129 static
2130 cmsUInt8Number* Pack1ByteSkip1SwapFirst(register _cmsTRANSFORM* info,
2131 register cmsUInt16Number wOut[],
2132 register cmsUInt8Number* output,
2133 register cmsUInt32Number Stride)
2135 output++;
2136 *output++ = FROM_16_TO_8(wOut[0]);
2138 return output;
2140 cmsUNUSED_PARAMETER(info);
2141 cmsUNUSED_PARAMETER(Stride);
2144 static
2145 cmsUInt8Number* Pack1Word(register _cmsTRANSFORM* info,
2146 register cmsUInt16Number wOut[],
2147 register cmsUInt8Number* output,
2148 register cmsUInt32Number Stride)
2150 *(cmsUInt16Number*) output = wOut[0];
2151 output+= 2;
2153 return output;
2155 cmsUNUSED_PARAMETER(info);
2156 cmsUNUSED_PARAMETER(Stride);
2160 static
2161 cmsUInt8Number* Pack1WordReversed(register _cmsTRANSFORM* info,
2162 register cmsUInt16Number wOut[],
2163 register cmsUInt8Number* output,
2164 register cmsUInt32Number Stride)
2166 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[0]);
2167 output+= 2;
2169 return output;
2171 cmsUNUSED_PARAMETER(info);
2172 cmsUNUSED_PARAMETER(Stride);
2175 static
2176 cmsUInt8Number* Pack1WordBigEndian(register _cmsTRANSFORM* info,
2177 register cmsUInt16Number wOut[],
2178 register cmsUInt8Number* output,
2179 register cmsUInt32Number Stride)
2181 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
2182 output+= 2;
2184 return output;
2186 cmsUNUSED_PARAMETER(info);
2187 cmsUNUSED_PARAMETER(Stride);
2191 static
2192 cmsUInt8Number* Pack1WordSkip1(register _cmsTRANSFORM* info,
2193 register cmsUInt16Number wOut[],
2194 register cmsUInt8Number* output,
2195 register cmsUInt32Number Stride)
2197 *(cmsUInt16Number*) output = wOut[0];
2198 output+= 4;
2200 return output;
2202 cmsUNUSED_PARAMETER(info);
2203 cmsUNUSED_PARAMETER(Stride);
2206 static
2207 cmsUInt8Number* Pack1WordSkip1SwapFirst(register _cmsTRANSFORM* info,
2208 register cmsUInt16Number wOut[],
2209 register cmsUInt8Number* output,
2210 register cmsUInt32Number Stride)
2212 output += 2;
2213 *(cmsUInt16Number*) output = wOut[0];
2214 output+= 2;
2216 return output;
2218 cmsUNUSED_PARAMETER(info);
2219 cmsUNUSED_PARAMETER(Stride);
2223 // Unencoded Float values -- don't try optimize speed
2224 static
2225 cmsUInt8Number* PackLabDoubleFrom16(register _cmsTRANSFORM* info,
2226 register cmsUInt16Number wOut[],
2227 register cmsUInt8Number* output,
2228 register cmsUInt32Number Stride)
2231 if (T_PLANAR(info -> OutputFormat)) {
2233 cmsCIELab Lab;
2234 cmsFloat64Number* Out = (cmsFloat64Number*) output;
2235 cmsLabEncoded2Float(&Lab, wOut);
2237 Out[0] = Lab.L;
2238 Out[Stride] = Lab.a;
2239 Out[Stride*2] = Lab.b;
2241 return output + sizeof(cmsFloat64Number);
2243 else {
2245 cmsLabEncoded2Float((cmsCIELab*) output, wOut);
2246 return output + (sizeof(cmsCIELab) + T_EXTRA(info ->OutputFormat) * sizeof(cmsFloat64Number));
2251 static
2252 cmsUInt8Number* PackLabFloatFrom16(register _cmsTRANSFORM* info,
2253 register cmsUInt16Number wOut[],
2254 register cmsUInt8Number* output,
2255 register cmsUInt32Number Stride)
2257 cmsCIELab Lab;
2258 cmsLabEncoded2Float(&Lab, wOut);
2260 if (T_PLANAR(info -> OutputFormat)) {
2262 cmsFloat32Number* Out = (cmsFloat32Number*) output;
2264 Out[0] = (cmsFloat32Number)Lab.L;
2265 Out[Stride] = (cmsFloat32Number)Lab.a;
2266 Out[Stride*2] = (cmsFloat32Number)Lab.b;
2268 return output + sizeof(cmsFloat32Number);
2270 else {
2272 ((cmsFloat32Number*) output)[0] = (cmsFloat32Number) Lab.L;
2273 ((cmsFloat32Number*) output)[1] = (cmsFloat32Number) Lab.a;
2274 ((cmsFloat32Number*) output)[2] = (cmsFloat32Number) Lab.b;
2276 return output + (3 + T_EXTRA(info ->OutputFormat)) * sizeof(cmsFloat32Number);
2280 static
2281 cmsUInt8Number* PackXYZDoubleFrom16(register _cmsTRANSFORM* Info,
2282 register cmsUInt16Number wOut[],
2283 register cmsUInt8Number* output,
2284 register cmsUInt32Number Stride)
2286 if (T_PLANAR(Info -> OutputFormat)) {
2288 cmsCIEXYZ XYZ;
2289 cmsFloat64Number* Out = (cmsFloat64Number*) output;
2290 cmsXYZEncoded2Float(&XYZ, wOut);
2292 Out[0] = XYZ.X;
2293 Out[Stride] = XYZ.Y;
2294 Out[Stride*2] = XYZ.Z;
2296 return output + sizeof(cmsFloat64Number);
2299 else {
2301 cmsXYZEncoded2Float((cmsCIEXYZ*) output, wOut);
2303 return output + (sizeof(cmsCIEXYZ) + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
2307 static
2308 cmsUInt8Number* PackDoubleFrom16(register _cmsTRANSFORM* info,
2309 register cmsUInt16Number wOut[],
2310 register cmsUInt8Number* output,
2311 register cmsUInt32Number Stride)
2313 int nChan = T_CHANNELS(info -> OutputFormat);
2314 int DoSwap = T_DOSWAP(info ->OutputFormat);
2315 int Reverse = T_FLAVOR(info ->OutputFormat);
2316 int Extra = T_EXTRA(info -> OutputFormat);
2317 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2318 int Planar = T_PLANAR(info -> OutputFormat);
2319 int ExtraFirst = DoSwap ^ SwapFirst;
2320 cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35 : 65535.0;
2321 cmsFloat64Number v = 0;
2322 cmsFloat64Number* swap1 = (cmsFloat64Number*) output;
2323 int i, start = 0;
2325 if (ExtraFirst)
2326 start = Extra;
2328 for (i=0; i < nChan; i++) {
2330 int index = DoSwap ? (nChan - i - 1) : i;
2332 v = (cmsFloat64Number) wOut[index] / maximum;
2334 if (Reverse)
2335 v = maximum - v;
2337 if (Planar)
2338 ((cmsFloat64Number*) output)[(i + start) * Stride]= v;
2339 else
2340 ((cmsFloat64Number*) output)[i + start] = v;
2343 if (!ExtraFirst) {
2344 output += Extra * sizeof(cmsFloat64Number);
2347 if (Extra == 0 && SwapFirst) {
2349 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat64Number));
2350 *swap1 = v;
2353 if (T_PLANAR(info -> OutputFormat))
2354 return output + sizeof(cmsFloat64Number);
2355 else
2356 return output + nChan * sizeof(cmsFloat64Number);
2361 static
2362 cmsUInt8Number* PackFloatFrom16(register _cmsTRANSFORM* info,
2363 register cmsUInt16Number wOut[],
2364 register cmsUInt8Number* output,
2365 register cmsUInt32Number Stride)
2367 int nChan = T_CHANNELS(info -> OutputFormat);
2368 int DoSwap = T_DOSWAP(info ->OutputFormat);
2369 int Reverse = T_FLAVOR(info ->OutputFormat);
2370 int Extra = T_EXTRA(info -> OutputFormat);
2371 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2372 int Planar = T_PLANAR(info -> OutputFormat);
2373 int ExtraFirst = DoSwap ^ SwapFirst;
2374 cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35 : 65535.0;
2375 cmsFloat64Number v = 0;
2376 cmsFloat32Number* swap1 = (cmsFloat32Number*) output;
2377 int i, start = 0;
2379 if (ExtraFirst)
2380 start = Extra;
2382 for (i=0; i < nChan; i++) {
2384 int index = DoSwap ? (nChan - i - 1) : i;
2386 v = (cmsFloat64Number) wOut[index] / maximum;
2388 if (Reverse)
2389 v = maximum - v;
2391 if (Planar)
2392 ((cmsFloat32Number*) output)[(i + start ) * Stride]= (cmsFloat32Number) v;
2393 else
2394 ((cmsFloat32Number*) output)[i + start] = (cmsFloat32Number) v;
2397 if (!ExtraFirst) {
2398 output += Extra * sizeof(cmsFloat32Number);
2401 if (Extra == 0 && SwapFirst) {
2403 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat32Number));
2404 *swap1 = (cmsFloat32Number) v;
2407 if (T_PLANAR(info -> OutputFormat))
2408 return output + sizeof(cmsFloat32Number);
2409 else
2410 return output + nChan * sizeof(cmsFloat32Number);
2415 // --------------------------------------------------------------------------------------------------------
2417 static
2418 cmsUInt8Number* PackFloatsFromFloat(_cmsTRANSFORM* info,
2419 cmsFloat32Number wOut[],
2420 cmsUInt8Number* output,
2421 cmsUInt32Number Stride)
2423 int nChan = T_CHANNELS(info -> OutputFormat);
2424 int DoSwap = T_DOSWAP(info ->OutputFormat);
2425 int Reverse = T_FLAVOR(info ->OutputFormat);
2426 int Extra = T_EXTRA(info -> OutputFormat);
2427 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2428 int Planar = T_PLANAR(info -> OutputFormat);
2429 int ExtraFirst = DoSwap ^ SwapFirst;
2430 cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
2431 cmsFloat32Number* swap1 = (cmsFloat32Number*) output;
2432 cmsFloat64Number v = 0;
2433 int i, start = 0;
2435 if (ExtraFirst)
2436 start = Extra;
2438 for (i=0; i < nChan; i++) {
2440 int index = DoSwap ? (nChan - i - 1) : i;
2442 v = wOut[index] * maximum;
2444 if (Reverse)
2445 v = maximum - v;
2447 if (Planar)
2448 ((cmsFloat32Number*) output)[(i + start)* Stride]= (cmsFloat32Number) v;
2449 else
2450 ((cmsFloat32Number*) output)[i + start] = (cmsFloat32Number) v;
2453 if (!ExtraFirst) {
2454 output += Extra * sizeof(cmsFloat32Number);
2457 if (Extra == 0 && SwapFirst) {
2459 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat32Number));
2460 *swap1 = (cmsFloat32Number) v;
2463 if (T_PLANAR(info -> OutputFormat))
2464 return output + sizeof(cmsFloat32Number);
2465 else
2466 return output + nChan * sizeof(cmsFloat32Number);
2469 static
2470 cmsUInt8Number* PackDoublesFromFloat(_cmsTRANSFORM* info,
2471 cmsFloat32Number wOut[],
2472 cmsUInt8Number* output,
2473 cmsUInt32Number Stride)
2475 int nChan = T_CHANNELS(info -> OutputFormat);
2476 int DoSwap = T_DOSWAP(info ->OutputFormat);
2477 int Reverse = T_FLAVOR(info ->OutputFormat);
2478 int Extra = T_EXTRA(info -> OutputFormat);
2479 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2480 int Planar = T_PLANAR(info -> OutputFormat);
2481 int ExtraFirst = DoSwap ^ SwapFirst;
2482 cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
2483 cmsFloat64Number v = 0;
2484 cmsFloat64Number* swap1 = (cmsFloat64Number*) output;
2485 int i, start = 0;
2487 if (ExtraFirst)
2488 start = Extra;
2490 for (i=0; i < nChan; i++) {
2492 int index = DoSwap ? (nChan - i - 1) : i;
2494 v = wOut[index] * maximum;
2496 if (Reverse)
2497 v = maximum - v;
2499 if (Planar)
2500 ((cmsFloat64Number*) output)[(i + start) * Stride] = v;
2501 else
2502 ((cmsFloat64Number*) output)[i + start] = v;
2505 if (!ExtraFirst) {
2506 output += Extra * sizeof(cmsFloat64Number);
2509 if (Extra == 0 && SwapFirst) {
2511 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat64Number));
2512 *swap1 = v;
2516 if (T_PLANAR(info -> OutputFormat))
2517 return output + sizeof(cmsFloat64Number);
2518 else
2519 return output + nChan * sizeof(cmsFloat64Number);
2527 static
2528 cmsUInt8Number* PackLabFloatFromFloat(_cmsTRANSFORM* Info,
2529 cmsFloat32Number wOut[],
2530 cmsUInt8Number* output,
2531 cmsUInt32Number Stride)
2533 cmsFloat32Number* Out = (cmsFloat32Number*) output;
2535 if (T_PLANAR(Info -> OutputFormat)) {
2537 Out[0] = (cmsFloat32Number) (wOut[0] * 100.0);
2538 Out[Stride] = (cmsFloat32Number) (wOut[1] * 255.0 - 128.0);
2539 Out[Stride*2] = (cmsFloat32Number) (wOut[2] * 255.0 - 128.0);
2541 return output + sizeof(cmsFloat32Number);
2543 else {
2545 Out[0] = (cmsFloat32Number) (wOut[0] * 100.0);
2546 Out[1] = (cmsFloat32Number) (wOut[1] * 255.0 - 128.0);
2547 Out[2] = (cmsFloat32Number) (wOut[2] * 255.0 - 128.0);
2549 return output + (sizeof(cmsFloat32Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
2555 static
2556 cmsUInt8Number* PackLabDoubleFromFloat(_cmsTRANSFORM* Info,
2557 cmsFloat32Number wOut[],
2558 cmsUInt8Number* output,
2559 cmsUInt32Number Stride)
2561 cmsFloat64Number* Out = (cmsFloat64Number*) output;
2563 if (T_PLANAR(Info -> OutputFormat)) {
2565 Out[0] = (cmsFloat64Number) (wOut[0] * 100.0);
2566 Out[Stride] = (cmsFloat64Number) (wOut[1] * 255.0 - 128.0);
2567 Out[Stride*2] = (cmsFloat64Number) (wOut[2] * 255.0 - 128.0);
2569 return output + sizeof(cmsFloat64Number);
2571 else {
2573 Out[0] = (cmsFloat64Number) (wOut[0] * 100.0);
2574 Out[1] = (cmsFloat64Number) (wOut[1] * 255.0 - 128.0);
2575 Out[2] = (cmsFloat64Number) (wOut[2] * 255.0 - 128.0);
2577 return output + (sizeof(cmsFloat64Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
2583 // From 0..1 range to 0..MAX_ENCODEABLE_XYZ
2584 static
2585 cmsUInt8Number* PackXYZFloatFromFloat(_cmsTRANSFORM* Info,
2586 cmsFloat32Number wOut[],
2587 cmsUInt8Number* output,
2588 cmsUInt32Number Stride)
2590 cmsFloat32Number* Out = (cmsFloat32Number*) output;
2592 if (T_PLANAR(Info -> OutputFormat)) {
2594 Out[0] = (cmsFloat32Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
2595 Out[Stride] = (cmsFloat32Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
2596 Out[Stride*2] = (cmsFloat32Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
2598 return output + sizeof(cmsFloat32Number);
2600 else {
2602 Out[0] = (cmsFloat32Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
2603 Out[1] = (cmsFloat32Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
2604 Out[2] = (cmsFloat32Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
2606 return output + (sizeof(cmsFloat32Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
2611 // Same, but convert to double
2612 static
2613 cmsUInt8Number* PackXYZDoubleFromFloat(_cmsTRANSFORM* Info,
2614 cmsFloat32Number wOut[],
2615 cmsUInt8Number* output,
2616 cmsUInt32Number Stride)
2618 cmsFloat64Number* Out = (cmsFloat64Number*) output;
2620 if (T_PLANAR(Info -> OutputFormat)) {
2622 Out[0] = (cmsFloat64Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
2623 Out[Stride] = (cmsFloat64Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
2624 Out[Stride*2] = (cmsFloat64Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
2626 return output + sizeof(cmsFloat64Number);
2628 else {
2630 Out[0] = (cmsFloat64Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
2631 Out[1] = (cmsFloat64Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
2632 Out[2] = (cmsFloat64Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
2634 return output + (sizeof(cmsFloat64Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
2640 // ----------------------------------------------------------------------------------------------------------------
2642 #ifndef CMS_NO_HALF_SUPPORT
2644 // Decodes an stream of half floats to wIn[] described by input format
2646 static
2647 cmsUInt8Number* UnrollHalfTo16(register _cmsTRANSFORM* info,
2648 register cmsUInt16Number wIn[],
2649 register cmsUInt8Number* accum,
2650 register cmsUInt32Number Stride)
2653 int nChan = T_CHANNELS(info -> InputFormat);
2654 int DoSwap = T_DOSWAP(info ->InputFormat);
2655 int Reverse = T_FLAVOR(info ->InputFormat);
2656 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
2657 int Extra = T_EXTRA(info -> InputFormat);
2658 int ExtraFirst = DoSwap ^ SwapFirst;
2659 int Planar = T_PLANAR(info -> InputFormat);
2660 cmsFloat32Number v;
2661 int i, start = 0;
2662 cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 655.35F : 65535.0F;
2665 if (ExtraFirst)
2666 start = Extra;
2668 for (i=0; i < nChan; i++) {
2670 int index = DoSwap ? (nChan - i - 1) : i;
2672 if (Planar)
2673 v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[(i + start) * Stride] );
2674 else
2675 v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[i + start] ) ;
2677 if (Reverse) v = maximum - v;
2679 wIn[index] = _cmsQuickSaturateWord(v * maximum);
2683 if (Extra == 0 && SwapFirst) {
2684 cmsUInt16Number tmp = wIn[0];
2686 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
2687 wIn[nChan-1] = tmp;
2690 if (T_PLANAR(info -> InputFormat))
2691 return accum + sizeof(cmsUInt16Number);
2692 else
2693 return accum + (nChan + Extra) * sizeof(cmsUInt16Number);
2696 // Decodes an stream of half floats to wIn[] described by input format
2698 static
2699 cmsUInt8Number* UnrollHalfToFloat(_cmsTRANSFORM* info,
2700 cmsFloat32Number wIn[],
2701 cmsUInt8Number* accum,
2702 cmsUInt32Number Stride)
2705 int nChan = T_CHANNELS(info -> InputFormat);
2706 int DoSwap = T_DOSWAP(info ->InputFormat);
2707 int Reverse = T_FLAVOR(info ->InputFormat);
2708 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
2709 int Extra = T_EXTRA(info -> InputFormat);
2710 int ExtraFirst = DoSwap ^ SwapFirst;
2711 int Planar = T_PLANAR(info -> InputFormat);
2712 cmsFloat32Number v;
2713 int i, start = 0;
2714 cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 100.0F : 1.0F;
2717 if (ExtraFirst)
2718 start = Extra;
2720 for (i=0; i < nChan; i++) {
2722 int index = DoSwap ? (nChan - i - 1) : i;
2724 if (Planar)
2725 v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[(i + start) * Stride] );
2726 else
2727 v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[i + start] ) ;
2729 v /= maximum;
2731 wIn[index] = Reverse ? 1 - v : v;
2735 if (Extra == 0 && SwapFirst) {
2736 cmsFloat32Number tmp = wIn[0];
2738 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number));
2739 wIn[nChan-1] = tmp;
2742 if (T_PLANAR(info -> InputFormat))
2743 return accum + sizeof(cmsUInt16Number);
2744 else
2745 return accum + (nChan + Extra) * sizeof(cmsUInt16Number);
2749 static
2750 cmsUInt8Number* PackHalfFrom16(register _cmsTRANSFORM* info,
2751 register cmsUInt16Number wOut[],
2752 register cmsUInt8Number* output,
2753 register cmsUInt32Number Stride)
2755 int nChan = T_CHANNELS(info -> OutputFormat);
2756 int DoSwap = T_DOSWAP(info ->OutputFormat);
2757 int Reverse = T_FLAVOR(info ->OutputFormat);
2758 int Extra = T_EXTRA(info -> OutputFormat);
2759 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2760 int Planar = T_PLANAR(info -> OutputFormat);
2761 int ExtraFirst = DoSwap ^ SwapFirst;
2762 cmsFloat32Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35F : 65535.0F;
2763 cmsFloat32Number v = 0;
2764 cmsUInt16Number* swap1 = (cmsUInt16Number*) output;
2765 int i, start = 0;
2767 if (ExtraFirst)
2768 start = Extra;
2770 for (i=0; i < nChan; i++) {
2772 int index = DoSwap ? (nChan - i - 1) : i;
2774 v = (cmsFloat32Number) wOut[index] / maximum;
2776 if (Reverse)
2777 v = maximum - v;
2779 if (Planar)
2780 ((cmsUInt16Number*) output)[(i + start ) * Stride]= _cmsFloat2Half(v);
2781 else
2782 ((cmsUInt16Number*) output)[i + start] = _cmsFloat2Half(v);
2785 if (!ExtraFirst) {
2786 output += Extra * sizeof(cmsUInt16Number);
2789 if (Extra == 0 && SwapFirst) {
2791 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number));
2792 *swap1 = _cmsFloat2Half(v);
2795 if (T_PLANAR(info -> OutputFormat))
2796 return output + sizeof(cmsUInt16Number);
2797 else
2798 return output + nChan * sizeof(cmsUInt16Number);
2803 static
2804 cmsUInt8Number* PackHalfFromFloat(_cmsTRANSFORM* info,
2805 cmsFloat32Number wOut[],
2806 cmsUInt8Number* output,
2807 cmsUInt32Number Stride)
2809 int nChan = T_CHANNELS(info -> OutputFormat);
2810 int DoSwap = T_DOSWAP(info ->OutputFormat);
2811 int Reverse = T_FLAVOR(info ->OutputFormat);
2812 int Extra = T_EXTRA(info -> OutputFormat);
2813 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2814 int Planar = T_PLANAR(info -> OutputFormat);
2815 int ExtraFirst = DoSwap ^ SwapFirst;
2816 cmsFloat32Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0F : 1.0F;
2817 cmsUInt16Number* swap1 = (cmsUInt16Number*) output;
2818 cmsFloat32Number v = 0;
2819 int i, start = 0;
2821 if (ExtraFirst)
2822 start = Extra;
2824 for (i=0; i < nChan; i++) {
2826 int index = DoSwap ? (nChan - i - 1) : i;
2828 v = wOut[index] * maximum;
2830 if (Reverse)
2831 v = maximum - v;
2833 if (Planar)
2834 ((cmsUInt16Number*) output)[(i + start)* Stride]= _cmsFloat2Half( v );
2835 else
2836 ((cmsUInt16Number*) output)[i + start] = _cmsFloat2Half( v );
2839 if (!ExtraFirst) {
2840 output += Extra * sizeof(cmsUInt16Number);
2843 if (Extra == 0 && SwapFirst) {
2845 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number));
2846 *swap1 = (cmsUInt16Number) _cmsFloat2Half( v );
2849 if (T_PLANAR(info -> OutputFormat))
2850 return output + sizeof(cmsUInt16Number);
2851 else
2852 return output + nChan * sizeof(cmsUInt16Number);
2855 #endif
2857 // ----------------------------------------------------------------------------------------------------------------
2860 static cmsFormatters16 InputFormatters16[] = {
2862 // Type Mask Function
2863 // ---------------------------- ------------------------------------ ----------------------------
2864 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, UnrollLabDoubleTo16},
2865 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, UnrollXYZDoubleTo16},
2866 { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, UnrollLabFloatTo16},
2867 { TYPE_GRAY_DBL, 0, UnrollDouble1Chan},
2868 { FLOAT_SH(1)|BYTES_SH(0), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR|
2869 ANYSWAP|ANYEXTRA|ANYSPACE, UnrollDoubleTo16},
2870 { FLOAT_SH(1)|BYTES_SH(4), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR|
2871 ANYSWAP|ANYEXTRA|ANYSPACE, UnrollFloatTo16},
2872 #ifndef CMS_NO_HALF_SUPPORT
2873 { FLOAT_SH(1)|BYTES_SH(2), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR|
2874 ANYEXTRA|ANYSWAP|ANYSPACE, UnrollHalfTo16},
2875 #endif
2877 { CHANNELS_SH(1)|BYTES_SH(1), ANYSPACE, Unroll1Byte},
2878 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Unroll1ByteSkip1},
2879 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(2), ANYSPACE, Unroll1ByteSkip2},
2880 { CHANNELS_SH(1)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Unroll1ByteReversed},
2881 { COLORSPACE_SH(PT_MCH2)|CHANNELS_SH(2)|BYTES_SH(1), 0, Unroll2Bytes},
2883 { TYPE_LabV2_8, 0, UnrollLabV2_8 },
2884 { TYPE_ALabV2_8, 0, UnrollALabV2_8 },
2885 { TYPE_LabV2_16, 0, UnrollLabV2_16 },
2887 { CHANNELS_SH(3)|BYTES_SH(1), ANYSPACE, Unroll3Bytes},
2888 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3BytesSwap},
2889 { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3BytesSkip1Swap},
2890 { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll3BytesSkip1SwapFirst},
2892 { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1),
2893 ANYSPACE, Unroll3BytesSkip1SwapSwapFirst},
2895 { CHANNELS_SH(4)|BYTES_SH(1), ANYSPACE, Unroll4Bytes},
2896 { CHANNELS_SH(4)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Unroll4BytesReverse},
2897 { CHANNELS_SH(4)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4BytesSwapFirst},
2898 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll4BytesSwap},
2899 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4BytesSwapSwapFirst},
2901 { BYTES_SH(1)|PLANAR_SH(1), ANYFLAVOR|ANYSWAPFIRST|
2902 ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollPlanarBytes},
2904 { BYTES_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
2905 ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollChunkyBytes},
2907 { CHANNELS_SH(1)|BYTES_SH(2), ANYSPACE, Unroll1Word},
2908 { CHANNELS_SH(1)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Unroll1WordReversed},
2909 { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(3), ANYSPACE, Unroll1WordSkip3},
2911 { CHANNELS_SH(2)|BYTES_SH(2), ANYSPACE, Unroll2Words},
2912 { CHANNELS_SH(3)|BYTES_SH(2), ANYSPACE, Unroll3Words},
2913 { CHANNELS_SH(4)|BYTES_SH(2), ANYSPACE, Unroll4Words},
2915 { CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Unroll3WordsSwap},
2916 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll3WordsSkip1SwapFirst},
2917 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3WordsSkip1Swap},
2918 { CHANNELS_SH(4)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Unroll4WordsReverse},
2919 { CHANNELS_SH(4)|BYTES_SH(2)|SWAPFIRST_SH(1), ANYSPACE, Unroll4WordsSwapFirst},
2920 { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Unroll4WordsSwap},
2921 { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4WordsSwapSwapFirst},
2924 { BYTES_SH(2)|PLANAR_SH(1), ANYFLAVOR|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollPlanarWords},
2925 { BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollAnyWords},
2930 static cmsFormattersFloat InputFormattersFloat[] = {
2932 // Type Mask Function
2933 // ---------------------------- ------------------------------------ ----------------------------
2934 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, UnrollLabDoubleToFloat},
2935 { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, UnrollLabFloatToFloat},
2937 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, UnrollXYZDoubleToFloat},
2938 { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, UnrollXYZFloatToFloat},
2940 { FLOAT_SH(1)|BYTES_SH(4), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
2941 ANYCHANNELS|ANYSPACE, UnrollFloatsToFloat},
2943 { FLOAT_SH(1)|BYTES_SH(0), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
2944 ANYCHANNELS|ANYSPACE, UnrollDoublesToFloat},
2945 #ifndef CMS_NO_HALF_SUPPORT
2946 { FLOAT_SH(1)|BYTES_SH(2), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
2947 ANYCHANNELS|ANYSPACE, UnrollHalfToFloat},
2948 #endif
2952 // Bit fields set to one in the mask are not compared
2953 static
2954 cmsFormatter _cmsGetStockInputFormatter(cmsUInt32Number dwInput, cmsUInt32Number dwFlags)
2956 cmsUInt32Number i;
2957 cmsFormatter fr;
2959 switch (dwFlags) {
2961 case CMS_PACK_FLAGS_16BITS: {
2962 for (i=0; i < sizeof(InputFormatters16) / sizeof(cmsFormatters16); i++) {
2963 cmsFormatters16* f = InputFormatters16 + i;
2965 if ((dwInput & ~f ->Mask) == f ->Type) {
2966 fr.Fmt16 = f ->Frm;
2967 return fr;
2971 break;
2973 case CMS_PACK_FLAGS_FLOAT: {
2974 for (i=0; i < sizeof(InputFormattersFloat) / sizeof(cmsFormattersFloat); i++) {
2975 cmsFormattersFloat* f = InputFormattersFloat + i;
2977 if ((dwInput & ~f ->Mask) == f ->Type) {
2978 fr.FmtFloat = f ->Frm;
2979 return fr;
2983 break;
2985 default:;
2989 fr.Fmt16 = NULL;
2990 return fr;
2993 static cmsFormatters16 OutputFormatters16[] = {
2994 // Type Mask Function
2995 // ---------------------------- ------------------------------------ ----------------------------
2997 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, PackLabDoubleFrom16},
2998 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, PackXYZDoubleFrom16},
3000 { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, PackLabFloatFrom16},
3002 { FLOAT_SH(1)|BYTES_SH(0), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
3003 ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackDoubleFrom16},
3004 { FLOAT_SH(1)|BYTES_SH(4), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
3005 ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackFloatFrom16},
3006 #ifndef CMS_NO_HALF_SUPPORT
3007 { FLOAT_SH(1)|BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
3008 ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackHalfFrom16},
3009 #endif
3011 { CHANNELS_SH(1)|BYTES_SH(1), ANYSPACE, Pack1Byte},
3012 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Pack1ByteSkip1},
3013 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack1ByteSkip1SwapFirst},
3015 { CHANNELS_SH(1)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Pack1ByteReversed},
3017 { TYPE_LabV2_8, 0, PackLabV2_8 },
3018 { TYPE_ALabV2_8, 0, PackALabV2_8 },
3019 { TYPE_LabV2_16, 0, PackLabV2_16 },
3021 { CHANNELS_SH(3)|BYTES_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesOptimized},
3022 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesAndSkip1Optimized},
3023 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1)|OPTIMIZED_SH(1),
3024 ANYSPACE, Pack3BytesAndSkip1SwapFirstOptimized},
3025 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1)|OPTIMIZED_SH(1),
3026 ANYSPACE, Pack3BytesAndSkip1SwapSwapFirstOptimized},
3027 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|EXTRA_SH(1)|OPTIMIZED_SH(1),
3028 ANYSPACE, Pack3BytesAndSkip1SwapOptimized},
3029 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesSwapOptimized},
3033 { CHANNELS_SH(3)|BYTES_SH(1), ANYSPACE, Pack3Bytes},
3034 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Pack3BytesAndSkip1},
3035 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack3BytesAndSkip1SwapFirst},
3036 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1),
3037 ANYSPACE, Pack3BytesAndSkip1SwapSwapFirst},
3038 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|EXTRA_SH(1), ANYSPACE, Pack3BytesAndSkip1Swap},
3039 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack3BytesSwap},
3040 { CHANNELS_SH(6)|BYTES_SH(1), ANYSPACE, Pack6Bytes},
3041 { CHANNELS_SH(6)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack6BytesSwap},
3042 { CHANNELS_SH(4)|BYTES_SH(1), ANYSPACE, Pack4Bytes},
3043 { CHANNELS_SH(4)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Pack4BytesReverse},
3044 { CHANNELS_SH(4)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack4BytesSwapFirst},
3045 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack4BytesSwap},
3046 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack4BytesSwapSwapFirst},
3048 { BYTES_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackAnyBytes},
3049 { BYTES_SH(1)|PLANAR_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackPlanarBytes},
3051 { CHANNELS_SH(1)|BYTES_SH(2), ANYSPACE, Pack1Word},
3052 { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(1), ANYSPACE, Pack1WordSkip1},
3053 { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack1WordSkip1SwapFirst},
3054 { CHANNELS_SH(1)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Pack1WordReversed},
3055 { CHANNELS_SH(1)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack1WordBigEndian},
3056 { CHANNELS_SH(3)|BYTES_SH(2), ANYSPACE, Pack3Words},
3057 { CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack3WordsSwap},
3058 { CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack3WordsBigEndian},
3059 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1), ANYSPACE, Pack3WordsAndSkip1},
3060 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack3WordsAndSkip1Swap},
3061 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack3WordsAndSkip1SwapFirst},
3063 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1),
3064 ANYSPACE, Pack3WordsAndSkip1SwapSwapFirst},
3066 { CHANNELS_SH(4)|BYTES_SH(2), ANYSPACE, Pack4Words},
3067 { CHANNELS_SH(4)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Pack4WordsReverse},
3068 { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack4WordsSwap},
3069 { CHANNELS_SH(4)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack4WordsBigEndian},
3071 { CHANNELS_SH(6)|BYTES_SH(2), ANYSPACE, Pack6Words},
3072 { CHANNELS_SH(6)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack6WordsSwap},
3074 { BYTES_SH(2)|PLANAR_SH(1), ANYFLAVOR|ANYENDIAN|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackPlanarWords},
3075 { BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackAnyWords}
3080 static cmsFormattersFloat OutputFormattersFloat[] = {
3081 // Type Mask Function
3082 // ---------------------------- --------------------------------------------------- ----------------------------
3083 { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, PackLabFloatFromFloat},
3084 { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, PackXYZFloatFromFloat},
3086 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, PackLabDoubleFromFloat},
3087 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, PackXYZDoubleFromFloat},
3089 { FLOAT_SH(1)|BYTES_SH(4), ANYPLANAR|
3090 ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackFloatsFromFloat },
3091 { FLOAT_SH(1)|BYTES_SH(0), ANYPLANAR|
3092 ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackDoublesFromFloat },
3093 #ifndef CMS_NO_HALF_SUPPORT
3094 { FLOAT_SH(1)|BYTES_SH(2),
3095 ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackHalfFromFloat },
3096 #endif
3103 // Bit fields set to one in the mask are not compared
3104 static
3105 cmsFormatter _cmsGetStockOutputFormatter(cmsUInt32Number dwInput, cmsUInt32Number dwFlags)
3107 cmsUInt32Number i;
3108 cmsFormatter fr;
3111 switch (dwFlags)
3114 case CMS_PACK_FLAGS_16BITS: {
3116 for (i=0; i < sizeof(OutputFormatters16) / sizeof(cmsFormatters16); i++) {
3117 cmsFormatters16* f = OutputFormatters16 + i;
3119 if ((dwInput & ~f ->Mask) == f ->Type) {
3120 fr.Fmt16 = f ->Frm;
3121 return fr;
3125 break;
3127 case CMS_PACK_FLAGS_FLOAT: {
3129 for (i=0; i < sizeof(OutputFormattersFloat) / sizeof(cmsFormattersFloat); i++) {
3130 cmsFormattersFloat* f = OutputFormattersFloat + i;
3132 if ((dwInput & ~f ->Mask) == f ->Type) {
3133 fr.FmtFloat = f ->Frm;
3134 return fr;
3138 break;
3140 default:;
3144 fr.Fmt16 = NULL;
3145 return fr;
3149 typedef struct _cms_formatters_factory_list {
3151 cmsFormatterFactory Factory;
3152 struct _cms_formatters_factory_list *Next;
3154 } cmsFormattersFactoryList;
3156 static cmsFormattersFactoryList* FactoryList = NULL;
3159 // Formatters management
3160 cmsBool _cmsRegisterFormattersPlugin(cmsContext id, cmsPluginBase* Data)
3162 cmsPluginFormatters* Plugin = (cmsPluginFormatters*) Data;
3163 cmsFormattersFactoryList* fl ;
3165 // Reset
3166 if (Data == NULL) {
3168 FactoryList = NULL;
3169 return TRUE;
3172 fl = (cmsFormattersFactoryList*) _cmsPluginMalloc(id, sizeof(cmsFormattersFactoryList));
3173 if (fl == NULL) return FALSE;
3175 fl ->Factory = Plugin ->FormattersFactory;
3177 fl ->Next = FactoryList;
3178 FactoryList = fl;
3180 return TRUE;
3183 cmsFormatter _cmsGetFormatter(cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8
3184 cmsFormatterDirection Dir,
3185 cmsUInt32Number dwFlags)
3187 cmsFormattersFactoryList* f;
3189 for (f = FactoryList; f != NULL; f = f ->Next) {
3191 cmsFormatter fn = f ->Factory(Type, Dir, dwFlags);
3192 if (fn.Fmt16 != NULL) return fn;
3195 // Revert to default
3196 if (Dir == cmsFormatterInput)
3197 return _cmsGetStockInputFormatter(Type, dwFlags);
3198 else
3199 return _cmsGetStockOutputFormatter(Type, dwFlags);
3203 // Return whatever given formatter refers to float values
3204 cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type)
3206 return T_FLOAT(Type) ? TRUE : FALSE;
3209 // Return whatever given formatter refers to 8 bits
3210 cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type)
3212 int Bytes = T_BYTES(Type);
3214 return (Bytes == 1);
3217 // Build a suitable formatter for the colorspace of this profile
3218 cmsUInt32Number CMSEXPORT cmsFormatterForColorspaceOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat)
3221 cmsColorSpaceSignature ColorSpace = cmsGetColorSpace(hProfile);
3222 cmsUInt32Number ColorSpaceBits = _cmsLCMScolorSpace(ColorSpace);
3223 cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace);
3224 cmsUInt32Number Float = lIsFloat ? 1 : 0;
3226 // Create a fake formatter for result
3227 return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans);
3230 // Build a suitable formatter for the colorspace of this profile
3231 cmsUInt32Number CMSEXPORT cmsFormatterForPCSOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat)
3234 cmsColorSpaceSignature ColorSpace = cmsGetPCS(hProfile);
3235 int ColorSpaceBits = _cmsLCMScolorSpace(ColorSpace);
3236 cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace);
3237 cmsUInt32Number Float = lIsFloat ? 1 : 0;
3239 // Create a fake formatter for result
3240 return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans);