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