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:
12 //
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
15 //
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.
23 //
24 //---------------------------------------------------------------------------------
25 //
26 #include "lcms2_internal.h"
27
28 // This module handles all formats supported by lcms. There are two flavors, 16 bits and
29 // floating point. Floating point is supported only in a subset, those formats holding
30 // cmsFloat32Number (4 bytes per component) and double (marked as 0 bytes per component
31 // as special case)
32
33 // ---------------------------------------------------------------------------
34
35
36 // This macro return words stored as big endian
37 #define CHANGE_ENDIAN(w) (cmsUInt16Number) ((cmsUInt16Number) ((w)<<8)|((w)>>8))
38
39 // These macros handles reversing (negative)
40 #define REVERSE_FLAVOR_8(x) ((cmsUInt8Number) (0xff-(x)))
41 #define REVERSE_FLAVOR_16(x) ((cmsUInt16Number)(0xffff-(x)))
42
43 // * 0xffff / 0xff00 = (255 * 257) / (255 * 256) = 257 / 256
FomLabV2ToLabV4(cmsUInt16Number x)44 cmsINLINE cmsUInt16Number FomLabV2ToLabV4(cmsUInt16Number x)
45 {
46 int a = (x << 8 | x) >> 8; // * 257 / 256
47 if ( a > 0xffff) return 0xffff;
48 return (cmsUInt16Number) a;
49 }
50
51 // * 0xf00 / 0xffff = * 256 / 257
FomLabV4ToLabV2(cmsUInt16Number x)52 cmsINLINE cmsUInt16Number FomLabV4ToLabV2(cmsUInt16Number x)
53 {
54 return (cmsUInt16Number) (((x << 8) + 0x80) / 257);
55 }
56
57
58 typedef struct {
59 cmsUInt32Number Type;
60 cmsUInt32Number Mask;
61 cmsFormatter16 Frm;
62
63 } cmsFormatters16;
64
65 typedef struct {
66 cmsUInt32Number Type;
67 cmsUInt32Number Mask;
68 cmsFormatterFloat Frm;
69
70 } cmsFormattersFloat;
71
72
73 #define ANYSPACE COLORSPACE_SH(31)
74 #define ANYCHANNELS CHANNELS_SH(15)
75 #define ANYEXTRA EXTRA_SH(7)
76 #define ANYPLANAR PLANAR_SH(1)
77 #define ANYENDIAN ENDIAN16_SH(1)
78 #define ANYSWAP DOSWAP_SH(1)
79 #define ANYSWAPFIRST SWAPFIRST_SH(1)
80 #define ANYFLAVOR FLAVOR_SH(1)
81
82
83 // Supress waning about info never being used
84
85 #ifdef _MSC_VER
86 #pragma warning(disable : 4100)
87 #endif
88
89 // Unpacking routines (16 bits) ----------------------------------------------------------------------------------------
90
91
92 // Does almost everything but is slow
93 static
UnrollChunkyBytes(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)94 cmsUInt8Number* UnrollChunkyBytes(register _cmsTRANSFORM* info,
95 register cmsUInt16Number wIn[],
96 register cmsUInt8Number* accum,
97 register cmsUInt32Number Stride)
98 {
99 int nChan = T_CHANNELS(info -> InputFormat);
100 int DoSwap = T_DOSWAP(info ->InputFormat);
101 int Reverse = T_FLAVOR(info ->InputFormat);
102 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
103 int Extra = T_EXTRA(info -> InputFormat);
104 int ExtraFirst = DoSwap ^ SwapFirst;
105 cmsUInt16Number v;
106 int i;
107
108 if (ExtraFirst) {
109 accum += Extra;
110 }
111
112 for (i=0; i < nChan; i++) {
113 int index = DoSwap ? (nChan - i - 1) : i;
114
115 v = FROM_8_TO_16(*accum);
116 v = Reverse ? REVERSE_FLAVOR_16(v) : v;
117 wIn[index] = v;
118 accum++;
119 }
120
121 if (!ExtraFirst) {
122 accum += Extra;
123 }
124
125 if (Extra == 0 && SwapFirst) {
126 cmsUInt16Number tmp = wIn[0];
127
128 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
129 wIn[nChan-1] = tmp;
130 }
131
132 return accum;
133
134 cmsUNUSED_PARAMETER(info);
135 cmsUNUSED_PARAMETER(Stride);
136
137 }
138
139 // Extra channels are just ignored because come in the next planes
140 static
UnrollPlanarBytes(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)141 cmsUInt8Number* UnrollPlanarBytes(register _cmsTRANSFORM* info,
142 register cmsUInt16Number wIn[],
143 register cmsUInt8Number* accum,
144 register cmsUInt32Number Stride)
145 {
146 int nChan = T_CHANNELS(info -> InputFormat);
147 int DoSwap = T_DOSWAP(info ->InputFormat);
148 int SwapFirst = T_SWAPFIRST(info ->InputFormat);
149 int Reverse = T_FLAVOR(info ->InputFormat);
150 int i;
151 cmsUInt8Number* Init = accum;
152
153 if (DoSwap ^ SwapFirst) {
154 accum += T_EXTRA(info -> InputFormat) * Stride;
155 }
156
157 for (i=0; i < nChan; i++) {
158
159 int index = DoSwap ? (nChan - i - 1) : i;
160 cmsUInt16Number v = FROM_8_TO_16(*accum);
161
162 wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
163 accum += Stride;
164 }
165
166 return (Init + 1);
167 }
168
169 // Special cases, provided for performance
170 static
Unroll4Bytes(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)171 cmsUInt8Number* Unroll4Bytes(register _cmsTRANSFORM* info,
172 register cmsUInt16Number wIn[],
173 register cmsUInt8Number* accum,
174 register cmsUInt32Number Stride)
175 {
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
180
181 return accum;
182
183 cmsUNUSED_PARAMETER(info);
184 cmsUNUSED_PARAMETER(Stride);
185 }
186
187 static
Unroll4BytesReverse(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)188 cmsUInt8Number* Unroll4BytesReverse(register _cmsTRANSFORM* info,
189 register cmsUInt16Number wIn[],
190 register cmsUInt8Number* accum,
191 register cmsUInt32Number Stride)
192 {
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
197
198 return accum;
199
200 cmsUNUSED_PARAMETER(info);
201 cmsUNUSED_PARAMETER(Stride);
202 }
203
204 static
Unroll4BytesSwapFirst(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)205 cmsUInt8Number* Unroll4BytesSwapFirst(register _cmsTRANSFORM* info,
206 register cmsUInt16Number wIn[],
207 register cmsUInt8Number* accum,
208 register cmsUInt32Number Stride)
209 {
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
214
215 return accum;
216
217 cmsUNUSED_PARAMETER(info);
218 cmsUNUSED_PARAMETER(Stride);
219 }
220
221 // KYMC
222 static
Unroll4BytesSwap(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)223 cmsUInt8Number* Unroll4BytesSwap(register _cmsTRANSFORM* info,
224 register cmsUInt16Number wIn[],
225 register cmsUInt8Number* accum,
226 register cmsUInt32Number Stride)
227 {
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
232
233 return accum;
234
235 cmsUNUSED_PARAMETER(info);
236 cmsUNUSED_PARAMETER(Stride);
237 }
238
239 static
Unroll4BytesSwapSwapFirst(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)240 cmsUInt8Number* Unroll4BytesSwapSwapFirst(register _cmsTRANSFORM* info,
241 register cmsUInt16Number wIn[],
242 register cmsUInt8Number* accum,
243 register cmsUInt32Number Stride)
244 {
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
249
250 return accum;
251
252 cmsUNUSED_PARAMETER(info);
253 cmsUNUSED_PARAMETER(Stride);
254 }
255
256 static
Unroll3Bytes(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)257 cmsUInt8Number* Unroll3Bytes(register _cmsTRANSFORM* info,
258 register cmsUInt16Number wIn[],
259 register cmsUInt8Number* accum,
260 register cmsUInt32Number Stride)
261 {
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
265
266 return accum;
267
268 cmsUNUSED_PARAMETER(info);
269 cmsUNUSED_PARAMETER(Stride);
270 }
271
272 static
Unroll3BytesSkip1Swap(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)273 cmsUInt8Number* Unroll3BytesSkip1Swap(register _cmsTRANSFORM* info,
274 register cmsUInt16Number wIn[],
275 register cmsUInt8Number* accum,
276 register cmsUInt32Number Stride)
277 {
278 accum++; // A
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
282
283 return accum;
284
285 cmsUNUSED_PARAMETER(info);
286 cmsUNUSED_PARAMETER(Stride);
287 }
288
289 static
Unroll3BytesSkip1SwapSwapFirst(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)290 cmsUInt8Number* Unroll3BytesSkip1SwapSwapFirst(register _cmsTRANSFORM* info,
291 register cmsUInt16Number wIn[],
292 register cmsUInt8Number* accum,
293 register cmsUInt32Number Stride)
294 {
295 wIn[2] = FROM_8_TO_16(*accum); accum++; // B
296 wIn[1] = FROM_8_TO_16(*accum); accum++; // G
297 wIn[0] = FROM_8_TO_16(*accum); accum++; // R
298 accum++; // A
299
300 return accum;
301
302 cmsUNUSED_PARAMETER(info);
303 cmsUNUSED_PARAMETER(Stride);
304 }
305
306 static
Unroll3BytesSkip1SwapFirst(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)307 cmsUInt8Number* Unroll3BytesSkip1SwapFirst(register _cmsTRANSFORM* info,
308 register cmsUInt16Number wIn[],
309 register cmsUInt8Number* accum,
310 register cmsUInt32Number Stride)
311 {
312 accum++; // A
313 wIn[0] = FROM_8_TO_16(*accum); accum++; // R
314 wIn[1] = FROM_8_TO_16(*accum); accum++; // G
315 wIn[2] = FROM_8_TO_16(*accum); accum++; // B
316
317 return accum;
318
319 cmsUNUSED_PARAMETER(info);
320 cmsUNUSED_PARAMETER(Stride);
321 }
322
323
324 // BRG
325 static
Unroll3BytesSwap(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)326 cmsUInt8Number* Unroll3BytesSwap(register _cmsTRANSFORM* info,
327 register cmsUInt16Number wIn[],
328 register cmsUInt8Number* accum,
329 register cmsUInt32Number Stride)
330 {
331 wIn[2] = FROM_8_TO_16(*accum); accum++; // B
332 wIn[1] = FROM_8_TO_16(*accum); accum++; // G
333 wIn[0] = FROM_8_TO_16(*accum); accum++; // R
334
335 return accum;
336
337 cmsUNUSED_PARAMETER(info);
338 cmsUNUSED_PARAMETER(Stride);
339 }
340
341 static
UnrollLabV2_8(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)342 cmsUInt8Number* UnrollLabV2_8(register _cmsTRANSFORM* info,
343 register cmsUInt16Number wIn[],
344 register cmsUInt8Number* accum,
345 register cmsUInt32Number Stride)
346 {
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
350
351 return accum;
352
353 cmsUNUSED_PARAMETER(info);
354 cmsUNUSED_PARAMETER(Stride);
355 }
356
357 static
UnrollALabV2_8(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)358 cmsUInt8Number* UnrollALabV2_8(register _cmsTRANSFORM* info,
359 register cmsUInt16Number wIn[],
360 register cmsUInt8Number* accum,
361 register cmsUInt32Number Stride)
362 {
363 accum++; // A
364 wIn[0] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // L
365 wIn[1] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // a
366 wIn[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // b
367
368 return accum;
369
370 cmsUNUSED_PARAMETER(info);
371 cmsUNUSED_PARAMETER(Stride);
372 }
373
374 static
UnrollLabV2_16(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)375 cmsUInt8Number* UnrollLabV2_16(register _cmsTRANSFORM* info,
376 register cmsUInt16Number wIn[],
377 register cmsUInt8Number* accum,
378 register cmsUInt32Number Stride)
379 {
380 wIn[0] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // L
381 wIn[1] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // a
382 wIn[2] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // b
383
384 return accum;
385
386 cmsUNUSED_PARAMETER(info);
387 cmsUNUSED_PARAMETER(Stride);
388 }
389
390 // for duplex
391 static
Unroll2Bytes(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)392 cmsUInt8Number* Unroll2Bytes(register _cmsTRANSFORM* info,
393 register cmsUInt16Number wIn[],
394 register cmsUInt8Number* accum,
395 register cmsUInt32Number Stride)
396 {
397 wIn[0] = FROM_8_TO_16(*accum); accum++; // ch1
398 wIn[1] = FROM_8_TO_16(*accum); accum++; // ch2
399
400 return accum;
401
402 cmsUNUSED_PARAMETER(info);
403 cmsUNUSED_PARAMETER(Stride);
404 }
405
406
407
408
409 // Monochrome duplicates L into RGB for null-transforms
410 static
Unroll1Byte(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)411 cmsUInt8Number* Unroll1Byte(register _cmsTRANSFORM* info,
412 register cmsUInt16Number wIn[],
413 register cmsUInt8Number* accum,
414 register cmsUInt32Number Stride)
415 {
416 wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L
417
418 return accum;
419
420 cmsUNUSED_PARAMETER(info);
421 cmsUNUSED_PARAMETER(Stride);
422 }
423
424
425 static
Unroll1ByteSkip1(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)426 cmsUInt8Number* Unroll1ByteSkip1(register _cmsTRANSFORM* info,
427 register cmsUInt16Number wIn[],
428 register cmsUInt8Number* accum,
429 register cmsUInt32Number Stride)
430 {
431 wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L
432 accum += 1;
433
434 return accum;
435
436 cmsUNUSED_PARAMETER(info);
437 cmsUNUSED_PARAMETER(Stride);
438 }
439
440 static
Unroll1ByteSkip2(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)441 cmsUInt8Number* Unroll1ByteSkip2(register _cmsTRANSFORM* info,
442 register cmsUInt16Number wIn[],
443 register cmsUInt8Number* accum,
444 register cmsUInt32Number Stride)
445 {
446 wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L
447 accum += 2;
448
449 return accum;
450
451 cmsUNUSED_PARAMETER(info);
452 cmsUNUSED_PARAMETER(Stride);
453 }
454
455 static
Unroll1ByteReversed(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)456 cmsUInt8Number* Unroll1ByteReversed(register _cmsTRANSFORM* info,
457 register cmsUInt16Number wIn[],
458 register cmsUInt8Number* accum,
459 register cmsUInt32Number Stride)
460 {
461 wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(FROM_8_TO_16(*accum)); accum++; // L
462
463 return accum;
464
465 cmsUNUSED_PARAMETER(info);
466 cmsUNUSED_PARAMETER(Stride);
467 }
468
469
470 static
UnrollAnyWords(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)471 cmsUInt8Number* UnrollAnyWords(register _cmsTRANSFORM* info,
472 register cmsUInt16Number wIn[],
473 register cmsUInt8Number* accum,
474 register cmsUInt32Number Stride)
475 {
476 int nChan = T_CHANNELS(info -> InputFormat);
477 int SwapEndian = T_ENDIAN16(info -> InputFormat);
478 int DoSwap = T_DOSWAP(info ->InputFormat);
479 int Reverse = T_FLAVOR(info ->InputFormat);
480 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
481 int Extra = T_EXTRA(info -> InputFormat);
482 int ExtraFirst = DoSwap ^ SwapFirst;
483 int i;
484
485 if (ExtraFirst) {
486 accum += Extra * sizeof(cmsUInt16Number);
487 }
488
489 for (i=0; i < nChan; i++) {
490
491 int index = DoSwap ? (nChan - i - 1) : i;
492 cmsUInt16Number v = *(cmsUInt16Number*) accum;
493
494 if (SwapEndian)
495 v = CHANGE_ENDIAN(v);
496
497 wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
498
499 accum += sizeof(cmsUInt16Number);
500 }
501
502 if (!ExtraFirst) {
503 accum += Extra * sizeof(cmsUInt16Number);
504 }
505
506 if (Extra == 0 && SwapFirst) {
507
508 cmsUInt16Number tmp = wIn[0];
509
510 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
511 wIn[nChan-1] = tmp;
512 }
513
514 return accum;
515
516 cmsUNUSED_PARAMETER(Stride);
517 }
518
519 static
UnrollPlanarWords(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)520 cmsUInt8Number* UnrollPlanarWords(register _cmsTRANSFORM* info,
521 register cmsUInt16Number wIn[],
522 register cmsUInt8Number* accum,
523 register cmsUInt32Number Stride)
524 {
525 int nChan = T_CHANNELS(info -> InputFormat);
526 int DoSwap= T_DOSWAP(info ->InputFormat);
527 int Reverse= T_FLAVOR(info ->InputFormat);
528 int SwapEndian = T_ENDIAN16(info -> InputFormat);
529 int i;
530 cmsUInt8Number* Init = accum;
531
532 if (DoSwap) {
533 accum += T_EXTRA(info -> InputFormat) * Stride * sizeof(cmsUInt16Number);
534 }
535
536 for (i=0; i < nChan; i++) {
537
538 int index = DoSwap ? (nChan - i - 1) : i;
539 cmsUInt16Number v = *(cmsUInt16Number*) accum;
540
541 if (SwapEndian)
542 v = CHANGE_ENDIAN(v);
543
544 wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
545
546 accum += Stride * sizeof(cmsUInt16Number);
547 }
548
549 return (Init + sizeof(cmsUInt16Number));
550 }
551
552
553 static
Unroll4Words(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)554 cmsUInt8Number* Unroll4Words(register _cmsTRANSFORM* info,
555 register cmsUInt16Number wIn[],
556 register cmsUInt8Number* accum,
557 register cmsUInt32Number Stride)
558 {
559 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
560 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
561 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
562 wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
563
564 return accum;
565
566 cmsUNUSED_PARAMETER(info);
567 cmsUNUSED_PARAMETER(Stride);
568 }
569
570 static
Unroll4WordsReverse(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)571 cmsUInt8Number* Unroll4WordsReverse(register _cmsTRANSFORM* info,
572 register cmsUInt16Number wIn[],
573 register cmsUInt8Number* accum,
574 register cmsUInt32Number Stride)
575 {
576 wIn[0] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // C
577 wIn[1] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // M
578 wIn[2] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // Y
579 wIn[3] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // K
580
581 return accum;
582
583 cmsUNUSED_PARAMETER(info);
584 cmsUNUSED_PARAMETER(Stride);
585 }
586
587 static
Unroll4WordsSwapFirst(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)588 cmsUInt8Number* Unroll4WordsSwapFirst(register _cmsTRANSFORM* info,
589 register cmsUInt16Number wIn[],
590 register cmsUInt8Number* accum,
591 register cmsUInt32Number Stride)
592 {
593 wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
594 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
595 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
596 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
597
598 return accum;
599
600 cmsUNUSED_PARAMETER(info);
601 cmsUNUSED_PARAMETER(Stride);
602 }
603
604 // KYMC
605 static
Unroll4WordsSwap(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)606 cmsUInt8Number* Unroll4WordsSwap(register _cmsTRANSFORM* info,
607 register cmsUInt16Number wIn[],
608 register cmsUInt8Number* accum,
609 register cmsUInt32Number Stride)
610 {
611 wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
612 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
613 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
614 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
615
616 return accum;
617
618 cmsUNUSED_PARAMETER(info);
619 cmsUNUSED_PARAMETER(Stride);
620 }
621
622 static
Unroll4WordsSwapSwapFirst(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)623 cmsUInt8Number* Unroll4WordsSwapSwapFirst(register _cmsTRANSFORM* info,
624 register cmsUInt16Number wIn[],
625 register cmsUInt8Number* accum,
626 register cmsUInt32Number Stride)
627 {
628 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // K
629 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // Y
630 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // M
631 wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // C
632
633 return accum;
634
635 cmsUNUSED_PARAMETER(info);
636 cmsUNUSED_PARAMETER(Stride);
637 }
638
639 static
Unroll3Words(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)640 cmsUInt8Number* Unroll3Words(register _cmsTRANSFORM* info,
641 register cmsUInt16Number wIn[],
642 register cmsUInt8Number* accum,
643 register cmsUInt32Number Stride)
644 {
645 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C R
646 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M G
647 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y B
648
649 return accum;
650
651 cmsUNUSED_PARAMETER(info);
652 cmsUNUSED_PARAMETER(Stride);
653 }
654
655 static
Unroll3WordsSwap(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)656 cmsUInt8Number* Unroll3WordsSwap(register _cmsTRANSFORM* info,
657 register cmsUInt16Number wIn[],
658 register cmsUInt8Number* accum,
659 register cmsUInt32Number Stride)
660 {
661 wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // C R
662 wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M G
663 wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // Y B
664
665 return accum;
666
667 cmsUNUSED_PARAMETER(info);
668 cmsUNUSED_PARAMETER(Stride);
669 }
670
671 static
Unroll3WordsSkip1Swap(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)672 cmsUInt8Number* Unroll3WordsSkip1Swap(register _cmsTRANSFORM* info,
673 register cmsUInt16Number wIn[],
674 register cmsUInt8Number* accum,
675 register cmsUInt32Number Stride)
676 {
677 accum += 2; // A
678 wIn[2] = *(cmsUInt16Number*) accum; accum += 2; // R
679 wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // G
680 wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // B
681
682 return accum;
683
684 cmsUNUSED_PARAMETER(info);
685 cmsUNUSED_PARAMETER(Stride);
686 }
687
688 static
Unroll3WordsSkip1SwapFirst(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)689 cmsUInt8Number* Unroll3WordsSkip1SwapFirst(register _cmsTRANSFORM* info,
690 register cmsUInt16Number wIn[],
691 register cmsUInt8Number* accum,
692 register cmsUInt32Number Stride)
693 {
694 accum += 2; // A
695 wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // R
696 wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // G
697 wIn[2] = *(cmsUInt16Number*) accum; accum += 2; // B
698
699 return accum;
700
701 cmsUNUSED_PARAMETER(info);
702 cmsUNUSED_PARAMETER(Stride);
703 }
704
705 static
Unroll1Word(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)706 cmsUInt8Number* Unroll1Word(register _cmsTRANSFORM* info,
707 register cmsUInt16Number wIn[],
708 register cmsUInt8Number* accum,
709 register cmsUInt32Number Stride)
710 {
711 wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // L
712
713 return accum;
714
715 cmsUNUSED_PARAMETER(info);
716 cmsUNUSED_PARAMETER(Stride);
717 }
718
719 static
Unroll1WordReversed(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)720 cmsUInt8Number* Unroll1WordReversed(register _cmsTRANSFORM* info,
721 register cmsUInt16Number wIn[],
722 register cmsUInt8Number* accum,
723 register cmsUInt32Number Stride)
724 {
725 wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2;
726
727 return accum;
728
729 cmsUNUSED_PARAMETER(info);
730 cmsUNUSED_PARAMETER(Stride);
731 }
732
733 static
Unroll1WordSkip3(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)734 cmsUInt8Number* Unroll1WordSkip3(register _cmsTRANSFORM* info,
735 register cmsUInt16Number wIn[],
736 register cmsUInt8Number* accum,
737 register cmsUInt32Number Stride)
738 {
739 wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum;
740
741 accum += 8;
742
743 return accum;
744
745 cmsUNUSED_PARAMETER(info);
746 cmsUNUSED_PARAMETER(Stride);
747 }
748
749 static
Unroll2Words(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)750 cmsUInt8Number* Unroll2Words(register _cmsTRANSFORM* info,
751 register cmsUInt16Number wIn[],
752 register cmsUInt8Number* accum,
753 register cmsUInt32Number Stride)
754 {
755 wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // ch1
756 wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // ch2
757
758 return accum;
759
760 cmsUNUSED_PARAMETER(info);
761 cmsUNUSED_PARAMETER(Stride);
762 }
763
764
765 // This is a conversion of Lab double to 16 bits
766 static
UnrollLabDoubleTo16(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)767 cmsUInt8Number* UnrollLabDoubleTo16(register _cmsTRANSFORM* info,
768 register cmsUInt16Number wIn[],
769 register cmsUInt8Number* accum,
770 register cmsUInt32Number Stride)
771 {
772 if (T_PLANAR(info -> InputFormat)) {
773
774 cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
775
776 cmsCIELab Lab;
777
778 Lab.L = Pt[0];
779 Lab.a = Pt[Stride];
780 Lab.b = Pt[Stride*2];
781
782 cmsFloat2LabEncoded(wIn, &Lab);
783 return accum + sizeof(cmsFloat64Number);
784 }
785 else {
786
787 cmsFloat2LabEncoded(wIn, (cmsCIELab*) accum);
788 accum += sizeof(cmsCIELab) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat64Number);
789 return accum;
790 }
791 }
792
793
794 // This is a conversion of Lab float to 16 bits
795 static
UnrollLabFloatTo16(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)796 cmsUInt8Number* UnrollLabFloatTo16(register _cmsTRANSFORM* info,
797 register cmsUInt16Number wIn[],
798 register cmsUInt8Number* accum,
799 register cmsUInt32Number Stride)
800 {
801 cmsCIELab Lab;
802
803 if (T_PLANAR(info -> InputFormat)) {
804
805 cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
806
807
808 Lab.L = Pt[0];
809 Lab.a = Pt[Stride];
810 Lab.b = Pt[Stride*2];
811
812 cmsFloat2LabEncoded(wIn, &Lab);
813 return accum + sizeof(cmsFloat32Number);
814 }
815 else {
816
817 Lab.L = ((cmsFloat32Number*) accum)[0];
818 Lab.a = ((cmsFloat32Number*) accum)[1];
819 Lab.b = ((cmsFloat32Number*) accum)[2];
820
821 cmsFloat2LabEncoded(wIn, &Lab);
822 accum += (3 + T_EXTRA(info ->InputFormat)) * sizeof(cmsFloat32Number);
823 return accum;
824 }
825 }
826
827 // This is a conversion of XYZ double to 16 bits
828 static
UnrollXYZDoubleTo16(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)829 cmsUInt8Number* UnrollXYZDoubleTo16(register _cmsTRANSFORM* info,
830 register cmsUInt16Number wIn[],
831 register cmsUInt8Number* accum,
832 register cmsUInt32Number Stride)
833 {
834 if (T_PLANAR(info -> InputFormat)) {
835
836 cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
837 cmsCIEXYZ XYZ;
838
839 XYZ.X = Pt[0];
840 XYZ.Y = Pt[Stride];
841 XYZ.Z = Pt[Stride*2];
842 cmsFloat2XYZEncoded(wIn, &XYZ);
843
844 return accum + sizeof(cmsFloat64Number);
845
846 }
847
848 else {
849 cmsFloat2XYZEncoded(wIn, (cmsCIEXYZ*) accum);
850 accum += sizeof(cmsCIEXYZ) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat64Number);
851
852 return accum;
853 }
854 }
855
856 // This is a conversion of XYZ float to 16 bits
857 static
UnrollXYZFloatTo16(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)858 cmsUInt8Number* UnrollXYZFloatTo16(register _cmsTRANSFORM* info,
859 register cmsUInt16Number wIn[],
860 register cmsUInt8Number* accum,
861 register cmsUInt32Number Stride)
862 {
863 if (T_PLANAR(info -> InputFormat)) {
864
865 cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
866 cmsCIEXYZ XYZ;
867
868 XYZ.X = Pt[0];
869 XYZ.Y = Pt[Stride];
870 XYZ.Z = Pt[Stride*2];
871 cmsFloat2XYZEncoded(wIn, &XYZ);
872
873 return accum + sizeof(cmsFloat32Number);
874
875 }
876
877 else {
878 cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
879 cmsCIEXYZ XYZ;
880
881 XYZ.X = Pt[0];
882 XYZ.Y = Pt[1];
883 XYZ.Z = Pt[2];
884 cmsFloat2XYZEncoded(wIn, &XYZ);
885
886 accum += 3 * sizeof(cmsFloat32Number) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat32Number);
887
888 return accum;
889 }
890 }
891
892 // Check if space is marked as ink
IsInkSpace(cmsUInt32Number Type)893 cmsINLINE cmsBool IsInkSpace(cmsUInt32Number Type)
894 {
895 switch (T_COLORSPACE(Type)) {
896
897 case PT_CMY:
898 case PT_CMYK:
899 case PT_MCH5:
900 case PT_MCH6:
901 case PT_MCH7:
902 case PT_MCH8:
903 case PT_MCH9:
904 case PT_MCH10:
905 case PT_MCH11:
906 case PT_MCH12:
907 case PT_MCH13:
908 case PT_MCH14:
909 case PT_MCH15: return TRUE;
910
911 default: return FALSE;
912 }
913 }
914
915 // Inks does come in percentage, remaining cases are between 0..1.0, again to 16 bits
916 static
UnrollDoubleTo16(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)917 cmsUInt8Number* UnrollDoubleTo16(register _cmsTRANSFORM* info,
918 register cmsUInt16Number wIn[],
919 register cmsUInt8Number* accum,
920 register cmsUInt32Number Stride)
921 {
922
923 int nChan = T_CHANNELS(info -> InputFormat);
924 int DoSwap = T_DOSWAP(info ->InputFormat);
925 int Reverse = T_FLAVOR(info ->InputFormat);
926 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
927 int Extra = T_EXTRA(info -> InputFormat);
928 int ExtraFirst = DoSwap ^ SwapFirst;
929 int Planar = T_PLANAR(info -> InputFormat);
930 cmsFloat64Number v;
931 cmsUInt16Number vi;
932 int i, start = 0;
933 cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
934
935
936 if (ExtraFirst)
937 start = Extra;
938
939 for (i=0; i < nChan; i++) {
940
941 int index = DoSwap ? (nChan - i - 1) : i;
942
943 if (Planar)
944 v = (cmsFloat32Number) ((cmsFloat64Number*) accum)[(i + start) * Stride];
945 else
946 v = (cmsFloat32Number) ((cmsFloat64Number*) accum)[i + start];
947
948 vi = _cmsQuickSaturateWord(v * maximum);
949
950 if (Reverse)
951 vi = REVERSE_FLAVOR_16(vi);
952
953 wIn[index] = vi;
954 }
955
956
957 if (Extra == 0 && SwapFirst) {
958 cmsUInt16Number tmp = wIn[0];
959
960 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
961 wIn[nChan-1] = tmp;
962 }
963
964 if (T_PLANAR(info -> InputFormat))
965 return accum + sizeof(cmsFloat64Number);
966 else
967 return accum + (nChan + Extra) * sizeof(cmsFloat64Number);
968 }
969
970
971
972 static
UnrollFloatTo16(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)973 cmsUInt8Number* UnrollFloatTo16(register _cmsTRANSFORM* info,
974 register cmsUInt16Number wIn[],
975 register cmsUInt8Number* accum,
976 register cmsUInt32Number Stride)
977 {
978
979 int nChan = T_CHANNELS(info -> InputFormat);
980 int DoSwap = T_DOSWAP(info ->InputFormat);
981 int Reverse = T_FLAVOR(info ->InputFormat);
982 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
983 int Extra = T_EXTRA(info -> InputFormat);
984 int ExtraFirst = DoSwap ^ SwapFirst;
985 int Planar = T_PLANAR(info -> InputFormat);
986 cmsFloat32Number v;
987 cmsUInt16Number vi;
988 int i, start = 0;
989 cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
990
991
992 if (ExtraFirst)
993 start = Extra;
994
995 for (i=0; i < nChan; i++) {
996
997 int index = DoSwap ? (nChan - i - 1) : i;
998
999 if (Planar)
1000 v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[(i + start) * Stride];
1001 else
1002 v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[i + start];
1003
1004 vi = _cmsQuickSaturateWord(v * maximum);
1005
1006 if (Reverse)
1007 vi = REVERSE_FLAVOR_16(vi);
1008
1009 wIn[index] = vi;
1010 }
1011
1012
1013 if (Extra == 0 && SwapFirst) {
1014 cmsUInt16Number tmp = wIn[0];
1015
1016 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
1017 wIn[nChan-1] = tmp;
1018 }
1019
1020 if (T_PLANAR(info -> InputFormat))
1021 return accum + sizeof(cmsFloat32Number);
1022 else
1023 return accum + (nChan + Extra) * sizeof(cmsFloat32Number);
1024 }
1025
1026
1027
1028
1029 // For 1 channel, we need to duplicate data (it comes in 0..1.0 range)
1030 static
UnrollDouble1Chan(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)1031 cmsUInt8Number* UnrollDouble1Chan(register _cmsTRANSFORM* info,
1032 register cmsUInt16Number wIn[],
1033 register cmsUInt8Number* accum,
1034 register cmsUInt32Number Stride)
1035 {
1036 cmsFloat64Number* Inks = (cmsFloat64Number*) accum;
1037
1038 wIn[0] = wIn[1] = wIn[2] = _cmsQuickSaturateWord(Inks[0] * 65535.0);
1039
1040 return accum + sizeof(cmsFloat64Number);
1041
1042 cmsUNUSED_PARAMETER(info);
1043 cmsUNUSED_PARAMETER(Stride);
1044 }
1045
1046 //-------------------------------------------------------------------------------------------------------------------
1047
1048 // For anything going from cmsFloat32Number
1049 static
UnrollFloatsToFloat(_cmsTRANSFORM * info,cmsFloat32Number wIn[],cmsUInt8Number * accum,cmsUInt32Number Stride)1050 cmsUInt8Number* UnrollFloatsToFloat(_cmsTRANSFORM* info,
1051 cmsFloat32Number wIn[],
1052 cmsUInt8Number* accum,
1053 cmsUInt32Number Stride)
1054 {
1055
1056 int nChan = T_CHANNELS(info -> InputFormat);
1057 int DoSwap = T_DOSWAP(info ->InputFormat);
1058 int Reverse = T_FLAVOR(info ->InputFormat);
1059 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
1060 int Extra = T_EXTRA(info -> InputFormat);
1061 int ExtraFirst = DoSwap ^ SwapFirst;
1062 int Planar = T_PLANAR(info -> InputFormat);
1063 cmsFloat32Number v;
1064 int i, start = 0;
1065 cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 100.0F : 1.0F;
1066
1067
1068 if (ExtraFirst)
1069 start = Extra;
1070
1071 for (i=0; i < nChan; i++) {
1072
1073 int index = DoSwap ? (nChan - i - 1) : i;
1074
1075 if (Planar)
1076 v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[(i + start) * Stride];
1077 else
1078 v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[i + start];
1079
1080 v /= maximum;
1081
1082 wIn[index] = Reverse ? 1 - v : v;
1083 }
1084
1085
1086 if (Extra == 0 && SwapFirst) {
1087 cmsFloat32Number tmp = wIn[0];
1088
1089 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number));
1090 wIn[nChan-1] = tmp;
1091 }
1092
1093 if (T_PLANAR(info -> InputFormat))
1094 return accum + sizeof(cmsFloat32Number);
1095 else
1096 return accum + (nChan + Extra) * sizeof(cmsFloat32Number);
1097 }
1098
1099 // For anything going from double
1100
1101 static
UnrollDoublesToFloat(_cmsTRANSFORM * info,cmsFloat32Number wIn[],cmsUInt8Number * accum,cmsUInt32Number Stride)1102 cmsUInt8Number* UnrollDoublesToFloat(_cmsTRANSFORM* info,
1103 cmsFloat32Number wIn[],
1104 cmsUInt8Number* accum,
1105 cmsUInt32Number Stride)
1106 {
1107
1108 int nChan = T_CHANNELS(info -> InputFormat);
1109 int DoSwap = T_DOSWAP(info ->InputFormat);
1110 int Reverse = T_FLAVOR(info ->InputFormat);
1111 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
1112 int Extra = T_EXTRA(info -> InputFormat);
1113 int ExtraFirst = DoSwap ^ SwapFirst;
1114 int Planar = T_PLANAR(info -> InputFormat);
1115 cmsFloat64Number v;
1116 int i, start = 0;
1117 cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 100.0 : 1.0;
1118
1119
1120 if (ExtraFirst)
1121 start = Extra;
1122
1123 for (i=0; i < nChan; i++) {
1124
1125 int index = DoSwap ? (nChan - i - 1) : i;
1126
1127 if (Planar)
1128 v = (cmsFloat64Number) ((cmsFloat64Number*) accum)[(i + start) * Stride];
1129 else
1130 v = (cmsFloat64Number) ((cmsFloat64Number*) accum)[i + start];
1131
1132 v /= maximum;
1133
1134 wIn[index] = (cmsFloat32Number) (Reverse ? 1.0 - v : v);
1135 }
1136
1137
1138 if (Extra == 0 && SwapFirst) {
1139 cmsFloat32Number tmp = wIn[0];
1140
1141 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number));
1142 wIn[nChan-1] = tmp;
1143 }
1144
1145 if (T_PLANAR(info -> InputFormat))
1146 return accum + sizeof(cmsFloat64Number);
1147 else
1148 return accum + (nChan + Extra) * sizeof(cmsFloat64Number);
1149 }
1150
1151
1152
1153 // From Lab double to cmsFloat32Number
1154 static
UnrollLabDoubleToFloat(_cmsTRANSFORM * info,cmsFloat32Number wIn[],cmsUInt8Number * accum,cmsUInt32Number Stride)1155 cmsUInt8Number* UnrollLabDoubleToFloat(_cmsTRANSFORM* info,
1156 cmsFloat32Number wIn[],
1157 cmsUInt8Number* accum,
1158 cmsUInt32Number Stride)
1159 {
1160 cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
1161
1162 if (T_PLANAR(info -> InputFormat)) {
1163
1164 wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
1165 wIn[1] = (cmsFloat32Number) ((Pt[Stride] + 128) / 255.0); // form -128..+127 to 0..1
1166 wIn[2] = (cmsFloat32Number) ((Pt[Stride*2] + 128) / 255.0);
1167
1168 return accum + sizeof(cmsFloat64Number);
1169 }
1170 else {
1171
1172 wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
1173 wIn[1] = (cmsFloat32Number) ((Pt[1] + 128) / 255.0); // form -128..+127 to 0..1
1174 wIn[2] = (cmsFloat32Number) ((Pt[2] + 128) / 255.0);
1175
1176 accum += sizeof(cmsFloat64Number)*(3 + T_EXTRA(info ->InputFormat));
1177 return accum;
1178 }
1179 }
1180
1181 // From Lab double to cmsFloat32Number
1182 static
UnrollLabFloatToFloat(_cmsTRANSFORM * info,cmsFloat32Number wIn[],cmsUInt8Number * accum,cmsUInt32Number Stride)1183 cmsUInt8Number* UnrollLabFloatToFloat(_cmsTRANSFORM* info,
1184 cmsFloat32Number wIn[],
1185 cmsUInt8Number* accum,
1186 cmsUInt32Number Stride)
1187 {
1188 cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
1189
1190 if (T_PLANAR(info -> InputFormat)) {
1191
1192 wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
1193 wIn[1] = (cmsFloat32Number) ((Pt[Stride] + 128) / 255.0); // form -128..+127 to 0..1
1194 wIn[2] = (cmsFloat32Number) ((Pt[Stride*2] + 128) / 255.0);
1195
1196 return accum + sizeof(cmsFloat32Number);
1197 }
1198 else {
1199
1200 wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
1201 wIn[1] = (cmsFloat32Number) ((Pt[1] + 128) / 255.0); // form -128..+127 to 0..1
1202 wIn[2] = (cmsFloat32Number) ((Pt[2] + 128) / 255.0);
1203
1204 accum += sizeof(cmsFloat32Number)*(3 + T_EXTRA(info ->InputFormat));
1205 return accum;
1206 }
1207 }
1208
1209
1210
1211 // 1.15 fixed point, that means maximum value is MAX_ENCODEABLE_XYZ (0xFFFF)
1212 static
UnrollXYZDoubleToFloat(_cmsTRANSFORM * info,cmsFloat32Number wIn[],cmsUInt8Number * accum,cmsUInt32Number Stride)1213 cmsUInt8Number* UnrollXYZDoubleToFloat(_cmsTRANSFORM* info,
1214 cmsFloat32Number wIn[],
1215 cmsUInt8Number* accum,
1216 cmsUInt32Number Stride)
1217 {
1218 cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
1219
1220 if (T_PLANAR(info -> InputFormat)) {
1221
1222 wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
1223 wIn[1] = (cmsFloat32Number) (Pt[Stride] / MAX_ENCODEABLE_XYZ);
1224 wIn[2] = (cmsFloat32Number) (Pt[Stride*2] / MAX_ENCODEABLE_XYZ);
1225
1226 return accum + sizeof(cmsFloat64Number);
1227 }
1228 else {
1229
1230 wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
1231 wIn[1] = (cmsFloat32Number) (Pt[1] / MAX_ENCODEABLE_XYZ);
1232 wIn[2] = (cmsFloat32Number) (Pt[2] / MAX_ENCODEABLE_XYZ);
1233
1234 accum += sizeof(cmsFloat64Number)*(3 + T_EXTRA(info ->InputFormat));
1235 return accum;
1236 }
1237 }
1238
1239 static
UnrollXYZFloatToFloat(_cmsTRANSFORM * info,cmsFloat32Number wIn[],cmsUInt8Number * accum,cmsUInt32Number Stride)1240 cmsUInt8Number* UnrollXYZFloatToFloat(_cmsTRANSFORM* info,
1241 cmsFloat32Number wIn[],
1242 cmsUInt8Number* accum,
1243 cmsUInt32Number Stride)
1244 {
1245 cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
1246
1247 if (T_PLANAR(info -> InputFormat)) {
1248
1249 wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
1250 wIn[1] = (cmsFloat32Number) (Pt[Stride] / MAX_ENCODEABLE_XYZ);
1251 wIn[2] = (cmsFloat32Number) (Pt[Stride*2] / MAX_ENCODEABLE_XYZ);
1252
1253 return accum + sizeof(cmsFloat32Number);
1254 }
1255 else {
1256
1257 wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
1258 wIn[1] = (cmsFloat32Number) (Pt[1] / MAX_ENCODEABLE_XYZ);
1259 wIn[2] = (cmsFloat32Number) (Pt[2] / MAX_ENCODEABLE_XYZ);
1260
1261 accum += sizeof(cmsFloat32Number)*(3 + T_EXTRA(info ->InputFormat));
1262 return accum;
1263 }
1264 }
1265
1266
1267
1268 // Packing routines -----------------------------------------------------------------------------------------------------------
1269
1270
1271 // Generic chunky for byte
1272
1273 static
PackAnyBytes(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1274 cmsUInt8Number* PackAnyBytes(register _cmsTRANSFORM* info,
1275 register cmsUInt16Number wOut[],
1276 register cmsUInt8Number* output,
1277 register cmsUInt32Number Stride)
1278 {
1279 int nChan = T_CHANNELS(info -> OutputFormat);
1280 int DoSwap = T_DOSWAP(info ->OutputFormat);
1281 int Reverse = T_FLAVOR(info ->OutputFormat);
1282 int Extra = T_EXTRA(info -> OutputFormat);
1283 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
1284 int ExtraFirst = DoSwap ^ SwapFirst;
1285 cmsUInt8Number* swap1;
1286 cmsUInt8Number v = 0;
1287 int i;
1288
1289 swap1 = output;
1290
1291 if (ExtraFirst) {
1292 output += Extra;
1293 }
1294
1295 for (i=0; i < nChan; i++) {
1296
1297 int index = DoSwap ? (nChan - i - 1) : i;
1298
1299 v = FROM_16_TO_8(wOut[index]);
1300
1301 if (Reverse)
1302 v = REVERSE_FLAVOR_8(v);
1303
1304 *output++ = v;
1305 }
1306
1307 if (!ExtraFirst) {
1308 output += Extra;
1309 }
1310
1311 if (Extra == 0 && SwapFirst) {
1312
1313 memmove(swap1 + 1, swap1, nChan-1);
1314 *swap1 = v;
1315 }
1316
1317
1318 return output;
1319
1320 cmsUNUSED_PARAMETER(Stride);
1321 }
1322
1323
1324
1325 static
PackAnyWords(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1326 cmsUInt8Number* PackAnyWords(register _cmsTRANSFORM* info,
1327 register cmsUInt16Number wOut[],
1328 register cmsUInt8Number* output,
1329 register cmsUInt32Number Stride)
1330 {
1331 int nChan = T_CHANNELS(info -> OutputFormat);
1332 int SwapEndian = T_ENDIAN16(info -> InputFormat);
1333 int DoSwap = T_DOSWAP(info ->OutputFormat);
1334 int Reverse = T_FLAVOR(info ->OutputFormat);
1335 int Extra = T_EXTRA(info -> OutputFormat);
1336 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
1337 int ExtraFirst = DoSwap ^ SwapFirst;
1338 cmsUInt16Number* swap1;
1339 cmsUInt16Number v = 0;
1340 int i;
1341
1342 swap1 = (cmsUInt16Number*) output;
1343
1344 if (ExtraFirst) {
1345 output += Extra * sizeof(cmsUInt16Number);
1346 }
1347
1348 for (i=0; i < nChan; i++) {
1349
1350 int index = DoSwap ? (nChan - i - 1) : i;
1351
1352 v = wOut[index];
1353
1354 if (SwapEndian)
1355 v = CHANGE_ENDIAN(v);
1356
1357 if (Reverse)
1358 v = REVERSE_FLAVOR_16(v);
1359
1360 *(cmsUInt16Number*) output = v;
1361
1362 output += sizeof(cmsUInt16Number);
1363 }
1364
1365 if (!ExtraFirst) {
1366 output += Extra * sizeof(cmsUInt16Number);
1367 }
1368
1369 if (Extra == 0 && SwapFirst) {
1370
1371 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number));
1372 *swap1 = v;
1373 }
1374
1375
1376 return output;
1377
1378 cmsUNUSED_PARAMETER(Stride);
1379 }
1380
1381
1382 static
PackPlanarBytes(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1383 cmsUInt8Number* PackPlanarBytes(register _cmsTRANSFORM* info,
1384 register cmsUInt16Number wOut[],
1385 register cmsUInt8Number* output,
1386 register cmsUInt32Number Stride)
1387 {
1388 int nChan = T_CHANNELS(info -> OutputFormat);
1389 int DoSwap = T_DOSWAP(info ->OutputFormat);
1390 int SwapFirst = T_SWAPFIRST(info ->OutputFormat);
1391 int Reverse = T_FLAVOR(info ->OutputFormat);
1392 int i;
1393 cmsUInt8Number* Init = output;
1394
1395
1396 if (DoSwap ^ SwapFirst) {
1397 output += T_EXTRA(info -> OutputFormat) * Stride;
1398 }
1399
1400
1401 for (i=0; i < nChan; i++) {
1402
1403 int index = DoSwap ? (nChan - i - 1) : i;
1404 cmsUInt8Number v = FROM_16_TO_8(wOut[index]);
1405
1406 *(cmsUInt8Number*) output = (cmsUInt8Number) (Reverse ? REVERSE_FLAVOR_8(v) : v);
1407 output += Stride;
1408 }
1409
1410 return (Init + 1);
1411
1412 cmsUNUSED_PARAMETER(Stride);
1413 }
1414
1415
1416 static
PackPlanarWords(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1417 cmsUInt8Number* PackPlanarWords(register _cmsTRANSFORM* info,
1418 register cmsUInt16Number wOut[],
1419 register cmsUInt8Number* output,
1420 register cmsUInt32Number Stride)
1421 {
1422 int nChan = T_CHANNELS(info -> OutputFormat);
1423 int DoSwap = T_DOSWAP(info ->OutputFormat);
1424 int Reverse= T_FLAVOR(info ->OutputFormat);
1425 int SwapEndian = T_ENDIAN16(info -> OutputFormat);
1426 int i;
1427 cmsUInt8Number* Init = output;
1428 cmsUInt16Number v;
1429
1430 if (DoSwap) {
1431 output += T_EXTRA(info -> OutputFormat) * Stride * sizeof(cmsUInt16Number);
1432 }
1433
1434 for (i=0; i < nChan; i++) {
1435
1436 int index = DoSwap ? (nChan - i - 1) : i;
1437
1438 v = wOut[index];
1439
1440 if (SwapEndian)
1441 v = CHANGE_ENDIAN(v);
1442
1443 if (Reverse)
1444 v = REVERSE_FLAVOR_16(v);
1445
1446 *(cmsUInt16Number*) output = v;
1447 output += (Stride * sizeof(cmsUInt16Number));
1448 }
1449
1450 return (Init + sizeof(cmsUInt16Number));
1451 }
1452
1453 // CMYKcm (unrolled for speed)
1454
1455 static
Pack6Bytes(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1456 cmsUInt8Number* Pack6Bytes(register _cmsTRANSFORM* info,
1457 register cmsUInt16Number wOut[],
1458 register cmsUInt8Number* output,
1459 register cmsUInt32Number Stride)
1460 {
1461 *output++ = FROM_16_TO_8(wOut[0]);
1462 *output++ = FROM_16_TO_8(wOut[1]);
1463 *output++ = FROM_16_TO_8(wOut[2]);
1464 *output++ = FROM_16_TO_8(wOut[3]);
1465 *output++ = FROM_16_TO_8(wOut[4]);
1466 *output++ = FROM_16_TO_8(wOut[5]);
1467
1468 return output;
1469
1470 cmsUNUSED_PARAMETER(info);
1471 cmsUNUSED_PARAMETER(Stride);
1472 }
1473
1474 // KCMYcm
1475
1476 static
Pack6BytesSwap(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1477 cmsUInt8Number* Pack6BytesSwap(register _cmsTRANSFORM* info,
1478 register cmsUInt16Number wOut[],
1479 register cmsUInt8Number* output,
1480 register cmsUInt32Number Stride)
1481 {
1482 *output++ = FROM_16_TO_8(wOut[5]);
1483 *output++ = FROM_16_TO_8(wOut[4]);
1484 *output++ = FROM_16_TO_8(wOut[3]);
1485 *output++ = FROM_16_TO_8(wOut[2]);
1486 *output++ = FROM_16_TO_8(wOut[1]);
1487 *output++ = FROM_16_TO_8(wOut[0]);
1488
1489 return output;
1490
1491 cmsUNUSED_PARAMETER(info);
1492 cmsUNUSED_PARAMETER(Stride);
1493 }
1494
1495 // CMYKcm
1496 static
Pack6Words(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1497 cmsUInt8Number* Pack6Words(register _cmsTRANSFORM* info,
1498 register cmsUInt16Number wOut[],
1499 register cmsUInt8Number* output,
1500 register cmsUInt32Number Stride)
1501 {
1502 *(cmsUInt16Number*) output = wOut[0];
1503 output+= 2;
1504 *(cmsUInt16Number*) output = wOut[1];
1505 output+= 2;
1506 *(cmsUInt16Number*) output = wOut[2];
1507 output+= 2;
1508 *(cmsUInt16Number*) output = wOut[3];
1509 output+= 2;
1510 *(cmsUInt16Number*) output = wOut[4];
1511 output+= 2;
1512 *(cmsUInt16Number*) output = wOut[5];
1513 output+= 2;
1514
1515 return output;
1516
1517 cmsUNUSED_PARAMETER(info);
1518 cmsUNUSED_PARAMETER(Stride);
1519 }
1520
1521 // KCMYcm
1522 static
Pack6WordsSwap(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1523 cmsUInt8Number* Pack6WordsSwap(register _cmsTRANSFORM* info,
1524 register cmsUInt16Number wOut[],
1525 register cmsUInt8Number* output,
1526 register cmsUInt32Number Stride)
1527 {
1528 *(cmsUInt16Number*) output = wOut[5];
1529 output+= 2;
1530 *(cmsUInt16Number*) output = wOut[4];
1531 output+= 2;
1532 *(cmsUInt16Number*) output = wOut[3];
1533 output+= 2;
1534 *(cmsUInt16Number*) output = wOut[2];
1535 output+= 2;
1536 *(cmsUInt16Number*) output = wOut[1];
1537 output+= 2;
1538 *(cmsUInt16Number*) output = wOut[0];
1539 output+= 2;
1540
1541 return output;
1542
1543 cmsUNUSED_PARAMETER(info);
1544 cmsUNUSED_PARAMETER(Stride);
1545 }
1546
1547
1548 static
Pack4Bytes(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1549 cmsUInt8Number* Pack4Bytes(register _cmsTRANSFORM* info,
1550 register cmsUInt16Number wOut[],
1551 register cmsUInt8Number* output,
1552 register cmsUInt32Number Stride)
1553 {
1554 *output++ = FROM_16_TO_8(wOut[0]);
1555 *output++ = FROM_16_TO_8(wOut[1]);
1556 *output++ = FROM_16_TO_8(wOut[2]);
1557 *output++ = FROM_16_TO_8(wOut[3]);
1558
1559 return output;
1560
1561 cmsUNUSED_PARAMETER(info);
1562 cmsUNUSED_PARAMETER(Stride);
1563 }
1564
1565 static
Pack4BytesReverse(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1566 cmsUInt8Number* Pack4BytesReverse(register _cmsTRANSFORM* info,
1567 register cmsUInt16Number wOut[],
1568 register cmsUInt8Number* output,
1569 register cmsUInt32Number Stride)
1570 {
1571 *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[0]));
1572 *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[1]));
1573 *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[2]));
1574 *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[3]));
1575
1576 return output;
1577
1578 cmsUNUSED_PARAMETER(info);
1579 cmsUNUSED_PARAMETER(Stride);
1580 }
1581
1582
1583 static
Pack4BytesSwapFirst(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1584 cmsUInt8Number* Pack4BytesSwapFirst(register _cmsTRANSFORM* info,
1585 register cmsUInt16Number wOut[],
1586 register cmsUInt8Number* output,
1587 register cmsUInt32Number Stride)
1588 {
1589 *output++ = FROM_16_TO_8(wOut[3]);
1590 *output++ = FROM_16_TO_8(wOut[0]);
1591 *output++ = FROM_16_TO_8(wOut[1]);
1592 *output++ = FROM_16_TO_8(wOut[2]);
1593
1594 return output;
1595
1596 cmsUNUSED_PARAMETER(info);
1597 cmsUNUSED_PARAMETER(Stride);
1598 }
1599
1600 // ABGR
1601 static
Pack4BytesSwap(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1602 cmsUInt8Number* Pack4BytesSwap(register _cmsTRANSFORM* info,
1603 register cmsUInt16Number wOut[],
1604 register cmsUInt8Number* output,
1605 register cmsUInt32Number Stride)
1606 {
1607 *output++ = FROM_16_TO_8(wOut[3]);
1608 *output++ = FROM_16_TO_8(wOut[2]);
1609 *output++ = FROM_16_TO_8(wOut[1]);
1610 *output++ = FROM_16_TO_8(wOut[0]);
1611
1612 return output;
1613
1614 cmsUNUSED_PARAMETER(info);
1615 cmsUNUSED_PARAMETER(Stride);
1616 }
1617
1618 static
Pack4BytesSwapSwapFirst(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1619 cmsUInt8Number* Pack4BytesSwapSwapFirst(register _cmsTRANSFORM* info,
1620 register cmsUInt16Number wOut[],
1621 register cmsUInt8Number* output,
1622 register cmsUInt32Number Stride)
1623 {
1624 *output++ = FROM_16_TO_8(wOut[2]);
1625 *output++ = FROM_16_TO_8(wOut[1]);
1626 *output++ = FROM_16_TO_8(wOut[0]);
1627 *output++ = FROM_16_TO_8(wOut[3]);
1628
1629 return output;
1630
1631 cmsUNUSED_PARAMETER(info);
1632 cmsUNUSED_PARAMETER(Stride);
1633 }
1634
1635 static
Pack4Words(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1636 cmsUInt8Number* Pack4Words(register _cmsTRANSFORM* info,
1637 register cmsUInt16Number wOut[],
1638 register cmsUInt8Number* output,
1639 register cmsUInt32Number Stride)
1640 {
1641 *(cmsUInt16Number*) output = wOut[0];
1642 output+= 2;
1643 *(cmsUInt16Number*) output = wOut[1];
1644 output+= 2;
1645 *(cmsUInt16Number*) output = wOut[2];
1646 output+= 2;
1647 *(cmsUInt16Number*) output = wOut[3];
1648 output+= 2;
1649
1650 return output;
1651
1652 cmsUNUSED_PARAMETER(info);
1653 cmsUNUSED_PARAMETER(Stride);
1654 }
1655
1656 static
Pack4WordsReverse(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1657 cmsUInt8Number* Pack4WordsReverse(register _cmsTRANSFORM* info,
1658 register cmsUInt16Number wOut[],
1659 register cmsUInt8Number* output,
1660 register cmsUInt32Number Stride)
1661 {
1662 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[0]);
1663 output+= 2;
1664 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[1]);
1665 output+= 2;
1666 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[2]);
1667 output+= 2;
1668 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[3]);
1669 output+= 2;
1670
1671 return output;
1672
1673 cmsUNUSED_PARAMETER(info);
1674 cmsUNUSED_PARAMETER(Stride);
1675 }
1676
1677 // ABGR
1678 static
Pack4WordsSwap(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1679 cmsUInt8Number* Pack4WordsSwap(register _cmsTRANSFORM* info,
1680 register cmsUInt16Number wOut[],
1681 register cmsUInt8Number* output,
1682 register cmsUInt32Number Stride)
1683 {
1684 *(cmsUInt16Number*) output = wOut[3];
1685 output+= 2;
1686 *(cmsUInt16Number*) output = wOut[2];
1687 output+= 2;
1688 *(cmsUInt16Number*) output = wOut[1];
1689 output+= 2;
1690 *(cmsUInt16Number*) output = wOut[0];
1691 output+= 2;
1692
1693 return output;
1694
1695 cmsUNUSED_PARAMETER(info);
1696 cmsUNUSED_PARAMETER(Stride);
1697 }
1698
1699 // CMYK
1700 static
Pack4WordsBigEndian(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1701 cmsUInt8Number* Pack4WordsBigEndian(register _cmsTRANSFORM* info,
1702 register cmsUInt16Number wOut[],
1703 register cmsUInt8Number* output,
1704 register cmsUInt32Number Stride)
1705 {
1706 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
1707 output+= 2;
1708 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[1]);
1709 output+= 2;
1710 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[2]);
1711 output+= 2;
1712 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[3]);
1713 output+= 2;
1714
1715 return output;
1716
1717 cmsUNUSED_PARAMETER(info);
1718 cmsUNUSED_PARAMETER(Stride);
1719 }
1720
1721
1722 static
PackLabV2_8(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1723 cmsUInt8Number* PackLabV2_8(register _cmsTRANSFORM* info,
1724 register cmsUInt16Number wOut[],
1725 register cmsUInt8Number* output,
1726 register cmsUInt32Number Stride)
1727 {
1728 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[0]));
1729 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[1]));
1730 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[2]));
1731
1732 return output;
1733
1734 cmsUNUSED_PARAMETER(info);
1735 cmsUNUSED_PARAMETER(Stride);
1736 }
1737
1738 static
PackALabV2_8(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1739 cmsUInt8Number* PackALabV2_8(register _cmsTRANSFORM* info,
1740 register cmsUInt16Number wOut[],
1741 register cmsUInt8Number* output,
1742 register cmsUInt32Number Stride)
1743 {
1744 output++;
1745 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[0]));
1746 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[1]));
1747 *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[2]));
1748
1749 return output;
1750
1751 cmsUNUSED_PARAMETER(info);
1752 cmsUNUSED_PARAMETER(Stride);
1753 }
1754
1755 static
PackLabV2_16(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1756 cmsUInt8Number* PackLabV2_16(register _cmsTRANSFORM* info,
1757 register cmsUInt16Number wOut[],
1758 register cmsUInt8Number* output,
1759 register cmsUInt32Number Stride)
1760 {
1761 *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[0]);
1762 output += 2;
1763 *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[1]);
1764 output += 2;
1765 *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[2]);
1766 output += 2;
1767
1768 return output;
1769
1770 cmsUNUSED_PARAMETER(info);
1771 cmsUNUSED_PARAMETER(Stride);
1772 }
1773
1774 static
Pack3Bytes(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1775 cmsUInt8Number* Pack3Bytes(register _cmsTRANSFORM* info,
1776 register cmsUInt16Number wOut[],
1777 register cmsUInt8Number* output,
1778 register cmsUInt32Number Stride)
1779 {
1780 *output++ = FROM_16_TO_8(wOut[0]);
1781 *output++ = FROM_16_TO_8(wOut[1]);
1782 *output++ = FROM_16_TO_8(wOut[2]);
1783
1784 return output;
1785
1786 cmsUNUSED_PARAMETER(info);
1787 cmsUNUSED_PARAMETER(Stride);
1788 }
1789
1790 static
Pack3BytesOptimized(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1791 cmsUInt8Number* Pack3BytesOptimized(register _cmsTRANSFORM* info,
1792 register cmsUInt16Number wOut[],
1793 register cmsUInt8Number* output,
1794 register cmsUInt32Number Stride)
1795 {
1796 *output++ = (wOut[0] & 0xFF);
1797 *output++ = (wOut[1] & 0xFF);
1798 *output++ = (wOut[2] & 0xFF);
1799
1800 return output;
1801
1802 cmsUNUSED_PARAMETER(info);
1803 cmsUNUSED_PARAMETER(Stride);
1804 }
1805
1806 static
Pack3BytesSwap(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1807 cmsUInt8Number* Pack3BytesSwap(register _cmsTRANSFORM* info,
1808 register cmsUInt16Number wOut[],
1809 register cmsUInt8Number* output,
1810 register cmsUInt32Number Stride)
1811 {
1812 *output++ = FROM_16_TO_8(wOut[2]);
1813 *output++ = FROM_16_TO_8(wOut[1]);
1814 *output++ = FROM_16_TO_8(wOut[0]);
1815
1816 return output;
1817
1818 cmsUNUSED_PARAMETER(info);
1819 cmsUNUSED_PARAMETER(Stride);
1820 }
1821
1822 static
Pack3BytesSwapOptimized(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1823 cmsUInt8Number* Pack3BytesSwapOptimized(register _cmsTRANSFORM* info,
1824 register cmsUInt16Number wOut[],
1825 register cmsUInt8Number* output,
1826 register cmsUInt32Number Stride)
1827 {
1828 *output++ = (wOut[2] & 0xFF);
1829 *output++ = (wOut[1] & 0xFF);
1830 *output++ = (wOut[0] & 0xFF);
1831
1832 return output;
1833
1834 cmsUNUSED_PARAMETER(info);
1835 cmsUNUSED_PARAMETER(Stride);
1836 }
1837
1838
1839 static
Pack3Words(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1840 cmsUInt8Number* Pack3Words(register _cmsTRANSFORM* info,
1841 register cmsUInt16Number wOut[],
1842 register cmsUInt8Number* output,
1843 register cmsUInt32Number Stride)
1844 {
1845 *(cmsUInt16Number*) output = wOut[0];
1846 output+= 2;
1847 *(cmsUInt16Number*) output = wOut[1];
1848 output+= 2;
1849 *(cmsUInt16Number*) output = wOut[2];
1850 output+= 2;
1851
1852 return output;
1853
1854 cmsUNUSED_PARAMETER(info);
1855 cmsUNUSED_PARAMETER(Stride);
1856 }
1857
1858 static
Pack3WordsSwap(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1859 cmsUInt8Number* Pack3WordsSwap(register _cmsTRANSFORM* info,
1860 register cmsUInt16Number wOut[],
1861 register cmsUInt8Number* output,
1862 register cmsUInt32Number Stride)
1863 {
1864 *(cmsUInt16Number*) output = wOut[2];
1865 output+= 2;
1866 *(cmsUInt16Number*) output = wOut[1];
1867 output+= 2;
1868 *(cmsUInt16Number*) output = wOut[0];
1869 output+= 2;
1870
1871 return output;
1872
1873 cmsUNUSED_PARAMETER(info);
1874 cmsUNUSED_PARAMETER(Stride);
1875 }
1876
1877 static
Pack3WordsBigEndian(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1878 cmsUInt8Number* Pack3WordsBigEndian(register _cmsTRANSFORM* info,
1879 register cmsUInt16Number wOut[],
1880 register cmsUInt8Number* output,
1881 register cmsUInt32Number Stride)
1882 {
1883 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
1884 output+= 2;
1885 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[1]);
1886 output+= 2;
1887 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[2]);
1888 output+= 2;
1889
1890 return output;
1891
1892 cmsUNUSED_PARAMETER(info);
1893 cmsUNUSED_PARAMETER(Stride);
1894 }
1895
1896 static
Pack3BytesAndSkip1(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1897 cmsUInt8Number* Pack3BytesAndSkip1(register _cmsTRANSFORM* info,
1898 register cmsUInt16Number wOut[],
1899 register cmsUInt8Number* output,
1900 register cmsUInt32Number Stride)
1901 {
1902 *output++ = FROM_16_TO_8(wOut[0]);
1903 *output++ = FROM_16_TO_8(wOut[1]);
1904 *output++ = FROM_16_TO_8(wOut[2]);
1905 output++;
1906
1907 return output;
1908
1909 cmsUNUSED_PARAMETER(info);
1910 cmsUNUSED_PARAMETER(Stride);
1911 }
1912
1913 static
Pack3BytesAndSkip1Optimized(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1914 cmsUInt8Number* Pack3BytesAndSkip1Optimized(register _cmsTRANSFORM* info,
1915 register cmsUInt16Number wOut[],
1916 register cmsUInt8Number* output,
1917 register cmsUInt32Number Stride)
1918 {
1919 *output++ = (wOut[0] & 0xFF);
1920 *output++ = (wOut[1] & 0xFF);
1921 *output++ = (wOut[2] & 0xFF);
1922 output++;
1923
1924 return output;
1925
1926 cmsUNUSED_PARAMETER(info);
1927 cmsUNUSED_PARAMETER(Stride);
1928 }
1929
1930
1931 static
Pack3BytesAndSkip1SwapFirst(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1932 cmsUInt8Number* Pack3BytesAndSkip1SwapFirst(register _cmsTRANSFORM* info,
1933 register cmsUInt16Number wOut[],
1934 register cmsUInt8Number* output,
1935 register cmsUInt32Number Stride)
1936 {
1937 output++;
1938 *output++ = FROM_16_TO_8(wOut[0]);
1939 *output++ = FROM_16_TO_8(wOut[1]);
1940 *output++ = FROM_16_TO_8(wOut[2]);
1941
1942 return output;
1943
1944 cmsUNUSED_PARAMETER(info);
1945 cmsUNUSED_PARAMETER(Stride);
1946 }
1947
1948 static
Pack3BytesAndSkip1SwapFirstOptimized(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1949 cmsUInt8Number* Pack3BytesAndSkip1SwapFirstOptimized(register _cmsTRANSFORM* info,
1950 register cmsUInt16Number wOut[],
1951 register cmsUInt8Number* output,
1952 register cmsUInt32Number Stride)
1953 {
1954 output++;
1955 *output++ = (wOut[0] & 0xFF);
1956 *output++ = (wOut[1] & 0xFF);
1957 *output++ = (wOut[2] & 0xFF);
1958
1959 return output;
1960
1961 cmsUNUSED_PARAMETER(info);
1962 cmsUNUSED_PARAMETER(Stride);
1963 }
1964
1965 static
Pack3BytesAndSkip1Swap(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1966 cmsUInt8Number* Pack3BytesAndSkip1Swap(register _cmsTRANSFORM* info,
1967 register cmsUInt16Number wOut[],
1968 register cmsUInt8Number* output,
1969 register cmsUInt32Number Stride)
1970 {
1971 output++;
1972 *output++ = FROM_16_TO_8(wOut[2]);
1973 *output++ = FROM_16_TO_8(wOut[1]);
1974 *output++ = FROM_16_TO_8(wOut[0]);
1975
1976 return output;
1977
1978 cmsUNUSED_PARAMETER(info);
1979 cmsUNUSED_PARAMETER(Stride);
1980 }
1981
1982 static
Pack3BytesAndSkip1SwapOptimized(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)1983 cmsUInt8Number* Pack3BytesAndSkip1SwapOptimized(register _cmsTRANSFORM* info,
1984 register cmsUInt16Number wOut[],
1985 register cmsUInt8Number* output,
1986 register cmsUInt32Number Stride)
1987 {
1988 output++;
1989 *output++ = (wOut[2] & 0xFF);
1990 *output++ = (wOut[1] & 0xFF);
1991 *output++ = (wOut[0] & 0xFF);
1992
1993 return output;
1994
1995 cmsUNUSED_PARAMETER(info);
1996 cmsUNUSED_PARAMETER(Stride);
1997 }
1998
1999
2000 static
Pack3BytesAndSkip1SwapSwapFirst(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)2001 cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirst(register _cmsTRANSFORM* info,
2002 register cmsUInt16Number wOut[],
2003 register cmsUInt8Number* output,
2004 register cmsUInt32Number Stride)
2005 {
2006 *output++ = FROM_16_TO_8(wOut[2]);
2007 *output++ = FROM_16_TO_8(wOut[1]);
2008 *output++ = FROM_16_TO_8(wOut[0]);
2009 output++;
2010
2011 return output;
2012
2013 cmsUNUSED_PARAMETER(info);
2014 cmsUNUSED_PARAMETER(Stride);
2015 }
2016
2017 static
Pack3BytesAndSkip1SwapSwapFirstOptimized(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)2018 cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirstOptimized(register _cmsTRANSFORM* info,
2019 register cmsUInt16Number wOut[],
2020 register cmsUInt8Number* output,
2021 register cmsUInt32Number Stride)
2022 {
2023 *output++ = (wOut[2] & 0xFF);
2024 *output++ = (wOut[1] & 0xFF);
2025 *output++ = (wOut[0] & 0xFF);
2026 output++;
2027
2028 return output;
2029
2030 cmsUNUSED_PARAMETER(info);
2031 cmsUNUSED_PARAMETER(Stride);
2032 }
2033
2034 static
Pack3WordsAndSkip1(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)2035 cmsUInt8Number* Pack3WordsAndSkip1(register _cmsTRANSFORM* info,
2036 register cmsUInt16Number wOut[],
2037 register cmsUInt8Number* output,
2038 register cmsUInt32Number Stride)
2039 {
2040 *(cmsUInt16Number*) output = wOut[0];
2041 output+= 2;
2042 *(cmsUInt16Number*) output = wOut[1];
2043 output+= 2;
2044 *(cmsUInt16Number*) output = wOut[2];
2045 output+= 2;
2046 output+= 2;
2047
2048 return output;
2049
2050 cmsUNUSED_PARAMETER(info);
2051 cmsUNUSED_PARAMETER(Stride);
2052 }
2053
2054 static
Pack3WordsAndSkip1Swap(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)2055 cmsUInt8Number* Pack3WordsAndSkip1Swap(register _cmsTRANSFORM* info,
2056 register cmsUInt16Number wOut[],
2057 register cmsUInt8Number* output,
2058 register cmsUInt32Number Stride)
2059 {
2060 output+= 2;
2061 *(cmsUInt16Number*) output = wOut[2];
2062 output+= 2;
2063 *(cmsUInt16Number*) output = wOut[1];
2064 output+= 2;
2065 *(cmsUInt16Number*) output = wOut[0];
2066 output+= 2;
2067
2068 return output;
2069
2070 cmsUNUSED_PARAMETER(info);
2071 cmsUNUSED_PARAMETER(Stride);
2072 }
2073
2074
2075 static
Pack3WordsAndSkip1SwapFirst(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)2076 cmsUInt8Number* Pack3WordsAndSkip1SwapFirst(register _cmsTRANSFORM* info,
2077 register cmsUInt16Number wOut[],
2078 register cmsUInt8Number* output,
2079 register cmsUInt32Number Stride)
2080 {
2081 output+= 2;
2082 *(cmsUInt16Number*) output = wOut[0];
2083 output+= 2;
2084 *(cmsUInt16Number*) output = wOut[1];
2085 output+= 2;
2086 *(cmsUInt16Number*) output = wOut[2];
2087 output+= 2;
2088
2089 return output;
2090
2091 cmsUNUSED_PARAMETER(info);
2092 cmsUNUSED_PARAMETER(Stride);
2093 }
2094
2095
2096 static
Pack3WordsAndSkip1SwapSwapFirst(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)2097 cmsUInt8Number* Pack3WordsAndSkip1SwapSwapFirst(register _cmsTRANSFORM* info,
2098 register cmsUInt16Number wOut[],
2099 register cmsUInt8Number* output,
2100 register cmsUInt32Number Stride)
2101 {
2102 *(cmsUInt16Number*) output = wOut[2];
2103 output+= 2;
2104 *(cmsUInt16Number*) output = wOut[1];
2105 output+= 2;
2106 *(cmsUInt16Number*) output = wOut[0];
2107 output+= 2;
2108 output+= 2;
2109
2110 return output;
2111
2112 cmsUNUSED_PARAMETER(info);
2113 cmsUNUSED_PARAMETER(Stride);
2114 }
2115
2116
2117
2118 static
Pack1Byte(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)2119 cmsUInt8Number* Pack1Byte(register _cmsTRANSFORM* info,
2120 register cmsUInt16Number wOut[],
2121 register cmsUInt8Number* output,
2122 register cmsUInt32Number Stride)
2123 {
2124 *output++ = FROM_16_TO_8(wOut[0]);
2125
2126 return output;
2127
2128 cmsUNUSED_PARAMETER(info);
2129 cmsUNUSED_PARAMETER(Stride);
2130 }
2131
2132
2133 static
Pack1ByteReversed(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)2134 cmsUInt8Number* Pack1ByteReversed(register _cmsTRANSFORM* info,
2135 register cmsUInt16Number wOut[],
2136 register cmsUInt8Number* output,
2137 register cmsUInt32Number Stride)
2138 {
2139 *output++ = FROM_16_TO_8(REVERSE_FLAVOR_16(wOut[0]));
2140
2141 return output;
2142
2143 cmsUNUSED_PARAMETER(info);
2144 cmsUNUSED_PARAMETER(Stride);
2145 }
2146
2147
2148 static
Pack1ByteSkip1(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)2149 cmsUInt8Number* Pack1ByteSkip1(register _cmsTRANSFORM* info,
2150 register cmsUInt16Number wOut[],
2151 register cmsUInt8Number* output,
2152 register cmsUInt32Number Stride)
2153 {
2154 *output++ = FROM_16_TO_8(wOut[0]);
2155 output++;
2156
2157 return output;
2158
2159 cmsUNUSED_PARAMETER(info);
2160 cmsUNUSED_PARAMETER(Stride);
2161 }
2162
2163
2164 static
Pack1ByteSkip1SwapFirst(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)2165 cmsUInt8Number* Pack1ByteSkip1SwapFirst(register _cmsTRANSFORM* info,
2166 register cmsUInt16Number wOut[],
2167 register cmsUInt8Number* output,
2168 register cmsUInt32Number Stride)
2169 {
2170 output++;
2171 *output++ = FROM_16_TO_8(wOut[0]);
2172
2173 return output;
2174
2175 cmsUNUSED_PARAMETER(info);
2176 cmsUNUSED_PARAMETER(Stride);
2177 }
2178
2179 static
Pack1Word(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)2180 cmsUInt8Number* Pack1Word(register _cmsTRANSFORM* info,
2181 register cmsUInt16Number wOut[],
2182 register cmsUInt8Number* output,
2183 register cmsUInt32Number Stride)
2184 {
2185 *(cmsUInt16Number*) output = wOut[0];
2186 output+= 2;
2187
2188 return output;
2189
2190 cmsUNUSED_PARAMETER(info);
2191 cmsUNUSED_PARAMETER(Stride);
2192 }
2193
2194
2195 static
Pack1WordReversed(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)2196 cmsUInt8Number* Pack1WordReversed(register _cmsTRANSFORM* info,
2197 register cmsUInt16Number wOut[],
2198 register cmsUInt8Number* output,
2199 register cmsUInt32Number Stride)
2200 {
2201 *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[0]);
2202 output+= 2;
2203
2204 return output;
2205
2206 cmsUNUSED_PARAMETER(info);
2207 cmsUNUSED_PARAMETER(Stride);
2208 }
2209
2210 static
Pack1WordBigEndian(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)2211 cmsUInt8Number* Pack1WordBigEndian(register _cmsTRANSFORM* info,
2212 register cmsUInt16Number wOut[],
2213 register cmsUInt8Number* output,
2214 register cmsUInt32Number Stride)
2215 {
2216 *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
2217 output+= 2;
2218
2219 return output;
2220
2221 cmsUNUSED_PARAMETER(info);
2222 cmsUNUSED_PARAMETER(Stride);
2223 }
2224
2225
2226 static
Pack1WordSkip1(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)2227 cmsUInt8Number* Pack1WordSkip1(register _cmsTRANSFORM* info,
2228 register cmsUInt16Number wOut[],
2229 register cmsUInt8Number* output,
2230 register cmsUInt32Number Stride)
2231 {
2232 *(cmsUInt16Number*) output = wOut[0];
2233 output+= 4;
2234
2235 return output;
2236
2237 cmsUNUSED_PARAMETER(info);
2238 cmsUNUSED_PARAMETER(Stride);
2239 }
2240
2241 static
Pack1WordSkip1SwapFirst(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)2242 cmsUInt8Number* Pack1WordSkip1SwapFirst(register _cmsTRANSFORM* info,
2243 register cmsUInt16Number wOut[],
2244 register cmsUInt8Number* output,
2245 register cmsUInt32Number Stride)
2246 {
2247 output += 2;
2248 *(cmsUInt16Number*) output = wOut[0];
2249 output+= 2;
2250
2251 return output;
2252
2253 cmsUNUSED_PARAMETER(info);
2254 cmsUNUSED_PARAMETER(Stride);
2255 }
2256
2257
2258 // Unencoded Float values -- don't try optimize speed
2259 static
PackLabDoubleFrom16(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)2260 cmsUInt8Number* PackLabDoubleFrom16(register _cmsTRANSFORM* info,
2261 register cmsUInt16Number wOut[],
2262 register cmsUInt8Number* output,
2263 register cmsUInt32Number Stride)
2264 {
2265
2266 if (T_PLANAR(info -> OutputFormat)) {
2267
2268 cmsCIELab Lab;
2269 cmsFloat64Number* Out = (cmsFloat64Number*) output;
2270 cmsLabEncoded2Float(&Lab, wOut);
2271
2272 Out[0] = Lab.L;
2273 Out[Stride] = Lab.a;
2274 Out[Stride*2] = Lab.b;
2275
2276 return output + sizeof(cmsFloat64Number);
2277 }
2278 else {
2279
2280 cmsLabEncoded2Float((cmsCIELab*) output, wOut);
2281 return output + (sizeof(cmsCIELab) + T_EXTRA(info ->OutputFormat) * sizeof(cmsFloat64Number));
2282 }
2283 }
2284
2285
2286 static
PackLabFloatFrom16(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)2287 cmsUInt8Number* PackLabFloatFrom16(register _cmsTRANSFORM* info,
2288 register cmsUInt16Number wOut[],
2289 register cmsUInt8Number* output,
2290 register cmsUInt32Number Stride)
2291 {
2292 cmsCIELab Lab;
2293 cmsLabEncoded2Float(&Lab, wOut);
2294
2295 if (T_PLANAR(info -> OutputFormat)) {
2296
2297 cmsFloat32Number* Out = (cmsFloat32Number*) output;
2298
2299 Out[0] = (cmsFloat32Number)Lab.L;
2300 Out[Stride] = (cmsFloat32Number)Lab.a;
2301 Out[Stride*2] = (cmsFloat32Number)Lab.b;
2302
2303 return output + sizeof(cmsFloat32Number);
2304 }
2305 else {
2306
2307 ((cmsFloat32Number*) output)[0] = (cmsFloat32Number) Lab.L;
2308 ((cmsFloat32Number*) output)[1] = (cmsFloat32Number) Lab.a;
2309 ((cmsFloat32Number*) output)[2] = (cmsFloat32Number) Lab.b;
2310
2311 return output + (3 + T_EXTRA(info ->OutputFormat)) * sizeof(cmsFloat32Number);
2312 }
2313 }
2314
2315 static
PackXYZDoubleFrom16(register _cmsTRANSFORM * Info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)2316 cmsUInt8Number* PackXYZDoubleFrom16(register _cmsTRANSFORM* Info,
2317 register cmsUInt16Number wOut[],
2318 register cmsUInt8Number* output,
2319 register cmsUInt32Number Stride)
2320 {
2321 if (T_PLANAR(Info -> OutputFormat)) {
2322
2323 cmsCIEXYZ XYZ;
2324 cmsFloat64Number* Out = (cmsFloat64Number*) output;
2325 cmsXYZEncoded2Float(&XYZ, wOut);
2326
2327 Out[0] = XYZ.X;
2328 Out[Stride] = XYZ.Y;
2329 Out[Stride*2] = XYZ.Z;
2330
2331 return output + sizeof(cmsFloat64Number);
2332
2333 }
2334 else {
2335
2336 cmsXYZEncoded2Float((cmsCIEXYZ*) output, wOut);
2337
2338 return output + (sizeof(cmsCIEXYZ) + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
2339 }
2340 }
2341
2342 static
PackXYZFloatFrom16(register _cmsTRANSFORM * Info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)2343 cmsUInt8Number* PackXYZFloatFrom16(register _cmsTRANSFORM* Info,
2344 register cmsUInt16Number wOut[],
2345 register cmsUInt8Number* output,
2346 register cmsUInt32Number Stride)
2347 {
2348 if (T_PLANAR(Info -> OutputFormat)) {
2349
2350 cmsCIEXYZ XYZ;
2351 cmsFloat32Number* Out = (cmsFloat32Number*) output;
2352 cmsXYZEncoded2Float(&XYZ, wOut);
2353
2354 Out[0] = (cmsFloat32Number) XYZ.X;
2355 Out[Stride] = (cmsFloat32Number) XYZ.Y;
2356 Out[Stride*2] = (cmsFloat32Number) XYZ.Z;
2357
2358 return output + sizeof(cmsFloat32Number);
2359
2360 }
2361 else {
2362
2363 cmsCIEXYZ XYZ;
2364 cmsFloat32Number* Out = (cmsFloat32Number*) output;
2365 cmsXYZEncoded2Float(&XYZ, wOut);
2366
2367 Out[0] = (cmsFloat32Number) XYZ.X;
2368 Out[1] = (cmsFloat32Number) XYZ.Y;
2369 Out[2] = (cmsFloat32Number) XYZ.Z;
2370
2371 return output + (3 * sizeof(cmsFloat32Number) + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
2372 }
2373 }
2374
2375 static
PackDoubleFrom16(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)2376 cmsUInt8Number* PackDoubleFrom16(register _cmsTRANSFORM* info,
2377 register cmsUInt16Number wOut[],
2378 register cmsUInt8Number* output,
2379 register cmsUInt32Number Stride)
2380 {
2381 int nChan = T_CHANNELS(info -> OutputFormat);
2382 int DoSwap = T_DOSWAP(info ->OutputFormat);
2383 int Reverse = T_FLAVOR(info ->OutputFormat);
2384 int Extra = T_EXTRA(info -> OutputFormat);
2385 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2386 int Planar = T_PLANAR(info -> OutputFormat);
2387 int ExtraFirst = DoSwap ^ SwapFirst;
2388 cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35 : 65535.0;
2389 cmsFloat64Number v = 0;
2390 cmsFloat64Number* swap1 = (cmsFloat64Number*) output;
2391 int i, start = 0;
2392
2393 if (ExtraFirst)
2394 start = Extra;
2395
2396 for (i=0; i < nChan; i++) {
2397
2398 int index = DoSwap ? (nChan - i - 1) : i;
2399
2400 v = (cmsFloat64Number) wOut[index] / maximum;
2401
2402 if (Reverse)
2403 v = maximum - v;
2404
2405 if (Planar)
2406 ((cmsFloat64Number*) output)[(i + start) * Stride]= v;
2407 else
2408 ((cmsFloat64Number*) output)[i + start] = v;
2409 }
2410
2411 if (!ExtraFirst) {
2412 output += Extra * sizeof(cmsFloat64Number);
2413 }
2414
2415 if (Extra == 0 && SwapFirst) {
2416
2417 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat64Number));
2418 *swap1 = v;
2419 }
2420
2421 if (T_PLANAR(info -> OutputFormat))
2422 return output + sizeof(cmsFloat64Number);
2423 else
2424 return output + nChan * sizeof(cmsFloat64Number);
2425
2426 }
2427
2428
2429 static
PackFloatFrom16(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)2430 cmsUInt8Number* PackFloatFrom16(register _cmsTRANSFORM* info,
2431 register cmsUInt16Number wOut[],
2432 register cmsUInt8Number* output,
2433 register cmsUInt32Number Stride)
2434 {
2435 int nChan = T_CHANNELS(info -> OutputFormat);
2436 int DoSwap = T_DOSWAP(info ->OutputFormat);
2437 int Reverse = T_FLAVOR(info ->OutputFormat);
2438 int Extra = T_EXTRA(info -> OutputFormat);
2439 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2440 int Planar = T_PLANAR(info -> OutputFormat);
2441 int ExtraFirst = DoSwap ^ SwapFirst;
2442 cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35 : 65535.0;
2443 cmsFloat64Number v = 0;
2444 cmsFloat32Number* swap1 = (cmsFloat32Number*) output;
2445 int i, start = 0;
2446
2447 if (ExtraFirst)
2448 start = Extra;
2449
2450 for (i=0; i < nChan; i++) {
2451
2452 int index = DoSwap ? (nChan - i - 1) : i;
2453
2454 v = (cmsFloat64Number) wOut[index] / maximum;
2455
2456 if (Reverse)
2457 v = maximum - v;
2458
2459 if (Planar)
2460 ((cmsFloat32Number*) output)[(i + start ) * Stride]= (cmsFloat32Number) v;
2461 else
2462 ((cmsFloat32Number*) output)[i + start] = (cmsFloat32Number) v;
2463 }
2464
2465 if (!ExtraFirst) {
2466 output += Extra * sizeof(cmsFloat32Number);
2467 }
2468
2469 if (Extra == 0 && SwapFirst) {
2470
2471 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat32Number));
2472 *swap1 = (cmsFloat32Number) v;
2473 }
2474
2475 if (T_PLANAR(info -> OutputFormat))
2476 return output + sizeof(cmsFloat32Number);
2477 else
2478 return output + nChan * sizeof(cmsFloat32Number);
2479 }
2480
2481
2482
2483 // --------------------------------------------------------------------------------------------------------
2484
2485 static
PackFloatsFromFloat(_cmsTRANSFORM * info,cmsFloat32Number wOut[],cmsUInt8Number * output,cmsUInt32Number Stride)2486 cmsUInt8Number* PackFloatsFromFloat(_cmsTRANSFORM* info,
2487 cmsFloat32Number wOut[],
2488 cmsUInt8Number* output,
2489 cmsUInt32Number Stride)
2490 {
2491 int nChan = T_CHANNELS(info -> OutputFormat);
2492 int DoSwap = T_DOSWAP(info ->OutputFormat);
2493 int Reverse = T_FLAVOR(info ->OutputFormat);
2494 int Extra = T_EXTRA(info -> OutputFormat);
2495 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2496 int Planar = T_PLANAR(info -> OutputFormat);
2497 int ExtraFirst = DoSwap ^ SwapFirst;
2498 cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
2499 cmsFloat32Number* swap1 = (cmsFloat32Number*) output;
2500 cmsFloat64Number v = 0;
2501 int i, start = 0;
2502
2503 if (ExtraFirst)
2504 start = Extra;
2505
2506 for (i=0; i < nChan; i++) {
2507
2508 int index = DoSwap ? (nChan - i - 1) : i;
2509
2510 v = wOut[index] * maximum;
2511
2512 if (Reverse)
2513 v = maximum - v;
2514
2515 if (Planar)
2516 ((cmsFloat32Number*) output)[(i + start)* Stride]= (cmsFloat32Number) v;
2517 else
2518 ((cmsFloat32Number*) output)[i + start] = (cmsFloat32Number) v;
2519 }
2520
2521 if (!ExtraFirst) {
2522 output += Extra * sizeof(cmsFloat32Number);
2523 }
2524
2525 if (Extra == 0 && SwapFirst) {
2526
2527 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat32Number));
2528 *swap1 = (cmsFloat32Number) v;
2529 }
2530
2531 if (T_PLANAR(info -> OutputFormat))
2532 return output + sizeof(cmsFloat32Number);
2533 else
2534 return output + nChan * sizeof(cmsFloat32Number);
2535 }
2536
2537 static
PackDoublesFromFloat(_cmsTRANSFORM * info,cmsFloat32Number wOut[],cmsUInt8Number * output,cmsUInt32Number Stride)2538 cmsUInt8Number* PackDoublesFromFloat(_cmsTRANSFORM* info,
2539 cmsFloat32Number wOut[],
2540 cmsUInt8Number* output,
2541 cmsUInt32Number Stride)
2542 {
2543 int nChan = T_CHANNELS(info -> OutputFormat);
2544 int DoSwap = T_DOSWAP(info ->OutputFormat);
2545 int Reverse = T_FLAVOR(info ->OutputFormat);
2546 int Extra = T_EXTRA(info -> OutputFormat);
2547 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2548 int Planar = T_PLANAR(info -> OutputFormat);
2549 int ExtraFirst = DoSwap ^ SwapFirst;
2550 cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
2551 cmsFloat64Number v = 0;
2552 cmsFloat64Number* swap1 = (cmsFloat64Number*) output;
2553 int i, start = 0;
2554
2555 if (ExtraFirst)
2556 start = Extra;
2557
2558 for (i=0; i < nChan; i++) {
2559
2560 int index = DoSwap ? (nChan - i - 1) : i;
2561
2562 v = wOut[index] * maximum;
2563
2564 if (Reverse)
2565 v = maximum - v;
2566
2567 if (Planar)
2568 ((cmsFloat64Number*) output)[(i + start) * Stride] = v;
2569 else
2570 ((cmsFloat64Number*) output)[i + start] = v;
2571 }
2572
2573 if (!ExtraFirst) {
2574 output += Extra * sizeof(cmsFloat64Number);
2575 }
2576
2577 if (Extra == 0 && SwapFirst) {
2578
2579 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat64Number));
2580 *swap1 = v;
2581 }
2582
2583
2584 if (T_PLANAR(info -> OutputFormat))
2585 return output + sizeof(cmsFloat64Number);
2586 else
2587 return output + nChan * sizeof(cmsFloat64Number);
2588
2589 }
2590
2591
2592
2593
2594
2595 static
PackLabFloatFromFloat(_cmsTRANSFORM * Info,cmsFloat32Number wOut[],cmsUInt8Number * output,cmsUInt32Number Stride)2596 cmsUInt8Number* PackLabFloatFromFloat(_cmsTRANSFORM* Info,
2597 cmsFloat32Number wOut[],
2598 cmsUInt8Number* output,
2599 cmsUInt32Number Stride)
2600 {
2601 cmsFloat32Number* Out = (cmsFloat32Number*) output;
2602
2603 if (T_PLANAR(Info -> OutputFormat)) {
2604
2605 Out[0] = (cmsFloat32Number) (wOut[0] * 100.0);
2606 Out[Stride] = (cmsFloat32Number) (wOut[1] * 255.0 - 128.0);
2607 Out[Stride*2] = (cmsFloat32Number) (wOut[2] * 255.0 - 128.0);
2608
2609 return output + sizeof(cmsFloat32Number);
2610 }
2611 else {
2612
2613 Out[0] = (cmsFloat32Number) (wOut[0] * 100.0);
2614 Out[1] = (cmsFloat32Number) (wOut[1] * 255.0 - 128.0);
2615 Out[2] = (cmsFloat32Number) (wOut[2] * 255.0 - 128.0);
2616
2617 return output + (sizeof(cmsFloat32Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
2618 }
2619
2620 }
2621
2622
2623 static
PackLabDoubleFromFloat(_cmsTRANSFORM * Info,cmsFloat32Number wOut[],cmsUInt8Number * output,cmsUInt32Number Stride)2624 cmsUInt8Number* PackLabDoubleFromFloat(_cmsTRANSFORM* Info,
2625 cmsFloat32Number wOut[],
2626 cmsUInt8Number* output,
2627 cmsUInt32Number Stride)
2628 {
2629 cmsFloat64Number* Out = (cmsFloat64Number*) output;
2630
2631 if (T_PLANAR(Info -> OutputFormat)) {
2632
2633 Out[0] = (cmsFloat64Number) (wOut[0] * 100.0);
2634 Out[Stride] = (cmsFloat64Number) (wOut[1] * 255.0 - 128.0);
2635 Out[Stride*2] = (cmsFloat64Number) (wOut[2] * 255.0 - 128.0);
2636
2637 return output + sizeof(cmsFloat64Number);
2638 }
2639 else {
2640
2641 Out[0] = (cmsFloat64Number) (wOut[0] * 100.0);
2642 Out[1] = (cmsFloat64Number) (wOut[1] * 255.0 - 128.0);
2643 Out[2] = (cmsFloat64Number) (wOut[2] * 255.0 - 128.0);
2644
2645 return output + (sizeof(cmsFloat64Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
2646 }
2647
2648 }
2649
2650
2651 // From 0..1 range to 0..MAX_ENCODEABLE_XYZ
2652 static
PackXYZFloatFromFloat(_cmsTRANSFORM * Info,cmsFloat32Number wOut[],cmsUInt8Number * output,cmsUInt32Number Stride)2653 cmsUInt8Number* PackXYZFloatFromFloat(_cmsTRANSFORM* Info,
2654 cmsFloat32Number wOut[],
2655 cmsUInt8Number* output,
2656 cmsUInt32Number Stride)
2657 {
2658 cmsFloat32Number* Out = (cmsFloat32Number*) output;
2659
2660 if (T_PLANAR(Info -> OutputFormat)) {
2661
2662 Out[0] = (cmsFloat32Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
2663 Out[Stride] = (cmsFloat32Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
2664 Out[Stride*2] = (cmsFloat32Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
2665
2666 return output + sizeof(cmsFloat32Number);
2667 }
2668 else {
2669
2670 Out[0] = (cmsFloat32Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
2671 Out[1] = (cmsFloat32Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
2672 Out[2] = (cmsFloat32Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
2673
2674 return output + (sizeof(cmsFloat32Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
2675 }
2676
2677 }
2678
2679 // Same, but convert to double
2680 static
PackXYZDoubleFromFloat(_cmsTRANSFORM * Info,cmsFloat32Number wOut[],cmsUInt8Number * output,cmsUInt32Number Stride)2681 cmsUInt8Number* PackXYZDoubleFromFloat(_cmsTRANSFORM* Info,
2682 cmsFloat32Number wOut[],
2683 cmsUInt8Number* output,
2684 cmsUInt32Number Stride)
2685 {
2686 cmsFloat64Number* Out = (cmsFloat64Number*) output;
2687
2688 if (T_PLANAR(Info -> OutputFormat)) {
2689
2690 Out[0] = (cmsFloat64Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
2691 Out[Stride] = (cmsFloat64Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
2692 Out[Stride*2] = (cmsFloat64Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
2693
2694 return output + sizeof(cmsFloat64Number);
2695 }
2696 else {
2697
2698 Out[0] = (cmsFloat64Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
2699 Out[1] = (cmsFloat64Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
2700 Out[2] = (cmsFloat64Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
2701
2702 return output + (sizeof(cmsFloat64Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
2703 }
2704
2705 }
2706
2707
2708 // ----------------------------------------------------------------------------------------------------------------
2709
2710 #ifndef CMS_NO_HALF_SUPPORT
2711
2712 // Decodes an stream of half floats to wIn[] described by input format
2713
2714 static
UnrollHalfTo16(register _cmsTRANSFORM * info,register cmsUInt16Number wIn[],register cmsUInt8Number * accum,register cmsUInt32Number Stride)2715 cmsUInt8Number* UnrollHalfTo16(register _cmsTRANSFORM* info,
2716 register cmsUInt16Number wIn[],
2717 register cmsUInt8Number* accum,
2718 register cmsUInt32Number Stride)
2719 {
2720
2721 int nChan = T_CHANNELS(info -> InputFormat);
2722 int DoSwap = T_DOSWAP(info ->InputFormat);
2723 int Reverse = T_FLAVOR(info ->InputFormat);
2724 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
2725 int Extra = T_EXTRA(info -> InputFormat);
2726 int ExtraFirst = DoSwap ^ SwapFirst;
2727 int Planar = T_PLANAR(info -> InputFormat);
2728 cmsFloat32Number v;
2729 int i, start = 0;
2730 cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 655.35F : 65535.0F;
2731
2732
2733 if (ExtraFirst)
2734 start = Extra;
2735
2736 for (i=0; i < nChan; i++) {
2737
2738 int index = DoSwap ? (nChan - i - 1) : i;
2739
2740 if (Planar)
2741 v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[(i + start) * Stride] );
2742 else
2743 v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[i + start] ) ;
2744
2745 if (Reverse) v = maximum - v;
2746
2747 wIn[index] = _cmsQuickSaturateWord(v * maximum);
2748 }
2749
2750
2751 if (Extra == 0 && SwapFirst) {
2752 cmsUInt16Number tmp = wIn[0];
2753
2754 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
2755 wIn[nChan-1] = tmp;
2756 }
2757
2758 if (T_PLANAR(info -> InputFormat))
2759 return accum + sizeof(cmsUInt16Number);
2760 else
2761 return accum + (nChan + Extra) * sizeof(cmsUInt16Number);
2762 }
2763
2764 // Decodes an stream of half floats to wIn[] described by input format
2765
2766 static
UnrollHalfToFloat(_cmsTRANSFORM * info,cmsFloat32Number wIn[],cmsUInt8Number * accum,cmsUInt32Number Stride)2767 cmsUInt8Number* UnrollHalfToFloat(_cmsTRANSFORM* info,
2768 cmsFloat32Number wIn[],
2769 cmsUInt8Number* accum,
2770 cmsUInt32Number Stride)
2771 {
2772
2773 int nChan = T_CHANNELS(info -> InputFormat);
2774 int DoSwap = T_DOSWAP(info ->InputFormat);
2775 int Reverse = T_FLAVOR(info ->InputFormat);
2776 int SwapFirst = T_SWAPFIRST(info -> InputFormat);
2777 int Extra = T_EXTRA(info -> InputFormat);
2778 int ExtraFirst = DoSwap ^ SwapFirst;
2779 int Planar = T_PLANAR(info -> InputFormat);
2780 cmsFloat32Number v;
2781 int i, start = 0;
2782 cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 100.0F : 1.0F;
2783
2784
2785 if (ExtraFirst)
2786 start = Extra;
2787
2788 for (i=0; i < nChan; i++) {
2789
2790 int index = DoSwap ? (nChan - i - 1) : i;
2791
2792 if (Planar)
2793 v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[(i + start) * Stride] );
2794 else
2795 v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[i + start] ) ;
2796
2797 v /= maximum;
2798
2799 wIn[index] = Reverse ? 1 - v : v;
2800 }
2801
2802
2803 if (Extra == 0 && SwapFirst) {
2804 cmsFloat32Number tmp = wIn[0];
2805
2806 memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number));
2807 wIn[nChan-1] = tmp;
2808 }
2809
2810 if (T_PLANAR(info -> InputFormat))
2811 return accum + sizeof(cmsUInt16Number);
2812 else
2813 return accum + (nChan + Extra) * sizeof(cmsUInt16Number);
2814 }
2815
2816
2817 static
PackHalfFrom16(register _cmsTRANSFORM * info,register cmsUInt16Number wOut[],register cmsUInt8Number * output,register cmsUInt32Number Stride)2818 cmsUInt8Number* PackHalfFrom16(register _cmsTRANSFORM* info,
2819 register cmsUInt16Number wOut[],
2820 register cmsUInt8Number* output,
2821 register cmsUInt32Number Stride)
2822 {
2823 int nChan = T_CHANNELS(info -> OutputFormat);
2824 int DoSwap = T_DOSWAP(info ->OutputFormat);
2825 int Reverse = T_FLAVOR(info ->OutputFormat);
2826 int Extra = T_EXTRA(info -> OutputFormat);
2827 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2828 int Planar = T_PLANAR(info -> OutputFormat);
2829 int ExtraFirst = DoSwap ^ SwapFirst;
2830 cmsFloat32Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35F : 65535.0F;
2831 cmsFloat32Number v = 0;
2832 cmsUInt16Number* swap1 = (cmsUInt16Number*) output;
2833 int i, start = 0;
2834
2835 if (ExtraFirst)
2836 start = Extra;
2837
2838 for (i=0; i < nChan; i++) {
2839
2840 int index = DoSwap ? (nChan - i - 1) : i;
2841
2842 v = (cmsFloat32Number) wOut[index] / maximum;
2843
2844 if (Reverse)
2845 v = maximum - v;
2846
2847 if (Planar)
2848 ((cmsUInt16Number*) output)[(i + start ) * Stride]= _cmsFloat2Half(v);
2849 else
2850 ((cmsUInt16Number*) output)[i + start] = _cmsFloat2Half(v);
2851 }
2852
2853 if (!ExtraFirst) {
2854 output += Extra * sizeof(cmsUInt16Number);
2855 }
2856
2857 if (Extra == 0 && SwapFirst) {
2858
2859 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number));
2860 *swap1 = _cmsFloat2Half(v);
2861 }
2862
2863 if (T_PLANAR(info -> OutputFormat))
2864 return output + sizeof(cmsUInt16Number);
2865 else
2866 return output + nChan * sizeof(cmsUInt16Number);
2867 }
2868
2869
2870
2871 static
PackHalfFromFloat(_cmsTRANSFORM * info,cmsFloat32Number wOut[],cmsUInt8Number * output,cmsUInt32Number Stride)2872 cmsUInt8Number* PackHalfFromFloat(_cmsTRANSFORM* info,
2873 cmsFloat32Number wOut[],
2874 cmsUInt8Number* output,
2875 cmsUInt32Number Stride)
2876 {
2877 int nChan = T_CHANNELS(info -> OutputFormat);
2878 int DoSwap = T_DOSWAP(info ->OutputFormat);
2879 int Reverse = T_FLAVOR(info ->OutputFormat);
2880 int Extra = T_EXTRA(info -> OutputFormat);
2881 int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
2882 int Planar = T_PLANAR(info -> OutputFormat);
2883 int ExtraFirst = DoSwap ^ SwapFirst;
2884 cmsFloat32Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0F : 1.0F;
2885 cmsUInt16Number* swap1 = (cmsUInt16Number*) output;
2886 cmsFloat32Number v = 0;
2887 int i, start = 0;
2888
2889 if (ExtraFirst)
2890 start = Extra;
2891
2892 for (i=0; i < nChan; i++) {
2893
2894 int index = DoSwap ? (nChan - i - 1) : i;
2895
2896 v = wOut[index] * maximum;
2897
2898 if (Reverse)
2899 v = maximum - v;
2900
2901 if (Planar)
2902 ((cmsUInt16Number*) output)[(i + start)* Stride]= _cmsFloat2Half( v );
2903 else
2904 ((cmsUInt16Number*) output)[i + start] = _cmsFloat2Half( v );
2905 }
2906
2907 if (!ExtraFirst) {
2908 output += Extra * sizeof(cmsUInt16Number);
2909 }
2910
2911 if (Extra == 0 && SwapFirst) {
2912
2913 memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number));
2914 *swap1 = (cmsUInt16Number) _cmsFloat2Half( v );
2915 }
2916
2917 if (T_PLANAR(info -> OutputFormat))
2918 return output + sizeof(cmsUInt16Number);
2919 else
2920 return output + nChan * sizeof(cmsUInt16Number);
2921 }
2922
2923 #endif
2924
2925 // ----------------------------------------------------------------------------------------------------------------
2926
2927
2928 static cmsFormatters16 InputFormatters16[] = {
2929
2930 // Type Mask Function
2931 // ---------------------------- ------------------------------------ ----------------------------
2932 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, UnrollLabDoubleTo16},
2933 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, UnrollXYZDoubleTo16},
2934 { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, UnrollLabFloatTo16},
2935 { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, UnrollXYZFloatTo16},
2936 { TYPE_GRAY_DBL, 0, UnrollDouble1Chan},
2937 { FLOAT_SH(1)|BYTES_SH(0), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR|
2938 ANYSWAP|ANYEXTRA|ANYSPACE, UnrollDoubleTo16},
2939 { FLOAT_SH(1)|BYTES_SH(4), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR|
2940 ANYSWAP|ANYEXTRA|ANYSPACE, UnrollFloatTo16},
2941 #ifndef CMS_NO_HALF_SUPPORT
2942 { FLOAT_SH(1)|BYTES_SH(2), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR|
2943 ANYEXTRA|ANYSWAP|ANYSPACE, UnrollHalfTo16},
2944 #endif
2945
2946 { CHANNELS_SH(1)|BYTES_SH(1), ANYSPACE, Unroll1Byte},
2947 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Unroll1ByteSkip1},
2948 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(2), ANYSPACE, Unroll1ByteSkip2},
2949 { CHANNELS_SH(1)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Unroll1ByteReversed},
2950 { COLORSPACE_SH(PT_MCH2)|CHANNELS_SH(2)|BYTES_SH(1), 0, Unroll2Bytes},
2951
2952 { TYPE_LabV2_8, 0, UnrollLabV2_8 },
2953 { TYPE_ALabV2_8, 0, UnrollALabV2_8 },
2954 { TYPE_LabV2_16, 0, UnrollLabV2_16 },
2955
2956 { CHANNELS_SH(3)|BYTES_SH(1), ANYSPACE, Unroll3Bytes},
2957 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3BytesSwap},
2958 { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3BytesSkip1Swap},
2959 { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll3BytesSkip1SwapFirst},
2960
2961 { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1),
2962 ANYSPACE, Unroll3BytesSkip1SwapSwapFirst},
2963
2964 { CHANNELS_SH(4)|BYTES_SH(1), ANYSPACE, Unroll4Bytes},
2965 { CHANNELS_SH(4)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Unroll4BytesReverse},
2966 { CHANNELS_SH(4)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4BytesSwapFirst},
2967 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll4BytesSwap},
2968 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4BytesSwapSwapFirst},
2969
2970 { BYTES_SH(1)|PLANAR_SH(1), ANYFLAVOR|ANYSWAPFIRST|
2971 ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollPlanarBytes},
2972
2973 { BYTES_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
2974 ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollChunkyBytes},
2975
2976 { CHANNELS_SH(1)|BYTES_SH(2), ANYSPACE, Unroll1Word},
2977 { CHANNELS_SH(1)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Unroll1WordReversed},
2978 { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(3), ANYSPACE, Unroll1WordSkip3},
2979
2980 { CHANNELS_SH(2)|BYTES_SH(2), ANYSPACE, Unroll2Words},
2981 { CHANNELS_SH(3)|BYTES_SH(2), ANYSPACE, Unroll3Words},
2982 { CHANNELS_SH(4)|BYTES_SH(2), ANYSPACE, Unroll4Words},
2983
2984 { CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Unroll3WordsSwap},
2985 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll3WordsSkip1SwapFirst},
2986 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3WordsSkip1Swap},
2987 { CHANNELS_SH(4)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Unroll4WordsReverse},
2988 { CHANNELS_SH(4)|BYTES_SH(2)|SWAPFIRST_SH(1), ANYSPACE, Unroll4WordsSwapFirst},
2989 { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Unroll4WordsSwap},
2990 { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4WordsSwapSwapFirst},
2991
2992
2993 { BYTES_SH(2)|PLANAR_SH(1), ANYFLAVOR|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollPlanarWords},
2994 { BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollAnyWords},
2995 };
2996
2997
2998
2999 static cmsFormattersFloat InputFormattersFloat[] = {
3000
3001 // Type Mask Function
3002 // ---------------------------- ------------------------------------ ----------------------------
3003 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, UnrollLabDoubleToFloat},
3004 { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, UnrollLabFloatToFloat},
3005
3006 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, UnrollXYZDoubleToFloat},
3007 { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, UnrollXYZFloatToFloat},
3008
3009 { FLOAT_SH(1)|BYTES_SH(4), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
3010 ANYCHANNELS|ANYSPACE, UnrollFloatsToFloat},
3011
3012 { FLOAT_SH(1)|BYTES_SH(0), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
3013 ANYCHANNELS|ANYSPACE, UnrollDoublesToFloat},
3014 #ifndef CMS_NO_HALF_SUPPORT
3015 { FLOAT_SH(1)|BYTES_SH(2), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
3016 ANYCHANNELS|ANYSPACE, UnrollHalfToFloat},
3017 #endif
3018 };
3019
3020
3021 // Bit fields set to one in the mask are not compared
3022 static
_cmsGetStockInputFormatter(cmsUInt32Number dwInput,cmsUInt32Number dwFlags)3023 cmsFormatter _cmsGetStockInputFormatter(cmsUInt32Number dwInput, cmsUInt32Number dwFlags)
3024 {
3025 cmsUInt32Number i;
3026 cmsFormatter fr;
3027
3028 switch (dwFlags) {
3029
3030 case CMS_PACK_FLAGS_16BITS: {
3031 for (i=0; i < sizeof(InputFormatters16) / sizeof(cmsFormatters16); i++) {
3032 cmsFormatters16* f = InputFormatters16 + i;
3033
3034 if ((dwInput & ~f ->Mask) == f ->Type) {
3035 fr.Fmt16 = f ->Frm;
3036 return fr;
3037 }
3038 }
3039 }
3040 break;
3041
3042 case CMS_PACK_FLAGS_FLOAT: {
3043 for (i=0; i < sizeof(InputFormattersFloat) / sizeof(cmsFormattersFloat); i++) {
3044 cmsFormattersFloat* f = InputFormattersFloat + i;
3045
3046 if ((dwInput & ~f ->Mask) == f ->Type) {
3047 fr.FmtFloat = f ->Frm;
3048 return fr;
3049 }
3050 }
3051 }
3052 break;
3053
3054 default:;
3055
3056 }
3057
3058 fr.Fmt16 = NULL;
3059 return fr;
3060 }
3061
3062 static cmsFormatters16 OutputFormatters16[] = {
3063 // Type Mask Function
3064 // ---------------------------- ------------------------------------ ----------------------------
3065
3066 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, PackLabDoubleFrom16},
3067 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, PackXYZDoubleFrom16},
3068
3069 { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, PackLabFloatFrom16},
3070 { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, PackXYZFloatFrom16},
3071
3072 { FLOAT_SH(1)|BYTES_SH(0), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
3073 ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackDoubleFrom16},
3074 { FLOAT_SH(1)|BYTES_SH(4), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
3075 ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackFloatFrom16},
3076 #ifndef CMS_NO_HALF_SUPPORT
3077 { FLOAT_SH(1)|BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
3078 ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackHalfFrom16},
3079 #endif
3080
3081 { CHANNELS_SH(1)|BYTES_SH(1), ANYSPACE, Pack1Byte},
3082 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Pack1ByteSkip1},
3083 { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack1ByteSkip1SwapFirst},
3084
3085 { CHANNELS_SH(1)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Pack1ByteReversed},
3086
3087 { TYPE_LabV2_8, 0, PackLabV2_8 },
3088 { TYPE_ALabV2_8, 0, PackALabV2_8 },
3089 { TYPE_LabV2_16, 0, PackLabV2_16 },
3090
3091 { CHANNELS_SH(3)|BYTES_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesOptimized},
3092 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesAndSkip1Optimized},
3093 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1)|OPTIMIZED_SH(1),
3094 ANYSPACE, Pack3BytesAndSkip1SwapFirstOptimized},
3095 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1)|OPTIMIZED_SH(1),
3096 ANYSPACE, Pack3BytesAndSkip1SwapSwapFirstOptimized},
3097 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|EXTRA_SH(1)|OPTIMIZED_SH(1),
3098 ANYSPACE, Pack3BytesAndSkip1SwapOptimized},
3099 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|OPTIMIZED_SH(1), ANYSPACE, Pack3BytesSwapOptimized},
3100
3101
3102
3103 { CHANNELS_SH(3)|BYTES_SH(1), ANYSPACE, Pack3Bytes},
3104 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Pack3BytesAndSkip1},
3105 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack3BytesAndSkip1SwapFirst},
3106 { CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1),
3107 ANYSPACE, Pack3BytesAndSkip1SwapSwapFirst},
3108 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|EXTRA_SH(1), ANYSPACE, Pack3BytesAndSkip1Swap},
3109 { CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack3BytesSwap},
3110 { CHANNELS_SH(6)|BYTES_SH(1), ANYSPACE, Pack6Bytes},
3111 { CHANNELS_SH(6)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack6BytesSwap},
3112 { CHANNELS_SH(4)|BYTES_SH(1), ANYSPACE, Pack4Bytes},
3113 { CHANNELS_SH(4)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Pack4BytesReverse},
3114 { CHANNELS_SH(4)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack4BytesSwapFirst},
3115 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack4BytesSwap},
3116 { CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack4BytesSwapSwapFirst},
3117
3118 { BYTES_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackAnyBytes},
3119 { BYTES_SH(1)|PLANAR_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackPlanarBytes},
3120
3121 { CHANNELS_SH(1)|BYTES_SH(2), ANYSPACE, Pack1Word},
3122 { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(1), ANYSPACE, Pack1WordSkip1},
3123 { CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack1WordSkip1SwapFirst},
3124 { CHANNELS_SH(1)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Pack1WordReversed},
3125 { CHANNELS_SH(1)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack1WordBigEndian},
3126 { CHANNELS_SH(3)|BYTES_SH(2), ANYSPACE, Pack3Words},
3127 { CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack3WordsSwap},
3128 { CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack3WordsBigEndian},
3129 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1), ANYSPACE, Pack3WordsAndSkip1},
3130 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1), ANYSPACE, Pack3WordsAndSkip1Swap},
3131 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack3WordsAndSkip1SwapFirst},
3132
3133 { CHANNELS_SH(3)|BYTES_SH(2)|EXTRA_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1),
3134 ANYSPACE, Pack3WordsAndSkip1SwapSwapFirst},
3135
3136 { CHANNELS_SH(4)|BYTES_SH(2), ANYSPACE, Pack4Words},
3137 { CHANNELS_SH(4)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Pack4WordsReverse},
3138 { CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack4WordsSwap},
3139 { CHANNELS_SH(4)|BYTES_SH(2)|ENDIAN16_SH(1), ANYSPACE, Pack4WordsBigEndian},
3140
3141 { CHANNELS_SH(6)|BYTES_SH(2), ANYSPACE, Pack6Words},
3142 { CHANNELS_SH(6)|BYTES_SH(2)|DOSWAP_SH(1), ANYSPACE, Pack6WordsSwap},
3143
3144 { BYTES_SH(2)|PLANAR_SH(1), ANYFLAVOR|ANYENDIAN|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackPlanarWords},
3145 { BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackAnyWords}
3146
3147 };
3148
3149
3150 static cmsFormattersFloat OutputFormattersFloat[] = {
3151 // Type Mask Function
3152 // ---------------------------- --------------------------------------------------- ----------------------------
3153 { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, PackLabFloatFromFloat},
3154 { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, PackXYZFloatFromFloat},
3155
3156 { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, PackLabDoubleFromFloat},
3157 { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, PackXYZDoubleFromFloat},
3158
3159 { FLOAT_SH(1)|BYTES_SH(4), ANYPLANAR|
3160 ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackFloatsFromFloat },
3161 { FLOAT_SH(1)|BYTES_SH(0), ANYPLANAR|
3162 ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackDoublesFromFloat },
3163 #ifndef CMS_NO_HALF_SUPPORT
3164 { FLOAT_SH(1)|BYTES_SH(2),
3165 ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackHalfFromFloat },
3166 #endif
3167
3168
3169
3170 };
3171
3172
3173 // Bit fields set to one in the mask are not compared
3174 static
_cmsGetStockOutputFormatter(cmsUInt32Number dwInput,cmsUInt32Number dwFlags)3175 cmsFormatter _cmsGetStockOutputFormatter(cmsUInt32Number dwInput, cmsUInt32Number dwFlags)
3176 {
3177 cmsUInt32Number i;
3178 cmsFormatter fr;
3179
3180
3181 switch (dwFlags)
3182 {
3183
3184 case CMS_PACK_FLAGS_16BITS: {
3185
3186 for (i=0; i < sizeof(OutputFormatters16) / sizeof(cmsFormatters16); i++) {
3187 cmsFormatters16* f = OutputFormatters16 + i;
3188
3189 if ((dwInput & ~f ->Mask) == f ->Type) {
3190 fr.Fmt16 = f ->Frm;
3191 return fr;
3192 }
3193 }
3194 }
3195 break;
3196
3197 case CMS_PACK_FLAGS_FLOAT: {
3198
3199 for (i=0; i < sizeof(OutputFormattersFloat) / sizeof(cmsFormattersFloat); i++) {
3200 cmsFormattersFloat* f = OutputFormattersFloat + i;
3201
3202 if ((dwInput & ~f ->Mask) == f ->Type) {
3203 fr.FmtFloat = f ->Frm;
3204 return fr;
3205 }
3206 }
3207 }
3208 break;
3209
3210 default:;
3211
3212 }
3213
3214 fr.Fmt16 = NULL;
3215 return fr;
3216 }
3217
3218
3219 typedef struct _cms_formatters_factory_list {
3220
3221 cmsFormatterFactory Factory;
3222 struct _cms_formatters_factory_list *Next;
3223
3224 } cmsFormattersFactoryList;
3225
3226 _cmsFormattersPluginChunkType _cmsFormattersPluginChunk = { NULL };
3227
3228
3229 // Duplicates the zone of memory used by the plug-in in the new context
3230 static
DupFormatterFactoryList(struct _cmsContext_struct * ctx,const struct _cmsContext_struct * src)3231 void DupFormatterFactoryList(struct _cmsContext_struct* ctx,
3232 const struct _cmsContext_struct* src)
3233 {
3234 _cmsFormattersPluginChunkType newHead = { NULL };
3235 cmsFormattersFactoryList* entry;
3236 cmsFormattersFactoryList* Anterior = NULL;
3237 _cmsFormattersPluginChunkType* head = (_cmsFormattersPluginChunkType*) src->chunks[FormattersPlugin];
3238
3239 _cmsAssert(head != NULL);
3240
3241 // Walk the list copying all nodes
3242 for (entry = head->FactoryList;
3243 entry != NULL;
3244 entry = entry ->Next) {
3245
3246 cmsFormattersFactoryList *newEntry = ( cmsFormattersFactoryList *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(cmsFormattersFactoryList));
3247
3248 if (newEntry == NULL)
3249 return;
3250
3251 // We want to keep the linked list order, so this is a little bit tricky
3252 newEntry -> Next = NULL;
3253 if (Anterior)
3254 Anterior -> Next = newEntry;
3255
3256 Anterior = newEntry;
3257
3258 if (newHead.FactoryList == NULL)
3259 newHead.FactoryList = newEntry;
3260 }
3261
3262 ctx ->chunks[FormattersPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsFormattersPluginChunkType));
3263 }
3264
3265 // The interpolation plug-in memory chunk allocator/dup
_cmsAllocFormattersPluginChunk(struct _cmsContext_struct * ctx,const struct _cmsContext_struct * src)3266 void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct* ctx,
3267 const struct _cmsContext_struct* src)
3268 {
3269 _cmsAssert(ctx != NULL);
3270
3271 if (src != NULL) {
3272
3273 // Duplicate the LIST
3274 DupFormatterFactoryList(ctx, src);
3275 }
3276 else {
3277 static _cmsFormattersPluginChunkType FormattersPluginChunk = { NULL };
3278 ctx ->chunks[FormattersPlugin] = _cmsSubAllocDup(ctx ->MemPool, &FormattersPluginChunk, sizeof(_cmsFormattersPluginChunkType));
3279 }
3280 }
3281
3282
3283
3284 // Formatters management
_cmsRegisterFormattersPlugin(cmsContext ContextID,cmsPluginBase * Data)3285 cmsBool _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Data)
3286 {
3287 _cmsFormattersPluginChunkType* ctx = ( _cmsFormattersPluginChunkType*) _cmsContextGetClientChunk(ContextID, FormattersPlugin);
3288 cmsPluginFormatters* Plugin = (cmsPluginFormatters*) Data;
3289 cmsFormattersFactoryList* fl ;
3290
3291 // Reset to built-in defaults
3292 if (Data == NULL) {
3293
3294 ctx ->FactoryList = NULL;
3295 return TRUE;
3296 }
3297
3298 fl = (cmsFormattersFactoryList*) _cmsPluginMalloc(ContextID, sizeof(cmsFormattersFactoryList));
3299 if (fl == NULL) return FALSE;
3300
3301 fl ->Factory = Plugin ->FormattersFactory;
3302
3303 fl ->Next = ctx -> FactoryList;
3304 ctx ->FactoryList = fl;
3305
3306 return TRUE;
3307 }
3308
_cmsGetFormatter(cmsContext ContextID,cmsUInt32Number Type,cmsFormatterDirection Dir,cmsUInt32Number dwFlags)3309 cmsFormatter _cmsGetFormatter(cmsContext ContextID,
3310 cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8
3311 cmsFormatterDirection Dir,
3312 cmsUInt32Number dwFlags)
3313 {
3314 _cmsFormattersPluginChunkType* ctx = ( _cmsFormattersPluginChunkType*) _cmsContextGetClientChunk(ContextID, FormattersPlugin);
3315 cmsFormattersFactoryList* f;
3316
3317 for (f =ctx->FactoryList; f != NULL; f = f ->Next) {
3318
3319 cmsFormatter fn = f ->Factory(Type, Dir, dwFlags);
3320 if (fn.Fmt16 != NULL) return fn;
3321 }
3322
3323 // Revert to default
3324 if (Dir == cmsFormatterInput)
3325 return _cmsGetStockInputFormatter(Type, dwFlags);
3326 else
3327 return _cmsGetStockOutputFormatter(Type, dwFlags);
3328 }
3329
3330
3331 // Return whatever given formatter refers to float values
_cmsFormatterIsFloat(cmsUInt32Number Type)3332 cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type)
3333 {
3334 return T_FLOAT(Type) ? TRUE : FALSE;
3335 }
3336
3337 // Return whatever given formatter refers to 8 bits
_cmsFormatterIs8bit(cmsUInt32Number Type)3338 cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type)
3339 {
3340 int Bytes = T_BYTES(Type);
3341
3342 return (Bytes == 1);
3343 }
3344
3345 // Build a suitable formatter for the colorspace of this profile
cmsFormatterForColorspaceOfProfile(cmsHPROFILE hProfile,cmsUInt32Number nBytes,cmsBool lIsFloat)3346 cmsUInt32Number CMSEXPORT cmsFormatterForColorspaceOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat)
3347 {
3348
3349 cmsColorSpaceSignature ColorSpace = cmsGetColorSpace(hProfile);
3350 cmsUInt32Number ColorSpaceBits = _cmsLCMScolorSpace(ColorSpace);
3351 cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace);
3352 cmsUInt32Number Float = lIsFloat ? 1 : 0;
3353
3354 // Create a fake formatter for result
3355 return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans);
3356 }
3357
3358 // Build a suitable formatter for the colorspace of this profile
cmsFormatterForPCSOfProfile(cmsHPROFILE hProfile,cmsUInt32Number nBytes,cmsBool lIsFloat)3359 cmsUInt32Number CMSEXPORT cmsFormatterForPCSOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat)
3360 {
3361
3362 cmsColorSpaceSignature ColorSpace = cmsGetPCS(hProfile);
3363 int ColorSpaceBits = _cmsLCMScolorSpace(ColorSpace);
3364 cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace);
3365 cmsUInt32Number Float = lIsFloat ? 1 : 0;
3366
3367 // Create a fake formatter for result
3368 return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans);
3369 }
3370