1 /* babl - dynamically extendable universal pixel conversion library.
2 * Copyright (C) 2005, 2014, 2019 Øyvind Kolås.
3 * Copyright (C) 2009, Martin Nordholts
4 * Copyright (C) 2014, 2019 Elle Stone
5 * Copyright (C) 2017, 2018 Red Hat, Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 3 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General
18 * Public License along with this library; if not, see
19 * <https://www.gnu.org/licenses/>.
28 #include <emmintrin.h>
29 #endif /* defined(USE_SSE2) */
31 #include "babl-internal.h"
32 #include "extensions/util.h"
34 #define DEGREES_PER_RADIAN (180 / 3.14159265358979323846)
35 #define RADIANS_PER_DEGREE (1 / DEGREES_PER_RADIAN)
36 #define DEGREES_PER_RADIANf (180 / 3.14159265358979323846f)
37 #define RADIANS_PER_DEGREEf (1 / DEGREES_PER_RADIANf)
39 #define LAB_EPSILON (216.0 / 24389.0)
40 #define LAB_EPSILONf (216.0f / 24389.0f)
41 #define LAB_KAPPA (24389.0 / 27.0)
42 #define LAB_KAPPAf (24389.0f / 27.0f)
44 /* The constants below hard-code the D50-adapted sRGB ICC profile
45 * reference white, aka the ICC profile D50 illuminant.
47 * In a properly ICC profile color-managed application, the profile
48 * illuminant values should be retrieved from the image's
49 * ICC profile's illuminant.
51 * At present, the ICC profile illuminant is always D50. This might
52 * change when the next version of the ICC specs is released.
54 * As encoded in an actual V2 or V4 ICC profile,
55 * the illuminant values are hexadecimal-rounded, as are the following
56 * hard-coded D50 ICC profile illuminant values:
59 #define D50_WHITE_REF_X 0.964202880
60 #define D50_WHITE_REF_Y 1.000000000
61 #define D50_WHITE_REF_Z 0.824905400
63 #define D50_WHITE_REF_Xf 0.964202880f
64 #define D50_WHITE_REF_Yf 1.000000000f
65 #define D50_WHITE_REF_Zf 0.824905400f
67 #define NEAR_ZERO 0.0000000001
68 #define NEAR_ZEROf 0.0000000001f
69 #define near_zero(a) ((a) < NEAR_ZERO && (a) > -NEAR_ZERO)
70 #define near_zerof(a) ((a) < NEAR_ZEROf && (a) > -NEAR_ZEROf)
72 #define D50_WHITE_REF_x 0.345702921222f
73 #define D50_WHITE_REF_y 0.358537532290f
76 static void types (void);
77 static void components (void);
78 static void models (void);
79 static void conversions (void);
80 static void formats (void);
83 #include "babl-verify-cpu.inc"
100 babl_component_new ("CIE L", "doc", "Luminance, range 0.0-100.0 in float", NULL
);
101 babl_component_new ("CIE a", "chroma", "doc", "chroma component 0.0 is no saturation", NULL
);
102 babl_component_new ("CIE b", "chroma", "doc", "chroma component 0.0 is no saturation", NULL
);
103 babl_component_new ("CIE C(ab)", "chroma", "doc", "chrominance/saturation", NULL
);
104 babl_component_new ("CIE H(ab)", "chroma", "doc", "hue value range 0.0-360.0", NULL
);
105 babl_component_new ("CIE X", NULL
);
106 babl_component_new ("CIE Y", NULL
);
107 babl_component_new ("CIE Z", NULL
);
108 babl_component_new ("CIE x", NULL
);
109 babl_component_new ("CIE y", NULL
);
111 babl_component_new ("CIE u", NULL
);
112 babl_component_new ("CIE v", NULL
);
113 /* babl_component_new ("CIE z", NULL);*/
121 "doc", "CIE Lab color model, a perceptually uniform space, euclidian distance in this space represents delta E.",
122 babl_component ("CIE L"),
123 babl_component ("CIE a"),
124 babl_component ("CIE b"),
129 "name", "CIE Lab alpha",
130 "doc", "CIE Lab color model, with separate alpha",
131 babl_component ("CIE L"),
132 babl_component ("CIE a"),
133 babl_component ("CIE b"),
134 babl_component ("A"),
140 "name", "CIE LCH(ab)",
141 "doc", "CIE LCH color model, using cylindrical coordinates",
142 babl_component ("CIE L"),
143 babl_component ("CIE C(ab)"),
144 babl_component ("CIE H(ab)"),
149 "name", "CIE LCH(ab) alpha",
150 "doc", "CIE LCH color model, using cylindrical coordinates, with separate alpha",
151 babl_component ("CIE L"),
152 babl_component ("CIE C(ab)"),
153 babl_component ("CIE H(ab)"),
154 babl_component ("A"),
161 babl_component ("CIE X"),
162 babl_component ("CIE Y"),
163 babl_component ("CIE Z"),
168 "name", "CIE XYZ alpha",
169 babl_component ("CIE X"),
170 babl_component ("CIE Y"),
171 babl_component ("CIE Z"),
172 babl_component ("A"),
179 "doc", "the coordinate system often used for drawing chromaticity diagrams. Y is luminance.",
180 babl_component ("CIE x"),
181 babl_component ("CIE y"),
182 babl_component ("CIE Y"),
187 "name", "CIE xyY alpha",
188 "doc", "the coordinate system often used for drawing chromaticity diagrams. Y is luminance, with separate alpha",
189 babl_component ("CIE x"),
190 babl_component ("CIE y"),
191 babl_component ("CIE Y"),
192 babl_component ("A"),
200 "doc", "A newer more perceptually uniform space than xyY for chromaticity diagrams.",
201 babl_component ("CIE Y"),
202 babl_component ("CIE u"),
203 babl_component ("CIE v"),
207 "name", "CIE Yuv alpha",
208 "doc", "A newer more perceptually uniform space than xyY for chromaticity diagrams, with separate alpha.",
209 babl_component ("CIE Y"),
210 babl_component ("CIE u"),
211 babl_component ("CIE v"),
212 babl_component ("A"),
216 static void rgbcie_init (void);
218 /******** begin double RGB/CIE color space conversions ****************/
220 static inline void ab_to_CHab (double a
,
225 static inline void CHab_to_ab (double C
,
230 static inline void XYZ_to_LAB (double X
,
238 static inline void LAB_to_XYZ (double L
,
246 static inline void XYZ_to_xyY (double X
,
254 static inline void xyY_to_XYZ (double x
,
263 static inline void XYZ_to_Yuv (double X
,
271 static inline void Yuv_to_XYZ (double Y
,
280 XYZ_to_LAB (double X
,
287 double xr
= X
/ D50_WHITE_REF_X
;
288 double yr
= Y
/ D50_WHITE_REF_Y
;
289 double zr
= Z
/ D50_WHITE_REF_Z
;
291 double fx
= xr
> LAB_EPSILON
? cbrt (xr
) : (LAB_KAPPA
* xr
+ 16.0) / 116.0;
292 double fy
= yr
> LAB_EPSILON
? cbrt (yr
) : (LAB_KAPPA
* yr
+ 16.0) / 116.0;
293 double fz
= zr
> LAB_EPSILON
? cbrt (zr
) : (LAB_KAPPA
* zr
+ 16.0) / 116.0;
295 *to_L
= 116.0 * fy
- 16.0;
296 *to_a
= 500.0 * (fx
- fy
);
297 *to_b
= 200.0 * (fy
- fz
);
301 LAB_to_XYZ (double L
,
308 double fy
= (L
+ 16.0) / 116.0;
309 double fy_cubed
= fy
* fy
* fy
;
311 double fx
= fy
+ a
/ 500.0;
312 double fx_cubed
= fx
* fx
* fx
;
314 double fz
= fy
- b
/ 200.0;
315 double fz_cubed
= fz
* fz
* fz
;
317 double yr
= L
> LAB_KAPPA
* LAB_EPSILON
? fy_cubed
: L
/ LAB_KAPPA
;
318 double xr
= fx_cubed
> LAB_EPSILON
? fx_cubed
: (fx
* 116.0 - 16.0) / LAB_KAPPA
;
319 double zr
= fz_cubed
> LAB_EPSILON
? fz_cubed
: (fz
* 116.0 - 16.0) / LAB_KAPPA
;
321 *to_X
= xr
* D50_WHITE_REF_X
;
322 *to_Y
= yr
* D50_WHITE_REF_Y
;
323 *to_Z
= zr
* D50_WHITE_REF_Z
;
328 XYZ_to_xyY (double X
,
335 double sum
= X
+ Y
+ Z
;
338 *to_x
= D50_WHITE_REF_x
;
339 *to_y
= D50_WHITE_REF_y
;
350 xyY_to_XYZ (double x
,
367 *to_Z
= ((1 - x
- y
) * Y
) / y
;
374 /* Code for near-zero XYZ and RGB for CIE 1976 UCS patterned
375 * after code written by and used with kind permission of Graeme Gill.
376 * Graeme Gill's code is in "icc.c"
377 * downloadable from http://argyllcms.com/ */
380 XYZ_to_Yuv (double X
,
387 double sum
= X
+ (15.0 * Y
) + (3.0 * Z
);
397 *to_u
= (4.0 * X
) / sum
;
398 *to_v
= (9.0 * Y
) / sum
;
403 Yuv_to_XYZ (double Y
,
418 *to_X
= ((9.0 * u
* Y
)/(4.0 * v
));
420 *to_Z
= -(((20.0 * v
+ 3.0 * u
- 12.0) * Y
)/(4.0 * v
));
427 rgba_to_xyz (const Babl
*conversion
,
432 const Babl
*space
= babl_conversion_get_source_space (conversion
);
435 double RGB
[3] = {((double *) src
)[0],
437 ((double *) src
)[2] };
438 babl_space_to_xyz (space
, RGB
, (double*)dst
);
440 src
+= sizeof (double) * 4;
441 dst
+= sizeof (double) * 3;
446 xyz_to_rgba (const Babl
*conversion
,
451 const Babl
*space
= babl_conversion_get_destination_space (conversion
);
454 babl_space_from_xyz (space
, (double*)src
, (double*) dst
);
455 ((double *) dst
)[3] = 1.0;
456 src
+= sizeof (double) * 3;
457 dst
+= sizeof (double) * 4;
462 rgba_to_xyza (const Babl
*conversion
,char *src
,
466 const Babl
*space
= babl_conversion_get_source_space (conversion
);
469 babl_space_to_xyz (space
, (double*)src
, (double*)dst
);
470 ((double *) dst
)[3] = ((double *) src
)[3];
472 src
+= sizeof (double) * 4;
473 dst
+= sizeof (double) * 4;
478 xyza_to_rgba (const Babl
*conversion
,char *src
,
482 const Babl
*space
= babl_conversion_get_destination_space (conversion
);
485 babl_space_from_xyz (space
, (double*)src
, (double*) dst
);
486 ((double *) dst
)[3] = ((double *) src
)[3];
488 src
+= sizeof (double) * 4;
489 dst
+= sizeof (double) * 4;
496 rgba_to_xyY (const Babl
*conversion
,
501 const Babl
*space
= babl_conversion_get_source_space (conversion
);
504 double XYZ
[3], x
, y
, Y
;
506 babl_space_to_xyz (space
, (double*)src
, XYZ
);
507 XYZ_to_xyY (XYZ
[0], XYZ
[1], XYZ
[2], &x
, &y
, &Y
);
509 ((double *) dst
)[0] = x
;
510 ((double *) dst
)[1] = y
;
511 ((double *) dst
)[2] = Y
;
513 src
+= sizeof (double) * 4;
514 dst
+= sizeof (double) * 3;
519 rgba_to_xyYa (const Babl
*conversion
,char *src
,
523 const Babl
*space
= babl_conversion_get_source_space (conversion
);
526 double alpha
= ((double *) src
)[3];
527 double XYZ
[3], x
, y
, Y
;
530 babl_space_to_xyz (space
, (double*)src
, XYZ
);
533 XYZ_to_xyY (XYZ
[0], XYZ
[1], XYZ
[2], &x
, &y
, &Y
);
535 ((double *) dst
)[0] = x
;
536 ((double *) dst
)[1] = y
;
537 ((double *) dst
)[2] = Y
;
538 ((double *) dst
)[3] = alpha
;
540 src
+= sizeof (double) * 4;
541 dst
+= sizeof (double) * 4;
549 rgba_to_Yuv (const Babl
*conversion
,char *src
,
553 const Babl
*space
= babl_conversion_get_source_space (conversion
);
556 double XYZ
[3], Y
, u
, v
;
558 babl_space_to_xyz (space
, (double*)src
, XYZ
);
559 XYZ_to_Yuv (XYZ
[0], XYZ
[1], XYZ
[2], &Y
, &u
, &v
);
561 ((double *) dst
)[0] = Y
;
562 ((double *) dst
)[1] = u
;
563 ((double *) dst
)[2] = v
;
565 src
+= sizeof (double) * 4;
566 dst
+= sizeof (double) * 3;
571 rgba_to_Yuva (const Babl
*conversion
,char *src
,
575 const Babl
*space
= babl_conversion_get_source_space (conversion
);
578 double alpha
= ((double *) src
)[3];
579 double XYZ
[3], Y
, u
, v
;
582 babl_space_to_xyz (space
, (double*)src
, XYZ
);
585 XYZ_to_Yuv (XYZ
[0], XYZ
[1], XYZ
[2], &Y
, &u
, &v
);
587 ((double *) dst
)[0] = Y
;
588 ((double *) dst
)[1] = u
;
589 ((double *) dst
)[2] = v
;
590 ((double *) dst
)[3] = alpha
;
592 src
+= sizeof (double) * 4;
593 dst
+= sizeof (double) * 4;
600 rgbaf_to_xyYaf (const Babl
*conversion
,
605 const Babl
*space
= babl_conversion_get_source_space (conversion
);
606 float m_0_0
= space
->space
.RGBtoXYZf
[0] / D50_WHITE_REF_Xf
;
607 float m_0_1
= space
->space
.RGBtoXYZf
[1] / D50_WHITE_REF_Xf
;
608 float m_0_2
= space
->space
.RGBtoXYZf
[2] / D50_WHITE_REF_Xf
;
609 float m_1_0
= space
->space
.RGBtoXYZf
[3] / D50_WHITE_REF_Yf
;
610 float m_1_1
= space
->space
.RGBtoXYZf
[4] / D50_WHITE_REF_Yf
;
611 float m_1_2
= space
->space
.RGBtoXYZf
[5] / D50_WHITE_REF_Yf
;
612 float m_2_0
= space
->space
.RGBtoXYZf
[6] / D50_WHITE_REF_Zf
;
613 float m_2_1
= space
->space
.RGBtoXYZf
[7] / D50_WHITE_REF_Zf
;
614 float m_2_2
= space
->space
.RGBtoXYZf
[8] / D50_WHITE_REF_Zf
;
619 float x
, y
, X
, Y
, Z
, r
, g
, b
, a
;
625 if (near_zerof(r
) && near_zerof(g
) && near_zerof(b
))
633 X
= m_0_0
* r
+ m_0_1
* g
+ m_0_2
* b
;
634 Y
= m_1_0
* r
+ m_1_1
* g
+ m_1_2
* b
;
635 Z
= m_2_0
* r
+ m_2_1
* g
+ m_2_2
* b
;
652 rgbf_to_xyYf (const Babl
*conversion
,float *src
,
656 const Babl
*space
= babl_conversion_get_source_space (conversion
);
657 float m_0_0
= space
->space
.RGBtoXYZf
[0] / D50_WHITE_REF_Xf
;
658 float m_0_1
= space
->space
.RGBtoXYZf
[1] / D50_WHITE_REF_Xf
;
659 float m_0_2
= space
->space
.RGBtoXYZf
[2] / D50_WHITE_REF_Xf
;
660 float m_1_0
= space
->space
.RGBtoXYZf
[3] / D50_WHITE_REF_Yf
;
661 float m_1_1
= space
->space
.RGBtoXYZf
[4] / D50_WHITE_REF_Yf
;
662 float m_1_2
= space
->space
.RGBtoXYZf
[5] / D50_WHITE_REF_Yf
;
663 float m_2_0
= space
->space
.RGBtoXYZf
[6] / D50_WHITE_REF_Zf
;
664 float m_2_1
= space
->space
.RGBtoXYZf
[7] / D50_WHITE_REF_Zf
;
665 float m_2_2
= space
->space
.RGBtoXYZf
[8] / D50_WHITE_REF_Zf
;
670 float x
, y
, X
, Y
, Z
, r
, g
, b
;
675 if (near_zerof(r
) && near_zerof(g
) && near_zerof(b
))
683 X
= m_0_0
* r
+ m_0_1
* g
+ m_0_2
* b
;
684 Y
= m_1_0
* r
+ m_1_1
* g
+ m_1_2
* b
;
685 Z
= m_2_0
* r
+ m_2_1
* g
+ m_2_2
* b
;
702 rgbaf_to_xyYf (const Babl
*conversion
,
707 const Babl
*space
= babl_conversion_get_source_space (conversion
);
708 float m_0_0
= space
->space
.RGBtoXYZf
[0] / D50_WHITE_REF_Xf
;
709 float m_0_1
= space
->space
.RGBtoXYZf
[1] / D50_WHITE_REF_Xf
;
710 float m_0_2
= space
->space
.RGBtoXYZf
[2] / D50_WHITE_REF_Xf
;
711 float m_1_0
= space
->space
.RGBtoXYZf
[3] / D50_WHITE_REF_Yf
;
712 float m_1_1
= space
->space
.RGBtoXYZf
[4] / D50_WHITE_REF_Yf
;
713 float m_1_2
= space
->space
.RGBtoXYZf
[5] / D50_WHITE_REF_Yf
;
714 float m_2_0
= space
->space
.RGBtoXYZf
[6] / D50_WHITE_REF_Zf
;
715 float m_2_1
= space
->space
.RGBtoXYZf
[7] / D50_WHITE_REF_Zf
;
716 float m_2_2
= space
->space
.RGBtoXYZf
[8] / D50_WHITE_REF_Zf
;
721 float x
, y
, X
, Y
, Z
, r
, g
, b
;
726 if (near_zerof(r
) && near_zerof(g
) && near_zerof(b
))
734 X
= m_0_0
* r
+ m_0_1
* g
+ m_0_2
* b
;
735 Y
= m_1_0
* r
+ m_1_1
* g
+ m_1_2
* b
;
736 Z
= m_2_0
* r
+ m_2_1
* g
+ m_2_2
* b
;
755 rgbaf_to_Yuvaf (const Babl
*conversion
,
760 const Babl
*space
= babl_conversion_get_source_space (conversion
);
761 float m_0_0
= space
->space
.RGBtoXYZf
[0] / D50_WHITE_REF_Xf
;
762 float m_0_1
= space
->space
.RGBtoXYZf
[1] / D50_WHITE_REF_Xf
;
763 float m_0_2
= space
->space
.RGBtoXYZf
[2] / D50_WHITE_REF_Xf
;
764 float m_1_0
= space
->space
.RGBtoXYZf
[3] / D50_WHITE_REF_Yf
;
765 float m_1_1
= space
->space
.RGBtoXYZf
[4] / D50_WHITE_REF_Yf
;
766 float m_1_2
= space
->space
.RGBtoXYZf
[5] / D50_WHITE_REF_Yf
;
767 float m_2_0
= space
->space
.RGBtoXYZf
[6] / D50_WHITE_REF_Zf
;
768 float m_2_1
= space
->space
.RGBtoXYZf
[7] / D50_WHITE_REF_Zf
;
769 float m_2_2
= space
->space
.RGBtoXYZf
[8] / D50_WHITE_REF_Zf
;
774 float u
, v
, X
, Y
, Z
, r
, g
, b
, a
, sum
;
780 if (near_zerof(r
) && near_zerof(g
) && near_zerof(b
))
788 X
= m_0_0
* r
+ m_0_1
* g
+ m_0_2
* b
;
789 Y
= m_1_0
* r
+ m_1_1
* g
+ m_1_2
* b
;
790 Z
= m_2_0
* r
+ m_2_1
* g
+ m_2_2
* b
;
792 sum
= (X
+ 15.0f
* Y
+ 3.0f
* Z
);
793 u
= (4.0f
* X
) / sum
;
794 v
= (9.0f
* Y
) / sum
;
808 rgbf_to_Yuvf (const Babl
*conversion
,float *src
,
812 const Babl
*space
= babl_conversion_get_source_space (conversion
);
813 float m_0_0
= space
->space
.RGBtoXYZf
[0] / D50_WHITE_REF_Xf
;
814 float m_0_1
= space
->space
.RGBtoXYZf
[1] / D50_WHITE_REF_Xf
;
815 float m_0_2
= space
->space
.RGBtoXYZf
[2] / D50_WHITE_REF_Xf
;
816 float m_1_0
= space
->space
.RGBtoXYZf
[3] / D50_WHITE_REF_Yf
;
817 float m_1_1
= space
->space
.RGBtoXYZf
[4] / D50_WHITE_REF_Yf
;
818 float m_1_2
= space
->space
.RGBtoXYZf
[5] / D50_WHITE_REF_Yf
;
819 float m_2_0
= space
->space
.RGBtoXYZf
[6] / D50_WHITE_REF_Zf
;
820 float m_2_1
= space
->space
.RGBtoXYZf
[7] / D50_WHITE_REF_Zf
;
821 float m_2_2
= space
->space
.RGBtoXYZf
[8] / D50_WHITE_REF_Zf
;
826 float u
, v
, X
, Y
, Z
, r
, g
, b
, sum
;
831 if (near_zerof(r
) && near_zerof(g
) && near_zerof(b
))
839 X
= m_0_0
* r
+ m_0_1
* g
+ m_0_2
* b
;
840 Y
= m_1_0
* r
+ m_1_1
* g
+ m_1_2
* b
;
841 Z
= m_2_0
* r
+ m_2_1
* g
+ m_2_2
* b
;
843 sum
= (X
+ 15.0f
* Y
+ 3.0f
* Z
);
844 u
= (4.0f
* X
) / sum
;
845 v
= (9.0f
* Y
) / sum
;
859 rgbaf_to_Yuvf (const Babl
*conversion
,
864 const Babl
*space
= babl_conversion_get_source_space (conversion
);
865 float m_0_0
= space
->space
.RGBtoXYZf
[0] / D50_WHITE_REF_Xf
;
866 float m_0_1
= space
->space
.RGBtoXYZf
[1] / D50_WHITE_REF_Xf
;
867 float m_0_2
= space
->space
.RGBtoXYZf
[2] / D50_WHITE_REF_Xf
;
868 float m_1_0
= space
->space
.RGBtoXYZf
[3] / D50_WHITE_REF_Yf
;
869 float m_1_1
= space
->space
.RGBtoXYZf
[4] / D50_WHITE_REF_Yf
;
870 float m_1_2
= space
->space
.RGBtoXYZf
[5] / D50_WHITE_REF_Yf
;
871 float m_2_0
= space
->space
.RGBtoXYZf
[6] / D50_WHITE_REF_Zf
;
872 float m_2_1
= space
->space
.RGBtoXYZf
[7] / D50_WHITE_REF_Zf
;
873 float m_2_2
= space
->space
.RGBtoXYZf
[8] / D50_WHITE_REF_Zf
;
878 float u
, v
, X
, Y
, Z
, r
, g
, b
, sum
;
883 if (near_zerof(r
) && near_zerof(g
) && near_zerof(b
))
891 X
= m_0_0
* r
+ m_0_1
* g
+ m_0_2
* b
;
892 Y
= m_1_0
* r
+ m_1_1
* g
+ m_1_2
* b
;
893 Z
= m_2_0
* r
+ m_2_1
* g
+ m_2_2
* b
;
895 sum
= (X
+ 15.0f
* Y
+ 3.0f
* Z
);
896 u
= (4.0f
* X
) / sum
;
897 v
= (9.0f
* Y
) / sum
;
915 xyY_to_rgba (const Babl
*conversion
,
920 const Babl
*space
= babl_conversion_get_destination_space (conversion
);
923 double x
= ((double *) src
)[0];
924 double y
= ((double *) src
)[1];
925 double Y
= ((double *) src
)[2];
927 double R
, G
, B
, X
, Z
;
930 xyY_to_XYZ (x
, y
, Y
, &X
, &Y
, &Z
);
934 double XYZ
[3] = {X
,Y
,Z
};
936 babl_space_from_xyz (space
, XYZ
, RGB
);
942 ((double *) dst
)[0] = R
;
943 ((double *) dst
)[1] = G
;
944 ((double *) dst
)[2] = B
;
945 ((double *) dst
)[3] = 1.0;
947 src
+= sizeof (double) * 3;
948 dst
+= sizeof (double) * 4;
954 xyYa_to_rgba (const Babl
*conversion
,char *src
,
958 const Babl
*space
= babl_conversion_get_destination_space (conversion
);
961 double x
= ((double *) src
)[0];
962 double y
= ((double *) src
)[1];
963 double Y
= ((double *) src
)[2];
964 double alpha
= ((double *) src
)[3];
969 xyY_to_XYZ (x
, y
, Y
, &X
, &Y
, &Z
);
973 double XYZ
[3] = {X
,Y
,Z
};
974 babl_space_from_xyz (space
, XYZ
, (double*)dst
);
976 ((double *) dst
)[3] = alpha
;
978 src
+= sizeof (double) * 4;
979 dst
+= sizeof (double) * 4;
988 Yuv_to_rgba (const Babl
*conversion
,char *src
,
992 const Babl
*space
= babl_conversion_get_destination_space (conversion
);
995 double Y
= ((double *) src
)[0];
996 double u
= ((double *) src
)[1];
997 double v
= ((double *) src
)[2];
999 double R
, G
, B
, X
, Z
;
1001 //convert Yuv to XYZ
1002 Yuv_to_XYZ (Y
, u
, v
, &X
, &Y
, &Z
);
1004 //convert XYZ to RGB
1006 double XYZ
[3] = {X
,Y
,Z
};
1008 babl_space_from_xyz (space
, XYZ
, RGB
);
1014 ((double *) dst
)[0] = R
;
1015 ((double *) dst
)[1] = G
;
1016 ((double *) dst
)[2] = B
;
1017 ((double *) dst
)[3] = 1.0;
1019 src
+= sizeof (double) * 3;
1020 dst
+= sizeof (double) * 4;
1026 Yuva_to_rgba (const Babl
*conversion
,char *src
,
1030 const Babl
*space
= babl_conversion_get_destination_space (conversion
);
1033 double Y
= ((double *) src
)[0];
1034 double u
= ((double *) src
)[1];
1035 double v
= ((double *) src
)[2];
1036 double alpha
= ((double *) src
)[3];
1040 //convert Yuv to XYZ
1041 Yuv_to_XYZ (Y
, u
, v
, &X
, &Y
, &Z
);
1044 //convert XYZ to RGB
1045 double XYZ
[3] = {X
,Y
,Z
};
1046 babl_space_from_xyz (space
, XYZ
, (double*)dst
);
1048 ((double *) dst
)[3] = alpha
;
1050 src
+= sizeof (double) * 4;
1051 dst
+= sizeof (double) * 4;
1059 xyYf_to_rgbf (const Babl
*conversion
,float *src
,
1063 const Babl
*space
= babl_conversion_get_source_space (conversion
);
1064 float m_0_0
= space
->space
.XYZtoRGBf
[0] * D50_WHITE_REF_Xf
;
1065 float m_0_1
= space
->space
.XYZtoRGBf
[1] * D50_WHITE_REF_Yf
;
1066 float m_0_2
= space
->space
.XYZtoRGBf
[2] * D50_WHITE_REF_Zf
;
1067 float m_1_0
= space
->space
.XYZtoRGBf
[3] * D50_WHITE_REF_Xf
;
1068 float m_1_1
= space
->space
.XYZtoRGBf
[4] * D50_WHITE_REF_Yf
;
1069 float m_1_2
= space
->space
.XYZtoRGBf
[5] * D50_WHITE_REF_Zf
;
1070 float m_2_0
= space
->space
.XYZtoRGBf
[6] * D50_WHITE_REF_Xf
;
1071 float m_2_1
= space
->space
.XYZtoRGBf
[7] * D50_WHITE_REF_Yf
;
1072 float m_2_2
= space
->space
.XYZtoRGBf
[8] * D50_WHITE_REF_Zf
;
1077 float X
, Z
, r
, g
, b
;
1092 Z
= ((1 - x
- y
) * Y
) / y
;
1095 r
= m_0_0
* X
+ m_0_1
* Y
+ m_0_2
* Z
;
1096 g
= m_1_0
* X
+ m_1_1
* Y
+ m_1_2
* Z
;
1097 b
= m_2_0
* X
+ m_2_1
* Y
+ m_2_2
* Z
;
1111 xyYf_to_rgbaf (const Babl
*conversion
,
1116 const Babl
*space
= babl_conversion_get_source_space (conversion
);
1117 float m_0_0
= space
->space
.XYZtoRGBf
[0] * D50_WHITE_REF_Xf
;
1118 float m_0_1
= space
->space
.XYZtoRGBf
[1] * D50_WHITE_REF_Yf
;
1119 float m_0_2
= space
->space
.XYZtoRGBf
[2] * D50_WHITE_REF_Zf
;
1120 float m_1_0
= space
->space
.XYZtoRGBf
[3] * D50_WHITE_REF_Xf
;
1121 float m_1_1
= space
->space
.XYZtoRGBf
[4] * D50_WHITE_REF_Yf
;
1122 float m_1_2
= space
->space
.XYZtoRGBf
[5] * D50_WHITE_REF_Zf
;
1123 float m_2_0
= space
->space
.XYZtoRGBf
[6] * D50_WHITE_REF_Xf
;
1124 float m_2_1
= space
->space
.XYZtoRGBf
[7] * D50_WHITE_REF_Yf
;
1125 float m_2_2
= space
->space
.XYZtoRGBf
[8] * D50_WHITE_REF_Zf
;
1130 float X
, Z
, r
, g
, b
;
1146 Z
= ((1 - x
- y
) * Y
) / y
;
1149 r
= m_0_0
* X
+ m_0_1
* Y
+ m_0_2
* Z
;
1150 g
= m_1_0
* X
+ m_1_1
* Y
+ m_1_2
* Z
;
1151 b
= m_2_0
* X
+ m_2_1
* Y
+ m_2_2
* Z
;
1164 xyYaf_to_rgbaf (const Babl
*conversion
,
1169 const Babl
*space
= babl_conversion_get_source_space (conversion
);
1170 float m_0_0
= space
->space
.XYZtoRGBf
[0] * D50_WHITE_REF_Xf
;
1171 float m_0_1
= space
->space
.XYZtoRGBf
[1] * D50_WHITE_REF_Yf
;
1172 float m_0_2
= space
->space
.XYZtoRGBf
[2] * D50_WHITE_REF_Zf
;
1173 float m_1_0
= space
->space
.XYZtoRGBf
[3] * D50_WHITE_REF_Xf
;
1174 float m_1_1
= space
->space
.XYZtoRGBf
[4] * D50_WHITE_REF_Yf
;
1175 float m_1_2
= space
->space
.XYZtoRGBf
[5] * D50_WHITE_REF_Zf
;
1176 float m_2_0
= space
->space
.XYZtoRGBf
[6] * D50_WHITE_REF_Xf
;
1177 float m_2_1
= space
->space
.XYZtoRGBf
[7] * D50_WHITE_REF_Yf
;
1178 float m_2_2
= space
->space
.XYZtoRGBf
[8] * D50_WHITE_REF_Zf
;
1183 float X
, Z
, r
, g
, b
;
1199 Z
= ((1 - x
- y
) * Y
) / y
;
1202 r
= m_0_0
* X
+ m_0_1
* Y
+ m_0_2
* Z
;
1203 g
= m_1_0
* X
+ m_1_1
* Y
+ m_1_2
* Z
;
1204 b
= m_2_0
* X
+ m_2_1
* Y
+ m_2_2
* Z
;
1221 Yuvf_to_rgbf (const Babl
*conversion
,float *src
,
1225 const Babl
*space
= babl_conversion_get_source_space (conversion
);
1226 float m_0_0
= space
->space
.XYZtoRGBf
[0] * D50_WHITE_REF_Xf
;
1227 float m_0_1
= space
->space
.XYZtoRGBf
[1] * D50_WHITE_REF_Yf
;
1228 float m_0_2
= space
->space
.XYZtoRGBf
[2] * D50_WHITE_REF_Zf
;
1229 float m_1_0
= space
->space
.XYZtoRGBf
[3] * D50_WHITE_REF_Xf
;
1230 float m_1_1
= space
->space
.XYZtoRGBf
[4] * D50_WHITE_REF_Yf
;
1231 float m_1_2
= space
->space
.XYZtoRGBf
[5] * D50_WHITE_REF_Zf
;
1232 float m_2_0
= space
->space
.XYZtoRGBf
[6] * D50_WHITE_REF_Xf
;
1233 float m_2_1
= space
->space
.XYZtoRGBf
[7] * D50_WHITE_REF_Yf
;
1234 float m_2_2
= space
->space
.XYZtoRGBf
[8] * D50_WHITE_REF_Zf
;
1239 float X
, Z
, r
, g
, b
;
1252 X
= ((9.0f
* u
* Y
)/(4.0f
* v
));
1254 Z
= -(((20.0f
* v
+ 3.0f
* u
- 12.0f
) * Y
)/(4.0f
* v
));
1257 r
= m_0_0
* X
+ m_0_1
* Y
+ m_0_2
* Z
;
1258 g
= m_1_0
* X
+ m_1_1
* Y
+ m_1_2
* Z
;
1259 b
= m_2_0
* X
+ m_2_1
* Y
+ m_2_2
* Z
;
1273 Yuvf_to_rgbaf (const Babl
*conversion
,
1278 const Babl
*space
= babl_conversion_get_source_space (conversion
);
1279 float m_0_0
= space
->space
.XYZtoRGBf
[0] * D50_WHITE_REF_Xf
;
1280 float m_0_1
= space
->space
.XYZtoRGBf
[1] * D50_WHITE_REF_Yf
;
1281 float m_0_2
= space
->space
.XYZtoRGBf
[2] * D50_WHITE_REF_Zf
;
1282 float m_1_0
= space
->space
.XYZtoRGBf
[3] * D50_WHITE_REF_Xf
;
1283 float m_1_1
= space
->space
.XYZtoRGBf
[4] * D50_WHITE_REF_Yf
;
1284 float m_1_2
= space
->space
.XYZtoRGBf
[5] * D50_WHITE_REF_Zf
;
1285 float m_2_0
= space
->space
.XYZtoRGBf
[6] * D50_WHITE_REF_Xf
;
1286 float m_2_1
= space
->space
.XYZtoRGBf
[7] * D50_WHITE_REF_Yf
;
1287 float m_2_2
= space
->space
.XYZtoRGBf
[8] * D50_WHITE_REF_Zf
;
1292 float X
, Z
, r
, g
, b
;
1305 X
= ((9.0f
* u
* Y
)/(4.0f
* v
));
1307 Z
= -(((20.0f
* v
+ 3.0f
* u
- 12.0f
) * Y
)/(4.0f
* v
));
1310 r
= m_0_0
* X
+ m_0_1
* Y
+ m_0_2
* Z
;
1311 g
= m_1_0
* X
+ m_1_1
* Y
+ m_1_2
* Z
;
1312 b
= m_2_0
* X
+ m_2_1
* Y
+ m_2_2
* Z
;
1325 Yuvaf_to_rgbaf (const Babl
*conversion
,
1330 const Babl
*space
= babl_conversion_get_source_space (conversion
);
1331 float m_0_0
= space
->space
.XYZtoRGBf
[0] * D50_WHITE_REF_Xf
;
1332 float m_0_1
= space
->space
.XYZtoRGBf
[1] * D50_WHITE_REF_Yf
;
1333 float m_0_2
= space
->space
.XYZtoRGBf
[2] * D50_WHITE_REF_Zf
;
1334 float m_1_0
= space
->space
.XYZtoRGBf
[3] * D50_WHITE_REF_Xf
;
1335 float m_1_1
= space
->space
.XYZtoRGBf
[4] * D50_WHITE_REF_Yf
;
1336 float m_1_2
= space
->space
.XYZtoRGBf
[5] * D50_WHITE_REF_Zf
;
1337 float m_2_0
= space
->space
.XYZtoRGBf
[6] * D50_WHITE_REF_Xf
;
1338 float m_2_1
= space
->space
.XYZtoRGBf
[7] * D50_WHITE_REF_Yf
;
1339 float m_2_2
= space
->space
.XYZtoRGBf
[8] * D50_WHITE_REF_Zf
;
1344 float X
, Z
, r
, g
, b
;
1358 X
= ((9.0f
* u
* Y
)/(4.0f
* v
));
1360 Z
= -(((20.0f
* v
+ 3.0f
* u
- 12.0f
) * Y
)/(4.0f
* v
));
1363 r
= m_0_0
* X
+ m_0_1
* Y
+ m_0_2
* Z
;
1364 g
= m_1_0
* X
+ m_1_1
* Y
+ m_1_2
* Z
;
1365 b
= m_2_0
* X
+ m_2_1
* Y
+ m_2_2
* Z
;
1381 rgba_to_lab (const Babl
*conversion
,
1386 const Babl
*space
= babl_conversion_get_source_space (conversion
);
1389 double XYZ
[3], L
, a
, b
;
1391 babl_space_to_xyz (space
, (double*)src
, XYZ
);
1392 XYZ_to_LAB (XYZ
[0], XYZ
[1], XYZ
[2], &L
, &a
, &b
);
1394 ((double *) dst
)[0] = L
;
1395 ((double *) dst
)[1] = a
;
1396 ((double *) dst
)[2] = b
;
1398 src
+= sizeof (double) * 4;
1399 dst
+= sizeof (double) * 3;
1405 lab_to_rgba (const Babl
*conversion
,
1410 const Babl
*space
= babl_conversion_get_destination_space (conversion
);
1413 double L
= ((double *) src
)[0];
1414 double a
= ((double *) src
)[1];
1415 double b
= ((double *) src
)[2];
1417 double X
, Y
, Z
, R
, G
, B
;
1419 //convert Lab to XYZ
1420 LAB_to_XYZ (L
, a
, b
, &X
, &Y
, &Z
);
1422 //convert XYZ to RGB
1424 double XYZ
[3] = {X
,Y
,Z
};
1426 babl_space_from_xyz (space
, XYZ
, RGB
);
1432 ((double *) dst
)[0] = R
;
1433 ((double *) dst
)[1] = G
;
1434 ((double *) dst
)[2] = B
;
1435 ((double *) dst
)[3] = 1.0;
1437 src
+= sizeof (double) * 3;
1438 dst
+= sizeof (double) * 4;
1443 rgba_to_laba (const Babl
*conversion
,
1448 const Babl
*space
= babl_conversion_get_source_space (conversion
);
1451 double alpha
= ((double *) src
)[3];
1452 double XYZ
[3], L
, a
, b
;
1454 //convert RGB to XYZ
1455 babl_space_to_xyz (space
, (double*)src
, XYZ
);
1457 //convert XYZ to Lab
1458 XYZ_to_LAB (XYZ
[0], XYZ
[1], XYZ
[2], &L
, &a
, &b
);
1460 ((double *) dst
)[0] = L
;
1461 ((double *) dst
)[1] = a
;
1462 ((double *) dst
)[2] = b
;
1463 ((double *) dst
)[3] = alpha
;
1465 src
+= sizeof (double) * 4;
1466 dst
+= sizeof (double) * 4;
1471 laba_to_rgba (const Babl
*conversion
,
1476 const Babl
*space
= babl_conversion_get_destination_space (conversion
);
1479 double L
= ((double *) src
)[0];
1480 double a
= ((double *) src
)[1];
1481 double b
= ((double *) src
)[2];
1482 double alpha
= ((double *) src
)[3];
1486 //convert Lab to XYZ
1487 LAB_to_XYZ (L
, a
, b
, &X
, &Y
, &Z
);
1490 //convert XYZ to RGB
1491 double XYZ
[3] = {X
,Y
,Z
};
1492 babl_space_from_xyz (space
, XYZ
, (double*)dst
);
1494 ((double *) dst
)[3] = alpha
;
1496 src
+= sizeof (double) * 4;
1497 dst
+= sizeof (double) * 4;
1505 CHab_to_ab (double C
,
1510 *to_a
= cos (H
* RADIANS_PER_DEGREE
) * C
;
1511 *to_b
= sin (H
* RADIANS_PER_DEGREE
) * C
;
1515 ab_to_CHab (double a
,
1520 *to_C
= sqrt ( (a
* a
) + (b
* b
) );
1521 *to_H
= atan2 (b
, a
) * DEGREES_PER_RADIAN
;
1523 // Keep H within the range 0-360
1529 rgba_to_lchab (const Babl
*conversion
,
1534 const Babl
*space
= babl_conversion_get_source_space (conversion
);
1538 double XYZ
[3], L
, a
, b
, C
, H
;
1540 //convert RGB to XYZ
1541 babl_space_to_xyz (space
, (double *)src
, XYZ
);
1543 //convert XYZ to Lab
1544 XYZ_to_LAB (XYZ
[0], XYZ
[1], XYZ
[2], &L
, &a
, &b
);
1547 //convert Lab to LCH(ab)
1548 ab_to_CHab (a
, b
, &C
, &H
);
1550 ((double *) dst
)[0] = L
;
1551 ((double *) dst
)[1] = C
;
1552 ((double *) dst
)[2] = H
;
1554 src
+= sizeof (double) * 4;
1555 dst
+= sizeof (double) * 3;
1560 lchab_to_rgba (const Babl
*conversion
,
1565 const Babl
*space
= babl_conversion_get_source_space (conversion
);
1569 double L
= ((double *) src
)[0];
1570 double C
= ((double *) src
)[1];
1571 double H
= ((double *) src
)[2];
1572 double a
, b
, X
, Y
, Z
;
1574 //Convert LCH(ab) to Lab
1575 CHab_to_ab (C
, H
, &a
, &b
);
1577 //Convert LAB to XYZ
1578 LAB_to_XYZ (L
, a
, b
, &X
, &Y
, &Z
);
1580 //Convert XYZ to RGB
1582 double XYZ
[3] = {X
,Y
,Z
};
1583 babl_space_from_xyz (space
, XYZ
, (double*)dst
);
1586 ((double *) dst
)[3] = 1.0;
1588 src
+= sizeof (double) * 3;
1589 dst
+= sizeof (double) * 4;
1594 rgba_to_lchaba (const Babl
*conversion
,
1599 const Babl
*space
= babl_conversion_get_source_space (conversion
);
1603 double alpha
= ((double *) src
)[3];
1604 double XYZ
[3], L
, a
, b
, C
, H
;
1606 //convert RGB to XYZ
1607 babl_space_to_xyz (space
, (double*)src
, XYZ
);
1609 //convert XYZ to Lab
1610 XYZ_to_LAB (XYZ
[0], XYZ
[1], XYZ
[2], &L
, &a
, &b
);
1612 //convert Lab to LCH(ab)
1613 ab_to_CHab (a
, b
, &C
, &H
);
1615 ((double *) dst
)[0] = L
;
1616 ((double *) dst
)[1] = C
;
1617 ((double *) dst
)[2] = H
;
1618 ((double *) dst
)[3] = alpha
;
1620 src
+= sizeof (double) * 4;
1621 dst
+= sizeof (double) * 4;
1626 lchaba_to_rgba (const Babl
*conversion
,
1631 const Babl
*space
= babl_conversion_get_destination_space (conversion
);
1634 double L
= ((double *) src
)[0];
1635 double C
= ((double *) src
)[1];
1636 double H
= ((double *) src
)[2];
1637 double alpha
= ((double *) src
)[3];
1638 double a
, b
, X
, Y
, Z
;
1640 //Convert LCH(ab) to Lab
1641 CHab_to_ab (C
, H
, &a
, &b
);
1643 //Convert Lab to XYZ
1644 LAB_to_XYZ (L
, a
, b
, &X
, &Y
, &Z
);
1646 //Convert XYZ to RGB
1648 double XYZ
[3] = {X
,Y
,Z
};
1649 babl_space_from_xyz (space
, XYZ
, (double*)dst
);
1651 ((double *) dst
)[3] = alpha
;
1653 src
+= sizeof (double) * 4;
1654 dst
+= sizeof (double) * 4;
1659 /******** end double RGB/CIE color space conversions ******************/
1661 /******** begin floating point RGB/CIE color space conversions ********/
1663 /* origin: http://www.hackersdelight.org/hdcodetxt/acbrt.c.txt
1664 * permissions: http://www.hackersdelight.org/permissions.htm
1667 * Return cube root of x
1673 union { float f
; uint32_t i
; } u
= { x
};
1675 u
.i
= u
.i
/ 4 + u
.i
/ 16;
1676 u
.i
= u
.i
+ u
.i
/ 16;
1677 u
.i
= u
.i
+ u
.i
/ 256;
1678 u
.i
= 0x2a5137a0 + u
.i
;
1679 u
.f
= 0.33333333f
* (2.0f
* u
.f
+ x
/ (u
.f
* u
.f
));
1680 u
.f
= 0.33333333f
* (2.0f
* u
.f
+ x
/ (u
.f
* u
.f
));
1692 Yf_to_Lf (const Babl
*conversion
,
1702 float L
= yr
> LAB_EPSILONf
? 116.0f
* _cbrtf (yr
) - 16 : LAB_KAPPAf
* yr
;
1712 Yaf_to_Lf (const Babl
*conversion
,
1722 float L
= yr
> LAB_EPSILONf
? 116.0f
* _cbrtf (yr
) - 16 : LAB_KAPPAf
* yr
;
1732 Yaf_to_Laf (const Babl
*conversion
,
1743 float L
= yr
> LAB_EPSILONf
? 116.0f
* _cbrtf (yr
) - 16 : LAB_KAPPAf
* yr
;
1754 rgbf_to_Labf (const Babl
*conversion
,
1759 const Babl
*space
= babl_conversion_get_source_space (conversion
);
1760 float m_0_0
= space
->space
.RGBtoXYZf
[0] / D50_WHITE_REF_Xf
;
1761 float m_0_1
= space
->space
.RGBtoXYZf
[1] / D50_WHITE_REF_Xf
;
1762 float m_0_2
= space
->space
.RGBtoXYZf
[2] / D50_WHITE_REF_Xf
;
1763 float m_1_0
= space
->space
.RGBtoXYZf
[3] / D50_WHITE_REF_Yf
;
1764 float m_1_1
= space
->space
.RGBtoXYZf
[4] / D50_WHITE_REF_Yf
;
1765 float m_1_2
= space
->space
.RGBtoXYZf
[5] / D50_WHITE_REF_Yf
;
1766 float m_2_0
= space
->space
.RGBtoXYZf
[6] / D50_WHITE_REF_Zf
;
1767 float m_2_1
= space
->space
.RGBtoXYZf
[7] / D50_WHITE_REF_Zf
;
1768 float m_2_2
= space
->space
.RGBtoXYZf
[8] / D50_WHITE_REF_Zf
;
1777 float xr
= m_0_0
* r
+ m_0_1
* g
+ m_0_2
* b
;
1778 float yr
= m_1_0
* r
+ m_1_1
* g
+ m_1_2
* b
;
1779 float zr
= m_2_0
* r
+ m_2_1
* g
+ m_2_2
* b
;
1781 float fx
= xr
> LAB_EPSILONf
? _cbrtf (xr
) : (LAB_KAPPAf
* xr
+ 16.0f
) / 116.0f
;
1782 float fy
= yr
> LAB_EPSILONf
? _cbrtf (yr
) : (LAB_KAPPAf
* yr
+ 16.0f
) / 116.0f
;
1783 float fz
= zr
> LAB_EPSILONf
? _cbrtf (zr
) : (LAB_KAPPAf
* zr
+ 16.0f
) / 116.0f
;
1785 float L
= 116.0f
* fy
- 16.0f
;
1786 float A
= 500.0f
* (fx
- fy
);
1787 float B
= 200.0f
* (fy
- fz
);
1799 rgbaf_to_Lf (const Babl
*conversion
,
1804 const Babl
*space
= babl_conversion_get_source_space (conversion
);
1805 float m_1_0
= space
->space
.RGBtoXYZf
[3] / D50_WHITE_REF_Yf
;
1806 float m_1_1
= space
->space
.RGBtoXYZf
[4] / D50_WHITE_REF_Yf
;
1807 float m_1_2
= space
->space
.RGBtoXYZf
[5] / D50_WHITE_REF_Yf
;
1816 float yr
= m_1_0
* r
+ m_1_1
* g
+ m_1_2
* b
;
1817 float L
= yr
> LAB_EPSILONf
? 116.0f
* _cbrtf (yr
) - 16 : LAB_KAPPAf
* yr
;
1827 rgbaf_to_Labf (const Babl
*conversion
,
1832 const Babl
*space
= babl_conversion_get_source_space (conversion
);
1833 float m_0_0
= space
->space
.RGBtoXYZf
[0] / D50_WHITE_REF_Xf
;
1834 float m_0_1
= space
->space
.RGBtoXYZf
[1] / D50_WHITE_REF_Xf
;
1835 float m_0_2
= space
->space
.RGBtoXYZf
[2] / D50_WHITE_REF_Xf
;
1836 float m_1_0
= space
->space
.RGBtoXYZf
[3] / D50_WHITE_REF_Yf
;
1837 float m_1_1
= space
->space
.RGBtoXYZf
[4] / D50_WHITE_REF_Yf
;
1838 float m_1_2
= space
->space
.RGBtoXYZf
[5] / D50_WHITE_REF_Yf
;
1839 float m_2_0
= space
->space
.RGBtoXYZf
[6] / D50_WHITE_REF_Zf
;
1840 float m_2_1
= space
->space
.RGBtoXYZf
[7] / D50_WHITE_REF_Zf
;
1841 float m_2_2
= space
->space
.RGBtoXYZf
[8] / D50_WHITE_REF_Zf
;
1850 float xr
= m_0_0
* r
+ m_0_1
* g
+ m_0_2
* b
;
1851 float yr
= m_1_0
* r
+ m_1_1
* g
+ m_1_2
* b
;
1852 float zr
= m_2_0
* r
+ m_2_1
* g
+ m_2_2
* b
;
1854 float fx
= xr
> LAB_EPSILONf
? _cbrtf (xr
) : (LAB_KAPPAf
* xr
+ 16.0f
) / 116.0f
;
1855 float fy
= yr
> LAB_EPSILONf
? _cbrtf (yr
) : (LAB_KAPPAf
* yr
+ 16.0f
) / 116.0f
;
1856 float fz
= zr
> LAB_EPSILONf
? _cbrtf (zr
) : (LAB_KAPPAf
* zr
+ 16.0f
) / 116.0f
;
1858 float L
= 116.0f
* fy
- 16.0f
;
1859 float A
= 500.0f
* (fx
- fy
);
1860 float B
= 200.0f
* (fy
- fz
);
1872 rgbaf_to_Labaf (const Babl
*conversion
,
1877 const Babl
*space
= babl_conversion_get_source_space (conversion
);
1878 float m_0_0
= space
->space
.RGBtoXYZf
[0] / D50_WHITE_REF_Xf
;
1879 float m_0_1
= space
->space
.RGBtoXYZf
[1] / D50_WHITE_REF_Xf
;
1880 float m_0_2
= space
->space
.RGBtoXYZf
[2] / D50_WHITE_REF_Xf
;
1881 float m_1_0
= space
->space
.RGBtoXYZf
[3] / D50_WHITE_REF_Yf
;
1882 float m_1_1
= space
->space
.RGBtoXYZf
[4] / D50_WHITE_REF_Yf
;
1883 float m_1_2
= space
->space
.RGBtoXYZf
[5] / D50_WHITE_REF_Yf
;
1884 float m_2_0
= space
->space
.RGBtoXYZf
[6] / D50_WHITE_REF_Zf
;
1885 float m_2_1
= space
->space
.RGBtoXYZf
[7] / D50_WHITE_REF_Zf
;
1886 float m_2_2
= space
->space
.RGBtoXYZf
[8] / D50_WHITE_REF_Zf
;
1896 float xr
= m_0_0
* r
+ m_0_1
* g
+ m_0_2
* b
;
1897 float yr
= m_1_0
* r
+ m_1_1
* g
+ m_1_2
* b
;
1898 float zr
= m_2_0
* r
+ m_2_1
* g
+ m_2_2
* b
;
1900 float fx
= xr
> LAB_EPSILONf
? _cbrtf (xr
) : (LAB_KAPPAf
* xr
+ 16.0f
) / 116.0f
;
1901 float fy
= yr
> LAB_EPSILONf
? _cbrtf (yr
) : (LAB_KAPPAf
* yr
+ 16.0f
) / 116.0f
;
1902 float fz
= zr
> LAB_EPSILONf
? _cbrtf (zr
) : (LAB_KAPPAf
* zr
+ 16.0f
) / 116.0f
;
1904 float L
= 116.0f
* fy
- 16.0f
;
1905 float A
= 500.0f
* (fx
- fy
);
1906 float B
= 200.0f
* (fy
- fz
);
1919 Labf_to_Lf (const Babl
*conversion
,
1936 Labaf_to_Lf (const Babl
*conversion
,
1953 Labf_to_rgbf (const Babl
*conversion
,
1958 const Babl
*space
= babl_conversion_get_source_space (conversion
);
1959 float m_0_0
= space
->space
.XYZtoRGBf
[0] * D50_WHITE_REF_Xf
;
1960 float m_0_1
= space
->space
.XYZtoRGBf
[1] * D50_WHITE_REF_Yf
;
1961 float m_0_2
= space
->space
.XYZtoRGBf
[2] * D50_WHITE_REF_Zf
;
1962 float m_1_0
= space
->space
.XYZtoRGBf
[3] * D50_WHITE_REF_Xf
;
1963 float m_1_1
= space
->space
.XYZtoRGBf
[4] * D50_WHITE_REF_Yf
;
1964 float m_1_2
= space
->space
.XYZtoRGBf
[5] * D50_WHITE_REF_Zf
;
1965 float m_2_0
= space
->space
.XYZtoRGBf
[6] * D50_WHITE_REF_Xf
;
1966 float m_2_1
= space
->space
.XYZtoRGBf
[7] * D50_WHITE_REF_Yf
;
1967 float m_2_2
= space
->space
.XYZtoRGBf
[8] * D50_WHITE_REF_Zf
;
1976 float fy
= (L
+ 16.0f
) / 116.0f
;
1977 float fx
= fy
+ A
/ 500.0f
;
1978 float fz
= fy
- B
/ 200.0f
;
1980 float yr
= L
> LAB_KAPPAf
* LAB_EPSILONf
? cubef (fy
) : L
/ LAB_KAPPAf
;
1981 float xr
= cubef (fx
) > LAB_EPSILONf
? cubef (fx
) : (fx
* 116.0f
- 16.0f
) / LAB_KAPPAf
;
1982 float zr
= cubef (fz
) > LAB_EPSILONf
? cubef (fz
) : (fz
* 116.0f
- 16.0f
) / LAB_KAPPAf
;
1984 float r
= m_0_0
* xr
+ m_0_1
* yr
+ m_0_2
* zr
;
1985 float g
= m_1_0
* xr
+ m_1_1
* yr
+ m_1_2
* zr
;
1986 float b
= m_2_0
* xr
+ m_2_1
* yr
+ m_2_2
* zr
;
1999 Labf_to_rgbaf (const Babl
*conversion
,float *src
,
2003 const Babl
*space
= babl_conversion_get_source_space (conversion
);
2004 float m_0_0
= space
->space
.XYZtoRGBf
[0] * D50_WHITE_REF_Xf
;
2005 float m_0_1
= space
->space
.XYZtoRGBf
[1] * D50_WHITE_REF_Yf
;
2006 float m_0_2
= space
->space
.XYZtoRGBf
[2] * D50_WHITE_REF_Zf
;
2007 float m_1_0
= space
->space
.XYZtoRGBf
[3] * D50_WHITE_REF_Xf
;
2008 float m_1_1
= space
->space
.XYZtoRGBf
[4] * D50_WHITE_REF_Yf
;
2009 float m_1_2
= space
->space
.XYZtoRGBf
[5] * D50_WHITE_REF_Zf
;
2010 float m_2_0
= space
->space
.XYZtoRGBf
[6] * D50_WHITE_REF_Xf
;
2011 float m_2_1
= space
->space
.XYZtoRGBf
[7] * D50_WHITE_REF_Yf
;
2012 float m_2_2
= space
->space
.XYZtoRGBf
[8] * D50_WHITE_REF_Zf
;
2021 float fy
= (L
+ 16.0f
) / 116.0f
;
2022 float fx
= fy
+ A
/ 500.0f
;
2023 float fz
= fy
- B
/ 200.0f
;
2025 float yr
= L
> LAB_KAPPAf
* LAB_EPSILONf
? cubef (fy
) : L
/ LAB_KAPPAf
;
2026 float xr
= cubef (fx
) > LAB_EPSILONf
? cubef (fx
) : (fx
* 116.0f
- 16.0f
) / LAB_KAPPAf
;
2027 float zr
= cubef (fz
) > LAB_EPSILONf
? cubef (fz
) : (fz
* 116.0f
- 16.0f
) / LAB_KAPPAf
;
2029 float r
= m_0_0
* xr
+ m_0_1
* yr
+ m_0_2
* zr
;
2030 float g
= m_1_0
* xr
+ m_1_1
* yr
+ m_1_2
* zr
;
2031 float b
= m_2_0
* xr
+ m_2_1
* yr
+ m_2_2
* zr
;
2044 Labaf_to_rgbaf (const Babl
*conversion
,
2049 const Babl
*space
= babl_conversion_get_source_space (conversion
);
2050 float m_0_0
= space
->space
.XYZtoRGBf
[0] * D50_WHITE_REF_Xf
;
2051 float m_0_1
= space
->space
.XYZtoRGBf
[1] * D50_WHITE_REF_Yf
;
2052 float m_0_2
= space
->space
.XYZtoRGBf
[2] * D50_WHITE_REF_Zf
;
2053 float m_1_0
= space
->space
.XYZtoRGBf
[3] * D50_WHITE_REF_Xf
;
2054 float m_1_1
= space
->space
.XYZtoRGBf
[4] * D50_WHITE_REF_Yf
;
2055 float m_1_2
= space
->space
.XYZtoRGBf
[5] * D50_WHITE_REF_Zf
;
2056 float m_2_0
= space
->space
.XYZtoRGBf
[6] * D50_WHITE_REF_Xf
;
2057 float m_2_1
= space
->space
.XYZtoRGBf
[7] * D50_WHITE_REF_Yf
;
2058 float m_2_2
= space
->space
.XYZtoRGBf
[8] * D50_WHITE_REF_Zf
;
2068 float fy
= (L
+ 16.0f
) / 116.0f
;
2069 float fx
= fy
+ A
/ 500.0f
;
2070 float fz
= fy
- B
/ 200.0f
;
2072 float yr
= L
> LAB_KAPPAf
* LAB_EPSILONf
? cubef (fy
) : L
/ LAB_KAPPAf
;
2073 float xr
= cubef (fx
) > LAB_EPSILONf
? cubef (fx
) : (fx
* 116.0f
- 16.0f
) / LAB_KAPPAf
;
2074 float zr
= cubef (fz
) > LAB_EPSILONf
? cubef (fz
) : (fz
* 116.0f
- 16.0f
) / LAB_KAPPAf
;
2076 float r
= m_0_0
* xr
+ m_0_1
* yr
+ m_0_2
* zr
;
2077 float g
= m_1_0
* xr
+ m_1_1
* yr
+ m_1_2
* zr
;
2078 float b
= m_2_0
* xr
+ m_2_1
* yr
+ m_2_2
* zr
;
2091 Labf_to_Lchabf (const Babl
*conversion
,
2104 float C
= sqrtf (A
* A
+ B
* B
);
2105 float H
= atan2f (B
, A
) * DEGREES_PER_RADIANf
;
2107 // Keep H within the range 0-360
2121 Lchabf_to_Labf (const Babl
*conversion
,
2134 float A
= C
* cosf (H
* RADIANS_PER_DEGREEf
);
2135 float B
= C
* sinf (H
* RADIANS_PER_DEGREEf
);
2147 Labaf_to_Lchabaf (const Babl
*conversion
,
2161 float C
= sqrtf (A
* A
+ B
* B
);
2162 float H
= atan2f (B
, A
) * DEGREES_PER_RADIANf
;
2164 // Keep H within the range 0-360
2179 Lchabaf_to_Labaf (const Babl
*conversion
,
2193 float A
= C
* cosf (H
* RADIANS_PER_DEGREEf
);
2194 float B
= C
* sinf (H
* RADIANS_PER_DEGREEf
);
2206 #if defined(USE_SSE2)
2208 /* This is an SSE2 version of Halley's method for approximating the
2209 * cube root of an IEEE float implementation.
2211 * The scalar version is as follows:
2213 * static inline float
2214 * _cbrt_5f (float x)
2216 * union { float f; uint32_t i; } u = { x };
2218 * u.i = u.i / 3 + 709921077;
2222 * static inline float
2223 * _cbrta_halleyf (float a, float R)
2225 * float a3 = a * a * a;
2226 * float b = a * (a3 + R + R) / (a3 + a3 + R);
2230 * static inline float
2236 * a = _cbrta_halleyf (a, x);
2237 * a = _cbrta_halleyf (a, x);
2241 * The above scalar version seems to have originated from
2242 * http://metamerist.com/cbrt/cbrt.htm but that's not accessible
2243 * anymore. At present there's a copy in CubeRoot.cpp in the Skia
2244 * sources that's licensed under a BSD-style license. There's some
2245 * discussion on the implementation at
2246 * http://www.voidcn.com/article/p-gpwztojr-wt.html.
2248 * Note that Darktable also has an SSE2 version of the same algorithm,
2249 * but uses only a single iteration of Halley's method, which is too
2252 /* Return cube roots of the four single-precision floating point
2255 static inline __m128
2256 _cbrtf_ps_sse2 (__m128 x
)
2258 const __m128i magic
= _mm_set1_epi32 (709921077);
2260 __m128i xi
= _mm_castps_si128 (x
);
2261 __m128 xi_3
= _mm_div_ps (_mm_cvtepi32_ps (xi
), _mm_set1_ps (3.0f
));
2262 __m128i ai
= _mm_add_epi32 (_mm_cvtps_epi32 (xi_3
), magic
);
2263 __m128 a
= _mm_castsi128_ps (ai
);
2265 __m128 a3
= _mm_mul_ps (_mm_mul_ps (a
, a
), a
);
2266 __m128 divisor
= _mm_add_ps (_mm_add_ps (a3
, a3
), x
);
2267 a
= _mm_div_ps (_mm_mul_ps (a
, _mm_add_ps (a3
, _mm_add_ps (x
, x
))), divisor
);
2269 a3
= _mm_mul_ps (_mm_mul_ps (a
, a
), a
);
2270 divisor
= _mm_add_ps (_mm_add_ps (a3
, a3
), x
);
2271 a
= _mm_div_ps (_mm_mul_ps (a
, _mm_add_ps (a3
, _mm_add_ps (x
, x
))), divisor
);
2276 static inline __m128
2277 lab_r_to_f_sse2 (__m128 r
)
2279 const __m128 epsilon
= _mm_set1_ps (LAB_EPSILON
);
2280 const __m128 kappa
= _mm_set1_ps (LAB_KAPPA
);
2282 const __m128 f_big
= _cbrtf_ps_sse2 (r
);
2284 const __m128 f_small
= _mm_div_ps (_mm_add_ps (_mm_mul_ps (kappa
, r
), _mm_set1_ps (16.0f
)),
2285 _mm_set1_ps (116.0f
));
2287 const __m128 mask
= _mm_cmpgt_ps (r
, epsilon
);
2288 const __m128 f
= _mm_or_ps (_mm_and_ps (mask
, f_big
), _mm_andnot_ps (mask
, f_small
));
2293 Yf_to_Lf_sse2 (const Babl
*conversion
,
2301 if (((uintptr_t) src
% 16) + ((uintptr_t) dst
% 16) == 0)
2303 const long n
= (samples
/ 4) * 4;
2305 for ( ; i
< n
; i
+= 4)
2307 __m128 Y
= _mm_load_ps (src
);
2309 __m128 fy
= lab_r_to_f_sse2 (Y
);
2311 __m128 L
= _mm_sub_ps (_mm_mul_ps (_mm_set1_ps (116.0f
), fy
), _mm_set1_ps (16.0f
));
2313 _mm_store_ps (dst
, L
);
2320 remainder
= samples
- i
;
2324 float L
= yr
> LAB_EPSILONf
? 116.0f
* _cbrtf (yr
) - 16 : LAB_KAPPAf
* yr
;
2334 Yaf_to_Lf_sse2 (const Babl
*conversion
,
2342 if (((uintptr_t) src
% 16) + ((uintptr_t) dst
% 16) == 0)
2344 const long n
= (samples
/ 4) * 4;
2346 for ( ; i
< n
; i
+= 4)
2348 __m128 YaYa0
= _mm_load_ps (src
);
2349 __m128 YaYa1
= _mm_load_ps (src
+ 4);
2351 __m128 Y
= _mm_shuffle_ps (YaYa0
, YaYa1
, _MM_SHUFFLE (2, 0, 2, 0));
2353 __m128 fy
= lab_r_to_f_sse2 (Y
);
2355 __m128 L
= _mm_sub_ps (_mm_mul_ps (_mm_set1_ps (116.0f
), fy
), _mm_set1_ps (16.0f
));
2357 _mm_store_ps (dst
, L
);
2364 remainder
= samples
- i
;
2368 float L
= yr
> LAB_EPSILONf
? 116.0f
* _cbrtf (yr
) - 16 : LAB_KAPPAf
* yr
;
2378 rgbaf_to_Lf_sse2 (const Babl
*conversion
,
2383 const Babl
*space
= babl_conversion_get_source_space (conversion
);
2384 const float m_1_0
= space
->space
.RGBtoXYZf
[3] / D50_WHITE_REF_Yf
;
2385 const float m_1_1
= space
->space
.RGBtoXYZf
[4] / D50_WHITE_REF_Yf
;
2386 const float m_1_2
= space
->space
.RGBtoXYZf
[5] / D50_WHITE_REF_Yf
;
2390 if (((uintptr_t) src
% 16) + ((uintptr_t) dst
% 16) == 0)
2392 const long n
= (samples
/ 4) * 4;
2393 const __m128 m_1_0_v
= _mm_set1_ps (m_1_0
);
2394 const __m128 m_1_1_v
= _mm_set1_ps (m_1_1
);
2395 const __m128 m_1_2_v
= _mm_set1_ps (m_1_2
);
2397 for ( ; i
< n
; i
+= 4)
2399 __m128 rgba0
= _mm_load_ps (src
);
2400 __m128 rgba1
= _mm_load_ps (src
+ 4);
2401 __m128 rgba2
= _mm_load_ps (src
+ 8);
2402 __m128 rgba3
= _mm_load_ps (src
+ 12);
2408 _MM_TRANSPOSE4_PS (r
, g
, b
, a
);
2411 __m128 yr
= _mm_add_ps (_mm_add_ps (_mm_mul_ps (m_1_0_v
, r
), _mm_mul_ps (m_1_1_v
, g
)),
2412 _mm_mul_ps (m_1_2_v
, b
));
2414 __m128 fy
= lab_r_to_f_sse2 (yr
);
2416 __m128 L
= _mm_sub_ps (_mm_mul_ps (_mm_set1_ps (116.0f
), fy
), _mm_set1_ps (16.0f
));
2418 _mm_store_ps (dst
, L
);
2426 remainder
= samples
- i
;
2433 float yr
= m_1_0
* r
+ m_1_1
* g
+ m_1_2
* b
;
2434 float L
= yr
> LAB_EPSILONf
? 116.0f
* _cbrtf (yr
) - 16 : LAB_KAPPAf
* yr
;
2444 rgbaf_to_Labaf_sse2_aligned_4mult (const Babl
*conversion
,
2449 const Babl
*space
= babl_conversion_get_source_space (conversion
);
2450 const float m_0_0
= space
->space
.RGBtoXYZf
[0] / D50_WHITE_REF_Xf
;
2451 const float m_0_1
= space
->space
.RGBtoXYZf
[1] / D50_WHITE_REF_Xf
;
2452 const float m_0_2
= space
->space
.RGBtoXYZf
[2] / D50_WHITE_REF_Xf
;
2453 const float m_1_0
= space
->space
.RGBtoXYZf
[3] / D50_WHITE_REF_Yf
;
2454 const float m_1_1
= space
->space
.RGBtoXYZf
[4] / D50_WHITE_REF_Yf
;
2455 const float m_1_2
= space
->space
.RGBtoXYZf
[5] / D50_WHITE_REF_Yf
;
2456 const float m_2_0
= space
->space
.RGBtoXYZf
[6] / D50_WHITE_REF_Zf
;
2457 const float m_2_1
= space
->space
.RGBtoXYZf
[7] / D50_WHITE_REF_Zf
;
2458 const float m_2_2
= space
->space
.RGBtoXYZf
[8] / D50_WHITE_REF_Zf
;
2461 const __m128 m_0_0_v
= _mm_set1_ps (m_0_0
);
2462 const __m128 m_0_1_v
= _mm_set1_ps (m_0_1
);
2463 const __m128 m_0_2_v
= _mm_set1_ps (m_0_2
);
2464 const __m128 m_1_0_v
= _mm_set1_ps (m_1_0
);
2465 const __m128 m_1_1_v
= _mm_set1_ps (m_1_1
);
2466 const __m128 m_1_2_v
= _mm_set1_ps (m_1_2
);
2467 const __m128 m_2_0_v
= _mm_set1_ps (m_2_0
);
2468 const __m128 m_2_1_v
= _mm_set1_ps (m_2_1
);
2469 const __m128 m_2_2_v
= _mm_set1_ps (m_2_2
);
2471 assert (((uintptr_t) src
% 16) + ((uintptr_t) dst
% 16) == 0);
2472 assert (samples
% 4 == 0);
2474 for ( ; i
< samples
; i
+= 4)
2481 __m128 rgba0
= _mm_load_ps (src
);
2482 __m128 rgba1
= _mm_load_ps (src
+ 4);
2483 __m128 rgba2
= _mm_load_ps (src
+ 8);
2484 __m128 rgba3
= _mm_load_ps (src
+ 12);
2490 _MM_TRANSPOSE4_PS (r
, g
, b
, a
);
2493 __m128 xr
= _mm_add_ps (_mm_add_ps (_mm_mul_ps (m_0_0_v
, r
), _mm_mul_ps (m_0_1_v
, g
)),
2494 _mm_mul_ps (m_0_2_v
, b
));
2495 __m128 yr
= _mm_add_ps (_mm_add_ps (_mm_mul_ps (m_1_0_v
, r
), _mm_mul_ps (m_1_1_v
, g
)),
2496 _mm_mul_ps (m_1_2_v
, b
));
2497 __m128 zr
= _mm_add_ps (_mm_add_ps (_mm_mul_ps (m_2_0_v
, r
), _mm_mul_ps (m_2_1_v
, g
)),
2498 _mm_mul_ps (m_2_2_v
, b
));
2500 __m128 fx
= lab_r_to_f_sse2 (xr
);
2501 __m128 fy
= lab_r_to_f_sse2 (yr
);
2502 __m128 fz
= lab_r_to_f_sse2 (zr
);
2504 __m128 L
= _mm_sub_ps (_mm_mul_ps (_mm_set1_ps (116.0f
), fy
), _mm_set1_ps (16.0f
));
2505 __m128 A
= _mm_mul_ps (_mm_set1_ps (500.0f
), _mm_sub_ps (fx
, fy
));
2506 __m128 B
= _mm_mul_ps (_mm_set1_ps (200.0f
), _mm_sub_ps (fy
, fz
));
2512 _MM_TRANSPOSE4_PS (Laba0
, Laba1
, Laba2
, Laba3
);
2515 _mm_store_ps (dst
, Laba0
);
2516 _mm_store_ps (dst
+ 4, Laba1
);
2517 _mm_store_ps (dst
+ 8, Laba2
);
2518 _mm_store_ps (dst
+ 12, Laba3
);
2526 rgbaf_to_Labaf_sse2 (const Babl
*conversion
,
2531 if (((uintptr_t) src
% 16) + ((uintptr_t) dst
% 16) == 0 ||
2534 long first_samples
= samples
/ 4 * 4;
2537 rgbaf_to_Labaf_sse2_aligned_4mult (conversion
, src
, dst
, first_samples
);
2538 remainder
= samples
- first_samples
;
2542 float __attribute__ ((aligned (16))) aligned_src
[16];
2543 float __attribute__ ((aligned (16))) aligned_dest
[16];
2545 memcpy (aligned_src
, src
+ first_samples
* 4, remainder
* 16);
2546 memset (aligned_src
+ remainder
* 4, 0, 4 * 16 - (remainder
* 16));
2547 rgbaf_to_Labaf_sse2_aligned_4mult (conversion
, (const float *) aligned_src
, aligned_dest
, 4);
2548 memcpy (dst
+ first_samples
* 4, aligned_dest
, remainder
* 16);
2553 float __attribute__ ((aligned (16))) _aligned_src
[4 * samples
];
2554 float __attribute__ ((aligned (16))) _aligned_dst
[4 * samples
];
2558 if (((uintptr_t) src
% 16) != 0)
2560 aligned_src
= _aligned_src
;
2561 memcpy (aligned_src
, src
, samples
* 16);
2565 aligned_src
= (float *) src
;
2568 if (((uintptr_t) dst
% 16) != 0)
2569 aligned_dst
= _aligned_dst
;
2573 rgbaf_to_Labaf_sse2 (conversion
, aligned_src
, aligned_dst
, samples
);
2575 if (((uintptr_t) dst
% 16) != 0)
2576 memcpy (dst
, aligned_dst
, samples
* 16);
2580 #endif /* defined(USE_SSE2) */
2587 babl_conversion_new (
2588 babl_model ("RGBA"),
2589 babl_model ("CIE Lab"),
2590 "linear", rgba_to_lab
,
2593 babl_conversion_new (
2594 babl_model ("CIE Lab"),
2595 babl_model ("RGBA"),
2596 "linear", lab_to_rgba
,
2599 babl_conversion_new (
2600 babl_model ("RGBA"),
2601 babl_model ("CIE Lab alpha"),
2602 "linear", rgba_to_laba
,
2605 babl_conversion_new (
2606 babl_model ("CIE Lab alpha"),
2607 babl_model ("RGBA"),
2608 "linear", laba_to_rgba
,
2611 babl_conversion_new (
2612 babl_model ("RGBA"),
2613 babl_model ("CIE LCH(ab)"),
2614 "linear", rgba_to_lchab
,
2617 babl_conversion_new (
2618 babl_model ("CIE LCH(ab)"),
2619 babl_model ("RGBA"),
2620 "linear", lchab_to_rgba
,
2623 babl_conversion_new (
2624 babl_model ("RGBA"),
2625 babl_model ("CIE LCH(ab) alpha"),
2626 "linear", rgba_to_lchaba
,
2629 babl_conversion_new (
2630 babl_model ("CIE LCH(ab) alpha"),
2631 babl_model ("RGBA"),
2632 "linear", lchaba_to_rgba
,
2635 babl_conversion_new (
2636 babl_model ("RGBA"),
2637 babl_model ("CIE XYZ"),
2638 "linear", rgba_to_xyz
,
2641 babl_conversion_new (
2642 babl_model ("CIE XYZ"),
2643 babl_model ("RGBA"),
2644 "linear", xyz_to_rgba
,
2647 babl_conversion_new (
2648 babl_model ("RGBA"),
2649 babl_model ("CIE XYZ alpha"),
2650 "linear", rgba_to_xyza
,
2653 babl_conversion_new (
2654 babl_model ("CIE XYZ alpha"),
2655 babl_model ("RGBA"),
2656 "linear", xyza_to_rgba
,
2661 babl_conversion_new (
2662 babl_model ("RGBA"),
2663 babl_model ("CIE xyY"),
2664 "linear", rgba_to_xyY
,
2667 babl_conversion_new (
2668 babl_model ("CIE xyY"),
2669 babl_model ("RGBA"),
2670 "linear", xyY_to_rgba
,
2673 babl_conversion_new (
2674 babl_model ("RGBA"),
2675 babl_model ("CIE xyY alpha"),
2676 "linear", rgba_to_xyYa
,
2679 babl_conversion_new (
2680 babl_model ("CIE xyY alpha"),
2681 babl_model ("RGBA"),
2682 "linear", xyYa_to_rgba
,
2687 babl_conversion_new (
2688 babl_model ("RGBA"),
2689 babl_model ("CIE Yuv"),
2690 "linear", rgba_to_Yuv
,
2693 babl_conversion_new (
2694 babl_model ("CIE Yuv"),
2695 babl_model ("RGBA"),
2696 "linear", Yuv_to_rgba
,
2699 babl_conversion_new (
2700 babl_model ("RGBA"),
2701 babl_model ("CIE Yuv alpha"),
2702 "linear", rgba_to_Yuva
,
2705 babl_conversion_new (
2706 babl_model ("CIE Yuv alpha"),
2707 babl_model ("RGBA"),
2708 "linear", Yuva_to_rgba
,
2714 babl_conversion_new (
2715 babl_format ("RGB float"),
2716 babl_format ("CIE Lab float"),
2717 "linear", rgbf_to_Labf
,
2720 babl_conversion_new (
2721 babl_format ("RGBA float"),
2722 babl_format ("CIE Lab float"),
2723 "linear", rgbaf_to_Labf
,
2726 babl_conversion_new (
2727 babl_format ("RGBA float"),
2728 babl_format ("CIE Lab alpha float"),
2729 "linear", rgbaf_to_Labaf
,
2732 babl_conversion_new (
2733 babl_format ("CIE Lab float"),
2734 babl_format ("RGB float"),
2735 "linear", Labf_to_rgbf
,
2738 babl_conversion_new (
2739 babl_format ("CIE Lab float"),
2740 babl_format ("RGBA float"),
2741 "linear", Labf_to_rgbaf
,
2744 babl_conversion_new (
2745 babl_format ("CIE Lab alpha float"),
2746 babl_format ("RGBA float"),
2747 "linear", Labaf_to_rgbaf
,
2750 babl_conversion_new (
2751 babl_format ("Y float"),
2752 babl_format ("CIE L float"),
2756 babl_conversion_new (
2757 babl_format ("YA float"),
2758 babl_format ("CIE L float"),
2759 "linear", Yaf_to_Lf
,
2762 babl_conversion_new (
2763 babl_format ("YA float"),
2764 babl_format ("CIE L alpha float"),
2765 "linear", Yaf_to_Laf
,
2768 babl_conversion_new (
2769 babl_format ("RGBA float"),
2770 babl_format ("CIE L float"),
2771 "linear", rgbaf_to_Lf
,
2774 babl_conversion_new (
2775 babl_format ("CIE Lab float"),
2776 babl_format ("CIE L float"),
2777 "linear", Labf_to_Lf
,
2780 babl_conversion_new (
2781 babl_format ("CIE Lab alpha float"),
2782 babl_format ("CIE L float"),
2783 "linear", Labaf_to_Lf
,
2786 babl_conversion_new (
2787 babl_format ("CIE Lab float"),
2788 babl_format ("CIE LCH(ab) float"),
2789 "linear", Labf_to_Lchabf
,
2792 babl_conversion_new (
2793 babl_format ("CIE LCH(ab) float"),
2794 babl_format ("CIE Lab float"),
2795 "linear", Lchabf_to_Labf
,
2798 babl_conversion_new (
2799 babl_format ("CIE Lab alpha float"),
2800 babl_format ("CIE LCH(ab) alpha float"),
2801 "linear", Labaf_to_Lchabaf
,
2804 babl_conversion_new (
2805 babl_format ("CIE LCH(ab) alpha float"),
2806 babl_format ("CIE Lab alpha float"),
2807 "linear", Lchabaf_to_Labaf
,
2812 babl_conversion_new (
2813 babl_format ("RGB float"),
2814 babl_format ("CIE xyY float"),
2815 "linear", rgbf_to_xyYf
,
2818 babl_conversion_new (
2819 babl_format ("RGBA float"),
2820 babl_format ("CIE xyY alpha float"),
2821 "linear", rgbaf_to_xyYaf
,
2824 babl_conversion_new (
2825 babl_format ("RGBA float"),
2826 babl_format ("CIE xyY float"),
2827 "linear", rgbaf_to_xyYf
,
2830 babl_conversion_new (
2831 babl_format ("CIE xyY float"),
2832 babl_format ("RGB float"),
2833 "linear", xyYf_to_rgbf
,
2836 babl_conversion_new (
2837 babl_format ("CIE xyY float"),
2838 babl_format ("RGBA float"),
2839 "linear", xyYf_to_rgbaf
,
2842 babl_conversion_new (
2843 babl_format ("CIE xyY alpha float"),
2844 babl_format ("RGBA float"),
2845 "linear", xyYaf_to_rgbaf
,
2849 babl_conversion_new (
2850 babl_format ("RGB float"),
2851 babl_format ("CIE Yuv float"),
2852 "linear", rgbf_to_Yuvf
,
2855 babl_conversion_new (
2856 babl_format ("RGBA float"),
2857 babl_format ("CIE Yuv alpha float"),
2858 "linear", rgbaf_to_Yuvaf
,
2861 babl_conversion_new (
2862 babl_format ("RGBA float"),
2863 babl_format ("CIE Yuv float"),
2864 "linear", rgbaf_to_Yuvf
,
2867 babl_conversion_new (
2868 babl_format ("CIE Yuv float"),
2869 babl_format ("RGB float"),
2870 "linear", Yuvf_to_rgbf
,
2873 babl_conversion_new (
2874 babl_format ("CIE Yuv float"),
2875 babl_format ("RGBA float"),
2876 "linear", Yuvf_to_rgbaf
,
2879 babl_conversion_new (
2880 babl_format ("CIE Yuv alpha float"),
2881 babl_format ("RGBA float"),
2882 "linear", Yuvaf_to_rgbaf
,
2885 #if defined(USE_SSE2)
2887 if (babl_cpu_accel_get_support () & BABL_CPU_ACCEL_X86_SSE2
)
2889 babl_conversion_new (
2890 babl_format ("RGBA float"),
2891 babl_format ("CIE Lab alpha float"),
2892 "linear", rgbaf_to_Labaf_sse2
,
2895 babl_conversion_new (
2896 babl_format ("Y float"),
2897 babl_format ("CIE L float"),
2898 "linear", Yf_to_Lf_sse2
,
2901 babl_conversion_new (
2902 babl_format ("YA float"),
2903 babl_format ("CIE L float"),
2904 "linear", Yaf_to_Lf_sse2
,
2907 babl_conversion_new (
2908 babl_format ("RGBA float"),
2909 babl_format ("CIE L float"),
2910 "linear", rgbaf_to_Lf_sse2
,
2915 #endif /* defined(USE_SSE2) */
2924 "name", "CIE Lab float",
2925 babl_model ("CIE Lab"),
2927 babl_type ("float"),
2928 babl_component ("CIE L"),
2929 babl_component ("CIE a"),
2930 babl_component ("CIE b"),
2934 "name", "CIE XYZ float",
2935 babl_model ("CIE XYZ"),
2937 babl_type ("float"),
2938 babl_component ("CIE X"),
2939 babl_component ("CIE Y"),
2940 babl_component ("CIE Z"),
2944 "name", "CIE XYZ alpha float",
2945 babl_model ("CIE XYZ"),
2947 babl_type ("float"),
2948 babl_component ("CIE X"),
2949 babl_component ("CIE Y"),
2950 babl_component ("CIE Z"),
2951 babl_component ("A"),
2955 "name", "CIE Lab alpha float",
2956 babl_model ("CIE Lab alpha"),
2958 babl_type ("float"),
2959 babl_component ("CIE L"),
2960 babl_component ("CIE a"),
2961 babl_component ("CIE b"),
2962 babl_component ("A"),
2966 "name", "CIE LCH(ab) float",
2967 babl_model ("CIE LCH(ab)"),
2969 babl_type ("float"),
2970 babl_component ("CIE L"),
2971 babl_component ("CIE C(ab)"),
2972 babl_component ("CIE H(ab)"),
2976 "name", "CIE LCH(ab) alpha float",
2977 babl_model ("CIE LCH(ab) alpha"),
2979 babl_type ("float"),
2980 babl_component ("CIE L"),
2981 babl_component ("CIE C(ab)"),
2982 babl_component ("CIE H(ab)"),
2983 babl_component ("A"),
2987 "name", "CIE L float",
2988 babl_model ("CIE Lab"),
2989 babl_type ("float"),
2990 babl_component ("CIE L"),
2994 "name", "CIE L alpha float",
2995 babl_model ("CIE Lab alpha"),
2996 babl_type ("float"),
2997 babl_component ("CIE L"),
2998 babl_component ("A"),
3002 "name", "CIE Lab u8",
3003 babl_model ("CIE Lab"),
3005 babl_type ("CIE u8 L"),
3006 babl_component ("CIE L"),
3007 babl_type ("CIE u8 ab"),
3008 babl_component ("CIE a"),
3009 babl_type ("CIE u8 ab"),
3010 babl_component ("CIE b"),
3014 "name", "CIE Lab alpha u8",
3015 babl_model ("CIE Lab alpha"),
3017 babl_type ("CIE u8 L"),
3018 babl_component ("CIE L"),
3019 babl_type ("CIE u8 ab"),
3020 babl_component ("CIE a"),
3021 babl_type ("CIE u8 ab"),
3022 babl_component ("CIE b"),
3024 babl_component ("A"),
3028 "name", "CIE Lab u16",
3029 babl_model ("CIE Lab"),
3031 babl_type ("CIE u16 L"),
3032 babl_component ("CIE L"),
3033 babl_type ("CIE u16 ab"),
3034 babl_component ("CIE a"),
3035 babl_type ("CIE u16 ab"),
3036 babl_component ("CIE b"),
3040 "name", "CIE Lab alpha u16",
3041 babl_model ("CIE Lab alpha"),
3043 babl_type ("CIE u16 L"),
3044 babl_component ("CIE L"),
3045 babl_type ("CIE u16 ab"),
3046 babl_component ("CIE a"),
3047 babl_type ("CIE u16 ab"),
3048 babl_component ("CIE b"),
3050 babl_component ("A"),
3054 "name", "CIE xyY float",
3055 babl_model ("CIE xyY"),
3057 babl_type ("float"),
3058 babl_component ("CIE x"),
3059 babl_component ("CIE y"),
3060 babl_component ("CIE Y"),
3064 "name", "CIE xyY alpha float",
3065 babl_model ("CIE xyY alpha"),
3067 babl_type ("float"),
3068 babl_component ("CIE x"),
3069 babl_component ("CIE y"),
3070 babl_component ("CIE Y"),
3071 babl_component ("A"),
3076 "name", "CIE Yuv float",
3077 babl_model ("CIE Yuv"),
3079 babl_type ("float"),
3080 babl_component ("CIE Y"),
3081 babl_component ("CIE u"),
3082 babl_component ("CIE v"),
3086 "name", "CIE Yuv alpha float",
3087 babl_model ("CIE Yuv alpha"),
3089 babl_type ("float"),
3090 babl_component ("CIE Y"),
3091 babl_component ("CIE u"),
3092 babl_component ("CIE v"),
3093 babl_component ("A"),
3098 /******** end floating point RGB/CIE color space conversions **********/
3100 /******** begin integer RGB/CIE color space conversions **************/
3103 convert_double_u8_scaled (const Babl
*conversion
,
3116 double dval
= *(double *) src
;
3117 unsigned char u8val
;
3121 else if (dval
> max_val
)
3124 u8val
= ((dval
- min_val
) / (max_val
- min_val
) * (max
- min
) + min
) + 0.5;
3126 *(unsigned char *) dst
= u8val
;
3133 convert_u8_double_scaled (const Babl
*conversion
,
3146 int u8val
= *(unsigned char *) src
;
3151 else if (u8val
> max
)
3154 dval
= (u8val
- min
) / (double) (max
- min
) * (max_val
- min_val
) + min_val
;
3156 (*(double *) dst
) = dval
;
3163 #define MAKE_CONVERSIONS(name, min_val, max_val, min, max) \
3165 convert_ ## name ## _double (const Babl *c, char *src, \
3171 convert_u8_double_scaled (c, min_val, max_val, min, max, \
3172 src, dst, src_pitch, dst_pitch, n); \
3175 convert_double_ ## name (const Babl *c, char *src, \
3181 convert_double_u8_scaled (c, min_val, max_val, min, max, \
3182 src, dst, src_pitch, dst_pitch, n); \
3185 /* source ICC.1:2004-10 */
3187 MAKE_CONVERSIONS (u8_l
, 0.0, 100.0, 0x00, 0xff)
3188 MAKE_CONVERSIONS (u8_ab
, -128.0, 127.0, 0x00, 0xff)
3190 #undef MAKE_CONVERSIONS
3193 convert_float_u8_scaled (const Babl
*conversion
,
3206 float dval
= *(float *) src
;
3207 unsigned char u8val
;
3211 else if (dval
> max_val
)
3214 u8val
= ((dval
- min_val
) / (max_val
- min_val
) * (max
- min
) + min
) + 0.5f
;
3216 *(unsigned char *) dst
= u8val
;
3223 convert_u8_float_scaled (const Babl
*conversion
,
3236 int u8val
= *(unsigned char *) src
;
3241 else if (u8val
> max
)
3244 dval
= (u8val
- min
) / (float) (max
- min
) * (max_val
- min_val
) + min_val
;
3246 (*(float *) dst
) = dval
;
3253 #define MAKE_CONVERSIONS(name, min_val, max_val, min, max) \
3255 convert_ ## name ## _float (const Babl *c, char *src, \
3261 convert_u8_float_scaled (c, min_val, max_val, min, max, \
3262 src, dst, src_pitch, dst_pitch, n); \
3265 convert_float_ ## name (const Babl *c, char *src, \
3271 convert_float_u8_scaled (c, min_val, max_val, min, max, \
3272 src, dst, src_pitch, dst_pitch, n); \
3275 /* source ICC.1:2004-10 */
3277 MAKE_CONVERSIONS (u8_l
, 0.0, 100.0, 0x00, 0xff)
3278 MAKE_CONVERSIONS (u8_ab
, -128.0, 127.0, 0x00, 0xff)
3280 #undef MAKE_CONVERSIONS
3305 babl_conversion_new (
3306 babl_type ("CIE u8 L"),
3307 babl_type ("double"),
3308 "plane", convert_u8_l_double
,
3311 babl_conversion_new (
3312 babl_type ("double"),
3313 babl_type ("CIE u8 L"),
3314 "plane", convert_double_u8_l
,
3318 babl_conversion_new (
3319 babl_type ("CIE u8 ab"),
3320 babl_type ("double"),
3321 "plane", convert_u8_ab_double
,
3324 babl_conversion_new (
3325 babl_type ("double"),
3326 babl_type ("CIE u8 ab"),
3327 "plane", convert_double_u8_ab
,
3331 babl_conversion_new (
3332 babl_type ("CIE u8 L"),
3333 babl_type ("float"),
3334 "plane", convert_u8_l_float
,
3337 babl_conversion_new (
3338 babl_type ("float"),
3339 babl_type ("CIE u8 L"),
3340 "plane", convert_float_u8_l
,
3344 babl_conversion_new (
3345 babl_type ("CIE u8 ab"),
3346 babl_type ("float"),
3347 "plane", convert_u8_ab_float
,
3350 babl_conversion_new (
3351 babl_type ("float"),
3352 babl_type ("CIE u8 ab"),
3353 "plane", convert_float_u8_ab
,
3359 convert_double_u16_scaled (const Babl
*conversion
,
3372 double dval
= *(double *) src
;
3373 unsigned short u16val
;
3377 else if (dval
> max_val
)
3380 u16val
= ((dval
- min_val
) / (max_val
- min_val
) * (max
- min
) + min
) + 0.5f
;
3382 *(unsigned short *) dst
= u16val
;
3389 convert_u16_double_scaled (const Babl
*conversion
,
3402 int u16val
= *(unsigned short *) src
;
3407 else if (u16val
> max
)
3410 dval
= (u16val
- min
) / (double) (max
- min
) * (max_val
- min_val
) + min_val
;
3412 (*(double *) dst
) = dval
;
3418 #define MAKE_CONVERSIONS(name, min_val, max_val, min, max) \
3420 convert_ ## name ## _double (const Babl *c, char *src, \
3426 convert_u16_double_scaled (c, min_val, max_val, min, max, \
3427 src, dst, src_pitch, dst_pitch, n); \
3430 convert_double_ ## name (const Babl *c, char *src, \
3436 convert_double_u16_scaled (c, min_val, max_val, min, max, \
3437 src, dst, src_pitch, dst_pitch, n); \
3440 MAKE_CONVERSIONS (u16_l
, 0.0, 100.0, 0x00, 0xffff)
3441 MAKE_CONVERSIONS (u16_ab
, -128.0, 127.0, 0x00, 0xffff)
3443 #undef MAKE_CONVERSIONS
3447 convert_float_u16_scaled (const Babl
*conversion
,
3460 float dval
= *(float *) src
;
3461 unsigned short u16val
;
3465 else if (dval
> max_val
)
3468 u16val
= ((dval
- min_val
) / (max_val
- min_val
) * (max
- min
) + min
) + 0.5f
;
3470 *(unsigned short *) dst
= u16val
;
3477 convert_u16_float_scaled (const Babl
*conversion
,
3490 int u16val
= *(unsigned short *) src
;
3495 else if (u16val
> max
)
3498 dval
= (u16val
- min
) / (float) (max
- min
) * (max_val
- min_val
) + min_val
;
3500 (*(float *) dst
) = dval
;
3506 #define MAKE_CONVERSIONS(name, min_val, max_val, min, max) \
3508 convert_ ## name ## _float (const Babl *c, char *src, \
3514 convert_u16_float_scaled (c, min_val, max_val, min, max, \
3515 src, dst, src_pitch, dst_pitch, n); \
3518 convert_float_ ## name (const Babl *c, char *src, \
3524 convert_float_u16_scaled (c, min_val, max_val, min, max, \
3525 src, dst, src_pitch, dst_pitch, n); \
3528 MAKE_CONVERSIONS (u16_l
, 0.0, 100.0, 0x00, 0xffff)
3529 MAKE_CONVERSIONS (u16_ab
, -128.0, 127.0, 0x00, 0xffff)
3531 #undef MAKE_CONVERSIONS
3557 babl_conversion_new (
3558 babl_type ("CIE u16 L"),
3559 babl_type ("double"),
3560 "plane", convert_u16_l_double
,
3563 babl_conversion_new (
3564 babl_type ("double"),
3565 babl_type ("CIE u16 L"),
3566 "plane", convert_double_u16_l
,
3570 babl_conversion_new (
3571 babl_type ("CIE u16 ab"),
3572 babl_type ("double"),
3573 "plane", convert_u16_ab_double
,
3576 babl_conversion_new (
3577 babl_type ("double"),
3578 babl_type ("CIE u16 ab"),
3579 "plane", convert_double_u16_ab
,
3583 babl_conversion_new (
3584 babl_type ("CIE u16 L"),
3585 babl_type ("float"),
3586 "plane", convert_u16_l_float
,
3589 babl_conversion_new (
3590 babl_type ("float"),
3591 babl_type ("CIE u16 L"),
3592 "plane", convert_float_u16_l
,
3596 babl_conversion_new (
3597 babl_type ("CIE u16 ab"),
3598 babl_type ("float"),
3599 "plane", convert_u16_ab_float
,
3602 babl_conversion_new (
3603 babl_type ("float"),
3604 babl_type ("CIE u16 ab"),
3605 "plane", convert_float_u16_ab
,
3617 /******** end integer RGB/CIE color space conversions ****************/
3620 rgbxyzrgb_init (void)
3627 static int initialized
= 0;