16 if (c <= 0.04045f)
return c / 12.92f;
17 return std::pow((c + 0.055f) / 1.055f, 2.4f);
22 if (c <= 0.0031308f)
return c * 12.92f;
23 return 1.055f * std::pow(c, 1.0f / 2.4f) - 0.055f;
28 inline void RGBtoHSV(
float r,
float g,
float b,
float& h,
float& s,
float& v)
30 if (!std::isfinite(r)) r = 0.0f;
31 if (!std::isfinite(g)) g = 0.0f;
32 if (!std::isfinite(b)) b = 0.0f;
34 r = std::max(r, 0.0f);
35 g = std::max(g, 0.0f);
36 b = std::max(b, 0.0f);
38 float maxc = std::max(r, std::max(g, b));
39 float minc = std::min(r, std::min(g, b));
41 float d = maxc - minc;
43 s = (maxc == 0.0f) ? 0.0f : d / maxc;
44 if (d == 0.0f) { h = 0.0f;
return; }
49 if (maxc == r) h = (g - b) / d + (g < b ? 6.0f : 0.0f);
50 else if (maxc == g) h = (b - r) / d + 2.0f;
51 else h = (r - g) / d + 4.0f;
55 inline std::array<float, 3>
HSVtoRGB(
float h,
float s,
float v)
57 if (!std::isfinite(h)) h = 0.0f;
58 if (!std::isfinite(s)) s = 0.0f;
59 if (!std::isfinite(v)) v = 0.0f;
61 h = std::max(h, 0.0f);
62 s = std::max(s, 0.0f);
63 v = std::max(v, 0.0f);
65 if (s == 0.0f)
return { v, v, v };
68 int i =
static_cast<int>(std::floor(h)) % 6;
69 float f = h - std::floor(h);
70 float p = v * (1.0f - s);
71 float q = v * (1.0f - s * f);
72 float t = v * (1.0f - s * (1.0f - f));
75 case 0:
return { v, t, p };
76 case 1:
return { q, v, p };
77 case 2:
return { p, v, t };
78 case 3:
return { p, q, v };
79 case 4:
return { t, p, v };
80 case 5:
default:
return { v, p, q };
86 inline void RGBtoHSL(
float r,
float g,
float b,
float& h,
float& s,
float& l)
88 if (!std::isfinite(r)) r = 0.0f;
89 if (!std::isfinite(g)) g = 0.0f;
90 if (!std::isfinite(b)) b = 0.0f;
92 r = std::max(r, 0.0f);
93 g = std::max(g, 0.0f);
94 b = std::max(b, 0.0f);
96 float maxc = std::max(r, std::max(g, b));
97 float minc = std::min(r, std::min(g, b));
99 l = 0.5f * (maxc + minc);
100 if (maxc == minc) { h = 0.0f; s = 0.0f;
return; }
102 float d = maxc - minc;
103 s = (l > 0.5f) ? (d / (2.0f - maxc - minc)) : (d / (maxc + minc));
108 if (maxc == r) h = (g - b) / d + (g < b ? 6.0f : 0.0f);
109 else if (maxc == g) h = (b - r) / d + 2.0f;
110 else h = (r - g) / d + 4.0f;
114 inline std::array<float, 3>
HSLtoRGB(
float h,
float s,
float l)
116 if (!std::isfinite(h)) h = 0.0f;
117 if (!std::isfinite(s)) s = 0.0f;
118 if (!std::isfinite(l)) l = 0.0f;
120 h = std::max(h, 0.0f);
121 s = std::max(s, 0.0f);
122 l = std::max(l, 0.0f);
124 if (s == 0.0f)
return { l, l, l };
126 auto hue2rgb = [](
float p,
float q,
float t) ->
float
128 if (t < 0.0f) t += 1.0f;
129 if (t > 1.0f) t -= 1.0f;
130 if (t < 1.0f / 6.0f)
return p + (q - p) * 6.0f * t;
131 if (t < 1.0f / 2.0f)
return q;
132 if (t < 2.0f / 3.0f)
return p + (q - p) * (2.0f / 3.0f - t) * 6.0f;
135 float q = (l < 0.5f) ? (l * (1.0f + s)) : (l + s - l * s);
136 float p = 2.0f * l - q;
137 return { hue2rgb(p, q, h + 1.0f / 3.0f), hue2rgb(p, q, h), hue2rgb(p, q, h - 1.0f / 3.0f) };
149 inline std::array<float, 3>
RGBtoXYZ(
float r,
float g,
float b)
153 R * 0.4124564f + G * 0.3575761f + B * 0.1804375f,
154 R * 0.2126729f + G * 0.7151522f + B * 0.0721750f,
155 R * 0.0193339f + G * 0.1191920f + B * 0.9503041f
159 inline std::array<float, 3>
XYZtoRGB(
float X,
float Y,
float Z)
161 float R = 3.2404542f *
X - 1.5371385f *
Y - 0.4985314f * Z;
162 float G = -0.9692660f *
X + 1.8760108f *
Y + 0.0415560f * Z;
163 float B = 0.0556434f *
X - 0.2040259f *
Y + 1.0572252f * Z;
164 return { std::clamp(R, 0.0f, 1.0f), std::clamp(G, 0.0f, 1.0f), std::clamp(B, 0.0f, 1.0f) };
168 inline void RGBtoLab(
float r,
float g,
float b,
float& L,
float& a,
float& bOut)
170 if (!std::isfinite(r)) r = 0.0f;
171 if (!std::isfinite(g)) g = 0.0f;
172 if (!std::isfinite(b)) b = 0.0f;
174 r = std::max(r, 0.0f);
175 g = std::max(g, 0.0f);
176 b = std::max(b, 0.0f);
179 auto f = [](
float t) {
187 L = 116.0f * fy - 16.0f;
188 a = 500.0f * (fx - fy);
189 bOut = 200.0f * (fy - fz);
192 inline std::array<float, 3>
LabToRGB(
float L,
float a,
float b)
194 if (!std::isfinite(L)) L = 0.0f;
195 if (!std::isfinite(a)) a = 0.0f;
196 if (!std::isfinite(b)) b = 0.0f;
200 L = std::max(L, 0.0f);
202 auto finv = [](
float t) {
206 float fy = (L + 16.0f) / 116.0f;
207 float fx = fy + a / 500.0f;
208 float fz = fy - b / 200.0f;
220 inline void RGBtoOklab(
float r,
float g,
float b,
float& L,
float& a,
float& bOut)
222 if (!std::isfinite(r)) r = 0.0f;
223 if (!std::isfinite(g)) g = 0.0f;
224 if (!std::isfinite(b)) b = 0.0f;
226 r = std::max(r, 0.0f);
227 g = std::max(g, 0.0f);
228 b = std::max(b, 0.0f);
231 float l = 0.4122214708f * R + 0.5363325363f * G + 0.0514459929f * B;
232 float m = 0.2119034982f * R + 0.6806995451f * G + 0.1073969566f * B;
233 float s = 0.0883024619f * R + 0.2817188376f * G + 0.6299787005f * B;
234 float l_ = std::cbrt(l), m_ = std::cbrt(m), s_ = std::cbrt(s);
235 L = 0.2104542553f * l_ + 0.7936177850f * m_ - 0.0040720468f * s_;
236 a = 1.9779984951f * l_ - 2.4285922050f * m_ + 0.4505937099f * s_;
237 bOut = 0.0259040371f * l_ + 0.7827717662f * m_ - 0.8086757660f * s_;
240 inline std::array<float, 3>
OklabToRGB(
float L,
float a,
float b)
242 if (!std::isfinite(L)) L = 0.0f;
243 if (!std::isfinite(a)) a = 0.0f;
244 if (!std::isfinite(b)) b = 0.0f;
248 L = std::max(L, 0.0f);
250 float l_ = L + 0.3963377774f * a + 0.2158037573f * b;
251 float m_ = L - 0.1055613458f * a - 0.0638541728f * b;
252 float s_ = L - 0.0894841775f * a - 1.2914855480f * b;
253 float l = l_ * l_ * l_, m = m_ * m_ * m_, s = s_ * s_ * s_;
254 float R = +4.0767416621f * l - 3.3077115913f * m + 0.2309699292f * s;
255 float G = -1.2684380046f * l + 2.6097574011f * m - 0.3413193965f * s;
256 float B = -0.0041960863f * l - 0.7034186147f * m + 1.7076147010f * s;
257 return { std::clamp(
LinearToSRGB(std::clamp(R, 0.0f, 1.0f)), 0.0f, 1.0f),
258 std::clamp(
LinearToSRGB(std::clamp(G, 0.0f, 1.0f)), 0.0f, 1.0f),
259 std::clamp(
LinearToSRGB(std::clamp(B, 0.0f, 1.0f)), 0.0f, 1.0f) };
@ X
Definition gui_scroll_management.h:24
@ Y
Definition gui_scroll_management.h:25
std::array< float, 3 > HSLtoRGB(float h, float s, float l)
Definition gui_color_conversions.h:114
std::array< float, 3 > LabToRGB(float L, float a, float b)
Definition gui_color_conversions.h:192
std::array< float, 3 > HSVtoRGB(float h, float s, float v)
Definition gui_color_conversions.h:55
float SRGBToLinear(float c)
Definition gui_color_conversions.h:14
void RGBtoHSL(float r, float g, float b, float &h, float &s, float &l)
Definition gui_color_conversions.h:86
void RGBtoOklab(float r, float g, float b, float &L, float &a, float &bOut)
Definition gui_color_conversions.h:220
void RGBtoLab(float r, float g, float b, float &L, float &a, float &bOut)
Definition gui_color_conversions.h:168
float LinearToSRGB(float c)
Definition gui_color_conversions.h:20
void RGBtoHSV(float r, float g, float b, float &h, float &s, float &v)
Definition gui_color_conversions.h:28
std::array< float, 3 > OklabToRGB(float L, float a, float b)
Definition gui_color_conversions.h:240
Definition gui_color_conversions.h:143
constexpr float kLabDelta
Definition gui_color_conversions.h:147
constexpr float kD65WhiteZ
Definition gui_color_conversions.h:146
std::array< float, 3 > XYZtoRGB(float X, float Y, float Z)
Definition gui_color_conversions.h:159
std::array< float, 3 > RGBtoXYZ(float r, float g, float b)
Definition gui_color_conversions.h:149
constexpr float kD65WhiteX
Definition gui_color_conversions.h:144
constexpr float kD65WhiteY
Definition gui_color_conversions.h:145
Definition gui_color_conversions.h:8