1 /* babl - dynamically extendable universal pixel conversion library.
2 * Copyright (C) 2012, Maxime Nicco <maxime.nicco@gmail.fr>
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/>.
20 * Adding support for HSV colorspace
29 #include "base/util.h"
31 #define MIN(a,b) (a > b) ? b : a;
32 #define MAX(a,b) (a < b) ? b : a;
33 #define EPSILON 1.0e-10
36 rgba_to_hsva (const Babl
*conversion
,
42 hsva_to_rgba (const Babl
*conversion
,
48 rgba_to_hsv (const Babl
*conversion
,
54 hsv_to_rgba (const Babl
*conversion
,
60 rgba_to_hsv_step (char *src
,
64 hsv_to_rgba_step (char *src
,
67 static void components (void);
68 static void models (void);
69 static void conversions (void);
70 static void formats (void);
89 babl_component_new ("hue", NULL
);
90 babl_component_new ("saturation", NULL
);
91 babl_component_new ("value", NULL
);
92 babl_component_new ("alpha", "alpha", NULL
);
101 babl_component ("hue"),
102 babl_component ("saturation"),
103 babl_component ("value"),
104 "doc", "A legacy color model that exists for compatibility with old GIMP code, V is MAX(R,G,B).",
109 babl_component ("hue"),
110 babl_component ("saturation"),
111 babl_component ("value"),
112 babl_component ("alpha"),
114 "doc", "HSV with separate alpha.",
122 babl_conversion_new (
125 "linear", rgba_to_hsva
,
129 babl_conversion_new (
132 "linear", rgba_to_hsv
,
136 babl_conversion_new (
139 "linear", hsva_to_rgba
,
143 babl_conversion_new (
146 "linear", hsv_to_rgba
,
155 "name", "HSVA float",
158 babl_component ("hue"),
159 babl_component ("saturation"),
160 babl_component ("value"),
161 babl_component ("alpha"),
169 babl_component ("hue"),
170 babl_component ("saturation"),
171 babl_component ("value"),
177 rgba_to_hsv_step (char *src
,
180 double hue
, saturation
, value
;
183 double red
= linear_to_gamma_2_2 (((double *) src
)[0]);
184 double green
= linear_to_gamma_2_2 (((double *) src
)[1]);
185 double blue
= linear_to_gamma_2_2 (((double *) src
)[2]);
189 value
= MAX (red
, blue
);
190 min
= MIN (green
, blue
);
194 value
= MAX (green
, blue
);
195 min
= MIN (red
, blue
);
198 chroma
= value
- min
;
203 saturation
= chroma
/ value
;
205 if (saturation
< EPSILON
)
211 if (fabs (red
- value
) < EPSILON
)
213 hue
= (green
- blue
) / chroma
;
218 else if (fabs (green
- value
) < EPSILON
)
219 hue
= 2.0 + (blue
- red
) / chroma
;
221 hue
= 4.0 + (red
- green
) / chroma
;
226 ((double *) dst
)[0] = hue
;
227 ((double *) dst
)[1] = saturation
;
228 ((double *) dst
)[2] = value
;
233 hsv_to_rgba_step (char *src
,
236 double hue
= ((double *) src
)[0];
237 double saturation
= ((double *) src
)[1];
238 double value
= ((double *) src
)[2];
240 double red
= 0, green
= 0, blue
= 0;
242 double chroma
, h_tmp
, x
, min
;
244 chroma
= saturation
* value
;
246 h_tmp
= fmod (hue
, 1.0);
247 h_tmp
+= h_tmp
< 0.0;
250 x
= chroma
* (1.0 - fabs (fmod (h_tmp
, 2.0) - 1.0));
257 else if (h_tmp
< 2.0)
262 else if (h_tmp
< 3.0)
267 else if (h_tmp
< 4.0)
272 else if (h_tmp
< 5.0)
277 else if (h_tmp
< 6.0)
283 min
= value
- chroma
;
289 ((double *) dst
)[0] = gamma_2_2_to_linear (red
);
290 ((double *) dst
)[1] = gamma_2_2_to_linear (green
);
291 ((double *) dst
)[2] = gamma_2_2_to_linear (blue
);
295 rgba_to_hsva (const Babl
*conversion
,
304 double alpha
= ((double *) src
)[3];
306 rgba_to_hsv_step (src
, dst
);
308 ((double *) dst
)[3] = alpha
;
310 src
+= 4 * sizeof (double);
311 dst
+= 4 * sizeof (double);
316 hsva_to_rgba (const Babl
*conversion
,
325 double alpha
= ((double *) src
)[3];
327 hsv_to_rgba_step (src
, dst
);
329 ((double *) dst
)[3] = alpha
;
331 src
+= 4 * sizeof (double);
332 dst
+= 4 * sizeof (double);
337 rgba_to_hsv (const Babl
*conversion
,
346 rgba_to_hsv_step (src
, dst
);
348 src
+= 4 * sizeof (double);
349 dst
+= 3 * sizeof (double);
354 hsv_to_rgba (const Babl
*conversion
,
363 hsv_to_rgba_step (src
, dst
);
365 ((double *) dst
)[3] = 1.0;
367 src
+= 3 * sizeof (double);
368 dst
+= 4 * sizeof (double);