1 //  Little cms
2 //  Copyright (C) 1998-2007 Marti Maria
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the "Software"),
6 // to deal in the Software without restriction, including without limitation
7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 // and/or sell copies of the Software, and to permit persons to whom the Software
9 // is furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
16 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 
22 
23 #include "lcms.h"
24 
25 // This module handles all formats supported by lcms
26 
27 
28 // ---------------------------------------------------------------------------
29 
30 
31 // This macro return words stored as big endian
32 
33 #define CHANGE_ENDIAN(w)    (WORD) ((WORD) ((w)<<8)|((w)>>8))
34 
35 // These macros handles reversing (negative)
36 
37 #define REVERSE_FLAVOR_8(x)     ((BYTE) (0xff-(x)))
38 #define REVERSE_FLAVOR_16(x)    ((WORD)(0xffff-(x)))
39 
40 // Supress waning about info never being used
41 
42 #ifdef __BORLANDC__
43 #pragma warn -par
44 #endif
45 
46 #ifdef _MSC_VER
47 #pragma warning(disable : 4100)
48 #endif
49 
50 // -------------------------------------------------------- Unpacking routines.
51 
52 
53 static
UnrollAnyBytes(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)54 LPBYTE UnrollAnyBytes(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
55 {
56        int nChan = T_CHANNELS(info -> InputFormat);
57        register int i;
58 
59        for (i=0; i < nChan; i++) {
60 
61               wIn[i] = RGB_8_TO_16(*accum); accum++;
62        }
63 
64        return accum + T_EXTRA(info -> InputFormat);
65 }
66 
67 
68 
69 static
Unroll4Bytes(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)70 LPBYTE Unroll4Bytes(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
71 {
72        wIn[0] = RGB_8_TO_16(*accum); accum++; // C
73        wIn[1] = RGB_8_TO_16(*accum); accum++; // M
74        wIn[2] = RGB_8_TO_16(*accum); accum++; // Y
75        wIn[3] = RGB_8_TO_16(*accum); accum++; // K
76 
77        return accum;
78 }
79 
80 static
Unroll4BytesReverse(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)81 LPBYTE Unroll4BytesReverse(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
82 {
83        wIn[0] = RGB_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // C
84        wIn[1] = RGB_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // M
85        wIn[2] = RGB_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // Y
86        wIn[3] = RGB_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // K
87 
88        return accum;
89 }
90 
91 
92 static
Unroll4BytesSwapFirst(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)93 LPBYTE Unroll4BytesSwapFirst(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
94 {
95 
96        wIn[3] = RGB_8_TO_16(*accum); accum++; // K
97        wIn[0] = RGB_8_TO_16(*accum); accum++; // C
98        wIn[1] = RGB_8_TO_16(*accum); accum++; // M
99        wIn[2] = RGB_8_TO_16(*accum); accum++; // Y
100 
101 
102        return accum;
103 }
104 
105 
106 
107 // KYMC
108 static
Unroll4BytesSwap(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)109 LPBYTE Unroll4BytesSwap(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
110 {
111        wIn[3] = RGB_8_TO_16(*accum); accum++;  // K
112        wIn[2] = RGB_8_TO_16(*accum); accum++;  // Y
113        wIn[1] = RGB_8_TO_16(*accum); accum++;  // M
114        wIn[0] = RGB_8_TO_16(*accum); accum++;  // C
115 
116        return accum;
117 }
118 
119 
120 static
Unroll4BytesSwapSwapFirst(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)121 LPBYTE Unroll4BytesSwapSwapFirst(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
122 {
123        wIn[2] = RGB_8_TO_16(*accum); accum++;  // K
124        wIn[1] = RGB_8_TO_16(*accum); accum++;  // Y
125        wIn[0] = RGB_8_TO_16(*accum); accum++;  // M
126        wIn[3] = RGB_8_TO_16(*accum); accum++;  // C
127 
128        return accum;
129 }
130 
131 
132 static
UnrollAnyWords(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)133 LPBYTE UnrollAnyWords(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
134 {
135      int nChan = T_CHANNELS(info -> InputFormat);
136      register int i;
137 
138      for (i=0; i < nChan; i++) {
139 
140               wIn[i] = *(LPWORD) accum; accum += 2;
141      }
142 
143      return accum + T_EXTRA(info -> InputFormat) * sizeof(WORD);
144 }
145 
146 
147 static
Unroll4Words(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)148 LPBYTE Unroll4Words(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
149 {
150        wIn[0] = *(LPWORD) accum; accum+= 2; // C
151        wIn[1] = *(LPWORD) accum; accum+= 2; // M
152        wIn[2] = *(LPWORD) accum; accum+= 2; // Y
153        wIn[3] = *(LPWORD) accum; accum+= 2; // K
154 
155        return accum;
156 }
157 
158 static
Unroll4WordsReverse(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)159 LPBYTE Unroll4WordsReverse(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
160 {
161        wIn[0] = REVERSE_FLAVOR_16(*(LPWORD) accum); accum+= 2; // C
162        wIn[1] = REVERSE_FLAVOR_16(*(LPWORD) accum); accum+= 2; // M
163        wIn[2] = REVERSE_FLAVOR_16(*(LPWORD) accum); accum+= 2; // Y
164        wIn[3] = REVERSE_FLAVOR_16(*(LPWORD) accum); accum+= 2; // K
165 
166        return accum;
167 }
168 
169 
170 static
Unroll4WordsSwapFirst(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)171 LPBYTE Unroll4WordsSwapFirst(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
172 {
173        wIn[3] = *(LPWORD) accum; accum+= 2; // K
174        wIn[0] = *(LPWORD) accum; accum+= 2; // C
175        wIn[1] = *(LPWORD) accum; accum+= 2; // M
176        wIn[2] = *(LPWORD) accum; accum+= 2; // Y
177 
178        return accum;
179 }
180 
181 
182 // KYMC
183 static
Unroll4WordsSwap(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)184 LPBYTE Unroll4WordsSwap(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
185 {
186        wIn[3] = *(LPWORD) accum; accum+= 2; // K
187        wIn[2] = *(LPWORD) accum; accum+= 2; // Y
188        wIn[1] = *(LPWORD) accum; accum+= 2; // M
189        wIn[0] = *(LPWORD) accum; accum+= 2; // C
190 
191        return accum;
192 }
193 
194 static
Unroll4WordsSwapSwapFirst(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)195 LPBYTE Unroll4WordsSwapSwapFirst(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
196 {
197        wIn[2] = *(LPWORD) accum; accum+= 2; // K
198        wIn[1] = *(LPWORD) accum; accum+= 2; // Y
199        wIn[0] = *(LPWORD) accum; accum+= 2; // M
200        wIn[3] = *(LPWORD) accum; accum+= 2; // C
201 
202        return accum;
203 }
204 
205 
206 static
Unroll4WordsBigEndian(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)207 LPBYTE Unroll4WordsBigEndian(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
208 {
209        wIn[0] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2; //C
210        wIn[1] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2; //M
211        wIn[2] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2; //Y
212        wIn[3] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2; //K
213 
214        return accum;
215 }
216 
217 static
Unroll4WordsBigEndianReverse(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)218 LPBYTE Unroll4WordsBigEndianReverse(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
219 {
220        wIn[0] = REVERSE_FLAVOR_16(CHANGE_ENDIAN(*(LPWORD) accum)); accum+= 2; //C
221        wIn[1] = REVERSE_FLAVOR_16(CHANGE_ENDIAN(*(LPWORD) accum)); accum+= 2; //M
222        wIn[2] = REVERSE_FLAVOR_16(CHANGE_ENDIAN(*(LPWORD) accum)); accum+= 2; //Y
223        wIn[3] = REVERSE_FLAVOR_16(CHANGE_ENDIAN(*(LPWORD) accum)); accum+= 2; //K
224 
225        return accum;
226 }
227 
228 
229 // KYMC
230 static
Unroll4WordsSwapBigEndian(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)231 LPBYTE Unroll4WordsSwapBigEndian(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
232 {
233        wIn[3] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2; //K
234        wIn[2] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2; //Y
235        wIn[1] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2; //M
236        wIn[0] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2; //C
237 
238        return accum;
239 }
240 
241 static
Unroll3Bytes(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)242 LPBYTE Unroll3Bytes(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
243 {
244 
245        wIn[0] = RGB_8_TO_16(*accum); accum++;     // R
246        wIn[1] = RGB_8_TO_16(*accum); accum++;     // G
247        wIn[2] = RGB_8_TO_16(*accum); accum++;     // B
248 
249        return accum;
250 }
251 
252 
253 // Lab8 encoding using v2 PCS
254 
255 static
Unroll3BytesLab(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)256 LPBYTE Unroll3BytesLab(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
257 {
258 
259        wIn[0] = (WORD) ((*accum) << 8); accum++;
260        wIn[1] = (WORD) ((*accum) << 8); accum++;
261        wIn[2] = (WORD) ((*accum) << 8); accum++;
262 
263        return accum;
264 }
265 
266 
267 // BRG
268 
269 static
Unroll3BytesSwap(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)270 LPBYTE Unroll3BytesSwap(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
271 {
272 
273        wIn[2] = RGB_8_TO_16(*accum); accum++;     // B
274        wIn[1] = RGB_8_TO_16(*accum); accum++;     // G
275        wIn[0] = RGB_8_TO_16(*accum); accum++;     // R
276 
277        return accum;
278 }
279 
280 static
Unroll3Words(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)281 LPBYTE Unroll3Words(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
282 {
283        wIn[0] = *(LPWORD) accum; accum+= 2;  // C R
284        wIn[1] = *(LPWORD) accum; accum+= 2;  // M G
285        wIn[2] = *(LPWORD) accum; accum+= 2;  // Y B
286        return accum;
287 }
288 
289 
290 static
Unroll3WordsSwap(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)291 LPBYTE Unroll3WordsSwap(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
292 {
293        wIn[2] = *(LPWORD) accum; accum+= 2;  // C R
294        wIn[1] = *(LPWORD) accum; accum+= 2;  // M G
295        wIn[0] = *(LPWORD) accum; accum+= 2;  // Y B
296        return accum;
297 }
298 
299 
300 static
Unroll3WordsBigEndian(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)301 LPBYTE Unroll3WordsBigEndian(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
302 {
303        wIn[0] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
304        wIn[1] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
305        wIn[2] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
306        return accum;
307 }
308 
309 
310 static
Unroll3WordsSwapBigEndian(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)311 LPBYTE Unroll3WordsSwapBigEndian(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
312 {
313        wIn[2] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
314        wIn[1] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
315        wIn[0] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
316        return accum;
317 }
318 
319 
320 
321 // Monochrome duplicates L into RGB for null-transforms
322 
323 static
Unroll1Byte(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)324 LPBYTE Unroll1Byte(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
325 {
326        wIn[0] = wIn[1] = wIn[2] = RGB_8_TO_16(*accum); accum++;     // L
327        return accum;
328 }
329 
330 
331 static
Unroll1ByteSkip2(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)332 LPBYTE Unroll1ByteSkip2(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
333 {
334        wIn[0] = wIn[1] = wIn[2] = RGB_8_TO_16(*accum); accum++;     // L
335        accum += 2;
336        return accum;
337 }
338 
339 static
Unroll1ByteReversed(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)340 LPBYTE Unroll1ByteReversed(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
341 {
342        wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(RGB_8_TO_16(*accum)); accum++;     // L
343        return accum;
344 }
345 
346 
347 static
Unroll1Word(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)348 LPBYTE Unroll1Word(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
349 {
350        wIn[0] = wIn[1] = wIn[2] = *(LPWORD) accum; accum+= 2;   // L
351        return accum;
352 }
353 
354 static
Unroll1WordReversed(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)355 LPBYTE Unroll1WordReversed(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
356 {
357        wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(*(LPWORD) accum); accum+= 2;
358        return accum;
359 }
360 
361 
362 static
Unroll1WordBigEndian(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)363 LPBYTE Unroll1WordBigEndian(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
364 {
365        wIn[0] = wIn[1] = wIn[2] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
366        return accum;
367 }
368 
369 static
Unroll1WordSkip3(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)370 LPBYTE Unroll1WordSkip3(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
371 {
372        wIn[0] = wIn[1] = wIn[2] = *(LPWORD) accum;
373 
374        accum += 8;
375        return accum;
376 }
377 
378 
379 // Monochrome + alpha. Alpha is lost
380 
381 static
Unroll2Byte(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)382 LPBYTE Unroll2Byte(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
383 {
384        wIn[0] = wIn[1] = wIn[2] = RGB_8_TO_16(*accum); accum++;     // L
385        wIn[3] = RGB_8_TO_16(*accum); accum++;                       // alpha
386        return accum;
387 }
388 
389 static
Unroll2ByteSwapFirst(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)390 LPBYTE Unroll2ByteSwapFirst(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
391 {
392        wIn[3] = RGB_8_TO_16(*accum); accum++;                       // alpha
393        wIn[0] = wIn[1] = wIn[2] = RGB_8_TO_16(*accum); accum++;     // L
394        return accum;
395 }
396 
397 
398 static
Unroll2Word(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)399 LPBYTE Unroll2Word(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
400 {
401        wIn[0] = wIn[1] = wIn[2] = *(LPWORD) accum; accum+= 2;   // L
402        wIn[3] = *(LPWORD) accum; accum += 2;                    // alpha
403 
404        return accum;
405 }
406 
407 
408 static
Unroll2WordSwapFirst(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)409 LPBYTE Unroll2WordSwapFirst(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
410 {
411        wIn[3] = *(LPWORD) accum; accum += 2;                    // alpha
412        wIn[0] = wIn[1] = wIn[2] = *(LPWORD) accum; accum+= 2;   // L
413 
414        return accum;
415 }
416 
417 static
Unroll2WordBigEndian(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)418 LPBYTE Unroll2WordBigEndian(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
419 {
420        wIn[0] = wIn[1] = wIn[2] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
421        wIn[3] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
422 
423        return accum;
424 }
425 
426 
427 
428 
429 static
UnrollPlanarBytes(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)430 LPBYTE UnrollPlanarBytes(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
431 {
432        int nChan = T_CHANNELS(info -> InputFormat);
433        register int i;
434        LPBYTE Init = accum;
435 
436        for (i=0; i < nChan; i++) {
437 
438               wIn[i] = RGB_8_TO_16(*accum);
439               accum += info -> StrideIn;
440        }
441 
442        return (Init + 1);
443 }
444 
445 
446 
447 static
UnrollPlanarWords(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)448 LPBYTE UnrollPlanarWords(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
449 {
450        int nChan = T_CHANNELS(info -> InputFormat);
451        register int i;
452        LPBYTE Init = accum;
453 
454        for (i=0; i < nChan; i++) {
455 
456               wIn[i] = *(LPWORD) accum;
457               accum += (info -> StrideIn * sizeof(WORD));
458        }
459 
460        return (Init + sizeof(WORD));
461 }
462 
463 
464 
465 static
UnrollPlanarWordsBigEndian(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)466 LPBYTE UnrollPlanarWordsBigEndian(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
467 {
468        int nChan = T_CHANNELS(info -> InputFormat);
469        register int i;
470        LPBYTE Init = accum;
471 
472        for (i=0; i < nChan; i++) {
473 
474               wIn[i] = CHANGE_ENDIAN(*(LPWORD) accum);
475               accum += (info -> StrideIn * sizeof(WORD));
476        }
477 
478        return (Init + sizeof(WORD));
479 }
480 
481 
482 // floating point
483 static
UnrollLabDouble(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)484 LPBYTE UnrollLabDouble(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
485 {
486 
487     if (T_PLANAR(info -> InputFormat)) {
488 
489         double* Pt = (double*) accum;
490 
491         cmsCIELab Lab;
492 
493         Lab.L = Pt[0];
494         Lab.a = Pt[info->StrideIn];
495         Lab.b = Pt[info->StrideIn*2];
496 
497         if (info ->lInputV4Lab)
498             cmsFloat2LabEncoded4(wIn, &Lab);
499         else
500             cmsFloat2LabEncoded(wIn, &Lab);
501 
502         return accum + sizeof(double);
503     }
504     else {
505 
506         if (info ->lInputV4Lab)
507             cmsFloat2LabEncoded4(wIn, (LPcmsCIELab) accum);
508         else
509             cmsFloat2LabEncoded(wIn, (LPcmsCIELab) accum);
510 
511         accum += sizeof(cmsCIELab);
512 
513         return accum;
514     }
515 }
516 
517 static
UnrollXYZDouble(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)518 LPBYTE UnrollXYZDouble(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
519 {
520     if (T_PLANAR(info -> InputFormat)) {
521 
522         double* Pt = (double*) accum;
523         cmsCIEXYZ XYZ;
524 
525         XYZ.X = Pt[0];
526         XYZ.Y = Pt[info->StrideIn];
527         XYZ.Z = Pt[info->StrideIn*2];
528         cmsFloat2XYZEncoded(wIn, &XYZ);
529 
530         return accum + sizeof(double);
531 
532     }
533 
534     else {
535 
536 
537         cmsFloat2XYZEncoded(wIn, (LPcmsCIEXYZ) accum);
538         accum += sizeof(cmsCIEXYZ);
539 
540         return accum;
541     }
542 }
543 
544 
545 
546 // Inks does come in percentage
547 static
UnrollInkDouble(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)548 LPBYTE UnrollInkDouble(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
549 {
550     double* Inks = (double*) accum;
551     int nChan  = T_CHANNELS(info -> InputFormat);
552     int Planar = T_PLANAR(info -> InputFormat);
553     int i;
554     double v;
555 
556     for (i=0; i <  nChan; i++) {
557 
558         if (Planar)
559 
560             v = Inks[i * info ->StrideIn];
561         else
562             v = Inks[i];
563 
564         v = floor(v * 655.35 + 0.5);
565 
566         if (v > 65535.0) v = 65535.0;
567         if (v < 0) v = 0;
568 
569         wIn[i] = (WORD) v;
570     }
571 
572     if (T_PLANAR(info -> InputFormat))
573         return accum + sizeof(double);
574     else
575         return accum + (nChan + T_EXTRA(info ->InputFormat)) * sizeof(double);
576 }
577 
578 
579 // Remaining cases are between 0..1.0
580 static
UnrollDouble(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)581 LPBYTE UnrollDouble(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
582 {
583     double* Inks = (double*) accum;
584     int nChan = T_CHANNELS(info -> InputFormat);
585     int Planar = T_PLANAR(info -> InputFormat);
586     int i;
587     double v;
588 
589     for (i=0; i < nChan; i++) {
590 
591         if (Planar)
592 
593             v = Inks[i * info ->StrideIn];
594         else
595             v = Inks[i];
596 
597         v = floor(v * 65535.0 + 0.5);
598 
599         if (v > 65535.0) v = 65535.0;
600         if (v < 0) v = 0;
601 
602         wIn[i] = (WORD) v;
603     }
604 
605     if (T_PLANAR(info -> InputFormat))
606         return accum + sizeof(double);
607     else
608         return accum + (nChan + T_EXTRA(info ->InputFormat)) * sizeof(double);
609 }
610 
611 
612 
613 static
UnrollDouble1Chan(register _LPcmsTRANSFORM info,register WORD wIn[],register LPBYTE accum)614 LPBYTE UnrollDouble1Chan(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
615 {
616     double* Inks = (double*) accum;
617     double v;
618 
619 
620     v = floor(Inks[0] * 65535.0 + 0.5);
621 
622     if (v > 65535.0) v = 65535.0;
623     if (v < 0) v = 0;
624 
625 
626     wIn[0] = wIn[1] = wIn[2] = (WORD) v;
627 
628     return accum + sizeof(double);
629 }
630 
631 
632 // ----------------------------------------------------------- Packing routines
633 
634 
635 // Generic N-bytes plus dither 16-to-8 conversion. Currently is just a quick hack
636 
637 static int err[MAXCHANNELS];
638 
639 static
PackNBytesDither(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)640 LPBYTE PackNBytesDither(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
641 {
642        int nChan  = T_CHANNELS(info -> OutputFormat);
643        register int i;
644        unsigned int n, pe, pf;
645 
646        for (i=0; i < nChan;  i++) {
647 
648               n = wOut[i] + err[i]; // Value
649 
650               pe = (n / 257);       // Whole part
651               pf = (n % 257);       // Fractional part
652 
653               err[i] = pf;          // Store it for next pixel
654 
655               *output++ = (BYTE) pe;
656        }
657 
658        return output + T_EXTRA(info ->OutputFormat);
659 }
660 
661 
662 
663 static
PackNBytesSwapDither(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)664 LPBYTE PackNBytesSwapDither(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
665 {
666        int nChan  = T_CHANNELS(info -> OutputFormat);
667        register int i;
668        unsigned int n, pe, pf;
669 
670        for (i=nChan-1; i >= 0;  --i) {
671 
672               n = wOut[i] + err[i];     // Value
673 
674               pe = (n / 257);           // Whole part
675               pf = (n % 257);           // Fractional part
676 
677               err[i] = pf;              // Store it for next pixel
678 
679               *output++ = (BYTE) pe;
680        }
681 
682 
683        return output + T_EXTRA(info ->OutputFormat);
684 }
685 
686 
687 
688 // Generic chunky for byte
689 
690 static
PackNBytes(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)691 LPBYTE PackNBytes(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
692 {
693        int nChan  = T_CHANNELS(info -> OutputFormat);
694        register int i;
695 
696        for (i=0; i < nChan;  i++)
697               *output++ = RGB_16_TO_8(wOut[i]);
698 
699        return output + T_EXTRA(info ->OutputFormat);
700 }
701 
702 // Chunky reversed order bytes
703 
704 static
PackNBytesSwap(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)705 LPBYTE PackNBytesSwap(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
706 {
707        int nChan  = T_CHANNELS(info -> OutputFormat);
708        register int i;
709 
710        for (i=nChan-1; i >= 0;  --i)
711               *output++ = RGB_16_TO_8(wOut[i]);
712 
713        return output + T_EXTRA(info ->OutputFormat);
714 
715 }
716 
717 
718 static
PackNWords(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)719 LPBYTE PackNWords(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
720 {
721        int nChan  = T_CHANNELS(info -> OutputFormat);
722        register int i;
723 
724        for (i=0; i < nChan; i++) {
725               *(LPWORD) output = wOut[i];
726               output += sizeof(WORD);
727        }
728 
729        return output + T_EXTRA(info ->OutputFormat) * sizeof(WORD);
730 }
731 
732 static
PackNWordsSwap(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)733 LPBYTE PackNWordsSwap(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
734 {
735        int nChan  = T_CHANNELS(info -> OutputFormat);
736        register int i;
737 
738        for (i=nChan-1; i >= 0; --i) {
739               *(LPWORD) output = wOut[i];
740               output += sizeof(WORD);
741        }
742 
743        return output + T_EXTRA(info ->OutputFormat) * sizeof(WORD);
744 }
745 
746 
747 
748 static
PackNWordsBigEndian(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)749 LPBYTE PackNWordsBigEndian(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
750 {
751        int nChan  = T_CHANNELS(info -> OutputFormat);
752        register int i;
753 
754        for (i=0; i < nChan; i++) {
755               *(LPWORD) output = CHANGE_ENDIAN(wOut[i]);
756               output += sizeof(WORD);
757        }
758 
759        return output + T_EXTRA(info ->OutputFormat) * sizeof(WORD);
760 }
761 
762 
763 static
PackNWordsSwapBigEndian(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)764 LPBYTE PackNWordsSwapBigEndian(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
765 {
766        int nChan  = T_CHANNELS(info -> OutputFormat);
767        register int i;
768 
769        for (i=nChan-1; i >= 0; --i) {
770               *(LPWORD) output = CHANGE_ENDIAN(wOut[i]);
771               output += sizeof(WORD);
772        }
773 
774        return output + T_EXTRA(info ->OutputFormat) * sizeof(WORD);
775 }
776 
777 
778 static
PackPlanarBytes(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)779 LPBYTE PackPlanarBytes(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
780 {
781        int nChan = T_CHANNELS(info -> OutputFormat);
782        register int i;
783        LPBYTE Init = output;
784 
785        for (i=0; i < nChan; i++) {
786 
787               *(LPBYTE) output = RGB_16_TO_8(wOut[i]);
788               output += info -> StrideOut;
789        }
790 
791        return (Init + 1);
792 }
793 
794 
795 static
PackPlanarWords(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)796 LPBYTE PackPlanarWords(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
797 {
798        int nChan = T_CHANNELS(info -> OutputFormat);
799        register int i;
800        LPBYTE Init = output;
801 
802        for (i=0; i < nChan; i++) {
803 
804               *(LPWORD) output = wOut[i];
805               output += (info -> StrideOut * sizeof(WORD));
806        }
807 
808        return (Init + 2);
809 }
810 
811 
812 // CMYKcm (unrolled for speed)
813 
814 static
Pack6Bytes(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)815 LPBYTE Pack6Bytes(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
816 {
817          *output++ = RGB_16_TO_8(wOut[0]);
818          *output++ = RGB_16_TO_8(wOut[1]);
819          *output++ = RGB_16_TO_8(wOut[2]);
820          *output++ = RGB_16_TO_8(wOut[3]);
821          *output++ = RGB_16_TO_8(wOut[4]);
822          *output++ = RGB_16_TO_8(wOut[5]);
823 
824          return output;
825 }
826 
827 // KCMYcm
828 
829 static
Pack6BytesSwap(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)830 LPBYTE Pack6BytesSwap(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
831 {
832        *output++ = RGB_16_TO_8(wOut[3]);
833        *output++ = RGB_16_TO_8(wOut[0]);
834        *output++ = RGB_16_TO_8(wOut[1]);
835        *output++ = RGB_16_TO_8(wOut[2]);
836        *output++ = RGB_16_TO_8(wOut[4]);
837        *output++ = RGB_16_TO_8(wOut[5]);
838 
839        return output;
840 }
841 
842 // CMYKcm
843 static
Pack6Words(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)844 LPBYTE Pack6Words(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
845 {
846        *(LPWORD) output = wOut[0];
847        output+= 2;
848        *(LPWORD) output = wOut[1];
849        output+= 2;
850        *(LPWORD) output = wOut[2];
851        output+= 2;
852        *(LPWORD) output = wOut[3];
853        output+= 2;
854        *(LPWORD) output = wOut[4];
855        output+= 2;
856        *(LPWORD) output = wOut[5];
857        output+= 2;
858 
859        return output;
860 }
861 
862 // KCMYcm
863 static
Pack6WordsSwap(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)864 LPBYTE Pack6WordsSwap(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
865 {
866        *(LPWORD) output = wOut[3];
867        output+= 2;
868        *(LPWORD) output = wOut[0];
869        output+= 2;
870        *(LPWORD) output = wOut[1];
871        output+= 2;
872        *(LPWORD) output = wOut[2];
873        output+= 2;
874        *(LPWORD) output = wOut[4];
875        output+= 2;
876        *(LPWORD) output = wOut[5];
877        output+= 2;
878 
879        return output;
880 }
881 
882 // CMYKcm
883 static
Pack6WordsBigEndian(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)884 LPBYTE Pack6WordsBigEndian(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
885 {
886        *(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
887        output+= 2;
888        *(LPWORD) output = CHANGE_ENDIAN(wOut[1]);
889        output+= 2;
890        *(LPWORD) output = CHANGE_ENDIAN(wOut[2]);
891        output+= 2;
892        *(LPWORD) output = CHANGE_ENDIAN(wOut[3]);
893        output+= 2;
894        *(LPWORD) output = CHANGE_ENDIAN(wOut[4]);
895        output+= 2;
896        *(LPWORD) output = CHANGE_ENDIAN(wOut[5]);
897        output+= 2;
898 
899        return output;
900 }
901 
902 // KCMYcm
903 static
Pack6WordsSwapBigEndian(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)904 LPBYTE Pack6WordsSwapBigEndian(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
905 {
906        *(LPWORD) output = CHANGE_ENDIAN(wOut[3]);
907        output+= 2;
908        *(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
909        output+= 2;
910        *(LPWORD) output = CHANGE_ENDIAN(wOut[1]);
911        output+= 2;
912        *(LPWORD) output = CHANGE_ENDIAN(wOut[2]);
913        output+= 2;
914        *(LPWORD) output = CHANGE_ENDIAN(wOut[4]);
915        output+= 2;
916        *(LPWORD) output = CHANGE_ENDIAN(wOut[5]);
917        output+= 2;
918 
919        return output;
920 }
921 
922 
923 static
Pack4Bytes(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)924 LPBYTE Pack4Bytes(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
925 {
926          *output++ = RGB_16_TO_8(wOut[0]);
927          *output++ = RGB_16_TO_8(wOut[1]);
928          *output++ = RGB_16_TO_8(wOut[2]);
929          *output++ = RGB_16_TO_8(wOut[3]);
930 
931          return output;
932 }
933 
934 static
Pack4BytesReverse(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)935 LPBYTE Pack4BytesReverse(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
936 {
937          *output++ = REVERSE_FLAVOR_8(RGB_16_TO_8(wOut[0]));
938          *output++ = REVERSE_FLAVOR_8(RGB_16_TO_8(wOut[1]));
939          *output++ = REVERSE_FLAVOR_8(RGB_16_TO_8(wOut[2]));
940          *output++ = REVERSE_FLAVOR_8(RGB_16_TO_8(wOut[3]));
941 
942          return output;
943 }
944 
945 
946 static
Pack4BytesSwapFirst(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)947 LPBYTE Pack4BytesSwapFirst(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
948 {
949          *output++ = RGB_16_TO_8(wOut[3]);
950          *output++ = RGB_16_TO_8(wOut[0]);
951          *output++ = RGB_16_TO_8(wOut[1]);
952          *output++ = RGB_16_TO_8(wOut[2]);
953 
954          return output;
955 }
956 
957 
958 // ABGR
959 
960 static
Pack4BytesSwap(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)961 LPBYTE Pack4BytesSwap(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
962 {
963        *output++ = RGB_16_TO_8(wOut[3]);
964        *output++ = RGB_16_TO_8(wOut[2]);
965        *output++ = RGB_16_TO_8(wOut[1]);
966        *output++ = RGB_16_TO_8(wOut[0]);
967 
968        return output;
969 }
970 
971 
972 static
Pack4BytesSwapSwapFirst(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)973 LPBYTE Pack4BytesSwapSwapFirst(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
974 {
975        *output++ = RGB_16_TO_8(wOut[2]);
976        *output++ = RGB_16_TO_8(wOut[1]);
977        *output++ = RGB_16_TO_8(wOut[0]);
978        *output++ = RGB_16_TO_8(wOut[3]);
979 
980        return output;
981 }
982 
983 
984 static
Pack4Words(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)985 LPBYTE Pack4Words(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
986 {
987        *(LPWORD) output = wOut[0];
988        output+= 2;
989        *(LPWORD) output = wOut[1];
990        output+= 2;
991        *(LPWORD) output = wOut[2];
992        output+= 2;
993        *(LPWORD) output = wOut[3];
994        output+= 2;
995 
996        return output;
997 }
998 
999 
1000 static
Pack4WordsReverse(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)1001 LPBYTE Pack4WordsReverse(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
1002 {
1003        *(LPWORD) output = REVERSE_FLAVOR_16(wOut[0]);
1004        output+= 2;
1005        *(LPWORD) output = REVERSE_FLAVOR_16(wOut[1]);
1006        output+= 2;
1007        *(LPWORD) output = REVERSE_FLAVOR_16(wOut[2]);
1008        output+= 2;
1009        *(LPWORD) output = REVERSE_FLAVOR_16(wOut[3]);
1010        output+= 2;
1011 
1012        return output;
1013 }
1014 
1015 // ABGR
1016 
1017 static
Pack4WordsSwap(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)1018 LPBYTE Pack4WordsSwap(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
1019 {
1020        *(LPWORD) output = wOut[3];
1021        output+= 2;
1022        *(LPWORD) output = wOut[2];
1023        output+= 2;
1024        *(LPWORD) output = wOut[1];
1025        output+= 2;
1026        *(LPWORD) output = wOut[0];
1027        output+= 2;
1028 
1029        return output;
1030 }
1031 
1032 // CMYK
1033 static
Pack4WordsBigEndian(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)1034 LPBYTE Pack4WordsBigEndian(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
1035 {
1036        *(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
1037        output+= 2;
1038        *(LPWORD) output = CHANGE_ENDIAN(wOut[1]);
1039        output+= 2;
1040        *(LPWORD) output = CHANGE_ENDIAN(wOut[2]);
1041        output+= 2;
1042        *(LPWORD) output = CHANGE_ENDIAN(wOut[3]);
1043        output+= 2;
1044 
1045        return output;
1046 }
1047 
1048 
1049 static
Pack4WordsBigEndianReverse(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)1050 LPBYTE Pack4WordsBigEndianReverse(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
1051 {
1052        *(LPWORD) output = CHANGE_ENDIAN(REVERSE_FLAVOR_16(wOut[0]));
1053        output+= 2;
1054        *(LPWORD) output = CHANGE_ENDIAN(REVERSE_FLAVOR_16(wOut[1]));
1055        output+= 2;
1056        *(LPWORD) output = CHANGE_ENDIAN(REVERSE_FLAVOR_16(wOut[2]));
1057        output+= 2;
1058        *(LPWORD) output = CHANGE_ENDIAN(REVERSE_FLAVOR_16(wOut[3]));
1059        output+= 2;
1060 
1061        return output;
1062 }
1063 
1064 // KYMC
1065 
1066 static
Pack4WordsSwapBigEndian(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)1067 LPBYTE Pack4WordsSwapBigEndian(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
1068 {
1069        *(LPWORD) output = CHANGE_ENDIAN(wOut[3]);
1070        output+= 2;
1071        *(LPWORD) output = CHANGE_ENDIAN(wOut[2]);
1072        output+= 2;
1073        *(LPWORD) output = CHANGE_ENDIAN(wOut[1]);
1074        output+= 2;
1075        *(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
1076        output+= 2;
1077 
1078        return output;
1079 }
1080 
1081 static
Pack3Bytes(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)1082 LPBYTE Pack3Bytes(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
1083 {
1084        *output++ = RGB_16_TO_8(wOut[0]);
1085        *output++ = RGB_16_TO_8(wOut[1]);
1086        *output++ = RGB_16_TO_8(wOut[2]);
1087 
1088        return output;
1089 }
1090 
1091 static
Pack3BytesLab(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)1092 LPBYTE Pack3BytesLab(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
1093 {
1094        *output++ = (BYTE) (wOut[0] >> 8);
1095        *output++ = (BYTE) (wOut[1] >> 8);
1096        *output++ = (BYTE) (wOut[2] >> 8);
1097 
1098        return output;
1099 }
1100 
1101 
1102 static
Pack3BytesSwap(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)1103 LPBYTE Pack3BytesSwap(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
1104 {
1105        *output++ = RGB_16_TO_8(wOut[2]);
1106        *output++ = RGB_16_TO_8(wOut[1]);
1107        *output++ = RGB_16_TO_8(wOut[0]);
1108 
1109        return output;
1110 }
1111 
1112 
1113 static
Pack3Words(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)1114 LPBYTE Pack3Words(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
1115 {
1116        *(LPWORD) output = wOut[0];
1117        output+= 2;
1118        *(LPWORD) output = wOut[1];
1119        output+= 2;
1120        *(LPWORD) output = wOut[2];
1121        output+= 2;
1122 
1123        return output;
1124 }
1125 
1126 static
Pack3WordsSwap(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)1127 LPBYTE Pack3WordsSwap(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
1128 {
1129        *(LPWORD) output = wOut[2];
1130        output+= 2;
1131        *(LPWORD) output = wOut[1];
1132        output+= 2;
1133        *(LPWORD) output = wOut[0];
1134        output+= 2;
1135 
1136        return output;
1137 }
1138 
1139 static
Pack3WordsBigEndian(register _LPcmsTRANSFORM info,register WORD wOut[],register LPBYTE output)1140 LPBYTE Pack3WordsBigEndian(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
1141 {
1142        *(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
1143        output+= 2;
1144        *(LPWORD) output = CHANGE_ENDIAN(wOut[1]);
1145        output+= 2;
1146        *(LPWORD) output = CHANGE_ENDIAN(wOut[2]);
1147        output+= 2;
1148 
1149        return output;
1150 }
1151 
1152 
1153 static
Pack3WordsSwapBigEndian(register _LPcmsTRANSFORM Info,register WORD wOut[],register LPBYTE output)1154 LPBYTE Pack3WordsSwapBigEndian(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
1155 {
1156        *(LPWORD) output = CHANGE_ENDIAN(wOut[2]);
1157        output+= 2;
1158        *(LPWORD) output = CHANGE_ENDIAN(wOut[1]);
1159        output+= 2;
1160        *(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
1161        output+= 2;
1162 
1163        return output;
1164 }
1165 
1166 
1167 static
Pack3BytesAndSkip1(register _LPcmsTRANSFORM Info,register WORD wOut[],register LPBYTE output)1168 LPBYTE Pack3BytesAndSkip1(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
1169 {
1170        *output++ = RGB_16_TO_8(wOut[0]);
1171        *output++ = RGB_16_TO_8(wOut[1]);
1172        *output++ = RGB_16_TO_8(wOut[2]);
1173        output++;
1174 
1175        return output;
1176 }
1177 
1178 
1179 static
Pack3BytesAndSkip1SwapFirst(register _LPcmsTRANSFORM Info,register WORD wOut[],register LPBYTE output)1180 LPBYTE Pack3BytesAndSkip1SwapFirst(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
1181 {
1182         output++;
1183        *output++ = RGB_16_TO_8(wOut[0]);
1184        *output++ = RGB_16_TO_8(wOut[1]);
1185        *output++ = RGB_16_TO_8(wOut[2]);
1186 
1187        return output;
1188 }
1189 
1190 static
Pack3BytesAndSkip1Swap(register _LPcmsTRANSFORM Info,register WORD wOut[],register LPBYTE output)1191 LPBYTE Pack3BytesAndSkip1Swap(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
1192 {
1193         output++;
1194        *output++ = RGB_16_TO_8(wOut[2]);
1195        *output++ = RGB_16_TO_8(wOut[1]);
1196        *output++ = RGB_16_TO_8(wOut[0]);
1197 
1198        return output;
1199 }
1200 
1201 
1202 static
Pack3BytesAndSkip1SwapSwapFirst(register _LPcmsTRANSFORM Info,register WORD wOut[],register LPBYTE output)1203 LPBYTE Pack3BytesAndSkip1SwapSwapFirst(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
1204 {
1205        *output++ = RGB_16_TO_8(wOut[2]);
1206        *output++ = RGB_16_TO_8(wOut[1]);
1207        *output++ = RGB_16_TO_8(wOut[0]);
1208        output++;
1209 
1210        return output;
1211 }
1212 
1213 
1214 static
Pack3WordsAndSkip1(register _LPcmsTRANSFORM Info,register WORD wOut[],register LPBYTE output)1215 LPBYTE Pack3WordsAndSkip1(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
1216 {
1217        *(LPWORD) output = wOut[0];
1218        output+= 2;
1219        *(LPWORD) output = wOut[1];
1220        output+= 2;
1221        *(LPWORD) output = wOut[2];
1222        output+= 2;
1223        output+= 2;
1224 
1225        return output;
1226 }
1227 
1228 static
Pack3WordsAndSkip1Swap(register _LPcmsTRANSFORM Info,register WORD wOut[],register LPBYTE output)1229 LPBYTE Pack3WordsAndSkip1Swap(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
1230 {
1231        output+= 2;
1232        *(LPWORD) output = wOut[2];
1233        output+= 2;
1234        *(LPWORD) output = wOut[1];
1235        output+= 2;
1236        *(LPWORD) output = wOut[0];
1237        output+= 2;
1238 
1239 
1240        return output;
1241 }
1242 
1243 
1244 static
Pack3WordsAndSkip1SwapSwapFirst(register _LPcmsTRANSFORM Info,register WORD wOut[],register LPBYTE output)1245 LPBYTE Pack3WordsAndSkip1SwapSwapFirst(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
1246 {
1247        *(LPWORD) output = wOut[2];
1248        output+= 2;
1249        *(LPWORD) output = wOut[1];
1250        output+= 2;
1251        *(LPWORD) output = wOut[0];
1252        output+= 2;
1253        output+= 2;
1254 
1255 
1256        return output;
1257 }
1258 
1259 
1260 static
Pack3WordsAndSkip1BigEndian(register _LPcmsTRANSFORM Info,register WORD wOut[],register LPBYTE output)1261 LPBYTE Pack3WordsAndSkip1BigEndian(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
1262 {
1263        *(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
1264        output+= 2;
1265        *(LPWORD) output = CHANGE_ENDIAN(wOut[1]);
1266        output+= 2;
1267        *(LPWORD) output = CHANGE_ENDIAN(wOut[2]);
1268        output+= 2;
1269        output+= 2;
1270 
1271        return output;
1272 }
1273 
1274 
1275 static
Pack3WordsAndSkip1SwapBigEndian(register _LPcmsTRANSFORM Info,register WORD wOut[],register LPBYTE output)1276 LPBYTE Pack3WordsAndSkip1SwapBigEndian(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
1277 {
1278         output+= 2;
1279        *(LPWORD) output = CHANGE_ENDIAN(wOut[2]);
1280        output+= 2;
1281        *(LPWORD) output = CHANGE_ENDIAN(wOut[1]);
1282        output+= 2;
1283        *(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
1284        output+= 2;
1285 
1286 
1287        return output;
1288 }
1289 
1290 
1291 
1292 static
Pack1Byte(register _LPcmsTRANSFORM Info,register WORD wOut[],register LPBYTE output)1293 LPBYTE Pack1Byte(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
1294 {
1295        *output++ = RGB_16_TO_8(wOut[0]);
1296        return output;
1297 }
1298 
1299 
1300 static
Pack1ByteAndSkip1(register _LPcmsTRANSFORM Info,register WORD wOut[],register LPBYTE output)1301 LPBYTE Pack1ByteAndSkip1(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
1302 {
1303        *output++ = RGB_16_TO_8(wOut[0]);
1304        output++;
1305        return output;
1306 }
1307 
1308 
1309 static
Pack1ByteAndSkip1SwapFirst(register _LPcmsTRANSFORM Info,register WORD wOut[],register LPBYTE output)1310 LPBYTE Pack1ByteAndSkip1SwapFirst(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
1311 {
1312        output++;
1313        *output++ = RGB_16_TO_8(wOut[0]);
1314 
1315        return output;
1316 }
1317 
1318 static
Pack1Word(register _LPcmsTRANSFORM Info,register WORD wOut[],register LPBYTE output)1319 LPBYTE Pack1Word(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
1320 {
1321        *(LPWORD) output = wOut[0];
1322        output+= 2;
1323 
1324        return output;
1325 }
1326 
1327 static
Pack1WordBigEndian(register _LPcmsTRANSFORM Info,register WORD wOut[],register LPBYTE output)1328 LPBYTE Pack1WordBigEndian(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
1329 {
1330        *(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
1331        output+= 2;
1332 
1333        return output;
1334 }
1335 
1336 
1337 static
Pack1WordAndSkip1(register _LPcmsTRANSFORM Info,register WORD wOut[],register LPBYTE output)1338 LPBYTE Pack1WordAndSkip1(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
1339 {
1340        *(LPWORD) output = wOut[0];
1341        output+= 4;
1342 
1343        return output;
1344 }
1345 
1346 static
Pack1WordAndSkip1SwapFirst(register _LPcmsTRANSFORM Info,register WORD wOut[],register LPBYTE output)1347 LPBYTE Pack1WordAndSkip1SwapFirst(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
1348 {
1349        output += 2;
1350        *(LPWORD) output = wOut[0];
1351        output+= 2;
1352 
1353        return output;
1354 }
1355 
1356 
1357 static
Pack1WordAndSkip1BigEndian(register _LPcmsTRANSFORM Info,register WORD wOut[],register LPBYTE output)1358 LPBYTE Pack1WordAndSkip1BigEndian(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
1359 {
1360        *(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
1361        output+= 4;
1362 
1363        return output;
1364 }
1365 
1366 
1367 // Unencoded Float values -- don't try optimize speed
1368 
1369 static
PackLabDouble(register _LPcmsTRANSFORM Info,register WORD wOut[],register LPBYTE output)1370 LPBYTE PackLabDouble(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
1371 {
1372 
1373     if (T_PLANAR(Info -> OutputFormat)) {
1374 
1375         cmsCIELab  Lab;
1376         double* Out = (double*) output;
1377         cmsLabEncoded2Float(&Lab, wOut);
1378 
1379         Out[0]                  = Lab.L;
1380         Out[Info ->StrideOut]   = Lab.a;
1381         Out[Info ->StrideOut*2] = Lab.b;
1382 
1383         return output + sizeof(double);
1384 
1385     }
1386     else {
1387 
1388        if (Info ->lOutputV4Lab)
1389            cmsLabEncoded2Float4((LPcmsCIELab) output, wOut);
1390        else
1391            cmsLabEncoded2Float((LPcmsCIELab) output, wOut);
1392 
1393         return output + (sizeof(cmsCIELab) + T_EXTRA(Info ->OutputFormat) * sizeof(double));
1394     }
1395 
1396 }
1397 
1398 static
PackXYZDouble(register _LPcmsTRANSFORM Info,register WORD wOut[],register LPBYTE output)1399 LPBYTE PackXYZDouble(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
1400 {
1401 
1402     if (T_PLANAR(Info -> OutputFormat)) {
1403 
1404         cmsCIEXYZ XYZ;
1405         double* Out = (double*) output;
1406         cmsXYZEncoded2Float(&XYZ, wOut);
1407 
1408         Out[0]                  = XYZ.X;
1409         Out[Info ->StrideOut]   = XYZ.Y;
1410         Out[Info ->StrideOut*2] = XYZ.Z;
1411 
1412         return output + sizeof(double);
1413 
1414     }
1415     else {
1416 
1417         cmsXYZEncoded2Float((LPcmsCIEXYZ) output, wOut);
1418 
1419         return output + (sizeof(cmsCIEXYZ) + T_EXTRA(Info ->OutputFormat) * sizeof(double));
1420     }
1421 }
1422 
1423 
1424 
1425 static
PackInkDouble(register _LPcmsTRANSFORM Info,register WORD wOut[],register LPBYTE output)1426 LPBYTE PackInkDouble(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
1427 {
1428     double* Inks = (double*) output;
1429     int nChan = T_CHANNELS(Info -> OutputFormat);
1430     int i;
1431 
1432     if (T_PLANAR(Info -> OutputFormat)) {
1433 
1434         for (i=0; i <  nChan; i++) {
1435 
1436             Inks[i*Info ->StrideOut] = wOut[i] / 655.35;
1437         }
1438 
1439         return output + sizeof(double);
1440     }
1441     else {
1442 
1443         for (i=0; i <  nChan; i++) {
1444 
1445             Inks[i] = wOut[i] /  655.35;
1446         }
1447 
1448 
1449     return output + (nChan + T_EXTRA(Info ->OutputFormat)) * sizeof(double);
1450     }
1451 
1452 }
1453 
1454 
1455 static
PackDouble(register _LPcmsTRANSFORM Info,register WORD wOut[],register LPBYTE output)1456 LPBYTE PackDouble(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
1457 {
1458     double* Inks = (double*) output;
1459     int nChan = T_CHANNELS(Info -> OutputFormat);
1460     int i;
1461 
1462 
1463     if (T_PLANAR(Info -> OutputFormat)) {
1464 
1465         for (i=0; i <  nChan; i++) {
1466 
1467             Inks[i*Info ->StrideOut] = wOut[i] / 65535.0;
1468         }
1469 
1470         return output + sizeof(double);
1471 
1472     }
1473     else {
1474         for (i=0; i <  nChan; i++) {
1475 
1476             Inks[i] = wOut[i] /  65535.0;
1477         }
1478 
1479         return output + (nChan + T_EXTRA(Info ->OutputFormat)) * sizeof(double);
1480     }
1481 
1482 }
1483 
1484 
1485 //  choose routine from Input identifier
1486 
_cmsIdentifyInputFormat(_LPcmsTRANSFORM xform,DWORD dwInput)1487 _cmsFIXFN _cmsIdentifyInputFormat(_LPcmsTRANSFORM xform, DWORD dwInput)
1488 {
1489        _cmsFIXFN FromInput = NULL;
1490 
1491 
1492        // Check Named Color
1493 
1494        if (xform) {
1495 
1496            if (xform ->InputProfile) {
1497 
1498            if (cmsGetDeviceClass(xform ->InputProfile) == icSigNamedColorClass) {
1499 
1500                 if (dwInput != TYPE_NAMED_COLOR_INDEX) {
1501                     cmsSignalError(LCMS_ERRC_ABORTED, "Named color needs TYPE_NAMED_COLOR_INDEX");
1502                     return NULL;
1503                 }
1504            }
1505 
1506         }
1507        }
1508 
1509        // Unencoded modes
1510 
1511        if (T_BYTES(dwInput) == 0) {
1512 
1513            switch (T_COLORSPACE(dwInput)) {
1514 
1515            case PT_Lab:
1516                     FromInput = UnrollLabDouble;
1517                     break;
1518            case PT_XYZ:
1519                     FromInput = UnrollXYZDouble;
1520                     break;
1521 
1522            // 0.0 .. 1.0 range
1523 
1524            case PT_GRAY:
1525            case PT_RGB:
1526            case PT_YCbCr:
1527            case PT_YUV:
1528            case PT_YUVK:
1529            case PT_HSV:
1530            case PT_HLS:
1531            case PT_Yxy:
1532                     if (T_CHANNELS(dwInput) == 1)
1533                         FromInput = UnrollDouble1Chan;
1534                     else
1535                         FromInput = UnrollDouble;
1536                     break;
1537 
1538             // Inks (%) 0.0 .. 100.0
1539 
1540            default:
1541                     FromInput = UnrollInkDouble;
1542                     break;
1543            }
1544 
1545        }
1546        else {
1547 
1548            if (T_PLANAR(dwInput)) {
1549 
1550                switch (T_BYTES(dwInput)) {
1551 
1552                case 1:
1553                    FromInput = UnrollPlanarBytes;
1554                    break;
1555 
1556                case 2:
1557                    if (T_ENDIAN16(dwInput))
1558                        FromInput = UnrollPlanarWordsBigEndian;
1559                    else
1560                        FromInput = UnrollPlanarWords;
1561                    break;
1562 
1563                default:;
1564                }
1565        }
1566        else {
1567 
1568        switch (T_BYTES(dwInput)) {
1569 
1570        case 1: // 1 byte per channel
1571 
1572               switch (T_CHANNELS(dwInput) + T_EXTRA(dwInput)) {
1573 
1574               case 1: if (T_FLAVOR(dwInput))
1575                                 FromInput = Unroll1ByteReversed;
1576                             else
1577                                   FromInput = Unroll1Byte;
1578                       break;
1579 
1580               case 2: if (T_SWAPFIRST(dwInput))
1581                         FromInput = Unroll2ByteSwapFirst;
1582                       else
1583                         FromInput = Unroll2Byte;
1584                       break;
1585 
1586               case 3: if (T_DOSWAP(dwInput))
1587                             FromInput = Unroll3BytesSwap;
1588                       else {
1589                             if (T_EXTRA(dwInput) == 2)
1590                                 FromInput = Unroll1ByteSkip2;
1591                             else
1592                                 if (T_COLORSPACE(dwInput) == PT_Lab)
1593                                     FromInput = Unroll3BytesLab;
1594                                 else
1595                                     FromInput = Unroll3Bytes;
1596                       }
1597                       break;
1598               case 4:
1599                       // TODO: ALab8 must be fixed to match v2 encoding
1600 
1601                       if (T_DOSWAP(dwInput)) {
1602                             if (T_SWAPFIRST(dwInput))
1603 
1604                                 FromInput = Unroll4BytesSwapSwapFirst;
1605                             else
1606                                 FromInput = Unroll4BytesSwap;
1607                       }
1608                       else {
1609                             if (T_SWAPFIRST(dwInput))
1610                                 FromInput = Unroll4BytesSwapFirst;
1611                             else {
1612                                 if (T_FLAVOR(dwInput))
1613                                     FromInput = Unroll4BytesReverse;
1614                                 else
1615                                     FromInput = Unroll4Bytes;
1616                             }
1617                       }
1618                       break;
1619 
1620 
1621               case 5:
1622               case 6:
1623               case 7:
1624               case 8:
1625                    if (!T_DOSWAP(dwInput) && !T_SWAPFIRST(dwInput))
1626                        FromInput = UnrollAnyBytes;
1627                    break;
1628 
1629 
1630               default:;
1631               }
1632               break;
1633 
1634 
1635        case 2: // 1 word per channel
1636 
1637               switch (T_CHANNELS(dwInput) + T_EXTRA(dwInput))
1638               {
1639               case 1: if (T_ENDIAN16(dwInput))
1640                             FromInput = Unroll1WordBigEndian;
1641                       else
1642                           if (T_FLAVOR(dwInput))
1643                                 FromInput = Unroll1WordReversed;
1644                             else
1645                                   FromInput = Unroll1Word;
1646                       break;
1647 
1648               case 2: if (T_ENDIAN16(dwInput))
1649                             FromInput = Unroll2WordBigEndian;
1650                         else {
1651                           if (T_SWAPFIRST(dwInput))
1652                               FromInput = Unroll2WordSwapFirst;
1653                           else
1654                               FromInput = Unroll2Word;
1655                         }
1656                         break;
1657 
1658               case 3: if (T_DOSWAP(dwInput)) {
1659                             if (T_ENDIAN16(dwInput))
1660                                    FromInput = Unroll3WordsSwapBigEndian;
1661                             else
1662                                    FromInput = Unroll3WordsSwap;
1663                       }
1664                       else {
1665                             if (T_ENDIAN16(dwInput))
1666                                    FromInput = Unroll3WordsBigEndian;
1667                             else
1668                                    FromInput = Unroll3Words;
1669                       }
1670                       break;
1671 
1672               case 4: if (T_DOSWAP(dwInput)) {
1673 
1674                             if (T_ENDIAN16(dwInput))
1675                                    FromInput = Unroll4WordsSwapBigEndian;
1676                             else {
1677 
1678                                     if (T_SWAPFIRST(dwInput))
1679                                         FromInput = Unroll4WordsSwapSwapFirst;
1680                                     else
1681                                         FromInput = Unroll4WordsSwap;
1682 
1683                             }
1684 
1685                       }
1686                       else {
1687 
1688                             if (T_EXTRA(dwInput) == 3)
1689                                     FromInput = Unroll1WordSkip3;
1690                             else
1691 
1692                                 if (T_ENDIAN16(dwInput)) {
1693 
1694                                     if (T_FLAVOR(dwInput))
1695                                         FromInput = Unroll4WordsBigEndianReverse;
1696                                     else
1697                                         FromInput = Unroll4WordsBigEndian;
1698                                 }
1699                             else {
1700                                   if (T_SWAPFIRST(dwInput))
1701                                     FromInput = Unroll4WordsSwapFirst;
1702                                   else {
1703                                       if (T_FLAVOR(dwInput))
1704                                             FromInput = Unroll4WordsReverse;
1705                                       else
1706                                             FromInput = Unroll4Words;
1707                                   }
1708                             }
1709                       }
1710                       break;
1711 
1712 
1713               case 5:
1714               case 6:
1715               case 7:
1716               case 8:
1717                     if (!T_DOSWAP(dwInput) && !T_SWAPFIRST(dwInput))
1718                        FromInput = UnrollAnyWords;
1719                     break;
1720 
1721               }
1722               break;
1723 
1724        default:;
1725        }
1726        }
1727        }
1728 
1729 
1730        if (!FromInput)
1731               cmsSignalError(LCMS_ERRC_ABORTED, "Unknown input format");
1732 
1733        return FromInput;
1734 }
1735 
1736 //  choose routine from Input identifier
1737 
_cmsIdentifyOutputFormat(_LPcmsTRANSFORM xform,DWORD dwOutput)1738 _cmsFIXFN _cmsIdentifyOutputFormat(_LPcmsTRANSFORM xform, DWORD dwOutput)
1739 {
1740        _cmsFIXFN ToOutput = NULL;
1741 
1742 
1743        if (T_BYTES(dwOutput) == 0) {
1744 
1745            switch (T_COLORSPACE(dwOutput)) {
1746 
1747            case PT_Lab:
1748                     ToOutput = PackLabDouble;
1749                     break;
1750            case PT_XYZ:
1751                     ToOutput = PackXYZDouble;
1752                     break;
1753 
1754            // 0.0 .. 1.0 range
1755            case PT_GRAY:
1756            case PT_RGB:
1757            case PT_YCbCr:
1758            case PT_YUV:
1759            case PT_YUVK:
1760            case PT_HSV:
1761            case PT_HLS:
1762            case PT_Yxy:
1763                     ToOutput = PackDouble;
1764                     break;
1765 
1766             // Inks (%) 0.0 .. 100.0
1767 
1768            default:
1769                     ToOutput = PackInkDouble;
1770                     break;
1771            }
1772 
1773        }
1774        else
1775 
1776        if (T_PLANAR(dwOutput)) {
1777 
1778        switch (T_BYTES(dwOutput)) {
1779 
1780               case 1: ToOutput = PackPlanarBytes;
1781                       break;
1782 
1783               case 2:if (!T_ENDIAN16(dwOutput))
1784                             ToOutput = PackPlanarWords;
1785                       break;
1786 
1787               default:;
1788        }
1789        }
1790        else {
1791 
1792               switch (T_BYTES(dwOutput)) {
1793 
1794               case 1:
1795                      switch (T_CHANNELS(dwOutput))
1796                      {
1797                      case 1:
1798                             if (T_DITHER(dwOutput))
1799                                     ToOutput = PackNBytesDither;
1800                             else
1801                             ToOutput = Pack1Byte;
1802                             if (T_EXTRA(dwOutput) == 1) {
1803                                 if (T_SWAPFIRST(dwOutput))
1804                                    ToOutput = Pack1ByteAndSkip1SwapFirst;
1805                                 else
1806                                    ToOutput = Pack1ByteAndSkip1;
1807                             }
1808                             break;
1809 
1810                      case 3:
1811                          switch (T_EXTRA(dwOutput)) {
1812 
1813                          case 0: if (T_DOSWAP(dwOutput))
1814                                    ToOutput = Pack3BytesSwap;
1815                                  else
1816                                      if (T_COLORSPACE(dwOutput) == PT_Lab)
1817                                         ToOutput = Pack3BytesLab;
1818                                      else {
1819                                          if (T_DITHER(dwOutput))
1820                                                  ToOutput = PackNBytesDither;
1821                                      else
1822                                         ToOutput = Pack3Bytes;
1823                                      }
1824                              break;
1825 
1826                          case 1:    // TODO: ALab8 should be handled here
1827 
1828                                     if (T_DOSWAP(dwOutput)) {
1829 
1830                                     if (T_SWAPFIRST(dwOutput))
1831                                         ToOutput = Pack3BytesAndSkip1SwapSwapFirst;
1832                                     else
1833                                         ToOutput = Pack3BytesAndSkip1Swap;
1834                                  }
1835                              else {
1836                                    if (T_SWAPFIRST(dwOutput))
1837                                     ToOutput = Pack3BytesAndSkip1SwapFirst;
1838                                    else
1839                                     ToOutput = Pack3BytesAndSkip1;
1840                              }
1841                              break;
1842 
1843                          default:;
1844                          }
1845                          break;
1846 
1847                      case 4: if (T_EXTRA(dwOutput) == 0) {
1848 
1849 
1850                                 if (T_DOSWAP(dwOutput)) {
1851 
1852 
1853                                      if (T_SWAPFIRST(dwOutput)) {
1854                                          ToOutput = Pack4BytesSwapSwapFirst;
1855                                      }
1856                                      else {
1857 
1858                                            if (T_DITHER(dwOutput)) {
1859                                                   ToOutput = PackNBytesSwapDither;
1860                                            }
1861                                            else {
1862                                          ToOutput = Pack4BytesSwap;
1863                                  }
1864                                      }
1865                                  }
1866                                  else {
1867                                      if (T_SWAPFIRST(dwOutput))
1868                                          ToOutput = Pack4BytesSwapFirst;
1869                                      else {
1870 
1871                                          if (T_FLAVOR(dwOutput))
1872                                              ToOutput = Pack4BytesReverse;
1873                                          else {
1874                                              if (T_DITHER(dwOutput))
1875                                                  ToOutput = PackNBytesDither;
1876                                          else
1877                                              ToOutput = Pack4Bytes;
1878                                      }
1879                                  }
1880                              }
1881                              }
1882                             else {
1883                                     if (!T_DOSWAP(dwOutput) && !T_SWAPFIRST(dwOutput))
1884                                              ToOutput = PackNBytes;
1885                             }
1886                             break;
1887 
1888                      // Hexachrome separations.
1889                      case 6: if (T_EXTRA(dwOutput) == 0) {
1890 
1891                                     if( T_DOSWAP(dwOutput))
1892                                             ToOutput = Pack6BytesSwap;
1893                             else
1894                                    ToOutput = Pack6Bytes;
1895                             }
1896                             else {
1897                                     if (!T_DOSWAP(dwOutput) && !T_SWAPFIRST(dwOutput))
1898                                              ToOutput = PackNBytes;
1899 
1900                             }
1901                             break;
1902 
1903                      case 2:
1904                      case 5:
1905                      case 7:
1906                      case 8:
1907                      case 9:
1908                      case 10:
1909                      case 11:
1910                      case 12:
1911                      case 13:
1912                      case 14:
1913                      case 15:
1914 
1915                             if ((T_EXTRA(dwOutput) == 0) && (T_SWAPFIRST(dwOutput) == 0))
1916                             {
1917                                    if (T_DOSWAP(dwOutput))
1918                                           ToOutput = PackNBytesSwap;
1919                                    else {
1920 
1921                                        if (T_DITHER(dwOutput))
1922                                                  ToOutput = PackNBytesDither;
1923                                    else
1924                                           ToOutput = PackNBytes;
1925                                    }
1926                             }
1927                             break;
1928 
1929                      default:;
1930                      }
1931                      break;
1932 
1933 
1934               case 2:
1935 
1936                      switch (T_CHANNELS(dwOutput)) {
1937 
1938                      case 1:
1939                             if (T_ENDIAN16(dwOutput))
1940 
1941                                    ToOutput = Pack1WordBigEndian;
1942                             else
1943                                    ToOutput = Pack1Word;
1944 
1945                             if (T_EXTRA(dwOutput) == 1) {
1946 
1947                                if (T_ENDIAN16(dwOutput))
1948 
1949                                    ToOutput = Pack1WordAndSkip1BigEndian;
1950                                else {
1951                                    if (T_SWAPFIRST(dwOutput))
1952                                       ToOutput = Pack1WordAndSkip1SwapFirst;
1953                                    else
1954                                       ToOutput = Pack1WordAndSkip1;
1955                                }
1956                             }
1957                             break;
1958 
1959                      case 3:
1960 
1961                          switch (T_EXTRA(dwOutput)) {
1962 
1963                          case 0:
1964                                if (T_DOSWAP(dwOutput)) {
1965 
1966                                    if (T_ENDIAN16(dwOutput))
1967 
1968                                           ToOutput = Pack3WordsSwapBigEndian;
1969                                    else
1970                                           ToOutput = Pack3WordsSwap;
1971                                }
1972                                else {
1973                                    if (T_ENDIAN16(dwOutput))
1974 
1975                                       ToOutput = Pack3WordsBigEndian;
1976                                    else
1977                                       ToOutput = Pack3Words;
1978                                    }
1979                              break;
1980 
1981                          case 1: if (T_DOSWAP(dwOutput)) {
1982 
1983                                    if (T_ENDIAN16(dwOutput))
1984 
1985                                           ToOutput = Pack3WordsAndSkip1SwapBigEndian;
1986                                    else {
1987                                        if (T_SWAPFIRST(dwOutput))
1988                                           ToOutput = Pack3WordsAndSkip1SwapSwapFirst;
1989                                        else
1990                                           ToOutput = Pack3WordsAndSkip1Swap;
1991                                    }
1992                              }
1993                              else  {
1994                                    if (T_ENDIAN16(dwOutput))
1995                                           ToOutput = Pack3WordsAndSkip1BigEndian;
1996                                    else
1997                                           ToOutput = Pack3WordsAndSkip1;
1998                                    }
1999                          default:;
2000                          }
2001                          break;
2002 
2003                      case 4: if (T_EXTRA(dwOutput) == 0) {
2004 
2005                                    if (T_DOSWAP(dwOutput)) {
2006 
2007                                            if (T_ENDIAN16(dwOutput))
2008                                                  ToOutput = Pack4WordsSwapBigEndian;
2009                                            else
2010                                                  ToOutput = Pack4WordsSwap;
2011                                    }
2012                                    else {
2013 
2014                                        if (T_ENDIAN16(dwOutput)) {
2015 
2016                                            if (T_FLAVOR(dwOutput))
2017                                                 ToOutput = Pack4WordsBigEndianReverse;
2018                                            else
2019                                                 ToOutput = Pack4WordsBigEndian;
2020                                        }
2021                                        else {
2022                                           if (T_FLAVOR(dwOutput))
2023                                               ToOutput = Pack4WordsReverse;
2024                                           else
2025                                                ToOutput = Pack4Words;
2026                                         }
2027                                    }
2028                             }
2029                             else {
2030                                     if (!T_DOSWAP(dwOutput) && !T_SWAPFIRST(dwOutput))
2031                                              ToOutput = PackNWords;
2032                             }
2033                             break;
2034 
2035                      case 6: if (T_EXTRA(dwOutput) == 0) {
2036 
2037                                    if (T_DOSWAP(dwOutput)) {
2038 
2039                                           if (T_ENDIAN16(dwOutput))
2040                                                  ToOutput = Pack6WordsSwapBigEndian;
2041                                           else
2042                                                  ToOutput = Pack6WordsSwap;
2043                                    }
2044                                    else {
2045 
2046                                    if (T_ENDIAN16(dwOutput))
2047                                           ToOutput = Pack6WordsBigEndian;
2048                                    else
2049                                           ToOutput = Pack6Words;
2050                                    }
2051                              }
2052                             else {
2053                                     if (!T_DOSWAP(dwOutput) && !T_SWAPFIRST(dwOutput))
2054                                              ToOutput = PackNWords;
2055                             }
2056                             break;
2057 
2058 
2059                      case 2:
2060                      case 5:
2061                      case 7:
2062                      case 8:
2063                      case 9:
2064                      case 10:
2065                      case 11:
2066                      case 12:
2067                      case 13:
2068                      case 14:
2069                      case 15: if ((T_EXTRA(dwOutput) == 0) && (T_SWAPFIRST(dwOutput) == 0)) {
2070 
2071                                    if (T_DOSWAP(dwOutput)) {
2072 
2073                                           if (T_ENDIAN16(dwOutput))
2074                                                  ToOutput = PackNWordsSwapBigEndian;
2075                                           else
2076                                                  ToOutput = PackNWordsSwap;
2077                                    }
2078                                    else {
2079 
2080                                           if (T_ENDIAN16(dwOutput))
2081                                                  ToOutput = PackNWordsBigEndian;
2082                                           else
2083                                                  ToOutput = PackNWords;
2084                                           }
2085                              }
2086                              break;
2087 
2088                      default:;
2089                      }
2090                      break;
2091 
2092               default:;
2093               }
2094               }
2095 
2096               if (!ToOutput)
2097                      cmsSignalError(LCMS_ERRC_ABORTED, "Unknown output format");
2098 
2099               return ToOutput;
2100 }
2101 
2102 // User formatters for (weird) cases not already included
2103 
cmsSetUserFormatters(cmsHTRANSFORM hTransform,DWORD dwInput,cmsFORMATTER Input,DWORD dwOutput,cmsFORMATTER Output)2104 void LCMSEXPORT cmsSetUserFormatters(cmsHTRANSFORM hTransform, DWORD dwInput,  cmsFORMATTER Input,
2105                                                                DWORD dwOutput, cmsFORMATTER Output)
2106 {
2107     _LPcmsTRANSFORM xform = (_LPcmsTRANSFORM) (LPSTR) hTransform;
2108 
2109     if (Input != NULL) {
2110         xform ->FromInput = (_cmsFIXFN) Input;
2111         xform ->InputFormat = dwInput;
2112     }
2113 
2114     if (Output != NULL) {
2115         xform ->ToOutput  = (_cmsFIXFN) Output;
2116         xform ->OutputFormat = dwOutput;
2117     }
2118 
2119 }
2120 
cmsGetUserFormatters(cmsHTRANSFORM hTransform,LPDWORD InputFormat,cmsFORMATTER * Input,LPDWORD OutputFormat,cmsFORMATTER * Output)2121 void LCMSEXPORT cmsGetUserFormatters(cmsHTRANSFORM hTransform,
2122                                      LPDWORD InputFormat, cmsFORMATTER* Input,
2123                                      LPDWORD OutputFormat, cmsFORMATTER* Output)
2124 {
2125     _LPcmsTRANSFORM xform = (_LPcmsTRANSFORM) (LPSTR) hTransform;
2126 
2127     if (Input)        *Input =  (cmsFORMATTER) xform ->FromInput;
2128     if (InputFormat)  *InputFormat = xform -> InputFormat;
2129     if (Output)       *Output = (cmsFORMATTER) xform ->ToOutput;
2130     if (OutputFormat) *OutputFormat = xform -> OutputFormat;
2131 }
2132 
2133 
2134 // Change format of yet existing transform. No colorspace checking is performed
2135 
cmsChangeBuffersFormat(cmsHTRANSFORM hTransform,DWORD dwInputFormat,DWORD dwOutputFormat)2136 void LCMSEXPORT cmsChangeBuffersFormat(cmsHTRANSFORM hTransform,
2137                                         DWORD dwInputFormat,
2138                                         DWORD dwOutputFormat)
2139 {
2140 
2141     cmsSetUserFormatters(hTransform,
2142                         dwInputFormat,
2143                         (cmsFORMATTER) _cmsIdentifyInputFormat((_LPcmsTRANSFORM) hTransform, dwInputFormat),
2144                         dwOutputFormat,
2145                         (cmsFORMATTER) _cmsIdentifyOutputFormat((_LPcmsTRANSFORM) hTransform, dwOutputFormat));
2146 }
2147