Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
colorspace.h
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2012 Michal Babej.
4 Copyright (C) 2012-2013, 2017 Ulrich Pegelow.
5 Copyright (C) 2017 johannes hanika.
6 Copyright (C) 2018-2022 Aurélien PIERRE.
7 Copyright (C) 2020 Harold le Clément de Saint-Marcq.
8 Copyright (C) 2021 David Koller.
9 Copyright (C) 2021-2022 Pascal Obry.
10 Copyright (C) 2022 Sakari Kapanen.
11 Copyright (C) 2023 Luca Zulberti.
12
13 darktable is free software: you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 darktable is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with darktable. If not, see <http://www.gnu.org/licenses/>.
25*/
26
27#pragma once
28
29#include "common.h"
30
31static inline float4 matrix_dot(const float4 vector, const float4 matrix[3])
32{
33 float4 output;
34 const float4 vector_copy = { vector.x, vector.y, vector.z, 0.f };
35 output.x = dot(vector_copy, matrix[0]);
36 output.y = dot(vector_copy, matrix[1]);
37 output.z = dot(vector_copy, matrix[2]);
38 output.w = vector.w;
39 return output;
40}
41
42
43static inline float4 matrix_product(const float4 xyz, constant const float *const matrix)
44{
45 const float R = matrix[0] * xyz.x + matrix[1] * xyz.y + matrix[2] * xyz.z;
46 const float G = matrix[3] * xyz.x + matrix[4] * xyz.y + matrix[5] * xyz.z;
47 const float B = matrix[6] * xyz.x + matrix[7] * xyz.y + matrix[8] * xyz.z;
48 const float a = xyz.w;
49 return (float4)(R, G, B, a);
50}
51
52static inline float3 matrix_dot_float4_rows(const float4 row0, const float4 row1, const float4 row2, const float3 xyz)
53{
54 const float4 vv = (float4)(xyz.x, xyz.y, xyz.z, 0.0f);
55 return (float3)(dot(row0, vv), dot(row1, vv), dot(row2, vv));
56}
57
58static inline float3 matrix_dot_float4(const constant float4 *const matrix, const float3 xyz)
59{
60 return matrix_dot_float4_rows(matrix[0], matrix[1], matrix[2], xyz);
61}
62
63// same as above but with 4xfloat padded matrix
64static inline float4 matrix_product_float4(const float4 xyz, constant const float *const matrix)
65{
66 const float4 row0 = vload4(0, matrix);
67 const float4 row1 = vload4(1, matrix);
68 const float4 row2 = vload4(2, matrix);
69 const float3 out = matrix_dot_float4_rows(row0, row1, row2, xyz.xyz);
70 return (float4)(out.x, out.y, out.z, xyz.w);
71}
72
73static inline float4 Lab_2_LCH(float4 Lab)
74{
75 float H = atan2(Lab.z, Lab.y);
76
77 H = (H > 0.0f) ? H / (2.0f*M_PI_F) : 1.0f - fabs(H) / (2.0f*M_PI_F);
78
79 const float L = Lab.x;
80 const float C = sqrt(Lab.y*Lab.y + Lab.z*Lab.z);
81
82 return (float4)(L, C, H, Lab.w);
83}
84
85
86static inline float4 LCH_2_Lab(float4 LCH)
87{
88 const float L = LCH.x;
89 const float a = cos(2.0f*M_PI_F*LCH.z) * LCH.y;
90 const float b = sin(2.0f*M_PI_F*LCH.z) * LCH.y;
91
92 return (float4)(L, a, b, LCH.w);
93}
94
95
96static inline float4 lab_f(float4 x)
97{
98 const float4 epsilon = 216.0f / 24389.0f;
99 const float4 kappa = 24389.0f / 27.0f;
100 return (x > epsilon) ? native_powr(x, (float4)(1.0f/3.0f)) : (kappa * x + (float4)16.0f) / ((float4)116.0f);
101}
102
103
104static inline float4 XYZ_to_Lab(float4 xyz)
105{
106 float4 lab;
107 const float4 d50 = (float4)(0.9642f, 1.0f, 0.8249f, 1.0f);
108 xyz = lab_f(xyz / d50);
109 lab.x = 116.0f * xyz.y - 16.0f;
110 lab.y = 500.0f * (xyz.x - xyz.y);
111 lab.z = 200.0f * (xyz.y - xyz.z);
112
113 return lab;
114}
115
116
117static inline float4 lab_f_inv(float4 x)
118{
119 const float4 epsilon = 0.206896551f;
120 const float4 kappa = 24389.0f / 27.0f;
121 return (x > epsilon) ? x*x*x : ((float4)116.0f * x - (float4)16.0f)/kappa;
122}
123
124
125static inline float4 Lab_to_XYZ(float4 Lab)
126{
127 const float4 d50 = (float4)(0.9642f, 1.0f, 0.8249f, 0.0f);
128 float4 f;
129 f.y = (Lab.x + 16.0f)/116.0f;
130 f.x = Lab.y/500.0f + f.y;
131 f.z = f.y - Lab.z/200.0f;
132 return d50 * lab_f_inv(f);
133}
134
135static inline float4 prophotorgb_to_XYZ(float4 rgb)
136{
137 const float rgb_to_xyz[3][3] = { // prophoto rgb
138 {0.7976749f, 0.1351917f, 0.0313534f},
139 {0.2880402f, 0.7118741f, 0.0000857f},
140 {0.0000000f, 0.0000000f, 0.8252100f},
141 };
142 float4 XYZ = (float4)(0.0f, 0.0f, 0.0f, 0.0f);
143 XYZ.x += rgb_to_xyz[0][0] * rgb.x;
144 XYZ.x += rgb_to_xyz[0][1] * rgb.y;
145 XYZ.x += rgb_to_xyz[0][2] * rgb.z;
146 XYZ.y += rgb_to_xyz[1][0] * rgb.x;
147 XYZ.y += rgb_to_xyz[1][1] * rgb.y;
148 XYZ.y += rgb_to_xyz[1][2] * rgb.z;
149 XYZ.z += rgb_to_xyz[2][0] * rgb.x;
150 XYZ.z += rgb_to_xyz[2][1] * rgb.y;
151 XYZ.z += rgb_to_xyz[2][2] * rgb.z;
152 return XYZ;
153}
154
155static inline float4 XYZ_to_prophotorgb(float4 XYZ)
156{
157 const float xyz_to_rgb[3][3] = { // prophoto rgb d50
158 { 1.3459433f, -0.2556075f, -0.0511118f},
159 {-0.5445989f, 1.5081673f, 0.0205351f},
160 { 0.0000000f, 0.0000000f, 1.2118128f},
161 };
162 float4 rgb = (float4)(0.0f, 0.0f, 0.0f, 0.0f);
163 rgb.x += xyz_to_rgb[0][0] * XYZ.x;
164 rgb.x += xyz_to_rgb[0][1] * XYZ.y;
165 rgb.x += xyz_to_rgb[0][2] * XYZ.z;
166 rgb.y += xyz_to_rgb[1][0] * XYZ.x;
167 rgb.y += xyz_to_rgb[1][1] * XYZ.y;
168 rgb.y += xyz_to_rgb[1][2] * XYZ.z;
169 rgb.z += xyz_to_rgb[2][0] * XYZ.x;
170 rgb.z += xyz_to_rgb[2][1] * XYZ.y;
171 rgb.z += xyz_to_rgb[2][2] * XYZ.z;
172 return rgb;
173}
174
175static inline float4 Lab_to_prophotorgb(float4 Lab)
176{
177 const float4 XYZ = Lab_to_XYZ(Lab);
178 return XYZ_to_prophotorgb(XYZ);
179}
180
181static inline float4 prophotorgb_to_Lab(float4 rgb)
182{
183 const float4 XYZ = prophotorgb_to_XYZ(rgb);
184 return XYZ_to_Lab(XYZ);
185}
186
187static inline float4 RGB_2_HSL(const float4 RGB)
188{
189 float H, S, L;
190
191 // assumes that each channel is scaled to [0; 1]
192 const float R = RGB.x;
193 const float G = RGB.y;
194 const float B = RGB.z;
195
196 const float var_Min = fmin(R, fmin(G, B));
197 const float var_Max = fmax(R, fmax(G, B));
198 const float del_Max = var_Max - var_Min;
199
200 L = (var_Max + var_Min) / 2.0f;
201
202 if (del_Max < 1e-6f)
203 {
204 H = 0.0f;
205 S = 0.0f;
206 }
207 else
208 {
209 if (L < 0.5f) S = del_Max / (var_Max + var_Min);
210 else S = del_Max / (2.0f - var_Max - var_Min);
211
212 const float del_R = (((var_Max - R) / 6.0f) + (del_Max / 2.0f)) / del_Max;
213 const float del_G = (((var_Max - G) / 6.0f) + (del_Max / 2.0f)) / del_Max;
214 const float del_B = (((var_Max - B) / 6.0f) + (del_Max / 2.0f)) / del_Max;
215
216 if (R == var_Max) H = del_B - del_G;
217 else if (G == var_Max) H = (1.0f / 3.0f) + del_R - del_B;
218 else if (B == var_Max) H = (2.0f / 3.0f) + del_G - del_R;
219
220 if (H < 0.0f) H += 1.0f;
221 if (H > 1.0f) H -= 1.0f;
222 }
223
224 return (float4)(H, S, L, RGB.w);
225}
226
227
228
229static inline float Hue_2_RGB(float v1, float v2, float vH)
230{
231 if (vH < 0.0f) vH += 1.0f;
232 if (vH > 1.0f) vH -= 1.0f;
233 if ((6.0f * vH) < 1.0f) return (v1 + (v2 - v1) * 6.0f * vH);
234 if ((2.0f * vH) < 1.0f) return (v2);
235 if ((3.0f * vH) < 2.0f) return (v1 + (v2 - v1) * ((2.0f / 3.0f) - vH) * 6.0f);
236 return (v1);
237}
238
239
240
241static inline float4 HSL_2_RGB(const float4 HSL)
242{
243 float R, G, B;
244
245 const float H = HSL.x;
246 const float S = HSL.y;
247 const float L = HSL.z;
248
249 float var_1, var_2;
250
251 if (S < 1e-6f)
252 {
253 R = B = G = L;
254 }
255 else
256 {
257 if (L < 0.5f) var_2 = L * (1.0f + S);
258 else var_2 = (L + S) - (S * L);
259
260 var_1 = 2.0f * L - var_2;
261
262 R = Hue_2_RGB(var_1, var_2, H + (1.0f / 3.0f));
263 G = Hue_2_RGB(var_1, var_2, H);
264 B = Hue_2_RGB(var_1, var_2, H - (1.0f / 3.0f));
265 }
266
267 // returns RGB scaled to [0; 1] for each channel
268 return (float4)(R, G, B, HSL.w);
269}
270
271static inline float4 RGB_2_HSV(const float4 RGB)
272{
273 float4 HSV;
274
275 const float minv = fmin(RGB.x, fmin(RGB.y, RGB.z));
276 const float maxv = fmax(RGB.x, fmax(RGB.y, RGB.z));
277 const float delta = maxv - minv;
278
279 HSV.z = maxv;
280 HSV.w = RGB.w;
281
282 if(fabs(maxv) > 1e-6f && fabs(delta) > 1e-6f)
283 {
284 HSV.y = delta / maxv;
285 }
286 else
287 {
288 HSV.x = 0.0f;
289 HSV.y = 0.0f;
290 return HSV;
291 }
292
293 if (RGB.x == maxv)
294 HSV.x = (RGB.y - RGB.z) / delta;
295 else if (RGB.y == maxv)
296 HSV.x = 2.0f + (RGB.z - RGB.x) / delta;
297 else
298 HSV.x = 4.0f + (RGB.x - RGB.y) / delta;
299
300 HSV.x /= 6.0f;
301
302 if(HSV.x < 0)
303 HSV.x += 1.0f;
304
305 return HSV;
306}
307
308static inline float4 HSV_2_RGB(const float4 HSV)
309{
310 float4 RGB;
311
312 if (fabs(HSV.y) < 1e-6f)
313 {
314 RGB.x = RGB.y = RGB.z = HSV.z;
315 RGB.w = HSV.w;
316 return RGB;
317 }
318
319 const int i = floor(6.0f*HSV.x);
320 const float v = HSV.z;
321 const float w = HSV.w;
322 const float p = v * (1.0f - HSV.y);
323 const float q = v * (1.0f - HSV.y * (6.0f*HSV.x - i));
324 const float t = v * (1.0f - HSV.y * (1.0f - (6.0f*HSV.x - i)));
325
326 switch (i)
327 {
328 case 0:
329 RGB = (float4)(v, t, p, w);
330 break;
331 case 1:
332 RGB = (float4)(q, v, p, w);
333 break;
334 case 2:
335 RGB = (float4)(p, v, t, w);
336 break;
337 case 3:
338 RGB = (float4)(p, q, v, w);
339 break;
340 case 4:
341 RGB = (float4)(t, p, v, w);
342 break;
343 case 5:
344 default:
345 RGB = (float4)(v, p, q, w);
346 break;
347 }
348 return RGB;
349}
350
351
352// XYZ -> sRGB matrix, D65
353static inline float4 XYZ_to_sRGB(float4 XYZ)
354{
355 float4 sRGB;
356
357 sRGB.x = 3.1338561f * XYZ.x - 1.6168667f * XYZ.y - 0.4906146f * XYZ.z;
358 sRGB.y = -0.9787684f * XYZ.x + 1.9161415f * XYZ.y + 0.0334540f * XYZ.z;
359 sRGB.z = 0.0719453f * XYZ.x - 0.2289914f * XYZ.y + 1.4052427f * XYZ.z;
360 sRGB.w = XYZ.w;
361
362 return sRGB;
363}
364
365
366// sRGB -> XYZ matrix, D65
367static inline float4 sRGB_to_XYZ(float4 sRGB)
368{
369 float4 XYZ;
370
371 XYZ.x = 0.4360747f * sRGB.x + 0.3850649f * sRGB.y + 0.1430804f * sRGB.z;
372 XYZ.y = 0.2225045f * sRGB.x + 0.7168786f * sRGB.y + 0.0606169f * sRGB.z;
373 XYZ.z = 0.0139322f * sRGB.x + 0.0971045f * sRGB.y + 0.7141733f * sRGB.z;
374 XYZ.w = sRGB.w;
375
376 return XYZ;
377}
378
379
380static inline float4 XYZ_to_JzAzBz(float4 XYZ_D65)
381{
382 const float4 M[3] = { { 0.41478972f, 0.579999f, 0.0146480f, 0.0f },
383 { -0.2015100f, 1.120649f, 0.0531008f, 0.0f },
384 { -0.0166008f, 0.264800f, 0.6684799f, 0.0f } };
385
386 const float4 A[3] = { { 0.5f, 0.5f, 0.0f, 0.0f },
387 { 3.524000f, -4.066708f, 0.542708f, 0.0f },
388 { 0.199076f, 1.096799f, -1.295875f, 0.0f } };
389
390 float4 temp1, temp2;
391 // XYZ -> X'Y'Z
392 temp1.x = 1.15f * XYZ_D65.x - 0.15f * XYZ_D65.z;
393 temp1.y = 0.66f * XYZ_D65.y + 0.34f * XYZ_D65.x;
394 temp1.z = XYZ_D65.z;
395 temp1.w = 0.f;
396 // X'Y'Z -> LMS
397 temp2.x = dot(M[0], temp1);
398 temp2.y = dot(M[1], temp1);
399 temp2.z = dot(M[2], temp1);
400 temp2.w = 0.f;
401 // LMS -> L'M'S'
402 temp2 = native_powr(fmax(temp2 / 10000.f, 0.0f), 0.159301758f);
403 temp2 = native_powr((0.8359375f + 18.8515625f * temp2) / (1.0f + 18.6875f * temp2), 134.034375f);
404 // L'M'S' -> Izazbz
405 temp1.x = dot(A[0], temp2);
406 temp1.y = dot(A[1], temp2);
407 temp1.z = dot(A[2], temp2);
408 // Iz -> Jz
409 temp1.x = fmax(0.44f * temp1.x / (1.0f - 0.56f * temp1.x) - 1.6295499532821566e-11f, 0.f);
410 return temp1;
411}
412
413
414static inline float4 JzAzBz_2_XYZ(const float4 JzAzBz)
415{
416 const float b = 1.15f;
417 const float g = 0.66f;
418 const float c1 = 0.8359375f; // 3424 / 2^12
419 const float c2 = 18.8515625f; // 2413 / 2^7
420 const float c3 = 18.6875f; // 2392 / 2^7
421 const float n_inv = 1.0f / 0.159301758f; // 2610 / 2^14
422 const float p_inv = 1.0f / 134.034375f; // 1.7 x 2523 / 2^5
423 const float d = -0.56f;
424 const float d0 = 1.6295499532821566e-11f;
425 const float4 MI[3] = { { 1.9242264357876067f, -1.0047923125953657f, 0.0376514040306180f, 0.0f },
426 { 0.3503167620949991f, 0.7264811939316552f, -0.0653844229480850f, 0.0f },
427 { -0.0909828109828475f, -0.3127282905230739f, 1.5227665613052603f, 0.0f } };
428 const float4 AI[3] = { { 1.0f, 0.1386050432715393f, 0.0580473161561189f, 0.0f },
429 { 1.0f, -0.1386050432715393f, -0.0580473161561189f, 0.0f },
430 { 1.0f, -0.0960192420263190f, -0.8118918960560390f, 0.0f } };
431
432 float4 XYZ, LMS, IzAzBz;
433 // Jz -> Iz
434 IzAzBz = JzAzBz;
435 IzAzBz.x += d0;
436 IzAzBz.x = fmax(IzAzBz.x / (1.0f + d - d * IzAzBz.x), 0.f);
437 // IzAzBz -> L'M'S'
438 LMS.x = dot(AI[0], IzAzBz);
439 LMS.y = dot(AI[1], IzAzBz);
440 LMS.z = dot(AI[2], IzAzBz);
441 LMS.w = 0.f;
442 // L'M'S' -> LMS
443 LMS = native_powr(fmax(LMS, 0.0f), p_inv);
444 LMS = 10000.f * native_powr(fmax((c1 - LMS) / (c3 * LMS - c2), 0.0f), n_inv);
445 // LMS -> X'Y'Z
446 XYZ.x = dot(MI[0], LMS);
447 XYZ.y = dot(MI[1], LMS);
448 XYZ.z = dot(MI[2], LMS);
449 XYZ.w = 0.f;
450 // X'Y'Z -> XYZ_D65
451 float4 XYZ_D65;
452 XYZ_D65.x = (XYZ.x + (b - 1.0f) * XYZ.z) / b;
453 XYZ_D65.y = (XYZ.y + (g - 1.0f) * XYZ_D65.x) / g;
454 XYZ_D65.z = XYZ.z;
455 XYZ_D65.w = JzAzBz.w;
456 return XYZ_D65;
457}
458
459
460static inline float4 JzAzBz_to_JzCzhz(float4 JzAzBz)
461{
462 const float h = atan2(JzAzBz.z, JzAzBz.y) / (2.0f * M_PI_F);
463 float4 JzCzhz;
464 JzCzhz.x = JzAzBz.x;
465 JzCzhz.y = native_sqrt(JzAzBz.y * JzAzBz.y + JzAzBz.z * JzAzBz.z);
466 JzCzhz.z = (h >= 0.0f) ? h : 1.0f + h;
467 JzCzhz.w = JzAzBz.w;
468 return JzCzhz;
469}
470
471
472// Convert CIE 1931 2° XYZ D65 to CIE 2006 LMS D65 (cone space)
473/*
474* The CIE 1931 XYZ 2° observer D65 is converted to CIE 2006 LMS D65 using the approximation by
475* Richard A. Kirk, Chromaticity coordinates for graphic arts based on CIE 2006 LMS
476* with even spacing of Munsell colours
477* https://doi.org/10.2352/issn.2169-2629.2019.27.38
478*/
479
480static inline float4 XYZ_to_LMS(const float4 XYZ)
481{
482 const float4 XYZ_D65_to_LMS_2006_D65[3]
483 = { { 0.257085f, 0.859943f, -0.031061f, 0.f },
484 { -0.394427f, 1.175800f, 0.106423f, 0.f },
485 { 0.064856f, -0.076250f, 0.559067f, 0.f } };
486
488}
489
490
491static inline float4 LMS_to_XYZ(const float4 LMS)
492{
493 const float4 LMS_2006_D65_to_XYZ_D65[3]
494 = { { 1.80794659f, -1.29971660f, 0.34785879f, 0.f },
495 { 0.61783960f, 0.39595453f, -0.04104687f, 0.f },
496 { -0.12546960f, 0.20478038f, 1.74274183f, 0.f } };
497
499}
500
501
502/*
503* Convert from CIE 2006 LMS D65 to Filmlight RGB defined in
504* Richard A. Kirk, Chromaticity coordinates for graphic arts based on CIE 2006 LMS
505* with even spacing of Munsell colours
506* https://doi.org/10.2352/issn.2169-2629.2019.27.38
507*/
508
509static inline float4 gradingRGB_to_LMS(const float4 RGB)
510{
511 const float4 filmlightRGB_D65_to_LMS_D65[3]
512 = { { 0.95f, 0.38f, 0.00f, 0.f },
513 { 0.05f, 0.62f, 0.03f, 0.f },
514 { 0.00f, 0.00f, 0.97f, 0.f } };
515
517}
518
519static inline float4 LMS_to_gradingRGB(const float4 LMS)
520{
521 const float4 LMS_D65_to_filmlightRGB_D65[3]
522 = { { 1.0877193f, -0.66666667f, 0.02061856f, 0.f },
523 { -0.0877193f, 1.66666667f, -0.05154639f, 0.f },
524 { 0.f, 0.f, 1.03092784f, 0.f } };
525
527}
528
529
530/*
531* Re-express the Filmlight RGB triplet as Yrg luminance/chromacity coordinates
532*/
533
534static inline float4 LMS_to_Yrg(const float4 LMS)
535{
536 // compute luminance
537 const float Y = 0.68990272f * LMS.x + 0.34832189f * LMS.y;
538
539 // normalize LMS
540 const float a = LMS.x + LMS.y + LMS.z;
541 const float4 lms = (a == 0.f) ? 0.f : LMS / a;
542
543 // convert to Filmlight rgb (normalized)
544 const float4 rgb = LMS_to_gradingRGB(lms);
545
546 return (float4)(Y, rgb.x, rgb.y, LMS.w);
547}
548
549
550static inline float4 Yrg_to_LMS(const float4 Yrg)
551{
552 const float Y = Yrg.x;
553
554 // reform rgb (normalized) from chroma
555 const float r = Yrg.y;
556 const float g = Yrg.z;
557 const float b = 1.f - r - g;
558 const float4 rgb = { r, g, b, 0.f };
559
560 // convert to lms (normalized)
561 const float4 lms = gradingRGB_to_LMS(rgb);
562
563 // denormalize to LMS
564 const float denom = (0.68990272f * lms.x + 0.34832189f * lms.y);
565 const float a = (denom == 0.f) ? 0.f : Y / denom;
566 return lms * a;
567}
568
569
570/*
571* Re-express Filmlight Yrg in polar coordinates Ych
572*/
573
574static inline float4 Yrg_to_Ych(const float4 Yrg)
575{
576 const float Y = Yrg.x;
577 // Subtract white point. These are the r, g coordinates of
578 // sRGB (D50 adapted) (1, 1, 1) taken through
579 // XYZ D50 -> CAT16 D50->D65 adaptation -> LMS 2006
580 // -> grading RGB conversion.
581 const float r = Yrg.y - 0.21902143f;
582 const float g = Yrg.z - 0.54371398f;
583 const float c = hypot(g, r);
584 const float h = atan2(g, r);
585 return (float4)(Y, c, h, Yrg.w);
586}
587
588
589static inline float4 Ych_to_Yrg(const float4 Ych)
590{
591 const float Y = Ych.x;
592 const float c = Ych.y;
593 const float h = Ych.z;
594 const float r = c * native_cos(h) + 0.21902143f;
595 const float g = c * native_sin(h) + 0.54371398f;
596 return (float4)(Y, r, g, Ych.w);
597}
598
599
600static inline float4 dt_xyY_to_uvY(const float4 xyY)
601{
602 // This is the linear part of the chromaticity transform from CIE L*u*v* e.g. u'v'.
603 // See https://en.wikipedia.org/wiki/CIELUV
604 // It rescales the chromaticity diagram xyY in a more perceptual way,
605 // but it is still not hue-linear and not perfectly perceptual.
606 // As such, it is the only radiometricly-accurate representation of hue non-linearity in human vision system.
607 // Use it for "hue preserving" (as much as possible) gamut mapping in scene-referred space
608 const float denominator = -2.f * xyY.x + 12.f * xyY.y + 3.f;
609 float4 uvY;
610 uvY.x = 4.f * xyY.x / denominator; // u'
611 uvY.y = 9.f * xyY.y / denominator; // v'
612 uvY.z = xyY.z; // Y
613 uvY.w = xyY.w;
614 return uvY;
615}
616
617
618static inline float4 dt_uvY_to_xyY(const float4 uvY)
619{
620 // This is the linear part of chromaticity transform from CIE L*u*v* e.g. u'v'.
621 // See https://en.wikipedia.org/wiki/CIELUV
622 // It rescales the chromaticity diagram xyY in a more perceptual way,
623 // but it is still not hue-linear and not perfectly perceptual.
624 // As such, it is the only radiometricly-accurate representation of hue non-linearity in human vision system.
625 // Use it for "hue preserving" (as much as possible) gamut mapping in scene-referred space
626 const float denominator = 6.0f * uvY.x - 16.f * uvY.y + 12.0f;
627 float4 xyY;
628 xyY.x = 9.f * uvY.x / denominator; // x
629 xyY.y = 4.f * uvY.y / denominator; // y
630 xyY.z = uvY.z; // Y
631 xyY.w = uvY.w;
632 return xyY;
633}
634
635static inline float4 dt_XYZ_to_xyY(const float4 XYZ)
636{
637 float4 xyY;
638 const float sum = XYZ.x + XYZ.y + XYZ.z;
639 xyY.xy = XYZ.xy / sum;
640 xyY.z = XYZ.y;
641 xyY.w = XYZ.w;
642 return xyY;
643}
644
645static inline float4 dt_xyY_to_XYZ(const float4 xyY)
646{
647 float4 XYZ;
648 XYZ.x = xyY.z * xyY.x / xyY.y;
649 XYZ.y = xyY.z;
650 XYZ.z = xyY.z * (1.f - xyY.x - xyY.y) / xyY.y;
651 XYZ.w = xyY.w;
652 return XYZ;
653}
654
655// port src/common/chromatic_adaptation.h
656
657static inline float4 convert_XYZ_to_bradford_LMS(const float4 XYZ)
658{
659 // Warning : needs XYZ normalized with Y - you need to downscale before
660 const float4 XYZ_to_Bradford_LMS[3] = { { 0.8951f, 0.2664f, -0.1614f, 0.f },
661 { -0.7502f, 1.7135f, 0.0367f, 0.f },
662 { 0.0389f, -0.0685f, 1.0296f, 0.f } };
663
665}
666
667static inline float4 convert_bradford_LMS_to_XYZ(const float4 LMS)
668{
669 // Warning : output XYZ normalized with Y - you need to upscale later
670 const float4 Bradford_LMS_to_XYZ[3] = { { 0.9870f, -0.1471f, 0.1600f, 0.f },
671 { 0.4323f, 0.5184f, 0.0493f, 0.f },
672 { -0.0085f, 0.0400f, 0.9685f, 0.f } };
673
675}
676
677static inline float4 convert_XYZ_to_CAT16_LMS(const float4 XYZ)
678{
679 // Warning : needs XYZ normalized with Y - you need to downscale before
680 const float4 XYZ_to_CAT16_LMS[3] = { { 0.401288f, 0.650173f, -0.051461f, 0.f },
681 { -0.250268f, 1.204414f, 0.045854f, 0.f },
682 { -0.002079f, 0.048952f, 0.953127f, 0.f } };
683
685}
686
687static inline float4 convert_CAT16_LMS_to_XYZ(const float4 LMS)
688{
689 // Warning : output XYZ normalized with Y - you need to upscale later
690 const float4 CAT16_LMS_to_XYZ[3] = { { 1.862068f, -1.011255f, 0.149187f, 0.f },
691 { 0.38752f , 0.621447f, -0.008974f, 0.f },
692 { -0.015841f, -0.034123f, 1.049964f, 0.f } };
693
695}
696
697static inline void bradford_adapt_D50(float4 *lms_in,
698 const float4 origin_illuminant,
699 const float p, const int full)
700{
701 // Bradford chromatic adaptation from origin to target D50 illuminant in LMS space
702 // p = powf(origin_illuminant[2] / D50[2], 0.0834f) needs to be precomputed for performance,
703 // since it is independent from current pixel values
704 // origin illuminant need also to be precomputed to LMS
705
706 // Precomputed D50 primaries in Bradford LMS for ICC transforms
707 const float4 D50 = { 0.996078f, 1.020646f, 0.818155f, 0.f };
708
709 if(full)
710 {
711 float4 temp = *lms_in / origin_illuminant;
712
713 // use linear Bradford if B is negative
714 temp.z = (temp.z > 0.f) ? native_powr(temp.z, p) : temp.z;
715
716 *lms_in = D50 * temp;
717 }
718 else
719 *lms_in *= D50 / origin_illuminant;
720}
721
722static inline void CAT16_adapt_D50(float4 *lms_in,
723 const float4 origin_illuminant,
724 const float D, const int full)
725{
726 // CAT16 chromatic adaptation from origin to target D50 illuminant in LMS space
727 // D is the coefficient of adaptation, depending of the surround lighting
728 // origin illuminant need also to be precomputed to LMS
729
730 // Precomputed D50 primaries in CAT16 LMS for ICC transforms
731 const float4 D50 = { 0.994535f, 1.000997f, 0.833036f, 0.f };
732
733 if(full) *lms_in *= D50 / origin_illuminant;
734 else *lms_in *= (D * D50 / origin_illuminant + 1.f - D);
735}
736
737static inline void XYZ_adapt_D50(float4 *lms_in,
738 const float4 origin_illuminant)
739{
740 // XYZ chromatic adaptation from origin to target D65 illuminant in XYZ space
741 // origin illuminant need also to be precomputed to XYZ
742
743 // Precomputed D50 primaries in XYZ for camera WB adjustment
744 const float4 D50 = { 0.9642119944211994f, 1.0f, 0.8251882845188288f, 0.f };
745 *lms_in *= D50 / origin_illuminant;
746}
747
748static inline float4 gamut_check_Yrg(float4 Ych)
749{
750 // Do a test conversion to Yrg
751 float4 Yrg = Ych_to_Yrg(Ych);
752
753 // Gamut-clip in Yrg at constant hue and luminance
754 // e.g. find the max chroma value that fits in gamut at the current hue
755 const float D65_r = 0.21902143f;
756 const float D65_g = 0.54371398f;
757 float max_c = Ych.y;
758 const float cos_h = native_cos(Ych.z);
759 const float sin_h = native_sin(Ych.z);
760
761 if(Yrg.y < 0.f)
762 {
763 max_c = fmin(-D65_r / cos_h, max_c);
764 }
765 if(Yrg.z < 0.f)
766 {
767 max_c = fmin(-D65_g / sin_h, max_c);
768 }
769 if(Yrg.y + Yrg.z > 1.f)
770 {
771 max_c = fmin((1.f - D65_r - D65_g) / (cos_h + sin_h), max_c);
772 }
773
774 // Overwrite chroma with the sanitized value and
775 Ych.y = max_c;
776
777 return Ych;
778}
779
780
789static inline float Y_to_dt_UCS_L_star(const float Y)
790{
791 // WARNING: L_star needs to be < 2.098883786377, meaning Y needs to be < 3.875766378407574e+19
792 const float Y_hat = native_powr(Y, 0.631651345306265f);
793 return 2.098883786377f * Y_hat / (Y_hat + 1.12426773749357f);
794}
795
796static inline float dt_UCS_L_star_to_Y(const float L_star)
797{
798 // WARNING: L_star needs to be < 2.098883786377, meaning Y needs to be < 3.875766378407574e+19
799 return native_powr((1.12426773749357f * L_star / (2.098883786377f - L_star)), 1.5831518565279648f);
800}
801
802static inline void xyY_to_dt_UCS_UV(const float4 xyY, float UV_star_prime[2])
803{
804 float4 x_factors = { -0.783941002840055f, 0.745273540913283f, 0.318707282433486f, 0.f };
805 float4 y_factors = { 0.277512987809202f, -0.205375866083878f, 2.16743692732158f, 0.f };
806 float4 offsets = { 0.153836578598858f, -0.165478376301988f, 0.291320554395942f, 0.f };
807
808 float4 UVD = x_factors * xyY.x + y_factors * xyY.y + offsets;
809 UVD.xy /= UVD.z;
810
811 float UV_star[2] = { 0.f };
812 const float factors[2] = { 1.39656225667f, 1.4513954287f };
813 const float half_values[2] = { 1.49217352929f, 1.52488637914f };
814 for(int c = 0; c < 2; c++)
815 UV_star[c] = factors[c] * ((float *)&UVD)[c] / (fabs(((float *)&UVD)[c]) + half_values[c]);
816
817 // The following is equivalent to a 2D matrix product
818 UV_star_prime[0] = -1.124983854323892f * UV_star[0] - 0.980483721769325f * UV_star[1];
819 UV_star_prime[1] = 1.86323315098672f * UV_star[0] + 1.971853092390862f * UV_star[1];
820}
821
822
823static inline float4 xyY_to_dt_UCS_JCH(const float4 xyY, const float L_white)
824{
825 /*
826 input :
827 * xyY in normalized CIE XYZ for the 2° 1931 observer adapted for D65
828 * L_white the lightness of white as dt UCS L* lightness
829 * cz = 1 for standard pre-print proofing conditions with average surround and n = 20 %
830 (background = middle grey, white = perfect diffuse white)
831 range : xy in [0; 1], Y normalized for perfect diffuse white = 1
832 */
833
834 float UV_star_prime[2];
836
837 const float L_star = Y_to_dt_UCS_L_star(xyY.z);
838 const float M2 = UV_star_prime[0] * UV_star_prime[0] + UV_star_prime[1] * UV_star_prime[1]; // square of colorfulness M
839
840 // should be JCH[0] = powf(L_star / L_white), cz) but we treat only the case where cz = 1
841 float4 JCH;
842 JCH.x = L_star / L_white;
843 JCH.y = 15.932993652962535f * native_powr(L_star, 0.6523997524738018f) * native_powr(M2, 0.6007557017508491f) / L_white;
844 JCH.z = atan2(UV_star_prime[1], UV_star_prime[0]);
845 return JCH;
846
847}
848
849static inline float4 dt_UCS_JCH_to_xyY(const float4 JCH, const float L_white)
850{
851 /*
852 input :
853 * xyY in normalized CIE XYZ for the 2° 1931 observer adapted for D65
854 * L_white the lightness of white as dt UCS L* lightness
855 * cz = 1 for standard pre-print proofing conditions with average surround and n = 20 %
856 (background = middle grey, white = perfect diffuse white)
857 range : xy in [0; 1], Y normalized for perfect diffuse white = 1
858 */
859
860 // should be L_star = powf(JCH[0], 1.f / cz) * L_white but we treat only the case where cz = 1
861 const float L_star = JCH.x * L_white;
862 const float M = native_powr(JCH.y * L_white / (15.932993652962535f * native_powr(L_star, 0.6523997524738018f)), 0.8322850678616855f);
863
864 const float U_star_prime = M * native_cos(JCH.z);
865 const float V_star_prime = M * native_sin(JCH.z);
866
867 // The following is equivalent to a 2D matrix product
868 const float UV_star[2] = { -5.037522385190711f * U_star_prime - 2.504856328185843f * V_star_prime,
869 4.760029407436461f * U_star_prime + 2.874012963239247f * V_star_prime };
870
871 float UV[2] = {0.f};
872 const float factors[2] = { 1.39656225667f, 1.4513954287f };
873 const float half_values[2] = { 1.49217352929f,1.52488637914f };
874 for(int c = 0; c < 2; c++)
875 UV[c] = -half_values[c] * UV_star[c] / (fabs(UV_star[c]) - factors[c]);
876
877 const float4 U_factors = { 0.167171472114775f, -0.150959086409163f, 0.940254742367256f, 0.f };
878 const float4 V_factors = { 0.141299802443708f, -0.155185060382272f, 1.000000000000000f, 0.f };
879 const float4 offsets = { -0.00801531300850582f, -0.00843312433578007f, -0.0256325967652889f, 0.f };
880
881 float4 xyD = U_factors * UV[0] + V_factors * UV[1] + offsets;
882
883 float4 xyY;
884 xyY.x = xyD.x / xyD.z;
885 xyY.y = xyD.y / xyD.z;
887 return xyY;
888}
889
890
891static inline float4 dt_UCS_JCH_to_HSB(const float4 JCH)
892{
893 float4 HSB;
894 HSB.z = JCH.x * (native_powr(JCH.y, 1.33654221029386f) + 1.f);
895 HSB.y = (HSB.z > 0.f) ? JCH.y / HSB.z : 0.f;
896 HSB.x = JCH.z;
897 return HSB;
898}
899
900
901static inline float4 dt_UCS_HSB_to_JCH(const float4 HSB)
902{
903 float4 JCH;
904 JCH.z = HSB.x;
905 JCH.y = HSB.y * HSB.z;
906 JCH.x = HSB.z / (native_powr(JCH.y, 1.33654221029386f) + 1.f);
907 return JCH;
908}
909
910
911static inline float4 dt_UCS_JCH_to_HCB(const float4 JCH)
912{
913 float4 HCB;
914 HCB.z = JCH.x * (native_powr(JCH.y, 1.33654221029386f) + 1.f);
915 HCB.y = JCH.y;
916 HCB.x = JCH.z;
917 return HCB;
918}
919
920
921static inline float4 dt_UCS_HCB_to_JCH(const float4 HCB)
922{
923 float4 JCH;
924 JCH.z = HCB.x;
925 JCH.y = HCB.y;
926 JCH.x = HCB.z / (native_powr(HCB.y, 1.33654221029386f) + 1.f);
927 return JCH;
928}
const dt_colormatrix_t CAT16_LMS_to_XYZ
Definition chromatic_adaptation.h:89
const dt_colormatrix_t XYZ_to_CAT16_LMS
Definition chromatic_adaptation.h:85
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
Definition chromatic_adaptation.h:315
const dt_colormatrix_t XYZ_to_Bradford_LMS
Definition chromatic_adaptation.h:45
const dt_colormatrix_t Bradford_LMS_to_XYZ
Definition chromatic_adaptation.h:49
static float4 dt_UCS_JCH_to_HCB(const float4 JCH)
Definition colorspace.h:911
static float4 RGB_2_HSV(const float4 RGB)
Definition colorspace.h:271
static float4 LCH_2_Lab(float4 LCH)
Definition colorspace.h:86
static float4 XYZ_to_JzAzBz(float4 XYZ_D65)
Definition colorspace.h:380
static float4 dt_xyY_to_XYZ(const float4 xyY)
Definition colorspace.h:645
static float4 Lab_to_prophotorgb(float4 Lab)
Definition colorspace.h:175
static float4 prophotorgb_to_Lab(float4 rgb)
Definition colorspace.h:181
static float4 dt_UCS_HSB_to_JCH(const float4 HSB)
Definition colorspace.h:901
static void CAT16_adapt_D50(float4 *lms_in, const float4 origin_illuminant, const float D, const int full)
Definition colorspace.h:722
static float4 gradingRGB_to_LMS(const float4 RGB)
Definition colorspace.h:509
static void xyY_to_dt_UCS_UV(const float4 xyY, float UV_star_prime[2])
Definition colorspace.h:802
static float4 XYZ_to_sRGB(float4 XYZ)
Definition colorspace.h:353
static float4 gamut_check_Yrg(float4 Ych)
Definition colorspace.h:748
static float4 dt_xyY_to_uvY(const float4 xyY)
Definition colorspace.h:600
static float4 XYZ_to_Lab(float4 xyz)
Definition colorspace.h:104
static float4 matrix_product_float4(const float4 xyz, constant const float *const matrix)
Definition colorspace.h:64
static float4 JzAzBz_2_XYZ(const float4 JzAzBz)
Definition colorspace.h:414
static float4 HSL_2_RGB(const float4 HSL)
Definition colorspace.h:241
static float3 matrix_dot_float4(const constant float4 *const matrix, const float3 xyz)
Definition colorspace.h:58
static float4 LMS_to_XYZ(const float4 LMS)
Definition colorspace.h:491
static float4 prophotorgb_to_XYZ(float4 rgb)
Definition colorspace.h:135
static float4 Lab_2_LCH(float4 Lab)
Definition colorspace.h:73
static float4 convert_XYZ_to_bradford_LMS(const float4 XYZ)
Definition colorspace.h:657
static float4 JzAzBz_to_JzCzhz(float4 JzAzBz)
Definition colorspace.h:460
static float4 matrix_product(const float4 xyz, constant const float *const matrix)
Definition colorspace.h:43
static float4 Yrg_to_Ych(const float4 Yrg)
Definition colorspace.h:574
static float4 Ych_to_Yrg(const float4 Ych)
Definition colorspace.h:589
static float Hue_2_RGB(float v1, float v2, float vH)
Definition colorspace.h:229
static float4 dt_uvY_to_xyY(const float4 uvY)
Definition colorspace.h:618
static float4 convert_XYZ_to_CAT16_LMS(const float4 XYZ)
Definition colorspace.h:677
static void bradford_adapt_D50(float4 *lms_in, const float4 origin_illuminant, const float p, const int full)
Definition colorspace.h:697
static float4 lab_f(float4 x)
Definition colorspace.h:96
static float4 LMS_to_gradingRGB(const float4 LMS)
Definition colorspace.h:519
static void XYZ_adapt_D50(float4 *lms_in, const float4 origin_illuminant)
Definition colorspace.h:737
static float4 RGB_2_HSL(const float4 RGB)
Definition colorspace.h:187
static float4 dt_UCS_JCH_to_HSB(const float4 JCH)
Definition colorspace.h:891
static float4 matrix_dot(const float4 vector, const float4 matrix[3])
Definition colorspace.h:31
static float dt_UCS_L_star_to_Y(const float L_star)
Definition colorspace.h:796
static float4 dt_UCS_JCH_to_xyY(const float4 JCH, const float L_white)
Definition colorspace.h:849
static float4 HSV_2_RGB(const float4 HSV)
Definition colorspace.h:308
static float4 Yrg_to_LMS(const float4 Yrg)
Definition colorspace.h:550
static float4 LMS_to_Yrg(const float4 LMS)
Definition colorspace.h:534
static float3 matrix_dot_float4_rows(const float4 row0, const float4 row1, const float4 row2, const float3 xyz)
Definition colorspace.h:52
static float Y_to_dt_UCS_L_star(const float Y)
Definition colorspace.h:789
static float4 lab_f_inv(float4 x)
Definition colorspace.h:117
static float4 xyY_to_dt_UCS_JCH(const float4 xyY, const float L_white)
Definition colorspace.h:823
static float4 dt_XYZ_to_xyY(const float4 XYZ)
Definition colorspace.h:635
static float4 convert_CAT16_LMS_to_XYZ(const float4 LMS)
Definition colorspace.h:687
static float4 Lab_to_XYZ(float4 Lab)
Definition colorspace.h:125
static float4 XYZ_to_prophotorgb(float4 XYZ)
Definition colorspace.h:155
static float4 convert_bradford_LMS_to_XYZ(const float4 LMS)
Definition colorspace.h:667
static float4 XYZ_to_LMS(const float4 XYZ)
Definition colorspace.h:480
static float4 dt_UCS_HCB_to_JCH(const float4 HCB)
Definition colorspace.h:921
static float4 sRGB_to_XYZ(float4 sRGB)
Definition colorspace.h:367
#define B(y, x)
Definition colorspaces.c:187
#define A(y, x)
Definition colorspaces.c:186
dt_aligned_pixel_t LMS
Definition colorspaces_inline_conversions.h:952
static dt_aligned_pixel_t Ych
Definition colorspaces_inline_conversions.h:1357
const float U_star_prime
Definition colorspaces_inline_conversions.h:1645
dt_aligned_pixel_t UVD
Definition colorspaces_inline_conversions.h:1571
static float UV_star_prime[2]
Definition colorspaces_inline_conversions.h:1565
static const float L_white
Definition colorspaces_inline_conversions.h:1594
const float i
Definition colorspaces_inline_conversions.h:669
float UV_star[2]
Definition colorspaces_inline_conversions.h:1578
dt_aligned_pixel_t lms
Definition colorspaces_inline_conversions.h:1293
static dt_aligned_pixel_t HSV
Definition colorspaces_inline_conversions.h:767
static dt_aligned_pixel_t xyY
Definition colorspaces_inline_conversions.h:266
const float L_star
Definition colorspaces_inline_conversions.h:1608
const float factors[2]
Definition colorspaces_inline_conversions.h:1579
const float h
Definition colorspaces_inline_conversions.h:1366
const float c
Definition colorspaces_inline_conversions.h:1365
const float L
Definition colorspaces_inline_conversions.h:724
const dt_aligned_pixel_t V_factors
Definition colorspaces_inline_conversions.h:1659
const float g
Definition colorspaces_inline_conversions.h:925
float UV[2]
Definition colorspaces_inline_conversions.h:1652
const float denom
Definition colorspaces_inline_conversions.h:1334
const dt_aligned_pixel_t f
Definition colorspaces_inline_conversions.h:256
static dt_aligned_pixel_t LCH
Definition colorspaces_inline_conversions.h:835
const dt_aligned_pixel_t offsets
Definition colorspaces_inline_conversions.h:1569
static dt_aligned_pixel_t uvY
Definition colorspaces_inline_conversions.h:303
static dt_aligned_pixel_t Yrg
Definition colorspaces_inline_conversions.h:1287
const float half_values[2]
Definition colorspaces_inline_conversions.h:1580
static const dt_aligned_pixel_t d50
Definition colorspaces_inline_conversions.h:222
static dt_aligned_pixel_t HSL
Definition colorspaces_inline_conversions.h:719
static const dt_colormatrix_t filmlightRGB_D65_to_LMS_D65
Definition colorspaces_inline_conversions.h:1227
static const float dt_aligned_pixel_t JCH
Definition colorspaces_inline_conversions.h:1595
const float d0
Definition colorspaces_inline_conversions.h:932
const float d
Definition colorspaces_inline_conversions.h:931
static dt_aligned_pixel_t HSB
Definition colorspaces_inline_conversions.h:1682
static const dt_colormatrix_t M
Definition colorspaces_inline_conversions.h:933
const float n_inv
Definition colorspaces_inline_conversions.h:1057
const dt_colormatrix_t MI
Definition colorspaces_inline_conversions.h:1061
static const dt_colormatrix_t LMS_D65_to_filmlightRGB_D65
Definition colorspaces_inline_conversions.h:1232
static dt_aligned_pixel_t sRGB
Definition colorspaces_inline_conversions.h:430
dt_aligned_pixel_t xyD
Definition colorspaces_inline_conversions.h:1662
const float r
Definition colorspaces_inline_conversions.h:1324
dt_aligned_pixel_t IzAzBz
Definition colorspaces_inline_conversions.h:1074
static dt_aligned_pixel_t XYZ_D65
Definition colorspaces_inline_conversions.h:869
const float b
Definition colorspaces_inline_conversions.h:1326
static dt_aligned_pixel_t Lab
Definition colorspaces_inline_conversions.h:228
static dt_aligned_pixel_t HCB
Definition colorspaces_inline_conversions.h:1717
const float a
Definition colorspaces_inline_conversions.h:1292
const float p_inv
Definition colorspaces_inline_conversions.h:1058
const dt_colormatrix_t AI
Definition colorspaces_inline_conversions.h:1066
const dt_aligned_pixel_t y_factors
Definition colorspaces_inline_conversions.h:1568
static const dt_colormatrix_t dt_aligned_pixel_t out
Definition colorspaces_inline_conversions.h:184
const float c3
Definition colorspaces_inline_conversions.h:928
static const dt_colormatrix_t XYZ_D65_to_LMS_2006_D65
Definition colorspaces_inline_conversions.h:1165
const float M2
Definition colorspaces_inline_conversions.h:1609
static const dt_colormatrix_t LMS_2006_D65_to_XYZ_D65
Definition colorspaces_inline_conversions.h:1170
static dt_aligned_pixel_t XYZ
Definition colorspaces_inline_conversions.h:252
static dt_aligned_pixel_t JzCzhz
Definition colorspaces_inline_conversions.h:1030
static const float const float C
Definition colorspaces_inline_conversions.h:666
static dt_aligned_pixel_t JzAzBz
Definition colorspaces_inline_conversions.h:923
static dt_aligned_pixel_t rgb
Definition colorspaces_inline_conversions.h:530
const float V_star_prime
Definition colorspaces_inline_conversions.h:1646
static dt_aligned_pixel_t RGB
Definition colorspaces_inline_conversions.h:509
static const dt_colormatrix_t matrix
Definition colorspaces_inline_conversions.h:182
const float delta
Definition colorspaces_inline_conversions.h:722
const dt_aligned_pixel_t U_factors
Definition colorspaces_inline_conversions.h:1658
#define S(V, params)
Definition common/histogram.c:39
static const dt_aligned_pixel_simd_t const dt_aligned_pixel_simd_t row1
Definition darktable.h:547
static const dt_aligned_pixel_simd_t const dt_aligned_pixel_simd_t const dt_aligned_pixel_simd_t row2
Definition darktable.h:548
static const dt_aligned_pixel_simd_t row0
Definition darktable.h:546
#define M_PI_F
Definition data/kernels/common.h:36
#define H
Definition diffuse.c:624
static double dot(int g[], double x, double y, double z)
Definition grain.c:179
static const float x
Definition iop_profile.h:239
const int t
Definition iop_profile.h:227
static const float v
Definition iop_profile.h:223
#define R
#define c2
Definition colorspaces_inline_conversions.h:1055
#define c1
Definition colorspaces_inline_conversions.h:1054