87#define INVERSE_SQRT_3 0.5773502691896258f
88#define SAFETY_MARGIN 0.01f
90#define DT_GUI_CURVE_EDITOR_INSET DT_PIXEL_APPLY_DPI(1)
356 return _(
"fil_mic rgb");
361 return _(
"tone mapping|curve|view transform|contrast|saturation|highlights");
367 "for display on SDR screens and paper prints\n"
368 "while preventing clipping in non-destructive ways"),
369 _(
"corrective and creative"),
370 _(
"linear or non-linear, RGB, scene-referred"),
371 _(
"non-linear, RGB"),
372 _(
"non-linear, RGB, display-referred"));
435 geometry->
grey_display = powf(CLAMP(
p->grey_point_target,
p->black_point_target,
p->white_point_target) / 100.0f,
436 1.0f /
p->output_power);
438 geometry->
grey_display = powf(0.1845f, 1.0f /
p->output_power);
440 const float dynamic_range =
p->white_point_source -
p->black_point_source;
441 geometry->
grey_log = fabsf(
p->black_point_source) / dynamic_range;
442 geometry->
black_display = powf(CLAMP(
p->black_point_target, 0.0f,
p->grey_point_target) / 100.0f,
443 1.0f /
p->output_power);
444 geometry->
white_display = powf(fmaxf(
p->white_point_target,
p->grey_point_target) / 100.0f,
445 1.0f /
p->output_power);
447 const float slope =
p->contrast * dynamic_range / 8.0f;
448 float min_contrast = 1.0f;
449 min_contrast = fmaxf(min_contrast,
451 min_contrast = fmaxf(min_contrast,
456 const float clamped_contrast = CLAMP(geometry->
contrast, min_contrast, 100.0f);
458 geometry->
contrast = clamped_contrast;
480 const float latitude = CLAMP(
p->latitude, 0.0f, 100.0f) / 100.0f;
481 const float balance = CLAMP(
p->balance, -50.0f, 50.0f) / 100.0f;
490 const float balance_correction = (balance > 0.0f)
493 nodes->
toe_log -= balance_correction;
504 float *
const toe,
float *
const shoulder)
510 *toe = CLAMP(
p->latitude, 0.0f, 100.0f);
511 *shoulder = CLAMP(
p->latitude, 0.0f, 100.0f);
515 const float toe_span = fmaxf(geometry.
grey_log - geometry.
xmin, 1e-6f);
516 const float shoulder_span = fmaxf(geometry.
xmax - geometry.
grey_log, 1e-6f);
517 *toe = CLAMP((geometry.
grey_log - nodes.
toe_log) / toe_span, 0.0f, 1.0f) * 100.0f;
518 *shoulder = CLAMP((nodes.
shoulder_log - geometry.
grey_log) / shoulder_span, 0.0f, 1.0f) * 100.0f;
522 const float toe,
const float shoulder,
523 float *
const latitude,
float *
const balance)
528 *latitude =
p->latitude;
529 *balance =
p->balance;
533 const float toe_value = CLAMP(toe, 0.0f, 100.0f) / 100.0f;
534 const float shoulder_value = CLAMP(shoulder, 0.0f, 100.0f) / 100.0f;
535 const float toe_span = fmaxf(geometry.
grey_log - geometry.
xmin, 1e-6f);
536 const float shoulder_span = fmaxf(geometry.
xmax - geometry.
grey_log, 1e-6f);
537 const float latitude_value = CLAMP((toe_span * toe_value + shoulder_span * shoulder_value)
538 / (toe_span + shoulder_span),
541 float balance_value = 0.0f;
542 if(latitude_value > 1e-6f)
544 if(toe_value > shoulder_value)
545 balance_value = 0.5f * (1.0f - shoulder_value / latitude_value);
546 else if(shoulder_value > toe_value)
547 balance_value = 0.5f * (toe_value / latitude_value - 1.0f);
550 *latitude = latitude_value * 100.0f;
551 *balance = CLAMP(balance_value, -0.5f, 0.5f) * 100.0f;
564 float grey_log = spline.
x[2];
565 float toe_log = fminf(spline.
x[1], grey_log);
566 float shoulder_log = fmaxf(spline.
x[3], grey_log);
567 float black_display = spline.
y[0];
568 float grey_display = spline.
y[2];
569 float white_display = spline.
y[4];
570 const float scaled_safety_margin =
SAFETY_MARGIN * (white_display - black_display);
571 float toe_display = fminf(spline.
y[1], grey_display);
572 float shoulder_display = fmaxf(spline.
y[3], grey_display);
574 float hardness =
n->output_power;
575 float contrast = (shoulder_display - toe_display) / (shoulder_log - toe_log);
577 float linear_intercept = grey_display - (contrast * grey_log);
578 if(toe_display < black_display + scaled_safety_margin)
580 toe_display = black_display + scaled_safety_margin;
582 toe_log = (toe_display - linear_intercept) / contrast;
584 if(shoulder_display > white_display - scaled_safety_margin)
586 shoulder_display = white_display - scaled_safety_margin;
588 shoulder_log = (shoulder_display - linear_intercept) / contrast;
591 contrast *= 8.0f / (
n->white_point_source -
n->black_point_source);
592 contrast *= hardness * powf(grey_display, hardness-1.0f);
594 const float latitude = CLAMP((shoulder_display - toe_display) / ((white_display - black_display) - 2.0f * scaled_safety_margin), 0.0f, 0.99f);
596 float toe_display_ref = latitude * (black_display + scaled_safety_margin) + (1.0f - latitude) * grey_display;
597 float shoulder_display_ref = latitude * (white_display - scaled_safety_margin) + (1.0f - latitude) * grey_display;
599 if(shoulder_display < shoulder_display_ref)
600 balance = 0.5f * (1.0f - fmaxf(shoulder_display - grey_display, 0.0f) / fmaxf(shoulder_display_ref - grey_display, 1E-5f));
602 balance = -0.5f * (1.0f - fmaxf(grey_display - toe_display, 0.0f) / fmaxf(grey_display - toe_display_ref, 1E-5f));
609 n->black_point_target = powf(black_display, hardness) * 100.0f;
610 n->white_point_target = powf(white_display, hardness) * 100.0f;
612 n->latitude = latitude * 100.0f;
613 n->contrast = contrast;
614 n->balance = balance * 100.0f;
619 const int new_version)
621 if(old_version == 1 && new_version == 5)
623 typedef struct dt_iop_filmicrgb_params_v1_t
625 float grey_point_source;
626 float black_point_source;
627 float white_point_source;
628 float security_factor;
629 float grey_point_target;
630 float black_point_target;
631 float white_point_target;
638 } dt_iop_filmicrgb_params_v1_t;
640 dt_iop_filmicrgb_params_v1_t *o = (dt_iop_filmicrgb_params_v1_t *)old_params;
646 n->grey_point_source = o->grey_point_source;
647 n->white_point_source = o->white_point_source;
648 n->black_point_source = o->black_point_source;
649 n->security_factor = o->security_factor;
650 n->grey_point_target = o->grey_point_target;
651 n->black_point_target = o->black_point_target;
652 n->white_point_target = o->white_point_target;
653 n->output_power = o->output_power;
654 n->latitude = o->latitude;
655 n->contrast = o->contrast;
656 n->saturation = o->saturation;
657 n->balance = o->balance;
658 n->preserve_color = o->preserve_color;
661 n->reconstruct_threshold
663 n->reconstruct_bloom_vs_details =
d->reconstruct_bloom_vs_details;
664 n->reconstruct_grey_vs_color =
d->reconstruct_grey_vs_color;
665 n->reconstruct_structure_vs_texture =
d->reconstruct_structure_vs_texture;
666 n->reconstruct_feather = 3.0f;
668 n->auto_hardness =
TRUE;
669 n->custom_grey =
TRUE;
670 n->high_quality_reconstruction = 0;
671 n->noise_distribution =
d->noise_distribution;
672 n->noise_level = 0.f;
674 n->compensate_icc_black =
FALSE;
678 if(old_version == 2 && new_version == 5)
680 typedef struct dt_iop_filmicrgb_params_v2_t
682 float grey_point_source;
683 float black_point_source;
684 float white_point_source;
685 float reconstruct_threshold;
686 float reconstruct_feather;
687 float reconstruct_bloom_vs_details;
688 float reconstruct_grey_vs_color;
689 float reconstruct_structure_vs_texture;
690 float security_factor;
691 float grey_point_target;
692 float black_point_target;
693 float white_point_target;
703 int high_quality_reconstruction;
706 } dt_iop_filmicrgb_params_v2_t;
708 dt_iop_filmicrgb_params_v2_t *o = (dt_iop_filmicrgb_params_v2_t *)old_params;
714 n->grey_point_source = o->grey_point_source;
715 n->white_point_source = o->white_point_source;
716 n->black_point_source = o->black_point_source;
717 n->security_factor = o->security_factor;
718 n->grey_point_target = o->grey_point_target;
719 n->black_point_target = o->black_point_target;
720 n->white_point_target = o->white_point_target;
721 n->output_power = o->output_power;
722 n->latitude = o->latitude;
723 n->contrast = o->contrast;
724 n->saturation = o->saturation;
725 n->balance = o->balance;
726 n->preserve_color = o->preserve_color;
727 n->shadows = o->shadows;
728 n->highlights = o->highlights;
729 n->reconstruct_threshold = o->reconstruct_threshold;
730 n->reconstruct_bloom_vs_details = o->reconstruct_bloom_vs_details;
731 n->reconstruct_grey_vs_color = o->reconstruct_grey_vs_color;
732 n->reconstruct_structure_vs_texture = o->reconstruct_structure_vs_texture;
733 n->reconstruct_feather = o->reconstruct_feather;
734 n->version = o->version;
735 n->auto_hardness = o->auto_hardness;
736 n->custom_grey = o->custom_grey;
737 n->high_quality_reconstruction = o->high_quality_reconstruction;
738 n->noise_level =
d->noise_level;
739 n->noise_distribution =
d->noise_distribution;
740 n->noise_level = 0.f;
742 n->compensate_icc_black =
FALSE;
746 if(old_version == 3 && new_version == 5)
748 typedef struct dt_iop_filmicrgb_params_v3_t
750 float grey_point_source;
751 float black_point_source;
752 float white_point_source;
753 float reconstruct_threshold;
754 float reconstruct_feather;
755 float reconstruct_bloom_vs_details;
757 float reconstruct_grey_vs_color;
759 float reconstruct_structure_vs_texture;
761 float security_factor;
762 float grey_point_target;
763 float black_point_target;
764 float white_point_target;
775 gboolean auto_hardness;
776 gboolean custom_grey;
777 int high_quality_reconstruction;
779 int noise_distribution;
783 } dt_iop_filmicrgb_params_v3_t;
785 dt_iop_filmicrgb_params_v3_t *o = (dt_iop_filmicrgb_params_v3_t *)old_params;
791 n->grey_point_source = o->grey_point_source;
792 n->white_point_source = o->white_point_source;
793 n->black_point_source = o->black_point_source;
794 n->security_factor = o->security_factor;
795 n->grey_point_target = o->grey_point_target;
796 n->black_point_target = o->black_point_target;
797 n->white_point_target = o->white_point_target;
798 n->output_power = o->output_power;
799 n->latitude = o->latitude;
800 n->contrast = o->contrast;
801 n->saturation = o->saturation;
802 n->balance = o->balance;
803 n->preserve_color = o->preserve_color;
804 n->shadows = o->shadows;
805 n->highlights = o->highlights;
806 n->reconstruct_threshold = o->reconstruct_threshold;
807 n->reconstruct_bloom_vs_details = o->reconstruct_bloom_vs_details;
808 n->reconstruct_grey_vs_color = o->reconstruct_grey_vs_color;
809 n->reconstruct_structure_vs_texture = o->reconstruct_structure_vs_texture;
810 n->reconstruct_feather = o->reconstruct_feather;
811 n->version = o->version;
812 n->auto_hardness = o->auto_hardness;
813 n->custom_grey = o->custom_grey;
814 n->high_quality_reconstruction = o->high_quality_reconstruction;
815 n->noise_level =
d->noise_level;
816 n->noise_distribution =
d->noise_distribution;
817 n->noise_level =
d->noise_level;
819 n->compensate_icc_black =
FALSE;
823 if(old_version == 4 && new_version == 5)
825 typedef struct dt_iop_filmicrgb_params_v4_t
827 float grey_point_source;
828 float black_point_source;
829 float white_point_source;
830 float reconstruct_threshold;
831 float reconstruct_feather;
832 float reconstruct_bloom_vs_details;
833 float reconstruct_grey_vs_color;
834 float reconstruct_structure_vs_texture;
835 float security_factor;
836 float grey_point_target;
837 float black_point_target;
838 float white_point_target;
847 gboolean auto_hardness;
848 gboolean custom_grey;
849 int high_quality_reconstruction;
853 gboolean compensate_icc_black;
854 gint internal_version;
855 } dt_iop_filmicrgb_params_v4_t;
857 dt_iop_filmicrgb_params_v4_t *o = (dt_iop_filmicrgb_params_v4_t *)old_params;
861 switch(o->internal_version)
881static inline __attribute__((always_inline))
float pixel_rgb_norm_power_simd(
const dt_aligned_pixel_simd_t pixel)
886 float numerator = 0.0f;
887 float denominator = 0.0f;
889 for(
int c = 0; c < 3; c++)
891 const float value = fabsf(pixel[c]);
893 const float RGB_cubic = RGB_square *
value;
894 numerator += RGB_cubic;
895 denominator += RGB_square;
898 return numerator / fmaxf(denominator, 1e-12f);
904 return pixel_rgb_norm_power_simd(dt_load_simd_aligned(pixel));
921 return fmaxf(fmaxf(pixel[0], pixel[1]), pixel[2]);
930 return dt_ioppr_get_rgb_matrix_luminance(
rgb, work_profile->
matrix_in, work_profile->
lut_in,
931 work_profile->unbounded_coeffs_in, work_profile->
lutsize,
935 return work_profile->
matrix_in[1][0] * pixel[0] + work_profile->
matrix_in[1][1] * pixel[1]
936 + work_profile->
matrix_in[1][2] * pixel[2];
939 return pixel[0] * 0.2225045f + pixel[1] * 0.7168786f + pixel[2] * 0.0606169f;
942 return pixel_rgb_norm_power_simd(pixel);
945 return sqrtf(sqf(pixel[0]) + sqf(pixel[1]) + sqf(pixel[2]));
948 return sqrtf(sqf(pixel[0]) + sqf(pixel[1]) + sqf(pixel[2])) *
INVERSE_SQRT_3;
957 return dt_ioppr_get_rgb_matrix_luminance(
rgb, work_profile->
matrix_in, work_profile->
lut_in,
958 work_profile->unbounded_coeffs_in, work_profile->
lutsize,
962 return work_profile->
matrix_in[1][0] * pixel[0] + work_profile->
matrix_in[1][1] * pixel[1]
963 + work_profile->
matrix_in[1][2] * pixel[2];
966 return pixel[0] * 0.2225045f + pixel[1] * 0.7168786f + pixel[2] * 0.0606169f;
975 return get_pixel_norm_simd(dt_load_simd_aligned(pixel), variant, work_profile);
980 const
float dynamic_range)
982 return clamp_simd((log2f(
x / grey) - black) / dynamic_range);
987 const
float dynamic_range)
990 return grey * exp2f(dynamic_range *
x + black);
1009 if(
x < latitude_min)
1015 result = M1[0] +
x * (M2[0] +
x * (M3[0] +
x * (M4[0] +
x * M5[0])));
1020 result = M1[0] +
x * (M2[0] +
x * (M3[0] +
x * M4[0]));
1025 const float xi = latitude_min -
x;
1026 const float rat = xi * (xi * M2[0] + 1.f);
1027 result = M4[0] - M1[0] * rat / (rat + M3[0]);
1030 else if(
x > latitude_max)
1036 result = M1[1] +
x * (M2[1] +
x * (M3[1] +
x * (M4[1] +
x * M5[1])));
1041 result = M1[1] +
x * (M2[1] +
x * (M3[1] +
x * M4[1]));
1046 const float xi =
x - latitude_max;
1047 const float rat = xi * (xi * M2[1] + 1.f);
1048 result = M4[1] + M1[1] * rat / (rat + M3[1]);
1054 result = M1[2] +
x * M2[2];
1062filmic_desaturate_v1(
const float x,
const float sigma_toe,
const float sigma_shoulder,
1063 const float saturation)
1065 const float radius_toe =
x;
1066 const float radius_shoulder = 1.0f -
x;
1068 const float key_toe = expf(-0.5f * radius_toe * radius_toe / sigma_toe);
1069 const float key_shoulder = expf(-0.5f * radius_shoulder * radius_shoulder / sigma_shoulder);
1071 return 1.0f -
clamp_simd((key_toe + key_shoulder) / saturation);
1077filmic_desaturate_v2(
const float x,
const float sigma_toe,
const float sigma_shoulder,
1078 const float saturation)
1080 const float radius_toe =
x;
1081 const float radius_shoulder = 1.0f -
x;
1082 const float sat2 = 0.5f / sqrtf(saturation);
1083 const float key_toe = expf(-radius_toe * radius_toe / sigma_toe * sat2);
1084 const float key_shoulder = expf(-radius_shoulder * radius_shoulder / sigma_shoulder * sat2);
1086 return (saturation - (key_toe + key_shoulder) * (saturation));
1097#define MAX_NUM_SCALES 10
1100 const float normalize,
const float feathering,
const size_t width,
1101 const size_t height,
const size_t ch)
1113 const float pix_max = fmaxf(sqrtf(sqf(in[
k]) + sqf(in[
k + 1]) + sqf(in[
k + 2])), 0.f);
1114 const float argument = -pix_max *
normalize + feathering;
1122 clipped += (4.f > argument);
1126 return (clipped > 9);
1129 float *
const inpainted,
const float noise_level,
const float threshold,
1138 for(
size_t j = 0; j <
width; j++)
1148 const size_t idx =
i *
width + j;
1149 const size_t index = idx * 4;
1150 const float weight = mask[idx];
1151 const float *
const restrict pix_in = __builtin_assume_aligned(in + index, 16);
1163 float *
const restrict pix_out = __builtin_assume_aligned(inpainted + index, 16);
1171 const float *
const restrict texture,
const float *
const restrict mask,
1172 float *
const restrict reconstructed,
const size_t width,
1173 const size_t height,
const size_t ch,
const float gamma,
1174 const float gamma_comp,
const float beta,
const float beta_comp,
1175 const float delta,
const size_t s,
const size_t scales)
1180 const float alpha = mask[
k /
ch];
1183 const float *
const restrict HF_c = __builtin_assume_aligned(HF +
k, 16);
1184 const float *
const restrict LF_c = __builtin_assume_aligned(LF +
k, 16);
1185 const float *
const restrict TT_c = __builtin_assume_aligned(texture +
k, 16);
1194 const float grey_details = (HF_c[0] + HF_c[1] + HF_c[2]) / 3.f;
1199 const float grey_HF = beta_comp * (gamma_comp * grey_details + gamma * grey_texture);
1203 const float grey_residual = beta_comp * (LF_c[0] + LF_c[1] + LF_c[2]) / 3.f;
1204 __OMP_SIMD__(aligned(reconstructed:64) aligned(HF_c, LF_c, TT_c:16))
1205 for(
size_t c = 0; c < 4; c++)
1212 const float details = (gamma_comp * HF_c[c] + gamma * TT_c[c]) * beta + grey_HF;
1215 const float residual = (s == scales - 1) ? (grey_residual + LF_c[c] * beta) : 0.f;
1216 reconstructed[
k + c] += alpha * (
delta * details + residual);
1223 const float *
const restrict texture,
1224 const float *
const restrict mask,
1225 float *
const restrict reconstructed,
const size_t width,
1226 const size_t height,
const size_t ch,
const float gamma,
1227 const float gamma_comp,
const float beta,
const float beta_comp,
1228 const float delta,
const size_t s,
const size_t scales)
1246 const float alpha = mask[
k /
ch];
1249 const float *
const restrict HF_c = __builtin_assume_aligned(HF +
k, 16);
1250 const float *
const restrict LF_c = __builtin_assume_aligned(LF +
k, 16);
1251 const float *
const restrict TT_c = __builtin_assume_aligned(texture +
k, 16);
1260 const float grey_details = (HF_c[0] + HF_c[1] + HF_c[2]) / 3.f;
1265 const float grey_HF = (gamma_comp * grey_details + gamma * grey_texture);
1267 for(
size_t c = 0; c < 4; c++)
1271 const float details = 0.5f * ((gamma_comp * HF_c[c] + gamma * TT_c[c]) + grey_HF);
1274 const float residual = (s == scales - 1) ? LF_c[c] : 0.f;
1275 reconstructed[
k + c] += alpha * (
delta * details + residual);
1282static inline void init_reconstruct(
const float *
const restrict in,
const float *
const restrict mask,
1283 float *
const restrict reconstructed,
const size_t width,
1292 reconstructed[4*
k + c] = fmaxf(in[4*
k + c] * (1.f - mask[
k]), 0.f);
1299 float *
const restrict HF,
float *
const restrict texture,
1304 for(
size_t c = 0; c < 4; ++c) HF[4*
k + c] = texture[4*
k + c] = detail[4*
k + c] - LF[4*
k + c];
1329 const float *
const restrict in,
const float *
const restrict mask,
1330 float *
const restrict reconstructed,
1338 const int scales =
get_scales(pipe, roi_in, piece);
1374 for(
int s = 0; s < scales; ++s)
1376 const float *restrict detail;
1378 float *restrict HF_RGB_temp;
1385 HF_RGB_temp = LF_even;
1391 HF_RGB_temp = LF_odd;
1397 HF_RGB_temp = LF_even;
1400 const int mult = 1 << s;
1415 gamma, gamma_comp, beta, beta_comp,
delta, s, scales);
1418 gamma, gamma_comp, beta, beta_comp,
delta, s, scales);
1441 const float *
const restrict pix_in = in +
k;
1442 float *
const restrict pix_out =
out +
k;
1446 for(
int c = 0; c < 3; c++)
1451 const float lum = (work_profile)
1452 ? dt_ioppr_get_rgb_matrix_luminance(temp, work_profile->
matrix_in, work_profile->
lut_in,
1453 work_profile->unbounded_coeffs_in,
1461 for(
int c = 0; c < 3; c++)
1464 spline.
M1, spline.
M2, spline.
M3, spline.
M4, spline.
M5,
1466 spline.
y[0], spline.
y[4]),
1482 const float *
const restrict pix_in = in +
k;
1483 float *
const restrict pix_out =
out +
k;
1487 for(
int c = 0; c < 3; c++)
1492 const float lum = (work_profile)
1493 ? dt_ioppr_get_rgb_matrix_luminance(temp, work_profile->
matrix_in, work_profile->
lut_in,
1494 work_profile->unbounded_coeffs_in,
1502 for(
int c = 0; c < 3; c++)
1505 spline.
M1, spline.
M2, spline.
M3, spline.
M4, spline.
M5,
1507 spline.
y[0], spline.
y[4]),
1523 const float *
const restrict pix_in = in +
k;
1524 float *
const restrict pix_out =
out +
k;
1527 float norm = fmaxf(get_pixel_norm(pix_in, variant, work_profile),
NORM_MIN);
1531 ratios[c] = pix_in[c] / norm;
1534 const float min_ratios = fminf(fminf(ratios[0], ratios[1]), ratios[2]);
1535 if(min_ratios < 0.0f)
1546 const float lum = (work_profile) ? dt_ioppr_get_rgb_matrix_luminance(
1547 ratios, work_profile->
matrix_in, work_profile->
lut_in, work_profile->unbounded_coeffs_in,
1552 for(
int c = 0; c < 3; c++) ratios[c] =
linear_saturation(ratios[c], lum, desaturation) / norm;
1556 norm = powf(
CLAMPF(filmic_spline(norm, spline.
M1, spline.
M2, spline.
M3, spline.
M4, spline.
M5,
1558 spline.
y[0], spline.
y[4]),
1578 const float *
const restrict pix_in = in +
k;
1579 float *
const restrict pix_out =
out +
k;
1581 float norm = fmaxf(get_pixel_norm(pix_in, variant, work_profile),
NORM_MIN);
1587 ratios[c] = pix_in[c] / norm;
1590 const float min_ratios = fminf(fminf(ratios[0], ratios[1]), ratios[2]);
1591 const int sanitize = (min_ratios < 0.0f);
1595 ratios[c] -= min_ratios;
1605 norm = powf(
CLAMPF(filmic_spline(norm, spline.
M1, spline.
M2, spline.
M3, spline.
M4, spline.
M5,
1607 spline.
y[0], spline.
y[4]),
1611 for(
int c = 0; c < 3; c++) ratios[c] = fmaxf(ratios[c] + (1.0f - ratios[c]) * (1.0f - desaturation), 0.0f);
1616 norm /= fmaxf(get_pixel_norm(ratios, variant, work_profile),
NORM_MIN);
1619 pix_out[c] = ratios[c] * norm;
1622 const float max_pix = fmaxf(fmaxf(pix_out[0], pix_out[1]), pix_out[2]);
1623 const int penalize = (max_pix > 1.0f);
1630 ratios[c] = fmaxf(ratios[c] + (1.0f - max_pix), 0.0f);
1631 pix_out[c] = ratios[c] * norm;
1638static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
1639pipe_RGB_to_Ych_simd(
const dt_aligned_pixel_simd_t in,
const dt_aligned_pixel_simd_t matrix0,
1640 const dt_aligned_pixel_simd_t matrix1,
const dt_aligned_pixel_simd_t matrix2)
1651 const dt_aligned_pixel_simd_t
Yrg = LMS_to_Yrg_simd(dt_mat3x4_mul_vec4(in, matrix0, matrix1, matrix2));
1652 const float r =
Yrg[1] - 0.21902143f;
1653 const float g =
Yrg[2] - 0.54371398f;
1654 const float c = dt_fast_hypotf(
g,
r);
1655 const float cos_h =
c != 0.f ?
r /
c : 1.f;
1656 const float sin_h =
c != 0.f ?
g /
c : 0.f;
1657 return (dt_aligned_pixel_simd_t){
Yrg[0],
c, cos_h, sin_h };
1661static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
1662Ych_to_pipe_RGB_simd(
const dt_aligned_pixel_simd_t in,
const dt_aligned_pixel_simd_t matrix0,
1663 const dt_aligned_pixel_simd_t matrix1,
const dt_aligned_pixel_simd_t matrix2)
1668 const dt_aligned_pixel_simd_t
Yrg = {
1670 in[1] * in[2] + 0.21902143f,
1671 in[1] * in[3] + 0.54371398f,
1674 return dt_mat3x4_mul_vec4(Yrg_to_LMS_simd(Yrg), matrix0, matrix1, matrix2);
1677static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
1678filmic_desaturate_v4(
const dt_aligned_pixel_simd_t Ych_original, dt_aligned_pixel_simd_t Ych_final,
1679 const float saturation)
1687 const float chroma_original = Ych_original[1] * Ych_original[0];
1688 float chroma_final = Ych_final[1] * Ych_final[0];
1697 const float delta_chroma = saturation * (chroma_original - chroma_final);
1699 const int filmic_brightens = (Ych_final[0] > Ych_original[0]);
1700 const int filmic_resat = (chroma_original < chroma_final);
1701 const int filmic_desat = (chroma_original > chroma_final);
1702 const int user_resat = (saturation > 0.f);
1703 const int user_desat = (saturation < 0.f);
1705 chroma_final = (filmic_brightens && filmic_resat)
1706 ? (chroma_original + chroma_final) / 2.f
1707 : ((user_resat && filmic_desat) || user_desat)
1708 ? chroma_final + delta_chroma
1711 Ych_final[1] = fmaxf(chroma_final / Ych_final[0], 0.f);
1721#define CIE_Y_1931_to_CIE_Y_2006(x) (1.05785528f * (x))
1725clip_chroma_white_raw(
const float coeffs[3],
const float target_white,
const float Y,
1726 const float cos_h,
const float sin_h)
1728 const float denominator_Y_coeff = coeffs[0] * (0.979381443298969f * cos_h + 0.391752577319588f * sin_h)
1729 + coeffs[1] * (0.0206185567010309f * cos_h + 0.608247422680412f * sin_h)
1730 - coeffs[2] * (cos_h + sin_h);
1731 const float denominator_target_term = target_white * (0.68285981628866f * cos_h + 0.482137060515464f * sin_h);
1734 if(denominator_Y_coeff == 0.f)
return FLT_MAX;
1739 const float Y_asymptote = denominator_target_term / denominator_Y_coeff;
1740 if(Y <= Y_asymptote)
return FLT_MAX;
1746 const float denominator = Y * denominator_Y_coeff - denominator_target_term;
1747 const float numerator = -0.427506877216495f
1748 * (Y * (coeffs[0] + 0.856492345150334f * coeffs[1] + 0.554995960637719f * coeffs[2])
1749 - 0.988237752433297f * target_white);
1751 return numerator / denominator;
1756clip_chroma_white(
const float coeffs[3],
const float target_white,
const float Y,
1757 const float cos_h,
const float sin_h)
1763 const float eps = 1e-3f;
1765 const float delta_Y =
MAX(max_Y - Y, 0.f);
1769 max_chroma = delta_Y / (
eps * max_Y) * clip_chroma_white_raw(coeffs, target_white, (1.f -
eps) * max_Y, cos_h, sin_h);
1773 max_chroma = clip_chroma_white_raw(coeffs, target_white, Y, cos_h, sin_h);
1775 return max_chroma >= 0.f ? max_chroma : FLT_MAX;
1780clip_chroma_black(
const float coeffs[3],
const float cos_h,
const float sin_h)
1789 const float denominator = coeffs[0] * (0.979381443298969f * cos_h + 0.391752577319588f * sin_h)
1790 + coeffs[1] * (0.0206185567010309f * cos_h + 0.608247422680412f * sin_h)
1791 - coeffs[2] * (cos_h + sin_h);
1794 if(denominator == 0.f)
return FLT_MAX;
1796 const float numerator = -0.427506877216495f * (coeffs[0] + 0.856492345150334f * coeffs[1] + 0.554995960637719f * coeffs[2]);
1797 const float max_chroma = numerator / denominator;
1798 return max_chroma >= 0.f ? max_chroma : FLT_MAX;
1803clip_chroma(
const dt_colormatrix_t matrix_out,
const float target_white,
const float Y,
1804 const float cos_h,
const float sin_h,
const float chroma)
1812 const float chroma_R_white = clip_chroma_white(matrix_out[0], target_white, Y, cos_h, sin_h);
1813 const float chroma_G_white = clip_chroma_white(matrix_out[1], target_white, Y, cos_h, sin_h);
1814 const float chroma_B_white = clip_chroma_white(matrix_out[2], target_white, Y, cos_h, sin_h);
1815 const float max_chroma_white =
MIN(
MIN(chroma_R_white, chroma_G_white), chroma_B_white);
1817 const float chroma_R_black = clip_chroma_black(matrix_out[0], cos_h, sin_h);
1818 const float chroma_G_black = clip_chroma_black(matrix_out[1], cos_h, sin_h);
1819 const float chroma_B_black = clip_chroma_black(matrix_out[2], cos_h, sin_h);
1820 const float max_chroma_black =
MIN(
MIN(chroma_R_black, chroma_G_black), chroma_B_black);
1822 return MIN(
MIN(chroma, max_chroma_black), max_chroma_white);
1826static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
1827gamut_check_Yrg_filmic_simd(
const dt_aligned_pixel_simd_t Ych)
1831 const dt_aligned_pixel_simd_t
Yrg = {
1833 Ych[1] * Ych[2] + 0.21902143f,
1834 Ych[1] * Ych[3] + 0.54371398f,
1837 float max_c = Ych[1];
1839 if(Yrg[1] < 0.f) max_c = fminf(-0.21902143f / Ych[2], max_c);
1840 if(Yrg[2] < 0.f) max_c = fminf(-0.54371398f / Ych[3], max_c);
1841 if(Yrg[1] + Yrg[2] > 1.f) max_c = fminf((1.f - 0.21902143f - 0.54371398f) / (Ych[2] + Ych[3]), max_c);
1843 return (dt_aligned_pixel_simd_t){ Ych[0], max_c, Ych[2], Ych[3] };
1847static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
1848gamut_check_RGB_simd(
const dt_colormatrix_t matrix_out,
const dt_aligned_pixel_simd_t matrix_in0,
1849 const dt_aligned_pixel_simd_t matrix_in1,
const dt_aligned_pixel_simd_t matrix_in2,
1850 const dt_aligned_pixel_simd_t matrix_out0,
const dt_aligned_pixel_simd_t matrix_out1,
1851 const dt_aligned_pixel_simd_t matrix_out2,
const float display_black,
1852 const float display_white,
const dt_aligned_pixel_simd_t Ych_in)
1856 dt_aligned_pixel_simd_t RGB_brightened = Ych_to_pipe_RGB_simd(Ych_in, matrix_out0, matrix_out1, matrix_out2);
1857 const float min_pix =
MIN(
MIN(RGB_brightened[0], RGB_brightened[1]), RGB_brightened[2]);
1858 const float black_offset =
MAX(-min_pix, 0.f);
1861 const dt_aligned_pixel_simd_t Ych_brightened
1862 = pipe_RGB_to_Ych_simd(RGB_brightened, matrix_in0, matrix_in1, matrix_in2);
1868 const float Y = CLAMP((Ych_in[0] + Ych_brightened[0]) / 2.f,
1871 const float new_chroma = clip_chroma(matrix_out, display_white, Y, Ych_in[2], Ych_in[3], Ych_in[1]);
1874 dt_aligned_pixel_simd_t RGB_out
1875 = Ych_to_pipe_RGB_simd((dt_aligned_pixel_simd_t){
Y, new_chroma, Ych_in[2], Ych_in[3] },
1876 matrix_out0, matrix_out1, matrix_out2);
1884static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
1885gamut_mapping_simd(dt_aligned_pixel_simd_t Ych_final,
const dt_aligned_pixel_simd_t Ych_original,
1886 const dt_colormatrix_t output_matrix,
const dt_aligned_pixel_simd_t input_matrix0,
1887 const dt_aligned_pixel_simd_t input_matrix1,
const dt_aligned_pixel_simd_t input_matrix2,
1888 const dt_aligned_pixel_simd_t output_matrix0,
const dt_aligned_pixel_simd_t output_matrix1,
1889 const dt_aligned_pixel_simd_t output_matrix2,
1890 const dt_colormatrix_t export_output_matrix,
const dt_aligned_pixel_simd_t export_input_matrix0,
1891 const dt_aligned_pixel_simd_t export_input_matrix1,
const dt_aligned_pixel_simd_t export_input_matrix2,
1892 const dt_aligned_pixel_simd_t export_output_matrix0,
const dt_aligned_pixel_simd_t export_output_matrix1,
1893 const dt_aligned_pixel_simd_t export_output_matrix2,
const float display_black,
1894 const float display_white,
const float saturation,
const int use_output_profile)
1897 Ych_final[2] = Ych_original[2];
1898 Ych_final[3] = Ych_original[3];
1904 Ych_final = filmic_desaturate_v4(Ych_original, Ych_final, saturation);
1905 Ych_final = gamut_check_Yrg_filmic_simd(Ych_final);
1907 if(!use_output_profile)
1911 return gamut_check_RGB_simd(output_matrix, input_matrix0, input_matrix1, input_matrix2,
1912 output_matrix0, output_matrix1, output_matrix2,
1913 display_black, display_white, Ych_final);
1918 dt_aligned_pixel_simd_t pix_out
1919 = gamut_check_RGB_simd(export_output_matrix, export_input_matrix0, export_input_matrix1, export_input_matrix2,
1920 export_output_matrix0, export_output_matrix1, export_output_matrix2,
1921 display_black, display_white, Ych_final);
1924 const dt_aligned_pixel_simd_t
LMS
1925 = dt_mat3x4_mul_vec4(pix_out, export_input_matrix0, export_input_matrix1, export_input_matrix2);
1927 return dt_mat3x4_mul_vec4(
LMS, output_matrix0, output_matrix1, output_matrix2);
1948 const int use_output_profile = (!
IS_NULL_PTR(export_profile));
1949 if(use_output_profile)
1960 return use_output_profile;
1997 simd_matrices->
input[
row] = dt_colormatrix_row_to_simd(input_matrix_t,
row);
1998 simd_matrices->
output[
row] = dt_colormatrix_row_to_simd(output_matrix_t,
row);
1999 simd_matrices->
export_input[
row] = dt_colormatrix_row_to_simd(export_input_matrix_t,
row);
2000 simd_matrices->
export_output[
row] = dt_colormatrix_row_to_simd(export_output_matrix_t,
row);
2004static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
2005norm_tone_mapping_v4_simd(
const dt_aligned_pixel_simd_t pix_in,
2010 const float norm_min,
const float norm_max)
2014 float norm =
CLAMPF(get_pixel_norm_simd(pix_in,
type, work_profile), norm_min, norm_max);
2016 const dt_aligned_pixel_simd_t ratios = pix_in /
dt_simd_set1(norm);
2022 norm = powf(
CLAMPF(filmic_spline(norm, spline.
M1, spline.
M2, spline.
M3, spline.
M4, spline.
M5,
2024 spline.
y[0], spline.
y[4]),
2031static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
2037 dt_aligned_pixel_simd_t pix_out = pix_in;
2038 for(
size_t c = 0;
c < 3;
c++)
2041 pix_out[
c] = powf(
CLAMPF(filmic_spline(mapped, spline.
M1, spline.
M2, spline.
M3, spline.
M4, spline.
M5,
2058 const float display_black,
const float display_white)
2066 const int use_output_profile = filmic_v4_prepare_matrices(input_matrix, output_matrix, export_input_matrix,
2067 export_output_matrix, work_profile, export_profile);
2076 const dt_aligned_pixel_simd_t pix_in = dt_load_simd_aligned(in +
k);
2077 const dt_aligned_pixel_simd_t pix_out
2078 = norm_tone_mapping_v4_simd(pix_in, variant, work_profile, data, spline, norm_min, norm_max);
2081 const dt_aligned_pixel_simd_t Ych_original = pipe_RGB_to_Ych_simd(pix_in, simd_matrices.
input[0],
2082 simd_matrices.
input[1], simd_matrices.
input[2]);
2083 const dt_aligned_pixel_simd_t Ych_final = pipe_RGB_to_Ych_simd(pix_out, simd_matrices.
input[0],
2084 simd_matrices.
input[1], simd_matrices.
input[2]);
2086 dt_store_simd_nontemporal(
out +
k,
2087 gamut_mapping_simd(Ych_final, Ych_original, output_matrix,
2088 simd_matrices.
input[0], simd_matrices.
input[1], simd_matrices.
input[2],
2090 export_output_matrix,
2093 display_black, display_white, data->
saturation, use_output_profile));
2106 const float display_black,
const float display_white)
2115 const int use_output_profile = filmic_v4_prepare_matrices(input_matrix, output_matrix, export_input_matrix,
2116 export_output_matrix, work_profile, export_profile);
2122 const dt_aligned_pixel_simd_t pix_in = dt_load_simd_aligned(in +
k);
2123 const dt_aligned_pixel_simd_t pix_out = RGB_tone_mapping_v4_simd(pix_in, data, spline);
2124 const dt_aligned_pixel_simd_t Ych_original = pipe_RGB_to_Ych_simd(pix_in, simd_matrices.
input[0],
2125 simd_matrices.
input[1], simd_matrices.
input[2]);
2126 dt_aligned_pixel_simd_t Ych_final = pipe_RGB_to_Ych_simd(pix_out, simd_matrices.
input[0],
2127 simd_matrices.
input[1], simd_matrices.
input[2]);
2129 Ych_final[1] = fminf(Ych_original[1], Ych_final[1]);
2131 dt_store_simd_nontemporal(
out +
k,
2132 gamut_mapping_simd(Ych_final, Ych_original, output_matrix,
2133 simd_matrices.
input[0], simd_matrices.
input[1], simd_matrices.
input[2],
2135 export_output_matrix,
2138 display_black, display_white, data->
saturation, use_output_profile));
2145static inline void filmic_v5(
const float *
const restrict in,
float *
const restrict
out,
2150 const size_t height,
const size_t ch,
const float display_black,
2151 const float display_white)
2160 const int use_output_profile = filmic_v4_prepare_matrices(input_matrix, output_matrix, export_input_matrix,
2161 export_output_matrix, work_profile, export_profile);
2170 const dt_aligned_pixel_simd_t pix_in = dt_load_simd_aligned(in +
k);
2171 const dt_aligned_pixel_simd_t naive_rgb = RGB_tone_mapping_v4_simd(pix_in, data, spline);
2172 const dt_aligned_pixel_simd_t max_rgb
2179 const dt_aligned_pixel_simd_t Ych_original = pipe_RGB_to_Ych_simd(pix_in, simd_matrices.
input[0],
2180 simd_matrices.
input[1], simd_matrices.
input[2]);
2182 dt_aligned_pixel_simd_t Ych_final = pipe_RGB_to_Ych_simd(pix_out, simd_matrices.
input[0],
2183 simd_matrices.
input[1], simd_matrices.
input[2]);
2185 Ych_final[1] = fminf(Ych_original[1], Ych_final[1]);
2187 dt_store_simd_nontemporal(
out +
k,
2188 gamut_mapping_simd(Ych_final, Ych_original, output_matrix,
2189 simd_matrices.
input[0], simd_matrices.
input[1], simd_matrices.
input[2],
2191 export_output_matrix,
2194 display_black, display_white, 0.f, use_output_profile));
2201static inline void display_mask(
const float *
const restrict mask,
float *
const restrict
out,
2214static inline void compute_ratios(
const float *
const restrict in,
float *
const restrict norms,
2215 float *
const restrict ratios,
2217 const int variant,
const size_t width,
const size_t height)
2222 const dt_aligned_pixel_simd_t pix_in = dt_load_simd_aligned(in +
k);
2223 const float norm = fmaxf(get_pixel_norm_simd(pix_in, variant, work_profile),
NORM_MIN);
2224 norms[
k / 4] = norm;
2225 dt_store_simd_nontemporal(ratios +
k, pix_in /
dt_simd_set1(norm));
2232static inline void restore_ratios(
float *
const restrict ratios,
const float *
const restrict norms,
2238 dt_aligned_pixel_simd_t ratio = dt_load_simd_aligned(ratios + 4 *
k);
2239 const float norm = norms[
k];
2244 dt_store_simd_nontemporal(ratios + 4 *
k, ratio);
2252 const int scales =
get_scales(pipe, roi_in, piece);
2253 const int max_filter_radius = (1 << scales);
2257 tiling->factor_cl = 9.0f;
2260 tiling->maxbuf_cl = 1.0f;
2262 tiling->overlap = max_filter_radius;
2270 const void *
const restrict ivoid,
2271 void *
const restrict
ovoid)
2279 const size_t ch = 4;
2290 float *restrict in = (
float *)ivoid;
2291 float *
const restrict
out = (
float *)
ovoid;
2315 if(recover_highlights &&
IS_NULL_PTR(reconstructed))
2370 data, piece, roi_in, roi_out))
2395 const float white_display = powf(data->spline.y[4], data->
output_power);
2396 const float black_display = powf(data->spline.y[0], data->
output_power);
2400 filmic_v5(in,
out, work_profile, export_profile, data, data->spline, roi_out->
width,
2401 roi_out->
height,
ch, black_display, white_display);
2445 const int devid = pipe->
devid;
2451 const int scales =
get_scales(pipe, roi_in, piece);
2464 err = CL_MEM_OBJECT_ALLOCATION_FAILURE;
2475 if(err != CL_SUCCESS)
goto error;
2493 for(
int s = 0; s < scales; ++s)
2515 const int mult = 1 << s;
2518 const int clamp_lf = 1;
2521 .yoffset = 0, .yfactor = 1,
2522 .cellsize = 4 *
sizeof(float), .overhead = 0,
2523 .sizex = 1 << 16, .sizey = 1 };
2525 hblocksize = hlocopt.
sizex;
2532 const size_t horizontal_local[3] = { hblocksize, 1, 1 };
2540 (hblocksize + 4 * mult) * 4 *
sizeof(
float), NULL);
2542 horizontal_sizes, horizontal_local);
2554 if(err != CL_SUCCESS)
goto error;
2558 .yoffset = 2 * mult, .yfactor = 1,
2559 .cellsize = 4 *
sizeof(float), .overhead = 0,
2560 .sizex = 1, .sizey = 1 << 16 };
2562 vblocksize = vlocopt.
sizey;
2569 const size_t vertical_local[3] = { 1, vblocksize, 1 };
2577 (vblocksize + 4 * mult) * 4 *
sizeof(
float), NULL);
2579 vertical_sizes, vertical_local);
2591 if(err != CL_SUCCESS)
goto error;
2601 if(err != CL_SUCCESS)
goto error;
2604 size_t origin[] = { 0, 0, 0 };
2606 if(err != CL_SUCCESS)
goto error;
2609 const int blur_size = 1;
2610 const int clamp_hf = 0;
2618 if(err != CL_SUCCESS)
goto error;
2627 if(err != CL_SUCCESS)
goto error;
2647 if(err != CL_SUCCESS)
goto error;
2668 const int devid = pipe->
devid;
2675 cl_mem inpainted = NULL;
2676 cl_mem reconstructed = NULL;
2678 cl_mem ratios = NULL;
2679 cl_mem norms = NULL;
2684 const int use_work_profile = (
IS_NULL_PTR(work_profile)) ? 0 : 1;
2692 const int use_output_profile = filmic_v4_prepare_matrices(input_matrix, output_matrix, export_input_matrix,
2693 export_output_matrix, work_profile, export_profile);
2698 float input_matrix_3x4[12];
2699 float output_matrix_3x4[12];
2705 cl_mem export_input_matrix_cl = NULL;
2706 cl_mem export_output_matrix_cl = NULL;
2708 cl_mem dev_profile_info = NULL;
2709 cl_mem dev_profile_lut = NULL;
2711 cl_float *profile_lut_cl = NULL;
2713 cl_mem clipped = NULL;
2716 &dev_profile_info, &dev_profile_lut);
2717 if(err != CL_SUCCESS)
goto error;
2719 if(use_output_profile)
2721 float export_input_matrix_3x4[12];
2722 float export_output_matrix_3x4[12];
2732 uint32_t is_clipped = 0;
2735 if(err != CL_SUCCESS)
goto error;
2747 if(err != CL_SUCCESS)
goto error;
2751 if(err != CL_SUCCESS)
goto error;
2776 const float noise_level =
d->noise_level / scale;
2787 if(err != CL_SUCCESS)
goto error;
2792 if(err != CL_SUCCESS)
goto error;
2796 if(
d->high_quality_reconstruction > 0)
2803 for(
int i = 0;
i <
d->high_quality_reconstruction;
i++)
2813 if(err != CL_SUCCESS)
goto error;
2817 if(err != CL_SUCCESS)
goto error;
2826 if(err != CL_SUCCESS)
goto error;
2844 const float white_display = powf(spline.
y[4],
d->output_power);
2845 const float black_display = powf(spline.
y[0],
d->output_power);
2884 if(err != CL_SUCCESS)
goto error;
2926 if(err != CL_SUCCESS)
goto error;
2962 const float grey = get_pixel_norm(self->
picked_color,
p->preserve_color, work_profile) / 2.0f;
2964 const float prev_grey =
p->grey_point_source;
2965 p->grey_point_source = CLAMP(100.f * grey, 0.001f, 100.0f);
2966 const float grey_var = log2f(prev_grey /
p->grey_point_source);
2967 p->black_point_source =
p->black_point_source - grey_var;
2968 p->white_point_source =
p->white_point_source + grey_var;
2969 p->output_power = logf(
p->grey_point_target / 100.0f)
2970 / logf(-
p->black_point_source / (
p->white_point_source -
p->black_point_source));
2979 gtk_widget_queue_draw(self->
widget);
2993 float EVmin = CLAMP(log2f(black / (
p->grey_point_source / 100.0f)), -16.0f, -1.0f);
2994 EVmin *= (1.0f +
p->security_factor / 100.0f);
2996 p->black_point_source = fmaxf(EVmin, -16.0f);
2997 p->output_power = logf(
p->grey_point_target / 100.0f)
2998 / logf(-
p->black_point_source / (
p->white_point_source -
p->black_point_source));
3005 gtk_widget_queue_draw(self->
widget);
3020 float EVmax = CLAMP(log2f(white / (
p->grey_point_source / 100.0f)), 1.0f, 16.0f);
3021 EVmax *= (1.0f +
p->security_factor / 100.0f);
3023 p->white_point_source = EVmax;
3024 p->output_power = logf(
p->grey_point_target / 100.0f)
3025 / logf(-
p->black_point_source / (
p->white_point_source -
p->black_point_source));
3032 gtk_widget_queue_draw(self->
widget);
3045 const float grey = get_pixel_norm(self->
picked_color,
p->preserve_color, work_profile) / 2.0f;
3046 p->grey_point_source = CLAMP(100.f * grey, 0.001f, 100.0f);
3051 float EVmax = CLAMP(log2f(white / (
p->grey_point_source / 100.0f)), 1.0f, 16.0f);
3052 EVmax *= (1.0f +
p->security_factor / 100.0f);
3056 float EVmin = CLAMP(log2f(black / (
p->grey_point_source / 100.0f)), -16.0f, -1.0f);
3057 EVmin *= (1.0f +
p->security_factor / 100.0f);
3059 p->black_point_source = fmaxf(EVmin, -16.0f);
3060 p->white_point_source = EVmax;
3061 p->output_power = logf(
p->grey_point_target / 100.0f)
3062 / logf(-
p->black_point_source / (
p->white_point_source -
p->black_point_source));
3071 gtk_widget_queue_draw(self->
widget);
3085 const float *
const restrict in = (
const float *)
i;
3087 float min_Y = INFINITY;
3088 float max_RGB = 0.0f;
3091 for(
size_t k = 0;
k < (size_t)roi_out->
width * roi_out->
height * 4;
k += 4)
3095 work_profile->unbounded_coeffs_in, work_profile->
lutsize,
3098 if(isfinite(
XYZ[1]))
3099 min_Y = fminf(min_Y,
XYZ[1]);
3101 const float pixel_max = fmaxf(in[
k], fmaxf(in[
k + 1], in[
k + 2]));
3102 if(isfinite(pixel_max))
3103 max_RGB = fmaxf(max_RGB, pixel_max);
3106 if(!isfinite(min_Y) || !isfinite(max_RGB))
return;
3108 const float grey =
p->grey_point_source / 100.0f;
3109 const float white = fmaxf(max_RGB,
NORM_MIN);
3110 const float black = fmaxf(min_Y,
NORM_MIN);
3112 float EVmax = CLAMP(log2f(white / grey), 1.0f, 16.0f);
3113 EVmax *= (1.0f +
p->security_factor / 100.0f);
3115 float EVmin = CLAMP(log2f(black / grey), -16.0f, -1.0f);
3116 EVmin *= (1.0f +
p->security_factor / 100.0f);
3118 p->black_point_source = fmaxf(EVmin, -16.0f);
3119 p->white_point_source = EVmax;
3120 p->output_power = logf(
p->grey_point_target / 100.0f)
3121 / logf(-
p->black_point_source / (
p->white_point_source -
p->black_point_source));
3128 (
void *)picker, (
void *)pipe,
3135 if(picker ==
g->grey_point_source)
3137 else if(picker ==
g->black_point_source)
3139 else if(picker ==
g->white_point_source)
3141 else if(picker ==
g->auto_button)
3149 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->
off),
TRUE);
3156 g->show_mask = !(
g->show_mask);
3161 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
g->show_highlight_mask), !
g->show_mask);
3174 float grey_display = 0.4638f;
3175 gboolean clamping =
FALSE;
3180 grey_display = powf(CLAMP(
p->grey_point_target,
p->black_point_target,
p->white_point_target) / 100.0f,
3181 1.0f / (
p->output_power));
3186 grey_display = powf(0.1845f, 1.0f / (
p->output_power));
3189 const float white_source =
p->white_point_source;
3190 const float black_source =
p->black_point_source;
3191 const float dynamic_range = white_source - black_source;
3194 const float black_log = 0.0f;
3195 const float grey_log = fabsf(
p->black_point_source) / dynamic_range;
3196 const float white_log = 1.0f;
3199 float black_display, white_display;
3207 black_display = CLAMP(
p->black_point_target, 0.0f,
p->grey_point_target) / 100.0f;
3208 white_display = fmaxf(
p->white_point_target,
p->grey_point_target) / 100.0f;
3213 black_display = powf(CLAMP(
p->black_point_target, 0.0f,
p->grey_point_target) / 100.0f,
3214 1.0f / (
p->output_power));
3216 = powf(fmaxf(
p->white_point_target,
p->grey_point_target) / 100.0f, 1.0f / (
p->output_power));
3219 float toe_log, shoulder_log, toe_display, shoulder_display, contrast;
3220 float balance = CLAMP(
p->balance, -50.0f, 50.0f) / 100.0f;
3223 float latitude = CLAMP(
p->latitude, 0.0f, 100.0f) / 100.0f * dynamic_range;
3224 contrast = CLAMP(
p->contrast, 1.00001f, 6.0f);
3228 toe_log = grey_log - latitude / dynamic_range * fabsf(black_source / dynamic_range);
3229 shoulder_log = grey_log + latitude / dynamic_range * fabsf(white_source / dynamic_range);
3232 float linear_intercept = grey_display - (contrast * grey_log);
3235 toe_display = (toe_log * contrast + linear_intercept);
3236 shoulder_display = (shoulder_log * contrast + linear_intercept);
3239 const float norm = sqrtf(contrast * contrast + 1.0f);
3242 const float coeff = -((2.0f * latitude) / dynamic_range) * balance;
3244 toe_display +=
coeff * contrast / norm;
3245 shoulder_display +=
coeff * contrast / norm;
3246 toe_log +=
coeff / norm;
3247 shoulder_log +=
coeff / norm;
3273 spline->
x[0] = black_log;
3274 spline->
x[1] = toe_log;
3275 spline->
x[2] = grey_log;
3276 spline->
x[3] = shoulder_log;
3277 spline->
x[4] = white_log;
3279 spline->
y[0] = black_display;
3280 spline->
y[1] = toe_display;
3281 spline->
y[2] = grey_display;
3282 spline->
y[3] = shoulder_display;
3283 spline->
y[4] = white_display;
3288 spline->
type[0] =
p->shadows;
3289 spline->
type[1] =
p->highlights;
3296 const double Tl = spline->
x[1];
3297 const double Tl2 = Tl * Tl;
3298 const double Tl3 = Tl2 * Tl;
3299 const double Tl4 = Tl3 * Tl;
3301 const double Sl = spline->
x[3];
3302 const double Sl2 = Sl * Sl;
3303 const double Sl3 = Sl2 * Sl;
3304 const double Sl4 = Sl3 * Sl;
3314 spline->
M2[2] = contrast;
3315 spline->
M1[2] = spline->
y[1] - spline->
M2[2] * spline->
x[1];
3316 spline->
M3[2] = 0.f;
3317 spline->
M4[2] = 0.f;
3318 spline->
M5[2] = 0.f;
3326 Tl4, Tl3, Tl2, Tl, 1.,
3327 4. * Tl3, 3. * Tl2, 2. * Tl, 1., 0.,
3328 12. * Tl2, 6. * Tl, 2., 0., 0. };
3330 double b0[
ORDER_4] = { spline->
y[0], 0., spline->
y[1], spline->
M2[2], 0. };
3334 spline->
M5[0] = b0[0];
3335 spline->
M4[0] = b0[1];
3336 spline->
M3[0] = b0[2];
3337 spline->
M2[0] = b0[3];
3338 spline->
M1[0] = b0[4];
3345 3. * Tl2, 2. * Tl, 1., 0.,
3346 6. * Tl, 2., 0., 0. };
3348 double b0[
ORDER_3] = { spline->
y[0], spline->
y[1], spline->
M2[2], 0. };
3352 spline->
M5[0] = 0.0f;
3353 spline->
M4[0] = b0[0];
3354 spline->
M3[0] = b0[1];
3355 spline->
M2[0] = b0[2];
3356 spline->
M1[0] = b0[3];
3360 const float P1[2] = { black_log, black_display };
3361 const float P0[2] = { toe_log, toe_display };
3362 const float x = P0[0] - P1[0];
3363 const float y = P0[1] - P1[1];
3364 const float g = contrast;
3365 const float b =
g / (2.f * y) + (sqrtf(sqf(
x *
g / y + 1.f) - 4.f) - 1.f) / (2.f *
x);
3366 const float c = y /
g * (b * sqf(
x) +
x) / (b * sqf(
x) +
x - (y /
g));
3367 const float a = c *
g;
3371 spline->
M4[0] = toe_display;
3380 3. * Sl2, 2. * Sl, 1., 0.,
3381 6. * Sl, 2., 0., 0. };
3383 double b1[
ORDER_3] = { spline->
y[4], spline->
y[3], spline->
M2[2], 0. };
3387 spline->
M5[1] = 0.0f;
3388 spline->
M4[1] = b1[0];
3389 spline->
M3[1] = b1[1];
3390 spline->
M2[1] = b1[2];
3391 spline->
M1[1] = b1[3];
3398 Sl4, Sl3, Sl2, Sl, 1.,
3399 4. * Sl3, 3. * Sl2, 2. * Sl, 1., 0.,
3400 12. * Sl2, 6. * Sl, 2., 0., 0. };
3402 double b1[
ORDER_4] = { spline->
y[4], 0., spline->
y[3], spline->
M2[2], 0. };
3406 spline->
M5[1] = b1[0];
3407 spline->
M4[1] = b1[1];
3408 spline->
M3[1] = b1[2];
3409 spline->
M2[1] = b1[3];
3410 spline->
M1[1] = b1[4];
3414 const float P1[2] = { white_log, white_display };
3415 const float P0[2] = { shoulder_log, shoulder_display };
3416 const float x = P1[0] - P0[0];
3417 const float y = P1[1] - P0[1];
3418 const float g = contrast;
3419 const float b =
g / (2.f * y) + (sqrtf(sqf(
x *
g / y + 1.f) - 4.f) - 1.f) / (2.f *
x);
3420 const float c = y /
g * (b * sqf(
x) +
x) / (b * sqf(
x) +
x - (y /
g));
3421 const float a = c *
g;
3425 spline->
M4[1] = shoulder_display;
3437 float grey_source = 0.1845f, grey_display = 0.4638f;
3441 grey_source =
p->grey_point_source / 100.0f;
3442 grey_display = powf(
p->grey_point_target / 100.0f, 1.0f / (
p->output_power));
3447 grey_source = 0.1845f;
3448 grey_display = powf(0.1845f, 1.0f / (
p->output_power));
3452 const float white_source =
p->white_point_source;
3453 const float black_source =
p->black_point_source;
3454 const float dynamic_range = white_source - black_source;
3457 const float grey_log = fabsf(
p->black_point_source) / dynamic_range;
3460 float contrast =
p->contrast;
3465 contrast = 1.0001f * grey_display / grey_log;
3469 d->dynamic_range = dynamic_range;
3470 d->black_source = black_source;
3471 d->grey_source = grey_source;
3472 d->output_power =
p->output_power;
3473 d->contrast = contrast;
3474 d->version =
p->version;
3475 d->spline_version =
p->spline_version;
3476 d->preserve_color =
p->preserve_color;
3477 d->high_quality_reconstruction =
p->high_quality_reconstruction;
3478 d->noise_level =
p->noise_level;
3485 d->saturation =
p->saturation / 100.0f;
3487 d->saturation = (2.0f *
p->saturation / 100.0f + 1.0f);
3489 d->sigma_toe = powf(
d->spline.latitude_min / 3.0f, 2.0f);
3490 d->sigma_shoulder = powf((1.0f -
d->spline.latitude_max) / 3.0f, 2.0f);
3492 d->reconstruct_threshold = powf(2.0f, white_source +
p->reconstruct_threshold) * grey_source;
3493 d->reconstruct_feather = exp2f(12.f /
p->reconstruct_feather);
3496 d->normalize =
d->reconstruct_feather /
d->reconstruct_threshold;
3497 d->reconstruct_structure_vs_texture = (
p->reconstruct_structure_vs_texture / 100.0f + 1.f) / 2.f;
3498 d->reconstruct_bloom_vs_details = (
p->reconstruct_bloom_vs_details / 100.0f + 1.f) / 2.f;
3499 d->reconstruct_grey_vs_color = (
p->reconstruct_grey_vs_color / 100.0f + 1.f) / 2.f;
3509 gint mask_was_shown =
g->show_mask;
3511 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
g->show_highlight_mask),
FALSE);
3533 float shoulder = 0.0f;
3550 &
p->latitude, &
p->balance);
3564 g->gui_show_labels =
dt_conf_get_int(
"plugins/darkroom/filmicrgb/graph_show_labels");
3566 g->gui_sizes_inited =
FALSE;
3570 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
g->auto_hardness),
p->auto_hardness);
3571 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
g->custom_grey),
p->custom_grey);
3582 d->white_point_source =
module->so->get_f("white_point_source")->Float.Default;
3583 d->output_power =
module->so->get_f("output_power")->Float.Default;
3594 d->white_point_source = exposure + 2.45f;
3595 d->black_point_source =
d->white_point_source - 12.f;
3596 d->output_power = logf(
d->grey_point_target / 100.0f)
3597 / logf(-
d->black_point_source / (
d->white_point_source -
d->black_point_source));
3599 module->workflow_enabled = TRUE;
3606 const int program = 22;
3621 const int wavelets = 35;
3658 double destination_y, gboolean show_head)
3660 cairo_move_to(cr, origin_x, origin_y);
3661 cairo_line_to(cr, destination_x, destination_y);
3667 const float angle_arrow = 45.f / 360.f *
M_PI;
3668 const float angle_trunk = atan2f((destination_y - origin_y), (destination_x - origin_x));
3671 const float x_1 = destination_x + radius / sinf(angle_arrow + angle_trunk);
3672 const float y_1 = destination_y + radius / cosf(angle_arrow + angle_trunk);
3674 const float x_2 = destination_x - radius / sinf(-angle_arrow + angle_trunk);
3675 const float y_2 = destination_y - radius / cosf(-angle_arrow + angle_trunk);
3677 cairo_move_to(cr, x_1, y_1);
3678 cairo_line_to(cr, destination_x, destination_y);
3679 cairo_line_to(cr, x_2, y_2);
3687 if(!
g->gui_sizes_inited)
return;
3702 cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha);
3707 cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha * 0.5);
3717 const float scale = 0.85;
3718 cairo_scale(cr, scale, scale);
3719 button->
icon(cr, -scale * button->
w / 2., -scale * button->
h / 2., scale * button->
w, scale * button->
h, 0, NULL);
3732 gtk_widget_get_allocation(widget, &
g->allocation);
3734 cairo_surface_t *cst =
3736 PangoFontDescription *desc =
3738 cairo_t *cr = cairo_create(cst);
3739 PangoLayout *layout = pango_cairo_create_layout(cr);
3741 pango_layout_set_font_description(layout, desc);
3742 pango_cairo_context_set_resolution(pango_layout_get_context(layout),
darktable.
gui->
dpi);
3743 g->context = gtk_widget_get_style_context(widget);
3748 const gint font_size = pango_font_description_get_size(desc);
3749 pango_font_description_set_size(desc, 0.95 * font_size);
3750 pango_layout_set_font_description(layout, desc);
3753 g_strlcpy(text,
"X",
sizeof(text));
3754 pango_layout_set_text(layout, text, -1);
3755 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
3756 g->line_height =
g->ink.height;
3759 g_strlcpy(text,
"-",
sizeof(text));
3760 pango_layout_set_text(layout, text, -1);
3761 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
3762 g->sign_width =
g->ink.width / 2.0;
3765 g_strlcpy(text,
"0",
sizeof(text));
3766 pango_layout_set_text(layout, text, -1);
3767 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
3768 g->zero_width =
g->ink.width;
3774 float margin_bottom;
3775 if(
g->gui_show_labels)
3778 margin_left = 3. *
g->zero_width + 2. *
g->inset;
3779 margin_bottom = 2. *
g->line_height + 4. *
g->inset;
3783 margin_left =
g->inset;
3784 margin_bottom =
g->inset;
3787 const float margin_top = 2. *
g->line_height +
g->inset;
3790 g->graph_width =
g->allocation.width - margin_right - margin_left;
3791 g->graph_height =
g->allocation.height - margin_bottom - margin_top;
3793 gtk_render_background(
g->context, cr, 0, 0,
g->allocation.width,
g->allocation.height);
3799 g->buttons[
i].right =
g->allocation.width;
3803 g->buttons[
i].w =
g->buttons[
i].right -
g->buttons[
i].left;
3804 g->buttons[
i].h =
g->buttons[
i].bottom -
g->buttons[
i].top;
3805 g->buttons[
i].state = GTK_STATE_FLAG_NORMAL;
3808 g->gui_sizes_inited =
TRUE;
3818 const float grey =
p->grey_point_source / 100.f;
3819 const float DR =
p->white_point_source -
p->black_point_source;
3822 cairo_translate(cr, margin_left, margin_top);
3824 cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
3827 pango_font_description_set_size(desc, font_size);
3828 pango_layout_set_font_description(layout, desc);
3830 g_strlcpy(text, _(
"look only"),
sizeof(text));
3832 g_strlcpy(text, _(
"look + mapping (lin)"),
sizeof(text));
3834 g_strlcpy(text, _(
"look + mapping (log)"),
sizeof(text));
3836 g_strlcpy(text, _(
"dynamic range mapping"),
sizeof(text));
3838 pango_layout_set_text(layout, text, -1);
3839 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
3843 cairo_rectangle(cr,
g->allocation.width - margin_left -
g->ink.width -
g->ink.x - 2. *
g->inset,
3844 -
g->line_height -
g->inset - 0.5 *
g->ink.height -
g->ink.y -
g->inset,
3845 g->ink.width + 3. *
g->inset,
g->ink.height + 2. *
g->inset);
3850 cairo_move_to(cr,
g->allocation.width - margin_left -
g->ink.width -
g->ink.x -
g->inset,
3851 -
g->line_height -
g->inset - 0.5 *
g->ink.height -
g->ink.y);
3852 pango_cairo_show_layout(cr, layout);
3856 pango_font_description_set_size(desc, 0.95 * font_size);
3857 pango_layout_set_font_description(layout, desc);
3863 cairo_rectangle(cr, 0, 0,
g->graph_width,
g->graph_height);
3865 cairo_fill_preserve(cr);
3875 cairo_scale(cr, 1., -1.);
3876 cairo_translate(cr, 0., -
g->graph_height);
3887 cairo_move_to(cr, 0,
g->graph_height);
3888 cairo_line_to(cr,
g->graph_width, 0);
3894 const float saturation = (2.0f *
p->saturation / 100.0f + 1.0f);
3895 const float sigma_toe = powf(
g->spline.latitude_min / 3.0f, 2.0f);
3896 const float sigma_shoulder = powf((1.0f -
g->spline.latitude_max) / 3.0f, 2.0f);
3898 cairo_set_source_rgb(cr, .5, .5, .5);
3908 cairo_move_to(cr, 0,
3909 g->graph_height * (1.0 - filmic_desaturate_v1(0.0f, sigma_toe, sigma_shoulder, saturation)));
3910 for(
int k = 1;
k < 256;
k++)
3912 float x =
k / 255.0;
3913 const float y = filmic_desaturate_v1(
x, sigma_toe, sigma_shoulder, saturation);
3920 cairo_line_to(cr,
x *
g->graph_width,
g->graph_height * (1.0 - y));
3925 cairo_move_to(cr, 0,
3926 g->graph_height * (1.0 - filmic_desaturate_v2(0.0f, sigma_toe, sigma_shoulder, saturation)));
3927 for(
int k = 1;
k < 256;
k++)
3929 float x =
k / 255.0;
3930 const float y = filmic_desaturate_v2(
x, sigma_toe, sigma_shoulder, saturation);
3937 cairo_line_to(cr,
x *
g->graph_width,
g->graph_height * (1.0 - y));
3943 float x_start = 0.f;
3949 float y_start =
clamp_simd(filmic_spline(x_start,
g->spline.M1,
g->spline.M2,
g->spline.M3,
g->spline.M4,
3950 g->spline.M5,
g->spline.latitude_min,
g->spline.latitude_max,
g->spline.type));
3953 y_start = powf(y_start,
p->output_power);
3957 cairo_move_to(cr, 0,
g->graph_height * (1.0 - y_start));
3959 for(
int k = 1;
k < 256;
k++)
3963 float x = powf(
k / 255.0f, 2.4f);
3971 float y = filmic_spline(
value,
g->spline.M1,
g->spline.M2,
g->spline.M3,
g->spline.M4,
g->spline.M5,
3972 g->spline.latitude_min,
g->spline.latitude_max,
g->spline.type);
3980 const float margin = 1
E-5;
3981 if(y >
g->spline.y[4] + margin)
3984 cairo_set_source_rgb(cr, 0.75, .5, 0.);
3986 else if(y < g->spline.
y[0] - margin)
3989 cairo_set_source_rgb(cr, 0.75, .5, 0.);
3997 y = powf(y,
p->output_power);
4001 cairo_line_to(cr,
x *
g->graph_width,
g->graph_height * (1.0 - y));
4003 cairo_move_to(cr,
x *
g->graph_width,
g->graph_height * (1.0 - y));
4015 float x_grey =
g->spline.x[2];
4016 float y_grey =
g->spline.y[2];
4021 y_grey = powf(y_grey,
p->output_power);
4029 cairo_set_source_rgb(cr, 0.75, 0.5, 0.0);
4030 cairo_arc(cr, x_grey *
g->graph_width, (1.0 - y_grey) *
g->graph_height,
DT_PIXEL_APPLY_DPI(6), 0,
4036 float x_black = 0.f;
4037 float y_black = 0.f;
4039 float x_white = 1.f;
4040 float y_white = 1.f;
4042 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);
4043 const float central_slope_angle = atanf(central_slope) +
M_PI / 2.0f;
4045 for(
int k = 0;
k < 5;
k++)
4049 float x =
g->spline.x[
k];
4050 float y =
g->spline.y[
k];
4051 const float ymin =
g->spline.y[0];
4052 const float ymax =
g->spline.y[4];
4054 const float y_margin =
SAFETY_MARGIN * 1.1f * (ymax - ymin);
4055 gboolean red = (((
k == 1) && (y - ymin <= y_margin))
4056 || ((
k == 3) && (ymax - y <= y_margin)));
4057 float start_angle = 0.0f;
4058 float end_angle = 2.f *
M_PI;
4061 if(contrast_clamped)
4065 start_angle = central_slope_angle +
M_PI;
4066 end_angle = central_slope_angle;
4070 start_angle = central_slope_angle;
4071 end_angle = start_angle +
M_PI;
4078 y = powf(y,
p->output_power);
4098 if(red) cairo_set_source_rgb(cr, 0.8, 0.35, 0.35);
4101 cairo_arc(cr,
x *
g->graph_width, (1.0 - y) *
g->graph_height,
DT_PIXEL_APPLY_DPI(4), start_angle, end_angle);
4111 if(
g->gui_show_labels)
4114 const float x_legend_top =
g->graph_height + 0.5 *
g->line_height;
4118 snprintf(text,
sizeof(text),
"%.0f",
p->grey_point_target);
4119 pango_layout_set_text(layout, text, -1);
4120 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4121 cairo_move_to(cr, -2. *
g->inset -
g->ink.width -
g->ink.x,
4122 (1.0 - y_grey) *
g->graph_height - 0.5 *
g->ink.height -
g->ink.y);
4123 pango_cairo_show_layout(cr, layout);
4129 snprintf(text,
sizeof(text),
"%+.1f", 0.f);
4131 snprintf(text,
sizeof(text),
"%.0f",
p->grey_point_source);
4133 pango_layout_set_text(layout, text, -1);
4134 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4135 cairo_move_to(cr, x_grey *
g->graph_width - 0.5 *
g->ink.width -
g->ink.x, x_legend_top);
4136 pango_cairo_show_layout(cr, layout);
4141 snprintf(text,
sizeof(text),
"%.0f",
p->black_point_target);
4142 pango_layout_set_text(layout, text, -1);
4143 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4144 cairo_move_to(cr, -2. *
g->inset -
g->ink.width -
g->ink.x,
4145 (1.0 - y_black) *
g->graph_height - 0.5 *
g->ink.height -
g->ink.y);
4146 pango_cairo_show_layout(cr, layout);
4151 snprintf(text,
sizeof(text),
"%.0f",
p->white_point_target);
4152 pango_layout_set_text(layout, text, -1);
4153 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4154 cairo_move_to(cr, -2. *
g->inset -
g->ink.width -
g->ink.x,
4155 (1.0 - y_white) *
g->graph_height - 0.5 *
g->ink.height -
g->ink.y);
4156 pango_cairo_show_layout(cr, layout);
4162 snprintf(text,
sizeof(text),
"%+.1f",
p->black_point_source);
4164 snprintf(text,
sizeof(text),
"%.0f", exp2f(
p->black_point_source) *
p->grey_point_source);
4166 pango_layout_set_text(layout, text, -1);
4167 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4168 cairo_move_to(cr, x_black *
g->graph_width - 0.5 *
g->ink.width -
g->ink.x, x_legend_top);
4169 pango_cairo_show_layout(cr, layout);
4175 snprintf(text,
sizeof(text),
"%+.1f",
p->white_point_source);
4179 snprintf(text,
sizeof(text),
"%.0f \342\206\222", 100.f);
4181 snprintf(text,
sizeof(text),
"%.0f", exp2f(
p->white_point_source) *
p->grey_point_source);
4184 pango_layout_set_text(layout, text, -1);
4185 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4187 fminf(x_white, 1.f) *
g->graph_width - 0.5 *
g->ink.width -
g->ink.x
4188 + 2. * (x_white > 1.f) *
g->sign_width,
4190 pango_cairo_show_layout(cr, layout);
4199 PangoStyle backup = pango_font_description_get_style(desc);
4200 pango_font_description_set_style(desc, PANGO_STYLE_ITALIC);
4201 pango_layout_set_font_description(layout, desc);
4203 snprintf(text,
sizeof(text), _(
"(%.0f %%)"), exp2f(
p->white_point_source) *
p->grey_point_source);
4204 pango_layout_set_text(layout, text, -1);
4205 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4206 cairo_move_to(cr,
g->allocation.width -
g->ink.width -
g->ink.x - margin_left,
4207 g->graph_height + 3. *
g->inset +
g->line_height -
g->ink.y);
4208 pango_cairo_show_layout(cr, layout);
4212 pango_font_description_set_style(desc, backup);
4213 pango_layout_set_font_description(layout, desc);
4219 g_strlcpy(text, _(
"% display"),
sizeof(text));
4220 pango_layout_set_text(layout, text, -1);
4221 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4222 cairo_move_to(cr, -2. *
g->inset -
g->zero_width -
g->ink.x,
4223 -
g->line_height -
g->inset - 0.5 *
g->ink.height -
g->ink.y);
4224 pango_cairo_show_layout(cr, layout);
4231 g_strlcpy(text, _(
"EV scene"),
sizeof(text));
4235 g_strlcpy(text, _(
"% camera"),
sizeof(text));
4237 pango_layout_set_text(layout, text, -1);
4238 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4239 cairo_move_to(cr, 0.5 *
g->graph_width - 0.5 *
g->ink.width -
g->ink.x,
4240 g->graph_height + 3. *
g->inset +
g->line_height -
g->ink.y);
4241 pango_cairo_show_layout(cr, layout);
4248 cairo_identity_matrix(cr);
4254 const float display_DR = 12.f + log2f(
p->white_point_target / 100.f);
4256 const float y_display =
g->allocation.height / 3.f +
g->line_height;
4257 const float y_scene = 2. *
g->allocation.height / 3.f +
g->line_height;
4259 const float display_top = y_display -
g->line_height / 2;
4260 const float display_bottom = display_top +
g->line_height;
4262 const float scene_top = y_scene -
g->line_height / 2;
4263 const float scene_bottom = scene_top +
g->line_height;
4267 if(
g->gui_show_labels)
4271 g_strlcpy(text, _(
"display"),
sizeof(text));
4272 pango_layout_set_text(layout, text, -1);
4273 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4274 cairo_move_to(cr, 0., y_display - 0.5 *
g->ink.height -
g->ink.y);
4275 pango_cairo_show_layout(cr, layout);
4277 const float display_label_width =
g->ink.width;
4280 g_strlcpy(text, _(
"(%)"),
sizeof(text));
4281 pango_layout_set_text(layout, text, -1);
4282 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4283 cairo_move_to(cr, 0.5 * display_label_width - 0.5 *
g->ink.width -
g->ink.x,
4284 display_top - 4. *
g->inset -
g->ink.height -
g->ink.y);
4285 pango_cairo_show_layout(cr, layout);
4289 g_strlcpy(text, _(
"scene"),
sizeof(text));
4290 pango_layout_set_text(layout, text, -1);
4291 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4292 cairo_move_to(cr, 0., y_scene - 0.5 *
g->ink.height -
g->ink.y);
4293 pango_cairo_show_layout(cr, layout);
4295 const float scene_label_width =
g->ink.width;
4298 g_strlcpy(text, _(
"(EV)"),
sizeof(text));
4299 pango_layout_set_text(layout, text, -1);
4300 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4301 cairo_move_to(cr, 0.5 * scene_label_width - 0.5 *
g->ink.width -
g->ink.x,
4302 scene_bottom + 2. *
g->inset + 0. *
g->ink.height +
g->ink.y);
4303 pango_cairo_show_layout(cr, layout);
4308 dt_cairo_draw_arrow(cr, fminf(scene_label_width, display_label_width) / 2.f, y_scene -
g->line_height,
4309 fminf(scene_label_width, display_label_width) / 2.f,
4310 y_display +
g->line_height +
g->inset,
TRUE);
4312 column_left = fmaxf(display_label_width, scene_label_width) +
g->inset;
4320 const float display_HL_EV = -log2f(
p->grey_point_target /
p->white_point_target);
4321 const float display_LL_EV = display_DR - display_HL_EV;
4322 const float display_real_black_EV
4323 = -fmaxf(log2f(
p->black_point_target /
p->grey_point_target),
4324 -11.685887601778058f + display_HL_EV - log2f(
p->white_point_target / 100.f));
4325 const float scene_HL_EV =
p->white_point_source;
4326 const float scene_LL_EV = -
p->black_point_source;
4329 const float max_DR = ceilf(fmaxf(display_HL_EV, scene_HL_EV)) + ceilf(fmaxf(display_LL_EV, scene_LL_EV));
4330 const float EV = (column_right) / max_DR;
4334 const float grey_EV = fmaxf(ceilf(display_HL_EV), ceilf(scene_HL_EV));
4338 const float display_black_x = grey_x - display_real_black_EV * EV;
4339 const float display_DR_start_x = grey_x - display_LL_EV * EV;
4340 const float display_white_x = grey_x + display_HL_EV * EV;
4342 const float scene_black_x = grey_x - scene_LL_EV * EV;
4343 const float scene_white_x = grey_x + scene_HL_EV * EV;
4344 const float scene_lat_bottom = grey_x + (
g->spline.x[1] -
g->spline.x[2]) * EV * DR;
4345 const float scene_lat_top = grey_x + (
g->spline.x[3] -
g->spline.x[2]) * EV * DR;
4353 float display_lat_bottom = filmic_spline(
g->spline.latitude_min,
g->spline.M1,
g->spline.M2,
g->spline.M3,
g->spline.M4,
4354 g->spline.M5,
g->spline.latitude_min,
g->spline.latitude_max,
g->spline.type);
4355 display_lat_bottom = powf(fmaxf(display_lat_bottom,
NORM_MIN),
p->output_power);
4358 display_lat_bottom = log2f(display_lat_bottom/ (
p->grey_point_target / 100.f));
4361 if(display_lat_bottom < 0.f)
4362 display_lat_bottom = fmaxf(display_lat_bottom, -display_real_black_EV);
4363 else if(display_lat_bottom > 0.f)
4364 display_lat_bottom = fminf(display_lat_bottom, display_HL_EV);
4367 display_lat_bottom = grey_x + display_lat_bottom * EV;
4370 float display_lat_top = filmic_spline(
g->spline.latitude_max,
g->spline.M1,
g->spline.M2,
g->spline.M3,
g->spline.M4,
4371 g->spline.M5,
g->spline.latitude_min,
g->spline.latitude_max,
g->spline.type);
4372 display_lat_top = powf(fmaxf(display_lat_top,
NORM_MIN),
p->output_power);
4375 display_lat_top = log2f(display_lat_top / (
p->grey_point_target / 100.f));
4378 if(display_lat_top < 0.f)
4379 display_lat_top = fmaxf(display_lat_top, -display_real_black_EV);
4380 else if(display_lat_top > 0.f)
4381 display_lat_top = fminf(display_lat_top, display_HL_EV);
4384 display_lat_top = grey_x + display_lat_top * EV;
4386 cairo_move_to(cr, scene_lat_bottom, scene_top);
4387 cairo_line_to(cr, scene_lat_top, scene_top);
4388 cairo_line_to(cr, display_lat_top, display_bottom);
4389 cairo_line_to(cr, display_lat_bottom, display_bottom);
4390 cairo_line_to(cr, scene_lat_bottom, scene_top);
4394 for(
int i = 0;
i < (int)ceilf(display_DR);
i++)
4397 const float shade = powf(exp2f(-11.f + (
float)
i), 1.f / 2.4f);
4398 cairo_set_source_rgb(cr, shade, shade, shade);
4399 cairo_rectangle(cr, display_DR_start_x +
i * EV, display_top, EV,
g->line_height);
4400 cairo_fill_preserve(cr);
4403 cairo_set_source_rgb(cr, 0.75, .5, 0.);
4409 cairo_move_to(cr, grey_x, display_bottom + 2. *
g->inset);
4410 cairo_line_to(cr, grey_x, display_top - 2. *
g->inset);
4415 for(
int i = floorf(
p->black_point_source);
i < ceilf(
p->white_point_source);
i++)
4419 const float shade = powf(0.1845f * exp2f((
float)
i), 1.f / 2.4f);
4420 const float x_temp = grey_x +
i * EV;
4421 cairo_set_source_rgb(cr, shade, shade, shade);
4422 cairo_rectangle(cr, x_temp, scene_top, EV,
g->line_height);
4423 cairo_fill_preserve(cr);
4426 cairo_set_source_rgb(cr, 0.75, .5, 0.);
4435 if((
float)
i >
p->black_point_source && (
float)i < p->white_point_source)
4438 const float normal_value = ((float)
i -
p->black_point_source) / DR;
4439 float y_temp = filmic_spline(normal_value,
g->spline.M1,
g->spline.M2,
g->spline.M3,
g->spline.M4,
4440 g->spline.M5,
g->spline.latitude_min,
g->spline.latitude_max,
g->spline.type);
4441 y_temp = powf(fmaxf(y_temp,
NORM_MIN),
p->output_power);
4444 y_temp = log2f(y_temp / (
p->grey_point_target / 100.f));
4448 y_temp = fmaxf(y_temp, -display_real_black_EV);
4449 else if(y_temp > 0.f)
4450 y_temp = fminf(y_temp, display_HL_EV);
4453 y_temp = grey_x + y_temp * EV;
4461 float x_temp = grey_x +
p->black_point_source * EV;
4462 float y_temp = grey_x - display_real_black_EV * EV;
4465 x_temp = grey_x +
p->white_point_source * EV;
4466 y_temp = grey_x + display_HL_EV * EV;
4472 cairo_move_to(cr, display_black_x, display_bottom);
4473 cairo_line_to(cr, display_black_x, display_top - 2. *
g->inset);
4477 cairo_move_to(cr, grey_x, display_bottom);
4478 cairo_line_to(cr, grey_x, display_top - 2. *
g->inset);
4482 cairo_move_to(cr, display_white_x, display_bottom);
4483 cairo_line_to(cr, display_white_x, display_top - 2. *
g->inset);
4487 cairo_move_to(cr, scene_black_x, scene_bottom + 2. *
g->inset);
4488 cairo_line_to(cr, scene_black_x, scene_top);
4492 cairo_move_to(cr, grey_x, scene_bottom + 2. *
g->inset);
4493 cairo_line_to(cr, grey_x, scene_top);
4497 cairo_move_to(cr, scene_white_x, scene_bottom + 2. *
g->inset);
4498 cairo_line_to(cr, scene_white_x, scene_top);
4505 snprintf(text,
sizeof(text),
"%+.1f",
p->black_point_source);
4506 pango_layout_set_text(layout, text, -1);
4507 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4508 cairo_move_to(cr, scene_black_x - 0.5 *
g->ink.width -
g->ink.x,
4509 scene_bottom + 2. *
g->inset + 0. *
g->ink.height +
g->ink.y);
4510 pango_cairo_show_layout(cr, layout);
4514 snprintf(text,
sizeof(text),
"%+.1f", 0.f);
4515 pango_layout_set_text(layout, text, -1);
4516 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4517 cairo_move_to(cr, grey_x - 0.5 *
g->ink.width -
g->ink.x,
4518 scene_bottom + 2. *
g->inset + 0. *
g->ink.height +
g->ink.y);
4519 pango_cairo_show_layout(cr, layout);
4523 snprintf(text,
sizeof(text),
"%+.1f",
p->white_point_source);
4524 pango_layout_set_text(layout, text, -1);
4525 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4526 cairo_move_to(cr, scene_white_x - 0.5 *
g->ink.width -
g->ink.x,
4527 scene_bottom + 2. *
g->inset + 0. *
g->ink.height +
g->ink.y);
4528 pango_cairo_show_layout(cr, layout);
4532 snprintf(text,
sizeof(text),
"%.0f",
p->black_point_target);
4533 pango_layout_set_text(layout, text, -1);
4534 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4535 cairo_move_to(cr, display_black_x - 0.5 *
g->ink.width -
g->ink.x,
4536 display_top - 4. *
g->inset -
g->ink.height -
g->ink.y);
4537 pango_cairo_show_layout(cr, layout);
4541 snprintf(text,
sizeof(text),
"%.0f",
p->grey_point_target);
4542 pango_layout_set_text(layout, text, -1);
4543 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4544 cairo_move_to(cr, grey_x - 0.5 *
g->ink.width -
g->ink.x,
4545 display_top - 4. *
g->inset -
g->ink.height -
g->ink.y);
4546 pango_cairo_show_layout(cr, layout);
4550 snprintf(text,
sizeof(text),
"%.0f",
p->white_point_target);
4551 pango_layout_set_text(layout, text, -1);
4552 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4553 cairo_move_to(cr, display_white_x - 0.5 *
g->ink.width -
g->ink.x,
4554 display_top - 4. *
g->inset -
g->ink.height -
g->ink.y);
4555 pango_cairo_show_layout(cr, layout);
4560 pango_font_description_set_size(desc, font_size);
4561 pango_layout_set_font_description(layout, desc);
4564 cairo_set_source_surface(crf, cst, 0, 0);
4566 cairo_surface_destroy(cst);
4567 g_object_unref(layout);
4568 pango_font_description_free(desc);
4584 if(event->button == 1 && event->type == GDK_2BUTTON_PRESS)
4590 gtk_widget_queue_draw(GTK_WIDGET(
g->area));
4599 else if(event->button == 1)
4610 gtk_widget_queue_draw(GTK_WIDGET(
g->area));
4616 g->gui_show_labels = !
g->gui_show_labels;
4617 gtk_widget_queue_draw(GTK_WIDGET(
g->area));
4618 dt_conf_set_int(
"plugins/darkroom/filmicrgb/graph_show_labels",
g->gui_show_labels);
4628 else if(event->button == 3)
4638 gtk_widget_queue_draw(GTK_WIDGET(
g->area));
4644 g->gui_show_labels = !
g->gui_show_labels;
4645 gtk_widget_queue_draw(GTK_WIDGET(
g->area));
4646 dt_conf_set_int(
"plugins/darkroom/filmicrgb/graph_show_labels",
g->gui_show_labels);
4666 g->gui_hover =
TRUE;
4667 gtk_widget_queue_draw(GTK_WIDGET(
g->area));
4680 gtk_widget_queue_draw(GTK_WIDGET(
g->area));
4690 if(!
g->gui_sizes_inited)
return FALSE;
4693 const float y =
event->y;
4694 const float x =
event->x;
4696 if(
x > 0. && x < g->allocation.width && y > 0. && y < g->allocation.height)
g->gui_hover =
TRUE;
4698 gint save_active_button =
g->active_button;
4703 gint found_something =
FALSE;
4707 if(
x >
g->buttons[
i].left && x < g->buttons[
i].right && y >
g->buttons[
i].top && y < g->buttons[
i].bottom)
4710 g->buttons[
i].mouse_hover =
TRUE;
4711 g->active_button =
i;
4712 found_something =
TRUE;
4717 g->buttons[
i].mouse_hover =
FALSE;
4727 gtk_widget_set_tooltip_text(GTK_WIDGET(
g->area), _(
"use the parameters below to set the nodes.\n"
4728 "the bright curve is the filmic tone mapping curve\n"
4729 "the dark curve is the desaturation curve."));
4733 gtk_widget_set_tooltip_text(GTK_WIDGET(
g->area), _(
"toggle axis labels and values display"));
4737 gtk_widget_set_tooltip_text(GTK_WIDGET(
g->area), _(
"cycle through graph views.\n"
4738 "left click: cycle forward.\n"
4739 "right click: cycle backward.\n"
4740 "double-click: reset to look view."));
4744 gtk_widget_set_tooltip_text(GTK_WIDGET(
g->area),
"");
4747 if(save_active_button !=
g->active_button) gtk_widget_queue_draw(GTK_WIDGET(
g->area));
4753 if(save_active_button !=
g->active_button) (GTK_WIDGET(
g->area));
4766 const int aspect =
dt_conf_get_int(
"plugins/darkroom/filmicrgb/aspect_percent");
4767 dt_conf_set_int(
"plugins/darkroom/filmicrgb/aspect_percent", aspect + delta_y);
4781 g->gui_show_labels =
TRUE;
4783 g->gui_sizes_inited =
FALSE;
4786 const float aspect =
dt_conf_get_int(
"plugins/darkroom/filmicrgb/aspect_percent") / 100.0;
4788 g_object_set_data(G_OBJECT(
g->area),
"iop-instance", self);
4790 gtk_widget_set_can_focus(GTK_WIDGET(
g->area),
TRUE);
4791 gtk_widget_add_events(GTK_WIDGET(
g->area), GDK_BUTTON_PRESS_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK
4794 g_signal_connect(G_OBJECT(
g->area),
"button-press-event", G_CALLBACK(
area_button_press), self);
4795 g_signal_connect(G_OBJECT(
g->area),
"leave-notify-event", G_CALLBACK(
area_leave_notify), self);
4796 g_signal_connect(G_OBJECT(
g->area),
"enter-notify-event", G_CALLBACK(
area_enter_notify), self);
4797 g_signal_connect(G_OBJECT(
g->area),
"motion-notify-event", G_CALLBACK(
area_motion_notify), self);
4806 g->grey_point_source
4810 gtk_widget_set_tooltip_text(
g->grey_point_source,
4811 _(
"adjust to match the average luminance of the image's subject.\n"
4812 "the value entered here will then be remapped to 18.45%.\n"
4813 "decrease the value to increase the overall brightness."));
4816 g->white_point_source
4820 gtk_widget_set_tooltip_text(
g->white_point_source,
4821 _(
"number of stops between middle gray and pure white.\n"
4822 "this is a reading a lightmeter would give you on the scene.\n"
4823 "adjust so highlights clipping is avoided"));
4826 g->black_point_source
4830 gtk_widget_set_tooltip_text(
4831 g->black_point_source, _(
"number of stops between middle gray and pure black.\n"
4832 "this is a reading a lightmeter would give you on the scene.\n"
4833 "increase to get more contrast.\ndecrease to recover more details in low-lights."));
4839 gtk_widget_set_tooltip_text(
g->security_factor, _(
"symmetrically enlarge or shrink the computed dynamic range.\n"
4840 "useful to give a safety margin to extreme luminances."));
4843 GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
4846 gtk_box_pack_start(GTK_BOX(hbox),
g->auto_button,
FALSE,
FALSE, 0);
4848 gtk_widget_set_tooltip_text(
g->auto_button, _(
"try to optimize the settings with some statistical assumptions.\n"
4849 "this will fit the luminance range inside the histogram bounds.\n"
4850 "works better for landscapes and evenly-lit pictures\n"
4851 "but fails for high-keys, low-keys and high-ISO pictures.\n"
4852 "this is not an artificial intelligence, but a simple guess.\n"
4853 "ensure you understand its assumptions before using it."));
4860 gtk_widget_set_tooltip_text(
g->custom_grey, _(
"enable to input custom middle-gray values.\n"
4861 "this is not recommended in general.\n"
4862 "fix the global exposure in the exposure module instead.\n"
4863 "disable to use standard 18.45 %% middle gray."));
4873 gtk_widget_set_tooltip_text(
g->reconstruct_threshold,
4874 _(
"set the exposure threshold upon which\n"
4875 "clipped highlights get reconstructed.\n"
4876 "values are relative to the scene white point.\n"
4877 "0 EV means the threshold is the same as the scene white point.\n"
4878 "decrease to include more areas,\n"
4879 "increase to exclude more areas."));
4883 gtk_widget_set_tooltip_text(
g->reconstruct_feather,
4884 _(
"soften the transition between clipped highlights and valid pixels.\n"
4885 "decrease to make the transition harder and sharper,\n"
4886 "increase to make the transition softer and blurrier."));
4889 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
4890 gtk_box_pack_start(GTK_BOX(hbox),
dt_ui_label_new(_(
"display highlight reconstruction mask")),
TRUE,
TRUE, 0);
4903 gtk_widget_set_tooltip_text(
g->reconstruct_structure_vs_texture,
4905 _(
"decide which reconstruction strategy to favor,\n"
4906 "between inpainting a smooth color gradient,\n"
4907 "or trying to recover the textured details.\n"
4908 "0% is an equal mix of both.\n"
4909 "increase if at least one RGB channel is not clipped.\n"
4910 "decrease if all RGB channels are clipped over large areas."));
4914 gtk_widget_set_tooltip_text(
g->reconstruct_bloom_vs_details,
4916 _(
"decide which reconstruction strategy to favor,\n"
4917 "between blooming highlights like film does,\n"
4918 "or trying to recover sharp details.\n"
4919 "0% is an equal mix of both.\n"
4920 "increase if you want more details.\n"
4921 "decrease if you want more blur."));
4926 gtk_widget_set_tooltip_text(
g->reconstruct_grey_vs_color,
4928 _(
"decide which reconstruction strategy to favor,\n"
4929 "between recovering monochromatic highlights,\n"
4930 "or trying to recover colorful highlights.\n"
4931 "0% is an equal mix of both.\n"
4932 "increase if you want more color.\n"
4933 "decrease if you see magenta or out-of-gamut highlights."));
4940 gtk_widget_set_tooltip_text(
g->high_quality_reconstruction,
4941 _(
"run extra passes of chromaticity reconstruction.\n"
4942 "more iterations means more color propagation from neighbourhood.\n"
4943 "this will be slower but will yield more neutral highlights.\n"
4944 "it also helps with difficult cases of magenta highlights."));
4948 gtk_widget_set_tooltip_text(
g->noise_level, _(
"add statistical noise in reconstructed highlights.\n"
4949 "this avoids highlights to look too smooth\n"
4950 "when the picture is noisy overall,\n"
4951 "so they blend with the rest of the picture."));
4955 gtk_widget_set_tooltip_text(
g->noise_distribution, _(
"choose the statistical distribution of noise.\n"
4956 "this is useful to match natural sensor noise pattern.\n"));
4967 gtk_widget_set_tooltip_text(
g->contrast, _(
"slope of the linear part of the curve\n"
4968 "affects mostly the mid-tones"));
4972 gtk_widget_set_tooltip_text(
g->output_power, _(
"equivalent to paper grade in analog.\n"
4973 "increase to make highlights brighter and less compressed.\n"
4974 "decrease to mute highlights."));
4981 gtk_widget_set_tooltip_text(
g->toe,
4982 _(
"distance between middle gray and the start of the shadows roll-off.\n"
4983 "0% keeps the toe at middle gray, 100% pushes it to the point where the\n"
4984 "current slope would hit the output black level."));
4992 gtk_widget_set_tooltip_text(
g->shoulder,
4993 _(
"distance between middle gray and the start of the highlights roll-off.\n"
4994 "0% keeps the shoulder at middle gray, 100% pushes it to the point where the\n"
4995 "current slope would hit the output white level."));
5000 gtk_widget_set_tooltip_text(
g->highlights, _(
"choose the desired curvature of the filmic spline in highlights.\n"
5001 "hard uses a high curvature resulting in more tonal compression.\n"
5002 "soft uses a low curvature resulting in less tonal compression."));
5005 gtk_widget_set_tooltip_text(
g->shadows, _(
"choose the desired curvature of the filmic spline in shadows.\n"
5006 "hard uses a high curvature resulting in more tonal compression.\n"
5007 "soft uses a low curvature resulting in less tonal compression."));
5015 gtk_widget_set_tooltip_text(
g->saturation, _(
"desaturates the output of the module\n"
5016 "specifically at extreme luminances.\n"
5017 "increase if shadows and/or highlights are under-saturated."));
5020 gtk_widget_set_tooltip_text(
g->preserve_color, _(
"ensure the original color are preserved.\n"
5021 "may reinforce chromatic aberrations and chroma noise,\n"
5022 "so ensure they are properly corrected elsewhere.\n"));
5029 gtk_widget_set_tooltip_text(
g->version,
5030 _(
"v3 is darktable 3.0 desaturation method, same as color balance.\n"
5031 "v4 is a newer desaturation method, based on spectral purity of light."));
5035 gtk_widget_set_tooltip_text(
5036 g->auto_hardness, _(
"enable to auto-set the look hardness depending on the scene white and black points.\n"
5037 "this keeps the middle gray on the identity line and improves fast tuning.\n"
5038 "disable if you want a manual control."));
5047 gtk_widget_set_tooltip_text(
g->black_point_target, _(
"luminance of output pure black, "
5048 "this should be 0%\nexcept if you want a faded look"));
5053 gtk_widget_set_tooltip_text(
g->grey_point_target,
5054 _(
"middle gray value of the target display or color space.\n"
5055 "you should never touch that unless you know what you are doing."));
5061 gtk_widget_set_tooltip_text(
g->white_point_target, _(
"luminance of output pure white, "
5062 "this should be 100%\nexcept if you want a faded look"));
5067 gtk_box_pack_start(GTK_BOX(self->
widget), GTK_WIDGET(
g->area),
TRUE,
TRUE, 0);
5068 gtk_box_pack_start(GTK_BOX(self->
widget), GTK_WIDGET(
g->notebook),
FALSE,
FALSE, 0);
5076 if(
IS_NULL_PTR(w) || w ==
g->auto_hardness || w ==
g->security_factor || w ==
g->grey_point_source
5077 || w ==
g->black_point_source || w ==
g->white_point_source)
5081 if(w ==
g->security_factor || w ==
g->grey_point_source)
5083 float prev = *(
float *)previous;
5084 if(w ==
g->security_factor)
5086 float ratio = (
p->security_factor - prev) / (prev + 100.0f);
5088 float EVmin =
p->black_point_source;
5089 EVmin = EVmin + ratio * EVmin;
5091 float EVmax =
p->white_point_source;
5092 EVmax = EVmax + ratio * EVmax;
5094 p->white_point_source = EVmax;
5095 p->black_point_source = EVmin;
5099 float grey_var = log2f(prev /
p->grey_point_source);
5100 p->black_point_source =
p->black_point_source - grey_var;
5101 p->white_point_source =
p->white_point_source + grey_var;
5108 if(
p->auto_hardness)
5109 p->output_power = logf(
p->grey_point_target / 100.0f)
5110 / logf(-
p->black_point_source / (
p->white_point_source -
p->black_point_source));
5112 gtk_widget_set_visible(GTK_WIDGET(
g->output_power), !
p->auto_hardness);
5123 gtk_widget_set_tooltip_text(
g->saturation, _(
"desaturates the output of the module\n"
5124 "specifically at extreme luminances.\n"
5125 "increase if shadows and/or highlights are under-saturated."));
5130 gtk_widget_set_tooltip_text(
g->saturation, _(
"desaturates the output of the module\n"
5131 "specifically at medium luminances.\n"
5132 "increase if midtones are under-saturated."));
5137 gtk_widget_set_tooltip_text(
g->saturation, _(
"Positive values ensure saturation is kept unchanged over the whole range.\n"
5138 "Negative values bleache highlights at constant hue and luminance.\n"
5139 "Zero is an equal mix of both strategies."));
5140 gtk_widget_set_visible(GTK_WIDGET(
g->preserve_color),
FALSE);
5144 gtk_widget_set_visible(GTK_WIDGET(
g->preserve_color),
TRUE);
5148 if(
IS_NULL_PTR(w) || w ==
g->reconstruct_bloom_vs_details)
5150 if(
p->reconstruct_bloom_vs_details == -100.f)
5155 gtk_widget_set_sensitive(
g->reconstruct_structure_vs_texture,
FALSE);
5159 gtk_widget_set_sensitive(
g->reconstruct_structure_vs_texture,
TRUE);
5165 gtk_widget_set_visible(
g->grey_point_source,
p->custom_grey);
5166 gtk_widget_set_visible(
g->grey_point_target,
p->custom_grey);
5170 gtk_widget_queue_draw(GTK_WIDGET(
g->area));
static void error(char *msg)
Definition ashift_lsd.c:202
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
void dt_bauhaus_slider_set_soft_range(GtkWidget *widget, float soft_min, float soft_max)
Definition bauhaus.c:1297
void dt_bauhaus_slider_set_digits(GtkWidget *widget, int val)
Definition bauhaus.c:2910
float dt_bauhaus_slider_get(GtkWidget *widget)
Definition bauhaus.c:2859
void dt_bauhaus_slider_set_soft_max(GtkWidget *widget, float val)
Definition bauhaus.c:1274
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
Definition bauhaus.c:2882
void dt_bauhaus_widget_set_label(GtkWidget *widget, const char *label)
Definition bauhaus.c:1303
GtkWidget * dt_bauhaus_slider_new_with_range(dt_bauhaus_t *bh, dt_gui_module_t *self, float min, float max, float step, float defval, int digits)
Definition bauhaus.c:1429
void dt_bauhaus_slider_set_format(GtkWidget *widget, const char *format)
Definition bauhaus.c:2974
#define DT_BAUHAUS_SPACE
Definition bauhaus.h:282
static void set_color(cairo_t *cr, GdkRGBA color)
Definition bauhaus.h:402
#define INNER_PADDING
Definition bauhaus.h:76
int width
Definition bilateral.h:1
int height
Definition bilateral.h:1
static __DT_CLONE_TARGETS__ void normalize(float *const buffer, const size_t width, const size_t height, const float norm)
Definition blurs.c:347
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:325
#define BSPLINE_FSIZE
Definition bspline.h:30
const dt_colormatrix_t XYZ_D65_to_D50_CAT16
Definition chromatic_adaptation.h:258
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
Definition chromatic_adaptation.h:309
return vector dt_simd_set1(valid ?(scaling+NORM_MIN) :NORM_MIN)
static float dt_camera_rgb_luminance(const float4 rgb)
Definition color_conversion.h:166
@ IOP_CS_RGB
Definition color_conversion.h:34
void dt_iop_color_picker_reset(dt_iop_module_t *module, gboolean keep)
Definition color_picker_proxy.c:494
GtkWidget * dt_color_picker_new(dt_iop_module_t *module, dt_iop_color_picker_kind_t kind, GtkWidget *w)
Definition color_picker_proxy.c:806
@ DT_COLOR_PICKER_AREA
Definition color_picker_proxy.h:45
dt_aligned_pixel_t LMS
Definition colorspaces_inline_conversions.h:701
const float i
Definition colorspaces_inline_conversions.h:440
static dt_aligned_pixel_t rgb
Definition colorspaces_inline_conversions.h:344
const float g
Definition colorspaces_inline_conversions.h:674
const float threshold
Definition colorspaces_inline_conversions.h:176
const float d
Definition colorspaces_inline_conversions.h:680
static const float const float const float min
Definition colorspaces_inline_conversions.h:438
static dt_aligned_pixel_t XYZ
Definition colorspaces_inline_conversions.h:98
const float max
Definition colorspaces_inline_conversions.h:490
const dt_colormatrix_t dt_aligned_pixel_t out
Definition colorspaces_inline_conversions.h:42
const float n
Definition colorspaces_inline_conversions.h:678
dt_store_simd_aligned(out, dt_mat3x4_mul_vec4(vin, dt_colormatrix_row_to_simd(matrix, 0), dt_colormatrix_row_to_simd(matrix, 1), dt_colormatrix_row_to_simd(matrix, 2)))
static const int row
Definition colorspaces_inline_conversions.h:35
const float delta
Definition colorspaces_inline_conversions.h:491
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
float dt_image_get_exposure_bias(const struct dt_image_t *image_storage)
Definition common/image.c:2958
int dt_image_is_raw(const dt_image_t *img)
Definition common/image.c:189
void dt_conf_set_int(const char *name, int val)
Definition control/conf.c:130
int dt_conf_get_int(const char *name)
Definition control/conf.c:241
darktable_t darktable
Definition darktable.c:173
void dt_print(dt_debug_thread_t thread, const char *msg,...)
Definition darktable.c:1448
#define dt_free_align(ptr)
Definition darktable.h:481
static void * dt_calloc_align(size_t size)
Definition darktable.h:488
#define __OMP_SIMD__(...)
Definition darktable.h:262
@ DT_DEBUG_OPENCL
Definition darktable.h:721
@ DT_DEBUG_DEV
Definition darktable.h:717
#define DT_ALIGNED_ARRAY
Definition darktable.h:388
#define for_each_channel(_var,...)
Definition darktable.h:662
#define dt_pixelpipe_cache_alloc_align_float_cache(pixels, id)
Definition darktable.h:447
float dt_aligned_pixel_simd_t __attribute__((vector_size(16), aligned(16)))
Enable aggressive floating-point arithmetic optimizations, in denormals handling. Set through user pr...
Definition darktable.h:524
#define dt_free(ptr)
Definition darktable.h:456
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
Definition darktable.h:151
#define __OMP_DECLARE_SIMD__(...)
Definition darktable.h:263
#define dt_pixelpipe_cache_free_align(mem)
Definition darktable.h:453
#define dt_pixelpipe_cache_alloc_align_float(pixels, pipe)
Definition darktable.h:442
#define __DT_CLONE_TARGETS__
Definition darktable.h:367
#define __OMP_PARALLEL_FOR__(...)
Definition darktable.h:258
static const dt_aligned_pixel_simd_t value
Definition darktable.h:577
#define __OMP_PARALLEL_FOR_SIMD__(...)
Definition darktable.h:259
static gboolean dt_modifier_is(const GdkModifierType state, const GdkModifierType desired_modifier_mask)
Definition darktable.h:892
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Definition darktable.h:281
dt_noise_distribution_t
Definition data/kernels/noise_generator.h:25
@ DT_NOISE_GAUSSIAN
Definition data/kernels/noise_generator.h:27
@ DT_NOISE_POISSONIAN
Definition data/kernels/noise_generator.h:28
@ DT_NOISE_UNIFORM
Definition data/kernels/noise_generator.h:26
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:132
static unsigned int splitmix32(const unsigned long seed)
Definition data/kernels/noise_generator.h:32
static float xoshiro128plus(uint state[4])
Definition data/kernels/noise_generator.h:49
#define dt_dev_add_history_item(dev, module, enable, redraw)
Definition dev_history.h:257
void dt_iop_params_t
Definition dev_history.h:41
#define dt_dev_pixelpipe_update_history_main(dev)
Definition dev_pixelpipe.h:40
@ DT_DEV_PIXELPIPE_DISPLAY_MASK
Definition develop.h:118
@ DT_DEV_PIXELPIPE_DISPLAY_PASSTHRU
Definition develop.h:136
@ DT_DEV_PIXELPIPE_DISPLAY_NONE
Definition develop.h:117
static float dt_log_scale_axis(const float x, const float base)
Definition draw.h:186
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:143
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:191
GtkWidget * dtgtk_drawing_area_new_with_aspect_ratio(double aspect)
Definition drawingarea.c:54
void dtgtk_drawing_area_set_aspect_ratio(GtkWidget *widget, double aspect)
Definition drawingarea.c:63
void dtgtk_cairo_paint_refresh(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
Definition dtgtk/paint.c:1666
void dtgtk_cairo_paint_showmask(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
Definition dtgtk/paint.c:2301
void dtgtk_cairo_paint_text_label(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
Definition dtgtk/paint.c:2450
void(* DTGTKCairoPaintIconFunc)(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
Definition dtgtk/paint.h:75
static void weight(const float *c1, const float *c2, const float sharpen, dt_aligned_pixel_t weight)
Definition eaw.c:30
static void toe_shoulder_callback(GtkWidget *slider, gpointer user_data)
Definition filmicrgb.c:3542
static gboolean area_button_press(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
Definition filmicrgb.c:4572
static gboolean area_scroll_callback(GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
Definition filmicrgb.c:4758
const char ** description(struct dt_iop_module_t *self)
Definition filmicrgb.c:364
int default_group()
Definition filmicrgb.c:375
static gboolean area_leave_notify(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
Definition filmicrgb.c:4672
static __DT_CLONE_TARGETS__ void display_mask(const float *const restrict mask, float *const restrict out, const size_t width, const size_t height)
Definition filmicrgb.c:2201
dt_iop_filmic_noise_distribution_t
Definition filmicrgb.c:187
@ DT_FILMIC_NOISE_UNIFORM
Definition filmicrgb.c:188
@ DT_FILMIC_NOISE_POISSONIAN
Definition filmicrgb.c:190
@ DT_FILMIC_NOISE_GAUSSIAN
Definition filmicrgb.c:189
dt_iop_filmicrgb_curve_type_t
Definition filmicrgb.c:136
@ DT_FILMIC_CURVE_RATIONAL
Definition filmicrgb.c:139
@ DT_FILMIC_CURVE_POLY_4
Definition filmicrgb.c:137
@ DT_FILMIC_CURVE_POLY_3
Definition filmicrgb.c:138
void gui_reset(dt_iop_module_t *self)
Definition filmicrgb.c:3650
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:3684
static gboolean dt_iop_tonecurve_draw(GtkWidget *widget, cairo_t *crf, gpointer user_data)
Definition filmicrgb.c:3724
dt_iop_filmic_rgb_gui_mode_t
Definition filmicrgb.c:177
@ DT_FILMIC_GUI_LOOK
Definition filmicrgb.c:178
@ DT_FILMIC_GUI_RANGES
Definition filmicrgb.c:181
@ DT_FILMIC_GUI_BASECURVE
Definition filmicrgb.c:179
@ DT_FILMIC_GUI_BASECURVE_LOG
Definition filmicrgb.c:180
@ DT_FILMIC_GUI_LAST
Definition filmicrgb.c:182
static __DT_CLONE_TARGETS__ 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:1432
void reload_defaults(dt_iop_module_t *module)
Definition filmicrgb.c:3577
static __DT_CLONE_TARGETS__ 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:1170
dt_iop_filmicrgb_colorscience_type_t
Definition filmicrgb.c:144
@ DT_FILMIC_COLORSCIENCE_V1
Definition filmicrgb.c:145
@ DT_FILMIC_COLORSCIENCE_V2
Definition filmicrgb.c:146
@ DT_FILMIC_COLORSCIENCE_V5
Definition filmicrgb.c:149
@ DT_FILMIC_COLORSCIENCE_V4
Definition filmicrgb.c:148
@ DT_FILMIC_COLORSCIENCE_V3
Definition filmicrgb.c:147
#define LOGBASE
Definition filmicrgb.c:3655
__DT_CLONE_TARGETS__ int process(dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const restrict ivoid, void *const restrict ovoid)
Definition filmicrgb.c:2269
void gui_update(dt_iop_module_t *self)
Refresh GUI controls from current params and configuration.
Definition filmicrgb.c:3555
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:3657
static void apply_auto_grey(dt_iop_module_t *self, const dt_iop_order_iccprofile_info_t *const work_profile)
Definition filmicrgb.c:2955
static __DT_CLONE_TARGETS__ 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:1568
static void apply_auto_black(dt_iop_module_t *self, const dt_iop_order_iccprofile_info_t *const work_profile)
Definition filmicrgb.c:2983
static __DT_CLONE_TARGETS__ 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:1222
const char * aliases()
Definition filmicrgb.c:359
void gui_focus(struct dt_iop_module_t *self, gboolean in)
Definition filmicrgb.c:3502
static cl_int reconstruct_highlights_cl(const dt_dev_pixelpipe_t *pipe, cl_mem in, cl_mem mask, cl_mem reconstructed, const dt_iop_filmicrgb_reconstruction_type_t variant, dt_iop_filmicrgb_global_data_t *const gd, const dt_iop_filmicrgb_data_t *const data, const dt_dev_pixelpipe_iop_t *piece, const dt_iop_roi_t *const roi_in)
Definition filmicrgb.c:2439
#define CIE_Y_1931_to_CIE_Y_2006(x)
Definition filmicrgb.c:1721
const char * name()
Definition filmicrgb.c:354
static __DT_CLONE_TARGETS__ 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:2051
static __DT_CLONE_TARGETS__ 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:1514
static __DT_CLONE_TARGETS__ 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:2099
void gui_init(dt_iop_module_t *self)
Definition filmicrgb.c:4775
dt_iop_filmicrgb_methods_type_t
Definition filmicrgb.c:125
@ DT_FILMIC_METHOD_POWER_NORM
Definition filmicrgb.c:129
@ DT_FILMIC_METHOD_EUCLIDEAN_NORM_V1
Definition filmicrgb.c:131
@ DT_FILMIC_METHOD_NONE
Definition filmicrgb.c:126
@ DT_FILMIC_METHOD_MAX_RGB
Definition filmicrgb.c:127
@ DT_FILMIC_METHOD_EUCLIDEAN_NORM_V2
Definition filmicrgb.c:130
@ DT_FILMIC_METHOD_LUMINANCE
Definition filmicrgb.c:128
static __DT_CLONE_TARGETS__ 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:1473
static float log_tonemapping(const float x, const float grey, const float black, const float dynamic_range)
Definition filmicrgb.c:979
dt_iop_filmicrgb_reconstruction_type_t
Definition filmicrgb.c:160
@ DT_FILMIC_RECONSTRUCT_RATIOS
Definition filmicrgb.c:162
@ DT_FILMIC_RECONSTRUCT_RGB
Definition filmicrgb.c:161
static void filmic_v3_legacy_to_direct(const dt_iop_filmicrgb_params_t *const p, float *const toe, float *const shoulder)
Definition filmicrgb.c:503
void gui_changed(dt_iop_module_t *self, GtkWidget *w, void *previous)
Definition filmicrgb.c:5071
dt_iop_filmicrgb_gui_button_t
Definition filmicrgb.c:230
@ DT_FILMIC_GUI_BUTTON_LAST
Definition filmicrgb.c:233
@ DT_FILMIC_GUI_BUTTON_LABELS
Definition filmicrgb.c:232
@ DT_FILMIC_GUI_BUTTON_TYPE
Definition filmicrgb.c:231
void tiling_callback(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, struct dt_develop_tiling_t *tiling)
Definition filmicrgb.c:2249
static __DT_CLONE_TARGETS__ int get_scales(const dt_dev_pixelpipe_t *const pipe, const dt_iop_roi_t *roi_in, const dt_dev_pixelpipe_iop_t *const piece)
Definition filmicrgb.c:1308
static int reconstruct_highlights(const dt_dev_pixelpipe_t *const pipe, 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, const 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:1328
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:3430
static void apply_auto_white_point_source(dt_iop_module_t *self, const dt_iop_order_iccprofile_info_t *const work_profile)
Definition filmicrgb.c:3010
#define ORDER_4
Definition filmicrgb.c:3166
static float exp_tonemapping_v2(const float x, const float grey, const float black, const float dynamic_range)
Definition filmicrgb.c:986
void cleanup_global(dt_iop_module_so_t *module)
Definition filmicrgb.c:3629
static void filmic_prepare_simd_matrices(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, dt_iop_filmicrgb_simd_matrices_t *const simd_matrices)
Definition filmicrgb.c:1978
static gboolean area_enter_notify(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
Definition filmicrgb.c:4659
void cleanup_pipe(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition filmicrgb.c:3522
static __DT_CLONE_TARGETS__ 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:1099
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
Definition filmicrgb.c:385
void input_format(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, dt_iop_buffer_dsc_t *dsc)
Definition filmicrgb.c:390
static gboolean area_motion_notify(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
Definition filmicrgb.c:4684
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:1128
int flags()
Definition filmicrgb.c:380
static void apply_autotune(dt_iop_module_t *self, const dt_iop_order_iccprofile_info_t *const work_profile)
Definition filmicrgb.c:3036
static __DT_CLONE_TARGETS__ 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:2145
static gboolean filmic_v3_compute_geometry(const dt_iop_filmicrgb_params_t *const p, dt_iop_filmicrgb_v3_geometry_t *const geometry)
Definition filmicrgb.c:429
static void show_mask_callback(GtkToggleButton *button, GdkEventButton *event, gpointer user_data)
Definition filmicrgb.c:3145
#define ORDER_3
Definition filmicrgb.c:3167
static __DT_CLONE_TARGETS__ 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:1298
static void convert_to_spline_v3(dt_iop_filmicrgb_params_t *n)
Definition filmicrgb.c:555
static __DT_CLONE_TARGETS__ 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:2214
static void filmic_v3_direct_to_legacy(const dt_iop_filmicrgb_params_t *const p, const float toe, const float shoulder, float *const latitude, float *const balance)
Definition filmicrgb.c:521
#define MAX_NUM_SCALES
Definition filmicrgb.c:1097
dt_iop_filmicrgb_spline_version_type_t
Definition filmicrgb.c:153
@ DT_FILMIC_SPLINE_VERSION_V2
Definition filmicrgb.c:155
@ DT_FILMIC_SPLINE_VERSION_V3
Definition filmicrgb.c:156
@ DT_FILMIC_SPLINE_VERSION_V1
Definition filmicrgb.c:154
void init_pipe(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition filmicrgb.c:3516
static void filmic_gui_sync_toe_shoulder(dt_iop_module_t *self)
Definition filmicrgb.c:3528
#define INVERSE_SQRT_3
Definition filmicrgb.c:87
void init_global(dt_iop_module_so_t *module)
Definition filmicrgb.c:3604
void autoset(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, const void *i)
Definition filmicrgb.c:3075
static gboolean filmic_v3_compute_nodes_from_legacy(const dt_iop_filmicrgb_params_t *const p, dt_iop_filmicrgb_v3_geometry_t *const geometry, dt_iop_filmicrgb_v3_nodes_t *const nodes)
Definition filmicrgb.c:474
int process_cl(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, cl_mem dev_in, cl_mem dev_out)
Definition filmicrgb.c:2660
static __DT_CLONE_TARGETS__ 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:1282
void color_picker_apply(dt_iop_module_t *self, GtkWidget *picker, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition filmicrgb.c:3124
#define SAFETY_MARGIN
Definition filmicrgb.c:88
static float linear_saturation(const float x, const float luminance, const float saturation)
Definition filmicrgb.c:1091
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:3171
static __DT_CLONE_TARGETS__ void restore_ratios(float *const restrict ratios, const float *const restrict norms, const size_t width, const size_t height)
Definition filmicrgb.c:2232
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:618
static int gauss_solve(double *A, double *b, int n)
Definition gaussian_elimination.h:104
gboolean dt_gui_get_scroll_unit_deltas(const GdkEventScroll *event, int *delta_x, int *delta_y)
Definition gtk.c:214
GtkWidget * dt_ui_notebook_page(GtkNotebook *notebook, const char *text, const char *tooltip)
Definition gtk.c:1918
GtkNotebook * dt_ui_notebook_new()
Definition gtk.c:1913
void dt_gui_add_class(GtkWidget *widget, const gchar *class_name)
Definition gtk.c:129
static cairo_surface_t * dt_cairo_image_surface_create(cairo_format_t format, int width, int height)
Definition gtk.h:226
static GtkWidget * dt_ui_section_label_new(const gchar *str)
Definition gtk.h:361
#define DT_PIXEL_APPLY_DPI(value)
Definition gtk.h:75
static GtkWidget * dt_ui_label_new(const gchar *str)
Definition gtk.h:371
#define DT_GUI_MODULE(x)
Definition gui_module_api.h:67
void dt_iop_request_focus(dt_iop_module_t *module)
Definition imageop.c:1924
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:2786
float dt_dev_get_module_scale(const dt_dev_pixelpipe_t *const pipe, const dt_iop_roi_t *const roi_in)
Definition imageop.c:123
void dt_iop_set_cache_bypass(dt_iop_module_t *module, gboolean state)
Definition imageop.c:2560
#define dt_omploop_sfence()
Definition imageop.h:689
@ IOP_FLAGS_INCLUDE_IN_STYLES
Definition imageop.h:166
@ IOP_FLAGS_SUPPORTS_BLENDING
Definition imageop.h:167
@ IOP_FLAGS_ALLOW_TILING
Definition imageop.h:169
@ IOP_GROUP_TONES
Definition imageop.h:137
#define IOP_GUI_ALLOC(module)
Definition imageop.h:586
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:287
GtkWidget * dt_bauhaus_toggle_from_params(dt_iop_module_t *self, const char *param)
Definition imageop_gui.c:246
GtkWidget * dt_bauhaus_slider_from_params(dt_iop_module_t *self, const char *param)
Definition imageop_gui.c:77
GtkWidget * dt_bauhaus_combobox_from_params(dt_iop_module_t *self, const char *param)
Definition imageop_gui.c:182
void *const ovoid
Definition imageop_math.h:178
dt_iop_order_iccprofile_info_t * dt_ioppr_get_pipe_output_profile_info(const struct dt_dev_pixelpipe_t *pipe)
Definition iop_profile.c:879
dt_iop_order_iccprofile_info_t * dt_ioppr_get_pipe_work_profile_info(const struct dt_dev_pixelpipe_t *pipe)
Definition iop_profile.c:869
dt_iop_order_iccprofile_info_t * dt_ioppr_get_pipe_current_profile_info(dt_iop_module_t *module, const struct dt_dev_pixelpipe_t *pipe)
Definition iop_profile.c:884
void dt_ioppr_free_iccprofile_params_cl(dt_colorspaces_iccprofile_info_cl_t **_profile_info_cl, cl_float **_profile_lut_cl, cl_mem *_dev_profile_info, cl_mem *_dev_profile_lut)
Definition iop_profile.c:1224
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:747
cl_int dt_ioppr_build_iccprofile_params_cl(const dt_iop_order_iccprofile_info_t *const profile_info, const int devid, dt_colorspaces_iccprofile_info_cl_t **_profile_info_cl, cl_float **_profile_lut_cl, cl_mem *_dev_profile_info, cl_mem *_dev_profile_lut)
Definition iop_profile.c:1169
static const float x
Definition iop_profile.h:235
const float *const const float coeff[3]
Definition iop_profile.h:240
@ linear
Definition lightroom.c:368
float *const restrict luminance
Definition luminance_mask.h:77
float *const restrict const size_t k
Definition luminance_mask.h:78
float *const restrict const size_t const size_t ch
Definition luminance_mask.h:78
#define NORM_MIN
Definition math.h:35
#define CLAMPF(a, mn, mx)
Definition math.h:89
#define M_PI
Definition math.h:45
float DT_ALIGNED_ARRAY dt_colormatrix_t[4][4]
Definition matrices.h:33
static void transpose_3xSSE(const dt_colormatrix_t input, dt_colormatrix_t output)
Definition matrices.h:68
static void pack_3xSSE_to_3x4(const dt_colormatrix_t input, float output[12])
Definition matrices.h:149
static void dt_colormatrix_mul(dt_colormatrix_t dst, const dt_colormatrix_t m1, const dt_colormatrix_t m2)
Definition matrices.h:166
size_t size
Definition mipmap_cache.c:3
c
Definition derive_filmic_v6_gamut_mapping.py:35
Yrg
Definition derive_filmic_v6_gamut_mapping.py:38
Y
Definition derive_filmic_v6_gamut_mapping.py:35
float dt_aligned_pixel_t[4]
Definition noiseprofile.c:28
int dt_opencl_local_buffer_opt(const int devid, const int kernel, dt_opencl_local_buffer_t *factors)
Definition opencl.c:2970
int dt_opencl_enqueue_kernel_2d(const int dev, const int kernel, const size_t *sizes)
Definition opencl.c:1951
void * dt_opencl_alloc_device_buffer(const int devid, const size_t size)
Definition opencl.c:2359
void * dt_opencl_alloc_device(const int devid, const int width, const int height, const int bpp)
Definition opencl.c:2286
int dt_opencl_create_kernel(const int prog, const char *name)
Definition opencl.c:1845
void * dt_opencl_copy_host_to_device_constant(const int devid, const size_t size, void *host)
Definition opencl.c:2147
int dt_opencl_write_buffer_to_device(const int devid, void *host, void *device, const size_t offset, const size_t size, const int blocking)
Definition opencl.c:2135
int dt_opencl_enqueue_copy_image(const int devid, cl_mem src, cl_mem dst, size_t *orig_src, size_t *orig_dst, size_t *region)
Definition opencl.c:2076
int dt_opencl_read_buffer_from_device(const int devid, void *host, void *device, const size_t offset, const size_t size, const int blocking)
Definition opencl.c:2124
void dt_opencl_free_kernel(const int kernel)
Definition opencl.c:1888
int dt_opencl_set_kernel_arg(const int dev, const int kernel, const int num, const size_t size, const void *arg)
Definition opencl.c:1942
int dt_opencl_enqueue_kernel_2d_with_local(const int dev, const int kernel, const size_t *sizes, const size_t *local)
Definition opencl.c:1957
void dt_opencl_release_mem_object(cl_mem mem)
Definition opencl.c:2198
#define ROUNDUP(a, n)
Definition opencl.h:78
#define ROUNDUPDHT(a, b)
Definition opencl.h:82
#define ROUNDUPDWD(a, b)
Definition opencl.h:81
static float fmaxabsf(const float a, const float b)
Definition openmp_maths.h:109
static float clamp_simd(const float x)
Definition openmp_maths.h:127
@ DT_DEV_PIXELPIPE_FULL
Definition pixelpipe.h:39
#define eps
Definition rcd.c:81
struct _GtkWidget GtkWidget
Definition splash.h:29
const float uint32_t state[4]
Definition src/develop/noise_generator.h:72
const float sigma
Definition src/develop/noise_generator.h:71
const float r
Definition src/develop/noise_generator.h:101
const float const int flip
Definition src/develop/noise_generator.h:78
const float noise
Definition src/develop/noise_generator.h:87
int32_t num_openmp_threads
Definition darktable.h:757
struct dt_gui_gtk_t * gui
Definition darktable.h:774
struct dt_bauhaus_t * bauhaus
Definition darktable.h:777
struct dt_develop_t * develop
Definition darktable.h:769
GdkRGBA graph_bg
Definition bauhaus.h:273
GdkRGBA graph_border
Definition bauhaus.h:273
PangoFontDescription * pango_font_desc
Definition bauhaus.h:266
float quad_width
Definition bauhaus.h:265
GdkRGBA graph_fg
Definition bauhaus.h:273
Definition color_conversion.h:42
Definition pixelpipe_hb.h:96
size_t data_size
Definition pixelpipe_hb.h:108
dt_iop_roi_t buf_in
Definition pixelpipe_hb.h:131
dt_iop_buffer_dsc_t dsc_in
Definition pixelpipe_hb.h:142
struct dt_iop_module_t *void * data
Definition pixelpipe_hb.h:97
dt_iop_roi_t roi_in
Definition pixelpipe_hb.h:132
dt_iop_roi_t roi_out
Definition pixelpipe_hb.h:132
Definition pixelpipe_hb.h:218
int mask_display
Definition pixelpipe_hb.h:295
dt_dev_pixelpipe_type_t type
Definition pixelpipe_hb.h:300
float iscale
Definition pixelpipe_hb.h:232
int devid
Definition pixelpipe_hb.h:308
int32_t gui_attached
Definition develop.h:162
dt_image_t image_storage
Definition develop.h:248
GList * iop
Definition develop.h:268
double dpi
Definition gtk.h:162
gint scroll_mask
Definition gtk.h:179
int32_t reset
Definition gtk.h:143
unsigned int channels
Definition format.h:54
dt_iop_buffer_type_t datatype
Definition format.h:56
Definition filmicrgb.c:167
dt_aligned_pixel_t M2
Definition filmicrgb.c:168
dt_aligned_pixel_t M4
Definition filmicrgb.c:168
dt_iop_filmicrgb_curve_type_t type[2]
Definition filmicrgb.c:172
dt_aligned_pixel_t M5
Definition filmicrgb.c:168
float latitude_min
Definition filmicrgb.c:169
float y[5]
Definition filmicrgb.c:170
dt_aligned_pixel_t M1
Definition filmicrgb.c:168
float x[5]
Definition filmicrgb.c:171
dt_aligned_pixel_t M3
Definition filmicrgb.c:168
float latitude_max
Definition filmicrgb.c:169
Definition filmicrgb.c:309
int high_quality_reconstruction
Definition filmicrgb.c:329
int spline_version
Definition filmicrgb.c:328
float reconstruct_feather
Definition filmicrgb.c:315
float dynamic_range
Definition filmicrgb.c:320
float reconstruct_structure_vs_texture
Definition filmicrgb.c:318
float max_grad
Definition filmicrgb.c:310
float reconstruct_grey_vs_color
Definition filmicrgb.c:317
float output_power
Definition filmicrgb.c:322
float sigma_shoulder
Definition filmicrgb.c:324
float white_source
Definition filmicrgb.c:311
float noise_level
Definition filmicrgb.c:325
float sigma_toe
Definition filmicrgb.c:324
dt_noise_distribution_t noise_distribution
Definition filmicrgb.c:331
int version
Definition filmicrgb.c:327
float grey_source
Definition filmicrgb.c:312
float normalize
Definition filmicrgb.c:319
float reconstruct_bloom_vs_details
Definition filmicrgb.c:316
float saturation
Definition filmicrgb.c:321
float contrast
Definition filmicrgb.c:323
struct dt_iop_filmic_rgb_spline_t spline DT_ALIGNED_ARRAY
Definition filmicrgb.c:330
float black_source
Definition filmicrgb.c:313
float reconstruct_threshold
Definition filmicrgb.c:314
int preserve_color
Definition filmicrgb.c:326
Definition filmicrgb.c:336
int kernel_filmic_rgb_chroma
Definition filmicrgb.c:338
int kernel_filmic_bspline_vertical
Definition filmicrgb.c:342
int kernel_filmic_rgb_split
Definition filmicrgb.c:337
int kernel_filmic_wavelets_reconstruct
Definition filmicrgb.c:348
int kernel_filmic_wavelets_detail
Definition filmicrgb.c:347
int kernel_filmic_show_mask
Definition filmicrgb.c:340
int kernel_filmic_compute_ratios
Definition filmicrgb.c:349
int kernel_filmic_init_reconstruct
Definition filmicrgb.c:346
int kernel_filmic_restore_ratios
Definition filmicrgb.c:350
int kernel_filmic_bspline_vertical_local
Definition filmicrgb.c:344
int kernel_filmic_mask
Definition filmicrgb.c:339
int kernel_filmic_bspline_horizontal
Definition filmicrgb.c:343
int kernel_filmic_inpaint_noise
Definition filmicrgb.c:341
int kernel_filmic_bspline_horizontal_local
Definition filmicrgb.c:345
Definition filmicrgb.c:258
GtkWidget * high_quality_reconstruction
Definition filmicrgb.c:281
GtkWidget * autoset_display_gamma
Definition filmicrgb.c:276
GtkWidget * reconstruct_grey_vs_color
Definition filmicrgb.c:262
GtkWidget * auto_hardness
Definition filmicrgb.c:279
dt_iop_filmicrgb_gui_button_data_t buttons[DT_FILMIC_GUI_BUTTON_LAST]
Definition filmicrgb.c:293
GtkWidget * reconstruct_bloom_vs_details
Definition filmicrgb.c:262
GtkWidget * reconstruct_threshold
Definition filmicrgb.c:262
GtkNotebook * notebook
Definition filmicrgb.c:284
GtkWidget * contrast
Definition filmicrgb.c:273
float graph_height
Definition filmicrgb.c:300
GtkWidget * auto_button
Definition filmicrgb.c:266
GtkWidget * saturation
Definition filmicrgb.c:274
GtkWidget * show_highlight_mask
Definition filmicrgb.c:264
float sign_width
Definition filmicrgb.c:297
GtkWidget * white_point_target
Definition filmicrgb.c:268
GtkWidget * grey_point_source
Definition filmicrgb.c:260
gint gui_show_labels
Definition filmicrgb.c:289
GtkWidget * highlights
Definition filmicrgb.c:277
GtkDrawingArea * area
Definition filmicrgb.c:285
GtkStyleContext * context
Definition filmicrgb.c:305
GtkWidget * output_power
Definition filmicrgb.c:270
GtkWidget * preserve_color
Definition filmicrgb.c:275
PangoRectangle ink
Definition filmicrgb.c:304
dt_iop_filmicrgb_gui_button_t active_button
Definition filmicrgb.c:292
GtkWidget * shadows
Definition filmicrgb.c:277
gint gui_hover
Definition filmicrgb.c:290
GtkAllocation allocation
Definition filmicrgb.c:303
GtkWidget * noise_level
Definition filmicrgb.c:282
GtkWidget * grey_point_target
Definition filmicrgb.c:267
dt_iop_filmic_rgb_gui_mode_t gui_mode
Definition filmicrgb.c:288
gint gui_sizes_inited
Definition filmicrgb.c:291
GtkWidget * black_point_source
Definition filmicrgb.c:261
GtkWidget * reconstruct_structure_vs_texture
Definition filmicrgb.c:263
float graph_width
Definition filmicrgb.c:299
GtkWidget * reconstruct_feather
Definition filmicrgb.c:263
GtkWidget * version
Definition filmicrgb.c:278
GtkWidget * noise_distribution
Definition filmicrgb.c:282
float zero_width
Definition filmicrgb.c:298
GtkWidget * shoulder
Definition filmicrgb.c:272
gint show_mask
Definition filmicrgb.c:287
GtkWidget * toe
Definition filmicrgb.c:271
float line_height
Definition filmicrgb.c:296
GtkWidget * black_point_target
Definition filmicrgb.c:269
int inset
Definition filmicrgb.c:301
GtkWidget * custom_grey
Definition filmicrgb.c:280
struct dt_iop_filmic_rgb_spline_t spline DT_ALIGNED_ARRAY
Definition filmicrgb.c:286
GtkWidget * white_point_source
Definition filmicrgb.c:259
GtkWidget * security_factor
Definition filmicrgb.c:265
GtkWidget * compensate_icc_black
Definition filmicrgb.c:283
Definition filmicrgb.c:195
float reconstruct_threshold
Definition filmicrgb.c:199
float reconstruct_grey_vs_color
Definition filmicrgb.c:202
float reconstruct_feather
Definition filmicrgb.c:200
dt_iop_filmicrgb_curve_type_t shadows
Definition filmicrgb.c:220
dt_iop_filmicrgb_spline_version_type_t spline_version
Definition filmicrgb.c:223
float white_point_target
Definition filmicrgb.c:207
gboolean auto_hardness
Definition filmicrgb.c:216
float contrast
Definition filmicrgb.c:210
float latitude
Definition filmicrgb.c:209
float security_factor
Definition filmicrgb.c:204
dt_iop_filmicrgb_colorscience_type_t version
Definition filmicrgb.c:215
float balance
Definition filmicrgb.c:212
dt_iop_filmic_noise_distribution_t noise_distribution
Definition filmicrgb.c:219
dt_iop_filmicrgb_methods_type_t preserve_color
Definition filmicrgb.c:214
int high_quality_reconstruction
Definition filmicrgb.c:218
dt_iop_filmicrgb_curve_type_t highlights
Definition filmicrgb.c:221
float grey_point_source
Definition filmicrgb.c:196
float output_power
Definition filmicrgb.c:208
float reconstruct_bloom_vs_details
Definition filmicrgb.c:201
float grey_point_target
Definition filmicrgb.c:205
float saturation
Definition filmicrgb.c:211
gboolean custom_grey
Definition filmicrgb.c:217
float noise_level
Definition filmicrgb.c:213
float black_point_source
Definition filmicrgb.c:197
gboolean compensate_icc_black
Definition filmicrgb.c:222
float black_point_target
Definition filmicrgb.c:206
float white_point_source
Definition filmicrgb.c:198
float reconstruct_structure_vs_texture
Definition filmicrgb.c:203
Definition filmicrgb.c:1964
dt_aligned_pixel_simd_t input[3]
Definition filmicrgb.c:1965
dt_aligned_pixel_simd_t output[3]
Definition filmicrgb.c:1966
dt_aligned_pixel_simd_t export_output[3]
Definition filmicrgb.c:1968
dt_aligned_pixel_simd_t export_input[3]
Definition filmicrgb.c:1967
Definition filmicrgb.c:402
float white_display
Definition filmicrgb.c:406
float linear_intercept
Definition filmicrgb.c:408
float black_display
Definition filmicrgb.c:405
float xmin
Definition filmicrgb.c:409
gboolean contrast_clamped
Definition filmicrgb.c:411
float grey_display
Definition filmicrgb.c:404
float grey_log
Definition filmicrgb.c:403
float contrast
Definition filmicrgb.c:407
float xmax
Definition filmicrgb.c:410
Definition filmicrgb.c:415
float shoulder_display
Definition filmicrgb.c:419
float toe_display
Definition filmicrgb.c:418
float toe_log
Definition filmicrgb.c:416
float shoulder_log
Definition filmicrgb.c:417
dt_iop_global_data_t * data
Definition imageop.h:233
GtkDarktableToggleButton * off
Definition imageop.h:341
dt_iop_params_t * default_params
Definition imageop.h:309
GtkWidget * widget
Definition imageop.h:339
struct dt_develop_t * dev
Definition imageop.h:298
dt_iop_gui_data_t * gui_data
Definition imageop.h:313
dt_iop_global_data_t * global_data
Definition imageop.h:316
gboolean enabled
Definition imageop.h:300
dt_aligned_pixel_t picked_color_min
Definition imageop.h:274
int request_mask_display
Definition imageop.h:268
dt_aligned_pixel_t picked_color_max
Definition imageop.h:274
dt_aligned_pixel_t picked_color
Definition imageop.h:274
dt_iop_params_t * params
Definition imageop.h:309
Definition iop_profile.h:52
int nonlinearlut
Definition iop_profile.h:63
int lutsize
Definition iop_profile.h:58
dt_colormatrix_t matrix_out
Definition iop_profile.h:57
float * lut_in[3]
Definition iop_profile.h:59
dt_colormatrix_t matrix_in_transposed
Definition iop_profile.h:65
dt_colormatrix_t matrix_in
Definition iop_profile.h:56
Region of interest passed through the pixelpipe.
Definition imageop.h:72
int width
Definition imageop.h:73
int height
Definition imageop.h:73
const int xoffset
Definition opencl.h:270
int sizey
Definition opencl.h:277
int sizex
Definition opencl.h:276
#define E
Definition test_filmicrgb.c:61
#define MIN(a, b)
Definition thinplate.c:32
#define MAX(a, b)
Definition thinplate.c:29