1 /* babl - dynamically extendable universal pixel conversion library.
2 * Copyright (C) 2012, Øyvind Kolås
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 3 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General
15 * Public License along with this library; if not, see
16 * <https://www.gnu.org/licenses/>.
24 #include "babl-internal.h"
25 #include "babl-cpuaccel.h"
26 #include "extensions/util.h"
27 #include "base/util.h"
29 static const Babl
*trc_srgb
= NULL
;
33 conv_yaF_linear_yAF_linear (const Babl
*conversion
,
34 unsigned char *__restrict__ src
,
35 unsigned char *__restrict__ dst
,
38 float *fsrc
= (float *) src
;
39 float *fdst
= (float *) dst
;
44 float alpha
= fsrc
[1];
45 float used_alpha
= babl_epsilon_for_zero_float (alpha
);
46 *fdst
++ = (*fsrc
++) * used_alpha
;
54 conv_yAF_linear_yaF_linear (const Babl
*conversion
,
55 unsigned char *__restrict__ src
,
56 unsigned char *__restrict__ dst
,
59 float *fsrc
= (float *) src
;
60 float *fdst
= (float *) dst
;
65 float alpha
= fsrc
[1];
66 float alpha_reciprocal
= 1.0f
/babl_epsilon_for_zero_float (alpha
);
67 *fdst
++ = (*fsrc
++) * alpha_reciprocal
;
75 conv_yaF_linear_yAF_nonlinear (const Babl
*conversion
,
76 unsigned char *__restrict__ src
,
77 unsigned char *__restrict__ dst
,
80 const Babl
*space
= babl_conversion_get_destination_space (conversion
);
81 const Babl
**trc
= (void*)space
->space
.trc
;
83 float *fsrc
= (float *) src
;
84 float *fdst
= (float *) dst
;
89 float alpha
= fsrc
[1];
90 float used_alpha
= babl_epsilon_for_zero_float (alpha
);
91 *fdst
++ = babl_trc_from_linear (trc
[0], *fsrc
++) * used_alpha
;
98 conv_rgbaF_linear_rgbAF_nonlinear (const Babl
*conversion
,
99 unsigned char *__restrict__ src
,
100 unsigned char *__restrict__ dst
,
103 const Babl
*space
= babl_conversion_get_destination_space (conversion
);
104 const Babl
**trc
= (void*)space
->space
.trc
;
106 float *fsrc
= (float *) src
;
107 float *fdst
= (float *) dst
;
112 float alpha
= fsrc
[3];
113 float used_alpha
= babl_epsilon_for_zero_float (alpha
);
114 *fdst
++ = babl_trc_from_linear (trc
[0], *fsrc
++) * used_alpha
;
115 *fdst
++ = babl_trc_from_linear (trc
[1], *fsrc
++) * used_alpha
;
116 *fdst
++ = babl_trc_from_linear (trc
[2], *fsrc
++) * used_alpha
;
123 conv_rgbaF_linear_rgbAF_perceptual (const Babl
*conversion
,
124 unsigned char *__restrict__ src
,
125 unsigned char *__restrict__ dst
,
128 float *fsrc
= (float *) src
;
129 float *fdst
= (float *) dst
;
134 float alpha
= fsrc
[3];
135 float used_alpha
= babl_epsilon_for_zero (alpha
);
136 *fdst
++ = babl_trc_from_linear (trc_srgb
, *fsrc
++) * used_alpha
;
137 *fdst
++ = babl_trc_from_linear (trc_srgb
, *fsrc
++) * used_alpha
;
138 *fdst
++ = babl_trc_from_linear (trc_srgb
, *fsrc
++) * used_alpha
;
146 conv_rgbAF_linear_rgbAF_nonlinear (const Babl
*conversion
,
147 unsigned char *__restrict__ src
,
148 unsigned char *__restrict__ dst
,
151 const Babl
*space
= babl_conversion_get_destination_space (conversion
);
152 const Babl
**trc
= (void*)space
->space
.trc
;
154 float *fsrc
= (float *) src
;
155 float *fdst
= (float *) dst
;
160 float alpha
= fsrc
[3];
171 float alpha_recip
= 1.0f
/ alpha
;
172 *fdst
++ = babl_trc_from_linear (trc
[0], *fsrc
++ * alpha_recip
) * alpha
;
173 *fdst
++ = babl_trc_from_linear (trc
[1], *fsrc
++ * alpha_recip
) * alpha
;
174 *fdst
++ = babl_trc_from_linear (trc
[2], *fsrc
++ * alpha_recip
) * alpha
;
182 conv_yAF_linear_yAF_nonlinear (const Babl
*conversion
,
183 unsigned char *__restrict__ src
,
184 unsigned char *__restrict__ dst
,
187 const Babl
*space
= babl_conversion_get_destination_space (conversion
);
188 const Babl
**trc
= (void*)space
->space
.trc
;
190 float *fsrc
= (float *) src
;
191 float *fdst
= (float *) dst
;
196 float alpha
= fsrc
[1];
207 float alpha_recip
= 1.0f
/ alpha
;
208 *fdst
++ = babl_trc_from_linear (trc
[0], *fsrc
++ * alpha_recip
) * alpha
;
217 conv_rgbAF_linear_rgbAF_perceptual (const Babl
*conversion
,
218 unsigned char *__restrict__ src
,
219 unsigned char *__restrict__ dst
,
223 float *fsrc
= (float *) src
;
224 float *fdst
= (float *) dst
;
229 float alpha
= fsrc
[3];
240 float alpha_recip
= 1.0f
/ alpha
;
241 *fdst
++ = babl_trc_from_linear (trc_srgb
, *fsrc
++ * alpha_recip
) * alpha
;
242 *fdst
++ = babl_trc_from_linear (trc_srgb
, *fsrc
++ * alpha_recip
) * alpha
;
243 *fdst
++ = babl_trc_from_linear (trc_srgb
, *fsrc
++ * alpha_recip
) * alpha
;
251 conv_yaF_linear_yaF_nonlinear (const Babl
*conversion
,
252 unsigned char *__restrict__ src
,
253 unsigned char *__restrict__ dst
,
256 const Babl
*space
= babl_conversion_get_destination_space (conversion
);
257 const Babl
**trc
= (void*)space
->space
.trc
;
259 float *fsrc
= (float *) src
;
260 float *fdst
= (float *) dst
;
261 babl_trc_from_linear_buf (trc
[0], fsrc
, fdst
, 2, 2, 1, samples
);
265 conv_rgbaF_linear_rgbaF_nonlinear (const Babl
*conversion
,
266 unsigned char *__restrict__ src
,
267 unsigned char *__restrict__ dst
,
270 const Babl
*space
= babl_conversion_get_destination_space (conversion
);
271 const Babl
**trc
= (void*)space
->space
.trc
;
273 float *fsrc
= (float *) src
;
274 float *fdst
= (float *) dst
;
279 *fdst
++ = babl_trc_from_linear (trc
[0], *fsrc
++);
280 *fdst
++ = babl_trc_from_linear (trc
[1], *fsrc
++);
281 *fdst
++ = babl_trc_from_linear (trc
[2], *fsrc
++);
287 conv_rgbaF_linear_rgbaF_perceptual (const Babl
*conversion
,
288 unsigned char *__restrict__ src
,
289 unsigned char *__restrict__ dst
,
292 float *fsrc
= (float *) src
;
293 float *fdst
= (float *) dst
;
294 babl_trc_from_linear_buf (trc_srgb
, fsrc
, fdst
, 4, 4, 3, samples
);
298 conv_yF_linear_yF_nonlinear (const Babl
*conversion
,
299 unsigned char *__restrict__ src
,
300 unsigned char *__restrict__ dst
,
303 const Babl
*space
= babl_conversion_get_destination_space (conversion
);
304 const Babl
**trc
= (void*)space
->space
.trc
;
305 float *fsrc
= (float *) src
;
306 float *fdst
= (float *) dst
;
307 babl_trc_from_linear_buf (trc
[0], fsrc
, fdst
, 1, 1, 1, samples
);
312 conv_rgbF_linear_rgbF_nonlinear (const Babl
*conversion
,
313 unsigned char *__restrict__ src
,
314 unsigned char *__restrict__ dst
,
317 const Babl
*space
= babl_conversion_get_destination_space (conversion
);
318 const Babl
**trc
= (void*)space
->space
.trc
;
319 float *fsrc
= (float *) src
;
320 float *fdst
= (float *) dst
;
325 *fdst
++ = babl_trc_from_linear (trc
[0], *fsrc
++);
326 *fdst
++ = babl_trc_from_linear (trc
[1], *fsrc
++);
327 *fdst
++ = babl_trc_from_linear (trc
[2], *fsrc
++);
332 conv_rgbF_linear_rgbF_perceptual (const Babl
*conversion
,
333 unsigned char *__restrict__ src
,
334 unsigned char *__restrict__ dst
,
337 float *fsrc
= (float *) src
;
338 float *fdst
= (float *) dst
;
339 babl_trc_from_linear_buf (trc_srgb
, fsrc
, fdst
, 3, 3, 3, samples
);
343 conv_rgbaF_nonlinear_rgbaF_linear (const Babl
*conversion
,
344 unsigned char *__restrict__ src
,
345 unsigned char *__restrict__ dst
,
348 const Babl
*space
= babl_conversion_get_destination_space (conversion
);
349 const Babl
**trc
= (void*)space
->space
.trc
;
350 float *fsrc
= (float *) src
;
351 float *fdst
= (float *) dst
;
356 *fdst
++ = babl_trc_to_linear (trc
[0], *fsrc
++);
357 *fdst
++ = babl_trc_to_linear (trc
[1], *fsrc
++);
358 *fdst
++ = babl_trc_to_linear (trc
[2], *fsrc
++);
365 conv_yaF_nonlinear_yaF_linear (const Babl
*conversion
,
366 unsigned char *__restrict__ src
,
367 unsigned char *__restrict__ dst
,
370 const Babl
*space
= babl_conversion_get_destination_space (conversion
);
371 const Babl
**trc
= (void*)space
->space
.trc
;
372 float *fsrc
= (float *) src
;
373 float *fdst
= (float *) dst
;
374 babl_trc_to_linear_buf (trc
[0], fsrc
, fdst
, 2, 2, 1, samples
);
379 conv_rgbaF_perceptual_rgbaF_linear (const Babl
*conversion
,
380 unsigned char *__restrict__ src
,
381 unsigned char *__restrict__ dst
,
384 float *fsrc
= (float *) src
;
385 float *fdst
= (float *) dst
;
386 babl_trc_to_linear_buf (trc_srgb
, fsrc
, fdst
, 4, 4, 3, samples
);
391 conv_rgbF_nonlinear_rgbF_linear (const Babl
*conversion
,
392 unsigned char *__restrict__ src
,
393 unsigned char *__restrict__ dst
,
396 const Babl
*space
= babl_conversion_get_destination_space (conversion
);
397 const Babl
**trc
= (void*)space
->space
.trc
;
398 float *fsrc
= (float *) src
;
399 float *fdst
= (float *) dst
;
404 *fdst
++ = babl_trc_to_linear (trc
[0], *fsrc
++);
405 *fdst
++ = babl_trc_to_linear (trc
[1], *fsrc
++);
406 *fdst
++ = babl_trc_to_linear (trc
[2], *fsrc
++);
412 conv_yF_nonlinear_yF_linear (const Babl
*conversion
,
413 unsigned char *__restrict__ src
,
414 unsigned char *__restrict__ dst
,
417 const Babl
*space
= babl_conversion_get_destination_space (conversion
);
418 const Babl
**trc
= (void*)space
->space
.trc
;
419 float *fsrc
= (float *) src
;
420 float *fdst
= (float *) dst
;
422 babl_trc_to_linear_buf (trc
[0], fsrc
, fdst
, 1, 1, 1, samples
);
426 conv_rgbF_perceptual_rgbF_linear (const Babl
*conversion
,
427 unsigned char *__restrict__ src
,
428 unsigned char *__restrict__ dst
,
431 float *fsrc
= (float *) src
;
432 float *fdst
= (float *) dst
;
433 babl_trc_to_linear_buf (trc_srgb
, fsrc
, fdst
, 3, 3, 3, samples
);
437 #define o(src, dst) \
438 babl_conversion_new (src, dst, "linear", conv_ ## src ## _ ## dst, NULL)
441 #include "babl-verify-cpu.inc"
448 const Babl
*yaF_linear
= babl_format_new (
451 babl_component ("Y"),
452 babl_component ("A"),
454 const Babl
*yAF_linear
= babl_format_new (
457 babl_component ("Ya"),
458 babl_component ("A"),
460 const Babl
*yaF_nonlinear
= babl_format_new (
463 babl_component ("Y'"),
464 babl_component ("A"),
466 const Babl
*rgbaF_linear
= babl_format_new (
469 babl_component ("R"),
470 babl_component ("G"),
471 babl_component ("B"),
472 babl_component ("A"),
474 const Babl
*rgbAF_linear
= babl_format_new (
475 babl_model ("RaGaBaA"),
477 babl_component ("Ra"),
478 babl_component ("Ga"),
479 babl_component ("Ba"),
480 babl_component ("A"),
482 const Babl
*rgbaF_nonlinear
= babl_format_new (
483 babl_model ("R'G'B'A"),
485 babl_component ("R'"),
486 babl_component ("G'"),
487 babl_component ("B'"),
488 babl_component ("A"),
490 const Babl
*rgbaF_perceptual
= babl_format_new (
491 babl_model ("R~G~B~A"),
493 babl_component ("R~"),
494 babl_component ("G~"),
495 babl_component ("B~"),
496 babl_component ("A"),
498 const Babl
*yAF_nonlinear
= babl_format_new (
501 babl_component ("Y'a"),
502 babl_component ("A"),
504 const Babl
*rgbAF_nonlinear
= babl_format_new (
505 babl_model ("R'aG'aB'aA"),
507 babl_component ("R'a"),
508 babl_component ("G'a"),
509 babl_component ("B'a"),
510 babl_component ("A"),
512 const Babl
*rgbAF_perceptual
= babl_format_new (
513 babl_model ("R~aG~aB~aA"),
515 babl_component ("R~a"),
516 babl_component ("G~a"),
517 babl_component ("B~a"),
518 babl_component ("A"),
520 const Babl
*yF_linear
= babl_format_new (
523 babl_component ("Y"),
525 const Babl
*yF_nonlinear
= babl_format_new (
528 babl_component ("Y'"),
530 const Babl
*rgbF_linear
= babl_format_new (
533 babl_component ("R"),
534 babl_component ("G"),
535 babl_component ("B"),
537 const Babl
*rgbF_nonlinear
= babl_format_new (
538 babl_model ("R'G'B'"),
540 babl_component ("R'"),
541 babl_component ("G'"),
542 babl_component ("B'"),
544 const Babl
*rgbF_perceptual
= babl_format_new (
545 babl_model ("R~G~B~"),
547 babl_component ("R~"),
548 babl_component ("G~"),
549 babl_component ("B~"),
551 trc_srgb
= babl_trc("sRGB");
553 o (rgbAF_linear
, rgbAF_nonlinear
);
554 o (rgbaF_linear
, rgbAF_nonlinear
);
555 o (rgbaF_linear
, rgbaF_nonlinear
);
556 o (rgbaF_nonlinear
, rgbaF_linear
);
557 o (rgbF_linear
, rgbF_nonlinear
);
558 o (rgbF_nonlinear
, rgbF_linear
);
561 o (yaF_linear
, yAF_linear
);
562 o (yAF_linear
, yaF_linear
);
563 o (yAF_linear
, yAF_nonlinear
);
564 o (yaF_linear
, yAF_nonlinear
);
565 o (yaF_linear
, yaF_nonlinear
);
566 o (yaF_nonlinear
, yaF_linear
);
567 o (yF_linear
, yF_nonlinear
);
568 o (yF_nonlinear
, yF_linear
);
570 o (rgbAF_linear
, rgbAF_perceptual
);
571 o (rgbaF_linear
, rgbAF_perceptual
);
572 o (rgbaF_linear
, rgbaF_perceptual
);
573 o (rgbaF_perceptual
, rgbaF_linear
);
574 o (rgbF_linear
, rgbF_perceptual
);
575 o (rgbF_perceptual
, rgbF_linear
);