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