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")
364 return _(
"fil_mic rgb");
369 return _(
"tone mapping|curve|view transform|contrast|saturation|highlights");
375 "for display on SDR screens and paper prints\n"
376 "while preventing clipping in non-destructive ways"),
377 _(
"corrective and creative"),
378 _(
"linear or non-linear, RGB, scene-referred"),
379 _(
"non-linear, RGB"),
380 _(
"non-linear, RGB, display-referred"));
443 geometry->
grey_display = powf(CLAMP(
p->grey_point_target,
p->black_point_target,
p->white_point_target) / 100.0f,
444 1.0f /
p->output_power);
446 geometry->
grey_display = powf(0.1845f, 1.0f /
p->output_power);
448 const float dynamic_range =
p->white_point_source -
p->black_point_source;
449 geometry->
grey_log = fabsf(
p->black_point_source) / dynamic_range;
450 geometry->
black_display = powf(CLAMP(
p->black_point_target, 0.0f,
p->grey_point_target) / 100.0f,
451 1.0f /
p->output_power);
452 geometry->
white_display = powf(fmaxf(
p->white_point_target,
p->grey_point_target) / 100.0f,
453 1.0f /
p->output_power);
455 const float slope =
p->contrast * dynamic_range / 8.0f;
456 float min_contrast = 1.0f;
457 min_contrast = fmaxf(min_contrast,
459 min_contrast = fmaxf(min_contrast,
464 const float clamped_contrast = CLAMP(geometry->
contrast, min_contrast, 100.0f);
466 geometry->
contrast = clamped_contrast;
488 const float latitude = CLAMP(
p->latitude, 0.0f, 100.0f) / 100.0f;
489 const float balance = CLAMP(
p->balance, -50.0f, 50.0f) / 100.0f;
498 const float balance_correction = (balance > 0.0f)
501 nodes->
toe_log -= balance_correction;
512 float *
const toe,
float *
const shoulder)
518 *toe = CLAMP(
p->latitude, 0.0f, 100.0f);
519 *shoulder = CLAMP(
p->latitude, 0.0f, 100.0f);
523 const float toe_span = fmaxf(geometry.
grey_log - geometry.
xmin, 1e-6f);
524 const float shoulder_span = fmaxf(geometry.
xmax - geometry.
grey_log, 1e-6f);
525 *toe = CLAMP((geometry.
grey_log - nodes.
toe_log) / toe_span, 0.0f, 1.0f) * 100.0f;
526 *shoulder = CLAMP((nodes.
shoulder_log - geometry.
grey_log) / shoulder_span, 0.0f, 1.0f) * 100.0f;
530 const float toe,
const float shoulder,
531 float *
const latitude,
float *
const balance)
536 *latitude =
p->latitude;
537 *balance =
p->balance;
541 const float toe_value = CLAMP(toe, 0.0f, 100.0f) / 100.0f;
542 const float shoulder_value = CLAMP(shoulder, 0.0f, 100.0f) / 100.0f;
543 const float toe_span = fmaxf(geometry.
grey_log - geometry.
xmin, 1e-6f);
544 const float shoulder_span = fmaxf(geometry.
xmax - geometry.
grey_log, 1e-6f);
545 const float latitude_value = CLAMP((toe_span * toe_value + shoulder_span * shoulder_value)
546 / (toe_span + shoulder_span),
549 float balance_value = 0.0f;
550 if(latitude_value > 1e-6f)
552 if(toe_value > shoulder_value)
553 balance_value = 0.5f * (1.0f - shoulder_value / latitude_value);
554 else if(shoulder_value > toe_value)
555 balance_value = 0.5f * (toe_value / latitude_value - 1.0f);
558 *latitude = latitude_value * 100.0f;
559 *balance = CLAMP(balance_value, -0.5f, 0.5f) * 100.0f;
572 float grey_log = spline.
x[2];
573 float toe_log = fminf(spline.
x[1], grey_log);
574 float shoulder_log = fmaxf(spline.
x[3], grey_log);
575 float black_display = spline.
y[0];
576 float grey_display = spline.
y[2];
577 float white_display = spline.
y[4];
578 const float scaled_safety_margin =
SAFETY_MARGIN * (white_display - black_display);
579 float toe_display = fminf(spline.
y[1], grey_display);
580 float shoulder_display = fmaxf(spline.
y[3], grey_display);
582 float hardness =
n->output_power;
583 float contrast = (shoulder_display - toe_display) / (shoulder_log - toe_log);
585 float linear_intercept = grey_display - (contrast * grey_log);
586 if(toe_display < black_display + scaled_safety_margin)
588 toe_display = black_display + scaled_safety_margin;
590 toe_log = (toe_display - linear_intercept) / contrast;
592 if(shoulder_display > white_display - scaled_safety_margin)
594 shoulder_display = white_display - scaled_safety_margin;
596 shoulder_log = (shoulder_display - linear_intercept) / contrast;
599 contrast *= 8.0f / (
n->white_point_source -
n->black_point_source);
600 contrast *= hardness * powf(grey_display, hardness-1.0f);
602 const float latitude = CLAMP((shoulder_display - toe_display) / ((white_display - black_display) - 2.0f * scaled_safety_margin), 0.0f, 0.99f);
604 float toe_display_ref = latitude * (black_display + scaled_safety_margin) + (1.0f - latitude) * grey_display;
605 float shoulder_display_ref = latitude * (white_display - scaled_safety_margin) + (1.0f - latitude) * grey_display;
607 if(shoulder_display < shoulder_display_ref)
608 balance = 0.5f * (1.0f - fmaxf(shoulder_display - grey_display, 0.0f) / fmaxf(shoulder_display_ref - grey_display, 1E-5f));
610 balance = -0.5f * (1.0f - fmaxf(grey_display - toe_display, 0.0f) / fmaxf(grey_display - toe_display_ref, 1E-5f));
617 n->black_point_target = powf(black_display, hardness) * 100.0f;
618 n->white_point_target = powf(white_display, hardness) * 100.0f;
620 n->latitude = latitude * 100.0f;
621 n->contrast = contrast;
622 n->balance = balance * 100.0f;
627 const int new_version)
629 if(old_version == 1 && new_version == 5)
631 typedef struct dt_iop_filmicrgb_params_v1_t
633 float grey_point_source;
634 float black_point_source;
635 float white_point_source;
636 float security_factor;
637 float grey_point_target;
638 float black_point_target;
639 float white_point_target;
646 } dt_iop_filmicrgb_params_v1_t;
648 dt_iop_filmicrgb_params_v1_t *o = (dt_iop_filmicrgb_params_v1_t *)old_params;
654 n->grey_point_source = o->grey_point_source;
655 n->white_point_source = o->white_point_source;
656 n->black_point_source = o->black_point_source;
657 n->security_factor = o->security_factor;
658 n->grey_point_target = o->grey_point_target;
659 n->black_point_target = o->black_point_target;
660 n->white_point_target = o->white_point_target;
661 n->output_power = o->output_power;
662 n->latitude = o->latitude;
663 n->contrast = o->contrast;
664 n->saturation = o->saturation;
665 n->balance = o->balance;
666 n->preserve_color = o->preserve_color;
669 n->reconstruct_threshold
671 n->reconstruct_bloom_vs_details =
d->reconstruct_bloom_vs_details;
672 n->reconstruct_grey_vs_color =
d->reconstruct_grey_vs_color;
673 n->reconstruct_structure_vs_texture =
d->reconstruct_structure_vs_texture;
674 n->reconstruct_feather = 3.0f;
676 n->auto_hardness =
TRUE;
677 n->custom_grey =
TRUE;
678 n->high_quality_reconstruction = 0;
679 n->noise_distribution =
d->noise_distribution;
680 n->noise_level = 0.f;
682 n->compensate_icc_black =
FALSE;
686 if(old_version == 2 && new_version == 5)
688 typedef struct dt_iop_filmicrgb_params_v2_t
690 float grey_point_source;
691 float black_point_source;
692 float white_point_source;
693 float reconstruct_threshold;
694 float reconstruct_feather;
695 float reconstruct_bloom_vs_details;
696 float reconstruct_grey_vs_color;
697 float reconstruct_structure_vs_texture;
698 float security_factor;
699 float grey_point_target;
700 float black_point_target;
701 float white_point_target;
711 int high_quality_reconstruction;
714 } dt_iop_filmicrgb_params_v2_t;
716 dt_iop_filmicrgb_params_v2_t *o = (dt_iop_filmicrgb_params_v2_t *)old_params;
722 n->grey_point_source = o->grey_point_source;
723 n->white_point_source = o->white_point_source;
724 n->black_point_source = o->black_point_source;
725 n->security_factor = o->security_factor;
726 n->grey_point_target = o->grey_point_target;
727 n->black_point_target = o->black_point_target;
728 n->white_point_target = o->white_point_target;
729 n->output_power = o->output_power;
730 n->latitude = o->latitude;
731 n->contrast = o->contrast;
732 n->saturation = o->saturation;
733 n->balance = o->balance;
734 n->preserve_color = o->preserve_color;
735 n->shadows = o->shadows;
736 n->highlights = o->highlights;
737 n->reconstruct_threshold = o->reconstruct_threshold;
738 n->reconstruct_bloom_vs_details = o->reconstruct_bloom_vs_details;
739 n->reconstruct_grey_vs_color = o->reconstruct_grey_vs_color;
740 n->reconstruct_structure_vs_texture = o->reconstruct_structure_vs_texture;
741 n->reconstruct_feather = o->reconstruct_feather;
742 n->version = o->version;
743 n->auto_hardness = o->auto_hardness;
744 n->custom_grey = o->custom_grey;
745 n->high_quality_reconstruction = o->high_quality_reconstruction;
746 n->noise_level =
d->noise_level;
747 n->noise_distribution =
d->noise_distribution;
748 n->noise_level = 0.f;
750 n->compensate_icc_black =
FALSE;
754 if(old_version == 3 && new_version == 5)
756 typedef struct dt_iop_filmicrgb_params_v3_t
758 float grey_point_source;
759 float black_point_source;
760 float white_point_source;
761 float reconstruct_threshold;
762 float reconstruct_feather;
763 float reconstruct_bloom_vs_details;
765 float reconstruct_grey_vs_color;
767 float reconstruct_structure_vs_texture;
769 float security_factor;
770 float grey_point_target;
771 float black_point_target;
772 float white_point_target;
783 gboolean auto_hardness;
784 gboolean custom_grey;
785 int high_quality_reconstruction;
787 int noise_distribution;
791 } dt_iop_filmicrgb_params_v3_t;
793 dt_iop_filmicrgb_params_v3_t *o = (dt_iop_filmicrgb_params_v3_t *)old_params;
799 n->grey_point_source = o->grey_point_source;
800 n->white_point_source = o->white_point_source;
801 n->black_point_source = o->black_point_source;
802 n->security_factor = o->security_factor;
803 n->grey_point_target = o->grey_point_target;
804 n->black_point_target = o->black_point_target;
805 n->white_point_target = o->white_point_target;
806 n->output_power = o->output_power;
807 n->latitude = o->latitude;
808 n->contrast = o->contrast;
809 n->saturation = o->saturation;
810 n->balance = o->balance;
811 n->preserve_color = o->preserve_color;
812 n->shadows = o->shadows;
813 n->highlights = o->highlights;
814 n->reconstruct_threshold = o->reconstruct_threshold;
815 n->reconstruct_bloom_vs_details = o->reconstruct_bloom_vs_details;
816 n->reconstruct_grey_vs_color = o->reconstruct_grey_vs_color;
817 n->reconstruct_structure_vs_texture = o->reconstruct_structure_vs_texture;
818 n->reconstruct_feather = o->reconstruct_feather;
819 n->version = o->version;
820 n->auto_hardness = o->auto_hardness;
821 n->custom_grey = o->custom_grey;
822 n->high_quality_reconstruction = o->high_quality_reconstruction;
823 n->noise_level =
d->noise_level;
824 n->noise_distribution =
d->noise_distribution;
825 n->noise_level =
d->noise_level;
827 n->compensate_icc_black =
FALSE;
831 if(old_version == 4 && new_version == 5)
833 typedef struct dt_iop_filmicrgb_params_v4_t
835 float grey_point_source;
836 float black_point_source;
837 float white_point_source;
838 float reconstruct_threshold;
839 float reconstruct_feather;
840 float reconstruct_bloom_vs_details;
841 float reconstruct_grey_vs_color;
842 float reconstruct_structure_vs_texture;
843 float security_factor;
844 float grey_point_target;
845 float black_point_target;
846 float white_point_target;
855 gboolean auto_hardness;
856 gboolean custom_grey;
857 int high_quality_reconstruction;
861 gboolean compensate_icc_black;
862 gint internal_version;
863 } dt_iop_filmicrgb_params_v4_t;
865 dt_iop_filmicrgb_params_v4_t *o = (dt_iop_filmicrgb_params_v4_t *)old_params;
869 switch(o->internal_version)
894 float numerator = 0.0f;
895 float denominator = 0.0f;
897 for(
int c = 0;
c < 3;
c++)
899 const float value = fabsf(pixel[
c]);
901 const float RGB_cubic = RGB_square *
value;
902 numerator += RGB_cubic;
903 denominator += RGB_square;
906 return numerator / fmaxf(denominator, 1e-12f);
928 return fmaxf(fmaxf(pixel[0], pixel[1]), pixel[2]);
935 dt_aligned_pixel_t
rgb;
938 work_profile->unbounded_coeffs_in, work_profile->
lutsize,
942 return work_profile->
matrix_in[1][0] * pixel[0] + work_profile->
matrix_in[1][1] * pixel[1]
943 + work_profile->
matrix_in[1][2] * pixel[2];
946 return pixel[0] * 0.2225045f + pixel[1] * 0.7168786f + pixel[2] * 0.0606169f;
952 return sqrtf(
sqf(pixel[0]) +
sqf(pixel[1]) +
sqf(pixel[2]));
962 dt_aligned_pixel_t
rgb;
965 work_profile->unbounded_coeffs_in, work_profile->
lutsize,
969 return work_profile->
matrix_in[1][0] * pixel[0] + work_profile->
matrix_in[1][1] * pixel[1]
970 + work_profile->
matrix_in[1][2] * pixel[2];
973 return pixel[0] * 0.2225045f + pixel[1] * 0.7168786f + pixel[2] * 0.0606169f;
984#pragma omp declare simd uniform(grey, black, dynamic_range)
987 const float dynamic_range)
989 return clamp_simd((log2f(
x / grey) - black) / dynamic_range);
993#pragma omp declare simd uniform(grey, black, dynamic_range)
996 const float dynamic_range)
999 return grey * exp2f(dynamic_range *
x + black);
1004#pragma omp declare simd aligned(M1, M2, M3, M4 : 16) uniform(M1, M2, M3, M4, M5, latitude_min, latitude_max)
1006static inline float filmic_spline(
const float x,
const dt_aligned_pixel_t M1,
const dt_aligned_pixel_t
M2,
1007 const dt_aligned_pixel_t M3,
const dt_aligned_pixel_t M4,
1008 const dt_aligned_pixel_t M5,
const float latitude_min,
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];
1071#pragma omp declare simd uniform(sigma_toe, sigma_shoulder)
1074 const float saturation)
1076 const float radius_toe =
x;
1077 const float radius_shoulder = 1.0f -
x;
1079 const float key_toe = expf(-0.5f * radius_toe * radius_toe / sigma_toe);
1080 const float key_shoulder = expf(-0.5f * radius_shoulder * radius_shoulder / sigma_shoulder);
1082 return 1.0f -
clamp_simd((key_toe + key_shoulder) / saturation);
1087#pragma omp declare simd uniform(sigma_toe, sigma_shoulder)
1090 const float saturation)
1092 const float radius_toe =
x;
1093 const float radius_shoulder = 1.0f -
x;
1094 const float sat2 = 0.5f / sqrtf(saturation);
1095 const float key_toe = expf(-radius_toe * radius_toe / sigma_toe * sat2);
1096 const float key_shoulder = expf(-radius_shoulder * radius_shoulder / sigma_shoulder * sat2);
1098 return (saturation - (key_toe + key_shoulder) * (saturation));
1103#pragma omp declare simd
1107 return luminance + saturation * (
x - luminance);
1111#define MAX_NUM_SCALES 10
1115#pragma omp declare simd aligned(in, mask : 64) uniform(feathering, normalize, width, height, ch)
1119 const float normalize,
const float feathering,
const size_t width,
1120 const size_t height,
const size_t ch)
1132 const unsigned int oldMode = _MM_GET_FLUSH_ZERO_MODE();
1133 _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
1137#pragma omp parallel for simd default(none) \
1138 dt_omp_firstprivate(in, mask, normalize, feathering, width, height, ch) \
1139 schedule(simd:static) aligned(mask, in:64) reduction(+:clipped)
1141 for(
size_t k = 0; k <
height *
width * ch; k += ch)
1143 const float pix_max = fmaxf(sqrtf(
sqf(in[k]) +
sqf(in[k + 1]) +
sqf(in[k + 2])), 0.f);
1144 const float argument = -pix_max *
normalize + feathering;
1152 clipped += (4.f > argument);
1156 _MM_SET_FLUSH_ZERO_MODE(oldMode);
1160 return (clipped > 9);
1165#pragma omp declare simd aligned(in, mask, inpainted:64) uniform(width, height, noise_level, noise_distribution, threshold)
1168 float *
const inpainted,
const float noise_level,
const float threshold,
1177#pragma omp parallel for default(none) \
1178 dt_omp_firstprivate(in, mask, inpainted, width, height, noise_level, noise_distribution, threshold) \
1179 schedule(simd:static) collapse(2)
1182 for(
size_t j = 0; j <
width; j++)
1192 const size_t idx =
i *
width + j;
1193 const size_t index = idx * 4;
1194 const float weight = mask[idx];
1195 const float *
const restrict pix_in = __builtin_assume_aligned(in + index, 16);
1196 dt_aligned_pixel_t noise = { 0.f };
1197 dt_aligned_pixel_t sigma = { 0.f };
1207 float *
const restrict pix_out = __builtin_assume_aligned(inpainted + index, 16);
1209 pix_out[
c] = fmaxf(pix_in[
c] * (1.0f -
weight) +
weight * noise[
c], 0.f);
1215 const float *
const restrict texture,
const float *
const restrict mask,
1216 float *
const restrict reconstructed,
const size_t width,
1217 const size_t height,
const size_t ch,
const float gamma,
1218 const float gamma_comp,
const float beta,
const float beta_comp,
1219 const float delta,
const size_t s,
const size_t scales)
1222#pragma omp parallel for default(none) \
1223 dt_omp_firstprivate(width, height, ch, HF, LF, texture, mask, reconstructed, gamma, gamma_comp, beta, \
1224 beta_comp, delta, s, scales) schedule(simd : static)
1226 for(
size_t k = 0; k <
height *
width * ch; k += 4)
1228 const float alpha = mask[k / ch];
1231 const float *
const restrict HF_c = __builtin_assume_aligned(HF + k, 16);
1232 const float *
const restrict LF_c = __builtin_assume_aligned(LF + k, 16);
1233 const float *
const restrict TT_c = __builtin_assume_aligned(texture + k, 16);
1242 const float grey_details = (HF_c[0] + HF_c[1] + HF_c[2]) / 3.f;
1247 const float grey_HF = beta_comp * (gamma_comp * grey_details + gamma * grey_texture);
1251 const float grey_residual = beta_comp * (LF_c[0] + LF_c[1] + LF_c[2]) / 3.f;
1254 #pragma omp simd aligned(reconstructed:64) aligned(HF_c, LF_c, TT_c:16)
1256 for(
size_t c = 0;
c < 4;
c++)
1263 const float details = (gamma_comp * HF_c[
c] + gamma * TT_c[
c]) * beta + grey_HF;
1266 const float residual = (s == scales - 1) ? (grey_residual + LF_c[
c] * beta) : 0.f;
1267 reconstructed[k +
c] += alpha * (
delta * details + residual);
1274 const float *
const restrict texture,
1275 const float *
const restrict mask,
1276 float *
const restrict reconstructed,
const size_t width,
1277 const size_t height,
const size_t ch,
const float gamma,
1278 const float gamma_comp,
const float beta,
const float beta_comp,
1279 const float delta,
const size_t s,
const size_t scales)
1295#pragma omp parallel for default(none) \
1296 dt_omp_firstprivate(width, height, ch, HF, LF, texture, mask, reconstructed, gamma, gamma_comp, beta, \
1297 beta_comp, delta, s, scales) schedule(simd \
1300 for(
size_t k = 0; k <
height *
width * ch; k += 4)
1302 const float alpha = mask[k / ch];
1305 const float *
const restrict HF_c = __builtin_assume_aligned(HF + k, 16);
1306 const float *
const restrict LF_c = __builtin_assume_aligned(LF + k, 16);
1307 const float *
const restrict TT_c = __builtin_assume_aligned(texture + k, 16);
1316 const float grey_details = (HF_c[0] + HF_c[1] + HF_c[2]) / 3.f;
1321 const float grey_HF = (gamma_comp * grey_details + gamma * grey_texture);
1324 #pragma omp simd aligned(reconstructed:64) aligned(HF_c, TT_c, LF_c:16) linear(k:4)
1326 for(
size_t c = 0;
c < 4;
c++)
1330 const float details = 0.5f * ((gamma_comp * HF_c[
c] + gamma * TT_c[
c]) + grey_HF);
1333 const float residual = (s == scales - 1) ? LF_c[
c] : 0.f;
1334 reconstructed[k +
c] += alpha * (
delta * details + residual);
1340static inline void init_reconstruct(
const float *
const restrict in,
const float *
const restrict mask,
1341 float *
const restrict reconstructed,
const size_t width,
const size_t height)
1346#pragma omp parallel for default(none) dt_omp_firstprivate(in, mask, reconstructed, width, height) \
1352 reconstructed[4*k +
c] = fmaxf(in[4*k +
c] * (1.f - mask[k]), 0.f);
1359 float *
const restrict HF,
float *
const restrict texture,
1360 const size_t width,
const size_t height,
const size_t ch)
1363#pragma omp parallel for simd default(none) dt_omp_firstprivate(width, height, HF, LF, detail, texture) \
1365 : static) aligned(HF, LF, detail, texture : 64)
1369 for(
size_t c = 0;
c < 4; ++
c) HF[4*k +
c] = texture[4*k +
c] = detail[4*k +
c] - LF[4*k +
c];
1385 const float scale = roi_in->
scale;
1393 float *
const restrict reconstructed,
1401 const int scales =
get_scales(roi_in, piece);
1412 if(!LF_even || !LF_odd || !HF_RGB || !HF_grey || !temp)
1437 for(
int s = 0; s < scales; ++s)
1439 const float *restrict detail;
1441 float *restrict HF_RGB_temp;
1448 HF_RGB_temp = LF_even;
1454 HF_RGB_temp = LF_odd;
1460 HF_RGB_temp = LF_even;
1463 const int mult = 1 << s;
1478 gamma, gamma_comp, beta, beta_comp,
delta, s, scales);
1481 gamma, gamma_comp, beta, beta_comp,
delta, s, scales);
1501#pragma omp parallel for default(none) \
1502 dt_omp_firstprivate(width, height, data, in, out, work_profile, spline) \
1503 schedule(simd : static)
1507 const float *
const restrict pix_in = in + k;
1508 float *
const restrict pix_out =
out + k;
1509 dt_aligned_pixel_t temp;
1512 for(
int c = 0;
c < 3;
c++)
1517 const float lum = (work_profile)
1519 work_profile->unbounded_coeffs_in,
1527 for(
int c = 0;
c < 3;
c++)
1530 spline.
M1, spline.
M2, spline.
M3, spline.
M4, spline.
M5,
1532 spline.
y[0], spline.
y[4]),
1545#pragma omp parallel for default(none) \
1546 dt_omp_firstprivate(width, height, data, in, out, work_profile, spline) \
1547 schedule(simd : static)
1551 const float *
const restrict pix_in = in + k;
1552 float *
const restrict pix_out =
out + k;
1553 dt_aligned_pixel_t temp;
1556 for(
int c = 0;
c < 3;
c++)
1561 const float lum = (work_profile)
1563 work_profile->unbounded_coeffs_in,
1571 for(
int c = 0;
c < 3;
c++)
1574 spline.
M1, spline.
M2, spline.
M3, spline.
M4, spline.
M5,
1576 spline.
y[0], spline.
y[4]),
1589#pragma omp parallel for default(none) \
1590 dt_omp_firstprivate(width, height, data, in, out, work_profile, variant, spline) schedule(simd : static)
1594 const float *
const restrict pix_in = in + k;
1595 float *
const restrict pix_out =
out + k;
1597 dt_aligned_pixel_t ratios = { 0.0f };
1602 ratios[
c] = pix_in[
c] / norm;
1605 const float min_ratios = fminf(fminf(ratios[0], ratios[1]), ratios[2]);
1606 if(min_ratios < 0.0f)
1618 ratios, work_profile->
matrix_in, work_profile->
lut_in, work_profile->unbounded_coeffs_in,
1629 spline.
y[0], spline.
y[4]),
1642 const size_t width,
const size_t height,
const size_t ch,
1647#pragma omp parallel for default(none) \
1648 dt_omp_firstprivate(width, height, ch, data, in, out, work_profile, variant, spline, colorscience_version) \
1649 schedule(simd :static)
1651 for(
size_t k = 0; k <
height *
width * ch; k += ch)
1653 const float *
const restrict pix_in = in + k;
1654 float *
const restrict pix_out =
out + k;
1659 dt_aligned_pixel_t ratios = { 0.0f };
1662 ratios[
c] = pix_in[
c] / norm;
1665 const float min_ratios = fminf(fminf(ratios[0], ratios[1]), ratios[2]);
1666 const int sanitize = (min_ratios < 0.0f);
1670 ratios[
c] -= min_ratios;
1682 spline.
y[0], spline.
y[4]),
1686 for(
int c = 0;
c < 3;
c++) ratios[
c] = fmaxf(ratios[
c] + (1.0f - ratios[
c]) * (1.0f - desaturation), 0.0f);
1694 pix_out[
c] = ratios[
c] * norm;
1697 const float max_pix = fmaxf(fmaxf(pix_out[0], pix_out[1]), pix_out[2]);
1698 const int penalize = (max_pix > 1.0f);
1705 ratios[
c] = fmaxf(ratios[
c] + (1.0f - max_pix), 0.0f);
1706 pix_out[
c] = ratios[
c] * norm;
1714pipe_RGB_to_Ych_simd(
const dt_aligned_pixel_simd_t in,
const dt_aligned_pixel_simd_t matrix0,
1715 const dt_aligned_pixel_simd_t matrix1,
const dt_aligned_pixel_simd_t matrix2)
1726 const dt_aligned_pixel_simd_t
Yrg = LMS_to_Yrg_simd(dt_mat3x4_mul_vec4(in, matrix0, matrix1, matrix2));
1727 const float r =
Yrg[1] - 0.21902143f;
1728 const float g =
Yrg[2] - 0.54371398f;
1730 const float cos_h =
c != 0.f ?
r /
c : 1.f;
1731 const float sin_h =
c != 0.f ?
g /
c : 0.f;
1732 return (dt_aligned_pixel_simd_t){
Yrg[0],
c, cos_h, sin_h };
1736static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
1737Ych_to_pipe_RGB_simd(
const dt_aligned_pixel_simd_t in,
const dt_aligned_pixel_simd_t matrix0,
1738 const dt_aligned_pixel_simd_t matrix1,
const dt_aligned_pixel_simd_t matrix2)
1743 const dt_aligned_pixel_simd_t
Yrg = {
1745 in[1] * in[2] + 0.21902143f,
1746 in[1] * in[3] + 0.54371398f,
1749 return dt_mat3x4_mul_vec4(Yrg_to_LMS_simd(
Yrg), matrix0, matrix1, matrix2);
1752static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
1753filmic_desaturate_v4(
const dt_aligned_pixel_simd_t Ych_original, dt_aligned_pixel_simd_t Ych_final,
1754 const float saturation)
1762 const float chroma_original = Ych_original[1] * Ych_original[0];
1763 float chroma_final = Ych_final[1] * Ych_final[0];
1772 const float delta_chroma = saturation * (chroma_original - chroma_final);
1774 const int filmic_brightens = (Ych_final[0] > Ych_original[0]);
1775 const int filmic_resat = (chroma_original < chroma_final);
1776 const int filmic_desat = (chroma_original > chroma_final);
1777 const int user_resat = (saturation > 0.f);
1778 const int user_desat = (saturation < 0.f);
1780 chroma_final = (filmic_brightens && filmic_resat)
1781 ? (chroma_original + chroma_final) / 2.f
1782 : ((user_resat && filmic_desat) || user_desat)
1783 ? chroma_final + delta_chroma
1786 Ych_final[1] = fmaxf(chroma_final / Ych_final[0], 0.f);
1796#define CIE_Y_1931_to_CIE_Y_2006(x) (1.05785528f * (x))
1800 const float cos_h,
const float sin_h)
1802 const float denominator_Y_coeff = coeffs[0] * (0.979381443298969f * cos_h + 0.391752577319588f * sin_h)
1803 + coeffs[1] * (0.0206185567010309f * cos_h + 0.608247422680412f * sin_h)
1804 - coeffs[2] * (cos_h + sin_h);
1805 const float denominator_target_term = target_white * (0.68285981628866f * cos_h + 0.482137060515464f * sin_h);
1808 if(denominator_Y_coeff == 0.f)
return FLT_MAX;
1813 const float Y_asymptote = denominator_target_term / denominator_Y_coeff;
1814 if(Y <= Y_asymptote)
return FLT_MAX;
1820 const float denominator = Y * denominator_Y_coeff - denominator_target_term;
1821 const float numerator = -0.427506877216495f
1822 * (Y * (coeffs[0] + 0.856492345150334f * coeffs[1] + 0.554995960637719f * coeffs[2])
1823 - 0.988237752433297f * target_white);
1825 return numerator / denominator;
1829static inline float clip_chroma_white(
const float coeffs[3],
const float target_white,
const float Y,
1830 const float cos_h,
const float sin_h)
1836 const float eps = 1e-3f;
1838 const float delta_Y =
MAX(max_Y - Y, 0.f);
1848 return max_chroma >= 0.f ? max_chroma : FLT_MAX;
1861 const float denominator = coeffs[0] * (0.979381443298969f * cos_h + 0.391752577319588f * sin_h)
1862 + coeffs[1] * (0.0206185567010309f * cos_h + 0.608247422680412f * sin_h)
1863 - coeffs[2] * (cos_h + sin_h);
1866 if(denominator == 0.f)
return FLT_MAX;
1868 const float numerator = -0.427506877216495f * (coeffs[0] + 0.856492345150334f * coeffs[1] + 0.554995960637719f * coeffs[2]);
1869 const float max_chroma = numerator / denominator;
1870 return max_chroma >= 0.f ? max_chroma : FLT_MAX;
1875 const float cos_h,
const float sin_h,
const float chroma)
1883 const float chroma_R_white =
clip_chroma_white(matrix_out[0], target_white, Y, cos_h, sin_h);
1884 const float chroma_G_white =
clip_chroma_white(matrix_out[1], target_white, Y, cos_h, sin_h);
1885 const float chroma_B_white =
clip_chroma_white(matrix_out[2], target_white, Y, cos_h, sin_h);
1886 const float max_chroma_white =
MIN(
MIN(chroma_R_white, chroma_G_white), chroma_B_white);
1891 const float max_chroma_black =
MIN(
MIN(chroma_R_black, chroma_G_black), chroma_B_black);
1893 return MIN(
MIN(chroma, max_chroma_black), max_chroma_white);
1897static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
1898gamut_check_Yrg_filmic_simd(
const dt_aligned_pixel_simd_t
Ych)
1902 const dt_aligned_pixel_simd_t
Yrg = {
1904 Ych[1] *
Ych[2] + 0.21902143f,
1905 Ych[1] *
Ych[3] + 0.54371398f,
1908 float max_c =
Ych[1];
1910 if(
Yrg[1] < 0.f) max_c = fminf(-0.21902143f /
Ych[2], max_c);
1911 if(
Yrg[2] < 0.f) max_c = fminf(-0.54371398f /
Ych[3], max_c);
1912 if(
Yrg[1] +
Yrg[2] > 1.f) max_c = fminf((1.f - 0.21902143f - 0.54371398f) / (
Ych[2] +
Ych[3]), max_c);
1914 return (dt_aligned_pixel_simd_t){
Ych[0], max_c,
Ych[2],
Ych[3] };
1918static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
1919gamut_check_RGB_simd(
const dt_colormatrix_t matrix_out,
const dt_aligned_pixel_simd_t matrix_in0,
1920 const dt_aligned_pixel_simd_t matrix_in1,
const dt_aligned_pixel_simd_t matrix_in2,
1921 const dt_aligned_pixel_simd_t matrix_out0,
const dt_aligned_pixel_simd_t matrix_out1,
1922 const dt_aligned_pixel_simd_t matrix_out2,
const float display_black,
1923 const float display_white,
const dt_aligned_pixel_simd_t Ych_in)
1927 dt_aligned_pixel_simd_t RGB_brightened = Ych_to_pipe_RGB_simd(Ych_in, matrix_out0, matrix_out1, matrix_out2);
1928 const float min_pix =
MIN(
MIN(RGB_brightened[0], RGB_brightened[1]), RGB_brightened[2]);
1929 const float black_offset =
MAX(-min_pix, 0.f);
1932 const dt_aligned_pixel_simd_t Ych_brightened
1933 = pipe_RGB_to_Ych_simd(RGB_brightened, matrix_in0, matrix_in1, matrix_in2);
1939 const float Y = CLAMP((Ych_in[0] + Ych_brightened[0]) / 2.f,
1942 const float new_chroma =
clip_chroma(matrix_out, display_white, Y, Ych_in[2], Ych_in[3], Ych_in[1]);
1945 dt_aligned_pixel_simd_t RGB_out
1946 = Ych_to_pipe_RGB_simd((dt_aligned_pixel_simd_t){
Y, new_chroma, Ych_in[2], Ych_in[3] },
1947 matrix_out0, matrix_out1, matrix_out2);
1955static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
1956gamut_mapping_simd(dt_aligned_pixel_simd_t Ych_final,
const dt_aligned_pixel_simd_t Ych_original,
1957 const dt_colormatrix_t output_matrix,
const dt_aligned_pixel_simd_t input_matrix0,
1958 const dt_aligned_pixel_simd_t input_matrix1,
const dt_aligned_pixel_simd_t input_matrix2,
1959 const dt_aligned_pixel_simd_t output_matrix0,
const dt_aligned_pixel_simd_t output_matrix1,
1960 const dt_aligned_pixel_simd_t output_matrix2,
1961 const dt_colormatrix_t export_output_matrix,
const dt_aligned_pixel_simd_t export_input_matrix0,
1962 const dt_aligned_pixel_simd_t export_input_matrix1,
const dt_aligned_pixel_simd_t export_input_matrix2,
1963 const dt_aligned_pixel_simd_t export_output_matrix0,
const dt_aligned_pixel_simd_t export_output_matrix1,
1964 const dt_aligned_pixel_simd_t export_output_matrix2,
const float display_black,
1965 const float display_white,
const float saturation,
const int use_output_profile)
1968 Ych_final[2] = Ych_original[2];
1969 Ych_final[3] = Ych_original[3];
1975 Ych_final = filmic_desaturate_v4(Ych_original, Ych_final, saturation);
1976 Ych_final = gamut_check_Yrg_filmic_simd(Ych_final);
1978 if(!use_output_profile)
1982 return gamut_check_RGB_simd(output_matrix, input_matrix0, input_matrix1, input_matrix2,
1983 output_matrix0, output_matrix1, output_matrix2,
1984 display_black, display_white, Ych_final);
1989 dt_aligned_pixel_simd_t pix_out
1990 = gamut_check_RGB_simd(export_output_matrix, export_input_matrix0, export_input_matrix1, export_input_matrix2,
1991 export_output_matrix0, export_output_matrix1, export_output_matrix2,
1992 display_black, display_white, Ych_final);
1995 const dt_aligned_pixel_simd_t
LMS
1996 = dt_mat3x4_mul_vec4(pix_out, export_input_matrix0, export_input_matrix1, export_input_matrix2);
1998 return dt_mat3x4_mul_vec4(
LMS, output_matrix0, output_matrix1, output_matrix2);
2019 const int use_output_profile = (export_profile != NULL);
2020 if(use_output_profile)
2031 return use_output_profile;
2068 simd_matrices->
input[
row] = dt_colormatrix_row_to_simd(input_matrix_t,
row);
2069 simd_matrices->
output[
row] = dt_colormatrix_row_to_simd(output_matrix_t,
row);
2070 simd_matrices->
export_input[
row] = dt_colormatrix_row_to_simd(export_input_matrix_t,
row);
2071 simd_matrices->
export_output[
row] = dt_colormatrix_row_to_simd(export_output_matrix_t,
row);
2075static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
2076norm_tone_mapping_v4_simd(
const dt_aligned_pixel_simd_t pix_in,
2081 const float norm_min,
const float norm_max)
2087 const dt_aligned_pixel_simd_t ratios = pix_in /
dt_simd_set1(norm);
2095 spline.
y[0], spline.
y[4]),
2102static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
2108 dt_aligned_pixel_simd_t pix_out = pix_in;
2109 for(
size_t c = 0;
c < 3;
c++)
2126 const size_t width,
const size_t height,
const size_t ch,
2128 const float display_black,
const float display_white)
2137 export_output_matrix, work_profile, export_profile);
2145#pragma omp parallel for default(none) \
2146 dt_omp_firstprivate(width, height, ch, data, in, out, work_profile, input_matrix, output_matrix, \
2147 variant, spline, display_white, display_black, export_input_matrix, export_output_matrix, \
2148 use_output_profile, norm_min, norm_max, simd_matrices) \
2151 for(
size_t k = 0; k <
height *
width * ch; k += ch)
2154 const dt_aligned_pixel_simd_t pix_out
2155 = norm_tone_mapping_v4_simd(pix_in, variant, work_profile, data, spline, norm_min, norm_max);
2158 const dt_aligned_pixel_simd_t Ych_original = pipe_RGB_to_Ych_simd(pix_in, simd_matrices.
input[0],
2159 simd_matrices.
input[1], simd_matrices.
input[2]);
2160 const dt_aligned_pixel_simd_t Ych_final = pipe_RGB_to_Ych_simd(pix_out, simd_matrices.
input[0],
2161 simd_matrices.
input[1], simd_matrices.
input[2]);
2163 dt_store_simd_nontemporal(
out + k,
2164 gamut_mapping_simd(Ych_final, Ych_original, output_matrix,
2165 simd_matrices.
input[0], simd_matrices.
input[1], simd_matrices.
input[2],
2167 export_output_matrix,
2170 display_black, display_white, data->
saturation, use_output_profile));
2180 const size_t width,
const size_t height,
const size_t ch,
2182 const float display_black,
const float display_white)
2192 export_output_matrix, work_profile, export_profile);
2196#pragma omp parallel for default(none) \
2197 dt_omp_firstprivate(width, height, ch, data, in, out, work_profile, input_matrix, output_matrix, \
2198 variant, spline, display_white, display_black, export_input_matrix, export_output_matrix, \
2199 use_output_profile, simd_matrices) \
2202 for(
size_t k = 0; k <
height *
width * ch; k += ch)
2205 const dt_aligned_pixel_simd_t pix_out = RGB_tone_mapping_v4_simd(pix_in, data, spline);
2206 const dt_aligned_pixel_simd_t Ych_original = pipe_RGB_to_Ych_simd(pix_in, simd_matrices.
input[0],
2207 simd_matrices.
input[1], simd_matrices.
input[2]);
2208 dt_aligned_pixel_simd_t Ych_final = pipe_RGB_to_Ych_simd(pix_out, simd_matrices.
input[0],
2209 simd_matrices.
input[1], simd_matrices.
input[2]);
2211 Ych_final[1] = fminf(Ych_original[1], Ych_final[1]);
2213 dt_store_simd_nontemporal(
out + k,
2214 gamut_mapping_simd(Ych_final, Ych_original, output_matrix,
2215 simd_matrices.
input[0], simd_matrices.
input[1], simd_matrices.
input[2],
2217 export_output_matrix,
2220 display_black, display_white, data->
saturation, use_output_profile));
2226static inline void filmic_v5(
const float *
const restrict in,
float *
const restrict
out,
2231 const size_t width,
const size_t height,
const size_t ch,
2232 const float display_black,
const float display_white)
2242 export_output_matrix, work_profile, export_profile);
2250#pragma omp parallel for default(none) \
2251 dt_omp_firstprivate(width, height, ch, data, in, out, work_profile, input_matrix, output_matrix, \
2252 spline, display_white, display_black, norm_min, norm_max, export_input_matrix, export_output_matrix, \
2253 use_output_profile, simd_matrices) \
2256 for(
size_t k = 0; k <
height *
width * ch; k += ch)
2259 const dt_aligned_pixel_simd_t naive_rgb = RGB_tone_mapping_v4_simd(pix_in, data, spline);
2260 const dt_aligned_pixel_simd_t max_rgb
2263 const dt_aligned_pixel_simd_t pix_out
2267 const dt_aligned_pixel_simd_t Ych_original = pipe_RGB_to_Ych_simd(pix_in, simd_matrices.
input[0],
2268 simd_matrices.
input[1], simd_matrices.
input[2]);
2270 dt_aligned_pixel_simd_t Ych_final = pipe_RGB_to_Ych_simd(pix_out, simd_matrices.
input[0],
2271 simd_matrices.
input[1], simd_matrices.
input[2]);
2273 Ych_final[1] = fminf(Ych_original[1], Ych_final[1]);
2275 dt_store_simd_nontemporal(
out + k,
2276 gamut_mapping_simd(Ych_final, Ych_original, output_matrix,
2277 simd_matrices.
input[0], simd_matrices.
input[1], simd_matrices.
input[2],
2279 export_output_matrix,
2282 display_black, display_white, 0.f, use_output_profile));
2292#pragma omp parallel for default(none) dt_omp_firstprivate(width, height, out, mask) schedule(static)
2302static inline void compute_ratios(
const float *
const restrict in,
float *
const restrict norms,
2303 float *
const restrict ratios,
2308#pragma omp parallel for default(none) \
2309 dt_omp_firstprivate(width, height, norms, ratios, in, work_profile, variant) schedule(static)
2315 norms[k / 4] = norm;
2316 dt_store_simd_nontemporal(ratios + k, pix_in /
dt_simd_set1(norm));
2322static inline void restore_ratios(
float *
const restrict ratios,
const float *
const restrict norms,
2326 #pragma omp parallel for default(none) \
2327 dt_omp_firstprivate(width, height, norms, ratios) \
2328 schedule(simd:static)
2333 const float norm = norms[k];
2338 dt_store_simd_nontemporal(ratios + 4 * k, ratio);
2346 const int scales =
get_scales(roi_in, piece);
2347 const int max_filter_radius = (1 << scales);
2351 tiling->factor_cl = 9.0f;
2354 tiling->maxbuf_cl = 1.0f;
2356 tiling->overlap = max_filter_radius;
2363 const void *
const restrict ivoid,
2364 void *
const restrict ovoid)
2372 const size_t ch = 4;
2383 float *restrict in = (
float *)ivoid;
2384 float *
const restrict
out = (
float *)ovoid;
2389 const float scale = fmaxf(1.f / roi_in->
scale, 1.f);
2408 if(recover_highlights && !reconstructed)
2415 if(recover_highlights && mask && reconstructed)
2446 if(!norms || !ratios)
2463 data, piece, roi_in, roi_out))
2488 const float white_display = powf(data->spline.y[4], data->
output_power);
2489 const float black_display = powf(data->spline.y[0], data->
output_power);
2493 filmic_v5(in,
out, work_profile, export_profile, data, data->spline, roi_out->
width,
2494 roi_out->
height, ch, black_display, white_display);
2507 roi_out->
height, ch, data->
version, black_display, white_display);
2520 roi_out->
height, ch, data->
version, black_display, white_display);
2532static inline cl_int reconstruct_highlights_cl(
const dt_dev_pixelpipe_t *pipe, cl_mem in, cl_mem mask, cl_mem reconstructed,
2538 const int devid = pipe->
devid;
2541 size_t sizes[] = { ROUNDUPDWD(
width, devid), ROUNDUPDHT(
height, devid), 1 };
2544 const int scales =
get_scales(roi_in, piece);
2547 cl_mem LF_even = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float) * 4);
2548 cl_mem LF_odd = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float) * 4);
2549 cl_mem HF_RGB = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float) * 4);
2550 cl_mem HF_grey = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float) * 4);
2553 cl_mem temp = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float) * 4);;
2555 if(!LF_even || !LF_odd || !HF_RGB || !HF_grey || !temp)
2557 err = CL_MEM_OBJECT_ALLOCATION_FAILURE;
2568 if(err != CL_SUCCESS)
goto error;
2586 for(
int s = 0; s < scales; ++s)
2608 const int mult = 1 << s;
2611 const int clamp_lf = 1;
2619 if(err != CL_SUCCESS)
goto error;
2628 if(err != CL_SUCCESS)
goto error;
2638 if(err != CL_SUCCESS)
goto error;
2641 size_t origin[] = { 0, 0, 0 };
2642 err = dt_opencl_enqueue_copy_image(devid, HF_RGB, HF_grey, origin, origin, sizes);
2643 if(err != CL_SUCCESS)
goto error;
2646 const int blur_size = 1;
2647 const int clamp_hf = 0;
2655 if(err != CL_SUCCESS)
goto error;
2664 if(err != CL_SUCCESS)
goto error;
2684 if(err != CL_SUCCESS)
goto error;
2705 const int devid = pipe->
devid;
2709 size_t sizes[] = { ROUNDUPDWD(
width, devid), ROUNDUPDHT(
height, devid), 1 };
2712 cl_mem inpainted = NULL;
2713 cl_mem reconstructed = NULL;
2715 cl_mem ratios = NULL;
2716 cl_mem norms = NULL;
2721 const int use_work_profile = (work_profile == NULL) ? 0 : 1;
2730 export_output_matrix, work_profile, export_profile);
2735 float input_matrix_3x4[12];
2736 float output_matrix_3x4[12];
2740 cl_mem input_matrix_cl = dt_opencl_copy_host_to_device_constant(devid,
sizeof(input_matrix_3x4), input_matrix_3x4);
2741 cl_mem output_matrix_cl = dt_opencl_copy_host_to_device_constant(devid,
sizeof(output_matrix_3x4), output_matrix_3x4);
2742 cl_mem export_input_matrix_cl = NULL;
2743 cl_mem export_output_matrix_cl = NULL;
2745 cl_mem dev_profile_info = NULL;
2746 cl_mem dev_profile_lut = NULL;
2748 cl_float *profile_lut_cl = NULL;
2750 cl_mem clipped = NULL;
2752 err = dt_ioppr_build_iccprofile_params_cl(work_profile, devid, &profile_info_cl, &profile_lut_cl,
2753 &dev_profile_info, &dev_profile_lut);
2754 if(err != CL_SUCCESS)
goto error;
2756 if(use_output_profile)
2758 float export_input_matrix_3x4[12];
2759 float export_output_matrix_3x4[12];
2762 export_input_matrix_cl = dt_opencl_copy_host_to_device_constant(devid,
sizeof(export_input_matrix_3x4), export_input_matrix_3x4);
2763 export_output_matrix_cl = dt_opencl_copy_host_to_device_constant(devid,
sizeof(export_output_matrix_3x4), export_output_matrix_3x4);
2767 const float scale = fmaxf(1.f / roi_in->
scale, 1.f);
2769 uint32_t is_clipped = 0;
2770 clipped = dt_opencl_alloc_device_buffer(devid,
sizeof(uint32_t));
2771 err = dt_opencl_write_buffer_to_device(devid, &is_clipped, clipped, 0,
sizeof(uint32_t), CL_TRUE);
2772 if(err != CL_SUCCESS)
goto error;
2775 mask = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float));
2784 if(err != CL_SUCCESS)
goto error;
2787 err = dt_opencl_read_buffer_from_device(devid, &is_clipped, clipped, 0,
sizeof(uint32_t), CL_TRUE);
2788 if(err != CL_SUCCESS)
goto error;
2805 dt_ioppr_free_iccprofile_params_cl(&profile_info_cl, &profile_lut_cl, &dev_profile_info, &dev_profile_lut);
2813 const float noise_level =
d->noise_level / scale;
2814 inpainted = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float) * 4);
2824 if(err != CL_SUCCESS)
goto error;
2827 reconstructed = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float) * 4);
2829 if(err != CL_SUCCESS)
goto error;
2833 if(
d->high_quality_reconstruction > 0)
2835 ratios = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float) * 4);
2836 norms = dt_opencl_alloc_device(devid, sizes[0], sizes[1],
sizeof(
float));
2840 for(
int i = 0;
i <
d->high_quality_reconstruction;
i++)
2850 if(err != CL_SUCCESS)
goto error;
2854 if(err != CL_SUCCESS)
goto error;
2863 if(err != CL_SUCCESS)
goto error;
2881 const float white_display = powf(spline.
y[4],
d->output_power);
2882 const float black_display = powf(spline.
y[0],
d->output_power);
2921 if(err != CL_SUCCESS)
goto error;
2963 if(err != CL_SUCCESS)
goto error;
2967 dt_ioppr_free_iccprofile_params_cl(&profile_info_cl, &profile_lut_cl, &dev_profile_info, &dev_profile_lut);
2975 dt_ioppr_free_iccprofile_params_cl(&profile_info_cl, &profile_lut_cl, &dev_profile_info, &dev_profile_lut);
3001 const float prev_grey =
p->grey_point_source;
3002 p->grey_point_source = CLAMP(100.f * grey, 0.001f, 100.0f);
3003 const float grey_var = log2f(prev_grey /
p->grey_point_source);
3004 p->black_point_source =
p->black_point_source - grey_var;
3005 p->white_point_source =
p->white_point_source + grey_var;
3006 p->output_power = logf(
p->grey_point_target / 100.0f)
3007 / logf(-
p->black_point_source / (
p->white_point_source -
p->black_point_source));
3016 gtk_widget_queue_draw(self->
widget);
3030 float EVmin = CLAMP(log2f(black / (
p->grey_point_source / 100.0f)), -16.0f, -1.0f);
3031 EVmin *= (1.0f +
p->security_factor / 100.0f);
3033 p->black_point_source = fmaxf(EVmin, -16.0f);
3034 p->output_power = logf(
p->grey_point_target / 100.0f)
3035 / logf(-
p->black_point_source / (
p->white_point_source -
p->black_point_source));
3042 gtk_widget_queue_draw(self->
widget);
3057 float EVmax = CLAMP(log2f(white / (
p->grey_point_source / 100.0f)), 1.0f, 16.0f);
3058 EVmax *= (1.0f +
p->security_factor / 100.0f);
3060 p->white_point_source = EVmax;
3061 p->output_power = logf(
p->grey_point_target / 100.0f)
3062 / logf(-
p->black_point_source / (
p->white_point_source -
p->black_point_source));
3069 gtk_widget_queue_draw(self->
widget);
3083 p->grey_point_source = CLAMP(100.f * grey, 0.001f, 100.0f);
3088 float EVmax = CLAMP(log2f(white / (
p->grey_point_source / 100.0f)), 1.0f, 16.0f);
3089 EVmax *= (1.0f +
p->security_factor / 100.0f);
3093 float EVmin = CLAMP(log2f(black / (
p->grey_point_source / 100.0f)), -16.0f, -1.0f);
3094 EVmin *= (1.0f +
p->security_factor / 100.0f);
3096 p->black_point_source = fmaxf(EVmin, -16.0f);
3097 p->white_point_source = EVmax;
3098 p->output_power = logf(
p->grey_point_target / 100.0f)
3099 / logf(-
p->black_point_source / (
p->white_point_source -
p->black_point_source));
3108 gtk_widget_queue_draw(self->
widget);
3116 (
void *)picker, (
void *)pipe,
3123 if(picker ==
g->grey_point_source)
3125 else if(picker ==
g->black_point_source)
3127 else if(picker ==
g->white_point_source)
3129 else if(picker ==
g->auto_button)
3137 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->
off),
TRUE);
3144 g->show_mask = !(
g->show_mask);
3149 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
g->show_highlight_mask), !
g->show_mask);
3162 float grey_display = 0.4638f;
3163 gboolean clamping =
FALSE;
3168 grey_display = powf(CLAMP(
p->grey_point_target,
p->black_point_target,
p->white_point_target) / 100.0f,
3169 1.0f / (
p->output_power));
3174 grey_display = powf(0.1845f, 1.0f / (
p->output_power));
3177 const float white_source =
p->white_point_source;
3178 const float black_source =
p->black_point_source;
3179 const float dynamic_range = white_source - black_source;
3182 const float black_log = 0.0f;
3183 const float grey_log = fabsf(
p->black_point_source) / dynamic_range;
3184 const float white_log = 1.0f;
3187 float black_display, white_display;
3195 black_display = CLAMP(
p->black_point_target, 0.0f,
p->grey_point_target) / 100.0f;
3196 white_display = fmaxf(
p->white_point_target,
p->grey_point_target) / 100.0f;
3201 black_display = powf(CLAMP(
p->black_point_target, 0.0f,
p->grey_point_target) / 100.0f,
3202 1.0f / (
p->output_power));
3204 = powf(fmaxf(
p->white_point_target,
p->grey_point_target) / 100.0f, 1.0f / (
p->output_power));
3207 float toe_log, shoulder_log, toe_display, shoulder_display, contrast;
3208 float balance = CLAMP(
p->balance, -50.0f, 50.0f) / 100.0f;
3211 float latitude = CLAMP(
p->latitude, 0.0f, 100.0f) / 100.0f * dynamic_range;
3212 contrast = CLAMP(
p->contrast, 1.00001f, 6.0f);
3216 toe_log = grey_log - latitude / dynamic_range * fabsf(black_source / dynamic_range);
3217 shoulder_log = grey_log + latitude / dynamic_range * fabsf(white_source / dynamic_range);
3220 float linear_intercept = grey_display - (contrast * grey_log);
3223 toe_display = (toe_log * contrast + linear_intercept);
3224 shoulder_display = (shoulder_log * contrast + linear_intercept);
3227 const float norm = sqrtf(contrast * contrast + 1.0f);
3230 const float coeff = -((2.0f * latitude) / dynamic_range) * balance;
3232 toe_display +=
coeff * contrast / norm;
3233 shoulder_display +=
coeff * contrast / norm;
3234 toe_log +=
coeff / norm;
3235 shoulder_log +=
coeff / norm;
3261 spline->
x[0] = black_log;
3262 spline->
x[1] = toe_log;
3263 spline->
x[2] = grey_log;
3264 spline->
x[3] = shoulder_log;
3265 spline->
x[4] = white_log;
3267 spline->
y[0] = black_display;
3268 spline->
y[1] = toe_display;
3269 spline->
y[2] = grey_display;
3270 spline->
y[3] = shoulder_display;
3271 spline->
y[4] = white_display;
3276 spline->
type[0] =
p->shadows;
3277 spline->
type[1] =
p->highlights;
3284 const double Tl = spline->
x[1];
3285 const double Tl2 = Tl * Tl;
3286 const double Tl3 = Tl2 * Tl;
3287 const double Tl4 = Tl3 * Tl;
3289 const double Sl = spline->
x[3];
3290 const double Sl2 = Sl * Sl;
3291 const double Sl3 = Sl2 * Sl;
3292 const double Sl4 = Sl3 * Sl;
3302 spline->
M2[2] = contrast;
3303 spline->
M1[2] = spline->
y[1] - spline->
M2[2] * spline->
x[1];
3304 spline->
M3[2] = 0.f;
3305 spline->
M4[2] = 0.f;
3306 spline->
M5[2] = 0.f;
3314 Tl4, Tl3, Tl2, Tl, 1.,
3315 4. * Tl3, 3. * Tl2, 2. * Tl, 1., 0.,
3316 12. * Tl2, 6. * Tl, 2., 0., 0. };
3318 double b0[
ORDER_4] = { spline->
y[0], 0., spline->
y[1], spline->
M2[2], 0. };
3322 spline->
M5[0] = b0[0];
3323 spline->
M4[0] = b0[1];
3324 spline->
M3[0] = b0[2];
3325 spline->
M2[0] = b0[3];
3326 spline->
M1[0] = b0[4];
3333 3. * Tl2, 2. * Tl, 1., 0.,
3334 6. * Tl, 2., 0., 0. };
3336 double b0[
ORDER_3] = { spline->
y[0], spline->
y[1], spline->
M2[2], 0. };
3340 spline->
M5[0] = 0.0f;
3341 spline->
M4[0] = b0[0];
3342 spline->
M3[0] = b0[1];
3343 spline->
M2[0] = b0[2];
3344 spline->
M1[0] = b0[3];
3348 const float P1[2] = { black_log, black_display };
3349 const float P0[2] = { toe_log, toe_display };
3350 const float x = P0[0] - P1[0];
3351 const float y = P0[1] - P1[1];
3352 const float g = contrast;
3353 const float b =
g / (2.f * y) + (sqrtf(
sqf(
x *
g / y + 1.f) - 4.f) - 1.f) / (2.f *
x);
3354 const float c = y /
g * (
b *
sqf(
x) +
x) / (
b *
sqf(
x) +
x - (y /
g));
3355 const float a =
c *
g;
3359 spline->
M4[0] = toe_display;
3368 3. * Sl2, 2. * Sl, 1., 0.,
3369 6. * Sl, 2., 0., 0. };
3371 double b1[
ORDER_3] = { spline->
y[4], spline->
y[3], spline->
M2[2], 0. };
3375 spline->
M5[1] = 0.0f;
3376 spline->
M4[1] = b1[0];
3377 spline->
M3[1] = b1[1];
3378 spline->
M2[1] = b1[2];
3379 spline->
M1[1] = b1[3];
3386 Sl4, Sl3, Sl2, Sl, 1.,
3387 4. * Sl3, 3. * Sl2, 2. * Sl, 1., 0.,
3388 12. * Sl2, 6. * Sl, 2., 0., 0. };
3390 double b1[
ORDER_4] = { spline->
y[4], 0., spline->
y[3], spline->
M2[2], 0. };
3394 spline->
M5[1] = b1[0];
3395 spline->
M4[1] = b1[1];
3396 spline->
M3[1] = b1[2];
3397 spline->
M2[1] = b1[3];
3398 spline->
M1[1] = b1[4];
3402 const float P1[2] = { white_log, white_display };
3403 const float P0[2] = { shoulder_log, shoulder_display };
3404 const float x = P1[0] - P0[0];
3405 const float y = P1[1] - P0[1];
3406 const float g = contrast;
3407 const float b =
g / (2.f * y) + (sqrtf(
sqf(
x *
g / y + 1.f) - 4.f) - 1.f) / (2.f *
x);
3408 const float c = y /
g * (
b *
sqf(
x) +
x) / (
b *
sqf(
x) +
x - (y /
g));
3409 const float a =
c *
g;
3413 spline->
M4[1] = shoulder_display;
3425 float grey_source = 0.1845f, grey_display = 0.4638f;
3429 grey_source =
p->grey_point_source / 100.0f;
3430 grey_display = powf(
p->grey_point_target / 100.0f, 1.0f / (
p->output_power));
3435 grey_source = 0.1845f;
3436 grey_display = powf(0.1845f, 1.0f / (
p->output_power));
3440 const float white_source =
p->white_point_source;
3441 const float black_source =
p->black_point_source;
3442 const float dynamic_range = white_source - black_source;
3445 const float grey_log = fabsf(
p->black_point_source) / dynamic_range;
3448 float contrast =
p->contrast;
3453 contrast = 1.0001f * grey_display / grey_log;
3457 d->dynamic_range = dynamic_range;
3458 d->black_source = black_source;
3459 d->grey_source = grey_source;
3460 d->output_power =
p->output_power;
3461 d->contrast = contrast;
3462 d->version =
p->version;
3463 d->spline_version =
p->spline_version;
3464 d->preserve_color =
p->preserve_color;
3465 d->high_quality_reconstruction =
p->high_quality_reconstruction;
3466 d->noise_level =
p->noise_level;
3473 d->saturation =
p->saturation / 100.0f;
3475 d->saturation = (2.0f *
p->saturation / 100.0f + 1.0f);
3477 d->sigma_toe = powf(
d->spline.latitude_min / 3.0f, 2.0f);
3478 d->sigma_shoulder = powf((1.0f -
d->spline.latitude_max) / 3.0f, 2.0f);
3480 d->reconstruct_threshold = powf(2.0f, white_source +
p->reconstruct_threshold) * grey_source;
3481 d->reconstruct_feather = exp2f(12.f /
p->reconstruct_feather);
3484 d->normalize =
d->reconstruct_feather /
d->reconstruct_threshold;
3485 d->reconstruct_structure_vs_texture = (
p->reconstruct_structure_vs_texture / 100.0f + 1.f) / 2.f;
3486 d->reconstruct_bloom_vs_details = (
p->reconstruct_bloom_vs_details / 100.0f + 1.f) / 2.f;
3487 d->reconstruct_grey_vs_color = (
p->reconstruct_grey_vs_color / 100.0f + 1.f) / 2.f;
3497 gint mask_was_shown =
g->show_mask;
3499 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
g->show_highlight_mask),
FALSE);
3521 float shoulder = 0.0f;
3538 &
p->latitude, &
p->balance);
3552 g->gui_show_labels =
dt_conf_get_int(
"plugins/darkroom/filmicrgb/graph_show_labels");
3554 g->gui_sizes_inited =
FALSE;
3558 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
g->auto_hardness),
p->auto_hardness);
3559 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
g->custom_grey),
p->custom_grey);
3570 d->white_point_source =
module->so->get_f("white_point_source")->Float.Default;
3571 d->output_power =
module->so->get_f("output_power")->Float.Default;
3582 d->white_point_source = exposure + 2.45f;
3583 d->black_point_source =
d->white_point_source - 12.f;
3584 d->output_power = logf(
d->grey_point_target / 100.0f)
3585 / logf(-
d->black_point_source / (
d->white_point_source -
d->black_point_source));
3587 module->workflow_enabled = TRUE;
3594 const int program = 22;
3609 const int wavelets = 35;
3642 double destination_y, gboolean show_head)
3644 cairo_move_to(cr, origin_x, origin_y);
3645 cairo_line_to(cr, destination_x, destination_y);
3651 const float angle_arrow = 45.f / 360.f *
M_PI;
3652 const float angle_trunk = atan2f((destination_y - origin_y), (destination_x - origin_x));
3655 const float x_1 = destination_x + radius / sinf(angle_arrow + angle_trunk);
3656 const float y_1 = destination_y + radius / cosf(angle_arrow + angle_trunk);
3658 const float x_2 = destination_x - radius / sinf(-angle_arrow + angle_trunk);
3659 const float y_2 = destination_y - radius / cosf(-angle_arrow + angle_trunk);
3661 cairo_move_to(cr, x_1, y_1);
3662 cairo_line_to(cr, destination_x, destination_y);
3663 cairo_line_to(cr, x_2, y_2);
3671 if(!
g->gui_sizes_inited)
return;
3686 cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha);
3691 cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha * 0.5);
3701 const float scale = 0.85;
3702 cairo_scale(cr, scale, scale);
3703 button->
icon(cr, -scale * button->
w / 2., -scale * button->
h / 2., scale * button->
w, scale * button->
h, 0, NULL);
3716 gtk_widget_get_allocation(widget, &
g->allocation);
3718 cairo_surface_t *cst =
3720 PangoFontDescription *desc =
3722 cairo_t *cr = cairo_create(cst);
3723 PangoLayout *layout = pango_cairo_create_layout(cr);
3725 pango_layout_set_font_description(layout, desc);
3726 pango_cairo_context_set_resolution(pango_layout_get_context(layout),
darktable.
gui->
dpi);
3727 g->context = gtk_widget_get_style_context(widget);
3732 const gint font_size = pango_font_description_get_size(desc);
3733 pango_font_description_set_size(desc, 0.95 * font_size);
3734 pango_layout_set_font_description(layout, desc);
3737 g_strlcpy(text,
"X",
sizeof(text));
3738 pango_layout_set_text(layout, text, -1);
3739 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
3740 g->line_height =
g->ink.height;
3743 g_strlcpy(text,
"-",
sizeof(text));
3744 pango_layout_set_text(layout, text, -1);
3745 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
3746 g->sign_width =
g->ink.width / 2.0;
3749 g_strlcpy(text,
"0",
sizeof(text));
3750 pango_layout_set_text(layout, text, -1);
3751 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
3752 g->zero_width =
g->ink.width;
3758 float margin_bottom;
3759 if(
g->gui_show_labels)
3762 margin_left = 3. *
g->zero_width + 2. *
g->inset;
3763 margin_bottom = 2. *
g->line_height + 4. *
g->inset;
3767 margin_left =
g->inset;
3768 margin_bottom =
g->inset;
3771 const float margin_top = 2. *
g->line_height +
g->inset;
3774 g->graph_width =
g->allocation.width - margin_right - margin_left;
3775 g->graph_height =
g->allocation.height - margin_bottom - margin_top;
3777 gtk_render_background(
g->context, cr, 0, 0,
g->allocation.width,
g->allocation.height);
3783 g->buttons[
i].right =
g->allocation.width;
3787 g->buttons[
i].w =
g->buttons[
i].right -
g->buttons[
i].left;
3788 g->buttons[
i].h =
g->buttons[
i].bottom -
g->buttons[
i].top;
3789 g->buttons[
i].state = GTK_STATE_FLAG_NORMAL;
3792 g->gui_sizes_inited =
TRUE;
3802 const float grey =
p->grey_point_source / 100.f;
3803 const float DR =
p->white_point_source -
p->black_point_source;
3806 cairo_translate(cr, margin_left, margin_top);
3808 cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
3811 pango_font_description_set_size(desc, font_size);
3812 pango_layout_set_font_description(layout, desc);
3814 g_strlcpy(text, _(
"look only"),
sizeof(text));
3816 g_strlcpy(text, _(
"look + mapping (lin)"),
sizeof(text));
3818 g_strlcpy(text, _(
"look + mapping (log)"),
sizeof(text));
3820 g_strlcpy(text, _(
"dynamic range mapping"),
sizeof(text));
3822 pango_layout_set_text(layout, text, -1);
3823 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
3827 cairo_rectangle(cr,
g->allocation.width - margin_left -
g->ink.width -
g->ink.x - 2. *
g->inset,
3828 -
g->line_height -
g->inset - 0.5 *
g->ink.height -
g->ink.y -
g->inset,
3829 g->ink.width + 3. *
g->inset,
g->ink.height + 2. *
g->inset);
3834 cairo_move_to(cr,
g->allocation.width - margin_left -
g->ink.width -
g->ink.x -
g->inset,
3835 -
g->line_height -
g->inset - 0.5 *
g->ink.height -
g->ink.y);
3836 pango_cairo_show_layout(cr, layout);
3840 pango_font_description_set_size(desc, 0.95 * font_size);
3841 pango_layout_set_font_description(layout, desc);
3847 cairo_rectangle(cr, 0, 0,
g->graph_width,
g->graph_height);
3849 cairo_fill_preserve(cr);
3859 cairo_scale(cr, 1., -1.);
3860 cairo_translate(cr, 0., -
g->graph_height);
3871 cairo_move_to(cr, 0,
g->graph_height);
3872 cairo_line_to(cr,
g->graph_width, 0);
3878 const float saturation = (2.0f *
p->saturation / 100.0f + 1.0f);
3879 const float sigma_toe = powf(
g->spline.latitude_min / 3.0f, 2.0f);
3880 const float sigma_shoulder = powf((1.0f -
g->spline.latitude_max) / 3.0f, 2.0f);
3882 cairo_set_source_rgb(cr, .5, .5, .5);
3892 cairo_move_to(cr, 0,
3894 for(
int k = 1; k < 256; k++)
3896 float x = k / 255.0;
3904 cairo_line_to(cr,
x *
g->graph_width,
g->graph_height * (1.0 - y));
3909 cairo_move_to(cr, 0,
3911 for(
int k = 1; k < 256; k++)
3913 float x = k / 255.0;
3921 cairo_line_to(cr,
x *
g->graph_width,
g->graph_height * (1.0 - y));
3927 float x_start = 0.f;
3934 g->spline.M5,
g->spline.latitude_min,
g->spline.latitude_max,
g->spline.type));
3937 y_start = powf(y_start,
p->output_power);
3941 cairo_move_to(cr, 0,
g->graph_height * (1.0 - y_start));
3943 for(
int k = 1; k < 256; k++)
3947 float x = powf(k / 255.0f, 2.4f);
3956 g->spline.latitude_min,
g->spline.latitude_max,
g->spline.type);
3964 const float margin = 1
E-5;
3965 if(y >
g->spline.y[4] + margin)
3968 cairo_set_source_rgb(cr, 0.75, .5, 0.);
3970 else if(y < g->spline.
y[0] - margin)
3973 cairo_set_source_rgb(cr, 0.75, .5, 0.);
3981 y = powf(y,
p->output_power);
3985 cairo_line_to(cr,
x *
g->graph_width,
g->graph_height * (1.0 - y));
3987 cairo_move_to(cr,
x *
g->graph_width,
g->graph_height * (1.0 - y));
3999 float x_grey =
g->spline.x[2];
4000 float y_grey =
g->spline.y[2];
4005 y_grey = powf(y_grey,
p->output_power);
4013 cairo_set_source_rgb(cr, 0.75, 0.5, 0.0);
4014 cairo_arc(cr, x_grey *
g->graph_width, (1.0 - y_grey) *
g->graph_height,
DT_PIXEL_APPLY_DPI(6), 0,
4020 float x_black = 0.f;
4021 float y_black = 0.f;
4023 float x_white = 1.f;
4024 float y_white = 1.f;
4026 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);
4027 const float central_slope_angle = atanf(central_slope) +
M_PI / 2.0f;
4029 for(
int k = 0; k < 5; k++)
4033 float x =
g->spline.x[k];
4034 float y =
g->spline.y[k];
4035 const float ymin =
g->spline.y[0];
4036 const float ymax =
g->spline.y[4];
4038 const float y_margin =
SAFETY_MARGIN * 1.1f * (ymax - ymin);
4039 gboolean red = (((k == 1) && (y - ymin <= y_margin))
4040 || ((k == 3) && (ymax - y <= y_margin)));
4041 float start_angle = 0.0f;
4042 float end_angle = 2.f *
M_PI;
4045 if(contrast_clamped)
4049 start_angle = central_slope_angle +
M_PI;
4050 end_angle = central_slope_angle;
4054 start_angle = central_slope_angle;
4055 end_angle = start_angle +
M_PI;
4062 y = powf(y,
p->output_power);
4082 if(red) cairo_set_source_rgb(cr, 0.8, 0.35, 0.35);
4085 cairo_arc(cr,
x *
g->graph_width, (1.0 - y) *
g->graph_height,
DT_PIXEL_APPLY_DPI(4), start_angle, end_angle);
4095 if(
g->gui_show_labels)
4098 const float x_legend_top =
g->graph_height + 0.5 *
g->line_height;
4102 snprintf(text,
sizeof(text),
"%.0f",
p->grey_point_target);
4103 pango_layout_set_text(layout, text, -1);
4104 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4105 cairo_move_to(cr, -2. *
g->inset -
g->ink.width -
g->ink.x,
4106 (1.0 - y_grey) *
g->graph_height - 0.5 *
g->ink.height -
g->ink.y);
4107 pango_cairo_show_layout(cr, layout);
4113 snprintf(text,
sizeof(text),
"%+.1f", 0.f);
4115 snprintf(text,
sizeof(text),
"%.0f",
p->grey_point_source);
4117 pango_layout_set_text(layout, text, -1);
4118 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4119 cairo_move_to(cr, x_grey *
g->graph_width - 0.5 *
g->ink.width -
g->ink.x, x_legend_top);
4120 pango_cairo_show_layout(cr, layout);
4125 snprintf(text,
sizeof(text),
"%.0f",
p->black_point_target);
4126 pango_layout_set_text(layout, text, -1);
4127 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4128 cairo_move_to(cr, -2. *
g->inset -
g->ink.width -
g->ink.x,
4129 (1.0 - y_black) *
g->graph_height - 0.5 *
g->ink.height -
g->ink.y);
4130 pango_cairo_show_layout(cr, layout);
4135 snprintf(text,
sizeof(text),
"%.0f",
p->white_point_target);
4136 pango_layout_set_text(layout, text, -1);
4137 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4138 cairo_move_to(cr, -2. *
g->inset -
g->ink.width -
g->ink.x,
4139 (1.0 - y_white) *
g->graph_height - 0.5 *
g->ink.height -
g->ink.y);
4140 pango_cairo_show_layout(cr, layout);
4146 snprintf(text,
sizeof(text),
"%+.1f",
p->black_point_source);
4148 snprintf(text,
sizeof(text),
"%.0f", exp2f(
p->black_point_source) *
p->grey_point_source);
4150 pango_layout_set_text(layout, text, -1);
4151 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4152 cairo_move_to(cr, x_black *
g->graph_width - 0.5 *
g->ink.width -
g->ink.x, x_legend_top);
4153 pango_cairo_show_layout(cr, layout);
4159 snprintf(text,
sizeof(text),
"%+.1f",
p->white_point_source);
4163 snprintf(text,
sizeof(text),
"%.0f \342\206\222", 100.f);
4165 snprintf(text,
sizeof(text),
"%.0f", exp2f(
p->white_point_source) *
p->grey_point_source);
4168 pango_layout_set_text(layout, text, -1);
4169 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4171 fminf(x_white, 1.f) *
g->graph_width - 0.5 *
g->ink.width -
g->ink.x
4172 + 2. * (x_white > 1.f) *
g->sign_width,
4174 pango_cairo_show_layout(cr, layout);
4183 PangoStyle backup = pango_font_description_get_style(desc);
4184 pango_font_description_set_style(desc, PANGO_STYLE_ITALIC);
4185 pango_layout_set_font_description(layout, desc);
4187 snprintf(text,
sizeof(text), _(
"(%.0f %%)"), exp2f(
p->white_point_source) *
p->grey_point_source);
4188 pango_layout_set_text(layout, text, -1);
4189 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4190 cairo_move_to(cr,
g->allocation.width -
g->ink.width -
g->ink.x - margin_left,
4191 g->graph_height + 3. *
g->inset +
g->line_height -
g->ink.y);
4192 pango_cairo_show_layout(cr, layout);
4196 pango_font_description_set_style(desc, backup);
4197 pango_layout_set_font_description(layout, desc);
4203 g_strlcpy(text, _(
"% display"),
sizeof(text));
4204 pango_layout_set_text(layout, text, -1);
4205 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4206 cairo_move_to(cr, -2. *
g->inset -
g->zero_width -
g->ink.x,
4207 -
g->line_height -
g->inset - 0.5 *
g->ink.height -
g->ink.y);
4208 pango_cairo_show_layout(cr, layout);
4215 g_strlcpy(text, _(
"EV scene"),
sizeof(text));
4219 g_strlcpy(text, _(
"% camera"),
sizeof(text));
4221 pango_layout_set_text(layout, text, -1);
4222 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4223 cairo_move_to(cr, 0.5 *
g->graph_width - 0.5 *
g->ink.width -
g->ink.x,
4224 g->graph_height + 3. *
g->inset +
g->line_height -
g->ink.y);
4225 pango_cairo_show_layout(cr, layout);
4232 cairo_identity_matrix(cr);
4238 const float display_DR = 12.f + log2f(
p->white_point_target / 100.f);
4240 const float y_display =
g->allocation.height / 3.f +
g->line_height;
4241 const float y_scene = 2. *
g->allocation.height / 3.f +
g->line_height;
4243 const float display_top = y_display -
g->line_height / 2;
4244 const float display_bottom = display_top +
g->line_height;
4246 const float scene_top = y_scene -
g->line_height / 2;
4247 const float scene_bottom = scene_top +
g->line_height;
4251 if(
g->gui_show_labels)
4255 g_strlcpy(text, _(
"display"),
sizeof(text));
4256 pango_layout_set_text(layout, text, -1);
4257 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4258 cairo_move_to(cr, 0., y_display - 0.5 *
g->ink.height -
g->ink.y);
4259 pango_cairo_show_layout(cr, layout);
4261 const float display_label_width =
g->ink.width;
4264 g_strlcpy(text, _(
"(%)"),
sizeof(text));
4265 pango_layout_set_text(layout, text, -1);
4266 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4267 cairo_move_to(cr, 0.5 * display_label_width - 0.5 *
g->ink.width -
g->ink.x,
4268 display_top - 4. *
g->inset -
g->ink.height -
g->ink.y);
4269 pango_cairo_show_layout(cr, layout);
4273 g_strlcpy(text, _(
"scene"),
sizeof(text));
4274 pango_layout_set_text(layout, text, -1);
4275 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4276 cairo_move_to(cr, 0., y_scene - 0.5 *
g->ink.height -
g->ink.y);
4277 pango_cairo_show_layout(cr, layout);
4279 const float scene_label_width =
g->ink.width;
4282 g_strlcpy(text, _(
"(EV)"),
sizeof(text));
4283 pango_layout_set_text(layout, text, -1);
4284 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4285 cairo_move_to(cr, 0.5 * scene_label_width - 0.5 *
g->ink.width -
g->ink.x,
4286 scene_bottom + 2. *
g->inset + 0. *
g->ink.height +
g->ink.y);
4287 pango_cairo_show_layout(cr, layout);
4292 dt_cairo_draw_arrow(cr, fminf(scene_label_width, display_label_width) / 2.f, y_scene -
g->line_height,
4293 fminf(scene_label_width, display_label_width) / 2.f,
4294 y_display +
g->line_height +
g->inset,
TRUE);
4296 column_left = fmaxf(display_label_width, scene_label_width) +
g->inset;
4304 const float display_HL_EV = -log2f(
p->grey_point_target /
p->white_point_target);
4305 const float display_LL_EV = display_DR - display_HL_EV;
4306 const float display_real_black_EV
4307 = -fmaxf(log2f(
p->black_point_target /
p->grey_point_target),
4308 -11.685887601778058f + display_HL_EV - log2f(
p->white_point_target / 100.f));
4309 const float scene_HL_EV =
p->white_point_source;
4310 const float scene_LL_EV = -
p->black_point_source;
4313 const float max_DR = ceilf(fmaxf(display_HL_EV, scene_HL_EV)) + ceilf(fmaxf(display_LL_EV, scene_LL_EV));
4314 const float EV = (column_right) / max_DR;
4318 const float grey_EV = fmaxf(ceilf(display_HL_EV), ceilf(scene_HL_EV));
4322 const float display_black_x = grey_x - display_real_black_EV * EV;
4323 const float display_DR_start_x = grey_x - display_LL_EV * EV;
4324 const float display_white_x = grey_x + display_HL_EV * EV;
4326 const float scene_black_x = grey_x - scene_LL_EV * EV;
4327 const float scene_white_x = grey_x + scene_HL_EV * EV;
4328 const float scene_lat_bottom = grey_x + (
g->spline.x[1] -
g->spline.x[2]) * EV * DR;
4329 const float scene_lat_top = grey_x + (
g->spline.x[3] -
g->spline.x[2]) * EV * DR;
4337 float display_lat_bottom =
filmic_spline(
g->spline.latitude_min,
g->spline.M1,
g->spline.M2,
g->spline.M3,
g->spline.M4,
4338 g->spline.M5,
g->spline.latitude_min,
g->spline.latitude_max,
g->spline.type);
4339 display_lat_bottom = powf(fmaxf(display_lat_bottom,
NORM_MIN),
p->output_power);
4342 display_lat_bottom = log2f(display_lat_bottom/ (
p->grey_point_target / 100.f));
4345 if(display_lat_bottom < 0.f)
4346 display_lat_bottom = fmaxf(display_lat_bottom, -display_real_black_EV);
4347 else if(display_lat_bottom > 0.f)
4348 display_lat_bottom = fminf(display_lat_bottom, display_HL_EV);
4351 display_lat_bottom = grey_x + display_lat_bottom * EV;
4354 float display_lat_top =
filmic_spline(
g->spline.latitude_max,
g->spline.M1,
g->spline.M2,
g->spline.M3,
g->spline.M4,
4355 g->spline.M5,
g->spline.latitude_min,
g->spline.latitude_max,
g->spline.type);
4356 display_lat_top = powf(fmaxf(display_lat_top,
NORM_MIN),
p->output_power);
4359 display_lat_top = log2f(display_lat_top / (
p->grey_point_target / 100.f));
4362 if(display_lat_top < 0.f)
4363 display_lat_top = fmaxf(display_lat_top, -display_real_black_EV);
4364 else if(display_lat_top > 0.f)
4365 display_lat_top = fminf(display_lat_top, display_HL_EV);
4368 display_lat_top = grey_x + display_lat_top * EV;
4370 cairo_move_to(cr, scene_lat_bottom, scene_top);
4371 cairo_line_to(cr, scene_lat_top, scene_top);
4372 cairo_line_to(cr, display_lat_top, display_bottom);
4373 cairo_line_to(cr, display_lat_bottom, display_bottom);
4374 cairo_line_to(cr, scene_lat_bottom, scene_top);
4378 for(
int i = 0;
i < (int)ceilf(display_DR);
i++)
4381 const float shade = powf(exp2f(-11.f + (
float)
i), 1.f / 2.4f);
4382 cairo_set_source_rgb(cr, shade, shade, shade);
4383 cairo_rectangle(cr, display_DR_start_x +
i * EV, display_top, EV,
g->line_height);
4384 cairo_fill_preserve(cr);
4387 cairo_set_source_rgb(cr, 0.75, .5, 0.);
4393 cairo_move_to(cr, grey_x, display_bottom + 2. *
g->inset);
4394 cairo_line_to(cr, grey_x, display_top - 2. *
g->inset);
4399 for(
int i = floorf(
p->black_point_source);
i < ceilf(
p->white_point_source);
i++)
4403 const float shade = powf(0.1845f * exp2f((
float)
i), 1.f / 2.4f);
4404 const float x_temp = grey_x +
i * EV;
4405 cairo_set_source_rgb(cr, shade, shade, shade);
4406 cairo_rectangle(cr, x_temp, scene_top, EV,
g->line_height);
4407 cairo_fill_preserve(cr);
4410 cairo_set_source_rgb(cr, 0.75, .5, 0.);
4419 if((
float)
i >
p->black_point_source && (
float)i < p->white_point_source)
4422 const float normal_value = ((float)
i -
p->black_point_source) / DR;
4423 float y_temp =
filmic_spline(normal_value,
g->spline.M1,
g->spline.M2,
g->spline.M3,
g->spline.M4,
4424 g->spline.M5,
g->spline.latitude_min,
g->spline.latitude_max,
g->spline.type);
4425 y_temp = powf(fmaxf(y_temp,
NORM_MIN),
p->output_power);
4428 y_temp = log2f(y_temp / (
p->grey_point_target / 100.f));
4432 y_temp = fmaxf(y_temp, -display_real_black_EV);
4433 else if(y_temp > 0.f)
4434 y_temp = fminf(y_temp, display_HL_EV);
4437 y_temp = grey_x + y_temp * EV;
4445 float x_temp = grey_x +
p->black_point_source * EV;
4446 float y_temp = grey_x - display_real_black_EV * EV;
4449 x_temp = grey_x +
p->white_point_source * EV;
4450 y_temp = grey_x + display_HL_EV * EV;
4456 cairo_move_to(cr, display_black_x, display_bottom);
4457 cairo_line_to(cr, display_black_x, display_top - 2. *
g->inset);
4461 cairo_move_to(cr, grey_x, display_bottom);
4462 cairo_line_to(cr, grey_x, display_top - 2. *
g->inset);
4466 cairo_move_to(cr, display_white_x, display_bottom);
4467 cairo_line_to(cr, display_white_x, display_top - 2. *
g->inset);
4471 cairo_move_to(cr, scene_black_x, scene_bottom + 2. *
g->inset);
4472 cairo_line_to(cr, scene_black_x, scene_top);
4476 cairo_move_to(cr, grey_x, scene_bottom + 2. *
g->inset);
4477 cairo_line_to(cr, grey_x, scene_top);
4481 cairo_move_to(cr, scene_white_x, scene_bottom + 2. *
g->inset);
4482 cairo_line_to(cr, scene_white_x, scene_top);
4489 snprintf(text,
sizeof(text),
"%+.1f",
p->black_point_source);
4490 pango_layout_set_text(layout, text, -1);
4491 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4492 cairo_move_to(cr, scene_black_x - 0.5 *
g->ink.width -
g->ink.x,
4493 scene_bottom + 2. *
g->inset + 0. *
g->ink.height +
g->ink.y);
4494 pango_cairo_show_layout(cr, layout);
4498 snprintf(text,
sizeof(text),
"%+.1f", 0.f);
4499 pango_layout_set_text(layout, text, -1);
4500 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4501 cairo_move_to(cr, grey_x - 0.5 *
g->ink.width -
g->ink.x,
4502 scene_bottom + 2. *
g->inset + 0. *
g->ink.height +
g->ink.y);
4503 pango_cairo_show_layout(cr, layout);
4507 snprintf(text,
sizeof(text),
"%+.1f",
p->white_point_source);
4508 pango_layout_set_text(layout, text, -1);
4509 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4510 cairo_move_to(cr, scene_white_x - 0.5 *
g->ink.width -
g->ink.x,
4511 scene_bottom + 2. *
g->inset + 0. *
g->ink.height +
g->ink.y);
4512 pango_cairo_show_layout(cr, layout);
4516 snprintf(text,
sizeof(text),
"%.0f",
p->black_point_target);
4517 pango_layout_set_text(layout, text, -1);
4518 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4519 cairo_move_to(cr, display_black_x - 0.5 *
g->ink.width -
g->ink.x,
4520 display_top - 4. *
g->inset -
g->ink.height -
g->ink.y);
4521 pango_cairo_show_layout(cr, layout);
4525 snprintf(text,
sizeof(text),
"%.0f",
p->grey_point_target);
4526 pango_layout_set_text(layout, text, -1);
4527 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4528 cairo_move_to(cr, grey_x - 0.5 *
g->ink.width -
g->ink.x,
4529 display_top - 4. *
g->inset -
g->ink.height -
g->ink.y);
4530 pango_cairo_show_layout(cr, layout);
4534 snprintf(text,
sizeof(text),
"%.0f",
p->white_point_target);
4535 pango_layout_set_text(layout, text, -1);
4536 pango_layout_get_pixel_extents(layout, &
g->ink, NULL);
4537 cairo_move_to(cr, display_white_x - 0.5 *
g->ink.width -
g->ink.x,
4538 display_top - 4. *
g->inset -
g->ink.height -
g->ink.y);
4539 pango_cairo_show_layout(cr, layout);
4544 pango_font_description_set_size(desc, font_size);
4545 pango_layout_set_font_description(layout, desc);
4548 cairo_set_source_surface(crf, cst, 0, 0);
4550 cairo_surface_destroy(cst);
4551 g_object_unref(layout);
4552 pango_font_description_free(desc);
4568 if(event->button == 1 && event->type == GDK_2BUTTON_PRESS)
4574 gtk_widget_queue_draw(GTK_WIDGET(
g->area));
4583 else if(event->button == 1)
4594 gtk_widget_queue_draw(GTK_WIDGET(
g->area));
4600 g->gui_show_labels = !
g->gui_show_labels;
4601 gtk_widget_queue_draw(GTK_WIDGET(
g->area));
4602 dt_conf_set_int(
"plugins/darkroom/filmicrgb/graph_show_labels",
g->gui_show_labels);
4612 else if(event->button == 3)
4622 gtk_widget_queue_draw(GTK_WIDGET(
g->area));
4628 g->gui_show_labels = !
g->gui_show_labels;
4629 gtk_widget_queue_draw(GTK_WIDGET(
g->area));
4630 dt_conf_set_int(
"plugins/darkroom/filmicrgb/graph_show_labels",
g->gui_show_labels);
4650 g->gui_hover =
TRUE;
4651 gtk_widget_queue_draw(GTK_WIDGET(
g->area));
4664 gtk_widget_queue_draw(GTK_WIDGET(
g->area));
4674 if(!
g->gui_sizes_inited)
return FALSE;
4677 const float y =
event->y;
4678 const float x =
event->x;
4680 if(
x > 0. && x < g->allocation.width && y > 0. && y < g->allocation.height)
g->gui_hover =
TRUE;
4682 gint save_active_button =
g->active_button;
4687 gint found_something =
FALSE;
4691 if(
x >
g->buttons[
i].left && x < g->buttons[
i].right && y >
g->buttons[
i].top && y < g->buttons[
i].bottom)
4694 g->buttons[
i].mouse_hover =
TRUE;
4695 g->active_button =
i;
4696 found_something =
TRUE;
4701 g->buttons[
i].mouse_hover =
FALSE;
4711 gtk_widget_set_tooltip_text(GTK_WIDGET(
g->area), _(
"use the parameters below to set the nodes.\n"
4712 "the bright curve is the filmic tone mapping curve\n"
4713 "the dark curve is the desaturation curve."));
4717 gtk_widget_set_tooltip_text(GTK_WIDGET(
g->area), _(
"toggle axis labels and values display"));
4721 gtk_widget_set_tooltip_text(GTK_WIDGET(
g->area), _(
"cycle through graph views.\n"
4722 "left click: cycle forward.\n"
4723 "right click: cycle backward.\n"
4724 "double-click: reset to look view."));
4728 gtk_widget_set_tooltip_text(GTK_WIDGET(
g->area),
"");
4731 if(save_active_button !=
g->active_button) gtk_widget_queue_draw(GTK_WIDGET(
g->area));
4737 if(save_active_button !=
g->active_button) (GTK_WIDGET(
g->area));
4750 const int aspect =
dt_conf_get_int(
"plugins/darkroom/filmicrgb/aspect_percent");
4751 dt_conf_set_int(
"plugins/darkroom/filmicrgb/aspect_percent", aspect + delta_y);
4765 g->gui_show_labels =
TRUE;
4767 g->gui_sizes_inited =
FALSE;
4770 const float aspect =
dt_conf_get_int(
"plugins/darkroom/filmicrgb/aspect_percent") / 100.0;
4772 g_object_set_data(G_OBJECT(
g->area),
"iop-instance", self);
4774 gtk_widget_set_can_focus(GTK_WIDGET(
g->area),
TRUE);
4775 gtk_widget_add_events(GTK_WIDGET(
g->area), GDK_BUTTON_PRESS_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK
4778 g_signal_connect(G_OBJECT(
g->area),
"button-press-event", G_CALLBACK(
area_button_press), self);
4779 g_signal_connect(G_OBJECT(
g->area),
"leave-notify-event", G_CALLBACK(
area_leave_notify), self);
4780 g_signal_connect(G_OBJECT(
g->area),
"enter-notify-event", G_CALLBACK(
area_enter_notify), self);
4781 g_signal_connect(G_OBJECT(
g->area),
"motion-notify-event", G_CALLBACK(
area_motion_notify), self);
4790 g->grey_point_source
4794 gtk_widget_set_tooltip_text(
g->grey_point_source,
4795 _(
"adjust to match the average luminance of the image's subject.\n"
4796 "the value entered here will then be remapped to 18.45%.\n"
4797 "decrease the value to increase the overall brightness."));
4800 g->white_point_source
4804 gtk_widget_set_tooltip_text(
g->white_point_source,
4805 _(
"number of stops between middle gray and pure white.\n"
4806 "this is a reading a lightmeter would give you on the scene.\n"
4807 "adjust so highlights clipping is avoided"));
4810 g->black_point_source
4814 gtk_widget_set_tooltip_text(
4815 g->black_point_source, _(
"number of stops between middle gray and pure black.\n"
4816 "this is a reading a lightmeter would give you on the scene.\n"
4817 "increase to get more contrast.\ndecrease to recover more details in low-lights."));
4823 gtk_widget_set_tooltip_text(
g->security_factor, _(
"symmetrically enlarge or shrink the computed dynamic range.\n"
4824 "useful to give a safety margin to extreme luminances."));
4827 GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
4830 gtk_box_pack_start(GTK_BOX(hbox),
g->auto_button,
FALSE,
FALSE, 0);
4832 gtk_widget_set_tooltip_text(
g->auto_button, _(
"try to optimize the settings with some statistical assumptions.\n"
4833 "this will fit the luminance range inside the histogram bounds.\n"
4834 "works better for landscapes and evenly-lit pictures\n"
4835 "but fails for high-keys, low-keys and high-ISO pictures.\n"
4836 "this is not an artificial intelligence, but a simple guess.\n"
4837 "ensure you understand its assumptions before using it."));
4844 gtk_widget_set_tooltip_text(
g->custom_grey, _(
"enable to input custom middle-gray values.\n"
4845 "this is not recommended in general.\n"
4846 "fix the global exposure in the exposure module instead.\n"
4847 "disable to use standard 18.45 %% middle gray."));
4857 gtk_widget_set_tooltip_text(
g->reconstruct_threshold,
4858 _(
"set the exposure threshold upon which\n"
4859 "clipped highlights get reconstructed.\n"
4860 "values are relative to the scene white point.\n"
4861 "0 EV means the threshold is the same as the scene white point.\n"
4862 "decrease to include more areas,\n"
4863 "increase to exclude more areas."));
4867 gtk_widget_set_tooltip_text(
g->reconstruct_feather,
4868 _(
"soften the transition between clipped highlights and valid pixels.\n"
4869 "decrease to make the transition harder and sharper,\n"
4870 "increase to make the transition softer and blurrier."));
4873 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
4874 gtk_box_pack_start(GTK_BOX(hbox),
dt_ui_label_new(_(
"display highlight reconstruction mask")),
TRUE,
TRUE, 0);
4887 gtk_widget_set_tooltip_text(
g->reconstruct_structure_vs_texture,
4889 _(
"decide which reconstruction strategy to favor,\n"
4890 "between inpainting a smooth color gradient,\n"
4891 "or trying to recover the textured details.\n"
4892 "0% is an equal mix of both.\n"
4893 "increase if at least one RGB channel is not clipped.\n"
4894 "decrease if all RGB channels are clipped over large areas."));
4898 gtk_widget_set_tooltip_text(
g->reconstruct_bloom_vs_details,
4900 _(
"decide which reconstruction strategy to favor,\n"
4901 "between blooming highlights like film does,\n"
4902 "or trying to recover sharp details.\n"
4903 "0% is an equal mix of both.\n"
4904 "increase if you want more details.\n"
4905 "decrease if you want more blur."));
4910 gtk_widget_set_tooltip_text(
g->reconstruct_grey_vs_color,
4912 _(
"decide which reconstruction strategy to favor,\n"
4913 "between recovering monochromatic highlights,\n"
4914 "or trying to recover colorful highlights.\n"
4915 "0% is an equal mix of both.\n"
4916 "increase if you want more color.\n"
4917 "decrease if you see magenta or out-of-gamut highlights."));
4924 gtk_widget_set_tooltip_text(
g->high_quality_reconstruction,
4925 _(
"run extra passes of chromaticity reconstruction.\n"
4926 "more iterations means more color propagation from neighbourhood.\n"
4927 "this will be slower but will yield more neutral highlights.\n"
4928 "it also helps with difficult cases of magenta highlights."));
4932 gtk_widget_set_tooltip_text(
g->noise_level, _(
"add statistical noise in reconstructed highlights.\n"
4933 "this avoids highlights to look too smooth\n"
4934 "when the picture is noisy overall,\n"
4935 "so they blend with the rest of the picture."));
4939 gtk_widget_set_tooltip_text(
g->noise_distribution, _(
"choose the statistical distribution of noise.\n"
4940 "this is useful to match natural sensor noise pattern.\n"));
4951 gtk_widget_set_tooltip_text(
g->contrast, _(
"slope of the linear part of the curve\n"
4952 "affects mostly the mid-tones"));
4956 gtk_widget_set_tooltip_text(
g->output_power, _(
"equivalent to paper grade in analog.\n"
4957 "increase to make highlights brighter and less compressed.\n"
4958 "decrease to mute highlights."));
4965 gtk_widget_set_tooltip_text(
g->toe,
4966 _(
"distance between middle gray and the start of the shadows roll-off.\n"
4967 "0% keeps the toe at middle gray, 100% pushes it to the point where the\n"
4968 "current slope would hit the output black level."));
4976 gtk_widget_set_tooltip_text(
g->shoulder,
4977 _(
"distance between middle gray and the start of the highlights roll-off.\n"
4978 "0% keeps the shoulder at middle gray, 100% pushes it to the point where the\n"
4979 "current slope would hit the output white level."));
4984 gtk_widget_set_tooltip_text(
g->highlights, _(
"choose the desired curvature of the filmic spline in highlights.\n"
4985 "hard uses a high curvature resulting in more tonal compression.\n"
4986 "soft uses a low curvature resulting in less tonal compression."));
4989 gtk_widget_set_tooltip_text(
g->shadows, _(
"choose the desired curvature of the filmic spline in shadows.\n"
4990 "hard uses a high curvature resulting in more tonal compression.\n"
4991 "soft uses a low curvature resulting in less tonal compression."));
4999 gtk_widget_set_tooltip_text(
g->saturation, _(
"desaturates the output of the module\n"
5000 "specifically at extreme luminances.\n"
5001 "increase if shadows and/or highlights are under-saturated."));
5004 gtk_widget_set_tooltip_text(
g->preserve_color, _(
"ensure the original color are preserved.\n"
5005 "may reinforce chromatic aberrations and chroma noise,\n"
5006 "so ensure they are properly corrected elsewhere.\n"));
5013 gtk_widget_set_tooltip_text(
g->version,
5014 _(
"v3 is darktable 3.0 desaturation method, same as color balance.\n"
5015 "v4 is a newer desaturation method, based on spectral purity of light."));
5019 gtk_widget_set_tooltip_text(
5020 g->auto_hardness, _(
"enable to auto-set the look hardness depending on the scene white and black points.\n"
5021 "this keeps the middle gray on the identity line and improves fast tuning.\n"
5022 "disable if you want a manual control."));
5031 gtk_widget_set_tooltip_text(
g->black_point_target, _(
"luminance of output pure black, "
5032 "this should be 0%\nexcept if you want a faded look"));
5037 gtk_widget_set_tooltip_text(
g->grey_point_target,
5038 _(
"middle gray value of the target display or color space.\n"
5039 "you should never touch that unless you know what you are doing."));
5045 gtk_widget_set_tooltip_text(
g->white_point_target, _(
"luminance of output pure white, "
5046 "this should be 100%\nexcept if you want a faded look"));
5051 gtk_box_pack_start(GTK_BOX(self->
widget), GTK_WIDGET(
g->area),
TRUE,
TRUE, 0);
5052 gtk_box_pack_start(GTK_BOX(self->
widget), GTK_WIDGET(
g->notebook),
FALSE,
FALSE, 0);
5060 if(!w || w ==
g->auto_hardness || w ==
g->security_factor || w ==
g->grey_point_source
5061 || w ==
g->black_point_source || w ==
g->white_point_source)
5065 if(w ==
g->security_factor || w ==
g->grey_point_source)
5067 float prev = *(
float *)previous;
5068 if(w ==
g->security_factor)
5070 float ratio = (
p->security_factor - prev) / (prev + 100.0f);
5072 float EVmin =
p->black_point_source;
5073 EVmin = EVmin + ratio * EVmin;
5075 float EVmax =
p->white_point_source;
5076 EVmax = EVmax + ratio * EVmax;
5078 p->white_point_source = EVmax;
5079 p->black_point_source = EVmin;
5083 float grey_var = log2f(prev /
p->grey_point_source);
5084 p->black_point_source =
p->black_point_source - grey_var;
5085 p->white_point_source =
p->white_point_source + grey_var;
5092 if(
p->auto_hardness)
5093 p->output_power = logf(
p->grey_point_target / 100.0f)
5094 / logf(-
p->black_point_source / (
p->white_point_source -
p->black_point_source));
5096 gtk_widget_set_visible(GTK_WIDGET(
g->output_power), !
p->auto_hardness);
5102 if(!w || w ==
g->version)
5107 gtk_widget_set_tooltip_text(
g->saturation, _(
"desaturates the output of the module\n"
5108 "specifically at extreme luminances.\n"
5109 "increase if shadows and/or highlights are under-saturated."));
5114 gtk_widget_set_tooltip_text(
g->saturation, _(
"desaturates the output of the module\n"
5115 "specifically at medium luminances.\n"
5116 "increase if midtones are under-saturated."));
5121 gtk_widget_set_tooltip_text(
g->saturation, _(
"Positive values ensure saturation is kept unchanged over the whole range.\n"
5122 "Negative values bleache highlights at constant hue and luminance.\n"
5123 "Zero is an equal mix of both strategies."));
5124 gtk_widget_set_visible(GTK_WIDGET(
g->preserve_color),
FALSE);
5128 gtk_widget_set_visible(GTK_WIDGET(
g->preserve_color),
TRUE);
5132 if(!w || w ==
g->reconstruct_bloom_vs_details)
5134 if(
p->reconstruct_bloom_vs_details == -100.f)
5139 gtk_widget_set_sensitive(
g->reconstruct_structure_vs_texture,
FALSE);
5143 gtk_widget_set_sensitive(
g->reconstruct_structure_vs_texture,
TRUE);
5147 if(!w || w ==
g->custom_grey)
5149 gtk_widget_set_visible(
g->grey_point_source,
p->custom_grey);
5150 gtk_widget_set_visible(
g->grey_point_target,
p->custom_grey);
5154 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:1255
void dt_bauhaus_slider_set_digits(GtkWidget *widget, int val)
Definition bauhaus.c:2827
float dt_bauhaus_slider_get(GtkWidget *widget)
Definition bauhaus.c:2776
void dt_bauhaus_slider_set_soft_max(GtkWidget *widget, float val)
Definition bauhaus.c:1232
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
Definition bauhaus.c:2799
void dt_bauhaus_widget_set_label(GtkWidget *widget, const char *label)
Definition bauhaus.c:1261
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:1387
void dt_bauhaus_slider_set_format(GtkWidget *widget, const char *format)
Definition bauhaus.c:2887
#define DT_BAUHAUS_SPACE
Definition bauhaus.h:281
static void set_color(cairo_t *cr, GdkRGBA color)
Definition bauhaus.h:399
#define INNER_PADDING
Definition bauhaus.h:76
int width
Definition bilateral.h:1
int height
Definition bilateral.h:1
static void normalize(float *const buffer, const size_t width, const size_t height, const float norm)
Definition blurs.c:366
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:362
#define BSPLINE_FSIZE
Definition bspline.h:30
const dt_colormatrix_t XYZ_D65_to_D50_CAT16
Definition chromatic_adaptation.h:260
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
Definition chromatic_adaptation.h:315
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:471
GtkWidget * dt_color_picker_new(dt_iop_module_t *module, dt_iop_color_picker_kind_t kind, GtkWidget *w)
Definition color_picker_proxy.c:741
@ DT_COLOR_PICKER_AREA
Definition color_picker_proxy.h:45
dt_aligned_pixel_t LMS
Definition colorspaces_inline_conversions.h:952
static dt_aligned_pixel_t Ych
Definition colorspaces_inline_conversions.h:1357
const float i
Definition colorspaces_inline_conversions.h:669
const float c
Definition colorspaces_inline_conversions.h:1365
const float g
Definition colorspaces_inline_conversions.h:925
static dt_aligned_pixel_t Yrg
Definition colorspaces_inline_conversions.h:1287
const float threshold
Definition colorspaces_inline_conversions.h:340
const float d
Definition colorspaces_inline_conversions.h:931
const float r
Definition colorspaces_inline_conversions.h:1324
const float b
Definition colorspaces_inline_conversions.h:1326
const float a
Definition colorspaces_inline_conversions.h:1292
static const dt_colormatrix_t dt_aligned_pixel_t out
Definition colorspaces_inline_conversions.h:184
static const dt_colormatrix_t XYZ_D65_to_LMS_2006_D65
Definition colorspaces_inline_conversions.h:1165
const float n
Definition colorspaces_inline_conversions.h:929
const float M2
Definition colorspaces_inline_conversions.h:1609
static const dt_colormatrix_t LMS_2006_D65_to_XYZ_D65
Definition colorspaces_inline_conversions.h:1170
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:175
static dt_aligned_pixel_t rgb
Definition colorspaces_inline_conversions.h:530
return dt_load_simd_aligned(JCH)
const float delta
Definition colorspaces_inline_conversions.h:722
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:1530
#define dt_free_align(ptr)
Definition darktable.h:405
static void * dt_calloc_align(size_t size)
Definition darktable.h:412
@ DT_DEBUG_OPENCL
Definition darktable.h:642
@ DT_DEBUG_DEV
Definition darktable.h:638
#define DT_ALIGNED_ARRAY
Definition darktable.h:312
#define for_each_channel(_var,...)
Definition darktable.h:582
#define dt_pixelpipe_cache_alloc_align_float_cache(pixels, id)
Definition darktable.h:371
float dt_aligned_pixel_simd_t __attribute__((vector_size(16), aligned(16)))
Multi-tap smudge source sample with directional jitter.
Definition darktable.h:448
#define dt_free(ptr)
Definition darktable.h:380
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
Definition darktable.h:150
#define dt_pixelpipe_cache_free_align(mem)
Definition darktable.h:377
#define dt_pixelpipe_cache_alloc_align_float(pixels, pipe)
Definition darktable.h:366
#define __DT_CLONE_TARGETS__
Definition darktable.h:291
static const dt_aligned_pixel_simd_t value
Definition darktable.h:501
static gboolean dt_modifier_is(const GdkModifierType state, const GdkModifierType desired_modifier_mask)
Definition darktable.h:825
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:253
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:112
@ DT_DEV_PIXELPIPE_DISPLAY_PASSTHRU
Definition develop.h:130
@ DT_DEV_PIXELPIPE_DISPLAY_NONE
Definition develop.h:111
static float dt_log_scale_axis(const float x, const float base)
Definition draw.h:188
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:193
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:3530
static gboolean area_button_press(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
Definition filmicrgb.c:4556
static gboolean area_scroll_callback(GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
Definition filmicrgb.c:4742
const char ** description(struct dt_iop_module_t *self)
Definition filmicrgb.c:372
int default_group()
Definition filmicrgb.c:383
static gboolean area_leave_notify(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
Definition filmicrgb.c:4656
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:3634
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:3668
static float pixel_rgb_norm_power(const dt_aligned_pixel_t pixel)
Definition filmicrgb.c:909
static gboolean dt_iop_tonecurve_draw(GtkWidget *widget, cairo_t *crf, gpointer user_data)
Definition filmicrgb.c:3708
static int get_scales(const dt_iop_roi_t *roi_in, const dt_dev_pixelpipe_iop_t *const piece)
Definition filmicrgb.c:1373
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
void reload_defaults(dt_iop_module_t *module)
Definition filmicrgb.c:3565
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:1214
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
static float clip_chroma(const dt_colormatrix_t matrix_out, const float target_white, const float Y, const float cos_h, const float sin_h, const float chroma)
Definition filmicrgb.c:1874
#define LOGBASE
Definition filmicrgb.c:3639
static float filmic_desaturate_v1(const float x, const float sigma_toe, const float sigma_shoulder, const float saturation)
Definition filmicrgb.c:1073
void gui_update(dt_iop_module_t *self)
Refresh GUI controls from current params and configuration.
Definition filmicrgb.c:3543
static void filmic_chroma_v4(const float *const restrict in, float *const restrict out, const dt_iop_order_iccprofile_info_t *const work_profile, const dt_iop_order_iccprofile_info_t *const export_profile, const dt_iop_filmicrgb_data_t *const data, const dt_iop_filmic_rgb_spline_t spline, const int variant, const size_t width, const size_t height, const size_t ch, const dt_iop_filmicrgb_colorscience_type_t colorscience_version, const float display_black, const float display_white)
Definition filmicrgb.c:2121
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:3641
static void apply_auto_grey(dt_iop_module_t *self, const dt_iop_order_iccprofile_info_t *const work_profile)
Definition filmicrgb.c:2992
static void apply_auto_black(dt_iop_module_t *self, const dt_iop_order_iccprofile_info_t *const work_profile)
Definition filmicrgb.c:3020
static void filmic_split_v2_v3(const float *const restrict in, float *const restrict out, const dt_iop_order_iccprofile_info_t *const work_profile, const dt_iop_filmicrgb_data_t *const data, const dt_iop_filmic_rgb_spline_t spline, const size_t width, const size_t height)
Definition filmicrgb.c:1538
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:1273
const char * aliases()
Definition filmicrgb.c:367
void gui_focus(struct dt_iop_module_t *self, gboolean in)
Definition filmicrgb.c:3490
static void filmic_split_v1(const float *const restrict in, float *const restrict out, const dt_iop_order_iccprofile_info_t *const work_profile, const dt_iop_filmicrgb_data_t *const data, const dt_iop_filmic_rgb_spline_t spline, const size_t width, const size_t height)
Definition filmicrgb.c:1494
#define CIE_Y_1931_to_CIE_Y_2006(x)
Definition filmicrgb.c:1796
static void restore_ratios(float *const restrict ratios, const float *const restrict norms, const size_t width, const size_t height)
Definition filmicrgb.c:2322
const char * name()
Definition filmicrgb.c:362
static void filmic_chroma_v2_v3(const float *const restrict in, float *const restrict out, const dt_iop_order_iccprofile_info_t *const work_profile, const dt_iop_filmicrgb_data_t *const data, const dt_iop_filmic_rgb_spline_t spline, const int variant, const size_t width, const size_t height, const size_t ch, const dt_iop_filmicrgb_colorscience_type_t colorscience_version)
Definition filmicrgb.c:1638
void gui_init(dt_iop_module_t *self)
Definition filmicrgb.c:4759
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 float log_tonemapping(const float x, const float grey, const float black, const float dynamic_range)
Definition filmicrgb.c:986
static float get_pixel_norm(const dt_aligned_pixel_t pixel, const dt_iop_filmicrgb_methods_type_t variant, const dt_iop_order_iccprofile_info_t *const work_profile)
Definition filmicrgb.c:977
static void init_reconstruct(const float *const restrict in, const float *const restrict mask, float *const restrict reconstructed, const size_t width, const size_t height)
Definition filmicrgb.c:1340
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 float get_pixel_norm_simd(const dt_aligned_pixel_simd_t pixel, const dt_iop_filmicrgb_methods_type_t variant, const dt_iop_order_iccprofile_info_t *const work_profile)
Definition filmicrgb.c:915
static void filmic_v3_legacy_to_direct(const dt_iop_filmicrgb_params_t *const p, float *const toe, float *const shoulder)
Definition filmicrgb.c:511
void gui_changed(dt_iop_module_t *self, GtkWidget *w, void *previous)
Definition filmicrgb.c:5055
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:2343
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:3418
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:3047
#define ORDER_4
Definition filmicrgb.c:3154
static float exp_tonemapping_v2(const float x, const float grey, const float black, const float dynamic_range)
Definition filmicrgb.c:995
static float filmic_desaturate_v2(const float x, const float sigma_toe, const float sigma_shoulder, const float saturation)
Definition filmicrgb.c:1089
void cleanup_global(dt_iop_module_so_t *module)
Definition filmicrgb.c:3615
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:2049
static gboolean area_enter_notify(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
Definition filmicrgb.c:4643
void cleanup_pipe(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition filmicrgb.c:3510
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:1118
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
Definition filmicrgb.c:393
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:398
static gboolean area_motion_notify(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
Definition filmicrgb.c:4668
static void compute_ratios(const float *const restrict in, float *const restrict norms, float *const restrict ratios, const dt_iop_order_iccprofile_info_t *const work_profile, const int variant, const size_t width, const size_t height)
Definition filmicrgb.c:2302
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:2362
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:1167
int flags()
Definition filmicrgb.c:388
static void apply_autotune(dt_iop_module_t *self, const dt_iop_order_iccprofile_info_t *const work_profile)
Definition filmicrgb.c:3073
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:437
static void show_mask_callback(GtkToggleButton *button, GdkEventButton *event, gpointer user_data)
Definition filmicrgb.c:3133
#define ORDER_3
Definition filmicrgb.c:3155
static float clip_chroma_white(const float coeffs[3], const float target_white, const float Y, const float cos_h, const float sin_h)
Definition filmicrgb.c:1829
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:1358
static void convert_to_spline_v3(dt_iop_filmicrgb_params_t *n)
Definition filmicrgb.c:563
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:529
#define MAX_NUM_SCALES
Definition filmicrgb.c:1111
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:3504
static float pixel_rgb_norm_power_simd(const dt_aligned_pixel_simd_t pixel)
Definition filmicrgb.c:889
static void filmic_gui_sync_toe_shoulder(dt_iop_module_t *self)
Definition filmicrgb.c:3516
#define INVERSE_SQRT_3
Definition filmicrgb.c:87
static void filmic_v5(const float *const restrict in, float *const restrict out, const dt_iop_order_iccprofile_info_t *const work_profile, const dt_iop_order_iccprofile_info_t *const export_profile, const dt_iop_filmicrgb_data_t *const data, const dt_iop_filmic_rgb_spline_t spline, const size_t width, const size_t height, const size_t ch, const float display_black, const float display_white)
Definition filmicrgb.c:2226
static float filmic_spline(const float x, const dt_aligned_pixel_t M1, const dt_aligned_pixel_t M2, const dt_aligned_pixel_t M3, const dt_aligned_pixel_t M4, const dt_aligned_pixel_t M5, const float latitude_min, const float latitude_max, const dt_iop_filmicrgb_curve_type_t type[2])
Definition filmicrgb.c:1006
static int filmic_v4_prepare_matrices(dt_colormatrix_t input_matrix, dt_colormatrix_t output_matrix, dt_colormatrix_t export_input_matrix, dt_colormatrix_t export_output_matrix, const dt_iop_order_iccprofile_info_t *const work_profile, const dt_iop_order_iccprofile_info_t *const export_profile)
Definition filmicrgb.c:2002
void init_global(dt_iop_module_so_t *module)
Definition filmicrgb.c:3592
static void display_mask(const float *const restrict mask, float *const restrict out, const size_t width, const size_t height)
Definition filmicrgb.c:2288
static int reconstruct_highlights(const float *const restrict in, const float *const restrict mask, float *const restrict reconstructed, const dt_iop_filmicrgb_reconstruction_type_t variant, const size_t ch, const dt_iop_filmicrgb_data_t *const data, 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:1392
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:482
static void filmic_split_v4(const float *const restrict in, float *const restrict out, const dt_iop_order_iccprofile_info_t *const work_profile, const dt_iop_order_iccprofile_info_t *const export_profile, const dt_iop_filmicrgb_data_t *const data, const dt_iop_filmic_rgb_spline_t spline, const int variant, const size_t width, const size_t height, const size_t ch, const dt_iop_filmicrgb_colorscience_type_t colorscience_version, const float display_black, const float display_white)
Definition filmicrgb.c:2175
static float clip_chroma_white_raw(const float coeffs[3], const float target_white, const float Y, const float cos_h, const float sin_h)
Definition filmicrgb.c:1799
static void filmic_chroma_v1(const float *const restrict in, float *const restrict out, const dt_iop_order_iccprofile_info_t *const work_profile, const dt_iop_filmicrgb_data_t *const data, const dt_iop_filmic_rgb_spline_t spline, const int variant, const size_t width, const size_t height)
Definition filmicrgb.c:1582
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:3112
#define SAFETY_MARGIN
Definition filmicrgb.c:88
static float linear_saturation(const float x, const float luminance, const float saturation)
Definition filmicrgb.c:1105
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:3159
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:626
static float clip_chroma_black(const float coeffs[3], const float cos_h, const float sin_h)
Definition filmicrgb.c:1852
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:1917
GtkNotebook * dt_ui_notebook_new()
Definition gtk.c:1912
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:355
#define DT_PIXEL_APPLY_DPI(value)
Definition gtk.h:75
static GtkWidget * dt_ui_label_new(const gchar *str)
Definition gtk.h:365
#define DT_GUI_MODULE(x)
Definition gui_module_api.h:67
void dt_iop_request_focus(dt_iop_module_t *module)
Definition imageop.c:2025
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:2866
void dt_iop_set_cache_bypass(dt_iop_module_t *module, gboolean state)
Definition imageop.c:2594
#define dt_omploop_sfence()
Definition imageop.h:595
@ IOP_FLAGS_INCLUDE_IN_STYLES
Definition imageop.h:143
@ IOP_FLAGS_SUPPORTS_BLENDING
Definition imageop.h:144
@ IOP_FLAGS_ALLOW_TILING
Definition imageop.h:146
@ IOP_GROUP_TONES
Definition imageop.h:114
#define IOP_GUI_ALLOC(module)
Definition imageop.h:492
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
static void dt_iop_alpha_copy(const void *const ivoid, void *const ovoid, const size_t width, const size_t height)
Definition imageop_math.h:181
dt_iop_order_iccprofile_info_t * dt_ioppr_get_pipe_output_profile_info(const struct dt_dev_pixelpipe_t *pipe)
Definition iop_profile.c:924
dt_iop_order_iccprofile_info_t * dt_ioppr_get_pipe_work_profile_info(const struct dt_dev_pixelpipe_t *pipe)
Definition iop_profile.c:914
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:929
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:792
static const float x
Definition iop_profile.h:239
static const float *const const float coeff[3]
Definition iop_profile.h:246
static float dt_ioppr_get_rgb_matrix_luminance(const dt_aligned_pixel_t rgb, const dt_colormatrix_t matrix_in, float *const lut_in[3], const float unbounded_coeffs_in[3][3], const int lutsize, const int nonlinearlut)
Definition iop_profile.h:276
static void flip(float *x, float *y)
Definition lightroom.c:1015
static float sqf(const float x)
Definition math.h:223
#define NORM_MIN
Definition math.h:35
static float dt_fast_hypotf(const float x, const float y)
Definition math.h:280
#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
Y
Definition derive_filmic_v6_gamut_mapping.py:35
mask
Definition dtstyle_to_xmp.py:79
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 float fmaxabsf(const float a, const float b)
Definition openmp_maths.h:121
static float clamp_simd(const float x)
Definition openmp_maths.h:143
@ DT_DEV_PIXELPIPE_FULL
Definition pixelpipe.h:39
#define eps
Definition rcd.c:86
struct _GtkWidget GtkWidget
Definition splash.h:29
int32_t num_openmp_threads
Definition darktable.h:686
struct dt_gui_gtk_t * gui
Definition darktable.h:703
struct dt_bauhaus_t * bauhaus
Definition darktable.h:706
struct dt_develop_t * develop
Definition darktable.h:698
GdkRGBA graph_bg
Definition bauhaus.h:272
GdkRGBA graph_border
Definition bauhaus.h:272
PangoFontDescription * pango_font_desc
Definition bauhaus.h:265
float quad_width
Definition bauhaus.h:264
GdkRGBA graph_fg
Definition bauhaus.h:272
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:129
struct dt_iop_module_t *void * data
Definition pixelpipe_hb.h:96
dt_iop_roi_t roi_in
Definition pixelpipe_hb.h:130
dt_iop_roi_t roi_out
Definition pixelpipe_hb.h:130
Definition pixelpipe_hb.h:216
int mask_display
Definition pixelpipe_hb.h:279
dt_dev_pixelpipe_type_t type
Definition pixelpipe_hb.h:284
int devid
Definition pixelpipe_hb.h:292
int32_t gui_attached
Definition develop.h:158
dt_image_t image_storage
Definition develop.h:243
GList * iop
Definition develop.h:263
double dpi
Definition gtk.h:162
gint scroll_mask
Definition gtk.h:179
int32_t reset
Definition gtk.h:143
Definition develop/format.h:48
unsigned int channels
Definition develop/format.h:50
dt_iop_buffer_type_t datatype
Definition develop/format.h:52
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:356
int kernel_filmic_wavelets_detail
Definition filmicrgb.c:355
int kernel_filmic_show_mask
Definition filmicrgb.c:350
int kernel_filmic_compute_ratios
Definition filmicrgb.c:357
int kernel_filmic_init_reconstruct
Definition filmicrgb.c:354
int kernel_filmic_restore_ratios
Definition filmicrgb.c:358
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
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:2035
dt_aligned_pixel_simd_t input[3]
Definition filmicrgb.c:2036
dt_aligned_pixel_simd_t output[3]
Definition filmicrgb.c:2037
dt_aligned_pixel_simd_t export_output[3]
Definition filmicrgb.c:2039
dt_aligned_pixel_simd_t export_input[3]
Definition filmicrgb.c:2038
Definition filmicrgb.c:410
float white_display
Definition filmicrgb.c:414
float linear_intercept
Definition filmicrgb.c:416
float black_display
Definition filmicrgb.c:413
float xmin
Definition filmicrgb.c:417
gboolean contrast_clamped
Definition filmicrgb.c:419
float grey_display
Definition filmicrgb.c:412
float grey_log
Definition filmicrgb.c:411
float contrast
Definition filmicrgb.c:415
float xmax
Definition filmicrgb.c:418
Definition filmicrgb.c:423
float shoulder_display
Definition filmicrgb.c:427
float toe_display
Definition filmicrgb.c:426
float toe_log
Definition filmicrgb.c:424
float shoulder_log
Definition filmicrgb.c:425
dt_iop_global_data_t * data
Definition imageop.h:203
GtkDarktableToggleButton * off
Definition imageop.h:304
dt_iop_params_t * default_params
Definition imageop.h:272
GtkWidget * widget
Definition imageop.h:302
struct dt_develop_t * dev
Definition imageop.h:261
dt_iop_gui_data_t * gui_data
Definition imageop.h:276
gboolean enabled
Definition imageop.h:263
dt_aligned_pixel_t picked_color_min
Definition imageop.h:244
int request_mask_display
Definition imageop.h:238
dt_aligned_pixel_t picked_color_max
Definition imageop.h:244
dt_aligned_pixel_t picked_color
Definition imageop.h:244
dt_iop_params_t * params
Definition imageop.h:272
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
double scale
Definition imageop.h:69
int width
Definition imageop.h:68
int height
Definition imageop.h:68
#define E
Definition test_filmicrgb.c:61
#define MIN(a, b)
Definition thinplate.c:32
#define MAX(a, b)
Definition thinplate.c:29