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