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)
130#pragma GCC optimize("finite-math-only", "fp-contract=fast", "fast-math", "no-math-errno")
366 return _(
"fil_mic rgb");
371 return _(
"tone mapping|curve|view transform|contrast|saturation|highlights");
377 "for display on SDR screens and paper prints\n"
378 "while preventing clipping in non-destructive ways"),
379 _(
"corrective and creative"),
380 _(
"linear or non-linear, RGB, scene-referred"),
381 _(
"non-linear, RGB"),
382 _(
"non-linear, RGB, display-referred"));
445 geometry->
grey_display = powf(CLAMP(
p->grey_point_target,
p->black_point_target,
p->white_point_target) / 100.0f,
446 1.0f /
p->output_power);
448 geometry->
grey_display = powf(0.1845f, 1.0f /
p->output_power);
450 const float dynamic_range =
p->white_point_source -
p->black_point_source;
451 geometry->
grey_log = fabsf(
p->black_point_source) / dynamic_range;
452 geometry->
black_display = powf(CLAMP(
p->black_point_target, 0.0f,
p->grey_point_target) / 100.0f,
453 1.0f /
p->output_power);
454 geometry->
white_display = powf(fmaxf(
p->white_point_target,
p->grey_point_target) / 100.0f,
455 1.0f /
p->output_power);
457 const float slope =
p->contrast * dynamic_range / 8.0f;
458 float min_contrast = 1.0f;
459 min_contrast = fmaxf(min_contrast,
461 min_contrast = fmaxf(min_contrast,
466 const float clamped_contrast = CLAMP(geometry->
contrast, min_contrast, 100.0f);
468 geometry->
contrast = clamped_contrast;
490 const float latitude = CLAMP(
p->latitude, 0.0f, 100.0f) / 100.0f;
491 const float balance = CLAMP(
p->balance, -50.0f, 50.0f) / 100.0f;
500 const float balance_correction = (balance > 0.0f)
503 nodes->
toe_log -= balance_correction;
514 float *
const toe,
float *
const shoulder)
520 *toe = CLAMP(
p->latitude, 0.0f, 100.0f);
521 *shoulder = CLAMP(
p->latitude, 0.0f, 100.0f);
525 const float toe_span = fmaxf(geometry.
grey_log - geometry.
xmin, 1e-6f);
526 const float shoulder_span = fmaxf(geometry.
xmax - geometry.
grey_log, 1e-6f);
527 *toe = CLAMP((geometry.
grey_log - nodes.
toe_log) / toe_span, 0.0f, 1.0f) * 100.0f;
528 *shoulder = CLAMP((nodes.
shoulder_log - geometry.
grey_log) / shoulder_span, 0.0f, 1.0f) * 100.0f;
532 const float toe,
const float shoulder,
533 float *
const latitude,
float *
const balance)
538 *latitude =
p->latitude;
539 *balance =
p->balance;
543 const float toe_value = CLAMP(toe, 0.0f, 100.0f) / 100.0f;
544 const float shoulder_value = CLAMP(shoulder, 0.0f, 100.0f) / 100.0f;
545 const float toe_span = fmaxf(geometry.
grey_log - geometry.
xmin, 1e-6f);
546 const float shoulder_span = fmaxf(geometry.
xmax - geometry.
grey_log, 1e-6f);
547 const float latitude_value = CLAMP((toe_span * toe_value + shoulder_span * shoulder_value)
548 / (toe_span + shoulder_span),
551 float balance_value = 0.0f;
552 if(latitude_value > 1e-6f)
554 if(toe_value > shoulder_value)
555 balance_value = 0.5f * (1.0f - shoulder_value / latitude_value);
556 else if(shoulder_value > toe_value)
557 balance_value = 0.5f * (toe_value / latitude_value - 1.0f);
560 *latitude = latitude_value * 100.0f;
561 *balance = CLAMP(balance_value, -0.5f, 0.5f) * 100.0f;
574 float grey_log = spline.
x[2];
575 float toe_log = fminf(spline.
x[1], grey_log);
576 float shoulder_log = fmaxf(spline.
x[3], grey_log);
577 float black_display = spline.
y[0];
578 float grey_display = spline.
y[2];
579 float white_display = spline.
y[4];
580 const float scaled_safety_margin =
SAFETY_MARGIN * (white_display - black_display);
581 float toe_display = fminf(spline.
y[1], grey_display);
582 float shoulder_display = fmaxf(spline.
y[3], grey_display);
584 float hardness =
n->output_power;
585 float contrast = (shoulder_display - toe_display) / (shoulder_log - toe_log);
587 float linear_intercept = grey_display - (contrast * grey_log);
588 if(toe_display < black_display + scaled_safety_margin)
590 toe_display = black_display + scaled_safety_margin;
592 toe_log = (toe_display - linear_intercept) / contrast;
594 if(shoulder_display > white_display - scaled_safety_margin)
596 shoulder_display = white_display - scaled_safety_margin;
598 shoulder_log = (shoulder_display - linear_intercept) / contrast;
601 contrast *= 8.0f / (
n->white_point_source -
n->black_point_source);
602 contrast *= hardness * powf(grey_display, hardness-1.0f);
604 const float latitude = CLAMP((shoulder_display - toe_display) / ((white_display - black_display) - 2.0f * scaled_safety_margin), 0.0f, 0.99f);
606 float toe_display_ref = latitude * (black_display + scaled_safety_margin) + (1.0f - latitude) * grey_display;
607 float shoulder_display_ref = latitude * (white_display - scaled_safety_margin) + (1.0f - latitude) * grey_display;
609 if(shoulder_display < shoulder_display_ref)
610 balance = 0.5f * (1.0f - fmaxf(shoulder_display - grey_display, 0.0f) / fmaxf(shoulder_display_ref - grey_display, 1E-5f));
612 balance = -0.5f * (1.0f - fmaxf(grey_display - toe_display, 0.0f) / fmaxf(grey_display - toe_display_ref, 1E-5f));
619 n->black_point_target = powf(black_display, hardness) * 100.0f;
620 n->white_point_target = powf(white_display, hardness) * 100.0f;
622 n->latitude = latitude * 100.0f;
623 n->contrast = contrast;
624 n->balance = balance * 100.0f;
629 const int new_version)
631 if(old_version == 1 && new_version == 5)
633 typedef struct dt_iop_filmicrgb_params_v1_t
635 float grey_point_source;
636 float black_point_source;
637 float white_point_source;
638 float security_factor;
639 float grey_point_target;
640 float black_point_target;
641 float white_point_target;
648 } dt_iop_filmicrgb_params_v1_t;
650 dt_iop_filmicrgb_params_v1_t *o = (dt_iop_filmicrgb_params_v1_t *)old_params;
656 n->grey_point_source = o->grey_point_source;
657 n->white_point_source = o->white_point_source;
658 n->black_point_source = o->black_point_source;
659 n->security_factor = o->security_factor;
660 n->grey_point_target = o->grey_point_target;
661 n->black_point_target = o->black_point_target;
662 n->white_point_target = o->white_point_target;
663 n->output_power = o->output_power;
664 n->latitude = o->latitude;
665 n->contrast = o->contrast;
666 n->saturation = o->saturation;
667 n->balance = o->balance;
668 n->preserve_color = o->preserve_color;
671 n->reconstruct_threshold
673 n->reconstruct_bloom_vs_details =
d->reconstruct_bloom_vs_details;
674 n->reconstruct_grey_vs_color =
d->reconstruct_grey_vs_color;
675 n->reconstruct_structure_vs_texture =
d->reconstruct_structure_vs_texture;
676 n->reconstruct_feather = 3.0f;
678 n->auto_hardness =
TRUE;
679 n->custom_grey =
TRUE;
680 n->high_quality_reconstruction = 0;
681 n->noise_distribution =
d->noise_distribution;
682 n->noise_level = 0.f;
684 n->compensate_icc_black =
FALSE;
688 if(old_version == 2 && new_version == 5)
690 typedef struct dt_iop_filmicrgb_params_v2_t
692 float grey_point_source;
693 float black_point_source;
694 float white_point_source;
695 float reconstruct_threshold;
696 float reconstruct_feather;
697 float reconstruct_bloom_vs_details;
698 float reconstruct_grey_vs_color;
699 float reconstruct_structure_vs_texture;
700 float security_factor;
701 float grey_point_target;
702 float black_point_target;
703 float white_point_target;
713 int high_quality_reconstruction;
716 } dt_iop_filmicrgb_params_v2_t;
718 dt_iop_filmicrgb_params_v2_t *o = (dt_iop_filmicrgb_params_v2_t *)old_params;
724 n->grey_point_source = o->grey_point_source;
725 n->white_point_source = o->white_point_source;
726 n->black_point_source = o->black_point_source;
727 n->security_factor = o->security_factor;
728 n->grey_point_target = o->grey_point_target;
729 n->black_point_target = o->black_point_target;
730 n->white_point_target = o->white_point_target;
731 n->output_power = o->output_power;
732 n->latitude = o->latitude;
733 n->contrast = o->contrast;
734 n->saturation = o->saturation;
735 n->balance = o->balance;
736 n->preserve_color = o->preserve_color;
737 n->shadows = o->shadows;
738 n->highlights = o->highlights;
739 n->reconstruct_threshold = o->reconstruct_threshold;
740 n->reconstruct_bloom_vs_details = o->reconstruct_bloom_vs_details;
741 n->reconstruct_grey_vs_color = o->reconstruct_grey_vs_color;
742 n->reconstruct_structure_vs_texture = o->reconstruct_structure_vs_texture;
743 n->reconstruct_feather = o->reconstruct_feather;
744 n->version = o->version;
745 n->auto_hardness = o->auto_hardness;
746 n->custom_grey = o->custom_grey;
747 n->high_quality_reconstruction = o->high_quality_reconstruction;
748 n->noise_level =
d->noise_level;
749 n->noise_distribution =
d->noise_distribution;
750 n->noise_level = 0.f;
752 n->compensate_icc_black =
FALSE;
756 if(old_version == 3 && new_version == 5)
758 typedef struct dt_iop_filmicrgb_params_v3_t
760 float grey_point_source;
761 float black_point_source;
762 float white_point_source;
763 float reconstruct_threshold;
764 float reconstruct_feather;
765 float reconstruct_bloom_vs_details;
767 float reconstruct_grey_vs_color;
769 float reconstruct_structure_vs_texture;
771 float security_factor;
772 float grey_point_target;
773 float black_point_target;
774 float white_point_target;
785 gboolean auto_hardness;
786 gboolean custom_grey;
787 int high_quality_reconstruction;
789 int noise_distribution;
793 } dt_iop_filmicrgb_params_v3_t;
795 dt_iop_filmicrgb_params_v3_t *o = (dt_iop_filmicrgb_params_v3_t *)old_params;
801 n->grey_point_source = o->grey_point_source;
802 n->white_point_source = o->white_point_source;
803 n->black_point_source = o->black_point_source;
804 n->security_factor = o->security_factor;
805 n->grey_point_target = o->grey_point_target;
806 n->black_point_target = o->black_point_target;
807 n->white_point_target = o->white_point_target;
808 n->output_power = o->output_power;
809 n->latitude = o->latitude;
810 n->contrast = o->contrast;
811 n->saturation = o->saturation;
812 n->balance = o->balance;
813 n->preserve_color = o->preserve_color;
814 n->shadows = o->shadows;
815 n->highlights = o->highlights;
816 n->reconstruct_threshold = o->reconstruct_threshold;
817 n->reconstruct_bloom_vs_details = o->reconstruct_bloom_vs_details;
818 n->reconstruct_grey_vs_color = o->reconstruct_grey_vs_color;
819 n->reconstruct_structure_vs_texture = o->reconstruct_structure_vs_texture;
820 n->reconstruct_feather = o->reconstruct_feather;
821 n->version = o->version;
822 n->auto_hardness = o->auto_hardness;
823 n->custom_grey = o->custom_grey;
824 n->high_quality_reconstruction = o->high_quality_reconstruction;
825 n->noise_level =
d->noise_level;
826 n->noise_distribution =
d->noise_distribution;
827 n->noise_level =
d->noise_level;
829 n->compensate_icc_black =
FALSE;
833 if(old_version == 4 && new_version == 5)
835 typedef struct dt_iop_filmicrgb_params_v4_t
837 float grey_point_source;
838 float black_point_source;
839 float white_point_source;
840 float reconstruct_threshold;
841 float reconstruct_feather;
842 float reconstruct_bloom_vs_details;
843 float reconstruct_grey_vs_color;
844 float reconstruct_structure_vs_texture;
845 float security_factor;
846 float grey_point_target;
847 float black_point_target;
848 float white_point_target;
857 gboolean auto_hardness;
858 gboolean custom_grey;
859 int high_quality_reconstruction;
863 gboolean compensate_icc_black;
864 gint internal_version;
865 } dt_iop_filmicrgb_params_v4_t;
867 dt_iop_filmicrgb_params_v4_t *o = (dt_iop_filmicrgb_params_v4_t *)old_params;
871 switch(o->internal_version)
891static inline __attribute__((always_inline))
float pixel_rgb_norm_power_simd(
const dt_aligned_pixel_simd_t pixel)
896 float numerator = 0.0f;
897 float denominator = 0.0f;
899 for(
int c = 0; c < 3; c++)
901 const float value = fabsf(pixel[c]);
903 const float RGB_cubic = RGB_square *
value;
904 numerator += RGB_cubic;
905 denominator += RGB_square;
908 return numerator / fmaxf(denominator, 1e-12f);
914 return pixel_rgb_norm_power_simd(dt_load_simd_aligned(pixel));
931 return fmaxf(fmaxf(pixel[0], pixel[1]), pixel[2]);
940 return dt_ioppr_get_rgb_matrix_luminance(
rgb, work_profile->
matrix_in, work_profile->
lut_in,
941 work_profile->unbounded_coeffs_in, work_profile->
lutsize,
945 return work_profile->
matrix_in[1][0] * pixel[0] + work_profile->
matrix_in[1][1] * pixel[1]
946 + work_profile->
matrix_in[1][2] * pixel[2];
949 return pixel[0] * 0.2225045f + pixel[1] * 0.7168786f + pixel[2] * 0.0606169f;
952 return pixel_rgb_norm_power_simd(pixel);
955 return sqrtf(sqf(pixel[0]) + sqf(pixel[1]) + sqf(pixel[2]));
958 return sqrtf(sqf(pixel[0]) + sqf(pixel[1]) + sqf(pixel[2])) *
INVERSE_SQRT_3;
967 return dt_ioppr_get_rgb_matrix_luminance(
rgb, work_profile->
matrix_in, work_profile->
lut_in,
968 work_profile->unbounded_coeffs_in, work_profile->
lutsize,
972 return work_profile->
matrix_in[1][0] * pixel[0] + work_profile->
matrix_in[1][1] * pixel[1]
973 + work_profile->
matrix_in[1][2] * pixel[2];
976 return pixel[0] * 0.2225045f + pixel[1] * 0.7168786f + pixel[2] * 0.0606169f;
985 return get_pixel_norm_simd(dt_load_simd_aligned(pixel), variant, work_profile);
990 const
float dynamic_range)
992 return clamp_simd((log2f(
x / grey) - black) / dynamic_range);
997 const
float dynamic_range)
1000 return grey * exp2f(dynamic_range *
x + black);
1019 if(
x < latitude_min)
1025 result = M1[0] +
x * (M2[0] +
x * (M3[0] +
x * (M4[0] +
x * M5[0])));
1030 result = M1[0] +
x * (M2[0] +
x * (M3[0] +
x * M4[0]));
1035 const float xi = latitude_min -
x;
1036 const float rat = xi * (xi * M2[0] + 1.f);
1037 result = M4[0] - M1[0] * rat / (rat + M3[0]);
1040 else if(
x > latitude_max)
1046 result = M1[1] +
x * (M2[1] +
x * (M3[1] +
x * (M4[1] +
x * M5[1])));
1051 result = M1[1] +
x * (M2[1] +
x * (M3[1] +
x * M4[1]));
1056 const float xi =
x - latitude_max;
1057 const float rat = xi * (xi * M2[1] + 1.f);
1058 result = M4[1] + M1[1] * rat / (rat + M3[1]);
1064 result = M1[2] +
x * M2[2];
1072filmic_desaturate_v1(
const float x,
const float sigma_toe,
const float sigma_shoulder,
1073 const float saturation)
1075 const float radius_toe =
x;
1076 const float radius_shoulder = 1.0f -
x;
1078 const float key_toe = expf(-0.5f * radius_toe * radius_toe / sigma_toe);
1079 const float key_shoulder = expf(-0.5f * radius_shoulder * radius_shoulder / sigma_shoulder);
1081 return 1.0f -
clamp_simd((key_toe + key_shoulder) / saturation);
1087filmic_desaturate_v2(
const float x,
const float sigma_toe,
const float sigma_shoulder,
1088 const float saturation)
1090 const float radius_toe =
x;
1091 const float radius_shoulder = 1.0f -
x;
1092 const float sat2 = 0.5f / sqrtf(saturation);
1093 const float key_toe = expf(-radius_toe * radius_toe / sigma_toe * sat2);
1094 const float key_shoulder = expf(-radius_shoulder * radius_shoulder / sigma_shoulder * sat2);
1096 return (saturation - (key_toe + key_shoulder) * (saturation));
1107#define MAX_NUM_SCALES 10
1110 const float normalize,
const float feathering,
const size_t width,
1111 const size_t height,
const size_t ch)
1123 const unsigned int oldMode = _MM_GET_FLUSH_ZERO_MODE();
1124 _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
1129 const float pix_max = fmaxf(sqrtf(sqf(in[
k]) + sqf(in[
k + 1]) + sqf(in[
k + 2])), 0.f);
1130 const float argument = -pix_max *
normalize + feathering;
1138 clipped += (4.f > argument);
1142 _MM_SET_FLUSH_ZERO_MODE(oldMode);
1146 return (clipped > 9);
1149 float *
const inpainted,
const float noise_level,
const float threshold,
1158 for(
size_t j = 0; j <
width; j++)
1168 const size_t idx =
i *
width + j;
1169 const size_t index = idx * 4;
1170 const float weight = mask[idx];
1171 const float *
const restrict pix_in = __builtin_assume_aligned(in + index, 16);
1183 float *
const restrict pix_out = __builtin_assume_aligned(inpainted + index, 16);
1191 const float *
const restrict texture,
const float *
const restrict mask,
1192 float *
const restrict reconstructed,
const size_t width,
1193 const size_t height,
const size_t ch,
const float gamma,
1194 const float gamma_comp,
const float beta,
const float beta_comp,
1195 const float delta,
const size_t s,
const size_t scales)
1200 const float alpha = mask[
k /
ch];
1203 const float *
const restrict HF_c = __builtin_assume_aligned(HF +
k, 16);
1204 const float *
const restrict LF_c = __builtin_assume_aligned(LF +
k, 16);
1205 const float *
const restrict TT_c = __builtin_assume_aligned(texture +
k, 16);
1214 const float grey_details = (HF_c[0] + HF_c[1] + HF_c[2]) / 3.f;
1219 const float grey_HF = beta_comp * (gamma_comp * grey_details + gamma * grey_texture);
1223 const float grey_residual = beta_comp * (LF_c[0] + LF_c[1] + LF_c[2]) / 3.f;
1224 __OMP_SIMD__(aligned(reconstructed:64) aligned(HF_c, LF_c, TT_c:16))
1225 for(
size_t c = 0; c < 4; c++)
1232 const float details = (gamma_comp * HF_c[c] + gamma * TT_c[c]) * beta + grey_HF;
1235 const float residual = (s == scales - 1) ? (grey_residual + LF_c[c] * beta) : 0.f;
1236 reconstructed[
k + c] += alpha * (
delta * details + residual);
1243 const float *
const restrict texture,
1244 const float *
const restrict mask,
1245 float *
const restrict reconstructed,
const size_t width,
1246 const size_t height,
const size_t ch,
const float gamma,
1247 const float gamma_comp,
const float beta,
const float beta_comp,
1248 const float delta,
const size_t s,
const size_t scales)
1266 const float alpha = mask[
k /
ch];
1269 const float *
const restrict HF_c = __builtin_assume_aligned(HF +
k, 16);
1270 const float *
const restrict LF_c = __builtin_assume_aligned(LF +
k, 16);
1271 const float *
const restrict TT_c = __builtin_assume_aligned(texture +
k, 16);
1280 const float grey_details = (HF_c[0] + HF_c[1] + HF_c[2]) / 3.f;
1285 const float grey_HF = (gamma_comp * grey_details + gamma * grey_texture);
1287 for(
size_t c = 0; c < 4; c++)
1291 const float details = 0.5f * ((gamma_comp * HF_c[c] + gamma * TT_c[c]) + grey_HF);
1294 const float residual = (s == scales - 1) ? LF_c[c] : 0.f;
1295 reconstructed[
k + c] += alpha * (
delta * details + residual);
1302static inline void init_reconstruct(
const float *
const restrict in,
const float *
const restrict mask,
1303 float *
const restrict reconstructed,
const size_t width,
1312 reconstructed[4*
k + c] = fmaxf(in[4*
k + c] * (1.f - mask[
k]), 0.f);
1319 float *
const restrict HF,
float *
const restrict texture,
1324 for(
size_t c = 0; c < 4; ++c) HF[4*
k + c] = texture[4*
k + c] = detail[4*
k + c] - LF[4*
k + c];
1349 const float *
const restrict in,
const float *
const restrict mask,
1350 float *
const restrict reconstructed,
1358 const int scales =
get_scales(pipe, roi_in, piece);
1394 for(
int s = 0; s < scales; ++s)
1396 const float *restrict detail;
1398 float *restrict HF_RGB_temp;
1405 HF_RGB_temp = LF_even;
1411 HF_RGB_temp = LF_odd;
1417 HF_RGB_temp = LF_even;
1420 const int mult = 1 << s;
1435 gamma, gamma_comp, beta, beta_comp,
delta, s, scales);
1438 gamma, gamma_comp, beta, beta_comp,
delta, s, scales);
1461 const float *
const restrict pix_in = in +
k;
1462 float *
const restrict pix_out =
out +
k;
1466 for(
int c = 0; c < 3; c++)
1471 const float lum = (work_profile)
1472 ? dt_ioppr_get_rgb_matrix_luminance(temp, work_profile->
matrix_in, work_profile->
lut_in,
1473 work_profile->unbounded_coeffs_in,
1481 for(
int c = 0; c < 3; c++)
1484 spline.
M1, spline.
M2, spline.
M3, spline.
M4, spline.
M5,
1486 spline.
y[0], spline.
y[4]),
1502 const float *
const restrict pix_in = in +
k;
1503 float *
const restrict pix_out =
out +
k;
1507 for(
int c = 0; c < 3; c++)
1512 const float lum = (work_profile)
1513 ? dt_ioppr_get_rgb_matrix_luminance(temp, work_profile->
matrix_in, work_profile->
lut_in,
1514 work_profile->unbounded_coeffs_in,
1522 for(
int c = 0; c < 3; c++)
1525 spline.
M1, spline.
M2, spline.
M3, spline.
M4, spline.
M5,
1527 spline.
y[0], spline.
y[4]),
1543 const float *
const restrict pix_in = in +
k;
1544 float *
const restrict pix_out =
out +
k;
1547 float norm = fmaxf(get_pixel_norm(pix_in, variant, work_profile),
NORM_MIN);
1551 ratios[c] = pix_in[c] / norm;
1554 const float min_ratios = fminf(fminf(ratios[0], ratios[1]), ratios[2]);
1555 if(min_ratios < 0.0f)
1566 const float lum = (work_profile) ? dt_ioppr_get_rgb_matrix_luminance(
1567 ratios, work_profile->
matrix_in, work_profile->
lut_in, work_profile->unbounded_coeffs_in,
1572 for(
int c = 0; c < 3; c++) ratios[c] =
linear_saturation(ratios[c], lum, desaturation) / norm;
1576 norm = powf(
CLAMPF(filmic_spline(norm, spline.
M1, spline.
M2, spline.
M3, spline.
M4, spline.
M5,
1578 spline.
y[0], spline.
y[4]),
1598 const float *
const restrict pix_in = in +
k;
1599 float *
const restrict pix_out =
out +
k;
1601 float norm = fmaxf(get_pixel_norm(pix_in, variant, work_profile),
NORM_MIN);
1607 ratios[c] = pix_in[c] / norm;
1610 const float min_ratios = fminf(fminf(ratios[0], ratios[1]), ratios[2]);
1611 const int sanitize = (min_ratios < 0.0f);
1615 ratios[c] -= min_ratios;
1625 norm = powf(
CLAMPF(filmic_spline(norm, spline.
M1, spline.
M2, spline.
M3, spline.
M4, spline.
M5,
1627 spline.
y[0], spline.
y[4]),
1631 for(
int c = 0; c < 3; c++) ratios[c] = fmaxf(ratios[c] + (1.0f - ratios[c]) * (1.0f - desaturation), 0.0f);
1636 norm /= fmaxf(get_pixel_norm(ratios, variant, work_profile),
NORM_MIN);
1639 pix_out[c] = ratios[c] * norm;
1642 const float max_pix = fmaxf(fmaxf(pix_out[0], pix_out[1]), pix_out[2]);
1643 const int penalize = (max_pix > 1.0f);
1650 ratios[c] = fmaxf(ratios[c] + (1.0f - max_pix), 0.0f);
1651 pix_out[c] = ratios[c] * norm;
1658static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
1659pipe_RGB_to_Ych_simd(
const dt_aligned_pixel_simd_t in,
const dt_aligned_pixel_simd_t matrix0,
1660 const dt_aligned_pixel_simd_t matrix1,
const dt_aligned_pixel_simd_t matrix2)
1671 const dt_aligned_pixel_simd_t
Yrg = LMS_to_Yrg_simd(dt_mat3x4_mul_vec4(in, matrix0, matrix1, matrix2));
1672 const float r =
Yrg[1] - 0.21902143f;
1673 const float g =
Yrg[2] - 0.54371398f;
1674 const float c = dt_fast_hypotf(
g,
r);
1675 const float cos_h =
c != 0.f ?
r /
c : 1.f;
1676 const float sin_h =
c != 0.f ?
g /
c : 0.f;
1677 return (dt_aligned_pixel_simd_t){
Yrg[0],
c, cos_h, sin_h };
1681static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
1682Ych_to_pipe_RGB_simd(
const dt_aligned_pixel_simd_t in,
const dt_aligned_pixel_simd_t matrix0,
1683 const dt_aligned_pixel_simd_t matrix1,
const dt_aligned_pixel_simd_t matrix2)
1688 const dt_aligned_pixel_simd_t
Yrg = {
1690 in[1] * in[2] + 0.21902143f,
1691 in[1] * in[3] + 0.54371398f,
1694 return dt_mat3x4_mul_vec4(Yrg_to_LMS_simd(Yrg), matrix0, matrix1, matrix2);
1697static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
1698filmic_desaturate_v4(
const dt_aligned_pixel_simd_t Ych_original, dt_aligned_pixel_simd_t Ych_final,
1699 const float saturation)
1707 const float chroma_original = Ych_original[1] * Ych_original[0];
1708 float chroma_final = Ych_final[1] * Ych_final[0];
1717 const float delta_chroma = saturation * (chroma_original - chroma_final);
1719 const int filmic_brightens = (Ych_final[0] > Ych_original[0]);
1720 const int filmic_resat = (chroma_original < chroma_final);
1721 const int filmic_desat = (chroma_original > chroma_final);
1722 const int user_resat = (saturation > 0.f);
1723 const int user_desat = (saturation < 0.f);
1725 chroma_final = (filmic_brightens && filmic_resat)
1726 ? (chroma_original + chroma_final) / 2.f
1727 : ((user_resat && filmic_desat) || user_desat)
1728 ? chroma_final + delta_chroma
1731 Ych_final[1] = fmaxf(chroma_final / Ych_final[0], 0.f);
1741#define CIE_Y_1931_to_CIE_Y_2006(x) (1.05785528f * (x))
1745clip_chroma_white_raw(
const float coeffs[3],
const float target_white,
const float Y,
1746 const float cos_h,
const float sin_h)
1748 const float denominator_Y_coeff = coeffs[0] * (0.979381443298969f * cos_h + 0.391752577319588f * sin_h)
1749 + coeffs[1] * (0.0206185567010309f * cos_h + 0.608247422680412f * sin_h)
1750 - coeffs[2] * (cos_h + sin_h);
1751 const float denominator_target_term = target_white * (0.68285981628866f * cos_h + 0.482137060515464f * sin_h);
1754 if(denominator_Y_coeff == 0.f)
return FLT_MAX;
1759 const float Y_asymptote = denominator_target_term / denominator_Y_coeff;
1760 if(Y <= Y_asymptote)
return FLT_MAX;
1766 const float denominator = Y * denominator_Y_coeff - denominator_target_term;
1767 const float numerator = -0.427506877216495f
1768 * (Y * (coeffs[0] + 0.856492345150334f * coeffs[1] + 0.554995960637719f * coeffs[2])
1769 - 0.988237752433297f * target_white);
1771 return numerator / denominator;
1776clip_chroma_white(
const float coeffs[3],
const float target_white,
const float Y,
1777 const float cos_h,
const float sin_h)
1783 const float eps = 1e-3f;
1785 const float delta_Y =
MAX(max_Y - Y, 0.f);
1789 max_chroma = delta_Y / (
eps * max_Y) * clip_chroma_white_raw(coeffs, target_white, (1.f -
eps) * max_Y, cos_h, sin_h);
1793 max_chroma = clip_chroma_white_raw(coeffs, target_white, Y, cos_h, sin_h);
1795 return max_chroma >= 0.f ? max_chroma : FLT_MAX;
1800clip_chroma_black(
const float coeffs[3],
const float cos_h,
const float sin_h)
1809 const float denominator = coeffs[0] * (0.979381443298969f * cos_h + 0.391752577319588f * sin_h)
1810 + coeffs[1] * (0.0206185567010309f * cos_h + 0.608247422680412f * sin_h)
1811 - coeffs[2] * (cos_h + sin_h);
1814 if(denominator == 0.f)
return FLT_MAX;
1816 const float numerator = -0.427506877216495f * (coeffs[0] + 0.856492345150334f * coeffs[1] + 0.554995960637719f * coeffs[2]);
1817 const float max_chroma = numerator / denominator;
1818 return max_chroma >= 0.f ? max_chroma : FLT_MAX;
1823clip_chroma(
const dt_colormatrix_t matrix_out,
const float target_white,
const float Y,
1824 const float cos_h,
const float sin_h,
const float chroma)
1832 const float chroma_R_white = clip_chroma_white(matrix_out[0], target_white, Y, cos_h, sin_h);
1833 const float chroma_G_white = clip_chroma_white(matrix_out[1], target_white, Y, cos_h, sin_h);
1834 const float chroma_B_white = clip_chroma_white(matrix_out[2], target_white, Y, cos_h, sin_h);
1835 const float max_chroma_white =
MIN(
MIN(chroma_R_white, chroma_G_white), chroma_B_white);
1837 const float chroma_R_black = clip_chroma_black(matrix_out[0], cos_h, sin_h);
1838 const float chroma_G_black = clip_chroma_black(matrix_out[1], cos_h, sin_h);
1839 const float chroma_B_black = clip_chroma_black(matrix_out[2], cos_h, sin_h);
1840 const float max_chroma_black =
MIN(
MIN(chroma_R_black, chroma_G_black), chroma_B_black);
1842 return MIN(
MIN(chroma, max_chroma_black), max_chroma_white);
1846static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
1847gamut_check_Yrg_filmic_simd(
const dt_aligned_pixel_simd_t Ych)
1851 const dt_aligned_pixel_simd_t
Yrg = {
1853 Ych[1] * Ych[2] + 0.21902143f,
1854 Ych[1] * Ych[3] + 0.54371398f,
1857 float max_c = Ych[1];
1859 if(Yrg[1] < 0.f) max_c = fminf(-0.21902143f / Ych[2], max_c);
1860 if(Yrg[2] < 0.f) max_c = fminf(-0.54371398f / Ych[3], max_c);
1861 if(Yrg[1] + Yrg[2] > 1.f) max_c = fminf((1.f - 0.21902143f - 0.54371398f) / (Ych[2] + Ych[3]), max_c);
1863 return (dt_aligned_pixel_simd_t){ Ych[0], max_c, Ych[2], Ych[3] };
1867static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
1868gamut_check_RGB_simd(
const dt_colormatrix_t matrix_out,
const dt_aligned_pixel_simd_t matrix_in0,
1869 const dt_aligned_pixel_simd_t matrix_in1,
const dt_aligned_pixel_simd_t matrix_in2,
1870 const dt_aligned_pixel_simd_t matrix_out0,
const dt_aligned_pixel_simd_t matrix_out1,
1871 const dt_aligned_pixel_simd_t matrix_out2,
const float display_black,
1872 const float display_white,
const dt_aligned_pixel_simd_t Ych_in)
1876 dt_aligned_pixel_simd_t RGB_brightened = Ych_to_pipe_RGB_simd(Ych_in, matrix_out0, matrix_out1, matrix_out2);
1877 const float min_pix =
MIN(
MIN(RGB_brightened[0], RGB_brightened[1]), RGB_brightened[2]);
1878 const float black_offset =
MAX(-min_pix, 0.f);
1881 const dt_aligned_pixel_simd_t Ych_brightened
1882 = pipe_RGB_to_Ych_simd(RGB_brightened, matrix_in0, matrix_in1, matrix_in2);
1888 const float Y = CLAMP((Ych_in[0] + Ych_brightened[0]) / 2.f,
1891 const float new_chroma = clip_chroma(matrix_out, display_white, Y, Ych_in[2], Ych_in[3], Ych_in[1]);
1894 dt_aligned_pixel_simd_t RGB_out
1895 = Ych_to_pipe_RGB_simd((dt_aligned_pixel_simd_t){
Y, new_chroma, Ych_in[2], Ych_in[3] },
1896 matrix_out0, matrix_out1, matrix_out2);
1904static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
1905gamut_mapping_simd(dt_aligned_pixel_simd_t Ych_final,
const dt_aligned_pixel_simd_t Ych_original,
1906 const dt_colormatrix_t output_matrix,
const dt_aligned_pixel_simd_t input_matrix0,
1907 const dt_aligned_pixel_simd_t input_matrix1,
const dt_aligned_pixel_simd_t input_matrix2,
1908 const dt_aligned_pixel_simd_t output_matrix0,
const dt_aligned_pixel_simd_t output_matrix1,
1909 const dt_aligned_pixel_simd_t output_matrix2,
1910 const dt_colormatrix_t export_output_matrix,
const dt_aligned_pixel_simd_t export_input_matrix0,
1911 const dt_aligned_pixel_simd_t export_input_matrix1,
const dt_aligned_pixel_simd_t export_input_matrix2,
1912 const dt_aligned_pixel_simd_t export_output_matrix0,
const dt_aligned_pixel_simd_t export_output_matrix1,
1913 const dt_aligned_pixel_simd_t export_output_matrix2,
const float display_black,
1914 const float display_white,
const float saturation,
const int use_output_profile)
1917 Ych_final[2] = Ych_original[2];
1918 Ych_final[3] = Ych_original[3];
1924 Ych_final = filmic_desaturate_v4(Ych_original, Ych_final, saturation);
1925 Ych_final = gamut_check_Yrg_filmic_simd(Ych_final);
1927 if(!use_output_profile)
1931 return gamut_check_RGB_simd(output_matrix, input_matrix0, input_matrix1, input_matrix2,
1932 output_matrix0, output_matrix1, output_matrix2,
1933 display_black, display_white, Ych_final);
1938 dt_aligned_pixel_simd_t pix_out
1939 = gamut_check_RGB_simd(export_output_matrix, export_input_matrix0, export_input_matrix1, export_input_matrix2,
1940 export_output_matrix0, export_output_matrix1, export_output_matrix2,
1941 display_black, display_white, Ych_final);
1944 const dt_aligned_pixel_simd_t
LMS
1945 = dt_mat3x4_mul_vec4(pix_out, export_input_matrix0, export_input_matrix1, export_input_matrix2);
1947 return dt_mat3x4_mul_vec4(
LMS, output_matrix0, output_matrix1, output_matrix2);
1968 const int use_output_profile = (!
IS_NULL_PTR(export_profile));
1969 if(use_output_profile)
1980 return use_output_profile;
2017 simd_matrices->
input[
row] = dt_colormatrix_row_to_simd(input_matrix_t,
row);
2018 simd_matrices->
output[
row] = dt_colormatrix_row_to_simd(output_matrix_t,
row);
2019 simd_matrices->
export_input[
row] = dt_colormatrix_row_to_simd(export_input_matrix_t,
row);
2020 simd_matrices->
export_output[
row] = dt_colormatrix_row_to_simd(export_output_matrix_t,
row);
2024static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
2025norm_tone_mapping_v4_simd(
const dt_aligned_pixel_simd_t pix_in,
2030 const float norm_min,
const float norm_max)
2034 float norm =
CLAMPF(get_pixel_norm_simd(pix_in,
type, work_profile), norm_min, norm_max);
2036 const dt_aligned_pixel_simd_t ratios = pix_in /
dt_simd_set1(norm);
2042 norm = powf(
CLAMPF(filmic_spline(norm, spline.
M1, spline.
M2, spline.
M3, spline.
M4, spline.
M5,
2044 spline.
y[0], spline.
y[4]),
2051static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
2057 dt_aligned_pixel_simd_t pix_out = pix_in;
2058 for(
size_t c = 0;
c < 3;
c++)
2061 pix_out[
c] = powf(
CLAMPF(filmic_spline(mapped, spline.
M1, spline.
M2, spline.
M3, spline.
M4, spline.
M5,
2078 const float display_black,
const float display_white)
2086 const int use_output_profile = filmic_v4_prepare_matrices(input_matrix, output_matrix, export_input_matrix,
2087 export_output_matrix, work_profile, export_profile);
2096 const dt_aligned_pixel_simd_t pix_in = dt_load_simd_aligned(in +
k);
2097 const dt_aligned_pixel_simd_t pix_out
2098 = norm_tone_mapping_v4_simd(pix_in, variant, work_profile, data, spline, norm_min, norm_max);
2101 const dt_aligned_pixel_simd_t Ych_original = pipe_RGB_to_Ych_simd(pix_in, simd_matrices.
input[0],
2102 simd_matrices.
input[1], simd_matrices.
input[2]);
2103 const dt_aligned_pixel_simd_t Ych_final = pipe_RGB_to_Ych_simd(pix_out, simd_matrices.
input[0],
2104 simd_matrices.
input[1], simd_matrices.
input[2]);
2106 dt_store_simd_nontemporal(
out +
k,
2107 gamut_mapping_simd(Ych_final, Ych_original, output_matrix,
2108 simd_matrices.
input[0], simd_matrices.
input[1], simd_matrices.
input[2],
2110 export_output_matrix,
2113 display_black, display_white, data->
saturation, use_output_profile));
2126 const float display_black,
const float display_white)
2135 const int use_output_profile = filmic_v4_prepare_matrices(input_matrix, output_matrix, export_input_matrix,
2136 export_output_matrix, work_profile, export_profile);
2142 const dt_aligned_pixel_simd_t pix_in = dt_load_simd_aligned(in +
k);
2143 const dt_aligned_pixel_simd_t pix_out = RGB_tone_mapping_v4_simd(pix_in, data, spline);
2144 const dt_aligned_pixel_simd_t Ych_original = pipe_RGB_to_Ych_simd(pix_in, simd_matrices.
input[0],
2145 simd_matrices.
input[1], simd_matrices.
input[2]);
2146 dt_aligned_pixel_simd_t Ych_final = pipe_RGB_to_Ych_simd(pix_out, simd_matrices.
input[0],
2147 simd_matrices.
input[1], simd_matrices.
input[2]);
2149 Ych_final[1] = fminf(Ych_original[1], Ych_final[1]);
2151 dt_store_simd_nontemporal(
out +
k,
2152 gamut_mapping_simd(Ych_final, Ych_original, output_matrix,
2153 simd_matrices.
input[0], simd_matrices.
input[1], simd_matrices.
input[2],
2155 export_output_matrix,
2158 display_black, display_white, data->
saturation, use_output_profile));
2165static inline void filmic_v5(
const float *
const restrict in,
float *
const restrict
out,
2170 const size_t height,
const size_t ch,
const float display_black,
2171 const float display_white)
2180 const int use_output_profile = filmic_v4_prepare_matrices(input_matrix, output_matrix, export_input_matrix,
2181 export_output_matrix, work_profile, export_profile);
2190 const dt_aligned_pixel_simd_t pix_in = dt_load_simd_aligned(in +
k);
2191 const dt_aligned_pixel_simd_t naive_rgb = RGB_tone_mapping_v4_simd(pix_in, data, spline);
2192 const dt_aligned_pixel_simd_t max_rgb
2199 const dt_aligned_pixel_simd_t Ych_original = pipe_RGB_to_Ych_simd(pix_in, simd_matrices.
input[0],
2200 simd_matrices.
input[1], simd_matrices.
input[2]);
2202 dt_aligned_pixel_simd_t Ych_final = pipe_RGB_to_Ych_simd(pix_out, simd_matrices.
input[0],
2203 simd_matrices.
input[1], simd_matrices.
input[2]);
2205 Ych_final[1] = fminf(Ych_original[1], Ych_final[1]);
2207 dt_store_simd_nontemporal(
out +
k,
2208 gamut_mapping_simd(Ych_final, Ych_original, output_matrix,
2209 simd_matrices.
input[0], simd_matrices.
input[1], simd_matrices.
input[2],
2211 export_output_matrix,
2214 display_black, display_white, 0.f, use_output_profile));
2221static inline void display_mask(
const float *
const restrict mask,
float *
const restrict
out,
2234static inline void compute_ratios(
const float *
const restrict in,
float *
const restrict norms,
2235 float *
const restrict ratios,
2237 const int variant,
const size_t width,
const size_t height)
2242 const dt_aligned_pixel_simd_t pix_in = dt_load_simd_aligned(in +
k);
2243 const float norm = fmaxf(get_pixel_norm_simd(pix_in, variant, work_profile),
NORM_MIN);
2244 norms[
k / 4] = norm;
2245 dt_store_simd_nontemporal(ratios +
k, pix_in /
dt_simd_set1(norm));
2252static inline void restore_ratios(
float *
const restrict ratios,
const float *
const restrict norms,
2258 dt_aligned_pixel_simd_t ratio = dt_load_simd_aligned(ratios + 4 *
k);
2259 const float norm = norms[
k];
2264 dt_store_simd_nontemporal(ratios + 4 *
k, ratio);
2272 const int scales =
get_scales(pipe, roi_in, piece);
2273 const int max_filter_radius = (1 << scales);
2277 tiling->factor_cl = 9.0f;
2280 tiling->maxbuf_cl = 1.0f;
2282 tiling->overlap = max_filter_radius;
2290 const void *
const restrict ivoid,
2291 void *
const restrict
ovoid)
2299 const size_t ch = 4;
2310 float *restrict in = (
float *)ivoid;
2311 float *
const restrict
out = (
float *)
ovoid;
2335 if(recover_highlights &&
IS_NULL_PTR(reconstructed))
2342 if(recover_highlights && mask && reconstructed)
2390 data, piece, roi_in, roi_out))
2415 const float white_display = powf(data->spline.y[4], data->
output_power);
2416 const float black_display = powf(data->spline.y[0], data->
output_power);
2420 filmic_v5(in,
out, work_profile, export_profile, data, data->spline, roi_out->
width,
2421 roi_out->
height,
ch, black_display, white_display);
2459static inline cl_int reconstruct_highlights_cl(
const dt_dev_pixelpipe_t *pipe, cl_mem in, cl_mem mask, cl_mem reconstructed,
2465 const int devid = pipe->
devid;
2468 size_t sizes[] = { ROUNDUPDWD(
width, devid), ROUNDUPDHT(
height, devid), 1 };
2471 const int scales =
get_scales(pipe, roi_in, piece);
2474 cl_mem LF_even = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float) * 4);
2475 cl_mem LF_odd = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float) * 4);
2476 cl_mem HF_RGB = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float) * 4);
2477 cl_mem HF_grey = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float) * 4);
2480 cl_mem temp = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float) * 4);;
2484 err = CL_MEM_OBJECT_ALLOCATION_FAILURE;
2495 if(err != CL_SUCCESS)
goto error;
2513 for(
int s = 0; s < scales; ++s)
2535 const int mult = 1 << s;
2538 const int clamp_lf = 1;
2540 dt_opencl_local_buffer_t hlocopt = (dt_opencl_local_buffer_t){ .xoffset = 2 * mult, .xfactor = 1,
2541 .yoffset = 0, .yfactor = 1,
2542 .cellsize = 4 *
sizeof(float), .overhead = 0,
2543 .sizex = 1 << 16, .sizey = 1 };
2545 hblocksize = hlocopt.sizex;
2551 const size_t horizontal_sizes[3] = { ROUNDUP(
width, hblocksize), ROUNDUPDHT(
height, devid), 1 };
2552 const size_t horizontal_local[3] = { hblocksize, 1, 1 };
2560 (hblocksize + 4 * mult) * 4 *
sizeof(
float), NULL);
2562 horizontal_sizes, horizontal_local);
2574 if(err != CL_SUCCESS)
goto error;
2577 dt_opencl_local_buffer_t vlocopt = (dt_opencl_local_buffer_t){ .xoffset = 0, .xfactor = 1,
2578 .yoffset = 2 * mult, .yfactor = 1,
2579 .cellsize = 4 *
sizeof(float), .overhead = 0,
2580 .sizex = 1, .sizey = 1 << 16 };
2582 vblocksize = vlocopt.sizey;
2588 const size_t vertical_sizes[3] = { ROUNDUPDWD(
width, devid), ROUNDUP(
height, vblocksize), 1 };
2589 const size_t vertical_local[3] = { 1, vblocksize, 1 };
2597 (vblocksize + 4 * mult) * 4 *
sizeof(
float), NULL);
2599 vertical_sizes, vertical_local);
2611 if(err != CL_SUCCESS)
goto error;
2621 if(err != CL_SUCCESS)
goto error;
2624 size_t origin[] = { 0, 0, 0 };
2625 err = dt_opencl_enqueue_copy_image(devid, HF_RGB, HF_grey, origin, origin, sizes);
2626 if(err != CL_SUCCESS)
goto error;
2629 const int blur_size = 1;
2630 const int clamp_hf = 0;
2638 if(err != CL_SUCCESS)
goto error;
2647 if(err != CL_SUCCESS)
goto error;
2667 if(err != CL_SUCCESS)
goto error;
2688 const int devid = pipe->
devid;
2692 size_t sizes[] = { ROUNDUPDWD(
width, devid), ROUNDUPDHT(
height, devid), 1 };
2695 cl_mem inpainted = NULL;
2696 cl_mem reconstructed = NULL;
2698 cl_mem ratios = NULL;
2699 cl_mem norms = NULL;
2704 const int use_work_profile = (
IS_NULL_PTR(work_profile)) ? 0 : 1;
2712 const int use_output_profile = filmic_v4_prepare_matrices(input_matrix, output_matrix, export_input_matrix,
2713 export_output_matrix, work_profile, export_profile);
2718 float input_matrix_3x4[12];
2719 float output_matrix_3x4[12];
2723 cl_mem input_matrix_cl = dt_opencl_copy_host_to_device_constant(devid,
sizeof(input_matrix_3x4), input_matrix_3x4);
2724 cl_mem output_matrix_cl = dt_opencl_copy_host_to_device_constant(devid,
sizeof(output_matrix_3x4), output_matrix_3x4);
2725 cl_mem export_input_matrix_cl = NULL;
2726 cl_mem export_output_matrix_cl = NULL;
2728 cl_mem dev_profile_info = NULL;
2729 cl_mem dev_profile_lut = NULL;
2731 cl_float *profile_lut_cl = NULL;
2733 cl_mem clipped = NULL;
2735 err = dt_ioppr_build_iccprofile_params_cl(work_profile, devid, &profile_info_cl, &profile_lut_cl,
2736 &dev_profile_info, &dev_profile_lut);
2737 if(err != CL_SUCCESS)
goto error;
2739 if(use_output_profile)
2741 float export_input_matrix_3x4[12];
2742 float export_output_matrix_3x4[12];
2745 export_input_matrix_cl = dt_opencl_copy_host_to_device_constant(devid,
sizeof(export_input_matrix_3x4), export_input_matrix_3x4);
2746 export_output_matrix_cl = dt_opencl_copy_host_to_device_constant(devid,
sizeof(export_output_matrix_3x4), export_output_matrix_3x4);
2752 uint32_t is_clipped = 0;
2753 clipped = dt_opencl_alloc_device_buffer(devid,
sizeof(uint32_t));
2754 err = dt_opencl_write_buffer_to_device(devid, &is_clipped, clipped, 0,
sizeof(uint32_t), CL_TRUE);
2755 if(err != CL_SUCCESS)
goto error;
2758 mask = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float));
2767 if(err != CL_SUCCESS)
goto error;
2770 err = dt_opencl_read_buffer_from_device(devid, &is_clipped, clipped, 0,
sizeof(uint32_t), CL_TRUE);
2771 if(err != CL_SUCCESS)
goto error;
2788 dt_ioppr_free_iccprofile_params_cl(&profile_info_cl, &profile_lut_cl, &dev_profile_info, &dev_profile_lut);
2796 const float noise_level =
d->noise_level / scale;
2797 inpainted = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float) * 4);
2807 if(err != CL_SUCCESS)
goto error;
2810 reconstructed = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float) * 4);
2812 if(err != CL_SUCCESS)
goto error;
2816 if(
d->high_quality_reconstruction > 0)
2818 ratios = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float) * 4);
2819 norms = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float));
2823 for(
int i = 0;
i <
d->high_quality_reconstruction;
i++)
2833 if(err != CL_SUCCESS)
goto error;
2837 if(err != CL_SUCCESS)
goto error;
2846 if(err != CL_SUCCESS)
goto error;
2864 const float white_display = powf(spline.
y[4],
d->output_power);
2865 const float black_display = powf(spline.
y[0],
d->output_power);
2904 if(err != CL_SUCCESS)
goto error;
2946 if(err != CL_SUCCESS)
goto error;
2950 dt_ioppr_free_iccprofile_params_cl(&profile_info_cl, &profile_lut_cl, &dev_profile_info, &dev_profile_lut);
2958 dt_ioppr_free_iccprofile_params_cl(&profile_info_cl, &profile_lut_cl, &dev_profile_info, &dev_profile_lut);
2982 const float grey = get_pixel_norm(self->
picked_color,
p->preserve_color, work_profile) / 2.0f;
2984 const float prev_grey =
p->grey_point_source;
2985 p->grey_point_source = CLAMP(100.f * grey, 0.001f, 100.0f);
2986 const float grey_var = log2f(prev_grey /
p->grey_point_source);
2987 p->black_point_source =
p->black_point_source - grey_var;
2988 p->white_point_source =
p->white_point_source + grey_var;
2989 p->output_power = logf(
p->grey_point_target / 100.0f)
2990 / logf(-
p->black_point_source / (
p->white_point_source -
p->black_point_source));
2999 gtk_widget_queue_draw(self->
widget);
3013 float EVmin = CLAMP(log2f(black / (
p->grey_point_source / 100.0f)), -16.0f, -1.0f);
3014 EVmin *= (1.0f +
p->security_factor / 100.0f);
3016 p->black_point_source = fmaxf(EVmin, -16.0f);
3017 p->output_power = logf(
p->grey_point_target / 100.0f)
3018 / logf(-
p->black_point_source / (
p->white_point_source -
p->black_point_source));
3025 gtk_widget_queue_draw(self->
widget);
3040 float EVmax = CLAMP(log2f(white / (
p->grey_point_source / 100.0f)), 1.0f, 16.0f);
3041 EVmax *= (1.0f +
p->security_factor / 100.0f);
3043 p->white_point_source = EVmax;
3044 p->output_power = logf(
p->grey_point_target / 100.0f)
3045 / logf(-
p->black_point_source / (
p->white_point_source -
p->black_point_source));
3052 gtk_widget_queue_draw(self->
widget);
3065 const float grey = get_pixel_norm(self->
picked_color,
p->preserve_color, work_profile) / 2.0f;
3066 p->grey_point_source = CLAMP(100.f * grey, 0.001f, 100.0f);
3071 float EVmax = CLAMP(log2f(white / (
p->grey_point_source / 100.0f)), 1.0f, 16.0f);
3072 EVmax *= (1.0f +
p->security_factor / 100.0f);
3076 float EVmin = CLAMP(log2f(black / (
p->grey_point_source / 100.0f)), -16.0f, -1.0f);
3077 EVmin *= (1.0f +
p->security_factor / 100.0f);
3079 p->black_point_source = fmaxf(EVmin, -16.0f);
3080 p->white_point_source = EVmax;
3081 p->output_power = logf(
p->grey_point_target / 100.0f)
3082 / logf(-
p->black_point_source / (
p->white_point_source -
p->black_point_source));
3091 gtk_widget_queue_draw(self->
widget);
3099 (
void *)picker, (
void *)pipe,
3106 if(picker ==
g->grey_point_source)
3108 else if(picker ==
g->black_point_source)
3110 else if(picker ==
g->white_point_source)
3112 else if(picker ==
g->auto_button)
3120 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->
off),
TRUE);
3127 g->show_mask = !(
g->show_mask);
3132 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
g->show_highlight_mask), !
g->show_mask);
3145 float grey_display = 0.4638f;
3146 gboolean clamping =
FALSE;
3151 grey_display = powf(CLAMP(
p->grey_point_target,
p->black_point_target,
p->white_point_target) / 100.0f,
3152 1.0f / (
p->output_power));
3157 grey_display = powf(0.1845f, 1.0f / (
p->output_power));
3160 const float white_source =
p->white_point_source;
3161 const float black_source =
p->black_point_source;
3162 const float dynamic_range = white_source - black_source;
3165 const float black_log = 0.0f;
3166 const float grey_log = fabsf(
p->black_point_source) / dynamic_range;
3167 const float white_log = 1.0f;
3170 float black_display, white_display;
3178 black_display = CLAMP(
p->black_point_target, 0.0f,
p->grey_point_target) / 100.0f;
3179 white_display = fmaxf(
p->white_point_target,
p->grey_point_target) / 100.0f;
3184 black_display = powf(CLAMP(
p->black_point_target, 0.0f,
p->grey_point_target) / 100.0f,
3185 1.0f / (
p->output_power));
3187 = powf(fmaxf(
p->white_point_target,
p->grey_point_target) / 100.0f, 1.0f / (
p->output_power));
3190 float toe_log, shoulder_log, toe_display, shoulder_display, contrast;
3191 float balance = CLAMP(
p->balance, -50.0f, 50.0f) / 100.0f;
3194 float latitude = CLAMP(
p->latitude, 0.0f, 100.0f) / 100.0f * dynamic_range;
3195 contrast = CLAMP(
p->contrast, 1.00001f, 6.0f);
3199 toe_log = grey_log - latitude / dynamic_range * fabsf(black_source / dynamic_range);
3200 shoulder_log = grey_log + latitude / dynamic_range * fabsf(white_source / dynamic_range);
3203 float linear_intercept = grey_display - (contrast * grey_log);
3206 toe_display = (toe_log * contrast + linear_intercept);
3207 shoulder_display = (shoulder_log * contrast + linear_intercept);
3210 const float norm = sqrtf(contrast * contrast + 1.0f);
3213 const float coeff = -((2.0f * latitude) / dynamic_range) * balance;
3215 toe_display +=
coeff * contrast / norm;
3216 shoulder_display +=
coeff * contrast / norm;
3217 toe_log +=
coeff / norm;
3218 shoulder_log +=
coeff / norm;
3244 spline->
x[0] = black_log;
3245 spline->
x[1] = toe_log;
3246 spline->
x[2] = grey_log;
3247 spline->
x[3] = shoulder_log;
3248 spline->
x[4] = white_log;
3250 spline->
y[0] = black_display;
3251 spline->
y[1] = toe_display;
3252 spline->
y[2] = grey_display;
3253 spline->
y[3] = shoulder_display;
3254 spline->
y[4] = white_display;
3259 spline->
type[0] =
p->shadows;
3260 spline->
type[1] =
p->highlights;
3267 const double Tl = spline->
x[1];
3268 const double Tl2 = Tl * Tl;
3269 const double Tl3 = Tl2 * Tl;
3270 const double Tl4 = Tl3 * Tl;
3272 const double Sl = spline->
x[3];
3273 const double Sl2 = Sl * Sl;
3274 const double Sl3 = Sl2 * Sl;
3275 const double Sl4 = Sl3 * Sl;
3285 spline->
M2[2] = contrast;
3286 spline->
M1[2] = spline->
y[1] - spline->
M2[2] * spline->
x[1];
3287 spline->
M3[2] = 0.f;
3288 spline->
M4[2] = 0.f;
3289 spline->
M5[2] = 0.f;
3297 Tl4, Tl3, Tl2, Tl, 1.,
3298 4. * Tl3, 3. * Tl2, 2. * Tl, 1., 0.,
3299 12. * Tl2, 6. * Tl, 2., 0., 0. };
3301 double b0[
ORDER_4] = { spline->
y[0], 0., spline->
y[1], spline->
M2[2], 0. };
3305 spline->
M5[0] = b0[0];
3306 spline->
M4[0] = b0[1];
3307 spline->
M3[0] = b0[2];
3308 spline->
M2[0] = b0[3];
3309 spline->
M1[0] = b0[4];
3316 3. * Tl2, 2. * Tl, 1., 0.,
3317 6. * Tl, 2., 0., 0. };
3319 double b0[
ORDER_3] = { spline->
y[0], spline->
y[1], spline->
M2[2], 0. };
3323 spline->
M5[0] = 0.0f;
3324 spline->
M4[0] = b0[0];
3325 spline->
M3[0] = b0[1];
3326 spline->
M2[0] = b0[2];
3327 spline->
M1[0] = b0[3];
3331 const float P1[2] = { black_log, black_display };
3332 const float P0[2] = { toe_log, toe_display };
3333 const float x = P0[0] - P1[0];
3334 const float y = P0[1] - P1[1];
3335 const float g = contrast;
3336 const float b =
g / (2.f * y) + (sqrtf(sqf(
x *
g / y + 1.f) - 4.f) - 1.f) / (2.f *
x);
3337 const float c = y /
g * (b * sqf(
x) +
x) / (b * sqf(
x) +
x - (y /
g));
3338 const float a = c *
g;
3342 spline->
M4[0] = toe_display;
3351 3. * Sl2, 2. * Sl, 1., 0.,
3352 6. * Sl, 2., 0., 0. };
3354 double b1[
ORDER_3] = { spline->
y[4], spline->
y[3], spline->
M2[2], 0. };
3358 spline->
M5[1] = 0.0f;
3359 spline->
M4[1] = b1[0];
3360 spline->
M3[1] = b1[1];
3361 spline->
M2[1] = b1[2];
3362 spline->
M1[1] = b1[3];
3369 Sl4, Sl3, Sl2, Sl, 1.,
3370 4. * Sl3, 3. * Sl2, 2. * Sl, 1., 0.,
3371 12. * Sl2, 6. * Sl, 2., 0., 0. };
3373 double b1[
ORDER_4] = { spline->
y[4], 0., spline->
y[3], spline->
M2[2], 0. };
3377 spline->
M5[1] = b1[0];
3378 spline->
M4[1] = b1[1];
3379 spline->
M3[1] = b1[2];
3380 spline->
M2[1] = b1[3];
3381 spline->
M1[1] = b1[4];
3385 const float P1[2] = { white_log, white_display };
3386 const float P0[2] = { shoulder_log, shoulder_display };
3387 const float x = P1[0] - P0[0];
3388 const float y = P1[1] - P0[1];
3389 const float g = contrast;
3390 const float b =
g / (2.f * y) + (sqrtf(sqf(
x *
g / y + 1.f) - 4.f) - 1.f) / (2.f *
x);
3391 const float c = y /
g * (b * sqf(
x) +
x) / (b * sqf(
x) +
x - (y /
g));
3392 const float a = c *
g;
3396 spline->
M4[1] = shoulder_display;
3408 float grey_source = 0.1845f, grey_display = 0.4638f;
3412 grey_source =
p->grey_point_source / 100.0f;
3413 grey_display = powf(
p->grey_point_target / 100.0f, 1.0f / (
p->output_power));
3418 grey_source = 0.1845f;
3419 grey_display = powf(0.1845f, 1.0f / (
p->output_power));
3423 const float white_source =
p->white_point_source;
3424 const float black_source =
p->black_point_source;
3425 const float dynamic_range = white_source - black_source;
3428 const float grey_log = fabsf(
p->black_point_source) / dynamic_range;
3431 float contrast =
p->contrast;
3436 contrast = 1.0001f * grey_display / grey_log;
3440 d->dynamic_range = dynamic_range;
3441 d->black_source = black_source;
3442 d->grey_source = grey_source;
3443 d->output_power =
p->output_power;
3444 d->contrast = contrast;
3445 d->version =
p->version;
3446 d->spline_version =
p->spline_version;
3447 d->preserve_color =
p->preserve_color;
3448 d->high_quality_reconstruction =
p->high_quality_reconstruction;
3449 d->noise_level =
p->noise_level;
3456 d->saturation =
p->saturation / 100.0f;
3458 d->saturation = (2.0f *
p->saturation / 100.0f + 1.0f);
3460 d->sigma_toe = powf(
d->spline.latitude_min / 3.0f, 2.0f);
3461 d->sigma_shoulder = powf((1.0f -
d->spline.latitude_max) / 3.0f, 2.0f);
3463 d->reconstruct_threshold = powf(2.0f, white_source +
p->reconstruct_threshold) * grey_source;
3464 d->reconstruct_feather = exp2f(12.f /
p->reconstruct_feather);
3467 d->normalize =
d->reconstruct_feather /
d->reconstruct_threshold;
3468 d->reconstruct_structure_vs_texture = (
p->reconstruct_structure_vs_texture / 100.0f + 1.f) / 2.f;
3469 d->reconstruct_bloom_vs_details = (
p->reconstruct_bloom_vs_details / 100.0f + 1.f) / 2.f;
3470 d->reconstruct_grey_vs_color = (
p->reconstruct_grey_vs_color / 100.0f + 1.f) / 2.f;
3480 gint mask_was_shown =
g->show_mask;
3482 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
g->show_highlight_mask),
FALSE);
3504 float shoulder = 0.0f;
3521 &
p->latitude, &
p->balance);
3535 g->gui_show_labels =
dt_conf_get_int(
"plugins/darkroom/filmicrgb/graph_show_labels");
3537 g->gui_sizes_inited =
FALSE;
3541 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
g->auto_hardness),
p->auto_hardness);
3542 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
g->custom_grey),
p->custom_grey);
3553 d->white_point_source =
module->so->get_f("white_point_source")->Float.Default;
3554 d->output_power =
module->so->get_f("output_power")->Float.Default;
3565 d->white_point_source = exposure + 2.45f;
3566 d->black_point_source =
d->white_point_source - 12.f;
3567 d->output_power = logf(
d->grey_point_target / 100.0f)
3568 / logf(-
d->black_point_source / (
d->white_point_source -
d->black_point_source));
3570 module->workflow_enabled = TRUE;
3577 const int program = 22;
3592 const int wavelets = 35;
3629 double destination_y, gboolean show_head)
3631 cairo_move_to(cr, origin_x, origin_y);
3632 cairo_line_to(cr, destination_x, destination_y);
3638 const float angle_arrow = 45.f / 360.f *
M_PI;
3639 const float angle_trunk = atan2f((destination_y - origin_y), (destination_x - origin_x));
3642 const float x_1 = destination_x + radius / sinf(angle_arrow + angle_trunk);
3643 const float y_1 = destination_y + radius / cosf(angle_arrow + angle_trunk);
3645 const float x_2 = destination_x - radius / sinf(-angle_arrow + angle_trunk);
3646 const float y_2 = destination_y - radius / cosf(-angle_arrow + angle_trunk);
3648 cairo_move_to(cr, x_1, y_1);
3649 cairo_line_to(cr, destination_x, destination_y);
3650 cairo_line_to(cr, x_2, y_2);
3658 if(!
g->gui_sizes_inited)
return;
3673 cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha);
3678 cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha * 0.5);
3688 const float scale = 0.85;
3689 cairo_scale(cr, scale, scale);
3690 button->
icon(cr, -scale * button->
w / 2., -scale * button->
h / 2., scale * button->
w, scale * button->
h, 0, NULL);
3703 gtk_widget_get_allocation(widget, &
g->allocation);
3705 cairo_surface_t *cst =
3707 PangoFontDescription *desc =
3709 cairo_t *cr = cairo_create(cst);
3710 PangoLayout *layout = pango_cairo_create_layout(cr);
3712 pango_layout_set_font_description(layout, desc);
3713 pango_cairo_context_set_resolution(pango_layout_get_context(layout),
darktable.
gui->
dpi);
3714 g->context = gtk_widget_get_style_context(widget);
3719 const gint font_size = pango_font_description_get_size(desc);
3720 pango_font_description_set_size(desc, 0.95 * font_size);
3721 pango_layout_set_font_description(layout, desc);
3724 g_strlcpy(text,
"X",
sizeof(text));
3725 pango_layout_set_text(layout, text, -1);
3726 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
3727 g->line_height =
g->ink.height;
3730 g_strlcpy(text,
"-",
sizeof(text));
3731 pango_layout_set_text(layout, text, -1);
3732 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
3733 g->sign_width =
g->ink.width / 2.0;
3736 g_strlcpy(text,
"0",
sizeof(text));
3737 pango_layout_set_text(layout, text, -1);
3738 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
3739 g->zero_width =
g->ink.width;
3745 float margin_bottom;
3746 if(
g->gui_show_labels)
3749 margin_left = 3. *
g->zero_width + 2. *
g->inset;
3750 margin_bottom = 2. *
g->line_height + 4. *
g->inset;
3754 margin_left =
g->inset;
3755 margin_bottom =
g->inset;
3758 const float margin_top = 2. *
g->line_height +
g->inset;
3761 g->graph_width =
g->allocation.width - margin_right - margin_left;
3762 g->graph_height =
g->allocation.height - margin_bottom - margin_top;
3764 gtk_render_background(
g->context, cr, 0, 0,
g->allocation.width,
g->allocation.height);
3770 g->buttons[
i].right =
g->allocation.width;
3774 g->buttons[
i].w =
g->buttons[
i].right -
g->buttons[
i].left;
3775 g->buttons[
i].h =
g->buttons[
i].bottom -
g->buttons[
i].top;
3776 g->buttons[
i].state = GTK_STATE_FLAG_NORMAL;
3779 g->gui_sizes_inited =
TRUE;
3789 const float grey =
p->grey_point_source / 100.f;
3790 const float DR =
p->white_point_source -
p->black_point_source;
3793 cairo_translate(cr, margin_left, margin_top);
3795 cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
3798 pango_font_description_set_size(desc, font_size);
3799 pango_layout_set_font_description(layout, desc);
3801 g_strlcpy(text, _(
"look only"),
sizeof(text));
3803 g_strlcpy(text, _(
"look + mapping (lin)"),
sizeof(text));
3805 g_strlcpy(text, _(
"look + mapping (log)"),
sizeof(text));
3807 g_strlcpy(text, _(
"dynamic range mapping"),
sizeof(text));
3809 pango_layout_set_text(layout, text, -1);
3810 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
3814 cairo_rectangle(cr,
g->allocation.width - margin_left -
g->ink.width -
g->ink.x - 2. *
g->inset,
3815 -
g->line_height -
g->inset - 0.5 *
g->ink.height -
g->ink.y -
g->inset,
3816 g->ink.width + 3. *
g->inset,
g->ink.height + 2. *
g->inset);
3821 cairo_move_to(cr,
g->allocation.width - margin_left -
g->ink.width -
g->ink.x -
g->inset,
3822 -
g->line_height -
g->inset - 0.5 *
g->ink.height -
g->ink.y);
3823 pango_cairo_show_layout(cr, layout);
3827 pango_font_description_set_size(desc, 0.95 * font_size);
3828 pango_layout_set_font_description(layout, desc);
3834 cairo_rectangle(cr, 0, 0,
g->graph_width,
g->graph_height);
3836 cairo_fill_preserve(cr);
3846 cairo_scale(cr, 1., -1.);
3847 cairo_translate(cr, 0., -
g->graph_height);
3858 cairo_move_to(cr, 0,
g->graph_height);
3859 cairo_line_to(cr,
g->graph_width, 0);
3865 const float saturation = (2.0f *
p->saturation / 100.0f + 1.0f);
3866 const float sigma_toe = powf(
g->spline.latitude_min / 3.0f, 2.0f);
3867 const float sigma_shoulder = powf((1.0f -
g->spline.latitude_max) / 3.0f, 2.0f);
3869 cairo_set_source_rgb(cr, .5, .5, .5);
3879 cairo_move_to(cr, 0,
3880 g->graph_height * (1.0 - filmic_desaturate_v1(0.0f, sigma_toe, sigma_shoulder, saturation)));
3881 for(
int k = 1;
k < 256;
k++)
3883 float x =
k / 255.0;
3884 const float y = filmic_desaturate_v1(
x, sigma_toe, sigma_shoulder, saturation);
3891 cairo_line_to(cr,
x *
g->graph_width,
g->graph_height * (1.0 - y));
3896 cairo_move_to(cr, 0,
3897 g->graph_height * (1.0 - filmic_desaturate_v2(0.0f, sigma_toe, sigma_shoulder, saturation)));
3898 for(
int k = 1;
k < 256;
k++)
3900 float x =
k / 255.0;
3901 const float y = filmic_desaturate_v2(
x, sigma_toe, sigma_shoulder, saturation);
3908 cairo_line_to(cr,
x *
g->graph_width,
g->graph_height * (1.0 - y));
3914 float x_start = 0.f;
3920 float y_start =
clamp_simd(filmic_spline(x_start,
g->spline.M1,
g->spline.M2,
g->spline.M3,
g->spline.M4,
3921 g->spline.M5,
g->spline.latitude_min,
g->spline.latitude_max,
g->spline.type));
3924 y_start = powf(y_start,
p->output_power);
3928 cairo_move_to(cr, 0,
g->graph_height * (1.0 - y_start));
3930 for(
int k = 1;
k < 256;
k++)
3934 float x = powf(
k / 255.0f, 2.4f);
3942 float y = filmic_spline(
value,
g->spline.M1,
g->spline.M2,
g->spline.M3,
g->spline.M4,
g->spline.M5,
3943 g->spline.latitude_min,
g->spline.latitude_max,
g->spline.type);
3951 const float margin = 1
E-5;
3952 if(y >
g->spline.y[4] + margin)
3955 cairo_set_source_rgb(cr, 0.75, .5, 0.);
3957 else if(y < g->spline.
y[0] - margin)
3960 cairo_set_source_rgb(cr, 0.75, .5, 0.);
3968 y = powf(y,
p->output_power);
3972 cairo_line_to(cr,
x *
g->graph_width,
g->graph_height * (1.0 - y));
3974 cairo_move_to(cr,
x *
g->graph_width,
g->graph_height * (1.0 - y));
3986 float x_grey =
g->spline.x[2];
3987 float y_grey =
g->spline.y[2];
3992 y_grey = powf(y_grey,
p->output_power);
4000 cairo_set_source_rgb(cr, 0.75, 0.5, 0.0);
4001 cairo_arc(cr, x_grey *
g->graph_width, (1.0 - y_grey) *
g->graph_height,
DT_PIXEL_APPLY_DPI(6), 0,
4007 float x_black = 0.f;
4008 float y_black = 0.f;
4010 float x_white = 1.f;
4011 float y_white = 1.f;
4013 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);
4014 const float central_slope_angle = atanf(central_slope) +
M_PI / 2.0f;
4016 for(
int k = 0;
k < 5;
k++)
4020 float x =
g->spline.x[
k];
4021 float y =
g->spline.y[
k];
4022 const float ymin =
g->spline.y[0];
4023 const float ymax =
g->spline.y[4];
4025 const float y_margin =
SAFETY_MARGIN * 1.1f * (ymax - ymin);
4026 gboolean red = (((
k == 1) && (y - ymin <= y_margin))
4027 || ((
k == 3) && (ymax - y <= y_margin)));
4028 float start_angle = 0.0f;
4029 float end_angle = 2.f *
M_PI;
4032 if(contrast_clamped)
4036 start_angle = central_slope_angle +
M_PI;
4037 end_angle = central_slope_angle;
4041 start_angle = central_slope_angle;
4042 end_angle = start_angle +
M_PI;
4049 y = powf(y,
p->output_power);
4069 if(red) cairo_set_source_rgb(cr, 0.8, 0.35, 0.35);
4072 cairo_arc(cr,
x *
g->graph_width, (1.0 - y) *
g->graph_height,
DT_PIXEL_APPLY_DPI(4), start_angle, end_angle);
4082 if(
g->gui_show_labels)
4085 const float x_legend_top =
g->graph_height + 0.5 *
g->line_height;
4089 snprintf(text,
sizeof(text),
"%.0f",
p->grey_point_target);
4090 pango_layout_set_text(layout, text, -1);
4091 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4092 cairo_move_to(cr, -2. *
g->inset -
g->ink.width -
g->ink.x,
4093 (1.0 - y_grey) *
g->graph_height - 0.5 *
g->ink.height -
g->ink.y);
4094 pango_cairo_show_layout(cr, layout);
4100 snprintf(text,
sizeof(text),
"%+.1f", 0.f);
4102 snprintf(text,
sizeof(text),
"%.0f",
p->grey_point_source);
4104 pango_layout_set_text(layout, text, -1);
4105 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4106 cairo_move_to(cr, x_grey *
g->graph_width - 0.5 *
g->ink.width -
g->ink.x, x_legend_top);
4107 pango_cairo_show_layout(cr, layout);
4112 snprintf(text,
sizeof(text),
"%.0f",
p->black_point_target);
4113 pango_layout_set_text(layout, text, -1);
4114 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4115 cairo_move_to(cr, -2. *
g->inset -
g->ink.width -
g->ink.x,
4116 (1.0 - y_black) *
g->graph_height - 0.5 *
g->ink.height -
g->ink.y);
4117 pango_cairo_show_layout(cr, layout);
4122 snprintf(text,
sizeof(text),
"%.0f",
p->white_point_target);
4123 pango_layout_set_text(layout, text, -1);
4124 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4125 cairo_move_to(cr, -2. *
g->inset -
g->ink.width -
g->ink.x,
4126 (1.0 - y_white) *
g->graph_height - 0.5 *
g->ink.height -
g->ink.y);
4127 pango_cairo_show_layout(cr, layout);
4133 snprintf(text,
sizeof(text),
"%+.1f",
p->black_point_source);
4135 snprintf(text,
sizeof(text),
"%.0f", exp2f(
p->black_point_source) *
p->grey_point_source);
4137 pango_layout_set_text(layout, text, -1);
4138 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4139 cairo_move_to(cr, x_black *
g->graph_width - 0.5 *
g->ink.width -
g->ink.x, x_legend_top);
4140 pango_cairo_show_layout(cr, layout);
4146 snprintf(text,
sizeof(text),
"%+.1f",
p->white_point_source);
4150 snprintf(text,
sizeof(text),
"%.0f \342\206\222", 100.f);
4152 snprintf(text,
sizeof(text),
"%.0f", exp2f(
p->white_point_source) *
p->grey_point_source);
4155 pango_layout_set_text(layout, text, -1);
4156 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4158 fminf(x_white, 1.f) *
g->graph_width - 0.5 *
g->ink.width -
g->ink.x
4159 + 2. * (x_white > 1.f) *
g->sign_width,
4161 pango_cairo_show_layout(cr, layout);
4170 PangoStyle backup = pango_font_description_get_style(desc);
4171 pango_font_description_set_style(desc, PANGO_STYLE_ITALIC);
4172 pango_layout_set_font_description(layout, desc);
4174 snprintf(text,
sizeof(text), _(
"(%.0f %%)"), exp2f(
p->white_point_source) *
p->grey_point_source);
4175 pango_layout_set_text(layout, text, -1);
4176 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4177 cairo_move_to(cr,
g->allocation.width -
g->ink.width -
g->ink.x - margin_left,
4178 g->graph_height + 3. *
g->inset +
g->line_height -
g->ink.y);
4179 pango_cairo_show_layout(cr, layout);
4183 pango_font_description_set_style(desc, backup);
4184 pango_layout_set_font_description(layout, desc);
4190 g_strlcpy(text, _(
"% display"),
sizeof(text));
4191 pango_layout_set_text(layout, text, -1);
4192 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4193 cairo_move_to(cr, -2. *
g->inset -
g->zero_width -
g->ink.x,
4194 -
g->line_height -
g->inset - 0.5 *
g->ink.height -
g->ink.y);
4195 pango_cairo_show_layout(cr, layout);
4202 g_strlcpy(text, _(
"EV scene"),
sizeof(text));
4206 g_strlcpy(text, _(
"% camera"),
sizeof(text));
4208 pango_layout_set_text(layout, text, -1);
4209 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4210 cairo_move_to(cr, 0.5 *
g->graph_width - 0.5 *
g->ink.width -
g->ink.x,
4211 g->graph_height + 3. *
g->inset +
g->line_height -
g->ink.y);
4212 pango_cairo_show_layout(cr, layout);
4219 cairo_identity_matrix(cr);
4225 const float display_DR = 12.f + log2f(
p->white_point_target / 100.f);
4227 const float y_display =
g->allocation.height / 3.f +
g->line_height;
4228 const float y_scene = 2. *
g->allocation.height / 3.f +
g->line_height;
4230 const float display_top = y_display -
g->line_height / 2;
4231 const float display_bottom = display_top +
g->line_height;
4233 const float scene_top = y_scene -
g->line_height / 2;
4234 const float scene_bottom = scene_top +
g->line_height;
4238 if(
g->gui_show_labels)
4242 g_strlcpy(text, _(
"display"),
sizeof(text));
4243 pango_layout_set_text(layout, text, -1);
4244 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4245 cairo_move_to(cr, 0., y_display - 0.5 *
g->ink.height -
g->ink.y);
4246 pango_cairo_show_layout(cr, layout);
4248 const float display_label_width =
g->ink.width;
4251 g_strlcpy(text, _(
"(%)"),
sizeof(text));
4252 pango_layout_set_text(layout, text, -1);
4253 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4254 cairo_move_to(cr, 0.5 * display_label_width - 0.5 *
g->ink.width -
g->ink.x,
4255 display_top - 4. *
g->inset -
g->ink.height -
g->ink.y);
4256 pango_cairo_show_layout(cr, layout);
4260 g_strlcpy(text, _(
"scene"),
sizeof(text));
4261 pango_layout_set_text(layout, text, -1);
4262 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4263 cairo_move_to(cr, 0., y_scene - 0.5 *
g->ink.height -
g->ink.y);
4264 pango_cairo_show_layout(cr, layout);
4266 const float scene_label_width =
g->ink.width;
4269 g_strlcpy(text, _(
"(EV)"),
sizeof(text));
4270 pango_layout_set_text(layout, text, -1);
4271 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4272 cairo_move_to(cr, 0.5 * scene_label_width - 0.5 *
g->ink.width -
g->ink.x,
4273 scene_bottom + 2. *
g->inset + 0. *
g->ink.height +
g->ink.y);
4274 pango_cairo_show_layout(cr, layout);
4279 dt_cairo_draw_arrow(cr, fminf(scene_label_width, display_label_width) / 2.f, y_scene -
g->line_height,
4280 fminf(scene_label_width, display_label_width) / 2.f,
4281 y_display +
g->line_height +
g->inset,
TRUE);
4283 column_left = fmaxf(display_label_width, scene_label_width) +
g->inset;
4291 const float display_HL_EV = -log2f(
p->grey_point_target /
p->white_point_target);
4292 const float display_LL_EV = display_DR - display_HL_EV;
4293 const float display_real_black_EV
4294 = -fmaxf(log2f(
p->black_point_target /
p->grey_point_target),
4295 -11.685887601778058f + display_HL_EV - log2f(
p->white_point_target / 100.f));
4296 const float scene_HL_EV =
p->white_point_source;
4297 const float scene_LL_EV = -
p->black_point_source;
4300 const float max_DR = ceilf(fmaxf(display_HL_EV, scene_HL_EV)) + ceilf(fmaxf(display_LL_EV, scene_LL_EV));
4301 const float EV = (column_right) / max_DR;
4305 const float grey_EV = fmaxf(ceilf(display_HL_EV), ceilf(scene_HL_EV));
4309 const float display_black_x = grey_x - display_real_black_EV * EV;
4310 const float display_DR_start_x = grey_x - display_LL_EV * EV;
4311 const float display_white_x = grey_x + display_HL_EV * EV;
4313 const float scene_black_x = grey_x - scene_LL_EV * EV;
4314 const float scene_white_x = grey_x + scene_HL_EV * EV;
4315 const float scene_lat_bottom = grey_x + (
g->spline.x[1] -
g->spline.x[2]) * EV * DR;
4316 const float scene_lat_top = grey_x + (
g->spline.x[3] -
g->spline.x[2]) * EV * DR;
4324 float display_lat_bottom = filmic_spline(
g->spline.latitude_min,
g->spline.M1,
g->spline.M2,
g->spline.M3,
g->spline.M4,
4325 g->spline.M5,
g->spline.latitude_min,
g->spline.latitude_max,
g->spline.type);
4326 display_lat_bottom = powf(fmaxf(display_lat_bottom,
NORM_MIN),
p->output_power);
4329 display_lat_bottom = log2f(display_lat_bottom/ (
p->grey_point_target / 100.f));
4332 if(display_lat_bottom < 0.f)
4333 display_lat_bottom = fmaxf(display_lat_bottom, -display_real_black_EV);
4334 else if(display_lat_bottom > 0.f)
4335 display_lat_bottom = fminf(display_lat_bottom, display_HL_EV);
4338 display_lat_bottom = grey_x + display_lat_bottom * EV;
4341 float display_lat_top = filmic_spline(
g->spline.latitude_max,
g->spline.M1,
g->spline.M2,
g->spline.M3,
g->spline.M4,
4342 g->spline.M5,
g->spline.latitude_min,
g->spline.latitude_max,
g->spline.type);
4343 display_lat_top = powf(fmaxf(display_lat_top,
NORM_MIN),
p->output_power);
4346 display_lat_top = log2f(display_lat_top / (
p->grey_point_target / 100.f));
4349 if(display_lat_top < 0.f)
4350 display_lat_top = fmaxf(display_lat_top, -display_real_black_EV);
4351 else if(display_lat_top > 0.f)
4352 display_lat_top = fminf(display_lat_top, display_HL_EV);
4355 display_lat_top = grey_x + display_lat_top * EV;
4357 cairo_move_to(cr, scene_lat_bottom, scene_top);
4358 cairo_line_to(cr, scene_lat_top, scene_top);
4359 cairo_line_to(cr, display_lat_top, display_bottom);
4360 cairo_line_to(cr, display_lat_bottom, display_bottom);
4361 cairo_line_to(cr, scene_lat_bottom, scene_top);
4365 for(
int i = 0;
i < (int)ceilf(display_DR);
i++)
4368 const float shade = powf(exp2f(-11.f + (
float)
i), 1.f / 2.4f);
4369 cairo_set_source_rgb(cr, shade, shade, shade);
4370 cairo_rectangle(cr, display_DR_start_x +
i * EV, display_top, EV,
g->line_height);
4371 cairo_fill_preserve(cr);
4374 cairo_set_source_rgb(cr, 0.75, .5, 0.);
4380 cairo_move_to(cr, grey_x, display_bottom + 2. *
g->inset);
4381 cairo_line_to(cr, grey_x, display_top - 2. *
g->inset);
4386 for(
int i = floorf(
p->black_point_source);
i < ceilf(
p->white_point_source);
i++)
4390 const float shade = powf(0.1845f * exp2f((
float)
i), 1.f / 2.4f);
4391 const float x_temp = grey_x +
i * EV;
4392 cairo_set_source_rgb(cr, shade, shade, shade);
4393 cairo_rectangle(cr, x_temp, scene_top, EV,
g->line_height);
4394 cairo_fill_preserve(cr);
4397 cairo_set_source_rgb(cr, 0.75, .5, 0.);
4406 if((
float)
i >
p->black_point_source && (
float)i < p->white_point_source)
4409 const float normal_value = ((float)
i -
p->black_point_source) / DR;
4410 float y_temp = filmic_spline(normal_value,
g->spline.M1,
g->spline.M2,
g->spline.M3,
g->spline.M4,
4411 g->spline.M5,
g->spline.latitude_min,
g->spline.latitude_max,
g->spline.type);
4412 y_temp = powf(fmaxf(y_temp,
NORM_MIN),
p->output_power);
4415 y_temp = log2f(y_temp / (
p->grey_point_target / 100.f));
4419 y_temp = fmaxf(y_temp, -display_real_black_EV);
4420 else if(y_temp > 0.f)
4421 y_temp = fminf(y_temp, display_HL_EV);
4424 y_temp = grey_x + y_temp * EV;
4432 float x_temp = grey_x +
p->black_point_source * EV;
4433 float y_temp = grey_x - display_real_black_EV * EV;
4436 x_temp = grey_x +
p->white_point_source * EV;
4437 y_temp = grey_x + display_HL_EV * EV;
4443 cairo_move_to(cr, display_black_x, display_bottom);
4444 cairo_line_to(cr, display_black_x, display_top - 2. *
g->inset);
4448 cairo_move_to(cr, grey_x, display_bottom);
4449 cairo_line_to(cr, grey_x, display_top - 2. *
g->inset);
4453 cairo_move_to(cr, display_white_x, display_bottom);
4454 cairo_line_to(cr, display_white_x, display_top - 2. *
g->inset);
4458 cairo_move_to(cr, scene_black_x, scene_bottom + 2. *
g->inset);
4459 cairo_line_to(cr, scene_black_x, scene_top);
4463 cairo_move_to(cr, grey_x, scene_bottom + 2. *
g->inset);
4464 cairo_line_to(cr, grey_x, scene_top);
4468 cairo_move_to(cr, scene_white_x, scene_bottom + 2. *
g->inset);
4469 cairo_line_to(cr, scene_white_x, scene_top);
4476 snprintf(text,
sizeof(text),
"%+.1f",
p->black_point_source);
4477 pango_layout_set_text(layout, text, -1);
4478 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4479 cairo_move_to(cr, scene_black_x - 0.5 *
g->ink.width -
g->ink.x,
4480 scene_bottom + 2. *
g->inset + 0. *
g->ink.height +
g->ink.y);
4481 pango_cairo_show_layout(cr, layout);
4485 snprintf(text,
sizeof(text),
"%+.1f", 0.f);
4486 pango_layout_set_text(layout, text, -1);
4487 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4488 cairo_move_to(cr, grey_x - 0.5 *
g->ink.width -
g->ink.x,
4489 scene_bottom + 2. *
g->inset + 0. *
g->ink.height +
g->ink.y);
4490 pango_cairo_show_layout(cr, layout);
4494 snprintf(text,
sizeof(text),
"%+.1f",
p->white_point_source);
4495 pango_layout_set_text(layout, text, -1);
4496 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4497 cairo_move_to(cr, scene_white_x - 0.5 *
g->ink.width -
g->ink.x,
4498 scene_bottom + 2. *
g->inset + 0. *
g->ink.height +
g->ink.y);
4499 pango_cairo_show_layout(cr, layout);
4503 snprintf(text,
sizeof(text),
"%.0f",
p->black_point_target);
4504 pango_layout_set_text(layout, text, -1);
4505 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4506 cairo_move_to(cr, display_black_x - 0.5 *
g->ink.width -
g->ink.x,
4507 display_top - 4. *
g->inset -
g->ink.height -
g->ink.y);
4508 pango_cairo_show_layout(cr, layout);
4512 snprintf(text,
sizeof(text),
"%.0f",
p->grey_point_target);
4513 pango_layout_set_text(layout, text, -1);
4514 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4515 cairo_move_to(cr, grey_x - 0.5 *
g->ink.width -
g->ink.x,
4516 display_top - 4. *
g->inset -
g->ink.height -
g->ink.y);
4517 pango_cairo_show_layout(cr, layout);
4521 snprintf(text,
sizeof(text),
"%.0f",
p->white_point_target);
4522 pango_layout_set_text(layout, text, -1);
4523 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4524 cairo_move_to(cr, display_white_x - 0.5 *
g->ink.width -
g->ink.x,
4525 display_top - 4. *
g->inset -
g->ink.height -
g->ink.y);
4526 pango_cairo_show_layout(cr, layout);
4531 pango_font_description_set_size(desc, font_size);
4532 pango_layout_set_font_description(layout, desc);
4535 cairo_set_source_surface(crf, cst, 0, 0);
4537 cairo_surface_destroy(cst);
4538 g_object_unref(layout);
4539 pango_font_description_free(desc);
4555 if(event->button == 1 && event->type == GDK_2BUTTON_PRESS)
4561 gtk_widget_queue_draw(GTK_WIDGET(
g->area));
4570 else if(event->button == 1)
4581 gtk_widget_queue_draw(GTK_WIDGET(
g->area));
4587 g->gui_show_labels = !
g->gui_show_labels;
4588 gtk_widget_queue_draw(GTK_WIDGET(
g->area));
4589 dt_conf_set_int(
"plugins/darkroom/filmicrgb/graph_show_labels",
g->gui_show_labels);
4599 else if(event->button == 3)
4609 gtk_widget_queue_draw(GTK_WIDGET(
g->area));
4615 g->gui_show_labels = !
g->gui_show_labels;
4616 gtk_widget_queue_draw(GTK_WIDGET(
g->area));
4617 dt_conf_set_int(
"plugins/darkroom/filmicrgb/graph_show_labels",
g->gui_show_labels);
4637 g->gui_hover =
TRUE;
4638 gtk_widget_queue_draw(GTK_WIDGET(
g->area));
4651 gtk_widget_queue_draw(GTK_WIDGET(
g->area));
4661 if(!
g->gui_sizes_inited)
return FALSE;
4664 const float y =
event->y;
4665 const float x =
event->x;
4667 if(
x > 0. && x < g->allocation.width && y > 0. && y < g->allocation.height)
g->gui_hover =
TRUE;
4669 gint save_active_button =
g->active_button;
4674 gint found_something =
FALSE;
4678 if(
x >
g->buttons[
i].left && x < g->buttons[
i].right && y >
g->buttons[
i].top && y < g->buttons[
i].bottom)
4681 g->buttons[
i].mouse_hover =
TRUE;
4682 g->active_button =
i;
4683 found_something =
TRUE;
4688 g->buttons[
i].mouse_hover =
FALSE;
4698 gtk_widget_set_tooltip_text(GTK_WIDGET(
g->area), _(
"use the parameters below to set the nodes.\n"
4699 "the bright curve is the filmic tone mapping curve\n"
4700 "the dark curve is the desaturation curve."));
4704 gtk_widget_set_tooltip_text(GTK_WIDGET(
g->area), _(
"toggle axis labels and values display"));
4708 gtk_widget_set_tooltip_text(GTK_WIDGET(
g->area), _(
"cycle through graph views.\n"
4709 "left click: cycle forward.\n"
4710 "right click: cycle backward.\n"
4711 "double-click: reset to look view."));
4715 gtk_widget_set_tooltip_text(GTK_WIDGET(
g->area),
"");
4718 if(save_active_button !=
g->active_button) gtk_widget_queue_draw(GTK_WIDGET(
g->area));
4724 if(save_active_button !=
g->active_button) (GTK_WIDGET(
g->area));
4737 const int aspect =
dt_conf_get_int(
"plugins/darkroom/filmicrgb/aspect_percent");
4738 dt_conf_set_int(
"plugins/darkroom/filmicrgb/aspect_percent", aspect + delta_y);
4752 g->gui_show_labels =
TRUE;
4754 g->gui_sizes_inited =
FALSE;
4757 const float aspect =
dt_conf_get_int(
"plugins/darkroom/filmicrgb/aspect_percent") / 100.0;
4759 g_object_set_data(G_OBJECT(
g->area),
"iop-instance", self);
4761 gtk_widget_set_can_focus(GTK_WIDGET(
g->area),
TRUE);
4762 gtk_widget_add_events(GTK_WIDGET(
g->area), GDK_BUTTON_PRESS_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK
4765 g_signal_connect(G_OBJECT(
g->area),
"button-press-event", G_CALLBACK(
area_button_press), self);
4766 g_signal_connect(G_OBJECT(
g->area),
"leave-notify-event", G_CALLBACK(
area_leave_notify), self);
4767 g_signal_connect(G_OBJECT(
g->area),
"enter-notify-event", G_CALLBACK(
area_enter_notify), self);
4768 g_signal_connect(G_OBJECT(
g->area),
"motion-notify-event", G_CALLBACK(
area_motion_notify), self);
4777 g->grey_point_source
4781 gtk_widget_set_tooltip_text(
g->grey_point_source,
4782 _(
"adjust to match the average luminance of the image's subject.\n"
4783 "the value entered here will then be remapped to 18.45%.\n"
4784 "decrease the value to increase the overall brightness."));
4787 g->white_point_source
4791 gtk_widget_set_tooltip_text(
g->white_point_source,
4792 _(
"number of stops between middle gray and pure white.\n"
4793 "this is a reading a lightmeter would give you on the scene.\n"
4794 "adjust so highlights clipping is avoided"));
4797 g->black_point_source
4801 gtk_widget_set_tooltip_text(
4802 g->black_point_source, _(
"number of stops between middle gray and pure black.\n"
4803 "this is a reading a lightmeter would give you on the scene.\n"
4804 "increase to get more contrast.\ndecrease to recover more details in low-lights."));
4810 gtk_widget_set_tooltip_text(
g->security_factor, _(
"symmetrically enlarge or shrink the computed dynamic range.\n"
4811 "useful to give a safety margin to extreme luminances."));
4814 GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
4817 gtk_box_pack_start(GTK_BOX(hbox),
g->auto_button,
FALSE,
FALSE, 0);
4819 gtk_widget_set_tooltip_text(
g->auto_button, _(
"try to optimize the settings with some statistical assumptions.\n"
4820 "this will fit the luminance range inside the histogram bounds.\n"
4821 "works better for landscapes and evenly-lit pictures\n"
4822 "but fails for high-keys, low-keys and high-ISO pictures.\n"
4823 "this is not an artificial intelligence, but a simple guess.\n"
4824 "ensure you understand its assumptions before using it."));
4831 gtk_widget_set_tooltip_text(
g->custom_grey, _(
"enable to input custom middle-gray values.\n"
4832 "this is not recommended in general.\n"
4833 "fix the global exposure in the exposure module instead.\n"
4834 "disable to use standard 18.45 %% middle gray."));
4844 gtk_widget_set_tooltip_text(
g->reconstruct_threshold,
4845 _(
"set the exposure threshold upon which\n"
4846 "clipped highlights get reconstructed.\n"
4847 "values are relative to the scene white point.\n"
4848 "0 EV means the threshold is the same as the scene white point.\n"
4849 "decrease to include more areas,\n"
4850 "increase to exclude more areas."));
4854 gtk_widget_set_tooltip_text(
g->reconstruct_feather,
4855 _(
"soften the transition between clipped highlights and valid pixels.\n"
4856 "decrease to make the transition harder and sharper,\n"
4857 "increase to make the transition softer and blurrier."));
4860 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
4861 gtk_box_pack_start(GTK_BOX(hbox),
dt_ui_label_new(_(
"display highlight reconstruction mask")),
TRUE,
TRUE, 0);
4874 gtk_widget_set_tooltip_text(
g->reconstruct_structure_vs_texture,
4876 _(
"decide which reconstruction strategy to favor,\n"
4877 "between inpainting a smooth color gradient,\n"
4878 "or trying to recover the textured details.\n"
4879 "0% is an equal mix of both.\n"
4880 "increase if at least one RGB channel is not clipped.\n"
4881 "decrease if all RGB channels are clipped over large areas."));
4885 gtk_widget_set_tooltip_text(
g->reconstruct_bloom_vs_details,
4887 _(
"decide which reconstruction strategy to favor,\n"
4888 "between blooming highlights like film does,\n"
4889 "or trying to recover sharp details.\n"
4890 "0% is an equal mix of both.\n"
4891 "increase if you want more details.\n"
4892 "decrease if you want more blur."));
4897 gtk_widget_set_tooltip_text(
g->reconstruct_grey_vs_color,
4899 _(
"decide which reconstruction strategy to favor,\n"
4900 "between recovering monochromatic highlights,\n"
4901 "or trying to recover colorful highlights.\n"
4902 "0% is an equal mix of both.\n"
4903 "increase if you want more color.\n"
4904 "decrease if you see magenta or out-of-gamut highlights."));
4911 gtk_widget_set_tooltip_text(
g->high_quality_reconstruction,
4912 _(
"run extra passes of chromaticity reconstruction.\n"
4913 "more iterations means more color propagation from neighbourhood.\n"
4914 "this will be slower but will yield more neutral highlights.\n"
4915 "it also helps with difficult cases of magenta highlights."));
4919 gtk_widget_set_tooltip_text(
g->noise_level, _(
"add statistical noise in reconstructed highlights.\n"
4920 "this avoids highlights to look too smooth\n"
4921 "when the picture is noisy overall,\n"
4922 "so they blend with the rest of the picture."));
4926 gtk_widget_set_tooltip_text(
g->noise_distribution, _(
"choose the statistical distribution of noise.\n"
4927 "this is useful to match natural sensor noise pattern.\n"));
4938 gtk_widget_set_tooltip_text(
g->contrast, _(
"slope of the linear part of the curve\n"
4939 "affects mostly the mid-tones"));
4943 gtk_widget_set_tooltip_text(
g->output_power, _(
"equivalent to paper grade in analog.\n"
4944 "increase to make highlights brighter and less compressed.\n"
4945 "decrease to mute highlights."));
4952 gtk_widget_set_tooltip_text(
g->toe,
4953 _(
"distance between middle gray and the start of the shadows roll-off.\n"
4954 "0% keeps the toe at middle gray, 100% pushes it to the point where the\n"
4955 "current slope would hit the output black level."));
4963 gtk_widget_set_tooltip_text(
g->shoulder,
4964 _(
"distance between middle gray and the start of the highlights roll-off.\n"
4965 "0% keeps the shoulder at middle gray, 100% pushes it to the point where the\n"
4966 "current slope would hit the output white level."));
4971 gtk_widget_set_tooltip_text(
g->highlights, _(
"choose the desired curvature of the filmic spline in highlights.\n"
4972 "hard uses a high curvature resulting in more tonal compression.\n"
4973 "soft uses a low curvature resulting in less tonal compression."));
4976 gtk_widget_set_tooltip_text(
g->shadows, _(
"choose the desired curvature of the filmic spline in shadows.\n"
4977 "hard uses a high curvature resulting in more tonal compression.\n"
4978 "soft uses a low curvature resulting in less tonal compression."));
4986 gtk_widget_set_tooltip_text(
g->saturation, _(
"desaturates the output of the module\n"
4987 "specifically at extreme luminances.\n"
4988 "increase if shadows and/or highlights are under-saturated."));
4991 gtk_widget_set_tooltip_text(
g->preserve_color, _(
"ensure the original color are preserved.\n"
4992 "may reinforce chromatic aberrations and chroma noise,\n"
4993 "so ensure they are properly corrected elsewhere.\n"));
5000 gtk_widget_set_tooltip_text(
g->version,
5001 _(
"v3 is darktable 3.0 desaturation method, same as color balance.\n"
5002 "v4 is a newer desaturation method, based on spectral purity of light."));
5006 gtk_widget_set_tooltip_text(
5007 g->auto_hardness, _(
"enable to auto-set the look hardness depending on the scene white and black points.\n"
5008 "this keeps the middle gray on the identity line and improves fast tuning.\n"
5009 "disable if you want a manual control."));
5018 gtk_widget_set_tooltip_text(
g->black_point_target, _(
"luminance of output pure black, "
5019 "this should be 0%\nexcept if you want a faded look"));
5024 gtk_widget_set_tooltip_text(
g->grey_point_target,
5025 _(
"middle gray value of the target display or color space.\n"
5026 "you should never touch that unless you know what you are doing."));
5032 gtk_widget_set_tooltip_text(
g->white_point_target, _(
"luminance of output pure white, "
5033 "this should be 100%\nexcept if you want a faded look"));
5038 gtk_box_pack_start(GTK_BOX(self->
widget), GTK_WIDGET(
g->area),
TRUE,
TRUE, 0);
5039 gtk_box_pack_start(GTK_BOX(self->
widget), GTK_WIDGET(
g->notebook),
FALSE,
FALSE, 0);
5047 if(
IS_NULL_PTR(w) || w ==
g->auto_hardness || w ==
g->security_factor || w ==
g->grey_point_source
5048 || w ==
g->black_point_source || w ==
g->white_point_source)
5052 if(w ==
g->security_factor || w ==
g->grey_point_source)
5054 float prev = *(
float *)previous;
5055 if(w ==
g->security_factor)
5057 float ratio = (
p->security_factor - prev) / (prev + 100.0f);
5059 float EVmin =
p->black_point_source;
5060 EVmin = EVmin + ratio * EVmin;
5062 float EVmax =
p->white_point_source;
5063 EVmax = EVmax + ratio * EVmax;
5065 p->white_point_source = EVmax;
5066 p->black_point_source = EVmin;
5070 float grey_var = log2f(prev /
p->grey_point_source);
5071 p->black_point_source =
p->black_point_source - grey_var;
5072 p->white_point_source =
p->white_point_source + grey_var;
5079 if(
p->auto_hardness)
5080 p->output_power = logf(
p->grey_point_target / 100.0f)
5081 / logf(-
p->black_point_source / (
p->white_point_source -
p->black_point_source));
5083 gtk_widget_set_visible(GTK_WIDGET(
g->output_power), !
p->auto_hardness);
5094 gtk_widget_set_tooltip_text(
g->saturation, _(
"desaturates the output of the module\n"
5095 "specifically at extreme luminances.\n"
5096 "increase if shadows and/or highlights are under-saturated."));
5101 gtk_widget_set_tooltip_text(
g->saturation, _(
"desaturates the output of the module\n"
5102 "specifically at medium luminances.\n"
5103 "increase if midtones are under-saturated."));
5108 gtk_widget_set_tooltip_text(
g->saturation, _(
"Positive values ensure saturation is kept unchanged over the whole range.\n"
5109 "Negative values bleache highlights at constant hue and luminance.\n"
5110 "Zero is an equal mix of both strategies."));
5111 gtk_widget_set_visible(GTK_WIDGET(
g->preserve_color),
FALSE);
5115 gtk_widget_set_visible(GTK_WIDGET(
g->preserve_color),
TRUE);
5119 if(
IS_NULL_PTR(w) || w ==
g->reconstruct_bloom_vs_details)
5121 if(
p->reconstruct_bloom_vs_details == -100.f)
5126 gtk_widget_set_sensitive(
g->reconstruct_structure_vs_texture,
FALSE);
5130 gtk_widget_set_sensitive(
g->reconstruct_structure_vs_texture,
TRUE);
5136 gtk_widget_set_visible(
g->grey_point_source,
p->custom_grey);
5137 gtk_widget_set_visible(
g->grey_point_target,
p->custom_grey);
5141 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:1264
void dt_bauhaus_slider_set_digits(GtkWidget *widget, int val)
Definition bauhaus.c:2873
float dt_bauhaus_slider_get(GtkWidget *widget)
Definition bauhaus.c:2822
void dt_bauhaus_slider_set_soft_max(GtkWidget *widget, float val)
Definition bauhaus.c:1241
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
Definition bauhaus.c:2845
void dt_bauhaus_widget_set_label(GtkWidget *widget, const char *label)
Definition bauhaus.c:1270
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:1396
void dt_bauhaus_slider_set_format(GtkWidget *widget, const char *format)
Definition bauhaus.c:2937
#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:324
#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:811
@ 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
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:2975
int dt_image_is_raw(const dt_image_t *img)
Definition common/image.c:192
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:178
void dt_print(dt_debug_thread_t thread, const char *msg,...)
Definition darktable.c:1536
#define dt_free_align(ptr)
Definition darktable.h:480
static void * dt_calloc_align(size_t size)
Definition darktable.h:487
#define __OMP_SIMD__(...)
Definition darktable.h:261
@ DT_DEBUG_OPENCL
Definition darktable.h:721
@ DT_DEBUG_DEV
Definition darktable.h:717
#define DT_ALIGNED_ARRAY
Definition darktable.h:387
#define for_each_channel(_var,...)
Definition darktable.h:661
#define dt_pixelpipe_cache_alloc_align_float_cache(pixels, id)
Definition darktable.h:446
float dt_aligned_pixel_simd_t __attribute__((vector_size(16), aligned(16)))
Multi-tap smudge source sample with directional jitter.
Definition darktable.h:523
#define dt_free(ptr)
Definition darktable.h:455
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
Definition darktable.h:150
#define __OMP_DECLARE_SIMD__(...)
Definition darktable.h:262
#define dt_pixelpipe_cache_free_align(mem)
Definition darktable.h:452
#define dt_pixelpipe_cache_alloc_align_float(pixels, pipe)
Definition darktable.h:441
#define __DT_CLONE_TARGETS__
Definition darktable.h:366
#define __OMP_PARALLEL_FOR__(...)
Definition darktable.h:257
static const dt_aligned_pixel_simd_t value
Definition darktable.h:576
#define __OMP_PARALLEL_FOR_SIMD__(...)
Definition darktable.h:258
static gboolean dt_modifier_is(const GdkModifierType state, const GdkModifierType desired_modifier_mask)
Definition darktable.h:893
#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:280
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:1458
void dtgtk_cairo_paint_showmask(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
Definition dtgtk/paint.c:2025
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:2174
void(* DTGTKCairoPaintIconFunc)(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
Definition dtgtk/paint.h:74
static void weight(const float *c1, const float *c2, const float sharpen, dt_aligned_pixel_t weight)
Definition eaw.c:33
static void toe_shoulder_callback(GtkWidget *slider, gpointer user_data)
Definition filmicrgb.c:3513
static gboolean area_button_press(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
Definition filmicrgb.c:4543
static gboolean area_scroll_callback(GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
Definition filmicrgb.c:4729
const char ** description(struct dt_iop_module_t *self)
Definition filmicrgb.c:374
int default_group()
Definition filmicrgb.c:385
static gboolean area_leave_notify(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
Definition filmicrgb.c:4643
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:2221
dt_iop_filmic_noise_distribution_t
Definition filmicrgb.c:197
@ DT_FILMIC_NOISE_UNIFORM
Definition filmicrgb.c:198
@ DT_FILMIC_NOISE_POISSONIAN
Definition filmicrgb.c:200
@ DT_FILMIC_NOISE_GAUSSIAN
Definition filmicrgb.c:199
dt_iop_filmicrgb_curve_type_t
Definition filmicrgb.c:146
@ DT_FILMIC_CURVE_RATIONAL
Definition filmicrgb.c:149
@ DT_FILMIC_CURVE_POLY_4
Definition filmicrgb.c:147
@ DT_FILMIC_CURVE_POLY_3
Definition filmicrgb.c:148
void gui_reset(dt_iop_module_t *self)
Definition filmicrgb.c:3621
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:3655
static gboolean dt_iop_tonecurve_draw(GtkWidget *widget, cairo_t *crf, gpointer user_data)
Definition filmicrgb.c:3695
dt_iop_filmic_rgb_gui_mode_t
Definition filmicrgb.c:187
@ DT_FILMIC_GUI_LOOK
Definition filmicrgb.c:188
@ DT_FILMIC_GUI_RANGES
Definition filmicrgb.c:191
@ DT_FILMIC_GUI_BASECURVE
Definition filmicrgb.c:189
@ DT_FILMIC_GUI_BASECURVE_LOG
Definition filmicrgb.c:190
@ DT_FILMIC_GUI_LAST
Definition filmicrgb.c:192
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:1452
void reload_defaults(dt_iop_module_t *module)
Definition filmicrgb.c:3548
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:1190
dt_iop_filmicrgb_colorscience_type_t
Definition filmicrgb.c:154
@ DT_FILMIC_COLORSCIENCE_V1
Definition filmicrgb.c:155
@ DT_FILMIC_COLORSCIENCE_V2
Definition filmicrgb.c:156
@ DT_FILMIC_COLORSCIENCE_V5
Definition filmicrgb.c:159
@ DT_FILMIC_COLORSCIENCE_V4
Definition filmicrgb.c:158
@ DT_FILMIC_COLORSCIENCE_V3
Definition filmicrgb.c:157
#define LOGBASE
Definition filmicrgb.c:3626
__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:2289
void gui_update(dt_iop_module_t *self)
Refresh GUI controls from current params and configuration.
Definition filmicrgb.c:3526
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:3628
static void apply_auto_grey(dt_iop_module_t *self, const dt_iop_order_iccprofile_info_t *const work_profile)
Definition filmicrgb.c:2975
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:1588
static void apply_auto_black(dt_iop_module_t *self, const dt_iop_order_iccprofile_info_t *const work_profile)
Definition filmicrgb.c:3003
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:1242
const char * aliases()
Definition filmicrgb.c:369
void gui_focus(struct dt_iop_module_t *self, gboolean in)
Definition filmicrgb.c:3473
#define CIE_Y_1931_to_CIE_Y_2006(x)
Definition filmicrgb.c:1741
const char * name()
Definition filmicrgb.c:364
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:2071
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:1534
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:2119
void gui_init(dt_iop_module_t *self)
Definition filmicrgb.c:4746
dt_iop_filmicrgb_methods_type_t
Definition filmicrgb.c:135
@ DT_FILMIC_METHOD_POWER_NORM
Definition filmicrgb.c:139
@ DT_FILMIC_METHOD_EUCLIDEAN_NORM_V1
Definition filmicrgb.c:141
@ DT_FILMIC_METHOD_NONE
Definition filmicrgb.c:136
@ DT_FILMIC_METHOD_MAX_RGB
Definition filmicrgb.c:137
@ DT_FILMIC_METHOD_EUCLIDEAN_NORM_V2
Definition filmicrgb.c:140
@ DT_FILMIC_METHOD_LUMINANCE
Definition filmicrgb.c:138
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:1493
static float log_tonemapping(const float x, const float grey, const float black, const float dynamic_range)
Definition filmicrgb.c:989
dt_iop_filmicrgb_reconstruction_type_t
Definition filmicrgb.c:170
@ DT_FILMIC_RECONSTRUCT_RATIOS
Definition filmicrgb.c:172
@ DT_FILMIC_RECONSTRUCT_RGB
Definition filmicrgb.c:171
static void filmic_v3_legacy_to_direct(const dt_iop_filmicrgb_params_t *const p, float *const toe, float *const shoulder)
Definition filmicrgb.c:513
void gui_changed(dt_iop_module_t *self, GtkWidget *w, void *previous)
Definition filmicrgb.c:5042
dt_iop_filmicrgb_gui_button_t
Definition filmicrgb.c:240
@ DT_FILMIC_GUI_BUTTON_LAST
Definition filmicrgb.c:243
@ DT_FILMIC_GUI_BUTTON_LABELS
Definition filmicrgb.c:242
@ DT_FILMIC_GUI_BUTTON_TYPE
Definition filmicrgb.c:241
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:2269
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:1328
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:1348
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:3401
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:3030
#define ORDER_4
Definition filmicrgb.c:3137
static float exp_tonemapping_v2(const float x, const float grey, const float black, const float dynamic_range)
Definition filmicrgb.c:996
void cleanup_global(dt_iop_module_so_t *module)
Definition filmicrgb.c:3600
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:1998
static gboolean area_enter_notify(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
Definition filmicrgb.c:4630
void cleanup_pipe(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition filmicrgb.c:3493
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:1109
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
Definition filmicrgb.c:395
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:400
static gboolean area_motion_notify(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
Definition filmicrgb.c:4655
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:1148
int flags()
Definition filmicrgb.c:390
static void apply_autotune(dt_iop_module_t *self, const dt_iop_order_iccprofile_info_t *const work_profile)
Definition filmicrgb.c:3056
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:2165
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:439
static void show_mask_callback(GtkToggleButton *button, GdkEventButton *event, gpointer user_data)
Definition filmicrgb.c:3116
#define ORDER_3
Definition filmicrgb.c:3138
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:1318
static void convert_to_spline_v3(dt_iop_filmicrgb_params_t *n)
Definition filmicrgb.c:565
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:2234
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:531
#define MAX_NUM_SCALES
Definition filmicrgb.c:1107
dt_iop_filmicrgb_spline_version_type_t
Definition filmicrgb.c:163
@ DT_FILMIC_SPLINE_VERSION_V2
Definition filmicrgb.c:165
@ DT_FILMIC_SPLINE_VERSION_V3
Definition filmicrgb.c:166
@ DT_FILMIC_SPLINE_VERSION_V1
Definition filmicrgb.c:164
void init_pipe(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition filmicrgb.c:3487
static void filmic_gui_sync_toe_shoulder(dt_iop_module_t *self)
Definition filmicrgb.c:3499
#define INVERSE_SQRT_3
Definition filmicrgb.c:87
void init_global(dt_iop_module_so_t *module)
Definition filmicrgb.c:3575
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:484
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:1302
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:3095
#define SAFETY_MARGIN
Definition filmicrgb.c:88
static float linear_saturation(const float x, const float luminance, const float saturation)
Definition filmicrgb.c:1101
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:3142
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:2252
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:628
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:1995
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:2836
float dt_dev_get_module_scale(const dt_dev_pixelpipe_t *const pipe, const dt_iop_roi_t *const roi_in)
Definition imageop.c:125
void dt_iop_set_cache_bypass(dt_iop_module_t *module, gboolean state)
Definition imageop.c:2610
#define dt_omploop_sfence()
Definition imageop.h:672
@ 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:569
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:290
GtkWidget * dt_bauhaus_toggle_from_params(dt_iop_module_t *self, const char *param)
Definition imageop_gui.c:249
GtkWidget * dt_bauhaus_slider_from_params(dt_iop_module_t *self, const char *param)
Definition imageop_gui.c:80
GtkWidget * dt_bauhaus_combobox_from_params(dt_iop_module_t *self, const char *param)
Definition imageop_gui.c:185
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:897
dt_iop_order_iccprofile_info_t * dt_ioppr_get_pipe_work_profile_info(const struct dt_dev_pixelpipe_t *pipe)
Definition iop_profile.c:887
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:902
dt_iop_order_iccprofile_info_t * dt_ioppr_get_iop_work_profile_info(struct dt_iop_module_t *module, GList *iop_list)
Definition iop_profile.c:765
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:83
float *const restrict const size_t k
Definition luminance_mask.h:84
float *const restrict const size_t const size_t ch
Definition luminance_mask.h:84
#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
mask
Definition dtstyle_to_xmp.py:79
float dt_aligned_pixel_t[4]
Definition noiseprofile.c:28
static int dt_opencl_enqueue_kernel_2d(const int dev, const int kernel, const size_t *sizes)
Definition opencl.h:574
static int dt_opencl_set_kernel_arg(const int dev, const int kernel, const size_t size, const void *arg)
Definition opencl.h:570
static int dt_opencl_create_kernel(const int program, const char *name)
Definition opencl.h:549
static void dt_opencl_free_kernel(const int kernel)
Definition opencl.h:553
static void dt_opencl_release_mem_object(void *mem)
Definition opencl.h:619
static int dt_opencl_enqueue_kernel_2d_with_local(const int dev, const int kernel, const size_t *sizes, const size_t *local)
Definition opencl.h:578
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:86
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:95
size_t data_size
Definition pixelpipe_hb.h:107
dt_iop_roi_t buf_in
Definition pixelpipe_hb.h:130
struct dt_iop_module_t *void * data
Definition pixelpipe_hb.h:96
dt_iop_roi_t roi_in
Definition pixelpipe_hb.h:131
dt_iop_roi_t roi_out
Definition pixelpipe_hb.h:131
Definition pixelpipe_hb.h:217
int mask_display
Definition pixelpipe_hb.h:291
dt_dev_pixelpipe_type_t type
Definition pixelpipe_hb.h:296
float iscale
Definition pixelpipe_hb.h:228
int devid
Definition pixelpipe_hb.h:304
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
Definition develop/format.h:52
unsigned int channels
Definition develop/format.h:54
dt_iop_buffer_type_t datatype
Definition develop/format.h:56
Definition filmicrgb.c:177
dt_aligned_pixel_t M2
Definition filmicrgb.c:178
dt_aligned_pixel_t M4
Definition filmicrgb.c:178
dt_iop_filmicrgb_curve_type_t type[2]
Definition filmicrgb.c:182
dt_aligned_pixel_t M5
Definition filmicrgb.c:178
float latitude_min
Definition filmicrgb.c:179
float y[5]
Definition filmicrgb.c:180
dt_aligned_pixel_t M1
Definition filmicrgb.c:178
float x[5]
Definition filmicrgb.c:181
dt_aligned_pixel_t M3
Definition filmicrgb.c:178
float latitude_max
Definition filmicrgb.c:179
Definition filmicrgb.c:319
int high_quality_reconstruction
Definition filmicrgb.c:339
int spline_version
Definition filmicrgb.c:338
float reconstruct_feather
Definition filmicrgb.c:325
float dynamic_range
Definition filmicrgb.c:330
float reconstruct_structure_vs_texture
Definition filmicrgb.c:328
float max_grad
Definition filmicrgb.c:320
float reconstruct_grey_vs_color
Definition filmicrgb.c:327
float output_power
Definition filmicrgb.c:332
float sigma_shoulder
Definition filmicrgb.c:334
float white_source
Definition filmicrgb.c:321
float noise_level
Definition filmicrgb.c:335
float sigma_toe
Definition filmicrgb.c:334
dt_noise_distribution_t noise_distribution
Definition filmicrgb.c:341
int version
Definition filmicrgb.c:337
float grey_source
Definition filmicrgb.c:322
float normalize
Definition filmicrgb.c:329
float reconstruct_bloom_vs_details
Definition filmicrgb.c:326
float saturation
Definition filmicrgb.c:331
float contrast
Definition filmicrgb.c:333
struct dt_iop_filmic_rgb_spline_t spline DT_ALIGNED_ARRAY
Definition filmicrgb.c:340
float black_source
Definition filmicrgb.c:323
float reconstruct_threshold
Definition filmicrgb.c:324
int preserve_color
Definition filmicrgb.c:336
Definition filmicrgb.c:346
int kernel_filmic_rgb_chroma
Definition filmicrgb.c:348
int kernel_filmic_bspline_vertical
Definition filmicrgb.c:352
int kernel_filmic_rgb_split
Definition filmicrgb.c:347
int kernel_filmic_wavelets_reconstruct
Definition filmicrgb.c:358
int kernel_filmic_wavelets_detail
Definition filmicrgb.c:357
int kernel_filmic_show_mask
Definition filmicrgb.c:350
int kernel_filmic_compute_ratios
Definition filmicrgb.c:359
int kernel_filmic_init_reconstruct
Definition filmicrgb.c:356
int kernel_filmic_restore_ratios
Definition filmicrgb.c:360
int kernel_filmic_bspline_vertical_local
Definition filmicrgb.c:354
int kernel_filmic_mask
Definition filmicrgb.c:349
int kernel_filmic_bspline_horizontal
Definition filmicrgb.c:353
int kernel_filmic_inpaint_noise
Definition filmicrgb.c:351
int kernel_filmic_bspline_horizontal_local
Definition filmicrgb.c:355
Definition filmicrgb.c:268
GtkWidget * high_quality_reconstruction
Definition filmicrgb.c:291
GtkWidget * autoset_display_gamma
Definition filmicrgb.c:286
GtkWidget * reconstruct_grey_vs_color
Definition filmicrgb.c:272
GtkWidget * auto_hardness
Definition filmicrgb.c:289
dt_iop_filmicrgb_gui_button_data_t buttons[DT_FILMIC_GUI_BUTTON_LAST]
Definition filmicrgb.c:303
GtkWidget * reconstruct_bloom_vs_details
Definition filmicrgb.c:272
GtkWidget * reconstruct_threshold
Definition filmicrgb.c:272
GtkNotebook * notebook
Definition filmicrgb.c:294
GtkWidget * contrast
Definition filmicrgb.c:283
float graph_height
Definition filmicrgb.c:310
GtkWidget * auto_button
Definition filmicrgb.c:276
GtkWidget * saturation
Definition filmicrgb.c:284
GtkWidget * show_highlight_mask
Definition filmicrgb.c:274
float sign_width
Definition filmicrgb.c:307
GtkWidget * white_point_target
Definition filmicrgb.c:278
GtkWidget * grey_point_source
Definition filmicrgb.c:270
gint gui_show_labels
Definition filmicrgb.c:299
GtkWidget * highlights
Definition filmicrgb.c:287
GtkDrawingArea * area
Definition filmicrgb.c:295
GtkStyleContext * context
Definition filmicrgb.c:315
GtkWidget * output_power
Definition filmicrgb.c:280
GtkWidget * preserve_color
Definition filmicrgb.c:285
PangoRectangle ink
Definition filmicrgb.c:314
dt_iop_filmicrgb_gui_button_t active_button
Definition filmicrgb.c:302
GtkWidget * shadows
Definition filmicrgb.c:287
gint gui_hover
Definition filmicrgb.c:300
GtkAllocation allocation
Definition filmicrgb.c:313
GtkWidget * noise_level
Definition filmicrgb.c:292
GtkWidget * grey_point_target
Definition filmicrgb.c:277
dt_iop_filmic_rgb_gui_mode_t gui_mode
Definition filmicrgb.c:298
gint gui_sizes_inited
Definition filmicrgb.c:301
GtkWidget * black_point_source
Definition filmicrgb.c:271
GtkWidget * reconstruct_structure_vs_texture
Definition filmicrgb.c:273
float graph_width
Definition filmicrgb.c:309
GtkWidget * reconstruct_feather
Definition filmicrgb.c:273
GtkWidget * version
Definition filmicrgb.c:288
GtkWidget * noise_distribution
Definition filmicrgb.c:292
float zero_width
Definition filmicrgb.c:308
GtkWidget * shoulder
Definition filmicrgb.c:282
gint show_mask
Definition filmicrgb.c:297
GtkWidget * toe
Definition filmicrgb.c:281
float line_height
Definition filmicrgb.c:306
GtkWidget * black_point_target
Definition filmicrgb.c:279
int inset
Definition filmicrgb.c:311
GtkWidget * custom_grey
Definition filmicrgb.c:290
struct dt_iop_filmic_rgb_spline_t spline DT_ALIGNED_ARRAY
Definition filmicrgb.c:296
GtkWidget * white_point_source
Definition filmicrgb.c:269
GtkWidget * security_factor
Definition filmicrgb.c:275
GtkWidget * compensate_icc_black
Definition filmicrgb.c:293
Definition filmicrgb.c:205
float reconstruct_threshold
Definition filmicrgb.c:209
float reconstruct_grey_vs_color
Definition filmicrgb.c:212
float reconstruct_feather
Definition filmicrgb.c:210
dt_iop_filmicrgb_curve_type_t shadows
Definition filmicrgb.c:230
dt_iop_filmicrgb_spline_version_type_t spline_version
Definition filmicrgb.c:233
float white_point_target
Definition filmicrgb.c:217
gboolean auto_hardness
Definition filmicrgb.c:226
float contrast
Definition filmicrgb.c:220
float latitude
Definition filmicrgb.c:219
float security_factor
Definition filmicrgb.c:214
dt_iop_filmicrgb_colorscience_type_t version
Definition filmicrgb.c:225
float balance
Definition filmicrgb.c:222
dt_iop_filmic_noise_distribution_t noise_distribution
Definition filmicrgb.c:229
dt_iop_filmicrgb_methods_type_t preserve_color
Definition filmicrgb.c:224
int high_quality_reconstruction
Definition filmicrgb.c:228
dt_iop_filmicrgb_curve_type_t highlights
Definition filmicrgb.c:231
float grey_point_source
Definition filmicrgb.c:206
float output_power
Definition filmicrgb.c:218
float reconstruct_bloom_vs_details
Definition filmicrgb.c:211
float grey_point_target
Definition filmicrgb.c:215
float saturation
Definition filmicrgb.c:221
gboolean custom_grey
Definition filmicrgb.c:227
float noise_level
Definition filmicrgb.c:223
float black_point_source
Definition filmicrgb.c:207
gboolean compensate_icc_black
Definition filmicrgb.c:232
float black_point_target
Definition filmicrgb.c:216
float white_point_source
Definition filmicrgb.c:208
float reconstruct_structure_vs_texture
Definition filmicrgb.c:213
Definition filmicrgb.c:1984
dt_aligned_pixel_simd_t input[3]
Definition filmicrgb.c:1985
dt_aligned_pixel_simd_t output[3]
Definition filmicrgb.c:1986
dt_aligned_pixel_simd_t export_output[3]
Definition filmicrgb.c:1988
dt_aligned_pixel_simd_t export_input[3]
Definition filmicrgb.c:1987
Definition filmicrgb.c:412
float white_display
Definition filmicrgb.c:416
float linear_intercept
Definition filmicrgb.c:418
float black_display
Definition filmicrgb.c:415
float xmin
Definition filmicrgb.c:419
gboolean contrast_clamped
Definition filmicrgb.c:421
float grey_display
Definition filmicrgb.c:414
float grey_log
Definition filmicrgb.c:413
float contrast
Definition filmicrgb.c:417
float xmax
Definition filmicrgb.c:420
Definition filmicrgb.c:425
float shoulder_display
Definition filmicrgb.c:429
float toe_display
Definition filmicrgb.c:428
float toe_log
Definition filmicrgb.c:426
float shoulder_log
Definition filmicrgb.c:427
dt_iop_global_data_t * data
Definition imageop.h:232
GtkDarktableToggleButton * off
Definition imageop.h:333
dt_iop_params_t * default_params
Definition imageop.h:301
GtkWidget * widget
Definition imageop.h:331
struct dt_develop_t * dev
Definition imageop.h:290
dt_iop_gui_data_t * gui_data
Definition imageop.h:305
gboolean enabled
Definition imageop.h:292
dt_aligned_pixel_t picked_color_min
Definition imageop.h:273
int request_mask_display
Definition imageop.h:267
dt_aligned_pixel_t picked_color_max
Definition imageop.h:273
dt_aligned_pixel_t picked_color
Definition imageop.h:273
dt_iop_params_t * params
Definition imageop.h:301
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
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
#define E
Definition test_filmicrgb.c:61
#define MIN(a, b)
Definition thinplate.c:32
#define MAX(a, b)
Definition thinplate.c:29