1*3ac0a46fSAndroid Build Coastguard Worker //---------------------------------------------------------------------------------
2*3ac0a46fSAndroid Build Coastguard Worker //
3*3ac0a46fSAndroid Build Coastguard Worker // Little Color Management System
4*3ac0a46fSAndroid Build Coastguard Worker // Copyright (c) 1998-2023 Marti Maria Saguer
5*3ac0a46fSAndroid Build Coastguard Worker //
6*3ac0a46fSAndroid Build Coastguard Worker // Permission is hereby granted, free of charge, to any person obtaining
7*3ac0a46fSAndroid Build Coastguard Worker // a copy of this software and associated documentation files (the "Software"),
8*3ac0a46fSAndroid Build Coastguard Worker // to deal in the Software without restriction, including without limitation
9*3ac0a46fSAndroid Build Coastguard Worker // the rights to use, copy, modify, merge, publish, distribute, sublicense,
10*3ac0a46fSAndroid Build Coastguard Worker // and/or sell copies of the Software, and to permit persons to whom the Software
11*3ac0a46fSAndroid Build Coastguard Worker // is furnished to do so, subject to the following conditions:
12*3ac0a46fSAndroid Build Coastguard Worker //
13*3ac0a46fSAndroid Build Coastguard Worker // The above copyright notice and this permission notice shall be included in
14*3ac0a46fSAndroid Build Coastguard Worker // all copies or substantial portions of the Software.
15*3ac0a46fSAndroid Build Coastguard Worker //
16*3ac0a46fSAndroid Build Coastguard Worker // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17*3ac0a46fSAndroid Build Coastguard Worker // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
18*3ac0a46fSAndroid Build Coastguard Worker // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19*3ac0a46fSAndroid Build Coastguard Worker // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20*3ac0a46fSAndroid Build Coastguard Worker // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21*3ac0a46fSAndroid Build Coastguard Worker // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22*3ac0a46fSAndroid Build Coastguard Worker // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23*3ac0a46fSAndroid Build Coastguard Worker //
24*3ac0a46fSAndroid Build Coastguard Worker //---------------------------------------------------------------------------------
25*3ac0a46fSAndroid Build Coastguard Worker //
26*3ac0a46fSAndroid Build Coastguard Worker
27*3ac0a46fSAndroid Build Coastguard Worker #include "lcms2_internal.h"
28*3ac0a46fSAndroid Build Coastguard Worker
29*3ac0a46fSAndroid Build Coastguard Worker // Alpha copy ------------------------------------------------------------------------------------------------------------------
30*3ac0a46fSAndroid Build Coastguard Worker
31*3ac0a46fSAndroid Build Coastguard Worker // This macro return words stored as big endian
32*3ac0a46fSAndroid Build Coastguard Worker #define CHANGE_ENDIAN(w) (cmsUInt16Number) ((cmsUInt16Number) ((w)<<8)|((w)>>8))
33*3ac0a46fSAndroid Build Coastguard Worker
34*3ac0a46fSAndroid Build Coastguard Worker
35*3ac0a46fSAndroid Build Coastguard Worker // Floor to byte, taking care of saturation
_cmsQuickSaturateByte(cmsFloat64Number d)36*3ac0a46fSAndroid Build Coastguard Worker cmsINLINE cmsUInt8Number _cmsQuickSaturateByte(cmsFloat64Number d)
37*3ac0a46fSAndroid Build Coastguard Worker {
38*3ac0a46fSAndroid Build Coastguard Worker d += 0.5;
39*3ac0a46fSAndroid Build Coastguard Worker if (d <= 0) return 0;
40*3ac0a46fSAndroid Build Coastguard Worker if (d >= 255.0) return 255;
41*3ac0a46fSAndroid Build Coastguard Worker
42*3ac0a46fSAndroid Build Coastguard Worker return (cmsUInt8Number) _cmsQuickFloorWord(d);
43*3ac0a46fSAndroid Build Coastguard Worker }
44*3ac0a46fSAndroid Build Coastguard Worker
45*3ac0a46fSAndroid Build Coastguard Worker
46*3ac0a46fSAndroid Build Coastguard Worker // Return the size in bytes of a given formatter
47*3ac0a46fSAndroid Build Coastguard Worker static
trueBytesSize(cmsUInt32Number Format)48*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number trueBytesSize(cmsUInt32Number Format)
49*3ac0a46fSAndroid Build Coastguard Worker {
50*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number fmt_bytes = T_BYTES(Format);
51*3ac0a46fSAndroid Build Coastguard Worker
52*3ac0a46fSAndroid Build Coastguard Worker // For double, the T_BYTES field returns zero
53*3ac0a46fSAndroid Build Coastguard Worker if (fmt_bytes == 0)
54*3ac0a46fSAndroid Build Coastguard Worker return sizeof(double);
55*3ac0a46fSAndroid Build Coastguard Worker
56*3ac0a46fSAndroid Build Coastguard Worker // Otherwise, it is already correct for all formats
57*3ac0a46fSAndroid Build Coastguard Worker return fmt_bytes;
58*3ac0a46fSAndroid Build Coastguard Worker }
59*3ac0a46fSAndroid Build Coastguard Worker
60*3ac0a46fSAndroid Build Coastguard Worker
61*3ac0a46fSAndroid Build Coastguard Worker // Several format converters
62*3ac0a46fSAndroid Build Coastguard Worker
63*3ac0a46fSAndroid Build Coastguard Worker typedef void(*cmsFormatterAlphaFn)(void* dst, const void* src);
64*3ac0a46fSAndroid Build Coastguard Worker
65*3ac0a46fSAndroid Build Coastguard Worker
66*3ac0a46fSAndroid Build Coastguard Worker // From 8
67*3ac0a46fSAndroid Build Coastguard Worker
68*3ac0a46fSAndroid Build Coastguard Worker static
copy8(void * dst,const void * src)69*3ac0a46fSAndroid Build Coastguard Worker void copy8(void* dst, const void* src)
70*3ac0a46fSAndroid Build Coastguard Worker {
71*3ac0a46fSAndroid Build Coastguard Worker memmove(dst, src, 1);
72*3ac0a46fSAndroid Build Coastguard Worker }
73*3ac0a46fSAndroid Build Coastguard Worker
74*3ac0a46fSAndroid Build Coastguard Worker static
from8to16(void * dst,const void * src)75*3ac0a46fSAndroid Build Coastguard Worker void from8to16(void* dst, const void* src)
76*3ac0a46fSAndroid Build Coastguard Worker {
77*3ac0a46fSAndroid Build Coastguard Worker cmsUInt8Number n = *(cmsUInt8Number*)src;
78*3ac0a46fSAndroid Build Coastguard Worker *(cmsUInt16Number*) dst = (cmsUInt16Number) FROM_8_TO_16(n);
79*3ac0a46fSAndroid Build Coastguard Worker }
80*3ac0a46fSAndroid Build Coastguard Worker
81*3ac0a46fSAndroid Build Coastguard Worker static
from8to16SE(void * dst,const void * src)82*3ac0a46fSAndroid Build Coastguard Worker void from8to16SE(void* dst, const void* src)
83*3ac0a46fSAndroid Build Coastguard Worker {
84*3ac0a46fSAndroid Build Coastguard Worker cmsUInt8Number n = *(cmsUInt8Number*)src;
85*3ac0a46fSAndroid Build Coastguard Worker *(cmsUInt16Number*)dst = CHANGE_ENDIAN(FROM_8_TO_16(n));
86*3ac0a46fSAndroid Build Coastguard Worker }
87*3ac0a46fSAndroid Build Coastguard Worker
88*3ac0a46fSAndroid Build Coastguard Worker static
from8toFLT(void * dst,const void * src)89*3ac0a46fSAndroid Build Coastguard Worker void from8toFLT(void* dst, const void* src)
90*3ac0a46fSAndroid Build Coastguard Worker {
91*3ac0a46fSAndroid Build Coastguard Worker *(cmsFloat32Number*)dst = (cmsFloat32Number) (*(cmsUInt8Number*)src) / 255.0f;
92*3ac0a46fSAndroid Build Coastguard Worker }
93*3ac0a46fSAndroid Build Coastguard Worker
94*3ac0a46fSAndroid Build Coastguard Worker static
from8toDBL(void * dst,const void * src)95*3ac0a46fSAndroid Build Coastguard Worker void from8toDBL(void* dst, const void* src)
96*3ac0a46fSAndroid Build Coastguard Worker {
97*3ac0a46fSAndroid Build Coastguard Worker *(cmsFloat64Number*)dst = (cmsFloat64Number) (*(cmsUInt8Number*)src) / 255.0;
98*3ac0a46fSAndroid Build Coastguard Worker }
99*3ac0a46fSAndroid Build Coastguard Worker
100*3ac0a46fSAndroid Build Coastguard Worker static
from8toHLF(void * dst,const void * src)101*3ac0a46fSAndroid Build Coastguard Worker void from8toHLF(void* dst, const void* src)
102*3ac0a46fSAndroid Build Coastguard Worker {
103*3ac0a46fSAndroid Build Coastguard Worker #ifndef CMS_NO_HALF_SUPPORT
104*3ac0a46fSAndroid Build Coastguard Worker cmsFloat32Number n = (*(cmsUInt8Number*)src) / 255.0f;
105*3ac0a46fSAndroid Build Coastguard Worker *(cmsUInt16Number*)dst = _cmsFloat2Half(n);
106*3ac0a46fSAndroid Build Coastguard Worker #else
107*3ac0a46fSAndroid Build Coastguard Worker cmsUNUSED_PARAMETER(dst);
108*3ac0a46fSAndroid Build Coastguard Worker cmsUNUSED_PARAMETER(src);
109*3ac0a46fSAndroid Build Coastguard Worker #endif
110*3ac0a46fSAndroid Build Coastguard Worker }
111*3ac0a46fSAndroid Build Coastguard Worker
112*3ac0a46fSAndroid Build Coastguard Worker // From 16
113*3ac0a46fSAndroid Build Coastguard Worker
114*3ac0a46fSAndroid Build Coastguard Worker static
from16to8(void * dst,const void * src)115*3ac0a46fSAndroid Build Coastguard Worker void from16to8(void* dst, const void* src)
116*3ac0a46fSAndroid Build Coastguard Worker {
117*3ac0a46fSAndroid Build Coastguard Worker cmsUInt16Number n = *(cmsUInt16Number*)src;
118*3ac0a46fSAndroid Build Coastguard Worker *(cmsUInt8Number*) dst = FROM_16_TO_8(n);
119*3ac0a46fSAndroid Build Coastguard Worker }
120*3ac0a46fSAndroid Build Coastguard Worker
121*3ac0a46fSAndroid Build Coastguard Worker static
from16SEto8(void * dst,const void * src)122*3ac0a46fSAndroid Build Coastguard Worker void from16SEto8(void* dst, const void* src)
123*3ac0a46fSAndroid Build Coastguard Worker {
124*3ac0a46fSAndroid Build Coastguard Worker cmsUInt16Number n = *(cmsUInt16Number*)src;
125*3ac0a46fSAndroid Build Coastguard Worker *(cmsUInt8Number*)dst = FROM_16_TO_8(CHANGE_ENDIAN(n));
126*3ac0a46fSAndroid Build Coastguard Worker }
127*3ac0a46fSAndroid Build Coastguard Worker
128*3ac0a46fSAndroid Build Coastguard Worker static
copy16(void * dst,const void * src)129*3ac0a46fSAndroid Build Coastguard Worker void copy16(void* dst, const void* src)
130*3ac0a46fSAndroid Build Coastguard Worker {
131*3ac0a46fSAndroid Build Coastguard Worker memmove(dst, src, 2);
132*3ac0a46fSAndroid Build Coastguard Worker }
133*3ac0a46fSAndroid Build Coastguard Worker
134*3ac0a46fSAndroid Build Coastguard Worker static
from16to16(void * dst,const void * src)135*3ac0a46fSAndroid Build Coastguard Worker void from16to16(void* dst, const void* src)
136*3ac0a46fSAndroid Build Coastguard Worker {
137*3ac0a46fSAndroid Build Coastguard Worker cmsUInt16Number n = *(cmsUInt16Number*)src;
138*3ac0a46fSAndroid Build Coastguard Worker *(cmsUInt16Number*)dst = CHANGE_ENDIAN(n);
139*3ac0a46fSAndroid Build Coastguard Worker }
140*3ac0a46fSAndroid Build Coastguard Worker
141*3ac0a46fSAndroid Build Coastguard Worker static
from16toFLT(void * dst,const void * src)142*3ac0a46fSAndroid Build Coastguard Worker void from16toFLT(void* dst, const void* src)
143*3ac0a46fSAndroid Build Coastguard Worker {
144*3ac0a46fSAndroid Build Coastguard Worker *(cmsFloat32Number*)dst = (*(cmsUInt16Number*)src) / 65535.0f;
145*3ac0a46fSAndroid Build Coastguard Worker }
146*3ac0a46fSAndroid Build Coastguard Worker
147*3ac0a46fSAndroid Build Coastguard Worker static
from16SEtoFLT(void * dst,const void * src)148*3ac0a46fSAndroid Build Coastguard Worker void from16SEtoFLT(void* dst, const void* src)
149*3ac0a46fSAndroid Build Coastguard Worker {
150*3ac0a46fSAndroid Build Coastguard Worker *(cmsFloat32Number*)dst = (CHANGE_ENDIAN(*(cmsUInt16Number*)src)) / 65535.0f;
151*3ac0a46fSAndroid Build Coastguard Worker }
152*3ac0a46fSAndroid Build Coastguard Worker
153*3ac0a46fSAndroid Build Coastguard Worker static
from16toDBL(void * dst,const void * src)154*3ac0a46fSAndroid Build Coastguard Worker void from16toDBL(void* dst, const void* src)
155*3ac0a46fSAndroid Build Coastguard Worker {
156*3ac0a46fSAndroid Build Coastguard Worker *(cmsFloat64Number*)dst = (cmsFloat64Number) (*(cmsUInt16Number*)src) / 65535.0;
157*3ac0a46fSAndroid Build Coastguard Worker }
158*3ac0a46fSAndroid Build Coastguard Worker
159*3ac0a46fSAndroid Build Coastguard Worker static
from16SEtoDBL(void * dst,const void * src)160*3ac0a46fSAndroid Build Coastguard Worker void from16SEtoDBL(void* dst, const void* src)
161*3ac0a46fSAndroid Build Coastguard Worker {
162*3ac0a46fSAndroid Build Coastguard Worker *(cmsFloat64Number*)dst = (cmsFloat64Number) (CHANGE_ENDIAN(*(cmsUInt16Number*)src)) / 65535.0;
163*3ac0a46fSAndroid Build Coastguard Worker }
164*3ac0a46fSAndroid Build Coastguard Worker
165*3ac0a46fSAndroid Build Coastguard Worker static
from16toHLF(void * dst,const void * src)166*3ac0a46fSAndroid Build Coastguard Worker void from16toHLF(void* dst, const void* src)
167*3ac0a46fSAndroid Build Coastguard Worker {
168*3ac0a46fSAndroid Build Coastguard Worker #ifndef CMS_NO_HALF_SUPPORT
169*3ac0a46fSAndroid Build Coastguard Worker cmsFloat32Number n = (*(cmsUInt16Number*)src) / 65535.0f;
170*3ac0a46fSAndroid Build Coastguard Worker *(cmsUInt16Number*)dst = _cmsFloat2Half(n);
171*3ac0a46fSAndroid Build Coastguard Worker #else
172*3ac0a46fSAndroid Build Coastguard Worker cmsUNUSED_PARAMETER(dst);
173*3ac0a46fSAndroid Build Coastguard Worker cmsUNUSED_PARAMETER(src);
174*3ac0a46fSAndroid Build Coastguard Worker #endif
175*3ac0a46fSAndroid Build Coastguard Worker }
176*3ac0a46fSAndroid Build Coastguard Worker
177*3ac0a46fSAndroid Build Coastguard Worker static
from16SEtoHLF(void * dst,const void * src)178*3ac0a46fSAndroid Build Coastguard Worker void from16SEtoHLF(void* dst, const void* src)
179*3ac0a46fSAndroid Build Coastguard Worker {
180*3ac0a46fSAndroid Build Coastguard Worker #ifndef CMS_NO_HALF_SUPPORT
181*3ac0a46fSAndroid Build Coastguard Worker cmsFloat32Number n = (CHANGE_ENDIAN(*(cmsUInt16Number*)src)) / 65535.0f;
182*3ac0a46fSAndroid Build Coastguard Worker *(cmsUInt16Number*)dst = _cmsFloat2Half(n);
183*3ac0a46fSAndroid Build Coastguard Worker #else
184*3ac0a46fSAndroid Build Coastguard Worker cmsUNUSED_PARAMETER(dst);
185*3ac0a46fSAndroid Build Coastguard Worker cmsUNUSED_PARAMETER(src);
186*3ac0a46fSAndroid Build Coastguard Worker #endif
187*3ac0a46fSAndroid Build Coastguard Worker }
188*3ac0a46fSAndroid Build Coastguard Worker // From Float
189*3ac0a46fSAndroid Build Coastguard Worker
190*3ac0a46fSAndroid Build Coastguard Worker static
fromFLTto8(void * dst,const void * src)191*3ac0a46fSAndroid Build Coastguard Worker void fromFLTto8(void* dst, const void* src)
192*3ac0a46fSAndroid Build Coastguard Worker {
193*3ac0a46fSAndroid Build Coastguard Worker cmsFloat32Number n = *(cmsFloat32Number*)src;
194*3ac0a46fSAndroid Build Coastguard Worker *(cmsUInt8Number*)dst = _cmsQuickSaturateByte(n * 255.0);
195*3ac0a46fSAndroid Build Coastguard Worker }
196*3ac0a46fSAndroid Build Coastguard Worker
197*3ac0a46fSAndroid Build Coastguard Worker static
fromFLTto16(void * dst,const void * src)198*3ac0a46fSAndroid Build Coastguard Worker void fromFLTto16(void* dst, const void* src)
199*3ac0a46fSAndroid Build Coastguard Worker {
200*3ac0a46fSAndroid Build Coastguard Worker cmsFloat32Number n = *(cmsFloat32Number*)src;
201*3ac0a46fSAndroid Build Coastguard Worker *(cmsUInt16Number*)dst = _cmsQuickSaturateWord(n * 65535.0);
202*3ac0a46fSAndroid Build Coastguard Worker }
203*3ac0a46fSAndroid Build Coastguard Worker
204*3ac0a46fSAndroid Build Coastguard Worker static
fromFLTto16SE(void * dst,const void * src)205*3ac0a46fSAndroid Build Coastguard Worker void fromFLTto16SE(void* dst, const void* src)
206*3ac0a46fSAndroid Build Coastguard Worker {
207*3ac0a46fSAndroid Build Coastguard Worker cmsFloat32Number n = *(cmsFloat32Number*)src;
208*3ac0a46fSAndroid Build Coastguard Worker cmsUInt16Number i = _cmsQuickSaturateWord(n * 65535.0);
209*3ac0a46fSAndroid Build Coastguard Worker
210*3ac0a46fSAndroid Build Coastguard Worker *(cmsUInt16Number*)dst = CHANGE_ENDIAN(i);
211*3ac0a46fSAndroid Build Coastguard Worker }
212*3ac0a46fSAndroid Build Coastguard Worker
213*3ac0a46fSAndroid Build Coastguard Worker static
copy32(void * dst,const void * src)214*3ac0a46fSAndroid Build Coastguard Worker void copy32(void* dst, const void* src)
215*3ac0a46fSAndroid Build Coastguard Worker {
216*3ac0a46fSAndroid Build Coastguard Worker memmove(dst, src, sizeof(cmsFloat32Number));
217*3ac0a46fSAndroid Build Coastguard Worker }
218*3ac0a46fSAndroid Build Coastguard Worker
219*3ac0a46fSAndroid Build Coastguard Worker static
fromFLTtoDBL(void * dst,const void * src)220*3ac0a46fSAndroid Build Coastguard Worker void fromFLTtoDBL(void* dst, const void* src)
221*3ac0a46fSAndroid Build Coastguard Worker {
222*3ac0a46fSAndroid Build Coastguard Worker cmsFloat32Number n = *(cmsFloat32Number*)src;
223*3ac0a46fSAndroid Build Coastguard Worker *(cmsFloat64Number*)dst = (cmsFloat64Number)n;
224*3ac0a46fSAndroid Build Coastguard Worker }
225*3ac0a46fSAndroid Build Coastguard Worker
226*3ac0a46fSAndroid Build Coastguard Worker static
fromFLTtoHLF(void * dst,const void * src)227*3ac0a46fSAndroid Build Coastguard Worker void fromFLTtoHLF(void* dst, const void* src)
228*3ac0a46fSAndroid Build Coastguard Worker {
229*3ac0a46fSAndroid Build Coastguard Worker #ifndef CMS_NO_HALF_SUPPORT
230*3ac0a46fSAndroid Build Coastguard Worker cmsFloat32Number n = *(cmsFloat32Number*)src;
231*3ac0a46fSAndroid Build Coastguard Worker *(cmsUInt16Number*)dst = _cmsFloat2Half(n);
232*3ac0a46fSAndroid Build Coastguard Worker #else
233*3ac0a46fSAndroid Build Coastguard Worker cmsUNUSED_PARAMETER(dst);
234*3ac0a46fSAndroid Build Coastguard Worker cmsUNUSED_PARAMETER(src);
235*3ac0a46fSAndroid Build Coastguard Worker #endif
236*3ac0a46fSAndroid Build Coastguard Worker }
237*3ac0a46fSAndroid Build Coastguard Worker
238*3ac0a46fSAndroid Build Coastguard Worker
239*3ac0a46fSAndroid Build Coastguard Worker // From HALF
240*3ac0a46fSAndroid Build Coastguard Worker
241*3ac0a46fSAndroid Build Coastguard Worker static
fromHLFto8(void * dst,const void * src)242*3ac0a46fSAndroid Build Coastguard Worker void fromHLFto8(void* dst, const void* src)
243*3ac0a46fSAndroid Build Coastguard Worker {
244*3ac0a46fSAndroid Build Coastguard Worker #ifndef CMS_NO_HALF_SUPPORT
245*3ac0a46fSAndroid Build Coastguard Worker cmsFloat32Number n = _cmsHalf2Float(*(cmsUInt16Number*)src);
246*3ac0a46fSAndroid Build Coastguard Worker *(cmsUInt8Number*)dst = _cmsQuickSaturateByte(n * 255.0);
247*3ac0a46fSAndroid Build Coastguard Worker #else
248*3ac0a46fSAndroid Build Coastguard Worker cmsUNUSED_PARAMETER(dst);
249*3ac0a46fSAndroid Build Coastguard Worker cmsUNUSED_PARAMETER(src);
250*3ac0a46fSAndroid Build Coastguard Worker #endif
251*3ac0a46fSAndroid Build Coastguard Worker
252*3ac0a46fSAndroid Build Coastguard Worker }
253*3ac0a46fSAndroid Build Coastguard Worker
254*3ac0a46fSAndroid Build Coastguard Worker static
fromHLFto16(void * dst,const void * src)255*3ac0a46fSAndroid Build Coastguard Worker void fromHLFto16(void* dst, const void* src)
256*3ac0a46fSAndroid Build Coastguard Worker {
257*3ac0a46fSAndroid Build Coastguard Worker #ifndef CMS_NO_HALF_SUPPORT
258*3ac0a46fSAndroid Build Coastguard Worker cmsFloat32Number n = _cmsHalf2Float(*(cmsUInt16Number*)src);
259*3ac0a46fSAndroid Build Coastguard Worker *(cmsUInt16Number*)dst = _cmsQuickSaturateWord(n * 65535.0);
260*3ac0a46fSAndroid Build Coastguard Worker #else
261*3ac0a46fSAndroid Build Coastguard Worker cmsUNUSED_PARAMETER(dst);
262*3ac0a46fSAndroid Build Coastguard Worker cmsUNUSED_PARAMETER(src);
263*3ac0a46fSAndroid Build Coastguard Worker #endif
264*3ac0a46fSAndroid Build Coastguard Worker }
265*3ac0a46fSAndroid Build Coastguard Worker
266*3ac0a46fSAndroid Build Coastguard Worker static
fromHLFto16SE(void * dst,const void * src)267*3ac0a46fSAndroid Build Coastguard Worker void fromHLFto16SE(void* dst, const void* src)
268*3ac0a46fSAndroid Build Coastguard Worker {
269*3ac0a46fSAndroid Build Coastguard Worker #ifndef CMS_NO_HALF_SUPPORT
270*3ac0a46fSAndroid Build Coastguard Worker cmsFloat32Number n = _cmsHalf2Float(*(cmsUInt16Number*)src);
271*3ac0a46fSAndroid Build Coastguard Worker cmsUInt16Number i = _cmsQuickSaturateWord(n * 65535.0);
272*3ac0a46fSAndroid Build Coastguard Worker *(cmsUInt16Number*)dst = CHANGE_ENDIAN(i);
273*3ac0a46fSAndroid Build Coastguard Worker #else
274*3ac0a46fSAndroid Build Coastguard Worker cmsUNUSED_PARAMETER(dst);
275*3ac0a46fSAndroid Build Coastguard Worker cmsUNUSED_PARAMETER(src);
276*3ac0a46fSAndroid Build Coastguard Worker #endif
277*3ac0a46fSAndroid Build Coastguard Worker }
278*3ac0a46fSAndroid Build Coastguard Worker
279*3ac0a46fSAndroid Build Coastguard Worker static
fromHLFtoFLT(void * dst,const void * src)280*3ac0a46fSAndroid Build Coastguard Worker void fromHLFtoFLT(void* dst, const void* src)
281*3ac0a46fSAndroid Build Coastguard Worker {
282*3ac0a46fSAndroid Build Coastguard Worker #ifndef CMS_NO_HALF_SUPPORT
283*3ac0a46fSAndroid Build Coastguard Worker *(cmsFloat32Number*)dst = _cmsHalf2Float(*(cmsUInt16Number*)src);
284*3ac0a46fSAndroid Build Coastguard Worker #else
285*3ac0a46fSAndroid Build Coastguard Worker cmsUNUSED_PARAMETER(dst);
286*3ac0a46fSAndroid Build Coastguard Worker cmsUNUSED_PARAMETER(src);
287*3ac0a46fSAndroid Build Coastguard Worker #endif
288*3ac0a46fSAndroid Build Coastguard Worker }
289*3ac0a46fSAndroid Build Coastguard Worker
290*3ac0a46fSAndroid Build Coastguard Worker static
fromHLFtoDBL(void * dst,const void * src)291*3ac0a46fSAndroid Build Coastguard Worker void fromHLFtoDBL(void* dst, const void* src)
292*3ac0a46fSAndroid Build Coastguard Worker {
293*3ac0a46fSAndroid Build Coastguard Worker #ifndef CMS_NO_HALF_SUPPORT
294*3ac0a46fSAndroid Build Coastguard Worker *(cmsFloat64Number*)dst = (cmsFloat64Number)_cmsHalf2Float(*(cmsUInt16Number*)src);
295*3ac0a46fSAndroid Build Coastguard Worker #else
296*3ac0a46fSAndroid Build Coastguard Worker cmsUNUSED_PARAMETER(dst);
297*3ac0a46fSAndroid Build Coastguard Worker cmsUNUSED_PARAMETER(src);
298*3ac0a46fSAndroid Build Coastguard Worker #endif
299*3ac0a46fSAndroid Build Coastguard Worker }
300*3ac0a46fSAndroid Build Coastguard Worker
301*3ac0a46fSAndroid Build Coastguard Worker // From double
302*3ac0a46fSAndroid Build Coastguard Worker static
fromDBLto8(void * dst,const void * src)303*3ac0a46fSAndroid Build Coastguard Worker void fromDBLto8(void* dst, const void* src)
304*3ac0a46fSAndroid Build Coastguard Worker {
305*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number n = *(cmsFloat64Number*)src;
306*3ac0a46fSAndroid Build Coastguard Worker *(cmsUInt8Number*)dst = _cmsQuickSaturateByte(n * 255.0);
307*3ac0a46fSAndroid Build Coastguard Worker }
308*3ac0a46fSAndroid Build Coastguard Worker
309*3ac0a46fSAndroid Build Coastguard Worker static
fromDBLto16(void * dst,const void * src)310*3ac0a46fSAndroid Build Coastguard Worker void fromDBLto16(void* dst, const void* src)
311*3ac0a46fSAndroid Build Coastguard Worker {
312*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number n = *(cmsFloat64Number*)src;
313*3ac0a46fSAndroid Build Coastguard Worker *(cmsUInt16Number*)dst = _cmsQuickSaturateWord(n * 65535.0f);
314*3ac0a46fSAndroid Build Coastguard Worker }
315*3ac0a46fSAndroid Build Coastguard Worker
316*3ac0a46fSAndroid Build Coastguard Worker static
fromDBLto16SE(void * dst,const void * src)317*3ac0a46fSAndroid Build Coastguard Worker void fromDBLto16SE(void* dst, const void* src)
318*3ac0a46fSAndroid Build Coastguard Worker {
319*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number n = *(cmsFloat64Number*)src;
320*3ac0a46fSAndroid Build Coastguard Worker cmsUInt16Number i = _cmsQuickSaturateWord(n * 65535.0f);
321*3ac0a46fSAndroid Build Coastguard Worker *(cmsUInt16Number*)dst = CHANGE_ENDIAN(i);
322*3ac0a46fSAndroid Build Coastguard Worker }
323*3ac0a46fSAndroid Build Coastguard Worker
324*3ac0a46fSAndroid Build Coastguard Worker static
fromDBLtoFLT(void * dst,const void * src)325*3ac0a46fSAndroid Build Coastguard Worker void fromDBLtoFLT(void* dst, const void* src)
326*3ac0a46fSAndroid Build Coastguard Worker {
327*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number n = *(cmsFloat64Number*)src;
328*3ac0a46fSAndroid Build Coastguard Worker *(cmsFloat32Number*)dst = (cmsFloat32Number) n;
329*3ac0a46fSAndroid Build Coastguard Worker }
330*3ac0a46fSAndroid Build Coastguard Worker
331*3ac0a46fSAndroid Build Coastguard Worker static
fromDBLtoHLF(void * dst,const void * src)332*3ac0a46fSAndroid Build Coastguard Worker void fromDBLtoHLF(void* dst, const void* src)
333*3ac0a46fSAndroid Build Coastguard Worker {
334*3ac0a46fSAndroid Build Coastguard Worker #ifndef CMS_NO_HALF_SUPPORT
335*3ac0a46fSAndroid Build Coastguard Worker cmsFloat32Number n = (cmsFloat32Number) *(cmsFloat64Number*)src;
336*3ac0a46fSAndroid Build Coastguard Worker *(cmsUInt16Number*)dst = _cmsFloat2Half(n);
337*3ac0a46fSAndroid Build Coastguard Worker #else
338*3ac0a46fSAndroid Build Coastguard Worker cmsUNUSED_PARAMETER(dst);
339*3ac0a46fSAndroid Build Coastguard Worker cmsUNUSED_PARAMETER(src);
340*3ac0a46fSAndroid Build Coastguard Worker #endif
341*3ac0a46fSAndroid Build Coastguard Worker }
342*3ac0a46fSAndroid Build Coastguard Worker
343*3ac0a46fSAndroid Build Coastguard Worker static
copy64(void * dst,const void * src)344*3ac0a46fSAndroid Build Coastguard Worker void copy64(void* dst, const void* src)
345*3ac0a46fSAndroid Build Coastguard Worker {
346*3ac0a46fSAndroid Build Coastguard Worker memmove(dst, src, sizeof(cmsFloat64Number));
347*3ac0a46fSAndroid Build Coastguard Worker }
348*3ac0a46fSAndroid Build Coastguard Worker
349*3ac0a46fSAndroid Build Coastguard Worker
350*3ac0a46fSAndroid Build Coastguard Worker // Returns the position (x or y) of the formatter in the table of functions
351*3ac0a46fSAndroid Build Coastguard Worker static
FormatterPos(cmsUInt32Number frm)352*3ac0a46fSAndroid Build Coastguard Worker int FormatterPos(cmsUInt32Number frm)
353*3ac0a46fSAndroid Build Coastguard Worker {
354*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number b = T_BYTES(frm);
355*3ac0a46fSAndroid Build Coastguard Worker
356*3ac0a46fSAndroid Build Coastguard Worker if (b == 0 && T_FLOAT(frm))
357*3ac0a46fSAndroid Build Coastguard Worker return 5; // DBL
358*3ac0a46fSAndroid Build Coastguard Worker #ifndef CMS_NO_HALF_SUPPORT
359*3ac0a46fSAndroid Build Coastguard Worker if (b == 2 && T_FLOAT(frm))
360*3ac0a46fSAndroid Build Coastguard Worker return 3; // HLF
361*3ac0a46fSAndroid Build Coastguard Worker #endif
362*3ac0a46fSAndroid Build Coastguard Worker if (b == 4 && T_FLOAT(frm))
363*3ac0a46fSAndroid Build Coastguard Worker return 4; // FLT
364*3ac0a46fSAndroid Build Coastguard Worker if (b == 2 && !T_FLOAT(frm))
365*3ac0a46fSAndroid Build Coastguard Worker {
366*3ac0a46fSAndroid Build Coastguard Worker if (T_ENDIAN16(frm))
367*3ac0a46fSAndroid Build Coastguard Worker return 2; // 16SE
368*3ac0a46fSAndroid Build Coastguard Worker else
369*3ac0a46fSAndroid Build Coastguard Worker return 1; // 16
370*3ac0a46fSAndroid Build Coastguard Worker }
371*3ac0a46fSAndroid Build Coastguard Worker if (b == 1 && !T_FLOAT(frm))
372*3ac0a46fSAndroid Build Coastguard Worker return 0; // 8
373*3ac0a46fSAndroid Build Coastguard Worker return -1; // not recognized
374*3ac0a46fSAndroid Build Coastguard Worker }
375*3ac0a46fSAndroid Build Coastguard Worker
376*3ac0a46fSAndroid Build Coastguard Worker // Obtains an alpha-to-alpha function formatter
377*3ac0a46fSAndroid Build Coastguard Worker static
_cmsGetFormatterAlpha(cmsContext id,cmsUInt32Number in,cmsUInt32Number out)378*3ac0a46fSAndroid Build Coastguard Worker cmsFormatterAlphaFn _cmsGetFormatterAlpha(cmsContext id, cmsUInt32Number in, cmsUInt32Number out)
379*3ac0a46fSAndroid Build Coastguard Worker {
380*3ac0a46fSAndroid Build Coastguard Worker static const cmsFormatterAlphaFn FormattersAlpha[6][6] = {
381*3ac0a46fSAndroid Build Coastguard Worker
382*3ac0a46fSAndroid Build Coastguard Worker /* from 8 */ { copy8, from8to16, from8to16SE, from8toHLF, from8toFLT, from8toDBL },
383*3ac0a46fSAndroid Build Coastguard Worker /* from 16*/ { from16to8, copy16, from16to16, from16toHLF, from16toFLT, from16toDBL },
384*3ac0a46fSAndroid Build Coastguard Worker /* from 16SE*/{ from16SEto8, from16to16, copy16, from16SEtoHLF,from16SEtoFLT, from16SEtoDBL },
385*3ac0a46fSAndroid Build Coastguard Worker /* from HLF*/ { fromHLFto8, fromHLFto16, fromHLFto16SE, copy16, fromHLFtoFLT, fromHLFtoDBL },
386*3ac0a46fSAndroid Build Coastguard Worker /* from FLT*/ { fromFLTto8, fromFLTto16, fromFLTto16SE, fromFLTtoHLF, copy32, fromFLTtoDBL },
387*3ac0a46fSAndroid Build Coastguard Worker /* from DBL*/ { fromDBLto8, fromDBLto16, fromDBLto16SE, fromDBLtoHLF, fromDBLtoFLT, copy64 }};
388*3ac0a46fSAndroid Build Coastguard Worker
389*3ac0a46fSAndroid Build Coastguard Worker int in_n = FormatterPos(in);
390*3ac0a46fSAndroid Build Coastguard Worker int out_n = FormatterPos(out);
391*3ac0a46fSAndroid Build Coastguard Worker
392*3ac0a46fSAndroid Build Coastguard Worker if (in_n < 0 || out_n < 0 || in_n > 5 || out_n > 5) {
393*3ac0a46fSAndroid Build Coastguard Worker
394*3ac0a46fSAndroid Build Coastguard Worker cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized alpha channel width");
395*3ac0a46fSAndroid Build Coastguard Worker return NULL;
396*3ac0a46fSAndroid Build Coastguard Worker }
397*3ac0a46fSAndroid Build Coastguard Worker
398*3ac0a46fSAndroid Build Coastguard Worker return FormattersAlpha[in_n][out_n];
399*3ac0a46fSAndroid Build Coastguard Worker }
400*3ac0a46fSAndroid Build Coastguard Worker
401*3ac0a46fSAndroid Build Coastguard Worker
402*3ac0a46fSAndroid Build Coastguard Worker
403*3ac0a46fSAndroid Build Coastguard Worker // This function computes the distance from each component to the next one in bytes.
404*3ac0a46fSAndroid Build Coastguard Worker static
ComputeIncrementsForChunky(cmsUInt32Number Format,cmsUInt32Number ComponentStartingOrder[],cmsUInt32Number ComponentPointerIncrements[])405*3ac0a46fSAndroid Build Coastguard Worker void ComputeIncrementsForChunky(cmsUInt32Number Format,
406*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number ComponentStartingOrder[],
407*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number ComponentPointerIncrements[])
408*3ac0a46fSAndroid Build Coastguard Worker {
409*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number channels[cmsMAXCHANNELS];
410*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number extra = T_EXTRA(Format);
411*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number nchannels = T_CHANNELS(Format);
412*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number total_chans = nchannels + extra;
413*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number i;
414*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number channelSize = trueBytesSize(Format);
415*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number pixelSize = channelSize * total_chans;
416*3ac0a46fSAndroid Build Coastguard Worker
417*3ac0a46fSAndroid Build Coastguard Worker // Sanity check
418*3ac0a46fSAndroid Build Coastguard Worker if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS)
419*3ac0a46fSAndroid Build Coastguard Worker return;
420*3ac0a46fSAndroid Build Coastguard Worker
421*3ac0a46fSAndroid Build Coastguard Worker memset(channels, 0, sizeof(channels));
422*3ac0a46fSAndroid Build Coastguard Worker
423*3ac0a46fSAndroid Build Coastguard Worker // Separation is independent of starting point and only depends on channel size
424*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < extra; i++)
425*3ac0a46fSAndroid Build Coastguard Worker ComponentPointerIncrements[i] = pixelSize;
426*3ac0a46fSAndroid Build Coastguard Worker
427*3ac0a46fSAndroid Build Coastguard Worker // Handle do swap
428*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < total_chans; i++)
429*3ac0a46fSAndroid Build Coastguard Worker {
430*3ac0a46fSAndroid Build Coastguard Worker if (T_DOSWAP(Format)) {
431*3ac0a46fSAndroid Build Coastguard Worker channels[i] = total_chans - i - 1;
432*3ac0a46fSAndroid Build Coastguard Worker }
433*3ac0a46fSAndroid Build Coastguard Worker else {
434*3ac0a46fSAndroid Build Coastguard Worker channels[i] = i;
435*3ac0a46fSAndroid Build Coastguard Worker }
436*3ac0a46fSAndroid Build Coastguard Worker }
437*3ac0a46fSAndroid Build Coastguard Worker
438*3ac0a46fSAndroid Build Coastguard Worker // Handle swap first (ROL of positions), example CMYK -> KCMY | 0123 -> 3012
439*3ac0a46fSAndroid Build Coastguard Worker if (T_SWAPFIRST(Format) && total_chans > 1) {
440*3ac0a46fSAndroid Build Coastguard Worker
441*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number tmp = channels[0];
442*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < total_chans-1; i++)
443*3ac0a46fSAndroid Build Coastguard Worker channels[i] = channels[i + 1];
444*3ac0a46fSAndroid Build Coastguard Worker
445*3ac0a46fSAndroid Build Coastguard Worker channels[total_chans - 1] = tmp;
446*3ac0a46fSAndroid Build Coastguard Worker }
447*3ac0a46fSAndroid Build Coastguard Worker
448*3ac0a46fSAndroid Build Coastguard Worker // Handle size
449*3ac0a46fSAndroid Build Coastguard Worker if (channelSize > 1)
450*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < total_chans; i++) {
451*3ac0a46fSAndroid Build Coastguard Worker channels[i] *= channelSize;
452*3ac0a46fSAndroid Build Coastguard Worker }
453*3ac0a46fSAndroid Build Coastguard Worker
454*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < extra; i++)
455*3ac0a46fSAndroid Build Coastguard Worker ComponentStartingOrder[i] = channels[i + nchannels];
456*3ac0a46fSAndroid Build Coastguard Worker }
457*3ac0a46fSAndroid Build Coastguard Worker
458*3ac0a46fSAndroid Build Coastguard Worker
459*3ac0a46fSAndroid Build Coastguard Worker
460*3ac0a46fSAndroid Build Coastguard Worker // On planar configurations, the distance is the stride added to any non-negative
461*3ac0a46fSAndroid Build Coastguard Worker static
ComputeIncrementsForPlanar(cmsUInt32Number Format,cmsUInt32Number BytesPerPlane,cmsUInt32Number ComponentStartingOrder[],cmsUInt32Number ComponentPointerIncrements[])462*3ac0a46fSAndroid Build Coastguard Worker void ComputeIncrementsForPlanar(cmsUInt32Number Format,
463*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number BytesPerPlane,
464*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number ComponentStartingOrder[],
465*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number ComponentPointerIncrements[])
466*3ac0a46fSAndroid Build Coastguard Worker {
467*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number channels[cmsMAXCHANNELS];
468*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number extra = T_EXTRA(Format);
469*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number nchannels = T_CHANNELS(Format);
470*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number total_chans = nchannels + extra;
471*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number i;
472*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number channelSize = trueBytesSize(Format);
473*3ac0a46fSAndroid Build Coastguard Worker
474*3ac0a46fSAndroid Build Coastguard Worker // Sanity check
475*3ac0a46fSAndroid Build Coastguard Worker if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS)
476*3ac0a46fSAndroid Build Coastguard Worker return;
477*3ac0a46fSAndroid Build Coastguard Worker
478*3ac0a46fSAndroid Build Coastguard Worker memset(channels, 0, sizeof(channels));
479*3ac0a46fSAndroid Build Coastguard Worker
480*3ac0a46fSAndroid Build Coastguard Worker // Separation is independent of starting point and only depends on channel size
481*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < extra; i++)
482*3ac0a46fSAndroid Build Coastguard Worker ComponentPointerIncrements[i] = channelSize;
483*3ac0a46fSAndroid Build Coastguard Worker
484*3ac0a46fSAndroid Build Coastguard Worker // Handle do swap
485*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < total_chans; i++)
486*3ac0a46fSAndroid Build Coastguard Worker {
487*3ac0a46fSAndroid Build Coastguard Worker if (T_DOSWAP(Format)) {
488*3ac0a46fSAndroid Build Coastguard Worker channels[i] = total_chans - i - 1;
489*3ac0a46fSAndroid Build Coastguard Worker }
490*3ac0a46fSAndroid Build Coastguard Worker else {
491*3ac0a46fSAndroid Build Coastguard Worker channels[i] = i;
492*3ac0a46fSAndroid Build Coastguard Worker }
493*3ac0a46fSAndroid Build Coastguard Worker }
494*3ac0a46fSAndroid Build Coastguard Worker
495*3ac0a46fSAndroid Build Coastguard Worker // Handle swap first (ROL of positions), example CMYK -> KCMY | 0123 -> 3012
496*3ac0a46fSAndroid Build Coastguard Worker if (T_SWAPFIRST(Format) && total_chans > 0) {
497*3ac0a46fSAndroid Build Coastguard Worker
498*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number tmp = channels[0];
499*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < total_chans - 1; i++)
500*3ac0a46fSAndroid Build Coastguard Worker channels[i] = channels[i + 1];
501*3ac0a46fSAndroid Build Coastguard Worker
502*3ac0a46fSAndroid Build Coastguard Worker channels[total_chans - 1] = tmp;
503*3ac0a46fSAndroid Build Coastguard Worker }
504*3ac0a46fSAndroid Build Coastguard Worker
505*3ac0a46fSAndroid Build Coastguard Worker // Handle size
506*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < total_chans; i++) {
507*3ac0a46fSAndroid Build Coastguard Worker channels[i] *= BytesPerPlane;
508*3ac0a46fSAndroid Build Coastguard Worker }
509*3ac0a46fSAndroid Build Coastguard Worker
510*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < extra; i++)
511*3ac0a46fSAndroid Build Coastguard Worker ComponentStartingOrder[i] = channels[i + nchannels];
512*3ac0a46fSAndroid Build Coastguard Worker }
513*3ac0a46fSAndroid Build Coastguard Worker
514*3ac0a46fSAndroid Build Coastguard Worker
515*3ac0a46fSAndroid Build Coastguard Worker
516*3ac0a46fSAndroid Build Coastguard Worker // Dispatcher por chunky and planar RGB
517*3ac0a46fSAndroid Build Coastguard Worker static
ComputeComponentIncrements(cmsUInt32Number Format,cmsUInt32Number BytesPerPlane,cmsUInt32Number ComponentStartingOrder[],cmsUInt32Number ComponentPointerIncrements[])518*3ac0a46fSAndroid Build Coastguard Worker void ComputeComponentIncrements(cmsUInt32Number Format,
519*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number BytesPerPlane,
520*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number ComponentStartingOrder[],
521*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number ComponentPointerIncrements[])
522*3ac0a46fSAndroid Build Coastguard Worker {
523*3ac0a46fSAndroid Build Coastguard Worker if (T_PLANAR(Format)) {
524*3ac0a46fSAndroid Build Coastguard Worker
525*3ac0a46fSAndroid Build Coastguard Worker ComputeIncrementsForPlanar(Format, BytesPerPlane, ComponentStartingOrder, ComponentPointerIncrements);
526*3ac0a46fSAndroid Build Coastguard Worker }
527*3ac0a46fSAndroid Build Coastguard Worker else {
528*3ac0a46fSAndroid Build Coastguard Worker ComputeIncrementsForChunky(Format, ComponentStartingOrder, ComponentPointerIncrements);
529*3ac0a46fSAndroid Build Coastguard Worker }
530*3ac0a46fSAndroid Build Coastguard Worker
531*3ac0a46fSAndroid Build Coastguard Worker }
532*3ac0a46fSAndroid Build Coastguard Worker
533*3ac0a46fSAndroid Build Coastguard Worker
534*3ac0a46fSAndroid Build Coastguard Worker
535*3ac0a46fSAndroid Build Coastguard Worker // Handles extra channels copying alpha if requested by the flags
_cmsHandleExtraChannels(_cmsTRANSFORM * p,const void * in,void * out,cmsUInt32Number PixelsPerLine,cmsUInt32Number LineCount,const cmsStride * Stride)536*3ac0a46fSAndroid Build Coastguard Worker void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,
537*3ac0a46fSAndroid Build Coastguard Worker void* out,
538*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number PixelsPerLine,
539*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number LineCount,
540*3ac0a46fSAndroid Build Coastguard Worker const cmsStride* Stride)
541*3ac0a46fSAndroid Build Coastguard Worker {
542*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number i, j, k;
543*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number nExtra;
544*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number SourceStartingOrder[cmsMAXCHANNELS];
545*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number SourceIncrements[cmsMAXCHANNELS];
546*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number DestStartingOrder[cmsMAXCHANNELS];
547*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number DestIncrements[cmsMAXCHANNELS];
548*3ac0a46fSAndroid Build Coastguard Worker
549*3ac0a46fSAndroid Build Coastguard Worker cmsFormatterAlphaFn copyValueFn;
550*3ac0a46fSAndroid Build Coastguard Worker
551*3ac0a46fSAndroid Build Coastguard Worker // Make sure we need some copy
552*3ac0a46fSAndroid Build Coastguard Worker if (!(p->dwOriginalFlags & cmsFLAGS_COPY_ALPHA))
553*3ac0a46fSAndroid Build Coastguard Worker return;
554*3ac0a46fSAndroid Build Coastguard Worker
555*3ac0a46fSAndroid Build Coastguard Worker // Exit early if in-place color-management is occurring - no need to copy extra channels to themselves.
556*3ac0a46fSAndroid Build Coastguard Worker if (p->InputFormat == p->OutputFormat && in == out)
557*3ac0a46fSAndroid Build Coastguard Worker return;
558*3ac0a46fSAndroid Build Coastguard Worker
559*3ac0a46fSAndroid Build Coastguard Worker // Make sure we have same number of alpha channels. If not, just return as this should be checked at transform creation time.
560*3ac0a46fSAndroid Build Coastguard Worker nExtra = T_EXTRA(p->InputFormat);
561*3ac0a46fSAndroid Build Coastguard Worker if (nExtra != T_EXTRA(p->OutputFormat))
562*3ac0a46fSAndroid Build Coastguard Worker return;
563*3ac0a46fSAndroid Build Coastguard Worker
564*3ac0a46fSAndroid Build Coastguard Worker // Anything to do?
565*3ac0a46fSAndroid Build Coastguard Worker if (nExtra == 0)
566*3ac0a46fSAndroid Build Coastguard Worker return;
567*3ac0a46fSAndroid Build Coastguard Worker
568*3ac0a46fSAndroid Build Coastguard Worker // Compute the increments
569*3ac0a46fSAndroid Build Coastguard Worker ComputeComponentIncrements(p->InputFormat, Stride->BytesPerPlaneIn, SourceStartingOrder, SourceIncrements);
570*3ac0a46fSAndroid Build Coastguard Worker ComputeComponentIncrements(p->OutputFormat, Stride->BytesPerPlaneOut, DestStartingOrder, DestIncrements);
571*3ac0a46fSAndroid Build Coastguard Worker
572*3ac0a46fSAndroid Build Coastguard Worker // Check for conversions 8, 16, half, float, dbl
573*3ac0a46fSAndroid Build Coastguard Worker copyValueFn = _cmsGetFormatterAlpha(p->ContextID, p->InputFormat, p->OutputFormat);
574*3ac0a46fSAndroid Build Coastguard Worker if (copyValueFn == NULL)
575*3ac0a46fSAndroid Build Coastguard Worker return;
576*3ac0a46fSAndroid Build Coastguard Worker
577*3ac0a46fSAndroid Build Coastguard Worker if (nExtra == 1) { // Optimized routine for copying a single extra channel quickly
578*3ac0a46fSAndroid Build Coastguard Worker
579*3ac0a46fSAndroid Build Coastguard Worker cmsUInt8Number* SourcePtr;
580*3ac0a46fSAndroid Build Coastguard Worker cmsUInt8Number* DestPtr;
581*3ac0a46fSAndroid Build Coastguard Worker
582*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number SourceStrideIncrement = 0;
583*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number DestStrideIncrement = 0;
584*3ac0a46fSAndroid Build Coastguard Worker
585*3ac0a46fSAndroid Build Coastguard Worker // The loop itself
586*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < LineCount; i++) {
587*3ac0a46fSAndroid Build Coastguard Worker
588*3ac0a46fSAndroid Build Coastguard Worker // Prepare pointers for the loop
589*3ac0a46fSAndroid Build Coastguard Worker SourcePtr = (cmsUInt8Number*)in + SourceStartingOrder[0] + SourceStrideIncrement;
590*3ac0a46fSAndroid Build Coastguard Worker DestPtr = (cmsUInt8Number*)out + DestStartingOrder[0] + DestStrideIncrement;
591*3ac0a46fSAndroid Build Coastguard Worker
592*3ac0a46fSAndroid Build Coastguard Worker for (j = 0; j < PixelsPerLine; j++) {
593*3ac0a46fSAndroid Build Coastguard Worker
594*3ac0a46fSAndroid Build Coastguard Worker copyValueFn(DestPtr, SourcePtr);
595*3ac0a46fSAndroid Build Coastguard Worker
596*3ac0a46fSAndroid Build Coastguard Worker SourcePtr += SourceIncrements[0];
597*3ac0a46fSAndroid Build Coastguard Worker DestPtr += DestIncrements[0];
598*3ac0a46fSAndroid Build Coastguard Worker }
599*3ac0a46fSAndroid Build Coastguard Worker
600*3ac0a46fSAndroid Build Coastguard Worker SourceStrideIncrement += Stride->BytesPerLineIn;
601*3ac0a46fSAndroid Build Coastguard Worker DestStrideIncrement += Stride->BytesPerLineOut;
602*3ac0a46fSAndroid Build Coastguard Worker }
603*3ac0a46fSAndroid Build Coastguard Worker
604*3ac0a46fSAndroid Build Coastguard Worker }
605*3ac0a46fSAndroid Build Coastguard Worker else { // General case with more than one extra channel
606*3ac0a46fSAndroid Build Coastguard Worker
607*3ac0a46fSAndroid Build Coastguard Worker cmsUInt8Number* SourcePtr[cmsMAXCHANNELS];
608*3ac0a46fSAndroid Build Coastguard Worker cmsUInt8Number* DestPtr[cmsMAXCHANNELS];
609*3ac0a46fSAndroid Build Coastguard Worker
610*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number SourceStrideIncrements[cmsMAXCHANNELS];
611*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number DestStrideIncrements[cmsMAXCHANNELS];
612*3ac0a46fSAndroid Build Coastguard Worker
613*3ac0a46fSAndroid Build Coastguard Worker memset(SourceStrideIncrements, 0, sizeof(SourceStrideIncrements));
614*3ac0a46fSAndroid Build Coastguard Worker memset(DestStrideIncrements, 0, sizeof(DestStrideIncrements));
615*3ac0a46fSAndroid Build Coastguard Worker
616*3ac0a46fSAndroid Build Coastguard Worker // The loop itself
617*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < LineCount; i++) {
618*3ac0a46fSAndroid Build Coastguard Worker
619*3ac0a46fSAndroid Build Coastguard Worker // Prepare pointers for the loop
620*3ac0a46fSAndroid Build Coastguard Worker for (j = 0; j < nExtra; j++) {
621*3ac0a46fSAndroid Build Coastguard Worker
622*3ac0a46fSAndroid Build Coastguard Worker SourcePtr[j] = (cmsUInt8Number*)in + SourceStartingOrder[j] + SourceStrideIncrements[j];
623*3ac0a46fSAndroid Build Coastguard Worker DestPtr[j] = (cmsUInt8Number*)out + DestStartingOrder[j] + DestStrideIncrements[j];
624*3ac0a46fSAndroid Build Coastguard Worker }
625*3ac0a46fSAndroid Build Coastguard Worker
626*3ac0a46fSAndroid Build Coastguard Worker for (j = 0; j < PixelsPerLine; j++) {
627*3ac0a46fSAndroid Build Coastguard Worker
628*3ac0a46fSAndroid Build Coastguard Worker for (k = 0; k < nExtra; k++) {
629*3ac0a46fSAndroid Build Coastguard Worker
630*3ac0a46fSAndroid Build Coastguard Worker copyValueFn(DestPtr[k], SourcePtr[k]);
631*3ac0a46fSAndroid Build Coastguard Worker
632*3ac0a46fSAndroid Build Coastguard Worker SourcePtr[k] += SourceIncrements[k];
633*3ac0a46fSAndroid Build Coastguard Worker DestPtr[k] += DestIncrements[k];
634*3ac0a46fSAndroid Build Coastguard Worker }
635*3ac0a46fSAndroid Build Coastguard Worker }
636*3ac0a46fSAndroid Build Coastguard Worker
637*3ac0a46fSAndroid Build Coastguard Worker for (j = 0; j < nExtra; j++) {
638*3ac0a46fSAndroid Build Coastguard Worker
639*3ac0a46fSAndroid Build Coastguard Worker SourceStrideIncrements[j] += Stride->BytesPerLineIn;
640*3ac0a46fSAndroid Build Coastguard Worker DestStrideIncrements[j] += Stride->BytesPerLineOut;
641*3ac0a46fSAndroid Build Coastguard Worker }
642*3ac0a46fSAndroid Build Coastguard Worker }
643*3ac0a46fSAndroid Build Coastguard Worker }
644*3ac0a46fSAndroid Build Coastguard Worker }
645*3ac0a46fSAndroid Build Coastguard Worker
646*3ac0a46fSAndroid Build Coastguard Worker
647