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