58#define INVERSE_SQRT_3 0.5773502691896258f
59#define SAFETY_MARGIN 0.01f
61#define DT_GUI_CURVE_EDITOR_INSET DT_PIXEL_APPLY_DPI(1)
102#pragma GCC optimize("unroll-loops", "tree-loop-if-convert", "tree-loop-distribution", "no-strict-aliasing", \
103 "loop-interchange", "loop-nest-optimize", "tree-loop-im", "unswitch-loops", \
104 "tree-loop-ivcanon", "ira-loop-pressure", "split-ivs-in-unroller", \
105 "variable-expansion-in-unroller", "split-loops", "ivopts", "predictive-commoning", \
106 "tree-loop-linear", "loop-block", "loop-strip-mine", "finite-math-only", "fp-contract=fast", \
107 "fast-math", "no-math-errno")
341 return _(
"fil_mic rgb");
346 return _(
"tone mapping|curve|view transform|contrast|saturation|highlights");
352 "for display on SDR screens and paper prints\n"
353 "while preventing clipping in non-destructive ways"),
354 _(
"corrective and creative"),
355 _(
"linear or non-linear, RGB, scene-referred"),
356 _(
"non-linear, RGB"),
357 _(
"non-linear, RGB, display-referred"));
388 float grey_log = spline.
x[2];
389 float toe_log = fminf(spline.
x[1], grey_log);
390 float shoulder_log = fmaxf(spline.
x[3], grey_log);
391 float black_display = spline.
y[0];
392 float grey_display = spline.
y[2];
393 float white_display = spline.
y[4];
394 const float scaled_safety_margin =
SAFETY_MARGIN * (white_display - black_display);
395 float toe_display = fminf(spline.
y[1], grey_display);
396 float shoulder_display = fmaxf(spline.
y[3], grey_display);
399 float contrast = (shoulder_display - toe_display) / (shoulder_log - toe_log);
401 float linear_intercept = grey_display - (contrast * grey_log);
402 if(toe_display < black_display + scaled_safety_margin)
404 toe_display = black_display + scaled_safety_margin;
406 toe_log = (toe_display - linear_intercept) / contrast;
408 if(shoulder_display > white_display - scaled_safety_margin)
410 shoulder_display = white_display - scaled_safety_margin;
412 shoulder_log = (shoulder_display - linear_intercept) / contrast;
416 contrast *= hardness * powf(grey_display, hardness-1.0f);
418 const float latitude = CLAMP((shoulder_display - toe_display) / ((white_display - black_display) - 2.0f * scaled_safety_margin), 0.0f, 0.99f);
420 float toe_display_ref = latitude * (black_display + scaled_safety_margin) + (1.0f - latitude) * grey_display;
421 float shoulder_display_ref = latitude * (white_display - scaled_safety_margin) + (1.0f - latitude) * grey_display;
423 if(shoulder_display < shoulder_display_ref)
424 balance = 0.5f * (1.0f - fmaxf(shoulder_display - grey_display, 0.0f) / fmaxf(shoulder_display_ref - grey_display, 1E-5f));
426 balance = -0.5f * (1.0f - fmaxf(grey_display - toe_display, 0.0f) / fmaxf(grey_display - toe_display_ref, 1E-5f));
443 const int new_version)
445 if(old_version == 1 && new_version == 5)
447 typedef struct dt_iop_filmicrgb_params_v1_t
449 float grey_point_source;
450 float black_point_source;
451 float white_point_source;
452 float security_factor;
453 float grey_point_target;
454 float black_point_target;
455 float white_point_target;
462 } dt_iop_filmicrgb_params_v1_t;
464 dt_iop_filmicrgb_params_v1_t *o = (dt_iop_filmicrgb_params_v1_t *)old_params;
502 if(old_version == 2 && new_version == 5)
504 typedef struct dt_iop_filmicrgb_params_v2_t
506 float grey_point_source;
507 float black_point_source;
508 float white_point_source;
509 float reconstruct_threshold;
510 float reconstruct_feather;
511 float reconstruct_bloom_vs_details;
512 float reconstruct_grey_vs_color;
513 float reconstruct_structure_vs_texture;
514 float security_factor;
515 float grey_point_target;
516 float black_point_target;
517 float white_point_target;
527 int high_quality_reconstruction;
530 } dt_iop_filmicrgb_params_v2_t;
532 dt_iop_filmicrgb_params_v2_t *o = (dt_iop_filmicrgb_params_v2_t *)old_params;
570 if(old_version == 3 && new_version == 5)
572 typedef struct dt_iop_filmicrgb_params_v3_t
574 float grey_point_source;
575 float black_point_source;
576 float white_point_source;
577 float reconstruct_threshold;
578 float reconstruct_feather;
579 float reconstruct_bloom_vs_details;
581 float reconstruct_grey_vs_color;
583 float reconstruct_structure_vs_texture;
585 float security_factor;
586 float grey_point_target;
587 float black_point_target;
588 float white_point_target;
599 gboolean auto_hardness;
600 gboolean custom_grey;
601 int high_quality_reconstruction;
603 int noise_distribution;
607 } dt_iop_filmicrgb_params_v3_t;
609 dt_iop_filmicrgb_params_v3_t *o = (dt_iop_filmicrgb_params_v3_t *)old_params;
647 if(old_version == 4 && new_version == 5)
649 typedef struct dt_iop_filmicrgb_params_v4_t
651 float grey_point_source;
652 float black_point_source;
653 float white_point_source;
654 float reconstruct_threshold;
655 float reconstruct_feather;
656 float reconstruct_bloom_vs_details;
657 float reconstruct_grey_vs_color;
658 float reconstruct_structure_vs_texture;
659 float security_factor;
660 float grey_point_target;
661 float black_point_target;
662 float white_point_target;
671 gboolean auto_hardness;
672 gboolean custom_grey;
673 int high_quality_reconstruction;
677 gboolean compensate_icc_black;
678 gint internal_version;
679 } dt_iop_filmicrgb_params_v4_t;
681 dt_iop_filmicrgb_params_v4_t *o = (dt_iop_filmicrgb_params_v4_t *)old_params;
685 switch(o->internal_version)
706#pragma omp declare simd aligned(pixel:16)
713 float numerator = 0.0f;
714 float denominator = 0.0f;
716 for(
int c = 0; c < 3; c++)
718 const float value = fabsf(pixel[c]);
719 const float RGB_square = value * value;
720 const float RGB_cubic = RGB_square * value;
721 numerator += RGB_cubic;
722 denominator += RGB_square;
725 return numerator / fmaxf(denominator, 1e-12f);
730#pragma omp declare simd aligned(pixel : 16) uniform(variant, work_profile)
744 return fmaxf(fmaxf(pixel[0], pixel[1]), pixel[2]);
747 return (work_profile)
749 work_profile->unbounded_coeffs_in, work_profile->
lutsize,
757 return sqrtf(
sqf(pixel[0]) +
sqf(pixel[1]) +
sqf(pixel[2]));
763 return (work_profile)
765 work_profile->unbounded_coeffs_in, work_profile->
lutsize,
772#pragma omp declare simd uniform(grey, black, dynamic_range)
774static inline float log_tonemapping(
const float x,
const float grey,
const float black,
775 const float dynamic_range)
777 return clamp_simd((log2f(x / grey) - black) / dynamic_range);
781#pragma omp declare simd uniform(grey, black, dynamic_range)
784 const float dynamic_range)
787 return grey * exp2f(dynamic_range * x + black);
792#pragma omp declare simd aligned(M1, M2, M3, M4 : 16) uniform(M1, M2, M3, M4, M5, latitude_min, latitude_max)
794static inline float filmic_spline(
const float x,
const dt_aligned_pixel_t M1,
const dt_aligned_pixel_t M2,
795 const dt_aligned_pixel_t M3,
const dt_aligned_pixel_t M4,
796 const dt_aligned_pixel_t M5,
const float latitude_min,
813 result = M1[0] + x * (M2[0] + x * (M3[0] + x * (M4[0] + x * M5[0])));
818 result = M1[0] + x * (M2[0] + x * (M3[0] + x * M4[0]));
823 const float xi = latitude_min - x;
824 const float rat = xi * (xi * M2[0] + 1.f);
825 result = M4[0] - M1[0] * rat / (rat + M3[0]);
828 else if(x > latitude_max)
834 result = M1[1] + x * (M2[1] + x * (M3[1] + x * (M4[1] + x * M5[1])));
839 result = M1[1] + x * (M2[1] + x * (M3[1] + x * M4[1]));
844 const float xi = x - latitude_max;
845 const float rat = xi * (xi * M2[1] + 1.f);
846 result = M4[1] + M1[1] * rat / (rat + M3[1]);
852 result = M1[2] + x * M2[2];
860#pragma omp declare simd uniform(sigma_toe, sigma_shoulder)
863 const float saturation)
865 const float radius_toe = x;
866 const float radius_shoulder = 1.0f - x;
868 const float key_toe = expf(-0.5f * radius_toe * radius_toe / sigma_toe);
869 const float key_shoulder = expf(-0.5f * radius_shoulder * radius_shoulder / sigma_shoulder);
871 return 1.0f -
clamp_simd((key_toe + key_shoulder) / saturation);
876#pragma omp declare simd uniform(sigma_toe, sigma_shoulder)
879 const float saturation)
881 const float radius_toe = x;
882 const float radius_shoulder = 1.0f - x;
883 const float sat2 = 0.5f / sqrtf(saturation);
884 const float key_toe = expf(-radius_toe * radius_toe / sigma_toe * sat2);
885 const float key_shoulder = expf(-radius_shoulder * radius_shoulder / sigma_shoulder * sat2);
887 return (saturation - (key_toe + key_shoulder) * (saturation));
892#pragma omp declare simd
894static inline float linear_saturation(
const float x,
const float luminance,
const float saturation)
896 return luminance + saturation * (x - luminance);
900#define MAX_NUM_SCALES 10
904#pragma omp declare simd aligned(in, mask : 64) uniform(feathering, normalize, width, height, ch)
907 const float normalize,
const float feathering,
const size_t width,
908 const size_t height,
const size_t ch)
920 const unsigned int oldMode = _MM_GET_FLUSH_ZERO_MODE();
921 _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
925#pragma omp parallel for simd default(none) \
926 dt_omp_firstprivate(in, mask, normalize, feathering, width, height, ch) \
927 schedule(simd:static) aligned(mask, in:64) reduction(+:clipped)
929 for(
size_t k = 0; k <
height *
width * ch; k += ch)
931 const float pix_max = fmaxf(sqrtf(
sqf(in[k]) +
sqf(in[k + 1]) +
sqf(in[k + 2])), 0.f);
932 const float argument = -pix_max *
normalize + feathering;
940 clipped += (4.f > argument);
944 _MM_SET_FLUSH_ZERO_MODE(oldMode);
948 return (clipped > 9);
953#pragma omp declare simd aligned(in, mask, inpainted:64) uniform(width, height, noise_level, noise_distribution, threshold)
955inline static void inpaint_noise(
const float *
const in,
const float *
const mask,
956 float *
const inpainted,
const float noise_level,
const float threshold,
965#pragma omp parallel for default(none) \
966 dt_omp_firstprivate(in, mask, inpainted, width, height, noise_level, noise_distribution, threshold) \
967 schedule(simd:static) collapse(2)
969 for(
size_t i = 0; i <
height; i++)
970 for(
size_t j = 0; j <
width; j++)
980 const size_t idx = i *
width + j;
981 const size_t index = idx * 4;
982 const float weight = mask[idx];
983 const float *
const restrict pix_in = __builtin_assume_aligned(in + index, 16);
984 dt_aligned_pixel_t noise = { 0.f };
985 dt_aligned_pixel_t sigma = { 0.f };
989 sigma[c] = pix_in[c] * noise_level / threshold;
995 float *
const restrict pix_out = __builtin_assume_aligned(inpainted + index, 16);
997 pix_out[c] = fmaxf(pix_in[c] * (1.0f -
weight) +
weight * noise[c], 0.f);
1002 const float *
const restrict texture,
const float *
const restrict mask,
1003 float *
const restrict reconstructed,
const size_t width,
1004 const size_t height,
const size_t ch,
const float gamma,
1005 const float gamma_comp,
const float beta,
const float beta_comp,
1006 const float delta,
const size_t s,
const size_t scales)
1009#pragma omp parallel for default(none) \
1010 dt_omp_firstprivate(width, height, ch, HF, LF, texture, mask, reconstructed, gamma, gamma_comp, beta, \
1011 beta_comp, delta, s, scales) schedule(simd : static)
1013 for(
size_t k = 0; k <
height *
width * ch; k += 4)
1015 const float alpha = mask[k / ch];
1018 const float *
const restrict HF_c = __builtin_assume_aligned(HF + k, 16);
1019 const float *
const restrict LF_c = __builtin_assume_aligned(LF + k, 16);
1020 const float *
const restrict TT_c = __builtin_assume_aligned(texture + k, 16);
1029 const float grey_details = (HF_c[0] + HF_c[1] + HF_c[2]) / 3.f;
1034 const float grey_HF = beta_comp * (gamma_comp * grey_details + gamma * grey_texture);
1038 const float grey_residual = beta_comp * (LF_c[0] + LF_c[1] + LF_c[2]) / 3.f;
1041 #pragma omp simd aligned(reconstructed:64) aligned(HF_c, LF_c, TT_c:16)
1043 for(
size_t c = 0; c < 4; c++)
1050 const float details = (gamma_comp * HF_c[c] + gamma * TT_c[c]) * beta + grey_HF;
1053 const float residual = (s == scales - 1) ? (grey_residual + LF_c[c] * beta) : 0.f;
1054 reconstructed[k + c] += alpha * (delta * details + residual);
1060 const float *
const restrict texture,
1061 const float *
const restrict mask,
1062 float *
const restrict reconstructed,
const size_t width,
1063 const size_t height,
const size_t ch,
const float gamma,
1064 const float gamma_comp,
const float beta,
const float beta_comp,
1065 const float delta,
const size_t s,
const size_t scales)
1081#pragma omp parallel for default(none) \
1082 dt_omp_firstprivate(width, height, ch, HF, LF, texture, mask, reconstructed, gamma, gamma_comp, beta, \
1083 beta_comp, delta, s, scales) schedule(simd \
1086 for(
size_t k = 0; k <
height *
width * ch; k += 4)
1088 const float alpha = mask[k / ch];
1091 const float *
const restrict HF_c = __builtin_assume_aligned(HF + k, 16);
1092 const float *
const restrict LF_c = __builtin_assume_aligned(LF + k, 16);
1093 const float *
const restrict TT_c = __builtin_assume_aligned(texture + k, 16);
1102 const float grey_details = (HF_c[0] + HF_c[1] + HF_c[2]) / 3.f;
1107 const float grey_HF = (gamma_comp * grey_details + gamma * grey_texture);
1110 #pragma omp simd aligned(reconstructed:64) aligned(HF_c, TT_c, LF_c:16) linear(k:4)
1112 for(
size_t c = 0; c < 4; c++)
1116 const float details = 0.5f * ((gamma_comp * HF_c[c] + gamma * TT_c[c]) + grey_HF);
1119 const float residual = (s == scales - 1) ? LF_c[c] : 0.f;
1120 reconstructed[k + c] += alpha * (delta * details + residual);
1126static inline void init_reconstruct(
const float *
const restrict in,
const float *
const restrict mask,
1127 float *
const restrict reconstructed,
const size_t width,
const size_t height)
1132#pragma omp parallel for default(none) dt_omp_firstprivate(in, mask, reconstructed, width, height) \
1138 reconstructed[4*k + c] = fmaxf(in[4*k + c] * (1.f - mask[k]), 0.f);
1144 float *
const restrict HF,
float *
const restrict texture,
1145 const size_t width,
const size_t height,
const size_t ch)
1148#pragma omp parallel for simd default(none) dt_omp_firstprivate(width, height, HF, LF, detail, texture) \
1150 : static) aligned(HF, LF, detail, texture : 64)
1154 for(
size_t c = 0; c < 4; ++c) HF[4*k + c] = texture[4*k + c] = detail[4*k + c] - LF[4*k + c];
1170 const float scale = roi_in->
scale / piece->
iscale;
1178 float *
const restrict reconstructed,
1183 gint success =
TRUE;
1186 const int scales =
get_scales(roi_in, piece);
1197 if(!LF_even || !LF_odd || !HF_RGB || !HF_grey || !temp)
1199 dt_control_log(_(
"filmic highlights reconstruction failed to allocate memory, check your RAM settings"));
1223 for(
int s = 0; s < scales; ++s)
1225 const float *restrict detail;
1227 float *restrict HF_RGB_temp;
1234 HF_RGB_temp = LF_even;
1240 HF_RGB_temp = LF_odd;
1246 HF_RGB_temp = LF_even;
1249 const int mult = 1 << s;
1264 gamma, gamma_comp, beta, beta_comp, delta, s, scales);
1267 gamma, gamma_comp, beta, beta_comp, delta, s, scales);
1280static inline void filmic_split_v1(
const float *
const restrict in,
float *
const restrict out,
1287#pragma omp parallel for default(none) \
1288 dt_omp_firstprivate(width, height, data, in, out, work_profile, spline) \
1289 schedule(simd : static)
1293 const float *
const restrict pix_in = in + k;
1294 float *
const restrict pix_out = out + k;
1295 dt_aligned_pixel_t temp;
1298 for(
int c = 0; c < 3; c++)
1303 const float lum = (work_profile)
1305 work_profile->unbounded_coeffs_in,
1313 for(
int c = 0; c < 3; c++)
1316 spline.
M1, spline.
M2, spline.
M3, spline.
M4, spline.
M5,
1318 spline.
y[0], spline.
y[4]),
1331#pragma omp parallel for default(none) \
1332 dt_omp_firstprivate(width, height, data, in, out, work_profile, spline) \
1333 schedule(simd : static)
1337 const float *
const restrict pix_in = in + k;
1338 float *
const restrict pix_out = out + k;
1339 dt_aligned_pixel_t temp;
1342 for(
int c = 0; c < 3; c++)
1347 const float lum = (work_profile)
1349 work_profile->unbounded_coeffs_in,
1357 for(
int c = 0; c < 3; c++)
1360 spline.
M1, spline.
M2, spline.
M3, spline.
M4, spline.
M5,
1362 spline.
y[0], spline.
y[4]),
1375#pragma omp parallel for default(none) \
1376 dt_omp_firstprivate(width, height, data, in, out, work_profile, variant, spline) schedule(simd : static)
1380 const float *
const restrict pix_in = in + k;
1381 float *
const restrict pix_out = out + k;
1383 dt_aligned_pixel_t ratios = { 0.0f };
1388 ratios[c] = pix_in[c] / norm;
1391 const float min_ratios = fminf(fminf(ratios[0], ratios[1]), ratios[2]);
1392 if(min_ratios < 0.0f)
1404 ratios, work_profile->
matrix_in, work_profile->
lut_in, work_profile->unbounded_coeffs_in,
1409 for(
int c = 0; c < 3; c++) ratios[c] =
linear_saturation(ratios[c], lum, desaturation) / norm;
1415 spline.
y[0], spline.
y[4]),
1428 const size_t width,
const size_t height,
const size_t ch,
1433#pragma omp parallel for default(none) \
1434 dt_omp_firstprivate(width, height, ch, data, in, out, work_profile, variant, spline, colorscience_version) \
1435 schedule(simd :static)
1437 for(
size_t k = 0; k <
height *
width * ch; k += ch)
1439 const float *
const restrict pix_in = in + k;
1440 float *
const restrict pix_out = out + k;
1445 dt_aligned_pixel_t ratios = { 0.0f };
1448 ratios[c] = pix_in[c] / norm;
1451 const float min_ratios = fminf(fminf(ratios[0], ratios[1]), ratios[2]);
1452 const int sanitize = (min_ratios < 0.0f);
1456 ratios[c] -= min_ratios;
1468 spline.
y[0], spline.
y[4]),
1472 for(
int c = 0; c < 3; c++) ratios[c] = fmaxf(ratios[c] + (1.0f - ratios[c]) * (1.0f - desaturation), 0.0f);
1480 pix_out[c] = ratios[c] * norm;
1483 const float max_pix = fmaxf(fmaxf(pix_out[0], pix_out[1]), pix_out[2]);
1484 const int penalize = (max_pix > 1.0f);
1491 ratios[c] = fmaxf(ratios[c] + (1.0f - max_pix), 0.0f);
1492 pix_out[c] = ratios[c] * norm;
1500#pragma omp declare simd uniform(matrix) aligned(in, out:16) aligned(matrix:64)
1504 dt_aligned_pixel_t LMS = { 0.f };
1505 dt_aligned_pixel_t Yrg = { 0.f };
1519#pragma omp declare simd uniform(matrix) aligned(in, out:16) aligned(matrix:64)
1523 dt_aligned_pixel_t LMS = { 0.f };
1524 dt_aligned_pixel_t Yrg = { 0.f };
1536static inline void filmic_desaturate_v4(
const dt_aligned_pixel_t Ych_original, dt_aligned_pixel_t Ych_final,
const float saturation)
1544 const float chroma_original = Ych_original[1] * Ych_original[0];
1545 float chroma_final = Ych_final[1] * Ych_final[0];
1554 const float delta_chroma = saturation * (chroma_original - chroma_final);
1556 const int filmic_brightens = (Ych_final[0] > Ych_original[0]);
1557 const int filmic_resat = (chroma_original < chroma_final);
1558 const int filmic_desat = (chroma_original > chroma_final);
1559 const int user_resat = (saturation > 0.f);
1560 const int user_desat = (saturation < 0.f);
1562 chroma_final = (filmic_brightens && filmic_resat)
1563 ? (chroma_original + chroma_final) / 2.f
1564 : ((user_resat && filmic_desat) || user_desat)
1565 ? chroma_final + delta_chroma
1568 Ych_final[1] = fmaxf(chroma_final / Ych_final[0], 0.f);
1577#define CIE_Y_1931_to_CIE_Y_2006(x) (1.05785528f * (x))
1581 const float cos_h,
const float sin_h)
1583 const float denominator_Y_coeff = coeffs[0] * (0.979381443298969f * cos_h + 0.391752577319588f * sin_h)
1584 + coeffs[1] * (0.0206185567010309f * cos_h + 0.608247422680412f * sin_h)
1585 - coeffs[2] * (cos_h + sin_h);
1586 const float denominator_target_term = target_white * (0.68285981628866f * cos_h + 0.482137060515464f * sin_h);
1589 if(denominator_Y_coeff == 0.f)
return FLT_MAX;
1594 const float Y_asymptote = denominator_target_term / denominator_Y_coeff;
1595 if(Y <= Y_asymptote)
return FLT_MAX;
1601 const float denominator = Y * denominator_Y_coeff - denominator_target_term;
1602 const float numerator = -0.427506877216495f
1603 * (Y * (coeffs[0] + 0.856492345150334f * coeffs[1] + 0.554995960637719f * coeffs[2])
1604 - 0.988237752433297f * target_white);
1606 return numerator / denominator;
1610static inline float clip_chroma_white(
const float coeffs[3],
const float target_white,
const float Y,
1611 const float cos_h,
const float sin_h)
1617 const float eps = 1e-3f;
1619 const float delta_Y =
MAX(max_Y - Y, 0.f);
1629 return max_chroma >= 0.f ? max_chroma : FLT_MAX;
1642 const float denominator = coeffs[0] * (0.979381443298969f * cos_h + 0.391752577319588f * sin_h)
1643 + coeffs[1] * (0.0206185567010309f * cos_h + 0.608247422680412f * sin_h)
1644 - coeffs[2] * (cos_h + sin_h);
1647 if(denominator == 0.f)
return FLT_MAX;
1649 const float numerator = -0.427506877216495f * (coeffs[0] + 0.856492345150334f * coeffs[1] + 0.554995960637719f * coeffs[2]);
1650 const float max_chroma = numerator / denominator;
1651 return max_chroma >= 0.f ? max_chroma : FLT_MAX;
1656 const float cos_h,
const float sin_h,
const float chroma)
1664 const float chroma_R_white =
clip_chroma_white(matrix_out[0], target_white, Y, cos_h, sin_h);
1665 const float chroma_G_white =
clip_chroma_white(matrix_out[1], target_white, Y, cos_h, sin_h);
1666 const float chroma_B_white =
clip_chroma_white(matrix_out[2], target_white, Y, cos_h, sin_h);
1667 const float max_chroma_white =
MIN(
MIN(chroma_R_white, chroma_G_white), chroma_B_white);
1672 const float max_chroma_black =
MIN(
MIN(chroma_R_black, chroma_G_black), chroma_B_black);
1674 return MIN(
MIN(chroma, max_chroma_black), max_chroma_white);
1679 const float display_black,
const float display_white,
1680 const dt_aligned_pixel_t Ych_in, dt_aligned_pixel_t RGB_out)
1684 dt_aligned_pixel_t RGB_brightened = { 0.f };
1686 const float min_pix =
MIN(
MIN(RGB_brightened[0], RGB_brightened[1]), RGB_brightened[2]);
1687 const float black_offset =
MAX(-min_pix, 0.f);
1689 dt_aligned_pixel_t Ych_brightened = { 0.f };
1698 const float cos_h = cosf(Ych_in[2]);
1699 const float sin_h = sinf(Ych_in[2]);
1700 const float new_chroma =
clip_chroma(matrix_out, display_white, Y, cos_h, sin_h, Ych_in[1]);
1703 const dt_aligned_pixel_t Ych = { Y, new_chroma, Ych_in[2], 0.f };
1707 for_each_channel(c, aligned(RGB_out)) RGB_out[c] = CLAMP(RGB_out[c], 0.f, display_white);
1712#pragma omp declare simd uniform(input_matrix, output_matrix, export_input_matrix, export_output_matrix, use_output_profile) \
1713 aligned(Ych_final, Ych_original, pix_out:16) aligned(input_matrix, output_matrix, export_input_matrix, export_output_matrix:64)
1715static inline void gamut_mapping(dt_aligned_pixel_t Ych_final, dt_aligned_pixel_t Ych_original, dt_aligned_pixel_t pix_out,
1718 const float display_black,
const float display_white,
const float saturation,
1719 const int use_output_profile)
1722 Ych_final[2] = Ych_original[2];
1725 Ych_final[0] = CLAMP(Ych_final[0],
1733 if(!use_output_profile)
1737 gamut_check_RGB(input_matrix, output_matrix, display_black, display_white, Ych_final, pix_out);
1743 gamut_check_RGB(export_input_matrix, export_output_matrix, display_black, display_white, Ych_final, pix_out);
1746 dt_aligned_pixel_t LMS = { 0.f };
1772 const int use_output_profile = (export_profile != NULL);
1773 if(use_output_profile)
1784 return use_output_profile;
1788#pragma omp declare simd uniform(work_profile, data, spline, norm_min, norm_max, display_black, display_white, type) \
1789 aligned(pix_in, pix_out:16)
1796 const float norm_min,
const float norm_max,
1797 const float display_black,
const float display_white)
1806 dt_aligned_pixel_t ratios = { 0.0f };
1825#pragma omp declare simd uniform(data, spline, display_black, display_white) \
1826 aligned(pix_in, pix_out:16)
1831 const float display_black,
const float display_white)
1853 const size_t width,
const size_t height,
const size_t ch,
1855 const float display_black,
const float display_white)
1864 export_output_matrix, work_profile, export_profile);
1870#pragma omp parallel for default(none) \
1871 dt_omp_firstprivate(width, height, ch, data, in, out, work_profile, input_matrix, output_matrix, \
1872 variant, spline, display_white, display_black, export_input_matrix, export_output_matrix, \
1873 use_output_profile, norm_min, norm_max) \
1874 schedule(simd :static)
1876 for(
size_t k = 0; k <
height *
width * ch; k += ch)
1878 const float *
const restrict pix_in = in + k;
1879 float *
const restrict pix_out = out + k;
1881 norm_tone_mapping_v4(pix_in, pix_out, variant, work_profile, data, spline, norm_min, norm_max, display_black, display_white);
1884 dt_aligned_pixel_t Ych_original = { 0.f };
1888 dt_aligned_pixel_t Ych_final = { 0.f };
1891 gamut_mapping(Ych_final, Ych_original, pix_out, input_matrix, output_matrix, export_input_matrix,
1892 export_output_matrix, display_black, display_white, data->
saturation, use_output_profile);
1896static inline void filmic_split_v4(
const float *
const restrict in,
float *
const restrict out,
1901 const size_t width,
const size_t height,
const size_t ch,
1903 const float display_black,
const float display_white)
1913 export_output_matrix, work_profile, export_profile);
1915#pragma omp parallel for default(none) \
1916 dt_omp_firstprivate(width, height, ch, data, in, out, work_profile, input_matrix, output_matrix, \
1917 variant, spline, display_white, display_black, export_input_matrix, export_output_matrix, \
1918 use_output_profile) \
1919 schedule(simd :static)
1921 for(
size_t k = 0; k <
height *
width * ch; k += ch)
1923 const float *
const restrict pix_in = in + k;
1924 float *
const restrict pix_out = out + k;
1929 dt_aligned_pixel_t Ych_original = { 0.f };
1933 dt_aligned_pixel_t Ych_final = { 0.f };
1936 Ych_final[1] = fminf(Ych_original[1], Ych_final[1]);
1938 gamut_mapping(Ych_final, Ych_original, pix_out, input_matrix, output_matrix, export_input_matrix,
1939 export_output_matrix, display_black, display_white, data->
saturation, use_output_profile);
1944static inline void filmic_v5(
const float *
const restrict in,
float *
const restrict out,
1949 const size_t width,
const size_t height,
const size_t ch,
1950 const float display_black,
const float display_white)
1960 export_output_matrix, work_profile, export_profile);
1966#pragma omp parallel for default(none) \
1967 dt_omp_firstprivate(width, height, ch, data, in, out, work_profile, input_matrix, output_matrix, \
1968 spline, display_white, display_black, norm_min, norm_max, export_input_matrix, export_output_matrix, \
1969 use_output_profile) \
1970 schedule(simd :static)
1972 for(
size_t k = 0; k <
height *
width * ch; k += ch)
1974 const float *
const restrict pix_in = in + k;
1975 float *
const restrict pix_out = out + k;
1977 dt_aligned_pixel_t max_rgb = { 0.f };
1978 dt_aligned_pixel_t naive_rgb = { 0.f };
1985 pix_out[c] = (0.5f - data->
saturation) * naive_rgb[c] + (0.5f + data->
saturation) * max_rgb[c];
1988 dt_aligned_pixel_t Ych_original = { 0.f };
1992 dt_aligned_pixel_t Ych_final = { 0.f };
1995 Ych_final[1] = fminf(Ych_original[1], Ych_final[1]);
1997 gamut_mapping(Ych_final, Ych_original, pix_out, input_matrix, output_matrix, export_input_matrix,
1998 export_output_matrix, display_black, display_white, 0.f, use_output_profile);
2003static inline void display_mask(
const float *
const restrict mask,
float *
const restrict out,
const size_t width,
2007#pragma omp parallel for default(none) dt_omp_firstprivate(width, height, out, mask) schedule(static)
2012 out[4*k+c] = mask[k];
2017static inline void compute_ratios(
const float *
const restrict in,
float *
const restrict norms,
2018 float *
const restrict ratios,
2023#pragma omp parallel for default(none) \
2024 dt_omp_firstprivate(width, height, norms, ratios, in, work_profile, variant) schedule(static)
2029 norms[k / 4] = norm;
2031 ratios[k + c] = in[k + c] / norm;
2036static inline void restore_ratios(
float *
const restrict ratios,
const float *
const restrict norms,
2040 #pragma omp parallel for default(none) \
2041 dt_omp_firstprivate(width, height, norms, ratios) \
2042 schedule(simd:static)
2046 ratios[4*k + c] =
clamp_simd(ratios[4*k + c]) * norms[k];
2053 const int scales =
get_scales(roi_in, piece);
2054 const int max_filter_radius = (1 << scales);
2058 tiling->factor_cl = 9.0f;
2061 tiling->maxbuf_cl = 1.0f;
2063 tiling->overlap = max_filter_radius;
2082 const size_t ch = 4;
2093 float *restrict in = (
float *)ivoid;
2094 float *
const restrict out = (
float *)ovoid;
2098 const float scale = fmaxf(piece->
iscale / roi_in->
scale, 1.f);
2119 if(recover_highlights && mask && reconstructed)
2129 gint success_2 =
TRUE;
2145 success_2 = success_2
2147 data, piece, roi_in, roi_out);
2156 if(success_1 && success_2) in = reconstructed;
2161 const float white_display = powf(data->spline.y[4], data->
output_power);
2162 const float black_display = powf(data->spline.y[0], data->
output_power);
2166 filmic_v5(in, out, work_profile, export_profile, data, data->spline, roi_out->
width,
2167 roi_out->
height, ch, black_display, white_display);
2180 roi_out->
height, ch, data->
version, black_display, white_display);
2193 roi_out->
height, ch, data->
version, black_display, white_display);
2204static inline cl_int reconstruct_highlights_cl(cl_mem in, cl_mem mask, cl_mem reconstructed,
2210 const int devid = piece->
pipe->devid;
2213 size_t sizes[] = { ROUNDUPDWD(
width, devid), ROUNDUPDHT(
height, devid), 1 };
2216 const int scales =
get_scales(roi_in, piece);
2219 cl_mem LF_even = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float) * 4);
2220 cl_mem LF_odd = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float) * 4);
2221 cl_mem HF_RGB = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float) * 4);
2222 cl_mem HF_grey = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float) * 4);
2225 cl_mem temp = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float) * 4);;
2227 if(!LF_even || !LF_odd || !HF_RGB || !HF_grey || !temp)
2229 dt_control_log(_(
"filmic highlights reconstruction failed to allocate memory on GPU"));
2230 err = CL_MEM_OBJECT_ALLOCATION_FAILURE;
2241 if(err != CL_SUCCESS)
goto error;
2259 for(
int s = 0; s < scales; ++s)
2281 const int mult = 1 << s;
2284 const int clamp_lf = 1;
2292 if(err != CL_SUCCESS)
goto error;
2301 if(err != CL_SUCCESS)
goto error;
2311 if(err != CL_SUCCESS)
goto error;
2314 size_t origin[] = { 0, 0, 0 };
2315 err = dt_opencl_enqueue_copy_image(devid, HF_RGB, HF_grey, origin, origin, sizes);
2316 if(err != CL_SUCCESS)
goto error;
2319 const int blur_size = 1;
2320 const int clamp_hf = 0;
2328 if(err != CL_SUCCESS)
goto error;
2337 if(err != CL_SUCCESS)
goto error;
2357 if(err != CL_SUCCESS)
goto error;
2384 const int devid = piece->
pipe->devid;
2388 size_t sizes[] = { ROUNDUPDWD(
width, devid), ROUNDUPDHT(
height, devid), 1 };
2391 cl_mem inpainted = NULL;
2392 cl_mem reconstructed = NULL;
2394 cl_mem ratios = NULL;
2395 cl_mem norms = NULL;
2400 const int use_work_profile = (work_profile == NULL) ? 0 : 1;
2409 export_output_matrix, work_profile, export_profile);
2411 const float norm_min =
exp_tonemapping_v2(0.f, d->grey_source, d->black_source, d->dynamic_range);
2412 const float norm_max =
exp_tonemapping_v2(1.f, d->grey_source, d->black_source, d->dynamic_range);
2414 cl_mem input_matrix_cl = dt_opencl_copy_host_to_device_constant(devid, 12 *
sizeof(
float), input_matrix);
2415 cl_mem output_matrix_cl = dt_opencl_copy_host_to_device_constant(devid, 12 *
sizeof(
float), output_matrix);
2416 cl_mem export_input_matrix_cl = NULL;
2417 cl_mem export_output_matrix_cl = NULL;
2419 cl_mem dev_profile_info = NULL;
2420 cl_mem dev_profile_lut = NULL;
2422 cl_float *profile_lut_cl = NULL;
2424 cl_mem clipped = NULL;
2426 err = dt_ioppr_build_iccprofile_params_cl(work_profile, devid, &profile_info_cl, &profile_lut_cl,
2427 &dev_profile_info, &dev_profile_lut);
2428 if(err != CL_SUCCESS)
goto error;
2430 if(use_output_profile)
2432 export_input_matrix_cl = dt_opencl_copy_host_to_device_constant(devid, 12 *
sizeof(
float), export_input_matrix);
2433 export_output_matrix_cl = dt_opencl_copy_host_to_device_constant(devid, 12 *
sizeof(
float), export_output_matrix);
2437 const float scale = fmaxf(piece->
iscale / roi_in->
scale, 1.f);
2439 uint32_t is_clipped = 0;
2440 clipped = dt_opencl_alloc_device_buffer(devid,
sizeof(uint32_t));
2441 err = dt_opencl_write_buffer_to_device(devid, &is_clipped, clipped, 0,
sizeof(uint32_t), CL_TRUE);
2442 if(err != CL_SUCCESS)
goto error;
2445 mask = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float));
2454 if(err != CL_SUCCESS)
goto error;
2457 err = dt_opencl_read_buffer_from_device(devid, &is_clipped, clipped, 0,
sizeof(uint32_t), CL_TRUE);
2458 if(err != CL_SUCCESS)
goto error;
2475 dt_ioppr_free_iccprofile_params_cl(&profile_info_cl, &profile_lut_cl, &dev_profile_info, &dev_profile_lut);
2483 const float noise_level = d->noise_level / scale;
2484 inpainted = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float) * 4);
2494 if(err != CL_SUCCESS)
goto error;
2497 reconstructed = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float) * 4);
2499 if(err != CL_SUCCESS)
goto error;
2503 if(d->high_quality_reconstruction > 0)
2505 ratios = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float) * 4);
2506 norms = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float));
2510 for(
int i = 0; i < d->high_quality_reconstruction; i++)
2520 if(err != CL_SUCCESS)
goto error;
2524 if(err != CL_SUCCESS)
goto error;
2533 if(err != CL_SUCCESS)
goto error;
2551 const float white_display = powf(spline.y[4], d->output_power);
2552 const float black_display = powf(spline.y[0], d->output_power);
2591 if(err != CL_SUCCESS)
goto error;
2633 if(err != CL_SUCCESS)
goto error;
2637 dt_ioppr_free_iccprofile_params_cl(&profile_info_cl, &profile_lut_cl, &dev_profile_info, &dev_profile_lut);
2645 dt_ioppr_free_iccprofile_params_cl(&profile_info_cl, &profile_lut_cl, &dev_profile_info, &dev_profile_lut);
2672 const float prev_grey = p->grey_point_source;
2673 p->grey_point_source = CLAMP(100.f * grey, 0.001f, 100.0f);
2674 const float grey_var = log2f(prev_grey / p->grey_point_source);
2675 p->black_point_source = p->black_point_source - grey_var;
2676 p->white_point_source = p->white_point_source + grey_var;
2677 p->output_power = logf(p->grey_point_target / 100.0f)
2678 / logf(-p->black_point_source / (p->white_point_source - p->black_point_source));
2687 gtk_widget_queue_draw(self->
widget);
2702 float EVmin = CLAMP(log2f(black / (p->grey_point_source / 100.0f)), -16.0f, -1.0f);
2703 EVmin *= (1.0f + p->security_factor / 100.0f);
2705 p->black_point_source = fmaxf(EVmin, -16.0f);
2706 p->output_power = logf(p->grey_point_target / 100.0f)
2707 / logf(-p->black_point_source / (p->white_point_source - p->black_point_source));
2714 gtk_widget_queue_draw(self->
widget);
2730 float EVmax = CLAMP(log2f(white / (p->grey_point_source / 100.0f)), 1.0f, 16.0f);
2731 EVmax *= (1.0f + p->security_factor / 100.0f);
2733 p->white_point_source = EVmax;
2734 p->output_power = logf(p->grey_point_target / 100.0f)
2735 / logf(-p->black_point_source / (p->white_point_source - p->black_point_source));
2742 gtk_widget_queue_draw(self->
widget);
2757 p->grey_point_source = CLAMP(100.f * grey, 0.001f, 100.0f);
2762 float EVmax = CLAMP(log2f(white / (p->grey_point_source / 100.0f)), 1.0f, 16.0f);
2763 EVmax *= (1.0f + p->security_factor / 100.0f);
2767 float EVmin = CLAMP(log2f(black / (p->grey_point_source / 100.0f)), -16.0f, -1.0f);
2768 EVmin *= (1.0f + p->security_factor / 100.0f);
2770 p->black_point_source = fmaxf(EVmin, -16.0f);
2771 p->white_point_source = EVmax;
2772 p->output_power = logf(p->grey_point_target / 100.0f)
2773 / logf(-p->black_point_source / (p->white_point_source - p->black_point_source));
2782 gtk_widget_queue_draw(self->
widget);
2790 if(picker == g->grey_point_source)
2792 else if(picker == g->black_point_source)
2794 else if(picker == g->white_point_source)
2796 else if(picker == g->auto_button)
2804 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->
off),
TRUE);
2811 g->show_mask = !(g->show_mask);
2816 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->show_highlight_mask), !g->show_mask);
2831 float grey_display = 0.4638f;
2832 gboolean clamping =
FALSE;
2837 grey_display = powf(CLAMP(p->grey_point_target, p->black_point_target, p->white_point_target) / 100.0f,
2838 1.0f / (p->output_power));
2843 grey_display = powf(0.1845f, 1.0f / (p->output_power));
2846 const float white_source = p->white_point_source;
2847 const float black_source = p->black_point_source;
2848 const float dynamic_range = white_source - black_source;
2851 const float black_log = 0.0f;
2852 const float grey_log = fabsf(p->black_point_source) / dynamic_range;
2853 const float white_log = 1.0f;
2856 float black_display, white_display;
2864 black_display = CLAMP(p->black_point_target, 0.0f, p->grey_point_target) / 100.0f;
2865 white_display = fmaxf(p->white_point_target, p->grey_point_target) / 100.0f;
2870 black_display = powf(CLAMP(p->black_point_target, 0.0f, p->grey_point_target) / 100.0f,
2871 1.0f / (p->output_power));
2873 = powf(fmaxf(p->white_point_target, p->grey_point_target) / 100.0f, 1.0f / (p->output_power));
2876 float toe_log, shoulder_log, toe_display, shoulder_display, contrast;
2877 float balance = CLAMP(p->balance, -50.0f, 50.0f) / 100.0f;
2880 float latitude = CLAMP(p->latitude, 0.0f, 100.0f) / 100.0f * dynamic_range;
2881 contrast = CLAMP(p->contrast, 1.00001f, 6.0f);
2885 toe_log = grey_log - latitude / dynamic_range * fabsf(black_source / dynamic_range);
2886 shoulder_log = grey_log + latitude / dynamic_range * fabsf(white_source / dynamic_range);
2889 float linear_intercept = grey_display - (contrast * grey_log);
2892 toe_display = (toe_log * contrast + linear_intercept);
2893 shoulder_display = (shoulder_log * contrast + linear_intercept);
2896 const float norm = sqrtf(contrast * contrast + 1.0f);
2899 const float coeff = -((2.0f * latitude) / dynamic_range) * balance;
2901 toe_display += coeff * contrast / norm;
2902 shoulder_display += coeff * contrast / norm;
2903 toe_log += coeff / norm;
2904 shoulder_log += coeff / norm;
2908 const float hardness = p->output_power;
2910 float latitude = CLAMP(p->latitude, 0.0f, 100.0f) / 100.0f;
2911 float slope = p->contrast * dynamic_range / 8.0f;
2912 float min_contrast = 1.0f;
2914 min_contrast = fmaxf(min_contrast, (white_display - grey_display) / (white_log - grey_log));
2916 min_contrast = fmaxf(min_contrast, (grey_display - black_display) / (grey_log - black_log));
2925 contrast = slope / (hardness * powf(grey_display, hardness - 1.0f));
2926 float clamped_contrast = CLAMP(contrast, min_contrast, 100.0f);
2927 clamping = (clamped_contrast != contrast);
2928 contrast = clamped_contrast;
2931 float linear_intercept = grey_display - (contrast * grey_log);
2937 const float xmin = (black_display +
SAFETY_MARGIN * (white_display - black_display) - linear_intercept) / contrast;
2938 const float xmax = (white_display -
SAFETY_MARGIN * (white_display - black_display) - linear_intercept) / contrast;
2942 toe_log = (1.0f - latitude) * grey_log + latitude * xmin;
2943 shoulder_log = (1.0f - latitude) * grey_log + latitude * xmax;
2947 float balance_correction = (balance > 0.0f) ? 2.0f * balance * (shoulder_log - grey_log)
2948 : 2.0f * balance * (grey_log - toe_log);
2949 toe_log -= balance_correction;
2950 shoulder_log -= balance_correction;
2951 toe_log = fmaxf(toe_log, xmin);
2952 shoulder_log = fminf(shoulder_log, xmax);
2955 toe_display = (toe_log * contrast + linear_intercept);
2956 shoulder_display = (shoulder_log * contrast + linear_intercept);
2970 spline->
x[0] = black_log;
2971 spline->
x[1] = toe_log;
2972 spline->
x[2] = grey_log;
2973 spline->
x[3] = shoulder_log;
2974 spline->
x[4] = white_log;
2976 spline->
y[0] = black_display;
2977 spline->
y[1] = toe_display;
2978 spline->
y[2] = grey_display;
2979 spline->
y[3] = shoulder_display;
2980 spline->
y[4] = white_display;
2985 spline->
type[0] = p->shadows;
2986 spline->
type[1] = p->highlights;
2993 const double Tl = spline->
x[1];
2994 const double Tl2 = Tl * Tl;
2995 const double Tl3 = Tl2 * Tl;
2996 const double Tl4 = Tl3 * Tl;
2998 const double Sl = spline->
x[3];
2999 const double Sl2 = Sl * Sl;
3000 const double Sl3 = Sl2 * Sl;
3001 const double Sl4 = Sl3 * Sl;
3011 spline->
M2[2] = contrast;
3012 spline->
M1[2] = spline->
y[1] - spline->
M2[2] * spline->
x[1];
3013 spline->
M3[2] = 0.f;
3014 spline->
M4[2] = 0.f;
3015 spline->
M5[2] = 0.f;
3023 Tl4, Tl3, Tl2, Tl, 1.,
3024 4. * Tl3, 3. * Tl2, 2. * Tl, 1., 0.,
3025 12. * Tl2, 6. * Tl, 2., 0., 0. };
3027 double b0[
ORDER_4] = { spline->
y[0], 0., spline->
y[1], spline->
M2[2], 0. };
3031 spline->
M5[0] = b0[0];
3032 spline->
M4[0] = b0[1];
3033 spline->
M3[0] = b0[2];
3034 spline->
M2[0] = b0[3];
3035 spline->
M1[0] = b0[4];
3042 3. * Tl2, 2. * Tl, 1., 0.,
3043 6. * Tl, 2., 0., 0. };
3045 double b0[
ORDER_3] = { spline->
y[0], spline->
y[1], spline->
M2[2], 0. };
3049 spline->
M5[0] = 0.0f;
3050 spline->
M4[0] = b0[0];
3051 spline->
M3[0] = b0[1];
3052 spline->
M2[0] = b0[2];
3053 spline->
M1[0] = b0[3];
3057 const float P1[2] = { black_log, black_display };
3058 const float P0[2] = { toe_log, toe_display };
3059 const float x = P0[0] - P1[0];
3060 const float y = P0[1] - P1[1];
3061 const float g = contrast;
3062 const float b = g / (2.f * y) + (sqrtf(
sqf(x * g / y + 1.f) - 4.f) - 1.f) / (2.f * x);
3063 const float c = y / g * (b *
sqf(x) + x) / (b *
sqf(x) + x - (y / g));
3064 const float a = c * g;
3068 spline->
M4[0] = toe_display;
3077 3. * Sl2, 2. * Sl, 1., 0.,
3078 6. * Sl, 2., 0., 0. };
3080 double b1[
ORDER_3] = { spline->
y[4], spline->
y[3], spline->
M2[2], 0. };
3084 spline->
M5[1] = 0.0f;
3085 spline->
M4[1] = b1[0];
3086 spline->
M3[1] = b1[1];
3087 spline->
M2[1] = b1[2];
3088 spline->
M1[1] = b1[3];
3095 Sl4, Sl3, Sl2, Sl, 1.,
3096 4. * Sl3, 3. * Sl2, 2. * Sl, 1., 0.,
3097 12. * Sl2, 6. * Sl, 2., 0., 0. };
3099 double b1[
ORDER_4] = { spline->
y[4], 0., spline->
y[3], spline->
M2[2], 0. };
3103 spline->
M5[1] = b1[0];
3104 spline->
M4[1] = b1[1];
3105 spline->
M3[1] = b1[2];
3106 spline->
M2[1] = b1[3];
3107 spline->
M1[1] = b1[4];
3111 const float P1[2] = { white_log, white_display };
3112 const float P0[2] = { shoulder_log, shoulder_display };
3113 const float x = P1[0] - P0[0];
3114 const float y = P1[1] - P0[1];
3115 const float g = contrast;
3116 const float b = g / (2.f * y) + (sqrtf(
sqf(x * g / y + 1.f) - 4.f) - 1.f) / (2.f * x);
3117 const float c = y / g * (b *
sqf(x) + x) / (b *
sqf(x) + x - (y / g));
3118 const float a = c * g;
3122 spline->
M4[1] = shoulder_display;
3134 float grey_source = 0.1845f, grey_display = 0.4638f;
3138 grey_source = p->grey_point_source / 100.0f;
3139 grey_display = powf(p->grey_point_target / 100.0f, 1.0f / (p->output_power));
3144 grey_source = 0.1845f;
3145 grey_display = powf(0.1845f, 1.0f / (p->output_power));
3149 const float white_source = p->white_point_source;
3150 const float black_source = p->black_point_source;
3151 const float dynamic_range = white_source - black_source;
3154 const float grey_log = fabsf(p->black_point_source) / dynamic_range;
3157 float contrast = p->contrast;
3162 contrast = 1.0001f * grey_display / grey_log;
3184 d->
saturation = (2.0f * p->saturation / 100.0f + 1.0f);
3186 d->
sigma_toe = powf(d->spline.latitude_min / 3.0f, 2.0f);
3187 d->
sigma_shoulder = powf((1.0f - d->spline.latitude_max) / 3.0f, 2.0f);
3206 gint mask_was_shown = g->show_mask;
3207 g->show_mask =
FALSE;
3208 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->show_highlight_mask),
FALSE);
3233 g->show_mask =
FALSE;
3234 g->gui_mode =
dt_conf_get_int(
"plugins/darkroom/filmicrgb/graph_view");
3235 g->gui_show_labels =
dt_conf_get_int(
"plugins/darkroom/filmicrgb/graph_show_labels");
3236 g->gui_hover =
FALSE;
3237 g->gui_sizes_inited =
FALSE;
3241 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->auto_hardness), p->auto_hardness);
3242 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->custom_grey), p->custom_grey);
3253 d->
output_power =
module->so->get_f("output_power")->Float.Default;
3269 module->workflow_enabled = TRUE;
3276 const int program = 22;
3291 const int wavelets = 35;
3313 module->data = NULL;
3325 double destination_y, gboolean show_head)
3327 cairo_move_to(cr, origin_x, origin_y);
3328 cairo_line_to(cr, destination_x, destination_y);
3334 const float angle_arrow = 45.f / 360.f *
M_PI;
3335 const float angle_trunk = atan2f((destination_y - origin_y), (destination_x - origin_x));
3338 const float x_1 = destination_x + radius / sinf(angle_arrow + angle_trunk);
3339 const float y_1 = destination_y + radius / cosf(angle_arrow + angle_trunk);
3341 const float x_2 = destination_x - radius / sinf(-angle_arrow + angle_trunk);
3342 const float y_2 = destination_y - radius / cosf(-angle_arrow + angle_trunk);
3344 cairo_move_to(cr, x_1, y_1);
3345 cairo_line_to(cr, destination_x, destination_y);
3346 cairo_line_to(cr, x_2, y_2);
3354 if(!g->gui_sizes_inited)
return;
3369 cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha);
3374 cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha * 0.5);
3384 const float scale = 0.85;
3385 cairo_scale(cr, scale, scale);
3386 button->
icon(cr, -scale * button->
w / 2., -scale * button->
h / 2., scale * button->
w, scale * button->
h, 0, NULL);
3399 gtk_widget_get_allocation(widget, &g->allocation);
3401 cairo_surface_t *cst =
3403 PangoFontDescription *desc =
3405 cairo_t *cr = cairo_create(cst);
3406 PangoLayout *layout = pango_cairo_create_layout(cr);
3408 pango_layout_set_font_description(layout, desc);
3409 pango_cairo_context_set_resolution(pango_layout_get_context(layout),
darktable.
gui->
dpi);
3410 g->context = gtk_widget_get_style_context(widget);
3415 const gint font_size = pango_font_description_get_size(desc);
3416 pango_font_description_set_size(desc, 0.95 * font_size);
3417 pango_layout_set_font_description(layout, desc);
3420 g_strlcpy(text,
"X",
sizeof(text));
3421 pango_layout_set_text(layout, text, -1);
3422 pango_layout_get_pixel_extents(layout, &g->ink, NULL);
3423 g->line_height = g->ink.height;
3426 g_strlcpy(text,
"-",
sizeof(text));
3427 pango_layout_set_text(layout, text, -1);
3428 pango_layout_get_pixel_extents(layout, &g->ink, NULL);
3429 g->sign_width = g->ink.width / 2.0;
3432 g_strlcpy(text,
"0",
sizeof(text));
3433 pango_layout_set_text(layout, text, -1);
3434 pango_layout_get_pixel_extents(layout, &g->ink, NULL);
3435 g->zero_width = g->ink.width;
3441 float margin_bottom;
3442 if(g->gui_show_labels)
3445 margin_left = 3. * g->zero_width + 2. * g->inset;
3446 margin_bottom = 2. * g->line_height + 4. * g->inset;
3450 margin_left = g->inset;
3451 margin_bottom = g->inset;
3454 const float margin_top = 2. * g->line_height + g->inset;
3457 g->graph_width = g->allocation.width - margin_right - margin_left;
3458 g->graph_height = g->allocation.height - margin_bottom - margin_top;
3460 gtk_render_background(g->context, cr, 0, 0, g->allocation.width, g->allocation.height);
3466 g->buttons[i].right = g->allocation.width;
3470 g->buttons[i].w = g->buttons[i].right - g->buttons[i].left;
3471 g->buttons[i].h = g->buttons[i].bottom - g->buttons[i].top;
3472 g->buttons[i].state = GTK_STATE_FLAG_NORMAL;
3475 g->gui_sizes_inited =
TRUE;
3485 const float grey = p->grey_point_source / 100.f;
3486 const float DR = p->white_point_source - p->black_point_source;
3489 cairo_translate(cr, margin_left, margin_top);
3491 cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
3494 pango_font_description_set_size(desc, font_size);
3495 pango_layout_set_font_description(layout, desc);
3497 g_strlcpy(text, _(
"look only"),
sizeof(text));
3499 g_strlcpy(text, _(
"look + mapping (lin)"),
sizeof(text));
3501 g_strlcpy(text, _(
"look + mapping (log)"),
sizeof(text));
3503 g_strlcpy(text, _(
"dynamic range mapping"),
sizeof(text));
3505 pango_layout_set_text(layout, text, -1);
3506 pango_layout_get_pixel_extents(layout, &g->ink, NULL);
3510 cairo_rectangle(cr, g->allocation.width - margin_left - g->ink.width - g->ink.x - 2. * g->inset,
3511 -g->line_height - g->inset - 0.5 * g->ink.height - g->ink.y - g->inset,
3512 g->ink.width + 3. * g->inset, g->ink.height + 2. * g->inset);
3517 cairo_move_to(cr, g->allocation.width - margin_left - g->ink.width - g->ink.x - g->inset,
3518 -g->line_height - g->inset - 0.5 * g->ink.height - g->ink.y);
3519 pango_cairo_show_layout(cr, layout);
3523 pango_font_description_set_size(desc, 0.95 * font_size);
3524 pango_layout_set_font_description(layout, desc);
3530 cairo_rectangle(cr, 0, 0, g->graph_width, g->graph_height);
3532 cairo_fill_preserve(cr);
3542 cairo_scale(cr, 1., -1.);
3543 cairo_translate(cr, 0., -g->graph_height);
3546 dt_draw_grid(cr, 4, 0, 0, g->graph_width, g->graph_height);
3554 cairo_move_to(cr, 0, g->graph_height);
3555 cairo_line_to(cr, g->graph_width, 0);
3561 const float saturation = (2.0f * p->saturation / 100.0f + 1.0f);
3562 const float sigma_toe = powf(g->spline.latitude_min / 3.0f, 2.0f);
3563 const float sigma_shoulder = powf((1.0f - g->spline.latitude_max) / 3.0f, 2.0f);
3565 cairo_set_source_rgb(cr, .5, .5, .5);
3575 cairo_move_to(cr, 0,
3577 for(
int k = 1; k < 256; k++)
3579 float x = k / 255.0;
3587 cairo_line_to(cr, x * g->graph_width, g->graph_height * (1.0 - y));
3592 cairo_move_to(cr, 0,
3594 for(
int k = 1; k < 256; k++)
3596 float x = k / 255.0;
3604 cairo_line_to(cr, x * g->graph_width, g->graph_height * (1.0 - y));
3610 float x_start = 0.f;
3617 g->spline.M5, g->spline.latitude_min, g->spline.latitude_max, g->spline.type));
3620 y_start = powf(y_start, p->output_power);
3624 cairo_move_to(cr, 0, g->graph_height * (1.0 - y_start));
3626 for(
int k = 1; k < 256; k++)
3630 float x = powf(k / 255.0f, 2.4f);
3638 float y =
filmic_spline(value, g->spline.M1, g->spline.M2, g->spline.M3, g->spline.M4, g->spline.M5,
3639 g->spline.latitude_min, g->spline.latitude_max, g->spline.type);
3647 const float margin = 1
E-5;
3648 if(y > g->spline.y[4] + margin)
3651 cairo_set_source_rgb(cr, 0.75, .5, 0.);
3653 else if(y < g->spline.y[0] - margin)
3656 cairo_set_source_rgb(cr, 0.75, .5, 0.);
3664 y = powf(y, p->output_power);
3668 cairo_line_to(cr, x * g->graph_width, g->graph_height * (1.0 - y));
3670 cairo_move_to(cr, x * g->graph_width, g->graph_height * (1.0 - y));
3682 float x_grey = g->spline.x[2];
3683 float y_grey = g->spline.y[2];
3688 y_grey = powf(y_grey, p->output_power);
3696 cairo_set_source_rgb(cr, 0.75, 0.5, 0.0);
3697 cairo_arc(cr, x_grey * g->graph_width, (1.0 - y_grey) * g->graph_height,
DT_PIXEL_APPLY_DPI(6), 0,
3703 float x_black = 0.f;
3704 float y_black = 0.f;
3706 float x_white = 1.f;
3707 float y_white = 1.f;
3709 const float central_slope = (g->spline.y[3] - g->spline.y[1]) * g->graph_width / ((g->spline.x[3] - g->spline.x[1]) * g->graph_height);
3710 const float central_slope_angle = atanf(central_slope) +
M_PI / 2.0f;
3712 for(
int k = 0; k < 5; k++)
3716 float x = g->spline.x[k];
3717 float y = g->spline.y[k];
3718 const float ymin = g->spline.y[0];
3719 const float ymax = g->spline.y[4];
3721 const float y_margin =
SAFETY_MARGIN * 1.1f * (ymax - ymin);
3722 gboolean red = (((k == 1) && (y - ymin <= y_margin))
3723 || ((k == 3) && (ymax - y <= y_margin)));
3724 float start_angle = 0.0f;
3725 float end_angle = 2.f *
M_PI;
3728 if(contrast_clamped)
3732 start_angle = central_slope_angle +
M_PI;
3733 end_angle = central_slope_angle;
3737 start_angle = central_slope_angle;
3738 end_angle = start_angle +
M_PI;
3745 y = powf(y, p->output_power);
3765 if(red) cairo_set_source_rgb(cr, 0.8, 0.35, 0.35);
3768 cairo_arc(cr, x * g->graph_width, (1.0 - y) * g->graph_height,
DT_PIXEL_APPLY_DPI(4), start_angle, end_angle);
3778 if(g->gui_show_labels)
3781 const float x_legend_top = g->graph_height + 0.5 * g->line_height;
3785 snprintf(text,
sizeof(text),
"%.0f", p->grey_point_target);
3786 pango_layout_set_text(layout, text, -1);
3787 pango_layout_get_pixel_extents(layout, &g->ink, NULL);
3788 cairo_move_to(cr, -2. * g->inset - g->ink.width - g->ink.x,
3789 (1.0 - y_grey) * g->graph_height - 0.5 * g->ink.height - g->ink.y);
3790 pango_cairo_show_layout(cr, layout);
3796 snprintf(text,
sizeof(text),
"%+.1f", 0.f);
3798 snprintf(text,
sizeof(text),
"%.0f", p->grey_point_source);
3800 pango_layout_set_text(layout, text, -1);
3801 pango_layout_get_pixel_extents(layout, &g->ink, NULL);
3802 cairo_move_to(cr, x_grey * g->graph_width - 0.5 * g->ink.width - g->ink.x, x_legend_top);
3803 pango_cairo_show_layout(cr, layout);
3808 snprintf(text,
sizeof(text),
"%.0f", p->black_point_target);
3809 pango_layout_set_text(layout, text, -1);
3810 pango_layout_get_pixel_extents(layout, &g->ink, NULL);
3811 cairo_move_to(cr, -2. * g->inset - g->ink.width - g->ink.x,
3812 (1.0 - y_black) * g->graph_height - 0.5 * g->ink.height - g->ink.y);
3813 pango_cairo_show_layout(cr, layout);
3818 snprintf(text,
sizeof(text),
"%.0f", p->white_point_target);
3819 pango_layout_set_text(layout, text, -1);
3820 pango_layout_get_pixel_extents(layout, &g->ink, NULL);
3821 cairo_move_to(cr, -2. * g->inset - g->ink.width - g->ink.x,
3822 (1.0 - y_white) * g->graph_height - 0.5 * g->ink.height - g->ink.y);
3823 pango_cairo_show_layout(cr, layout);
3829 snprintf(text,
sizeof(text),
"%+.1f", p->black_point_source);
3831 snprintf(text,
sizeof(text),
"%.0f", exp2f(p->black_point_source) * p->grey_point_source);
3833 pango_layout_set_text(layout, text, -1);
3834 pango_layout_get_pixel_extents(layout, &g->ink, NULL);
3835 cairo_move_to(cr, x_black * g->graph_width - 0.5 * g->ink.width - g->ink.x, x_legend_top);
3836 pango_cairo_show_layout(cr, layout);
3842 snprintf(text,
sizeof(text),
"%+.1f", p->white_point_source);
3846 snprintf(text,
sizeof(text),
"%.0f \342\206\222", 100.f);
3848 snprintf(text,
sizeof(text),
"%.0f", exp2f(p->white_point_source) * p->grey_point_source);
3851 pango_layout_set_text(layout, text, -1);
3852 pango_layout_get_pixel_extents(layout, &g->ink, NULL);
3854 fminf(x_white, 1.f) * g->graph_width - 0.5 * g->ink.width - g->ink.x
3855 + 2. * (x_white > 1.f) * g->sign_width,
3857 pango_cairo_show_layout(cr, layout);
3866 PangoStyle backup = pango_font_description_get_style(desc);
3867 pango_font_description_set_style(desc, PANGO_STYLE_ITALIC);
3868 pango_layout_set_font_description(layout, desc);
3870 snprintf(text,
sizeof(text), _(
"(%.0f %%)"), exp2f(p->white_point_source) * p->grey_point_source);
3871 pango_layout_set_text(layout, text, -1);
3872 pango_layout_get_pixel_extents(layout, &g->ink, NULL);
3873 cairo_move_to(cr, g->allocation.width - g->ink.width - g->ink.x - margin_left,
3874 g->graph_height + 3. * g->inset + g->line_height - g->ink.y);
3875 pango_cairo_show_layout(cr, layout);
3879 pango_font_description_set_style(desc, backup);
3880 pango_layout_set_font_description(layout, desc);
3886 g_strlcpy(text, _(
"% display"),
sizeof(text));
3887 pango_layout_set_text(layout, text, -1);
3888 pango_layout_get_pixel_extents(layout, &g->ink, NULL);
3889 cairo_move_to(cr, -2. * g->inset - g->zero_width - g->ink.x,
3890 -g->line_height - g->inset - 0.5 * g->ink.height - g->ink.y);
3891 pango_cairo_show_layout(cr, layout);
3898 g_strlcpy(text, _(
"EV scene"),
sizeof(text));
3902 g_strlcpy(text, _(
"% camera"),
sizeof(text));
3904 pango_layout_set_text(layout, text, -1);
3905 pango_layout_get_pixel_extents(layout, &g->ink, NULL);
3906 cairo_move_to(cr, 0.5 * g->graph_width - 0.5 * g->ink.width - g->ink.x,
3907 g->graph_height + 3. * g->inset + g->line_height - g->ink.y);
3908 pango_cairo_show_layout(cr, layout);
3915 cairo_identity_matrix(cr);
3921 const float display_DR = 12.f + log2f(p->white_point_target / 100.f);
3923 const float y_display = g->allocation.height / 3.f + g->line_height;
3924 const float y_scene = 2. * g->allocation.height / 3.f + g->line_height;
3926 const float display_top = y_display - g->line_height / 2;
3927 const float display_bottom = display_top + g->line_height;
3929 const float scene_top = y_scene - g->line_height / 2;
3930 const float scene_bottom = scene_top + g->line_height;
3934 if(g->gui_show_labels)
3938 g_strlcpy(text, _(
"display"),
sizeof(text));
3939 pango_layout_set_text(layout, text, -1);
3940 pango_layout_get_pixel_extents(layout, &g->ink, NULL);
3941 cairo_move_to(cr, 0., y_display - 0.5 * g->ink.height - g->ink.y);
3942 pango_cairo_show_layout(cr, layout);
3944 const float display_label_width = g->ink.width;
3947 g_strlcpy(text, _(
"(%)"),
sizeof(text));
3948 pango_layout_set_text(layout, text, -1);
3949 pango_layout_get_pixel_extents(layout, &g->ink, NULL);
3950 cairo_move_to(cr, 0.5 * display_label_width - 0.5 * g->ink.width - g->ink.x,
3951 display_top - 4. * g->inset - g->ink.height - g->ink.y);
3952 pango_cairo_show_layout(cr, layout);
3956 g_strlcpy(text, _(
"scene"),
sizeof(text));
3957 pango_layout_set_text(layout, text, -1);
3958 pango_layout_get_pixel_extents(layout, &g->ink, NULL);
3959 cairo_move_to(cr, 0., y_scene - 0.5 * g->ink.height - g->ink.y);
3960 pango_cairo_show_layout(cr, layout);
3962 const float scene_label_width = g->ink.width;
3965 g_strlcpy(text, _(
"(EV)"),
sizeof(text));
3966 pango_layout_set_text(layout, text, -1);
3967 pango_layout_get_pixel_extents(layout, &g->ink, NULL);
3968 cairo_move_to(cr, 0.5 * scene_label_width - 0.5 * g->ink.width - g->ink.x,
3969 scene_bottom + 2. * g->inset + 0. * g->ink.height + g->ink.y);
3970 pango_cairo_show_layout(cr, layout);
3975 dt_cairo_draw_arrow(cr, fminf(scene_label_width, display_label_width) / 2.f, y_scene - g->line_height,
3976 fminf(scene_label_width, display_label_width) / 2.f,
3977 y_display + g->line_height + g->inset,
TRUE);
3979 column_left = fmaxf(display_label_width, scene_label_width) + g->inset;
3987 const float display_HL_EV = -log2f(p->grey_point_target / p->white_point_target);
3988 const float display_LL_EV = display_DR - display_HL_EV;
3989 const float display_real_black_EV
3990 = -fmaxf(log2f(p->black_point_target / p->grey_point_target),
3991 -11.685887601778058f + display_HL_EV - log2f(p->white_point_target / 100.f));
3992 const float scene_HL_EV = p->white_point_source;
3993 const float scene_LL_EV = -p->black_point_source;
3996 const float max_DR = ceilf(fmaxf(display_HL_EV, scene_HL_EV)) + ceilf(fmaxf(display_LL_EV, scene_LL_EV));
3997 const float EV = (column_right) / max_DR;
4001 const float grey_EV = fmaxf(ceilf(display_HL_EV), ceilf(scene_HL_EV));
4005 const float display_black_x = grey_x - display_real_black_EV * EV;
4006 const float display_DR_start_x = grey_x - display_LL_EV * EV;
4007 const float display_white_x = grey_x + display_HL_EV * EV;
4009 const float scene_black_x = grey_x - scene_LL_EV * EV;
4010 const float scene_white_x = grey_x + scene_HL_EV * EV;
4011 const float scene_lat_bottom = grey_x + (g->spline.x[1] - g->spline.x[2]) * EV * DR;
4012 const float scene_lat_top = grey_x + (g->spline.x[3] - g->spline.x[2]) * EV * DR;
4020 float display_lat_bottom =
filmic_spline(g->spline.latitude_min, g->spline.M1, g->spline.M2, g->spline.M3, g->spline.M4,
4021 g->spline.M5, g->spline.latitude_min, g->spline.latitude_max, g->spline.type);
4022 display_lat_bottom = powf(fmaxf(display_lat_bottom,
NORM_MIN), p->output_power);
4025 display_lat_bottom = log2f(display_lat_bottom/ (p->grey_point_target / 100.f));
4028 if(display_lat_bottom < 0.f)
4029 display_lat_bottom = fmaxf(display_lat_bottom, -display_real_black_EV);
4030 else if(display_lat_bottom > 0.f)
4031 display_lat_bottom = fminf(display_lat_bottom, display_HL_EV);
4034 display_lat_bottom = grey_x + display_lat_bottom * EV;
4037 float display_lat_top =
filmic_spline(g->spline.latitude_max, g->spline.M1, g->spline.M2, g->spline.M3, g->spline.M4,
4038 g->spline.M5, g->spline.latitude_min, g->spline.latitude_max, g->spline.type);
4039 display_lat_top = powf(fmaxf(display_lat_top,
NORM_MIN), p->output_power);
4042 display_lat_top = log2f(display_lat_top / (p->grey_point_target / 100.f));
4045 if(display_lat_top < 0.f)
4046 display_lat_top = fmaxf(display_lat_top, -display_real_black_EV);
4047 else if(display_lat_top > 0.f)
4048 display_lat_top = fminf(display_lat_top, display_HL_EV);
4051 display_lat_top = grey_x + display_lat_top * EV;
4053 cairo_move_to(cr, scene_lat_bottom, scene_top);
4054 cairo_line_to(cr, scene_lat_top, scene_top);
4055 cairo_line_to(cr, display_lat_top, display_bottom);
4056 cairo_line_to(cr, display_lat_bottom, display_bottom);
4057 cairo_line_to(cr, scene_lat_bottom, scene_top);
4061 for(
int i = 0; i < (int)ceilf(display_DR); i++)
4064 const float shade = powf(exp2f(-11.f + (
float)i), 1.f / 2.4f);
4065 cairo_set_source_rgb(cr, shade, shade, shade);
4066 cairo_rectangle(cr, display_DR_start_x + i * EV, display_top, EV, g->line_height);
4067 cairo_fill_preserve(cr);
4070 cairo_set_source_rgb(cr, 0.75, .5, 0.);
4076 cairo_move_to(cr, grey_x, display_bottom + 2. * g->inset);
4077 cairo_line_to(cr, grey_x, display_top - 2. * g->inset);
4082 for(
int i = floorf(p->black_point_source); i < ceilf(p->white_point_source); i++)
4086 const float shade = powf(0.1845f * exp2f((
float)i), 1.f / 2.4f);
4087 const float x_temp = grey_x + i * EV;
4088 cairo_set_source_rgb(cr, shade, shade, shade);
4089 cairo_rectangle(cr, x_temp, scene_top, EV, g->line_height);
4090 cairo_fill_preserve(cr);
4093 cairo_set_source_rgb(cr, 0.75, .5, 0.);
4102 if((
float)i > p->black_point_source && (
float)i < p->white_point_source)
4105 const float normal_value = ((float)i - p->black_point_source) / DR;
4106 float y_temp =
filmic_spline(normal_value, g->spline.M1, g->spline.M2, g->spline.M3, g->spline.M4,
4107 g->spline.M5, g->spline.latitude_min, g->spline.latitude_max, g->spline.type);
4108 y_temp = powf(fmaxf(y_temp,
NORM_MIN), p->output_power);
4111 y_temp = log2f(y_temp / (p->grey_point_target / 100.f));
4115 y_temp = fmaxf(y_temp, -display_real_black_EV);
4116 else if(y_temp > 0.f)
4117 y_temp = fminf(y_temp, display_HL_EV);
4120 y_temp = grey_x + y_temp * EV;
4128 float x_temp = grey_x + p->black_point_source * EV;
4129 float y_temp = grey_x - display_real_black_EV * EV;
4132 x_temp = grey_x + p->white_point_source * EV;
4133 y_temp = grey_x + display_HL_EV * EV;
4139 cairo_move_to(cr, display_black_x, display_bottom);
4140 cairo_line_to(cr, display_black_x, display_top - 2. * g->inset);
4144 cairo_move_to(cr, grey_x, display_bottom);
4145 cairo_line_to(cr, grey_x, display_top - 2. * g->inset);
4149 cairo_move_to(cr, display_white_x, display_bottom);
4150 cairo_line_to(cr, display_white_x, display_top - 2. * g->inset);
4154 cairo_move_to(cr, scene_black_x, scene_bottom + 2. * g->inset);
4155 cairo_line_to(cr, scene_black_x, scene_top);
4159 cairo_move_to(cr, grey_x, scene_bottom + 2. * g->inset);
4160 cairo_line_to(cr, grey_x, scene_top);
4164 cairo_move_to(cr, scene_white_x, scene_bottom + 2. * g->inset);
4165 cairo_line_to(cr, scene_white_x, scene_top);
4172 snprintf(text,
sizeof(text),
"%+.1f", p->black_point_source);
4173 pango_layout_set_text(layout, text, -1);
4174 pango_layout_get_pixel_extents(layout, &g->ink, NULL);
4175 cairo_move_to(cr, scene_black_x - 0.5 * g->ink.width - g->ink.x,
4176 scene_bottom + 2. * g->inset + 0. * g->ink.height + g->ink.y);
4177 pango_cairo_show_layout(cr, layout);
4181 snprintf(text,
sizeof(text),
"%+.1f", 0.f);
4182 pango_layout_set_text(layout, text, -1);
4183 pango_layout_get_pixel_extents(layout, &g->ink, NULL);
4184 cairo_move_to(cr, grey_x - 0.5 * g->ink.width - g->ink.x,
4185 scene_bottom + 2. * g->inset + 0. * g->ink.height + g->ink.y);
4186 pango_cairo_show_layout(cr, layout);
4190 snprintf(text,
sizeof(text),
"%+.1f", p->white_point_source);
4191 pango_layout_set_text(layout, text, -1);
4192 pango_layout_get_pixel_extents(layout, &g->ink, NULL);
4193 cairo_move_to(cr, scene_white_x - 0.5 * g->ink.width - g->ink.x,
4194 scene_bottom + 2. * g->inset + 0. * g->ink.height + g->ink.y);
4195 pango_cairo_show_layout(cr, layout);
4199 snprintf(text,
sizeof(text),
"%.0f", p->black_point_target);
4200 pango_layout_set_text(layout, text, -1);
4201 pango_layout_get_pixel_extents(layout, &g->ink, NULL);
4202 cairo_move_to(cr, display_black_x - 0.5 * g->ink.width - g->ink.x,
4203 display_top - 4. * g->inset - g->ink.height - g->ink.y);
4204 pango_cairo_show_layout(cr, layout);
4208 snprintf(text,
sizeof(text),
"%.0f", p->grey_point_target);
4209 pango_layout_set_text(layout, text, -1);
4210 pango_layout_get_pixel_extents(layout, &g->ink, NULL);
4211 cairo_move_to(cr, grey_x - 0.5 * g->ink.width - g->ink.x,
4212 display_top - 4. * g->inset - g->ink.height - g->ink.y);
4213 pango_cairo_show_layout(cr, layout);
4217 snprintf(text,
sizeof(text),
"%.0f", p->white_point_target);
4218 pango_layout_set_text(layout, text, -1);
4219 pango_layout_get_pixel_extents(layout, &g->ink, NULL);
4220 cairo_move_to(cr, display_white_x - 0.5 * g->ink.width - g->ink.x,
4221 display_top - 4. * g->inset - g->ink.height - g->ink.y);
4222 pango_cairo_show_layout(cr, layout);
4227 pango_font_description_set_size(desc, font_size);
4228 pango_layout_set_font_description(layout, desc);
4231 cairo_set_source_surface(crf, cst, 0, 0);
4233 cairo_surface_destroy(cst);
4234 g_object_unref(layout);
4235 pango_font_description_free(desc);
4251 if(event->button == 1 && event->type == GDK_2BUTTON_PRESS)
4257 gtk_widget_queue_draw(GTK_WIDGET(g->area));
4258 dt_conf_set_int(
"plugins/darkroom/filmicrgb/graph_view", g->gui_mode);
4266 else if(event->button == 1)
4277 gtk_widget_queue_draw(GTK_WIDGET(g->area));
4278 dt_conf_set_int(
"plugins/darkroom/filmicrgb/graph_view", g->gui_mode);
4283 g->gui_show_labels = !g->gui_show_labels;
4284 gtk_widget_queue_draw(GTK_WIDGET(g->area));
4285 dt_conf_set_int(
"plugins/darkroom/filmicrgb/graph_show_labels", g->gui_show_labels);
4295 else if(event->button == 3)
4305 gtk_widget_queue_draw(GTK_WIDGET(g->area));
4306 dt_conf_set_int(
"plugins/darkroom/filmicrgb/graph_view", g->gui_mode);
4311 g->gui_show_labels = !g->gui_show_labels;
4312 gtk_widget_queue_draw(GTK_WIDGET(g->area));
4313 dt_conf_set_int(
"plugins/darkroom/filmicrgb/graph_show_labels", g->gui_show_labels);
4333 g->gui_hover =
TRUE;
4334 gtk_widget_queue_draw(GTK_WIDGET(g->area));
4346 g->gui_hover =
FALSE;
4347 gtk_widget_queue_draw(GTK_WIDGET(g->area));
4357 if(!g->gui_sizes_inited)
return FALSE;
4360 const float y =
event->y;
4361 const float x =
event->x;
4363 if(x > 0. && x < g->allocation.width && y > 0. && y < g->allocation.height) g->gui_hover =
TRUE;
4365 gint save_active_button = g->active_button;
4370 gint found_something =
FALSE;
4374 if(x > g->buttons[i].left && x < g->buttons[i].right && y > g->buttons[i].top && y < g->buttons[i].bottom)
4377 g->buttons[i].mouse_hover =
TRUE;
4378 g->active_button = i;
4379 found_something =
TRUE;
4384 g->buttons[i].mouse_hover =
FALSE;
4394 gtk_widget_set_tooltip_text(GTK_WIDGET(g->area), _(
"use the parameters below to set the nodes.\n"
4395 "the bright curve is the filmic tone mapping curve\n"
4396 "the dark curve is the desaturation curve."));
4400 gtk_widget_set_tooltip_text(GTK_WIDGET(g->area), _(
"toggle axis labels and values display"));
4404 gtk_widget_set_tooltip_text(GTK_WIDGET(g->area), _(
"cycle through graph views.\n"
4405 "left click: cycle forward.\n"
4406 "right click: cycle backward.\n"
4407 "double-click: reset to look view."));
4411 gtk_widget_set_tooltip_text(GTK_WIDGET(g->area),
"");
4414 if(save_active_button != g->active_button) gtk_widget_queue_draw(GTK_WIDGET(g->area));
4420 if(save_active_button != g->active_button) (GTK_WIDGET(g->area));
4433 const int aspect =
dt_conf_get_int(
"plugins/darkroom/filmicrgb/aspect_percent");
4434 dt_conf_set_int(
"plugins/darkroom/filmicrgb/aspect_percent", aspect + delta_y);
4446 g->show_mask =
FALSE;
4448 g->gui_show_labels =
TRUE;
4449 g->gui_hover =
FALSE;
4450 g->gui_sizes_inited =
FALSE;
4453 const float aspect =
dt_conf_get_int(
"plugins/darkroom/filmicrgb/aspect_percent") / 100.0;
4455 g_object_set_data(G_OBJECT(g->area),
"iop-instance", self);
4457 gtk_widget_set_can_focus(GTK_WIDGET(g->area),
TRUE);
4458 gtk_widget_add_events(GTK_WIDGET(g->area), GDK_BUTTON_PRESS_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK
4461 g_signal_connect(G_OBJECT(g->area),
"button-press-event", G_CALLBACK(
area_button_press), self);
4462 g_signal_connect(G_OBJECT(g->area),
"leave-notify-event", G_CALLBACK(
area_leave_notify), self);
4463 g_signal_connect(G_OBJECT(g->area),
"enter-notify-event", G_CALLBACK(
area_enter_notify), self);
4464 g_signal_connect(G_OBJECT(g->area),
"motion-notify-event", G_CALLBACK(
area_motion_notify), self);
4473 g->grey_point_source
4477 gtk_widget_set_tooltip_text(g->grey_point_source,
4478 _(
"adjust to match the average luminance of the image's subject.\n"
4479 "the value entered here will then be remapped to 18.45%.\n"
4480 "decrease the value to increase the overall brightness."));
4483 g->white_point_source
4487 gtk_widget_set_tooltip_text(g->white_point_source,
4488 _(
"number of stops between middle gray and pure white.\n"
4489 "this is a reading a lightmeter would give you on the scene.\n"
4490 "adjust so highlights clipping is avoided"));
4493 g->black_point_source
4497 gtk_widget_set_tooltip_text(
4498 g->black_point_source, _(
"number of stops between middle gray and pure black.\n"
4499 "this is a reading a lightmeter would give you on the scene.\n"
4500 "increase to get more contrast.\ndecrease to recover more details in low-lights."));
4506 gtk_widget_set_tooltip_text(g->security_factor, _(
"symmetrically enlarge or shrink the computed dynamic range.\n"
4507 "useful to give a safety margin to extreme luminances."));
4510 GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
4513 gtk_box_pack_start(GTK_BOX(hbox), g->auto_button,
FALSE,
FALSE, 0);
4515 gtk_widget_set_tooltip_text(g->auto_button, _(
"try to optimize the settings with some statistical assumptions.\n"
4516 "this will fit the luminance range inside the histogram bounds.\n"
4517 "works better for landscapes and evenly-lit pictures\n"
4518 "but fails for high-keys, low-keys and high-ISO pictures.\n"
4519 "this is not an artificial intelligence, but a simple guess.\n"
4520 "ensure you understand its assumptions before using it."));
4527 gtk_widget_set_tooltip_text(g->custom_grey, _(
"enable to input custom middle-gray values.\n"
4528 "this is not recommended in general.\n"
4529 "fix the global exposure in the exposure module instead.\n"
4530 "disable to use standard 18.45 %% middle gray."));
4540 gtk_widget_set_tooltip_text(g->reconstruct_threshold,
4541 _(
"set the exposure threshold upon which\n"
4542 "clipped highlights get reconstructed.\n"
4543 "values are relative to the scene white point.\n"
4544 "0 EV means the threshold is the same as the scene white point.\n"
4545 "decrease to include more areas,\n"
4546 "increase to exclude more areas."));
4550 gtk_widget_set_tooltip_text(g->reconstruct_feather,
4551 _(
"soften the transition between clipped highlights and valid pixels.\n"
4552 "decrease to make the transition harder and sharper,\n"
4553 "increase to make the transition softer and blurrier."));
4556 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
4557 gtk_box_pack_start(GTK_BOX(hbox),
dt_ui_label_new(_(
"display highlight reconstruction mask")),
TRUE,
TRUE, 0);
4570 gtk_widget_set_tooltip_text(g->reconstruct_structure_vs_texture,
4572 _(
"decide which reconstruction strategy to favor,\n"
4573 "between inpainting a smooth color gradient,\n"
4574 "or trying to recover the textured details.\n"
4575 "0% is an equal mix of both.\n"
4576 "increase if at least one RGB channel is not clipped.\n"
4577 "decrease if all RGB channels are clipped over large areas."));
4581 gtk_widget_set_tooltip_text(g->reconstruct_bloom_vs_details,
4583 _(
"decide which reconstruction strategy to favor,\n"
4584 "between blooming highlights like film does,\n"
4585 "or trying to recover sharp details.\n"
4586 "0% is an equal mix of both.\n"
4587 "increase if you want more details.\n"
4588 "decrease if you want more blur."));
4593 gtk_widget_set_tooltip_text(g->reconstruct_grey_vs_color,
4595 _(
"decide which reconstruction strategy to favor,\n"
4596 "between recovering monochromatic highlights,\n"
4597 "or trying to recover colorful highlights.\n"
4598 "0% is an equal mix of both.\n"
4599 "increase if you want more color.\n"
4600 "decrease if you see magenta or out-of-gamut highlights."));
4607 gtk_widget_set_tooltip_text(g->high_quality_reconstruction,
4608 _(
"run extra passes of chromaticity reconstruction.\n"
4609 "more iterations means more color propagation from neighbourhood.\n"
4610 "this will be slower but will yield more neutral highlights.\n"
4611 "it also helps with difficult cases of magenta highlights."));
4615 gtk_widget_set_tooltip_text(g->noise_level, _(
"add statistical noise in reconstructed highlights.\n"
4616 "this avoids highlights to look too smooth\n"
4617 "when the picture is noisy overall,\n"
4618 "so they blend with the rest of the picture."));
4622 gtk_widget_set_tooltip_text(g->noise_distribution, _(
"choose the statistical distribution of noise.\n"
4623 "this is useful to match natural sensor noise pattern.\n"));
4634 gtk_widget_set_tooltip_text(g->contrast, _(
"slope of the linear part of the curve\n"
4635 "affects mostly the mid-tones"));
4639 gtk_widget_set_tooltip_text(g->output_power, _(
"equivalent to paper grade in analog.\n"
4640 "increase to make highlights brighter and less compressed.\n"
4641 "decrease to mute highlights."));
4646 gtk_widget_set_tooltip_text(g->latitude,
4647 _(
"width of the linear domain in the middle of the curve,\n"
4648 "increase to get more contrast and less desaturation at extreme luminances,\n"
4649 "decrease otherwise. no desaturation happens in the latitude range.\n"
4650 "this has no effect on mid-tones."));
4654 gtk_widget_set_tooltip_text(g->balance, _(
"slides the latitude along the slope\n"
4655 "to give more room to shadows or highlights.\n"
4656 "use it if you need to protect the details\n"
4657 "at one extremity of the histogram."));
4661 gtk_widget_set_tooltip_text(g->highlights, _(
"choose the desired curvature of the filmic spline in highlights.\n"
4662 "hard uses a high curvature resulting in more tonal compression.\n"
4663 "soft uses a low curvature resulting in less tonal compression."));
4666 gtk_widget_set_tooltip_text(g->shadows, _(
"choose the desired curvature of the filmic spline in shadows.\n"
4667 "hard uses a high curvature resulting in more tonal compression.\n"
4668 "soft uses a low curvature resulting in less tonal compression."));
4676 gtk_widget_set_tooltip_text(g->saturation, _(
"desaturates the output of the module\n"
4677 "specifically at extreme luminances.\n"
4678 "increase if shadows and/or highlights are under-saturated."));
4681 gtk_widget_set_tooltip_text(g->preserve_color, _(
"ensure the original color are preserved.\n"
4682 "may reinforce chromatic aberrations and chroma noise,\n"
4683 "so ensure they are properly corrected elsewhere.\n"));
4690 gtk_widget_set_tooltip_text(g->version,
4691 _(
"v3 is darktable 3.0 desaturation method, same as color balance.\n"
4692 "v4 is a newer desaturation method, based on spectral purity of light."));
4696 gtk_widget_set_tooltip_text(
4697 g->auto_hardness, _(
"enable to auto-set the look hardness depending on the scene white and black points.\n"
4698 "this keeps the middle gray on the identity line and improves fast tuning.\n"
4699 "disable if you want a manual control."));
4708 gtk_widget_set_tooltip_text(g->black_point_target, _(
"luminance of output pure black, "
4709 "this should be 0%\nexcept if you want a faded look"));
4714 gtk_widget_set_tooltip_text(g->grey_point_target,
4715 _(
"middle gray value of the target display or color space.\n"
4716 "you should never touch that unless you know what you are doing."));
4722 gtk_widget_set_tooltip_text(g->white_point_target, _(
"luminance of output pure white, "
4723 "this should be 100%\nexcept if you want a faded look"));
4728 gtk_box_pack_start(GTK_BOX(self->
widget), GTK_WIDGET(g->area),
TRUE,
TRUE, 0);
4729 gtk_box_pack_start(GTK_BOX(self->
widget), GTK_WIDGET(g->notebook),
FALSE,
FALSE, 0);
4737 if(!w || w == g->auto_hardness || w == g->security_factor || w == g->grey_point_source
4738 || w == g->black_point_source || w == g->white_point_source)
4742 if(w == g->security_factor || w == g->grey_point_source)
4744 float prev = *(
float *)previous;
4745 if(w == g->security_factor)
4747 float ratio = (p->security_factor - prev) / (prev + 100.0f);
4749 float EVmin = p->black_point_source;
4750 EVmin = EVmin + ratio * EVmin;
4752 float EVmax = p->white_point_source;
4753 EVmax = EVmax + ratio * EVmax;
4755 p->white_point_source = EVmax;
4756 p->black_point_source = EVmin;
4760 float grey_var = log2f(prev / p->grey_point_source);
4761 p->black_point_source = p->black_point_source - grey_var;
4762 p->white_point_source = p->white_point_source + grey_var;
4769 if(p->auto_hardness)
4770 p->output_power = logf(p->grey_point_target / 100.0f)
4771 / logf(-p->black_point_source / (p->white_point_source - p->black_point_source));
4773 gtk_widget_set_visible(GTK_WIDGET(g->output_power), !p->auto_hardness);
4779 if(!w || w == g->version)
4784 gtk_widget_set_tooltip_text(g->saturation, _(
"desaturates the output of the module\n"
4785 "specifically at extreme luminances.\n"
4786 "increase if shadows and/or highlights are under-saturated."));
4791 gtk_widget_set_tooltip_text(g->saturation, _(
"desaturates the output of the module\n"
4792 "specifically at medium luminances.\n"
4793 "increase if midtones are under-saturated."));
4798 gtk_widget_set_tooltip_text(g->saturation, _(
"Positive values ensure saturation is kept unchanged over the whole range.\n"
4799 "Negative values bleache highlights at constant hue and luminance.\n"
4800 "Zero is an equal mix of both strategies."));
4801 gtk_widget_set_visible(GTK_WIDGET(g->preserve_color),
FALSE);
4805 gtk_widget_set_visible(GTK_WIDGET(g->preserve_color),
TRUE);
4809 if(!w || w == g->reconstruct_bloom_vs_details)
4811 if(p->reconstruct_bloom_vs_details == -100.f)
4816 gtk_widget_set_sensitive(g->reconstruct_structure_vs_texture,
FALSE);
4820 gtk_widget_set_sensitive(g->reconstruct_structure_vs_texture,
TRUE);
4824 if(!w || w == g->custom_grey)
4826 gtk_widget_set_visible(g->grey_point_source, p->custom_grey);
4827 gtk_widget_set_visible(g->grey_point_target, p->custom_grey);
4830 gtk_widget_queue_draw(GTK_WIDGET(g->area));
static void error(char *msg)
Definition ashift_lsd.c:191
#define TRUE
Definition ashift_lsd.c:151
#define FALSE
Definition ashift_lsd.c:147
void dt_bauhaus_slider_set_soft_range(GtkWidget *widget, float soft_min, float soft_max)
Definition bauhaus.c:1206
void dt_bauhaus_slider_set_digits(GtkWidget *widget, int val)
Definition bauhaus.c:2759
void dt_bauhaus_slider_set_soft_max(GtkWidget *widget, float val)
Definition bauhaus.c:1183
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
Definition bauhaus.c:2731
void dt_bauhaus_widget_set_label(GtkWidget *widget, const char *label)
Definition bauhaus.c:1212
void dt_bauhaus_slider_set_format(GtkWidget *widget, const char *format)
Definition bauhaus.c:2819
#define DT_BAUHAUS_SPACE
Definition bauhaus.h:262
static void set_color(cairo_t *cr, GdkRGBA color)
Definition bauhaus.h:380
#define INNER_PADDING
Definition bauhaus.h:54
int width
Definition bilateral.h:1
int height
Definition bilateral.h:1
static void normalize(float *const buffer, const size_t width, const size_t height, const float norm)
Definition blurs.c:354
static void blur_2D_Bspline(const float *const restrict in, float *const restrict out, float *const restrict tempbuf, const size_t width, const size_t height, const int mult, const gboolean clip_negatives)
Definition bspline.h:136
#define BSPLINE_FSIZE
Definition bspline.h:9
const dt_colormatrix_t XYZ_D65_to_D50_CAT16
Definition chromatic_adaptation.h:367
const dt_colormatrix_t XYZ_D50_to_D65_CAT16
Definition chromatic_adaptation.h:357
static float dt_camera_rgb_luminance(const float4 rgb)
Definition color_conversion.h:152
@ IOP_CS_RGB
Definition color_conversion.h:28
void dt_iop_color_picker_reset(dt_iop_module_t *module, gboolean keep)
Definition color_picker_proxy.c:120
GtkWidget * dt_color_picker_new(dt_iop_module_t *module, dt_iop_color_picker_kind_t kind, GtkWidget *w)
Definition color_picker_proxy.c:347
@ DT_COLOR_PICKER_AREA
Definition color_picker_proxy.h:37
static float4 gamut_check_Yrg(float4 Ych)
Definition colorspace.h:730
static float4 Yrg_to_Ych(const float4 Yrg)
Definition colorspace.h:556
static float4 Ych_to_Yrg(const float4 Ych)
Definition colorspace.h:571
static float4 Yrg_to_LMS(const float4 Yrg)
Definition colorspace.h:532
static float4 LMS_to_Yrg(const float4 LMS)
Definition colorspace.h:516
static const dt_colormatrix_t XYZ_D65_to_LMS_2006_D65
Definition colorspaces_inline_conversions.h:1035
static const dt_colormatrix_t LMS_2006_D65_to_XYZ_D65
Definition colorspaces_inline_conversions.h:1040
float dt_image_get_exposure_bias(const struct dt_image_t *image_storage)
Definition common/image.c:2508
int dt_image_is_raw(const dt_image_t *img)
Definition common/image.c:120
void dt_conf_set_int(const char *name, int val)
Definition conf.c:106
int dt_conf_get_int(const char *name)
Definition conf.c:194
void dt_control_log(const char *msg,...)
Definition control.c:424
darktable_t darktable
Definition darktable.c:111
void dt_print(dt_debug_thread_t thread, const char *msg,...)
Definition darktable.c:1395
static void * dt_calloc_align(size_t size)
Definition darktable.h:339
@ DT_DEBUG_OPENCL
Definition darktable.h:478
#define DT_ALIGNED_ARRAY
Definition darktable.h:270
#define for_each_channel(_var,...)
Definition darktable.h:411
static float * dt_alloc_align_float(size_t pixels)
Definition darktable.h:345
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
Definition darktable.h:108
#define dt_free_align(A)
Definition darktable.h:334
static gboolean dt_modifier_is(const GdkModifierType state, const GdkModifierType desired_modifier_mask)
Definition darktable.h:665
static void * dt_alloc_sse_ps(size_t pixels)
Definition darktable.h:356
dt_noise_distribution_t
Definition data/kernels/noise_generator.h:23
@ DT_NOISE_GAUSSIAN
Definition data/kernels/noise_generator.h:25
@ DT_NOISE_POISSONIAN
Definition data/kernels/noise_generator.h:26
@ DT_NOISE_UNIFORM
Definition data/kernels/noise_generator.h:24
static float4 dt_noise_generator_simd(const dt_noise_distribution_t distribution, const float4 mu, const float4 param, uint state[4])
Definition data/kernels/noise_generator.h:130
static unsigned int splitmix32(const unsigned long seed)
Definition data/kernels/noise_generator.h:30
static float xoshiro128plus(uint state[4])
Definition data/kernels/noise_generator.h:47
#define dt_dev_add_history_item(dev, module, enable)
Definition dev_history.h:72
void dt_iop_params_t
Definition dev_history.h:22
#define dt_dev_invalidate(dev)
Definition develop.h:354
@ DT_DEV_PIXELPIPE_DISPLAY_MASK
Definition develop.h:82
@ DT_DEV_PIXELPIPE_DISPLAY_PASSTHRU
Definition develop.h:100
@ DT_DEV_PIXELPIPE_DISPLAY_NONE
Definition develop.h:81
#define dt_dev_refresh_ui_images(dev)
Definition develop.h:338
static float dt_log_scale_axis(const float x, const float base)
Definition draw.h:137
static void dt_draw_grid(cairo_t *cr, const int num, const int left, const int top, const int right, const int bottom)
Definition draw.h:92
static void dt_draw_loglog_grid(cairo_t *cr, const int num, const int left, const int top, const int right, const int bottom, const float base)
Definition draw.h:142
GtkWidget * dtgtk_drawing_area_new_with_aspect_ratio(double aspect)
Definition drawingarea.c:50
void dtgtk_drawing_area_set_aspect_ratio(GtkWidget *widget, double aspect)
Definition drawingarea.c:59
static void weight(const float *c1, const float *c2, const float sharpen, dt_aligned_pixel_t weight)
Definition eaw.c:29
static void gamut_mapping(dt_aligned_pixel_t Ych_final, dt_aligned_pixel_t Ych_original, dt_aligned_pixel_t pix_out, const dt_colormatrix_t input_matrix, const dt_colormatrix_t output_matrix, const dt_colormatrix_t export_input_matrix, const dt_colormatrix_t export_output_matrix, const float display_black, const float display_white, const float saturation, const int use_output_profile)
Definition filmicrgb.c:1715
static void norm_tone_mapping_v4(const dt_aligned_pixel_t pix_in, dt_aligned_pixel_t pix_out, const dt_iop_filmicrgb_methods_type_t type, const dt_iop_order_iccprofile_info_t *const work_profile, const dt_iop_filmicrgb_data_t *const data, const dt_iop_filmic_rgb_spline_t spline, const float norm_min, const float norm_max, const float display_black, const float display_white)
Definition filmicrgb.c:1791
static gboolean area_button_press(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
Definition filmicrgb.c:4239
static gboolean area_scroll_callback(GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
Definition filmicrgb.c:4425
const char ** description(struct dt_iop_module_t *self)
Definition filmicrgb.c:349
int default_group()
Definition filmicrgb.c:360
static gboolean area_leave_notify(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
Definition filmicrgb.c:4339
dt_iop_filmic_noise_distribution_t
Definition filmicrgb.c:174
@ DT_FILMIC_NOISE_UNIFORM
Definition filmicrgb.c:175
@ DT_FILMIC_NOISE_POISSONIAN
Definition filmicrgb.c:177
@ DT_FILMIC_NOISE_GAUSSIAN
Definition filmicrgb.c:176
dt_iop_filmicrgb_curve_type_t
Definition filmicrgb.c:123
@ DT_FILMIC_CURVE_RATIONAL
Definition filmicrgb.c:126
@ DT_FILMIC_CURVE_POLY_4
Definition filmicrgb.c:124
@ DT_FILMIC_CURVE_POLY_3
Definition filmicrgb.c:125
void gui_reset(dt_iop_module_t *self)
Definition filmicrgb.c:3317
void filmic_gui_draw_icon(cairo_t *cr, struct dt_iop_filmicrgb_gui_button_data_t *button, struct dt_iop_filmicrgb_gui_data_t *g)
Definition filmicrgb.c:3351
static float pixel_rgb_norm_power(const dt_aligned_pixel_t pixel)
Definition filmicrgb.c:708
void tiling_callback(struct dt_iop_module_t *self, struct dt_dev_pixelpipe_iop_t *piece, const dt_iop_roi_t *roi_in, const dt_iop_roi_t *roi_out, struct dt_develop_tiling_t *tiling)
Definition filmicrgb.c:2049
static gboolean dt_iop_tonecurve_draw(GtkWidget *widget, cairo_t *crf, gpointer user_data)
Definition filmicrgb.c:3391
static int get_scales(const dt_iop_roi_t *roi_in, const dt_dev_pixelpipe_iop_t *const piece)
Definition filmicrgb.c:1158
static void gamut_check_RGB(const dt_colormatrix_t matrix_in, const dt_colormatrix_t matrix_out, const float display_black, const float display_white, const dt_aligned_pixel_t Ych_in, dt_aligned_pixel_t RGB_out)
Definition filmicrgb.c:1678
static void RGB_tone_mapping_v4(const dt_aligned_pixel_t pix_in, dt_aligned_pixel_t pix_out, const dt_iop_filmicrgb_data_t *const data, const dt_iop_filmic_rgb_spline_t spline, const float display_black, const float display_white)
Definition filmicrgb.c:1828
static void wavelets_reconstruct_RGB(const float *const restrict HF, const float *const restrict LF, const float *const restrict texture, const float *const restrict mask, float *const restrict reconstructed, const size_t width, const size_t height, const size_t ch, const float gamma, const float gamma_comp, const float beta, const float beta_comp, const float delta, const size_t s, const size_t scales)
Definition filmicrgb.c:1001
dt_iop_filmic_rgb_gui_mode_t
Definition filmicrgb.c:164
@ DT_FILMIC_GUI_LOOK
Definition filmicrgb.c:165
@ DT_FILMIC_GUI_RANGES
Definition filmicrgb.c:168
@ DT_FILMIC_GUI_BASECURVE
Definition filmicrgb.c:166
@ DT_FILMIC_GUI_BASECURVE_LOG
Definition filmicrgb.c:167
@ DT_FILMIC_GUI_LAST
Definition filmicrgb.c:169
void reload_defaults(dt_iop_module_t *module)
Definition filmicrgb.c:3247
void color_picker_apply(dt_iop_module_t *self, GtkWidget *picker, dt_dev_pixelpipe_iop_t *piece)
Definition filmicrgb.c:2786
dt_iop_filmicrgb_colorscience_type_t
Definition filmicrgb.c:131
@ DT_FILMIC_COLORSCIENCE_V1
Definition filmicrgb.c:132
@ DT_FILMIC_COLORSCIENCE_V2
Definition filmicrgb.c:133
@ DT_FILMIC_COLORSCIENCE_V5
Definition filmicrgb.c:136
@ DT_FILMIC_COLORSCIENCE_V4
Definition filmicrgb.c:135
@ DT_FILMIC_COLORSCIENCE_V3
Definition filmicrgb.c:134
static float clip_chroma(const dt_colormatrix_t matrix_out, const float target_white, const float Y, const float cos_h, const float sin_h, const float chroma)
Definition filmicrgb.c:1655
#define LOGBASE
Definition filmicrgb.c:3322
static float filmic_desaturate_v1(const float x, const float sigma_toe, const float sigma_shoulder, const float saturation)
Definition filmicrgb.c:862
void gui_update(dt_iop_module_t *self)
Definition filmicrgb.c:3226
static void filmic_chroma_v4(const float *const restrict in, float *const restrict out, const dt_iop_order_iccprofile_info_t *const work_profile, const dt_iop_order_iccprofile_info_t *const export_profile, const dt_iop_filmicrgb_data_t *const data, const dt_iop_filmic_rgb_spline_t spline, const int variant, const size_t width, const size_t height, const size_t ch, const dt_iop_filmicrgb_colorscience_type_t colorscience_version, const float display_black, const float display_white)
Definition filmicrgb.c:1848
static void dt_cairo_draw_arrow(cairo_t *cr, double origin_x, double origin_y, double destination_x, double destination_y, gboolean show_head)
Definition filmicrgb.c:3324
static void filmic_split_v2_v3(const float *const restrict in, float *const restrict out, const dt_iop_order_iccprofile_info_t *const work_profile, const dt_iop_filmicrgb_data_t *const data, const dt_iop_filmic_rgb_spline_t spline, const size_t width, const size_t height)
Definition filmicrgb.c:1324
const char * aliases()
Definition filmicrgb.c:344
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition filmicrgb.c:370
void gui_focus(struct dt_iop_module_t *self, gboolean in)
Definition filmicrgb.c:3199
static void filmic_split_v1(const float *const restrict in, float *const restrict out, const dt_iop_order_iccprofile_info_t *const work_profile, const dt_iop_filmicrgb_data_t *const data, const dt_iop_filmic_rgb_spline_t spline, const size_t width, const size_t height)
Definition filmicrgb.c:1280
static void apply_autotune(dt_iop_module_t *self)
Definition filmicrgb.c:2746
#define CIE_Y_1931_to_CIE_Y_2006(x)
Definition filmicrgb.c:1577
static void restore_ratios(float *const restrict ratios, const float *const restrict norms, const size_t width, const size_t height)
Definition filmicrgb.c:2036
const char * name()
Definition filmicrgb.c:339
static void filmic_chroma_v2_v3(const float *const restrict in, float *const restrict out, const dt_iop_order_iccprofile_info_t *const work_profile, const dt_iop_filmicrgb_data_t *const data, const dt_iop_filmic_rgb_spline_t spline, const int variant, const size_t width, const size_t height, const size_t ch, const dt_iop_filmicrgb_colorscience_type_t colorscience_version)
Definition filmicrgb.c:1424
void gui_init(dt_iop_module_t *self)
Definition filmicrgb.c:4442
dt_iop_filmicrgb_methods_type_t
Definition filmicrgb.c:112
@ DT_FILMIC_METHOD_POWER_NORM
Definition filmicrgb.c:116
@ DT_FILMIC_METHOD_EUCLIDEAN_NORM_V1
Definition filmicrgb.c:118
@ DT_FILMIC_METHOD_NONE
Definition filmicrgb.c:113
@ DT_FILMIC_METHOD_MAX_RGB
Definition filmicrgb.c:114
@ DT_FILMIC_METHOD_EUCLIDEAN_NORM_V2
Definition filmicrgb.c:117
@ DT_FILMIC_METHOD_LUMINANCE
Definition filmicrgb.c:115
static float log_tonemapping(const float x, const float grey, const float black, const float dynamic_range)
Definition filmicrgb.c:774
static float get_pixel_norm(const dt_aligned_pixel_t pixel, const dt_iop_filmicrgb_methods_type_t variant, const dt_iop_order_iccprofile_info_t *const work_profile)
Definition filmicrgb.c:732
static void init_reconstruct(const float *const restrict in, const float *const restrict mask, float *const restrict reconstructed, const size_t width, const size_t height)
Definition filmicrgb.c:1126
dt_iop_filmicrgb_reconstruction_type_t
Definition filmicrgb.c:147
@ DT_FILMIC_RECONSTRUCT_RATIOS
Definition filmicrgb.c:149
@ DT_FILMIC_RECONSTRUCT_RGB
Definition filmicrgb.c:148
void gui_changed(dt_iop_module_t *self, GtkWidget *w, void *previous)
Definition filmicrgb.c:4732
dt_iop_filmicrgb_gui_button_t
Definition filmicrgb.c:217
@ DT_FILMIC_GUI_BUTTON_LAST
Definition filmicrgb.c:220
@ DT_FILMIC_GUI_BUTTON_LABELS
Definition filmicrgb.c:219
@ DT_FILMIC_GUI_BUTTON_TYPE
Definition filmicrgb.c:218
void process(dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const void *const restrict ivoid, void *const restrict ovoid, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out)
Definition filmicrgb.c:2069
void commit_params(dt_iop_module_t *self, dt_iop_params_t *p1, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition filmicrgb.c:3127
static gint mask_clipped_pixels(const float *const restrict in, float *const restrict mask, const float normalize, const float feathering, const size_t width, const size_t height, const size_t ch)
Definition filmicrgb.c:906
#define ORDER_4
Definition filmicrgb.c:2823
static float exp_tonemapping_v2(const float x, const float grey, const float black, const float dynamic_range)
Definition filmicrgb.c:783
static void pipe_RGB_to_Ych(const dt_aligned_pixel_t in, const dt_colormatrix_t matrix, dt_aligned_pixel_t out)
Definition filmicrgb.c:1502
static float filmic_desaturate_v2(const float x, const float sigma_toe, const float sigma_shoulder, const float saturation)
Definition filmicrgb.c:878
void cleanup_global(dt_iop_module_so_t *module)
Definition filmicrgb.c:3297
static gboolean area_enter_notify(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
Definition filmicrgb.c:4326
void cleanup_pipe(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition filmicrgb.c:3220
static gboolean area_motion_notify(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
Definition filmicrgb.c:4351
static void compute_ratios(const float *const restrict in, float *const restrict norms, float *const restrict ratios, const dt_iop_order_iccprofile_info_t *const work_profile, const int variant, const size_t width, const size_t height)
Definition filmicrgb.c:2017
static void inpaint_noise(const float *const in, const float *const mask, float *const inpainted, const float noise_level, const float threshold, const dt_noise_distribution_t noise_distribution, const size_t width, const size_t height)
Definition filmicrgb.c:955
int flags()
Definition filmicrgb.c:365
static void filmic_desaturate_v4(const dt_aligned_pixel_t Ych_original, dt_aligned_pixel_t Ych_final, const float saturation)
Definition filmicrgb.c:1536
static void show_mask_callback(GtkToggleButton *button, GdkEventButton *event, gpointer user_data)
Definition filmicrgb.c:2800
#define ORDER_3
Definition filmicrgb.c:2824
static void apply_auto_white_point_source(dt_iop_module_t *self)
Definition filmicrgb.c:2719
static float clip_chroma_white(const float coeffs[3], const float target_white, const float Y, const float cos_h, const float sin_h)
Definition filmicrgb.c:1610
static void convert_to_spline_v3(dt_iop_filmicrgb_params_t *n)
Definition filmicrgb.c:379
static gint reconstruct_highlights(const float *const restrict in, const float *const restrict mask, float *const restrict reconstructed, const dt_iop_filmicrgb_reconstruction_type_t variant, const size_t ch, const dt_iop_filmicrgb_data_t *const data, dt_dev_pixelpipe_iop_t *piece, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out)
Definition filmicrgb.c:1177
#define MAX_NUM_SCALES
Definition filmicrgb.c:900
dt_iop_filmicrgb_spline_version_type_t
Definition filmicrgb.c:140
@ DT_FILMIC_SPLINE_VERSION_V2
Definition filmicrgb.c:142
@ DT_FILMIC_SPLINE_VERSION_V3
Definition filmicrgb.c:143
@ DT_FILMIC_SPLINE_VERSION_V1
Definition filmicrgb.c:141
void init_pipe(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition filmicrgb.c:3214
#define INVERSE_SQRT_3
Definition filmicrgb.c:58
static void filmic_v5(const float *const restrict in, float *const restrict out, const dt_iop_order_iccprofile_info_t *const work_profile, const dt_iop_order_iccprofile_info_t *const export_profile, const dt_iop_filmicrgb_data_t *const data, const dt_iop_filmic_rgb_spline_t spline, const size_t width, const size_t height, const size_t ch, const float display_black, const float display_white)
Definition filmicrgb.c:1944
static void Ych_to_pipe_RGB(const dt_aligned_pixel_t in, const dt_colormatrix_t matrix, dt_aligned_pixel_t out)
Definition filmicrgb.c:1521
static float filmic_spline(const float x, const dt_aligned_pixel_t M1, const dt_aligned_pixel_t M2, const dt_aligned_pixel_t M3, const dt_aligned_pixel_t M4, const dt_aligned_pixel_t M5, const float latitude_min, const float latitude_max, const dt_iop_filmicrgb_curve_type_t type[2])
Definition filmicrgb.c:794
static void apply_auto_black(dt_iop_module_t *self)
Definition filmicrgb.c:2691
static int filmic_v4_prepare_matrices(dt_colormatrix_t input_matrix, dt_colormatrix_t output_matrix, dt_colormatrix_t export_input_matrix, dt_colormatrix_t export_output_matrix, const dt_iop_order_iccprofile_info_t *const work_profile, const dt_iop_order_iccprofile_info_t *const export_profile)
Definition filmicrgb.c:1755
void init_global(dt_iop_module_so_t *module)
Definition filmicrgb.c:3274
static void display_mask(const float *const restrict mask, float *const restrict out, const size_t width, const size_t height)
Definition filmicrgb.c:2003
static void filmic_split_v4(const float *const restrict in, float *const restrict out, const dt_iop_order_iccprofile_info_t *const work_profile, const dt_iop_order_iccprofile_info_t *const export_profile, const dt_iop_filmicrgb_data_t *const data, const dt_iop_filmic_rgb_spline_t spline, const int variant, const size_t width, const size_t height, const size_t ch, const dt_iop_filmicrgb_colorscience_type_t colorscience_version, const float display_black, const float display_white)
Definition filmicrgb.c:1896
static float clip_chroma_white_raw(const float coeffs[3], const float target_white, const float Y, const float cos_h, const float sin_h)
Definition filmicrgb.c:1580
static void apply_auto_grey(dt_iop_module_t *self)
Definition filmicrgb.c:2662
static void wavelets_detail_level(const float *const restrict detail, const float *const restrict LF, float *const restrict HF, float *const restrict texture, const size_t width, const size_t height, const size_t ch)
Definition filmicrgb.c:1143
static void filmic_chroma_v1(const float *const restrict in, float *const restrict out, const dt_iop_order_iccprofile_info_t *const work_profile, const dt_iop_filmicrgb_data_t *const data, const dt_iop_filmic_rgb_spline_t spline, const int variant, const size_t width, const size_t height)
Definition filmicrgb.c:1368
#define SAFETY_MARGIN
Definition filmicrgb.c:59
static float linear_saturation(const float x, const float luminance, const float saturation)
Definition filmicrgb.c:894
static gboolean dt_iop_filmic_rgb_compute_spline(const dt_iop_filmicrgb_params_t *const p, struct dt_iop_filmic_rgb_spline_t *const spline)
Definition filmicrgb.c:2828
int legacy_params(dt_iop_module_t *self, const void *const old_params, const int old_version, void *new_params, const int new_version)
Definition filmicrgb.c:442
static void wavelets_reconstruct_ratios(const float *const restrict HF, const float *const restrict LF, const float *const restrict texture, const float *const restrict mask, float *const restrict reconstructed, const size_t width, const size_t height, const size_t ch, const float gamma, const float gamma_comp, const float beta, const float beta_comp, const float delta, const size_t s, const size_t scales)
Definition filmicrgb.c:1059
static float clip_chroma_black(const float coeffs[3], const float cos_h, const float sin_h)
Definition filmicrgb.c:1633
static int gauss_solve(double *A, double *b, int n)
Definition gaussian_elimination.h:97
gboolean dt_gui_get_scroll_unit_deltas(const GdkEventScroll *event, int *delta_x, int *delta_y)
Definition gtk.c:157
GtkWidget * dt_ui_notebook_page(GtkNotebook *notebook, const char *text, const char *tooltip)
Definition gtk.c:1391
GtkNotebook * dt_ui_notebook_new()
Definition gtk.c:1386
void dt_gui_add_class(GtkWidget *widget, const gchar *class_name)
Definition gtk.c:72
static cairo_surface_t * dt_cairo_image_surface_create(cairo_format_t format, int width, int height)
Definition gtk.h:154
static GtkWidget * dt_ui_section_label_new(const gchar *str)
Definition gtk.h:283
#define DT_PIXEL_APPLY_DPI(value)
Definition gtk.h:38
static GtkWidget * dt_ui_label_new(const gchar *str)
Definition gtk.h:293
void dt_iop_request_focus(dt_iop_module_t *module)
Definition imageop.c:1883
const char ** dt_iop_set_description(dt_iop_module_t *module, const char *main_text, const char *purpose, const char *input, const char *process, const char *output)
Definition imageop.c:2819
void dt_iop_set_cache_bypass(dt_iop_module_t *module, gboolean state)
Definition imageop.c:2447
@ IOP_FLAGS_INCLUDE_IN_STYLES
Definition imageop.h:107
@ IOP_FLAGS_SUPPORTS_BLENDING
Definition imageop.h:108
@ IOP_FLAGS_ALLOW_TILING
Definition imageop.h:110
@ IOP_GROUP_TONES
Definition imageop.h:78
#define IOP_GUI_ALLOC(module)
Definition imageop.h:465
GtkWidget * dt_iop_togglebutton_new(dt_iop_module_t *self, const char *section, const gchar *label, const gchar *ctrl_label, GCallback callback, gboolean local, guint accel_key, GdkModifierType mods, DTGTKCairoPaintIconFunc paint, GtkWidget *box)
Definition imageop_gui.c:285
GtkWidget * dt_bauhaus_toggle_from_params(dt_iop_module_t *self, const char *param)
Definition imageop_gui.c:244
GtkWidget * dt_bauhaus_slider_from_params(dt_iop_module_t *self, const char *param)
Definition imageop_gui.c:75
GtkWidget * dt_bauhaus_combobox_from_params(dt_iop_module_t *self, const char *param)
Definition imageop_gui.c:180
static void dt_iop_alpha_copy(const void *const ivoid, void *const ovoid, const size_t width, const size_t height)
Definition imageop_math.h:170
dt_iop_order_iccprofile_info_t * dt_ioppr_get_iop_work_profile_info(struct dt_iop_module_t *module, GList *iop_list)
Definition iop_profile.c:765
dt_iop_order_iccprofile_info_t * dt_ioppr_get_pipe_work_profile_info(struct dt_dev_pixelpipe_t *pipe)
Definition iop_profile.c:887
dt_iop_order_iccprofile_info_t * dt_ioppr_get_pipe_output_profile_info(struct dt_dev_pixelpipe_t *pipe)
Definition iop_profile.c:897
static float dt_ioppr_get_rgb_matrix_luminance(const dt_aligned_pixel_t rgb, const dt_colormatrix_t matrix_in, float *const lut_in[3], const float unbounded_coeffs_in[3][3], const int lutsize, const int nonlinearlut)
Definition iop_profile.h:258
static void flip(float *x, float *y)
Definition lightroom.c:1035
static float sqf(const float x)
Definition math.h:215
#define NORM_MIN
Definition math.h:27
#define CLAMPF(a, mn, mx)
Definition math.h:81
#define M_PI
Definition math.h:37
float DT_ALIGNED_ARRAY dt_colormatrix_t[4][4]
Definition matrices.h:24
static void dt_colormatrix_mul(dt_colormatrix_t dst, const dt_colormatrix_t m1, const dt_colormatrix_t m2)
Definition matrices.h:140
static void dot_product(const dt_aligned_pixel_t v_in, const dt_colormatrix_t M, dt_aligned_pixel_t v_out)
Definition matrices.h:178
size_t size
Definition mipmap_cache.c:3
g
Definition derive_filmic_v6_gamut_mapping.py:18
mask
Definition dtstyle_to_xmp.py:54
static int dt_opencl_enqueue_kernel_2d(const int dev, const int kernel, const size_t *sizes)
Definition opencl.h:560
static int dt_opencl_set_kernel_arg(const int dev, const int kernel, const size_t size, const void *arg)
Definition opencl.h:556
static int dt_opencl_create_kernel(const int program, const char *name)
Definition opencl.h:535
static void dt_opencl_free_kernel(const int kernel)
Definition opencl.h:539
static void dt_opencl_release_mem_object(void *mem)
Definition opencl.h:601
static float fmaxabsf(const float a, const float b)
Definition openmp_maths.h:119
static float clamp_simd(const float x)
Definition openmp_maths.h:141
void dtgtk_cairo_paint_refresh(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
Definition paint.c:1380
void dtgtk_cairo_paint_showmask(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
Definition paint.c:1947
void dtgtk_cairo_paint_text_label(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
Definition paint.c:2096
void(* DTGTKCairoPaintIconFunc)(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
Definition paint.h:46
@ DT_DEV_PIXELPIPE_FULL
Definition pixelpipe.h:31
#define eps
Definition rcd.c:81
int32_t num_openmp_threads
Definition darktable.h:524
struct dt_gui_gtk_t * gui
Definition darktable.h:541
struct dt_bauhaus_t * bauhaus
Definition darktable.h:544
struct dt_develop_t * develop
Definition darktable.h:536
GdkRGBA graph_bg
Definition bauhaus.h:253
GdkRGBA graph_border
Definition bauhaus.h:253
PangoFontDescription * pango_font_desc
Definition bauhaus.h:247
float quad_width
Definition bauhaus.h:246
GdkRGBA graph_fg
Definition bauhaus.h:253
Definition color_conversion.h:36
Definition pixelpipe_hb.h:46
int colors
Definition pixelpipe_hb.h:85
double iscale
Definition pixelpipe_hb.h:70
size_t data_size
Definition pixelpipe_hb.h:59
dt_iop_roi_t buf_in
Definition pixelpipe_hb.h:86
struct dt_iop_module_t *struct dt_dev_pixelpipe_t * pipe
Definition pixelpipe_hb.h:48
void * data
Definition pixelpipe_hb.h:49
Definition pixelpipe_hb.h:127
int32_t gui_attached
Definition develop.h:144
dt_image_t image_storage
Definition develop.h:164
GList * iop
Definition develop.h:173
double dpi
Definition gtk.h:117
gint scroll_mask
Definition gtk.h:126
int32_t reset
Definition gtk.h:98
Definition filmicrgb.c:154
dt_aligned_pixel_t M2
Definition filmicrgb.c:155
dt_aligned_pixel_t M4
Definition filmicrgb.c:155
dt_iop_filmicrgb_curve_type_t type[2]
Definition filmicrgb.c:159
dt_aligned_pixel_t M5
Definition filmicrgb.c:155
float latitude_min
Definition filmicrgb.c:156
float y[5]
Definition filmicrgb.c:157
dt_aligned_pixel_t M1
Definition filmicrgb.c:155
float x[5]
Definition filmicrgb.c:158
dt_aligned_pixel_t M3
Definition filmicrgb.c:155
float latitude_max
Definition filmicrgb.c:156
Definition filmicrgb.c:296
int high_quality_reconstruction
Definition filmicrgb.c:316
int spline_version
Definition filmicrgb.c:315
float reconstruct_feather
Definition filmicrgb.c:302
float dynamic_range
Definition filmicrgb.c:307
float reconstruct_structure_vs_texture
Definition filmicrgb.c:305
float max_grad
Definition filmicrgb.c:297
float reconstruct_grey_vs_color
Definition filmicrgb.c:304
float output_power
Definition filmicrgb.c:309
float sigma_shoulder
Definition filmicrgb.c:311
float white_source
Definition filmicrgb.c:298
float noise_level
Definition filmicrgb.c:312
float sigma_toe
Definition filmicrgb.c:311
dt_noise_distribution_t noise_distribution
Definition filmicrgb.c:318
int version
Definition filmicrgb.c:314
float grey_source
Definition filmicrgb.c:299
float normalize
Definition filmicrgb.c:306
float reconstruct_bloom_vs_details
Definition filmicrgb.c:303
float saturation
Definition filmicrgb.c:308
float contrast
Definition filmicrgb.c:310
struct dt_iop_filmic_rgb_spline_t spline DT_ALIGNED_ARRAY
Definition filmicrgb.c:317
float black_source
Definition filmicrgb.c:300
float reconstruct_threshold
Definition filmicrgb.c:301
int preserve_color
Definition filmicrgb.c:313
Definition filmicrgb.c:323
int kernel_filmic_rgb_chroma
Definition filmicrgb.c:325
int kernel_filmic_bspline_vertical
Definition filmicrgb.c:329
int kernel_filmic_rgb_split
Definition filmicrgb.c:324
int kernel_filmic_wavelets_reconstruct
Definition filmicrgb.c:333
int kernel_filmic_wavelets_detail
Definition filmicrgb.c:332
int kernel_filmic_show_mask
Definition filmicrgb.c:327
int kernel_filmic_compute_ratios
Definition filmicrgb.c:334
int kernel_filmic_init_reconstruct
Definition filmicrgb.c:331
int kernel_filmic_restore_ratios
Definition filmicrgb.c:335
int kernel_filmic_mask
Definition filmicrgb.c:326
int kernel_filmic_bspline_horizontal
Definition filmicrgb.c:330
int kernel_filmic_inpaint_noise
Definition filmicrgb.c:328
Definition filmicrgb.c:245
GtkWidget * high_quality_reconstruction
Definition filmicrgb.c:268
GtkWidget * autoset_display_gamma
Definition filmicrgb.c:263
GtkWidget * reconstruct_grey_vs_color
Definition filmicrgb.c:249
GtkWidget * auto_hardness
Definition filmicrgb.c:266
dt_iop_filmicrgb_gui_button_data_t buttons[DT_FILMIC_GUI_BUTTON_LAST]
Definition filmicrgb.c:280
GtkWidget * reconstruct_bloom_vs_details
Definition filmicrgb.c:249
GtkWidget * reconstruct_threshold
Definition filmicrgb.c:249
GtkNotebook * notebook
Definition filmicrgb.c:271
GtkWidget * contrast
Definition filmicrgb.c:259
float graph_height
Definition filmicrgb.c:287
GtkWidget * auto_button
Definition filmicrgb.c:253
GtkWidget * saturation
Definition filmicrgb.c:260
GtkWidget * show_highlight_mask
Definition filmicrgb.c:251
float sign_width
Definition filmicrgb.c:284
GtkWidget * white_point_target
Definition filmicrgb.c:255
GtkWidget * grey_point_source
Definition filmicrgb.c:247
GtkWidget * latitude
Definition filmicrgb.c:258
gint gui_show_labels
Definition filmicrgb.c:276
GtkWidget * highlights
Definition filmicrgb.c:264
GtkWidget * balance
Definition filmicrgb.c:261
GtkDrawingArea * area
Definition filmicrgb.c:272
GtkStyleContext * context
Definition filmicrgb.c:292
GtkWidget * output_power
Definition filmicrgb.c:257
GtkWidget * preserve_color
Definition filmicrgb.c:262
PangoRectangle ink
Definition filmicrgb.c:291
dt_iop_filmicrgb_gui_button_t active_button
Definition filmicrgb.c:279
GtkWidget * shadows
Definition filmicrgb.c:264
gint gui_hover
Definition filmicrgb.c:277
GtkAllocation allocation
Definition filmicrgb.c:290
GtkWidget * noise_level
Definition filmicrgb.c:269
GtkWidget * grey_point_target
Definition filmicrgb.c:254
dt_iop_filmic_rgb_gui_mode_t gui_mode
Definition filmicrgb.c:275
gint gui_sizes_inited
Definition filmicrgb.c:278
GtkWidget * black_point_source
Definition filmicrgb.c:248
GtkWidget * reconstruct_structure_vs_texture
Definition filmicrgb.c:250
float graph_width
Definition filmicrgb.c:286
GtkWidget * reconstruct_feather
Definition filmicrgb.c:250
GtkWidget * version
Definition filmicrgb.c:265
GtkWidget * noise_distribution
Definition filmicrgb.c:269
float zero_width
Definition filmicrgb.c:285
gint show_mask
Definition filmicrgb.c:274
float line_height
Definition filmicrgb.c:283
GtkWidget * black_point_target
Definition filmicrgb.c:256
int inset
Definition filmicrgb.c:288
GtkWidget * custom_grey
Definition filmicrgb.c:267
struct dt_iop_filmic_rgb_spline_t spline DT_ALIGNED_ARRAY
Definition filmicrgb.c:273
GtkWidget * white_point_source
Definition filmicrgb.c:246
GtkWidget * security_factor
Definition filmicrgb.c:252
GtkWidget * compensate_icc_black
Definition filmicrgb.c:270
Definition filmicrgb.c:182
float reconstruct_threshold
Definition filmicrgb.c:186
float reconstruct_grey_vs_color
Definition filmicrgb.c:189
float reconstruct_feather
Definition filmicrgb.c:187
dt_iop_filmicrgb_curve_type_t shadows
Definition filmicrgb.c:207
dt_iop_filmicrgb_spline_version_type_t spline_version
Definition filmicrgb.c:210
float white_point_target
Definition filmicrgb.c:194
gboolean auto_hardness
Definition filmicrgb.c:203
float contrast
Definition filmicrgb.c:197
float latitude
Definition filmicrgb.c:196
float security_factor
Definition filmicrgb.c:191
dt_iop_filmicrgb_colorscience_type_t version
Definition filmicrgb.c:202
float balance
Definition filmicrgb.c:199
dt_iop_filmic_noise_distribution_t noise_distribution
Definition filmicrgb.c:206
dt_iop_filmicrgb_methods_type_t preserve_color
Definition filmicrgb.c:201
int high_quality_reconstruction
Definition filmicrgb.c:205
dt_iop_filmicrgb_curve_type_t highlights
Definition filmicrgb.c:208
float grey_point_source
Definition filmicrgb.c:183
float output_power
Definition filmicrgb.c:195
float reconstruct_bloom_vs_details
Definition filmicrgb.c:188
float grey_point_target
Definition filmicrgb.c:192
float saturation
Definition filmicrgb.c:198
gboolean custom_grey
Definition filmicrgb.c:204
float noise_level
Definition filmicrgb.c:200
float black_point_source
Definition filmicrgb.c:184
gboolean compensate_icc_black
Definition filmicrgb.c:209
float black_point_target
Definition filmicrgb.c:193
float white_point_source
Definition filmicrgb.c:185
float reconstruct_structure_vs_texture
Definition filmicrgb.c:190
dt_iop_global_data_t * data
Definition imageop.h:168
GtkDarktableToggleButton * off
Definition imageop.h:270
dt_iop_params_t * default_params
Definition imageop.h:238
GtkWidget * widget
Definition imageop.h:268
struct dt_develop_t * dev
Definition imageop.h:227
dt_iop_gui_data_t * gui_data
Definition imageop.h:242
gboolean enabled
Definition imageop.h:229
dt_aligned_pixel_t picked_color_min
Definition imageop.h:210
int request_mask_display
Definition imageop.h:204
dt_aligned_pixel_t picked_color_max
Definition imageop.h:210
dt_aligned_pixel_t picked_color
Definition imageop.h:210
dt_iop_params_t * params
Definition imageop.h:238
Definition iop_profile.h:41
int nonlinearlut
Definition iop_profile.h:52
int lutsize
Definition iop_profile.h:47
dt_colormatrix_t matrix_out
Definition iop_profile.h:46
float * lut_in[3]
Definition iop_profile.h:48
dt_colormatrix_t matrix_in
Definition iop_profile.h:45
double scale
Definition imageop.h:34
int width
Definition imageop.h:33
int height
Definition imageop.h:33
#define E
Definition test_filmicrgb.c:48
#define MIN(a, b)
Definition thinplate.c:23
#define MAX(a, b)
Definition thinplate.c:20