21void hsv_to_rgb(
float h,
float s,
float v,
float *r_r,
float *r_g,
float *r_b)
25 nr =
fabsf(h * 6.0f - 3.0f) - 1.0f;
26 ng = 2.0f -
fabsf(h * 6.0f - 2.0f);
27 nb = 2.0f -
fabsf(h * 6.0f - 4.0f);
29 CLAMP(nr, 0.0f, 1.0f);
30 CLAMP(nb, 0.0f, 1.0f);
31 CLAMP(ng, 0.0f, 1.0f);
33 *r_r = ((nr - 1.0f) * s + 1.0f) *
v;
34 *r_g = ((ng - 1.0f) * s + 1.0f) *
v;
35 *r_b = ((nb - 1.0f) * s + 1.0f) *
v;
38void hsl_to_rgb(
float h,
float s,
float l,
float *r_r,
float *r_g,
float *r_b)
40 float nr, ng, nb, chroma;
42 nr =
fabsf(h * 6.0f - 3.0f) - 1.0f;
43 ng = 2.0f -
fabsf(h * 6.0f - 2.0f);
44 nb = 2.0f -
fabsf(h * 6.0f - 4.0f);
46 CLAMP(nr, 0.0f, 1.0f);
47 CLAMP(nb, 0.0f, 1.0f);
48 CLAMP(ng, 0.0f, 1.0f);
50 chroma = (1.0f -
fabsf(2.0f *
l - 1.0f)) * s;
52 *r_r = (nr - 0.5f) * chroma +
l;
53 *r_g = (ng - 0.5f) * chroma +
l;
54 *r_b = (nb - 0.5f) * chroma +
l;
59 hsv_to_rgb(hsv[0], hsv[1], hsv[2], &r_rgb[0], &r_rgb[1], &r_rgb[2]);
64 hsl_to_rgb(hsl[0], hsl[1], hsl[2], &r_rgb[0], &r_rgb[1], &r_rgb[2]);
67void rgb_to_yuv(
float r,
float g,
float b,
float *r_y,
float *r_u,
float *r_v,
int colorspace)
73 y = 0.299f * r + 0.587f * g + 0.114f *
b;
74 u = -0.147f * r - 0.289f * g + 0.436f *
b;
75 v = 0.615f * r - 0.515f * g - 0.100f *
b;
80 y = 0.2126f * r + 0.7152f * g + 0.0722f *
b;
81 u = -0.09991f * r - 0.33609f * g + 0.436f *
b;
82 v = 0.615f * r - 0.55861f * g - 0.05639f *
b;
91void yuv_to_rgb(
float y,
float u,
float v,
float *r_r,
float *r_g,
float *r_b,
int colorspace)
98 g =
y - 0.394f * u - 0.581f *
v;
104 r =
y + 1.28033f *
v;
105 g =
y - 0.21482f * u - 0.38059f *
v;
106 b =
y + 2.12798f * u;
115void rgb_to_ycc(
float r,
float g,
float b,
float *r_y,
float *r_cb,
float *r_cr,
int colorspace)
118 float y = 128.0f, cr = 128.0f, cb = 128.0f;
124 switch (colorspace) {
126 y = (0.257f * sr) + (0.504f * sg) + (0.098f * sb) + 16.0f;
127 cb = (-0.148f * sr) - (0.291f * sg) + (0.439f * sb) + 128.0f;
128 cr = (0.439f * sr) - (0.368f * sg) - (0.071f * sb) + 128.0f;
131 y = (0.183f * sr) + (0.614f * sg) + (0.062f * sb) + 16.0f;
132 cb = (-0.101f * sr) - (0.338f * sg) + (0.439f * sb) + 128.0f;
133 cr = (0.439f * sr) - (0.399f * sg) - (0.040f * sb) + 128.0f;
136 y = (0.299f * sr) + (0.587f * sg) + (0.114f * sb);
137 cb = (-0.16874f * sr) - (0.33126f * sg) + (0.5f * sb) + 128.0f;
138 cr = (0.5f * sr) - (0.41869f * sg) - (0.08131f * sb) + 128.0f;
150void ycc_to_rgb(
float y,
float cb,
float cr,
float *r_r,
float *r_g,
float *r_b,
int colorspace)
158 float r = 128.0f, g = 128.0f,
b = 128.0f;
160 switch (colorspace) {
162 r = 1.164f * (
y - 16.0f) + 1.596f * (cr - 128.0f);
163 g = 1.164f * (
y - 16.0f) - 0.813f * (cr - 128.0f) - 0.392f * (cb - 128.0f);
164 b = 1.164f * (
y - 16.0f) + 2.017f * (cb - 128.0f);
167 r = 1.164f * (
y - 16.0f) + 1.793f * (cr - 128.0f);
168 g = 1.164f * (
y - 16.0f) - 0.534f * (cr - 128.0f) - 0.213f * (cb - 128.0f);
169 b = 1.164f * (
y - 16.0f) + 2.115f * (cb - 128.0f);
172 r =
y + 1.402f * cr - 179.456f;
173 g =
y - 0.34414f * cb - 0.71414f * cr + 135.45984f;
174 b =
y + 1.772f * cb - 226.816f;
185void hex_to_rgb(
const char *hexcol,
float *r_r,
float *r_g,
float *r_b)
190void hex_to_rgba(
const char *hexcol,
float *r_r,
float *r_g,
float *r_b,
float *r_a)
193 bool has_alpha =
false;
195 if (hexcol[0] ==
'#') {
199 if (sscanf(hexcol,
"%02x%02x%02x%02x", &ri, &gi, &bi, &ai) == 4) {
203 else if (sscanf(hexcol,
"%02x%02x%02x", &ri, &gi, &bi) == 3) {
206 else if (sscanf(hexcol,
"%01x%01x%01x", &ri, &gi, &bi) == 3) {
214 *r_r = *r_g = *r_b = 0.0f;
221 *r_r =
float(ri) * (1.0f / 255.0f);
222 *r_g =
float(gi) * (1.0f / 255.0f);
223 *r_b =
float(bi) * (1.0f / 255.0f);
224 CLAMP(*r_r, 0.0f, 1.0f);
225 CLAMP(*r_g, 0.0f, 1.0f);
226 CLAMP(*r_b, 0.0f, 1.0f);
228 if (r_a && has_alpha) {
229 *r_a =
float(ai) * (1.0f / 255.0f);
230 CLAMP(*r_a, 0.0f, 1.0f);
234void rgb_to_hsv(
float r,
float g,
float b,
float *r_h,
float *r_s,
float *r_v)
247 k = -2.0f / 6.0f - k;
253 *r_h =
fabsf(k + (g -
b) / (6.0f * chroma + 1e-20f));
254 *r_s = chroma / (r + 1e-20f);
260 rgb_to_hsv(rgb[0], rgb[1], rgb[2], &r_hsv[0], &r_hsv[1], &r_hsv[2]);
263void rgb_to_hsl(
float r,
float g,
float b,
float *r_h,
float *r_s,
float *r_l)
265 const float cmax =
max_fff(r, g,
b);
266 const float cmin =
min_fff(r, g,
b);
267 float h, s,
l =
min_ff(1.0f, (cmax + cmin) / 2.0f);
273 float d = cmax - cmin;
274 s =
l > 0.5f ? d / (2.0f - cmax - cmin) : d / (cmax + cmin);
276 h = (g -
b) / d + (g <
b ? 6.0f : 0.0f);
278 else if (cmax == g) {
279 h = (
b - r) / d + 2.0f;
282 h = (r - g) / d + 4.0f;
297 const float orig_s = *r_s;
298 const float orig_h = *r_h;
299 const float threshold = 1e-5f;
305 if (*r_l <= threshold) {
309 else if (*r_s <= threshold) {
315 if (
fabsf(*r_h) <= threshold &&
fabsf(orig_h - 1.0f) <= threshold) {
318 else if (
fabsf(*r_h - 1.0f) <= threshold &&
fabsf(orig_h) <= threshold) {
330 rgb_to_hsl(rgb[0], rgb[1], rgb[2], &r_hsl[0], &r_hsl[1], &r_hsl[2]);
338 const float orig_h = *r_h;
339 const float orig_s = *r_s;
340 const float threshold = 1e-5f;
346 if (*r_v <= threshold) {
350 else if (*r_s <= threshold) {
355 if (
fabsf(*r_h) <= threshold &&
fabsf(orig_h - 1.0f) <= threshold) {
358 else if (
fabsf(*r_h - 1.0f) <= threshold &&
fabsf(orig_h) <= threshold) {
370 if (
UNLIKELY(hsv[0] < 0.0f || hsv[0] > 1.0f)) {
371 hsv[0] = hsv[0] -
floorf(hsv[0]);
373 CLAMP(hsv[1], 0.0f, 1.0f);
374 CLAMP(hsv[2], 0.0f, v_max);
385 r =
uint(rf * 255.0f);
386 g =
uint(gf * 255.0f);
387 b =
uint(bf * 255.0f);
389 col = (r + (g * 256) + (
b * 256 * 256));
401 ir = std::min<uint>(ir, 255);
402 ig = std::min<uint>(ig, 255);
403 ib = std::min<uint>(ib, 255);
405 return (ir + (ig * 256) + (ib * 256 * 256));
410 *r_r =
float(
col & 0xFF) * (1.0f / 255.0f);
411 *r_g =
float((
col >> 8) & 0xFF) * (1.0f / 255.0f);
412 *r_b =
float((
col >> 16) & 0xFF) * (1.0f / 255.0f);
420 return (c < 0.0f) ? 0.0f : c * (1.0f / 12.92f);
423 return powf((c + 0.055f) * (1.0f / 1.055f), 2.4f);
428 if (c < 0.0031308f) {
429 return (c < 0.0f) ? 0.0f : c * 12.92f;
432 return 1.055f *
powf(c, 1.0f / 2.4f) - 0.055f;
451 ret = _mm_mul_ps(arg, _mm_castsi128_ps(_mm_set1_epi32(e2coeff)));
452 ret = _mm_cvtepi32_ps(_mm_castps_si128(
ret));
453 ret = _mm_mul_ps(
ret, _mm_castsi128_ps(_mm_set1_epi32(
exp)));
454 ret = _mm_castsi128_ps(_mm_cvtps_epi32(
ret));
461 __m128 approx2 = _mm_mul_ps(old_result, old_result);
462 __m128 approx4 = _mm_mul_ps(approx2, approx2);
463 __m128 t = _mm_div_ps(
x, approx4);
464 __m128 summ = _mm_add_ps(_mm_mul_ps(_mm_set1_ps(4.0f), old_result), t);
465 return _mm_mul_ps(summ, _mm_set1_ps(1.0f / 5.0f));
481 __m128 arg2 = _mm_mul_ps(arg, arg);
482 __m128 arg4 = _mm_mul_ps(arg2, arg2);
489 return _mm_mul_ps(
x, _mm_mul_ps(
x,
x));
494 __m128 r = _mm_rsqrt_ps(
in);
499# if defined(__SSE2__)
500 r = _mm_add_ps(_mm_mul_ps(_mm_set1_ps(1.5f), r),
501 _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(
in, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r)));
514 __m128 xover = _mm_mul_ps(arg, xf);
516 __m128 x2 = _mm_mul_ps(arg, arg);
517 __m128 xunder = _mm_mul_ps(x2, xfm1);
519 __m128 xavg = _mm_mul_ps(_mm_set1_ps(1.0f / (3.0f * 0.629960524947437f) * 0.999852f),
520 _mm_add_ps(xover, xunder));
526MALWAYS_INLINE __m128 _bli_math_blend_sse(
const __m128
mask,
const __m128 a,
const __m128
b)
529 return _mm_blendv_ps(
b, a,
mask);
531 return _mm_or_ps(_mm_and_ps(
mask, a), _mm_andnot_ps(
mask,
b));
537 __m128 cmp = _mm_cmplt_ps(c, _mm_set1_ps(0.04045f));
538 __m128 lt = _mm_max_ps(_mm_mul_ps(c, _mm_set1_ps(1.0f / 12.92f)), _mm_set1_ps(0.0f));
539 __m128 gtebase = _mm_mul_ps(_mm_add_ps(c, _mm_set1_ps(0.055f)),
540 _mm_set1_ps(1.0f / 1.055f));
542 return _bli_math_blend_sse(cmp, lt, gte);
547 __m128 cmp = _mm_cmplt_ps(c, _mm_set1_ps(0.0031308f));
548 __m128 lt = _mm_max_ps(_mm_mul_ps(c, _mm_set1_ps(12.92f)), _mm_set1_ps(0.0f));
550 _mm_set1_ps(-0.055f));
551 return _bli_math_blend_sse(cmp, lt, gte);
556 float r[4] = {srgb[0], srgb[1], srgb[2], 1.0f};
557 __m128 *rv = (__m128 *)&r;
558 *rv = srgb_to_linearrgb_v4_simd(*rv);
566 float r[4] = {linear[0], linear[1], linear[2], 1.0f};
567 __m128 *rv = (__m128 *)&r;
568 *rv = linearrgb_to_srgb_v4_simd(*rv);
581 memcpy(&r, &
v,
sizeof(
v));
588 memcpy(&r, &
v,
sizeof(
v));
603 float approx2 = old_result * old_result;
604 float approx4 = approx2 * approx2;
605 float t =
x / approx4;
606 float summ = 4.0f * old_result + t;
607 return summ * (1.0f / 5.0f);
613 float arg2 = arg * arg;
614 float arg4 = arg2 * arg2;
629 float xover = arg * xf;
631 float x2 = arg * arg;
632 float xunder = x2 * xfm1;
633 float xavg = (1.0f / (3.0f * 0.629960524947437f) * 0.999852f) * (xover + xunder);
642 return (c < 0.0f) ? 0.0f : c * (1.0f / 12.92f);
650 if (c < 0.0031308f) {
651 return (c < 0.0f) ? 0.0f : c * 12.92f;
679 rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv + 1, hsv + 2);
681 hsv[0] += hue_offset;
685 else if (hsv[0] < 0.0f) {
689 hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb + 1, rgb + 2);
731 if (
i < 0x80 || (
i >= 0x8000 &&
i < 0x8080)) {
735 if (
i >= 0x7f80 &&
i < 0x8000) {
760 for (
i = 0;
i < 0x10000;
i++) {
774 for (
b = 0;
b <= 255;
b++) {
802 {0.0f, {0.18006f, 0.26352f}, -0.24341f}, {10.0f, {0.18066f, 0.26589f}, -0.25479f},
803 {20.0f, {0.18133f, 0.26846f}, -0.26876f}, {30.0f, {0.18208f, 0.27119f}, -0.28539f},
804 {40.0f, {0.18293f, 0.27407f}, -0.30470f}, {50.0f, {0.18388f, 0.27709f}, -0.32675f},
805 {60.0f, {0.18494f, 0.28021f}, -0.35156f}, {70.0f, {0.18611f, 0.28342f}, -0.37915f},
806 {80.0f, {0.18740f, 0.28668f}, -0.40955f}, {90.0f, {0.18880f, 0.28997f}, -0.44278f},
807 {100.0f, {0.19032f, 0.29326f}, -0.47888f}, {125.0f, {0.19462f, 0.30141f}, -0.58204f},
808 {150.0f, {0.19962f, 0.30921f}, -0.70471f}, {175.0f, {0.20525f, 0.31647f}, -0.84901f},
809 {200.0f, {0.21142f, 0.32312f}, -1.0182f}, {225.0f, {0.21807f, 0.32909f}, -1.2168f},
810 {250.0f, {0.22511f, 0.33439f}, -1.4512f}, {275.0f, {0.23247f, 0.33904f}, -1.7298f},
811 {300.0f, {0.24010f, 0.34308f}, -2.0637f}, {325.0f, {0.24792f, 0.34655f}, -2.4681f},
812 {350.0f, {0.25591f, 0.34951f}, -2.9641f}, {375.0f, {0.26400f, 0.35200f}, -3.5814f},
813 {400.0f, {0.27218f, 0.35407f}, -4.3633f}, {425.0f, {0.28039f, 0.35577f}, -5.3762f},
814 {450.0f, {0.28863f, 0.35714f}, -6.7262f}, {475.0f, {0.29685f, 0.35823f}, -8.5955f},
815 {500.0f, {0.30505f, 0.35907f}, -11.324f}, {525.0f, {0.31320f, 0.35968f}, -15.628f},
816 {550.0f, {0.32129f, 0.36011f}, -23.325f}, {575.0f, {0.32931f, 0.36038f}, -40.770f},
817 {600.0f, {0.33724f, 0.36051f}, -116.45f},
823 const float2 uv =
float2{4.0f * white.x, 6.0f * white.y} /
dot(white, {1.0f, 15.0f, 3.0f});
826 auto check = [uv](
const float val,
const locus_entry_t &entry) {
return entry.dist(uv) < val; };
835 const float d_low = low.
dist(uv) /
sqrtf(1.0f + low.
t * low.
t);
836 const float d_high = high.dist(uv) /
sqrtf(1.0f + high.t * high.t);
837 const float f = d_low / (d_low - d_high);
841 const float abs_tint =
length(uv - uv_temp) * 3000.0f;
842 if (abs_tint > 150.0f) {
847 tint = abs_tint * ((uv.x < uv_temp.x) ? 1.0f : -1.0f);
854 const float mired =
clamp(
856 auto check = [](
const locus_entry_t &entry,
const float val) {
return entry.
mired < val; };
862 const float f = (mired - low.
mired) / (high.mired - low.
mired);
874 uv -= isotherm * tint / 3000.0f;
877 const float x = 3.0f * uv.x / (2.0f * uv.x - 8.0f * uv.y + 4.0f);
878 const float y = 2.0f * uv.y / (2.0f * uv.x - 8.0f * uv.y + 4.0f);
888 {0.8951f, -0.7502f, 0.0389f},
889 {0.2664f, 1.7135f, -0.0685f},
890 {-0.1614f, 0.0367f, 1.0296f},
894 const float3 from_LMS = bradford * from_XYZ / from_XYZ.y;
895 const float3 to_LMS = bradford * to_XYZ / to_XYZ.y;
#define BLI_assert_unreachable()
#define BLI_assert_msg(a, msg)
MINLINE float max_fff(float a, float b, float c)
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
MINLINE float min_fff(float a, float b, float c)
#define BLI_YUV_ITU_BT709
#define BLI_YCC_JFIF_0_255
MINLINE void rgb_uchar_to_float(float r_col[3], const unsigned char col_ub[3])
#define BLI_YCC_ITU_BT601
MINLINE void rgb_float_to_uchar(unsigned char r_col[3], const float col_f[3])
#define BLI_YUV_ITU_BT601
#define BLI_YCC_ITU_BT709
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE btScalar length() const
Return the length of the vector.
IMETHOD Vector diff(const Vector &a, const Vector &b, double dt)
VecBase< float, D > normalize(VecOp< float, D >) RET
MALWAYS_INLINE float _bli_math_fastpow(const int exp, const int e2coeff, const float arg)
void hsv_to_rgb_v(const float hsv[3], float r_rgb[3])
static float index_to_float(const ushort i)
void rgb_to_hsv_v(const float rgb[3], float r_hsv[3])
MALWAYS_INLINE float srgb_to_linearrgb_approx(float c)
void rgb_to_hsl(float r, float g, float b, float *r_h, float *r_s, float *r_l)
void rgb_to_hsl_compat(float r, float g, float b, float *r_h, float *r_s, float *r_l)
MALWAYS_INLINE float int_as_float(int32_t v)
void rgb_to_hsv_compat_v(const float rgb[3], float r_hsv[3])
MALWAYS_INLINE float _bli_math_rsqrt(float in)
void hex_to_rgba(const char *hexcol, float *r_r, float *r_g, float *r_b, float *r_a)
void rgb_to_hsv(float r, float g, float b, float *r_h, float *r_s, float *r_v)
uint hsv_to_cpack(float h, float s, float v)
MALWAYS_INLINE float linearrgb_to_srgb_approx(float c)
void linearrgb_to_srgb_v3_v3(float srgb[3], const float linear[3])
MALWAYS_INLINE float _bli_math_improve_5throot_solution(const float old_result, const float x)
void hsl_to_rgb_v(const float hsl[3], float r_rgb[3])
void ycc_to_rgb(float y, float cb, float cr, float *r_r, float *r_g, float *r_b, int colorspace)
void rgb_byte_set_hue_float_offset(uchar rgb[3], float hue_offset)
void hsv_to_rgb(float h, float s, float v, float *r_r, float *r_g, float *r_b)
void rgb_to_ycc(float r, float g, float b, float *r_y, float *r_cb, float *r_cr, int colorspace)
MALWAYS_INLINE float _bli_math_fastpow24(const float arg)
void rgb_to_yuv(float r, float g, float b, float *r_y, float *r_u, float *r_v, int colorspace)
void rgb_to_hsv_compat(float r, float g, float b, float *r_h, float *r_s, float *r_v)
void BLI_init_srgb_conversion()
void hsv_clamp_v(float hsv[3], float v_max)
void hsl_to_rgb(float h, float s, float l, float *r_r, float *r_g, float *r_b)
float srgb_to_linearrgb(float c)
static ushort hipart(const float f)
void srgb_to_linearrgb_v3_v3(float linear[3], const float srgb[3])
ushort BLI_color_to_srgb_table[0x10000]
void hex_to_rgb(const char *hexcol, float *r_r, float *r_g, float *r_b)
void cpack_to_rgb(uint col, float *r_r, float *r_g, float *r_b)
float BLI_color_from_srgb_table[256]
MALWAYS_INLINE int32_t float_as_int(float v)
float linearrgb_to_srgb(float c)
void yuv_to_rgb(float y, float u, float v, float *r_r, float *r_g, float *r_b, int colorspace)
void rgb_to_hsl_v(const float rgb[3], float r_hsl[3])
void rgb_to_hsl_compat_v(const float rgb[3], float r_hsl[3])
MALWAYS_INLINE float _bli_math_fastpow512(const float arg)
uint rgb_to_cpack(float r, float g, float b)
void rgb_float_set_hue_float_offset(float rgb[3], float hue_offset)
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
T clamp(const T &a, const T &min, const T &max)
float3 whitepoint_from_temp_tint(float temperature, float tint)
bool whitepoint_to_temp_tint(const float3 &white, float &temperature, float &tint)
T dot(const QuaternionBase< T > &a, const QuaternionBase< T > &b)
static const std::array< locus_entry_t, 31 > planck_locus
CartesianBasis invert(const CartesianBasis &basis)
MatT from_scale(const VecBase< typename MatT::base_type, ScaleDim > &scale)
T interpolate(const T &a, const T &b, const FactorT &t)
float3x3 chromatic_adaption_matrix(const float3 &from_XYZ, const float3 &to_XYZ)
VecBase< float, 2 > float2
MatBase< float, 3, 3 > float3x3
VecBase< float, 3 > float3
float dist(const float2 p) const