95 { 0.37208f, 0.37529f },
96 { 0.40910f, 0.39430f },
97 { 0.44018f, 0.40329f },
98 { 0.31379f, 0.34531f },
99 { 0.37790f, 0.38835f },
100 { 0.31292f, 0.32933f },
101 { 0.34588f, 0.35875f },
102 { 0.37417f, 0.37281f },
103 { 0.34609f, 0.35986f },
104 { 0.38052f, 0.37713f },
105 { 0.43695f, 0.40441f } };
117 { 0.4357f, 0.4012f },
118 { 0.3756f, 0.3723f },
119 { 0.3422f, 0.3502f },
120 { 0.3118f, 0.3236f },
121 { 0.4474f, 0.4066f },
122 { 0.4557f, 0.4211f },
123 { 0.4560f, 0.4548f },
124 { 0.3781f, 0.3775f }};
127#pragma omp declare simd
135 const float n = (
x - 0.3366f)/(y - 0.1735f);
136 return -949.86315f + 6253.80338f * expf(-
n / 0.92159f) + 28.70599f * expf(-
n / 0.20039f) + 0.00004f * expf(-
n / 0.07125f);
141#pragma omp declare simd
149 if(
t >= 4000.f &&
t <= 7000.0f)
150 x_temp = ((-4.6070e9f /
t + 2.9678e6f) /
t + 0.09911e3f) /
t + 0.244063f;
151 else if(
t > 7000.f &&
t <= 25000.f)
152 x_temp = ((-2.0064e9f /
t + 1.9018e6f) /
t + 0.24748e3f) /
t + 0.237040f;
154 y_temp = (-3.f * x_temp + 2.87f) * x_temp - 0.275f;
162#pragma omp declare simd
170 if(
t >= 1667.f &&
t <= 4000.f)
171 x_temp = ((-0.2661239e9f /
t - 0.2343589e6f) /
t + 0.8776956e3f) /
t + 0.179910f;
172 else if(
t > 4000.f &&
t <= 25000.f)
173 x_temp = ((-3.0258469e9f /
t + 2.1070379e6f) /
t + 0.2226347e3f) /
t + 0.240390f;
175 if(
t >= 1667.f &&
t <= 2222.f)
176 y_temp = ((-1.1063814f * x_temp - 1.34811020f) * x_temp + 2.18555832f) * x_temp - 0.20219683f;
177 else if(
t > 2222.f &&
t <= 4000.f)
178 y_temp = ((-0.9549476f * x_temp - 1.37418593f) * x_temp + 2.09137015f) * x_temp - 0.16748867f;
179 else if(
t > 4000.f &&
t <= 25000.f)
180 y_temp = (( 3.0817580f * x_temp - 5.87338670f) * x_temp + 3.75112997f) * x_temp - 0.37001483f;
188#pragma omp declare simd
194 XYZ[2] = (1.f -
x - y) / y;
199#pragma omp declare simd
204 dt_aligned_pixel_t
XYZ;
212 const float max_RGB = fmaxf(fmaxf(
RGB[0],
RGB[1]),
RGB[2]);
213 for(
int c = 0;
c < 3;
c++)
RGB[
c] = fmaxf(
RGB[
c] / max_RGB, 0.f);
218#pragma omp declare simd
234 float *chroma_x,
float *chroma_y);
239 const dt_aligned_pixel_t custom_wb,
240 float *x_out,
float *y_out,
301 if(y != 0.f &&
x != 0.f)
break;
309 if(y != 0.f &&
x != 0.f)
break;
327 if(
x != 0.f && y != 0.f)
342 dt_aligned_pixel_t
XYZ,
LMS;
345 XYZ[0] = CAM_to_XYZ[0][0] / WB[0] + CAM_to_XYZ[1][0] / WB[1] + CAM_to_XYZ[2][0] / WB[2];
346 XYZ[1] = CAM_to_XYZ[0][1] / WB[0] + CAM_to_XYZ[1][1] / WB[1] + CAM_to_XYZ[2][1] / WB[2];
347 XYZ[2] = CAM_to_XYZ[0][2] / WB[0] + CAM_to_XYZ[1][2] / WB[1] + CAM_to_XYZ[2][2] / WB[2];
350 static const dt_aligned_pixel_t D65 = { 0.941238f, 1.040633f, 1.088932f, 0.f };
351 const float p = powf(1.088932f / 0.818155f, 0.0834f);
371 for(
int i = 0;
i < 3;
i++)
373 for(
int j = 0; j < 6; j++)
374 work[
i][j] = j ==
i+3;
375 for(
int j = 0; j < 3; j++)
376 for(
int k = 0; k <
size; k++)
377 work[
i][j] += in[k][
i] * in[k][j];
379 for(
int i = 0;
i < 3;
i++)
381 float num = work[
i][
i];
382 for(
int j = 0; j < 6; j++)
384 for(
int k = 0; k < 3; k++)
388 for(
int j = 0; j < 6; j++)
389 work[k][j] -= work[
i][j] * num;
393 for(
int j = 0; j < 3; j++)
396 for(
int k = 0; k < 3; k++)
397 out[
i][j] += work[j][k+3] * in[
i][k];
403 float *chroma_x,
float *chroma_y)
405 if(img == NULL)
return FALSE;
408 int has_valid_coeffs =
TRUE;
412 for(
int k = 0; has_valid_coeffs && k < num_coeffs; k++)
415 if(!has_valid_coeffs)
return FALSE;
423 for(
size_t k = 0; k < 4; k++) WB[k] *= custom_wb[k];
426 float XYZ_to_CAM[4][3];
427 XYZ_to_CAM[0][0] = NAN;
447 for(
int k=0; k<4; k++)
448 for(
int i=0;
i<3;
i++)
452 if(isnan(XYZ_to_CAM[0][0]))
return FALSE;
456 float CAM_to_XYZ[4][3];
457 CAM_to_XYZ[0][0] = NAN;
459 if(isnan(CAM_to_XYZ[0][0]))
return FALSE;
471#pragma omp declare simd
479 if(
t >= 1667.f &&
t <= 2222.f)
480 n = (-3.3191442f *
x - 2.69622040f) *
x + 2.18555832f;
481 else if(
t > 2222.f &&
t <= 4000.f)
482 n = (-2.8648428f *
x - 2.74837186f) *
x + 2.09137015f;
483 else if(
t > 4000.f &&
t < 25000.f)
484 n = (9.2452740f *
x - 11.7467734f) *
x + 3.75112997f;
490#pragma omp declare simd
493 float *x_out,
float *y_out)
497 const float norm = sqrtf(1.f +
n *
n);
498 *x_out =
x + tint *
n / norm;
499 *y_out = y - tint / norm;
504#pragma omp declare simd
510 const float norm = sqrtf(1.f +
n *
n);
513 const float tint = -(y - y_bb) * norm;
519#pragma omp declare simd
521static inline void xy_to_uv(
const float xy[2],
float uv[2])
525 const float denom = 12.f * xy[1] - 1.882f * xy[0] + 2.9088f;
526 uv[0] = 5.5932f * xy[0] + 1.9116 * xy[1];
527 uv[1] = 7.8972f * xy[1];
553 if(
n.radius <
r.radius)
return n;
559#pragma omp declare reduction(pairmin:struct pair:omp_out=pair_min(omp_out,omp_in)) \
560 initializer(omp_priv = { FLT_MAX, 0.0f })
569 static const float T_min = 1667.f;
570 static const float T_max = 25000.f;
571 static const float T_range = T_max - T_min;
572 static const size_t LUT_samples = 1<<16;
574 struct pair min_radius = { FLT_MAX, 0.0f };
576#if !(defined(__apple_build_version__) && __apple_build_version__ < 11030000)
578#pragma omp parallel for default(none) \
579 dt_omp_firstprivate(x, y, T_min, T_range, LUT_samples) reduction(pairmin:min_radius)\
580 schedule(simd:static)
583 for(
size_t i = 0;
i < LUT_samples;
i++)
586 const float step = powf((
float)
i / (
float)(LUT_samples - 1), 4.0f);
589 const float T = T_min + step * T_range;
603 min_radius =
pair_min(min_radius, radius_tmp);
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
Definition chromatic_adaptation.h:315
static const dt_aligned_pixel_simd_t illuminant
Definition chromatic_adaptation.h:313
static float4 convert_XYZ_to_bradford_LMS(const float4 XYZ)
Definition colorspace.h:657
static void bradford_adapt_D50(float4 *lms_in, const float4 origin_illuminant, const float p, const int full)
Definition colorspace.h:697
static float4 convert_bradford_LMS_to_XYZ(const float4 LMS)
Definition colorspace.h:667
dt_aligned_pixel_t LMS
Definition colorspaces_inline_conversions.h:952
const float i
Definition colorspaces_inline_conversions.h:669
dt_XYZ_to_Rec709_D50(XYZ, rgb)
const float c
Definition colorspaces_inline_conversions.h:1365
const float denom
Definition colorspaces_inline_conversions.h:1334
const float r
Definition colorspaces_inline_conversions.h:1324
static const dt_colormatrix_t dt_aligned_pixel_t out
Definition colorspaces_inline_conversions.h:184
const float n
Definition colorspaces_inline_conversions.h:929
static dt_aligned_pixel_t XYZ
Definition colorspaces_inline_conversions.h:252
dt_store_simd_aligned(out, dt_mat3x4_mul_vec4(vin, dt_colormatrix_row_to_simd(matrix, 0), dt_colormatrix_row_to_simd(matrix, 1), dt_colormatrix_row_to_simd(matrix, 2)))
static dt_aligned_pixel_t RGB
Definition colorspaces_inline_conversions.h:509
return dt_load_simd_aligned(JCH)
gboolean dt_image_is_matrix_correction_supported(const dt_image_t *img)
Definition common/image.c:268
@ DT_IMAGE_4BAYER
Definition common/image.h:127
#define DT_ALIGNED_ARRAY
Definition darktable.h:312
static int illuminant_to_xy(const dt_illuminant_t illuminant, const dt_image_t *img, const dt_aligned_pixel_t custom_wb, float *x_out, float *y_out, const float t, const dt_illuminant_fluo_t fluo, const dt_illuminant_led_t iled)
Definition illuminants.h:237
dt_illuminant_t
Definition illuminants.h:35
@ DT_ILLUMINANT_A
Definition illuminants.h:37
@ DT_ILLUMINANT_PIPE
Definition illuminants.h:36
@ DT_ILLUMINANT_CAMERA
Definition illuminants.h:46
@ DT_ILLUMINANT_BB
Definition illuminants.h:42
@ DT_ILLUMINANT_F
Definition illuminants.h:40
@ DT_ILLUMINANT_CUSTOM
Definition illuminants.h:43
@ DT_ILLUMINANT_LED
Definition illuminants.h:41
@ DT_ILLUMINANT_DETECT_EDGES
Definition illuminants.h:45
@ DT_ILLUMINANT_E
Definition illuminants.h:39
@ DT_ILLUMINANT_LAST
Definition illuminants.h:47
@ DT_ILLUMINANT_DETECT_SURFACES
Definition illuminants.h:44
@ DT_ILLUMINANT_D
Definition illuminants.h:38
static void WB_coeffs_to_illuminant_xy(const float CAM_to_XYZ[4][3], const dt_aligned_pixel_t WB, float *x, float *y)
Definition illuminants.h:338
static void illuminant_CCT_to_RGB(const float t, dt_aligned_pixel_t RGB)
Definition illuminants.h:220
static void illuminant_xy_to_RGB(const float x, const float y, dt_aligned_pixel_t RGB)
Definition illuminants.h:201
static void illuminant_xy_to_XYZ(const float x, const float y, dt_aligned_pixel_t XYZ)
Definition illuminants.h:190
static float xy_to_CCT(const float x, const float y)
Definition illuminants.h:129
static void CCT_to_xy_daylight(const float t, float *x, float *y)
Definition illuminants.h:143
dt_illuminant_led_t
Definition illuminants.h:70
@ DT_ILLUMINANT_LED_BH1
Definition illuminants.h:76
@ DT_ILLUMINANT_LED_B5
Definition illuminants.h:75
@ DT_ILLUMINANT_LED_B2
Definition illuminants.h:72
@ DT_ILLUMINANT_LED_B1
Definition illuminants.h:71
@ DT_ILLUMINANT_LED_LAST
Definition illuminants.h:80
@ DT_ILLUMINANT_LED_V1
Definition illuminants.h:78
@ DT_ILLUMINANT_LED_B3
Definition illuminants.h:73
@ DT_ILLUMINANT_LED_B4
Definition illuminants.h:74
@ DT_ILLUMINANT_LED_V2
Definition illuminants.h:79
@ DT_ILLUMINANT_LED_RGB1
Definition illuminants.h:77
static float CCT_reverse_lookup(const float x, const float y)
Definition illuminants.h:563
static float get_tint_from_tinted_xy(const float x, const float y, const float t)
Definition illuminants.h:506
static float planckian_normal(const float x, const float t)
Definition illuminants.h:473
static int find_temperature_from_raw_coeffs(const dt_image_t *img, const dt_aligned_pixel_t custom_wb, float *chroma_x, float *chroma_y)
Definition illuminants.h:402
static void CCT_to_xy_blackbody(const float t, float *x, float *y)
Definition illuminants.h:164
static float fluorescent[DT_ILLUMINANT_FLUO_LAST][2]
Definition illuminants.h:94
static void matrice_pseudoinverse(float(*in)[3], float(*out)[3], int size)
Definition illuminants.h:367
dt_illuminant_fluo_t
Definition illuminants.h:52
@ DT_ILLUMINANT_FLUO_F6
Definition illuminants.h:58
@ DT_ILLUMINANT_FLUO_F4
Definition illuminants.h:56
@ DT_ILLUMINANT_FLUO_F1
Definition illuminants.h:53
@ DT_ILLUMINANT_FLUO_F5
Definition illuminants.h:57
@ DT_ILLUMINANT_FLUO_F2
Definition illuminants.h:54
@ DT_ILLUMINANT_FLUO_F3
Definition illuminants.h:55
@ DT_ILLUMINANT_FLUO_F12
Definition illuminants.h:64
@ DT_ILLUMINANT_FLUO_F8
Definition illuminants.h:60
@ DT_ILLUMINANT_FLUO_F9
Definition illuminants.h:61
@ DT_ILLUMINANT_FLUO_LAST
Definition illuminants.h:65
@ DT_ILLUMINANT_FLUO_F11
Definition illuminants.h:63
@ DT_ILLUMINANT_FLUO_F7
Definition illuminants.h:59
@ DT_ILLUMINANT_FLUO_F10
Definition illuminants.h:62
static void blackbody_xy_to_tinted_xy(const float x, const float y, const float t, const float tint, float *x_out, float *y_out)
Definition illuminants.h:492
static void xy_to_uv(const float xy[2], float uv[2])
Definition illuminants.h:521
static float led[DT_ILLUMINANT_LED_LAST][2]
Definition illuminants.h:116
struct pair pair_min(struct pair r, struct pair n)
Definition illuminants.h:550
static const float x
Definition iop_profile.h:239
const int t
Definition iop_profile.h:227
static float dt_fast_hypotf(const float x, const float y)
Definition math.h:280
size_t size
Definition mipmap_cache.c:3
Definition common/image.h:247
int32_t flags
Definition common/image.h:285
float d65_color_matrix[9]
Definition common/image.h:299
float adobe_XYZ_to_CAM[4][3]
Definition common/image.h:322
dt_aligned_pixel_t wb_coeffs
Definition common/image.h:319
Definition illuminants.h:545
float temperature
Definition illuminants.h:547
float radius
Definition illuminants.h:546