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