74#define DT_GUI_CURVE_EDITOR_INSET DT_PIXEL_APPLY_DPI(1)
186 return _(
"filmic (legacy)");
201 return _(
"this module is deprecated. better use filmic rgb module instead.");
218 const int new_version)
220 if(old_version == 1 && new_version == 3)
222 typedef struct dt_iop_filmic_params_v1_t
224 float grey_point_source;
225 float black_point_source;
226 float white_point_source;
227 float security_factor;
228 float grey_point_target;
229 float black_point_target;
230 float white_point_target;
232 float latitude_stops;
237 } dt_iop_filmic_params_v1_t;
239 dt_iop_filmic_params_v1_t *o = (dt_iop_filmic_params_v1_t *)old_params;
245 n->grey_point_source = o->grey_point_source;
246 n->white_point_source = o->white_point_source;
247 n->black_point_source = o->black_point_source;
248 n->security_factor = o->security_factor;
249 n->grey_point_target = o->grey_point_target;
250 n->black_point_target = o->black_point_target;
251 n->white_point_target = o->white_point_target;
252 n->output_power = o->output_power;
253 n->latitude_stops = o->latitude_stops;
254 n->contrast = o->contrast;
255 n->saturation = o->saturation;
256 n->balance = o->balance;
257 n->interpolator = o->interpolator;
258 n->preserve_color = 0;
259 n->global_saturation = 100;
263 if (old_version == 2 && new_version == 3)
265 typedef struct dt_iop_filmic_params_v2_t
267 float grey_point_source;
268 float black_point_source;
269 float white_point_source;
270 float security_factor;
271 float grey_point_target;
272 float black_point_target;
273 float white_point_target;
275 float latitude_stops;
281 } dt_iop_filmic_params_v2_t;
283 dt_iop_filmic_params_v2_t *o = (dt_iop_filmic_params_v2_t *)old_params;
289 n->grey_point_source = o->grey_point_source;
290 n->white_point_source = o->white_point_source;
291 n->black_point_source = o->black_point_source;
292 n->security_factor = o->security_factor;
293 n->grey_point_target = o->grey_point_target;
294 n->black_point_target = o->black_point_target;
295 n->white_point_target = o->white_point_target;
296 n->output_power = o->output_power;
297 n->latitude_stops = o->latitude_stops;
298 n->contrast = o->contrast;
299 n->saturation = o->saturation;
300 n->balance = o->balance;
301 n->interpolator = o->interpolator;
302 n->preserve_color = o->preserve_color;
303 n->global_saturation = 100;
312 memset(&
p, 0,
sizeof(
p));
318 p.output_power = 2.2f;
319 p.white_point_target = 100.0f;
320 p.black_point_target = 0.0f;
321 p.grey_point_target = 18.0f;
324 p.security_factor = 0.0f;
326 p.preserve_color = 1;
328 p.saturation = 60.0f;
329 p.global_saturation = 70.0f;
332 p.grey_point_source = 25.4f;
333 p.latitude_stops = 2.25f;
334 p.white_point_source = 1.95f;
335 p.black_point_source = -7.05f;
337 self->version(), &
p,
sizeof(
p), 1);
340 p.grey_point_source = 18.0f;
341 p.latitude_stops = 2.75f;
342 p.white_point_source = 2.45f;
343 p.black_point_source = -7.55f;
345 self->version(), &
p,
sizeof(
p), 1);
348 p.grey_point_source = 12.77f;
349 p.latitude_stops = 3.0f;
350 p.white_point_source = 2.95f;
351 p.black_point_source = -8.05f;
353 self->version(), &
p,
sizeof(
p), 1);
356 p.grey_point_source = 9.0f;
357 p.latitude_stops = 3.5f;
358 p.white_point_source = 3.45f;
359 p.black_point_source = -8.55f;
361 self->version(), &
p,
sizeof(
p), 1);
364 p.grey_point_source = 6.38f;
365 p.latitude_stops = 3.75f;
366 p.white_point_source = 3.95f;
367 p.black_point_source = -9.05f;
369 self->version(), &
p,
sizeof(
p), 1);
372 p.grey_point_source = 4.5f;
373 p.latitude_stops = 4.25f;
374 p.white_point_source = 4.45f;
375 p.black_point_source = -9.55f;
377 self->version(), &
p,
sizeof(
p), 1);
380 p.grey_point_source = 3.19f;
381 p.latitude_stops = 4.50f;
382 p.white_point_source = 4.95f;
383 p.black_point_source = -10.05f;
385 self->version(), &
p,
sizeof(
p), 1);
388 p.grey_point_source = 2.25f;
389 p.latitude_stops = 5.0f;
390 p.white_point_source = 5.45f;
391 p.black_point_source = -10.55f;
393 self->version(), &
p,
sizeof(
p), 1);
396 p.grey_point_source = 1.125f;
397 p.latitude_stops = 6.0f;
398 p.white_point_source = 6.45f;
399 p.black_point_source = -11.55f;
401 self->version(), &
p,
sizeof(
p), 1);
406 return expf(- (
x *
x) / (2.0f * std * std)) / (std * powf(2.0f *
M_PI, 0.5f));
411 const void *
const ivoid,
void *
const ovoid)
425 const float EPS = powf(2.0f, -16);
434 float *in = ((
float *)ivoid) +
k;
443 float concavity, luma;
450 for(
int c = 0; c < 3; c++)
452 rgb[c] = luma + saturation * (
rgb[c] - luma);
463 for (
int c = 0; c < 3; ++c) ratios[c] =
rgb[c] /
max;
468 max = CLAMP(
max, 0.0f, 1.0f);
471 index = CLAMP(
max * 0x10000ul, 0, 0xffff);
473 concavity = data->
grad_2[index];
476 for (
int c = 0; c < 3; ++c)
rgb[c] = ratios[c] *
max;
484 for(
int c = 0; c < 3; c++)
489 rgb[c] = CLAMP(
rgb[c], 0.0f, 1.0f);
492 index[c] = CLAMP(
rgb[c] * 0x10000ul, 0, 0xffff);
497 concavity = data->
grad_2[(int)CLAMP(
XYZ[1] * 0x10000ul, 0, 0xffff)];
500 for(
int c = 0; c < 3; c++)
rgb[c] = data->
table[index[c]];
507 for(
int c = 0; c < 3; c++)
510 rgb[c] = luma + concavity * (
rgb[c] - luma);
518 dt_prophotorgb_to_Lab(
rgb,
out);
535 const int devid = pipe->
devid;
541 cl_mem dev_table = NULL;
542 cl_mem diff_table = NULL;
550 const float dynamic_range =
d->dynamic_range;
551 const float shadows_range =
d->black_source;
552 const float grey =
d->grey_source;
553 const float contrast =
d->contrast;
554 const float power =
d->output_power;
555 const int preserve_color =
d->preserve_color;
556 const float saturation =
d->global_saturation / 100.0f;
573 if(err != CL_SUCCESS)
goto error;
588 if (
p->latitude_stops > (
p->white_point_source -
p->black_point_source) * 0.99f)
592 p->latitude_stops = (
p->white_point_source -
p->black_point_source) * 0.99f;
608 const float grey =
XYZ[1];
609 const float prev_grey =
p->grey_point_source;
610 p->grey_point_source = 100.f * grey;
611 const float grey_var =
Log2(prev_grey /
p->grey_point_source);
612 p->black_point_source =
p->black_point_source - grey_var;
613 p->white_point_source =
p->white_point_source + grey_var;
622 gtk_widget_queue_draw(self->
gui->
widget);
631 const float noise = powf(2.0f, -16.0f);
636 const float black =
XYZ[1];
637 float EVmin =
Log2Thres(black / (
p->grey_point_source / 100.0f),
noise);
638 EVmin *= (1.0f +
p->security_factor / 100.0f);
640 p->black_point_source = EVmin;
649 gtk_widget_queue_draw(self->
gui->
widget);
659 const float noise = powf(2.0f, -16.0f);
664 const float white =
XYZ[1];
665 float EVmax =
Log2Thres(white / (
p->grey_point_source / 100.0f),
noise);
666 EVmax *= (1.0f +
p->security_factor / 100.0f);
668 p->white_point_source = EVmax;
677 gtk_widget_queue_draw(self->
gui->
widget);
687 float previous =
p->security_factor;
689 float ratio = (
p->security_factor - previous) / (previous + 100.0f);
691 float EVmin =
p->black_point_source;
692 EVmin = EVmin + ratio * EVmin;
694 float EVmax =
p->white_point_source;
695 EVmax = EVmax + ratio * EVmax;
697 p->white_point_source = EVmax;
698 p->black_point_source = EVmin;
710 gtk_widget_queue_draw(self->
gui->
widget);
718 const float noise = powf(2.0f, -16.0f);
723 const float grey =
XYZ[1];
724 p->grey_point_source = 100.f * grey;
728 const float black =
XYZ[1];
729 float EVmin =
Log2Thres(black / (
p->grey_point_source / 100.0f),
noise);
730 EVmin *= (1.0f +
p->security_factor / 100.0f);
734 const float white =
XYZ[1];
735 float EVmax =
Log2Thres(white / (
p->grey_point_source / 100.0f),
noise);
736 EVmax *= (1.0f +
p->security_factor / 100.0f);
738 p->black_point_source = EVmin;
739 p->white_point_source = EVmax;
750 gtk_widget_queue_draw(self->
gui->
widget);
756 if (picker ==
g->grey_point_source)
758 else if(picker ==
g->black_point_source)
760 else if(picker ==
g->white_point_source)
762 else if(picker ==
g->auto_button)
765 fprintf(stderr,
"[filmic] unknown color picker\n");
774 float prev_grey =
p->grey_point_source;
777 float grey_var =
Log2(prev_grey /
p->grey_point_source);
778 p->black_point_source =
p->black_point_source - grey_var;
779 p->white_point_source =
p->white_point_source + grey_var;
789 gtk_widget_queue_draw(self->
gui->
widget);
805 gtk_widget_queue_draw(self->
gui->
widget);
821 gtk_widget_queue_draw(self->
gui->
widget);
832 gtk_widget_queue_draw(self->
gui->
widget);
848 gtk_widget_queue_draw(self->
gui->
widget);
859 gtk_widget_queue_draw(self->
gui->
widget);
890 gtk_widget_queue_draw(self->
gui->
widget);
901 gtk_widget_queue_draw(self->
gui->
widget);
912 gtk_widget_queue_draw(self->
gui->
widget);
923 gtk_widget_queue_draw(self->
gui->
widget);
963 gtk_widget_queue_draw(self->
gui->
widget);
970 p->preserve_color = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
979 const float white_source =
p->white_point_source;
980 const float black_source =
p->black_point_source;
981 const float dynamic_range = white_source - black_source;
984 const float black_log = 0.0f;
985 const float grey_log = fabsf(
p->black_point_source) / dynamic_range;
986 const float white_log = 1.0f;
989 const float black_display = CLAMP(
p->black_point_target, 0.0f,
p->grey_point_target) / 100.0f;
990 const float grey_display = powf(CLAMP(
p->grey_point_target,
p->black_point_target,
p->white_point_target) / 100.0f, 1.0f / (
p->output_power));
991 const float white_display = CLAMP(
p->white_point_target,
p->grey_point_target, 100.0f) / 100.0f;
993 const float latitude = CLAMP(
p->latitude_stops, 0.01f, dynamic_range * 0.99f);
994 const float balance = CLAMP(
p->balance, -50.0f, 50.0f) / 100.0f;
996 const float contrast =
p->contrast;
1000 float toe_log = grey_log - latitude/dynamic_range * fabsf(black_source/dynamic_range);
1001 float shoulder_log = grey_log + latitude/dynamic_range * white_source/dynamic_range;
1005 float linear_intercept = grey_display - (contrast * grey_log);
1008 float toe_display = (toe_log * contrast + linear_intercept);
1009 float shoulder_display = (shoulder_log * contrast + linear_intercept);
1012 const float norm = powf(powf(contrast, 2.0f) + 1.0f, 0.5f);
1015 const float coeff = -(dynamic_range - latitude) / dynamic_range * balance;
1017 toe_display +=
coeff * contrast /norm;
1018 shoulder_display +=
coeff * contrast /norm;
1019 toe_log +=
coeff /norm;
1020 shoulder_log +=
coeff /norm;
1023 toe_log = CLAMP(toe_log, 0.0f, grey_log);
1024 shoulder_log = CLAMP(shoulder_log, grey_log, 1.0f);
1025 toe_display = CLAMP(toe_display, black_display, grey_display);
1026 shoulder_display = CLAMP(shoulder_display, grey_display, white_display);
1039 int TOE_LOST =
FALSE;
1040 int SHOULDER_LOST =
FALSE;
1042 if ((toe_log == grey_log && toe_display == grey_display) || (toe_log == 0.0f && toe_display == black_display))
1046 if ((shoulder_log == grey_log && shoulder_display == grey_display) || (shoulder_log == 1.0f && shoulder_display == white_display))
1048 SHOULDER_LOST =
TRUE;
1053 if (SHOULDER_LOST && !TOE_LOST)
1056 nodes_data->
nodes = 4;
1057 nodes_data->
x[0] = black_log;
1058 nodes_data->
x[1] = toe_log;
1059 nodes_data->
x[2] = grey_log;
1060 nodes_data->
x[3] = white_log;
1062 nodes_data->
y[0] = black_display;
1063 nodes_data->
y[1] = toe_display;
1064 nodes_data->
y[2] = grey_display;
1065 nodes_data->
y[3] = white_display;
1069 d->latitude_min = toe_log;
1070 d->latitude_max = white_log;
1076 else if (TOE_LOST && !SHOULDER_LOST)
1079 nodes_data->
nodes = 4;
1081 nodes_data->
x[0] = black_log;
1082 nodes_data->
x[1] = grey_log;
1083 nodes_data->
x[2] = shoulder_log;
1084 nodes_data->
x[3] = white_log;
1086 nodes_data->
y[0] = black_display;
1087 nodes_data->
y[1] = grey_display;
1088 nodes_data->
y[2] = shoulder_display;
1089 nodes_data->
y[3] = white_display;
1093 d->latitude_min = black_log;
1094 d->latitude_max = shoulder_log;
1100 else if (TOE_LOST && SHOULDER_LOST)
1103 nodes_data->
nodes = 3;
1105 nodes_data->
x[0] = black_log;
1106 nodes_data->
x[1] = grey_log;
1107 nodes_data->
x[2] = white_log;
1109 nodes_data->
y[0] = black_display;
1110 nodes_data->
y[1] = grey_display;
1111 nodes_data->
y[2] = white_display;
1115 d->latitude_min = black_log;
1116 d->latitude_max = white_log;
1125 nodes_data->
nodes = 4;
1127 nodes_data->
x[0] = black_log;
1128 nodes_data->
x[1] = toe_log;
1130 nodes_data->
x[2] = shoulder_log;
1131 nodes_data->
x[3] = white_log;
1133 nodes_data->
y[0] = black_display;
1134 nodes_data->
y[1] = toe_display;
1136 nodes_data->
y[2] = shoulder_display;
1137 nodes_data->
y[3] = white_display;
1141 d->latitude_min = toe_log;
1142 d->latitude_max = shoulder_log;
1148 if (
p->interpolator != 3)
1180 for(
int k = 0;
k <
res;
k++) table[
k] = (table[
k] + table_temp[
k]) / 2.0f;
1191 d->preserve_color =
p->preserve_color;
1194 const float white_source =
p->white_point_source;
1195 const float grey_source =
p->grey_point_source / 100.0f;
1196 const float black_source =
p->black_point_source;
1197 const float dynamic_range = white_source - black_source;
1200 const float grey_log = fabsf(
p->black_point_source) / dynamic_range;
1203 const float grey_display = powf(
p->grey_point_target / 100.0f, 1.0f / (
p->output_power));
1205 float contrast =
p->contrast;
1206 if (contrast < grey_display / grey_log)
1209 contrast = 1.0001f * grey_display / grey_log;
1213 d->dynamic_range = dynamic_range;
1214 d->black_source = black_source;
1215 d->grey_source = grey_source;
1216 d->output_power =
p->output_power;
1217 d->saturation =
p->saturation;
1218 d->global_saturation =
p->global_saturation;
1219 d->contrast = contrast;
1230 const float latitude =
d->latitude_max -
d->latitude_min;
1231 const float center = (
d->latitude_max +
d->latitude_min)/2.0f;
1232 const float saturation =
d->saturation / 100.0f;
1233 const float sigma = saturation * saturation * latitude * latitude;
1235 for(
int k = 0;
k < 65536;
k++)
1237 const float x = ((float)
k) / 65536.0f;
1240 d->grad_2[
k] = expf(-0.5f * (center -
x) * (center -
x) /
sigma);
1244 d->grad_2[
k] = 0.0f;
1285 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
g->preserve_color),
p->preserve_color);
1288 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
g->extra_toggle)));
1290 gtk_widget_queue_draw(self->
gui->
widget);
1296 module->params = calloc(1, sizeof(dt_iop_filmic_params_t));
1297 module->default_params = calloc(1, sizeof(dt_iop_filmic_params_t));
1298 module->default_enabled = 0;
1299 module->params_size = sizeof(dt_iop_filmic_params_t);
1303 .grey_point_source = 18,
1304 .black_point_source = -8.65,
1305 .white_point_source = 2.45,
1306 .security_factor = 0.0,
1307 .grey_point_target = 18.0,
1308 .black_point_target = 0.0,
1309 .white_point_target = 100.0,
1310 .output_power = 2.2,
1311 .latitude_stops = 2.0,
1313 .saturation = 100.0,
1314 .global_saturation = 100.0,
1317 .preserve_color = 0,
1323 const int program = 22;
1351 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
g->extra_toggle),
FALSE);
1363 GtkAllocation allocation;
1364 gtk_widget_get_allocation(widget, &allocation);
1365 int width = allocation.width,
height = allocation.height;
1367 cairo_t *cr = cairo_create(cst);
1370 cairo_set_source_rgb(cr, .2, .2, .2);
1373 cairo_translate(cr, inset, inset);
1377 cairo_set_source_rgb(cr, .3, .3, .3);
1383 cairo_set_source_rgb(cr, .1, .1, .1);
1387 const float DR = (
p->white_point_source -
p->black_point_source);
1388 const float grey = -
p->black_point_source / DR;
1389 int rescale =
FALSE;
1393 b =
Log2( 1.0f / (-1 + powf(2.0f, a)));
1394 d = - powf(2.0f, b);
1396 if (grey > powf(
p->grey_point_target / 100.0f,
p->output_power))
1402 for (
int i = 0;
i < 50; ++
i)
1404 a =
Log2((0.5f -
d) / (1.0f -
d)) / (grey - 1.0f);
1405 b =
Log2( 1.0f / (-1 + powf(2.0f, a)));
1406 d = - powf(2.0f, b);
1410 const float gamma = (logf(
p->grey_point_target / 100.0f) / logf(0.5f)) /
p->output_power;
1414 cairo_set_source_rgb(cr, 0.9, 0.9, 0.9);
1416 for(
int k = 0;
k < nodes_data->
nodes;
k++)
1422 const float x = (rescale) ? powf(2.0f, (
double)a * nodes_data->
x[
k] + b) +
d : nodes_data->
x[
k];
1423 const float y = powf(nodes_data->
y[
k], 1.0f / gamma);
1426 cairo_stroke_preserve(cr);
1434 cairo_set_source_rgb(cr, .9, .9, .9);
1435 cairo_move_to(cr, 0,
height * (1.0 - c->table[0]));
1437 for(
int k = 1;
k < 256;
k++)
1443 const float x = (rescale) ? powf(2.0f, (
double)a *
k / 255.0f + b) +
d :
k / 255.0f;
1444 const float y = powf(c->table[
k], 1.0f / gamma);
1445 cairo_line_to(cr,
x *
width, (
double)
height * (1.0 - y));
1449 cairo_set_source_surface(crf, cst, 0, 0);
1451 cairo_surface_destroy(cst);
1459 const gboolean active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
g->extra_toggle));
1473 g->area = GTK_DRAWING_AREA(gtk_drawing_area_new());
1474 gtk_widget_set_hexpand(GTK_WIDGET(
g->area),
TRUE);
1475 gtk_widget_set_tooltip_text(GTK_WIDGET(
g->area), _(
"read-only graph, use the parameters below to set the nodes"));
1476 gtk_box_pack_start(GTK_BOX(self->
gui->
widget),
1478 "plugins/darkroom/filmic/graphheight", 200, 100),
1490 gtk_widget_set_tooltip_text(
g->grey_point_source, _(
"adjust to match the average luminance of the subject.\n"
1491 "except in back-lighting situations, this should be around 18%."));
1499 gtk_box_pack_start(GTK_BOX(self->
gui->
widget),
g->white_point_source,
TRUE,
TRUE, 0);
1501 gtk_widget_set_tooltip_text(
g->white_point_source, _(
"number of stops between middle gray and pure white.\n"
1502 "this is a reading a lightmeter would give you on the scene.\n"
1503 "adjust so highlights clipping is avoided"));
1511 gtk_box_pack_start(GTK_BOX(self->
gui->
widget),
g->black_point_source,
TRUE,
TRUE, 0);
1513 gtk_widget_set_tooltip_text(
g->black_point_source, _(
"number of stops between middle gray and pure black.\n"
1514 "this is a reading a lightmeter would give you on the scene.\n"
1515 "increase to get more contrast.\ndecrease to recover more details in low-lights."));
1524 gtk_widget_set_tooltip_text(
g->security_factor, _(
"enlarge or shrink the computed dynamic range.\n"
1525 "useful in conjunction with \"auto tune levels\"."));
1532 gtk_widget_set_tooltip_text(
g->auto_button, _(
"try to optimize the settings with some guessing.\n"
1533 "this will fit the luminance range inside the histogram bounds.\n"
1534 "works better for landscapes and evenly-lit pictures\nbut fails for high-keys and low-keys." ));
1544 gtk_widget_set_tooltip_text(
g->contrast, _(
"slope of the linear part of the curve\n"
1545 "affects mostly the mid-tones"));
1546 g_signal_connect(G_OBJECT(
g->contrast),
"value-changed", G_CALLBACK(
contrast_callback), self);
1554 gtk_widget_set_tooltip_text(
g->latitude_stops, _(
"width of the linear domain in the middle of the curve.\n"
1555 "increase to get more contrast at the extreme luminances.\n"
1556 "this has no effect on mid-tones."));
1564 gtk_widget_set_tooltip_text(
g->balance, _(
"slides the latitude along the slope\nto give more room to shadows or highlights.\n"
1565 "use it if you need to protect the details\nat one extremity of the histogram."));
1566 g_signal_connect(G_OBJECT(
g->balance),
"value-changed", G_CALLBACK(
balance_callback), self);
1574 gtk_widget_set_tooltip_text(
g->global_saturation, _(
"desaturates the input of the module globally.\n"
1575 "you need to set this value below 100%\nif the chrominance preservation is enabled."));
1584 gtk_widget_set_tooltip_text(
g->saturation, _(
"desaturates the output of the module\nspecifically at extreme luminances.\n"
1585 "decrease if shadows and/or highlights are over-saturated."));
1586 g_signal_connect(G_OBJECT(
g->saturation),
"value-changed", G_CALLBACK(
saturation_callback), self);
1600 gtk_widget_set_tooltip_text(
g->interpolator, _(
"change this method if you see reversed contrast or faded blacks"));
1604 g->preserve_color = gtk_check_button_new_with_label(_(
"preserve the chrominance"));
1605 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(
g->preserve_color),
p->preserve_color);
1606 gtk_widget_set_tooltip_text(
g->preserve_color, _(
"ensure the original color are preserved.\n"
1607 "may reinforce chromatic aberrations.\n"
1608 "you need to manually tune the saturation when using this mode."));
1619 gtk_box_pack_start(GTK_BOX(destdisp_head), destdisp,
TRUE,
TRUE, 0);
1620 gtk_box_pack_start(GTK_BOX(destdisp_head),
g->extra_toggle,
FALSE,
FALSE, 0);
1621 gtk_widget_set_visible(extra_options,
FALSE);
1632 gtk_box_pack_start(GTK_BOX(extra_options),
g->black_point_target,
FALSE,
FALSE, 0);
1634 gtk_widget_set_tooltip_text(
g->black_point_target, _(
"luminance of output pure black, "
1635 "this should be 0%\nexcept if you want a faded look"));
1641 gtk_box_pack_start(GTK_BOX(extra_options),
g->grey_point_target,
FALSE,
FALSE, 0);
1643 gtk_widget_set_tooltip_text(
g->grey_point_target, _(
"middle gray value of the target display or color space.\n"
1644 "you should never touch that unless you know what you are doing."));
1650 gtk_box_pack_start(GTK_BOX(extra_options),
g->white_point_target,
FALSE,
FALSE, 0);
1652 gtk_widget_set_tooltip_text(
g->white_point_target, _(
"luminance of output pure white, "
1653 "this should be 100%\nexcept if you want a faded look"));
1659 gtk_box_pack_start(GTK_BOX(extra_options),
g->output_power,
FALSE,
FALSE, 0);
1660 gtk_widget_set_tooltip_text(
g->output_power, _(
"power or gamma of the transfer function\nof the display or color space.\n"
1661 "you should never touch that unless you know what you are doing."));
static void error(char *msg)
void dt_bauhaus_slider_set_soft_range(GtkWidget *widget, float soft_min, float soft_max)
float dt_bauhaus_slider_get(GtkWidget *widget)
int dt_bauhaus_combobox_get(GtkWidget *widget)
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
void dt_bauhaus_combobox_set(GtkWidget *widget, const int pos)
void dt_bauhaus_widget_set_label(GtkWidget *widget, const char *label)
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)
GtkWidget * dt_bauhaus_combobox_new(dt_bauhaus_t *bh, dt_gui_module_t *self)
void dt_bauhaus_slider_set_format(GtkWidget *widget, const char *format)
void dt_bauhaus_combobox_add(GtkWidget *widget, const char *text)
void dt_iop_color_picker_reset(dt_iop_module_t *module, gboolean keep)
GtkWidget * dt_color_picker_new(dt_iop_module_t *module, dt_iop_color_picker_kind_t kind, GtkWidget *w)
const float *const const float coeff[3]
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
dt_prophotorgb_to_XYZ(rgb, XYZ)
static dt_aligned_pixel_t rgb
dt_XYZ_to_prophotorgb(XYZ, rgb)
static dt_aligned_pixel_t XYZ
const dt_colormatrix_t dt_aligned_pixel_t out
struct dt_bauhaus_t * dt_bauhaus_get_global(void)
#define dt_dev_add_history_item(dev, module, enable, redraw)
@ DT_DEV_PIXELPIPE_DISPLAY_MASK
static void dt_draw_curve_calc_values(dt_draw_curve_t *c, const float min, const float max, const int res, float *x, float *y)
static void dt_draw_grid(cairo_t *cr, const int num, const int left, const int top, const int right, const int bottom)
static void dt_draw_curve_destroy(dt_draw_curve_t *c)
static int dt_draw_curve_add_point(dt_draw_curve_t *c, const float x, const float y)
static dt_draw_curve_t * dt_draw_curve_new(const float min, const float max, unsigned int type)
void dtgtk_expander_set_expanded(GtkDarktableExpander *expander, gboolean expanded)
GtkWidget * dtgtk_expander_new(GtkWidget *header, GtkWidget *body)
#define DTGTK_EXPANDER(obj)
static void preserve_color_callback(GtkWidget *widget, dt_iop_module_t *self)
void init(dt_iop_module_t *module)
static void white_point_target_callback(GtkWidget *slider, gpointer user_data)
void gui_reset(dt_iop_module_t *self)
static void sanitize_latitude(dt_iop_filmic_params_t *p, dt_iop_filmic_gui_data_t *g)
static void contrast_callback(GtkWidget *slider, gpointer user_data)
static void interpolator_callback(GtkWidget *widget, dt_iop_module_t *self)
static gboolean dt_iop_tonecurve_draw(GtkWidget *widget, cairo_t *crf, gpointer user_data)
static void output_power_callback(GtkWidget *slider, gpointer user_data)
static void latitude_stops_callback(GtkWidget *slider, gpointer user_data)
void gui_update(dt_iop_module_t *self)
Refresh GUI controls from current params and configuration.
__DT_CLONE_TARGETS__ int process(dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid)
#define DT_GUI_CURVE_EDITOR_INSET
static void security_threshold_callback(GtkWidget *slider, gpointer user_data)
static void apply_autotune(dt_iop_module_t *self)
void cleanup(dt_iop_module_t *module)
static void balance_callback(GtkWidget *slider, gpointer user_data)
void gui_init(dt_iop_module_t *self)
static void grey_point_target_callback(GtkWidget *slider, gpointer user_data)
static void grey_point_source_callback(GtkWidget *slider, gpointer user_data)
void commit_params(dt_iop_module_t *self, dt_iop_params_t *p1, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
static float gaussian(float x, float std)
void cleanup_global(dt_iop_module_so_t *module)
static void _extra_options_button_changed(GtkDarktableToggleButton *widget, gpointer user_data)
void cleanup_pipe(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
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)
static void apply_auto_white_point_source(dt_iop_module_t *self)
static void global_saturation_callback(GtkWidget *slider, gpointer user_data)
void init_presets(dt_iop_module_so_t *self)
static void saturation_callback(GtkWidget *slider, gpointer user_data)
static void black_point_target_callback(GtkWidget *slider, gpointer user_data)
void init_pipe(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
static void white_point_source_callback(GtkWidget *slider, gpointer user_data)
static void black_point_source_callback(GtkWidget *slider, gpointer user_data)
void compute_curve_lut(dt_iop_filmic_params_t *p, float *table, float *table_temp, int res, dt_iop_filmic_data_t *d, dt_iop_filmic_nodes_t *nodes_data)
static void apply_auto_black(dt_iop_module_t *self)
void init_global(dt_iop_module_so_t *module)
const char * deprecated_msg()
int process_cl(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, cl_mem dev_in, cl_mem dev_out)
static void apply_auto_grey(dt_iop_module_t *self)
void color_picker_apply(dt_iop_module_t *self, GtkWidget *picker, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
int legacy_params(dt_iop_module_t *self, const void *const old_params, const int old_version, void *new_params, const int new_version)
void dt_gui_presets_add_generic(const char *name, dt_dev_operation_t op, const int32_t version, const void *params, const int32_t params_size, const int32_t enabled)
@ IOP_FLAGS_INCLUDE_IN_STYLES
@ IOP_FLAGS_SUPPORTS_BLENDING
static dt_iop_gui_data_t * dt_iop_gui_data(const struct dt_iop_module_t *m)
The module's GUI data blob, NULL-safe for headless callers: IOP process() implementations read it for...
#define IOP_GUI_ALLOC(module)
GtkWidget * dt_ui_section_label_new(const gchar *str)
void dt_print(dt_debug_thread_t thread, const char *msg,...) __attribute__((format(printf
Print to stdout when thread is enabled, prefixed with seconds since startup.
float *const restrict const size_t k
float *const restrict const size_t const size_t ch
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
static float fastlog2(float x)
static float Log2(float x)
static float Log2Thres(float x, float Thres)
#define dt_free_align(ptr)
Release memory from dt_alloc_align() and set ptr to NULL.
static void * dt_calloc_align(size_t size)
dt_alloc_align() followed by a zero fill.
#define DT_ALIGNED_ARRAY
Align an object on a cacheline boundary, so AVX2 can load it whole.
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
DT_MODULE() for a module whose params struct is introspected.
int dt_opencl_enqueue_kernel_2d(const int dev, const int kernel, const size_t *sizes)
int dt_opencl_create_kernel(const int prog, const char *name)
void dt_opencl_free_kernel(const int kernel)
int dt_opencl_set_kernel_arg(const int dev, const int kernel, const int num, const size_t size, const void *arg)
void * dt_opencl_copy_host_to_device(const int devid, void *host, const int width, const int height, const int bpp)
void dt_opencl_release_mem_object(cl_mem mem)
#define __OMP_PARALLEL_FOR_SIMD__(...)
static cairo_surface_t * dt_cairo_image_surface_create(cairo_format_t format, int width, int height)
DT_ALIGNED_PIXEL float dt_aligned_pixel_t[4]
struct dt_iop_module_t *void * data
dt_iop_buffer_type_t datatype
float table_temp[0x10000]
GtkWidget * extra_expander
GtkWidget * preserve_color
GtkWidget * black_point_target
GtkWidget * global_saturation
GtkWidget * black_point_source
GtkWidget * white_point_target
GtkWidget * grey_point_source
GtkWidget * white_point_source
GtkWidget * grey_point_target
GtkWidget * security_factor
GtkWidget * latitude_stops
dt_iop_global_data_t * data
dt_iop_params_t * default_params
struct dt_iop_module_gui_t * gui
struct dt_develop_t * dev
dt_iop_global_data_t * global_data
dt_aligned_pixel_t picked_color_min
dt_aligned_pixel_t picked_color_max
dt_aligned_pixel_t picked_color
Region of interest passed through the pixelpipe.
#define __DT_CLONE_TARGETS__